@nx/oxlint 0.0.1 → 23.2.0-beta.11
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 +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/src/plugins/plugin.d.ts +9 -1
- package/dist/src/plugins/plugin.js +174 -10
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
<div style="text-align: center;">
|
|
9
9
|
|
|
10
|
-
[]()
|
|
10
|
+
[](<>)
|
|
11
11
|
[](https://www.npmjs.com/package/nx)
|
|
12
|
-
[]()
|
|
12
|
+
[](<>)
|
|
13
13
|
[](http://commitizen.github.io/cz-cli/)
|
|
14
14
|
[](https://go.nx.dev/community)
|
|
15
15
|
[](https://nx.dev/docs/features/ci-features/sandboxing)
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createNodes, createNodesV2, type OxlintPluginOptions, } from './src/plugins/plugin.js';
|
|
1
|
+
export { createDependencies, createNodes, createNodesV2, type OxlintPluginOptions, } from './src/plugins/plugin.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// The graph plugin only — this is what `nx.json` names as `@nx/oxlint`.
|
|
2
2
|
// Generators live in `./generators`.
|
|
3
|
-
export { createNodes, createNodesV2, } from './src/plugins/plugin.js';
|
|
3
|
+
export { createDependencies, createNodes, createNodesV2, } from './src/plugins/plugin.js';
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import { CreateNodes } from '@nx/devkit';
|
|
1
|
+
import { CreateDependencies, CreateNodes } from '@nx/devkit';
|
|
2
2
|
export interface OxlintPluginOptions {
|
|
3
3
|
targetName?: string;
|
|
4
4
|
}
|
|
5
5
|
export declare const createNodes: CreateNodes<OxlintPluginOptions>;
|
|
6
6
|
export declare const createNodesV2: CreateNodes<OxlintPluginOptions>;
|
|
7
|
+
/**
|
|
8
|
+
* A config's `jsPlugins` produce the lint results, so every project linted
|
|
9
|
+
* under that config depends on them. Resolving the specifiers here, against the
|
|
10
|
+
* finished node set, is what makes a workspace plugin a project edge and an npm
|
|
11
|
+
* plugin an external edge; `^default` then hashes both. Implicit, because the
|
|
12
|
+
* config may not be a file of the depending project.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createDependencies: CreateDependencies<OxlintPluginOptions>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { buildPackageJsonPatterns, buildPackageJsonWorkspacesMatcher, calculateHashesForCreateNodes, combineGlobPatterns, globWithWorkspaceContext, hashObject, PluginCache, workspaceDataDirectory, } from '@nx/devkit/internal';
|
|
2
|
-
import { createNodesFromFiles, detectPackageManager, getPackageManagerCommand, readJsonFile, } from '@nx/devkit';
|
|
1
|
+
import { buildPackageJsonPatterns, buildPackageJsonWorkspacesMatcher, calculateHashesForCreateNodes, combineGlobPatterns, globWithWorkspaceContext, hashObject, PluginCache, TargetProjectLocator, workspaceDataDirectory, } from '@nx/devkit/internal';
|
|
2
|
+
import { createNodesFromFiles, DependencyType, detectPackageManager, getPackageManagerCommand, readJsonFile, validateDependency, } from '@nx/devkit';
|
|
3
3
|
import { getLockFileName, getRootTsConfigFileName } from '@nx/js';
|
|
4
4
|
import { walkTsconfigExtendsChain, } from '@nx/js/internal';
|
|
5
5
|
import { execFileSync } from 'node:child_process';
|
|
@@ -32,7 +32,7 @@ const OXLINT_CONFIG_GLOB = combineGlobPatterns([
|
|
|
32
32
|
...OXLINT_CONFIG_FILENAMES.map((f) => `**/${f}`),
|
|
33
33
|
...PROJECT_CONFIG_FILENAMES.map((f) => `**/${f}`),
|
|
34
34
|
]);
|
|
35
|
-
const internalCreateNodes = async (configFilePath, options, context, projectRootsByOxlintRoots, getLintableFilesPerProjectRoot, configChainsByConfig, tsconfigChainsByProjectRoot, projectsCache, hashByRoot, pmc, rootConfig) => {
|
|
35
|
+
const internalCreateNodes = async (configFilePath, options, context, projectRootsByOxlintRoots, getLintableFilesPerProjectRoot, configChainsByConfig, jsPluginSpecifiersByConfig, tsconfigChainsByProjectRoot, projectsCache, hashByRoot, pmc, rootConfig) => {
|
|
36
36
|
const configDir = dirname(configFilePath);
|
|
37
37
|
// Collect each project root's contribution in parallel, but write them into
|
|
38
38
|
// `projects` afterwards in input order so insertion order (and therefore
|
|
@@ -53,7 +53,7 @@ const internalCreateNodes = async (configFilePath, options, context, projectRoot
|
|
|
53
53
|
projectsCache.set(hash, {});
|
|
54
54
|
return null;
|
|
55
55
|
}
|
|
56
|
-
const project = getProjectUsingOxlintConfig(configFilePath, projectRoot, options, context, pmc, configChainsByConfig, tsconfigChainsByProjectRoot.get(projectRoot) ?? [], rootConfig);
|
|
56
|
+
const project = getProjectUsingOxlintConfig(configFilePath, projectRoot, options, context, pmc, configChainsByConfig, jsPluginSpecifiersByConfig, tsconfigChainsByProjectRoot.get(projectRoot) ?? [], rootConfig);
|
|
57
57
|
if (project) {
|
|
58
58
|
const entry = { [projectRoot]: project };
|
|
59
59
|
projectsCache.set(hash, entry);
|
|
@@ -90,7 +90,7 @@ export const createNodes = [
|
|
|
90
90
|
// Workspace-global and invariant for the whole run, so it is resolved once
|
|
91
91
|
// here rather than re-stat'ed for every project.
|
|
92
92
|
const rootConfig = OXLINT_CONFIG_FILENAMES.find((file) => existsSync(join(context.workspaceRoot, file)));
|
|
93
|
-
const configChainsByConfig = collectConfigChains(oxlintConfigFiles, context.workspaceRoot);
|
|
93
|
+
const { chains: configChainsByConfig, jsPluginSpecifiersByConfig } = collectConfigChains(oxlintConfigFiles, context.workspaceRoot);
|
|
94
94
|
const tsconfigChainsByProjectRoot = collectTsconfigChainsByProjectRoot(projectRoots, context.workspaceRoot);
|
|
95
95
|
// Stats the workspace root, so detect once for both uses below — and after
|
|
96
96
|
// the bail, so a workspace with no Oxlint config never pays for it.
|
|
@@ -106,10 +106,17 @@ export const createNodes = [
|
|
|
106
106
|
});
|
|
107
107
|
// Deduped: every chain ends at the same root config, and each duplicate
|
|
108
108
|
// is another whole-workspace glob for the hasher.
|
|
109
|
+
const allConfigs = [
|
|
110
|
+
...governingConfigs,
|
|
111
|
+
...governingConfigs.flatMap((config) => configChainsByConfig.get(config) ?? []),
|
|
112
|
+
];
|
|
109
113
|
return [
|
|
110
114
|
...new Set([
|
|
111
|
-
...
|
|
112
|
-
...
|
|
115
|
+
...allConfigs,
|
|
116
|
+
...allConfigs.flatMap((config) => localJsPluginFiles(config, jsPluginSpecifiersByConfig.get(config) ?? [])),
|
|
117
|
+
// Change which files Oxlint considers lintable, and therefore
|
|
118
|
+
// whether a target is inferred at all.
|
|
119
|
+
...ancestorEslintignorePaths(root),
|
|
113
120
|
lockFilePattern,
|
|
114
121
|
...(tsconfigChainsByProjectRoot.get(root) ?? []),
|
|
115
122
|
]),
|
|
@@ -117,7 +124,7 @@ export const createNodes = [
|
|
|
117
124
|
}));
|
|
118
125
|
const hashByRoot = new Map(projectRoots.map((r, i) => [r, hashes[i]]));
|
|
119
126
|
try {
|
|
120
|
-
return await createNodesFromFiles((configFile, fileOptions, fileContext) => internalCreateNodes(configFile, fileOptions, fileContext, projectRootsByOxlintRoots, getLintableFilesPerProjectRoot, configChainsByConfig, tsconfigChainsByProjectRoot, targetsCache, hashByRoot, pmc, rootConfig), oxlintConfigFiles, options, context);
|
|
127
|
+
return await createNodesFromFiles((configFile, fileOptions, fileContext) => internalCreateNodes(configFile, fileOptions, fileContext, projectRootsByOxlintRoots, getLintableFilesPerProjectRoot, configChainsByConfig, jsPluginSpecifiersByConfig, tsconfigChainsByProjectRoot, targetsCache, hashByRoot, pmc, rootConfig), oxlintConfigFiles, options, context);
|
|
121
128
|
}
|
|
122
129
|
finally {
|
|
123
130
|
targetsCache.writeToDisk();
|
|
@@ -125,6 +132,98 @@ export const createNodes = [
|
|
|
125
132
|
},
|
|
126
133
|
];
|
|
127
134
|
export const createNodesV2 = createNodes;
|
|
135
|
+
/**
|
|
136
|
+
* A config's `jsPlugins` produce the lint results, so every project linted
|
|
137
|
+
* under that config depends on them. Resolving the specifiers here, against the
|
|
138
|
+
* finished node set, is what makes a workspace plugin a project edge and an npm
|
|
139
|
+
* plugin an external edge; `^default` then hashes both. Implicit, because the
|
|
140
|
+
* config may not be a file of the depending project.
|
|
141
|
+
*/
|
|
142
|
+
export const createDependencies = (_options, context) => {
|
|
143
|
+
// Walked rather than flattened: this runs on every graph build, and a copy
|
|
144
|
+
// of the whole file map is the wrong price for finding a few config files.
|
|
145
|
+
const oxlintConfigFiles = [];
|
|
146
|
+
const collect = (files) => {
|
|
147
|
+
for (const { file } of files) {
|
|
148
|
+
if (OXLINT_CONFIG_FILENAMES.includes(basename(file))) {
|
|
149
|
+
oxlintConfigFiles.push(file);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
for (const files of Object.values(context.fileMap.projectFileMap)) {
|
|
154
|
+
collect(files);
|
|
155
|
+
}
|
|
156
|
+
collect(context.fileMap.nonProjectFiles);
|
|
157
|
+
if (oxlintConfigFiles.length === 0) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const { chains, jsPluginSpecifiersByConfig } = collectConfigChains(oxlintConfigFiles, context.workspaceRoot);
|
|
161
|
+
const configsWithPlugins = [...jsPluginSpecifiersByConfig].filter(([, specifiers]) => specifiers.length > 0);
|
|
162
|
+
if (configsWithPlugins.length === 0) {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
const nodes = {};
|
|
166
|
+
for (const [name, data] of Object.entries(context.projects)) {
|
|
167
|
+
nodes[name] = { name, type: null, data };
|
|
168
|
+
}
|
|
169
|
+
// Own resolution cache: the locator's shared default one is never
|
|
170
|
+
// invalidated, so a plugin resolved before `install` would stay unresolved
|
|
171
|
+
// for the life of the plugin worker.
|
|
172
|
+
const locator = new TargetProjectLocator(nodes, context.externalNodes, new Map());
|
|
173
|
+
// Resolution is relative to the config, so it is the same for every project
|
|
174
|
+
// that config governs.
|
|
175
|
+
const targetsByConfig = new Map();
|
|
176
|
+
const resolveTargets = (config) => {
|
|
177
|
+
let targets = targetsByConfig.get(config);
|
|
178
|
+
if (!targets) {
|
|
179
|
+
targets = [];
|
|
180
|
+
for (const specifier of jsPluginSpecifiersByConfig.get(config) ?? []) {
|
|
181
|
+
const target = locator.findProjectFromImport(specifier, config);
|
|
182
|
+
if (target) {
|
|
183
|
+
targets.push(target);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
targetsByConfig.set(config, targets);
|
|
187
|
+
}
|
|
188
|
+
return targets;
|
|
189
|
+
};
|
|
190
|
+
const dependencies = [];
|
|
191
|
+
for (const [name, project] of Object.entries(context.projects)) {
|
|
192
|
+
if (!Object.values(project.targets ?? {}).some((target) => target.metadata?.technologies?.includes('oxlint'))) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
// Own directory and every ancestor, plus their `extends` chains — the
|
|
196
|
+
// same set `createNodes` hashes. A plugin project that depends on a
|
|
197
|
+
// project it lints closes a cycle here; that is a real circularity, and
|
|
198
|
+
// the docs say so.
|
|
199
|
+
const governingConfigs = oxlintConfigFiles.filter((config) => {
|
|
200
|
+
const configDir = dirname(config);
|
|
201
|
+
return configDir === project.root || isSubDir(configDir, project.root);
|
|
202
|
+
});
|
|
203
|
+
const configs = new Set([
|
|
204
|
+
...governingConfigs,
|
|
205
|
+
...governingConfigs.flatMap((config) => chains.get(config) ?? []),
|
|
206
|
+
]);
|
|
207
|
+
const targets = new Set();
|
|
208
|
+
for (const config of configs) {
|
|
209
|
+
for (const target of resolveTargets(config)) {
|
|
210
|
+
if (target !== name) {
|
|
211
|
+
targets.add(target);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
for (const target of targets) {
|
|
216
|
+
const dependency = {
|
|
217
|
+
source: name,
|
|
218
|
+
target,
|
|
219
|
+
type: DependencyType.implicit,
|
|
220
|
+
};
|
|
221
|
+
validateDependency(dependency, context);
|
|
222
|
+
dependencies.push(dependency);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return dependencies;
|
|
226
|
+
};
|
|
128
227
|
function splitConfigFiles(configFiles, workspaceRoot) {
|
|
129
228
|
const oxlintConfigFiles = [];
|
|
130
229
|
const packageJsonFiles = [];
|
|
@@ -186,9 +285,13 @@ function splitConfigFiles(configFiles, workspaceRoot) {
|
|
|
186
285
|
* Oxlint resolves entries relative to the referencing config and only tracks the
|
|
187
286
|
* chain for its LSP, so Nx walks it here or caching goes stale. TypeScript
|
|
188
287
|
* configs are not statically readable, so only the file itself is tracked.
|
|
288
|
+
*
|
|
289
|
+
* Also collects each config's raw `jsPlugins` specifiers. `createDependencies`
|
|
290
|
+
* resolves them to graph nodes; `createNodes` only needs the local files.
|
|
189
291
|
*/
|
|
190
292
|
function collectConfigChains(oxlintConfigFiles, workspaceRoot) {
|
|
191
293
|
const result = new Map();
|
|
294
|
+
const jsPluginSpecifiersByConfig = new Map();
|
|
192
295
|
// Shared across configs so the common root config is read once. `null` records
|
|
193
296
|
// a failed read, so a bad file is not retried per referrer.
|
|
194
297
|
const jsonCache = new Map();
|
|
@@ -201,6 +304,25 @@ function collectConfigChains(oxlintConfigFiles, workspaceRoot) {
|
|
|
201
304
|
}
|
|
202
305
|
return exists;
|
|
203
306
|
};
|
|
307
|
+
const recordJsPluginSpecifiers = (relativeConfigPath, jsPlugins) => {
|
|
308
|
+
if (jsPluginSpecifiersByConfig.has(relativeConfigPath)) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const specifiers = [];
|
|
312
|
+
if (Array.isArray(jsPlugins)) {
|
|
313
|
+
for (const entry of jsPlugins) {
|
|
314
|
+
const specifier = typeof entry === 'string'
|
|
315
|
+
? entry
|
|
316
|
+
: typeof entry?.specifier === 'string'
|
|
317
|
+
? entry.specifier
|
|
318
|
+
: undefined;
|
|
319
|
+
if (specifier) {
|
|
320
|
+
specifiers.push(specifier);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
jsPluginSpecifiersByConfig.set(relativeConfigPath, specifiers);
|
|
325
|
+
};
|
|
204
326
|
const readConfig = (relativeConfigPath) => {
|
|
205
327
|
if (jsonCache.has(relativeConfigPath)) {
|
|
206
328
|
return jsonCache.get(relativeConfigPath);
|
|
@@ -234,6 +356,7 @@ function collectConfigChains(oxlintConfigFiles, workspaceRoot) {
|
|
|
234
356
|
return;
|
|
235
357
|
}
|
|
236
358
|
const json = readConfig(relativeConfigPath);
|
|
359
|
+
recordJsPluginSpecifiers(relativeConfigPath, json?.jsPlugins);
|
|
237
360
|
if (!Array.isArray(json?.extends)) {
|
|
238
361
|
return;
|
|
239
362
|
}
|
|
@@ -256,7 +379,25 @@ function collectConfigChains(oxlintConfigFiles, workspaceRoot) {
|
|
|
256
379
|
walk(configFile);
|
|
257
380
|
result.set(configFile, extended);
|
|
258
381
|
}
|
|
259
|
-
return result;
|
|
382
|
+
return { chains: result, jsPluginSpecifiersByConfig };
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Workspace-relative paths of a config's relative-path `jsPlugins`. Declared as
|
|
386
|
+
* file inputs because such a file may sit outside every project (`tools/x.js`
|
|
387
|
+
* at the root), where no graph edge can reach it.
|
|
388
|
+
*/
|
|
389
|
+
function localJsPluginFiles(relativeConfigPath, specifiers) {
|
|
390
|
+
const files = [];
|
|
391
|
+
for (const specifier of specifiers) {
|
|
392
|
+
if (!specifier.startsWith('.')) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const resolved = normalize(join(dirname(relativeConfigPath), specifier));
|
|
396
|
+
if (resolved !== '..' && !resolved.startsWith('../')) {
|
|
397
|
+
files.push(resolved);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return files;
|
|
260
401
|
}
|
|
261
402
|
/**
|
|
262
403
|
* Per project root, the `extends`-reachable tsconfig files that live OUTSIDE the
|
|
@@ -372,6 +513,23 @@ async function collectLintableFilesByProjectRoot(projectRoots, context) {
|
|
|
372
513
|
}
|
|
373
514
|
return lintableFilesPerProjectRoot;
|
|
374
515
|
}
|
|
516
|
+
/**
|
|
517
|
+
* `.eslintignore` candidates in every ancestor directory of the project root,
|
|
518
|
+
* workspace root included. The project's own directory is excluded — files
|
|
519
|
+
* there are covered by the `default` input.
|
|
520
|
+
*/
|
|
521
|
+
function ancestorEslintignorePaths(projectRoot) {
|
|
522
|
+
const result = [];
|
|
523
|
+
let dir = projectRoot === '.' ? '.' : dirname(projectRoot);
|
|
524
|
+
while (true) {
|
|
525
|
+
result.push(dir === '.' ? '.eslintignore' : `${dir}/.eslintignore`);
|
|
526
|
+
if (dir === '.') {
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
dir = dirname(dir);
|
|
530
|
+
}
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
375
533
|
// Only the keys are read, so the value type is left open for both callers.
|
|
376
534
|
function getRootForDirectory(directory, roots) {
|
|
377
535
|
let currentPath = normalize(directory);
|
|
@@ -383,7 +541,7 @@ function getRootForDirectory(directory, roots) {
|
|
|
383
541
|
}
|
|
384
542
|
return roots.has(currentPath) ? currentPath : null;
|
|
385
543
|
}
|
|
386
|
-
function getProjectUsingOxlintConfig(configFilePath, projectRoot, options, context, pmc, configChainsByConfig, tsconfigChainOutsideProjectRoot, rootConfig) {
|
|
544
|
+
function getProjectUsingOxlintConfig(configFilePath, projectRoot, options, context, pmc, configChainsByConfig, jsPluginSpecifiersByConfig, tsconfigChainOutsideProjectRoot, rootConfig) {
|
|
387
545
|
let standaloneSrcPath;
|
|
388
546
|
if (projectRoot === '.' &&
|
|
389
547
|
existsSync(join(context.workspaceRoot, projectRoot, 'package.json'))) {
|
|
@@ -410,6 +568,7 @@ function getProjectUsingOxlintConfig(configFilePath, projectRoot, options, conte
|
|
|
410
568
|
];
|
|
411
569
|
const isRootProject = projectRoot === '.';
|
|
412
570
|
const lintPath = isRootProject && standaloneSrcPath ? `./${standaloneSrcPath}` : '.';
|
|
571
|
+
const jsPluginFiles = new Set(configInputs.flatMap((config) => localJsPluginFiles(config, jsPluginSpecifiersByConfig.get(config) ?? [])));
|
|
413
572
|
const targetConfig = {
|
|
414
573
|
command: `oxlint ${lintPath}`,
|
|
415
574
|
options: { cwd: projectRoot },
|
|
@@ -418,6 +577,11 @@ function getProjectUsingOxlintConfig(configFilePath, projectRoot, options, conte
|
|
|
418
577
|
'default',
|
|
419
578
|
'^default',
|
|
420
579
|
...configInputs.map((config) => `{workspaceRoot}/${config}`),
|
|
580
|
+
...[...jsPluginFiles].map((file) => `{workspaceRoot}/${file}`),
|
|
581
|
+
// Oxlint layers .eslintignore files from every ancestor of a linted
|
|
582
|
+
// file; the project's own is covered by `default`. Declared even when
|
|
583
|
+
// absent, like the extends chain.
|
|
584
|
+
...ancestorEslintignorePaths(projectRoot).map((file) => `{workspaceRoot}/${file}`),
|
|
421
585
|
...tsconfigChainOutsideProjectRoot.map((file) => `{workspaceRoot}/${file}`),
|
|
422
586
|
{ externalDependencies: ['oxlint'] },
|
|
423
587
|
],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/oxlint",
|
|
3
3
|
"description": "Experimental. The Oxlint plugin for Nx contains generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "23.2.0-beta.11",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
},
|
|
69
69
|
"generators": "./generators.json",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"
|
|
72
|
-
"@nx/
|
|
73
|
-
"@nx/
|
|
74
|
-
"
|
|
71
|
+
"tslib": "^2.3.0",
|
|
72
|
+
"@nx/devkit": "23.2.0-beta.11",
|
|
73
|
+
"@nx/eslint-plugin": "23.2.0-beta.11",
|
|
74
|
+
"@nx/js": "23.2.0-beta.11"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"oxlint": "^1.43.0"
|
|
@@ -85,6 +85,6 @@
|
|
|
85
85
|
"node": "^20.19.0 || >=22.12.0"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"nx": "
|
|
88
|
+
"nx": "23.2.0-beta.11"
|
|
89
89
|
}
|
|
90
|
-
}
|
|
90
|
+
}
|