@sanity/workflow-engine 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @sanity/workflow-engine
2
2
 
3
+ ## 0.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0bc4328: Render diagram tooltips in the Studio's own idiom, through one seam instead of six hand-assembled bodies:
8
+ - Pin the chrome once (padding 2, radius 3, shadow 2, 280px sentence cap / 400px for dev mode's label-value grids). Bodies no longer carry their own outer padding, which had stacked a `padding={3}` box inside the tooltip's own padding.
9
+ - A title with nothing under it renders in regular weight — it is the whole message, not a heading. Semibold is reserved for a title that actually heads content, one per tooltip: gate headings now separate from their checklist rows by full-strength versus muted text rather than a second bold.
10
+ - Checklists, the grouped-edge roster, the group vertex's stage list and an activity's causal waits render as real `<ul>`/`<li>` rows, so wrapping and nesting come from the browser. Previously these were flattened into padded strings with `white-space: pre-wrap`, which left a wrapped row's continuation aligned under its own marker. Each row leads with its glyph in a fixed-width column and hangs its wrapped lines back to the text: one column for a bullet and a verdict alike, where a `list-style-type` marker box is sized by its own content and put the two on different left edges within one tooltip. The glyph is inline content rather than a marker, so it is selected and copied with the row it belongs to.
11
+ - Space the body on one three-step rhythm, named by the role a gap plays: independent blocks (the activity roster, each gate) separate furthest, a lead-in sits closer to the list it introduces, and rows within a list sit closest. A stage tooltip nests several of these, and at one flat step the whole explanation read as a single mass.
12
+ - `MetaTable` renders rows only; the title and description come from the shared body, so dev-mode and end-user tooltips head identically.
13
+
14
+ `OUTCOME_MARKS` and `NEUTRAL_MARK` are now exported (from `@sanity/groq-condition-describe`, re-exported by `@sanity/workflow-engine`), so a structured checklist renderer and `checklistLines` draw their verdict glyphs from one vocabulary.
15
+
16
+ - 41a3f02: Add `dueDate` and `dueDatetime` field kinds — elevated aliases of `date` / `datetime` (same stored value and validation) that mark THE due date of a level, so surfaces can identify a deadline by kind instead of guessing which date field means "due". Declarable at workflow, stage, and activity scope; optional (no field becomes required). The kind reserves a level's single due slot, so deploy enforces both halves of that: at most one due-\* (either kind, combined) per scope, and none below scope level — a due-\* nested in an `object`/`array` sub-field or an effect's `outputs` is rejected, naming `date` / `datetime` as the fix, because no deadline reader looks there. A `todoList` row's `dueDate` column is unaffected; it is a `date` named `dueDate`, not the kind. Choice lists (`options`) work on the due kinds exactly as on `date` / `datetime`. Persisted-model version 5 (additive, reader floor unchanged).
17
+
18
+ The Studio plugin edits and renders the new kinds exactly like the base kinds they elevate: the calendar picker in the start dialog, the Overview pills, the inline field editors and the activity row's date control, a locale-formatted face, and the Workflows tool's Date filter. Every date-family branch now routes through one shared kind predicate, so an elevated alias can't drift out of a site.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [0bc4328]
23
+ - @sanity/groq-condition-describe@0.4.0
24
+
25
+ ## 0.23.0
26
+
27
+ ### Minor Changes
28
+
29
+ - 795b4bb: `set-stage` now makes `--to` optional: omit it on an interactive terminal and the command presents a picker of the instance's declared stages, with the current stage marked and the cursor opened on it. Because `set-stage` is an admin override, every declared stage is offered — not just reachable transitions. The candidates come from the instance's pinned definition snapshot (the same model the engine validates the move against), so the menu can never offer a stage the move would reject. Off a non-interactive terminal `--to` stays required, so scripted use is unaffected. The engine now exports `parseDefinitionSnapshotValue` for reading a definition snapshot from a minimal instance shape.
30
+
31
+ ### Patch Changes
32
+
33
+ - 94d311e: Resolve account-global actor identities when a Studio client is explicitly bound to a project API host, and refuse project-scoped identities returned through custom or malformed API hosts.
34
+
3
35
  ## 0.22.0
4
36
 
5
37
  ### Patch Changes
package/DATAMODEL.md CHANGED
@@ -666,6 +666,42 @@ from that snapshot. Definitions are create-only and instance persists retain
666
666
  unknown fields, so model-4 data survives round trips; the floor prevents an
667
667
  older engine from interpreting it in the first place.
668
668
 
669
+ ### Model 5 — the `dueDate` / `dueDatetime` field kinds (reader floor: 4)
670
+
671
+ One additive growth ships as model 5 — model 4 was released before it landed,
672
+ so it mints the next version rather than amending a shipped one. It does not
673
+ raise the reader floor; the writer maximum stays 4.
674
+
675
+ Two elevated scalar aliases mark THE due date for a level (workflow, stage, or
676
+ activity): `dueDate` aliases `date` (same stored `YYYY-MM-DD` value and
677
+ validation) and `dueDatetime` aliases `datetime` (same stored ISO-8601 value
678
+ and validation). The kind lets surfaces identify a level's deadline instead of
679
+ guessing which date field means "due". Both are optional; a deploy invariant
680
+ allows at most one due-\* (either kind, combined) per scope, so "the due date"
681
+ is never ambiguous. Both stamped trees grow the value:
682
+
683
+ - **Definition tree** — `fields[].type` admits `'dueDate'` and `'dueDatetime'`
684
+ on a scope's own entries only. A due-\* nested in an `object`/`array`
685
+ sub-field, or in an effect's `outputs`, is rejected at deploy: the kind names
686
+ the deadline OF A LEVEL, and every deadline reader consults scope entries, so
687
+ a nested one is dead configuration. Nested dates stay `date` / `datetime`.
688
+ Existing `todoList` sugar is unaffected — its `dueDate` row column is a
689
+ `date` named `dueDate`, not the kind.
690
+ - **Instance tree** — resolved `fields[]` entries admit `_type: 'dueDate'` and
691
+ `_type: 'dueDatetime'` (the same arm shapes as `date` / `datetime`).
692
+
693
+ Manifest feature: `due-date-field-kinds` (definition + instance, additive,
694
+ detectable, floor 0).
695
+
696
+ Would an old reader misread the kinds (rule 5)? No — the same loud refusal as
697
+ the `subject` and `progress` kinds: an older engine (model 4 and below) that
698
+ loaded a due-date-carrying instance fails the strict `fields[]` variant with
699
+ `PersistedDocShapeError` before interpreting anything, and cannot deploy or
700
+ evaluate a due-date-declaring definition. The stored value is byte-identical to
701
+ its base `date` / `datetime`, so no older code path can write it while skipping
702
+ validation — there is no silent bypass to fence, and the kinds leave the floor
703
+ at 0.
704
+
669
705
  ## Pending governed changes
670
706
 
671
707
  - **`temp.system.guard` → `system.guard`** — the guard doc type's `temp.`
@@ -150,7 +150,7 @@ function parentRef(instance) {
150
150
  return instance.ancestors.at(-1);
151
151
  }
152
152
 
153
- const DATA_MODEL_VERSION = 4, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
153
+ const DATA_MODEL_VERSION = 5, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
154
154
 
155
155
  class ReaderModelAcknowledgementError extends WorkflowError {
156
156
  code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
@@ -241,6 +241,14 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
241
241
  compatibility: "reader-floor",
242
242
  applicability: "detectable",
243
243
  summary: "Start and activity readiness use named polymorphic requirement arrays."
244
+ }), Object.freeze({
245
+ id: "due-date-field-kinds",
246
+ introducedInModel: 5,
247
+ minReaderModel: 0,
248
+ documentTypes: Object.freeze([ "definition", "instance" ]),
249
+ compatibility: "additive",
250
+ applicability: "detectable",
251
+ summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
244
252
  }) ]);
245
253
 
246
254
  function recordOf(value) {
@@ -315,7 +323,8 @@ const featureDetectors = {
315
323
  "progress-field-kind": document => hasFieldKind(document, "progress"),
316
324
  "effect-claim-tokens": hasClaimTokens,
317
325
  "classified-principal-ids": () => !0,
318
- "readiness-requirements": hasReadinessRequirements
326
+ "readiness-requirements": hasReadinessRequirements,
327
+ "due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
319
328
  };
320
329
 
321
330
  function requiredModelFeatures(documentType, document) {
@@ -1879,7 +1888,7 @@ const GdrUriSchema = v__namespace.custom(s => typeof s == "string" && isGdrUri(s
1879
1888
  }), tolerantObject()({
1880
1889
  type: v__namespace.literal("role"),
1881
1890
  role: NonEmptyString
1882
- }) ]), NullableString = v__namespace.union([ v__namespace.null(), v__namespace.string() ]), NullableNumber = v__namespace.union([ v__namespace.null(), v__namespace.number() ]), NullableBoolean = v__namespace.union([ v__namespace.null(), v__namespace.boolean() ]), NullableProgress = v__namespace.union([ v__namespace.null(), v__namespace.pipe(v__namespace.number(), v__namespace.finite("progress must be a finite number"), v__namespace.minValue(0, "progress must be at least 0"), v__namespace.maxValue(100, "progress must be at most 100")) ]), NullableDateTime = v__namespace.union([ v__namespace.null(), IsoTimestamp ]), NullableDate = v__namespace.union([ v__namespace.null(), v__namespace.pipe(v__namespace.string(), v__namespace.regex(/^\d{4}-\d{2}-\d{2}$/, "must be a `YYYY-MM-DD` date")) ]), NullableUrl = NullableString, CHOICE_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number", "url", "date", "datetime", "dateTime" ]);
1891
+ }) ]), NullableString = v__namespace.union([ v__namespace.null(), v__namespace.string() ]), NullableNumber = v__namespace.union([ v__namespace.null(), v__namespace.number() ]), NullableBoolean = v__namespace.union([ v__namespace.null(), v__namespace.boolean() ]), NullableProgress = v__namespace.union([ v__namespace.null(), v__namespace.pipe(v__namespace.number(), v__namespace.finite("progress must be a finite number"), v__namespace.minValue(0, "progress must be at least 0"), v__namespace.maxValue(100, "progress must be at most 100")) ]), NullableDateTime = v__namespace.union([ v__namespace.null(), IsoTimestamp ]), NullableDate = v__namespace.union([ v__namespace.null(), v__namespace.pipe(v__namespace.string(), v__namespace.regex(/^\d{4}-\d{2}-\d{2}$/, "must be a `YYYY-MM-DD` date")) ]), NullableUrl = NullableString, CHOICE_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number", "url", "date", "dueDate", "datetime", "dueDatetime", "dateTime" ]);
1883
1892
 
