nx 23.3.0-beta.0 → 23.3.0-beta.2

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 (184) hide show
  1. package/dist/src/command-line/format/format.js +2 -18
  2. package/dist/src/command-line/graph/graph.js +42 -3
  3. package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +0 -3
  4. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +0 -3
  5. package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +0 -3
  6. package/dist/src/command-line/init/implementation/angular/index.js +0 -3
  7. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +0 -3
  8. package/dist/src/command-line/init/implementation/format.js +2 -3
  9. package/dist/src/command-line/init/implementation/utils.d.ts +0 -1
  10. package/dist/src/command-line/init/implementation/utils.js +0 -8
  11. package/dist/src/command-line/init/init-v2.js +0 -3
  12. package/dist/src/command-line/migrate/agentic/definitions.js +75 -19
  13. package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
  14. package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
  15. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
  16. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
  17. package/dist/src/command-line/migrate/agentic/handoff.d.ts +27 -17
  18. package/dist/src/command-line/migrate/agentic/handoff.js +107 -24
  19. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +21 -0
  20. package/dist/src/command-line/migrate/agentic/instruction-files.js +36 -0
  21. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +16 -0
  22. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +70 -0
  23. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
  24. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
  25. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
  26. package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
  27. package/dist/src/command-line/migrate/agentic/runner.d.ts +17 -8
  28. package/dist/src/command-line/migrate/agentic/runner.js +110 -55
  29. package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
  30. package/dist/src/command-line/migrate/agentic/types.js +10 -7
  31. package/dist/src/command-line/migrate/migrate-commits.d.ts +1 -0
  32. package/dist/src/command-line/migrate/migrate-commits.js +9 -0
  33. package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
  34. package/dist/src/command-line/migrate/migrate-output.js +3 -7
  35. package/dist/src/command-line/migrate/migrate.js +21 -8
  36. package/dist/src/command-line/migrate/run/agent-output.d.ts +10 -0
  37. package/dist/src/command-line/migrate/run/agent-output.js +16 -2
  38. package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
  39. package/dist/src/command-line/migrate/run/agent-work-payload.js +142 -0
  40. package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
  41. package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
  42. package/dist/src/command-line/migrate/run/index.d.ts +1 -1
  43. package/dist/src/command-line/migrate/run/issues.d.ts +106 -0
  44. package/dist/src/command-line/migrate/run/issues.js +980 -0
  45. package/dist/src/command-line/migrate/run/orchestrator.d.ts +1 -0
  46. package/dist/src/command-line/migrate/run/orchestrator.js +662 -105
  47. package/dist/src/command-line/migrate/run/run-state.d.ts +43 -8
  48. package/dist/src/command-line/migrate/run/run-state.js +184 -20
  49. package/dist/src/command-line/migrate/run/runbook.d.ts +17 -0
  50. package/dist/src/command-line/migrate/run/runbook.js +97 -0
  51. package/dist/src/command-line/migrate/run/state-lock.d.ts +2 -2
  52. package/dist/src/command-line/migrate/run/state-lock.js +2 -2
  53. package/dist/src/command-line/migrate/run/state-machine.d.ts +5 -1
  54. package/dist/src/command-line/migrate/run/state-machine.js +27 -1
  55. package/dist/src/command-line/migrate/run/worker.js +206 -56
  56. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -11
  57. package/dist/src/command-line/release/publish.js +11 -4
  58. package/dist/src/command-line/release/utils/remote-release-clients/github.js +3 -3
  59. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
  60. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +2 -0
  61. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +35 -0
  62. package/dist/src/command-line/report/report.d.ts +2 -0
  63. package/dist/src/command-line/report/report.js +28 -1
  64. package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  65. package/dist/src/command-line/yargs-utils/shared-options.js +22 -4
  66. package/dist/src/config/workspace-json-project-json.d.ts +2 -0
  67. package/dist/src/core/graph/main.js +1 -1
  68. package/dist/src/daemon/client/client.d.ts +6 -2
  69. package/dist/src/daemon/client/client.js +27 -11
  70. package/dist/src/daemon/message-types/get-plugin-capabilities.d.ts +5 -0
  71. package/dist/src/daemon/message-types/get-plugin-capabilities.js +11 -0
  72. package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
  73. package/dist/src/daemon/server/handle-get-plugin-capabilities.d.ts +2 -0
  74. package/dist/src/daemon/server/handle-get-plugin-capabilities.js +13 -0
  75. package/dist/src/daemon/server/handle-hash-tasks.d.ts +8 -2
  76. package/dist/src/daemon/server/handle-hash-tasks.js +16 -3
  77. package/dist/src/daemon/server/handle-outputs-changes.d.ts +2 -2
  78. package/dist/src/daemon/server/handle-outputs-changes.js +21 -6
  79. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
  80. package/dist/src/daemon/server/outputs-tracking.d.ts +6 -0
  81. package/dist/src/daemon/server/outputs-tracking.js +18 -0
  82. package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
  83. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +100 -70
  84. package/dist/src/daemon/server/restart-checks.d.ts +22 -0
  85. package/dist/src/daemon/server/restart-checks.js +77 -0
  86. package/dist/src/daemon/server/server.js +33 -18
  87. package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
  88. package/dist/src/daemon/server/shutdown-utils.js +3 -26
  89. package/dist/src/hasher/hash-task.js +20 -16
  90. package/dist/src/hasher/native-task-hasher-impl.d.ts +8 -0
  91. package/dist/src/hasher/native-task-hasher-impl.js +46 -3
  92. package/dist/src/hasher/task-hasher.d.ts +9 -0
  93. package/dist/src/hasher/task-hasher.js +14 -0
  94. package/dist/src/native/index.d.ts +222 -21
  95. package/dist/src/native/index.js +3 -3
  96. package/dist/src/native/native-bindings.js +4 -1
  97. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  98. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  99. package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
  100. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
  101. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
  102. package/dist/src/plugins/js/utils/register.js +2 -1
  103. package/dist/src/project-graph/affected/locators/project-glob-changes.js +19 -26
  104. package/dist/src/project-graph/error-types.d.ts +5 -0
  105. package/dist/src/project-graph/error-types.js +44 -5
  106. package/dist/src/project-graph/file-utils.d.ts +2 -0
  107. package/dist/src/project-graph/file-utils.js +6 -1
  108. package/dist/src/project-graph/nx-deps-cache.d.ts +5 -2
  109. package/dist/src/project-graph/nx-deps-cache.js +4 -4
  110. package/dist/src/project-graph/plugins/get-plugins.d.ts +3 -1
  111. package/dist/src/project-graph/plugins/get-plugins.js +60 -82
  112. package/dist/src/project-graph/plugins/in-process-loader.d.ts +1 -1
  113. package/dist/src/project-graph/plugins/in-process-loader.js +1 -4
  114. package/dist/src/project-graph/plugins/isolation/index.d.ts +1 -1
  115. package/dist/src/project-graph/plugins/isolation/index.js +3 -1
  116. package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +8 -0
  117. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +42 -6
  118. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.d.ts +10 -1
  119. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.js +67 -17
  120. package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
  121. package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
  122. package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +5 -2
  123. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +14 -1
  124. package/dist/src/project-graph/plugins/nx-plugin-capabilities.d.ts +6 -0
  125. package/dist/src/project-graph/plugins/nx-plugin-capabilities.js +28 -0
  126. package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
  127. package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
  128. package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
  129. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +14 -1
  130. package/dist/src/project-graph/project-graph.js +43 -42
  131. package/dist/src/tasks-runner/batch/run-batch.js +15 -0
  132. package/dist/src/tasks-runner/cache.d.ts +35 -0
  133. package/dist/src/tasks-runner/cache.js +40 -0
  134. package/dist/src/tasks-runner/create-task-graph.js +1 -0
  135. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  136. package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
  137. package/dist/src/tasks-runner/forked-process-task-runner.js +8 -7
  138. package/dist/src/tasks-runner/init-tasks-runner.js +5 -1
  139. package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
  140. package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
  141. package/dist/src/tasks-runner/life-cycle.js +7 -0
  142. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
  143. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
  144. package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
  145. package/dist/src/tasks-runner/prune-task-graph.js +45 -0
  146. package/dist/src/tasks-runner/run-command.js +14 -3
  147. package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
  148. package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
  149. package/dist/src/tasks-runner/task-orchestrator.d.ts +64 -2
  150. package/dist/src/tasks-runner/task-orchestrator.js +232 -46
  151. package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
  152. package/dist/src/tasks-runner/terminal-output-path.js +18 -0
  153. package/dist/src/tasks-runner/utils.js +5 -2
  154. package/dist/src/utils/ab-testing.d.ts +4 -1
  155. package/dist/src/utils/ab-testing.js +11 -7
  156. package/dist/src/utils/chunkify.d.ts +1 -7
  157. package/dist/src/utils/chunkify.js +2 -8
  158. package/dist/src/utils/command-line-utils.d.ts +19 -0
  159. package/dist/src/utils/command-line-utils.js +10 -3
  160. package/dist/src/utils/formatters/index.d.ts +6 -0
  161. package/dist/src/utils/formatters/index.js +5 -0
  162. package/dist/src/utils/formatters/prettier.d.ts +0 -8
  163. package/dist/src/utils/formatters/prettier.js +4 -26
  164. package/dist/src/utils/handle-errors.js +5 -43
  165. package/dist/src/utils/installed-nx-version.js +2 -48
  166. package/dist/src/utils/min-release-age/packument.js +1 -1
  167. package/dist/src/utils/output.d.ts +22 -3
  168. package/dist/src/utils/output.js +28 -5
  169. package/dist/src/utils/package-json.d.ts +25 -0
  170. package/dist/src/utils/package-json.js +41 -6
  171. package/dist/src/utils/package-manager.d.ts +6 -0
  172. package/dist/src/utils/package-manager.js +10 -0
  173. package/dist/src/utils/plugins/plugin-capabilities.js +7 -2
  174. package/dist/src/utils/provenance.js +20 -4
  175. package/dist/src/utils/serialize-overrides-into-command-line.js +2 -4
  176. package/dist/src/utils/workspace-context.d.ts +47 -3
  177. package/dist/src/utils/workspace-context.js +162 -10
  178. package/package.json +12 -13
  179. package/schemas/nx-schema.json +4 -0
  180. package/schemas/project-schema.json +4 -0
  181. package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
  182. package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
  183. package/dist/src/daemon/server/watcher.d.ts +0 -18
  184. package/dist/src/daemon/server/watcher.js +0 -126
