@ng-native/nx 0.17.1 → 0.18.1
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/application/index.cjs +32 -17
- package/application/schema.json +10 -1
- package/files/AGENTS.md +4 -0
- package/files/src/main.ts +5 -3
- package/library/index.cjs +2 -3
- package/migrations.json +11 -1
- package/native-app.cjs +21 -9
- package/package.json +5 -4
package/application/index.cjs
CHANGED
|
@@ -29,7 +29,7 @@ const {
|
|
|
29
29
|
addDependenciesToPackageJson,
|
|
30
30
|
} = require('@nx/devkit');
|
|
31
31
|
const native = require('../native-app.cjs');
|
|
32
|
-
const { init
|
|
32
|
+
const { init } = require('../init/index.cjs');
|
|
33
33
|
const { usesWorkspaces, includeInWorkspaces } = require('./workspaces.cjs');
|
|
34
34
|
const { asSaved } = require('../save-exact.cjs');
|
|
35
35
|
const { registerSyncGenerator } = require('../sync/index.cjs');
|
|
@@ -42,9 +42,14 @@ function names(tree, options) {
|
|
|
42
42
|
// A workspace package is named for the workspace's scope, as Nx names its own.
|
|
43
43
|
const projectName = workspaces && scope ? `${scope}/${name}` : name;
|
|
44
44
|
const bundleIdentifier = options.bundleIdentifier ?? native.bundleIdentifier(name, scope);
|
|
45
|
-
|
|
45
|
+
const lint = options.linter === 'eslint';
|
|
46
|
+
return { directory, name, projectName, workspaces, bundleIdentifier, lint };
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
/** The app's dev dependencies: with `--linter=eslint`, ESLint and the plugin as well. */
|
|
50
|
+
const devDependencies = (lint) =>
|
|
51
|
+
lint ? { ...native.devDependencies, ...native.lintDevDependencies } : native.devDependencies;
|
|
52
|
+
|
|
48
53
|
/**
|
|
49
54
|
* Whether the workspace's `tsconfig.base.json` is where its libraries' path aliases live, or will.
|
|
50
55
|
* With package-manager workspaces, only when it has a `paths` list, as the `angular-monorepo`
|
|
@@ -125,7 +130,7 @@ function metroPort(tree) {
|
|
|
125
130
|
return port;
|
|
126
131
|
}
|
|
127
132
|
|
|
128
|
-
function targets(directory, port, oneCopy) {
|
|
133
|
+
function targets(directory, port, oneCopy, lint) {
|
|
129
134
|
const run = (command) => ({ executor: 'nx:run-commands', options: { cwd: directory, command } });
|
|
130
135
|
const own = port === DEFAULT_PORT ? '' : ` --port ${port}`;
|
|
131
136
|
// `expo run:ios` and `expo run:android` build the port into the app, so a later app's has to be
|
|
@@ -143,6 +148,7 @@ function targets(directory, port, oneCopy) {
|
|
|
143
148
|
outputs: ['{projectRoot}/.angular-native'],
|
|
144
149
|
},
|
|
145
150
|
test: { ...run('vitest run'), cache: true, inputs: ['default', '^production'] },
|
|
151
|
+
...(lint && { lint: { ...run('eslint .'), cache: true, inputs: ['default', '^production'] } }),
|
|
146
152
|
start: { ...run(`expo start${own}`), continuous: true },
|
|
147
153
|
serve: { ...run(`expo start${own}`), continuous: true },
|
|
148
154
|
...runs,
|
|
@@ -150,13 +156,14 @@ function targets(directory, port, oneCopy) {
|
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
/** The Commands section of the app's `AGENTS.md`, as this workspace runs them. */
|
|
153
|
-
function commands(name) {
|
|
159
|
+
function commands(name, lint) {
|
|
154
160
|
const rows = [
|
|
155
161
|
[`nx start ${name}`, 'Metro; press i or a for a simulator, or scan the QR code with Expo Go'],
|
|
156
162
|
[`nx run ${name}:run-ios`, 'the iOS simulator'],
|
|
157
163
|
[`nx run ${name}:run-android`, 'the Android emulator'],
|
|
158
164
|
[`nx test ${name}`, 'Vitest, in Node against a fake native layer: no simulator needed'],
|
|
159
165
|
[`nx typecheck ${name}`, 'TypeScript, without emitting'],
|
|
166
|
+
...(lint ? [[`nx lint ${name}`, 'ESLint: what compiles but does nothing on a device']] : []),
|
|
160
167
|
];
|
|
161
168
|
const width = Math.max(...rows.map(([command]) => command.length)) + 2;
|
|
162
169
|
return [
|
|
@@ -165,7 +172,10 @@ function commands(name) {
|
|
|
165
172
|
'```',
|
|
166
173
|
'',
|
|
167
174
|
'`src/main.ts` mounts the root component, `src/app/app.ts`. ' +
|
|
168
|
-
|
|
175
|
+
(lint
|
|
176
|
+
? `Run \`nx test ${name}\`, \`nx typecheck ${name}\` and \`nx lint ${name}\` after a change; ` +
|
|
177
|
+
'all three are fast.'
|
|
178
|
+
: `Run \`nx test ${name}\` and \`nx typecheck ${name}\` after a change; both are fast.`),
|
|
169
179
|
].join('\n');
|
|
170
180
|
}
|
|
171
181
|
|
|
@@ -186,14 +196,15 @@ function listed(manifest) {
|
|
|
186
196
|
return Object.keys({ ...manifest.dependencies, ...manifest.devDependencies });
|
|
187
197
|
}
|
|
188
198
|
|
|
189
|
-
async function writeFiles(tree, { directory, projectName, workspaces, bundleIdentifier }) {
|
|
199
|
+
async function writeFiles(tree, { directory, projectName, workspaces, bundleIdentifier, lint }) {
|
|
190
200
|
const file = (name, content) => tree.write(joinPathFragments(directory, name), content);
|
|
191
201
|
for (const name of native.SOURCE_FILES) file(name, native.sourceFile(name));
|
|
192
202
|
file('app.json', native.appJson(projectName, bundleIdentifier));
|
|
193
|
-
file('AGENTS.md', native.agentsFile(commands(projectName)));
|
|
203
|
+
file('AGENTS.md', native.agentsFile(commands(projectName, lint)));
|
|
194
204
|
file('CLAUDE.md', '@AGENTS.md\n');
|
|
195
205
|
file('metro.config.js', native.METRO_CONFIG);
|
|
196
206
|
file('.gitignore', native.GITIGNORE);
|
|
207
|
+
if (lint) file('eslint.config.mjs', native.ESLINT_CONFIG);
|
|
197
208
|
|
|
198
209
|
const base = hasPathAliases(tree, workspaces);
|
|
199
210
|
const workspaceBase = base ? `${offsetFromRoot(directory)}tsconfig.base.json` : undefined;
|
|
@@ -210,7 +221,7 @@ async function writeFiles(tree, { directory, projectName, workspaces, bundleIden
|
|
|
210
221
|
const root = readJson(tree, 'package.json');
|
|
211
222
|
Object.assign(manifest, {
|
|
212
223
|
dependencies: await appDependencies(tree, root, native.dependencies),
|
|
213
|
-
devDependencies: await appDependencies(tree, root,
|
|
224
|
+
devDependencies: await appDependencies(tree, root, devDependencies(lint)),
|
|
214
225
|
});
|
|
215
226
|
} else {
|
|
216
227
|
manifest.dependencies = native.prebuildPins(root);
|
|
@@ -228,11 +239,11 @@ function ignoreExpo(tree) {
|
|
|
228
239
|
|
|
229
240
|
/**
|
|
230
241
|
* @param {import('@nx/devkit').Tree} tree
|
|
231
|
-
* @param {{ directory: string, name?: string, bundleIdentifier?: string, tags?: string, skipInstall?: boolean, skipFormat?: boolean }} options
|
|
242
|
+
* @param {{ directory: string, name?: string, bundleIdentifier?: string, tags?: string, linter?: 'eslint' | 'none', skipInstall?: boolean, skipFormat?: boolean }} options
|
|
232
243
|
*/
|
|
233
244
|
async function application(tree, options) {
|
|
234
245
|
const resolved = names(tree, options);
|
|
235
|
-
const { directory, projectName, workspaces } = resolved;
|
|
246
|
+
const { directory, projectName, workspaces, lint } = resolved;
|
|
236
247
|
const problem = native.bundleIdentifierProblem(resolved.bundleIdentifier);
|
|
237
248
|
if (problem) throw new Error(problem);
|
|
238
249
|
if (tree.exists(joinPathFragments(directory, 'package.json'))) {
|
|
@@ -244,22 +255,24 @@ async function application(tree, options) {
|
|
|
244
255
|
if (workspaces) {
|
|
245
256
|
includeInWorkspaces(tree, directory);
|
|
246
257
|
} else {
|
|
247
|
-
|
|
258
|
+
const linter = options.linter;
|
|
259
|
+
for (const problem of native.conflicts(readJson(tree, 'package.json'), { linter })) {
|
|
260
|
+
logger.warn(problem);
|
|
261
|
+
}
|
|
248
262
|
const existing = listed(readJson(tree, 'package.json'));
|
|
249
263
|
addDependenciesToPackageJson(
|
|
250
264
|
tree,
|
|
251
265
|
await asSaved(tree, native.dependencies, existing),
|
|
252
|
-
await asSaved(tree,
|
|
266
|
+
await asSaved(tree, devDependencies(lint), existing),
|
|
253
267
|
'package.json',
|
|
254
268
|
true,
|
|
255
269
|
);
|
|
256
270
|
}
|
|
257
|
-
// `
|
|
271
|
+
// `tsconfigPaths()`, which the app's Vitest config uses to reach the workspace's libraries.
|
|
258
272
|
// Added now rather than only when present, because a library generated later is the ordinary
|
|
259
273
|
// case and nothing would come back to add it then.
|
|
260
274
|
if (hasPathAliases(tree, workspaces)) {
|
|
261
|
-
|
|
262
|
-
addDependenciesToPackageJson(tree, {}, vite, 'package.json', true);
|
|
275
|
+
addDependenciesToPackageJson(tree, {}, native.vitestPathsDependencies, 'package.json', true);
|
|
263
276
|
}
|
|
264
277
|
await writeFiles(tree, resolved);
|
|
265
278
|
addProjectConfiguration(tree, projectName, {
|
|
@@ -270,7 +283,7 @@ async function application(tree, options) {
|
|
|
270
283
|
.split(',')
|
|
271
284
|
.map((tag) => tag.trim())
|
|
272
285
|
.filter(Boolean),
|
|
273
|
-
targets: targets(directory, port, linksLibraries(tree, workspaces)),
|
|
286
|
+
targets: targets(directory, port, linksLibraries(tree, workspaces), lint),
|
|
274
287
|
});
|
|
275
288
|
|
|
276
289
|
ignoreExpo(tree);
|
|
@@ -279,7 +292,9 @@ async function application(tree, options) {
|
|
|
279
292
|
if (!options.skipFormat) await formatFiles(tree);
|
|
280
293
|
logger.info(
|
|
281
294
|
`Created ${directory}. nx start ${projectName} runs Metro; nx run ${projectName}:run-ios, ` +
|
|
282
|
-
`nx test ${projectName}, nx typecheck ${projectName},
|
|
295
|
+
`nx test ${projectName}, nx typecheck ${projectName}, ` +
|
|
296
|
+
(lint ? `nx lint ${projectName}, ` : '') +
|
|
297
|
+
`nx export ${projectName}.`,
|
|
283
298
|
);
|
|
284
299
|
if (options.skipInstall) return initTask;
|
|
285
300
|
return runTasksInSerial(initTask, () => installPackagesTask(tree, true));
|
package/application/schema.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"directory": {
|
|
9
9
|
"type": "string",
|
|
10
10
|
"description": "Where the app goes, relative to the workspace root: apps/mobile.",
|
|
11
|
-
"$default": {
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
},
|
|
12
15
|
"x-prompt": "Which directory should the app be created in?"
|
|
13
16
|
},
|
|
14
17
|
"name": {
|
|
@@ -24,6 +27,12 @@
|
|
|
24
27
|
"type": "string",
|
|
25
28
|
"description": "Comma-separated tags for the project."
|
|
26
29
|
},
|
|
30
|
+
"linter": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "eslint adds an eslint.config.mjs with @ng-native/eslint-plugin's recommended rules, its dependencies and a lint target.",
|
|
33
|
+
"enum": ["eslint", "none"],
|
|
34
|
+
"default": "none"
|
|
35
|
+
},
|
|
27
36
|
"skipInstall": {
|
|
28
37
|
"type": "boolean",
|
|
29
38
|
"description": "Write the files without installing.",
|
package/files/AGENTS.md
CHANGED
|
@@ -83,3 +83,7 @@ change; both are fast.
|
|
|
83
83
|
`getByText` or `getByTestId` (which matches `nativeID` and `testID`), and act with
|
|
84
84
|
`userEvent.setup().press(...)` or `.type(...)`, all from `@ng-native/testing`. Tests run in Node
|
|
85
85
|
with no simulator, so write one alongside a change.
|
|
86
|
+
|
|
87
|
+
A service that depends on the platform injects `OS` and `OS_VERSION` from `@ng-native/device`
|
|
88
|
+
rather than importing `Platform` from `react-native`, which a test cannot load. A test provides
|
|
89
|
+
the values it wants: `{ provide: OS, useValue: 'android' }`.
|
package/files/src/main.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { App } from './app/app.ts';
|
|
|
10
10
|
|
|
11
11
|
registerPlatformComponents(Platform.OS);
|
|
12
12
|
|
|
13
|
-
AppRegistry.registerRunnable('main', ({ rootTag }
|
|
13
|
+
AppRegistry.registerRunnable('main', ({ rootTag }) => {
|
|
14
14
|
const app = mount(Number(rootTag), App, getFabricUIManager(), {
|
|
15
15
|
// Colours, as the integers the platform wants.
|
|
16
16
|
processColor,
|
|
@@ -26,6 +26,8 @@ AppRegistry.registerRunnable('main', ({ rootTag }: { rootTag: number | string })
|
|
|
26
26
|
|
|
27
27
|
// Re-resolves the conditions when the device rotates or the theme changes. A rotation dirties
|
|
28
28
|
// no component and no binding, so without this nothing re-renders and `dark:` stops following
|
|
29
|
-
// the system switch.
|
|
30
|
-
|
|
29
|
+
// the system switch. It stops with the app, which Android destroys when it recreates the
|
|
30
|
+
// activity, so the app mounted in its place is the only one still watching.
|
|
31
|
+
const stopWatching = watchConditions(app.engine);
|
|
32
|
+
app.applicationRef.onDestroy(stopWatching);
|
|
31
33
|
});
|
package/library/index.cjs
CHANGED
|
@@ -328,10 +328,9 @@ async function library(tree, options) {
|
|
|
328
328
|
});
|
|
329
329
|
|
|
330
330
|
await addImports(tree, directory, angular ? {} : typecheckDependencies);
|
|
331
|
-
// `
|
|
331
|
+
// `tsconfigPaths()`, which the Vitest config uses to reach the workspace's other libraries.
|
|
332
332
|
if (aliases) {
|
|
333
|
-
|
|
334
|
-
addDependenciesToPackageJson(tree, {}, vite, 'package.json', true);
|
|
333
|
+
addDependenciesToPackageJson(tree, {}, native.vitestPathsDependencies, 'package.json', true);
|
|
335
334
|
}
|
|
336
335
|
|
|
337
336
|
if (!options.skipFormat) await formatFiles(tree);
|
package/migrations.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generators": {
|
|
3
3
|
"sync-app-versions": {
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.18.1",
|
|
5
5
|
"description": "Move the @ng-native packages each project's own package.json lists to the new version.",
|
|
6
6
|
"implementation": "./migrations/run.cjs#sync-app-versions"
|
|
7
7
|
},
|
|
@@ -39,6 +39,16 @@
|
|
|
39
39
|
"version": "0.17.1",
|
|
40
40
|
"description": "Give each Angular Native project in angular.json a typecheck target, run by ngc.",
|
|
41
41
|
"implementation": "./migrations/run.cjs#native-typecheck-target"
|
|
42
|
+
},
|
|
43
|
+
"stop-watching-conditions": {
|
|
44
|
+
"version": "0.17.2",
|
|
45
|
+
"description": "Keep what watchConditions returns in each app's entry point and stop it as the app is destroyed.",
|
|
46
|
+
"implementation": "./migrations/run.cjs#stop-watching-conditions"
|
|
47
|
+
},
|
|
48
|
+
"vitest-tsconfig-paths": {
|
|
49
|
+
"version": "0.18.1",
|
|
50
|
+
"description": "Resolve the workspace's path aliases in Nx Vitest configs with vite-tsconfig-paths, as nxViteTsPaths does nothing from Nx 24.",
|
|
51
|
+
"implementation": "./migrations/run.cjs#vitest-tsconfig-paths"
|
|
42
52
|
}
|
|
43
53
|
}
|
|
44
54
|
}
|
package/native-app.cjs
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* import a library at all: Metro reports `Cannot resolve @org/ui`.
|
|
14
14
|
* - `tsconfig.json` also extends the workspace's `tsconfig.base.json` when there is one, which is
|
|
15
15
|
* where those aliases live, and puts back the Expo settings the workspace's base overrides.
|
|
16
|
-
* - `vitest.config.mts` adds `
|
|
17
|
-
* aliases, which Vitest does not read from tsconfig either.
|
|
16
|
+
* - `vitest.config.mts` adds `vite-tsconfig-paths` when the workspace has path aliases, for the
|
|
17
|
+
* same aliases, which Vitest does not read from tsconfig either. It is what Nx 24 writes in its
|
|
18
|
+
* own Vite configs: `nxViteTsPaths` from `@nx/vite` is an inert stub there.
|
|
18
19
|
*
|
|
19
20
|
* What does not depend on Nx, the dependencies, `app.json` and bundle identifier among them, is
|
|
20
21
|
* `@ng-native/migrate/native-app.cjs`, which `@ng-native/schematics` builds its apps from too.
|
|
@@ -33,10 +34,10 @@ const { dependencies, devDependencies, accepted } = shared;
|
|
|
33
34
|
*/
|
|
34
35
|
const expoCompanions = {
|
|
35
36
|
'react-dom': dependencies.react,
|
|
36
|
-
'@expo/cli': '^
|
|
37
|
+
'@expo/cli': '^58.1.14',
|
|
37
38
|
'@babel/runtime': '^7.20.0',
|
|
38
39
|
'@babel/core': devDependencies['@babel/core'],
|
|
39
|
-
'@expo/metro': '~
|
|
40
|
+
'@expo/metro': '~58.0.0',
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
/**
|
|
@@ -98,13 +99,13 @@ function tsconfig(workspaceBase, conditions = []) {
|
|
|
98
99
|
const customConditions = ['react-native', ...conditions.filter((c) => c !== 'react-native')];
|
|
99
100
|
if (!workspaceBase) {
|
|
100
101
|
if (customConditions.length > 1) compilerOptions.customConditions = customConditions;
|
|
101
|
-
return { extends: 'expo/tsconfig.base', compilerOptions, angularCompilerOptions };
|
|
102
|
+
return { extends: 'expo/tsconfig.base.json', compilerOptions, angularCompilerOptions };
|
|
102
103
|
}
|
|
103
104
|
// The workspace's base is written for a web build or for emitting declarations, and wins over
|
|
104
105
|
// Expo's where they overlap. These are Expo's, restored: without `DOM` and `ESNext` the framework
|
|
105
106
|
// packages' own source, which the app compiles, fails to typecheck.
|
|
106
107
|
return {
|
|
107
|
-
extends: ['expo/tsconfig.base', workspaceBase],
|
|
108
|
+
extends: ['expo/tsconfig.base.json', workspaceBase],
|
|
108
109
|
compilerOptions: {
|
|
109
110
|
...compilerOptions,
|
|
110
111
|
noEmit: true,
|
|
@@ -122,7 +123,7 @@ function tsconfig(workspaceBase, conditions = []) {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
/** The `@ng-native` packages with entry points beside their main one, each published in `dist`. */
|
|
125
|
-
const WITH_ENTRY_POINTS = ['components', 'expo', 'platform', 'web'];
|
|
126
|
+
const WITH_ENTRY_POINTS = ['components', 'expo', 'platform', 'web', 'web-compat'];
|
|
126
127
|
|
|
127
128
|
/** `nx typecheck` in a workspace whose libraries are the package manager's links. */
|
|
128
129
|
const TYPECHECK_ONE_COPY = TYPECHECK.replace('tsconfig.json', 'tsconfig.typecheck.json');
|
|
@@ -153,12 +154,22 @@ function vitestConfig(withPaths) {
|
|
|
153
154
|
return template
|
|
154
155
|
.replace(
|
|
155
156
|
"import { defineConfig } from 'vitest/config';",
|
|
156
|
-
"import
|
|
157
|
+
"import tsconfigPaths from 'vite-tsconfig-paths';\n" +
|
|
157
158
|
"import { defineConfig } from 'vitest/config';",
|
|
158
159
|
)
|
|
159
|
-
.replace('plugins: [ngNative()],', 'plugins: [
|
|
160
|
+
.replace('plugins: [ngNative()],', 'plugins: [tsconfigPaths(), ngNative()],');
|
|
160
161
|
}
|
|
161
162
|
|
|
163
|
+
/**
|
|
164
|
+
* What `vitestConfig(true)` imports, at the range Nx 24 adds for its own Vite configs, and Vite at
|
|
165
|
+
* the range `@ng-native/testing` peers on. Both peer on Vite optionally, so npm installs it for
|
|
166
|
+
* neither, and an integrated workspace from the `angular-monorepo` preset may have none at its root.
|
|
167
|
+
*/
|
|
168
|
+
const vitestPathsDependencies = {
|
|
169
|
+
'vite-tsconfig-paths': '^5.1.4',
|
|
170
|
+
vite: '^6.0.0 || ^7.0.0 || ^8.0.0',
|
|
171
|
+
};
|
|
172
|
+
|
|
162
173
|
/**
|
|
163
174
|
* The ranges a workspace package's `package.json` lists: the root's own where everything it can
|
|
164
175
|
* resolve to is a version Angular Native accepts, so that pnpm does not install a second Vitest
|
|
@@ -195,6 +206,7 @@ module.exports = {
|
|
|
195
206
|
tsconfig,
|
|
196
207
|
typecheckTsconfig,
|
|
197
208
|
vitestConfig,
|
|
209
|
+
vitestPathsDependencies,
|
|
198
210
|
reuseRootRanges,
|
|
199
211
|
expoCompanions,
|
|
200
212
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-native/nx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "Nx generators for Angular Native: nx add, an Expo app project whose targets run it, and native libraries and components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"@ng-native/analog",
|
|
24
24
|
"@ng-native/components",
|
|
25
25
|
"@ng-native/device",
|
|
26
|
+
"@ng-native/eslint-plugin",
|
|
26
27
|
"@ng-native/expo",
|
|
27
28
|
"@ng-native/fabric",
|
|
28
29
|
"@ng-native/icons",
|
|
@@ -39,13 +40,13 @@
|
|
|
39
40
|
]
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"@ng-native/migrate": "0.
|
|
43
|
-
"@nx/devkit": "^23.0.0",
|
|
43
|
+
"@ng-native/migrate": "0.18.1",
|
|
44
|
+
"@nx/devkit": "^23.0.0 || ^24.0.0",
|
|
44
45
|
"minimatch": "^10.0.0",
|
|
45
46
|
"semver": "^7.7.0"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
|
-
"nx": "^23.0.0"
|
|
49
|
+
"nx": "^23.0.0 || ^24.0.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/semver": "^7.7.0",
|