@contentful/experience-design-system-cli 2.12.4-dev-build-262febd.0 → 2.12.4-dev-build-5aa6a69.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.12.4-dev-build-262febd.0",
3
+ "version": "2.12.4-dev-build-5aa6a69.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,25 +2,26 @@
2
2
  // expands the second generic argument to string | JSXElementConstructor<any>).
3
3
  // Only the first generic argument (the props type name) is captured.
4
4
  const REACT_ELEMENT_GENERIC = /(?:React\.)?ReactElement\s*<\s*([A-Za-z_$][\w$.]*)(?![\w$.])/g;
5
- // Svelte 5 typed snippets: `Snippet<[XProps]>`. The type argument is a tuple
6
- // listing render args; when a snippet is authored to render a nested
7
- // ComponentType, the single tuple element is that component's Props type.
8
- // We only match the single-element tuple form — non-props render args
9
- // (e.g. `Snippet<[year: number]>`) don't reference a ComponentType and are
10
- // filtered out below via propsToComponent lookup.
11
- const SVELTE_SNIPPET_GENERIC = /Snippet\s*<\s*\[\s*([A-Za-z_$][\w$.]*)\s*\]\s*>/g;
5
+ const SVELTE_SNIPPET_TUPLE = /Snippet\s*<\s*\[([^\]]*)\]\s*>/g;
6
+ const IDENTIFIER = /[A-Za-z_$][\w$.]*/g;
12
7
  export function extractAllowedComponentsFromTypeText(typeText, ctx) {
13
8
  const found = new Set();
14
- for (const re of [REACT_ELEMENT_GENERIC, SVELTE_SNIPPET_GENERIC]) {
15
- re.lastIndex = 0;
16
- let m;
17
- while ((m = re.exec(typeText)) !== null) {
18
- const propsTypeName = m[1];
19
- const componentName = ctx.propsToComponent.get(propsTypeName);
20
- if (componentName && ctx.componentNames.has(componentName)) {
21
- found.add(componentName);
22
- }
23
- }
9
+ const record = (propsTypeName) => {
10
+ const componentName = ctx.propsToComponent.get(propsTypeName);
11
+ if (componentName && ctx.componentNames.has(componentName))
12
+ found.add(componentName);
13
+ };
14
+ REACT_ELEMENT_GENERIC.lastIndex = 0;
15
+ let m;
16
+ while ((m = REACT_ELEMENT_GENERIC.exec(typeText)) !== null)
17
+ record(m[1]);
18
+ SVELTE_SNIPPET_TUPLE.lastIndex = 0;
19
+ while ((m = SVELTE_SNIPPET_TUPLE.exec(typeText)) !== null) {
20
+ const tupleBody = m[1];
21
+ IDENTIFIER.lastIndex = 0;
22
+ let id;
23
+ while ((id = IDENTIFIER.exec(tupleBody)) !== null)
24
+ record(id[0]);
24
25
  }
25
26
  return [...found].sort();
26
27
  }
@@ -924,10 +924,7 @@ export function FieldEditor({ value, width, height, active = true, onChange, onS
924
924
  if (props.length === 0 && slots.length === 0) {
925
925
  return (_jsxs(Box, { flexDirection: "column", width: width, borderStyle: "single", borderColor: "yellow", children: [_jsx(Text, { bold: true, color: "yellow", children: "FIELD EDITOR \u2014 no fields" }), _jsx(Text, { color: "yellow", children: "⚠ No properties classified for this component. The LLM didn't find anything to classify." }), _jsx(Text, { dimColor: true, children: "You can add fields manually below or reject this component." }), _jsx(Text, { dimColor: true, children: "Ctrl+S to save \u00B7 Esc to discard" })] }));
926
926
  }
927
- // When $properties is empty but $slots exist, surface the same warning
928
- // prominently in the panel so the user understands why the component looks
929
- // sparse — and can act on it (manually add a prop or reject).
930
- const hasEmptyProperties = props.length === 0;
927
+ const hasEmptyProperties = props.length === 0 && slots.length === 0;
931
928
  const modeLabel = (() => {
932
929
  if (editingValue) {
933
930
  return editingValue.mode === 'add' ? 'Enter to add · Esc to cancel' : 'Enter to save edit · Esc to cancel';
@@ -25,9 +25,10 @@ import { computeNextScrollOffset } from '../../../analyze/select/tui/hooks/scrol
25
25
  * Within each tier (empty / non-empty) we tie-break alphabetically by `key`.
26
26
  */
27
27
  export function sortComponentsForSidebar(components) {
28
+ const isEmpty = (entry) => Object.keys(entry.$properties ?? {}).length === 0 && Object.keys(entry.$slots ?? {}).length === 0;
28
29
  return [...components].sort((a, b) => {
29
- const aEmpty = Object.keys(a.entry.$properties ?? {}).length === 0;
30
- const bEmpty = Object.keys(b.entry.$properties ?? {}).length === 0;
30
+ const aEmpty = isEmpty(a.entry);
31
+ const bEmpty = isEmpty(b.entry);
31
32
  if (aEmpty !== bEmpty)
32
33
  return aEmpty ? -1 : 1;
33
34
  return a.key.localeCompare(b.key);
@@ -473,12 +474,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
473
474
  }
474
475
  const selected = components[selectedIdx] ?? null;
475
476
  const selectedJson = selected ? JSON.stringify({ [selected.key]: selected.entry }, null, 2) : '';
476
- // A component with zero classified $properties is a real defensibility issue
477
- // it can't be pushed to Contentful (no fields). Surface it in the sidebar via
478
- // the existing warning-color path (yellow) and a "(empty)" suffix so the user
479
- // can see what went wrong. They can manually add props in FieldEditor or
480
- // explicitly reject the component.
481
- const isEmpty = (c) => Object.keys(c.entry.$properties).length === 0;
477
+ const isEmpty = (c) => Object.keys(c.entry.$properties).length === 0 && Object.keys(c.entry.$slots ?? {}).length === 0;
482
478
  const emptyCount = components.filter(isEmpty).length;
483
479
  const sidebarItems = components.map((c) => ({
484
480
  id: c.key,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.12.4-dev-build-262febd.0",
3
+ "version": "2.12.4-dev-build-5aa6a69.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,7 +37,7 @@
37
37
  "svelte": "^5.56.4",
38
38
  "ts-morph": "^27.0.2",
39
39
  "typescript": "^5.9.3",
40
- "@contentful/experience-design-system-types": "2.12.4-dev-build-262febd.0"
40
+ "@contentful/experience-design-system-types": "2.12.4-dev-build-5aa6a69.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@tsconfig/node24": "^24.0.3",