@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.2 → 3.9.0-ultramodern.4

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 (93) hide show
  1. package/dist/cjs/ultramodern-package-source.cjs +2 -1
  2. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.cjs +5 -2
  3. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.cjs +5 -0
  4. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.cjs +1 -0
  5. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.cjs +30 -9
  6. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.cjs +9 -13
  7. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.cjs +30 -7
  8. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.cjs +99 -0
  9. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.cjs +14 -5
  10. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.cjs +215 -0
  11. package/dist/cjs/ultramodern-tooling/commands/migrate-strict-effect.cjs +72 -8
  12. package/dist/cjs/ultramodern-workspace/api/client.cjs +2 -2
  13. package/dist/cjs/ultramodern-workspace/api/service.cjs +45 -16
  14. package/dist/cjs/ultramodern-workspace/api/shared.cjs +26 -16
  15. package/dist/cjs/ultramodern-workspace/mf-validation/inspect.cjs +6 -2
  16. package/dist/cjs/ultramodern-workspace/module-federation/reexport-module.cjs +18 -51
  17. package/dist/cjs/ultramodern-workspace/package-json.cjs +13 -1
  18. package/dist/cjs/ultramodern-workspace/policy.cjs +1 -0
  19. package/dist/cjs/ultramodern-workspace/tsconfigs.cjs +3 -0
  20. package/dist/cjs/ultramodern-workspace/workspace-script-plan.cjs +1 -1
  21. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +5 -0
  22. package/dist/cjs/ultramodern-workspace/workspace-validation-contract.cjs +2 -1
  23. package/dist/cjs/ultramodern-workspace/write-app.cjs +10 -4
  24. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +5 -3
  25. package/dist/esm/ultramodern-package-source.js +2 -1
  26. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  27. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  28. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  29. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +30 -9
  30. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  31. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  32. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +50 -0
  33. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +14 -5
  34. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +166 -0
  35. package/dist/esm/ultramodern-tooling/commands/migrate-strict-effect.js +73 -9
  36. package/dist/esm/ultramodern-workspace/api/client.js +2 -2
  37. package/dist/esm/ultramodern-workspace/api/service.js +45 -16
  38. package/dist/esm/ultramodern-workspace/api/shared.js +27 -17
  39. package/dist/esm/ultramodern-workspace/mf-validation/inspect.js +6 -2
  40. package/dist/esm/ultramodern-workspace/module-federation/reexport-module.js +18 -51
  41. package/dist/esm/ultramodern-workspace/package-json.js +13 -1
  42. package/dist/esm/ultramodern-workspace/policy.js +1 -0
  43. package/dist/esm/ultramodern-workspace/tsconfigs.js +3 -0
  44. package/dist/esm/ultramodern-workspace/workspace-script-plan.js +1 -1
  45. package/dist/esm/ultramodern-workspace/workspace-scripts.js +5 -0
  46. package/dist/esm/ultramodern-workspace/workspace-validation-contract.js +2 -1
  47. package/dist/esm/ultramodern-workspace/write-app.js +10 -4
  48. package/dist/esm/ultramodern-workspace/write-workspace.js +6 -4
  49. package/dist/esm-node/ultramodern-package-source.js +2 -1
  50. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-build-identity.js +5 -2
  51. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-modern-configs.js +5 -0
  52. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/generated-artifacts-typescript.js +1 -0
  53. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.js +30 -9
  54. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-policy.js +9 -13
  55. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.js +30 -7
  56. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.js +51 -0
  57. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/toolchain-pins.js +14 -5
  58. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.js +167 -0
  59. package/dist/esm-node/ultramodern-tooling/commands/migrate-strict-effect.js +73 -9
  60. package/dist/esm-node/ultramodern-workspace/api/client.js +2 -2
  61. package/dist/esm-node/ultramodern-workspace/api/service.js +45 -16
  62. package/dist/esm-node/ultramodern-workspace/api/shared.js +27 -17
  63. package/dist/esm-node/ultramodern-workspace/mf-validation/inspect.js +6 -2
  64. package/dist/esm-node/ultramodern-workspace/module-federation/reexport-module.js +18 -51
  65. package/dist/esm-node/ultramodern-workspace/package-json.js +13 -1
  66. package/dist/esm-node/ultramodern-workspace/policy.js +1 -0
  67. package/dist/esm-node/ultramodern-workspace/tsconfigs.js +3 -0
  68. package/dist/esm-node/ultramodern-workspace/workspace-script-plan.js +1 -1
  69. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +5 -0
  70. package/dist/esm-node/ultramodern-workspace/workspace-validation-contract.js +2 -1
  71. package/dist/esm-node/ultramodern-workspace/write-app.js +10 -4
  72. package/dist/esm-node/ultramodern-workspace/write-workspace.js +6 -4
  73. package/dist/types/ultramodern-package-source.d.ts +1 -1
  74. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/package-cohort.d.ts +3 -1
  75. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/pnpm-yaml.d.ts +7 -0
  76. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/shared-api-infrastructure.d.ts +4 -0
  77. package/dist/types/ultramodern-tooling/commands/migrate-strict-effect/workspace-artifact-ownership.d.ts +27 -0
  78. package/dist/types/ultramodern-workspace/api/client.d.ts +3 -1
  79. package/dist/types/ultramodern-workspace/api/service.d.ts +3 -1
  80. package/dist/types/ultramodern-workspace/api/shared.d.ts +2 -0
  81. package/dist/types/ultramodern-workspace/module-federation/reexport-module.d.ts +2 -2
  82. package/dist/types/ultramodern-workspace/package-json.d.ts +1 -1
  83. package/dist/types/ultramodern-workspace/policy.d.ts +2 -0
  84. package/dist/types/ultramodern-workspace/workspace-validation-contract.d.ts +1 -1
  85. package/package.json +5 -4
  86. package/template-workspace/.modernjs/release-cohort.json +40 -40
  87. package/template-workspace/scripts/bootstrap-agent-skills.mjs +4 -4
  88. package/templates/packages/effect-bff-runtime.ts +50 -0
  89. package/templates/packages/microvertical-api-baseline.ts +102 -0
  90. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +49 -28
  91. package/templates/workspace-scripts/microvertical-api-baseline-boundary.mts +944 -0
  92. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +25 -7
  93. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +1 -1
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ preserveConsumerWorkspaceArtifacts: ()=>preserveConsumerWorkspaceArtifacts
41
+ });
42
+ const external_node_fs_namespaceObject = require("node:fs");
43
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
44
+ const external_node_path_namespaceObject = require("node:path");
45
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const parser_namespaceObject = require("@babel/parser");
47
+ const fs_io_cjs_namespaceObject = require("../../../ultramodern-workspace/fs-io.cjs");
48
+ function isLiteralData(node, literalIdentifiers) {
49
+ if (!node) return false;
50
+ if ('Identifier' === node.type) return literalIdentifiers?.has(node.name) ?? false;
51
+ if ([
52
+ 'StringLiteral',
53
+ 'NumericLiteral',
54
+ 'BooleanLiteral',
55
+ 'NullLiteral'
56
+ ].includes(node.type)) return true;
57
+ if ('UnaryExpression' === node.type) return '-' === node.operator && 'NumericLiteral' === node.argument.type;
58
+ if ('ArrayExpression' === node.type) return node.elements.every((element)=>isLiteralData(element, literalIdentifiers));
59
+ return 'ObjectExpression' === node.type && node.properties.every((property)=>'ObjectProperty' === property.type && !property.computed && !property.shorthand && [
60
+ 'Identifier',
61
+ 'StringLiteral',
62
+ 'NumericLiteral'
63
+ ].includes(property.key.type) && isLiteralData(property.value, literalIdentifiers));
64
+ }
65
+ function withoutGeneratedData(source, binding) {
66
+ if (!binding) return source;
67
+ const parsed = (0, parser_namespaceObject.parse)(source, {
68
+ sourceType: 'module',
69
+ plugins: [
70
+ "typescript"
71
+ ]
72
+ });
73
+ for (const statement of parsed.program.body)if ('VariableDeclaration' === statement.type && 'const' === statement.kind) {
74
+ for (const declaration of statement.declarations)if ('Identifier' === declaration.id.type && declaration.id.name === binding && declaration.init && isLiteralData(declaration.init)) return source.slice(0, declaration.init.start) + '{}' + source.slice(declaration.init.end);
75
+ }
76
+ return source;
77
+ }
78
+ function staticPropertyValue(node, name) {
79
+ if (node?.type !== 'ObjectExpression') return;
80
+ const keys = new Set();
81
+ let value;
82
+ for (const property of node.properties){
83
+ if ('ObjectProperty' !== property.type || property.computed || property.shorthand || ![
84
+ 'Identifier',
85
+ 'StringLiteral'
86
+ ].includes(property.key.type)) return;
87
+ const key = property.key.name ?? property.key.value;
88
+ if (keys.has(key)) return;
89
+ keys.add(key);
90
+ if (key === name) value = property.value;
91
+ }
92
+ return value;
93
+ }
94
+ function refreshValidatorReleaseCohort(source, releaseCohort) {
95
+ try {
96
+ const parsed = (0, parser_namespaceObject.parse)(source, {
97
+ sourceType: 'module',
98
+ plugins: [
99
+ "typescript"
100
+ ],
101
+ tokens: true
102
+ });
103
+ const constants = parsed.program.body.flatMap((statement)=>'VariableDeclaration' === statement.type && 'const' === statement.kind ? statement.declarations : []);
104
+ const matches = [];
105
+ for (const statement of parsed.program.body)if ('VariableDeclaration' === statement.type && 'const' === statement.kind) for (const declaration of statement.declarations){
106
+ const kind = staticPropertyValue(declaration.init, 'kind');
107
+ if (kind?.type !== 'StringLiteral' || 'modernjs.ultramodern-workspace-validation-contract' !== kind.value) continue;
108
+ const cohort = staticPropertyValue(staticPropertyValue(declaration.init, 'cohort'), 'releaseCohort');
109
+ const schema = staticPropertyValue(cohort, 'schema');
110
+ const schemaVersion = staticPropertyValue(cohort, 'schemaVersion');
111
+ const version = staticPropertyValue(staticPropertyValue(cohort, 'release'), 'version');
112
+ const versionConstant = version?.type === 'Identifier' ? constants.find((declaration)=>'Identifier' === declaration.id.type && declaration.id.name === version.name && declaration.init?.type === 'StringLiteral') : void 0;
113
+ if (schema?.type === 'StringLiteral' && 'bleedingdev.ultramodern.release-cohort' === schema.value && schemaVersion?.type === 'NumericLiteral' && 1 === schemaVersion.value && isLiteralData(cohort, versionConstant ? new Set([
114
+ version.name
115
+ ]) : void 0)) matches.push({
116
+ cohort,
117
+ version,
118
+ versionConstant
119
+ });
120
+ }
121
+ if (1 !== matches.length) return source;
122
+ const { cohort, version, versionConstant } = matches[0];
123
+ let content = JSON.stringify(releaseCohort, null, 2);
124
+ const edits = [];
125
+ if (versionConstant && !parsed.tokens?.some((token)=>'name' === token.type.label && token.value === version.name && token.start !== versionConstant.id.start && (token.start < cohort.start || token.end > cohort.end))) {
126
+ content = content.replaceAll(`"version": ${JSON.stringify(releaseCohort.release.version)}`, `"version": ${version.name}`);
127
+ edits.push({
128
+ start: versionConstant.init.start,
129
+ end: versionConstant.init.end,
130
+ content: JSON.stringify(releaseCohort.release.version)
131
+ });
132
+ }
133
+ edits.push({
134
+ start: cohort.start,
135
+ end: cohort.end,
136
+ content
137
+ });
138
+ for (const edit of edits.toSorted((left, right)=>right.start - left.start))source = source.slice(0, edit.start) + edit.content + source.slice(edit.end);
139
+ return source;
140
+ } catch {
141
+ return source;
142
+ }
143
+ }
144
+ function preserveConsumerWorkspaceArtifacts(io, candidates) {
145
+ const preservedPaths = new Set();
146
+ const physicalRoot = external_node_fs_default().realpathSync(io.workspaceRoot);
147
+ const canonicalSources = (0, fs_io_cjs_namespaceObject.formatGeneratedSourceCandidates)(candidates.map((candidate, index)=>[
148
+ `canonical/${index}/${candidate.relativePath}`,
149
+ withoutGeneratedData(candidate.content, candidate.generatedDataBinding)
150
+ ]));
151
+ for (const [index, candidate] of candidates.entries()){
152
+ const paths = [
153
+ candidate.relativePath,
154
+ candidate.legacyPath
155
+ ].filter((value)=>void 0 !== value);
156
+ for (const relativePath of paths){
157
+ const filePath = external_node_path_default().join(io.workspaceRoot, relativePath);
158
+ if (!external_node_fs_default().existsSync(filePath)) continue;
159
+ const physicalRelative = external_node_path_default().relative(physicalRoot, external_node_fs_default().realpathSync(filePath));
160
+ if ('..' === physicalRelative || physicalRelative.startsWith(`..${external_node_path_default().sep}`) || external_node_path_default().isAbsolute(physicalRelative)) throw new Error(`Refusing to inspect an artifact outside the workspace: ${relativePath}`);
161
+ const source = external_node_fs_default().readFileSync(filePath, 'utf8');
162
+ let recognized = source === candidate.content;
163
+ if (!recognized) try {
164
+ const normalized = withoutGeneratedData(source, candidate.generatedDataBinding);
165
+ const canonical = canonicalSources[index];
166
+ recognized = normalized === canonical || (0, fs_io_cjs_namespaceObject.formatGeneratedSourceCandidates)([
167
+ [
168
+ relativePath,
169
+ normalized
170
+ ]
171
+ ])[0] === canonical;
172
+ } catch {}
173
+ if (!recognized) for (const pairedPath of paths)preservedPaths.add(pairedPath);
174
+ }
175
+ }
176
+ const reported = new Set();
177
+ const isPreserved = (filePath)=>{
178
+ const relativePath = external_node_path_default().relative(io.workspaceRoot, filePath).split(external_node_path_default().sep).join('/');
179
+ if (!preservedPaths.has(relativePath)) return false;
180
+ if (!reported.has(relativePath)) {
181
+ io.log(`${relativePath} preserved consumer-owned artifact: its canonical generated source does not match.`);
182
+ reported.add(relativePath);
183
+ }
184
+ return true;
185
+ };
186
+ return {
187
+ preservedPaths,
188
+ refreshReleaseCohort (releaseCohort) {
189
+ if (!releaseCohort) return;
190
+ for (const candidate of candidates)if ('workspaceValidationContract' === candidate.generatedDataBinding) for (const relativePath of [
191
+ candidate.relativePath,
192
+ candidate.legacyPath
193
+ ]){
194
+ if (!relativePath || !preservedPaths.has(relativePath)) continue;
195
+ const filePath = external_node_path_default().join(io.workspaceRoot, relativePath);
196
+ if (!external_node_fs_default().existsSync(filePath)) continue;
197
+ const source = external_node_fs_default().readFileSync(filePath, 'utf8');
198
+ io.write(filePath, refreshValidatorReleaseCohort(source, releaseCohort));
199
+ }
200
+ },
201
+ io: {
202
+ ...io,
203
+ write: (filePath, content)=>isPreserved(filePath) ? false : io.write(filePath, content),
204
+ writeGenerated: (filePath, content)=>isPreserved(filePath) ? false : io.writeGenerated(filePath, content),
205
+ remove: (filePath)=>isPreserved(filePath) ? false : io.remove(filePath)
206
+ }
207
+ };
208
+ }
209
+ exports.preserveConsumerWorkspaceArtifacts = __webpack_exports__.preserveConsumerWorkspaceArtifacts;
210
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
211
+ "preserveConsumerWorkspaceArtifacts"
212
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
213
+ Object.defineProperty(exports, '__esModule', {
214
+ value: true
215
+ });
@@ -44,11 +44,13 @@ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node
44
44
  const external_node_path_namespaceObject = require("node:path");
