@contentful/experience-design-system-cli 2.12.4-dev-build-ff57340.0 → 2.13.1-dev-build-fa478b3.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.
Files changed (55) hide show
  1. package/dist/package.json +3 -6
  2. package/dist/src/analyze/command.js +2 -22
  3. package/dist/src/analyze/select/command.js +1 -1
  4. package/dist/src/analyze/select/tui/components/FieldEditor.d.ts +1 -24
  5. package/dist/src/analyze/select/tui/components/FieldEditor.js +10 -137
  6. package/dist/src/analyze/select-agent/command.js +1 -1
  7. package/dist/src/apply/command.d.ts +1 -34
  8. package/dist/src/apply/command.js +0 -81
  9. package/dist/src/import/tui/WizardApp.js +10 -59
  10. package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +1 -1
  11. package/dist/src/import/tui/steps/GenerateReviewStep.js +23 -213
  12. package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +0 -10
  13. package/dist/src/import/tui/steps/WizardPreviewStep.js +51 -95
  14. package/dist/src/import/tui/steps/preview-diff.js +0 -48
  15. package/dist/src/session/db.d.ts +0 -9
  16. package/dist/src/session/db.js +0 -46
  17. package/dist/src/types.d.ts +2 -76
  18. package/dist/src/types.js +1 -4
  19. package/package.json +3 -6
  20. package/dist/src/analyze/cycle-detection.d.ts +0 -93
  21. package/dist/src/analyze/cycle-detection.js +0 -326
  22. package/dist/src/analyze/extract/astro.d.ts +0 -5
  23. package/dist/src/analyze/extract/astro.js +0 -289
  24. package/dist/src/analyze/extract/non-authorable-filter.d.ts +0 -16
  25. package/dist/src/analyze/extract/non-authorable-filter.js +0 -60
  26. package/dist/src/analyze/extract/pipeline.d.ts +0 -6
  27. package/dist/src/analyze/extract/pipeline.js +0 -314
  28. package/dist/src/analyze/extract/react.d.ts +0 -2
  29. package/dist/src/analyze/extract/react.js +0 -2041
  30. package/dist/src/analyze/extract/scoring.d.ts +0 -12
  31. package/dist/src/analyze/extract/scoring.js +0 -108
  32. package/dist/src/analyze/extract/slot-allowed-components.d.ts +0 -8
  33. package/dist/src/analyze/extract/slot-allowed-components.js +0 -40
  34. package/dist/src/analyze/extract/slot-detection.d.ts +0 -35
  35. package/dist/src/analyze/extract/slot-detection.js +0 -101
  36. package/dist/src/analyze/extract/source-inspection.d.ts +0 -13
  37. package/dist/src/analyze/extract/source-inspection.js +0 -189
  38. package/dist/src/analyze/extract/stencil.d.ts +0 -2
  39. package/dist/src/analyze/extract/stencil.js +0 -296
  40. package/dist/src/analyze/extract/svelte.d.ts +0 -5
  41. package/dist/src/analyze/extract/svelte.js +0 -1626
  42. package/dist/src/analyze/extract/tsx-shared.d.ts +0 -8
  43. package/dist/src/analyze/extract/tsx-shared.js +0 -263
  44. package/dist/src/analyze/extract/validate.d.ts +0 -16
  45. package/dist/src/analyze/extract/validate.js +0 -94
  46. package/dist/src/analyze/extract/vue-tsx.d.ts +0 -2
  47. package/dist/src/analyze/extract/vue-tsx.js +0 -498
  48. package/dist/src/analyze/extract/vue.d.ts +0 -5
  49. package/dist/src/analyze/extract/vue.js +0 -653
  50. package/dist/src/analyze/extract/web-components.d.ts +0 -2
  51. package/dist/src/analyze/extract/web-components.js +0 -876
  52. package/dist/src/analyze/pre-classify.d.ts +0 -17
  53. package/dist/src/analyze/pre-classify.js +0 -211
  54. package/dist/src/apply/error-parser.d.ts +0 -43
  55. package/dist/src/apply/error-parser.js +0 -163
