@schematics/angular 21.0.0-next.0 → 21.0.0-next.2
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 +5 -3
- package/ai-config/schema.json +1 -17
- package/app-shell/index.d.ts +2 -1
- package/app-shell/index.js +16 -24
- package/application/index.js +29 -1
- package/application/schema.d.ts +19 -1
- package/application/schema.js +13 -1
- package/application/schema.json +12 -2
- package/collection.json +7 -0
- package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template +6 -6
- package/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template +1 -1
- package/component/index.d.ts +2 -1
- package/component/index.js +49 -53
- package/component/schema.d.ts +5 -0
- package/component/schema.json +5 -0
- package/config/index.d.ts +2 -1
- package/config/index.js +12 -19
- package/directive/files/__name@dasherize__.__type@dasherize__.spec.ts.template +3 -3
- package/directive/files/__name@dasherize__.__type@dasherize__.ts.template +1 -1
- package/directive/index.d.ts +2 -1
- package/directive/index.js +25 -27
- package/directive/schema.d.ts +5 -0
- package/directive/schema.json +5 -0
- package/migrations/karma/karma-config-comparer.js +1 -1
- package/migrations/migration-collection.json +1 -0
- package/module/index.d.ts +2 -1
- package/module/index.js +48 -50
- package/ng-new/index.js +1 -0
- package/ng-new/schema.d.ts +19 -2
- package/ng-new/schema.js +13 -2
- package/ng-new/schema.json +8 -2
- package/package.json +4 -4
- package/pipe/index.d.ts +2 -2
- package/pipe/index.js +16 -18
- package/server/index.d.ts +2 -1
- package/server/index.js +67 -71
- package/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template +4 -4
- package/service/files/__name@dasherize__.__type@dasherize__.ts.template +1 -1
- package/service/index.d.ts +2 -1
- package/service/index.js +20 -4
- package/service/schema.d.ts +5 -0
- package/service/schema.json +5 -0
- package/service-worker/index.d.ts +2 -1
- package/service-worker/index.js +44 -81
- package/ssr/index.d.ts +2 -1
- package/ssr/index.js +32 -40
- package/tailwind/files/.postcssrc.json.template +5 -0
- package/tailwind/index.d.ts +12 -0
- package/tailwind/index.js +105 -0
- package/tailwind/schema.d.ts +7 -0
- package/tailwind/schema.js +4 -0
- package/tailwind/schema.json +15 -0
- package/utility/ast-utils.js +31 -17
- package/utility/generate-from-files.d.ts +1 -0
- package/utility/latest-versions/package.json +3 -1
- package/utility/latest-versions.js +3 -3
- package/utility/project.d.ts +25 -0
- package/utility/project.js +30 -0
- package/utility/standalone/rules.js +2 -3
- package/web-worker/index.d.ts +2 -1
- package/web-worker/index.js +60 -70
- package/workspace/schema.d.ts +0 -1
- package/workspace/schema.js +0 -1
- package/workspace/schema.json +1 -1
- /package/application/files/common-files/src/app/{app.html.template → app__suffix__.html.template} +0 -0
- /package/application/files/module-files/src/app/{app.spec.ts.template → app__suffix__.spec.ts.template} +0 -0
- /package/application/files/module-files/src/app/{app.ts.template → app__suffix__.ts.template} +0 -0
- /package/application/files/standalone-files/src/app/{app.spec.ts.template → app__suffix__.spec.ts.template} +0 -0
- /package/application/files/standalone-files/src/app/{app.ts.template → app__suffix__.ts.template} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { TestBed } from '@angular/core/testing';
|
|
2
2
|
|
|
3
|
-
import { <%=
|
|
3
|
+
import { <%= classifiedName %> } from './<%= dasherize(name) %><%= type ? '.' + dasherize(type) : '' %>';
|
|
4
4
|
|
|
5
|
-
describe('<%=
|
|
6
|
-
let service: <%=
|
|
5
|
+
describe('<%= classifiedName %>', () => {
|
|
6
|
+
let service: <%= classifiedName %>;
|
|
7
7
|
|
|
8
8
|
beforeEach(() => {
|
|
9
9
|
TestBed.configureTestingModule({});
|
|
10
|
-
service = TestBed.inject(<%=
|
|
10
|
+
service = TestBed.inject(<%= classifiedName %>);
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
it('should be created', () => {
|
package/service/index.d.ts
CHANGED
package/service/index.js
CHANGED
|
@@ -7,8 +7,24 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
|
|
10
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
11
11
|
const generate_from_files_1 = require("../utility/generate-from-files");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const parse_name_1 = require("../utility/parse-name");
|
|
13
|
+
const project_1 = require("../utility/project");
|
|
14
|
+
const validation_1 = require("../utility/validation");
|
|
15
|
+
const workspace_1 = require("../utility/workspace");
|
|
16
|
+
exports.default = (0, project_1.createProjectSchematic)((options, { project, tree }) => {
|
|
17
|
+
if (options.path === undefined) {
|
|
18
|
+
options.path = (0, workspace_1.buildDefaultPath)(project);
|
|
19
|
+
}
|
|
20
|
+
const parsedPath = (0, parse_name_1.parseName)(options.path, options.name);
|
|
21
|
+
options.name = parsedPath.name;
|
|
22
|
+
options.path = parsedPath.path;
|
|
23
|
+
const classifiedName = schematics_1.strings.classify(options.name) +
|
|
24
|
+
(options.addTypeToClassName && options.type ? schematics_1.strings.classify(options.type) : '');
|
|
25
|
+
(0, validation_1.validateClassName)(classifiedName);
|
|
26
|
+
return (0, generate_from_files_1.generateFromFiles)({
|
|
27
|
+
...options,
|
|
28
|
+
classifiedName,
|
|
29
|
+
});
|
|
30
|
+
});
|
package/service/schema.d.ts
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* process of generating a new service with the necessary files and boilerplate code.
|
|
5
5
|
*/
|
|
6
6
|
export type Schema = {
|
|
7
|
+
/**
|
|
8
|
+
* When true, the 'type' option will be appended to the generated class name. When false,
|
|
9
|
+
* only the file name will include the type.
|
|
10
|
+
*/
|
|
11
|
+
addTypeToClassName?: boolean;
|
|
7
12
|
/**
|
|
8
13
|
* Creates files at the top level of the project or the given path. If set to false, a new
|
|
9
14
|
* folder with the service's name will be created to contain the files.
|
package/service/schema.json
CHANGED
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"type": {
|
|
44
44
|
"type": "string",
|
|
45
45
|
"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`."
|
|
46
|
+
},
|
|
47
|
+
"addTypeToClassName": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"default": true,
|
|
50
|
+
"description": "When true, the 'type' option will be appended to the generated class name. When false, only the file name will include the type."
|
|
46
51
|
}
|
|
47
52
|
},
|
|
48
53
|
"required": ["name", "project"]
|
|
@@ -7,4 +7,5 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Rule } from '@angular-devkit/schematics';
|
|
9
9
|
import { Schema as ServiceWorkerOptions } from './schema';
|
|
10
|
-
|
|
10
|
+
declare const _default: (options: ServiceWorkerOptions) => Rule;
|
|
11
|
+
export default _default;
|
package/service-worker/index.js
CHANGED
|
@@ -6,50 +6,20 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
-
}
|
|
15
|
-
Object.defineProperty(o, k2, desc);
|
|
16
|
-
}) : (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
o[k2] = m[k];
|
|
19
|
-
}));
|
|
20
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
-
}) : function(o, v) {
|
|
23
|
-
o["default"] = v;
|
|
24
|
-
});
|
|
25
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
-
var ownKeys = function(o) {
|
|
27
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
-
var ar = [];
|
|
29
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
-
return ar;
|
|
31
|
-
};
|
|
32
|
-
return ownKeys(o);
|
|
33
|
-
};
|
|
34
|
-
return function (mod) {
|
|
35
|
-
if (mod && mod.__esModule) return mod;
|
|
36
|
-
var result = {};
|
|
37
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
-
__setModuleDefault(result, mod);
|
|
39
|
-
return result;
|
|
40
|
-
};
|
|
41
|
-
})();
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
42
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.default = default_1;
|
|
44
|
-
const core_1 = require("@angular-devkit/core");
|
|
45
13
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
46
|
-
const
|
|
14
|
+
const posix_1 = require("node:path/posix");
|
|
15
|
+
const typescript_1 = __importDefault(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
47
16
|
const utility_1 = require("../utility");
|
|
48
17
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
49
18
|
const change_1 = require("../utility/change");
|
|
50
19
|
const dependency_1 = require("../utility/dependency");
|
|
51
20
|
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
|
|
52
21
|
const paths_1 = require("../utility/paths");
|
|
22
|
+
const project_1 = require("../utility/project");
|
|
53
23
|
const project_targets_1 = require("../utility/project-targets");
|
|
54
24
|
const app_config_1 = require("../utility/standalone/app_config");
|
|
55
25
|
const util_1 = require("../utility/standalone/util");
|
|
@@ -71,7 +41,7 @@ function updateAppModule(mainPath) {
|
|
|
71
41
|
addImport(host, modulePath, 'ServiceWorkerModule', '@angular/service-worker');
|
|
72
42
|
addImport(host, modulePath, 'isDevMode', '@angular/core');
|
|
73
43
|
// register SW in application module
|
|
74
|
-
const importText =
|
|
44
|
+
const importText = `
|
|
75
45
|
ServiceWorkerModule.register('ngsw-worker.js', {
|
|
76
46
|
enabled: !isDevMode(),
|
|
77
47
|
// Register the ServiceWorker as soon as the application is stable
|
|
@@ -102,53 +72,46 @@ function addProvideServiceWorker(projectName, mainPath) {
|
|
|
102
72
|
}
|
|
103
73
|
function getTsSourceFile(host, path) {
|
|
104
74
|
const content = host.readText(path);
|
|
105
|
-
const source =
|
|
75
|
+
const source = typescript_1.default.createSourceFile(path, content, typescript_1.default.ScriptTarget.Latest, true);
|
|
106
76
|
return source;
|
|
107
77
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const ngswConfigPath = (0, core_1.join)((0, core_1.normalize)(project.root), 'ngsw-config.json');
|
|
125
|
-
if (buildTarget.builder === workspace_models_1.Builders.Application ||
|
|
126
|
-
buildTarget.builder === workspace_models_1.Builders.BuildApplication) {
|
|
127
|
-
const productionConf = buildTarget.configurations?.production;
|
|
128
|
-
if (productionConf) {
|
|
129
|
-
productionConf.serviceWorker = ngswConfigPath;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
buildOptions.serviceWorker = true;
|
|
134
|
-
buildOptions.ngswConfigPath = ngswConfigPath;
|
|
78
|
+
exports.default = (0, project_1.createProjectSchematic)(async (options, { project, workspace, tree }) => {
|
|
79
|
+
if (project.extensions.projectType !== 'application') {
|
|
80
|
+
throw new schematics_1.SchematicsException(`Service worker requires a project type of "application".`);
|
|
81
|
+
}
|
|
82
|
+
const buildTarget = project.targets.get('build');
|
|
83
|
+
if (!buildTarget) {
|
|
84
|
+
throw (0, project_targets_1.targetBuildNotFoundError)();
|
|
85
|
+
}
|
|
86
|
+
const buildOptions = buildTarget.options;
|
|
87
|
+
const browserEntryPoint = await (0, util_1.getMainFilePath)(tree, options.project);
|
|
88
|
+
const ngswConfigPath = (0, posix_1.join)(project.root, 'ngsw-config.json');
|
|
89
|
+
if (buildTarget.builder === workspace_models_1.Builders.Application ||
|
|
90
|
+
buildTarget.builder === workspace_models_1.Builders.BuildApplication) {
|
|
91
|
+
const productionConf = buildTarget.configurations?.production;
|
|
92
|
+
if (productionConf) {
|
|
93
|
+
productionConf.serviceWorker = ngswConfigPath;
|
|
135
94
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
buildOptions.serviceWorker = true;
|
|
98
|
+
buildOptions.ngswConfigPath = ngswConfigPath;
|
|
99
|
+
}
|
|
100
|
+
await (0, utility_1.writeWorkspace)(tree, workspace);
|
|
101
|
+
return (0, schematics_1.chain)([
|
|
102
|
+
addDependencies(),
|
|
103
|
+
(0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
104
|
+
(0, schematics_1.applyTemplates)({
|
|
105
|
+
...options,
|
|
106
|
+
relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(project.root),
|
|
107
|
+
}),
|
|
108
|
+
(0, schematics_1.move)(project.root),
|
|
109
|
+
])),
|
|
110
|
+
(0, ng_ast_utils_1.isStandaloneApp)(tree, browserEntryPoint)
|
|
111
|
+
? addProvideServiceWorker(options.project, browserEntryPoint)
|
|
112
|
+
: updateAppModule(browserEntryPoint),
|
|
113
|
+
]);
|
|
114
|
+
});
|
|
152
115
|
function addImport(host, filePath, symbolName, moduleName) {
|
|
153
116
|
const moduleSource = getTsSourceFile(host, filePath);
|
|
154
117
|
const change = (0, ast_utils_1.insertImport)(moduleSource, filePath, symbolName, moduleName);
|
package/ssr/index.d.ts
CHANGED
package/ssr/index.js
CHANGED
|
@@ -7,17 +7,16 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.dev/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.default = default_1;
|
|
11
10
|
const core_1 = require("@angular-devkit/core");
|
|
12
11
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
13
|
-
const
|
|
12
|
+
const posix_1 = require("node:path/posix");
|
|
14
13
|
const utility_1 = require("../utility");
|
|
15
14
|
const json_file_1 = require("../utility/json-file");
|
|
16
15
|
const latest_versions_1 = require("../utility/latest-versions");
|
|
17
16
|
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
|
|
17
|
+
const project_1 = require("../utility/project");
|
|
18
18
|
const project_targets_1 = require("../utility/project-targets");
|
|
19
19
|
const util_1 = require("../utility/standalone/util");
|
|
20
|
-
const workspace_1 = require("../utility/workspace");
|
|
21
20
|
const SERVE_SSR_TARGET_NAME = 'serve-ssr';
|
|
22
21
|
const PRERENDER_TARGET_NAME = 'prerender';
|
|
23
22
|
const DEFAULT_BROWSER_DIR = 'browser';
|
|
@@ -48,7 +47,7 @@ async function getApplicationBuilderOutputPaths(host, projectName) {
|
|
|
48
47
|
}
|
|
49
48
|
let { outputPath } = architectTarget.options;
|
|
50
49
|
// Use default if not explicitly specified
|
|
51
|
-
outputPath ??=
|
|
50
|
+
outputPath ??= (0, posix_1.join)('dist', projectName);
|
|
52
51
|
const defaultDirs = {
|
|
53
52
|
server: DEFAULT_SERVER_DIR,
|
|
54
53
|
browser: DEFAULT_BROWSER_DIR,
|
|
@@ -78,7 +77,7 @@ function addScriptsRule({ project }, isUsingApplicationBuilder) {
|
|
|
78
77
|
if (isUsingApplicationBuilder) {
|
|
79
78
|
const { base, server } = await getApplicationBuilderOutputPaths(host, project);
|
|
80
79
|
pkg.scripts ??= {};
|
|
81
|
-
pkg.scripts[`serve:ssr:${project}`] = `node ${
|
|
80
|
+
pkg.scripts[`serve:ssr:${project}`] = `node ${(0, posix_1.join)(base, server)}/server.mjs`;
|
|
82
81
|
}
|
|
83
82
|
else {
|
|
84
83
|
const serverDist = await getLegacyOutputPaths(host, project, 'server');
|
|
@@ -128,7 +127,7 @@ function updateApplicationBuilderWorkspaceConfigRule(projectSourceRoot, options,
|
|
|
128
127
|
if (outputPath && (0, core_1.isJsonObject)(outputPath)) {
|
|
129
128
|
if (outputPath.browser === '') {
|
|
130
129
|
const base = outputPath.base;
|
|
131
|
-
logger.warn(`The output location of the browser build has been updated from "${base}" to "${
|
|
130
|
+
logger.warn(`The output location of the browser build has been updated from "${base}" to "${(0, posix_1.join)(base, DEFAULT_BROWSER_DIR)}".
|
|
132
131
|
You might need to adjust your deployment pipeline.`);
|
|
133
132
|
if ((outputPath.media && outputPath.media !== DEFAULT_MEDIA_DIR) ||
|
|
134
133
|
(outputPath.server && outputPath.server !== DEFAULT_SERVER_DIR)) {
|
|
@@ -144,7 +143,7 @@ function updateApplicationBuilderWorkspaceConfigRule(projectSourceRoot, options,
|
|
|
144
143
|
outputPath,
|
|
145
144
|
outputMode: 'server',
|
|
146
145
|
ssr: {
|
|
147
|
-
entry: (0,
|
|
146
|
+
entry: (0, posix_1.join)(projectSourceRoot, 'server.ts'),
|
|
148
147
|
},
|
|
149
148
|
};
|
|
150
149
|
});
|
|
@@ -158,7 +157,7 @@ function updateWebpackBuilderWorkspaceConfigRule(projectSourceRoot, options) {
|
|
|
158
157
|
}
|
|
159
158
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
160
159
|
const serverTarget = project.targets.get('server');
|
|
161
|
-
(serverTarget.options ??= {}).main =
|
|
160
|
+
(serverTarget.options ??= {}).main = (0, posix_1.join)(projectSourceRoot, 'server.ts');
|
|
162
161
|
const serveSSRTarget = project.targets.get(SERVE_SSR_TARGET_NAME);
|
|
163
162
|
if (serveSSRTarget) {
|
|
164
163
|
return;
|
|
@@ -260,7 +259,7 @@ function addServerFile(projectSourceRoot, options, isStandalone) {
|
|
|
260
259
|
: await getLegacyOutputPaths(host, projectName, 'build');
|
|
261
260
|
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(`./files/${usingApplicationBuilder ? 'application-builder' : 'server-builder'}`), [
|
|
262
261
|
(0, schematics_1.applyTemplates)({
|
|
263
|
-
...
|
|
262
|
+
...schematics_1.strings,
|
|
264
263
|
...options,
|
|
265
264
|
browserDistDirectory,
|
|
266
265
|
isStandalone,
|
|
@@ -269,34 +268,27 @@ function addServerFile(projectSourceRoot, options, isStandalone) {
|
|
|
269
268
|
]));
|
|
270
269
|
};
|
|
271
270
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
]),
|
|
297
|
-
addServerFile(sourceRoot, options, isStandalone),
|
|
298
|
-
addScriptsRule(options, usingApplicationBuilder),
|
|
299
|
-
addDependencies(options, usingApplicationBuilder),
|
|
300
|
-
]);
|
|
301
|
-
};
|
|
302
|
-
}
|
|
271
|
+
exports.default = (0, project_1.createProjectSchematic)(async (options, { project, tree, context }) => {
|
|
272
|
+
const browserEntryPoint = await (0, util_1.getMainFilePath)(tree, options.project);
|
|
273
|
+
const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(tree, browserEntryPoint);
|
|
274
|
+
const usingApplicationBuilder = (0, project_targets_1.isUsingApplicationBuilder)(project);
|
|
275
|
+
const sourceRoot = project.sourceRoot ?? (0, posix_1.join)(project.root, 'src');
|
|
276
|
+
return (0, schematics_1.chain)([
|
|
277
|
+
(0, schematics_1.schematic)('server', {
|
|
278
|
+
...options,
|
|
279
|
+
skipInstall: true,
|
|
280
|
+
}),
|
|
281
|
+
...(usingApplicationBuilder
|
|
282
|
+
? [
|
|
283
|
+
updateApplicationBuilderWorkspaceConfigRule(sourceRoot, options, context),
|
|
284
|
+
updateApplicationBuilderTsConfigRule(options),
|
|
285
|
+
]
|
|
286
|
+
: [
|
|
287
|
+
updateWebpackBuilderServerTsConfigRule(options),
|
|
288
|
+
updateWebpackBuilderWorkspaceConfigRule(sourceRoot, options),
|
|
289
|
+
]),
|
|
290
|
+
addServerFile(sourceRoot, options, isStandalone),
|
|
291
|
+
addScriptsRule(options, usingApplicationBuilder),
|
|
292
|
+
addDependencies(options, usingApplicationBuilder),
|
|
293
|
+
]);
|
|
294
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
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 { type Rule } from '@angular-devkit/schematics';
|
|
9
|
+
declare const _default: (options: {
|
|
10
|
+
project: string;
|
|
11
|
+
}) => Rule;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
14
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
15
|
+
const posix_1 = require("node:path/posix");
|
|
16
|
+
const utility_1 = require("../utility");
|
|
17
|
+
const json_file_1 = require("../utility/json-file");
|
|
18
|
+
const latest_versions_1 = require("../utility/latest-versions");
|
|
19
|
+
const project_1 = require("../utility/project");
|
|
20
|
+
const TAILWIND_DEPENDENCIES = ['tailwindcss', '@tailwindcss/postcss', 'postcss'];
|
|
21
|
+
const POSTCSS_CONFIG_FILES = ['.postcssrc.json', 'postcss.config.json'];
|
|
22
|
+
function addTailwindStyles(options, project) {
|
|
23
|
+
return async (tree) => {
|
|
24
|
+
const buildTarget = project.targets.get('build');
|
|
25
|
+
if (!buildTarget) {
|
|
26
|
+
throw new schematics_1.SchematicsException(`Project "${options.project}" does not have a build target.`);
|
|
27
|
+
}
|
|
28
|
+
const styles = buildTarget.options?.['styles'];
|
|
29
|
+
let stylesheetPath;
|
|
30
|
+
if (styles) {
|
|
31
|
+
stylesheetPath = styles
|
|
32
|
+
.map((s) => (typeof s === 'string' ? s : s.input))
|
|
33
|
+
.find((p) => p.endsWith('.css'));
|
|
34
|
+
}
|
|
35
|
+
if (!stylesheetPath) {
|
|
36
|
+
const newStylesheetPath = (0, posix_1.join)(project.sourceRoot ?? 'src', 'tailwind.css');
|
|
37
|
+
tree.create(newStylesheetPath, '@import "tailwindcss";\n');
|
|
38
|
+
return (0, utility_1.updateWorkspace)((workspace) => {
|
|
39
|
+
const project = workspace.projects.get(options.project);
|
|
40
|
+
if (project) {
|
|
41
|
+
const buildTarget = project.targets.get('build');
|
|
42
|
+
(0, node_assert_1.default)(buildTarget, 'Build target should still be present');
|
|
43
|
+
// Update main styles
|
|
44
|
+
const buildOptions = buildTarget.options;
|
|
45
|
+
(0, node_assert_1.default)(buildOptions, 'Build options should still be present');
|
|
46
|
+
const existingStyles = buildOptions['styles'] ?? [];
|
|
47
|
+
buildOptions['styles'] = [newStylesheetPath, ...existingStyles];
|
|
48
|
+
// Update configuration styles
|
|
49
|
+
if (buildTarget.configurations) {
|
|
50
|
+
for (const config of Object.values(buildTarget.configurations)) {
|
|
51
|
+
if (config && 'styles' in config) {
|
|
52
|
+
const existingStyles = config['styles'] ?? [];
|
|
53
|
+
config['styles'] = [newStylesheetPath, ...existingStyles];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
let stylesheetContent = tree.readText(stylesheetPath);
|
|
62
|
+
if (!stylesheetContent.includes('@import "tailwindcss";')) {
|
|
63
|
+
stylesheetContent += '\n@import "tailwindcss";\n';
|
|
64
|
+
tree.overwrite(stylesheetPath, stylesheetContent);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function managePostCssConfiguration(project) {
|
|
70
|
+
return async (tree) => {
|
|
71
|
+
const searchPaths = ['/', project.root]; // Workspace root and project root
|
|
72
|
+
for (const path of searchPaths) {
|
|
73
|
+
for (const configFile of POSTCSS_CONFIG_FILES) {
|
|
74
|
+
const fullPath = (0, posix_1.join)(path, configFile);
|
|
75
|
+
if (tree.exists(fullPath)) {
|
|
76
|
+
const postcssConfig = new json_file_1.JSONFile(tree, fullPath);
|
|
77
|
+
const tailwindPluginPath = ['plugins', '@tailwindcss/postcss'];
|
|
78
|
+
if (postcssConfig.get(tailwindPluginPath) === undefined) {
|
|
79
|
+
postcssConfig.modify(tailwindPluginPath, {});
|
|
80
|
+
}
|
|
81
|
+
// Config found and handled
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// No existing config found, so create one from the template
|
|
87
|
+
const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
88
|
+
(0, schematics_1.applyTemplates)({
|
|
89
|
+
...schematics_1.strings,
|
|
90
|
+
}),
|
|
91
|
+
(0, schematics_1.move)(project.root),
|
|
92
|
+
]);
|
|
93
|
+
return (0, schematics_1.mergeWith)(templateSource);
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
exports.default = (0, project_1.createProjectSchematic)((options, { project }) => {
|
|
97
|
+
return (0, schematics_1.chain)([
|
|
98
|
+
addTailwindStyles(options, project),
|
|
99
|
+
managePostCssConfiguration(project),
|
|
100
|
+
...TAILWIND_DEPENDENCIES.map((name) => (0, utility_1.addDependency)(name, latest_versions_1.latestVersions[name], {
|
|
101
|
+
type: utility_1.DependencyType.Dev,
|
|
102
|
+
existing: utility_1.ExistingBehavior.Skip,
|
|
103
|
+
})),
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema",
|
|
3
|
+
"title": "Tailwind CSS Schematic",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"project": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"description": "The name of the project.",
|
|
9
|
+
"$default": {
|
|
10
|
+
"$source": "projectName"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"required": ["project"]
|
|
15
|
+
}
|