lua-cli 3.32.5 → 3.32.6

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.
@@ -72,6 +72,11 @@ export declare interface ApprovalOptions {
72
72
  /** default 'continue' (denial is data unless 'fail') */
73
73
  onDeny?: WorkflowApprovalOnDeny;
74
74
  businessHours?: WorkflowBusinessHours;
75
+ /**
76
+ * Optional — inferred `true` from a non-empty `editablePaths` (LUA-808 / LUA-825: the validator's `approvalEditable`
77
+ * rule, applied by the builder too); an explicit `false` beside paths is refused as contradictory. Absent with no
78
+ * paths ⇒ `false` (the approver decides, never edits).
79
+ */
75
80
  editable?: boolean;
76
81
  /** grammar: `drafts`, `drafts[*]`, `drafts[*].body`, `drafts[3].body`, `summary.title` */
77
82
  editablePaths?: string[];
@@ -735,6 +735,23 @@ function modelUnresolvedMessage(r) {
735
735
  }
736
736
  __name(modelUnresolvedMessage, "modelUnresolvedMessage");
737
737
  __name2(modelUnresolvedMessage, "modelUnresolvedMessage");
738
+ function providerModelId(code) {
739
+ const requested = typeof code === "string" ? code.trim() : "";
740
+ if (!requested || isModelIdSentinel(requested)) return requested;
741
+ const slash = requested.indexOf("/");
742
+ if (slash <= 0) return requested;
743
+ const provider = requested.slice(0, slash).toLowerCase();
744
+ if (MODEL_ID_BYOK_PROVIDERS.includes(provider)) return requested;
745
+ return requested.slice(slash + 1);
746
+ }
747
+ __name(providerModelId, "providerModelId");
748
+ __name2(providerModelId, "providerModelId");
749
+ var MODEL_SNAPSHOT_SUFFIX = /(?:[-@](?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])|-(?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]))$/;
750
+ function providerModelFamily(code) {
751
+ return providerModelId(code).toLowerCase().replace(MODEL_SNAPSHOT_SUFFIX, "");
752
+ }
753
+ __name(providerModelFamily, "providerModelFamily");
754
+ __name2(providerModelFamily, "providerModelFamily");
738
755
  var IMPLICIT_MODEL_SELECTION_SOURCES = [
739
756
  "workspace-default",
740
757
  "platform-default"
@@ -3233,7 +3250,7 @@ function fillHitl(node) {
3233
3250
  if (a.onTimeout === void 0) a.onTimeout = "deny";
3234
3251
  if (a.onDeny === void 0) a.onDeny = "continue";
3235
3252
  if (a.excludeInitiator === void 0) a.excludeInitiator = false;
3236
- if (a.editable === void 0) a.editable = false;
3253
+ if (a.editable === void 0) a.editable = approvalEditable(a);
3237
3254
  return;
3238
3255
  }
3239
3256
  const w = node;
@@ -3773,7 +3790,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
3773
3790
  }
3774
3791
  const a = node;
3775
3792
  checkId(a.id, path);