45
45
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
46
  const external_ultramodern_release_cohort_cjs_namespaceObject = require("../../ultramodern-release-cohort.cjs");
47
+ const app_files_cjs_namespaceObject = require("../../ultramodern-workspace/app-files.cjs");
47
48
  const contracts_cjs_namespaceObject = require("../../ultramodern-workspace/contracts.cjs");
48
49
  const delivery_unit_stamp_cjs_namespaceObject = require("../../ultramodern-workspace/delivery-unit-stamp.cjs");
49
50
  const policy_cjs_namespaceObject = require("../../ultramodern-workspace/policy.cjs");
50
51
  const shells_cjs_namespaceObject = require("../../ultramodern-workspace/shells.cjs");
51
52
  const workspace_scripts_cjs_namespaceObject = require("../../ultramodern-workspace/workspace-scripts.cjs");
53
+ const zerops_cjs_namespaceObject = require("../../ultramodern-workspace/zerops.cjs");
52
54
  const external_config_cjs_namespaceObject = require("../config.cjs");
53
55
  const api_metadata_cjs_namespaceObject = require("./migrate-strict-effect/api-metadata.cjs");
54
56
  const declaration_patches_cjs_namespaceObject = require("./migrate-strict-effect/declaration-patches.cjs");
@@ -61,7 +63,9 @@ const package_cohort_cjs_namespaceObject = require("./migrate-strict-effect/pack
61
63
  const package_source_cjs_namespaceObject = require("./migrate-strict-effect/package-source.cjs");
62
64
  const pnpm_policy_cjs_namespaceObject = require("./migrate-strict-effect/pnpm-policy.cjs");
63
65
  const react_router_retirement_cjs_namespaceObject = require("./migrate-strict-effect/react-router-retirement.cjs");
66
+ const shared_api_infrastructure_cjs_namespaceObject = require("./migrate-strict-effect/shared-api-infrastructure.cjs");
64
67
  const toolchain_pins_cjs_namespaceObject = require("./migrate-strict-effect/toolchain-pins.cjs");
68
+ const workspace_artifact_ownership_cjs_namespaceObject = require("./migrate-strict-effect/workspace-artifact-ownership.cjs");
65
69
  const external_options_cjs_namespaceObject = require("./options.cjs");
66
70
  const retiredMetadataPaths = [
67
71
  '.modernjs/ultramodern-generated-contract.json',
@@ -117,10 +121,24 @@ function synchronizeMigrationDeliveryUnitMetadata(io, raw, packageSource) {
117
121
  'schemaVersion',
118
122
  'id',
119
123
  "description",
120
- 'preset',
121
- 'sharedPackages',
122
- 'validation'
123
- ])topology[key] = canonicalTopology[key];
124
+ 'preset'
125
+ ])if ('id' === key || "description" === key) topology[key] ??= canonicalTopology[key];
126
+ else topology[key] = canonicalTopology[key];
127
+ const existingSharedPackages = Array.isArray(topology.sharedPackages) ? topology.sharedPackages : [];
128
+ topology.sharedPackages = [
129
+ ...existingSharedPackages,
130
+ ...canonicalTopology.sharedPackages.filter((candidate)=>!existingSharedPackages.some((existing)=>existing.id === candidate.id))
131
+ ];
132
+ topology.validation = {
133
+ ...canonicalTopology.validation,
134
+ ...topology.validation,
135
+ commands: [
136
+ ...new Set([
137
+ ...topology.validation?.commands ?? [],
138
+ ...canonicalTopology.validation.commands
139
+ ])
140
+ ]
141
+ };
124
142
  const canonicalTopologyApps = new Map([
125
143
  canonicalTopology.shell,
126
144
  ...canonicalTopology.verticals ?? []
@@ -143,8 +161,21 @@ function synchronizeMigrationDeliveryUnitMetadata(io, raw, packageSource) {
143
161
  'api',
144
162
  'cloudflare',
145
163
  'ownership'
146
- ])if (Object.hasOwn(canonicalEntry, key)) entry[key] = canonicalEntry[key];
147
- else delete entry[key];
164
+ ])if (Object.hasOwn(canonicalEntry, key)) {
165
+ const canonicalValue = canonicalEntry[key];
166
+ if ('api' === key && entry.api && canonicalValue && 'object' == typeof canonicalValue) {
167
+ const nextApi = {
168
+ ...entry.api,
169
+ ...canonicalValue
170
+ };
171
+ if (!Object.hasOwn(entry.api, 'domainOperations')) delete nextApi.domainOperations;
172
+ entry.api = nextApi;
173
+ } else if ('cloudflare' === key && entry.cloudflare && canonicalValue && 'object' == typeof canonicalValue) entry.cloudflare = {
174
+ ...canonicalValue,
175
+ ...entry.cloudflare
176
+ };
177
+ else entry[key] = canonicalValue;
178
+ } else delete entry[key];
148
179
  }
