@contentful/experience-design-system-extraction 2.36.2-dev-build-a6f80ae6.0 → 2.36.2-dev-build-450d231a.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 +1 -1
- package/dist/src/extract/controller/extract-controller.d.ts +10 -0
- package/dist/src/extract/controller/extract-controller.js +33 -0
- package/dist/src/extract/controller/helpers/validate-endpoint-request.d.ts +2 -0
- package/dist/src/extract/controller/helpers/validate-endpoint-request.js +24 -0
- package/dist/src/extract/{astro.d.ts → framework-adapters/astro/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/astro/extractor.js +45 -0
- package/dist/src/extract/framework-adapters/astro/frontmatter.d.ts +11 -0
- package/dist/src/extract/framework-adapters/astro/frontmatter.js +96 -0
- package/dist/src/extract/framework-adapters/astro/helpers/collect-astro-props-bindings.d.ts +4 -0
- package/dist/src/extract/framework-adapters/astro/helpers/collect-astro-props-bindings.js +47 -0
- package/dist/src/extract/framework-adapters/astro/slots.d.ts +7 -0
- package/dist/src/extract/framework-adapters/astro/slots.js +44 -0
- package/dist/src/extract/{react.d.ts → framework-adapters/react/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/react/extractor.js +31 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-dom-wrapper-contexts.d.ts +4 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-dom-wrapper-contexts.js +73 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-prop-dataflow.d.ts +14 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-prop-dataflow.js +220 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-react-impl-hints.d.ts +5 -0
- package/dist/src/extract/framework-adapters/react/helpers/collect-react-impl-hints.js +32 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-dom-is-pure-wrapper.d.ts +2 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-dom-is-pure-wrapper.js +59 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-dom-type-patterns.d.ts +8 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-dom-type-patterns.js +29 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-omit-wrapped-custom-props.d.ts +2 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-omit-wrapped-custom-props.js +64 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-pick-type-patterns.d.ts +4 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-pick-type-patterns.js +64 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-react-polymorphic.d.ts +5 -0
- package/dist/src/extract/framework-adapters/react/helpers/detect-react-polymorphic.js +170 -0
- package/dist/src/extract/framework-adapters/react/helpers/dom-attribute-surfaces.d.ts +15 -0
- package/dist/src/extract/framework-adapters/react/helpers/dom-attribute-surfaces.js +231 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-binding-fallback-props.d.ts +4 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-binding-fallback-props.js +50 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-from-react-source-file.d.ts +5 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-from-react-source-file.js +23 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-allowed-components.d.ts +2 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-allowed-components.js +25 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-binding-defaults.d.ts +6 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-binding-defaults.js +48 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-component-from-export.d.ts +15 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-component-from-export.js +106 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-prop-types.d.ts +3 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-prop-types.js +64 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-props-from-type.d.ts +15 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-props-from-type.js +318 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-slots.d.ts +6 -0
- package/dist/src/extract/framework-adapters/react/helpers/extract-react-slots.js +44 -0
- package/dist/src/extract/framework-adapters/react/helpers/filter-impl-alias-props.d.ts +4 -0
- package/dist/src/extract/framework-adapters/react/helpers/filter-impl-alias-props.js +52 -0
- package/dist/src/extract/framework-adapters/react/helpers/infer-primitive-dom-props.d.ts +6 -0
- package/dist/src/extract/framework-adapters/react/helpers/infer-primitive-dom-props.js +69 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-component-function.d.ts +4 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-component-function.js +131 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-react-prop-forwarding.d.ts +8 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-react-prop-forwarding.js +22 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-react-props-type.d.ts +14 -0
- package/dist/src/extract/framework-adapters/react/helpers/resolve-react-props-type.js +86 -0
- package/dist/src/extract/framework-adapters/react/helpers/synthesize-react-structural-slots.d.ts +8 -0
- package/dist/src/extract/framework-adapters/react/helpers/synthesize-react-structural-slots.js +44 -0
- package/dist/src/extract/framework-adapters/shared/helpers/build-component-lookup-maps.d.ts +5 -0
- package/dist/src/extract/framework-adapters/shared/helpers/build-component-lookup-maps.js +10 -0
- package/dist/src/extract/framework-adapters/shared/helpers/collect-jsdoc-slot-comments.d.ts +2 -0
- package/dist/src/extract/framework-adapters/shared/helpers/collect-jsdoc-slot-comments.js +13 -0
- package/dist/src/extract/{file-extraction-workers.d.ts → framework-adapters/shared/helpers/file-processing/file-workers.d.ts} +1 -13
- package/dist/src/extract/{file-extraction-workers.js → framework-adapters/shared/helpers/file-processing/file-workers.js} +0 -19
- package/dist/src/extract/framework-adapters/shared/helpers/file-processing/project-source-files.d.ts +5 -0
- package/dist/src/extract/framework-adapters/shared/helpers/file-processing/project-source-files.js +13 -0
- package/dist/src/extract/framework-adapters/shared/helpers/file-processing/result-normalizer.d.ts +6 -0
- package/dist/src/extract/framework-adapters/shared/helpers/file-processing/result-normalizer.js +6 -0
- package/dist/src/extract/framework-adapters/shared/helpers/find-tsx-workspace-package.d.ts +2 -0
- package/dist/src/extract/framework-adapters/shared/helpers/find-tsx-workspace-package.js +62 -0
- package/dist/src/extract/{source-line-metadata.d.ts → framework-adapters/shared/helpers/get-node-source-lines.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-tsconfig-path.d.ts +7 -0
- package/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-tsconfig-path.js +93 -0
- package/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-workspace-imports.d.ts +6 -0
- package/dist/src/extract/framework-adapters/shared/helpers/resolve-tsx-workspace-imports.js +58 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-node-utils.d.ts +13 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-node-utils.js +76 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-renderable-exports.d.ts +12 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-renderable-exports.js +35 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-shared.d.ts +14 -0
- package/dist/src/extract/framework-adapters/shared/helpers/tsx-shared.js +54 -0
- package/dist/src/extract/{stencil.d.ts → framework-adapters/stencil/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/stencil/extractor.js +82 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/detect-stencil-class.d.ts +7 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/detect-stencil-class.js +32 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-props.d.ts +5 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-props.js +62 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-slots.d.ts +6 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/extract-stencil-slots.js +87 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/stencil-prop-helpers.d.ts +5 -0
- package/dist/src/extract/framework-adapters/stencil/helpers/stencil-prop-helpers.js +39 -0
- package/dist/src/extract/{svelte.d.ts → framework-adapters/svelte/extractor.d.ts} +2 -1
- package/dist/src/extract/framework-adapters/svelte/extractor.js +27 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/classify-svelte-props-annotation.d.ts +6 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/classify-svelte-props-annotation.js +51 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/collect-svelte-type-references.d.ts +3 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/collect-svelte-type-references.js +52 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-from-svelte-file.d.ts +7 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-from-svelte-file.js +90 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-ast-type-members.d.ts +15 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-ast-type-members.js +46 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-declaration-data.d.ts +7 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-declaration-data.js +64 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-external-type-members.d.ts +4 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-external-type-members.js +58 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-from-destructure.d.ts +4 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-from-destructure.js +85 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-props.d.ts +22 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-props.js +55 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-template-slots.d.ts +7 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-template-slots.js +63 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-type-member-props.d.ts +3 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/extract-svelte-type-member-props.js +31 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/find-svelte-script-declarations.d.ts +8 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/find-svelte-script-declarations.js +91 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/get-svelte-component-name.d.ts +1 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/get-svelte-component-name.js +26 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/render-svelte-type-strings.d.ts +3 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/render-svelte-type-strings.js +91 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/render-svelte-type.d.ts +11 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/render-svelte-type.js +68 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-dts-location.d.ts +1 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-dts-location.js +90 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-allowed-components.d.ts +2 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-allowed-components.js +20 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-external-type-readers.d.ts +3 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-external-type-readers.js +68 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-type-checker.d.ts +4 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-type-checker.js +68 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-type-members.d.ts +6 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-type-members.js +30 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-unresolved-retry.d.ts +13 -0
- package/dist/src/extract/framework-adapters/svelte/helpers/resolve-svelte-unresolved-retry.js +192 -0
- package/dist/src/extract/framework-adapters/svelte/types/svelte-ast-node.d.ts +12 -0
- package/dist/src/extract/framework-adapters/svelte/types/svelte-ast-node.js +1 -0
- package/dist/src/extract/{vue.d.ts → framework-adapters/vue/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/vue/extractor.js +61 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-object-props.d.ts +3 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-object-props.js +67 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-options-props.d.ts +4 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-options-props.js +72 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-object-props.d.ts +8 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-object-props.js +64 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-props.d.ts +2 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-setup-props.js +66 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-slots.d.ts +24 -0
- package/dist/src/extract/framework-adapters/vue/helpers/extract-vue-slots.js +56 -0
- package/dist/src/extract/framework-adapters/vue/helpers/resolve-vue-component-name.d.ts +2 -0
- package/dist/src/extract/framework-adapters/vue/helpers/resolve-vue-component-name.js +9 -0
- package/dist/src/extract/framework-adapters/vue/helpers/resolve-workspace-module.d.ts +1 -0
- package/dist/src/extract/framework-adapters/vue/helpers/resolve-workspace-module.js +76 -0
- package/dist/src/extract/framework-adapters/vue/helpers/workspace-package-dirs.d.ts +2 -0
- package/dist/src/extract/framework-adapters/vue/helpers/workspace-package-dirs.js +77 -0
- package/dist/src/extract/{vue-tsx.d.ts → framework-adapters/vue-tsx/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/vue-tsx/extractor.js +82 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-props.d.ts +5 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-props.js +189 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-slots.d.ts +4 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/extract-vue-tsx-slots.js +91 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/resolve-ast-object.d.ts +11 -0
- package/dist/src/extract/framework-adapters/vue-tsx/helpers/resolve-ast-object.js +95 -0
- package/dist/src/extract/{web-components.d.ts → framework-adapters/web-components/extractor.d.ts} +1 -1
- package/dist/src/extract/framework-adapters/web-components/extractor.js +55 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/collect-wc-html-templates.d.ts +4 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/collect-wc-html-templates.js +67 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/detect-wc-non-public-members.d.ts +9 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/detect-wc-non-public-members.js +11 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-accessor-props.d.ts +3 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-accessor-props.js +65 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-class-properties.d.ts +3 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-class-properties.js +60 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-inheritance.d.ts +4 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-inheritance.js +16 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-jsdoc-attr-props.d.ts +3 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-jsdoc-attr-props.js +24 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-observed-attrs.d.ts +3 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-observed-attrs.js +27 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-slots.d.ts +6 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-slots.js +56 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-template-content.d.ts +4 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/extract-wc-template-content.js +49 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/merge-wc-prop-lists.d.ts +9 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/merge-wc-prop-lists.js +19 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-base-class.d.ts +2 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-base-class.js +59 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-decorator-tag.d.ts +2 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-decorator-tag.js +54 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import-source.d.ts +7 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import-source.js +47 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import.d.ts +4 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-import.js +93 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-sibling-definition.d.ts +4 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-sibling-definition.js +79 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-tag-name.d.ts +7 -0
- package/dist/src/extract/framework-adapters/web-components/helpers/resolve-wc-tag-name.js +62 -0
- package/dist/src/extract/helpers/evidence/ast/collect-structural-jsx-evidence.d.ts +5 -0
- package/dist/src/extract/helpers/evidence/ast/collect-structural-jsx-evidence.js +63 -0
- package/dist/src/extract/helpers/evidence/ast/detect-react-node-types.d.ts +2 -0
- package/dist/src/extract/helpers/evidence/ast/detect-react-node-types.js +24 -0
- package/dist/src/extract/helpers/evidence/ast/get-jsx-ast-data.d.ts +14 -0
- package/dist/src/extract/helpers/evidence/ast/get-jsx-ast-data.js +85 -0
- package/dist/src/extract/helpers/evidence/collect-jsx-component-references.d.ts +5 -0
- package/dist/src/extract/helpers/evidence/collect-jsx-component-references.js +52 -0
- package/dist/src/extract/helpers/evidence/detect-slot-from-prop.d.ts +16 -0
- package/dist/src/extract/helpers/evidence/detect-slot-from-prop.js +39 -0
- package/dist/src/extract/orchestrator/execute-extraction-orchestrator.d.ts +13 -0
- package/dist/src/extract/orchestrator/execute-extraction-orchestrator.js +17 -0
- package/dist/src/{pre-classify.d.ts → extract/services/classification/classify-component-props.d.ts} +3 -5
- package/dist/src/{pre-classify.js → extract/services/classification/classify-component-props.js} +8 -100
- package/dist/src/extract/services/classification/helpers/check-prop-types.d.ts +7 -0
- package/dist/src/extract/services/classification/helpers/check-prop-types.js +22 -0
- package/dist/src/extract/services/classification/helpers/detect-dom-props.d.ts +2 -0
- package/dist/src/extract/services/classification/helpers/detect-dom-props.js +63 -0
- package/dist/src/extract/services/deduplication/deduplicate-components.d.ts +2 -0
- package/dist/src/extract/services/deduplication/deduplicate-components.js +58 -0
- package/dist/src/extract/services/deduplication/helpers/component-path-analysis.d.ts +10 -0
- package/dist/src/extract/services/deduplication/helpers/component-path-analysis.js +85 -0
- package/dist/src/extract/services/deduplication/helpers/component-path-scoring.d.ts +10 -0
- package/dist/src/extract/services/deduplication/helpers/component-path-scoring.js +73 -0
- package/dist/src/extract/services/extraction/extract-components.d.ts +3 -0
- package/dist/src/extract/services/extraction/extract-components.js +19 -0
- package/dist/src/extract/services/extraction/helpers/collect-sveltekit-route-exclusions.d.ts +2 -0
- package/dist/src/extract/services/extraction/helpers/collect-sveltekit-route-exclusions.js +18 -0
- package/dist/src/extract/services/extraction/helpers/filter-hook-components.d.ts +6 -0
- package/dist/src/extract/services/extraction/helpers/filter-hook-components.js +18 -0
- package/dist/src/extract/services/extraction/helpers/register-extractors.d.ts +8 -0
- package/dist/src/extract/services/extraction/helpers/register-extractors.js +71 -0
- package/dist/src/extract/services/extraction/helpers/run-extractor-batches.d.ts +4 -0
- package/dist/src/extract/services/extraction/helpers/run-extractor-batches.js +24 -0
- package/dist/src/extract/services/quality/evaluate-extraction-quality.d.ts +4 -0
- package/dist/src/extract/services/quality/evaluate-extraction-quality.js +61 -0
- package/dist/src/extract/services/quality/helpers/authorability/evaluate-authorability.d.ts +28 -0
- package/dist/src/extract/services/quality/helpers/authorability/evaluate-authorability.js +67 -0
- package/dist/src/extract/services/quality/helpers/inspection/detect-data-wrapper-patterns.d.ts +16 -0
- package/dist/src/extract/services/quality/helpers/inspection/detect-data-wrapper-patterns.js +63 -0
- package/dist/src/extract/{source-inspection.d.ts → services/quality/helpers/inspection/inspect-component-source.d.ts} +3 -6
- package/dist/src/extract/{source-inspection.js → services/quality/helpers/inspection/inspect-component-source.js} +5 -65
- package/dist/src/extract/{validate.d.ts → services/quality/helpers/inspection/validate-extracted-components.d.ts} +1 -1
- package/dist/src/extract/services/quality/helpers/scoring/collect-scoring-inputs.d.ts +14 -0
- package/dist/src/extract/{scoring.js → services/quality/helpers/scoring/collect-scoring-inputs.js} +10 -24
- package/dist/src/extract/services/quality/helpers/scoring/compute-extraction-score.d.ts +6 -0
- package/dist/src/extract/services/quality/helpers/scoring/compute-extraction-score.js +12 -0
- package/dist/src/extract/types/classification.d.ts +4 -0
- package/dist/src/extract/types/classification.js +1 -0
- package/dist/src/extract/types/component-extractor.d.ts +7 -0
- package/dist/src/extract/types/component-extractor.js +1 -0
- package/dist/src/{types.d.ts → extract/types/component.d.ts} +0 -22
- package/dist/src/extract/types/component.js +1 -0
- package/dist/src/extract/types/contract.d.ts +16 -0
- package/dist/src/extract/types/contract.js +1 -0
- package/dist/src/extract/types/display.d.ts +3 -0
- package/dist/src/{types.js → extract/types/display.js} +1 -1
- package/dist/src/extract/types/options.d.ts +15 -0
- package/dist/src/extract/types/options.js +1 -0
- package/dist/src/extract/types/scoring.d.ts +9 -0
- package/dist/src/extract/types/scoring.js +1 -0
- package/dist/src/extract/types/source-inspection.d.ts +5 -0
- package/dist/src/extract/types/source-inspection.js +1 -0
- package/dist/src/index.d.ts +27 -21
- package/dist/src/index.js +21 -17
- package/package.json +1 -1
- package/dist/src/extract/astro.js +0 -226
- package/dist/src/extract/non-authorable-filter.d.ts +0 -17
- package/dist/src/extract/non-authorable-filter.js +0 -60
- package/dist/src/extract/pipeline.d.ts +0 -7
- package/dist/src/extract/pipeline.js +0 -343
- package/dist/src/extract/react.js +0 -2069
- package/dist/src/extract/scoring.d.ts +0 -12
- package/dist/src/extract/slot-detection.d.ts +0 -35
- package/dist/src/extract/slot-detection.js +0 -98
- package/dist/src/extract/stencil.js +0 -312
- package/dist/src/extract/structural-slot-evidence.d.ts +0 -63
- package/dist/src/extract/structural-slot-evidence.js +0 -278
- package/dist/src/extract/svelte.js +0 -1309
- package/dist/src/extract/tsx-shared.d.ts +0 -37
- package/dist/src/extract/tsx-shared.js +0 -368
- package/dist/src/extract/vue-tsx.js +0 -449
- package/dist/src/extract/vue.js +0 -605
- package/dist/src/extract/web-components.js +0 -863
- /package/dist/src/extract/{source-line-metadata.js → framework-adapters/shared/helpers/get-node-source-lines.js} +0 -0
- /package/dist/src/extract/{resolve-local-module.d.ts → framework-adapters/shared/helpers/resolve-import-file-path.d.ts} +0 -0
- /package/dist/src/extract/{resolve-local-module.js → framework-adapters/shared/helpers/resolve-import-file-path.js} +0 -0
- /package/dist/src/extract/{resolve-type-property.d.ts → framework-adapters/shared/helpers/resolve-type-symbol.d.ts} +0 -0
- /package/dist/src/extract/{resolve-type-property.js → framework-adapters/shared/helpers/resolve-type-symbol.js} +0 -0
- /package/dist/src/extract/{slot-allowed-components.d.ts → helpers/evidence/collect-allowed-component-names.d.ts} +0 -0
- /package/dist/src/extract/{slot-allowed-components.js → helpers/evidence/collect-allowed-component-names.js} +0 -0
- /package/dist/src/extract/{parse-imported-names.d.ts → helpers/evidence/parse-source-imports.d.ts} +0 -0
- /package/dist/src/extract/{parse-imported-names.js → helpers/evidence/parse-source-imports.js} +0 -0
- /package/dist/src/extract/{validate.js → services/quality/helpers/inspection/validate-extracted-components.js} +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { scoreComponentSourcePath, resolvePackageRootInfo, resolveComponentScopeInfo, resolveTopLevelFamilyName, } from './component-path-analysis.js';
|
|
2
|
+
export { scoreComponentSourcePath, resolvePackageRootInfo, resolveComponentScopeInfo, resolveTopLevelFamilyName };
|
|
3
|
+
export function isWithinComponentFamily(relativeSegments, componentName) {
|
|
4
|
+
const [first, second, third] = relativeSegments;
|
|
5
|
+
const componentFilenames = new Set([
|
|
6
|
+
`${componentName}.tsx`,
|
|
7
|
+
`${componentName}.ts`,
|
|
8
|
+
`${componentName}.vue`,
|
|
9
|
+
'index.tsx',
|
|
10
|
+
'index.ts',
|
|
11
|
+
'index.vue',
|
|
12
|
+
]);
|
|
13
|
+
if (relativeSegments.length === 1) {
|
|
14
|
+
return new Set([`${componentName}.tsx`, `${componentName}.ts`, `${componentName}.vue`]).has(first);
|
|
15
|
+
}
|
|
16
|
+
if (first === 'src' && second === 'components' && third === componentName)
|
|
17
|
+
return true;
|
|
18
|
+
if (first === 'components' && second === componentName)
|
|
19
|
+
return true;
|
|
20
|
+
if (first === 'src' && second === componentName)
|
|
21
|
+
return true;
|
|
22
|
+
if (first === componentName)
|
|
23
|
+
return componentFilenames.has(second) || relativeSegments.length > 2;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
export function resolveDeduplicationScopeKey(filePath, componentName, topLevelFamiliesByRoot) {
|
|
27
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
28
|
+
const scopeInfo = resolveComponentScopeInfo(filePath);
|
|
29
|
+
if (!scopeInfo)
|
|
30
|
+
return normalized;
|
|
31
|
+
const { rootKey, relativeSegments } = scopeInfo;
|
|
32
|
+
const topLevelFamilies = topLevelFamiliesByRoot.get(rootKey);
|
|
33
|
+
if (topLevelFamilies?.has(componentName) && isWithinComponentFamily(relativeSegments, componentName)) {
|
|
34
|
+
return `${rootKey}::${componentName}`;
|
|
35
|
+
}
|
|
36
|
+
const [first, second, third] = relativeSegments;
|
|
37
|
+
if (first === 'src' && second === 'components' && third)
|
|
38
|
+
return `${rootKey}/src/components/${third}`;
|
|
39
|
+
if (first === 'components' && second)
|
|
40
|
+
return `${rootKey}/components/${second}`;
|
|
41
|
+
if (first === 'src' && second && relativeSegments.length > 2)
|
|
42
|
+
return `${rootKey}/src/${second}`;
|
|
43
|
+
if (first && relativeSegments.length > 1)
|
|
44
|
+
return `${rootKey}/${first}`;
|
|
45
|
+
return rootKey;
|
|
46
|
+
}
|
|
47
|
+
export function selectPreferredComponentSource(existing, candidate) {
|
|
48
|
+
const existingScore = scoreComponentSourcePath(existing.source);
|
|
49
|
+
const candidateScore = scoreComponentSourcePath(candidate.source);
|
|
50
|
+
if (candidateScore > existingScore)
|
|
51
|
+
return {
|
|
52
|
+
winner: candidate,
|
|
53
|
+
loser: existing,
|
|
54
|
+
reason: `preferred ${candidate.source} over ${existing.source} based on path heuristics`,
|
|
55
|
+
};
|
|
56
|
+
if (candidateScore < existingScore)
|
|
57
|
+
return {
|
|
58
|
+
winner: existing,
|
|
59
|
+
loser: candidate,
|
|
60
|
+
reason: `kept ${existing.source} over ${candidate.source} based on path heuristics`,
|
|
61
|
+
};
|
|
62
|
+
if (candidate.source.length < existing.source.length)
|
|
63
|
+
return {
|
|
64
|
+
winner: candidate,
|
|
65
|
+
loser: existing,
|
|
66
|
+
reason: `preferred shorter path ${candidate.source} over ${existing.source}`,
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
winner: existing,
|
|
70
|
+
loser: candidate,
|
|
71
|
+
reason: `kept ${existing.source} over ${candidate.source} by stable first-seen order`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ComponentExtractionResult, ExtractorProgress } from '../../types/component.js';
|
|
2
|
+
import type { ExtractorOptions } from '../../types/options.js';
|
|
3
|
+
export declare function extractComponents(filePaths: string[], onProgress?: (progress: ExtractorProgress) => void, opts?: ExtractorOptions): Promise<ComponentExtractionResult>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { deduplicateComponents } from '../deduplication/deduplicate-components.js';
|
|
2
|
+
import { extractorRegistry, routeFilesToExtractors } from './helpers/register-extractors.js';
|
|
3
|
+
import { runExtractorBatches } from './helpers/run-extractor-batches.js';
|
|
4
|
+
import { collectSvelteKitRouteExclusions } from './helpers/collect-sveltekit-route-exclusions.js';
|
|
5
|
+
import { filterHookComponents } from './helpers/filter-hook-components.js';
|
|
6
|
+
export async function extractComponents(filePaths, onProgress, opts) {
|
|
7
|
+
const routeExclusions = collectSvelteKitRouteExclusions(filePaths);
|
|
8
|
+
const routedFiles = routeFilesToExtractors(filePaths, extractorRegistry);
|
|
9
|
+
const results = await runExtractorBatches(routedFiles, onProgress, opts);
|
|
10
|
+
const deduplicated = deduplicateComponents(results);
|
|
11
|
+
const { components, exclusions: hookExclusions, warnings: hookWarnings, } = filterHookComponents(deduplicated.components);
|
|
12
|
+
deduplicated.warnings.push(...hookWarnings);
|
|
13
|
+
const allExclusions = [...routeExclusions, ...hookExclusions, ...(deduplicated.exclusions ?? [])];
|
|
14
|
+
return {
|
|
15
|
+
components,
|
|
16
|
+
warnings: deduplicated.warnings,
|
|
17
|
+
...(allExclusions.length > 0 ? { exclusions: allExclusions } : {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function collectSvelteKitRouteExclusions(filePaths) {
|
|
2
|
+
return filePaths.flatMap((filePath) => {
|
|
3
|
+
if (!filePath.endsWith('.svelte'))
|
|
4
|
+
return [];
|
|
5
|
+
const name = filePath.replace(/\\/g, '/').split('/').pop() ?? '';
|
|
6
|
+
if (!/^\+(page|layout|error)\.svelte$/.test(name))
|
|
7
|
+
return [];
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
itemType: 'file',
|
|
11
|
+
name,
|
|
12
|
+
source: filePath,
|
|
13
|
+
reason: 'SvelteKit route entrypoints are framework-managed, not authorable components',
|
|
14
|
+
stage: 'file-filter',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExtractionExclusion, RawComponentDefinition } from '../../../types/component.js';
|
|
2
|
+
export declare function filterHookComponents(components: RawComponentDefinition[]): {
|
|
3
|
+
components: RawComponentDefinition[];
|
|
4
|
+
exclusions: ExtractionExclusion[];
|
|
5
|
+
warnings: string[];
|
|
6
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function filterHookComponents(components) {
|
|
2
|
+
const exclusions = [];
|
|
3
|
+
const warnings = [];
|
|
4
|
+
const kept = components.filter((component) => {
|
|
5
|
+
if (!/^use[A-Z]/.test(component.name))
|
|
6
|
+
return true;
|
|
7
|
+
warnings.push(`Skipped hook: ${component.name} (hooks are not renderable components)`);
|
|
8
|
+
exclusions.push({
|
|
9
|
+
itemType: 'component',
|
|
10
|
+
name: component.name,
|
|
11
|
+
source: component.source,
|
|
12
|
+
reason: 'Hook names are not renderable components',
|
|
13
|
+
stage: 'component-filter',
|
|
14
|
+
});
|
|
15
|
+
return false;
|
|
16
|
+
});
|
|
17
|
+
return { components: kept, exclusions, warnings };
|
|
18
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ComponentExtractor } from '../../../types/component-extractor.js';
|
|
2
|
+
export interface ExtractorFileGroup {
|
|
3
|
+
extractor: ComponentExtractor;
|
|
4
|
+
filePaths: string[];
|
|
5
|
+
}
|
|
6
|
+
/** Ordered adapter registration; overlapping filters intentionally allow a file to be inspected by multiple adapters. */
|
|
7
|
+
export declare const extractorRegistry: readonly ComponentExtractor[];
|
|
8
|
+
export declare function routeFilesToExtractors(filePaths: readonly string[], extractors?: readonly ComponentExtractor[]): ExtractorFileGroup[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { extractAstroComponents } from '../../../framework-adapters/astro/extractor.js';
|
|
2
|
+
import { extractReactComponents } from '../../../framework-adapters/react/extractor.js';
|
|
3
|
+
import { extractStencilComponents } from '../../../framework-adapters/stencil/extractor.js';
|
|
4
|
+
import { extractSvelteComponents } from '../../../framework-adapters/svelte/extractor.js';
|
|
5
|
+
import { extractVueTsxComponents } from '../../../framework-adapters/vue-tsx/extractor.js';
|
|
6
|
+
import { extractVueComponents } from '../../../framework-adapters/vue/extractor.js';
|
|
7
|
+
import { extractWebComponentDefinitions } from '../../../framework-adapters/web-components/extractor.js';
|
|
8
|
+
/** Ordered adapter registration; overlapping filters intentionally allow a file to be inspected by multiple adapters. */
|
|
9
|
+
export const extractorRegistry = [
|
|
10
|
+
{
|
|
11
|
+
name: 'stencil',
|
|
12
|
+
fileFilter: (filePath) => /\.[jt]sx$/.test(filePath),
|
|
13
|
+
extract: extractStencilComponents,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'react',
|
|
17
|
+
fileFilter: (filePath) => /\.[jt]sx?$/.test(filePath) && !filePath.endsWith('.d.ts'),
|
|
18
|
+
extract: extractReactComponents,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'vue-tsx',
|
|
22
|
+
fileFilter: (filePath) => /\.[jt]sx?$/.test(filePath) && !filePath.endsWith('.d.ts'),
|
|
23
|
+
extract: extractVueTsxComponents,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'vue',
|
|
27
|
+
fileFilter: (filePath) => filePath.endsWith('.vue'),
|
|
28
|
+
extract: extractVueComponents,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'astro',
|
|
32
|
+
fileFilter: (filePath) => filePath.endsWith('.astro'),
|
|
33
|
+
extract: extractAstroComponents,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'web-components',
|
|
37
|
+
fileFilter: (filePath) => /\.[jt]s$/.test(filePath) && !/\.[jt]sx$/.test(filePath) && !filePath.endsWith('.d.ts'),
|
|
38
|
+
extract: extractWebComponentDefinitions,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'svelte',
|
|
42
|
+
fileFilter: (filePath) => {
|
|
43
|
+
if (!filePath.endsWith('.svelte'))
|
|
44
|
+
return false;
|
|
45
|
+
const filename = filePath.replace(/\\/g, '/').split('/').pop() ?? '';
|
|
46
|
+
if (/^\+(page|layout|error)\.svelte$/.test(filename))
|
|
47
|
+
return false;
|
|
48
|
+
return true;
|
|
49
|
+
},
|
|
50
|
+
extract: extractSvelteComponents,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
export function routeFilesToExtractors(filePaths, extractors = extractorRegistry) {
|
|
54
|
+
const filesByExtractor = new Map();
|
|
55
|
+
for (const extractor of extractors) {
|
|
56
|
+
filesByExtractor.set(extractor, []);
|
|
57
|
+
}
|
|
58
|
+
for (const filePath of filePaths) {
|
|
59
|
+
for (const extractor of extractors) {
|
|
60
|
+
if (extractor.fileFilter(filePath)) {
|
|
61
|
+
filesByExtractor.get(extractor)?.push(filePath);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return extractors
|
|
66
|
+
.map((extractor) => ({
|
|
67
|
+
extractor,
|
|
68
|
+
filePaths: filesByExtractor.get(extractor) ?? [],
|
|
69
|
+
}))
|
|
70
|
+
.filter(({ filePaths: groupedFilePaths }) => groupedFilePaths.length > 0);
|
|
71
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ComponentExtractionResult, ExtractorProgress } from '../../../types/component.js';
|
|
2
|
+
import type { ExtractorOptions } from '../../../types/options.js';
|
|
3
|
+
import type { ExtractorFileGroup } from './register-extractors.js';
|
|
4
|
+
export declare function runExtractorBatches(batches: readonly ExtractorFileGroup[], onProgress?: (progress: ExtractorProgress) => void, options?: ExtractorOptions): Promise<ComponentExtractionResult[]>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function runExtractorBatches(batches, onProgress, options) {
|
|
2
|
+
const perExtractorFiles = new Map();
|
|
3
|
+
const perExtractorComponents = new Map();
|
|
4
|
+
let totalFilesProcessed = 0;
|
|
5
|
+
let totalComponentsFound = 0;
|
|
6
|
+
return Promise.all(batches.map(async ({ extractor, filePaths }) => {
|
|
7
|
+
if (filePaths.length === 0)
|
|
8
|
+
return { components: [], warnings: [] };
|
|
9
|
+
perExtractorFiles.set(extractor, 0);
|
|
10
|
+
perExtractorComponents.set(extractor, 0);
|
|
11
|
+
return extractor.extract(filePaths, (progress) => {
|
|
12
|
+
const previousFiles = perExtractorFiles.get(extractor) ?? 0;
|
|
13
|
+
const previousComponents = perExtractorComponents.get(extractor) ?? 0;
|
|
14
|
+
totalFilesProcessed += progress.filesProcessed - previousFiles;
|
|
15
|
+
totalComponentsFound += progress.componentsFound - previousComponents;
|
|
16
|
+
perExtractorFiles.set(extractor, progress.filesProcessed);
|
|
17
|
+
perExtractorComponents.set(extractor, progress.componentsFound);
|
|
18
|
+
onProgress?.({
|
|
19
|
+
filesProcessed: totalFilesProcessed,
|
|
20
|
+
componentsFound: totalComponentsFound,
|
|
21
|
+
});
|
|
22
|
+
}, options);
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RawComponentDefinition } from '../../types/component.js';
|
|
2
|
+
import type { ExtractionEndpointResponse } from '../../types/contract.js';
|
|
3
|
+
/** Applies inspection, authorability, scoring, review, and validation policies to extracted models. */
|
|
4
|
+
export declare function evaluateExtractionQuality(components: readonly RawComponentDefinition[], initialWarnings?: readonly string[]): Promise<ExtractionEndpointResponse>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { hasNoAuthoringSurface } from './helpers/authorability/evaluate-authorability.js';
|
|
2
|
+
import { computeExtractionScore, deriveNeedsReview } from './helpers/scoring/compute-extraction-score.js';
|
|
3
|
+
import { inspectComponentSource, describeReviewReasons } from './helpers/inspection/inspect-component-source.js';
|
|
4
|
+
import { validateExtractedComponents } from './helpers/inspection/validate-extracted-components.js';
|
|
5
|
+
function wrapperConfidenceToIssueCount(confidence) {
|
|
6
|
+
if (confidence >= 4)
|
|
7
|
+
return 2;
|
|
8
|
+
if (confidence === 3)
|
|
9
|
+
return 1;
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
/** Applies inspection, authorability, scoring, review, and validation policies to extracted models. */
|
|
13
|
+
export async function evaluateExtractionQuality(components, initialWarnings = []) {
|
|
14
|
+
const inspectedComponents = await Promise.all(components.map(async (component) => ({
|
|
15
|
+
component,
|
|
16
|
+
inspection: await inspectComponentSource(component),
|
|
17
|
+
})));
|
|
18
|
+
const scoredComponents = [];
|
|
19
|
+
const warnings = [...initialWarnings];
|
|
20
|
+
for (const { component, inspection } of inspectedComponents) {
|
|
21
|
+
const verdict = hasNoAuthoringSurface(component);
|
|
22
|
+
const keepDespiteZeroSurface = verdict.skip && verdict.reason === 'component has no props and no slots' && inspection.keepDespiteZeroSurface;
|
|
23
|
+
const retainedForReview = verdict.skip && !keepDespiteZeroSurface;
|
|
24
|
+
if (retainedForReview) {
|
|
25
|
+
warnings.push(`${component.name}: requires operator review (${verdict.reason})`);
|
|
26
|
+
}
|
|
27
|
+
if (keepDespiteZeroSurface) {
|
|
28
|
+
warnings.push(`${component.name}: retained despite 0 props/slots because the source renders visible or compositional UI`);
|
|
29
|
+
}
|
|
30
|
+
if (inspection.reviewReasons.length > 0) {
|
|
31
|
+
const reviewNotes = describeReviewReasons(inspection.reviewReasons)
|
|
32
|
+
.filter((note) => note !== 'high-confidence data-fetch wrapper')
|
|
33
|
+
.join('; ');
|
|
34
|
+
if (reviewNotes)
|
|
35
|
+
warnings.push(`${component.name}: ${reviewNotes}`);
|
|
36
|
+
}
|
|
37
|
+
const extractorReasons = component.reviewReasons ?? [];
|
|
38
|
+
const nonAuthorableReason = retainedForReview ? [`non-authorable:${verdict.reason}`] : [];
|
|
39
|
+
const { confidence, reasons } = computeExtractionScore(component, {
|
|
40
|
+
additionalIssueCount: wrapperConfidenceToIssueCount(inspection.wrapperConfidence) +
|
|
41
|
+
extractorReasons.length +
|
|
42
|
+
nonAuthorableReason.length,
|
|
43
|
+
additionalReasons: [...extractorReasons, ...inspection.reviewReasons, ...nonAuthorableReason],
|
|
44
|
+
});
|
|
45
|
+
scoredComponents.push({
|
|
46
|
+
...component,
|
|
47
|
+
extractionConfidence: confidence,
|
|
48
|
+
reviewReasons: reasons,
|
|
49
|
+
needsReview: deriveNeedsReview(confidence) ||
|
|
50
|
+
inspection.wrapperConfidence >= 4 ||
|
|
51
|
+
inspection.keepDespiteZeroSurface ||
|
|
52
|
+
retainedForReview ||
|
|
53
|
+
extractorReasons.includes('props-type-unresolved') ||
|
|
54
|
+
(component.needsReview ?? false),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
components: validateExtractedComponents(scoredComponents),
|
|
59
|
+
warnings,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RawComponentDefinition, RawPropDefinition, RawSlotDefinition } from '../../../../types/component.js';
|
|
2
|
+
export interface AuthoringSurfaceCheck {
|
|
3
|
+
skip: boolean;
|
|
4
|
+
reason?: string;
|
|
5
|
+
}
|
|
6
|
+
/** Returns true when the prop is an event-handler function or a React ref — not something a content editor configures. */
|
|
7
|
+
export declare function isHandlerOrRefProp(prop: RawPropDefinition): boolean;
|
|
8
|
+
/** Rule 1: no props AND no slots — analytics scripts, GTM tags, layout fixers, security tokens, etc. */
|
|
9
|
+
export declare function hasNoPropsAndNoSlots(props: RawPropDefinition[], slots: RawSlotDefinition[]): boolean;
|
|
10
|
+
/** Rule 2: createContext source with a prop literally named `value` — the canonical `<Context.Provider value={...}>` call site. */
|
|
11
|
+
export declare function isContextProviderWithValueProp(props: RawPropDefinition[], usesCreateContext: boolean | undefined): boolean;
|
|
12
|
+
/** Rule 3: createContext source with zero props — a Provider that hard-codes its context value internally (e.g. FontProvider). */
|
|
13
|
+
export declare function isHardwiredContextProvider(props: RawPropDefinition[], usesCreateContext: boolean | undefined): boolean;
|
|
14
|
+
/** Rule 4: createContext source with exactly one non-handler prop — a Provider that takes its context value as a single data prop (e.g. LocaleProvider, NavigationProvider). */
|
|
15
|
+
export declare function isSingleDataPropContextWrapper(props: RawPropDefinition[], usesCreateContext: boolean | undefined): boolean;
|
|
16
|
+
/** Rule 5: every prop is an event handler or ref — pure plumbing with no authoring surface (e.g. OsanoCookiePlaceholder({ onBannerLoaded })). */
|
|
17
|
+
export declare function hasOnlyEventHandlers(props: RawPropDefinition[]): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Checks whether a component has no surface for a content editor to configure.
|
|
20
|
+
* Returns { skip: true, reason } for infrastructure components that should be
|
|
21
|
+
* flagged for operator review before authoring-token generation.
|
|
22
|
+
*
|
|
23
|
+
* Uses prop-shape signals only — no component-name or source-path patterns.
|
|
24
|
+
* A design system can live anywhere under any naming convention; relying on
|
|
25
|
+
* suffixes like `*Provider` or paths like `src/lib/` would silently fail in
|
|
26
|
+
* other repos.
|
|
27
|
+
*/
|
|
28
|
+
export declare function hasNoAuthoringSurface(component: RawComponentDefinition): AuthoringSurfaceCheck;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const HANDLER_TYPE_PATTERN = /=>|EventHandler|Dispatch<|SetStateAction/;
|
|
2
|
+
const REF_TYPE_PATTERN = /Ref<|RefObject<|MutableRefObject/;
|
|
3
|
+
/** Returns true when the prop is an event-handler function or a React ref — not something a content editor configures. */
|
|
4
|
+
export function isHandlerOrRefProp(prop) {
|
|
5
|
+
if (HANDLER_TYPE_PATTERN.test(prop.type))
|
|
6
|
+
return true;
|
|
7
|
+
if (REF_TYPE_PATTERN.test(prop.type))
|
|
8
|
+
return true;
|
|
9
|
+
if (/^on[A-Z]/.test(prop.name) || /^set[A-Z]/.test(prop.name))
|
|
10
|
+
return true;
|
|
11
|
+
if (prop.name === 'ref' || prop.name === 'innerRef')
|
|
12
|
+
return true;
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
/** Rule 1: no props AND no slots — analytics scripts, GTM tags, layout fixers, security tokens, etc. */
|
|
16
|
+
export function hasNoPropsAndNoSlots(props, slots) {
|
|
17
|
+
return props.length === 0 && slots.length === 0;
|
|
18
|
+
}
|
|
19
|
+
/** Rule 2: createContext source with a prop literally named `value` — the canonical `<Context.Provider value={...}>` call site. */
|
|
20
|
+
export function isContextProviderWithValueProp(props, usesCreateContext) {
|
|
21
|
+
return !!usesCreateContext && props.some((p) => p.name === 'value');
|
|
22
|
+
}
|
|
23
|
+
/** Rule 3: createContext source with zero props — a Provider that hard-codes its context value internally (e.g. FontProvider). */
|
|
24
|
+
export function isHardwiredContextProvider(props, usesCreateContext) {
|
|
25
|
+
return !!usesCreateContext && props.length === 0;
|
|
26
|
+
}
|
|
27
|
+
/** Rule 4: createContext source with exactly one non-handler prop — a Provider that takes its context value as a single data prop (e.g. LocaleProvider, NavigationProvider). */
|
|
28
|
+
export function isSingleDataPropContextWrapper(props, usesCreateContext) {
|
|
29
|
+
return !!usesCreateContext && props.length === 1 && !isHandlerOrRefProp(props[0]);
|
|
30
|
+
}
|
|
31
|
+
/** Rule 5: every prop is an event handler or ref — pure plumbing with no authoring surface (e.g. OsanoCookiePlaceholder({ onBannerLoaded })). */
|
|
32
|
+
export function hasOnlyEventHandlers(props) {
|
|
33
|
+
return props.length > 0 && props.every(isHandlerOrRefProp);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Checks whether a component has no surface for a content editor to configure.
|
|
37
|
+
* Returns { skip: true, reason } for infrastructure components that should be
|
|
38
|
+
* flagged for operator review before authoring-token generation.
|
|
39
|
+
*
|
|
40
|
+
* Uses prop-shape signals only — no component-name or source-path patterns.
|
|
41
|
+
* A design system can live anywhere under any naming convention; relying on
|
|
42
|
+
* suffixes like `*Provider` or paths like `src/lib/` would silently fail in
|
|
43
|
+
* other repos.
|
|
44
|
+
*/
|
|
45
|
+
export function hasNoAuthoringSurface(component) {
|
|
46
|
+
const { props, slots, usesCreateContext } = component;
|
|
47
|
+
if (hasNoPropsAndNoSlots(props, slots))
|
|
48
|
+
return { skip: true, reason: 'component has no props and no slots' };
|
|
49
|
+
if (isContextProviderWithValueProp(props, usesCreateContext))
|
|
50
|
+
return {
|
|
51
|
+
skip: true,
|
|
52
|
+
reason: 'source uses createContext and component exposes a Context.Provider value prop',
|
|
53
|
+
};
|
|
54
|
+
if (isHardwiredContextProvider(props, usesCreateContext))
|
|
55
|
+
return {
|
|
56
|
+
skip: true,
|
|
57
|
+
reason: 'source uses createContext and component has no props',
|
|
58
|
+
};
|
|
59
|
+
if (isSingleDataPropContextWrapper(props, usesCreateContext))
|
|
60
|
+
return {
|
|
61
|
+
skip: true,
|
|
62
|
+
reason: 'source uses createContext and component has a single non-handler prop',
|
|
63
|
+
};
|
|
64
|
+
if (hasOnlyEventHandlers(props))
|
|
65
|
+
return { skip: true, reason: 'every prop is a handler or ref' };
|
|
66
|
+
return { skip: false };
|
|
67
|
+
}
|
package/dist/src/extract/services/quality/helpers/inspection/detect-data-wrapper-patterns.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RawComponentDefinition } from '../../../../types/component.js';
|
|
2
|
+
export declare const DATA_WRAPPER_REASON_PREFIX = "data-wrapper:";
|
|
3
|
+
export declare const VISIBLE_UI_TAG_PATTERN: RegExp;
|
|
4
|
+
export declare const GENERATED_IMPORT_PATTERN: RegExp;
|
|
5
|
+
export declare const GENERATED_QUERY_HOOK_PATTERN: RegExp;
|
|
6
|
+
export declare const GQL_FILENAME_PATTERN: RegExp;
|
|
7
|
+
export declare const LOADING_NULL_GUARD_PATTERN: RegExp;
|
|
8
|
+
export declare function escapeRegExp(value: string): string;
|
|
9
|
+
export declare function collectSiblingRendererImports(sourceText: string): string[];
|
|
10
|
+
export declare function hasSiblingForwardRender(sourceText: string, siblingImports: string[]): boolean;
|
|
11
|
+
export declare function hasVisibleUiRender(sourceText: string): boolean;
|
|
12
|
+
/** Returns the prop names when all props are infra-only fetch props; returns empty array otherwise. */
|
|
13
|
+
export declare function collectInfraPropNames(component: RawComponentDefinition): string[];
|
|
14
|
+
/** Maps a raw wrapper evidence score (0–∞) to a 0–5 confidence value. */
|
|
15
|
+
export declare function mapScoreToWrapperConfidence(score: number): 0 | 1 | 2 | 3 | 4 | 5;
|
|
16
|
+
export declare function dedupeStrings(values: string[]): string[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { parseImportedNames } from '../../../../helpers/evidence/parse-source-imports.js';
|
|
2
|
+
export const DATA_WRAPPER_REASON_PREFIX = 'data-wrapper:';
|
|
3
|
+
const INFRA_PROP_NAMES = new Set(['id', 'locale', 'preview', 'slug', 'topic', 'previousComponent', '__typename']);
|
|
4
|
+
export const VISIBLE_UI_TAG_PATTERN = /<(?:[A-Z][A-Za-z0-9_.]*|div|span|section|main|article|header|footer|nav|aside|img|video|p|h[1-6]|ul|ol|li|button|input|textarea|select|form|label|table|tbody|thead|tr|td|th)\b/;
|
|
5
|
+
export const GENERATED_IMPORT_PATTERN = /from\s+['"][^'"]*__generated[^'"]*['"]/;
|
|
6
|
+
export const GENERATED_QUERY_HOOK_PATTERN = /\buse[A-Z][A-Za-z0-9]*(?:Lazy|Suspense)?Query\s*\(/;
|
|
7
|
+
export const GQL_FILENAME_PATTERN = /(?:-gql|-ggl)\.[cm]?[jt]sx?$/i;
|
|
8
|
+
export const LOADING_NULL_GUARD_PATTERN = /if\s*\([^)]*(?:isLoading|loading|!data|!\w+Collection|!\w+Item|!\w+)\s*[^)]*\)\s*return\s+null\b/;
|
|
9
|
+
const IMPORT_PATTERN = /import\s+(?:type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
10
|
+
export function escapeRegExp(value) {
|
|
11
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
12
|
+
}
|
|
13
|
+
export function collectSiblingRendererImports(sourceText) {
|
|
14
|
+
const names = new Set();
|
|
15
|
+
for (const match of sourceText.matchAll(IMPORT_PATTERN)) {
|
|
16
|
+
const importClause = match[1]?.trim() ?? '';
|
|
17
|
+
const importPath = match[2]?.trim() ?? '';
|
|
18
|
+
if (!importPath.startsWith('./'))
|
|
19
|
+
continue;
|
|
20
|
+
if (importPath.includes('__generated'))
|
|
21
|
+
continue;
|
|
22
|
+
if (/-g(?:ql|gl)(?:$|\.)/i.test(importPath))
|
|
23
|
+
continue;
|
|
24
|
+
for (const name of parseImportedNames(importClause)) {
|
|
25
|
+
if (name)
|
|
26
|
+
names.add(name);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return [...names];
|
|
30
|
+
}
|
|
31
|
+
export function hasSiblingForwardRender(sourceText, siblingImports) {
|
|
32
|
+
return siblingImports.some((name) => {
|
|
33
|
+
const renderPattern = new RegExp(`<${escapeRegExp(name)}\\b[\\s\\S]*?(?:/>|</${escapeRegExp(name)}>)`);
|
|
34
|
+
if (!renderPattern.test(sourceText))
|
|
35
|
+
return false;
|
|
36
|
+
const siblingSpreadPattern = new RegExp(`<${escapeRegExp(name)}\\b[^>]*\\{\\.\\.\\.(?!props\\b)[^}]+\\}`);
|
|
37
|
+
const propsPlusSiblingSpreadPattern = new RegExp(`<${escapeRegExp(name)}\\b[^>]*\\{\\.\\.\\.props\\}[^>]*\\{\\.\\.\\.(?!props\\b)[^}]+\\}`);
|
|
38
|
+
return siblingSpreadPattern.test(sourceText) || propsPlusSiblingSpreadPattern.test(sourceText);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function hasVisibleUiRender(sourceText) {
|
|
42
|
+
return /return\s*(?:\(|<)/.test(sourceText) && VISIBLE_UI_TAG_PATTERN.test(sourceText);
|
|
43
|
+
}
|
|
44
|
+
/** Returns the prop names when all props are infra-only fetch props; returns empty array otherwise. */
|
|
45
|
+
export function collectInfraPropNames(component) {
|
|
46
|
+
const props = component.props.map((prop) => prop.name);
|
|
47
|
+
return props.length > 0 && props.every((prop) => INFRA_PROP_NAMES.has(prop)) ? props : [];
|
|
48
|
+
}
|
|
49
|
+
/** Maps a raw wrapper evidence score (0–∞) to a 0–5 confidence value. */
|
|
50
|
+
export function mapScoreToWrapperConfidence(score) {
|
|
51
|
+
if (score <= 0)
|
|
52
|
+
return 0;
|
|
53
|
+
if (score <= 2)
|
|
54
|
+
return 2;
|
|
55
|
+
if (score <= 4)
|
|
56
|
+
return 3;
|
|
57
|
+
if (score <= 6)
|
|
58
|
+
return 4;
|
|
59
|
+
return 5;
|
|
60
|
+
}
|
|
61
|
+
export function dedupeStrings(values) {
|
|
62
|
+
return [...new Set(values)];
|
|
63
|
+
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type { RawComponentDefinition } from '
|
|
1
|
+
import type { RawComponentDefinition } from '../../../../types/component.js';
|
|
2
|
+
import type { ComponentSourceInspection } from '../../../../types/source-inspection.js';
|
|
3
|
+
export type { ComponentSourceInspection } from '../../../../types/source-inspection.js';
|
|
2
4
|
export declare const HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON = "data-fetch-wrapper";
|
|
3
5
|
export declare const POSSIBLE_DATA_FETCH_WRAPPER_REASON = "possible-data-fetch-wrapper";
|
|
4
6
|
export declare const ZERO_SURFACE_RENDERED_UI_REASON = "zero-surface:rendered-ui";
|
|
5
|
-
export interface ComponentSourceInspection {
|
|
6
|
-
wrapperConfidence: 0 | 1 | 2 | 3 | 4 | 5;
|
|
7
|
-
reviewReasons: string[];
|
|
8
|
-
keepDespiteZeroSurface: boolean;
|
|
9
|
-
}
|
|
10
7
|
export declare function inspectComponentSource(component: RawComponentDefinition): Promise<ComponentSourceInspection>;
|
|
11
8
|
export declare function isDataWrapperReviewReason(reason: string): boolean;
|
|
12
9
|
export declare function describeReviewReason(reason: string): string;
|
|
@@ -1,68 +1,8 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import {
|
|
2
|
+
import { DATA_WRAPPER_REASON_PREFIX, GENERATED_IMPORT_PATTERN, GENERATED_QUERY_HOOK_PATTERN, GQL_FILENAME_PATTERN, LOADING_NULL_GUARD_PATTERN, collectSiblingRendererImports, hasSiblingForwardRender, hasVisibleUiRender, collectInfraPropNames, mapScoreToWrapperConfidence, dedupeStrings, } from './detect-data-wrapper-patterns.js';
|
|
3
3
|
export const HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON = 'data-fetch-wrapper';
|
|
4
4
|
export const POSSIBLE_DATA_FETCH_WRAPPER_REASON = 'possible-data-fetch-wrapper';
|
|
5
5
|
export const ZERO_SURFACE_RENDERED_UI_REASON = 'zero-surface:rendered-ui';
|
|
6
|
-
const DATA_WRAPPER_REASON_PREFIX = 'data-wrapper:';
|
|
7
|
-
const INFRA_PROP_NAMES = new Set(['id', 'locale', 'preview', 'slug', 'topic', 'previousComponent', '__typename']);
|
|
8
|
-
const VISIBLE_UI_TAG_PATTERN = /<(?:[A-Z][A-Za-z0-9_.]*|div|span|section|main|article|header|footer|nav|aside|img|video|p|h[1-6]|ul|ol|li|button|input|textarea|select|form|label|table|tbody|thead|tr|td|th)\b/;
|
|
9
|
-
const GENERATED_IMPORT_PATTERN = /from\s+['"][^'"]*__generated[^'"]*['"]/;
|
|
10
|
-
const GENERATED_QUERY_HOOK_PATTERN = /\buse[A-Z][A-Za-z0-9]*(?:Lazy|Suspense)?Query\s*\(/;
|
|
11
|
-
const GQL_FILENAME_PATTERN = /(?:-gql|-ggl)\.[cm]?[jt]sx?$/i;
|
|
12
|
-
const LOADING_NULL_GUARD_PATTERN = /if\s*\([^)]*(?:isLoading|loading|!data|!\w+Collection|!\w+Item|!\w+)\s*[^)]*\)\s*return\s+null\b/;
|
|
13
|
-
const IMPORT_PATTERN = /import\s+(?:type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
14
|
-
function escapeRegExp(value) {
|
|
15
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
16
|
-
}
|
|
17
|
-
function collectSiblingRendererImports(sourceText) {
|
|
18
|
-
const names = new Set();
|
|
19
|
-
for (const match of sourceText.matchAll(IMPORT_PATTERN)) {
|
|
20
|
-
const importClause = match[1]?.trim() ?? '';
|
|
21
|
-
const importPath = match[2]?.trim() ?? '';
|
|
22
|
-
if (!importPath.startsWith('./'))
|
|
23
|
-
continue;
|
|
24
|
-
if (importPath.includes('__generated'))
|
|
25
|
-
continue;
|
|
26
|
-
if (/-g(?:ql|gl)(?:$|\.)/i.test(importPath))
|
|
27
|
-
continue;
|
|
28
|
-
for (const name of parseImportedNames(importClause)) {
|
|
29
|
-
if (name)
|
|
30
|
-
names.add(name);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return [...names];
|
|
34
|
-
}
|
|
35
|
-
function hasSiblingForwardRender(sourceText, siblingImports) {
|
|
36
|
-
return siblingImports.some((name) => {
|
|
37
|
-
const renderPattern = new RegExp(`<${escapeRegExp(name)}\\b[\\s\\S]*?(?:/>|</${escapeRegExp(name)}>)`);
|
|
38
|
-
if (!renderPattern.test(sourceText))
|
|
39
|
-
return false;
|
|
40
|
-
const siblingSpreadPattern = new RegExp(`<${escapeRegExp(name)}\\b[^>]*\\{\\.\\.\\.(?!props\\b)[^}]+\\}`);
|
|
41
|
-
const propsPlusSiblingSpreadPattern = new RegExp(`<${escapeRegExp(name)}\\b[^>]*\\{\\.\\.\\.props\\}[^>]*\\{\\.\\.\\.(?!props\\b)[^}]+\\}`);
|
|
42
|
-
return siblingSpreadPattern.test(sourceText) || propsPlusSiblingSpreadPattern.test(sourceText);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function hasVisibleUiRender(sourceText) {
|
|
46
|
-
return /return\s*(?:\(|<)/.test(sourceText) && VISIBLE_UI_TAG_PATTERN.test(sourceText);
|
|
47
|
-
}
|
|
48
|
-
function infraPropNames(component) {
|
|
49
|
-
const props = component.props.map((prop) => prop.name);
|
|
50
|
-
return props.length > 0 && props.every((prop) => INFRA_PROP_NAMES.has(prop)) ? props : [];
|
|
51
|
-
}
|
|
52
|
-
function scoreToConfidence(score) {
|
|
53
|
-
if (score <= 0)
|
|
54
|
-
return 0;
|
|
55
|
-
if (score <= 2)
|
|
56
|
-
return 2;
|
|
57
|
-
if (score <= 4)
|
|
58
|
-
return 3;
|
|
59
|
-
if (score <= 6)
|
|
60
|
-
return 4;
|
|
61
|
-
return 5;
|
|
62
|
-
}
|
|
63
|
-
function dedupeReasons(reasons) {
|
|
64
|
-
return [...new Set(reasons)];
|
|
65
|
-
}
|
|
66
6
|
export async function inspectComponentSource(component) {
|
|
67
7
|
let sourceText = '';
|
|
68
8
|
try {
|
|
@@ -78,7 +18,7 @@ export async function inspectComponentSource(component) {
|
|
|
78
18
|
const reviewReasons = [];
|
|
79
19
|
let wrapperScore = 0;
|
|
80
20
|
const hasGeneratedQueryHook = GENERATED_IMPORT_PATTERN.test(sourceText) && GENERATED_QUERY_HOOK_PATTERN.test(sourceText);
|
|
81
|
-
const infraProps =
|
|
21
|
+
const infraProps = collectInfraPropNames(component);
|
|
82
22
|
const siblingImports = collectSiblingRendererImports(sourceText);
|
|
83
23
|
if (GQL_FILENAME_PATTERN.test(component.source)) {
|
|
84
24
|
reviewReasons.push('data-wrapper:gql-filename');
|
|
@@ -110,7 +50,7 @@ export async function inspectComponentSource(component) {
|
|
|
110
50
|
reviewReasons.push('data-wrapper:loading-null-guard');
|
|
111
51
|
wrapperScore += 1;
|
|
112
52
|
}
|
|
113
|
-
const wrapperConfidence =
|
|
53
|
+
const wrapperConfidence = mapScoreToWrapperConfidence(wrapperScore);
|
|
114
54
|
if (wrapperConfidence >= 4) {
|
|
115
55
|
reviewReasons.unshift(HIGH_CONFIDENCE_DATA_FETCH_WRAPPER_REASON);
|
|
116
56
|
}
|
|
@@ -123,7 +63,7 @@ export async function inspectComponentSource(component) {
|
|
|
123
63
|
}
|
|
124
64
|
return {
|
|
125
65
|
wrapperConfidence,
|
|
126
|
-
reviewReasons:
|
|
66
|
+
reviewReasons: dedupeStrings(reviewReasons),
|
|
127
67
|
keepDespiteZeroSurface,
|
|
128
68
|
};
|
|
129
69
|
}
|
|
@@ -159,5 +99,5 @@ export function describeReviewReason(reason) {
|
|
|
159
99
|
}
|
|
160
100
|
}
|
|
161
101
|
export function describeReviewReasons(reasons) {
|
|
162
|
-
return
|
|
102
|
+
return dedupeStrings(reasons.map(describeReviewReason));
|
|
163
103
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RawComponentDefinition, ExtractionValidationIssue } from '
|
|
1
|
+
import type { RawComponentDefinition, ExtractionValidationIssue } from '../../../../types/component.js';
|
|
2
2
|
export declare function validateExtractedComponents(components: RawComponentDefinition[]): RawComponentDefinition[];
|
|
3
3
|
export declare function shouldExcludeDueToValidation(component: RawComponentDefinition): boolean;
|
|
4
4
|
/**
|