@empire-builder-kit/nx 1.0.0-beta.10

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 (243) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +34 -0
  4. package/executors.json +74 -0
  5. package/generators.json +40 -0
  6. package/migrations/standard-pre-v1-to-v1.md +11 -0
  7. package/package.json +80 -0
  8. package/src/blueprints/execution.d.ts +31 -0
  9. package/src/blueprints/execution.js +166 -0
  10. package/src/blueprints/execution.js.map +1 -0
  11. package/src/blueprints/index.d.ts +5 -0
  12. package/src/blueprints/index.js +9 -0
  13. package/src/blueprints/index.js.map +1 -0
  14. package/src/blueprints/inputs.d.ts +43 -0
  15. package/src/blueprints/inputs.js +103 -0
  16. package/src/blueprints/inputs.js.map +1 -0
  17. package/src/blueprints/manifest.d.ts +281 -0
  18. package/src/blueprints/manifest.js +441 -0
  19. package/src/blueprints/manifest.js.map +1 -0
  20. package/src/blueprints/resolver.d.ts +28 -0
  21. package/src/blueprints/resolver.js +218 -0
  22. package/src/blueprints/resolver.js.map +1 -0
  23. package/src/blueprints/transitions.d.ts +20 -0
  24. package/src/blueprints/transitions.js +61 -0
  25. package/src/blueprints/transitions.js.map +1 -0
  26. package/src/executors/deploy/deploy.d.ts +4 -0
  27. package/src/executors/deploy/deploy.js +6 -0
  28. package/src/executors/deploy/deploy.js.map +1 -0
  29. package/src/executors/deployment-plan/deployment-plan.d.ts +9 -0
  30. package/src/executors/deployment-plan/deployment-plan.js +50 -0
  31. package/src/executors/deployment-plan/deployment-plan.js.map +1 -0
  32. package/src/executors/deployment-plan/schema.json +24 -0
  33. package/src/executors/dev/dev.d.ts +4 -0
  34. package/src/executors/dev/dev.js +6 -0
  35. package/src/executors/dev/dev.js.map +1 -0
  36. package/src/executors/dev-doctor/dev-doctor.d.ts +31 -0
  37. package/src/executors/dev-doctor/dev-doctor.js +260 -0
  38. package/src/executors/dev-doctor/dev-doctor.js.map +1 -0
  39. package/src/executors/dev-doctor/schema.json +17 -0
  40. package/src/executors/dev-setup/dev-setup.d.ts +11 -0
  41. package/src/executors/dev-setup/dev-setup.js +454 -0
  42. package/src/executors/dev-setup/dev-setup.js.map +1 -0
  43. package/src/executors/dev-setup/schema.json +16 -0
  44. package/src/executors/fleet/fleet.d.ts +62 -0
  45. package/src/executors/fleet/fleet.js +613 -0
  46. package/src/executors/fleet/fleet.js.map +1 -0
  47. package/src/executors/fleet/schema.json +37 -0
  48. package/src/executors/foundation-preflight/foundation-preflight.d.ts +15 -0
  49. package/src/executors/foundation-preflight/foundation-preflight.js +116 -0
  50. package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -0
  51. package/src/executors/foundation-preflight/schema.json +31 -0
  52. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +8 -0
  53. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +41 -0
  54. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -0
  55. package/src/executors/foundation-profile-preflight/schema.json +21 -0
  56. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.d.ts +13 -0
  57. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +69 -0
  58. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +1 -0
  59. package/src/executors/foundation-remove-preflight/schema.json +17 -0
  60. package/src/executors/github-bootstrap/github-bootstrap.d.ts +8 -0
  61. package/src/executors/github-bootstrap/github-bootstrap.js +30 -0
  62. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -0
  63. package/src/executors/github-bootstrap/schema.json +25 -0
  64. package/src/executors/refresh/refresh.d.ts +4 -0
  65. package/src/executors/refresh/refresh.js +6 -0
  66. package/src/executors/refresh/refresh.js.map +1 -0
  67. package/src/executors/remove/remove.d.ts +4 -0
  68. package/src/executors/remove/remove.js +6 -0
  69. package/src/executors/remove/remove.js.map +1 -0
  70. package/src/executors/sst-lifecycle/run-sst-command.d.ts +31 -0
  71. package/src/executors/sst-lifecycle/run-sst-command.js +226 -0
  72. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -0
  73. package/src/executors/sst-lifecycle/schema.json +45 -0
  74. package/src/executors/unlock/unlock.d.ts +4 -0
  75. package/src/executors/unlock/unlock.js +6 -0
  76. package/src/executors/unlock/unlock.js.map +1 -0
  77. package/src/executors/work-markers/schema.json +14 -0
  78. package/src/executors/work-markers/work-markers.d.ts +6 -0
  79. package/src/executors/work-markers/work-markers.js +20 -0
  80. package/src/executors/work-markers/work-markers.js.map +1 -0
  81. package/src/foundation/aurora-logical-database.d.ts +76 -0
  82. package/src/foundation/aurora-logical-database.js +419 -0
  83. package/src/foundation/aurora-logical-database.js.map +1 -0
  84. package/src/foundation/discovery.d.ts +55 -0
  85. package/src/foundation/discovery.js +55 -0
  86. package/src/foundation/discovery.js.map +1 -0
  87. package/src/foundation/index.d.ts +6 -0
  88. package/src/foundation/index.js +10 -0
  89. package/src/foundation/index.js.map +1 -0
  90. package/src/foundation/local-database-contract.d.ts +30 -0
  91. package/src/foundation/local-database-contract.js +75 -0
  92. package/src/foundation/local-database-contract.js.map +1 -0
  93. package/src/foundation/preflight.d.ts +31 -0
  94. package/src/foundation/preflight.js +114 -0
  95. package/src/foundation/preflight.js.map +1 -0
  96. package/src/foundation/provision-database-bindings.d.ts +30 -0
  97. package/src/foundation/provision-database-bindings.js +113 -0
  98. package/src/foundation/provision-database-bindings.js.map +1 -0
  99. package/src/foundation/provision-logical-database.d.ts +26 -0
  100. package/src/foundation/provision-logical-database.js +163 -0
  101. package/src/foundation/provision-logical-database.js.map +1 -0
  102. package/src/foundation/requirements.d.ts +37 -0
  103. package/src/foundation/requirements.js +141 -0
  104. package/src/foundation/requirements.js.map +1 -0
  105. package/src/foundation/stages.d.ts +14 -0
  106. package/src/foundation/stages.js +51 -0
  107. package/src/foundation/stages.js.map +1 -0
  108. package/src/generators/function/function.d.ts +13 -0
  109. package/src/generators/function/function.js +71 -0
  110. package/src/generators/function/function.js.map +1 -0
  111. package/src/generators/function/schema.d.ts +5 -0
  112. package/src/generators/function/schema.json +20 -0
  113. package/src/generators/job/job.d.ts +4 -0
  114. package/src/generators/job/job.js +5 -0
  115. package/src/generators/job/job.js.map +1 -0
  116. package/src/generators/preset/generator.d.ts +5 -0
  117. package/src/generators/preset/generator.js +41 -0
  118. package/src/generators/preset/generator.js.map +1 -0
  119. package/src/generators/preset/schema.d.ts +4 -0
  120. package/src/generators/preset/schema.json +22 -0
  121. package/src/generators/preset/workspace-files.d.ts +18 -0
  122. package/src/generators/preset/workspace-files.js +1605 -0
  123. package/src/generators/preset/workspace-files.js.map +1 -0
  124. package/src/generators/repository-policy/repository-policy.d.ts +4 -0
  125. package/src/generators/repository-policy/repository-policy.js +107 -0
  126. package/src/generators/repository-policy/repository-policy.js.map +1 -0
  127. package/src/generators/repository-policy/schema.d.ts +18 -0
  128. package/src/generators/repository-policy/schema.json +46 -0
  129. package/src/generators/service/service.d.ts +4 -0
  130. package/src/generators/service/service.js +5 -0
  131. package/src/generators/service/service.js.map +1 -0
  132. package/src/generators/slice/schema.d.ts +7 -0
  133. package/src/generators/slice/schema.json +38 -0
  134. package/src/generators/slice/slice.d.ts +26 -0
  135. package/src/generators/slice/slice.js +1698 -0
  136. package/src/generators/slice/slice.js.map +1 -0
  137. package/src/generators/upgrade/schema.d.ts +8 -0
  138. package/src/generators/upgrade/schema.json +31 -0
  139. package/src/generators/upgrade/upgrade.d.ts +27 -0
  140. package/src/generators/upgrade/upgrade.js +682 -0
  141. package/src/generators/upgrade/upgrade.js.map +1 -0
  142. package/src/generators/workload/schema.d.ts +6 -0
  143. package/src/generators/workload/schema.json +21 -0
  144. package/src/generators/workload/workload.d.ts +16 -0
  145. package/src/generators/workload/workload.js +157 -0
  146. package/src/generators/workload/workload.js.map +1 -0
  147. package/src/git-policy/action-pins.d.ts +28 -0
  148. package/src/git-policy/action-pins.js +35 -0
  149. package/src/git-policy/action-pins.js.map +1 -0
  150. package/src/git-policy/github-bootstrap.d.ts +23 -0
  151. package/src/git-policy/github-bootstrap.js +759 -0
  152. package/src/git-policy/github-bootstrap.js.map +1 -0
  153. package/src/git-policy/index.d.ts +3 -0
  154. package/src/git-policy/index.js +7 -0
  155. package/src/git-policy/index.js.map +1 -0
  156. package/src/git-policy/routing.d.ts +15 -0
  157. package/src/git-policy/routing.js +77 -0
  158. package/src/git-policy/routing.js.map +1 -0
  159. package/src/index.d.ts +8 -0
  160. package/src/index.js +12 -0
  161. package/src/index.js.map +1 -0
  162. package/src/local-dev/contracts.d.ts +31 -0
  163. package/src/local-dev/contracts.js +126 -0
  164. package/src/local-dev/contracts.js.map +1 -0
  165. package/src/local-dev/effects.d.ts +16 -0
  166. package/src/local-dev/effects.js +63 -0
  167. package/src/local-dev/effects.js.map +1 -0
  168. package/src/local-dev/gateway-daemon.d.ts +4 -0
  169. package/src/local-dev/gateway-daemon.js +39 -0
  170. package/src/local-dev/gateway-daemon.js.map +1 -0
  171. package/src/local-dev/gateway.d.ts +60 -0
  172. package/src/local-dev/gateway.js +368 -0
  173. package/src/local-dev/gateway.js.map +1 -0
  174. package/src/local-dev/identity.d.ts +16 -0
  175. package/src/local-dev/identity.js +101 -0
  176. package/src/local-dev/identity.js.map +1 -0
  177. package/src/local-dev/index.d.ts +7 -0
  178. package/src/local-dev/index.js +11 -0
  179. package/src/local-dev/index.js.map +1 -0
  180. package/src/local-dev/portless.d.ts +15 -0
  181. package/src/local-dev/portless.js +115 -0
  182. package/src/local-dev/portless.js.map +1 -0
  183. package/src/local-dev/ports.d.ts +10 -0
  184. package/src/local-dev/ports.js +39 -0
  185. package/src/local-dev/ports.js.map +1 -0
  186. package/src/local-dev/proxy.d.ts +37 -0
  187. package/src/local-dev/proxy.js +271 -0
  188. package/src/local-dev/proxy.js.map +1 -0
  189. package/src/local-dev/tls.d.ts +24 -0
  190. package/src/local-dev/tls.js +294 -0
  191. package/src/local-dev/tls.js.map +1 -0
  192. package/src/ownership/composition.d.ts +16 -0
  193. package/src/ownership/composition.js +125 -0
  194. package/src/ownership/composition.js.map +1 -0
  195. package/src/ownership/foundation-record.d.ts +66 -0
  196. package/src/ownership/foundation-record.js +108 -0
  197. package/src/ownership/foundation-record.js.map +1 -0
  198. package/src/ownership/hash.d.ts +2 -0
  199. package/src/ownership/hash.js +10 -0
  200. package/src/ownership/hash.js.map +1 -0
  201. package/src/ownership/index.d.ts +6 -0
  202. package/src/ownership/index.js +10 -0
  203. package/src/ownership/index.js.map +1 -0
  204. package/src/ownership/json-ownership.d.ts +13 -0
  205. package/src/ownership/json-ownership.js +147 -0
  206. package/src/ownership/json-ownership.js.map +1 -0
  207. package/src/ownership/record.d.ts +186 -0
  208. package/src/ownership/record.js +336 -0
  209. package/src/ownership/record.js.map +1 -0
  210. package/src/ownership/workspace-record.d.ts +66 -0
  211. package/src/ownership/workspace-record.js +108 -0
  212. package/src/ownership/workspace-record.js.map +1 -0
  213. package/src/repository-policy/aurora-preflight.d.ts +15 -0
  214. package/src/repository-policy/aurora-preflight.js +45 -0
  215. package/src/repository-policy/aurora-preflight.js.map +1 -0
  216. package/src/repository-policy/deployment-plan.d.ts +24 -0
  217. package/src/repository-policy/deployment-plan.js +124 -0
  218. package/src/repository-policy/deployment-plan.js.map +1 -0
  219. package/src/repository-policy/foundation-profile.d.ts +20 -0
  220. package/src/repository-policy/foundation-profile.js +45 -0
  221. package/src/repository-policy/foundation-profile.js.map +1 -0
  222. package/src/repository-policy/index.d.ts +4 -0
  223. package/src/repository-policy/index.js +8 -0
  224. package/src/repository-policy/index.js.map +1 -0
  225. package/src/repository-policy/policy.d.ts +59 -0
  226. package/src/repository-policy/policy.js +274 -0
  227. package/src/repository-policy/policy.js.map +1 -0
  228. package/src/schemas/blueprint-input-schema-v1.json +23 -0
  229. package/src/schemas/blueprint-v1.json +186 -0
  230. package/src/schemas/foundation-ownership-v2.json +42 -0
  231. package/src/schemas/foundation-requirement-v1.json +32 -0
  232. package/src/schemas/generated-ownership-v2.json +117 -0
  233. package/src/schemas/repository-policy-v1.json +58 -0
  234. package/src/schemas/workspace-ownership-v2.json +42 -0
  235. package/src/validation.d.ts +14 -0
  236. package/src/validation.js +14 -0
  237. package/src/validation.js.map +1 -0
  238. package/src/work-markers/index.d.ts +1 -0
  239. package/src/work-markers/index.js +5 -0
  240. package/src/work-markers/index.js.map +1 -0
  241. package/src/work-markers/work-markers.d.ts +39 -0
  242. package/src/work-markers/work-markers.js +359 -0
  243. package/src/work-markers/work-markers.js.map +1 -0
