@nestjs/schematics 12.0.0-alpha.7 → 12.0.0-alpha.9

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 (50) hide show
  1. package/dist/lib/application/application.factory.js +7 -3
  2. package/dist/lib/application/files/js/package.json +9 -9
  3. package/dist/lib/application/files/js/test/app.e2e-__specFileSuffix__.js +4 -0
  4. package/dist/lib/application/files/ts/oxlint.json +10 -0
  5. package/dist/lib/application/files/ts/package.json +9 -14
  6. package/dist/lib/application/files/ts/test/app.e2e-__specFileSuffix__.ts +4 -0
  7. package/dist/lib/application/files/ts-esm/oxlint.json +10 -0
  8. package/dist/lib/application/files/ts-esm/package.json +10 -15
  9. package/dist/lib/application/schema.json +5 -0
  10. package/dist/lib/class/class.factory.js +2 -0
  11. package/dist/lib/class/schema.json +5 -0
  12. package/dist/lib/controller/controller.factory.js +7 -4
  13. package/dist/lib/controller/schema.json +5 -0
  14. package/dist/lib/decorator/decorator.factory.js +7 -2
  15. package/dist/lib/decorator/schema.json +5 -0
  16. package/dist/lib/filter/filter.factory.js +2 -0
  17. package/dist/lib/filter/schema.json +5 -0
  18. package/dist/lib/gateway/gateway.factory.js +7 -4
  19. package/dist/lib/gateway/schema.json +5 -0
  20. package/dist/lib/guard/guard.factory.js +2 -0
  21. package/dist/lib/guard/schema.json +5 -0
  22. package/dist/lib/interceptor/interceptor.factory.js +2 -0
  23. package/dist/lib/interceptor/schema.json +5 -0
  24. package/dist/lib/interface/interface.factory.js +7 -2
  25. package/dist/lib/interface/schema.json +5 -0
  26. package/dist/lib/library/library.factory.js +3 -1
  27. package/dist/lib/library/schema.json +5 -0
  28. package/dist/lib/middleware/middleware.factory.js +2 -0
  29. package/dist/lib/middleware/schema.json +5 -0
  30. package/dist/lib/module/module.factory.js +8 -5
  31. package/dist/lib/module/schema.json +5 -0
  32. package/dist/lib/pipe/pipe.factory.js +2 -0
  33. package/dist/lib/pipe/schema.json +5 -0
  34. package/dist/lib/provider/provider.factory.js +7 -4
  35. package/dist/lib/provider/schema.json +5 -0
  36. package/dist/lib/resolver/resolver.factory.js +7 -4
  37. package/dist/lib/resolver/schema.json +5 -0
  38. package/dist/lib/resource/resource.factory.js +11 -8
  39. package/dist/lib/resource/schema.json +5 -0
  40. package/dist/lib/service/schema.json +5 -0
  41. package/dist/lib/service/service.factory.js +7 -4
  42. package/dist/lib/sub-app/schema.json +5 -0
  43. package/dist/lib/sub-app/sub-app.factory.js +7 -1
  44. package/dist/utils/format-files.rule.d.ts +3 -0
  45. package/dist/utils/format-files.rule.js +45 -0
  46. package/dist/utils/index.d.ts +1 -0
  47. package/dist/utils/index.js +1 -0
  48. package/package.json +14 -11
  49. package/dist/lib/application/files/ts/eslint.config.mjs +0 -34
  50. package/dist/lib/application/files/ts-esm/eslint.config.mjs +0 -33
@@ -1,6 +1,7 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
- import { apply, filter, mergeWith, move, noop, template, url, } from '@angular-devkit/schematics';
2
+ import { apply, chain, filter, mergeWith, move, noop, template, url, } from '@angular-devkit/schematics';
3
3
  import { basename, parse } from 'path';
4
+ import { formatFiles } from '../../utils/format-files.rule.js';
4
5
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
5
6
  import { DEFAULT_AUTHOR, DEFAULT_DESCRIPTION, DEFAULT_LANGUAGE, DEFAULT_VERSION, } from '../defaults.js';
