@sanity/workflow-engine 0.23.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,27 @@
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
+
3
25
  ## 0.23.0
4
26
 
5
27
  ### Minor 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
+ }
3180
3208
  }
3181
3209
 
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({
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
+ }) ]);
3221
+ }
3222
+
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;
@@ -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
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()({
@@ -12775,10 +12775,18 @@ const HISTORY_DISPLAY = {
12775
12775
  title: "Date value",
12776
12776
  description: "Date-only (YYYY-MM-DD) entry, no time component."
12777
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
+ },
12778
12782
  datetime: {
12779
12783
  title: "Date / time value",
12780
12784
  description: "ISO-8601 timestamp entry."
12781
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
+ },
12782
12790
  url: {
12783
12791
  title: "URL value",
12784
12792
  description: "Validated URL entry."
@@ -13118,6 +13126,20 @@ Object.defineProperty(exports, "MAX_COUNTERFACTUAL_INDEX", {
13118
13126
  }
13119
13127
  });
13120
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
+
13121
13143
  Object.defineProperty(exports, "analyzeCondition", {
13122
13144
  enumerable: !0,
13123
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.
@@ -6796,7 +6825,7 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6796
6825
  readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
6797
6826
  readonly expectedMinReaderModel: unknown;
6798
6827
  readonly engineMinReaderModel = 4;
6799
- readonly engineModelVersion = 4;
6828
+ readonly engineModelVersion = 5;
6800
6829
  readonly documentationUrl =
6801
6830
  "https://www.sanity.io/docs/editorial-workflows/prerelease";
6802
6831
  constructor(expectedMinReaderModel: unknown, context?: string);
@@ -8639,6 +8668,10 @@ export declare function toBareId(id: string): string;
8639
8668
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
8640
8669
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
8641
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.
8642
8675
  */
8643
8676
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
8644
8677
  type: "todoList";
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.
@@ -6796,7 +6825,7 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6796
6825
  readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
6797
6826
  readonly expectedMinReaderModel: unknown;
6798
6827
  readonly engineMinReaderModel = 4;
6799
- readonly engineModelVersion = 4;
6828
+ readonly engineModelVersion = 5;
6800
6829
  readonly documentationUrl =
6801
6830
  "https://www.sanity.io/docs/editorial-workflows/prerelease";
6802
6831
  constructor(expectedMinReaderModel: unknown, context?: string);
@@ -8639,6 +8668,10 @@ export declare function toBareId(id: string): string;
8639
8668
  * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object
8640
8669
  * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
8641
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.
8642
8675
  */
8643
8676
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
8644
8677
  type: "todoList";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { ACTION_SEMANTICS, ACTIVITY_KINDS, ANONYMOUS_IDENTITY, DATA_MODEL_CHANGE
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()({
@@ -12759,10 +12759,18 @@ const HISTORY_DISPLAY = {
12759
12759
  title: "Date value",
12760
12760
  description: "Date-only (YYYY-MM-DD) entry, no time component."
12761
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
+ },
12762
12766
  datetime: {
12763
12767
  title: "Date / time value",
12764
12768
  description: "ISO-8601 timestamp entry."
12765
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
+ },
12766
12774
  url: {
12767
12775
  title: "URL value",
12768
12776
  description: "Validated URL entry."
@@ -12913,4 +12921,4 @@ function displayDescription(typeKey) {
12913
12921
  if (typeKey) return DISPLAY[typeKey]?.description;
12914
12922
  }
12915
12923
 
12916
- 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, 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 };
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.23.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",