@sanity/workflow-engine 0.23.0 → 0.25.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 +80 -0
- package/DATAMODEL.md +36 -0
- package/dist/_chunks-cjs/invariants.cjs +110 -22
- package/dist/_chunks-es/invariants.js +107 -23
- package/dist/define.d.cts +6 -0
- package/dist/define.d.ts +6 -0
- package/dist/index.cjs +120 -21
- package/dist/index.d.cts +85 -21
- package/dist/index.d.ts +85 -21
- package/dist/index.js +105 -24
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
# @sanity/workflow-engine
|
|
2
2
|
|
|
3
|
+
## 0.25.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 177d600: Deployed workflow environment tags are now discoverable.
|
|
8
|
+
|
|
9
|
+
The engine gains two cross-partition GROQ builders: `deployedTagsGroq()` lists
|
|
10
|
+
every tag holding a deployed definition in a resource, and
|
|
11
|
+
`definitionTagsGroq()` narrows that to one definition name via `$definition`.
|
|
12
|
+
Both deliberately span tag partitions — every other read is tag-scoped, and
|
|
13
|
+
`workflow.query` refuses GROQ that isn't — so they answer "which environments
|
|
14
|
+
exist here" for a caller holding a resource but no tag. They report what is
|
|
15
|
+
_observed_: a tag with nothing deployed does not appear.
|
|
16
|
+
|
|
17
|
+
The stdio MCP server adds a `list_workflow_tags` tool taking a
|
|
18
|
+
`workflow_resource` and no tag. It is registered by the host rather than exported
|
|
19
|
+
as a tool def, because a def is only ever handed an engine and an engine is
|
|
20
|
+
pinned to one tag. `LIST_WORKFLOW_TAGS_TOOL_NAME` and
|
|
21
|
+
`LIST_WORKFLOW_TAGS_DESCRIPTION` are exported so an embedding host registers the
|
|
22
|
+
same capability under the same name without re-authoring the model-facing
|
|
23
|
+
wording. The `tag` parameter's description now points an agent at that tool where
|
|
24
|
+
a server offers it and at the user otherwise, and requires confirmation either
|
|
25
|
+
way — having the list does not license picking from it.
|
|
26
|
+
|
|
27
|
+
Both registration paths share one outcome path, `withToolTelemetry`, so the
|
|
28
|
+
result envelope, error rendering, and the `Editorial Workflows MCP Tool Called`
|
|
29
|
+
event cannot diverge between a def-backed tool and a host-registered one. Tag
|
|
30
|
+
discovery reports its adoption event like every other tool, and because it names
|
|
31
|
+
a resource it can also initialize the stdio server's deferred telemetry shell —
|
|
32
|
+
which matters when discovery is an agent's first call.
|
|
33
|
+
|
|
34
|
+
The CLI's definition-tags probe runs the engine's builder instead of its own
|
|
35
|
+
copy of the query, so its `params` key is `definition` rather than `name`, and
|
|
36
|
+
the tag partitions it names in an ambiguity error arrive sorted from the lake.
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- fc12989: Fixes actor resolution failing with `principal id "…" is not an account-global
|
|
41
|
+
user id` for a session scoped to a single project, such as a SAML-SSO Studio
|
|
42
|
+
session.
|
|
43
|
+
|
|
44
|
+
`actor.id` is always the account-global user id, and the id's namespace decides
|
|
45
|
+
which read supplies it rather than the host that answered. Whichever `/users/me`
|
|
46
|
+
read returns an already-account-global id supplies it; a project-scoped id is
|
|
47
|
+
bridged to its account-global form first — by string surgery for an
|
|
48
|
+
`e-<globalId>` principal, otherwise through the project's own user directory
|
|
49
|
+
(`/projects/<id>/users/<principal>` → `sanityUserId`). A SAML-SSO session
|
|
50
|
+
resolves through that directory, because the global host holds no
|
|
51
|
+
account-global record for it.
|
|
52
|
+
|
|
53
|
+
A session whose id is already account-global issues no directory request. A
|
|
54
|
+
project-scoped id that no route can bridge is refused, naming both failed
|
|
55
|
+
routes.
|
|
56
|
+
|
|
57
|
+
The project-user directory admits only a row answering the id it asked for,
|
|
58
|
+
matching the batched member join: a row for another principal reports
|
|
59
|
+
inaccessible rather than resolving to that person's identity.
|
|
60
|
+
|
|
61
|
+
## 0.24.0
|
|
62
|
+
|
|
63
|
+
### Minor Changes
|
|
64
|
+
|
|
65
|
+
- 0bc4328: Render diagram tooltips in the Studio's own idiom, through one seam instead of six hand-assembled bodies:
|
|
66
|
+
- 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.
|
|
67
|
+
- 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.
|
|
68
|
+
- 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.
|
|
69
|
+
- 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.
|
|
70
|
+
- `MetaTable` renders rows only; the title and description come from the shared body, so dev-mode and end-user tooltips head identically.
|
|
71
|
+
|
|
72
|
+
`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.
|
|
73
|
+
|
|
74
|
+
- 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).
|
|
75
|
+
|
|
76
|
+
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.
|
|
77
|
+
|
|
78
|
+
### Patch Changes
|
|
79
|
+
|
|
80
|
+
- Updated dependencies [0bc4328]
|
|
81
|
+
- @sanity/groq-condition-describe@0.4.0
|
|
82
|
+
|
|
3
83
|
## 0.23.0
|
|
4
84
|
|
|
5
85
|
### 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 =
|
|
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) {
|
|
@@ -1845,6 +1854,18 @@ function classifyPrincipalId(id) {
|
|
|
1845
1854
|
};
|
|
1846
1855
|
}
|
|
1847
1856
|
|
|
1857
|
+
function directoryBridgeId(sanityUserId) {
|
|
1858
|
+
if (typeof sanityUserId == "string") return classifyPrincipalId(sanityUserId).namespace === "global" ? sanityUserId : void 0;
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
function firstCarriedGlobalId(candidates) {
|
|
1862
|
+
for (const candidate of candidates) {
|
|
1863
|
+
if (candidate === void 0) continue;
|
|
1864
|
+
const {globalId: globalId} = classifyPrincipalId(candidate);
|
|
1865
|
+
if (globalId !== void 0) return globalId;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1848
1869
|
function lakePrincipalId(args) {
|
|
1849
1870
|
return args.localPrincipalId ?? args.actor.id;
|
|
1850
1871
|
}
|
|
@@ -1879,7 +1900,7 @@ const GdrUriSchema = v__namespace.custom(s => typeof s == "string" && isGdrUri(s
|
|
|
1879
1900
|
}), tolerantObject()({
|
|
1880
1901
|
type: v__namespace.literal("role"),
|
|
1881
1902
|
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" ]);
|
|
1903
|
+
}) ]), 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
1904
|
|
|
1884
1905
|
function normalizedChoiceKind(kind) {
|
|
1885
1906
|
return kind === "dateTime" ? "datetime" : kind;
|
|
@@ -1914,7 +1935,9 @@ const fieldValueSchemas = {
|
|
|
1914
1935
|
progress: NullableProgress,
|
|
1915
1936
|
boolean: NullableBoolean,
|
|
1916
1937
|
date: NullableDate,
|
|
1938
|
+
dueDate: NullableDate,
|
|
1917
1939
|
datetime: NullableDateTime,
|
|
1940
|
+
dueDatetime: NullableDateTime,
|
|
1918
1941
|
url: NullableUrl,
|
|
1919
1942
|
actor: v__namespace.union([ v__namespace.null(), ActorShape ]),
|
|
1920
1943
|
assignee: v__namespace.union([ v__namespace.null(), AssigneeShape ]),
|
|
@@ -2279,7 +2302,7 @@ function groupMembershipNames(group) {
|
|
|
2279
2302
|
return group === void 0 ? [] : typeof group == "string" ? [ group ] : [ ...group ];
|
|
2280
2303
|
}
|
|
2281
2304
|
|
|
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({
|
|
2305
|
+
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
2306
|
min: v__namespace.optional(FiniteNumber),
|
|
2284
2307
|
max: v__namespace.optional(FiniteNumber)
|
|
2285
2308
|
}), 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 +2692,10 @@ function isSubjectEntry(entry) {
|
|
|
2669
2692
|
return entry.type === "subject";
|
|
2670
2693
|
}
|
|
2671
2694
|
|
|
2695
|
+
function isDueDateEntry(entry) {
|
|
2696
|
+
return entry.type === "dueDate" || entry.type === "dueDatetime";
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2672
2699
|
function isInputSourced(entry) {
|
|
2673
2700
|
return entry.initialValue?.type === "input";
|
|
2674
2701
|
}
|
|
@@ -3175,25 +3202,79 @@ function checkAssigneesEntries(def, issues) {
|
|
|
3175
3202
|
});
|
|
3176
3203
|
}
|
|
3177
3204
|
|
|
3178
|
-
function
|
|
3179
|
-
|
|
3205
|
+
function checkDueDateEntries(def, issues) {
|
|
3206
|
+
for (const {entries: entries, path: path, label: label} of fieldScopes(def)) {
|
|
3207
|
+
(entries ?? []).filter(isDueDateEntry).length > 1 && issues.push({
|
|
3208
|
+
path: path,
|
|
3209
|
+
message: "at most one due-date field entry per scope (dueDate or dueDatetime combined) — surfaces identify the deadline by kind"
|
|
3210
|
+
});
|
|
3211
|
+
for (const site of belowScopeNestedSites({
|
|
3212
|
+
entries: entries,
|
|
3213
|
+
path: path,
|
|
3214
|
+
isKind: isDueDateEntry
|
|
3215
|
+
})) issues.push({
|
|
3216
|
+
path: site.path,
|
|
3217
|
+
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`
|
|
3218
|
+
});
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
|
|
3222
|
+
function nestedKindPaths(args) {
|
|
3223
|
+
const {shapes: shapes, base: base, isKind: isKind} = args;
|
|
3224
|
+
return (shapes ?? []).flatMap((shape, i) => isKind(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedKindPaths({
|
|
3225
|
+
shapes: shape.fields,
|
|
3226
|
+
base: [ ...base, i, "fields" ],
|
|
3227
|
+
isKind: isKind
|
|
3228
|
+
}), ...nestedKindPaths({
|
|
3229
|
+
shapes: shape.of,
|
|
3230
|
+
base: [ ...base, i, "of" ],
|
|
3231
|
+
isKind: isKind
|
|
3232
|
+
}) ]);
|
|
3180
3233
|
}
|
|
3181
3234
|
|
|
3182
|
-
function
|
|
3183
|
-
|
|
3235
|
+
function belowScopeNestedSites(args) {
|
|
3236
|
+
const {entries: entries, path: path, isKind: isKind} = args;
|
|
3237
|
+
return (entries ?? []).flatMap((entry, n) => [ ...nestedKindPaths({
|
|
3238
|
+
shapes: entry.fields,
|
|
3239
|
+
base: [ ...path, n, "fields" ],
|
|
3240
|
+
isKind: isKind
|
|
3241
|
+
}), ...nestedKindPaths({
|
|
3242
|
+
shapes: entry.of,
|
|
3243
|
+
base: [ ...path, n, "of" ],
|
|
3244
|
+
isKind: isKind
|
|
3245
|
+
}) ].map(nestedPath => ({
|
|
3246
|
+
path: nestedPath,
|
|
3247
|
+
entry: entry
|
|
3248
|
+
})));
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
function checkLevelKindEffectOutputs(def, issues) {
|
|
3252
|
+
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
3253
|
action: action,
|
|
3185
3254
|
path: [ "stages", i, "activities", j, "actions", a ],
|
|
3186
3255
|
issues: issues
|
|
3187
3256
|
});
|
|
3188
3257
|
}
|
|
3189
3258
|
|
|
3190
|
-
|
|
3259
|
+
const LEVEL_KIND_OUTPUT_RULES = [ {
|
|
3260
|
+
isKind: isSubjectEntry,
|
|
3261
|
+
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`
|
|
3262
|
+
}, {
|
|
3263
|
+
isKind: isDueDateEntry,
|
|
3264
|
+
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`
|
|
3265
|
+
} ];
|
|
3266
|
+
|
|
3267
|
+
function pushOutputIssues(args) {
|
|
3191
3268
|
const {action: action, path: path, issues: issues} = args;
|
|
3192
3269
|
for (const [e, effect] of (action.effects ?? []).entries()) {
|
|
3193
3270
|
const base = [ ...path, "effects", e, "outputs" ];
|
|
3194
|
-
for (const
|
|
3271
|
+
for (const {isKind: isKind, message: message} of LEVEL_KIND_OUTPUT_RULES) for (const nestedPath of nestedKindPaths({
|
|
3272
|
+
shapes: effect.outputs,
|
|
3273
|
+
base: base,
|
|
3274
|
+
isKind: isKind
|
|
3275
|
+
})) issues.push({
|
|
3195
3276
|
path: nestedPath,
|
|
3196
|
-
message:
|
|
3277
|
+
message: message(effect.name)
|
|
3197
3278
|
});
|
|
3198
3279
|
}
|
|
3199
3280
|
}
|
|
@@ -3211,13 +3292,14 @@ function checkSubjectEntries(def, issues) {
|
|
|
3211
3292
|
path: [ ...path, n ],
|
|
3212
3293
|
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
3294
|
});
|
|
3214
|
-
for (const
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3295
|
+
for (const site of belowScopeNestedSites({
|
|
3296
|
+
entries: entries,
|
|
3297
|
+
path: path,
|
|
3298
|
+
isKind: isSubjectEntry
|
|
3299
|
+
})) issues.push({
|
|
3300
|
+
path: site.path,
|
|
3301
|
+
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`
|
|
3302
|
+
});
|
|
3221
3303
|
}
|
|
3222
3304
|
}
|
|
3223
3305
|
|
|
@@ -3853,7 +3935,9 @@ const SCALAR = {
|
|
|
3853
3935
|
progress: () => SCALAR,
|
|
3854
3936
|
boolean: () => SCALAR,
|
|
3855
3937
|
date: () => SCALAR,
|
|
3938
|
+
dueDate: () => SCALAR,
|
|
3856
3939
|
datetime: () => SCALAR,
|
|
3940
|
+
dueDatetime: () => SCALAR,
|
|
3857
3941
|
url: () => SCALAR,
|
|
3858
3942
|
actor: () => ACTOR_VALUE,
|
|
3859
3943
|
assignee: () => ASSIGNEE_VALUE,
|
|
@@ -3944,10 +4028,10 @@ function checkWorkflowInvariants(def) {
|
|
|
3944
4028
|
checkRequiredField(def, issues), checkStart(def, issues), checkPredicates(def, issues),
|
|
3945
4029
|
checkUnboundConditionVars(def, issues), checkConditionFieldReads(def, issues), checkFieldReadSeeds(def, issues),
|
|
3946
4030
|
checkFieldReadOpValues(def, issues), checkUpdateWhereOps(def, issues), checkGuardFieldReads(def, issues),
|
|
3947
|
-
checkAssigneesEntries(def, issues),
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
checkGroups(def, issues), issues;
|
|
4031
|
+
checkAssigneesEntries(def, issues), checkDueDateEntries(def, issues), checkSubjectEntries(def, issues),
|
|
4032
|
+
checkLevelKindEffectOutputs(def, issues), checkActivityTerminalPaths(def, issues),
|
|
4033
|
+
checkTerminalStageActivities(def, issues), checkTriggeredActionParams(def, issues),
|
|
4034
|
+
checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
|
|
3951
4035
|
}
|
|
3952
4036
|
|
|
3953
4037
|
exports.ACTION_SEMANTICS = ACTION_SEMANTICS;
|
|
@@ -4100,6 +4184,8 @@ exports.deriveExecutorClassification = deriveExecutorClassification;
|
|
|
4100
4184
|
|
|
4101
4185
|
exports.desugarWorkflow = desugarWorkflow;
|
|
4102
4186
|
|
|
4187
|
+
exports.directoryBridgeId = directoryBridgeId;
|
|
4188
|
+
|
|
4103
4189
|
exports.driverKind = driverKind;
|
|
4104
4190
|
|
|
4105
4191
|
exports.errorMessage = errorMessage;
|
|
@@ -4116,6 +4202,8 @@ exports.fieldTreeShape = fieldTreeShape;
|
|
|
4116
4202
|
|
|
4117
4203
|
exports.fieldValueSchemas = fieldValueSchemas;
|
|
4118
4204
|
|
|
4205
|
+
exports.firstCarriedGlobalId = firstCarriedGlobalId;
|
|
4206
|
+
|
|
4119
4207
|
exports.formatIssuePath = formatIssuePath;
|
|
4120
4208
|
|
|
4121
4209
|
exports.formatIssues = formatIssues;
|
|
@@ -136,7 +136,7 @@ function parentRef(instance) {
|
|
|
136
136
|
return instance.ancestors.at(-1);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
const DATA_MODEL_VERSION =
|
|
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) {
|
|
@@ -1831,6 +1840,18 @@ function classifyPrincipalId(id) {
|
|
|
1831
1840
|
};
|
|
1832
1841
|
}
|
|
1833
1842
|
|
|
1843
|
+
function directoryBridgeId(sanityUserId) {
|
|
1844
|
+
if (typeof sanityUserId == "string") return classifyPrincipalId(sanityUserId).namespace === "global" ? sanityUserId : void 0;
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
function firstCarriedGlobalId(candidates) {
|
|
1848
|
+
for (const candidate of candidates) {
|
|
1849
|
+
if (candidate === void 0) continue;
|
|
1850
|
+
const {globalId: globalId} = classifyPrincipalId(candidate);
|
|
1851
|
+
if (globalId !== void 0) return globalId;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1834
1855
|
function lakePrincipalId(args) {
|
|
1835
1856
|
return args.localPrincipalId ?? args.actor.id;
|
|
1836
1857
|
}
|
|
@@ -1865,7 +1886,7 @@ const GdrUriSchema = v.custom(s => typeof s == "string" && isGdrUri(s), "must be
|
|
|
1865
1886
|
}), tolerantObject()({
|
|
1866
1887
|
type: v.literal("role"),
|
|
1867
1888
|
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" ]);
|
|
1889
|
+
}) ]), 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
1890
|
|
|
1870
1891
|
function normalizedChoiceKind(kind) {
|
|
1871
1892
|
return kind === "dateTime" ? "datetime" : kind;
|
|
@@ -1900,7 +1921,9 @@ const fieldValueSchemas = {
|
|
|
1900
1921
|
progress: NullableProgress,
|
|
1901
1922
|
boolean: NullableBoolean,
|
|
1902
1923
|
date: NullableDate,
|
|
1924
|
+
dueDate: NullableDate,
|
|
1903
1925
|
datetime: NullableDateTime,
|
|
1926
|
+
dueDatetime: NullableDateTime,
|
|
1904
1927
|
url: NullableUrl,
|
|
1905
1928
|
actor: v.union([ v.null(), ActorShape ]),
|
|
1906
1929
|
assignee: v.union([ v.null(), AssigneeShape ]),
|
|
@@ -2265,7 +2288,7 @@ function groupMembershipNames(group) {
|
|
|
2265
2288
|
return group === void 0 ? [] : typeof group == "string" ? [ group ] : [ ...group ];
|
|
2266
2289
|
}
|
|
2267
2290
|
|
|
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({
|
|
2291
|
+
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
2292
|
min: v.optional(FiniteNumber),
|
|
2270
2293
|
max: v.optional(FiniteNumber)
|
|
2271
2294
|
}), 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 +2678,10 @@ function isSubjectEntry(entry) {
|
|
|
2655
2678
|
return entry.type === "subject";
|
|
2656
2679
|
}
|
|
2657
2680
|
|
|
2681
|
+
function isDueDateEntry(entry) {
|
|
2682
|
+
return entry.type === "dueDate" || entry.type === "dueDatetime";
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2658
2685
|
function isInputSourced(entry) {
|
|
2659
2686
|
return entry.initialValue?.type === "input";
|
|
2660
2687
|
}
|
|
@@ -3161,25 +3188,79 @@ function checkAssigneesEntries(def, issues) {
|
|
|
3161
3188
|
});
|
|
3162
3189
|
}
|
|
3163
3190
|
|
|
3164
|
-
function
|
|
3165
|
-
|
|
3191
|
+
function checkDueDateEntries(def, issues) {
|
|
3192
|
+
for (const {entries: entries, path: path, label: label} of fieldScopes(def)) {
|
|
3193
|
+
(entries ?? []).filter(isDueDateEntry).length > 1 && issues.push({
|
|
3194
|
+
path: path,
|
|
3195
|
+
message: "at most one due-date field entry per scope (dueDate or dueDatetime combined) — surfaces identify the deadline by kind"
|
|
3196
|
+
});
|
|
3197
|
+
for (const site of belowScopeNestedSites({
|
|
3198
|
+
entries: entries,
|
|
3199
|
+
path: path,
|
|
3200
|
+
isKind: isDueDateEntry
|
|
3201
|
+
})) issues.push({
|
|
3202
|
+
path: site.path,
|
|
3203
|
+
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`
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
function nestedKindPaths(args) {
|
|
3209
|
+
const {shapes: shapes, base: base, isKind: isKind} = args;
|
|
3210
|
+
return (shapes ?? []).flatMap((shape, i) => isKind(shape) ? [ [ ...base, i, "type" ] ] : [ ...nestedKindPaths({
|
|
3211
|
+
shapes: shape.fields,
|
|
3212
|
+
base: [ ...base, i, "fields" ],
|
|
3213
|
+
isKind: isKind
|
|
3214
|
+
}), ...nestedKindPaths({
|
|
3215
|
+
shapes: shape.of,
|
|
3216
|
+
base: [ ...base, i, "of" ],
|
|
3217
|
+
isKind: isKind
|
|
3218
|
+
}) ]);
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
function belowScopeNestedSites(args) {
|
|
3222
|
+
const {entries: entries, path: path, isKind: isKind} = args;
|
|
3223
|
+
return (entries ?? []).flatMap((entry, n) => [ ...nestedKindPaths({
|
|
3224
|
+
shapes: entry.fields,
|
|
3225
|
+
base: [ ...path, n, "fields" ],
|
|
3226
|
+
isKind: isKind
|
|
3227
|
+
}), ...nestedKindPaths({
|
|
3228
|
+
shapes: entry.of,
|
|
3229
|
+
base: [ ...path, n, "of" ],
|
|
3230
|
+
isKind: isKind
|
|
3231
|
+
}) ].map(nestedPath => ({
|
|
3232
|
+
path: nestedPath,
|
|
3233
|
+
entry: entry
|
|
3234
|
+
})));
|
|
3166
3235
|
}
|
|
3167
3236
|
|
|
3168
|
-
function
|
|
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())
|
|
3237
|
+
function checkLevelKindEffectOutputs(def, issues) {
|
|
3238
|
+
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
3239
|
action: action,
|
|
3171
3240
|
path: [ "stages", i, "activities", j, "actions", a ],
|
|
3172
3241
|
issues: issues
|
|
3173
3242
|
});
|
|
3174
3243
|
}
|
|
3175
3244
|
|
|
3176
|
-
|
|
3245
|
+
const LEVEL_KIND_OUTPUT_RULES = [ {
|
|
3246
|
+
isKind: isSubjectEntry,
|
|
3247
|
+
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`
|
|
3248
|
+
}, {
|
|
3249
|
+
isKind: isDueDateEntry,
|
|
3250
|
+
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`
|
|
3251
|
+
} ];
|
|
3252
|
+
|
|
3253
|
+
function pushOutputIssues(args) {
|
|
3177
3254
|
const {action: action, path: path, issues: issues} = args;
|
|
3178
3255
|
for (const [e, effect] of (action.effects ?? []).entries()) {
|
|
3179
3256
|
const base = [ ...path, "effects", e, "outputs" ];
|
|
3180
|
-
for (const
|
|
3257
|
+
for (const {isKind: isKind, message: message} of LEVEL_KIND_OUTPUT_RULES) for (const nestedPath of nestedKindPaths({
|
|
3258
|
+
shapes: effect.outputs,
|
|
3259
|
+
base: base,
|
|
3260
|
+
isKind: isKind
|
|
3261
|
+
})) issues.push({
|
|
3181
3262
|
path: nestedPath,
|
|
3182
|
-
message:
|
|
3263
|
+
message: message(effect.name)
|
|
3183
3264
|
});
|
|
3184
3265
|
}
|
|
3185
3266
|
}
|
|
@@ -3197,13 +3278,14 @@ function checkSubjectEntries(def, issues) {
|
|
|
3197
3278
|
path: [ ...path, n ],
|
|
3198
3279
|
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
3280
|
});
|
|
3200
|
-
for (const
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3281
|
+
for (const site of belowScopeNestedSites({
|
|
3282
|
+
entries: entries,
|
|
3283
|
+
path: path,
|
|
3284
|
+
isKind: isSubjectEntry
|
|
3285
|
+
})) issues.push({
|
|
3286
|
+
path: site.path,
|
|
3287
|
+
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`
|
|
3288
|
+
});
|
|
3207
3289
|
}
|
|
3208
3290
|
}
|
|
3209
3291
|
|
|
@@ -3839,7 +3921,9 @@ const SCALAR = {
|
|
|
3839
3921
|
progress: () => SCALAR,
|
|
3840
3922
|
boolean: () => SCALAR,
|
|
3841
3923
|
date: () => SCALAR,
|
|
3924
|
+
dueDate: () => SCALAR,
|
|
3842
3925
|
datetime: () => SCALAR,
|
|
3926
|
+
dueDatetime: () => SCALAR,
|
|
3843
3927
|
url: () => SCALAR,
|
|
3844
3928
|
actor: () => ACTOR_VALUE,
|
|
3845
3929
|
assignee: () => ASSIGNEE_VALUE,
|
|
@@ -3930,10 +4014,10 @@ function checkWorkflowInvariants(def) {
|
|
|
3930
4014
|
checkRequiredField(def, issues), checkStart(def, issues), checkPredicates(def, issues),
|
|
3931
4015
|
checkUnboundConditionVars(def, issues), checkConditionFieldReads(def, issues), checkFieldReadSeeds(def, issues),
|
|
3932
4016
|
checkFieldReadOpValues(def, issues), checkUpdateWhereOps(def, issues), checkGuardFieldReads(def, issues),
|
|
3933
|
-
checkAssigneesEntries(def, issues),
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
checkGroups(def, issues), issues;
|
|
4017
|
+
checkAssigneesEntries(def, issues), checkDueDateEntries(def, issues), checkSubjectEntries(def, issues),
|
|
4018
|
+
checkLevelKindEffectOutputs(def, issues), checkActivityTerminalPaths(def, issues),
|
|
4019
|
+
checkTerminalStageActivities(def, issues), checkTriggeredActionParams(def, issues),
|
|
4020
|
+
checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
|
|
3937
4021
|
}
|
|
3938
4022
|
|
|
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, 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 };
|
|
4023
|
+
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, directoryBridgeId, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldTreeShape, fieldValueSchemas, firstCarriedGlobalId, 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";
|