6
7
  export function main(options) {
@@ -9,7 +10,10 @@ export function main(options) {
9
10
  ? options.name
10
11
  : options.directory;
11
12
  options = transform(options);
12
- return mergeWith(generate(options, path));
13
+ return chain([
14
+ mergeWith(generate(options, path)),
15
+ options.format === true ? formatFiles() : noop(),
16
+ ]);
13
17
  }
14
18
  function transform(options) {
15
19
  const target = Object.assign({}, options);
@@ -20,7 +24,7 @@ function transform(options) {
20
24
  target.language = target.language ? target.language : DEFAULT_LANGUAGE;
21
25
  target.name = resolvePackageName(target.name.toString());
22
26
  target.version = target.version ? target.version : DEFAULT_VERSION;
23
- target.type = target.type ?? 'cjs';
27
+ target.type = target.type ?? 'esm';
24
28
  target.specFileSuffix = normalizeToKebabOrSnakeCase(options.specFileSuffix || 'spec');
25
29
  target.packageManager =
26
30
  !target.packageManager || target.packageManager === 'undefined'
@@ -14,24 +14,24 @@
14
14
  "test:e2e": "jest --config ./test/jest-e2e.json"
15
15
  },
16
16
  "dependencies": {
17
- "@nestjs/common": "^11.0.1",
18
- "@nestjs/core": "^11.0.1",
19
- "@nestjs/platform-express": "^11.0.1",
17
+ "@nestjs/common": "next",
18
+ "@nestjs/core": "next",
19
+ "@nestjs/platform-express": "next",
20
20
  "reflect-metadata": "^0.2.0",
21
21
  "rxjs": "^7.2.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@nestjs/testing": "^11.0.1",
24
+ "@nestjs/testing": "next",
25
25
  "@babel/core": "7.29.0",
26
26
  "@babel/node": "7.29.0",
27
27
  "@babel/plugin-proposal-decorators": "7.29.0",
28
28
  "@babel/plugin-transform-runtime": "7.29.0",
29
- "@babel/preset-env": "7.29.0",
30
- "@babel/register": "7.28.6",
31
- "@babel/runtime": "7.28.6",
32
- "jest": "30.2.0",
29
+ "@babel/preset-env": "7.29.5",
30
+ "@babel/register": "7.29.3",
31
+ "@babel/runtime": "7.29.2",
32
+ "jest": "30.4.2",
33
33
  "nodemon": "3.1.14",
34
- "prettier": "3.8.1",
34
+ "prettier": "3.8.3",
35
35
  "supertest": "7.2.2"
36
36
  }
37
37
  }
@@ -20,4 +20,8 @@ describe('AppController (e2e)', () => {
20
20
  .expect(200)
21
21
  .expect('Hello World!');
22
22
  });
23
+
24
+ afterEach(async () => {
25
+ await app.close();
26
+ });
23
27
  });
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/crates/oxc_linter/src/rules.rs",
3
+ "rules": {
4
+ "@typescript-eslint/no-explicit-any": "off",
5
+ "@typescript-eslint/no-floating-promises": "warn"
6
+ },
7
+ "env": {
8
+ "node": true
9
+ }
10
+ }
@@ -12,7 +12,7 @@
12
12
  "start:dev": "nest start --watch",
13
13
  "start:debug": "nest start --debug --watch",
14
14
  "start:prod": "node dist/main",
15
- "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
15
+ "lint": "oxlint src/ test/",
16
16
  "test": "jest",
17
17
  "test:watch": "jest --watch",
18
18
  "test:cov": "jest --coverage",
@@ -20,26 +20,22 @@
20
20
  "test:e2e": "jest --config ./test/jest-e2e.json"
21
21
  },
22
22
  "dependencies": {
23
- "@nestjs/common": "^11.0.1",
24
- "@nestjs/core": "^11.0.1",
25
- "@nestjs/platform-express": "^11.0.1",
23
+ "@nestjs/common": "next",
24
+ "@nestjs/core": "next",
25
+ "@nestjs/platform-express": "next",
26
26
  "reflect-metadata": "^0.2.2",
27
27
  "rxjs": "^7.8.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@eslint/js": "^10.0.0",
31
- "@nestjs/cli": "^11.0.0",
32
- "@nestjs/schematics": "^11.0.0",
33
- "@nestjs/testing": "^11.0.1",
30
+ "@nestjs/cli": "next",
31
+ "@nestjs/schematics": "next",
32
+ "@nestjs/testing": "next",
34
33
  "@types/express": "^5.0.0",
35
34
  "@types/jest": "^30.0.0",
36
35
  "@types/node": "^24.0.0",
37
36
  "@types/supertest": "^7.0.0",
38
- "eslint": "^10.0.0",
39
- "eslint-config-prettier": "^10.0.1",
40
- "eslint-plugin-prettier": "^5.5.0",
41
- "globals": "^17.0.0",
42
37
  "jest": "^30.0.0",
38
+ "oxlint": "^1.58.0",
43
39
  "prettier": "^3.4.2",
44
40
  "source-map-support": "^0.5.21",
45
41
  "supertest": "^7.0.0",
@@ -47,7 +43,6 @@
47
43
  "ts-loader": "^9.5.2",
48
44
  "ts-node": "^10.9.2",
49
45
  "tsconfig-paths": "^4.2.0",
50
- "typescript": "^5.7.3",
51
- "typescript-eslint": "^8.30.0"
46
+ "typescript": "^6.0.2"
52
47
  }
