@dialpad/dialtone-css 8.81.0-next.5 → 8.81.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/lib/build/js/dialtone_migrate/index.mjs +39 -2
- package/lib/build/js/dialtone_migrate/test.mjs +88 -0
- package/lib/build/js/dialtone_migrate_flex_to_stack/index.mjs +27 -4
- package/lib/build/js/dialtone_migrate_typography/index.mjs +28 -6
- package/lib/build/js/dialtone_migrate_typography/test.mjs +82 -0
- package/lib/dist/dialtone-default-theme.css +1 -0
- package/lib/dist/dialtone-default-theme.min.css +1 -1
- package/lib/dist/dialtone-docs.json +1 -1
- package/lib/dist/js/dialtone_migrate/index.mjs +39 -2
- package/lib/dist/js/dialtone_migrate/test.mjs +88 -0
- package/lib/dist/js/dialtone_migrate_flex_to_stack/index.mjs +27 -4
- package/lib/dist/js/dialtone_migrate_typography/index.mjs +28 -6
- package/lib/dist/js/dialtone_migrate_typography/test.mjs +82 -0
- package/lib/dist/no-layers/dialtone-default-theme.css +1 -0
- package/lib/dist/no-layers/dialtone-default-theme.min.css +1 -1
- package/lib/dist/tokens/tokens-base-dark.css +1 -0
- package/lib/dist/tokens/tokens-base-light.css +1 -0
- package/lib/dist/tokens/tokens-debug-base.css +1 -0
- package/lib/dist/tokens-docs.json +1 -1
- package/package.json +2 -2
|
@@ -18,7 +18,11 @@
|
|
|
18
18
|
* --yes Apply all changes without prompting
|
|
19
19
|
* --health-check Report migration status without modifying files
|
|
20
20
|
* --all Run all required migrations without selection prompt
|
|
21
|
+
* --include-opt-in Also run opt-in migrations (with --all, or on its own = everything)
|
|
21
22
|
* --only <ids> Comma-separated list of migration IDs to run
|
|
23
|
+
* --package <name> Package name to use for injected component imports
|
|
24
|
+
* (default: @dialpad/dialtone-vue). Useful when running
|
|
25
|
+
* Dialtone under a custom package alias (e.g. @dialpad/dialtone-next).
|
|
22
26
|
* --help Show help
|
|
23
27
|
*
|
|
24
28
|
* Examples:
|
|
@@ -50,6 +54,7 @@ const __dirname = path.dirname(__filename);
|
|
|
50
54
|
* @property {'config'|'standalone'|'manual'} type
|
|
51
55
|
* @property {string} [configName] - Config filename for migration-helper type
|
|
52
56
|
* @property {string} [scriptDir] - Directory name for standalone scripts
|
|
57
|
+
* @property {boolean} [supportsPackageArg] - Forward --package to this standalone script
|
|
53
58
|
* @property {string[]} [extraArgs] - Extra CLI args to forward
|
|
54
59
|
* @property {RegExp[]} detectPatterns - Patterns that indicate migration is still needed
|
|
55
60
|
* @property {string[]} fileExtensions - File extensions to scan during health check
|
|
@@ -250,6 +255,8 @@ const MIGRATIONS = [
|
|
|
250
255
|
category: 'opt-in',
|
|
251
256
|
type: 'standalone',
|
|
252
257
|
scriptDir: 'dialtone_migrate_flex_to_stack',
|
|
258
|
+
// Injects a DtStack import, so it honors the --package override.
|
|
259
|
+
supportsPackageArg: true,
|
|
253
260
|
detectPatterns: [
|
|
254
261
|
/class="[^"]*d-d-flex[^"]*"/,
|
|
255
262
|
],
|
|
@@ -304,6 +311,8 @@ const MIGRATIONS = [
|
|
|
304
311
|
category: 'opt-in',
|
|
305
312
|
type: 'standalone',
|
|
306
313
|
scriptDir: 'dialtone_migrate_typography',
|
|
314
|
+
// Injects a DtText import, so it honors the --package override.
|
|
315
|
+
supportsPackageArg: true,
|
|
307
316
|
detectPatterns: [
|
|
308
317
|
/class="[^"]*d-(?:headline|body|label)--(?:sm|md|lg|xl|xxl)/,
|
|
309
318
|
/class="[^"]*d-(?:headline|body|label)-(?:small|medium|large)/,
|
|
@@ -371,6 +380,17 @@ async function writeMigrationMarker (cwd, id) {
|
|
|
371
380
|
function parseArgs (args) {
|
|
372
381
|
const cwdIndex = args.indexOf('--cwd');
|
|
373
382
|
const onlyIndex = args.indexOf('--only');
|
|
383
|
+
const packageIndex = args.indexOf('--package');
|
|
384
|
+
|
|
385
|
+
// --package must be followed by an actual package name. Reject a missing value
|
|
386
|
+
// or a value that is really the next option (e.g. `--package --all`) so invalid
|
|
387
|
+
// input never reaches the alias confirmation or child-migration args.
|
|
388
|
+
const packageValue = packageIndex !== -1 ? args[packageIndex + 1] : undefined;
|
|
389
|
+
if (packageIndex !== -1 && (!packageValue || packageValue.startsWith('-'))) {
|
|
390
|
+
console.error('\n --package requires a package name (e.g. --package @dialpad/dialtone-next)\n');
|
|
391
|
+
process.exit(1);
|
|
392
|
+
}
|
|
393
|
+
|
|
374
394
|
return {
|
|
375
395
|
help: args.includes('--help'),
|
|
376
396
|
dryRun: args.includes('--dry-run'),
|
|
@@ -378,12 +398,14 @@ function parseArgs (args) {
|
|
|
378
398
|
noImport: args.includes('--no-import'),
|
|
379
399
|
healthCheck: args.includes('--health-check'),
|
|
380
400
|
all: args.includes('--all'),
|
|
401
|
+
includeOptIn: args.includes('--include-opt-in'),
|
|
381
402
|
cwd: cwdIndex !== -1 && args[cwdIndex + 1]
|
|
382
403
|
? path.resolve(args[cwdIndex + 1])
|
|
383
404
|
: process.cwd(),
|
|
384
405
|
only: onlyIndex !== -1 && args[onlyIndex + 1]
|
|
385
406
|
? args[onlyIndex + 1].split(',').map(s => s.trim())
|
|
386
407
|
: null,
|
|
408
|
+
packageName: packageIndex !== -1 ? packageValue : null,
|
|
387
409
|
};
|
|
388
410
|
}
|
|
389
411
|
|
|
@@ -400,7 +422,11 @@ Options:
|
|
|
400
422
|
--yes Apply all changes without prompting
|
|
401
423
|
--health-check Report migration status without modifying files
|
|
402
424
|
--all Run all required migrations without selection prompt
|
|
425
|
+
--include-opt-in Also run opt-in migrations (with --all, or on its own = everything)
|
|
403
426
|
--only <ids> Comma-separated list of migration IDs to run
|
|
427
|
+
--package <name> Package name to use for injected component imports
|
|
428
|
+
(default: @dialpad/dialtone-vue). Useful when running
|
|
429
|
+
Dialtone under a custom package alias (e.g. @dialpad/dialtone-next).
|
|
404
430
|
--help Show help
|
|
405
431
|
|
|
406
432
|
Available migration IDs (required):
|
|
@@ -413,6 +439,7 @@ Examples:
|
|
|
413
439
|
npx dialtone-migrate # Interactive selection
|
|
414
440
|
npx dialtone-migrate --health-check --cwd ./src # Check migration status
|
|
415
441
|
npx dialtone-migrate --all --dry-run # Dry-run all required
|
|
442
|
+
npx dialtone-migrate --all --include-opt-in --yes # Run required + opt-in
|
|
416
443
|
npx dialtone-migrate --only color-stops,hsl-to-oklch --yes
|
|
417
444
|
`);
|
|
418
445
|
}
|
|
@@ -792,6 +819,9 @@ async function runStandaloneMigration (migration, opts) {
|
|
|
792
819
|
if (opts.dryRun) args.push('--dry-run');
|
|
793
820
|
if (opts.autoYes) args.push('--yes');
|
|
794
821
|
if (opts.noImport) args.push('--no-import');
|
|
822
|
+
if (opts.packageName && migration.supportsPackageArg) {
|
|
823
|
+
args.push('--package', opts.packageName);
|
|
824
|
+
}
|
|
795
825
|
|
|
796
826
|
return new Promise((resolve, reject) => {
|
|
797
827
|
const child = spawn(process.execPath, [scriptPath, ...args], {
|
|
@@ -872,8 +902,12 @@ async function main () {
|
|
|
872
902
|
}
|
|
873
903
|
return m;
|
|
874
904
|
});
|
|
875
|
-
} else if (opts.all) {
|
|
876
|
-
|
|
905
|
+
} else if (opts.all || opts.includeOptIn) {
|
|
906
|
+
// --include-opt-in widens the selection to every migration; --all alone stays
|
|
907
|
+
// required-only. Either flag skips the interactive prompt.
|
|
908
|
+
selected = opts.includeOptIn
|
|
909
|
+
? MIGRATIONS.slice()
|
|
910
|
+
: MIGRATIONS.filter(m => m.category === 'required');
|
|
877
911
|
} else {
|
|
878
912
|
selected = await selectMigrations(MIGRATIONS);
|
|
879
913
|
}
|
|
@@ -885,6 +919,9 @@ async function main () {
|
|
|
885
919
|
|
|
886
920
|
// Confirmation
|
|
887
921
|
console.log(`\n Target directory: ${opts.cwd}`);
|
|
922
|
+
if (opts.packageName) {
|
|
923
|
+
console.log(` Import package: ${opts.packageName}`);
|
|
924
|
+
}
|
|
888
925
|
console.log(` Migrations to run (${selected.length}):\n`);
|
|
889
926
|
for (const m of selected) {
|
|
890
927
|
const tag = m.category === 'required' ? '[REQUIRED]' : '[OPT-IN]';
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dialtone-migrate (master orchestrator) tests.
|
|
3
|
+
*
|
|
4
|
+
* Exercises migration selection via the CLI in --dry-run against an empty temp
|
|
5
|
+
* directory, asserting which categories each flag selects.
|
|
6
|
+
* Run: node --test packages/dialtone-css/lib/build/js/dialtone_migrate/test.mjs
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, it } from 'node:test';
|
|
10
|
+
import assert from 'node:assert/strict';
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { fileURLToPath } from 'node:url';
|
|
16
|
+
|
|
17
|
+
const cli = path.join(path.dirname(fileURLToPath(import.meta.url)), 'index.mjs');
|
|
18
|
+
|
|
19
|
+
// Run the CLI in --dry-run against an empty temp dir and return stdout.
|
|
20
|
+
function runDryRun (flags) {
|
|
21
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'dlt-master-'));
|
|
22
|
+
try {
|
|
23
|
+
return execFileSync(
|
|
24
|
+
process.execPath,
|
|
25
|
+
[cli, '--dry-run', '--cwd', tmp, ...flags],
|
|
26
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] },
|
|
27
|
+
);
|
|
28
|
+
} finally {
|
|
29
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function selectedCount (output) {
|
|
34
|
+
const m = output.match(/Migrations to run \((\d+)\)/);
|
|
35
|
+
return m ? Number(m[1]) : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('migration selection', () => {
|
|
39
|
+
it('--all selects the required migrations only (excludes opt-in)', () => {
|
|
40
|
+
const output = runDryRun(['--all']);
|
|
41
|
+
assert.equal(selectedCount(output), 12);
|
|
42
|
+
assert.ok(!output.includes('[OPT-IN]'), '--all must not select opt-in migrations');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('--all --include-opt-in selects every migration', () => {
|
|
46
|
+
const output = runDryRun(['--all', '--include-opt-in']);
|
|
47
|
+
assert.equal(selectedCount(output), 20);
|
|
48
|
+
assert.ok(output.includes('[OPT-IN]'), 'opt-in migrations should be selected');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('--include-opt-in on its own also selects every migration', () => {
|
|
52
|
+
const output = runDryRun(['--include-opt-in']);
|
|
53
|
+
assert.equal(selectedCount(output), 20);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('--package validation', () => {
|
|
58
|
+
// Run the CLI with the given args and return { status, stderr }; never throws.
|
|
59
|
+
function run (extraArgs) {
|
|
60
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'dlt-master-'));
|
|
61
|
+
try {
|
|
62
|
+
execFileSync(process.execPath, [cli, '--dry-run', '--cwd', tmp, ...extraArgs],
|
|
63
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
64
|
+
return { status: 0, stderr: '' };
|
|
65
|
+
} catch (err) {
|
|
66
|
+
return { status: err.status, stderr: String(err.stderr ?? '') };
|
|
67
|
+
} finally {
|
|
68
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
it('rejects --package with no value', () => {
|
|
73
|
+
const { status, stderr } = run(['--all', '--package']);
|
|
74
|
+
assert.equal(status, 1);
|
|
75
|
+
assert.match(stderr, /--package requires a package name/);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('rejects --package followed by another option (--package --all)', () => {
|
|
79
|
+
const { status, stderr } = run(['--package', '--all']);
|
|
80
|
+
assert.equal(status, 1);
|
|
81
|
+
assert.match(stderr, /--package requires a package name/);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('accepts a valid package name', () => {
|
|
85
|
+
const { status } = run(['--all', '--package', '@dialpad/dialtone-next']);
|
|
86
|
+
assert.equal(status, 0);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -1030,7 +1030,7 @@ async function processFile(filePath, options) {
|
|
|
1030
1030
|
|
|
1031
1031
|
// Auto-inject DtStack import before writing; fall back to manual instructions if needed.
|
|
1032
1032
|
// Skipped entirely when --no-import is set (e.g. DtStack is globally registered).
|
|
1033
|
-
const importCheck = options.noImport ? null : detectMissingStackImport(newContent, changes > 0);
|
|
1033
|
+
const importCheck = options.noImport ? null : detectMissingStackImport(newContent, changes > 0, options.package);
|
|
1034
1034
|
let finalContent = newContent;
|
|
1035
1035
|
if (importCheck?.needsImport) {
|
|
1036
1036
|
const injected = injectComponentImport(newContent, 'DtStack', importCheck.suggestedPath);
|
|
@@ -1102,9 +1102,10 @@ async function cleanupMarkers(filePath, options) {
|
|
|
1102
1102
|
* Check if a file needs DtStack import
|
|
1103
1103
|
* @param {string} content - Full file content
|
|
1104
1104
|
* @param {boolean} usesStack - Whether file has <dt-stack> in template
|
|
1105
|
+
* @param {string} [packageName] - Explicit package to import from (overrides detection)
|
|
1105
1106
|
* @returns {object|null} - Detection result with suggested import path, or null if import exists
|
|
1106
1107
|
*/
|
|
1107
|
-
function detectMissingStackImport(content, usesStack) {
|
|
1108
|
+
function detectMissingStackImport(content, usesStack, packageName) {
|
|
1108
1109
|
if (!usesStack) return null;
|
|
1109
1110
|
|
|
1110
1111
|
// Check if DtStack is already imported
|
|
@@ -1112,7 +1113,7 @@ function detectMissingStackImport(content, usesStack) {
|
|
|
1112
1113
|
if (hasImport) return null;
|
|
1113
1114
|
|
|
1114
1115
|
// Analyze existing imports to suggest appropriate path
|
|
1115
|
-
const importPath = detectImportPattern(content);
|
|
1116
|
+
const importPath = detectImportPattern(content, packageName);
|
|
1116
1117
|
|
|
1117
1118
|
return {
|
|
1118
1119
|
needsImport: true,
|
|
@@ -1124,9 +1125,17 @@ function detectMissingStackImport(content, usesStack) {
|
|
|
1124
1125
|
/**
|
|
1125
1126
|
* Detect import pattern from existing imports in file
|
|
1126
1127
|
* @param {string} content - File content
|
|
1128
|
+
* @param {string} [packageName] - Explicit package name (e.g. @dialpad/dialtone-next).
|
|
1129
|
+
* When provided, it is used verbatim, overriding the heuristics below. This lets
|
|
1130
|
+
* consumers running Dialtone under a custom package alias inject the correct import.
|
|
1127
1131
|
* @returns {string} - Suggested import path
|
|
1128
1132
|
*/
|
|
1129
|
-
function detectImportPattern(content) {
|
|
1133
|
+
function detectImportPattern(content, packageName) {
|
|
1134
|
+
// Explicit override: honor the caller-provided package name.
|
|
1135
|
+
if (packageName) {
|
|
1136
|
+
return packageName;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1130
1139
|
// Check for @/ alias (absolute from package root)
|
|
1131
1140
|
if (content.includes('from \'@/components/')) {
|
|
1132
1141
|
return '@/components/stack';
|
|
@@ -1257,6 +1266,7 @@ function parseArgs() {
|
|
|
1257
1266
|
showOutline: false, // Add migration marker for visual debugging
|
|
1258
1267
|
removeOutline: false, // Remove migration markers (cleanup mode)
|
|
1259
1268
|
noImport: false, // Skip import injection (for apps that globally register DtStack)
|
|
1269
|
+
package: null, // Override the package name used for injected DtStack imports
|
|
1260
1270
|
};
|
|
1261
1271
|
|
|
1262
1272
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -1285,6 +1295,9 @@ Options:
|
|
|
1285
1295
|
--show-outline Add data-migrate-outline attribute for visual debugging
|
|
1286
1296
|
--remove-outline Remove data-migrate-outline attributes after review
|
|
1287
1297
|
--no-import Skip import injection (use when DtStack is globally registered)
|
|
1298
|
+
--package <name> Package name for injected DtStack imports
|
|
1299
|
+
(default: @dialpad/dialtone-vue when a Dialtone import is detected).
|
|
1300
|
+
Use when Dialtone runs under a custom alias, e.g. @dialpad/dialtone-next.
|
|
1288
1301
|
--help, -h Show help
|
|
1289
1302
|
|
|
1290
1303
|
Post-Migration Steps:
|
|
@@ -1333,6 +1346,15 @@ Examples:
|
|
|
1333
1346
|
options.removeOutline = true;
|
|
1334
1347
|
} else if (arg === '--no-import') {
|
|
1335
1348
|
options.noImport = true;
|
|
1349
|
+
} else if (arg === '--package') {
|
|
1350
|
+
// Reject a missing value or one that is really the next option (e.g.
|
|
1351
|
+
// `--package --yes`) so an invalid alias is never recorded.
|
|
1352
|
+
const value = args[i + 1];
|
|
1353
|
+
if (!value || value.startsWith('-')) {
|
|
1354
|
+
console.error('\n --package requires a package name (e.g. --package @dialpad/dialtone-next)\n');
|
|
1355
|
+
process.exit(1);
|
|
1356
|
+
}
|
|
1357
|
+
options.package = args[++i];
|
|
1336
1358
|
} else if (arg === '--file' && args[i + 1]) {
|
|
1337
1359
|
const filePath = args[++i];
|
|
1338
1360
|
options.files.push(filePath);
|
|
@@ -1430,6 +1452,7 @@ async function main() {
|
|
|
1430
1452
|
showOutline: options.showOutline,
|
|
1431
1453
|
validate: options.validate,
|
|
1432
1454
|
noImport: options.noImport,
|
|
1455
|
+
package: options.package,
|
|
1433
1456
|
});
|
|
1434
1457
|
}
|
|
1435
1458
|
|
|
@@ -1235,11 +1235,20 @@ async function validateAndResolveFiles (filePaths, extensions) {
|
|
|
1235
1235
|
// Import detection (ported from flex-to-stack)
|
|
1236
1236
|
//------------------------------------------------------------------------------
|
|
1237
1237
|
|
|
1238
|
-
export function detectImportPathFor (content) {
|
|
1239
|
-
return detectImportPattern(content);
|
|
1238
|
+
export function detectImportPathFor (content, packageName) {
|
|
1239
|
+
return detectImportPattern(content, packageName);
|
|
1240
1240
|
}
|
|
1241
1241
|
|
|
1242
|
-
|
|
1242
|
+
/**
|
|
1243
|
+
* @param {string} content - File content
|
|
1244
|
+
* @param {string} [packageName] - Explicit package name (e.g. @dialpad/dialtone-next).
|
|
1245
|
+
* When provided, it is used verbatim, overriding the heuristics below. This lets
|
|
1246
|
+
* consumers running Dialtone under a custom package alias inject the correct import.
|
|
1247
|
+
*/
|
|
1248
|
+
function detectImportPattern (content, packageName) {
|
|
1249
|
+
// Explicit override: honor the caller-provided package name.
|
|
1250
|
+
if (packageName) return packageName;
|
|
1251
|
+
|
|
1243
1252
|
if (content.includes('from \'@/components/')) return '@/components/text';
|
|
1244
1253
|
if (content.includes('from \'./\'')) return './';
|
|
1245
1254
|
if (content.includes('from \'@dialpad/dialtone-vue') || content.includes('from \'@dialpad/dialtone-icons')) {
|
|
@@ -1248,13 +1257,13 @@ function detectImportPattern (content) {
|
|
|
1248
1257
|
return '@/components/text';
|
|
1249
1258
|
}
|
|
1250
1259
|
|
|
1251
|
-
function detectMissingDtTextImport (content, usesText) {
|
|
1260
|
+
function detectMissingDtTextImport (content, usesText, packageName) {
|
|
1252
1261
|
if (!usesText) return null;
|
|
1253
1262
|
const hasImport = /import\s+(?:\{[^}]*\bDtText\b[^}]*\}|DtText)\s+from/.test(content);
|
|
1254
1263
|
if (hasImport) return null;
|
|
1255
1264
|
return {
|
|
1256
1265
|
needsImport: true,
|
|
1257
|
-
suggestedPath: detectImportPattern(content),
|
|
1266
|
+
suggestedPath: detectImportPattern(content, packageName),
|
|
1258
1267
|
hasComponentsObject: /components:\s*\{/.test(content),
|
|
1259
1268
|
};
|
|
1260
1269
|
}
|
|
@@ -1537,7 +1546,7 @@ async function processFile (filePath, options) {
|
|
|
1537
1546
|
const addedDtText = afterCount > beforeCount;
|
|
1538
1547
|
// Auto-inject DtText import before writing; fall back to manual instructions if needed.
|
|
1539
1548
|
// Skipped entirely when --no-import is set (e.g. DtText is globally registered).
|
|
1540
|
-
const importCheck = options.noImport ? null : detectMissingDtTextImport(transformed, addedDtText);
|
|
1549
|
+
const importCheck = options.noImport ? null : detectMissingDtTextImport(transformed, addedDtText, options.package);
|
|
1541
1550
|
|
|
1542
1551
|
let finalContent = transformed;
|
|
1543
1552
|
if (importCheck?.needsImport) {
|
|
@@ -1580,6 +1589,7 @@ function parseArgs () {
|
|
|
1580
1589
|
removeMarkers: false,
|
|
1581
1590
|
validate: false,
|
|
1582
1591
|
noImport: false, // Skip import injection (for apps that globally register DtText)
|
|
1592
|
+
package: null, // Override the package name used for injected DtText imports
|
|
1583
1593
|
};
|
|
1584
1594
|
|
|
1585
1595
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -1600,6 +1610,9 @@ Options:
|
|
|
1600
1610
|
--validate Read-only mode: scan existing <dt-text> for prop bugs
|
|
1601
1611
|
(object syntax, invalid values, mixed CSS classes)
|
|
1602
1612
|
--no-import Skip import injection (use when DtText is globally registered)
|
|
1613
|
+
--package <name> Package name for injected DtText imports
|
|
1614
|
+
(default: @dialpad/dialtone-vue when a Dialtone import is detected).
|
|
1615
|
+
Use when Dialtone runs under a custom alias, e.g. @dialpad/dialtone-next.
|
|
1603
1616
|
--help, -h Show help
|
|
1604
1617
|
|
|
1605
1618
|
Examples:
|
|
@@ -1630,6 +1643,15 @@ Post-Migration Steps:
|
|
|
1630
1643
|
options.validate = true;
|
|
1631
1644
|
} else if (arg === '--no-import') {
|
|
1632
1645
|
options.noImport = true;
|
|
1646
|
+
} else if (arg === '--package') {
|
|
1647
|
+
// Reject a missing value or one that is really the next option (e.g.
|
|
1648
|
+
// `--package --yes`) so an invalid alias is never recorded.
|
|
1649
|
+
const value = args[i + 1];
|
|
1650
|
+
if (!value || value.startsWith('-')) {
|
|
1651
|
+
console.error('\n --package requires a package name (e.g. --package @dialpad/dialtone-next)\n');
|
|
1652
|
+
process.exit(1);
|
|
1653
|
+
}
|
|
1654
|
+
options.package = args[++i];
|
|
1633
1655
|
}
|
|
1634
1656
|
}
|
|
1635
1657
|
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
import { describe, it } from 'node:test';
|
|
9
9
|
import assert from 'node:assert/strict';
|
|
10
|
+
import { execFileSync } from 'node:child_process';
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import os from 'node:os';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
10
15
|
import {
|
|
11
16
|
transformContent,
|
|
12
17
|
detectImportPathFor,
|
|
@@ -729,6 +734,83 @@ describe('import detection', () => {
|
|
|
729
734
|
const path = detectImportPathFor(content);
|
|
730
735
|
assert.equal(path, '@/components/text');
|
|
731
736
|
});
|
|
737
|
+
|
|
738
|
+
it('uses the explicit package name when provided, overriding detection', () => {
|
|
739
|
+
const content = `<script>\nimport { DtButton } from '@/components/button';\n</script>`;
|
|
740
|
+
const path = detectImportPathFor(content, '@dialpad/dialtone-next');
|
|
741
|
+
assert.equal(path, '@dialpad/dialtone-next');
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
it('explicit package name applies even when no imports are present', () => {
|
|
745
|
+
const content = `<template><p class="d-headline--md">x</p></template>`;
|
|
746
|
+
const path = detectImportPathFor(content, '@dialpad/dialtone-next');
|
|
747
|
+
assert.equal(path, '@dialpad/dialtone-next');
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// ---------------------------------------------------------------------------
|
|
752
|
+
// --package end-to-end: prove the flag reaches the injected import, both via
|
|
753
|
+
// the standalone CLI and forwarded through the master orchestrator.
|
|
754
|
+
// ---------------------------------------------------------------------------
|
|
755
|
+
|
|
756
|
+
describe('--package end-to-end', () => {
|
|
757
|
+
const dir = path.dirname(fileURLToPath(import.meta.url));
|
|
758
|
+
const typographyCli = path.join(dir, 'index.mjs');
|
|
759
|
+
const masterCli = path.join(dir, '..', 'dialtone_migrate', 'index.mjs');
|
|
760
|
+
|
|
761
|
+
// Uses <script setup> so the import auto-injects, a local @/components import so
|
|
762
|
+
// that without --package detection would resolve to @/components/text (not the
|
|
763
|
+
// package), and a d-headline-- class so a <dt-text> is added (triggering the import).
|
|
764
|
+
const SOURCE = [
|
|
765
|
+
'<script setup>',
|
|
766
|
+
`import { DtButton } from '@/components/button';`,
|
|
767
|
+
'</script>',
|
|
768
|
+
'<template>',
|
|
769
|
+
' <p class="d-headline--md">Title</p>',
|
|
770
|
+
'</template>',
|
|
771
|
+
'',
|
|
772
|
+
].join('\n');
|
|
773
|
+
|
|
774
|
+
function migrate (argv) {
|
|
775
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'dlt-typo-'));
|
|
776
|
+
const file = path.join(tmp, 'Sample.vue');
|
|
777
|
+
fs.writeFileSync(file, SOURCE, 'utf8');
|
|
778
|
+
try {
|
|
779
|
+
execFileSync(process.execPath, argv(tmp), { stdio: 'ignore' });
|
|
780
|
+
return fs.readFileSync(file, 'utf8');
|
|
781
|
+
} finally {
|
|
782
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
it('standalone CLI injects the explicit package into the generated import', () => {
|
|
787
|
+
const output = migrate(tmp => [
|
|
788
|
+
typographyCli, '--cwd', tmp, '--yes', '--package', '@dialpad/dialtone-next',
|
|
789
|
+
]);
|
|
790
|
+
assert.match(output, /import \{ DtText \} from '@dialpad\/dialtone-next';/);
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
it('master orchestrator forwards --package to the typography child', () => {
|
|
794
|
+
// The import lands on @dialpad/dialtone-next only if the master forwarded the
|
|
795
|
+
// flag; otherwise detection would pick @/components/text from the existing import.
|
|
796
|
+
const output = migrate(tmp => [
|
|
797
|
+
masterCli, '--only', 'typography', '--yes', '--cwd', tmp, '--package', '@dialpad/dialtone-next',
|
|
798
|
+
]);
|
|
799
|
+
assert.match(output, /import \{ DtText \} from '@dialpad\/dialtone-next';/);
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
it('rejects --package followed by another option (--package --yes)', () => {
|
|
803
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'dlt-typo-'));
|
|
804
|
+
try {
|
|
805
|
+
assert.throws(
|
|
806
|
+
() => execFileSync(process.execPath, [typographyCli, '--cwd', tmp, '--package', '--yes'],
|
|
807
|
+
{ stdio: ['ignore', 'ignore', 'pipe'] }),
|
|
808
|
+
err => err.status === 1 && /--package requires a package name/.test(String(err.stderr)),
|
|
809
|
+
);
|
|
810
|
+
} finally {
|
|
811
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
812
|
+
}
|
|
813
|
+
});
|
|
732
814
|
});
|
|
733
815
|
|
|
734
816
|
describe('--remove-markers', () => {
|
|
@@ -17000,6 +17000,7 @@
|
|
|
17000
17000
|
--dt-layout-75: calc(var(--dt-layout-base) * 0.75); /* 48px */
|
|
17001
17001
|
--dt-layout-50: calc(var(--dt-layout-base) * 0.5); /* 32px */
|
|
17002
17002
|
--dt-layout-25: calc(var(--dt-layout-base) * 0.25); /* 16px */
|
|
17003
|
+
--dt-layout-0: calc(var(--dt-layout-base) * 0); /* 0px */
|
|
17003
17004
|
--dt-spacing-800: calc(var(--dt-spacing-base) * 8); /* 64px */
|
|
17004
17005
|
--dt-spacing-750: calc(var(--dt-spacing-base) * 7.5); /* 60px */
|
|
17005
17006
|
--dt-spacing-700: calc(var(--dt-spacing-base) * 7); /* 56px */
|