windmill-cli 1.693.4 → 1.693.5
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 +1124 -768
- package/package.json +1 -1
package/esm/main.js
CHANGED
|
@@ -5,43 +5,25 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
function __accessProp(key) {
|
|
9
|
-
return this[key];
|
|
10
|
-
}
|
|
11
|
-
var __toESMCache_node;
|
|
12
|
-
var __toESMCache_esm;
|
|
13
8
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
-
var canCache = mod != null && typeof mod === "object";
|
|
15
|
-
if (canCache) {
|
|
16
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
-
var cached = cache.get(mod);
|
|
18
|
-
if (cached)
|
|
19
|
-
return cached;
|
|
20
|
-
}
|
|
21
9
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
10
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
11
|
for (let key of __getOwnPropNames(mod))
|
|
24
12
|
if (!__hasOwnProp.call(to, key))
|
|
25
13
|
__defProp(to, key, {
|
|
26
|
-
get:
|
|
14
|
+
get: () => mod[key],
|
|
27
15
|
enumerable: true
|
|
28
16
|
});
|
|
29
|
-
if (canCache)
|
|
30
|
-
cache.set(mod, to);
|
|
31
17
|
return to;
|
|
32
18
|
};
|
|
33
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var __returnValue = (v) => v;
|
|
35
|
-
function __exportSetter(name, newValue) {
|
|
36
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
-
}
|
|
38
20
|
var __export = (target, all) => {
|
|
39
21
|
for (var name in all)
|
|
40
22
|
__defProp(target, name, {
|
|
41
23
|
get: all[name],
|
|
42
24
|
enumerable: true,
|
|
43
25
|
configurable: true,
|
|
44
|
-
set:
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
45
27
|
});
|
|
46
28
|
};
|
|
47
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -13203,7 +13185,7 @@ function sameValueZero(a, b) {
|
|
|
13203
13185
|
}
|
|
13204
13186
|
function equal(a, b) {
|
|
13205
13187
|
const seen = new Map;
|
|
13206
|
-
return function
|
|
13188
|
+
return function compare(a2, b2) {
|
|
13207
13189
|
if (sameValueZero(a2, b2))
|
|
13208
13190
|
return true;
|
|
13209
13191
|
if (isPrimitive(a2) || isPrimitive(b2))
|
|
@@ -13228,7 +13210,7 @@ function equal(a, b) {
|
|
|
13228
13210
|
throw new TypeError("Cannot compare WeakSet instances");
|
|
13229
13211
|
}
|
|
13230
13212
|
if (a2 instanceof WeakRef) {
|
|
13231
|
-
return
|
|
13213
|
+
return compare(a2.deref(), b2.deref());
|
|
13232
13214
|
}
|
|
13233
13215
|
if (seen.get(a2) === b2) {
|
|
13234
13216
|
return true;
|
|
@@ -13250,7 +13232,7 @@ function equal(a, b) {
|
|
|
13250
13232
|
return a2.symmetricDifference(b2).size === 0;
|
|
13251
13233
|
}
|
|
13252
13234
|
for (const key of aKeys) {
|
|
13253
|
-
if (!b2.has(key) || !
|
|
13235
|
+
if (!b2.has(key) || !compare(a2.get(key), b2.get(key))) {
|
|
13254
13236
|
return false;
|
|
13255
13237
|
}
|
|
13256
13238
|
}
|
|
@@ -13259,9 +13241,9 @@ function equal(a, b) {
|
|
|
13259
13241
|
let unmatchedEntries = a2.size;
|
|
13260
13242
|
for (const [aKey, aValue] of a2.entries()) {
|
|
13261
13243
|
for (const [bKey, bValue] of b2.entries()) {
|
|
13262
|
-
if (!
|
|
13244
|
+
if (!compare(aKey, bKey))
|
|
13263
13245
|
continue;
|
|
13264
|
-
if (aKey === aValue && bKey === bValue ||
|
|
13246
|
+
if (aKey === aValue && bKey === bValue || compare(aValue, bValue)) {
|
|
13265
13247
|
unmatchedEntries--;
|
|
13266
13248
|
break;
|
|
13267
13249
|
}
|
|
@@ -13281,7 +13263,7 @@ function equal(a, b) {
|
|
|
13281
13263
|
keys = getKeysDeep(a2).union(getKeysDeep(b2));
|
|
13282
13264
|
}
|
|
13283
13265
|
for (const key of keys) {
|
|
13284
|
-
if (!
|
|
13266
|
+
if (!compare(a2[key], b2[key])) {
|
|
13285
13267
|
return false;
|
|
13286
13268
|
}
|
|
13287
13269
|
if (key in a2 && !(key in b2) || key in b2 && !(key in a2)) {
|
|
@@ -26462,6 +26444,9 @@ function getScriptBasePathFromModulePath(p) {
|
|
|
26462
26444
|
return;
|
|
26463
26445
|
return norm.slice(0, idx);
|
|
26464
26446
|
}
|
|
26447
|
+
function scriptPathToRemotePath(p) {
|
|
26448
|
+
return (isModuleEntryPoint(p) ? getScriptBasePathFromModulePath(p) : p.substring(0, p.indexOf("."))).replaceAll(SEP2, "/");
|
|
26449
|
+
}
|
|
26465
26450
|
function getDeleteSuffix(type, format6) {
|
|
26466
26451
|
return getFolderSuffixes()[type] + "/" + METADATA_FILES[type][format6];
|
|
26467
26452
|
}
|
|
@@ -30420,7 +30405,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
30420
30405
|
if (!duplex.push(data3))
|
|
30421
30406
|
ws.pause();
|
|
30422
30407
|
});
|
|
30423
|
-
ws.once("error", function
|
|
30408
|
+
ws.once("error", function error(err) {
|
|
30424
30409
|
if (duplex.destroyed)
|
|
30425
30410
|
return;
|
|
30426
30411
|
terminateOnDestroy = false;
|
|
@@ -30438,7 +30423,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
30438
30423
|
return;
|
|
30439
30424
|
}
|
|
30440
30425
|
let called = false;
|
|
30441
|
-
ws.once("error", function
|
|
30426
|
+
ws.once("error", function error(err2) {
|
|
30442
30427
|
called = true;
|
|
30443
30428
|
callback(err2);
|
|
30444
30429
|
});
|
|
@@ -30452,7 +30437,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
30452
30437
|
};
|
|
30453
30438
|
duplex._final = function(callback) {
|
|
30454
30439
|
if (ws.readyState === ws.CONNECTING) {
|
|
30455
|
-
ws.once("open", function
|
|
30440
|
+
ws.once("open", function open() {
|
|
30456
30441
|
duplex._final(callback);
|
|
30457
30442
|
});
|
|
30458
30443
|
return;
|
|
@@ -30476,7 +30461,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
30476
30461
|
};
|
|
30477
30462
|
duplex._write = function(chunk, encoding, callback) {
|
|
30478
30463
|
if (ws.readyState === ws.CONNECTING) {
|
|
30479
|
-
ws.once("open", function
|
|
30464
|
+
ws.once("open", function open() {
|
|
30480
30465
|
duplex._write(chunk, encoding, callback);
|
|
30481
30466
|
});
|
|
30482
30467
|
return;
|
|
@@ -35527,7 +35512,7 @@ var require_BufferList = __commonJS((exports, module) => {
|
|
|
35527
35512
|
this.tail = null;
|
|
35528
35513
|
this.length = 0;
|
|
35529
35514
|
}
|
|
35530
|
-
BufferList.prototype.push = function
|
|
35515
|
+
BufferList.prototype.push = function push(v) {
|
|
35531
35516
|
var entry = { data: v, next: null };
|
|
35532
35517
|
if (this.length > 0)
|
|
35533
35518
|
this.tail.next = entry;
|
|
@@ -35558,7 +35543,7 @@ var require_BufferList = __commonJS((exports, module) => {
|
|
|
35558
35543
|
this.head = this.tail = null;
|
|
35559
35544
|
this.length = 0;
|
|
35560
35545
|
};
|
|
35561
|
-
BufferList.prototype.join = function
|
|
35546
|
+
BufferList.prototype.join = function join(s) {
|
|
35562
35547
|
if (this.length === 0)
|
|
35563
35548
|
return "";
|
|
35564
35549
|
var p = this.head;
|
|
@@ -37493,7 +37478,7 @@ var require_nodejsUtils = __commonJS((exports, module) => {
|
|
|
37493
37478
|
|
|
37494
37479
|
// node_modules/set-immediate-shim/index.js
|
|
37495
37480
|
var require_set_immediate_shim = __commonJS((exports, module) => {
|
|
37496
|
-
module.exports = typeof setImmediate === "function" ? setImmediate : function
|
|
37481
|
+
module.exports = typeof setImmediate === "function" ? setImmediate : function setImmediate() {
|
|
37497
37482
|
var args = [].slice.apply(arguments);
|
|
37498
37483
|
args.splice(1, 0, 0);
|
|
37499
37484
|
setTimeout.apply(null, args);
|
|
@@ -45848,7 +45833,7 @@ var require_headers = __commonJS((exports) => {
|
|
|
45848
45833
|
}
|
|
45849
45834
|
return result;
|
|
45850
45835
|
};
|
|
45851
|
-
exports.encode = function
|
|
45836
|
+
exports.encode = function encode(opts) {
|
|
45852
45837
|
const buf = b4a.alloc(512);
|
|
45853
45838
|
let name = opts.name;
|
|
45854
45839
|
let prefix = "";
|
|
@@ -45889,7 +45874,7 @@ var require_headers = __commonJS((exports) => {
|
|
|
45889
45874
|
b4a.write(buf, encodeOct(cksum(buf), 6), 148);
|
|
45890
45875
|
return buf;
|
|
45891
45876
|
};
|
|
45892
|
-
exports.decode = function
|
|
45877
|
+
exports.decode = function decode(buf, filenameEncoding, allowUnknownFormat) {
|
|
45893
45878
|
let typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET;
|
|
45894
45879
|
let name = decodeStr(buf, 0, 100, filenameEncoding);
|
|
45895
45880
|
const mode = decodeOct(buf, 100, 8);
|
|
@@ -48800,7 +48785,7 @@ var require_subschema = __commonJS((exports) => {
|
|
|
48800
48785
|
|
|
48801
48786
|
// node_modules/fast-deep-equal/index.js
|
|
48802
48787
|
var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
48803
|
-
module.exports = function
|
|
48788
|
+
module.exports = function equal(a, b) {
|
|
48804
48789
|
if (a === b)
|
|
48805
48790
|
return true;
|
|
48806
48791
|
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
@@ -48812,7 +48797,7 @@ var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
|
48812
48797
|
if (length != b.length)
|
|
48813
48798
|
return false;
|
|
48814
48799
|
for (i = length;i-- !== 0; )
|
|
48815
|
-
if (!
|
|
48800
|
+
if (!equal(a[i], b[i]))
|
|
48816
48801
|
return false;
|
|
48817
48802
|
return true;
|
|
48818
48803
|
}
|
|
@@ -48831,7 +48816,7 @@ var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
|
48831
48816
|
return false;
|
|
48832
48817
|
for (i = length;i-- !== 0; ) {
|
|
48833
48818
|
var key = keys[i];
|
|
48834
|
-
if (!
|
|
48819
|
+
if (!equal(a[key], b[key]))
|
|
48835
48820
|
return false;
|
|
48836
48821
|
}
|
|
48837
48822
|
return true;
|
|
@@ -61660,7 +61645,7 @@ async function handleFile(path8, workspace, alreadySynced, message, opts, rawWor
|
|
|
61660
61645
|
}
|
|
61661
61646
|
debug(`Processing local script ${path8}`);
|
|
61662
61647
|
alreadySynced.push(path8);
|
|
61663
|
-
const remotePath =
|
|
61648
|
+
const remotePath = scriptPathToRemotePath(path8);
|
|
61664
61649
|
const language = inferContentTypeFromFilePath(path8, opts?.defaultTs);
|
|
61665
61650
|
const codebase = language == "bun" ? findCodebase(path8, codebases) : undefined;
|
|
61666
61651
|
let bundleContent = undefined;
|
|
@@ -63593,8 +63578,11 @@ function getLanguageFromExtension(ext2, defaultTs = "bun") {
|
|
|
63593
63578
|
}
|
|
63594
63579
|
return;
|
|
63595
63580
|
}
|
|
63596
|
-
function sanitizeForFilesystem(summary) {
|
|
63597
|
-
|
|
63581
|
+
function sanitizeForFilesystem(summary, options) {
|
|
63582
|
+
let name = summary.replaceAll(" ", "_").replace(/[/\\:*?"<>|\x00-\x1f\x7f]/g, "").replace(/_+/g, "_").replace(/^[._]+|[._]+$/g, "");
|
|
63583
|
+
if (!options?.preserveCase) {
|
|
63584
|
+
name = name.toLowerCase();
|
|
63585
|
+
}
|
|
63598
63586
|
return WINDOWS_RESERVED.test(name.toLowerCase()) ? `_${name}` : name;
|
|
63599
63587
|
}
|
|
63600
63588
|
function newPathAssigner(defaultTs, options) {
|
|
@@ -63626,7 +63614,7 @@ function newRawAppPathAssigner(defaultTs) {
|
|
|
63626
63614
|
const seen_names = new Set;
|
|
63627
63615
|
function assignPath(summary, language) {
|
|
63628
63616
|
let name;
|
|
63629
|
-
name = summary ? sanitizeForFilesystem(summary) : "";
|
|
63617
|
+
name = summary ? sanitizeForFilesystem(summary, { preserveCase: true }) : "";
|
|
63630
63618
|
let original_name = name;
|
|
63631
63619
|
if (name == "") {
|
|
63632
63620
|
original_name = "runnable";
|
|
@@ -63995,6 +63983,19 @@ var init_relative_imports = __esm(async () => {
|
|
|
63995
63983
|
// src/commands/flow/flow_metadata.ts
|
|
63996
63984
|
import * as path10 from "node:path";
|
|
63997
63985
|
import { sep as SEP7 } from "node:path";
|
|
63986
|
+
async function isFlowDirectlyStale(folder, hashes, conf) {
|
|
63987
|
+
if (await checkifMetadataUptodate(folder, hashes[TOP_HASH], conf, TOP_HASH)) {
|
|
63988
|
+
return false;
|
|
63989
|
+
}
|
|
63990
|
+
const fileEntries = Object.entries(hashes).filter(([k]) => k !== TOP_HASH);
|
|
63991
|
+
if (fileEntries.length === 0)
|
|
63992
|
+
return true;
|
|
63993
|
+
for (const [k, h] of fileEntries) {
|
|
63994
|
+
if (!await checkifMetadataUptodate(folder, h, conf, k))
|
|
63995
|
+
return true;
|
|
63996
|
+
}
|
|
63997
|
+
return false;
|
|
63998
|
+
}
|
|
63998
63999
|
async function generateFlowHash(rawWorkspaceDependencies, folder, defaultTs) {
|
|
63999
64000
|
const elems = await FSFSElement(path10.join(process.cwd(), folder), [], true);
|
|
64000
64001
|
const hashes = {};
|
|
@@ -64014,6 +64015,14 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64014
64015
|
if (folder.endsWith(SEP7)) {
|
|
64015
64016
|
folder = folder.substring(0, folder.length - 1);
|
|
64016
64017
|
}
|
|
64018
|
+
if (opts.rehashOnly) {
|
|
64019
|
+
const hashes = await generateFlowHash({}, folder, opts.defaultTs);
|
|
64020
|
+
await clearGlobalLock(folder);
|
|
64021
|
+
for (const [k, v] of Object.entries(hashes)) {
|
|
64022
|
+
await updateMetadataGlobalLock(folder, v, k);
|
|
64023
|
+
}
|
|
64024
|
+
return;
|
|
64025
|
+
}
|
|
64017
64026
|
const remote_path = extractNameFromFolder(folder.replaceAll(SEP7, "/"), "flow");
|
|
64018
64027
|
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
64019
64028
|
info(`Generating lock for flow ${folder} at ${remote_path}`);
|
|
@@ -64043,7 +64052,7 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64043
64052
|
inlineScriptPaths.push(treePath);
|
|
64044
64053
|
}
|
|
64045
64054
|
const hashes = await generateFlowHash({}, folder, opts.defaultTs);
|
|
64046
|
-
const isDirectlyStale =
|
|
64055
|
+
const isDirectlyStale = await isFlowDirectlyStale(folder, hashes, conf);
|
|
64047
64056
|
await tree.addNode(folderNormalized, "", "bun", "", inlineScriptPaths, "flow", folderNormalized, folder, isDirectlyStale);
|
|
64048
64057
|
return;
|
|
64049
64058
|
}
|
|
@@ -64052,7 +64061,7 @@ async function generateFlowLockInternal(folder, dryRun, workspace, opts, justUpd
|
|
|
64052
64061
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
64053
64062
|
filteredDeps = await filterWorkspaceDependenciesForFlow(flowValue.value, rawWorkspaceDependencies, folder);
|
|
64054
64063
|
const hashes = await generateFlowHash(filteredDeps, folder, opts.defaultTs);
|
|
64055
|
-
const isDirectlyStale =
|
|
64064
|
+
const isDirectlyStale = await isFlowDirectlyStale(folder, hashes, conf);
|
|
64056
64065
|
if (!isDirectlyStale) {
|
|
64057
64066
|
if (!noStaleMessage) {
|
|
64058
64067
|
info(colors.green(`Flow ${remote_path} metadata is up-to-date, skipping`));
|
|
@@ -64227,6 +64236,662 @@ var init_flow_metadata = __esm(async () => {
|
|
|
64227
64236
|
import_yaml9 = __toESM(require_dist(), 1);
|
|
64228
64237
|
});
|
|
64229
64238
|
|
|
64239
|
+
// src/utils/dependency_tree.ts
|
|
64240
|
+
async function uploadScripts(tree, workspace) {
|
|
64241
|
+
const scriptHashes = {};
|
|
64242
|
+
const workspaceDeps = [];
|
|
64243
|
+
for (const path11 of tree.allPaths()) {
|
|
64244
|
+
const content = tree.getContent(path11);
|
|
64245
|
+
const itemType = tree.getItemType(path11);
|
|
64246
|
+
if (itemType === "dependencies") {
|
|
64247
|
+
if (content === undefined)
|
|
64248
|
+
continue;
|
|
64249
|
+
const info2 = workspaceDependenciesPathToLanguageAndFilename(path11);
|
|
64250
|
+
if (info2) {
|
|
64251
|
+
const hash2 = await generateHash(content);
|
|
64252
|
+
workspaceDeps.push({ path: path11, language: info2.language, name: info2.name, hash: hash2 });
|
|
64253
|
+
}
|
|
64254
|
+
} else if (itemType === "script") {
|
|
64255
|
+
if (!content)
|
|
64256
|
+
continue;
|
|
64257
|
+
const hash2 = await generateHash(content);
|
|
64258
|
+
scriptHashes[path11] = hash2;
|
|
64259
|
+
}
|
|
64260
|
+
}
|
|
64261
|
+
if (Object.keys(scriptHashes).length === 0 && workspaceDeps.length === 0)
|
|
64262
|
+
return;
|
|
64263
|
+
const mismatched = await diffRawScriptsWithDeployed({
|
|
64264
|
+
workspace: workspace.workspaceId,
|
|
64265
|
+
requestBody: {
|
|
64266
|
+
scripts: scriptHashes,
|
|
64267
|
+
workspace_deps: workspaceDeps
|
|
64268
|
+
}
|
|
64269
|
+
});
|
|
64270
|
+
for (const path11 of mismatched) {
|
|
64271
|
+
const content = tree.getContent(path11);
|
|
64272
|
+
const itemType = tree.getItemType(path11);
|
|
64273
|
+
if (itemType === "dependencies") {
|
|
64274
|
+
if (content !== undefined) {
|
|
64275
|
+
tree.setContentHash(path11, "mismatched");
|
|
64276
|
+
}
|
|
64277
|
+
} else if (content) {
|
|
64278
|
+
const hash2 = await storeRawScriptTemp({
|
|
64279
|
+
workspace: workspace.workspaceId,
|
|
64280
|
+
requestBody: content
|
|
64281
|
+
});
|
|
64282
|
+
tree.setContentHash(path11, hash2);
|
|
64283
|
+
}
|
|
64284
|
+
}
|
|
64285
|
+
}
|
|
64286
|
+
|
|
64287
|
+
class DoubleLinkedDependencyTree {
|
|
64288
|
+
nodes = new Map;
|
|
64289
|
+
workspaceDeps = {};
|
|
64290
|
+
setWorkspaceDeps(deps) {
|
|
64291
|
+
this.workspaceDeps = deps;
|
|
64292
|
+
}
|
|
64293
|
+
async addNode(path11, content, language, metadata, imports, itemType, folder, originalPath, isDirectlyStale, isRawApp) {
|
|
64294
|
+
const hasWorkspaceDeps = itemType === "script" || itemType === "inline_script";
|
|
64295
|
+
const filteredDeps = hasWorkspaceDeps ? filterWorkspaceDependencies(this.workspaceDeps, content, language) : {};
|
|
64296
|
+
const stalenessHash = await generateScriptHash({}, content, metadata);
|
|
64297
|
+
if (!this.nodes.has(path11)) {
|
|
64298
|
+
this.nodes.set(path11, {
|
|
64299
|
+
content: "",
|
|
64300
|
+
stalenessHash: "",
|
|
64301
|
+
language: "deno",
|
|
64302
|
+
metadata: "",
|
|
64303
|
+
imports: new Set,
|
|
64304
|
+
importedBy: new Set,
|
|
64305
|
+
itemType: "script",
|
|
64306
|
+
folder: "",
|
|
64307
|
+
originalPath: "",
|
|
64308
|
+
isDirectlyStale: false
|
|
64309
|
+
});
|
|
64310
|
+
}
|
|
64311
|
+
const node = this.nodes.get(path11);
|
|
64312
|
+
node.content = content;
|
|
64313
|
+
node.stalenessHash = stalenessHash;
|
|
64314
|
+
node.language = language;
|
|
64315
|
+
node.metadata = metadata;
|
|
64316
|
+
node.itemType = itemType;
|
|
64317
|
+
node.folder = folder;
|
|
64318
|
+
node.originalPath = originalPath;
|
|
64319
|
+
node.isDirectlyStale = isDirectlyStale;
|
|
64320
|
+
node.isRawApp = isRawApp;
|
|
64321
|
+
const filteredDepsPaths = Object.keys(filteredDeps);
|
|
64322
|
+
for (const depsPath of filteredDepsPaths) {
|
|
64323
|
+
if (!this.nodes.has(depsPath)) {
|
|
64324
|
+
const depsInfo = workspaceDependenciesPathToLanguageAndFilename(depsPath);
|
|
64325
|
+
const contentHash = await generateHash(filteredDeps[depsPath] + depsPath);
|
|
64326
|
+
const isUpToDate = await checkifMetadataUptodate(depsPath, contentHash, undefined);
|
|
64327
|
+
this.nodes.set(depsPath, {
|
|
64328
|
+
content: filteredDeps[depsPath],
|
|
64329
|
+
stalenessHash: "",
|
|
64330
|
+
language: depsInfo?.language ?? "deno",
|
|
64331
|
+
metadata: "",
|
|
64332
|
+
imports: new Set,
|
|
64333
|
+
importedBy: new Set,
|
|
64334
|
+
itemType: "dependencies",
|
|
64335
|
+
folder: "",
|
|
64336
|
+
originalPath: depsPath,
|
|
64337
|
+
isDirectlyStale: !isUpToDate
|
|
64338
|
+
});
|
|
64339
|
+
}
|
|
64340
|
+
}
|
|
64341
|
+
const allImports = [...imports, ...filteredDepsPaths];
|
|
64342
|
+
for (const importPath of allImports) {
|
|
64343
|
+
node.imports.add(importPath);
|
|
64344
|
+
if (!this.nodes.has(importPath)) {
|
|
64345
|
+
this.nodes.set(importPath, {
|
|
64346
|
+
content: "",
|
|
64347
|
+
stalenessHash: "",
|
|
64348
|
+
language: "deno",
|
|
64349
|
+
metadata: "",
|
|
64350
|
+
imports: new Set,
|
|
64351
|
+
importedBy: new Set,
|
|
64352
|
+
itemType: "script",
|
|
64353
|
+
folder: "",
|
|
64354
|
+
originalPath: "",
|
|
64355
|
+
isDirectlyStale: false
|
|
64356
|
+
});
|
|
64357
|
+
}
|
|
64358
|
+
this.nodes.get(importPath).importedBy.add(path11);
|
|
64359
|
+
}
|
|
64360
|
+
}
|
|
64361
|
+
getContent(path11) {
|
|
64362
|
+
return this.nodes.get(path11)?.content;
|
|
64363
|
+
}
|
|
64364
|
+
getStalenessHash(path11) {
|
|
64365
|
+
return this.nodes.get(path11)?.stalenessHash;
|
|
64366
|
+
}
|
|
64367
|
+
getContentHash(path11) {
|
|
64368
|
+
return this.nodes.get(path11)?.contentHash;
|
|
64369
|
+
}
|
|
64370
|
+
setContentHash(path11, hash2) {
|
|
64371
|
+
const node = this.nodes.get(path11);
|
|
64372
|
+
if (node) {
|
|
64373
|
+
node.contentHash = hash2;
|
|
64374
|
+
}
|
|
64375
|
+
}
|
|
64376
|
+
getLanguage(path11) {
|
|
64377
|
+
return this.nodes.get(path11)?.language;
|
|
64378
|
+
}
|
|
64379
|
+
getMetadata(path11) {
|
|
64380
|
+
return this.nodes.get(path11)?.metadata;
|
|
64381
|
+
}
|
|
64382
|
+
getStaleReason(path11) {
|
|
64383
|
+
return this.nodes.get(path11)?.staleReason;
|
|
64384
|
+
}
|
|
64385
|
+
getItemType(path11) {
|
|
64386
|
+
return this.nodes.get(path11)?.itemType;
|
|
64387
|
+
}
|
|
64388
|
+
getFolder(path11) {
|
|
64389
|
+
return this.nodes.get(path11)?.folder;
|
|
64390
|
+
}
|
|
64391
|
+
getIsRawApp(path11) {
|
|
64392
|
+
return this.nodes.get(path11)?.isRawApp;
|
|
64393
|
+
}
|
|
64394
|
+
getIsDirectlyStale(path11) {
|
|
64395
|
+
return this.nodes.get(path11)?.isDirectlyStale ?? false;
|
|
64396
|
+
}
|
|
64397
|
+
getOriginalPath(path11) {
|
|
64398
|
+
return this.nodes.get(path11)?.originalPath;
|
|
64399
|
+
}
|
|
64400
|
+
getImports(path11) {
|
|
64401
|
+
return this.nodes.get(path11)?.imports;
|
|
64402
|
+
}
|
|
64403
|
+
isStale(path11) {
|
|
64404
|
+
return this.nodes.get(path11)?.staleReason !== undefined;
|
|
64405
|
+
}
|
|
64406
|
+
propagateStaleness() {
|
|
64407
|
+
const directlyStale = new Set;
|
|
64408
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64409
|
+
if (node.isDirectlyStale) {
|
|
64410
|
+
directlyStale.add(path11);
|
|
64411
|
+
node.staleReason = "content changed";
|
|
64412
|
+
}
|
|
64413
|
+
}
|
|
64414
|
+
const allStale = new Set(directlyStale);
|
|
64415
|
+
const queue = [...directlyStale];
|
|
64416
|
+
const visited = new Set;
|
|
64417
|
+
while (queue.length > 0) {
|
|
64418
|
+
const scriptPath = queue.shift();
|
|
64419
|
+
if (visited.has(scriptPath))
|
|
64420
|
+
continue;
|
|
64421
|
+
visited.add(scriptPath);
|
|
64422
|
+
const node = this.nodes.get(scriptPath);
|
|
64423
|
+
if (!node)
|
|
64424
|
+
continue;
|
|
64425
|
+
for (const importer of node.importedBy) {
|
|
64426
|
+
if (!allStale.has(importer)) {
|
|
64427
|
+
allStale.add(importer);
|
|
64428
|
+
queue.push(importer);
|
|
64429
|
+
const importerNode = this.nodes.get(importer);
|
|
64430
|
+
if (importerNode)
|
|
64431
|
+
importerNode.staleReason = `depends on ${scriptPath}`;
|
|
64432
|
+
}
|
|
64433
|
+
}
|
|
64434
|
+
}
|
|
64435
|
+
}
|
|
64436
|
+
traverseTransitive(scriptPath, callback) {
|
|
64437
|
+
const queue = [scriptPath];
|
|
64438
|
+
const visited = new Set;
|
|
64439
|
+
while (queue.length > 0) {
|
|
64440
|
+
const current = queue.shift();
|
|
64441
|
+
if (visited.has(current))
|
|
64442
|
+
continue;
|
|
64443
|
+
visited.add(current);
|
|
64444
|
+
const node = this.nodes.get(current);
|
|
64445
|
+
if (!node)
|
|
64446
|
+
continue;
|
|
64447
|
+
for (const importPath of node.imports) {
|
|
64448
|
+
const importNode = this.nodes.get(importPath);
|
|
64449
|
+
if (importNode) {
|
|
64450
|
+
const stop = callback(importPath, importNode);
|
|
64451
|
+
if (!stop) {
|
|
64452
|
+
queue.push(importPath);
|
|
64453
|
+
}
|
|
64454
|
+
}
|
|
64455
|
+
}
|
|
64456
|
+
}
|
|
64457
|
+
}
|
|
64458
|
+
allPaths() {
|
|
64459
|
+
return this.nodes.keys();
|
|
64460
|
+
}
|
|
64461
|
+
*stalePaths() {
|
|
64462
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64463
|
+
if (node.staleReason) {
|
|
64464
|
+
yield path11;
|
|
64465
|
+
}
|
|
64466
|
+
}
|
|
64467
|
+
}
|
|
64468
|
+
has(path11) {
|
|
64469
|
+
return this.nodes.has(path11);
|
|
64470
|
+
}
|
|
64471
|
+
getMismatchedWorkspaceDeps() {
|
|
64472
|
+
const result = {};
|
|
64473
|
+
for (const [path11, node] of this.nodes.entries()) {
|
|
64474
|
+
if (node.itemType === "dependencies" && node.contentHash && node.content !== undefined) {
|
|
64475
|
+
result[path11] = node.content;
|
|
64476
|
+
}
|
|
64477
|
+
}
|
|
64478
|
+
return result;
|
|
64479
|
+
}
|
|
64480
|
+
getTempScriptRefs(scriptPath) {
|
|
64481
|
+
const result = {};
|
|
64482
|
+
this.traverseTransitive(scriptPath, (_path, node) => {
|
|
64483
|
+
if (node.contentHash) {
|
|
64484
|
+
result[_path] = node.contentHash;
|
|
64485
|
+
}
|
|
64486
|
+
});
|
|
64487
|
+
return result;
|
|
64488
|
+
}
|
|
64489
|
+
async persistDepsHashes(depsPaths) {
|
|
64490
|
+
for (const path11 of depsPaths) {
|
|
64491
|
+
const node = this.nodes.get(path11);
|
|
64492
|
+
if (node?.itemType === "dependencies" && node.content !== undefined) {
|
|
64493
|
+
const hash2 = await generateHash(node.content + path11);
|
|
64494
|
+
await updateMetadataGlobalLock(path11, hash2);
|
|
64495
|
+
}
|
|
64496
|
+
}
|
|
64497
|
+
}
|
|
64498
|
+
get size() {
|
|
64499
|
+
return this.nodes.size;
|
|
64500
|
+
}
|
|
64501
|
+
}
|
|
64502
|
+
var init_dependency_tree = __esm(async () => {
|
|
64503
|
+
init_services_gen();
|
|
64504
|
+
await __promiseAll([
|
|
64505
|
+
init_metadata(),
|
|
64506
|
+
init_utils()
|
|
64507
|
+
]);
|
|
64508
|
+
});
|
|
64509
|
+
|
|
64510
|
+
// src/commands/generate-metadata/generate-metadata.ts
|
|
64511
|
+
var exports_generate_metadata = {};
|
|
64512
|
+
__export(exports_generate_metadata, {
|
|
64513
|
+
rehashOnly: () => rehashOnly,
|
|
64514
|
+
default: () => generate_metadata_default
|
|
64515
|
+
});
|
|
64516
|
+
import { sep as SEP8 } from "node:path";
|
|
64517
|
+
async function walkLocalScripts(codebases, ignore) {
|
|
64518
|
+
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, {});
|
|
64519
|
+
return Object.keys(elems);
|
|
64520
|
+
}
|
|
64521
|
+
async function walkLocalFlowFolders(ignore) {
|
|
64522
|
+
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, {});
|
|
64523
|
+
return Object.keys(elems).map((x) => x.substring(0, x.lastIndexOf(SEP8)));
|
|
64524
|
+
}
|
|
64525
|
+
async function walkLocalAppItems(ignore) {
|
|
64526
|
+
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, {});
|
|
64527
|
+
return Object.keys(elems).map((p) => ({
|
|
64528
|
+
folder: p.substring(0, p.lastIndexOf(SEP8)),
|
|
64529
|
+
rawApp: p.endsWith(SEP8 + "raw_app.yaml")
|
|
64530
|
+
}));
|
|
64531
|
+
}
|
|
64532
|
+
function categorizeLocalFiles(paths) {
|
|
64533
|
+
const scripts = [];
|
|
64534
|
+
const flowFolderSet = new Set;
|
|
64535
|
+
const appPaths = [];
|
|
64536
|
+
for (const p of paths) {
|
|
64537
|
+
if (p.endsWith(SEP8 + "flow.yaml") || p.endsWith(SEP8 + "flow.json")) {
|
|
64538
|
+
flowFolderSet.add(p.substring(0, p.lastIndexOf(SEP8)));
|
|
64539
|
+
} else if (p.endsWith(SEP8 + "raw_app.yaml") || p.endsWith(SEP8 + "app.yaml")) {
|
|
64540
|
+
appPaths.push(p);
|
|
64541
|
+
} else if (exts.some((ext2) => p.endsWith(ext2)) && !isFolderResourcePathAnyFormat(p) && !(isScriptModulePath(p) && !isModuleEntryPoint(p))) {
|
|
64542
|
+
scripts.push(p);
|
|
64543
|
+
}
|
|
64544
|
+
}
|
|
64545
|
+
return { scripts, flowFolders: [...flowFolderSet], appPaths };
|
|
64546
|
+
}
|
|
64547
|
+
async function rehashOnly(opts, folder, rehashFilter) {
|
|
64548
|
+
const codebases = await listSyncCodebases(opts);
|
|
64549
|
+
const ignore = await ignoreF(opts);
|
|
64550
|
+
const counts = { scripts: 0, flows: 0, apps: 0 };
|
|
64551
|
+
const folderFilter = folder?.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
64552
|
+
const inFilter = (p) => {
|
|
64553
|
+
if (!folderFilter)
|
|
64554
|
+
return true;
|
|
64555
|
+
const n = p.replaceAll("\\", "/");
|
|
64556
|
+
return n === folderFilter || n.startsWith(folderFilter + "/");
|
|
64557
|
+
};
|
|
64558
|
+
const conf = rehashFilter?.missingOnly ? await readLockfile() : undefined;
|
|
64559
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
64560
|
+
const hasEntry = (key, subpath) => {
|
|
64561
|
+
if (!conf?.locks)
|
|
64562
|
+
return false;
|
|
64563
|
+
if (isFlatKeyed) {
|
|
64564
|
+
const fullKey = subpath ? `${key}+${subpath}` : key;
|
|
64565
|
+
return conf.locks[fullKey] !== undefined || conf.locks["./" + fullKey] !== undefined;
|
|
64566
|
+
}
|
|
64567
|
+
for (const p of [key, "./" + key]) {
|
|
64568
|
+
const obj = conf.locks[p];
|
|
64569
|
+
if (obj === undefined)
|
|
64570
|
+
continue;
|
|
64571
|
+
if (!subpath)
|
|
64572
|
+
return true;
|
|
64573
|
+
if (typeof obj === "object" && obj?.[subpath] !== undefined)
|
|
64574
|
+
return true;
|
|
64575
|
+
}
|
|
64576
|
+
return false;
|
|
64577
|
+
};
|
|
64578
|
+
const skipIfExisting = (remotePath, subpath) => !!rehashFilter?.missingOnly && hasEntry(remotePath, subpath);
|
|
64579
|
+
let scriptPaths;
|
|
64580
|
+
let flowFolders;
|
|
64581
|
+
let appPaths;
|
|
64582
|
+
if (rehashFilter?.localFiles) {
|
|
64583
|
+
const cat = categorizeLocalFiles(rehashFilter.localFiles);
|
|
64584
|
+
scriptPaths = cat.scripts;
|
|
64585
|
+
flowFolders = cat.flowFolders;
|
|
64586
|
+
appPaths = cat.appPaths.map((p) => ({
|
|
64587
|
+
folder: p.substring(0, p.lastIndexOf(SEP8)),
|
|
64588
|
+
rawApp: p.endsWith(SEP8 + "raw_app.yaml")
|
|
64589
|
+
}));
|
|
64590
|
+
} else {
|
|
64591
|
+
scriptPaths = await walkLocalScripts(codebases, ignore);
|
|
64592
|
+
flowFolders = await walkLocalFlowFolders(ignore);
|
|
64593
|
+
appPaths = await walkLocalAppItems(ignore);
|
|
64594
|
+
}
|
|
64595
|
+
const stubWorkspace = {};
|
|
64596
|
+
const rehashOpts = { ...opts, rehashOnly: true };
|
|
64597
|
+
if (!rehashFilter?.skipScripts) {
|
|
64598
|
+
for (const e of scriptPaths) {
|
|
64599
|
+
const remotePath = scriptPathToRemotePath(e);
|
|
64600
|
+
if (!inFilter(remotePath))
|
|
64601
|
+
continue;
|
|
64602
|
+
if (rehashFilter?.missingOnly) {
|
|
64603
|
+
if (skipIfExisting(remotePath) || skipIfExisting(remotePath, "__script_hash"))
|
|
64604
|
+
continue;
|
|
64605
|
+
}
|
|
64606
|
+
try {
|
|
64607
|
+
await generateScriptMetadataInternal(e, stubWorkspace, rehashOpts, false, true, {}, codebases, false);
|
|
64608
|
+
counts.scripts++;
|
|
64609
|
+
} catch (err) {
|
|
64610
|
+
warn(`Skipping ${e}: ${err instanceof Error ? err.message : err}`);
|
|
64611
|
+
}
|
|
64612
|
+
}
|
|
64613
|
+
}
|
|
64614
|
+
if (!rehashFilter?.skipFlows) {
|
|
64615
|
+
for (const f of flowFolders) {
|
|
64616
|
+
if (!inFilter(f))
|
|
64617
|
+
continue;
|
|
64618
|
+
if (rehashFilter?.missingOnly) {
|
|
64619
|
+
const folderNormalized = f.replaceAll(SEP8, "/");
|
|
64620
|
+
if (skipIfExisting(folderNormalized, "__flow_hash"))
|
|
64621
|
+
continue;
|
|
64622
|
+
}
|
|
64623
|
+
try {
|
|
64624
|
+
await generateFlowLockInternal(f, false, stubWorkspace, rehashOpts, false, true);
|
|
64625
|
+
counts.flows++;
|
|
64626
|
+
} catch (err) {
|
|
64627
|
+
warn(`Skipping ${f}: ${err instanceof Error ? err.message : err}`);
|
|
64628
|
+
}
|
|
64629
|
+
}
|
|
64630
|
+
}
|
|
64631
|
+
if (!rehashFilter?.skipApps) {
|
|
64632
|
+
for (const { folder: appFolder, rawApp } of appPaths) {
|
|
64633
|
+
if (!inFilter(appFolder))
|
|
64634
|
+
continue;
|
|
64635
|
+
if (rehashFilter?.missingOnly) {
|
|
64636
|
+
const folderNormalized = appFolder.replaceAll(SEP8, "/");
|
|
64637
|
+
if (skipIfExisting(folderNormalized, "__app_hash"))
|
|
64638
|
+
continue;
|
|
64639
|
+
}
|
|
64640
|
+
try {
|
|
64641
|
+
await generateAppLocksInternal(appFolder, rawApp, false, stubWorkspace, rehashOpts, false, true);
|
|
64642
|
+
counts.apps++;
|
|
64643
|
+
} catch (err) {
|
|
64644
|
+
warn(`Skipping ${appFolder}: ${err instanceof Error ? err.message : err}`);
|
|
64645
|
+
}
|
|
64646
|
+
}
|
|
64647
|
+
}
|
|
64648
|
+
if (counts.scripts + counts.flows + counts.apps > 0 || !rehashFilter?.missingOnly) {
|
|
64649
|
+
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.`);
|
|
64650
|
+
}
|
|
64651
|
+
return counts;
|
|
64652
|
+
}
|
|
64653
|
+
async function generateMetadata2(opts, folder) {
|
|
64654
|
+
if (folder === "") {
|
|
64655
|
+
folder = undefined;
|
|
64656
|
+
}
|
|
64657
|
+
const workspace = await resolveWorkspace(opts);
|
|
64658
|
+
await requireLogin(opts);
|
|
64659
|
+
opts = await mergeConfigWithConfigFile(opts);
|
|
64660
|
+
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(false);
|
|
64661
|
+
const codebases = await listSyncCodebases(opts);
|
|
64662
|
+
const ignore = await ignoreF(opts);
|
|
64663
|
+
const skipScripts = opts.skipScripts ?? false;
|
|
64664
|
+
const skipFlows = opts.skipFlows ?? opts.schemaOnly ?? false;
|
|
64665
|
+
const skipApps = opts.skipApps ?? opts.schemaOnly ?? false;
|
|
64666
|
+
const checking = [];
|
|
64667
|
+
if (!skipScripts)
|
|
64668
|
+
checking.push("scripts");
|
|
64669
|
+
if (!skipFlows)
|
|
64670
|
+
checking.push("flows");
|
|
64671
|
+
if (!skipApps)
|
|
64672
|
+
checking.push("apps");
|
|
64673
|
+
if (checking.length === 0) {
|
|
64674
|
+
info(colors.yellow("Nothing to check (all types skipped)"));
|
|
64675
|
+
return;
|
|
64676
|
+
}
|
|
64677
|
+
info(`Checking ${checking.join(", ")}...`);
|
|
64678
|
+
const tree = new DoubleLinkedDependencyTree;
|
|
64679
|
+
tree.setWorkspaceDeps(rawWorkspaceDependencies);
|
|
64680
|
+
if (!skipScripts) {
|
|
64681
|
+
for (const e of await walkLocalScripts(codebases, ignore)) {
|
|
64682
|
+
await generateScriptMetadataInternal(e, workspace, opts, true, true, rawWorkspaceDependencies, codebases, false, tree);
|
|
64683
|
+
}
|
|
64684
|
+
}
|
|
64685
|
+
if (!skipFlows) {
|
|
64686
|
+
for (const flowFolder of await walkLocalFlowFolders(ignore)) {
|
|
64687
|
+
await generateFlowLockInternal(flowFolder, true, workspace, opts, false, true, tree);
|
|
64688
|
+
}
|
|
64689
|
+
}
|
|
64690
|
+
if (!skipApps) {
|
|
64691
|
+
for (const { folder: appFolder, rawApp } of await walkLocalAppItems(ignore)) {
|
|
64692
|
+
await generateAppLocksInternal(appFolder, rawApp, true, workspace, opts, false, true, tree);
|
|
64693
|
+
}
|
|
64694
|
+
}
|
|
64695
|
+
tree.propagateStaleness();
|
|
64696
|
+
try {
|
|
64697
|
+
await uploadScripts(tree, workspace);
|
|
64698
|
+
} catch (e) {
|
|
64699
|
+
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.`));
|
|
64700
|
+
}
|
|
64701
|
+
const staleItems = [];
|
|
64702
|
+
const seenFolders = new Set;
|
|
64703
|
+
for (const p of tree.allPaths()) {
|
|
64704
|
+
const staleReason = tree.getStaleReason(p);
|
|
64705
|
+
if (!staleReason)
|
|
64706
|
+
continue;
|
|
64707
|
+
const itemType = tree.getItemType(p);
|
|
64708
|
+
const itemFolder = tree.getFolder(p);
|
|
64709
|
+
if (itemType === "dependencies") {
|
|
64710
|
+
staleItems.push({ type: itemType, path: p, folder: itemFolder, staleReason });
|
|
64711
|
+
} else if (itemType === "inline_script") {
|
|
64712
|
+
continue;
|
|
64713
|
+
} else if (itemType === "script") {
|
|
64714
|
+
const originalPath = tree.getOriginalPath(p);
|
|
64715
|
+
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, staleReason });
|
|
64716
|
+
} else if (!seenFolders.has(itemFolder)) {
|
|
64717
|
+
seenFolders.add(itemFolder);
|
|
64718
|
+
const originalPath = tree.getOriginalPath(p);
|
|
64719
|
+
staleItems.push({ type: itemType, path: originalPath, folder: itemFolder, isRawApp: tree.getIsRawApp(p), staleReason });
|
|
64720
|
+
}
|
|
64721
|
+
}
|
|
64722
|
+
let filteredItems = staleItems;
|
|
64723
|
+
if (folder) {
|
|
64724
|
+
folder = folder.replaceAll("\\", "/");
|
|
64725
|
+
if (folder.endsWith("/")) {
|
|
64726
|
+
folder = folder.substring(0, folder.length - 1);
|
|
64727
|
+
}
|
|
64728
|
+
const folderNoExt = folder.replace(/\.[^/.]+$/, "");
|
|
64729
|
+
const isInsideFolder = (item) => {
|
|
64730
|
+
const normalizedFolder = item.folder.replaceAll("\\", "/");
|
|
64731
|
+
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
64732
|
+
return normalizedFolder === folder || normalizedFolder.startsWith(folder + "/") || normalizedPath === folder || normalizedPath === folderNoExt;
|
|
64733
|
+
};
|
|
64734
|
+
const isPathInFolder = (p) => p.startsWith(folder + "/") || p === folder || p === folderNoExt;
|
|
64735
|
+
const touchesFolder = (treePath) => {
|
|
64736
|
+
if (isPathInFolder(treePath))
|
|
64737
|
+
return true;
|
|
64738
|
+
let found = false;
|
|
64739
|
+
tree.traverseTransitive(treePath, (importPath) => {
|
|
64740
|
+
if (isPathInFolder(importPath)) {
|
|
64741
|
+
found = true;
|
|
64742
|
+
return true;
|
|
64743
|
+
}
|
|
64744
|
+
});
|
|
64745
|
+
return found;
|
|
64746
|
+
};
|
|
64747
|
+
const isRelevant = (item) => {
|
|
64748
|
+
if (isInsideFolder(item))
|
|
64749
|
+
return true;
|
|
64750
|
+
if (item.type === "dependencies")
|
|
64751
|
+
return true;
|
|
64752
|
+
const treePath = (item.type === "script" ? item.path.replace(/\.[^/.]+$/, "") : item.folder).replaceAll("\\", "/");
|
|
64753
|
+
return touchesFolder(treePath);
|
|
64754
|
+
};
|
|
64755
|
+
if (opts.strictFolderBoundaries) {
|
|
64756
|
+
filteredItems = staleItems.filter(isInsideFolder);
|
|
64757
|
+
const excludedStale = staleItems.filter((item) => !isInsideFolder(item) && isRelevant(item) && item.type !== "dependencies");
|
|
64758
|
+
for (const item of excludedStale) {
|
|
64759
|
+
const normalizedPath = item.path.replaceAll("\\", "/");
|
|
64760
|
+
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.`));
|
|
64761
|
+
}
|
|
64762
|
+
} else {
|
|
64763
|
+
filteredItems = staleItems.filter(isRelevant);
|
|
64764
|
+
}
|
|
64765
|
+
}
|
|
64766
|
+
if (filteredItems.length === 0) {
|
|
64767
|
+
info(colors.green("All metadata up-to-date"));
|
|
64768
|
+
return;
|
|
64769
|
+
}
|
|
64770
|
+
const scripts = filteredItems.filter((i) => i.type === "script");
|
|
64771
|
+
const flows = filteredItems.filter((i) => i.type === "flow");
|
|
64772
|
+
const apps2 = filteredItems.filter((i) => i.type === "app");
|
|
64773
|
+
const deps = filteredItems.filter((i) => i.type === "dependencies");
|
|
64774
|
+
info("");
|
|
64775
|
+
info(`Found ${colors.bold(String(filteredItems.length))} item(s) with stale metadata:`);
|
|
64776
|
+
const printItems = (label, items) => {
|
|
64777
|
+
if (items.length === 0)
|
|
64778
|
+
return;
|
|
64779
|
+
info(` ${label} (${items.length}):`);
|
|
64780
|
+
for (const item of items) {
|
|
64781
|
+
const reason = item.staleReason ? colors.dim(colors.white(` — ${item.staleReason}`)) : "";
|
|
64782
|
+
info(` ~ ${item.path}` + reason);
|
|
64783
|
+
}
|
|
64784
|
+
};
|
|
64785
|
+
printItems("Workspace dependencies", deps);
|
|
64786
|
+
printItems("Scripts", scripts);
|
|
64787
|
+
printItems("Flows", flows);
|
|
64788
|
+
printItems("Apps", apps2);
|
|
64789
|
+
if (opts.dryRun) {
|
|
64790
|
+
return;
|
|
64791
|
+
}
|
|
64792
|
+
info("");
|
|
64793
|
+
const isInteractive = process.stdin.isTTY ?? false;
|
|
64794
|
+
if (!opts.yes && isInteractive && !await Confirm.prompt({
|
|
64795
|
+
message: "Update metadata?",
|
|
64796
|
+
default: true
|
|
64797
|
+
})) {
|
|
64798
|
+
return;
|
|
64799
|
+
}
|
|
64800
|
+
info("");
|
|
64801
|
+
const mismatchedWorkspaceDeps = tree.getMismatchedWorkspaceDeps();
|
|
64802
|
+
const total = filteredItems.length - deps.length;
|
|
64803
|
+
const maxWidth = `[${total}/${total}]`.length;
|
|
64804
|
+
let current = 0;
|
|
64805
|
+
const formatProgress = (n) => {
|
|
64806
|
+
return colors.dim(colors.white(`[${n}/${total}]`.padEnd(maxWidth, " ")));
|
|
64807
|
+
};
|
|
64808
|
+
const errors = [];
|
|
64809
|
+
for (const item of scripts) {
|
|
64810
|
+
current++;
|
|
64811
|
+
info(`${formatProgress(current)} script ${item.path}`);
|
|
64812
|
+
try {
|
|
64813
|
+
await generateScriptMetadataInternal(item.path, workspace, opts, false, true, mismatchedWorkspaceDeps, codebases, false, tree);
|
|
64814
|
+
} catch (e) {
|
|
64815
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64816
|
+
errors.push({ path: item.path, error: msg });
|
|
64817
|
+
error(` Failed: ${msg}`);
|
|
64818
|
+
}
|
|
64819
|
+
}
|
|
64820
|
+
for (const item of flows) {
|
|
64821
|
+
current++;
|
|
64822
|
+
try {
|
|
64823
|
+
const result = await generateFlowLockInternal(item.folder.replaceAll("/", SEP8), false, workspace, opts, false, true, tree);
|
|
64824
|
+
const flowResult = result;
|
|
64825
|
+
const scriptsInfo = flowResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${flowResult.updatedScripts.join(", ")}`)) : "";
|
|
64826
|
+
info(`${formatProgress(current)} flow ${item.path}${scriptsInfo}`);
|
|
64827
|
+
} catch (e) {
|
|
64828
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64829
|
+
errors.push({ path: item.path, error: msg });
|
|
64830
|
+
info(`${formatProgress(current)} flow ${item.path}`);
|
|
64831
|
+
error(` Failed: ${msg}`);
|
|
64832
|
+
}
|
|
64833
|
+
}
|
|
64834
|
+
for (const item of apps2) {
|
|
64835
|
+
current++;
|
|
64836
|
+
try {
|
|
64837
|
+
const result = await generateAppLocksInternal(item.folder.replaceAll("/", SEP8), item.isRawApp, false, workspace, opts, false, true, tree);
|
|
64838
|
+
const appResult = result;
|
|
64839
|
+
const scriptsInfo = appResult?.updatedScripts?.length ? colors.dim(colors.white(`: ${appResult.updatedScripts.join(", ")}`)) : "";
|
|
64840
|
+
info(`${formatProgress(current)} app ${item.path}${scriptsInfo}`);
|
|
64841
|
+
} catch (e) {
|
|
64842
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
64843
|
+
errors.push({ path: item.path, error: msg });
|
|
64844
|
+
info(`${formatProgress(current)} app ${item.path}`);
|
|
64845
|
+
error(` Failed: ${msg}`);
|
|
64846
|
+
}
|
|
64847
|
+
}
|
|
64848
|
+
const allStaleDeps = staleItems.filter((i) => i.type === "dependencies");
|
|
64849
|
+
await tree.persistDepsHashes(allStaleDeps.map((d) => d.path));
|
|
64850
|
+
const succeeded = total - errors.length;
|
|
64851
|
+
info("");
|
|
64852
|
+
if (errors.length > 0) {
|
|
64853
|
+
info(`Done. Updated ${colors.bold(String(succeeded))}/${total} item(s). ${colors.red(String(errors.length) + " failed")}:`);
|
|
64854
|
+
for (const { path: path11, error: error2 } of errors) {
|
|
64855
|
+
error(` ${path11}: ${error2}`);
|
|
64856
|
+
}
|
|
64857
|
+
process.exitCode = 1;
|
|
64858
|
+
} else {
|
|
64859
|
+
info(`Done. Updated ${colors.bold(String(total))} item(s).`);
|
|
64860
|
+
}
|
|
64861
|
+
}
|
|
64862
|
+
async function rehashCommand(opts, folder) {
|
|
64863
|
+
if (folder === "")
|
|
64864
|
+
folder = undefined;
|
|
64865
|
+
opts = await mergeConfigWithConfigFile(opts);
|
|
64866
|
+
await rehashOnly(opts, folder, {
|
|
64867
|
+
skipScripts: opts.skipScripts,
|
|
64868
|
+
skipFlows: opts.skipFlows,
|
|
64869
|
+
skipApps: opts.skipApps
|
|
64870
|
+
});
|
|
64871
|
+
}
|
|
64872
|
+
var command7, generate_metadata_default;
|
|
64873
|
+
var init_generate_metadata = __esm(async () => {
|
|
64874
|
+
init_mod3();
|
|
64875
|
+
init_colors2();
|
|
64876
|
+
init_log();
|
|
64877
|
+
await __promiseAll([
|
|
64878
|
+
init_confirm(),
|
|
64879
|
+
init_conf(),
|
|
64880
|
+
init_context(),
|
|
64881
|
+
init_auth(),
|
|
64882
|
+
init_metadata(),
|
|
64883
|
+
init_flow_metadata(),
|
|
64884
|
+
init_app_metadata(),
|
|
64885
|
+
init_sync(),
|
|
64886
|
+
init_script(),
|
|
64887
|
+
init_resource_folders(),
|
|
64888
|
+
init_codebase(),
|
|
64889
|
+
init_dependency_tree()
|
|
64890
|
+
]);
|
|
64891
|
+
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));
|
|
64892
|
+
generate_metadata_default = command7;
|
|
64893
|
+
});
|
|
64894
|
+
|
|
64230
64895
|
// src/commands/sync/sync.ts
|
|
64231
64896
|
var exports_sync = {};
|
|
64232
64897
|
__export(exports_sync, {
|
|
@@ -64248,7 +64913,7 @@ __export(exports_sync, {
|
|
|
64248
64913
|
});
|
|
64249
64914
|
import { writeFile as writeFile7, readdir as readdir4, stat as stat7, rm, copyFile, mkdir as mkdir5 } from "node:fs/promises";
|
|
64250
64915
|
import * as path11 from "node:path";
|
|
64251
|
-
import { sep as
|
|
64916
|
+
import { sep as SEP9 } from "node:path";
|
|
64252
64917
|
function resolveWsNameFromBranch(opts, branchName) {
|
|
64253
64918
|
const match2 = findWorkspaceByGitBranch(opts.workspaces, branchName);
|
|
64254
64919
|
return match2 ? match2[0] : branchName;
|
|
@@ -64578,11 +65243,11 @@ function extractInlineScriptsForApps(key, rec, pathAssigner, toId, removeSchema)
|
|
|
64578
65243
|
const o = v;
|
|
64579
65244
|
const name = toId(key ?? "", rec);
|
|
64580
65245
|
const [basePathO, ext2] = pathAssigner.assignPath(name, o["language"]);
|
|
64581
|
-
const basePath = basePathO.replaceAll(
|
|
65246
|
+
const basePath = basePathO.replaceAll(SEP9, "/");
|
|
64582
65247
|
const r = [];
|
|
64583
65248
|
if (o["content"]) {
|
|
64584
65249
|
const content = o["content"];
|
|
64585
|
-
o["content"] = "!inline " + basePath.replaceAll(
|
|
65250
|
+
o["content"] = "!inline " + basePath.replaceAll(SEP9, "/") + ext2;
|
|
64586
65251
|
r.push({
|
|
64587
65252
|
path: basePath + ext2,
|
|
64588
65253
|
content
|
|
@@ -64590,7 +65255,7 @@ function extractInlineScriptsForApps(key, rec, pathAssigner, toId, removeSchema)
|
|
|
64590
65255
|
}
|
|
64591
65256
|
if (o["lock"] && o["lock"] != "") {
|
|
64592
65257
|
const lock = o["lock"];
|
|
64593
|
-
o["lock"] = "!inline " + basePath.replaceAll(
|
|
65258
|
+
o["lock"] = "!inline " + basePath.replaceAll(SEP9, "/") + "lock";
|
|
64594
65259
|
r.push({
|
|
64595
65260
|
path: basePath + "lock",
|
|
64596
65261
|
content: lock
|
|
@@ -64624,7 +65289,7 @@ function parseFileResourceTypeMap(raw) {
|
|
|
64624
65289
|
return { formatExtMap, filesetMap };
|
|
64625
65290
|
}
|
|
64626
65291
|
async function findFilesetResourceFile(changePath) {
|
|
64627
|
-
const filesetIdx = changePath.indexOf(".fileset" +
|
|
65292
|
+
const filesetIdx = changePath.indexOf(".fileset" + SEP9);
|
|
64628
65293
|
if (filesetIdx === -1) {
|
|
64629
65294
|
throw new Error(`Not a fileset resource path: ${changePath}`);
|
|
64630
65295
|
}
|
|
@@ -64724,12 +65389,12 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64724
65389
|
try {
|
|
64725
65390
|
const assigner = newPathAssigner(defaultTs, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
64726
65391
|
const inlineMapping = extractCurrentMapping(flow.value.modules, {}, flow.value.failure_module, flow.value.preprocessor_module);
|
|
64727
|
-
inlineScripts = extractInlineScripts(flow.value.modules, inlineMapping,
|
|
65392
|
+
inlineScripts = extractInlineScripts(flow.value.modules, inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
64728
65393
|
if (flow.value.failure_module) {
|
|
64729
|
-
inlineScripts.push(...extractInlineScripts([flow.value.failure_module], inlineMapping,
|
|
65394
|
+
inlineScripts.push(...extractInlineScripts([flow.value.failure_module], inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
64730
65395
|
}
|
|
64731
65396
|
if (flow.value.preprocessor_module) {
|
|
64732
|
-
inlineScripts.push(...extractInlineScripts([flow.value.preprocessor_module], inlineMapping,
|
|
65397
|
+
inlineScripts.push(...extractInlineScripts([flow.value.preprocessor_module], inlineMapping, SEP9, defaultTs, assigner, { skipInlineScriptSuffix: getNonDottedPaths() }));
|
|
64733
65398
|
}
|
|
64734
65399
|
} catch (error2) {
|
|
64735
65400
|
error(`Failed to extract inline scripts for flow at path: ${p}`);
|
|
@@ -64939,10 +65604,10 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64939
65604
|
const hasModules = parsed["modules"] && Object.keys(parsed["modules"]).length > 0;
|
|
64940
65605
|
if (parsed["lock"] && parsed["lock"] != "" && parsed["codebase"] == undefined) {
|
|
64941
65606
|
if (hasModules) {
|
|
64942
|
-
const scriptBase = removeSuffix(removeSuffix(p.replaceAll(
|
|
65607
|
+
const scriptBase = removeSuffix(removeSuffix(p.replaceAll(SEP9, "/"), ".json"), ".script");
|
|
64943
65608
|
parsed["lock"] = "!inline " + scriptBase + getModuleFolderSuffix() + "/script.lock";
|
|
64944
65609
|
} else {
|
|
64945
|
-
parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(
|
|
65610
|
+
parsed["lock"] = "!inline " + removeSuffix(p.replaceAll(SEP9, "/"), ".json") + ".lock";
|
|
64946
65611
|
}
|
|
64947
65612
|
} else if (parsed["lock"] == "") {
|
|
64948
65613
|
parsed["lock"] = "";
|
|
@@ -64972,9 +65637,9 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
64972
65637
|
const formatExtension = resourceTypeToFormatExtension[resourceType];
|
|
64973
65638
|
const isFileset = resourceTypeToIsFileset[resourceType] ?? false;
|
|
64974
65639
|
if (isFileset) {
|
|
64975
|
-
parsed["value"] = "!inline_fileset " + removeSuffix(p.replaceAll(
|
|
65640
|
+
parsed["value"] = "!inline_fileset " + removeSuffix(p.replaceAll(SEP9, "/"), ".resource.json") + ".fileset";
|
|
64976
65641
|
} else if (formatExtension) {
|
|
64977
|
-
parsed["value"]["content"] = "!inline " + removeSuffix(p.replaceAll(
|
|
65642
|
+
parsed["value"]["content"] = "!inline " + removeSuffix(p.replaceAll(SEP9, "/"), ".resource.json") + ".resource.file." + formatExtension;
|
|
64978
65643
|
}
|
|
64979
65644
|
return useYaml ? import_yaml11.stringify(parsed, yamlOptions) : JSON.stringify(parsed, null, 2);
|
|
64980
65645
|
}
|
|
@@ -65141,7 +65806,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, re
|
|
|
65141
65806
|
}
|
|
65142
65807
|
};
|
|
65143
65808
|
}
|
|
65144
|
-
return _internal_folder("." +
|
|
65809
|
+
return _internal_folder("." + SEP9, zip);
|
|
65145
65810
|
}
|
|
65146
65811
|
async function* readDirRecursiveWithIgnore2(ignore, root) {
|
|
65147
65812
|
const stack = [
|
|
@@ -65160,7 +65825,7 @@ async function* readDirRecursiveWithIgnore2(ignore, root) {
|
|
|
65160
65825
|
yield e;
|
|
65161
65826
|
for await (const e2 of e.c()) {
|
|
65162
65827
|
if (e2.isDirectory) {
|
|
65163
|
-
const dirName = e2.path.split(
|
|
65828
|
+
const dirName = e2.path.split(SEP9).pop();
|
|
65164
65829
|
if (dirName == "node_modules" || dirName == ".claude" || dirName?.startsWith(".")) {
|
|
65165
65830
|
continue;
|
|
65166
65831
|
}
|
|
@@ -65183,7 +65848,7 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
|
|
|
65183
65848
|
for await (const entry of readDirRecursiveWithIgnore2(ignore, els)) {
|
|
65184
65849
|
if (entry.isDirectory) {
|
|
65185
65850
|
if (!isRemote) {
|
|
65186
|
-
const dirName = entry.path.split(
|
|
65851
|
+
const dirName = entry.path.split(SEP9).pop() ?? "";
|
|
65187
65852
|
if (hasWrongFormatSuffix(dirName)) {
|
|
65188
65853
|
wrongFormatPaths.push(entry.path);
|
|
65189
65854
|
}
|
|
@@ -65228,7 +65893,7 @@ async function elementsToMap(els, ignore, json, skips, specificItems, branchOver
|
|
|
65228
65893
|
}
|
|
65229
65894
|
}
|
|
65230
65895
|
if (isRawAppFile(path12)) {
|
|
65231
|
-
const suffix = path12.split(getFolderSuffix("raw_app") +
|
|
65896
|
+
const suffix = path12.split(getFolderSuffix("raw_app") + SEP9).pop();
|
|
65232
65897
|
if (suffix?.startsWith("dist/") || suffix == "wmill.d.ts" || suffix == "package-lock.json" || suffix == "DATATABLES.md") {
|
|
65233
65898
|
continue;
|
|
65234
65899
|
}
|
|
@@ -65499,7 +66164,8 @@ async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetada
|
|
|
65499
66164
|
}
|
|
65500
66165
|
return a.path.localeCompare(b.path);
|
|
65501
66166
|
});
|
|
65502
|
-
|
|
66167
|
+
const localMap = isEls1Remote ? m2 : m1;
|
|
66168
|
+
return { changes, localMap };
|
|
65503
66169
|
}
|
|
65504
66170
|
function getOrderFromPath(p) {
|
|
65505
66171
|
const typ = getTypeStrFromPath(p);
|
|
@@ -65728,7 +66394,7 @@ async function pull(opts) {
|
|
|
65728
66394
|
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
66395
|
const remote = ZipFSElement(zipFile, !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, true, parseSyncBehavior(opts.syncBehavior) >= 1);
|
|
65730
66396
|
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);
|
|
66397
|
+
const { changes, localMap } = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, wsNameForFiles, true);
|
|
65732
66398
|
info(`remote (${workspace.name}) -> local: ${changes.length} changes to apply`);
|
|
65733
66399
|
if (opts.dryRun && opts.jsonOutput) {
|
|
65734
66400
|
const result = {
|
|
@@ -65892,6 +66558,31 @@ Done! All ${changes.length} changes applied locally and wmill-lock.yaml updated.
|
|
|
65892
66558
|
} else if (opts.jsonOutput) {
|
|
65893
66559
|
console.log(JSON.stringify({ success: true, message: "No changes to apply", total: 0 }, null, 2));
|
|
65894
66560
|
}
|
|
66561
|
+
if (!opts.jsonOutput && !opts.dryRun) {
|
|
66562
|
+
try {
|
|
66563
|
+
const { rehashOnly: rehashOnly2 } = await init_generate_metadata().then(() => exports_generate_metadata);
|
|
66564
|
+
const postPullPaths = new Set(Object.keys(localMap));
|
|
66565
|
+
for (const change of changes) {
|
|
66566
|
+
if (change.name === "added")
|
|
66567
|
+
postPullPaths.add(change.path);
|
|
66568
|
+
else if (change.name === "deleted")
|
|
66569
|
+
postPullPaths.delete(change.path);
|
|
66570
|
+
}
|
|
66571
|
+
const filled = await rehashOnly2(opts, undefined, {
|
|
66572
|
+
missingOnly: true,
|
|
66573
|
+
localFiles: postPullPaths
|
|
66574
|
+
});
|
|
66575
|
+
const total = filled.scripts + filled.flows + filled.apps;
|
|
66576
|
+
if (total > 0) {
|
|
66577
|
+
info(colors.gray(`Auto-filled ${total} missing lockfile entr${total === 1 ? "y" : "ies"} (${filled.scripts} script, ${filled.flows} flow, ${filled.apps} app) from disk.`));
|
|
66578
|
+
}
|
|
66579
|
+
} catch (e) {
|
|
66580
|
+
if (e instanceof UnknownLockVersionError || e instanceof MalformedLockfileError) {
|
|
66581
|
+
throw e;
|
|
66582
|
+
}
|
|
66583
|
+
warn(colors.yellow(`Could not auto-fill missing lockfile entries: ${e instanceof Error ? e.message : e}`));
|
|
66584
|
+
}
|
|
66585
|
+
}
|
|
65895
66586
|
try {
|
|
65896
66587
|
await pullSharedUi(workspace.workspaceId);
|
|
65897
66588
|
} catch (e) {
|
|
@@ -66020,7 +66711,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66020
66711
|
} catch {}
|
|
66021
66712
|
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
66713
|
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);
|
|
66714
|
+
const { changes } = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, wsNameForFiles, false);
|
|
66024
66715
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
66025
66716
|
const tracker = await buildTracker(changes);
|
|
66026
66717
|
const autoRegenerate = !!opts.autoMetadata;
|
|
@@ -66127,7 +66818,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66127
66818
|
if (changes.length > 0) {
|
|
66128
66819
|
const folderNames = new Set;
|
|
66129
66820
|
for (const change of changes) {
|
|
66130
|
-
const parts = change.path.split(
|
|
66821
|
+
const parts = change.path.split(SEP9);
|
|
66131
66822
|
if (parts.length >= 3 && parts[0] === "f" && change.name !== "deleted") {
|
|
66132
66823
|
folderNames.add(parts[1]);
|
|
66133
66824
|
}
|
|
@@ -66160,7 +66851,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
66160
66851
|
const userIsAdmin = user.is_admin;
|
|
66161
66852
|
const msg = `${userIsAdmin ? "Warning: " : ""}Missing folder.meta.yaml for:
|
|
66162
66853
|
${folderList}
|
|
66163
|
-
|
|
66854
|
+
Run 'wmill folder add-missing' to create them locally, then push again.`;
|
|
66164
66855
|
if (!userIsAdmin) {
|
|
66165
66856
|
if (opts.jsonOutput) {
|
|
66166
66857
|
console.log(JSON.stringify({ success: false, error: "missing_folders", missing_folders: missingFolders, message: msg }, null, 2));
|
|
@@ -66242,7 +66933,7 @@ ${folderList}
|
|
|
66242
66933
|
};
|
|
66243
66934
|
await preCheckPermissionedAs(changes, user.email, userIsAdminOrDeployer, opts.acceptOverridingPermissionedAsWithSelf ?? false, !!process.stdin.isTTY);
|
|
66244
66935
|
} 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,
|
|
66936
|
+
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
66937
|
}
|
|
66247
66938
|
if (!opts.yes && !await Confirm.prompt({
|
|
66248
66939
|
message: `Do you want to apply these ${changes.length} changes to the remote?`,
|
|
@@ -66273,7 +66964,7 @@ ${folderList}
|
|
|
66273
66964
|
parallelizationFactor = 1;
|
|
66274
66965
|
}
|
|
66275
66966
|
const allGrouped = Array.from(groupedChanges.entries());
|
|
66276
|
-
const isFolderMetaGroup = ([basePath]) => basePath.endsWith(`${
|
|
66967
|
+
const isFolderMetaGroup = ([basePath]) => basePath.endsWith(`${SEP9}folder`) || basePath === "folder";
|
|
66277
66968
|
const folderMetaGroups = allGrouped.filter(isFolderMetaGroup);
|
|
66278
66969
|
const groupedChangesArray = allGrouped.filter((g) => !isFolderMetaGroup(g));
|
|
66279
66970
|
info(`found changes for ${allGrouped.length} items with a total of ${allGrouped.reduce((acc, [_, changes2]) => acc + changes2.length, 0)} files to process`);
|
|
@@ -66289,7 +66980,7 @@ ${folderList}
|
|
|
66289
66980
|
while (pool.size < effectiveParallelism() && queue.length > 0) {
|
|
66290
66981
|
const [groupBasePath, initialChanges] = queue.shift();
|
|
66291
66982
|
let changes2 = initialChanges;
|
|
66292
|
-
const isFolderGroup = groupBasePath.endsWith(`${
|
|
66983
|
+
const isFolderGroup = groupBasePath.endsWith(`${SEP9}folder`) || groupBasePath === "folder";
|
|
66293
66984
|
const promise = (async () => {
|
|
66294
66985
|
const alreadySynced = [];
|
|
66295
66986
|
const deletedVarsResPaths = [];
|
|
@@ -66421,7 +67112,7 @@ ${folderList}
|
|
|
66421
67112
|
info(`Deleting ${typ} ${change.path}`);
|
|
66422
67113
|
}
|
|
66423
67114
|
const workspaceId = workspace.workspaceId;
|
|
66424
|
-
const target = change.path.replaceAll(
|
|
67115
|
+
const target = change.path.replaceAll(SEP9, "/");
|
|
66425
67116
|
switch (typ) {
|
|
66426
67117
|
case "script": {
|
|
66427
67118
|
await archiveScriptByPath({
|
|
@@ -66433,7 +67124,7 @@ ${folderList}
|
|
|
66433
67124
|
case "folder":
|
|
66434
67125
|
await deleteFolder({
|
|
66435
67126
|
workspace: workspaceId,
|
|
66436
|
-
name: change.path.split(
|
|
67127
|
+
name: change.path.split(SEP9)[1]
|
|
66437
67128
|
});
|
|
66438
67129
|
break;
|
|
66439
67130
|
case "resource": {
|
|
@@ -66732,14 +67423,14 @@ Done! All ${changes.length} changes pushed to the remote workspace ${workspace.w
|
|
|
66732
67423
|
}
|
|
66733
67424
|
}
|
|
66734
67425
|
var import_yaml11, branchDeprecationWarned = false, yamlOptions, isNotWmillFile = (p, isDirectory2) => {
|
|
66735
|
-
if (p.endsWith(
|
|
67426
|
+
if (p.endsWith(SEP9)) {
|
|
66736
67427
|
return false;
|
|
66737
67428
|
}
|
|
66738
|
-
if (p.startsWith("ui" +
|
|
67429
|
+
if (p.startsWith("ui" + SEP9)) {
|
|
66739
67430
|
return true;
|
|
66740
67431
|
}
|
|
66741
67432
|
if (isDirectory2) {
|
|
66742
|
-
return !p.startsWith("u" +
|
|
67433
|
+
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
67434
|
}
|
|
66744
67435
|
if (isScriptModulePath(p)) {
|
|
66745
67436
|
return false;
|
|
@@ -66747,16 +67438,16 @@ var import_yaml11, branchDeprecationWarned = false, yamlOptions, isNotWmillFile
|
|
|
66747
67438
|
try {
|
|
66748
67439
|
const typ = getTypeStrFromPath(p);
|
|
66749
67440
|
if (typ == "resource-type" || typ == "settings" || typ == "encryption_key") {
|
|
66750
|
-
return p.includes(
|
|
67441
|
+
return p.includes(SEP9);
|
|
66751
67442
|
} else {
|
|
66752
|
-
return !p.startsWith("u" +
|
|
67443
|
+
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
67444
|
}
|
|
66754
67445
|
} catch {
|
|
66755
67446
|
return true;
|
|
66756
67447
|
}
|
|
66757
67448
|
}, isWhitelisted = (p) => {
|
|
66758
|
-
return p == "." +
|
|
66759
|
-
},
|
|
67449
|
+
return p == "." + SEP9 || p == "" || p == "u" || p == "f" || p == "g" || p == "ui" || p == "users" || p == "groups" || p == "dependencies";
|
|
67450
|
+
}, command8, sync_default;
|
|
66760
67451
|
var init_sync = __esm(async () => {
|
|
66761
67452
|
init_colors2();
|
|
66762
67453
|
init_mod3();
|
|
@@ -66798,8 +67489,8 @@ var init_sync = __esm(async () => {
|
|
|
66798
67489
|
aliasDuplicateObjects: false,
|
|
66799
67490
|
singleQuote: true
|
|
66800
67491
|
};
|
|
66801
|
-
|
|
66802
|
-
sync_default =
|
|
67492
|
+
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);
|
|
67493
|
+
sync_default = command8;
|
|
66803
67494
|
});
|
|
66804
67495
|
|
|
66805
67496
|
// windmill-utils-internal/src/parse/parse-schema.ts
|
|
@@ -67004,7 +67695,7 @@ var init_parse_schema = __esm(() => {
|
|
|
67004
67695
|
});
|
|
67005
67696
|
|
|
67006
67697
|
// src/utils/metadata.ts
|
|
67007
|
-
import { sep as
|
|
67698
|
+
import { sep as SEP10 } from "node:path";
|
|
67008
67699
|
import { writeFile as writeFile8, stat as stat8, rm as rm2, readdir as readdir5 } from "node:fs/promises";
|
|
67009
67700
|
import { readFileSync as readFileSync2, existsSync as existsSync6, readdirSync, statSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
67010
67701
|
import * as path12 from "node:path";
|
|
@@ -67098,7 +67789,7 @@ async function blueColor() {
|
|
|
67098
67789
|
}
|
|
67099
67790
|
async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRun, noStaleMessage, rawWorkspaceDependencies, codebases, justUpdateMetadataLock, tree) {
|
|
67100
67791
|
const isFolderLayout = isModuleEntryPoint(scriptPath);
|
|
67101
|
-
const remotePath =
|
|
67792
|
+
const remotePath = scriptPathToRemotePath(scriptPath);
|
|
67102
67793
|
const language = inferContentTypeFromFilePath(scriptPath, opts.defaultTs);
|
|
67103
67794
|
const metadataWithType = await parseMetadataFile(remotePath, undefined);
|
|
67104
67795
|
const scriptContent = await readTextFile(scriptPath);
|
|
@@ -67113,6 +67804,22 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67113
67804
|
moduleHashes = await computeModuleHashes(moduleFolderPath, opts.defaultTs, tree ? {} : rawWorkspaceDependencies, isFolderLayout);
|
|
67114
67805
|
}
|
|
67115
67806
|
const hasModuleHashes = Object.keys(moduleHashes).length > 0;
|
|
67807
|
+
if (opts.rehashOnly) {
|
|
67808
|
+
if (hasModuleHashes) {
|
|
67809
|
+
const sortedEntries = Object.entries(moduleHashes).sort(([a], [b]) => a.localeCompare(b));
|
|
67810
|
+
const metaHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
|
|
67811
|
+
await clearGlobalLock(remotePath);
|
|
67812
|
+
await updateMetadataGlobalLock(remotePath, metaHash, SCRIPT_TOP_HASH);
|
|
67813
|
+
for (const [modulePath, moduleHash] of Object.entries(moduleHashes)) {
|
|
67814
|
+
await updateMetadataGlobalLock(remotePath, moduleHash, modulePath);
|
|
67815
|
+
}
|
|
67816
|
+
} else {
|
|
67817
|
+
await clearGlobalLock(remotePath);
|
|
67818
|
+
await updateMetadataGlobalLock(remotePath, hash2);
|
|
67819
|
+
}
|
|
67820
|
+
return;
|
|
67821
|
+
}
|
|
67822
|
+
const conf = await readLockfile();
|
|
67116
67823
|
let checkHash = hash2;
|
|
67117
67824
|
let checkSubpath;
|
|
67118
67825
|
if (hasModuleHashes) {
|
|
@@ -67120,7 +67827,6 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67120
67827
|
checkHash = await generateHash(hash2 + JSON.stringify(sortedEntries));
|
|
67121
67828
|
checkSubpath = SCRIPT_TOP_HASH;
|
|
67122
67829
|
}
|
|
67123
|
-
const conf = await readLockfile();
|
|
67124
67830
|
const isDirectlyStale = !await checkifMetadataUptodate(remotePath, checkHash, conf, checkSubpath);
|
|
67125
67831
|
if (tree) {
|
|
67126
67832
|
if (dryRun) {
|
|
@@ -67183,9 +67889,9 @@ async function generateScriptMetadataInternal(scriptPath, workspace, opts, dryRu
|
|
|
67183
67889
|
}
|
|
67184
67890
|
} else {
|
|
67185
67891
|
if (isFolderLayout) {
|
|
67186
|
-
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(
|
|
67892
|
+
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP10, "/") + getModuleFolderSuffix() + "/script.lock";
|
|
67187
67893
|
} else {
|
|
67188
|
-
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(
|
|
67894
|
+
metadataParsedContent.lock = "!inline " + remotePath.replaceAll(SEP10, "/") + ".script.lock";
|
|
67189
67895
|
}
|
|
67190
67896
|
}
|
|
67191
67897
|
let metaPath;
|
|
@@ -67372,7 +68078,7 @@ async function updateScriptLock(workspace, scriptContent, language, remotePath,
|
|
|
67372
68078
|
const lockPath = lockPathOverride ?? remotePath + ".script.lock";
|
|
67373
68079
|
if (lock != "") {
|
|
67374
68080
|
await writeFile8(lockPath, lock, "utf-8");
|
|
67375
|
-
metadataContent.lock = "!inline " + lockPath.replaceAll(
|
|
68081
|
+
metadataContent.lock = "!inline " + lockPath.replaceAll(SEP10, "/");
|
|
67376
68082
|
} else {
|
|
67377
68083
|
try {
|
|
67378
68084
|
if (await stat8(lockPath)) {
|
|
@@ -67686,22 +68392,29 @@ async function parseMetadataFile(scriptPath, generateMetadataIfMissing) {
|
|
|
67686
68392
|
};
|
|
67687
68393
|
}
|
|
67688
68394
|
function normalizeLockPath(p) {
|
|
67689
|
-
|
|
68395
|
+
let n = p.replace(/\\/g, "/");
|
|
68396
|
+
if (n.startsWith("./"))
|
|
68397
|
+
n = n.slice(2);
|
|
68398
|
+
return n;
|
|
67690
68399
|
}
|
|
67691
68400
|
async function readLockfile() {
|
|
68401
|
+
let parsed;
|
|
67692
68402
|
try {
|
|
67693
|
-
|
|
67694
|
-
if (typeof read2 == "object" && read2 != null) {
|
|
67695
|
-
return read2;
|
|
67696
|
-
} else {
|
|
67697
|
-
throw new Error("Invalid lockfile");
|
|
67698
|
-
}
|
|
68403
|
+
parsed = await yamlParseFile(WMILL_LOCKFILE);
|
|
67699
68404
|
} catch {
|
|
67700
|
-
const lock = { locks: {}, version:
|
|
68405
|
+
const lock = { locks: {}, version: CURRENT_LOCK_VERSION };
|
|
67701
68406
|
await writeFile8(WMILL_LOCKFILE, import_yaml13.stringify(lock, yamlOptions), "utf-8");
|
|
67702
68407
|
info(colors.green("wmill-lock.yaml created"));
|
|
67703
68408
|
return lock;
|
|
67704
68409
|
}
|
|
68410
|
+
if (typeof parsed != "object" || parsed == null) {
|
|
68411
|
+
throw new MalformedLockfileError("wmill-lock.yaml is malformed (expected an object). Refusing to operate to avoid corrupting the lockfile.");
|
|
68412
|
+
}
|
|
68413
|
+
const conf = parsed;
|
|
68414
|
+
if (conf.version != null && !KNOWN_LOCK_VERSIONS.includes(conf.version)) {
|
|
68415
|
+
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.`);
|
|
68416
|
+
}
|
|
68417
|
+
return conf;
|
|
67705
68418
|
}
|
|
67706
68419
|
function v2LockPath(path13, subpath) {
|
|
67707
68420
|
const normalizedPath = normalizeLockPath(path13);
|
|
@@ -67718,15 +68431,18 @@ async function checkifMetadataUptodate(path13, hash2, conf, subpath) {
|
|
|
67718
68431
|
if (!conf.locks) {
|
|
67719
68432
|
return false;
|
|
67720
68433
|
}
|
|
67721
|
-
const
|
|
67722
|
-
if (
|
|
67723
|
-
const
|
|
67724
|
-
return
|
|
67725
|
-
}
|
|
67726
|
-
|
|
67727
|
-
const
|
|
67728
|
-
|
|
68434
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68435
|
+
if (isFlatKeyed) {
|
|
68436
|
+
const key = v2LockPath(path13, subpath);
|
|
68437
|
+
return conf.locks?.[key] === hash2 || conf.locks?.["./" + key] === hash2;
|
|
68438
|
+
}
|
|
68439
|
+
for (const p of [path13, "./" + path13]) {
|
|
68440
|
+
const obj = conf.locks?.[p];
|
|
68441
|
+
const v = subpath && typeof obj == "object" ? obj?.[subpath] : obj;
|
|
68442
|
+
if (v === hash2)
|
|
68443
|
+
return true;
|
|
67729
68444
|
}
|
|
68445
|
+
return false;
|
|
67730
68446
|
}
|
|
67731
68447
|
async function generateScriptHash(rawWorkspaceDependencies, scriptContent, newMetadataContent) {
|
|
67732
68448
|
return await generateHash(JSON.stringify(rawWorkspaceDependencies) + scriptContent + newMetadataContent);
|
|
@@ -67761,15 +68477,16 @@ async function clearGlobalLock(path13) {
|
|
|
67761
68477
|
if (!conf?.locks) {
|
|
67762
68478
|
conf.locks = {};
|
|
67763
68479
|
}
|
|
67764
|
-
const
|
|
67765
|
-
if (
|
|
68480
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68481
|
+
if (isFlatKeyed) {
|
|
67766
68482
|
const key = v2LockPath(path13);
|
|
68483
|
+
const legacyKey = "./" + key;
|
|
67767
68484
|
if (conf.locks) {
|
|
67768
68485
|
Object.keys(conf.locks).forEach((k) => {
|
|
67769
|
-
if (conf.locks)
|
|
67770
|
-
|
|
67771
|
-
|
|
67772
|
-
|
|
68486
|
+
if (!conf.locks)
|
|
68487
|
+
return;
|
|
68488
|
+
if (k === key || k.startsWith(key + "+") || k === legacyKey || k.startsWith(legacyKey + "+")) {
|
|
68489
|
+
delete conf.locks[k];
|
|
67773
68490
|
}
|
|
67774
68491
|
});
|
|
67775
68492
|
}
|
|
@@ -67781,8 +68498,8 @@ async function updateMetadataGlobalLock(path13, hash2, subpath) {
|
|
|
67781
68498
|
if (!conf?.locks) {
|
|
67782
68499
|
conf.locks = {};
|
|
67783
68500
|
}
|
|
67784
|
-
const
|
|
67785
|
-
if (
|
|
68501
|
+
const isFlatKeyed = conf?.version === "v2";
|
|
68502
|
+
if (isFlatKeyed) {
|
|
67786
68503
|
conf.locks[v2LockPath(path13, subpath)] = hash2;
|
|
67787
68504
|
} else {
|
|
67788
68505
|
if (subpath) {
|
|
@@ -67798,7 +68515,7 @@ async function updateMetadataGlobalLock(path13, hash2, subpath) {
|
|
|
67798
68515
|
}
|
|
67799
68516
|
await writeFile8(WMILL_LOCKFILE, import_yaml13.stringify(conf, yamlOptions), "utf-8");
|
|
67800
68517
|
}
|
|
67801
|
-
var import_yaml13, _require, _parserCache, LockfileGenerationError, LANG_ANNOTATION_CONFIG, lockCache, WMILL_LOCKFILE = "wmill-lock.yaml", SCRIPT_TOP_HASH = "__script_hash";
|
|
68518
|
+
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
68519
|
var init_metadata = __esm(async () => {
|
|
67803
68520
|
init_colors2();
|
|
67804
68521
|
init_log();
|
|
@@ -67824,6 +68541,18 @@ var init_metadata = __esm(async () => {
|
|
|
67824
68541
|
this.name = "LockfileGenerationError";
|
|
67825
68542
|
}
|
|
67826
68543
|
};
|
|
68544
|
+
UnknownLockVersionError = class UnknownLockVersionError extends Error {
|
|
68545
|
+
constructor(message) {
|
|
68546
|
+
super(message);
|
|
68547
|
+
this.name = "UnknownLockVersionError";
|
|
68548
|
+
}
|
|
68549
|
+
};
|
|
68550
|
+
MalformedLockfileError = class MalformedLockfileError extends Error {
|
|
68551
|
+
constructor(message) {
|
|
68552
|
+
super(message);
|
|
68553
|
+
this.name = "MalformedLockfileError";
|
|
68554
|
+
}
|
|
68555
|
+
};
|
|
67827
68556
|
LANG_ANNOTATION_CONFIG = {
|
|
67828
68557
|
python3: { comment: "#", keyword: "requirements", validityRe: /^#\s?(\S+)\s*$/ },
|
|
67829
68558
|
bun: { comment: "//", keyword: "package_json" },
|
|
@@ -67833,6 +68562,7 @@ var init_metadata = __esm(async () => {
|
|
|
67833
68562
|
powershell: { comment: "#", keyword: "modules_json" }
|
|
67834
68563
|
};
|
|
67835
68564
|
lockCache = new Map;
|
|
68565
|
+
KNOWN_LOCK_VERSIONS = ["v1", "v2"];
|
|
67836
68566
|
});
|
|
67837
68567
|
|
|
67838
68568
|
// src/commands/app/raw_apps.ts
|
|
@@ -67843,7 +68573,7 @@ __export(exports_raw_apps, {
|
|
|
67843
68573
|
loadRunnablesFromBackend: () => loadRunnablesFromBackend,
|
|
67844
68574
|
generatingPolicy: () => generatingPolicy
|
|
67845
68575
|
});
|
|
67846
|
-
import { sep as
|
|
68576
|
+
import { sep as SEP11 } from "node:path";
|
|
67847
68577
|
import path13 from "node:path";
|
|
67848
68578
|
import { readdir as readdir6 } from "node:fs/promises";
|
|
67849
68579
|
async function readSiblingLock(backendPath, runnableId, allFiles) {
|
|
@@ -67981,7 +68711,7 @@ async function collectAppFiles(localPath) {
|
|
|
67981
68711
|
if (entry.name === APP_BACKEND_FOLDER || entry.name === "node_modules" || entry.name === "dist" || entry.name === ".claude" || entry.name === "sql_to_apply") {
|
|
67982
68712
|
continue;
|
|
67983
68713
|
}
|
|
67984
|
-
await readDirRecursive2(fullPath +
|
|
68714
|
+
await readDirRecursive2(fullPath + SEP11, relativePath + "/");
|
|
67985
68715
|
} else if (entry.isFile()) {
|
|
67986
68716
|
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
68717
|
continue;
|
|
@@ -67999,7 +68729,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
67999
68729
|
return;
|
|
68000
68730
|
}
|
|
68001
68731
|
alreadySynced.push(localPath);
|
|
68002
|
-
remotePath = remotePath.replaceAll(
|
|
68732
|
+
remotePath = remotePath.replaceAll(SEP11, "/");
|
|
68003
68733
|
let app = undefined;
|
|
68004
68734
|
try {
|
|
68005
68735
|
app = await getAppByPath({
|
|
@@ -68013,8 +68743,8 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
68013
68743
|
if (app) {
|
|
68014
68744
|
app.policy = undefined;
|
|
68015
68745
|
}
|
|
68016
|
-
if (!localPath.endsWith(
|
|
68017
|
-
localPath +=
|
|
68746
|
+
if (!localPath.endsWith(SEP11)) {
|
|
68747
|
+
localPath += SEP11;
|
|
68018
68748
|
}
|
|
68019
68749
|
const appFilePath = localPath + "raw_app.yaml";
|
|
68020
68750
|
const localApp = await yamlParseFile(appFilePath);
|
|
@@ -68030,7 +68760,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
|
|
|
68030
68760
|
} else {
|
|
68031
68761
|
runnables = {};
|
|
68032
68762
|
}
|
|
68033
|
-
replaceInlineScripts2(runnables, backendPath +
|
|
68763
|
+
replaceInlineScripts2(runnables, backendPath + SEP11, true);
|
|
68034
68764
|
repopulateFields(runnables);
|
|
68035
68765
|
const appForPolicy = { ...localApp, runnables };
|
|
68036
68766
|
await generatingPolicy(appForPolicy, remotePath, localApp?.["public"] ?? false);
|
|
@@ -68142,7 +68872,20 @@ __export(exports_app_metadata, {
|
|
|
68142
68872
|
});
|
|
68143
68873
|
import path14 from "node:path";
|
|
68144
68874
|
import { mkdir as mkdir6, readdir as readdir7 } from "node:fs/promises";
|
|
68145
|
-
import { sep as
|
|
68875
|
+
import { sep as SEP12 } from "node:path";
|
|
68876
|
+
async function isAppDirectlyStale(appFolder, hashes, conf) {
|
|
68877
|
+
if (await checkifMetadataUptodate(appFolder, hashes[TOP_HASH2], conf, TOP_HASH2)) {
|
|
68878
|
+
return false;
|
|
68879
|
+
}
|
|
68880
|
+
const fileEntries = Object.entries(hashes).filter(([k]) => k !== TOP_HASH2);
|
|
68881
|
+
if (fileEntries.length === 0)
|
|
68882
|
+
return true;
|
|
68883
|
+
for (const [k, h] of fileEntries) {
|
|
68884
|
+
if (!await checkifMetadataUptodate(appFolder, h, conf, k))
|
|
68885
|
+
return true;
|
|
68886
|
+
}
|
|
68887
|
+
return false;
|
|
68888
|
+
}
|
|
68146
68889
|
async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
68147
68890
|
const runnablesFolder = rawApp ? path14.join(folder, APP_BACKEND_FOLDER) : folder;
|
|
68148
68891
|
const hashes = {};
|
|
@@ -68156,7 +68899,7 @@ async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
|
68156
68899
|
}
|
|
68157
68900
|
}
|
|
68158
68901
|
if (exts.some((e) => f.path.endsWith(e))) {
|
|
68159
|
-
const relativePath = normalizeLockPath(f.path.replace(runnablesFolder +
|
|
68902
|
+
const relativePath = normalizeLockPath(f.path.replace(runnablesFolder + SEP12, ""));
|
|
68160
68903
|
hashes[relativePath] = await generateHash(await f.getContentText() + JSON.stringify(rawReqs));
|
|
68161
68904
|
}
|
|
68162
68905
|
}
|
|
@@ -68172,23 +68915,31 @@ async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
|
68172
68915
|
return { ...sortedHashes, [TOP_HASH2]: await generateHash(JSON.stringify(sortedHashes)) };
|
|
68173
68916
|
}
|
|
68174
68917
|
async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, opts, justUpdateMetadataLock, noStaleMessage, tree) {
|
|
68175
|
-
if (appFolder.endsWith(
|
|
68918
|
+
if (appFolder.endsWith(SEP12)) {
|
|
68176
68919
|
appFolder = appFolder.substring(0, appFolder.length - 1);
|
|
68177
68920
|
}
|
|
68178
|
-
|
|
68921
|
+
if (opts.rehashOnly) {
|
|
68922
|
+
const hashes = await generateAppHash({}, appFolder, rawApp, opts.defaultTs);
|
|
68923
|
+
await clearGlobalLock(appFolder);
|
|
68924
|
+
for (const [k, v] of Object.entries(hashes)) {
|
|
68925
|
+
await updateMetadataGlobalLock(appFolder, v, k);
|
|
68926
|
+
}
|
|
68927
|
+
return;
|
|
68928
|
+
}
|
|
68929
|
+
const remote_path = appFolder.replaceAll(SEP12, "/");
|
|
68179
68930
|
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
68180
68931
|
info(`Generating locks for app ${appFolder} at ${remote_path}`);
|
|
68181
68932
|
}
|
|
68182
68933
|
const appFilePath = path14.join(appFolder, rawApp ? "raw_app.yaml" : "app.yaml");
|
|
68183
68934
|
const appFile = await yamlParseFile(appFilePath);
|
|
68184
68935
|
const appValue = rawApp ? appFile.runnables : appFile.value;
|
|
68185
|
-
const folderNormalized = appFolder.replaceAll(
|
|
68936
|
+
const folderNormalized = appFolder.replaceAll(SEP12, "/");
|
|
68186
68937
|
let filteredDeps = {};
|
|
68187
68938
|
const conf = await readLockfile();
|
|
68188
68939
|
if (tree) {
|
|
68189
68940
|
if (dryRun) {
|
|
68190
68941
|
const hashes = await generateAppHash({}, appFolder, rawApp, opts.defaultTs);
|
|
68191
|
-
const isDirectlyStale =
|
|
68942
|
+
const isDirectlyStale = await isAppDirectlyStale(appFolder, hashes, conf);
|
|
68192
68943
|
let treeAppValue = structuredClone(appValue);
|
|
68193
68944
|
if (rawApp) {
|
|
68194
68945
|
const runnablesPath = path14.join(appFolder, APP_BACKEND_FOLDER);
|
|
@@ -68204,7 +68955,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68204
68955
|
}
|
|
68205
68956
|
let content = inlineScript.content;
|
|
68206
68957
|
if (typeof content === "string" && content.startsWith("!inline ")) {
|
|
68207
|
-
const filePath = appFolder +
|
|
68958
|
+
const filePath = appFolder + SEP12 + content.replace("!inline ", "");
|
|
68208
68959
|
try {
|
|
68209
68960
|
content = await readTextFile(filePath);
|
|
68210
68961
|
} catch {
|
|
@@ -68226,7 +68977,7 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68226
68977
|
const rawWorkspaceDependencies = await getRawWorkspaceDependencies(true);
|
|
68227
68978
|
filteredDeps = await filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependencies, appFolder);
|
|
68228
68979
|
const hashes = await generateAppHash(filteredDeps, appFolder, rawApp, opts.defaultTs);
|
|
68229
|
-
const isDirectlyStale =
|
|
68980
|
+
const isDirectlyStale = await isAppDirectlyStale(appFolder, hashes, conf);
|
|
68230
68981
|
if (!isDirectlyStale) {
|
|
68231
68982
|
if (!noStaleMessage) {
|
|
68232
68983
|
info(colors.green(`App ${remote_path} metadata is up-to-date, skipping`));
|
|
@@ -68263,11 +69014,11 @@ async function generateAppLocksInternal(appFolder, rawApp, dryRun, workspace, op
|
|
|
68263
69014
|
if (Object.keys(runnables).length === 0 && rawAppFile.runnables) {
|
|
68264
69015
|
runnables = rawAppFile.runnables;
|
|
68265
69016
|
}
|
|
68266
|
-
replaceInlineScripts2(runnables, runnablesPath +
|
|
69017
|
+
replaceInlineScripts2(runnables, runnablesPath + SEP12, false);
|
|
68267
69018
|
updatedScripts = await updateRawAppRunnables(workspace, runnables, remote_path, appFolder, filteredDeps, opts.defaultTs, noStaleMessage, tempScriptRefs);
|
|
68268
69019
|
} else {
|
|
68269
69020
|
const normalAppFile = appFile;
|
|
68270
|
-
replaceInlineScripts2(normalAppFile.value, appFolder +
|
|
69021
|
+
replaceInlineScripts2(normalAppFile.value, appFolder + SEP12, false);
|
|
68271
69022
|
const result = await updateAppInlineScripts(workspace, normalAppFile.value, remote_path, appFolder, filteredDeps, opts.defaultTs, noStaleMessage, tempScriptRefs);
|
|
68272
69023
|
normalAppFile.value = result.value;
|
|
68273
69024
|
updatedScripts = result.updatedScripts;
|
|
@@ -68299,7 +69050,7 @@ async function filterWorkspaceDependenciesForApp(appValue, rawWorkspaceDependenc
|
|
|
68299
69050
|
}
|
|
68300
69051
|
return inlineScript;
|
|
68301
69052
|
});
|
|
68302
|
-
return await filterWorkspaceDependenciesForScripts(scripts, rawWorkspaceDependencies, folder,
|
|
69053
|
+
return await filterWorkspaceDependenciesForScripts(scripts, rawWorkspaceDependencies, folder, SEP12);
|
|
68303
69054
|
}
|
|
68304
69055
|
async function traverseAndProcessInlineScripts(obj, processor, currentPath = []) {
|
|
68305
69056
|
if (!obj || typeof obj !== "object") {
|
|
@@ -68354,7 +69105,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
|
|
|
68354
69105
|
}
|
|
68355
69106
|
if (language === "frontend") {
|
|
68356
69107
|
const [basePathO, ext2] = pathAssigner.assignPath(runnableId, language);
|
|
68357
|
-
const basePath = basePathO.replaceAll(
|
|
69108
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68358
69109
|
const contentPath = path14.join(runnablesFolder, `${basePath}${ext2}`);
|
|
68359
69110
|
writeIfChanged(contentPath, content);
|
|
68360
69111
|
const simplifiedRunnable = { type: "inline" };
|
|
@@ -68372,7 +69123,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
|
|
|
68372
69123
|
try {
|
|
68373
69124
|
const lock = await generateInlineScriptLock(workspace, content, language, `${remotePath}/${runnableId}`, rawDeps, tempScriptRefs);
|
|
68374
69125
|
const [basePathO, ext2] = pathAssigner.assignPath(runnableId, language);
|
|
68375
|
-
const basePath = basePathO.replaceAll(
|
|
69126
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68376
69127
|
const contentPath = path14.join(runnablesFolder, `${basePath}${ext2}`);
|
|
68377
69128
|
const lockPath = path14.join(runnablesFolder, `${basePath}lock`);
|
|
68378
69129
|
writeIfChanged(contentPath, content);
|
|
@@ -68421,7 +69172,7 @@ async function updateAppInlineScripts(workspace, appValue, remotePath, appFolder
|
|
|
68421
69172
|
lock = await generateInlineScriptLock(workspace, content, language, scriptPath, rawDeps, tempScriptRefs);
|
|
68422
69173
|
}
|
|
68423
69174
|
const [basePathO, ext2] = pathAssigner.assignPath(scriptName, language);
|
|
68424
|
-
const basePath = basePathO.replaceAll(
|
|
69175
|
+
const basePath = basePathO.replaceAll(SEP12, "/");
|
|
68425
69176
|
const contentPath = path14.join(appFolder, `${basePath}${ext2}`);
|
|
68426
69177
|
const lockPath = path14.join(appFolder, `${basePath}lock`);
|
|
68427
69178
|
writeIfChanged(contentPath, content);
|
|
@@ -68550,7 +69301,7 @@ async function inferRunnableSchemaFromFile(appFolder, runnableFilePath, defaultT
|
|
|
68550
69301
|
warn(colors.yellow(`Could not read file: ${fullFilePath}`));
|
|
68551
69302
|
return;
|
|
68552
69303
|
}
|
|
68553
|
-
const remotePath = appFolder.replaceAll(
|
|
69304
|
+
const remotePath = appFolder.replaceAll(SEP12, "/");
|
|
68554
69305
|
try {
|
|
68555
69306
|
const schemaResult = await inferSchema(language, content, currentSchema, `${remotePath}/${runnableId}`);
|
|
68556
69307
|
info(colors.green(` Inferred schema for ${runnableId}`));
|
|
@@ -68586,7 +69337,7 @@ async function inferAllInlineSchemas(appFolder, defaultTs = "bun") {
|
|
|
68586
69337
|
return schemas;
|
|
68587
69338
|
}
|
|
68588
69339
|
function getAppFolders(elems, extension) {
|
|
68589
|
-
return Object.keys(elems).filter((p) => p.endsWith(
|
|
69340
|
+
return Object.keys(elems).filter((p) => p.endsWith(SEP12 + extension)).map((p) => p.substring(0, p.length - (SEP12 + extension).length));
|
|
68590
69341
|
}
|
|
68591
69342
|
async function generateLocksCommand(opts, appPath) {
|
|
68592
69343
|
const { generateAppLocksInternal: generateAppLocksInternal2 } = await init_app_metadata().then(() => exports_app_metadata);
|
|
@@ -68604,7 +69355,7 @@ async function generateLocksCommand(opts, appPath) {
|
|
|
68604
69355
|
} else {
|
|
68605
69356
|
const ignore = await ignoreF2(opts);
|
|
68606
69357
|
const elems = await elementsToMap2(await FSFSElement2(process.cwd(), [], true), (p, isD) => {
|
|
68607
|
-
return ignore(p, isD) || !isD && !p.endsWith(
|
|
69358
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP12 + "raw_app.yaml") && !p.endsWith(SEP12 + "app.yaml");
|
|
68608
69359
|
}, false, {});
|
|
68609
69360
|
const rawAppFolders = getAppFolders(elems, "raw_app.yaml");
|
|
68610
69361
|
const appFolders = getAppFolders(elems, "app.yaml");
|
|
@@ -68846,7 +69597,7 @@ async function generateAgents(opts, appFolder) {
|
|
|
68846
69597
|
await requireLogin(opts);
|
|
68847
69598
|
await regenerateAgentDocs(workspace.workspaceId, targetDir);
|
|
68848
69599
|
}
|
|
68849
|
-
var
|
|
69600
|
+
var command9, generate_agents_default;
|
|
68850
69601
|
var init_generate_agents = __esm(async () => {
|
|
68851
69602
|
init_mod3();
|
|
68852
69603
|
init_colors2();
|
|
@@ -68859,12 +69610,12 @@ var init_generate_agents = __esm(async () => {
|
|
|
68859
69610
|
init_sync(),
|
|
68860
69611
|
init_resource_folders()
|
|
68861
69612
|
]);
|
|
68862
|
-
|
|
68863
|
-
generate_agents_default =
|
|
69613
|
+
command9 = new Command().description("regenerate AGENTS.md and DATATABLES.md from remote workspace").arguments("[app_folder:string]").action(generateAgents);
|
|
69614
|
+
generate_agents_default = command9;
|
|
68864
69615
|
});
|
|
68865
69616
|
|
|
68866
69617
|
// src/commands/app/dev.ts
|
|
68867
|
-
import { sep as
|
|
69618
|
+
import { sep as SEP13 } from "node:path";
|
|
68868
69619
|
import * as http2 from "node:http";
|
|
68869
69620
|
import * as fs11 from "node:fs";
|
|
68870
69621
|
import * as path16 from "node:path";
|
|
@@ -69555,7 +70306,7 @@ async function loadRunnables() {
|
|
|
69555
70306
|
runnables = rawApp?.runnables ?? {};
|
|
69556
70307
|
}
|
|
69557
70308
|
convertRunnablesToApiFormat(runnables);
|
|
69558
|
-
replaceInlineScripts2(runnables, backendPath +
|
|
70309
|
+
replaceInlineScripts2(runnables, backendPath + SEP13, true);
|
|
69559
70310
|
repopulateFields(runnables);
|
|
69560
70311
|
return runnables;
|
|
69561
70312
|
} catch (error2) {
|
|
@@ -70007,7 +70758,7 @@ var DEFAULT_PORT = 4000, DEFAULT_HOST = "localhost", createHTML = (jsPath, cssPa
|
|
|
70007
70758
|
</script>
|
|
70008
70759
|
</body>
|
|
70009
70760
|
</html>
|
|
70010
|
-
`,
|
|
70761
|
+
`, command10, dev_default, ITERATIONS_BEFORE_SLOW_REFRESH = 10, ITERATIONS_BEFORE_SUPER_SLOW_REFRESH = 100, QUEUE_LOG_INTERVAL_MS2 = 5000;
|
|
70011
70762
|
var init_dev = __esm(async () => {
|
|
70012
70763
|
init_mod3();
|
|
70013
70764
|
init_colors2();
|
|
@@ -70032,10 +70783,10 @@ var init_dev = __esm(async () => {
|
|
|
70032
70783
|
init_generate_agents(),
|
|
70033
70784
|
init_resource_folders()
|
|
70034
70785
|
]);
|
|
70035
|
-
|
|
70786
|
+
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
70787
|
default: DEFAULT_HOST
|
|
70037
70788
|
}).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 =
|
|
70789
|
+
dev_default = command10;
|
|
70039
70790
|
});
|
|
70040
70791
|
|
|
70041
70792
|
// src/commands/app/lint.ts
|
|
@@ -70164,7 +70915,7 @@ async function lint2(opts, appFolder) {
|
|
|
70164
70915
|
✅ All checks passed
|
|
70165
70916
|
`));
|
|
70166
70917
|
}
|
|
70167
|
-
var
|
|
70918
|
+
var command11, lint_default2;
|
|
70168
70919
|
var init_lint2 = __esm(async () => {
|
|
70169
70920
|
init_mod3();
|
|
70170
70921
|
init_colors2();
|
|
@@ -70176,8 +70927,8 @@ var init_lint2 = __esm(async () => {
|
|
|
70176
70927
|
init_raw_apps(),
|
|
70177
70928
|
init_resource_folders()
|
|
70178
70929
|
]);
|
|
70179
|
-
|
|
70180
|
-
lint_default2 =
|
|
70930
|
+
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);
|
|
70931
|
+
lint_default2 = command11;
|
|
70181
70932
|
});
|
|
70182
70933
|
|
|
70183
70934
|
// src/commands/app/new.ts
|
|
@@ -70713,7 +71464,7 @@ createApp(App).mount('#root')`, indexCss = `body {
|
|
|
70713
71464
|
.myclass {
|
|
70714
71465
|
border: 1px solid gray;
|
|
70715
71466
|
padding: 2px;
|
|
70716
|
-
}`, templates,
|
|
71467
|
+
}`, templates, command12, new_default;
|
|
70717
71468
|
var init_new = __esm(async () => {
|
|
70718
71469
|
init_mod3();
|
|
70719
71470
|
init_colors2();
|
|
@@ -70798,12 +71549,12 @@ var init_new = __esm(async () => {
|
|
|
70798
71549
|
}
|
|
70799
71550
|
}
|
|
70800
71551
|
};
|
|
70801
|
-
|
|
70802
|
-
new_default =
|
|
71552
|
+
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);
|
|
71553
|
+
new_default = command12;
|
|
70803
71554
|
});
|
|
70804
71555
|
|
|
70805
71556
|
// src/commands/app/app.ts
|
|
70806
|
-
import { sep as
|
|
71557
|
+
import { sep as SEP14 } from "node:path";
|
|
70807
71558
|
import { stat as stat10 } from "node:fs/promises";
|
|
70808
71559
|
function respecializeFields(fields) {
|
|
70809
71560
|
Object.entries(fields).forEach(([k, v]) => {
|
|
@@ -70877,7 +71628,7 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
|
|
|
70877
71628
|
return;
|
|
70878
71629
|
}
|
|
70879
71630
|
alreadySynced2.push(localPath);
|
|
70880
|
-
remotePath = remotePath.replaceAll(
|
|
71631
|
+
remotePath = remotePath.replaceAll(SEP14, "/");
|
|
70881
71632
|
let app = undefined;
|
|
70882
71633
|
try {
|
|
70883
71634
|
app = await getAppByPath({
|
|
@@ -70897,8 +71648,8 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
|
|
|
70897
71648
|
if (app) {
|
|
70898
71649
|
app.policy = undefined;
|
|
70899
71650
|
}
|
|
70900
|
-
if (!localPath.endsWith(
|
|
70901
|
-
localPath +=
|
|
71651
|
+
if (!localPath.endsWith(SEP14)) {
|
|
71652
|
+
localPath += SEP14;
|
|
70902
71653
|
}
|
|
70903
71654
|
const path19 = localPath + "app.yaml";
|
|
70904
71655
|
const localApp = await yamlParseFile(path19);
|
|
@@ -70999,12 +71750,12 @@ async function push5(opts, filePath, remotePath) {
|
|
|
70999
71750
|
}
|
|
71000
71751
|
const workspace = await resolveWorkspace(opts);
|
|
71001
71752
|
await requireLogin(opts);
|
|
71002
|
-
const normalizedPath = filePath.endsWith(
|
|
71753
|
+
const normalizedPath = filePath.endsWith(SEP14) ? filePath.slice(0, -1) : filePath;
|
|
71003
71754
|
const isRawApp = normalizedPath.endsWith("__raw_app") || normalizedPath.endsWith(".raw_app");
|
|
71004
71755
|
let hasRawAppYaml = false;
|
|
71005
71756
|
if (!isRawApp) {
|
|
71006
71757
|
try {
|
|
71007
|
-
const rawAppPath = (filePath.endsWith(
|
|
71758
|
+
const rawAppPath = (filePath.endsWith(SEP14) ? filePath : filePath + SEP14) + "raw_app.yaml";
|
|
71008
71759
|
await stat10(rawAppPath);
|
|
71009
71760
|
hasRawAppYaml = true;
|
|
71010
71761
|
} catch {}
|
|
@@ -71018,7 +71769,7 @@ async function push5(opts, filePath, remotePath) {
|
|
|
71018
71769
|
info(colors.bold.underline.green("App pushed"));
|
|
71019
71770
|
}
|
|
71020
71771
|
}
|
|
71021
|
-
var alreadySynced2,
|
|
71772
|
+
var alreadySynced2, command13, app_default;
|
|
71022
71773
|
var init_app = __esm(async () => {
|
|
71023
71774
|
init_mod3();
|
|
71024
71775
|
init_mod6();
|
|
@@ -71039,7 +71790,7 @@ var init_app = __esm(async () => {
|
|
|
71039
71790
|
init_generate_agents()
|
|
71040
71791
|
]);
|
|
71041
71792
|
alreadySynced2 = [];
|
|
71042
|
-
|
|
71793
|
+
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
71794
|
warn(colors.yellow('This command is deprecated. Use "wmill generate-metadata" instead.'));
|
|
71044
71795
|
const { generateLocksCommand: generateLocksCommand2 } = await init_app_metadata().then(() => exports_app_metadata);
|
|
71045
71796
|
await generateLocksCommand2(opts, appFolder);
|
|
@@ -71069,12 +71820,12 @@ var init_app = __esm(async () => {
|
|
|
71069
71820
|
});
|
|
71070
71821
|
info(colors.green(`Updated permissioned_as for app ${appPath} to ${email}`));
|
|
71071
71822
|
});
|
|
71072
|
-
app_default =
|
|
71823
|
+
app_default = command13;
|
|
71073
71824
|
});
|
|
71074
71825
|
|
|
71075
71826
|
// src/commands/folder/folder.ts
|
|
71076
71827
|
import { stat as stat11, readdir as readdir8, writeFile as writeFile11, mkdir as mkdir8 } from "node:fs/promises";
|
|
71077
|
-
import { sep as
|
|
71828
|
+
import { sep as SEP15 } from "node:path";
|
|
71078
71829
|
async function list7(opts) {
|
|
71079
71830
|
if (opts.json)
|
|
71080
71831
|
setSilent(true);
|
|
@@ -71094,8 +71845,8 @@ async function list7(opts) {
|
|
|
71094
71845
|
}
|
|
71095
71846
|
}
|
|
71096
71847
|
async function newFolder(opts, name) {
|
|
71097
|
-
const dirPath = `f${
|
|
71098
|
-
const filePath = `${dirPath}${
|
|
71848
|
+
const dirPath = `f${SEP15}${name}`;
|
|
71849
|
+
const filePath = `${dirPath}${SEP15}folder.meta.yaml`;
|
|
71099
71850
|
try {
|
|
71100
71851
|
await stat11(filePath);
|
|
71101
71852
|
throw new Error("File already exists: " + filePath);
|
|
@@ -71133,13 +71884,13 @@ async function get5(opts, name) {
|
|
|
71133
71884
|
}
|
|
71134
71885
|
}
|
|
71135
71886
|
async function pushFolder(workspace, name, folder, localFolder) {
|
|
71136
|
-
if (name.startsWith(
|
|
71887
|
+
if (name.startsWith(SEP15)) {
|
|
71137
71888
|
name = name.substring(1);
|
|
71138
71889
|
}
|
|
71139
|
-
if (name.startsWith("f" +
|
|
71890
|
+
if (name.startsWith("f" + SEP15)) {
|
|
71140
71891
|
name = name.substring(2);
|
|
71141
71892
|
}
|
|
71142
|
-
name = name.split(
|
|
71893
|
+
name = name.split(SEP15)[0];
|
|
71143
71894
|
debug(`Processing local folder ${name}`);
|
|
71144
71895
|
try {
|
|
71145
71896
|
folder = await getFolder({ workspace, name });
|
|
@@ -71183,7 +71934,7 @@ async function pushFolder(workspace, name, folder, localFolder) {
|
|
|
71183
71934
|
async function push6(opts, name) {
|
|
71184
71935
|
const workspace = await resolveWorkspace(opts);
|
|
71185
71936
|
await requireLogin(opts);
|
|
71186
|
-
const metaPath = `f${
|
|
71937
|
+
const metaPath = `f${SEP15}${name}${SEP15}folder.meta.yaml`;
|
|
71187
71938
|
try {
|
|
71188
71939
|
await stat11(metaPath);
|
|
71189
71940
|
} catch {
|
|
@@ -71206,7 +71957,7 @@ async function addMissing(opts) {
|
|
|
71206
71957
|
for (const entry of entries) {
|
|
71207
71958
|
if (!entry.isDirectory())
|
|
71208
71959
|
continue;
|
|
71209
|
-
const metaPath = `${fDir}${
|
|
71960
|
+
const metaPath = `${fDir}${SEP15}${entry.name}${SEP15}folder.meta.yaml`;
|
|
71210
71961
|
try {
|
|
71211
71962
|
await stat11(metaPath);
|
|
71212
71963
|
} catch {
|
|
@@ -71233,7 +71984,7 @@ async function addMissing(opts) {
|
|
|
71233
71984
|
info(`
|
|
71234
71985
|
Created ${missing.length} folder.meta.yaml file(s). You can now run 'wmill sync push' to push them.`);
|
|
71235
71986
|
}
|
|
71236
|
-
var import_yaml24,
|
|
71987
|
+
var import_yaml24, command14, folder_default;
|
|
71237
71988
|
var init_folder = __esm(async () => {
|
|
71238
71989
|
init_colors2();
|
|
71239
71990
|
init_mod3();
|
|
@@ -71247,7 +71998,7 @@ var init_folder = __esm(async () => {
|
|
|
71247
71998
|
init_types()
|
|
71248
71999
|
]);
|
|
71249
72000
|
import_yaml24 = __toESM(require_dist(), 1);
|
|
71250
|
-
|
|
72001
|
+
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
72002
|
const workspace = await resolveWorkspace(opts);
|
|
71252
72003
|
await requireLogin(opts);
|
|
71253
72004
|
const folder = await getFolder({
|
|
@@ -71295,13 +72046,13 @@ var init_folder = __esm(async () => {
|
|
|
71295
72046
|
info(colors.yellow(`No rule matches path '${testPath}' (relative: '${relative7}')`));
|
|
71296
72047
|
}
|
|
71297
72048
|
});
|
|
71298
|
-
folder_default =
|
|
72049
|
+
folder_default = command14;
|
|
71299
72050
|
});
|
|
71300
72051
|
|
|
71301
72052
|
// src/commands/variable/variable.ts
|
|
71302
72053
|
import { mkdir as mkdir9, stat as stat12, writeFile as writeFile12 } from "node:fs/promises";
|
|
71303
72054
|
import { dirname as dirname14 } from "node:path";
|
|
71304
|
-
import { sep as
|
|
72055
|
+
import { sep as SEP16 } from "node:path";
|
|
71305
72056
|
async function list8(opts) {
|
|
71306
72057
|
if (opts.json)
|
|
71307
72058
|
setSilent(true);
|
|
@@ -71370,7 +72121,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71370
72121
|
try {
|
|
71371
72122
|
variable = await getVariable({
|
|
71372
72123
|
workspace,
|
|
71373
|
-
path: remotePath.replaceAll(
|
|
72124
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71374
72125
|
decryptSecret: plainSecrets,
|
|
71375
72126
|
includeEncrypted: true
|
|
71376
72127
|
});
|
|
@@ -71386,7 +72137,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71386
72137
|
debug(`Variable ${remotePath} is not up-to-date, updating`);
|
|
71387
72138
|
await updateVariable({
|
|
71388
72139
|
workspace,
|
|
71389
|
-
path: remotePath.replaceAll(
|
|
72140
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71390
72141
|
alreadyEncrypted: !plainSecrets,
|
|
71391
72142
|
requestBody: {
|
|
71392
72143
|
...localVariable,
|
|
@@ -71399,7 +72150,7 @@ async function pushVariable(workspace, remotePath, variable, localVariable, plai
|
|
|
71399
72150
|
workspace,
|
|
71400
72151
|
alreadyEncrypted: !plainSecrets,
|
|
71401
72152
|
requestBody: {
|
|
71402
|
-
path: remotePath.replaceAll(
|
|
72153
|
+
path: remotePath.replaceAll(SEP16, "/"),
|
|
71403
72154
|
...localVariable
|
|
71404
72155
|
}
|
|
71405
72156
|
});
|
|
@@ -71445,7 +72196,7 @@ async function add2(opts, value, remotePath) {
|
|
|
71445
72196
|
}, true);
|
|
71446
72197
|
info(colors.bold.underline.green(`Variable ${remotePath} pushed`));
|
|
71447
72198
|
}
|
|
71448
|
-
var import_yaml25,
|
|
72199
|
+
var import_yaml25, command15, variable_default;
|
|
71449
72200
|
var init_variable = __esm(async () => {
|
|
71450
72201
|
init_mod3();
|
|
71451
72202
|
init_mod6();
|
|
@@ -71459,14 +72210,14 @@ var init_variable = __esm(async () => {
|
|
|
71459
72210
|
init_confirm()
|
|
71460
72211
|
]);
|
|
71461
72212
|
import_yaml25 = __toESM(require_dist(), 1);
|
|
71462
|
-
|
|
71463
|
-
variable_default =
|
|
72213
|
+
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);
|
|
72214
|
+
variable_default = command15;
|
|
71464
72215
|
});
|
|
71465
72216
|
|
|
71466
72217
|
// src/commands/schedule/schedule.ts
|
|
71467
72218
|
import { mkdir as mkdir10, stat as stat13, writeFile as writeFile13 } from "node:fs/promises";
|
|
71468
72219
|
import { dirname as dirname15 } from "node:path";
|
|
71469
|
-
import { sep as
|
|
72220
|
+
import { sep as SEP17 } from "node:path";
|
|
71470
72221
|
async function list9(opts) {
|
|
71471
72222
|
if (opts.json)
|
|
71472
72223
|
setSilent(true);
|
|
@@ -71530,7 +72281,7 @@ async function get7(opts, path19) {
|
|
|
71530
72281
|
}
|
|
71531
72282
|
}
|
|
71532
72283
|
async function pushSchedule(workspace, path19, schedule, localSchedule, permissionedAsContext) {
|
|
71533
|
-
path19 = removeType(path19, "schedule").replaceAll(
|
|
72284
|
+
path19 = removeType(path19, "schedule").replaceAll(SEP17, "/");
|
|
71534
72285
|
debug(`Processing local schedule ${path19}`);
|
|
71535
72286
|
try {
|
|
71536
72287
|
schedule = await getSchedule({ workspace, path: path19 });
|
|
@@ -71632,7 +72383,7 @@ async function push8(opts, filePath, remotePath) {
|
|
|
71632
72383
|
await pushSchedule(workspace.workspaceId, remotePath, undefined, parseFromFile(filePath));
|
|
71633
72384
|
console.log(colors.bold.underline.green("Schedule pushed"));
|
|
71634
72385
|
}
|
|
71635
|
-
var import_yaml26,
|
|
72386
|
+
var import_yaml26, command16, schedule_default;
|
|
71636
72387
|
var init_schedule = __esm(async () => {
|
|
71637
72388
|
init_mod3();
|
|
71638
72389
|
init_mod6();
|
|
@@ -71647,7 +72398,7 @@ var init_schedule = __esm(async () => {
|
|
|
71647
72398
|
init_types()
|
|
71648
72399
|
]);
|
|
71649
72400
|
import_yaml26 = __toESM(require_dist(), 1);
|
|
71650
|
-
|
|
72401
|
+
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").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
72402
|
const workspace = await resolveWorkspace(opts);
|
|
71652
72403
|
await requireLogin(opts);
|
|
71653
72404
|
const cache3 = new Map;
|
|
@@ -71669,7 +72420,7 @@ var init_schedule = __esm(async () => {
|
|
|
71669
72420
|
});
|
|
71670
72421
|
info(colors.green(`Updated permissioned_as for schedule ${schedulePath} to ${email} (username: ${username})`));
|
|
71671
72422
|
});
|
|
71672
|
-
schedule_default =
|
|
72423
|
+
schedule_default = command16;
|
|
71673
72424
|
});
|
|
71674
72425
|
|
|
71675
72426
|
// src/commands/instance/slack.ts
|
|
@@ -72763,7 +73514,7 @@ async function whoami3(opts) {
|
|
|
72763
73514
|
error(colors.red(`Failed to retrieve whoami information: ${error2.message}`));
|
|
72764
73515
|
}
|
|
72765
73516
|
}
|
|
72766
|
-
var import_yaml29,
|
|
73517
|
+
var import_yaml29, command17, instance_default;
|
|
72767
73518
|
var init_instance = __esm(async () => {
|
|
72768
73519
|
init_colors2();
|
|
72769
73520
|
init_mod3();
|
|
@@ -72788,7 +73539,7 @@ var init_instance = __esm(async () => {
|
|
|
72788
73539
|
init_workspace()
|
|
72789
73540
|
]);
|
|
72790
73541
|
import_yaml29 = __toESM(require_dist(), 1);
|
|
72791
|
-
|
|
73542
|
+
command17 = new Command().description("sync local with a remote instance or the opposite (push or pull)").action(async () => {
|
|
72792
73543
|
info("4 actions available, add, remove, switch, pull and push. Use -h to display help.");
|
|
72793
73544
|
const activeInstance = await getActiveInstance({});
|
|
72794
73545
|
new Table2().header(["name", "remote", "token"]).padding(2).border(true).body((await allInstances()).map((x) => [
|
|
@@ -72814,7 +73565,7 @@ var init_instance = __esm(async () => {
|
|
|
72814
73565
|
await removeInstance(choice);
|
|
72815
73566
|
info(colors.green.underline(`Removed instance ${choice}`));
|
|
72816
73567
|
}).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 =
|
|
73568
|
+
instance_default = command17;
|
|
72818
73569
|
});
|
|
72819
73570
|
|
|
72820
73571
|
// src/commands/user/user.ts
|
|
@@ -73169,7 +73920,7 @@ async function pushInstanceGroups(opts, preview2 = false) {
|
|
|
73169
73920
|
info(colors.green("Groups pushed to the instance"));
|
|
73170
73921
|
}
|
|
73171
73922
|
}
|
|
73172
|
-
var import_yaml31, INSTANCE_USERS_PATH = "instance_users.yaml", instanceUsersPath, INSTANCE_GROUPS_PATH = "instance_groups.yaml", instanceGroupsPath,
|
|
73923
|
+
var import_yaml31, INSTANCE_USERS_PATH = "instance_users.yaml", instanceUsersPath, INSTANCE_GROUPS_PATH = "instance_groups.yaml", instanceGroupsPath, command18, user_default;
|
|
73173
73924
|
var init_user = __esm(async () => {
|
|
73174
73925
|
init_colors2();
|
|
73175
73926
|
init_mod3();
|
|
@@ -73185,12 +73936,12 @@ var init_user = __esm(async () => {
|
|
|
73185
73936
|
import_yaml31 = __toESM(require_dist(), 1);
|
|
73186
73937
|
instanceUsersPath = INSTANCE_USERS_PATH;
|
|
73187
73938
|
instanceGroupsPath = INSTANCE_GROUPS_PATH;
|
|
73188
|
-
|
|
73939
|
+
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
73940
|
depends: ["password"]
|
|
73190
73941
|
}).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
73942
|
depends: ["email"]
|
|
73192
73943
|
}).action(createToken2);
|
|
73193
|
-
user_default =
|
|
73944
|
+
user_default = command18;
|
|
73194
73945
|
});
|
|
73195
73946
|
|
|
73196
73947
|
// src/commands/dependencies/dependencies.ts
|
|
@@ -73239,7 +73990,7 @@ async function pushWorkspaceDependencies(workspace, path20, _befObj, newDependen
|
|
|
73239
73990
|
});
|
|
73240
73991
|
info(colors.green(`Successfully pushed ${displayName} for ${language}`));
|
|
73241
73992
|
}
|
|
73242
|
-
var
|
|
73993
|
+
var command19, dependencies_default;
|
|
73243
73994
|
var init_dependencies = __esm(async () => {
|
|
73244
73995
|
init_colors2();
|
|
73245
73996
|
init_mod3();
|
|
@@ -73251,14 +74002,14 @@ var init_dependencies = __esm(async () => {
|
|
|
73251
74002
|
init_metadata(),
|
|
73252
74003
|
init_utils()
|
|
73253
74004
|
]);
|
|
73254
|
-
|
|
73255
|
-
dependencies_default =
|
|
74005
|
+
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);
|
|
74006
|
+
dependencies_default = command19;
|
|
73256
74007
|
});
|
|
73257
74008
|
|
|
73258
74009
|
// src/commands/trigger/trigger.ts
|
|
73259
74010
|
import { mkdir as mkdir12, stat as stat15, writeFile as writeFile17 } from "node:fs/promises";
|
|
73260
74011
|
import { dirname as dirname16 } from "node:path";
|
|
73261
|
-
import { sep as
|
|
74012
|
+
import { sep as SEP18 } from "node:path";
|
|
73262
74013
|
async function getTrigger(triggerType, workspace, path20) {
|
|
73263
74014
|
const triggerFunctions = {
|
|
73264
74015
|
http: getHttpTrigger,
|
|
@@ -73309,7 +74060,7 @@ async function createTrigger(triggerType, workspace, path20, trigger) {
|
|
|
73309
74060
|
await triggerFunction({ workspace, path: path20, requestBody: trigger });
|
|
73310
74061
|
}
|
|
73311
74062
|
async function pushTrigger(triggerType, workspace, path20, trigger, localTrigger, permissionedAsContext) {
|
|
73312
|
-
path20 = removeType(path20, triggerType + "_trigger").replaceAll(
|
|
74063
|
+
path20 = removeType(path20, triggerType + "_trigger").replaceAll(SEP18, "/");
|
|
73313
74064
|
debug(`Processing local ${triggerType} trigger ${path20}`);
|
|
73314
74065
|
try {
|
|
73315
74066
|
trigger = await getTrigger(triggerType, workspace, path20);
|
|
@@ -73615,7 +74366,7 @@ async function push10(opts, filePath, remotePath) {
|
|
|
73615
74366
|
await pushTrigger(triggerKind, workspace.workspaceId, remotePath, undefined, parseFromFile(filePath));
|
|
73616
74367
|
console.log(colors.bold.underline.green("Trigger pushed"));
|
|
73617
74368
|
}
|
|
73618
|
-
var import_yaml33, triggerTemplates, TRIGGER_SKIP_FIELDS,
|
|
74369
|
+
var import_yaml33, triggerTemplates, TRIGGER_SKIP_FIELDS, command20, trigger_default;
|
|
73619
74370
|
var init_trigger = __esm(async () => {
|
|
73620
74371
|
init_services_gen();
|
|
73621
74372
|
init_mod3();
|
|
@@ -73721,7 +74472,7 @@ var init_trigger = __esm(async () => {
|
|
|
73721
74472
|
}
|
|
73722
74473
|
};
|
|
73723
74474
|
TRIGGER_SKIP_FIELDS = new Set(["workspace_id", "extra_perms", "edited_by", "edited_at"]);
|
|
73724
|
-
|
|
74475
|
+
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
74476
|
const workspace = await resolveWorkspace(opts);
|
|
73726
74477
|
await requireLogin(opts);
|
|
73727
74478
|
if (!opts.kind) {
|
|
@@ -73744,12 +74495,12 @@ var init_trigger = __esm(async () => {
|
|
|
73744
74495
|
});
|
|
73745
74496
|
info(colors.green(`Updated permissioned_as for ${opts.kind} trigger ${triggerPath} to ${email} (username: ${username})`));
|
|
73746
74497
|
});
|
|
73747
|
-
trigger_default =
|
|
74498
|
+
trigger_default = command20;
|
|
73748
74499
|
});
|
|
73749
74500
|
|
|
73750
74501
|
// src/types.ts
|
|
73751
74502
|
import * as path20 from "node:path";
|
|
73752
|
-
import { sep as
|
|
74503
|
+
import { sep as SEP19 } from "node:path";
|
|
73753
74504
|
function isSuperset(subset, superset) {
|
|
73754
74505
|
return Object.keys(subset).every((key) => {
|
|
73755
74506
|
const eq = deepEqual(subset[key], superset[key]);
|
|
@@ -73893,7 +74644,7 @@ function getTypeStrFromPath(p) {
|
|
|
73893
74644
|
if (isRawAppPath(p)) {
|
|
73894
74645
|
return "raw_app";
|
|
73895
74646
|
}
|
|
73896
|
-
if (p.startsWith("dependencies" +
|
|
74647
|
+
if (p.startsWith("dependencies" + SEP19)) {
|
|
73897
74648
|
return "workspace_dependencies";
|
|
73898
74649
|
}
|
|
73899
74650
|
if (isFileResource(p) || isFilesetResource(p)) {
|
|
@@ -73923,7 +74674,7 @@ function getTypeStrFromPath(p) {
|
|
|
73923
74674
|
}
|
|
73924
74675
|
}
|
|
73925
74676
|
function removeType(str, type) {
|
|
73926
|
-
const normalizedStr = path20.normalize(str).replaceAll(
|
|
74677
|
+
const normalizedStr = path20.normalize(str).replaceAll(SEP19, "/");
|
|
73927
74678
|
if (normalizedStr.endsWith("." + type + ".yaml") || normalizedStr.endsWith("." + type + ".json")) {
|
|
73928
74679
|
return normalizedStr.slice(0, normalizedStr.length - type.length - 6);
|
|
73929
74680
|
}
|
|
@@ -73933,7 +74684,7 @@ function removeType(str, type) {
|
|
|
73933
74684
|
return normalizedStr;
|
|
73934
74685
|
}
|
|
73935
74686
|
function extractNativeTriggerInfo(p) {
|
|
73936
|
-
const normalizedPath = path20.normalize(p).replaceAll(
|
|
74687
|
+
const normalizedPath = path20.normalize(p).replaceAll(SEP19, "/");
|
|
73937
74688
|
const withoutExt = normalizedPath.replace(/\.(json|yaml)$/, "");
|
|
73938
74689
|
const match2 = withoutExt.match(/^(.+)\.(flow|script)\.([^.]+)\.(\w+)_native_trigger$/);
|
|
73939
74690
|
if (!match2) {
|
|
@@ -73947,8 +74698,8 @@ function extractNativeTriggerInfo(p) {
|
|
|
73947
74698
|
};
|
|
73948
74699
|
}
|
|
73949
74700
|
function removePathPrefix(str, prefix) {
|
|
73950
|
-
const normalizedStr = path20.normalize(str).replaceAll(
|
|
73951
|
-
const normalizedPrefix = path20.normalize(prefix).replaceAll(
|
|
74701
|
+
const normalizedStr = path20.normalize(str).replaceAll(SEP19, "/");
|
|
74702
|
+
const normalizedPrefix = path20.normalize(prefix).replaceAll(SEP19, "/");
|
|
73952
74703
|
if (normalizedStr === normalizedPrefix) {
|
|
73953
74704
|
return "";
|
|
73954
74705
|
}
|
|
@@ -74120,7 +74871,7 @@ var init_local_path_scripts = __esm(async () => {
|
|
|
74120
74871
|
});
|
|
74121
74872
|
|
|
74122
74873
|
// src/commands/flow/flow.ts
|
|
74123
|
-
import { sep as
|
|
74874
|
+
import { sep as SEP20 } from "node:path";
|
|
74124
74875
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
74125
74876
|
function normalizeOptionalString(value) {
|
|
74126
74877
|
return typeof value === "string" && value.trim() === "" ? undefined : value ?? undefined;
|
|
@@ -74181,7 +74932,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74181
74932
|
return;
|
|
74182
74933
|
}
|
|
74183
74934
|
alreadySynced3.push(localPath);
|
|
74184
|
-
remotePath = remotePath.replaceAll(
|
|
74935
|
+
remotePath = remotePath.replaceAll(SEP20, "/");
|
|
74185
74936
|
let flow = undefined;
|
|
74186
74937
|
try {
|
|
74187
74938
|
flow = await getFlowByPath({
|
|
@@ -74189,18 +74940,18 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74189
74940
|
path: remotePath
|
|
74190
74941
|
});
|
|
74191
74942
|
} catch {}
|
|
74192
|
-
if (!localPath.endsWith(
|
|
74193
|
-
localPath +=
|
|
74943
|
+
if (!localPath.endsWith(SEP20)) {
|
|
74944
|
+
localPath += SEP20;
|
|
74194
74945
|
}
|
|
74195
74946
|
const localFlow = await yamlParseFile(localPath + "flow.yaml");
|
|
74196
74947
|
const fileReader = async (path21) => await readTextFile(localPath + path21);
|
|
74197
74948
|
const missingFiles = [];
|
|
74198
|
-
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath,
|
|
74949
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74199
74950
|
if (localFlow.value.failure_module) {
|
|
74200
|
-
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath,
|
|
74951
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74201
74952
|
}
|
|
74202
74953
|
if (localFlow.value.preprocessor_module) {
|
|
74203
|
-
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, localPath,
|
|
74954
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, localPath, SEP20, undefined, missingFiles);
|
|
74204
74955
|
}
|
|
74205
74956
|
if (missingFiles.length > 0) {
|
|
74206
74957
|
warn(colors.yellow(`Warning: missing inline script file(s): ${missingFiles.join(", ")}. ` + `The flow will be pushed with unresolved !inline references.`));
|
|
@@ -74223,9 +74974,9 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74223
74974
|
info(colors.bold.yellow(`Updating flow ${remotePath}...`));
|
|
74224
74975
|
await updateFlow({
|
|
74225
74976
|
workspace,
|
|
74226
|
-
path: remotePath.replaceAll(
|
|
74977
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74227
74978
|
requestBody: {
|
|
74228
|
-
path: remotePath.replaceAll(
|
|
74979
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74229
74980
|
deployment_message: message,
|
|
74230
74981
|
...localFlow,
|
|
74231
74982
|
...preserveFields
|
|
@@ -74237,7 +74988,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
|
|
|
74237
74988
|
await createFlow({
|
|
74238
74989
|
workspace,
|
|
74239
74990
|
requestBody: {
|
|
74240
|
-
path: remotePath.replaceAll(
|
|
74991
|
+
path: remotePath.replaceAll(SEP20, "/"),
|
|
74241
74992
|
deployment_message: message,
|
|
74242
74993
|
...localFlow,
|
|
74243
74994
|
...preserveFields
|
|
@@ -74486,25 +75237,25 @@ async function preview2(opts, flowPath) {
|
|
|
74486
75237
|
const workspace = await resolveWorkspace(opts);
|
|
74487
75238
|
await requireLogin(opts);
|
|
74488
75239
|
const codebases = useLocalPathScripts ? listSyncCodebases(opts) : [];
|
|
74489
|
-
const isFlowDir = flowPath.endsWith(".flow") || flowPath.endsWith(".flow" +
|
|
75240
|
+
const isFlowDir = flowPath.endsWith(".flow") || flowPath.endsWith(".flow" + SEP20) || flowPath.endsWith("__flow") || flowPath.endsWith("__flow" + SEP20);
|
|
74490
75241
|
if (!isFlowDir) {
|
|
74491
75242
|
if (flowPath.endsWith("flow.yaml") || flowPath.endsWith("flow.json")) {
|
|
74492
|
-
flowPath = flowPath.substring(0, flowPath.lastIndexOf(
|
|
75243
|
+
flowPath = flowPath.substring(0, flowPath.lastIndexOf(SEP20));
|
|
74493
75244
|
} else {
|
|
74494
75245
|
throw new Error("Flow path must be a .flow/__flow directory or a flow.yaml file");
|
|
74495
75246
|
}
|
|
74496
75247
|
}
|
|
74497
|
-
if (!flowPath.endsWith(
|
|
74498
|
-
flowPath +=
|
|
75248
|
+
if (!flowPath.endsWith(SEP20)) {
|
|
75249
|
+
flowPath += SEP20;
|
|
74499
75250
|
}
|
|
74500
75251
|
const localFlow = await yamlParseFile(flowPath + "flow.yaml");
|
|
74501
75252
|
const fileReader = async (path21) => await readTextFile(flowPath + path21);
|
|
74502
|
-
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath,
|
|
75253
|
+
await replaceInlineScripts(localFlow.value.modules, fileReader, exports_log, flowPath, SEP20);
|
|
74503
75254
|
if (localFlow.value.failure_module) {
|
|
74504
|
-
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath,
|
|
75255
|
+
await replaceInlineScripts([localFlow.value.failure_module], fileReader, exports_log, flowPath, SEP20);
|
|
74505
75256
|
}
|
|
74506
75257
|
if (localFlow.value.preprocessor_module) {
|
|
74507
|
-
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath,
|
|
75258
|
+
await replaceInlineScripts([localFlow.value.preprocessor_module], fileReader, exports_log, flowPath, SEP20);
|
|
74508
75259
|
}
|
|
74509
75260
|
if (useLocalPathScripts) {
|
|
74510
75261
|
const scriptPaths = collectPathScriptPaths(localFlow.value);
|
|
@@ -74534,7 +75285,7 @@ async function preview2(opts, flowPath) {
|
|
|
74534
75285
|
workspace: workspace.workspaceId,
|
|
74535
75286
|
requestBody: {
|
|
74536
75287
|
value: localFlow.value,
|
|
74537
|
-
path: flowPath.substring(0, flowPath.indexOf(".flow")).replaceAll(
|
|
75288
|
+
path: flowPath.substring(0, flowPath.indexOf(".flow")).replaceAll(SEP20, "/"),
|
|
74538
75289
|
args: input
|
|
74539
75290
|
}
|
|
74540
75291
|
});
|
|
@@ -74566,8 +75317,8 @@ async function generateLocks(opts, folder) {
|
|
|
74566
75317
|
} else {
|
|
74567
75318
|
const ignore = await ignoreF(opts);
|
|
74568
75319
|
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(
|
|
75320
|
+
return ignore(p, isD) || !isD && !p.endsWith(SEP20 + "flow.yaml") && !p.endsWith(SEP20 + "flow.json");
|
|
75321
|
+
}, false, {})).map((x) => x.substring(0, x.lastIndexOf(SEP20)));
|
|
74571
75322
|
let hasAny = false;
|
|
74572
75323
|
for (const folder2 of elems) {
|
|
74573
75324
|
const candidate = await generateFlowLockInternal(folder2, true, workspace, opts);
|
|
@@ -74666,7 +75417,7 @@ async function showVersion(opts, flowPath, version) {
|
|
|
74666
75417
|
console.log(JSON.stringify(flow.value, null, 2));
|
|
74667
75418
|
}
|
|
74668
75419
|
}
|
|
74669
|
-
var import_yaml36, alreadySynced3,
|
|
75420
|
+
var import_yaml36, alreadySynced3, command21, flow_default;
|
|
74670
75421
|
var init_flow = __esm(async () => {
|
|
74671
75422
|
init_colors2();
|
|
74672
75423
|
init_mod3();
|
|
@@ -74691,7 +75442,7 @@ var init_flow = __esm(async () => {
|
|
|
74691
75442
|
]);
|
|
74692
75443
|
import_yaml36 = __toESM(require_dist(), 1);
|
|
74693
75444
|
alreadySynced3 = [];
|
|
74694
|
-
|
|
75445
|
+
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
75446
|
const workspace = await resolveWorkspace(opts);
|
|
74696
75447
|
await requireLogin(opts);
|
|
74697
75448
|
const remote = await getFlowByPath({
|
|
@@ -74712,7 +75463,7 @@ var init_flow = __esm(async () => {
|
|
|
74712
75463
|
});
|
|
74713
75464
|
info(colors.green(`Updated permissioned_as for flow ${flowPath} to ${email}`));
|
|
74714
75465
|
});
|
|
74715
|
-
flow_default =
|
|
75466
|
+
flow_default = command21;
|
|
74716
75467
|
});
|
|
74717
75468
|
|
|
74718
75469
|
// src/commands/gitsync-settings/converter.ts
|
|
@@ -75651,286 +76402,15 @@ __export(exports_gitsync_settings, {
|
|
|
75651
76402
|
pullGitSyncSettings: () => pullGitSyncSettings,
|
|
75652
76403
|
default: () => gitsync_settings_default
|
|
75653
76404
|
});
|
|
75654
|
-
var
|
|
76405
|
+
var command23, gitsync_settings_default;
|
|
75655
76406
|
var init_gitsync_settings = __esm(async () => {
|
|
75656
76407
|
init_mod3();
|
|
75657
76408
|
await __promiseAll([
|
|
75658
76409
|
init_pull2(),
|
|
75659
76410
|
init_push()
|
|
75660
76411
|
]);
|
|
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
|
-
]);
|
|
76412
|
+
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);
|
|
76413
|
+
gitsync_settings_default = command23;
|
|
75934
76414
|
});
|
|
75935
76415
|
|
|
75936
76416
|
// src/main.ts
|
|
@@ -77207,8 +77687,8 @@ async function pull2(opts) {
|
|
|
77207
77687
|
await pushResourceType(workspace.workspaceId, x.name + ".resource-type.json", undefined, x);
|
|
77208
77688
|
}
|
|
77209
77689
|
}
|
|
77210
|
-
var
|
|
77211
|
-
var hub_default =
|
|
77690
|
+
var command22 = new Command().name("hub").description("Hub related commands. EXPERIMENTAL. INTERNAL USE ONLY.").command("pull").description("pull any supported definitions. EXPERIMENTAL.").action(pull2);
|
|
77691
|
+
var hub_default = command22;
|
|
77212
77692
|
|
|
77213
77693
|
// src/main.ts
|
|
77214
77694
|
await __promiseAll([
|
|
@@ -77299,8 +77779,8 @@ async function pushWorkerGroups(opts) {
|
|
|
77299
77779
|
await pushInstanceConfigs(opts, false);
|
|
77300
77780
|
}
|
|
77301
77781
|
}
|
|
77302
|
-
var
|
|
77303
|
-
var worker_groups_default =
|
|
77782
|
+
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);
|
|
77783
|
+
var worker_groups_default = command24;
|
|
77304
77784
|
|
|
77305
77785
|
// src/main.ts
|
|
77306
77786
|
await init_lint();
|
|
@@ -77329,7 +77809,7 @@ await __promiseAll([
|
|
|
77329
77809
|
init_local_path_scripts()
|
|
77330
77810
|
]);
|
|
77331
77811
|
var import_yaml40 = __toESM(require_dist(), 1);
|
|
77332
|
-
import { sep as
|
|
77812
|
+
import { sep as SEP21 } from "node:path";
|
|
77333
77813
|
import * as http3 from "node:http";
|
|
77334
77814
|
import * as https from "node:https";
|
|
77335
77815
|
import { access, readdir as readdir10, realpath, stat as stat17, unlink, writeFile as writeFile19 } from "node:fs/promises";
|
|
@@ -77582,7 +78062,7 @@ async function dev2(opts) {
|
|
|
77582
78062
|
if (paths.length == 0) {
|
|
77583
78063
|
return;
|
|
77584
78064
|
}
|
|
77585
|
-
const nativePath = (await realpath(paths[0])).replace(base +
|
|
78065
|
+
const nativePath = (await realpath(paths[0])).replace(base + SEP21, "");
|
|
77586
78066
|
const cpath = nativePath.replaceAll("\\", "/");
|
|
77587
78067
|
const insideFlow = isInsideFlowFolder(cpath);
|
|
77588
78068
|
if (insideFlow || !ignore(nativePath, false)) {
|
|
@@ -77599,7 +78079,7 @@ async function dev2(opts) {
|
|
|
77599
78079
|
return;
|
|
77600
78080
|
const wmFlowPath = stripFolderSuffix(localPath.replace(/\/$/, ""), FLOW_SUFFIXES);
|
|
77601
78081
|
const localFlow = await yamlParseFile(localPath + "flow.yaml");
|
|
77602
|
-
await replaceInlineScripts(localFlow.value.modules, async (path22) => await readTextFile(localPath + path22), exports_log, localPath,
|
|
78082
|
+
await replaceInlineScripts(localFlow.value.modules, async (path22) => await readTextFile(localPath + path22), exports_log, localPath, SEP21, undefined);
|
|
77603
78083
|
snapshotPathScripts(localFlow.value);
|
|
77604
78084
|
const localScriptReader = createPreviewLocalScriptReader({
|
|
77605
78085
|
exts,
|
|
@@ -77652,7 +78132,7 @@ async function dev2(opts) {
|
|
|
77652
78132
|
if (!flowDir || !flowYaml)
|
|
77653
78133
|
throw new Error("not a flow");
|
|
77654
78134
|
const localFlow = await yamlParseFile(flowYaml);
|
|
77655
|
-
await replaceInlineScripts(localFlow.value.modules, async (p) => await readTextFile(flowDir + p), exports_log, flowDir,
|
|
78135
|
+
await replaceInlineScripts(localFlow.value.modules, async (p) => await readTextFile(flowDir + p), exports_log, flowDir, SEP21, undefined);
|
|
77656
78136
|
snapshotPathScripts(localFlow.value);
|
|
77657
78137
|
const localScriptReader = createPreviewLocalScriptReader({
|
|
77658
78138
|
exts,
|
|
@@ -77999,8 +78479,8 @@ async function dev2(opts) {
|
|
|
77999
78479
|
await Promise.all([startServer(), watchChanges()]);
|
|
78000
78480
|
console.log("Stopped dev mode");
|
|
78001
78481
|
}
|
|
78002
|
-
var
|
|
78003
|
-
var dev_default2 =
|
|
78482
|
+
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);
|
|
78483
|
+
var dev_default2 = command25;
|
|
78004
78484
|
|
|
78005
78485
|
// src/main.ts
|
|
78006
78486
|
init_gen();
|
|
@@ -78114,8 +78594,8 @@ Worker Group: ${group.groupName} (${group.workers.length} workers)`);
|
|
|
78114
78594
|
info("Use 'wmill instance add' to add a new instance");
|
|
78115
78595
|
}
|
|
78116
78596
|
}
|
|
78117
|
-
var
|
|
78118
|
-
var workers_default =
|
|
78597
|
+
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);
|
|
78598
|
+
var workers_default = command26;
|
|
78119
78599
|
|
|
78120
78600
|
// src/commands/queues/queues.ts
|
|
78121
78601
|
init_mod3();
|
|
@@ -78223,8 +78703,8 @@ async function displayQueues(opts, workspace) {
|
|
|
78223
78703
|
info("Use 'wmill instance add' to add a new instance");
|
|
78224
78704
|
}
|
|
78225
78705
|
}
|
|
78226
|
-
var
|
|
78227
|
-
var queues_default =
|
|
78706
|
+
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);
|
|
78707
|
+
var queues_default = command27;
|
|
78228
78708
|
|
|
78229
78709
|
// src/main.ts
|
|
78230
78710
|
await init_dependencies();
|
|
@@ -78276,7 +78756,7 @@ When a new app needs to be created, YOU run \`wmill app new\` yourself with \`--
|
|
|
78276
78756
|
|
|
78277
78757
|
## Triggers
|
|
78278
78758
|
|
|
78279
|
-
You MUST use the \`triggers\` skill to configure HTTP routes, WebSocket, Kafka, NATS, SQS, MQTT, GCP, or Postgres CDC triggers.
|
|
78759
|
+
You MUST use the \`triggers\` skill to configure HTTP routes, WebSocket, Kafka, NATS, SQS, MQTT, GCP, Azure, Email, or Postgres CDC triggers.
|
|
78280
78760
|
|
|
78281
78761
|
## Schedules
|
|
78282
78762
|
|
|
@@ -83871,6 +84351,49 @@ Examples:
|
|
|
83871
84351
|
- \`u/user/webhook.http_trigger.yaml\`
|
|
83872
84352
|
- \`f/data/kafka_consumer.kafka_trigger.yaml\`
|
|
83873
84353
|
- \`f/sync/postgres_cdc.postgres_trigger.yaml\`
|
|
84354
|
+
- \`f/inbound/orders.email_trigger.yaml\`
|
|
84355
|
+
|
|
84356
|
+
## Email Triggers
|
|
84357
|
+
|
|
84358
|
+
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.
|
|
84359
|
+
|
|
84360
|
+
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).
|
|
84361
|
+
|
|
84362
|
+
### Payload
|
|
84363
|
+
|
|
84364
|
+
The runnable receives:
|
|
84365
|
+
|
|
84366
|
+
- \`parsed_email\` — \`{ headers, text_body, html_body, attachments[] }\`. Each \`attachment\` has \`{ headers, body }\`.
|
|
84367
|
+
- \`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.
|
|
84368
|
+
- \`email_extra_args\` (optional, only when sender appended \`+key=value\` extras) — a flat object of the parsed extras.
|
|
84369
|
+
|
|
84370
|
+
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.
|
|
84371
|
+
|
|
84372
|
+
### Attachments are S3 objects
|
|
84373
|
+
|
|
84374
|
+
Binary attachments are uploaded to the workspace S3 bucket and surface in \`parsed_email.attachments[i].body\` as:
|
|
84375
|
+
|
|
84376
|
+
\`\`\`json
|
|
84377
|
+
{ "s3": "windmill_emails/<job_id>/attachments/<filename>" }
|
|
84378
|
+
\`\`\`
|
|
84379
|
+
|
|
84380
|
+
To read the bytes inside a script, use the wmill SDK:
|
|
84381
|
+
|
|
84382
|
+
\`\`\`ts
|
|
84383
|
+
// TypeScript
|
|
84384
|
+
import * as wmill from "windmill-client"
|
|
84385
|
+
const file = await wmill.loadS3File(parsed_email.attachments[0].body)
|
|
84386
|
+
\`\`\`
|
|
84387
|
+
|
|
84388
|
+
\`\`\`python
|
|
84389
|
+
# Python
|
|
84390
|
+
import wmill
|
|
84391
|
+
data = wmill.load_s3_file(parsed_email["attachments"][0]["body"])
|
|
84392
|
+
\`\`\`
|
|
84393
|
+
|
|
84394
|
+
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.
|
|
84395
|
+
|
|
84396
|
+
Text/HTML/inline parts are placed inline in \`body\` as strings.
|
|
83874
84397
|
|
|
83875
84398
|
## CLI Commands
|
|
83876
84399
|
|
|
@@ -84804,6 +85327,15 @@ Generate metadata (locks, schemas) for all scripts, flows, and apps
|
|
|
84804
85327
|
- \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
|
|
84805
85328
|
- \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
|
|
84806
85329
|
|
|
85330
|
+
**Subcommands:**
|
|
85331
|
+
|
|
85332
|
+
- \`generate-metadata rehash [folder:string]\`
|
|
85333
|
+
- \`--skip-scripts\` - Skip processing scripts
|
|
85334
|
+
- \`--skip-flows\` - Skip processing flows
|
|
85335
|
+
- \`--skip-apps\` - Skip processing apps
|
|
85336
|
+
- \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
|
|
85337
|
+
- \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
|
|
85338
|
+
|
|
84807
85339
|
### gitsync-settings
|
|
84808
85340
|
|
|
84809
85341
|
Manage git-sync settings between local wmill.yaml and Windmill backend
|
|
@@ -85477,6 +86009,71 @@ required:
|
|
|
85477
86009
|
- azure_mode
|
|
85478
86010
|
- scope_resource_id
|
|
85479
86011
|
- subscription_name
|
|
86012
|
+
`,
|
|
86013
|
+
email_trigger: `type: object
|
|
86014
|
+
properties:
|
|
86015
|
+
script_path:
|
|
86016
|
+
type: string
|
|
86017
|
+
description: Path to the script or flow to execute when triggered
|
|
86018
|
+
permissioned_as:
|
|
86019
|
+
type: string
|
|
86020
|
+
description: The user or group this trigger runs as (permissioned_as)
|
|
86021
|
+
is_flow:
|
|
86022
|
+
type: boolean
|
|
86023
|
+
description: True if script_path points to a flow, false if it points to a script
|
|
86024
|
+
labels:
|
|
86025
|
+
type: array
|
|
86026
|
+
items:
|
|
86027
|
+
type: string
|
|
86028
|
+
local_part:
|
|
86029
|
+
type: string
|
|
86030
|
+
workspaced_local_part:
|
|
86031
|
+
type: boolean
|
|
86032
|
+
error_handler_path:
|
|
86033
|
+
type: string
|
|
86034
|
+
error_handler_args:
|
|
86035
|
+
type: object
|
|
86036
|
+
description: The arguments to pass to the script or flow
|
|
86037
|
+
retry:
|
|
86038
|
+
type: object
|
|
86039
|
+
properties:
|
|
86040
|
+
constant:
|
|
86041
|
+
type: object
|
|
86042
|
+
description: Retry with constant delay between attempts
|
|
86043
|
+
properties:
|
|
86044
|
+
attempts:
|
|
86045
|
+
type: integer
|
|
86046
|
+
description: Number of retry attempts
|
|
86047
|
+
seconds:
|
|
86048
|
+
type: integer
|
|
86049
|
+
description: Seconds to wait between retries
|
|
86050
|
+
exponential:
|
|
86051
|
+
type: object
|
|
86052
|
+
description: Retry with exponential backoff (delay doubles each time)
|
|
86053
|
+
properties:
|
|
86054
|
+
attempts:
|
|
86055
|
+
type: integer
|
|
86056
|
+
description: Number of retry attempts
|
|
86057
|
+
multiplier:
|
|
86058
|
+
type: integer
|
|
86059
|
+
description: Multiplier for exponential backoff
|
|
86060
|
+
seconds:
|
|
86061
|
+
type: integer
|
|
86062
|
+
minimum: 1
|
|
86063
|
+
description: Initial delay in seconds
|
|
86064
|
+
random_factor:
|
|
86065
|
+
type: integer
|
|
86066
|
+
minimum: 0
|
|
86067
|
+
maximum: 100
|
|
86068
|
+
description: Random jitter percentage (0-100) to avoid thundering herd
|
|
86069
|
+
retry_if:
|
|
86070
|
+
$ref: '#/components/schemas/RetryIf'
|
|
86071
|
+
description: Retry configuration for failed module executions
|
|
86072
|
+
required:
|
|
86073
|
+
- script_path
|
|
86074
|
+
- permissioned_as
|
|
86075
|
+
- is_flow
|
|
86076
|
+
- local_part
|
|
85480
86077
|
`,
|
|
85481
86078
|
gcp_trigger: `type: object
|
|
85482
86079
|
properties:
|
|
@@ -86404,7 +87001,8 @@ var SCHEMA_MAPPINGS = {
|
|
|
86404
87001
|
{ name: "MqttTrigger", schemaKey: "mqtt_trigger", filePattern: "*.mqtt_trigger.yaml" },
|
|
86405
87002
|
{ name: "SqsTrigger", schemaKey: "sqs_trigger", filePattern: "*.sqs_trigger.yaml" },
|
|
86406
87003
|
{ name: "GcpTrigger", schemaKey: "gcp_trigger", filePattern: "*.gcp_trigger.yaml" },
|
|
86407
|
-
{ name: "AzureTrigger", schemaKey: "azure_trigger", filePattern: "*.azure_trigger.yaml" }
|
|
87004
|
+
{ name: "AzureTrigger", schemaKey: "azure_trigger", filePattern: "*.azure_trigger.yaml" },
|
|
87005
|
+
{ name: "EmailTrigger", schemaKey: "email_trigger", filePattern: "*.email_trigger.yaml" }
|
|
86408
87006
|
],
|
|
86409
87007
|
schedules: [
|
|
86410
87008
|
{ name: "Schedule", schemaKey: "schedule", filePattern: "*.schedule.yaml" }
|
|
@@ -87225,8 +87823,8 @@ async function initAction(opts) {
|
|
|
87225
87823
|
info(colors.gray("Skipped resource type namespace generation (no workspace bound). Run 'wmill workspace bind' then 'wmill init' to generate it."));
|
|
87226
87824
|
}
|
|
87227
87825
|
}
|
|
87228
|
-
var
|
|
87229
|
-
var init_default =
|
|
87826
|
+
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);
|
|
87827
|
+
var init_default = command28;
|
|
87230
87828
|
|
|
87231
87829
|
// src/commands/jobs/jobs.ts
|
|
87232
87830
|
init_mod3();
|
|
@@ -87392,8 +87990,8 @@ Warning: Found ${workers.length} active worker(s) on the instance.`));
|
|
|
87392
87990
|
}
|
|
87393
87991
|
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
87992
|
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 =
|
|
87993
|
+
var command29 = new Command().description("Manage jobs (import/export)").command("pull", pull3).command("push", push12);
|
|
87994
|
+
var jobs_default = command29;
|
|
87397
87995
|
|
|
87398
87996
|
// src/commands/job/job.ts
|
|
87399
87997
|
init_mod3();
|
|
@@ -87707,8 +88305,8 @@ async function cancel(opts, id) {
|
|
|
87707
88305
|
info(colors.green(`Job ${id} canceled.`));
|
|
87708
88306
|
}
|
|
87709
88307
|
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 =
|
|
88308
|
+
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);
|
|
88309
|
+
var job_default = command30;
|
|
87712
88310
|
|
|
87713
88311
|
// src/commands/group/group.ts
|
|
87714
88312
|
init_mod3();
|
|
@@ -87807,8 +88405,8 @@ async function removeUser(opts, name, username) {
|
|
|
87807
88405
|
});
|
|
87808
88406
|
info(colors.green(`User '${username}' removed from group '${name}'.`));
|
|
87809
88407
|
}
|
|
87810
|
-
var
|
|
87811
|
-
var group_default =
|
|
88408
|
+
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);
|
|
88409
|
+
var group_default = command31;
|
|
87812
88410
|
|
|
87813
88411
|
// src/commands/audit/audit.ts
|
|
87814
88412
|
init_mod3();
|
|
@@ -87885,8 +88483,8 @@ async function get12(opts, id) {
|
|
|
87885
88483
|
}
|
|
87886
88484
|
}
|
|
87887
88485
|
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 =
|
|
88486
|
+
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);
|
|
88487
|
+
var audit_default = command32;
|
|
87890
88488
|
|
|
87891
88489
|
// src/commands/token/token.ts
|
|
87892
88490
|
init_mod3();
|
|
@@ -87940,253 +88538,11 @@ async function deleteToken2(opts, tokenPrefix) {
|
|
|
87940
88538
|
await deleteToken({ tokenPrefix });
|
|
87941
88539
|
info(colors.green(`Token with prefix '${tokenPrefix}' deleted.`));
|
|
87942
88540
|
}
|
|
87943
|
-
var
|
|
87944
|
-
var token_default =
|
|
88541
|
+
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);
|
|
88542
|
+
var token_default = command33;
|
|
87945
88543
|
|
|
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;
|
|
88544
|
+
// src/main.ts
|
|
88545
|
+
await init_generate_metadata();
|
|
88190
88546
|
|
|
88191
88547
|
// src/commands/docs/docs.ts
|
|
88192
88548
|
init_mod3();
|