@contentful/experience-design-system-cli 2.11.2-dev-build-ffd086e.0 → 2.11.2-dev-build-003ce84.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.11.2-dev-build-ffd086e.0",
3
+ "version": "2.11.2-dev-build-003ce84.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,70 +27,6 @@ function isNumberType(type) {
27
27
  function isComplexType(type) {
28
28
  return !isSimpleType(type);
29
29
  }
30
- const DOM_PASS_THROUGH_PROPS = new Set([
31
- // Bare HTML / framework styling pass-through
32
- 'className',
33
- 'class',
34
- 'classes',
35
- 'classNames',
36
- 'rootClassName',
37
- 'prefixCls',
38
- 'style',
39
- 'styles',
40
- // Bare HTML attributes
41
- 'id',
42
- 'role',
43
- 'tabIndex',
44
- 'tabindex',
45
- 'name',
46
- 'htmlFor',
47
- 'for',
48
- 'slot',
49
- 'is',
50
- 'lang',
51
- 'dir',
52
- 'hidden',
53
- 'draggable',
54
- 'spellCheck',
55
- 'spellcheck',
56
- 'contentEditable',
57
- 'contenteditable',
58
- 'inputMode',
59
- 'inputmode',
60
- 'autoComplete',
61
- 'autocomplete',
62
- 'autoFocus',
63
- 'autofocus',
64
- 'translate',
65
- 'part',
66
- 'exportparts',
67
- 'aria',
68
- // Framework theming / pass-through escape hatches — dev-facing, never marketer-configurable
69
- 'dt',
70
- 'pt',
71
- 'ptOptions',
72
- 'unstyled',
73
- // Polymorphic component props — change rendered HTML/component, not marketer-visible behavior
74
- 'as',
75
- 'element',
76
- 'component',
77
- // QA / vendor test attributes
78
- 'dataQa',
79
- 'data-qa',
80
- // Vue v-model internals — framework wiring, never marketer-configurable
81
- 'modelValue',
82
- 'modelModifiers',
83
- ]);
84
- function isDomPassThroughProp(name) {
85
- if (DOM_PASS_THROUGH_PROPS.has(name))
86
- return true;
87
- // aria-label, aria-hidden, ariaLabel, ariaHidden — both kebab and camel forms
88
- if (/^aria[-A-Z]/.test(name))
89
- return true;
90
- if (name.startsWith('data-'))
91
- return true;
92
- return false;
93
- }
94
30
  /**
95
31
  * Deterministic pre-classification rule engine.
96
32
  * Applies rules in priority order and returns on the first match.
@@ -118,12 +54,9 @@ export function preClassifyProp(prop) {
118
54
  if (type.includes('Dispatch<') || type.includes('SetStateAction')) {
119
55
  return { category: 'exclude' };
120
56
  }
121
- // Rule 6: DOM / a11y / framework pass-through props
122
- // These are escape hatches developers use to wire components into the DOM.
123
- // Marketers should never configure them in the ExO editor; exposing them
124
- // generates noise that obscures the props that actually carry intent.
125
- if (isDomPassThroughProp(name)) {
126
- return { category: 'exclude' };
57
+ // Rule 6: className, style, styles
58
+ if (name === 'className' || name === 'style' || name === 'styles') {
59
+ return { category: 'design', cdfTypeHint: 'string' };
127
60
  }
128
61
  // Rule 7: String literal union
129
62
  if (isStringLiteralUnion(type)) {
@@ -13,5 +13,5 @@ export function DoneStep({ componentTypes, designTokens, summary, spaceId, envir
13
13
  function EntityRows({ entity, label }) {
14
14
  return (_jsxs(_Fragment, { children: [entity.created > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "green", children: "\u2713" }), _jsxs(Text, { children: [entity.created, " ", label, entity.created !== 1 ? 's' : '', " created"] })] })), entity.updated > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "green", children: "\u2713" }), _jsxs(Text, { children: [entity.updated, " ", label, entity.updated !== 1 ? 's' : '', " updated"] })] })), entity.failed > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: "red", children: "\u2717" }), _jsxs(Text, { color: "red", children: [entity.failed, " ", label, entity.failed !== 1 ? 's' : '', " failed \u2014 check logs above"] })] }))] }));
15
15
  }
16
- return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [success ? (_jsx(Text, { bold: true, color: "green", children: "Done!" })) : (_jsx(Text, { bold: true, color: "yellow", children: "\u26A0 Finished with errors" })), totalPushed === 0 && totalFailed === 0 && !summary ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Nothing was pushed \u2014 everything was already up to date." }) })) : (_jsxs(Box, { flexDirection: "column", gap: 0, marginTop: 1, children: [_jsx(EntityRows, { entity: componentTypes, label: "Component Type" }), _jsx(EntityRows, { entity: designTokens, label: "Design Token" }), summary && (_jsxs(Box, { gap: 1, marginTop: 1, children: [_jsxs(Text, { dimColor: true, children: ["Server: ", summary.succeeded, "/", summary.total, " succeeded"] }), summary.failed > 0 && _jsxs(Text, { color: "red", children: [", ", summary.failed, " failed"] })] }))] })), _jsxs(Box, { gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Space:" }), _jsx(Text, { children: spaceId }), _jsx(Text, { dimColor: true, children: "/" }), _jsx(Text, { dimColor: true, children: "Environment:" }), _jsx(Text, { children: environmentId })] }), success && totalPushed > 0 && (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Your design system is now in Contentful ExO." }), _jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(Text, { dimColor: true, children: "View it here:" }), _jsx(Text, { color: "cyan", children: `https://app.contentful.com/spaces/${spaceId}/environments/${environmentId}/exo/components` })] })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "[Enter / q] Exit" }) })] }));
16
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [success ? (_jsx(Text, { bold: true, color: "green", children: "Done!" })) : (_jsx(Text, { bold: true, color: "yellow", children: "\u26A0 Finished with errors" })), totalPushed === 0 && totalFailed === 0 && !summary ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Nothing was pushed \u2014 everything was already up to date." }) })) : (_jsxs(Box, { flexDirection: "column", gap: 0, marginTop: 1, children: [_jsx(EntityRows, { entity: componentTypes, label: "Component Type" }), _jsx(EntityRows, { entity: designTokens, label: "Design Token" }), summary && (_jsxs(Box, { gap: 1, marginTop: 1, children: [_jsxs(Text, { dimColor: true, children: ["Server: ", summary.succeeded, "/", summary.total, " succeeded"] }), summary.failed > 0 && _jsxs(Text, { color: "red", children: [", ", summary.failed, " failed"] })] }))] })), _jsxs(Box, { gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Space:" }), _jsx(Text, { children: spaceId }), _jsx(Text, { dimColor: true, children: "/" }), _jsx(Text, { dimColor: true, children: "Environment:" }), _jsx(Text, { children: environmentId })] }), success && totalPushed > 0 && (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Your design system is now in Contentful ExO." }), _jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(Text, { dimColor: true, children: "View it here:" }), _jsx(Text, { color: "cyan", children: `https://app.contentful.com/spaces/${spaceId}/environments/${environmentId}/views/components` })] })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "[Enter / q] Exit" }) })] }));
17
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.11.2-dev-build-ffd086e.0",
3
+ "version": "2.11.2-dev-build-003ce84.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  "react-dom": "^18.3.1",
37
37
  "ts-morph": "^27.0.2",
38
38
  "typescript": "^5.9.3",
39
- "@contentful/experience-design-system-types": "2.11.2-dev-build-ffd086e.0"
39
+ "@contentful/experience-design-system-types": "2.11.2-dev-build-003ce84.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tsconfig/node24": "^24.0.3",
@@ -131,30 +131,15 @@ The pre-classified `category` in the raw input is a starting point — correct i
131
131
 
132
132
  For each `RawPropDefinition`, apply in order:
133
133
 
134
- 1. **Framework / DOM / accessibility pass-through?** → `exclude_prop`. These are escape hatches for developers, not configurable surfaces for marketers. Exposing them in the ExO editor adds noise that obscures the props that actually carry intent. Always exclude:
135
- - Framework internals: `ref`, `innerRef`, event handlers (any `onSomething`), `testId`, `data-testid`, `key`
136
- - DOM pass-through: `className`, `class`, `classes`, `classNames`, `rootClassName`, `prefixCls`, `style`, `styles`, `id`, `role`, `tabIndex`, `name` (the bare HTML form `name` attribute), `htmlFor`, `for`, `slot`, `is`, `lang`, `dir`, `hidden`, `draggable`, `spellCheck`, `contentEditable`, `inputMode`, `autoComplete`, `autoFocus`, `translate`, `part`, `exportparts`
137
- - Accessibility pass-through: any `aria-*` or `ariaSomething` prop (including bare `aria` as an aria-attributes object), `aria-label`, `aria-hidden`, `aria-describedby`, `aria-controls`
138
- - Data attributes: any `data-*` prop
139
- - **Polymorphic component props**: `as`, `element`, `component` (when typed as an HTML tag string or component reference) these change rendered HTML, not marketer-visible behavior
140
- - **Framework theming / pass-through escape hatches**: PrimeVue's `dt` / `pt` / `ptOptions` / `unstyled`, MUI/Chakra-style `sx`, anything explicitly typed as a developer "override" / "passthrough" object
141
- - **Important caveat**: only exclude when the prop is one of these *as the bare HTML attribute or framework-internal pass-through*. Compound names like `fileName`, `displayName`, `dataset`, `dataSource`, `roleDescription`, `idLabel` are not pass-through — classify them normally.
142
- 2. **Common semantic props DO classify, do not exclude.** The LLM has been over-excluding these because they sound like framework internals; they are not. Classify each per the rest of this tree:
143
- - `icon` / `leftIcon` / `rightIcon` / `prefixIcon` / `suffixIcon` — slot or `string` (icon name); see slot guidance below
144
- - `items` / `options` / `actions` / `links` — usually array content; if the element shape is simple, classify as `string` (comma-separated names/IDs) and note in `description`. Only exclude when elements are deep nested objects with no flat representation.
145
- - `value` (the bare prop, not `modelValue`) — content prop, usually `string` (or `enum` if from a fixed set). Note: Vue's `modelValue` / `modelModifiers` are excluded by pre-classify because they're v-model framework wiring.
146
- - `form` (when not the literal `<form>` HTML attribute) — typically content; classify as `string` unless it's a complex form-config object
147
- - `inputId` / `componentId` — these CAN be content (anchor IDs, marketer-set tracking refs). Classify as `string`, `cdf_category: "content"` when the type is a plain string. Only exclude if the prop is clearly internal (e.g. typed as a generated React ID).
148
- - `accessibleNameRef` / `accessibleDescriptionRef` (web components) — these are ID references for a11y wiring; classify as `string`, `cdf_category: "state"` (behavioral wiring, not design or content).
149
- - `eventDetails` / similar telemetry props — `cdf_category: "state"`.
150
- 3. **Positional/geometric design prop?** (`top`, `bottom`, `left`, `right`, `rotation`, `offset`, `zIndex`) → `classify_prop`, `cdf_type: "string"`, `cdf_category: "design"`.
151
- 4. **Has `tokenReference`?** → `cdf_type: "token"`, resolve `token_kind` via sidecar lookup (see below). This overrides all other heuristics.
152
- 5. **Union of string literals** (e.g. `'a' | 'b' | 'c'`)? → `cdf_type: "enum"`, extract literals into `values`.
153
- 6. **Raw type is `string`** and prop name is `href`, `url`, or clearly a URL? → `cdf_type: "string"`, `cdf_category: "content"`.
154
- 7. **Raw type is `string` / `number` / `boolean`?** → For `boolean`, use `cdf_type: "boolean"` with `default: true` or `false` (native boolean). For `number`, use `cdf_type: "string"` with `default` as the numeric value as a string (e.g. `"0"`). For `string`, use `cdf_type: "string"`.
155
- 8. **Media/image type** (`ImageProps`, `MediaSource`, asset types)? → `cdf_type: "media"`.
156
- 9. **Rich text / markup** (`ReactNode` used as content, HTML string)? → `cdf_type: "richtext"`.
157
- 10. **Complex type — resolve before excluding** (see below).
134
+ 1. **Framework internal?** (`ref`, event handlers, `testId`, `data-testid`, `key`) → `exclude_prop`.
135
+ 2. **CSS design prop?** (`className`, `style`, `styles`, positional/geometric props like `top`, `bottom`, `left`, `right`, `rotation`, `offset`) `classify_prop`, `cdf_type: "string"`, `cdf_category: "design"`.
136
+ 3. **Has `tokenReference`?** `cdf_type: "token"`, resolve `token_kind` via sidecar lookup (see below). This overrides all other heuristics.
137
+ 4. **Union of string literals** (e.g. `'a' | 'b' | 'c'`)? `cdf_type: "enum"`, extract literals into `values`.
138
+ 5. **Raw type is `string`** and prop name is `href`, `url`, or clearly a URL? → `cdf_type: "string"`, `cdf_category: "content"`.
139
+ 6. **Raw type is `string` / `number` / `boolean`?** → For `boolean`, use `cdf_type: "boolean"` with `default: true` or `false` (native boolean). For `number`, use `cdf_type: "string"` with `default` as the numeric value as a string (e.g. `"0"`). For `string`, use `cdf_type: "string"`.
140
+ 7. **Media/image type** (`ImageProps`, `MediaSource`, asset types)? `cdf_type: "media"`.
141
+ 8. **Rich text / markup** (`ReactNode` used as content, HTML string)? `cdf_type: "richtext"`.
142
+ 9. **Complex typeresolve before excluding** (see below).
158
143
 
159
144
  ---
160
145
 
@@ -283,7 +268,7 @@ Input:
283
268
  {"name":"variant","type":"'primary'|'secondary'|'ghost'","category":"design","defaultValue":"'primary'"},
284
269
  {"name":"disabled","type":"boolean","category":"design"},
285
270
  {"name":"onClick","type":"()=>void","category":"state"},
286
- {"name":"className","type":"string"}
271
+ {"name":"className","type":"string","category":"design"}
287
272
  ],
288
273
  "slots": [{"name":"icon","description":"Optional leading icon"}]
289
274
  }
@@ -301,8 +286,8 @@ disabled is a boolean state prop — raw category says design, correcting to sta
301
286
  {"tool":"classify_prop","prop":"disabled","cdf_type":"boolean","cdf_category":"state","required":false,"default":false,"description":"Disables the button"}
302
287
  onClick is an event handler — framework internal
303
288
  {"tool":"exclude_prop","prop":"onClick","reason":"event handler — framework internal"}
304
- className is a DOM pass-through developers wire CSS, marketers never set this
305
- {"tool":"exclude_prop","prop":"className","reason":"DOM pass-through — not a marketer-configurable surface"}
289
+ className is a CSS design escape hatch classify as string/design
290
+ {"tool":"classify_prop","prop":"className","cdf_type":"string","cdf_category":"design","required":false,"description":"CSS class override"}
306
291
  icon slot is clearly optional (decorative leading icon)
307
292
  {"tool":"classify_slot","slot":"icon","required":false,"description":"Optional leading icon"}
308
293
  ```
@@ -352,7 +337,7 @@ Before emitting any tool calls, verify:
352
337
  5. Every `cdf_type: "token"` has `token_kind` (or a warning in `description` if lookup failed)
353
338
  6. No `cdf_type: "link"` — all href/url props use `string`
354
339
  7. `required` values are JSON booleans, not strings
355
- 8. Framework, DOM, accessibility, and data-* pass-through props are excluded — `className`/`classes`/`classNames`/`rootClassName`/`prefixCls`, `style`, `id`, `role`, `tabIndex`, `name` (bare HTML form attribute), `aria-*` (and bare `aria`), `data-*`, polymorphic `as`/`element`/`component`, framework theming `dt`/`pt`/`ptOptions`/`unstyled`/`sx`. Discrete positional/geometric props (`top`, `bottom`, `left`, `right`, `rotation`, etc.) ARE classified as `string` design props. Common semantic props (`icon`, `items`, `actions`, `options`, `value`, `form`, `inputId`, `componentId`) are NOT excluded — classify them per their content/design/state nature.
340
+ 8. Framework internals (`ref`, event handlers, test IDs) are excluded — `className`, `style`, and `styles` are classified as `string` design props; discrete positional/geometric props (`top`, `bottom`, `left`, `right`, `rotation`, etc.) are also classified
356
341
  9. No `cdf_type: "link"` used — `link` is reserved and rejected by the CLI parser
357
342
  10. No `cdf_type: "number"` used — this is not a supported type; use `"string"` with numeric defaults. `cdf_type: "boolean"` IS valid — use it for boolean toggle props.
358
343