@nocobase/plugin-flow-engine 2.1.0-alpha.18 → 2.1.0-alpha.19

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.
Files changed (56) hide show
  1. package/dist/externalVersion.js +11 -11
  2. package/dist/node_modules/ses/package.json +1 -1
  3. package/dist/node_modules/zod/package.json +1 -1
  4. package/dist/server/flow-surfaces/action-scope.js +3 -1
  5. package/dist/server/flow-surfaces/apply/compiler.js +84 -5
  6. package/dist/server/flow-surfaces/approval/blueprint-service.d.ts +84 -0
  7. package/dist/server/flow-surfaces/approval/blueprint-service.js +589 -0
  8. package/dist/server/flow-surfaces/approval/blueprint.d.ts +21 -0
  9. package/dist/server/flow-surfaces/approval/blueprint.js +190 -0
  10. package/dist/server/flow-surfaces/approval/builder.d.ts +225 -0
  11. package/dist/server/flow-surfaces/approval/builder.js +384 -0
  12. package/dist/server/flow-surfaces/approval/catalog-specs.d.ts +33 -0
  13. package/dist/server/flow-surfaces/approval/catalog-specs.js +156 -0
  14. package/dist/server/flow-surfaces/approval/index.d.ts +14 -0
  15. package/dist/server/flow-surfaces/approval/index.js +40 -0
  16. package/dist/server/flow-surfaces/approval/runtime-config.d.ts +44 -0
  17. package/dist/server/flow-surfaces/approval/runtime-config.js +299 -0
  18. package/dist/server/flow-surfaces/approval/semantic-use.d.ts +23 -0
  19. package/dist/server/flow-surfaces/approval/semantic-use.js +155 -0
  20. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +36 -2
  21. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +7 -0
  22. package/dist/server/flow-surfaces/builder.d.ts +2 -0
  23. package/dist/server/flow-surfaces/builder.js +83 -10
  24. package/dist/server/flow-surfaces/catalog.d.ts +10 -0
  25. package/dist/server/flow-surfaces/catalog.js +368 -9
  26. package/dist/server/flow-surfaces/chart-config.d.ts +1 -1
  27. package/dist/server/flow-surfaces/compose-compiler.d.ts +1 -0
  28. package/dist/server/flow-surfaces/compose-compiler.js +2 -1
  29. package/dist/server/flow-surfaces/configure-options.js +61 -3
  30. package/dist/server/flow-surfaces/constants.d.ts +342 -5
  31. package/dist/server/flow-surfaces/constants.js +59 -125
  32. package/dist/server/flow-surfaces/default-action-popup.d.ts +1 -0
  33. package/dist/server/flow-surfaces/default-action-popup.js +6 -2
  34. package/dist/server/flow-surfaces/field-semantics.js +2 -1
  35. package/dist/server/flow-surfaces/index.js +21 -273
  36. package/dist/server/flow-surfaces/locator.js +8 -6
  37. package/dist/server/flow-surfaces/node-use-sets.js +15 -3
  38. package/dist/server/flow-surfaces/placement.js +11 -7
  39. package/dist/server/flow-surfaces/planning/action-specs.d.ts +1 -1
  40. package/dist/server/flow-surfaces/planning/compiler.d.ts +1 -1
  41. package/dist/server/flow-surfaces/planning/key-kind.js +7 -5
  42. package/dist/server/flow-surfaces/reaction/registry.d.ts +13 -0
  43. package/dist/server/flow-surfaces/reaction/registry.js +13 -0
  44. package/dist/server/flow-surfaces/service-utils.d.ts +10 -14
  45. package/dist/server/flow-surfaces/service-utils.js +4 -2
  46. package/dist/server/flow-surfaces/service.d.ts +63 -1
  47. package/dist/server/flow-surfaces/service.js +1058 -109
  48. package/dist/server/flow-surfaces/surface-context.d.ts +1 -0
  49. package/dist/server/flow-surfaces/surface-context.js +99 -19
  50. package/dist/server/flow-surfaces/types.d.ts +4 -1
  51. package/dist/swagger/flow-surfaces.d.ts +406 -2
  52. package/dist/swagger/flow-surfaces.examples.d.ts +164 -0
  53. package/dist/swagger/flow-surfaces.examples.js +184 -0
  54. package/dist/swagger/flow-surfaces.js +390 -76
  55. package/dist/swagger/index.d.ts +406 -2
  56. package/package.json +2 -2
@@ -30,6 +30,7 @@ __export(flow_surfaces_exports, {
30
30
  });
31
31
  module.exports = __toCommonJS(flow_surfaces_exports);
32
32
  var import_constants = require("../server/flow-surfaces/constants");
33
+ var import_catalog_specs = require("../server/flow-surfaces/approval/catalog-specs");
33
34
  var import_flow_surfaces = require("./flow-surfaces.examples");
34
35
  var import_flow_surfaces2 = require("./flow-surfaces.template-action-docs");
35
36
  var import_flow_surfaces3 = require("./flow-surfaces.template-schemas");
