@schematics/angular 21.0.0-next.5 → 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__suffix__.spec.ts.template +2 -2
- package/application/files/standalone-files/src/app/app__suffix__.spec.ts.template +2 -2
- package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template +1 -1
- package/component/index.js +3 -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 +3 -3
- package/ssr/files/application-builder/server.ts.template +2 -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/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
|
}
|
|
@@ -20,9 +20,9 @@ describe('App', () => {
|
|
|
20
20
|
expect(app).toBeTruthy();
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
it('should render title', () => {
|
|
23
|
+
it('should render title', <% if(zoneless) { %> async <% } %>() => {
|
|
24
24
|
const fixture = TestBed.createComponent(App);
|
|
25
|
-
fixture.detectChanges();
|
|
25
|
+
<%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %>
|
|
26
26
|
const compiled = fixture.nativeElement as HTMLElement;
|
|
27
27
|
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, <%= name %>');
|
|
28
28
|
});
|
|
@@ -14,9 +14,9 @@ describe('App', () => {
|
|
|
14
14
|
expect(app).toBeTruthy();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it('should render title', () => {
|
|
17
|
+
it('should render title', <% if(zoneless) { %> async <% } %>() => {
|
|
18
18
|
const fixture = TestBed.createComponent(App);
|
|
19
|
-
fixture.detectChanges();
|
|
19
|
+
<%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %>
|
|
20
20
|
const compiled = fixture.nativeElement as HTMLElement;
|
|
21
21
|
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, <%= name %>');
|
|
22
22
|
});
|
|
@@ -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) => {
|
|
@@ -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,8 +22,8 @@
|
|
|
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": {
|
|
@@ -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
|
+
}
|