@sanity/workflow-engine 0.18.0 → 0.20.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.
@@ -4,6 +4,8 @@ import { conditionOutcome, runGroq as runGroq$1, evaluateConditionOutcome as eva
4
4
 
5
5
  import { parse } from "groq-js";
6
6
 
7
+ import { isDraftId, isVersionId, getPublishedId } from "@sanity/id-utils";
8
+
7
9
  class WorkflowError extends Error {
8
10
  kind;
9
11
  constructor(kind, message, options) {
@@ -113,7 +115,7 @@ function parentRef(instance) {
113
115
  return instance.ancestors.at(-1);
114
116
  }
115
117
 
116
- const DATA_MODEL_VERSION = 2, DATA_MODEL_MIN_READER = 2, READER_MODEL_ROLLOUT_URL = "https://github.com/sanity-io/workflows/blob/main/docs/reader-model-rollout.md";
118
+ const DATA_MODEL_VERSION = 3, DATA_MODEL_MIN_READER = 2, READER_MODEL_ROLLOUT_URL = "https://github.com/sanity-io/workflows/blob/main/docs/reader-model-rollout.md";
117
119
 
118
120
  class ReaderModelAcknowledgementError extends WorkflowError {
119
121
  code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
@@ -172,6 +174,22 @@ const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
172
174
  compatibility: "reader-floor",
173
175
  applicability: "detectable",
174
176
  summary: "String, text, and number values may carry persisted inclusive bounds."
177
+ }), Object.freeze({
178
+ id: "progress-field-kind",
179
+ introducedInModel: 3,
180
+ minReaderModel: 0,
181
+ documentTypes: Object.freeze([ "definition", "instance" ]),
182
+ compatibility: "additive",
183
+ applicability: "detectable",
184
+ summary: "A progress field kind carries application-defined 0–100 completion."
185
+ }), Object.freeze({
186
+ id: "effect-claim-tokens",
187
+ introducedInModel: 3,
188
+ minReaderModel: 0,
189
+ documentTypes: Object.freeze([ "instance" ]),
190
+ compatibility: "additive",
191
+ applicability: "detectable",
192
+ summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
175
193
  }) ]);
176
194
 
177
195
  function recordOf(value) {
@@ -208,8 +226,8 @@ function hasChoiceList(document) {
208
226
  });
209
227
  }
210
228
 
211
- function hasSubjectField(document) {
212
- return persistedFieldEntries(document).some(entry => entry.type === "subject" || entry._type === "subject");
229
+ function hasFieldKind(document, kind) {
230
+ return persistedFieldEntries(document).some(entry => entry.type === kind || entry._type === kind);
213
231
  }
214
232
 
215
233
  function hasActionSemantics(document) {
@@ -224,12 +242,22 @@ function hasScalarValidation(document) {
224
242
  });
225
243
  }
226
244
 
245
+ function hasClaimTokens(document) {
246
+ const root = recordOf(document);
247
+ return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
248
+ const claim = recordOf(entry.claim);
249
+ return claim !== void 0 && typeof claim.claimToken == "string";
250
+ });
251
+ }
252
+
227
253
  const featureDetectors = {
228
254
  "governed-model-stamps": () => !0,
229
- "subject-field-kind": hasSubjectField,
255
+ "subject-field-kind": document => hasFieldKind(document, "subject"),
230
256
  "typed-scalar-choice-lists": hasChoiceList,
231
257
  "action-semantics": hasActionSemantics,
232
- "inclusive-scalar-bounds": hasScalarValidation
258
+ "inclusive-scalar-bounds": hasScalarValidation,
259
+ "progress-field-kind": document => hasFieldKind(document, "progress"),
260
+ "effect-claim-tokens": hasClaimTokens
233
261
  };
234
262
 