149
180
  }
150
181
  (0, io_cjs_namespaceObject.writeJsonFile)(io, topologyPath, topology);
@@ -165,7 +196,10 @@ function synchronizeMigrationCompactPolicy(io, raw, packageSource) {
165
196
  const apps = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(migrated);
166
197
  apps.filter((app)=>'shell' !== app.kind);
167
198
  const canonical = requireRecord((0, contracts_cjs_namespaceObject.createUltramodernConfig)(migrated.workspace.packageScope, packageSource.modernPackageVersion, packageSource, apps, migrated.features.tailwind, migrated.bridge, (0, external_config_cjs_namespaceObject.additionalShellsFromToolingConfig)(migrated), apps.find((app)=>'shell' === app.kind)), 'Generated compact policy');
168
- for (const key of compactPolicyKeys)raw[key] = canonical[key];
199
+ for (const key of compactPolicyKeys){
200
+ if ('workspace' === key) canonical.workspace.packageManager.version = raw.workspace.packageManager.version;
201
+ raw[key] = canonical[key];
202
+ }
169
203
  (0, io_cjs_namespaceObject.writeJsonFile)(io, external_node_path_default().join(io.workspaceRoot, '.modernjs/ultramodern.json'), raw);
170
204
  }
171
205
  function reconcileRootPackageSourceMetadata(packageJson, packageSource) {
@@ -305,6 +339,33 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
305
339
  version: packageSource.modernPackageVersion
306
340
  });