@@ -198,12 +198,13 @@ function getUncommittedFiles() {
198
198
  '--name-only',
199
199
  '--no-renames',
200
200
  '--relative',
201
+ '-z',
201
202
  'HEAD',
202
203
  '.',
203
204
  ]);
204
205
  }
205
206
  function getUntrackedFiles() {
206
- return parseGitOutput(['ls-files', '--others', '--exclude-standard']);
207
+ return parseGitOutput(['ls-files', '--others', '--exclude-standard', '-z']);
207
208
  }
208
209
  function getMergeBase(base, head = 'HEAD') {
209
210
  (0, git_revision_1.assertValidGitRevision)(base);
@@ -230,6 +231,7 @@ function getFilesUsingBaseAndHead(base, head) {
230
231
  '--name-only',
231
232
  '--no-renames',
232
233
  '--relative',
234
+ '-z',
233
235
  base,
234
236
  head,
235
237
  ]);
@@ -242,11 +244,16 @@ function runGit(args) {
242
244
  windowsHide: true,
243
245
  });
244
246
  }
247
+ /**
248
+ * Parses NUL-terminated paths, so callers must pass `-z`, and must pass it
249
+ * before the pathspec — git fatals on a `-z` that follows one. Without `-z` git
250
+ * escapes paths that contain non-ASCII or quoting characters, and honours
251
+ * `core.quotepath`, which is on by default.
252
+ */
245
253
  function parseGitOutput(args) {
246
254
  return runGit(args)
247
255
  .toString('utf-8')
248
- .split('\n')
249
- .map((a) => a.trim())
256
+ .split('\0')
250
257
  .filter((a) => a.length > 0);
251
258
  }
