@empire-builder-kit/nx 1.0.0-rc.43 → 1.0.0-rc.44

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empire-builder-kit/nx",
3
- "version": "1.0.0-rc.43",
3
+ "version": "1.0.0-rc.44",
4
4
  "description": "Nx generators, executors, and Blueprint contracts for Empire Builder Kit",
5
5
  "keywords": [
6
6
  "aws",
@@ -145,7 +145,7 @@
145
145
  "provenance": false
146
146
  },
147
147
  "dependencies": {
148
- "@empire-builder-kit/runtime": "1.0.0-rc.43",
148
+ "@empire-builder-kit/runtime": "1.0.0-rc.44",
149
149
  "@aws-sdk/client-cloudfront": "^3.700.0",
150
150
  "@aws-sdk/client-cloudwatch": "^3.700.0",
151
151
  "@aws-sdk/client-cloudwatch-logs": "^3.700.0",
@@ -178,5 +178,5 @@
178
178
  "engines": {
179
179
  "node": ">=22.13.0"
180
180
  },
181
- "gitHead": "7703b131fbcd59bc364ce7f914a1ff22250378c9"
181
+ "gitHead": "37e9dfcf2fcd9561ca389019600206d05975598a"
182
182
  }
@@ -3,6 +3,29 @@ export interface DependencyOverrides {
3
3
  schemaVersion: 1;
4
4
  overrides: Record<string, string>;
5
5
  }
6
+ /**
7
+ * Reviewed overrides seeded into a workspace that has no
8
+ * `supply-chain/dependency-overrides.json` yet. Each selector names an exact
9
+ * transitive release that the keyed `nx` version pins and that carries a high
10
+ * advisory; each target is clean and older than the generated minimum release
11
+ * age. The overrides are derived from that one `nx` release, so a spec fails
12
+ * when the framework or generated `nx` pin moves and the list must be
13
+ * reviewed again. An existing seeded file always wins over these defaults.
14
+ *
15
+ * A `name@x.y.z` selector is not limited to the `nx` pin. pnpm rewrites every
16
+ * dependency whose declared range includes x.y.z (in practice a caret or tilde
17
+ * range on the same major), so minimatch's `brace-expansion` range `^5.0.5`
18
+ * also resolves 5.0.12. A declared range that excludes x.y.z keeps its own
19
+ * resolution.
20
+ */
21
+ export declare const DEFAULT_DEPENDENCY_OVERRIDES: {
22
+ readonly nxVersion: "23.2.1";
23
+ readonly overrides: {
24
+ readonly 'axios@1.18.1': "1.20.0";
25
+ readonly 'brace-expansion@5.0.9': "5.0.12";
26
+ readonly 'smol-toml@1.6.1': "1.9.0";
27
+ };
28
+ };
6
29
  /** Seeded pins are data, never package-manager hooks or alternate registries. */
7
30
  export declare function parseDependencyOverrides(value: unknown): DependencyOverrides;
8
31
  export declare function renderDependencyOverridesYaml(value: DependencyOverrides): string;
@@ -1,11 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEPENDENCY_OVERRIDES_PATH = void 0;
3
+ exports.DEFAULT_DEPENDENCY_OVERRIDES = exports.DEPENDENCY_OVERRIDES_PATH = void 0;
4
4
  exports.parseDependencyOverrides = parseDependencyOverrides;
5
5
  exports.renderDependencyOverridesYaml = renderDependencyOverridesYaml;
6
6
  const semver_1 = require("semver");
7
7
  const deterministic_order_js_1 = require("../../deterministic-order.js");
8
8
  exports.DEPENDENCY_OVERRIDES_PATH = 'supply-chain/dependency-overrides.json';