307
341
  const releaseCohort = 'install' === packageSource.strategy ? (0, external_ultramodern_release_cohort_cjs_namespaceObject.readCreateReleaseCohort)() : void 0;
342
+ const currentApps = (0, external_config_cjs_namespaceObject.workspaceAppsFromToolingConfig)(current);
343
+ const allCurrentApps = (0, external_config_cjs_namespaceObject.allWorkspaceAppsFromToolingConfig)(current);
344
+ const artifactOwnership = (0, workspace_artifact_ownership_cjs_namespaceObject.preserveConsumerWorkspaceArtifacts)(io, [
345
+ ...allCurrentApps.map((app)=>({
346
+ relativePath: `${app.directory}/src/modern-app-env.d.ts`,
347
+ content: (0, app_files_cjs_namespaceObject.createAppEnvDts)(app, allCurrentApps.filter((remote)=>'shell' !== remote.kind), current.workspace.packageScope)
348
+ })),
349
+ ...(0, workspace_scripts_cjs_namespaceObject.migratedWorkspaceScriptArtifacts)({
350
+ shellOnly: false,
351
+ hasBackendSurface: true
352
+ }).filter((artifact)=>"scripts/validate-ultramodern-workspace.mts" !== artifact.relativePath),
353
+ {
354
+ relativePath: "scripts/validate-ultramodern-workspace.mts",
355
+ legacyPath: "scripts/validate-ultramodern-workspace.mjs",
356
+ generatedDataBinding: 'workspaceValidationContract',
357
+ content: (0, workspace_scripts_cjs_namespaceObject.createWorkspaceValidationScript)(current.workspace.packageScope, current.features.tailwind, currentApps.filter((app)=>'shell' !== app.kind), void 0, (0, external_config_cjs_namespaceObject.additionalShellsFromToolingConfig)(current), currentApps.find((app)=>'shell' === app.kind))
358
+ },
359
+ {
360
+ relativePath: 'zerops.yaml',
361
+ content: `${(0, zerops_cjs_namespaceObject.createZeropsYaml)(current.workspace.packageScope, (0, external_config_cjs_namespaceObject.allWorkspaceAppsFromToolingConfig)(current))}\n`
362
+ },
363
+ {
364
+ relativePath: "scripts/materialize-zerops-runtime.mjs",
365
+ content: (0, workspace_scripts_cjs_namespaceObject.createZeropsRuntimeMaterializationScript)()
366
+ }
367
+ ]);
368
+ io = artifactOwnership.io;
308
369
  (0, api_metadata_cjs_namespaceObject.reconcileCompactPackageSourceMetadata)(raw.packageSource, packageSource);
