@nx/js 24.0.0-beta.1 → 24.0.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.
package/dist/node.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createNodes, createNodesV2, type NodeScriptsPluginOptions, } from './src/plugins/scripts/node-plugin';
package/dist/node.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = exports.createNodes = void 0;
4
+ var node_plugin_1 = require("./src/plugins/scripts/node-plugin");
5
+ Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return node_plugin_1.createNodes; } });
6
+ Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return node_plugin_1.createNodesV2; } });
@@ -0,0 +1,20 @@
1
+ import { type CreateNodes, type TargetConfiguration } from '@nx/devkit';
2
+ import { type Shebang } from './shebang';
3
+ export interface ScriptPluginDefinition<T> {
4
+ /** Prefix of the plugin's cache file. */
5
+ cacheName: string;
6
+ technology: string;
7
+ /** Only files whose shebang the plugin claims become targets. */
8
+ claims(shebang: Shebang): boolean;
9
+ /** `file` is relative to the target's cwd. */
10
+ command(file: string, shebang: Shebang, watch: boolean): string;
11
+ /** Targets not tied to a shebang; claimed scripts win on name clashes. */
12
+ extraTargets?(projectRoot: string, workspaceRoot: string, options: T): Promise<ScriptTargets>;
13
+ }
14
+ export type ScriptTargets = Record<string, TargetConfiguration>;
15
+ export declare function createScriptNodes<T extends object>(definition: ScriptPluginDefinition<T>): CreateNodes<T>;
16
+ /**
17
+ * Quotes a path for a shell command when the shell would split or expand it.
18
+ * Double quotes keep spaces intact in sh and cmd.exe; cmd.exe still expands `%VAR%`.
19
+ */
20
+ export declare function quoteShellArg(arg: string): string;
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createScriptNodes = createScriptNodes;
4
+ exports.quoteShellArg = quoteShellArg;
5
+ const devkit_1 = require("@nx/devkit");
6
+ const internal_1 = require("@nx/devkit/internal");
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = require("node:path");
9
+ const frontmatter_1 = require("./frontmatter");
10
+ const shebang_1 = require("./shebang");
11
+ // Frontmatter keys the plugin interprets; any other key merges into the target.
12
+ const RESERVED_KEYS = ['name', 'description', 'disable', 'watch', 'cwd'];
13
+ const SCRIPT_GLOB = '**/*.{js,cjs,mjs,ts,cts,mts}';
14
+ const PROJECT_MARKERS = ['package.json', 'project.json'];
15
+ function createScriptNodes(definition) {
16
+ return [
17
+ (0, internal_1.combineGlobPatterns)([
18
+ SCRIPT_GLOB,
19
+ ...PROJECT_MARKERS.map((marker) => `**/${marker}`),
20
+ ]),
21
+ async (files, options, context) => {
22
+ const scriptsByRoot = groupScriptsByProjectRoot(files, !!definition.extraTargets);
23
+ const projectRoots = [...scriptsByRoot.keys()];
24
+ if (!projectRoots.length) {
25
+ return [];
26
+ }
27
+ const cache = new internal_1.PluginCache((0, node_path_1.join)(internal_1.workspaceDataDirectory, `${definition.cacheName}-${(0, internal_1.hashObject)(options ?? {})}.hash`));
28
+ try {
29
+ const hashes = await (0, internal_1.calculateHashesForCreateNodes)(projectRoots, options ?? {}, context);
30
+ const results = [];
31
+ for (const [i, projectRoot] of projectRoots.entries()) {
32
+ const { marker, scripts } = scriptsByRoot.get(projectRoot);
33
+ // include/exclude can change which scripts a project gets without
34
+ // changing its contents.
35
+ const key = (0, internal_1.hashObject)([hashes[i], [...scripts].sort()]);
36
+ if (!cache.has(key)) {
37
+ cache.set(key, {
38
+ ...(await definition.extraTargets?.(projectRoot, context.workspaceRoot, options)),
39
+ ...createTargets(definition, context.workspaceRoot, projectRoot, scripts),
40
+ });
41
+ }
42
+ const targets = cache.get(key);
43
+ if (Object.keys(targets).length) {
44
+ results.push([
45
+ scripts[0] ?? marker,
46
+ { projects: { [projectRoot]: { root: projectRoot, targets } } },
47
+ ]);
48
+ }
49
+ }
50
+ return results;
51
+ }
52
+ finally {
53
+ cache.writeToDisk();
54
+ }
55
+ },
56
+ ];
57
+ }
58
+ /**
59
+ * Assigns each script to its nearest enclosing project root. Roots without
60
+ * scripts are kept only when `includeAllRoots` is set.
61
+ */
62
+ function groupScriptsByProjectRoot(files, includeAllRoots) {
63
+ const markers = new Map();
64
+ const scripts = [];
65
+ for (const file of files) {
66
+ if (PROJECT_MARKERS.includes((0, node_path_1.basename)(file))) {
67
+ markers.set((0, node_path_1.dirname)(file), file);
68
+ }
69
+ else {
70
+ scripts.push(file);
71
+ }
72
+ }
73
+ const byRoot = new Map();
74
+ if (includeAllRoots) {
75
+ for (const [root, marker] of markers) {
76
+ byRoot.set(root, { marker, scripts: [] });
77
+ }
78
+ }
79
+ for (const script of scripts) {
80
+ let dir = (0, node_path_1.dirname)(script);
81
+ while (!markers.has(dir) && dir !== '.') {
82
+ dir = (0, node_path_1.dirname)(dir);
83
+ }
84
+ if (!markers.has(dir)) {
85
+ continue;
86
+ }
87
+ if (!byRoot.has(dir)) {
88
+ byRoot.set(dir, { marker: markers.get(dir), scripts: [] });
89
+ }
90
+ byRoot.get(dir).scripts.push(script);
91
+ }
92
+ return byRoot;
93
+ }
94
+ function createTargets(definition, workspaceRoot, projectRoot, scripts) {
95
+ const claimed = [];
96
+ for (const script of scripts) {
97
+ const absolutePath = (0, node_path_1.join)(workspaceRoot, script);
98
+ const line = (0, shebang_1.readShebangLine)(absolutePath);
99
+ const shebang = line === null ? null : (0, shebang_1.parseShebang)(line);
100
+ if (!shebang || !definition.claims(shebang)) {
101
+ continue;
102
+ }
103
+ let frontmatter = {};
104
+ try {
105
+ frontmatter = (0, frontmatter_1.parseFrontmatter)((0, node_fs_1.readFileSync)(absolutePath, 'utf-8'));
106
+ }
107
+ catch (e) {
108
+ devkit_1.logger.warn(`Ignoring the nx frontmatter in ${script}: ${e.message}`);
109
+ }
110
+ frontmatter = dropInvalidKeys(frontmatter, script);
111
+ if (frontmatter.disable === true) {
112
+ continue;
113
+ }
114
+ claimed.push({
115
+ path: script,
116
+ relativePath: node_path_1.posix.relative(projectRoot, script),
117
+ shebang,
118
+ frontmatter,
119
+ });
120
+ }
121
+ const baseNameCounts = new Map();
122
+ for (const { relativePath } of claimed) {
123
+ const name = withoutExtension((0, node_path_1.basename)(relativePath));
124
+ baseNameCounts.set(name, (baseNameCounts.get(name) ?? 0) + 1);
125
+ }
126
+ const targets = {};
127
+ for (const script of claimed) {
128
+ const baseName = withoutExtension((0, node_path_1.basename)(script.relativePath));
129
+ const name = typeof script.frontmatter.name === 'string'
130
+ ? script.frontmatter.name
131
+ : baseNameCounts.get(baseName) > 1
132
+ ? withoutExtension(script.relativePath)
133
+ : baseName;
134
+ targets[name] = createTarget(definition, projectRoot, script);
135
+ }
136
+ return targets;
137
+ }
138
+ function createTarget(definition, projectRoot, { path, relativePath, shebang, frontmatter }) {
139
+ const { description, watch, cwd, options, metadata } = frontmatter;
140
+ const rest = { ...frontmatter };
141
+ for (const key of [...RESERVED_KEYS, 'options', 'metadata']) {
142
+ delete rest[key];
143
+ }
144
+ const targetCwd = cwd ?? (typeof options?.cwd === 'string' ? options.cwd : projectRoot);
145
+ return {
146
+ command: definition.command(quoteShellArg(node_path_1.posix.relative(targetCwd, path)), shebang, watch === true),
147
+ options: { ...options, cwd: targetCwd },
148
+ cache: false,
149
+ ...(watch === true && { continuous: true }),
150
+ metadata: {
151
+ technologies: [definition.technology],
152
+ description: description ?? `Runs ${relativePath}`,
153
+ ...metadata,
154
+ },
155
+ ...rest,
156
+ };
157
+ }
158
+ const EXPECTED_TYPES = {
159
+ name: 'string',
160
+ description: 'string',
161
+ cwd: 'string',
162
+ cache: 'boolean',
163
+ continuous: 'boolean',
164
+ watch: 'boolean',
165
+ disable: 'boolean',
166
+ dependsOn: 'array',
167
+ inputs: 'array',
168
+ outputs: 'array',
169
+ options: 'object',
170
+ metadata: 'object',
171
+ };
172
+ /** Drops known keys with the wrong type so they cannot break the project graph. */
173
+ function dropInvalidKeys(frontmatter, script) {
174
+ const valid = {};
175
+ for (const [key, value] of Object.entries(frontmatter)) {
176
+ const expected = EXPECTED_TYPES[key];
177
+ const actual = Array.isArray(value)
178
+ ? 'array'
179
+ : value === null
180
+ ? 'null'
181
+ : typeof value;
182
+ if (expected && actual !== expected) {
183
+ devkit_1.logger.warn(`Ignoring nx frontmatter key "${key}" in ${script}: expected ${expected}, got ${actual}.`);
184
+ continue;
185
+ }
186
+ valid[key] = value;
187
+ }
188
+ return valid;
189
+ }
190
+ /**
191
+ * Quotes a path for a shell command when the shell would split or expand it.
192
+ * Double quotes keep spaces intact in sh and cmd.exe; cmd.exe still expands `%VAR%`.
193
+ */
194
+ function quoteShellArg(arg) {
195
+ if (/^[\w@%+=:,./-]+$/.test(arg)) {
196
+ return arg;
197
+ }
198
+ return '"' + arg.replace(/(["\\$`])/g, '\\$1') + '"';
199
+ }
200
+ function withoutExtension(path) {
201
+ return path.slice(0, path.length - (0, node_path_1.extname)(path).length);
202
+ }
@@ -0,0 +1,6 @@
1
+ export type Frontmatter = Record<string, unknown>;
2
+ /**
3
+ * Reads the YAML in a `/** @nx ... *\/` block comment after the shebang. Any other
4
+ * first comment yields `{}`. Throws on malformed YAML or an unterminated `@nx` block.
5
+ */
6
+ export declare function parseFrontmatter(source: string): Frontmatter;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFrontmatter = parseFrontmatter;
4
+ const js_yaml_1 = require("@zkochan/js-yaml");
5
+ const shebang_1 = require("./shebang");
6
+ /**
7
+ * Reads the YAML in a `/** @nx ... *\/` block comment after the shebang. Any other
8
+ * first comment yields `{}`. Throws on malformed YAML or an unterminated `@nx` block.
9
+ */
10
+ function parseFrontmatter(source) {
11
+ const lines = (0, shebang_1.stripBom)(source).split(/\r?\n/);
12
+ // lines[0] is the shebang; blank lines may follow it.
13
+ let start = 1;
14
+ while (start < lines.length && !lines[start].trim()) {
15
+ start++;
16
+ }
17
+ if (!lines[start]?.trim().startsWith('/*')) {
18
+ return {};
19
+ }
20
+ const block = [];
21
+ let terminated = false;
22
+ for (let i = start; i < lines.length; i++) {
23
+ let line = i === start ? lines[i].trim().replace(/^\/\*\*?/, '') : lines[i];
24
+ const end = line.indexOf('*/');
25
+ if (end !== -1) {
26
+ line = line.slice(0, end);
27
+ terminated = true;
28
+ }
29
+ // Tolerate JSDoc-style ` * ` line prefixes.
30
+ block.push(line.replace(/^\s*\* ?/, ''));
31
+ if (terminated) {
32
+ break;
33
+ }
34
+ }
35
+ const firstContent = block.findIndex((line) => line.trim());
36
+ const marker = (block[firstContent] ?? '').match(/^\s*@nx(?=\s|$)(.*)$/);
37
+ if (!marker) {
38
+ return {};
39
+ }
40
+ if (!terminated) {
41
+ throw new Error('Unterminated "@nx" frontmatter block.');
42
+ }
43
+ const body = [marker[1].trim(), ...block.slice(firstContent + 1)];
44
+ const parsed = (0, js_yaml_1.load)(body.join('\n'));
45
+ if (parsed == null) {
46
+ return {};
47
+ }
48
+ if (typeof parsed !== 'object' || Array.isArray(parsed)) {
49
+ throw new Error('The "@nx" frontmatter block must be a YAML mapping.');
50
+ }
51
+ return parsed;
52
+ }
@@ -0,0 +1,9 @@
1
+ export interface NodeScriptsPluginOptions {
2
+ /**
3
+ * `dependsOn` for `bin` targets whose file is build output (not a tracked
4
+ * workspace file). Defaults to `["build"]`.
5
+ */
6
+ binDependsOn?: string[];
7
+ }
8
+ export declare const createNodes: import("@nx/devkit").CreateNodes<NodeScriptsPluginOptions>;
9
+ export declare const createNodesV2: import("@nx/devkit").CreateNodes<NodeScriptsPluginOptions>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = exports.createNodes = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const internal_1 = require("@nx/devkit/internal");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const create_script_nodes_1 = require("./create-script-nodes");
9
+ exports.createNodes = (0, create_script_nodes_1.createScriptNodes)({
10
+ cacheName: 'js-node-scripts',
11
+ technology: 'node',
12
+ claims: (shebang) => shebang.interpreter === 'node',
13
+ command: (file, shebang, watch) => ['node', ...(watch ? ['--watch'] : []), ...shebang.args, file].join(' '),
14
+ extraTargets: createBinTargets,
15
+ });
16
+ exports.createNodesV2 = exports.createNodes;
17
+ async function createBinTargets(projectRoot, workspaceRoot, options) {
18
+ const packageJsonPath = (0, node_path_1.join)(workspaceRoot, projectRoot, 'package.json');
19
+ if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
20
+ return {};
21
+ }
22
+ const bins = readBinEntries((0, devkit_1.readJsonFile)(packageJsonPath));
23
+ if (!bins.length) {
24
+ return {};
25
+ }
26
+ const binFiles = bins.map(([, path]) => node_path_1.posix.join(projectRoot, node_path_1.posix.normalize(path)));
27
+ const tracked = new Set(await (0, internal_1.globWithWorkspaceContext)(workspaceRoot, binFiles));
28
+ const targets = {};
29
+ bins.forEach(([name, path], i) => {
30
+ const target = {
31
+ command: `node ${(0, create_script_nodes_1.quoteShellArg)(node_path_1.posix.normalize(path))}`,
32
+ options: { cwd: projectRoot },
33
+ cache: false,
34
+ metadata: {
35
+ technologies: ['node'],
36
+ description: `Runs the ${name} bin`,
37
+ },
38
+ };
39
+ if (!tracked.has(binFiles[i])) {
40
+ target.dependsOn = options?.binDependsOn ?? ['build'];
41
+ }
42
+ targets[name] = target;
43
+ });
44
+ return targets;
45
+ }
46
+ function readBinEntries(packageJson) {
47
+ const { name, bin } = packageJson;
48
+ if (typeof bin === 'string') {
49
+ return name ? [[name.replace(/^@[^/]+\//, ''), bin]] : [];
50
+ }
51
+ return Object.entries(bin ?? {}).filter((entry) => typeof entry[1] === 'string');
52
+ }
@@ -0,0 +1,14 @@
1
+ export interface Shebang {
2
+ /** Program that runs the file, e.g. `node` or `tsx`. */
3
+ interpreter: string;
4
+ /** Arguments that follow the interpreter on the shebang line. */
5
+ args: string[];
6
+ }
7
+ /** Returns the shebang line without `#!`, or `null` when the file has none. */
8
+ export declare function readShebangLine(absolutePath: string): string | null;
9
+ /**
10
+ * Handles `/usr/bin/env node`, `/usr/bin/env -S node --flags`,
11
+ * `/usr/bin/env -S npx tsx` and direct paths such as `/usr/local/bin/node`.
12
+ */
13
+ export declare function parseShebang(line: string): Shebang | null;
14
+ export declare function stripBom(text: string): string;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readShebangLine = readShebangLine;
4
+ exports.parseShebang = parseShebang;
5
+ exports.stripBom = stripBom;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const SNIFF_BYTES = 512;
9
+ const PACKAGE_RUNNERS = new Set(['npx', 'pnpx', 'bunx']);
10
+ /** Returns the shebang line without `#!`, or `null` when the file has none. */
11
+ function readShebangLine(absolutePath) {
12
+ const buffer = Buffer.alloc(SNIFF_BYTES);
13
+ const fd = (0, node_fs_1.openSync)(absolutePath, 'r');
14
+ let bytesRead;
15
+ try {
16
+ bytesRead = (0, node_fs_1.readSync)(fd, buffer, 0, SNIFF_BYTES, 0);
17
+ }
18
+ finally {
19
+ (0, node_fs_1.closeSync)(fd);
20
+ }
21
+ const text = stripBom(buffer.toString('utf8', 0, bytesRead));
22
+ if (!text.startsWith('#!')) {
23
+ return null;
24
+ }
25
+ const end = text.search(/\r?\n/);
26
+ return (end === -1 ? text : text.slice(0, end)).slice(2).trim();
27
+ }
28
+ /**
29
+ * Handles `/usr/bin/env node`, `/usr/bin/env -S node --flags`,
30
+ * `/usr/bin/env -S npx tsx` and direct paths such as `/usr/local/bin/node`.
31
+ */
32
+ function parseShebang(line) {
33
+ let tokens = line.split(/\s+/).filter(Boolean);
34
+ if (tokens.length && (0, node_path_1.basename)(tokens[0]) === 'env') {
35
+ tokens = tokens.slice(1);
36
+ if (tokens[0] === '-S') {
37
+ tokens = tokens.slice(1);
38
+ }
39
+ }
40
+ if (tokens.length && PACKAGE_RUNNERS.has((0, node_path_1.basename)(tokens[0]))) {
41
+ tokens = tokens.slice(1);
42
+ }
43
+ if (!tokens.length) {
44
+ return null;
45
+ }
46
+ return { interpreter: (0, node_path_1.basename)(tokens[0]), args: tokens.slice(1) };
47
+ }
48
+ function stripBom(text) {
49
+ return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
50
+ }
@@ -0,0 +1,2 @@
1
+ export declare const createNodes: import("@nx/devkit").CreateNodes<Record<string, never>>;
2
+ export declare const createNodesV2: import("@nx/devkit").CreateNodes<Record<string, never>>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = exports.createNodes = void 0;
4
+ const create_script_nodes_1 = require("./create-script-nodes");
5
+ exports.createNodes = (0, create_script_nodes_1.createScriptNodes)({
6
+ cacheName: 'js-tsx-scripts',
7
+ technology: 'tsx',
8
+ claims: (shebang) => shebang.interpreter === 'tsx',
9
+ command: (file, shebang, watch) => ['tsx', ...(watch ? ['watch'] : []), ...shebang.args, file].join(' '),
10
+ });
11
+ exports.createNodesV2 = exports.createNodes;
package/dist/tsx.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createNodes, createNodesV2 } from './src/plugins/scripts/tsx-plugin';
package/dist/tsx.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = exports.createNodes = void 0;
4
+ var tsx_plugin_1 = require("./src/plugins/scripts/tsx-plugin");
5
+ Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return tsx_plugin_1.createNodes; } });
6
+ Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return tsx_plugin_1.createNodesV2; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "24.0.0-beta.1",
3
+ "version": "24.0.0-beta.2",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -39,6 +39,12 @@
39
39
  "typescript": [
40
40
  "dist/typescript.d.ts"
41
41
  ],
42
+ "node": [
43
+ "dist/node.d.ts"
44
+ ],
45
+ "tsx": [
46
+ "dist/tsx.d.ts"
47
+ ],
42
48
  "plugins/jest/local-registry": [
43
49
  "dist/plugins/jest/local-registry.d.ts"
44
50
  ],
@@ -96,6 +102,16 @@
96
102
  "types": "./dist/typescript.d.ts",
97
103
  "default": "./dist/typescript.js"
98
104
  },
