ts/R/compile.R
2025-01-21 20:51:28 +13:00

66 lines
1.7 KiB
R

#' Compile R functions to TypeScript schemas
#' @param f A function or file path
#' @param name The name of the function
#' @param ... Additional arguments
#' @param file The file path to write the TypeScript schema (optional). If `""`, the output is printed to the standard output console (see `cat`).
#' @return Character vector of TypeScript schema, or NULL if writing to file
#' @md
#' @export
ts_compile <- function(f, ..., name, file) {
o <- UseMethod("ts_compile")
}
#' @export
ts_compile.ts_function <- function(f, ..., name = deparse(substitute(f))) {
inputs <- f$args
result <- f$result
inputs <- sapply(inputs, \(x) x$input_type)
fn_args <- paste(paste(inputs), collapse = ", ")
sprintf(
"const %s = Robj.ocap([%s], %s);", name, fn_args,
result$return_type
)
}
#' @export
ts_compile.character <- function(
f,
file = sprintf("%s.rserve.ts", tools::file_path_sans_ext(f))) {
if (length(f) > 1) {
return(sapply(f, ts_compile))
}
if (!file.exists(f)) {
warning(sprintf("File not found: %s", f))
return()
}
e <- new.env()
source(f, local = e)
x <- sapply(ls(e), \(x) ts_compile(e[[x]], file = file, name = x))
src <- c(
"import { Robj } from 'rserve-ts';",
"import { z } from 'zod';",
"\n",
x,
"\n",
sprintf("export default {\n %s\n};", paste(ls(e), collapse = ",\n "))
)
# if (file != "" && file.exists(file)) {
# stop(sprintf("File exists: %s", file))
# return()
# }
cat(src, file = file, sep = "\n")
invisible()
}
#' @export
ts_compile.default <- function(f, ...) {
warning("Not supported")
}