53
48
  }
@@ -22,4 +22,8 @@ describe('AppController (e2e)', () => {
22
22
  .expect(200)
23
23
  .expect('Hello World!');
24
24
  });
25
+
26
+ afterEach(async () => {
27
+ await app.close();
28
+ });
25
29
  });
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/crates/oxc_linter/src/rules.rs",
3
+ "rules": {
4
+ "@typescript-eslint/no-explicit-any": "off",
5
+ "@typescript-eslint/no-floating-promises": "warn"
6
+ },
7
+ "env": {
8
+ "node": true
9
+ }
10
+ }
@@ -13,7 +13,7 @@
13
13
  "start:dev": "nest start --watch",
14
14
  "start:debug": "nest start --debug --watch",
15
15
  "start:prod": "node dist/main",
16
- "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
16
+ "lint": "oxlint src/ test/",
17
17
  "test": "vitest run",
18
18
  "test:watch": "vitest",
19
19
  "test:cov": "vitest run --coverage",
@@ -21,29 +21,24 @@
21
21
  "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
22
22
  },
23
23
  "dependencies": {
24
- "@nestjs/common": "^11.0.1",
25
- "@nestjs/core": "^11.0.1",
26
- "@nestjs/platform-express": "^11.0.1",
24
+ "@nestjs/common": "next",
25
+ "@nestjs/core": "next",
26
+ "@nestjs/platform-express": "next",
27
27
  "reflect-metadata": "^0.2.2",
28
28
  "rxjs": "^7.8.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@eslint/js": "^10.0.0",
32
- "@nestjs/cli": "^11.0.0",
33
- "@nestjs/schematics": "^11.0.0",
34
- "@nestjs/testing": "^11.0.1",
31
+ "@nestjs/cli": "next",
32
+ "@nestjs/schematics": "next",
33
+ "@nestjs/testing": "next",
35
34
  "@types/express": "^5.0.0",
36
35
  "@types/node": "^24.0.0",
37
36
  "@types/supertest": "^7.0.0",
38
- "eslint": "^10.0.0",
39
- "eslint-config-prettier": "^10.0.1",
40
- "eslint-plugin-prettier": "^5.5.0",
41
- "globals": "^17.0.0",
37
+ "oxlint": "^1.58.0",
42
38
  "prettier": "^3.4.2",
43
39
  "source-map-support": "^0.5.21",
44
40
  "supertest": "^7.0.0",
45
- "typescript": "^5.7.3",
46
- "typescript-eslint": "^8.30.0",
47
- "vitest": "^4.0.0-beta.1"
41
+ "typescript": "^6.0.2",
42
+ "vitest": "^4.1.2"
48
43
  }
49
44
  }
@@ -79,6 +79,11 @@
79
79
  "type": "string",
80
80
  "default": "spec",
81
81
  "description": "Specifies the file suffix of spec files."
82
+ },
83
+ "format": {
84
+ "type": "boolean",
85
+ "default": false,
86
+ "description": "Format generated files using Prettier if available."
82
87
  }
83
88
  },
84
89
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -13,6 +14,7 @@ export function main(options) {
13
14
  return tree;
14
15
  },
15
16
  mergeWith(generate(options)),
17
+ options.format === true ? formatFiles() : noop(),
16
18
  ]);
17
19
  }
18
20
  function transform(options) {
@@ -44,6 +44,11 @@
44
44
  "className": {
45
45
  "type": "string",
46
46
  "description": "Class name to be used internally."
47
+ },
48
+ "format": {
49
+ "type": "boolean",
50
+ "default": false,
51
+ "description": "Format generated files using Prettier if available."
47
52
  }
48
53
  },
49
54
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, filter, mergeWith, move, noop, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -16,6 +17,7 @@ export function main(options) {
16
17
  mergeSourceRoot(options),
17
18
  mergeWith(generate(options)),
18
19
  addDeclarationToModule(options),
20
+ options.format === true ? formatFiles() : noop(),
19
21
  ]))(tree, context);
20
22
  };
21
23
  }
@@ -55,10 +57,11 @@ function addDeclarationToModule(options) {
55
57
  if (options.skipImport !== undefined && options.skipImport) {
56
58
  return tree;
57
59
  }
58
- options.module = new ModuleFinder(tree).find({
59
- name: options.name,
60
- path: options.path,
61
- });
60
+ options.module =
61
+ new ModuleFinder(tree).find({
62
+ name: options.name,
63
+ path: options.path,
64
+ }) ?? undefined;
62
65
  if (!options.module) {
63
66
  return tree;
64
67
  }
@@ -49,6 +49,11 @@
49
49
  "type": "string",
50
50
  "default": "spec",
51
51
  "description": "Specifies the file suffix of spec files."
52
+ },
53
+ "format": {
54
+ "type": "boolean",
55
+ "default": false,
56
+ "description": "Format generated files using Prettier if available."
52
57
  }