309
370
  reconcileRootPackageSourceMetadata((0, io_cjs_namespaceObject.readJsonFile)(external_node_path_default().join(io.workspaceRoot, 'package.json')), packageSource);
310
371
  (0, pnpm_policy_cjs_namespaceObject.updateGeneratedPnpmWorkspacePolicy)((0, io_cjs_namespaceObject.createMigrationIo)(io.workspaceRoot, true), packageSource, {
@@ -325,6 +386,7 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
325
386
  const verticalApps = migrated.topology.apps.filter((app)=>'shell' !== app.kind);
326
387
  const hasBackendSurface = verticalApps.some((app)=>app.api);
327
388
  const shellOnly = 0 === verticalApps.length;
389
+ if (hasBackendSurface) (0, shared_api_infrastructure_cjs_namespaceObject.ensureSharedApiInfrastructure)(io, migrated.workspace.packageScope, packageSource);
328
390
  if (shellOnly) {
329
391
  io.log('Shell-only workspace: skipping backend-federation and Zerops runtime stages.');
330
392
  for (const relativePath of [
@@ -355,6 +417,7 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
355
417
  io.writeGenerated(external_node_path_default().join(io.workspaceRoot, artifact.relativePath), artifact.content);
356
418
  }
357
419
  io.writeGenerated(external_node_path_default().join(io.workspaceRoot, "scripts/validate-ultramodern-workspace.mts"), (0, workspace_scripts_cjs_namespaceObject.createWorkspaceValidationScript)(validationContractInputs.scope, validationContractInputs.enableTailwind, validationContractInputs.remotes, releaseCohort, validationContractInputs.additionalShells, validationContractInputs.primaryShell, raw, external_node_fs_default().existsSync(external_node_path_default().join(io.workspaceRoot, 'topology/ownership.json')) ? requireRecord((0, io_cjs_namespaceObject.readJsonFile)(external_node_path_default().join(io.workspaceRoot, 'topology/ownership.json')), 'Ownership topology') : void 0, developmentOverlay));
420
+ artifactOwnership.refreshReleaseCohort(releaseCohort);
358
421
  for (const relativePath of retiredMetadataPaths)io.remove(external_node_path_default().join(io.workspaceRoot, relativePath));
359
422
  (0, generated_artifacts_cjs_namespaceObject.updateGeneratedBuildIdentityModules)(io, migrated);
360
423
  (0, generated_artifacts_cjs_namespaceObject.updateGeneratedTypeScriptSurfaces)(io, migrated);
@@ -369,7 +432,7 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
369
432
  reconcileRootPackageSourceMetadata(packageJson, packageSource);
370
433
  (0, toolchain_pins_cjs_namespaceObject.updateRootPackageToolchain)(packageJson);
371
434
  }
372
- (0, package_cohort_cjs_namespaceObject.updateModernDependencies)(packageJson, packageSource);
435
+ (0, package_cohort_cjs_namespaceObject.updateModernDependencies)(packageJson, packageSource, releaseCohort);
373
436
  const ownsGeneratedScripts = 'package.json' === relativePackageFile || allMigratedApps.some((app)=>`${app.directory}/package.json` === relativePackageFile);
374
437
  (0, package_cohort_cjs_namespaceObject.updateGeneratedToolingDependencies)(packageJson, {
375
438
  ownsGeneratedScripts
@@ -379,6 +442,7 @@ function migrateStrictEffect(args, context, io, dryRun, skipInstall) {
379
442
  if ('preserved' === retiredReactRouter) io.log(`${relativePackageFile} keeps its react-router dependency: authored source imports React Router directly, so its generated Module Federation config keeps bridge.enableBridgeRouter: true.`);
380
443
  else if ('removed' === retiredReactRouter) io.log(`${relativePackageFile} dropped its obsolete react-router dependency: no authored source imports React Router.`);
381
444
  (0, package_cohort_cjs_namespaceObject.updateGeneratedPackageScripts)(packageJson, {
445
+ preservedArtifacts: artifactOwnership.preservedPaths,
382
446
  relativePackageFile,
383
447
  apps: allMigratedApps,
384
448
  shellOnly,
@@ -35,7 +35,7 @@ const external_descriptors_cjs_namespaceObject = require("../descriptors.cjs");
35
35
  const external_naming_cjs_namespaceObject = require("../naming.cjs");
36
36
  const external_checkout_cart_cjs_namespaceObject = require("./checkout-cart.cjs");
37
37
  const external_names_cjs_namespaceObject = require("./names.cjs");
38
- function createApiClient(service, contractImportPath) {
38
+ function createApiClient(service, contractImportPath, options) {
39
39
  const apiExport = (0, external_names_cjs_namespaceObject.verticalApiExport)(service);
40
40
  const contractExport = (0, external_names_cjs_namespaceObject.verticalApiGroupName)(service);
41
41
  const stem = (0, external_descriptors_cjs_namespaceObject.resolveApiStem)(service);
@@ -151,7 +151,7 @@ export const ${readinessName} = (
151
151
  operationContext:
152
152
  options.operationContext ?? ${groupName}OperationContexts.readiness,
153
153
  }).pipe(
154
- Effect.flatMap(client => client.${groupName}.readiness({})),
154
+ Effect.flatMap(client => client.${options ? 'foundation' : groupName}.readiness({})),
155
155
  );
156
156
 
157
157
  export const ${getName} = (
@@ -37,23 +37,22 @@ const external_naming_cjs_namespaceObject = require("../naming.cjs");
37
37
  const external_checkout_cart_cjs_namespaceObject = require("./checkout-cart.cjs");
38
38
  const external_names_cjs_namespaceObject = require("./names.cjs");
39
39
  const external_rpc_cjs_namespaceObject = require("./rpc.cjs");
40
- function createApiServiceEntry(service, contractImportPath) {
40
+ function createApiServiceEntry(service, contractImportPath, options) {
41
41
  if ((service.api?.protocol ?? 'rest') === 'rpc') return (0, external_rpc_cjs_namespaceObject.createRpcApiServiceEntry)(service);
42
42
  const apiExport = (0, external_names_cjs_namespaceObject.verticalApiExport)(service);
43
43
  const groupName = (0, external_names_cjs_namespaceObject.verticalApiGroupName)(service);
44
44
  const notFoundErrorExport = (0, external_names_cjs_namespaceObject.verticalApiNotFoundErrorExport)(service);
45
45
  const stem = (0, external_descriptors_cjs_namespaceObject.resolveApiStem)(service);
46
- return `import {
47
- defineEffectBff,
46
+ const assemblyImport = options ? `import { assembleEffectBffRuntime } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/server/effect-bff-runtime';\n` : '';
47
+ return `${assemblyImport}import {
48
+ ${options ? '' : 'defineEffectBff,'}
48
49
  Effect,
49
50
  HttpApiBuilder,
50
51
  Layer,
51
52
  } from '@modern-js/plugin-bff/effect-edge';
52
- import type {
53
- EffectBffDefinition,
54
- EffectBffRuntime,
53
+ ${options ? '' : `import type {
55
54
  EffectRuntimeLayer,
56
- } from '@modern-js/plugin-bff/effect-edge';
55
+ } from '@modern-js/plugin-bff/effect-edge';`}
57
56
  import { ultramodernApiMarker } from '../shared/ultramodern-build.ts';
58
57
  import {
59
58
  ${apiExport},
@@ -83,6 +82,31 @@ const operationAttributes = (operationContext: OperationContext) => ({
83
82
  : {}),
84
83
  });
85
84
 
85
+ ${options ? `const ${groupName}ReadinessLayer = HttpApiBuilder.group(
86
+ ${apiExport},
87
+ 'foundation',
88
+ handlers => handlers
89
+ .handle('readiness', () =>
90
+ Effect.succeed({
91
+ checks: {
92
+ api: 'ready' as const,
93
+ moduleFederation: 'ready' as const,
94
+ ssr: 'ready' as const,
95
+ translations: 'ready' as const,
96
+ },
97
+ marker: ultramodernApiMarker,
98
+ status: 'ready' as const,
99
+ versionSkew: 'none' as const,
100
+ }).pipe(
101
+ Effect.withSpan('ultramodern.api.${groupName}.readiness', {
102
+ attributes: operationAttributes(${groupName}OperationContexts.readiness),
103
+ kind: 'server',
104
+ }),
105
+ ),
106
+ )
107
+ ,
108
+ );` : ''}
109
+
86
110
  const ${groupName}Layer = HttpApiBuilder.group(
87
111
  ${apiExport},
88
112
  '${groupName}',
@@ -101,7 +125,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
101
125
  }),
102
126
  ),
103
127
  )
104
- .handle('readiness', () =>
128
+ ${options ? '' : ` .handle('readiness', () =>
105
129
  Effect.succeed({
106
130
  checks: {
107
131
  api: 'ready' as const,
@@ -119,6 +143,7 @@ const ${groupName}Layer = HttpApiBuilder.group(
119
143
  }),
120
144
  ),
121
145
  )
146
+ `}
122
147
  .handle('get', ({ params }) => {
123
148
  const matchedItem = ${groupName}Items.find(
124
149
  candidate => candidate.id === params.id,
@@ -158,14 +183,18 @@ const ${groupName}Layer = HttpApiBuilder.group(
158
183
  )${(0, external_checkout_cart_cjs_namespaceObject.createCheckoutCartServerHandlers)(service)},
159
184
  );
160
185
 
161
- const layer = HttpApiBuilder.layer(${apiExport}).pipe(
162
- Layer.provide(${groupName}Layer),
163
- ) satisfies EffectRuntimeLayer;
164
- const apiRuntime: EffectBffDefinition<typeof ${apiExport}, EffectRuntimeLayer> &
165
- EffectBffRuntime<typeof ${apiExport}, EffectRuntimeLayer> = defineEffectBff({
166
- api: ${apiExport},
167
- layer,
168
- });
186
+ ${options ? `const apiHandlersLive = Layer.mergeAll(${groupName}Layer, ${groupName}ReadinessLayer);
187
+ export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () =>
188
+ assembleEffectBffRuntime({
189
+ api: ${apiExport},
190
+ handlers: apiHandlersLive,
191
+ });` : `export const make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime = () => {
192
+ const layer = HttpApiBuilder.layer(${apiExport}).pipe(
193
+ Layer.provide(${groupName}Layer),
194
+ ) satisfies EffectRuntimeLayer;
195
+ return defineEffectBff({ api: ${apiExport}, layer });
196
+ };`}
197
+ const apiRuntime = make${apiExport[0].toUpperCase()}${apiExport.slice(1)}Runtime();
169
198
 
170
199
  export default apiRuntime;
171
200
  `;
@@ -45,7 +45,7 @@ function createSharedApiImports() {
45
45
  } from '@modern-js/plugin-bff/effect-client';
46
46
  `;
47
47
  }
48
- function createSharedApiContract(service) {
48
+ function createSharedApiContract(service, shared = false) {
49
49
  const schemaExport = (0, external_names_cjs_namespaceObject.verticalApiSchemaExport)(service);
50
50
  const markerSchemaExport = (0, external_names_cjs_namespaceObject.verticalApiMarkerSchemaExport)(service);
51
51
  const readinessSchemaExport = (0, external_names_cjs_namespaceObject.verticalApiReadinessSchemaExport)(service);
@@ -102,7 +102,7 @@ function createSharedApiContract(service) {
102
102
  listOperationContext,
103
103
  readinessOperationContext
104
104
  }).trim();
105
- return `export interface ${markerType} {
105
+ return `${shared ? `export type ${markerType} = MicroVerticalBuildMarker;` : `export interface ${markerType} {
106
106
  readonly appId: string;
107
107
  readonly build: string;
108
108
  readonly buildMarker: string;
@@ -112,7 +112,7 @@ function createSharedApiContract(service) {
112
112
  readonly surface: string;
113
113
  readonly unitId: string;
114
114
  readonly version: string;
115
- }
115
+ }`}
116
116
 
117
117
  export interface ${itemType} {
118
118
  readonly id: string;
@@ -120,7 +120,7 @@ export interface ${itemType} {
120
120
  readonly title: string;
121
121
  }
122
122
 
123
- export interface ${readinessType} {
123
+ ${shared ? `export type ${readinessType} = MicroVerticalReadiness;` : `export interface ${readinessType} {
124
124
  readonly checks: {
125
125
  readonly api: 'ready';
126
126
  readonly moduleFederation: 'ready';
@@ -130,7 +130,7 @@ export interface ${readinessType} {
130
130
  readonly marker: ${markerType};
131
131
  readonly status: 'ready';
132
132
  readonly versionSkew: 'none';
133
- }
133
+ }`}
134
134
 
135
135
  export interface ${createPayloadType} {
136
136
  readonly title: string;
@@ -149,7 +149,7 @@ export interface ${notFoundErrorExport} {
149
149
  readonly id: string;
150
150
  }
151
151
 
152
- export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
152
+ ${shared ? `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = MicroVerticalBuildMarkerSchema;` : `export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct({
153
153
  appId: Schema.String,
154
154
  build: Schema.String,
155
155
  buildMarker: Schema.String,
@@ -159,7 +159,7 @@ export const ${markerSchemaExport}: Schema.Codec<${markerType}> = Schema.Struct(
159
159
  surface: Schema.String,
160
160
  unitId: Schema.String,
161
161
  version: Schema.String,
162
- });
162
+ });`}
163
163
 
164
164
  export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
165
165
  id: Schema.String,
@@ -167,7 +167,7 @@ export const ${schemaExport}: Schema.Codec<${itemType}> = Schema.Struct({
167
167
  title: Schema.String,
168
168
  });
169
169
 
170
- export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
170
+ ${shared ? `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = MicroVerticalReadinessSchema;` : `export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.Struct({
171
171
  checks: Schema.Struct({
172
172
  api: Schema.Literal('ready'),
173
173
  moduleFederation: Schema.Literal('ready'),
@@ -177,7 +177,7 @@ export const ${readinessSchemaExport}: Schema.Codec<${readinessType}> = Schema.S
177
177
  marker: ${markerSchemaExport},
178
178
  status: Schema.Literal('ready'),
179
179
  versionSkew: Schema.Literal('none'),
180
- });
180
+ });`}
181
181
 
182
182
  export const ${createPayloadSchemaExport}: Schema.Codec<${createPayloadType}> = Schema.Struct({
183
183
  title: Schema.String,
@@ -189,7 +189,7 @@ ${checkoutCartSharedSchemaSection}export const ${notFoundSchemaExport}: Schema.C
189
189
  HttpApiSchema.status(404),
190
190
  );
191
191
 
192
- export interface OperationContext {
192
+ ${shared ? 'export type OperationContext = MicroVerticalOperationContext;' : `export interface OperationContext {
193
193
  method: string;
194
194
  operationId: string;
195
195
  routePath: string;
@@ -201,9 +201,14 @@ export interface OperationContext {
201
201
  | 'data-platform'
202
202
  | 'unknown';
203
203
  traceId?: string;
204
- }
204
+ }`}
205
205
 
206
- export const ${apiExport} = HttpApi.make('${apiName}').add(
206
+ ${shared ? `export const ${groupName}FoundationApi = HttpApi.make('${apiName}Foundation').add(
207
+ HttpApiGroup.make('foundation').add(
208
+ HttpApiEndpoint.get('readiness', '/${stem}/readiness', { success: ${readinessSchemaExport} }),
209
+ ),
210
+ );` : ''}
211
+ export const ${apiExport} = HttpApi.make('${apiName}')${shared ? `.addHttpApi(${groupName}FoundationApi)` : ''}.add(
207
212
  HttpApiGroup.make('${groupName}')
208
213
  .add(
209
214
  HttpApiEndpoint.get('list', '/${stem}', {
@@ -215,11 +220,12 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
215
220
  }),
216
221
  }),
217
222
  )
218
- .add(
223
+ ${shared ? '' : ` .add(
219
224
  HttpApiEndpoint.get('readiness', '/${stem}/readiness', {
220
225
  success: ${readinessSchemaExport},
221
226
  }),
222
227
  )
228
+ `}
223
229
  .add(
224
230
  HttpApiEndpoint.get('get', '/${stem}/:id', {
225
231
  error: ${notFoundSchemaExport},
@@ -240,7 +246,7 @@ export const ${apiExport} = HttpApi.make('${apiName}').add(
240
246
  );
241
247
 
242
248
  export const ${groupName}OperationContexts = {
243
- ${operationContextEntries}
249
+ ${shared ? operationContextEntries.replaceAll(/(\w+: )\{([\s\S]*?)\},/gu, (_, key, fields)=>`${key}createMicroVerticalOperationContext({${fields.replace(/\n\s*source: 'generated-client',/u, '')}}),`) : operationContextEntries}
244
250
  } satisfies Record<string, OperationContext>;
245
251
 
246
252
  export const ${groupName}ApiContract = {
@@ -251,9 +257,13 @@ ${(0, external_checkout_cart_cjs_namespaceObject.createCheckoutCartApiContractFi
251
257
  } as const;
252
258
  `;
253
259
  }
254
- function createSharedApi(service) {
260
+ function createSharedApi(service, options) {
261
+ const imports = options ? `import { MicroVerticalBuildMarkerSchema, MicroVerticalReadinessSchema, createMicroVerticalOperationContext } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/microvertical-api-baseline';
262
+ import type { MicroVerticalBuildMarker, MicroVerticalReadiness, MicroVerticalOperationContext } from '${(0, external_naming_cjs_namespaceObject.packageName)(options.scope, 'shared-contracts')}/microvertical-api-baseline';
263
+ ` : '';
255
264
  return `${createSharedApiImports()}
256
- ${createSharedApiContract(service)}`;
265
+ ${imports}
266
+ ${createSharedApiContract(service, void 0 !== options)}`;
257
267
  }
258
268
  exports.createSharedApi = __webpack_exports__.createSharedApi;
259
269
  for(var __rspack_i in __webpack_exports__)if (-1 === [
@@ -43,7 +43,11 @@ function extractExposes(configPath, value) {
43
43
  if (array) return array.sort();
44
44
  throw new Error(`Cannot statically extract Module Federation exposes from ${configPath}; use a literal exposes object or string array.`);
45
45
  }
46
- function extractDtsSettings(configPath, value) {
46
+ function extractDtsSettings(configPath, value, exposes) {
47
+ if ('false' === value) {
48
+ if (exposes.length > 0) throw new Error(`Module Federation DTS cannot be disabled for exposed app ${configPath}.`);
49
+ return {};
50
+ }
47
51
  if (void 0 === value) return {};
48
52
  const dts = (0, external_object_literal_cjs_namespaceObject.parseObjectLiteral)(value);
49
53
  if (!dts || dts.hasSpread) throw new Error(`Cannot statically extract Module Federation DTS settings from ${configPath}; use a literal dts object.`);
@@ -70,7 +74,7 @@ function inspectModuleFederationConfigSource(source, appDir, configPath) {
70
74
  return {
71
75
  appDir,
72
76
  configPath,
73
- dts: extractDtsSettings(configPath, properties.properties.get('dts')),
77
+ dts: extractDtsSettings(configPath, properties.properties.get('dts'), exposes),
74
78
  exposes,
75
79
  hostOnlyNoExposes
76
80
  };