@nocobase/plugin-flow-engine 2.2.0-alpha.3 → 2.2.0-alpha.5

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 (26) hide show
  1. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextApis.js +2 -2
  2. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextEnvs.js +2 -2
  3. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/getContextVars.js +2 -2
  4. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/lintAndTestJS.js +2 -2
  5. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/patchJSCode.js +2 -2
  6. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/readJSCode.js +2 -2
  7. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/writeJSCode.js +2 -2
  8. package/dist/externalVersion.js +9 -9
  9. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  10. package/dist/node_modules/acorn/package.json +1 -1
  11. package/dist/node_modules/acorn-jsx/package.json +1 -1
  12. package/dist/node_modules/acorn-walk/package.json +1 -1
  13. package/dist/node_modules/ses/package.json +1 -1
  14. package/dist/node_modules/zod/package.json +1 -1
  15. package/dist/server/flow-surfaces/authoring-validation.d.ts +2 -1
  16. package/dist/server/flow-surfaces/authoring-validation.js +24 -10
  17. package/dist/server/flow-surfaces/blueprint/compile-plan.js +19 -15
  18. package/dist/server/flow-surfaces/blueprint/normalize-document.js +2 -1
  19. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +1 -0
  20. package/dist/server/flow-surfaces/builder.js +24 -4
  21. package/dist/server/flow-surfaces/service.d.ts +11 -0
  22. package/dist/server/flow-surfaces/service.js +251 -24
  23. package/dist/swagger/flow-surfaces.d.ts +12 -0
  24. package/dist/swagger/flow-surfaces.js +18 -6
  25. package/dist/swagger/index.d.ts +12 -0
  26. package/package.json +2 -2