53
58
  },
54
59
  "required": ["name"]
@@ -1,11 +1,16 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
- import { apply, chain, mergeWith, move, SchematicsException, template, url, } from '@angular-devkit/schematics';
2
+ import { apply, chain, mergeWith, noop, move, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { mergeSourceRoot } from '../../utils/source-root.helpers.js';
6
7
  export function main(options) {
7
8
  options = transform(options);
8
- return chain([mergeSourceRoot(options), mergeWith(generate(options))]);
9
+ return chain([
10
+ mergeSourceRoot(options),
11
+ mergeWith(generate(options)),
12
+ options.format === true ? formatFiles() : noop(),
13
+ ]);
9
14
  }
10
15
  function transform(options) {
11
16
  const target = Object.assign({}, options);
@@ -30,6 +30,11 @@
30
30
  "type": "boolean",
31
31
  "default": true,
32
32
  "description": "Flag to indicate if a directory is created."
33
+ },
34
+ "format": {
35
+ "type": "boolean",
36
+ "default": false,
37
+ "description": "Format generated files using Prettier if available."
33
38
  }
34
39
  },
35
40
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  return tree;
13
14
  },
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]);
16
18
  }
17
19
  function transform(options) {
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -13,6 +14,7 @@ export function main(options) {
13
14
  mergeSourceRoot(options),
14
15
  addDeclarationToModule(options),
15
16
  mergeWith(generate(options)),
17
+ options.format === true ? formatFiles() : noop(),
16
18
  ]))(tree, context);
17
19
  };
18
20
  }
@@ -55,10 +57,11 @@ function addDeclarationToModule(options) {
55
57
  if (options.skipImport !== undefined && options.skipImport) {
56
58
  return tree;
57
59
  }
58
- options.module = new ModuleFinder(tree).find({
59
- name: options.name,
60
- path: options.path,
61
- });
60
+ options.module =
61
+ new ModuleFinder(tree).find({
62
+ name: options.name,
63
+ path: options.path,
64
+ }) ?? undefined;
62
65
  if (!options.module) {
63
66
  return tree;
64
67
  }
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  return tree;
13
14
  },
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]);
16
18
  }
17
19
  function transform(options) {
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  return tree;
13
14
  },
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]);
16
18
  }
17
19
  function transform(options) {
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,11 +1,16 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
- import { apply, chain, mergeWith, move, SchematicsException, template, url, } from '@angular-devkit/schematics';
2
+ import { apply, chain, mergeWith, noop, move, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { mergeSourceRoot } from '../../utils/source-root.helpers.js';
6
7
  export function main(options) {
7
8
  options = transform(options);
8
- return chain([mergeSourceRoot(options), mergeWith(generate(options))]);
9
+ return chain([
10
+ mergeSourceRoot(options),
11
+ mergeWith(generate(options)),
12
+ options.format === true ? formatFiles() : noop(),
13
+ ]);
9
14
  }
10
15
  function transform(options) {
11
16
  const target = Object.assign({}, options);
@@ -26,6 +26,11 @@
26
26
  "type": "boolean",
27
27
  "default": true,
28
28
  "description": "Flag to indicate if a directory is created."
29
+ },
30
+ "format": {
31
+ "type": "boolean",
32
+ "default": false,
33
+ "description": "Format generated files using Prettier if available."
29
34
  }
30
35
  },
31
36
  "required": ["name"]
@@ -1,6 +1,7 @@
1
1
  import { join, normalize, strings } from '@angular-devkit/core';
2
- import { apply, branchAndMerge, chain, mergeWith, move, SchematicsException, template, url, } from '@angular-devkit/schematics';
2
+ import { apply, branchAndMerge, chain, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
3
  import { parse } from 'jsonc-parser';
4
+ import { formatFiles } from '../../utils/format-files.rule.js';
4
5
  import { createModuleNameMapper, inPlaceSortByKeys, normalizeToKebabOrSnakeCase, } from '../../utils/index.js';
5
6
  import { DEFAULT_LANGUAGE, DEFAULT_LIB_PATH, DEFAULT_PATH_NAME, PROJECT_TYPE, } from '../defaults.js';
6
7
  import { FileSystemReader } from '../readers/index.js';
@@ -17,6 +18,7 @@ export function main(options) {
17
18
  return tree;
18
19
  },
19
20
  branchAndMerge(mergeWith(generate(options))),
21
+ options.format === true ? formatFiles() : noop(),
20
22
  ]);
