@empire-builder-kit/nx 1.0.0-rc.2 → 1.0.0-rc.21

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 (253) hide show
  1. package/executors.json +10 -0
  2. package/package.json +4 -4
  3. package/src/cli/output.js +1 -1
  4. package/src/developer-agent/model.js +4 -4
  5. package/src/developer-agent/model.js.map +1 -1
  6. package/src/developer-agent/operation-registry.js +67 -10
  7. package/src/developer-agent/operation-registry.js.map +1 -1
  8. package/src/developer-agent/planning.js +7 -9
  9. package/src/developer-agent/planning.js.map +1 -1
  10. package/src/developer-agent/workspace-inspection.js +12 -0
  11. package/src/developer-agent/workspace-inspection.js.map +1 -1
  12. package/src/executors/blueprint-trust/blueprint-trust.js +6 -0
  13. package/src/executors/blueprint-trust/blueprint-trust.js.map +1 -1
  14. package/src/executors/deployment-plan/deployment-plan.js +5 -0
  15. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  16. package/src/executors/foundation-preflight/foundation-preflight.d.ts +2 -0
  17. package/src/executors/foundation-preflight/foundation-preflight.js +6 -2
  18. package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -1
  19. package/src/executors/foundation-preflight/schema.json +10 -0
  20. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +2 -0
  21. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +2 -1
  22. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -1
  23. package/src/executors/foundation-profile-preflight/schema.json +19 -3
  24. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  25. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  26. package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +229 -5
  27. package/src/executors/infrastructure-plan/infrastructure-plan.js +2298 -175
  28. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -1
  29. package/src/executors/infrastructure-plan/schema.json +16 -0
  30. package/src/executors/local-deploy/fixtures/local-deploy-state-machine.mjs +53 -0
  31. package/src/executors/local-deploy/local-approval.d.ts +23 -0
  32. package/src/executors/local-deploy/local-approval.js +43 -0
  33. package/src/executors/local-deploy/local-approval.js.map +1 -0
  34. package/src/executors/local-deploy/local-deploy.d.ts +69 -0
  35. package/src/executors/local-deploy/local-deploy.js +911 -0
  36. package/src/executors/local-deploy/local-deploy.js.map +1 -0
  37. package/src/executors/local-deploy/schema.json +42 -0
  38. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +3 -0
  39. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +94 -0
  40. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +1 -0
  41. package/src/executors/router-waf-rehearsal/schema.json +9 -0
  42. package/src/executors/secret-metadata/schema.json +5 -0
  43. package/src/executors/secret-metadata/secret-metadata.d.ts +12 -1
  44. package/src/executors/secret-metadata/secret-metadata.js +68 -16
  45. package/src/executors/secret-metadata/secret-metadata.js.map +1 -1
  46. package/src/executors/sst-lifecycle/logging-preflight.d.ts +5 -0
  47. package/src/executors/sst-lifecycle/logging-preflight.js +23 -13
  48. package/src/executors/sst-lifecycle/logging-preflight.js.map +1 -1
  49. package/src/executors/sst-lifecycle/run-sst-command.d.ts +8 -1
  50. package/src/executors/sst-lifecycle/run-sst-command.js +144 -12
  51. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  52. package/src/executors/sst-lifecycle/schema.json +13 -1
  53. package/src/executors/sst-lifecycle/sst-environment-source.d.ts +25 -0
  54. package/src/executors/sst-lifecycle/sst-environment-source.js +213 -0
  55. package/src/executors/sst-lifecycle/sst-environment-source.js.map +1 -0
  56. package/src/foundation/index.d.ts +2 -0
  57. package/src/foundation/index.js +2 -0
  58. package/src/foundation/index.js.map +1 -1
  59. package/src/foundation/logging-preflight.js +1 -1
  60. package/src/foundation/logging-preflight.js.map +1 -1
  61. package/src/foundation/logging.d.ts +3 -1
  62. package/src/foundation/logging.js +1 -1
  63. package/src/foundation/logging.js.map +1 -1
  64. package/src/foundation/partial-state.d.ts +10 -0
  65. package/src/foundation/partial-state.js +21 -0
  66. package/src/foundation/partial-state.js.map +1 -0
  67. package/src/foundation/router-waf.d.ts +98 -0
  68. package/src/foundation/router-waf.js +401 -0
  69. package/src/foundation/router-waf.js.map +1 -0
  70. package/src/generators/function/function.js +2 -1
  71. package/src/generators/function/function.js.map +1 -1
  72. package/src/generators/post-generation-install.d.ts +1 -0
  73. package/src/generators/post-generation-install.js +134 -67
  74. package/src/generators/post-generation-install.js.map +1 -1
  75. package/src/generators/preset/generator.js +23 -3
  76. package/src/generators/preset/generator.js.map +1 -1
  77. package/src/generators/preset/schema.d.ts +7 -0
  78. package/src/generators/preset/schema.json +47 -0
  79. package/src/generators/preset/tool-versions.d.ts +5 -5
  80. package/src/generators/preset/tool-versions.js +4 -4
  81. package/src/generators/preset/workspace-files-ci-acceptance.d.ts +1 -0
  82. package/src/generators/preset/workspace-files-ci-acceptance.js +791 -0
  83. package/src/generators/preset/workspace-files-ci-acceptance.js.map +1 -0
  84. package/src/generators/preset/workspace-files-developer-agent.d.ts +2 -0
  85. package/src/generators/preset/workspace-files-developer-agent.js +25 -11
  86. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -1
  87. package/src/generators/preset/workspace-files-foundation-workload-roles.js +5 -2
  88. package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +1 -1
  89. package/src/generators/preset/workspace-files-performance-load.js +2 -1
  90. package/src/generators/preset/workspace-files-performance-load.js.map +1 -1
  91. package/src/generators/preset/workspace-files-workload-role-baseline.js +254 -42
  92. package/src/generators/preset/workspace-files-workload-role-baseline.js.map +1 -1
  93. package/src/generators/preset/workspace-files.d.ts +8 -4
  94. package/src/generators/preset/workspace-files.js +1039 -68
  95. package/src/generators/preset/workspace-files.js.map +1 -1
  96. package/src/generators/repository-policy/repository-policy.js +65 -3
  97. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  98. package/src/generators/repository-policy/schema.d.ts +6 -0
  99. package/src/generators/repository-policy/schema.json +46 -0
  100. package/src/generators/slice/built-in-plan-api-files.js +2 -1
  101. package/src/generators/slice/built-in-plan-api-files.js.map +1 -1
  102. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +19 -1
  103. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -1
  104. package/src/generators/slice/built-in-plan-data-files.js +16 -5
  105. package/src/generators/slice/built-in-plan-data-files.js.map +1 -1
  106. package/src/generators/slice/built-in-plan-data-retention-job-files.js +10 -6
  107. package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +1 -1
  108. package/src/generators/slice/built-in-plan-database-lifecycle-files.js +25 -10
  109. package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +1 -1
  110. package/src/generators/slice/built-in-plan-foundation-files.js +2 -3
  111. package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -1
  112. package/src/generators/slice/built-in-plan-infrastructure-files.js +364 -29
  113. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -1
  114. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js +67 -11
  115. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +1 -1
  116. package/src/generators/slice/built-in-plan-metadata-files.js +1 -0
  117. package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -1
  118. package/src/generators/slice/built-in-plan-operations-files.js +442 -5
  119. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -1
  120. package/src/generators/slice/built-in-plan-performance-files.d.ts +2 -1
  121. package/src/generators/slice/built-in-plan-performance-files.js +41 -47
  122. package/src/generators/slice/built-in-plan-performance-files.js.map +1 -1
  123. package/src/generators/slice/built-in-plan-project-files.js +14 -1
  124. package/src/generators/slice/built-in-plan-project-files.js.map +1 -1
  125. package/src/generators/slice/built-in-plan-release-files.js +235 -56
  126. package/src/generators/slice/built-in-plan-release-files.js.map +1 -1
  127. package/src/generators/slice/built-in-plan-testing-files.js +92 -5
  128. package/src/generators/slice/built-in-plan-testing-files.js.map +1 -1
  129. package/src/generators/slice/built-in-plan-web-files.js +13 -0
  130. package/src/generators/slice/built-in-plan-web-files.js.map +1 -1
  131. package/src/generators/slice/built-in-plan-workload-role-files.js +5 -2
  132. package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -1
  133. package/src/generators/slice/built-in-plan.d.ts +2 -1
  134. package/src/generators/slice/built-in-plan.js +8 -5
  135. package/src/generators/slice/built-in-plan.js.map +1 -1
  136. package/src/generators/slice/slice.js +11 -3
  137. package/src/generators/slice/slice.js.map +1 -1
  138. package/src/generators/upgrade/upgrade.js +35 -0
  139. package/src/generators/upgrade/upgrade.js.map +1 -1
  140. package/src/generators/workload/frozen-container.d.ts +3 -2
  141. package/src/generators/workload/frozen-container.js +6 -4
  142. package/src/generators/workload/frozen-container.js.map +1 -1
  143. package/src/generators/workload/workload.js +2 -2
  144. package/src/generators/workload/workload.js.map +1 -1
  145. package/src/git-policy/github-bootstrap.d.ts +3 -1
  146. package/src/git-policy/github-bootstrap.js +22 -5
  147. package/src/git-policy/github-bootstrap.js.map +1 -1
  148. package/src/git-policy/routing.d.ts +2 -0
  149. package/src/git-policy/routing.js +12 -1
  150. package/src/git-policy/routing.js.map +1 -1
  151. package/src/infrastructure-change/local-capability.d.ts +73 -0
  152. package/src/infrastructure-change/local-capability.js +114 -0
  153. package/src/infrastructure-change/local-capability.js.map +1 -0
  154. package/src/infrastructure-change/model.d.ts +25 -4
  155. package/src/infrastructure-change/model.js +1 -0
  156. package/src/infrastructure-change/model.js.map +1 -1
  157. package/src/infrastructure-change/normalize.d.ts +4 -0
  158. package/src/infrastructure-change/normalize.js +47 -7
  159. package/src/infrastructure-change/normalize.js.map +1 -1
  160. package/src/infrastructure-change/plan.d.ts +30 -3
  161. package/src/infrastructure-change/plan.js +323 -13
  162. package/src/infrastructure-change/plan.js.map +1 -1
  163. package/src/infrastructure-change/risk.d.ts +3 -1
  164. package/src/infrastructure-change/risk.js +96 -16
  165. package/src/infrastructure-change/risk.js.map +1 -1
  166. package/src/local-dev/environment-inspector.d.ts +1 -0
  167. package/src/local-dev/environment-inspector.js +21 -9
  168. package/src/local-dev/environment-inspector.js.map +1 -1
  169. package/src/local-dev/private-state.d.ts +2 -0
  170. package/src/local-dev/private-state.js +3 -1
  171. package/src/local-dev/private-state.js.map +1 -1
  172. package/src/performance/cost-controls.d.ts +5 -3
  173. package/src/performance/cost-controls.js +30 -24
  174. package/src/performance/cost-controls.js.map +1 -1
  175. package/src/performance/model.d.ts +1 -1
  176. package/src/performance/model.js +0 -2
  177. package/src/performance/model.js.map +1 -1
  178. package/src/performance/test-fixtures.js +0 -2
  179. package/src/performance/test-fixtures.js.map +1 -1
  180. package/src/release/source-authority.d.ts +1 -0
  181. package/src/release/source-authority.js +136 -9
  182. package/src/release/source-authority.js.map +1 -1
  183. package/src/repository-policy/deployment-plan.d.ts +4 -1
  184. package/src/repository-policy/deployment-plan.js +8 -0
  185. package/src/repository-policy/deployment-plan.js.map +1 -1
  186. package/src/repository-policy/foundation-profile.js +1 -2
  187. package/src/repository-policy/foundation-profile.js.map +1 -1
  188. package/src/repository-policy/policy.d.ts +25 -1
  189. package/src/repository-policy/policy.js +145 -4
  190. package/src/repository-policy/policy.js.map +1 -1
  191. package/src/schemas/performance-policy-v1.json +0 -2
  192. package/src/schemas/repository-policy-v1.json +41 -0
  193. package/src/secrets/operator.js +22 -4
  194. package/src/secrets/operator.js.map +1 -1
  195. package/src/secrets/verification.js +9 -1
  196. package/src/secrets/verification.js.map +1 -1
  197. package/src/sst-environment-source-format.d.ts +3 -0
  198. package/src/sst-environment-source-format.js +179 -0
  199. package/src/sst-environment-source-format.js.map +1 -0
  200. package/src/supply-chain/blueprint-trust-git.js +72 -21
  201. package/src/supply-chain/blueprint-trust-git.js.map +1 -1
  202. package/src/supply-chain/blueprint-verification-authority.js +55 -3
  203. package/src/supply-chain/blueprint-verification-authority.js.map +1 -1
  204. package/src/supply-chain/blueprint-verification-execution.js +17 -2
  205. package/src/supply-chain/blueprint-verification-execution.js.map +1 -1
  206. package/src/supply-chain/build-output.d.ts +7 -1
  207. package/src/supply-chain/build-output.js +160 -20
  208. package/src/supply-chain/build-output.js.map +1 -1
  209. package/src/supply-chain/generated-command.js +131 -43
  210. package/src/supply-chain/generated-command.js.map +1 -1
  211. package/src/supply-chain/generated-container-release-command.js +187 -38
  212. package/src/supply-chain/generated-container-release-command.js.map +1 -1
  213. package/src/supply-chain/generated-ecr-collector-command.js +12 -2
  214. package/src/supply-chain/generated-ecr-collector-command.js.map +1 -1
  215. package/src/supply-chain/generated-scanner-command.js +114 -54
  216. package/src/supply-chain/generated-scanner-command.js.map +1 -1
  217. package/src/supply-chain/inventory.d.ts +17 -0
  218. package/src/supply-chain/inventory.js +114 -3
  219. package/src/supply-chain/inventory.js.map +1 -1
  220. package/src/supply-chain/pnpm-toolchain-authority.d.ts +4 -3
  221. package/src/supply-chain/pnpm-toolchain-authority.js +20 -34
  222. package/src/supply-chain/pnpm-toolchain-authority.js.map +1 -1
  223. package/src/supply-chain/policy.js +4 -1
  224. package/src/supply-chain/policy.js.map +1 -1
  225. package/src/supply-chain/sbom.d.ts +1 -1
  226. package/src/supply-chain/sbom.js +30 -5
  227. package/src/supply-chain/sbom.js.map +1 -1
  228. package/src/supply-chain/scanner.js +10 -1
  229. package/src/supply-chain/scanner.js.map +1 -1
  230. package/src/workload-roles/account-baseline.d.ts +11 -0
  231. package/src/workload-roles/account-baseline.js +253 -16
  232. package/src/workload-roles/account-baseline.js.map +1 -1
  233. package/src/workload-roles/authority.d.ts +3 -1
  234. package/src/workload-roles/authority.js +48 -2
  235. package/src/workload-roles/authority.js.map +1 -1
  236. package/src/workload-roles/aws-s3-state.js +27 -0
  237. package/src/workload-roles/aws-s3-state.js.map +1 -1
  238. package/src/workload-roles/boundary.d.ts +2 -1
  239. package/src/workload-roles/boundary.js +9 -2
  240. package/src/workload-roles/boundary.js.map +1 -1
  241. package/src/workload-roles/handler.js +52 -24
  242. package/src/workload-roles/handler.js.map +1 -1
  243. package/src/workload-roles/injection.js +1 -1
  244. package/src/workload-roles/injection.js.map +1 -1
  245. package/src/workload-roles/provisioner.js +12 -4
  246. package/src/workload-roles/provisioner.js.map +1 -1
  247. package/src/workload-roles/registration.d.ts +1 -0
  248. package/src/workload-roles/registration.js +5 -0
  249. package/src/workload-roles/registration.js.map +1 -1
  250. package/src/workload-roles/stage-boundary.js +1 -1
  251. package/src/workload-roles/stage-boundary.js.map +1 -1
  252. package/src/workload-roles/standard-slice.js +1 -0
  253. package/src/workload-roles/standard-slice.js.map +1 -1
