windmill-cli 1.654.0 → 1.655.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.
- package/esm/main.js +1650 -1306
- 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.
|
|
11788
|
+
VERSION: "1.655.0",
|
|
11789
11789
|
WITH_CREDENTIALS: true,
|
|
11790
11790
|
interceptors: {
|
|
11791
11791
|
request: new Interceptors,
|
|
@@ -12347,6 +12347,7 @@ __export(exports_services_gen, {
|
|
|
12347
12347
|
globalUserRename: () => globalUserRename,
|
|
12348
12348
|
globalUserDelete: () => globalUserDelete,
|
|
12349
12349
|
gitRepoViewerFileUpload: () => gitRepoViewerFileUpload,
|
|
12350
|
+
ghesInstallationCallback: () => ghesInstallationCallback,
|
|
12350
12351
|
getWorkspaceUsage: () => getWorkspaceUsage,
|
|
12351
12352
|
getWorkspaceSlackOauthConfig: () => getWorkspaceSlackOauthConfig,
|
|
12352
12353
|
getWorkspaceName: () => getWorkspaceName,
|
|
@@ -12451,6 +12452,7 @@ __export(exports_services_gen, {
|
|
|
12451
12452
|
getGlobal: () => getGlobal,
|
|
12452
12453
|
getGithubAppToken: () => getGithubAppToken,
|
|
12453
12454
|
getGitCommitHash: () => getGitCommitHash,
|
|
12455
|
+
getGhesConfig: () => getGhesConfig,
|
|
12454
12456
|
getGcpTrigger: () => getGcpTrigger,
|
|
12455
12457
|
getFolderUsage: () => getFolderUsage,
|
|
12456
12458
|
getFolderPermissionHistory: () => getFolderPermissionHistory,
|
|
@@ -12660,6 +12662,7 @@ __export(exports_services_gen, {
|
|
|
12660
12662
|
connectClientCredentials: () => connectClientCredentials,
|
|
12661
12663
|
connectCallback: () => connectCallback,
|
|
12662
12664
|
compareWorkspaces: () => compareWorkspaces,
|
|
12665
|
+
commitKafkaOffsets: () => commitKafkaOffsets,
|
|
12663
12666
|
clearIndex: () => clearIndex,
|
|
12664
12667
|
checkS3FolderExists: () => checkS3FolderExists,
|
|
12665
12668
|
checkInstanceSharingAvailable: () => checkInstanceSharingAvailable,
|
|
@@ -13310,6 +13313,21 @@ var backendVersion = () => {
|
|
|
13310
13313
|
body: data2.requestBody,
|
|
13311
13314
|
mediaType: "application/json"
|
|
13312
13315
|
});
|
|
13316
|
+
}, ghesInstallationCallback = (data2) => {
|
|
13317
|
+
return request(OpenAPI, {
|
|
13318
|
+
method: "POST",
|
|
13319
|
+
url: "/w/{workspace}/github_app/ghes_installation_callback",
|
|
13320
|
+
path: {
|
|
13321
|
+
workspace: data2.workspace
|
|
13322
|
+
},
|
|
13323
|
+
body: data2.requestBody,
|
|
13324
|
+
mediaType: "application/json"
|
|
13325
|
+
});
|
|
13326
|
+
}, getGhesConfig = () => {
|
|
13327
|
+
return request(OpenAPI, {
|
|
13328
|
+
method: "GET",
|
|
13329
|
+
url: "/github_app/ghes_config"
|
|
13330
|
+
});
|
|
13313
13331
|
}, acceptInvite = (data2) => {
|
|
13314
13332
|
return request(OpenAPI, {
|
|
13315
13333
|
method: "POST",
|
|
@@ -17229,6 +17247,17 @@ var backendVersion = () => {
|
|
|
17229
17247
|
path: data2.path
|
|
17230
17248
|
}
|
|
17231
17249
|
});
|
|
17250
|
+
}, commitKafkaOffsets = (data2) => {
|
|
17251
|
+
return request(OpenAPI, {
|
|
17252
|
+
method: "POST",
|
|
17253
|
+
url: "/w/{workspace}/kafka_triggers/commit_offsets/{path}",
|
|
17254
|
+
path: {
|
|
17255
|
+
workspace: data2.workspace,
|
|
17256
|
+
path: data2.path
|
|
17257
|
+
},
|
|
17258
|
+
body: data2.requestBody,
|
|
17259
|
+
mediaType: "application/json"
|
|
17260
|
+
});
|
|
17232
17261
|
}, createNatsTrigger = (data2) => {
|
|
17233
17262
|
return request(OpenAPI, {
|
|
17234
17263
|
method: "POST",
|
|
@@ -59333,6 +59362,7 @@ async function bootstrap(opts, scriptPath, language) {
|
|
|
59333
59362
|
});
|
|
59334
59363
|
}
|
|
59335
59364
|
async function generateMetadata(opts, scriptPath) {
|
|
59365
|
+
warn(colors.yellow('This command is deprecated. Use "wmill generate-metadata" instead.'));
|
|
59336
59366
|
info("This command only works for workspace scripts, for flows inline scripts use `wmill flow generate-locks`");
|
|
59337
59367
|
if (scriptPath == "") {
|
|
59338
59368
|
scriptPath = undefined;
|
|
@@ -60551,7 +60581,7 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
60551
60581
|
} else if (dryRun) {
|
|
60552
60582
|
return remote_path;
|
|
60553
60583
|
}
|
|
60554
|
-
if (Object.keys(filteredDeps).length > 0) {
|
|
60584
|
+
if (Object.keys(filteredDeps).length > 0 && !noStaleMessage) {
|
|
60555
60585
|
info((await blueColor())(`Found workspace dependencies (${workspaceDependenciesLanguages.map((l) => l.filename).join("/")}) for ${folder}, using them`));
|
|
60556
60586
|
}
|
|
60557
60587
|
if (!justUpdateMetadataLock) {
|
|
@@ -60564,10 +60594,26 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
60564
60594
|
changedScripts.push(path7);
|
|
60565
60595
|
}
|
|
60566
60596
|
}
|
|
60567
|
-
|
|
60568
|
-
|
|
60597
|
+
if (!noStaleMessage) {
|
|
60598
|
+
info(`Recomputing locks of ${changedScripts.join(", ")} in ${folder}`);
|
|
60599
|
+
}
|
|
60600
|
+
const fileReader = async (path7) => await readFile7(folder + SEP7 + path7, "utf-8");
|
|
60601
|
+
await replaceInlineScripts(flowValue.value.modules, fileReader, exports_log, folder + SEP7, SEP7, changedScripts);
|
|
60602
|
+
if (flowValue.value.failure_module) {
|
|
60603
|
+
await replaceInlineScripts([flowValue.value.failure_module], fileReader, exports_log, folder + SEP7, SEP7, changedScripts);
|
|
60604
|
+
}
|
|
60605
|
+
if (flowValue.value.preprocessor_module) {
|
|
60606
|
+
await replaceInlineScripts([flowValue.value.preprocessor_module], fileReader, exports_log, folder + SEP7, SEP7, changedScripts);
|
|
60607
|
+
}
|
|
60569
60608
|
flowValue.value = await updateFlow2(workspace, flowValue.value, remote_path, filteredDeps);
|
|
60570
|
-
const
|
|
60609
|
+
const lockAssigner = newPathAssigner(opts.defaultTs ?? "bun");
|
|
60610
|
+
const inlineScripts = extractInlineScripts(flowValue.value.modules, {}, SEP7, opts.defaultTs, lockAssigner);
|
|
60611
|
+
if (flowValue.value.failure_module) {
|
|
60612
|
+
inlineScripts.push(...extractInlineScripts([flowValue.value.failure_module], {}, SEP7, opts.defaultTs, lockAssigner));
|
|
60613
|
+
}
|
|
60614
|
+
if (flowValue.value.preprocessor_module) {
|
|
60615
|
+
inlineScripts.push(...extractInlineScripts([flowValue.value.preprocessor_module], {}, SEP7, opts.defaultTs, lockAssigner));
|
|
60616
|
+
}
|
|
60571
60617
|
inlineScripts.forEach((s) => {
|
|
60572
60618
|
writeIfChanged(process.cwd() + SEP7 + folder + SEP7 + s.path, s.content);
|
|
60573
60619
|
});
|
|
@@ -60578,10 +60624,20 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
60578
60624
|
for (const [path7, hash2] of Object.entries(hashes)) {
|
|
60579
60625
|
await updateMetadataGlobalLock(folder, hash2, path7);
|
|
60580
60626
|
}
|
|
60581
|
-
|
|
60627
|
+
if (!noStaleMessage) {
|
|
60628
|
+
info(colors.green(`Flow ${remote_path} lockfiles updated`));
|
|
60629
|
+
}
|
|
60582
60630
|
}
|
|
60583
60631
|
async function filterWorkspaceDependenciesForFlow(flowValue, rawWorkspaceDependencies, folder) {
|
|
60584
|
-
const
|
|
60632
|
+
const clonedValue = structuredClone(flowValue);
|
|
60633
|
+
const depAssigner = newPathAssigner("bun");
|
|
60634
|
+
const inlineScripts = extractInlineScripts(clonedValue.modules, {}, SEP7, undefined, depAssigner);
|
|
60635
|
+
if (clonedValue.failure_module) {
|
|
60636
|
+
inlineScripts.push(...extractInlineScripts([clonedValue.failure_module], {}, SEP7, undefined, depAssigner));
|
|
60637
|
+
}
|
|
60638
|
+
if (clonedValue.preprocessor_module) {
|
|
60639
|
+
inlineScripts.push(...extractInlineScripts([clonedValue.preprocessor_module], {}, SEP7, undefined, depAssigner));
|
|
60640
|
+
}
|
|
60585
60641
|
const scripts = inlineScripts.filter((s) => !s.is_lock).map((s) => ({ content: s.content, language: s.language }));
|
|
60586
60642
|
return await filterWorkspaceDependenciesForScripts(scripts, rawWorkspaceDependencies, folder, SEP7);
|
|
60587
60643
|
}
|
|
@@ -60645,6 +60701,7 @@ var init_flow_metadata = __esm(async () => {
|
|
|
60645
60701
|
init_log();
|
|
60646
60702
|
init_yaml();
|
|
60647
60703
|
init_extractor();
|
|
60704
|
+
init_path_assigner();
|
|
60648
60705
|
init_script_common();
|
|
60649
60706
|
init_resource_folders();
|
|
60650
60707
|
await __promiseAll([
|
|
@@ -61038,7 +61095,14 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
61038
61095
|
}
|
|
61039
61096
|
let inlineScripts;
|
|
61040
61097
|
try {
|
|
61041
|
-
|
|
61098
|
+
const assigner = newPathAssigner(defaultTs, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
61099
|
+
inlineScripts = extractInlineScripts(flow.value.modules, {}, SEP8, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
61100
|
+
if (flow.value.failure_module) {
|
|
61101
|
+
inlineScripts.push(...extractInlineScripts([flow.value.failure_module], {}, SEP8, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
61102
|
+
}
|
|
61103
|
+
if (flow.value.preprocessor_module) {
|
|
61104
|
+
inlineScripts.push(...extractInlineScripts([flow.value.preprocessor_module], {}, SEP8, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
61105
|
+
}
|
|
61042
61106
|
} catch (error2) {
|
|
61043
61107
|
error(`Failed to extract inline scripts for flow at path: ${p}`);
|
|
61044
61108
|
throw error2;
|
|
@@ -62941,7 +63005,7 @@ function loadParser(pkgName) {
|
|
|
62941
63005
|
p = (async () => {
|
|
62942
63006
|
const mod = await import(pkgName);
|
|
62943
63007
|
const wasmPath = _require.resolve(`${pkgName}/windmill_parser_wasm_bg.wasm`);
|
|
62944
|
-
await mod.default(readFileSync3(wasmPath));
|
|
63008
|
+
await mod.default({ module_or_path: readFileSync3(wasmPath) });
|
|
62945
63009
|
return mod;
|
|
62946
63010
|
})();
|
|
62947
63011
|
_parserCache.set(pkgName, p);
|
|
@@ -63035,7 +63099,7 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
63035
63099
|
} else if (dryRun) {
|
|
63036
63100
|
return `${remotePath} (${language})`;
|
|
63037
63101
|
}
|
|
63038
|
-
if (!justUpdateMetadataLock) {
|
|
63102
|
+
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
63039
63103
|
info(colors.gray(`Generating metadata for ${scriptPath}`));
|
|
63040
63104
|
}
|
|
63041
63105
|
const metadataParsedContent = metadataWithType?.payload;
|
|
@@ -63828,6 +63892,7 @@ var init_raw_apps = __esm(async () => {
|
|
|
63828
63892
|
var exports_app_metadata = {};
|
|
63829
63893
|
__export(exports_app_metadata, {
|
|
63830
63894
|
inferRunnableSchemaFromFile: () => inferRunnableSchemaFromFile,
|
|
63895
|
+
getAppFolders: () => getAppFolders,
|
|
63831
63896
|
generateLocksCommand: () => generateLocksCommand,
|
|
63832
63897
|
generateAppLocksInternal: () => generateAppLocksInternal,
|
|
63833
63898
|
filterWorkspaceDependenciesForApp: () => filterWorkspaceDependenciesForApp,
|
|
@@ -63883,7 +63948,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
63883
63948
|
} else if (dryRun) {
|
|
63884
63949
|
return remote_path;
|
|
63885
63950
|
}
|
|
63886
|
-
if (Object.keys(filteredDeps).length > 0) {
|
|
63951
|
+
if (Object.keys(filteredDeps).length > 0 && !noStaleMessage) {
|
|
63887
63952
|
info((await blueColor())(`Found workspace dependencies (${workspaceDependenciesLanguages.map((l) => l.filename).join("/")}) for ${appFolder}, using them`));
|
|
63888
63953
|
}
|
|
63889
63954
|
if (!justUpdateMetadataLock) {
|
|
@@ -63897,7 +63962,9 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
63897
63962
|
}
|
|
63898
63963
|
}
|
|
63899
63964
|
if (changedScripts.length > 0) {
|
|
63900
|
-
|
|
63965
|
+
if (!noStaleMessage) {
|
|
63966
|
+
info(`Recomputing locks of ${changedScripts.join(", ")} in ${appFolder}`);
|
|
63967
|
+
}
|
|
63901
63968
|
if (rawApp) {
|
|
63902
63969
|
const runnablesPath = path9.join(appFolder, APP_BACKEND_FOLDER);
|
|
63903
63970
|
const rawAppFile = appFile;
|
|
@@ -63913,7 +63980,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
63913
63980
|
normalAppFile.value = await updateAppInlineScripts(workspace, normalAppFile.value, remote_path, appFolder, filteredDeps, opts.defaultTs);
|
|
63914
63981
|
writeIfChanged(appFilePath, import_yaml17.stringify(appFile, yamlOptions));
|
|
63915
63982
|
}
|
|
63916
|
-
} else {
|
|
63983
|
+
} else if (!noStaleMessage) {
|
|
63917
63984
|
info(colors.gray(`No scripts changed in ${appFolder}`));
|
|
63918
63985
|
}
|
|
63919
63986
|
}
|
|
@@ -63922,7 +63989,9 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
63922
63989
|
for (const [scriptPath, hash2] of Object.entries(hashes)) {
|
|
63923
63990
|
await updateMetadataGlobalLock(appFolder, hash2, scriptPath);
|
|
63924
63991
|
}
|
|
63925
|
-
|
|
63992
|
+
if (!noStaleMessage) {
|
|
63993
|
+
info(colors.green(`App ${remote_path} lockfiles updated`));
|
|
63994
|
+
}
|
|
63926
63995
|
}
|
|
63927
63996
|
async function filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependencies, folder) {
|
|
63928
63997
|
const scripts = [];
|
|
@@ -66377,6 +66446,7 @@ var init_app = __esm(async () => {
|
|
|
66377
66446
|
]);
|
|
66378
66447
|
alreadySynced2 = [];
|
|
66379
66448
|
command11 = new Command().description("app related commands").option("--json", "Output as JSON (for piping to jq)").action(list4).command("list", "list all apps").option("--json", "Output as JSON (for piping to jq)").action(list4).command("get", "get an app's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get3).command("push", "push a local app ").arguments("<file_path:string> <remote_path:string>").action(push4).command("dev", dev_default).command("lint", lint_default2).command("new", new_default).command("generate-agents", generate_agents_default).command("generate-locks", "re-generate the lockfiles for app runnables inline scripts that have changed").arguments("[app_folder:string]").option("--yes", "Skip confirmation prompt").option("--dry-run", "Perform a dry run without making changes").option("--default-ts <runtime:string>", "Default TypeScript runtime (bun or deno)").action(async (opts, appFolder) => {
|
|
66449
|
+
warn(colors.yellow('This command is deprecated. Use "wmill generate-metadata" instead.'));
|
|
66380
66450
|
const { generateLocksCommand: generateLocksCommand2 } = await init_app_metadata().then(() => exports_app_metadata);
|
|
66381
66451
|
await generateLocksCommand2(opts, appFolder);
|
|
66382
66452
|
});
|
|
@@ -69294,7 +69364,14 @@ async function pushFlow(workspace, remotePath, localPath, message) {
|
|
|
69294
69364
|
localPath += SEP19;
|
|
69295
69365
|
}
|
|
69296
69366
|
const localFlow = await yamlParseFile(localPath + "flow.yaml");
|
|
69297
|
-
|
|
69367
|
+
const fileReader = async (path17) => await readFile14(localPath + path17, "utf-8");
|
|
69368
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath, SEP19);
|
|
69369
|
+
if (localFlow.value.failure_module) {
|
|
69370
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath, SEP19);
|
|
69371
|
+
}
|
|
69372
|
+
if (localFlow.value.preprocessor_module) {
|
|
69373
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, localPath, SEP19);
|
|
69374
|
+
}
|
|
69298
69375
|
if (flow) {
|
|
69299
69376
|
if (isSuperset(localFlow, flow)) {
|
|
69300
69377
|
info(colors.green(`Flow ${remotePath} is up to date`));
|
|
@@ -69436,7 +69513,14 @@ async function preview2(opts, flowPath) {
|
|
|
69436
69513
|
flowPath += SEP19;
|
|
69437
69514
|
}
|
|
69438
69515
|
const localFlow = await yamlParseFile(flowPath + "flow.yaml");
|
|
69439
|
-
|
|
69516
|
+
const fileReader = async (path17) => await readFile14(flowPath + path17, "utf-8");
|
|
69517
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath, SEP19);
|
|
69518
|
+
if (localFlow.value.failure_module) {
|
|
69519
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath, SEP19);
|
|
69520
|
+
}
|
|
69521
|
+
if (localFlow.value.preprocessor_module) {
|
|
69522
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath, SEP19);
|
|
69523
|
+
}
|
|
69440
69524
|
const input = opts.data ? await resolve6(opts.data) : {};
|
|
69441
69525
|
if (!opts.silent) {
|
|
69442
69526
|
info(colors.yellow(`Running flow preview for ${flowPath}...`));
|
|
@@ -69466,6 +69550,7 @@ async function preview2(opts, flowPath) {
|
|
|
69466
69550
|
}
|
|
69467
69551
|
}
|
|
69468
69552
|
async function generateLocks(opts, folder) {
|
|
69553
|
+
warn(colors.yellow('This command is deprecated. Use "wmill generate-metadata" instead.'));
|
|
69469
69554
|
const workspace = await resolveWorkspace(opts);
|
|
69470
69555
|
await requireLogin(opts);
|
|
69471
69556
|
opts = await mergeConfigWithConfigFile(opts);
|
|
@@ -72174,25 +72259,25 @@ import { stat as stat15, writeFile as writeFile19, rm as rm4, mkdir as mkdir8 }
|
|
|
72174
72259
|
|
|
72175
72260
|
// src/guidance/skills.ts
|
|
72176
72261
|
var SKILLS = [
|
|
72177
|
-
{ name: "write-script-
|
|
72178
|
-
{ name: "write-script-java", description: "MUST use when writing Java scripts.", languageKey: "java" },
|
|
72179
|
-
{ name: "write-script-graphql", description: "MUST use when writing GraphQL queries.", languageKey: "graphql" },
|
|
72180
|
-
{ name: "write-script-rust", description: "MUST use when writing Rust scripts.", languageKey: "rust" },
|
|
72181
|
-
{ name: "write-script-bunnative", description: "MUST use when writing Bun Native scripts.", languageKey: "bunnative" },
|
|
72182
|
-
{ name: "write-script-postgresql", description: "MUST use when writing PostgreSQL queries.", languageKey: "postgresql" },
|
|
72183
|
-
{ name: "write-script-php", description: "MUST use when writing PHP scripts.", languageKey: "php" },
|
|
72262
|
+
{ name: "write-script-bash", description: "MUST use when writing Bash scripts.", languageKey: "bash" },
|
|
72184
72263
|
{ name: "write-script-bigquery", description: "MUST use when writing BigQuery queries.", languageKey: "bigquery" },
|
|
72185
72264
|
{ name: "write-script-bun", description: "MUST use when writing Bun/TypeScript scripts.", languageKey: "bun" },
|
|
72265
|
+
{ name: "write-script-bunnative", description: "MUST use when writing Bun Native scripts.", languageKey: "bunnative" },
|
|
72186
72266
|
{ name: "write-script-csharp", description: "MUST use when writing C# scripts.", languageKey: "csharp" },
|
|
72187
|
-
{ name: "write-script-mssql", description: "MUST use when writing MS SQL Server queries.", languageKey: "mssql" },
|
|
72188
72267
|
{ name: "write-script-deno", description: "MUST use when writing Deno/TypeScript scripts.", languageKey: "deno" },
|
|
72268
|
+
{ name: "write-script-duckdb", description: "MUST use when writing DuckDB queries.", languageKey: "duckdb" },
|
|
72269
|
+
{ name: "write-script-go", description: "MUST use when writing Go scripts.", languageKey: "go" },
|
|
72270
|
+
{ name: "write-script-graphql", description: "MUST use when writing GraphQL queries.", languageKey: "graphql" },
|
|
72271
|
+
{ name: "write-script-java", description: "MUST use when writing Java scripts.", languageKey: "java" },
|
|
72272
|
+
{ name: "write-script-mssql", description: "MUST use when writing MS SQL Server queries.", languageKey: "mssql" },
|
|
72189
72273
|
{ name: "write-script-mysql", description: "MUST use when writing MySQL queries.", languageKey: "mysql" },
|
|
72274
|
+
{ name: "write-script-nativets", description: "MUST use when writing Native TypeScript scripts.", languageKey: "nativets" },
|
|
72275
|
+
{ name: "write-script-php", description: "MUST use when writing PHP scripts.", languageKey: "php" },
|
|
72276
|
+
{ name: "write-script-postgresql", description: "MUST use when writing PostgreSQL queries.", languageKey: "postgresql" },
|
|
72190
72277
|
{ name: "write-script-powershell", description: "MUST use when writing PowerShell scripts.", languageKey: "powershell" },
|
|
72191
|
-
{ name: "write-script-snowflake", description: "MUST use when writing Snowflake queries.", languageKey: "snowflake" },
|
|
72192
72278
|
{ name: "write-script-python3", description: "MUST use when writing Python scripts.", languageKey: "python3" },
|
|
72193
|
-
{ name: "write-script-
|
|
72194
|
-
{ name: "write-script-
|
|
72195
|
-
{ name: "write-script-nativets", description: "MUST use when writing Native TypeScript scripts.", languageKey: "nativets" },
|
|
72279
|
+
{ name: "write-script-rust", description: "MUST use when writing Rust scripts.", languageKey: "rust" },
|
|
72280
|
+
{ name: "write-script-snowflake", description: "MUST use when writing Snowflake queries.", languageKey: "snowflake" },
|
|
72196
72281
|
{ name: "write-flow", description: "MUST use when creating flows." },
|
|
72197
72282
|
{ name: "raw-app", description: "MUST use when creating raw apps." },
|
|
72198
72283
|
{ name: "triggers", description: "MUST use when configuring triggers." },
|
|
@@ -72201,294 +72286,116 @@ var SKILLS = [
|
|
|
72201
72286
|
{ name: "cli-commands", description: "MUST use when using the CLI." }
|
|
72202
72287
|
];
|
|
72203
72288
|
var SKILL_CONTENT = {
|
|
72204
|
-
"write-script-
|
|
72205
|
-
name: write-script-
|
|
72206
|
-
description: MUST use when writing
|
|
72289
|
+
"write-script-bash": `---
|
|
72290
|
+
name: write-script-bash
|
|
72291
|
+
description: MUST use when writing Bash scripts.
|
|
72207
72292
|
---
|
|
72208
72293
|
|
|
72209
72294
|
## CLI Commands
|
|
72210
72295
|
|
|
72211
|
-
Place scripts in a folder. After writing, run:
|
|
72296
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
72212
72297
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
72213
72298
|
- \`wmill sync push\` - Deploy to Windmill
|
|
72214
72299
|
|
|
72300
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
72301
|
+
|
|
72215
72302
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
72216
72303
|
|
|
72217
|
-
#
|
|
72304
|
+
# Bash
|
|
72218
72305
|
|
|
72219
72306
|
## Structure
|
|
72220
72307
|
|
|
72221
|
-
|
|
72308
|
+
Do not include \`#!/bin/bash\`. Arguments are obtained as positional parameters:
|
|
72222
72309
|
|
|
72223
|
-
\`\`\`
|
|
72224
|
-
|
|
72310
|
+
\`\`\`bash
|
|
72311
|
+
# Get arguments
|
|
72312
|
+
var1="$1"
|
|
72313
|
+
var2="$2"
|
|
72225
72314
|
|
|
72226
|
-
|
|
72227
|
-
|
|
72228
|
-
|
|
72229
|
-
|
|
72230
|
-
}, nil
|
|
72231
|
-
}
|
|
72315
|
+
echo "Processing $var1 and $var2"
|
|
72316
|
+
|
|
72317
|
+
# Return JSON by echoing to stdout
|
|
72318
|
+
echo "{\\"result\\": \\"$var1\\", \\"count\\": $var2}"
|
|
72232
72319
|
\`\`\`
|
|
72233
72320
|
|
|
72234
72321
|
**Important:**
|
|
72235
|
-
-
|
|
72236
|
-
-
|
|
72237
|
-
-
|
|
72238
|
-
|
|
72239
|
-
## Return Types
|
|
72322
|
+
- Do not include shebang (\`#!/bin/bash\`)
|
|
72323
|
+
- Arguments are always strings
|
|
72324
|
+
- Access with \`$1\`, \`$2\`, etc.
|
|
72240
72325
|
|
|
72241
|
-
|
|
72326
|
+
## Output
|
|
72242
72327
|
|
|
72243
|
-
|
|
72244
|
-
package inner
|
|
72328
|
+
The script output is captured as the result. For structured data, output valid JSON:
|
|
72245
72329
|
|
|
72246
|
-
|
|
72247
|
-
|
|
72248
|
-
|
|
72249
|
-
}
|
|
72330
|
+
\`\`\`bash
|
|
72331
|
+
name="$1"
|
|
72332
|
+
count="$2"
|
|
72250
72333
|
|
|
72251
|
-
|
|
72252
|
-
|
|
72253
|
-
|
|
72254
|
-
|
|
72255
|
-
|
|
72334
|
+
# Output JSON result
|
|
72335
|
+
cat << EOF
|
|
72336
|
+
{
|
|
72337
|
+
"name": "$name",
|
|
72338
|
+
"count": $count,
|
|
72339
|
+
"timestamp": "$(date -Iseconds)"
|
|
72256
72340
|
}
|
|
72341
|
+
EOF
|
|
72257
72342
|
\`\`\`
|
|
72258
72343
|
|
|
72259
|
-
##
|
|
72260
|
-
|
|
72261
|
-
Return errors as the second return value:
|
|
72262
|
-
|
|
72263
|
-
\`\`\`go
|
|
72264
|
-
package inner
|
|
72344
|
+
## Environment Variables
|
|
72265
72345
|
|
|
72266
|
-
|
|
72346
|
+
Environment variables set in Windmill are available:
|
|
72267
72347
|
|
|
72268
|
-
|
|
72269
|
-
|
|
72270
|
-
|
|
72271
|
-
|
|
72272
|
-
return "success", nil
|
|
72273
|
-
}
|
|
72348
|
+
\`\`\`bash
|
|
72349
|
+
# Access environment variable
|
|
72350
|
+
echo "Workspace: $WM_WORKSPACE"
|
|
72351
|
+
echo "Job ID: $WM_JOB_ID"
|
|
72274
72352
|
\`\`\`
|
|
72275
72353
|
`,
|
|
72276
|
-
"write-script-
|
|
72277
|
-
name: write-script-
|
|
72278
|
-
description: MUST use when writing
|
|
72354
|
+
"write-script-bigquery": `---
|
|
72355
|
+
name: write-script-bigquery
|
|
72356
|
+
description: MUST use when writing BigQuery queries.
|
|
72279
72357
|
---
|
|
72280
72358
|
|
|
72281
72359
|
## CLI Commands
|
|
72282
72360
|
|
|
72283
|
-
Place scripts in a folder. After writing, run:
|
|
72361
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
72284
72362
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
72285
72363
|
- \`wmill sync push\` - Deploy to Windmill
|
|
72286
72364
|
|
|
72287
|
-
|
|
72288
|
-
|
|
72289
|
-
# Java
|
|
72290
|
-
|
|
72291
|
-
The script must contain a Main public class with a \`public static main()\` method:
|
|
72292
|
-
|
|
72293
|
-
\`\`\`java
|
|
72294
|
-
public class Main {
|
|
72295
|
-
public static Object main(String name, int count) {
|
|
72296
|
-
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
|
72297
|
-
result.put("name", name);
|
|
72298
|
-
result.put("count", count);
|
|
72299
|
-
return result;
|
|
72300
|
-
}
|
|
72301
|
-
}
|
|
72302
|
-
\`\`\`
|
|
72303
|
-
|
|
72304
|
-
**Important:**
|
|
72305
|
-
- Class must be named \`Main\`
|
|
72306
|
-
- Method must be \`public static Object main(...)\`
|
|
72307
|
-
- Return type is \`Object\` or \`void\`
|
|
72308
|
-
|
|
72309
|
-
## Maven Dependencies
|
|
72310
|
-
|
|
72311
|
-
Add dependencies using comments at the top:
|
|
72312
|
-
|
|
72313
|
-
\`\`\`java
|
|
72314
|
-
//requirements:
|
|
72315
|
-
//com.google.code.gson:gson:2.10.1
|
|
72316
|
-
//org.apache.httpcomponents:httpclient:4.5.14
|
|
72317
|
-
|
|
72318
|
-
import com.google.gson.Gson;
|
|
72319
|
-
|
|
72320
|
-
public class Main {
|
|
72321
|
-
public static Object main(String input) {
|
|
72322
|
-
Gson gson = new Gson();
|
|
72323
|
-
return gson.fromJson(input, Object.class);
|
|
72324
|
-
}
|
|
72325
|
-
}
|
|
72326
|
-
\`\`\`
|
|
72327
|
-
`,
|
|
72328
|
-
"write-script-graphql": `---
|
|
72329
|
-
name: write-script-graphql
|
|
72330
|
-
description: MUST use when writing GraphQL queries.
|
|
72331
|
-
---
|
|
72332
|
-
|
|
72333
|
-
## CLI Commands
|
|
72334
|
-
|
|
72335
|
-
Place scripts in a folder. After writing, run:
|
|
72336
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
72337
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
72365
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
72338
72366
|
|
|
72339
72367
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
72340
72368
|
|
|
72341
|
-
#
|
|
72342
|
-
|
|
72343
|
-
## Structure
|
|
72344
|
-
|
|
72345
|
-
Write GraphQL queries or mutations. Arguments can be added as query parameters:
|
|
72346
|
-
|
|
72347
|
-
\`\`\`graphql
|
|
72348
|
-
query GetUser($id: ID!) {
|
|
72349
|
-
user(id: $id) {
|
|
72350
|
-
id
|
|
72351
|
-
name
|
|
72352
|
-
email
|
|
72353
|
-
}
|
|
72354
|
-
}
|
|
72355
|
-
\`\`\`
|
|
72356
|
-
|
|
72357
|
-
## Variables
|
|
72358
|
-
|
|
72359
|
-
Variables are passed as script arguments and automatically bound to the query:
|
|
72369
|
+
# BigQuery
|
|
72360
72370
|
|
|
72361
|
-
|
|
72362
|
-
query SearchProducts($query: String!, $limit: Int = 10) {
|
|
72363
|
-
products(search: $query, first: $limit) {
|
|
72364
|
-
edges {
|
|
72365
|
-
node {
|
|
72366
|
-
id
|
|
72367
|
-
name
|
|
72368
|
-
price
|
|
72369
|
-
}
|
|
72370
|
-
}
|
|
72371
|
-
}
|
|
72372
|
-
}
|
|
72373
|
-
\`\`\`
|
|
72371
|
+
Arguments use \`@name\` syntax.
|
|
72374
72372
|
|
|
72375
|
-
|
|
72373
|
+
Name the parameters by adding comments before the statement:
|
|
72376
72374
|
|
|
72377
|
-
\`\`\`
|
|
72378
|
-
|
|
72379
|
-
|
|
72380
|
-
|
|
72381
|
-
name
|
|
72382
|
-
createdAt
|
|
72383
|
-
}
|
|
72384
|
-
}
|
|
72375
|
+
\`\`\`sql
|
|
72376
|
+
-- @name1 (string)
|
|
72377
|
+
-- @name2 (int64) = 0
|
|
72378
|
+
SELECT * FROM users WHERE name = @name1 AND age > @name2;
|
|
72385
72379
|
\`\`\`
|
|
72386
72380
|
`,
|
|
72387
|
-
"write-script-
|
|
72388
|
-
name: write-script-
|
|
72389
|
-
description: MUST use when writing
|
|
72381
|
+
"write-script-bun": `---
|
|
72382
|
+
name: write-script-bun
|
|
72383
|
+
description: MUST use when writing Bun/TypeScript scripts.
|
|
72390
72384
|
---
|
|
72391
72385
|
|
|
72392
72386
|
## CLI Commands
|
|
72393
72387
|
|
|
72394
|
-
Place scripts in a folder. After writing, run:
|
|
72388
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
72395
72389
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
72396
72390
|
- \`wmill sync push\` - Deploy to Windmill
|
|
72397
72391
|
|
|
72398
|
-
|
|
72399
|
-
|
|
72400
|
-
# Rust
|
|
72401
|
-
|
|
72402
|
-
## Structure
|
|
72403
|
-
|
|
72404
|
-
The script must contain a function called \`main\` with proper return type:
|
|
72405
|
-
|
|
72406
|
-
\`\`\`rust
|
|
72407
|
-
use anyhow::anyhow;
|
|
72408
|
-
use serde::Serialize;
|
|
72409
|
-
|
|
72410
|
-
#[derive(Serialize, Debug)]
|
|
72411
|
-
struct ReturnType {
|
|
72412
|
-
result: String,
|
|
72413
|
-
count: i32,
|
|
72414
|
-
}
|
|
72415
|
-
|
|
72416
|
-
fn main(param1: String, param2: i32) -> anyhow::Result<ReturnType> {
|
|
72417
|
-
Ok(ReturnType {
|
|
72418
|
-
result: param1,
|
|
72419
|
-
count: param2,
|
|
72420
|
-
})
|
|
72421
|
-
}
|
|
72422
|
-
\`\`\`
|
|
72423
|
-
|
|
72424
|
-
**Important:**
|
|
72425
|
-
- Arguments should be owned types
|
|
72426
|
-
- Return type must be serializable (\`#[derive(Serialize)]\`)
|
|
72427
|
-
- Return type is \`anyhow::Result<T>\`
|
|
72428
|
-
|
|
72429
|
-
## Dependencies
|
|
72430
|
-
|
|
72431
|
-
Packages must be specified with a partial cargo.toml at the beginning of the script:
|
|
72432
|
-
|
|
72433
|
-
\`\`\`rust
|
|
72434
|
-
//! \`\`\`cargo
|
|
72435
|
-
//! [dependencies]
|
|
72436
|
-
//! anyhow = "1.0.86"
|
|
72437
|
-
//! reqwest = { version = "0.11", features = ["json"] }
|
|
72438
|
-
//! tokio = { version = "1", features = ["full"] }
|
|
72439
|
-
//! \`\`\`
|
|
72440
|
-
|
|
72441
|
-
use anyhow::anyhow;
|
|
72442
|
-
// ... rest of the code
|
|
72443
|
-
\`\`\`
|
|
72444
|
-
|
|
72445
|
-
**Note:** Serde is already included, no need to add it again.
|
|
72446
|
-
|
|
72447
|
-
## Async Functions
|
|
72448
|
-
|
|
72449
|
-
If you need to handle async functions (e.g., using tokio), keep the main function sync and create the runtime inside:
|
|
72450
|
-
|
|
72451
|
-
\`\`\`rust
|
|
72452
|
-
//! \`\`\`cargo
|
|
72453
|
-
//! [dependencies]
|
|
72454
|
-
//! anyhow = "1.0.86"
|
|
72455
|
-
//! tokio = { version = "1", features = ["full"] }
|
|
72456
|
-
//! reqwest = { version = "0.11", features = ["json"] }
|
|
72457
|
-
//! \`\`\`
|
|
72458
|
-
|
|
72459
|
-
use anyhow::anyhow;
|
|
72460
|
-
use serde::Serialize;
|
|
72461
|
-
|
|
72462
|
-
#[derive(Serialize, Debug)]
|
|
72463
|
-
struct Response {
|
|
72464
|
-
data: String,
|
|
72465
|
-
}
|
|
72466
|
-
|
|
72467
|
-
fn main(url: String) -> anyhow::Result<Response> {
|
|
72468
|
-
let rt = tokio::runtime::Runtime::new()?;
|
|
72469
|
-
rt.block_on(async {
|
|
72470
|
-
let resp = reqwest::get(&url).await?.text().await?;
|
|
72471
|
-
Ok(Response { data: resp })
|
|
72472
|
-
})
|
|
72473
|
-
}
|
|
72474
|
-
\`\`\`
|
|
72475
|
-
`,
|
|
72476
|
-
"write-script-bunnative": `---
|
|
72477
|
-
name: write-script-bunnative
|
|
72478
|
-
description: MUST use when writing Bun Native scripts.
|
|
72479
|
-
---
|
|
72480
|
-
|
|
72481
|
-
## CLI Commands
|
|
72482
|
-
|
|
72483
|
-
Place scripts in a folder. After writing, run:
|
|
72484
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
72485
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
72392
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
72486
72393
|
|
|
72487
72394
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
72488
72395
|
|
|
72489
|
-
# TypeScript (Bun
|
|
72396
|
+
# TypeScript (Bun)
|
|
72490
72397
|
|
|
72491
|
-
|
|
72398
|
+
Bun runtime with full npm ecosystem and fastest execution.
|
|
72492
72399
|
|
|
72493
72400
|
## Structure
|
|
72494
72401
|
|
|
@@ -72501,7 +72408,7 @@ export async function main(param1: string, param2: number) {
|
|
|
72501
72408
|
}
|
|
72502
72409
|
\`\`\`
|
|
72503
72410
|
|
|
72504
|
-
Do not call the main function.
|
|
72411
|
+
Do not call the main function. Libraries are installed automatically.
|
|
72505
72412
|
|
|
72506
72413
|
## Resource Types
|
|
72507
72414
|
|
|
@@ -72521,18 +72428,20 @@ Before using a resource type, check the \`rt.d.ts\` file in the project root to
|
|
|
72521
72428
|
|
|
72522
72429
|
## Imports
|
|
72523
72430
|
|
|
72524
|
-
**No imports allowed.** Use the globally available \`fetch\` function:
|
|
72525
|
-
|
|
72526
72431
|
\`\`\`typescript
|
|
72527
|
-
|
|
72528
|
-
|
|
72529
|
-
return await response.json();
|
|
72530
|
-
}
|
|
72432
|
+
import Stripe from "stripe";
|
|
72433
|
+
import { someFunction } from "some-package";
|
|
72531
72434
|
\`\`\`
|
|
72532
72435
|
|
|
72533
72436
|
## Windmill Client
|
|
72534
72437
|
|
|
72535
|
-
|
|
72438
|
+
Import the windmill client for platform interactions:
|
|
72439
|
+
|
|
72440
|
+
\`\`\`typescript
|
|
72441
|
+
import * as wmill from "windmill-client";
|
|
72442
|
+
\`\`\`
|
|
72443
|
+
|
|
72444
|
+
See the SDK documentation for available methods.
|
|
72536
72445
|
|
|
72537
72446
|
## Preprocessor Scripts
|
|
72538
72447
|
|
|
@@ -72602,36 +72511,6 @@ const result: S3Object = await wmill.writeS3File(
|
|
|
72602
72511
|
|
|
72603
72512
|
Import: import * as wmill from 'windmill-client'
|
|
72604
72513
|
|
|
72605
|
-
/**
|
|
72606
|
-
* Create a SQL template function for PostgreSQL/datatable queries
|
|
72607
|
-
* @param name - Database/datatable name (default: "main")
|
|
72608
|
-
* @returns SQL template function for building parameterized queries
|
|
72609
|
-
* @example
|
|
72610
|
-
* let sql = wmill.datatable()
|
|
72611
|
-
* let name = 'Robin'
|
|
72612
|
-
* let age = 21
|
|
72613
|
-
* await sql\`
|
|
72614
|
-
* SELECT * FROM friends
|
|
72615
|
-
* WHERE name = \${name} AND age = \${age}::int
|
|
72616
|
-
* \`.fetch()
|
|
72617
|
-
*/
|
|
72618
|
-
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
72619
|
-
|
|
72620
|
-
/**
|
|
72621
|
-
* Create a SQL template function for DuckDB/ducklake queries
|
|
72622
|
-
* @param name - DuckDB database name (default: "main")
|
|
72623
|
-
* @returns SQL template function for building parameterized queries
|
|
72624
|
-
* @example
|
|
72625
|
-
* let sql = wmill.ducklake()
|
|
72626
|
-
* let name = 'Robin'
|
|
72627
|
-
* let age = 21
|
|
72628
|
-
* await sql\`
|
|
72629
|
-
* SELECT * FROM friends
|
|
72630
|
-
* WHERE name = \${name} AND age = \${age}
|
|
72631
|
-
* \`.fetch()
|
|
72632
|
-
*/
|
|
72633
|
-
ducklake(name: string = "main"): SqlTemplateFunction
|
|
72634
|
-
|
|
72635
72514
|
/**
|
|
72636
72515
|
* Initialize the Windmill client with authentication token and base URL
|
|
72637
72516
|
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
|
@@ -73124,144 +73003,64 @@ waitForApproval(options?: { timeout?: number; form?: object; }): PromiseLike<{ v
|
|
|
73124
73003
|
* const results = await parallel(items, process, { concurrency: 5 });
|
|
73125
73004
|
*/
|
|
73126
73005
|
async parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
|
|
73127
|
-
`,
|
|
73128
|
-
"write-script-postgresql": `---
|
|
73129
|
-
name: write-script-postgresql
|
|
73130
|
-
description: MUST use when writing PostgreSQL queries.
|
|
73131
|
-
---
|
|
73132
|
-
|
|
73133
|
-
## CLI Commands
|
|
73134
73006
|
|
|
73135
|
-
|
|
73136
|
-
|
|
73137
|
-
|
|
73138
|
-
|
|
73139
|
-
|
|
73140
|
-
|
|
73141
|
-
|
|
73142
|
-
|
|
73143
|
-
Arguments are obtained directly in the statement with \`$1::{type}\`, \`$2::{type}\`, etc.
|
|
73144
|
-
|
|
73145
|
-
Name the parameters by adding comments at the beginning of the script (without specifying the type):
|
|
73146
|
-
|
|
73147
|
-
\`\`\`sql
|
|
73148
|
-
-- $1 name1
|
|
73149
|
-
-- $2 name2 = default_value
|
|
73150
|
-
SELECT * FROM users WHERE name = $1::TEXT AND age > $2::INT;
|
|
73151
|
-
\`\`\`
|
|
73152
|
-
`,
|
|
73153
|
-
"write-script-php": `---
|
|
73154
|
-
name: write-script-php
|
|
73155
|
-
description: MUST use when writing PHP scripts.
|
|
73156
|
-
---
|
|
73157
|
-
|
|
73158
|
-
## CLI Commands
|
|
73159
|
-
|
|
73160
|
-
Place scripts in a folder. After writing, run:
|
|
73161
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73162
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
73163
|
-
|
|
73164
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
73165
|
-
|
|
73166
|
-
# PHP
|
|
73167
|
-
|
|
73168
|
-
## Structure
|
|
73169
|
-
|
|
73170
|
-
The script must start with \`<?php\` and contain at least one function called \`main\`:
|
|
73171
|
-
|
|
73172
|
-
\`\`\`php
|
|
73173
|
-
<?php
|
|
73174
|
-
|
|
73175
|
-
function main(string $param1, int $param2) {
|
|
73176
|
-
return ["result" => $param1, "count" => $param2];
|
|
73177
|
-
}
|
|
73178
|
-
\`\`\`
|
|
73179
|
-
|
|
73180
|
-
## Resource Types
|
|
73181
|
-
|
|
73182
|
-
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
|
|
73183
|
-
|
|
73184
|
-
You need to **redefine** the type of the resources that are needed before the main function. Always check if the class already exists using \`class_exists\`:
|
|
73185
|
-
|
|
73186
|
-
\`\`\`php
|
|
73187
|
-
<?php
|
|
73188
|
-
|
|
73189
|
-
if (!class_exists('Postgresql')) {
|
|
73190
|
-
class Postgresql {
|
|
73191
|
-
public string $host;
|
|
73192
|
-
public int $port;
|
|
73193
|
-
public string $user;
|
|
73194
|
-
public string $password;
|
|
73195
|
-
public string $dbname;
|
|
73196
|
-
}
|
|
73197
|
-
}
|
|
73198
|
-
|
|
73199
|
-
function main(Postgresql $db) {
|
|
73200
|
-
// $db contains the database connection details
|
|
73201
|
-
}
|
|
73202
|
-
\`\`\`
|
|
73203
|
-
|
|
73204
|
-
The resource type name has to be exactly as specified.
|
|
73205
|
-
|
|
73206
|
-
## Library Dependencies
|
|
73207
|
-
|
|
73208
|
-
Specify library dependencies as comments before the main function:
|
|
73209
|
-
|
|
73210
|
-
\`\`\`php
|
|
73211
|
-
<?php
|
|
73212
|
-
|
|
73213
|
-
// require:
|
|
73214
|
-
// guzzlehttp/guzzle
|
|
73215
|
-
// stripe/stripe-php@^10.0
|
|
73007
|
+
/**
|
|
73008
|
+
* Commit Kafka offsets for a trigger with auto_commit disabled.
|
|
73009
|
+
* @param triggerPath - Path to the Kafka trigger (from event.wm_trigger.trigger_path)
|
|
73010
|
+
* @param topic - Kafka topic name (from event.topic)
|
|
73011
|
+
* @param partition - Partition number (from event.partition)
|
|
73012
|
+
* @param offset - Message offset to commit (from event.offset)
|
|
73013
|
+
*/
|
|
73014
|
+
async commitKafkaOffsets(triggerPath: string, topic: string, partition: number, offset: number,): Promise<void>
|
|
73216
73015
|
|
|
73217
|
-
|
|
73218
|
-
|
|
73219
|
-
|
|
73220
|
-
|
|
73016
|
+
/**
|
|
73017
|
+
* Create a SQL template function for PostgreSQL/datatable queries
|
|
73018
|
+
* @param name - Database/datatable name (default: "main")
|
|
73019
|
+
* @returns SQL template function for building parameterized queries
|
|
73020
|
+
* @example
|
|
73021
|
+
* let sql = wmill.datatable()
|
|
73022
|
+
* let name = 'Robin'
|
|
73023
|
+
* let age = 21
|
|
73024
|
+
* await sql\`
|
|
73025
|
+
* SELECT * FROM friends
|
|
73026
|
+
* WHERE name = \${name} AND age = \${age}::int
|
|
73027
|
+
* \`.fetch()
|
|
73028
|
+
*/
|
|
73029
|
+
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
73221
73030
|
|
|
73222
|
-
|
|
73031
|
+
/**
|
|
73032
|
+
* Create a SQL template function for DuckDB/ducklake queries
|
|
73033
|
+
* @param name - DuckDB database name (default: "main")
|
|
73034
|
+
* @returns SQL template function for building parameterized queries
|
|
73035
|
+
* @example
|
|
73036
|
+
* let sql = wmill.ducklake()
|
|
73037
|
+
* let name = 'Robin'
|
|
73038
|
+
* let age = 21
|
|
73039
|
+
* await sql\`
|
|
73040
|
+
* SELECT * FROM friends
|
|
73041
|
+
* WHERE name = \${name} AND age = \${age}
|
|
73042
|
+
* \`.fetch()
|
|
73043
|
+
*/
|
|
73044
|
+
ducklake(name: string = "main"): SqlTemplateFunction
|
|
73223
73045
|
`,
|
|
73224
|
-
"write-script-
|
|
73225
|
-
name: write-script-
|
|
73226
|
-
description: MUST use when writing
|
|
73046
|
+
"write-script-bunnative": `---
|
|
73047
|
+
name: write-script-bunnative
|
|
73048
|
+
description: MUST use when writing Bun Native scripts.
|
|
73227
73049
|
---
|
|
73228
73050
|
|
|
73229
73051
|
## CLI Commands
|
|
73230
73052
|
|
|
73231
|
-
Place scripts in a folder. After writing, run:
|
|
73053
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
73232
73054
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73233
73055
|
- \`wmill sync push\` - Deploy to Windmill
|
|
73234
73056
|
|
|
73235
|
-
|
|
73236
|
-
|
|
73237
|
-
# BigQuery
|
|
73238
|
-
|
|
73239
|
-
Arguments use \`@name\` syntax.
|
|
73240
|
-
|
|
73241
|
-
Name the parameters by adding comments before the statement:
|
|
73242
|
-
|
|
73243
|
-
\`\`\`sql
|
|
73244
|
-
-- @name1 (string)
|
|
73245
|
-
-- @name2 (int64) = 0
|
|
73246
|
-
SELECT * FROM users WHERE name = @name1 AND age > @name2;
|
|
73247
|
-
\`\`\`
|
|
73248
|
-
`,
|
|
73249
|
-
"write-script-bun": `---
|
|
73250
|
-
name: write-script-bun
|
|
73251
|
-
description: MUST use when writing Bun/TypeScript scripts.
|
|
73252
|
-
---
|
|
73253
|
-
|
|
73254
|
-
## CLI Commands
|
|
73255
|
-
|
|
73256
|
-
Place scripts in a folder. After writing, run:
|
|
73257
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73258
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
73057
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
73259
73058
|
|
|
73260
73059
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
73261
73060
|
|
|
73262
|
-
# TypeScript (Bun)
|
|
73061
|
+
# TypeScript (Bun Native)
|
|
73263
73062
|
|
|
73264
|
-
|
|
73063
|
+
Native TypeScript execution with fetch only - no external imports allowed.
|
|
73265
73064
|
|
|
73266
73065
|
## Structure
|
|
73267
73066
|
|
|
@@ -73274,7 +73073,7 @@ export async function main(param1: string, param2: number) {
|
|
|
73274
73073
|
}
|
|
73275
73074
|
\`\`\`
|
|
73276
73075
|
|
|
73277
|
-
Do not call the main function.
|
|
73076
|
+
Do not call the main function.
|
|
73278
73077
|
|
|
73279
73078
|
## Resource Types
|
|
73280
73079
|
|
|
@@ -73294,20 +73093,18 @@ Before using a resource type, check the \`rt.d.ts\` file in the project root to
|
|
|
73294
73093
|
|
|
73295
73094
|
## Imports
|
|
73296
73095
|
|
|
73096
|
+
**No imports allowed.** Use the globally available \`fetch\` function:
|
|
73097
|
+
|
|
73297
73098
|
\`\`\`typescript
|
|
73298
|
-
|
|
73299
|
-
|
|
73099
|
+
export async function main(url: string) {
|
|
73100
|
+
const response = await fetch(url);
|
|
73101
|
+
return await response.json();
|
|
73102
|
+
}
|
|
73300
73103
|
\`\`\`
|
|
73301
73104
|
|
|
73302
73105
|
## Windmill Client
|
|
73303
73106
|
|
|
73304
|
-
|
|
73305
|
-
|
|
73306
|
-
\`\`\`typescript
|
|
73307
|
-
import * as wmill from "windmill-client";
|
|
73308
|
-
\`\`\`
|
|
73309
|
-
|
|
73310
|
-
See the SDK documentation for available methods.
|
|
73107
|
+
The windmill client is not available in native TypeScript mode. Use fetch to call APIs directly.
|
|
73311
73108
|
|
|
73312
73109
|
## Preprocessor Scripts
|
|
73313
73110
|
|
|
@@ -73377,36 +73174,6 @@ const result: S3Object = await wmill.writeS3File(
|
|
|
73377
73174
|
|
|
73378
73175
|
Import: import * as wmill from 'windmill-client'
|
|
73379
73176
|
|
|
73380
|
-
/**
|
|
73381
|
-
* Create a SQL template function for PostgreSQL/datatable queries
|
|
73382
|
-
* @param name - Database/datatable name (default: "main")
|
|
73383
|
-
* @returns SQL template function for building parameterized queries
|
|
73384
|
-
* @example
|
|
73385
|
-
* let sql = wmill.datatable()
|
|
73386
|
-
* let name = 'Robin'
|
|
73387
|
-
* let age = 21
|
|
73388
|
-
* await sql\`
|
|
73389
|
-
* SELECT * FROM friends
|
|
73390
|
-
* WHERE name = \${name} AND age = \${age}::int
|
|
73391
|
-
* \`.fetch()
|
|
73392
|
-
*/
|
|
73393
|
-
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
73394
|
-
|
|
73395
|
-
/**
|
|
73396
|
-
* Create a SQL template function for DuckDB/ducklake queries
|
|
73397
|
-
* @param name - DuckDB database name (default: "main")
|
|
73398
|
-
* @returns SQL template function for building parameterized queries
|
|
73399
|
-
* @example
|
|
73400
|
-
* let sql = wmill.ducklake()
|
|
73401
|
-
* let name = 'Robin'
|
|
73402
|
-
* let age = 21
|
|
73403
|
-
* await sql\`
|
|
73404
|
-
* SELECT * FROM friends
|
|
73405
|
-
* WHERE name = \${name} AND age = \${age}
|
|
73406
|
-
* \`.fetch()
|
|
73407
|
-
*/
|
|
73408
|
-
ducklake(name: string = "main"): SqlTemplateFunction
|
|
73409
|
-
|
|
73410
73177
|
/**
|
|
73411
73178
|
* Initialize the Windmill client with authentication token and base URL
|
|
73412
73179
|
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
|
@@ -73899,6 +73666,45 @@ waitForApproval(options?: { timeout?: number; form?: object; }): PromiseLike<{ v
|
|
|
73899
73666
|
* const results = await parallel(items, process, { concurrency: 5 });
|
|
73900
73667
|
*/
|
|
73901
73668
|
async parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
|
|
73669
|
+
|
|
73670
|
+
/**
|
|
73671
|
+
* Commit Kafka offsets for a trigger with auto_commit disabled.
|
|
73672
|
+
* @param triggerPath - Path to the Kafka trigger (from event.wm_trigger.trigger_path)
|
|
73673
|
+
* @param topic - Kafka topic name (from event.topic)
|
|
73674
|
+
* @param partition - Partition number (from event.partition)
|
|
73675
|
+
* @param offset - Message offset to commit (from event.offset)
|
|
73676
|
+
*/
|
|
73677
|
+
async commitKafkaOffsets(triggerPath: string, topic: string, partition: number, offset: number,): Promise<void>
|
|
73678
|
+
|
|
73679
|
+
/**
|
|
73680
|
+
* Create a SQL template function for PostgreSQL/datatable queries
|
|
73681
|
+
* @param name - Database/datatable name (default: "main")
|
|
73682
|
+
* @returns SQL template function for building parameterized queries
|
|
73683
|
+
* @example
|
|
73684
|
+
* let sql = wmill.datatable()
|
|
73685
|
+
* let name = 'Robin'
|
|
73686
|
+
* let age = 21
|
|
73687
|
+
* await sql\`
|
|
73688
|
+
* SELECT * FROM friends
|
|
73689
|
+
* WHERE name = \${name} AND age = \${age}::int
|
|
73690
|
+
* \`.fetch()
|
|
73691
|
+
*/
|
|
73692
|
+
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
73693
|
+
|
|
73694
|
+
/**
|
|
73695
|
+
* Create a SQL template function for DuckDB/ducklake queries
|
|
73696
|
+
* @param name - DuckDB database name (default: "main")
|
|
73697
|
+
* @returns SQL template function for building parameterized queries
|
|
73698
|
+
* @example
|
|
73699
|
+
* let sql = wmill.ducklake()
|
|
73700
|
+
* let name = 'Robin'
|
|
73701
|
+
* let age = 21
|
|
73702
|
+
* await sql\`
|
|
73703
|
+
* SELECT * FROM friends
|
|
73704
|
+
* WHERE name = \${name} AND age = \${age}
|
|
73705
|
+
* \`.fetch()
|
|
73706
|
+
*/
|
|
73707
|
+
ducklake(name: string = "main"): SqlTemplateFunction
|
|
73902
73708
|
`,
|
|
73903
73709
|
"write-script-csharp": `---
|
|
73904
73710
|
name: write-script-csharp
|
|
@@ -73907,10 +73713,12 @@ description: MUST use when writing C# scripts.
|
|
|
73907
73713
|
|
|
73908
73714
|
## CLI Commands
|
|
73909
73715
|
|
|
73910
|
-
Place scripts in a folder. After writing, run:
|
|
73716
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
73911
73717
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73912
73718
|
- \`wmill sync push\` - Deploy to Windmill
|
|
73913
73719
|
|
|
73720
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
73721
|
+
|
|
73914
73722
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
73915
73723
|
|
|
73916
73724
|
# C#
|
|
@@ -73954,31 +73762,6 @@ public class Script
|
|
|
73954
73762
|
}
|
|
73955
73763
|
}
|
|
73956
73764
|
\`\`\`
|
|
73957
|
-
`,
|
|
73958
|
-
"write-script-mssql": `---
|
|
73959
|
-
name: write-script-mssql
|
|
73960
|
-
description: MUST use when writing MS SQL Server queries.
|
|
73961
|
-
---
|
|
73962
|
-
|
|
73963
|
-
## CLI Commands
|
|
73964
|
-
|
|
73965
|
-
Place scripts in a folder. After writing, run:
|
|
73966
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73967
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
73968
|
-
|
|
73969
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
73970
|
-
|
|
73971
|
-
# Microsoft SQL Server (MSSQL)
|
|
73972
|
-
|
|
73973
|
-
Arguments use \`@P1\`, \`@P2\`, etc.
|
|
73974
|
-
|
|
73975
|
-
Name the parameters by adding comments before the statement:
|
|
73976
|
-
|
|
73977
|
-
\`\`\`sql
|
|
73978
|
-
-- @P1 name1 (varchar)
|
|
73979
|
-
-- @P2 name2 (int) = 0
|
|
73980
|
-
SELECT * FROM users WHERE name = @P1 AND age > @P2;
|
|
73981
|
-
\`\`\`
|
|
73982
73765
|
`,
|
|
73983
73766
|
"write-script-deno": `---
|
|
73984
73767
|
name: write-script-deno
|
|
@@ -73987,10 +73770,12 @@ description: MUST use when writing Deno/TypeScript scripts.
|
|
|
73987
73770
|
|
|
73988
73771
|
## CLI Commands
|
|
73989
73772
|
|
|
73990
|
-
Place scripts in a folder. After writing, run:
|
|
73773
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
73991
73774
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
73992
73775
|
- \`wmill sync push\` - Deploy to Windmill
|
|
73993
73776
|
|
|
73777
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
73778
|
+
|
|
73994
73779
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
73995
73780
|
|
|
73996
73781
|
# TypeScript (Deno)
|
|
@@ -74115,6 +73900,508 @@ const result: S3Object = await wmill.writeS3File(
|
|
|
74115
73900
|
|
|
74116
73901
|
Import: import * as wmill from 'windmill-client'
|
|
74117
73902
|
|
|
73903
|
+
/**
|
|
73904
|
+
* Initialize the Windmill client with authentication token and base URL
|
|
73905
|
+
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
|
73906
|
+
* @param baseUrl - API base URL (defaults to BASE_INTERNAL_URL or BASE_URL env variable)
|
|
73907
|
+
*/
|
|
73908
|
+
setClient(token?: string, baseUrl?: string): void
|
|
73909
|
+
|
|
73910
|
+
/**
|
|
73911
|
+
* Create a client configuration from env variables
|
|
73912
|
+
* @returns client configuration
|
|
73913
|
+
*/
|
|
73914
|
+
getWorkspace(): string
|
|
73915
|
+
|
|
73916
|
+
/**
|
|
73917
|
+
* Get a resource value by path
|
|
73918
|
+
* @param path path of the resource, default to internal state path
|
|
73919
|
+
* @param undefinedIfEmpty if the resource does not exist, return undefined instead of throwing an error
|
|
73920
|
+
* @returns resource value
|
|
73921
|
+
*/
|
|
73922
|
+
async getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any>
|
|
73923
|
+
|
|
73924
|
+
/**
|
|
73925
|
+
* Get the true root job id
|
|
73926
|
+
* @param jobId job id to get the root job id from (default to current job)
|
|
73927
|
+
* @returns root job id
|
|
73928
|
+
*/
|
|
73929
|
+
async getRootJobId(jobId?: string): Promise<string>
|
|
73930
|
+
|
|
73931
|
+
/**
|
|
73932
|
+
* @deprecated Use runScriptByPath or runScriptByHash instead
|
|
73933
|
+
*/
|
|
73934
|
+
async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
73935
|
+
|
|
73936
|
+
/**
|
|
73937
|
+
* Run a script synchronously by its path and wait for the result
|
|
73938
|
+
* @param path - Script path in Windmill
|
|
73939
|
+
* @param args - Arguments to pass to the script
|
|
73940
|
+
* @param verbose - Enable verbose logging
|
|
73941
|
+
* @returns Script execution result
|
|
73942
|
+
*/
|
|
73943
|
+
async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
73944
|
+
|
|
73945
|
+
/**
|
|
73946
|
+
* Run a script synchronously by its hash and wait for the result
|
|
73947
|
+
* @param hash_ - Script hash in Windmill
|
|
73948
|
+
* @param args - Arguments to pass to the script
|
|
73949
|
+
* @param verbose - Enable verbose logging
|
|
73950
|
+
* @returns Script execution result
|
|
73951
|
+
*/
|
|
73952
|
+
async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
73953
|
+
|
|
73954
|
+
/**
|
|
73955
|
+
* Append a text to the result stream
|
|
73956
|
+
* @param text text to append to the result stream
|
|
73957
|
+
*/
|
|
73958
|
+
appendToResultStream(text: string): void
|
|
73959
|
+
|
|
73960
|
+
/**
|
|
73961
|
+
* Stream to the result stream
|
|
73962
|
+
* @param stream stream to stream to the result stream
|
|
73963
|
+
*/
|
|
73964
|
+
async streamResult(stream: AsyncIterable<string>): Promise<void>
|
|
73965
|
+
|
|
73966
|
+
/**
|
|
73967
|
+
* Run a flow synchronously by its path and wait for the result
|
|
73968
|
+
* @param path - Flow path in Windmill
|
|
73969
|
+
* @param args - Arguments to pass to the flow
|
|
73970
|
+
* @param verbose - Enable verbose logging
|
|
73971
|
+
* @returns Flow execution result
|
|
73972
|
+
*/
|
|
73973
|
+
async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
73974
|
+
|
|
73975
|
+
/**
|
|
73976
|
+
* Wait for a job to complete and return its result
|
|
73977
|
+
* @param jobId - ID of the job to wait for
|
|
73978
|
+
* @param verbose - Enable verbose logging
|
|
73979
|
+
* @returns Job result when completed
|
|
73980
|
+
*/
|
|
73981
|
+
async waitJob(jobId: string, verbose: boolean = false): Promise<any>
|
|
73982
|
+
|
|
73983
|
+
/**
|
|
73984
|
+
* Get the result of a completed job
|
|
73985
|
+
* @param jobId - ID of the completed job
|
|
73986
|
+
* @returns Job result
|
|
73987
|
+
*/
|
|
73988
|
+
async getResult(jobId: string): Promise<any>
|
|
73989
|
+
|
|
73990
|
+
/**
|
|
73991
|
+
* Get the result of a job if completed, or its current status
|
|
73992
|
+
* @param jobId - ID of the job
|
|
73993
|
+
* @returns Object with started, completed, success, and result properties
|
|
73994
|
+
*/
|
|
73995
|
+
async getResultMaybe(jobId: string): Promise<any>
|
|
73996
|
+
|
|
73997
|
+
/**
|
|
73998
|
+
* @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead
|
|
73999
|
+
*/
|
|
74000
|
+
async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
|
|
74001
|
+
|
|
74002
|
+
/**
|
|
74003
|
+
* Run a script asynchronously by its path
|
|
74004
|
+
* @param path - Script path in Windmill
|
|
74005
|
+
* @param args - Arguments to pass to the script
|
|
74006
|
+
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
74007
|
+
* @returns Job ID of the created job
|
|
74008
|
+
*/
|
|
74009
|
+
async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
|
|
74010
|
+
|
|
74011
|
+
/**
|
|
74012
|
+
* Run a script asynchronously by its hash
|
|
74013
|
+
* @param hash_ - Script hash in Windmill
|
|
74014
|
+
* @param args - Arguments to pass to the script
|
|
74015
|
+
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
74016
|
+
* @returns Job ID of the created job
|
|
74017
|
+
*/
|
|
74018
|
+
async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
|
|
74019
|
+
|
|
74020
|
+
/**
|
|
74021
|
+
* Run a flow asynchronously by its path
|
|
74022
|
+
* @param path - Flow path in Windmill
|
|
74023
|
+
* @param args - Arguments to pass to the flow
|
|
74024
|
+
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
74025
|
+
* @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
|
|
74026
|
+
* @returns Job ID of the created job
|
|
74027
|
+
*/
|
|
74028
|
+
async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
|
|
74029
|
+
|
|
74030
|
+
/**
|
|
74031
|
+
* Resolve a resource value in case the default value was picked because the input payload was undefined
|
|
74032
|
+
* @param obj resource value or path of the resource under the format \`$res:path\`
|
|
74033
|
+
* @returns resource value
|
|
74034
|
+
*/
|
|
74035
|
+
async resolveDefaultResource(obj: any): Promise<any>
|
|
74036
|
+
|
|
74037
|
+
/**
|
|
74038
|
+
* Get the state file path from environment variables
|
|
74039
|
+
* @returns State path string
|
|
74040
|
+
*/
|
|
74041
|
+
getStatePath(): string
|
|
74042
|
+
|
|
74043
|
+
/**
|
|
74044
|
+
* Set a resource value by path
|
|
74045
|
+
* @param path path of the resource to set, default to state path
|
|
74046
|
+
* @param value new value of the resource to set
|
|
74047
|
+
* @param initializeToTypeIfNotExist if the resource does not exist, initialize it with this type
|
|
74048
|
+
*/
|
|
74049
|
+
async setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise<void>
|
|
74050
|
+
|
|
74051
|
+
/**
|
|
74052
|
+
* Set the state
|
|
74053
|
+
* @param state state to set
|
|
74054
|
+
* @deprecated use setState instead
|
|
74055
|
+
*/
|
|
74056
|
+
async setInternalState(state: any): Promise<void>
|
|
74057
|
+
|
|
74058
|
+
/**
|
|
74059
|
+
* Set the state
|
|
74060
|
+
* @param state state to set
|
|
74061
|
+
* @param path Optional state resource path override. Defaults to \`getStatePath()\`.
|
|
74062
|
+
*/
|
|
74063
|
+
async setState(state: any, path?: string): Promise<void>
|
|
74064
|
+
|
|
74065
|
+
/**
|
|
74066
|
+
* Set the progress
|
|
74067
|
+
* Progress cannot go back and limited to 0% to 99% range
|
|
74068
|
+
* @param percent Progress to set in %
|
|
74069
|
+
* @param jobId? Job to set progress for
|
|
74070
|
+
*/
|
|
74071
|
+
async setProgress(percent: number, jobId?: any): Promise<void>
|
|
74072
|
+
|
|
74073
|
+
/**
|
|
74074
|
+
* Get the progress
|
|
74075
|
+
* @param jobId? Job to get progress from
|
|
74076
|
+
* @returns Optional clamped between 0 and 100 progress value
|
|
74077
|
+
*/
|
|
74078
|
+
async getProgress(jobId?: any): Promise<number | null>
|
|
74079
|
+
|
|
74080
|
+
/**
|
|
74081
|
+
* Set a flow user state
|
|
74082
|
+
* @param key key of the state
|
|
74083
|
+
* @param value value of the state
|
|
74084
|
+
*/
|
|
74085
|
+
async setFlowUserState(key: string, value: any, errorIfNotPossible?: boolean): Promise<void>
|
|
74086
|
+
|
|
74087
|
+
/**
|
|
74088
|
+
* Get a flow user state
|
|
74089
|
+
* @param path path of the variable
|
|
74090
|
+
*/
|
|
74091
|
+
async getFlowUserState(key: string, errorIfNotPossible?: boolean): Promise<any>
|
|
74092
|
+
|
|
74093
|
+
/**
|
|
74094
|
+
* Get the internal state
|
|
74095
|
+
* @deprecated use getState instead
|
|
74096
|
+
*/
|
|
74097
|
+
async getInternalState(): Promise<any>
|
|
74098
|
+
|
|
74099
|
+
/**
|
|
74100
|
+
* Get the state shared across executions
|
|
74101
|
+
* @param path Optional state resource path override. Defaults to \`getStatePath()\`.
|
|
74102
|
+
*/
|
|
74103
|
+
async getState(path?: string): Promise<any>
|
|
74104
|
+
|
|
74105
|
+
/**
|
|
74106
|
+
* Get a variable by path
|
|
74107
|
+
* @param path path of the variable
|
|
74108
|
+
* @returns variable value
|
|
74109
|
+
*/
|
|
74110
|
+
async getVariable(path: string): Promise<string>
|
|
74111
|
+
|
|
74112
|
+
/**
|
|
74113
|
+
* Set a variable by path, create if not exist
|
|
74114
|
+
* @param path path of the variable
|
|
74115
|
+
* @param value value of the variable
|
|
74116
|
+
* @param isSecretIfNotExist if the variable does not exist, create it as secret or not (default: false)
|
|
74117
|
+
* @param descriptionIfNotExist if the variable does not exist, create it with this description (default: "")
|
|
74118
|
+
*/
|
|
74119
|
+
async setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise<void>
|
|
74120
|
+
|
|
74121
|
+
/**
|
|
74122
|
+
* Build a PostgreSQL connection URL from a database resource
|
|
74123
|
+
* @param path - Path to the database resource
|
|
74124
|
+
* @returns PostgreSQL connection URL string
|
|
74125
|
+
*/
|
|
74126
|
+
async databaseUrlFromResource(path: string): Promise<string>
|
|
74127
|
+
|
|
74128
|
+
async polarsConnectionSettings(s3_resource_path: string | undefined): Promise<any>
|
|
74129
|
+
|
|
74130
|
+
async duckdbConnectionSettings(s3_resource_path: string | undefined): Promise<any>
|
|
74131
|
+
|
|
74132
|
+
/**
|
|
74133
|
+
* Get S3 client settings from a resource or workspace default
|
|
74134
|
+
* @param s3_resource_path - Path to S3 resource (uses workspace default if undefined)
|
|
74135
|
+
* @returns S3 client configuration settings
|
|
74136
|
+
*/
|
|
74137
|
+
async denoS3LightClientSettings(s3_resource_path: string | undefined): Promise<DenoS3LightClientSettings>
|
|
74138
|
+
|
|
74139
|
+
/**
|
|
74140
|
+
* Load the content of a file stored in S3. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
|
|
74141
|
+
*
|
|
74142
|
+
* \`\`\`typescript
|
|
74143
|
+
* let fileContent = await wmill.loadS3FileContent(inputFile)
|
|
74144
|
+
* // if the file is a raw text file, it can be decoded and printed directly:
|
|
74145
|
+
* const text = new TextDecoder().decode(fileContentStream)
|
|
74146
|
+
* console.log(text);
|
|
74147
|
+
* \`\`\`
|
|
74148
|
+
*/
|
|
74149
|
+
async loadS3File(s3object: S3Object, s3ResourcePath: string | undefined = undefined): Promise<Uint8Array | undefined>
|
|
74150
|
+
|
|
74151
|
+
/**
|
|
74152
|
+
* Load the content of a file stored in S3 as a stream. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
|
|
74153
|
+
*
|
|
74154
|
+
* \`\`\`typescript
|
|
74155
|
+
* let fileContentBlob = await wmill.loadS3FileStream(inputFile)
|
|
74156
|
+
* // if the content is plain text, the blob can be read directly:
|
|
74157
|
+
* console.log(await fileContentBlob.text());
|
|
74158
|
+
* \`\`\`
|
|
74159
|
+
*/
|
|
74160
|
+
async loadS3FileStream(s3object: S3Object, s3ResourcePath: string | undefined = undefined): Promise<Blob | undefined>
|
|
74161
|
+
|
|
74162
|
+
/**
|
|
74163
|
+
* Persist a file to the S3 bucket. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
|
|
74164
|
+
*
|
|
74165
|
+
* \`\`\`typescript
|
|
74166
|
+
* const s3object = await writeS3File(s3Object, "Hello Windmill!")
|
|
74167
|
+
* const fileContentAsUtf8Str = (await s3object.toArray()).toString('utf-8')
|
|
74168
|
+
* console.log(fileContentAsUtf8Str)
|
|
74169
|
+
* \`\`\`
|
|
74170
|
+
*/
|
|
74171
|
+
async writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath: string | undefined = undefined, contentType: string | undefined = undefined, contentDisposition: string | undefined = undefined): Promise<S3Object>
|
|
74172
|
+
|
|
74173
|
+
/**
|
|
74174
|
+
* Sign S3 objects to be used by anonymous users in public apps
|
|
74175
|
+
* @param s3objects s3 objects to sign
|
|
74176
|
+
* @returns signed s3 objects
|
|
74177
|
+
*/
|
|
74178
|
+
async signS3Objects(s3objects: S3Object[]): Promise<S3Object[]>
|
|
74179
|
+
|
|
74180
|
+
/**
|
|
74181
|
+
* Sign S3 object to be used by anonymous users in public apps
|
|
74182
|
+
* @param s3object s3 object to sign
|
|
74183
|
+
* @returns signed s3 object
|
|
74184
|
+
*/
|
|
74185
|
+
async signS3Object(s3object: S3Object): Promise<S3Object>
|
|
74186
|
+
|
|
74187
|
+
/**
|
|
74188
|
+
* Generate a presigned public URL for an array of S3 objects.
|
|
74189
|
+
* If an S3 object is not signed yet, it will be signed first.
|
|
74190
|
+
* @param s3Objects s3 objects to sign
|
|
74191
|
+
* @returns list of signed public URLs
|
|
74192
|
+
*/
|
|
74193
|
+
async getPresignedS3PublicUrls(s3Objects: S3Object[], { baseUrl }: { baseUrl?: string } = {}): Promise<string[]>
|
|
74194
|
+
|
|
74195
|
+
/**
|
|
74196
|
+
* Generate a presigned public URL for an S3 object. If the S3 object is not signed yet, it will be signed first.
|
|
74197
|
+
* @param s3Object s3 object to sign
|
|
74198
|
+
* @returns signed public URL
|
|
74199
|
+
*/
|
|
74200
|
+
async getPresignedS3PublicUrl(s3Objects: S3Object, { baseUrl }: { baseUrl?: string } = {}): Promise<string>
|
|
74201
|
+
|
|
74202
|
+
/**
|
|
74203
|
+
* Get URLs needed for resuming a flow after this step
|
|
74204
|
+
* @param approver approver name
|
|
74205
|
+
* @param flowLevel if true, generate resume URLs for the parent flow instead of the specific step.
|
|
74206
|
+
* This allows pre-approvals that can be consumed by any later suspend step in the same flow.
|
|
74207
|
+
* @returns approval page UI URL, resume and cancel API URLs for resuming the flow
|
|
74208
|
+
*/
|
|
74209
|
+
async getResumeUrls(approver?: string, flowLevel?: boolean): Promise<{
|
|
74210
|
+
approvalPage: string;
|
|
74211
|
+
resume: string;
|
|
74212
|
+
cancel: string;
|
|
74213
|
+
}>
|
|
74214
|
+
|
|
74215
|
+
/**
|
|
74216
|
+
* @deprecated use getResumeUrls instead
|
|
74217
|
+
*/
|
|
74218
|
+
getResumeEndpoints(approver?: string): Promise<{
|
|
74219
|
+
approvalPage: string;
|
|
74220
|
+
resume: string;
|
|
74221
|
+
cancel: string;
|
|
74222
|
+
}>
|
|
74223
|
+
|
|
74224
|
+
/**
|
|
74225
|
+
* Get an OIDC jwt token for auth to external services (e.g: Vault, AWS) (ee only)
|
|
74226
|
+
* @param audience audience of the token
|
|
74227
|
+
* @param expiresIn Optional number of seconds until the token expires
|
|
74228
|
+
* @returns jwt token
|
|
74229
|
+
*/
|
|
74230
|
+
async getIdToken(audience: string, expiresIn?: number): Promise<string>
|
|
74231
|
+
|
|
74232
|
+
/**
|
|
74233
|
+
* Convert a base64-encoded string to Uint8Array
|
|
74234
|
+
* @param data - Base64-encoded string
|
|
74235
|
+
* @returns Decoded Uint8Array
|
|
74236
|
+
*/
|
|
74237
|
+
base64ToUint8Array(data: string): Uint8Array
|
|
74238
|
+
|
|
74239
|
+
/**
|
|
74240
|
+
* Convert a Uint8Array to base64-encoded string
|
|
74241
|
+
* @param arrayBuffer - Uint8Array to encode
|
|
74242
|
+
* @returns Base64-encoded string
|
|
74243
|
+
*/
|
|
74244
|
+
uint8ArrayToBase64(arrayBuffer: Uint8Array): string
|
|
74245
|
+
|
|
74246
|
+
/**
|
|
74247
|
+
* Get email from workspace username
|
|
74248
|
+
* This method is particularly useful for apps that require the email address of the viewer.
|
|
74249
|
+
* Indeed, in the viewer context, WM_USERNAME is set to the username of the viewer but WM_EMAIL is set to the email of the creator of the app.
|
|
74250
|
+
* @param username
|
|
74251
|
+
* @returns email address
|
|
74252
|
+
*/
|
|
74253
|
+
async usernameToEmail(username: string): Promise<string>
|
|
74254
|
+
|
|
74255
|
+
/**
|
|
74256
|
+
* Sends an interactive approval request via Slack, allowing optional customization of the message, approver, and form fields.
|
|
74257
|
+
*
|
|
74258
|
+
* **[Enterprise Edition Only]** To include form fields in the Slack approval request, go to **Advanced -> Suspend -> Form**
|
|
74259
|
+
* and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
|
|
74260
|
+
*
|
|
74261
|
+
* @param {Object} options - The configuration options for the Slack approval request.
|
|
74262
|
+
* @param {string} options.slackResourcePath - The path to the Slack resource in Windmill.
|
|
74263
|
+
* @param {string} options.channelId - The Slack channel ID where the approval request will be sent.
|
|
74264
|
+
* @param {string} [options.message] - Optional custom message to include in the Slack approval request.
|
|
74265
|
+
* @param {string} [options.approver] - Optional user ID or name of the approver for the request.
|
|
74266
|
+
* @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
|
|
74267
|
+
* @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
|
|
74268
|
+
* @param {string} [options.resumeButtonText] - Optional text for the resume button.
|
|
74269
|
+
* @param {string} [options.cancelButtonText] - Optional text for the cancel button.
|
|
74270
|
+
*
|
|
74271
|
+
* @returns {Promise<void>} Resolves when the Slack approval request is successfully sent.
|
|
74272
|
+
*
|
|
74273
|
+
* @throws {Error} If the function is not called within a flow or flow preview.
|
|
74274
|
+
* @throws {Error} If the \`JobService.getSlackApprovalPayload\` call fails.
|
|
74275
|
+
*
|
|
74276
|
+
* **Usage Example:**
|
|
74277
|
+
* \`\`\`typescript
|
|
74278
|
+
* await requestInteractiveSlackApproval({
|
|
74279
|
+
* slackResourcePath: "/u/alex/my_slack_resource",
|
|
74280
|
+
* channelId: "admins-slack-channel",
|
|
74281
|
+
* message: "Please approve this request",
|
|
74282
|
+
* approver: "approver123",
|
|
74283
|
+
* defaultArgsJson: { key1: "value1", key2: 42 },
|
|
74284
|
+
* dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
|
|
74285
|
+
* resumeButtonText: "Resume",
|
|
74286
|
+
* cancelButtonText: "Cancel",
|
|
74287
|
+
* });
|
|
74288
|
+
* \`\`\`
|
|
74289
|
+
*
|
|
74290
|
+
* **Note:** This function requires execution within a Windmill flow or flow preview.
|
|
74291
|
+
*/
|
|
74292
|
+
async requestInteractiveSlackApproval({ slackResourcePath, channelId, message, approver, defaultArgsJson, dynamicEnumsJson, resumeButtonText, cancelButtonText, }: SlackApprovalOptions): Promise<void>
|
|
74293
|
+
|
|
74294
|
+
/**
|
|
74295
|
+
* Sends an interactive approval request via Teams, allowing optional customization of the message, approver, and form fields.
|
|
74296
|
+
*
|
|
74297
|
+
* **[Enterprise Edition Only]** To include form fields in the Teams approval request, go to **Advanced -> Suspend -> Form**
|
|
74298
|
+
* and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
|
|
74299
|
+
*
|
|
74300
|
+
* @param {Object} options - The configuration options for the Teams approval request.
|
|
74301
|
+
* @param {string} options.teamName - The Teams team name where the approval request will be sent.
|
|
74302
|
+
* @param {string} options.channelName - The Teams channel name where the approval request will be sent.
|
|
74303
|
+
* @param {string} [options.message] - Optional custom message to include in the Teams approval request.
|
|
74304
|
+
* @param {string} [options.approver] - Optional user ID or name of the approver for the request.
|
|
74305
|
+
* @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
|
|
74306
|
+
* @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
|
|
74307
|
+
*
|
|
74308
|
+
* @returns {Promise<void>} Resolves when the Teams approval request is successfully sent.
|
|
74309
|
+
*
|
|
74310
|
+
* @throws {Error} If the function is not called within a flow or flow preview.
|
|
74311
|
+
* @throws {Error} If the \`JobService.getTeamsApprovalPayload\` call fails.
|
|
74312
|
+
*
|
|
74313
|
+
* **Usage Example:**
|
|
74314
|
+
* \`\`\`typescript
|
|
74315
|
+
* await requestInteractiveTeamsApproval({
|
|
74316
|
+
* teamName: "admins-teams",
|
|
74317
|
+
* channelName: "admins-teams-channel",
|
|
74318
|
+
* message: "Please approve this request",
|
|
74319
|
+
* approver: "approver123",
|
|
74320
|
+
* defaultArgsJson: { key1: "value1", key2: 42 },
|
|
74321
|
+
* dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
|
|
74322
|
+
* });
|
|
74323
|
+
* \`\`\`
|
|
74324
|
+
*
|
|
74325
|
+
* **Note:** This function requires execution within a Windmill flow or flow preview.
|
|
74326
|
+
*/
|
|
74327
|
+
async requestInteractiveTeamsApproval({ teamName, channelName, message, approver, defaultArgsJson, dynamicEnumsJson, }: TeamsApprovalOptions): Promise<void>
|
|
74328
|
+
|
|
74329
|
+
/**
|
|
74330
|
+
* Parse an S3 object from URI string or record format
|
|
74331
|
+
* @param s3Object - S3 object as URI string (s3://storage/key) or record
|
|
74332
|
+
* @returns S3 object record with storage and s3 key
|
|
74333
|
+
*/
|
|
74334
|
+
parseS3Object(s3Object: S3Object): S3ObjectRecord
|
|
74335
|
+
|
|
74336
|
+
setWorkflowCtx(ctx: WorkflowCtx | null): void
|
|
74337
|
+
|
|
74338
|
+
async sleep(seconds: number): Promise<void>
|
|
74339
|
+
|
|
74340
|
+
async step<T>(name: string, fn: () => T | Promise<T>): Promise<T>
|
|
74341
|
+
|
|
74342
|
+
/**
|
|
74343
|
+
* Create a task that dispatches to a separate Windmill script.
|
|
74344
|
+
*
|
|
74345
|
+
* @example
|
|
74346
|
+
* const extract = taskScript("f/data/extract");
|
|
74347
|
+
* // inside workflow: await extract({ url: "https://..." })
|
|
74348
|
+
*/
|
|
74349
|
+
taskScript(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
|
|
74350
|
+
|
|
74351
|
+
/**
|
|
74352
|
+
* Create a task that dispatches to a separate Windmill flow.
|
|
74353
|
+
*
|
|
74354
|
+
* @example
|
|
74355
|
+
* const pipeline = taskFlow("f/etl/pipeline");
|
|
74356
|
+
* // inside workflow: await pipeline({ input: data })
|
|
74357
|
+
*/
|
|
74358
|
+
taskFlow(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
|
|
74359
|
+
|
|
74360
|
+
/**
|
|
74361
|
+
* Mark an async function as a workflow-as-code entry point.
|
|
74362
|
+
*
|
|
74363
|
+
* The function must be **deterministic**: given the same inputs it must call
|
|
74364
|
+
* tasks in the same order on every replay. Branching on task results is fine
|
|
74365
|
+
* (results are replayed from checkpoint), but branching on external state
|
|
74366
|
+
* (current time, random values, external API calls) must use \`step()\` to
|
|
74367
|
+
* checkpoint the value so replays see the same result.
|
|
74368
|
+
*/
|
|
74369
|
+
workflow<T>(fn: (...args: any[]) => Promise<T>): void
|
|
74370
|
+
|
|
74371
|
+
/**
|
|
74372
|
+
* Suspend the workflow and wait for an external approval.
|
|
74373
|
+
*
|
|
74374
|
+
* Use \`getResumeUrls()\` (wrapped in \`step()\`) to obtain resume/cancel/approvalPage
|
|
74375
|
+
* URLs before calling this function.
|
|
74376
|
+
*
|
|
74377
|
+
* @example
|
|
74378
|
+
* const urls = await step("urls", () => getResumeUrls());
|
|
74379
|
+
* await step("notify", () => sendEmail(urls.approvalPage));
|
|
74380
|
+
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
74381
|
+
*/
|
|
74382
|
+
waitForApproval(options?: { timeout?: number; form?: object; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
74383
|
+
|
|
74384
|
+
/**
|
|
74385
|
+
* Process items in parallel with optional concurrency control.
|
|
74386
|
+
*
|
|
74387
|
+
* Each item is processed by calling \`fn(item)\`, which should be a task().
|
|
74388
|
+
* Items are dispatched in batches of \`concurrency\` (default: all at once).
|
|
74389
|
+
*
|
|
74390
|
+
* @example
|
|
74391
|
+
* const process = task(async (item: string) => { ... });
|
|
74392
|
+
* const results = await parallel(items, process, { concurrency: 5 });
|
|
74393
|
+
*/
|
|
74394
|
+
async parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
|
|
74395
|
+
|
|
74396
|
+
/**
|
|
74397
|
+
* Commit Kafka offsets for a trigger with auto_commit disabled.
|
|
74398
|
+
* @param triggerPath - Path to the Kafka trigger (from event.wm_trigger.trigger_path)
|
|
74399
|
+
* @param topic - Kafka topic name (from event.topic)
|
|
74400
|
+
* @param partition - Partition number (from event.partition)
|
|
74401
|
+
* @param offset - Message offset to commit (from event.offset)
|
|
74402
|
+
*/
|
|
74403
|
+
async commitKafkaOffsets(triggerPath: string, topic: string, partition: number, offset: number,): Promise<void>
|
|
74404
|
+
|
|
74118
74405
|
/**
|
|
74119
74406
|
* Create a SQL template function for PostgreSQL/datatable queries
|
|
74120
74407
|
* @param name - Database/datatable name (default: "main")
|
|
@@ -74144,6 +74431,414 @@ datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
|
74144
74431
|
* \`.fetch()
|
|
74145
74432
|
*/
|
|
74146
74433
|
ducklake(name: string = "main"): SqlTemplateFunction
|
|
74434
|
+
`,
|
|
74435
|
+
"write-script-duckdb": `---
|
|
74436
|
+
name: write-script-duckdb
|
|
74437
|
+
description: MUST use when writing DuckDB queries.
|
|
74438
|
+
---
|
|
74439
|
+
|
|
74440
|
+
## CLI Commands
|
|
74441
|
+
|
|
74442
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74443
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74444
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74445
|
+
|
|
74446
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74447
|
+
|
|
74448
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74449
|
+
|
|
74450
|
+
# DuckDB
|
|
74451
|
+
|
|
74452
|
+
Arguments are defined with comments and used with \`$name\` syntax:
|
|
74453
|
+
|
|
74454
|
+
\`\`\`sql
|
|
74455
|
+
-- $name (text) = default
|
|
74456
|
+
-- $age (integer)
|
|
74457
|
+
SELECT * FROM users WHERE name = $name AND age > $age;
|
|
74458
|
+
\`\`\`
|
|
74459
|
+
|
|
74460
|
+
## Ducklake Integration
|
|
74461
|
+
|
|
74462
|
+
Attach Ducklake for data lake operations:
|
|
74463
|
+
|
|
74464
|
+
\`\`\`sql
|
|
74465
|
+
-- Main ducklake
|
|
74466
|
+
ATTACH 'ducklake' AS dl;
|
|
74467
|
+
|
|
74468
|
+
-- Named ducklake
|
|
74469
|
+
ATTACH 'ducklake://my_lake' AS dl;
|
|
74470
|
+
|
|
74471
|
+
-- Then query
|
|
74472
|
+
SELECT * FROM dl.schema.table;
|
|
74473
|
+
\`\`\`
|
|
74474
|
+
|
|
74475
|
+
## External Database Connections
|
|
74476
|
+
|
|
74477
|
+
Connect to external databases using resources:
|
|
74478
|
+
|
|
74479
|
+
\`\`\`sql
|
|
74480
|
+
ATTACH '$res:path/to/resource' AS db (TYPE postgres);
|
|
74481
|
+
SELECT * FROM db.schema.table;
|
|
74482
|
+
\`\`\`
|
|
74483
|
+
|
|
74484
|
+
## S3 File Operations
|
|
74485
|
+
|
|
74486
|
+
Read files from S3 storage:
|
|
74487
|
+
|
|
74488
|
+
\`\`\`sql
|
|
74489
|
+
-- Default storage
|
|
74490
|
+
SELECT * FROM read_csv('s3:///path/to/file.csv');
|
|
74491
|
+
|
|
74492
|
+
-- Named storage
|
|
74493
|
+
SELECT * FROM read_csv('s3://storage_name/path/to/file.csv');
|
|
74494
|
+
|
|
74495
|
+
-- Parquet files
|
|
74496
|
+
SELECT * FROM read_parquet('s3:///path/to/file.parquet');
|
|
74497
|
+
|
|
74498
|
+
-- JSON files
|
|
74499
|
+
SELECT * FROM read_json('s3:///path/to/file.json');
|
|
74500
|
+
\`\`\`
|
|
74501
|
+
`,
|
|
74502
|
+
"write-script-go": `---
|
|
74503
|
+
name: write-script-go
|
|
74504
|
+
description: MUST use when writing Go scripts.
|
|
74505
|
+
---
|
|
74506
|
+
|
|
74507
|
+
## CLI Commands
|
|
74508
|
+
|
|
74509
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74510
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74511
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74512
|
+
|
|
74513
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74514
|
+
|
|
74515
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74516
|
+
|
|
74517
|
+
# Go
|
|
74518
|
+
|
|
74519
|
+
## Structure
|
|
74520
|
+
|
|
74521
|
+
The file package must be \`inner\` and export a function called \`main\`:
|
|
74522
|
+
|
|
74523
|
+
\`\`\`go
|
|
74524
|
+
package inner
|
|
74525
|
+
|
|
74526
|
+
func main(param1 string, param2 int) (map[string]interface{}, error) {
|
|
74527
|
+
return map[string]interface{}{
|
|
74528
|
+
"result": param1,
|
|
74529
|
+
"count": param2,
|
|
74530
|
+
}, nil
|
|
74531
|
+
}
|
|
74532
|
+
\`\`\`
|
|
74533
|
+
|
|
74534
|
+
**Important:**
|
|
74535
|
+
- Package must be \`inner\`
|
|
74536
|
+
- Return type must be \`({return_type}, error)\`
|
|
74537
|
+
- Function name is \`main\` (lowercase)
|
|
74538
|
+
|
|
74539
|
+
## Return Types
|
|
74540
|
+
|
|
74541
|
+
The return type can be any Go type that can be serialized to JSON:
|
|
74542
|
+
|
|
74543
|
+
\`\`\`go
|
|
74544
|
+
package inner
|
|
74545
|
+
|
|
74546
|
+
type Result struct {
|
|
74547
|
+
Name string \`json:"name"\`
|
|
74548
|
+
Count int \`json:"count"\`
|
|
74549
|
+
}
|
|
74550
|
+
|
|
74551
|
+
func main(name string, count int) (Result, error) {
|
|
74552
|
+
return Result{
|
|
74553
|
+
Name: name,
|
|
74554
|
+
Count: count,
|
|
74555
|
+
}, nil
|
|
74556
|
+
}
|
|
74557
|
+
\`\`\`
|
|
74558
|
+
|
|
74559
|
+
## Error Handling
|
|
74560
|
+
|
|
74561
|
+
Return errors as the second return value:
|
|
74562
|
+
|
|
74563
|
+
\`\`\`go
|
|
74564
|
+
package inner
|
|
74565
|
+
|
|
74566
|
+
import "errors"
|
|
74567
|
+
|
|
74568
|
+
func main(value int) (string, error) {
|
|
74569
|
+
if value < 0 {
|
|
74570
|
+
return "", errors.New("value must be positive")
|
|
74571
|
+
}
|
|
74572
|
+
return "success", nil
|
|
74573
|
+
}
|
|
74574
|
+
\`\`\`
|
|
74575
|
+
`,
|
|
74576
|
+
"write-script-graphql": `---
|
|
74577
|
+
name: write-script-graphql
|
|
74578
|
+
description: MUST use when writing GraphQL queries.
|
|
74579
|
+
---
|
|
74580
|
+
|
|
74581
|
+
## CLI Commands
|
|
74582
|
+
|
|
74583
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74584
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74585
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74586
|
+
|
|
74587
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74588
|
+
|
|
74589
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74590
|
+
|
|
74591
|
+
# GraphQL
|
|
74592
|
+
|
|
74593
|
+
## Structure
|
|
74594
|
+
|
|
74595
|
+
Write GraphQL queries or mutations. Arguments can be added as query parameters:
|
|
74596
|
+
|
|
74597
|
+
\`\`\`graphql
|
|
74598
|
+
query GetUser($id: ID!) {
|
|
74599
|
+
user(id: $id) {
|
|
74600
|
+
id
|
|
74601
|
+
name
|
|
74602
|
+
email
|
|
74603
|
+
}
|
|
74604
|
+
}
|
|
74605
|
+
\`\`\`
|
|
74606
|
+
|
|
74607
|
+
## Variables
|
|
74608
|
+
|
|
74609
|
+
Variables are passed as script arguments and automatically bound to the query:
|
|
74610
|
+
|
|
74611
|
+
\`\`\`graphql
|
|
74612
|
+
query SearchProducts($query: String!, $limit: Int = 10) {
|
|
74613
|
+
products(search: $query, first: $limit) {
|
|
74614
|
+
edges {
|
|
74615
|
+
node {
|
|
74616
|
+
id
|
|
74617
|
+
name
|
|
74618
|
+
price
|
|
74619
|
+
}
|
|
74620
|
+
}
|
|
74621
|
+
}
|
|
74622
|
+
}
|
|
74623
|
+
\`\`\`
|
|
74624
|
+
|
|
74625
|
+
## Mutations
|
|
74626
|
+
|
|
74627
|
+
\`\`\`graphql
|
|
74628
|
+
mutation CreateUser($input: CreateUserInput!) {
|
|
74629
|
+
createUser(input: $input) {
|
|
74630
|
+
id
|
|
74631
|
+
name
|
|
74632
|
+
createdAt
|
|
74633
|
+
}
|
|
74634
|
+
}
|
|
74635
|
+
\`\`\`
|
|
74636
|
+
`,
|
|
74637
|
+
"write-script-java": `---
|
|
74638
|
+
name: write-script-java
|
|
74639
|
+
description: MUST use when writing Java scripts.
|
|
74640
|
+
---
|
|
74641
|
+
|
|
74642
|
+
## CLI Commands
|
|
74643
|
+
|
|
74644
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74645
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74646
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74647
|
+
|
|
74648
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74649
|
+
|
|
74650
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74651
|
+
|
|
74652
|
+
# Java
|
|
74653
|
+
|
|
74654
|
+
The script must contain a Main public class with a \`public static main()\` method:
|
|
74655
|
+
|
|
74656
|
+
\`\`\`java
|
|
74657
|
+
public class Main {
|
|
74658
|
+
public static Object main(String name, int count) {
|
|
74659
|
+
java.util.Map<String, Object> result = new java.util.HashMap<>();
|
|
74660
|
+
result.put("name", name);
|
|
74661
|
+
result.put("count", count);
|
|
74662
|
+
return result;
|
|
74663
|
+
}
|
|
74664
|
+
}
|
|
74665
|
+
\`\`\`
|
|
74666
|
+
|
|
74667
|
+
**Important:**
|
|
74668
|
+
- Class must be named \`Main\`
|
|
74669
|
+
- Method must be \`public static Object main(...)\`
|
|
74670
|
+
- Return type is \`Object\` or \`void\`
|
|
74671
|
+
|
|
74672
|
+
## Maven Dependencies
|
|
74673
|
+
|
|
74674
|
+
Add dependencies using comments at the top:
|
|
74675
|
+
|
|
74676
|
+
\`\`\`java
|
|
74677
|
+
//requirements:
|
|
74678
|
+
//com.google.code.gson:gson:2.10.1
|
|
74679
|
+
//org.apache.httpcomponents:httpclient:4.5.14
|
|
74680
|
+
|
|
74681
|
+
import com.google.gson.Gson;
|
|
74682
|
+
|
|
74683
|
+
public class Main {
|
|
74684
|
+
public static Object main(String input) {
|
|
74685
|
+
Gson gson = new Gson();
|
|
74686
|
+
return gson.fromJson(input, Object.class);
|
|
74687
|
+
}
|
|
74688
|
+
}
|
|
74689
|
+
\`\`\`
|
|
74690
|
+
`,
|
|
74691
|
+
"write-script-mssql": `---
|
|
74692
|
+
name: write-script-mssql
|
|
74693
|
+
description: MUST use when writing MS SQL Server queries.
|
|
74694
|
+
---
|
|
74695
|
+
|
|
74696
|
+
## CLI Commands
|
|
74697
|
+
|
|
74698
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74699
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74700
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74701
|
+
|
|
74702
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74703
|
+
|
|
74704
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74705
|
+
|
|
74706
|
+
# Microsoft SQL Server (MSSQL)
|
|
74707
|
+
|
|
74708
|
+
Arguments use \`@P1\`, \`@P2\`, etc.
|
|
74709
|
+
|
|
74710
|
+
Name the parameters by adding comments before the statement:
|
|
74711
|
+
|
|
74712
|
+
\`\`\`sql
|
|
74713
|
+
-- @P1 name1 (varchar)
|
|
74714
|
+
-- @P2 name2 (int) = 0
|
|
74715
|
+
SELECT * FROM users WHERE name = @P1 AND age > @P2;
|
|
74716
|
+
\`\`\`
|
|
74717
|
+
`,
|
|
74718
|
+
"write-script-mysql": `---
|
|
74719
|
+
name: write-script-mysql
|
|
74720
|
+
description: MUST use when writing MySQL queries.
|
|
74721
|
+
---
|
|
74722
|
+
|
|
74723
|
+
## CLI Commands
|
|
74724
|
+
|
|
74725
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74726
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74727
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74728
|
+
|
|
74729
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74730
|
+
|
|
74731
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74732
|
+
|
|
74733
|
+
# MySQL
|
|
74734
|
+
|
|
74735
|
+
Arguments use \`?\` placeholders.
|
|
74736
|
+
|
|
74737
|
+
Name the parameters by adding comments before the statement:
|
|
74738
|
+
|
|
74739
|
+
\`\`\`sql
|
|
74740
|
+
-- ? name1 (text)
|
|
74741
|
+
-- ? name2 (int) = 0
|
|
74742
|
+
SELECT * FROM users WHERE name = ? AND age > ?;
|
|
74743
|
+
\`\`\`
|
|
74744
|
+
`,
|
|
74745
|
+
"write-script-nativets": `---
|
|
74746
|
+
name: write-script-nativets
|
|
74747
|
+
description: MUST use when writing Native TypeScript scripts.
|
|
74748
|
+
---
|
|
74749
|
+
|
|
74750
|
+
## CLI Commands
|
|
74751
|
+
|
|
74752
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74753
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74754
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
74755
|
+
|
|
74756
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
74757
|
+
|
|
74758
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74759
|
+
|
|
74760
|
+
# TypeScript (Native)
|
|
74761
|
+
|
|
74762
|
+
Native TypeScript execution with fetch only - no external imports allowed.
|
|
74763
|
+
|
|
74764
|
+
## Structure
|
|
74765
|
+
|
|
74766
|
+
Export a single **async** function called \`main\`:
|
|
74767
|
+
|
|
74768
|
+
\`\`\`typescript
|
|
74769
|
+
export async function main(param1: string, param2: number) {
|
|
74770
|
+
// Your code here
|
|
74771
|
+
return { result: param1, count: param2 };
|
|
74772
|
+
}
|
|
74773
|
+
\`\`\`
|
|
74774
|
+
|
|
74775
|
+
Do not call the main function.
|
|
74776
|
+
|
|
74777
|
+
## Resource Types
|
|
74778
|
+
|
|
74779
|
+
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
|
|
74780
|
+
|
|
74781
|
+
Use the \`RT\` namespace for resource types:
|
|
74782
|
+
|
|
74783
|
+
\`\`\`typescript
|
|
74784
|
+
export async function main(stripe: RT.Stripe) {
|
|
74785
|
+
// stripe contains API key and config from the resource
|
|
74786
|
+
}
|
|
74787
|
+
\`\`\`
|
|
74788
|
+
|
|
74789
|
+
Only use resource types if you need them to satisfy the instructions. Always use the RT namespace.
|
|
74790
|
+
|
|
74791
|
+
Before using a resource type, check the \`rt.d.ts\` file in the project root to see all available resource types and their fields. This file is generated by \`wmill resource-type generate-namespace\`.
|
|
74792
|
+
|
|
74793
|
+
## Imports
|
|
74794
|
+
|
|
74795
|
+
**No imports allowed.** Use the globally available \`fetch\` function:
|
|
74796
|
+
|
|
74797
|
+
\`\`\`typescript
|
|
74798
|
+
export async function main(url: string) {
|
|
74799
|
+
const response = await fetch(url);
|
|
74800
|
+
return await response.json();
|
|
74801
|
+
}
|
|
74802
|
+
\`\`\`
|
|
74803
|
+
|
|
74804
|
+
## Windmill Client
|
|
74805
|
+
|
|
74806
|
+
The windmill client is not available in native TypeScript mode. Use fetch to call APIs directly.
|
|
74807
|
+
|
|
74808
|
+
## Preprocessor Scripts
|
|
74809
|
+
|
|
74810
|
+
For preprocessor scripts, the function should be named \`preprocessor\` and receives an \`event\` parameter:
|
|
74811
|
+
|
|
74812
|
+
\`\`\`typescript
|
|
74813
|
+
type Event = {
|
|
74814
|
+
kind:
|
|
74815
|
+
| "webhook"
|
|
74816
|
+
| "http"
|
|
74817
|
+
| "websocket"
|
|
74818
|
+
| "kafka"
|
|
74819
|
+
| "email"
|
|
74820
|
+
| "nats"
|
|
74821
|
+
| "postgres"
|
|
74822
|
+
| "sqs"
|
|
74823
|
+
| "mqtt"
|
|
74824
|
+
| "gcp";
|
|
74825
|
+
body: any;
|
|
74826
|
+
headers: Record<string, string>;
|
|
74827
|
+
query: Record<string, string>;
|
|
74828
|
+
};
|
|
74829
|
+
|
|
74830
|
+
export async function preprocessor(event: Event) {
|
|
74831
|
+
return {
|
|
74832
|
+
param1: event.body.field1,
|
|
74833
|
+
param2: event.query.id
|
|
74834
|
+
};
|
|
74835
|
+
}
|
|
74836
|
+
\`\`\`
|
|
74837
|
+
|
|
74838
|
+
|
|
74839
|
+
# TypeScript SDK (windmill-client)
|
|
74840
|
+
|
|
74841
|
+
Import: import * as wmill from 'windmill-client'
|
|
74147
74842
|
|
|
74148
74843
|
/**
|
|
74149
74844
|
* Initialize the Windmill client with authentication token and base URL
|
|
@@ -74637,30 +75332,144 @@ waitForApproval(options?: { timeout?: number; form?: object; }): PromiseLike<{ v
|
|
|
74637
75332
|
* const results = await parallel(items, process, { concurrency: 5 });
|
|
74638
75333
|
*/
|
|
74639
75334
|
async parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
|
|
75335
|
+
|
|
75336
|
+
/**
|
|
75337
|
+
* Commit Kafka offsets for a trigger with auto_commit disabled.
|
|
75338
|
+
* @param triggerPath - Path to the Kafka trigger (from event.wm_trigger.trigger_path)
|
|
75339
|
+
* @param topic - Kafka topic name (from event.topic)
|
|
75340
|
+
* @param partition - Partition number (from event.partition)
|
|
75341
|
+
* @param offset - Message offset to commit (from event.offset)
|
|
75342
|
+
*/
|
|
75343
|
+
async commitKafkaOffsets(triggerPath: string, topic: string, partition: number, offset: number,): Promise<void>
|
|
75344
|
+
|
|
75345
|
+
/**
|
|
75346
|
+
* Create a SQL template function for PostgreSQL/datatable queries
|
|
75347
|
+
* @param name - Database/datatable name (default: "main")
|
|
75348
|
+
* @returns SQL template function for building parameterized queries
|
|
75349
|
+
* @example
|
|
75350
|
+
* let sql = wmill.datatable()
|
|
75351
|
+
* let name = 'Robin'
|
|
75352
|
+
* let age = 21
|
|
75353
|
+
* await sql\`
|
|
75354
|
+
* SELECT * FROM friends
|
|
75355
|
+
* WHERE name = \${name} AND age = \${age}::int
|
|
75356
|
+
* \`.fetch()
|
|
75357
|
+
*/
|
|
75358
|
+
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
75359
|
+
|
|
75360
|
+
/**
|
|
75361
|
+
* Create a SQL template function for DuckDB/ducklake queries
|
|
75362
|
+
* @param name - DuckDB database name (default: "main")
|
|
75363
|
+
* @returns SQL template function for building parameterized queries
|
|
75364
|
+
* @example
|
|
75365
|
+
* let sql = wmill.ducklake()
|
|
75366
|
+
* let name = 'Robin'
|
|
75367
|
+
* let age = 21
|
|
75368
|
+
* await sql\`
|
|
75369
|
+
* SELECT * FROM friends
|
|
75370
|
+
* WHERE name = \${name} AND age = \${age}
|
|
75371
|
+
* \`.fetch()
|
|
75372
|
+
*/
|
|
75373
|
+
ducklake(name: string = "main"): SqlTemplateFunction
|
|
75374
|
+
`,
|
|
75375
|
+
"write-script-php": `---
|
|
75376
|
+
name: write-script-php
|
|
75377
|
+
description: MUST use when writing PHP scripts.
|
|
75378
|
+
---
|
|
75379
|
+
|
|
75380
|
+
## CLI Commands
|
|
75381
|
+
|
|
75382
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
75383
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
75384
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
75385
|
+
|
|
75386
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
75387
|
+
|
|
75388
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
75389
|
+
|
|
75390
|
+
# PHP
|
|
75391
|
+
|
|
75392
|
+
## Structure
|
|
75393
|
+
|
|
75394
|
+
The script must start with \`<?php\` and contain at least one function called \`main\`:
|
|
75395
|
+
|
|
75396
|
+
\`\`\`php
|
|
75397
|
+
<?php
|
|
75398
|
+
|
|
75399
|
+
function main(string $param1, int $param2) {
|
|
75400
|
+
return ["result" => $param1, "count" => $param2];
|
|
75401
|
+
}
|
|
75402
|
+
\`\`\`
|
|
75403
|
+
|
|
75404
|
+
## Resource Types
|
|
75405
|
+
|
|
75406
|
+
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
|
|
75407
|
+
|
|
75408
|
+
You need to **redefine** the type of the resources that are needed before the main function. Always check if the class already exists using \`class_exists\`:
|
|
75409
|
+
|
|
75410
|
+
\`\`\`php
|
|
75411
|
+
<?php
|
|
75412
|
+
|
|
75413
|
+
if (!class_exists('Postgresql')) {
|
|
75414
|
+
class Postgresql {
|
|
75415
|
+
public string $host;
|
|
75416
|
+
public int $port;
|
|
75417
|
+
public string $user;
|
|
75418
|
+
public string $password;
|
|
75419
|
+
public string $dbname;
|
|
75420
|
+
}
|
|
75421
|
+
}
|
|
75422
|
+
|
|
75423
|
+
function main(Postgresql $db) {
|
|
75424
|
+
// $db contains the database connection details
|
|
75425
|
+
}
|
|
75426
|
+
\`\`\`
|
|
75427
|
+
|
|
75428
|
+
The resource type name has to be exactly as specified.
|
|
75429
|
+
|
|
75430
|
+
## Library Dependencies
|
|
75431
|
+
|
|
75432
|
+
Specify library dependencies as comments before the main function:
|
|
75433
|
+
|
|
75434
|
+
\`\`\`php
|
|
75435
|
+
<?php
|
|
75436
|
+
|
|
75437
|
+
// require:
|
|
75438
|
+
// guzzlehttp/guzzle
|
|
75439
|
+
// stripe/stripe-php@^10.0
|
|
75440
|
+
|
|
75441
|
+
function main() {
|
|
75442
|
+
// Libraries are available
|
|
75443
|
+
}
|
|
75444
|
+
\`\`\`
|
|
75445
|
+
|
|
75446
|
+
One dependency per line. No need to require autoload, it is already done.
|
|
74640
75447
|
`,
|
|
74641
|
-
"write-script-
|
|
74642
|
-
name: write-script-
|
|
74643
|
-
description: MUST use when writing
|
|
75448
|
+
"write-script-postgresql": `---
|
|
75449
|
+
name: write-script-postgresql
|
|
75450
|
+
description: MUST use when writing PostgreSQL queries.
|
|
74644
75451
|
---
|
|
74645
75452
|
|
|
74646
75453
|
## CLI Commands
|
|
74647
75454
|
|
|
74648
|
-
Place scripts in a folder. After writing, run:
|
|
75455
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74649
75456
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74650
75457
|
- \`wmill sync push\` - Deploy to Windmill
|
|
74651
75458
|
|
|
75459
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
75460
|
+
|
|
74652
75461
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74653
75462
|
|
|
74654
|
-
#
|
|
75463
|
+
# PostgreSQL
|
|
74655
75464
|
|
|
74656
|
-
Arguments
|
|
75465
|
+
Arguments are obtained directly in the statement with \`$1::{type}\`, \`$2::{type}\`, etc.
|
|
74657
75466
|
|
|
74658
|
-
Name the parameters by adding comments
|
|
75467
|
+
Name the parameters by adding comments at the beginning of the script (without specifying the type):
|
|
74659
75468
|
|
|
74660
75469
|
\`\`\`sql
|
|
74661
|
-
--
|
|
74662
|
-
--
|
|
74663
|
-
SELECT * FROM users WHERE name =
|
|
75470
|
+
-- $1 name1
|
|
75471
|
+
-- $2 name2 = default_value
|
|
75472
|
+
SELECT * FROM users WHERE name = $1::TEXT AND age > $2::INT;
|
|
74664
75473
|
\`\`\`
|
|
74665
75474
|
`,
|
|
74666
75475
|
"write-script-powershell": `---
|
|
@@ -74670,10 +75479,12 @@ description: MUST use when writing PowerShell scripts.
|
|
|
74670
75479
|
|
|
74671
75480
|
## CLI Commands
|
|
74672
75481
|
|
|
74673
|
-
Place scripts in a folder. After writing, run:
|
|
75482
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74674
75483
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74675
75484
|
- \`wmill sync push\` - Deploy to Windmill
|
|
74676
75485
|
|
|
75486
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
75487
|
+
|
|
74677
75488
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74678
75489
|
|
|
74679
75490
|
# PowerShell
|
|
@@ -74731,31 +75542,6 @@ $result = @{
|
|
|
74731
75542
|
|
|
74732
75543
|
$result
|
|
74733
75544
|
\`\`\`
|
|
74734
|
-
`,
|
|
74735
|
-
"write-script-snowflake": `---
|
|
74736
|
-
name: write-script-snowflake
|
|
74737
|
-
description: MUST use when writing Snowflake queries.
|
|
74738
|
-
---
|
|
74739
|
-
|
|
74740
|
-
## CLI Commands
|
|
74741
|
-
|
|
74742
|
-
Place scripts in a folder. After writing, run:
|
|
74743
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74744
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
74745
|
-
|
|
74746
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74747
|
-
|
|
74748
|
-
# Snowflake
|
|
74749
|
-
|
|
74750
|
-
Arguments use \`?\` placeholders.
|
|
74751
|
-
|
|
74752
|
-
Name the parameters by adding comments before the statement:
|
|
74753
|
-
|
|
74754
|
-
\`\`\`sql
|
|
74755
|
-
-- ? name1 (text)
|
|
74756
|
-
-- ? name2 (number) = 0
|
|
74757
|
-
SELECT * FROM users WHERE name = ? AND age > ?;
|
|
74758
|
-
\`\`\`
|
|
74759
75545
|
`,
|
|
74760
75546
|
"write-script-python3": `---
|
|
74761
75547
|
name: write-script-python3
|
|
@@ -74764,10 +75550,12 @@ description: MUST use when writing Python scripts.
|
|
|
74764
75550
|
|
|
74765
75551
|
## CLI Commands
|
|
74766
75552
|
|
|
74767
|
-
Place scripts in a folder. After writing, run:
|
|
75553
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
74768
75554
|
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
74769
75555
|
- \`wmill sync push\` - Deploy to Windmill
|
|
74770
75556
|
|
|
75557
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
75558
|
+
|
|
74771
75559
|
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
74772
75560
|
|
|
74773
75561
|
# Python
|
|
@@ -75508,806 +76296,186 @@ def task_script(path: str, timeout: Optional[int] = None, tag: Optional[str] = N
|
|
|
75508
76296
|
#
|
|
75509
76297
|
# @workflow
|
|
75510
76298
|
# async def main():
|
|
75511
|
-
# result = await pipeline(input=data)
|
|
75512
|
-
def task_flow(path: str, timeout: Optional[int] = None, tag: Optional[str] = None, cache_ttl: Optional[int] = None, priority: Optional[int] = None, concurrency_limit: Optional[int] = None, concurrency_key: Optional[str] = None, concurrency_time_window_s: Optional[int] = None)
|
|
75513
|
-
|
|
75514
|
-
# Decorator marking an async function as a workflow-as-code entry point.
|
|
75515
|
-
#
|
|
75516
|
-
# The function must be **deterministic**: given the same inputs it must call
|
|
75517
|
-
# tasks in the same order on every replay. Branching on task results is fine
|
|
75518
|
-
# (results are replayed from checkpoint), but branching on external state
|
|
75519
|
-
# (current time, random values, external API calls) must use \`\`step()\`\` to
|
|
75520
|
-
# checkpoint the value so replays see the same result.
|
|
75521
|
-
def workflow(func)
|
|
75522
|
-
|
|
75523
|
-
# Execute \`\`fn\`\` inline and checkpoint the result.
|
|
75524
|
-
#
|
|
75525
|
-
# On replay the cached value is returned without re-executing \`\`fn\`\`.
|
|
75526
|
-
# Use for lightweight deterministic operations (timestamps, random IDs,
|
|
75527
|
-
# config reads) that should not incur the overhead of a child job.
|
|
75528
|
-
async def step(name: str, fn)
|
|
75529
|
-
|
|
75530
|
-
# Server-side sleep — suspend the workflow for the given duration without holding a worker.
|
|
75531
|
-
#
|
|
75532
|
-
# Inside a @workflow, the parent job suspends and auto-resumes after \`\`seconds\`\`.
|
|
75533
|
-
# Outside a workflow, falls back to \`\`asyncio.sleep\`\`.
|
|
75534
|
-
async def sleep(seconds: int)
|
|
75535
|
-
|
|
75536
|
-
# Suspend the workflow and wait for an external approval.
|
|
75537
|
-
#
|
|
75538
|
-
# Use \`\`get_resume_urls()\`\` (wrapped in \`\`step()\`\`) to obtain
|
|
75539
|
-
# resume/cancel/approval URLs before calling this function.
|
|
75540
|
-
#
|
|
75541
|
-
# Returns a dict with \`\`value\`\` (form data), \`\`approver\`\`, and \`\`approved\`\`.
|
|
75542
|
-
#
|
|
75543
|
-
# Example::
|
|
75544
|
-
#
|
|
75545
|
-
# urls = await step("urls", lambda: get_resume_urls())
|
|
75546
|
-
# await step("notify", lambda: send_email(urls["approvalPage"]))
|
|
75547
|
-
# result = await wait_for_approval(timeout=3600)
|
|
75548
|
-
async def wait_for_approval(timeout: int = 1800, form: dict | None = None) -> dict
|
|
75549
|
-
|
|
75550
|
-
# Process items in parallel with optional concurrency control.
|
|
75551
|
-
#
|
|
75552
|
-
# Each item is processed by calling \`\`fn(item)\`\`, which should be a @task.
|
|
75553
|
-
# Items are dispatched in batches of \`\`concurrency\`\` (default: all at once).
|
|
75554
|
-
#
|
|
75555
|
-
# Example::
|
|
75556
|
-
#
|
|
75557
|
-
# @task
|
|
75558
|
-
# async def process(item: str):
|
|
75559
|
-
# ...
|
|
75560
|
-
#
|
|
75561
|
-
# results = await parallel(items, process, concurrency=5)
|
|
75562
|
-
async def parallel(items, fn, concurrency: Optional[int] = None)
|
|
75563
|
-
|
|
75564
|
-
`,
|
|
75565
|
-
"write-script-duckdb": `---
|
|
75566
|
-
name: write-script-duckdb
|
|
75567
|
-
description: MUST use when writing DuckDB queries.
|
|
75568
|
-
---
|
|
75569
|
-
|
|
75570
|
-
## CLI Commands
|
|
75571
|
-
|
|
75572
|
-
Place scripts in a folder. After writing, run:
|
|
75573
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
75574
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
75575
|
-
|
|
75576
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
75577
|
-
|
|
75578
|
-
# DuckDB
|
|
75579
|
-
|
|
75580
|
-
Arguments are defined with comments and used with \`$name\` syntax:
|
|
75581
|
-
|
|
75582
|
-
\`\`\`sql
|
|
75583
|
-
-- $name (text) = default
|
|
75584
|
-
-- $age (integer)
|
|
75585
|
-
SELECT * FROM users WHERE name = $name AND age > $age;
|
|
75586
|
-
\`\`\`
|
|
75587
|
-
|
|
75588
|
-
## Ducklake Integration
|
|
75589
|
-
|
|
75590
|
-
Attach Ducklake for data lake operations:
|
|
75591
|
-
|
|
75592
|
-
\`\`\`sql
|
|
75593
|
-
-- Main ducklake
|
|
75594
|
-
ATTACH 'ducklake' AS dl;
|
|
75595
|
-
|
|
75596
|
-
-- Named ducklake
|
|
75597
|
-
ATTACH 'ducklake://my_lake' AS dl;
|
|
75598
|
-
|
|
75599
|
-
-- Then query
|
|
75600
|
-
SELECT * FROM dl.schema.table;
|
|
75601
|
-
\`\`\`
|
|
75602
|
-
|
|
75603
|
-
## External Database Connections
|
|
75604
|
-
|
|
75605
|
-
Connect to external databases using resources:
|
|
75606
|
-
|
|
75607
|
-
\`\`\`sql
|
|
75608
|
-
ATTACH '$res:path/to/resource' AS db (TYPE postgres);
|
|
75609
|
-
SELECT * FROM db.schema.table;
|
|
75610
|
-
\`\`\`
|
|
75611
|
-
|
|
75612
|
-
## S3 File Operations
|
|
75613
|
-
|
|
75614
|
-
Read files from S3 storage:
|
|
75615
|
-
|
|
75616
|
-
\`\`\`sql
|
|
75617
|
-
-- Default storage
|
|
75618
|
-
SELECT * FROM read_csv('s3:///path/to/file.csv');
|
|
75619
|
-
|
|
75620
|
-
-- Named storage
|
|
75621
|
-
SELECT * FROM read_csv('s3://storage_name/path/to/file.csv');
|
|
75622
|
-
|
|
75623
|
-
-- Parquet files
|
|
75624
|
-
SELECT * FROM read_parquet('s3:///path/to/file.parquet');
|
|
75625
|
-
|
|
75626
|
-
-- JSON files
|
|
75627
|
-
SELECT * FROM read_json('s3:///path/to/file.json');
|
|
75628
|
-
\`\`\`
|
|
75629
|
-
`,
|
|
75630
|
-
"write-script-bash": `---
|
|
75631
|
-
name: write-script-bash
|
|
75632
|
-
description: MUST use when writing Bash scripts.
|
|
75633
|
-
---
|
|
75634
|
-
|
|
75635
|
-
## CLI Commands
|
|
75636
|
-
|
|
75637
|
-
Place scripts in a folder. After writing, run:
|
|
75638
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
75639
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
75640
|
-
|
|
75641
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
75642
|
-
|
|
75643
|
-
# Bash
|
|
75644
|
-
|
|
75645
|
-
## Structure
|
|
75646
|
-
|
|
75647
|
-
Do not include \`#!/bin/bash\`. Arguments are obtained as positional parameters:
|
|
75648
|
-
|
|
75649
|
-
\`\`\`bash
|
|
75650
|
-
# Get arguments
|
|
75651
|
-
var1="$1"
|
|
75652
|
-
var2="$2"
|
|
75653
|
-
|
|
75654
|
-
echo "Processing $var1 and $var2"
|
|
75655
|
-
|
|
75656
|
-
# Return JSON by echoing to stdout
|
|
75657
|
-
echo "{\\"result\\": \\"$var1\\", \\"count\\": $var2}"
|
|
75658
|
-
\`\`\`
|
|
75659
|
-
|
|
75660
|
-
**Important:**
|
|
75661
|
-
- Do not include shebang (\`#!/bin/bash\`)
|
|
75662
|
-
- Arguments are always strings
|
|
75663
|
-
- Access with \`$1\`, \`$2\`, etc.
|
|
75664
|
-
|
|
75665
|
-
## Output
|
|
75666
|
-
|
|
75667
|
-
The script output is captured as the result. For structured data, output valid JSON:
|
|
75668
|
-
|
|
75669
|
-
\`\`\`bash
|
|
75670
|
-
name="$1"
|
|
75671
|
-
count="$2"
|
|
75672
|
-
|
|
75673
|
-
# Output JSON result
|
|
75674
|
-
cat << EOF
|
|
75675
|
-
{
|
|
75676
|
-
"name": "$name",
|
|
75677
|
-
"count": $count,
|
|
75678
|
-
"timestamp": "$(date -Iseconds)"
|
|
75679
|
-
}
|
|
75680
|
-
EOF
|
|
75681
|
-
\`\`\`
|
|
75682
|
-
|
|
75683
|
-
## Environment Variables
|
|
75684
|
-
|
|
75685
|
-
Environment variables set in Windmill are available:
|
|
75686
|
-
|
|
75687
|
-
\`\`\`bash
|
|
75688
|
-
# Access environment variable
|
|
75689
|
-
echo "Workspace: $WM_WORKSPACE"
|
|
75690
|
-
echo "Job ID: $WM_JOB_ID"
|
|
75691
|
-
\`\`\`
|
|
75692
|
-
`,
|
|
75693
|
-
"write-script-nativets": `---
|
|
75694
|
-
name: write-script-nativets
|
|
75695
|
-
description: MUST use when writing Native TypeScript scripts.
|
|
75696
|
-
---
|
|
75697
|
-
|
|
75698
|
-
## CLI Commands
|
|
75699
|
-
|
|
75700
|
-
Place scripts in a folder. After writing, run:
|
|
75701
|
-
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
75702
|
-
- \`wmill sync push\` - Deploy to Windmill
|
|
75703
|
-
|
|
75704
|
-
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
75705
|
-
|
|
75706
|
-
# TypeScript (Native)
|
|
75707
|
-
|
|
75708
|
-
Native TypeScript execution with fetch only - no external imports allowed.
|
|
75709
|
-
|
|
75710
|
-
## Structure
|
|
75711
|
-
|
|
75712
|
-
Export a single **async** function called \`main\`:
|
|
75713
|
-
|
|
75714
|
-
\`\`\`typescript
|
|
75715
|
-
export async function main(param1: string, param2: number) {
|
|
75716
|
-
// Your code here
|
|
75717
|
-
return { result: param1, count: param2 };
|
|
75718
|
-
}
|
|
75719
|
-
\`\`\`
|
|
75720
|
-
|
|
75721
|
-
Do not call the main function.
|
|
75722
|
-
|
|
75723
|
-
## Resource Types
|
|
75724
|
-
|
|
75725
|
-
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
|
|
75726
|
-
|
|
75727
|
-
Use the \`RT\` namespace for resource types:
|
|
75728
|
-
|
|
75729
|
-
\`\`\`typescript
|
|
75730
|
-
export async function main(stripe: RT.Stripe) {
|
|
75731
|
-
// stripe contains API key and config from the resource
|
|
75732
|
-
}
|
|
75733
|
-
\`\`\`
|
|
75734
|
-
|
|
75735
|
-
Only use resource types if you need them to satisfy the instructions. Always use the RT namespace.
|
|
75736
|
-
|
|
75737
|
-
Before using a resource type, check the \`rt.d.ts\` file in the project root to see all available resource types and their fields. This file is generated by \`wmill resource-type generate-namespace\`.
|
|
75738
|
-
|
|
75739
|
-
## Imports
|
|
75740
|
-
|
|
75741
|
-
**No imports allowed.** Use the globally available \`fetch\` function:
|
|
75742
|
-
|
|
75743
|
-
\`\`\`typescript
|
|
75744
|
-
export async function main(url: string) {
|
|
75745
|
-
const response = await fetch(url);
|
|
75746
|
-
return await response.json();
|
|
75747
|
-
}
|
|
75748
|
-
\`\`\`
|
|
75749
|
-
|
|
75750
|
-
## Windmill Client
|
|
75751
|
-
|
|
75752
|
-
The windmill client is not available in native TypeScript mode. Use fetch to call APIs directly.
|
|
75753
|
-
|
|
75754
|
-
## Preprocessor Scripts
|
|
75755
|
-
|
|
75756
|
-
For preprocessor scripts, the function should be named \`preprocessor\` and receives an \`event\` parameter:
|
|
75757
|
-
|
|
75758
|
-
\`\`\`typescript
|
|
75759
|
-
type Event = {
|
|
75760
|
-
kind:
|
|
75761
|
-
| "webhook"
|
|
75762
|
-
| "http"
|
|
75763
|
-
| "websocket"
|
|
75764
|
-
| "kafka"
|
|
75765
|
-
| "email"
|
|
75766
|
-
| "nats"
|
|
75767
|
-
| "postgres"
|
|
75768
|
-
| "sqs"
|
|
75769
|
-
| "mqtt"
|
|
75770
|
-
| "gcp";
|
|
75771
|
-
body: any;
|
|
75772
|
-
headers: Record<string, string>;
|
|
75773
|
-
query: Record<string, string>;
|
|
75774
|
-
};
|
|
75775
|
-
|
|
75776
|
-
export async function preprocessor(event: Event) {
|
|
75777
|
-
return {
|
|
75778
|
-
param1: event.body.field1,
|
|
75779
|
-
param2: event.query.id
|
|
75780
|
-
};
|
|
75781
|
-
}
|
|
75782
|
-
\`\`\`
|
|
75783
|
-
|
|
75784
|
-
|
|
75785
|
-
# TypeScript SDK (windmill-client)
|
|
75786
|
-
|
|
75787
|
-
Import: import * as wmill from 'windmill-client'
|
|
75788
|
-
|
|
75789
|
-
/**
|
|
75790
|
-
* Create a SQL template function for PostgreSQL/datatable queries
|
|
75791
|
-
* @param name - Database/datatable name (default: "main")
|
|
75792
|
-
* @returns SQL template function for building parameterized queries
|
|
75793
|
-
* @example
|
|
75794
|
-
* let sql = wmill.datatable()
|
|
75795
|
-
* let name = 'Robin'
|
|
75796
|
-
* let age = 21
|
|
75797
|
-
* await sql\`
|
|
75798
|
-
* SELECT * FROM friends
|
|
75799
|
-
* WHERE name = \${name} AND age = \${age}::int
|
|
75800
|
-
* \`.fetch()
|
|
75801
|
-
*/
|
|
75802
|
-
datatable(name: string = "main"): DatatableSqlTemplateFunction
|
|
75803
|
-
|
|
75804
|
-
/**
|
|
75805
|
-
* Create a SQL template function for DuckDB/ducklake queries
|
|
75806
|
-
* @param name - DuckDB database name (default: "main")
|
|
75807
|
-
* @returns SQL template function for building parameterized queries
|
|
75808
|
-
* @example
|
|
75809
|
-
* let sql = wmill.ducklake()
|
|
75810
|
-
* let name = 'Robin'
|
|
75811
|
-
* let age = 21
|
|
75812
|
-
* await sql\`
|
|
75813
|
-
* SELECT * FROM friends
|
|
75814
|
-
* WHERE name = \${name} AND age = \${age}
|
|
75815
|
-
* \`.fetch()
|
|
75816
|
-
*/
|
|
75817
|
-
ducklake(name: string = "main"): SqlTemplateFunction
|
|
75818
|
-
|
|
75819
|
-
/**
|
|
75820
|
-
* Initialize the Windmill client with authentication token and base URL
|
|
75821
|
-
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
|
75822
|
-
* @param baseUrl - API base URL (defaults to BASE_INTERNAL_URL or BASE_URL env variable)
|
|
75823
|
-
*/
|
|
75824
|
-
setClient(token?: string, baseUrl?: string): void
|
|
75825
|
-
|
|
75826
|
-
/**
|
|
75827
|
-
* Create a client configuration from env variables
|
|
75828
|
-
* @returns client configuration
|
|
75829
|
-
*/
|
|
75830
|
-
getWorkspace(): string
|
|
75831
|
-
|
|
75832
|
-
/**
|
|
75833
|
-
* Get a resource value by path
|
|
75834
|
-
* @param path path of the resource, default to internal state path
|
|
75835
|
-
* @param undefinedIfEmpty if the resource does not exist, return undefined instead of throwing an error
|
|
75836
|
-
* @returns resource value
|
|
75837
|
-
*/
|
|
75838
|
-
async getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any>
|
|
75839
|
-
|
|
75840
|
-
/**
|
|
75841
|
-
* Get the true root job id
|
|
75842
|
-
* @param jobId job id to get the root job id from (default to current job)
|
|
75843
|
-
* @returns root job id
|
|
75844
|
-
*/
|
|
75845
|
-
async getRootJobId(jobId?: string): Promise<string>
|
|
75846
|
-
|
|
75847
|
-
/**
|
|
75848
|
-
* @deprecated Use runScriptByPath or runScriptByHash instead
|
|
75849
|
-
*/
|
|
75850
|
-
async runScript(path: string | null = null, hash_: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
75851
|
-
|
|
75852
|
-
/**
|
|
75853
|
-
* Run a script synchronously by its path and wait for the result
|
|
75854
|
-
* @param path - Script path in Windmill
|
|
75855
|
-
* @param args - Arguments to pass to the script
|
|
75856
|
-
* @param verbose - Enable verbose logging
|
|
75857
|
-
* @returns Script execution result
|
|
75858
|
-
*/
|
|
75859
|
-
async runScriptByPath(path: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
75860
|
-
|
|
75861
|
-
/**
|
|
75862
|
-
* Run a script synchronously by its hash and wait for the result
|
|
75863
|
-
* @param hash_ - Script hash in Windmill
|
|
75864
|
-
* @param args - Arguments to pass to the script
|
|
75865
|
-
* @param verbose - Enable verbose logging
|
|
75866
|
-
* @returns Script execution result
|
|
75867
|
-
*/
|
|
75868
|
-
async runScriptByHash(hash_: string, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
75869
|
-
|
|
75870
|
-
/**
|
|
75871
|
-
* Append a text to the result stream
|
|
75872
|
-
* @param text text to append to the result stream
|
|
75873
|
-
*/
|
|
75874
|
-
appendToResultStream(text: string): void
|
|
75875
|
-
|
|
75876
|
-
/**
|
|
75877
|
-
* Stream to the result stream
|
|
75878
|
-
* @param stream stream to stream to the result stream
|
|
75879
|
-
*/
|
|
75880
|
-
async streamResult(stream: AsyncIterable<string>): Promise<void>
|
|
75881
|
-
|
|
75882
|
-
/**
|
|
75883
|
-
* Run a flow synchronously by its path and wait for the result
|
|
75884
|
-
* @param path - Flow path in Windmill
|
|
75885
|
-
* @param args - Arguments to pass to the flow
|
|
75886
|
-
* @param verbose - Enable verbose logging
|
|
75887
|
-
* @returns Flow execution result
|
|
75888
|
-
*/
|
|
75889
|
-
async runFlow(path: string | null = null, args: Record<string, any> | null = null, verbose: boolean = false): Promise<any>
|
|
75890
|
-
|
|
75891
|
-
/**
|
|
75892
|
-
* Wait for a job to complete and return its result
|
|
75893
|
-
* @param jobId - ID of the job to wait for
|
|
75894
|
-
* @param verbose - Enable verbose logging
|
|
75895
|
-
* @returns Job result when completed
|
|
75896
|
-
*/
|
|
75897
|
-
async waitJob(jobId: string, verbose: boolean = false): Promise<any>
|
|
75898
|
-
|
|
75899
|
-
/**
|
|
75900
|
-
* Get the result of a completed job
|
|
75901
|
-
* @param jobId - ID of the completed job
|
|
75902
|
-
* @returns Job result
|
|
75903
|
-
*/
|
|
75904
|
-
async getResult(jobId: string): Promise<any>
|
|
75905
|
-
|
|
75906
|
-
/**
|
|
75907
|
-
* Get the result of a job if completed, or its current status
|
|
75908
|
-
* @param jobId - ID of the job
|
|
75909
|
-
* @returns Object with started, completed, success, and result properties
|
|
75910
|
-
*/
|
|
75911
|
-
async getResultMaybe(jobId: string): Promise<any>
|
|
75912
|
-
|
|
75913
|
-
/**
|
|
75914
|
-
* @deprecated Use runScriptByPathAsync or runScriptByHashAsync instead
|
|
75915
|
-
*/
|
|
75916
|
-
async runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null): Promise<string>
|
|
75917
|
-
|
|
75918
|
-
/**
|
|
75919
|
-
* Run a script asynchronously by its path
|
|
75920
|
-
* @param path - Script path in Windmill
|
|
75921
|
-
* @param args - Arguments to pass to the script
|
|
75922
|
-
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
75923
|
-
* @returns Job ID of the created job
|
|
75924
|
-
*/
|
|
75925
|
-
async runScriptByPathAsync(path: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
|
|
75926
|
-
|
|
75927
|
-
/**
|
|
75928
|
-
* Run a script asynchronously by its hash
|
|
75929
|
-
* @param hash_ - Script hash in Windmill
|
|
75930
|
-
* @param args - Arguments to pass to the script
|
|
75931
|
-
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
75932
|
-
* @returns Job ID of the created job
|
|
75933
|
-
*/
|
|
75934
|
-
async runScriptByHashAsync(hash_: string, args: Record<string, any> | null = null, scheduledInSeconds: number | null = null): Promise<string>
|
|
75935
|
-
|
|
75936
|
-
/**
|
|
75937
|
-
* Run a flow asynchronously by its path
|
|
75938
|
-
* @param path - Flow path in Windmill
|
|
75939
|
-
* @param args - Arguments to pass to the flow
|
|
75940
|
-
* @param scheduledInSeconds - Schedule execution for a future time (in seconds)
|
|
75941
|
-
* @param doNotTrackInParent - If false, tracks state in parent job (only use when fully awaiting the job)
|
|
75942
|
-
* @returns Job ID of the created job
|
|
75943
|
-
*/
|
|
75944
|
-
async runFlowAsync(path: string | null, args: Record<string, any> | null, scheduledInSeconds: number | null = null, // can only be set to false if this the job will be fully await and not concurrent with any other job // as otherwise the child flow and its own child will store their state in the parent job which will // lead to incorrectness and failures doNotTrackInParent: boolean = true): Promise<string>
|
|
75945
|
-
|
|
75946
|
-
/**
|
|
75947
|
-
* Resolve a resource value in case the default value was picked because the input payload was undefined
|
|
75948
|
-
* @param obj resource value or path of the resource under the format \`$res:path\`
|
|
75949
|
-
* @returns resource value
|
|
75950
|
-
*/
|
|
75951
|
-
async resolveDefaultResource(obj: any): Promise<any>
|
|
75952
|
-
|
|
75953
|
-
/**
|
|
75954
|
-
* Get the state file path from environment variables
|
|
75955
|
-
* @returns State path string
|
|
75956
|
-
*/
|
|
75957
|
-
getStatePath(): string
|
|
75958
|
-
|
|
75959
|
-
/**
|
|
75960
|
-
* Set a resource value by path
|
|
75961
|
-
* @param path path of the resource to set, default to state path
|
|
75962
|
-
* @param value new value of the resource to set
|
|
75963
|
-
* @param initializeToTypeIfNotExist if the resource does not exist, initialize it with this type
|
|
75964
|
-
*/
|
|
75965
|
-
async setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise<void>
|
|
75966
|
-
|
|
75967
|
-
/**
|
|
75968
|
-
* Set the state
|
|
75969
|
-
* @param state state to set
|
|
75970
|
-
* @deprecated use setState instead
|
|
75971
|
-
*/
|
|
75972
|
-
async setInternalState(state: any): Promise<void>
|
|
76299
|
+
# result = await pipeline(input=data)
|
|
76300
|
+
def task_flow(path: str, timeout: Optional[int] = None, tag: Optional[str] = None, cache_ttl: Optional[int] = None, priority: Optional[int] = None, concurrency_limit: Optional[int] = None, concurrency_key: Optional[str] = None, concurrency_time_window_s: Optional[int] = None)
|
|
75973
76301
|
|
|
75974
|
-
|
|
75975
|
-
|
|
75976
|
-
|
|
75977
|
-
|
|
75978
|
-
|
|
75979
|
-
|
|
76302
|
+
# Decorator marking an async function as a workflow-as-code entry point.
|
|
76303
|
+
#
|
|
76304
|
+
# The function must be **deterministic**: given the same inputs it must call
|
|
76305
|
+
# tasks in the same order on every replay. Branching on task results is fine
|
|
76306
|
+
# (results are replayed from checkpoint), but branching on external state
|
|
76307
|
+
# (current time, random values, external API calls) must use \`\`step()\`\` to
|
|
76308
|
+
# checkpoint the value so replays see the same result.
|
|
76309
|
+
def workflow(func)
|
|
75980
76310
|
|
|
75981
|
-
|
|
75982
|
-
|
|
75983
|
-
|
|
75984
|
-
|
|
75985
|
-
|
|
75986
|
-
|
|
75987
|
-
async setProgress(percent: number, jobId?: any): Promise<void>
|
|
76311
|
+
# Execute \`\`fn\`\` inline and checkpoint the result.
|
|
76312
|
+
#
|
|
76313
|
+
# On replay the cached value is returned without re-executing \`\`fn\`\`.
|
|
76314
|
+
# Use for lightweight deterministic operations (timestamps, random IDs,
|
|
76315
|
+
# config reads) that should not incur the overhead of a child job.
|
|
76316
|
+
async def step(name: str, fn)
|
|
75988
76317
|
|
|
75989
|
-
|
|
75990
|
-
|
|
75991
|
-
|
|
75992
|
-
|
|
75993
|
-
|
|
75994
|
-
async getProgress(jobId?: any): Promise<number | null>
|
|
76318
|
+
# Server-side sleep — suspend the workflow for the given duration without holding a worker.
|
|
76319
|
+
#
|
|
76320
|
+
# Inside a @workflow, the parent job suspends and auto-resumes after \`\`seconds\`\`.
|
|
76321
|
+
# Outside a workflow, falls back to \`\`asyncio.sleep\`\`.
|
|
76322
|
+
async def sleep(seconds: int)
|
|
75995
76323
|
|
|
75996
|
-
|
|
75997
|
-
|
|
75998
|
-
|
|
75999
|
-
|
|
76000
|
-
|
|
76001
|
-
|
|
76324
|
+
# Suspend the workflow and wait for an external approval.
|
|
76325
|
+
#
|
|
76326
|
+
# Use \`\`get_resume_urls()\`\` (wrapped in \`\`step()\`\`) to obtain
|
|
76327
|
+
# resume/cancel/approval URLs before calling this function.
|
|
76328
|
+
#
|
|
76329
|
+
# Returns a dict with \`\`value\`\` (form data), \`\`approver\`\`, and \`\`approved\`\`.
|
|
76330
|
+
#
|
|
76331
|
+
# Example::
|
|
76332
|
+
#
|
|
76333
|
+
# urls = await step("urls", lambda: get_resume_urls())
|
|
76334
|
+
# await step("notify", lambda: send_email(urls["approvalPage"]))
|
|
76335
|
+
# result = await wait_for_approval(timeout=3600)
|
|
76336
|
+
async def wait_for_approval(timeout: int = 1800, form: dict | None = None) -> dict
|
|
76002
76337
|
|
|
76003
|
-
|
|
76004
|
-
|
|
76005
|
-
|
|
76006
|
-
|
|
76007
|
-
|
|
76338
|
+
# Process items in parallel with optional concurrency control.
|
|
76339
|
+
#
|
|
76340
|
+
# Each item is processed by calling \`\`fn(item)\`\`, which should be a @task.
|
|
76341
|
+
# Items are dispatched in batches of \`\`concurrency\`\` (default: all at once).
|
|
76342
|
+
#
|
|
76343
|
+
# Example::
|
|
76344
|
+
#
|
|
76345
|
+
# @task
|
|
76346
|
+
# async def process(item: str):
|
|
76347
|
+
# ...
|
|
76348
|
+
#
|
|
76349
|
+
# results = await parallel(items, process, concurrency=5)
|
|
76350
|
+
async def parallel(items, fn, concurrency: Optional[int] = None)
|
|
76008
76351
|
|
|
76009
|
-
|
|
76010
|
-
|
|
76011
|
-
|
|
76012
|
-
|
|
76013
|
-
|
|
76352
|
+
# Commit Kafka offsets for a trigger with auto_commit disabled.
|
|
76353
|
+
#
|
|
76354
|
+
# Args:
|
|
76355
|
+
# trigger_path: Path to the Kafka trigger (from event['wm_trigger']['trigger_path'])
|
|
76356
|
+
# topic: Kafka topic name (from event['topic'])
|
|
76357
|
+
# partition: Partition number (from event['partition'])
|
|
76358
|
+
# offset: Message offset to commit (from event['offset'])
|
|
76359
|
+
def commit_kafka_offsets(trigger_path: str, topic: str, partition: int, offset: int) -> None
|
|
76014
76360
|
|
|
76015
|
-
|
|
76016
|
-
|
|
76017
|
-
|
|
76018
|
-
|
|
76019
|
-
|
|
76361
|
+
`,
|
|
76362
|
+
"write-script-rust": `---
|
|
76363
|
+
name: write-script-rust
|
|
76364
|
+
description: MUST use when writing Rust scripts.
|
|
76365
|
+
---
|
|
76020
76366
|
|
|
76021
|
-
|
|
76022
|
-
* Get a variable by path
|
|
76023
|
-
* @param path path of the variable
|
|
76024
|
-
* @returns variable value
|
|
76025
|
-
*/
|
|
76026
|
-
async getVariable(path: string): Promise<string>
|
|
76367
|
+
## CLI Commands
|
|
76027
76368
|
|
|
76028
|
-
|
|
76029
|
-
|
|
76030
|
-
|
|
76031
|
-
* @param value value of the variable
|
|
76032
|
-
* @param isSecretIfNotExist if the variable does not exist, create it as secret or not (default: false)
|
|
76033
|
-
* @param descriptionIfNotExist if the variable does not exist, create it with this description (default: "")
|
|
76034
|
-
*/
|
|
76035
|
-
async setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise<void>
|
|
76369
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
76370
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
76371
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
76036
76372
|
|
|
76037
|
-
|
|
76038
|
-
* Build a PostgreSQL connection URL from a database resource
|
|
76039
|
-
* @param path - Path to the database resource
|
|
76040
|
-
* @returns PostgreSQL connection URL string
|
|
76041
|
-
*/
|
|
76042
|
-
async databaseUrlFromResource(path: string): Promise<string>
|
|
76373
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
76043
76374
|
|
|
76044
|
-
|
|
76375
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
76045
76376
|
|
|
76046
|
-
|
|
76377
|
+
# Rust
|
|
76047
76378
|
|
|
76048
|
-
|
|
76049
|
-
* Get S3 client settings from a resource or workspace default
|
|
76050
|
-
* @param s3_resource_path - Path to S3 resource (uses workspace default if undefined)
|
|
76051
|
-
* @returns S3 client configuration settings
|
|
76052
|
-
*/
|
|
76053
|
-
async denoS3LightClientSettings(s3_resource_path: string | undefined): Promise<DenoS3LightClientSettings>
|
|
76379
|
+
## Structure
|
|
76054
76380
|
|
|
76055
|
-
|
|
76056
|
-
* Load the content of a file stored in S3. If the s3ResourcePath is undefined, it will default to the workspace S3 resource.
|
|
76057
|
-
*
|
|
76058
|
-
* \`\`\`typescript
|
|
76059
|
-
* let fileContent = await wmill.loadS3FileContent(inputFile)
|
|
76060
|
-
* // if the file is a raw text file, it can be decoded and printed directly:
|
|
76061
|
-
* const text = new TextDecoder().decode(fileContentStream)
|
|
76062
|
-
* console.log(text);
|
|
76063
|
-
* \`\`\`
|
|
76064
|
-
*/
|
|
76065
|
-
async loadS3File(s3object: S3Object, s3ResourcePath: string | undefined = undefined): Promise<Uint8Array | undefined>
|
|
76381
|
+
The script must contain a function called \`main\` with proper return type:
|
|
76066
76382
|
|
|
76067
|
-
|
|
76068
|
-
|
|
76069
|
-
|
|
76070
|
-
* \`\`\`typescript
|
|
76071
|
-
* let fileContentBlob = await wmill.loadS3FileStream(inputFile)
|
|
76072
|
-
* // if the content is plain text, the blob can be read directly:
|
|
76073
|
-
* console.log(await fileContentBlob.text());
|
|
76074
|
-
* \`\`\`
|
|
76075
|
-
*/
|
|
76076
|
-
async loadS3FileStream(s3object: S3Object, s3ResourcePath: string | undefined = undefined): Promise<Blob | undefined>
|
|
76383
|
+
\`\`\`rust
|
|
76384
|
+
use anyhow::anyhow;
|
|
76385
|
+
use serde::Serialize;
|
|
76077
76386
|
|
|
76078
|
-
|
|
76079
|
-
|
|
76080
|
-
|
|
76081
|
-
|
|
76082
|
-
|
|
76083
|
-
* const fileContentAsUtf8Str = (await s3object.toArray()).toString('utf-8')
|
|
76084
|
-
* console.log(fileContentAsUtf8Str)
|
|
76085
|
-
* \`\`\`
|
|
76086
|
-
*/
|
|
76087
|
-
async writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath: string | undefined = undefined, contentType: string | undefined = undefined, contentDisposition: string | undefined = undefined): Promise<S3Object>
|
|
76387
|
+
#[derive(Serialize, Debug)]
|
|
76388
|
+
struct ReturnType {
|
|
76389
|
+
result: String,
|
|
76390
|
+
count: i32,
|
|
76391
|
+
}
|
|
76088
76392
|
|
|
76089
|
-
|
|
76090
|
-
|
|
76091
|
-
|
|
76092
|
-
|
|
76093
|
-
|
|
76094
|
-
|
|
76393
|
+
fn main(param1: String, param2: i32) -> anyhow::Result<ReturnType> {
|
|
76394
|
+
Ok(ReturnType {
|
|
76395
|
+
result: param1,
|
|
76396
|
+
count: param2,
|
|
76397
|
+
})
|
|
76398
|
+
}
|
|
76399
|
+
\`\`\`
|
|
76095
76400
|
|
|
76096
|
-
|
|
76097
|
-
|
|
76098
|
-
|
|
76099
|
-
|
|
76100
|
-
*/
|
|
76101
|
-
async signS3Object(s3object: S3Object): Promise<S3Object>
|
|
76401
|
+
**Important:**
|
|
76402
|
+
- Arguments should be owned types
|
|
76403
|
+
- Return type must be serializable (\`#[derive(Serialize)]\`)
|
|
76404
|
+
- Return type is \`anyhow::Result<T>\`
|
|
76102
76405
|
|
|
76103
|
-
|
|
76104
|
-
* Generate a presigned public URL for an array of S3 objects.
|
|
76105
|
-
* If an S3 object is not signed yet, it will be signed first.
|
|
76106
|
-
* @param s3Objects s3 objects to sign
|
|
76107
|
-
* @returns list of signed public URLs
|
|
76108
|
-
*/
|
|
76109
|
-
async getPresignedS3PublicUrls(s3Objects: S3Object[], { baseUrl }: { baseUrl?: string } = {}): Promise<string[]>
|
|
76406
|
+
## Dependencies
|
|
76110
76407
|
|
|
76111
|
-
|
|
76112
|
-
* Generate a presigned public URL for an S3 object. If the S3 object is not signed yet, it will be signed first.
|
|
76113
|
-
* @param s3Object s3 object to sign
|
|
76114
|
-
* @returns signed public URL
|
|
76115
|
-
*/
|
|
76116
|
-
async getPresignedS3PublicUrl(s3Objects: S3Object, { baseUrl }: { baseUrl?: string } = {}): Promise<string>
|
|
76408
|
+
Packages must be specified with a partial cargo.toml at the beginning of the script:
|
|
76117
76409
|
|
|
76118
|
-
|
|
76119
|
-
|
|
76120
|
-
|
|
76121
|
-
|
|
76122
|
-
|
|
76123
|
-
|
|
76124
|
-
|
|
76125
|
-
async getResumeUrls(approver?: string, flowLevel?: boolean): Promise<{
|
|
76126
|
-
approvalPage: string;
|
|
76127
|
-
resume: string;
|
|
76128
|
-
cancel: string;
|
|
76129
|
-
}>
|
|
76410
|
+
\`\`\`rust
|
|
76411
|
+
//! \`\`\`cargo
|
|
76412
|
+
//! [dependencies]
|
|
76413
|
+
//! anyhow = "1.0.86"
|
|
76414
|
+
//! reqwest = { version = "0.11", features = ["json"] }
|
|
76415
|
+
//! tokio = { version = "1", features = ["full"] }
|
|
76416
|
+
//! \`\`\`
|
|
76130
76417
|
|
|
76131
|
-
|
|
76132
|
-
|
|
76133
|
-
|
|
76134
|
-
getResumeEndpoints(approver?: string): Promise<{
|
|
76135
|
-
approvalPage: string;
|
|
76136
|
-
resume: string;
|
|
76137
|
-
cancel: string;
|
|
76138
|
-
}>
|
|
76418
|
+
use anyhow::anyhow;
|
|
76419
|
+
// ... rest of the code
|
|
76420
|
+
\`\`\`
|
|
76139
76421
|
|
|
76140
|
-
|
|
76141
|
-
* Get an OIDC jwt token for auth to external services (e.g: Vault, AWS) (ee only)
|
|
76142
|
-
* @param audience audience of the token
|
|
76143
|
-
* @param expiresIn Optional number of seconds until the token expires
|
|
76144
|
-
* @returns jwt token
|
|
76145
|
-
*/
|
|
76146
|
-
async getIdToken(audience: string, expiresIn?: number): Promise<string>
|
|
76422
|
+
**Note:** Serde is already included, no need to add it again.
|
|
76147
76423
|
|
|
76148
|
-
|
|
76149
|
-
* Convert a base64-encoded string to Uint8Array
|
|
76150
|
-
* @param data - Base64-encoded string
|
|
76151
|
-
* @returns Decoded Uint8Array
|
|
76152
|
-
*/
|
|
76153
|
-
base64ToUint8Array(data: string): Uint8Array
|
|
76424
|
+
## Async Functions
|
|
76154
76425
|
|
|
76155
|
-
|
|
76156
|
-
* Convert a Uint8Array to base64-encoded string
|
|
76157
|
-
* @param arrayBuffer - Uint8Array to encode
|
|
76158
|
-
* @returns Base64-encoded string
|
|
76159
|
-
*/
|
|
76160
|
-
uint8ArrayToBase64(arrayBuffer: Uint8Array): string
|
|
76426
|
+
If you need to handle async functions (e.g., using tokio), keep the main function sync and create the runtime inside:
|
|
76161
76427
|
|
|
76162
|
-
|
|
76163
|
-
|
|
76164
|
-
|
|
76165
|
-
|
|
76166
|
-
|
|
76167
|
-
|
|
76168
|
-
|
|
76169
|
-
async usernameToEmail(username: string): Promise<string>
|
|
76428
|
+
\`\`\`rust
|
|
76429
|
+
//! \`\`\`cargo
|
|
76430
|
+
//! [dependencies]
|
|
76431
|
+
//! anyhow = "1.0.86"
|
|
76432
|
+
//! tokio = { version = "1", features = ["full"] }
|
|
76433
|
+
//! reqwest = { version = "0.11", features = ["json"] }
|
|
76434
|
+
//! \`\`\`
|
|
76170
76435
|
|
|
76171
|
-
|
|
76172
|
-
|
|
76173
|
-
*
|
|
76174
|
-
* **[Enterprise Edition Only]** To include form fields in the Slack approval request, go to **Advanced -> Suspend -> Form**
|
|
76175
|
-
* and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
|
|
76176
|
-
*
|
|
76177
|
-
* @param {Object} options - The configuration options for the Slack approval request.
|
|
76178
|
-
* @param {string} options.slackResourcePath - The path to the Slack resource in Windmill.
|
|
76179
|
-
* @param {string} options.channelId - The Slack channel ID where the approval request will be sent.
|
|
76180
|
-
* @param {string} [options.message] - Optional custom message to include in the Slack approval request.
|
|
76181
|
-
* @param {string} [options.approver] - Optional user ID or name of the approver for the request.
|
|
76182
|
-
* @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
|
|
76183
|
-
* @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
|
|
76184
|
-
* @param {string} [options.resumeButtonText] - Optional text for the resume button.
|
|
76185
|
-
* @param {string} [options.cancelButtonText] - Optional text for the cancel button.
|
|
76186
|
-
*
|
|
76187
|
-
* @returns {Promise<void>} Resolves when the Slack approval request is successfully sent.
|
|
76188
|
-
*
|
|
76189
|
-
* @throws {Error} If the function is not called within a flow or flow preview.
|
|
76190
|
-
* @throws {Error} If the \`JobService.getSlackApprovalPayload\` call fails.
|
|
76191
|
-
*
|
|
76192
|
-
* **Usage Example:**
|
|
76193
|
-
* \`\`\`typescript
|
|
76194
|
-
* await requestInteractiveSlackApproval({
|
|
76195
|
-
* slackResourcePath: "/u/alex/my_slack_resource",
|
|
76196
|
-
* channelId: "admins-slack-channel",
|
|
76197
|
-
* message: "Please approve this request",
|
|
76198
|
-
* approver: "approver123",
|
|
76199
|
-
* defaultArgsJson: { key1: "value1", key2: 42 },
|
|
76200
|
-
* dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
|
|
76201
|
-
* resumeButtonText: "Resume",
|
|
76202
|
-
* cancelButtonText: "Cancel",
|
|
76203
|
-
* });
|
|
76204
|
-
* \`\`\`
|
|
76205
|
-
*
|
|
76206
|
-
* **Note:** This function requires execution within a Windmill flow or flow preview.
|
|
76207
|
-
*/
|
|
76208
|
-
async requestInteractiveSlackApproval({ slackResourcePath, channelId, message, approver, defaultArgsJson, dynamicEnumsJson, resumeButtonText, cancelButtonText, }: SlackApprovalOptions): Promise<void>
|
|
76436
|
+
use anyhow::anyhow;
|
|
76437
|
+
use serde::Serialize;
|
|
76209
76438
|
|
|
76210
|
-
|
|
76211
|
-
|
|
76212
|
-
|
|
76213
|
-
|
|
76214
|
-
* and define a form. Learn more at [Windmill Documentation](https://www.windmill.dev/docs/flows/flow_approval#form).
|
|
76215
|
-
*
|
|
76216
|
-
* @param {Object} options - The configuration options for the Teams approval request.
|
|
76217
|
-
* @param {string} options.teamName - The Teams team name where the approval request will be sent.
|
|
76218
|
-
* @param {string} options.channelName - The Teams channel name where the approval request will be sent.
|
|
76219
|
-
* @param {string} [options.message] - Optional custom message to include in the Teams approval request.
|
|
76220
|
-
* @param {string} [options.approver] - Optional user ID or name of the approver for the request.
|
|
76221
|
-
* @param {DefaultArgs} [options.defaultArgsJson] - Optional object defining or overriding the default arguments to a form field.
|
|
76222
|
-
* @param {Enums} [options.dynamicEnumsJson] - Optional object overriding the enum default values of an enum form field.
|
|
76223
|
-
*
|
|
76224
|
-
* @returns {Promise<void>} Resolves when the Teams approval request is successfully sent.
|
|
76225
|
-
*
|
|
76226
|
-
* @throws {Error} If the function is not called within a flow or flow preview.
|
|
76227
|
-
* @throws {Error} If the \`JobService.getTeamsApprovalPayload\` call fails.
|
|
76228
|
-
*
|
|
76229
|
-
* **Usage Example:**
|
|
76230
|
-
* \`\`\`typescript
|
|
76231
|
-
* await requestInteractiveTeamsApproval({
|
|
76232
|
-
* teamName: "admins-teams",
|
|
76233
|
-
* channelName: "admins-teams-channel",
|
|
76234
|
-
* message: "Please approve this request",
|
|
76235
|
-
* approver: "approver123",
|
|
76236
|
-
* defaultArgsJson: { key1: "value1", key2: 42 },
|
|
76237
|
-
* dynamicEnumsJson: { foo: ["choice1", "choice2"], bar: ["optionA", "optionB"] },
|
|
76238
|
-
* });
|
|
76239
|
-
* \`\`\`
|
|
76240
|
-
*
|
|
76241
|
-
* **Note:** This function requires execution within a Windmill flow or flow preview.
|
|
76242
|
-
*/
|
|
76243
|
-
async requestInteractiveTeamsApproval({ teamName, channelName, message, approver, defaultArgsJson, dynamicEnumsJson, }: TeamsApprovalOptions): Promise<void>
|
|
76439
|
+
#[derive(Serialize, Debug)]
|
|
76440
|
+
struct Response {
|
|
76441
|
+
data: String,
|
|
76442
|
+
}
|
|
76244
76443
|
|
|
76245
|
-
|
|
76246
|
-
|
|
76247
|
-
|
|
76248
|
-
|
|
76249
|
-
|
|
76250
|
-
|
|
76444
|
+
fn main(url: String) -> anyhow::Result<Response> {
|
|
76445
|
+
let rt = tokio::runtime::Runtime::new()?;
|
|
76446
|
+
rt.block_on(async {
|
|
76447
|
+
let resp = reqwest::get(&url).await?.text().await?;
|
|
76448
|
+
Ok(Response { data: resp })
|
|
76449
|
+
})
|
|
76450
|
+
}
|
|
76451
|
+
\`\`\`
|
|
76452
|
+
`,
|
|
76453
|
+
"write-script-snowflake": `---
|
|
76454
|
+
name: write-script-snowflake
|
|
76455
|
+
description: MUST use when writing Snowflake queries.
|
|
76456
|
+
---
|
|
76251
76457
|
|
|
76252
|
-
|
|
76458
|
+
## CLI Commands
|
|
76253
76459
|
|
|
76254
|
-
|
|
76460
|
+
Place scripts in a folder. After writing, tell the user they can run:
|
|
76461
|
+
- \`wmill script generate-metadata\` - Generate .script.yaml and .lock files
|
|
76462
|
+
- \`wmill sync push\` - Deploy to Windmill
|
|
76255
76463
|
|
|
76256
|
-
|
|
76464
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
76257
76465
|
|
|
76258
|
-
|
|
76259
|
-
* Create a task that dispatches to a separate Windmill script.
|
|
76260
|
-
*
|
|
76261
|
-
* @example
|
|
76262
|
-
* const extract = taskScript("f/data/extract");
|
|
76263
|
-
* // inside workflow: await extract({ url: "https://..." })
|
|
76264
|
-
*/
|
|
76265
|
-
taskScript(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
|
|
76466
|
+
Use \`wmill resource-type list --schema\` to discover available resource types.
|
|
76266
76467
|
|
|
76267
|
-
|
|
76268
|
-
* Create a task that dispatches to a separate Windmill flow.
|
|
76269
|
-
*
|
|
76270
|
-
* @example
|
|
76271
|
-
* const pipeline = taskFlow("f/etl/pipeline");
|
|
76272
|
-
* // inside workflow: await pipeline({ input: data })
|
|
76273
|
-
*/
|
|
76274
|
-
taskFlow(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
|
|
76468
|
+
# Snowflake
|
|
76275
76469
|
|
|
76276
|
-
|
|
76277
|
-
* Mark an async function as a workflow-as-code entry point.
|
|
76278
|
-
*
|
|
76279
|
-
* The function must be **deterministic**: given the same inputs it must call
|
|
76280
|
-
* tasks in the same order on every replay. Branching on task results is fine
|
|
76281
|
-
* (results are replayed from checkpoint), but branching on external state
|
|
76282
|
-
* (current time, random values, external API calls) must use \`step()\` to
|
|
76283
|
-
* checkpoint the value so replays see the same result.
|
|
76284
|
-
*/
|
|
76285
|
-
workflow<T>(fn: (...args: any[]) => Promise<T>): void
|
|
76470
|
+
Arguments use \`?\` placeholders.
|
|
76286
76471
|
|
|
76287
|
-
|
|
76288
|
-
* Suspend the workflow and wait for an external approval.
|
|
76289
|
-
*
|
|
76290
|
-
* Use \`getResumeUrls()\` (wrapped in \`step()\`) to obtain resume/cancel/approvalPage
|
|
76291
|
-
* URLs before calling this function.
|
|
76292
|
-
*
|
|
76293
|
-
* @example
|
|
76294
|
-
* const urls = await step("urls", () => getResumeUrls());
|
|
76295
|
-
* await step("notify", () => sendEmail(urls.approvalPage));
|
|
76296
|
-
* const { value, approver } = await waitForApproval({ timeout: 3600 });
|
|
76297
|
-
*/
|
|
76298
|
-
waitForApproval(options?: { timeout?: number; form?: object; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
|
|
76472
|
+
Name the parameters by adding comments before the statement:
|
|
76299
76473
|
|
|
76300
|
-
|
|
76301
|
-
|
|
76302
|
-
|
|
76303
|
-
*
|
|
76304
|
-
|
|
76305
|
-
*
|
|
76306
|
-
* @example
|
|
76307
|
-
* const process = task(async (item: string) => { ... });
|
|
76308
|
-
* const results = await parallel(items, process, { concurrency: 5 });
|
|
76309
|
-
*/
|
|
76310
|
-
async parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
|
|
76474
|
+
\`\`\`sql
|
|
76475
|
+
-- ? name1 (text)
|
|
76476
|
+
-- ? name2 (number) = 0
|
|
76477
|
+
SELECT * FROM users WHERE name = ? AND age > ?;
|
|
76478
|
+
\`\`\`
|
|
76311
76479
|
`,
|
|
76312
76480
|
"write-flow": `---
|
|
76313
76481
|
name: write-flow
|
|
@@ -76320,10 +76488,12 @@ description: MUST use when creating flows.
|
|
|
76320
76488
|
|
|
76321
76489
|
Create a folder ending with \`.flow\` and add a YAML file with the flow definition.
|
|
76322
76490
|
For rawscript modules, use \`!inline path/to/script.ts\` for the content key.
|
|
76323
|
-
After writing:
|
|
76491
|
+
After writing, tell the user they can run:
|
|
76324
76492
|
- \`wmill flow generate-locks <path_to_flow_folder> --yes\` - Generate lock files for the specific flow you modified (e.g. \`wmill flow generate-locks f/my_folder/my_flow.flow --yes\`)
|
|
76325
76493
|
- \`wmill sync push\` - Deploy to Windmill
|
|
76326
76494
|
|
|
76495
|
+
Do NOT run these commands yourself. Instead, inform the user that they should run them.
|
|
76496
|
+
|
|
76327
76497
|
## OpenFlow Schema
|
|
76328
76498
|
|
|
76329
76499
|
The OpenFlow schema (openflow.openapi.yaml) is the source of truth for flow structure. Refer to OPENFLOW_SCHEMA for the complete type definitions.
|
|
@@ -76521,7 +76691,7 @@ export async function main(user_id: string) {
|
|
|
76521
76691
|
}
|
|
76522
76692
|
\`\`\`
|
|
76523
76693
|
|
|
76524
|
-
After creating, generate lock files:
|
|
76694
|
+
After creating, tell the user they can generate lock files by running:
|
|
76525
76695
|
\`\`\`bash
|
|
76526
76696
|
wmill app generate-locks
|
|
76527
76697
|
\`\`\`
|
|
@@ -76674,6 +76844,8 @@ data:
|
|
|
76674
76844
|
|
|
76675
76845
|
## CLI Commands
|
|
76676
76846
|
|
|
76847
|
+
Tell the user they can run these commands (do NOT run them yourself):
|
|
76848
|
+
|
|
76677
76849
|
| Command | Description |
|
|
76678
76850
|
|---------|-------------|
|
|
76679
76851
|
| \`wmill app new\` | Create a new raw app interactively |
|
|
@@ -76690,7 +76862,7 @@ data:
|
|
|
76690
76862
|
3. **Keep runnables focused** - one function per file
|
|
76691
76863
|
4. **Use descriptive IDs** - \`get_user.ts\` not \`a.ts\`
|
|
76692
76864
|
5. **Always whitelist tables** - add to \`data.tables\` before querying
|
|
76693
|
-
6. **Generate locks** - run \`wmill app generate-locks\` after adding/modifying backend runnables
|
|
76865
|
+
6. **Generate locks** - tell the user to run \`wmill app generate-locks\` after adding/modifying backend runnables
|
|
76694
76866
|
`,
|
|
76695
76867
|
triggers: `---
|
|
76696
76868
|
name: triggers
|
|
@@ -76712,6 +76884,8 @@ Examples:
|
|
|
76712
76884
|
|
|
76713
76885
|
## CLI Commands
|
|
76714
76886
|
|
|
76887
|
+
After writing, tell the user they can run these commands (do NOT run them yourself):
|
|
76888
|
+
|
|
76715
76889
|
\`\`\`bash
|
|
76716
76890
|
# Push trigger configuration
|
|
76717
76891
|
wmill sync push
|
|
@@ -76761,6 +76935,8 @@ Windmill uses 6-field cron expressions (includes seconds):
|
|
|
76761
76935
|
|
|
76762
76936
|
## CLI Commands
|
|
76763
76937
|
|
|
76938
|
+
After writing, tell the user they can run these commands (do NOT run them yourself):
|
|
76939
|
+
|
|
76764
76940
|
\`\`\`bash
|
|
76765
76941
|
# Push schedules to Windmill
|
|
76766
76942
|
wmill sync push
|
|
@@ -77016,7 +77192,7 @@ wmill resource-type list --schema
|
|
|
77016
77192
|
# Get specific resource type schema
|
|
77017
77193
|
wmill resource-type get postgresql
|
|
77018
77194
|
|
|
77019
|
-
# Push resources
|
|
77195
|
+
# Push resources (tell the user to run this, do NOT run it yourself)
|
|
77020
77196
|
wmill sync push
|
|
77021
77197
|
\`\`\`
|
|
77022
77198
|
`,
|
|
@@ -77029,8 +77205,6 @@ description: MUST use when using the CLI.
|
|
|
77029
77205
|
|
|
77030
77206
|
The Windmill CLI (\`wmill\`) provides commands for managing scripts, flows, apps, and other resources.
|
|
77031
77207
|
|
|
77032
|
-
Current version: 1.651.1
|
|
77033
|
-
|
|
77034
77208
|
## Global Options
|
|
77035
77209
|
|
|
77036
77210
|
- \`--workspace <workspace:string>\` - Specify the target workspace. This overrides the default workspace.
|
|
@@ -77776,6 +77950,18 @@ properties:
|
|
|
77776
77950
|
key:
|
|
77777
77951
|
type: string
|
|
77778
77952
|
value: {}
|
|
77953
|
+
auto_offset_reset:
|
|
77954
|
+
type: string
|
|
77955
|
+
enum:
|
|
77956
|
+
- latest
|
|
77957
|
+
- earliest
|
|
77958
|
+
description: Initial offset behavior when consumer group has no committed offset.
|
|
77959
|
+
'latest' starts from new messages only, 'earliest' starts from the beginning.
|
|
77960
|
+
auto_commit:
|
|
77961
|
+
type: boolean
|
|
77962
|
+
description: When true (default), offsets are committed automatically after receiving
|
|
77963
|
+
each message. When false, you must manually commit offsets using the commit_offsets
|
|
77964
|
+
endpoint.
|
|
77779
77965
|
error_handler_path:
|
|
77780
77966
|
type: string
|
|
77781
77967
|
description: Path to a script or flow to run when the triggered job fails
|
|
@@ -78764,6 +78950,164 @@ var push12 = new Command().description("Push completed and queued jobs to worksp
|
|
|
78764
78950
|
var command28 = new Command().description("Manage jobs (import/export)").command("pull", pull3).command("push", push12);
|
|
78765
78951
|
var jobs_default = command28;
|
|
78766
78952
|
|
|
78953
|
+
// src/commands/generate-metadata/generate-metadata.ts
|
|
78954
|
+
init_mod3();
|
|
78955
|
+
init_colors2();
|
|
78956
|
+
init_log();
|
|
78957
|
+
init_resource_folders();
|
|
78958
|
+
await __promiseAll([
|
|
78959
|
+
init_confirm(),
|
|
78960
|
+
init_conf(),
|
|
78961
|
+
init_context(),
|
|
78962
|
+
init_auth(),
|
|
78963
|
+
init_metadata(),
|
|
78964
|
+
init_flow_metadata(),
|
|
78965
|
+
init_app_metadata(),
|
|
78966
|
+
init_sync(),
|
|
78967
|
+
init_script(),
|
|
78968
|
+
init_codebase()
|
|
78969
|
+
]);
|
|
78970
|
+
import { sep as SEP21 } from "node:path";
|
|
78971
|
+
async function generateMetadata2(opts, folder) {
|
|
78972
|
+
if (folder === "") {
|
|
78973
|
+
folder = undefined;
|
|
78974
|
+
}
|
|
78975
|
+
const workspace = await resolveWorkspace(opts);
|
|
78976
|
+
await requireLogin(opts);
|
|
78977
|
+
opts = await mergeConfigWithConfigFile(opts);
|
|
78978
|
+
const rawWorkspaceDependencies = await getRawWorkspaceDependencies();
|
|
78979
|
+
const codebases = await listSyncCodebases(opts);
|
|
78980
|
+
const ignore = await ignoreF(opts);
|
|
78981
|
+
const staleItems = [];
|
|
78982
|
+
const skipScripts = opts.skipScripts ?? false;
|
|
78983
|
+
const skipFlows = opts.skipFlows ?? opts.schemaOnly ?? false;
|
|
78984
|
+
const skipApps = opts.skipApps ?? opts.schemaOnly ?? false;
|
|
78985
|
+
const checking = [];
|
|
78986
|
+
if (!skipScripts)
|
|
78987
|
+
checking.push("scripts");
|
|
78988
|
+
if (!skipFlows)
|
|
78989
|
+
checking.push("flows");
|
|
78990
|
+
if (!skipApps)
|
|
78991
|
+
checking.push("apps");
|
|
78992
|
+
if (checking.length === 0) {
|
|
78993
|
+
info(colors.yellow("Nothing to check (all types skipped)"));
|
|
78994
|
+
return;
|
|
78995
|
+
}
|
|
78996
|
+
info(colors.gray(`Checking ${checking.join(", ")}...`));
|
|
78997
|
+
if (!skipScripts) {
|
|
78998
|
+
const scriptElems = await elementsToMap(await FSFSElement(process.cwd(), codebases, false), (p, isD) => {
|
|
78999
|
+
return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFlowPath(p) || isAppPath(p);
|
|
79000
|
+
}, false, {});
|
|
79001
|
+
for (const e of Object.keys(scriptElems)) {
|
|
79002
|
+
const candidate = await generateScriptMetadataInternal(e, workspace, opts, true, true, rawWorkspaceDependencies, codebases, false);
|
|
79003
|
+
if (candidate) {
|
|
79004
|
+
staleItems.push({ type: "script", path: candidate, folder: e });
|
|
79005
|
+
}
|
|
79006
|
+
}
|
|
79007
|
+
}
|
|
79008
|
+
if (!skipFlows) {
|
|
79009
|
+
const flowElems = Object.keys(await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => {
|
|
79010
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP21 + "flow.yaml") && !p.endsWith(SEP21 + "flow.json");
|
|
79011
|
+
}, false, {})).map((x) => x.substring(0, x.lastIndexOf(SEP21)));
|
|
79012
|
+
for (const folder2 of flowElems) {
|
|
79013
|
+
const candidate = await generateFlowLockInternal(folder2, true, workspace, opts, false, true);
|
|
79014
|
+
if (candidate) {
|
|
79015
|
+
staleItems.push({ type: "flow", path: candidate, folder: folder2 });
|
|
79016
|
+
}
|
|
79017
|
+
}
|
|
79018
|
+
}
|
|
79019
|
+
if (!skipApps) {
|
|
79020
|
+
const elems = await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => {
|
|
79021
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP21 + "raw_app.yaml") && !p.endsWith(SEP21 + "app.yaml");
|
|
79022
|
+
}, false, {});
|
|
79023
|
+
const rawAppFolders = getAppFolders(elems, "raw_app.yaml");
|
|
79024
|
+
const appFolders = getAppFolders(elems, "app.yaml");
|
|
79025
|
+
for (const appFolder of rawAppFolders) {
|
|
79026
|
+
const candidate = await generateAppLocksInternal(appFolder, true, true, workspace, opts, false, true);
|
|
79027
|
+
if (candidate) {
|
|
79028
|
+
staleItems.push({ type: "app", path: candidate, folder: appFolder, isRawApp: true });
|
|
79029
|
+
}
|
|
79030
|
+
}
|
|
79031
|
+
for (const appFolder of appFolders) {
|
|
79032
|
+
const candidate = await generateAppLocksInternal(appFolder, false, true, workspace, opts, false, true);
|
|
79033
|
+
if (candidate) {
|
|
79034
|
+
staleItems.push({ type: "app", path: candidate, folder: appFolder, isRawApp: false });
|
|
79035
|
+
}
|
|
79036
|
+
}
|
|
79037
|
+
}
|
|
79038
|
+
let filteredItems = staleItems;
|
|
79039
|
+
if (folder) {
|
|
79040
|
+
if (folder.endsWith(SEP21)) {
|
|
79041
|
+
folder = folder.substring(0, folder.length - 1);
|
|
79042
|
+
}
|
|
79043
|
+
filteredItems = staleItems.filter((item) => item.folder === folder || item.folder.startsWith(folder + SEP21));
|
|
79044
|
+
}
|
|
79045
|
+
if (filteredItems.length === 0) {
|
|
79046
|
+
info(colors.green("All metadata up-to-date"));
|
|
79047
|
+
return;
|
|
79048
|
+
}
|
|
79049
|
+
const scripts = filteredItems.filter((i) => i.type === "script");
|
|
79050
|
+
const flows = filteredItems.filter((i) => i.type === "flow");
|
|
79051
|
+
const apps2 = filteredItems.filter((i) => i.type === "app");
|
|
79052
|
+
info("");
|
|
79053
|
+
info(`Found ${filteredItems.length} item(s) with stale metadata:`);
|
|
79054
|
+
if (scripts.length > 0) {
|
|
79055
|
+
info(colors.gray(` Scripts (${scripts.length}):`));
|
|
79056
|
+
for (const item of scripts) {
|
|
79057
|
+
info(colors.yellow(` ${item.path}`));
|
|
79058
|
+
}
|
|
79059
|
+
}
|
|
79060
|
+
if (flows.length > 0) {
|
|
79061
|
+
info(colors.gray(` Flows (${flows.length}):`));
|
|
79062
|
+
for (const item of flows) {
|
|
79063
|
+
info(colors.yellow(` ${item.path}`));
|
|
79064
|
+
}
|
|
79065
|
+
}
|
|
79066
|
+
if (apps2.length > 0) {
|
|
79067
|
+
info(colors.gray(` Apps (${apps2.length}):`));
|
|
79068
|
+
for (const item of apps2) {
|
|
79069
|
+
info(colors.yellow(` ${item.path}`));
|
|
79070
|
+
}
|
|
79071
|
+
}
|
|
79072
|
+
if (opts.dryRun) {
|
|
79073
|
+
return;
|
|
79074
|
+
}
|
|
79075
|
+
info("");
|
|
79076
|
+
if (!opts.yes && !await Confirm.prompt({
|
|
79077
|
+
message: "Update metadata?",
|
|
79078
|
+
default: true
|
|
79079
|
+
})) {
|
|
79080
|
+
return;
|
|
79081
|
+
}
|
|
79082
|
+
info("");
|
|
79083
|
+
const total = filteredItems.length;
|
|
79084
|
+
const maxWidth = `[${total}/${total}]`.length;
|
|
79085
|
+
let current = 0;
|
|
79086
|
+
const formatProgress = (n) => {
|
|
79087
|
+
const bracket = `[${n}/${total}]`;
|
|
79088
|
+
return colors.gray(bracket.padEnd(maxWidth, " "));
|
|
79089
|
+
};
|
|
79090
|
+
for (const item of scripts) {
|
|
79091
|
+
current++;
|
|
79092
|
+
info(`${formatProgress(current)} script ${colors.cyan(item.path)}`);
|
|
79093
|
+
await generateScriptMetadataInternal(item.folder, workspace, opts, false, true, rawWorkspaceDependencies, codebases, false);
|
|
79094
|
+
}
|
|
79095
|
+
for (const item of flows) {
|
|
79096
|
+
current++;
|
|
79097
|
+
info(`${formatProgress(current)} flow ${colors.cyan(item.path)}`);
|
|
79098
|
+
await generateFlowLockInternal(item.folder, false, workspace, opts, false, true);
|
|
79099
|
+
}
|
|
79100
|
+
for (const item of apps2) {
|
|
79101
|
+
current++;
|
|
79102
|
+
info(`${formatProgress(current)} app ${colors.cyan(item.path)}`);
|
|
79103
|
+
await generateAppLocksInternal(item.folder, item.isRawApp, false, workspace, opts, false, true);
|
|
79104
|
+
}
|
|
79105
|
+
info("");
|
|
79106
|
+
info(colors.green(`Done. Updated ${total} item(s).`));
|
|
79107
|
+
}
|
|
79108
|
+
var command29 = new Command().description("Generate metadata (locks, schemas) for all scripts, flows, and apps").arguments("[folder:string]").option("--yes", "Skip confirmation prompt").option("--dry-run", "Show what would be updated without making changes").option("--lock-only", "Re-generate only the lock files").option("--schema-only", "Re-generate only script schemas (skips flows and apps)").option("--skip-scripts", "Skip processing scripts").option("--skip-flows", "Skip processing flows").option("--skip-apps", "Skip processing apps").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which files to include").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which files to exclude").action(generateMetadata2);
|
|
79109
|
+
var generate_metadata_default = command29;
|
|
79110
|
+
|
|
78767
79111
|
// src/commands/docs/docs.ts
|
|
78768
79112
|
init_mod3();
|
|
78769
79113
|
init_colors2();
|
|
@@ -78834,13 +79178,13 @@ ${await res.text()}`);
|
|
|
78834
79178
|
console.log();
|
|
78835
79179
|
}
|
|
78836
79180
|
}
|
|
78837
|
-
var
|
|
78838
|
-
var docs_default =
|
|
79181
|
+
var command30 = new Command().name("docs").description("Search Windmill documentation. Requires Enterprise Edition.").arguments("<query:string>").option("--json", "Output results as JSON.").action(docs);
|
|
79182
|
+
var docs_default = command30;
|
|
78839
79183
|
|
|
78840
79184
|
// src/main.ts
|
|
78841
79185
|
await init_context();
|
|
78842
|
-
var VERSION = "1.
|
|
78843
|
-
var
|
|
79186
|
+
var VERSION = "1.655.0";
|
|
79187
|
+
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) => {
|
|
78844
79188
|
console.log("CLI version: " + VERSION);
|
|
78845
79189
|
try {
|
|
78846
79190
|
const provider = new NpmProvider({ package: "windmill-cli" });
|
|
@@ -78870,20 +79214,20 @@ var command30 = new Command().name("wmill").action(() => info(`Welcome to Windmi
|
|
|
78870
79214
|
error(e);
|
|
78871
79215
|
info("Try running with sudo and otherwise check the result of the command: npm uninstall windmill-cli && npm install -g windmill-cli");
|
|
78872
79216
|
})).command("completions", new Command().description("Generate shell completions.").command("bash", new Command().description("Generate bash completions.").action(() => {
|
|
78873
|
-
process.stdout.write(generateShellCompletions(
|
|
79217
|
+
process.stdout.write(generateShellCompletions(command31, "bash") + `
|
|
78874
79218
|
`);
|
|
78875
79219
|
})).command("zsh", new Command().description("Generate zsh completions.").action(() => {
|
|
78876
|
-
process.stdout.write(generateShellCompletions(
|
|
79220
|
+
process.stdout.write(generateShellCompletions(command31, "zsh") + `
|
|
78877
79221
|
`);
|
|
78878
79222
|
})).command("fish", new Command().description("Generate fish completions.").action(() => {
|
|
78879
|
-
process.stdout.write(generateShellCompletions(
|
|
79223
|
+
process.stdout.write(generateShellCompletions(command31, "fish") + `
|
|
78880
79224
|
`);
|
|
78881
79225
|
})));
|
|
78882
79226
|
async function main2() {
|
|
78883
79227
|
try {
|
|
78884
79228
|
const args = process.argv.slice(2);
|
|
78885
79229
|
if (args.length === 0) {
|
|
78886
|
-
|
|
79230
|
+
command31.showHelp();
|
|
78887
79231
|
}
|
|
78888
79232
|
const LOG_LEVEL = args.includes("--verbose") || args.includes("--debug") ? "DEBUG" : "INFO";
|
|
78889
79233
|
setShowDiffs(args.includes("--show-diffs"));
|
|
@@ -78893,7 +79237,7 @@ async function main2() {
|
|
|
78893
79237
|
if (extraHeaders) {
|
|
78894
79238
|
OpenAPI.HEADERS = extraHeaders;
|
|
78895
79239
|
}
|
|
78896
|
-
await
|
|
79240
|
+
await command31.parse(args);
|
|
78897
79241
|
} catch (e) {
|
|
78898
79242
|
if (e && typeof e === "object" && "name" in e && e.name === "ApiError") {
|
|
78899
79243
|
console.log("Server failed. " + e.statusText + ": " + e.body);
|
|
@@ -78918,7 +79262,7 @@ if (isMain()) {
|
|
|
78918
79262
|
process.stdin.destroy();
|
|
78919
79263
|
});
|
|
78920
79264
|
}
|
|
78921
|
-
var main_default =
|
|
79265
|
+
var main_default = command31;
|
|
78922
79266
|
export {
|
|
78923
79267
|
add as workspaceAdd,
|
|
78924
79268
|
workspace_default as workspace,
|