windmill-cli 1.693.4 → 1.694.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 +1149 -738
- package/package.json +1 -1
package/esm/main.js
CHANGED
|
@@ -16710,7 +16710,7 @@ var init_OpenAPI = __esm(() => {
|
|
|
16710
16710
|
PASSWORD: undefined,
|
|
16711
16711
|
TOKEN: getEnv3("WM_TOKEN"),
|
|
16712
16712
|
USERNAME: undefined,
|
|
16713
|
-
VERSION: "1.
|
|
16713
|
+
VERSION: "1.694.0",
|
|
16714
16714
|
WITH_CREDENTIALS: true,
|
|
16715
16715
|
interceptors: {
|
|
16716
16716
|
request: new Interceptors,
|
|
@@ -25100,6 +25100,24 @@ async function requireLogin(opts) {
|
|
|
25100
25100
|
throw new Error(`Network error: Could not connect to Windmill server at ${workspace.remote}`);
|
|
25101
25101
|
}
|
|
25102
25102
|
if (opts.token || opts.baseUrl) {
|
|
25103
|
+
const isApiError = error2 && typeof error2 === "object" && "name" in error2 && error2.name === "ApiError";
|
|
25104
|
+
if (isApiError) {
|
|
25105
|
+
const status = error2.status;
|
|
25106
|
+
const body = error2.body;
|
|
25107
|
+
let bodyStr = typeof body === "object" && body !== null ? JSON.stringify(body) : String(body ?? "").trim();
|
|
25108
|
+
bodyStr = bodyStr.replace(/\s*[@(]\w+\.rs:\d+[:\d]*\)?/g, "");
|
|
25109
|
+
bodyStr = bodyStr.replace(/^(Permission denied|Not authorized): /, "");
|
|
25110
|
+
if (status === 403) {
|
|
25111
|
+
info(colors.red(`Permission denied: the token is valid but lacks the required scope.${bodyStr ? `
|
|
25112
|
+
${bodyStr}` : ""}`));
|
|
25113
|
+
} else if (status === 401) {
|
|
25114
|
+
info(colors.red(`Could not authenticate with the provided credentials. Please check your --token and --base-url and try again.${bodyStr ? `
|
|
25115
|
+
${bodyStr}` : ""}`));
|
|
25116
|
+
} else {
|
|
25117
|
+
info(colors.red(`Request failed (${status ?? "unknown"}): ${bodyStr}`));
|
|
25118
|
+
}
|
|
25119
|
+
return process.exit(1);
|
|
25120
|
+
}
|
|
25103
25121
|
info(colors.red("Could not authenticate with the provided credentials. Please check your --token and --base-url and try again."));
|
|
25104
25122
|
return process.exit(1);
|
|
25105
25123
|
}
|
|
@@ -26462,6 +26480,9 @@ function getScriptBasePathFromModulePath(p) {
|
|
|
26462
26480
|
return;
|
|
26463
26481
|
return norm.slice(0, idx);
|
|
26464
26482
|
}
|
|
26483
|
+
function scriptPathToRemotePath(p) {
|
|
26484
|
+
return (isModuleEntryPoint(p) ? getScriptBasePathFromModulePath(p) : p.substring(0, p.indexOf("."))).replaceAll(SEP2, "/");
|
|
26485
|
+
}
|
|
26465
26486
|
function getDeleteSuffix(type, format6) {
|
|
26466
26487
|
return getFolderSuffixes()[type] + "/" + METADATA_FILES[type][format6];
|
|
26467
26488
|
}
|
|
@@ -61660,7 +61681,7 @@ async function handleFile(path8, workspace, alreadySynced, message, opts, rawWor
|
|
|
61660
61681
|
}
|
|
61661
61682
|
debug(`Processing local script ${path8}`);
|
|
61662
61683
|
alreadySynced.push(path8);
|
|
61663
|
-
const remotePath =
|
|
61684
|
+
const remotePath = scriptPathToRemotePath(path8);
|
|
61664
61685
|
const language = inferContentTypeFromFilePath(path8, opts?.defaultTs);
|
|
61665
61686
|
const codebase = language == "bun" ? findCodebase(path8, codebases) : undefined;
|
|
61666
61687
|
let bundleContent = undefined;
|
|
@@ -63593,8 +63614,11 @@ function getLanguageFromExtension(ext2, defaultTs = "bun") {
|
|
|
63593
63614
|
}
|
|
63594
63615
|
return;
|
|
63595
63616
|
}
|
|
63596
|
-
function sanitizeForFilesystem(summary) {
|
|
63597
|
-
|
|
63617
|
+
function sanitizeForFilesystem(summary, options) {
|
|
63618
|
+
let name = summary.replaceAll(" ", "_").replace(/[/\\:*?"<>|\x00-\x1f\x7f]/g, "").replace(/_+/g, "_").replace(/^[._]+|[._]+$/g, "");
|
|
63619
|
+
if (!options?.preserveCase) {
|
|
63620
|
+
name = name.toLowerCase();
|
|
63621
|
+
}
|
|
63598
63622
|
return WINDOWS_RESERVED.test(name.toLowerCase()) ? `_${name}` : name;
|
|
63599
63623
|
}
|
|
63600
63624
|
function newPathAssigner(defaultTs, options) {
|
|
@@ -63626,7 +63650,7 @@ function newRawAppPathAssigner(defaultTs) {
|
|
|
63626
63650
|
const seen_names = new Set;
|
|
63627
63651
|
function assignPath(summary, language) {
|
|
63628
63652
|
let name;
|
|
63629
|
-
name = summary ? sanitizeForFilesystem(summary) : "";
|
|
63653
|
+
name = summary ? sanitizeForFilesystem(summary, { preserveCase: true }) : "";
|
|
63630
63654
|
let original_name = name;
|
|
63631
63655
|
if (name == "") {
|
|
63632
63656
|
original_name = "runnable";
|
|
@@ -63995,6 +64019,19 @@ var init_relative_imports = __esm(async () => {
|
|
|
63995
64019
|
// src/commands/flow/flow_metadata.ts
|
|
63996
64020
|
import * as path10 from "node:path";
|
|
63997
64021
|
import { sep as SEP7 } from "node:path";
|
|
64022
|
+
async function isFlowDirectlyStale(folder, hashes, conf) {
|
|
64023
|
+
if (await checkifMetadataUptodate(folder, hashes[TOP_HASH], conf, TOP_HASH)) {
|
|
64024
|
+
return false;
|
|
64025
|
+
}
|
|
64026
|
+
const fileEntries = Object.entries(hashes).filter(([k]) => k !== TOP_HASH);
|
|
64027
|
+
if (fileEntries.length === 0)
|
|
64028
|
+
return true;
|
|
64029
|
+
for (const [k, h] of fileEntries) {
|
|
64030
|
+
if (!await checkifMetadataUptodate(folder, h, conf, k))
|
|
64031
|
+
return true;
|
|
64032
|
+
}
|
|
64033
|
+
return false;
|
|
64034
|
+
}
|
|
63998
64035
|
async function generateFlowHash(rawWorkspaceDependencies, folder, defaultTs) {
|
|
63999
64036
|
const elems = await FSFSElement(path10.join(process.cwd(), folder), [], true);
|
|
64000
64037
|
const hashes = {};
|
|
@@ -64014,6 +64051,14 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64014
64051
|
if (folder.endsWith(SEP7)) {
|
|
64015
64052
|
folder = folder.substring(0, folder.length - 1);
|
|
64016
64053
|
}
|
|
64054
|
+
if (opts.rehashOnly) {
|
|
64055
|
+
const hashes = await generateFlowHash({}, folder, opts.defaultTs);
|
|
64056
|
+
await clearGlobalLock(folder);
|
|
64057
|
+
for (const [k, v] of Object.entries(hashes)) {
|
|
64058
|
+
await updateMetadataGlobalLock(folder, v, k);
|
|
64059
|
+
}
|
|
64060
|
+
return;
|
|
64061
|
+
}
|
|
64017
64062
|
const remote_path = extractNameFromFolder(folder.replaceAll(SEP7, "/"), "flow");
|
|
64018
64063
|
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
64019
64064
|
info(`Generating lock for flow ${folder} at ${remote_path}`);
|
|
@@ -64043,7 +64088,7 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64043
64088
|
inlineScriptPaths.push(treePath);
|
|
64044
64089
|
}
|
|
64045
64090
|
const hashes = await generateFlowHash({}, folder, opts.defaultTs);
|
|
64046
|
-
const isDirectlyStale =
|
|
64091
|
+
const isDirectlyStale = await isFlowDirectlyStale(folder, hashes, conf);
|
|
64047
64092
|
await tree.addNode(folderNormalized, "", "bun", "", inlineScriptPaths, "flow", folderNormalized, folder, isDirectlyStale);
|
|
64048
64093
|
return;
|
|
64049
64094
|
}
|
|
@@ -64052,7 +64097,7 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64052
64097
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
64053
64098
|
filteredDeps = await filterWorkspaceDependenciesForFlow(flowValue.value, rawWorkspaceDependencies, folder);
|
|
64054
64099
|
const hashes = await generateFlowHash(filteredDeps, folder, opts.defaultTs);
|
|
64055
|
-
const isDirectlyStale =
|
|
64100
|
+
const isDirectlyStale = await isFlowDirectlyStale(folder, hashes, conf);
|
|
64056
64101
|
if (!isDirectlyStale) {
|
|
64057
64102
|
if (!noStaleMessage) {
|
|
64058
64103
|
info(colors.green(`Flow ${remote_path} metadata is up-to-date, skipping`));
|
|
@@ -64227,6 +64272,662 @@ var init_flow_metadata = __esm(async () => {
|
|
|
64227
64272
|
import_yaml9 = __toESM(require_dist(), 1);
|
|
64228
64273
|
});
|
|
64229
64274
|
|
|
64275
|
+
// src/utils/dependency_tree.ts
|
|
64276
|
+
async function uploadScripts(tree, workspace) {
|
|
64277
|
+
const scriptHashes = {};
|
|
64278
|
+
const workspaceDeps = [];
|
|
64279
|
+
for (const path11 of tree.allPaths()) {
|
|
64280
|
+
const content = tree.getContent(path11);
|
|
64281
|
+
const itemType = tree.getItemType(path11);
|
|
64282
|
+
if (itemType === "dependencies") {
|
|
64283
|
+
if (content === undefined)
|
|
64284
|
+
continue;
|
|
64285
|
+
const info2 = workspaceDependenciesPathToLanguageAndFilename(path11);
|
|
64286
|
+
if (info2) {
|
|
64287
|
+
const hash2 = await generateHash(content);
|
|
64288
|
+
workspaceDeps.push({ path: path11, language: info2.language, name: info2.name, hash: hash2 });
|
|
64289
|
+
}
|
|
64290
|
+
} else if (itemType === "script") {
|
|
64291
|
+
if (!content)
|
|
64292
|
+
continue;
|
|
64293
|
+
const hash2 = await generateHash(content);
|
|
64294
|
+
scriptHashes[path11] = hash2;
|
|
64295
|
+
}
|
|
64296
|
+
}
|
|
64297
|
+
if (Object.keys(scriptHashes).length === 0 && workspaceDeps.length === 0)
|
|
64298
|
+
return;
|
|
64299
|
+
const mismatched = await diffRawScriptsWithDeployed({
|
|
64300
|
+
workspace: workspace.workspaceId,
|
|
64301
|
+
requestBody: {
|
|
64302
|
+
scripts: scriptHashes,
|
|
64303
|
+
workspace_deps: workspaceDeps
|
|
64304
|
+
}
|
|
64305
|
+
});
|
|
64306
|
+
for (const path11 of mismatched) {
|
|
64307
|
+
const content = tree.getContent(path11);
|
|
64308
|
+
const itemType = tree.getItemType(path11);
|
|
64309
|
+
if (itemType === "dependencies") {
|
|
64310
|
+
if (content !== undefined) {
|
|
64311
|
+
tree.setContentHash(path11, "mismatched");
|
|
64312
|
+
}
|
|
64313
|
+
} else if (content) {
|
|
64314
|
+
const hash2 = await storeRawScriptTemp({
|
|
64315
|
+
workspace: workspace.workspaceId,
|
|
64316
|
+
requestBody: content
|
|
64317
|
+
});
|
|
64318
|
+
tree.setContentHash(path11, hash2);
|
|
64319
|
+
}
|
|
64320
|
+
}
|
|
64321
|
+
}
|
|
64322
|
+
|
|
64323
|
+
class DoubleLinkedDependencyTree {
|
|
64324
|
+
nodes = new Map;
|
|
64325
|
+
workspaceDeps = {};
|
|
64326
|
+
setWorkspaceDeps(deps) {
|
|
64327
|
+
this.workspaceDeps = deps;
|
|
64328
|
+
}
|
|
64329
|
+
async addNode(path11, content, language, metadata, imports, itemType, folder, originalPath, isDirectlyStale, isRawApp) {
|
|
64330
|
+
const hasWorkspaceDeps = itemType === "script" || itemType === "inline_script";
|
|
64331
|
+
const filteredDeps = hasWorkspaceDeps ? filterWorkspaceDependencies(this.workspaceDeps, content, language) : {};
|
|
64332
|
+
const stalenessHash = await generateScriptHash({}, content, metadata);
|
|
64333
|
+
if (!this.nodes.has(path11)) {
|
|
64334
|
+
this.nodes.set(path11, {
|
|
64335
|
+
content: "",
|
|
64336
|
+
stalenessHash: "",
|
|
64337
|
+
language: "deno",
|
|
64338
|
+
metadata: "",
|
|
64339
|
+
imports: new Set,
|
|
64340
|
+
importedBy: new Set,
|
|
64341
|
+
itemType: "script",
|
|
64342
|
+
folder: "",
|
|
64343
|
+
originalPath: "",
|
|
64344
|
+
isDirectlyStale: false
|
|
64345
|
+
});
|
|
64346
|
+
}
|
|
64347
|
+
const node = this.nodes.get(path11);
|
|
64348
|
+
node.content = content;
|
|
64349
|
+
node.stalenessHash = stalenessHash;
|
|
64350
|
+
node.language = language;
|
|
64351
|
+
node.metadata = metadata;
|
|
64352
|
+
node.itemType = itemType;
|
|
64353
|
+
node.folder = folder;
|
|
64354
|
+
node.originalPath = originalPath;
|
|
64355
|
+
node.isDirectlyStale = isDirectlyStale;
|
|
64356
|
+
node.isRawApp = isRawApp;
|
|
64357
|
+
const filteredDepsPaths = Object.keys(filteredDeps);
|
|
64358
|
+
for (const depsPath of filteredDepsPaths) {
|
|
64359
|
+
if (!this.nodes.has(depsPath)) {
|
|
64360
|
+
const depsInfo = workspaceDependenciesPathToLanguageAndFilename(depsPath);
|
|
64361
|
+
const contentHash = await generateHash(filteredDeps[depsPath] + depsPath);
|
|
64362
|
+
const isUpToDate = await checkifMetadataUptodate(depsPath, contentHash, undefined);
|
|
64363
|
+
this.nodes.set(depsPath, {
|
|
64364
|
+
content: filteredDeps[depsPath],
|
|
64365
|
+
stalenessHash: "",
|
|
64366
|
+
language: depsInfo?.language ?? "deno",
|
|
64367
|
+
metadata: "",
|
|
64368
|
+
imports: new Set,
|
|
64369
|
+
importedBy: new Set,
|
|
64370
|
+
itemType: "dependencies",
|
|
64371
|
+
folder: "",
|
|
64372
|
+
originalPath: depsPath,
|
|
64373
|
+
isDirectlyStale: !isUpToDate
|
|
64374
|
+
});
|
|
64375
|
+
}
|
|
64376
|
+
}
|
|
64377
|
+
const allImports = [...imports, ...filteredDepsPaths];
|
|
64378
|
+
for (const importPath of allImports) {
|
|
64379
|
+
node.imports.add(importPath);
|
|
64380
|
+
if (!this.nodes.has(importPath)) {
|
|
64381
|
+
this.nodes.set(importPath, {
|
|
64382
|
+
content: "",
|
|
64383
|
+
stalenessHash: "",
|
|
64384
|
+
language: "deno",
|
|
64385
|
+
metadata: "",
|
|
64386
|
+
imports: new Set,
|
|
64387
|
+
importedBy: new Set,
|
|
64388
|
+
itemType: "script",
|
|
64389
|
+
folder: "",
|
|
64390
|
+
originalPath: "",
|
|
64391
|
+
isDirectlyStale: false
|
|
64392
|
+
});
|
|
64393
|
+
}
|
|
64394
|
+
this.nodes.get(importPath).importedBy.add(path11);
|
|
64395
|
+
}
|
|
64396
|
+
}
|
|
64397
|
+
getContent(path11) {
|
|
64398
|
+
return this.nodes.get(path11)?.content;
|
|
64399
|
+
}
|
|
64400
|
+
getStalenessHash(path11) {
|
|
64401
|
+
return this.nodes.get(path11)?.stalenessHash;
|
|
64402
|
+
}
|
|
64403
|
+
getContentHash(path11) {
|
|
64404
|
+
return this.nodes.get(path11)?.contentHash;
|
|
64405
|
+
}
|
|
64406
|
+
setContentHash(path11, hash2) {
|
|
64407
|
+
const node = this.nodes.get(path11);
|
|
64408
|
+
if (node) {
|
|
64409
|
+
node.contentHash = hash2;
|
|
64410
|
+
}
|
|
64411
|
+
}
|
|
64412
|
+
getLanguage(path11) {
|
|
64413
|
+
return this.nodes.get(path11)?.language;
|
|
64414
|
+
}
|
|
64415
|
+
getMetadata(path11) {
|
|
64416
|
+
return this.nodes.get(path11)?.metadata;
|
|
64417
|
+
}
|
|
64418
|
+
getStaleReason(path11) {
|
|
64419
|
+
return this.nodes.get(path11)?.staleReason;
|
|
64420
|
+
}
|
|
64421
|
+
getItemType(path11) {
|
|
64422
|
+
return this.nodes.get(path11)?.itemType;
|
|
64423
|
+
}
|
|
64424
|
+
getFolder(path11) {
|
|
64425
|
+
return this.nodes.get(path11)?.folder;
|
|
64426
|
+
}
|
|
64427
|
+
getIsRawApp(path11) {
|
|
64428
|
+
return this.nodes.get(path11)?.isRawApp;
|
|
64429
|
+
}
|
|
64430
|
+
getIsDirectlyStale(path11) {
|
|
64431
|
+
return this.nodes.get(path11)?.isDirectlyStale ?? false;
|
|
64432
|
+
}
|
|
64433
|
+
getOriginalPath(path11) {
|
|
64434
|
+
return this.nodes.get(path11)?.originalPath;
|
|
64435
|
+
}
|
|
64436
|
+
getImports(path11) {
|
|
64437
|
+
return this.nodes.get(path11)?.imports;
|
|
64438
|
+
}
|
|
64439
|
+
isStale(path11) {
|
|
64440
|
+
return this.nodes.get(path11)?.staleReason !== undefined;
|
|
64441
|
+
}
|
|
64442
|
+
propagateStaleness() {
|
|
64443
|
+
const directlyStale = new Set;
|
|
64444
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64445
|
+
if (node.isDirectlyStale) {
|
|
64446
|
+
directlyStale.add(path11);
|
|
64447
|
+
node.staleReason = "content changed";
|
|
64448
|
+
}
|
|
64449
|
+
}
|
|
64450
|
+
const allStale = new Set(directlyStale);
|
|
64451
|
+
const queue = [...directlyStale];
|
|
64452
|
+
const visited = new Set;
|
|
64453
|
+
while (queue.length > 0) {
|
|
64454
|
+
const scriptPath = queue.shift();
|
|
64455
|
+
if (visited.has(scriptPath))
|
|
64456
|
+
continue;
|
|
64457
|
+
visited.add(scriptPath);
|
|
64458
|
+
const node = this.nodes.get(scriptPath);
|
|
64459
|
+
if (!node)
|
|
64460
|
+
continue;
|
|
64461
|
+
for (const importer of node.importedBy) {
|
|
64462
|
+
if (!allStale.has(importer)) {
|
|
64463
|
+
allStale.add(importer);
|
|
64464
|
+
queue.push(importer);
|
|
64465
|
+
const importerNode = this.nodes.get(importer);
|
|
64466
|
+
if (importerNode)
|
|
64467
|
+
importerNode.staleReason = `depends on ${scriptPath}`;
|
|
64468
|
+
}
|
|
64469
|
+
}
|
|
64470
|
+
}
|
|
64471
|
+
}
|
|
64472
|
+
traverseTransitive(scriptPath, callback) {
|
|
64473
|
+
const queue = [scriptPath];
|
|
64474
|
+
const visited = new Set;
|
|
64475
|
+
while (queue.length > 0) {
|
|
64476
|
+
const current = queue.shift();
|
|
64477
|
+
if (visited.has(current))
|
|
64478
|
+
continue;
|
|
64479
|
+
visited.add(current);
|
|
64480
|
+
const node = this.nodes.get(current);
|
|
64481
|
+
if (!node)
|
|
64482
|
+
continue;
|
|
64483
|
+
for (const importPath of node.imports) {
|
|
64484
|
+
const importNode = this.nodes.get(importPath);
|
|
64485
|
+
if (importNode) {
|
|
64486
|
+
const stop = callback(importPath, importNode);
|
|
64487
|
+
if (!stop) {
|
|
64488
|
+
queue.push(importPath);
|
|
64489
|
+
}
|
|
64490
|
+
}
|
|
64491
|
+
}
|
|
64492
|
+
}
|
|
64493
|
+
}
|
|
64494
|
+
allPaths() {
|
|
64495
|
+
return this.nodes.keys();
|
|
64496
|
+
}
|
|
64497
|
+
*stalePaths() {
|
|
64498
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64499
|
+
if (node.staleReason) {
|
|
64500
|
+
yield path11;
|
|
64501
|
+
}
|
|
64502
|
+
}
|
|
64503
|
+
}
|
|
64504
|
+
has(path11) {
|
|
64505
|
+
return this.nodes.has(path11);
|
|
64506
|
+
}
|
|
64507
|
+
getMismatchedWorkspaceDeps() {
|
|
64508
|
+
const result = {};
|
|
64509
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64510
|
+
if (node.itemType === "dependencies" && node.contentHash && node.content !== undefined) {
|
|
64511
|
+
result[path11] = node.content;
|
|
64512
|
+
}
|
|
64513
|
+
}
|
|
64514
|
+
return result;
|
|
64515
|
+
}
|
|
64516
|
+
getTempScriptRefs(scriptPath) {
|
|
64517
|
+
const result = {};
|
|
64518
|
+
this.traverseTransitive(scriptPath, (_path, node) => {
|
|
64519
|
+
if (node.contentHash) {
|
|
64520
|
+
result[_path] = node.contentHash;
|
|
64521
|
+
}
|
|
64522
|
+
});
|
|
64523
|
+
return result;
|
|
64524
|
+
}
|
|
64525
|
+
async persistDepsHashes(depsPaths) {
|
|
64526
|
+
for (const path11 of depsPaths) {
|
|
64527
|
+
const node = this.nodes.get(path11);
|
|
64528
|
+
if (node?.itemType === "dependencies" && node.content !== undefined) {
|
|
64529
|
+
const hash2 = await generateHash(node.content + path11);
|
|
64530
|
+
await updateMetadataGlobalLock(path11, hash2);
|
|
64531
|
+
}
|
|
64532
|
+
}
|
|
64533
|
+
}
|
|
64534
|
+
get size() {
|
|
64535
|
+
return this.nodes.size;
|
|
64536
|
+
}
|
|
64537
|
+
}
|
|
64538
|
+
var init_dependency_tree = __esm(async () => {
|
|
64539
|
+
init_services_gen();
|
|
64540
|
+
await __promiseAll([
|
|
64541
|
+
init_metadata(),
|
|
64542
|
+
init_utils()
|
|
64543
|
+
]);
|
|
64544
|
+
});
|
|
64545
|
+
|
|
64546
|
+
// src/commands/generate-metadata/generate-metadata.ts
|
|
64547
|
+
var exports_generate_metadata = {};
|
|
64548
|
+
__export(exports_generate_metadata, {
|
|
64549
|
+
rehashOnly: () => rehashOnly,
|
|
64550
|
+
default: () => generate_metadata_default
|
|
64551
|
+
});
|
|
64552
|
+
import { sep as SEP8 } from "node:path";
|
|
64553
|
+
async function walkLocalScripts(codebases, ignore) {
|
|
64554
|
+
const elems = await elementsToMap(await FSFSElement(process.cwd(), codebases, false), (p, isD) => !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFolderResourcePathAnyFormat(p) || isScriptModulePath(p) && !isModuleEntryPoint(p), false, {});
|
|
64555
|
+
return Object.keys(elems);
|
|
64556
|
+
}
|
|
64557
|
+
async function walkLocalFlowFolders(ignore) {
|
|
64558
|
+
const elems = await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => ignore(p, isD) || !isD && !p.endsWith(SEP8 + "flow.yaml") && !p.endsWith(SEP8 + "flow.json"), false, {});
|
|
64559
|
+
return Object.keys(elems).map((x) => x.substring(0, x.lastIndexOf(SEP8)));
|
|
64560
|
+
}
|
|
64561
|
+
async function walkLocalAppItems(ignore) {
|
|
64562
|
+
const elems = await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => ignore(p, isD) || !isD && !p.endsWith(SEP8 + "raw_app.yaml") && !p.endsWith(SEP8 + "app.yaml"), false, {});
|
|
64563
|
+
return Object.keys(elems).map((p) => ({
|
|
64564
|
+
folder: p.substring(0, p.lastIndexOf(SEP8)),
|
|
64565
|
+
rawApp: p.endsWith(SEP8 + "raw_app.yaml")
|
|
64566
|
+
}));
|
|
64567
|
+
}
|
|
64568
|
+
function categorizeLocalFiles(paths) {
|
|
64569
|
+
const scripts = [];
|
|
64570
|
+
const flowFolderSet = new Set;
|
|
64571
|
+
const appPaths = [];
|
|
64572
|
+
for (const p of paths) {
|
|
64573
|
+
if (p.endsWith(SEP8 + "flow.yaml") || p.endsWith(SEP8 + "flow.json")) {
|
|
64574
|
+
flowFolderSet.add(p.substring(0, p.lastIndexOf(SEP8)));
|
|
64575
|
+
} else if (p.endsWith(SEP8 + "raw_app.yaml") || p.endsWith(SEP8 + "app.yaml")) {
|
|
64576
|
+
appPaths.push(p);
|
|
64577
|
+
} else if (exts.some((ext2) => p.endsWith(ext2)) && !isFolderResourcePathAnyFormat(p) && !(isScriptModulePath(p) && !isModuleEntryPoint(p))) {
|
|
64578
|
+
scripts.push(p);
|
|
64579
|
+
}
|
|
64580
|
+
}
|
|
64581
|
+
return { scripts, flowFolders: [...flowFolderSet], appPaths };
|
|
64582
|
+
}
|
|
64583
|
+
async function rehashOnly(opts, folder, rehashFilter) {
|
|
64584
|
+
const codebases = await listSyncCodebases(opts);
|
|
64585
|
+
const ignore = await ignoreF(opts);
|
|
64586
|
+
const counts = { scripts: 0, flows: 0, apps: 0 };
|
|
64587
|
+
const folderFilter = folder?.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
64588
|
+
const inFilter = (p) => {
|
|
64589
|
+
if (!folderFilter)
|
|
64590
|
+
return true;
|
|
64591
|
+
const n = p.replaceAll("\\", "/");
|
|
64592
|
+
return n === folderFilter || n.startsWith(folderFilter + "/");
|
|
64593
|
+
};
|
|
64594
|
+
const conf = rehashFilter?.missingOnly ? await readLockfile() : undefined;
|
|
64595
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
64596
|
+
const hasEntry = (key, subpath) => {
|
|
64597
|
+
if (!conf?.locks)
|
|
64598
|
+
return false;
|
|
64599
|
+
if (isFlatKeyed) {
|
|
64600
|
+
const fullKey = subpath ? `${key}+${subpath}` : key;
|
|
64601
|
+
return conf.locks[fullKey] !== undefined || conf.locks["./" + fullKey] !== undefined;
|
|
64602
|
+
}
|
|
64603
|
+
for (const p of [key, "./" + key]) {
|
|
64604
|
+
const obj = conf.locks[p];
|
|
64605
|
+
if (obj === undefined)
|
|
64606
|
+
continue;
|
|
64607
|
+
if (!subpath)
|
|
64608
|
+
return true;
|
|
64609
|
+
if (typeof obj === "object" && obj?.[subpath] !== undefined)
|
|
64610
|
+
return true;
|
|
64611
|
+
}
|
|
64612
|
+
return false;
|
|
64613
|
+
};
|
|
64614
|
+
const skipIfExisting = (remotePath, subpath) => !!rehashFilter?.missingOnly && hasEntry(remotePath, subpath);
|
|
64615
|
+
let scriptPaths;
|
|
64616
|
+
let flowFolders;
|
|
64617
|
+
let appPaths;
|
|
64618
|
+
if (rehashFilter?.localFiles) {
|
|
64619
|
+
const cat = categorizeLocalFiles(rehashFilter.localFiles);
|
|
64620
|
+
scriptPaths = cat.scripts;
|
|
64621
|
+
flowFolders = cat.flowFolders;
|
|
64622
|
+
appPaths = cat.appPaths.map((p) => ({
|
|
64623
|
+
folder: p.substring(0, p.lastIndexOf(SEP8)),
|
|
64624
|
+
rawApp: p.endsWith(SEP8 + "raw_app.yaml")
|
|
64625
|
+
}));
|
|
64626
|
+
} else {
|
|
64627
|
+
scriptPaths = await walkLocalScripts(codebases, ignore);
|
|
64628
|
+
flowFolders = await walkLocalFlowFolders(ignore);
|
|
64629
|
+
appPaths = await walkLocalAppItems(ignore);
|
|
64630
|
+
}
|
|
64631
|
+
const stubWorkspace = {};
|
|
64632
|
+
const rehashOpts = { ...opts, rehashOnly: true };
|
|
64633
|
+
if (!rehashFilter?.skipScripts) {
|
|
64634
|
+
for (const e of scriptPaths) {
|
|
64635
|
+
const remotePath = scriptPathToRemotePath(e);
|
|
64636
|
+
if (!inFilter(remotePath))
|
|
64637
|
+
continue;
|
|
64638
|
+
if (rehashFilter?.missingOnly) {
|
|
64639
|
+
if (skipIfExisting(remotePath) || skipIfExisting(remotePath, "__script_hash"))
|
|
64640
|
+
continue;
|
|
64641
|
+
}
|
|
64642
|
+
try {
|
|
64643
|
+
await generateScriptMetadataInternal(e, stubWorkspace, rehashOpts, false, true, {}, codebases, false);
|
|
64644
|
+
counts.scripts++;
|
|
64645
|
+
} catch (err) {
|
|
64646
|
+
warn(`Skipping ${e}: ${err instanceof Error ? err.message : err}`);
|
|
64647
|
+
}
|
|
64648
|
+
}
|
|
64649
|
+
}
|
|
64650
|
+
if (!rehashFilter?.skipFlows) {
|
|
64651
|
+
for (const f of flowFolders) {
|
|
64652
|
+
if (!inFilter(f))
|
|
64653
|
+
continue;
|
|
64654
|
+
if (rehashFilter?.missingOnly) {
|
|
64655
|
+
const folderNormalized = f.replaceAll(SEP8, "/");
|
|
64656
|
+
if (skipIfExisting(folderNormalized, "__flow_hash"))
|
|
64657
|
+
continue;
|
|
64658
|
+
}
|
|
64659
|
+
try {
|
|
64660
|
+
await generateFlowLockInternal(f, false, stubWorkspace, rehashOpts, false, true);
|
|
64661
|
+
counts.flows++;
|
|
64662
|
+
} catch (err) {
|
|
64663
|
+
warn(`Skipping ${f}: ${err instanceof Error ? err.message : err}`);
|
|
64664
|
+
}
|
|
64665
|
+
}
|
|
64666
|
+
}
|
|
64667
|
+
if (!rehashFilter?.skipApps) {
|
|
64668
|
+
for (const { folder: appFolder, rawApp } of appPaths) {
|
|
64669
|
+
if (!inFilter(appFolder))
|
|
64670
|
+
continue;
|
|
64671
|
+
if (rehashFilter?.missingOnly) {
|
|
64672
|
+
const folderNormalized = appFolder.replaceAll(SEP8, "/");
|
|
64673
|
+
if (skipIfExisting(folderNormalized, "__app_hash"))
|
|
64674
|
+
continue;
|
|
64675
|
+
}
|
|
64676
|
+
try {
|
|
64677
|
+
await generateAppLocksInternal(appFolder, rawApp, false, stubWorkspace, rehashOpts, false, true);
|
|
64678
|
+
counts.apps++;
|
|
64679
|
+
} catch (err) {
|
|
64680
|
+
warn(`Skipping ${appFolder}: ${err instanceof Error ? err.message : err}`);
|
|
64681
|
+
}
|
|
64682
|
+
}
|
|
64683
|
+
}
|
|
64684
|
+
if (counts.scripts + counts.flows + counts.apps > 0 || !rehashFilter?.missingOnly) {
|
|
64685
|
+
info(`Rehashed ${colors.bold(String(counts.scripts))} script(s), ` + `${colors.bold(String(counts.flows))} flow(s), ` + `${colors.bold(String(counts.apps))} app(s) from disk.`);
|
|
64686
|
+
}
|
|
64687
|
+
return counts;
|
|
64688
|
+
}
|
|
64689
|
+
async function generateMetadata2(opts, folder) {
|
|
64690
|
+
if (folder === "") {
|
|
64691
|
+
folder = undefined;
|
|
64692
|
+
}
|
|
64693
|
+
const workspace = await resolveWorkspace(opts);
|
|
64694
|
+
await requireLogin(opts);
|
|
64695
|
+
opts = await mergeConfigWithConfigFile(opts);
|
|
64696
|
+
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(false);
|
|
64697
|
+
const codebases = await listSyncCodebases(opts);
|
|
64698
|
+
const ignore = await ignoreF(opts);
|
|
64699
|
+
const skipScripts = opts.skipScripts ?? false;
|
|
64700
|
+
const skipFlows = opts.skipFlows ?? opts.schemaOnly ?? false;
|
|
64701
|
+
const skipApps = opts.skipApps ?? opts.schemaOnly ?? false;
|
|
64702
|
+
const checking = [];
|
|
64703
|
+
if (!skipScripts)
|
|
64704
|
+
checking.push("scripts");
|
|
64705
|
+
if (!skipFlows)
|
|
64706
|
+
checking.push("flows");
|
|
64707
|
+
if (!skipApps)
|
|
64708
|
+
checking.push("apps");
|
|
64709
|
+
if (checking.length === 0) {
|
|
64710
|
+
info(colors.yellow("Nothing to check (all types skipped)"));
|
|
64711
|
+
return;
|
|
64712
|
+
}
|
|
64713
|
+
info(`Checking ${checking.join(", ")}...`);
|
|
64714
|
+
const tree = new DoubleLinkedDependencyTree;
|
|
64715
|
+
tree.setWorkspaceDeps(rawWorkspaceDependencies);
|
|
64716
|
+
if (!skipScripts) {
|
|
64717
|
+
for (const e of await walkLocalScripts(codebases, ignore)) {
|
|
64718
|
+
await generateScriptMetadataInternal(e, workspace, opts, true, true, rawWorkspaceDependencies, codebases, false, tree);
|
|
64719
|
+
}
|
|
64720
|
+
}
|
|
64721
|
+
if (!skipFlows) {
|
|
64722
|
+
for (const flowFolder of await walkLocalFlowFolders(ignore)) {
|
|
64723
|
+
await generateFlowLockInternal(flowFolder, true, workspace, opts, false, true, tree);
|
|
64724
|
+
}
|
|
64725
|
+
}
|
|
64726
|
+
if (!skipApps) {
|
|
64727
|
+
for (const { folder: appFolder, rawApp } of await walkLocalAppItems(ignore)) {
|
|
64728
|
+
await generateAppLocksInternal(appFolder, rawApp, true, workspace, opts, false, true, tree);
|
|
64729
|
+
}
|
|
64730
|
+
}
|
|
64731
|
+
tree.propagateStaleness();
|
|
64732
|
+
try {
|
|
64733
|
+
await uploadScripts(tree, workspace);
|
|
64734
|
+
} catch (e) {
|
|
64735
|
+
warn(colors.yellow(`Failed to upload scripts to temp storage (backend may be too old): ${e}. ` + `Locks will be generated using deployed script versions only — locally modified ` + `relative imports may not be reflected.`));
|
|
64736
|
+
}
|
|
64737
|
+
const staleItems = [];
|
|
64738
|
+
const seenFolders = new Set;
|
|
64739
|
+
for (const p of tree.allPaths()) {
|
|
64740
|
+
const staleReason = tree.getStaleReason(p);
|
|
64741
|
+
if (!staleReason)
|
|
64742
|
+
continue;
|
|
64743
|
+
const itemType = tree.getItemType(p);
|
|
64744
|
+
const itemFolder = tree.getFolder(p);
|
|
64745
|
+
if (itemType === "dependencies") {
|
|
64746
|
+
staleItems.push({ type: itemType, path: p, folder: itemFolder, staleReason });
|
|
64747
|
+
} else if (itemType === "inline_script") {
|
|
64748
|
+
continue;
|
|
64749
|
+
} else if (itemType === "script") {
|
|
64750
|
+
const originalPath = tree.getOriginalPath(p);
|
|
64751
|
+
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, staleReason });
|
|
64752
|
+
} else if (!seenFolders.has(itemFolder)) {
|
|
64753
|
+
seenFolders.add(itemFolder);
|
|
64754
|
+
const originalPath = tree.getOriginalPath(p);
|
|
64755
|
+
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, isRawApp: tree.getIsRawApp(p), staleReason });
|
|
64756
|
+
}
|
|
64757
|
+
}
|
|
64758
|
+
let filteredItems = staleItems;
|
|
64759
|
+
if (folder) {
|
|
64760
|
+
folder = folder.replaceAll("\\", "/");
|
|
64761
|
+
if (folder.endsWith("/")) {
|
|
64762
|
+
folder = folder.substring(0, folder.length - 1);
|
|
64763
|
+
}
|
|
64764
|
+
const folderNoExt = folder.replace(/\.[^/.]+$/, "");
|
|
64765
|
+
const isInsideFolder = (item) => {
|
|
64766
|
+
const normalizedFolder = item.folder.replaceAll("\\", "/");
|
|
64767
|
+
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
64768
|
+
return normalizedFolder === folder || normalizedFolder.startsWith(folder + "/") || normalizedPath === folder || normalizedPath === folderNoExt;
|
|
64769
|
+
};
|
|
64770
|
+
const isPathInFolder = (p) => p.startsWith(folder + "/") || p === folder || p === folderNoExt;
|
|
64771
|
+
const touchesFolder = (treePath) => {
|
|
64772
|
+
if (isPathInFolder(treePath))
|
|
64773
|
+
return true;
|
|
64774
|
+
let found = false;
|
|
64775
|
+
tree.traverseTransitive(treePath, (importPath) => {
|
|
64776
|
+
if (isPathInFolder(importPath)) {
|
|
64777
|
+
found = true;
|
|
64778
|
+
return true;
|
|
64779
|
+
}
|
|
64780
|
+
});
|
|
64781
|
+
return found;
|
|
64782
|
+
};
|
|
64783
|
+
const isRelevant = (item) => {
|
|
64784
|
+
if (isInsideFolder(item))
|
|
64785
|
+
return true;
|
|
64786
|
+
if (item.type === "dependencies")
|
|
64787
|
+
return true;
|
|
64788
|
+
const treePath = (item.type === "script" ? item.path.replace(/\.[^/.]+$/, "") : item.folder).replaceAll("\\", "/");
|
|
64789
|
+
return touchesFolder(treePath);
|
|
64790
|
+
};
|
|
64791
|
+
if (opts.strictFolderBoundaries) {
|
|
64792
|
+
filteredItems = staleItems.filter(isInsideFolder);
|
|
64793
|
+
const excludedStale = staleItems.filter((item) => !isInsideFolder(item) && isRelevant(item) && item.type !== "dependencies");
|
|
64794
|
+
for (const item of excludedStale) {
|
|
64795
|
+
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
64796
|
+
warn(colors.yellow(`Warning: ${normalizedPath} depends on something inside "${folder}" but is outside it — skipped due to --strict-folder-boundaries. Next generate-metadata will not detect it as stale.`));
|
|
64797
|
+
}
|
|
64798
|
+
} else {
|
|
64799
|
+
filteredItems = staleItems.filter(isRelevant);
|
|
64800
|
+
}
|
|
64801
|
+
}
|
|
64802
|
+
if (filteredItems.length === 0) {
|
|
64803
|
+
info(colors.green("All metadata up-to-date"));
|
|
64804
|
+
return;
|
|
64805
|
+
}
|
|
64806
|
+
const scripts = filteredItems.filter((i) => i.type === "script");
|
|
64807
|
+
const flows = filteredItems.filter((i) => i.type === "flow");
|
|
64808
|
+
const apps2 = filteredItems.filter((i) => i.type === "app");
|
|
64809
|
+
const deps = filteredItems.filter((i) => i.type === "dependencies");
|
|
64810
|
+
info("");
|
|
64811
|
+
info(`Found ${colors.bold(String(filteredItems.length))} item(s) with stale metadata:`);
|
|
64812
|
+
const printItems = (label, items) => {
|
|
64813
|
+
if (items.length === 0)
|
|
64814
|
+
return;
|
|
64815
|
+
info(` ${label} (${items.length}):`);
|
|
64816
|
+
for (const item of items) {
|
|
64817
|
+
const reason = item.staleReason ? colors.dim(colors.white(` — ${item.staleReason}`)) : "";
|
|
64818
|
+
info(` ~ ${item.path}` + reason);
|
|
64819
|
+
}
|
|
64820
|
+
};
|
|
64821
|
+
printItems("Workspace dependencies", deps);
|
|
64822
|
+
printItems("Scripts", scripts);
|
|
64823
|
+
printItems("Flows", flows);
|
|
64824
|
+
printItems("Apps", apps2);
|
|
64825
|
+
if (opts.dryRun) {
|
|
64826
|
+
return;
|
|
64827
|
+
}
|
|
64828
|
+
info("");
|
|
64829
|
+
const isInteractive = process.stdin.isTTY ?? false;
|
|
64830
|
+
if (!opts.yes && isInteractive && !await Confirm.prompt({
|
|
64831
|
+
message: "Update metadata?",
|
|
64832
|
+
default: true
|
|
64833
|
+
})) {
|
|
64834
|
+
return;
|
|
64835
|
+
}
|
|
64836
|
+
info("");
|
|
64837
|
+
const mismatchedWorkspaceDeps = tree.getMismatchedWorkspaceDeps();
|
|
64838
|
+
const total = filteredItems.length - deps.length;
|
|
64839
|
+
const maxWidth = `[${total}/${total}]`.length;
|
|
64840
|
+
let current = 0;
|
|
64841
|
+
const formatProgress = (n) => {
|
|
64842
|
+
return colors.dim(colors.white(`[${n}/${total}]`.padEnd(maxWidth, " ")));
|
|
64843
|
+
};
|
|
64844
|
+
const errors = [];
|
|
64845
|
+
for (const item of scripts) {
|
|
64846
|
+
current++;
|
|
64847
|
+
info(`${formatProgress(current)} script ${item.path}`);
|
|
64848
|
+
try {
|
|
64849
|
+
await generateScriptMetadataInternal(item.path, workspace, opts, false, true, mismatchedWorkspaceDeps, codebases, false, tree);
|
|
64850
|
+
} catch (e) {
|
|
64851
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64852
|
+
errors.push({ path: item.path, error: msg });
|
|
64853
|
+
error(` Failed: ${msg}`);
|
|
64854
|
+
}
|
|
64855
|
+
}
|
|
64856
|
+
for (const item of flows) {
|
|
64857
|
+
current++;
|
|
64858
|
+
try {
|
|
64859
|
+
const result = await generateFlowLockInternal(item.folder.replaceAll("/", SEP8), false, workspace, opts, false, true, tree);
|
|
64860
|
+
const flowResult = result;
|
|
64861
|
+
const scriptsInfo = flowResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${flowResult.updatedScripts.join(", ")}`)) : "";
|
|
64862
|
+
info(`${formatProgress(current)} flow ${item.path}${scriptsInfo}`);
|
|
64863
|
+
} catch (e) {
|
|
64864
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64865
|
+
errors.push({ path: item.path, error: msg });
|
|
64866
|
+
info(`${formatProgress(current)} flow ${item.path}`);
|
|
64867
|
+
error(` Failed: ${msg}`);
|
|
64868
|
+
}
|
|
64869
|
+
}
|
|
64870
|
+
for (const item of apps2) {
|
|
64871
|
+
current++;
|
|
64872
|
+
try {
|
|
64873
|
+
const result = await generateAppLocksInternal(item.folder.replaceAll("/", SEP8), item.isRawApp, false, workspace, opts, false, true, tree);
|
|
64874
|
+
const appResult = result;
|
|
64875
|
+
const scriptsInfo = appResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${appResult.updatedScripts.join(", ")}`)) : "";
|
|
64876
|
+
info(`${formatProgress(current)} app ${item.path}${scriptsInfo}`);
|
|
64877
|
+
} catch (e) {
|
|
64878
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64879
|
+
errors.push({ path: item.path, error: msg });
|
|
64880
|
+
info(`${formatProgress(current)} app ${item.path}`);
|
|
64881
|
+
error(` Failed: ${msg}`);
|
|
64882
|
+
}
|
|
64883
|
+
}
|
|
64884
|
+
const allStaleDeps = staleItems.filter((i) => i.type === "dependencies");
|
|
64885
|
+
await tree.persistDepsHashes(allStaleDeps.map((d) => d.path));
|
|
64886
|
+
const succeeded = total - errors.length;
|
|
64887
|
+
info("");
|
|
64888
|
+
if (errors.length > 0) {
|
|
64889
|
+
info(`Done. Updated ${colors.bold(String(succeeded))}/${total} item(s). ${colors.red(String(errors.length) + " failed")}:`);
|
|
64890
|
+
for (const { path: path11, error: error2 } of errors) {
|
|
64891
|
+
error(` ${path11}: ${error2}`);
|
|
64892
|
+
}
|
|
64893
|
+
process.exitCode = 1;
|
|
64894
|
+
} else {
|
|
64895
|
+
info(`Done. Updated ${colors.bold(String(total))} item(s).`);
|
|
64896
|
+
}
|
|
64897
|
+
}
|
|
64898
|
+
async function rehashCommand(opts, folder) {
|
|
64899
|
+
if (folder === "")
|
|
64900
|
+
folder = undefined;
|
|
64901
|
+
opts = await mergeConfigWithConfigFile(opts);
|
|
64902
|
+
await rehashOnly(opts, folder, {
|
|
64903
|
+
skipScripts: opts.skipScripts,
|
|
64904
|
+
skipFlows: opts.skipFlows,
|
|
64905
|
+
skipApps: opts.skipApps
|
|
64906
|
+
});
|
|
64907
|
+
}
|
|
64908
|
+
var command7, generate_metadata_default;
|
|
64909
|
+
var init_generate_metadata = __esm(async () => {
|
|
64910
|
+
init_mod3();
|
|
64911
|
+
init_colors2();
|
|
64912
|
+
init_log();
|
|
64913
|
+
await __promiseAll([
|
|
64914
|
+
init_confirm(),
|
|
64915
|
+
init_conf(),
|
|
64916
|
+
init_context(),
|
|
64917
|
+
init_auth(),
|
|
64918
|
+
init_metadata(),
|
|
64919
|
+
init_flow_metadata(),
|
|
64920
|
+
init_app_metadata(),
|
|
64921
|
+
init_sync(),
|
|
64922
|
+
init_script(),
|
|
64923
|
+
init_resource_folders(),
|
|
64924
|
+
init_codebase(),
|
|
64925
|
+
init_dependency_tree()
|
|
64926
|
+
]);
|
|
64927
|
+
command7 = 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("--strict-folder-boundaries", "Only update items inside the specified folder (requires folder argument)").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).command("rehash", new Command().description("Trust on-disk content; rewrite wmill-lock.yaml hashes without backend " + "trips or yaml/lock rewrites. Useful for bootstrapping missing lockfile " + "entries or recovering from older-CLI hash drift.").arguments("[folder:string]").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(rehashCommand));
|
|
64928
|
+
generate_metadata_default = command7;
|
|
64929
|
+
});
|
|
64930
|
+
|
|
64230
64931
|
// src/commands/sync/sync.ts
|
|
64231
64932
|
var exports_sync = {};
|
|
64232
64933
|
__export(exports_sync, {
|
|
@@ -64248,7 +64949,7 @@ __export(exports_sync, {
|
|
|
64248
64949
|
});
|
|
64249
64950
|
import { writeFile as writeFile7, readdir as readdir4, stat as stat7, rm, copyFile, mkdir as mkdir5 } from "node:fs/promises";
|
|
64250
64951
|
import * as path11 from "node:path";
|
|
64251
|
-
import { sep as
|
|
64952
|
+
import { sep as SEP9 } from "node:path";
|
|
64252
64953
|
function resolveWsNameFromBranch(opts, branchName) {
|
|
64253
64954
|
const match2 = findWorkspaceByGitBranch(opts.workspaces, branchName);
|
|
64254
64955
|
return match2 ? match2[0] : branchName;
|
|
@@ -64578,11 +65279,11 @@ function extractInlineScriptsForApps(key, rec, pathAssigner, toId, removeSchema)
|
|
|
64578
65279
|
const o = v;
|
|
64579
65280
|
const name = toId(key ?? "", rec);
|
|
64580
65281
|
const [basePathO, ext2] = pathAssigner.assignPath(name, o["language"]);
|
|
64581
|
-
const basePath = basePathO.replaceAll(
|
|
65282
|
+
const basePath = basePathO.replaceAll(SEP9, "/");
|
|
64582
65283
|
const r = [];
|
|
64583
65284
|
if (o["content"]) {
|
|
64584
65285
|
const content = o["content"];
|
|
64585
|
-
o["content"] = "!inline " + basePath.replaceAll(
|
|
65286
|
+
o["content"] = "!inline " + basePath.replaceAll(SEP9, "/") + ext2;
|
|
64586
65287
|
r.push({
|
|
64587
65288
|
path: basePath + ext2,
|
|
64588
65289
|
content
|
|
@@ -64590,7 +65291,7 @@ function extractInlineScriptsForApps(key, rec, pathAssigner, toId, removeSchema)
|
|
|
64590
65291
|
}
|
|
64591
65292
|
if (o["lock"] && o["lock"] != "") {
|
|
64592
65293
|
const lock = o["lock"];
|
|
64593
|
-
o["lock"] = "!inline " + basePath.replaceAll(
|
|
65294
|
+
o["lock"] = "!inline " + basePath.replaceAll(SEP9, "/") + "lock";
|
|
64594
65295
|
r.push({
|
|
64595
65296
|
path: basePath + "lock",
|
|
64596
65297
|
content: lock
|
|
@@ -64624,7 +65325,7 @@ function parseFileResourceTypeMap(raw) {
|
|
|
64624
65325
|
return { formatExtMap, filesetMap };
|
|
64625
65326
|
}
|
|
64626
65327
|
async function findFilesetResourceFile(changePath) {
|
|
64627
|
-
const filesetIdx = changePath.indexOf(".fileset" +
|
|
65328
|
+
const filesetIdx = changePath.indexOf(".fileset" + SEP9);
|
|
64628
65329
|
if (filesetIdx === -1) {
|
|
64629
65330
|
throw new Error(`Not a fileset resource path: ${changePath}`);
|
|
64630
65331
|
}
|
|
@@ -64724,12 +65425,12 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64724
65425
|
try {
|
|
64725
65426
|
const assigner = newPathAssigner(defaultTs, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
64726
65427
|
const inlineMapping = extractCurrentMapping(flow.value.modules, {}, flow.value.failure_module, flow.value.preprocessor_module);
|
|
64727
|
-
inlineScripts = extractInlineScripts(flow.value.modules, inlineMapping,
|
|
65428
|
+
inlineScripts = extractInlineScripts(flow.value.modules, inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
64728
65429
|
if (flow.value.failure_module) {
|
|
64729
|
-
inlineScripts.push(...extractInlineScripts([flow.value.failure_module], inlineMapping,
|
|
65430
|
+
inlineScripts.push(...extractInlineScripts([flow.value.failure_module], inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
64730
65431
|
}
|
|
64731
65432
|
if (flow.value.preprocessor_module) {
|
|
64732
|
-
inlineScripts.push(...extractInlineScripts([flow.value.preprocessor_module], inlineMapping,
|
|
65433
|
+
inlineScripts.push(...extractInlineScripts([flow.value.preprocessor_module], inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
64733
65434
|
}
|
|
64734
65435
|
} catch (error2) {
|
|
64735
65436
|
error(`Failed to extract inline scripts for flow at path: ${p}`);
|
|
@@ -64939,10 +65640,10 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64939
65640
|
const hasModules = parsed["modules"] && Object.keys(parsed["modules"]).length > 0;
|
|
64940
65641
|
if (parsed["lock"] && parsed["lock"] != "" && parsed["codebase"] == undefined) {
|
|
64941
65642
|
if (hasModules) {
|
|
64942
|
-
const scriptBase = removeSuffix(removeSuffix(p.replaceAll(
|
|
65643
|
+
const scriptBase = removeSuffix(removeSuffix(p.replaceAll(SEP9, "/"), ".json"), ".script");
|
|
64943
65644
|
parsed["lock"] = "!inline " + scriptBase + getModuleFolderSuffix() + "/script.lock";
|
|
64944
65645
|
} else {
|
|
64945
|
-
parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(
|
|
65646
|
+
parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(SEP9, "/"), ".json") + ".lock";
|
|
64946
65647
|
}
|
|
64947
65648
|
} else if (parsed["lock"] == "") {
|
|
64948
65649
|
parsed["lock"] = "";
|
|
@@ -64972,9 +65673,9 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64972
65673
|
const formatExtension = resourceTypeToFormatExtension[resourceType];
|
|
64973
65674
|
const isFileset = resourceTypeToIsFileset[resourceType] ?? false;
|
|
64974
65675
|
if (isFileset) {
|
|
64975
|
-
parsed["value"] = "!inline_fileset " + removeSuffix(p.replaceAll(
|
|
65676
|
+
parsed["value"] = "!inline_fileset " + removeSuffix(p.replaceAll(SEP9, "/"), ".resource.json") + ".fileset";
|
|
64976
65677
|
} else if (formatExtension) {
|
|
64977
|
-
parsed["value"]["content"] = "!inline " + removeSuffix(p.replaceAll(
|
|
65678
|
+
parsed["value"]["content"] = "!inline " + removeSuffix(p.replaceAll(SEP9, "/"), ".resource.json") + ".resource.file." + formatExtension;
|
|
64978
65679
|
}
|
|
64979
65680
|
return useYaml ? import_yaml11.stringify(parsed, yamlOptions) : JSON.stringify(parsed, null, 2);
|
|
64980
65681
|
}
|
|
@@ -65141,7 +65842,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
65141
65842
|
}
|
|
65142
65843
|
};
|
|
65143
65844
|
}
|
|
65144
|
-
return _internal_folder("." +
|
|
65845
|
+
return _internal_folder("." + SEP9, zip);
|
|
65145
65846
|
}
|
|
65146
65847
|
async function* readDirRecursiveWithIgnore2(ignore, root) {
|
|
65147
65848
|
const stack = [
|
|
@@ -65160,7 +65861,7 @@ async function* readDirRecursiveWithIgnore2(ignore, root) {
|
|
|
65160
65861
|
yield e;
|
|
65161
65862
|
for await (const e2 of e.c()) {
|
|
65162
65863
|
if (e2.isDirectory) {
|
|
65163
|
-
const dirName = e2.path.split(
|
|
65864
|
+
const dirName = e2.path.split(SEP9).pop();
|
|
65164
65865
|
if (dirName == "node_modules" || dirName == ".claude" || dirName?.startsWith(".")) {
|
|
65165
65866
|
continue;
|
|
65166
65867
|
}
|
|
@@ -65183,7 +65884,7 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
|
|
|
65183
65884
|
for await (const entry of readDirRecursiveWithIgnore2(ignore, els)) {
|
|
65184
65885
|
if (entry.isDirectory) {
|
|
65185
65886
|
if (!isRemote) {
|
|
65186
|
-
const dirName = entry.path.split(
|
|
65887
|
+
const dirName = entry.path.split(SEP9).pop() ?? "";
|
|
65187
65888
|
if (hasWrongFormatSuffix(dirName)) {
|
|
65188
65889
|
wrongFormatPaths.push(entry.path);
|
|
65189
65890
|
}
|
|
@@ -65228,7 +65929,7 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
|
|
|
65228
65929
|
}
|
|
65229
65930
|
}
|
|
65230
65931
|
if (isRawAppFile(path12)) {
|
|
65231
|
-
const suffix = path12.split(getFolderSuffix("raw_app") +
|
|
65932
|
+
const suffix = path12.split(getFolderSuffix("raw_app") + SEP9).pop();
|
|
65232
65933
|
if (suffix?.startsWith("dist/") || suffix == "wmill.d.ts" || suffix == "package-lock.json" || suffix == "DATATABLES.md") {
|
|
65233
65934
|
continue;
|
|
65234
65935
|
}
|
|
@@ -65499,7 +66200,8 @@ async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetada
|
|
|
65499
66200
|
}
|
|
65500
66201
|
return a.path.localeCompare(b.path);
|
|
65501
66202
|
});
|
|
65502
|
-
|
|
66203
|
+
const localMap = isEls1Remote ? m2 : m1;
|
|
66204
|
+
return { changes, localMap };
|
|
65503
66205
|
}
|
|
65504
66206
|
function getOrderFromPath(p) {
|
|
65505
66207
|
const typ = getTypeStrFromPath(p);
|
|
@@ -65728,7 +66430,7 @@ async function pull(opts) {
|
|
|
65728
66430
|
const zipFile = await downloadZip(workspace, opts.plainSecrets, opts.skipVariables, opts.skipResources, opts.skipResourceTypes, opts.skipSecrets, opts.includeSchedules, opts.includeTriggers, opts.includeUsers, opts.includeGroups, opts.includeSettings, opts.includeKey, opts.skipWorkspaceDependencies, opts.defaultTs);
|
|
65729
66431
|
const remote = ZipFSElement(zipFile, !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, true, parseSyncBehavior(opts.syncBehavior) >= 1);
|
|
65730
66432
|
const local = !opts.stateful ? await FSFSElement(process.cwd(), codebases, true) : await FSFSElement(path11.join(process.cwd(), ".wmill"), [], true);
|
|
65731
|
-
const changes = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, wsNameForFiles, true);
|
|
66433
|
+
const { changes, localMap } = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, wsNameForFiles, true);
|
|
65732
66434
|
info(`remote (${workspace.name}) -> local: ${changes.length} changes to apply`);
|
|
65733
66435
|
if (opts.dryRun && opts.jsonOutput) {
|
|
65734
66436
|
const result = {
|
|
@@ -65892,6 +66594,31 @@ Done! All ${changes.length} changes applied locally and wmill-lock.yaml updated.
|
|
|
65892
66594
|
} else if (opts.jsonOutput) {
|
|
65893
66595
|
console.log(JSON.stringify({ success: true, message: "No changes to apply", total: 0 }, null, 2));
|
|
65894
66596
|
}
|
|
66597
|
+
if (!opts.jsonOutput && !opts.dryRun) {
|
|
66598
|
+
try {
|
|
66599
|
+
const { rehashOnly: rehashOnly2 } = await init_generate_metadata().then(() => exports_generate_metadata);
|
|
66600
|
+
const postPullPaths = new Set(Object.keys(localMap));
|
|
66601
|
+
for (const change of changes) {
|
|
66602
|
+
if (change.name === "added")
|
|
66603
|
+
postPullPaths.add(change.path);
|
|
66604
|
+
else if (change.name === "deleted")
|
|
66605
|
+
postPullPaths.delete(change.path);
|
|
66606
|
+
}
|
|
66607
|
+
const filled = await rehashOnly2(opts, undefined, {
|
|
66608
|
+
missingOnly: true,
|
|
66609
|
+
localFiles: postPullPaths
|
|
66610
|
+
});
|
|
66611
|
+
const total = filled.scripts + filled.flows + filled.apps;
|
|
66612
|
+
if (total > 0) {
|
|
66613
|
+
info(colors.gray(`Auto-filled ${total} missing lockfile entr${total === 1 ? "y" : "ies"} (${filled.scripts} script, ${filled.flows} flow, ${filled.apps} app) from disk.`));
|
|
66614
|
+
}
|
|
66615
|
+
} catch (e) {
|
|
66616
|
+
if (e instanceof UnknownLockVersionError || e instanceof MalformedLockfileError) {
|
|
66617
|
+
throw e;
|
|
66618
|
+
}
|
|
66619
|
+
warn(colors.yellow(`Could not auto-fill missing lockfile entries: ${e instanceof Error ? e.message : e}`));
|
|
66620
|
+
}
|
|
66621
|
+
}
|
|
65895
66622
|
try {
|
|
65896
66623
|
await pullSharedUi(workspace.workspaceId);
|
|
65897
66624
|
} catch (e) {
|
|
@@ -66020,7 +66747,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66020
66747
|
} catch {}
|
|
66021
66748
|
const remote = ZipFSElement(await downloadZip(workspace, opts.plainSecrets, opts.skipVariables, opts.skipResources, opts.skipResourceTypes, opts.skipSecrets, opts.includeSchedules, opts.includeTriggers, opts.includeUsers, opts.includeGroups, opts.includeSettings, opts.includeKey, opts.skipWorkspaceDependencies, opts.defaultTs), !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, false, parseSyncBehavior(opts.syncBehavior) >= 1);
|
|
66022
66749
|
const local = await FSFSElement(path11.join(process.cwd(), ""), codebases, false);
|
|
66023
|
-
const changes = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, wsNameForFiles, false);
|
|
66750
|
+
const { changes } = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, wsNameForFiles, false);
|
|
66024
66751
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
66025
66752
|
const tracker = await buildTracker(changes);
|
|
66026
66753
|
const autoRegenerate = !!opts.autoMetadata;
|
|
@@ -66127,7 +66854,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66127
66854
|
if (changes.length > 0) {
|
|
66128
66855
|
const folderNames = new Set;
|
|
66129
66856
|
for (const change of changes) {
|
|
66130
|
-
const parts = change.path.split(
|
|
66857
|
+
const parts = change.path.split(SEP9);
|
|
66131
66858
|
if (parts.length >= 3 && parts[0] === "f" && change.name !== "deleted") {
|
|
66132
66859
|
folderNames.add(parts[1]);
|
|
66133
66860
|
}
|
|
@@ -66160,7 +66887,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66160
66887
|
const userIsAdmin = user.is_admin;
|
|
66161
66888
|
const msg = `${userIsAdmin ? "Warning: " : ""}Missing folder.meta.yaml for:
|
|
66162
66889
|
${folderList}
|
|
66163
|
-
|
|
66890
|
+
Run 'wmill folder add-missing' to create them locally, then push again.`;
|
|
66164
66891
|
if (!userIsAdmin) {
|
|
66165
66892
|
if (opts.jsonOutput) {
|
|
66166
66893
|
console.log(JSON.stringify({ success: false, error: "missing_folders", missing_folders: missingFolders, message: msg }, null, 2));
|
|
@@ -66242,7 +66969,7 @@ ${folderList}
|
|
|
66242
66969
|
};
|
|
66243
66970
|
await preCheckPermissionedAs(changes, user.email, userIsAdminOrDeployer, opts.acceptOverridingPermissionedAsWithSelf ?? false, !!process.stdin.isTTY);
|
|
66244
66971
|
} else if (folderDefaultAnnotations && folderDefaultAnnotations.size > 0) {
|
|
66245
|
-
warn(colors.yellow(`This workspace has folder default_permissioned_as rules that affect ${folderDefaultAnnotations.size} item(s) being pushed,
|
|
66972
|
+
warn(colors.yellow(`This workspace has folder default_permissioned_as rules that affect ${folderDefaultAnnotations.size} item(s) being pushed, but syncBehavior is not set in wmill.yaml. Add 'syncBehavior: v1' to enable ownership preservation on update and on_behalf_of stripping on pull.`));
|
|
66246
66973
|
}
|
|
66247
66974
|
if (!opts.yes && !await Confirm.prompt({
|
|
66248
66975
|
message: `Do you want to apply these ${changes.length} changes to the remote?`,
|
|
@@ -66273,7 +67000,7 @@ ${folderList}
|
|
|
66273
67000
|
parallelizationFactor = 1;
|
|
66274
67001
|
}
|
|
66275
67002
|
const allGrouped = Array.from(groupedChanges.entries());
|
|
66276
|
-
const isFolderMetaGroup = ([basePath]) => basePath.endsWith(`${
|
|
67003
|
+
const isFolderMetaGroup = ([basePath]) => basePath.endsWith(`${SEP9}folder`) || basePath === "folder";
|
|
66277
67004
|
const folderMetaGroups = allGrouped.filter(isFolderMetaGroup);
|
|
66278
67005
|
const groupedChangesArray = allGrouped.filter((g) => !isFolderMetaGroup(g));
|
|
66279
67006
|
info(`found changes for ${allGrouped.length} items with a total of ${allGrouped.reduce((acc, [_, changes2]) => acc + changes2.length, 0)} files to process`);
|
|
@@ -66289,7 +67016,7 @@ ${folderList}
|
|
|
66289
67016
|
while (pool.size < effectiveParallelism() && queue.length > 0) {
|
|
66290
67017
|
const [groupBasePath, initialChanges] = queue.shift();
|
|
66291
67018
|
let changes2 = initialChanges;
|
|
66292
|
-
const isFolderGroup = groupBasePath.endsWith(`${
|
|
67019
|
+
const isFolderGroup = groupBasePath.endsWith(`${SEP9}folder`) || groupBasePath === "folder";
|
|
66293
67020
|
const promise = (async () => {
|
|
66294
67021
|
const alreadySynced = [];
|
|
66295
67022
|
const deletedVarsResPaths = [];
|
|
@@ -66421,7 +67148,7 @@ ${folderList}
|
|
|
66421
67148
|
info(`Deleting ${typ} ${change.path}`);
|
|
66422
67149
|
}
|
|
66423
67150
|
const workspaceId = workspace.workspaceId;
|
|
66424
|
-
const target = change.path.replaceAll(
|
|
67151
|
+
const target = change.path.replaceAll(SEP9, "/");
|
|
66425
67152
|
switch (typ) {
|
|
66426
67153
|
case "script": {
|
|
66427
67154
|
await archiveScriptByPath({
|
|
@@ -66433,7 +67160,7 @@ ${folderList}
|
|
|
66433
67160
|
case "folder":
|
|
66434
67161
|
await deleteFolder({
|
|
66435
67162
|
workspace: workspaceId,
|
|
66436
|
-
name: change.path.split(
|
|
67163
|
+
name: change.path.split(SEP9)[1]
|
|
66437
67164
|
});
|
|
66438
67165
|
break;
|
|
66439
67166
|
case "resource": {
|
|
@@ -66732,14 +67459,14 @@ Done! All ${changes.length} changes pushed to the remote workspace ${workspace.w
|
|
|
66732
67459
|
}
|
|
66733
67460
|
}
|
|
66734
67461
|
var import_yaml11, branchDeprecationWarned = false, yamlOptions, isNotWmillFile = (p, isDirectory2) => {
|
|
66735
|
-
if (p.endsWith(
|
|
67462
|
+
if (p.endsWith(SEP9)) {
|
|
66736
67463
|
return false;
|
|
66737
67464
|
}
|
|
66738
|
-
if (p.startsWith("ui" +
|
|
67465
|
+
if (p.startsWith("ui" + SEP9)) {
|
|
66739
67466
|
return true;
|
|
66740
67467
|
}
|
|
66741
67468
|
if (isDirectory2) {
|
|
66742
|
-
return !p.startsWith("u" +
|
|
67469
|
+
return !p.startsWith("u" + SEP9) && !p.startsWith("f" + SEP9) && !p.startsWith("g" + SEP9) && !p.startsWith("users" + SEP9) && !p.startsWith("groups" + SEP9) && !p.startsWith("dependencies" + SEP9);
|
|
66743
67470
|
}
|
|
66744
67471
|
if (isScriptModulePath(p)) {
|
|
66745
67472
|
return false;
|
|
@@ -66747,16 +67474,16 @@ var import_yaml11, branchDeprecationWarned = false, yamlOptions, isNotWmillFile
|
|
|
66747
67474
|
try {
|
|
66748
67475
|
const typ = getTypeStrFromPath(p);
|
|
66749
67476
|
if (typ == "resource-type" || typ == "settings" || typ == "encryption_key") {
|
|
66750
|
-
return p.includes(
|
|
67477
|
+
return p.includes(SEP9);
|
|
66751
67478
|
} else {
|
|
66752
|
-
return !p.startsWith("u" +
|
|
67479
|
+
return !p.startsWith("u" + SEP9) && !p.startsWith("f" + SEP9) && !p.startsWith("g" + SEP9) && !p.startsWith("users" + SEP9) && !p.startsWith("groups" + SEP9) && !p.startsWith("dependencies" + SEP9);
|
|
66753
67480
|
}
|
|
66754
67481
|
} catch {
|
|
66755
67482
|
return true;
|
|
66756
67483
|
}
|
|
66757
67484
|
}, isWhitelisted = (p) => {
|
|
66758
|
-
return p == "." +
|
|
66759
|
-
},
|
|
67485
|
+
return p == "." + SEP9 || p == "" || p == "u" || p == "f" || p == "g" || p == "ui" || p == "users" || p == "groups" || p == "dependencies";
|
|
67486
|
+
}, command8, sync_default;
|
|
66760
67487
|
var init_sync = __esm(async () => {
|
|
66761
67488
|
init_colors2();
|
|
66762
67489
|
init_mod3();
|
|
@@ -66798,8 +67525,8 @@ var init_sync = __esm(async () => {
|
|
|
66798
67525
|
aliasDuplicateObjects: false,
|
|
66799
67526
|
singleQuote: true
|
|
66800
67527
|
};
|
|
66801
|
-
|
|
66802
|
-
sync_default =
|
|
67528
|
+
command8 = new Command().description("sync local with a remote workspaces or the opposite (push or pull)").action(() => info("2 actions available, pull and push. Use -h to display help.")).command("pull").description("Pull any remote changes and apply them locally.").option("--yes", "Pull without needing confirmation").option("--dry-run", "Show changes that would be pulled without actually pushing").option("--plain-secrets", "Pull secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--include-secrets", "Include secrets in sync (overrides skipSecrets in wmill.yaml)").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Overrides wmill.yaml includes").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account. Overrides wmill.yaml excludes").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides").option("--branch, --env <branch:string>", "[Deprecated: use --workspace] Override the current git branch/environment").action(pull).command("push").description("Push any local changes and apply them remotely.").option("--yes", "Push without needing confirmation").option("--dry-run", "Show changes that would be pushed without actually pushing").option("--plain-secrets", "Push secrets as plain text").option("--json", "Use JSON instead of YAML").option("--skip-variables", "Skip syncing variables (including secrets)").option("--skip-secrets", "Skip syncing only secrets variables").option("--include-secrets", "Include secrets in sync (overrides skipSecrets in wmill.yaml)").option("--skip-resources", "Skip syncing resources").option("--skip-resource-types", "Skip syncing resource types").option("--skip-scripts", "Skip syncing scripts").option("--skip-flows", "Skip syncing flows").option("--skip-apps", "Skip syncing apps").option("--skip-folders", "Skip syncing folders").option("--skip-workspace-dependencies", "Skip syncing workspace dependencies").option("--include-schedules", "Include syncing schedules").option("--include-triggers", "Include syncing triggers").option("--include-users", "Include syncing users").option("--include-groups", "Include syncing groups").option("--include-settings", "Include syncing workspace settings").option("--include-key", "Include workspace encryption key").option("--skip-branch-validation", "Skip git branch validation and prompts").option("--json-output", "Output results in JSON format").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").option("--extra-includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy").option("--message <message:string>", "Include a message that will be added to all scripts/flows/apps updated during this push").option("--parallel <number>", "Number of changes to process in parallel").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when multiple repositories exist").option("--branch, --env <branch:string>", "[Deprecated: use --workspace] Override the current git branch/environment").option("--lint", "Run lint validation before pushing").option("--locks-required", "Fail if scripts or flow inline scripts that need locks have no locks").option("--auto-metadata", "Automatically regenerate stale metadata (locks and schemas) before pushing").option("--accept-overriding-permissioned-as-with-self", "Accept that items with a different permissioned_as will be updated with your own user").action(push4);
|
|
67529
|
+
sync_default = command8;
|
|
66803
67530
|
});
|
|
66804
67531
|
|
|
66805
67532
|
// windmill-utils-internal/src/parse/parse-schema.ts
|
|
@@ -67004,7 +67731,7 @@ var init_parse_schema = __esm(() => {
|
|
|
67004
67731
|
});
|
|
67005
67732
|
|
|
67006
67733
|
// src/utils/metadata.ts
|
|
67007
|
-
import { sep as
|
|
67734
|
+
import { sep as SEP10 } from "node:path";
|
|
67008
67735
|
import { writeFile as writeFile8, stat as stat8, rm as rm2, readdir as readdir5 } from "node:fs/promises";
|
|
67009
67736
|
import { readFileSync as readFileSync2, existsSync as existsSync6, readdirSync, statSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
67010
67737
|
import * as path12 from "node:path";
|
|
@@ -67098,7 +67825,7 @@ async function blueColor() {
|
|
|
67098
67825
|
}
|
|
67099
67826
|
async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRun, noStaleMessage, rawWorkspaceDependencies, codebases, justUpdateMetadataLock, tree) {
|
|
67100
67827
|
const isFolderLayout = isModuleEntryPoint(scriptPath);
|
|
67101
|
-
const remotePath =
|
|
67828
|
+
const remotePath = scriptPathToRemotePath(scriptPath);
|
|
67102
67829
|
const language = inferContentTypeFromFilePath(scriptPath, opts.defaultTs);
|
|
67103
67830
|
const metadataWithType = await parseMetadataFile(remotePath, undefined);
|
|
67104
67831
|
const scriptContent = await readTextFile(scriptPath);
|
|
@@ -67113,6 +67840,22 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67113
67840
|
moduleHashes = await computeModuleHashes(moduleFolderPath, opts.defaultTs, tree ? {} : rawWorkspaceDependencies, isFolderLayout);
|
|
67114
67841
|
}
|
|
67115
67842
|
const hasModuleHashes = Object.keys(moduleHashes).length > 0;
|
|
67843
|
+
if (opts.rehashOnly) {
|
|
67844
|
+
if (hasModuleHashes) {
|
|
67845
|
+
const sortedEntries = Object.entries(moduleHashes).sort(([a], [b]) => a.localeCompare(b));
|
|
67846
|
+
const metaHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
|
|
67847
|
+
await clearGlobalLock(remotePath);
|
|
67848
|
+
await updateMetadataGlobalLock(remotePath, metaHash, SCRIPT_TOP_HASH);
|
|
67849
|
+
for (const [modulePath, moduleHash] of Object.entries(moduleHashes)) {
|
|
67850
|
+
await updateMetadataGlobalLock(remotePath, moduleHash, modulePath);
|
|
67851
|
+
}
|
|
67852
|
+
} else {
|
|
67853
|
+
await clearGlobalLock(remotePath);
|
|
67854
|
+
await updateMetadataGlobalLock(remotePath, hash2);
|
|
67855
|
+
}
|
|
67856
|
+
return;
|
|
67857
|
+
}
|
|
67858
|
+
const conf = await readLockfile();
|
|
67116
67859
|
let checkHash = hash2;
|
|
67117
67860
|
let checkSubpath;
|
|
67118
67861
|
if (hasModuleHashes) {
|
|
@@ -67120,7 +67863,6 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67120
67863
|
checkHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
|
|
67121
67864
|
checkSubpath = SCRIPT_TOP_HASH;
|
|
67122
67865
|
}
|
|
67123
|
-
const conf = await readLockfile();
|
|
67124
67866
|
const isDirectlyStale = !await checkifMetadataUptodate(remotePath, checkHash, conf, checkSubpath);
|
|
67125
67867
|
if (tree) {
|
|
67126
67868
|
if (dryRun) {
|
|
@@ -67183,9 +67925,9 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67183
67925
|
}
|
|
67184
67926
|
} else {
|
|
67185
67927
|
if (isFolderLayout) {
|
|
67186
|
-
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(
|
|
67928
|
+
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP10, "/") + getModuleFolderSuffix() + "/script.lock";
|
|
67187
67929
|
} else {
|
|
67188
|
-
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(
|
|
67930
|
+
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP10, "/") + ".script.lock";
|
|
67189
67931
|
}
|
|
67190
67932
|
}
|
|
67191
67933
|
let metaPath;
|
|
@@ -67372,7 +68114,7 @@ async function updateScriptLock(workspace, scriptContent, language, remotePath,
|
|
|
67372
68114
|
const lockPath = lockPathOverride ?? remotePath + ".script.lock";
|
|
67373
68115
|
if (lock != "") {
|
|
67374
68116
|
await writeFile8(lockPath, lock, "utf-8");
|
|
67375
|
-
metadataContent.lock = "!inline " + lockPath.replaceAll(
|
|
68117
|
+
metadataContent.lock = "!inline " + lockPath.replaceAll(SEP10, "/");
|
|
67376
68118
|
} else {
|
|
67377
68119
|
try {
|
|
67378
68120
|
if (await stat8(lockPath)) {
|
|
@@ -67686,22 +68428,29 @@ async function parseMetadataFile(scriptPath, generateMetadataIfMissing) {
|
|
|
67686
68428
|
};
|
|
67687
68429
|
}
|
|
67688
68430
|
function normalizeLockPath(p) {
|
|
67689
|
-
|
|
68431
|
+
let n = p.replace(/\\/g, "/");
|
|
68432
|
+
if (n.startsWith("./"))
|
|
68433
|
+
n = n.slice(2);
|
|
68434
|
+
return n;
|
|
67690
68435
|
}
|
|
67691
68436
|
async function readLockfile() {
|
|
68437
|
+
let parsed;
|
|
67692
68438
|
try {
|
|
67693
|
-
|
|
67694
|
-
if (typeof read2 == "object" && read2 != null) {
|
|
67695
|
-
return read2;
|
|
67696
|
-
} else {
|
|
67697
|
-
throw new Error("Invalid lockfile");
|
|
67698
|
-
}
|
|
68439
|
+
parsed = await yamlParseFile(WMILL_LOCKFILE);
|
|
67699
68440
|
} catch {
|
|
67700
|
-
const lock = { locks: {}, version:
|
|
68441
|
+
const lock = { locks: {}, version: CURRENT_LOCK_VERSION };
|
|
67701
68442
|
await writeFile8(WMILL_LOCKFILE, import_yaml13.stringify(lock, yamlOptions), "utf-8");
|
|
67702
68443
|
info(colors.green("wmill-lock.yaml created"));
|
|
67703
68444
|
return lock;
|
|
67704
68445
|
}
|
|
68446
|
+
if (typeof parsed != "object" || parsed == null) {
|
|
68447
|
+
throw new MalformedLockfileError("wmill-lock.yaml is malformed (expected an object). Refusing to operate to avoid corrupting the lockfile.");
|
|
68448
|
+
}
|
|
68449
|
+
const conf = parsed;
|
|
68450
|
+
if (conf.version != null && !KNOWN_LOCK_VERSIONS.includes(conf.version)) {
|
|
68451
|
+
throw new UnknownLockVersionError(`wmill-lock.yaml is at unknown version "${conf.version}". This was written by a newer wmill CLI; please upgrade with \`wmill upgrade\`. Refusing to operate to avoid corrupting the lockfile.`);
|
|
68452
|
+
}
|
|
68453
|
+
return conf;
|
|
67705
68454
|
}
|
|
67706
68455
|
function v2LockPath(path13, subpath) {
|
|
67707
68456
|
const normalizedPath = normalizeLockPath(path13);
|
|
@@ -67718,15 +68467,18 @@ async function checkifMetadataUptodate(path13, hash2, conf, subpath) {
|
|
|
67718
68467
|
if (!conf.locks) {
|
|
67719
68468
|
return false;
|
|
67720
68469
|
}
|
|
67721
|
-
const
|
|
67722
|
-
if (
|
|
67723
|
-
const
|
|
67724
|
-
return
|
|
67725
|
-
}
|
|
67726
|
-
|
|
67727
|
-
const
|
|
67728
|
-
|
|
68470
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68471
|
+
if (isFlatKeyed) {
|
|
68472
|
+
const key = v2LockPath(path13, subpath);
|
|
68473
|
+
return conf.locks?.[key] === hash2 || conf.locks?.["./" + key] === hash2;
|
|
68474
|
+
}
|
|
68475
|
+
for (const p of [path13, "./" + path13]) {
|
|
68476
|
+
const obj = conf.locks?.[p];
|
|
68477
|
+
const v = subpath && typeof obj == "object" ? obj?.[subpath] : obj;
|
|
68478
|
+
if (v === hash2)
|
|
68479
|
+
return true;
|
|
67729
68480
|
}
|
|
68481
|
+
return false;
|
|
67730
68482
|
}
|
|
67731
68483
|
async function generateScriptHash(rawWorkspaceDependencies, scriptContent, newMetadataContent) {
|
|
67732
68484
|
return await generateHash(JSON.stringify(rawWorkspaceDependencies) + scriptContent + newMetadataContent);
|
|
@@ -67761,15 +68513,16 @@ async function clearGlobalLock(path13) {
|
|
|
67761
68513
|
if (!conf?.locks) {
|
|
67762
68514
|
conf.locks = {};
|
|
67763
68515
|
}
|
|
67764
|
-
const
|
|
67765
|
-
if (
|
|
68516
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68517
|
+
if (isFlatKeyed) {
|
|
67766
68518
|
const key = v2LockPath(path13);
|
|
68519
|
+
const legacyKey = "./" + key;
|
|
67767
68520
|
if (conf.locks) {
|
|
67768
68521
|
Object.keys(conf.locks).forEach((k) => {
|
|
67769
|
-
if (conf.locks)
|
|
67770
|
-
|
|
67771
|
-
|
|
67772
|
-
|
|
68522
|
+
if (!conf.locks)
|
|
68523
|
+
return;
|
|
68524
|
+
if (k === key || k.startsWith(key + "+") || k === legacyKey || k.startsWith(legacyKey + "+")) {
|
|
68525
|
+
delete conf.locks[k];
|
|
67773
68526
|
}
|
|
67774
68527
|
});
|
|
67775
68528
|
}
|
|
@@ -67781,8 +68534,8 @@ async function updateMetadataGlobalLock(path13, hash2, subpath) {
|
|
|
67781
68534
|
if (!conf?.locks) {
|
|
67782
68535
|
conf.locks = {};
|
|
67783
68536
|
}
|
|
67784
|
-
const
|
|
67785
|
-
if (
|
|
68537
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68538
|
+
if (isFlatKeyed) {
|
|
67786
68539
|
conf.locks[v2LockPath(path13, subpath)] = hash2;
|
|
67787
68540
|
} else {
|
|
67788
68541
|
if (subpath) {
|
|
@@ -67798,7 +68551,7 @@ async function updateMetadataGlobalLock(path13, hash2, subpath) {
|
|
|
67798
68551
|
}
|
|
67799
68552
|
await writeFile8(WMILL_LOCKFILE, import_yaml13.stringify(conf, yamlOptions), "utf-8");
|
|
67800
68553
|
}
|
|
67801
|
-
var import_yaml13, _require, _parserCache, LockfileGenerationError, LANG_ANNOTATION_CONFIG, lockCache, WMILL_LOCKFILE = "wmill-lock.yaml", SCRIPT_TOP_HASH = "__script_hash";
|
|
68554
|
+
var import_yaml13, _require, _parserCache, LockfileGenerationError, UnknownLockVersionError, MalformedLockfileError, LANG_ANNOTATION_CONFIG, lockCache, WMILL_LOCKFILE = "wmill-lock.yaml", CURRENT_LOCK_VERSION = "v2", KNOWN_LOCK_VERSIONS, SCRIPT_TOP_HASH = "__script_hash";
|
|
67802
68555
|
var init_metadata = __esm(async () => {
|
|
67803
68556
|
init_colors2();
|
|
67804
68557
|
init_log();
|
|
@@ -67824,6 +68577,18 @@ var init_metadata = __esm(async () => {
|
|
|
67824
68577
|
this.name = "LockfileGenerationError";
|
|
67825
68578
|
}
|
|
67826
68579
|
};
|
|
68580
|
+
UnknownLockVersionError = class UnknownLockVersionError extends Error {
|
|
68581
|
+
constructor(message) {
|
|
68582
|
+
super(message);
|
|
68583
|
+
this.name = "UnknownLockVersionError";
|
|
68584
|
+
}
|
|
68585
|
+
};
|
|
68586
|
+
MalformedLockfileError = class MalformedLockfileError extends Error {
|
|
68587
|
+
constructor(message) {
|
|
68588
|
+
super(message);
|
|
68589
|
+
this.name = "MalformedLockfileError";
|
|
68590
|
+
}
|
|
68591
|
+
};
|
|
67827
68592
|
LANG_ANNOTATION_CONFIG = {
|
|
67828
68593
|
python3: { comment: "#", keyword: "requirements", validityRe: /^#\s?(\S+)\s*$/ },
|
|
67829
68594
|
bun: { comment: "//", keyword: "package_json" },
|
|
@@ -67833,6 +68598,7 @@ var init_metadata = __esm(async () => {
|
|
|
67833
68598
|
powershell: { comment: "#", keyword: "modules_json" }
|
|
67834
68599
|
};
|
|
67835
68600
|
lockCache = new Map;
|
|
68601
|
+
KNOWN_LOCK_VERSIONS = ["v1", "v2"];
|
|
67836
68602
|
});
|
|
67837
68603
|
|
|
67838
68604
|
// src/commands/app/raw_apps.ts
|
|
@@ -67843,7 +68609,7 @@ __export(exports_raw_apps, {
|
|
|
67843
68609
|
loadRunnablesFromBackend: () => loadRunnablesFromBackend,
|
|
67844
68610
|
generatingPolicy: () => generatingPolicy
|
|
67845
68611
|
});
|
|
67846
|
-
import { sep as
|
|
68612
|
+
import { sep as SEP11 } from "node:path";
|
|
67847
68613
|
import path13 from "node:path";
|
|
67848
68614
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
67849
68615
|
async function readSiblingLock(backendPath, runnableId, allFiles) {
|
|
@@ -67981,7 +68747,7 @@ async function collectAppFiles(localPath) {
|
|
|
67981
68747
|
if (entry.name === APP_BACKEND_FOLDER || entry.name === "node_modules" || entry.name === "dist" || entry.name === ".claude" || entry.name === "sql_to_apply") {
|
|
67982
68748
|
continue;
|
|
67983
68749
|
}
|
|
67984
|
-
await readDirRecursive2(fullPath +
|
|
68750
|
+
await readDirRecursive2(fullPath + SEP11, relativePath + "/");
|
|
67985
68751
|
} else if (entry.isFile()) {
|
|
67986
68752
|
if (entry.name === "raw_app.yaml" || entry.name === "package-lock.json" || entry.name === "DATATABLES.md" || entry.name === "AGENTS.md" || entry.name === "wmill.d.ts") {
|
|
67987
68753
|
continue;
|
|
@@ -67999,7 +68765,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
67999
68765
|
return;
|
|
68000
68766
|
}
|
|
68001
68767
|
alreadySynced.push(localPath);
|
|
68002
|
-
remotePath = remotePath.replaceAll(
|
|
68768
|
+
remotePath = remotePath.replaceAll(SEP11, "/");
|
|
68003
68769
|
let app = undefined;
|
|
68004
68770
|
try {
|
|
68005
68771
|
app = await getAppByPath({
|
|
@@ -68013,8 +68779,8 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
68013
68779
|
if (app) {
|
|
68014
68780
|
app.policy = undefined;
|
|
68015
68781
|
}
|
|
68016
|
-
if (!localPath.endsWith(
|
|
68017
|
-
localPath +=
|
|
68782
|
+
if (!localPath.endsWith(SEP11)) {
|
|
68783
|
+
localPath += SEP11;
|
|
68018
68784
|
}
|
|
68019
68785
|
const appFilePath = localPath + "raw_app.yaml";
|
|
68020
68786
|
const localApp = await yamlParseFile(appFilePath);
|
|
@@ -68030,7 +68796,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
68030
68796
|
} else {
|
|
68031
68797
|
runnables = {};
|
|
68032
68798
|
}
|
|
68033
|
-
replaceInlineScripts2(runnables, backendPath +
|
|
68799
|
+
replaceInlineScripts2(runnables, backendPath + SEP11, true);
|
|
68034
68800
|
repopulateFields(runnables);
|
|
68035
68801
|
const appForPolicy = { ...localApp, runnables };
|
|
68036
68802
|
await generatingPolicy(appForPolicy, remotePath, localApp?.["public"] ?? false);
|
|
@@ -68142,7 +68908,20 @@ __export(exports_app_metadata, {
|
|
|
68142
68908
|
});
|
|
68143
68909
|
import path14 from "node:path";
|
|
68144
68910
|
import { mkdir as mkdir6, readdir as readdir7 } from "node:fs/promises";
|
|
68145
|
-
import { sep as
|
|
68911
|
+
import { sep as SEP12 } from "node:path";
|
|
68912
|
+
async function isAppDirectlyStale(appFolder, hashes, conf) {
|
|
68913
|
+
if (await checkifMetadataUptodate(appFolder, hashes[TOP_HASH2], conf, TOP_HASH2)) {
|
|
68914
|
+
return false;
|
|
68915
|
+
}
|
|
68916
|
+
const fileEntries = Object.entries(hashes).filter(([k]) => k !== TOP_HASH2);
|
|
68917
|
+
if (fileEntries.length === 0)
|
|
68918
|
+
return true;
|
|
68919
|
+
for (const [k, h] of fileEntries) {
|
|
68920
|
+
if (!await checkifMetadataUptodate(appFolder, h, conf, k))
|
|
68921
|
+
return true;
|
|
68922
|
+
}
|
|
68923
|
+
return false;
|
|
68924
|
+
}
|
|
68146
68925
|
async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
68147
68926
|
const runnablesFolder = rawApp ? path14.join(folder, APP_BACKEND_FOLDER) : folder;
|
|
68148
68927
|
const hashes = {};
|
|
@@ -68156,7 +68935,7 @@ async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
|
68156
68935
|
}
|
|
68157
68936
|
}
|
|
68158
68937
|
if (exts.some((e) => f.path.endsWith(e))) {
|
|
68159
|
-
const relativePath = normalizeLockPath(f.path.replace(runnablesFolder +
|
|
68938
|
+
const relativePath = normalizeLockPath(f.path.replace(runnablesFolder + SEP12, ""));
|
|
68160
68939
|
hashes[relativePath] = await generateHash(await f.getContentText() + JSON.stringify(rawReqs));
|
|
68161
68940
|
}
|
|
68162
68941
|
}
|
|
@@ -68172,23 +68951,31 @@ async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
|
68172
68951
|
return { ...sortedHashes, [TOP_HASH2]: await generateHash(JSON.stringify(sortedHashes)) };
|
|
68173
68952
|
}
|
|
68174
68953
|
async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, opts, justUpdateMetadataLock, noStaleMessage, tree) {
|
|
68175
|
-
if (appFolder.endsWith(
|
|
68954
|
+
if (appFolder.endsWith(SEP12)) {
|
|
68176
68955
|
appFolder = appFolder.substring(0, appFolder.length - 1);
|
|
68177
68956
|
}
|
|
68178
|
-
|
|
68957
|
+
if (opts.rehashOnly) {
|
|
68958
|
+
const hashes = await generateAppHash({}, appFolder, rawApp, opts.defaultTs);
|
|
68959
|
+
await clearGlobalLock(appFolder);
|
|
68960
|
+
for (const [k, v] of Object.entries(hashes)) {
|
|
68961
|
+
await updateMetadataGlobalLock(appFolder, v, k);
|
|
68962
|
+
}
|
|
68963
|
+
return;
|
|
68964
|
+
}
|
|
68965
|
+
const remote_path = appFolder.replaceAll(SEP12, "/");
|
|
68179
68966
|
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
68180
68967
|
info(`Generating locks for app ${appFolder} at ${remote_path}`);
|
|
68181
68968
|
}
|
|
68182
68969
|
const appFilePath = path14.join(appFolder, rawApp ? "raw_app.yaml" : "app.yaml");
|
|
68183
68970
|
const appFile = await yamlParseFile(appFilePath);
|
|
68184
68971
|
const appValue = rawApp ? appFile.runnables : appFile.value;
|
|
68185
|
-
const folderNormalized = appFolder.replaceAll(
|
|
68972
|
+
const folderNormalized = appFolder.replaceAll(SEP12, "/");
|
|
68186
68973
|
let filteredDeps = {};
|
|
68187
68974
|
const conf = await readLockfile();
|
|
68188
68975
|
if (tree) {
|
|
68189
68976
|
if (dryRun) {
|
|
68190
68977
|
const hashes = await generateAppHash({}, appFolder, rawApp, opts.defaultTs);
|
|
68191
|
-
const isDirectlyStale =
|
|
68978
|
+
const isDirectlyStale = await isAppDirectlyStale(appFolder, hashes, conf);
|
|
68192
68979
|
let treeAppValue = structuredClone(appValue);
|
|
68193
68980
|
if (rawApp) {
|
|
68194
68981
|
const runnablesPath = path14.join(appFolder, APP_BACKEND_FOLDER);
|
|
@@ -68204,7 +68991,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68204
68991
|
}
|
|
68205
68992
|
let content = inlineScript.content;
|
|
68206
68993
|
if (typeof content === "string" && content.startsWith("!inline ")) {
|
|
68207
|
-
const filePath = appFolder +
|
|
68994
|
+
const filePath = appFolder + SEP12 + content.replace("!inline ", "");
|
|
68208
68995
|
try {
|
|
68209
68996
|
content = await readTextFile(filePath);
|
|
68210
68997
|
} catch {
|
|
@@ -68226,7 +69013,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68226
69013
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
68227
69014
|
filteredDeps = await filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependencies, appFolder);
|
|
68228
69015
|
const hashes = await generateAppHash(filteredDeps, appFolder, rawApp, opts.defaultTs);
|
|
68229
|
-
const isDirectlyStale =
|
|
69016
|
+
const isDirectlyStale = await isAppDirectlyStale(appFolder, hashes, conf);
|
|
68230
69017
|
if (!isDirectlyStale) {
|
|
68231
69018
|
if (!noStaleMessage) {
|
|
68232
69019
|
info(colors.green(`App ${remote_path} metadata is up-to-date, skipping`));
|
|
@@ -68263,11 +69050,11 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68263
69050
|
if (Object.keys(runnables).length === 0 && rawAppFile.runnables) {
|
|
68264
69051
|
runnables = rawAppFile.runnables;
|
|
68265
69052
|
}
|
|
68266
|
-
replaceInlineScripts2(runnables, runnablesPath +
|
|
69053
|
+
replaceInlineScripts2(runnables, runnablesPath + SEP12, false);
|
|
68267
69054
|
updatedScripts = await updateRawAppRunnables(workspace, runnables, remote_path, appFolder, filteredDeps, opts.defaultTs, noStaleMessage, tempScriptRefs);
|
|
68268
69055
|
} else {
|
|
68269
69056
|
const normalAppFile = appFile;
|
|
68270
|
-
replaceInlineScripts2(normalAppFile.value, appFolder +
|
|
69057
|
+
replaceInlineScripts2(normalAppFile.value, appFolder + SEP12, false);
|
|
68271
69058
|
const result = await updateAppInlineScripts(workspace, normalAppFile.value, remote_path, appFolder, filteredDeps, opts.defaultTs, noStaleMessage, tempScriptRefs);
|
|
68272
69059
|
normalAppFile.value = result.value;
|
|
68273
69060
|
updatedScripts = result.updatedScripts;
|
|
@@ -68299,7 +69086,7 @@ async function filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependenc
|
|
|
68299
69086
|
}
|
|
68300
69087
|
return inlineScript;
|
|
68301
69088
|
});
|
|
68302
|
-
return await filterWorkspaceDependenciesForScripts(scripts, rawWorkspaceDependencies, folder,
|
|
69089
|
+
return await filterWorkspaceDependenciesForScripts(scripts, rawWorkspaceDependencies, folder, SEP12);
|
|
68303
69090
|
}
|
|
68304
69091
|
async function traverseAndProcessInlineScripts(obj, processor, currentPath = []) {
|
|
68305
69092
|
if (!obj || typeof obj !== "object") {
|
|
@@ -68354,7 +69141,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
|
|
|
68354
69141
|
}
|
|
68355
69142
|
if (language === "frontend") {
|
|
68356
69143
|
const [basePathO, ext2] = pathAssigner.assignPath(runnableId, language);
|
|
68357
|
-
const basePath = basePathO.replaceAll(
|
|
69144
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68358
69145
|
const contentPath = path14.join(runnablesFolder, `${basePath}${ext2}`);
|
|
68359
69146
|
writeIfChanged(contentPath, content);
|
|
68360
69147
|
const simplifiedRunnable = { type: "inline" };
|
|
@@ -68372,7 +69159,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
|
|
|
68372
69159
|
try {
|
|
68373
69160
|
const lock = await generateInlineScriptLock(workspace, content, language, `${remotePath}/${runnableId}`, rawDeps, tempScriptRefs);
|
|
68374
69161
|
const [basePathO, ext2] = pathAssigner.assignPath(runnableId, language);
|
|
68375
|
-
const basePath = basePathO.replaceAll(
|
|
69162
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68376
69163
|
const contentPath = path14.join(runnablesFolder, `${basePath}${ext2}`);
|
|
68377
69164
|
const lockPath = path14.join(runnablesFolder, `${basePath}lock`);
|
|
68378
69165
|
writeIfChanged(contentPath, content);
|
|
@@ -68421,7 +69208,7 @@ async function updateAppInlineScripts(workspace, appValue, remotePath, appFolder
|
|
|
68421
69208
|
lock = await generateInlineScriptLock(workspace, content, language, scriptPath, rawDeps, tempScriptRefs);
|
|
68422
69209
|
}
|
|
68423
69210
|
const [basePathO, ext2] = pathAssigner.assignPath(scriptName, language);
|
|
68424
|
-
const basePath = basePathO.replaceAll(
|
|
69211
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68425
69212
|
const contentPath = path14.join(appFolder, `${basePath}${ext2}`);
|
|
68426
69213
|
const lockPath = path14.join(appFolder, `${basePath}lock`);
|
|
68427
69214
|
writeIfChanged(contentPath, content);
|
|
@@ -68550,7 +69337,7 @@ async function inferRunnableSchemaFromFile(appFolder, runnableFilePath, defaultT
|
|
|
68550
69337
|
warn(colors.yellow(`Could not read file: ${fullFilePath}`));
|
|
68551
69338
|
return;
|
|
68552
69339
|
}
|
|
68553
|
-
const remotePath = appFolder.replaceAll(
|
|
69340
|
+
const remotePath = appFolder.replaceAll(SEP12, "/");
|
|
68554
69341
|
try {
|
|
68555
69342
|
const schemaResult = await inferSchema(language, content, currentSchema, `${remotePath}/${runnableId}`);
|
|
68556
69343
|
info(colors.green(` Inferred schema for ${runnableId}`));
|
|
@@ -68586,7 +69373,7 @@ async function inferAllInlineSchemas(appFolder, defaultTs = "bun") {
|
|
|
68586
69373
|
return schemas;
|
|
68587
69374
|
}
|
|
68588
69375
|
function getAppFolders(elems, extension) {
|
|
68589
|
-
return Object.keys(elems).filter((p) => p.endsWith(
|
|
69376
|
+
return Object.keys(elems).filter((p) => p.endsWith(SEP12 + extension)).map((p) => p.substring(0, p.length - (SEP12 + extension).length));
|
|
68590
69377
|
}
|
|
68591
69378
|
async function generateLocksCommand(opts, appPath) {
|
|
68592
69379
|
const { generateAppLocksInternal: generateAppLocksInternal2 } = await init_app_metadata().then(() => exports_app_metadata);
|
|
@@ -68604,7 +69391,7 @@ async function generateLocksCommand(opts, appPath) {
|
|
|
68604
69391
|
} else {
|
|
68605
69392
|
const ignore = await ignoreF2(opts);
|
|
68606
69393
|
const elems = await elementsToMap2(await FSFSElement2(process.cwd(), [], true), (p, isD) => {
|
|
68607
|
-
return ignore(p, isD) || !isD && !p.endsWith(
|
|
69394
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP12 + "raw_app.yaml") && !p.endsWith(SEP12 + "app.yaml");
|
|
68608
69395
|
}, false, {});
|
|
68609
69396
|
const rawAppFolders = getAppFolders(elems, "raw_app.yaml");
|
|
68610
69397
|
const appFolders = getAppFolders(elems, "app.yaml");
|
|
@@ -68846,7 +69633,7 @@ async function generateAgents(opts, appFolder) {
|
|
|
68846
69633
|
await requireLogin(opts);
|
|
68847
69634
|
await regenerateAgentDocs(workspace.workspaceId, targetDir);
|
|
68848
69635
|
}
|
|
68849
|
-
var
|
|
69636
|
+
var command9, generate_agents_default;
|
|
68850
69637
|
var init_generate_agents = __esm(async () => {
|
|
68851
69638
|
init_mod3();
|
|
68852
69639
|
init_colors2();
|
|
@@ -68859,12 +69646,12 @@ var init_generate_agents = __esm(async () => {
|
|
|
68859
69646
|
init_sync(),
|
|
68860
69647
|
init_resource_folders()
|
|
68861
69648
|
]);
|
|
68862
|
-
|
|
68863
|
-
generate_agents_default =
|
|
69649
|
+
command9 = new Command().description("regenerate AGENTS.md and DATATABLES.md from remote workspace").arguments("[app_folder:string]").action(generateAgents);
|
|
69650
|
+
generate_agents_default = command9;
|
|
68864
69651
|
});
|
|
68865
69652
|
|
|
68866
69653
|
// src/commands/app/dev.ts
|
|
68867
|
-
import { sep as
|
|
69654
|
+
import { sep as SEP13 } from "node:path";
|
|
68868
69655
|
import * as http2 from "node:http";
|
|
68869
69656
|
import * as fs11 from "node:fs";
|
|
68870
69657
|
import * as path16 from "node:path";
|
|
@@ -69555,7 +70342,7 @@ async function loadRunnables() {
|
|
|
69555
70342
|
runnables = rawApp?.runnables ?? {};
|
|
69556
70343
|
}
|
|
69557
70344
|
convertRunnablesToApiFormat(runnables);
|
|
69558
|
-
replaceInlineScripts2(runnables, backendPath +
|
|
70345
|
+
replaceInlineScripts2(runnables, backendPath + SEP13, true);
|
|
69559
70346
|
repopulateFields(runnables);
|
|
69560
70347
|
return runnables;
|
|
69561
70348
|
} catch (error2) {
|
|
@@ -70007,7 +70794,7 @@ var DEFAULT_PORT = 4000, DEFAULT_HOST = "localhost", createHTML = (jsPath, cssPa
|
|
|
70007
70794
|
</script>
|
|
70008
70795
|
</body>
|
|
70009
70796
|
</html>
|
|
70010
|
-
`,
|
|
70797
|
+
`, command10, dev_default, ITERATIONS_BEFORE_SLOW_REFRESH = 10, ITERATIONS_BEFORE_SUPER_SLOW_REFRESH = 100, QUEUE_LOG_INTERVAL_MS2 = 5000;
|
|
70011
70798
|
var init_dev = __esm(async () => {
|
|
70012
70799
|
init_mod3();
|
|
70013
70800
|
init_colors2();
|
|
@@ -70032,10 +70819,10 @@ var init_dev = __esm(async () => {
|
|
|
70032
70819
|
init_generate_agents(),
|
|
70033
70820
|
init_resource_folders()
|
|
70034
70821
|
]);
|
|
70035
|
-
|
|
70822
|
+
command10 = new Command().description("Start a development server for building apps with live reload and hot module replacement").arguments("[app_folder:string]").option("--port <port:number>", "Port to run the dev server on (will find next available port if occupied)").option("--host <host:string>", "Host to bind the dev server to", {
|
|
70036
70823
|
default: DEFAULT_HOST
|
|
70037
70824
|
}).option("--entry <entry:string>", "Entry point file (default: index.ts for Svelte/Vue, index.tsx otherwise)").option("--no-open", "Don't automatically open the browser").action(dev);
|
|
70038
|
-
dev_default =
|
|
70825
|
+
dev_default = command10;
|
|
70039
70826
|
});
|
|
70040
70827
|
|
|
70041
70828
|
// src/commands/app/lint.ts
|
|
@@ -70164,7 +70951,7 @@ async function lint2(opts, appFolder) {
|
|
|
70164
70951
|
✅ All checks passed
|
|
70165
70952
|
`));
|
|
70166
70953
|
}
|
|
70167
|
-
var
|
|
70954
|
+
var command11, lint_default2;
|
|
70168
70955
|
var init_lint2 = __esm(async () => {
|
|
70169
70956
|
init_mod3();
|
|
70170
70957
|
init_colors2();
|
|
@@ -70176,8 +70963,8 @@ var init_lint2 = __esm(async () => {
|
|
|
70176
70963
|
init_raw_apps(),
|
|
70177
70964
|
init_resource_folders()
|
|
70178
70965
|
]);
|
|
70179
|
-
|
|
70180
|
-
lint_default2 =
|
|
70966
|
+
command11 = new Command().description("Lint a raw app folder to validate structure and buildability").arguments("[app_folder:string]").option("--fix", "Attempt to fix common issues (not implemented yet)").action(lint2);
|
|
70967
|
+
lint_default2 = command11;
|
|
70181
70968
|
});
|
|
70182
70969
|
|
|
70183
70970
|
// src/commands/app/new.ts
|
|
@@ -70713,7 +71500,7 @@ createApp(App).mount('#root')`, indexCss = `body {
|
|
|
70713
71500
|
.myclass {
|
|
70714
71501
|
border: 1px solid gray;
|
|
70715
71502
|
padding: 2px;
|
|
70716
|
-
}`, templates,
|
|
71503
|
+
}`, templates, command12, new_default;
|
|
70717
71504
|
var init_new = __esm(async () => {
|
|
70718
71505
|
init_mod3();
|
|
70719
71506
|
init_colors2();
|
|
@@ -70798,12 +71585,12 @@ var init_new = __esm(async () => {
|
|
|
70798
71585
|
}
|
|
70799
71586
|
}
|
|
70800
71587
|
};
|
|
70801
|
-
|
|
70802
|
-
new_default =
|
|
71588
|
+
command12 = new Command().description("create a new raw app from a template").option("--summary <summary:string>", "App summary (short description). Skips the prompt when provided. Triggers non-interactive mode.").option("--path <path:string>", "App path (e.g., f/folder/my_app or u/username/my_app). Skips the prompt when provided. Triggers non-interactive mode.").option("--framework <framework:string>", "Framework template: react19 | react18 | svelte5 | vue. Skips the prompt when provided. Triggers non-interactive mode.").option("--datatable <datatable:string>", "Datatable to wire up. Without this flag in non-interactive mode, no datatable is configured.").option("--schema <schema:string>", "Schema to use with --datatable. Created (CREATE SCHEMA IF NOT EXISTS) if it doesn't already exist.").option("--overwrite", "Overwrite the target directory if it already exists, without prompting.").option("--no-open-in-desktop", "Do not prompt to open the new app in Claude Desktop.").action(newApp);
|
|
71589
|
+
new_default = command12;
|
|
70803
71590
|
});
|
|
70804
71591
|
|
|
70805
71592
|
// src/commands/app/app.ts
|
|
70806
|
-
import { sep as
|
|
71593
|
+
import { sep as SEP14 } from "node:path";
|
|
70807
71594
|
import { stat as stat10 } from "node:fs/promises";
|
|
70808
71595
|
function respecializeFields(fields) {
|
|
70809
71596
|
Object.entries(fields).forEach(([k, v]) => {
|
|
@@ -70877,7 +71664,7 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
|
|
|
70877
71664
|
return;
|
|
70878
71665
|
}
|
|
70879
71666
|
alreadySynced2.push(localPath);
|
|
70880
|
-
remotePath = remotePath.replaceAll(
|
|
71667
|
+
remotePath = remotePath.replaceAll(SEP14, "/");
|
|
70881
71668
|
let app = undefined;
|
|
70882
71669
|
try {
|
|
70883
71670
|
app = await getAppByPath({
|
|
@@ -70897,8 +71684,8 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
|
|
|
70897
71684
|
if (app) {
|
|
70898
71685
|
app.policy = undefined;
|
|
70899
71686
|
}
|
|
70900
|
-
if (!localPath.endsWith(
|
|
70901
|
-
localPath +=
|
|
71687
|
+
if (!localPath.endsWith(SEP14)) {
|
|
71688
|
+
localPath += SEP14;
|
|
70902
71689
|
}
|
|
70903
71690
|
const path19 = localPath + "app.yaml";
|
|
70904
71691
|
const localApp = await yamlParseFile(path19);
|
|
@@ -70999,12 +71786,12 @@ async function push5(opts, filePath, remotePath) {
|
|
|
70999
71786
|
}
|
|
71000
71787
|
const workspace = await resolveWorkspace(opts);
|
|
71001
71788
|
await requireLogin(opts);
|
|
71002
|
-
const normalizedPath = filePath.endsWith(
|
|
71789
|
+
const normalizedPath = filePath.endsWith(SEP14) ? filePath.slice(0, -1) : filePath;
|
|
71003
71790
|
const isRawApp = normalizedPath.endsWith("__raw_app") || normalizedPath.endsWith(".raw_app");
|
|
71004
71791
|
let hasRawAppYaml = false;
|
|
71005
71792
|
if (!isRawApp) {
|
|
71006
71793
|
try {
|
|
71007
|
-
const rawAppPath = (filePath.endsWith(
|
|
71794
|
+
const rawAppPath = (filePath.endsWith(SEP14) ? filePath : filePath + SEP14) + "raw_app.yaml";
|
|
71008
71795
|
await stat10(rawAppPath);
|
|
71009
71796
|
hasRawAppYaml = true;
|
|
71010
71797
|
} catch {}
|
|
@@ -71018,7 +71805,7 @@ async function push5(opts, filePath, remotePath) {
|
|
|
71018
71805
|
info(colors.bold.underline.green("App pushed"));
|
|
71019
71806
|
}
|
|
71020
71807
|
}
|
|
71021
|
-
var alreadySynced2,
|
|
71808
|
+
var alreadySynced2, command13, app_default;
|
|
71022
71809
|
var init_app = __esm(async () => {
|
|
71023
71810
|
init_mod3();
|
|
71024
71811
|
init_mod6();
|
|
@@ -71039,7 +71826,7 @@ var init_app = __esm(async () => {
|
|
|
71039
71826
|
init_generate_agents()
|
|
71040
71827
|
]);
|
|
71041
71828
|
alreadySynced2 = [];
|
|
71042
|
-
|
|
71829
|
+
command13 = new Command().description("app related commands").option("--json", "Output as JSON (for piping to jq)").action(list6).command("list", "list all apps").option("--json", "Output as JSON (for piping to jq)").action(list6).command("get", "get an app's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get4).command("push", "push a local app ").arguments("<file_path:string> <remote_path:string>").action(push5).command("dev", dev_default).command("lint", lint_default2).command("new", new_default).command("generate-agents", generate_agents_default).command("generate-locks", 'DEPRECATED: re-generate app lockfiles. Use "wmill generate-metadata" instead.').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) => {
|
|
71043
71830
|
warn(colors.yellow('This command is deprecated. Use "wmill generate-metadata" instead.'));
|
|
71044
71831
|
const { generateLocksCommand: generateLocksCommand2 } = await init_app_metadata().then(() => exports_app_metadata);
|
|
71045
71832
|
await generateLocksCommand2(opts, appFolder);
|
|
@@ -71069,12 +71856,12 @@ var init_app = __esm(async () => {
|
|
|
71069
71856
|
});
|
|
71070
71857
|
info(colors.green(`Updated permissioned_as for app ${appPath} to ${email}`));
|
|
71071
71858
|
});
|
|
71072
|
-
app_default =
|
|
71859
|
+
app_default = command13;
|
|
71073
71860
|
});
|
|
71074
71861
|
|
|
71075
71862
|
// src/commands/folder/folder.ts
|
|
71076
71863
|
import { stat as stat11, readdir as readdir8, writeFile as writeFile11, mkdir as mkdir8 } from "node:fs/promises";
|
|
71077
|
-
import { sep as
|
|
71864
|
+
import { sep as SEP15 } from "node:path";
|
|
71078
71865
|
async function list7(opts) {
|
|
71079
71866
|
if (opts.json)
|
|
71080
71867
|
setSilent(true);
|
|
@@ -71094,8 +71881,8 @@ async function list7(opts) {
|
|
|
71094
71881
|
}
|
|
71095
71882
|
}
|
|
71096
71883
|
async function newFolder(opts, name) {
|
|
71097
|
-
const dirPath = `f${
|
|
71098
|
-
const filePath = `${dirPath}${
|
|
71884
|
+
const dirPath = `f${SEP15}${name}`;
|
|
71885
|
+
const filePath = `${dirPath}${SEP15}folder.meta.yaml`;
|
|
71099
71886
|
try {
|
|
71100
71887
|
await stat11(filePath);
|
|
71101
71888
|
throw new Error("File already exists: " + filePath);
|
|
@@ -71133,13 +71920,13 @@ async function get5(opts, name) {
|
|
|
71133
71920
|
}
|
|
71134
71921
|
}
|
|
71135
71922
|
async function pushFolder(workspace, name, folder, localFolder) {
|
|
71136
|
-
if (name.startsWith(
|
|
71923
|
+
if (name.startsWith(SEP15)) {
|
|
71137
71924
|
name = name.substring(1);
|
|
71138
71925
|
}
|
|
71139
|
-
if (name.startsWith("f" +
|
|
71926
|
+
if (name.startsWith("f" + SEP15)) {
|
|
71140
71927
|
name = name.substring(2);
|
|
71141
71928
|
}
|
|
71142
|
-
name = name.split(
|
|
71929
|
+
name = name.split(SEP15)[0];
|
|
71143
71930
|
debug(`Processing local folder ${name}`);
|
|
71144
71931
|
try {
|
|
71145
71932
|
folder = await getFolder({ workspace, name });
|
|
@@ -71183,7 +71970,7 @@ async function pushFolder(workspace, name, folder, localFolder) {
|
|
|
71183
71970
|
async function push6(opts, name) {
|
|
71184
71971
|
const workspace = await resolveWorkspace(opts);
|
|
71185
71972
|
await requireLogin(opts);
|
|
71186
|
-
const metaPath = `f${
|
|
71973
|
+
const metaPath = `f${SEP15}${name}${SEP15}folder.meta.yaml`;
|
|
71187
71974
|
try {
|
|
71188
71975
|
await stat11(metaPath);
|
|
71189
71976
|
} catch {
|
|
@@ -71206,7 +71993,7 @@ async function addMissing(opts) {
|
|
|
71206
71993
|
for (const entry of entries) {
|
|
71207
71994
|
if (!entry.isDirectory())
|
|
71208
71995
|
continue;
|
|
71209
|
-
const metaPath = `${fDir}${
|
|
71996
|
+
const metaPath = `${fDir}${SEP15}${entry.name}${SEP15}folder.meta.yaml`;
|
|
71210
71997
|
try {
|
|
71211
71998
|
await stat11(metaPath);
|
|
71212
71999
|
} catch {
|
|
@@ -71233,7 +72020,7 @@ async function addMissing(opts) {
|
|
|
71233
72020
|
info(`
|
|
71234
72021
|
Created ${missing.length} folder.meta.yaml file(s). You can now run 'wmill sync push' to push them.`);
|
|
71235
72022
|
}
|
|
71236
|
-
var import_yaml24,
|
|
72023
|
+
var import_yaml24, command14, folder_default;
|
|
71237
72024
|
var init_folder = __esm(async () => {
|
|
71238
72025
|
init_colors2();
|
|
71239
72026
|
init_mod3();
|
|
@@ -71247,7 +72034,7 @@ var init_folder = __esm(async () => {
|
|
|
71247
72034
|
init_types()
|
|
71248
72035
|
]);
|
|
71249
72036
|
import_yaml24 = __toESM(require_dist(), 1);
|
|
71250
|
-
|
|
72037
|
+
command14 = new Command().description("folder related commands").option("--json", "Output as JSON (for piping to jq)").action(list7).command("list", "list all folders").option("--json", "Output as JSON (for piping to jq)").action(list7).command("get", "get a folder's details").arguments("<name:string>").option("--json", "Output as JSON (for piping to jq)").action(get5).command("new", "create a new folder locally").arguments("<name:string>").option("--summary <summary:string>", "folder summary").action(newFolder).command("push", "push a local folder to the remote by name. This overrides any remote versions.").arguments("<name:string>").action(push6).command("add-missing", "create default folder.meta.yaml for all subdirectories of f/ that are missing one").option("-y, --yes", "skip confirmation prompt").action(addMissing).command("show-rules", "Show default_permissioned_as rules for a folder. Use --test-path to see which rule matches a given item path.").arguments("<name:string>").option("--test-path <path:string>", "Test which rule matches this item path (e.g. f/prod/jobs/my_script)").option("--json", "Output as JSON").action(async (opts, folderName2) => {
|
|
71251
72038
|
const workspace = await resolveWorkspace(opts);
|
|
71252
72039
|
await requireLogin(opts);
|
|
71253
72040
|
const folder = await getFolder({
|
|
@@ -71295,13 +72082,13 @@ var init_folder = __esm(async () => {
|
|
|
71295
72082
|
info(colors.yellow(`No rule matches path '${testPath}' (relative: '${relative7}')`));
|
|
71296
72083
|
}
|
|
71297
72084
|
});
|
|
71298
|
-
folder_default =
|
|
72085
|
+
folder_default = command14;
|
|
71299
72086
|
});
|
|
71300
72087
|
|
|
71301
72088
|
// src/commands/variable/variable.ts
|
|
71302
72089
|
import { mkdir as mkdir9, stat as stat12, writeFile as writeFile12 } from "node:fs/promises";
|
|
71303
72090
|
import { dirname as dirname14 } from "node:path";
|
|
71304
|
-
import { sep as
|
|
72091
|
+
import { sep as SEP16 } from "node:path";
|
|
71305
72092
|
async function list8(opts) {
|
|
71306
72093
|
if (opts.json)
|
|
71307
72094
|
setSilent(true);
|
|
@@ -71370,7 +72157,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71370
72157
|
try {
|
|
71371
72158
|
variable = await getVariable({
|
|
71372
72159
|
workspace,
|
|
71373
|
-
path: remotePath.replaceAll(
|
|
72160
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71374
72161
|
decryptSecret: plainSecrets,
|
|
71375
72162
|
includeEncrypted: true
|
|
71376
72163
|
});
|
|
@@ -71386,7 +72173,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71386
72173
|
debug(`Variable ${remotePath} is not up-to-date, updating`);
|
|
71387
72174
|
await updateVariable({
|
|
71388
72175
|
workspace,
|
|
71389
|
-
path: remotePath.replaceAll(
|
|
72176
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71390
72177
|
alreadyEncrypted: !plainSecrets,
|
|
71391
72178
|
requestBody: {
|
|
71392
72179
|
...localVariable,
|
|
@@ -71399,7 +72186,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71399
72186
|
workspace,
|
|
71400
72187
|
alreadyEncrypted: !plainSecrets,
|
|
71401
72188
|
requestBody: {
|
|
71402
|
-
path: remotePath.replaceAll(
|
|
72189
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71403
72190
|
...localVariable
|
|
71404
72191
|
}
|
|
71405
72192
|
});
|
|
@@ -71445,7 +72232,7 @@ async function add2(opts, value, remotePath) {
|
|
|
71445
72232
|
}, true);
|
|
71446
72233
|
info(colors.bold.underline.green(`Variable ${remotePath} pushed`));
|
|
71447
72234
|
}
|
|
71448
|
-
var import_yaml25,
|
|
72235
|
+
var import_yaml25, command15, variable_default;
|
|
71449
72236
|
var init_variable = __esm(async () => {
|
|
71450
72237
|
init_mod3();
|
|
71451
72238
|
init_mod6();
|
|
@@ -71459,14 +72246,14 @@ var init_variable = __esm(async () => {
|
|
|
71459
72246
|
init_confirm()
|
|
71460
72247
|
]);
|
|
71461
72248
|
import_yaml25 = __toESM(require_dist(), 1);
|
|
71462
|
-
|
|
71463
|
-
variable_default =
|
|
72249
|
+
command15 = new Command().description("variable related commands").option("--json", "Output as JSON (for piping to jq)").action(list8).command("list", "list all variables").option("--json", "Output as JSON (for piping to jq)").action(list8).command("get", "get a variable's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get6).command("new", "create a new variable locally").arguments("<path:string>").action(newVariable).command("push", "Push a local variable spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").option("--plain-secrets", "Push secrets as plain text").action(push7).command("add", "Create a new variable on the remote. This will update the variable if it already exists.").arguments("<value:string> <remote_path:string>").option("--plain-secrets", "Push secrets as plain text").option("--public", "Legacy option, use --plain-secrets instead").action(add2);
|
|
72250
|
+
variable_default = command15;
|
|
71464
72251
|
});
|
|
71465
72252
|
|
|
71466
72253
|
// src/commands/schedule/schedule.ts
|
|
71467
72254
|
import { mkdir as mkdir10, stat as stat13, writeFile as writeFile13 } from "node:fs/promises";
|
|
71468
72255
|
import { dirname as dirname15 } from "node:path";
|
|
71469
|
-
import { sep as
|
|
72256
|
+
import { sep as SEP17 } from "node:path";
|
|
71470
72257
|
async function list9(opts) {
|
|
71471
72258
|
if (opts.json)
|
|
71472
72259
|
setSilent(true);
|
|
@@ -71530,7 +72317,7 @@ async function get7(opts, path19) {
|
|
|
71530
72317
|
}
|
|
71531
72318
|
}
|
|
71532
72319
|
async function pushSchedule(workspace, path19, schedule, localSchedule, permissionedAsContext) {
|
|
71533
|
-
path19 = removeType(path19, "schedule").replaceAll(
|
|
72320
|
+
path19 = removeType(path19, "schedule").replaceAll(SEP17, "/");
|
|
71534
72321
|
debug(`Processing local schedule ${path19}`);
|
|
71535
72322
|
try {
|
|
71536
72323
|
schedule = await getSchedule({ workspace, path: path19 });
|
|
@@ -71565,7 +72352,7 @@ async function pushSchedule(workspace, path19, schedule, localSchedule, permissi
|
|
|
71565
72352
|
...preserveFields
|
|
71566
72353
|
}
|
|
71567
72354
|
});
|
|
71568
|
-
if (localSchedule.enabled
|
|
72355
|
+
if (localSchedule.enabled !== undefined && localSchedule.enabled !== schedule.enabled) {
|
|
71569
72356
|
info(colors.bold.yellow(`Schedule ${path19} is ${localSchedule.enabled ? "enabled" : "disabled"} locally but not on remote, updating remote`));
|
|
71570
72357
|
await setScheduleEnabled({
|
|
71571
72358
|
workspace,
|
|
@@ -71600,13 +72387,31 @@ async function enable(opts, path19) {
|
|
|
71600
72387
|
opts = await mergeConfigWithConfigFile(opts);
|
|
71601
72388
|
const workspace = await resolveWorkspace(opts);
|
|
71602
72389
|
await requireLogin(opts);
|
|
71603
|
-
|
|
71604
|
-
|
|
71605
|
-
|
|
71606
|
-
|
|
71607
|
-
|
|
72390
|
+
try {
|
|
72391
|
+
await setScheduleEnabled({
|
|
72392
|
+
workspace: workspace.workspaceId,
|
|
72393
|
+
path: path19,
|
|
72394
|
+
requestBody: { enabled: true, force: opts.force }
|
|
72395
|
+
});
|
|
72396
|
+
} catch (e) {
|
|
72397
|
+
const conflict = parseForkConflict(e);
|
|
72398
|
+
if (conflict) {
|
|
72399
|
+
error(`Cannot enable schedule '${path19}': the parent workspace '${conflict.parentWorkspaceId}' has the same path configured. ` + `Both crons would fire on every tick and the script would run twice per scheduled time.
|
|
72400
|
+
` + `Re-run with --force to enable anyway.`);
|
|
72401
|
+
process.exit(1);
|
|
72402
|
+
}
|
|
72403
|
+
throw e;
|
|
72404
|
+
}
|
|
71608
72405
|
info(colors.green(`Schedule ${path19} enabled.`));
|
|
71609
72406
|
}
|
|
72407
|
+
function parseForkConflict(e) {
|
|
72408
|
+
const body = e?.body;
|
|
72409
|
+
const raw = typeof body === "string" ? body : e?.message ?? "";
|
|
72410
|
+
const m = String(raw).match(/fork-conflict:([^:]+):(.+)/);
|
|
72411
|
+
if (!m)
|
|
72412
|
+
return;
|
|
72413
|
+
return { kind: m[1], parentWorkspaceId: m[2].trim() };
|
|
72414
|
+
}
|
|
71610
72415
|
async function disable(opts, path19) {
|
|
71611
72416
|
opts = await mergeConfigWithConfigFile(opts);
|
|
71612
72417
|
const workspace = await resolveWorkspace(opts);
|
|
@@ -71632,7 +72437,7 @@ async function push8(opts, filePath, remotePath) {
|
|
|
71632
72437
|
await pushSchedule(workspace.workspaceId, remotePath, undefined, parseFromFile(filePath));
|
|
71633
72438
|
console.log(colors.bold.underline.green("Schedule pushed"));
|
|
71634
72439
|
}
|
|
71635
|
-
var import_yaml26,
|
|
72440
|
+
var import_yaml26, command16, schedule_default;
|
|
71636
72441
|
var init_schedule = __esm(async () => {
|
|
71637
72442
|
init_mod3();
|
|
71638
72443
|
init_mod6();
|
|
@@ -71647,7 +72452,7 @@ var init_schedule = __esm(async () => {
|
|
|
71647
72452
|
init_types()
|
|
71648
72453
|
]);
|
|
71649
72454
|
import_yaml26 = __toESM(require_dist(), 1);
|
|
71650
|
-
|
|
72455
|
+
command16 = new Command().description("schedule related commands").option("--json", "Output as JSON (for piping to jq)").action(list9).command("list", "list all schedules").option("--json", "Output as JSON (for piping to jq)").action(list9).command("get", "get a schedule's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get7).command("new", "create a new schedule locally").arguments("<path:string>").action(newSchedule).command("push", "push a local schedule spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push8).command("enable", "Enable a schedule").option("--force", "Bypass the fork-conflict warning when the parent workspace has the same schedule (acknowledges that both crons will fire)").arguments("<path:string>").action(enable).command("disable", "Disable a schedule").arguments("<path:string>").action(disable).command("set-permissioned-as", "Set the email (run-as user) for a schedule (requires admin or wm_deployers group)").arguments("<path:string> <email:string>").action(async (opts, schedulePath, email) => {
|
|
71651
72456
|
const workspace = await resolveWorkspace(opts);
|
|
71652
72457
|
await requireLogin(opts);
|
|
71653
72458
|
const cache3 = new Map;
|
|
@@ -71669,7 +72474,7 @@ var init_schedule = __esm(async () => {
|
|
|
71669
72474
|
});
|
|
71670
72475
|
info(colors.green(`Updated permissioned_as for schedule ${schedulePath} to ${email} (username: ${username})`));
|
|
71671
72476
|
});
|
|
71672
|
-
schedule_default =
|
|
72477
|
+
schedule_default = command16;
|
|
71673
72478
|
});
|
|
71674
72479
|
|
|
71675
72480
|
// src/commands/instance/slack.ts
|
|
@@ -72763,7 +73568,7 @@ async function whoami3(opts) {
|
|
|
72763
73568
|
error(colors.red(`Failed to retrieve whoami information: ${error2.message}`));
|
|
72764
73569
|
}
|
|
72765
73570
|
}
|
|
72766
|
-
var import_yaml29,
|
|
73571
|
+
var import_yaml29, command17, instance_default;
|
|
72767
73572
|
var init_instance = __esm(async () => {
|
|
72768
73573
|
init_colors2();
|
|
72769
73574
|
init_mod3();
|
|
@@ -72788,7 +73593,7 @@ var init_instance = __esm(async () => {
|
|
|
72788
73593
|
init_workspace()
|
|
72789
73594
|
]);
|
|
72790
73595
|
import_yaml29 = __toESM(require_dist(), 1);
|
|
72791
|
-
|
|
73596
|
+
command17 = new Command().description("sync local with a remote instance or the opposite (push or pull)").action(async () => {
|
|
72792
73597
|
info("4 actions available, add, remove, switch, pull and push. Use -h to display help.");
|
|
72793
73598
|
const activeInstance = await getActiveInstance({});
|
|
72794
73599
|
new Table2().header(["name", "remote", "token"]).padding(2).border(true).body((await allInstances()).map((x) => [
|
|
@@ -72814,7 +73619,7 @@ var init_instance = __esm(async () => {
|
|
|
72814
73619
|
await removeInstance(choice);
|
|
72815
73620
|
info(colors.green.underline(`Removed instance ${choice}`));
|
|
72816
73621
|
}).command("switch").complete("instance", async () => (await allInstances()).map((x) => x.name)).arguments("<instance:string:instance>").description("Switch the current instance").action(switchI).command("pull").description("Pull instance settings, users, configs, instance groups and overwrite local").option("--yes", "Pull without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pulling users").option("--skip-settings", "Skip pulling settings").option("--skip-configs", "Skip pulling configs (worker groups)").option("--skip-groups", "Skip pulling instance groups").option("--include-workspaces", "Also pull workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to pull from, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces to pull, used to create the folders when using --include-workspaces").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePull).command("push").description("Push instance settings, users, configs, group and overwrite remote").option("--yes", "Push without needing confirmation").option("--dry-run", "Perform a dry run without making changes").option("--skip-users", "Skip pushing users").option("--skip-settings", "Skip pushing settings").option("--skip-configs", "Skip pushing configs (worker groups)").option("--skip-groups", "Skip pushing instance groups").option("--include-workspaces", "Also push workspaces").option("--folder-per-instance", "Create a folder per instance").option("--instance <instance:string>", "Name of the instance to push to, override the active instance").option("--prefix <prefix:string>", "Prefix of the local workspaces folders to push").option("--prefix-settings", "Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance").action(instancePush).command("whoami").description("Display information about the currently logged-in user").action(whoami3).command("get-config").description("Dump the current instance config (global settings + worker configs) as YAML").option("-o, --output-file <file:string>", "Write YAML to a file instead of stdout").option("--show-secrets", "Include sensitive fields (license key, JWT secret) without prompting").option("--instance <instance:string>", "Name of the instance, override the active instance").action(getConfig2).command("connect-slack").description("Non-interactively connect Slack at the instance level using a pre-minted bot token (xoxb-...). Produces the same artifacts as the UI OAuth flow: global_settings 'slack' row + encrypted f/slack_bot/global_bot_token variable and resource in the admins workspace.").option("--bot-token <bot_token:string>", "Slack bot token (xoxb-...)", { required: true }).option("--team-id <team_id:string>", "Slack team id", { required: true }).option("--team-name <team_name:string>", "Slack team name", { required: true }).option("--instance <instance:string>", "Instance profile to connect against (defaults to the active instance)").action((opts) => connectSlackInstance2(opts));
|
|
72817
|
-
instance_default =
|
|
73622
|
+
instance_default = command17;
|
|
72818
73623
|
});
|
|
72819
73624
|
|
|
72820
73625
|
// src/commands/user/user.ts
|
|
@@ -73169,7 +73974,7 @@ async function pushInstanceGroups(opts, preview2 = false) {
|
|
|
73169
73974
|
info(colors.green("Groups pushed to the instance"));
|
|
73170
73975
|
}
|
|
73171
73976
|
}
|
|
73172
|
-
var import_yaml31, INSTANCE_USERS_PATH = "instance_users.yaml", instanceUsersPath, INSTANCE_GROUPS_PATH = "instance_groups.yaml", instanceGroupsPath,
|
|
73977
|
+
var import_yaml31, INSTANCE_USERS_PATH = "instance_users.yaml", instanceUsersPath, INSTANCE_GROUPS_PATH = "instance_groups.yaml", instanceGroupsPath, command18, user_default;
|
|
73173
73978
|
var init_user = __esm(async () => {
|
|
73174
73979
|
init_colors2();
|
|
73175
73980
|
init_mod3();
|
|
@@ -73185,12 +73990,12 @@ var init_user = __esm(async () => {
|
|
|
73185
73990
|
import_yaml31 = __toESM(require_dist(), 1);
|
|
73186
73991
|
instanceUsersPath = INSTANCE_USERS_PATH;
|
|
73187
73992
|
instanceGroupsPath = INSTANCE_GROUPS_PATH;
|
|
73188
|
-
|
|
73993
|
+
command18 = new Command().description("user related commands").action(list10).command("add", "Create a user").arguments("<email:string> [password:string]").option("--superadmin", "Specify to make the new user superadmin.").option("--company <company:string>", "Specify to set the company of the new user.").option("--name <name:string>", "Specify to set the name of the new user.").action(add3).command("remove", "Delete a user").arguments("<email:string>").action(remove2).command("create-token", "Create a new API token for the authenticated user").option("--email <email:string>", "Specify credentials to use for authentication. This will not be stored. It will only be used to exchange for a token with the API server, which will not be stored either.", {
|
|
73189
73994
|
depends: ["password"]
|
|
73190
73995
|
}).option("--password <password:string>", "Specify credentials to use for authentication. This will not be stored. It will only be used to exchange for a token with the API server, which will not be stored either.", {
|
|
73191
73996
|
depends: ["email"]
|
|
73192
73997
|
}).action(createToken2);
|
|
73193
|
-
user_default =
|
|
73998
|
+
user_default = command18;
|
|
73194
73999
|
});
|
|
73195
74000
|
|
|
73196
74001
|
// src/commands/dependencies/dependencies.ts
|
|
@@ -73239,7 +74044,7 @@ async function pushWorkspaceDependencies(workspace, path20, _befObj, newDependen
|
|
|
73239
74044
|
});
|
|
73240
74045
|
info(colors.green(`Successfully pushed ${displayName} for ${language}`));
|
|
73241
74046
|
}
|
|
73242
|
-
var
|
|
74047
|
+
var command19, dependencies_default;
|
|
73243
74048
|
var init_dependencies = __esm(async () => {
|
|
73244
74049
|
init_colors2();
|
|
73245
74050
|
init_mod3();
|
|
@@ -73251,14 +74056,14 @@ var init_dependencies = __esm(async () => {
|
|
|
73251
74056
|
init_metadata(),
|
|
73252
74057
|
init_utils()
|
|
73253
74058
|
]);
|
|
73254
|
-
|
|
73255
|
-
dependencies_default =
|
|
74059
|
+
command19 = new Command().alias("deps").description("workspace dependencies related commands").command("push", "Push workspace dependencies from a local file").arguments("<file_path:string>").action(push9);
|
|
74060
|
+
dependencies_default = command19;
|
|
73256
74061
|
});
|
|
73257
74062
|
|
|
73258
74063
|
// src/commands/trigger/trigger.ts
|
|
73259
74064
|
import { mkdir as mkdir12, stat as stat15, writeFile as writeFile17 } from "node:fs/promises";
|
|
73260
74065
|
import { dirname as dirname16 } from "node:path";
|
|
73261
|
-
import { sep as
|
|
74066
|
+
import { sep as SEP18 } from "node:path";
|
|
73262
74067
|
async function getTrigger(triggerType, workspace, path20) {
|
|
73263
74068
|
const triggerFunctions = {
|
|
73264
74069
|
http: getHttpTrigger,
|
|
@@ -73309,7 +74114,7 @@ async function createTrigger(triggerType, workspace, path20, trigger) {
|
|
|
73309
74114
|
await triggerFunction({ workspace, path: path20, requestBody: trigger });
|
|
73310
74115
|
}
|
|
73311
74116
|
async function pushTrigger(triggerType, workspace, path20, trigger, localTrigger, permissionedAsContext) {
|
|
73312
|
-
path20 = removeType(path20, triggerType + "_trigger").replaceAll(
|
|
74117
|
+
path20 = removeType(path20, triggerType + "_trigger").replaceAll(SEP18, "/");
|
|
73313
74118
|
debug(`Processing local ${triggerType} trigger ${path20}`);
|
|
73314
74119
|
try {
|
|
73315
74120
|
trigger = await getTrigger(triggerType, workspace, path20);
|
|
@@ -73615,7 +74420,7 @@ async function push10(opts, filePath, remotePath) {
|
|
|
73615
74420
|
await pushTrigger(triggerKind, workspace.workspaceId, remotePath, undefined, parseFromFile(filePath));
|
|
73616
74421
|
console.log(colors.bold.underline.green("Trigger pushed"));
|
|
73617
74422
|
}
|
|
73618
|
-
var import_yaml33, triggerTemplates, TRIGGER_SKIP_FIELDS,
|
|
74423
|
+
var import_yaml33, triggerTemplates, TRIGGER_SKIP_FIELDS, command20, trigger_default;
|
|
73619
74424
|
var init_trigger = __esm(async () => {
|
|
73620
74425
|
init_services_gen();
|
|
73621
74426
|
init_mod3();
|
|
@@ -73721,7 +74526,7 @@ var init_trigger = __esm(async () => {
|
|
|
73721
74526
|
}
|
|
73722
74527
|
};
|
|
73723
74528
|
TRIGGER_SKIP_FIELDS = new Set(["workspace_id", "extra_perms", "edited_by", "edited_at"]);
|
|
73724
|
-
|
|
74529
|
+
command20 = new Command().description("trigger related commands").option("--json", "Output as JSON (for piping to jq)").action(list11).command("list", "list all triggers").option("--json", "Output as JSON (for piping to jq)").action(list11).command("get", "get a trigger's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").option("--kind <kind:string>", "Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email). Recommended for faster lookup").action(get8).command("new", "create a new trigger locally").arguments("<path:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)").action(newTrigger).command("push", "push a local trigger spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").action(push10).command("set-permissioned-as", "Set the email (run-as user) for a trigger (requires admin or wm_deployers group)").arguments("<path:string> <email:string>").option("--kind <kind:string>", "Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)").action(async (opts, triggerPath, email) => {
|
|
73725
74530
|
const workspace = await resolveWorkspace(opts);
|
|
73726
74531
|
await requireLogin(opts);
|
|
73727
74532
|
if (!opts.kind) {
|
|
@@ -73744,12 +74549,12 @@ var init_trigger = __esm(async () => {
|
|
|
73744
74549
|
});
|
|
73745
74550
|
info(colors.green(`Updated permissioned_as for ${opts.kind} trigger ${triggerPath} to ${email} (username: ${username})`));
|
|
73746
74551
|
});
|
|
73747
|
-
trigger_default =
|
|
74552
|
+
trigger_default = command20;
|
|
73748
74553
|
});
|
|
73749
74554
|
|
|
73750
74555
|
// src/types.ts
|
|
73751
74556
|
import * as path20 from "node:path";
|
|
73752
|
-
import { sep as
|
|
74557
|
+
import { sep as SEP19 } from "node:path";
|
|
73753
74558
|
function isSuperset(subset, superset) {
|
|
73754
74559
|
return Object.keys(subset).every((key) => {
|
|
73755
74560
|
const eq = deepEqual(subset[key], superset[key]);
|
|
@@ -73893,7 +74698,7 @@ function getTypeStrFromPath(p) {
|
|
|
73893
74698
|
if (isRawAppPath(p)) {
|
|
73894
74699
|
return "raw_app";
|
|
73895
74700
|
}
|
|
73896
|
-
if (p.startsWith("dependencies" +
|
|
74701
|
+
if (p.startsWith("dependencies" + SEP19)) {
|
|
73897
74702
|
return "workspace_dependencies";
|
|
73898
74703
|
}
|
|
73899
74704
|
if (isFileResource(p) || isFilesetResource(p)) {
|
|
@@ -73923,7 +74728,7 @@ function getTypeStrFromPath(p) {
|
|
|
73923
74728
|
}
|
|
73924
74729
|
}
|
|
73925
74730
|
function removeType(str, type) {
|
|
73926
|
-
const normalizedStr = path20.normalize(str).replaceAll(
|
|
74731
|
+
const normalizedStr = path20.normalize(str).replaceAll(SEP19, "/");
|
|
73927
74732
|
if (normalizedStr.endsWith("." + type + ".yaml") || normalizedStr.endsWith("." + type + ".json")) {
|
|
73928
74733
|
return normalizedStr.slice(0, normalizedStr.length - type.length - 6);
|
|
73929
74734
|
}
|
|
@@ -73933,7 +74738,7 @@ function removeType(str, type) {
|
|
|
73933
74738
|
return normalizedStr;
|
|
73934
74739
|
}
|
|
73935
74740
|
function extractNativeTriggerInfo(p) {
|
|
73936
|
-
const normalizedPath = path20.normalize(p).replaceAll(
|
|
74741
|
+
const normalizedPath = path20.normalize(p).replaceAll(SEP19, "/");
|
|
73937
74742
|
const withoutExt = normalizedPath.replace(/\.(json|yaml)$/, "");
|
|
73938
74743
|
const match2 = withoutExt.match(/^(.+)\.(flow|script)\.([^.]+)\.(\w+)_native_trigger$/);
|
|
73939
74744
|
if (!match2) {
|
|
@@ -73947,8 +74752,8 @@ function extractNativeTriggerInfo(p) {
|
|
|
73947
74752
|
};
|
|
73948
74753
|
}
|
|
73949
74754
|
function removePathPrefix(str, prefix) {
|
|
73950
|
-
const normalizedStr = path20.normalize(str).replaceAll(
|
|
73951
|
-
const normalizedPrefix = path20.normalize(prefix).replaceAll(
|
|
74755
|
+
const normalizedStr = path20.normalize(str).replaceAll(SEP19, "/");
|
|
74756
|
+
const normalizedPrefix = path20.normalize(prefix).replaceAll(SEP19, "/");
|
|
73952
74757
|
if (normalizedStr === normalizedPrefix) {
|
|
73953
74758
|
return "";
|
|
73954
74759
|
}
|
|
@@ -74120,7 +74925,7 @@ var init_local_path_scripts = __esm(async () => {
|
|
|
74120
74925
|
});
|
|
74121
74926
|
|
|
74122
74927
|
// src/commands/flow/flow.ts
|
|
74123
|
-
import { sep as
|
|
74928
|
+
import { sep as SEP20 } from "node:path";
|
|
74124
74929
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
74125
74930
|
function normalizeOptionalString(value) {
|
|
74126
74931
|
return typeof value === "string" && value.trim() === "" ? undefined : value ?? undefined;
|
|
@@ -74181,7 +74986,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74181
74986
|
return;
|
|
74182
74987
|
}
|
|
74183
74988
|
alreadySynced3.push(localPath);
|
|
74184
|
-
remotePath = remotePath.replaceAll(
|
|
74989
|
+
remotePath = remotePath.replaceAll(SEP20, "/");
|
|
74185
74990
|
let flow = undefined;
|
|
74186
74991
|
try {
|
|
74187
74992
|
flow = await getFlowByPath({
|
|
@@ -74189,18 +74994,18 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74189
74994
|
path: remotePath
|
|
74190
74995
|
});
|
|
74191
74996
|
} catch {}
|
|
74192
|
-
if (!localPath.endsWith(
|
|
74193
|
-
localPath +=
|
|
74997
|
+
if (!localPath.endsWith(SEP20)) {
|
|
74998
|
+
localPath += SEP20;
|
|
74194
74999
|
}
|
|
74195
75000
|
const localFlow = await yamlParseFile(localPath + "flow.yaml");
|
|
74196
75001
|
const fileReader = async (path21) => await readTextFile(localPath + path21);
|
|
74197
75002
|
const missingFiles = [];
|
|
74198
|
-
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath,
|
|
75003
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74199
75004
|
if (localFlow.value.failure_module) {
|
|
74200
|
-
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath,
|
|
75005
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74201
75006
|
}
|
|
74202
75007
|
if (localFlow.value.preprocessor_module) {
|
|
74203
|
-
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, localPath,
|
|
75008
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74204
75009
|
}
|
|
74205
75010
|
if (missingFiles.length > 0) {
|
|
74206
75011
|
warn(colors.yellow(`Warning: missing inline script file(s): ${missingFiles.join(", ")}. ` + `The flow will be pushed with unresolved !inline references.`));
|
|
@@ -74223,9 +75028,9 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74223
75028
|
info(colors.bold.yellow(`Updating flow ${remotePath}...`));
|
|
74224
75029
|
await updateFlow({
|
|
74225
75030
|
workspace,
|
|
74226
|
-
path: remotePath.replaceAll(
|
|
75031
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74227
75032
|
requestBody: {
|
|
74228
|
-
path: remotePath.replaceAll(
|
|
75033
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74229
75034
|
deployment_message: message,
|
|
74230
75035
|
...localFlow,
|
|
74231
75036
|
...preserveFields
|
|
@@ -74237,7 +75042,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74237
75042
|
await createFlow({
|
|
74238
75043
|
workspace,
|
|
74239
75044
|
requestBody: {
|
|
74240
|
-
path: remotePath.replaceAll(
|
|
75045
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74241
75046
|
deployment_message: message,
|
|
74242
75047
|
...localFlow,
|
|
74243
75048
|
...preserveFields
|
|
@@ -74486,25 +75291,25 @@ async function preview2(opts, flowPath) {
|
|
|
74486
75291
|
const workspace = await resolveWorkspace(opts);
|
|
74487
75292
|
await requireLogin(opts);
|
|
74488
75293
|
const codebases = useLocalPathScripts ? listSyncCodebases(opts) : [];
|
|
74489
|
-
const isFlowDir = flowPath.endsWith(".flow") || flowPath.endsWith(".flow" +
|
|
75294
|
+
const isFlowDir = flowPath.endsWith(".flow") || flowPath.endsWith(".flow" + SEP20) || flowPath.endsWith("__flow") || flowPath.endsWith("__flow" + SEP20);
|
|
74490
75295
|
if (!isFlowDir) {
|
|
74491
75296
|
if (flowPath.endsWith("flow.yaml") || flowPath.endsWith("flow.json")) {
|
|
74492
|
-
flowPath = flowPath.substring(0, flowPath.lastIndexOf(
|
|
75297
|
+
flowPath = flowPath.substring(0, flowPath.lastIndexOf(SEP20));
|
|
74493
75298
|
} else {
|
|
74494
75299
|
throw new Error("Flow path must be a .flow/__flow directory or a flow.yaml file");
|
|
74495
75300
|
}
|
|
74496
75301
|
}
|
|
74497
|
-
if (!flowPath.endsWith(
|
|
74498
|
-
flowPath +=
|
|
75302
|
+
if (!flowPath.endsWith(SEP20)) {
|
|
75303
|
+
flowPath += SEP20;
|
|
74499
75304
|
}
|
|
74500
75305
|
const localFlow = await yamlParseFile(flowPath + "flow.yaml");
|
|
74501
75306
|
const fileReader = async (path21) => await readTextFile(flowPath + path21);
|
|
74502
|
-
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath,
|
|
75307
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath, SEP20);
|
|
74503
75308
|
if (localFlow.value.failure_module) {
|
|
74504
|
-
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath,
|
|
75309
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath, SEP20);
|
|
74505
75310
|
}
|
|
74506
75311
|
if (localFlow.value.preprocessor_module) {
|
|
74507
|
-
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath,
|
|
75312
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath, SEP20);
|
|
74508
75313
|
}
|
|
74509
75314
|
if (useLocalPathScripts) {
|
|
74510
75315
|
const scriptPaths = collectPathScriptPaths(localFlow.value);
|
|
@@ -74534,7 +75339,7 @@ async function preview2(opts, flowPath) {
|
|
|
74534
75339
|
workspace: workspace.workspaceId,
|
|
74535
75340
|
requestBody: {
|
|
74536
75341
|
value: localFlow.value,
|
|
74537
|
-
path: flowPath.substring(0, flowPath.indexOf(".flow")).replaceAll(
|
|
75342
|
+
path: flowPath.substring(0, flowPath.indexOf(".flow")).replaceAll(SEP20, "/"),
|
|
74538
75343
|
args: input
|
|
74539
75344
|
}
|
|
74540
75345
|
});
|
|
@@ -74566,8 +75371,8 @@ async function generateLocks(opts, folder) {
|
|
|
74566
75371
|
} else {
|
|
74567
75372
|
const ignore = await ignoreF(opts);
|
|
74568
75373
|
const elems = Object.keys(await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => {
|
|
74569
|
-
return ignore(p, isD) || !isD && !p.endsWith(
|
|
74570
|
-
}, false, {})).map((x) => x.substring(0, x.lastIndexOf(
|
|
75374
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP20 + "flow.yaml") && !p.endsWith(SEP20 + "flow.json");
|
|
75375
|
+
}, false, {})).map((x) => x.substring(0, x.lastIndexOf(SEP20)));
|
|
74571
75376
|
let hasAny = false;
|
|
74572
75377
|
for (const folder2 of elems) {
|
|
74573
75378
|
const candidate = await generateFlowLockInternal(folder2, true, workspace, opts);
|
|
@@ -74666,7 +75471,7 @@ async function showVersion(opts, flowPath, version) {
|
|
|
74666
75471
|
console.log(JSON.stringify(flow.value, null, 2));
|
|
74667
75472
|
}
|
|
74668
75473
|
}
|
|
74669
|
-
var import_yaml36, alreadySynced3,
|
|
75474
|
+
var import_yaml36, alreadySynced3, command21, flow_default;
|
|
74670
75475
|
var init_flow = __esm(async () => {
|
|
74671
75476
|
init_colors2();
|
|
74672
75477
|
init_mod3();
|
|
@@ -74691,7 +75496,7 @@ var init_flow = __esm(async () => {
|
|
|
74691
75496
|
]);
|
|
74692
75497
|
import_yaml36 = __toESM(require_dist(), 1);
|
|
74693
75498
|
alreadySynced3 = [];
|
|
74694
|
-
|
|
75499
|
+
command21 = new Command().description("flow related commands").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list12).command("list", "list all flows").option("--show-archived", "Enable archived flows in output").option("--json", "Output as JSON (for piping to jq)").action(list12).command("get", "get a flow's details").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(get9).command("push", "push a local flow spec. This overrides any remote versions.").arguments("<file_path:string> <remote_path:string>").option("--message <message:string>", "Deployment message").action(push11).command("run", "run a flow by path.").arguments("<path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not ouput anything other then the final output. Useful for scripting.").action(run3).command("preview", "preview a local flow without deploying it. Runs the flow definition from local files and uses local PathScripts by default.").arguments("<flow_path:string>").option("-d --data <data:string>", "Inputs specified as a JSON string or a file using @<filename> or stdin using @-.").option("-s --silent", "Do not output anything other then the final output. Useful for scripting.").option("--remote", "Use deployed workspace scripts for PathScript steps instead of local files.").action(preview2).command("generate-locks", 'DEPRECATED: re-generate flow lock files. Use "wmill generate-metadata" instead.').arguments("[flow:file]").option("--yes", "Skip confirmation prompt").option("--dry-run", "Perform a dry run without making changes").option("-i --includes <patterns:file[]>", "Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string)").option("-e --excludes <patterns:file[]>", "Comma separated patterns to specify which file to NOT take into account.").action(generateLocks).command("new", "create a new empty flow").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2).command("bootstrap", "create a new empty flow (alias for new)").arguments("<flow_path:string>").option("--summary <summary:string>", "flow summary").option("--description <description:string>", "flow description").action(bootstrap2).command("history", "Show version history for a flow").arguments("<path:string>").option("--json", "Output as JSON (for piping to jq)").action(history2).command("show-version", "Show a specific version of a flow").arguments("<path:string> <version:string>").option("--json", "Output as JSON (for piping to jq)").action(showVersion).command("set-permissioned-as", "Set the on_behalf_of_email for a flow (requires admin or wm_deployers group)").arguments("<path:string> <email:string>").action(async (opts, flowPath, email) => {
|
|
74695
75500
|
const workspace = await resolveWorkspace(opts);
|
|
74696
75501
|
await requireLogin(opts);
|
|
74697
75502
|
const remote = await getFlowByPath({
|
|
@@ -74712,7 +75517,7 @@ var init_flow = __esm(async () => {
|
|
|
74712
75517
|
});
|
|
74713
75518
|
info(colors.green(`Updated permissioned_as for flow ${flowPath} to ${email}`));
|
|
74714
75519
|
});
|
|
74715
|
-
flow_default =
|
|
75520
|
+
flow_default = command21;
|
|
74716
75521
|
});
|
|
74717
75522
|
|
|
74718
75523
|
// src/commands/gitsync-settings/converter.ts
|
|
@@ -75651,286 +76456,15 @@ __export(exports_gitsync_settings, {
|
|
|
75651
76456
|
pullGitSyncSettings: () => pullGitSyncSettings,
|
|
75652
76457
|
default: () => gitsync_settings_default
|
|
75653
76458
|
});
|
|
75654
|
-
var
|
|
76459
|
+
var command23, gitsync_settings_default;
|
|
75655
76460
|
var init_gitsync_settings = __esm(async () => {
|
|
75656
76461
|
init_mod3();
|
|
75657
76462
|
await __promiseAll([
|
|
75658
76463
|
init_pull2(),
|
|
75659
76464
|
init_push()
|
|
75660
76465
|
]);
|
|
75661
|
-
|
|
75662
|
-
gitsync_settings_default =
|
|
75663
|
-
});
|
|
75664
|
-
|
|
75665
|
-
// src/utils/dependency_tree.ts
|
|
75666
|
-
async function uploadScripts(tree, workspace) {
|
|
75667
|
-
const scriptHashes = {};
|
|
75668
|
-
const workspaceDeps = [];
|
|
75669
|
-
for (const path22 of tree.allPaths()) {
|
|
75670
|
-
const content = tree.getContent(path22);
|
|
75671
|
-
const itemType = tree.getItemType(path22);
|
|
75672
|
-
if (itemType === "dependencies") {
|
|
75673
|
-
if (content === undefined)
|
|
75674
|
-
continue;
|
|
75675
|
-
const info2 = workspaceDependenciesPathToLanguageAndFilename(path22);
|
|
75676
|
-
if (info2) {
|
|
75677
|
-
const hash2 = await generateHash(content);
|
|
75678
|
-
workspaceDeps.push({ path: path22, language: info2.language, name: info2.name, hash: hash2 });
|
|
75679
|
-
}
|
|
75680
|
-
} else if (itemType === "script") {
|
|
75681
|
-
if (!content)
|
|
75682
|
-
continue;
|
|
75683
|
-
const hash2 = await generateHash(content);
|
|
75684
|
-
scriptHashes[path22] = hash2;
|
|
75685
|
-
}
|
|
75686
|
-
}
|
|
75687
|
-
if (Object.keys(scriptHashes).length === 0 && workspaceDeps.length === 0)
|
|
75688
|
-
return;
|
|
75689
|
-
const mismatched = await diffRawScriptsWithDeployed({
|
|
75690
|
-
workspace: workspace.workspaceId,
|
|
75691
|
-
requestBody: {
|
|
75692
|
-
scripts: scriptHashes,
|
|
75693
|
-
workspace_deps: workspaceDeps
|
|
75694
|
-
}
|
|
75695
|
-
});
|
|
75696
|
-
for (const path22 of mismatched) {
|
|
75697
|
-
const content = tree.getContent(path22);
|
|
75698
|
-
const itemType = tree.getItemType(path22);
|
|
75699
|
-
if (itemType === "dependencies") {
|
|
75700
|
-
if (content !== undefined) {
|
|
75701
|
-
tree.setContentHash(path22, "mismatched");
|
|
75702
|
-
}
|
|
75703
|
-
} else if (content) {
|
|
75704
|
-
const hash2 = await storeRawScriptTemp({
|
|
75705
|
-
workspace: workspace.workspaceId,
|
|
75706
|
-
requestBody: content
|
|
75707
|
-
});
|
|
75708
|
-
tree.setContentHash(path22, hash2);
|
|
75709
|
-
}
|
|
75710
|
-
}
|
|
75711
|
-
}
|
|
75712
|
-
|
|
75713
|
-
class DoubleLinkedDependencyTree {
|
|
75714
|
-
nodes = new Map;
|
|
75715
|
-
workspaceDeps = {};
|
|
75716
|
-
setWorkspaceDeps(deps) {
|
|
75717
|
-
this.workspaceDeps = deps;
|
|
75718
|
-
}
|
|
75719
|
-
async addNode(path22, content, language, metadata, imports, itemType, folder, originalPath, isDirectlyStale, isRawApp) {
|
|
75720
|
-
const hasWorkspaceDeps = itemType === "script" || itemType === "inline_script";
|
|
75721
|
-
const filteredDeps = hasWorkspaceDeps ? filterWorkspaceDependencies(this.workspaceDeps, content, language) : {};
|
|
75722
|
-
const stalenessHash = await generateScriptHash({}, content, metadata);
|
|
75723
|
-
if (!this.nodes.has(path22)) {
|
|
75724
|
-
this.nodes.set(path22, {
|
|
75725
|
-
content: "",
|
|
75726
|
-
stalenessHash: "",
|
|
75727
|
-
language: "deno",
|
|
75728
|
-
metadata: "",
|
|
75729
|
-
imports: new Set,
|
|
75730
|
-
importedBy: new Set,
|
|
75731
|
-
itemType: "script",
|
|
75732
|
-
folder: "",
|
|
75733
|
-
originalPath: "",
|
|
75734
|
-
isDirectlyStale: false
|
|
75735
|
-
});
|
|
75736
|
-
}
|
|
75737
|
-
const node = this.nodes.get(path22);
|
|
75738
|
-
node.content = content;
|
|
75739
|
-
node.stalenessHash = stalenessHash;
|
|
75740
|
-
node.language = language;
|
|
75741
|
-
node.metadata = metadata;
|
|
75742
|
-
node.itemType = itemType;
|
|
75743
|
-
node.folder = folder;
|
|
75744
|
-
node.originalPath = originalPath;
|
|
75745
|
-
node.isDirectlyStale = isDirectlyStale;
|
|
75746
|
-
node.isRawApp = isRawApp;
|
|
75747
|
-
const filteredDepsPaths = Object.keys(filteredDeps);
|
|
75748
|
-
for (const depsPath of filteredDepsPaths) {
|
|
75749
|
-
if (!this.nodes.has(depsPath)) {
|
|
75750
|
-
const depsInfo = workspaceDependenciesPathToLanguageAndFilename(depsPath);
|
|
75751
|
-
const contentHash = await generateHash(filteredDeps[depsPath] + depsPath);
|
|
75752
|
-
const isUpToDate = await checkifMetadataUptodate(depsPath, contentHash, undefined);
|
|
75753
|
-
this.nodes.set(depsPath, {
|
|
75754
|
-
content: filteredDeps[depsPath],
|
|
75755
|
-
stalenessHash: "",
|
|
75756
|
-
language: depsInfo?.language ?? "deno",
|
|
75757
|
-
metadata: "",
|
|
75758
|
-
imports: new Set,
|
|
75759
|
-
importedBy: new Set,
|
|
75760
|
-
itemType: "dependencies",
|
|
75761
|
-
folder: "",
|
|
75762
|
-
originalPath: depsPath,
|
|
75763
|
-
isDirectlyStale: !isUpToDate
|
|
75764
|
-
});
|
|
75765
|
-
}
|
|
75766
|
-
}
|
|
75767
|
-
const allImports = [...imports, ...filteredDepsPaths];
|
|
75768
|
-
for (const importPath of allImports) {
|
|
75769
|
-
node.imports.add(importPath);
|
|
75770
|
-
if (!this.nodes.has(importPath)) {
|
|
75771
|
-
this.nodes.set(importPath, {
|
|
75772
|
-
content: "",
|
|
75773
|
-
stalenessHash: "",
|
|
75774
|
-
language: "deno",
|
|
75775
|
-
metadata: "",
|
|
75776
|
-
imports: new Set,
|
|
75777
|
-
importedBy: new Set,
|
|
75778
|
-
itemType: "script",
|
|
75779
|
-
folder: "",
|
|
75780
|
-
originalPath: "",
|
|
75781
|
-
isDirectlyStale: false
|
|
75782
|
-
});
|
|
75783
|
-
}
|
|
75784
|
-
this.nodes.get(importPath).importedBy.add(path22);
|
|
75785
|
-
}
|
|
75786
|
-
}
|
|
75787
|
-
getContent(path22) {
|
|
75788
|
-
return this.nodes.get(path22)?.content;
|
|
75789
|
-
}
|
|
75790
|
-
getStalenessHash(path22) {
|
|
75791
|
-
return this.nodes.get(path22)?.stalenessHash;
|
|
75792
|
-
}
|
|
75793
|
-
getContentHash(path22) {
|
|
75794
|
-
return this.nodes.get(path22)?.contentHash;
|
|
75795
|
-
}
|
|
75796
|
-
setContentHash(path22, hash2) {
|
|
75797
|
-
const node = this.nodes.get(path22);
|
|
75798
|
-
if (node) {
|
|
75799
|
-
node.contentHash = hash2;
|
|
75800
|
-
}
|
|
75801
|
-
}
|
|
75802
|
-
getLanguage(path22) {
|
|
75803
|
-
return this.nodes.get(path22)?.language;
|
|
75804
|
-
}
|
|
75805
|
-
getMetadata(path22) {
|
|
75806
|
-
return this.nodes.get(path22)?.metadata;
|
|
75807
|
-
}
|
|
75808
|
-
getStaleReason(path22) {
|
|
75809
|
-
return this.nodes.get(path22)?.staleReason;
|
|
75810
|
-
}
|
|
75811
|
-
getItemType(path22) {
|
|
75812
|
-
return this.nodes.get(path22)?.itemType;
|
|
75813
|
-
}
|
|
75814
|
-
getFolder(path22) {
|
|
75815
|
-
return this.nodes.get(path22)?.folder;
|
|
75816
|
-
}
|
|
75817
|
-
getIsRawApp(path22) {
|
|
75818
|
-
return this.nodes.get(path22)?.isRawApp;
|
|
75819
|
-
}
|
|
75820
|
-
getIsDirectlyStale(path22) {
|
|
75821
|
-
return this.nodes.get(path22)?.isDirectlyStale ?? false;
|
|
75822
|
-
}
|
|
75823
|
-
getOriginalPath(path22) {
|
|
75824
|
-
return this.nodes.get(path22)?.originalPath;
|
|
75825
|
-
}
|
|
75826
|
-
getImports(path22) {
|
|
75827
|
-
return this.nodes.get(path22)?.imports;
|
|
75828
|
-
}
|
|
75829
|
-
isStale(path22) {
|
|
75830
|
-
return this.nodes.get(path22)?.staleReason !== undefined;
|
|
75831
|
-
}
|
|
75832
|
-
propagateStaleness() {
|
|
75833
|
-
const directlyStale = new Set;
|
|
75834
|
-
for (const [path22, node] of this.nodes.entries()) {
|
|
75835
|
-
if (node.isDirectlyStale) {
|
|
75836
|
-
directlyStale.add(path22);
|
|
75837
|
-
node.staleReason = "content changed";
|
|
75838
|
-
}
|
|
75839
|
-
}
|
|
75840
|
-
const allStale = new Set(directlyStale);
|
|
75841
|
-
const queue = [...directlyStale];
|
|
75842
|
-
const visited = new Set;
|
|
75843
|
-
while (queue.length > 0) {
|
|
75844
|
-
const scriptPath = queue.shift();
|
|
75845
|
-
if (visited.has(scriptPath))
|
|
75846
|
-
continue;
|
|
75847
|
-
visited.add(scriptPath);
|
|
75848
|
-
const node = this.nodes.get(scriptPath);
|
|
75849
|
-
if (!node)
|
|
75850
|
-
continue;
|
|
75851
|
-
for (const importer of node.importedBy) {
|
|
75852
|
-
if (!allStale.has(importer)) {
|
|
75853
|
-
allStale.add(importer);
|
|
75854
|
-
queue.push(importer);
|
|
75855
|
-
const importerNode = this.nodes.get(importer);
|
|
75856
|
-
if (importerNode)
|
|
75857
|
-
importerNode.staleReason = `depends on ${scriptPath}`;
|
|
75858
|
-
}
|
|
75859
|
-
}
|
|
75860
|
-
}
|
|
75861
|
-
}
|
|
75862
|
-
traverseTransitive(scriptPath, callback) {
|
|
75863
|
-
const queue = [scriptPath];
|
|
75864
|
-
const visited = new Set;
|
|
75865
|
-
while (queue.length > 0) {
|
|
75866
|
-
const current = queue.shift();
|
|
75867
|
-
if (visited.has(current))
|
|
75868
|
-
continue;
|
|
75869
|
-
visited.add(current);
|
|
75870
|
-
const node = this.nodes.get(current);
|
|
75871
|
-
if (!node)
|
|
75872
|
-
continue;
|
|
75873
|
-
for (const importPath of node.imports) {
|
|
75874
|
-
const importNode = this.nodes.get(importPath);
|
|
75875
|
-
if (importNode) {
|
|
75876
|
-
const stop = callback(importPath, importNode);
|
|
75877
|
-
if (!stop) {
|
|
75878
|
-
queue.push(importPath);
|
|
75879
|
-
}
|
|
75880
|
-
}
|
|
75881
|
-
}
|
|
75882
|
-
}
|
|
75883
|
-
}
|
|
75884
|
-
allPaths() {
|
|
75885
|
-
return this.nodes.keys();
|
|
75886
|
-
}
|
|
75887
|
-
*stalePaths() {
|
|
75888
|
-
for (const [path22, node] of this.nodes.entries()) {
|
|
75889
|
-
if (node.staleReason) {
|
|
75890
|
-
yield path22;
|
|
75891
|
-
}
|
|
75892
|
-
}
|
|
75893
|
-
}
|
|
75894
|
-
has(path22) {
|
|
75895
|
-
return this.nodes.has(path22);
|
|
75896
|
-
}
|
|
75897
|
-
getMismatchedWorkspaceDeps() {
|
|
75898
|
-
const result2 = {};
|
|
75899
|
-
for (const [path22, node] of this.nodes.entries()) {
|
|
75900
|
-
if (node.itemType === "dependencies" && node.contentHash && node.content !== undefined) {
|
|
75901
|
-
result2[path22] = node.content;
|
|
75902
|
-
}
|
|
75903
|
-
}
|
|
75904
|
-
return result2;
|
|
75905
|
-
}
|
|
75906
|
-
getTempScriptRefs(scriptPath) {
|
|
75907
|
-
const result2 = {};
|
|
75908
|
-
this.traverseTransitive(scriptPath, (_path, node) => {
|
|
75909
|
-
if (node.contentHash) {
|
|
75910
|
-
result2[_path] = node.contentHash;
|
|
75911
|
-
}
|
|
75912
|
-
});
|
|
75913
|
-
return result2;
|
|
75914
|
-
}
|
|
75915
|
-
async persistDepsHashes(depsPaths) {
|
|
75916
|
-
for (const path22 of depsPaths) {
|
|
75917
|
-
const node = this.nodes.get(path22);
|
|
75918
|
-
if (node?.itemType === "dependencies" && node.content !== undefined) {
|
|
75919
|
-
const hash2 = await generateHash(node.content + path22);
|
|
75920
|
-
await updateMetadataGlobalLock(path22, hash2);
|
|
75921
|
-
}
|
|
75922
|
-
}
|
|
75923
|
-
}
|
|
75924
|
-
get size() {
|
|
75925
|
-
return this.nodes.size;
|
|
75926
|
-
}
|
|
75927
|
-
}
|
|
75928
|
-
var init_dependency_tree = __esm(async () => {
|
|
75929
|
-
init_services_gen();
|
|
75930
|
-
await __promiseAll([
|
|
75931
|
-
init_metadata(),
|
|
75932
|
-
init_utils()
|
|
75933
|
-
]);
|
|
76466
|
+
command23 = new Command().description("Manage git-sync settings between local wmill.yaml and Windmill backend").command("pull").description("Pull git-sync settings from Windmill backend to local wmill.yaml").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo)").option("--default", "Write settings to top-level defaults instead of overrides").option("--replace", "Replace existing settings (non-interactive mode)").option("--override", "Add branch-specific override (non-interactive mode)").option("--diff", "Show differences without applying changes").option("--json-output", "Output in JSON format").option("--with-backend-settings <json:string>", "Use provided JSON settings instead of querying backend (for testing)").option("--yes", "Skip interactive prompts and use default behavior").option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides").action(pullGitSyncSettings).command("push").description("Push git-sync settings from local wmill.yaml to Windmill backend").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo)").option("--diff", "Show what would be pushed without applying changes").option("--json-output", "Output in JSON format").option("--with-backend-settings <json:string>", "Use provided JSON settings instead of querying backend (for testing)").option("--yes", "Skip interactive prompts and use default behavior").option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides").action(pushGitSyncSettings);
|
|
76467
|
+
gitsync_settings_default = command23;
|
|
75934
76468
|
});
|
|
75935
76469
|
|
|
75936
76470
|
// src/main.ts
|
|
@@ -77207,8 +77741,8 @@ async function pull2(opts) {
|
|
|
77207
77741
|
await pushResourceType(workspace.workspaceId, x.name + ".resource-type.json", undefined, x);
|
|
77208
77742
|
}
|
|
77209
77743
|
}
|
|
77210
|
-
var
|
|
77211
|
-
var hub_default =
|
|
77744
|
+
var command22 = new Command().name("hub").description("Hub related commands. EXPERIMENTAL. INTERNAL USE ONLY.").command("pull").description("pull any supported definitions. EXPERIMENTAL.").action(pull2);
|
|
77745
|
+
var hub_default = command22;
|
|
77212
77746
|
|
|
77213
77747
|
// src/main.ts
|
|
77214
77748
|
await __promiseAll([
|
|
@@ -77299,8 +77833,8 @@ async function pushWorkerGroups(opts) {
|
|
|
77299
77833
|
await pushInstanceConfigs(opts, false);
|
|
77300
77834
|
}
|
|
77301
77835
|
}
|
|
77302
|
-
var
|
|
77303
|
-
var worker_groups_default =
|
|
77836
|
+
var command24 = new Command().description("display worker groups, pull and push worker groups configs").action(displayWorkerGroups).command("pull").description("Pull worker groups (similar to `wmill instance pull --skip-users --skip-settings --skip-groups`)").option("--instance", "Name of the instance to push to, override the active instance").option("--base-url", "Base url to be passed to the instance settings instead of the local one").option("--yes", "Pull without needing confirmation").action(pullWorkerGroups).command("push").description("Push worker groups (similar to `wmill instance push --skip-users --skip-settings --skip-groups`)").option("--instance [instance]", "Name of the instance to push to, override the active instance").option("--base-url [baseUrl]", "If used with --token, will be used as the base url for the instance").option("--yes", "Push without needing confirmation").action(pushWorkerGroups);
|
|
77837
|
+
var worker_groups_default = command24;
|
|
77304
77838
|
|
|
77305
77839
|
// src/main.ts
|
|
77306
77840
|
await init_lint();
|
|
@@ -77329,7 +77863,7 @@ await __promiseAll([
|
|
|
77329
77863
|
init_local_path_scripts()
|
|
77330
77864
|
]);
|
|
77331
77865
|
var import_yaml40 = __toESM(require_dist(), 1);
|
|
77332
|
-
import { sep as
|
|
77866
|
+
import { sep as SEP21 } from "node:path";
|
|
77333
77867
|
import * as http3 from "node:http";
|
|
77334
77868
|
import * as https from "node:https";
|
|
77335
77869
|
import { access, readdir as readdir10, realpath, stat as stat17, unlink, writeFile as writeFile19 } from "node:fs/promises";
|
|
@@ -77582,7 +78116,7 @@ async function dev2(opts) {
|
|
|
77582
78116
|
if (paths.length == 0) {
|
|
77583
78117
|
return;
|
|
77584
78118
|
}
|
|
77585
|
-
const nativePath = (await realpath(paths[0])).replace(base +
|
|
78119
|
+
const nativePath = (await realpath(paths[0])).replace(base + SEP21, "");
|
|
77586
78120
|
const cpath = nativePath.replaceAll("\\", "/");
|
|
77587
78121
|
const insideFlow = isInsideFlowFolder(cpath);
|
|
77588
78122
|
if (insideFlow || !ignore(nativePath, false)) {
|
|
@@ -77599,7 +78133,7 @@ async function dev2(opts) {
|
|
|
77599
78133
|
return;
|
|
77600
78134
|
const wmFlowPath = stripFolderSuffix(localPath.replace(/\/$/, ""), FLOW_SUFFIXES);
|
|
77601
78135
|
const localFlow = await yamlParseFile(localPath + "flow.yaml");
|
|
77602
|
-
await replaceInlineScripts(localFlow.value.modules, async (path22) => await readTextFile(localPath + path22), exports_log, localPath,
|
|
78136
|
+
await replaceInlineScripts(localFlow.value.modules, async (path22) => await readTextFile(localPath + path22), exports_log, localPath, SEP21, undefined);
|
|
77603
78137
|
snapshotPathScripts(localFlow.value);
|
|
77604
78138
|
const localScriptReader = createPreviewLocalScriptReader({
|
|
77605
78139
|
exts,
|
|
@@ -77652,7 +78186,7 @@ async function dev2(opts) {
|
|
|
77652
78186
|
if (!flowDir || !flowYaml)
|
|
77653
78187
|
throw new Error("not a flow");
|
|
77654
78188
|
const localFlow = await yamlParseFile(flowYaml);
|
|
77655
|
-
await replaceInlineScripts(localFlow.value.modules, async (p) => await readTextFile(flowDir + p), exports_log, flowDir,
|
|
78189
|
+
await replaceInlineScripts(localFlow.value.modules, async (p) => await readTextFile(flowDir + p), exports_log, flowDir, SEP21, undefined);
|
|
77656
78190
|
snapshotPathScripts(localFlow.value);
|
|
77657
78191
|
const localScriptReader = createPreviewLocalScriptReader({
|
|
77658
78192
|
exts,
|
|
@@ -77999,8 +78533,8 @@ async function dev2(opts) {
|
|
|
77999
78533
|
await Promise.all([startServer(), watchChanges()]);
|
|
78000
78534
|
console.log("Stopped dev mode");
|
|
78001
78535
|
}
|
|
78002
|
-
var
|
|
78003
|
-
var dev_default2 =
|
|
78536
|
+
var command25 = new Command().description("Watch local file changes and live-reload the dev page for preview. Does NOT deploy to the remote workspace — use wmill sync push for that.").option("--includes <pattern...:string>", "Filter paths given a glob pattern or path").option("--proxy-port <port:number>", "Port for a localhost reverse proxy to the remote Windmill server").option("--path <path:string>", "Watch a specific windmill path (e.g., u/admin/my_script or f/my_flow)").option("--no-open", "Do not open the browser automatically").action(dev2);
|
|
78537
|
+
var dev_default2 = command25;
|
|
78004
78538
|
|
|
78005
78539
|
// src/main.ts
|
|
78006
78540
|
init_gen();
|
|
@@ -78114,8 +78648,8 @@ Worker Group: ${group.groupName} (${group.workers.length} workers)`);
|
|
|
78114
78648
|
info("Use 'wmill instance add' to add a new instance");
|
|
78115
78649
|
}
|
|
78116
78650
|
}
|
|
78117
|
-
var
|
|
78118
|
-
var workers_default =
|
|
78651
|
+
var command26 = new Command().description("List all workers grouped by worker groups").option("--instance [instance]", "Name of the instance to push to, override the active instance").option("--base-url [baseUrl]", "If used with --token, will be used as the base url for the instance").action(displayWorkers);
|
|
78652
|
+
var workers_default = command26;
|
|
78119
78653
|
|
|
78120
78654
|
// src/commands/queues/queues.ts
|
|
78121
78655
|
init_mod3();
|
|
@@ -78223,8 +78757,8 @@ async function displayQueues(opts, workspace) {
|
|
|
78223
78757
|
info("Use 'wmill instance add' to add a new instance");
|
|
78224
78758
|
}
|
|
78225
78759
|
}
|
|
78226
|
-
var
|
|
78227
|
-
var queues_default =
|
|
78760
|
+
var command27 = new Command().description("List all queues with their metrics").arguments("[workspace:string] the optional workspace to filter by (default to all workspaces)").option("--instance [instance]", "Name of the instance to push to, override the active instance").option("--base-url [baseUrl]", "If used with --token, will be used as the base url for the instance").action(displayQueues);
|
|
78761
|
+
var queues_default = command27;
|
|
78228
78762
|
|
|
78229
78763
|
// src/main.ts
|
|
78230
78764
|
await init_dependencies();
|
|
@@ -78276,7 +78810,7 @@ When a new app needs to be created, YOU run \`wmill app new\` yourself with \`--
|
|
|
78276
78810
|
|
|
78277
78811
|
## Triggers
|
|
78278
78812
|
|
|
78279
|
-
You MUST use the \`triggers\` skill to configure HTTP routes, WebSocket, Kafka, NATS, SQS, MQTT, GCP, or Postgres CDC triggers.
|
|
78813
|
+
You MUST use the \`triggers\` skill to configure HTTP routes, WebSocket, Kafka, NATS, SQS, MQTT, GCP, Azure, Email, or Postgres CDC triggers.
|
|
78280
78814
|
|
|
78281
78815
|
## Schedules
|
|
78282
78816
|
|
|
@@ -83871,6 +84405,49 @@ Examples:
|
|
|
83871
84405
|
- \`u/user/webhook.http_trigger.yaml\`
|
|
83872
84406
|
- \`f/data/kafka_consumer.kafka_trigger.yaml\`
|
|
83873
84407
|
- \`f/sync/postgres_cdc.postgres_trigger.yaml\`
|
|
84408
|
+
- \`f/inbound/orders.email_trigger.yaml\`
|
|
84409
|
+
|
|
84410
|
+
## Email Triggers
|
|
84411
|
+
|
|
84412
|
+
An email trigger routes incoming emails to a script or flow. Each trigger reserves a local-part: emails sent to \`<local_part>@<windmill_email_domain>\` are delivered to the configured runnable. Set \`workspaced_local_part: true\` to namespace it per workspace (the actual recipient becomes \`<workspace_id>-<local_part>@…\`); on Windmill Cloud this is required.
|
|
84413
|
+
|
|
84414
|
+
Senders may append URL-style extras to the local-part with \`+\`: \`mytrigger+foo=bar+baz=qux@…\`. They flow through to the script as \`email_extra_args\` (see below).
|
|
84415
|
+
|
|
84416
|
+
### Payload
|
|
84417
|
+
|
|
84418
|
+
The runnable receives:
|
|
84419
|
+
|
|
84420
|
+
- \`parsed_email\` — \`{ headers, text_body, html_body, attachments[] }\`. Each \`attachment\` has \`{ headers, body }\`.
|
|
84421
|
+
- \`raw_email\` — the raw RFC 822 message as a string, **or** an S3 object (\`{ s3: "windmill_emails/<job_id>/raw.eml" }\`) if the message exceeds 1 MiB.
|
|
84422
|
+
- \`email_extra_args\` (optional, only when sender appended \`+key=value\` extras) — a flat object of the parsed extras.
|
|
84423
|
+
|
|
84424
|
+
With a preprocessor, all of the above are nested under \`event\` along with \`event.kind = "email"\` and \`event.trigger_path\` (the trigger's path). Without a preprocessor, \`trigger_path\` is **not** exposed — add a preprocessor if you need it.
|
|
84425
|
+
|
|
84426
|
+
### Attachments are S3 objects
|
|
84427
|
+
|
|
84428
|
+
Binary attachments are uploaded to the workspace S3 bucket and surface in \`parsed_email.attachments[i].body\` as:
|
|
84429
|
+
|
|
84430
|
+
\`\`\`json
|
|
84431
|
+
{ "s3": "windmill_emails/<job_id>/attachments/<filename>" }
|
|
84432
|
+
\`\`\`
|
|
84433
|
+
|
|
84434
|
+
To read the bytes inside a script, use the wmill SDK:
|
|
84435
|
+
|
|
84436
|
+
\`\`\`ts
|
|
84437
|
+
// TypeScript
|
|
84438
|
+
import * as wmill from "windmill-client"
|
|
84439
|
+
const file = await wmill.loadS3File(parsed_email.attachments[0].body)
|
|
84440
|
+
\`\`\`
|
|
84441
|
+
|
|
84442
|
+
\`\`\`python
|
|
84443
|
+
# Python
|
|
84444
|
+
import wmill
|
|
84445
|
+
data = wmill.load_s3_file(parsed_email["attachments"][0]["body"])
|
|
84446
|
+
\`\`\`
|
|
84447
|
+
|
|
84448
|
+
If the workspace has no S3 resource configured (Workspace Settings → Object storage), \`body\` falls back to the string \`"configure s3 in the workspace settings to handle attachments"\`. The same applies to large \`raw_email\` bodies. Email attachment storage requires the server to be built with the \`parquet\` feature.
|
|
84449
|
+
|
|
84450
|
+
Text/HTML/inline parts are placed inline in \`body\` as strings.
|
|
83874
84451
|
|
|
83875
84452
|
## CLI Commands
|
|
83876
84453
|
|
|
@@ -84804,6 +85381,15 @@ Generate metadata (locks, schemas) for all scripts, flows, and apps
|
|
|
84804
85381
|
- \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
|
|
84805
85382
|
- \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
|
|
84806
85383
|
|
|
85384
|
+
**Subcommands:**
|
|
85385
|
+
|
|
85386
|
+
- \`generate-metadata rehash [folder:string]\`
|
|
85387
|
+
- \`--skip-scripts\` - Skip processing scripts
|
|
85388
|
+
- \`--skip-flows\` - Skip processing flows
|
|
85389
|
+
- \`--skip-apps\` - Skip processing apps
|
|
85390
|
+
- \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
|
|
85391
|
+
- \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
|
|
85392
|
+
|
|
84807
85393
|
### gitsync-settings
|
|
84808
85394
|
|
|
84809
85395
|
Manage git-sync settings between local wmill.yaml and Windmill backend
|
|
@@ -85012,6 +85598,7 @@ schedule related commands
|
|
|
85012
85598
|
- \`schedule new <path:string>\` - create a new schedule locally
|
|
85013
85599
|
- \`schedule push <file_path:string> <remote_path:string>\` - push a local schedule spec. This overrides any remote versions.
|
|
85014
85600
|
- \`schedule enable <path:string>\` - Enable a schedule
|
|
85601
|
+
- \`--force\` - Bypass the fork-conflict warning when the parent workspace has the same schedule (acknowledges that both crons will fire)
|
|
85015
85602
|
- \`schedule disable <path:string>\` - Disable a schedule
|
|
85016
85603
|
- \`schedule set-permissioned-as <path:string> <email:string>\` - Set the email (run-as user) for a schedule (requires admin or wm_deployers group)
|
|
85017
85604
|
|
|
@@ -85477,6 +86064,71 @@ required:
|
|
|
85477
86064
|
- azure_mode
|
|
85478
86065
|
- scope_resource_id
|
|
85479
86066
|
- subscription_name
|
|
86067
|
+
`,
|
|
86068
|
+
email_trigger: `type: object
|
|
86069
|
+
properties:
|
|
86070
|
+
script_path:
|
|
86071
|
+
type: string
|
|
86072
|
+
description: Path to the script or flow to execute when triggered
|
|
86073
|
+
permissioned_as:
|
|
86074
|
+
type: string
|
|
86075
|
+
description: The user or group this trigger runs as (permissioned_as)
|
|
86076
|
+
is_flow:
|
|
86077
|
+
type: boolean
|
|
86078
|
+
description: True if script_path points to a flow, false if it points to a script
|
|
86079
|
+
labels:
|
|
86080
|
+
type: array
|
|
86081
|
+
items:
|
|
86082
|
+
type: string
|
|
86083
|
+
local_part:
|
|
86084
|
+
type: string
|
|
86085
|
+
workspaced_local_part:
|
|
86086
|
+
type: boolean
|
|
86087
|
+
error_handler_path:
|
|
86088
|
+
type: string
|
|
86089
|
+
error_handler_args:
|
|
86090
|
+
type: object
|
|
86091
|
+
description: The arguments to pass to the script or flow
|
|
86092
|
+
retry:
|
|
86093
|
+
type: object
|
|
86094
|
+
properties:
|
|
86095
|
+
constant:
|
|
86096
|
+
type: object
|
|
86097
|
+
description: Retry with constant delay between attempts
|
|
86098
|
+
properties:
|
|
86099
|
+
attempts:
|
|
86100
|
+
type: integer
|
|
86101
|
+
description: Number of retry attempts
|
|
86102
|
+
seconds:
|
|
86103
|
+
type: integer
|
|
86104
|
+
description: Seconds to wait between retries
|
|
86105
|
+
exponential:
|
|
86106
|
+
type: object
|
|
86107
|
+
description: Retry with exponential backoff (delay doubles each time)
|
|
86108
|
+
properties:
|
|
86109
|
+
attempts:
|
|
86110
|
+
type: integer
|
|
86111
|
+
description: Number of retry attempts
|
|
86112
|
+
multiplier:
|
|
86113
|
+
type: integer
|
|
86114
|
+
description: Multiplier for exponential backoff
|
|
86115
|
+
seconds:
|
|
86116
|
+
type: integer
|
|
86117
|
+
minimum: 1
|
|
86118
|
+
description: Initial delay in seconds
|
|
86119
|
+
random_factor:
|
|
86120
|
+
type: integer
|
|
86121
|
+
minimum: 0
|
|
86122
|
+
maximum: 100
|
|
86123
|
+
description: Random jitter percentage (0-100) to avoid thundering herd
|
|
86124
|
+
retry_if:
|
|
86125
|
+
$ref: '#/components/schemas/RetryIf'
|
|
86126
|
+
description: Retry configuration for failed module executions
|
|
86127
|
+
required:
|
|
86128
|
+
- script_path
|
|
86129
|
+
- permissioned_as
|
|
86130
|
+
- is_flow
|
|
86131
|
+
- local_part
|
|
85480
86132
|
`,
|
|
85481
86133
|
gcp_trigger: `type: object
|
|
85482
86134
|
properties:
|
|
@@ -86404,7 +87056,8 @@ var SCHEMA_MAPPINGS = {
|
|
|
86404
87056
|
{ name: "MqttTrigger", schemaKey: "mqtt_trigger", filePattern: "*.mqtt_trigger.yaml" },
|
|
86405
87057
|
{ name: "SqsTrigger", schemaKey: "sqs_trigger", filePattern: "*.sqs_trigger.yaml" },
|
|
86406
87058
|
{ name: "GcpTrigger", schemaKey: "gcp_trigger", filePattern: "*.gcp_trigger.yaml" },
|
|
86407
|
-
{ name: "AzureTrigger", schemaKey: "azure_trigger", filePattern: "*.azure_trigger.yaml" }
|
|
87059
|
+
{ name: "AzureTrigger", schemaKey: "azure_trigger", filePattern: "*.azure_trigger.yaml" },
|
|
87060
|
+
{ name: "EmailTrigger", schemaKey: "email_trigger", filePattern: "*.email_trigger.yaml" }
|
|
86408
87061
|
],
|
|
86409
87062
|
schedules: [
|
|
86410
87063
|
{ name: "Schedule", schemaKey: "schedule", filePattern: "*.schedule.yaml" }
|
|
@@ -87225,8 +87878,8 @@ async function initAction(opts) {
|
|
|
87225
87878
|
info(colors.gray("Skipped resource type namespace generation (no workspace bound). Run 'wmill workspace bind' then 'wmill init' to generate it."));
|
|
87226
87879
|
}
|
|
87227
87880
|
}
|
|
87228
|
-
var
|
|
87229
|
-
var init_default =
|
|
87881
|
+
var command28 = new Command().description("Bootstrap a windmill project with a wmill.yaml file").option("--use-default", "Use default settings without checking backend").option("--use-backend", "Use backend git-sync settings if available").option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo) when using backend settings").option("--bind-profile", "Automatically bind active workspace profile to current Git branch").option("--no-bind-profile", "Skip workspace profile binding prompt").action(initAction);
|
|
87882
|
+
var init_default = command28;
|
|
87230
87883
|
|
|
87231
87884
|
// src/commands/jobs/jobs.ts
|
|
87232
87885
|
init_mod3();
|
|
@@ -87392,8 +88045,8 @@ Warning: Found ${workers.length} active worker(s) on the instance.`));
|
|
|
87392
88045
|
}
|
|
87393
88046
|
var pull3 = new Command().description("Pull completed and queued jobs from workspace").option("-c, --completed-output <file:string>", "Completed jobs output file (default: completed_jobs.json)").option("-q, --queued-output <file:string>", "Queued jobs output file (default: queued_jobs.json)").option("--skip-worker-check", "Skip checking for active workers before export").arguments("[workspace:string]").action(pullJobs);
|
|
87394
88047
|
var push12 = new Command().description("Push completed and queued jobs to workspace").option("-c, --completed-file <file:string>", "Completed jobs input file (default: completed_jobs.json)").option("-q, --queued-file <file:string>", "Queued jobs input file (default: queued_jobs.json)").option("--skip-worker-check", "Skip checking for active workers before import").arguments("[workspace:string]").action(pushJobs);
|
|
87395
|
-
var
|
|
87396
|
-
var jobs_default =
|
|
88048
|
+
var command29 = new Command().description("Manage jobs (import/export)").command("pull", pull3).command("push", push12);
|
|
88049
|
+
var jobs_default = command29;
|
|
87397
88050
|
|
|
87398
88051
|
// src/commands/job/job.ts
|
|
87399
88052
|
init_mod3();
|
|
@@ -87707,8 +88360,8 @@ async function cancel(opts, id) {
|
|
|
87707
88360
|
info(colors.green(`Job ${id} canceled.`));
|
|
87708
88361
|
}
|
|
87709
88362
|
var listOptions = (cmd) => cmd.option("--json", "Output as JSON (for piping to jq)").option("--script-path <scriptPath:string>", "Filter by exact script/flow path").option("--created-by <createdBy:string>", "Filter by creator username").option("--running", "Show only running jobs").option("--failed", "Show only failed jobs").option("--success <success:boolean>", "Filter by success status (true/false)").option("--limit <limit:number>", "Number of jobs to return (default 30, max 100)").option("--job-kinds <jobKinds:string>", "Filter by job kinds (default: script,flow,singlestepflow)").option("--label <label:string>", "Filter by job label").option("--all", "Include sub-jobs (flow steps). By default only top-level jobs are shown").option("--parent <parent:string>", "Filter by parent job ID (show sub-jobs of a specific flow)").option("--is-flow-step", "Show only flow step jobs");
|
|
87710
|
-
var
|
|
87711
|
-
var job_default =
|
|
88363
|
+
var command30 = listOptions(new Command().description("Manage jobs (list, inspect, cancel)")).action(list13).command("list", listOptions(new Command().description("List recent jobs"))).action(list13).command("get", "Get job details. For flows: shows step tree with sub-job IDs").arguments("<id:string>").option("--json", "Output as JSON (for piping to jq)").action(get10).command("result", "Get the result of a completed job (machine-friendly)").arguments("<id:string>").action(result).command("logs", "Get job logs. For flows: aggregates all step logs").arguments("<id:string>").action(logs).command("cancel", "Cancel a running or queued job").arguments("<id:string>").option("--reason <reason:string>", "Reason for cancellation").action(cancel);
|
|
88364
|
+
var job_default = command30;
|
|
87712
88365
|
|
|
87713
88366
|
// src/commands/group/group.ts
|
|
87714
88367
|
init_mod3();
|
|
@@ -87807,8 +88460,8 @@ async function removeUser(opts, name, username) {
|
|
|
87807
88460
|
});
|
|
87808
88461
|
info(colors.green(`User '${username}' removed from group '${name}'.`));
|
|
87809
88462
|
}
|
|
87810
|
-
var
|
|
87811
|
-
var group_default =
|
|
88463
|
+
var command31 = new Command().description("Manage workspace groups").option("--json", "Output as JSON (for piping to jq)").action(list14).command("list", "List all groups in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list14).command("get", "Get group details and members").arguments("<name:string>").option("--json", "Output as JSON (for piping to jq)").action(get11).command("create", "Create a new group").arguments("<name:string>").option("--summary <summary:string>", "Group summary/description").action(create).command("delete", "Delete a group").arguments("<name:string>").action(deleteGroup2).command("add-user", "Add a user to a group").arguments("<name:string> <username:string>").action(addUser2).command("remove-user", "Remove a user from a group").arguments("<name:string> <username:string>").action(removeUser);
|
|
88464
|
+
var group_default = command31;
|
|
87812
88465
|
|
|
87813
88466
|
// src/commands/audit/audit.ts
|
|
87814
88467
|
init_mod3();
|
|
@@ -87885,8 +88538,8 @@ async function get12(opts, id) {
|
|
|
87885
88538
|
}
|
|
87886
88539
|
}
|
|
87887
88540
|
var auditListOptions = (cmd) => cmd.option("--json", "Output as JSON (for piping to jq)").option("--username <username:string>", "Filter by username").option("--operation <operation:string>", "Filter by operation (exact or prefix)").option("--action-kind <actionKind:string>", "Filter by action kind (Create, Update, Delete, Execute)").option("--before <before:string>", "Filter events before this timestamp").option("--after <after:string>", "Filter events after this timestamp").option("--limit <limit:number>", "Number of entries to return (default 30, max 100)");
|
|
87888
|
-
var
|
|
87889
|
-
var audit_default =
|
|
88541
|
+
var command32 = auditListOptions(new Command().description("View audit logs (requires admin)")).action(list15).command("list", auditListOptions(new Command().description("List audit log entries"))).action(list15).command("get", "Get a specific audit log entry").arguments("<id:string>").option("--json", "Output as JSON (for piping to jq)").action(get12);
|
|
88542
|
+
var audit_default = command32;
|
|
87890
88543
|
|
|
87891
88544
|
// src/commands/token/token.ts
|
|
87892
88545
|
init_mod3();
|
|
@@ -87940,253 +88593,11 @@ async function deleteToken2(opts, tokenPrefix) {
|
|
|
87940
88593
|
await deleteToken({ tokenPrefix });
|
|
87941
88594
|
info(colors.green(`Token with prefix '${tokenPrefix}' deleted.`));
|
|
87942
88595
|
}
|
|
87943
|
-
var
|
|
87944
|
-
var token_default =
|
|
88596
|
+
var command33 = new Command().description("Manage API tokens").option("--json", "Output as JSON (for piping to jq)").action(list16).command("list", "List API tokens").option("--json", "Output as JSON (for piping to jq)").action(list16).command("create", "Create a new API token").option("--label <label:string>", "Token label").option("--expiration <expiration:string>", "Token expiration (ISO 8601 timestamp)").action(create2).command("delete", "Delete a token by its prefix").arguments("<token_prefix:string>").action(deleteToken2);
|
|
88597
|
+
var token_default = command33;
|
|
87945
88598
|
|
|
87946
|
-
// src/
|
|
87947
|
-
|
|
87948
|
-
init_colors2();
|
|
87949
|
-
init_log();
|
|
87950
|
-
await __promiseAll([
|
|
87951
|
-
init_confirm(),
|
|
87952
|
-
init_conf(),
|
|
87953
|
-
init_context(),
|
|
87954
|
-
init_auth(),
|
|
87955
|
-
init_metadata(),
|
|
87956
|
-
init_flow_metadata(),
|
|
87957
|
-
init_app_metadata(),
|
|
87958
|
-
init_sync(),
|
|
87959
|
-
init_script(),
|
|
87960
|
-
init_resource_folders(),
|
|
87961
|
-
init_codebase(),
|
|
87962
|
-
init_dependency_tree()
|
|
87963
|
-
]);
|
|
87964
|
-
import { sep as SEP21 } from "node:path";
|
|
87965
|
-
async function generateMetadata2(opts, folder) {
|
|
87966
|
-
if (folder === "") {
|
|
87967
|
-
folder = undefined;
|
|
87968
|
-
}
|
|
87969
|
-
const workspace = await resolveWorkspace(opts);
|
|
87970
|
-
await requireLogin(opts);
|
|
87971
|
-
opts = await mergeConfigWithConfigFile(opts);
|
|
87972
|
-
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(false);
|
|
87973
|
-
const codebases = await listSyncCodebases(opts);
|
|
87974
|
-
const ignore = await ignoreF(opts);
|
|
87975
|
-
const skipScripts = opts.skipScripts ?? false;
|
|
87976
|
-
const skipFlows = opts.skipFlows ?? opts.schemaOnly ?? false;
|
|
87977
|
-
const skipApps = opts.skipApps ?? opts.schemaOnly ?? false;
|
|
87978
|
-
const checking = [];
|
|
87979
|
-
if (!skipScripts)
|
|
87980
|
-
checking.push("scripts");
|
|
87981
|
-
if (!skipFlows)
|
|
87982
|
-
checking.push("flows");
|
|
87983
|
-
if (!skipApps)
|
|
87984
|
-
checking.push("apps");
|
|
87985
|
-
if (checking.length === 0) {
|
|
87986
|
-
info(colors.yellow("Nothing to check (all types skipped)"));
|
|
87987
|
-
return;
|
|
87988
|
-
}
|
|
87989
|
-
info(`Checking ${checking.join(", ")}...`);
|
|
87990
|
-
const tree = new DoubleLinkedDependencyTree;
|
|
87991
|
-
tree.setWorkspaceDeps(rawWorkspaceDependencies);
|
|
87992
|
-
if (!skipScripts) {
|
|
87993
|
-
const scriptElems = await elementsToMap(await FSFSElement(process.cwd(), codebases, false), (p, isD) => {
|
|
87994
|
-
return !isD && !exts.some((ext2) => p.endsWith(ext2)) || ignore(p, isD) || isFolderResourcePathAnyFormat(p) || isScriptModulePath(p) && !isModuleEntryPoint(p);
|
|
87995
|
-
}, false, {});
|
|
87996
|
-
for (const e of Object.keys(scriptElems)) {
|
|
87997
|
-
await generateScriptMetadataInternal(e, workspace, opts, true, true, rawWorkspaceDependencies, codebases, false, tree);
|
|
87998
|
-
}
|
|
87999
|
-
}
|
|
88000
|
-
if (!skipFlows) {
|
|
88001
|
-
const flowElems = Object.keys(await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => {
|
|
88002
|
-
return ignore(p, isD) || !isD && !p.endsWith(SEP21 + "flow.yaml") && !p.endsWith(SEP21 + "flow.json");
|
|
88003
|
-
}, false, {})).map((x) => x.substring(0, x.lastIndexOf(SEP21)));
|
|
88004
|
-
for (const flowFolder of flowElems) {
|
|
88005
|
-
await generateFlowLockInternal(flowFolder, true, workspace, opts, false, true, tree);
|
|
88006
|
-
}
|
|
88007
|
-
}
|
|
88008
|
-
if (!skipApps) {
|
|
88009
|
-
const elems = await elementsToMap(await FSFSElement(process.cwd(), [], true), (p, isD) => {
|
|
88010
|
-
return ignore(p, isD) || !isD && !p.endsWith(SEP21 + "raw_app.yaml") && !p.endsWith(SEP21 + "app.yaml");
|
|
88011
|
-
}, false, {});
|
|
88012
|
-
const rawAppFolders = getAppFolders(elems, "raw_app.yaml");
|
|
88013
|
-
const appFolders = getAppFolders(elems, "app.yaml");
|
|
88014
|
-
for (const appFolder of rawAppFolders) {
|
|
88015
|
-
await generateAppLocksInternal(appFolder, true, true, workspace, opts, false, true, tree);
|
|
88016
|
-
}
|
|
88017
|
-
for (const appFolder of appFolders) {
|
|
88018
|
-
await generateAppLocksInternal(appFolder, false, true, workspace, opts, false, true, tree);
|
|
88019
|
-
}
|
|
88020
|
-
}
|
|
88021
|
-
tree.propagateStaleness();
|
|
88022
|
-
try {
|
|
88023
|
-
await uploadScripts(tree, workspace);
|
|
88024
|
-
} catch (e) {
|
|
88025
|
-
warn(colors.yellow(`Failed to upload scripts to temp storage (backend may be too old): ${e}. ` + `Locks will be generated using deployed script versions only — locally modified ` + `relative imports may not be reflected.`));
|
|
88026
|
-
}
|
|
88027
|
-
const staleItems = [];
|
|
88028
|
-
const seenFolders = new Set;
|
|
88029
|
-
for (const p of tree.allPaths()) {
|
|
88030
|
-
const staleReason = tree.getStaleReason(p);
|
|
88031
|
-
if (!staleReason)
|
|
88032
|
-
continue;
|
|
88033
|
-
const itemType = tree.getItemType(p);
|
|
88034
|
-
const itemFolder = tree.getFolder(p);
|
|
88035
|
-
if (itemType === "dependencies") {
|
|
88036
|
-
staleItems.push({ type: itemType, path: p, folder: itemFolder, staleReason });
|
|
88037
|
-
} else if (itemType === "inline_script") {
|
|
88038
|
-
continue;
|
|
88039
|
-
} else if (itemType === "script") {
|
|
88040
|
-
const originalPath = tree.getOriginalPath(p);
|
|
88041
|
-
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, staleReason });
|
|
88042
|
-
} else if (!seenFolders.has(itemFolder)) {
|
|
88043
|
-
seenFolders.add(itemFolder);
|
|
88044
|
-
const originalPath = tree.getOriginalPath(p);
|
|
88045
|
-
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, isRawApp: tree.getIsRawApp(p), staleReason });
|
|
88046
|
-
}
|
|
88047
|
-
}
|
|
88048
|
-
let filteredItems = staleItems;
|
|
88049
|
-
if (folder) {
|
|
88050
|
-
folder = folder.replaceAll("\\", "/");
|
|
88051
|
-
if (folder.endsWith("/")) {
|
|
88052
|
-
folder = folder.substring(0, folder.length - 1);
|
|
88053
|
-
}
|
|
88054
|
-
const folderNoExt = folder.replace(/\.[^/.]+$/, "");
|
|
88055
|
-
const isInsideFolder = (item) => {
|
|
88056
|
-
const normalizedFolder = item.folder.replaceAll("\\", "/");
|
|
88057
|
-
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
88058
|
-
return normalizedFolder === folder || normalizedFolder.startsWith(folder + "/") || normalizedPath === folder || normalizedPath === folderNoExt;
|
|
88059
|
-
};
|
|
88060
|
-
const isPathInFolder = (p) => p.startsWith(folder + "/") || p === folder || p === folderNoExt;
|
|
88061
|
-
const touchesFolder = (treePath) => {
|
|
88062
|
-
if (isPathInFolder(treePath))
|
|
88063
|
-
return true;
|
|
88064
|
-
let found = false;
|
|
88065
|
-
tree.traverseTransitive(treePath, (importPath) => {
|
|
88066
|
-
if (isPathInFolder(importPath)) {
|
|
88067
|
-
found = true;
|
|
88068
|
-
return true;
|
|
88069
|
-
}
|
|
88070
|
-
});
|
|
88071
|
-
return found;
|
|
88072
|
-
};
|
|
88073
|
-
const isRelevant = (item) => {
|
|
88074
|
-
if (isInsideFolder(item))
|
|
88075
|
-
return true;
|
|
88076
|
-
if (item.type === "dependencies")
|
|
88077
|
-
return true;
|
|
88078
|
-
const treePath = (item.type === "script" ? item.path.replace(/\.[^/.]+$/, "") : item.folder).replaceAll("\\", "/");
|
|
88079
|
-
return touchesFolder(treePath);
|
|
88080
|
-
};
|
|
88081
|
-
if (opts.strictFolderBoundaries) {
|
|
88082
|
-
filteredItems = staleItems.filter(isInsideFolder);
|
|
88083
|
-
const excludedStale = staleItems.filter((item) => !isInsideFolder(item) && isRelevant(item) && item.type !== "dependencies");
|
|
88084
|
-
for (const item of excludedStale) {
|
|
88085
|
-
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
88086
|
-
warn(colors.yellow(`Warning: ${normalizedPath} depends on something inside "${folder}" but is outside it — skipped due to --strict-folder-boundaries. Next generate-metadata will not detect it as stale.`));
|
|
88087
|
-
}
|
|
88088
|
-
} else {
|
|
88089
|
-
filteredItems = staleItems.filter(isRelevant);
|
|
88090
|
-
}
|
|
88091
|
-
}
|
|
88092
|
-
if (filteredItems.length === 0) {
|
|
88093
|
-
info(colors.green("All metadata up-to-date"));
|
|
88094
|
-
return;
|
|
88095
|
-
}
|
|
88096
|
-
const scripts = filteredItems.filter((i) => i.type === "script");
|
|
88097
|
-
const flows = filteredItems.filter((i) => i.type === "flow");
|
|
88098
|
-
const apps2 = filteredItems.filter((i) => i.type === "app");
|
|
88099
|
-
const deps = filteredItems.filter((i) => i.type === "dependencies");
|
|
88100
|
-
info("");
|
|
88101
|
-
info(`Found ${colors.bold(String(filteredItems.length))} item(s) with stale metadata:`);
|
|
88102
|
-
const printItems = (label, items) => {
|
|
88103
|
-
if (items.length === 0)
|
|
88104
|
-
return;
|
|
88105
|
-
info(` ${label} (${items.length}):`);
|
|
88106
|
-
for (const item of items) {
|
|
88107
|
-
const reason = item.staleReason ? colors.dim(colors.white(` — ${item.staleReason}`)) : "";
|
|
88108
|
-
info(` ~ ${item.path}` + reason);
|
|
88109
|
-
}
|
|
88110
|
-
};
|
|
88111
|
-
printItems("Workspace dependencies", deps);
|
|
88112
|
-
printItems("Scripts", scripts);
|
|
88113
|
-
printItems("Flows", flows);
|
|
88114
|
-
printItems("Apps", apps2);
|
|
88115
|
-
if (opts.dryRun) {
|
|
88116
|
-
return;
|
|
88117
|
-
}
|
|
88118
|
-
info("");
|
|
88119
|
-
const isInteractive = process.stdin.isTTY ?? false;
|
|
88120
|
-
if (!opts.yes && isInteractive && !await Confirm.prompt({
|
|
88121
|
-
message: "Update metadata?",
|
|
88122
|
-
default: true
|
|
88123
|
-
})) {
|
|
88124
|
-
return;
|
|
88125
|
-
}
|
|
88126
|
-
info("");
|
|
88127
|
-
const mismatchedWorkspaceDeps = tree.getMismatchedWorkspaceDeps();
|
|
88128
|
-
const total = filteredItems.length - deps.length;
|
|
88129
|
-
const maxWidth = `[${total}/${total}]`.length;
|
|
88130
|
-
let current = 0;
|
|
88131
|
-
const formatProgress = (n) => {
|
|
88132
|
-
return colors.dim(colors.white(`[${n}/${total}]`.padEnd(maxWidth, " ")));
|
|
88133
|
-
};
|
|
88134
|
-
const errors = [];
|
|
88135
|
-
for (const item of scripts) {
|
|
88136
|
-
current++;
|
|
88137
|
-
info(`${formatProgress(current)} script ${item.path}`);
|
|
88138
|
-
try {
|
|
88139
|
-
await generateScriptMetadataInternal(item.path, workspace, opts, false, true, mismatchedWorkspaceDeps, codebases, false, tree);
|
|
88140
|
-
} catch (e) {
|
|
88141
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
88142
|
-
errors.push({ path: item.path, error: msg });
|
|
88143
|
-
error(` Failed: ${msg}`);
|
|
88144
|
-
}
|
|
88145
|
-
}
|
|
88146
|
-
for (const item of flows) {
|
|
88147
|
-
current++;
|
|
88148
|
-
try {
|
|
88149
|
-
const result2 = await generateFlowLockInternal(item.folder.replaceAll("/", SEP21), false, workspace, opts, false, true, tree);
|
|
88150
|
-
const flowResult = result2;
|
|
88151
|
-
const scriptsInfo = flowResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${flowResult.updatedScripts.join(", ")}`)) : "";
|
|
88152
|
-
info(`${formatProgress(current)} flow ${item.path}${scriptsInfo}`);
|
|
88153
|
-
} catch (e) {
|
|
88154
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
88155
|
-
errors.push({ path: item.path, error: msg });
|
|
88156
|
-
info(`${formatProgress(current)} flow ${item.path}`);
|
|
88157
|
-
error(` Failed: ${msg}`);
|
|
88158
|
-
}
|
|
88159
|
-
}
|
|
88160
|
-
for (const item of apps2) {
|
|
88161
|
-
current++;
|
|
88162
|
-
try {
|
|
88163
|
-
const result2 = await generateAppLocksInternal(item.folder.replaceAll("/", SEP21), item.isRawApp, false, workspace, opts, false, true, tree);
|
|
88164
|
-
const appResult = result2;
|
|
88165
|
-
const scriptsInfo = appResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${appResult.updatedScripts.join(", ")}`)) : "";
|
|
88166
|
-
info(`${formatProgress(current)} app ${item.path}${scriptsInfo}`);
|
|
88167
|
-
} catch (e) {
|
|
88168
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
88169
|
-
errors.push({ path: item.path, error: msg });
|
|
88170
|
-
info(`${formatProgress(current)} app ${item.path}`);
|
|
88171
|
-
error(` Failed: ${msg}`);
|
|
88172
|
-
}
|
|
88173
|
-
}
|
|
88174
|
-
const allStaleDeps = staleItems.filter((i) => i.type === "dependencies");
|
|
88175
|
-
await tree.persistDepsHashes(allStaleDeps.map((d) => d.path));
|
|
88176
|
-
const succeeded = total - errors.length;
|
|
88177
|
-
info("");
|
|
88178
|
-
if (errors.length > 0) {
|
|
88179
|
-
info(`Done. Updated ${colors.bold(String(succeeded))}/${total} item(s). ${colors.red(String(errors.length) + " failed")}:`);
|
|
88180
|
-
for (const { path: path22, error: error2 } of errors) {
|
|
88181
|
-
error(` ${path22}: ${error2}`);
|
|
88182
|
-
}
|
|
88183
|
-
process.exitCode = 1;
|
|
88184
|
-
} else {
|
|
88185
|
-
info(`Done. Updated ${colors.bold(String(total))} item(s).`);
|
|
88186
|
-
}
|
|
88187
|
-
}
|
|
88188
|
-
var command33 = 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("--strict-folder-boundaries", "Only update items inside the specified folder (requires folder argument)").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);
|
|
88189
|
-
var generate_metadata_default = command33;
|
|
88599
|
+
// src/main.ts
|
|
88600
|
+
await init_generate_metadata();
|
|
88190
88601
|
|
|
88191
88602
|
// src/commands/docs/docs.ts
|
|
88192
88603
|
init_mod3();
|
|
@@ -88334,7 +88745,7 @@ var config_default = command35;
|
|
|
88334
88745
|
|
|
88335
88746
|
// src/main.ts
|
|
88336
88747
|
await init_context();
|
|
88337
|
-
var VERSION = "1.
|
|
88748
|
+
var VERSION = "1.694.0";
|
|
88338
88749
|
async function checkVersionSafe(cmd) {
|
|
88339
88750
|
const mainCommand = cmd.getMainCommand();
|
|
88340
88751
|
const upgradeCommand = mainCommand.getCommand("upgrade");
|