@schematics/angular 21.0.0-next.0 → 21.0.0-next.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 (69) hide show
  1. package/ai-config/index.js +5 -3
  2. package/ai-config/schema.json +1 -17
  3. package/app-shell/index.d.ts +2 -1
  4. package/app-shell/index.js +16 -24
  5. package/application/index.js +29 -1
  6. package/application/schema.d.ts +19 -1
  7. package/application/schema.js +13 -1
  8. package/application/schema.json +12 -2
  9. package/collection.json +7 -0
  10. package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template +6 -6
  11. package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template +1 -1
  12. package/component/index.d.ts +2 -1
  13. package/component/index.js +49 -53
  14. package/component/schema.d.ts +5 -0
  15. package/component/schema.json +5 -0
  16. package/config/index.d.ts +2 -1
  17. package/config/index.js +12 -19
  18. package/directive/files/__name@dasherize__.__type@dasherize__.spec.ts.template +3 -3
  19. package/directive/files/__name@dasherize__.__type@dasherize__.ts.template +1 -1
  20. package/directive/index.d.ts +2 -1
  21. package/directive/index.js +25 -27
  22. package/directive/schema.d.ts +5 -0
  23. package/directive/schema.json +5 -0
  24. package/migrations/karma/karma-config-comparer.js +1 -1
  25. package/migrations/migration-collection.json +1 -0
  26. package/module/index.d.ts +2 -1
  27. package/module/index.js +48 -50
  28. package/ng-new/index.js +1 -0
  29. package/ng-new/schema.d.ts +19 -2
  30. package/ng-new/schema.js +13 -2
  31. package/ng-new/schema.json +8 -2
  32. package/package.json +4 -4
  33. package/pipe/index.d.ts +2 -2
  34. package/pipe/index.js +16 -18
  35. package/server/index.d.ts +2 -1
  36. package/server/index.js +67 -71
  37. package/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template +4 -4
  38. package/service/files/__name@dasherize__.__type@dasherize__.ts.template +1 -1
  39. package/service/index.d.ts +2 -1
  40. package/service/index.js +20 -4
  41. package/service/schema.d.ts +5 -0
  42. package/service/schema.json +5 -0
  43. package/service-worker/index.d.ts +2 -1
  44. package/service-worker/index.js +44 -81
  45. package/ssr/index.d.ts +2 -1
  46. package/ssr/index.js +32 -40
  47. package/tailwind/files/.postcssrc.json.template +5 -0
  48. package/tailwind/index.d.ts +12 -0
  49. package/tailwind/index.js +105 -0
  50. package/tailwind/schema.d.ts +7 -0
  51. package/tailwind/schema.js +4 -0
  52. package/tailwind/schema.json +15 -0
  53. package/utility/ast-utils.js +31 -17
  54. package/utility/generate-from-files.d.ts +1 -0
  55. package/utility/latest-versions/package.json +3 -1
  56. package/utility/latest-versions.js +3 -3
  57. package/utility/project.d.ts +25 -0
  58. package/utility/project.js +30 -0
  59. package/utility/standalone/rules.js +2 -3
  60. package/web-worker/index.d.ts +2 -1
  61. package/web-worker/index.js +60 -70
  62. package/workspace/schema.d.ts +0 -1
  63. package/workspace/schema.js +0 -1
  64. package/workspace/schema.json +1 -1
  65. /package/application/files/common-files/src/app/{app.html.template → app__suffix__.html.template} +0 -0
  66. /package/application/files/module-files/src/app/{app.spec.ts.template → app__suffix__.spec.ts.template} +0 -0
  67. /package/application/files/module-files/src/app/{app.ts.template → app__suffix__.ts.template} +0 -0
  68. /package/application/files/standalone-files/src/app/{app.spec.ts.template → app__suffix__.spec.ts.template} +0 -0
  69. /package/application/files/standalone-files/src/app/{app.ts.template → app__suffix__.ts.template} +0 -0
@@ -57,7 +57,6 @@ exports.isImported = isImported;
57
57
  exports.getRouterModuleDeclaration = getRouterModuleDeclaration;
58
58
  exports.addRouteDeclarationToModule = addRouteDeclarationToModule;
59
59
  exports.hasTopLevelIdentifier = hasTopLevelIdentifier;
60
- const core_1 = require("@angular-devkit/core");
61
60
  const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
62
61
  const change_1 = require("./change");
63
62
  const eol_1 = require("./eol");
@@ -116,6 +115,7 @@ function insertImport(source, fileToEdit, symbolName, fileName, isDefault = fals
116
115
  ` from '${fileName}'${insertAtBeginning ? `;${eol}` : ''}`;
117
116
  return insertAfterLastOccurrence(allImports, toInsert, fileToEdit, fallbackPos, ts.SyntaxKind.StringLiteral);
118
117
  }