21
23
  }
22
24
  function getDefaultLibraryPrefix(defaultLibraryPrefix = '@app') {
@@ -36,6 +36,11 @@
36
36
  "type": "string",
37
37
  "default": "spec",
38
38
  "description": "Specifies the file suffix of spec files."
39
+ },
40
+ "format": {
41
+ "type": "boolean",
42
+ "default": false,
43
+ "description": "Format generated files using Prettier if available."
39
44
  }
40
45
  },
41
46
  "required": ["name", "prefix"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  return tree;
13
14
  },
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]);
16
18
  }
17
19
  function transform(options) {
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
- import { apply, branchAndMerge, chain, mergeWith, move, template, url, } from '@angular-devkit/schematics';
2
+ import { apply, branchAndMerge, chain, mergeWith, move, noop, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  mergeSourceRoot(options),
13
14
  addDeclarationToModule(options),
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]))(tree, context);
16
18
  };
17
19
  }
@@ -42,10 +44,11 @@ function addDeclarationToModule(options) {
42
44
  if (options.skipImport !== undefined && options.skipImport) {
43
45
  return tree;
44
46
  }
45
- options.module = new ModuleFinder(tree).find({
46
- name: options.name,
47
- path: options.path,
48
- });
47
+ options.module =
48
+ new ModuleFinder(tree).find({
49
+ name: options.name,
50
+ path: options.path,
51
+ }) ?? undefined;
49
52
  if (!options.module) {
50
53
  return tree;
51
54
  }
@@ -40,6 +40,11 @@
40
40
  "type": "boolean",
41
41
  "default": false,
42
42
  "description": "Flag to indicate if a directory is created."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { NameParser } from '../../utils/name.parser.js';
5
6
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -12,6 +13,7 @@ export function main(options) {
12
13
  return tree;
13
14
  },
14
15
  mergeWith(generate(options)),
16
+ options.format === true ? formatFiles() : noop(),
15
17
  ]);
16
18
  }
17
19
  function transform(options) {
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -13,6 +14,7 @@ export function main(options) {
13
14
  mergeSourceRoot(options),
14
15
  addDeclarationToModule(options),
15
16
  mergeWith(generate(options)),
17
+ options.format === true ? formatFiles() : noop(),
16
18
  ]))(tree, context);
17
19
  };
18
20
  }
@@ -59,10 +61,11 @@ function addDeclarationToModule(options) {
59
61
  if (options.skipImport !== undefined && options.skipImport) {
60
62
  return tree;
61
63
  }
62
- options.module = new ModuleFinder(tree).find({
63
- name: options.name,
64
- path: options.path,
65
- });
64
+ options.module =
65
+ new ModuleFinder(tree).find({
66
+ name: options.name,
67
+ path: options.path,
68
+ }) ?? undefined;
66
69
  if (!options.module) {
67
70
  return tree;
68
71
  }
@@ -44,6 +44,11 @@
44
44
  "className": {
45
45
  "type": "string",
46
46
  "description": "Class name to be used internally."
47
+ },
48
+ "format": {
49
+ "type": "boolean",
50
+ "default": false,
51
+ "description": "Format generated files using Prettier if available."
47
52
  }
48
53
  },
49
54
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -13,6 +14,7 @@ export function main(options) {
13
14
  mergeSourceRoot(options),
14
15
  addDeclarationToModule(options),
15
16
  mergeWith(generate(options)),
17
+ options.format === true ? formatFiles() : noop(),
16
18
  ]))(tree, context);
17
19
  };
18
20
  }
@@ -54,10 +56,11 @@ function addDeclarationToModule(options) {
54
56
  if (options.skipImport !== undefined && options.skipImport) {
55
57
  return tree;
56
58
  }
57
- options.module = new ModuleFinder(tree).find({
58
- name: options.name,
59
- path: options.path,
60
- });
59
+ options.module =
60
+ new ModuleFinder(tree).find({
61
+ name: options.name,
62
+ path: options.path,
63
+ }) ?? undefined;
61
64
  if (!options.module) {
62
65
  return tree;
63
66
  }
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -5,6 +5,7 @@ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks/index.j
5
5
  import pluralize from 'pluralize';
6
6
  import { ModuleDeclarator, ModuleFinder, } from '../../index.js';
7
7
  import { addPackageJsonDependency, getPackageJsonDependency, NodeDependencyType, } from '../../utils/dependencies.utils.js';
8
+ import { formatFiles } from '../../utils/format-files.rule.js';
8
9
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
9
10
  import { NameParser } from '../../utils/name.parser.js';
10
11
  import { isEsmProject, mergeSourceRoot, } from '../../utils/source-root.helpers.js';
@@ -17,6 +18,7 @@ export function main(options) {
17
18
  mergeSourceRoot(options),
18
19
  addDeclarationToModule(options),
19
20
  mergeWith(generate(options)),
21
+ options.format === true ? formatFiles() : noop(),
20
22
  ]))(tree, context);
