@empire-builder-kit/nx 1.0.0-rc.32 → 1.0.0-rc.34

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 (111) hide show
  1. package/package.json +3 -3
  2. package/src/aws-authority/stage-authority.js +4 -0
  3. package/src/aws-authority/stage-authority.js.map +1 -1
  4. package/src/developer-agent/model.d.ts +1 -1
  5. package/src/developer-agent/operation-registry.js +25 -3
  6. package/src/developer-agent/operation-registry.js.map +1 -1
  7. package/src/developer-agent/planning.js +9 -4
  8. package/src/developer-agent/planning.js.map +1 -1
  9. package/src/developer-agent/validation.js +5 -1
  10. package/src/developer-agent/validation.js.map +1 -1
  11. package/src/executors/deployment-plan/deployment-plan.js +3 -0
  12. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  13. package/src/executors/foundation-profile-preflight/production-database-safeguard.d.ts +1 -0
  14. package/src/executors/foundation-profile-preflight/production-database-safeguard.js +4 -2
  15. package/src/executors/foundation-profile-preflight/production-database-safeguard.js.map +1 -1
  16. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  17. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  18. package/src/executors/local-deploy/local-deploy.d.ts +21 -3
  19. package/src/executors/local-deploy/local-deploy.js +201 -1
  20. package/src/executors/local-deploy/local-deploy.js.map +1 -1
  21. package/src/executors/local-deploy/schema.json +21 -0
  22. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +13 -0
  23. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +323 -137
  24. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +1 -1
  25. package/src/executors/router-waf-rehearsal/schema.json +5 -0
  26. package/src/executors/secret-initialize/secret-initialize.d.ts +2 -0
  27. package/src/executors/secret-initialize/secret-initialize.js +57 -3
  28. package/src/executors/secret-initialize/secret-initialize.js.map +1 -1
  29. package/src/executors/sst-lifecycle/run-sst-command.d.ts +2 -0
  30. package/src/executors/sst-lifecycle/run-sst-command.js +4 -0
  31. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  32. package/src/foundation/index.d.ts +1 -0
  33. package/src/foundation/index.js +8 -0
  34. package/src/foundation/index.js.map +1 -1
  35. package/src/foundation/private-smoke-access.d.ts +23 -0
  36. package/src/foundation/private-smoke-access.js +127 -0
  37. package/src/foundation/private-smoke-access.js.map +1 -0
  38. package/src/foundation/private-smoke-admission.d.ts +43 -0
  39. package/src/foundation/private-smoke-admission.js +158 -0
  40. package/src/foundation/private-smoke-admission.js.map +1 -0
  41. package/src/foundation/private-smoke-control-plane.d.ts +18 -0
  42. package/src/foundation/private-smoke-control-plane.js +173 -0
  43. package/src/foundation/private-smoke-control-plane.js.map +1 -0
  44. package/src/generators/preset/dependency-overrides.d.ts +8 -0
  45. package/src/generators/preset/dependency-overrides.js +55 -0
  46. package/src/generators/preset/dependency-overrides.js.map +1 -0
  47. package/src/generators/preset/tool-versions.d.ts +2 -0
  48. package/src/generators/preset/tool-versions.js +3 -1
  49. package/src/generators/preset/tool-versions.js.map +1 -1
  50. package/src/generators/preset/workspace-files-developer-agent.js +19 -6
  51. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -1
  52. package/src/generators/preset/workspace-files-thin-deploy.d.ts +16 -1
  53. package/src/generators/preset/workspace-files-thin-deploy.js +946 -26
  54. package/src/generators/preset/workspace-files-thin-deploy.js.map +1 -1
  55. package/src/generators/preset/workspace-files-thin-docs.d.ts +2 -0
  56. package/src/generators/preset/workspace-files-thin-docs.js +66 -6
  57. package/src/generators/preset/workspace-files-thin-docs.js.map +1 -1
  58. package/src/generators/preset/workspace-files.d.ts +8 -1
  59. package/src/generators/preset/workspace-files.js +97 -21
  60. package/src/generators/preset/workspace-files.js.map +1 -1
  61. package/src/generators/repository-policy/repository-policy.js +1 -0
  62. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  63. package/src/generators/repository-policy/schema.d.ts +2 -0
  64. package/src/generators/repository-policy/schema.json +27 -7
  65. package/src/generators/slice/built-in-plan-background-work-files.d.ts +2 -0
  66. package/src/generators/slice/built-in-plan-background-work-files.js +89 -0
  67. package/src/generators/slice/built-in-plan-background-work-files.js.map +1 -0
  68. package/src/generators/slice/built-in-plan-database-lifecycle-files.js +20 -4
  69. package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +1 -1
  70. package/src/generators/slice/built-in-plan-infrastructure-files.js +22 -9
  71. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -1
  72. package/src/generators/slice/built-in-plan-operations-files.js +8 -10
  73. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -1
  74. package/src/generators/slice/built-in-plan.js +3 -0
  75. package/src/generators/slice/built-in-plan.js.map +1 -1
  76. package/src/generators/upgrade/upgrade.d.ts +12 -0
  77. package/src/generators/upgrade/upgrade.js +84 -9
  78. package/src/generators/upgrade/upgrade.js.map +1 -1
  79. package/src/generators/workload/workload.js +1 -1
  80. package/src/git-policy/action-pins.d.ts +5 -0
  81. package/src/git-policy/action-pins.js +5 -0
  82. package/src/git-policy/action-pins.js.map +1 -1
  83. package/src/git-policy/github-bootstrap.d.ts +10 -2
  84. package/src/git-policy/github-bootstrap.js +129 -34
  85. package/src/git-policy/github-bootstrap.js.map +1 -1
  86. package/src/git-policy/routing.d.ts +5 -1
  87. package/src/git-policy/routing.js +50 -0
  88. package/src/git-policy/routing.js.map +1 -1
  89. package/src/performance/model.d.ts +1 -1
  90. package/src/repository-policy/capacity-migration.d.ts +3 -0
  91. package/src/repository-policy/capacity-migration.js +21 -0
  92. package/src/repository-policy/capacity-migration.js.map +1 -0
  93. package/src/repository-policy/foundation-profile.js +10 -0
  94. package/src/repository-policy/foundation-profile.js.map +1 -1
  95. package/src/repository-policy/policy.d.ts +13 -2
  96. package/src/repository-policy/policy.js +47 -2
  97. package/src/repository-policy/policy.js.map +1 -1
  98. package/src/schemas/repository-policy-v1.json +56 -17
  99. package/src/supply-chain/generated-container-release-command.js +281 -74
  100. package/src/supply-chain/generated-container-release-command.js.map +1 -1
  101. package/src/supply-chain/generated-files.js +21 -11
  102. package/src/supply-chain/generated-files.js.map +1 -1
  103. package/src/supply-chain/generated-scanner-command.js +1 -1
  104. package/src/supply-chain/scanner.js +3 -0
  105. package/src/supply-chain/scanner.js.map +1 -1
  106. package/src/workspace-deployment/affected-lifecycle.d.ts +53 -0
  107. package/src/workspace-deployment/affected-lifecycle.js +84 -0
  108. package/src/workspace-deployment/affected-lifecycle.js.map +1 -0
  109. package/src/workspace-deployment/index.d.ts +1 -0
  110. package/src/workspace-deployment/index.js +1 -0
  111. package/src/workspace-deployment/index.js.map +1 -1
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runGithubPrivateSmoke = runGithubPrivateSmoke;
4
+ exports.cleanupGithubPrivateSmoke = cleanupGithubPrivateSmoke;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const router_waf_js_1 = require("./router-waf.js");
8
+ const private_smoke_control_plane_js_1 = require("./private-smoke-control-plane.js");
9
+ const private_smoke_admission_js_1 = require("./private-smoke-admission.js");
10
+ function check(condition, message) {
11
+ if (!condition)
12
+ throw new Error(`Private smoke access: ${message}`);
13
+ }
14
+ /** Called only inside the source/role-verified protected stage lifecycle. */
15
+ async function runGithubPrivateSmoke(input, dependencies = {}) {
16
+ return privateSmokeOperation(input, dependencies, false);
17
+ }
18
+ /** Generated protected workflow finalizer. It can only remove an exact admission. */
19
+ async function cleanupGithubPrivateSmoke(input, dependencies = {}) {
20
+ return privateSmokeOperation({ ...input, url: '', run: async () => undefined }, dependencies, true);
21
+ }
22
+ async function privateSmokeOperation(input, dependencies, cleanupOnly) {
23
+ const environment = dependencies.environment ?? process.env;
24
+ const request = dependencies.fetch ?? fetch;
25
+ const policy = (0, router_waf_js_1.normalizeRouterWafPolicy)(JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(input.root, 'packages/foundation/security/router-waf.json'), 'utf8')));
26
+ check(policy.deploymentProfile === input.deploymentProfile, 'WAF deployment profile differs from repository policy');
27
+ const stagePolicy = policy.stages[input.stage];
28
+ check(stagePolicy, 'inactive WAF stage');
29
+ if (stagePolicy.access === 'public' || stagePolicy.mode === 'count') {
30
+ await input.run();
31
+ return;
32
+ }
33
+ const baseline = stagePolicy.allowedCidrs.filter((cidr) => !cidr.includes(':'));
34
+ check(baseline.length > 0, 'private hosted smoke requires a committed IPv4 baseline');
35
+ const repository = environment.GITHUB_REPOSITORY ?? '';
36
+ const ref = `refs/heads/${input.stage === 'production' ? 'main' : 'develop'}`;
37
+ const workflow = `${repository}/.github/workflows/deploy.yml@${ref}`;
38
+ check(environment.GITHUB_ACTIONS === 'true' &&
39
+ /^[\w.-]+\/[\w.-]+$/.test(repository) &&
40
+ environment.GITHUB_REF === ref &&
41
+ environment.GITHUB_SHA === input.source &&
42
+ environment.EBK_GITHUB_JOB_WORKFLOW_REF === workflow &&
43
+ ((environment.GITHUB_EVENT_NAME === 'workflow_dispatch' &&
44
+ environment.GITHUB_WORKFLOW_REF === workflow) ||
45
+ (environment.GITHUB_EVENT_NAME === 'push' &&
46
+ input.deploymentProfile !== 'starter' &&
47
+ environment.GITHUB_WORKFLOW_REF ===
48
+ `${repository}/.github/workflows/ci.yml@${ref}`)), 'exact protected deployment workflow/source required');
49
+ const run = environment.GITHUB_RUN_ID ?? '';
50
+ const attempt = environment.GITHUB_RUN_ATTEMPT ?? '';
51
+ check(/^[1-9]\d*$/.test(run) &&
52
+ /^[1-9]\d*$/.test(attempt) &&
53
+ /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(input.source), 'invalid protected invocation identity');
54
+ const store = await (dependencies.open ?? private_smoke_control_plane_js_1.openPrivateSmokeControlPlane)({
55
+ account: input.account,
56
+ stage: input.stage,
57
+ workspace: input.workspace,
58
+ policyDigest: (0, router_waf_js_1.routerWafPolicyDigest)(policy),
59
+ }, cleanupOnly ? undefined : input.url);
60
+ await (0, private_smoke_admission_js_1.recoverSmokeAdmission)(store, baseline, async (lease) => {
61
+ // An old attempt of this run can be recovered only after GitHub confirms it ended.
62
+ if (lease.run === run && lease.attempt === attempt)
63
+ return cleanupOnly && lease.source === input.source;
64
+ const token = environment.GITHUB_TOKEN;
65
+ check(token, 'stale admission requires actions:read to confirm the exact prior run completed');
66
+ const response = await request(`https://api.github.com/repos/${repository}/actions/runs/${lease.run}/attempts/${lease.attempt}`, {
67
+ headers: {
68
+ Authorization: `Bearer ${token}`,
69
+ Accept: 'application/vnd.github+json',
70
+ },
71
+ redirect: 'error',
72
+ signal: AbortSignal.timeout(15_000),
73
+ });
74
+ check(response.ok, 'prior workflow status unavailable; admission retained for protected recovery');
75
+ const prior = (await response.json());
76
+ const headRepository = prior.head_repository;
77
+ return (String(prior.id) === lease.run &&
78
+ String(prior.run_attempt) === lease.attempt &&
79
+ prior.status === 'completed' &&
80
+ prior.head_sha === lease.source &&
81
+ prior.head_branch === ref.slice('refs/heads/'.length) &&
82
+ headRepository?.full_name === repository &&
83
+ ((prior.path === '.github/workflows/deploy.yml' &&
84
+ prior.event === 'workflow_dispatch') ||
85
+ (input.deploymentProfile !== 'starter' &&
86
+ prior.path === '.github/workflows/ci.yml' &&
87
+ prior.event === 'push')));
88
+ });
89
+ if (cleanupOnly)
90
+ return;
91
+ const ipResponse = await request('https://checkip.amazonaws.com', {
92
+ redirect: 'error',
93
+ signal: AbortSignal.timeout(15_000),
94
+ });
95
+ check(ipResponse.ok, 'runner IPv4 lookup failed');
96
+ const address = await ipResponse.text();
97
+ check(address.length <= 64, 'runner IPv4 response exceeds bound');
98
+ const cidr = (0, private_smoke_admission_js_1.publicRunnerIpv4)(address.trim());
99
+ const wait = dependencies.wait ??
100
+ ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
101
+ async function observe(allowed) {
102
+ for (let poll = 0; poll < 24; poll += 1) {
103
+ const response = await request(input.url, {
104
+ redirect: 'manual',
105
+ signal: AbortSignal.timeout(15_000),
106
+ });
107
+ // Do not consume or retain an application response body.
108
+ await response.body?.cancel();
109
+ if (allowed
110
+ ? response.status >= 200 && response.status < 400
111
+ : response.status === 403)
112
+ return;
113
+ if (poll < 23)
114
+ await wait(5_000);
115
+ }
116
+ throw new Error(`Private smoke access: ${allowed ? 'admission' : 'revocation'} was not observed; deployment acceptance prohibited`);
117
+ }
118
+ await (0, private_smoke_admission_js_1.withPrivateSmokeAdmission)({
119
+ store,
120
+ context: { run, attempt, source: input.source, baseline },
121
+ cidr,
122
+ run: input.run,
123
+ awaitAdmission: () => observe(true),
124
+ awaitRevocation: () => observe(false),
125
+ });
126
+ }
127
+ //# sourceMappingURL=private-smoke-access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-smoke-access.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/private-smoke-access.ts"],"names":[],"mappings":";;AA0CA,sDAKC;AAGD,8DASC;AA3DD,qCAAuC;AACvC,yCAAiC;AAEjC,mDAGyB;AACzB,qFAAgF;AAChF,6EAKsC;AAwBtC,SAAS,KAAK,CAAC,SAAkB,EAAE,OAAe;IAChD,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,6EAA6E;AACtE,KAAK,UAAU,qBAAqB,CACzC,KAA8B,EAC9B,eAAyC,EAAE;IAE3C,OAAO,qBAAqB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,qFAAqF;AAC9E,KAAK,UAAU,yBAAyB,CAC7C,KAAmD,EACnD,eAAyC,EAAE;IAE3C,OAAO,qBAAqB,CAC1B,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,EAAE,EACjD,YAAY,EACZ,IAAI,CACL,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,KAA8B,EAC9B,YAAsC,EACtC,WAAoB;IAEpB,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC;IAC5D,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,IAAI,KAAK,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAA,wCAAwB,EACrC,IAAI,CAAC,KAAK,CACR,IAAA,sBAAY,EACV,IAAA,gBAAI,EAAC,KAAK,CAAC,IAAI,EAAE,8CAA8C,CAAC,EAChE,MAAM,CACP,CACF,CACF,CAAC;IACF,KAAK,CACH,MAAM,CAAC,iBAAiB,KAAK,KAAK,CAAC,iBAAiB,EACpD,uDAAuD,CACxD,CAAC;IACF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/C,KAAK,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IACzC,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACpE,MAAM,KAAK,CAAC,GAAG,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM,CAC9C,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAC9B,CAAC;IACF,KAAK,CACH,QAAQ,CAAC,MAAM,GAAG,CAAC,EACnB,yDAAyD,CAC1D,CAAC;IACF,MAAM,UAAU,GAAG,WAAW,CAAC,iBAAiB,IAAI,EAAE,CAAC;IACvD,MAAM,GAAG,GAAG,cAAc,KAAK,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IAC9E,MAAM,QAAQ,GAAG,GAAG,UAAU,iCAAiC,GAAG,EAAE,CAAC;IACrE,KAAK,CACH,WAAW,CAAC,cAAc,KAAK,MAAM;QACnC,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC;QACrC,WAAW,CAAC,UAAU,KAAK,GAAG;QAC9B,WAAW,CAAC,UAAU,KAAK,KAAK,CAAC,MAAM;QACvC,WAAW,CAAC,2BAA2B,KAAK,QAAQ;QACpD,CAAC,CAAC,WAAW,CAAC,iBAAiB,KAAK,mBAAmB;YACrD,WAAW,CAAC,mBAAmB,KAAK,QAAQ,CAAC;YAC7C,CAAC,WAAW,CAAC,iBAAiB,KAAK,MAAM;gBACvC,KAAK,CAAC,iBAAiB,KAAK,SAAS;gBACrC,WAAW,CAAC,mBAAmB;oBAC7B,GAAG,UAAU,6BAA6B,GAAG,EAAE,CAAC,CAAC,EACzD,qDAAqD,CACtD,CAAC;IACF,MAAM,GAAG,GAAG,WAAW,CAAC,aAAa,IAAI,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,kBAAkB,IAAI,EAAE,CAAC;IACrD,KAAK,CACH,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;QAC1B,iCAAiC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EACtD,uCAAuC,CACxC,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI,6DAA4B,CAAC,CACrE;QACE,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,YAAY,EAAE,IAAA,qCAAqB,EAAC,MAAM,CAAC;KAC5C,EACD,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CACpC,CAAC;IACF,MAAM,IAAA,kDAAqB,EACzB,KAAK,EACL,QAAQ,EACR,KAAK,EAAE,KAA0B,EAAE,EAAE;QACnC,mFAAmF;QACnF,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO;YAChD,OAAO,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;QACtD,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC;QACvC,KAAK,CACH,KAAK,EACL,gFAAgF,CACjF,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,gCAAgC,UAAU,iBAAiB,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,OAAO,EAAE,EAChG;YACE,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,MAAM,EAAE,6BAA6B;aACtC;YACD,QAAQ,EAAE,OAAO;YACjB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;SACpC,CACF,CAAC;QACF,KAAK,CACH,QAAQ,CAAC,EAAE,EACX,8EAA8E,CAC/E,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;QACjE,MAAM,cAAc,GAAG,KAAK,CAAC,eACO,CAAC;QACrC,OAAO,CACL,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,GAAG;YAC9B,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,KAAK,CAAC,OAAO;YAC3C,KAAK,CAAC,MAAM,KAAK,WAAW;YAC5B,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM;YAC/B,KAAK,CAAC,WAAW,KAAK,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC;YACrD,cAAc,EAAE,SAAS,KAAK,UAAU;YACxC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,8BAA8B;gBAC7C,KAAK,CAAC,KAAK,KAAK,mBAAmB,CAAC;gBACpC,CAAC,KAAK,CAAC,iBAAiB,KAAK,SAAS;oBACpC,KAAK,CAAC,IAAI,KAAK,0BAA0B;oBACzC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAC7B,CAAC;IACJ,CAAC,CACF,CAAC;IACF,IAAI,WAAW;QAAE,OAAO;IACxB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,+BAA+B,EAAE;QAChE,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IACH,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,2BAA2B,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;IACxC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,oCAAoC,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,IAAA,6CAAgB,EAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GACR,YAAY,CAAC,IAAI;QACjB,CAAC,CAAC,YAAoB,EAAE,EAAE,CACxB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IACvE,KAAK,UAAU,OAAO,CAAC,OAAgB;QACrC,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACxC,QAAQ,EAAE,QAAQ;gBAClB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,CAAC,CAAC;YACH,yDAAyD;YACzD,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAC9B,IACE,OAAO;gBACL,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG;gBACjD,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG;gBAE3B,OAAO;YACT,IAAI,IAAI,GAAG,EAAE;gBAAE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,qDAAqD,CACnH,CAAC;IACJ,CAAC;IACD,MAAM,IAAA,sDAAyB,EAAC;QAC9B,KAAK;QACL,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE;QACzD,IAAI;QACJ,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,cAAc,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;QACnC,eAAe,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;KACtC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,43 @@
1
+ export interface SmokeAdmissionContext {
2
+ run: string;
3
+ attempt: string;
4
+ source: string;
5
+ baseline: readonly string[];
6
+ }
7
+ export interface SmokeIpSet {
8
+ addresses: readonly string[];
9
+ description: string;
10
+ lockToken: string;
11
+ }
12
+ export interface SmokeIpSetStore {
13
+ read(): Promise<SmokeIpSet>;
14
+ update(previous: SmokeIpSet, next: Pick<SmokeIpSet, 'addresses' | 'description'>): Promise<void>;
15
+ }
16
+ export interface SmokeAdmissionLease {
17
+ run: string;
18
+ attempt: string;
19
+ source: string;
20
+ cidr: string;
21
+ baseline: string;
22
+ expiresAt: number;
23
+ }
24
+ export declare function runnerAlreadyAllowed(cidr: string, baseline: readonly string[]): boolean;
25
+ export declare function publicRunnerIpv4(value: string): string;
26
+ export declare function parseSmokeAdmissionLease(description: string): SmokeAdmissionLease | undefined;
27
+ /** Remove only this lease's address. Never replace unrelated addresses with a baseline. */
28
+ export declare function cleanupSmokeAdmission(store: SmokeIpSetStore, context: SmokeAdmissionContext): Promise<void>;
29
+ /** A retained lease alone, or its expiry, is not proof that a different run ended. */
30
+ export declare function recoverSmokeAdmission(store: SmokeIpSetStore, baseline: readonly string[], completedRun: (lease: SmokeAdmissionLease) => Promise<boolean>): Promise<void>;
31
+ export declare function withPrivateSmokeAdmission<T>(input: {
32
+ store: SmokeIpSetStore;
33
+ context: SmokeAdmissionContext;
34
+ cidr: string;
35
+ run: () => Promise<T>;
36
+ awaitAdmission: () => Promise<void>;
37
+ awaitRevocation: () => Promise<void>;
38
+ now?: () => number;
39
+ signals?: {
40
+ on(event: 'SIGINT' | 'SIGTERM', listener: () => void): unknown;
41
+ removeListener(event: 'SIGINT' | 'SIGTERM', listener: () => void): unknown;
42
+ };
43
+ }): Promise<T>;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runnerAlreadyAllowed = runnerAlreadyAllowed;
4
+ exports.publicRunnerIpv4 = publicRunnerIpv4;
5
+ exports.parseSmokeAdmissionLease = parseSmokeAdmissionLease;
6
+ exports.cleanupSmokeAdmission = cleanupSmokeAdmission;
7
+ exports.recoverSmokeAdmission = recoverSmokeAdmission;
8
+ exports.withPrivateSmokeAdmission = withPrivateSmokeAdmission;
9
+ const node_crypto_1 = require("node:crypto");
10
+ const node_net_1 = require("node:net");
11
+ const prefix = 'ebk-smoke-v1:';
12
+ const sorted = (values) => [...values].sort();
13
+ const same = (a, b) => JSON.stringify(sorted(a)) === JSON.stringify(sorted(b));
14
+ const baselineDigest = (values) => (0, node_crypto_1.createHash)('sha256')
15
+ .update(JSON.stringify(sorted(values)))
16
+ .digest('hex');
17
+ function requireCondition(condition, message) {
18
+ if (!condition)
19
+ throw new Error(`Private smoke access: ${message}`);
20
+ }
21
+ function runnerAlreadyAllowed(cidr, baseline) {
22
+ const address = cidr.replace(/\/32$/, '');
23
+ requireCondition(cidr === publicRunnerIpv4(address), 'admission is not an exact /32');
24
+ const numeric = (ip) => ip.split('.').reduce((value, octet) => value * 256 + Number(octet), 0) >>>
25
+ 0;
26
+ return baseline.some((entry) => {
27
+ const [network, bits] = entry.split('/');
28
+ requireCondition((0, node_net_1.isIP)(network) === 4 && /^(?:[0-9]|[12][0-9]|3[0-2])$/.test(bits), 'invalid IPv4 baseline');
29
+ const mask = Number(bits) === 0 ? 0 : (0xffffffff << (32 - Number(bits))) >>> 0;
30
+ return (numeric(address) & mask) === (numeric(network) & mask);
31
+ });
32
+ }
33
+ function publicRunnerIpv4(value) {
34
+ requireCondition((0, node_net_1.isIP)(value) === 4, 'one exact public IPv4 runner address is required');
35
+ const [a, b] = value.split('.').map(Number);
36
+ requireCondition(a > 0 &&
37
+ a < 224 &&
38
+ a !== 10 &&
39
+ a !== 127 &&
40
+ !(a === 169 && b === 254) &&
41
+ !(a === 172 && b >= 16 && b <= 31) &&
42
+ !(a === 192 && b === 168) &&
43
+ !(a === 100 && b >= 64 && b <= 127) &&
44
+ !(a === 198 && (b === 18 || b === 19)), 'non-public runner address refused');
45
+ return `${value}/32`;
46
+ }
47
+ function parseSmokeAdmissionLease(description) {
48
+ if (description === '')
49
+ return undefined;
50
+ requireCondition(description.startsWith(prefix) && description.length <= 256, 'unrecognized IP-set description; do not overwrite it');
51
+ const parts = description.slice(prefix.length).split(',');
52
+ requireCondition(parts.length === 6, 'malformed admission lease');
53
+ const [run, attempt, source, cidr, baseline, expires] = parts;
54
+ requireCondition(/^[1-9][0-9]*$/.test(run) &&
55
+ /^[1-9][0-9]*$/.test(attempt) &&
56
+ /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(source) &&
57
+ /^[a-f0-9]{64}$/.test(baseline) &&
58
+ /^[0-9]{13}$/.test(expires), 'malformed admission identity');
59
+ requireCondition(cidr === publicRunnerIpv4(cidr.replace(/\/32$/, '')), 'admission is not an exact /32');
60
+ return { run, attempt, source, cidr, baseline, expiresAt: Number(expires) };
61
+ }
62
+ function belongsTo(lease, context) {
63
+ return (lease.run === context.run &&
64
+ lease.attempt === context.attempt &&
65
+ lease.source === context.source);
66
+ }
67
+ /** Remove only this lease's address. Never replace unrelated addresses with a baseline. */
68
+ async function cleanupSmokeAdmission(store, context) {
69
+ for (let attempt = 0; attempt < 3; attempt += 1) {
70
+ const before = await store.read();
71
+ const lease = parseSmokeAdmissionLease(before.description);
72
+ if (!lease) {
73
+ requireCondition(same(before.addresses, context.baseline), 'allowlist differs from committed baseline; cleanup unproved');
74
+ return;
75
+ }
76
+ requireCondition(belongsTo(lease, context), 'another run owns the admission; use protected stale recovery');
77
+ requireCondition(lease.baseline === baselineDigest(context.baseline) &&
78
+ !context.baseline.includes(lease.cidr), 'lease baseline changed; investigate without deleting');
79
+ try {
80
+ await store.update(before, {
81
+ addresses: before.addresses.filter((cidr) => cidr !== lease.cidr),
82
+ description: '',
83
+ });
84
+ }
85
+ catch {
86
+ // An update may have succeeded remotely. Read back before retrying it.
87
+ }
88
+ const after = await store.read();
89
+ if (!after.description && !after.addresses.includes(lease.cidr)) {
90
+ requireCondition(same(after.addresses, context.baseline), 'temporary admission removed but unrelated allowlist drift remains');
91
+ return;
92
+ }
93
+ }
94
+ throw new Error('Private smoke access: cleanup unproved; deployment acceptance is prohibited. Run protected smoke-access cleanup before retrying.');
95
+ }
96
+ /** A retained lease alone, or its expiry, is not proof that a different run ended. */
97
+ async function recoverSmokeAdmission(store, baseline, completedRun) {
98
+ const current = await store.read();
99
+ const lease = parseSmokeAdmissionLease(current.description);
100
+ if (!lease) {
101
+ requireCondition(same(current.addresses, baseline), 'unleased allowlist drift requires investigation');
102
+ return;
103
+ }
104
+ requireCondition(lease.baseline === baselineDigest(baseline), 'stale lease baseline differs from committed policy');
105
+ requireCondition(await completedRun(lease), 'prior admission run is not confirmed complete');
106
+ await cleanupSmokeAdmission(store, { ...lease, baseline });
107
+ }
108
+ async function withPrivateSmokeAdmission(input) {
109
+ const { store, context, cidr } = input;
110
+ requireCondition(cidr === publicRunnerIpv4(cidr.replace(/\/32$/, '')), 'admission is not an exact /32');
111
+ const before = await store.read();
112
+ requireCondition(!parseSmokeAdmissionLease(before.description), 'recover the existing admission before starting smoke');
113
+ requireCondition(same(before.addresses, context.baseline), 'live allowlist differs from committed baseline');
114
+ const alreadyAllowed = runnerAlreadyAllowed(cidr, context.baseline);
115
+ const description = prefix +
116
+ [
117
+ context.run,
118
+ context.attempt,
119
+ context.source,
120
+ cidr,
121
+ baselineDigest(context.baseline),
122
+ (input.now ?? Date.now)() + 40 * 60_000,
123
+ ].join(',');
124
+ parseSmokeAdmissionLease(description);
125
+ const signals = input.signals ?? process;
126
+ let interrupted = false;
127
+ const stop = () => {
128
+ interrupted = true;
129
+ };
130
+ signals.on('SIGINT', stop);
131
+ signals.on('SIGTERM', stop);
132
+ try {
133
+ if (!alreadyAllowed)
134
+ await store.update(before, {
135
+ addresses: sorted([...context.baseline, cidr]),
136
+ description,
137
+ });
138
+ const after = await store.read();
139
+ requireCondition(same(after.addresses, alreadyAllowed ? context.baseline : [...context.baseline, cidr]) && after.description === (alreadyAllowed ? '' : description), 'admission readback differs');
140
+ await input.awaitAdmission();
141
+ requireCondition(!interrupted, 'interrupted before smoke');
142
+ const result = await input.run();
143
+ requireCondition(!interrupted, 'smoke interrupted');
144
+ return result;
145
+ }
146
+ finally {
147
+ try {
148
+ await cleanupSmokeAdmission(store, context);
149
+ if (!alreadyAllowed)
150
+ await input.awaitRevocation();
151
+ }
152
+ finally {
153
+ signals.removeListener('SIGINT', stop);
154
+ signals.removeListener('SIGTERM', stop);
155
+ }
156
+ }
157
+ }
158
+ //# sourceMappingURL=private-smoke-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-smoke-admission.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/private-smoke-admission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { WAFV2Client } from '@aws-sdk/client-wafv2';
2
+ import { CloudFrontClient } from '@aws-sdk/client-cloudfront';
3
+ import type { SmokeIpSetStore } from './private-smoke-admission.js';
4
+ import type { CanonicalDeploymentStage } from '../repository-policy/index.js';
5
+ export interface PrivateSmokeResourceIdentity {
6
+ account: string;
7
+ stage: CanonicalDeploymentStage;
8
+ workspace: string;
9
+ policyDigest: string;
10
+ }
11
+ export interface PrivateSmokeClients {
12
+ waf: Pick<WAFV2Client, 'send'>;
13
+ cloudfront: Pick<CloudFrontClient, 'send'>;
14
+ }
15
+ /** Only global WAF resources attached to the exact generated Router are eligible. */
16
+ export declare function openPrivateSmokeControlPlane(identity: PrivateSmokeResourceIdentity, smokeUrl: string | undefined, clients?: PrivateSmokeClients): Promise<SmokeIpSetStore & {
17
+ arn: string;
18
+ }>;
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openPrivateSmokeControlPlane = openPrivateSmokeControlPlane;
4
+ const client_wafv2_1 = require("@aws-sdk/client-wafv2");
5
+ const client_cloudfront_1 = require("@aws-sdk/client-cloudfront");
6
+ function check(condition, message) {
7
+ if (!condition)
8
+ throw new Error(`Private smoke access: ${message}`);
9
+ }
10
+ /** Only global WAF resources attached to the exact generated Router are eligible. */
11
+ async function openPrivateSmokeControlPlane(identity, smokeUrl, clients = {
12
+ waf: new client_wafv2_1.WAFV2Client({
13
+ region: 'us-east-1',
14
+ endpoint: 'https://wafv2.us-east-1.amazonaws.com',
15
+ maxAttempts: 3,
16
+ requestHandler: { connectionTimeout: 10_000, requestTimeout: 30_000 },
17
+ }),
18
+ cloudfront: new client_cloudfront_1.CloudFrontClient({
19
+ region: 'us-east-1',
20
+ endpoint: 'https://cloudfront.amazonaws.com',
21
+ maxAttempts: 3,
22
+ requestHandler: { connectionTimeout: 10_000, requestTimeout: 30_000 },
23
+ }),
24
+ }) {
25
+ check(/^\d{12}$/.test(identity.account) &&
26
+ /^[a-z0-9][a-z0-9-]{0,62}$/.test(identity.workspace) &&
27
+ ['development', 'staging', 'production'].includes(identity.stage) &&
28
+ /^sha256:[a-f0-9]{64}$/.test(identity.policyDigest), 'invalid committed resource identity');
29
+ const url = smokeUrl === undefined ? undefined : new URL(smokeUrl);
30
+ if (url)
31
+ check(url.protocol === 'https:' && !url.username && !url.password && !url.port, 'credential-free HTTPS Router required');
32
+ const name = `foundation-${identity.stage}-router-ipv4-allowlist`;
33
+ const ipSets = [];
34
+ let marker;
35
+ const seen = new Set();
36
+ do {
37
+ const page = await clients.waf.send(new client_wafv2_1.ListIPSetsCommand({
38
+ Scope: 'CLOUDFRONT',
39
+ Limit: 100,
40
+ NextMarker: marker,
41
+ }));
42
+ ipSets.push(...(page.IPSets ?? []));
43
+ marker = page.NextMarker;
44
+ check(!marker || !seen.has(marker), 'IP-set pagination did not advance');
45
+ if (marker)
46
+ seen.add(marker);
47
+ check(seen.size <= 100, 'IP-set inventory exceeds bounded inspection');
48
+ } while (marker);
49
+ const matches = ipSets.filter((set) => set.Name === name);
50
+ check(matches.length === 1 && matches[0].Id, 'exact stage IPv4 IP set missing or ambiguous; configure a baseline IPv4 CIDR before private hosted smoke');
51
+ const selected = matches[0];
52
+ const arn = `arn:aws:wafv2:us-east-1:${identity.account}:global/ipset/${name}/${selected.Id}`;
53
+ check(selected.ARN === arn, 'IP-set account/scope/identity mismatch');
54
+ const expectedTags = {
55
+ 'ebk:managed-by': 'empire-builder-kit',
56
+ 'ebk:owner': 'foundation',
57
+ 'ebk:stage': identity.stage,
58
+ 'ebk:workspace': identity.workspace,
59
+ 'ebk:policy-digest': identity.policyDigest,
60
+ };
61
+ async function attestTags(resourceArn) {
62
+ const tags = {};
63
+ let tagMarker;
64
+ const markers = new Set();
65
+ do {
66
+ const page = await clients.waf.send(new client_wafv2_1.ListTagsForResourceCommand({
67
+ ResourceARN: resourceArn,
68
+ NextMarker: tagMarker,
69
+ Limit: 100,
70
+ }));
71
+ for (const tag of page.TagInfoForResource?.TagList ?? []) {
72
+ if (tag.Key && tag.Value)
73
+ tags[tag.Key] = tag.Value;
74
+ }
75
+ tagMarker = page.NextMarker;
76
+ check(!tagMarker || !markers.has(tagMarker), 'tag pagination did not advance');
77
+ if (tagMarker)
78
+ markers.add(tagMarker);
79
+ check(markers.size <= 10, 'tag inventory exceeds bounded inspection');
80
+ } while (tagMarker);
81
+ for (const [key, value] of Object.entries(expectedTags))
82
+ check(tags[key] === value, 'WAF ownership or committed policy differs');
83
+ }
84
+ await attestTags(arn);
85
+ // Cleanup never expands access; exact tagged IP-set identity and lease are sufficient.
86
+ // Admission additionally proves the Router-to-ACL-to-IP-set attachment.
87
+ if (url) {
88
+ const distributions = [];
89
+ marker = undefined;
90
+ seen.clear();
91
+ do {
92
+ const page = await clients.cloudfront.send(new client_cloudfront_1.ListDistributionsCommand({ Marker: marker }));
93
+ distributions.push(...(page.DistributionList?.Items ?? []));
94
+ marker = page.DistributionList?.NextMarker;
95
+ check(!page.DistributionList?.IsTruncated || marker, 'truncated Router inventory has no continuation');
96
+ check(!marker || !seen.has(marker), 'Router pagination did not advance');
97
+ if (marker)
98
+ seen.add(marker);
99
+ check(seen.size <= 100, 'Router inventory exceeds bounded inspection');
100
+ } while (marker);
101
+ const routers = distributions.filter((router) => router.DomainName === url.hostname ||
102
+ router.Aliases?.Items?.includes(url.hostname));
103
+ check(routers.length === 1 &&
104
+ routers[0].Enabled &&
105
+ routers[0].ARN?.startsWith(`arn:aws:cloudfront::${identity.account}:distribution/`), 'exact account Router missing, disabled, or ambiguous');
106
+ const acls = [];
107
+ marker = undefined;
108
+ seen.clear();
109
+ do {
110
+ const page = await clients.waf.send(new client_wafv2_1.ListWebACLsCommand({
111
+ Scope: 'CLOUDFRONT',
112
+ Limit: 100,
113
+ NextMarker: marker,
114
+ }));
115
+ acls.push(...(page.WebACLs ?? []));
116
+ marker = page.NextMarker;
117
+ check(!marker || !seen.has(marker), 'Web ACL pagination did not advance');
118
+ if (marker)
119
+ seen.add(marker);
120
+ check(seen.size <= 100, 'Web ACL inventory exceeds bounded inspection');
121
+ } while (marker);
122
+ const attached = acls.filter((acl) => acl.ARN === routers[0].WebACLId);
123
+ check(attached.length === 1 &&
124
+ attached[0].Id &&
125
+ attached[0].Name &&
126
+ attached[0].ARN?.startsWith(`arn:aws:wafv2:us-east-1:${identity.account}:global/webacl/`), 'Router Web ACL is outside the exact account/scope');
127
+ const acl = attached[0];
128
+ await attestTags(acl.ARN);
129
+ const { WebACL } = await clients.waf.send(new client_wafv2_1.GetWebACLCommand({ Scope: 'CLOUDFRONT', Name: acl.Name, Id: acl.Id }));
130
+ check(WebACL?.ARN === acl.ARN, 'Web ACL readback identity differs');
131
+ const rules = WebACL?.Rules?.filter((rule) => rule.Name === 'StageIpAllowlist') ?? [];
132
+ const statement = rules[0]?.Statement?.NotStatement?.Statement;
133
+ const refs = statement?.IPSetReferenceStatement
134
+ ? [statement.IPSetReferenceStatement]
135
+ : statement?.OrStatement?.Statements?.map((item) => item.IPSetReferenceStatement);
136
+ check(rules.length === 1 &&
137
+ rules[0].Action?.Block &&
138
+ refs?.length &&
139
+ refs.every((ref) => ref?.ARN) &&
140
+ refs.filter((ref) => ref?.ARN === arn).length === 1, 'Router blocking rule does not reference the exact IP set');
141
+ // A dual-stack rule may have only its same-stage IPv6 companion, never an arbitrary second set.
142
+ check(refs.every((ref) => ref?.ARN === arn ||
143
+ ref?.ARN?.startsWith(`arn:aws:wafv2:us-east-1:${identity.account}:global/ipset/foundation-${identity.stage}-router-ipv6-allowlist/`)), 'Router allowlist contains an out-of-stage reference');
144
+ }
145
+ const key = { Name: name, Id: selected.Id, Scope: 'CLOUDFRONT' };
146
+ return {
147
+ arn,
148
+ async read() {
149
+ await attestTags(arn);
150
+ const { IPSet, LockToken } = await clients.waf.send(new client_wafv2_1.GetIPSetCommand(key));
151
+ check(IPSet?.ARN === arn &&
152
+ IPSet.Name === name &&
153
+ IPSet.IPAddressVersion === 'IPV4' &&
154
+ LockToken &&
155
+ Array.isArray(IPSet.Addresses), 'live IP-set identity mismatch');
156
+ return {
157
+ addresses: IPSet.Addresses,
158
+ description: IPSet.Description ?? '',
159
+ lockToken: LockToken,
160
+ };
161
+ },
162
+ async update(previous, next) {
163
+ await attestTags(arn);
164
+ await clients.waf.send(new client_wafv2_1.UpdateIPSetCommand({
165
+ ...key,
166
+ LockToken: previous.lockToken,
167
+ Addresses: [...next.addresses],
168
+ Description: next.description || undefined,
169
+ }));
170
+ },
171
+ };
172
+ }
173
+ //# sourceMappingURL=private-smoke-control-plane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-smoke-control-plane.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/private-smoke-control-plane.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const DEPENDENCY_OVERRIDES_PATH = "supply-chain/dependency-overrides.json";
2
+ export interface DependencyOverrides {
3
+ schemaVersion: 1;
4
+ overrides: Record<string, string>;
5
+ }
6
+ /** Seeded pins are data, never package-manager hooks or alternate registries. */
7
+ export declare function parseDependencyOverrides(value: unknown): DependencyOverrides;
8
+ export declare function renderDependencyOverridesYaml(value: DependencyOverrides): string;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEPENDENCY_OVERRIDES_PATH = void 0;
4
+ exports.parseDependencyOverrides = parseDependencyOverrides;
5
+ exports.renderDependencyOverridesYaml = renderDependencyOverridesYaml;
6
+ const semver_1 = require("semver");
7
+ const deterministic_order_js_1 = require("../../deterministic-order.js");
8
+ exports.DEPENDENCY_OVERRIDES_PATH = 'supply-chain/dependency-overrides.json';
9
+ function isSelector(value) {
10
+ const parts = value.split('>');
11
+ if (parts.length > 2)
12
+ return false;
13
+ return parts.every((part) => {
14
+ const match = /^((?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*)(?:@(.+))?$/u.exec(part);
15
+ return (match !== null &&
16
+ (match[2] === undefined || (0, semver_1.validRange)(match[2]) !== null));
17
+ });
18
+ }
19
+ /** Seeded pins are data, never package-manager hooks or alternate registries. */
20
+ function parseDependencyOverrides(value) {
21
+ const fail = () => {
22
+ throw new Error(`${exports.DEPENDENCY_OVERRIDES_PATH} must contain schemaVersion 1 and at most 256 npm selectors mapped to exact versions.`);
23
+ };
24
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
25
+ return fail();
26
+ const record = value;
27
+ if (record.schemaVersion !== 1 ||
28
+ Object.keys(record).some((key) => key !== 'schemaVersion' && key !== 'overrides'))
29
+ return fail();
30
+ if (typeof record.overrides !== 'object' ||
31
+ record.overrides === null ||
32
+ Array.isArray(record.overrides))
33
+ return fail();
34
+ const entries = Object.entries(record.overrides);
35
+ if (entries.length > 256)
36
+ return fail();
37
+ for (const [selector, version] of entries) {
38
+ if (selector.length > 256 ||
39
+ !isSelector(selector) ||
40
+ typeof version !== 'string' ||
41
+ (0, semver_1.valid)(version) !== version)
42
+ return fail();
43
+ }
44
+ return {
45
+ schemaVersion: 1,
46
+ overrides: Object.fromEntries(entries.sort(([left], [right]) => (0, deterministic_order_js_1.compareUtf16)(left, right))),
47
+ };
48
+ }
49
+ function renderDependencyOverridesYaml(value) {
50
+ const entries = Object.entries(value.overrides);
51
+ return entries.length === 0
52
+ ? ''
53
+ : `overrides:\n${entries.map(([selector, version]) => ` ${JSON.stringify(selector)}: ${JSON.stringify(version)}`).join('\n')}\n`;
54
+ }
55
+ //# sourceMappingURL=dependency-overrides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-overrides.js","sourceRoot":"","sources":["../../../../../../packages/nx/src/generators/preset/dependency-overrides.ts"],"names":[],"mappings":"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"}