@contentful/experience-design-system-extraction 2.26.1
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/LICENSE +21 -0
- package/dist/package.json +59 -0
- package/dist/src/extract/astro.d.ts +5 -0
- package/dist/src/extract/astro.js +289 -0
- package/dist/src/extract/non-authorable-filter.d.ts +16 -0
- package/dist/src/extract/non-authorable-filter.js +60 -0
- package/dist/src/extract/pipeline.d.ts +6 -0
- package/dist/src/extract/pipeline.js +314 -0
- package/dist/src/extract/react.d.ts +2 -0
- package/dist/src/extract/react.js +2310 -0
- package/dist/src/extract/scoring.d.ts +12 -0
- package/dist/src/extract/scoring.js +108 -0
- package/dist/src/extract/slot-allowed-components.d.ts +6 -0
- package/dist/src/extract/slot-allowed-components.js +40 -0
- package/dist/src/extract/slot-detection.d.ts +35 -0
- package/dist/src/extract/slot-detection.js +101 -0
- package/dist/src/extract/source-inspection.d.ts +13 -0
- package/dist/src/extract/source-inspection.js +189 -0
- package/dist/src/extract/stencil.d.ts +2 -0
- package/dist/src/extract/stencil.js +328 -0
- package/dist/src/extract/structural-slot-evidence.d.ts +36 -0
- package/dist/src/extract/structural-slot-evidence.js +121 -0
- package/dist/src/extract/svelte.d.ts +5 -0
- package/dist/src/extract/svelte.js +1357 -0
- package/dist/src/extract/tsx-shared.d.ts +15 -0
- package/dist/src/extract/tsx-shared.js +276 -0
- package/dist/src/extract/validate.d.ts +16 -0
- package/dist/src/extract/validate.js +94 -0
- package/dist/src/extract/vue-tsx.d.ts +2 -0
- package/dist/src/extract/vue-tsx.js +498 -0
- package/dist/src/extract/vue.d.ts +5 -0
- package/dist/src/extract/vue.js +653 -0
- package/dist/src/extract/web-components.d.ts +2 -0
- package/dist/src/extract/web-components.js +876 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +22 -0
- package/dist/src/pre-classify.d.ts +17 -0
- package/dist/src/pre-classify.js +225 -0
- package/dist/src/types.d.ts +91 -0
- package/dist/src/types.js +4 -0
- package/package.json +58 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type { RawComponentDefinition, RawPropDefinition, RawSlotDefinition, ComponentExtractionResult, ExtractorProgress, ExtractorOptions, ComponentExtractor, ExtractionValidationIssue, ExtractionValidationIssueCode, } from './types.js';
|
|
2
|
+
export { stripScoringFields } from './types.js';
|
|
3
|
+
export { extractComponents } from './extract/pipeline.js';
|
|
4
|
+
export { extractReactComponents } from './extract/react.js';
|
|
5
|
+
export { extractVueComponents } from './extract/vue.js';
|
|
6
|
+
export { extractVueTsxComponents } from './extract/vue-tsx.js';
|
|
7
|
+
export { extractStencilComponents } from './extract/stencil.js';
|
|
8
|
+
export { extractAstroComponents } from './extract/astro.js';
|
|
9
|
+
export { extractWebComponentDefinitions } from './extract/web-components.js';
|
|
10
|
+
export { extractSvelteComponents } from './extract/svelte.js';
|
|
11
|
+
export { extractAllowedComponentsFromTypeText, extractAllowedComponentsFromJsdoc, } from './extract/slot-allowed-components.js';
|
|
12
|
+
export { isNonAuthorableComponent } from './extract/non-authorable-filter.js';
|
|
13
|
+
export { computeExtractionScore, deriveNeedsReview } from './extract/scoring.js';
|
|
14
|
+
export type { ExtractionScore, ExtractionScoreOptions, ExtractionConfidence } from './extract/scoring.js';
|
|
15
|
+
export { inspectComponentSource, describeReviewReasons, describeReviewReason, isDataWrapperReviewReason, HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON, POSSIBLE_DATA_FETCH_WRAPPER_REASON, ZERO_SURFACE_RENDERED_UI_REASON, } from './extract/source-inspection.js';
|
|
16
|
+
export type { ComponentSourceInspection } from './extract/source-inspection.js';
|
|
17
|
+
export { validateExtractedComponents, shouldExcludeDueToValidation, formatExclusionWarning, } from './extract/validate.js';
|
|
18
|
+
export { CONTENT_NAME_EXCEPTIONS, isReactNodeType, isArrayReactNodeType, shouldBeSlot, } from './extract/slot-detection.js';
|
|
19
|
+
export { preClassifyProp, preClassifyComponent } from './pre-classify.js';
|
|
20
|
+
export type { PreClassification } from './pre-classify.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { stripScoringFields } from './types.js';
|
|
2
|
+
// Core extraction pipeline
|
|
3
|
+
export { extractComponents } from './extract/pipeline.js';
|
|
4
|
+
// Framework-specific extractors
|
|
5
|
+
export { extractReactComponents } from './extract/react.js';
|
|
6
|
+
export { extractVueComponents } from './extract/vue.js';
|
|
7
|
+
export { extractVueTsxComponents } from './extract/vue-tsx.js';
|
|
8
|
+
export { extractStencilComponents } from './extract/stencil.js';
|
|
9
|
+
export { extractAstroComponents } from './extract/astro.js';
|
|
10
|
+
export { extractWebComponentDefinitions } from './extract/web-components.js';
|
|
11
|
+
export { extractSvelteComponents } from './extract/svelte.js';
|
|
12
|
+
export { extractAllowedComponentsFromTypeText, extractAllowedComponentsFromJsdoc, } from './extract/slot-allowed-components.js';
|
|
13
|
+
// Post-extraction filtering and scoring
|
|
14
|
+
export { isNonAuthorableComponent } from './extract/non-authorable-filter.js';
|
|
15
|
+
export { computeExtractionScore, deriveNeedsReview } from './extract/scoring.js';
|
|
16
|
+
export { inspectComponentSource, describeReviewReasons, describeReviewReason, isDataWrapperReviewReason, HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON, POSSIBLE_DATA_FETCH_WRAPPER_REASON, ZERO_SURFACE_RENDERED_UI_REASON, } from './extract/source-inspection.js';
|
|
17
|
+
// Validation
|
|
18
|
+
export { validateExtractedComponents, shouldExcludeDueToValidation, formatExclusionWarning, } from './extract/validate.js';
|
|
19
|
+
// Slot detection helpers
|
|
20
|
+
export { CONTENT_NAME_EXCEPTIONS, isReactNodeType, isArrayReactNodeType, shouldBeSlot, } from './extract/slot-detection.js';
|
|
21
|
+
// Pre-classification
|
|
22
|
+
export { preClassifyProp, preClassifyComponent } from './pre-classify.js';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RawPropDefinition, RawComponentDefinition } from './types.js';
|
|
2
|
+
export interface PreClassification {
|
|
3
|
+
category: 'content' | 'design' | 'state' | 'exclude';
|
|
4
|
+
cdfTypeHint?: 'string' | 'enum' | 'richtext' | 'media' | 'boolean';
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Deterministic pre-classification rule engine.
|
|
8
|
+
* Applies rules in priority order and returns on the first match.
|
|
9
|
+
*/
|
|
10
|
+
export declare function preClassifyProp(prop: RawPropDefinition): PreClassification | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Applies pre-classification to all props in a component definition.
|
|
13
|
+
* - Leaves existing category values unchanged
|
|
14
|
+
* - Sets category for content/design/state matches
|
|
15
|
+
* - Removes props that match an exclusion rule so they cannot reach agent classification
|
|
16
|
+
*/
|
|
17
|
+
export declare function preClassifyComponent(component: RawComponentDefinition): RawComponentDefinition;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether a type string represents a simple/primitive type
|
|
3
|
+
* (string, boolean, number, or string literal union) vs a complex type
|
|
4
|
+
* (object, function, array, generic, etc.).
|
|
5
|
+
*/
|
|
6
|
+
function isSimpleType(type) {
|
|
7
|
+
const t = type.trim();
|
|
8
|
+
if (t === 'string' || t === 'boolean' || t === 'number')
|
|
9
|
+
return true;
|
|
10
|
+
// String literal union (e.g., "'a' | 'b'")
|
|
11
|
+
if (isStringLiteralUnion(t))
|
|
12
|
+
return true;
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
function isStringLiteralUnion(type) {
|
|
16
|
+
return type.includes('|') && type.includes("'");
|
|
17
|
+
}
|
|
18
|
+
function isBooleanType(type) {
|
|
19
|
+
return type.trim() === 'boolean';
|
|
20
|
+
}
|
|
21
|
+
function isStringType(type) {
|
|
22
|
+
return type.trim() === 'string';
|
|
23
|
+
}
|
|
24
|
+
function isNumberType(type) {
|
|
25
|
+
return type.trim() === 'number';
|
|
26
|
+
}
|
|
27
|
+
function isComplexType(type) {
|
|
28
|
+
return !isSimpleType(type);
|
|
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
|
+
'htmlFor',
|
|
46
|
+
'for',
|
|
47
|
+
'slot',
|
|
48
|
+
'is',
|
|
49
|
+
'lang',
|
|
50
|
+
'dir',
|
|
51
|
+
'hidden',
|
|
52
|
+
'draggable',
|
|
53
|
+
'spellCheck',
|
|
54
|
+
'spellcheck',
|
|
55
|
+
'contentEditable',
|
|
56
|
+
'contenteditable',
|
|
57
|
+
'inputMode',
|
|
58
|
+
'inputmode',
|
|
59
|
+
'autoComplete',
|
|
60
|
+
'autocomplete',
|
|
61
|
+
'autoFocus',
|
|
62
|
+
'autofocus',
|
|
63
|
+
'translate',
|
|
64
|
+
'part',
|
|
65
|
+
'exportparts',
|
|
66
|
+
'aria',
|
|
67
|
+
// Framework theming / pass-through escape hatches — dev-facing, never marketer-configurable
|
|
68
|
+
'dt',
|
|
69
|
+
'pt',
|
|
70
|
+
'ptOptions',
|
|
71
|
+
'unstyled',
|
|
72
|
+
'sx',
|
|
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
|
+
/**
|
|
95
|
+
* Deterministic pre-classification rule engine.
|
|
96
|
+
* Applies rules in priority order and returns on the first match.
|
|
97
|
+
*/
|
|
98
|
+
export function preClassifyProp(prop) {
|
|
99
|
+
const { name, type } = prop;
|
|
100
|
+
// Rule 1: Event handlers
|
|
101
|
+
// name starts with `on` + uppercase, OR type contains `=> void` or `EventHandler`
|
|
102
|
+
if (/^on[A-Z]/.test(name) || type.includes('=> void') || type.includes('EventHandler')) {
|
|
103
|
+
return { category: 'exclude' };
|
|
104
|
+
}
|
|
105
|
+
// Rule 2: Refs
|
|
106
|
+
if (name === 'ref' || name === 'innerRef' || type.includes('Ref<') || type.includes('RefObject<')) {
|
|
107
|
+
return { category: 'exclude' };
|
|
108
|
+
}
|
|
109
|
+
// Rule 3: Test IDs
|
|
110
|
+
if (name === 'testId' || name === 'data-testid' || name === 'dataTestId') {
|
|
111
|
+
return { category: 'exclude' };
|
|
112
|
+
}
|
|
113
|
+
// Rule 4: Key prop
|
|
114
|
+
if (name === 'key') {
|
|
115
|
+
return { category: 'exclude' };
|
|
116
|
+
}
|
|
117
|
+
// Rule 5: Dispatch/setter
|
|
118
|
+
if (type.includes('Dispatch<') || type.includes('SetStateAction')) {
|
|
119
|
+
return { category: 'exclude' };
|
|
120
|
+
}
|
|
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' };
|
|
127
|
+
}
|
|
128
|
+
// `name` is overloaded: form controls forward it to the DOM, while icons,
|
|
129
|
+
// flags, and animations often use it as an authorable semantic selector.
|
|
130
|
+
// Exclude only when the extractor retained concrete DOM provenance.
|
|
131
|
+
if (name === 'name' && prop.domAttribute) {
|
|
132
|
+
return { category: 'exclude' };
|
|
133
|
+
}
|
|
134
|
+
// Rule 7: String literal union
|
|
135
|
+
if (isStringLiteralUnion(type)) {
|
|
136
|
+
return { category: 'design', cdfTypeHint: 'enum' };
|
|
137
|
+
}
|
|
138
|
+
// Rule 8: Design name patterns (only for simple types)
|
|
139
|
+
if (!isComplexType(type)) {
|
|
140
|
+
const designNameStart = /^(variant|size|spacing|gap|color|bg|theme|align|layout|orientation|position)/i;
|
|
141
|
+
const designNameEnd = /(Color|Size|Variant|Style)$/;
|
|
142
|
+
if (designNameStart.test(name) || designNameEnd.test(name)) {
|
|
143
|
+
return { category: 'design', cdfTypeHint: 'string' };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Rule 10: Boolean + state names (checked before rule 9 since state names
|
|
147
|
+
// like "disabled" would otherwise match the visual toggle prefix "disable")
|
|
148
|
+
if (isBooleanType(type)) {
|
|
149
|
+
const stateNames = ['disabled', 'loading', 'expanded', 'isOpen', 'selected', 'checked', 'active', 'preview'];
|
|
150
|
+
if (stateNames.includes(name)) {
|
|
151
|
+
return { category: 'state', cdfTypeHint: 'boolean' };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Rule 9: Boolean + visual toggle name
|
|
155
|
+
if (isBooleanType(type)) {
|
|
156
|
+
const visualToggle = /^(hide|show|enable|disable|vertical|horizontal|reverse|bold|italic|imageOn|with)/i;
|
|
157
|
+
if (visualToggle.test(name)) {
|
|
158
|
+
return { category: 'design', cdfTypeHint: 'boolean' };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Rule 11: State identifiers
|
|
162
|
+
if (name === 'componentId' || name === 'sectionKey' || name === 'locale' || name === 'variantIndex') {
|
|
163
|
+
return { category: 'state', cdfTypeHint: 'string' };
|
|
164
|
+
}
|
|
165
|
+
// Rule 12: URL patterns (string type only)
|
|
166
|
+
if (isStringType(type)) {
|
|
167
|
+
const urlNameStart = /^(href|url|link|src)/i;
|
|
168
|
+
const urlNameEnd = /(Url|Href|Link|Src)$/;
|
|
169
|
+
if (urlNameStart.test(name) || urlNameEnd.test(name)) {
|
|
170
|
+
return { category: 'content', cdfTypeHint: 'string' };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Rule 13: Text patterns (string type only)
|
|
174
|
+
if (isStringType(type)) {
|
|
175
|
+
const textNameStart = /^(label|title|text|description|caption|heading|subheading|body|alt|name|placeholder|summary)/i;
|
|
176
|
+
const textNameEnd = /(Text|Label|Title|Name)$/;
|
|
177
|
+
if (textNameStart.test(name) || textNameEnd.test(name)) {
|
|
178
|
+
return { category: 'content', cdfTypeHint: 'string' };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Rule 14: Remaining strings
|
|
182
|
+
if (isStringType(type)) {
|
|
183
|
+
return { category: 'content', cdfTypeHint: 'string' };
|
|
184
|
+
}
|
|
185
|
+
// Rule 15: Remaining booleans
|
|
186
|
+
if (isBooleanType(type)) {
|
|
187
|
+
return { category: 'design', cdfTypeHint: 'boolean' };
|
|
188
|
+
}
|
|
189
|
+
// Rule 16: Remaining numbers
|
|
190
|
+
if (isNumberType(type)) {
|
|
191
|
+
return { category: 'design', cdfTypeHint: 'string' };
|
|
192
|
+
}
|
|
193
|
+
// Rule 17: Complex/object/function/array types — no hint
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Applies pre-classification to all props in a component definition.
|
|
198
|
+
* - Leaves existing category values unchanged
|
|
199
|
+
* - Sets category for content/design/state matches
|
|
200
|
+
* - Removes props that match an exclusion rule so they cannot reach agent classification
|
|
201
|
+
*/
|
|
202
|
+
export function preClassifyComponent(component) {
|
|
203
|
+
const props = component.props.flatMap((prop) => {
|
|
204
|
+
const result = preClassifyProp(prop);
|
|
205
|
+
// Excluded props are developer-facing wiring and must not be included in
|
|
206
|
+
// the component payload passed to classification or generation, even if a
|
|
207
|
+
// prior step assigned them a category.
|
|
208
|
+
if (result?.category === 'exclude') {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
// Provenance is extraction-only evidence. Do not add it to the payload
|
|
212
|
+
// presented to downstream agents.
|
|
213
|
+
const { domAttribute: _domAttribute, ...authorableProp } = prop;
|
|
214
|
+
// If category is already set, leave unchanged
|
|
215
|
+
if (prop.category) {
|
|
216
|
+
return [authorableProp];
|
|
217
|
+
}
|
|
218
|
+
if (!result) {
|
|
219
|
+
return [authorableProp];
|
|
220
|
+
}
|
|
221
|
+
// Set category hint
|
|
222
|
+
return [{ ...authorableProp, category: result.category }];
|
|
223
|
+
});
|
|
224
|
+
return { ...component, props };
|
|
225
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export type ExtractionValidationIssueCode = 'EMPTY_COMPONENT_NAME' | 'EMPTY_PROP_NAME' | 'EMPTY_SLOT_NAME' | 'PROP_SLOT_NAME_COLLISION' | 'DUPLICATE_COMPONENT_NAME' | 'EMPTY_COMPONENT' | 'SERVER_VALIDATION_FAILED';
|
|
2
|
+
export type ExtractionValidationIssue = {
|
|
3
|
+
severity: 'error' | 'warning';
|
|
4
|
+
code: ExtractionValidationIssueCode;
|
|
5
|
+
message: string;
|
|
6
|
+
field?: string;
|
|
7
|
+
};
|
|
8
|
+
export interface RawPropDefinition {
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
required: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* True when extraction can prove that the prop is forwarded to the
|
|
14
|
+
* same-named attribute on an intrinsic DOM element. This distinguishes
|
|
15
|
+
* overloaded names such as the form attribute `name` from semantic props
|
|
16
|
+
* that select visible content (for example an icon or flag name).
|
|
17
|
+
*/
|
|
18
|
+
domAttribute?: boolean;
|
|
19
|
+
category?: 'content' | 'design' | 'state';
|
|
20
|
+
defaultValue?: string;
|
|
21
|
+
allowedValues?: string[];
|
|
22
|
+
description?: string;
|
|
23
|
+
tokenReference?: string;
|
|
24
|
+
/** 1-indexed source line where this prop's declaration begins; relative to RawComponentDefinition.source. */
|
|
25
|
+
sourceStartLine?: number;
|
|
26
|
+
/** 1-indexed inclusive source line where this prop's declaration ends; relative to RawComponentDefinition.source. */
|
|
27
|
+
sourceEndLine?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface RawSlotDefinition {
|
|
30
|
+
name: string;
|
|
31
|
+
isDefault: boolean;
|
|
32
|
+
description?: string;
|
|
33
|
+
allowedComponents?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Component names implied by usage evidence (a runtime type-predicate
|
|
36
|
+
* function, a `.type === Component` identity check, or direct JSX
|
|
37
|
+
* instantiation) rather than a declared slot contract. Kept separate from
|
|
38
|
+
* `allowedComponents` so downstream provenance stays honest — this is a
|
|
39
|
+
* lower-trust signal that a declared contract always overrides.
|
|
40
|
+
*/
|
|
41
|
+
structuralAllowedComponents?: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface RawComponentDefinition {
|
|
44
|
+
name: string;
|
|
45
|
+
source: string;
|
|
46
|
+
framework: 'react' | 'next' | 'vue' | 'astro' | 'web-component' | 'stencil' | 'svelte';
|
|
47
|
+
props: RawPropDefinition[];
|
|
48
|
+
slots: RawSlotDefinition[];
|
|
49
|
+
/**
|
|
50
|
+
* True when the source file declaring this component calls
|
|
51
|
+
* React.createContext / createContext. Used downstream to filter
|
|
52
|
+
* non-authorable context-provider components.
|
|
53
|
+
*/
|
|
54
|
+
usesCreateContext?: boolean;
|
|
55
|
+
extractionConfidence?: number | null;
|
|
56
|
+
reviewReasons?: string[];
|
|
57
|
+
needsReview?: boolean;
|
|
58
|
+
validationIssues?: ExtractionValidationIssue[];
|
|
59
|
+
/** Absolute path to the source file this component was extracted from. Null for synthesized / multi-file. */
|
|
60
|
+
sourcePath?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ComponentExtractionResult {
|
|
63
|
+
components: RawComponentDefinition[];
|
|
64
|
+
warnings: string[];
|
|
65
|
+
}
|
|
66
|
+
export type ExtractorProgress = {
|
|
67
|
+
filesProcessed: number;
|
|
68
|
+
componentsFound: number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Optional extraction-time settings forwarded from the CLI through the
|
|
72
|
+
* pipeline to each extractor. Only the Svelte extractor currently consumes
|
|
73
|
+
* any of these; other extractors ignore the value.
|
|
74
|
+
*/
|
|
75
|
+
export interface ExtractorOptions {
|
|
76
|
+
/**
|
|
77
|
+
* Whether the Svelte extractor should run a retry pass for components whose
|
|
78
|
+
* declared Props type couldn't be resolved on the first pass (cross-package
|
|
79
|
+
* extends, path-alias-only types, etc.). See svelte.ts for the policy.
|
|
80
|
+
*/
|
|
81
|
+
resolveUnreachable?: 'auto' | 'always' | 'never';
|
|
82
|
+
/** Absolute project root — used by the retry pass to locate tsconfig.json and node_modules. */
|
|
83
|
+
projectRoot?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface ComponentExtractor {
|
|
86
|
+
name: string;
|
|
87
|
+
fileFilter: (filePath: string) => boolean;
|
|
88
|
+
extract(filePaths: string[], onProgress?: (p: ExtractorProgress) => void, opts?: ExtractorOptions): Promise<ComponentExtractionResult>;
|
|
89
|
+
}
|
|
90
|
+
/** Strip internal scoring fields before serialising a RawComponentDefinition for display or editing. */
|
|
91
|
+
export declare function stripScoringFields({ extractionConfidence: _c, reviewReasons: _r, needsReview: _n, ...rest }: RawComponentDefinition): Omit<RawComponentDefinition, 'extractionConfidence' | 'reviewReasons' | 'needsReview'>;
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contentful/experience-design-system-extraction",
|
|
3
|
+
"version": "2.26.1",
|
|
4
|
+
"description": "Component extraction engine for the Contentful Experience Design System SDK",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/src/index.js",
|
|
8
|
+
"types": "./dist/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/src/index.d.ts",
|
|
12
|
+
"import": "./dist/src/index.js",
|
|
13
|
+
"node": "./dist/src/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://npm.pkg.github.com/"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@vue/compiler-sfc": "^3.5.31",
|
|
25
|
+
"svelte": "^5.56.4",
|
|
26
|
+
"ts-morph": "^27.0.2",
|
|
27
|
+
"typescript": "^5.9.3"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@tsconfig/node24": "^24.0.4",
|
|
31
|
+
"@types/node": "^24.0.3",
|
|
32
|
+
"eslint": "^9.39.5",
|
|
33
|
+
"eslint-config-prettier": "^10.1.8",
|
|
34
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
35
|
+
"typescript-eslint": "^8.67.0",
|
|
36
|
+
"vitest": "^4.0.16"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/contentful/experience-design-system-sdk-public.git",
|
|
41
|
+
"directory": "packages/experience-design-system-extraction"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/contentful/experience-design-system-sdk-public#readme",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/contentful/experience-design-system-sdk-public/issues"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=24"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "nx build experience-design-system-extraction",
|
|
52
|
+
"typecheck": "nx typecheck experience-design-system-extraction",
|
|
53
|
+
"clean": "nx clean experience-design-system-extraction",
|
|
54
|
+
"test": "nx test experience-design-system-extraction",
|
|
55
|
+
"lint": "nx lint experience-design-system-extraction",
|
|
56
|
+
"lint:fix": "nx lint:fix experience-design-system-extraction"
|
|
57
|
+
}
|
|
58
|
+
}
|