@ethlete/core 5.0.0-next.6 → 5.0.0-next.60
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/CHANGELOG.md +686 -0
- package/README.md +28 -4
- package/fesm2022/ethlete-core.mjs +8020 -3527
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/generators/devtools-about/generator.js +122 -0
- package/generators/devtools-about/schema.json +25 -0
- package/generators/generators.json +26 -5
- package/generators/migrate-provider-shape/migration-scope.js +35 -0
- package/generators/migrate-provider-shape/migration.js +50 -0
- package/generators/migrate-provider-shape/provider-shape.js +284 -0
- package/generators/migrate-provider-shape/schema.json +26 -0
- package/generators/migrate-surface-interaction-swatch/interaction-swatch.js +63 -0
- package/generators/migrate-surface-interaction-swatch/migration.js +36 -0
- package/generators/migrate-surface-interaction-swatch/schema.json +26 -0
- package/generators/migrate-to-v5/color-naming.js +170 -0
- package/generators/migrate-to-v5/create-provider.js +14 -14
- package/generators/migrate-to-v5/migration.js +11 -1
- package/generators/migrate-to-v5/removed-exports.js +93 -0
- package/generators/migrate-to-v5/router-state-service.js +33 -8
- package/generators/migrate-to-v5/schema.json +10 -0
- package/generators/migrate-to-v5/viewport-service.js +41 -60
- package/generators/tailwind-4-color-theme/generator.js +608 -0
- package/generators/tailwind-4-color-theme/schema.json +44 -0
- package/generators/tailwind-4-surface-theme/generator.js +599 -0
- package/generators/tailwind-4-surface-theme/schema.json +48 -0
- package/migrations/seo-directive-removed.md +80 -0
- package/migrations/surface-theme-regenerate.md +20 -0
- package/migrations.json +43 -0
- package/package.json +25 -14
- package/types/ethlete-core.d.ts +3329 -1774
- package/generators/tailwind-4-theme/generator.js +0 -490
- package/generators/tailwind-4-theme/schema.json +0 -32
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
3
2
|
import { logger } from '@nx/devkit';
|
|
4
3
|
import * as ts from 'typescript';
|
|
5
4
|
export default async function migrateViewportService(tree) {
|
|
@@ -12,7 +11,7 @@ export default async function migrateViewportService(tree) {
|
|
|
12
11
|
for (const child of children) {
|
|
13
12
|
const path = dir === '.' ? child : `${dir}/${child}`;
|
|
14
13
|
if (tree.isFile(path)) {
|
|
15
|
-
if (path.endsWith('.ts') && !path.includes('node_modules')
|
|
14
|
+
if (path.endsWith('.ts') && !path.includes('node_modules')) {
|
|
16
15
|
tsFiles.push(path);
|
|
17
16
|
}
|
|
18
17
|
else if (path.endsWith('.css') ||
|
|
@@ -23,6 +22,8 @@ export default async function migrateViewportService(tree) {
|
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
else {
|
|
25
|
+
if (child === 'node_modules')
|
|
26
|
+
continue;
|
|
26
27
|
findFiles(path);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -45,6 +46,9 @@ export default async function migrateViewportService(tree) {
|
|
|
45
46
|
continue;
|
|
46
47
|
logger.log(`Processing: ${filePath}`);
|
|
47
48
|
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
49
|
+
const viewportPackage = getViewportServicePackage(sourceFile);
|
|
50
|
+
if (viewportPackage !== '@ethlete/core' && !viewportPackage?.startsWith('@fifa-gg/uikit'))
|
|
51
|
+
continue;
|
|
48
52
|
// Check if this is a component with a template
|
|
49
53
|
const templatePath = findTemplateForComponent(tree, filePath, sourceFile);
|
|
50
54
|
// Track signal properties for template migration
|
|
@@ -94,7 +98,7 @@ export default async function migrateViewportService(tree) {
|
|
|
94
98
|
}
|
|
95
99
|
});
|
|
96
100
|
// Check if any replacements use toObservable or toSignal
|
|
97
|
-
for (const [original, replacement] of context.replacements) {
|
|
101
|
+
for (const [original, replacement] of [...context.replacements].sort((a, b) => b[0].length - a[0].length)) {
|
|
98
102
|
if (replacement.includes('toObservable(')) {
|
|
99
103
|
allImportsNeeded['@angular/core/rxjs-interop'].add('toObservable');
|
|
100
104
|
}
|
|
@@ -175,6 +179,7 @@ export default async function migrateViewportService(tree) {
|
|
|
175
179
|
componentTemplateMigrations.set(filePath, templateMigrationInfo);
|
|
176
180
|
}
|
|
177
181
|
const updatedSourceFileForInline = ts.createSourceFile(filePath, updatedContent, ts.ScriptTarget.Latest, true);
|
|
182
|
+
const inlineTemplateEdits = [];
|
|
178
183
|
updatedSourceFileForInline.forEachChild((node) => {
|
|
179
184
|
if (ts.isClassDeclaration(node)) {
|
|
180
185
|
const decorators =
|
|
@@ -193,25 +198,25 @@ export default async function migrateViewportService(tree) {
|
|
|
193
198
|
let templateText = prop.initializer.getText();
|
|
194
199
|
// Remove the surrounding quotes/backticks
|
|
195
200
|
templateText = templateText.slice(1, -1);
|
|
196
|
-
|
|
197
|
-
for (const propName of templateMigrationInfo.signalProperties) {
|
|
198
|
-
const regex = new RegExp(`\\b${propName}(?!\\s*\\()\\b`, 'g');
|
|
199
|
-
templateText = templateText.replace(regex, `${propName}()`);
|
|
200
|
-
}
|
|
201
|
+
templateText = migrateTemplateText(templateText, templateMigrationInfo.signalProperties);
|
|
201
202
|
// Re-wrap with original quotes/backticks
|
|
202
203
|
const quote = prop.initializer.getText()[0];
|
|
203
204
|
const newInitializer = quote + templateText + quote;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
inlineTemplateEdits.push({
|
|
206
|
+
start: prop.initializer.getStart(updatedSourceFileForInline),
|
|
207
|
+
end: prop.initializer.getEnd(),
|
|
208
|
+
replacement: newInitializer,
|
|
209
|
+
});
|
|
209
210
|
}
|
|
210
211
|
});
|
|
211
212
|
}
|
|
212
213
|
});
|
|
213
214
|
}
|
|
214
215
|
});
|
|
216
|
+
inlineTemplateEdits.sort((a, b) => b.start - a.start);
|
|
217
|
+
for (const edit of inlineTemplateEdits) {
|
|
218
|
+
updatedContent = updatedContent.slice(0, edit.start) + edit.replacement + updatedContent.slice(edit.end);
|
|
219
|
+
}
|
|
215
220
|
// Write the updated content if changes were made
|
|
216
221
|
if (updatedContent !== content) {
|
|
217
222
|
tree.write(filePath, updatedContent);
|
|
@@ -276,28 +281,24 @@ function detectCssVariableUsage(tree, styleFiles) {
|
|
|
276
281
|
}
|
|
277
282
|
return { hasViewportVariables, hasScrollbarVariables };
|
|
278
283
|
}
|
|
284
|
+
const migrateTemplateExpression = (expression, signalProperties) => {
|
|
285
|
+
let migrated = expression;
|
|
286
|
+
for (const propName of signalProperties) {
|
|
287
|
+
const regex = new RegExp(`\\b${escapeRegExp(propName)}(?!\\s*\\()\\b`, 'g');
|
|
288
|
+
migrated = migrated.replace(regex, `${propName}()`);
|
|
289
|
+
}
|
|
290
|
+
return migrated;
|
|
291
|
+
};
|
|
292
|
+
const migrateTemplateText = (template, signalProperties) => template
|
|
293
|
+
.replace(/{{([\s\S]*?)}}/g, (_, expression) => `{{${migrateTemplateExpression(expression, signalProperties)}}}`)
|
|
294
|
+
.replace(/((?:\[[^\]]+\]|\([^)]+\)|\*[\w.-]+)\s*=\s*)(["'])([\s\S]*?)\2/g, (_, prefix, quote, expression) => `${prefix}${quote}${migrateTemplateExpression(expression, signalProperties)}${quote}`)
|
|
295
|
+
.replace(/@(if|for|switch|case|defer)\s*\(([^\n{}]*)\)/g, (_, block, expression) => `@${block} (${migrateTemplateExpression(expression, signalProperties)})`);
|
|
279
296
|
function migrateTemplateFile(tree, htmlFilePath, migrationInfo) {
|
|
280
297
|
const content = tree.read(htmlFilePath, 'utf-8');
|
|
281
298
|
if (!content)
|
|
282
299
|
return false;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
// For each signal property, replace usages with () calls
|
|
286
|
-
for (const propName of migrationInfo.signalProperties) {
|
|
287
|
-
// Match property usage in various Angular contexts:
|
|
288
|
-
// 1. Interpolation: {{ propName }}
|
|
289
|
-
// 2. Property binding: [prop]="propName"
|
|
290
|
-
// 3. Event binding: (event)="propName === value"
|
|
291
|
-
// 4. Structural directives: *ngIf="propName"
|
|
292
|
-
// But NOT if already called: propName()
|
|
293
|
-
// Create a regex that matches the property but not if followed by (
|
|
294
|
-
const regex = new RegExp(`\\b${escapeRegExp(propName)}(?!\\s*\\()\\b`, 'g');
|
|
295
|
-
const newContent = updatedContent.replace(regex, `${propName}()`);
|
|
296
|
-
if (newContent !== updatedContent) {
|
|
297
|
-
updatedContent = newContent;
|
|
298
|
-
hasChanges = true;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
300
|
+
const updatedContent = migrateTemplateText(content, migrationInfo.signalProperties);
|
|
301
|
+
const hasChanges = updatedContent !== content;
|
|
301
302
|
if (hasChanges) {
|
|
302
303
|
tree.write(htmlFilePath, updatedContent);
|
|
303
304
|
}
|
|
@@ -340,7 +341,7 @@ function getViewportServicePackage(sourceFile) {
|
|
|
340
341
|
sourceFile.forEachChild((node) => {
|
|
341
342
|
if (ts.isImportDeclaration(node) && node.importClause?.namedBindings) {
|
|
342
343
|
if (ts.isNamedImports(node.importClause.namedBindings)) {
|
|
343
|
-
const hasViewportService = node.importClause.namedBindings.elements.some((el) => el.name.text === 'ViewportService');
|
|
344
|
+
const hasViewportService = node.importClause.namedBindings.elements.some((el) => (el.propertyName?.text ?? el.name.text) === 'ViewportService');
|
|
344
345
|
if (hasViewportService && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
345
346
|
packageName = node.moduleSpecifier.text;
|
|
346
347
|
}
|
|
@@ -359,7 +360,7 @@ function getPropertyMaps(packageName) {
|
|
|
359
360
|
isLg: isEthleteCore ? 'injectIsLg' : 'injectIsXl',
|
|
360
361
|
isXl: isEthleteCore ? 'injectIsXl' : 'injectIs2Xl',
|
|
361
362
|
is2Xl: 'injectIs2Xl',
|
|
362
|
-
isBase:
|
|
363
|
+
isBase: 'injectIsLg',
|
|
363
364
|
viewportSize: 'injectViewportDimensions',
|
|
364
365
|
scrollbarSize: 'injectScrollbarDimensions',
|
|
365
366
|
currentViewport: 'injectCurrentBreakpoint',
|
|
@@ -1093,7 +1094,7 @@ function findClassForViewportService(sourceFile, viewportServiceVar) {
|
|
|
1093
1094
|
function findAvailableMemberName(baseName, existingMembers) {
|
|
1094
1095
|
// baseName already has $ suffix for observables at this point
|
|
1095
1096
|
// Try variations: name, _name, #name
|
|
1096
|
-
const candidates = [baseName, `_${baseName}
|
|
1097
|
+
const candidates = [baseName, `_${baseName}`];
|
|
1097
1098
|
for (const candidate of candidates) {
|
|
1098
1099
|
if (!existingMembers.has(candidate)) {
|
|
1099
1100
|
return candidate;
|
|
@@ -1161,29 +1162,8 @@ function migrateMonitorViewport(sourceFile, content, viewportServiceVars, cssVar
|
|
|
1161
1162
|
return { content, imports };
|
|
1162
1163
|
}
|
|
1163
1164
|
// Determine what to add to constructor
|
|
1164
|
-
const constructorStatements = [];
|
|
1165
|
-
|
|
1166
|
-
constructorStatements.push('writeViewportSizeToCssVariables();');
|
|
1167
|
-
imports.push('writeViewportSizeToCssVariables');
|
|
1168
|
-
}
|
|
1169
|
-
if (cssVariablesUsed.hasScrollbarVariables) {
|
|
1170
|
-
constructorStatements.push('writeScrollbarSizeToCssVariables();');
|
|
1171
|
-
imports.push('writeScrollbarSizeToCssVariables');
|
|
1172
|
-
}
|
|
1173
|
-
if (constructorStatements.length === 0) {
|
|
1174
|
-
// Just remove monitorViewport calls
|
|
1175
|
-
const modifications = monitorViewportCalls.map((call) => ({
|
|
1176
|
-
start: call.start,
|
|
1177
|
-
end: call.end,
|
|
1178
|
-
replacement: '',
|
|
1179
|
-
}));
|
|
1180
|
-
// Apply modifications from end to start
|
|
1181
|
-
modifications.sort((a, b) => b.start - a.start);
|
|
1182
|
-
for (const mod of modifications) {
|
|
1183
|
-
updatedContent = updatedContent.slice(0, mod.start) + mod.replacement + updatedContent.slice(mod.end);
|
|
1184
|
-
}
|
|
1185
|
-
return { content: updatedContent, imports };
|
|
1186
|
-
}
|
|
1165
|
+
const constructorStatements = ['writeViewportSizeToCssVariables();', 'writeScrollbarSizeToCssVariables();'];
|
|
1166
|
+
imports.push('writeViewportSizeToCssVariables', 'writeScrollbarSizeToCssVariables');
|
|
1187
1167
|
// Group calls by class
|
|
1188
1168
|
const callsByClass = new Map();
|
|
1189
1169
|
for (const call of monitorViewportCalls) {
|
|
@@ -1278,8 +1258,10 @@ function addImportsToPackage(sourceFile, content, neededImports, packageName) {
|
|
|
1278
1258
|
statement.moduleSpecifier.text === packageName);
|
|
1279
1259
|
const importsToAdd = Array.from(neededImports).sort();
|
|
1280
1260
|
if (existingImport?.importClause?.namedBindings && ts.isNamedImports(existingImport.importClause.namedBindings)) {
|
|
1281
|
-
const
|
|
1282
|
-
const
|
|
1261
|
+
const existingElements = existingImport.importClause.namedBindings.elements;
|
|
1262
|
+
const existingImportedNames = existingElements.map((el) => el.propertyName?.text ?? el.name.text);
|
|
1263
|
+
const existingImportNames = existingElements.map((el) => el.getText(sourceFile));
|
|
1264
|
+
const newImports = importsToAdd.filter((imp) => !existingImportedNames.includes(imp));
|
|
1283
1265
|
if (newImports.length > 0) {
|
|
1284
1266
|
const allImports = [...existingImportNames, ...newImports].sort();
|
|
1285
1267
|
const importText = existingImport.getText(sourceFile);
|
|
@@ -1675,4 +1657,3 @@ function checkIfPropertyIsUsedElsewhere(sourceFile, classNode, propertyName, pro
|
|
|
1675
1657
|
});
|
|
1676
1658
|
return isUsed;
|
|
1677
1659
|
}
|
|
1678
|
-
//# sourceMappingURL=viewport-service.js.map
|