@@ -45,7 +46,7 @@ const FILTER_GROUP_EXAMPLE = {
45
46
  const STRING_OR_INTEGER_SCHEMA = {
46
47
  oneOf: [{ type: "string" }, { type: "integer" }]
47
48
  };
48
- const ACTION_TYPE_ENUM = [
49
+ const BASE_ACTION_TYPE_ENUM = [
49
50
  "filter",
50
51
  "addNew",
51
52
  "popup",
@@ -74,8 +75,10 @@ const ACTION_TYPE_ENUM = [
74
75
  "reset",
75
76
  "collapse"
76
77
  ];
77
- const APPLY_BLUEPRINT_ACTION_TYPE_ENUM = ACTION_TYPE_ENUM.filter((item) => item !== "addChild");
78
- const NON_RECORD_ACTION_TYPE_ENUM = [
78
+ const ACTION_TYPE_ENUM = [...BASE_ACTION_TYPE_ENUM, ...import_catalog_specs.APPROVAL_ACTION_PUBLIC_KEYS];
79
+ const APPLY_BLUEPRINT_ACTION_TYPE_ENUM = BASE_ACTION_TYPE_ENUM.filter((item) => item !== "addChild");
80
+ const APPROVAL_BLUEPRINT_ACTION_TYPE_ENUM = [...import_catalog_specs.APPROVAL_ACTION_PUBLIC_KEYS];
81
+ const BASE_NON_RECORD_ACTION_TYPE_ENUM = [
79
82
  "filter",
80
83
  "addNew",
81
84
  "popup",
@@ -98,6 +101,7 @@ const NON_RECORD_ACTION_TYPE_ENUM = [
98
101
  "reset",
99
102
  "collapse"
100
103
  ];
104
+ const NON_RECORD_ACTION_TYPE_ENUM = [...BASE_NON_RECORD_ACTION_TYPE_ENUM, ...import_catalog_specs.APPROVAL_ACTION_PUBLIC_KEYS];
101
105
  const RECORD_ACTION_TYPE_ENUM = [
102
106
  "popup",
103
107
  "js",
@@ -125,12 +129,16 @@ const APPLY_BLUEPRINT_BLOCK_TYPE_ENUM = [
125
129
  "actionPanel",
126
130
  "jsBlock"
127
131
  ];
132
+ const APPROVAL_BLUEPRINT_BLOCK_TYPE_ENUM = [...import_catalog_specs.APPROVAL_BLOCK_PUBLIC_KEYS];
133
+ const COMPOSE_BLOCK_TYPE_ENUM = [...APPLY_BLUEPRINT_BLOCK_TYPE_ENUM, ...import_catalog_specs.APPROVAL_BLOCK_PUBLIC_KEYS];
128
134
  const ADD_CHILD_TREE_TABLE_NOTE = "`addChild` is only valid when the live target `catalog.recordActions` exposes it, which normally means a table bound to a tree collection with `treeTable` enabled.";
129
135
  const APPLY_BLUEPRINT_ADD_CHILD_NOTE = "`addChild` is not auto-promoted from `actions`; author it only under `recordActions`, and only when the live target `catalog.recordActions` exposes it for a tree table.";
130
136
  const REACTION_FINGERPRINT_DESCRIPTION = "Optional optimistic-concurrency fingerprint from `getReactionMeta.capabilities[].fingerprint`. When provided, the write fails with HTTP 409 if the current slot fingerprint no longer matches.";
131
137
  const REACTION_RULES_REPLACE_DESCRIPTION = "Full replacement payload for the resolved reaction slot. Pass `[]` to clear all rules from that slot.";
132
138
  const REACTION_LOCALIZED_FORM_TARGET_DESCRIPTION = "Reaction write target. Use the live block/action uid for localized edits. For form field-value and form field-linkage writes, keep passing the outer form block uid; the backend resolves the inner form-grid slot automatically.";
133
139
  const REACTION_OUTER_FORM_TARGET_NOTE = "Pass the outer form block uid, not the inner form-grid uid.";
140
+ const REQUEST_POPUP_TRY_TEMPLATE_DESCRIPTION = "When true and no explicit popup.template is provided, the backend tries to auto-select one compatible popup template. Non-relation scenes only match non-relation templates. Relation scenes prefer same-relation templates first, then compatible non-relation templates. When no candidate matches, the request silently falls back to local/default popup behavior.";
141
+ const REQUEST_POPUP_SAVE_AS_TEMPLATE_DESCRIPTION = "Immediately saves explicit local popup blocks as a popup template and converts the created popup to that template reference. Requires local `popup.blocks` and cannot be combined with `popup.template` or `popup.tryTemplate`. When `popup.saveAsTemplate.local` is provided, later `popup.template.local` references in the same compose/applyBlueprint call can reuse that saved popup template.";
134
142
  function ref(name) {
135
143
  return {
136
144
  $ref: `#/components/schemas/${name}`
@@ -225,6 +233,54 @@ function buildReactionWriteRequestSchema(ruleSchemaName) {
225
233
  additionalProperties: false
226
234
  };
227
235
  }
236
+ function buildFlowSurfaceRequestPopupSchema() {
237
+ return {
238
+ type: "object",
239
+ anyOf: [
240
+ {
241
+ required: ["template"]
242
+ },
243
+ {
244
+ required: ["tryTemplate"]
245
+ },
246
+ {
247
+ required: ["defaultType"]
248
+ },
249
+ {
250
+ anyOf: [{ required: ["title"] }, { required: ["mode"] }, { required: ["blocks"] }, { required: ["layout"] }]
251
+ }
252
+ ],
253
+ properties: {
254
+ title: {
255
+ type: "string"
256
+ },
257
+ template: ref("FlowSurfaceRequestPopupTemplateRef"),
258
+ tryTemplate: {
259
+ type: "boolean",
260
+ description: REQUEST_POPUP_TRY_TEMPLATE_DESCRIPTION
261
+ },
262
+ defaultType: {
263
+ type: "string",
264
+ enum: ["view", "edit"],
265
+ description: "When popup content is omitted, asks the backend to prefer a compatible popup template first and otherwise auto-generate a default relation popup. Defaults to `view` for field popups."
266
+ },
267
+ saveAsTemplate: {
268
+ allOf: [ref("FlowSurfaceRequestPopupSaveAsTemplate")],
269
+ description: REQUEST_POPUP_SAVE_AS_TEMPLATE_DESCRIPTION
270
+ },
271
+ mode: {
272
+ type: "string",
273
+ enum: ["append", "replace"]
274
+ },
275
+ blocks: {
276
+ type: "array",
277
+ items: ref("FlowSurfaceComposeBlockSpec")
278
+ },
279
+ layout: ref("FlowSurfaceComposeLayout")
280
+ },
281
+ additionalProperties: false
282
+ };
283
+ }
228
284
  function buildReactionWriteResultSchema(ruleSchemaName) {
229
285
  return {
230
286
  type: "object",
@@ -408,7 +464,7 @@ const actionDocs = {
408
464
  tags: [FLOW_SURFACES_TAG],
409
465
  summary: "Apply a page blueprint to create or replace one Modern page",
410
466
  description: valuesCompatibilityNote(
411
- 'Accepts one simplified JSON page blueprint and compiles it to internal flow-surface operations. The public blueprint describes page structure (`create` or `replace`, page metadata, ordered tabs, blocks, fields, actions, inline popups, optional reusable assets) and optional top-level `reaction.items[]` for whole-page interaction authoring. Each reaction item targets an explicit local key / bind key produced by the same blueprint run. Only explicitly listed reaction items are written. `rules: []` clears the targeted slot. Repeating the same `(type, target)` reaction slot in one blueprint is invalid. In `replace`, reaction targets always bind to the newly produced blueprint result, not historical nodes from the previous page version; if a slot must exist in the resulting surface, include it explicitly instead of relying on omission. Localized reaction edits on an existing surface should use `getReactionMeta` + `set*Rules` instead of applying a whole page blueprint again. The request body is that page-document JSON object itself and must not be JSON-stringified. Wrong: `{ "requestBody": "{\\"version\\":\\"1\\"}" }`. Internal planning details stay hidden. In `create`, `navigation.group.routeId` is the preferred way to target an existing menu group. It is exact-targeting only and cannot be mixed with existing-group metadata such as `icon`, `tooltip`, or `hideInMenu`; applyBlueprint create mode does not mutate existing group metadata, so callers should use `updateMenu` separately when that is required. When only `navigation.group.title` is provided, applyBlueprint reuses one existing same-title group when it is unique, creates a new group when none exists, and rejects ambiguous multi-match cases. Same-title reuse is title-only; if an existing group\'s metadata must change, use low-level `updateMenu` instead of applyBlueprint create. `replace` uses `target.pageSchemaUid`, updates only the explicit page-level fields provided in `page`, maps blueprint tabs to existing route-backed tab slots by index, rewrites each slot in order, removes trailing old tabs, and appends extra new tabs when needed. Tab and block keys are optional in the public blueprint; omit them unless custom layout or cross-block targeting needs a stable in-document identifier. `layout` is only allowed on tabs and inline popup documents; blocks themselves do not accept a `layout` property. Public applyBlueprint blocks do not support generic `form`; use `editForm` or `createForm`. Custom `edit` popups that provide `popup.blocks` must include exactly one `editForm` block; that `editForm` may omit `resource` and then inherits the opener\'s current-record context. When layout is omitted, applyBlueprint auto-generates a simple top-to-bottom layout. When a `replace` run expands a page to multiple tabs while the current page still has `enableTabs=false`, callers must set `page.enableTabs=true` explicitly. The response hides execution internals and returns only the resolved page target and final surface readback.'
467
+ 'Accepts one simplified JSON page blueprint and compiles it to internal flow-surface operations. The public blueprint describes page structure (`create` or `replace`, page metadata, ordered tabs, blocks, fields, actions, inline popups, optional reusable assets) and optional top-level `reaction.items[]` for whole-page interaction authoring. Each reaction item targets an explicit local key / bind key produced by the same blueprint run. Only explicitly listed reaction items are written. `rules: []` clears the targeted slot. Repeating the same `(type, target)` reaction slot in one blueprint is invalid. In `replace`, reaction targets always bind to the newly produced blueprint result, not historical nodes from the previous page version; if a slot must exist in the resulting surface, include it explicitly instead of relying on omission. Localized reaction edits on an existing surface should use `getReactionMeta` + `set*Rules` instead of applying a whole page blueprint again. The request body is that page-document JSON object itself and must not be JSON-stringified. Wrong: `{ "requestBody": "{\\"version\\":\\"1\\"}" }`. Internal planning details stay hidden. In `create`, `navigation.group.routeId` is the preferred way to target an existing menu group. It is exact-targeting only and cannot be mixed with existing-group metadata such as `icon`, `tooltip`, or `hideInMenu`; applyBlueprint create mode does not mutate existing group metadata, so callers should use `updateMenu` separately when that is required. When only `navigation.group.title` is provided, applyBlueprint reuses one existing same-title group when it is unique, creates a new group when none exists, and rejects ambiguous multi-match cases. Same-title reuse is title-only; if an existing group\'s metadata must change, use low-level `updateMenu` instead of applyBlueprint create. `replace` uses `target.pageSchemaUid`, updates only the explicit page-level fields provided in `page`, maps blueprint tabs to existing route-backed tab slots by index, rewrites each slot in order, removes trailing old tabs, and appends extra new tabs when needed. Tab and block keys are optional in the public blueprint; omit them unless custom layout or cross-block targeting needs a stable in-document identifier. `layout` is only allowed on tabs and inline popup documents; blocks themselves do not accept a `layout` property. Public applyBlueprint blocks do not support generic `form`; use `editForm` or `createForm`. Inline popup documents may set `popup.tryTemplate=true` to ask the backend for the best compatible popup template before falling back to local popup content. Inline popup documents may also set `popup.saveAsTemplate={ name, description, local? }` to convert the newly created local popup into a saved popup template immediately, and later inline popups in the same blueprint may reuse that freshly created template through `popup.template={ local, mode }`. Custom `edit` popups that provide `popup.blocks` must include exactly one `editForm` block; that `editForm` may omit `resource` and then inherits the opener\'s current-record context. When layout is omitted, applyBlueprint auto-generates a simple top-to-bottom layout. When a `replace` run expands a page to multiple tabs while the current page still has `enableTabs=false`, callers must set `page.enableTabs=true` explicitly. The response hides execution internals and returns only the resolved page target and final surface readback.'
412
468
  ),
413
469
  requestBody: {
414
470
  required: true,
@@ -431,12 +487,42 @@ const actionDocs = {
431
487
  },
432
488
  responses: responses("FlowSurfaceApplyBlueprintResponse")
433
489
  },
490
+ applyApprovalBlueprint: {
491
+ tags: [FLOW_SURFACES_TAG],
492
+ summary: "Apply an approval blueprint to initiator, approver, or task-card surfaces",
493
+ description: valuesCompatibilityNote(
494
+ "Builds workflow-approval configuration surfaces through the existing flowSurfaces orchestration layer instead of a separate approval resource. This is the preferred whole-surface bootstrap / replace entry for approval initiator, approver, and task-card UIs. Unlike route-backed `applyBlueprint`, this action targets approval-bound FlowModel roots stored on approval workflow trigger config (`workflow.config.approvalUid` / `workflow.config.taskCardUid`) or approval node config (`node.config.approvalUid` / `node.config.taskCardUid`). The backend creates or reuses the correct approval root automatically, rewrites the binding uid, applies a `replace` blueprint to that root, and reconciles approval runtime config derived from approval actions such as withdraw / approve / reject / return / delegate / add-assignee. `surface='initiator'` requires `workflowId` and writes page-like `blocks + layout` into `TriggerChildPageModel -> TriggerChildPageTabModel -> TriggerBlockGridModel`. `surface='approver'` requires `nodeId` and writes page-like `blocks + layout` into `ApprovalChildPageModel -> ApprovalChildPageTabModel -> ApprovalBlockGridModel`. `surface='taskCard'` requires exactly one of `workflowId` or `nodeId` and writes `fields + layout` into `ApplyTaskCardDetailsModel` or `ApprovalTaskCardDetailsModel`. This v1 action does not cover legacy schema-config wiring; it focuses on approval FlowModel construction, binding persistence, and approval runtime-config synchronization. When `layout` is omitted, the backend generates a simple top-to-bottom layout for the resulting blocks or fields."
495
+ ),
496
+ requestBody: {
497
+ required: true,
498
+ content: {
499
+ "application/json": {
500
+ schema: ref("FlowSurfaceApplyApprovalBlueprintRequest"),
501
+ examples: {
502
+ initiator: {
503
+ summary: "Replace an approval initiator surface on the workflow trigger",
504
+ value: import_flow_surfaces.flowSurfaceExamples.applyApprovalBlueprintInitiator
505
+ },
506
+ approver: {
507
+ summary: "Replace an approval approver surface on one approval node",
508
+ value: import_flow_surfaces.flowSurfaceExamples.applyApprovalBlueprintApprover
509
+ },
510
+ taskCard: {
511
+ summary: "Replace an approval task-card surface on one approval node",
512
+ value: import_flow_surfaces.flowSurfaceExamples.applyApprovalBlueprintTaskCard
513
+ }
514
+ }
515
+ }
516
+ }
517
+ },
518
+ responses: responses("FlowSurfaceApplyApprovalBlueprintResponse")
519
+ },
434
520
  ...templateActionDocs,
435
521
  compose: {
436
522
  tags: [FLOW_SURFACES_TAG],
437
523
  summary: "Compose blocks, fields, actions and simple layout under an existing surface",
438
524
  description: valuesCompatibilityNote(
439
- 'Organizes content under an existing page/tab/grid/popup using the public block/action/field semantics as a low-level building primitive. The caller does not need to pass raw `use`, `fieldUse`, or `stepParams`. Blocks, fields, and actions can declare stable `key` values, and the compose result returns the same keys so later orchestration can reference nested popup or form nodes deterministically. Blocks may be created from `template`, and form templates can set `template.usage="fields"` to import only their grid fields. Popup-capable actions and fields may reuse `popup.template`. For collection blocks under a popup, check `catalog.blocks[].resourceBindings` first. The `select / subForm / bulkEditForm` scene is currently recognized only, and popup collection block creation is not supported in that scene.'
525
+ 'Organizes content under an existing page/tab/grid/popup using the public block/action/field semantics as a low-level building primitive. The caller does not need to pass raw `use`, `fieldUse`, or `stepParams`. Blocks, fields, and actions can declare stable `key` values, and the compose result returns the same keys so later orchestration can reference nested popup or form nodes deterministically. Blocks may be created from `template`, and form templates can set `template.usage="fields"` to import only their grid fields. Popup-capable actions and fields may reuse `popup.template`, set `popup.tryTemplate=true` to ask the backend for one compatible popup template before falling back to local/default popup behavior, or set `popup.saveAsTemplate={ name, description, local? }` to immediately save newly created local popup content as a popup template reference. Later popup-capable fields and actions in the same compose call may reuse that freshly created template through `popup.template={ local, mode }`. For collection blocks under a popup, check `catalog.blocks[].resourceBindings` first. The `select / subForm / bulkEditForm` scene is currently recognized only, and popup collection block creation is not supported in that scene. For approval surfaces, use `applyApprovalBlueprint` first to bootstrap or replace the bound approval root; use `compose` only after that root already exists.'
440
526
  ),
441
527
  requestBody: {
442
528
  required: true,
@@ -482,7 +568,7 @@ const actionDocs = {
482
568
  tags: [FLOW_SURFACES_TAG],
483
569
  summary: "Apply simple semantic changes to a page, tab, block, field or action",
484
570
  description: valuesCompatibilityNote(
485
- "Uses simple `changes` to update high-frequency settings such as page/tab titles, table pageSize, field clickToOpen, and action openView/confirm without requiring the caller to know internal paths. For advanced reaction authoring, prefer `getReactionMeta` + `set*Rules`; the raw `assignRules` / `linkageRules` examples here are compatibility-only. Check `catalog.node.configureOptions` together with the relevant catalog item `configureOptions` before calling this action."
571
+ "Uses simple `changes` to update high-frequency settings such as page/tab titles, table pageSize, field clickToOpen, and action openView/confirm without requiring the caller to know internal paths. For advanced reaction authoring, prefer `getReactionMeta` + `set*Rules`; the raw `assignRules` / `linkageRules` examples here are compatibility-only. Check `catalog.node.configureOptions` together with the relevant catalog item `configureOptions` before calling this action. On approval action nodes, this route also accepts approval-specific keys such as `approvalReturn` and `assigneesScope`, and flowSurfaces persists the matching approval runtime config. It does not replace `applyApprovalBlueprint` for whole-surface approval bootstrap."
486
572
  ),
487
573
  requestBody: {
488
574
  required: true,
@@ -676,7 +762,7 @@ const actionDocs = {
676
762
  tags: [FLOW_SURFACES_TAG],
677
763
  summary: "Add a block under a surface or grid container",
678
764
  description: valuesCompatibilityNote(
679
- 'Creates a block by catalog key or an explicitly supported block use. It can also create from `template`, using `mode="reference"` or `mode="copy"`. Form templates may set `template.usage="fields"` to create a fresh host block and import only its grid fields. Popup-capable host nodes automatically receive the popup shell. For collection blocks under a popup, check `catalog.blocks[].resourceBindings` first, then pass the semantic `resource.binding`. The lower-level `resourceInit` is still accepted for compatibility, but the server validates it against popup semantics. `resource` and `resourceInit` are mutually exclusive. The `select / subForm / bulkEditForm` scene is currently recognized only, and popup collection block creation is not supported in that scene. Direct add does not accept raw `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse the public configuration semantics from `configure.changes` plus the catalog item/node `configureOptions`.'
765
+ 'Creates a block by catalog key or an explicitly supported block use. It can also create from `template`, using `mode="reference"` or `mode="copy"`. Form templates may set `template.usage="fields"` to create a fresh host block and import only its grid fields. Popup-capable host nodes automatically receive the popup shell. For collection blocks under a popup, check `catalog.blocks[].resourceBindings` first, then pass the semantic `resource.binding`. The lower-level `resourceInit` is still accepted for compatibility, but the server validates it against popup semantics. `resource` and `resourceInit` are mutually exclusive. The `select / subForm / bulkEditForm` scene is currently recognized only, and popup collection block creation is not supported in that scene. Direct add does not accept raw `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse the public configuration semantics from `configure.changes` plus the catalog item/node `configureOptions`. Approval block keys are only exposed under approval grids and do not auto-create an approval root; bootstrap approval surfaces with `applyApprovalBlueprint` first.'
680
766
  ),
681
767
  requestBody: {
682
768
  required: true,
@@ -710,7 +796,7 @@ const actionDocs = {
710
796
  tags: [FLOW_SURFACES_TAG],
711
797
  summary: "Add a field wrapper and inner field under a field container",
712
798
  description: valuesCompatibilityNote(
713
- "Automatically derives the wrapper/inner-field combination from the container use and the field interface. It can also import a form template through `template`, using `reference` or `copy` mode for the target form grid. `fieldUse` is only kept as a compatibility check and is no longer an arbitrary creation entry. Direct add does not accept raw `wrapperProps` / `fieldProps` / `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse the public configuration semantics from `configure.changes` plus the catalog item/node `configureOptions`. Popup-capable fields can also pass `popup` directly to append a local popup subtree or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. If local openView is enabled but no popup content is provided, the server fills in the popup page/tab/grid shell automatically."
799
+ "Automatically derives the wrapper/inner-field combination from the container use and the field interface. It can also import a form template through `template`, using `reference` or `copy` mode for the target form grid. `fieldUse` is only kept as a compatibility check and is no longer an arbitrary creation entry. Direct add does not accept raw `wrapperProps` / `fieldProps` / `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse the public configuration semantics from `configure.changes` plus the catalog item/node `configureOptions`. Popup-capable fields can also pass `popup` directly to append a local popup subtree or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. `popup.tryTemplate=true` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. `popup.saveAsTemplate={ name, description }` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. If local openView is enabled but no popup content is provided, the server fills in the popup page/tab/grid shell automatically. Under approval forms, direct field creation preserves the `PatternFormFieldModel` inner node semantics and does not allow standalone `jsItem`."
714
800
  ),
715
801
  requestBody: {
716
802
  required: true,
@@ -737,6 +823,18 @@ const actionDocs = {
737
823
  popupTemplate: {
738
824
  summary: "Create a bound field that reuses a saved popup template",
739
825
  value: import_flow_surfaces.flowSurfaceExamples.addFieldPopupTemplate
826
+ },
827
+ autoPopupTemplate: {
828
+ summary: "Create a bound field and let the backend auto-select a compatible popup template",
829
+ value: import_flow_surfaces.flowSurfaceExamples.addFieldAutoPopupTemplate
830
+ },
831
+ defaultEditPopup: {
832
+ summary: "Create a relation field and let the backend auto-complete a default edit popup when no explicit popup content is provided",
833
+ value: import_flow_surfaces.flowSurfaceExamples.addFieldDefaultEditPopup
834
+ },
835
+ savePopupTemplate: {
836
+ summary: "Create a bound field and immediately save its explicit local popup as a popup template",
837
+ value: import_flow_surfaces.flowSurfaceExamples.addFieldSavePopupTemplate
740
838
  }
741
839
  }
742
840
  }
@@ -748,7 +846,7 @@ const actionDocs = {
748
846
  tags: [FLOW_SURFACES_TAG],
749
847
  summary: "Add a non-record action under an allowed block/form/filter-form/action-panel container",
750
848
  description: valuesCompatibilityNote(
751
- "Only non-record actions that are public in the catalog and visible in the current container may be created. Typical cases include table block actions, form submit, filter-form reset, and action-panel actions. Use `addRecordAction` for record actions. Direct add does not accept raw `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse `configure.changes` plus the catalog item/node `configureOptions`. Popup-capable actions may also include `popup` directly to append a popup subtree or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored."
849
+ "Only non-record actions that are public in the catalog and visible in the current container may be created. Typical cases include table block actions, form submit, filter-form reset, and action-panel actions. Use `addRecordAction` for record actions. Direct add does not accept raw `props` / `decoratorProps` / `stepParams` / `flowRegistry`. Use `settings` and reuse `configure.changes` plus the catalog item/node `configureOptions`. Popup-capable actions may also include `popup` directly to append a popup subtree or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. `popup.tryTemplate=true` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. `popup.saveAsTemplate={ name, description }` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. Approval action keys are singleton within one approval form or process form, and flowSurfaces reconciles the related workflow/node runtime config after successful writes."
752
850
  ),
753
851
  requestBody: {
754
852
  required: true,
@@ -771,6 +869,14 @@ const actionDocs = {
771
869
  jsItem: {
772
870
  summary: "Create a form JS item action under a create/edit/form action container",
773
871
  value: import_flow_surfaces.flowSurfaceExamples.addJsItemAction
872
+ },
873
+ autoPopupTemplate: {
874
+ summary: "Create a popup-capable action and let the backend auto-select a compatible popup template",
875
+ value: import_flow_surfaces.flowSurfaceExamples.addAutoPopupAction
876
+ },
877
+ savePopupTemplate: {
878
+ summary: "Create a popup-capable action and immediately save its explicit local popup as a popup template",
879
+ value: import_flow_surfaces.flowSurfaceExamples.addSavePopupAction
774
880
  }
775
881
  }
776
882
  }
@@ -782,7 +888,7 @@ const actionDocs = {
782
888
  tags: [FLOW_SURFACES_TAG],
783
889
  summary: "Add a record action under a record-capable owner target",
784
890
  description: valuesCompatibilityNote(
785
- `Only record actions that are public in the catalog and visible in the current container may be created. The public target must be a record-capable owner target such as table/details/list/gridCard. Do not pass internal container uids such as a table actions column or a list/gridCard item. ${ADD_CHILD_TREE_TABLE_NOTE} Direct add does not accept raw \`props\` / \`decoratorProps\` / \`stepParams\` / \`flowRegistry\`. Use \`settings\` and reuse \`configure.changes\` plus the catalog item/node \`configureOptions\`. Popup-capable actions may also include \`popup\` directly to append a popup subtree or \`popup.template\` to reuse a saved popup template in \`reference\` / \`copy\` mode. When \`popup.template\` is present, \`popup.title\` still applies, while local \`popup.mode\` / \`popup.blocks\` / \`popup.layout\` are accepted but ignored.`
891
+ `Only record actions that are public in the catalog and visible in the current container may be created. The public target must be a record-capable owner target such as table/details/list/gridCard. Do not pass internal container uids such as a table actions column or a list/gridCard item. ${ADD_CHILD_TREE_TABLE_NOTE} Direct add does not accept raw \`props\` / \`decoratorProps\` / \`stepParams\` / \`flowRegistry\`. Use \`settings\` and reuse \`configure.changes\` plus the catalog item/node \`configureOptions\`. Popup-capable actions may also include \`popup\` directly to append a popup subtree or \`popup.template\` to reuse a saved popup template in \`reference\` / \`copy\` mode. \`popup.tryTemplate=true\` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. \`popup.saveAsTemplate={ name, description }\` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When \`popup.template\` is present, \`popup.title\` still applies, while local \`popup.mode\` / \`popup.blocks\` / \`popup.layout\` are accepted but ignored.`
786
892
  ),
787
893
  requestBody: {
788
894
  required: true,
@@ -801,6 +907,14 @@ const actionDocs = {
801
907
  js: {
802
908
  summary: "Create a JS record action under a details block owner target",
803
909
  value: import_flow_surfaces.flowSurfaceExamples.addRecordJsAction
910
+ },
911
+ autoPopupTemplate: {
912
+ summary: "Create a view/edit-like record action and let the backend auto-select a compatible popup template",
913
+ value: import_flow_surfaces.flowSurfaceExamples.addRecordAutoPopupTemplate
914
+ },
915
+ savePopupTemplate: {
916
+ summary: "Create a view/edit-like record action and immediately save its explicit local popup as a popup template",
917
+ value: import_flow_surfaces.flowSurfaceExamples.addRecordSavePopupTemplate
804
918
  }
805
919
  }
806
920
  }
@@ -821,7 +935,7 @@ const actionDocs = {
821
935
  tags: [FLOW_SURFACES_TAG],
822
936
  summary: "Add multiple fields sequentially under the same target",
823
937
  description: valuesCompatibilityNote(
824
- "Creates multiple fields sequentially under the same target. The request may either import one shared `template` or create explicit `fields[]`. Each item may include `settings`, and popup-capable fields may also include `popup` directly for local popup content or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. Raw `wrapperProps` / `fieldProps` / `props` / `decoratorProps` / `stepParams` / `flowRegistry` are not accepted. Partial-success semantics apply: a failure in one item does not roll back the others. Results are returned in input order as `index/key/ok/result/error`, and each `error` always includes `message/type/code/status`."
938
+ "Creates multiple fields sequentially under the same target. The request may either import one shared `template` or create explicit `fields[]`. Each item may include `settings`, and popup-capable fields may also include `popup` directly for local popup content or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. `popup.tryTemplate=true` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. `popup.saveAsTemplate={ name, description }` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. Raw `wrapperProps` / `fieldProps` / `props` / `decoratorProps` / `stepParams` / `flowRegistry` are not accepted. Partial-success semantics apply: a failure in one item does not roll back the others. Results are returned in input order as `index/key/ok/result/error`, and each `error` always includes `message/type/code/status`."
825
939
  ),
826
940
  requestBody: requestBody("FlowSurfaceAddFieldsRequest", import_flow_surfaces.flowSurfaceExamples.addFields),
827
941
  responses: responses("FlowSurfaceAddFieldsResult")
@@ -830,7 +944,7 @@ const actionDocs = {
830
944
  tags: [FLOW_SURFACES_TAG],
831
945
  summary: "Add multiple non-record actions sequentially under the same target",
832
946
  description: valuesCompatibilityNote(
833
- "Creates multiple non-record actions sequentially under the same target. Each item may include `settings`, and popup-capable actions may also include `popup` directly for local popup content or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. Raw `props` / `decoratorProps` / `stepParams` / `flowRegistry` are not accepted. Partial-success semantics apply. Record actions do not belong to this entry and should use `addRecordActions` instead. Each failed item always returns an `error` with `message/type/code/status`."
947
+ "Creates multiple non-record actions sequentially under the same target. Each item may include `settings`, and popup-capable actions may also include `popup` directly for local popup content or `popup.template` to reuse a saved popup template in `reference` / `copy` mode. `popup.tryTemplate=true` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. `popup.saveAsTemplate={ name, description }` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When `popup.template` is present, `popup.title` still applies, while local `popup.mode` / `popup.blocks` / `popup.layout` are accepted but ignored. Raw `props` / `decoratorProps` / `stepParams` / `flowRegistry` are not accepted. Partial-success semantics apply. Record actions do not belong to this entry and should use `addRecordActions` instead. Each failed item always returns an `error` with `message/type/code/status`."
834
948
  ),
835
949
  requestBody: requestBody("FlowSurfaceAddActionsRequest", import_flow_surfaces.flowSurfaceExamples.addActions),
836
950
  responses: responses("FlowSurfaceAddActionsResult")
@@ -839,7 +953,7 @@ const actionDocs = {
839
953
  tags: [FLOW_SURFACES_TAG],
840
954
  summary: "Add multiple record actions sequentially under the same record-capable owner target",
841
955
  description: valuesCompatibilityNote(
842
- `Creates multiple record actions sequentially under the same target. The target must be a record-capable owner target, and the server resolves the canonical record-action container automatically. Do not pass internal container uids such as a table actions column or a list/gridCard item. ${ADD_CHILD_TREE_TABLE_NOTE} Each item may include \`settings\`, and popup-capable actions may also include \`popup\` directly for local popup content or \`popup.template\` to reuse a saved popup template in \`reference\` / \`copy\` mode. When \`popup.template\` is present, \`popup.title\` still applies, while local \`popup.mode\` / \`popup.blocks\` / \`popup.layout\` are accepted but ignored. Raw \`props\` / \`decoratorProps\` / \`stepParams\` / \`flowRegistry\` are not accepted. Partial-success semantics apply: a failure in one item does not roll back the others. Each failed item always returns an \`error\` with \`message/type/code/status\`.`
956
+ `Creates multiple record actions sequentially under the same target. The target must be a record-capable owner target, and the server resolves the canonical record-action container automatically. Do not pass internal container uids such as a table actions column or a list/gridCard item. ${ADD_CHILD_TREE_TABLE_NOTE} Each item may include \`settings\`, and popup-capable actions may also include \`popup\` directly for local popup content or \`popup.template\` to reuse a saved popup template in \`reference\` / \`copy\` mode. \`popup.tryTemplate=true\` asks the backend to auto-select a compatible popup template first, preferring the same relation when one exists and otherwise falling back to a compatible non-relation template. \`popup.saveAsTemplate={ name, description }\` saves explicit local popup blocks as a popup template and converts the created popup to that reference immediately. When \`popup.template\` is present, \`popup.title\` still applies, while local \`popup.mode\` / \`popup.blocks\` / \`popup.layout\` are accepted but ignored. Raw \`props\` / \`decoratorProps\` / \`stepParams\` / \`flowRegistry\` are not accepted. Partial-success semantics apply: a failure in one item does not roll back the others. Each failed item always returns an \`error\` with \`message/type/code/status\`.`
843
957
  ),
844
958
  requestBody: {
845
959
  required: true,
@@ -1586,6 +1700,7 @@ const schemas = {
1586
1700
  use: {
1587
1701
  type: "string"
1588
1702
  },
1703
+ popup: ref("FlowSurfaceApplyNodePopup"),
1589
1704
  props: ANY_OBJECT_SCHEMA,
1590
1705
  decoratorProps: ANY_OBJECT_SCHEMA,
1591
1706
  stepParams: ANY_OBJECT_SCHEMA,
@@ -1605,9 +1720,26 @@ const schemas = {
1605
1720
  },
1606
1721
  additionalProperties: false
1607
1722
  },
1723
+ FlowSurfaceApplyNodePopup: {
1724
+ type: "object",
1725
+ properties: {
1726
+ template: ref("FlowSurfacePopupTemplateRef"),
1727
+ tryTemplate: {
1728
+ type: "boolean",
1729
+ description: "Apply-only popup shortcut for popup-capable field/action child nodes. When true and no explicit template is provided, the backend tries the same auto-selection rule as add/compose popup inputs."
1730
+ },
1731
+ defaultType: {
1732
+ type: "string",
1733
+ enum: ["view", "edit"],
1734
+ description: "When popup content is omitted, asks the backend to prefer a compatible popup template first and otherwise auto-generate a default relation popup of the requested type."
1735
+ }
1736
+ },
1737
+ additionalProperties: false
1738
+ },
1608
1739
  FlowSurfaceApplySpec: {
1609
1740
  type: "object",
1610
1741
  properties: {
1742
+ popup: ref("FlowSurfaceApplyNodePopup"),
1611
1743
  props: ANY_OBJECT_SCHEMA,
1612
1744
  decoratorProps: ANY_OBJECT_SCHEMA,
1613
1745
  stepParams: ANY_OBJECT_SCHEMA,
@@ -1969,7 +2101,7 @@ const schemas = {
1969
2101
  description: "Reference to another compose block key, typically used by filter-form fields."
1970
2102
  },
1971
2103
  settings: ANY_OBJECT_SCHEMA,
1972
- popup: ref("FlowSurfaceComposeFieldPopup")
2104
+ popup: ref("FlowSurfaceComposeRequestFieldPopup")
1973
2105
  },
1974
2106
  additionalProperties: false
1975
2107
  },
@@ -2031,18 +2163,88 @@ const schemas = {
2031
2163
  FlowSurfacePopupTemplateRef: {
2032
2164
  allOf: [ref("FlowSurfaceTemplateRef")]
2033
2165
  },
2166
+ FlowSurfacePopupSaveAsTemplate: {
2167
+ type: "object",
2168
+ required: ["name", "description"],
2169
+ properties: {
2170
+ name: {
2171
+ type: "string",
2172
+ description: "Template name saved immediately from explicit local popup content."
2173
+ },
2174
+ description: {
2175
+ type: "string",
2176
+ description: "Template description saved immediately from explicit local popup content."
2177
+ }
2178
+ },
2179
+ additionalProperties: false
2180
+ },
2181
+ FlowSurfaceRequestPopupTemplateRef: {
2182
+ type: "object",
2183
+ oneOf: [{ required: ["uid"] }, { required: ["local"] }],
2184
+ properties: {
2185
+ uid: {
2186
+ type: "string",
2187
+ description: "Saved template uid."
2188
+ },
2189
+ local: {
2190
+ type: "string",
2191
+ description: "Request-scoped popup template alias produced earlier by `popup.saveAsTemplate.local` in the same compose/applyBlueprint call. The alias itself is not persisted."
2192
+ },
2193
+ mode: {
2194
+ type: "string",
2195
+ enum: ["reference", "copy"],
2196
+ default: "reference"
2197
+ }
2198
+ },
2199
+ additionalProperties: false
2200
+ },
2201
+ FlowSurfaceRequestPopupSaveAsTemplate: {
2202
+ type: "object",
2203
+ required: ["name", "description"],
2204
+ properties: {
2205
+ name: {
2206
+ type: "string",
2207
+ description: "Template name saved immediately from explicit local popup content."
2208
+ },
2209
+ description: {
2210
+ type: "string",
2211
+ description: "Template description saved immediately from explicit local popup content."
2212
+ },
2213
+ local: {
2214
+ type: "string",
2215
+ description: "Optional request-scoped alias that later `popup.template.local` references can consume within the same compose/applyBlueprint call. The alias itself is not persisted."
2216
+ }
2217
+ },
2218
+ additionalProperties: false
2219
+ },
2220
+ FlowSurfaceComposeRequestActionPopup: buildFlowSurfaceRequestPopupSchema(),
2221
+ FlowSurfaceComposeRequestFieldPopup: buildFlowSurfaceRequestPopupSchema(),
2034
2222
  FlowSurfaceComposeActionPopup: {
2035
2223
  type: "object",
2036
- oneOf: [
2224
+ anyOf: [
2037
2225
  {
2038
2226
  required: ["template"]
2039
2227
  },
2040
2228
  {
2041
- anyOf: [{ required: ["mode"] }, { required: ["blocks"] }, { required: ["layout"] }]
2229
+ required: ["tryTemplate"]
2230
+ },
2231
+ {
2232
+ anyOf: [{ required: ["title"] }, { required: ["mode"] }, { required: ["blocks"] }, { required: ["layout"] }]
2042
2233
  }
2043
2234
  ],
2044
2235
  properties: {
2236
+ title: {
2237
+ type: "string"
2238
+ },
2045
2239
  template: ref("FlowSurfacePopupTemplateRef"),
2240
+ tryTemplate: {
2241
+ type: "boolean",
2242
+ description: "When true and no explicit popup.template is provided, the backend tries to auto-select one compatible popup template. Non-relation scenes only match non-relation templates. Relation scenes prefer same-relation templates first, then compatible non-relation templates. When no candidate matches, the request silently falls back to local/default popup behavior."
2243
+ },
2244
+ saveAsTemplate: {
2245
+ allOf: [ref("FlowSurfacePopupSaveAsTemplate")],
2246
+ description: "Immediately saves explicit local popup blocks as a popup template and converts the created popup to that template reference. Requires local `popup.blocks` and cannot be combined with `popup.template` or `popup.tryTemplate`."
2247
+ },
2046
2248
  mode: {
2047
2249
  type: "string",
2048
2250
  enum: ["append", "replace"]
@@ -2057,16 +2259,38 @@ const schemas = {
2057
2259
  },
2058
2260
  FlowSurfaceComposeFieldPopup: {
2059
2261
  type: "object",
2060
- oneOf: [
2262
+ anyOf: [
2061
2263
  {
2062
2264
  required: ["template"]
2063
2265
  },
2064
2266
  {
2065
- anyOf: [{ required: ["mode"] }, { required: ["blocks"] }, { required: ["layout"] }]
2267
+ required: ["tryTemplate"]
2268
+ },
2269
+ {
2270
+ required: ["defaultType"]
2271
+ },
2272
+ {
2273
+ anyOf: [{ required: ["title"] }, { required: ["mode"] }, { required: ["blocks"] }, { required: ["layout"] }]
2066
2274
  }
2067
2275
  ],
2068
2276
  properties: {
2277
+ title: {
2278
+ type: "string"
2279
+ },
2069
2280
  template: ref("FlowSurfacePopupTemplateRef"),
2281
+ tryTemplate: {
2282
+ type: "boolean",
2283
+ description: "When true and no explicit popup.template is provided, the backend tries to auto-select one compatible popup template. Non-relation scenes only match non-relation templates. Relation scenes prefer same-relation templates first, then compatible non-relation templates. When no candidate matches, the request silently falls back to local/default popup behavior."
2284
+ },
2285
+ defaultType: {
2286
+ type: "string",
2287
+ enum: ["view", "edit"],
2288
+ description: "When popup content is omitted, the backend prefers a compatible popup template first and otherwise auto-generates a default relation popup of the requested type."
2289
+ },
2290
+ saveAsTemplate: {
2291
+ allOf: [ref("FlowSurfacePopupSaveAsTemplate")],
2292
+ description: "Immediately saves explicit local popup blocks as a popup template and converts the created popup to that template reference. Requires local `popup.blocks` and cannot be combined with `popup.template` or `popup.tryTemplate`."
2293
+ },
2070
2294
  mode: {
2071
2295
  type: "string",
2072
2296
  enum: ["append", "replace"]
@@ -2096,6 +2320,30 @@ const schemas = {
2096
2320
  enum: NON_RECORD_ACTION_TYPE_ENUM
2097
2321
  },
2098
2322
  settings: ANY_OBJECT_SCHEMA,
2323
+ popup: ref("FlowSurfaceComposeRequestActionPopup")
2324
+ },
2325
+ additionalProperties: false
2326
+ }
2327
+ ]
2328
+ },
2329
+ FlowSurfaceApprovalBlueprintActionSpec: {
2330
+ oneOf: [
2331
+ {
2332
+ type: "string",
2333
+ enum: APPROVAL_BLUEPRINT_ACTION_TYPE_ENUM
2334
+ },
2335
+ {
2336
+ type: "object",
2337
+ required: ["type"],
2338
+ properties: {
2339
+ key: {
2340
+ type: "string"
2341
+ },
2342
+ type: {
2343
+ type: "string",
2344
+ enum: APPROVAL_BLUEPRINT_ACTION_TYPE_ENUM
2345
+ },
2346
+ settings: ANY_OBJECT_SCHEMA,
2099
2347
  popup: ref("FlowSurfaceComposeActionPopup")
2100
2348
  },
2101
2349
  additionalProperties: false
@@ -2119,7 +2367,7 @@ const schemas = {
2119
2367
  enum: RECORD_ACTION_TYPE_ENUM
2120
2368
  },
2121
2369
  settings: ANY_OBJECT_SCHEMA,
2122
- popup: ref("FlowSurfaceComposeActionPopup")
2370
+ popup: ref("FlowSurfaceComposeRequestActionPopup")
2123
2371
  },
2124
2372
  additionalProperties: false
2125
2373
  }
@@ -2135,20 +2383,7 @@ const schemas = {
2135
2383
  },
2136
2384
  type: {
2137
2385
  type: "string",
2138
- enum: [
2139
- "table",
2140
- "createForm",
2141
- "editForm",
2142
- "details",
2143
- "filterForm",
2144
- "list",
2145
- "gridCard",
2146
- "markdown",
2147
- "iframe",
2148
- "chart",
2149
- "actionPanel",
2150
- "jsBlock"
2151
- ]
2386
+ enum: COMPOSE_BLOCK_TYPE_ENUM
2152
2387
  },
2153
2388
  template: ref("FlowSurfaceBlockTemplateRef"),
2154
2389
  resource: ref("FlowSurfaceBlockResourceInput"),
@@ -2170,6 +2405,30 @@ const schemas = {
2170
2405
  },
2171
2406
  additionalProperties: false
2172
2407
  },
2408
+ FlowSurfaceApprovalBlueprintBlockSpec: {
2409
+ type: "object",
2410
+ required: ["key", "type"],
2411
+ properties: {
2412
+ key: {
2413
+ type: "string"
2414
+ },
2415
+ type: {
2416
+ type: "string",
2417
+ enum: APPROVAL_BLUEPRINT_BLOCK_TYPE_ENUM
2418
+ },
2419
+ resource: ref("FlowSurfaceBlockResourceInput"),
2420
+ settings: ANY_OBJECT_SCHEMA,
2421
+ fields: {
2422
+ type: "array",
2423
+ items: ref("FlowSurfaceComposeFieldSpec")
2424
+ },
2425
+ actions: {
2426
+ type: "array",
2427
+ items: ref("FlowSurfaceApprovalBlueprintActionSpec")
2428
+ }
2429
+ },
2430
+ additionalProperties: false
2431
+ },
2173
2432
  FlowSurfaceComposeRequest: {
2174
2433
  type: "object",
2175
2434
  required: ["target"],
@@ -2281,20 +2540,7 @@ const schemas = {
2281
2540
  },
2282
2541
  type: {
2283
2542
  type: "string",
2284
- enum: [
2285
- "table",
2286
- "createForm",
2287
- "editForm",
2288
- "details",
2289
- "filterForm",
2290
- "list",
2291
- "gridCard",
2292
- "markdown",
2293
- "iframe",
2294
- "chart",
2295
- "actionPanel",
2296
- "jsBlock"
2297
- ]
2543
+ enum: COMPOSE_BLOCK_TYPE_ENUM
2298
2544
  },
2299
2545
  uid: {
2300
2546
  type: "string"
@@ -3053,7 +3299,20 @@ const schemas = {
3053
3299
  type: "string",
3054
3300
  enum: ["append", "replace"]
3055
3301
  },
3056
- template: ref("FlowSurfacePopupTemplateRef"),
3302
+ template: ref("FlowSurfaceRequestPopupTemplateRef"),
3303
+ tryTemplate: {
3304
+ type: "boolean",
3305
+ description: "When true and no explicit popup.template is provided, applyBlueprint asks the backend to auto-select one compatible popup template. Non-relation scenes only match non-relation templates. Relation scenes prefer same-relation templates first, then compatible non-relation templates. When no candidate matches, inline popup blocks/layout still act as the fallback if present."
3306
+ },
3307
+ defaultType: {
3308
+ type: "string",
3309
+ enum: ["view", "edit"],
3310
+ description: "When popup content is omitted, applyBlueprint prefers a compatible popup template first and otherwise auto-generates a default relation popup of the requested type."
3311
+ },
3312
+ saveAsTemplate: {
3313
+ allOf: [ref("FlowSurfaceRequestPopupSaveAsTemplate")],
3314
+ description: "Immediately saves explicit local popup blocks as a popup template and converts the created popup to that template reference. Requires local `popup.blocks` and cannot be combined with `popup.template` or `popup.tryTemplate`. When `popup.saveAsTemplate.local` is provided, later `popup.template.local` references in the same blueprint can reuse that saved popup template."
3315
+ },
3057
3316
  blocks: {
3058
3317
  type: "array",
3059
3318
  description: "Inline popup blocks. For custom `edit` popups, provide exactly one `editForm` block plus any optional sibling blocks.",
@@ -3336,6 +3595,87 @@ const schemas = {
3336
3595
  },
3337
3596
  additionalProperties: false
3338
3597
  },
3598
+ FlowSurfaceApprovalBlueprintSurface: {
3599
+ type: "string",
3600
+ enum: ["initiator", "approver", "taskCard"]
3601
+ },
3602
+ FlowSurfaceApplyApprovalBlueprintBinding: {
3603
+ type: "object",
3604
+ required: ["resourceName", "filterByTk", "configPath"],
3605
+ properties: {
3606
+ resourceName: {
3607
+ type: "string",
3608
+ enum: ["workflows", "flow_nodes"]
3609
+ },
3610
+ filterByTk: STRING_OR_INTEGER_SCHEMA,
3611
+ configPath: {
3612
+ type: "string"
3613
+ }
3614
+ },
3615
+ additionalProperties: false
3616
+ },
3617
+ FlowSurfaceApplyApprovalBlueprintTarget: {
3618
+ type: "object",
3619
+ required: ["uid"],
3620
+ properties: {
3621
+ uid: {
3622
+ type: "string"
3623
+ },
3624
+ workflowId: STRING_OR_INTEGER_SCHEMA,
3625
+ nodeId: STRING_OR_INTEGER_SCHEMA
3626
+ },
3627
+ additionalProperties: false
3628
+ },
3629
+ FlowSurfaceApplyApprovalBlueprintRequest: {
3630
+ type: "object",
3631
+ required: ["surface"],
3632
+ description: "Simplified approval-surface blueprint request for workflow approval UIs. This is the preferred bootstrap / replace route for approval initiator, approver, and task-card surfaces. `version` may be omitted and defaults to '1'. `mode` may be omitted and defaults to `replace`; v1 only supports `replace`. Runtime validation enforces binding rules: `initiator` requires `workflowId`, `approver` requires `nodeId`, and `taskCard` requires exactly one of `workflowId` or `nodeId`. Page-like surfaces (`initiator`, `approver`) accept `blocks + layout`; `taskCard` accepts `fields + layout`. This route does not perform schema wiring, but it does persist binding fields and reconcile approval runtime config from approval actions.",
3633
+ properties: {
3634
+ version: {
3635
+ type: "string",
3636
+ enum: ["1"]
3637
+ },
3638
+ mode: {
3639
+ type: "string",
3640
+ enum: ["replace"],
3641
+ default: "replace"
3642
+ },
3643
+ surface: ref("FlowSurfaceApprovalBlueprintSurface"),
3644
+ workflowId: STRING_OR_INTEGER_SCHEMA,
3645
+ nodeId: STRING_OR_INTEGER_SCHEMA,
3646
+ blocks: {
3647
+ type: "array",
3648
+ items: ref("FlowSurfaceApprovalBlueprintBlockSpec"),
3649
+ description: "Page-like approval content for `initiator` and `approver` surfaces."
3650
+ },
3651
+ fields: {
3652
+ type: "array",
3653
+ items: ref("FlowSurfaceComposeFieldSpec"),
3654
+ description: "Task-card field list for `taskCard` surfaces."
3655
+ },
3656
+ layout: ref("FlowSurfaceComposeLayout")
3657
+ },
3658
+ additionalProperties: false
3659
+ },
3660
+ FlowSurfaceApplyApprovalBlueprintResponse: {
3661
+ type: "object",
3662
+ required: ["version", "mode", "surfaceType", "target", "binding", "surface"],
3663
+ properties: {
3664
+ version: {
3665
+ type: "string",
3666
+ enum: ["1"]
3667
+ },
3668
+ mode: {
3669
+ type: "string",
3670
+ enum: ["replace"]
3671
+ },
3672
+ surfaceType: ref("FlowSurfaceApprovalBlueprintSurface"),
3673
+ target: ref("FlowSurfaceApplyApprovalBlueprintTarget"),
3674
+ binding: ref("FlowSurfaceApplyApprovalBlueprintBinding"),
3675
+ surface: ref("FlowSurfaceGetResponse")
3676
+ },
3677
+ additionalProperties: false
3678
+ },
3339
3679
  FlowSurfaceConfigureRequest: {
3340
3680
  type: "object",
3341
3681
  required: ["target", "changes"],
@@ -3809,20 +4149,7 @@ const schemas = {
3809
4149
  target: ref("FlowSurfaceWriteTarget"),
3810
4150
  type: {
3811
4151
  type: "string",
3812
- enum: [
3813
- "table",
3814
- "createForm",
3815
- "editForm",
3816
- "details",
3817
- "filterForm",
3818
- "list",
3819
- "gridCard",
3820
- "markdown",
3821
- "iframe",
3822
- "chart",
3823
- "actionPanel",
3824
- "jsBlock"
3825
- ]
4152
+ enum: COMPOSE_BLOCK_TYPE_ENUM
3826
4153
  },
3827
4154
  use: {
3828
4155
  type: "string"
@@ -4086,20 +4413,7 @@ const schemas = {
4086
4413
  },
4087
4414
  type: {
4088
4415
  type: "string",
4089
- enum: [
4090
- "table",
4091
- "createForm",
4092
- "editForm",
4093
- "details",
4094
- "filterForm",
4095
- "list",
4096
- "gridCard",
4097
- "markdown",
4098
- "iframe",
4099
- "chart",
4100
- "actionPanel",
4101
- "jsBlock"
4102
- ]
4416
+ enum: COMPOSE_BLOCK_TYPE_ENUM
4103
4417
  },
4104
4418
  use: {
4105
4419
  type: "string"