@@ -0,0 +1,682 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preserveCompositionRegions = preserveCompositionRegions;
4
+ exports.createUpgradeReport = createUpgradeReport;
5
+ exports.upgradeGenerator = upgradeGenerator;
6
+ const devkit_1 = require("@nx/devkit");
7
+ const node_path_1 = require("node:path");
8
+ const prettier_1 = require("prettier");
9
+ const index_js_1 = require("../../blueprints/index.js");
10
+ const index_js_2 = require("../../foundation/index.js");
11
+ const index_js_3 = require("../../ownership/index.js");
12
+ const function_js_1 = require("../function/function.js");
13
+ const generator_js_1 = require("../preset/generator.js");
14
+ const workspace_files_js_1 = require("../preset/workspace-files.js");
15
+ const slice_js_1 = require("../slice/slice.js");
16
+ const workload_js_1 = require("../workload/workload.js");
17
+ const COMPOSITION_REGIONS = [
18
+ 'composition-imports',
19
+ 'workload-registrations',
20
+ 'function-registrations',
21
+ 'composition-outputs',
22
+ ];
23
+ function preserveCompositionRegions(current, target) {
24
+ let merged = target;
25
+ for (const region of COMPOSITION_REGIONS) {
26
+ const start = `// <ebk:${region}:start>`;
27
+ const end = `// <ebk:${region}:end>`;
28
+ const currentStart = current.indexOf(start);
29
+ const currentEnd = current.indexOf(end);
30
+ const targetStart = merged.indexOf(start);
31
+ const targetEnd = merged.indexOf(end);
32
+ if (currentStart < 0 ||
33
+ currentEnd < currentStart ||
34
+ targetStart < 0 ||
35
+ targetEnd < targetStart) {
36
+ continue;
37
+ }
38
+ const currentBody = current.slice(currentStart + start.length, currentEnd);
39
+ merged =
40
+ merged.slice(0, targetStart + start.length) +
41
+ currentBody +
42
+ merged.slice(targetEnd);
43
+ }
44
+ return merged;
45
+ }
46
+ function json(value) {
47
+ return `${JSON.stringify(value, null, 2)}\n`;
48
+ }
49
+ function upgradeConflictMessage(label, report) {
50
+ const ownershipDetails = [
51
+ ...report.conflictingJsonMembers.map((member) => `- conflicting JSON ownership claim: ${member}`),
52
+ ...report.expandedJsonOwnership.map((path) => `- unsafe expansion to whole-file JSON ownership: ${path}`),
53
+ ];
54
+ return `${label} upgrade has user-modified managed files or unsafe JSON ownership changes:\n${report.conflicting.map((path) => `- ${path}`).join('\n')}${ownershipDetails.length > 0 ? `\n${ownershipDetails.join('\n')}` : ''}\nResolve or restore them before applying the upgrade.`;
55
+ }
56
+ async function formatRenderedFiles(files, prefix = '') {
57
+ return Object.fromEntries(await Promise.all(Object.entries(files).map(async ([path, contents]) => {
58
+ try {
59
+ return [
60
+ path,
61
+ await (0, prettier_1.format)(contents, {
62
+ filepath: node_path_1.posix.join(prefix, path),
63
+ singleQuote: true,
64
+ }),
65
+ ];
66
+ }
67
+ catch {
68
+ return [path, contents];
69
+ }
70
+ })));
71
+ }
72
+ function readJson(tree, path, label) {
73
+ const contents = tree.read(path, 'utf8');
74
+ if (contents === null)
75
+ throw new Error(`${label} does not exist at ${path}.`);
76
+ try {
77
+ return JSON.parse(contents);
78
+ }
79
+ catch (error) {
80
+ throw new Error(`${label} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
81
+ }
82
+ }
83
+ function ownershipValidationMessage(label, issues) {
84
+ const details = issues
85
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
86
+ .join('\n');
87
+ const regenerateHint = issues.some(({ path }) => path === 'ownership.schemaVersion')
88
+ ? '\nOwnership schema v2 has no pre-release migration shim. Regenerate this unpublished alpha workspace as documented in docs/upgrades.md.'
89
+ : '';
90
+ return `${label} is invalid:\n${details}${regenerateHint}`;
91
+ }
92
+ function requireUpgradePrerequisites(tree, target) {
93
+ const installedVersion = (0, generator_js_1.frameworkPackageVersion)();
94
+ const workspaceResult = (0, index_js_3.validateWorkspaceOwnershipRecord)(readJson(tree, '.ebk/ownership.json', 'Workspace ownership metadata'));
95
+ if (!workspaceResult.valid) {
96
+ throw new Error(ownershipValidationMessage('Workspace ownership metadata', workspaceResult.issues));
97
+ }
98
+ if (workspaceResult.value.frameworkVersion !== installedVersion) {
99
+ throw new Error(`Workspace tooling is recorded at ${workspaceResult.value.frameworkVersion}, but the installed @empire-builder-kit/nx version is ${installedVersion}. Report and apply the workspace upgrade before upgrading the ${target === 'foundation' ? 'Standard Foundation' : 'Product Slice'}.`);
100
+ }
101
+ if (target === 'foundation')
102
+ return;
103
+ const foundationResult = (0, index_js_3.validateFoundationOwnershipRecord)(readJson(tree, 'packages/foundation/.ebk/ownership.json', 'Standard Foundation ownership metadata'));
104
+ if (!foundationResult.valid) {
105
+ throw new Error(ownershipValidationMessage('Standard Foundation ownership metadata', foundationResult.issues));
106
+ }
107
+ if (foundationResult.value.frameworkVersion !== installedVersion) {
108
+ throw new Error(`Standard Foundation is recorded at ${foundationResult.value.frameworkVersion}, but the installed @empire-builder-kit/nx version is ${installedVersion}. Report and apply the Foundation upgrade before upgrading a Product Slice.`);
109
+ }
110
+ }
111
+ function requireName(name) {
112
+ const value = name.trim();
113
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(value)) {
114
+ throw new Error('Upgrade target name must use lowercase letters, numbers, and hyphens.');
115
+ }
116
+ return value;
117
+ }
118
+ function workspaceScope(packageJson) {
119
+ const name = packageJson.name?.trim();
120
+ if (!name || !/^[a-z0-9][a-z0-9-]*$/.test(name)) {
121
+ throw new Error('Workspace package.json must have an unscoped lowercase name.');
122
+ }
123
+ return `@${name}`;
124
+ }
125
+ function parseInputs(value, fallback) {
126
+ if (value === undefined)
127
+ return fallback;
128
+ if (typeof value !== 'string')
129
+ return value;
130
+ try {
131
+ const parsed = JSON.parse(value);
132
+ if (typeof parsed !== 'object' ||
133
+ parsed === null ||
134
+ Array.isArray(parsed)) {
135
+ throw new Error('value must be a JSON object');
136
+ }
137
+ return parsed;
138
+ }
139
+ catch (error) {
140
+ throw new Error(`Blueprint --inputs must be valid JSON object syntax: ${error instanceof Error ? error.message : String(error)}`);
141
+ }
142
+ }
143
+ function breakingTransitionMessage(current, blueprint, transition) {
144
+ const declarations = transition.availableMigrations.map(({ from, id, manualSuccession, to }) => `- ${id}: ${from} -> ${to}; guide ${blueprint.manifest.name}@${blueprint.manifest.version}:${manualSuccession}`);
145
+ const reason = transition.reason === 'blueprint-identity-change'
146
+ ? 'Changing Blueprint package identity is a manual replacement, not a v1 managed upgrade.'
147
+ : transition.reason === 'ambiguous-migrations'
148
+ ? 'More than one publisher migration matches the recorded version; the publisher must make the transition unambiguous.'
149
+ : transition.reason === 'source-range-mismatch'
150
+ ? 'The target Blueprint declares migrations, but none has a source range matching the recorded version.'
151
+ : 'The target Blueprint declares no breaking-version migration.';
152
+ return `[ebk-upgrade] blocked breaking Blueprint transition
153
+ Recorded: ${current.name}@${current.version}
154
+ Requested: ${blueprint.manifest.name}@${blueprint.manifest.version}
155
+ Compatible target line: ${current.name}@${transition.compatibilityLine}
156
+ Reason: ${reason}
157
+ ${declarations.length > 0 ? `Available target declarations:\n${declarations.join('\n')}\n` : ''}No Blueprint files were rendered or changed. Keep using an exact compatible-line target, or create a reviewed replacement Product Slice with publisher guidance.`;
158
+ }
159
+ function gateBreakingBlueprintTransition(current, blueprint, apply) {
160
+ const transition = (0, index_js_1.classifyBlueprintTransition)(current, blueprint.manifest);
161
+ if (transition.kind === 'compatible')
162
+ return false;
163
+ if (transition.kind === 'blocked') {
164
+ throw new Error(breakingTransitionMessage(current, blueprint, transition));
165
+ }
166
+ const { migration } = transition;
167
+ const report = {
168
+ affectedManagedSurfaces: migration.affectedManagedSurfaces,
169
+ contracts: migration.contracts,
170
+ databaseChange: migration.databaseChange,
171
+ dependencyChanges: migration.dependencyChanges,
172
+ executor: migration.executor
173
+ ? `${blueprint.manifest.name}@${blueprint.manifest.version}:${migration.executor}`
174
+ : null,
175
+ infrastructureChanges: migration.infrastructureChanges,
176
+ maintenanceWindowRequired: migration.maintenanceWindowRequired,
177
+ migration: migration.id,
178
+ preflight: migration.preflight,
179
+ recorded: `${current.name}@${current.version}`,
180
+ requested: `${blueprint.manifest.name}@${blueprint.manifest.version}`,
181
+ rollback: migration.rollback,
182
+ sourceRange: migration.from,
183
+ manualSuccession: `${blueprint.manifest.name}@${blueprint.manifest.version}:${migration.manualSuccession}`,
184
+ verification: migration.verification,
185
+ };
186
+ devkit_1.logger.info(`[ebk-upgrade] declared breaking Blueprint transition — manual succession only\n${JSON.stringify(report, null, 2)}\nNo Blueprint files were rendered or changed. The declared executor, if any, was not executed.`);
187
+ if (apply) {
188
+ throw new Error(`Breaking Blueprint migration ${migration.id} is report-only in v1 and was not applied. Follow ${report.manualSuccession}; do not restamp the target Blueprint as active until manual succession is complete.`);
189
+ }
190
+ return true;
191
+ }
192
+ function createUpgradeReport(currentFiles, currentOwnership, targetFiles, targetOwnership, jsonOwnershipChanges = {
193
+ claimedJsonMembers: [],
194
+ conflictingJsonMembers: [],
195
+ expandedJsonOwnership: [],
196
+ releasedJsonMembers: [],
197
+ }) {
198
+ const report = {
199
+ addedSeeded: [],
200
+ changed: [],
201
+ claimedJsonMembers: [...jsonOwnershipChanges.claimedJsonMembers],
202
+ conflicting: [],
203
+ conflictingJsonMembers: [...jsonOwnershipChanges.conflictingJsonMembers],
204
+ expandedJsonOwnership: [...jsonOwnershipChanges.expandedJsonOwnership],
205
+ missing: [],
206
+ obsolete: [],
207
+ preservedSeeded: [],
208
+ releasedJsonMembers: [...jsonOwnershipChanges.releasedJsonMembers],
209
+ unchanged: [],
210
+ };
211
+ const targetPaths = new Set(targetOwnership.paths.map(({ path }) => path));
212
+ const currentPathOwnership = new Map(currentOwnership.paths.map((entry) => [entry.path, entry]));
213
+ for (const { mode, path } of targetOwnership.paths) {
214
+ const current = currentFiles.get(path) ?? null;
215
+ const target = targetFiles.get(path);
216
+ const currentEntry = currentPathOwnership.get(path);
217
+ if (target === undefined) {
218
+ throw new Error(`Target Blueprint did not render owned path ${path}.`);
219
+ }
220
+ if (mode === 'seeded') {
221
+ (current === null ? report.addedSeeded : report.preservedSeeded).push(path);
222
+ }
223
+ else if (current === null) {
224
+ report.missing.push(path);
225
+ }
226
+ else if (currentEntry !== undefined &&
227
+ (0, index_js_3.hashOwnedContent)(current, currentEntry) !== currentEntry.sha256) {
228
+ report.conflicting.push(path);
229
+ }
230
+ else if (current === target) {
231
+ report.unchanged.push(path);
232
+ }
233
+ else if (currentEntry === undefined) {
234
+ report.conflicting.push(path);
235
+ }
236
+ else {
237
+ report.changed.push(path);
238
+ }
239
+ }
240
+ for (const entry of currentOwnership.paths) {
241
+ const { mode, origin, path, sha256 } = entry;
242
+ if (mode !== 'managed' ||
243
+ origin === 'composition' ||
244
+ targetPaths.has(path)) {
245
+ continue;
246
+ }
247
+ const current = currentFiles.get(path) ?? null;
248
+ if (current === null)
249
+ continue;
250
+ if ((0, index_js_3.hashOwnedContent)(current, entry) === sha256) {
251
+ report.obsolete.push(path);
252
+ }
253
+ else if (!report.conflicting.includes(path)) {
254
+ report.conflicting.push(path);
255
+ }
256
+ }
257
+ const ownershipConflictPaths = new Set([
258
+ ...report.expandedJsonOwnership,
259
+ ...report.conflictingJsonMembers.map((member) => member.slice(0, member.indexOf('#/'))),
260
+ ]);
261
+ for (const path of ownershipConflictPaths) {
262
+ report.changed = report.changed.filter((entry) => entry !== path);
263
+ report.unchanged = report.unchanged.filter((entry) => entry !== path);
264
+ if (!report.conflicting.includes(path))
265
+ report.conflicting.push(path);
266
+ }
267
+ for (const paths of Object.values(report))
268
+ paths.sort();
269
+ return report;
270
+ }
271
+ function mergeStructuredTargetFiles(currentFiles, currentOwnership, targetFiles, targetOwnership) {
272
+ const files = new Map(targetFiles);
273
+ const changes = {
274
+ claimedJsonMembers: [],
275
+ conflictingJsonMembers: [],
276
+ expandedJsonOwnership: [],
277
+ releasedJsonMembers: [],
278
+ };
279
+ const currentEntries = new Map(currentOwnership.paths.map((entry) => [entry.path, entry]));
280
+ for (const targetEntry of targetOwnership.paths) {
281
+ const currentEntry = currentEntries.get(targetEntry.path);
282
+ const current = currentFiles.get(targetEntry.path) ?? null;
283
+ const target = files.get(targetEntry.path);
284
+ if (current === null || target === undefined)
285
+ continue;
286
+ if (currentEntry?.managedJsonPointers && !targetEntry.managedJsonPointers) {
287
+ if (targetEntry.mode === 'managed') {
288
+ changes.expandedJsonOwnership.push(targetEntry.path);
289
+ }
290
+ else {
291
+ changes.releasedJsonMembers.push(...currentEntry.managedJsonPointers.map((pointer) => `${targetEntry.path}#${pointer}`));
292
+ }
293
+ continue;
294
+ }
295
+ if (!targetEntry.managedJsonPointers)
296
+ continue;
297
+ if (currentEntry?.managedJsonPointers) {
298
+ const transition = (0, index_js_3.analyzeManagedJsonPointerTransition)(current, target, currentEntry.managedJsonPointers, targetEntry.managedJsonPointers);
299
+ changes.claimedJsonMembers.push(...transition.claimed.map((pointer) => `${targetEntry.path}#${pointer}`));
300
+ changes.conflictingJsonMembers.push(...transition.conflictingClaims.map((pointer) => `${targetEntry.path}#${pointer}`));
301
+ changes.releasedJsonMembers.push(...transition.released.map((pointer) => `${targetEntry.path}#${pointer}`));
302
+ if (transition.conflictingClaims.length > 0) {
303
+ files.set(targetEntry.path, current);
304
+ continue;
305
+ }
306
+ }
307
+ files.set(targetEntry.path, (0, index_js_3.mergeManagedJsonContents)(current, target, targetEntry.managedJsonPointers));
308
+ }
309
+ return { files, ...changes };
310
+ }
311
+ function renderCompositionUpgradePlan(ownership) {
312
+ const compositionPaths = ownership.paths.filter(({ origin }) => origin === 'composition');
313
+ const functionNames = new Set();
314
+ const workloads = new Map();
315
+ for (const { path } of compositionPaths) {
316
+ const functionMatch = /^infra\/functions\/([^/]+)\.ts$/.exec(path);
317
+ if (functionMatch?.[1])
318
+ functionNames.add(functionMatch[1]);
319
+ const workloadMatch = /^(services|jobs)\/([^/]+)\//.exec(path);
320
+ if (workloadMatch?.[1] && workloadMatch[2]) {
321
+ workloads.set(`${workloadMatch[1]}/${workloadMatch[2]}`, {
322
+ kind: workloadMatch[1] === 'services' ? 'service' : 'job',
323
+ name: workloadMatch[2],
324
+ });
325
+ }
326
+ }
327
+ const files = {};
328
+ const paths = new Map();
329
+ const addPlan = (planFiles, planPaths) => {
330
+ Object.assign(files, planFiles);
331
+ for (const entry of planPaths) {
332
+ const contents = planFiles[entry.path];
333
+ if (contents === undefined) {
334
+ throw new Error(`Composition plan did not render ${entry.path}.`);
335
+ }
336
+ paths.set(entry.path, {
337
+ ...(entry.managedJsonPointers
338
+ ? { managedJsonPointers: entry.managedJsonPointers }
339
+ : {}),
340
+ mode: entry.mode ?? 'managed',
341
+ origin: 'composition',
342
+ path: entry.path,
343
+ sha256: (0, index_js_3.hashOwnedContent)(contents, entry),
344
+ });
345
+ }
346
+ };
347
+ for (const name of functionNames) {
348
+ const plan = (0, function_js_1.createFunctionFilePlan)(ownership.slice, name);
349
+ addPlan(plan.files, plan.paths);
350
+ }
351
+ for (const { kind, name } of workloads.values()) {
352
+ const plan = (0, workload_js_1.createWorkloadFilePlan)(ownership.slice, name, kind);
353
+ addPlan(plan.files, plan.paths);
354
+ }
355
+ for (const entry of compositionPaths) {
356
+ if (paths.has(entry.path))
357
+ continue;
358
+ paths.set(entry.path, entry);
359
+ }
360
+ return { files, paths: [...paths.values()] };
361
+ }
362
+ async function upgradeFoundation(tree, options, packageJson) {
363
+ if (options.blueprint !== undefined || options.inputs !== undefined) {
364
+ throw new Error('Standard Foundation upgrades do not accept Blueprint or input options.');
365
+ }
366
+ const root = 'packages/foundation';
367
+ const ownershipResult = (0, index_js_3.validateFoundationOwnershipRecord)(readJson(tree, node_path_1.posix.join(root, '.ebk/ownership.json'), 'Standard Foundation ownership metadata'));
368
+ if (!ownershipResult.valid) {
369
+ throw new Error(ownershipValidationMessage('Standard Foundation ownership metadata', ownershipResult.issues));
370
+ }
371
+ if (!packageJson.name) {
372
+ throw new Error('Workspace package.json must declare a name.');
373
+ }
374
+ const currentOwnership = ownershipResult.value;
375
+ const renderedTarget = (0, workspace_files_js_1.renderFoundationFilePlan)({
376
+ frameworkVersion: (0, generator_js_1.frameworkPackageVersion)(),
377
+ name: packageJson.name,
378
+ });
379
+ const target = {
380
+ ...renderedTarget,
381
+ files: await formatRenderedFiles(renderedTarget.files, root),
382
+ };
383
+ const targetValidation = (0, index_js_3.validateFoundationOwnershipRecord)(target.ownership);
384
+ if (!targetValidation.valid) {
385
+ throw new Error(`Target Standard Foundation ownership metadata is invalid:\n${targetValidation.issues
386
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
387
+ .join('\n')}`);
388
+ }
389
+ const allPaths = new Set([
390
+ ...currentOwnership.paths.map(({ path }) => path),
391
+ ...target.ownership.paths.map(({ path }) => path),
392
+ ]);
393
+ const currentFiles = new Map([...allPaths].map((path) => [
394
+ path,
395
+ tree.read(node_path_1.posix.join(root, path), 'utf8'),
396
+ ]));
397
+ const mergedTarget = mergeStructuredTargetFiles(currentFiles, currentOwnership, new Map(Object.entries(target.files)), target.ownership);
398
+ const report = createUpgradeReport(currentFiles, currentOwnership, mergedTarget.files, target.ownership, mergedTarget);
399
+ devkit_1.logger.info(`[ebk-upgrade] foundation ${currentOwnership.frameworkVersion} -> ${target.ownership.frameworkVersion}\n${JSON.stringify(report, null, 2)}`);
400
+ if (!options.apply)
401
+ return;
402
+ if (report.conflicting.length > 0) {
403
+ throw new Error(upgradeConflictMessage('Standard Foundation', report));
404
+ }
405
+ for (const path of report.obsolete)
406
+ tree.delete(node_path_1.posix.join(root, path));
407
+ const writePaths = new Set([
408
+ ...report.changed,
409
+ ...report.missing,
410
+ ...report.addedSeeded,
411
+ '.ebk/ownership.json',
412
+ ]);
413
+ for (const path of writePaths) {
414
+ const contents = mergedTarget.files.get(path);
415
+ if (contents === undefined) {
416
+ throw new Error(`Target Standard Foundation did not render ${path}.`);
417
+ }
418
+ tree.write(node_path_1.posix.join(root, path), contents);
419
+ }
420
+ if (!options.skipFormat)
421
+ await (0, devkit_1.formatFiles)(tree);
422
+ (0, index_js_3.restampFoundationOwnership)(tree);
423
+ }
424
+ async function upgradeWorkspace(tree, options, packageJson) {
425
+ if (options.blueprint !== undefined || options.inputs !== undefined) {
426
+ throw new Error('Workspace upgrades do not accept Blueprint or input options.');
427
+ }
428
+ const ownershipResult = (0, index_js_3.validateWorkspaceOwnershipRecord)(readJson(tree, '.ebk/ownership.json', 'Workspace ownership metadata'));
429
+ if (!ownershipResult.valid) {
430
+ throw new Error(ownershipValidationMessage('Workspace ownership metadata', ownershipResult.issues));
431
+ }
432
+ if (!packageJson.name) {
433
+ throw new Error('Workspace package.json must declare a name.');
434
+ }
435
+ const currentOwnership = ownershipResult.value;
436
+ const renderedTarget = (0, workspace_files_js_1.renderWorkspaceRootFilePlan)({
437
+ frameworkVersion: (0, generator_js_1.frameworkPackageVersion)(),
438
+ name: packageJson.name,
439
+ });
440
+ const target = {
441
+ ...renderedTarget,
442
+ files: await formatRenderedFiles(renderedTarget.files),
443
+ };
444
+ const targetValidation = (0, index_js_3.validateWorkspaceOwnershipRecord)(target.ownership);
445
+ if (!targetValidation.valid) {
446
+ throw new Error('Target workspace ownership metadata is invalid.');
447
+ }
448
+ const allPaths = new Set([
449
+ ...currentOwnership.paths.map(({ path }) => path),
450
+ ...target.ownership.paths.map(({ path }) => path),
451
+ ]);
452
+ const currentFiles = new Map([...allPaths].map((path) => [path, tree.read(path, 'utf8')]));
453
+ const mergedTarget = mergeStructuredTargetFiles(currentFiles, currentOwnership, new Map(Object.entries(target.files)), target.ownership);
454
+ const report = createUpgradeReport(currentFiles, currentOwnership, mergedTarget.files, target.ownership, mergedTarget);
455
+ devkit_1.logger.info(`[ebk-upgrade] workspace ${currentOwnership.frameworkVersion} -> ${target.ownership.frameworkVersion}\n${JSON.stringify(report, null, 2)}`);
456
+ const repositoryPolicyContents = tree.read('ebk.repository-policy.json', 'utf8');
457
+ if (repositoryPolicyContents !== null) {
458
+ try {
459
+ const repositoryPolicy = JSON.parse(repositoryPolicyContents);
460
+ if (typeof repositoryPolicy === 'object' &&
461
+ repositoryPolicy !== null &&
462
+ !Array.isArray(repositoryPolicy) &&
463
+ !Object.prototype.hasOwnProperty.call(repositoryPolicy, 'productionApproval')) {
464
+ devkit_1.logger.warn('[ebk-upgrade] Preserved pre-beta.7 Repository Operating Policy requires an explicit production approval amendment before workspace health or GitHub bootstrap. Report it with pnpm nx g @empire-builder-kit/nx:repository-policy --productionApprovalMode=promotion-pr, then rerun with --apply after review. Use environment-reviewer instead only when that stronger committed contract is intended and supported.');
465
+ }
466
+ }
467
+ catch {
468
+ // The upgrade preserves adopter-owned policy source. Its normal validator
469
+ // reports malformed JSON; this notice is only for the known missing member.
470
+ }
471
+ }
472
+ if (!options.apply)
473
+ return;
474
+ if (report.conflicting.length > 0) {
475
+ throw new Error(upgradeConflictMessage('Workspace', report));
476
+ }
477
+ for (const path of report.obsolete)
478
+ tree.delete(path);
479
+ const writePaths = new Set([
480
+ ...report.changed,
481
+ ...report.missing,
482
+ ...report.addedSeeded,
483
+ '.ebk/ownership.json',
484
+ ]);
485
+ for (const path of writePaths) {
486
+ const contents = mergedTarget.files.get(path);
487
+ if (contents === undefined) {
488
+ throw new Error(`Target workspace did not render ${path}.`);
489
+ }
490
+ tree.write(path, contents);
491
+ }
492
+ if (!options.skipFormat)
493
+ await (0, devkit_1.formatFiles)(tree);
494
+ (0, index_js_3.restampWorkspaceOwnership)(tree);
495
+ }
496
+ async function upgradeGenerator(tree, options) {
497
+ const name = requireName(options.name);
498
+ const packageJson = readJson(tree, 'package.json', 'Workspace package.json');
499
+ if (name === 'workspace') {
500
+ return upgradeWorkspace(tree, options, packageJson);
501
+ }
502
+ if (name === 'foundation') {
503
+ requireUpgradePrerequisites(tree, 'foundation');
504
+ return upgradeFoundation(tree, options, packageJson);
505
+ }
506
+ requireUpgradePrerequisites(tree, 'product-slice');
507
+ const root = node_path_1.posix.join('packages', name);
508
+ const ownershipResult = (0, index_js_3.validateGeneratedOwnershipRecord)(readJson(tree, node_path_1.posix.join(root, '.ebk/ownership.json'), 'Product Slice ownership metadata'));
509
+ if (!ownershipResult.valid) {
510
+ throw new Error(ownershipValidationMessage('Product Slice ownership metadata', ownershipResult.issues));
511
+ }
512
+ const currentOwnership = ownershipResult.value;
513
+ if (currentOwnership.slice !== name) {
514
+ throw new Error(`Ownership metadata belongs to ${currentOwnership.slice}, not ${name}.`);
515
+ }
516
+ const recordedReference = currentOwnership.blueprint.name === index_js_1.BUILTIN_BLUEPRINT_NAME
517
+ ? index_js_1.BUILTIN_BLUEPRINT_REFERENCE
518
+ : `${currentOwnership.blueprint.name}@${currentOwnership.blueprint.version}`;
519
+ const blueprint = (0, index_js_1.resolveBlueprint)({
520
+ localPackages: packageJson.ebk?.blueprints?.localPackages,
521
+ reference: options.blueprint ?? recordedReference,
522
+ trust: { packages: packageJson.ebk?.blueprints?.trustedPackages ?? [] },
523
+ workspaceRoot: tree.root,
524
+ });
525
+ const inputResult = (0, index_js_1.validateBlueprintInputs)(blueprint.inputSchema, parseInputs(options.inputs, currentOwnership.inputs));
526
+ if (!inputResult.valid) {
527
+ throw new Error(`Blueprint inputs are invalid:\n${inputResult.issues
528
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
529
+ .join('\n')}`);
530
+ }
531
+ const compatibility = (0, index_js_2.validateFoundationCompatibility)(blueprint.manifest.foundation, readJson(tree, 'packages/foundation/contracts/foundation.json', 'Standard Foundation descriptor'));
532
+ if (!compatibility.valid) {
533
+ throw new Error(`Standard Foundation is incompatible with the target Blueprint:\n${compatibility.issues
534
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
535
+ .join('\n')}`);
536
+ }
537
+ if (gateBreakingBlueprintTransition(currentOwnership.blueprint, blueprint, options.apply === true)) {
538
+ return;
539
+ }
540
+ let targetFiles;
541
+ let targetOwnership;
542
+ const scope = workspaceScope(packageJson);
543
+ if (blueprint.source === 'built-in') {
544
+ const runtimeVersion = packageJson.dependencies?.['@empire-builder-kit/runtime'];
545
+ if (!runtimeVersion)
546
+ throw new Error('Workspace must depend on @empire-builder-kit/runtime.');
547
+ const plan = (0, slice_js_1.createBuiltInSlicePlan)(name, scope, runtimeVersion, blueprint.manifest, inputResult.value);
548
+ targetFiles = Object.fromEntries(Object.entries(plan.files).map(([path, contents]) => {
549
+ const current = tree.read(node_path_1.posix.join(root, path), 'utf8');
550
+ return [
551
+ path,
552
+ current === null
553
+ ? contents
554
+ : preserveCompositionRegions(current, contents),
555
+ ];
556
+ }));
557
+ targetOwnership = plan.ownership;
558
+ }
559
+ else {
560
+ if (!blueprint.generatorPath) {
561
+ throw new Error('Resolved external Blueprint has no generator entry point.');
562
+ }
563
+ const generated = await (0, index_js_1.executeBlueprintGenerator)(blueprint.generatorPath, {
564
+ foundation: compatibility.value,
565
+ inputs: inputResult.value,
566
+ manifest: blueprint.manifest,
567
+ name,
568
+ root,
569
+ workspace: { name: packageJson.name ?? '', scope },
570
+ });
571
+ const paths = generated.files.map(({ contents, managedJsonPointers, mode, path }) => ({
572
+ ...(managedJsonPointers ? { managedJsonPointers } : {}),
573
+ mode,
574
+ origin: 'blueprint',
575
+ path,
576
+ sha256: (0, index_js_3.hashOwnedContent)(contents, { managedJsonPointers }),
577
+ }));
578
+ paths.sort((left, right) => left.path.localeCompare(right.path));
579
+ targetOwnership = {
580
+ blueprint: {
581
+ name: blueprint.manifest.name,
582
+ version: blueprint.manifest.version,
583
+ },
584
+ contracts: generated.contracts,
585
+ foundation: blueprint.manifest.foundation,
586
+ inputs: inputResult.value,
587
+ paths,
588
+ projects: generated.projects,
589
+ schemaVersion: index_js_3.GENERATED_OWNERSHIP_SCHEMA_VERSION,
590
+ slice: name,
591
+ verification: blueprint.manifest.verification,
592
+ };
593
+ targetFiles = Object.fromEntries([
594
+ ...generated.files.map(({ contents, path }) => [path, contents]),
595
+ ['.ebk/ownership.json', json(targetOwnership)],
596
+ ]);
597
+ }
598
+ const targetPathSet = new Set(targetOwnership.paths.map(({ path }) => path));
599
+ const compositionPlan = renderCompositionUpgradePlan(currentOwnership);
600
+ const compositionPaths = compositionPlan.paths.filter(({ path }) => !targetPathSet.has(path));
601
+ for (const entry of compositionPaths) {
602
+ const contents = compositionPlan.files[entry.path] ??
603
+ tree.read(node_path_1.posix.join(root, entry.path), 'utf8');
604
+ if (contents === null) {
605
+ throw new Error(`Composed owned path is missing: ${entry.path}.`);
606
+ }
607
+ targetFiles = { ...targetFiles, [entry.path]: contents };
608
+ }
609
+ targetFiles = await formatRenderedFiles(targetFiles, root);
610
+ targetOwnership = {
611
+ ...targetOwnership,
612
+ ...(targetOwnership.migrationHistory === undefined &&
613
+ currentOwnership.migrationHistory !== undefined
614
+ ? { migrationHistory: currentOwnership.migrationHistory }
615
+ : {}),
616
+ paths: [...targetOwnership.paths, ...compositionPaths].map((entry) => {
617
+ const contents = targetFiles[entry.path];
618
+ if (contents === undefined) {
619
+ throw new Error(`Target Blueprint did not render ${entry.path}.`);
620
+ }
621
+ return { ...entry, sha256: (0, index_js_3.hashOwnedContent)(contents, entry) };
622
+ }),
623
+ projects: [
624
+ ...new Set([...targetOwnership.projects, ...currentOwnership.projects]),
625
+ ].sort(),
626
+ };
627
+ targetFiles = {
628
+ ...targetFiles,
629
+ '.ebk/ownership.json': json(targetOwnership),
630
+ };
631
+ const targetValidation = (0, index_js_3.validateGeneratedOwnershipRecord)(targetOwnership);
632
+ if (!targetValidation.valid) {
633
+ throw new Error(`Target ownership metadata is invalid:\n${targetValidation.issues
634
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
635
+ .join('\n')}`);
636
+ }
637
+ const allPaths = new Set([
638
+ ...currentOwnership.paths.map(({ path }) => path),
639
+ ...targetOwnership.paths.map(({ path }) => path),
640
+ ]);
641
+ const currentFiles = new Map([...allPaths].map((path) => [
642
+ path,
643
+ tree.read(node_path_1.posix.join(root, path), 'utf8'),
644
+ ]));
645
+ const mergedTarget = mergeStructuredTargetFiles(currentFiles, currentOwnership, new Map(Object.entries(targetFiles)), targetOwnership);
646
+ const report = createUpgradeReport(currentFiles, currentOwnership, mergedTarget.files, targetOwnership, mergedTarget);
647
+ devkit_1.logger.info(`[ebk-upgrade] ${name} ${currentOwnership.blueprint.name}@${currentOwnership.blueprint.version} -> ${blueprint.manifest.name}@${blueprint.manifest.version}\n${JSON.stringify(report, null, 2)}`);
648
+ if (!options.apply)
649
+ return;
650
+ if (report.conflicting.length > 0) {
651
+ throw new Error(upgradeConflictMessage('Product Slice', report));
652
+ }
653
+ for (const path of report.obsolete)
654
+ tree.delete(node_path_1.posix.join(root, path));
655
+ const writePaths = new Set([
656
+ ...report.changed,
657
+ ...report.missing,
658
+ ...report.addedSeeded,
659
+ '.ebk/ownership.json',
660
+ ]);
661
+ for (const path of writePaths) {
662
+ const contents = mergedTarget.files.get(path);
663
+ if (contents === undefined)
664
+ throw new Error(`Target Blueprint did not render ${path}.`);
665
+ tree.write(node_path_1.posix.join(root, path), contents);
666
+ }
667
+ if (blueprint.source === 'installed') {
668
+ packageJson.devDependencies = {
669
+ ...packageJson.devDependencies,
670
+ [blueprint.manifest.name]: blueprint.manifest.version,
671
+ };
672
+ tree.write('package.json', json(packageJson));
673
+ }
674
+ if (!options.skipFormat)
675
+ await (0, devkit_1.formatFiles)(tree);
676
+ (0, index_js_3.restampProductSliceOwnership)(tree, name);
677
+ return options.skipInstall
678
+ ? undefined
679
+ : () => (0, devkit_1.installPackagesTask)(tree, true);
680
+ }
681
+ exports.default = upgradeGenerator;
682
+ //# sourceMappingURL=upgrade.js.map