@ohos-ports/nx 23.3.0-beta.2 → 24.0.2-beta.0
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/README.md +3 -6
- package/dist/bin/nx.js +2 -2
- package/dist/bin/post-install.js +5 -3
- package/dist/nx-cloud-internals.d.ts +1 -0
- package/dist/nx-cloud-internals.js +7 -1
- package/dist/src/adapter/ngcli-adapter.js +2 -2
- package/dist/src/ai/clone-ai-config-repo.js +49 -12
- package/dist/src/command-line/add/add.d.ts +2 -0
- package/dist/src/command-line/add/add.js +23 -5
- package/dist/src/command-line/affected/affected.js +2 -2
- package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +0 -12
- package/dist/src/command-line/graph/graph.js +38 -10
- package/dist/src/command-line/init/command-object.js +0 -12
- package/dist/src/command-line/init/implementation/add-nx-to-nest.js +21 -62
- package/dist/src/command-line/init/init-v2.js +0 -2
- package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
- package/dist/src/command-line/migrate/agentic/definitions.d.ts +1 -3
- package/dist/src/command-line/migrate/agentic/definitions.js +5 -97
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +7 -45
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +9 -51
- package/dist/src/command-line/migrate/agentic/handoff.d.ts +1 -43
- package/dist/src/command-line/migrate/agentic/handoff.js +3 -119
- package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +0 -21
- package/dist/src/command-line/migrate/agentic/instruction-files.js +6 -27
- package/dist/src/command-line/migrate/agentic/master/run-master-session.d.ts +19 -1
- package/dist/src/command-line/migrate/agentic/master/run-master-session.js +88 -49
- package/dist/src/command-line/migrate/agentic/master/spawn-master.d.ts +1 -0
- package/dist/src/command-line/migrate/agentic/master/spawn-master.js +86 -24
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +2 -2
- package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +2 -2
- package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +1 -12
- package/dist/src/command-line/migrate/agentic/prompts/fragments.js +8 -17
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +0 -15
- package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +3 -100
- package/dist/src/command-line/migrate/agentic/select.d.ts +12 -6
- package/dist/src/command-line/migrate/agentic/select.js +38 -8
- package/dist/src/command-line/migrate/agentic/types.d.ts +9 -68
- package/dist/src/command-line/migrate/agentic/types.js +6 -8
- package/dist/src/command-line/migrate/command-object.js +6 -10
- package/dist/src/command-line/migrate/execute-migration.d.ts +6 -6
- package/dist/src/command-line/migrate/execute-migration.js +25 -15
- package/dist/src/command-line/migrate/migrate-analytics.d.ts +18 -1
- package/dist/src/command-line/migrate/migrate-analytics.js +38 -0
- package/dist/src/command-line/migrate/migrate-commits.d.ts +29 -17
- package/dist/src/command-line/migrate/migrate-commits.js +86 -32
- package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
- package/dist/src/command-line/migrate/migrate-config.js +12 -6
- package/dist/src/command-line/migrate/migrate-output.d.ts +1 -6
- package/dist/src/command-line/migrate/migrate-output.js +1 -10
- package/dist/src/command-line/migrate/migrate.d.ts +6 -30
- package/dist/src/command-line/migrate/migrate.js +257 -255
- package/dist/src/command-line/migrate/resolve-package-version.d.ts +2 -4
- package/dist/src/command-line/migrate/resolve-package-version.js +2 -35
- package/dist/src/command-line/migrate/run/agent-output.d.ts +2 -0
- package/dist/src/command-line/migrate/run/agent-output.js +9 -0
- package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
- package/dist/src/command-line/migrate/run/broker.js +69 -21
- package/dist/src/command-line/migrate/run/clean-retry.js +4 -2
- package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
- package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
- package/dist/src/command-line/migrate/run/give-up.d.ts +4 -3
- package/dist/src/command-line/migrate/run/give-up.js +8 -5
- package/dist/src/command-line/migrate/run/index.d.ts +7 -5
- package/dist/src/command-line/migrate/run/index.js +16 -1
- package/dist/src/command-line/migrate/run/issues.js +7 -2
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +61 -4
- package/dist/src/command-line/migrate/run/orchestrator.js +397 -133
- package/dist/src/command-line/migrate/run/run-state.d.ts +17 -1
- package/dist/src/command-line/migrate/run/run-state.js +41 -2
- package/dist/src/command-line/migrate/run/runbook.d.ts +1 -0
- package/dist/src/command-line/migrate/run/runbook.js +115 -18
- package/dist/src/command-line/migrate/run/state-lock.d.ts +29 -4
- package/dist/src/command-line/migrate/run/state-lock.js +102 -10
- package/dist/src/command-line/migrate/run/state-machine.js +4 -1
- package/dist/src/command-line/migrate/run/util.d.ts +7 -2
- package/dist/src/command-line/migrate/run/util.js +30 -3
- package/dist/src/command-line/migrate/run/worker.d.ts +1 -1
- package/dist/src/command-line/migrate/run/worker.js +252 -250
- package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
- package/dist/src/command-line/migrate/sort-migrations.js +1 -12
- package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +17 -12
- package/dist/src/command-line/release/changelog.js +9 -6
- package/dist/src/command-line/release/config/config.d.ts +1 -0
- package/dist/src/command-line/release/config/config.js +48 -9
- package/dist/src/command-line/release/release.js +2 -2
- package/dist/src/command-line/release/utils/git.js +8 -7
- package/dist/src/command-line/release/utils/interpolate-release-config.d.ts +6 -0
- package/dist/src/command-line/release/utils/interpolate-release-config.js +39 -0
- package/dist/src/command-line/release/utils/release-graph.d.ts +5 -0
- package/dist/src/command-line/release/utils/release-graph.js +1 -0
- package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -6
- package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +5 -6
- package/dist/src/command-line/release/utils/resolve-changelog-renderer.js +2 -2
- package/dist/src/command-line/release/utils/shared.js +10 -10
- package/dist/src/command-line/release/utils/version-plan-utils.d.ts +3 -12
- package/dist/src/command-line/release/utils/version-plan-utils.js +33 -55
- package/dist/src/command-line/release/version/version-actions.js +2 -1
- package/dist/src/command-line/release/version.js +5 -2
- package/dist/src/command-line/reset/reset.js +58 -62
- package/dist/src/command-line/run/executor-utils.js +1 -0
- package/dist/src/command-line/run/run-one.d.ts +20 -1
- package/dist/src/command-line/run/run-one.js +153 -5
- package/dist/src/command-line/run/run.js +2 -1
- package/dist/src/command-line/show/projects.js +5 -3
- package/dist/src/command-line/show/show-target/info.d.ts +10 -1
- package/dist/src/command-line/show/show-target/info.js +100 -15
- package/dist/src/command-line/show/show-target/inputs.js +10 -2
- package/dist/src/command-line/show/show-target/utils.js +1 -0
- package/dist/src/command-line/watch/command-object.js +3 -22
- package/dist/src/command-line/watch/watch.d.ts +0 -7
- package/dist/src/command-line/watch/watch.js +1 -1
- package/dist/src/command-line/yargs-utils/shared-options.js +1 -1
- package/dist/src/config/misc-interfaces.d.ts +18 -0
- package/dist/src/config/nx-json.d.ts +22 -11
- package/dist/src/config/task-graph.d.ts +1 -1
- package/dist/src/config/workspace-json-project-json.d.ts +88 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/core/graph/runtime.js +1 -1
- package/dist/src/core/graph/styles.css +1 -1
- package/dist/src/core/graph/styles.js +1 -1
- package/dist/src/daemon/client/client.d.ts +15 -0
- package/dist/src/daemon/client/client.js +181 -71
- package/dist/src/daemon/client/daemon-socket-messenger.d.ts +1 -1
- package/dist/src/daemon/client/daemon-socket-messenger.js +2 -2
- package/dist/src/daemon/server/client-socket-context.js +1 -1
- package/dist/src/daemon/server/handle-process-in-background.js +21 -9
- package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +2 -1
- package/dist/src/daemon/server/handle-select-affected-tasks.js +21 -13
- package/dist/src/daemon/server/native-js-loader.d.ts +1 -0
- package/dist/src/daemon/server/native-js-loader.js +21 -0
- package/dist/src/daemon/server/project-graph-incremental-recomputation.js +4 -8
- package/dist/src/daemon/server/server.d.ts +2 -1
- package/dist/src/daemon/server/server.js +17 -4
- package/dist/src/daemon/server/shutdown-utils.js +0 -3
- package/dist/src/daemon/server/start.d.ts +1 -0
- package/dist/src/daemon/server/start.js +2 -0
- package/dist/src/daemon/socket-utils.d.ts +11 -9
- package/dist/src/daemon/socket-utils.js +31 -61
- package/dist/src/daemon/tmp-dir.d.ts +19 -14
- package/dist/src/daemon/tmp-dir.js +142 -354
- package/dist/src/devkit-exports.d.ts +9 -1
- package/dist/src/devkit-exports.js +12 -1
- package/dist/src/devkit-internals.d.ts +6 -5
- package/dist/src/devkit-internals.js +13 -4
- package/dist/src/executors/run-commands/run-commands.impl.d.ts +4 -2
- package/dist/src/executors/run-commands/run-commands.impl.js +53 -27
- package/dist/src/executors/run-commands/running-tasks.d.ts +13 -4
- package/dist/src/executors/run-commands/running-tasks.js +148 -95
- package/dist/src/executors/run-commands/schema.json +1 -1
- package/dist/src/hasher/check-task-files.js +5 -8
- package/dist/src/hasher/file-hasher.js +9 -7
- package/dist/src/hasher/hash-task.js +4 -0
- package/dist/src/hasher/native-task-hasher-impl.js +3 -1
- package/dist/src/hasher/task-hasher.d.ts +2 -0
- package/dist/src/hasher/task-hasher.js +4 -1
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.d.ts +1 -2
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.js +6 -11
- package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.md +2 -2
- package/dist/src/migrations/update-24-0-0/enable-legacy-affected.d.ts +4 -0
- package/dist/src/migrations/update-24-0-0/enable-legacy-affected.js +15 -0
- package/dist/src/migrations/update-24-0-0/enable-legacy-affected.md +30 -0
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.d.ts +3 -0
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.js +100 -0
- package/dist/src/migrations/update-24-0-0/find-custom-hashers.md +63 -0
- package/dist/src/migrations/update-24-0-0/move-custom-hashers-to-inputs.md +146 -0
- package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.d.ts +3 -0
- package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.js +130 -0
- package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.md +62 -0
- package/dist/src/native/assert-supported-platform.js +1 -1
- package/dist/src/native/index.d.ts +238 -18
- package/dist/src/native/index.js +6 -1
- package/dist/src/native/native-bindings.js +15 -6
- package/dist/src/native/nx.openharmony-arm64.node +0 -0
- package/dist/src/native/nx.wasi-browser.js +1 -0
- package/dist/src/native/nx.wasi.cjs +1 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/nx-cloud/update-manager.d.ts +14 -0
- package/dist/src/nx-cloud/update-manager.js +237 -50
- package/dist/src/plugins/js/lock-file/pnpm-parser.js +3 -4
- package/dist/src/plugins/js/lock-file/pruned-output.d.ts +2 -2
- package/dist/src/plugins/js/lock-file/pruned-output.js +4 -4
- package/dist/src/plugins/js/utils/register.js +9 -4
- package/dist/src/project-graph/affected/affected-tasks.d.ts +9 -6
- package/dist/src/project-graph/affected/affected-tasks.js +31 -7
- package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +7 -0
- package/dist/src/project-graph/plugins/loaded-nx-plugin.js +49 -6
- package/dist/src/project-graph/utils/project-configuration/target-merging.js +1 -1
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +12 -133
- package/dist/src/project-graph/utils/project-configuration-utils.js +2 -2
- package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
- package/dist/src/tasks-runner/create-task-graph.d.ts +8 -7
- package/dist/src/tasks-runner/create-task-graph.js +50 -27
- package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
- package/dist/src/tasks-runner/init-tasks-runner.js +116 -59
- package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
- package/dist/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +5 -2
- package/dist/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +4 -1
- package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +5 -1
- package/dist/src/tasks-runner/pseudo-ipc.d.ts +1 -0
- package/dist/src/tasks-runner/pseudo-ipc.js +4 -0
- package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
- package/dist/src/tasks-runner/pseudo-terminal.js +2 -2
- package/dist/src/tasks-runner/readiness/executor-ready-signal.d.ts +7 -0
- package/dist/src/tasks-runner/readiness/executor-ready-signal.js +43 -0
- package/dist/src/tasks-runner/readiness/probes.d.ts +14 -0
- package/dist/src/tasks-runner/readiness/probes.js +101 -0
- package/dist/src/tasks-runner/readiness/ready-signal-server.d.ts +18 -0
- package/dist/src/tasks-runner/readiness/ready-signal-server.js +72 -0
- package/dist/src/tasks-runner/readiness/ready-signal.d.ts +33 -0
- package/dist/src/tasks-runner/readiness/ready-signal.js +92 -0
- package/dist/src/tasks-runner/readiness/ready-when.d.ts +84 -0
- package/dist/src/tasks-runner/readiness/ready-when.js +371 -0
- package/dist/src/tasks-runner/readiness/startup-host.d.ts +1 -0
- package/dist/src/tasks-runner/readiness/startup-host.js +32 -0
- package/dist/src/tasks-runner/run-command.d.ts +6 -2
- package/dist/src/tasks-runner/run-command.js +21 -31
- package/dist/src/tasks-runner/run-outcome.d.ts +16 -0
- package/dist/src/tasks-runner/run-outcome.js +39 -0
- package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
- package/dist/src/tasks-runner/running-tasks/running-task.d.ts +1 -1
- package/dist/src/tasks-runner/task-env.d.ts +10 -0
- package/dist/src/tasks-runner/task-env.js +37 -5
- package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
- package/dist/src/tasks-runner/task-graph-utils.js +17 -12
- package/dist/src/tasks-runner/task-orchestrator.d.ts +62 -18
- package/dist/src/tasks-runner/task-orchestrator.js +750 -150
- package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
- package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
- package/dist/src/tasks-runner/tasks-schedule.js +63 -6
- package/dist/src/tasks-runner/tokens.d.ts +54 -0
- package/dist/src/tasks-runner/tokens.js +161 -0
- package/dist/src/tasks-runner/utils.d.ts +35 -6
- package/dist/src/tasks-runner/utils.js +149 -68
- package/dist/src/ultracache/ci-status.d.ts +24 -0
- package/dist/src/ultracache/ci-status.js +87 -0
- package/dist/src/ultracache/config.d.ts +3 -3
- package/dist/src/ultracache/config.js +4 -4
- package/dist/src/ultracache/fetch.d.ts +2 -0
- package/dist/src/ultracache/fetch.js +1 -0
- package/dist/src/ultracache/overrides.js +4 -0
- package/dist/src/utils/acknowledge-build-scripts.d.ts +34 -1
- package/dist/src/utils/acknowledge-build-scripts.js +171 -32
- package/dist/src/utils/child-process.js +2 -1
- package/dist/src/utils/find-matching-projects.js +9 -6
- package/dist/src/utils/git-utils.d.ts +12 -5
- package/dist/src/utils/git-utils.js +69 -11
- package/dist/src/utils/long-running-target.d.ts +1 -3
- package/dist/src/utils/long-running-target.js +1 -3
- package/dist/src/utils/output.d.ts +4 -3
- package/dist/src/utils/output.js +4 -3
- package/dist/src/utils/owned-private-dir.d.ts +1 -17
- package/dist/src/utils/owned-private-dir.js +10 -62
- package/dist/src/utils/package-manager.d.ts +8 -0
- package/dist/src/utils/package-manager.js +65 -8
- package/dist/src/utils/perf-hooks.d.ts +1 -0
- package/dist/src/utils/plugins/core-plugins.js +5 -1
- package/dist/src/utils/progress-topics.d.ts +1 -0
- package/dist/src/utils/progress-topics.js +1 -0
- package/dist/src/utils/safe-spawn.js +1 -5
- package/dist/src/utils/shell-quoting.d.ts +8 -1
- package/dist/src/utils/shell-quoting.js +12 -1
- package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
- package/dist/src/utils/spawn-without-terminal.js +110 -0
- package/dist/src/utils/string-similarity.d.ts +38 -0
- package/dist/src/utils/string-similarity.js +108 -0
- package/migrations.json +20 -6
- package/package.json +15 -24
- package/schemas/migrations-schema.json +11 -0
- package/schemas/nx-schema.json +133 -11
- package/schemas/project-schema.json +114 -4
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +0 -56
- package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +0 -67
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +0 -49
- package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +0 -53
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +0 -26
- package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +0 -27
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +0 -70
- package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +0 -113
- package/dist/src/command-line/migrate/agentic/run-step.d.ts +0 -68
- package/dist/src/command-line/migrate/agentic/run-step.js +0 -148
- package/dist/src/command-line/migrate/agentic/runner.d.ts +0 -21
- package/dist/src/command-line/migrate/agentic/runner.js +0 -262
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +0 -9
- package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +0 -18
- package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +0 -18
- package/dist/src/tasks-runner/legacy-depends-on-warning.js +0 -109
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReadySignalServer = void 0;
|
|
4
|
+
const socket_utils_1 = require("../../daemon/socket-utils");
|
|
5
|
+
const pseudo_ipc_1 = require("../pseudo-ipc");
|
|
6
|
+
const ready_signal_1 = require("./ready-signal");
|
|
7
|
+
let id = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Receives the readiness signals of the producers this process starts. It
|
|
10
|
+
* does not depend on the pseudo terminal, which Windows and non-TTY runs lack.
|
|
11
|
+
*/
|
|
12
|
+
class ReadySignalServer {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.path = (0, socket_utils_1.getForkedProcessOsSocketPath)(`${process.pid}-ready-${id++}`);
|
|
15
|
+
this.server = new pseudo_ipc_1.PseudoIPCServer(this.path);
|
|
16
|
+
this.listeners = new Map();
|
|
17
|
+
// A producer can signal before its probe subscribes. Only tasks given the
|
|
18
|
+
// socket are buffered for, until their probe subscribes.
|
|
19
|
+
this.early = new Map();
|
|
20
|
+
this.issued = new Set();
|
|
21
|
+
}
|
|
22
|
+
async env(taskId) {
|
|
23
|
+
this.started ??= this.server.init().then(() => {
|
|
24
|
+
this.server.onMessageFromChildren((message) => {
|
|
25
|
+
if (isReadySignalMessage(message))
|
|
26
|
+
this.dispatch(message);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
await this.started;
|
|
30
|
+
this.issued.add(taskId);
|
|
31
|
+
return {
|
|
32
|
+
[ready_signal_1.READY_SIGNAL_SOCKET_ENV]: this.path,
|
|
33
|
+
[ready_signal_1.READY_SIGNAL_TASK_ENV]: taskId,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
subscribe(taskId, listener) {
|
|
37
|
+
this.listeners.set(taskId, listener);
|
|
38
|
+
this.issued.delete(taskId);
|
|
39
|
+
for (const message of this.early.get(taskId) ?? []) {
|
|
40
|
+
listener(message);
|
|
41
|
+
}
|
|
42
|
+
this.early.delete(taskId);
|
|
43
|
+
return () => {
|
|
44
|
+
if (this.listeners.get(taskId) === listener) {
|
|
45
|
+
this.listeners.delete(taskId);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
close() {
|
|
50
|
+
if (this.started) {
|
|
51
|
+
this.server.close();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
dispatch(message) {
|
|
55
|
+
const listener = this.listeners.get(message.taskId);
|
|
56
|
+
if (listener) {
|
|
57
|
+
listener(message);
|
|
58
|
+
}
|
|
59
|
+
else if (this.issued.has(message.taskId)) {
|
|
60
|
+
const early = this.early.get(message.taskId) ?? [];
|
|
61
|
+
early.push(message);
|
|
62
|
+
this.early.set(message.taskId, early);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.ReadySignalServer = ReadySignalServer;
|
|
67
|
+
function isReadySignalMessage(message) {
|
|
68
|
+
if (typeof message !== 'object' || message === null)
|
|
69
|
+
return false;
|
|
70
|
+
const { type, taskId } = message;
|
|
71
|
+
return type === 'nx-ready-signal:ready' && typeof taskId === 'string';
|
|
72
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const READY_SIGNAL_SOCKET_ENV = "NX_READY_SIGNAL_SOCKET";
|
|
2
|
+
export declare const READY_SIGNAL_TASK_ENV = "NX_READY_SIGNAL_TASK";
|
|
3
|
+
export declare const READY_URL_ENV = "NX_READY_URL";
|
|
4
|
+
export type ReadySignalMessage = {
|
|
5
|
+
type: 'nx-ready-signal:ready';
|
|
6
|
+
taskId: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
};
|
|
9
|
+
type ListeningServer = {
|
|
10
|
+
address(): {
|
|
11
|
+
address: string;
|
|
12
|
+
family: string;
|
|
13
|
+
port: number;
|
|
14
|
+
} | string | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Tells Nx that the task running this process is ready, for a target whose
|
|
18
|
+
* readyWhen is `signal`. Only the first call counts, so call it once the server
|
|
19
|
+
* listens. A server that isn't listening reports nothing. Pass the listening
|
|
20
|
+
* server or its url to have it passed on to the tasks that waited, as
|
|
21
|
+
* NX_READY_URL.
|
|
22
|
+
*/
|
|
23
|
+
export declare function emitReadySignal(server?: ListeningServer | string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `configured` moved to the address the server reported, for a task that
|
|
26
|
+
* waited for a signal: its protocol and port, and its host unless `configured`
|
|
27
|
+
* names localhost and the server listens on loopback. Keeps the path and
|
|
28
|
+
* query. Returns `configured` when no address was reported, and the reported
|
|
29
|
+
* address when `configured` is missing or not a URL.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getReadyUrl(configured: string): string;
|
|
32
|
+
export declare function getReadyUrl(configured?: string): string | undefined;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.READY_URL_ENV = exports.READY_SIGNAL_TASK_ENV = exports.READY_SIGNAL_SOCKET_ENV = void 0;
|
|
4
|
+
exports.emitReadySignal = emitReadySignal;
|
|
5
|
+
exports.getReadyUrl = getReadyUrl;
|
|
6
|
+
// Set on the env of a producer whose readyWhen is `signal`
|
|
7
|
+
exports.READY_SIGNAL_SOCKET_ENV = 'NX_READY_SIGNAL_SOCKET';
|
|
8
|
+
exports.READY_SIGNAL_TASK_ENV = 'NX_READY_SIGNAL_TASK';
|
|
9
|
+
// Set on the env of a task that waited for a producer that signalled its url
|
|
10
|
+
exports.READY_URL_ENV = 'NX_READY_URL';
|
|
11
|
+
let client;
|
|
12
|
+
let readySent = false;
|
|
13
|
+
function connect() {
|
|
14
|
+
const path = process.env[exports.READY_SIGNAL_SOCKET_ENV];
|
|
15
|
+
const taskId = process.env[exports.READY_SIGNAL_TASK_ENV];
|
|
16
|
+
if (!path || !taskId) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
// Required lazily to keep this module light for the task env code
|
|
20
|
+
const { PseudoIPCClient } = require('../pseudo-ipc');
|
|
21
|
+
// A failed connection must not crash the server it reports on, nor keep
|
|
22
|
+
// its process alive
|
|
23
|
+
client ??= new PseudoIPCClient(path)
|
|
24
|
+
.onMessageFromParent(taskId, () => { }, () => { }, () => { })
|
|
25
|
+
.unref();
|
|
26
|
+
return { client, taskId };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Tells Nx that the task running this process is ready, for a target whose
|
|
30
|
+
* readyWhen is `signal`. Only the first call counts, so call it once the server
|
|
31
|
+
* listens. A server that isn't listening reports nothing. Pass the listening
|
|
32
|
+
* server or its url to have it passed on to the tasks that waited, as
|
|
33
|
+
* NX_READY_URL.
|
|
34
|
+
*/
|
|
35
|
+
function emitReadySignal(server) {
|
|
36
|
+
const connection = connect();
|
|
37
|
+
if (!connection || readySent) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
// Express 5 calls the listen callback with the error when listening fails
|
|
41
|
+
if (server && typeof server !== 'string' && !server.address()) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
readySent = true;
|
|
45
|
+
const url = typeof server === 'string' ? server : getServerUrl(server);
|
|
46
|
+
connection.client.sendMessageToParent({
|
|
47
|
+
type: 'nx-ready-signal:ready',
|
|
48
|
+
taskId: connection.taskId,
|
|
49
|
+
...(url ? { url } : {}),
|
|
50
|
+
});
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
// Mirrors getListeningUrl in @nx/devkit/internal, which nx can't import
|
|
54
|
+
function getServerUrl(server) {
|
|
55
|
+
const address = server?.address();
|
|
56
|
+
if (!address || typeof address === 'string') {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const { Server: TlsServer } = require('tls');
|
|
60
|
+
const host = address.address === '::' || address.address === '0.0.0.0'
|
|
61
|
+
? 'localhost'
|
|
62
|
+
: address.family === 'IPv6'
|
|
63
|
+
? `[${address.address}]`
|
|
64
|
+
: address.address;
|
|
65
|
+
const protocol = server instanceof TlsServer ? 'https' : 'http';
|
|
66
|
+
return `${protocol}://${host}:${address.port}/`;
|
|
67
|
+
}
|
|
68
|
+
function getReadyUrl(configured) {
|
|
69
|
+
const ready = process.env[exports.READY_URL_ENV];
|
|
70
|
+
if (!ready || !URL.canParse(ready)) {
|
|
71
|
+
return configured;
|
|
72
|
+
}
|
|
73
|
+
if (!configured || !URL.canParse(configured)) {
|
|
74
|
+
return ready;
|
|
75
|
+
}
|
|
76
|
+
const url = new URL(configured);
|
|
77
|
+
const reported = new URL(ready);
|
|
78
|
+
url.protocol = reported.protocol;
|
|
79
|
+
url.port = reported.port;
|
|
80
|
+
// A localhost name reaches either loopback address; an IP literal only its own
|
|
81
|
+
if (!isLocalhostName(url.hostname) || !isLoopback(reported.hostname)) {
|
|
82
|
+
url.hostname = reported.hostname;
|
|
83
|
+
}
|
|
84
|
+
return url.toString();
|
|
85
|
+
}
|
|
86
|
+
function isLocalhostName(hostname) {
|
|
87
|
+
return hostname === 'localhost' || hostname.endsWith('.localhost');
|
|
88
|
+
}
|
|
89
|
+
function isLoopback(hostname) {
|
|
90
|
+
const host = hostname.replace(/^\[|\]$/g, '');
|
|
91
|
+
return isLocalhostName(host) || host === '::1' || /^127\./.test(host);
|
|
92
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ProjectGraph } from '../../config/project-graph';
|
|
2
|
+
import type { Task, TaskGraph } from '../../config/task-graph';
|
|
3
|
+
import type { ProjectConfiguration, ReadyWhen } from '../../config/workspace-json-project-json';
|
|
4
|
+
export declare const DEFAULT_READY_TIMEOUT = 600000;
|
|
5
|
+
type ReadyWhenProbe<Deferred> = {
|
|
6
|
+
timeout: number;
|
|
7
|
+
interval?: number;
|
|
8
|
+
} & ({
|
|
9
|
+
kind: 'url';
|
|
10
|
+
url: string | Deferred;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'port';
|
|
13
|
+
port: number | Deferred;
|
|
14
|
+
host?: string | Deferred;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'command';
|
|
17
|
+
command: string | Deferred;
|
|
18
|
+
env?: Record<string, string>;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'logMatches';
|
|
21
|
+
logMatches: (string | Deferred)[];
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'signal';
|
|
24
|
+
});
|
|
25
|
+
export type NormalizedReadyWhen = ReadyWhenProbe<never>;
|
|
26
|
+
export interface ReadyWhenWait {
|
|
27
|
+
timeout: number;
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ReadyWhenData {
|
|
31
|
+
workspaceRoot: string;
|
|
32
|
+
projectRoot: string;
|
|
33
|
+
projectName: string;
|
|
34
|
+
options: Record<string, unknown>;
|
|
35
|
+
env: () => NodeJS.ProcessEnv;
|
|
36
|
+
}
|
|
37
|
+
export declare function normalizeReadyWhen(readyWhen: ReadyWhen, taskId: string, data: ReadyWhenData): NormalizedReadyWhen | null;
|
|
38
|
+
/**
|
|
39
|
+
* Checks a producer's probe without the env the producer runs with. A value
|
|
40
|
+
* that reads that env is left to getReadyWhen in the process that runs the
|
|
41
|
+
* producer, and every other value is checked the way getReadyWhen checks it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function checkReadyWhen(readyWhen: ReadyWhen, taskId: string, data: Omit<ReadyWhenData, 'env'>): ReadyWhenWait;
|
|
44
|
+
export declare function readinessTimeoutError(taskId: string, readyWhen: NormalizedReadyWhen | ReadyWhenWait): Error;
|
|
45
|
+
export declare class ProducerFailedError extends Error {
|
|
46
|
+
constructor(taskId: string);
|
|
47
|
+
}
|
|
48
|
+
export declare class NotReadyError extends Error {
|
|
49
|
+
}
|
|
50
|
+
export declare class InvalidReadyWhenError extends Error {
|
|
51
|
+
}
|
|
52
|
+
export declare function notReadyError(taskId: string, reason: 'exited' | 'was stopped' | 'failed'): Error;
|
|
53
|
+
export declare function getReadyWhenConfig(task: Task, projectGraph: ProjectGraph): ReadyWhen | null | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* The probe of a producer this process starts with `taskEnv`. Env tokens read
|
|
56
|
+
* `taskEnv`, or for run-commands the env its command runs with
|
|
57
|
+
*/
|
|
58
|
+
export declare function getReadyWhen(task: Task, projectGraph: ProjectGraph, projects: Record<string, ProjectConfiguration>, workspaceRoot: string, taskEnv: NodeJS.ProcessEnv, inputs?: {
|
|
59
|
+
readyWhen: ReadyWhen;
|
|
60
|
+
executor: string;
|
|
61
|
+
data: {
|
|
62
|
+
workspaceRoot: string;
|
|
63
|
+
projectRoot: string;
|
|
64
|
+
projectName: string;
|
|
65
|
+
options: any;
|
|
66
|
+
};
|
|
67
|
+
}): NormalizedReadyWhen | null;
|
|
68
|
+
export declare const TASK_OPTIONS_ENV = "NX_TASK_OPTIONS";
|
|
69
|
+
export declare function getReadyWhenWait(task: Task, projectGraph: ProjectGraph, projects: Record<string, ProjectConfiguration>, workspaceRoot: string): ReadyWhenWait | null;
|
|
70
|
+
export type ReadyWhenInputs = ReturnType<typeof getReadyWhenInputs>;
|
|
71
|
+
export declare function getReadyWhenInputs(task: Task, projectGraph: ProjectGraph, projects: Record<string, ProjectConfiguration>, workspaceRoot: string): {
|
|
72
|
+
readyWhen: ReadyWhen;
|
|
73
|
+
executor: string;
|
|
74
|
+
data: {
|
|
75
|
+
workspaceRoot: string;
|
|
76
|
+
projectRoot: string;
|
|
77
|
+
projectName: string;
|
|
78
|
+
options: any;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export declare function mayReportReadyUrl(task: Task, projectGraph: ProjectGraph): boolean;
|
|
82
|
+
export declare function getReadyProducerIds(task: Task, taskGraph: TaskGraph): string[];
|
|
83
|
+
export declare function getReadyDependencies(taskGraph: TaskGraph, projectGraph: ProjectGraph): Record<string, string[]>;
|
|
84
|
+
export {};
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TASK_OPTIONS_ENV = exports.InvalidReadyWhenError = exports.NotReadyError = exports.ProducerFailedError = exports.DEFAULT_READY_TIMEOUT = void 0;
|
|
4
|
+
exports.normalizeReadyWhen = normalizeReadyWhen;
|
|
5
|
+
exports.checkReadyWhen = checkReadyWhen;
|
|
6
|
+
exports.readinessTimeoutError = readinessTimeoutError;
|
|
7
|
+
exports.notReadyError = notReadyError;
|
|
8
|
+
exports.getReadyWhenConfig = getReadyWhenConfig;
|
|
9
|
+
exports.getReadyWhen = getReadyWhen;
|
|
10
|
+
exports.getReadyWhenWait = getReadyWhenWait;
|
|
11
|
+
exports.getReadyWhenInputs = getReadyWhenInputs;
|
|
12
|
+
exports.mayReportReadyUrl = mayReportReadyUrl;
|
|
13
|
+
exports.getReadyProducerIds = getReadyProducerIds;
|
|
14
|
+
exports.getReadyDependencies = getReadyDependencies;
|
|
15
|
+
const path_1 = require("path");
|
|
16
|
+
const params_1 = require("../../utils/params");
|
|
17
|
+
const tokens_1 = require("../tokens");
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
const native_1 = require("../../native");
|
|
20
|
+
exports.DEFAULT_READY_TIMEOUT = 600_000;
|
|
21
|
+
// Node timers take at most a signed 32-bit count of milliseconds
|
|
22
|
+
const MAX_DURATION = 2_147_483_647;
|
|
23
|
+
const PROBE_KEYS = ['url', 'port', 'command', 'logMatches', 'signal'];
|
|
24
|
+
class EnvUnknownHere extends Error {
|
|
25
|
+
}
|
|
26
|
+
// A value that reads the producer's env. It keeps its written form, and
|
|
27
|
+
// getReadyWhen checks it in the process that runs the producer
|
|
28
|
+
class EnvDeferred {
|
|
29
|
+
constructor(written) {
|
|
30
|
+
this.written = written;
|
|
31
|
+
}
|
|
32
|
+
toString() {
|
|
33
|
+
return this.written;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// `options` and `env` are tokens only with a path, so shell text such as
|
|
37
|
+
// `${options}` stays as written
|
|
38
|
+
const PATHLESS_TOKENS = new Set([
|
|
39
|
+
'workspaceRoot',
|
|
40
|
+
'projectRoot',
|
|
41
|
+
'projectName',
|
|
42
|
+
]);
|
|
43
|
+
function normalizeReadyWhen(readyWhen, taskId, data) {
|
|
44
|
+
const probe = resolveReadyWhen(readyWhen, taskId, data);
|
|
45
|
+
// Only checkReadyWhen's env throws EnvUnknownHere, so nothing is deferred
|
|
46
|
+
return probe.kind === 'serverPicksPort'
|
|
47
|
+
? null
|
|
48
|
+
: probe;
|
|
49
|
+
}
|
|
50
|
+
function resolveReadyWhen(readyWhen, taskId, data) {
|
|
51
|
+
const invalid = (reason) => new InvalidReadyWhenError(`Task "${taskId}" has an invalid "readyWhen": ${reason}.`);
|
|
52
|
+
if (typeof readyWhen !== 'object' || readyWhen === null) {
|
|
53
|
+
throw invalid('expected an object');
|
|
54
|
+
}
|
|
55
|
+
const config = readyWhen;
|
|
56
|
+
const scope = {
|
|
57
|
+
isToken: (name, path) => path === undefined
|
|
58
|
+
? PATHLESS_TOKENS.has(name)
|
|
59
|
+
: name === 'options' || name === 'env',
|
|
60
|
+
read: (name, path) => (0, tokens_1.readPath)(data[name], path),
|
|
61
|
+
env: { read: data.env },
|
|
62
|
+
noValue: (token) => {
|
|
63
|
+
throw invalid(`"${token}" has no value`);
|
|
64
|
+
},
|
|
65
|
+
toText: (value, token) => {
|
|
66
|
+
if (!['string', 'number', 'boolean'].includes(typeof value)) {
|
|
67
|
+
throw invalid(`"${token}" is not a string or a number`);
|
|
68
|
+
}
|
|
69
|
+
return String(value);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
// A flag passed without a value parses as `true`, and no host or port is a
|
|
73
|
+
// boolean
|
|
74
|
+
const hostScope = {
|
|
75
|
+
...scope,
|
|
76
|
+
isUnset: (value) => typeof value === 'boolean',
|
|
77
|
+
};
|
|
78
|
+
// The Rspack dev server reads an empty port option as 0. An empty env var
|
|
79
|
+
// stays unset.
|
|
80
|
+
const portScope = {
|
|
81
|
+
...hostScope,
|
|
82
|
+
read: (name, path) => {
|
|
83
|
+
const value = scope.read(name, path);
|
|
84
|
+
return value === '' ? 0 : value;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
const resolve = (value, tokenScope = scope) => {
|
|
88
|
+
if (typeof value !== 'string') {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
let nodes;
|
|
92
|
+
try {
|
|
93
|
+
nodes = (0, tokens_1.parseTokens)(value, tokenScope);
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
throw invalid(e.message);
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return (0, tokens_1.renderTokens)(nodes, tokenScope);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e instanceof EnvUnknownHere) {
|
|
103
|
+
return new EnvDeferred(value);
|
|
104
|
+
}
|
|
105
|
+
throw e;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
// Braces are never valid in a host or port once resolved, so a leftover is
|
|
109
|
+
// a typo. A url keeps them: they are legal in its path and query.
|
|
110
|
+
const resolveWithoutBraces = (key, tokenScope) => {
|
|
111
|
+
const value = resolve(config[key], tokenScope);
|
|
112
|
+
if (typeof value === 'string' && /[{}]/.test(value)) {
|
|
113
|
+
throw invalid(`"${key}" contains an unknown placeholder`);
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
};
|
|
117
|
+
const present = PROBE_KEYS.filter((key) => config[key] != null);
|
|
118
|
+
if (present.length !== 1) {
|
|
119
|
+
throw invalid(`expected exactly one of ${PROBE_KEYS.map((k) => `"${k}"`).join(', ')}`);
|
|
120
|
+
}
|
|
121
|
+
const timeout = config.timeout ?? exports.DEFAULT_READY_TIMEOUT;
|
|
122
|
+
if (!isDuration(timeout)) {
|
|
123
|
+
throw invalid(`"timeout" must be an integer from 1 to ${MAX_DURATION}`);
|
|
124
|
+
}
|
|
125
|
+
const shared = { timeout };
|
|
126
|
+
if (config.interval != null) {
|
|
127
|
+
if (!isDuration(config.interval)) {
|
|
128
|
+
throw invalid(`"interval" must be an integer from 1 to ${MAX_DURATION}`);
|
|
129
|
+
}
|
|
130
|
+
shared.interval = config.interval;
|
|
131
|
+
}
|
|
132
|
+
switch (present[0]) {
|
|
133
|
+
case 'url': {
|
|
134
|
+
const url = resolve(config.url);
|
|
135
|
+
if (!(url instanceof EnvDeferred) &&
|
|
136
|
+
(typeof url !== 'string' || !isHttpUrl(url))) {
|
|
137
|
+
throw invalid('"url" must be an http or https URL');
|
|
138
|
+
}
|
|
139
|
+
return { kind: 'url', url, ...shared };
|
|
140
|
+
}
|
|
141
|
+
case 'port': {
|
|
142
|
+
let port = resolveWithoutBraces('port', portScope);
|
|
143
|
+
if (typeof port === 'string' && /^\d+$/.test(port)) {
|
|
144
|
+
port = Number(port);
|
|
145
|
+
}
|
|
146
|
+
if (port !== 0 &&
|
|
147
|
+
port !== 'auto' &&
|
|
148
|
+
!(port instanceof EnvDeferred) &&
|
|
149
|
+
(!isPositiveInteger(port) || port > 65535)) {
|
|
150
|
+
throw invalid('"port" must be an integer from 0 to 65535, or "auto"');
|
|
151
|
+
}
|
|
152
|
+
const host = resolveWithoutBraces('host', hostScope);
|
|
153
|
+
if (host == null) {
|
|
154
|
+
return port === 0 || port === 'auto'
|
|
155
|
+
? { kind: 'serverPicksPort', port, ...shared }
|
|
156
|
+
: { kind: 'port', port, ...shared };
|
|
157
|
+
}
|
|
158
|
+
if (!(host instanceof EnvDeferred) &&
|
|
159
|
+
(typeof host !== 'string' || !host)) {
|
|
160
|
+
throw invalid('"host" must be a non-empty string');
|
|
161
|
+
}
|
|
162
|
+
return port === 0 || port === 'auto'
|
|
163
|
+
? { kind: 'serverPicksPort', port, host, ...shared }
|
|
164
|
+
: { kind: 'port', port, host, ...shared };
|
|
165
|
+
}
|
|
166
|
+
case 'command': {
|
|
167
|
+
const command = resolve(config.command);
|
|
168
|
+
if (!(command instanceof EnvDeferred) &&
|
|
169
|
+
(typeof command !== 'string' || !command)) {
|
|
170
|
+
throw invalid('"command" must be a non-empty string');
|
|
171
|
+
}
|
|
172
|
+
return { kind: 'command', command, ...shared };
|
|
173
|
+
}
|
|
174
|
+
case 'logMatches': {
|
|
175
|
+
const logMatches = (Array.isArray(config.logMatches)
|
|
176
|
+
? config.logMatches
|
|
177
|
+
: [config.logMatches]).map((match) => resolve(match));
|
|
178
|
+
if (logMatches.length === 0 ||
|
|
179
|
+
!logMatches.every((m) => m instanceof EnvDeferred || (typeof m === 'string' && !!m))) {
|
|
180
|
+
throw invalid('"logMatches" must be a non-empty string or an array of them');
|
|
181
|
+
}
|
|
182
|
+
return { kind: 'logMatches', logMatches, ...shared };
|
|
183
|
+
}
|
|
184
|
+
case 'signal': {
|
|
185
|
+
if (config.signal !== true) {
|
|
186
|
+
throw invalid('"signal" must be true');
|
|
187
|
+
}
|
|
188
|
+
if (config.interval != null) {
|
|
189
|
+
throw invalid('"interval" is not used by "signal"');
|
|
190
|
+
}
|
|
191
|
+
return { kind: 'signal', timeout };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Checks a producer's probe without the env the producer runs with. A value
|
|
197
|
+
* that reads that env is left to getReadyWhen in the process that runs the
|
|
198
|
+
* producer, and every other value is checked the way getReadyWhen checks it.
|
|
199
|
+
*/
|
|
200
|
+
function checkReadyWhen(readyWhen, taskId, data) {
|
|
201
|
+
const probe = resolveReadyWhen(readyWhen, taskId, {
|
|
202
|
+
...data,
|
|
203
|
+
env: () => {
|
|
204
|
+
throw new EnvUnknownHere();
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
return {
|
|
208
|
+
timeout: probe.timeout,
|
|
209
|
+
description: describeReadyWhen(probe),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function readinessTimeoutError(taskId, readyWhen) {
|
|
213
|
+
const description = 'kind' in readyWhen ? describeReadyWhen(readyWhen) : readyWhen.description;
|
|
214
|
+
const longer = Math.min(readyWhen.timeout * 2, MAX_DURATION);
|
|
215
|
+
return new Error(`Task "${taskId}" did not become ready within ${(0, native_1.formatDuration)(readyWhen.timeout)} (readyWhen: ${description}). ` +
|
|
216
|
+
`If it needs longer, set "timeout": ${longer} in the target's "readyWhen", as { "...": true, "timeout": ${longer} } to keep an inferred check. ` +
|
|
217
|
+
'To change the check, set "readyWhen" on the target or in "targetDefaults" in nx.json, or set it to null to turn it off.');
|
|
218
|
+
}
|
|
219
|
+
// The row carries only the status; the owner reports the reason
|
|
220
|
+
class ProducerFailedError extends Error {
|
|
221
|
+
constructor(taskId) {
|
|
222
|
+
super(`Task "${taskId}" failed its readiness check in the process that started it.`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.ProducerFailedError = ProducerFailedError;
|
|
226
|
+
// An exit or a stop is completed by its own handler, not as a verdict
|
|
227
|
+
class NotReadyError extends Error {
|
|
228
|
+
}
|
|
229
|
+
exports.NotReadyError = NotReadyError;
|
|
230
|
+
class InvalidReadyWhenError extends Error {
|
|
231
|
+
}
|
|
232
|
+
exports.InvalidReadyWhenError = InvalidReadyWhenError;
|
|
233
|
+
function notReadyError(taskId, reason) {
|
|
234
|
+
return new NotReadyError(`Task "${taskId}" ${reason} before it became ready.`);
|
|
235
|
+
}
|
|
236
|
+
function describeReadyWhen(readyWhen) {
|
|
237
|
+
switch (readyWhen.kind) {
|
|
238
|
+
case 'url':
|
|
239
|
+
return `url ${readyWhen.url}`;
|
|
240
|
+
case 'port':
|
|
241
|
+
case 'serverPicksPort':
|
|
242
|
+
return readyWhen.host
|
|
243
|
+
? `port ${readyWhen.host}:${readyWhen.port}`
|
|
244
|
+
: `port ${readyWhen.port}`;
|
|
245
|
+
case 'command':
|
|
246
|
+
return `command "${readyWhen.command}"`;
|
|
247
|
+
case 'logMatches':
|
|
248
|
+
return `logMatches ${readyWhen.logMatches.map((m) => `"${m}"`).join(', ')}`;
|
|
249
|
+
case 'signal':
|
|
250
|
+
return 'signal';
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Raw config: scheduling must not throw on an invalid value, the producer's
|
|
254
|
+
// own start reports that
|
|
255
|
+
function getReadyWhenConfig(task, projectGraph) {
|
|
256
|
+
if (!task.continuous) {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
return projectGraph.nodes[task.target.project]?.data?.targets?.[task.target.target]?.readyWhen;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The probe of a producer this process starts with `taskEnv`. Env tokens read
|
|
263
|
+
* `taskEnv`, or for run-commands the env its command runs with
|
|
264
|
+
*/
|
|
265
|
+
function getReadyWhen(task, projectGraph, projects, workspaceRoot, taskEnv, inputs = getReadyWhenInputs(task, projectGraph, projects, workspaceRoot)) {
|
|
266
|
+
if (!inputs) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
const { readyWhen, executor, data } = inputs;
|
|
270
|
+
const { options } = data;
|
|
271
|
+
let commandEnv;
|
|
272
|
+
const env = () => {
|
|
273
|
+
if (executor !== 'nx:run-commands') {
|
|
274
|
+
return taskEnv;
|
|
275
|
+
}
|
|
276
|
+
if (commandEnv) {
|
|
277
|
+
return commandEnv;
|
|
278
|
+
}
|
|
279
|
+
// Required lazily, so loading run-command.ts doesn't also load the
|
|
280
|
+
// run-commands executor
|
|
281
|
+
const { calculateCwd, processEnv } = require('../../executors/run-commands/running-tasks');
|
|
282
|
+
commandEnv = processEnv(options.color, calculateCwd(options.cwd, {
|
|
283
|
+
root: workspaceRoot,
|
|
284
|
+
}), (options.env ?? {}), options.envFile, taskEnv);
|
|
285
|
+
return commandEnv;
|
|
286
|
+
};
|
|
287
|
+
const probe = normalizeReadyWhen(readyWhen, task.id, { ...data, env });
|
|
288
|
+
if (probe?.kind === 'command') {
|
|
289
|
+
probe.env = {
|
|
290
|
+
...Object.fromEntries(Object.entries(env()).filter(([, value]) => value !== undefined)),
|
|
291
|
+
[exports.TASK_OPTIONS_ENV]: JSON.stringify(options),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return probe;
|
|
295
|
+
}
|
|
296
|
+
// A command check reads the options its producer runs with from this variable
|
|
297
|
+
exports.TASK_OPTIONS_ENV = 'NX_TASK_OPTIONS';
|
|
298
|
+
// The probe of a producer another process may run
|
|
299
|
+
function getReadyWhenWait(task, projectGraph, projects, workspaceRoot) {
|
|
300
|
+
const inputs = getReadyWhenInputs(task, projectGraph, projects, workspaceRoot);
|
|
301
|
+
return inputs && checkReadyWhen(inputs.readyWhen, task.id, inputs.data);
|
|
302
|
+
}
|
|
303
|
+
// Placeholders resolve against the options the executor receives: aliases,
|
|
304
|
+
// schema defaults and the spelling of command-line overrides applied
|
|
305
|
+
function getReadyWhenInputs(task, projectGraph, projects, workspaceRoot) {
|
|
306
|
+
const readyWhen = getReadyWhenConfig(task, projectGraph);
|
|
307
|
+
if (readyWhen == null) {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
const node = projectGraph.nodes[task.target.project];
|
|
311
|
+
const target = node.data.targets[task.target.target];
|
|
312
|
+
const { schema } = (0, utils_1.getExecutorForTask)(task, projects);
|
|
313
|
+
const options = (0, params_1.combineOptionsForExecutor)(task.overrides, task.target.configuration ?? target.defaultConfiguration, target, schema, task.target.project, (0, path_1.relative)(task.projectRoot ?? workspaceRoot, process.cwd()), process.env.NX_VERBOSE_LOGGING === 'true');
|
|
314
|
+
return {
|
|
315
|
+
readyWhen,
|
|
316
|
+
executor: target.executor,
|
|
317
|
+
data: {
|
|
318
|
+
workspaceRoot,
|
|
319
|
+
projectRoot: node.data.root,
|
|
320
|
+
projectName: node.name,
|
|
321
|
+
options,
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
// Only a signal check reports a URL, which its waiters get as NX_READY_URL
|
|
326
|
+
function mayReportReadyUrl(task, projectGraph) {
|
|
327
|
+
const readyWhen = getReadyWhenConfig(task, projectGraph);
|
|
328
|
+
if (typeof readyWhen !== 'object' || readyWhen === null) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
const kind = PROBE_KEYS.find((key) => readyWhen[key] != null);
|
|
332
|
+
switch (kind) {
|
|
333
|
+
case 'signal':
|
|
334
|
+
return true;
|
|
335
|
+
case 'url':
|
|
336
|
+
case 'port':
|
|
337
|
+
case 'command':
|
|
338
|
+
case 'logMatches':
|
|
339
|
+
case undefined:
|
|
340
|
+
return false;
|
|
341
|
+
default: {
|
|
342
|
+
const unhandled = kind;
|
|
343
|
+
throw new Error(`Unhandled readyWhen check: ${unhandled}`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function getReadyProducerIds(task, taskGraph) {
|
|
348
|
+
return (taskGraph.continuousDependencies[task.id] ?? [])
|
|
349
|
+
.filter((edge) => edge.waitFor === 'ready')
|
|
350
|
+
.map((edge) => edge.id);
|
|
351
|
+
}
|
|
352
|
+
// Producers with a probe that each task waits on; tasks with none are left out
|
|
353
|
+
function getReadyDependencies(taskGraph, projectGraph) {
|
|
354
|
+
const readyDependencies = {};
|
|
355
|
+
for (const task of Object.values(taskGraph.tasks)) {
|
|
356
|
+
const producerIds = getReadyProducerIds(task, taskGraph).filter((id) => getReadyWhenConfig(taskGraph.tasks[id], projectGraph) != null);
|
|
357
|
+
if (producerIds.length > 0) {
|
|
358
|
+
readyDependencies[task.id] = producerIds;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return readyDependencies;
|
|
362
|
+
}
|
|
363
|
+
function isPositiveInteger(value) {
|
|
364
|
+
return Number.isInteger(value) && value > 0;
|
|
365
|
+
}
|
|
366
|
+
function isDuration(value) {
|
|
367
|
+
return isPositiveInteger(value) && value <= MAX_DURATION;
|
|
368
|
+
}
|
|
369
|
+
function isHttpUrl(value) {
|
|
370
|
+
return (URL.canParse(value) && ['http:', 'https:'].includes(new URL(value).protocol));
|
|
371
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveStartupHost(host: string | undefined): string | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveStartupHost = resolveStartupHost;
|
|
4
|
+
const net_1 = require("net");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
// webpack-dev-server and the Rspack dev server resolve these hosts when they
|
|
7
|
+
// start (`Server.getHostname`). A wildcard fallback means loopback to the probe.
|
|
8
|
+
function resolveStartupHost(host) {
|
|
9
|
+
switch (host) {
|
|
10
|
+
case 'local-ip':
|
|
11
|
+
return findIp('IPv4') ?? findIp('IPv6') ?? '0.0.0.0';
|
|
12
|
+
case 'local-ipv4':
|
|
13
|
+
return findIp('IPv4') ?? '0.0.0.0';
|
|
14
|
+
case 'local-ipv6':
|
|
15
|
+
return findIp('IPv6') ?? '::';
|
|
16
|
+
default:
|
|
17
|
+
return host;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// The IPv6 ranges `Server.findIp` accepts: unique local, IPv4-mapped, loopback
|
|
21
|
+
const FIND_IP_V6_RANGES = new net_1.BlockList();
|
|
22
|
+
FIND_IP_V6_RANGES.addSubnet('fc00::', 7, 'ipv6');
|
|
23
|
+
FIND_IP_V6_RANGES.addSubnet('::ffff:0:0', 96, 'ipv6');
|
|
24
|
+
FIND_IP_V6_RANGES.addAddress('::1', 'ipv6');
|
|
25
|
+
function findIp(family) {
|
|
26
|
+
return Object.values((0, os_1.networkInterfaces)())
|
|
27
|
+
.flatMap((addresses) => addresses ?? [])
|
|
28
|
+
.find(({ address, family: addressFamily, internal }) => address &&
|
|
29
|
+
addressFamily === family &&
|
|
30
|
+
!internal &&
|
|
31
|
+
(family === 'IPv4' || FIND_IP_V6_RANGES.check(address, 'ipv6')))?.address;
|
|
32
|
+
}
|