@schematics/angular 19.0.0-rc.1 → 19.0.0-rc.3

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.
@@ -202,7 +202,7 @@ function addStandaloneServerRoute(options) {
202
202
  if (!host.exists(configFilePath)) {
203
203
  throw new schematics_1.SchematicsException(`Cannot find "${configFilePath}".`);
204
204
  }
205
- const recorder = host.beginUpdate(configFilePath);
205
+ let recorder = host.beginUpdate(configFilePath);
206
206
  let configSourceFile = getSourceFile(host, configFilePath);
207
207
  if (!(0, ast_utils_1.isImported)(configSourceFile, 'ROUTES', '@angular/router')) {
208
208
  const routesChange = (0, ast_utils_1.insertImport)(configSourceFile, configFilePath, 'ROUTES', '@angular/router');
@@ -229,6 +229,16 @@ function addStandaloneServerRoute(options) {
229
229
  }\n `,
230
230
  ];
231
231
  recorder.insertRight(providersLiteral.getStart(), `[\n${updatedProvidersString.join(',\n')}]`);
232
+ if (options.serverRouting) {
233
+ host.commitUpdate(recorder);
234
+ configSourceFile = getSourceFile(host, configFilePath);
235
+ const functionCall = (0, ast_utils_1.findNodes)(configSourceFile, typescript_1.default.isCallExpression).find((n) => typescript_1.default.isIdentifier(n.expression) && n.expression.getText() === 'provideServerRoutesConfig');
236
+ if (!functionCall) {
237
+ throw new schematics_1.SchematicsException(`Cannot find the "provideServerRoutesConfig" function call in "${configFilePath}".`);
238
+ }
239
+ recorder = host.beginUpdate(configFilePath);
240
+ recorder.insertLeft(functionCall.end - 1, `, { appShellRoute: '${APP_SHELL_ROUTE}' }`);
241
+ }
232
242
  // Add AppShellComponent import
233
243
  const appShellImportChange = (0, ast_utils_1.insertImport)(configSourceFile, configFilePath, 'AppShellComponent', './app-shell/app-shell.component');
234
244
  (0, change_1.applyToUpdateRecorder)(recorder, [appShellImportChange]);
@@ -279,9 +289,7 @@ function default_1(options) {
279
289
  ...(isStandalone
280
290
  ? [addStandaloneServerRoute(options)]
281
291
  : [addRouterModule(browserEntryPoint), addServerRoutes(options)]),
282
- options.serverRouting
283
- ? addServerRoutingConfig(options)
284
- : addAppShellConfigToWorkspace(options),
292
+ options.serverRouting ? (0, schematics_1.noop)() : addAppShellConfigToWorkspace(options),
285
293
  (0, schematics_1.schematic)('component', {
286
294
  name: 'app-shell',
287
295
  module: 'app.module.server.ts',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematics/angular",
3
- "version": "19.0.0-rc.1",
3
+ "version": "19.0.0-rc.3",
4
4
  "description": "Schematics specific to Angular",
5
5
  "homepage": "https://github.com/angular/angular-cli",
6
6
  "keywords": [
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "schematics": "./collection.json",
24
24
  "dependencies": {
25
- "@angular-devkit/core": "19.0.0-rc.1",
26
- "@angular-devkit/schematics": "19.0.0-rc.1",
25
+ "@angular-devkit/core": "19.0.0-rc.3",
26
+ "@angular-devkit/schematics": "19.0.0-rc.3",
27
27
  "jsonc-parser": "3.3.1"
28
28
  },
29
29
  "packageManager": "yarn@4.5.0",
@@ -2,7 +2,7 @@ import 'zone.js/node';
2
2
 
3
3
  import { APP_BASE_HREF } from '@angular/common';
4
4
  import { CommonEngine } from '@angular/ssr/node';
5
- import * as express from 'express';
5
+ import express from 'express';
6
6
  import { existsSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  import <% if (isStandalone) { %>bootstrap<% } else { %>AppServerModule<% } %> from './main.server';
package/ssr/index.d.ts CHANGED
@@ -7,4 +7,6 @@
7
7
  */
8
8
  import { Rule } from '@angular-devkit/schematics';
9
9
  import { Schema as SSROptions } from './schema';
10
- export default function (options: SSROptions): Rule;
10
+ export default function (inputOptions: SSROptions): Rule;
11
+ export type Prompt = (message: string, defaultValue: boolean) => Promise<boolean>;
12
+ export declare function setPrompterForTestOnly(prompter?: Prompt): void;
package/ssr/index.js CHANGED
@@ -6,8 +6,32 @@
6
6
  * Use of this source code is governed by an MIT-style license that can be
7
7
  * found in the LICENSE file at https://angular.dev/license
8
8
  */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
9
32
  Object.defineProperty(exports, "__esModule", { value: true });
10
33
  exports.default = default_1;
34
+ exports.setPrompterForTestOnly = setPrompterForTestOnly;
11
35
  const core_1 = require("@angular-devkit/core");
12
36
  const schematics_1 = require("@angular-devkit/schematics");
13
37
  const node_path_1 = require("node:path");
@@ -19,6 +43,7 @@ const project_targets_1 = require("../utility/project-targets");
19
43
  const util_1 = require("../utility/standalone/util");
20
44
  const workspace_1 = require("../utility/workspace");
21
45
  const workspace_models_1 = require("../utility/workspace-models");
46
+ const tty_1 = require("./tty");
22
47
  const SERVE_SSR_TARGET_NAME = 'serve-ssr';
23
48
  const PRERENDER_TARGET_NAME = 'prerender';
24
49
  const DEFAULT_BROWSER_DIR = 'browser';
@@ -49,7 +74,7 @@ async function getApplicationBuilderOutputPaths(host, projectName) {
49
74
  }
50
75
  const { outputPath } = architectTarget.options;
51
76
  if (outputPath === null || outputPath === undefined) {
52
- throw new schematics_1.SchematicsException(`outputPath for ${projectName} ${target} target is undeined or null.`);
77
+ throw new schematics_1.SchematicsException(`outputPath for ${projectName} ${target} target is undefined or null.`);
53
78
  }
54
79
  const defaultDirs = {
55
80
  server: DEFAULT_SERVER_DIR,
@@ -266,16 +291,18 @@ function addServerFile(projectSourceRoot, options, isStandalone) {
266
291
  ]));
267
292
  };
268
293
  }
269
- function default_1(options) {
294
+ function default_1(inputOptions) {
270
295
  return async (host, context) => {
271
- const browserEntryPoint = await (0, util_1.getMainFilePath)(host, options.project);
296
+ const browserEntryPoint = await (0, util_1.getMainFilePath)(host, inputOptions.project);
272
297
  const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(host, browserEntryPoint);
273
298
  const workspace = await (0, workspace_1.getWorkspace)(host);
274
- const clientProject = workspace.projects.get(options.project);
299
+ const clientProject = workspace.projects.get(inputOptions.project);
275
300
  if (!clientProject) {
276
301
  throw (0, project_targets_1.targetBuildNotFoundError)();
277
302
  }
278
303
  const isUsingApplicationBuilder = usingApplicationBuilder(clientProject);
304
+ const serverRouting = await isServerRoutingEnabled(isUsingApplicationBuilder, inputOptions);
305
+ const options = { ...inputOptions, serverRouting };
279
306
  const sourceRoot = clientProject.sourceRoot ?? node_path_1.posix.join(clientProject.root, 'src');
280
307
  return (0, schematics_1.chain)([
281
308
  (0, schematics_1.schematic)('server', {
@@ -302,3 +329,38 @@ function usingApplicationBuilder(project) {
302
329
  const isUsingApplicationBuilder = buildBuilder === workspace_models_1.Builders.Application || buildBuilder === workspace_models_1.Builders.BuildApplication;
303
330
  return isUsingApplicationBuilder;
304
331
  }
332
+ const defaultPrompter = async (message, defaultValue) => {
333
+ const { confirm } = await Promise.resolve().then(() => __importStar(require('@inquirer/prompts')));
334
+ return await confirm({
335
+ message,
336
+ default: defaultValue,
337
+ });
338
+ };
339
+ // Allow the prompt functionality to be overridden to facilitate testing.
340
+ let prompt = defaultPrompter;
341
+ function setPrompterForTestOnly(prompter) {
342
+ prompt = prompter ?? defaultPrompter;
343
+ }
344
+ /** Returns whether or not server routing is enabled, potentially prompting the user if necessary. */
345
+ async function isServerRoutingEnabled(isUsingApplicationBuilder, options) {
346
+ if (!isUsingApplicationBuilder) {
347
+ if (options.serverRouting) {
348
+ throw new schematics_1.SchematicsException('Server routing APIs can only be added to a project using `application` builder.');
349
+ }
350
+ else {
351
+ return false;
352
+ }
353
+ }
354
+ // Use explicit option if provided.
355
+ if (options.serverRouting !== undefined) {
356
+ return options.serverRouting;
357
+ }
358
+ const serverRoutingDefault = false;
359
+ // Use the default if not in an interactive terminal.
360
+ if (!(0, tty_1.isTTY)()) {
361
+ return serverRoutingDefault;
362
+ }
363
+ // Prompt the user if in an interactive terminal and no option was provided.
364
+ return await prompt('Would you like to use the Server Routing and App Engine APIs (Developer Preview) for this server application?',
365
+ /* defaultValue */ serverRoutingDefault);
366
+ }
package/ssr/schema.json CHANGED
@@ -18,9 +18,7 @@
18
18
  },
19
19
  "serverRouting": {
20
20
  "description": "Creates a server application using the Server Routing and App Engine APIs (Developer Preview).",
21
- "x-prompt": "Would you like to use the Server Routing and App Engine APIs (Developer Preview) for this server application?",
22
- "type": "boolean",
23
- "default": false
21
+ "type": "boolean"
24
22
  }
25
23
  },
26
24
  "required": ["project"],
package/ssr/tty.d.ts ADDED
@@ -0,0 +1,8 @@
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
+ export declare function isTTY(): boolean;
package/ssr/tty.js ADDED
@@ -0,0 +1,22 @@
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.isTTY = isTTY;
11
+ function _isTruthy(value) {
12
+ // Returns true if value is a string that is anything but 0 or false.
13
+ return value !== undefined && value !== '0' && value.toUpperCase() !== 'FALSE';
14
+ }
15
+ function isTTY() {
16
+ // If we force TTY, we always return true.
17
+ const force = process.env['NG_FORCE_TTY'];
18
+ if (force !== undefined) {
19
+ return _isTruthy(force);
20
+ }
21
+ return !!process.stdout.isTTY && !_isTruthy(process.env['CI']);
22
+ }
@@ -15,6 +15,6 @@ exports.latestVersions = {
15
15
  ...dependencies,
16
16
  // As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
17
17
  Angular: dependencies['@angular/core'],
18
- DevkitBuildAngular: '^19.0.0-rc.1',
19
- AngularSSR: '^19.0.0-rc.1',
18
+ DevkitBuildAngular: '^19.0.0-rc.3',
19
+ AngularSSR: '^19.0.0-rc.3',
20
20
  };