@@ -1,296 +0,0 @@
1
- import { Project, Node } from 'ts-morph';
2
- function isStencilFile(sourceFile) {
3
- return sourceFile.getImportDeclarations().some((imp) => imp.getModuleSpecifierValue() === '@stencil/core');
4
- }
5
- function kebabToPascal(input) {
6
- return input
7
- .split('-')
8
- .filter(Boolean)
9
- .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
10
- .join('');
11
- }
12
- function getComponentTag(classDecl) {
13
- for (const decorator of classDecl.getDecorators()) {
14
- if (decorator.getName() !== 'Component')
15
- continue;
16
- const args = decorator.getArguments();
17
- if (args.length === 0)
18
- continue;
19
- const arg = args[0];
20
- if (!Node.isObjectLiteralExpression(arg))
21
- continue;
22
- const tagProp = arg.getProperty('tag');
23
- if (!tagProp || !Node.isPropertyAssignment(tagProp))
24
- continue;
25
- const initializer = tagProp.getInitializer();
26
- if (!initializer || !Node.isStringLiteral(initializer))
27
- continue;
28
- return initializer.getLiteralValue();
29
- }
30
- return undefined;
31
- }
32
- function hasDecorator(node, decoratorName) {
33
- if (!Node.isPropertyDeclaration(node))
34
- return false;
35
- return node.getDecorators().some((d) => d.getName() === decoratorName);
36
- }
37
- function extractAllowedValues(typeText) {
38
- // Match inline string literal unions: 'a' | 'b' | 'c'
39
- const literalPattern = /^'[^']*'(?:\s*\|\s*'[^']*')+$/;
40
- if (!literalPattern.test(typeText.trim()))
41
- return undefined;
42
- const values = typeText
43
- .split('|')
44
- .map((v) => v.trim().replace(/^'|'$/g, ''))
45
- .filter(Boolean)
46
- .sort();
47
- return values.length >= 2 ? values : undefined;
48
- }
49
- function extractProps(classDecl) {
50
- const props = [];
51
- for (const property of classDecl.getProperties()) {
52
- if (!hasDecorator(property, 'Prop'))
53
- continue;
54
- const name = property.getName();
55
- const typeNode = property.getTypeNode();
56
- const typeText = typeNode ? typeNode.getText() : 'unknown';
57
- const hasQuestionToken = property.hasQuestionToken();
58
- const hasExclamation = property.hasExclamationToken();
59
- const initializer = property.getInitializer();
60
- let defaultValue;
61
- if (initializer) {
62
- if (Node.isStringLiteral(initializer)) {
63
- defaultValue = initializer.getLiteralValue();
64
- }
65
- else {
66
- defaultValue = initializer.getText();
67
- }
68
- }
69
- const isRequired = hasExclamation || (!hasQuestionToken && !initializer);
70
- // JSDoc description
71
- const jsDocs = property.getJsDocs();
72
- let description;
73
- let isDeprecated = false;
74
- if (jsDocs.length > 0) {
75
- const jsDoc = jsDocs[0];
76
- description = jsDoc.getDescription().trim() || undefined;
77
- for (const tag of jsDoc.getTags()) {
78
- if (tag.getTagName() === 'deprecated') {
79
- isDeprecated = true;
80
- // The deprecated tag may carry a message (e.g. "@deprecated Use size instead.")
81
- const tagComment = tag.getCommentText()?.trim();
82
- if (tagComment && !description) {
83
- description = tagComment;
84
- }
85
- }
86
- }
87
- }
88
- if (isDeprecated && description) {
89
- description = `[DEPRECATED] ${description}`;
90
- }
91
- else if (isDeprecated) {
92
- description = '[DEPRECATED]';
93
- }
94
- const allowedValues = extractAllowedValues(typeText);
95
- props.push({
96
- name,
97
- type: typeText,
98
- required: isRequired,
99
- ...(defaultValue !== undefined && { defaultValue }),
100
- ...(description && { description }),
101
- ...(allowedValues && { allowedValues }),
102
- sourceStartLine: property.getStartLineNumber(),
103
- sourceEndLine: property.getEndLineNumber(),
104
- });
105
- }
106
- return props.sort((a, b) => a.name.localeCompare(b.name));
107
- }
108
- function normalizeSlotName(name) {
109
- const normalizedName = name && name.length > 0 ? name : 'default';
110
- return {
111
- name: normalizedName,
112
- isDefault: normalizedName === 'default',
113
- };
114
- }
115
- function extractSlots(classDecl, warnings, componentName) {
116
- const slots = new Map();
117
- const upsertSlot = (slot) => {
118
- const existing = slots.get(slot.name);
119
- if (!existing) {
120
- slots.set(slot.name, slot);
121
- return;
122
- }
123
- slots.set(slot.name, {
124
- ...existing,
125
- ...slot,
126
- description: existing.description ?? slot.description,
127
- });
128
- };
129
- const jsDocs = classDecl.getJsDocs();
130
- for (const jsDoc of jsDocs) {
131
- for (const tag of jsDoc.getTags()) {
132
- if (tag.getTagName() !== 'slot')
133
- continue;
134
- const comment = tag.getCommentText()?.trim();
135
- if (!comment)
136
- continue;
137
- if (comment.startsWith('{')) {
138
- try {
139
- const parsed = JSON.parse(comment);
140
- const slot = normalizeSlotName(parsed.name);
141
- let description = parsed.description || undefined;
142
- if (parsed.isDeprecated && description) {
143
- description = `[DEPRECATED] ${description}`;
144
- }
145
- else if (parsed.isDeprecated) {
146
- description = '[DEPRECATED]';
147
- }
148
- upsertSlot({
149
- ...slot,
150
- ...(description && { description }),
151
- });
152
- continue;
153
- }
154
- catch {
155
- warnings.push(`Failed to parse @slot JSDoc in ${componentName}: invalid JSON "${comment}"`);
156
- continue;
157
- }
158
- }
159
- const match = comment.match(/^(?:(\S+)\s*-\s*)?(.*)$/s);
160
- if (!match)
161
- continue;
162
- const [, rawName, rawDescription] = match;
163
- const slot = normalizeSlotName(rawName);
164
- const description = rawDescription.trim() || undefined;
165
- upsertSlot({
166
- ...slot,
167
- ...(description && { description }),
168
- });
169
- }
170
- }
171
- for (const method of classDecl.getMethods()) {
172
- method.forEachDescendant((node) => {
173
- if (!Node.isJsxSelfClosingElement(node) && !Node.isJsxElement(node))
174
- return;
175
- const openingElement = Node.isJsxElement(node) ? node.getOpeningElement() : node;
176
- const tagName = openingElement.getTagNameNode().getText();
177
- const slotAttribute = openingElement
178
- .getAttributes()
179
- .find((attribute) => Node.isJsxAttribute(attribute) && attribute.getNameNode().getText() === 'slot');
180
- if (tagName === 'slot') {
181
- const nameAttribute = openingElement
182
- .getAttributes()
183
- .find((attribute) => Node.isJsxAttribute(attribute) && attribute.getNameNode().getText() === 'name');
184
- const initializer = Node.isJsxAttribute(nameAttribute) ? nameAttribute.getInitializer() : undefined;
185
- const name = initializer && Node.isStringLiteral(initializer)
186
- ? initializer.getLiteralValue()
187
- : initializer && Node.isJsxExpression(initializer)
188
- ? (initializer.getExpression()?.getText() ?? '')
189
- : '';
190
- upsertSlot({
191
- ...normalizeSlotName(name),
192
- });
193
- return;
194
- }
195
- if (!Node.isJsxAttribute(slotAttribute))
196
- return;
197
- const initializer = slotAttribute.getInitializer();
198
- if (!initializer || !Node.isStringLiteral(initializer))
199
- return;
200
- const name = initializer.getLiteralValue();
201
- if (!name)
202
- return;
203
- upsertSlot({
204
- name,
205
- isDefault: false,
206
- });
207
- });
208
- }
209
- return [...slots.values()].sort((a, b) => a.name.localeCompare(b.name));
210
- }
211
- function detectEvents(classDecl) {
212
- const eventNames = [];
213
- for (const property of classDecl.getProperties()) {
214
- if (!hasDecorator(property, 'Event'))
215
- continue;
216
- eventNames.push(property.getName());
217
- }
218
- return eventNames.sort();
219
- }
220
- function extractFromSourceFile(sourceFile, warnings) {
221
- const components = [];
222
- for (const classDecl of sourceFile.getClasses()) {
223
- const tag = getComponentTag(classDecl);
224
- if (!tag)
225
- continue;
226
- const name = kebabToPascal(tag);
227
- const props = extractProps(classDecl);
228
- const slots = extractSlots(classDecl, warnings, name);
229
- const eventNames = detectEvents(classDecl);
230
- if (eventNames.length > 0) {
231
- warnings.push(`Component ${name} has ${eventNames.length} events not captured: ${eventNames.join(', ')}`);
232
- }
233
- components.push({
234
- name,
235
- source: sourceFile.getFilePath(),
236
- sourcePath: sourceFile.getFilePath(),
237
- framework: 'stencil',
238
- props,
239
- slots,
240
- });
241
- }
242
- return components;
243
- }
244
- function detectFunctionalComponents(sourceFile, warnings) {
245
- for (const [exportName, declarations] of sourceFile.getExportedDeclarations()) {
246
- for (const decl of declarations) {
247
- if (!Node.isVariableDeclaration(decl))
248
- continue;
249
- const typeNode = decl.getTypeNode();
250
- if (!typeNode)
251
- continue;
252
- const typeText = typeNode.getText();
253
- if (!typeText.startsWith('FunctionalComponent'))
254
- continue;
255
- warnings.push(`Stencil FunctionalComponent detected but not extracted: ${exportName} in ${sourceFile.getFilePath()}`);
256
- }
257
- }
258
- }
259
- export async function extractStencilComponents(filePaths) {
260
- const tsxFiles = filePaths.filter((f) => /\.[jt]sx$/.test(f));
261
- if (tsxFiles.length === 0) {
262
- return { components: [], warnings: [] };
263
- }
264
- const project = new Project({
265
- compilerOptions: {
266
- jsx: 1, // JsxEmit.Preserve
267
- target: 99, // ScriptTarget.ESNext
268
- module: 99, // ModuleKind.ESNext
269
- moduleResolution: 100, // ModuleResolutionKind.Bundler
270
- skipLibCheck: true,
271
- allowJs: true,
272
- },
273
- skipAddingFilesFromTsConfig: true,
274
- });
275
- for (const filePath of tsxFiles) {
276
- project.addSourceFileAtPath(filePath);
277
- }
278
- const warnings = [];
279
- const components = [];
280
- for (const sourceFile of project.getSourceFiles()) {
281
- try {
282
- if (!isStencilFile(sourceFile))
283
- continue;
284
- const extracted = extractFromSourceFile(sourceFile, warnings);
285
- components.push(...extracted);
286
- detectFunctionalComponents(sourceFile, warnings);
287
- }
288
- catch (e) {
289
- warnings.push(`Failed to extract from ${sourceFile.getFilePath()}: ${e instanceof Error ? e.message : String(e)}`);
290
- }
291
- }
292
- return {
293
- components: components.sort((a, b) => a.name.localeCompare(b.name)),
294
- warnings,
295
- };
296
- }
@@ -1,5 +0,0 @@
1
- import type { ComponentExtractionResult, ExtractorOptions } from '../../types.js';
2
- export declare function extractSvelteComponents(filePaths: string[], onProgress?: (p: {
3
- filesProcessed: number;
4
- componentsFound: number;
5
- }) => void, opts?: ExtractorOptions): Promise<ComponentExtractionResult>;