@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 +3 -3
- package/src/generators/preset/dependency-overrides.d.ts +23 -0
- package/src/generators/preset/dependency-overrides.js +24 -1
- package/src/generators/preset/tool-versions.d.ts +1 -1
- package/src/generators/preset/tool-versions.js +1 -1
- package/src/generators/preset/workspace-files.d.ts +2 -0
- package/src/generators/preset/workspace-files.js +4 -1
- package/src/generators/slice/built-in-plan-shared.d.ts +2 -2
- package/src/generators/slice/built-in-plan-shared.js +1 -1
- package/src/generators/workload/service-performance-files.js +22 -5
- package/src/local-dev/ports.d.ts +11 -1
- package/src/local-dev/ports.js +78 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empire-builder-kit/nx",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
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.
|
|
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": "
|
|
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.
|
|
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.
|
|
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
|
-
? {
|
|
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.
|
|
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.
|
|
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[];
|
|
@@ -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 (
|
|
1659
|
-
|
|
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
|
-
|
|
1703
|
-
|
|
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) {
|
package/src/local-dev/ports.d.ts
CHANGED
|
@@ -6,11 +6,21 @@ export interface TcpPortRange {
|
|
|
6
6
|
first: number;
|
|
7
7
|
last: number;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
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>;
|
package/src/local-dev/ports.js
CHANGED
|
@@ -21,7 +21,33 @@ function validRange(range) {
|
|
|
21
21
|
range.first <= range.last &&
|
|
22
22
|
range.last <= 65_535);
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
95
|
+
values = text.trim().split(/\s+/).map(Number);
|
|
73
96
|
}
|
|
74
|
-
|
|
75
|
-
|
|
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();
|