@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
@@ -7,12 +7,12 @@
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
10
  const schematics_1 = require("@angular-devkit/schematics");
12
11
  const add_declaration_to_ng_module_1 = require("../utility/add-declaration-to-ng-module");
13
12
  const find_module_1 = require("../utility/find-module");
14
13
  const generate_from_files_1 = require("../utility/generate-from-files");
15
14
  const parse_name_1 = require("../utility/parse-name");
15
+ const project_1 = require("../utility/project");
16
16
  const validation_1 = require("../utility/validation");
17
17
  const workspace_1 = require("../utility/workspace");
18
18
  function buildSelector(options, projectPrefix) {
@@ -25,29 +25,27 @@ function buildSelector(options, projectPrefix) {
25
25
  }
26
26
  return schematics_1.strings.camelize(selector);
27
27
  }
28
- function default_1(options) {
29
- return async (host) => {
30
- const workspace = await (0, workspace_1.getWorkspace)(host);
31
- const project = workspace.projects.get(options.project);
32
- if (!project) {
33
- throw new schematics_1.SchematicsException(`Project "${options.project}" does not exist.`);
34
- }
35
- if (options.path === undefined) {
36
- options.path = (0, workspace_1.buildDefaultPath)(project);
37
- }
38
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
39
- const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
40
- options.name = parsedPath.name;
41
- options.path = parsedPath.path;
42
- options.selector = options.selector || buildSelector(options, project.prefix || '');
43
- (0, validation_1.validateHtmlSelector)(options.selector);
44
- (0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
45
- return (0, schematics_1.chain)([
46
- (0, add_declaration_to_ng_module_1.addDeclarationToNgModule)({
47
- type: 'directive',
48
- ...options,
49
- }),
50
- (0, generate_from_files_1.generateFromFiles)(options),
51
- ]);
52
- };
53
- }
28
+ exports.default = (0, project_1.createProjectSchematic)((options, { project, tree }) => {
29
+ if (options.path === undefined) {
30
+ options.path = (0, workspace_1.buildDefaultPath)(project);
31
+ }
32
+ options.module = (0, find_module_1.findModuleFromOptions)(tree, options);
33
+ const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
34
+ options.name = parsedPath.name;
35
+ options.path = parsedPath.path;
36
+ options.selector = options.selector || buildSelector(options, project.prefix || '');
37
+ (0, validation_1.validateHtmlSelector)(options.selector);
38
+ const classifiedName = schematics_1.strings.classify(options.name) +
39
+ (options.addTypeToClassName && options.type ? schematics_1.strings.classify(options.type) : '');
40
+ (0, validation_1.validateClassName)(classifiedName);
41
+ return (0, schematics_1.chain)([
42
+ (0, add_declaration_to_ng_module_1.addDeclarationToNgModule)({
43
+ type: 'directive',
44
+ ...options,
45
+ }),
46
+ (0, generate_from_files_1.generateFromFiles)({
47
+ ...options,
48
+ classifiedName,
49
+ }),
50
+ ]);
51
+ });
@@ -5,6 +5,11 @@
5
5
  * and boilerplate code for a new directive.
6
6
  */
7
7
  export type Schema = {
8
+ /**
9
+ * When true, the 'type' option will be appended to the generated class name. When false,
10
+ * only the file name will include the type.
11
+ */
12
+ addTypeToClassName?: boolean;
8
13
  /**
9
14
  * Automatically export the directive from the specified NgModule, making it accessible to
10
15
  * other modules in the application.
@@ -84,6 +84,11 @@
84
84
  "type": {
85
85
  "type": "string",
86
86
  "description": "Append a custom type to the directive's filename. For example, if you set the type to `directive`, the file will be named `example.directive.ts`."
87
+ },
88
+ "addTypeToClassName": {
89
+ "type": "boolean",
90
+ "default": true,
91
+ "description": "When true, the 'type' option will be appended to the generated class name. When false, only the file name will include the type."
87
92
  }
88
93
  },
89
94
  "required": ["name", "project"]
@@ -27,7 +27,7 @@ const karma_config_analyzer_1 = require("./karma-config-analyzer");
27
27
  * @returns The content of the default `karma.conf.js` file.
28
28
  */
29
29
  async function generateDefaultKarmaConfig(relativePathToWorkspaceRoot, projectName, needDevkitPlugin) {
30
- const templatePath = posix_1.default.join(__dirname, '../../config/files/karma.conf.js.template');
30
+ const templatePath = require.resolve('../../config/files/karma.conf.js.template');
31
31
  let template = await (0, promises_1.readFile)(templatePath, 'utf-8');
32
32
  // TODO: Replace this with the actual schematic templating logic.
33
33
  template = template
@@ -1,4 +1,5 @@
1
1
  {
2
+ "encapsulation": false,
2
3
  "schematics": {
3
4
  "use-application-builder": {
4
5
  "version": "21.0.0",
package/module/index.d.ts CHANGED
@@ -7,4 +7,5 @@
7
7
  */
8
8
  import { Rule } from '@angular-devkit/schematics';
9
9
  import { Schema as ModuleOptions } from './schema';
10
- export default function (options: ModuleOptions): Rule;
10
+ declare const _default: (options: ModuleOptions) => Rule;
11
+ export default _default;
package/module/index.js CHANGED
@@ -40,7 +40,6 @@ var __importStar = (this && this.__importStar) || (function () {
40
40
  };
41
41
  })();
42
42
  Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.default = default_1;
44
43
  const schematics_1 = require("@angular-devkit/schematics");
45
44
  const posix_1 = require("node:path/posix");
46
45
  const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
@@ -48,6 +47,7 @@ const ast_utils_1 = require("../utility/ast-utils");
48
47
  const change_1 = require("../utility/change");
49
48
  const find_module_1 = require("../utility/find-module");
50
49
  const parse_name_1 = require("../utility/parse-name");
50
+ const project_1 = require("../utility/project");
51
51
  const validation_1 = require("../utility/validation");
52
52
  const workspace_1 = require("../utility/workspace");
53
53
  const schema_1 = require("./schema");
@@ -112,53 +112,51 @@ function buildRoute(options, modulePath) {
112
112
  const loadChildren = `() => import('${relativeModulePath}').then(m => m.${moduleName})`;
113
113
  return `{ path: '${options.route}', loadChildren: ${loadChildren} }`;
114
114
  }
115
- function default_1(options) {
116
- return async (host) => {
117
- if (options.path === undefined) {
118
- options.path = await (0, workspace_1.createDefaultPath)(host, options.project);
119
- }
120
- if (options.module) {
121
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
122
- }
123
- let routingModulePath;
124
- const isLazyLoadedModuleGen = !!(options.route && options.module);
125
- if (isLazyLoadedModuleGen) {
126
- options.routingScope = schema_1.RoutingScope.Child;
127
- routingModulePath = getRoutingModulePath(host, options.module);
128
- }
129
- const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
130
- options.name = parsedPath.name;
131
- options.path = parsedPath.path;
132
- (0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
133
- const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
134
- options.routing || (isLazyLoadedModuleGen && routingModulePath)
135
- ? (0, schematics_1.noop)()
136
- : (0, schematics_1.filter)((path) => !path.includes('-routing')),
137
- (0, schematics_1.applyTemplates)({
138
- ...schematics_1.strings,
139
- 'if-flat': (s) => (options.flat ? '' : s),
140
- lazyRoute: isLazyLoadedModuleGen,
141
- lazyRouteWithoutRouteModule: isLazyLoadedModuleGen && !routingModulePath,
142
- lazyRouteWithRouteModule: isLazyLoadedModuleGen && !!routingModulePath,
143
- ...options,
144
- }),
145
- (0, schematics_1.move)(parsedPath.path),
146
- ]);
147
- const moduleDasherized = schematics_1.strings.dasherize(options.name);
148
- const modulePath = `${!options.flat ? moduleDasherized + '/' : ''}${moduleDasherized}${options.typeSeparator}module.ts`;
149
- const componentOptions = {
150
- module: modulePath,
151
- flat: options.flat,
152
- name: options.name,
153
- path: options.path,
154
- project: options.project,
155
- standalone: false,
156
- };
157
- return (0, schematics_1.chain)([
158
- !isLazyLoadedModuleGen ? addImportToNgModule(options) : (0, schematics_1.noop)(),
159
- addRouteDeclarationToNgModule(options, routingModulePath),
160
- (0, schematics_1.mergeWith)(templateSource),
161
- isLazyLoadedModuleGen ? (0, schematics_1.schematic)('component', componentOptions) : (0, schematics_1.noop)(),
162
- ]);
115
+ exports.default = (0, project_1.createProjectSchematic)(async (options, { tree }) => {
116
+ if (options.path === undefined) {
117
+ options.path = await (0, workspace_1.createDefaultPath)(tree, options.project);
118
+ }
119
+ if (options.module) {
120
+ options.module = (0, find_module_1.findModuleFromOptions)(tree, options);
121
+ }
122
+ let routingModulePath;
123
+ const isLazyLoadedModuleGen = !!(options.route && options.module);
124
+ if (isLazyLoadedModuleGen) {
125
+ options.routingScope = schema_1.RoutingScope.Child;
126
+ routingModulePath = getRoutingModulePath(tree, options.module);
127
+ }
128
+ const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
129
+ options.name = parsedPath.name;
130
+ options.path = parsedPath.path;
131
+ (0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
132
+ const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
133
+ options.routing || (isLazyLoadedModuleGen && routingModulePath)
134
+ ? (0, schematics_1.noop)()
135
+ : (0, schematics_1.filter)((path) => !path.includes('-routing')),
136
+ (0, schematics_1.applyTemplates)({
137
+ ...schematics_1.strings,
138
+ 'if-flat': (s) => (options.flat ? '' : s),
139
+ lazyRoute: isLazyLoadedModuleGen,
140
+ lazyRouteWithoutRouteModule: isLazyLoadedModuleGen && !routingModulePath,
141
+ lazyRouteWithRouteModule: isLazyLoadedModuleGen && !!routingModulePath,
142
+ ...options,
143
+ }),
144
+ (0, schematics_1.move)(parsedPath.path),
145
+ ]);
146
+ const moduleDasherized = schematics_1.strings.dasherize(options.name);
147
+ const modulePath = `${!options.flat ? moduleDasherized + '/' : ''}${moduleDasherized}${options.typeSeparator}module.ts`;
148
+ const componentOptions = {
149
+ module: modulePath,
150
+ flat: options.flat,
151
+ name: options.name,
152
+ path: options.path,
153
+ project: options.project,
154
+ standalone: false,
163
155
  };
164
- }
156
+ return (0, schematics_1.chain)([
157
+ !isLazyLoadedModuleGen ? addImportToNgModule(options) : (0, schematics_1.noop)(),
158
+ addRouteDeclarationToNgModule(options, routingModulePath),
159
+ (0, schematics_1.mergeWith)(templateSource),
160
+ isLazyLoadedModuleGen ? (0, schematics_1.schematic)('component', componentOptions) : (0, schematics_1.noop)(),
161
+ ]);
162
+ });
package/ng-new/index.js CHANGED
@@ -41,6 +41,7 @@ function default_1(options) {
41
41
  standalone: options.standalone,
42
42
  ssr: options.ssr,
43
43
  zoneless: options.zoneless,
44
+ fileNameStyleGuide: options.fileNameStyleGuide,
44
45
  };
45
46
  return (0, schematics_1.chain)([
46
47
  (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.empty)(), [
@@ -25,6 +25,13 @@ export type Schema = {
25
25
  * the workspace will be created in the current directory.
26
26
  */
27
27
  directory?: string;
28
+ /**
29
+ * The file naming convention to use for generated files. The '2025' style guide (default)
30
+ * uses a concise format (e.g., `app.ts` for the root component), while the '2016' style
31
+ * guide includes the type in the file name (e.g., `app.component.ts`). For more
32
+ * information, see the Angular Style Guide (https://angular.dev/style-guide).
33
+ */
34
+ fileNameStyleGuide?: FileNameStyleGuide;
28
35
  /**
29
36
  * Include the styles for the initial application's root component directly within the
30
37
  * `app.component.ts` file. By default, a separate stylesheet file (e.g.,
@@ -135,12 +142,21 @@ export type CommitObject = {
135
142
  name: string;
136
143
  [property: string]: any;
137
144
  };
145
+ /**
146
+ * The file naming convention to use for generated files. The '2025' style guide (default)
147
+ * uses a concise format (e.g., `app.ts` for the root component), while the '2016' style
148
+ * guide includes the type in the file name (e.g., `app.component.ts`). For more
149
+ * information, see the Angular Style Guide (https://angular.dev/style-guide).
150
+ */
151
+ export declare enum FileNameStyleGuide {
152
+ The2016 = "2016",
153
+ The2025 = "2025"
154
+ }
138
155
  /**
139
156
  * The package manager used to install dependencies.
140
157
  */
141
158
  export declare enum PackageManager {
142
159
  Bun = "bun",
143
- Cnpm = "cnpm",
144
160
  Npm = "npm",
145
161
  Pnpm = "pnpm",
146
162
  Yarn = "yarn"
@@ -152,7 +168,8 @@ export declare enum Style {
152
168
  Css = "css",
153
169
  Less = "less",
154
170
  Sass = "sass",
155
- Scss = "scss"
171
+ Scss = "scss",
172
+ Tailwind = "tailwind"
156
173
  }
157
174
  /**
158
175
  * Sets the view encapsulation mode for components in the initial project. This determines
package/ng-new/schema.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
3
3
  // CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.ViewEncapsulation = exports.Style = exports.PackageManager = exports.AiConfig = void 0;
5
+ exports.ViewEncapsulation = exports.Style = exports.PackageManager = exports.FileNameStyleGuide = exports.AiConfig = void 0;
6
6
  var AiConfig;
7
7
  (function (AiConfig) {
8
8
  AiConfig["Claude"] = "claude";
@@ -13,13 +13,23 @@ var AiConfig;
13
13
  AiConfig["None"] = "none";
14
14
  AiConfig["Windsurf"] = "windsurf";
15
15
  })(AiConfig || (exports.AiConfig = AiConfig = {}));
16
+ /**
17
+ * The file naming convention to use for generated files. The '2025' style guide (default)
18
+ * uses a concise format (e.g., `app.ts` for the root component), while the '2016' style
19
+ * guide includes the type in the file name (e.g., `app.component.ts`). For more
20
+ * information, see the Angular Style Guide (https://angular.dev/style-guide).
21
+ */
22
+ var FileNameStyleGuide;
23
+ (function (FileNameStyleGuide) {
24
+ FileNameStyleGuide["The2016"] = "2016";
25
+ FileNameStyleGuide["The2025"] = "2025";
26
+ })(FileNameStyleGuide || (exports.FileNameStyleGuide = FileNameStyleGuide = {}));
16
27
  /**
17
28
  * The package manager used to install dependencies.
18
29
  */
19
30
  var PackageManager;
20
31
  (function (PackageManager) {
21
32
  PackageManager["Bun"] = "bun";
22
- PackageManager["Cnpm"] = "cnpm";
23
33
  PackageManager["Npm"] = "npm";
24
34
  PackageManager["Pnpm"] = "pnpm";
25
35
  PackageManager["Yarn"] = "yarn";
@@ -33,6 +43,7 @@ var Style;
33
43
  Style["Less"] = "less";
34
44
  Style["Sass"] = "sass";
35
45
  Style["Scss"] = "scss";
46
+ Style["Tailwind"] = "tailwind";
36
47
  })(Style || (exports.Style = Style = {}));
37
48
  /**
38
49
  * Sets the view encapsulation mode for components in the initial project. This determines
@@ -99,7 +99,7 @@
99
99
  "style": {
100
100
  "description": "The type of stylesheet files to be created for components in the initial project.",
101
101
  "type": "string",
102
- "enum": ["css", "scss", "sass", "less"],
102
+ "enum": ["css", "scss", "sass", "less", "tailwind"],
103
103
  "x-user-analytics": "ep.ng_style"
104
104
  },
105
105
  "skipTests": {
@@ -126,7 +126,7 @@
126
126
  "packageManager": {
127
127
  "description": "The package manager used to install dependencies.",
128
128
  "type": "string",
129
- "enum": ["npm", "yarn", "pnpm", "cnpm", "bun"]
129
+ "enum": ["npm", "yarn", "pnpm", "bun"]
130
130
  },
131
131
  "standalone": {
132
132
  "description": "Creates an application based upon the standalone API, without NgModules.",
@@ -151,6 +151,12 @@
151
151
  "type": "string",
152
152
  "enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf"]
153
153
  }
154
+ },
155
+ "fileNameStyleGuide": {
156
+ "type": "string",
157
+ "enum": ["2016", "2025"],
158
+ "default": "2025",
159
+ "description": "The file naming convention to use for generated files. The '2025' style guide (default) uses a concise format (e.g., `app.ts` for the root component), while the '2016' style guide includes the type in the file name (e.g., `app.component.ts`). For more information, see the Angular Style Guide (https://angular.dev/style-guide)."
154
160
  }
155
161
  },
156
162
  "required": ["name", "version"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "21.0.0-next.0",
3
+ "version": "21.0.0-next.2",
4
4
  "description": "Schematics specific to Angular",
5
5
  "homepage": "https://github.com/angular/angular-cli",
6
6
  "keywords": [
@@ -22,15 +22,15 @@
22
22
  },
23
23
  "schematics": "./collection.json",
24
24
  "dependencies": {
25
- "@angular-devkit/core": "21.0.0-next.0",
26
- "@angular-devkit/schematics": "21.0.0-next.0",
25
+ "@angular-devkit/core": "21.0.0-next.2",
26
+ "@angular-devkit/schematics": "21.0.0-next.2",
27
27
  "jsonc-parser": "3.3.1"
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
31
31
  "url": "https://github.com/angular/angular-cli.git"
32
32
  },
33
- "packageManager": "pnpm@10.15.0",
33
+ "packageManager": "pnpm@10.15.1",
34
34
  "engines": {
35
35
  "node": "^20.19.0 || ^22.12.0 || >=24.0.0",
36
36
  "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
package/pipe/index.d.ts CHANGED
@@ -5,6 +5,6 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.dev/license
7
7
  */
8
- import { Rule } from '@angular-devkit/schematics';
9
8
  import { Schema as PipeOptions } from './schema';
10
- export default function (options: PipeOptions): Rule;
9
+ declare const _default: (options: PipeOptions) => import("@angular-devkit/schematics").Rule;
10
+ export default _default;
package/pipe/index.js CHANGED
@@ -7,28 +7,26 @@
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
10
  const schematics_1 = require("@angular-devkit/schematics");
12
11
  const add_declaration_to_ng_module_1 = require("../utility/add-declaration-to-ng-module");
13
12
  const find_module_1 = require("../utility/find-module");
14
13
  const generate_from_files_1 = require("../utility/generate-from-files");
15
14
  const parse_name_1 = require("../utility/parse-name");
15
+ const project_1 = require("../utility/project");
16
16
  const validation_1 = require("../utility/validation");
17
17
  const workspace_1 = require("../utility/workspace");
18
- function default_1(options) {
19
- return async (host) => {
20
- options.path ??= await (0, workspace_1.createDefaultPath)(host, options.project);
21
- options.module = (0, find_module_1.findModuleFromOptions)(host, options);
22
- const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
23
- options.name = parsedPath.name;
24
- options.path = parsedPath.path;
25
- (0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
26
- return (0, schematics_1.chain)([
27
- (0, add_declaration_to_ng_module_1.addDeclarationToNgModule)({
28
- type: 'pipe',
29
- ...options,
30
- }),
31
- (0, generate_from_files_1.generateFromFiles)(options),
32
- ]);
33
- };
34
- }
18
+ exports.default = (0, project_1.createProjectSchematic)(async (options, { tree }) => {
19
+ options.path ??= await (0, workspace_1.createDefaultPath)(tree, options.project);
20
+ options.module = (0, find_module_1.findModuleFromOptions)(tree, options);
21
+ const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
22
+ options.name = parsedPath.name;
23
+ options.path = parsedPath.path;
24
+ (0, validation_1.validateClassName)(schematics_1.strings.classify(options.name));
25
+ return (0, schematics_1.chain)([
26
+ (0, add_declaration_to_ng_module_1.addDeclarationToNgModule)({
27
+ type: 'pipe',
28
+ ...options,
29
+ }),
30
+ (0, generate_from_files_1.generateFromFiles)(options),
31
+ ]);
32
+ });
package/server/index.d.ts CHANGED
@@ -7,4 +7,5 @@
7
7
  */
8
8
  import { Rule } from '@angular-devkit/schematics';
9
9
  import { Schema as ServerOptions } from './schema';
10
- export default function (options: ServerOptions): Rule;
10
+ declare const _default: (options: ServerOptions) => Rule;
11
+ export default _default;
package/server/index.js CHANGED
@@ -7,7 +7,6 @@
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
10
  const core_1 = require("@angular-devkit/core");
12
11
  const schematics_1 = require("@angular-devkit/schematics");
13
12
  const node_path_1 = require("node:path");
@@ -17,6 +16,7 @@ const json_file_1 = require("../utility/json-file");
17
16
  const latest_versions_1 = require("../utility/latest-versions");
18
17
  const ng_ast_utils_1 = require("../utility/ng-ast-utils");
19
18
  const paths_1 = require("../utility/paths");
19
+ const project_1 = require("../utility/project");
20
20
  const project_targets_1 = require("../utility/project-targets");
21
21
  const app_component_1 = require("../utility/standalone/app_component");
22
22
  const util_1 = require("../utility/standalone/util");
@@ -132,74 +132,70 @@ function addDependencies(skipInstall) {
132
132
  ]);
133
133
  };
134
134
  }
135
- function default_1(options) {
136
- return async (host) => {
137
- const workspace = await (0, workspace_1.getWorkspace)(host);
138
- const clientProject = workspace.projects.get(options.project);
139
- if (clientProject?.extensions.projectType !== 'application') {
140
- throw new schematics_1.SchematicsException(`Server schematic requires a project type of "application".`);
141
- }
142
- const clientBuildTarget = clientProject.targets.get('build');
143
- if (!clientBuildTarget) {
144
- throw (0, project_targets_1.targetBuildNotFoundError)();
145
- }
146
- const usingApplicationBuilder = (0, project_targets_1.isUsingApplicationBuilder)(clientProject);
147
- if (clientProject.targets.has('server') ||
148
- (usingApplicationBuilder && clientBuildTarget.options?.server !== undefined)) {
149
- // Server has already been added.
150
- return;
151
- }
152
- const clientBuildOptions = clientBuildTarget.options;
153
- const browserEntryPoint = await (0, util_1.getMainFilePath)(host, options.project);
154
- const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(host, browserEntryPoint);
155
- const sourceRoot = clientProject.sourceRoot ?? (0, core_1.join)((0, core_1.normalize)(clientProject.root), 'src');
156
- let filesUrl = `./files/${usingApplicationBuilder ? 'application-builder/' : 'server-builder/'}`;
157
- filesUrl += isStandalone ? 'standalone-src' : 'ngmodule-src';
158
- const { componentName, componentImportPathInSameFile, moduleName, moduleImportPathInSameFile } = (0, app_component_1.resolveBootstrappedComponentData)(host, browserEntryPoint) || {
159
- componentName: 'App',
160
- componentImportPathInSameFile: './app/app',
161
- moduleName: 'AppModule',
162
- moduleImportPathInSameFile: './app/app.module',
163
- };
164
- const templateSource = (0, schematics_1.apply)((0, schematics_1.url)(filesUrl), [
165
- (0, schematics_1.applyTemplates)({
166
- ...schematics_1.strings,
167
- ...options,
168
- appComponentName: componentName,
169
- appComponentPath: componentImportPathInSameFile,
170
- appModuleName: moduleName,
171
- appModulePath: moduleImportPathInSameFile === null
172
- ? null
173
- : `./${node_path_1.posix.basename(moduleImportPathInSameFile)}`,
174
- }),
175
- (0, schematics_1.move)(sourceRoot),
176
- ]);
177
- const clientTsConfig = (0, core_1.normalize)(clientBuildOptions.tsConfig);
178
- const tsConfigExtends = (0, core_1.basename)(clientTsConfig);
179
- const tsConfigDirectory = (0, core_1.dirname)(clientTsConfig);
180
- return (0, schematics_1.chain)([
181
- (0, schematics_1.mergeWith)(templateSource),
182
- ...(usingApplicationBuilder
183
- ? [
184
- updateConfigFileApplicationBuilder(options),
185
- updateTsConfigFile(clientBuildOptions.tsConfig),
186
- ]
187
- : [
188
- (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files/server-builder/root'), [
189
- (0, schematics_1.applyTemplates)({
190
- ...schematics_1.strings,
191
- ...options,
192
- stripTsExtension: (s) => s.replace(/\.ts$/, ''),
193
- tsConfigExtends,
194
- hasLocalizePackage: !!(0, dependencies_1.getPackageJsonDependency)(host, '@angular/localize'),
195
- relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(tsConfigDirectory),
196
- }),
197
- (0, schematics_1.move)(tsConfigDirectory),
198
- ])),
199
- updateConfigFileBrowserBuilder(options, tsConfigDirectory),
200
- ]),
201
- addDependencies(options.skipInstall),
202
- (0, utility_1.addRootProvider)(options.project, ({ code, external }) => code `${external('provideClientHydration', '@angular/platform-browser')}(${external('withEventReplay', '@angular/platform-browser')}())`),
203
- ]);
135
+ exports.default = (0, project_1.createProjectSchematic)(async (options, { project, tree }) => {
136
+ if (project?.extensions.projectType !== 'application') {
137
+ throw new schematics_1.SchematicsException(`Server schematic requires a project type of "application".`);
138
+ }
139
+ const clientBuildTarget = project.targets.get('build');
140
+ if (!clientBuildTarget) {
141
+ throw (0, project_targets_1.targetBuildNotFoundError)();
142
+ }
143
+ const usingApplicationBuilder = (0, project_targets_1.isUsingApplicationBuilder)(project);
144
+ if (project.targets.has('server') ||
145
+ (usingApplicationBuilder && clientBuildTarget.options?.server !== undefined)) {
146
+ // Server has already been added.
147
+ return (0, schematics_1.noop)();
148
+ }
149
+ const clientBuildOptions = clientBuildTarget.options;
150
+ const browserEntryPoint = await (0, util_1.getMainFilePath)(tree, options.project);
151
+ const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(tree, browserEntryPoint);
152
+ const sourceRoot = project.sourceRoot ?? (0, core_1.join)((0, core_1.normalize)(project.root), 'src');
153
+ let filesUrl = `./files/${usingApplicationBuilder ? 'application-builder/' : 'server-builder/'}`;
154
+ filesUrl += isStandalone ? 'standalone-src' : 'ngmodule-src';
155
+ const { componentName, componentImportPathInSameFile, moduleName, moduleImportPathInSameFile } = (0, app_component_1.resolveBootstrappedComponentData)(tree, browserEntryPoint) || {
156
+ componentName: 'App',
157
+ componentImportPathInSameFile: './app/app',
158
+ moduleName: 'AppModule',
159
+ moduleImportPathInSameFile: './app/app.module',
204
160
  };
205
- }
161
+ const templateSource = (0, schematics_1.apply)((0, schematics_1.url)(filesUrl), [
162
+ (0, schematics_1.applyTemplates)({
163
+ ...schematics_1.strings,
164
+ ...options,
165
+ appComponentName: componentName,
166
+ appComponentPath: componentImportPathInSameFile,
167
+ appModuleName: moduleName,
168
+ appModulePath: moduleImportPathInSameFile === null
169
+ ? null
170
+ : `./${node_path_1.posix.basename(moduleImportPathInSameFile)}`,
171
+ }),
172
+ (0, schematics_1.move)(sourceRoot),
173
+ ]);
174
+ const clientTsConfig = (0, core_1.normalize)(clientBuildOptions.tsConfig);
175
+ const tsConfigExtends = (0, core_1.basename)(clientTsConfig);
176
+ const tsConfigDirectory = (0, core_1.dirname)(clientTsConfig);
177
+ return (0, schematics_1.chain)([
178
+ (0, schematics_1.mergeWith)(templateSource),
179
+ ...(usingApplicationBuilder
180
+ ? [
181
+ updateConfigFileApplicationBuilder(options),
182
+ updateTsConfigFile(clientBuildOptions.tsConfig),
183
+ ]
184
+ : [
185
+ (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files/server-builder/root'), [
186
+ (0, schematics_1.applyTemplates)({
187
+ ...schematics_1.strings,
188
+ ...options,
189
+ stripTsExtension: (s) => s.replace(/\.ts$/, ''),
190
+ tsConfigExtends,
191
+ hasLocalizePackage: !!(0, dependencies_1.getPackageJsonDependency)(tree, '@angular/localize'),
192
+ relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(tsConfigDirectory),
193
+ }),
194
+ (0, schematics_1.move)(tsConfigDirectory),
195
+ ])),
196
+ updateConfigFileBrowserBuilder(options, tsConfigDirectory),
197
+ ]),
198
+ addDependencies(options.skipInstall),
199
+ (0, utility_1.addRootProvider)(options.project, ({ code, external }) => code `${external('provideClientHydration', '@angular/platform-browser')}(${external('withEventReplay', '@angular/platform-browser')}())`),
200
+ ]);
201
+ });