118
+ const findNodesCache = new WeakMap();
119
119
  function findNodes(node, kindOrGuard, max = Infinity, recursive = false) {
120
120
  if (!node || max == 0) {
121
121
  return [];
@@ -123,6 +123,13 @@ function findNodes(node, kindOrGuard, max = Infinity, recursive = false) {
123
123
  const test = typeof kindOrGuard === 'function'
124
124
  ? kindOrGuard
125
125
  : (node) => node.kind === kindOrGuard;
126
+ // Caching is only supported for the entire file
127
+ if (ts.isSourceFile(node)) {
128
+ const sourceFileCache = findNodesCache.get(node);
129
+ if (sourceFileCache?.has(kindOrGuard)) {
130
+ return sourceFileCache.get(kindOrGuard);
131
+ }
132
+ }
126
133
  const arr = [];
127
134
  if (test(node)) {
128
135
  arr.push(node);
@@ -141,6 +148,14 @@ function findNodes(node, kindOrGuard, max = Infinity, recursive = false) {
141
148
  }
142
149
  }
143
150
  }
151
+ if (ts.isSourceFile(node)) {
152
+ let sourceFileCache = findNodesCache.get(node);
153
+ if (!sourceFileCache) {
154
+ sourceFileCache = new Map();
155
+ findNodesCache.set(node, sourceFileCache);
156
+ }
157
+ sourceFileCache.set(kindOrGuard, arr);
158
+ }
144
159
  return arr;
145
160
  }
146
161
  /**
@@ -150,17 +165,12 @@ function findNodes(node, kindOrGuard, max = Infinity, recursive = false) {
150
165
  */
151
166
  function getSourceNodes(sourceFile) {
152
167
  const nodes = [sourceFile];
153
- const result = [];
154
- while (nodes.length > 0) {
155
- const node = nodes.shift();
156
- if (node) {
157
- result.push(node);
158
- if (node.getChildCount(sourceFile) >= 0) {
159
- nodes.unshift(...node.getChildren());
160
- }
161
- }
168
+ // NOTE: nodes.length changes inside of the loop but we only append to the end
169
+ for (let i = 0; i < nodes.length; i++) {
170
+ const node = nodes[i];
171
+ nodes.push(...node.getChildren(sourceFile));
162
172
  }
163
- return result;
173
+ return nodes;
164
174
  }
165
175
  function findNode(node, kind, text) {
166
176
  if (node.kind === kind && node.getText() === text) {
@@ -312,7 +322,11 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
312
322
  let toInsert;
313
323
  if (node.properties.length == 0) {
314
324
  position = node.getEnd() - 1;
315
- toInsert = `\n ${metadataField}: [\n${core_1.tags.indentBy(4) `${symbolName}`}\n ]\n`;
325
+ toInsert = `
326
+ ${metadataField}: [
327
+ ${' '.repeat(4)}${symbolName}
328
+ ]
329
+ `;
316
330
  }
317
331
  else {
318
332
  const childNode = node.properties[node.properties.length - 1];
@@ -323,7 +337,7 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
323
337
  if (matches) {
324
338
  toInsert =
325
339
  `,${matches[0]}${metadataField}: [${matches[1]}` +
326
- `${core_1.tags.indentBy(matches[2].length + 2) `${symbolName}`}${matches[0]}]`;
340
+ `${' '.repeat(matches[2].length + 2)}${symbolName}${matches[0]}]`;
327
341
  }
328
342
  else {
329
343
  toInsert = `, ${metadataField}: [${symbolName}]`;
@@ -349,8 +363,8 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
349
363
  const assignmentInit = assignment.initializer;
350
364
  const elements = assignmentInit.elements;
351
365
  if (elements.length) {
352
- const symbolsArray = elements.map((node) => core_1.tags.oneLine `${node.getText()}`);
353
- if (symbolsArray.includes(core_1.tags.oneLine `${symbolName}`)) {
366
+ const symbolsArray = elements.map((node) => node.getText());
367
+ if (symbolsArray.includes(symbolName)) {
354
368
  return [];
355
369
  }
356
370
  expression = elements[elements.length - 1];
@@ -363,14 +377,14 @@ function addSymbolToNgModuleMetadata(source, ngModulePath, metadataField, symbol
363
377
  if (ts.isArrayLiteralExpression(expression)) {
364
378
  // We found the field but it's empty. Insert it just before the `]`.
365
379
  position--;
366
- toInsert = `\n${core_1.tags.indentBy(4) `${symbolName}`}\n `;
380
+ toInsert = `\n${' '.repeat(4)}${symbolName}\n `;
367
381
  }
368
382
  else {
369
383
  // Get the indentation of the last element, if any.
370
384
  const text = expression.getFullText(source);
371
385
  const matches = text.match(/^(\r?\n)(\s*)/);
372
386
  if (matches) {
373
- toInsert = `,${matches[1]}${core_1.tags.indentBy(matches[2].length) `${symbolName}`}`;
387
+ toInsert = `,${matches[1]}${' '.repeat(matches[2].length)}${symbolName}`;
374
388
  }
375
389
  else {
376
390
  toInsert = `, ${symbolName}`;
@@ -15,5 +15,6 @@ export interface GenerateFromFilesOptions {
15
15
  skipTests?: boolean;
16
16
  templateFilesDirectory?: string;
17
17
  type?: string;
18
+ classifiedName?: string;
18
19
  }
19
20
  export declare function generateFromFiles(options: GenerateFromFilesOptions, extraTemplateValues?: Record<string, string | ((v: string) => string)>): Rule;
@@ -8,7 +8,7 @@
8
8
  "@types/node": "^20.17.19",
9
9
  "browser-sync": "^3.0.0",
10
10
  "express": "^5.1.0",
11
- "jasmine-core": "~5.9.0",
11
+ "jasmine-core": "~5.10.0",
12
12
  "jasmine-spec-reporter": "~7.0.0",
13
13
  "karma-chrome-launcher": "~3.2.0",
14
14
  "karma-coverage": "~2.2.0",
@@ -19,6 +19,8 @@
19
19
  "postcss": "^8.5.3",
20
20
  "protractor": "~7.0.0",
21
21
  "rxjs": "~7.8.0",
22
+ "tailwindcss": "^4.1.12",
23
+ "@tailwindcss/postcss": "^4.1.12",
22
24
  "tslib": "^2.3.0",
23
25
  "ts-node": "~10.9.0",
24
26
  "typescript": "~5.9.2",
@@ -16,7 +16,7 @@ exports.latestVersions = {
16
16
  // As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
17
17
  Angular: '^21.0.0-next.0',
18
18
  NgPackagr: '^21.0.0-next.0',
19
- DevkitBuildAngular: '^21.0.0-next.0',
20
- AngularBuild: '^21.0.0-next.0',
21
- AngularSSR: '^21.0.0-next.0',
19
+ DevkitBuildAngular: '^21.0.0-next.2',
20
+ AngularBuild: '^21.0.0-next.2',
21
+ AngularSSR: '^21.0.0-next.2',
22
22
  };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
9
+ import { ProjectDefinition, WorkspaceDefinition } from './workspace';
10
+ /**
11
+ * Creates a schematic rule factory that provides project information to the given factory function.
12
+ * The project is determined from the `project` option. If the project is not found, an exception is
13
+ * thrown.
14
+ *
15
+ * @param factory The factory function that creates the schematic rule.
16
+ * @returns A schematic rule factory.
17
+ */
18
+ export declare function createProjectSchematic<S extends {
19
+ project: string;
20
+ }>(factory: (options: S, projectContext: {
21
+ project: ProjectDefinition;
22
+ workspace: WorkspaceDefinition;
23
+ tree: Tree;
24
+ context: SchematicContext;
25
+ }) => Rule | Promise<Rule>): (options: S) => Rule;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createProjectSchematic = createProjectSchematic;
11
+ const schematics_1 = require("@angular-devkit/schematics");
12
+ const workspace_1 = require("./workspace");
13
+ /**
14
+ * Creates a schematic rule factory that provides project information to the given factory function.
15
+ * The project is determined from the `project` option. If the project is not found, an exception is
16
+ * thrown.
17
+ *
18
+ * @param factory The factory function that creates the schematic rule.
19
+ * @returns A schematic rule factory.
20
+ */
21
+ function createProjectSchematic(factory) {
22
+ return (options) => async (tree, context) => {
23
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
24
+ const project = workspace.projects.get(options.project);
25
+ if (!project) {
26
+ throw new schematics_1.SchematicsException(`Project "${options.project}" does not exist.`);
27
+ }
28
+ return factory(options, { project, workspace, tree, context });
29
+ };
30
+ }
@@ -9,7 +9,6 @@
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.addRootImport = addRootImport;
11
11
  exports.addRootProvider = addRootProvider;
12
- const core_1 = require("@angular-devkit/core");
13
12
  const schematics_1 = require("@angular-devkit/schematics");
14
13
  const ast_utils_1 = require("../ast-utils");
15
14
  const change_1 = require("../change");
@@ -137,7 +136,7 @@ function insertStandaloneRootProvider(tree, mainFilePath, expression) {
137
136
  addProvidersExpressionToAppConfig(tree, appConfig, expression);
138
137
  return;
139
138
  }
140
- const newAppConfig = `, {\n${core_1.tags.indentBy(2) `providers: [${expression}]`}\n}`;
139
+ const newAppConfig = `, {\n${' '.repeat(2)}providers: [${expression}]\n}`;
141
140
  let targetCall;
142
141
  if (bootstrapCall.arguments.length === 1) {
143
142
  targetCall = bootstrapCall;
@@ -170,7 +169,7 @@ function addProvidersExpressionToAppConfig(tree, appConfig, expression) {
170
169
  ]);
171
170
  }
172
171
  else {
173
- const prop = core_1.tags.indentBy(2) `providers: [${expression}]`;
172
+ const prop = `${' '.repeat(2)}providers: [${expression}]`;
174
173
  let toInsert;
175
174
  let insertPosition;
176
175
  if (configProps.length === 0) {
@@ -7,4 +7,5 @@
7
7
  */
8
8
  import { Rule } from '@angular-devkit/schematics';
9
9
  import { Schema as WebWorkerOptions } from './schema';
10
- export default function (options: WebWorkerOptions): Rule;
10
+ declare const _default: (options: WebWorkerOptions) => Rule;
11
+ export default _default;
@@ -7,11 +7,11 @@
7
7
  * found in the LICENSE file at https://angular.dev/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.default = default_1;
11
- const core_1 = require("@angular-devkit/core");
12
10
  const schematics_1 = require("@angular-devkit/schematics");
11
+ const posix_1 = require("node:path/posix");
13
12
  const parse_name_1 = require("../utility/parse-name");
14
13
  const paths_1 = require("../utility/paths");
14
+ const project_1 = require("../utility/project");
15
15
  const workspace_1 = require("../utility/workspace");
16
16
  function addSnippet(options) {
17
17
  return (host, context) => {
@@ -33,18 +33,18 @@ function addSnippet(options) {
33
33
  }
34
34
  const siblingModulePath = `${options.path}/${siblingModules[0]}`;
35
35
  const logMessage = 'console.log(`page got message: ${data}`);';
36
- const workerCreationSnippet = core_1.tags.stripIndent `
37
- if (typeof Worker !== 'undefined') {
38
- // Create a new
39
- const worker = new Worker(new URL('./${options.name}.worker', import.meta.url));
40
- worker.onmessage = ({ data }) => {
41
- ${logMessage}
42
- };
43
- worker.postMessage('hello');
44
- } else {
45
- // Web Workers are not supported in this environment.
46
- // You should add a fallback so that your program still executes correctly.
47
- }
36
+ const workerCreationSnippet = `
37
+ if (typeof Worker !== 'undefined') {
38
+ // Create a new
39
+ const worker = new Worker(new URL('./${options.name}.worker', import.meta.url));
40
+ worker.onmessage = ({ data }) => {
41
+ ${logMessage}
42
+ };
43
+ worker.postMessage('hello');
44
+ } else {
45
+ // Web Workers are not supported in this environment.
46
+ // You should add a fallback so that your program still executes correctly.
47
+ }
48
48
  `;
49
49
  // Append the worker creation snippet.
50
50
  const originalContent = host.readText(siblingModulePath);
@@ -52,59 +52,49 @@ function addSnippet(options) {
52
52
  return host;
53
53
  };
54
54
  }
55
- function default_1(options) {
56
- return async (host) => {
57
- const workspace = await (0, workspace_1.getWorkspace)(host);
58
- if (!options.project) {
59
- throw new schematics_1.SchematicsException('Option "project" is required.');
60
- }
61
- const project = workspace.projects.get(options.project);
62
- if (!project) {
63
- throw new schematics_1.SchematicsException(`Invalid project name (${options.project})`);
64
- }
65
- const projectType = project.extensions['projectType'];
66
- if (projectType !== 'application') {
67
- throw new schematics_1.SchematicsException(`Web Worker requires a project type of "application".`);
68
- }
69
- if (options.path === undefined) {
70
- options.path = (0, workspace_1.buildDefaultPath)(project);
71
- }
72
- const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
73
- options.name = parsedPath.name;
74
- options.path = parsedPath.path;
75
- const templateSourceWorkerCode = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker'), [
76
- (0, schematics_1.applyTemplates)({ ...options, ...schematics_1.strings }),
77
- (0, schematics_1.move)(parsedPath.path),
78
- ]);
79
- const root = project.root || '';
80
- const templateSourceWorkerConfig = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker-tsconfig'), [
81
- (0, schematics_1.applyTemplates)({
82
- ...options,
83
- relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(root),
84
- }),
85
- (0, schematics_1.move)(root),
86
- ]);
87
- return (0, schematics_1.chain)([
88
- // Add project configuration.
89
- (0, workspace_1.updateWorkspace)((workspace) => {
90
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
91
- const project = workspace.projects.get(options.project);
92
- const buildTarget = project.targets.get('build');
93
- const testTarget = project.targets.get('test');
94
- if (!buildTarget) {
95
- throw new Error(`Build target is not defined for this project.`);
96
- }
97
- const workerConfigPath = (0, core_1.join)((0, core_1.normalize)(root), 'tsconfig.worker.json');
98
- (buildTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
99
- if (testTarget) {
100
- (testTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
101
- }
102
- }),
103
- // Create the worker in a sibling module.
104
- options.snippet ? addSnippet(options) : (0, schematics_1.noop)(),
105
- // Add the worker.
106
- (0, schematics_1.mergeWith)(templateSourceWorkerCode),
107
- (0, schematics_1.mergeWith)(templateSourceWorkerConfig),
108
- ]);
109
- };
110
- }
55
+ exports.default = (0, project_1.createProjectSchematic)((options, { project }) => {
56
+ const projectType = project.extensions['projectType'];
57
+ if (projectType !== 'application') {
58
+ throw new schematics_1.SchematicsException(`Web Worker requires a project type of "application".`);
59
+ }
60
+ if (options.path === undefined) {
61
+ options.path = (0, workspace_1.buildDefaultPath)(project);
62
+ }
63
+ const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
64
+ options.name = parsedPath.name;
65
+ options.path = parsedPath.path;
66
+ const templateSourceWorkerCode = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker'), [
67
+ (0, schematics_1.applyTemplates)({ ...options, ...schematics_1.strings }),
68
+ (0, schematics_1.move)(parsedPath.path),
69
+ ]);
70
+ const root = project.root || '';
71
+ const templateSourceWorkerConfig = (0, schematics_1.apply)((0, schematics_1.url)('./files/worker-tsconfig'), [
72
+ (0, schematics_1.applyTemplates)({
73
+ ...options,
74
+ relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(root),
75
+ }),
76
+ (0, schematics_1.move)(root),
77
+ ]);
78
+ return (0, schematics_1.chain)([
79
+ // Add project configuration.
80
+ (0, workspace_1.updateWorkspace)((workspace) => {
81
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
82
+ const project = workspace.projects.get(options.project);
83
+ const buildTarget = project.targets.get('build');
84
+ const testTarget = project.targets.get('test');
85
+ if (!buildTarget) {
86
+ throw new Error(`Build target is not defined for this project.`);
87
+ }
88
+ const workerConfigPath = (0, posix_1.join)(root, 'tsconfig.worker.json');
89
+ (buildTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
90
+ if (testTarget) {
91
+ (testTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath;
92
+ }
93
+ }),
94
+ // Create the worker in a sibling module.
95
+ options.snippet ? addSnippet(options) : (0, schematics_1.noop)(),
96
+ // Add the worker.
97
+ (0, schematics_1.mergeWith)(templateSourceWorkerCode),
98
+ (0, schematics_1.mergeWith)(templateSourceWorkerConfig),
99
+ ]);
100
+ });
@@ -40,7 +40,6 @@ export type Schema = {
40
40
  */
41
41
  export declare enum PackageManager {
42
42
  Bun = "bun",
43
- Cnpm = "cnpm",
44
43
  Npm = "npm",
45
44
  Pnpm = "pnpm",
46
45
  Yarn = "yarn"
@@ -9,7 +9,6 @@ exports.PackageManager = void 0;
9
9
  var PackageManager;
10
10
  (function (PackageManager) {
11
11
  PackageManager["Bun"] = "bun";
12
- PackageManager["Cnpm"] = "cnpm";
13
12
  PackageManager["Npm"] = "npm";
14
13
  PackageManager["Pnpm"] = "pnpm";
15
14
  PackageManager["Yarn"] = "yarn";
@@ -40,7 +40,7 @@
40
40
  "packageManager": {
41
41
  "description": "The package manager to use for installing dependencies.",
42
42
  "type": "string",
43
- "enum": ["npm", "yarn", "pnpm", "cnpm", "bun"]
43
+ "enum": ["npm", "yarn", "pnpm", "bun"]
44
44
  }
45
45
  },
46
46
  "required": ["name", "version"]