Files
windmill/cli/windmill-utils-internal/src/inline-scripts/extractor.ts
centdix 5b0ea4d2de chore: use windmill-utils-internal for cli (#6297)
* add utils package

* naming

* cleaning

* simplify assignPath

* rename old files

* same for locks

* create on confirm

* default true

* use replaceinlinescripts from utils

* use extractscriptfromflows

* make it compile

* cleaning

* use argsigtojson

* fix

* fix missing await

* cleaner

* cleaning

* cleaning

* use in frontend

* add docs

* testing

* remove log

* use autogenerated types

* remove old

* fix

* cleaning

* adapt usage

* draft

* better build script

* fix build

* revert to default creation

* add docs

* remove and rename

* make everything work

* add await

* only if not installed

* add vs code setting

* add to publish action

* fix bc

* safer use of sep

* fix

* do not rename on push

* no publish on release

* use published package on frontend

* nit
2025-07-31 13:23:39 +00:00

107 lines
3.6 KiB
TypeScript

import { assignPath } from "../path-utils/path-assigner";
import { FlowModule } from "../gen/types.gen";
/**
* Represents an inline script extracted from a flow module
*/
interface InlineScript {
/** File path where the script content should be written */
path: string;
/** The actual script content */
content: string;
}
/**
* Extracts inline scripts from flow modules, converting them to separate files
* and replacing the original content with file references.
*
* @param modules - Array of flow modules to process
* @param mapping - Optional mapping of module IDs to custom file paths
* @param defaultTs - Default TypeScript runtime to use ("bun" or "deno")
* @returns Array of inline scripts with their paths and content
*/
export function extractInlineScripts(
modules: FlowModule[],
mapping: Record<string, string> = {},
separator: string = "/",
defaultTs?: "bun" | "deno"
): InlineScript[] {
return modules.flatMap((m) => {
if (m.value.type == "rawscript") {
const [basePath, ext] = assignPath(
m.id,
m.value.language,
defaultTs
);
const path = mapping[m.id] ?? basePath + ext;
const content = m.value.content;
const r = [{ path: path, content: content }];
m.value.content = "!inline " + path.replaceAll(separator, "/");
const lock = m.value.lock;
if (lock && lock != "") {
const lockPath = basePath + "lock";
m.value.lock = "!inline " + lockPath.replaceAll(separator, "/");
r.push({ path: lockPath, content: lock });
}
return r;
} else if (m.value.type == "forloopflow") {
return extractInlineScripts(m.value.modules, mapping, separator, defaultTs);
} else if (m.value.type == "branchall") {
return m.value.branches.flatMap((b) =>
extractInlineScripts(b.modules, mapping, separator, defaultTs)
);
} else if (m.value.type == "whileloopflow") {
return extractInlineScripts(m.value.modules, mapping, separator, defaultTs);
} else if (m.value.type == "branchone") {
return [
...m.value.branches.flatMap((b) =>
extractInlineScripts(b.modules, mapping, separator, defaultTs)
),
...extractInlineScripts(m.value.default, mapping, separator, defaultTs),
];
} else {
return [];
}
});
}
/**
* Extracts the current mapping of module IDs to file paths from flow modules
* by analyzing existing inline script references.
*
* @param modules - Array of flow modules to analyze (can be undefined)
* @param mapping - Existing mapping to extend (defaults to empty object)
* @returns Record mapping module IDs to their corresponding file paths
*/
export function extractCurrentMapping(
modules: FlowModule[] | undefined,
mapping: Record<string, string> = {}
): Record<string, string> {
if (!modules || !Array.isArray(modules)) {
return mapping;
}
modules.forEach((m) => {
if (!m?.value?.type) {
return;
}
if (m.value.type === "rawscript") {
if (m.value.content && m.value.content.startsWith("!inline ")) {
mapping[m.id] = m.value.content.trim().split(" ")[1];
}
} else if (
m.value.type === "forloopflow" ||
m.value.type === "whileloopflow"
) {
extractCurrentMapping(m.value.modules, mapping);
} else if (m.value.type === "branchall") {
m.value.branches.forEach((b) => extractCurrentMapping(b.modules, mapping));
} else if (m.value.type === "branchone") {
m.value.branches.forEach((b) => extractCurrentMapping(b.modules, mapping));
extractCurrentMapping(m.value.default, mapping);
}
});
return mapping;
}