ngx-theme-stack 2.1.0 → 3.1.0
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/README.md +63 -11
- package/package.json +3 -3
- package/schematics/ng-add/anti-flash.js +2 -23
- package/schematics/ng-add/anti-flash.js.map +1 -1
- package/schematics/ng-add/app-config.js +0 -2
- package/schematics/ng-add/app-config.js.map +1 -1
- package/schematics/ng-add/index.js +14 -17
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/utils.d.ts +1 -1
- package/schematics/ng-add/utils.js +2 -1
- package/schematics/ng-add/utils.js.map +1 -1
- package/schematics/sync/index.js +100 -111
- package/schematics/sync/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ngx-theme-stack 🎨
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
A simple and powerful headless theme manager for **Angular**. Built for performance and SSR support.
|
|
6
6
|
|
|
@@ -40,6 +40,17 @@ When running `ng add`, you will be presented with two configuration options:
|
|
|
40
40
|
- Decide how to apply themes: via classes (`class`), attributes (`data-theme`), or both.
|
|
41
41
|
- **Pick your strategy**: `critters` for modern SSR/SSG apps or `blocking` for standard CSS loading.
|
|
42
42
|
|
|
43
|
+
## 🤖 What does `ng add` do for you?
|
|
44
|
+
|
|
45
|
+
To provide a "Zero Config" experience, the installation command automates the following:
|
|
46
|
+
|
|
47
|
+
1. **`package.json`**: Adds a `"prebuild"` script that executes the synchronization automatically before every build.
|
|
48
|
+
2. **`angular.json`**:
|
|
49
|
+
- Adds `src/themes.css` to the global styles list.
|
|
50
|
+
- Configures the `inlineCritical` optimization based on your selected strategy.
|
|
51
|
+
3. **`index.html`**: Injects the marker and the blocking anti-flash script into the `<head>`.
|
|
52
|
+
4. **`themes.css`**: Creates a base file with selectors ready for you to define your variables.
|
|
53
|
+
|
|
43
54
|
## 🏗️ Architecture & Extensibility
|
|
44
55
|
|
|
45
56
|
The library is designed to be flexible. The **`CoreThemeService`** is the foundation:
|
|
@@ -63,8 +74,37 @@ For common use cases, we include three services with predefined logic:
|
|
|
63
74
|
| :-------------- | :-------- |
|
|
64
75
|
| **Angular 21** | ✅ Stable |
|
|
65
76
|
| **Angular 20** | ✅ Stable |
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
|
|
78
|
+
## ⚙️ Configuration
|
|
79
|
+
|
|
80
|
+
The best way to configure the library is during installation, but you can also manually adjust the providers in your `app.config.ts`:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { provideThemeStack } from 'ngx-theme-stack';
|
|
84
|
+
|
|
85
|
+
export const appConfig: ApplicationConfig = {
|
|
86
|
+
providers: [
|
|
87
|
+
provideThemeStack({
|
|
88
|
+
themes: ['light', 'dark', 'sunset'], // Your theme identifiers
|
|
89
|
+
defaultTheme: 'system', // Initial fallback ('system' resolves via matchMedia)
|
|
90
|
+
mode: 'class', // 'class', 'attribute' or 'both'
|
|
91
|
+
strategy: 'critters', // 'critters' (SSR) or 'blocking' (Standard SPA)
|
|
92
|
+
storageKey: 'ngx-theme-stack-theme' // LocalStorage key
|
|
93
|
+
})
|
|
94
|
+
]
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
| Option | Type | Default | Description |
|
|
99
|
+
| :--- | :--- | :--- | :--- |
|
|
100
|
+
| `themes` | `string[]` | `['light', 'dark', 'system']` | List of supported theme identifiers. |
|
|
101
|
+
| `defaultTheme` | `string` | `'system'` | Theme used on first visit or when no preference is saved. |
|
|
102
|
+
| `mode` | `NgMode` | `'class'` | How the theme is applied: `class`, `attribute` (`data-theme`), or `both`. |
|
|
103
|
+
| `strategy` | `NgStrategy`| `'critters'` | Anti-flash performance strategy: `critters` (inlined CSS) or `blocking`. |
|
|
104
|
+
| `storageKey` | `string` | `'ngx-theme-stack-theme'` | Key used to persist theme preference in `localStorage`. |
|
|
105
|
+
|
|
106
|
+
> [!IMPORTANT]
|
|
107
|
+
> Whenever you update these settings, run `ng generate ngx-theme-stack:sync` to ensure your `index.html` is updated with the correct anti-flash script.
|
|
68
108
|
|
|
69
109
|
## 🛠️ Basic Usage
|
|
70
110
|
|
|
@@ -144,17 +184,25 @@ The library targets the `<html>` element. Based on your configured `mode`, you s
|
|
|
144
184
|
--text-color: #ffffff;
|
|
145
185
|
}
|
|
146
186
|
|
|
147
|
-
|
|
148
|
-
[data-theme='sunset'] {
|
|
187
|
+
.sunset {
|
|
149
188
|
--bg-color: #ff5f6d;
|
|
150
189
|
--text-color: #ffffff;
|
|
151
190
|
}
|
|
152
191
|
|
|
153
|
-
/*
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
192
|
+
/* Using Attributes (Attribute Mode) */
|
|
193
|
+
[data-theme='light'] {
|
|
194
|
+
--bg-color: #ffffff;
|
|
195
|
+
--text-color: #333333;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
[data-theme='dark'] {
|
|
199
|
+
--bg-color: #121212;
|
|
200
|
+
--text-color: #ffffff;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
[data-theme='sunset'] {
|
|
204
|
+
--bg-color: #ff5f6d;
|
|
205
|
+
--text-color: #ffffff;
|
|
158
206
|
}
|
|
159
207
|
```
|
|
160
208
|
|
|
@@ -208,7 +256,11 @@ This approach keeps your UI code clean, semantic, and fully synchronized with `n
|
|
|
208
256
|
1. **Critters (Default)**: Best for SSR/Static sites. It uses hidden markers to trick the Angular builder into inlining all your theme CSS variables directly in the HTML `<head>`. Result: **Zero network requests for CSS variables.**
|
|
209
257
|
2. **Blocking**: Best for standard SPAs. It loads the `themes.css` file as a traditional blocking resource.
|
|
210
258
|
|
|
211
|
-
The `ng-add` schematic helps you configure the right one automatically.
|
|
259
|
+
The `ng-add` schematic helps you configure the right one automatically. You can always use the **Sync Command** to refresh your `index.html` if you change your configuration:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
ng generate ngx-theme-stack:sync --project YOUR_PROJECT_NAME
|
|
263
|
+
```
|
|
212
264
|
|
|
213
265
|
## 📄 License
|
|
214
266
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-theme-stack",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "A stack of themes for Angular applications.",
|
|
5
5
|
"schematics": "./schematics/collection.json",
|
|
6
6
|
"ng-add": {
|
|
7
7
|
"save": "devDependencies"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"@angular/common": "^
|
|
11
|
-
"@angular/core": "^
|
|
10
|
+
"@angular/common": "^20.0.0 || ^21.0.0",
|
|
11
|
+
"@angular/core": "^20.0.0 || ^21.0.0"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"tslib": "^2.3.0"
|
|
@@ -55,17 +55,6 @@ function patchIndexHtml(tree, context, sourceRoot, options) {
|
|
|
55
55
|
if (!tree.exists(path))
|
|
56
56
|
continue;
|
|
57
57
|
const content = tree.readText(path);
|
|
58
|
-
// ── CSP Detection ────────────────────────────────────────────────────────
|
|
59
|
-
const hasCspMeta = content.includes('Content-Security-Policy') || content.includes('content-security-policy');
|
|
60
|
-
if (hasCspMeta) {
|
|
61
|
-
context.logger.warn(`⚠ A Content-Security-Policy meta tag was detected in ${path}.\n` +
|
|
62
|
-
` Inline scripts may be blocked by your CSP.\n` +
|
|
63
|
-
` Options:\n` +
|
|
64
|
-
` 1. Add a nonce to the injected <script> tag and allow it in your CSP.\n` +
|
|
65
|
-
` 2. Add the script hash to your CSP: script-src 'sha256-<HASH>'.\n` +
|
|
66
|
-
` 3. Allow 'unsafe-inline' (not recommended for production).\n` +
|
|
67
|
-
` See: https://angular.dev/guide/security#content-security-policy`);
|
|
68
|
-
}
|
|
69
58
|
const scriptTag = `\n <!-- ngx-theme-stack anti-flash -->\n <script>${buildAntiFlashScript({
|
|
70
59
|
storageKey: options.storageKey,
|
|
71
60
|
defaultTheme: options.defaultTheme,
|
|
@@ -73,14 +62,12 @@ function patchIndexHtml(tree, context, sourceRoot, options) {
|
|
|
73
62
|
})}</script>`;
|
|
74
63
|
let updated = content;
|
|
75
64
|
// ── 1. Update Anti-Flash Script ──────────────────────────────────────────
|
|
76
|
-
const SCRIPT_BLOCK_RE =
|
|
65
|
+
const SCRIPT_BLOCK_RE = /<!--\s*ngx-theme-stack\s*anti-flash\s*-->\s*<script[^>]*>[\s\S]*?<\/script>/;
|
|
77
66
|
if (SCRIPT_BLOCK_RE.test(updated)) {
|
|
78
67
|
updated = updated.replace(SCRIPT_BLOCK_RE, scriptTag);
|
|
79
|
-
context.logger.info(`✔ Updated anti-flash script in ${path}`);
|
|
80
68
|
}
|
|
81
69
|
else {
|
|
82
70
|
updated = updated.replace('<head>', `<head>${scriptTag}`);
|
|
83
|
-
context.logger.info(`✔ Injected anti-flash script into ${path}`);
|
|
84
71
|
}
|
|
85
72
|
// ── 2. Update Critters Trick ─────────────────────────────────────────────
|
|
86
73
|
const CRITTERS_BLOCK_RE = /<!-- ngx-theme-stack critters-trick -->[\s\S]*?<!-- \/ngx-theme-stack critters-trick -->/;
|
|
@@ -101,15 +88,12 @@ function patchIndexHtml(tree, context, sourceRoot, options) {
|
|
|
101
88
|
` <!-- /ngx-theme-stack critters-trick -->`;
|
|
102
89
|
if (CRITTERS_BLOCK_RE.test(updated)) {
|
|
103
90
|
updated = updated.replace(CRITTERS_BLOCK_RE, crittersBlock);
|
|
104
|
-
context.logger.info(`✔ Updated Critters-trick block in ${path}`);
|
|
105
91
|
}
|
|
106
92
|
else if (CRITTERS_ID_RE.test(updated)) {
|
|
107
93
|
updated = updated.replace(CRITTERS_ID_RE, crittersBlock);
|
|
108
|
-
context.logger.info(`✔ Wrapped existing Critters-trick div with markers in ${path}`);
|
|
109
94
|
}
|
|
110
95
|
else {
|
|
111
96
|
updated = updated.replace('</body>', ` ${crittersBlock}\n </body>`);
|
|
112
|
-
context.logger.info(`✔ Injected Critters-trick block before </body> in ${path}`);
|
|
113
97
|
}
|
|
114
98
|
}
|
|
115
99
|
else {
|
|
@@ -120,16 +104,11 @@ function patchIndexHtml(tree, context, sourceRoot, options) {
|
|
|
120
104
|
else if (CRITTERS_ID_RE.test(updated)) {
|
|
121
105
|
updated = updated.replace(CRITTERS_ID_RE, '');
|
|
122
106
|
}
|
|
123
|
-
context.logger.info(`✔ Removed Critters-trick from ${path}`);
|
|
124
107
|
}
|
|
125
108
|
tree.overwrite(path, updated);
|
|
126
|
-
if (hasCspMeta) {
|
|
127
|
-
context.logger.warn(` → Remember to allow the inline script in your CSP before deploying.`);
|
|
128
|
-
}
|
|
129
109
|
return;
|
|
130
110
|
}
|
|
131
111
|
context.logger.warn(`⚠ Could not find index.html (tried: ${candidates.join(', ')}).\n` +
|
|
132
|
-
` Add the anti-flash script manually to the <head> of your index.html
|
|
133
|
-
` See: https://github.com/your-org/ngx-theme-stack#anti-flash`);
|
|
112
|
+
` Add the anti-flash script manually to the <head> of your index.html.`);
|
|
134
113
|
}
|
|
135
114
|
//# sourceMappingURL=anti-flash.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anti-flash.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/anti-flash.ts"],"names":[],"mappings":";;AA0DA,
|
|
1
|
+
{"version":3,"file":"anti-flash.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/anti-flash.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,6 @@ function patchAppConfig(tree, context, sourceRoot, provideCall) {
|
|
|
20
20
|
if (updated.includes('provideThemeStack')) {
|
|
21
21
|
updated = updated.replace(/provideThemeStack\s*\([\s\S]*?\)/, provideCall);
|
|
22
22
|
tree.overwrite(filePath, updated);
|
|
23
|
-
context.logger.info(`✔ Updated provideThemeStack configuration in ${filePath}`);
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
26
25
|
// Add import if missing
|
|
@@ -44,7 +43,6 @@ function patchAppConfig(tree, context, sourceRoot, provideCall) {
|
|
|
44
43
|
updated = updated.replace(/bootstrapApplication\s*\(\s*([^,)]+)\s*\)/, `bootstrapApplication($1, {\n providers: [\n ${provideCall}\n ]\n})`);
|
|
45
44
|
}
|
|
46
45
|
tree.overwrite(filePath, updated);
|
|
47
|
-
context.logger.info(`✔ Added ${provideCall} to ${filePath}`);
|
|
48
46
|
return;
|
|
49
47
|
}
|
|
50
48
|
context.logger.warn(`⚠ Could not find app.config.ts / main.ts / app.module.ts.\n` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/app-config.ts"],"names":[],"mappings":";;AAWA,
|
|
1
|
+
{"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/app-config.ts"],"names":[],"mappings":";;AAWA,wCA0DC;AAnED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAC5B,IAAU,EACV,OAAyB,EACzB,UAAkB,EAClB,WAAmB;IAEnB,MAAM,UAAU,GAAG,CAAC,GAAG,UAAU,oBAAoB,EAAE,GAAG,UAAU,UAAU,EAAE,GAAG,UAAU,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhK,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,SAAS;QAErC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAExC,IAAI,OAAO,GAAG,OAAO,CAAC;QAEtB,IAAI,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,EAAE,WAAW,CAAC,CAAC;YAC3E,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAChD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC9C,OAAO;gBACL,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;oBACzB,wDAAwD;oBACxD,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC3B,CAAC;QAED,8BAA8B;QAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,6BAA6B,EAC7B,CAAC,EAAU,EAAE,KAAa,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAChF,OAAO,eAAe,OAAO,GAAG,GAAG,GAAG,WAAW,OAAO,CAAC;YAC3D,CAAC,CACF,CAAC;QACJ,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;YACpD,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,2CAA2C,EAC3C,mDAAmD,WAAW,WAAW,CAC1E,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,6DAA6D;QAC3D,qBAAqB;QACrB,4DAA4D;QAC5D,kBAAkB,WAAW,IAAI,CACpC,CAAC;AACJ,CAAC"}
|
|
@@ -86,11 +86,12 @@ function ngAdd(options) {
|
|
|
86
86
|
let finalThemes;
|
|
87
87
|
let themesToScaffold;
|
|
88
88
|
let finalStrategy;
|
|
89
|
+
const changeset = [];
|
|
89
90
|
if (options.mode === 'quick') {
|
|
90
91
|
const themes = [...constants_1.DEFAULT_THEMES];
|
|
91
92
|
const { defaultTheme, storageKey, mode } = constants_1.DEFAULTS;
|
|
92
93
|
const strategy = 'critters'; // default for quick
|
|
93
|
-
provideCall = (0, utils_1.buildProvideCall)(defaultTheme, storageKey, mode, themes);
|
|
94
|
+
provideCall = (0, utils_1.buildProvideCall)(defaultTheme, storageKey, mode, themes, strategy);
|
|
94
95
|
scriptOptions = { storageKey, defaultTheme, mode };
|
|
95
96
|
finalThemes = themes;
|
|
96
97
|
themesToScaffold = themes.filter((t) => t !== 'system');
|
|
@@ -101,20 +102,14 @@ function ngAdd(options) {
|
|
|
101
102
|
context.logger.info('🛠 Custom setup — answer the prompts below:');
|
|
102
103
|
const opts = yield collectCustomOptions();
|
|
103
104
|
const { defaultTheme, storageKey, mode, themes, strategy } = opts;
|
|
104
|
-
|
|
105
|
-
context.logger.info(` defaultTheme : ${defaultTheme}`);
|
|
106
|
-
context.logger.info(` themes : [${themes.join(', ')}]`);
|
|
107
|
-
context.logger.info(` storageKey : ${storageKey}`);
|
|
108
|
-
context.logger.info(` mode : ${mode}`);
|
|
109
|
-
context.logger.info(` strategy : ${strategy}`);
|
|
110
|
-
provideCall = (0, utils_1.buildProvideCall)(defaultTheme, storageKey, mode, themes);
|
|
105
|
+
provideCall = (0, utils_1.buildProvideCall)(defaultTheme, storageKey, mode, themes, strategy);
|
|
111
106
|
scriptOptions = { storageKey, defaultTheme, mode };
|
|
112
107
|
finalThemes = themes;
|
|
113
108
|
themesToScaffold = themes.filter((t) => t !== 'system');
|
|
114
109
|
finalStrategy = strategy;
|
|
115
110
|
}
|
|
116
111
|
return (0, schematics_1.chain)([
|
|
117
|
-
(t
|
|
112
|
+
(t) => {
|
|
118
113
|
const themesPath = `${projectSourceRoot}/themes.css`;
|
|
119
114
|
if (!t.exists(themesPath)) {
|
|
120
115
|
let content = '/* ngx-theme-stack tokens */\n\n';
|
|
@@ -128,13 +123,10 @@ function ngAdd(options) {
|
|
|
128
123
|
}
|
|
129
124
|
});
|
|
130
125
|
t.create(themesPath, content);
|
|
131
|
-
|
|
132
|
-
context.logger.info(`\u001b[32m✔ Created ${themesPath} with your theme selectors.\u001b[0m`);
|
|
126
|
+
changeset.push(` \u001b[36mA\u001b[0m ${themesPath.replace(/^\//, '')} (theme tokens)`);
|
|
133
127
|
}
|
|
134
128
|
else {
|
|
135
|
-
|
|
136
|
-
context.logger.info(`\u001b[33mℹ ${themesPath} already exists. Skipping creation to preserve your styles.\u001b[0m`);
|
|
137
|
-
context.logger.info(` Tip: Make sure to manually add selectors (class or attribute) for any new themes.`);
|
|
129
|
+
changeset.push(` \u001b[90mℹ\u001b[0m ${themesPath.replace(/^\//, '')} (already exists)`);
|
|
138
130
|
}
|
|
139
131
|
},
|
|
140
132
|
(t) => {
|
|
@@ -145,9 +137,10 @@ function ngAdd(options) {
|
|
|
145
137
|
pkg.scripts = pkg.scripts || {};
|
|
146
138
|
pkg.scripts.prebuild = `ng generate ngx-theme-stack:sync --project ${projectName}`;
|
|
147
139
|
t.overwrite(pkgPath, JSON.stringify(pkg, null, 2));
|
|
140
|
+
changeset.push(' \u001b[33mM\u001b[0m package.json (prebuild script)');
|
|
148
141
|
}
|
|
149
142
|
},
|
|
150
|
-
(t
|
|
143
|
+
(t) => {
|
|
151
144
|
var _a;
|
|
152
145
|
const workspaceConfig = t.read('/angular.json');
|
|
153
146
|
if (workspaceConfig) {
|
|
@@ -171,16 +164,20 @@ function ngAdd(options) {
|
|
|
171
164
|
styles: { inlineCritical: false },
|
|
172
165
|
};
|
|
173
166
|
}
|
|
174
|
-
context.logger.info(`✔ Disabled inlineCritical in angular.json for blocking strategy.`);
|
|
175
167
|
}
|
|
176
168
|
t.overwrite('/angular.json', JSON.stringify(workspace, null, 2));
|
|
169
|
+
changeset.push(' \u001b[33mM\u001b[0m angular.json (styles & optimization)');
|
|
177
170
|
}
|
|
178
171
|
},
|
|
179
172
|
(t, ctx) => {
|
|
180
173
|
(0, app_config_1.patchAppConfig)(t, ctx, projectSourceRoot, provideCall);
|
|
174
|
+
changeset.push(' \u001b[33mM\u001b[0m app.config.ts (provided theme stack)');
|
|
181
175
|
(0, anti_flash_1.patchIndexHtml)(t, ctx, projectSourceRoot, Object.assign(Object.assign({}, scriptOptions), { themes: finalThemes, strategy: options.strategy || finalStrategy }));
|
|
176
|
+
changeset.push(' \u001b[33mM\u001b[0m index.html (injected anti-flash)');
|
|
177
|
+
ctx.logger.info('\u001b[1mChangeset:\u001b[0m');
|
|
178
|
+
changeset.forEach((entry) => ctx.logger.info(entry));
|
|
182
179
|
ctx.logger.info('');
|
|
183
|
-
ctx.logger.info('
|
|
180
|
+
ctx.logger.info('\u001b[1m\u001b[32m🏁 Done.\u001b[0m');
|
|
184
181
|
ctx.logger.info('');
|
|
185
182
|
},
|
|
186
183
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/index.ts"],"names":[],"mappings":";;;;;;;;;;;AAiEA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,4 +12,4 @@ export declare function ask(rl: readline.Interface, question: string): Promise<s
|
|
|
12
12
|
* If the input is invalid or ignored, the default index item is returned.
|
|
13
13
|
*/
|
|
14
14
|
export declare function askList(rl: readline.Interface, label: string, items: readonly string[], defaultIndex?: number): Promise<string>;
|
|
15
|
-
export declare function buildProvideCall(defaultTheme: string, storageKey: string, mode: string, themes: string[]): string;
|
|
15
|
+
export declare function buildProvideCall(defaultTheme: string, storageKey: string, mode: string, themes: string[], strategy: string): string;
|
|
@@ -39,7 +39,7 @@ function askList(rl_1, label_1, items_1) {
|
|
|
39
39
|
return isNaN(n) || n < 1 || n > items.length ? items[defaultIndex] : items[n - 1];
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
function buildProvideCall(defaultTheme, storageKey, mode, themes) {
|
|
42
|
+
function buildProvideCall(defaultTheme, storageKey, mode, themes, strategy) {
|
|
43
43
|
const themesArr = themes.map((t) => `'${t}'`).join(', ');
|
|
44
44
|
return [
|
|
45
45
|
'provideThemeStack({',
|
|
@@ -47,6 +47,7 @@ function buildProvideCall(defaultTheme, storageKey, mode, themes) {
|
|
|
47
47
|
` defaultTheme: '${defaultTheme}',`,
|
|
48
48
|
` storageKey: '${storageKey}',`,
|
|
49
49
|
` mode: '${mode}',`,
|
|
50
|
+
` strategy: '${strategy}',`,
|
|
50
51
|
' })',
|
|
51
52
|
].join('\n');
|
|
52
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/utils.ts"],"names":[],"mappings":";;;;;;;;;;;AAMA,4BAEC;AAKD,kBAEC;AAMD,0BAWC;AAED,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/ng-add/utils.ts"],"names":[],"mappings":";;;;;;;;;;;AAMA,4BAEC;AAKD,kBAEC;AAMD,0BAWC;AAED,4CAiBC;AAnDD,qCAAqC;AAGrC;;GAEG;AACH,SAAgB,QAAQ;IACtB,OAAO,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,SAAgB,GAAG,CAAC,EAAsB,EAAE,QAAgB;IAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,SAAsB,OAAO;yDAC3B,EAAsB,EACtB,KAAa,EACb,KAAwB,EACxB,YAAY,GAAG,CAAC;QAEhB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;QAC5E,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,aAAa,YAAY,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,CAAC;CAAA;AAED,SAAgB,gBAAgB,CAC9B,YAAoB,EACpB,UAAkB,EAClB,IAAY,EACZ,MAAgB,EAChB,QAAgB;IAEhB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO;QACL,qBAAqB;QACrB,kBAAkB,SAAS,IAAI;QAC/B,wBAAwB,YAAY,IAAI;QACxC,sBAAsB,UAAU,IAAI;QACpC,gBAAgB,IAAI,IAAI;QACxB,oBAAoB,QAAQ,IAAI;QAChC,QAAQ;KACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
package/schematics/sync/index.js
CHANGED
|
@@ -29,7 +29,7 @@ const OPTION_STRATEGY_RE = /strategy\s*:\s*['"]([^'"]+)['"]/;
|
|
|
29
29
|
*/
|
|
30
30
|
const OPTION_THEMES_RE = /themes\s*:\s*\[([^\]]*)\]/;
|
|
31
31
|
/** Matches the complete <script> anti-flash block (identified by its marker comment). */
|
|
32
|
-
const SCRIPT_BLOCK_RE =
|
|
32
|
+
const SCRIPT_BLOCK_RE = /<!--\s*ngx-theme-stack\s*anti-flash\s*-->\s*<script[^>]*>[\s\S]*?<\/script>/;
|
|
33
33
|
/** Marker injected by ng-add that delimits the Critters Trick zone in <body>. */
|
|
34
34
|
const CRITTERS_MARKER = '<!-- ngx-theme-stack critters-trick -->';
|
|
35
35
|
/** Regex that matches the entire Critters Trick block (marker + divs). */
|
|
@@ -70,11 +70,6 @@ function extractConfig(tree, sourceRoot, context) {
|
|
|
70
70
|
.map((t) => t.trim().replace(/^['"]|['"]$/g, ''))
|
|
71
71
|
.filter(Boolean)
|
|
72
72
|
: [...constants_1.DEFAULTS.themes];
|
|
73
|
-
context.logger.info(` Detected mode : ${mode}`);
|
|
74
|
-
context.logger.info(` Detected strategy : ${strategy !== null && strategy !== void 0 ? strategy : '(not in code, using auto-detect)'}`);
|
|
75
|
-
context.logger.info(` Detected storageKey : ${storageKey}`);
|
|
76
|
-
context.logger.info(` Detected defaultTheme : ${defaultTheme}`);
|
|
77
|
-
context.logger.info(` Detected themes : [${themes.join(', ')}]`);
|
|
78
73
|
return { mode, strategy, storageKey, defaultTheme, themes };
|
|
79
74
|
}
|
|
80
75
|
// Fallback to defaults if no config file found
|
|
@@ -139,103 +134,6 @@ function buildCrittersDivs(themes, mode) {
|
|
|
139
134
|
` <!-- /ngx-theme-stack critters-trick -->`);
|
|
140
135
|
}
|
|
141
136
|
// ── index.html patching ───────────────────────────────────────────────────────
|
|
142
|
-
function syncIndexHtml(tree, context, sourceRoot, config, strategy) {
|
|
143
|
-
const candidates = [`${sourceRoot}/index.html`, 'public/index.html'].map((p) => p.startsWith('/') ? p.slice(1) : p);
|
|
144
|
-
for (const path of candidates) {
|
|
145
|
-
if (!tree.exists(path))
|
|
146
|
-
continue;
|
|
147
|
-
let content = tree.readText(path);
|
|
148
|
-
if (!content.includes('ngx-theme-stack anti-flash')) {
|
|
149
|
-
context.logger.warn(`⚠ Anti-flash script marker not found in ${path}.\n` +
|
|
150
|
-
` Run 'ng add ngx-theme-stack' first, or add the script manually.`);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
// ── 1. Sync the anti-flash JS script ───────────────────────────────────
|
|
154
|
-
const newScriptBlock = `<!-- ngx-theme-stack anti-flash -->\n <script>${buildScript(config)}</script>`;
|
|
155
|
-
const updatedScript = content.replace(SCRIPT_BLOCK_RE, newScriptBlock);
|
|
156
|
-
if (updatedScript === content) {
|
|
157
|
-
context.logger.warn(`⚠ Could not replace script block in ${path}. The format may have changed.`);
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
content = updatedScript;
|
|
161
|
-
context.logger.info(`✔ Anti-flash script synced in ${path}`);
|
|
162
|
-
// ── 2. Sync the Critters Trick divs (only for 'critters' strategy) ─────
|
|
163
|
-
if (strategy === 'critters') {
|
|
164
|
-
const crittersBlock = buildCrittersDivs(config.themes, config.mode);
|
|
165
|
-
const CRITTERS_ID_RE = /<div id="ngx-theme-stack-critters-trick"[\s\S]*?<\/div>/;
|
|
166
|
-
if (CRITTERS_BLOCK_RE.test(content)) {
|
|
167
|
-
content = content.replace(CRITTERS_BLOCK_RE, crittersBlock);
|
|
168
|
-
context.logger.info(`✔ Critters Trick block updated in ${path}`);
|
|
169
|
-
}
|
|
170
|
-
else if (CRITTERS_ID_RE.test(content)) {
|
|
171
|
-
content = content.replace(CRITTERS_ID_RE, crittersBlock);
|
|
172
|
-
context.logger.info(`✔ Critters Trick div wrapped in ${path}`);
|
|
173
|
-
}
|
|
174
|
-
else if (content.includes(CRITTERS_MARKER)) {
|
|
175
|
-
content = content.replace(CRITTERS_MARKER, crittersBlock);
|
|
176
|
-
context.logger.info(`✔ Critters Trick divs injected in ${path}`);
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
content = content.replace('</body>', ` ${crittersBlock}\n </body>`);
|
|
180
|
-
context.logger.info(`✔ Critters Trick block added before </body> in ${path}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
// blocking strategy: remove any existing Critters divs if present
|
|
185
|
-
if (CRITTERS_BLOCK_RE.test(content)) {
|
|
186
|
-
content = content.replace(CRITTERS_BLOCK_RE, '');
|
|
187
|
-
context.logger.info(`✔ Critters Trick divs removed (blocking strategy) in ${path}`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
tree.overwrite(path, content);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
context.logger.warn(`⚠ Could not find index.html (tried: ${candidates.join(', ')}).`);
|
|
194
|
-
}
|
|
195
|
-
// ── angular.json patching ───────────────────────────────────────────────────
|
|
196
|
-
function syncAngularJson(tree, context, projectName, strategy) {
|
|
197
|
-
var _a, _b;
|
|
198
|
-
const content = tree.read('/angular.json');
|
|
199
|
-
if (!content)
|
|
200
|
-
return;
|
|
201
|
-
const workspace = JSON.parse(content.toString());
|
|
202
|
-
const project = workspace.projects[projectName];
|
|
203
|
-
if (!project)
|
|
204
|
-
return;
|
|
205
|
-
const buildTarget = (_a = project.architect) === null || _a === void 0 ? void 0 : _a.build;
|
|
206
|
-
if (!buildTarget)
|
|
207
|
-
return;
|
|
208
|
-
const prodConfig = (_b = buildTarget.configurations) === null || _b === void 0 ? void 0 : _b.production;
|
|
209
|
-
if (!prodConfig)
|
|
210
|
-
return;
|
|
211
|
-
if (strategy === 'blocking') {
|
|
212
|
-
// Disable inlineCritical for blocking strategy
|
|
213
|
-
if (typeof prodConfig.optimization === 'object') {
|
|
214
|
-
prodConfig.optimization.styles = prodConfig.optimization.styles || {};
|
|
215
|
-
if (prodConfig.optimization.styles.inlineCritical !== false) {
|
|
216
|
-
prodConfig.optimization.styles.inlineCritical = false;
|
|
217
|
-
context.logger.info(`✔ Disabled inlineCritical in angular.json projects/${projectName} (production).`);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
// It's either boolean or undefined
|
|
222
|
-
prodConfig.optimization = {
|
|
223
|
-
styles: { inlineCritical: false },
|
|
224
|
-
};
|
|
225
|
-
context.logger.info(`✔ Disabled inlineCritical in angular.json projects/${projectName} (production).`);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
// Enable inlineCritical (or revert to default) for critters strategy
|
|
230
|
-
if (typeof prodConfig.optimization === 'object' && prodConfig.optimization.styles) {
|
|
231
|
-
if (prodConfig.optimization.styles.inlineCritical === false) {
|
|
232
|
-
prodConfig.optimization.styles.inlineCritical = true;
|
|
233
|
-
context.logger.info(`✔ Re-enabled inlineCritical in angular.json projects/${projectName} (production).`);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
tree.overwrite('/angular.json', JSON.stringify(workspace, null, 2));
|
|
238
|
-
}
|
|
239
137
|
// ── Schematic factory ─────────────────────────────────────────────────────────
|
|
240
138
|
/**
|
|
241
139
|
* `ng generate ngx-theme-stack:sync`
|
|
@@ -284,7 +182,7 @@ function detectStrategy(tree, sourceRoot, explicitStrategy) {
|
|
|
284
182
|
}
|
|
285
183
|
function sync(options) {
|
|
286
184
|
return (tree, context) => {
|
|
287
|
-
var _a, _b;
|
|
185
|
+
var _a, _b, _c, _d, _e, _f;
|
|
288
186
|
const workspaceConfig = tree.read('/angular.json');
|
|
289
187
|
if (!workspaceConfig) {
|
|
290
188
|
throw new Error('Could not find angular.json. Are you in an Angular workspace?');
|
|
@@ -298,16 +196,107 @@ function sync(options) {
|
|
|
298
196
|
const sourceRoot = project.sourceRoot || `${(_b = project.root) !== null && _b !== void 0 ? _b : ''}/src`;
|
|
299
197
|
const config = extractConfig(tree, sourceRoot, context);
|
|
300
198
|
const strategy = (options.strategy || config.strategy || detectStrategy(tree, sourceRoot));
|
|
199
|
+
const changeset = [];
|
|
301
200
|
context.logger.info('');
|
|
302
|
-
context.logger.info(`🔄 ngx-theme-stack sync [project: ${projectName}
|
|
303
|
-
context.logger.info('');
|
|
304
|
-
syncIndexHtml(tree, context, sourceRoot, config, strategy);
|
|
305
|
-
syncAngularJson(tree, context, projectName, strategy);
|
|
201
|
+
context.logger.info(`🔄 ngx-theme-stack — sync [project: ${projectName}]`);
|
|
306
202
|
context.logger.info('');
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
203
|
+
// ── 1. index.html ──
|
|
204
|
+
const candidates = [`${sourceRoot}/index.html`, 'public/index.html'].map((p) => p.startsWith('/') ? p.slice(1) : p);
|
|
205
|
+
for (const path of candidates) {
|
|
206
|
+
if (!tree.exists(path))
|
|
207
|
+
continue;
|
|
208
|
+
let content = tree.readText(path);
|
|
209
|
+
let changed = false;
|
|
210
|
+
if (content.includes('ngx-theme-stack anti-flash')) {
|
|
211
|
+
const newScriptBlock = `<!-- ngx-theme-stack anti-flash -->\n <script>${buildScript(config)}</script>`;
|
|
212
|
+
if (SCRIPT_BLOCK_RE.test(content)) {
|
|
213
|
+
const updatedScript = content.replace(SCRIPT_BLOCK_RE, newScriptBlock);
|
|
214
|
+
if (updatedScript !== content) {
|
|
215
|
+
content = updatedScript;
|
|
216
|
+
changed = true;
|
|
217
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (anti-flash script)`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (strategy === 'critters') {
|
|
222
|
+
const crittersBlock = buildCrittersDivs(config.themes, config.mode);
|
|
223
|
+
const CRITTERS_ID_RE = /<div id="ngx-theme-stack-critters-trick"[\s\S]*?<\/div>/;
|
|
224
|
+
if (CRITTERS_BLOCK_RE.test(content)) {
|
|
225
|
+
const updated = content.replace(CRITTERS_BLOCK_RE, crittersBlock);
|
|
226
|
+
if (updated !== content) {
|
|
227
|
+
content = updated;
|
|
228
|
+
changed = true;
|
|
229
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (critters-trick divs updated)`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else if (CRITTERS_ID_RE.test(content)) {
|
|
233
|
+
content = content.replace(CRITTERS_ID_RE, crittersBlock);
|
|
234
|
+
changed = true;
|
|
235
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (critters-trick divs wrapped)`);
|
|
236
|
+
}
|
|
237
|
+
else if (content.includes(CRITTERS_MARKER)) {
|
|
238
|
+
content = content.replace(CRITTERS_MARKER, crittersBlock);
|
|
239
|
+
changed = true;
|
|
240
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (critters-trick divs injected)`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
content = content.replace('</body>', ` ${crittersBlock}\n </body>`);
|
|
244
|
+
changed = true;
|
|
245
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (critters-trick block added)`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (CRITTERS_BLOCK_RE.test(content)) {
|
|
249
|
+
content = content.replace(CRITTERS_BLOCK_RE, '');
|
|
250
|
+
changed = true;
|
|
251
|
+
changeset.push(` \u001b[32m✔\u001b[0m ${path} (critters-trick divs removed)`);
|
|
252
|
+
}
|
|
253
|
+
if (changed) {
|
|
254
|
+
tree.overwrite(path, content);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
changeset.push(` \u001b[90mℹ\u001b[0m ${path} (already synced)`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// ── 2. angular.json ──
|
|
261
|
+
const angularJson = tree.read('/angular.json');
|
|
262
|
+
if (angularJson) {
|
|
263
|
+
const workspace = JSON.parse(angularJson.toString());
|
|
264
|
+
const project = workspace.projects[projectName];
|
|
265
|
+
const prodConfig = (_e = (_d = (_c = project.architect) === null || _c === void 0 ? void 0 : _c.build) === null || _d === void 0 ? void 0 : _d.configurations) === null || _e === void 0 ? void 0 : _e.production;
|
|
266
|
+
if (prodConfig) {
|
|
267
|
+
let changed = false;
|
|
268
|
+
if (strategy === 'blocking') {
|
|
269
|
+
if (typeof prodConfig.optimization === 'object') {
|
|
270
|
+
prodConfig.optimization.styles = prodConfig.optimization.styles || {};
|
|
271
|
+
if (prodConfig.optimization.styles.inlineCritical !== false) {
|
|
272
|
+
prodConfig.optimization.styles.inlineCritical = false;
|
|
273
|
+
changed = true;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
prodConfig.optimization = { styles: { inlineCritical: false } };
|
|
278
|
+
changed = true;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (typeof prodConfig.optimization === 'object' && ((_f = prodConfig.optimization.styles) === null || _f === void 0 ? void 0 : _f.inlineCritical) === false) {
|
|
282
|
+
prodConfig.optimization.styles.inlineCritical = true;
|
|
283
|
+
changed = true;
|
|
284
|
+
}
|
|
285
|
+
if (changed) {
|
|
286
|
+
tree.overwrite('/angular.json', JSON.stringify(workspace, null, 2));
|
|
287
|
+
changeset.push(' \u001b[33mM\u001b[0m angular.json (optimization synced)');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
context.logger.info('\u001b[1mChangeset:\u001b[0m');
|
|
292
|
+
if (changeset.length === 0) {
|
|
293
|
+
context.logger.info(' (no changes needed)');
|
|
310
294
|
}
|
|
295
|
+
else {
|
|
296
|
+
changeset.forEach((entry) => context.logger.info(entry));
|
|
297
|
+
}
|
|
298
|
+
context.logger.info('');
|
|
299
|
+
context.logger.info('\u001b[1m\u001b[32m🏁 Done.\u001b[0m');
|
|
311
300
|
context.logger.info('');
|
|
312
301
|
};
|
|
313
302
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/sync/index.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/sync/index.ts"],"names":[],"mappings":"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"}
|