mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 18:13:38 +08:00
Compare commits
8 Commits
3207d54852
...
ffdd926625
Author | SHA1 | Date | |
---|---|---|---|
|
ffdd926625 | ||
|
b66d36b4b0 | ||
|
26fd4ea73a | ||
|
33b9de3eb1 | ||
|
fe69a9b23a | ||
|
bc0f07b484 | ||
|
e7ae25a76b | ||
|
882dc4884f |
goldens/public-api/angular/ssr
package.jsonpackages
angular
build
pwa
ssr
angular_devkit
build_angular
schematics
schematics/angular
app-shell
library
migrations
server/files
application-builder
server-builder/standalone-src/app
service
files/__name@dasherize@if-flat__
__name@dasherize__.__type@dasherize__.spec.ts.template__name@dasherize__.__type@dasherize__.ts.template__name@dasherize__.service.spec.ts.template
index.tsindex_spec.tsschema.jsonutility
tests/legacy-cli
@ -27,7 +27,7 @@ export enum PrerenderFallback {
|
||||
}
|
||||
|
||||
// @public
|
||||
export function provideServerRouting(routes: ServerRoute[], ...features: ServerRoutesFeature<ServerRoutesFeatureKind>[]): EnvironmentProviders;
|
||||
export function provideServerRendering(...features: ServerRenderingFeature<ServerRenderingFeatureKind>[]): EnvironmentProviders;
|
||||
|
||||
// @public
|
||||
export enum RenderMode {
|
||||
@ -72,7 +72,10 @@ export interface ServerRouteServer extends ServerRouteCommon {
|
||||
}
|
||||
|
||||
// @public
|
||||
export function withAppShell(component: Type<unknown> | (() => Promise<Type<unknown> | DefaultExport<Type<unknown>>>)): ServerRoutesFeature<ServerRoutesFeatureKind.AppShell>;
|
||||
export function withAppShell(component: Type<unknown> | (() => Promise<Type<unknown> | DefaultExport<Type<unknown>>>)): ServerRenderingFeature<ServerRenderingFeatureKind.AppShell>;
|
||||
|
||||
// @public
|
||||
export function withRoutes(routes: ServerRoute[]): ServerRenderingFeature<ServerRenderingFeatureKind.ServerRoutes>;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
|
14
package.json
14
package.json
@ -46,7 +46,6 @@
|
||||
},
|
||||
"homepage": "https://github.com/angular/angular-cli",
|
||||
"devDependencies": {
|
||||
"@ampproject/remapping": "2.3.0",
|
||||
"@angular/animations": "20.0.0-next.2",
|
||||
"@angular/cdk": "20.0.0-next.1",
|
||||
"@angular/common": "20.0.0-next.2",
|
||||
@ -134,34 +133,24 @@
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.1.0",
|
||||
"karma-source-map-support": "1.4.0",
|
||||
"less": "4.2.2",
|
||||
"listr2": "8.2.5",
|
||||
"lmdb": "3.2.6",
|
||||
"lodash": "^4.17.21",
|
||||
"magic-string": "0.30.17",
|
||||
"mrmime": "2.0.1",
|
||||
"ng-packagr": "20.0.0-next.1",
|
||||
"npm": "^11.0.0",
|
||||
"open": "10.1.0",
|
||||
"ora": "5.4.1",
|
||||
"parse5-html-rewriting-stream": "7.0.0",
|
||||
"piscina": "4.9.0",
|
||||
"postcss": "8.5.3",
|
||||
"prettier": "^3.0.0",
|
||||
"protractor": "~7.0.0",
|
||||
"puppeteer": "18.2.1",
|
||||
"puppeteer": "24.4.0",
|
||||
"quicktype-core": "23.0.171",
|
||||
"rollup": "4.36.0",
|
||||
"rollup-license-plugin": "~3.0.1",
|
||||
"rollup-plugin-sourcemaps": "^0.6.0",
|
||||
"rxjs": "7.8.2",
|
||||
"sass": "1.85.1",
|
||||
"semver": "7.7.1",
|
||||
"shelljs": "^0.9.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"symbol-observable": "4.0.0",
|
||||
"tar": "^7.0.0",
|
||||
"tinyglobby": "0.2.12",
|
||||
"tree-kill": "1.2.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "2.8.1",
|
||||
@ -170,7 +159,6 @@
|
||||
"unenv": "^1.10.0",
|
||||
"verdaccio": "6.0.5",
|
||||
"verdaccio-auth-memory": "^10.0.0",
|
||||
"watchpack": "2.4.2",
|
||||
"yargs-parser": "21.1.1",
|
||||
"zone.js": "^0.15.0"
|
||||
},
|
||||
|
@ -74,15 +74,28 @@ ts_project(
|
||||
data = RUNTIME_ASSETS,
|
||||
module_name = "@angular/build",
|
||||
deps = [
|
||||
":node_modules/@ampproject/remapping",
|
||||
":node_modules/@angular-devkit/architect",
|
||||
":node_modules/@angular-devkit/core",
|
||||
":node_modules/@angular/ssr",
|
||||
":node_modules/@inquirer/confirm",
|
||||
":node_modules/@vitejs/plugin-basic-ssl",
|
||||
":node_modules/jsonc-parser",
|
||||
":node_modules/less",
|
||||
":node_modules/listr2",
|
||||
":node_modules/lmdb",
|
||||
":node_modules/magic-string",
|
||||
":node_modules/mrmime",
|
||||
":node_modules/ng-packagr",
|
||||
":node_modules/parse5-html-rewriting-stream",
|
||||
":node_modules/picomatch",
|
||||
":node_modules/piscina",
|
||||
":node_modules/postcss",
|
||||
":node_modules/sass",
|
||||
":node_modules/source-map-support",
|
||||
":node_modules/tinyglobby",
|
||||
":node_modules/vite",
|
||||
"//:node_modules/@ampproject/remapping",
|
||||
":node_modules/watchpack",
|
||||
"//:node_modules/@angular/common",
|
||||
"//:node_modules/@angular/compiler",
|
||||
"//:node_modules/@angular/compiler-cli",
|
||||
@ -108,23 +121,10 @@ ts_project(
|
||||
"//:node_modules/https-proxy-agent",
|
||||
"//:node_modules/istanbul-lib-instrument",
|
||||
"//:node_modules/karma",
|
||||
"//:node_modules/less",
|
||||
"//:node_modules/listr2",
|
||||
"//:node_modules/lmdb",
|
||||
"//:node_modules/magic-string",
|
||||
"//:node_modules/mrmime",
|
||||
"//:node_modules/ng-packagr",
|
||||
"//:node_modules/parse5-html-rewriting-stream",
|
||||
"//:node_modules/piscina",
|
||||
"//:node_modules/postcss",
|
||||
"//:node_modules/rollup",
|
||||
"//:node_modules/sass",
|
||||
"//:node_modules/semver",
|
||||
"//:node_modules/source-map-support",
|
||||
"//:node_modules/tinyglobby",
|
||||
"//:node_modules/tslib",
|
||||
"//:node_modules/typescript",
|
||||
"//:node_modules/watchpack",
|
||||
],
|
||||
)
|
||||
|
||||
@ -204,7 +204,7 @@ ts_project(
|
||||
"//:node_modules/@angular/platform-browser",
|
||||
"//:node_modules/@angular/platform-browser-dynamic",
|
||||
"//:node_modules/@angular/router",
|
||||
"//:node_modules/ng-packagr",
|
||||
":node_modules/ng-packagr",
|
||||
"//:node_modules/rxjs",
|
||||
"//:node_modules/tslib",
|
||||
"//:node_modules/typescript",
|
||||
|
@ -51,7 +51,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/ssr": "workspace:*",
|
||||
"@angular-devkit/core": "workspace:*"
|
||||
"@angular-devkit/core": "workspace:*",
|
||||
"less": "4.2.2",
|
||||
"ng-packagr": "20.0.0-next.1",
|
||||
"postcss": "8.5.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP",
|
||||
|
@ -162,7 +162,7 @@ describeServeBuilder(
|
||||
// See: https://github.com/angular/angular-cli/pull/17624
|
||||
// eslint-disable-next-line max-len
|
||||
// executablePath: '/Users/<USERNAME>/git/angular-cli/node_modules/puppeteer/.local-chromium/mac-818858/chrome-mac/Chromium.app/Contents/MacOS/Chromium',
|
||||
ignoreHTTPSErrors: true,
|
||||
acceptInsecureCerts: true,
|
||||
args: ['--no-sandbox', '--disable-gpu'],
|
||||
});
|
||||
});
|
||||
|
@ -36,8 +36,8 @@ ts_project(
|
||||
deps = [
|
||||
":node_modules/@angular-devkit/schematics",
|
||||
":node_modules/@schematics/angular",
|
||||
":node_modules/parse5-html-rewriting-stream",
|
||||
"//:node_modules/@types/node",
|
||||
"//:node_modules/parse5-html-rewriting-stream",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -14,8 +14,9 @@ export { createRequestHandler, type RequestHandlerFunction } from './src/handler
|
||||
export {
|
||||
PrerenderFallback,
|
||||
type ServerRoute,
|
||||
provideServerRouting,
|
||||
provideServerRendering,
|
||||
withAppShell,
|
||||
withRoutes,
|
||||
RenderMode,
|
||||
type ServerRouteClient,
|
||||
type ServerRoutePrerender,
|
||||
|
@ -11,8 +11,11 @@ import {
|
||||
InjectionToken,
|
||||
Provider,
|
||||
Type,
|
||||
inject,
|
||||
makeEnvironmentProviders,
|
||||
provideEnvironmentInitializer,
|
||||
} from '@angular/core';
|
||||
import { provideServerRendering as provideServerRenderingPlatformServer } from '@angular/platform-server';
|
||||
import { type DefaultExport, ROUTES, type Route } from '@angular/router';
|
||||
|
||||
/**
|
||||
@ -22,25 +25,26 @@ import { type DefaultExport, ROUTES, type Route } from '@angular/router';
|
||||
const APP_SHELL_ROUTE = 'ng-app-shell';
|
||||
|
||||
/**
|
||||
* Identifies a particular kind of `ServerRoutesFeatureKind`.
|
||||
* @see {@link ServerRoutesFeature}
|
||||
* Identifies a particular kind of `ServerRenderingFeatureKind`.
|
||||
* @see {@link ServerRenderingFeature}
|
||||
*/
|
||||
enum ServerRoutesFeatureKind {
|
||||
enum ServerRenderingFeatureKind {
|
||||
AppShell,
|
||||
ServerRoutes,
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper type to represent a server routes feature.
|
||||
* @see {@link ServerRoutesFeatureKind}
|
||||
* @see {@link ServerRenderingFeatureKind}
|
||||
*/
|
||||
interface ServerRoutesFeature<FeatureKind extends ServerRoutesFeatureKind> {
|
||||
interface ServerRenderingFeature<FeatureKind extends ServerRenderingFeatureKind> {
|
||||
ɵkind: FeatureKind;
|
||||
ɵproviders: Provider[];
|
||||
ɵproviders: (Provider | EnvironmentProviders)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Different rendering modes for server routes.
|
||||
* @see {@link provideServerRouting}
|
||||
* @see {@link withRoutes}
|
||||
* @see {@link ServerRoute}
|
||||
*/
|
||||
export enum RenderMode {
|
||||
@ -171,7 +175,7 @@ export interface ServerRouteServer extends ServerRouteCommon {
|
||||
|
||||
/**
|
||||
* Server route configuration.
|
||||
* @see {@link provideServerRouting}
|
||||
* @see {@link withRoutes}
|
||||
*/
|
||||
export type ServerRoute =
|
||||
| ServerRouteClient
|
||||
@ -200,62 +204,103 @@ export interface ServerRoutesConfig {
|
||||
export const SERVER_ROUTES_CONFIG = new InjectionToken<ServerRoutesConfig>('SERVER_ROUTES_CONFIG');
|
||||
|
||||
/**
|
||||
* Sets up the necessary providers for configuring server routes.
|
||||
* This function accepts an array of server routes and optional configuration
|
||||
* options, returning an `EnvironmentProviders` object that encapsulates
|
||||
* the server routes and configuration settings.
|
||||
* Configures server-side routing for the application.
|
||||
*
|
||||
* @param routes - An array of server routes to be provided.
|
||||
* @param features - (Optional) server routes features.
|
||||
* @returns An `EnvironmentProviders` instance with the server routes configuration.
|
||||
* This function registers an array of `ServerRoute` definitions, enabling server-side rendering
|
||||
* for specific URL paths. These routes are used to pre-render content on the server, improving
|
||||
* initial load performance and SEO.
|
||||
*
|
||||
* @param routes - An array of `ServerRoute` objects, each defining a server-rendered route.
|
||||
* @returns A `ServerRenderingFeature` object configuring server-side routes.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { provideServerRendering, withRoutes, ServerRoute, RenderMode } from '@angular/ssr';
|
||||
*
|
||||
* const serverRoutes: ServerRoute[] = [
|
||||
* {
|
||||
* route: '', // This renders the "/" route on the client (CSR)
|
||||
* renderMode: RenderMode.Client,
|
||||
* },
|
||||
* {
|
||||
* route: 'about', // This page is static, so we prerender it (SSG)
|
||||
* renderMode: RenderMode.Prerender,
|
||||
* },
|
||||
* {
|
||||
* route: 'profile', // This page requires user-specific data, so we use SSR
|
||||
* renderMode: RenderMode.Server,
|
||||
* },
|
||||
* {
|
||||
* route: '**', // All other routes will be rendered on the server (SSR)
|
||||
* renderMode: RenderMode.Server,
|
||||
* },
|
||||
* ];
|
||||
*
|
||||
* provideServerRendering(withRoutes(serverRoutes));
|
||||
* ```
|
||||
*
|
||||
* @see {@link provideServerRendering}
|
||||
* @see {@link ServerRoute}
|
||||
* @see {@link withAppShell}
|
||||
*/
|
||||
export function provideServerRouting(
|
||||
export function withRoutes(
|
||||
routes: ServerRoute[],
|
||||
...features: ServerRoutesFeature<ServerRoutesFeatureKind>[]
|
||||
): EnvironmentProviders {
|
||||
): ServerRenderingFeature<ServerRenderingFeatureKind.ServerRoutes> {
|
||||
const config: ServerRoutesConfig = { routes };
|
||||
const hasAppShell = features.some((f) => f.ɵkind === ServerRoutesFeatureKind.AppShell);
|
||||
if (hasAppShell) {
|
||||
config.appShellRoute = APP_SHELL_ROUTE;
|
||||
}
|
||||
|
||||
const providers: Provider[] = [
|
||||
{
|
||||
provide: SERVER_ROUTES_CONFIG,
|
||||
useValue: config,
|
||||
},
|
||||
];
|
||||
|
||||
for (const feature of features) {
|
||||
providers.push(...feature.ɵproviders);
|
||||
}
|
||||
|
||||
return makeEnvironmentProviders(providers);
|
||||
return {
|
||||
ɵkind: ServerRenderingFeatureKind.ServerRoutes,
|
||||
ɵproviders: [
|
||||
{
|
||||
provide: SERVER_ROUTES_CONFIG,
|
||||
useValue: config,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the app shell route with the provided component.
|
||||
* Configures the shell of the application.
|
||||
*
|
||||
* The app shell serves as the main entry point for the application and is commonly used
|
||||
* to enable server-side rendering (SSR) of the application shell. It handles requests
|
||||
* that do not match any specific server route, providing a fallback mechanism and improving
|
||||
* perceived performance during navigation.
|
||||
* The app shell is a minimal, static HTML page that is served immediately, while the
|
||||
* full Angular application loads in the background. This improves perceived performance
|
||||
* by providing instant feedback to the user.
|
||||
*
|
||||
* This configuration is particularly useful in applications leveraging Progressive Web App (PWA)
|
||||
* patterns, such as service workers, to deliver a seamless user experience.
|
||||
* This function configures the app shell route, which serves the provided component for
|
||||
* requests that do not match any defined server routes.
|
||||
*
|
||||
* @param component The Angular component to render for the app shell route.
|
||||
* @returns A server routes feature configuration for the app shell.
|
||||
* @param component - The Angular component to render for the app shell. Can be a direct
|
||||
* component type or a dynamic import function.
|
||||
* @returns A `ServerRenderingFeature` object configuring the app shell.
|
||||
*
|
||||
* @see {@link provideServerRouting}
|
||||
* @example
|
||||
* ```ts
|
||||
* import { provideServerRendering, withAppShell, withRoutes } from '@angular/ssr';
|
||||
* import { AppShellComponent } from './app-shell.component';
|
||||
*
|
||||
* provideServerRendering(
|
||||
* withRoutes(serverRoutes),
|
||||
* withAppShell(AppShellComponent)
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { provideServerRendering, withAppShell, withRoutes } from '@angular/ssr';
|
||||
*
|
||||
* provideServerRendering(
|
||||
* withRoutes(serverRoutes),
|
||||
* withAppShell(() =>
|
||||
* import('./app-shell.component').then((m) => m.AppShellComponent)
|
||||
* )
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @see {@link provideServerRendering}
|
||||
* @see {@link https://angular.dev/ecosystem/service-workers/app-shell | App shell pattern on Angular.dev}
|
||||
*/
|
||||
export function withAppShell(
|
||||
component: Type<unknown> | (() => Promise<Type<unknown> | DefaultExport<Type<unknown>>>),
|
||||
): ServerRoutesFeature<ServerRoutesFeatureKind.AppShell> {
|
||||
): ServerRenderingFeature<ServerRenderingFeatureKind.AppShell> {
|
||||
const routeConfig: Route = {
|
||||
path: APP_SHELL_ROUTE,
|
||||
};
|
||||
@ -267,13 +312,73 @@ export function withAppShell(
|
||||
}
|
||||
|
||||
return {
|
||||
ɵkind: ServerRoutesFeatureKind.AppShell,
|
||||
ɵkind: ServerRenderingFeatureKind.AppShell,
|
||||
ɵproviders: [
|
||||
{
|
||||
provide: ROUTES,
|
||||
useValue: routeConfig,
|
||||
multi: true,
|
||||
},
|
||||
provideEnvironmentInitializer(() => {
|
||||
const config = inject(SERVER_ROUTES_CONFIG);
|
||||
config.appShellRoute = APP_SHELL_ROUTE;
|
||||
}),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures server-side rendering for an Angular application.
|
||||
*
|
||||
* This function sets up the necessary providers for server-side rendering, including
|
||||
* support for server routes and app shell. It combines features configured using
|
||||
* `withRoutes` and `withAppShell` to provide a comprehensive server-side rendering setup.
|
||||
*
|
||||
* @param features - Optional features to configure additional server rendering behaviors.
|
||||
* @returns An `EnvironmentProviders` instance with the server-side rendering configuration.
|
||||
*
|
||||
* @example
|
||||
* Basic example of how you can enable server-side rendering in your application
|
||||
* when using the `bootstrapApplication` function:
|
||||
*
|
||||
* ```ts
|
||||
* import { bootstrapApplication } from '@angular/platform-browser';
|
||||
* import { provideServerRendering, withRoutes, withAppShell } from '@angular/ssr';
|
||||
* import { AppComponent } from './app/app.component';
|
||||
* import { SERVER_ROUTES } from './app/app.server.routes';
|
||||
* import { AppShellComponent } from './app/app-shell.component';
|
||||
*
|
||||
* bootstrapApplication(AppComponent, {
|
||||
* providers: [
|
||||
* provideServerRendering(
|
||||
* withRoutes(SERVER_ROUTES),
|
||||
* withAppShell(AppShellComponent)
|
||||
* )
|
||||
* ]
|
||||
* });
|
||||
* ```
|
||||
* @see {@link withRoutes} configures server-side routing
|
||||
* @see {@link withAppShell} configures the application shell
|
||||
*/
|
||||
export function provideServerRendering(
|
||||
...features: ServerRenderingFeature<ServerRenderingFeatureKind>[]
|
||||
): EnvironmentProviders {
|
||||
let hasAppShell = false;
|
||||
let hasServerRoutes = false;
|
||||
const providers: (Provider | EnvironmentProviders)[] = [provideServerRenderingPlatformServer()];
|
||||
|
||||
for (const { ɵkind, ɵproviders } of features) {
|
||||
hasAppShell ||= ɵkind === ServerRenderingFeatureKind.AppShell;
|
||||
hasServerRoutes ||= ɵkind === ServerRenderingFeatureKind.ServerRoutes;
|
||||
providers.push(...ɵproviders);
|
||||
}
|
||||
|
||||
if (!hasServerRoutes && hasAppShell) {
|
||||
throw new Error(
|
||||
`Configuration error: found 'withAppShell()' without 'withRoutes()' in the same call to 'provideServerRendering()'.` +
|
||||
`The 'withAppShell()' function requires 'withRoutes()' to be used.`,
|
||||
);
|
||||
}
|
||||
|
||||
return makeEnvironmentProviders(providers);
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ ts_project(
|
||||
"//:node_modules/@angular/compiler",
|
||||
"//:node_modules/@angular/core",
|
||||
"//:node_modules/@angular/platform-browser",
|
||||
"//:node_modules/@angular/platform-server",
|
||||
"//:node_modules/@angular/router",
|
||||
"//:node_modules/@types/node",
|
||||
"//packages/angular/ssr",
|
||||
|
@ -24,12 +24,6 @@ const CRITTERS_ACTUAL_LICENSE_FILE_PATH = join(
|
||||
'third_party/beasties/THIRD_PARTY_LICENSES.txt',
|
||||
);
|
||||
|
||||
/**
|
||||
* Path to the golden reference license file for the Beasties library.
|
||||
* This file is used as a reference for comparison and is located in the same directory as this script.
|
||||
*/
|
||||
const CRITTERS_GOLDEN_LICENSE_FILE_PATH = join(__dirname, 'THIRD_PARTY_LICENSES.txt.golden');
|
||||
|
||||
describe('NPM Package Tests', () => {
|
||||
it('should not include the contents of third_party/beasties/index.js in the FESM bundle', async () => {
|
||||
const fesmFilePath = join(ANGULAR_SSR_PACKAGE_PATH, 'fesm2022/ssr.mjs');
|
||||
|
@ -14,11 +14,10 @@ import {
|
||||
provideExperimentalZonelessChangeDetection,
|
||||
} from '@angular/core';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { provideServerRendering } from '@angular/platform-server';
|
||||
import { RouterOutlet, Routes, provideRouter } from '@angular/router';
|
||||
import { destroyAngularServerApp } from '../src/app';
|
||||
import { ServerAsset, setAngularAppManifest } from '../src/manifest';
|
||||
import { ServerRoute, provideServerRouting } from '../src/routes/route-config';
|
||||
import { ServerRoute, provideServerRendering, withRoutes } from '../src/routes/route-config';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@ -94,10 +93,9 @@ export function setAngularAppTestingManifest(
|
||||
bootstrap: async () => () => {
|
||||
return bootstrapApplication(rootComponent, {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
provideExperimentalZonelessChangeDetection(),
|
||||
provideRouter(routes),
|
||||
provideServerRouting(serverRoutes),
|
||||
provideServerRendering(withRoutes(serverRoutes)),
|
||||
...extraProviders,
|
||||
],
|
||||
});
|
||||
|
@ -129,6 +129,7 @@ ts_project(
|
||||
data = RUNTIME_ASSETS,
|
||||
module_name = "@angular-devkit/build-angular",
|
||||
deps = [
|
||||
":node_modules/@ampproject/remapping",
|
||||
":node_modules/@angular-devkit/architect",
|
||||
":node_modules/@angular-devkit/build-webpack",
|
||||
":node_modules/@angular-devkit/core",
|
||||
@ -151,17 +152,21 @@ ts_project(
|
||||
":node_modules/license-webpack-plugin",
|
||||
":node_modules/loader-utils",
|
||||
":node_modules/mini-css-extract-plugin",
|
||||
":node_modules/ng-packagr",
|
||||
":node_modules/piscina",
|
||||
":node_modules/postcss",
|
||||
":node_modules/postcss-loader",
|
||||
":node_modules/resolve-url-loader",
|
||||
":node_modules/sass",
|
||||
":node_modules/sass-loader",
|
||||
":node_modules/source-map-loader",
|
||||
":node_modules/source-map-support",
|
||||
":node_modules/terser",
|
||||
":node_modules/webpack",
|
||||
":node_modules/webpack-dev-middleware",
|
||||
":node_modules/webpack-dev-server",
|
||||
":node_modules/webpack-merge",
|
||||
":node_modules/webpack-subresource-integrity",
|
||||
"//:node_modules/@ampproject/remapping",
|
||||
"//:node_modules/@angular/common",
|
||||
"//:node_modules/@angular/compiler-cli",
|
||||
"//:node_modules/@angular/core",
|
||||
@ -193,15 +198,10 @@ ts_project(
|
||||
"//:node_modules/istanbul-lib-instrument",
|
||||
"//:node_modules/karma",
|
||||
"//:node_modules/karma-source-map-support",
|
||||
"//:node_modules/ng-packagr",
|
||||
"//:node_modules/open",
|
||||
"//:node_modules/ora",
|
||||
"//:node_modules/piscina",
|
||||
"//:node_modules/postcss",
|
||||
"//:node_modules/rxjs",
|
||||
"//:node_modules/sass",
|
||||
"//:node_modules/semver",
|
||||
"//:node_modules/source-map-support",
|
||||
"//:node_modules/tree-kill",
|
||||
"//:node_modules/tslib",
|
||||
"//:node_modules/typescript",
|
||||
|
@ -66,8 +66,9 @@
|
||||
"esbuild": "0.25.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"undici": "7.5.0",
|
||||
"@angular/ssr": "workspace:*"
|
||||
"@angular/ssr": "workspace:*",
|
||||
"ng-packagr": "20.0.0-next.1",
|
||||
"undici": "7.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler-cli": "0.0.0-ANGULAR-FW-PEER-DEP",
|
||||
|
@ -162,7 +162,7 @@ describeServeBuilder(
|
||||
// See: https://github.com/angular/angular-cli/pull/17624
|
||||
// eslint-disable-next-line max-len
|
||||
// executablePath: '/Users/<USERNAME>/git/angular-cli/node_modules/puppeteer/.local-chromium/mac-818858/chrome-mac/Chromium.app/Contents/MacOS/Chromium',
|
||||
ignoreHTTPSErrors: true,
|
||||
acceptInsecureCerts: true,
|
||||
args: ['--no-sandbox', '--disable-gpu'],
|
||||
});
|
||||
});
|
||||
|
@ -29,8 +29,8 @@ ts_project(
|
||||
deps = [
|
||||
":node_modules/@angular-devkit/core",
|
||||
":node_modules/jsonc-parser",
|
||||
":node_modules/magic-string",
|
||||
"//:node_modules/@types/node",
|
||||
"//:node_modules/magic-string",
|
||||
"//:node_modules/rxjs",
|
||||
],
|
||||
)
|
||||
|
@ -300,12 +300,12 @@ function addServerRoutingConfig(options: AppShellOptions, isStandalone: boolean)
|
||||
/** max */ undefined,
|
||||
/** recursive */ true,
|
||||
).find(
|
||||
(n) => ts.isIdentifier(n.expression) && n.expression.getText() === 'provideServerRouting',
|
||||
(n) => ts.isIdentifier(n.expression) && n.expression.getText() === 'provideServerRendering',
|
||||
);
|
||||
|
||||
if (!functionCall) {
|
||||
throw new SchematicsException(
|
||||
`Cannot find the "provideServerRouting" function call in "${configFilePath}".`,
|
||||
`Cannot find the "provideServerRendering" function call in "${configFilePath}".`,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -123,11 +123,11 @@ describe('App Shell Schematic', () => {
|
||||
expect(content).toMatch(/app-shell/);
|
||||
});
|
||||
|
||||
it(`should update the 'provideServerRouting' call to include 'withAppShell'`, async () => {
|
||||
it(`should update the 'provideServerRendering' call to include 'withAppShell'`, async () => {
|
||||
const tree = await schematicRunner.runSchematic('app-shell', defaultOptions, appTree);
|
||||
const content = tree.readContent('/projects/bar/src/app/app.config.server.ts');
|
||||
expect(tags.oneLine`${content}`).toContain(
|
||||
tags.oneLine`provideServerRouting(serverRoutes, withAppShell(AppShell))`,
|
||||
tags.oneLine`provideServerRendering(withRoutes(serverRoutes), withAppShell(AppShell))`,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -2,6 +2,5 @@
|
||||
* Public API Surface of <%= dasherize(name) %>
|
||||
*/
|
||||
|
||||
export * from './lib/<%= dasherize(name) %>.service';
|
||||
export * from './lib/<%= dasherize(name) %>';<% if (!standalone) { %>
|
||||
export * from './lib/<%= dasherize(name) %>.module';<% } %>
|
||||
|
@ -185,12 +185,6 @@ export default function (options: LibraryOptions): Rule {
|
||||
standalone: options.standalone,
|
||||
project: packageName,
|
||||
}),
|
||||
schematic('service', {
|
||||
name: options.name,
|
||||
flat: true,
|
||||
path: sourceDir,
|
||||
project: packageName,
|
||||
}),
|
||||
(_tree: Tree, context: SchematicContext) => {
|
||||
if (!options.skipPackageJson && !options.skipInstall) {
|
||||
context.addTask(new NodePackageInstallTask());
|
||||
|
@ -57,8 +57,6 @@ describe('Library Schematic', () => {
|
||||
'/projects/foo/src/my-index.ts',
|
||||
'/projects/foo/src/lib/foo.spec.ts',
|
||||
'/projects/foo/src/lib/foo.ts',
|
||||
'/projects/foo/src/lib/foo.service.spec.ts',
|
||||
'/projects/foo/src/lib/foo.service.ts',
|
||||
]),
|
||||
);
|
||||
});
|
||||
@ -102,8 +100,6 @@ describe('Library Schematic', () => {
|
||||
'/some/other/directory/bar/src/my-index.ts',
|
||||
'/some/other/directory/bar/src/lib/foo.spec.ts',
|
||||
'/some/other/directory/bar/src/lib/foo.ts',
|
||||
'/some/other/directory/bar/src/lib/foo.service.spec.ts',
|
||||
'/some/other/directory/bar/src/lib/foo.service.ts',
|
||||
]),
|
||||
);
|
||||
});
|
||||
@ -207,10 +203,8 @@ describe('Library Schematic', () => {
|
||||
const project = config.projects.pascalCasedName;
|
||||
expect(project).toBeDefined();
|
||||
expect(project.root).toEqual('projects/pascal-cased-name');
|
||||
const svcContent = tree.readContent(
|
||||
'/projects/pascal-cased-name/src/lib/pascal-cased-name.service.ts',
|
||||
);
|
||||
expect(svcContent).toMatch(/providedIn: 'root'/);
|
||||
const svcContent = tree.readContent('/projects/pascal-cased-name/src/lib/pascal-cased-name.ts');
|
||||
expect(svcContent).toContain('@Component');
|
||||
});
|
||||
|
||||
describe(`update package.json`, () => {
|
||||
@ -320,7 +314,6 @@ describe('Library Schematic', () => {
|
||||
|
||||
const pkgJsonPath = '/projects/myscope/mylib/package.json';
|
||||
expect(tree.files).toContain(pkgJsonPath);
|
||||
expect(tree.files).toContain('/projects/myscope/mylib/src/lib/mylib.service.ts');
|
||||
expect(tree.files).toContain('/projects/myscope/mylib/src/lib/mylib.ts');
|
||||
|
||||
const pkgJson = JSON.parse(tree.readContent(pkgJsonPath));
|
||||
@ -431,8 +424,6 @@ describe('Library Schematic', () => {
|
||||
'/projects/foo/src/lib/foo.module.ts',
|
||||
'/projects/foo/src/lib/foo.spec.ts',
|
||||
'/projects/foo/src/lib/foo.ts',
|
||||
'/projects/foo/src/lib/foo.service.spec.ts',
|
||||
'/projects/foo/src/lib/foo.service.ts',
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
@ -1,5 +1,15 @@
|
||||
{
|
||||
"schematics": {
|
||||
"replace-provide-server-rendering-import": {
|
||||
"version": "20.0.0",
|
||||
"factory": "./replace-provide-server-rendering-import/migration",
|
||||
"description": "Migrate imports of 'provideServerRendering' from '@angular/platform-server' to '@angular/ssr'."
|
||||
},
|
||||
"replace-provide-server-routing": {
|
||||
"version": "20.0.0",
|
||||
"factory": "./replace-provide-server-routing/migration",
|
||||
"description": "Migrate 'provideServerRendering' to use 'withRoutes' and remove 'provideServerRouting' from '@angular/ssr'."
|
||||
},
|
||||
"use-application-builder": {
|
||||
"version": "20.0.0",
|
||||
"factory": "./use-application-builder/migration",
|
||||
|
110
packages/schematics/angular/migrations/replace-provide-server-rendering-import/migration.ts
Normal file
110
packages/schematics/angular/migrations/replace-provide-server-rendering-import/migration.ts
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import { DirEntry, Rule } from '@angular-devkit/schematics';
|
||||
import * as ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
||||
import { NodeDependencyType, addPackageJsonDependency } from '../../utility/dependencies';
|
||||
import { latestVersions } from '../../utility/latest-versions';
|
||||
|
||||
function* visit(directory: DirEntry): IterableIterator<[fileName: string, contents: string]> {
|
||||
for (const path of directory.subfiles) {
|
||||
if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
|
||||
const entry = directory.file(path);
|
||||
if (entry) {
|
||||
const content = entry.content;
|
||||
if (
|
||||
content.includes('provideServerRendering') &&
|
||||
content.includes('@angular/platform-server')
|
||||
) {
|
||||
// Only need to rename the import so we can just string replacements.
|
||||
yield [entry.path, content.toString()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const path of directory.subdirs) {
|
||||
if (path === 'node_modules' || path.startsWith('.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield* visit(directory.dir(path));
|
||||
}
|
||||
}
|
||||
|
||||
export default function (): Rule {
|
||||
return async (tree) => {
|
||||
addPackageJsonDependency(tree, {
|
||||
name: '@angular/ssr',
|
||||
version: latestVersions.AngularSSR,
|
||||
type: NodeDependencyType.Default,
|
||||
overwrite: false,
|
||||
});
|
||||
|
||||
for (const [filePath, content] of visit(tree.root)) {
|
||||
let updatedContent = content;
|
||||
const ssrImports = new Set<string>();
|
||||
const platformServerImports = new Set<string>();
|
||||
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
||||
|
||||
sourceFile.forEachChild((node) => {
|
||||
if (ts.isImportDeclaration(node)) {
|
||||
const moduleSpecifier = node.moduleSpecifier.getText(sourceFile);
|
||||
if (moduleSpecifier.includes('@angular/platform-server')) {
|
||||
const importClause = node.importClause;
|
||||
if (
|
||||
importClause &&
|
||||
importClause.namedBindings &&
|
||||
ts.isNamedImports(importClause.namedBindings)
|
||||
) {
|
||||
const namedImports = importClause.namedBindings.elements.map((e) =>
|
||||
e.getText(sourceFile),
|
||||
);
|
||||
namedImports.forEach((importName) => {
|
||||
if (importName === 'provideServerRendering') {
|
||||
ssrImports.add(importName);
|
||||
} else {
|
||||
platformServerImports.add(importName);
|
||||
}
|
||||
});
|
||||
}
|
||||
updatedContent = updatedContent.replace(node.getFullText(sourceFile), '');
|
||||
} else if (moduleSpecifier.includes('@angular/ssr')) {
|
||||
const importClause = node.importClause;
|
||||
if (
|
||||
importClause &&
|
||||
importClause.namedBindings &&
|
||||
ts.isNamedImports(importClause.namedBindings)
|
||||
) {
|
||||
importClause.namedBindings.elements.forEach((e) => {
|
||||
ssrImports.add(e.getText(sourceFile));
|
||||
});
|
||||
}
|
||||
updatedContent = updatedContent.replace(node.getFullText(sourceFile), '');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (platformServerImports.size > 0) {
|
||||
updatedContent =
|
||||
`import { ${Array.from(platformServerImports).sort().join(', ')} } from '@angular/platform-server';\n` +
|
||||
updatedContent;
|
||||
}
|
||||
|
||||
if (ssrImports.size > 0) {
|
||||
updatedContent =
|
||||
`import { ${Array.from(ssrImports).sort().join(', ')} } from '@angular/ssr';\n` +
|
||||
updatedContent;
|
||||
}
|
||||
|
||||
if (content !== updatedContent) {
|
||||
tree.overwrite(filePath, updatedContent);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
75
packages/schematics/angular/migrations/replace-provide-server-rendering-import/migration_spec.ts
Normal file
75
packages/schematics/angular/migrations/replace-provide-server-rendering-import/migration_spec.ts
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import { EmptyTree } from '@angular-devkit/schematics';
|
||||
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
|
||||
|
||||
describe(`Migration to use the 'provideServerRendering' from '@angular/ssr'`, () => {
|
||||
const schematicRunner = new SchematicTestRunner(
|
||||
'migrations',
|
||||
require.resolve('../migration-collection.json'),
|
||||
);
|
||||
|
||||
let tree: UnitTestTree;
|
||||
const schematicName = 'replace-provide-server-rendering-import';
|
||||
|
||||
beforeEach(() => {
|
||||
tree = new UnitTestTree(new EmptyTree());
|
||||
tree.create(
|
||||
'/package.json',
|
||||
JSON.stringify({
|
||||
dependencies: {
|
||||
'@angular/ssr': '0.0.0',
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should replace provideServerRendering with @angular/ssr and keep other imports', async () => {
|
||||
tree.create(
|
||||
'test.ts',
|
||||
`import { provideServerRendering, otherFunction } from '@angular/platform-server';`,
|
||||
);
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('test.ts');
|
||||
expect(content).toContain("import { provideServerRendering } from '@angular/ssr';");
|
||||
expect(content).toContain("import { otherFunction } from '@angular/platform-server';");
|
||||
});
|
||||
|
||||
it('should not replace provideServerRendering that is imported from @angular/ssr', async () => {
|
||||
tree.create(
|
||||
'test.ts',
|
||||
`
|
||||
import { otherFunction } from '@angular/platform-server';
|
||||
import { provideServerRendering, provideServerRouting } from '@angular/ssr';
|
||||
`,
|
||||
);
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('test.ts');
|
||||
expect(content).toContain(
|
||||
"import { provideServerRendering, provideServerRouting } from '@angular/ssr';",
|
||||
);
|
||||
expect(content).toContain("import { otherFunction } from '@angular/platform-server';");
|
||||
});
|
||||
|
||||
it('should merge with existing @angular/ssr imports', async () => {
|
||||
tree.create(
|
||||
'test.ts',
|
||||
`
|
||||
import { provideServerRouting } from '@angular/ssr';
|
||||
import { provideServerRendering } from '@angular/platform-server';
|
||||
`,
|
||||
);
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('test.ts');
|
||||
expect(content).toContain(
|
||||
"import { provideServerRendering, provideServerRouting } from '@angular/ssr';",
|
||||
);
|
||||
expect(content.match(/@angular\/ssr/g) || []).toHaveSize(1);
|
||||
});
|
||||
});
|
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import { DirEntry, Rule } from '@angular-devkit/schematics';
|
||||
import * as ts from '../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
||||
import { getPackageJsonDependency } from '../../utility/dependencies';
|
||||
|
||||
function* visit(directory: DirEntry): IterableIterator<[fileName: string, contents: string]> {
|
||||
for (const path of directory.subfiles) {
|
||||
if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
|
||||
const entry = directory.file(path);
|
||||
if (entry) {
|
||||
const content = entry.content;
|
||||
if (content.includes('provideServerRouting') && content.includes('@angular/ssr')) {
|
||||
// Only need to rename the import so we can just string replacements.
|
||||
yield [entry.path, content.toString()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const path of directory.subdirs) {
|
||||
if (path === 'node_modules' || path.startsWith('.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
yield* visit(directory.dir(path));
|
||||
}
|
||||
}
|
||||
|
||||
export default function (): Rule {
|
||||
return async (tree) => {
|
||||
if (!getPackageJsonDependency(tree, '@angular/ssr')) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [filePath, content] of visit(tree.root)) {
|
||||
const recorder = tree.beginUpdate(filePath);
|
||||
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
||||
|
||||
function visit(node: ts.Node) {
|
||||
if (
|
||||
ts.isPropertyAssignment(node) &&
|
||||
ts.isIdentifier(node.name) &&
|
||||
node.name.text === 'providers' &&
|
||||
ts.isArrayLiteralExpression(node.initializer)
|
||||
) {
|
||||
const providersArray = node.initializer;
|
||||
const newProviders = providersArray.elements
|
||||
.filter((el) => {
|
||||
return !(
|
||||
ts.isCallExpression(el) &&
|
||||
ts.isIdentifier(el.expression) &&
|
||||
el.expression.text === 'provideServerRendering'
|
||||
);
|
||||
})
|
||||
.map((el) => {
|
||||
if (
|
||||
ts.isCallExpression(el) &&
|
||||
ts.isIdentifier(el.expression) &&
|
||||
el.expression.text === 'provideServerRouting'
|
||||
) {
|
||||
const [withRouteVal, ...others] = el.arguments.map((arg) => arg.getText());
|
||||
|
||||
return `provideServerRendering(withRoutes(${withRouteVal})${others.length ? ', ' + others.join(', ') : ''})`;
|
||||
}
|
||||
|
||||
return el.getText();
|
||||
});
|
||||
|
||||
// Update the 'providers' array in the source file
|
||||
recorder.remove(providersArray.getStart(), providersArray.getWidth());
|
||||
recorder.insertRight(providersArray.getStart(), `[${newProviders.join(', ')}]`);
|
||||
}
|
||||
|
||||
ts.forEachChild(node, visit);
|
||||
}
|
||||
|
||||
// Visit all nodes to update 'providers'
|
||||
visit(sourceFile);
|
||||
|
||||
// Update imports by removing 'provideServerRouting'
|
||||
const importDecl = sourceFile.statements.find(
|
||||
(stmt) =>
|
||||
ts.isImportDeclaration(stmt) &&
|
||||
ts.isStringLiteral(stmt.moduleSpecifier) &&
|
||||
stmt.moduleSpecifier.text === '@angular/ssr',
|
||||
) as ts.ImportDeclaration | undefined;
|
||||
|
||||
if (importDecl?.importClause?.namedBindings) {
|
||||
const namedBindings = importDecl?.importClause.namedBindings;
|
||||
|
||||
if (ts.isNamedImports(namedBindings)) {
|
||||
const elements = namedBindings.elements;
|
||||
const updatedElements = elements
|
||||
.map((el) => el.getText())
|
||||
.filter((x) => x !== 'provideServerRouting');
|
||||
|
||||
updatedElements.push('withRoutes');
|
||||
|
||||
recorder.remove(namedBindings.getStart(), namedBindings.getWidth());
|
||||
recorder.insertLeft(namedBindings.getStart(), `{ ${updatedElements.sort().join(', ')} }`);
|
||||
}
|
||||
}
|
||||
|
||||
tree.commitUpdate(recorder);
|
||||
}
|
||||
};
|
||||
}
|
89
packages/schematics/angular/migrations/replace-provide-server-routing/migration_spec.ts
Normal file
89
packages/schematics/angular/migrations/replace-provide-server-routing/migration_spec.ts
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import { EmptyTree } from '@angular-devkit/schematics';
|
||||
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
|
||||
|
||||
describe(`Migration to replace 'provideServerRouting' with 'provideServerRendering' from '@angular/ssr'`, () => {
|
||||
const schematicRunner = new SchematicTestRunner(
|
||||
'migrations',
|
||||
require.resolve('../migration-collection.json'),
|
||||
);
|
||||
|
||||
const schematicName = 'replace-provide-server-routing';
|
||||
let tree: UnitTestTree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tree = new UnitTestTree(new EmptyTree());
|
||||
tree.create(
|
||||
'/package.json',
|
||||
JSON.stringify({
|
||||
dependencies: {
|
||||
'@angular/ssr': '0.0.0',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
tree.create(
|
||||
'src/app/app.config.ts',
|
||||
`
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideServerRendering, provideServerRouting } from '@angular/ssr';
|
||||
import { serverRoutes } from './app.routes';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
provideServerRouting(serverRoutes)
|
||||
]
|
||||
};
|
||||
`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should add "withRoutes" to the import statement', async () => {
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('src/app/app.config.ts');
|
||||
|
||||
expect(content).toContain(`import { provideServerRendering, withRoutes } from '@angular/ssr';`);
|
||||
});
|
||||
|
||||
it('should remove "provideServerRouting" and update "provideServerRendering"', async () => {
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('src/app/app.config.ts');
|
||||
|
||||
expect(content).toContain(`providers: [provideServerRendering(withRoutes(serverRoutes))]`);
|
||||
expect(content).not.toContain(`provideServerRouting(serverRoutes)`);
|
||||
});
|
||||
|
||||
it('should correctly handle provideServerRouting with extra arguments', async () => {
|
||||
tree.overwrite(
|
||||
'src/app/app.config.ts',
|
||||
`
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideServerRendering, provideServerRouting } from '@angular/ssr';
|
||||
import { serverRoutes } from './app.routes';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
provideServerRouting(serverRoutes, withAppShell(AppShellComponent))
|
||||
]
|
||||
};
|
||||
`,
|
||||
);
|
||||
|
||||
const newTree = await schematicRunner.runSchematic(schematicName, {}, tree);
|
||||
const content = newTree.readContent('src/app/app.config.ts');
|
||||
|
||||
expect(content).toContain(
|
||||
`providers: [provideServerRendering(withRoutes(serverRoutes), withAppShell(AppShellComponent))]`,
|
||||
);
|
||||
expect(content).not.toContain(`provideServerRouting(serverRoutes)`);
|
||||
});
|
||||
});
|
@ -1,13 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { provideServerRouting } from '@angular/ssr';
|
||||
import { provideServerRendering, withRoutes } from '@angular/ssr';
|
||||
import { App } from './app';
|
||||
import { AppModule } from './app.module';
|
||||
import { serverRoutes } from './app.routes.server';
|
||||
|
||||
@NgModule({
|
||||
imports: [AppModule, ServerModule],
|
||||
providers: [provideServerRouting(serverRoutes)],
|
||||
imports: [AppModule],
|
||||
providers: [provideServerRendering(withRoutes(serverRoutes))],
|
||||
bootstrap: [App],
|
||||
})
|
||||
export class AppServerModule {}
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
|
||||
import { provideServerRendering } from '@angular/platform-server';
|
||||
import { provideServerRouting } from '@angular/ssr';
|
||||
import { provideServerRendering, withRoutes } from '@angular/ssr';
|
||||
import { appConfig } from './app.config';
|
||||
import { serverRoutes } from './app.routes.server';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
provideServerRendering(),
|
||||
provideServerRouting(serverRoutes)
|
||||
provideServerRendering(withRoutes(serverRoutes))
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core';
|
||||
import { provideServerRendering } from '@angular/platform-server';
|
||||
import { provideServerRendering } from '@angular/ssr';
|
||||
import { appConfig } from './app.config';
|
||||
|
||||
const serverConfig: ApplicationConfig = {
|
||||
|
16
packages/schematics/angular/service/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template
Normal file
16
packages/schematics/angular/service/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { <%= classify(name) %><%= classify(type) %> } from './<%= dasherize(name) %><%= type ? '.' + dasherize(type) : '' %>';
|
||||
|
||||
describe('<%= classify(name) %><%= classify(type) %>', () => {
|
||||
let service: <%= classify(name) %><%= classify(type) %>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(<%= classify(name) %><%= classify(type) %>);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class <%= classify(name) %>Service {
|
||||
export class <%= classify(name) %><%= classify(type) %> {
|
||||
|
||||
constructor() { }
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { <%= classify(name) %>Service } from './<%= dasherize(name) %>.service';
|
||||
|
||||
describe('<%= classify(name) %>Service', () => {
|
||||
let service: <%= classify(name) %>Service;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(<%= classify(name) %>Service);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@ -15,6 +15,9 @@ export default function (options: ServiceOptions): Rule {
|
||||
const flat = options.flat;
|
||||
options.flat = true;
|
||||
|
||||
// Schematic templates require a defined type value
|
||||
options.type ??= '';
|
||||
|
||||
return generateFromFiles(options, {
|
||||
'if-flat': (s: string) => (flat ? '' : s),
|
||||
});
|
||||
|
@ -46,15 +46,15 @@ describe('Service Schematic', () => {
|
||||
|
||||
const tree = await schematicRunner.runSchematic('service', options, appTree);
|
||||
const files = tree.files;
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.service.spec.ts');
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.service.ts');
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.spec.ts');
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.ts');
|
||||
});
|
||||
|
||||
it('service should be tree-shakeable', async () => {
|
||||
const options = { ...defaultOptions };
|
||||
|
||||
const tree = await schematicRunner.runSchematic('service', options, appTree);
|
||||
const content = tree.readContent('/projects/bar/src/app/foo/foo.service.ts');
|
||||
const content = tree.readContent('/projects/bar/src/app/foo/foo.ts');
|
||||
expect(content).toMatch(/providedIn: 'root'/);
|
||||
});
|
||||
|
||||
@ -63,8 +63,8 @@ describe('Service Schematic', () => {
|
||||
|
||||
const tree = await schematicRunner.runSchematic('service', options, appTree);
|
||||
const files = tree.files;
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.service.ts');
|
||||
expect(files).not.toContain('/projects/bar/src/app/foo/foo.service.spec.ts');
|
||||
expect(files).toContain('/projects/bar/src/app/foo/foo.ts');
|
||||
expect(files).not.toContain('/projects/bar/src/app/foo/foo.spec.ts');
|
||||
});
|
||||
|
||||
it('should respect the sourceRoot value', async () => {
|
||||
@ -72,6 +72,24 @@ describe('Service Schematic', () => {
|
||||
config.projects.bar.sourceRoot = 'projects/bar/custom';
|
||||
appTree.overwrite('/angular.json', JSON.stringify(config, null, 2));
|
||||
appTree = await schematicRunner.runSchematic('service', defaultOptions, appTree);
|
||||
expect(appTree.files).toContain('/projects/bar/custom/app/foo/foo.service.ts');
|
||||
expect(appTree.files).toContain('/projects/bar/custom/app/foo/foo.ts');
|
||||
});
|
||||
|
||||
it('should respect the type option', async () => {
|
||||
const options = { ...defaultOptions, type: 'Service' };
|
||||
const tree = await schematicRunner.runSchematic('service', options, appTree);
|
||||
const content = tree.readContent('/projects/bar/src/app/foo/foo.service.ts');
|
||||
const testContent = tree.readContent('/projects/bar/src/app/foo/foo.service.spec.ts');
|
||||
expect(content).toContain('export class FooService');
|
||||
expect(testContent).toContain("describe('FooService'");
|
||||
});
|
||||
|
||||
it('should allow empty string in the type option', async () => {
|
||||
const options = { ...defaultOptions, type: '' };
|
||||
const tree = await schematicRunner.runSchematic('service', options, appTree);
|
||||
const content = tree.readContent('/projects/bar/src/app/foo/foo.ts');
|
||||
const testContent = tree.readContent('/projects/bar/src/app/foo/foo.spec.ts');
|
||||
expect(content).toContain('export class Foo');
|
||||
expect(testContent).toContain("describe('Foo'");
|
||||
});
|
||||
});
|
||||
|
@ -39,6 +39,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Skip the generation of a unit test file `spec.ts` for the service.",
|
||||
"default": false
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Append a custom type to the service's filename. For example, if you set the type to `service`, the file will be named `my-service.service.ts`."
|
||||
}
|
||||
},
|
||||
"required": ["name", "project"]
|
||||
|
@ -7,12 +7,14 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
FileOperator,
|
||||
Rule,
|
||||
Tree,
|
||||
apply,
|
||||
applyTemplates,
|
||||
chain,
|
||||
filter,
|
||||
forEach,
|
||||
mergeWith,
|
||||
move,
|
||||
noop,
|
||||
@ -31,6 +33,7 @@ export interface GenerateFromFilesOptions {
|
||||
project: string;
|
||||
skipTests?: boolean;
|
||||
templateFilesDirectory?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export function generateFromFiles(
|
||||
@ -56,6 +59,16 @@ export function generateFromFiles(
|
||||
...options,
|
||||
...extraTemplateValues,
|
||||
}),
|
||||
!options.type
|
||||
? forEach(((file) => {
|
||||
return file.path.includes('..')
|
||||
? {
|
||||
content: file.content,
|
||||
path: file.path.replace('..', '.'),
|
||||
}
|
||||
: file;
|
||||
}) as FileOperator)
|
||||
: noop(),
|
||||
move(parsedPath.path + (options.flat ? '' : '/' + strings.dasherize(options.name))),
|
||||
]);
|
||||
|
||||
|
185
pnpm-lock.yaml
generated
185
pnpm-lock.yaml
generated
@ -14,9 +14,6 @@ importers:
|
||||
|
||||
.:
|
||||
devDependencies:
|
||||
'@ampproject/remapping':
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
'@angular/animations':
|
||||
specifier: 20.0.0-next.2
|
||||
version: 20.0.0-next.2(@angular/core@20.0.0-next.2)
|
||||
@ -278,27 +275,12 @@ importers:
|
||||
karma-source-map-support:
|
||||
specifier: 1.4.0
|
||||
version: 1.4.0
|
||||
less:
|
||||
specifier: 4.2.2
|
||||
version: 4.2.2
|
||||
listr2:
|
||||
specifier: 8.2.5
|
||||
version: 8.2.5
|
||||
lmdb:
|
||||
specifier: 3.2.6
|
||||
version: 3.2.6
|
||||
lodash:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
magic-string:
|
||||
specifier: 0.30.17
|
||||
version: 0.30.17
|
||||
mrmime:
|
||||
specifier: 2.0.1
|
||||
version: 2.0.1
|
||||
ng-packagr:
|
||||
specifier: 20.0.0-next.1
|
||||
version: 20.0.0-next.1(@angular/compiler-cli@20.0.0-next.2(@angular/compiler@20.0.0-next.2)(typescript@5.8.2))(tslib@2.8.1)(typescript@5.8.2)
|
||||
npm:
|
||||
specifier: ^11.0.0
|
||||
version: 11.2.0
|
||||
@ -308,15 +290,6 @@ importers:
|
||||
ora:
|
||||
specifier: 5.4.1
|
||||
version: 5.4.1
|
||||
parse5-html-rewriting-stream:
|
||||
specifier: 7.0.0
|
||||
version: 7.0.0
|
||||
piscina:
|
||||
specifier: 4.9.0
|
||||
version: 4.9.0
|
||||
postcss:
|
||||
specifier: 8.5.3
|
||||
version: 8.5.3
|
||||
prettier:
|
||||
specifier: ^3.0.0
|
||||
version: 3.5.3
|
||||
@ -324,8 +297,8 @@ importers:
|
||||
specifier: ~7.0.0
|
||||
version: 7.0.0
|
||||
puppeteer:
|
||||
specifier: 18.2.1
|
||||
version: 18.2.1(encoding@0.1.13)
|
||||
specifier: 24.4.0
|
||||
version: 24.4.0(typescript@5.8.2)
|
||||
quicktype-core:
|
||||
specifier: 23.0.171
|
||||
version: 23.0.171(encoding@0.1.13)
|
||||
@ -341,9 +314,6 @@ importers:
|
||||
rxjs:
|
||||
specifier: 7.8.2
|
||||
version: 7.8.2
|
||||
sass:
|
||||
specifier: 1.85.1
|
||||
version: 1.85.1
|
||||
semver:
|
||||
specifier: 7.7.1
|
||||
version: 7.7.1
|
||||
@ -359,9 +329,6 @@ importers:
|
||||
tar:
|
||||
specifier: ^7.0.0
|
||||
version: 7.4.3
|
||||
tinyglobby:
|
||||
specifier: 0.2.12
|
||||
version: 0.2.12
|
||||
tree-kill:
|
||||
specifier: 1.2.2
|
||||
version: 1.2.2
|
||||
@ -386,9 +353,6 @@ importers:
|
||||
verdaccio-auth-memory:
|
||||
specifier: ^10.0.0
|
||||
version: 10.2.2
|
||||
watchpack:
|
||||
specifier: 2.4.2
|
||||
version: 2.4.2
|
||||
yargs-parser:
|
||||
specifier: 21.1.1
|
||||
version: 21.1.1
|
||||
@ -510,6 +474,15 @@ importers:
|
||||
'@angular/ssr':
|
||||
specifier: workspace:*
|
||||
version: link:../ssr
|
||||
less:
|
||||
specifier: 4.2.2
|
||||
version: 4.2.2
|
||||
ng-packagr:
|
||||
specifier: 20.0.0-next.1
|
||||
version: 20.0.0-next.1(@angular/compiler-cli@20.0.0-next.2(@angular/compiler@20.0.0-next.2)(typescript@5.8.2))(tslib@2.8.1)(typescript@5.8.2)
|
||||
postcss:
|
||||
specifier: 8.5.3
|
||||
version: 8.5.3
|
||||
|
||||
packages/angular/cli:
|
||||
dependencies:
|
||||
@ -817,6 +790,9 @@ importers:
|
||||
'@angular/ssr':
|
||||
specifier: workspace:*
|
||||
version: link:../../angular/ssr
|
||||
ng-packagr:
|
||||
specifier: 20.0.0-next.1
|
||||
version: 20.0.0-next.1(@angular/compiler-cli@20.0.0-next.2(@angular/compiler@20.0.0-next.2)(typescript@5.8.2))(tslib@2.8.1)(typescript@5.8.2)
|
||||
undici:
|
||||
specifier: 7.5.0
|
||||
version: 7.5.0
|
||||
@ -3689,9 +3665,6 @@ packages:
|
||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
|
||||
chownr@1.1.4:
|
||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||
|
||||
chownr@2.0.0:
|
||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||
engines: {node: '>=10'}
|
||||
@ -3907,9 +3880,6 @@ packages:
|
||||
create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
|
||||
cross-fetch@3.1.5:
|
||||
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
|
||||
|
||||
cross-fetch@4.1.0:
|
||||
resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==}
|
||||
|
||||
@ -4129,9 +4099,6 @@ packages:
|
||||
engines: {node: '>= 0.8.0'}
|
||||
hasBin: true
|
||||
|
||||
devtools-protocol@0.0.1045489:
|
||||
resolution: {integrity: sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ==}
|
||||
|
||||
devtools-protocol@0.0.1413902:
|
||||
resolution: {integrity: sha512-yRtvFD8Oyk7C9Os3GmnFZLu53yAfsnyw1s+mLmHHUK0GQEc9zthHWvS1r67Zqzm5t7v56PILHIVZ7kmFMaL2yQ==}
|
||||
|
||||
@ -4660,9 +4627,6 @@ packages:
|
||||
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
fs-constants@1.0.0:
|
||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||
|
||||
fs-extra@3.0.1:
|
||||
resolution: {integrity: sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==}
|
||||
|
||||
@ -5880,9 +5844,6 @@ packages:
|
||||
mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
|
||||
mkdirp-classic@0.5.3:
|
||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||
|
||||
mkdirp@0.5.6:
|
||||
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
|
||||
hasBin: true
|
||||
@ -6596,18 +6557,14 @@ packages:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
puppeteer-core@18.2.1:
|
||||
resolution: {integrity: sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==}
|
||||
engines: {node: '>=14.1.0'}
|
||||
|
||||
puppeteer-core@24.4.0:
|
||||
resolution: {integrity: sha512-eFw66gCnWo0X8Hyf9KxxJtms7a61NJVMiSaWfItsFPzFBsjsWdmcNlBdsA1WVwln6neoHhsG+uTVesKmTREn/g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
puppeteer@18.2.1:
|
||||
resolution: {integrity: sha512-7+UhmYa7wxPh2oMRwA++k8UGVDxh3YdWFB52r9C3tM81T6BU7cuusUSxImz0GEYSOYUKk/YzIhkQ6+vc0gHbxQ==}
|
||||
engines: {node: '>=14.1.0'}
|
||||
deprecated: < 22.8.2 is no longer supported
|
||||
puppeteer@24.4.0:
|
||||
resolution: {integrity: sha512-E4JhJzjS8AAI+6N/b+Utwarhz6zWl3+MR725fal+s3UlOlX2eWdsvYYU+Q5bXMjs9eZEGkNQroLkn7j11s2k1Q==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
q@1.4.1:
|
||||
resolution: {integrity: sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==}
|
||||
@ -7287,16 +7244,9 @@ packages:
|
||||
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tar-fs@2.1.1:
|
||||
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
|
||||
|
||||
tar-fs@3.0.8:
|
||||
resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==}
|
||||
|
||||
tar-stream@2.2.0:
|
||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tar-stream@3.1.7:
|
||||
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
|
||||
|
||||
@ -7526,9 +7476,6 @@ packages:
|
||||
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
|
||||
|
||||
undici-types@6.19.8:
|
||||
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
|
||||
|
||||
@ -7902,18 +7849,6 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
ws@8.9.0:
|
||||
resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
xhr2@0.2.1:
|
||||
resolution: {integrity: sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -11221,8 +11156,6 @@ snapshots:
|
||||
dependencies:
|
||||
readdirp: 4.1.2
|
||||
|
||||
chownr@1.1.4: {}
|
||||
|
||||
chownr@2.0.0: {}
|
||||
|
||||
chownr@3.0.0: {}
|
||||
@ -11453,12 +11386,6 @@ snapshots:
|
||||
|
||||
create-require@1.1.1: {}
|
||||
|
||||
cross-fetch@3.1.5(encoding@0.1.13):
|
||||
dependencies:
|
||||
node-fetch: 2.6.7(encoding@0.1.13)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
cross-fetch@4.1.0(encoding@0.1.13):
|
||||
dependencies:
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
@ -11636,14 +11563,13 @@ snapshots:
|
||||
detect-libc@1.0.3:
|
||||
optional: true
|
||||
|
||||
detect-libc@2.0.3: {}
|
||||
detect-libc@2.0.3:
|
||||
optional: true
|
||||
|
||||
detect-node@2.1.0: {}
|
||||
|
||||
dev-ip@1.0.1: {}
|
||||
|
||||
devtools-protocol@0.0.1045489: {}
|
||||
|
||||
devtools-protocol@0.0.1413902: {}
|
||||
|
||||
di@0.0.1: {}
|
||||
@ -12346,8 +12272,6 @@ snapshots:
|
||||
|
||||
fresh@0.5.2: {}
|
||||
|
||||
fs-constants@1.0.0: {}
|
||||
|
||||
fs-extra@3.0.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@ -13457,6 +13381,7 @@ snapshots:
|
||||
'@lmdb/lmdb-linux-arm64': 3.2.6
|
||||
'@lmdb/lmdb-linux-x64': 3.2.6
|
||||
'@lmdb/lmdb-win32-x64': 3.2.6
|
||||
optional: true
|
||||
|
||||
loader-runner@4.3.0: {}
|
||||
|
||||
@ -13704,8 +13629,6 @@ snapshots:
|
||||
|
||||
mitt@3.0.1: {}
|
||||
|
||||
mkdirp-classic@0.5.3: {}
|
||||
|
||||
mkdirp@0.5.6:
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
@ -13737,6 +13660,7 @@ snapshots:
|
||||
msgpackr@1.11.2:
|
||||
optionalDependencies:
|
||||
msgpackr-extract: 3.0.3
|
||||
optional: true
|
||||
|
||||
multicast-dns@7.2.5:
|
||||
dependencies:
|
||||
@ -13799,7 +13723,8 @@ snapshots:
|
||||
|
||||
nice-try@1.0.5: {}
|
||||
|
||||
node-addon-api@6.1.0: {}
|
||||
node-addon-api@6.1.0:
|
||||
optional: true
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
optional: true
|
||||
@ -13831,6 +13756,7 @@ snapshots:
|
||||
node-gyp-build-optional-packages@5.2.2:
|
||||
dependencies:
|
||||
detect-libc: 2.0.3
|
||||
optional: true
|
||||
|
||||
node-gyp@11.1.0:
|
||||
dependencies:
|
||||
@ -14017,7 +13943,8 @@ snapshots:
|
||||
strip-ansi: 6.0.1
|
||||
wcwidth: 1.0.1
|
||||
|
||||
ordered-binary@1.5.3: {}
|
||||
ordered-binary@1.5.3:
|
||||
optional: true
|
||||
|
||||
os-tmpdir@1.0.2: {}
|
||||
|
||||
@ -14402,24 +14329,6 @@ snapshots:
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
puppeteer-core@18.2.1(encoding@0.1.13):
|
||||
dependencies:
|
||||
cross-fetch: 3.1.5(encoding@0.1.13)
|
||||
debug: 4.3.4
|
||||
devtools-protocol: 0.0.1045489
|
||||
extract-zip: 2.0.1
|
||||
https-proxy-agent: 5.0.1(supports-color@10.0.0)
|
||||
proxy-from-env: 1.1.0
|
||||
rimraf: 3.0.2
|
||||
tar-fs: 2.1.1
|
||||
unbzip2-stream: 1.4.3
|
||||
ws: 8.9.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- encoding
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
puppeteer-core@24.4.0:
|
||||
dependencies:
|
||||
'@puppeteer/browsers': 2.8.0
|
||||
@ -14434,16 +14343,19 @@ snapshots:
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
puppeteer@18.2.1(encoding@0.1.13):
|
||||
puppeteer@24.4.0(typescript@5.8.2):
|
||||
dependencies:
|
||||
https-proxy-agent: 5.0.1(supports-color@10.0.0)
|
||||
progress: 2.0.3
|
||||
proxy-from-env: 1.1.0
|
||||
puppeteer-core: 18.2.1(encoding@0.1.13)
|
||||
'@puppeteer/browsers': 2.8.0
|
||||
chromium-bidi: 2.1.2(devtools-protocol@0.0.1413902)
|
||||
cosmiconfig: 9.0.0(typescript@5.8.2)
|
||||
devtools-protocol: 0.0.1413902
|
||||
puppeteer-core: 24.4.0
|
||||
typed-query-selector: 2.12.0
|
||||
transitivePeerDependencies:
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
- encoding
|
||||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
|
||||
q@1.4.1: {}
|
||||
@ -15300,13 +15212,6 @@ snapshots:
|
||||
|
||||
tapable@2.2.1: {}
|
||||
|
||||
tar-fs@2.1.1:
|
||||
dependencies:
|
||||
chownr: 1.1.4
|
||||
mkdirp-classic: 0.5.3
|
||||
pump: 3.0.2
|
||||
tar-stream: 2.2.0
|
||||
|
||||
tar-fs@3.0.8:
|
||||
dependencies:
|
||||
pump: 3.0.2
|
||||
@ -15317,14 +15222,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- bare-buffer
|
||||
|
||||
tar-stream@2.2.0:
|
||||
dependencies:
|
||||
bl: 4.1.0
|
||||
end-of-stream: 1.4.4
|
||||
fs-constants: 1.0.0
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.2
|
||||
|
||||
tar-stream@3.1.7:
|
||||
dependencies:
|
||||
b4a: 1.6.7
|
||||
@ -15572,11 +15469,6 @@ snapshots:
|
||||
has-symbols: 1.1.0
|
||||
which-boxed-primitive: 1.1.1
|
||||
|
||||
unbzip2-stream@1.4.3:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
through: 2.3.8
|
||||
|
||||
undici-types@6.19.8: {}
|
||||
|
||||
undici@7.5.0: {}
|
||||
@ -15773,7 +15665,8 @@ snapshots:
|
||||
dependencies:
|
||||
defaults: 1.0.4
|
||||
|
||||
weak-lru-cache@1.2.2: {}
|
||||
weak-lru-cache@1.2.2:
|
||||
optional: true
|
||||
|
||||
web-streams-polyfill@3.3.3: {}
|
||||
|
||||
@ -16004,8 +15897,6 @@ snapshots:
|
||||
|
||||
ws@8.18.1: {}
|
||||
|
||||
ws@8.9.0: {}
|
||||
|
||||
xhr2@0.2.1: {}
|
||||
|
||||
xml2js@0.4.23:
|
||||
|
@ -17,7 +17,7 @@ export async function libraryConsumptionSetup(): Promise<void> {
|
||||
export class MyLibComponent {}`,
|
||||
'./src/app/app.ts': `
|
||||
import { Component } from '@angular/core';
|
||||
import { MyLibService, MyLibComponent } from 'my-lib';
|
||||
import { MyLibComponent } from 'my-lib';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@ -28,8 +28,7 @@ export async function libraryConsumptionSetup(): Promise<void> {
|
||||
export class App {
|
||||
title = 'test-project';
|
||||
|
||||
constructor(myLibService: MyLibService) {
|
||||
console.log(myLibService);
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
@ -9,8 +9,8 @@ export default function () {
|
||||
return (
|
||||
ng('generate', 'service', 'test-service')
|
||||
.then(() => expectFileToExist(serviceDir))
|
||||
.then(() => expectFileToExist(join(serviceDir, 'test-service.service.ts')))
|
||||
.then(() => expectFileToExist(join(serviceDir, 'test-service.service.spec.ts')))
|
||||
.then(() => expectFileToExist(join(serviceDir, 'test-service.ts')))
|
||||
.then(() => expectFileToExist(join(serviceDir, 'test-service.spec.ts')))
|
||||
|
||||
// Try to run the unit tests.
|
||||
.then(() => ng('test', '--watch=false'))
|
||||
|
@ -2,10 +2,10 @@ import { prependToFile, replaceInFile } from '../../utils/fs';
|
||||
import { ng } from '../../utils/process';
|
||||
|
||||
export default async function () {
|
||||
await ng('generate', 'service', 'user');
|
||||
await ng('generate', 'service', 'user-service');
|
||||
|
||||
// Update the application to use the new service
|
||||
await prependToFile('src/app/app.ts', "import { UserService } from './user.service';");
|
||||
await prependToFile('src/app/app.ts', "import { UserService } from './user-service';");
|
||||
|
||||
await replaceInFile(
|
||||
'src/app/app.ts',
|
||||
|
@ -257,10 +257,8 @@ Promise.all([findFreePort(), findFreePort(), findPackageTars()])
|
||||
console.log(`Current Directory: ${process.cwd()}`);
|
||||
console.log('Will loop forever while you debug... CTRL-C to quit.');
|
||||
|
||||
/* eslint-disable no-constant-condition */
|
||||
while (1) {
|
||||
// That's right!
|
||||
}
|
||||
// Wait forever until user explicitly cancels.
|
||||
await new Promise(() => {});
|
||||
}
|
||||
|
||||
process.exitCode = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user