@schematics/angular 21.0.0-next.4 → 21.0.0-next.6
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.
- package/ai-config/index.js +32 -15
- package/ai-config/schema.d.ts +1 -0
- package/ai-config/schema.js +1 -0
- package/ai-config/schema.json +5 -1
- package/application/files/module-files/src/app/app-module.ts.template +2 -3
- package/application/files/module-files/src/app/app__suffix__.spec.ts.template +4 -6
- package/application/files/standalone-files/src/app/app.config.ts.template +3 -3
- package/application/files/standalone-files/src/app/app__suffix__.spec.ts.template +4 -6
- package/application/schema.json +1 -1
- package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template +1 -1
- package/component/index.js +3 -0
- package/migrations/migration-collection.json +5 -0
- package/migrations/update-typescript-lib/migration.d.ts +9 -0
- package/migrations/update-typescript-lib/migration.js +79 -0
- package/migrations/use-application-builder/migration.js +1 -0
- package/ng-new/schema.d.ts +1 -0
- package/ng-new/schema.js +1 -0
- package/ng-new/schema.json +1 -1
- package/package.json +4 -4
- package/ssr/files/application-builder/server.ts.template +2 -2
- package/ssr/files/server-builder/server.ts.template +0 -2
- package/utility/latest-versions/package.json +1 -1
- package/utility/latest-versions.js +3 -3
- package/utility/project-targets.d.ts +1 -0
- package/utility/project-targets.js +10 -0
- package/workspace/files/__dot__gitignore.template +1 -0
- package/workspace/files/package.json.template +1 -0
- package/workspace/index.js +34 -9
- package/workspace/schema.json +4 -1
package/ai-config/index.js
CHANGED
|
@@ -11,6 +11,10 @@ exports.default = default_1;
|
|
|
11
11
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
12
12
|
const schema_1 = require("./schema");
|
|
13
13
|
const AI_TOOLS = {
|
|
14
|
+
agents: {
|
|
15
|
+
rulesName: 'AGENTS.md',
|
|
16
|
+
directory: '.',
|
|
17
|
+
},
|
|
14
18
|
gemini: {
|
|
15
19
|
rulesName: 'GEMINI.md',
|
|
16
20
|
directory: '.gemini',
|
|
@@ -39,19 +43,32 @@ const AI_TOOLS = {
|
|
|
39
43
|
},
|
|
40
44
|
};
|
|
41
45
|
function default_1({ tool }) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
return (tree, context) => {
|
|
47
|
+
if (!tool) {
|
|
48
|
+
return (0, schematics_1.noop)();
|
|
49
|
+
}
|
|
50
|
+
const rules = tool
|
|
51
|
+
.filter((tool) => tool !== schema_1.Tool.None)
|
|
52
|
+
.map((selectedTool) => {
|
|
53
|
+
const { rulesName, directory, frontmatter } = AI_TOOLS[selectedTool];
|
|
54
|
+
const path = `${directory}/${rulesName}`;
|
|
55
|
+
if (tree.exists(path)) {
|
|
56
|
+
const toolName = schematics_1.strings.classify(selectedTool);
|
|
57
|
+
context.logger.warn(`Skipping configuration file for '${toolName}' at '${path}' because it already exists.\n` +
|
|
58
|
+
'This is to prevent overwriting a potentially customized file. ' +
|
|
59
|
+
'If you want to regenerate it with Angular recommended defaults, please delete the existing file and re-run the command.\n' +
|
|
60
|
+
'You can review the latest recommendations at https://angular.dev/ai/develop-with-ai.');
|
|
61
|
+
return (0, schematics_1.noop)();
|
|
62
|
+
}
|
|
63
|
+
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
64
|
+
(0, schematics_1.applyTemplates)({
|
|
65
|
+
...schematics_1.strings,
|
|
66
|
+
rulesName,
|
|
67
|
+
frontmatter,
|
|
68
|
+
}),
|
|
69
|
+
(0, schematics_1.move)(directory),
|
|
70
|
+
]));
|
|
71
|
+
});
|
|
72
|
+
return (0, schematics_1.chain)(rules);
|
|
73
|
+
};
|
|
57
74
|
}
|
package/ai-config/schema.d.ts
CHANGED
package/ai-config/schema.js
CHANGED
package/ai-config/schema.json
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"value": "none",
|
|
19
19
|
"label": "None"
|
|
20
20
|
},
|
|
21
|
+
{
|
|
22
|
+
"value": "agents",
|
|
23
|
+
"label": "Agents.md [ https://agents.md/ ]"
|
|
24
|
+
},
|
|
21
25
|
{
|
|
22
26
|
"value": "claude",
|
|
23
27
|
"label": "Claude [ https://docs.anthropic.com/en/docs/claude-code/memory ]"
|
|
@@ -47,7 +51,7 @@
|
|
|
47
51
|
"description": "Specifies which AI tools to generate configuration files for. These file are used to improve the outputs of AI tools by following the best practices.",
|
|
48
52
|
"items": {
|
|
49
53
|
"type": "string",
|
|
50
|
-
"enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf"]
|
|
54
|
+
"enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf", "agents"]
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NgModule, provideBrowserGlobalErrorListeners
|
|
1
|
+
import { NgModule, provideBrowserGlobalErrorListeners } from '@angular/core';
|
|
2
2
|
import { BrowserModule } from '@angular/platform-browser';
|
|
3
3
|
<% if (routing) { %>
|
|
4
4
|
import { AppRoutingModule } from './app-routing-module';<% } %>
|
|
@@ -13,8 +13,7 @@ import { App } from './app';
|
|
|
13
13
|
AppRoutingModule<% } %>
|
|
14
14
|
],
|
|
15
15
|
providers: [
|
|
16
|
-
provideBrowserGlobalErrorListeners()
|
|
17
|
-
provideZonelessChangeDetection()<% } %>
|
|
16
|
+
provideBrowserGlobalErrorListeners()
|
|
18
17
|
],
|
|
19
18
|
bootstrap: [App]
|
|
20
19
|
})
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
<% } %>import { TestBed } from '@angular/core/testing';<% if (routing) { %>
|
|
1
|
+
import { TestBed } from '@angular/core/testing';<% if (routing) { %>
|
|
3
2
|
import { RouterModule } from '@angular/router';<% } %>
|
|
4
3
|
import { App } from './app';
|
|
5
4
|
|
|
@@ -11,8 +10,7 @@ describe('App', () => {
|
|
|
11
10
|
],<% } %>
|
|
12
11
|
declarations: [
|
|
13
12
|
App
|
|
14
|
-
]
|
|
15
|
-
providers: [provideZonelessChangeDetection()]<% } %>
|
|
13
|
+
],
|
|
16
14
|
}).compileComponents();
|
|
17
15
|
});
|
|
18
16
|
|
|
@@ -22,9 +20,9 @@ describe('App', () => {
|
|
|
22
20
|
expect(app).toBeTruthy();
|
|
23
21
|
});
|
|
24
22
|
|
|
25
|
-
it('should render title', () => {
|
|
23
|
+
it('should render title', <% if(zoneless) { %> async <% } %>() => {
|
|
26
24
|
const fixture = TestBed.createComponent(App);
|
|
27
|
-
fixture.detectChanges();
|
|
25
|
+
<%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %>
|
|
28
26
|
const compiled = fixture.nativeElement as HTMLElement;
|
|
29
27
|
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, <%= name %>');
|
|
30
28
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ApplicationConfig, provideBrowserGlobalErrorListeners
|
|
1
|
+
import { ApplicationConfig, provideBrowserGlobalErrorListeners<% if(!zoneless) { %>, provideZoneChangeDetection<% } %> } from '@angular/core';<% if (routing) { %>
|
|
2
2
|
import { provideRouter } from '@angular/router';
|
|
3
3
|
|
|
4
4
|
import { routes } from './app.routes';<% } %>
|
|
5
5
|
|
|
6
6
|
export const appConfig: ApplicationConfig = {
|
|
7
7
|
providers: [
|
|
8
|
-
provideBrowserGlobalErrorListeners()
|
|
9
|
-
|
|
8
|
+
provideBrowserGlobalErrorListeners(),<% if(!zoneless) { %>
|
|
9
|
+
provideZoneChangeDetection({ eventCoalescing: true }),<% } %>
|
|
10
10
|
<% if (routing) {%>provideRouter(routes)<% } %>
|
|
11
11
|
]
|
|
12
12
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
<% } %>import { TestBed } from '@angular/core/testing';
|
|
1
|
+
import { TestBed } from '@angular/core/testing';
|
|
3
2
|
import { App } from './app';
|
|
4
3
|
|
|
5
4
|
describe('App', () => {
|
|
6
5
|
beforeEach(async () => {
|
|
7
6
|
await TestBed.configureTestingModule({
|
|
8
|
-
imports: [App]
|
|
9
|
-
providers: [provideZonelessChangeDetection()]<% } %>
|
|
7
|
+
imports: [App],
|
|
10
8
|
}).compileComponents();
|
|
11
9
|
});
|
|
12
10
|
|
|
@@ -16,9 +14,9 @@ describe('App', () => {
|
|
|
16
14
|
expect(app).toBeTruthy();
|
|
17
15
|
});
|
|
18
16
|
|
|
19
|
-
it('should render title', () => {
|
|
17
|
+
it('should render title', <% if(zoneless) { %> async <% } %>() => {
|
|
20
18
|
const fixture = TestBed.createComponent(App);
|
|
21
|
-
fixture.detectChanges();
|
|
19
|
+
<%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %>
|
|
22
20
|
const compiled = fixture.nativeElement as HTMLElement;
|
|
23
21
|
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, <%= name %>');
|
|
24
22
|
});
|
package/application/schema.json
CHANGED
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"description": "Generate an application that does not use `zone.js`.",
|
|
127
127
|
"x-prompt": "Do you want to create a 'zoneless' application without zone.js?",
|
|
128
128
|
"type": "boolean",
|
|
129
|
-
"default":
|
|
129
|
+
"default": true
|
|
130
130
|
},
|
|
131
131
|
"fileNameStyleGuide": {
|
|
132
132
|
"type": "string",
|
|
@@ -14,7 +14,7 @@ describe('<%= classifiedName %>', () => {
|
|
|
14
14
|
|
|
15
15
|
fixture = TestBed.createComponent(<%= classifiedName %>);
|
|
16
16
|
component = fixture.componentInstance;
|
|
17
|
-
fixture.detectChanges();
|
|
17
|
+
<%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %>
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it('should create', () => {
|
package/component/index.js
CHANGED
|
@@ -12,6 +12,7 @@ const add_declaration_to_ng_module_1 = require("../utility/add-declaration-to-ng
|
|
|
12
12
|
const find_module_1 = require("../utility/find-module");
|
|
13
13
|
const parse_name_1 = require("../utility/parse-name");
|
|
14
14
|
const project_1 = require("../utility/project");
|
|
15
|
+
const project_targets_1 = require("../utility/project-targets");
|
|
15
16
|
const validation_1 = require("../utility/validation");
|
|
16
17
|
const workspace_1 = require("../utility/workspace");
|
|
17
18
|
const schema_1 = require("./schema");
|
|
@@ -40,6 +41,7 @@ exports.default = (0, project_1.createProjectSchematic)((options, { project, tre
|
|
|
40
41
|
const classifiedName = schematics_1.strings.classify(options.name) +
|
|
41
42
|
(options.addTypeToClassName && options.type ? schematics_1.strings.classify(options.type) : '');
|
|
42
43
|
(0, validation_1.validateClassName)(classifiedName);
|
|
44
|
+
const zoneless = (0, project_targets_1.isZonelessApp)(project);
|
|
43
45
|
const skipStyleFile = options.inlineStyle || options.style === schema_1.Style.None;
|
|
44
46
|
const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
45
47
|
options.skipTests ? (0, schematics_1.filter)((path) => !path.endsWith('.spec.ts.template')) : (0, schematics_1.noop)(),
|
|
@@ -52,6 +54,7 @@ exports.default = (0, project_1.createProjectSchematic)((options, { project, tre
|
|
|
52
54
|
...options,
|
|
53
55
|
// Add a new variable for the classified name, conditionally including the type
|
|
54
56
|
classifiedName,
|
|
57
|
+
zoneless,
|
|
55
58
|
}),
|
|
56
59
|
!options.type
|
|
57
60
|
? (0, schematics_1.forEach)(((file) => {
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"version": "21.0.0",
|
|
14
14
|
"factory": "./karma/migration",
|
|
15
15
|
"description": "Remove any karma configuration files that only contain the default content. The default configuration is automatically available without a specific project file."
|
|
16
|
+
},
|
|
17
|
+
"update-typescript-lib": {
|
|
18
|
+
"version": "21.0.0",
|
|
19
|
+
"factory": "./update-typescript-lib/migration",
|
|
20
|
+
"description": "Updates the 'lib' property in tsconfig files to use 'es2022' or a more modern version."
|
|
16
21
|
}
|
|
17
22
|
}
|
|
18
23
|
}
|
|
@@ -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.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import { Rule } from '@angular-devkit/schematics';
|
|
9
|
+
export default function (): Rule;
|
|
@@ -0,0 +1,79 @@
|
|
|
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.default = default_1;
|
|
11
|
+
const json_file_1 = require("../../utility/json-file");
|
|
12
|
+
const workspace_1 = require("../../utility/workspace");
|
|
13
|
+
function default_1() {
|
|
14
|
+
return async (host, context) => {
|
|
15
|
+
// Workspace level tsconfig
|
|
16
|
+
if (host.exists('tsconfig.json')) {
|
|
17
|
+
updateLib(host, 'tsconfig.json');
|
|
18
|
+
}
|
|
19
|
+
const workspace = await (0, workspace_1.getWorkspace)(host);
|
|
20
|
+
// Find all tsconfig which are references used by builders
|
|
21
|
+
for (const [, project] of workspace.projects) {
|
|
22
|
+
for (const [targetName, target] of project.targets) {
|
|
23
|
+
if (!target.options) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
// Update all other known CLI builders that use a tsconfig
|
|
27
|
+
const tsConfigs = [target.options, ...Object.values(target.configurations || {})]
|
|
28
|
+
.filter((opt) => typeof opt?.tsConfig === 'string')
|
|
29
|
+
.map((opt) => opt.tsConfig);
|
|
30
|
+
const uniqueTsConfigs = new Set(tsConfigs);
|
|
31
|
+
for (const tsConfig of uniqueTsConfigs) {
|
|
32
|
+
if (host.exists(tsConfig)) {
|
|
33
|
+
updateLib(host, tsConfig);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
context.logger.warn(`'${tsConfig}' referenced in the '${targetName}' target does not exist.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function updateLib(host, tsConfigPath) {
|
|
44
|
+
const json = new json_file_1.JSONFile(host, tsConfigPath);
|
|
45
|
+
const jsonPath = ['compilerOptions', 'lib'];
|
|
46
|
+
const lib = json.get(jsonPath);
|
|
47
|
+
if (!lib || !Array.isArray(lib)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const esLibs = lib.filter((l) => typeof l === 'string' && l.toLowerCase().startsWith('es'));
|
|
51
|
+
const hasDom = lib.some((l) => typeof l === 'string' && l.toLowerCase() === 'dom');
|
|
52
|
+
if (esLibs.length === 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const esLibToVersion = new Map();
|
|
56
|
+
for (const l of esLibs) {
|
|
57
|
+
const version = l.toLowerCase().match(/^es(next|(\d+))$/)?.[1];
|
|
58
|
+
if (version) {
|
|
59
|
+
esLibToVersion.set(l, version === 'next' ? Infinity : Number(version));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (esLibToVersion.size === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const latestEsLib = [...esLibToVersion.entries()].sort(([, v1], [, v2]) => v2 - v1)[0];
|
|
66
|
+
const latestVersion = latestEsLib[1];
|
|
67
|
+
if (hasDom) {
|
|
68
|
+
if (latestVersion <= 2022) {
|
|
69
|
+
json.remove(jsonPath);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// No 'dom' with 'es' libs, so update 'es' lib.
|
|
74
|
+
if (latestVersion < 2022) {
|
|
75
|
+
const newLibs = lib.filter((l) => !esLibToVersion.has(l));
|
|
76
|
+
newLibs.push('es2022');
|
|
77
|
+
json.modify(jsonPath, newLibs);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -270,6 +270,7 @@ function default_1() {
|
|
|
270
270
|
rootJson.modify(['compilerOptions', 'esModuleInterop'], true);
|
|
271
271
|
rootJson.modify(['compilerOptions', 'downlevelIteration'], undefined);
|
|
272
272
|
rootJson.modify(['compilerOptions', 'allowSyntheticDefaultImports'], undefined);
|
|
273
|
+
rootJson.modify(['compilerOptions', 'moduleResolution'], 'bundler');
|
|
273
274
|
}),
|
|
274
275
|
]);
|
|
275
276
|
}
|
package/ng-new/schema.d.ts
CHANGED
package/ng-new/schema.js
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
5
5
|
exports.ViewEncapsulation = exports.Style = exports.PackageManager = exports.FileNameStyleGuide = exports.AiConfig = void 0;
|
|
6
6
|
var AiConfig;
|
|
7
7
|
(function (AiConfig) {
|
|
8
|
+
AiConfig["Agents"] = "agents";
|
|
8
9
|
AiConfig["Claude"] = "claude";
|
|
9
10
|
AiConfig["Copilot"] = "copilot";
|
|
10
11
|
AiConfig["Cursor"] = "cursor";
|
package/ng-new/schema.json
CHANGED
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"description": "Specifies which AI tools to generate configuration files for. These file are used to improve the outputs of AI tools by following the best practices.",
|
|
150
150
|
"items": {
|
|
151
151
|
"type": "string",
|
|
152
|
-
"enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf"]
|
|
152
|
+
"enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf", "agents"]
|
|
153
153
|
}
|
|
154
154
|
},
|
|
155
155
|
"fileNameStyleGuide": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schematics/angular",
|
|
3
|
-
"version": "21.0.0-next.
|
|
3
|
+
"version": "21.0.0-next.6",
|
|
4
4
|
"description": "Schematics specific to Angular",
|
|
5
5
|
"homepage": "https://github.com/angular/angular-cli",
|
|
6
6
|
"keywords": [
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
},
|
|
23
23
|
"schematics": "./collection.json",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@angular-devkit/core": "21.0.0-next.
|
|
26
|
-
"@angular-devkit/schematics": "21.0.0-next.
|
|
25
|
+
"@angular-devkit/core": "21.0.0-next.6",
|
|
26
|
+
"@angular-devkit/schematics": "21.0.0-next.6",
|
|
27
27
|
"jsonc-parser": "3.3.1"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/angular/angular-cli.git"
|
|
32
32
|
},
|
|
33
|
-
"packageManager": "pnpm@10.17.
|
|
33
|
+
"packageManager": "pnpm@10.17.1",
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
36
36
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
|
@@ -48,10 +48,10 @@ app.use((req, res, next) => {
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* Start the server if this module is the main entry point.
|
|
51
|
+
* Start the server if this module is the main entry point, or it is ran via PM2.
|
|
52
52
|
* The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
|
|
53
53
|
*/
|
|
54
|
-
if (isMainModule(import.meta.url)) {
|
|
54
|
+
if (isMainModule(import.meta.url) || process.env['pm_id']) {
|
|
55
55
|
const port = process.env['PORT'] || 4000;
|
|
56
56
|
app.listen(port, (error) => {
|
|
57
57
|
if (error) {
|
|
@@ -16,7 +16,7 @@ exports.latestVersions = {
|
|
|
16
16
|
// As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
|
|
17
17
|
Angular: '^21.0.0-next.0',
|
|
18
18
|
NgPackagr: '^21.0.0-next.0',
|
|
19
|
-
DevkitBuildAngular: '^21.0.0-next.
|
|
20
|
-
AngularBuild: '^21.0.0-next.
|
|
21
|
-
AngularSSR: '^21.0.0-next.
|
|
19
|
+
DevkitBuildAngular: '^21.0.0-next.6',
|
|
20
|
+
AngularBuild: '^21.0.0-next.6',
|
|
21
|
+
AngularSSR: '^21.0.0-next.6',
|
|
22
22
|
};
|
|
@@ -9,3 +9,4 @@ import { SchematicsException } from '@angular-devkit/schematics';
|
|
|
9
9
|
import { ProjectDefinition } from './workspace';
|
|
10
10
|
export declare function targetBuildNotFoundError(): SchematicsException;
|
|
11
11
|
export declare function isUsingApplicationBuilder(project: ProjectDefinition): boolean;
|
|
12
|
+
export declare function isZonelessApp(project: ProjectDefinition): boolean;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.targetBuildNotFoundError = targetBuildNotFoundError;
|
|
11
11
|
exports.isUsingApplicationBuilder = isUsingApplicationBuilder;
|
|
12
|
+
exports.isZonelessApp = isZonelessApp;
|
|
12
13
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
13
14
|
const workspace_models_1 = require("./workspace-models");
|
|
14
15
|
function targetBuildNotFoundError() {
|
|
@@ -19,3 +20,12 @@ function isUsingApplicationBuilder(project) {
|
|
|
19
20
|
const isUsingApplicationBuilder = buildBuilder === workspace_models_1.Builders.Application || buildBuilder === workspace_models_1.Builders.BuildApplication;
|
|
20
21
|
return isUsingApplicationBuilder;
|
|
21
22
|
}
|
|
23
|
+
function isZonelessApp(project) {
|
|
24
|
+
const buildTarget = project.targets.get('build');
|
|
25
|
+
if (!buildTarget?.options?.polyfills) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const polyfills = buildTarget.options.polyfills;
|
|
29
|
+
const polyfillsList = Array.isArray(polyfills) ? polyfills : [polyfills];
|
|
30
|
+
return !polyfillsList.includes('zone.js');
|
|
31
|
+
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
]
|
|
22
22
|
},
|
|
23
23
|
"private": true,
|
|
24
|
+
<% if (packageManagerWithVersion) { %>"packageManager": "<%= packageManagerWithVersion %>",<% } %>
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@angular/common": "<%= latestVersions.Angular %>",
|
|
26
27
|
"@angular/compiler": "<%= latestVersions.Angular %>",
|
package/workspace/index.js
CHANGED
|
@@ -9,15 +9,40 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.default = default_1;
|
|
11
11
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
12
|
+
const node_child_process_1 = require("node:child_process");
|
|
12
13
|
const latest_versions_1 = require("../utility/latest-versions");
|
|
13
14
|
function default_1(options) {
|
|
14
|
-
return (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
return () => {
|
|
16
|
+
const packageManager = options.packageManager;
|
|
17
|
+
let packageManagerWithVersion;
|
|
18
|
+
if (packageManager) {
|
|
19
|
+
let packageManagerVersion;
|
|
20
|
+
try {
|
|
21
|
+
packageManagerVersion = (0, node_child_process_1.execSync)(`${packageManager} --version`, {
|
|
22
|
+
encoding: 'utf8',
|
|
23
|
+
stdio: 'pipe',
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
// NPM updater notifier will prevents the child process from closing until it timeout after 3 minutes.
|
|
27
|
+
NO_UPDATE_NOTIFIER: '1',
|
|
28
|
+
NPM_CONFIG_UPDATE_NOTIFIER: 'false',
|
|
29
|
+
},
|
|
30
|
+
}).trim();
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
if (packageManagerVersion) {
|
|
34
|
+
packageManagerWithVersion = `${packageManager}@${packageManagerVersion}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
38
|
+
options.minimal ? (0, schematics_1.filter)((path) => !path.endsWith('editorconfig.template')) : (0, schematics_1.noop)(),
|
|
39
|
+
(0, schematics_1.applyTemplates)({
|
|
40
|
+
utils: schematics_1.strings,
|
|
41
|
+
...options,
|
|
42
|
+
'dot': '.',
|
|
43
|
+
latestVersions: latest_versions_1.latestVersions,
|
|
44
|
+
packageManagerWithVersion,
|
|
45
|
+
}),
|
|
46
|
+
]));
|
|
47
|
+
};
|
|
23
48
|
}
|
package/workspace/schema.json
CHANGED
|
@@ -40,7 +40,10 @@
|
|
|
40
40
|
"packageManager": {
|
|
41
41
|
"description": "The package manager to use for installing dependencies.",
|
|
42
42
|
"type": "string",
|
|
43
|
-
"enum": ["npm", "yarn", "pnpm", "bun"]
|
|
43
|
+
"enum": ["npm", "yarn", "pnpm", "bun"],
|
|
44
|
+
"$default": {
|
|
45
|
+
"$source": "packageManager"
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
},
|
|
46
49
|
"required": ["name", "version"]
|