windmill-utils-internal
Version:
Internal utility functions for Windmill
158 lines (157 loc) • 5.05 kB
JavaScript
const INLINE_SCRIPT_PREFIX = "inline_script";
/**
* Mapping of supported languages to their file extensions
*/
export const LANGUAGE_EXTENSIONS = {
python3: "py",
bun: "bun.ts",
deno: "deno.ts",
go: "go",
bash: "sh",
powershell: "ps1",
postgresql: "pg.sql",
mysql: "my.sql",
bigquery: "bq.sql",
oracledb: "odb.sql",
snowflake: "sf.sql",
mssql: "ms.sql",
graphql: "gql",
nativets: "native.ts",
frontend: "frontend.js",
php: "php",
rust: "rs",
csharp: "cs",
nu: "nu",
ansible: "playbook.yml",
java: "java",
duckdb: "duckdb.sql",
bunnative: "ts",
// for related places search: ADD_NEW_LANG
};
/**
* Gets the appropriate file extension for a given programming language.
* Handles special cases for TypeScript variants based on the default runtime.
*
* @param language - The programming language to get extension for
* @param defaultTs - Default TypeScript runtime ("bun" or "deno")
* @returns File extension string (without the dot)
*/
export function getLanguageExtension(language, defaultTs = "bun") {
if (language === defaultTs || language === "bunnative") {
return "ts";
}
return LANGUAGE_EXTENSIONS[language] || "no_ext";
}
/**
* Reverse mapping from file extensions to languages.
* Used when deriving language from file extension.
*/
export const EXTENSION_TO_LANGUAGE = {
"py": "python3",
"bun.ts": "bun",
"deno.ts": "deno",
"go": "go",
"sh": "bash",
"ps1": "powershell",
"pg.sql": "postgresql",
"my.sql": "mysql",
"bq.sql": "bigquery",
"odb.sql": "oracledb",
"sf.sql": "snowflake",
"ms.sql": "mssql",
"gql": "graphql",
"native.ts": "nativets",
"frontend.js": "frontend",
"php": "php",
"rs": "rust",
"cs": "csharp",
"nu": "nu",
"playbook.yml": "ansible",
"java": "java",
"duckdb.sql": "duckdb",
// Plain .ts defaults to bun (will be overridden by defaultTs setting)
"ts": "bun",
};
/**
* Gets the language from a file extension.
*
* @param ext - File extension (e.g., "py", "ts", "bun.ts")
* @param defaultTs - Default TypeScript runtime for plain .ts files
* @returns The language, or undefined if not recognized
*/
export function getLanguageFromExtension(ext, defaultTs = "bun") {
// Check for compound extensions first (e.g., "bun.ts", "pg.sql")
const lang = EXTENSION_TO_LANGUAGE[ext];
if (lang) {
// For plain .ts, return the default TypeScript runtime
if (ext === "ts") {
return defaultTs;
}
return lang;
}
return undefined;
}
/**
* Creates a new path assigner for inline scripts.
*
* @param defaultTs - Default TypeScript runtime ("bun" or "deno")
* @param options - Optional configuration (can pass options object instead of defaultTs)
* @returns Path assigner function
*/
export function newPathAssigner(defaultTs, options) {
// Handle both old signature (defaultTs string) and new signature (options object)
const resolvedOptions = typeof defaultTs === "object"
? defaultTs
: { defaultTs, skipInlineScriptSuffix: options?.skipInlineScriptSuffix };
const { defaultTs: tsRuntime, skipInlineScriptSuffix } = resolvedOptions;
let counter = 0;
const seen_names = new Set();
function assignPath(summary, language) {
let name;
name = summary?.toLowerCase()?.replaceAll(" ", "_") ?? "";
let original_name = name;
if (name == "") {
original_name = INLINE_SCRIPT_PREFIX;
name = `${INLINE_SCRIPT_PREFIX}_0`;
}
while (seen_names.has(name)) {
counter++;
name = `${original_name}_${counter}`;
}
seen_names.add(name);
const ext = getLanguageExtension(language, tsRuntime);
// When skipInlineScriptSuffix is true, don't add .inline_script. to the path
const suffix = skipInlineScriptSuffix ? "." : ".inline_script.";
return [`${name}${suffix}`, ext];
}
return { assignPath };
}
/**
* Creates a new path assigner for raw app runnables.
* Unlike newPathAssigner, this does NOT add ".inline_script." prefix since
* everything in raw_app/backend/ is already known to be for inline scripts.
*
* @param defaultTs - Default TypeScript runtime ("bun" or "deno")
* @returns Path assigner function
*/
export function newRawAppPathAssigner(defaultTs) {
let counter = 0;
const seen_names = new Set();
function assignPath(summary, language) {
let name;
name = summary?.toLowerCase()?.replaceAll(" ", "_") ?? "";
let original_name = name;
if (name == "") {
original_name = "runnable";
name = `runnable_0`;
}
while (seen_names.has(name)) {
counter++;
name = `${original_name}_${counter}`;
}
seen_names.add(name);
const ext = getLanguageExtension(language, defaultTs);
return [`${name}.`, ext];
}
return { assignPath };
}