9
+ /**
10
+ * Reviewed overrides seeded into a workspace that has no
11
+ * `supply-chain/dependency-overrides.json` yet. Each selector names an exact
12
+ * transitive release that the keyed `nx` version pins and that carries a high
13
+ * advisory; each target is clean and older than the generated minimum release
14
+ * age. The overrides are derived from that one `nx` release, so a spec fails
15
+ * when the framework or generated `nx` pin moves and the list must be
16
+ * reviewed again. An existing seeded file always wins over these defaults.
17
+ *
18
+ * A `name@x.y.z` selector is not limited to the `nx` pin. pnpm rewrites every
19
+ * dependency whose declared range includes x.y.z (in practice a caret or tilde
20
+ * range on the same major), so minimatch's `brace-expansion` range `^5.0.5`
21
+ * also resolves 5.0.12. A declared range that excludes x.y.z keeps its own
22
+ * resolution.
23
+ */
24
+ exports.DEFAULT_DEPENDENCY_OVERRIDES = {
25
+ nxVersion: '23.2.1',
26
+ overrides: {
27
+ 'axios@1.18.1': '1.20.0',
28
+ 'brace-expansion@5.0.9': '5.0.12',
29
+ 'smol-toml@1.6.1': '1.9.0',
30
+ },
31
+ };
9
32
  function isSelector(value) {
10
33
  const parts = value.split('>');
11
34
  if (parts.length > 2)
@@ -7,7 +7,7 @@
7
7
  export declare const WORKSPACE_SST_VERSION: "4.17.1";
8
8
  export declare const WORKSPACE_NODE_VERSION: "22.23.1";
9
9
  export declare const WORKSPACE_PNPM_VERSION: "11.20.0";
10
- export declare const WORKSPACE_VITEST_VERSION: "4.1.4";
10
+ export declare const WORKSPACE_VITEST_VERSION: "4.1.11";
11
11
  export declare const WORKSPACE_PNPM_SHA512: "9a6f330a95b66446ea088faf1521405a8a01f07fde7124cc9958dfed52d4bb436737e65b08f85f37b46fcba375092558ac51262b816844b22f63406ed166bfee";
12
12
  export declare const WORKSPACE_PNPM_DESCRIPTOR: "pnpm@11.20.0+sha512.9a6f330a95b66446ea088faf1521405a8a01f07fde7124cc9958dfed52d4bb436737e65b08f85f37b46fcba375092558ac51262b816844b22f63406ed166bfee";
13
13
  /**
@@ -10,7 +10,7 @@ exports.WORKSPACE_SST_NPM_INTEGRITY = exports.WORKSPACE_PNPM_DESCRIPTOR = export
10
10
  exports.WORKSPACE_SST_VERSION = '4.17.1';
11
11
  exports.WORKSPACE_NODE_VERSION = '22.23.1';
12
12
  exports.WORKSPACE_PNPM_VERSION = '11.20.0';
13
- exports.WORKSPACE_VITEST_VERSION = '4.1.4';
13
+ exports.WORKSPACE_VITEST_VERSION = '4.1.11';
14
14
  exports.WORKSPACE_PNPM_SHA512 = '9a6f330a95b66446ea088faf1521405a8a01f07fde7124cc9958dfed52d4bb436737e65b08f85f37b46fcba375092558ac51262b816844b22f63406ed166bfee';
15
15
  exports.WORKSPACE_PNPM_DESCRIPTOR = `pnpm@${exports.WORKSPACE_PNPM_VERSION}+sha512.${exports.WORKSPACE_PNPM_SHA512}`;
16
16
  /**
@@ -8,6 +8,8 @@ export interface WorkspaceFileOptions {
8
8
  /** trunk (starter only) protects main alone and delivers production from
9
9
  * every merged main push; protected-pair keeps develop and main. */
10
10
  deliveryLane?: DeliveryLane;
11
+ /** Seeded supply-chain/dependency-overrides.json data. When absent, the
12
+ * workspace is seeded with DEFAULT_DEPENDENCY_OVERRIDES. */
11
13
  dependencyOverrides?: unknown;
12
14
  deploymentAccounts?: ConfiguredDeploymentAccounts;
13
15
  deploymentProfile?: DeploymentProfile;
@@ -1183,7 +1183,10 @@ function renderWorkspaceFiles(options) {
1183
1183
  requirements: options.foundationRequirements ?? [],
1184
1184
  });
1185
1185
  const dependencyOverrides = (0, dependency_overrides_js_1.parseDependencyOverrides)(options.dependencyOverrides === undefined
1186
- ? { schemaVersion: 1, overrides: {} }
1186
+ ? {
1187
+ schemaVersion: 1,
1188
+ overrides: { ...dependency_overrides_js_1.DEFAULT_DEPENDENCY_OVERRIDES.overrides },
1189
+ }
1187
1190
  : options.dependencyOverrides);
1188
1191
  const deploymentProfile = options.deploymentProfile ?? 'starter';
1189
1192
  const deliveryLane = options.deliveryLane ?? 'protected-pair';
