windmill-cli 1.657.2 → 1.659.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/esm/main.js +815 -406
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -11785,7 +11785,7 @@ var init_OpenAPI = __esm(() => {
11785
11785
  PASSWORD: undefined,
11786
11786
  TOKEN: getEnv2("WM_TOKEN"),
11787
11787
  USERNAME: undefined,
11788
- VERSION: "1.657.2",
11788
+ VERSION: "1.659.0",
11789
11789
  WITH_CREDENTIALS: true,
11790
11790
  interceptors: {
11791
11791
  request: new Interceptors,
@@ -12220,6 +12220,7 @@ __export(exports_services_gen, {
12220
12220
  logout: () => logout,
12221
12221
  loginWithOauth: () => loginWithOauth,
12222
12222
  login: () => login,
12223
+ logAiChat: () => logAiChat,
12223
12224
  loadTableRowCount: () => loadTableRowCount,
12224
12225
  loadParquetPreview: () => loadParquetPreview,
12225
12226
  loadGitRepoFilePreview: () => loadGitRepoFilePreview,
@@ -14242,6 +14243,16 @@ var backendVersion = () => {
14242
14243
  404: "protection rule not found"
14243
14244
  }
14244
14245
  });
14246
+ }, logAiChat = (data2) => {
14247
+ return request(OpenAPI, {
14248
+ method: "POST",
14249
+ url: "/w/{workspace}/workspaces/log_chat",
14250
+ path: {
14251
+ workspace: data2.workspace
14252
+ },
14253
+ body: data2.requestBody,
14254
+ mediaType: "application/json"
14255
+ });
14245
14256
  }, setPublicAppRateLimit = (data2) => {
14246
14257
  return request(OpenAPI, {
14247
14258
  method: "POST",
@@ -24318,6 +24329,29 @@ function isRawAppMetadataFile(p) {
24318
24329
  function isRawAppFolderMetadataFile(p) {
24319
24330
  return p.endsWith(getMetadataPathSuffix("raw_app", "yaml")) || p.endsWith(getMetadataPathSuffix("raw_app", "json"));
24320
24331
  }
24332
+ function getModuleFolderSuffix() {
24333
+ return MODULE_SUFFIX;
24334
+ }
24335
+ function isScriptModulePath(p) {
24336
+ return normalizeSep(p).includes(MODULE_SUFFIX + "/");
24337
+ }
24338
+ function isModuleEntryPoint(p) {
24339
+ const norm = normalizeSep(p);
24340
+ const suffix = MODULE_SUFFIX + "/";
24341
+ const idx = norm.indexOf(suffix);
24342
+ if (idx === -1)
24343
+ return false;
24344
+ const rest = norm.slice(idx + suffix.length);
24345
+ return rest.startsWith("script.") && !rest.includes("/");
24346
+ }
24347
+ function getScriptBasePathFromModulePath(p) {
24348
+ const norm = normalizeSep(p);
24349
+ const suffix = MODULE_SUFFIX + "/";
24350
+ const idx = norm.indexOf(suffix);
24351
+ if (idx === -1)
24352
+ return;
24353
+ return norm.slice(0, idx);
24354
+ }
24321
24355
  function getDeleteSuffix(type, format6) {
24322
24356
  return getFolderSuffixes()[type] + "/" + METADATA_FILES[type][format6];
24323
24357
  }
@@ -24333,7 +24367,7 @@ function transformJsonPathToDir(p, type) {
24333
24367
  }
24334
24368
  return p;
24335
24369
  }
24336
- var DOTTED_SUFFIXES, NON_DOTTED_SUFFIXES, _nonDottedPaths = false, _nonDottedPathsLogged = false, METADATA_FILES;
24370
+ var DOTTED_SUFFIXES, NON_DOTTED_SUFFIXES, _nonDottedPaths = false, _nonDottedPathsLogged = false, METADATA_FILES, MODULE_SUFFIX = "__mod";
24337
24371
  var init_resource_folders = __esm(() => {
24338
24372
  init_log();
24339
24373
  init_yaml();
@@ -24959,6 +24993,14 @@ async function readConfigFile() {
24959
24993
  migrationMessages.push("ℹ️ Removing empty 'overrides: {}' from wmill.yaml (migrated to gitBranches format)");
24960
24994
  }
24961
24995
  }
24996
+ if (conf && "environments" in conf) {
24997
+ if (!conf.gitBranches) {
24998
+ conf.gitBranches = conf.environments;
24999
+ } else {
25000
+ warn("⚠️ Both 'environments' and 'gitBranches' found in wmill.yaml. Using 'gitBranches' and ignoring 'environments'.");
25001
+ }
25002
+ delete conf.environments;
25003
+ }
24962
25004
  if (conf && "git_branches" in conf) {
24963
25005
  if (!conf.gitBranches) {
24964
25006
  conf.gitBranches = JSON.parse(JSON.stringify(conf.git_branches));
@@ -25503,7 +25545,7 @@ var init_workspace = __esm(async () => {
25503
25545
  ]);
25504
25546
  command = new Command().alias("profile").description("workspace related commands").action(list).command("switch").complete("workspace", async () => (await allWorkspaces()).map((x) => x.name)).description("Switch to another workspace").arguments("<workspace_name:string:workspace>").action(switchC).command("add").description("Add a workspace").arguments("[workspace_name:string] [workspace_id:string] [remote:string]").option("-c --create", "Create the workspace if it does not exist").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").option("--create-username <username:string>", "Specify your own username in the newly created workspace. Ignored if --create is not specified, the workspace already exists or automatic username creation is enabled on the instance.", {
25505
25547
  default: "admin"
25506
- }).action(add).command("remove").description("Remove a workspace").arguments("<workspace_name:string>").action(remove).command("whoami").description("Show the currently active user").action(whoami2).command("list").description("List local workspace profiles").action(list).command("list-remote").description("List workspaces on the remote server that you have access to").action(listRemote).command("bind").description("Bind the current Git branch to the active workspace").option("--branch <branch:string>", "Specify branch (defaults to current)").action((opts) => bind(opts, true)).command("unbind").description("Remove workspace binding from the current Git branch").option("--branch <branch:string>", "Specify branch (defaults to current)").action((opts) => bind(opts, false)).command("fork").description("Create a forked workspace").arguments("[workspace_name:string] [workspace_id:string]").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").action(createWorkspaceFork2).command("delete-fork").description("Delete a forked workspace and git branch").arguments("<fork_name:string>").option("-y --yes", "Skip confirmation prompt").action(deleteWorkspaceFork);
25548
+ }).action(add).command("remove").description("Remove a workspace").arguments("<workspace_name:string>").action(remove).command("whoami").description("Show the currently active user").action(whoami2).command("list").description("List local workspace profiles").action(list).command("list-remote").description("List workspaces on the remote server that you have access to").action(listRemote).command("bind").description("Bind the current Git branch to the active workspace").option("--branch, --env <branch:string>", "Specify branch/environment (defaults to current)").action((opts) => bind(opts, true)).command("unbind").description("Remove workspace binding from the current Git branch").option("--branch, --env <branch:string>", "Specify branch/environment (defaults to current)").action((opts) => bind(opts, false)).command("fork").description("Create a forked workspace").arguments("[workspace_name:string] [workspace_id:string]").option("--create-workspace-name <workspace_name:string>", "Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.").action(createWorkspaceFork2).command("delete-fork").description("Delete a forked workspace and git branch").arguments("<fork_name:string>").option("-y --yes", "Skip confirmation prompt").action(deleteWorkspaceFork);
25507
25549
  workspace_default = command;
25508
25550
  });
25509
25551
 
@@ -31128,7 +31170,7 @@ end
31128
31170
 
31129
31171
  // src/utils/script_common.ts
31130
31172
  function languageNeedsLock(language) {
31131
- return workspaceDependenciesLanguages.some((l) => l.language === language) || language === "deno" || language === "rust" || language === "ansible";
31173
+ return workspaceDependenciesLanguages.some((l) => l.language === language) && language !== "powershell" || language === "deno" || language === "rust" || language === "ansible";
31132
31174
  }
31133
31175
  function inferContentTypeFromFilePath(contentPath, defaultTs) {
31134
31176
  if (contentPath.endsWith(".py")) {
@@ -31187,7 +31229,8 @@ var init_script_common = __esm(() => {
31187
31229
  { language: "bun", filename: "package.json" },
31188
31230
  { language: "python3", filename: "requirements.in" },
31189
31231
  { language: "php", filename: "composer.json" },
31190
- { language: "go", filename: "go.mod" }
31232
+ { language: "go", filename: "go.mod" },
31233
+ { language: "powershell", filename: "modules.json" }
31191
31234
  ];
31192
31235
  });
31193
31236
 
@@ -58801,6 +58844,7 @@ var init_tar = __esm(() => {
58801
58844
  import { readFile as readFile5, writeFile as writeFile4, stat as stat3 } from "node:fs/promises";
58802
58845
  import { Buffer as Buffer4 } from "node:buffer";
58803
58846
  import { sep as SEP4 } from "node:path";
58847
+ import * as path5 from "node:path";
58804
58848
  import fs8 from "node:fs";
58805
58849
  import { execSync as execSync3 } from "node:child_process";
58806
58850
  function isRawAppBackendPath2(filePath) {
@@ -58830,8 +58874,8 @@ async function push(opts, filePath) {
58830
58874
  await handleFile(filePath, workspace, [], undefined, opts, await getRawWorkspaceDependencies(), codebases);
58831
58875
  info(colors.bold.underline.green(`Script ${filePath} pushed`));
58832
58876
  }
58833
- async function findResourceFile(path5) {
58834
- const splitPath = path5.split(".");
58877
+ async function findResourceFile(path6) {
58878
+ const splitPath = path6.split(".");
58835
58879
  let contentBasePathJSON = splitPath[0] + "." + splitPath[1] + ".json";
58836
58880
  let contentBasePathYAML = splitPath[0] + "." + splitPath[1] + ".yaml";
58837
58881
  const currentBranch = getCurrentGitBranch();
@@ -58852,45 +58896,48 @@ async function findResourceFile(path5) {
58852
58896
  throw new Error("Found two resource files for the same resource" + validCandidates.join(", "));
58853
58897
  }
58854
58898
  if (validCandidates.length < 1) {
58855
- throw new Error(`No resource matching file resource: ${path5}.`);
58899
+ throw new Error(`No resource matching file resource: ${path6}.`);
58856
58900
  }
58857
58901
  return validCandidates[0];
58858
58902
  }
58859
- async function handleScriptMetadata(path5, workspace, alreadySynced, message, rawWorkspaceDependencies, codebases, opts) {
58860
- if (path5.endsWith(".script.json") || path5.endsWith(".script.yaml") || path5.endsWith(".script.lock")) {
58861
- const contentPath = await findContentFile(path5);
58903
+ async function handleScriptMetadata(path6, workspace, alreadySynced, message, rawWorkspaceDependencies, codebases, opts) {
58904
+ const isFlatMeta = path6.endsWith(".script.json") || path6.endsWith(".script.yaml") || path6.endsWith(".script.lock");
58905
+ const isFolderMeta = !isFlatMeta && isScriptModulePath(path6) && (path6.endsWith("/script.yaml") || path6.endsWith("/script.json") || path6.endsWith("/script.lock"));
58906
+ if (isFlatMeta || isFolderMeta) {
58907
+ const contentPath = await findContentFile(path6);
58862
58908
  return handleFile(contentPath, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases);
58863
58909
  } else {
58864
58910
  return false;
58865
58911
  }
58866
58912
  }
58867
- async function handleFile(path5, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases) {
58868
- if (!isAppInlineScriptPath2(path5) && !isFlowInlineScriptPath2(path5) && !isRawAppBackendPath2(path5) && exts.some((exts) => path5.endsWith(exts))) {
58869
- if (alreadySynced.includes(path5)) {
58913
+ async function handleFile(path6, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases) {
58914
+ const moduleEntryPoint = isModuleEntryPoint(path6);
58915
+ if (!isAppInlineScriptPath2(path6) && !isFlowInlineScriptPath2(path6) && !isRawAppBackendPath2(path6) && (!isScriptModulePath(path6) || moduleEntryPoint) && exts.some((exts) => path6.endsWith(exts))) {
58916
+ if (alreadySynced.includes(path6)) {
58870
58917
  return true;
58871
58918
  }
58872
- debug(`Processing local script ${path5}`);
58873
- alreadySynced.push(path5);
58874
- const remotePath = path5.substring(0, path5.indexOf(".")).replaceAll(SEP4, "/");
58875
- const language = inferContentTypeFromFilePath(path5, opts?.defaultTs);
58876
- const codebase = language == "bun" ? findCodebase(path5, codebases) : undefined;
58919
+ debug(`Processing local script ${path6}`);
58920
+ alreadySynced.push(path6);
58921
+ const remotePath = moduleEntryPoint ? getScriptBasePathFromModulePath(path6).replaceAll(SEP4, "/") : path6.substring(0, path6.indexOf(".")).replaceAll(SEP4, "/");
58922
+ const language = inferContentTypeFromFilePath(path6, opts?.defaultTs);
58923
+ const codebase = language == "bun" ? findCodebase(path6, codebases) : undefined;
58877
58924
  let bundleContent = undefined;
58878
58925
  let forceTar = false;
58879
58926
  if (codebase) {
58880
58927
  let outputFiles = [];
58881
58928
  if (codebase.customBundler) {
58882
- info(`Using custom bundler ${codebase.customBundler} for ${path5}`);
58883
- bundleContent = execSync3(codebase.customBundler + " " + path5, {
58929
+ info(`Using custom bundler ${codebase.customBundler} for ${path6}`);
58930
+ bundleContent = execSync3(codebase.customBundler + " " + path6, {
58884
58931
  maxBuffer: 1024 * 1024 * 50
58885
58932
  }).toString();
58886
- info("Custom bundler executed for " + path5);
58933
+ info("Custom bundler executed for " + path6);
58887
58934
  } else {
58888
58935
  const esbuild = await import("esbuild");
58889
- info(`Started bundling ${path5} ...`);
58936
+ info(`Started bundling ${path6} ...`);
58890
58937
  const startTime = performance.now();
58891
58938
  const format6 = codebase.format ?? "cjs";
58892
58939
  const out = await esbuild.build({
58893
- entryPoints: [path5],
58940
+ entryPoints: [path6],
58894
58941
  format: format6,
58895
58942
  bundle: true,
58896
58943
  write: false,
@@ -58908,15 +58955,15 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
58908
58955
  bundleContent = out.outputFiles[0].text;
58909
58956
  outputFiles = out.outputFiles ?? [];
58910
58957
  if (outputFiles.length == 0) {
58911
- throw new Error(`No output files found for ${path5}`);
58958
+ throw new Error(`No output files found for ${path6}`);
58912
58959
  }
58913
- info(`Finished bundling ${path5}: ${(bundleContent.length / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58960
+ info(`Finished bundling ${path6}: ${(bundleContent.length / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58914
58961
  }
58915
58962
  if (outputFiles.length > 1) {
58916
- info(`Found multiple output files for ${path5}, creating a tarball... ${outputFiles.map((file) => file.path).join(", ")}`);
58963
+ info(`Found multiple output files for ${path6}, creating a tarball... ${outputFiles.map((file) => file.path).join(", ")}`);
58917
58964
  forceTar = true;
58918
58965
  const startTime = performance.now();
58919
- const mainPath = path5.split(SEP4).pop()?.split(".")[0] + ".js";
58966
+ const mainPath = path6.split(SEP4).pop()?.split(".")[0] + ".js";
58920
58967
  const mainContent = outputFiles.find((file) => file.path == "/" + mainPath)?.text ?? "";
58921
58968
  info(`Main content: ${mainContent.length}chars`);
58922
58969
  const entries = [
@@ -58931,10 +58978,10 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
58931
58978
  }
58932
58979
  bundleContent = await createTarBlob(entries);
58933
58980
  const endTime = performance.now();
58934
- info(`Finished creating tarball for ${path5}: ${(bundleContent.size / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58981
+ info(`Finished creating tarball for ${path6}: ${(bundleContent.size / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58935
58982
  } else {
58936
58983
  if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
58937
- info(`Using the following asset configuration for ${path5}: ${JSON.stringify(codebase.assets)}`);
58984
+ info(`Using the following asset configuration for ${path6}: ${JSON.stringify(codebase.assets)}`);
58938
58985
  const startTime = performance.now();
58939
58986
  const entries = [
58940
58987
  { name: "main.js", content: bundleContent }
@@ -58945,13 +58992,13 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
58945
58992
  }
58946
58993
  bundleContent = await createTarBlob(entries);
58947
58994
  const endTime = performance.now();
58948
- info(`Finished creating tarball for ${path5}: ${(bundleContent.size / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58995
+ info(`Finished creating tarball for ${path6}: ${(bundleContent.size / 1024).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`);
58949
58996
  }
58950
58997
  }
58951
58998
  }
58952
58999
  let typed = opts?.skipScriptsMetadata ? undefined : (await parseMetadataFile(remotePath, opts ? {
58953
59000
  ...opts,
58954
- path: path5,
59001
+ path: path6,
58955
59002
  workspaceRemote: workspace,
58956
59003
  schemaOnly: codebase ? true : undefined,
58957
59004
  rawWorkspaceDependencies,
@@ -58968,13 +59015,16 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
58968
59015
  } catch {
58969
59016
  debug(`Script ${remotePath} does not exist on remote`);
58970
59017
  }
58971
- const content = await readFile5(path5, "utf-8");
59018
+ const content = await readFile5(path6, "utf-8");
58972
59019
  if (opts?.skipScriptsMetadata) {
58973
59020
  typed = structuredClone(remote);
58974
59021
  }
58975
59022
  if (typed && codebase) {
58976
59023
  typed.codebase = await codebase.getDigest(forceTar);
58977
59024
  }
59025
+ const scriptBasePath = moduleEntryPoint ? getScriptBasePathFromModulePath(path6) : path6.substring(0, path6.indexOf("."));
59026
+ const moduleFolderPath = scriptBasePath + getModuleFolderSuffix();
59027
+ const modules = await readModulesFromDisk(moduleFolderPath, opts?.defaultTs, moduleEntryPoint);
58978
59028
  const requestBodyCommon = {
58979
59029
  content,
58980
59030
  description: typed?.description ?? "",
@@ -58993,7 +59043,6 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
58993
59043
  deployment_message: message,
58994
59044
  restart_unless_cancelled: typed?.restart_unless_cancelled,
58995
59045
  visible_to_runner_only: typed?.visible_to_runner_only,
58996
- no_main_func: typed?.no_main_func,
58997
59046
  has_preprocessor: typed?.has_preprocessor,
58998
59047
  priority: typed?.priority,
58999
59048
  concurrency_key: typed?.concurrency_key,
@@ -59002,12 +59051,13 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
59002
59051
  codebase: await codebase?.getDigest(forceTar),
59003
59052
  timeout: typed?.timeout,
59004
59053
  on_behalf_of_email: typed?.on_behalf_of_email,
59005
- envs: typed?.envs
59054
+ envs: typed?.envs,
59055
+ modules
59006
59056
  };
59007
59057
  if (remote) {
59008
59058
  if (content === remote.content) {
59009
59059
  if (typed == undefined || typed.description === remote.description && typed.summary === remote.summary && typed.kind == remote.kind && !remote.archived && (Array.isArray(remote?.lock) ? remote?.lock?.join(`
59010
- `) : remote?.lock ?? "").trim() == (typed?.lock ?? "").trim() && deepEqual(typed.schema, remote.schema) && typed.tag == remote.tag && (typed.ws_error_handler_muted ?? false) == remote.ws_error_handler_muted && typed.dedicated_worker == remote.dedicated_worker && typed.cache_ttl == remote.cache_ttl && typed.concurrency_time_window_s == remote.concurrency_time_window_s && typed.concurrent_limit == remote.concurrent_limit && Boolean(typed.restart_unless_cancelled) == Boolean(remote.restart_unless_cancelled) && Boolean(typed.visible_to_runner_only) == Boolean(remote.visible_to_runner_only) && Boolean(typed.no_main_func) == Boolean(remote.no_main_func) && Boolean(typed.has_preprocessor) == Boolean(remote.has_preprocessor) && typed.priority == Boolean(remote.priority) && typed.timeout == remote.timeout && typed.concurrency_key == remote["concurrency_key"] && typed.debounce_key == remote["debounce_key"] && typed.debounce_delay_s == remote["debounce_delay_s"] && typed.codebase == remote.codebase && typed.on_behalf_of_email == remote.on_behalf_of_email && deepEqual(typed.envs, remote.envs)) {
59060
+ `) : remote?.lock ?? "").trim() == (typed?.lock ?? "").trim() && deepEqual(typed.schema, remote.schema) && typed.tag == remote.tag && (typed.ws_error_handler_muted ?? false) == remote.ws_error_handler_muted && typed.dedicated_worker == remote.dedicated_worker && typed.cache_ttl == remote.cache_ttl && typed.concurrency_time_window_s == remote.concurrency_time_window_s && typed.concurrent_limit == remote.concurrent_limit && Boolean(typed.restart_unless_cancelled) == Boolean(remote.restart_unless_cancelled) && Boolean(typed.visible_to_runner_only) == Boolean(remote.visible_to_runner_only) && Boolean(typed.has_preprocessor) == Boolean(remote.has_preprocessor) && typed.priority == Boolean(remote.priority) && typed.timeout == remote.timeout && typed.concurrency_key == remote["concurrency_key"] && typed.debounce_key == remote["debounce_key"] && typed.debounce_delay_s == remote["debounce_delay_s"] && typed.codebase == remote.codebase && typed.on_behalf_of_email == remote.on_behalf_of_email && deepEqual(typed.envs, remote.envs) && deepEqual(modules ?? null, remote.modules ?? null)) {
59011
59061
  info(colors.green(`Script ${remotePath} is up to date`));
59012
59062
  return true;
59013
59063
  }
@@ -59032,6 +59082,50 @@ async function handleFile(path5, workspace, alreadySynced, message, opts, rawWor
59032
59082
  }
59033
59083
  return false;
59034
59084
  }
59085
+ async function readModulesFromDisk(moduleFolderPath, defaultTs, folderLayout = false) {
59086
+ if (!fs8.existsSync(moduleFolderPath) || !fs8.statSync(moduleFolderPath).isDirectory()) {
59087
+ return;
59088
+ }
59089
+ const modules = {};
59090
+ const isEntryPointFile = (name, isTopLevel) => {
59091
+ if (!folderLayout || !isTopLevel)
59092
+ return false;
59093
+ return name.startsWith("script.") || name === "script.lock" || name === "script.yaml" || name === "script.json";
59094
+ };
59095
+ function readDir2(dirPath, relPrefix) {
59096
+ const entries = fs8.readdirSync(dirPath, { withFileTypes: true });
59097
+ for (const entry of entries) {
59098
+ const fullPath = path5.join(dirPath, entry.name);
59099
+ const relPath = relPrefix ? relPrefix + "/" + entry.name : entry.name;
59100
+ const isTopLevel = relPrefix === "";
59101
+ if (entry.isDirectory()) {
59102
+ readDir2(fullPath, relPath);
59103
+ } else if (entry.isFile() && !entry.name.endsWith(".lock") && !isEntryPointFile(entry.name, isTopLevel)) {
59104
+ if (exts.some((ext2) => entry.name.endsWith(ext2))) {
59105
+ const content = fs8.readFileSync(fullPath, "utf-8");
59106
+ const language = inferContentTypeFromFilePath(entry.name, defaultTs);
59107
+ const baseName = entry.name.replace(/\.[^.]+$/, "");
59108
+ const lockPath = path5.join(dirPath, baseName + ".lock");
59109
+ let lock;
59110
+ if (fs8.existsSync(lockPath)) {
59111
+ lock = fs8.readFileSync(lockPath, "utf-8");
59112
+ }
59113
+ modules[relPath] = {
59114
+ content,
59115
+ language,
59116
+ lock: lock ?? undefined
59117
+ };
59118
+ }
59119
+ }
59120
+ }
59121
+ }
59122
+ readDir2(moduleFolderPath, "");
59123
+ if (Object.keys(modules).length === 0) {
59124
+ return;
59125
+ }
59126
+ debug(`Found ${Object.keys(modules).length} module(s) in ${moduleFolderPath}`);
59127
+ return modules;
59128
+ }
59035
59129
  async function createScript2(bundleContent, workspaceId, body, workspace) {
59036
59130
  const start = performance.now();
59037
59131
  if (!bundleContent) {
@@ -59060,7 +59154,8 @@ async function createScript2(bundleContent, workspaceId, body, workspace) {
59060
59154
  return performance.now() - start;
59061
59155
  }
59062
59156
  async function findContentFile(filePath) {
59063
- const candidates = filePath.endsWith("script.json") ? exts.map((x) => filePath.replace(".script.json", x)) : filePath.endsWith("script.lock") ? exts.map((x) => filePath.replace(".script.lock", x)) : exts.map((x) => filePath.replace(".script.yaml", x));
59157
+ const isModuleFolderMeta = filePath.endsWith("/script.yaml") || filePath.endsWith("/script.json") || filePath.endsWith("/script.lock");
59158
+ const candidates = isModuleFolderMeta ? exts.map((x) => filePath.replace(/\/script\.(yaml|json|lock)$/, "/script" + x)) : filePath.endsWith("script.json") ? exts.map((x) => filePath.replace(".script.json", x)) : filePath.endsWith("script.lock") ? exts.map((x) => filePath.replace(".script.lock", x)) : exts.map((x) => filePath.replace(".script.yaml", x));
59064
59159
  const validCandidates = (await Promise.all(candidates.map((x) => {
59065
59160
  return stat3(x).catch(() => {
59066
59161
  return;
@@ -59133,13 +59228,13 @@ function filePathExtensionFromContentType(language, defaultTs) {
59133
59228
  throw new Error("Invalid language: " + language);
59134
59229
  }
59135
59230
  }
59136
- function removeExtensionToPath(path5) {
59231
+ function removeExtensionToPath(path6) {
59137
59232
  for (const ext2 of exts) {
59138
- if (path5.endsWith(ext2)) {
59139
- return path5.substring(0, path5.length - ext2.length);
59233
+ if (path6.endsWith(ext2)) {
59234
+ return path6.substring(0, path6.length - ext2.length);
59140
59235
  }
59141
59236
  }
59142
- throw new Error("Invalid extension: " + path5);
59237
+ throw new Error("Invalid extension: " + path6);
59143
59238
  }
59144
59239
  async function list2(opts) {
59145
59240
  const workspace = await resolveWorkspace(opts);
@@ -59188,13 +59283,13 @@ async function resolve6(input) {
59188
59283
  throw e;
59189
59284
  }
59190
59285
  }
59191
- async function run2(opts, path5) {
59286
+ async function run2(opts, path6) {
59192
59287
  const workspace = await resolveWorkspace(opts);
59193
59288
  await requireLogin(opts);
59194
59289
  const input = opts.data ? await resolve6(opts.data) : {};
59195
59290
  const id = await runScriptByPath({
59196
59291
  workspace: workspace.workspaceId,
59197
- path: path5,
59292
+ path: path6,
59198
59293
  requestBody: input
59199
59294
  });
59200
59295
  if (!opts.silent) {
@@ -59286,12 +59381,12 @@ async function track_job(workspace, id) {
59286
59381
  info("Job appears to have completed, but no data can be retrieved");
59287
59382
  }
59288
59383
  }
59289
- async function show(opts, path5) {
59384
+ async function show(opts, path6) {
59290
59385
  const workspace = await resolveWorkspace(opts);
59291
59386
  await requireLogin(opts);
59292
59387
  const s = await getScriptByPath({
59293
59388
  workspace: workspace.workspaceId,
59294
- path: path5
59389
+ path: path6
59295
59390
  });
59296
59391
  info(colors.underline(s.path));
59297
59392
  if (s.description)
@@ -59299,12 +59394,12 @@ async function show(opts, path5) {
59299
59394
  info("");
59300
59395
  info(s.content);
59301
59396
  }
59302
- async function get(opts, path5) {
59397
+ async function get(opts, path6) {
59303
59398
  const workspace = await resolveWorkspace(opts);
59304
59399
  await requireLogin(opts);
59305
59400
  const s = await getScriptByPath({
59306
59401
  workspace: workspace.workspaceId,
59307
- path: path5
59402
+ path: path6
59308
59403
  });
59309
59404
  if (opts.json) {
59310
59405
  console.log(JSON.stringify(s));
@@ -59380,7 +59475,7 @@ async function generateMetadata(opts, scriptPath) {
59380
59475
  } else {
59381
59476
  const ignore = await ignoreF(opts);
59382
59477
  const elems = await elementsToMap(await FSFSElement(process.cwd(), codebases, false), (p, isD) => {
59383
- return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFlowPath(p) || isAppPath(p) || isRawAppPath(p);
59478
+ return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFlowPath(p) || isAppPath(p) || isRawAppPath(p) || isScriptModulePath(p) && !isModuleEntryPoint(p);
59384
59479
  }, false, {});
59385
59480
  let hasAny = false;
59386
59481
  info("Generating metadata for all stale scripts:");
@@ -59429,6 +59524,9 @@ async function preview(opts, filePath) {
59429
59524
  const language = inferContentTypeFromFilePath(filePath, opts?.defaultTs);
59430
59525
  const content = await readFile5(filePath, "utf-8");
59431
59526
  const input = opts.data ? await resolve6(opts.data) : {};
59527
+ const isFolderLayout = isModuleEntryPoint(filePath);
59528
+ const moduleFolderPath = isFolderLayout ? path5.dirname(filePath) : filePath.substring(0, filePath.indexOf(".")) + getModuleFolderSuffix();
59529
+ const modules = await readModulesFromDisk(moduleFolderPath, opts?.defaultTs, isFolderLayout);
59432
59530
  const codebase = language == "bun" ? findCodebase(filePath, codebases) : undefined;
59433
59531
  let bundledContent = undefined;
59434
59532
  let isTar = false;
@@ -59552,7 +59650,8 @@ async function preview(opts, filePath) {
59552
59650
  content,
59553
59651
  path: filePath.substring(0, filePath.indexOf(".")).replaceAll(SEP4, "/"),
59554
59652
  args: input,
59555
- language
59653
+ language,
59654
+ modules: modules ?? undefined
59556
59655
  }
59557
59656
  });
59558
59657
  if (opts.silent) {
@@ -59622,7 +59721,7 @@ var init_script = __esm(async () => {
59622
59721
  // src/commands/lint/lint.ts
59623
59722
  import { stat as stat4, readdir as readdir2 } from "node:fs/promises";
59624
59723
  import process12 from "node:process";
59625
- import * as path5 from "node:path";
59724
+ import * as path6 from "node:path";
59626
59725
  import { sep as SEP5 } from "node:path";
59627
59726
  function normalizePath(p) {
59628
59727
  return p.replaceAll(SEP5, "/");
@@ -59681,7 +59780,7 @@ async function isLockResolved(lockValue, baseDir) {
59681
59780
  return true;
59682
59781
  }
59683
59782
  async function checkInlineFile(relativePath, baseDir) {
59684
- const fullPath = path5.join(baseDir, relativePath.trim());
59783
+ const fullPath = path6.join(baseDir, relativePath.trim());
59685
59784
  try {
59686
59785
  const s = await stat4(fullPath);
59687
59786
  return s.size > 0;
@@ -59771,7 +59870,7 @@ async function checkRawAppRunnables(backendDir, rawAppYamlPath, defaultTs) {
59771
59870
  continue;
59772
59871
  const runnableId = fileName.replace(".yaml", "");
59773
59872
  processedIds.add(runnableId);
59774
- const filePath = path5.join(backendDir, fileName);
59873
+ const filePath = path6.join(backendDir, fileName);
59775
59874
  let runnable;
59776
59875
  try {
59777
59876
  runnable = await yamlParseFile(filePath);
@@ -59789,7 +59888,7 @@ async function checkRawAppRunnables(backendDir, rawAppYamlPath, defaultTs) {
59789
59888
  }
59790
59889
  if (!language || !languageNeedsLock(language))
59791
59890
  continue;
59792
- const lockFile = path5.join(backendDir, `${runnableId}.lock`);
59891
+ const lockFile = path6.join(backendDir, `${runnableId}.lock`);
59793
59892
  let hasLock = false;
59794
59893
  try {
59795
59894
  const s = await stat4(lockFile);
@@ -59836,7 +59935,7 @@ async function checkRawAppRunnables(backendDir, rawAppYamlPath, defaultTs) {
59836
59935
  }
59837
59936
  if (!languageNeedsLock(language))
59838
59937
  continue;
59839
- const lockFile = path5.join(backendDir, `${runnableId}.lock`);
59938
+ const lockFile = path6.join(backendDir, `${runnableId}.lock`);
59840
59939
  let hasLock = false;
59841
59940
  try {
59842
59941
  const s = await stat4(lockFile);
@@ -59856,7 +59955,7 @@ async function checkRawAppRunnables(backendDir, rawAppYamlPath, defaultTs) {
59856
59955
  }
59857
59956
  async function checkMissingLocks(opts, directory) {
59858
59957
  const initialCwd = process12.cwd();
59859
- const targetDirectory = directory ? path5.resolve(initialCwd, directory) : process12.cwd();
59958
+ const targetDirectory = directory ? path6.resolve(initialCwd, directory) : process12.cwd();
59860
59959
  const { ...syncOpts } = opts;
59861
59960
  const mergedOpts = await mergeConfigWithConfigFile(syncOpts);
59862
59961
  const ignore = await ignoreF(mergedOpts);
@@ -59880,19 +59979,19 @@ async function checkMissingLocks(opts, directory) {
59880
59979
  if (normalizedPath.endsWith("/flow.yaml") && normalizedPath.includes(flowSuffix + "/")) {
59881
59980
  flowYamls.push({
59882
59981
  normalizedPath,
59883
- fullPath: path5.join(targetDirectory, entry.path)
59982
+ fullPath: path6.join(targetDirectory, entry.path)
59884
59983
  });
59885
59984
  }
59886
59985
  if (normalizedPath.endsWith("/app.yaml") && normalizedPath.includes(appSuffix + "/")) {
59887
59986
  appYamls.push({
59888
59987
  normalizedPath,
59889
- fullPath: path5.join(targetDirectory, entry.path)
59988
+ fullPath: path6.join(targetDirectory, entry.path)
59890
59989
  });
59891
59990
  }
59892
59991
  if (normalizedPath.endsWith("/raw_app.yaml") && normalizedPath.includes(rawAppSuffix + "/")) {
59893
59992
  rawAppYamls.push({
59894
59993
  normalizedPath,
59895
- fullPath: path5.join(targetDirectory, entry.path)
59994
+ fullPath: path6.join(targetDirectory, entry.path)
59896
59995
  });
59897
59996
  }
59898
59997
  }
@@ -59901,14 +60000,14 @@ async function checkMissingLocks(opts, directory) {
59901
60000
  let language = null;
59902
60001
  for (const ext2 of exts) {
59903
60002
  try {
59904
- await stat4(path5.join(targetDirectory, basePath + ext2));
60003
+ await stat4(path6.join(targetDirectory, basePath + ext2));
59905
60004
  language = inferContentTypeFromFilePath(basePath + ext2, defaultTs);
59906
60005
  break;
59907
60006
  } catch {}
59908
60007
  }
59909
60008
  if (language && languageNeedsLock(language)) {
59910
60009
  try {
59911
- const metadata = await yamlParseFile(path5.join(targetDirectory, yamlPath));
60010
+ const metadata = await yamlParseFile(path6.join(targetDirectory, yamlPath));
59912
60011
  const lockResolved = await isLockResolved(metadata?.lock, targetDirectory);
59913
60012
  if (!lockResolved) {
59914
60013
  issues.push({
@@ -59925,7 +60024,7 @@ async function checkMissingLocks(opts, directory) {
59925
60024
  }
59926
60025
  }
59927
60026
  for (const { normalizedPath: flowYamlPath, fullPath } of flowYamls) {
59928
- const flowDir = path5.dirname(fullPath);
60027
+ const flowDir = path6.dirname(fullPath);
59929
60028
  try {
59930
60029
  const flowFile = await yamlParseFile(fullPath);
59931
60030
  if (!flowFile?.value?.modules)
@@ -59950,7 +60049,7 @@ async function checkMissingLocks(opts, directory) {
59950
60049
  }
59951
60050
  }
59952
60051
  for (const { normalizedPath: appYamlPath, fullPath } of appYamls) {
59953
- const appDir = path5.dirname(fullPath);
60052
+ const appDir = path6.dirname(fullPath);
59954
60053
  try {
59955
60054
  const appFile = await yamlParseFile(fullPath);
59956
60055
  if (!appFile?.value)
@@ -59975,8 +60074,8 @@ async function checkMissingLocks(opts, directory) {
59975
60074
  }
59976
60075
  }
59977
60076
  for (const { normalizedPath: rawAppYamlPath, fullPath } of rawAppYamls) {
59978
- const rawAppDir = path5.dirname(fullPath);
59979
- const backendDir = path5.join(rawAppDir, "backend");
60077
+ const rawAppDir = path6.dirname(fullPath);
60078
+ const backendDir = path6.join(rawAppDir, "backend");
59980
60079
  try {
59981
60080
  await stat4(backendDir);
59982
60081
  } catch {
@@ -59993,7 +60092,7 @@ async function checkMissingLocks(opts, directory) {
59993
60092
  }
59994
60093
  async function runLint(opts, directory) {
59995
60094
  const initialCwd = process12.cwd();
59996
- const explicitTargetDirectory = directory ? path5.resolve(initialCwd, directory) : undefined;
60095
+ const explicitTargetDirectory = directory ? path6.resolve(initialCwd, directory) : undefined;
59997
60096
  const { json: _json, ...syncOpts } = opts;
59998
60097
  const mergedOpts = await mergeConfigWithConfigFile(syncOpts);
59999
60098
  const targetDirectory = explicitTargetDirectory ?? process12.cwd();
@@ -60255,11 +60354,11 @@ async function list3(opts) {
60255
60354
  new Table2().header(["Path", "Resource Type"]).padding(2).border(true).body(total.map((x) => [x.path, x.resource_type])).render();
60256
60355
  }
60257
60356
  }
60258
- async function newResource(opts, path6) {
60259
- if (!validatePath(path6)) {
60357
+ async function newResource(opts, path7) {
60358
+ if (!validatePath(path7)) {
60260
60359
  return;
60261
60360
  }
60262
- const filePath = path6 + ".resource.yaml";
60361
+ const filePath = path7 + ".resource.yaml";
60263
60362
  try {
60264
60363
  await stat5(filePath);
60265
60364
  throw new Error("File already exists: " + filePath);
@@ -60278,12 +60377,12 @@ async function newResource(opts, path6) {
60278
60377
  });
60279
60378
  info(colors.green(`Created ${filePath}`));
60280
60379
  }
60281
- async function get2(opts, path6) {
60380
+ async function get2(opts, path7) {
60282
60381
  const workspace = await resolveWorkspace(opts);
60283
60382
  await requireLogin(opts);
60284
60383
  const r = await getResource({
60285
60384
  workspace: workspace.workspaceId,
60286
- path: path6
60385
+ path: path7
60287
60386
  });
60288
60387
  if (opts.json) {
60289
60388
  console.log(JSON.stringify(r));
@@ -60435,11 +60534,11 @@ var init_path_assigner = __esm(() => {
60435
60534
  // windmill-utils-internal/src/inline-scripts/extractor.ts
60436
60535
  function extractRawscriptInline(id, summary, rawscript, mapping, separator, assigner) {
60437
60536
  const [basePath, ext2] = assigner.assignPath(summary ?? id, rawscript.language);
60438
- const path6 = mapping[id] ?? basePath + ext2;
60537
+ const path7 = mapping[id] ?? basePath + ext2;
60439
60538
  const language = rawscript.language;
60440
60539
  const content = rawscript.content;
60441
- const r = [{ path: path6, content, language, is_lock: false }];
60442
- rawscript.content = "!inline " + path6.replaceAll(separator, "/");
60540
+ const r = [{ path: path7, content, language, is_lock: false }];
60541
+ rawscript.content = "!inline " + path7.replaceAll(separator, "/");
60443
60542
  const lock = rawscript.lock;
60444
60543
  if (lock && lock != "") {
60445
60544
  const lockPath = basePath + "lock";
@@ -60486,13 +60585,13 @@ async function replaceRawscriptInline(id, rawscript, fileReader, logger, separat
60486
60585
  if (!rawscript.content || !rawscript.content.startsWith("!inline")) {
60487
60586
  return;
60488
60587
  }
60489
- const path6 = rawscript.content.split(" ")[1];
60490
- const pathSuffix = path6.split(".").slice(1).join(".");
60588
+ const path7 = rawscript.content.split(" ")[1];
60589
+ const pathSuffix = path7.split(".").slice(1).join(".");
60491
60590
  const newPath = id + "." + pathSuffix;
60492
60591
  try {
60493
- rawscript.content = await fileReader(path6);
60592
+ rawscript.content = await fileReader(path7);
60494
60593
  } catch {
60495
- logger.error(`Script file ${path6} not found`);
60594
+ logger.error(`Script file ${path7} not found`);
60496
60595
  try {
60497
60596
  rawscript.content = await fileReader(newPath);
60498
60597
  } catch {
@@ -60500,7 +60599,7 @@ async function replaceRawscriptInline(id, rawscript, fileReader, logger, separat
60500
60599
  }
60501
60600
  }
60502
60601
  const lock = rawscript.lock;
60503
- if (removeLocks && removeLocks.includes(path6)) {
60602
+ if (removeLocks && removeLocks.includes(path7)) {
60504
60603
  rawscript.lock = undefined;
60505
60604
  } else if (lock && typeof lock === "string" && lock.trimStart().startsWith("!inline ")) {
60506
60605
  const lockPath = lock.split(" ")[1];
@@ -60546,11 +60645,11 @@ async function replaceInlineScripts(modules, fileReader, logger = {
60546
60645
  }
60547
60646
 
60548
60647
  // src/commands/flow/flow_metadata.ts
60549
- import * as path6 from "node:path";
60648
+ import * as path7 from "node:path";
60550
60649
  import { sep as SEP7 } from "node:path";
60551
60650
  import { readFile as readFile7 } from "node:fs/promises";
60552
60651
  async function generateFlowHash(rawWorkspaceDependencies, folder, defaultTs) {
60553
- const elems = await FSFSElement(path6.join(process.cwd(), folder), [], true);
60652
+ const elems = await FSFSElement(path7.join(process.cwd(), folder), [], true);
60554
60653
  const hashes = {};
60555
60654
  for await (const f of elems.getChildren()) {
60556
60655
  if (exts.some((e) => f.path.endsWith(e))) {
@@ -60586,18 +60685,18 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
60586
60685
  }
60587
60686
  let changedScripts = [];
60588
60687
  if (!justUpdateMetadataLock) {
60589
- for (const [path7, hash2] of Object.entries(hashes)) {
60590
- if (path7 == TOP_HASH) {
60688
+ for (const [path8, hash2] of Object.entries(hashes)) {
60689
+ if (path8 == TOP_HASH) {
60591
60690
  continue;
60592
60691
  }
60593
- if (!await checkifMetadataUptodate(folder, hash2, conf, path7)) {
60594
- changedScripts.push(path7);
60692
+ if (!await checkifMetadataUptodate(folder, hash2, conf, path8)) {
60693
+ changedScripts.push(path8);
60595
60694
  }
60596
60695
  }
60597
60696
  if (!noStaleMessage) {
60598
60697
  info(`Recomputing locks of ${changedScripts.join(", ")} in ${folder}`);
60599
60698
  }
60600
- const fileReader = async (path7) => await readFile7(folder + SEP7 + path7, "utf-8");
60699
+ const fileReader = async (path8) => await readFile7(folder + SEP7 + path8, "utf-8");
60601
60700
  await replaceInlineScripts(flowValue.value.modules, fileReader, exports_log, folder + SEP7, SEP7, changedScripts);
60602
60701
  if (flowValue.value.failure_module) {
60603
60702
  await replaceInlineScripts([flowValue.value.failure_module], fileReader, exports_log, folder + SEP7, SEP7, changedScripts);
@@ -60623,8 +60722,8 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
60623
60722
  }
60624
60723
  hashes = await generateFlowHash(filteredDeps, folder, opts.defaultTs);
60625
60724
  await clearGlobalLock(folder);
60626
- for (const [path7, hash2] of Object.entries(hashes)) {
60627
- await updateMetadataGlobalLock(folder, hash2, path7);
60725
+ for (const [path8, hash2] of Object.entries(hashes)) {
60726
+ await updateMetadataGlobalLock(folder, hash2, path8);
60628
60727
  }
60629
60728
  if (!noStaleMessage) {
60630
60729
  info(colors.green(`Flow ${remote_path} lockfiles updated`));
@@ -60739,7 +60838,7 @@ __export(exports_sync, {
60739
60838
  FSFSElement: () => FSFSElement
60740
60839
  });
60741
60840
  import { readFile as readFile8, writeFile as writeFile6, readdir as readdir4, stat as stat6, rm, copyFile, mkdir as mkdir3 } from "node:fs/promises";
60742
- import * as path7 from "node:path";
60841
+ import * as path8 from "node:path";
60743
60842
  import { sep as SEP8 } from "node:path";
60744
60843
  function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
60745
60844
  return Object.assign({}, effectiveOpts, cliOpts);
@@ -60747,8 +60846,8 @@ function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
60747
60846
  async function resolveEffectiveSyncOptions(workspace, localConfig, promotion, branchOverride) {
60748
60847
  return await getEffectiveSettings(localConfig, promotion, false, false, branchOverride);
60749
60848
  }
60750
- function findCodebase(path8, codebases) {
60751
- if (!path8.endsWith(".ts")) {
60849
+ function findCodebase(path9, codebases) {
60850
+ if (!path9.endsWith(".ts")) {
60752
60851
  return;
60753
60852
  }
60754
60853
  for (const c of codebases) {
@@ -60764,7 +60863,7 @@ function findCodebase(path8, codebases) {
60764
60863
  if (included) {
60765
60864
  break;
60766
60865
  }
60767
- if (minimatch(path8, r)) {
60866
+ if (minimatch(path9, r)) {
60768
60867
  included = true;
60769
60868
  }
60770
60869
  }
@@ -60772,7 +60871,7 @@ function findCodebase(path8, codebases) {
60772
60871
  c.excludes = [c.excludes];
60773
60872
  }
60774
60873
  for (const r of c.excludes ?? []) {
60775
- if (minimatch(path8, r)) {
60874
+ if (minimatch(path9, r)) {
60776
60875
  excluded = true;
60777
60876
  }
60778
60877
  }
@@ -60781,13 +60880,13 @@ function findCodebase(path8, codebases) {
60781
60880
  }
60782
60881
  }
60783
60882
  }
60784
- async function addCodebaseDigestIfRelevant(path8, content, codebases, ignoreCodebaseChanges) {
60785
- const isScript = path8.endsWith(".script.yaml");
60883
+ async function addCodebaseDigestIfRelevant(path9, content, codebases, ignoreCodebaseChanges) {
60884
+ const isScript = path9.endsWith(".script.yaml");
60786
60885
  if (!isScript) {
60787
60886
  return content;
60788
60887
  }
60789
60888
  let isTs = true;
60790
- const replacedPath = path8.replace(".script.yaml", ".ts");
60889
+ const replacedPath = path9.replace(".script.yaml", ".ts");
60791
60890
  try {
60792
60891
  await stat6(replacedPath);
60793
60892
  } catch {
@@ -60801,9 +60900,9 @@ async function addCodebaseDigestIfRelevant(path8, content, codebases, ignoreCode
60801
60900
  if (c) {
60802
60901
  let parsed;
60803
60902
  try {
60804
- parsed = yamlParseContent(path8, content);
60903
+ parsed = yamlParseContent(path9, content);
60805
60904
  } catch (error2) {
60806
- error(`Failed to parse YAML content for codebase digest at path: ${path8}`);
60905
+ error(`Failed to parse YAML content for codebase digest at path: ${path9}`);
60807
60906
  throw error2;
60808
60907
  }
60809
60908
  if (parsed && typeof parsed == "object") {
@@ -60815,7 +60914,7 @@ async function addCodebaseDigestIfRelevant(path8, content, codebases, ignoreCode
60815
60914
  parsed["lock"] = "";
60816
60915
  return import_yaml10.stringify(parsed, yamlOptions);
60817
60916
  } else {
60818
- throw Error(`Expected local yaml ${path8} to be an object, found: ${content} instead`);
60917
+ throw Error(`Expected local yaml ${path9} to be an object, found: ${content} instead`);
60819
60918
  }
60820
60919
  }
60821
60920
  }
@@ -60832,7 +60931,7 @@ async function FSFSElement(p, codebases, ignoreCodebaseChanges) {
60832
60931
  try {
60833
60932
  const entries = await readdir4(localP, { withFileTypes: true });
60834
60933
  for (const e of entries) {
60835
- yield _internal_element(path7.join(localP, e.name), e.isDirectory(), codebases2);
60934
+ yield _internal_element(path8.join(localP, e.name), e.isDirectory(), codebases2);
60836
60935
  }
60837
60936
  } catch (e) {
60838
60937
  warn(`Error reading dir: ${localP}, ${e}`);
@@ -61070,6 +61169,24 @@ async function findFilesetResourceFile(changePath) {
61070
61169
  throw new Error(`No resource metadata file found for fileset resource: ${changePath}`);
61071
61170
  }
61072
61171
  function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, resourceTypeToIsFileset, ignoreCodebaseChanges) {
61172
+ let _moduleScriptPaths = null;
61173
+ async function getModuleScriptPaths() {
61174
+ if (_moduleScriptPaths === null) {
61175
+ _moduleScriptPaths = new Set;
61176
+ for (const filename in zip.files) {
61177
+ if (filename.endsWith(".script.json") && !zip.files[filename].dir) {
61178
+ try {
61179
+ const content = await zip.files[filename].async("text");
61180
+ const parsed = JSON.parse(content);
61181
+ if (parsed.modules && Object.keys(parsed.modules).length > 0) {
61182
+ _moduleScriptPaths.add(filename.slice(0, -".script.json".length));
61183
+ }
61184
+ } catch {}
61185
+ }
61186
+ }
61187
+ }
61188
+ return _moduleScriptPaths;
61189
+ }
61073
61190
  async function _internal_file(p, f) {
61074
61191
  const kind = isFlowMetadataFile(p) ? "flow" : isAppMetadataFile(p) ? "app" : isRawAppMetadataFile(p) ? "raw_app" : p.endsWith(".script.json") ? "script" : p.endsWith(".resource.json") ? "resource" : p.startsWith("dependencies/") ? "dependencies" : "other";
61075
61192
  const isJson = p.endsWith(".json");
@@ -61086,7 +61203,20 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61086
61203
  return useYaml && isJson ? p.replaceAll(".json", ".yaml") : p;
61087
61204
  }
61088
61205
  }
61089
- const finalPath = transformPath();
61206
+ let finalPath = transformPath();
61207
+ if (kind == "other" && exts.some((ext2) => p.endsWith(ext2))) {
61208
+ const normalizedP = p.replace(/^\.[\\/]/, "");
61209
+ const moduleScripts = await getModuleScriptPaths();
61210
+ for (const basePath of moduleScripts) {
61211
+ if (normalizedP.startsWith(basePath + ".")) {
61212
+ const ext2 = normalizedP.slice(basePath.length);
61213
+ const dir = path8.dirname(finalPath);
61214
+ const base = path8.basename(basePath);
61215
+ finalPath = path8.join(dir, base + getModuleFolderSuffix(), "script" + ext2);
61216
+ break;
61217
+ }
61218
+ }
61219
+ }
61090
61220
  const r = [
61091
61221
  {
61092
61222
  isDirectory: kind == "flow" || kind == "app" || kind == "raw_app",
@@ -61117,7 +61247,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61117
61247
  for (const s of inlineScripts) {
61118
61248
  yield {
61119
61249
  isDirectory: false,
61120
- path: path7.join(finalPath, s.path),
61250
+ path: path8.join(finalPath, s.path),
61121
61251
  async* getChildren() {},
61122
61252
  async getContentText() {
61123
61253
  return s.content;
@@ -61126,7 +61256,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61126
61256
  }
61127
61257
  yield {
61128
61258
  isDirectory: false,
61129
- path: path7.join(finalPath, "flow.yaml"),
61259
+ path: path8.join(finalPath, "flow.yaml"),
61130
61260
  async* getChildren() {},
61131
61261
  async getContentText() {
61132
61262
  return import_yaml10.stringify(flow, yamlOptions);
@@ -61150,7 +61280,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61150
61280
  for (const s of inlineScripts) {
61151
61281
  yield {
61152
61282
  isDirectory: false,
61153
- path: path7.join(finalPath, s.path),
61283
+ path: path8.join(finalPath, s.path),
61154
61284
  async* getChildren() {},
61155
61285
  async getContentText() {
61156
61286
  return s.content;
@@ -61163,7 +61293,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61163
61293
  app.policy = undefined;
61164
61294
  yield {
61165
61295
  isDirectory: false,
61166
- path: path7.join(finalPath, "app.yaml"),
61296
+ path: path8.join(finalPath, "app.yaml"),
61167
61297
  async* getChildren() {},
61168
61298
  async getContentText() {
61169
61299
  return import_yaml10.stringify(app, yamlOptions);
@@ -61218,7 +61348,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61218
61348
  }
61219
61349
  yield {
61220
61350
  isDirectory: false,
61221
- path: path7.join(finalPath, filePath.substring(1)),
61351
+ path: path8.join(finalPath, filePath.substring(1)),
61222
61352
  async* getChildren() {},
61223
61353
  async getContentText() {
61224
61354
  if (typeof content !== "string") {
@@ -61235,7 +61365,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61235
61365
  for (const s of inlineScripts) {
61236
61366
  yield {
61237
61367
  isDirectory: false,
61238
- path: path7.join(finalPath, APP_BACKEND_FOLDER, s.path),
61368
+ path: path8.join(finalPath, APP_BACKEND_FOLDER, s.path),
61239
61369
  async* getChildren() {},
61240
61370
  async getContentText() {
61241
61371
  return s.content;
@@ -61271,7 +61401,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61271
61401
  }
61272
61402
  yield {
61273
61403
  isDirectory: false,
61274
- path: path7.join(finalPath, APP_BACKEND_FOLDER, `${runnableId}.yaml`),
61404
+ path: path8.join(finalPath, APP_BACKEND_FOLDER, `${runnableId}.yaml`),
61275
61405
  async* getChildren() {},
61276
61406
  async getContentText() {
61277
61407
  return import_yaml10.stringify(simplifiedRunnable, yamlOptions);
@@ -61285,7 +61415,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61285
61415
  delete rawApp?.["value"];
61286
61416
  yield {
61287
61417
  isDirectory: false,
61288
- path: path7.join(finalPath, "raw_app.yaml"),
61418
+ path: path8.join(finalPath, "raw_app.yaml"),
61289
61419
  async* getChildren() {},
61290
61420
  async getContentText() {
61291
61421
  return import_yaml10.stringify(rawApp, yamlOptions);
@@ -61293,7 +61423,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61293
61423
  };
61294
61424
  yield {
61295
61425
  isDirectory: false,
61296
- path: path7.join(finalPath, "DATATABLES.md"),
61426
+ path: path8.join(finalPath, "DATATABLES.md"),
61297
61427
  async* getChildren() {},
61298
61428
  async getContentText() {
61299
61429
  return generateDatatablesDocumentation(data3);
@@ -61311,8 +61441,14 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61311
61441
  error(`Failed to parse script.yaml at path: ${p}`);
61312
61442
  throw error2;
61313
61443
  }
61444
+ const hasModules = parsed["modules"] && Object.keys(parsed["modules"]).length > 0;
61314
61445
  if (parsed["lock"] && parsed["lock"] != "" && parsed["codebase"] == undefined) {
61315
- parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(SEP8, "/"), ".json") + ".lock";
61446
+ if (hasModules) {
61447
+ const scriptBase = removeSuffix(removeSuffix(p.replaceAll(SEP8, "/"), ".json"), ".script");
61448
+ parsed["lock"] = "!inline " + scriptBase + getModuleFolderSuffix() + "/script.lock";
61449
+ } else {
61450
+ parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(SEP8, "/"), ".json") + ".lock";
61451
+ }
61316
61452
  } else if (parsed["lock"] == "") {
61317
61453
  parsed["lock"] = "";
61318
61454
  } else {
@@ -61321,6 +61457,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61321
61457
  if (ignoreCodebaseChanges && parsed["codebase"]) {
61322
61458
  parsed["codebase"] = undefined;
61323
61459
  }
61460
+ delete parsed["modules"];
61324
61461
  return useYaml ? import_yaml10.stringify(parsed, yamlOptions) : JSON.stringify(parsed, null, 2);
61325
61462
  }
61326
61463
  if (kind == "resource") {
@@ -61363,16 +61500,56 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61363
61500
  throw error2;
61364
61501
  }
61365
61502
  const lock = parsed["lock"];
61503
+ const scriptModules = parsed["modules"];
61504
+ const hasModules = scriptModules && Object.keys(scriptModules).length > 0;
61505
+ const metaExt = useYaml ? ".yaml" : ".json";
61506
+ const scriptBasePath = removeSuffix(removeSuffix(finalPath, metaExt), ".script");
61507
+ const moduleFolderPath = scriptBasePath + getModuleFolderSuffix();
61508
+ if (hasModules) {
61509
+ r[0].path = path8.join(moduleFolderPath, "script" + metaExt);
61510
+ }
61366
61511
  if (lock && lock != "") {
61367
61512
  r.push({
61368
61513
  isDirectory: false,
61369
- path: removeSuffix(finalPath, ".json") + ".lock",
61514
+ path: hasModules ? path8.join(moduleFolderPath, "script.lock") : removeSuffix(finalPath, metaExt) + ".lock",
61370
61515
  async* getChildren() {},
61371
61516
  async getContentText() {
61372
61517
  return lock;
61373
61518
  }
61374
61519
  });
61375
61520
  }
61521
+ if (hasModules) {
61522
+ r.push({
61523
+ isDirectory: true,
61524
+ path: moduleFolderPath,
61525
+ async* getChildren() {
61526
+ for (const [relPath, mod] of Object.entries(scriptModules)) {
61527
+ yield {
61528
+ isDirectory: false,
61529
+ path: path8.join(moduleFolderPath, relPath),
61530
+ async* getChildren() {},
61531
+ async getContentText() {
61532
+ return mod.content;
61533
+ }
61534
+ };
61535
+ if (mod.lock) {
61536
+ const baseName = relPath.replace(/\.[^.]+$/, "");
61537
+ yield {
61538
+ isDirectory: false,
61539
+ path: path8.join(moduleFolderPath, baseName + ".lock"),
61540
+ async* getChildren() {},
61541
+ async getContentText() {
61542
+ return mod.lock;
61543
+ }
61544
+ };
61545
+ }
61546
+ }
61547
+ },
61548
+ async getContentText() {
61549
+ throw new Error("Cannot get content of directory");
61550
+ }
61551
+ });
61552
+ }
61376
61553
  }
61377
61554
  if (kind == "resource") {
61378
61555
  const content = await f.async("text");
@@ -61396,7 +61573,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61396
61573
  if (typeof fileContent === "string") {
61397
61574
  yield {
61398
61575
  isDirectory: false,
61399
- path: path7.join(filesetBasePath, relPath),
61576
+ path: path8.join(filesetBasePath, relPath),
61400
61577
  async* getChildren() {},
61401
61578
  async getContentText() {
61402
61579
  return fileContent;
@@ -61432,7 +61609,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
61432
61609
  async* getChildren() {
61433
61610
  for (const filename in zip2.files) {
61434
61611
  const file = zip2.files[filename];
61435
- const totalPath = path7.join(p, filename);
61612
+ const totalPath = path8.join(p, filename);
61436
61613
  if (file.dir) {
61437
61614
  const e = zip2.folder(file.name);
61438
61615
  yield _internal_folder(totalPath, e);
@@ -61491,11 +61668,15 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
61491
61668
  if (entry.isDirectory || entry.ignored) {
61492
61669
  continue;
61493
61670
  }
61494
- const path8 = entry.path;
61495
- if (!isFileResource(path8) && !isFilesetResource(path8) && !isRawAppFile(path8) && !isWorkspaceDependencies(path8)) {
61496
- if (json && path8.endsWith(".yaml"))
61671
+ const path9 = entry.path;
61672
+ if (isScriptModulePath(path9)) {
61673
+ map[path9] = await entry.getContentText();
61674
+ continue;
61675
+ }
61676
+ if (!isFileResource(path9) && !isFilesetResource(path9) && !isRawAppFile(path9) && !isWorkspaceDependencies(path9)) {
61677
+ if (json && path9.endsWith(".yaml"))
61497
61678
  continue;
61498
- if (!json && path8.endsWith(".json"))
61679
+ if (!json && path9.endsWith(".json"))
61499
61680
  continue;
61500
61681
  if (![
61501
61682
  "json",
@@ -61516,39 +61697,39 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
61516
61697
  "nu",
61517
61698
  "java",
61518
61699
  "rb"
61519
- ].includes(path8.split(".").pop() ?? "")) {
61700
+ ].includes(path9.split(".").pop() ?? "")) {
61520
61701
  continue;
61521
61702
  }
61522
61703
  }
61523
- if (isRawAppFile(path8)) {
61524
- const suffix = path8.split(getFolderSuffix("raw_app") + SEP8).pop();
61704
+ if (isRawAppFile(path9)) {
61705
+ const suffix = path9.split(getFolderSuffix("raw_app") + SEP8).pop();
61525
61706
  if (suffix?.startsWith("dist/") || suffix == "wmill.d.ts" || suffix == "package-lock.json" || suffix == "DATATABLES.md") {
61526
61707
  continue;
61527
61708
  }
61528
61709
  }
61529
- if (skips.skipResources && (isFileResource(path8) || isFilesetResource(path8)))
61710
+ if (skips.skipResources && (isFileResource(path9) || isFilesetResource(path9)))
61530
61711
  continue;
61531
61712
  const ext2 = json ? ".json" : ".yaml";
61532
- if (!skips.includeSchedules && path8.endsWith(".schedule" + ext2))
61713
+ if (!skips.includeSchedules && path9.endsWith(".schedule" + ext2))
61533
61714
  continue;
61534
- if (!skips.includeTriggers && (path8.endsWith(".http_trigger" + ext2) || path8.endsWith(".websocket_trigger" + ext2) || path8.endsWith(".kafka_trigger" + ext2) || path8.endsWith(".nats_trigger" + ext2) || path8.endsWith(".postgres_trigger" + ext2) || path8.endsWith(".mqtt_trigger" + ext2) || path8.endsWith(".sqs_trigger" + ext2) || path8.endsWith(".gcp_trigger" + ext2) || path8.endsWith(".email_trigger" + ext2) || path8.endsWith("_native_trigger" + ext2))) {
61715
+ if (!skips.includeTriggers && (path9.endsWith(".http_trigger" + ext2) || path9.endsWith(".websocket_trigger" + ext2) || path9.endsWith(".kafka_trigger" + ext2) || path9.endsWith(".nats_trigger" + ext2) || path9.endsWith(".postgres_trigger" + ext2) || path9.endsWith(".mqtt_trigger" + ext2) || path9.endsWith(".sqs_trigger" + ext2) || path9.endsWith(".gcp_trigger" + ext2) || path9.endsWith(".email_trigger" + ext2) || path9.endsWith("_native_trigger" + ext2))) {
61535
61716
  continue;
61536
61717
  }
61537
- if (!skips.includeUsers && path8.endsWith(".user" + ext2))
61718
+ if (!skips.includeUsers && path9.endsWith(".user" + ext2))
61538
61719
  continue;
61539
- if (!skips.includeGroups && path8.endsWith(".group" + ext2))
61720
+ if (!skips.includeGroups && path9.endsWith(".group" + ext2))
61540
61721
  continue;
61541
- if (!skips.includeSettings && path8 === "settings" + ext2)
61722
+ if (!skips.includeSettings && path9 === "settings" + ext2)
61542
61723
  continue;
61543
- if (!skips.includeKey && path8 === "encryption_key")
61724
+ if (!skips.includeKey && path9 === "encryption_key")
61544
61725
  continue;
61545
- if (skips.skipResources && path8.endsWith(".resource" + ext2))
61726
+ if (skips.skipResources && path9.endsWith(".resource" + ext2))
61546
61727
  continue;
61547
- if (skips.skipResourceTypes && path8.endsWith(".resource-type" + ext2)) {
61728
+ if (skips.skipResourceTypes && path9.endsWith(".resource-type" + ext2)) {
61548
61729
  continue;
61549
61730
  }
61550
61731
  try {
61551
- const fileType = getTypeStrFromPath(path8);
61732
+ const fileType = getTypeStrFromPath(path9);
61552
61733
  if (skips.skipVariables && fileType === "variable")
61553
61734
  continue;
61554
61735
  if (skips.skipScripts && fileType === "script")
@@ -61562,27 +61743,27 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
61562
61743
  if (skips.skipWorkspaceDependencies && fileType === "workspace_dependencies")
61563
61744
  continue;
61564
61745
  } catch {}
61565
- if (specificItems && isBranchSpecificFile(path8)) {
61566
- if (!isCurrentBranchFile(path8, cachedBranch)) {
61746
+ if (specificItems && isBranchSpecificFile(path9)) {
61747
+ if (!isCurrentBranchFile(path9, cachedBranch)) {
61567
61748
  continue;
61568
61749
  }
61569
61750
  }
61570
61751
  const content = await entry.getContentText();
61571
- if (skips.skipSecrets && path8.endsWith(".variable" + ext2)) {
61752
+ if (skips.skipSecrets && path9.endsWith(".variable" + ext2)) {
61572
61753
  try {
61573
61754
  let o;
61574
61755
  if (json) {
61575
61756
  try {
61576
61757
  o = JSON.parse(content);
61577
61758
  } catch (error2) {
61578
- error(`Failed to parse JSON variable content at path: ${path8}`);
61759
+ error(`Failed to parse JSON variable content at path: ${path9}`);
61579
61760
  throw error2;
61580
61761
  }
61581
61762
  } else {
61582
61763
  try {
61583
- o = yamlParseContent(path8, content);
61764
+ o = yamlParseContent(path9, content);
61584
61765
  } catch (error2) {
61585
- error(`Failed to parse YAML variable content at path: ${path8}`);
61766
+ error(`Failed to parse YAML variable content at path: ${path9}`);
61586
61767
  throw error2;
61587
61768
  }
61588
61769
  }
@@ -61590,12 +61771,12 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
61590
61771
  continue;
61591
61772
  }
61592
61773
  } catch (e) {
61593
- warn(`Error reading variable ${path8} to check for secrets`);
61774
+ warn(`Error reading variable ${path9} to check for secrets`);
61594
61775
  }
61595
61776
  }
61596
- if (cachedBranch && isCurrentBranchFile(path8, cachedBranch)) {
61777
+ if (cachedBranch && isCurrentBranchFile(path9, cachedBranch)) {
61597
61778
  const currentBranch = cachedBranch;
61598
- const basePath = fromBranchSpecificPath(path8, currentBranch);
61779
+ const basePath = fromBranchSpecificPath(path9, currentBranch);
61599
61780
  if (!isItemTypeConfigured(basePath, specificItems)) {
61600
61781
  continue;
61601
61782
  }
@@ -61604,14 +61785,14 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
61604
61785
  }
61605
61786
  map[basePath] = content;
61606
61787
  processedBasePaths.add(basePath);
61607
- } else if (!isBranchSpecificFile(path8)) {
61608
- if (processedBasePaths.has(path8)) {
61788
+ } else if (!isBranchSpecificFile(path9)) {
61789
+ if (processedBasePaths.has(path9)) {
61609
61790
  continue;
61610
61791
  }
61611
- if (!isRemote && isSpecificItem(path8, specificItems)) {
61792
+ if (!isRemote && isSpecificItem(path9, specificItems)) {
61612
61793
  continue;
61613
61794
  }
61614
- map[path8] = content;
61795
+ map[path9] = content;
61615
61796
  }
61616
61797
  }
61617
61798
  return map;
@@ -61868,6 +62049,31 @@ async function addToChangedIfNotExists(p, tracker) {
61868
62049
  if (!tracker.rawApps.includes(folder)) {
61869
62050
  tracker.rawApps.push(folder);
61870
62051
  }
62052
+ } else if (isScriptModulePath(p)) {
62053
+ if (isModuleEntryPoint(p)) {
62054
+ if (!tracker.scripts.includes(p)) {
62055
+ tracker.scripts.push(p);
62056
+ }
62057
+ } else {
62058
+ const moduleSuffix = getModuleFolderSuffix() + "/";
62059
+ const idx = p.indexOf(moduleSuffix);
62060
+ if (idx !== -1) {
62061
+ const scriptBasePath = p.substring(0, idx);
62062
+ try {
62063
+ const contentPath = await findContentFile(scriptBasePath + getModuleFolderSuffix() + "/script.yaml");
62064
+ if (contentPath && !tracker.scripts.includes(contentPath)) {
62065
+ tracker.scripts.push(contentPath);
62066
+ }
62067
+ } catch {
62068
+ try {
62069
+ const contentPath = await findContentFile(scriptBasePath + ".script.yaml");
62070
+ if (contentPath && !tracker.scripts.includes(contentPath)) {
62071
+ tracker.scripts.push(contentPath);
62072
+ }
62073
+ } catch {}
62074
+ }
62075
+ }
62076
+ }
61871
62077
  } else {
61872
62078
  if (!tracker.scripts.includes(p)) {
61873
62079
  tracker.scripts.push(p);
@@ -61898,6 +62104,29 @@ async function buildTracker(changes) {
61898
62104
  }
61899
62105
  return tracker;
61900
62106
  }
62107
+ async function pushParentScriptForModule(modulePath, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases) {
62108
+ const moduleSuffix = getModuleFolderSuffix() + "/";
62109
+ const idx = modulePath.indexOf(moduleSuffix);
62110
+ if (idx === -1)
62111
+ return;
62112
+ const scriptBasePath = modulePath.substring(0, idx);
62113
+ const moduleFolderPath = scriptBasePath + getModuleFolderSuffix();
62114
+ try {
62115
+ const entryPoint = await findContentFile(moduleFolderPath + "/script.yaml");
62116
+ if (entryPoint) {
62117
+ await handleFile(entryPoint, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases);
62118
+ return;
62119
+ }
62120
+ } catch {}
62121
+ try {
62122
+ const contentPath = await findContentFile(scriptBasePath + ".script.yaml");
62123
+ if (contentPath) {
62124
+ await handleFile(contentPath, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases);
62125
+ }
62126
+ } catch {
62127
+ debug(`Could not find parent script for module: ${modulePath}`);
62128
+ }
62129
+ }
61901
62130
  async function pull(opts) {
61902
62131
  const originalCliOpts = { ...opts };
61903
62132
  opts = await mergeConfigWithConfigFile(opts);
@@ -61911,7 +62140,7 @@ async function pull(opts) {
61911
62140
  throw error2;
61912
62141
  }
61913
62142
  if (opts.stateful) {
61914
- await mkdir3(path7.join(process.cwd(), ".wmill"), { recursive: true });
62143
+ await mkdir3(path8.join(process.cwd(), ".wmill"), { recursive: true });
61915
62144
  }
61916
62145
  const workspace = await resolveWorkspace(opts, opts.branch);
61917
62146
  await requireLogin(opts);
@@ -61932,7 +62161,7 @@ async function pull(opts) {
61932
62161
  } catch {}
61933
62162
  const zipFile = await downloadZip(workspace, opts.plainSecrets, opts.skipVariables, opts.skipResources, opts.skipResourceTypes, opts.skipSecrets, opts.includeSchedules, opts.includeTriggers, opts.includeUsers, opts.includeGroups, opts.includeSettings, opts.includeKey, opts.skipWorkspaceDependencies, opts.defaultTs);
61934
62163
  const remote = ZipFSElement(zipFile, !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, true);
61935
- const local = !opts.stateful ? await FSFSElement(process.cwd(), codebases, true) : await FSFSElement(path7.join(process.cwd(), ".wmill"), [], true);
62164
+ const local = !opts.stateful ? await FSFSElement(process.cwd(), codebases, true) : await FSFSElement(path8.join(process.cwd(), ".wmill"), [], true);
61936
62165
  const changes = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, opts.branch, true);
61937
62166
  info(`remote (${workspace.name}) -> local: ${changes.length} changes to apply`);
61938
62167
  if (opts.dryRun && opts.jsonOutput) {
@@ -61976,8 +62205,8 @@ async function pull(opts) {
61976
62205
  targetPath = branchSpecificPath;
61977
62206
  }
61978
62207
  }
61979
- const target = path7.join(process.cwd(), targetPath);
61980
- const stateTarget = path7.join(process.cwd(), ".wmill", targetPath);
62208
+ const target = path8.join(process.cwd(), targetPath);
62209
+ const stateTarget = path8.join(process.cwd(), ".wmill", targetPath);
61981
62210
  if (change.name === "edited") {
61982
62211
  if (opts.stateful) {
61983
62212
  try {
@@ -62010,13 +62239,13 @@ Both local and remote have been modified.`));
62010
62239
  }
62011
62240
  await writeFile6(target, change.after, "utf-8");
62012
62241
  if (opts.stateful) {
62013
- await mkdir3(path7.dirname(stateTarget), { recursive: true });
62242
+ await mkdir3(path8.dirname(stateTarget), { recursive: true });
62014
62243
  await copyFile(target, stateTarget);
62015
62244
  }
62016
62245
  } else if (change.name === "added") {
62017
- await mkdir3(path7.dirname(target), { recursive: true });
62246
+ await mkdir3(path8.dirname(target), { recursive: true });
62018
62247
  if (opts.stateful) {
62019
- await mkdir3(path7.dirname(stateTarget), { recursive: true });
62248
+ await mkdir3(path8.dirname(stateTarget), { recursive: true });
62020
62249
  info(`Adding ${getTypeStrFromPath(change.path)} ${targetPath}${targetPath !== change.path ? colors.gray(` (branch-specific override for ${change.path})`) : ""}`);
62021
62250
  }
62022
62251
  await writeFile6(target, change.content, "utf-8");
@@ -62198,7 +62427,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
62198
62427
  resourceTypeToIsFileset = parsed.filesetMap;
62199
62428
  } catch {}
62200
62429
  const remote = ZipFSElement(await downloadZip(workspace, opts.plainSecrets, opts.skipVariables, opts.skipResources, opts.skipResourceTypes, opts.skipSecrets, opts.includeSchedules, opts.includeTriggers, opts.includeUsers, opts.includeGroups, opts.includeSettings, opts.includeKey, opts.skipWorkspaceDependencies, opts.defaultTs), !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, false);
62201
- const local = await FSFSElement(path7.join(process.cwd(), ""), codebases, false);
62430
+ const local = await FSFSElement(path8.join(process.cwd(), ""), codebases, false);
62202
62431
  const changes = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, opts.branch, false);
62203
62432
  const rawWorkspaceDependencies = await getRawWorkspaceDependencies();
62204
62433
  const tracker = await buildTracker(changes);
@@ -62264,7 +62493,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
62264
62493
  }
62265
62494
  for (const folderName of folderNames) {
62266
62495
  try {
62267
- await stat6(path7.join("f", folderName, "folder.meta.yaml"));
62496
+ await stat6(path8.join("f", folderName, "folder.meta.yaml"));
62268
62497
  } catch {
62269
62498
  missingFolders.push(folderName);
62270
62499
  }
@@ -62326,7 +62555,7 @@ ${folderList}
62326
62555
  let stateful = opts.stateful;
62327
62556
  if (stateful) {
62328
62557
  try {
62329
- await stat6(path7.join(process.cwd(), ".wmill"));
62558
+ await stat6(path8.join(process.cwd(), ".wmill"));
62330
62559
  } catch {
62331
62560
  stateful = false;
62332
62561
  }
@@ -62370,7 +62599,7 @@ ${folderList}
62370
62599
  let stateTarget = undefined;
62371
62600
  if (stateful) {
62372
62601
  try {
62373
- stateTarget = path7.join(process.cwd(), ".wmill", change.path);
62602
+ stateTarget = path8.join(process.cwd(), ".wmill", change.path);
62374
62603
  await stat6(stateTarget);
62375
62604
  } catch {
62376
62605
  stateTarget = undefined;
@@ -62387,9 +62616,15 @@ ${folderList}
62387
62616
  await writeFile6(stateTarget, change.after, "utf-8");
62388
62617
  }
62389
62618
  continue;
62619
+ } else if (isScriptModulePath(change.path)) {
62620
+ await pushParentScriptForModule(change.path, workspace, alreadySynced, opts.message, opts, rawWorkspaceDependencies, codebases);
62621
+ if (stateTarget) {
62622
+ await writeFile6(stateTarget, change.after, "utf-8");
62623
+ }
62624
+ continue;
62390
62625
  }
62391
62626
  if (stateTarget) {
62392
- await mkdir3(path7.dirname(stateTarget), { recursive: true });
62627
+ await mkdir3(path8.dirname(stateTarget), { recursive: true });
62393
62628
  info(`Editing ${getTypeStrFromPath(change.path)} ${change.path}`);
62394
62629
  }
62395
62630
  if (isFileResource(change.path)) {
@@ -62441,9 +62676,12 @@ ${folderList}
62441
62676
  continue;
62442
62677
  } else if (await handleFile(change.path, workspace, alreadySynced, opts.message, opts, rawWorkspaceDependencies, codebases)) {
62443
62678
  continue;
62679
+ } else if (isScriptModulePath(change.path)) {
62680
+ await pushParentScriptForModule(change.path, workspace, alreadySynced, opts.message, opts, rawWorkspaceDependencies, codebases);
62681
+ continue;
62444
62682
  }
62445
62683
  if (stateTarget) {
62446
- await mkdir3(path7.dirname(stateTarget), { recursive: true });
62684
+ await mkdir3(path8.dirname(stateTarget), { recursive: true });
62447
62685
  info(`Adding ${getTypeStrFromPath(change.path)} ${change.path}`);
62448
62686
  }
62449
62687
  const obj = parseFromPath(change.path, change.content);
@@ -62462,6 +62700,10 @@ ${folderList}
62462
62700
  if (change.path.endsWith(".lock")) {
62463
62701
  continue;
62464
62702
  }
62703
+ if (isScriptModulePath(change.path)) {
62704
+ await pushParentScriptForModule(change.path, workspace, alreadySynced, opts.message, opts, rawWorkspaceDependencies, codebases);
62705
+ continue;
62706
+ }
62465
62707
  const typ = getTypeStrFromPath(change.path);
62466
62708
  if (typ == "script") {
62467
62709
  info(`Archiving ${typ} ${change.path}`);
@@ -62720,6 +62962,9 @@ var import_yaml10, yamlOptions, isNotWmillFile = (p, isDirectory2) => {
62720
62962
  if (isDirectory2) {
62721
62963
  return !p.startsWith("u" + SEP8) && !p.startsWith("f" + SEP8) && !p.startsWith("g" + SEP8) && !p.startsWith("users" + SEP8) && !p.startsWith("groups" + SEP8) && !p.startsWith("dependencies" + SEP8);
62722
62964
  }
62965
+ if (isScriptModulePath(p)) {
62966
+ return false;
62967
+ }
62723
62968
  try {
62724
62969
  const typ = getTypeStrFromPath(p);
62725
62970
  if (typ == "resource-type" || typ == "settings" || typ == "encryption_key") {
@@ -62772,7 +63017,7 @@ var init_sync = __esm(async () => {
62772
63017
  aliasDuplicateObjects: false,
62773
63018
  singleQuote: true
62774
63019
  };
62775
- command6 = new Command().description("sync local with a remote workspaces or the opposite (push or pull)").action(() => info("2 actions available, pull and push. Use -h to display help.")).command("pull").description("Pull any remote changes and apply them locally.").option("--yes", "Pull without needing confirmation").option("--dry-run", "Show changes that would be pulled without actually pushing").option("--plain-secrets", "Pull secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Overrides wmill.yaml includes").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account. Overrides wmill.yaml excludes").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides").option("--branch <branch:string>", "Override the current git branch (works even outside a git repository)").action(pull).command("push").description("Push any local changes and apply them remotely.").option("--yes", "Push without needing confirmation").option("--dry-run", "Show changes that would be pushed without actually pushing").option("--plain-secrets", "Push secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--message <message:string>", "Include a message that will be added to all scripts/flows/apps updated during this push").option("--parallel <number>", "Number of changes to process in parallel").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--branch <branch:string>", "Override the current git branch (works even outside a git repository)").option("--lint", "Run lint validation before pushing").option("--locks-required", "Fail if scripts or flow inline scripts that need locks have no locks").action(push3);
63020
+ command6 = new Command().description("sync local with a remote workspaces or the opposite (push or pull)").action(() => info("2 actions available, pull and push. Use -h to display help.")).command("pull").description("Pull any remote changes and apply them locally.").option("--yes", "Pull without needing confirmation").option("--dry-run", "Show changes that would be pulled without actually pushing").option("--plain-secrets", "Pull secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Overrides wmill.yaml includes").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account. Overrides wmill.yaml excludes").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides").option("--branch, --env <branch:string>", "Override the current git branch/environment (works even outside a git repository)").action(pull).command("push").description("Push any local changes and apply them remotely.").option("--yes", "Push without needing confirmation").option("--dry-run", "Show changes that would be pushed without actually pushing").option("--plain-secrets", "Push secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--message <message:string>", "Include a message that will be added to all scripts/flows/apps updated during this push").option("--parallel <number>", "Number of changes to process in parallel").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--branch, --env <branch:string>", "Override the current git branch/environment (works even outside a git repository)").option("--lint", "Run lint validation before pushing").option("--locks-required", "Fail if scripts or flow inline scripts that need locks have no locks").action(push3);
62776
63021
  sync_default = command6;
62777
63022
  });
62778
63023
 
@@ -63003,7 +63248,8 @@ __export(exports_metadata, {
63003
63248
  });
63004
63249
  import { sep as SEP9 } from "node:path";
63005
63250
  import { readFile as readFile9, writeFile as writeFile7, stat as stat7, rm as rm2, readdir as readdir5 } from "node:fs/promises";
63006
- import { readFileSync as readFileSync3 } from "node:fs";
63251
+ import { readFileSync as readFileSync3, existsSync as existsSync4, readdirSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
63252
+ import * as path9 from "node:path";
63007
63253
  import { createRequire as createRequire2 } from "node:module";
63008
63254
  function loadParser(pkgName) {
63009
63255
  let p = _parserCache.get(pkgName);
@@ -63041,8 +63287,8 @@ async function getRawWorkspaceDependencies() {
63041
63287
  } catch {}
63042
63288
  return rawWorkspaceDeps;
63043
63289
  }
63044
- function workspaceDependenciesPathToLanguageAndFilename(path8) {
63045
- const relativePath = path8.replace("dependencies/", "");
63290
+ function workspaceDependenciesPathToLanguageAndFilename(path10) {
63291
+ const relativePath = path10.replace("dependencies/", "");
63046
63292
  for (const { filename, language } of workspaceDependenciesLanguages) {
63047
63293
  if (relativePath.endsWith(filename)) {
63048
63294
  return {
@@ -63089,20 +63335,48 @@ async function blueColor() {
63089
63335
  return isWin2 ? colors.black : colors.blue;
63090
63336
  }
63091
63337
  async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRun, noStaleMessage, rawWorkspaceDependencies, codebases, justUpdateMetadataLock) {
63092
- const remotePath = scriptPath.substring(0, scriptPath.indexOf(".")).replaceAll(SEP9, "/");
63338
+ const isFolderLayout = isModuleEntryPoint(scriptPath);
63339
+ const remotePath = isFolderLayout ? getScriptBasePathFromModulePath(scriptPath).replaceAll(SEP9, "/") : scriptPath.substring(0, scriptPath.indexOf(".")).replaceAll(SEP9, "/");
63093
63340
  const language = inferContentTypeFromFilePath(scriptPath, opts.defaultTs);
63094
63341
  const metadataWithType = await parseMetadataFile(remotePath, undefined);
63095
63342
  const scriptContent = await readFile9(scriptPath, "utf-8");
63096
63343
  const metadataContent = await readFile9(metadataWithType.path, "utf-8");
63097
63344
  const filteredRawWorkspaceDependencies = filterWorkspaceDependencies(rawWorkspaceDependencies, scriptContent, language);
63345
+ const moduleFolderPath = isFolderLayout ? path9.dirname(scriptPath) : scriptPath.substring(0, scriptPath.indexOf(".")) + getModuleFolderSuffix();
63346
+ const hasModules = existsSync4(moduleFolderPath) && statSync(moduleFolderPath).isDirectory();
63098
63347
  let hash2 = await generateScriptHash(filteredRawWorkspaceDependencies, scriptContent, metadataContent);
63099
- if (await checkifMetadataUptodate(remotePath, hash2, undefined)) {
63348
+ let moduleHashes = {};
63349
+ if (hasModules) {
63350
+ moduleHashes = await computeModuleHashes(moduleFolderPath, opts.defaultTs, rawWorkspaceDependencies, isFolderLayout);
63351
+ }
63352
+ const hasModuleHashes = Object.keys(moduleHashes).length > 0;
63353
+ let checkHash = hash2;
63354
+ let checkSubpath;
63355
+ if (hasModuleHashes) {
63356
+ const sortedEntries = Object.entries(moduleHashes).sort(([a], [b]) => a.localeCompare(b));
63357
+ checkHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
63358
+ checkSubpath = SCRIPT_TOP_HASH;
63359
+ }
63360
+ const conf = await readLockfile();
63361
+ if (await checkifMetadataUptodate(remotePath, checkHash, conf, checkSubpath)) {
63100
63362
  if (!noStaleMessage) {
63101
63363
  info(colors.green(`Script ${remotePath} metadata is up-to-date, skipping`));
63102
63364
  }
63103
63365
  return;
63104
63366
  } else if (dryRun) {
63105
- return `${remotePath} (${language})`;
63367
+ let detail = `${remotePath} (${language})`;
63368
+ if (hasModuleHashes) {
63369
+ const changed = [];
63370
+ for (const [modulePath, moduleHash] of Object.entries(moduleHashes)) {
63371
+ if (!await checkifMetadataUptodate(remotePath, moduleHash, conf, modulePath)) {
63372
+ changed.push(modulePath);
63373
+ }
63374
+ }
63375
+ if (changed.length > 0) {
63376
+ detail += ` [changed modules: ${changed.join(", ")}]`;
63377
+ }
63378
+ }
63379
+ return detail;
63106
63380
  }
63107
63381
  if (!justUpdateMetadataLock && !noStaleMessage) {
63108
63382
  info(colors.gray(`Generating metadata for ${scriptPath}`));
@@ -63114,40 +63388,79 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
63114
63388
  if (!opts.schemaOnly && !justUpdateMetadataLock) {
63115
63389
  const hasCodebase = findCodebase(scriptPath, codebases) != null;
63116
63390
  if (!hasCodebase) {
63117
- await updateScriptLock(workspace, scriptContent, language, remotePath, metadataParsedContent, filteredRawWorkspaceDependencies);
63391
+ const lockPathOverride = isFolderLayout ? path9.dirname(scriptPath) + "/script.lock" : undefined;
63392
+ await updateScriptLock(workspace, scriptContent, language, remotePath, metadataParsedContent, filteredRawWorkspaceDependencies, lockPathOverride);
63118
63393
  } else {
63119
63394
  metadataParsedContent.lock = "";
63120
63395
  }
63396
+ if (hasModules) {
63397
+ let changedModules;
63398
+ if (hasModuleHashes) {
63399
+ changedModules = [];
63400
+ for (const [modulePath, moduleHash] of Object.entries(moduleHashes)) {
63401
+ if (!await checkifMetadataUptodate(remotePath, moduleHash, conf, modulePath)) {
63402
+ changedModules.push(modulePath);
63403
+ }
63404
+ }
63405
+ if (changedModules.length === 0) {
63406
+ changedModules = undefined;
63407
+ }
63408
+ }
63409
+ await updateModuleLocks(workspace, moduleFolderPath, "", remotePath, rawWorkspaceDependencies, opts.defaultTs, changedModules);
63410
+ }
63121
63411
  } else {
63122
- metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP9, "/") + ".script.lock";
63412
+ if (isFolderLayout) {
63413
+ metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP9, "/") + getModuleFolderSuffix() + "/script.lock";
63414
+ } else {
63415
+ metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP9, "/") + ".script.lock";
63416
+ }
63123
63417
  }
63124
- let metaPath = remotePath + ".script.yaml";
63125
- let newMetadataContent = import_yaml12.stringify(metadataParsedContent, yamlOptions);
63126
- if (metadataWithType.isJson) {
63127
- metaPath = remotePath + ".script.json";
63128
- newMetadataContent = JSON.stringify(metadataParsedContent);
63418
+ let metaPath;
63419
+ let newMetadataContent;
63420
+ if (isFolderLayout) {
63421
+ if (metadataWithType.isJson) {
63422
+ metaPath = path9.dirname(scriptPath) + "/script.json";
63423
+ newMetadataContent = JSON.stringify(metadataParsedContent);
63424
+ } else {
63425
+ metaPath = path9.dirname(scriptPath) + "/script.yaml";
63426
+ newMetadataContent = import_yaml12.stringify(metadataParsedContent, yamlOptions);
63427
+ }
63428
+ } else {
63429
+ if (metadataWithType.isJson) {
63430
+ metaPath = remotePath + ".script.json";
63431
+ newMetadataContent = JSON.stringify(metadataParsedContent);
63432
+ } else {
63433
+ metaPath = remotePath + ".script.yaml";
63434
+ newMetadataContent = import_yaml12.stringify(metadataParsedContent, yamlOptions);
63435
+ }
63129
63436
  }
63130
63437
  const metadataContentUsedForHash = newMetadataContent;
63131
63438
  hash2 = await generateScriptHash(filteredRawWorkspaceDependencies, scriptContent, metadataContentUsedForHash);
63132
- await updateMetadataGlobalLock(remotePath, hash2);
63439
+ if (hasModuleHashes) {
63440
+ const sortedEntries = Object.entries(moduleHashes).sort(([a], [b]) => a.localeCompare(b));
63441
+ const metaHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
63442
+ await clearGlobalLock(remotePath);
63443
+ await updateMetadataGlobalLock(remotePath, metaHash, SCRIPT_TOP_HASH);
63444
+ for (const [modulePath, moduleHash] of Object.entries(moduleHashes)) {
63445
+ await updateMetadataGlobalLock(remotePath, moduleHash, modulePath);
63446
+ }
63447
+ } else {
63448
+ await updateMetadataGlobalLock(remotePath, hash2);
63449
+ }
63133
63450
  if (!justUpdateMetadataLock) {
63134
63451
  await writeFile7(metaPath, newMetadataContent, "utf-8");
63135
63452
  }
63136
63453
  return `${remotePath} (${language})`;
63137
63454
  }
63138
- async function updateScriptSchema(scriptContent, language, metadataContent, path8) {
63139
- const result = await inferSchema(language, scriptContent, metadataContent.schema, path8);
63455
+ async function updateScriptSchema(scriptContent, language, metadataContent, path10) {
63456
+ const result = await inferSchema(language, scriptContent, metadataContent.schema, path10);
63140
63457
  metadataContent.schema = result.schema;
63141
63458
  if (result.has_preprocessor) {
63142
63459
  metadataContent.has_preprocessor = result.has_preprocessor;
63143
63460
  } else {
63144
63461
  delete metadataContent.has_preprocessor;
63145
63462
  }
63146
- if (result.no_main_func) {
63147
- metadataContent.no_main_func = result.no_main_func;
63148
- } else {
63149
- delete metadataContent.no_main_func;
63150
- }
63463
+ delete metadataContent.auto_kind;
63151
63464
  }
63152
63465
  function extractWorkspaceDepsAnnotation(scriptContent, language) {
63153
63466
  const config = LANG_ANNOTATION_CONFIG[language];
@@ -63267,8 +63580,8 @@ async function fetchScriptLock(workspace, scriptContent, language, remotePath, r
63267
63580
  throw new LockfileGenerationError(`Failed to generate lockfile:${rawResponse.statusText}, ${responseText}, ${e}`);
63268
63581
  }
63269
63582
  }
63270
- async function updateScriptLock(workspace, scriptContent, language, remotePath, metadataContent, rawWorkspaceDependencies) {
63271
- if (!(workspaceDependenciesLanguages.some((l) => l.language == language) || language == "deno" || language == "rust" || language == "ansible")) {
63583
+ async function updateScriptLock(workspace, scriptContent, language, remotePath, metadataContent, rawWorkspaceDependencies, lockPathOverride) {
63584
+ if (!(workspaceDependenciesLanguages.some((l) => l.language == language) && language !== "powershell" || language == "deno" || language == "rust" || language == "ansible")) {
63272
63585
  return;
63273
63586
  }
63274
63587
  if (Object.keys(rawWorkspaceDependencies).length > 0) {
@@ -63276,7 +63589,7 @@ async function updateScriptLock(workspace, scriptContent, language, remotePath,
63276
63589
  info(`Generating script lock for ${remotePath} with raw workspace dependencies: ${dependencyPaths}`);
63277
63590
  }
63278
63591
  const lock = await fetchScriptLock(workspace, scriptContent, language, remotePath, rawWorkspaceDependencies);
63279
- const lockPath = remotePath + ".script.lock";
63592
+ const lockPath = lockPathOverride ?? remotePath + ".script.lock";
63280
63593
  if (lock != "") {
63281
63594
  await writeFile7(lockPath, lock, "utf-8");
63282
63595
  metadataContent.lock = "!inline " + lockPath.replaceAll(SEP9, "/");
@@ -63291,7 +63604,51 @@ async function updateScriptLock(workspace, scriptContent, language, remotePath,
63291
63604
  metadataContent.lock = "";
63292
63605
  }
63293
63606
  }
63294
- async function inferSchema(language, content, currentSchema, path8) {
63607
+ async function updateModuleLocks(workspace, dirPath, relPrefix, scriptRemotePath, rawWorkspaceDependencies, defaultTs, changedModules) {
63608
+ const entries = readdirSync(dirPath, { withFileTypes: true });
63609
+ for (const entry of entries) {
63610
+ const fullPath = path9.join(dirPath, entry.name);
63611
+ const relPath = relPrefix ? relPrefix + "/" + entry.name : entry.name;
63612
+ if (entry.isDirectory()) {
63613
+ await updateModuleLocks(workspace, fullPath, relPath, scriptRemotePath, rawWorkspaceDependencies, defaultTs, changedModules);
63614
+ } else if (entry.isFile() && !entry.name.endsWith(".lock") && !(relPrefix === "" && entry.name.startsWith("script."))) {
63615
+ let modLanguage;
63616
+ try {
63617
+ modLanguage = inferContentTypeFromFilePath(entry.name, defaultTs);
63618
+ } catch {
63619
+ continue;
63620
+ }
63621
+ if (!languageNeedsLock(modLanguage))
63622
+ continue;
63623
+ if (changedModules) {
63624
+ const normalizedRelPath = normalizeLockPath(relPath);
63625
+ if (!changedModules.includes(normalizedRelPath))
63626
+ continue;
63627
+ }
63628
+ const moduleContent = readFileSync3(fullPath, "utf-8");
63629
+ const moduleRemotePath = scriptRemotePath + "/" + relPath;
63630
+ info(colors.gray(`Generating lock for module ${relPath}`));
63631
+ try {
63632
+ const lock = await fetchScriptLock(workspace, moduleContent, modLanguage, moduleRemotePath, rawWorkspaceDependencies);
63633
+ const baseName = entry.name.replace(/\.[^.]+$/, "");
63634
+ const lockPath = path9.join(dirPath, baseName + ".lock");
63635
+ if (lock != "") {
63636
+ writeFileSync2(lockPath, lock, "utf-8");
63637
+ } else {
63638
+ try {
63639
+ if (existsSync4(lockPath)) {
63640
+ const { rm: rmAsync } = await import("node:fs/promises");
63641
+ await rmAsync(lockPath);
63642
+ }
63643
+ } catch {}
63644
+ }
63645
+ } catch (e) {
63646
+ info(colors.yellow(`Failed to generate lock for module ${relPath}: ${e}`));
63647
+ }
63648
+ }
63649
+ }
63650
+ }
63651
+ async function inferSchema(language, content, currentSchema, path10) {
63295
63652
  let inferedSchema;
63296
63653
  if (language === "python3") {
63297
63654
  const { parse_python } = await loadParser("windmill-parser-wasm-py");
@@ -63391,11 +63748,11 @@ async function inferSchema(language, content, currentSchema, path8) {
63391
63748
  throw new Error("Invalid language: " + language);
63392
63749
  }
63393
63750
  if (inferedSchema.type == "Invalid") {
63394
- info(colors.yellow(`Script ${path8} invalid, it cannot be parsed to infer schema.`));
63751
+ info(colors.yellow(`Script ${path10} invalid, it cannot be parsed to infer schema.`));
63395
63752
  return {
63396
63753
  schema: defaultScriptMetadata().schema,
63397
63754
  has_preprocessor: false,
63398
- no_main_func: false
63755
+ auto_kind: undefined
63399
63756
  };
63400
63757
  }
63401
63758
  if (!currentSchema) {
@@ -63423,7 +63780,7 @@ async function inferSchema(language, content, currentSchema, path8) {
63423
63780
  return {
63424
63781
  schema: currentSchema,
63425
63782
  has_preprocessor: inferedSchema.has_preprocessor,
63426
- no_main_func: inferedSchema.no_main_func
63783
+ auto_kind: inferedSchema.auto_kind
63427
63784
  };
63428
63785
  }
63429
63786
  function sortObject(obj) {
@@ -63468,33 +63825,55 @@ async function parseMetadataFile(scriptPath, generateMetadataIfMissing) {
63468
63825
  isJson: false
63469
63826
  };
63470
63827
  } catch {
63471
- info((await blueColor())(`Creating script metadata file for ${metadataFilePath}`));
63472
- metadataFilePath = scriptPath + ".script.yaml";
63473
- let scriptInitialMetadata = defaultScriptMetadata();
63474
- const lockPath = scriptPath + ".script.lock";
63475
- scriptInitialMetadata.lock = "!inline " + lockPath;
63476
- const scriptInitialMetadataYaml = import_yaml12.stringify(scriptInitialMetadata, yamlOptions);
63477
- await writeFile7(metadataFilePath, scriptInitialMetadataYaml, { flag: "wx", encoding: "utf-8" });
63478
- await writeFile7(lockPath, "", { flag: "wx", encoding: "utf-8" });
63479
- if (generateMetadataIfMissing) {
63480
- info((await blueColor())(`Generating lockfile and schema for ${metadataFilePath}`));
63828
+ const moduleFolderMeta = scriptPath + getModuleFolderSuffix();
63829
+ try {
63830
+ metadataFilePath = moduleFolderMeta + "/script.json";
63831
+ await stat7(metadataFilePath);
63832
+ return {
63833
+ path: metadataFilePath,
63834
+ payload: JSON.parse(await readFile9(metadataFilePath, "utf-8")),
63835
+ isJson: true
63836
+ };
63837
+ } catch {
63481
63838
  try {
63482
- await generateScriptMetadataInternal(generateMetadataIfMissing.path, generateMetadataIfMissing.workspaceRemote, generateMetadataIfMissing, false, false, generateMetadataIfMissing.rawWorkspaceDependencies, generateMetadataIfMissing.codebases, false);
63483
- scriptInitialMetadata = await yamlParseFile(metadataFilePath);
63484
- if (!generateMetadataIfMissing.schemaOnly) {
63485
- replaceLock(scriptInitialMetadata);
63486
- }
63487
- } catch (e) {
63488
- info(colors.yellow(`Failed to generate lockfile and schema for ${metadataFilePath}: ${e}`));
63489
- }
63839
+ metadataFilePath = moduleFolderMeta + "/script.yaml";
63840
+ await stat7(metadataFilePath);
63841
+ const payload = await yamlParseFile(metadataFilePath);
63842
+ replaceLock(payload);
63843
+ return {
63844
+ path: metadataFilePath,
63845
+ payload,
63846
+ isJson: false
63847
+ };
63848
+ } catch {}
63490
63849
  }
63491
- return {
63492
- path: metadataFilePath,
63493
- payload: scriptInitialMetadata,
63494
- isJson: false
63495
- };
63496
63850
  }
63497
63851
  }
63852
+ info((await blueColor())(`Creating script metadata file for ${metadataFilePath}`));
63853
+ metadataFilePath = scriptPath + ".script.yaml";
63854
+ let scriptInitialMetadata = defaultScriptMetadata();
63855
+ const lockPath = scriptPath + ".script.lock";
63856
+ scriptInitialMetadata.lock = "!inline " + lockPath;
63857
+ const scriptInitialMetadataYaml = import_yaml12.stringify(scriptInitialMetadata, yamlOptions);
63858
+ await writeFile7(metadataFilePath, scriptInitialMetadataYaml, { flag: "wx", encoding: "utf-8" });
63859
+ await writeFile7(lockPath, "", { flag: "wx", encoding: "utf-8" });
63860
+ if (generateMetadataIfMissing) {
63861
+ info((await blueColor())(`Generating lockfile and schema for ${metadataFilePath}`));
63862
+ try {
63863
+ await generateScriptMetadataInternal(generateMetadataIfMissing.path, generateMetadataIfMissing.workspaceRemote, generateMetadataIfMissing, false, false, generateMetadataIfMissing.rawWorkspaceDependencies, generateMetadataIfMissing.codebases, false);
63864
+ scriptInitialMetadata = await yamlParseFile(metadataFilePath);
63865
+ if (!generateMetadataIfMissing.schemaOnly) {
63866
+ replaceLock(scriptInitialMetadata);
63867
+ }
63868
+ } catch (e) {
63869
+ info(colors.yellow(`Failed to generate lockfile and schema for ${metadataFilePath}: ${e}`));
63870
+ }
63871
+ }
63872
+ return {
63873
+ path: metadataFilePath,
63874
+ payload: scriptInitialMetadata,
63875
+ isJson: false
63876
+ };
63498
63877
  }
63499
63878
  function normalizeLockPath(p) {
63500
63879
  return p.replace(/\\/g, "/");
@@ -63514,15 +63893,15 @@ async function readLockfile() {
63514
63893
  return lock;
63515
63894
  }
63516
63895
  }
63517
- function v2LockPath(path8, subpath) {
63518
- const normalizedPath = normalizeLockPath(path8);
63896
+ function v2LockPath(path10, subpath) {
63897
+ const normalizedPath = normalizeLockPath(path10);
63519
63898
  if (subpath) {
63520
63899
  return `${normalizedPath}+${normalizeLockPath(subpath)}`;
63521
63900
  } else {
63522
63901
  return normalizedPath;
63523
63902
  }
63524
63903
  }
63525
- async function checkifMetadataUptodate(path8, hash2, conf, subpath) {
63904
+ async function checkifMetadataUptodate(path10, hash2, conf, subpath) {
63526
63905
  if (!conf) {
63527
63906
  conf = await readLockfile();
63528
63907
  }
@@ -63531,10 +63910,10 @@ async function checkifMetadataUptodate(path8, hash2, conf, subpath) {
63531
63910
  }
63532
63911
  const isV2 = conf?.version == "v2";
63533
63912
  if (isV2) {
63534
- const current = conf.locks?.[v2LockPath(path8, subpath)];
63913
+ const current = conf.locks?.[v2LockPath(path10, subpath)];
63535
63914
  return current == hash2;
63536
63915
  } else {
63537
- const obj = conf.locks?.[path8];
63916
+ const obj = conf.locks?.[path10];
63538
63917
  const current = subpath && typeof obj == "object" ? obj?.[subpath] : obj;
63539
63918
  return current == hash2;
63540
63919
  }
@@ -63542,14 +63921,39 @@ async function checkifMetadataUptodate(path8, hash2, conf, subpath) {
63542
63921
  async function generateScriptHash(rawWorkspaceDependencies, scriptContent, newMetadataContent) {
63543
63922
  return await generateHash(JSON.stringify(rawWorkspaceDependencies) + scriptContent + newMetadataContent);
63544
63923
  }
63545
- async function clearGlobalLock(path8) {
63924
+ async function computeModuleHashes(moduleFolderPath, defaultTs, rawWorkspaceDependencies, isFolderLayout) {
63925
+ const hashes = {};
63926
+ async function readDir2(dirPath, relPrefix) {
63927
+ const entries = readdirSync(dirPath, { withFileTypes: true });
63928
+ for (const entry of entries) {
63929
+ const fullPath = path9.join(dirPath, entry.name);
63930
+ const relPath = relPrefix ? relPrefix + "/" + entry.name : entry.name;
63931
+ const isTopLevel = relPrefix === "";
63932
+ if (entry.isDirectory()) {
63933
+ await readDir2(fullPath, relPath);
63934
+ } else if (entry.isFile() && !entry.name.endsWith(".lock") && !(isFolderLayout && isTopLevel && entry.name.startsWith("script."))) {
63935
+ try {
63936
+ inferContentTypeFromFilePath(entry.name, defaultTs);
63937
+ } catch {
63938
+ continue;
63939
+ }
63940
+ const content = readFileSync3(fullPath, "utf-8");
63941
+ const normalizedPath = normalizeLockPath(relPath);
63942
+ hashes[normalizedPath] = await generateHash(content + JSON.stringify(rawWorkspaceDependencies));
63943
+ }
63944
+ }
63945
+ }
63946
+ await readDir2(moduleFolderPath, "");
63947
+ return hashes;
63948
+ }
63949
+ async function clearGlobalLock(path10) {
63546
63950
  const conf = await readLockfile();
63547
63951
  if (!conf?.locks) {
63548
63952
  conf.locks = {};
63549
63953
  }
63550
63954
  const isV2 = conf?.version == "v2";
63551
63955
  if (isV2) {
63552
- const key = v2LockPath(path8);
63956
+ const key = v2LockPath(path10);
63553
63957
  if (conf.locks) {
63554
63958
  Object.keys(conf.locks).forEach((k) => {
63555
63959
  if (conf.locks) {
@@ -63562,29 +63966,29 @@ async function clearGlobalLock(path8) {
63562
63966
  await writeFile7(WMILL_LOCKFILE, import_yaml12.stringify(conf, yamlOptions), "utf-8");
63563
63967
  }
63564
63968
  }
63565
- async function updateMetadataGlobalLock(path8, hash2, subpath) {
63969
+ async function updateMetadataGlobalLock(path10, hash2, subpath) {
63566
63970
  const conf = await readLockfile();
63567
63971
  if (!conf?.locks) {
63568
63972
  conf.locks = {};
63569
63973
  }
63570
63974
  const isV2 = conf?.version == "v2";
63571
63975
  if (isV2) {
63572
- conf.locks[v2LockPath(path8, subpath)] = hash2;
63976
+ conf.locks[v2LockPath(path10, subpath)] = hash2;
63573
63977
  } else {
63574
63978
  if (subpath) {
63575
- let prev = conf.locks[path8];
63979
+ let prev = conf.locks[path10];
63576
63980
  if (!prev || typeof prev != "object") {
63577
63981
  prev = {};
63578
- conf.locks[path8] = prev;
63982
+ conf.locks[path10] = prev;
63579
63983
  }
63580
63984
  prev[subpath] = hash2;
63581
63985
  } else {
63582
- conf.locks[path8] = hash2;
63986
+ conf.locks[path10] = hash2;
63583
63987
  }
63584
63988
  }
63585
63989
  await writeFile7(WMILL_LOCKFILE, import_yaml12.stringify(conf, yamlOptions), "utf-8");
63586
63990
  }
63587
- var import_yaml12, _require, _parserCache, LockfileGenerationError, LANG_ANNOTATION_CONFIG, lockCache, WMILL_LOCKFILE = "wmill-lock.yaml";
63991
+ var import_yaml12, _require, _parserCache, LockfileGenerationError, LANG_ANNOTATION_CONFIG, lockCache, WMILL_LOCKFILE = "wmill-lock.yaml", SCRIPT_TOP_HASH = "__script_hash";
63588
63992
  var init_metadata = __esm(async () => {
63589
63993
  init_colors2();
63590
63994
  init_log();
@@ -63592,6 +63996,7 @@ var init_metadata = __esm(async () => {
63592
63996
  init_script_bootstrap();
63593
63997
  init_script_common();
63594
63998
  init_script_common();
63999
+ init_resource_folders();
63595
64000
  init_parse_schema();
63596
64001
  await __promiseAll([
63597
64002
  init_sync(),
@@ -63612,14 +64017,15 @@ var init_metadata = __esm(async () => {
63612
64017
  bun: { comment: "//", keyword: "package_json" },
63613
64018
  nativets: { comment: "//", keyword: "package_json" },
63614
64019
  go: { comment: "//", keyword: "go_mod" },
63615
- php: { comment: "//", keyword: "composer_json" }
64020
+ php: { comment: "//", keyword: "composer_json" },
64021
+ powershell: { comment: "#", keyword: "modules_json" }
63616
64022
  };
63617
64023
  lockCache = new Map;
63618
64024
  });
63619
64025
 
63620
64026
  // src/commands/app/raw_apps.ts
63621
64027
  import { sep as SEP10 } from "node:path";
63622
- import path8 from "node:path";
64028
+ import path10 from "node:path";
63623
64029
  import { readFile as readFile10, readdir as readdir6 } from "node:fs/promises";
63624
64030
  async function findRunnableContentFile(backendPath, runnableId, allFiles) {
63625
64031
  for (const fileName of allFiles) {
@@ -63632,7 +64038,7 @@ async function findRunnableContentFile(backendPath, runnableId, allFiles) {
63632
64038
  const ext2 = fileName.substring(runnableId.length + 1);
63633
64039
  if (EXTENSION_TO_LANGUAGE[ext2]) {
63634
64040
  try {
63635
- const content = await readFile10(path8.join(backendPath, fileName), "utf-8");
64041
+ const content = await readFile10(path10.join(backendPath, fileName), "utf-8");
63636
64042
  return { ext: ext2, content };
63637
64043
  } catch {
63638
64044
  continue;
@@ -63669,7 +64075,7 @@ async function loadRunnablesFromBackend(backendPath, defaultTs = "bun") {
63669
64075
  }
63670
64076
  const runnableId = fileName.replace(".yaml", "");
63671
64077
  processedIds.add(runnableId);
63672
- const filePath = path8.join(backendPath, fileName);
64078
+ const filePath = path10.join(backendPath, fileName);
63673
64079
  const runnable = await yamlParseFile(filePath);
63674
64080
  if (runnable?.type === "inline") {
63675
64081
  const contentFile = await findRunnableContentFile(backendPath, runnableId, allFiles);
@@ -63677,7 +64083,7 @@ async function loadRunnablesFromBackend(backendPath, defaultTs = "bun") {
63677
64083
  const language = getLanguageFromExtension(contentFile.ext, defaultTs);
63678
64084
  let lock;
63679
64085
  try {
63680
- lock = await readFile10(path8.join(backendPath, `${runnableId}.lock`), "utf-8");
64086
+ lock = await readFile10(path10.join(backendPath, `${runnableId}.lock`), "utf-8");
63681
64087
  } catch {}
63682
64088
  runnable.inlineScript = {
63683
64089
  content: contentFile.content,
@@ -63708,7 +64114,7 @@ async function loadRunnablesFromBackend(backendPath, defaultTs = "bun") {
63708
64114
  const language = getLanguageFromExtension(contentFile.ext, defaultTs);
63709
64115
  let lock;
63710
64116
  try {
63711
- lock = await readFile10(path8.join(backendPath, `${runnableId}.lock`), "utf-8");
64117
+ lock = await readFile10(path10.join(backendPath, `${runnableId}.lock`), "utf-8");
63712
64118
  } catch {}
63713
64119
  runnables[runnableId] = {
63714
64120
  type: "inline",
@@ -63736,7 +64142,7 @@ function writeRunnableToBackend(backendPath, runnableId, runnable) {
63736
64142
  ...rest
63737
64143
  };
63738
64144
  }
63739
- const filePath = path8.join(backendPath, `${runnableId}.yaml`);
64145
+ const filePath = path10.join(backendPath, `${runnableId}.yaml`);
63740
64146
  writeIfChanged(filePath, import_yaml15.stringify(runnableToWrite, yamlOptions));
63741
64147
  }
63742
64148
  async function collectAppFiles(localPath) {
@@ -63787,7 +64193,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
63787
64193
  }
63788
64194
  const appFilePath = localPath + "raw_app.yaml";
63789
64195
  const localApp = await yamlParseFile(appFilePath);
63790
- const backendPath = path8.join(localPath, APP_BACKEND_FOLDER);
64196
+ const backendPath = path10.join(localPath, APP_BACKEND_FOLDER);
63791
64197
  const runnablesFromBackend = await loadRunnablesFromBackend(backendPath);
63792
64198
  let runnables;
63793
64199
  if (Object.keys(runnablesFromBackend).length > 0) {
@@ -63863,13 +64269,13 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
63863
64269
  });
63864
64270
  }
63865
64271
  }
63866
- async function generatingPolicy(app, path9, publicApp) {
63867
- info(colors.gray(`Generating fresh policy for app ${path9}...`));
64272
+ async function generatingPolicy(app, path11, publicApp) {
64273
+ info(colors.gray(`Generating fresh policy for app ${path11}...`));
63868
64274
  try {
63869
64275
  app.policy = await updateRawAppPolicy(app.runnables, app.policy);
63870
64276
  app.policy.execution_mode = publicApp ? "anonymous" : "publisher";
63871
64277
  } catch (e) {
63872
- error(colors.red(`Error generating policy for app ${path9}: ${e}`));
64278
+ error(colors.red(`Error generating policy for app ${path11}: ${e}`));
63873
64279
  throw e;
63874
64280
  }
63875
64281
  }
@@ -63906,11 +64312,11 @@ __export(exports_app_metadata, {
63906
64312
  filterWorkspaceDependenciesForApp: () => filterWorkspaceDependenciesForApp,
63907
64313
  APP_BACKEND_FOLDER: () => APP_BACKEND_FOLDER
63908
64314
  });
63909
- import path9 from "node:path";
64315
+ import path11 from "node:path";
63910
64316
  import { readFile as readFile11, mkdir as mkdir4 } from "node:fs/promises";
63911
64317
  import { sep as SEP11 } from "node:path";
63912
64318
  async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
63913
- const runnablesFolder = rawApp ? path9.join(folder, APP_BACKEND_FOLDER) : folder;
64319
+ const runnablesFolder = rawApp ? path11.join(folder, APP_BACKEND_FOLDER) : folder;
63914
64320
  const hashes = {};
63915
64321
  try {
63916
64322
  const elems = await FSFSElement(runnablesFolder, [], true);
@@ -63942,7 +64348,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
63942
64348
  info(`Generating locks for app ${appFolder} at ${remote_path}`);
63943
64349
  }
63944
64350
  const rawWorkspaceDependencies = await getRawWorkspaceDependencies();
63945
- const appFilePath = path9.join(appFolder, rawApp ? "raw_app.yaml" : "app.yaml");
64351
+ const appFilePath = path11.join(appFolder, rawApp ? "raw_app.yaml" : "app.yaml");
63946
64352
  const appFile = await yamlParseFile(appFilePath);
63947
64353
  const appValue = rawApp ? appFile.runnables : appFile.value;
63948
64354
  const filteredDeps = await filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependencies, appFolder);
@@ -63975,7 +64381,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
63975
64381
  info(`Recomputing locks of ${changedScripts.join(", ")} in ${appFolder}`);
63976
64382
  }
63977
64383
  if (rawApp) {
63978
- const runnablesPath = path9.join(appFolder, APP_BACKEND_FOLDER);
64384
+ const runnablesPath = path11.join(appFolder, APP_BACKEND_FOLDER);
63979
64385
  const rawAppFile = appFile;
63980
64386
  let runnables = await loadRunnablesFromBackend(runnablesPath);
63981
64387
  if (Object.keys(runnables).length === 0 && rawAppFile.runnables) {
@@ -64047,7 +64453,7 @@ async function traverseAndProcessInlineScripts(obj, processor, currentPath = [])
64047
64453
  }
64048
64454
  async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder, rawDeps, defaultTs = "bun", noStaleMessage) {
64049
64455
  const updatedRunnables = [];
64050
- const runnablesFolder = path9.join(appFolder, APP_BACKEND_FOLDER);
64456
+ const runnablesFolder = path11.join(appFolder, APP_BACKEND_FOLDER);
64051
64457
  try {
64052
64458
  await mkdir4(runnablesFolder, { recursive: true });
64053
64459
  } catch {}
@@ -64072,7 +64478,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
64072
64478
  if (language === "frontend") {
64073
64479
  const [basePathO, ext2] = pathAssigner.assignPath(runnable.name ?? runnableId, language);
64074
64480
  const basePath = basePathO.replaceAll(SEP11, "/");
64075
- const contentPath = path9.join(runnablesFolder, `${basePath}${ext2}`);
64481
+ const contentPath = path11.join(runnablesFolder, `${basePath}${ext2}`);
64076
64482
  writeIfChanged(contentPath, content);
64077
64483
  const simplifiedRunnable = { type: "inline" };
64078
64484
  for (const [key, value] of Object.entries(runnable)) {
@@ -64090,8 +64496,8 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
64090
64496
  const lock = await generateInlineScriptLock(workspace, content, language, `${remotePath}/${runnableId}`, rawDeps);
64091
64497
  const [basePathO, ext2] = pathAssigner.assignPath(runnable.name ?? runnableId, language);
64092
64498
  const basePath = basePathO.replaceAll(SEP11, "/");
64093
- const contentPath = path9.join(runnablesFolder, `${basePath}${ext2}`);
64094
- const lockPath = path9.join(runnablesFolder, `${basePath}lock`);
64499
+ const contentPath = path11.join(runnablesFolder, `${basePath}${ext2}`);
64500
+ const lockPath = path11.join(runnablesFolder, `${basePath}lock`);
64095
64501
  writeIfChanged(contentPath, content);
64096
64502
  if (lock && lock !== "") {
64097
64503
  writeIfChanged(lockPath, lock);
@@ -64139,8 +64545,8 @@ async function updateAppInlineScripts(workspace, appValue, remotePath, appFolder
64139
64545
  }
64140
64546
  const [basePathO, ext2] = pathAssigner.assignPath(scriptName, language);
64141
64547
  const basePath = basePathO.replaceAll(SEP11, "/");
64142
- const contentPath = path9.join(appFolder, `${basePath}${ext2}`);
64143
- const lockPath = path9.join(appFolder, `${basePath}lock`);
64548
+ const contentPath = path11.join(appFolder, `${basePath}${ext2}`);
64549
+ const lockPath = path11.join(appFolder, `${basePath}lock`);
64144
64550
  writeIfChanged(contentPath, content);
64145
64551
  if (lock && lock !== "") {
64146
64552
  writeIfChanged(lockPath, lock);
@@ -64210,7 +64616,7 @@ ${text}`);
64210
64616
  }
64211
64617
  }
64212
64618
  async function inferRunnableSchemaFromFile(appFolder, runnableFilePath) {
64213
- const fileName = path9.basename(runnableFilePath);
64619
+ const fileName = path11.basename(runnableFilePath);
64214
64620
  if (fileName.endsWith(".lock") || fileName.endsWith(".yaml")) {
64215
64621
  return;
64216
64622
  }
@@ -64219,13 +64625,13 @@ async function inferRunnableSchemaFromFile(appFolder, runnableFilePath) {
64219
64625
  return;
64220
64626
  }
64221
64627
  const runnableId = match2[1];
64222
- const runnableFilePath2 = path9.join(appFolder, APP_BACKEND_FOLDER, `${runnableId}.yaml`);
64628
+ const runnableFilePath2 = path11.join(appFolder, APP_BACKEND_FOLDER, `${runnableId}.yaml`);
64223
64629
  let runnable;
64224
64630
  try {
64225
64631
  runnable = await yamlParseFile(runnableFilePath2);
64226
64632
  } catch {
64227
64633
  try {
64228
- const appFilePath = path9.join(appFolder, "raw_app.yaml");
64634
+ const appFilePath = path11.join(appFolder, "raw_app.yaml");
64229
64635
  const appFile = await yamlParseFile(appFilePath);
64230
64636
  if (!appFile.runnables?.[runnableId]) {
64231
64637
  warn(colors.yellow(`Runnable ${runnableId} not found in backend folder or raw_app.yaml`));
@@ -64242,7 +64648,7 @@ async function inferRunnableSchemaFromFile(appFolder, runnableFilePath) {
64242
64648
  }
64243
64649
  const inlineScript = runnable.inlineScript;
64244
64650
  const language = inlineScript.language;
64245
- const fullFilePath = path9.join(appFolder, APP_BACKEND_FOLDER, runnableFilePath);
64651
+ const fullFilePath = path11.join(appFolder, APP_BACKEND_FOLDER, runnableFilePath);
64246
64652
  let content;
64247
64653
  try {
64248
64654
  content = await readFile11(fullFilePath, "utf-8");
@@ -64351,7 +64757,7 @@ var init_app_metadata = __esm(async () => {
64351
64757
  // src/commands/app/generate_agents.ts
64352
64758
  import * as fs9 from "node:fs";
64353
64759
  import { writeFile as writeFile8 } from "node:fs/promises";
64354
- import path10 from "node:path";
64760
+ import path12 from "node:path";
64355
64761
  import process13 from "node:process";
64356
64762
  function generateDatatablesMarkdown(schemas, localData) {
64357
64763
  const defaultDatatable = localData?.datatable;
@@ -64451,7 +64857,7 @@ Configure datatables in Workspace Settings > Windmill Data Tables.
64451
64857
  return content;
64452
64858
  }
64453
64859
  async function regenerateAgentDocs(workspaceId, targetDir, silent = false) {
64454
- const rawAppPath = path10.join(targetDir, "raw_app.yaml");
64860
+ const rawAppPath = path12.join(targetDir, "raw_app.yaml");
64455
64861
  if (!fs9.existsSync(rawAppPath)) {
64456
64862
  if (!silent) {
64457
64863
  error(colors.red(`Error: raw_app.yaml not found in ${targetDir}`));
@@ -64478,11 +64884,11 @@ async function regenerateAgentDocs(workspaceId, targetDir, silent = false) {
64478
64884
  }
64479
64885
  } catch {}
64480
64886
  const agentsContent = generateAgentsDocumentation(localData);
64481
- await writeFile8(path10.join(targetDir, "AGENTS.md"), agentsContent, "utf-8");
64482
- await writeFile8(path10.join(targetDir, "CLAUDE.md"), `Instructions are in @AGENTS.md
64887
+ await writeFile8(path12.join(targetDir, "AGENTS.md"), agentsContent, "utf-8");
64888
+ await writeFile8(path12.join(targetDir, "CLAUDE.md"), `Instructions are in @AGENTS.md
64483
64889
  `, "utf-8");
64484
64890
  const datatablesContent = generateDatatablesMarkdown(schemas, localData);
64485
- await writeFile8(path10.join(targetDir, "DATATABLES.md"), datatablesContent, "utf-8");
64891
+ await writeFile8(path12.join(targetDir, "DATATABLES.md"), datatablesContent, "utf-8");
64486
64892
  if (!silent) {
64487
64893
  info(colors.green(`✓ Generated AGENTS.md, CLAUDE.md, and DATATABLES.md`));
64488
64894
  const datatableCount = schemas.length;
@@ -64503,18 +64909,18 @@ async function generateAgents(opts, appFolder) {
64503
64909
  const cwd = process13.cwd();
64504
64910
  let targetDir = cwd;
64505
64911
  if (appFolder) {
64506
- targetDir = path10.isAbsolute(appFolder) ? appFolder : path10.join(cwd, appFolder);
64912
+ targetDir = path12.isAbsolute(appFolder) ? appFolder : path12.join(cwd, appFolder);
64507
64913
  }
64508
64914
  await loadNonDottedPathsSetting();
64509
- const dirName = path10.basename(targetDir);
64915
+ const dirName = path12.basename(targetDir);
64510
64916
  if (!hasFolderSuffix(dirName, "raw_app")) {
64511
- if (!hasFolderSuffix(path10.basename(cwd), "raw_app") && !appFolder) {
64917
+ if (!hasFolderSuffix(path12.basename(cwd), "raw_app") && !appFolder) {
64512
64918
  error(colors.red(`Error: Must be run inside a ${getFolderSuffix("raw_app")} folder or specify one as argument.`));
64513
64919
  info(colors.gray("Usage: wmill app generate-agents [app_folder]"));
64514
64920
  process13.exit(1);
64515
64921
  }
64516
64922
  }
64517
- const rawAppPath = path10.join(targetDir, "raw_app.yaml");
64923
+ const rawAppPath = path12.join(targetDir, "raw_app.yaml");
64518
64924
  if (!fs9.existsSync(rawAppPath)) {
64519
64925
  error(colors.red(`Error: raw_app.yaml not found in ${targetDir}`));
64520
64926
  process13.exit(1);
@@ -64544,9 +64950,9 @@ var init_generate_agents = __esm(async () => {
64544
64950
  import { sep as SEP12 } from "node:path";
64545
64951
  import * as http2 from "node:http";
64546
64952
  import * as fs10 from "node:fs";
64547
- import * as path11 from "node:path";
64953
+ import * as path13 from "node:path";
64548
64954
  import process14 from "node:process";
64549
- import { writeFileSync as writeFileSync2 } from "node:fs";
64955
+ import { writeFileSync as writeFileSync3 } from "node:fs";
64550
64956
  import { readFile as readFile12 } from "node:fs/promises";
64551
64957
  async function dev(opts, appFolder) {
64552
64958
  GLOBAL_CONFIG_OPT.noCdToRoot = true;
@@ -64554,20 +64960,20 @@ async function dev(opts, appFolder) {
64554
64960
  const originalCwd = process14.cwd();
64555
64961
  let targetDir = originalCwd;
64556
64962
  if (appFolder) {
64557
- targetDir = path11.isAbsolute(appFolder) ? appFolder : path11.join(originalCwd, appFolder);
64963
+ targetDir = path13.isAbsolute(appFolder) ? appFolder : path13.join(originalCwd, appFolder);
64558
64964
  if (!fs10.existsSync(targetDir)) {
64559
64965
  error(colors.red(`Error: Directory not found: ${targetDir}`));
64560
64966
  process14.exit(1);
64561
64967
  }
64562
64968
  }
64563
- const targetDirName = path11.basename(targetDir);
64969
+ const targetDirName = path13.basename(targetDir);
64564
64970
  if (!hasFolderSuffix(targetDirName, "raw_app")) {
64565
64971
  error(colors.red(`Error: The dev command must be run inside a ${getFolderSuffix("raw_app")} folder.
64566
64972
  ` + `Target directory: ${targetDirName}
64567
64973
  ` + `Please navigate to a folder ending with '${getFolderSuffix("raw_app")}' or specify one as argument.`));
64568
64974
  process14.exit(1);
64569
64975
  }
64570
- const rawAppPath = path11.join(targetDir, "raw_app.yaml");
64976
+ const rawAppPath = path13.join(targetDir, "raw_app.yaml");
64571
64977
  if (!fs10.existsSync(rawAppPath)) {
64572
64978
  error(colors.red(`Error: raw_app.yaml not found in ${targetDir}.
64573
64979
  ` + `The dev command requires a ${getFolderSuffix("raw_app")} folder containing a raw_app.yaml file.`));
@@ -64594,11 +65000,11 @@ async function dev(opts, appFolder) {
64594
65000
  error(colors.red(`Entry point "${entryPoint}" not found. Please specify a valid entry point with --entry.`));
64595
65001
  process14.exit(1);
64596
65002
  }
64597
- const appDir = path11.dirname(entryPoint) || process14.cwd();
65003
+ const appDir = path13.dirname(entryPoint) || process14.cwd();
64598
65004
  await ensureNodeModules(appDir);
64599
65005
  const inferredSchemas = {};
64600
65006
  genRunnablesTs(inferredSchemas);
64601
- const distDir = path11.join(process14.cwd(), "dist");
65007
+ const distDir = path13.join(process14.cwd(), "dist");
64602
65008
  if (!fs10.existsSync(distDir)) {
64603
65009
  fs10.mkdirSync(distDir);
64604
65010
  }
@@ -64661,7 +65067,7 @@ data: reload
64661
65067
  info(colors.blue(`\uD83D\uDC40 Watching for file changes...
64662
65068
  `));
64663
65069
  await ctx.rebuild();
64664
- const runnablesPath = path11.join(process14.cwd(), APP_BACKEND_FOLDER);
65070
+ const runnablesPath = path13.join(process14.cwd(), APP_BACKEND_FOLDER);
64665
65071
  let runnablesWatcher;
64666
65072
  if (fs10.existsSync(runnablesPath)) {
64667
65073
  info(colors.blue(`\uD83D\uDC41️ Watching runnables folder at: ${runnablesPath}
@@ -64673,8 +65079,8 @@ data: reload
64673
65079
  if (!filename)
64674
65080
  return;
64675
65081
  const fileStr = typeof filename === "string" ? filename : filename.toString();
64676
- const changedPath = path11.join(runnablesPath, fileStr);
64677
- const relativePath = path11.relative(process14.cwd(), changedPath);
65082
+ const changedPath = path13.join(runnablesPath, fileStr);
65083
+ const relativePath = path13.relative(process14.cwd(), changedPath);
64678
65084
  const relativeToRunnables = fileStr;
64679
65085
  if (changedPath.endsWith(".lock")) {
64680
65086
  return;
@@ -64725,7 +65131,7 @@ data: reload
64725
65131
  return;
64726
65132
  }
64727
65133
  if (url === "/dist/bundle.js" || url === "/bundle.js") {
64728
- const jsPath = path11.join(process14.cwd(), "dist/bundle.js");
65134
+ const jsPath = path13.join(process14.cwd(), "dist/bundle.js");
64729
65135
  if (fs10.existsSync(jsPath)) {
64730
65136
  res.writeHead(200, { "Content-Type": "application/javascript" });
64731
65137
  res.end(fs10.readFileSync(jsPath));
@@ -64736,7 +65142,7 @@ data: reload
64736
65142
  return;
64737
65143
  }
64738
65144
  if (url === "/dist/bundle.css" || url === "/bundle.css") {
64739
- const cssPath = path11.join(process14.cwd(), "dist/bundle.css");
65145
+ const cssPath = path13.join(process14.cwd(), "dist/bundle.css");
64740
65146
  if (fs10.existsSync(cssPath)) {
64741
65147
  res.writeHead(200, { "Content-Type": "text/css" });
64742
65148
  res.end(fs10.readFileSync(cssPath));
@@ -64747,7 +65153,7 @@ data: reload
64747
65153
  return;
64748
65154
  }
64749
65155
  if (url === "/dist/bundle.js.map" || url === "/bundle.js.map") {
64750
- const mapPath = path11.join(process14.cwd(), "dist/bundle.js.map");
65156
+ const mapPath = path13.join(process14.cwd(), "dist/bundle.js.map");
64751
65157
  if (fs10.existsSync(mapPath)) {
64752
65158
  res.writeHead(200, { "Content-Type": "application/json" });
64753
65159
  res.end(fs10.readFileSync(mapPath));
@@ -64758,7 +65164,7 @@ data: reload
64758
65164
  return;
64759
65165
  }
64760
65166
  if (url === "/dist/bundle.css.map" || url === "/bundle.css.map") {
64761
- const mapPath = path11.join(process14.cwd(), "dist/bundle.css.map");
65167
+ const mapPath = path13.join(process14.cwd(), "dist/bundle.css.map");
64762
65168
  if (fs10.existsSync(mapPath)) {
64763
65169
  res.writeHead(200, { "Content-Type": "application/json" });
64764
65170
  res.end(fs10.readFileSync(mapPath));
@@ -64772,12 +65178,12 @@ data: reload
64772
65178
  res.end(createHTML("/dist/bundle.js", "/dist/bundle.css"));
64773
65179
  });
64774
65180
  const wss = new import_websocket_server.default({ server });
64775
- const sqlToApplyPath = path11.join(process14.cwd(), "sql_to_apply");
65181
+ const sqlToApplyPath = path13.join(process14.cwd(), "sql_to_apply");
64776
65182
  const sqlFileQueue = [];
64777
65183
  let currentSqlFile = null;
64778
65184
  async function getDatatableConfig() {
64779
65185
  try {
64780
- const rawApp2 = await yamlParseFile(path11.join(process14.cwd(), "raw_app.yaml"));
65186
+ const rawApp2 = await yamlParseFile(path13.join(process14.cwd(), "raw_app.yaml"));
64781
65187
  return rawApp2?.data?.datatable;
64782
65188
  } catch {
64783
65189
  return;
@@ -64814,12 +65220,12 @@ data: reload
64814
65220
  }
64815
65221
  const filePath = sqlFileQueue.shift();
64816
65222
  if (!fs10.existsSync(filePath)) {
64817
- info(colors.gray(`File no longer exists: ${path11.basename(filePath)}`));
65223
+ info(colors.gray(`File no longer exists: ${path13.basename(filePath)}`));
64818
65224
  await processNextSqlFile();
64819
65225
  return;
64820
65226
  }
64821
65227
  currentSqlFile = filePath;
64822
- const fileName = path11.basename(filePath);
65228
+ const fileName = path13.basename(filePath);
64823
65229
  try {
64824
65230
  const sqlContent = await readFile12(filePath, "utf-8");
64825
65231
  if (!sqlContent.trim()) {
@@ -64841,9 +65247,9 @@ data: reload
64841
65247
  if (deleteFile && fs10.existsSync(filePath)) {
64842
65248
  try {
64843
65249
  fs10.unlinkSync(filePath);
64844
- info(colors.green(`✓ Deleted: ${path11.basename(filePath)}`));
65250
+ info(colors.green(`✓ Deleted: ${path13.basename(filePath)}`));
64845
65251
  } catch (error2) {
64846
- error(colors.red(`Failed to delete ${path11.basename(filePath)}: ${error2.message}`));
65252
+ error(colors.red(`Failed to delete ${path13.basename(filePath)}: ${error2.message}`));
64847
65253
  }
64848
65254
  }
64849
65255
  currentSqlFile = null;
@@ -64855,7 +65261,7 @@ data: reload
64855
65261
  try {
64856
65262
  const sqlContent = await readFile12(currentSqlFile, "utf-8");
64857
65263
  const datatable = await getDatatableConfig();
64858
- const fileName = path11.basename(currentSqlFile);
65264
+ const fileName = path13.basename(currentSqlFile);
64859
65265
  ws.send(JSON.stringify({
64860
65266
  type: "sqlMigration",
64861
65267
  fileName,
@@ -64869,7 +65275,7 @@ data: reload
64869
65275
  const sqlFiles = entries.filter((entry) => entry.endsWith(".sql"));
64870
65276
  if (sqlFiles.length > 0 && sqlFileQueue.length === 0) {
64871
65277
  for (const sqlFile of sqlFiles.sort()) {
64872
- queueSqlFile(path11.join(sqlToApplyPath, sqlFile));
65278
+ queueSqlFile(path13.join(sqlToApplyPath, sqlFile));
64873
65279
  }
64874
65280
  await processNextSqlFile();
64875
65281
  }
@@ -65048,7 +65454,7 @@ data: reload
65048
65454
  }
65049
65455
  info(colors.blue(`\uD83D\uDD0D Found ${sqlFiles.length} SQL file(s) in sql_to_apply/`));
65050
65456
  for (const sqlFile of sqlFiles) {
65051
- const filePath = path11.join(sqlToApplyPath, sqlFile);
65457
+ const filePath = path13.join(sqlToApplyPath, sqlFile);
65052
65458
  queueSqlFile(filePath);
65053
65459
  }
65054
65460
  await processNextSqlFile();
@@ -65066,11 +65472,11 @@ data: reload
65066
65472
  if (!filename)
65067
65473
  return;
65068
65474
  const fileStr = typeof filename === "string" ? filename : filename.toString();
65069
- const changedPath = path11.join(sqlToApplyPath, fileStr);
65475
+ const changedPath = path13.join(sqlToApplyPath, fileStr);
65070
65476
  if (!changedPath.endsWith(".sql")) {
65071
65477
  return;
65072
65478
  }
65073
- const fileName = path11.basename(changedPath);
65479
+ const fileName = path13.basename(changedPath);
65074
65480
  if (sqlDebounceTimeouts[changedPath]) {
65075
65481
  clearTimeout(sqlDebounceTimeouts[changedPath]);
65076
65482
  }
@@ -65128,11 +65534,11 @@ data: reload
65128
65534
  async function genRunnablesTs(schemaOverrides = {}) {
65129
65535
  info(colors.blue("\uD83D\uDD04 Generating wmill.d.ts..."));
65130
65536
  const localPath = process14.cwd();
65131
- const backendPath = path11.join(localPath, APP_BACKEND_FOLDER);
65537
+ const backendPath = path13.join(localPath, APP_BACKEND_FOLDER);
65132
65538
  let runnables = await loadRunnablesFromBackend(backendPath);
65133
65539
  if (Object.keys(runnables).length === 0) {
65134
65540
  try {
65135
- const rawApp = await yamlParseFile(path11.join(localPath, "raw_app.yaml"));
65541
+ const rawApp = await yamlParseFile(path13.join(localPath, "raw_app.yaml"));
65136
65542
  runnables = rawApp?.["runnables"] ?? {};
65137
65543
  } catch {
65138
65544
  runnables = {};
@@ -65148,7 +65554,7 @@ async function genRunnablesTs(schemaOverrides = {}) {
65148
65554
  }
65149
65555
  try {
65150
65556
  const newWmillTs = genWmillTs(runnables);
65151
- writeFileSync2(path11.join(process14.cwd(), "wmill.d.ts"), newWmillTs);
65557
+ writeFileSync3(path13.join(process14.cwd(), "wmill.d.ts"), newWmillTs);
65152
65558
  } catch (error2) {
65153
65559
  error(colors.red(`Failed to generate wmill.d.ts: ${error2.message}`));
65154
65560
  }
@@ -65166,10 +65572,10 @@ function convertRunnablesToApiFormat(runnables) {
65166
65572
  async function loadRunnables() {
65167
65573
  try {
65168
65574
  const localPath = process14.cwd();
65169
- const backendPath = path11.join(localPath, APP_BACKEND_FOLDER);
65575
+ const backendPath = path13.join(localPath, APP_BACKEND_FOLDER);
65170
65576
  let runnables = await loadRunnablesFromBackend(backendPath);
65171
65577
  if (Object.keys(runnables).length === 0) {
65172
- const rawApp = await yamlParseFile(path11.join(localPath, "raw_app.yaml"));
65578
+ const rawApp = await yamlParseFile(path13.join(localPath, "raw_app.yaml"));
65173
65579
  runnables = rawApp?.runnables ?? {};
65174
65580
  }
65175
65581
  convertRunnablesToApiFormat(runnables);
@@ -65650,7 +66056,7 @@ var init_dev = __esm(async () => {
65650
66056
 
65651
66057
  // src/commands/app/lint.ts
65652
66058
  import * as fs11 from "node:fs";
65653
- import * as path12 from "node:path";
66059
+ import * as path14 from "node:path";
65654
66060
  import process15 from "node:process";
65655
66061
  function validateRawAppYaml(appData) {
65656
66062
  const errors = [];
@@ -65665,7 +66071,7 @@ function validateRawAppYaml(appData) {
65665
66071
  async function validateRunnables(appDir, appData) {
65666
66072
  const errors = [];
65667
66073
  const warnings = [];
65668
- const backendPath = path12.join(appDir, APP_BACKEND_FOLDER);
66074
+ const backendPath = path14.join(appDir, APP_BACKEND_FOLDER);
65669
66075
  const runnablesFromBackend = await loadRunnablesFromBackend(backendPath);
65670
66076
  const hasBackendRunnables = Object.keys(runnablesFromBackend).length > 0;
65671
66077
  const hasYamlRunnables = appData.runnables && typeof appData.runnables === "object" && !Array.isArray(appData.runnables) && Object.keys(appData.runnables).length > 0;
@@ -65699,12 +66105,12 @@ async function validateBuild(appDir) {
65699
66105
  async function lintRawApp(appDir, opts) {
65700
66106
  const errors = [];
65701
66107
  const warnings = [];
65702
- const currentDirName = path12.basename(appDir);
66108
+ const currentDirName = path14.basename(appDir);
65703
66109
  if (!hasFolderSuffix(currentDirName, "raw_app")) {
65704
66110
  errors.push(`Not a raw app folder: '${currentDirName}' does not end with '${getFolderSuffix("raw_app")}'`);
65705
66111
  return { valid: false, errors, warnings };
65706
66112
  }
65707
- const rawAppPath = path12.join(appDir, "raw_app.yaml");
66113
+ const rawAppPath = path14.join(appDir, "raw_app.yaml");
65708
66114
  if (!fs11.existsSync(rawAppPath)) {
65709
66115
  errors.push("Missing raw_app.yaml file");
65710
66116
  return { valid: false, errors, warnings };
@@ -65788,7 +66194,7 @@ var init_lint2 = __esm(async () => {
65788
66194
 
65789
66195
  // src/commands/app/new.ts
65790
66196
  import { stat as stat8, writeFile as writeFile9, mkdir as mkdir5 } from "node:fs/promises";
65791
- import path13 from "node:path";
66197
+ import path15 from "node:path";
65792
66198
  function validateAppPath(appPath) {
65793
66199
  if (!appPath.startsWith("u/") && !appPath.startsWith("f/")) {
65794
66200
  return {
@@ -65993,7 +66399,7 @@ CREATE SCHEMA IF NOT EXISTS ${schemaName};
65993
66399
  }
65994
66400
  await loadNonDottedPathsSetting();
65995
66401
  const folderName = buildFolderPath(appPath, "raw_app");
65996
- const appDir = path13.join(process.cwd(), folderName);
66402
+ const appDir = path15.join(process.cwd(), folderName);
65997
66403
  try {
65998
66404
  await stat8(appDir);
65999
66405
  const overwrite = await Confirm.prompt({
@@ -66006,17 +66412,17 @@ CREATE SCHEMA IF NOT EXISTS ${schemaName};
66006
66412
  }
66007
66413
  } catch {}
66008
66414
  await mkdir5(appDir, { recursive: true });
66009
- await mkdir5(path13.join(appDir, "backend"), { recursive: true });
66010
- await mkdir5(path13.join(appDir, "sql_to_apply"), { recursive: true });
66415
+ await mkdir5(path15.join(appDir, "backend"), { recursive: true });
66416
+ await mkdir5(path15.join(appDir, "sql_to_apply"), { recursive: true });
66011
66417
  const rawAppConfig = {
66012
66418
  summary
66013
66419
  };
66014
66420
  if (dataConfig.datatable) {
66015
66421
  rawAppConfig.data = dataConfig;
66016
66422
  }
66017
- await writeFile9(path13.join(appDir, "raw_app.yaml"), import_yaml21.stringify(rawAppConfig, yamlOptions), "utf-8");
66423
+ await writeFile9(path15.join(appDir, "raw_app.yaml"), import_yaml21.stringify(rawAppConfig, yamlOptions), "utf-8");
66018
66424
  for (const [filePath, content] of Object.entries(template.files)) {
66019
- const fullPath = path13.join(appDir, filePath.slice(1));
66425
+ const fullPath = path15.join(appDir, filePath.slice(1));
66020
66426
  await writeFile9(fullPath, content.trim() + `
66021
66427
  `, "utf-8");
66022
66428
  }
@@ -66026,21 +66432,21 @@ CREATE SCHEMA IF NOT EXISTS ${schemaName};
66026
66432
  schema: dataConfig.schema
66027
66433
  } : undefined;
66028
66434
  const agentsContent = generateAgentsDocumentation(dataForDocs);
66029
- await writeFile9(path13.join(appDir, "AGENTS.md"), agentsContent, "utf-8");
66030
- await writeFile9(path13.join(appDir, "CLAUDE.md"), `Instructions are in @AGENTS.md
66435
+ await writeFile9(path15.join(appDir, "AGENTS.md"), agentsContent, "utf-8");
66436
+ await writeFile9(path15.join(appDir, "CLAUDE.md"), `Instructions are in @AGENTS.md
66031
66437
  `, "utf-8");
66032
66438
  const datatablesContent = generateDatatablesDocumentation(dataForDocs);
66033
- await writeFile9(path13.join(appDir, "DATATABLES.md"), datatablesContent, "utf-8");
66439
+ await writeFile9(path15.join(appDir, "DATATABLES.md"), datatablesContent, "utf-8");
66034
66440
  const exampleRunnable = {
66035
66441
  type: "inline",
66036
66442
  path: undefined
66037
66443
  };
66038
- await writeFile9(path13.join(appDir, "backend", "a.yaml"), import_yaml21.stringify(exampleRunnable, yamlOptions), "utf-8");
66039
- await writeFile9(path13.join(appDir, "backend", "a.ts"), `export async function main(x: number): Promise<string> {
66444
+ await writeFile9(path15.join(appDir, "backend", "a.yaml"), import_yaml21.stringify(exampleRunnable, yamlOptions), "utf-8");
66445
+ await writeFile9(path15.join(appDir, "backend", "a.ts"), `export async function main(x: number): Promise<string> {
66040
66446
  return \`Hello from backend! x = \${x}\`;
66041
66447
  }
66042
66448
  `, "utf-8");
66043
- await writeFile9(path13.join(appDir, "sql_to_apply", "README.md"), `# SQL Migrations Folder
66449
+ await writeFile9(path15.join(appDir, "sql_to_apply", "README.md"), `# SQL Migrations Folder
66044
66450
 
66045
66451
  This folder is for SQL migration files that will be applied to datatables during development.
66046
66452
 
@@ -66068,7 +66474,7 @@ This folder is for SQL migration files that will be applied to datatables during
66068
66474
  - Use idempotent SQL (\`CREATE TABLE IF NOT EXISTS\`, etc.)
66069
66475
  `);
66070
66476
  if (createSchemaSQL && schemaName) {
66071
- await writeFile9(path13.join(appDir, "sql_to_apply", `000_create_schema_${schemaName}.sql`), createSchemaSQL, "utf-8");
66477
+ await writeFile9(path15.join(appDir, "sql_to_apply", `000_create_schema_${schemaName}.sql`), createSchemaSQL, "utf-8");
66072
66478
  }
66073
66479
  info("");
66074
66480
  info(colors.bold.green(`App created successfully at ${folderName}/`));
@@ -66362,8 +66768,8 @@ async function pushApp(workspace, remotePath, localPath, message) {
66362
66768
  if (!localPath.endsWith(SEP13)) {
66363
66769
  localPath += SEP13;
66364
66770
  }
66365
- const path14 = localPath + "app.yaml";
66366
- const localApp = await yamlParseFile(path14);
66771
+ const path16 = localPath + "app.yaml";
66772
+ const localApp = await yamlParseFile(path16);
66367
66773
  replaceInlineScripts2(localApp.value, localPath, true);
66368
66774
  await generatingPolicy2(localApp, remotePath, localApp?.["public"] ?? localApp?.["policy"]?.["execution_mode"] == "anonymous");
66369
66775
  if (app) {
@@ -66392,13 +66798,13 @@ async function pushApp(workspace, remotePath, localPath, message) {
66392
66798
  });
66393
66799
  }
66394
66800
  }
66395
- async function generatingPolicy2(app, path14, publicApp) {
66396
- info(colors.gray(`Generating fresh policy for app ${path14}...`));
66801
+ async function generatingPolicy2(app, path16, publicApp) {
66802
+ info(colors.gray(`Generating fresh policy for app ${path16}...`));
66397
66803
  try {
66398
66804
  app.policy = await updatePolicy(app.value, undefined);
66399
66805
  app.policy.execution_mode = publicApp ? "anonymous" : "publisher";
66400
66806
  } catch (e) {
66401
- error(colors.red(`Error generating policy for app ${path14}: ${e}`));
66807
+ error(colors.red(`Error generating policy for app ${path16}: ${e}`));
66402
66808
  throw e;
66403
66809
  }
66404
66810
  }
@@ -66427,12 +66833,12 @@ async function list4(opts) {
66427
66833
  new Table2().header(["path", "summary"]).padding(2).border(true).body(total.map((x) => [x.path, x.summary])).render();
66428
66834
  }
66429
66835
  }
66430
- async function get3(opts, path14) {
66836
+ async function get3(opts, path16) {
66431
66837
  const workspace = await resolveWorkspace(opts);
66432
66838
  await requireLogin(opts);
66433
66839
  const a = await getAppByPath({
66434
66840
  workspace: workspace.workspaceId,
66435
- path: path14
66841
+ path: path16
66436
66842
  });
66437
66843
  if (opts.json) {
66438
66844
  console.log(JSON.stringify(a));
@@ -66693,9 +67099,9 @@ function compileResourceTypeToTsType(schema) {
66693
67099
  }
66694
67100
 
66695
67101
  // src/commands/resource-type/resource-type.ts
66696
- import { writeFileSync as writeFileSync3 } from "node:fs";
67102
+ import { writeFileSync as writeFileSync4 } from "node:fs";
66697
67103
  import { stat as stat10, writeFile as writeFile11 } from "node:fs/promises";
66698
- import path14 from "node:path";
67104
+ import path16 from "node:path";
66699
67105
  import process16 from "node:process";
66700
67106
  async function pushResourceType(workspace, remotePath, resource, localResource) {
66701
67107
  remotePath = removeType(remotePath, "resource-type");
@@ -66775,12 +67181,12 @@ async function newResourceType(opts, name) {
66775
67181
  });
66776
67182
  info(colors.green(`Created ${filePath}`));
66777
67183
  }
66778
- async function get5(opts, path15) {
67184
+ async function get5(opts, path17) {
66779
67185
  const workspace = await resolveWorkspace(opts);
66780
67186
  await requireLogin(opts);
66781
67187
  const rt = await getResourceType({
66782
67188
  workspace: workspace.workspaceId,
66783
- path: path15
67189
+ path: path17
66784
67190
  });
66785
67191
  if (opts.json) {
66786
67192
  console.log(JSON.stringify(rt));
@@ -66810,7 +67216,7 @@ async function generateRTNamespace(opts) {
66810
67216
  `);
66811
67217
  namespaceContent += `
66812
67218
  }`;
66813
- writeFileSync3(path14.join(process16.cwd(), "rt.d.ts"), namespaceContent);
67219
+ writeFileSync4(path16.join(process16.cwd(), "rt.d.ts"), namespaceContent);
66814
67220
  info(colors.green("Created rt.d.ts with resource types namespace (RT) for TypeScript."));
66815
67221
  }
66816
67222
  var import_yaml24, command13, resource_type_default;
@@ -66851,11 +67257,11 @@ async function list7(opts) {
66851
67257
  ])).render();
66852
67258
  }
66853
67259
  }
66854
- async function newVariable(opts, path15) {
66855
- if (!validatePath(path15)) {
67260
+ async function newVariable(opts, path17) {
67261
+ if (!validatePath(path17)) {
66856
67262
  return;
66857
67263
  }
66858
- const filePath = path15 + ".variable.yaml";
67264
+ const filePath = path17 + ".variable.yaml";
66859
67265
  try {
66860
67266
  await stat11(filePath);
66861
67267
  throw new Error("File already exists: " + filePath);
@@ -66874,12 +67280,12 @@ async function newVariable(opts, path15) {
66874
67280
  });
66875
67281
  info(colors.green(`Created ${filePath}`));
66876
67282
  }
66877
- async function get6(opts, path15) {
67283
+ async function get6(opts, path17) {
66878
67284
  const workspace = await resolveWorkspace(opts);
66879
67285
  await requireLogin(opts);
66880
67286
  const v = await getVariable({
66881
67287
  workspace: workspace.workspaceId,
66882
- path: path15
67288
+ path: path17
66883
67289
  });
66884
67290
  if (opts.json) {
66885
67291
  console.log(JSON.stringify(v));
@@ -67005,11 +67411,11 @@ async function list8(opts) {
67005
67411
  new Table2().header(["Path", "Schedule"]).padding(2).border(true).body(schedules.map((x) => [x.path, x.schedule])).render();
67006
67412
  }
67007
67413
  }
67008
- async function newSchedule(opts, path15) {
67009
- if (!validatePath(path15)) {
67414
+ async function newSchedule(opts, path17) {
67415
+ if (!validatePath(path17)) {
67010
67416
  return;
67011
67417
  }
67012
- const filePath = path15 + ".schedule.yaml";
67418
+ const filePath = path17 + ".schedule.yaml";
67013
67419
  try {
67014
67420
  await stat12(filePath);
67015
67421
  throw new Error("File already exists: " + filePath);
@@ -67032,12 +67438,12 @@ async function newSchedule(opts, path15) {
67032
67438
  });
67033
67439
  info(colors.green(`Created ${filePath}`));
67034
67440
  }
67035
- async function get7(opts, path15) {
67441
+ async function get7(opts, path17) {
67036
67442
  const workspace = await resolveWorkspace(opts);
67037
67443
  await requireLogin(opts);
67038
67444
  const s = await getSchedule({
67039
67445
  workspace: workspace.workspaceId,
67040
- path: path15
67446
+ path: path17
67041
67447
  });
67042
67448
  if (opts.json) {
67043
67449
  console.log(JSON.stringify(s));
@@ -67050,35 +67456,35 @@ async function get7(opts, path15) {
67050
67456
  console.log(colors.bold("Enabled:") + " " + (s.enabled ? "true" : "false"));
67051
67457
  }
67052
67458
  }
67053
- async function pushSchedule(workspace, path15, schedule, localSchedule) {
67054
- path15 = removeType(path15, "schedule").replaceAll(SEP16, "/");
67055
- debug(`Processing local schedule ${path15}`);
67459
+ async function pushSchedule(workspace, path17, schedule, localSchedule) {
67460
+ path17 = removeType(path17, "schedule").replaceAll(SEP16, "/");
67461
+ debug(`Processing local schedule ${path17}`);
67056
67462
  try {
67057
- schedule = await getSchedule({ workspace, path: path15 });
67058
- debug(`Schedule ${path15} exists on remote`);
67463
+ schedule = await getSchedule({ workspace, path: path17 });
67464
+ debug(`Schedule ${path17} exists on remote`);
67059
67465
  } catch {
67060
- debug(`Schedule ${path15} does not exist on remote`);
67466
+ debug(`Schedule ${path17} does not exist on remote`);
67061
67467
  }
67062
67468
  if (schedule) {
67063
67469
  if (isSuperset(localSchedule, schedule)) {
67064
- debug(`Schedule ${path15} is up to date`);
67470
+ debug(`Schedule ${path17} is up to date`);
67065
67471
  return;
67066
67472
  }
67067
- debug(`Updating schedule ${path15}`);
67473
+ debug(`Updating schedule ${path17}`);
67068
67474
  try {
67069
- info(colors.bold.yellow(`Updating schedule ${path15}`));
67475
+ info(colors.bold.yellow(`Updating schedule ${path17}`));
67070
67476
  await updateSchedule({
67071
67477
  workspace,
67072
- path: path15,
67478
+ path: path17,
67073
67479
  requestBody: {
67074
67480
  ...localSchedule
67075
67481
  }
67076
67482
  });
67077
67483
  if (localSchedule.enabled != schedule.enabled) {
67078
- info(colors.bold.yellow(`Schedule ${path15} is ${localSchedule.enabled ? "enabled" : "disabled"} locally but not on remote, updating remote`));
67484
+ info(colors.bold.yellow(`Schedule ${path17} is ${localSchedule.enabled ? "enabled" : "disabled"} locally but not on remote, updating remote`));
67079
67485
  await setScheduleEnabled({
67080
67486
  workspace,
67081
- path: path15,
67487
+ path: path17,
67082
67488
  requestBody: {
67083
67489
  enabled: localSchedule.enabled
67084
67490
  }
@@ -67089,12 +67495,12 @@ async function pushSchedule(workspace, path15, schedule, localSchedule) {
67089
67495
  throw e;
67090
67496
  }
67091
67497
  } else {
67092
- console.log(colors.bold.yellow("Creating new schedule " + path15));
67498
+ console.log(colors.bold.yellow("Creating new schedule " + path17));
67093
67499
  try {
67094
67500
  await createSchedule({
67095
67501
  workspace,
67096
67502
  requestBody: {
67097
- path: path15,
67503
+ path: path17,
67098
67504
  ...localSchedule
67099
67505
  }
67100
67506
  });
@@ -67762,7 +68168,7 @@ var init_settings = __esm(async () => {
67762
68168
  // src/commands/instance/instance.ts
67763
68169
  import { readFile as readFile13, writeFile as writeFile15, readdir as readdir8, mkdir as mkdir7, rm as rm3, stat as stat13 } from "node:fs/promises";
67764
68170
  import { appendFile } from "node:fs/promises";
67765
- import * as path15 from "node:path";
68171
+ import * as path17 from "node:path";
67766
68172
  async function allInstances() {
67767
68173
  try {
67768
68174
  const file = await getInstancesConfigFilePath();
@@ -67939,7 +68345,7 @@ async function instancePull(opts) {
67939
68345
  if (confirm) {
67940
68346
  if (uChanges > 0) {
67941
68347
  if (opts.folderPerInstance && opts.prefixSettings) {
67942
- await mkdir7(path15.join(rootDir, opts.prefix), {
68348
+ await mkdir7(path17.join(rootDir, opts.prefix), {
67943
68349
  recursive: true
67944
68350
  });
67945
68351
  }
@@ -67973,10 +68379,10 @@ Pulling all workspaces`);
67973
68379
  info(`
67974
68380
  Pulling workspace ` + remoteWorkspace.id);
67975
68381
  const workspaceName = opts?.folderPerInstance ? instance.prefix + "/" + remoteWorkspace.id : instance.prefix + "_" + remoteWorkspace.id;
67976
- await mkdir7(path15.join(rootDir, workspaceName), {
68382
+ await mkdir7(path17.join(rootDir, workspaceName), {
67977
68383
  recursive: true
67978
68384
  });
67979
- process.chdir(path15.join(rootDir, workspaceName));
68385
+ process.chdir(path17.join(rootDir, workspaceName));
67980
68386
  await addWorkspace({
67981
68387
  remote: instance.remote,
67982
68388
  name: workspaceName,
@@ -68011,7 +68417,7 @@ Pulling workspace ` + remoteWorkspace.id);
68011
68417
  if (confirmDelete) {
68012
68418
  for (const workspace of localWorkspacesToDelete) {
68013
68419
  await removeWorkspace(workspace.id, false, {});
68014
- await rm3(path15.join(rootDir, workspace.dir), {
68420
+ await rm3(path17.join(rootDir, workspace.dir), {
68015
68421
  recursive: true
68016
68422
  });
68017
68423
  }
@@ -68100,12 +68506,12 @@ Pushing all workspaces: ${localWorkspaces.map((x) => x.id).join(", ")}`);
68100
68506
  info(`
68101
68507
  Pushing workspace ` + localWorkspace.id);
68102
68508
  try {
68103
- process.chdir(path15.join(rootDir, localWorkspace.dir));
68509
+ process.chdir(path17.join(rootDir, localWorkspace.dir));
68104
68510
  } catch (_) {
68105
68511
  throw new Error("Workspace folder not found, are you in the right directory?");
68106
68512
  }
68107
68513
  try {
68108
- const workspaceSettings = await yamlParseFile(path15.join(process.cwd(), "settings.yaml"));
68514
+ const workspaceSettings = await yamlParseFile(path17.join(process.cwd(), "settings.yaml"));
68109
68515
  await add({
68110
68516
  token: instance.token,
68111
68517
  workspace: undefined,
@@ -68353,8 +68759,8 @@ async function createToken2(opts) {
68353
68759
  }
68354
68760
  info("Token: " + await createToken({ requestBody: {} }));
68355
68761
  }
68356
- async function pushWorkspaceUser(workspace, path16, user, localUser) {
68357
- const email = removePathPrefix(removeType(path16, "user"), "users");
68762
+ async function pushWorkspaceUser(workspace, path18, user, localUser) {
68763
+ const email = removePathPrefix(removeType(path18, "user"), "users");
68358
68764
  debug(`Processing local user ${email}`);
68359
68765
  if (!["operator", "developer", "admin"].includes(localUser.role)) {
68360
68766
  throw new Error(`Invalid role for user ${email}: ${localUser.role}`);
@@ -68417,8 +68823,8 @@ async function pushWorkspaceUser(workspace, path16, user, localUser) {
68417
68823
  }
68418
68824
  }
68419
68825
  }
68420
- async function pushGroup(workspace, path16, group, localGroup) {
68421
- const name = removePathPrefix(removeType(path16, "group"), "groups");
68826
+ async function pushGroup(workspace, path18, group, localGroup) {
68827
+ const name = removePathPrefix(removeType(path18, "group"), "groups");
68422
68828
  debug(`Processing local group ${name}`);
68423
68829
  try {
68424
68830
  const remoteGroup = await getGroup({
@@ -68669,11 +69075,11 @@ async function push9(opts, filePath) {
68669
69075
  const content = fs12.readFileSync(filePath, "utf8");
68670
69076
  await pushWorkspaceDependencies(workspace.workspaceId, filePath, null, content);
68671
69077
  }
68672
- async function pushWorkspaceDependencies(workspace, path16, _befObj, newDependenciesContent) {
69078
+ async function pushWorkspaceDependencies(workspace, path18, _befObj, newDependenciesContent) {
68673
69079
  try {
68674
- const res = workspaceDependenciesPathToLanguageAndFilename(path16);
69080
+ const res = workspaceDependenciesPathToLanguageAndFilename(path18);
68675
69081
  if (!res) {
68676
- throw new Error(`Unknown workspace dependencies file format: ${path16}`);
69082
+ throw new Error(`Unknown workspace dependencies file format: ${path18}`);
68677
69083
  }
68678
69084
  const { language, name } = res;
68679
69085
  const displayName = name ? `named dependencies "${name}"` : `workspace default dependencies`;
@@ -68727,7 +69133,7 @@ var init_dependencies = __esm(async () => {
68727
69133
  // src/commands/trigger/trigger.ts
68728
69134
  import { stat as stat14, writeFile as writeFile17 } from "node:fs/promises";
68729
69135
  import { sep as SEP17 } from "node:path";
68730
- async function getTrigger(triggerType, workspace, path16) {
69136
+ async function getTrigger(triggerType, workspace, path18) {
68731
69137
  const triggerFunctions = {
68732
69138
  http: getHttpTrigger,
68733
69139
  websocket: getWebsocketTrigger,
@@ -68740,10 +69146,10 @@ async function getTrigger(triggerType, workspace, path16) {
68740
69146
  email: getEmailTrigger
68741
69147
  };
68742
69148
  const triggerFunction = triggerFunctions[triggerType];
68743
- const trigger = await triggerFunction({ workspace, path: path16 });
69149
+ const trigger = await triggerFunction({ workspace, path: path18 });
68744
69150
  return trigger;
68745
69151
  }
68746
- async function updateTrigger(triggerType, workspace, path16, trigger) {
69152
+ async function updateTrigger(triggerType, workspace, path18, trigger) {
68747
69153
  const triggerFunctions = {
68748
69154
  http: updateHttpTrigger,
68749
69155
  websocket: updateWebsocketTrigger,
@@ -68756,9 +69162,9 @@ async function updateTrigger(triggerType, workspace, path16, trigger) {
68756
69162
  email: updateEmailTrigger
68757
69163
  };
68758
69164
  const triggerFunction = triggerFunctions[triggerType];
68759
- await triggerFunction({ workspace, path: path16, requestBody: trigger });
69165
+ await triggerFunction({ workspace, path: path18, requestBody: trigger });
68760
69166
  }
68761
- async function createTrigger(triggerType, workspace, path16, trigger) {
69167
+ async function createTrigger(triggerType, workspace, path18, trigger) {
68762
69168
  const triggerFunctions = {
68763
69169
  http: createHttpTrigger,
68764
69170
  websocket: createWebsocketTrigger,
@@ -68771,38 +69177,38 @@ async function createTrigger(triggerType, workspace, path16, trigger) {
68771
69177
  email: createEmailTrigger
68772
69178
  };
68773
69179
  const triggerFunction = triggerFunctions[triggerType];
68774
- await triggerFunction({ workspace, path: path16, requestBody: trigger });
69180
+ await triggerFunction({ workspace, path: path18, requestBody: trigger });
68775
69181
  }
68776
- async function pushTrigger(triggerType, workspace, path16, trigger, localTrigger) {
68777
- path16 = removeType(path16, triggerType + "_trigger").replaceAll(SEP17, "/");
68778
- debug(`Processing local ${triggerType} trigger ${path16}`);
69182
+ async function pushTrigger(triggerType, workspace, path18, trigger, localTrigger) {
69183
+ path18 = removeType(path18, triggerType + "_trigger").replaceAll(SEP17, "/");
69184
+ debug(`Processing local ${triggerType} trigger ${path18}`);
68779
69185
  try {
68780
- trigger = await getTrigger(triggerType, workspace, path16);
68781
- debug(`${triggerType} trigger ${path16} exists on remote`);
69186
+ trigger = await getTrigger(triggerType, workspace, path18);
69187
+ debug(`${triggerType} trigger ${path18} exists on remote`);
68782
69188
  } catch {
68783
- debug(`${triggerType} trigger ${path16} does not exist on remote`);
69189
+ debug(`${triggerType} trigger ${path18} does not exist on remote`);
68784
69190
  }
68785
69191
  if (trigger) {
68786
69192
  if (isSuperset(localTrigger, trigger)) {
68787
- debug(`${triggerType} trigger ${path16} is up to date`);
69193
+ debug(`${triggerType} trigger ${path18} is up to date`);
68788
69194
  return;
68789
69195
  }
68790
- debug(`${triggerType} trigger ${path16} is not up-to-date, updating...`);
69196
+ debug(`${triggerType} trigger ${path18} is not up-to-date, updating...`);
68791
69197
  try {
68792
- await updateTrigger(triggerType, workspace, path16, {
69198
+ await updateTrigger(triggerType, workspace, path18, {
68793
69199
  ...localTrigger,
68794
- path: path16
69200
+ path: path18
68795
69201
  });
68796
69202
  } catch (e) {
68797
69203
  console.error(e.body);
68798
69204
  throw e;
68799
69205
  }
68800
69206
  } else {
68801
- console.log(colors.bold.yellow(`Creating new ${triggerType} trigger: ${path16}`));
69207
+ console.log(colors.bold.yellow(`Creating new ${triggerType} trigger: ${path18}`));
68802
69208
  try {
68803
- await createTrigger(triggerType, workspace, path16, {
69209
+ await createTrigger(triggerType, workspace, path18, {
68804
69210
  ...localTrigger,
68805
- path: path16
69211
+ path: path18
68806
69212
  });
68807
69213
  } catch (e) {
68808
69214
  console.error(e.body);
@@ -68883,8 +69289,8 @@ async function pushNativeTrigger(workspace, filePath, _remoteTrigger, localTrigg
68883
69289
  }
68884
69290
  }
68885
69291
  }
68886
- async function newTrigger(opts, path16) {
68887
- if (!validatePath(path16)) {
69292
+ async function newTrigger(opts, path18) {
69293
+ if (!validatePath(path18)) {
68888
69294
  return;
68889
69295
  }
68890
69296
  if (!opts.kind) {
@@ -68894,7 +69300,7 @@ async function newTrigger(opts, path16) {
68894
69300
  throw new Error("Invalid trigger kind: " + opts.kind + ". Valid kinds: " + TRIGGER_TYPES.join(", "));
68895
69301
  }
68896
69302
  const kind = opts.kind;
68897
- const filePath = `${path16}.${kind}_trigger.yaml`;
69303
+ const filePath = `${path18}.${kind}_trigger.yaml`;
68898
69304
  try {
68899
69305
  await stat14(filePath);
68900
69306
  throw new Error("File already exists: " + filePath);
@@ -68909,14 +69315,14 @@ async function newTrigger(opts, path16) {
68909
69315
  });
68910
69316
  info(colors.green(`Created ${filePath}`));
68911
69317
  }
68912
- async function get8(opts, path16) {
69318
+ async function get8(opts, path18) {
68913
69319
  const workspace = await resolveWorkspace(opts);
68914
69320
  await requireLogin(opts);
68915
69321
  if (opts.kind) {
68916
69322
  if (!checkIfValidTrigger(opts.kind)) {
68917
69323
  throw new Error("Invalid trigger kind: " + opts.kind + ". Valid kinds: " + TRIGGER_TYPES.join(", "));
68918
69324
  }
68919
- const trigger = await getTrigger(opts.kind, workspace.workspaceId, path16);
69325
+ const trigger = await getTrigger(opts.kind, workspace.workspaceId, path18);
68920
69326
  if (opts.json) {
68921
69327
  console.log(JSON.stringify(trigger));
68922
69328
  } else {
@@ -68931,12 +69337,12 @@ async function get8(opts, path16) {
68931
69337
  const matches = [];
68932
69338
  for (const kind of TRIGGER_TYPES) {
68933
69339
  try {
68934
- const trigger = await getTrigger(kind, workspace.workspaceId, path16);
69340
+ const trigger = await getTrigger(kind, workspace.workspaceId, path18);
68935
69341
  matches.push({ kind, trigger });
68936
69342
  } catch {}
68937
69343
  }
68938
69344
  if (matches.length === 0) {
68939
- throw new Error("No trigger found at path: " + path16);
69345
+ throw new Error("No trigger found at path: " + path18);
68940
69346
  }
68941
69347
  if (matches.length === 1) {
68942
69348
  const { kind, trigger } = matches[0];
@@ -68951,7 +69357,7 @@ async function get8(opts, path16) {
68951
69357
  }
68952
69358
  return;
68953
69359
  }
68954
- console.log("Multiple triggers found at path " + path16 + ":");
69360
+ console.log("Multiple triggers found at path " + path18 + ":");
68955
69361
  for (const m of matches) {
68956
69362
  console.log(" - " + m.kind);
68957
69363
  }
@@ -69129,7 +69535,7 @@ var init_trigger = __esm(async () => {
69129
69535
  });
69130
69536
 
69131
69537
  // src/types.ts
69132
- import * as path16 from "node:path";
69538
+ import * as path18 from "node:path";
69133
69539
  import { sep as SEP18 } from "node:path";
69134
69540
  import { readFileSync as readFileSync5 } from "node:fs";
69135
69541
  function isSuperset(subset, superset) {
@@ -69174,8 +69580,8 @@ function showDiff(local, remote) {
69174
69580
  }
69175
69581
  info(finalString);
69176
69582
  }
69177
- function showConflict(path17, local, remote) {
69178
- info(colors.yellow(`- ${path17}`));
69583
+ function showConflict(path19, local, remote) {
69584
+ info(colors.yellow(`- ${path19}`));
69179
69585
  showDiff(local, remote);
69180
69586
  info("\x1B[31mlocal\x1B[31m - \x1B[32mremote\x1B[32m");
69181
69587
  info(`
@@ -69252,6 +69658,9 @@ function parseFromFile(p) {
69252
69658
  }
69253
69659
  }
69254
69660
  function getTypeStrFromPath(p) {
69661
+ if (isScriptModulePath(p)) {
69662
+ return "script";
69663
+ }
69255
69664
  if (isFlowPath(p)) {
69256
69665
  return "flow";
69257
69666
  }
@@ -69264,7 +69673,7 @@ function getTypeStrFromPath(p) {
69264
69673
  if (p.startsWith("dependencies" + SEP18)) {
69265
69674
  return "workspace_dependencies";
69266
69675
  }
69267
- const parsed = path16.parse(p);
69676
+ const parsed = path18.parse(p);
69268
69677
  if (parsed.ext == ".go" || parsed.ext == ".ts" || parsed.ext == ".sh" || parsed.ext == ".py" || parsed.ext == ".sql" || parsed.ext == ".gql" || parsed.ext == ".ps1" || parsed.ext == ".js" || parsed.ext == ".php" || parsed.ext == ".rs" || parsed.ext == ".cs" || parsed.ext == ".nu" || parsed.ext == ".java" || parsed.ext == ".rb" || parsed.ext == ".yml" && parsed.name.split(".").pop() == "playbook") {
69269
69678
  return "script";
69270
69679
  }
@@ -69291,14 +69700,14 @@ function getTypeStrFromPath(p) {
69291
69700
  }
69292
69701
  }
69293
69702
  function removeType(str, type) {
69294
- const normalizedStr = path16.normalize(str).replaceAll(SEP18, "/");
69703
+ const normalizedStr = path18.normalize(str).replaceAll(SEP18, "/");
69295
69704
  if (!normalizedStr.endsWith("." + type + ".yaml") && !normalizedStr.endsWith("." + type + ".json")) {
69296
69705
  throw new Error(str + " does not end with ." + type + ".(yaml|json)");
69297
69706
  }
69298
69707
  return normalizedStr.slice(0, normalizedStr.length - type.length - 6);
69299
69708
  }
69300
69709
  function extractNativeTriggerInfo(p) {
69301
- const normalizedPath = path16.normalize(p).replaceAll(SEP18, "/");
69710
+ const normalizedPath = path18.normalize(p).replaceAll(SEP18, "/");
69302
69711
  const withoutExt = normalizedPath.replace(/\.(json|yaml)$/, "");
69303
69712
  const match2 = withoutExt.match(/^(.+)\.(flow|script)\.([^.]+)\.(\w+)_native_trigger$/);
69304
69713
  if (!match2) {
@@ -69312,8 +69721,8 @@ function extractNativeTriggerInfo(p) {
69312
69721
  };
69313
69722
  }
69314
69723
  function removePathPrefix(str, prefix) {
69315
- const normalizedStr = path16.normalize(str).replaceAll(SEP18, "/");
69316
- const normalizedPrefix = path16.normalize(prefix).replaceAll(SEP18, "/");
69724
+ const normalizedStr = path18.normalize(str).replaceAll(SEP18, "/");
69725
+ const normalizedPrefix = path18.normalize(prefix).replaceAll(SEP18, "/");
69317
69726
  if (normalizedStr === normalizedPrefix) {
69318
69727
  return "";
69319
69728
  }
@@ -69383,7 +69792,7 @@ function defaultFlowDefinition() {
69383
69792
  // src/commands/flow/flow.ts
69384
69793
  import { sep as SEP19 } from "node:path";
69385
69794
  import { readFile as readFile14 } from "node:fs/promises";
69386
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "node:fs";
69795
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
69387
69796
  async function pushFlow(workspace, remotePath, localPath, message) {
69388
69797
  if (alreadySynced3.includes(localPath)) {
69389
69798
  return;
@@ -69401,7 +69810,7 @@ async function pushFlow(workspace, remotePath, localPath, message) {
69401
69810
  localPath += SEP19;
69402
69811
  }
69403
69812
  const localFlow = await yamlParseFile(localPath + "flow.yaml");
69404
- const fileReader = async (path17) => await readFile14(localPath + path17, "utf-8");
69813
+ const fileReader = async (path19) => await readFile14(localPath + path19, "utf-8");
69405
69814
  await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath, SEP19);
69406
69815
  if (localFlow.value.failure_module) {
69407
69816
  await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath, SEP19);
@@ -69475,12 +69884,12 @@ async function list11(opts) {
69475
69884
  new Table2().header(["path", "summary", "edited by"]).padding(2).border(true).body(total.map((x) => [x.path, x.summary, x.edited_by])).render();
69476
69885
  }
69477
69886
  }
69478
- async function get9(opts, path17) {
69887
+ async function get9(opts, path19) {
69479
69888
  const workspace = await resolveWorkspace(opts);
69480
69889
  await requireLogin(opts);
69481
69890
  const f = await getFlowByPath({
69482
69891
  workspace: workspace.workspaceId,
69483
- path: path17
69892
+ path: path19
69484
69893
  });
69485
69894
  if (opts.json) {
69486
69895
  console.log(JSON.stringify(f));
@@ -69492,13 +69901,13 @@ async function get9(opts, path17) {
69492
69901
  console.log(colors.bold("Edited at:") + " " + (f.edited_at ?? ""));
69493
69902
  }
69494
69903
  }
69495
- async function run3(opts, path17) {
69904
+ async function run3(opts, path19) {
69496
69905
  const workspace = await resolveWorkspace(opts);
69497
69906
  await requireLogin(opts);
69498
69907
  const input = opts.data ? await resolve6(opts.data) : {};
69499
69908
  const id = await runFlowByPath({
69500
69909
  workspace: workspace.workspaceId,
69501
- path: path17,
69910
+ path: path19,
69502
69911
  requestBody: input
69503
69912
  });
69504
69913
  let i = 0;
@@ -69550,7 +69959,7 @@ async function preview2(opts, flowPath) {
69550
69959
  flowPath += SEP19;
69551
69960
  }
69552
69961
  const localFlow = await yamlParseFile(flowPath + "flow.yaml");
69553
- const fileReader = async (path17) => await readFile14(flowPath + path17, "utf-8");
69962
+ const fileReader = async (path19) => await readFile14(flowPath + path19, "utf-8");
69554
69963
  await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath, SEP19);
69555
69964
  if (localFlow.value.failure_module) {
69556
69965
  await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath, SEP19);
@@ -69627,7 +70036,7 @@ function bootstrap2(opts, flowPath) {
69627
70036
  return;
69628
70037
  }
69629
70038
  const flowDirFullPath = `${flowPath}.flow`;
69630
- mkdirSync3(flowDirFullPath, { recursive: false });
70039
+ mkdirSync4(flowDirFullPath, { recursive: false });
69631
70040
  const newFlowDefinition = defaultFlowDefinition();
69632
70041
  if (opts.summary !== undefined) {
69633
70042
  newFlowDefinition.summary = opts.summary;
@@ -69637,7 +70046,7 @@ function bootstrap2(opts, flowPath) {
69637
70046
  }
69638
70047
  const newFlowDefinitionYaml = import_yaml36.stringify(newFlowDefinition);
69639
70048
  const flowYamlPath = `${flowDirFullPath}/flow.yaml`;
69640
- writeFileSync4(flowYamlPath, newFlowDefinitionYaml, { flag: "wx", encoding: "utf-8" });
70049
+ writeFileSync5(flowYamlPath, newFlowDefinitionYaml, { flag: "wx", encoding: "utf-8" });
69641
70050
  }
69642
70051
  var import_yaml36, alreadySynced3, command21, flow_default;
69643
70052
  var init_flow = __esm(async () => {
@@ -69958,8 +70367,8 @@ function outputResult(opts, result) {
69958
70367
  error(colors.red(result.error));
69959
70368
  }
69960
70369
  }
69961
- function normalizeRepoPath(path17) {
69962
- return path17.replace(/^\$res:/, "");
70370
+ function normalizeRepoPath(path19) {
70371
+ return path19.replace(/^\$res:/, "");
69963
70372
  }
69964
70373
  function getOrCreateBranchConfig(config, branchName) {
69965
70374
  if (!config.gitBranches) {
@@ -71956,7 +72365,7 @@ async function dev2(opts) {
71956
72365
  const flowFolderSuffix = getFolderSuffixWithSep("flow");
71957
72366
  const flowMetadataFile = getMetadataFileName("flow", "yaml");
71958
72367
  async function loadPaths(pathsToLoad) {
71959
- const paths = pathsToLoad.filter((path17) => exts.some((ext2) => path17.endsWith(ext2) || path17.endsWith(flowFolderSuffix + flowMetadataFile)));
72368
+ const paths = pathsToLoad.filter((path19) => exts.some((ext2) => path19.endsWith(ext2) || path19.endsWith(flowFolderSuffix + flowMetadataFile)));
71960
72369
  if (paths.length == 0) {
71961
72370
  return;
71962
72371
  }
@@ -71968,7 +72377,7 @@ async function dev2(opts) {
71968
72377
  if (typ == "flow") {
71969
72378
  const localPath = extractFolderPath(cpath, "flow");
71970
72379
  const localFlow = await yamlParseFile(localPath + "flow.yaml");
71971
- await replaceInlineScripts(localFlow.value.modules, async (path17) => await readFile15(localPath + path17, "utf-8"), exports_log, localPath, SEP20, undefined);
72380
+ await replaceInlineScripts(localFlow.value.modules, async (path19) => await readFile15(localPath + path19, "utf-8"), exports_log, localPath, SEP20, undefined);
71972
72381
  currentLastEdit = {
71973
72382
  type: "flow",
71974
72383
  flow: localFlow,
@@ -77615,7 +78024,7 @@ sync local with a remote workspaces or the opposite (push or pull)
77615
78024
  - \`--extra-includes <patterns:file[]>\` - Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy
77616
78025
  - \`--repository <repo:string>\` - Specify repository path (e.g., u/user/repo) when multiple repositories exist
77617
78026
  - \`--promotion <branch:string>\` - Use promotionOverrides from the specified branch instead of regular overrides
77618
- - \`--branch <branch:string>\` - Override the current git branch (works even outside a git repository)
78027
+ - \`--branch, --env <branch:string>\` - Override the current git branch/environment (works even outside a git repository)
77619
78028
  - \`sync push\` - Push any local changes and apply them remotely.
77620
78029
  - \`--yes\` - Push without needing confirmation
77621
78030
  - \`--dry-run\` - Show changes that would be pushed without actually pushing
@@ -77645,7 +78054,7 @@ sync local with a remote workspaces or the opposite (push or pull)
77645
78054
  - \`--message <message:string>\` - Include a message that will be added to all scripts/flows/apps updated during this push
77646
78055
  - \`--parallel <number>\` - Number of changes to process in parallel
77647
78056
  - \`--repository <repo:string>\` - Specify repository path (e.g., u/user/repo) when multiple repositories exist
77648
- - \`--branch <branch:string>\` - Override the current git branch (works even outside a git repository)
78057
+ - \`--branch, --env <branch:string>\` - Override the current git branch/environment (works even outside a git repository)
77649
78058
  - \`--lint\` - Run lint validation before pushing
77650
78059
  - \`--locks-required\` - Fail if scripts or flow inline scripts that need locks have no locks
77651
78060
 
@@ -77747,9 +78156,9 @@ workspace related commands
77747
78156
  - \`workspace list\` - List local workspace profiles
77748
78157
  - \`workspace list-remote\` - List workspaces on the remote server that you have access to
77749
78158
  - \`workspace bind\` - Bind the current Git branch to the active workspace
77750
- - \`--branch <branch:string>\` - Specify branch (defaults to current)
78159
+ - \`--branch, --env <branch:string>\` - Specify branch/environment (defaults to current)
77751
78160
  - \`workspace unbind\` - Remove workspace binding from the current Git branch
77752
- - \`--branch <branch:string>\` - Specify branch (defaults to current)
78161
+ - \`--branch, --env <branch:string>\` - Specify branch/environment (defaults to current)
77753
78162
  - \`workspace fork [workspace_name:string] [workspace_id:string]\` - Create a forked workspace
77754
78163
  - \`--create-workspace-name <workspace_name:string>\` - Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.
77755
78164
  - \`workspace delete-fork <fork_name:string>\` - Delete a forked workspace and git branch
@@ -79061,7 +79470,7 @@ async function generateMetadata2(opts, folder) {
79061
79470
  info(colors.gray(`Checking ${checking.join(", ")}...`));
79062
79471
  if (!skipScripts) {
79063
79472
  const scriptElems = await elementsToMap(await FSFSElement(process.cwd(), codebases, false), (p, isD) => {
79064
- return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFlowPath(p) || isAppPath(p) || isRawAppPath(p);
79473
+ return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFlowPath(p) || isAppPath(p) || isRawAppPath(p) || isScriptModulePath(p) && !isModuleEntryPoint(p);
79065
79474
  }, false, {});
79066
79475
  for (const e of Object.keys(scriptElems)) {
79067
79476
  const candidate = await generateScriptMetadataInternal(e, workspace, opts, true, true, rawWorkspaceDependencies, codebases, false);
@@ -79254,7 +79663,7 @@ var docs_default = command30;
79254
79663
 
79255
79664
  // src/main.ts
79256
79665
  await init_context();
79257
- var VERSION = "1.657.2";
79666
+ var VERSION = "1.659.0";
79258
79667
  var command31 = new Command().name("wmill").action(() => info(`Welcome to Windmill CLI ${VERSION}. Use -h for help.`)).description("Windmill CLI").globalOption("--workspace <workspace:string>", "Specify the target workspace. This overrides the default workspace.").globalOption("--debug --verbose", "Show debug/verbose logs").globalOption("--show-diffs", "Show diff informations when syncing (may show sensitive informations)").globalOption("--token <token:string>", "Specify an API token. This will override any stored token.").globalOption("--base-url <baseUrl:string>", "Specify the base URL of the API. If used, --token and --workspace are required and no local remote/workspace already set will be used.").globalOption("--config-dir <configDir:string>", "Specify a custom config directory. Overrides WMILL_CONFIG_DIR environment variable and default ~/.config location.").env("HEADERS <headers:string>", `Specify headers to use for all requests. e.g: "HEADERS='h1: v1, h2: v2'"`).version(VERSION).versionOption(false).command("init", init_default).command("app", app_default).command("flow", flow_default).command("script", script_default).command("workspace", workspace_default).command("resource", resource_default).command("resource-type", resource_type_default).command("user", user_default).command("variable", variable_default).command("hub", hub_default).command("folder", folder_default).command("schedule", schedule_default).command("trigger", trigger_default).command("dev", dev_default2).command("sync", sync_default).command("lint", lint_default).command("gitsync-settings", gitsync_settings_default).command("instance", instance_default).command("worker-groups", worker_groups_default).command("workers", workers_default).command("queues", queues_default).command("dependencies", dependencies_default).command("jobs", jobs_default).command("generate-metadata", generate_metadata_default).command("docs", docs_default).command("version --version", "Show version information").action(async (opts) => {
79259
79668
  console.log("CLI version: " + VERSION);
79260
79669
  try {