@@ -36,8 +36,8 @@ var getContextApis_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.getContextApis.title")}}`,
40
- about: `{{t("ai.tools.getContextApis.about")}}`
39
+ title: `{{t("ai.tools.getContextApis.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.getContextApis.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "getContextApis",
@@ -36,8 +36,8 @@ var getContextEnvs_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.getContextEnvs.title")}}`,
40
- about: `{{t("ai.tools.getContextEnvs.about")}}`
39
+ title: `{{t("ai.tools.getContextEnvs.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.getContextEnvs.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "getContextEnvs",
@@ -36,8 +36,8 @@ var getContextVars_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.getContextVars.title")}}`,
40
- about: `{{t("ai.tools.getContextVars.about")}}`
39
+ title: `{{t("ai.tools.getContextVars.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.getContextVars.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "getContextVars",
@@ -36,8 +36,8 @@ var lintAndTestJS_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.lintAndTestJS.title")}}`,
40
- about: `{{t("ai.tools.lintAndTestJS.about")}}`
39
+ title: `{{t("ai.tools.lintAndTestJS.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.lintAndTestJS.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "lintAndTestJS",
@@ -36,8 +36,8 @@ var patchJSCode_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.patchJSCode.title")}}`,
40
- about: `{{t("ai.tools.patchJSCode.about")}}`
39
+ title: `{{t("ai.tools.patchJSCode.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.patchJSCode.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "patchJSCode",
@@ -36,8 +36,8 @@ var readJSCode_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.readJSCode.title")}}`,
40
- about: `{{t("ai.tools.readJSCode.about")}}`
39
+ title: `{{t("ai.tools.readJSCode.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.readJSCode.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "readJSCode",
@@ -36,8 +36,8 @@ var writeJSCode_default = (0, import_ai.defineTools)({
36
36
  execution: "frontend",
37
37
  defaultPermission: "ALLOW",
38
38
  introduction: {
39
- title: `{{t("ai.tools.writeJSCode.title")}}`,
40
- about: `{{t("ai.tools.writeJSCode.about")}}`
39
+ title: `{{t("ai.tools.writeJSCode.title", { ns: "@nocobase/plugin-ai" })}}`,
40
+ about: `{{t("ai.tools.writeJSCode.about", { ns: "@nocobase/plugin-ai" })}}`
41
41
  },
42
42
  definition: {
43
43
  name: "writeJSCode",
@@ -8,16 +8,16 @@
8
8
  */
9
9
 
10
10
  module.exports = {
11
- "@nocobase/client": "2.2.0-alpha.3",
11
+ "@nocobase/client": "2.2.0-alpha.5",
12
12
  "lodash": "4.18.1",
13
- "@nocobase/database": "2.2.0-alpha.3",
14
- "@nocobase/data-source-manager": "2.2.0-alpha.3",
15
- "@nocobase/resourcer": "2.2.0-alpha.3",
16
- "@nocobase/utils": "2.2.0-alpha.3",
17
- "@nocobase/cache": "2.2.0-alpha.3",
18
- "@nocobase/server": "2.2.0-alpha.3",
19
- "@nocobase/actions": "2.2.0-alpha.3",
13
+ "@nocobase/database": "2.2.0-alpha.5",
14
+ "@nocobase/data-source-manager": "2.2.0-alpha.5",
15
+ "@nocobase/resourcer": "2.2.0-alpha.5",
16
+ "@nocobase/utils": "2.2.0-alpha.5",
17
+ "@nocobase/cache": "2.2.0-alpha.5",
18
+ "@nocobase/server": "2.2.0-alpha.5",
19
+ "@nocobase/actions": "2.2.0-alpha.5",
20
20
  "sequelize": "6.35.2",
21
21
  "@formily/json-schema": "2.3.7",
22
- "@nocobase/ai": "2.2.0-alpha.3"
22
+ "@nocobase/ai": "2.2.0-alpha.5"
23
23
  };
@@ -1 +1 @@
1
- {"name":"@ant-design/icons-svg","version":"4.3.1","sideEffects":false,"description":"Abstract nodes for ant design icons.","contributors":["HeskeyBaozi <hezhiyu233@foxmail.com>"],"homepage":"https://github.com/ant-design/ant-design-icons/","license":"MIT","main":"lib/index.js","module":"es/index.js","files":["lib","es","inline-svg","inline-namespaced-svg"],"repository":{"type":"git","url":"git+https://github.com/ant-design/ant-design-icons.git"},"scripts":{"g":"npm run generate","generate":"cross-env NODE_ENV=production gulp --require ts-node/register/transpile-only","type-check":"tsc --noEmit","build:es":"tsc --project tsconfig.build.json --module esnext --outDir es","build:lib":"tsc --project tsconfig.build.json --module commonjs --outDir lib","build":"cross-env NODE_ENV=production && npm run build:es && npm run build:lib","test":"cross-env NODE_ENV=test && npm run test:unit","test:unit":"jest","prepublishOnly":"npm run test && npm run g && npm run build && npm run type-check && npm run digest","digest":"node scripts/digest.js"},"bugs":{"url":"https://github.com/ant-design/ant-design-icons/issues"},"devDependencies":{"@babel/core":"^7.8.6","@babel/preset-env":"^7.8.6","@babel/preset-typescript":"^7.8.3","@rgrove/parse-xml":"^2.0.2","@types/gulp":"^4.0.6","@types/gulp-concat":"^0.0.32","@types/gulp-rename":"^0.0.33","@types/jest":"^25.1.3","@types/lodash.camelcase":"^4.3.6","@types/lodash.template":"^4.4.6","@types/lodash.upperfirst":"^4.3.6","@types/node":"^13.9.3","@types/ramda":"^0.26.43","@types/rgrove__parse-xml":"^1.1.0","@types/svgo":"^1.3.1","@types/through2":"^2.0.34","@typescript-eslint/eslint-plugin":"^2.21.0","@typescript-eslint/parser":"^2.21.0","babel-jest":"^25.1.0","cross-env":"^7.0.0","del":"^5.1.0","eslint":"^7.16.0","globby":"^11.0.0","gulp":"^4.0.2","gulp-clone":"^2.0.1","gulp-concat":"^2.6.1","gulp-header":"^2.0.9","gulp-rename":"^2.0.0","jest":"^25.1.0","lodash.camelcase":"^4.3.0","lodash.template":"^4.5.0","lodash.upperfirst":"^4.3.1","ramda":"^0.27.0","svgo":"^1.3.2","through2":"^3.0.1","ts-node":"^8.6.2","typescript":"^4.0.0","vinyl":"^2.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_lastModified":"2026-06-27T03:55:53.722Z"}
1
+ {"name":"@ant-design/icons-svg","version":"4.3.1","sideEffects":false,"description":"Abstract nodes for ant design icons.","contributors":["HeskeyBaozi <hezhiyu233@foxmail.com>"],"homepage":"https://github.com/ant-design/ant-design-icons/","license":"MIT","main":"lib/index.js","module":"es/index.js","files":["lib","es","inline-svg","inline-namespaced-svg"],"repository":{"type":"git","url":"git+https://github.com/ant-design/ant-design-icons.git"},"scripts":{"g":"npm run generate","generate":"cross-env NODE_ENV=production gulp --require ts-node/register/transpile-only","type-check":"tsc --noEmit","build:es":"tsc --project tsconfig.build.json --module esnext --outDir es","build:lib":"tsc --project tsconfig.build.json --module commonjs --outDir lib","build":"cross-env NODE_ENV=production && npm run build:es && npm run build:lib","test":"cross-env NODE_ENV=test && npm run test:unit","test:unit":"jest","prepublishOnly":"npm run test && npm run g && npm run build && npm run type-check && npm run digest","digest":"node scripts/digest.js"},"bugs":{"url":"https://github.com/ant-design/ant-design-icons/issues"},"devDependencies":{"@babel/core":"^7.8.6","@babel/preset-env":"^7.8.6","@babel/preset-typescript":"^7.8.3","@rgrove/parse-xml":"^2.0.2","@types/gulp":"^4.0.6","@types/gulp-concat":"^0.0.32","@types/gulp-rename":"^0.0.33","@types/jest":"^25.1.3","@types/lodash.camelcase":"^4.3.6","@types/lodash.template":"^4.4.6","@types/lodash.upperfirst":"^4.3.6","@types/node":"^13.9.3","@types/ramda":"^0.26.43","@types/rgrove__parse-xml":"^1.1.0","@types/svgo":"^1.3.1","@types/through2":"^2.0.34","@typescript-eslint/eslint-plugin":"^2.21.0","@typescript-eslint/parser":"^2.21.0","babel-jest":"^25.1.0","cross-env":"^7.0.0","del":"^5.1.0","eslint":"^7.16.0","globby":"^11.0.0","gulp":"^4.0.2","gulp-clone":"^2.0.1","gulp-concat":"^2.6.1","gulp-header":"^2.0.9","gulp-rename":"^2.0.0","jest":"^25.1.0","lodash.camelcase":"^4.3.0","lodash.template":"^4.5.0","lodash.upperfirst":"^4.3.1","ramda":"^0.27.0","svgo":"^1.3.2","through2":"^3.0.1","ts-node":"^8.6.2","typescript":"^4.0.0","vinyl":"^2.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_lastModified":"2026-07-04T02:09:37.413Z"}
@@ -1 +1 @@
1
- {"name":"acorn","description":"ECMAScript parser","homepage":"https://github.com/acornjs/acorn","main":"dist/acorn.js","types":"dist/acorn.d.ts","module":"dist/acorn.mjs","exports":{".":[{"import":"./dist/acorn.mjs","require":"./dist/acorn.js","default":"./dist/acorn.js"},"./dist/acorn.js"],"./package.json":"./package.json"},"version":"8.11.2","engines":{"node":">=0.4.0"},"maintainers":[{"name":"Marijn Haverbeke","email":"marijnh@gmail.com","web":"https://marijnhaverbeke.nl"},{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"https://rreverser.com/"},{"name":"Adrian Heine","web":"http://adrianheine.de"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn.git"},"license":"MIT","scripts":{"prepare":"cd ..; npm run build:main"},"bin":{"acorn":"./bin/acorn"},"_lastModified":"2026-06-27T03:55:54.609Z"}
1
+ {"name":"acorn","description":"ECMAScript parser","homepage":"https://github.com/acornjs/acorn","main":"dist/acorn.js","types":"dist/acorn.d.ts","module":"dist/acorn.mjs","exports":{".":[{"import":"./dist/acorn.mjs","require":"./dist/acorn.js","default":"./dist/acorn.js"},"./dist/acorn.js"],"./package.json":"./package.json"},"version":"8.11.2","engines":{"node":">=0.4.0"},"maintainers":[{"name":"Marijn Haverbeke","email":"marijnh@gmail.com","web":"https://marijnhaverbeke.nl"},{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"https://rreverser.com/"},{"name":"Adrian Heine","web":"http://adrianheine.de"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn.git"},"license":"MIT","scripts":{"prepare":"cd ..; npm run build:main"},"bin":{"acorn":"./bin/acorn"},"_lastModified":"2026-07-04T02:09:38.572Z"}
@@ -1 +1 @@
1
- {"name":"acorn-jsx","description":"Modern, fast React.js JSX parser","homepage":"https://github.com/acornjs/acorn-jsx","version":"5.3.2","maintainers":[{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"http://rreverser.com/"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn-jsx"},"license":"MIT","scripts":{"test":"node test/run.js"},"peerDependencies":{"acorn":"^6.0.0 || ^7.0.0 || ^8.0.0"},"devDependencies":{"acorn":"^8.0.1"},"_lastModified":"2026-06-27T03:55:55.027Z"}
1
+ {"name":"acorn-jsx","description":"Modern, fast React.js JSX parser","homepage":"https://github.com/acornjs/acorn-jsx","version":"5.3.2","maintainers":[{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"http://rreverser.com/"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn-jsx"},"license":"MIT","scripts":{"test":"node test/run.js"},"peerDependencies":{"acorn":"^6.0.0 || ^7.0.0 || ^8.0.0"},"devDependencies":{"acorn":"^8.0.1"},"_lastModified":"2026-07-04T02:09:39.010Z"}
@@ -1 +1 @@
1
- {"name":"acorn-walk","description":"ECMAScript (ESTree) AST walker","homepage":"https://github.com/acornjs/acorn","main":"dist/walk.js","types":"dist/walk.d.ts","module":"dist/walk.mjs","exports":{".":[{"import":"./dist/walk.mjs","require":"./dist/walk.js","default":"./dist/walk.js"},"./dist/walk.js"],"./package.json":"./package.json"},"version":"8.3.4","engines":{"node":">=0.4.0"},"dependencies":{"acorn":"^8.11.0"},"maintainers":[{"name":"Marijn Haverbeke","email":"marijnh@gmail.com","web":"https://marijnhaverbeke.nl"},{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"https://rreverser.com/"},{"name":"Adrian Heine","web":"http://adrianheine.de"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn.git"},"scripts":{"prepare":"cd ..; npm run build:walk"},"license":"MIT","_lastModified":"2026-06-27T03:55:55.140Z"}
1
+ {"name":"acorn-walk","description":"ECMAScript (ESTree) AST walker","homepage":"https://github.com/acornjs/acorn","main":"dist/walk.js","types":"dist/walk.d.ts","module":"dist/walk.mjs","exports":{".":[{"import":"./dist/walk.mjs","require":"./dist/walk.js","default":"./dist/walk.js"},"./dist/walk.js"],"./package.json":"./package.json"},"version":"8.3.4","engines":{"node":">=0.4.0"},"dependencies":{"acorn":"^8.11.0"},"maintainers":[{"name":"Marijn Haverbeke","email":"marijnh@gmail.com","web":"https://marijnhaverbeke.nl"},{"name":"Ingvar Stepanyan","email":"me@rreverser.com","web":"https://rreverser.com/"},{"name":"Adrian Heine","web":"http://adrianheine.de"}],"repository":{"type":"git","url":"https://github.com/acornjs/acorn.git"},"scripts":{"prepare":"cd ..; npm run build:walk"},"license":"MIT","_lastModified":"2026-07-04T02:09:39.124Z"}
@@ -1 +1 @@
1
- {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-06-27T03:55:54.218Z"}
1
+ {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-07-04T02:09:38.117Z"}
@@ -1 +1 @@
1
- {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-06-27T03:55:56.267Z"}
1
+ {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-07-04T02:09:40.247Z"}
@@ -13,7 +13,8 @@ export interface FlowSurfaceAuthoringValidationContext {
13
13
  applyBlueprintScriptAssets?: Record<string, any>;
14
14
  getCollection?: (dataSourceKey: string, collectionName: string) => any;
15
15
  getDefaultFieldGroups?: (dataSourceKey: string, collectionName: string) => any;
16
- findMenuGroupRoutesByTitle?: (title: string, transaction?: any) => Promise<any[]>;
16
+ findMenuGroupRoutesByTitle?: (title: string, transaction?: any, layoutUid?: string | string[]) => Promise<any[]>;
17
+ getUiLayoutTypeByUid?: (layoutUid: string, transaction?: any) => Promise<string | undefined>;
17
18
  transaction?: any;
18
19
  hostBlockType?: string;
19
20
  hostCollectionName?: string;
@@ -525,10 +525,13 @@ function pushChartBadRequestAuthoringError(errors, error, fallbackPath) {
525
525
  });
526
526
  }
527
527
  async function collectNavigationGroupErrors(actionName, values, context, errors) {
528
- var _a;
528
+ var _a, _b;
529
529
  if (actionName !== "applyBlueprint" || (values == null ? void 0 : values.mode) !== "create" || !_.isPlainObject((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.group)) {
530
530
  return;
531
531
  }
532
+ if (await isApplyBlueprintMobileCreateNavigation(values, context)) {
533
+ return;
534
+ }
532
535
  if (!_.isUndefined(values.navigation.group.routeId) || !context.findMenuGroupRoutesByTitle) {
533
536
  return;
534
537
  }
@@ -536,7 +539,8 @@ async function collectNavigationGroupErrors(actionName, values, context, errors)
536
539
  if (!groupTitle) {
537
540
  return;
538
541
  }
539
- const matchedRoutes = await context.findMenuGroupRoutesByTitle(groupTitle, context.transaction);
542
+ const layoutUid = String(((_b = values == null ? void 0 : values.navigation) == null ? void 0 : _b.layoutUid) || "").trim() || void 0;
543
+ const matchedRoutes = await context.findMenuGroupRoutesByTitle(groupTitle, context.transaction, layoutUid);
540
544
  const rootMatchedRoutes = filterRootMenuGroupRoutes(matchedRoutes);
541
545
  if (rootMatchedRoutes.length <= 1) {
542
546
  return;
@@ -553,15 +557,17 @@ async function collectNavigationGroupErrors(actionName, values, context, errors)
553
557
  });
554
558
  }
555
559
  async function collectNavigationIconErrors(actionName, values, context, errors) {
556
- var _a, _b, _c;
560
+ var _a, _b, _c, _d;
557
561
  if (actionName !== "applyBlueprint" || (values == null ? void 0 : values.mode) !== "create") {
558
562
  return;
559
563
  }
564
+ const isMobileCreateNavigation = await isApplyBlueprintMobileCreateNavigation(values, context);
560
565
  const group = _.isPlainObject((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.group) ? values.navigation.group : null;
561
566
  const groupRouteId = String((group == null ? void 0 : group.routeId) || "").trim();
562
- if (group && !groupRouteId && group.hideInMenu !== true) {
567
+ const layoutUid = String(((_b = values == null ? void 0 : values.navigation) == null ? void 0 : _b.layoutUid) || "").trim() || void 0;
568
+ if (!isMobileCreateNavigation && group && !groupRouteId && group.hideInMenu !== true) {
563
569
  const groupIcon = String(group.icon || "").trim();
564
- if (!groupIcon && await shouldRequireNewNavigationGroupIcon(group, context)) {
570
+ if (!groupIcon && await shouldRequireNewNavigationGroupIcon(group, context, layoutUid)) {
565
571
  pushAuthoringError(errors, {
566
572
  path: "$.navigation.group.icon",
567
573
  ruleId: "navigation-icon-required",
@@ -580,7 +586,7 @@ async function collectNavigationIconErrors(actionName, values, context, errors)
580
586
  }
581
587
  });
582
588
  }
583
- } else if (group && String(group.icon || "").trim() && !isValidAntDesignIconName(group.icon)) {
589
+ } else if (!isMobileCreateNavigation && group && String(group.icon || "").trim() && !isValidAntDesignIconName(group.icon)) {
584
590
  pushAuthoringError(errors, {
585
591
  path: "$.navigation.group.icon",
586
592
  ruleId: "navigation-icon-unknown",
@@ -590,7 +596,7 @@ async function collectNavigationIconErrors(actionName, values, context, errors)
590
596
  }
591
597
  });
592
598
  }
593
- const item = _.isPlainObject((_b = values == null ? void 0 : values.navigation) == null ? void 0 : _b.item) ? values.navigation.item : null;
599
+ const item = _.isPlainObject((_c = values == null ? void 0 : values.navigation) == null ? void 0 : _c.item) ? values.navigation.item : null;
594
600
  const itemIcon = String((item == null ? void 0 : item.icon) || "").trim();
595
601
  if (itemIcon && !isValidAntDesignIconName(itemIcon)) {
596
602
  pushAuthoringError(errors, {
@@ -602,7 +608,7 @@ async function collectNavigationIconErrors(actionName, values, context, errors)
602
608
  }
603
609
  });
604
610
  }
605
- const pageIcon = String(((_c = values == null ? void 0 : values.page) == null ? void 0 : _c.icon) || "").trim();
611
+ const pageIcon = String(((_d = values == null ? void 0 : values.page) == null ? void 0 : _d.icon) || "").trim();
606
612
  if (pageIcon && !isValidAntDesignIconName(pageIcon)) {
607
613
  pushAuthoringError(errors, {
608
614
  path: "$.page.icon",
@@ -614,12 +620,20 @@ async function collectNavigationIconErrors(actionName, values, context, errors)
614
620
  });
615
621
  }
616
622
  }
617
- async function shouldRequireNewNavigationGroupIcon(group, context) {
623
+ async function isApplyBlueprintMobileCreateNavigation(values, context) {
624
+ var _a;
625
+ const layoutUid = String(((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.layoutUid) || "").trim();
626
+ if (!layoutUid || !context.getUiLayoutTypeByUid) {
627
+ return false;
628
+ }
629
+ return await context.getUiLayoutTypeByUid(layoutUid, context.transaction) === "mobile";
630
+ }
631
+ async function shouldRequireNewNavigationGroupIcon(group, context, layoutUid) {
618
632
  const groupTitle = String((group == null ? void 0 : group.title) || "").trim();
619
633
  if (!groupTitle || !context.findMenuGroupRoutesByTitle) {
620
634
  return true;
621
635
  }
622
- const matchedRoutes = await context.findMenuGroupRoutesByTitle(groupTitle, context.transaction);
636
+ const matchedRoutes = await context.findMenuGroupRoutesByTitle(groupTitle, context.transaction, layoutUid);
623
637
  return filterRootMenuGroupRoutes(matchedRoutes).length === 0;
624
638
  }
625
639
  function filterRootMenuGroupRoutes(routes) {
@@ -83,19 +83,21 @@ function buildTabSelectorFromUid(uid) {
83
83
  };
84
84
  }
85
85
  function compileCreatePlan(document, getCollection) {
86
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
86
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
87
87
  const steps = [];
88
88
  const chrome = buildPageChrome(document);
89
- if (import_lodash.default.isPlainObject((_a = document.navigation) == null ? void 0 : _a.group) && import_lodash.default.isUndefined(document.navigation.group.routeId)) {
89
+ const layoutUid = (_a = document.navigation) == null ? void 0 : _a.layoutUid;
90
+ if (import_lodash.default.isPlainObject((_b = document.navigation) == null ? void 0 : _b.group) && import_lodash.default.isUndefined(document.navigation.group.routeId)) {
90
91
  steps.push({
91
92
  id: CREATE_MENU_GROUP_STEP_ID,
92
93
  action: "createMenu",
93
94
  values: (0, import_service_utils.buildDefinedPayload)({
94
- title: (_c = (_b = document.navigation) == null ? void 0 : _b.group) == null ? void 0 : _c.title,
95
+ layoutUid,
96
+ title: (_d = (_c = document.navigation) == null ? void 0 : _c.group) == null ? void 0 : _d.title,
95
97
  type: "group",
96
- icon: (_e = (_d = document.navigation) == null ? void 0 : _d.group) == null ? void 0 : _e.icon,
97
- tooltip: (_g = (_f = document.navigation) == null ? void 0 : _f.group) == null ? void 0 : _g.tooltip,
98
- hideInMenu: (_i = (_h = document.navigation) == null ? void 0 : _h.group) == null ? void 0 : _i.hideInMenu
98
+ icon: (_f = (_e = document.navigation) == null ? void 0 : _e.group) == null ? void 0 : _f.icon,
99
+ tooltip: (_h = (_g = document.navigation) == null ? void 0 : _g.group) == null ? void 0 : _h.tooltip,
100
+ hideInMenu: (_j = (_i = document.navigation) == null ? void 0 : _i.group) == null ? void 0 : _j.hideInMenu
99
101
  })
100
102
  });
101
103
  }
@@ -103,25 +105,27 @@ function compileCreatePlan(document, getCollection) {
103
105
  id: CREATE_MENU_ITEM_STEP_ID,
104
106
  action: "createMenu",
105
107
  values: (0, import_service_utils.buildDefinedPayload)({
106
- title: ((_k = (_j = document.navigation) == null ? void 0 : _j.item) == null ? void 0 : _k.title) || chrome.pageTitle,
108
+ layoutUid,
109
+ title: ((_l = (_k = document.navigation) == null ? void 0 : _k.item) == null ? void 0 : _l.title) || chrome.pageTitle,
107
110
  type: "item",
108
- icon: ((_m = (_l = document.navigation) == null ? void 0 : _l.item) == null ? void 0 : _m.icon) || ((_n = document.page) == null ? void 0 : _n.icon) || "FileOutlined",
109
- tooltip: (_p = (_o = document.navigation) == null ? void 0 : _o.item) == null ? void 0 : _p.tooltip,
110
- hideInMenu: (_r = (_q = document.navigation) == null ? void 0 : _q.item) == null ? void 0 : _r.hideInMenu,
111
- parentMenuRouteId: import_lodash.default.isUndefined((_t = (_s = document.navigation) == null ? void 0 : _s.group) == null ? void 0 : _t.routeId) ? ((_v = (_u = document.navigation) == null ? void 0 : _u.group) == null ? void 0 : _v.title) ? { step: CREATE_MENU_GROUP_STEP_ID, path: "routeId" } : void 0 : (_x = (_w = document.navigation) == null ? void 0 : _w.group) == null ? void 0 : _x.routeId
111
+ icon: ((_n = (_m = document.navigation) == null ? void 0 : _m.item) == null ? void 0 : _n.icon) || ((_o = document.page) == null ? void 0 : _o.icon) || "FileOutlined",
112
+ tooltip: (_q = (_p = document.navigation) == null ? void 0 : _p.item) == null ? void 0 : _q.tooltip,
113
+ hideInMenu: (_s = (_r = document.navigation) == null ? void 0 : _r.item) == null ? void 0 : _s.hideInMenu,
114
+ parentMenuRouteId: import_lodash.default.isUndefined((_u = (_t = document.navigation) == null ? void 0 : _t.group) == null ? void 0 : _u.routeId) ? ((_w = (_v = document.navigation) == null ? void 0 : _v.group) == null ? void 0 : _w.title) ? { step: CREATE_MENU_GROUP_STEP_ID, path: "routeId" } : void 0 : (_y = (_x = document.navigation) == null ? void 0 : _x.group) == null ? void 0 : _y.routeId
112
115
  })
113
116
  });
114
117
  steps.push({
115
118
  id: CREATE_PAGE_STEP_ID,
116
119
  action: "createPage",
117
120
  values: (0, import_service_utils.buildDefinedPayload)({
121
+ layoutUid,
118
122
  menuRouteId: { step: CREATE_MENU_ITEM_STEP_ID, path: "routeId" },
119
123
  title: chrome.pageTitle,
120
- icon: (_y = document.page) == null ? void 0 : _y.icon,
121
- documentTitle: (_z = document.page) == null ? void 0 : _z.documentTitle,
122
- enableHeader: (_A = document.page) == null ? void 0 : _A.enableHeader,
124
+ icon: (_z = document.page) == null ? void 0 : _z.icon,
125
+ documentTitle: (_A = document.page) == null ? void 0 : _A.documentTitle,
126
+ enableHeader: (_B = document.page) == null ? void 0 : _B.enableHeader,
123
127
  enableTabs: chrome.enableTabs,
124
- displayTitle: (_B = document.page) == null ? void 0 : _B.displayTitle,
128
+ displayTitle: (_C = document.page) == null ? void 0 : _C.displayTitle,
125
129
  tabTitle: chrome.tabTitle,
126
130
  tabIcon: chrome.tabIcon,
127
131
  tabDocumentTitle: chrome.tabDocumentTitle,
@@ -132,8 +132,9 @@ function normalizeNavigation(input) {
132
132
  return void 0;
133
133
  }
134
134
  (0, import_private_utils.assertPlainObject)(input, "flowSurfaces applyBlueprint navigation");
135
- (0, import_private_utils.assertOnlyAllowedKeys)(input, "flowSurfaces applyBlueprint navigation", ["group", "item"]);
135
+ (0, import_private_utils.assertOnlyAllowedKeys)(input, "flowSurfaces applyBlueprint navigation", ["layoutUid", "group", "item"]);
136
136
  const normalized = (0, import_service_utils.buildDefinedPayload)({
137
+ layoutUid: (0, import_private_utils.readOptionalString)(input.layoutUid),
137
138
  group: import_lodash.default.isUndefined(input.group) ? void 0 : (() => {
138
139
  (0, import_private_utils.assertPlainObject)(input.group, "flowSurfaces applyBlueprint navigation.group");
139
140
  (0, import_private_utils.assertOnlyAllowedKeys)(input.group, "flowSurfaces applyBlueprint navigation.group", [
@@ -20,6 +20,7 @@ export type FlowSurfaceApplyBlueprintNavigationGroup = {
20
20
  hideInMenu?: boolean;
21
21
  };
22
22
  export type FlowSurfaceApplyBlueprintNavigation = {
23
+ layoutUid?: string;
23
24
  group?: FlowSurfaceApplyBlueprintNavigationGroup;
24
25
  item?: {
25
26
  title?: string;
@@ -819,12 +819,16 @@ function buildActionDefaults(options) {
819
819
  (approvalDefaults == null ? void 0 : approvalDefaults.props) || {}
820
820
  );
821
821
  const normalizedProps = applyContainerActionStyle(props, options.containerUse);
822
+ const buttonGeneralProps = applyCompactRecordActionButtonDefaults(
823
+ pickButtonGeneralProps(normalizedProps),
824
+ options.containerUse
825
+ );
822
826
  const stepParams = import_lodash.default.merge(
823
827
  {},
824
828
  import_lodash.default.cloneDeep((approvalDefaults == null ? void 0 : approvalDefaults.stepParams) || {}),
825
829
  readonlyCalendarAction ? {} : {
826
830
  buttonSettings: {
827
- general: pickButtonGeneralProps(normalizedProps)
831
+ general: buttonGeneralProps
828
832
  }
829
833
  }
830
834
  );
@@ -1135,10 +1139,26 @@ function inferActionDefaultProps(use, scope) {
1135
1139
  }
1136
1140
  );
1137
1141
  }
1142
+ const COMPACT_RECORD_ACTION_CONTAINER_USES = /* @__PURE__ */ new Set([
1143
+ "TableActionsColumnModel",
1144
+ "ListItemModel",
1145
+ "GridCardItemModel",
1146
+ "CommentItemModel"
1147
+ ]);
1148
+ function isCompactRecordActionContainerUse(containerUse) {
1149
+ return COMPACT_RECORD_ACTION_CONTAINER_USES.has(String(containerUse || "").trim());
1150
+ }
1151
+ function applyCompactRecordActionButtonDefaults(props, containerUse) {
1152
+ if (isCompactRecordActionContainerUse(containerUse) && props.icon === null && !Object.prototype.hasOwnProperty.call(props, "iconOnly")) {
1153
+ return {
1154
+ ...props,
1155
+ iconOnly: false
1156
+ };
1157
+ }
1158
+ return props;
1159
+ }
1138
1160
  function applyContainerActionStyle(props, containerUse) {
1139
- if (["TableActionsColumnModel", "ListItemModel", "GridCardItemModel", "CommentItemModel"].includes(
1140
- String(containerUse || "").trim()
1141
- )) {
1161
+ if (isCompactRecordActionContainerUse(containerUse)) {
1142
1162
  return {
1143
1163
  ...props,
1144
1164
  type: "link",
@@ -86,7 +86,16 @@ export declare class FlowSurfacesService {
86
86
  private normalizeDesktopRouteRelationId;
87
87
  private readDesktopRouteUiLayoutUids;
88
88
  private resolveDefaultDesktopRouteUiLayoutUids;
89
+ private findDesktopRouteUiLayoutByUid;
90
+ private getDesktopRouteUiLayoutTypeByUid;
91
+ private isMobileDesktopRouteUiLayoutUid;
89
92
  private resolveInheritedDesktopRouteUiLayoutUids;
93
+ private normalizeExplicitDesktopRouteLayoutUid;
94
+ private normalizeDesktopRouteLayoutUidFilter;
95
+ private resolveDesktopRouteLayoutUidFilter;
96
+ private assertEnabledDesktopRouteUiLayoutUid;
97
+ private assertDesktopRouteBelongsToUiLayout;
98
+ private resolveRequestedDesktopRouteUiLayoutUids;
90
99
  private setDesktopRouteUiLayouts;
91
100
  private attachDesktopRouteUiLayoutsToRouteAndChildren;
92
101
  private ensureDesktopRouteUiLayouts;
@@ -213,6 +222,8 @@ export declare class FlowSurfacesService {
213
222
  private dispatchPlanOnlyAction;
214
223
  private resolveApplyBlueprintReplaceTargetInfo;
215
224
  private resolveApplyBlueprintCreateNavigationGroup;
225
+ private normalizeApplyBlueprintCreateMobileNavigation;
226
+ private assertApplyBlueprintCreateNavigationLayout;
216
227
  private resolveApplyBlueprintCreatePageIdentity;
217
228
  private prepareApplyBlueprintRequest;
218
229
  private prevalidateApplyBlueprintChartAssets;
@@ -690,6 +690,7 @@ function assertNoFlowSurfaceIdTitleFieldSettings(value, options = {}) {
690
690
  visit(value, options.basePath || []);
691
691
  }
692
692
  const DEFAULT_ADMIN_UI_LAYOUT_UID = "admin-layout-model";
693
+ const MOBILE_UI_LAYOUT_TYPE = "mobile";
693
694
  class FlowSurfacesService {
694
695
  constructor(plugin) {
695
696
  this.plugin = plugin;
@@ -923,12 +924,12 @@ class FlowSurfacesService {
923
924
  transaction
924
925
  });
925
926
  }
926
- async findMenuGroupRoutesByTitle(title, transaction) {
927
+ async findMenuGroupRoutesByTitle(title, transaction, layoutUid) {
927
928
  const normalizedTitle = String(title || "").trim();
928
929
  if (!normalizedTitle) {
929
930
  return [];
930
931
  }
931
- return import_lodash.default.castArray(
932
+ const routes = import_lodash.default.castArray(
932
933
  await this.db.getRepository("desktopRoutes").find({
933
934
  filter: {
934
935
  type: "group",
@@ -937,6 +938,18 @@ class FlowSurfacesService {
937
938
  transaction
938
939
  })
939
940
  );
941
+ const layoutUidFilter = await this.resolveDesktopRouteLayoutUidFilter(layoutUid, transaction);
942
+ if (!layoutUidFilter.length || !this.hasDesktopRouteUiLayoutsRelation()) {
943
+ return routes;
944
+ }
945
+ const matchedRoutes = [];
946
+ for (const route of routes) {
947
+ const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(this.readRouteField(route, "id"), transaction);
948
+ if (import_lodash.default.intersection(routeLayoutUids, layoutUidFilter).length) {
949
+ matchedRoutes.push(route);
950
+ }
951
+ }
952
+ return matchedRoutes;
940
953
  }
941
954
  routeParentIdMatches(routeParentId, parentId) {
942
955
  if (import_lodash.default.isNil(routeParentId) && import_lodash.default.isNil(parentId)) {
@@ -944,28 +957,42 @@ class FlowSurfacesService {
944
957
  }
945
958
  return String(routeParentId ?? "") === String(parentId ?? "");
946
959
  }
947
- async findMenuGroupRoutesByParentIdAndTitle(parentId, title, transaction) {
948
- const routes = await this.findMenuGroupRoutesByTitle(title, transaction);
960
+ async findMenuGroupRoutesByParentIdAndTitle(parentId, title, transaction, layoutUid) {
961
+ const routes = await this.findMenuGroupRoutesByTitle(title, transaction, layoutUid);
949
962
  return routes.filter(
950
963
  (route) => this.routeParentIdMatches(this.readRouteField(route, "parentId") ?? null, parentId)
951
964
  );
952
965
  }
953
- async findFlowPageRoutesByParentIdAndTitle(parentId, title, transaction) {
966
+ async findFlowPageRoutesByParentIdAndTitle(parentId, title, transaction, layoutUid) {
954
967
  const normalizedTitle = String(title || "").trim();
955
- const normalizedParentId = String(parentId ?? "").trim();
956
- if (!normalizedTitle || !normalizedParentId) {
968
+ if (!normalizedTitle) {
957
969
  return [];
958
970
  }
959
- return import_lodash.default.castArray(
971
+ const routes = import_lodash.default.castArray(
960
972
  await this.db.getRepository("desktopRoutes").find({
961
- filter: {
973
+ filter: (0, import_service_utils.buildDefinedPayload)({
962
974
  type: "flowPage",
963
975
  title: normalizedTitle,
964
- parentId: normalizedParentId
965
- },
976
+ parentId: import_lodash.default.isNil(parentId) ? void 0 : String(parentId)
977
+ }),
966
978
  transaction
967
979
  })
968
980
  );
981
+ const layoutUidFilter = await this.resolveDesktopRouteLayoutUidFilter(layoutUid, transaction);
982
+ const layoutMatchedRoutes = [];
983
+ if (!layoutUidFilter.length || !this.hasDesktopRouteUiLayoutsRelation()) {
984
+ layoutMatchedRoutes.push(...routes);
985
+ } else {
986
+ for (const route of routes) {
987
+ const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(this.readRouteField(route, "id"), transaction);
988
+ if (import_lodash.default.intersection(routeLayoutUids, layoutUidFilter).length) {
989
+ layoutMatchedRoutes.push(route);
990
+ }
991
+ }
992
+ }
993
+ return layoutMatchedRoutes.filter(
994
+ (route) => this.routeParentIdMatches(this.readRouteField(route, "parentId") ?? null, parentId)
995
+ );
969
996
  }
970
997
  async assertMenuParentIsGroup(parentMenuRouteId, transaction) {
971
998
  if (import_lodash.default.isNil(parentMenuRouteId)) {
@@ -1071,6 +1098,29 @@ class FlowSurfacesService {
1071
1098
  });
1072
1099
  return defaultLayout ? [DEFAULT_ADMIN_UI_LAYOUT_UID] : [];
1073
1100
  }
1101
+ async findDesktopRouteUiLayoutByUid(layoutUid, transaction) {
1102
+ const normalizedLayoutUid = this.normalizeExplicitDesktopRouteLayoutUid(layoutUid);
1103
+ if (!normalizedLayoutUid || !this.hasDesktopRouteUiLayoutsRelation()) {
1104
+ return null;
1105
+ }
1106
+ return this.db.getRepository("uiLayouts").findOne({
1107
+ filter: {
1108
+ uid: normalizedLayoutUid
1109
+ },
1110
+ transaction
1111
+ });
1112
+ }
1113
+ async getDesktopRouteUiLayoutTypeByUid(layoutUid, transaction) {
1114
+ var _a;
1115
+ const uiLayout = await this.findDesktopRouteUiLayoutByUid(layoutUid, transaction);
1116
+ return String(((_a = uiLayout == null ? void 0 : uiLayout.get) == null ? void 0 : _a.call(uiLayout, "layoutType")) || (uiLayout == null ? void 0 : uiLayout.layoutType) || "").trim() || void 0;
1117
+ }
1118
+ async isMobileDesktopRouteUiLayoutUid(layoutUid, transaction) {
1119
+ if (!layoutUid) {
1120
+ return false;
1121
+ }
1122
+ return await this.getDesktopRouteUiLayoutTypeByUid(layoutUid, transaction) === MOBILE_UI_LAYOUT_TYPE;
1123
+ }
1074
1124
  async resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction) {
1075
1125
  const parentRouteId = this.readRouteField(parentRoute, "id");
1076
1126
  if (!import_lodash.default.isNil(parentRouteId)) {
@@ -1081,6 +1131,86 @@ class FlowSurfacesService {
1081
1131
  }
1082
1132
  return this.resolveDefaultDesktopRouteUiLayoutUids(transaction);
1083
1133
  }
1134
+ normalizeExplicitDesktopRouteLayoutUid(value) {
1135
+ const normalized = String(value || "").trim();
1136
+ return normalized || void 0;
1137
+ }
1138
+ normalizeDesktopRouteLayoutUidFilter(value) {
1139
+ return import_lodash.default.uniq(
1140
+ import_lodash.default.castArray(value).map((item) => this.normalizeExplicitDesktopRouteLayoutUid(item)).filter(Boolean)
1141
+ );
1142
+ }
1143
+ async resolveDesktopRouteLayoutUidFilter(value, transaction) {
1144
+ const explicitLayoutUids = this.normalizeDesktopRouteLayoutUidFilter(value);
1145
+ if (explicitLayoutUids.length) {
1146
+ return explicitLayoutUids;
1147
+ }
1148
+ return this.resolveDefaultDesktopRouteUiLayoutUids(transaction);
1149
+ }
1150
+ async assertEnabledDesktopRouteUiLayoutUid(layoutUid, actionName, path, transaction) {
1151
+ if (!this.hasDesktopRouteUiLayoutsRelation()) {
1152
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} requires plugin-ui-layout desktop route relation support`, {
1153
+ ruleId: "navigation-layout-unsupported",
1154
+ path,
1155
+ details: {
1156
+ layoutUid
1157
+ }
1158
+ });
1159
+ }
1160
+ const uiLayout = await this.db.getRepository("uiLayouts").findOne({
1161
+ filter: {
1162
+ uid: layoutUid,
1163
+ enabled: true
1164
+ },
1165
+ transaction
1166
+ });
1167
+ if (!uiLayout) {
1168
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} must reference an enabled ui layout`, {
1169
+ ruleId: "navigation-layout-not-found",
1170
+ path,
1171
+ details: {
1172
+ layoutUid
1173
+ }
1174
+ });
1175
+ }
1176
+ }
1177
+ async assertDesktopRouteBelongsToUiLayout(actionName, route, layoutUid, path, transaction) {
1178
+ const normalizedLayoutUid = this.normalizeExplicitDesktopRouteLayoutUid(layoutUid);
1179
+ if (!normalizedLayoutUid || !route) {
1180
+ return;
1181
+ }
1182
+ const routeId = this.readRouteField(route, "id");
1183
+ const routeLayoutUids = await this.readDesktopRouteUiLayoutUids(routeId, transaction);
1184
+ if (routeLayoutUids.includes(normalizedLayoutUid)) {
1185
+ return;
1186
+ }
1187
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path} does not belong to ui layout '${normalizedLayoutUid}'`, {
1188
+ ruleId: "navigation-route-layout-mismatch",
1189
+ path,
1190
+ details: {
1191
+ routeId,
1192
+ layoutUid: normalizedLayoutUid,
1193
+ routeLayoutUids
1194
+ }
1195
+ });
1196
+ }
1197
+ async resolveRequestedDesktopRouteUiLayoutUids(values, parentRoute, actionName, transaction) {
1198
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(values.layoutUid);
1199
+ if (layoutUid) {
1200
+ await this.assertEnabledDesktopRouteUiLayoutUid(layoutUid, actionName, "values.layoutUid", transaction);
1201
+ if (parentRoute) {
1202
+ await this.assertDesktopRouteBelongsToUiLayout(
1203
+ actionName,
1204
+ parentRoute,
1205
+ layoutUid,
1206
+ "values.parentMenuRouteId",
1207
+ transaction
1208
+ );
1209
+ }
1210
+ return [layoutUid];
1211
+ }
1212
+ return this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction);
1213
+ }
1084
1214
  async setDesktopRouteUiLayouts(routeId, uiLayoutUids, transaction) {
1085
1215
  const relationRouteId = this.normalizeDesktopRouteRelationId(routeId);
1086
1216
  if (import_lodash.default.isUndefined(relationRouteId) || !uiLayoutUids.length || !this.hasDesktopRouteUiLayoutsRelation()) {
@@ -1181,8 +1311,19 @@ class FlowSurfacesService {
1181
1311
  async createFlowMenuGroup(values, transaction) {
1182
1312
  const parentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, transaction);
1183
1313
  const parentId = this.readRouteField(parentRoute, "id") ?? null;
1314
+ const routeUiLayoutUids = await this.resolveRequestedDesktopRouteUiLayoutUids(
1315
+ values,
1316
+ parentRoute,
1317
+ "createMenu",
1318
+ transaction
1319
+ );
1184
1320
  const title = String(values.title || "").trim();
1185
- const existingGroups = await this.findMenuGroupRoutesByParentIdAndTitle(parentId, title, transaction);
1321
+ const existingGroups = await this.findMenuGroupRoutesByParentIdAndTitle(
1322
+ parentId,
1323
+ title,
1324
+ transaction,
1325
+ routeUiLayoutUids
1326
+ );
1186
1327
  if (existingGroups.length === 1) {
1187
1328
  return this.buildMenuResult(existingGroups[0]);
1188
1329
  }
@@ -1222,7 +1363,7 @@ class FlowSurfacesService {
1222
1363
  });
1223
1364
  await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
1224
1365
  this.readRouteField(route, "id"),
1225
- await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction),
1366
+ routeUiLayoutUids,
1226
1367
  transaction
1227
1368
  );
