@contentful/experience-design-system-cli 2.25.1-dev-build-26ec156.0 → 2.25.1-dev-build-7be7857.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/dist/package.json +2 -2
- package/dist/src/session/db.d.ts +9 -0
- package/dist/src/session/db.js +126 -0
- package/package.json +6 -6
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.25.1-dev-build-
|
|
3
|
+
"version": "2.25.1-dev-build-7be7857.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"eslint-plugin-prettier": "^5.5.6",
|
|
58
58
|
"ink-testing-library": "^4.0.0",
|
|
59
59
|
"typescript-eslint": "^8.67.0",
|
|
60
|
-
"vitest": "^4.
|
|
60
|
+
"vitest": "^4.0.16"
|
|
61
61
|
},
|
|
62
62
|
"repository": {
|
|
63
63
|
"type": "git",
|
package/dist/src/session/db.d.ts
CHANGED
|
@@ -26,6 +26,15 @@ export interface StepRow {
|
|
|
26
26
|
}
|
|
27
27
|
export declare function getPipelineDbPath(): string;
|
|
28
28
|
export declare function openPipelineDb(dbPath?: string): DatabaseSync;
|
|
29
|
+
export type RawPropTokenPathKind = 'set' | 'allowed';
|
|
30
|
+
export interface RawPropTokenPathGroup {
|
|
31
|
+
componentId: string;
|
|
32
|
+
propName: string;
|
|
33
|
+
kind: RawPropTokenPathKind;
|
|
34
|
+
paths: string[];
|
|
35
|
+
}
|
|
36
|
+
export declare function replaceRawPropTokenPaths(db: DatabaseSync, sessionId: string, componentId: string, propName: string, kind: RawPropTokenPathKind, paths: string[]): void;
|
|
37
|
+
export declare function loadRawPropTokenPaths(db: DatabaseSync, sessionId: string): RawPropTokenPathGroup[];
|
|
29
38
|
export interface ApplyToolCallsResult {
|
|
30
39
|
classified: number;
|
|
31
40
|
excluded: number;
|
package/dist/src/session/db.js
CHANGED
|
@@ -185,6 +185,40 @@ export function openPipelineDb(dbPath) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
function applyDbMigrations(db) {
|
|
188
|
+
const migrations = [
|
|
189
|
+
{
|
|
190
|
+
name: '001-raw-prop-token-paths',
|
|
191
|
+
sql: `
|
|
192
|
+
CREATE TABLE IF NOT EXISTS raw_prop_token_paths (
|
|
193
|
+
session_id TEXT NOT NULL,
|
|
194
|
+
component_id TEXT NOT NULL,
|
|
195
|
+
prop_name TEXT NOT NULL,
|
|
196
|
+
kind TEXT NOT NULL CHECK (kind IN ('set', 'allowed')),
|
|
197
|
+
position INTEGER NOT NULL,
|
|
198
|
+
path TEXT NOT NULL,
|
|
199
|
+
PRIMARY KEY (session_id, component_id, prop_name, kind, position),
|
|
200
|
+
FOREIGN KEY (session_id, component_id, prop_name)
|
|
201
|
+
REFERENCES raw_props(session_id, component_id, name) ON DELETE CASCADE
|
|
202
|
+
);
|
|
203
|
+
`,
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
const hasAppliedMigration = db.prepare('SELECT 1 FROM migrations WHERE name = ?');
|
|
207
|
+
const recordMigration = db.prepare('INSERT INTO migrations (name, applied_at) VALUES (?, ?)');
|
|
208
|
+
for (const migration of migrations) {
|
|
209
|
+
if (hasAppliedMigration.get(migration.name))
|
|
210
|
+
continue;
|
|
211
|
+
db.exec('BEGIN');
|
|
212
|
+
try {
|
|
213
|
+
db.exec(migration.sql);
|
|
214
|
+
recordMigration.run(migration.name, new Date().toISOString());
|
|
215
|
+
db.exec('COMMIT');
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
db.exec('ROLLBACK');
|
|
219
|
+
throw e;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
188
222
|
const cols = db.prepare('PRAGMA table_info(raw_slots)').all();
|
|
189
223
|
if (!cols.some((c) => c.name === 'required')) {
|
|
190
224
|
db.exec('ALTER TABLE raw_slots ADD COLUMN required INTEGER NOT NULL DEFAULT 1 CHECK (required IN (0, 1))');
|
|
@@ -337,6 +371,59 @@ function applyDbMigrations(db) {
|
|
|
337
371
|
`);
|
|
338
372
|
}
|
|
339
373
|
}
|
|
374
|
+
export function replaceRawPropTokenPaths(db, sessionId, componentId, propName, kind, paths) {
|
|
375
|
+
const deletePaths = db.prepare(`DELETE FROM raw_prop_token_paths
|
|
376
|
+
WHERE session_id = ? AND component_id = ? AND prop_name = ? AND kind = ?`);
|
|
377
|
+
const insertPath = db.prepare(`INSERT INTO raw_prop_token_paths (session_id, component_id, prop_name, kind, position, path)
|
|
378
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
379
|
+
db.exec('BEGIN');
|
|
380
|
+
try {
|
|
381
|
+
deletePaths.run(sessionId, componentId, propName, kind);
|
|
382
|
+
if (paths.length === 0) {
|
|
383
|
+
// Row absence means the mapping has never been recorded. Keep an explicit
|
|
384
|
+
// marker for an empty mapping so it can round-trip distinctly.
|
|
385
|
+
insertPath.run(sessionId, componentId, propName, kind, -1, '');
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
paths.forEach((path, position) => {
|
|
389
|
+
insertPath.run(sessionId, componentId, propName, kind, position, path);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
db.exec('COMMIT');
|
|
393
|
+
}
|
|
394
|
+
catch (e) {
|
|
395
|
+
db.exec('ROLLBACK');
|
|
396
|
+
throw e;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
export function loadRawPropTokenPaths(db, sessionId) {
|
|
400
|
+
const rows = db
|
|
401
|
+
.prepare(`SELECT component_id, prop_name, kind, position, path
|
|
402
|
+
FROM raw_prop_token_paths
|
|
403
|
+
WHERE session_id = ?
|
|
404
|
+
ORDER BY component_id, prop_name, kind, position`)
|
|
405
|
+
.all(sessionId);
|
|
406
|
+
const groups = [];
|
|
407
|
+
for (const row of rows) {
|
|
408
|
+
const isEmptyMapping = row.position === -1 && row.path === '';
|
|
409
|
+
const previous = groups.at(-1);
|
|
410
|
+
if (previous &&
|
|
411
|
+
previous.componentId === row.component_id &&
|
|
412
|
+
previous.propName === row.prop_name &&
|
|
413
|
+
previous.kind === row.kind) {
|
|
414
|
+
if (!isEmptyMapping)
|
|
415
|
+
previous.paths.push(row.path);
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
groups.push({
|
|
419
|
+
componentId: row.component_id,
|
|
420
|
+
propName: row.prop_name,
|
|
421
|
+
kind: row.kind,
|
|
422
|
+
paths: isEmptyMapping ? [] : [row.path],
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
return groups;
|
|
426
|
+
}
|
|
340
427
|
export function loadComponentReviewMetadata(db, sessionId, componentName) {
|
|
341
428
|
const compRow = db
|
|
342
429
|
.prepare(`SELECT component_id, source, source_path FROM raw_components WHERE session_id = ? AND name = ?`)
|
|
@@ -785,6 +872,20 @@ export function storeCDFComponents(db, sessionId, components) {
|
|
|
785
872
|
VALUES (?, ?, ?, ?, ?)`);
|
|
786
873
|
const insertAllowedComponent = db.prepare(`INSERT INTO raw_slot_allowed_components (session_id, component_id, slot_name, allowed_component, position)
|
|
787
874
|
VALUES (?, ?, ?, ?, ?)`);
|
|
875
|
+
const deleteTokenPaths = db.prepare(`DELETE FROM raw_prop_token_paths WHERE session_id = ? AND component_id = ? AND prop_name = ? AND kind = ?`);
|
|
876
|
+
const insertTokenPath = db.prepare(`INSERT INTO raw_prop_token_paths (session_id, component_id, prop_name, kind, position, path)
|
|
877
|
+
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
878
|
+
// Absence of rows already means "mapping never ran", so a persisted-but-empty $token.allowed
|
|
879
|
+
// needs a sentinel row (position -1, empty path) to stay distinguishable on read-back.
|
|
880
|
+
const writeTokenPaths = (componentId, propName, kind, paths) => {
|
|
881
|
+
deleteTokenPaths.run(sessionId, componentId, propName, kind);
|
|
882
|
+
if (paths.length === 0) {
|
|
883
|
+
insertTokenPath.run(sessionId, componentId, propName, kind, -1, '');
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
paths.forEach((path, position) => insertTokenPath.run(sessionId, componentId, propName, kind, position, path));
|
|
887
|
+
}
|
|
888
|
+
};
|
|
788
889
|
const deleteSlots = db.prepare(`DELETE FROM raw_slots WHERE session_id = ? AND component_id = ?`);
|
|
789
890
|
const deleteSlotAllowedComponents = db.prepare(`DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ?`);
|
|
790
891
|
const readExistingSlotDefaults = db.prepare(`SELECT name, is_default FROM raw_slots WHERE session_id = ? AND component_id = ?`);
|
|
@@ -805,6 +906,11 @@ export function storeCDFComponents(db, sessionId, components) {
|
|
|
805
906
|
deleteAllowedValues.run(sessionId, componentId, propName);
|
|
806
907
|
prop.$values.forEach((v, i) => insertAllowedValue.run(sessionId, componentId, propName, v, i));
|
|
807
908
|
}
|
|
909
|
+
if (prop['$token.sets'] !== undefined)
|
|
910
|
+
writeTokenPaths(componentId, propName, 'set', prop['$token.sets']);
|
|
911
|
+
if (prop['$token.allowed'] !== undefined) {
|
|
912
|
+
writeTokenPaths(componentId, propName, 'allowed', prop['$token.allowed']);
|
|
913
|
+
}
|
|
808
914
|
}
|
|
809
915
|
const existingDefaults = new Map(readExistingSlotDefaults.all(sessionId, componentId).map((r) => [r.name, r.is_default]));
|
|
810
916
|
deleteSlotAllowedComponents.run(sessionId, componentId);
|
|
@@ -830,6 +936,11 @@ export function storeCDFComponents(db, sessionId, components) {
|
|
|
830
936
|
if (prop.$values && prop.$values.length > 0) {
|
|
831
937
|
prop.$values.forEach((v, i) => insertAllowedValue.run(sessionId, componentId, propName, v, i));
|
|
832
938
|
}
|
|
939
|
+
if (prop['$token.sets'] !== undefined)
|
|
940
|
+
writeTokenPaths(componentId, propName, 'set', prop['$token.sets']);
|
|
941
|
+
if (prop['$token.allowed'] !== undefined) {
|
|
942
|
+
writeTokenPaths(componentId, propName, 'allowed', prop['$token.allowed']);
|
|
943
|
+
}
|
|
833
944
|
}
|
|
834
945
|
let slotPos = 0;
|
|
835
946
|
for (const [slotName, slot] of Object.entries(entry.$slots ?? {})) {
|
|
@@ -875,10 +986,17 @@ export function loadCDFComponents(db, sessionId) {
|
|
|
875
986
|
.prepare(`SELECT component_id, slot_name, allowed_component
|
|
876
987
|
FROM raw_slot_allowed_components WHERE session_id = ? ORDER BY component_id, slot_name, position`)
|
|
877
988
|
.all(sessionId);
|
|
989
|
+
const tokenPaths = db
|
|
990
|
+
.prepare(`SELECT component_id, prop_name, kind, position, path
|
|
991
|
+
FROM raw_prop_token_paths WHERE session_id = ? ORDER BY component_id, prop_name, kind, position`)
|
|
992
|
+
.all(sessionId);
|
|
878
993
|
const propsByComponent = groupBy(props, (p) => p.component_id);
|
|
879
994
|
const allowedValuesByProp = groupBy(allowedValues, (av) => `${av.component_id}::${av.prop_name}`);
|
|
880
995
|
const slotsByComponent = groupBy(slots, (s) => s.component_id);
|
|
881
996
|
const allowedComponentsBySlot = groupBy(allowedComponents, (ac) => `${ac.component_id}::${ac.slot_name}`);
|
|
997
|
+
const tokenPathsByPropAndKind = groupBy(tokenPaths, (t) => `${t.component_id}::${t.prop_name}::${t.kind}`);
|
|
998
|
+
// A single sentinel row (position -1, empty path) means the mapping ran but produced no paths.
|
|
999
|
+
const toTokenPaths = (rows) => rows === undefined ? undefined : rows.length === 1 && rows[0].position === -1 ? [] : rows.map((r) => r.path);
|
|
882
1000
|
return components.map(({ component_id, name, description }) => {
|
|
883
1001
|
const compProps = propsByComponent.get(component_id) ?? [];
|
|
884
1002
|
const $properties = {};
|
|
@@ -906,6 +1024,14 @@ export function loadCDFComponents(db, sessionId) {
|
|
|
906
1024
|
propDef.$values = av.map((v) => v.value);
|
|
907
1025
|
if (p.cdf_token_kind !== null)
|
|
908
1026
|
propDef['$token.kind'] = p.cdf_token_kind;
|
|
1027
|
+
if (p.cdf_type === 'token' && p.cdf_category === 'design') {
|
|
1028
|
+
const sets = toTokenPaths(tokenPathsByPropAndKind.get(`${component_id}::${p.name}::set`));
|
|
1029
|
+
if (sets !== undefined)
|
|
1030
|
+
propDef['$token.sets'] = sets;
|
|
1031
|
+
const allowed = toTokenPaths(tokenPathsByPropAndKind.get(`${component_id}::${p.name}::allowed`));
|
|
1032
|
+
if (allowed !== undefined)
|
|
1033
|
+
propDef['$token.allowed'] = allowed;
|
|
1034
|
+
}
|
|
909
1035
|
$properties[p.name] = propDef;
|
|
910
1036
|
}
|
|
911
1037
|
const compSlots = slotsByComponent.get(component_id) ?? [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.25.1-dev-build-
|
|
3
|
+
"version": "2.25.1-dev-build-7be7857.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"react": "^18.3.1",
|
|
35
35
|
"react-devtools-core": "^4.19.1",
|
|
36
36
|
"react-dom": "^18.3.1",
|
|
37
|
-
"@contentful/experience-design-system-
|
|
38
|
-
"@contentful/experience-design-system-
|
|
39
|
-
"@contentful/experience-design-system-
|
|
40
|
-
"@contentful/experience-design-system-generation": "2.25.1-dev-build-
|
|
37
|
+
"@contentful/experience-design-system-client": "2.25.1-dev-build-7be7857.0",
|
|
38
|
+
"@contentful/experience-design-system-extraction": "2.25.1-dev-build-7be7857.0",
|
|
39
|
+
"@contentful/experience-design-system-types": "2.25.1-dev-build-7be7857.0",
|
|
40
|
+
"@contentful/experience-design-system-generation": "2.25.1-dev-build-7be7857.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"eslint-plugin-prettier": "^5.5.6",
|
|
49
49
|
"ink-testing-library": "^4.0.0",
|
|
50
50
|
"typescript-eslint": "^8.67.0",
|
|
51
|
-
"vitest": "^4.
|
|
51
|
+
"vitest": "^4.0.16"
|
|
52
52
|
},
|
|
53
53
|
"repository": {
|
|
54
54
|
"type": "git",
|