@@ -17,7 +17,7 @@ export declare const PRODUCT_VERSIONS: {
17
17
  readonly awsSts: "^3.700.0";
18
18
  readonly drizzle: "^0.45.2";
19
19
  readonly drizzleKit: "^0.31.4";
20
- readonly next: "16.3.6";
20
+ readonly next: "16.3.8";
21
21
  readonly pg: "^8.22.0";
22
22
  readonly playwright: "^1.59.1";
23
23
  readonly react: "19.2.8";
@@ -27,7 +27,7 @@ export declare const PRODUCT_VERSIONS: {
27
27
  readonly typesPg: "^8.15.5";
28
28
  readonly typesReact: "19.2.17";
29
29
  readonly typesReactDom: "19.2.3";
30
- readonly vitest: "4.1.4";
30
+ readonly vitest: "4.1.11";
31
31
  };
32
32
  export declare const PRODUCT_PACKAGE_MANAGED_JSON_POINTERS: readonly ["/name", "/version", "/private", "/dependencies/@aws-sdk~1client-appconfigdata", "/dependencies/@aws-sdk~1client-cloudwatch", "/dependencies/@aws-sdk~1client-cloudwatch-logs", "/dependencies/@aws-sdk~1client-cost-explorer", "/dependencies/@aws-sdk~1client-cognito-identity-provider", "/dependencies/@aws-sdk~1client-dynamodb", "/dependencies/@aws-sdk~1client-ecs", "/dependencies/@aws-sdk~1client-eventbridge", "/dependencies/@aws-sdk~1client-s3", "/dependencies/@aws-sdk~1client-secrets-manager", "/dependencies/@aws-sdk~1client-sfn", "/dependencies/@aws-sdk~1client-sqs", "/dependencies/@aws-sdk~1rds-signer", "/dependencies/@aws-sdk~1client-ssm", "/dependencies/@aws-sdk~1client-sts", "/dependencies/@empire-builder-kit~1runtime", "/dependencies/drizzle-orm", "/dependencies/next", "/dependencies/pg", "/dependencies/react", "/dependencies/react-dom", "/dependencies/server-only", "/devDependencies/@axe-core~1playwright", "/devDependencies/@playwright~1test", "/devDependencies/@types~1node", "/devDependencies/@types~1pg", "/devDependencies/@types~1react", "/devDependencies/@types~1react-dom", "/devDependencies/drizzle-kit", "/devDependencies/vitest", "/exports/.~1api-client", "/exports/.~1api-contract", "/exports/.~1contracts"];
33
33
  export declare function standardPackageManagedJsonPointers(sql: boolean): string[];
@@ -27,7 +27,7 @@ exports.PRODUCT_VERSIONS = {
27
27
  awsSts: '^3.700.0',
28
28
  drizzle: '^0.45.2',
29
29
  drizzleKit: '^0.31.4',
30
- next: '16.3.6',
30
+ next: '16.3.8',
31
31
  pg: '^8.22.0',
32
32
  playwright: '^1.59.1',
33
33
  react: '19.2.8',
@@ -1654,9 +1654,21 @@ describe('${input.workload} protected Service performance runtime', () => {
1654
1654
  );
1655
1655
  try {
1656
1656
  if (!server.listening) await once(server, 'listening');
1657
+ // start() keeps the production dual-stack wildcard bind. A wildcard
1658
+ // port can coincide with a foreign 127.0.0.1 listener that the loopback
1659
+ // probe would reach instead, so rebind this test server on 127.0.0.1.
1660
+ await new Promise<void>((resolve, reject) =>
1661
+ server.close((error) => (error ? reject(error) : resolve())),
1662
+ );
1663
+ server.listen({ host: '127.0.0.1', port: 0 });
1664
+ await once(server, 'listening');
1657
1665
  const address = server.address();
1658
- if (!address || typeof address === 'string') {
1659
- throw new Error('Generated Service did not bind a TCP port.');
1666
+ if (
1667
+ !address ||
1668
+ typeof address === 'string' ||
1669
+ address.address !== '127.0.0.1'
1670
+ ) {
1671
+ throw new Error('Generated Service did not bind a loopback TCP port.');
1660
1672
  }
1661
1673
  process.env.PORT = String(address.port);
1662
1674
  await expect(
@@ -1699,9 +1711,14 @@ describe('${input.workload} protected Service performance runtime', () => {
1699
1711
  saturation: { percent: 25 },
1700
1712
  });
1701
1713
  } finally {
1702
- await new Promise<void>((resolve, reject) =>
1703
- server.close((error) => (error ? reject(error) : resolve())),
1704
- );
1714
+ // A failed rebind (for example EADDRNOTAVAIL on a host without IPv4
1715
+ // loopback) leaves the server closed; closing it again would reject with
1716
+ // ERR_SERVER_NOT_RUNNING and hide the original error.
1717
+ if (server.listening) {
1718
+ await new Promise<void>((resolve, reject) =>
1719
+ server.close((error) => (error ? reject(error) : resolve())),
1720
+ );
1721
+ }
1705
1722
  if (previousPort === undefined) delete process.env.PORT;
1706
1723
  else process.env.PORT = previousPort;
1707
1724
  if (previousIngressProof === undefined) {
@@ -6,11 +6,21 @@ export interface TcpPortRange {
6
6
  first: number;
7
7
  last: number;
8
8
  }
9
- /** Read only. Never change sysctl/netsh or assume a custom range is default. */
9
+ /**
10
+ * Read only. Never change sysctl/netsh or assume a custom range is default.
11
+ *
12
+ * A supported platform is read at most three times, pausing 250 ms x attempt
13
+ * between reads (250 ms, then 500 ms). Each native command read is bounded by a
14
+ * 5 s timeout, so the worst-case failure on Windows or macOS takes about
15
+ * 3 x 5 s + 250 ms + 500 ms = 15.75 s before the
16
+ * `prerequisite-unavailable` error. An unsupported platform fails at once,
17
+ * without a read or a pause, and the error names it as unsupported.
18
+ */
10
19
  export declare function readAutomaticTcpPortRange(effects?: {
11
20
  platform?: NodeJS.Platform;
12
21
  read?: (path: string) => string;
13
22
  execute?: (command: string, args: string[]) => string;
23
+ pause?: (milliseconds: number) => void;
14
24
  }): TcpPortRange;
15
25
  export declare function preferredFleetPort(key: string): number;
16
26
  export declare function canBindLoopbackPort(port: number): Promise<boolean>;
@@ -21,7 +21,33 @@ function validRange(range) {
21
21
  range.first <= range.last &&
22
22
  range.last <= 65_535);
23
23
  }
24
- /** Read only. Never change sysctl/netsh or assume a custom range is default. */
24
+ /**
25
+ * Bounded attempts for the host range read. A loaded Windows host can fail a
26
+ * single netsh read transiently; three attempts with a short pause absorb that
27
+ * without hiding a persistent failure. Module-private: the specs observe the
28
+ * bound through the injected effects, and the public ./local-dev subpath does
29
+ * not export it.
30
+ */
31
+ const AUTOMATIC_TCP_PORT_RANGE_READ_ATTEMPTS = 3;
32
+ const AUTOMATIC_TCP_PORT_RANGE_RETRY_PAUSE_MS = 250;
33
+ const SUPPORTED_RANGE_PLATFORMS = [
34
+ 'linux',
35
+ 'darwin',
36
+ 'win32',
37
+ ];
38
+ function pauseSynchronously(milliseconds) {
39
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
40
+ }
41
+ /**
42
+ * Read only. Never change sysctl/netsh or assume a custom range is default.
43
+ *
44
+ * A supported platform is read at most three times, pausing 250 ms x attempt
45
+ * between reads (250 ms, then 500 ms). Each native command read is bounded by a
46
+ * 5 s timeout, so the worst-case failure on Windows or macOS takes about
47
+ * 3 x 5 s + 250 ms + 500 ms = 15.75 s before the
48
+ * `prerequisite-unavailable` error. An unsupported platform fails at once,
49
+ * without a read or a pause, and the error names it as unsupported.
50
+ */
25
51
  function readAutomaticTcpPortRange(effects = {}) {
26
52
  const platform = effects.platform ?? process.platform;
27
53
  const execute = effects.execute ??
@@ -32,48 +58,62 @@ function readAutomaticTcpPortRange(effects = {}) {
32
58
  windowsHide: true,
33
59
  stdio: ['ignore', 'pipe', 'pipe'],
34
60
  }));
35
- try {
36
- let values;
37
- if (platform === 'linux') {
38
- const text = (effects.read ?? ((path) => (0, node_fs_1.readFileSync)(path, 'utf8')))('/proc/sys/net/ipv4/ip_local_port_range');
39
- if (!/^\s*\d+\s+\d+\s*$/.test(text))
40
- throw new Error('Invalid range');
41
- values = text.trim().split(/\s+/).map(Number);
42
- }
43
- else if (platform === 'darwin') {
44
- const text = execute('/usr/sbin/sysctl', [
45
- '-n',
46
- 'net.inet.ip.portrange.first',
47
- 'net.inet.ip.portrange.last',
48
- ]);
49
- if (!/^\s*\d+\s+\d+\s*$/.test(text))
50
- throw new Error('Invalid range');
51
- values = text.trim().split(/\s+/).map(Number);
61
+ const read = effects.read ?? ((path) => (0, node_fs_1.readFileSync)(path, 'utf8'));
62
+ const pause = effects.pause ?? pauseSynchronously;
63
+ // An unsupported platform is not transient: fail before any read.
64
+ if (!SUPPORTED_RANGE_PLATFORMS.includes(platform)) {
65
+ throw new errors_js_1.LocalDevContractError('prerequisite-unavailable', `The host platform ${platform} is not supported for the automatic TCP client-port range read; ebk dev up supports Linux, macOS and Windows. No network setting was changed.`);
66
+ }
67
+ const attempts = AUTOMATIC_TCP_PORT_RANGE_READ_ATTEMPTS;
68
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
69
+ try {
70
+ return readAutomaticTcpPortRangeOnce(platform, read, execute);
52
71
  }
53
- else if (platform === 'win32') {
54
- const text = execute('netsh.exe', [
55
- 'int',
56
- 'ipv4',
57
- 'show',
58
- 'dynamicport',
59
- 'tcp',
60
- ]);
61
- // Labels are localized; the two numeric colon-delimited values are not.
62
- values = [...text.matchAll(/:\s*(\d+)\s*$/gm)].map((match) => Number(match[1]));
63
- if (values.length !== 2 || values[1] < 1)
64
- throw new Error('Invalid range');
65
- values[1] = values[0] + values[1] - 1;
72
+ catch {
73
+ if (attempt < attempts)
74
+ pause(AUTOMATIC_TCP_PORT_RANGE_RETRY_PAUSE_MS * attempt);
66
75
  }
67
- else
68
- throw new Error('Unsupported platform');
69
- const range = { first: values[0], last: values[1] };
70
- if (!validRange(range))
76
+ }
77
+ throw new errors_js_1.LocalDevContractError('prerequisite-unavailable', `Cannot read the host automatic TCP client-port range after ${attempts} ${attempts === 1 ? 'attempt' : 'attempts'}. Verify the native network configuration is readable before retrying ebk dev up; no network setting was changed.`);
78
+ }
79
+ function readAutomaticTcpPortRangeOnce(platform, read, execute) {
80
+ let values;
81
+ if (platform === 'linux') {
82
+ const text = read('/proc/sys/net/ipv4/ip_local_port_range');
83
+ if (!/^\s*\d+\s+\d+\s*$/.test(text))
84
+ throw new Error('Invalid range');
85
+ values = text.trim().split(/\s+/).map(Number);
86
+ }
87
+ else if (platform === 'darwin') {
88
+ const text = execute('/usr/sbin/sysctl', [
89
+ '-n',
90
+ 'net.inet.ip.portrange.first',
91
+ 'net.inet.ip.portrange.last',
92
+ ]);
93
+ if (!/^\s*\d+\s+\d+\s*$/.test(text))
71
94
  throw new Error('Invalid range');
72
- return range;
95
+ values = text.trim().split(/\s+/).map(Number);
73
96
  }
74
- catch {
75
- throw new errors_js_1.LocalDevContractError('prerequisite-unavailable', 'Cannot read the host automatic TCP client-port range. Verify the native network configuration is readable before retrying ebk dev up; no network setting was changed.');
97
+ else if (platform === 'win32') {
98
+ const text = execute('netsh.exe', [
99
+ 'int',
100
+ 'ipv4',
101
+ 'show',
102
+ 'dynamicport',
103
+ 'tcp',
104
+ ]);
105
+ // Labels are localized; the two numeric colon-delimited values are not.
106
+ values = [...text.matchAll(/:\s*(\d+)\s*$/gm)].map((match) => Number(match[1]));
107
+ if (values.length !== 2 || values[1] < 1)
108
+ throw new Error('Invalid range');
109
+ values[1] = values[0] + values[1] - 1;
76
110
  }
111
+ else
112
+ throw new Error('Unsupported platform');
113
+ const range = { first: values[0], last: values[1] };
114
+ if (!validRange(range))
115
+ throw new Error('Invalid range');
116
+ return range;
77
117
  }
78
118
  function preferredFleetPort(key) {
79
119
  const digest = (0, node_crypto_1.createHash)('sha256').update(key).digest();