windmill-cli 1.701.0 → 1.702.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 +165 -50
  2. package/package.json +1 -1
package/esm/main.js CHANGED
@@ -16752,7 +16752,7 @@ var init_OpenAPI = __esm(() => {
16752
16752
  PASSWORD: undefined,
16753
16753
  TOKEN: getEnv3("WM_TOKEN"),
16754
16754
  USERNAME: undefined,
16755
- VERSION: "1.701.0",
16755
+ VERSION: "1.702.0",
16756
16756
  WITH_CREDENTIALS: true,
16757
16757
  interceptors: {
16758
16758
  request: new Interceptors,
@@ -47151,7 +47151,7 @@ async function downloadZip(workspace, plainSecrets, skipVariables, skipResources
47151
47151
  }
47152
47152
  }
47153
47153
  const includeWorkspaceDependenciesValue = !(skipWorkspaceDependencies ?? false);
47154
- const baseParams = `&plain_secret=${plainSecrets ?? false}&skip_variables=${skipVariables ?? false}&skip_resources=${skipResources ?? false}&skip_secrets=${skipSecrets ?? false}&include_schedules=${includeSchedules ?? false}&include_triggers=${includeTriggers ?? false}&include_users=${includeUsers ?? false}&include_groups=${includeGroups ?? false}&include_settings=${includeSettings ?? false}&include_key=${includeKey ?? false}&include_workspace_dependencies=${includeWorkspaceDependenciesValue}&default_ts=${defaultTs ?? "bun"}&skip_resource_types=${skipResourceTypes ?? false}&settings_version=v2`;
47154
+ const baseParams = `&plain_secret=${plainSecrets ?? false}&skip_variables=${skipVariables ?? false}&skip_resources=${skipResources ?? false}&skip_secrets=${skipSecrets ?? false}&include_schedules=${includeSchedules ?? false}&include_triggers=${includeTriggers ?? false}&include_users=${includeUsers ?? false}&include_groups=${includeGroups ?? false}&include_settings=${includeSettings ?? false}&include_key=${includeKey ?? false}&include_workspace_dependencies=${includeWorkspaceDependenciesValue}&default_ts=${defaultTs ?? "bun"}&skip_resource_types=${skipResourceTypes ?? false}&settings_version=v2&preserve_extra_perms=true`;
47155
47155
  const baseUrl2 = workspace.remote + "api/w/" + workspace.workspaceId + "/workspaces/tarball?";
47156
47156
  const zipUrl = baseUrl2 + "archive_type=zip" + baseParams;
47157
47157
  const zipResponse = await fetch(zipUrl, { headers: requestHeaders, method: "GET" });
@@ -61584,6 +61584,109 @@ var require_dist3 = __commonJS((exports) => {
61584
61584
  __exportStar2(require_validation3(), exports);
61585
61585
  });
61586
61586
 
61587
+ // src/core/extra_perms.ts
61588
+ function normalize5(value, source) {
61589
+ const perms = {};
61590
+ const invalidOwners = new Set;
61591
+ if (value === null || value === undefined || typeof value !== "object" || Array.isArray(value)) {
61592
+ if (value !== undefined && value !== null) {
61593
+ error(colors.red(`extra_perms: ${source} is not a {owner: boolean} map — skipping ACL sync to avoid clobbering remote ACLs`));
61594
+ return { perms, invalidOwners, malformedTop: true };
61595
+ }
61596
+ return { perms, invalidOwners, malformedTop: false };
61597
+ }
61598
+ const invalidList = [];
61599
+ for (const [k, v] of Object.entries(value)) {
61600
+ if (typeof v === "boolean") {
61601
+ perms[k] = v;
61602
+ } else {
61603
+ invalidOwners.add(k);
61604
+ invalidList.push(k);
61605
+ }
61606
+ }
61607
+ if (invalidList.length > 0) {
61608
+ error(colors.red(`extra_perms: ${invalidList.length} invalid entry/entries in ${source} (non-boolean value, treating as "no opinion"): ${invalidList.join(", ")}`));
61609
+ }
61610
+ return { perms, invalidOwners, malformedTop: false };
61611
+ }
61612
+ function formatError(e) {
61613
+ if (!e || typeof e !== "object")
61614
+ return String(e);
61615
+ const anyE = e;
61616
+ if (anyE.body !== undefined) {
61617
+ if (typeof anyE.body === "string")
61618
+ return anyE.body;
61619
+ try {
61620
+ return JSON.stringify(anyE.body);
61621
+ } catch {}
61622
+ }
61623
+ if (typeof anyE.message === "string")
61624
+ return anyE.message;
61625
+ try {
61626
+ return JSON.stringify(e);
61627
+ } catch {
61628
+ return String(e);
61629
+ }
61630
+ }
61631
+ async function applyExtraPermsDiff(workspace, kind, path7, local, remote) {
61632
+ if (local === undefined || local === null) {
61633
+ return 0;
61634
+ }
61635
+ const localN = normalize5(local, "local yaml");
61636
+ if (localN.malformedTop) {
61637
+ return 0;
61638
+ }
61639
+ const remoteN = normalize5(remote, "remote response");
61640
+ const localPerms = localN.perms;
61641
+ const remotePerms = remoteN.perms;
61642
+ const toGrant = [];
61643
+ for (const [owner, write] of Object.entries(localPerms)) {
61644
+ if (!(owner in remotePerms) || remotePerms[owner] !== write) {
61645
+ toGrant.push([owner, write]);
61646
+ }
61647
+ }
61648
+ const toRevoke = Object.keys(remotePerms).filter((owner) => !(owner in localPerms) && !localN.invalidOwners.has(owner));
61649
+ if (toGrant.length === 0 && toRevoke.length === 0) {
61650
+ return 0;
61651
+ }
61652
+ let calls = 0;
61653
+ for (const [owner, write] of toGrant) {
61654
+ const access = write ? "write" : "read";
61655
+ try {
61656
+ await addGranularAcls({
61657
+ workspace,
61658
+ kind,
61659
+ path: path7,
61660
+ requestBody: { owner, write }
61661
+ });
61662
+ info(colors.green(` extra_perms: granted ${access} to ${owner} on ${kind}/${path7}`));
61663
+ calls += 1;
61664
+ } catch (e) {
61665
+ error(colors.red(` extra_perms: failed to grant ${access} to ${owner} on ${kind}/${path7}: ${formatError(e)}`));
61666
+ }
61667
+ }
61668
+ for (const owner of toRevoke) {
61669
+ try {
61670
+ await removeGranularAcls({
61671
+ workspace,
61672
+ kind,
61673
+ path: path7,
61674
+ requestBody: { owner }
61675
+ });
61676
+ info(colors.green(` extra_perms: revoked ${owner} on ${kind}/${path7}`));
61677
+ calls += 1;
61678
+ } catch (e) {
61679
+ error(colors.red(` extra_perms: failed to revoke ${owner} on ${kind}/${path7}: ${formatError(e)}`));
61680
+ }
61681
+ }
61682
+ return calls;
61683
+ }
61684
+ var init_extra_perms = __esm(() => {
61685
+ init_services_gen();
61686
+ init_log();
61687
+ init_colors2();
61688
+ });
61689
+
61587
61690
  // src/core/specific_items.ts
61588
61691
  async function resolveWsNameForGitBranch(branchName) {
61589
61692
  const config = await readConfigFile({ warnIfMissing: false });
@@ -62451,6 +62554,7 @@ async function handleFile(path8, workspace, alreadySynced, message, opts, rawWor
62451
62554
  if (typed == undefined || typed.description === remote.description && typed.summary === remote.summary && typed.kind == remote.kind && !remote.archived && (Array.isArray(remote?.lock) ? remote?.lock?.join(`
62452
62555
  `) : remote?.lock ?? "").trim() == (typed?.lock ?? "").trim() && deepEqual(typed.schema, remote.schema) && typed.tag == remote.tag && (typed.ws_error_handler_muted ?? false) == remote.ws_error_handler_muted && typed.dedicated_worker == remote.dedicated_worker && typed.cache_ttl == remote.cache_ttl && typed.concurrency_time_window_s == remote.concurrency_time_window_s && typed.concurrent_limit == remote.concurrent_limit && Boolean(typed.restart_unless_cancelled) == Boolean(remote.restart_unless_cancelled) && Boolean(typed.visible_to_runner_only) == Boolean(remote.visible_to_runner_only) && Boolean(typed.has_preprocessor) == Boolean(remote.has_preprocessor) && typed.priority == Boolean(remote.priority) && typed.timeout == remote.timeout && typed.concurrency_key == remote["concurrency_key"] && typed.debounce_key == remote["debounce_key"] && typed.debounce_delay_s == remote["debounce_delay_s"] && typed.codebase == remote.codebase && (hasOnBehalfOf ? true : typed.on_behalf_of_email == remote.on_behalf_of_email) && deepEqual(typed.envs, remote.envs) && deepEqual(modules ?? null, remote.modules ?? null)) {
62453
62556
  info(colors.green(`Script ${remotePath} is up to date`));
62557
+ await applyExtraPermsDiff(workspaceId, "script", remotePath.replaceAll(SEP4, "/"), typed?.extra_perms, remote?.extra_perms);
62454
62558
  return true;
62455
62559
  }
62456
62560
  }
@@ -62471,6 +62575,7 @@ async function handleFile(path8, workspace, alreadySynced, message, opts, rawWor
62471
62575
  const execTime = await createScript2(bundleContent, workspaceId, body, workspace);
62472
62576
  info(colors.yellow.bold(`Created new script ${remotePath} (${execTime.toFixed(0)}ms)`));
62473
62577
  }
62578
+ await applyExtraPermsDiff(workspaceId, "script", remotePath.replaceAll(SEP4, "/"), typed?.extra_perms, remote?.extra_perms);
62474
62579
  return true;
62475
62580
  }
62476
62581
  return false;
@@ -63213,6 +63318,7 @@ async function setPermissionedAs(opts, scriptPath, email) {
63213
63318
  }
63214
63319
  var import_yaml6, exts, languageAliases, command4, script_default;
63215
63320
  var init_script = __esm(async () => {
63321
+ init_extra_perms();
63216
63322
  init_colors2();
63217
63323
  init_mod3();
63218
63324
  init_mod6();
@@ -69443,31 +69549,32 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
69443
69549
  if (localApp.data) {
69444
69550
  value.data = localApp.data;
69445
69551
  }
69552
+ const { extra_perms: localPerms, ...localAppNoPerms } = localApp;
69446
69553
  if (app) {
69447
- const metadataUpToDate = isSuperset({ ...localApp, runnables }, app);
69554
+ const metadataUpToDate = isSuperset({ ...localAppNoPerms, runnables }, app);
69448
69555
  const filesUpToDate = deepEqual(files, app.value?.files);
69449
69556
  if (metadataUpToDate && filesUpToDate) {
69450
69557
  info(colors.green(`App ${remotePath} is up to date`));
69451
- return;
69558
+ } else {
69559
+ const { js, css } = await createBundleRaw();
69560
+ info(colors.bold.yellow(`Updating app ${remotePath}...`));
69561
+ await updateAppRaw({
69562
+ workspace,
69563
+ path: remotePath,
69564
+ formData: {
69565
+ app: {
69566
+ value,
69567
+ path: remotePath,
69568
+ summary: localApp.summary,
69569
+ policy: appForPolicy.policy,
69570
+ deployment_message: message,
69571
+ ...localApp.custom_path ? { custom_path: localApp.custom_path } : {}
69572
+ },
69573
+ js,
69574
+ css
69575
+ }
69576
+ });
69452
69577
  }
69453
- const { js, css } = await createBundleRaw();
69454
- info(colors.bold.yellow(`Updating app ${remotePath}...`));
69455
- await updateAppRaw({
69456
- workspace,
69457
- path: remotePath,
69458
- formData: {
69459
- app: {
69460
- value,
69461
- path: remotePath,
69462
- summary: localApp.summary,
69463
- policy: appForPolicy.policy,
69464
- deployment_message: message,
69465
- ...localApp.custom_path ? { custom_path: localApp.custom_path } : {}
69466
- },
69467
- js,
69468
- css
69469
- }
69470
- });
69471
69578
  } else {
69472
69579
  const { js, css } = await createBundleRaw();
69473
69580
  await createAppRaw({
@@ -69486,6 +69593,7 @@ async function pushRawApp(workspace, remotePath, localPath, message) {
69486
69593
  }
69487
69594
  });
69488
69595
  }
69596
+ await applyExtraPermsDiff(workspace, "raw_app", remotePath, localPerms, app?.extra_perms);
69489
69597
  }
69490
69598
  async function generatingPolicy(app, path14, publicApp) {
69491
69599
  info(colors.gray(`Generating fresh policy for app ${path14}...`));
@@ -69503,6 +69611,7 @@ var init_raw_apps = __esm(async () => {
69503
69611
  init_log();
69504
69612
  init_lib_es();
69505
69613
  init_services_gen();
69614
+ init_extra_perms();
69506
69615
  init_path_assigner();
69507
69616
  await __promiseAll([
69508
69617
  init_auth(),
@@ -72340,21 +72449,22 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
72340
72449
  }
72341
72450
  }
72342
72451
  }
72452
+ const { extra_perms: localPerms, ...localAppBody } = localApp;
72343
72453
  if (app) {
72344
- if (isSuperset(localApp, app)) {
72454
+ if (isSuperset(localAppBody, app)) {
72345
72455
  info(colors.green(`App ${remotePath} is up to date`));
72346
- return;
72456
+ } else {
72457
+ info(colors.bold.yellow(`Updating app ${remotePath}...`));
72458
+ await updateApp({
72459
+ workspace,
72460
+ path: remotePath,
72461
+ requestBody: {
72462
+ deployment_message: message,
72463
+ ...localAppBody,
72464
+ ...preserveFields
72465
+ }
72466
+ });
72347
72467
  }
72348
- info(colors.bold.yellow(`Updating app ${remotePath}...`));
72349
- await updateApp({
72350
- workspace,
72351
- path: remotePath,
72352
- requestBody: {
72353
- deployment_message: message,
72354
- ...localApp,
72355
- ...preserveFields
72356
- }
72357
- });
72358
72468
  } else {
72359
72469
  info(colors.yellow.bold("Creating new app..."));
72360
72470
  await createApp({
@@ -72362,11 +72472,12 @@ async function pushApp(workspace, remotePath, localPath, message, permissionedAs
72362
72472
  requestBody: {
72363
72473
  path: remotePath,
72364
72474
  deployment_message: message,
72365
- ...localApp,
72475
+ ...localAppBody,
72366
72476
  ...preserveFields
72367
72477
  }
72368
72478
  });
72369
72479
  }
72480
+ await applyExtraPermsDiff(workspace, "app", remotePath, localPerms, app?.extra_perms);
72370
72481
  }
72371
72482
  async function generatingPolicy2(app, path19, publicApp) {
72372
72483
  info(colors.gray(`Generating fresh policy for app ${path19}...`));
@@ -72496,6 +72607,7 @@ var init_app = __esm(async () => {
72496
72607
  init_lib_es();
72497
72608
  init_services_gen();
72498
72609
  init_global();
72610
+ init_extra_perms();
72499
72611
  await __promiseAll([
72500
72612
  init_auth(),
72501
72613
  init_context(),
@@ -75706,22 +75818,23 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
75706
75818
  info(`Preserving ${flow.on_behalf_of_email} as on_behalf_of for flow ${remotePath}`);
75707
75819
  }
75708
75820
  }
75821
+ const { extra_perms: localPerms, ...localFlowBody } = localFlow;
75709
75822
  if (flow) {
75710
- if (isSuperset(localFlow, flow)) {
75823
+ if (isSuperset(localFlowBody, flow)) {
75711
75824
  info(colors.green(`Flow ${remotePath} is up to date`));
75712
- return;
75713
- }
75714
- info(colors.bold.yellow(`Updating flow ${remotePath}...`));
75715
- await updateFlow({
75716
- workspace,
75717
- path: remotePath.replaceAll(SEP20, "/"),
75718
- requestBody: {
75825
+ } else {
75826
+ info(colors.bold.yellow(`Updating flow ${remotePath}...`));
75827
+ await updateFlow({
75828
+ workspace,
75719
75829
  path: remotePath.replaceAll(SEP20, "/"),
75720
- deployment_message: message,
75721
- ...localFlow,
75722
- ...preserveFields
75723
- }
75724
- });
75830
+ requestBody: {
75831
+ path: remotePath.replaceAll(SEP20, "/"),
75832
+ deployment_message: message,
75833
+ ...localFlowBody,
75834
+ ...preserveFields
75835
+ }
75836
+ });
75837
+ }
75725
75838
  } else {
75726
75839
  info(colors.bold.yellow("Creating new flow..."));
75727
75840
  try {
@@ -75730,7 +75843,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
75730
75843
  requestBody: {
75731
75844
  path: remotePath.replaceAll(SEP20, "/"),
75732
75845
  deployment_message: message,
75733
- ...localFlow,
75846
+ ...localFlowBody,
75734
75847
  ...preserveFields
75735
75848
  }
75736
75849
  });
@@ -75738,6 +75851,7 @@ async function pushFlow(workspace, remotePath, localPath, message, permissionedA
75738
75851
  throw new Error(`Failed to create flow ${remotePath}: ${e.body ?? e.message}`);
75739
75852
  }
75740
75853
  }
75854
+ await applyExtraPermsDiff(workspace, "flow", remotePath.replaceAll(SEP20, "/"), localPerms, flow?.extra_perms);
75741
75855
  }
75742
75856
  async function push11(opts, filePath, remotePath) {
75743
75857
  if (!validatePath(remotePath)) {
@@ -76164,6 +76278,7 @@ var init_flow = __esm(async () => {
76164
76278
  init_mod6();
76165
76279
  init_log();
76166
76280
  init_services_gen();
76281
+ init_extra_perms();
76167
76282
  await __promiseAll([
76168
76283
  init_types(),
76169
76284
  init_confirm(),
@@ -89686,7 +89801,7 @@ var config_default = command35;
89686
89801
 
89687
89802
  // src/main.ts
89688
89803
  await init_context();
89689
- var VERSION = "1.701.0";
89804
+ var VERSION = "1.702.0";
89690
89805
  async function checkVersionSafe(cmd) {
89691
89806
  const mainCommand = cmd.getMainCommand();
89692
89807
  const upgradeCommand = mainCommand.getCommand("upgrade");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.701.0",
3
+ "version": "1.702.0",
4
4
  "description": "CLI for Windmill",
5
5
  "license": "Apache 2.0",
6
6
  "type": "module",