1228
1369
  return this.buildMenuResult(route);
@@ -1230,6 +1371,12 @@ class FlowSurfacesService {
1230
1371
  async createFlowMenuItem(values, transaction) {
1231
1372
  var _a;
1232
1373
  const parentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, transaction);
1374
+ const routeUiLayoutUids = await this.resolveRequestedDesktopRouteUiLayoutUids(
1375
+ values,
1376
+ parentRoute,
1377
+ "createMenu",
1378
+ transaction
1379
+ );
1233
1380
  this.assertVisibleNavigationIcon("createMenu", "values", values);
1234
1381
  const pageSchemaUid = values.pageSchemaUid || (0, import_utils.uid)();
1235
1382
  const menuSchemaUid = (0, import_utils.uid)();
@@ -1276,7 +1423,7 @@ class FlowSurfacesService {
1276
1423
  });
1277
1424
  await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
1278
1425
  this.readRouteField(createdRoute, "id"),
1279
- await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction),
1426
+ routeUiLayoutUids,
1280
1427
  transaction
1281
1428
  );
1282
1429
  const route = await desktopRoutes.findOne({
@@ -1313,7 +1460,7 @@ class FlowSurfacesService {
1313
1460
  });
1314
1461
  }
1315
1462
  sanitizePublicCreateMenuValues(values) {
1316
- return import_lodash.default.pick(values, ["title", "type", "icon", "tooltip", "hideInMenu", "parentMenuRouteId"]);
1463
+ return import_lodash.default.pick(values, ["title", "type", "layoutUid", "icon", "tooltip", "hideInMenu", "parentMenuRouteId"]);
1317
1464
  }