235
263
  function requiredModelFeatures(documentType, document) {
@@ -316,6 +344,21 @@ function andConditions(parts) {
316
344
 
317
345
  const KNOWN_SCHEMES = /* @__PURE__ */ new Set([ "dataset", "canvas", "media-library", "dashboard" ]), KNOWN_SCHEMES_TEXT = [ ...KNOWN_SCHEMES ].join(", ");
318
346
 
347
+ class VersionSpecificDatasetGdrError extends Error {
348
+ documentId;
349
+ stableDocumentId;
350
+ constructor(documentId, uri) {
351
+ const stableDocumentId = getPublishedId(documentId);
352
+ super(`Invalid GDR "${uri}": dataset document ID "${documentId}" identifies a stored draft or release version. Use the stable document ID "${stableDocumentId}" and select drafts/releases through the workflow perspective.`),
353
+ this.name = "VersionSpecificDatasetGdrError", this.documentId = documentId, this.stableDocumentId = stableDocumentId;
354
+ }
355
+ }
356
+
357
+ function assertStableDatasetDocumentId(documentId, uri) {
358
+ const sanityId = documentId;
359
+ if (!(!isDraftId(sanityId) && !isVersionId(sanityId))) throw new VersionSpecificDatasetGdrError(documentId, uri);
360
+ }
361
+
319
362
  function parseGdr(uri) {
320
363
  const colon = uri.indexOf(":");
321
364
  if (colon < 0) throw new Error(`Invalid GDR "${uri}": must be a URI of form "<scheme>:<...id-parts>". Known schemes: ${KNOWN_SCHEMES_TEXT}.`);
@@ -325,11 +368,12 @@ function parseGdr(uri) {
325
368
  if (parts.some(part => part.length === 0)) throw new Error(`Invalid GDR "${uri}": id parts must be non-empty (no leading, trailing, or doubled ":").`);
326
369
  if (scheme === "dataset") {
327
370
  if (parts.length !== 3) throw new Error(`Invalid GDR "${uri}": dataset scheme requires <projectId>:<dataset>:<documentId> (3 parts after scheme); got ${parts.length}.`);
328
- return {
371
+ const documentId = parts[2];
372
+ return assertStableDatasetDocumentId(documentId, uri), {
329
373
  scheme: "dataset",
330
374
  projectId: parts[0],
331
375
  dataset: parts[1],
332
- documentId: parts[2]
376
+ documentId: documentId
333
377
  };
334
378
  }
335
379
  if (parts.length !== 2) throw new Error(`Invalid GDR "${uri}": ${scheme} scheme requires <resourceId>:<documentId> (2 parts after scheme); got ${parts.length}.`);
@@ -349,7 +393,11 @@ function tryParseGdr(uri) {
349
393
  }
350
394
 
351
395
  function gdrUri(parts) {
352
- return parts.scheme === "dataset" ? `dataset:${parts.projectId}:${parts.dataset}:${parts.documentId}` : `${parts.scheme}:${parts.resourceId}:${parts.documentId}`;
396
+ if (parts.scheme === "dataset") {
397
+ const uri = `dataset:${parts.projectId}:${parts.dataset}:${parts.documentId}`;
398
+ return assertStableDatasetDocumentId(parts.documentId, uri), uri;
399
+ }
400
+ return `${parts.scheme}:${parts.resourceId}:${parts.documentId}`;
353
401
  }
354
402
 
355
403
  function extractDocumentId(gdrUriString) {
@@ -531,7 +579,13 @@ function asPredicate(validate) {
531
579
  };
532
580
  }
533
581
 
534
- const isValidTag = asPredicate(validateTag), isValidAliasName = asPredicate(validateResourceAliasName), isValidDatasetId = asPredicate(datasetResourceParts), WorkflowResourceSchema = v.variant("type", [ v.object({
582
+ const isValidTag = asPredicate(validateTag), isValidAliasName = asPredicate(validateResourceAliasName), isValidDatasetId = asPredicate(datasetResourceParts);
583
+
584
+ function lakeSegment(label) {
585
+ return v.pipe(v.string(), v.nonEmpty(), v.check(isValidTag, `invalid ${label} — ${LAKE_ID_SEGMENT_GLOSS}`));
586
+ }
587
+
588
+ const WorkflowResourceSchema = v.variant("type", [ v.object({
535
589
  type: v.literal("dataset"),
536
590
  id: v.pipe(NonEmptyString$1, v.check(isValidDatasetId, 'invalid dataset resource id — expected "<projectId>.<dataset>"'))
537
591
  }), v.object({
@@ -547,14 +601,46 @@ const isValidTag = asPredicate(validateTag), isValidAliasName = asPredicate(vali
547
601
  name: v.pipe(NonEmptyString$1, v.check(isValidAliasName, "invalid resource handle name — lowercase letters, digits and dashes only, no leading dash")),
548
602
  resource: WorkflowResourceSchema
549
603
  }), DefinitionSchema = v.custom(input => typeof input == "object" && input !== null && typeof input.name == "string", "expected a workflow definition (an object with a string `name`)"), DeploymentSchema = v.object({
550
- name: NonEmptyString$1,
604
+ name: lakeSegment("name"),
551
605
  expectedMinReaderModel: v.optional(v.custom(() => !0), void 0),
552
- tag: v.pipe(v.string(), v.nonEmpty(), v.check(isValidTag, "invalid tag — lowercase letters, digits and dashes only, no leading dash, no dots")),
606
+ tag: lakeSegment("tag"),
553
607
  workflowResource: WorkflowResourceSchema,
554
- resourceAliases: v.optional(v.pipe(v.array(ResourceBindingSchema), v.check(bindings => new Set(bindings.map(binding => binding.name)).size === bindings.length, "duplicate resource handle name — each binding name must be unique within a deployment"))),
608
+ resourceAliases: v.optional(v.pipe(v.array(ResourceBindingSchema), v.check(bindings => duplicateHandleMessage(bindings) === void 0, issue => duplicateHandleMessage(issue.input) ?? "duplicate resource handle name"))),
555
609
  definitions: v.pipe(v.array(DefinitionSchema), v.minLength(1, "a deployment needs at least one definition"))
556
- }), TelemetryLoggerSchema = v.custom(input => typeof input == "object" && input !== null && typeof input.log == "function", "expected a telemetry logger (an object with a `log` function)"), WorkflowConfigSchema = v.object({
557
- deployments: v.pipe(v.array(DeploymentSchema), v.minLength(1, "a config needs at least one deployment"), v.check(deployments => new Set(deployments.map(deployment => deployment.tag)).size === deployments.length, "duplicate deployment tag — each deployment must use a unique tag")),
610
+ });
611
+
612
+ function firstDuplicatePair(items, keyOf) {
613
+ const seen = /* @__PURE__ */ new Map;
614
+ for (const item of items) {
615
+ const key = keyOf(item), earlier = seen.get(key);
616
+ if (earlier !== void 0) return [ earlier, item ];
617
+ seen.set(key, item);
618
+ }
619
+ }
620
+
621
+ function duplicateHandleMessage(bindings) {
622
+ const pair = firstDuplicatePair(bindings, binding => binding.name);
623
+ if (pair !== void 0) return `duplicate resource handle name "${pair[1].name}" — each binding name must be unique within a deployment`;
624
+ }
625
+
626
+ function duplicateNameMessage(deployments) {
627
+ const pair = firstDuplicatePair(deployments, deployment => deployment.name);
628
+ if (pair !== void 0) return `duplicate deployment name "${pair[1].name}" — each deployment must use a unique name`;
629
+ }
630
+
631
+ function partitionKey(deployment) {
632
+ return `${resourceGdr(deployment.workflowResource)} ${deployment.tag}`;
633
+ }
634
+
635
+ function partitionCollisionMessage(deployments) {
636
+ const pair = firstDuplicatePair(deployments, partitionKey);
637
+ if (pair === void 0) return;
638
+ const [first, second] = pair;
639
+ return `deployments "${first.name}" and "${second.name}" share workflow resource + tag "${second.tag}" — both would write into the same partition; change one deployment’s tag or resource`;
640
+ }
641
+
642
+ const TelemetryLoggerSchema = v.custom(input => typeof input == "object" && input !== null && typeof input.log == "function", "expected a telemetry logger (an object with a `log` function)"), WorkflowConfigSchema = v.object({
643
+ deployments: v.pipe(v.array(DeploymentSchema), v.minLength(1, "a config needs at least one deployment"), v.check(deployments => duplicateNameMessage(deployments) === void 0, issue => duplicateNameMessage(issue.input) ?? "duplicate deployment name"), v.check(deployments => partitionCollisionMessage(deployments) === void 0, issue => partitionCollisionMessage(issue.input) ?? "duplicate deployment partition")),
558
644
  telemetry: v.optional(TelemetryLoggerSchema)
559
645
  });
560
646
 
@@ -1708,7 +1794,7 @@ const GdrUriSchema = v.custom(s => typeof s == "string" && isGdrUri(s), "must be
1708
1794
  }), tolerantObject()({
1709
1795
  type: v.literal("role"),
1710
1796
  role: NonEmptyString
1711
- }) ]), NullableString = v.union([ v.null(), v.string() ]), NullableNumber = v.union([ v.null(), v.number() ]), NullableBoolean = v.union([ v.null(), v.boolean() ]), 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" ]);
1797
+ }) ]), 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" ]);
1712
1798
 
1713
1799
  function normalizedChoiceKind(kind) {
1714
1800
  return kind === "dateTime" ? "datetime" : kind;
@@ -1740,6 +1826,7 @@ const fieldValueSchemas = {
1740
1826
  string: NullableString,
1741
1827
  text: NullableString,
1742
1828
  number: NullableNumber,
1829
+ progress: NullableProgress,
1743
1830
  boolean: NullableBoolean,
1744
1831
  date: NullableDate,
1745
1832
  datetime: NullableDateTime,
@@ -1764,13 +1851,13 @@ function shapeValueSchema(shape, leaf) {
1764
1851
  }
1765
1852
 
1766
1853
  function scalarMeasurement(entryType, value) {
1767
- if (entryType === "number" && typeof value == "number") return value;
1854
+ if ((entryType === "number" || entryType === "progress") && typeof value == "number") return value;
1768
1855
  if ((entryType === "string" || entryType === "text") && typeof value == "string") return value.length;
1769
1856
  }
1770
1857
 
1771
1858
  function scalarBoundIssue(args) {
1772
1859
  const {entryType: entryType, measured: measured, bound: bound, limit: limit} = args;
1773
- return bound === void 0 || limit === "min" && measured >= bound || limit === "max" && measured <= bound ? void 0 : `${entryType === "number" ? "" : "length "}must be ${limit === "min" ? "greater than or equal to" : "less than or equal to"} ${bound}`;
1860
+ return bound === void 0 || limit === "min" && measured >= bound || limit === "max" && measured <= bound ? void 0 : `${entryType === "number" || entryType === "progress" ? "" : "length "}must be ${limit === "min" ? "greater than or equal to" : "less than or equal to"} ${bound}`;
1774
1861
  }
1775
1862
 
1776
1863
  function scalarValidationIssues(args) {
@@ -1948,7 +2035,15 @@ function groqIdentifier(referencedAs) {
1948
2035
  }
1949
2036
 
1950
2037
  function picklist(options) {
1951
- return v.picklist(options, `Invalid option: expected one of ${options.map(o => `"${o}"`).join("|")}`);
2038
+ return v.picklist(options, invalidOptionMessage(options));
2039
+ }
2040
+
2041
+ function invalidOptionMessage(options) {
2042
+ return `Invalid option: expected one of ${options.map(option => `"${option}"`).join("|")}`;
2043
+ }
2044
+
2045
+ function exhaustiveOptions() {
2046
+ return options => options;
1952
2047
  }
1953
2048
 
1954
2049
  function pinned() {
@@ -1963,12 +2058,12 @@ const LiteralSchema = v.strictObject({
1963
2058
  scope: v.optional(v.union([ v.literal("workflow"), v.literal("stage") ])),
1964
2059
  field: NonEmpty,
1965
2060
  path: v.optional(v.string())
1966
- }), FieldSourceSchema = v.union([ v.strictObject({
2061
+ }), FieldSourceSchema = v.variant("type", [ v.strictObject({
1967
2062
  type: v.literal("input")
1968
2063
  }), v.strictObject({
1969
2064
  type: v.literal("query"),
1970
2065
  query: NonEmpty
1971
- }), LiteralSchema, FieldReadSchema ]), ValueExprSchema = v.lazy(() => v.union([ LiteralSchema, FieldReadSchema, v.strictObject({
2066
+ }), LiteralSchema, FieldReadSchema ]), ValueExprSchema = v.lazy(() => v.variant("type", [ LiteralSchema, FieldReadSchema, v.strictObject({
1972
2067
  type: v.literal("param"),
1973
2068
  param: NonEmpty
1974
2069
  }), v.strictObject({
@@ -2063,7 +2158,7 @@ function groupMembershipNames(group) {
2063
2158
  return group === void 0 ? [] : typeof group == "string" ? [ group ] : [ ...group ];
2064
2159
  }
2065
2160
 
2066
- const FIELD_VALUE_KINDS = [ "doc.ref", "doc.refs", "subject", "release.ref", "string", "text", "number", "boolean", "date", "datetime", "url", "actor", "assignee", "assignees", "object", "array" ], FieldValueKindSchema = picklist(FIELD_VALUE_KINDS), FieldKindSchema = picklist(FIELD_VALUE_KINDS), FieldEntryName = groqIdentifier("`$fields.<name>`"), FiniteNumber = v.pipe(v.number(), v.finite("must be finite")), ScalarValidationSchema = v.pipe(v.strictObject({
2161
+ 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({
2067
2162
  min: v.optional(FiniteNumber),
2068
2163
  max: v.optional(FiniteNumber)
2069
2164
  }), 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({
@@ -2128,9 +2223,9 @@ function fieldBase(editable, group) {
2128
2223
  };
2129
2224
  }
2130
2225
 
2131
- function fieldEntryFields(editable, group) {
2226
+ function fieldEntryFields({editable: editable, group: group, kind: kind = FieldKindSchema}) {
2132
2227
  return {
2133
- type: FieldKindSchema,
2228
+ type: kind,
2134
2229
  ...fieldBase(editable, group),
2135
2230
  options: v.optional(ChoiceOptionsSchema),
2136
2231
  validation: v.optional(ScalarValidationSchema),
@@ -2172,7 +2267,7 @@ function choiceOptionsCheck() {
2172
2267
  }) ?? []).join("; "));
2173
2268
  }
2174
2269
 
2175
- const SCALAR_VALIDATION_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number" ]);
2270
+ const SCALAR_VALIDATION_KINDS = /* @__PURE__ */ new Set([ "string", "text", "number", "progress" ]);
2176
2271
 
2177
2272
  function scalarValidationCheck() {
2178
2273
  return v.check(entry => scalarValidationDeclarationIssues(entry) === void 0, issue => (scalarValidationDeclarationIssues(issue.input) ?? []).join("; "));
@@ -2181,13 +2276,24 @@ function scalarValidationCheck() {
2181
2276
  function scalarValidationDeclarationIssues(entry) {
2182
2277
  const {type: type, validation: validation} = entry;
2183
2278
  if (validation === void 0) return;
2184
- if (!SCALAR_VALIDATION_KINDS.has(type)) return [ `\`validation\` is only valid on \`string\` / \`text\` / \`number\` values, not "${type}"` ];
2279
+ if (!SCALAR_VALIDATION_KINDS.has(type)) return [ `\`validation\` is only valid on \`string\` / \`text\` / \`number\` / \`progress\` values, not "${type}"` ];
2280
+ if (type === "progress") {
2281
+ const issues2 = Object.entries(validation).flatMap(([bound, value]) => typeof value == "number" && value >= 0 && value <= 100 ? [] : [ `\`validation.${bound}\` must stay within the progress kind's 0–100 contract` ]);
2282
+ return issues2.length === 0 ? void 0 : issues2;
2283
+ }
2185
2284
  if (type === "number") return;
2186
2285
  const issues = Object.entries(validation).flatMap(([bound, value]) => Number.isInteger(value) && value >= 0 ? [] : [ `\`validation.${bound}\` must be a non-negative integer for ${type} length` ]);
2187
2286
  return issues.length === 0 ? void 0 : issues;
2188
2287
  }
2189
2288
 
2190
- const FieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields(StoredEditableSchema, StoredGroupMembershipSchema)), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), RawAuthoringFieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields(AuthoringEditableSchema, AuthoringGroupMembershipSchema)), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), ClaimFieldSchema = pinned()(v.strictObject({
2289
+ const FieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields({
2290
+ editable: StoredEditableSchema,
2291
+ group: StoredGroupMembershipSchema
2292
+ })), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), RawAuthoringFieldEntrySchema = pinned()(v.pipe(compositeChecked(fieldEntryFields({
2293
+ editable: AuthoringEditableSchema,
2294
+ group: AuthoringGroupMembershipSchema,
2295
+ kind: AuthoringRawFieldKindSchema
2296
+ })), refTypesCheck(), choiceOptionsCheck(), scalarValidationCheck(), literalSeedCheck())), ClaimFieldSchema = pinned()(v.strictObject({
2191
2297
  type: v.literal("claim"),
2192
2298
  name: FieldEntryName,
2193
2299
  title: v.optional(v.string()),
@@ -2202,7 +2308,10 @@ function listSugarFields(type) {
2202
2308
  };
2203
2309
  }
2204
2310
 
2205
- const TodoListFieldSchema = pinned()(v.strictObject(listSugarFields("todoList"))), NotesFieldSchema = pinned()(v.strictObject(listSugarFields("notes"))), AuthoringFieldEntrySchema = pinned()(v.union([ RawAuthoringFieldEntrySchema, ClaimFieldSchema, TodoListFieldSchema, NotesFieldSchema ])), EffectSchema = v.strictObject({
2311
+ const TodoListFieldSchema = pinned()(v.strictObject(listSugarFields("todoList"))), NotesFieldSchema = pinned()(v.strictObject(listSugarFields("notes"))), AuthoringFieldEntrySchema = pinned()(v.lazy(input => {
2312
+ const type = asShape(input).type;
2313
+ return type === "claim" ? ClaimFieldSchema : type === "todoList" ? TodoListFieldSchema : type === "notes" ? NotesFieldSchema : RawAuthoringFieldEntrySchema;
2314
+ })), EffectSchema = v.strictObject({
2206
2315
  name: NonEmpty,
2207
2316
  title: v.optional(v.string()),
2208
2317
  description: v.optional(v.string()),
@@ -3592,6 +3701,7 @@ const SCALAR = {
3592
3701
  string: () => SCALAR,
3593
3702
  text: () => SCALAR,
3594
3703
  number: () => SCALAR,
3704
+ progress: () => SCALAR,
3595
3705
  boolean: () => SCALAR,
3596
3706
  date: () => SCALAR,
3597
3707
  datetime: () => SCALAR,
@@ -3691,4 +3801,4 @@ function checkWorkflowInvariants(def) {
3691
3801
  checkGroups(def, issues), issues;
3692
3802
  }
3693
3803
 
3694
- export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, 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_ALLOWED_VARS, START_FILTER_VARS, SUBJECT_HAS_IN_FLIGHT_INSTANCE_VAR, SpawnContractsInvalidError, StoredFieldOpSchema, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assertReadableModel, assertReaderModelAcknowledgement, checkFieldValue, checkWorkflowInvariants, choiceValueIssues, 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, minReaderModelOf, modelStampFor, modelVersionOf, parentRef, parseDefinitionSnapshot, 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 };
3804
+ export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, 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_ALLOWED_VARS, START_FILTER_VARS, SUBJECT_HAS_IN_FLIGHT_INSTANCE_VAR, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assertReadableModel, assertReaderModelAcknowledgement, checkFieldValue, checkWorkflowInvariants, choiceValueIssues, 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, minReaderModelOf, modelStampFor, modelVersionOf, parentRef, parseDefinitionSnapshot, 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 };