@schematics/angular 17.1.0-next.0 → 17.1.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,17 @@
14
14
  "version": "17.0.0",
15
15
  "factory": "./update-17/update-workspace-config",
16
16
  "description": "Replace deprecated options in 'angular.json'."
17
+ },
18
+ "add-browser-sync-dependency": {
19
+ "version": "17.1.0",
20
+ "factory": "./update-17/add-browser-sync-dependency",
21
+ "description": "Add 'browser-sync' as dev dependency when '@angular-devkit/build-angular:ssr-dev-server' is used, as it is no longer a direct dependency of '@angular-devkit/build-angular'."
22
+ },
23
+ "use-application-builder": {
24
+ "version": "18.0.0",
25
+ "factory": "./update-17/use-application-builder",
26
+ "description": "Migrate application projects using '@angular-devkit/build-angular:browser' and '@angular-devkit/build-angular:browser-esbuild' to use the '@angular-devkit/build-angular:application' builder. Read more about this here: https://angular.dev/tools/cli/esbuild#using-the-application-builder",
27
+ "optional": true
17
28
  }
18
29
  }
19
30
  }
@@ -0,0 +1,9 @@
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.io/license
7
+ */
8
+ import { Rule } from '@angular-devkit/schematics';
9
+ export default function (): Rule;
@@ -0,0 +1,36 @@
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.io/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const utility_1 = require("../../utility");
11
+ const dependencies_1 = require("../../utility/dependencies");
12
+ const latest_versions_1 = require("../../utility/latest-versions");
13
+ const workspace_1 = require("../../utility/workspace");
14
+ const workspace_models_1 = require("../../utility/workspace-models");
15
+ const BROWSER_SYNC_VERSION = latest_versions_1.latestVersions['browser-sync'];
16
+ function default_1() {
17
+ return async (tree) => {
18
+ if ((0, dependencies_1.getPackageJsonDependency)(tree, 'browser-sync')?.version === BROWSER_SYNC_VERSION) {
19
+ return;
20
+ }
21
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
22
+ for (const project of workspace.projects.values()) {
23
+ if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
24
+ continue;
25
+ }
26
+ for (const target of project.targets.values()) {
27
+ if (target.builder === workspace_models_1.Builders.SsrDevServer) {
28
+ return (0, utility_1.addDependency)('browser-sync', BROWSER_SYNC_VERSION, {
29
+ type: utility_1.DependencyType.Dev,
30
+ });
31
+ }
32
+ }
33
+ }
34
+ };
35
+ }
36
+ exports.default = default_1;
@@ -0,0 +1,9 @@
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.io/license
7
+ */
8
+ import { Rule } from '@angular-devkit/schematics';
9
+ export default function (): Rule;
@@ -0,0 +1,141 @@
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.io/license
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const core_1 = require("@angular-devkit/core");
11
+ const schematics_1 = require("@angular-devkit/schematics");
12
+ const node_path_1 = require("node:path");
13
+ const json_file_1 = require("../../utility/json-file");
14
+ const workspace_1 = require("../../utility/workspace");
15
+ const workspace_models_1 = require("../../utility/workspace-models");
16
+ function default_1() {
17
+ return async (tree, context) => {
18
+ const rules = [];
19
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
20
+ for (const [name, project] of workspace.projects) {
21
+ if (project.extensions.projectType !== workspace_models_1.ProjectType.Application) {
22
+ // Only interested in application projects since these changes only effects application builders
23
+ continue;
24
+ }
25
+ const buildTarget = project.targets.get('build');
26
+ if (!buildTarget || buildTarget.builder === workspace_models_1.Builders.Application) {
27
+ continue;
28
+ }
29
+ if (buildTarget.builder !== workspace_models_1.Builders.BrowserEsbuild &&
30
+ buildTarget.builder !== workspace_models_1.Builders.Browser) {
31
+ context.logger.error(`Cannot update project "${name}" to use the application builder.` +
32
+ ` Only "${workspace_models_1.Builders.BrowserEsbuild}" and "${workspace_models_1.Builders.Browser}" can be automatically migrated.`);
33
+ continue;
34
+ }
35
+ // Update builder target and options
36
+ buildTarget.builder = workspace_models_1.Builders.Application;
37
+ const hasServerTarget = project.targets.has('server');
38
+ for (const [, options] of (0, workspace_1.allTargetOptions)(buildTarget, false)) {
39
+ // Show warnings for using no longer supported options
40
+ if (usesNoLongerSupportedOptions(options, context, name)) {
41
+ continue;
42
+ }
43
+ // Rename and transform options
44
+ options['browser'] = options['main'];
45
+ if (hasServerTarget && typeof options['browser'] === 'string') {
46
+ options['server'] = (0, node_path_1.dirname)(options['browser']) + '/main.server.ts';
47
+ }
48
+ options['serviceWorker'] = options['ngswConfigPath'] ?? options['serviceWorker'];
49
+ if (typeof options['polyfills'] === 'string') {
50
+ options['polyfills'] = [options['polyfills']];
51
+ }
52
+ if (typeof options['outputPath'] === 'string') {
53
+ options['outputPath'] = options['outputPath']?.replace(/\/browser\/?$/, '');
54
+ }
55
+ // Delete removed options
56
+ delete options['deployUrl'];
57
+ delete options['vendorChunk'];
58
+ delete options['commonChunk'];
59
+ delete options['resourcesOutputPath'];
60
+ delete options['buildOptimizer'];
61
+ delete options['main'];
62
+ delete options['ngswConfigPath'];
63
+ }
64
+ // Merge browser and server tsconfig
65
+ if (hasServerTarget) {
66
+ const browserTsConfig = buildTarget?.options?.tsConfig;
67
+ const serverTsConfig = project.targets.get('server')?.options?.tsConfig;
68
+ if (typeof browserTsConfig !== 'string') {
69
+ throw new schematics_1.SchematicsException(`Cannot update project "${name}" to use the application builder` +
70
+ ` as the browser tsconfig cannot be located.`);
71
+ }
72
+ if (typeof serverTsConfig !== 'string') {
73
+ throw new schematics_1.SchematicsException(`Cannot update project "${name}" to use the application builder` +
74
+ ` as the server tsconfig cannot be located.`);
75
+ }
76
+ const browserJson = new json_file_1.JSONFile(tree, browserTsConfig);
77
+ const serverJson = new json_file_1.JSONFile(tree, serverTsConfig);
78
+ const filesPath = ['files'];
79
+ const files = new Set([
80
+ ...(browserJson.get(filesPath) ?? []),
81
+ ...(serverJson.get(filesPath) ?? []),
82
+ ]);
83
+ // Server file will be added later by the means of the ssr schematic.
84
+ files.delete('server.ts');
85
+ browserJson.modify(filesPath, Array.from(files));
86
+ const typesPath = ['compilerOptions', 'types'];
87
+ browserJson.modify(typesPath, Array.from(new Set([
88
+ ...(browserJson.get(typesPath) ?? []),
89
+ ...(serverJson.get(typesPath) ?? []),
90
+ ])));
91
+ // Delete server tsconfig
92
+ tree.delete(serverTsConfig);
93
+ }
94
+ // Update main tsconfig
95
+ const rootJson = new json_file_1.JSONFile(tree, 'tsconfig.json');
96
+ rootJson.modify(['compilerOptions', 'esModuleInterop'], true);
97
+ rootJson.modify(['compilerOptions', 'downlevelIteration'], undefined);
98
+ rootJson.modify(['compilerOptions', 'allowSyntheticDefaultImports'], undefined);
99
+ // Update server file
100
+ const ssrMainFile = project.targets.get('server')?.options?.['main'];
101
+ if (typeof ssrMainFile === 'string') {
102
+ tree.delete(ssrMainFile);
103
+ rules.push((0, schematics_1.externalSchematic)('@schematics/angular', 'ssr', {
104
+ project: name,
105
+ skipInstall: true,
106
+ }));
107
+ }
108
+ // Delete package.json helper scripts
109
+ const pkgJson = new json_file_1.JSONFile(tree, 'package.json');
110
+ ['build:ssr', 'dev:ssr', 'serve:ssr', 'prerender'].forEach((s) => pkgJson.remove(['scripts', s]));
111
+ // Delete all redundant targets
112
+ for (const [key, target] of project.targets) {
113
+ switch (target.builder) {
114
+ case workspace_models_1.Builders.Server:
115
+ case workspace_models_1.Builders.Prerender:
116
+ case workspace_models_1.Builders.AppShell:
117
+ case workspace_models_1.Builders.SsrDevServer:
118
+ project.targets.delete(key);
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ // Save workspace changes
124
+ await core_1.workspaces.writeWorkspace(workspace, new workspace_1.TreeWorkspaceHost(tree));
125
+ return (0, schematics_1.chain)(rules);
126
+ };
127
+ }
128
+ exports.default = default_1;
129
+ function usesNoLongerSupportedOptions({ deployUrl, resourcesOutputPath }, context, projectName) {
130
+ let hasUsage = false;
131
+ if (typeof deployUrl === 'string') {
132
+ hasUsage = true;
133
+ context.logger.warn(`Skipping migration for project "${projectName}". "deployUrl" option is not available in the application builder.`);
134
+ }
135
+ if (typeof resourcesOutputPath === 'string' && /^\/?media\/?$/.test(resourcesOutputPath)) {
136
+ hasUsage = true;
137
+ context.logger.warn(`Skipping migration for project "${projectName}". "resourcesOutputPath" option is not available in the application builder.` +
138
+ `Media files will be output into a "media" directory within the output location.`);
139
+ }
140
+ return hasUsage;
141
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "17.1.0-next.0",
3
+ "version": "17.1.0-next.1",
4
4
  "description": "Schematics specific to Angular",
5
5
  "homepage": "https://github.com/angular/angular-cli",
6
6
  "keywords": [
@@ -23,8 +23,8 @@
23
23
  },
24
24
  "schematics": "./collection.json",
25
25
  "dependencies": {
26
- "@angular-devkit/core": "17.1.0-next.0",
27
- "@angular-devkit/schematics": "17.1.0-next.0",
26
+ "@angular-devkit/core": "17.1.0-next.1",
27
+ "@angular-devkit/schematics": "17.1.0-next.1",
28
28
  "jsonc-parser": "3.2.0"
29
29
  },
30
30
  "repository": {
package/ssr/index.js CHANGED
@@ -169,8 +169,8 @@ function updateWebpackBuilderServerTsConfigRule(options) {
169
169
  }
170
170
  };
171
171
  }
172
- function addDependencies() {
173
- return (0, schematics_1.chain)([
172
+ function addDependencies(isUsingApplicationBuilder) {
173
+ const rules = [
174
174
  (0, utility_1.addDependency)('@angular/ssr', latest_versions_1.latestVersions.AngularSSR, {
175
175
  type: utility_1.DependencyType.Default,
176
176
  }),
@@ -180,7 +180,13 @@ function addDependencies() {
180
180
  (0, utility_1.addDependency)('@types/express', latest_versions_1.latestVersions['@types/express'], {
181
181
  type: utility_1.DependencyType.Dev,
182
182
  }),
183
- ]);
183
+ ];
184
+ if (!isUsingApplicationBuilder) {
185
+ rules.push((0, utility_1.addDependency)('browser-sync', latest_versions_1.latestVersions['browser-sync'], {
186
+ type: utility_1.DependencyType.Dev,
187
+ }));
188
+ }
189
+ return (0, schematics_1.chain)(rules);
184
190
  }
185
191
  function addServerFile(options, isStandalone) {
186
192
  return async (host) => {
@@ -214,7 +220,7 @@ function default_1(options) {
214
220
  }
215
221
  const isUsingApplicationBuilder = clientProject.targets.get('build')?.builder === workspace_models_1.Builders.Application;
216
222
  return (0, schematics_1.chain)([
217
- (0, schematics_1.externalSchematic)('@schematics/angular', 'server', {
223
+ (0, schematics_1.schematic)('server', {
218
224
  ...options,
219
225
  skipInstall: true,
220
226
  }),
@@ -229,7 +235,7 @@ function default_1(options) {
229
235
  ]),
230
236
  addServerFile(options, isStandalone),
231
237
  addScriptsRule(options, isUsingApplicationBuilder),
232
- addDependencies(),
238
+ addDependencies(isUsingApplicationBuilder),
233
239
  ]);
234
240
  };
235
241
  }
@@ -6,6 +6,7 @@
6
6
  "@types/express": "^4.17.17",
7
7
  "@types/jasmine": "~5.1.0",
8
8
  "@types/node": "^18.18.0",
9
+ "browser-sync": "^2.29.3",
9
10
  "express": "^4.18.2",
10
11
  "jasmine-core": "~5.1.0",
11
12
  "jasmine-spec-reporter": "~7.0.0",
@@ -19,7 +20,7 @@
19
20
  "rxjs": "~7.8.0",
20
21
  "tslib": "^2.3.0",
21
22
  "ts-node": "~10.9.0",
22
- "typescript": "~5.2.2",
23
+ "typescript": "~5.3.2",
23
24
  "zone.js": "~0.14.2"
24
25
  }
25
26
  }
@@ -14,6 +14,6 @@ exports.latestVersions = {
14
14
  ...require('./latest-versions/package.json')['dependencies'],
15
15
  // As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
16
16
  Angular: '^17.1.0-next.0',
17
- DevkitBuildAngular: '^17.1.0-next.0',
18
- AngularSSR: '^17.1.0-next.0',
17
+ DevkitBuildAngular: '^17.1.0-next.1',
18
+ AngularSSR: '^17.1.0-next.1',
19
19
  };
@@ -20,6 +20,8 @@ export declare enum Builders {
20
20
  AppShell = "@angular-devkit/build-angular:app-shell",
21
21
  Server = "@angular-devkit/build-angular:server",
22
22
  Browser = "@angular-devkit/build-angular:browser",
23
+ SsrDevServer = "@angular-devkit/build-angular:ssr-dev-server",
24
+ Prerender = "@angular-devkit/build-angular:prerender",
23
25
  BrowserEsbuild = "@angular-devkit/build-angular:browser-esbuild",
24
26
  Karma = "@angular-devkit/build-angular:karma",
25
27
  TsLint = "@angular-devkit/build-angular:tslint",
@@ -25,6 +25,8 @@ var Builders;
25
25
  Builders["AppShell"] = "@angular-devkit/build-angular:app-shell";
26
26
  Builders["Server"] = "@angular-devkit/build-angular:server";
27
27
  Builders["Browser"] = "@angular-devkit/build-angular:browser";
28
+ Builders["SsrDevServer"] = "@angular-devkit/build-angular:ssr-dev-server";
29
+ Builders["Prerender"] = "@angular-devkit/build-angular:prerender";
28
30
  Builders["BrowserEsbuild"] = "@angular-devkit/build-angular:browser-esbuild";
29
31
  Builders["Karma"] = "@angular-devkit/build-angular:karma";
30
32
  Builders["TsLint"] = "@angular-devkit/build-angular:tslint";
@@ -10,6 +10,17 @@ import { Rule, Tree } from '@angular-devkit/schematics';
10
10
  export type WorkspaceDefinition = workspaces.WorkspaceDefinition;
11
11
  export type ProjectDefinition = workspaces.ProjectDefinition;
12
12
  export type TargetDefinition = workspaces.TargetDefinition;
13
+ /**
14
+ * A {@link workspaces.WorkspaceHost} backed by a Schematics {@link Tree} instance.
15
+ */
16
+ export declare class TreeWorkspaceHost implements workspaces.WorkspaceHost {
17
+ private readonly tree;
18
+ constructor(tree: Tree);
19
+ readFile(path: string): Promise<string>;
20
+ writeFile(path: string, data: string): Promise<void>;
21
+ isDirectory(path: string): Promise<boolean>;
22
+ isFile(path: string): Promise<boolean>;
23
+ }
13
24
  /**
14
25
  * Updates the workspace file (`angular.json`) found within the root of the schematic's tree.
15
26
  * The workspace object model can be directly modified within the provided updater function
@@ -7,7 +7,7 @@
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.allTargetOptions = exports.allWorkspaceTargets = exports.createDefaultPath = exports.buildDefaultPath = exports.writeWorkspace = exports.getWorkspace = exports.updateWorkspace = void 0;
10
+ exports.allTargetOptions = exports.allWorkspaceTargets = exports.createDefaultPath = exports.buildDefaultPath = exports.writeWorkspace = exports.getWorkspace = exports.updateWorkspace = exports.TreeWorkspaceHost = void 0;
11
11
  const core_1 = require("@angular-devkit/core");
12
12
  const schematics_1 = require("@angular-devkit/schematics");
13
13
  const workspace_models_1 = require("./workspace-models");
@@ -39,6 +39,7 @@ class TreeWorkspaceHost {
39
39
  return this.tree.exists(path);
40
40
  }
41
41
  }
42
+ exports.TreeWorkspaceHost = TreeWorkspaceHost;
42
43
  /**
43
44
  * Updates the workspace file (`angular.json`) found within the root of the schematic's tree.
44
45
  * The workspace object model can be directly modified within the provided updater function
@@ -50,11 +51,10 @@ class TreeWorkspaceHost {
50
51
  * workspace. A {@link WorkspaceDefinition} is provided as the first argument to the function.
51
52
  */
52
53
  function updateWorkspace(updater) {
53
- return async (tree) => {
54
- const host = new TreeWorkspaceHost(tree);
55
- const { workspace } = await core_1.workspaces.readWorkspace(DEFAULT_WORKSPACE_PATH, host);
54
+ return async (host) => {
55
+ const workspace = await getWorkspace(host);
56
56
  const result = await updater(workspace);
57
- await core_1.workspaces.writeWorkspace(workspace, host);
57
+ await core_1.workspaces.writeWorkspace(workspace, new TreeWorkspaceHost(host));
58
58
  return result || schematics_1.noop;
59
59
  };
60
60
  }
@@ -9,6 +9,7 @@
9
9
  "noPropertyAccessFromIndexSignature": true,
10
10
  "noImplicitReturns": true,
11
11
  "noFallthroughCasesInSwitch": true,<% } %>
12
+ "skipLibCheck": true,
12
13
  "esModuleInterop": true,
13
14
  "sourceMap": true,
14
15
  "declaration": false,