1884
1893
  function normalizedChoiceKind(kind) {
1885
1894
  return kind === "dateTime" ? "datetime" : kind;
@@ -1914,7 +1923,9 @@ const fieldValueSchemas = {
1914
1923
  progress: NullableProgress,
1915
1924
  boolean: NullableBoolean,
1916
1925
  date: NullableDate,
1926
+ dueDate: NullableDate,
1917
1927
  datetime: NullableDateTime,
1928
+ dueDatetime: NullableDateTime,
1918
1929
  url: NullableUrl,
1919
1930
  actor: v__namespace.union([ v__namespace.null(), ActorShape ]),
1920
1931
  assignee: v__namespace.union([ v__namespace.null(), AssigneeShape ]),
@@ -2279,7 +2290,7 @@ function groupMembershipNames(group) {
2279
2290
  return group === void 0 ? [] : typeof group == "string" ? [ group ] : [ ...group ];
2280
2291
  }
2281
2292
 
2282
- const FIELD_VALUE_KINDS = [ "doc.ref", "doc.refs", "subject", "release.ref", "string", "text", "number", "progress", "boolean", "date", "datetime", "url", "actor", "assignee", "assignees", "object", "array" ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), AUTHORING_FIELD_SUGAR_KINDS = exhaustiveOptions()([ "claim", "todoList", "notes" ]), AUTHORING_FIELD_KINDS = [ ...FIELD_VALUE_KINDS, ...AUTHORING_FIELD_SUGAR_KINDS ], AuthoringRawFieldKindSchema = v__namespace.picklist(FIELD_VALUE_KINDS, issue => `${invalidOptionMessage(AUTHORING_FIELD_KINDS)} but received ${JSON.stringify(issue.input)}`), FieldEntryName = groqIdentifier("`$fields.<name>`"), FiniteNumber = v__namespace.pipe(v__namespace.number(), v__namespace.finite("must be finite")), ScalarValidationSchema = v__namespace.pipe(v__namespace.strictObject({
2293
+ const FIELD_VALUE_KINDS = [ "doc.ref", "doc.refs", "subject", "release.ref", "string", "text", "number", "progress", "boolean", "date", "dueDate", "datetime", "dueDatetime", "url", "actor", "assignee", "assignees", "object", "array" ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), AUTHORING_FIELD_SUGAR_KINDS = exhaustiveOptions()([ "claim", "todoList", "notes" ]), AUTHORING_FIELD_KINDS = [ ...FIELD_VALUE_KINDS, ...AUTHORING_FIELD_SUGAR_KINDS ], AuthoringRawFieldKindSchema = v__namespace.picklist(FIELD_VALUE_KINDS, issue => `${invalidOptionMessage(AUTHORING_FIELD_KINDS)} but received ${JSON.stringify(issue.input)}`), FieldEntryName = groqIdentifier("`$fields.<name>`"), FiniteNumber = v__namespace.pipe(v__namespace.number(), v__namespace.finite("must be finite")), ScalarValidationSchema = v__namespace.pipe(v__namespace.strictObject({
2283
2294
  min: v__namespace.optional(FiniteNumber),
2284
2295
  max: v__namespace.optional(FiniteNumber)
2285
2296
  }), v__namespace.check(validation => validation.min !== void 0 || validation.max !== void 0, "declare at least one bound, or omit `validation`"), v__namespace.check(validation => validation.min === void 0 || validation.max === void 0 || validation.min <= validation.max, "`min` must be less than or equal to `max`")), ChoiceOptionsSchema = v__namespace.strictObject({
@@ -2669,6 +2680,10 @@ function isSubjectEntry(entry) {
2669
2680
  return entry.type === "subject";
2670
2681
  }
2671
2682
 
2683
+ function isDueDateEntry(entry) {
2684
+ return entry.type === "dueDate" || entry.type === "dueDatetime";
2685
+ }
2686
+
2672
2687
  function isInputSourced(entry) {
2673
2688
  return entry.initialValue?.type === "input";
2674
2689
  }
@@ -3175,25 +3190,79 @@ function checkAssigneesEntries(def, issues) {
3175
3190
  });
3176
3191
  }
3177
3192
 
3178
- function nestedSubjectPaths(shapes, base) {
3179
- return (shapes ?? []).flatMap((shape, i) => isSubjectEntry(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedSubjectPaths(shape.fields, [ ...base, i, "fields" ]), ...nestedSubjectPaths(shape.of, [ ...base, i, "of" ]) ]);
3193
+ function checkDueDateEntries(def, issues) {
3194
+ for (const {entries: entries, path: path, label: label} of fieldScopes(def)) {
3195
+ (entries ?? []).filter(isDueDateEntry).length > 1 && issues.push({
3196
+ path: path,
3197
+ message: "at most one due-date field entry per scope (dueDate or dueDatetime combined) — surfaces identify the deadline by kind"
3198
+ });
3199
+ for (const site of belowScopeNestedSites({
3200
+ entries: entries,
3201
+ path: path,
3202
+ isKind: isDueDateEntry
3203
+ })) issues.push({
3204
+ path: site.path,
3205
+ message: `${label} entry "${site.entry.name}" declares a due-date sub-field — a due-* kind marks THE deadline of a level, so nothing reads one below scope level. Declare \`date\` or \`datetime\` for a nested date`
3206
+ });
3207
+ }
3208
+ }
3209
+
3210
+ function nestedKindPaths(args) {
3211
+ const {shapes: shapes, base: base, isKind: isKind} = args;
3212
+ return (shapes ?? []).flatMap((shape, i) => isKind(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedKindPaths({
3213
+ shapes: shape.fields,
3214
+ base: [ ...base, i, "fields" ],
3215
+ isKind: isKind
3216
+ }), ...nestedKindPaths({
3217
+ shapes: shape.of,
3218
+ base: [ ...base, i, "of" ],
3219
+ isKind: isKind
3220
+ }) ]);
3180
3221
  }
3181
3222
 
3182
- function checkSubjectEffectOutputs(def, issues) {
3183
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) pushSubjectOutputIssues({
3223
+ function belowScopeNestedSites(args) {
3224
+ const {entries: entries, path: path, isKind: isKind} = args;
3225
+ return (entries ?? []).flatMap((entry, n) => [ ...nestedKindPaths({
3226
+ shapes: entry.fields,
3227
+ base: [ ...path, n, "fields" ],
3228
+ isKind: isKind
3229
+ }), ...nestedKindPaths({
3230
+ shapes: entry.of,
3231
+ base: [ ...path, n, "of" ],
3232
+ isKind: isKind
3233
+ }) ].map(nestedPath => ({
3234
+ path: nestedPath,
3235
+ entry: entry
3236
+ })));
3237
+ }
3238
+
3239
+ function checkLevelKindEffectOutputs(def, issues) {
3240
+ for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) pushOutputIssues({
3184
3241
  action: action,
3185
3242
  path: [ "stages", i, "activities", j, "actions", a ],
3186
3243
  issues: issues
3187
3244
  });
3188
3245
  }
3189
3246
 
3190
- function pushSubjectOutputIssues(args) {
3247
+ const LEVEL_KIND_OUTPUT_RULES = [ {
3248
+ isKind: isSubjectEntry,
3249
+ message: name => `effect "${name}" declares a \`subject\` output shape — no subject reader ever looks at effect outputs. Declare \`doc.ref\` for a document-valued output`
3250
+ }, {
3251
+ isKind: isDueDateEntry,
3252
+ message: name => `effect "${name}" declares a due-date output shape — a due-* kind marks THE deadline of a level, and no deadline reader looks at effect outputs. Declare \`date\` or \`datetime\` for a dated output`
3253
+ } ];
3254
+
3255
+ function pushOutputIssues(args) {
3191
3256
  const {action: action, path: path, issues: issues} = args;
3192
3257
  for (const [e, effect] of (action.effects ?? []).entries()) {
3193
3258
  const base = [ ...path, "effects", e, "outputs" ];
3194
- for (const nestedPath of nestedSubjectPaths(effect.outputs, base)) issues.push({
3259
+ for (const {isKind: isKind, message: message} of LEVEL_KIND_OUTPUT_RULES) for (const nestedPath of nestedKindPaths({
3260
+ shapes: effect.outputs,
3261
+ base: base,
3262
+ isKind: isKind
3263
+ })) issues.push({
3195
3264
  path: nestedPath,
3196
- message: `effect "${effect.name}" declares a \`subject\` output shape — no subject reader ever looks at effect outputs. Declare \`doc.ref\` for a document-valued output`
3265
+ message: message(effect.name)
3197
3266
  });
3198
3267
  }
3199
3268
  }
@@ -3211,13 +3280,14 @@ function checkSubjectEntries(def, issues) {
3211
3280
  path: [ ...path, n ],
3212
3281
  message: "at most one subject-kind field entry per workflow — the runtime identifies THE subject by kind, and a second one makes it ambiguous"
3213
3282
  });
3214
- for (const [n, entry] of (entries ?? []).entries()) {
3215
- const nested = [ ...nestedSubjectPaths(entry.fields, [ ...path, n, "fields" ]), ...nestedSubjectPaths(entry.of, [ ...path, n, "of" ]) ];
3216
- for (const nestedPath of nested) issues.push({
3217
- path: nestedPath,
3218
- message: `${label} entry "${entry.name}" declares a \`subject\` sub-field — a nested subject can never be read as the workflow's subject. Declare \`doc.ref\` for a nested reference`
3219
- });
3220
- }
3283
+ for (const site of belowScopeNestedSites({
3284
+ entries: entries,
3285
+ path: path,
3286
+ isKind: isSubjectEntry
3287
+ })) issues.push({
3288
+ path: site.path,
3289
+ message: `${label} entry "${site.entry.name}" declares a \`subject\` sub-field — a nested subject can never be read as the workflow's subject. Declare \`doc.ref\` for a nested reference`
3290
+ });
3221
3291
  }
3222
3292
  }
3223
3293
 
@@ -3853,7 +3923,9 @@ const SCALAR = {
3853
3923
  progress: () => SCALAR,
3854
3924
  boolean: () => SCALAR,
3855
3925
  date: () => SCALAR,
3926
+ dueDate: () => SCALAR,
3856
3927
  datetime: () => SCALAR,
3928
+ dueDatetime: () => SCALAR,
3857
3929
  url: () => SCALAR,
3858
3930
  actor: () => ACTOR_VALUE,
3859
3931
  assignee: () => ASSIGNEE_VALUE,
@@ -3944,10 +4016,10 @@ function checkWorkflowInvariants(def) {
3944
4016
  checkRequiredField(def, issues), checkStart(def, issues), checkPredicates(def, issues),
3945
4017
  checkUnboundConditionVars(def, issues), checkConditionFieldReads(def, issues), checkFieldReadSeeds(def, issues),
3946
4018
  checkFieldReadOpValues(def, issues), checkUpdateWhereOps(def, issues), checkGuardFieldReads(def, issues),
3947
- checkAssigneesEntries(def, issues), checkSubjectEntries(def, issues), checkSubjectEffectOutputs(def, issues),
3948
- checkActivityTerminalPaths(def, issues), checkTerminalStageActivities(def, issues),
3949
- checkTriggeredActionParams(def, issues), checkStoredRolesPlacement(def, issues),
3950
- checkGroups(def, issues), issues;
4019
+ checkAssigneesEntries(def, issues), checkDueDateEntries(def, issues), checkSubjectEntries(def, issues),
4020
+ checkLevelKindEffectOutputs(def, issues), checkActivityTerminalPaths(def, issues),
4021
+ checkTerminalStageActivities(def, issues), checkTriggeredActionParams(def, issues),
4022
+ checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
3951
4023
  }
3952
4024
 
3953
4025
  exports.ACTION_SEMANTICS = ACTION_SEMANTICS;
@@ -4182,6 +4254,8 @@ exports.parentRef = parentRef;
4182
4254
 
4183
4255
  exports.parseDefinitionSnapshot = parseDefinitionSnapshot;
4184
4256
 
4257
+ exports.parseDefinitionSnapshotValue = parseDefinitionSnapshotValue;
4258
+
4185
4259
  exports.parseFieldValue = parseFieldValue;
4186
4260
 
4187
4261
  exports.parseGdr = parseGdr;
@@ -136,7 +136,7 @@ function parentRef(instance) {
136
136
  return instance.ancestors.at(-1);
137
137
  }
138
138
 
139
- const DATA_MODEL_VERSION = 4, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
139
+ const DATA_MODEL_VERSION = 5, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
140
140
 
141
141
  class ReaderModelAcknowledgementError extends WorkflowError {
142
142
  code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
@@ -227,6 +227,14 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
227
227
  compatibility: "reader-floor",
228
228
  applicability: "detectable",
229
229
  summary: "Start and activity readiness use named polymorphic requirement arrays."
230
+ }), Object.freeze({
231
+ id: "due-date-field-kinds",
232
+ introducedInModel: 5,
233
+ minReaderModel: 0,
234
+ documentTypes: Object.freeze([ "definition", "instance" ]),
235
+ compatibility: "additive",
236
+ applicability: "detectable",
237
+ summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
230
238
  }) ]);
231
239
 
232
240
  function recordOf(value) {
@@ -301,7 +309,8 @@ const featureDetectors = {
301
309
  "progress-field-kind": document => hasFieldKind(document, "progress"),
302
310
  "effect-claim-tokens": hasClaimTokens,
303
311
  "classified-principal-ids": () => !0,
304
- "readiness-requirements": hasReadinessRequirements
312
+ "readiness-requirements": hasReadinessRequirements,
313
+ "due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
305
314
  };
306
315
 
307
316
  function requiredModelFeatures(documentType, document) {
@@ -1865,7 +1874,7 @@ const GdrUriSchema = v.custom(s => typeof s == "string" && isGdrUri(s), "must be
1865
1874
  }), tolerantObject()({
1866
1875
  type: v.literal("role"),
1867
1876
  role: NonEmptyString
1868
- }) ]), NullableString = v.union([ v.null(), v.string() ]), NullableNumber = v.union([ v.null(), v.number() ]), NullableBoolean = v.union([ v.null(), v.boolean() ]), NullableProgress = v.union([ v.null(), v.pipe(v.number(), v.finite("progress must be a finite number"), v.minValue(0, "progress must be at least 0"), v.maxValue(100, "progress must be at most 100")) ]), NullableDateTime = v.union([ v.null(), IsoTimestamp ]), NullableDate = v.union([ v.null(), v.pipe(v.string(), v.regex(/^\d{4}-\d{2}-\d{2}$/, "must be a `YYYY-MM-DD` date")) ]), NullableUrl = NullableString, CHOICE_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number", "url", "date", "datetime", "dateTime" ]);
1877
+ }) ]), NullableString = v.union([ v.null(), v.string() ]), NullableNumber = v.union([ v.null(), v.number() ]), NullableBoolean = v.union([ v.null(), v.boolean() ]), NullableProgress = v.union([ v.null(), v.pipe(v.number(), v.finite("progress must be a finite number"), v.minValue(0, "progress must be at least 0"), v.maxValue(100, "progress must be at most 100")) ]), NullableDateTime = v.union([ v.null(), IsoTimestamp ]), NullableDate = v.union([ v.null(), v.pipe(v.string(), v.regex(/^\d{4}-\d{2}-\d{2}$/, "must be a `YYYY-MM-DD` date")) ]), NullableUrl = NullableString, CHOICE_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number", "url", "date", "dueDate", "datetime", "dueDatetime", "dateTime" ]);
1869
1878
 