3776
- if (a.approver === "creator" && a.excludeInitiator === true) {
3793
+ if ((a.approver ?? "creator") === "creator" && a.excludeInitiator === true) {
3777
3794
  err("approver-excludes-only-candidate", "approver:'creator' with excludeInitiator:true always excludes the only candidate", path, a.id);
3778
3795
  }
3779
3796
  const editable = approvalEditable(a);
@@ -6221,6 +6238,63 @@ function rebaseItemPointer(pointer, itemsPath, index) {
6221
6238
  }
6222
6239
  __name(rebaseItemPointer, "rebaseItemPointer");
6223
6240
  __name3(rebaseItemPointer, "rebaseItemPointer");
6241
+ var WORKFLOW_SCHEDULE_TYPES = [
6242
+ "cron",
6243
+ "interval",
6244
+ "once"
6245
+ ];
6246
+ var WORKFLOW_SCHEDULE_SHAPE_ISSUE = "schedule-shape-invalid";
6247
+ var WORKFLOW_SCHEDULE_SHAPES_HINT = "`schedule` must be one of { type: 'cron', expression: '<5-field cron>', timezone?: '<IANA tz>' } | { type: 'interval', seconds: <n> } | { type: 'once', executeAt: '<ISO-8601>' }";
6248
+ var isObject = /* @__PURE__ */ __name3((v) => typeof v === "object" && v !== null && !Array.isArray(v), "isObject");
6249
+ function validateWorkflowSchedule(schedule, path = "/schedule") {
6250
+ if (schedule === void 0 || schedule === null) return [];
6251
+ const issue = /* @__PURE__ */ __name3((at, detail) => [
6252
+ {
6253
+ code: WORKFLOW_SCHEDULE_SHAPE_ISSUE,
6254
+ severity: "error",
6255
+ path: at,
6256
+ message: `${detail} \u2014 ${WORKFLOW_SCHEDULE_SHAPES_HINT}`
6257
+ }
6258
+ ], "issue");
6259
+ if (!isObject(schedule)) {
6260
+ return issue(path, `\`schedule\` is ${Array.isArray(schedule) ? "an array" : `a ${typeof schedule}`}, not a typed schedule object`);
6261
+ }
6262
+ const type = schedule.type;
6263
+ if (type === void 0) {
6264
+ const keys = Object.keys(schedule);
6265
+ const seen = keys.length ? ` (got { ${keys.join(", ")} })` : " (got {})";
6266
+ return issue(path, `\`schedule\` carries no \`type\` discriminator${seen}`);
6267
+ }
6268
+ if (typeof type !== "string" || !WORKFLOW_SCHEDULE_TYPES.includes(type)) {
6269
+ return issue(path, `\`schedule.type\` ${JSON.stringify(type)} is not one of ${WORKFLOW_SCHEDULE_TYPES.map((t) => `'${t}'`).join(" | ")}`);
6270
+ }
6271
+ switch (type) {
6272
+ case "cron": {
6273
+ if (typeof schedule.expression !== "string" || schedule.expression.trim().length === 0) {
6274
+ return issue(`${path}/expression`, "a { type: 'cron' } schedule needs a non-empty string `expression`");
6275
+ }
6276
+ if (schedule.timezone !== void 0 && (typeof schedule.timezone !== "string" || schedule.timezone.length === 0)) {
6277
+ return issue(`${path}/timezone`, "a { type: 'cron' } schedule's `timezone`, when given, is a non-empty IANA string");
6278
+ }
6279
+ return [];
6280
+ }
6281
+ case "interval": {
6282
+ const s = schedule.seconds;
6283
+ if (typeof s !== "number" || !Number.isFinite(s) || s <= 0) {
6284
+ return issue(`${path}/seconds`, "a { type: 'interval' } schedule needs a positive number `seconds`");
6285
+ }
6286
+ return [];
6287
+ }
6288
+ case "once": {
6289
+ if (typeof schedule.executeAt !== "string" || Number.isNaN(Date.parse(schedule.executeAt))) {
6290
+ return issue(`${path}/executeAt`, "a { type: 'once' } schedule needs an ISO-8601 string `executeAt`");
6291
+ }
6292
+ return [];
6293
+ }
6294
+ }
6295
+ }
6296
+ __name(validateWorkflowSchedule, "validateWorkflowSchedule");
6297
+ __name3(validateWorkflowSchedule, "validateWorkflowSchedule");
6224
6298
  var WORKFLOW_ENV_OVERLAY_MAX_KEYS = 64;
6225
6299
  var WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES = 4096;
6226
6300
  var WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE = /(SECRET|TOKEN|KEY|PASSWORD)$/;
@@ -7257,9 +7331,12 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
7257
7331
  if (opts.approver === "creator" && opts.excludeInitiator === true) {
7258
7332
  throw new LuaWorkflowBuildError("approver-excludes-only-candidate", `"${id}": approver:'creator' with excludeInitiator:true always excludes the only candidate`);
7259
7333
  }
7260
- if (opts.fourEyes !== void 0 && opts.editable !== true) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id}": fourEyes requires editable:true`);
7261
- if ((opts.editablePaths !== void 0 || opts.editedPayloadSchema !== void 0) && opts.editable !== true) {
7262
- throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": editablePaths / editedPayloadSchema require editable:true`);
7334
+ const editable = approvalEditable(opts);
7335
+ if (opts.fourEyes !== void 0 && !editable) throw new LuaWorkflowBuildError("four-eyes-requires-editable", `"${id}": \`fourEyes\` requires editable:true`);
7336
+ if (opts.editable === false && Array.isArray(opts.editablePaths) && opts.editablePaths.length > 0) {
7337
+ throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` beside editable:false is contradictory \u2014 drop the paths or set editable:true`);
7338
+ } else if ((opts.editablePaths !== void 0 || opts.editedPayloadSchema !== void 0) && !editable) {
7339
+ throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": \`editablePaths\` / \`editedPayloadSchema\` require editable:true (a non-empty editablePaths implies it)`);
7263
7340
  }
7264
7341
  for (const p of opts.editablePaths ?? []) {
7265
7342
  if (!EDITABLE_PATH_RE2.test(p)) throw new LuaWorkflowBuildError("editable-path-invalid", `"${id}": editablePaths entry "${p}" is outside the grammar seg(.seg)* with [*]/[n] selectors`);