windmill-cli 1.719.0 → 1.721.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/esm/main.js +189 -7
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -16772,7 +16772,7 @@ var init_OpenAPI = __esm(() => {
16772
16772
  PASSWORD: undefined,
16773
16773
  TOKEN: getEnv3("WM_TOKEN"),
16774
16774
  USERNAME: undefined,
16775
- VERSION: "1.719.0",
16775
+ VERSION: "1.721.0",
16776
16776
  WITH_CREDENTIALS: true,
16777
16777
  interceptors: {
16778
16778
  request: new Interceptors,
@@ -17056,6 +17056,7 @@ __export(exports_services_gen, {
17056
17056
  updateUser: () => updateUser,
17057
17057
  updateTutorialProgress: () => updateTutorialProgress,
17058
17058
  updateTokenScopes: () => updateTokenScopes,
17059
+ updateTokenLabel: () => updateTokenLabel,
17059
17060
  updateSqsTrigger: () => updateSqsTrigger,
17060
17061
  updateSharedUi: () => updateSharedUi,
17061
17062
  updateScriptHistory: () => updateScriptHistory,
@@ -19407,6 +19408,16 @@ var backendVersion = () => {
19407
19408
  body: data3.requestBody,
19408
19409
  mediaType: "application/json"
19409
19410
  });
19411
+ }, updateTokenLabel = (data3) => {
19412
+ return request(OpenAPI, {
19413
+ method: "POST",
19414
+ url: "/users/tokens/update_label/{token_prefix}",
19415
+ path: {
19416
+ token_prefix: data3.tokenPrefix
19417
+ },
19418
+ body: data3.requestBody,
19419
+ mediaType: "application/json"
19420
+ });
19410
19421
  }, listTokens = (data3 = {}) => {
19411
19422
  return request(OpenAPI, {
19412
19423
  method: "GET",
@@ -25293,7 +25304,7 @@ var init_auth = __esm(async () => {
25293
25304
  });
25294
25305
 
25295
25306
  // src/core/constants.ts
25296
- var WM_FORK_PREFIX = "wm-fork", VERSION = "1.719.0";
25307
+ var WM_FORK_PREFIX = "wm-fork", VERSION = "1.721.0";
25297
25308
 
25298
25309
  // src/utils/git.ts
25299
25310
  var exports_git = {};
@@ -65740,21 +65751,25 @@ var exports_sync = {};
65740
65751
  __export(exports_sync, {
65741
65752
  yamlSortedEntries: () => yamlSortedEntries,
65742
65753
  yamlOptions: () => yamlOptions,
65754
+ summarizeCaseRewrites: () => summarizeCaseRewrites,
65743
65755
  resolveWsNameForConfigFromFlags: () => resolveWsNameForConfigFromFlags,
65744
65756
  readDirRecursiveWithIgnore: () => readDirRecursiveWithIgnore2,
65745
65757
  push: () => push4,
65746
65758
  pull: () => pull,
65747
65759
  isWhitelisted: () => isWhitelisted,
65760
+ isCaseInsensitiveFilesystem: () => isCaseInsensitiveFilesystem,
65748
65761
  ignoreF: () => ignoreF,
65749
65762
  gitDeploy: () => gitDeploy,
65750
65763
  generateDatatablesDocumentation: () => generateDatatablesDocumentation,
65751
65764
  generateAgentsDocumentation: () => generateAgentsDocumentation,
65752
65765
  findCodebase: () => findCodebase,
65766
+ findCaseInsensitiveCollisions: () => findCaseInsensitiveCollisions,
65753
65767
  extractInlineScriptsForApps: () => extractInlineScriptsForApps,
65754
65768
  extractFieldsForRawApps: () => extractFieldsForRawApps,
65755
65769
  elementsToMap: () => elementsToMap,
65756
65770
  default: () => sync_default,
65757
65771
  computeWsSpecificFlagOnlyPushes: () => computeWsSpecificFlagOnlyPushes,
65772
+ canonicalizeCaseInsensitiveKeys: () => canonicalizeCaseInsensitiveKeys,
65758
65773
  FSFSElement: () => FSFSElement
65759
65774
  });
65760
65775
  import { writeFile as writeFile7, readdir as readdir4, stat as stat7, rm, copyFile, mkdir as mkdir5 } from "node:fs/promises";
@@ -66919,11 +66934,178 @@ ${configHint}`);
66919
66934
  }
66920
66935
  return map;
66921
66936
  }
66922
- async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetadataDeletion, codebases, ignoreCodebaseChanges, specificItems, branchOverride, isEls1Remote) {
66923
- const [m1, m2] = els2 ? await Promise.all([
66937
+ function findCaseInsensitiveCollisions(paths) {
66938
+ const byLower = new Map;
66939
+ for (const full of paths) {
66940
+ const segs = full.split(/[\\/]/).filter((s) => s.length > 0);
66941
+ let acc = "";
66942
+ for (let i = 0;i < segs.length; i++) {
66943
+ acc = i === 0 ? segs[i] : `${acc}/${segs[i]}`;
66944
+ const lower = acc.toLowerCase();
66945
+ let set = byLower.get(lower);
66946
+ if (!set) {
66947
+ set = new Set;
66948
+ byLower.set(lower, set);
66949
+ }
66950
+ set.add(acc);
66951
+ }
66952
+ }
66953
+ const collidingLowers = new Set;
66954
+ for (const [lower, set] of byLower) {
66955
+ if (set.size > 1)
66956
+ collidingLowers.add(lower);
66957
+ }
66958
+ const collisions = [];
66959
+ for (const lower of collidingLowers) {
66960
+ const parts = lower.split("/");
66961
+ let hasCollidingAncestor = false;
66962
+ for (let i = 1;i < parts.length; i++) {
66963
+ if (collidingLowers.has(parts.slice(0, i).join("/"))) {
66964
+ hasCollidingAncestor = true;
66965
+ break;
66966
+ }
66967
+ }
66968
+ if (!hasCollidingAncestor) {
66969
+ collisions.push([...byLower.get(lower)].sort());
66970
+ }
66971
+ }
66972
+ return collisions;
66973
+ }
66974
+ function canonicalizeCaseInsensitiveKeys(localMap, remoteMap) {
66975
+ const root = { children: new Map };
66976
+ for (const k of Object.keys(remoteMap)) {
66977
+ let node = root;
66978
+ for (const seg of k.split(/[\\/]/)) {
66979
+ if (seg.length === 0)
66980
+ continue;
66981
+ const lk = seg.toLowerCase();
66982
+ let entry = node.children.get(lk);
66983
+ if (!entry) {
66984
+ entry = { canonical: seg, ambiguous: false, node: { children: new Map } };
66985
+ node.children.set(lk, entry);
66986
+ } else if (entry.canonical !== seg) {
66987
+ entry.ambiguous = true;
66988
+ }
66989
+ node = entry.node;
66990
+ }
66991
+ }
66992
+ const out = {};
66993
+ const rewritten = [];
66994
+ for (const [k, v] of Object.entries(localMap)) {
66995
+ const sep3 = k.includes("\\") ? "\\" : "/";
66996
+ const segs = k.split(/[\\/]/);
66997
+ const canonSegs = [];
66998
+ let node = root;
66999
+ let changed = false;
67000
+ for (const seg of segs) {
67001
+ if (seg.length === 0) {
67002
+ canonSegs.push(seg);
67003
+ continue;
67004
+ }
67005
+ const entry = node?.children.get(seg.toLowerCase());
67006
+ if (entry && !entry.ambiguous) {
67007
+ if (entry.canonical !== seg)
67008
+ changed = true;
67009
+ canonSegs.push(entry.canonical);
67010
+ node = entry.node;
67011
+ } else {
67012
+ canonSegs.push(seg);
67013
+ node = undefined;
67014
+ }
67015
+ }
67016
+ const canonKey = canonSegs.join(sep3);
67017
+ if (changed && canonKey !== k) {
67018
+ out[canonKey] = v;
67019
+ rewritten.push({ from: k, to: canonKey });
67020
+ } else {
67021
+ out[k] = v;
67022
+ }
67023
+ }
67024
+ return {
67025
+ map: out,
67026
+ ambiguous: findCaseInsensitiveCollisions(Object.keys(remoteMap)),
67027
+ rewritten
67028
+ };
67029
+ }
67030
+ function summarizeCaseRewrites(rewritten) {
67031
+ const seen = new Set;
67032
+ const out = [];
67033
+ for (const { from, to } of rewritten) {
67034
+ const fromSegs = from.split(/[\\/]/);
67035
+ const toSegs = to.split(/[\\/]/);
67036
+ let i = 0;
67037
+ while (i < fromSegs.length && i < toSegs.length && fromSegs[i] === toSegs[i]) {
67038
+ i++;
67039
+ }
67040
+ const fromPrefix = fromSegs.slice(0, i + 1).join("/");
67041
+ const toPrefix = toSegs.slice(0, i + 1).join("/");
67042
+ const key = `${fromPrefix} -> ${toPrefix}`;
67043
+ if (!seen.has(key)) {
67044
+ seen.add(key);
67045
+ out.push(key);
67046
+ }
67047
+ }
67048
+ return out;
67049
+ }
67050
+ function warnUnrepresentableCaseCollisions(collisions) {
67051
+ if (collisions.length === 0)
67052
+ return;
67053
+ const groups = collisions.map((g) => ` - ${g.join(" <-> ")}`).join(`
67054
+ `);
67055
+ warn(`Found ${collisions.length} path(s) that differ only by letter case:
67056
+ ` + `${groups}
67057
+ ` + `On case-insensitive filesystems (Windows, default macOS) these collapse ` + `into a single file/directory and cannot both be synced. Rename one side ` + `to a distinct path to make the tree sync reliably across platforms.`);
67058
+ }
67059
+ async function isCaseInsensitiveFilesystem(dir) {
67060
+ const override = (process.env.WMILL_CASE_INSENSITIVE_FS ?? "").trim().toLowerCase();
67061
+ if (override === "true" || override === "1")
67062
+ return true;
67063
+ if (override === "false" || override === "0")
67064
+ return false;
67065
+ if (_caseInsensitiveFsCache !== undefined)
67066
+ return _caseInsensitiveFsCache;
67067
+ let result = false;
67068
+ try {
67069
+ const upper = path10.join(dir, `.wmill-CASEPROBE-${process.pid}.tmp`);
67070
+ const lower = path10.join(dir, `.wmill-caseprobe-${process.pid}.tmp`);
67071
+ await writeFile7(upper, "", "utf-8");
67072
+ try {
67073
+ await stat7(lower);
67074
+ result = true;
67075
+ } catch {
67076
+ result = false;
67077
+ }
67078
+ await rm(upper).catch(() => {});
67079
+ await rm(lower).catch(() => {});
67080
+ } catch {
67081
+ result = false;
67082
+ }
67083
+ _caseInsensitiveFsCache = result;
67084
+ return result;
67085
+ }
67086
+ async function compareDynFSElement(els1, els2, ignore, json, skips, ignoreMetadataDeletion, codebases, ignoreCodebaseChanges, specificItems, branchOverride, isEls1Remote, caseInsensitiveFs) {
67087
+ let [m1, m2] = els2 ? await Promise.all([
66924
67088
  elementsToMap(els1, ignore, json, skips, specificItems, branchOverride, isEls1Remote),
66925
67089
  elementsToMap(els2, ignore, json, skips, specificItems, branchOverride, !isEls1Remote)
66926
67090
  ]) : [await elementsToMap(els1, ignore, json, skips, specificItems, branchOverride, isEls1Remote), {}];
67091
+ if (els2 && isEls1Remote !== undefined) {
67092
+ const remoteMap = isEls1Remote ? m1 : m2;
67093
+ warnUnrepresentableCaseCollisions(findCaseInsensitiveCollisions(Object.keys(remoteMap)));
67094
+ if (caseInsensitiveFs) {
67095
+ const { map, rewritten } = canonicalizeCaseInsensitiveKeys(isEls1Remote ? m2 : m1, remoteMap);
67096
+ if (isEls1Remote) {
67097
+ m2 = map;
67098
+ } else {
67099
+ m1 = map;
67100
+ }
67101
+ const summary = summarizeCaseRewrites(rewritten);
67102
+ if (summary.length > 0) {
67103
+ info(`Reconciled ${summary.length} local path(s) to the server's casing ` + `(case-insensitive filesystem):
67104
+ ` + summary.map((s) => ` ${s}`).join(`
67105
+ `));
67106
+ }
67107
+ }
67108
+ }
66927
67109
  const changes = [];
66928
67110
  function parseYaml(k, v) {
66929
67111
  if (k.endsWith(".script.yaml")) {
@@ -67363,7 +67545,7 @@ async function pull(opts) {
67363
67545
  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);
67364
67546
  const remote = ZipFSElement(zipFile, !opts.json, opts.defaultTs ?? "bun", resourceTypeToFormatExtension, resourceTypeToIsFileset, true, parseSyncBehavior(opts.syncBehavior) >= 1);
67365
67547
  const local = !opts.stateful ? await FSFSElement(process.cwd(), codebases, true) : await FSFSElement(path10.join(process.cwd(), ".wmill"), [], true);
67366
- const { changes, localMap } = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, wsNameForFiles, true);
67548
+ const { changes, localMap } = await compareDynFSElement(remote, local, await ignoreF(opts), opts.json ?? false, opts, false, codebases, true, specificItems, wsNameForFiles, true, await isCaseInsensitiveFilesystem(process.cwd()));
67367
67549
  info(`remote (${workspace.name}) -> local: ${changes.length} changes to apply`);
67368
67550
  if (wsSpecificMerge.serverItems && wsSpecificMerge.serverItems.length > 0) {
67369
67551
  const changedPaths = new Set(changes.map((c) => c.path));
@@ -67726,7 +67908,7 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
67726
67908
  } catch {}
67727
67909
  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);
67728
67910
  const local = await FSFSElement(path10.join(process.cwd(), ""), codebases, false);
67729
- const { changes, localMap } = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, wsNameForFiles, false);
67911
+ const { changes, localMap } = await compareDynFSElement(local, remote, await ignoreF(opts), opts.json ?? false, opts, true, codebases, false, specificItems, wsNameForFiles, false, await isCaseInsensitiveFilesystem(process.cwd()));
67730
67912
  const wsSpecificFlagOnly = computeWsSpecificFlagOnlyPushes(localMap, localSpecificItems, serverWsSpecificItems);
67731
67913
  for (const item of wsSpecificFlagOnly) {
67732
67914
  if (changes.some((c) => c.path === item.filePath))
@@ -68512,7 +68694,7 @@ Done! All ${changes.length} changes pushed to the remote workspace ${workspace.w
68512
68694
  }
68513
68695
  }
68514
68696
  }
68515
- var import_yaml11, branchDeprecationWarned = false, yamlOptions, isNotWmillFile = (p, isDirectory2) => {
68697
+ var import_yaml11, branchDeprecationWarned = false, yamlOptions, _caseInsensitiveFsCache, isNotWmillFile = (p, isDirectory2) => {
68516
68698
  if (p.endsWith(SEP9)) {
68517
68699
  return false;
68518
68700
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.719.0",
3
+ "version": "1.721.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",