1870
1879
  function normalizedChoiceKind(kind) {
1871
1880
  return kind === "dateTime" ? "datetime" : kind;
@@ -1900,7 +1909,9 @@ const fieldValueSchemas = {
1900
1909
  progress: NullableProgress,
1901
1910
  boolean: NullableBoolean,
1902
1911
  date: NullableDate,
1912
+ dueDate: NullableDate,
1903
1913
  datetime: NullableDateTime,
1914
+ dueDatetime: NullableDateTime,
1904
1915
  url: NullableUrl,
1905
1916
  actor: v.union([ v.null(), ActorShape ]),
1906
1917
  assignee: v.union([ v.null(), AssigneeShape ]),
@@ -2265,7 +2276,7 @@ function groupMembershipNames(group) {
2265
2276
  return group === void 0 ? [] : typeof group == "string" ? [ group ] : [ ...group ];
2266
2277
  }
2267
2278
 
2268
- const FIELD_VALUE_KINDS = [ "doc.ref", "doc.refs", "subject", "release.ref", "string", "text", "number", "progress", "boolean", "date", "datetime", "url", "actor", "assignee", "assignees", "object", "array" ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), AUTHORING_FIELD_SUGAR_KINDS = exhaustiveOptions()([ "claim", "todoList", "notes" ]), AUTHORING_FIELD_KINDS = [ ...FIELD_VALUE_KINDS, ...AUTHORING_FIELD_SUGAR_KINDS ], AuthoringRawFieldKindSchema = v.picklist(FIELD_VALUE_KINDS, issue => `${invalidOptionMessage(AUTHORING_FIELD_KINDS)} but received ${JSON.stringify(issue.input)}`), FieldEntryName = groqIdentifier("`$fields.<name>`"), FiniteNumber = v.pipe(v.number(), v.finite("must be finite")), ScalarValidationSchema = v.pipe(v.strictObject({
2279
+ const FIELD_VALUE_KINDS = [ "doc.ref", "doc.refs", "subject", "release.ref", "string", "text", "number", "progress", "boolean", "date", "dueDate", "datetime", "dueDatetime", "url", "actor", "assignee", "assignees", "object", "array" ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), AUTHORING_FIELD_SUGAR_KINDS = exhaustiveOptions()([ "claim", "todoList", "notes" ]), AUTHORING_FIELD_KINDS = [ ...FIELD_VALUE_KINDS, ...AUTHORING_FIELD_SUGAR_KINDS ], AuthoringRawFieldKindSchema = v.picklist(FIELD_VALUE_KINDS, issue => `${invalidOptionMessage(AUTHORING_FIELD_KINDS)} but received ${JSON.stringify(issue.input)}`), FieldEntryName = groqIdentifier("`$fields.<name>`"), FiniteNumber = v.pipe(v.number(), v.finite("must be finite")), ScalarValidationSchema = v.pipe(v.strictObject({
2269
2280
  min: v.optional(FiniteNumber),
2270
2281
  max: v.optional(FiniteNumber)
2271
2282
  }), v.check(validation => validation.min !== void 0 || validation.max !== void 0, "declare at least one bound, or omit `validation`"), v.check(validation => validation.min === void 0 || validation.max === void 0 || validation.min <= validation.max, "`min` must be less than or equal to `max`")), ChoiceOptionsSchema = v.strictObject({
@@ -2655,6 +2666,10 @@ function isSubjectEntry(entry) {
2655
2666
  return entry.type === "subject";
2656
2667
  }
2657
2668
 
2669
+ function isDueDateEntry(entry) {
2670
+ return entry.type === "dueDate" || entry.type === "dueDatetime";
2671
+ }
2672
+
2658
2673
  function isInputSourced(entry) {
2659
2674
  return entry.initialValue?.type === "input";
2660
2675
  }
@@ -3161,25 +3176,79 @@ function checkAssigneesEntries(def, issues) {
3161
3176
  });
3162
3177
  }
3163
3178
 
3164
- function nestedSubjectPaths(shapes, base) {
3165
- return (shapes ?? []).flatMap((shape, i) => isSubjectEntry(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedSubjectPaths(shape.fields, [ ...base, i, "fields" ]), ...nestedSubjectPaths(shape.of, [ ...base, i, "of" ]) ]);
3179
+ function checkDueDateEntries(def, issues) {
3180
+ for (const {entries: entries, path: path, label: label} of fieldScopes(def)) {
3181
+ (entries ?? []).filter(isDueDateEntry).length > 1 && issues.push({
3182
+ path: path,
3183
+ message: "at most one due-date field entry per scope (dueDate or dueDatetime combined) — surfaces identify the deadline by kind"
3184
+ });
3185
+ for (const site of belowScopeNestedSites({
3186
+ entries: entries,
3187
+ path: path,
3188
+ isKind: isDueDateEntry
3189
+ })) issues.push({
3190
+ path: site.path,
3191
+ message: `${label} entry "${site.entry.name}" declares a due-date sub-field — a due-* kind marks THE deadline of a level, so nothing reads one below scope level. Declare \`date\` or \`datetime\` for a nested date`
3192
+ });
3193
+ }
3166
3194
  }
3167
3195
 
3168
- function checkSubjectEffectOutputs(def, issues) {
3169
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) pushSubjectOutputIssues({
3196
+ function nestedKindPaths(args) {
3197
+ const {shapes: shapes, base: base, isKind: isKind} = args;
3198
+ return (shapes ?? []).flatMap((shape, i) => isKind(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedKindPaths({
3199
+ shapes: shape.fields,
3200
+ base: [ ...base, i, "fields" ],
3201
+ isKind: isKind
3202
+ }), ...nestedKindPaths({
3203
+ shapes: shape.of,
3204
+ base: [ ...base, i, "of" ],
3205
+ isKind: isKind
3206
+ }) ]);
3207
+ }
3208
+
3209
+ function belowScopeNestedSites(args) {
3210
+ const {entries: entries, path: path, isKind: isKind} = args;
3211
+ return (entries ?? []).flatMap((entry, n) => [ ...nestedKindPaths({
3212
+ shapes: entry.fields,
3213
+ base: [ ...path, n, "fields" ],
3214
+ isKind: isKind
3215
+ }), ...nestedKindPaths({
3216
+ shapes: entry.of,
3217
+ base: [ ...path, n, "of" ],
3218
+ isKind: isKind
3219
+ }) ].map(nestedPath => ({
3220
+ path: nestedPath,
3221
+ entry: entry
3222
+ })));
3223
+ }
3224
+
3225
+ function checkLevelKindEffectOutputs(def, issues) {
3226
+ for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) pushOutputIssues({
3170
3227
  action: action,
3171
3228
  path: [ "stages", i, "activities", j, "actions", a ],
3172
3229
  issues: issues
3173
3230
  });
3174
3231
  }
3175
3232
 
3176
- function pushSubjectOutputIssues(args) {
3233
+ const LEVEL_KIND_OUTPUT_RULES = [ {
3234
+ isKind: isSubjectEntry,
3235
+ message: name => `effect "${name}" declares a \`subject\` output shape — no subject reader ever looks at effect outputs. Declare \`doc.ref\` for a document-valued output`
3236
+ }, {
3237
+ isKind: isDueDateEntry,
3238
+ message: name => `effect "${name}" declares a due-date output shape — a due-* kind marks THE deadline of a level, and no deadline reader looks at effect outputs. Declare \`date\` or \`datetime\` for a dated output`
3239
+ } ];
3240
+
3241
+ function pushOutputIssues(args) {
3177
3242
  const {action: action, path: path, issues: issues} = args;
3178
3243
  for (const [e, effect] of (action.effects ?? []).entries()) {
3179
3244
  const base = [ ...path, "effects", e, "outputs" ];
3180
- for (const nestedPath of nestedSubjectPaths(effect.outputs, base)) issues.push({
3245
+ for (const {isKind: isKind, message: message} of LEVEL_KIND_OUTPUT_RULES) for (const nestedPath of nestedKindPaths({
3246
+ shapes: effect.outputs,
3247
+ base: base,
3248
+ isKind: isKind
3249
+ })) issues.push({
3181
3250
  path: nestedPath,
3182
- message: `effect "${effect.name}" declares a \`subject\` output shape — no subject reader ever looks at effect outputs. Declare \`doc.ref\` for a document-valued output`
3251
+ message: message(effect.name)
3183
3252
  });
3184
3253
  }
3185
3254
  }
@@ -3197,13 +3266,14 @@ function checkSubjectEntries(def, issues) {
3197
3266
  path: [ ...path, n ],
3198
3267
  message: "at most one subject-kind field entry per workflow — the runtime identifies THE subject by kind, and a second one makes it ambiguous"
3199
3268
  });
3200
- for (const [n, entry] of (entries ?? []).entries()) {
3201
- const nested = [ ...nestedSubjectPaths(entry.fields, [ ...path, n, "fields" ]), ...nestedSubjectPaths(entry.of, [ ...path, n, "of" ]) ];
3202
- for (const nestedPath of nested) issues.push({
3203
- path: nestedPath,
3204
- message: `${label} entry "${entry.name}" declares a \`subject\` sub-field — a nested subject can never be read as the workflow's subject. Declare \`doc.ref\` for a nested reference`
3205
- });
3206
- }
3269
+ for (const site of belowScopeNestedSites({
3270
+ entries: entries,
3271
+ path: path,
3272
+ isKind: isSubjectEntry
3273
+ })) issues.push({
3274
+ path: site.path,
3275
+ message: `${label} entry "${site.entry.name}" declares a \`subject\` sub-field — a nested subject can never be read as the workflow's subject. Declare \`doc.ref\` for a nested reference`
3276
+ });
3207
3277
  }
3208
3278
  }
3209
3279
 
@@ -3839,7 +3909,9 @@ const SCALAR = {
3839
3909
  progress: () => SCALAR,
3840
3910
  boolean: () => SCALAR,
3841
3911
  date: () => SCALAR,
3912
+ dueDate: () => SCALAR,
3842
3913
  datetime: () => SCALAR,
3914
+ dueDatetime: () => SCALAR,
3843
3915
  url: () => SCALAR,
3844
3916
  actor: () => ACTOR_VALUE,
3845
3917
  assignee: () => ASSIGNEE_VALUE,
@@ -3930,10 +4002,10 @@ function checkWorkflowInvariants(def) {
3930
4002
  checkRequiredField(def, issues), checkStart(def, issues), checkPredicates(def, issues),
3931
4003
  checkUnboundConditionVars(def, issues), checkConditionFieldReads(def, issues), checkFieldReadSeeds(def, issues),
3932
4004
  checkFieldReadOpValues(def, issues), checkUpdateWhereOps(def, issues), checkGuardFieldReads(def, issues),
3933
- checkAssigneesEntries(def, issues), checkSubjectEntries(def, issues), checkSubjectEffectOutputs(def, issues),
3934
- checkActivityTerminalPaths(def, issues), checkTerminalStageActivities(def, issues),
3935
- checkTriggeredActionParams(def, issues), checkStoredRolesPlacement(def, issues),
3936
- checkGroups(def, issues), issues;
4005
+ checkAssigneesEntries(def, issues), checkDueDateEntries(def, issues), checkSubjectEntries(def, issues),
4006
+ checkLevelKindEffectOutputs(def, issues), checkActivityTerminalPaths(def, issues),
4007
+ checkTerminalStageActivities(def, issues), checkTriggeredActionParams(def, issues),
4008
+ checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
3937
4009
  }
3938
4010
 
3939
- export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, ModelVersionAheadError, NonEmptyString, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, ReaderModelAcknowledgementError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assertReadableModel, assertReaderModelAcknowledgement, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldTreeShape, fieldValueSchemas, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, isUnprimed, labelFor, lakePrincipalId, minReaderModelOf, modelStampFor, modelVersionOf, parentRef, parseDefinitionSnapshot, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, requiredModelFeatures, requiredReaderModel, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, terminalState, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };
4011
+ export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, ModelVersionAheadError, NonEmptyString, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, ReaderModelAcknowledgementError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assertReadableModel, assertReaderModelAcknowledgement, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldTreeShape, fieldValueSchemas, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, isUnprimed, labelFor, lakePrincipalId, minReaderModelOf, modelStampFor, modelVersionOf, parentRef, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, requiredModelFeatures, requiredReaderModel, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, terminalState, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };
package/dist/define.d.cts CHANGED
@@ -1148,7 +1148,9 @@ declare const FIELD_VALUE_KINDS: readonly [
1148
1148
  "progress",
1149
1149
  "boolean",
1150
1150
  "date",
1151
+ "dueDate",
1151
1152
  "datetime",
1153
+ "dueDatetime",
1152
1154
  "url",
1153
1155
  "actor",
1154
1156
  "assignee",
@@ -1879,6 +1881,10 @@ declare type TerminalActivityStatus =
1879
1881
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
1880
1882
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
1881
1883
  * `{label, status}` only (open ↔ done). Never a stored kind.
1884
+ *
1885
+ * The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
1886
+ * FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
1887
+ * and a repeating row has nothing to reserve.
1882
1888
  */
1883
1889
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
1884
1890
  type: "todoList";
package/dist/define.d.ts CHANGED
@@ -1148,7 +1148,9 @@ declare const FIELD_VALUE_KINDS: readonly [
1148
1148
  "progress",
1149
1149
  "boolean",
1150
1150
  "date",
1151
+ "dueDate",
1151
1152
  "datetime",
1153
+ "dueDatetime",
1152
1154
  "url",
1153
1155
  "actor",
1154
1156
  "assignee",
@@ -1879,6 +1881,10 @@ declare type TerminalActivityStatus =
1879
1881
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
1880
1882
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
1881
1883
  * `{label, status}` only (open ↔ done). Never a stored kind.
1884
+ *
1885
+ * The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
1886
+ * FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
1887
+ * and a repeating row has nothing to reserve.
1882
1888
  */
1883
1889
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
1884
1890
  type: "todoList";
package/dist/index.cjs CHANGED
@@ -4128,7 +4128,7 @@ const OptionalRefTypes = v__namespace.exactOptional(v__namespace.array(v__namesp
4128
4128
  })), v__namespace.looseObject(invariants.tolerantEntries()({
4129
4129
  ...fieldArm("subject", invariants.fieldValueSchemas.subject),
4130
4130
  types: OptionalRefTypes
4131
- })), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("release.ref", invariants.fieldValueSchemas["release.ref"]))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("string", invariants.fieldValueSchemas.string))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("text", invariants.fieldValueSchemas.text))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("number", invariants.fieldValueSchemas.number))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("progress", invariants.fieldValueSchemas.progress))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("boolean", invariants.fieldValueSchemas.boolean))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("date", invariants.fieldValueSchemas.date))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("datetime", invariants.fieldValueSchemas.datetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("url", invariants.fieldValueSchemas.url))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("actor", invariants.fieldValueSchemas.actor))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("assignee", invariants.fieldValueSchemas.assignee))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("assignees", invariants.fieldValueSchemas.assignees))), v__namespace.looseObject(invariants.tolerantEntries()({
4131
+ })), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("release.ref", invariants.fieldValueSchemas["release.ref"]))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("string", invariants.fieldValueSchemas.string))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("text", invariants.fieldValueSchemas.text))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("number", invariants.fieldValueSchemas.number))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("progress", invariants.fieldValueSchemas.progress))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("boolean", invariants.fieldValueSchemas.boolean))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("date", invariants.fieldValueSchemas.date))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDate", invariants.fieldValueSchemas.dueDate))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("datetime", invariants.fieldValueSchemas.datetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("dueDatetime", invariants.fieldValueSchemas.dueDatetime))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("url", invariants.fieldValueSchemas.url))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("actor", invariants.fieldValueSchemas.actor))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("assignee", invariants.fieldValueSchemas.assignee))), v__namespace.looseObject(invariants.tolerantEntries()(fieldArm("assignees", invariants.fieldValueSchemas.assignees))), v__namespace.looseObject(invariants.tolerantEntries()({
4132
4132
  ...fieldArm("object", v__namespace.union([ v__namespace.null(), UnknownRecord ])),