21
23
  };
22
24
  }
@@ -46,12 +48,12 @@ function generate(options) {
46
48
  if (path.endsWith('.dto.ts')) {
47
49
  return (options.type !== 'graphql-code-first' &&
48
50
  options.type !== 'graphql-schema-first' &&
49
- options.crud);
51
+ !!options.crud);
50
52
  }
51
53
  if (path.endsWith('.input.ts')) {
52
54
  return ((options.type === 'graphql-code-first' ||
53
55
  options.type === 'graphql-schema-first') &&
54
- options.crud);
56
+ !!options.crud);
55
57
  }
56
58
  if (path.endsWith('.resolver.ts') ||
57
59
  path.endsWith('.resolver.__specFileSuffix__.ts')) {
@@ -59,7 +61,7 @@ function generate(options) {
59
61
  options.type === 'graphql-schema-first');
60
62
  }
61
63
  if (path.endsWith('.graphql')) {
62
- return options.type === 'graphql-schema-first' && options.crud;
64
+ return options.type === 'graphql-schema-first' && !!options.crud;
63
65
  }
64
66
  if (path.endsWith('controller.ts') ||
65
67
  path.endsWith('.controller.__specFileSuffix__.ts')) {
@@ -70,7 +72,7 @@ function generate(options) {
70
72
  return options.type === 'ws';
71
73
  }
72
74
  if (path.includes('@ent')) {
73
- return options.crud;
75
+ return !!options.crud;
74
76
  }
75
77
  return true;
76
78
  }),
@@ -98,10 +100,11 @@ function addDeclarationToModule(options) {
98
100
  if (options.skipImport !== undefined && options.skipImport) {
99
101
  return tree;
100
102
  }
101
- options.module = new ModuleFinder(tree).find({
102
- name: options.name,
103
- path: options.path,
104
- });
103
+ options.module =
104
+ new ModuleFinder(tree).find({
105
+ name: options.name,
106
+ path: options.path,
107
+ }) ?? undefined;
105
108
  if (!options.module) {
106
109
  return tree;
107
110
  }
@@ -89,6 +89,11 @@
89
89
  "message": "Would you like to generate CRUD entry points?",
90
90
  "type": "confirmation"
91
91
  }
92
+ },
93
+ "format": {
94
+ "type": "boolean",
95
+ "default": false,
96
+ "description": "Format generated files using Prettier if available."
92
97
  }
93
98
  },
94
99
  "required": ["name"]
@@ -40,6 +40,11 @@
40
40
  "type": "string",
41
41
  "default": "spec",
42
42
  "description": "Specifies the file suffix of spec files."
43
+ },
44
+ "format": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Format generated files using Prettier if available."
43
48
  }
44
49
  },
45
50
  "required": ["name"]
@@ -1,5 +1,6 @@
1
1
  import { join, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, filter, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
+ import { formatFiles } from '../../utils/format-files.rule.js';
3
4
  import { normalizeToKebabOrSnakeCase } from '../../utils/formatting.js';
4
5
  import { ModuleDeclarator, } from '../../utils/module.declarator.js';
5
6
  import { ModuleFinder } from '../../utils/module.finder.js';
@@ -16,6 +17,7 @@ export function main(options) {
16
17
  mergeSourceRoot(options),
17
18
  addDeclarationToModule(options),
18
19
  mergeWith(generate(options)),
20
+ options.format === true ? formatFiles() : noop(),
19
21
  ]))(tree, context);
20
22
  };
21
23
  }
@@ -57,10 +59,11 @@ function addDeclarationToModule(options) {
57
59
  if (options.skipImport !== undefined && options.skipImport) {
58
60
  return tree;
59
61
  }
60
- options.module = new ModuleFinder(tree).find({
61
- name: options.name,
62
- path: options.path,
63
- });
62
+ options.module =
63
+ new ModuleFinder(tree).find({
64
+ name: options.name,
65
+ path: options.path,
66
+ }) ?? undefined;
64
67
  if (!options.module) {
65
68
  return tree;
66
69
  }
@@ -31,6 +31,11 @@
31
31
  "type": "string",
32
32
  "default": "spec",
33
33
  "description": "Specifies the file suffix of spec files."
34
+ },
35
+ "format": {
36
+ "type": "boolean",
37
+ "default": false,
38
+ "description": "Format generated files using Prettier if available."
34
39
  }
35
40
  },
36
41
  "required": ["name"]