1318
1465
  async loadRouteBackedPageStructure(route, transaction) {
1319
1466
  const routeId = this.readRouteField(route, "id");
@@ -3223,7 +3370,13 @@ class FlowSurfacesService {
3223
3370
  if (!groupTitle) {
3224
3371
  return document;
3225
3372
  }
3226
- const matchedRoutes = await this.findMenuGroupRoutesByParentIdAndTitle(null, groupTitle, transaction);
3373
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(document.navigation.layoutUid);
3374
+ const matchedRoutes = await this.findMenuGroupRoutesByParentIdAndTitle(
3375
+ null,
3376
+ groupTitle,
3377
+ transaction,
3378
+ layoutUid || await this.resolveDefaultDesktopRouteUiLayoutUids(transaction)
3379
+ );
3227
3380
  if (!matchedRoutes.length) {
3228
3381
  return document;
3229
3382
  }
@@ -3248,29 +3401,89 @@ class FlowSurfacesService {
3248
3401
  }
3249
3402
  };
3250
3403
  }
3404
+ async normalizeApplyBlueprintCreateMobileNavigation(document, transaction) {
3405
+ var _a;
3406
+ if (document.mode !== "create") {
3407
+ return document;
3408
+ }
3409
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_a = document.navigation) == null ? void 0 : _a.layoutUid);
3410
+ if (!await this.isMobileDesktopRouteUiLayoutUid(layoutUid, transaction)) {
3411
+ return document;
3412
+ }
3413
+ return {
3414
+ ...document,
3415
+ navigation: (0, import_service_utils.buildDefinedPayload)({
3416
+ ...document.navigation,
3417
+ layoutUid,
3418
+ group: void 0
3419
+ })
3420
+ };
3421
+ }
3422
+ async assertApplyBlueprintCreateNavigationLayout(document, transaction) {
3423
+ var _a, _b, _c;
3424
+ if (document.mode !== "create") {
3425
+ return;
3426
+ }
3427
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_a = document.navigation) == null ? void 0 : _a.layoutUid);
3428
+ if (!layoutUid) {
3429
+ return;
3430
+ }
3431
+ await this.assertEnabledDesktopRouteUiLayoutUid(
3432
+ layoutUid,
3433
+ "applyBlueprint",
3434
+ "values.navigation.layoutUid",
3435
+ transaction
3436
+ );
3437
+ if (await this.isMobileDesktopRouteUiLayoutUid(layoutUid, transaction)) {
3438
+ return;
3439
+ }
3440
+ const groupRouteId = (_c = (_b = document.navigation) == null ? void 0 : _b.group) == null ? void 0 : _c.routeId;
3441
+ if (import_lodash.default.isNil(groupRouteId) || groupRouteId === "") {
3442
+ return;
3443
+ }
3444
+ const groupRoute = await this.assertMenuParentIsGroup(groupRouteId, transaction);
3445
+ await this.assertDesktopRouteBelongsToUiLayout(
3446
+ "applyBlueprint",
3447
+ groupRoute,
3448
+ layoutUid,
3449
+ "values.navigation.group.routeId",
3450
+ transaction
3451
+ );
3452
+ }
3251
3453
  async resolveApplyBlueprintCreatePageIdentity(document, transaction) {
3252
- var _a, _b, _c, _d, _e;
3454
+ var _a, _b, _c, _d, _e, _f;
3253
3455
  if (document.mode !== "create") {
3254
3456
  return document;
3255
3457
  }
3256
3458
  const groupRouteId = (_b = (_a = document.navigation) == null ? void 0 : _a.group) == null ? void 0 : _b.routeId;
3257
- const pageTitle = String(((_c = document.page) == null ? void 0 : _c.title) || ((_e = (_d = document.navigation) == null ? void 0 : _d.item) == null ? void 0 : _e.title) || "").trim();
3258
- if (import_lodash.default.isNil(groupRouteId) || groupRouteId === "" || !pageTitle) {
3459
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid((_c = document.navigation) == null ? void 0 : _c.layoutUid);
3460
+ const pageTitle = String(((_d = document.page) == null ? void 0 : _d.title) || ((_f = (_e = document.navigation) == null ? void 0 : _e.item) == null ? void 0 : _f.title) || "").trim();
3461
+ const hasGroupRouteId = !import_lodash.default.isNil(groupRouteId) && groupRouteId !== "";
3462
+ if (!pageTitle || !hasGroupRouteId && !layoutUid) {
3259
3463
  return document;
3260
3464
  }
3261
- const matchedPages = await this.findFlowPageRoutesByParentIdAndTitle(groupRouteId, pageTitle, transaction);
3465
+ const groupRoute = hasGroupRouteId ? await this.findMenuRouteById(groupRouteId, transaction) : null;
3466
+ const layoutUidFilter = layoutUid || (groupRoute ? await this.resolveInheritedDesktopRouteUiLayoutUids(groupRoute, transaction) : void 0);
3467
+ const matchedPages = await this.findFlowPageRoutesByParentIdAndTitle(
3468
+ hasGroupRouteId ? groupRouteId : null,
3469
+ pageTitle,
3470
+ transaction,
3471
+ layoutUidFilter
3472
+ );
3262
3473
  if (!matchedPages.length) {
3263
3474
  return document;
3264
3475
  }
3265
3476
  if (matchedPages.length > 1) {
3477
+ const locationLabel = hasGroupRouteId ? `under navigation.group.routeId '${groupRouteId}'` : `at the root of ui layout '${layoutUid}'`;
3266
3478
  (0, import_errors.throwBadRequest)(
3267
- `flowSurfaces applyBlueprint navigation.group.routeId '${groupRouteId}' already has ${matchedPages.length} flow pages titled '${pageTitle}'; pass target.pageSchemaUid explicitly before applyBlueprint`
3479
+ `flowSurfaces applyBlueprint ${locationLabel} already has ${matchedPages.length} flow pages titled '${pageTitle}'; pass target.pageSchemaUid explicitly before applyBlueprint`
3268
3480
  );
3269
3481
  }
3270
3482
  const pageSchemaUid = String(this.readRouteField(matchedPages[0], "schemaUid") || "").trim();
3271
3483
  if (!pageSchemaUid) {
3484
+ const locationLabel = hasGroupRouteId ? `under navigation.group.routeId '${groupRouteId}'` : `at the root of ui layout '${layoutUid}'`;
3272
3485
  (0, import_errors.throwBadRequest)(
3273
- `flowSurfaces applyBlueprint existing flow page '${pageTitle}' under navigation.group.routeId '${groupRouteId}' is missing schemaUid; pass target.pageSchemaUid explicitly before applyBlueprint`
3486
+ `flowSurfaces applyBlueprint existing flow page '${pageTitle}' ${locationLabel} is missing schemaUid; pass target.pageSchemaUid explicitly before applyBlueprint`
3274
3487
  );
3275
3488
  }
3276
3489
  return {
@@ -3285,7 +3498,15 @@ class FlowSurfacesService {
3285
3498
  async prepareApplyBlueprintRequest(values, transaction, createdKanbanSortFields) {
3286
3499
  var _a;
3287
3500
  const initialDocument = (0, import_blueprint.prepareFlowSurfaceApplyBlueprintDocument)(values);
3288
- const groupResolvedDocument = await this.resolveApplyBlueprintCreateNavigationGroup(initialDocument, transaction);
3501
+ await this.assertApplyBlueprintCreateNavigationLayout(initialDocument, transaction);
3502
+ const mobileNormalizedDocument = await this.normalizeApplyBlueprintCreateMobileNavigation(
3503
+ initialDocument,
3504
+ transaction
3505
+ );
3506
+ const groupResolvedDocument = await this.resolveApplyBlueprintCreateNavigationGroup(
3507
+ mobileNormalizedDocument,
3508
+ transaction
3509
+ );
3289
3510
  const document = await this.resolveApplyBlueprintCreatePageIdentity(groupResolvedDocument, transaction);
3290
3511
  await this.prepareApplyBlueprintKanbanBlocks(document, transaction, createdKanbanSortFields);
3291
3512
  const replaceTarget = document.mode === "replace" && document.target ? await this.resolveApplyBlueprintReplaceTargetInfo(document.target.pageSchemaUid, transaction) : void 0;
@@ -3942,7 +4163,8 @@ class FlowSurfacesService {
3942
4163
  await (0, import_authoring_validation.assertFlowSurfaceAuthoringPayload)("applyBlueprint", values, {
3943
4164
  transaction: options.transaction,
3944
4165
  enabledPackages,
3945
- findMenuGroupRoutesByTitle: (title, transaction) => this.findMenuGroupRoutesByTitle(title, transaction),
4166
+ findMenuGroupRoutesByTitle: (title, transaction, layoutUid) => this.findMenuGroupRoutesByTitle(title, transaction, layoutUid),
4167
+ getUiLayoutTypeByUid: (layoutUid, transaction) => this.getDesktopRouteUiLayoutTypeByUid(layoutUid, transaction),
3946
4168
  getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey || "main", collectionName || "")
3947
4169
  });
3948
4170
  }
@@ -6026,6 +6248,11 @@ class FlowSurfacesService {
6026
6248
  const pageSchemaUid = this.readRouteField(route, "schemaUid");
6027
6249
  const structure = await this.loadRouteBackedPageStructure(route, transaction);
6028
6250
  let tabRoute = structure.tabRoutes[0];
6251
+ const layoutUid = this.normalizeExplicitDesktopRouteLayoutUid(values.layoutUid);
6252
+ if (layoutUid) {
6253
+ await this.assertEnabledDesktopRouteUiLayoutUid(layoutUid, "createPage", "values.layoutUid", transaction);
6254
+ await this.assertDesktopRouteBelongsToUiLayout("createPage", route, layoutUid, "values.menuRouteId", transaction);
6255
+ }
6029
6256
  const routeUiLayoutUids = await this.ensureDesktopRouteUiLayouts(route, transaction);
6030
6257
  const routeOptions = this.readRouteOptions(route);
6031
6258
  if (!routeOptions[FLOW_SURFACE_MENU_BINDABLE_OPTION_KEY]) {
@@ -2635,6 +2635,10 @@ declare const _default: {
2635
2635
  FlowSurfaceApplyBlueprintNavigation: {
2636
2636
  type: string;
2637
2637
  properties: {
2638
+ layoutUid: {
2639
+ type: string;
2640
+ description: string;
2641
+ };
2638
2642
  group: {
2639
2643
  $ref: string;
2640
2644
  };
@@ -3148,6 +3152,10 @@ declare const _default: {
3148
3152
  type: string;
3149
3153
  required: string[];
3150
3154
  properties: {
3155
+ layoutUid: {
3156
+ type: string;
3157
+ description: string;
3158
+ };
3151
3159
  title: {
3152
3160
  type: string;
3153
3161
  };
@@ -3270,6 +3278,10 @@ declare const _default: {
3270
3278
  FlowSurfaceCreatePageRequest: {
3271
3279
  type: string;
3272
3280
  properties: {
3281
+ layoutUid: {
3282
+ type: string;
3283
+ description: string;
3284
+ };
3273
3285
  menuRouteId: {
3274
3286
  oneOf: {
3275
3287
  type: string;
@@ -623,7 +623,7 @@ const actionDocs = {
623
623
  tags: [FLOW_SURFACES_TAG],
624
624
  summary: "Apply a page blueprint to create or replace one Modern page",
625
625
  description: valuesCompatibilityNote(
626
- `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\` has the highest priority when targeting an existing menu group. If \`routeId\` is present, applyBlueprint ignores \`title\`, \`icon\`, \`tooltip\`, and \`hideInMenu\` on \`navigation.group\`; applyBlueprint create mode does not mutate existing group metadata, so callers should use \`updateMenu\` separately when that is required. When \`routeId\` is omitted and \`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. Metadata such as \`icon\`, \`tooltip\`, and \`hideInMenu\` is used only when a new group is created and is ignored when an existing group is reused. \`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\`. AI employee actions use \`type: "aiEmployee"\` plus public \`settings.username\`, \`workContext\`, \`tasks\`, \`auto\`, and \`style\`; work context may target \`self\` or a same-blueprint block key and is persisted as real Flow Model \`uid\` values. For JS blocks/fields/actions, \`script\` is a non-empty string asset key into \`assets.scripts\`; put inline JS in \`settings.code\` and \`settings.version\`. Direct \`table\` / \`list\` / \`gridCard\` / \`calendar\` / \`kanban\` blocks may omit \`defaultFilter\`; the backend generates one from live metadata with up to 4 scalar/filterable fields. Explicit values must contain at least the smaller of 3 and the collection eligible-field count, and values with more than 4 fields are truncated before persistence. A valid explicit or generated block-level value backfills the default \`filter\` action \`settings.defaultFilter\`; explicit filter-action \`settings.defaultFilter\` still wins. ${TREE_TABLE_RECORD_ACTION_DEFAULTS_NOTE} ${APPLY_BLUEPRINT_TREE_TABLE_TITLE_FIELD_NOTE} 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 combine \`popup.tryTemplate\` with \`popup.saveAsTemplate={ name, description, local? }\`: a hit binds the matched template immediately and lets later inline popups in the same blueprint reuse that final bound template through \`popup.template={ local, mode }\`, while a miss requires explicit local \`popup.blocks\` so the fallback popup can be saved and reused. 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.`
626
+ `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.layoutUid\` optionally scopes menu group reuse, duplicate page identity checks, and newly created routes to an enabled UI layout such as \`admin-layout-model\` or \`mobile-layout-model\`; when the target layout type is mobile, applyBlueprint ignores \`navigation.group\` and creates a root-level mobile tab page. When \`layoutUid\` is omitted, routes keep the existing admin/default inheritance behavior. In non-mobile \`create\`, \`navigation.group.routeId\` has the highest priority when targeting an existing menu group. If \`routeId\` is present, applyBlueprint ignores \`title\`, \`icon\`, \`tooltip\`, and \`hideInMenu\` on \`navigation.group\`; applyBlueprint create mode does not mutate existing group metadata, so callers should use \`updateMenu\` separately when that is required. When \`routeId\` is omitted and \`navigation.group.title\` is provided, applyBlueprint reuses one existing same-title group in the target layout when it is unique, creates a new group when none exists, and rejects ambiguous multi-match cases. Metadata such as \`icon\`, \`tooltip\`, and \`hideInMenu\` is used only when a new group is created and is ignored when an existing group is reused. \`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\`. AI employee actions use \`type: "aiEmployee"\` plus public \`settings.username\`, \`workContext\`, \`tasks\`, \`auto\`, and \`style\`; work context may target \`self\` or a same-blueprint block key and is persisted as real Flow Model \`uid\` values. For JS blocks/fields/actions, \`script\` is a non-empty string asset key into \`assets.scripts\`; put inline JS in \`settings.code\` and \`settings.version\`. Direct \`table\` / \`list\` / \`gridCard\` / \`calendar\` / \`kanban\` blocks may omit \`defaultFilter\`; the backend generates one from live metadata with up to 4 scalar/filterable fields. Explicit values must contain at least the smaller of 3 and the collection eligible-field count, and values with more than 4 fields are truncated before persistence. A valid explicit or generated block-level value backfills the default \`filter\` action \`settings.defaultFilter\`; explicit filter-action \`settings.defaultFilter\` still wins. ${TREE_TABLE_RECORD_ACTION_DEFAULTS_NOTE} ${APPLY_BLUEPRINT_TREE_TABLE_TITLE_FIELD_NOTE} 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 combine \`popup.tryTemplate\` with \`popup.saveAsTemplate={ name, description, local? }\`: a hit binds the matched template immediately and lets later inline popups in the same blueprint reuse that final bound template through \`popup.template={ local, mode }\`, while a miss requires explicit local \`popup.blocks\` so the fallback popup can be saved and reused. 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.`
627
627
  ),
628
628
  requestBody: {
629
629
  required: true,
@@ -809,7 +809,7 @@ const actionDocs = {
809
809
  tags: [FLOW_SURFACES_TAG],
810
810
  summary: "Create a group menu or a bindable V2 menu item",
811
811
  description: valuesCompatibilityNote(
812
- 'Creates a FlowSurfaces menu node. `type="group"` creates a menu group. `type="item"` creates a menu item that can be bound to a modern page (v2), and automatically fills in the flowPage route, the default hidden tab route, and the RootPageModel anchor.'
812
+ 'Creates a FlowSurfaces menu node. `type="group"` creates a menu group. `type="item"` creates a menu item that can be bound to a modern page (v2), and automatically fills in the flowPage route, the default hidden tab route, and the RootPageModel anchor. Optional `layoutUid` scopes the route to an enabled UI layout; omitted values keep the existing parent/default admin layout inheritance.'
813
813
  ),
814
814
  requestBody: requestBody("FlowSurfaceCreateMenuRequest", import_flow_surfaces.flowSurfaceExamples.createMenu),
815
815
  responses: responses("FlowSurfaceCreateMenuResult")
@@ -827,7 +827,7 @@ const actionDocs = {
827
827
  tags: [FLOW_SURFACES_TAG],
828
828
  summary: "Initialize a modern page for an existing bindable menu item",
829
829
  description: valuesCompatibilityNote(
830
- "Initializes a modern page (v2) for an existing bindable menu item through `menuRouteId` first, and fills in the default BlockGridModel. In compatibility mode, if `menuRouteId` is omitted, the old behavior still applies and a top-level menu plus page will be created automatically. Before initialization, do not call page/tab lifecycle actions such as `addTab`, `updateTab`, `moveTab`, `removeTab`, or `destroyPage`."
830
+ "Initializes a modern page (v2) for an existing bindable menu item through `menuRouteId` first, and fills in the default BlockGridModel. Optional `layoutUid` asserts that the existing menu route belongs to the target UI layout; omitted values keep the existing parent/default admin layout inheritance. In compatibility mode, if `menuRouteId` is omitted, the old behavior still applies and a top-level menu plus page will be created automatically. Before initialization, do not call page/tab lifecycle actions such as `addTab`, `updateTab`, `moveTab`, `removeTab`, or `destroyPage`."
831
831
  ),
832
832
  requestBody: requestBody("FlowSurfaceCreatePageRequest", import_flow_surfaces.flowSurfaceExamples.createPage),
833
833
  responses: responses("FlowSurfaceCreatePageResult")
@@ -4167,11 +4167,11 @@ const schemas = {
4167
4167
  properties: {
4168
4168
  routeId: {
4169
4169
  ...STRING_OR_INTEGER_SCHEMA,
4170
- description: "Preferred existing menu-group route id. When present, routeId has the highest priority and title/icon/tooltip/hideInMenu are ignored. applyBlueprint create mode does not mutate existing group metadata; use low-level updateMenu separately when needed."
4170
+ description: "Preferred existing menu-group route id for non-mobile create mode. When present, routeId has the highest priority and title/icon/tooltip/hideInMenu are ignored. Ignored when navigation.layoutUid targets a mobile layout because mobile pages are created as root tabs. applyBlueprint create mode does not mutate existing group metadata; use low-level updateMenu separately when needed."
4171
4171
  },
4172
4172
  title: {
4173
4173
  type: "string",
4174
- description: "Group title for create mode. When `routeId` is omitted, applyBlueprint reuses a same-title group if the match is unique, creates one when no group exists, and rejects ambiguous multi-match cases. If an existing group is reused, group metadata is ignored; use low-level updateMenu to change existing group metadata."
4174
+ description: "Group title for non-mobile create mode. When `routeId` is omitted, applyBlueprint reuses a same-title group if the match is unique, creates one when no group exists, and rejects ambiguous multi-match cases. Ignored when navigation.layoutUid targets a mobile layout because mobile pages are created as root tabs. If an existing group is reused, group metadata is ignored; use low-level updateMenu to change existing group metadata."
4175
4175
  },
4176
4176
  icon: {
4177
4177
  type: "string",
@@ -4191,6 +4191,10 @@ const schemas = {
4191
4191
  FlowSurfaceApplyBlueprintNavigation: {
4192
4192
  type: "object",
4193
4193
  properties: {
4194
+ layoutUid: {
4195
+ type: "string",
4196
+ description: "Optional enabled UI layout uid that scopes create-mode route lookup and newly created routes. Use `mobile-layout-model` for mobile pages; mobile layouts ignore navigation.group and create a root-level tab page. When omitted, the server preserves the existing parent/default admin layout behavior."
4197
+ },
4194
4198
  group: ref("FlowSurfaceApplyBlueprintNavigationGroup"),
4195
4199
  item: {
4196
4200
  type: "object",
@@ -4406,7 +4410,7 @@ const schemas = {
4406
4410
  FlowSurfaceApplyBlueprintRequest: {
4407
4411
  type: "object",
4408
4412
  required: ["mode", "tabs"],
4409
- description: `Simplified page-structure request object for applyBlueprint. \`version\` may be omitted and defaults to '1'. Runtime validation enforces mode-specific rules: create does not accept target, while replace requires target.pageSchemaUid and does not use navigation. For JS blocks/fields/actions, \`script\` is a non-empty string asset key into \`assets.scripts\`, and referenced script assets must provide non-empty \`code\`; put inline JS in \`settings.code\` and \`settings.version\`. ${TREE_TABLE_RECORD_ACTION_DEFAULTS_NOTE} ${APPLY_BLUEPRINT_TREE_TABLE_TITLE_FIELD_NOTE} \`defaults.collections\` may provide main data-source collection-level fieldGroups, popup metadata with required \`name\` and \`description\`, and formBehavior for generated default add/edit popup forms; use \`defaults.dataSources.<dataSourceKey>.collections\` for external data sources. v1 does not support \`defaults.blocks\`.`,
4413
+ description: `Simplified page-structure request object for applyBlueprint. \`version\` may be omitted and defaults to '1'. Runtime validation enforces mode-specific rules: create does not accept target, while replace requires target.pageSchemaUid and does not use navigation. In create mode, \`navigation.layoutUid\` scopes menu group reuse, duplicate page identity, and newly created routes to the target layout; use \`mobile-layout-model\` for mobile pages, where \`navigation.group\` is ignored and the page is created as a root tab, and omit it for default admin behavior. For JS blocks/fields/actions, \`script\` is a non-empty string asset key into \`assets.scripts\`, and referenced script assets must provide non-empty \`code\`; put inline JS in \`settings.code\` and \`settings.version\`. ${TREE_TABLE_RECORD_ACTION_DEFAULTS_NOTE} ${APPLY_BLUEPRINT_TREE_TABLE_TITLE_FIELD_NOTE} \`defaults.collections\` may provide main data-source collection-level fieldGroups, popup metadata with required \`name\` and \`description\`, and formBehavior for generated default add/edit popup forms; use \`defaults.dataSources.<dataSourceKey>.collections\` for external data sources. v1 does not support \`defaults.blocks\`.`,
4410
4414
  properties: {
4411
4415
  version: {
4412
4416
  type: "string",
@@ -4578,6 +4582,10 @@ const schemas = {
4578
4582
  type: "object",
4579
4583
  required: ["title"],
4580
4584
  properties: {
4585
+ layoutUid: {
4586
+ type: "string",
4587
+ description: "Optional enabled UI layout uid for the created menu route, for example `mobile-layout-model`. When omitted, the route inherits its parent layout or the default admin layout."
4588
+ },
4581
4589
  title: {
4582
4590
  type: "string"
4583
4591
  },
@@ -4674,6 +4682,10 @@ const schemas = {
4674
4682
  FlowSurfaceCreatePageRequest: {
4675
4683
  type: "object",
4676
4684
  properties: {
4685
+ layoutUid: {
4686
+ type: "string",
4687
+ description: "Optional enabled UI layout uid. With `menuRouteId`, the existing route must already belong to this layout. Without `menuRouteId`, the compatibility create-menu fallback creates the route in this layout."
4688
+ },
4677
4689
  menuRouteId: STRING_OR_INTEGER_SCHEMA,
4678
4690
  pageSchemaUid: {
4679
4691
  type: "string"
@@ -2635,6 +2635,10 @@ declare const _default: {
2635
2635
  FlowSurfaceApplyBlueprintNavigation: {
2636
2636
  type: string;
2637
2637
  properties: {
2638
+ layoutUid: {
2639
+ type: string;
2640
+ description: string;
2641
+ };
2638
2642
  group: {
2639
2643
  $ref: string;
2640
2644
  };
@@ -3148,6 +3152,10 @@ declare const _default: {
3148
3152
  type: string;
3149
3153
  required: string[];
3150
3154
  properties: {
3155
+ layoutUid: {
3156
+ type: string;
3157
+ description: string;
3158
+ };
3151
3159
  title: {
3152
3160
  type: string;
3153
3161
  };
@@ -3270,6 +3278,10 @@ declare const _default: {
3270
3278
  FlowSurfaceCreatePageRequest: {
3271
3279
  type: string;
3272
3280
  properties: {
3281
+ layoutUid: {
3282
+ type: string;
3283
+ description: string;
3284
+ };
3273
3285
  menuRouteId: {
3274
3286
  oneOf: {
3275
3287
  type: string;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "前端流引擎",
5
5
  "description": "",
6
6
  "description.zh-CN": "",
7
- "version": "2.2.0-alpha.3",
7
+ "version": "2.2.0-alpha.5",
8
8
  "main": "./dist/server/index.js",
9
9
  "license": "Apache-2.0",
10
10
  "devDependencies": {
@@ -26,5 +26,5 @@
26
26
  "@nocobase/test": "2.x",
27
27
  "@nocobase/utils": "2.x"
28
28
  },
29
- "gitHead": "e3ec19361fd7981af9fe2a7f24ad335025cbefcd"
29
+ "gitHead": "814ff497dd1233ca7218c9f7f2a016c2ead6516d"
30
30
  }