@@ -47,11 +47,11 @@ function renderProductInfrastructureSafetyFiles(name) {
47
47
  authoritativeRefreshForbiddenForDetection: true,
48
48
  previewEnvironment: {
49
49
  PULUMI_OPTION_REFRESH: 'true',
50
- PULUMI_OPTION_RUN_PROGRAM: 'true',
50
+ PULUMI_OPTION_RUN_PROGRAM: 'false',
51
51
  },
52
52
  },
53
53
  planner: {
54
- command: 'sst diff --json plus same-command read-only refresh preview',
54
+ command: 'sst diff --json plus same-command separated refresh preview',
55
55
  executor: '@empire-builder-kit/nx:infrastructure-plan',
56
56
  scope: 'product-slice',
57
57
  sourceBoundary: 'desired-source-versus-recorded-sst-state',
@@ -60,16 +60,62 @@ function renderProductInfrastructureSafetyFiles(name) {
60
60
  version: '4.17.1',
61
61
  },
62
62
  policy: {
63
+ adoptedImports: [],
63
64
  additiveLowRiskTypes: [
64
65
  'aws:cloudwatch/dashboard:Dashboard',
66
+ 'aws:cloudwatch/logDataProtectionPolicy:LogDataProtectionPolicy',
65
67
  'aws:cloudwatch/logGroup:LogGroup',
66
68
  'aws:cloudwatch/metricAlarm:MetricAlarm',
67
69
  'random:index/randomPassword:RandomPassword',
68
70
  ],
71
+ additiveReviewedTypes: [
72
+ 'aws:appconfig/application:Application',
73
+ 'aws:appconfig/configurationProfile:ConfigurationProfile',
74
+ 'aws:appconfig/deploymentStrategy:DeploymentStrategy',
75
+ 'aws:appconfig/environment:Environment',
76
+ 'aws:cloudwatch/eventRule:EventRule',
77
+ 'aws:cloudwatch/eventTarget:EventTarget',
78
+ 'aws:ecs/taskDefinition:TaskDefinition',
79
+ 'aws:lambda/functionEventInvokeConfig:FunctionEventInvokeConfig',
80
+ 'aws:lambda/permission:Permission',
81
+ 'aws:s3/bucketCorsConfiguration:BucketCorsConfiguration',
82
+ 'aws:s3/bucketLifecycleConfigurationV2:BucketLifecycleConfigurationV2',
83
+ 'aws:s3/bucketOwnershipControls:BucketOwnershipControls',
84
+ 'aws:s3/bucketObjectv2:BucketObjectv2',
85
+ 'aws:s3/bucketPolicy:BucketPolicy',
86
+ 'aws:s3/bucketPublicAccessBlock:BucketPublicAccessBlock',
87
+ 'aws:s3/bucketServerSideEncryptionConfigurationV2:BucketServerSideEncryptionConfigurationV2',
88
+ 'aws:s3/bucketVersioningV2:BucketVersioningV2',
89
+ 'aws:sqs/queuePolicy:QueuePolicy',
90
+ 'pulumi-nodejs:dynamic:Resource',
91
+ 'pulumi:providers:aws',
92
+ 'pulumi:providers:pulumi-nodejs',
93
+ 'pulumi:providers:random',
94
+ 'pulumi:pulumi:Stack',
95
+ 'sst:aws:ApiGatewayV2',
96
+ 'sst:aws:ApiGatewayV2LambdaRoute',
97
+ 'sst:aws:Bucket',
98
+ 'sst:aws:Bus',
99
+ 'sst:aws:BusQueueSubscriber',
100
+ 'sst:aws:CDN',
101
+ 'sst:aws:Cluster',
102
+ 'sst:aws:CognitoUserPool',
103
+ 'sst:aws:CognitoUserPoolClient',
104
+ 'sst:aws:Function',
105
+ 'sst:aws:Nextjs',
106
+ 'sst:aws:Queue',
107
+ 'sst:aws:Router',
108
+ 'sst:aws:Task',
109
+ 'sst:aws:Vpc',
110
+ 'sst:sst:LinkRef',
111
+ 'sst:sst:Linkable',
112
+ 'sst:sst:Version',
113
+ ],
69
114
  costOrQuotaTypes: [
70
115
  'aws:apigatewayv2/api:Api',
71
116
  'aws:apigatewayv2/integration:Integration',
72
117
  'aws:apigatewayv2/route:Route',
118
+ 'aws:apigatewayv2/stage:Stage',
73
119
  'aws:apigatewayv2/vpcLink:VpcLink',
74
120
  'aws:appconfig/deployment:Deployment',
75
121
  'aws:budgets/budget:Budget',
@@ -77,12 +123,11 @@ function renderProductInfrastructureSafetyFiles(name) {
77
123
  'aws:cloudfront/distribution:Distribution',
78
124
  'aws:cloudfront/function:Function',
79
125
  'aws:cloudfront/keyValueStore:KeyValueStore',
80
- 'aws:costexplorer/anomalyMonitor:AnomalyMonitor',
81
- 'aws:costexplorer/anomalySubscription:AnomalySubscription',
82
126
  'aws:dynamodb/table:Table',
83
127
  'aws:ecs/service:Service',
84
128
  'aws:lambda/function:Function',
85
129
  'aws:rds/cluster:Cluster',
130
+ 'aws:sfn/stateMachine:StateMachine',
86
131
  ],
87
132
  failClosedOnUnknown: true,
88
133
  iamAccessAnalyzer: 'in-process-validate-policy-for-proposed-policy-documents',
@@ -93,12 +138,18 @@ function renderProductInfrastructureSafetyFiles(name) {
93
138
  redactBeforeReview: true,
94
139
  standingPolicyRiskClasses: ['no-change', 'additive-low-risk'],
95
140
  statefulTypes: [
141
+ 'aws:appconfig/hostedConfigurationVersion:HostedConfigurationVersion',
142
+ 'aws:cloudformation/stack:Stack',
143
+ 'aws:cognito/userPoolClient:UserPoolClient',
96
144
  'aws:dynamodb/table:Table',
145
+ 'aws:kms/alias:Alias',
97
146
  'aws:kms/key:Key',
98
147
  'aws:rds/cluster:Cluster',
99
148
  'aws:s3/bucket:Bucket',
149
+ 'aws:secretsmanager/secret:Secret',
100
150
  'aws:sqs/queue:Queue',
101
151
  'aws:ssm/parameter:Parameter',
152
+ 'random:index/randomBytes:RandomBytes',
102
153
  'random:index/randomPassword:RandomPassword',
103
154
  ],
104
155
  },
@@ -246,9 +297,11 @@ if (
246
297
  \`pnpm nx run <slice>:infrastructure-plan --stage=<protected-stage>\` runs the
247
298
  workspace-pinned SST 4.17.1 \`sst diff --json\` contract through the framework
248
299
  executor. It first compares desired source with SST's recorded engine state,
249
- then repeats the same preview with the pinned Pulumi read-only refresh and
250
- run-program options. Refresh-phase events are separated from desired operations
251
- in memory. Raw state, policy documents, provider values, and secret-adjacent
300
+ then repeats that non-writing diff with Pulumi's refresh option. The executor
301
+ separates provider refresh records from the subsequent desired-preview records,
302
+ validates both partitions, and uses only the refresh partition as drift
303
+ authority. The first ordinary preview remains the sole desired-update
304
+ authority. Raw state, policy documents, provider values, and secret-adjacent
252
305
  material are never written to review evidence.
253
306
 
254
307
  Unknown, destructive, stateful, security-expanding, protection-reducing, and
@@ -259,10 +312,13 @@ still independently revalidated before apply.
259
312
 
260
313
  Use only the bounded read-only preview for drift. Never invoke authoritative
261
314
  \`sst refresh\`, write state, unlock state, or mutate cloud resources to detect
262
- drift. A refresh preview is complete only when its desired phase materially
263
- equals the ordinary diff, its exact existing-resource inventory matches the
264
- full canonical state export, and all material properties have supported
265
- coverage. Generated non-secret String SSM parameter values are compared only in
315
+ drift. A refresh preview is complete only when desired-program execution
316
+ is disabled during the provider refresh subphase, refresh and desired events
317
+ remain structurally separable, its exact existing-resource inventory matches
318
+ the full canonical state export, and all material properties have supported
319
+ coverage. The preceding ordinary diff is the sole desired-update authority;
320
+ any ordinary preview failure or malformed post-refresh desired event fails
321
+ closed. Generated non-secret String SSM parameter values are compared only in
266
322
  memory; secret payloads remain unsupported and block.
267
323
 
268
324
  The generated contract is Slice-scoped and protected planning runs under the
@@ -1 +1 @@
1
- {"version":3,"file":"built-in-plan-infrastructure-safety-files.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/slice/built-in-plan-infrastructure-safety-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"built-in-plan-infrastructure-safety-files.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/slice/built-in-plan-infrastructure-safety-files.ts"],"names":[],"mappings":"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"}
@@ -202,6 +202,7 @@ declare global {
202
202
  ...values: unknown[]
203
203
  ) => unknown;
204
204
  const $jsonStringify: (value: unknown) => unknown;
205
+ const $output: (value: unknown) => any;
205
206
  const $transform: any;
206
207
  const $util: any;
207
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"built-in-plan-metadata-files.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/slice/built-in-plan-metadata-files.ts"],"names":[],"mappings":";;AAIA,4DAyNC;AA5ND,uEAAiD;AAEjD,gBAAgB;AAChB,SAAgB,wBAAwB,CACtC,IAAY,EACZ,KAAa,EACb,UAAkB,EAClB,SAAmC;IAEnC,OAAO;QACL,qBAAqB,EAAE,IAAA,8BAAI,EAAC,SAAS,CAAC;QACtC,WAAW,EAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;oBAyBN,IAAI;;;IAGpB,IAAI;;;;;gDAKwC,KAAK,IAAI,IAAI;;;;;;mBAM1C,IAAI;;;;;;;;;;;;;;gBAcP,IAAI;;;;;;wCAMoB,IAAI;;qBAEvB,IAAI;;;oCAGW,IAAI;;;;;;;;;;;;;;;;;;;;;;CAsBvC;QACG,oBAAoB,EAAE;IACtB,UAAU;IACV,UAAU;SACL,UAAU;SACV,UAAU;;;eAGJ,UAAU;CACxB;QACG,6BAA6B,EAAE,IAAA,8BAAI,EAAC;YAClC,QAAQ,EAAE,EAAE;YACZ,aAAa,EAAE,CAAC;SACjB,CAAC;QACF,sBAAsB,EAAE,KAAK,IAAI;;;;;;;;;;;;;CAapC;QACG,mBAAmB,EAAE,KAAK,IAAI;;;;;gBAKlB,IAAI;;;CAGnB;QACG,kBAAkB,EAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DhC;QACG,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;MAmBlB,UAAU;;;;;CAKf;KACE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"built-in-plan-metadata-files.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/slice/built-in-plan-metadata-files.ts"],"names":[],"mappings":";;AAIA,4DA0NC;AA7ND,uEAAiD;AAEjD,gBAAgB;AAChB,SAAgB,wBAAwB,CACtC,IAAY,EACZ,KAAa,EACb,UAAkB,EAClB,SAAmC;IAEnC,OAAO;QACL,qBAAqB,EAAE,IAAA,8BAAI,EAAC,SAAS,CAAC;QACtC,WAAW,EAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;oBAyBN,IAAI;;;IAGpB,IAAI;;;;;gDAKwC,KAAK,IAAI,IAAI;;;;;;mBAM1C,IAAI;;;;;;;;;;;;;;gBAcP,IAAI;;;;;;wCAMoB,IAAI;;qBAEvB,IAAI;;;oCAGW,IAAI;;;;;;;;;;;;;;;;;;;;;;CAsBvC;QACG,oBAAoB,EAAE;IACtB,UAAU;IACV,UAAU;SACL,UAAU;SACV,UAAU;;;eAGJ,UAAU;CACxB;QACG,6BAA6B,EAAE,IAAA,8BAAI,EAAC;YAClC,QAAQ,EAAE,EAAE;YACZ,aAAa,EAAE,CAAC;SACjB,CAAC;QACF,sBAAsB,EAAE,KAAK,IAAI;;;;;;;;;;;;;CAapC;QACG,mBAAmB,EAAE,KAAK,IAAI;;;;;gBAKlB,IAAI;;;CAGnB;QACG,kBAAkB,EAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DhC;QACG,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;MAoBlB,UAAU;;;;;CAKf;KACE,CAAC;AACJ,CAAC"}
@@ -7,6 +7,10 @@ const logging_registry_js_1 = require("../logging-registry.js");
7
7
  const built_in_plan_shared_js_1 = require("./built-in-plan-shared.js");
8
8
  /** @internal */
9
9
  function renderSliceOperationsFiles(name, workspace = 'workspace', frameworkVersion = 'workspace-installed') {
10
+ const pascalName = name
11
+ .split('-')
12
+ .map((segment) => segment[0]?.toUpperCase() + segment.slice(1))
13
+ .join('');
10
14
  return {
11
15
  'operations/features.json': (0, built_in_plan_shared_js_1.json)({
12
16
  features: [
@@ -532,7 +536,130 @@ process.stdout.write(
532
536
  'sst-env.d.ts': `// Bootstrap placeholder. SST overwrites this file after install, dev, or deploy.
533
537
  export {};
534
538
  `,
535
- 'sst.config.ts': `export default $config({
539
+ 'sst.config.ts': `const ebkNextBuildEnvironmentKeys = new Set([
540
+ 'AUTH_CLIENT_ID',
541
+ 'AUTH_USER_POOL_ID',
542
+ 'CI',
543
+ 'EBK_APPCONFIG_APPLICATION_ID',
544
+ 'EBK_APPCONFIG_ENVIRONMENT_ID',
545
+ 'EBK_APPCONFIG_PROFILE_ID',
546
+ 'EBK_FLEET_ORIGIN',
547
+ 'EBK_PERFORMANCE_ACCOUNT_FINGERPRINT',
548
+ 'EBK_PERFORMANCE_CANDIDATE_DIGEST',
549
+ 'EBK_PERFORMANCE_LOAD_ENABLED',
550
+ 'EBK_PERFORMANCE_ORIGIN',
551
+ 'EBK_PERFORMANCE_REGION',
552
+ 'EBK_PERFORMANCE_RELEASE_ID',
553
+ 'EBK_PERFORMANCE_RELEASE_MATERIAL_DIGEST',
554
+ 'EBK_PERFORMANCE_SLICE',
555
+ 'EBK_SECURE_COOKIES',
556
+ 'EBK_SOURCE_COMMIT',
557
+ 'EBK_STAGE',
558
+ 'EVENT_BUS_NAME',
559
+ 'NEXT_PUBLIC_API_URL',
560
+ 'NEXT_TELEMETRY_DISABLED',
561
+ 'SST',
562
+ 'SST_RESOURCE_App',
563
+ 'SST_RESOURCE_${pascalName}PrimaryDatabase',
564
+ 'SST_RESOURCE_FoundationIdentity',
565
+ ]);
566
+
567
+ const ebkRequiredNextBuildEnvironmentKeys = [
568
+ 'AUTH_CLIENT_ID',
569
+ 'AUTH_USER_POOL_ID',
570
+ 'CI',
571
+ 'EBK_FLEET_ORIGIN',
572
+ 'EBK_PERFORMANCE_ACCOUNT_FINGERPRINT',
573
+ 'EBK_PERFORMANCE_CANDIDATE_DIGEST',
574
+ 'EBK_PERFORMANCE_LOAD_ENABLED',
575
+ 'EBK_PERFORMANCE_ORIGIN',
576
+ 'EBK_PERFORMANCE_REGION',
577
+ 'EBK_PERFORMANCE_RELEASE_ID',
578
+ 'EBK_PERFORMANCE_RELEASE_MATERIAL_DIGEST',
579
+ 'EBK_PERFORMANCE_SLICE',
580
+ 'EBK_SECURE_COOKIES',
581
+ 'EBK_SOURCE_COMMIT',
582
+ 'EBK_STAGE',
583
+ 'EVENT_BUS_NAME',
584
+ 'NEXT_PUBLIC_API_URL',
585
+ 'NEXT_TELEMETRY_DISABLED',
586
+ 'SST',
587
+ 'SST_RESOURCE_App',
588
+ 'SST_RESOURCE_${pascalName}PrimaryDatabase',
589
+ 'SST_RESOURCE_FoundationIdentity',
590
+ ] as const;
591
+
592
+ const ebkLocalCommandResource = {
593
+ __pulumiType: 'command:local:Command',
594
+ } as unknown as new (
595
+ name: string,
596
+ args: { environment?: unknown; triggers?: unknown },
597
+ options?: unknown,
598
+ ) => unknown;
599
+
600
+ const ebkSourceCommitPattern = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
601
+
602
+ function exactNextBuildEnvironment(value: unknown): Record<string, string> {
603
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
604
+ throw new Error('The Next build environment must resolve to one object.');
605
+ }
606
+ const environment = value as Record<string, unknown>;
607
+ const retained = Object.fromEntries(
608
+ Object.entries(environment)
609
+ .filter(([key]) => ebkNextBuildEnvironmentKeys.has(key))
610
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
611
+ );
612
+ for (const key of ebkRequiredNextBuildEnvironmentKeys) {
613
+ if (typeof retained[key] !== 'string') {
614
+ throw new Error('The Next build environment omitted ' + key + '.');
615
+ }
616
+ }
617
+ return retained as Record<string, string>;
618
+ }
619
+
620
+ // SST 4.17.1 installs its transform globals only while evaluating $config.run.
621
+ // Register there, before infrastructure construction, rather than at module
622
+ // load. The explicit Slice buildCommand separately routes diff/refresh invokes
623
+ // through the wrapper.
624
+ function registerExactNextBuildEnvironmentTransform(): void {
625
+ $transform(
626
+ ebkLocalCommandResource,
627
+ (
628
+ args: { environment?: unknown; triggers?: unknown },
629
+ _options: unknown,
630
+ resourceName: string,
631
+ ) => {
632
+ if (resourceName !== '${pascalName}WebBuilder') return;
633
+ const unresolvedEnvironment = args.environment as Record<
634
+ string,
635
+ unknown
636
+ >;
637
+ const resolveEnvironment = (environment: Record<string, unknown>) =>
638
+ exactNextBuildEnvironment({
639
+ ...environment,
640
+ CI: 'true',
641
+ NEXT_TELEMETRY_DISABLED: '1',
642
+ });
643
+ args.environment = $output(unresolvedEnvironment).apply(
644
+ resolveEnvironment,
645
+ );
646
+ args.triggers = $output(unresolvedEnvironment).apply(
647
+ (environment: Record<string, unknown>) => {
648
+ const resolved = resolveEnvironment(environment);
649
+ const sourceCommit = resolved.EBK_SOURCE_COMMIT.trim();
650
+ if (!ebkSourceCommitPattern.test(sourceCommit)) {
651
+ throw new Error(
652
+ 'The Next builder requires one exact EBK source commit.',
653
+ );
654
+ }
655
+ return [sourceCommit];
656
+ },
657
+ );
658
+ },
659
+ );
660
+ }
661
+
662
+ export default $config({
536
663
  app(input: { stage?: string } | undefined) {
537
664
  const stage = input?.stage ?? 'development';
538
665
  const production = input?.stage === 'production';
@@ -544,16 +671,17 @@ export {};
544
671
  providers: {
545
672
  aws: {
546
673
  defaultTags: {
674
+ // SST contributes sst:app and sst:stage. Keep the provider baseline
675
+ // at eight tags so generated S3 asset objects remain within AWS's
676
+ // hard ten-tag object limit. Performance coverage requires this
677
+ // provider baseline; repository and production-profile identity is
678
+ // supplementary on resources using createStandardResourceTags.
547
679
  tags: {
548
680
  'ebk:cost-allocation': 'unallocated',
549
681
  'ebk:cost-scope': '${workspace}/${name}/' + stage,
550
682
  'ebk:framework-version': '${frameworkVersion}',
551
683
  'ebk:managed-by': 'empire-builder-kit',
552
684
  'ebk:owner': '${name}-product',
553
- 'ebk:production-profile':
554
- process.env.EBK_PRODUCTION_PROFILE ?? 'standard',
555
- 'ebk:repository':
556
- process.env.GITHUB_REPOSITORY ?? '${workspace}',
557
685
  'ebk:slice': '${name}',
558
686
  'ebk:stage': stage,
559
687
  'ebk:workspace': '${workspace}',
@@ -565,6 +693,7 @@ export {};
565
693
  };
566
694
  },
567
695
  async run() {
696
+ registerExactNextBuildEnvironmentTransform();
568
697
  const personalStagePattern = /^personal-[a-z0-9](?:[a-z0-9-]{0,34}[a-z0-9])?$/;
569
698
  if ($dev && !personalStagePattern.test($app.stage)) {
570
699
  throw new Error(
@@ -588,6 +717,314 @@ export {};
588
717
  return app(workloadRoles);
589
718
  },
590
719
  });
720
+ `,
721
+ 'tools/ebk-next-build-environment.mjs': `import { spawnSync } from 'node:child_process';
722
+ import {
723
+ chmodSync,
724
+ existsSync,
725
+ lstatSync,
726
+ readFileSync,
727
+ readdirSync,
728
+ realpathSync,
729
+ renameSync,
730
+ rmSync,
731
+ unlinkSync,
732
+ writeFileSync,
733
+ } from 'node:fs';
734
+ import { dirname, join, relative, resolve } from 'node:path';
735
+
736
+ // SST diff/refresh invokes the build outside the Command resource transform.
737
+ // Reconstruct the child environment here so every builder path has one policy.
738
+ const applicationKeys = new Set(${JSON.stringify([
739
+ 'AUTH_CLIENT_ID',
740
+ 'AUTH_USER_POOL_ID',
741
+ 'CI',
742
+ 'EBK_APPCONFIG_APPLICATION_ID',
743
+ 'EBK_APPCONFIG_ENVIRONMENT_ID',
744
+ 'EBK_APPCONFIG_PROFILE_ID',
745
+ 'EBK_FLEET_ORIGIN',
746
+ 'EBK_PERFORMANCE_ACCOUNT_FINGERPRINT',
747
+ 'EBK_PERFORMANCE_CANDIDATE_DIGEST',
748
+ 'EBK_PERFORMANCE_LOAD_ENABLED',
749
+ 'EBK_PERFORMANCE_ORIGIN',
750
+ 'EBK_PERFORMANCE_REGION',
751
+ 'EBK_PERFORMANCE_RELEASE_ID',
752
+ 'EBK_PERFORMANCE_RELEASE_MATERIAL_DIGEST',
753
+ 'EBK_PERFORMANCE_SLICE',
754
+ 'EBK_SECURE_COOKIES',
755
+ 'EBK_SOURCE_COMMIT',
756
+ 'EBK_STAGE',
757
+ 'EVENT_BUS_NAME',
758
+ 'NEXT_PUBLIC_API_URL',
759
+ 'NEXT_TELEMETRY_DISABLED',
760
+ 'SST',
761
+ 'SST_RESOURCE_App',
762
+ `SST_RESOURCE_${pascalName}PrimaryDatabase`,
763
+ 'SST_RESOURCE_FoundationIdentity',
764
+ ], null, 2)});
765
+ const operatingKeys = new Set(
766
+ [
767
+ 'APPDATA',
768
+ 'COMSPEC',
769
+ 'HOME',
770
+ 'LANG',
771
+ 'LC_ALL',
772
+ 'LOCALAPPDATA',
773
+ 'PATH',
774
+ 'PATHEXT',
775
+ 'PROGRAMDATA',
776
+ 'SHELL',
777
+ 'SYSTEMROOT',
778
+ 'TEMP',
779
+ 'TERM',
780
+ 'TMP',
781
+ 'TMPDIR',
782
+ 'TZ',
783
+ 'USERPROFILE',
784
+ ].map((key) => key.toLowerCase()),
785
+ );
786
+
787
+ if (process.argv.length !== 2) {
788
+ throw new Error('The Next build wrapper does not accept arguments.');
789
+ }
790
+
791
+ const root = realpathSync(process.cwd());
792
+ const openNextRoot = resolve(root, '.open-next');
793
+ const priorSealedFunctionBundles = [
794
+ resolve(root, '.open-next/image-optimization-function'),
795
+ resolve(root, '.open-next/server-functions/default'),
796
+ ];
797
+ if (process.platform === 'darwin') {
798
+ for (const priorBundle of priorSealedFunctionBundles) {
799
+ if (!existsSync(priorBundle)) continue;
800
+ if (realpathSync(priorBundle) !== priorBundle) {
801
+ throw new Error(
802
+ 'The prior sealed OpenNext Function bundle has an invalid identity.',
803
+ );
804
+ }
805
+ const pendingDirectories = [{ depth: 0, path: priorBundle }];
806
+ let observedDirectories = 0;
807
+ while (pendingDirectories.length > 0) {
808
+ const current = pendingDirectories.pop();
809
+ if (!current) break;
810
+ if (current.depth > 64) {
811
+ throw new Error(
812
+ 'The prior sealed OpenNext Function bundle exceeds its depth bound.',
813
+ );
814
+ }
815
+ observedDirectories += 1;
816
+ if (observedDirectories > 65_536) {
817
+ throw new Error(
818
+ 'The prior sealed OpenNext Function bundle exceeds its directory bound.',
819
+ );
820
+ }
821
+ const identity = lstatSync(current.path, { bigint: true });
822
+ if (!identity.isDirectory() || identity.isSymbolicLink()) {
823
+ throw new Error(
824
+ 'The prior sealed OpenNext Function directory changed identity.',
825
+ );
826
+ }
827
+ if ((identity.mode & 0o200n) === 0n) {
828
+ chmodSync(current.path, Number((identity.mode & 0o7_777n) | 0o200n));
829
+ }
830
+ for (const entry of readdirSync(current.path, {
831
+ withFileTypes: true,
832
+ }).sort((left, right) =>
833
+ left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
834
+ )) {
835
+ if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
836
+ const entryPath = join(current.path, entry.name);
837
+ const confined = relative(priorBundle, entryPath);
838
+ if (
839
+ confined === '..' ||
840
+ confined.startsWith('../') ||
841
+ resolve(priorBundle, confined) !== entryPath
842
+ ) {
843
+ throw new Error(
844
+ 'The prior sealed OpenNext Function directory escapes its root.',
845
+ );
846
+ }
847
+ pendingDirectories.push({ depth: current.depth + 1, path: entryPath });
848
+ }
849
+ }
850
+ }
851
+ if (existsSync(openNextRoot)) {
852
+ const identity = lstatSync(openNextRoot, { bigint: true });
853
+ if (
854
+ !identity.isDirectory() ||
855
+ identity.isSymbolicLink() ||
856
+ realpathSync(openNextRoot) !== openNextRoot
857
+ ) {
858
+ throw new Error('The prior OpenNext build root has an invalid identity.');
859
+ }
860
+ rmSync(openNextRoot, {
861
+ force: true,
862
+ maxRetries: 8,
863
+ recursive: true,
864
+ retryDelay: 50,
865
+ });
866
+ if (existsSync(openNextRoot)) {
867
+ throw new Error('The prior OpenNext build root was not removed.');
868
+ }
869
+ }
870
+ }
871
+
872
+ const environment = Object.fromEntries(
873
+ Object.entries(process.env)
874
+ .filter(
875
+ ([key, value]) =>
876
+ typeof value === 'string' &&
877
+ (applicationKeys.has(key) || operatingKeys.has(key.toLowerCase())),
878
+ )
879
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
880
+ );
881
+ const windows = process.platform === 'win32';
882
+ const result = spawnSync(
883
+ windows ? 'cmd.exe' : 'npx',
884
+ windows
885
+ ? ['/d', '/s', '/c', 'npx --yes @opennextjs/aws@3.9.14 build']
886
+ : ['--yes', '@opennextjs/aws@3.9.14', 'build'],
887
+ {
888
+ cwd: process.cwd(),
889
+ env: environment,
890
+ stdio: 'inherit',
891
+ windowsHide: true,
892
+ },
893
+ );
894
+ if (result.error) throw result.error;
895
+ if (result.signal) {
896
+ throw new Error('The Next build command exited from signal ' + result.signal + '.');
897
+ }
898
+ if (result.status !== 0) {
899
+ process.exitCode = result.status ?? 1;
900
+ } else {
901
+ // Finder can create .DS_Store files anywhere below OpenNext's assembled
902
+ // output while the macOS build is running. They have no runtime meaning,
903
+ // but SST includes them in Lambda archives, so their presence makes one
904
+ // immutable source alternate between different code object hashes. Remove
905
+ // only this exact derived metadata before SST archives the output.
906
+ if (realpathSync(openNextRoot) !== openNextRoot) {
907
+ throw new Error('The OpenNext build root has an invalid identity.');
908
+ }
909
+ const pendingDirectories = [{ depth: 0, path: openNextRoot }];
910
+ let observedEntries = 0;
911
+ let removedFinderMetadata = 0;
912
+ while (pendingDirectories.length > 0) {
913
+ const current = pendingDirectories.pop();
914
+ if (!current) break;
915
+ if (current.depth > 64) {
916
+ throw new Error('The OpenNext build tree exceeds its depth bound.');
917
+ }
918
+ for (const entry of readdirSync(current.path, { withFileTypes: true }).sort(
919
+ (left, right) =>
920
+ left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
921
+ )) {
922
+ observedEntries += 1;
923
+ if (observedEntries > 65_536) {
924
+ throw new Error('The OpenNext build tree exceeds its entry bound.');
925
+ }
926
+ const entryPath = join(current.path, entry.name);
927
+ const identity = lstatSync(entryPath, { bigint: true });
928
+ if (entry.name === '.DS_Store') {
929
+ removedFinderMetadata += 1;
930
+ if (
931
+ removedFinderMetadata > 256 ||
932
+ !identity.isFile() ||
933
+ identity.isSymbolicLink() ||
934
+ identity.nlink !== 1n ||
935
+ identity.size > 1_048_576n
936
+ ) {
937
+ throw new Error('The OpenNext Finder metadata has an invalid identity.');
938
+ }
939
+ unlinkSync(entryPath);
940
+ if (existsSync(entryPath)) {
941
+ throw new Error('The OpenNext Finder metadata was not removed.');
942
+ }
943
+ continue;
944
+ }
945
+ if (identity.isDirectory() && !identity.isSymbolicLink()) {
946
+ const confined = relative(openNextRoot, entryPath);
947
+ if (
948
+ confined === '..' ||
949
+ confined.startsWith('../') ||
950
+ resolve(openNextRoot, confined) !== entryPath
951
+ ) {
952
+ throw new Error('The OpenNext build entry escapes its root.');
953
+ }
954
+ pendingDirectories.push({ depth: current.depth + 1, path: entryPath });
955
+ }
956
+ }
957
+ }
958
+
959
+ // OpenNext 3.9.14 installs the image optimizer dependencies in an npm
960
+ // mkdtemp directory and copies npm's hidden package lock into the deployed
961
+ // bundle. npm records that random directory basename as the lock name. The
962
+ // name has no runtime meaning, but without this exact normalization two
963
+ // builds of one source produce different Lambda ZIP bytes.
964
+ const lockPath = resolve(
965
+ process.cwd(),
966
+ '.open-next/image-optimization-function/node_modules/.package-lock.json',
967
+ );
968
+ const lockParent = realpathSync(dirname(lockPath));
969
+ const confinedParent = relative(root, lockParent);
970
+ if (
971
+ confinedParent === '..' ||
972
+ confinedParent.startsWith('../') ||
973
+ resolve(lockParent, '.package-lock.json') !== lockPath
974
+ ) {
975
+ throw new Error('The OpenNext image optimizer package lock escapes the build root.');
976
+ }
977
+ const before = lstatSync(lockPath, { bigint: true });
978
+ if (
979
+ !before.isFile() ||
980
+ before.isSymbolicLink() ||
981
+ before.nlink !== 1n ||
982
+ before.size < 2n ||
983
+ before.size > 131_072n
984
+ ) {
985
+ throw new Error('The OpenNext image optimizer package lock has an invalid identity.');
986
+ }
987
+ const raw = readFileSync(lockPath, 'utf8');
988
+ if (Buffer.byteLength(raw, 'utf8') !== Number(before.size)) {
989
+ throw new Error('The OpenNext image optimizer package lock changed while reading.');
990
+ }
991
+ const parsed = JSON.parse(raw);
992
+ if (
993
+ parsed === null ||
994
+ typeof parsed !== 'object' ||
995
+ Array.isArray(parsed) ||
996
+ !/^open-next-install-image-optimization-function[A-Za-z0-9]{6}$/u.test(
997
+ parsed.name,
998
+ ) ||
999
+ parsed.lockfileVersion !== 3 ||
1000
+ parsed.requires !== true ||
1001
+ parsed.packages === null ||
1002
+ typeof parsed.packages !== 'object' ||
1003
+ Array.isArray(parsed.packages)
1004
+ ) {
1005
+ throw new Error('The OpenNext image optimizer package lock shape is unsupported.');
1006
+ }
1007
+ parsed.name = 'open-next-image-optimization-function';
1008
+ const normalized = JSON.stringify(parsed, null, 2) + '\\n';
1009
+ const temporaryPath = join(lockParent, '.package-lock.json.ebk-normalized');
1010
+ writeFileSync(temporaryPath, normalized, {
1011
+ encoding: 'utf8',
1012
+ flag: 'wx',
1013
+ mode: Number(before.mode & 0o777n),
1014
+ });
1015
+ chmodSync(temporaryPath, Number(before.mode & 0o777n));
1016
+ renameSync(temporaryPath, lockPath);
1017
+ const after = lstatSync(lockPath, { bigint: true });
1018
+ if (
1019
+ !after.isFile() ||
1020
+ after.isSymbolicLink() ||
1021
+ after.nlink !== 1n ||
1022
+ after.mode !== before.mode ||
1023
+ readFileSync(lockPath, 'utf8') !== normalized
1024
+ ) {
1025
+ throw new Error('The normalized OpenNext image optimizer package lock is invalid.');
1026
+ }
1027
+ }
591
1028
  `,
592
1029
  'tsconfig.json': (0, built_in_plan_shared_js_1.json)({
593
1030
  extends: '../../tsconfig.base.json',