@@ -2,6 +2,7 @@ import { join, normalize, strings } from '@angular-devkit/core';
2
2
  import { apply, branchAndMerge, chain, mergeWith, move, noop, SchematicsException, template, url, } from '@angular-devkit/schematics';
3
3
  import { existsSync, readFileSync } from 'fs';
4
4
  import { parse, stringify } from 'comment-json';
5
+ import { formatFiles } from '../../utils/format-files.rule.js';
5
6
  import { inPlaceSortByKeys, normalizeToKebabOrSnakeCase, } from '../../utils/index.js';
6
7
  import { DEFAULT_APPS_PATH, DEFAULT_APP_NAME, DEFAULT_DIR_ENTRY_APP, DEFAULT_LANGUAGE, DEFAULT_LIB_PATH, DEFAULT_PATH_NAME, PROJECT_TYPE, TEST_ENV, } from '../defaults.js';
7
8
  import { isEsmProject } from '../../utils/source-root.helpers.js';
@@ -24,6 +25,7 @@ export function main(options) {
24
25
  return tree;
25
26
  },
26
27
  branchAndMerge(mergeWith(generate(options))),
28
+ options.format === true ? formatFiles() : noop(),
27
29
  ]);
28
30
  }
29
31
  function getAppNameFromPackageJson() {
@@ -211,7 +213,11 @@ function moveDefaultAppToApps(projectRoot, appName, sourceRoot = DEFAULT_PATH_NA
211
213
  }
212
214
  function moveDirectoryTo(srcDir, destination, tree) {
213
215
  let srcDirExists = false;
214
- tree.getDir(srcDir).visit((filePath, file) => {
216
+ tree
217
+ .getDir(srcDir)
218
+ .visit((filePath, file) => {
219
+ if (!file)
220
+ return;
215
221
  srcDirExists = true;
216
222
  const newFilePath = join(destination, filePath);
217
223
  tree.create(newFilePath, file.content);
@@ -0,0 +1,3 @@
1
+ import { Path } from '@angular-devkit/core';
2
+ import { Rule } from '@angular-devkit/schematics';
3
+ export declare function formatFiles(paths?: Array<string | Path>): Rule;
@@ -0,0 +1,45 @@
1
+ const FORMATTABLE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
2
+ export function formatFiles(paths) {
3
+ return async (tree, _context) => {
4
+ let prettier;
5
+ try {
6
+ prettier = await import('prettier');
7
+ }
8
+ catch {
9
+ return tree;
10
+ }
11
+ const candidates = (paths ??
12
+ tree.actions
13
+ .filter((action) => action.kind === 'c' ||
14
+ action.kind === 'o' ||
15
+ action.kind === 'r')
16
+ .map((action) => action.path))
17
+ .map((p) => (typeof p === 'string' ? p : String(p)))
18
+ .filter((p) => FORMATTABLE_EXTENSIONS.some((ext) => p.endsWith(ext)));
19
+ const uniquePaths = Array.from(new Set(candidates));
20
+ for (const filePath of uniquePaths) {
21
+ if (!tree.exists(filePath)) {
22
+ continue;
23
+ }
24
+ const buffer = tree.read(filePath);
25
+ if (!buffer) {
26
+ continue;
27
+ }
28
+ const source = buffer.toString('utf-8');
29
+ try {
30
+ const resolvedOptions = (await prettier.resolveConfig(filePath)) ?? undefined;
31
+ const formatted = await prettier.format(source, {
32
+ ...resolvedOptions,
33
+ filepath: filePath,
34
+ });
35
+ if (formatted !== source) {
36
+ tree.overwrite(filePath, formatted);
37
+ }
38
+ }
39
+ catch {
40
+ continue;
41
+ }
42
+ }
43
+ return tree;
44
+ };
45
+ }
@@ -1,3 +1,4 @@
1
+ export * from './format-files.rule.js';
1
2
  export * from './metadata.manager.js';
2
3
  export * from './module-import.declarator.js';
3
4
  export * from './module-metadata.declarator.js';
@@ -1,3 +1,4 @@
1
+ export * from './format-files.rule.js';
1
2
  export * from './metadata.manager.js';
2
3
  export * from './module-import.declarator.js';
3
4
  export * from './module-metadata.declarator.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/schematics",
3
- "version": "12.0.0-alpha.7",
3
+ "version": "12.0.0-alpha.9",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@schematics)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,10 +13,10 @@
13
13
  "scripts": {
14
14
  "postbuild": "npm run copy:collection && npm run copy:lib",
15
15
  "build": "rm -rf dist *.tsbuildinfo && tsc -b tsconfig.lib.json",
16
- "clean": "find src -type f \\( -name '*.js' -o -name '*.d.ts' -o -name '*.js.map' -o -name '*.d.ts.map' \\) -not -path '*/files/*' -not -path '*/workspace/*' -not -name '*.schema.d.ts' -delete",
16
+ "clean": "del 'src/**/*.{js,d.ts,js.map,d.ts.map}' '!src/**/files/**' '!src/**/workspace/**' '!src/**/*.schema.d.ts'",
17
17
  "copy:collection": "cpx src/collection.json dist && cpx 'src/lib/**/schema.json' dist/lib",
18
18
  "copy:lib": "cpx 'src/lib/**/{files,workspace}/**/*.*' dist/lib && cpx 'src/lib/**/{files,workspace}/**/.!(gitignore)' dist/lib",
19
- "lint": "eslint '{src,test}/**/*.ts' --fix",
19
+ "lint": "oxlint --ignore-pattern 'src/**/files/**' --ignore-pattern 'src/**/workspace/**' src/ test/",
20
20
  "prepublish:next": "npm run build",
21
21
  "publish:next": "npm publish --access public --tag next",
22
22
  "prepublish:npm": "npm run build",
@@ -51,24 +51,27 @@
51
51
  "devDependencies": {
52
52
  "@commitlint/cli": "20.4.3",
53
53
  "@commitlint/config-angular": "20.4.3",
54
- "@eslint/js": "10.0.1",
55
54
  "@types/node": "25.3.5",
55
+ "@types/pluralize": "^0.0.33",
56
56
  "cpx2": "8.0.0",
57
- "eslint": "10.0.3",
58
- "eslint-config-prettier": "10.1.8",
59
- "eslint-plugin-prettier": "5.5.5",
60
- "globals": "17.4.0",
57
+ "del-cli": "^7.0.0",
61
58
  "husky": "9.1.7",
62
59
  "jiti": "2.6.1",
60
+ "oxlint": "1.58.0",
63
61
  "prettier": "3.8.1",
64
62
  "release-it": "19.2.4",
65
- "typescript": "5.9.3",
66
- "typescript-eslint": "8.56.1",
67
63
  "tsx": "4.21.0",
64
+ "typescript": "^6.0.2",
68
65
  "vitest": "4.0.18"
69
66
  },
70
67
  "peerDependencies": {
71
- "typescript": ">=5.9.3"
68
+ "prettier": "^3.0.0",
69
+ "typescript": ">=6.0.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "prettier": {
73
+ "optional": true
74
+ }
72
75
  },
73
76
  "schematics": "./dist/collection.json",
74
77
  "lint-staged": {
@@ -1,34 +0,0 @@
1
- import eslint from '@eslint/js';
2
- import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
3
- import globals from 'globals';
4
- import tseslint from 'typescript-eslint';
5
-
6
- export default [
7
- {
8
- ignores: ['eslint.config.mjs'],
9
- },
10
- eslint.configs.recommended,
11
- ...tseslint.configs.recommendedTypeChecked,
12
- eslintPluginPrettierRecommended,
13
- {
14
- languageOptions: {
15
- globals: {
16
- ...globals.node,
17
- ...globals.jest,
18
- },
19
- sourceType: 'commonjs',
20
- parserOptions: {
21
- projectService: true,
22
- tsconfigRootDir: import.meta.dirname,
23
- },
24
- },
25
- },
26
- {
27
- rules: {
28
- '@typescript-eslint/no-explicit-any': 'off',
29
- '@typescript-eslint/no-floating-promises': 'warn',
30
- '@typescript-eslint/no-unsafe-argument': 'warn',
31
- "prettier/prettier": ["error", { endOfLine: "auto" }],
32
- },
33
- },
34
- ];
@@ -1,33 +0,0 @@
1
- import eslint from '@eslint/js';
2
- import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
3
- import globals from 'globals';
4
- import tseslint from 'typescript-eslint';
5
-
6
- export default [
7
- {
8
- ignores: ['eslint.config.mjs'],
9
- },
10
- eslint.configs.recommended,
11
- ...tseslint.configs.recommendedTypeChecked,
12
- eslintPluginPrettierRecommended,
13
- {
14
- languageOptions: {
15
- globals: {
16
- ...globals.node,
17
- },
18
- sourceType: 'module',
19
- parserOptions: {
20
- projectService: true,
21
- tsconfigRootDir: import.meta.dirname,
22
- },
23
- },
24
- },
25
- {
26
- rules: {
27
- '@typescript-eslint/no-explicit-any': 'off',
28
- '@typescript-eslint/no-floating-promises': 'warn',
29
- '@typescript-eslint/no-unsafe-argument': 'warn',
30
- "prettier/prettier": ["error", { endOfLine: "auto" }],
31
- },
32
- },
33
- ];