4133
4133
  fields: v__namespace.array(PersistedFieldShapeSchema)
4134
4134
  })), v__namespace.looseObject(invariants.tolerantEntries()({
@@ -8493,9 +8493,13 @@ async function fetchGlobalUser(client) {
8493
8493
  reason: "the client cannot reach the global API host (no withConfig)"
8494
8494
  };
8495
8495
  let globalRequest, globalClient;
8496
+ const hostResolution = resolveGlobalApiHost(client);
8496
8497
  try {
8497
8498
  globalClient = client.withConfig({
8498
- useProjectHostname: !1
8499
+ useProjectHostname: !1,
8500
+ ...hostResolution.apiHost === void 0 ? {} : {
8501
+ apiHost: hostResolution.apiHost
8502
+ }
8499
8503
  }), globalRequest = lazyRequest(globalClient);
8500
8504
  } catch (err) {
8501
8505
  return {
@@ -8509,11 +8513,15 @@ async function fetchGlobalUser(client) {
8509
8513
  reason: "the global-host sibling client cannot issue requests"
8510
8514
  };
8511
8515
  try {
8512
- return {
8513
- user: await globalRequest({
8514
- uri: "/users/me",
8515
- tag: REQUEST_TAG.accessResolveActor
8516
- })
8516
+ const user = await globalRequest({
8517
+ uri: "/users/me",
8518
+ tag: REQUEST_TAG.accessResolveActor
8519
+ }), id = usableId(user);
8520
+ return hostResolution.requireGlobalPrincipal && id !== void 0 && invariants.classifyPrincipalId(id).namespace === "project" ? {
8521
+ user: void 0,
8522
+ reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
8523
+ } : {
8524
+ user: user
8517
8525
  };
8518
8526
  } catch (err) {
8519
8527
  return {
@@ -8524,6 +8532,34 @@ async function fetchGlobalUser(client) {
8524
8532
  }
8525
8533
  }
8526
8534
 
8535
+ function resolveGlobalApiHost(client) {
8536
+ if (typeof client.config != "function") return {
8537
+ requireGlobalPrincipal: !1
8538
+ };
8539
+ const apiHost = client.config().apiHost;
8540
+ if (apiHost === void 0) return {
8541
+ requireGlobalPrincipal: !1
8542
+ };
8543
+ let parsed;
8544
+ try {
8545
+ parsed = new URL(apiHost);
8546
+ } catch {
8547
+ return {
8548
+ requireGlobalPrincipal: !0
8549
+ };
8550
+ }
8551
+ if (/^api\.sanity\.(io|work)$/.test(parsed.hostname)) return {
8552
+ requireGlobalPrincipal: !1
8553
+ };
8554
+ const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
8555
+ return match === null ? {
8556
+ requireGlobalPrincipal: !0
8557
+ } : (parsed.hostname = `api.sanity.${match[1]}`, {
8558
+ apiHost: parsed.origin,
8559
+ requireGlobalPrincipal: !0
8560
+ });
8561
+ }
8562
+
8527
8563
  async function fetchGrantsCached(requestFn, resourcePath) {
8528
8564
  try {
8529
8565
  return await fetchGrants({
@@ -12739,10 +12775,18 @@ const HISTORY_DISPLAY = {
12739
12775
  title: "Date value",
12740
12776
  description: "Date-only (YYYY-MM-DD) entry, no time component."
12741
12777
  },
12778
+ dueDate: {
12779
+ title: "Due date",
12780
+ description: "THE due date for a level — same value as a date, elevated so surfaces identify the deadline by kind."
12781
+ },
12742
12782
  datetime: {
12743
12783
  title: "Date / time value",
12744
12784
  description: "ISO-8601 timestamp entry."
12745
12785
  },
12786
+ dueDatetime: {
12787
+ title: "Due date / time",
12788
+ description: "THE due datetime for a level — same value as a date/time, the timestamp counterpart of a due date."
12789
+ },
12746
12790
  url: {
12747
12791
  title: "URL value",
12748
12792
  description: "Validated URL entry."
@@ -13023,6 +13067,8 @@ exports.parentRef = invariants.parentRef;
13023
13067
 
13024
13068
  exports.parseDefinitionSnapshot = invariants.parseDefinitionSnapshot;
13025
13069
 
13070
+ exports.parseDefinitionSnapshotValue = invariants.parseDefinitionSnapshotValue;
13071
+
13026
13072
  exports.parseGdr = invariants.parseGdr;
13027
13073
 
13028
13074
  exports.parseResourceGdr = invariants.parseResourceGdr;
@@ -13080,6 +13126,20 @@ Object.defineProperty(exports, "MAX_COUNTERFACTUAL_INDEX", {
13080
13126
  }
13081
13127
  });
13082
13128
 
13129
+ Object.defineProperty(exports, "NEUTRAL_MARK", {
13130
+ enumerable: !0,
13131
+ get: function() {
13132
+ return groqConditionDescribe.NEUTRAL_MARK;
13133
+ }
13134
+ });
13135
+
13136
+ Object.defineProperty(exports, "OUTCOME_MARKS", {
13137
+ enumerable: !0,
13138
+ get: function() {
13139
+ return groqConditionDescribe.OUTCOME_MARKS;
13140
+ }
13141
+ });
13142
+
13083
13143
  Object.defineProperty(exports, "analyzeCondition", {
13084
13144
  enumerable: !0,
13085
13145
  get: function() {
package/dist/index.d.cts CHANGED
@@ -20,6 +20,8 @@ import { humanize } from "@sanity/groq-condition-describe";
20
20
  import { InsightPhrase } from "@sanity/groq-condition-describe";
21
21
  import { isComparisonOp } from "@sanity/groq-condition-describe";
22
22
  import { MAX_COUNTERFACTUAL_INDEX } from "@sanity/groq-condition-describe";
23
+ import { NEUTRAL_MARK } from "@sanity/groq-condition-describe";
24
+ import { OUTCOME_MARKS } from "@sanity/groq-condition-describe";
23
25
  import { quoted } from "@sanity/groq-condition-describe";
24
26
  import type { SanityDocument } from "@sanity/types";
25
27
  import { ScopeAssignment } from "@sanity/groq-condition-describe";
@@ -2357,6 +2359,15 @@ export declare const DATA_MODEL_CHANGES: readonly [
2357
2359
  applicability: "detectable";
2358
2360
  summary: "Start and activity readiness use named polymorphic requirement arrays.";
2359
2361
  }>,
2362
+ Readonly<{
2363
+ id: "due-date-field-kinds";
2364
+ introducedInModel: 5;
2365
+ minReaderModel: 0;
2366
+ documentTypes: readonly ["definition", "instance"];
2367
+ compatibility: "additive";
2368
+ applicability: "detectable";
2369
+ summary: string;
2370
+ }>,
2360
2371
  ];
2361
2372
 
2362
2373
  /**
@@ -2381,7 +2392,7 @@ export declare const DATA_MODEL_MIN_READER = 4;
2381
2392
  * job. Declare every bump in `DATAMODEL.md`; the model-surface snapshot test
2382
2393
  * keeps undeclared drift red.
2383
2394
  */
2384
- export declare const DATA_MODEL_VERSION = 4;
2395
+ export declare const DATA_MODEL_VERSION = 5;
2385
2396
 
2386
2397
  export declare interface DataModelChange {
2387
2398
  readonly id: string;
@@ -4337,10 +4348,18 @@ export declare const FIELD_KIND_DISPLAY: {
4337
4348
  title: string;
4338
4349
  description: string;
4339
4350
  };
4351
+ dueDate: {
4352
+ title: string;
4353
+ description: string;
4354
+ };
4340
4355
  datetime: {
4341
4356
  title: string;
4342
4357
  description: string;
4343
4358
  };
4359
+ dueDatetime: {
4360
+ title: string;
4361
+ description: string;
4362
+ };
4344
4363
  url: {
4345
4364
  title: string;
4346
4365
  description: string;
@@ -4389,7 +4408,9 @@ declare const FIELD_VALUE_KINDS: readonly [
4389
4408
  "progress",
4390
4409
  "boolean",
4391
4410
  "date",
4411
+ "dueDate",
4392
4412
  "datetime",
4413
+ "dueDatetime",
4393
4414
  "url",
4394
4415
  "actor",
4395
4416
  "assignee",
@@ -4534,8 +4555,12 @@ export declare interface FieldValueMap {
4534
4555
  boolean: boolean | null;
4535
4556
  /** Date-only (`YYYY-MM-DD`), no time component. */
4536
4557
  date: string | null;
4558
+ /** THE due date of a level — same value as {@link FieldValueMap.date}. */
4559
+ dueDate: string | null;
4537
4560
  /** ISO-8601 timestamp. */
4538
4561
  datetime: string | null;
4562
+ /** THE due datetime of a level — same value as {@link FieldValueMap.datetime}. */
4563
+ dueDatetime: string | null;
4539
4564
  url: string | null;
4540
4565
  actor: Actor | null;
4541
4566
  /** A single {@link Assignee} — the singular of {@link FieldValueMap.assignees}. */
@@ -6368,6 +6393,8 @@ export declare function narrateAutonomyWaits(
6368
6393
  ctx: DescribeContext,
6369
6394
  ): string[];
6370
6395
 
6396
+ export { NEUTRAL_MARK };
6397
+
6371
6398
  /** The default logger: emit nothing. The engine's twin of `@sanity/telemetry`'s `noopLogger`. */
6372
6399
  export declare const noopTelemetry: WorkflowTelemetryLogger;
6373
6400
 
@@ -6470,6 +6497,8 @@ export declare interface OperationResult {
6470
6497
  ranOps?: OpAppliedSummary[];
6471
6498
  }
6472
6499
 
6500
+ export { OUTCOME_MARKS };
6501
+
6473
6502
  /**
6474
6503
  * The instance's direct parent — the last entry of the root-first
6475
6504
  * {@link WorkflowInstance.ancestors} chain; `undefined` for a root instance.
@@ -6496,6 +6525,16 @@ export declare function parseDefinitionSnapshot(
6496
6525
  instance: WorkflowInstance,
6497
6526
  ): WorkflowDefinition;
6498
6527
 
6528
+ /**
6529
+ * The canonical parser for an instance's frozen
6530
+ * {@link WorkflowInstance.definitionSnapshot}. Accepting the persisted pair
6531
+ * keeps compatibility scanners and full instance consumers on the same
6532
+ * contextual failure path.
6533
+ */
6534
+ export declare function parseDefinitionSnapshotValue(
6535
+ instance: Pick<WorkflowInstance, "_id" | "definitionSnapshot">,
6536
+ ): WorkflowDefinition;
6537
+
6499
6538
  export declare interface ParsedGdr {
6500
6539
  scheme: GdrScheme;
6501
6540
  /** For `dataset`: `<projectId>` */
@@ -6786,7 +6825,7 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6786
6825
  readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
6787
6826
  readonly expectedMinReaderModel: unknown;
6788
6827
  readonly engineMinReaderModel = 4;
6789
- readonly engineModelVersion = 4;
6828
+ readonly engineModelVersion = 5;
6790
6829
  readonly documentationUrl =
6791
6830
  "https://www.sanity.io/docs/editorial-workflows/prerelease";
6792
6831
  constructor(expectedMinReaderModel: unknown, context?: string);
@@ -8629,6 +8668,10 @@ export declare function toBareId(id: string): string;
8629
8668
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
8630
8669
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
8631
8670
  * `{label, status}` only (open ↔ done). Never a stored kind.
8671
+ *
8672
+ * The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
8673
+ * FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
8674
+ * and a repeating row has nothing to reserve.
8632
8675
  */
8633
8676
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
8634
8677
  type: "todoList";
@@ -9321,6 +9364,13 @@ export declare interface WorkflowAutonomy extends AutonomyAnswer {
9321
9364
  }
9322
9365
 
9323
9366
  export declare interface WorkflowClient {
9367
+ /**
9368
+ * Read the effective client configuration. The engine probes `apiHost`
9369
+ * before deriving the global `/users/me` sibling because `@sanity/client`
9370
+ * shallow-merges `withConfig` overrides and otherwise preserves an explicit
9371
+ * project host even when `useProjectHostname` is set to `false`.
9372
+ */
9373
+ config?: () => WorkflowClientConfig;
9324
9374
  fetch: <T = unknown>(
9325
9375
  query: string,
9326
9376
  params?: Record<string, unknown>,
@@ -9448,6 +9498,8 @@ export declare interface WorkflowClientConfig {
9448
9498
  resource?: WorkflowResource;
9449
9499
  projectId?: string;
9450
9500
  dataset?: string;
9501
+ /** Explicit API origin, mirroring `@sanity/client`'s `apiHost`. */
9502
+ apiHost?: string;
9451
9503
  apiVersion?: string;
9452
9504
  requestTagPrefix?: string;
9453
9505
  /**
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ import { humanize } from "@sanity/groq-condition-describe";
20
20
  import { InsightPhrase } from "@sanity/groq-condition-describe";
21
21
  import { isComparisonOp } from "@sanity/groq-condition-describe";
22
22
  import { MAX_COUNTERFACTUAL_INDEX } from "@sanity/groq-condition-describe";
23
+ import { NEUTRAL_MARK } from "@sanity/groq-condition-describe";
24
+ import { OUTCOME_MARKS } from "@sanity/groq-condition-describe";
23
25
  import { quoted } from "@sanity/groq-condition-describe";
24
26
  import type { SanityDocument } from "@sanity/types";
25
27
  import { ScopeAssignment } from "@sanity/groq-condition-describe";
@@ -2357,6 +2359,15 @@ export declare const DATA_MODEL_CHANGES: readonly [
2357
2359
  applicability: "detectable";
2358
2360
  summary: "Start and activity readiness use named polymorphic requirement arrays.";
2359
2361
  }>,
2362
+ Readonly<{
2363
+ id: "due-date-field-kinds";
2364
+ introducedInModel: 5;
2365
+ minReaderModel: 0;
2366
+ documentTypes: readonly ["definition", "instance"];
2367
+ compatibility: "additive";
2368
+ applicability: "detectable";
2369
+ summary: string;
2370
+ }>,
2360
2371
  ];
2361
2372
 
2362
2373
  /**
@@ -2381,7 +2392,7 @@ export declare const DATA_MODEL_MIN_READER = 4;
2381
2392
  * job. Declare every bump in `DATAMODEL.md`; the model-surface snapshot test
2382
2393
  * keeps undeclared drift red.
2383
2394
  */
2384
- export declare const DATA_MODEL_VERSION = 4;
2395
+ export declare const DATA_MODEL_VERSION = 5;
2385
2396
 
2386
2397
  export declare interface DataModelChange {
2387
2398
  readonly id: string;
@@ -4337,10 +4348,18 @@ export declare const FIELD_KIND_DISPLAY: {
4337
4348
  title: string;
4338
4349
  description: string;
4339
4350
  };
4351
+ dueDate: {
4352
+ title: string;
4353
+ description: string;
4354
+ };
4340
4355
  datetime: {
4341
4356
  title: string;
4342
4357
  description: string;
4343
4358
  };
4359
+ dueDatetime: {
4360
+ title: string;
4361
+ description: string;
4362
+ };
4344
4363
  url: {
4345
4364
  title: string;
4346
4365
  description: string;
@@ -4389,7 +4408,9 @@ declare const FIELD_VALUE_KINDS: readonly [
4389
4408
  "progress",
4390
4409
  "boolean",
4391
4410
  "date",
4411
+ "dueDate",
4392
4412
  "datetime",
4413
+ "dueDatetime",
4393
4414
  "url",
4394
4415
  "actor",
4395
4416
  "assignee",
@@ -4534,8 +4555,12 @@ export declare interface FieldValueMap {
4534
4555
  boolean: boolean | null;
4535
4556
  /** Date-only (`YYYY-MM-DD`), no time component. */
4536
4557
  date: string | null;
4558
+ /** THE due date of a level — same value as {@link FieldValueMap.date}. */
4559
+ dueDate: string | null;
4537
4560
  /** ISO-8601 timestamp. */
4538
4561
  datetime: string | null;
4562
+ /** THE due datetime of a level — same value as {@link FieldValueMap.datetime}. */
4563
+ dueDatetime: string | null;
4539
4564
  url: string | null;
4540
4565
  actor: Actor | null;
4541
4566
  /** A single {@link Assignee} — the singular of {@link FieldValueMap.assignees}. */
@@ -6368,6 +6393,8 @@ export declare function narrateAutonomyWaits(
6368
6393
  ctx: DescribeContext,
6369
6394
  ): string[];
6370
6395
 
6396
+ export { NEUTRAL_MARK };
6397
+
6371
6398
  /** The default logger: emit nothing. The engine's twin of `@sanity/telemetry`'s `noopLogger`. */
6372
6399
  export declare const noopTelemetry: WorkflowTelemetryLogger;
6373
6400
 
@@ -6470,6 +6497,8 @@ export declare interface OperationResult {
6470
6497
  ranOps?: OpAppliedSummary[];
6471
6498
  }
6472
6499
 
6500
+ export { OUTCOME_MARKS };
6501
+
6473
6502
  /**
6474
6503
  * The instance's direct parent — the last entry of the root-first
6475
6504
  * {@link WorkflowInstance.ancestors} chain; `undefined` for a root instance.
@@ -6496,6 +6525,16 @@ export declare function parseDefinitionSnapshot(
6496
6525
  instance: WorkflowInstance,
6497
6526
  ): WorkflowDefinition;
6498
6527
 
6528
+ /**
6529
+ * The canonical parser for an instance's frozen
6530
+ * {@link WorkflowInstance.definitionSnapshot}. Accepting the persisted pair
6531
+ * keeps compatibility scanners and full instance consumers on the same
6532
+ * contextual failure path.
6533
+ */
6534
+ export declare function parseDefinitionSnapshotValue(
6535
+ instance: Pick<WorkflowInstance, "_id" | "definitionSnapshot">,
6536
+ ): WorkflowDefinition;
6537
+
6499
6538
  export declare interface ParsedGdr {
6500
6539
  scheme: GdrScheme;
6501
6540
  /** For `dataset`: `<projectId>` */
@@ -6786,7 +6825,7 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6786
6825
  readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
6787
6826
  readonly expectedMinReaderModel: unknown;
6788
6827
  readonly engineMinReaderModel = 4;
6789
- readonly engineModelVersion = 4;
6828
+ readonly engineModelVersion = 5;
6790
6829
  readonly documentationUrl =
6791
6830
  "https://www.sanity.io/docs/editorial-workflows/prerelease";
6792
6831
  constructor(expectedMinReaderModel: unknown, context?: string);
@@ -8629,6 +8668,10 @@ export declare function toBareId(id: string): string;
8629
8668
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
8630
8669
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
8631
8670
  * `{label, status}` only (open ↔ done). Never a stored kind.
8671
+ *
8672
+ * The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
8673
+ * FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
8674
+ * and a repeating row has nothing to reserve.
8632
8675
  */
8633
8676
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
8634
8677
  type: "todoList";
@@ -9321,6 +9364,13 @@ export declare interface WorkflowAutonomy extends AutonomyAnswer {
9321
9364
  }
9322
9365
 
9323
9366
  export declare interface WorkflowClient {
9367
+ /**
9368
+ * Read the effective client configuration. The engine probes `apiHost`
9369
+ * before deriving the global `/users/me` sibling because `@sanity/client`
9370
+ * shallow-merges `withConfig` overrides and otherwise preserves an explicit
9371
+ * project host even when `useProjectHostname` is set to `false`.
9372
+ */
9373
+ config?: () => WorkflowClientConfig;
9324
9374
  fetch: <T = unknown>(
9325
9375
  query: string,
9326
9376
  params?: Record<string, unknown>,
@@ -9448,6 +9498,8 @@ export declare interface WorkflowClientConfig {
9448
9498
  resource?: WorkflowResource;
9449
9499
  projectId?: string;
9450
9500
  dataset?: string;
9501
+ /** Explicit API origin, mirroring `@sanity/client`'s `apiHost`. */
9502
+ apiHost?: string;
9451
9503
  apiVersion?: string;
9452
9504
  requestTagPrefix?: string;
9453
9505
  /**
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { terminalState, andConditions, deriveActivityKind, parseDefinitionSnapshot, CALLER_BOUND_VARS, START_REQUIREMENT_VARS, CONDITION_VARS, isSubjectEntry, isUnevaluable, ContractViolationError, isStartableDefinition, conditionFieldReadNames, rethrowWithContext, isGdr, errorMessage, conditionParameterNames, START_FILTER_VARS, gdrFromResource, selfGdr, isSingleDocRefKind, parentRef, actorFulfillsRole, toBareId, WorkflowError, sameResource, resourceFromParsed, tryParseGdr, isTerminalActivityStatus, FieldValueShapeError, validateFieldValue, validateFieldAppendItem, evaluateCondition, isSingleDocRefEntry, choiceValueIssues, scalarValidationIssues, StoredFieldOpSchema, formatIssues, conditionSyntaxIssues, checkWorkflowInvariants, formatIssuePath, isGuardReadExpr, conditionEffectReads, EFFECTS_READ, datasetResourceParts, evaluatePredicates, WORKFLOW_DEFINITION_TYPE, tagScopeFilter, isCascadeFired, WORKFLOW_INSTANCE_TYPE, parseGdr, isGdrUri, gdrRef, isInputSourced, parseFieldValue, VersionSpecificDatasetGdrError, toPhysicalGdr, isBareSeedId, tolerantEntries, NonEmptyString, FIELD_VALUE_KINDS, tolerantObject, ActorShape, IsoTimestamp, ACTIVITY_STATUSES, GdrShape, DRIVER_KINDS, FIELD_SCOPES, fieldValueSchemas, parsePersistedDoc, ACTOR_KINDS, classifyPrincipalId, assertReadableModel, InstanceNotFoundError, modelStampFor, evaluateConditionOutcome, runGroq, FIELD_READ, MUTATION_GUARD_ACTIONS, resourceGdr, minReaderModelOf, resourceFromGdrUri, refTypeIssues, rejectedRefTypes, DOCUMENT_VALUE_PERMISSIONS, lakePrincipalId, driverKind, EffectNotFoundError, deriveExecutorClassification, validateTag, extractDocumentId, parseStoredDefinition, validateResourceAliasName, labelFor, DefinitionNotFoundError, definitionDocId, SpawnContractsInvalidError, gdrResourcePrefix, RESOURCE_ALIAS_NAME_SOURCE, isUnprimed, DefinitionInUseError, assertReaderModelAcknowledgement, isParseableInstant, groupMembershipNames } from "./_chunks-es/invariants.js";
2
2
 
3
- import { ACTION_SEMANTICS, ACTIVITY_KINDS, ANONYMOUS_IDENTITY, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_TRANSITION_WHEN, EXECUTOR_CLASSIFICATIONS, FILTER_SCOPE_VARS, GROUP_KINDS, GUARD_PREDICATE_VARS, ModelVersionAheadError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, SYSTEM_IDENTITY, clientConfigFromResource, fieldTreeShape, gdrUri, isNotesEntry, isTodoListEntry, isTodoListItem, modelVersionOf, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, releaseDocId, releaseRef, requiredModelFeatures, requiredReaderModel, resourceAliasesToMap, schemaTreeShape, startKindOf } from "./_chunks-es/invariants.js";
3
+ import { ACTION_SEMANTICS, ACTIVITY_KINDS, ANONYMOUS_IDENTITY, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_TRANSITION_WHEN, EXECUTOR_CLASSIFICATIONS, FILTER_SCOPE_VARS, GROUP_KINDS, GUARD_PREDICATE_VARS, ModelVersionAheadError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, SYSTEM_IDENTITY, clientConfigFromResource, fieldTreeShape, gdrUri, isNotesEntry, isTodoListEntry, isTodoListItem, modelVersionOf, parseDefinitionSnapshotValue, parseResourceGdr, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, releaseDocId, releaseRef, requiredModelFeatures, requiredReaderModel, resourceAliasesToMap, schemaTreeShape, startKindOf } from "./_chunks-es/invariants.js";
4
4
 
5
5
  import { atomNode, dedupeBy, analyzeCondition, atomReadsDataset, checklistLines as checklistLines$1, phrase, quoted, listAnd, describeAtom as describeAtom$1, describeCondition as describeCondition$1, guillemets, formatValue, humanize, listOr, scopeReadOf, describeRead, explainCondition, dedupeReads, whatIfCondition, MAX_COUNTERFACTUAL_INDEX } from "@sanity/groq-condition-describe";
6
6
 
7
- import { MAX_COUNTERFACTUAL_INDEX as MAX_COUNTERFACTUAL_INDEX2, analyzeCondition as analyzeCondition2, atomReadsDataset as atomReadsDataset2, explainCondition as explainCondition2, formatRead, guillemets as guillemets2, humanize as humanize2, isComparisonOp, quoted as quoted2, sentenceCase, whatIfCondition as whatIfCondition2, withAssignment } from "@sanity/groq-condition-describe";
7
+ import { MAX_COUNTERFACTUAL_INDEX as MAX_COUNTERFACTUAL_INDEX2, NEUTRAL_MARK, OUTCOME_MARKS, analyzeCondition as analyzeCondition2, atomReadsDataset as atomReadsDataset2, explainCondition as explainCondition2, formatRead, guillemets as guillemets2, humanize as humanize2, isComparisonOp, quoted as quoted2, sentenceCase, whatIfCondition as whatIfCondition2, withAssignment } from "@sanity/groq-condition-describe";
8
8
 
9
9
  import { evaluate, parse } from "groq-js";
10
10
 
@@ -4113,7 +4113,7 @@ const OptionalRefTypes = v.exactOptional(v.array(v.string())), ResolvedFieldEntr
4113
4113
  })), v.looseObject(tolerantEntries()({
4114
4114
  ...fieldArm("subject", fieldValueSchemas.subject),
4115
4115
  types: OptionalRefTypes
4116
- })), v.looseObject(tolerantEntries()(fieldArm("release.ref", fieldValueSchemas["release.ref"]))), v.looseObject(tolerantEntries()(fieldArm("string", fieldValueSchemas.string))), v.looseObject(tolerantEntries()(fieldArm("text", fieldValueSchemas.text))), v.looseObject(tolerantEntries()(fieldArm("number", fieldValueSchemas.number))), v.looseObject(tolerantEntries()(fieldArm("progress", fieldValueSchemas.progress))), v.looseObject(tolerantEntries()(fieldArm("boolean", fieldValueSchemas.boolean))), v.looseObject(tolerantEntries()(fieldArm("date", fieldValueSchemas.date))), v.looseObject(tolerantEntries()(fieldArm("datetime", fieldValueSchemas.datetime))), v.looseObject(tolerantEntries()(fieldArm("url", fieldValueSchemas.url))), v.looseObject(tolerantEntries()(fieldArm("actor", fieldValueSchemas.actor))), v.looseObject(tolerantEntries()(fieldArm("assignee", fieldValueSchemas.assignee))), v.looseObject(tolerantEntries()(fieldArm("assignees", fieldValueSchemas.assignees))), v.looseObject(tolerantEntries()({
4116
+ })), v.looseObject(tolerantEntries()(fieldArm("release.ref", fieldValueSchemas["release.ref"]))), v.looseObject(tolerantEntries()(fieldArm("string", fieldValueSchemas.string))), v.looseObject(tolerantEntries()(fieldArm("text", fieldValueSchemas.text))), v.looseObject(tolerantEntries()(fieldArm("number", fieldValueSchemas.number))), v.looseObject(tolerantEntries()(fieldArm("progress", fieldValueSchemas.progress))), v.looseObject(tolerantEntries()(fieldArm("boolean", fieldValueSchemas.boolean))), v.looseObject(tolerantEntries()(fieldArm("date", fieldValueSchemas.date))), v.looseObject(tolerantEntries()(fieldArm("dueDate", fieldValueSchemas.dueDate))), v.looseObject(tolerantEntries()(fieldArm("datetime", fieldValueSchemas.datetime))), v.looseObject(tolerantEntries()(fieldArm("dueDatetime", fieldValueSchemas.dueDatetime))), v.looseObject(tolerantEntries()(fieldArm("url", fieldValueSchemas.url))), v.looseObject(tolerantEntries()(fieldArm("actor", fieldValueSchemas.actor))), v.looseObject(tolerantEntries()(fieldArm("assignee", fieldValueSchemas.assignee))), v.looseObject(tolerantEntries()(fieldArm("assignees", fieldValueSchemas.assignees))), v.looseObject(tolerantEntries()({
4117
4117
  ...fieldArm("object", v.union([ v.null(), UnknownRecord ])),
4118
4118
  fields: v.array(PersistedFieldShapeSchema)
4119
4119
  })), v.looseObject(tolerantEntries()({
@@ -8477,9 +8477,13 @@ async function fetchGlobalUser(client) {
8477
8477
  reason: "the client cannot reach the global API host (no withConfig)"
8478
8478
  };
8479
8479
  let globalRequest, globalClient;
8480
+ const hostResolution = resolveGlobalApiHost(client);
8480
8481
  try {
8481
8482
  globalClient = client.withConfig({
8482
- useProjectHostname: !1
8483
+ useProjectHostname: !1,
8484
+ ...hostResolution.apiHost === void 0 ? {} : {
8485
+ apiHost: hostResolution.apiHost
8486
+ }
8483
8487
  }), globalRequest = lazyRequest(globalClient);
8484
8488
  } catch (err) {
8485
8489
  return {
@@ -8493,11 +8497,15 @@ async function fetchGlobalUser(client) {
8493
8497
  reason: "the global-host sibling client cannot issue requests"
8494
8498
  };
8495
8499
  try {
8496
- return {
8497
- user: await globalRequest({
8498
- uri: "/users/me",
8499
- tag: REQUEST_TAG.accessResolveActor
8500
- })
8500
+ const user = await globalRequest({
8501
+ uri: "/users/me",
8502
+ tag: REQUEST_TAG.accessResolveActor
8503
+ }), id = usableId(user);
8504
+ return hostResolution.requireGlobalPrincipal && id !== void 0 && classifyPrincipalId(id).namespace === "project" ? {
8505
+ user: void 0,
8506
+ reason: `global-host /users/me returned project-scoped principal "${id}"; the sibling client is still bound to a project API host`
8507
+ } : {
8508
+ user: user
8501
8509
  };
8502
8510
  } catch (err) {
8503
8511
  return {
@@ -8508,6 +8516,34 @@ async function fetchGlobalUser(client) {
8508
8516
  }
8509
8517
  }
8510
8518
 
8519
+ function resolveGlobalApiHost(client) {
8520
+ if (typeof client.config != "function") return {
8521
+ requireGlobalPrincipal: !1
8522
+ };
8523
+ const apiHost = client.config().apiHost;
8524
+ if (apiHost === void 0) return {
8525
+ requireGlobalPrincipal: !1
8526
+ };
8527
+ let parsed;
8528
+ try {
8529
+ parsed = new URL(apiHost);
8530
+ } catch {
8531
+ return {
8532
+ requireGlobalPrincipal: !0
8533
+ };
8534
+ }
8535
+ if (/^api\.sanity\.(io|work)$/.test(parsed.hostname)) return {
8536
+ requireGlobalPrincipal: !1
8537
+ };
8538
+ const match = /^[^.]+\.api\.sanity\.(io|work)$/.exec(parsed.hostname);
8539
+ return match === null ? {
8540
+ requireGlobalPrincipal: !0
8541
+ } : (parsed.hostname = `api.sanity.${match[1]}`, {
8542
+ apiHost: parsed.origin,
8543
+ requireGlobalPrincipal: !0
8544
+ });
8545
+ }
8546
+
8511
8547
  async function fetchGrantsCached(requestFn, resourcePath) {
8512
8548
  try {
8513
8549
  return await fetchGrants({
@@ -12723,10 +12759,18 @@ const HISTORY_DISPLAY = {
12723
12759
  title: "Date value",
12724
12760
  description: "Date-only (YYYY-MM-DD) entry, no time component."
12725
12761
  },
12762
+ dueDate: {
12763
+ title: "Due date",
12764
+ description: "THE due date for a level — same value as a date, elevated so surfaces identify the deadline by kind."
12765
+ },
12726
12766
  datetime: {
12727
12767
  title: "Date / time value",
12728
12768
  description: "ISO-8601 timestamp entry."
12729
12769
  },
12770
+ dueDatetime: {
12771
+ title: "Due date / time",
12772
+ description: "THE due datetime for a level — same value as a date/time, the timestamp counterpart of a due date."
12773
+ },
12730
12774
  url: {
12731
12775
  title: "URL value",
12732
12776
  description: "Validated URL entry."
@@ -12877,4 +12921,4 @@ function displayDescription(typeKey) {
12877
12921
  if (typeKey) return DISPLAY[typeKey]?.description;
12878
12922
  }
12879
12923
 
12880
- export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, OP_DISPLAY, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activityAutonomyOf, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientProjectUserDirectory, compileGuard, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionsListGroq, deniedGuardLabels, deniedGuardRefs, denyingGuards, deployStageGuards, deriveActivityKind, deriveExecutorClassification, deriveWorkflowAutonomy, describeAtom, describeAutonomyWait, describeCondition, describeDefinition, describeFieldInsight, describeNode, describeSite, describeSiteHeading, diagnoseInputFromEvaluation, diagnoseInstance, diffEntry, displayDescription, displayTitle, documentActionDenials, documentPrefilter, driverKind, effectOutputsMap, entryDocRefs, errorMessage, evaluateFromSnapshot, evaluateMutationGuard, evaluateStartFilter, expandResourceAliases, explainCondition2 as explainCondition, explainStartRequirement, extractDocumentId, fieldTreeShape, findCurrentActivityEntry, findOpenStageEntry, formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, inFlightFilter, initialFieldIssues, instanceDocId, instanceGuardQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseGdr, parseGuardDocument, parseInstanceDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, stageAutonomyOf, startFieldsParam, startKindOf, startRefusal, stripSystemFields, subjectDenialLabels, subscriptionDocument, subscriptionDocumentsForInstance, sweepStaleClaims, tagScopeFilter, terminalState, toBareId, tryParseGdr, unboundRequirementReads, unsatisfiedTransitionSummaries, validateDefinition, validateTag, verdictGuardsForInstance, wallClock, whatIfCondition2 as whatIfCondition, withAssignment, workflow };
12924
+ export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_KIND_DISPLAY, ACTOR_KINDS, ANONYMOUS_IDENTITY, AUTHORING_DISPLAY, ActionDisabledError, ActionParamsInvalidError, CONDITION_VARS, CONTEXT_ENTRY_DISPLAY, CascadeLimitError, ConcurrentCommitEffectOpsError, ConcurrentCompleteEffectError, ConcurrentEditFieldError, ConcurrentFireActionError, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_CONTENT_PERSPECTIVE, DEFAULT_EFFECT_LEASE_MS, DEFAULT_IDEMPOTENCY_TTL_MS, DEFAULT_TRANSITION_WHEN, DISPLAY, DRIVER_KINDS, DRIVER_KIND_DISPLAY, DefinitionInUseError, DefinitionNotFoundError, EFFECT_COMMIT_DISPATCH_CAP, EFFECT_COMMIT_QUEUE_DEPTH, ENGINE_API_VERSION, EXECUTION_KINDS, EXECUTOR_CLASSIFICATIONS, EXECUTOR_CLASSIFICATION_DISPLAY, EditFieldDeniedError, EffectCommitQueueOverflowError, EffectNotFoundError, EffectOpsInvalidError, EffectOutputsInvalidError, FIELD_KIND_DISPLAY, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GROUP_KIND_DISPLAY, GUARD_DOC_TYPE, GUARD_OWNER, GUARD_PREDICATE_VARS, HISTORY_DISPLAY, InitialFieldsInvalidError, InstanceNotFoundError, MAX_COUNTERFACTUAL_INDEX2 as MAX_COUNTERFACTUAL_INDEX, MissingHandlerError, ModelVersionAheadError, MutationGuardDeniedError, MutationGuardDocSchema, NEUTRAL_MARK, OP_DISPLAY, OUTCOME_MARKS, PartialGuardDeployError, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, ReaderModelAcknowledgementError, RefResourceUndeclaredError, RequiredFieldNotProvidedError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StaleEffectClaimError, StartNotAllowedError, StartNotPrimedError, StartNotSettledError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowActionFired, WorkflowActivityReset, WorkflowDefinitionDeleted, WorkflowDefinitionDeployed, WorkflowEffectCompleted, WorkflowEffectStateReported, WorkflowEffectsDrained, WorkflowError, WorkflowFieldEdited, WorkflowInstanceAborted, WorkflowInstanceSchema, WorkflowInstanceStarted, WorkflowInstanceTicked, WorkflowStageSet, WorkflowStageTransitioned, WorkflowStateDivergedError, abortReason, acceptsDocumentType, aclPathForResource, actionDisabledDetail, actionRendering, actionVerdict, activityAutonomyOf, analyzeCondition2 as analyzeCondition, applicableDefinitions, assertReadableModel, assertReaderModelAcknowledgement, atomReadsDataset2 as atomReadsDataset, autonomySummary, availableActions, buildInitialFields, buildSnapshot, checklistLines, classifyPrincipalId, clientConfigFromResource, clientProjectUserDirectory, compileGuard, computeDiffEntries, conditionFieldReadNames, conditionSitesOf, contentDocQuery, contentDraftFallback, contentReleaseName, contextMap, createEngine, createTelemetryIntake, datasetResourceParts, defaultLoggerFactory, definitionDeployedData, definitionLookupGroq, definitionsListGroq, deniedGuardLabels, deniedGuardRefs, denyingGuards, deployStageGuards, deriveActivityKind, deriveExecutorClassification, deriveWorkflowAutonomy, describeAtom, describeAutonomyWait, describeCondition, describeDefinition, describeFieldInsight, describeNode, describeSite, describeSiteHeading, diagnoseInputFromEvaluation, diagnoseInstance, diffEntry, displayDescription, displayTitle, documentActionDenials, documentPrefilter, driverKind, effectOutputsMap, entryDocRefs, errorMessage, evaluateFromSnapshot, evaluateMutationGuard, evaluateStartFilter, expandResourceAliases, explainCondition2 as explainCondition, explainStartRequirement, extractDocumentId, fieldTreeShape, findCurrentActivityEntry, findOpenStageEntry, formatRead, gdrFromResource, gdrRef, gdrUri, groupMembershipNames, groupSitesOf, guardMatches, guardsForDefinition, guardsForInstance, guardsForResource, guillemets2 as guillemets, hasSingleSubjectRequirement, hashDefinitionContent, humanize2 as humanize, inFlightFilter, initialFieldIssues, instanceDocId, instanceGuardQuery, instanceWatchesDocument, instancesGuardQuery, instancesQuery, isCascadeFired, isClaimExpired, isClientProjectUser, isComparisonOp, isDefinitionApplicable, isFilterScopedOut, isGdr, isInputSourced, isNotesEntry, isProjectUserNotFoundError, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTelemetryEnvDenied, isTerminalActivityStatus, isTerminalStage, isTodoListEntry, isTodoListItem, isUnprimed, lakeGuardId, lakePrincipalId, latestDefinitionsGroq, latestDeployedDefinitions, lintEffectOutputs, minReaderModelOf, missingRequiredInputs, modelVersionOf, narrateAutonomyWaits, noopTelemetry, parentRef, parseDefinitionInput, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseGdr, parseGuardDocument, parseInstanceDocument, parseResourceGdr, processShellUserProperties, projectStartSliceRow, projectToWatchRef, quoted2 as quoted, readInstanceDoc, readsRaw, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refsOf, rejectedRefTypes, releaseDocId, releaseRef, remediationsFor, requiredModelFeatures, requiredReaderModel, resolveAccess, resolveActor, resolveClientActor, resolveFieldEntry$1 as resolveFieldEntry, resourceAliasesToMap, resourceFromParsed, resourceGdr, retractStageGuards, sameResource, scalarValidationIssues, schemaTreeShape, sentenceCase, silentLogger, singleSubjectRequirementRefused, stageAutonomyOf, startFieldsParam, startKindOf, startRefusal, stripSystemFields, subjectDenialLabels, subscriptionDocument, subscriptionDocumentsForInstance, sweepStaleClaims, tagScopeFilter, terminalState, toBareId, tryParseGdr, unboundRequirementReads, unsatisfiedTransitionSummaries, validateDefinition, validateTag, verdictGuardsForInstance, wallClock, whatIfCondition2 as whatIfCondition, withAssignment, workflow };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/workflow-engine",
3
- "version": "0.22.0",
3
+ "version": "0.24.0",
4
4
  "description": "Workflow / BPM engine for Sanity content — define workflows as data, run them as instances against a Sanity client.",
5
5
  "keywords": [
6
6
  "bpm",
@@ -53,7 +53,7 @@
53
53
  "@sanity/types": "^5.28.0",
54
54
  "groq-js": "^1.30.2",
55
55
  "valibot": "^1.4.1",
56
- "@sanity/groq-condition-describe": "0.3.0"
56
+ "@sanity/groq-condition-describe": "0.4.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@sanity-labs/client-fake-for-test": "^0.10.0",