105
+ "./node": {
106
+ "@nx/nx-source": "./node.ts",
107
+ "types": "./dist/node.d.ts",
108
+ "default": "./dist/node.js"
109
+ },
110
+ "./tsx": {
111
+ "@nx/nx-source": "./tsx.ts",
112
+ "types": "./dist/tsx.d.ts",
113
+ "default": "./dist/tsx.js"
114
+ },
99
115
  "./plugins/jest/local-registry": {
100
116
  "@nx/nx-source": "./plugins/jest/local-registry.ts",
101
117
  "types": "./dist/plugins/jest/local-registry.d.ts",
@@ -138,8 +154,8 @@
138
154
  "@babel/preset-env": "^7.23.2",
139
155
  "@babel/preset-typescript": "^7.22.5",
140
156
  "@babel/runtime": "^7.22.6",
141
- "@nx/devkit": "24.0.0-beta.1",
142
- "@nx/workspace": "24.0.0-beta.1",
157
+ "@nx/devkit": "24.0.0-beta.2",
158
+ "@nx/workspace": "24.0.0-beta.2",
143
159
  "@zkochan/js-yaml": "0.0.7",
144
160
  "babel-plugin-const-enum": "^1.0.1",
145
161
  "babel-plugin-macros": "^3.1.0",
@@ -159,14 +175,14 @@
159
175
  "tslib": "^2.3.0"
160
176
  },
161
177
  "devDependencies": {
162
- "@nx/esbuild": "24.0.0-beta.1",
163
- "@nx/eslint": "24.0.0-beta.1",
164
- "@nx/jest": "24.0.0-beta.1",
165
- "@nx/oxlint": "24.0.0-beta.1",
166
- "@nx/rollup": "24.0.0-beta.1",
167
- "@nx/vite": "24.0.0-beta.1",
168
- "@nx/vitest": "24.0.0-beta.1",
169
- "nx": "24.0.0-beta.1"
178
+ "@nx/esbuild": "24.0.0-beta.2",
179
+ "@nx/eslint": "24.0.0-beta.2",
180
+ "@nx/jest": "24.0.0-beta.2",
181
+ "@nx/oxlint": "24.0.0-beta.2",
182
+ "@nx/rollup": "24.0.0-beta.2",
183
+ "@nx/vite": "24.0.0-beta.2",
184
+ "@nx/vitest": "24.0.0-beta.2",
185
+ "nx": "24.0.0-beta.2"
170
186
  },
171
187
  "peerDependencies": {
172
188
  "@swc/cli": ">=0.6.0 <0.9.0",