252
259
  function getProjectRoots(projectNames, { nodes }) {
@@ -1,4 +1,6 @@
1
1
  import type { Tree } from '../../generators/tree';
2
+ import { getOxfmtBinPath } from './oxfmt';
3
+ import { getPrettierPath } from './prettier';
2
4
  /**
3
5
  * Adding a member here does NOT reliably break compilation: the repo builds
4
6
  * with `strict: false`, so a `switch` that omits one is not an error. The
@@ -7,6 +9,10 @@ import type { Tree } from '../../generators/tree';
7
9
  * its emitted declarations, so those only fail once it has been rebuilt.
8
10
  */
9
11
  export type FormatterType = 'prettier' | 'oxfmt';
12
+ export declare const resolveFormatterBin: {
13
+ oxfmt: typeof getOxfmtBinPath;
14
+ prettier: typeof getPrettierPath;
15
+ };
10
16
  /** Test-only: the warn-once flag is module state and would leak between cases. */
11
17
  export declare function resetFormatterWarningsForTesting(): void;
12
18
  export declare function detectFormatter(root: string): FormatterType | null;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveFormatterBin = void 0;
3
4
  exports.resetFormatterWarningsForTesting = resetFormatterWarningsForTesting;
4
5
  exports.detectFormatter = detectFormatter;
5
6
  exports.detectFormatterInTree = detectFormatterInTree;
@@ -10,6 +11,10 @@ const fileutils_1 = require("../fileutils");
10
11
  const oxfmt_1 = require("./oxfmt");
11
12
  const prettier_1 = require("./prettier");
12
13
  const logger_1 = require("../logger");
14
+ exports.resolveFormatterBin = {
15
+ oxfmt: oxfmt_1.getOxfmtBinPath,
16
+ prettier: prettier_1.getPrettierPath,
17
+ };
13
18
  // Once per process: detection runs on every one of 200+ `formatFiles` call sites.
14
19
  let warnedBothConfigured = false;
15
20
  function warnBothConfigured() {
@@ -16,11 +16,3 @@ export declare function filterToPrettierSupportedFiles(files: string[]): Promise
16
16
  export declare function writeWithPrettier(patterns: string[], cwd?: string): void;
17
17
  export declare function checkWithPrettier(patterns: string[]): Promise<string[]>;
18
18
  export declare function getPrettierPath(): string;
19
- /**
20
- * Quote a pattern for prettier's shell-based exec calls; oxfmt uses execFile
21
- * and takes raw paths.
22
- *
23
- * Exported so `nx format` can size its chunks against the quoted length -
24
- * patterns are chunked before they get here, and quoting grows each one.
25
- */
26
- export declare function quoteForShell(pattern: string): string;
@@ -7,7 +7,6 @@ exports.filterToPrettierSupportedFiles = filterToPrettierSupportedFiles;
7
7
  exports.writeWithPrettier = writeWithPrettier;
8
8
  exports.checkWithPrettier = checkWithPrettier;
9
9
  exports.getPrettierPath = getPrettierPath;
10
- exports.quoteForShell = quoteForShell;
11
10
  const node_child_process_1 = require("node:child_process");
12
11
  const node_fs_1 = require("node:fs");
13
12
  const node_path_1 = require("node:path");
@@ -98,19 +97,17 @@ cwd) {
98
97
  if (patterns.length === 0) {
99
98
  // Prettier with no file arguments reads stdin, and `stdio: [0, 1, 2]` hands
100
99
  // it nx's own - from a terminal it blocks forever with nothing on screen. At
101
- // EOF it exits 0 under `--list-different` and 2 (which `execSync` throws on)
100
+ // EOF it exits 0 under `--list-different` and 2 (which `execFileSync` throws on)
102
101
  // without it, so which failure you get depends on `shouldUseListDifferent`.
103
102
  return;
104
103
  }
105
104
  const prettierPath = getPrettierPath();
106
- const listDifferentArg = shouldUseListDifferent() ? '--list-different ' : '';
105
+ const listDifferentArg = shouldUseListDifferent() ? ['--list-different'] : [];
107
106
  // No `--parser json` special case for `.swcrc`: prettier's own language table
108
107
  // maps it to the json parser, so it formats correctly on its own (measured).
109
108
  // Splitting the batch also meant one of the two spawns could receive zero
110
109
  // files, which is the error above.
111
- (0, node_child_process_1.execSync)(`node ${quoteForShell(prettierPath)} --write ${listDifferentArg}-- ${patterns
112
- .map(quoteForShell)
113
- .join(' ')}`, {
110
+ (0, node_child_process_1.execFileSync)(process.execPath, [prettierPath, '--write', ...listDifferentArg, '--', ...patterns], {
114
111
  cwd,
115
112
  stdio: [0, 1, 2],
116
113
  windowsHide: true,
@@ -119,9 +116,7 @@ cwd) {
119
116
  function checkWithPrettier(patterns) {
120
117
  const prettierPath = getPrettierPath();
121
118
  return new Promise((resolve, reject) => {
122
- (0, node_child_process_1.exec)(`node ${quoteForShell(prettierPath)} --list-different -- ${patterns
123
- .map(quoteForShell)
124
- .join(' ')}`, { encoding: 'utf-8', windowsHide: true, maxBuffer: shared_1.FORMATTER_MAX_BUFFER }, (error, stdout) => {
119
+ (0, node_child_process_1.execFile)(process.execPath, [prettierPath, '--list-different', '--', ...patterns], { encoding: 'utf-8', windowsHide: true, maxBuffer: shared_1.FORMATTER_MAX_BUFFER }, (error, stdout) => {
125
120
  if (error) {
126
121
  // As the oxfmt sibling: a spawn failure, kill or maxBuffer overrun reports a
127
122
  // string `code` or none. Prettier signals "files differ" numerically, so
@@ -182,20 +177,3 @@ function shouldUseListDifferent() {
182
177
  }
183
178
  return useListDifferent;
184
179
  }
185
- /**
186
- * Quote a pattern for prettier's shell-based exec calls; oxfmt uses execFile
187
- * and takes raw paths.
188
- *
189
- * Exported so `nx format` can size its chunks against the quoted length -
190
- * patterns are chunked before they get here, and quoting grows each one.
191
- */
192
- function quoteForShell(pattern) {
193
- // Interpolated into a command string, so every character special *inside
194
- // double quotes* needs escaping, not just `$`: a backtick substitutes, `"`
195
- // closes the quoting, `\` escapes what follows. One pass over the original,
196
- // since `String.replace` never re-scans what it inserted.
197
- const escaped = process.platform !== 'win32'
198
- ? pattern.replace(/([\\"`$])/g, '\\$1')
199
- : pattern;
200
- return `"${escaped}"`;
201
- }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleErrors = handleErrors;
4
+ const error_types_1 = require("../project-graph/error-types");
4
5
  const logger_1 = require("./logger");
5
6
  const output_1 = require("./output");
6
7
  const handle_import_1 = require("./handle-import");
@@ -17,35 +18,9 @@ async function handleErrors(isVerbose, fn) {
17
18
  if (err.constructor.name === 'UnsuccessfulWorkflowExecution') {
18
19
  logger_1.logger.error('The generator workflow failed. See above.');
19
20
  }
20
- else if (err.name === 'ProjectGraphError') {
21
- const projectGraphError = err;
22
- let title = projectGraphError.message;
23
- if (projectGraphError.cause &&
24
- typeof projectGraphError.cause === 'object' &&
25
- 'message' in projectGraphError.cause) {
26
- title += ' ' + projectGraphError.cause.message + '.';
27
- }
28
- output_1.output.error({
29
- title,
30
- bodyLines: isVerbose
31
- ? formatErrorStackAndCause(projectGraphError, isVerbose)
32
- : projectGraphError.getErrors().map((e) => e.message),
33
- });
34
- }
35
- else if (err.name === 'ProjectConfigurationsError') {
36
- const projectConfigurationsError = err;
37
- let title = projectConfigurationsError.message;
38
- if (projectConfigurationsError.cause &&
39
- typeof projectConfigurationsError.cause === 'object' &&
40
- 'message' in projectConfigurationsError.cause) {
41
- title += ' ' + projectConfigurationsError.cause.message + '.';
42
- }
43
- output_1.output.error({
44
- title,
45
- bodyLines: isVerbose
46
- ? formatErrorStackAndCause(projectConfigurationsError, isVerbose)
47
- : projectConfigurationsError.errors.map((e) => e.message),
48
- });
21
+ else if (err.name === 'ProjectGraphError' ||
22
+ err.name === 'ProjectConfigurationsError') {
23
+ output_1.output.error((0, error_types_1.formatProjectGraphError)(err, isVerbose));
49
24
  }
50
25
  else if (err.name === 'MinReleaseAgeViolationError') {
51
26
  // A cooldown violation already carries a user-shaped headline plus
@@ -59,7 +34,7 @@ async function handleErrors(isVerbose, fn) {
59
34
  const lines = (err.message ? err.message : err.toString()).split('\n');
60
35
  const bodyLines = lines.slice(1);
61
36
  if (isVerbose) {
62
- bodyLines.push(...formatErrorStackAndCause(err, isVerbose));
37
+ bodyLines.push((0, error_types_1.formatErrorStackAndCause)(err));
63
38
  }
64
39
  else if (err.stack) {
65
40
  bodyLines.push('Pass --verbose to see the stacktrace.');
@@ -76,16 +51,3 @@ async function handleErrors(isVerbose, fn) {
76
51
  return 1;
77
52
  }
78
53
  }
79
- function formatErrorStackAndCause(error, verbose) {
80
- return [
81
- verbose ? error.stack || error.message : error.message,
82
- ...(error.cause && typeof error.cause === 'object'
83
- ? [
84
- 'Caused by:',
85
- verbose && 'stack' in error.cause
86
- ? error.cause.stack.toString()
87
- : error.cause.toString(),
88
- ]
89
- : []),
90
- ];
91
- }
@@ -4,8 +4,6 @@ exports.getInstalledVersion = getInstalledVersion;
4
4
  exports.getInstalledNxVersion = getInstalledNxVersion;
5
5
  exports.getInstalledLegacyNrwlWorkspaceVersion = getInstalledLegacyNrwlWorkspaceVersion;
6
6
  exports.getInstalledPackageGroup = getInstalledPackageGroup;
7
- const tslib_1 = require("tslib");
8
- const node_module_1 = tslib_1.__importStar(require("node:module"));
9
7
  const fileutils_1 = require("./fileutils");
10
8
  const package_json_1 = require("./package-json");
11
9
  const workspace_root_1 = require("./workspace-root");
@@ -15,15 +13,11 @@ const installation_directory_1 = require("./installation-directory");
15
13
  * resolver. The resolver always reflects the workspace's `node_modules`/PnP
16
14
  * store rather than whichever copy happens to be loaded in the current process
17
15
  * (e.g. the temp `nx@latest` install used by the migrate bootstrap). See
18
- * nrwl/nx#35444 and `resolvePackageJsonWithoutCachePollution` below.
16
+ * nrwl/nx#35444 and `resolveWithoutCachePollution`.
19
17
  */
20
18
  function readInstalledPackageJson(packageName) {
21
- const path = resolvePackageJsonWithoutCachePollution(packageName, (0, installation_directory_1.getNxRequirePaths)(workspace_root_1.workspaceRoot));
22
- if (!path) {
23
- return null;
24
- }
25
19
  try {
26
- return (0, fileutils_1.readJsonFile)(path);
20
+ return (0, fileutils_1.readJsonFile)((0, package_json_1.resolveWithoutCachePollution)(`${packageName}/package.json`, (0, installation_directory_1.getNxRequirePaths)(workspace_root_1.workspaceRoot)));
27
21
  }
28
22
  catch {
29
23
  return null;
@@ -71,43 +65,3 @@ function getInstalledPackageGroup(packageName) {
71
65
  }
72
66
  return set;
73
67
  }
74
- /**
75
- * Resolve `<packageName>/package.json` via Node's CJS resolver while
76
- * neutralising both ways `require.resolve(req, { paths })` can lie about
77
- * the `paths` argument:
78
- *
79
- * 1. Process-wide `Module._pathCache` — swapped out for the duration of
80
- * the call, so any cache entries written are discarded and any
81
- * previously-poisoned entries are not read. Without this, an
82
- * in-process load of a second `nx` package (e.g. the temp `nx@latest`
83
- * install used by the daemon's AI-agents and console-status checks)
84
- * can poison the cache key this call uses and make us read the temp
85
- * path instead of the workspace path.
86
- *
87
- * 2. Package self-reference — when a file inside package `nx` calls
88
- * `require.resolve('nx/...')`, Node returns that calling package's
89
- * own file regardless of `paths`. We avoid that by issuing the
90
- * resolve from a `createRequire` rooted at a synthetic path that is
91
- * outside any package, so the resolver has no "self" to reference
92
- * and must honour `paths`.
93
- *
94
- * Node's single-threaded synchronous execution means `require.resolve` does
95
- * not yield, so no other code in the process can observe the swapped cache.
96
- */
97
- function resolvePackageJsonWithoutCachePollution(packageName, requirePaths) {
98
- // `_pathCache` is an internal Node API not exposed in @types/node.
99
- const realCache = node_module_1.default._pathCache;
100
- node_module_1.default._pathCache = Object.create(null);
101
- try {
102
- const detachedRequire = (0, node_module_1.createRequire)('/__nx_detached_resolver__/x.js');
103
- return detachedRequire.resolve(`${packageName}/package.json`, {
104
- paths: requirePaths,
105
- });
106
- }
107
- catch {
108
- return null;
109
- }
110
- finally {
111
- node_module_1.default._pathCache = realCache;
112
- }
113
- }
@@ -17,7 +17,7 @@ function toArray(value) {
17
17
  */
18
18
  async function fetchRegistryMetadata(pkg) {
19
19
  const raw = await (0, package_manager_1.packageRegistryView)(pkg, '', ['--json']);
20
- const parsed = JSON.parse(raw);
20
+ const parsed = (0, package_manager_1.parseRegistryViewJson)(raw);
21
21
  const time = parsed.time ?? null;
22
22
  if (time) {
23
23
  // The time map carries 'created'/'modified' alongside versions; they are
@@ -12,14 +12,33 @@ export type CollapsibleTaskStatus = Extract<TaskStatus, 'success' | 'local-cache
12
12
  * routed, the two behave identically.
13
13
  */
14
14
  export declare function isStaticOutputStyle(outputStyle: string | undefined): boolean;
15
+ /**
16
+ * Whether a style puts task output on the terminal at all.
17
+ *
18
+ * `summary` does not - it prints a status line and the path to each task's log,
19
+ * deliberately addressing the output instead of reproducing it. So every
20
+ * decision that would put a task's bytes on the terminal has to consult this
21
+ * first, including ones that bypass the life cycle: both batch folds and
22
+ * `BatchProcess`'s live forward write to `output` directly, and under `summary`
23
+ * each would dump exactly what the style exists to keep off the screen.
24
+ *
25
+ * Withholding is only half of it. Whatever a caller suppresses here has to be
26
+ * readable somewhere else, because the style's contract is that the output
27
+ * moved, not that it is gone - `BatchProcess` captures to a file rather than
28
+ * dropping, and `runBatch` hands its path to the life cycle.
29
+ */
30
+ export declare function printsTaskOutput(outputStyle: string | undefined): boolean;
15
31
  /**
16
32
  * Whether a run prints every task's output in full rather than collapsing the
17
33
  * ones that succeeded. Both static life cycles and the batch renderer have to
18
34
  * agree on this, so they read it from here rather than each deriving it.
19
35
  *
20
- * Exactly one style collapses, and it is also what a run that named no style
21
- * gets. Every other style prints in full because it was asked for explicitly,
22
- * so none may quietly withhold output. Note the static life cycles serve more
36
+ * Two styles collapse. `static-failures-only` shows only what failed, and is
37
+ * what a run that named no style gets; `summary` withholds task output
38
+ * altogether, addressing each log by path instead, and outranks `verbose` -
39
+ * asking for more detail cannot turn a style whose whole contract is "the
40
+ * output is on disk" back into one that prints. Every other style prints in
41
+ * full because it was asked for explicitly. Note the static life cycles serve more
23
42
  * styles than the static-sounding ones: `shouldUseDynamicLifeCycle` bails on
24
43
  * `isCI()` before it looks at the style at all, so in CI `dynamic` and `tui`
25
44
  * land here too. This is written as a deny-list for that reason — a new style
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.output = void 0;
4
4
  exports.isStaticOutputStyle = isStaticOutputStyle;
5
+ exports.printsTaskOutput = printsTaskOutput;
5
6
  exports.printsFullTaskOutput = printsFullTaskOutput;
6
7
  exports.isLogGroupingEnabled = isLogGroupingEnabled;
7
8
  exports.shouldGroupBatchOutput = shouldGroupBatchOutput;
@@ -23,14 +24,35 @@ const GH_GROUP_SUFFIX = '::endgroup::';
23
24
  function isStaticOutputStyle(outputStyle) {
24
25
  return outputStyle === 'static' || outputStyle === 'static-failures-only';
25
26
  }
27
+ /**
28
+ * Whether a style puts task output on the terminal at all.
29
+ *
30
+ * `summary` does not - it prints a status line and the path to each task's log,
31
+ * deliberately addressing the output instead of reproducing it. So every
32
+ * decision that would put a task's bytes on the terminal has to consult this
33
+ * first, including ones that bypass the life cycle: both batch folds and
34
+ * `BatchProcess`'s live forward write to `output` directly, and under `summary`
35
+ * each would dump exactly what the style exists to keep off the screen.
36
+ *
37
+ * Withholding is only half of it. Whatever a caller suppresses here has to be
38
+ * readable somewhere else, because the style's contract is that the output
39
+ * moved, not that it is gone - `BatchProcess` captures to a file rather than
40
+ * dropping, and `runBatch` hands its path to the life cycle.
41
+ */
42
+ function printsTaskOutput(outputStyle) {
43
+ return outputStyle !== 'summary';
44
+ }
26
45
  /**
27
46
  * Whether a run prints every task's output in full rather than collapsing the
28
47
  * ones that succeeded. Both static life cycles and the batch renderer have to
29
48
  * agree on this, so they read it from here rather than each deriving it.
30
49
  *
31
- * Exactly one style collapses, and it is also what a run that named no style
32
- * gets. Every other style prints in full because it was asked for explicitly,
33
- * so none may quietly withhold output. Note the static life cycles serve more
50
+ * Two styles collapse. `static-failures-only` shows only what failed, and is
51
+ * what a run that named no style gets; `summary` withholds task output
52
+ * altogether, addressing each log by path instead, and outranks `verbose` -
53
+ * asking for more detail cannot turn a style whose whole contract is "the
54
+ * output is on disk" back into one that prints. Every other style prints in
55
+ * full because it was asked for explicitly. Note the static life cycles serve more
34
56
  * styles than the static-sounding ones: `shouldUseDynamicLifeCycle` bails on
35
57
  * `isCI()` before it looks at the style at all, so in CI `dynamic` and `tui`
36
58
  * land here too. This is written as a deny-list for that reason — a new style
@@ -43,8 +65,9 @@ function isStaticOutputStyle(outputStyle) {
43
65
  * ever being consulted — including for the continuous tasks that must stream.
44
66
  */
45
67
  function printsFullTaskOutput(args) {
46
- return (!!args.verbose ||
47
- (args.outputStyle ?? 'static-failures-only') !== 'static-failures-only');
68
+ return (printsTaskOutput(args.outputStyle) &&
69
+ (!!args.verbose ||
70
+ (args.outputStyle ?? 'static-failures-only') !== 'static-failures-only'));
48
71
  }
49
72
  /**
50
73
  * Whether task output should be wrapped in collapsible log groups. Grouping
@@ -143,6 +143,31 @@ export declare function readModulePackageJson(moduleSpecifier: string, requirePa
143
143
  packageJson: PackageJson;
144
144
  path: string;
145
145
  };
146
+ /**
147
+ * Resolve `request` via Node's CJS resolver while neutralising both ways
148
+ * `require.resolve(req, { paths })` can lie about the `paths` argument:
149
+ *
150
+ * 1. Process-wide `Module._pathCache`. It is swapped out for the duration
151
+ * of the call, so any cache entries written are discarded and any
152
+ * previously-poisoned entries are not read. Without this, an
153
+ * in-process load of a second `nx` package (e.g. the temp `nx@latest`
154
+ * install used by the daemon's AI-agents and console-status checks)
155
+ * can poison the cache key this call uses and make us read the temp
156
+ * path instead of the workspace path.
157
+ *
158
+ * 2. Package self-reference. When a file inside package `nx` calls
159
+ * `require.resolve('nx/...')`, Node returns that calling package's
160
+ * own file regardless of `paths`. We avoid that by issuing the
161
+ * resolve from a `createRequire` rooted at a synthetic path that is
162
+ * outside any package, so the resolver has no "self" to reference
163
+ * and must honour `paths`.
164
+ *
165
+ * Node's single-threaded synchronous execution means `require.resolve` does
166
+ * not yield, so no other code in the process can observe the swapped cache.
167
+ *
168
+ * Throws like `require.resolve` when nothing matches.
169
+ */
170
+ export declare function resolveWithoutCachePollution(request: string, requirePaths: string[]): string;
146
171
  export declare function installPackageToTmp(pkg: string, requiredVersion: string, packageManager: PackageManager): {
147
172
  tempDir: string;
148
173
  cleanup: () => void;
@@ -8,12 +8,15 @@ exports.getTagsFromPackageJson = getTagsFromPackageJson;
8
8
  exports.readTargetsFromPackageJson = readTargetsFromPackageJson;
9
9
  exports.readModulePackageJsonWithoutFallbacks = readModulePackageJsonWithoutFallbacks;
10
10
  exports.readModulePackageJson = readModulePackageJson;
11
+ exports.resolveWithoutCachePollution = resolveWithoutCachePollution;
11
12
  exports.installPackageToTmp = installPackageToTmp;
12
13
  exports.installPackageToTmpAsync = installPackageToTmpAsync;
13
14
  exports.getDependencyVersionFromPackageJson = getDependencyVersionFromPackageJson;
15
+ const tslib_1 = require("tslib");
14
16
  const child_process_1 = require("child_process");
15
17
  const util_1 = require("util");
16
18
  const fs_1 = require("fs");
19
+ const node_module_1 = tslib_1.__importStar(require("node:module"));
17
20
  const path_1 = require("path");
18
21
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
19
22
  const tmp_1 = require("tmp");
@@ -169,9 +172,7 @@ function readTargetsFromPackageJson(packageJson, nxJson, projectRoot, workspaceR
169
172
  * @returns package json contents and path
170
173
  */
171
174
  function readModulePackageJsonWithoutFallbacks(moduleSpecifier, requirePaths = (0, installation_directory_1.getNxRequirePaths)()) {
172
- const packageJsonPath = require.resolve(`${moduleSpecifier}/package.json`, {
173
- paths: requirePaths,
174
- });
175
+ const packageJsonPath = resolveWithoutCachePollution(`${moduleSpecifier}/package.json`, requirePaths);
175
176
  const packageJson = (0, fileutils_1.readJsonFile)(packageJsonPath);
176
177
  return {
177
178
  path: packageJsonPath,
@@ -200,9 +201,7 @@ function readModulePackageJson(moduleSpecifier, requirePaths = (0, installation_
200
201
  readModulePackageJsonWithoutFallbacks(moduleSpecifier, requirePaths));
201
202
  }
202
203
  catch {
203
- const entryPoint = require.resolve(moduleSpecifier, {
204
- paths: requirePaths,
205
- });
204
+ const entryPoint = resolveWithoutCachePollution(moduleSpecifier, requirePaths);
206
205
  let moduleRootPath = (0, path_1.dirname)(entryPoint);
207
206
  packageJsonPath = (0, path_1.join)(moduleRootPath, 'package.json');
208
207
  while (!(0, fs_1.existsSync)(packageJsonPath)) {
@@ -219,6 +218,42 @@ function readModulePackageJson(moduleSpecifier, requirePaths = (0, installation_
219
218
  path: packageJsonPath,
220
219
  };
221
220
  }
221
+ /**
222
+ * Resolve `request` via Node's CJS resolver while neutralising both ways
223
+ * `require.resolve(req, { paths })` can lie about the `paths` argument:
224
+ *
225
+ * 1. Process-wide `Module._pathCache`. It is swapped out for the duration
226
+ * of the call, so any cache entries written are discarded and any
227
+ * previously-poisoned entries are not read. Without this, an
228
+ * in-process load of a second `nx` package (e.g. the temp `nx@latest`
229
+ * install used by the daemon's AI-agents and console-status checks)
230
+ * can poison the cache key this call uses and make us read the temp
231
+ * path instead of the workspace path.
232
+ *
233
+ * 2. Package self-reference. When a file inside package `nx` calls
234
+ * `require.resolve('nx/...')`, Node returns that calling package's
235
+ * own file regardless of `paths`. We avoid that by issuing the
236
+ * resolve from a `createRequire` rooted at a synthetic path that is
237
+ * outside any package, so the resolver has no "self" to reference
238
+ * and must honour `paths`.
239
+ *
240
+ * Node's single-threaded synchronous execution means `require.resolve` does
241
+ * not yield, so no other code in the process can observe the swapped cache.
242
+ *
243
+ * Throws like `require.resolve` when nothing matches.
244
+ */
245
+ function resolveWithoutCachePollution(request, requirePaths) {
246
+ // `_pathCache` is an internal Node API not exposed in @types/node.
247
+ const realCache = node_module_1.default._pathCache;
248
+ node_module_1.default._pathCache = Object.create(null);
249
+ try {
250
+ const detachedRequire = (0, node_module_1.createRequire)('/__nx_detached_resolver__/x.js');
251
+ return detachedRequire.resolve(request, { paths: requirePaths });
252
+ }
253
+ finally {
254
+ node_module_1.default._pathCache = realCache;
255
+ }
256
+ }
222
257
  /**
223
258
  * Prepares all necessary information for installing a package to a temporary directory.
224
259
  * This is used by both sync and async installation functions.
@@ -130,6 +130,12 @@ export declare function getWorkspaceRegistryUrlForDisplay(pkg: string): string |
130
130
  export declare function packageRegistryView(pkg: string, version: string, args: string[], options?: {
131
131
  forceNpm?: boolean;
132
132
  }): Promise<string>;
133
+ /**
134
+ * Parses `npm view --json` output. npm 12 wraps the result in an array even
135
+ * when a single version matches; npm <= 11 and pnpm print the bare value. A
136
+ * multi-version match (range spec) stays an array.
137
+ */
138
+ export declare function parseRegistryViewJson<T = unknown>(raw: string): T;
133
139
  /**
134
140
  * Only `npm pack` supports downloading a tarball of a specified remote
135
141
  * package. `yarn` packs the active workspace, `pnpm pack` only packs
@@ -15,6 +15,7 @@ exports.resolvePackageVersionUsingRegistry = resolvePackageVersionUsingRegistry;
15
15
  exports.resolvePackageVersionUsingInstallation = resolvePackageVersionUsingInstallation;
16
16
  exports.getWorkspaceRegistryUrlForDisplay = getWorkspaceRegistryUrlForDisplay;
17
17
  exports.packageRegistryView = packageRegistryView;
18
+ exports.parseRegistryViewJson = parseRegistryViewJson;
18
19
  exports.packageRegistryPack = packageRegistryPack;
19
20
  exports.clearPackageManagerVersionCache = clearPackageManagerVersionCache;
20
21
  exports.getPackageWorkspaces = getPackageWorkspaces;
@@ -705,6 +706,15 @@ options) {
705
706
  throw redactErrorCause(e);
706
707
  }
707
708
  }
709
+ /**
710
+ * Parses `npm view --json` output. npm 12 wraps the result in an array even
711
+ * when a single version matches; npm <= 11 and pnpm print the bare value. A
712
+ * multi-version match (range spec) stays an array.
713
+ */
714
+ function parseRegistryViewJson(raw) {
715
+ const parsed = JSON.parse(raw);
716
+ return Array.isArray(parsed) && parsed.length === 1 ? parsed[0] : parsed;
717
+ }
708
718
  /**
709
719
  * Only `npm pack` supports downloading a tarball of a specified remote
710
720
  * package. `yarn` packs the active workspace, `pnpm pack` only packs
@@ -63,12 +63,17 @@ async function tryGetModule(packageJson, workspaceRoot) {
63
63
  packageJson['nx-migrations'] ??
64
64
  packageJson['schematics'] ??
65
65
  packageJson['builders']) {
66
- const [pluginPromise] = (0, in_process_loader_1.loadNxPlugin)(packageJson.name, workspaceRoot);
67
- return await pluginPromise;
66
+ return await (0, in_process_loader_1.loadNxPlugin)(packageJson.name, workspaceRoot);
68
67
  }
69
68
  else {
70
69
  return {
71
70
  name: packageJson.name,
71
+ capabilities: () => ({
72
+ hasCreateDependencies: false,
73
+ hasCreateMetadata: false,
74
+ hasPreTasksExecution: false,
75
+ hasPostTasksExecution: false,
76
+ }),
72
77
  };
73
78
  }
74
79
  }
@@ -13,6 +13,15 @@ const package_manager_1 = require("./package-manager");
13
13
  *
14
14
  * Will throw if the package does not have valid provenance.
15
15
  */
16
+ /**
17
+ * A build the publish workflow cuts from master rather than from a tag:
18
+ * `23.3.0-pr.36841.f66e88b` from a pull request, `23.2.0-canary.20260908-89f02c1`
19
+ * from the nightly. Each segment is matched with its leading digits so an
20
+ * ordinary prerelease like `1.0.0-preview.1` does not qualify.
21
+ */
22
+ function isPublishedFromMaster(version) {
23
+ return /-pr\.\d+\./.test(version) || /-canary\.\d/.test(version);
24
+ }
16
25
  async function ensurePackageHasProvenance(packageName, packageVersion) {
17
26
  // this is used for locally released versions without provenance
18
27
  // do not set this for other reasons or you might be exposed to security risks
@@ -25,8 +34,8 @@ async function ensurePackageHasProvenance(packageName, packageVersion) {
25
34
  '--silent',
26
35
  ]);
27
36
  const parsed = JSON.parse(result);
28
- // `npm view <pkg>@<spec> --json` returns a bare object on npm <= 11 but an
29
- // array on npm 12 and pnpm, even for a single resolved version. A version
37
+ // `npm view <pkg>@<spec> --json` returns a bare object on npm <= 11 and
38
+ // pnpm but an array on npm 12, even for a single resolved version. A version
30
39
  // range matches several versions and the registry lists all of them
31
40
  // (including deprecated ones the installer skips), so we cannot tell which
32
41
  // one will actually be installed; refuse rather than verify the wrong
@@ -57,8 +66,15 @@ async function ensurePackageHasProvenance(packageName, packageVersion) {
57
66
  if (workflowParameters.path !== '.github/workflows/publish.yml') {
58
67
  throw new ProvenanceError(packageName, packageVersion, 'Publishing workflow does not match .github/workflows/publish.yml');
59
68
  }
60
- if (workflowParameters.ref !== `refs/tags/${npmViewResult.version}`) {
61
- throw new ProvenanceError(packageName, packageVersion, `Version ref does not match refs/tags/${npmViewResult.version}`);
69
+ // PR and canary releases are published by this same workflow running on
70
+ // master, so a tag for them does not exist and never will. Repository,
71
+ // workflow path and the artifact digest are still checked, so this only
72
+ // widens which ref of nrwl/nx is allowed to have built it.
73
+ const allowedRefs = isPublishedFromMaster(npmViewResult.version)
74
+ ? [`refs/tags/${npmViewResult.version}`, 'refs/heads/master']
75
+ : [`refs/tags/${npmViewResult.version}`];
76
+ if (!allowedRefs.includes(workflowParameters.ref)) {
77
+ throw new ProvenanceError(packageName, packageVersion, `Version ref does not match ${allowedRefs.join(' or ')}`);
62
78
  }
63
79
  // verify that provenance was generated from the exact same artifact as the one we are installing
64
80
  const distSha = Buffer.from(npmViewResult.dist.integrity.replace('sha512-', ''), 'base64').toString('hex');
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serializeOverridesIntoCommandLine = serializeOverridesIntoCommandLine;
4
- const flat_1 = require("flat");
5
4
  const shell_quoting_1 = require("./shell-quoting");
6
5
  function serializeOverridesIntoCommandLine(options) {
7
6
  const unparsed = options._ ? [...options._] : [];
@@ -24,9 +23,8 @@ function serializeOption(key, value, unparsed) {
24
23
  value.forEach((item) => serializeOption(key, item, unparsed));
25
24
  }
26
25
  else if (Object.prototype.toString.call(value) === '[object Object]') {
27
- const flattened = (0, flat_1.flatten)(value, { safe: true });
28
- for (const flattenedKey in flattened) {
29
- serializeOption(`${key}.${flattenedKey}`, flattened[flattenedKey], unparsed);
26
+ for (const nestedKey of Object.keys(value)) {
27
+ serializeOption(`${key}.${nestedKey}`, value[nestedKey], unparsed);
30
28
  }
31
29
  }
32
30
  else if (typeof value === 'string' &&