@astryxdesign/cli 0.1.7 → 0.1.8-canary.07362a9
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/CHANGELOG.md +40 -0
- package/README.md +115 -19
- package/{src/api → api/blog}/blog.mjs +42 -6
- package/{src/api → api/blog}/blog.test.mjs +2 -2
- package/api/build/build.mjs +92 -0
- package/api/build/build.test.mjs +92 -0
- package/{src/api → api/component}/component.mjs +49 -26
- package/{src/api → api/discover}/discover.mjs +55 -18
- package/{src/api → api/docs}/docs.mjs +47 -21
- package/{src/api → api/doctor}/doctor.mjs +13 -10
- package/{src/api → api}/error.mjs +2 -2
- package/{src/api → api/hook}/hook.mjs +11 -11
- package/{src/api → api}/index.mjs +16 -9
- package/{src/api → api/integration}/validate-integration.mjs +48 -15
- package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
- package/{src/api → api/layout}/layout.mjs +66 -17
- package/{src/api → api/layout}/layout.test.mjs +1 -1
- package/{src/api → api/search}/search.mjs +71 -12
- package/api/swizzle/swizzle.mjs +283 -0
- package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
- package/{src/api → api/template}/template-integration.test.mjs +2 -2
- package/{src/api → api/template}/template-suffix.test.mjs +3 -3
- package/{src/api → api/template}/template.mjs +96 -19
- package/{src/api → api/theme}/theme-add.mjs +35 -7
- package/{src → authoring}/codemod.mjs +6 -6
- package/{src → authoring}/config.test.mjs +1 -1
- package/{src → authoring}/doc.mjs +1 -1
- package/{src → authoring}/doc.test.mjs +1 -1
- package/{src → authoring}/template.mjs +1 -1
- package/bin/astryx.mjs +12 -10
- package/{src → cli}/commands/blog.mjs +48 -7
- package/{src → cli}/commands/build-theme.mjs +133 -115
- package/cli/commands/build.mjs +172 -0
- package/cli/commands/cli-postinstall.test.mjs +42 -0
- package/{src → cli}/commands/component/index.mjs +52 -25
- package/{src → cli}/commands/component-ownership.test.mjs +3 -3
- package/{src → cli}/commands/component-package.test.mjs +1 -1
- package/{src → cli}/commands/component-resolution.test.mjs +2 -2
- package/{src → cli}/commands/discover.mjs +23 -12
- package/{src → cli}/commands/docs.mjs +42 -10
- package/{src → cli}/commands/docs.test.mjs +1 -1
- package/{src → cli}/commands/doctor.mjs +3 -3
- package/{src → cli}/commands/doctor.test.mjs +2 -2
- package/{src → cli}/commands/ensure-core-built.mjs +3 -2
- package/{src → cli}/commands/external-showcase.test.mjs +1 -1
- package/{src → cli}/commands/hook/index.mjs +40 -17
- package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
- package/cli/commands/init.mjs +195 -0
- package/{src → cli}/commands/init.next-steps.test.mjs +1 -1
- package/cli/commands/interactive-guard.test.mjs +66 -0
- package/{src → cli}/commands/json-contract.test.mjs +2 -2
- package/{src → cli}/commands/layout.mjs +59 -19
- package/{src → cli}/commands/search.mjs +22 -15
- package/{src → cli}/commands/search.test.mjs +1 -1
- package/cli/commands/setup-nudge.test.mjs +108 -0
- package/cli/commands/swizzle.mjs +103 -0
- package/{src → cli}/commands/template.mjs +84 -53
- package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
- package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
- package/{src → cli}/commands/upgrade.mjs +291 -77
- package/cli/commands/upgrade.test.mjs +314 -0
- package/{src → cli}/commands/validate-integration.mjs +17 -37
- package/{src → cli}/index.mjs +55 -19
- package/{src/codemods → codemods}/__tests__/registry.test.mjs +1 -0
- package/{src/codemods → codemods}/ensure-jscodeshift.mjs +12 -28
- package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
- package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
- package/{src/codemods → codemods}/integration-runner.mjs +8 -3
- package/{src/codemods → codemods}/registry.mjs +4 -1
- package/{src/codemods → codemods}/run-codemod.mjs +18 -11
- package/{src/codemods → codemods}/runner.mjs +24 -14
- package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
- package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
- package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
- package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
- package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +117 -13
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +86 -15
- package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
- package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
- package/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
- package/codemods/transforms/v0.1.8/index.mjs +19 -0
- package/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +239 -0
- package/docs/cli-integrations.doc.mjs +150 -0
- package/docs/elevation.doc.mjs +79 -1
- package/docs/getting-started.doc.mjs +9 -9
- package/docs/internationalization.doc.mjs +92 -46
- package/docs/migration.doc.mjs +18 -18
- package/docs/principles.doc.dense.mjs +1 -1
- package/docs/principles.doc.mjs +6 -6
- package/docs/principles.doc.zh.mjs +1 -1
- package/docs/styling-libraries.doc.mjs +3 -3
- package/docs/styling.doc.mjs +4 -4
- package/docs/theme.doc.dense.mjs +2 -2
- package/docs/theme.doc.mjs +7 -7
- package/docs/theme.doc.zh.mjs +1 -1
- package/docs/tokens.doc.mjs +1 -1
- package/docs/working-with-ai.doc.mjs +19 -19
- package/{src/commands → lib/agent-docs}/agent-docs.mjs +164 -29
- package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
- package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +123 -10
- package/{src/lib → lib}/cli-error.mjs +2 -2
- package/{src/lib → lib}/component-discovery.mjs +44 -2
- package/{src/lib → lib}/component-format.mjs +67 -25
- package/{src/lib → lib}/component-loader.mjs +27 -13
- package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
- package/{src/lib → lib}/error-codes.test.mjs +1 -1
- package/{src/lib → lib}/hook-discovery.mjs +14 -1
- package/{src/lib → lib}/hook-format.mjs +29 -5
- package/{src/lib → lib}/integration-warnings.mjs +2 -2
- package/{src/lib → lib}/integrations.mjs +20 -0
- package/{src/lib → lib}/integrations.test.mjs +1 -1
- package/{src/lib → lib}/json-contract.test.mjs +1 -1
- package/{src/lib → lib}/json-shim.mjs +11 -6
- package/{src/lib → lib}/json-shim.test.mjs +1 -1
- package/{src/lib → lib}/json.mjs +3 -3
- package/{src/lib → lib}/levenshtein.mjs +6 -0
- package/{src/lib → lib}/manifest.mjs +7 -5
- package/{src/lib → lib}/manifest.test.mjs +2 -2
- package/{src/lib → lib}/module-loader.mjs +1 -0
- package/{src/lib → lib}/package-scanner.mjs +47 -0
- package/{src/lib → lib}/project.mjs +48 -18
- package/{src/lib → lib}/project.test.mjs +1 -1
- package/{src/lib → lib}/resolve-theme.mjs +5 -0
- package/{src/lib → lib}/string-utils.mjs +15 -0
- package/lib/term-log.mjs +57 -0
- package/{src/lib → lib}/xle/browser.mjs +18 -8
- package/{src/lib → lib}/xle/expand.mjs +155 -22
- package/{src/lib → lib}/xle/parse.mjs +119 -13
- package/{src/lib → lib}/xle/print.mjs +54 -14
- package/{src/lib → lib}/xle/registry-core.mjs +28 -3
- package/{src/lib → lib}/xle/registry.mjs +9 -4
- package/{src/lib → lib}/xle/splice.mjs +13 -2
- package/{src/lib → lib}/xle/validate.mjs +95 -14
- package/lib/xle/xle-ast.d.ts +214 -0
- package/package.json +37 -28
- package/scripts/postinstall.mjs +74 -0
- package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
- package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarShowcase.tsx +5 -5
- package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
- package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
- package/templates/blocks/components/Banner/BannerFloating.doc.mjs +14 -0
- package/templates/blocks/components/Banner/BannerFloating.tsx +16 -0
- package/templates/blocks/components/Button/ButtonFloating.doc.mjs +14 -0
- package/templates/blocks/components/Button/ButtonFloating.tsx +37 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.doc.mjs +14 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.tsx +23 -0
- package/templates/blocks/components/Card/CardElevations.doc.mjs +14 -0
- package/templates/blocks/components/Card/CardElevations.tsx +32 -0
- package/templates/blocks/components/Card/ClickableCardElevated.doc.mjs +14 -0
- package/templates/blocks/components/Card/ClickableCardElevated.tsx +21 -0
- package/templates/blocks/components/Card/SelectableCardElevated.doc.mjs +14 -0
- package/templates/blocks/components/Card/SelectableCardElevated.tsx +37 -0
- package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
- package/templates/blocks/components/ChatComposer/ChatComposerFlat.doc.mjs +14 -0
- package/templates/blocks/components/ChatComposer/ChatComposerFlat.tsx +75 -0
- package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
- package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
- package/templates/blocks/components/CodeBlock/CodeBlockTerminal.tsx +1 -1
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
- package/templates/blocks/components/IconButton/IconButtonFloating.doc.mjs +14 -0
- package/templates/blocks/components/IconButton/IconButtonFloating.tsx +37 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
- package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
- package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
- package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.doc.mjs +14 -0
- package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.tsx +39 -0
- package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.doc.mjs +14 -0
- package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.tsx +44 -0
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
- package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
- package/templates/blocks/components/TabList/TabListTabsWithActions.doc.mjs +1 -1
- package/templates/blocks/components/TabList/TabListTabsWithActions.tsx +2 -7
- package/templates/blocks/components/Table/TableRowStatusTable.doc.mjs +14 -0
- package/templates/blocks/components/Table/TableRowStatusTable.tsx +59 -0
- package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +6 -1
- package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +1 -0
- package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +1 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
- package/templates/pages/ai-chat/page.tsx +4 -4
- package/templates/pages/dashboard-portfolio/page.tsx +3 -11
- package/templates/pages/detail-page/page.tsx +5 -12
- package/templates/pages/documentation-design/page.tsx +1 -1
- package/templates/pages/messaging-shell/page.tsx +6 -8
- package/templates/pages/table-grouped/page.tsx +9 -14
- package/templates/pages/table-page/page.tsx +7 -9
- package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
- package/{src/types → types}/api.contract.assert.ts +17 -8
- package/{src/types → types}/api.d.ts +110 -9
- package/{src/types → types}/base.d.ts +40 -4
- package/types/build.d.ts +53 -0
- package/types/codemod.d.ts +166 -0
- package/{src/types → types}/component.d.ts +1 -1
- package/{src/types → types}/discover.d.ts +1 -1
- package/{src/types → types}/docs.d.ts +1 -4
- package/{src/types → types}/hook.d.ts +1 -1
- package/{src/types → types}/index.d.ts +1 -0
- package/types/jscodeshift.d.ts +19 -0
- package/types/layout.d.ts +74 -0
- package/{src/types → types}/swizzle.d.ts +4 -0
- package/{src/types → types}/template-api.d.ts +4 -1
- package/types/theme.d.ts +53 -0
- package/types/upgrade.d.ts +108 -0
- package/utils/package-manager.mjs +178 -0
- package/utils/package-manager.test.mjs +220 -0
- package/{src/utils → utils}/path-safety.mjs +0 -18
- package/{src/utils → utils}/paths.mjs +4 -1
- package/{src/utils → utils}/update-check.mjs +5 -4
- package/{src/utils → utils}/update-check.test.mjs +3 -3
- package/docs/integration-authoring.md +0 -105
- package/src/commands/build.mjs +0 -196
- package/src/commands/init.mjs +0 -288
- package/src/commands/interactive-guard.test.mjs +0 -69
- package/src/commands/swizzle.mjs +0 -440
- package/src/commands/upgrade.test.mjs +0 -160
- package/src/types/codemod.d.ts +0 -81
- package/src/types/theme.d.ts +0 -23
- package/src/types/upgrade.d.ts +0 -64
- package/src/utils/interactive.mjs +0 -76
- package/src/utils/interactive.test.mjs +0 -70
- package/src/utils/package-manager.mjs +0 -74
- package/src/utils/package-manager.test.mjs +0 -113
- /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
- /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
- /package/{src/api → api/template}/template.test.mjs +0 -0
- /package/{src → authoring}/codemod.test.mjs +0 -0
- /package/{src → authoring}/config.mjs +0 -0
- /package/{src → authoring}/integration.mjs +0 -0
- /package/{src → authoring}/template.test.mjs +0 -0
- /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
- /package/{src → cli}/commands/component.test.mjs +0 -0
- /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
- /package/{src → cli}/commands/template.test.mjs +0 -0
- /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
- /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
- /package/{src → cli}/update-hint-commands.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
- /package/{src/lib → lib}/cli-error.test.mjs +0 -0
- /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
- /package/{src/lib → lib}/component-format.test.mjs +0 -0
- /package/{src/lib → lib}/component-loader.test.mjs +0 -0
- /package/{src/lib → lib}/config-cache.mjs +0 -0
- /package/{src/lib → lib}/config-cache.test.mjs +0 -0
- /package/{src/lib → lib}/config-schema.mjs +0 -0
- /package/{src/lib → lib}/error-codes.mjs +0 -0
- /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
- /package/{src/lib → lib}/module-loader.test.mjs +0 -0
- /package/{src/lib → lib}/node-version.mjs +0 -0
- /package/{src/lib → lib}/node-version.test.mjs +0 -0
- /package/{src/lib → lib}/parse.mjs +0 -0
- /package/{src/lib → lib}/site.mjs +0 -0
- /package/{src/lib → lib}/xle/browser.d.ts +0 -0
- /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
- /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
- /package/{src/schemas → schemas}/template-schema.mjs +0 -0
- /package/{src/types → types}/config.d.ts +0 -0
- /package/{src/types → types}/doc.d.ts +0 -0
- /package/{src/types → types}/doctor.d.ts +0 -0
- /package/{src/types → types}/error-codes.d.ts +0 -0
- /package/{src/types → types}/integration.d.ts +0 -0
- /package/{src/types → types}/manifest.d.ts +0 -0
- /package/{src/types → types}/search.d.ts +0 -0
- /package/{src/types → types}/template.d.ts +0 -0
- /package/{src/types → types}/validate-integration.d.ts +0 -0
- /package/{src/utils → utils}/github.mjs +0 -0
- /package/{src/utils → utils}/path-safety.test.mjs +0 -0
- /package/{src/utils → utils}/paths.test.mjs +0 -0
- /package/{src/utils → utils}/semver.mjs +0 -0
- /package/{src/utils → utils}/semver.test.mjs +0 -0
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export class XLEParseError extends Error {
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} message
|
|
22
|
+
* @param {number} line
|
|
23
|
+
* @param {number} col
|
|
24
|
+
*/
|
|
20
25
|
constructor(message, line, col) {
|
|
21
26
|
super(message);
|
|
22
27
|
this.name = 'XLEParseError';
|
|
@@ -25,7 +30,10 @@ export class XLEParseError extends Error {
|
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Keys that expand to full prop names before validation.
|
|
35
|
+
* @type {Record<string, string>}
|
|
36
|
+
*/
|
|
29
37
|
export const KEY_ALIASES = {
|
|
30
38
|
p: 'padding', pad: 'padding', g: 'gap', c: 'columns', cols: 'columns',
|
|
31
39
|
w: 'width', h: 'height', cp: 'contentPadding', mw: 'maxWidth',
|
|
@@ -38,6 +46,12 @@ export const KEY_ALIASES = {
|
|
|
38
46
|
/** Fused shorthand letters (`p6`, `g4`, `cp2`…) — letter must be a KEY_ALIAS. */
|
|
39
47
|
const FUSED = new Set(['p', 'g', 'c', 'w', 'h', 'cp', 'mw', 'mh', 'rg', 'cg']);
|
|
40
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @param {string|null} name
|
|
51
|
+
* @param {number} line
|
|
52
|
+
* @param {number} col
|
|
53
|
+
* @returns {import('./xle-ast').XLENode}
|
|
54
|
+
*/
|
|
41
55
|
export function makeNode(name, line, col) {
|
|
42
56
|
return {
|
|
43
57
|
kind: 'node',
|
|
@@ -57,20 +71,30 @@ export function makeNode(name, line, col) {
|
|
|
57
71
|
};
|
|
58
72
|
}
|
|
59
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @param {number} line
|
|
76
|
+
* @param {number} col
|
|
77
|
+
* @returns {import('./xle-ast').XLEGroup}
|
|
78
|
+
*/
|
|
60
79
|
function makeGroup(line, col) {
|
|
61
80
|
return {kind: 'group', repeat: null, children: [], line, col};
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
// ─── shared low-level helpers ──────────────────────────────────────────────
|
|
65
84
|
|
|
66
|
-
const isIdentStart = (ch) => /[A-Za-z]/.test(ch);
|
|
67
|
-
const isIdent = (ch) => /[A-Za-z0-9_-]/.test(ch);
|
|
85
|
+
const isIdentStart = (/** @type {string} */ ch) => /[A-Za-z]/.test(ch);
|
|
86
|
+
const isIdent = (/** @type {string} */ ch) => /[A-Za-z0-9_-]/.test(ch);
|
|
68
87
|
|
|
69
88
|
/**
|
|
70
89
|
* Split a string into tokens at depth-0 whitespace, where (), [], {} and
|
|
71
90
|
* quotes raise depth. Used for attr blocks and outline lines.
|
|
91
|
+
* @param {string} str
|
|
92
|
+
* @param {number} line
|
|
93
|
+
* @param {number} startCol
|
|
94
|
+
* @returns {Array<{text: string, col: number}>}
|
|
72
95
|
*/
|
|
73
96
|
function tokenize(str, line, startCol) {
|
|
97
|
+
/** @type {Array<{text: string, col: number}>} */
|
|
74
98
|
const tokens = [];
|
|
75
99
|
let i = 0;
|
|
76
100
|
while (i < str.length) {
|
|
@@ -78,6 +102,7 @@ function tokenize(str, line, startCol) {
|
|
|
78
102
|
if (i >= str.length) break;
|
|
79
103
|
const start = i;
|
|
80
104
|
let depth = 0;
|
|
105
|
+
/** @type {string|null} */
|
|
81
106
|
let quote = null;
|
|
82
107
|
while (i < str.length) {
|
|
83
108
|
const ch = str[i];
|
|
@@ -101,7 +126,11 @@ function tokenize(str, line, startCol) {
|
|
|
101
126
|
return tokens;
|
|
102
127
|
}
|
|
103
128
|
|
|
104
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Parse a scalar/object/list attr value string into a JS value.
|
|
131
|
+
* @param {string} raw
|
|
132
|
+
* @returns {import('./xle-ast').XLEValue}
|
|
133
|
+
*/
|
|
105
134
|
export function parseValue(raw) {
|
|
106
135
|
const s = raw.trim();
|
|
107
136
|
if (/^(['"]).*\1$/.test(s)) return s.slice(1, -1);
|
|
@@ -110,6 +139,7 @@ export function parseValue(raw) {
|
|
|
110
139
|
if (s === 'false') return false;
|
|
111
140
|
if (s.startsWith('#')) return {idref: s.slice(1)};
|
|
112
141
|
if (s.startsWith('{') && s.endsWith('}')) {
|
|
142
|
+
/** @type {Record<string, import('./xle-ast').XLEValue>} */
|
|
113
143
|
const obj = {};
|
|
114
144
|
for (const part of splitTop(s.slice(1, -1), ',')) {
|
|
115
145
|
const idx = part.indexOf(':');
|
|
@@ -125,10 +155,16 @@ export function parseValue(raw) {
|
|
|
125
155
|
return s; // bare ident — enum string
|
|
126
156
|
}
|
|
127
157
|
|
|
128
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Split on a separator at bracket/quote depth 0.
|
|
160
|
+
* @param {string} str
|
|
161
|
+
* @param {string} sep
|
|
162
|
+
* @returns {string[]}
|
|
163
|
+
*/
|
|
129
164
|
function splitTop(str, sep) {
|
|
130
165
|
const parts = [];
|
|
131
166
|
let depth = 0;
|
|
167
|
+
/** @type {string|null} */
|
|
132
168
|
let quote = null;
|
|
133
169
|
let cur = '';
|
|
134
170
|
for (const ch of str) {
|
|
@@ -151,7 +187,13 @@ function splitTop(str, sep) {
|
|
|
151
187
|
return parts.map(p => p.trim()).filter(Boolean);
|
|
152
188
|
}
|
|
153
189
|
|
|
154
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Parse `{name +flag +flag2 :arg}` hint body (without braces).
|
|
192
|
+
* @param {string} body
|
|
193
|
+
* @param {number} line
|
|
194
|
+
* @param {number} col
|
|
195
|
+
* @returns {import('./xle-ast').Hint}
|
|
196
|
+
*/
|
|
155
197
|
function parseHintBody(body, line, col) {
|
|
156
198
|
const m = body.trim().match(/^([a-z0-9][a-z0-9-]*)((?:\s*\+[a-z0-9-]+)*)(?:\s*:(.*))?$/);
|
|
157
199
|
if (!m) {
|
|
@@ -169,8 +211,10 @@ function parseHintBody(body, line, col) {
|
|
|
169
211
|
}
|
|
170
212
|
|
|
171
213
|
/**
|
|
172
|
-
* Interpret one attribute token. Returns an attr record or
|
|
173
|
-
*
|
|
214
|
+
* Interpret one attribute token. Returns an attr record or a slot record.
|
|
215
|
+
* @param {{text: string, col: number}} token
|
|
216
|
+
* @param {number} line
|
|
217
|
+
* @returns {import('./xle-ast').Attr | import('./xle-ast').Slot}
|
|
174
218
|
*/
|
|
175
219
|
function parseAttrToken(token, line) {
|
|
176
220
|
const {text, col} = token;
|
|
@@ -182,6 +226,7 @@ function parseAttrToken(token, line) {
|
|
|
182
226
|
}
|
|
183
227
|
const name = text.slice(1, eq);
|
|
184
228
|
const rest = text.slice(eq + 1);
|
|
229
|
+
/** @type {import('./xle-ast').SlotValue} */
|
|
185
230
|
let value;
|
|
186
231
|
if (rest.startsWith('(') && rest.endsWith(')')) {
|
|
187
232
|
value = {subexpr: parseCompactSiblings(new CompactStream(rest.slice(1, -1), line, col + eq + 2))};
|
|
@@ -203,6 +248,7 @@ function parseAttrToken(token, line) {
|
|
|
203
248
|
|
|
204
249
|
// key=value (split at first depth-0 '=')
|
|
205
250
|
let depth = 0;
|
|
251
|
+
/** @type {string|null} */
|
|
206
252
|
let quote = null;
|
|
207
253
|
for (let i = 0; i < text.length; i++) {
|
|
208
254
|
const ch = text[i];
|
|
@@ -240,6 +286,11 @@ function parseAttrToken(token, line) {
|
|
|
240
286
|
// ─── compact (XLE) surface ─────────────────────────────────────────────────
|
|
241
287
|
|
|
242
288
|
class CompactStream {
|
|
289
|
+
/**
|
|
290
|
+
* @param {string} src
|
|
291
|
+
* @param {number} [line]
|
|
292
|
+
* @param {number} [col]
|
|
293
|
+
*/
|
|
243
294
|
constructor(src, line = 1, col = 1) {
|
|
244
295
|
this.src = src;
|
|
245
296
|
this.i = 0;
|
|
@@ -253,21 +304,29 @@ class CompactStream {
|
|
|
253
304
|
const col = (lines.length === 1 ? this.baseCol : 1) + lines[lines.length - 1].length;
|
|
254
305
|
return {line, col};
|
|
255
306
|
}
|
|
307
|
+
/** @param {number} [offset] */
|
|
256
308
|
peek(offset = 0) { return this.src[this.i + offset]; }
|
|
257
309
|
next() { return this.src[this.i++]; }
|
|
258
310
|
eof() { return this.i >= this.src.length; }
|
|
259
311
|
skipWs() { while (!this.eof() && /\s/.test(this.peek())) this.i++; }
|
|
312
|
+
/** @param {string} message */
|
|
260
313
|
error(message) {
|
|
261
314
|
const {line, col} = this.pos();
|
|
262
315
|
throw new XLEParseError(message, line, col);
|
|
263
316
|
}
|
|
264
|
-
/**
|
|
317
|
+
/**
|
|
318
|
+
* Consume through the matching close bracket; returns inner text.
|
|
319
|
+
* @param {string} open
|
|
320
|
+
* @param {string} close
|
|
321
|
+
* @returns {string}
|
|
322
|
+
*/
|
|
265
323
|
readBalanced(open, close) {
|
|
266
324
|
const startPos = this.pos();
|
|
267
325
|
if (this.peek() !== open) this.error(`Expected '${open}'`);
|
|
268
326
|
this.next();
|
|
269
327
|
const start = this.i;
|
|
270
328
|
let depth = 1;
|
|
329
|
+
/** @type {string|null} */
|
|
271
330
|
let quote = null;
|
|
272
331
|
while (!this.eof()) {
|
|
273
332
|
const ch = this.next();
|
|
@@ -292,6 +351,10 @@ class CompactStream {
|
|
|
292
351
|
}
|
|
293
352
|
}
|
|
294
353
|
|
|
354
|
+
/**
|
|
355
|
+
* @param {CompactStream} s
|
|
356
|
+
* @returns {import('./xle-ast').XLENode}
|
|
357
|
+
*/
|
|
295
358
|
function parseCompactNode(s) {
|
|
296
359
|
const {line, col} = s.pos();
|
|
297
360
|
let name = '';
|
|
@@ -359,6 +422,10 @@ function parseCompactNode(s) {
|
|
|
359
422
|
return node;
|
|
360
423
|
}
|
|
361
424
|
|
|
425
|
+
/**
|
|
426
|
+
* @param {CompactStream} s
|
|
427
|
+
* @returns {import('./xle-ast').XLEItem}
|
|
428
|
+
*/
|
|
362
429
|
function parseCompactTerm(s) {
|
|
363
430
|
s.skipWs();
|
|
364
431
|
if (s.peek() === '(') {
|
|
@@ -387,11 +454,20 @@ function parseCompactTerm(s) {
|
|
|
387
454
|
return parseCompactNode(s);
|
|
388
455
|
}
|
|
389
456
|
|
|
457
|
+
/**
|
|
458
|
+
* @param {import('./xle-ast').XLEItem} node
|
|
459
|
+
* @returns {import('./xle-ast').XLENode}
|
|
460
|
+
*/
|
|
390
461
|
function structuredCloneNode(node) {
|
|
391
462
|
return JSON.parse(JSON.stringify(node));
|
|
392
463
|
}
|
|
393
464
|
|
|
465
|
+
/**
|
|
466
|
+
* @param {CompactStream} s
|
|
467
|
+
* @returns {import('./xle-ast').XLEItem[]}
|
|
468
|
+
*/
|
|
394
469
|
function parseCompactSiblings(s) {
|
|
470
|
+
/** @type {import('./xle-ast').XLEItem[]} */
|
|
395
471
|
const terms = [];
|
|
396
472
|
for (;;) {
|
|
397
473
|
s.skipWs();
|
|
@@ -410,12 +486,17 @@ function parseCompactSiblings(s) {
|
|
|
410
486
|
return terms;
|
|
411
487
|
}
|
|
412
488
|
|
|
489
|
+
/**
|
|
490
|
+
* @param {string} source
|
|
491
|
+
* @returns {import('./xle-ast').XLEDoc}
|
|
492
|
+
*/
|
|
413
493
|
export function parseCompact(source) {
|
|
414
494
|
const parts = source.split(/;;/);
|
|
415
495
|
const main = new CompactStream(parts[0]);
|
|
416
496
|
const roots = parseCompactSiblings(main);
|
|
417
497
|
main.skipWs();
|
|
418
498
|
if (!main.eof()) main.error(`Unexpected '${main.peek()}'`);
|
|
499
|
+
/** @type {import('./xle-ast').XLEItem[]} */
|
|
419
500
|
const overlays = [];
|
|
420
501
|
for (const part of parts.slice(1)) {
|
|
421
502
|
const s = new CompactStream(part);
|
|
@@ -428,20 +509,35 @@ export function parseCompact(source) {
|
|
|
428
509
|
|
|
429
510
|
// ─── outline (XLO) surface ─────────────────────────────────────────────────
|
|
430
511
|
|
|
431
|
-
/**
|
|
512
|
+
/**
|
|
513
|
+
* Parse one outline line's node chain: `Layout > LayoutContent pad=0 !scroll`.
|
|
514
|
+
* @param {string} text
|
|
515
|
+
* @param {number} line
|
|
516
|
+
* @returns {{head: import('./xle-ast').XLENode, tail: import('./xle-ast').XLENode}}
|
|
517
|
+
*/
|
|
432
518
|
function parseOutlineChain(text, line) {
|
|
433
519
|
const segments = splitTop(text, '>');
|
|
520
|
+
/** @type {import('./xle-ast').XLENode | null} */
|
|
434
521
|
let head = null;
|
|
522
|
+
/** @type {import('./xle-ast').XLENode | null} */
|
|
435
523
|
let tail = null;
|
|
436
524
|
for (const segment of segments) {
|
|
437
525
|
const node = parseOutlineNodeSegment(segment, line);
|
|
438
526
|
if (!head) head = node;
|
|
439
|
-
else tail.children.push(node);
|
|
527
|
+
else /** @type {import('./xle-ast').XLENode} */ (tail).children.push(node);
|
|
440
528
|
tail = node;
|
|
441
529
|
}
|
|
442
|
-
return {head, tail}
|
|
530
|
+
return /** @type {{head: import('./xle-ast').XLENode, tail: import('./xle-ast').XLENode}} */ ({
|
|
531
|
+
head,
|
|
532
|
+
tail,
|
|
533
|
+
});
|
|
443
534
|
}
|
|
444
535
|
|
|
536
|
+
/**
|
|
537
|
+
* @param {string} segment
|
|
538
|
+
* @param {number} line
|
|
539
|
+
* @returns {import('./xle-ast').XLENode}
|
|
540
|
+
*/
|
|
445
541
|
function parseOutlineNodeSegment(segment, line) {
|
|
446
542
|
const tokens = tokenize(segment, line, 0);
|
|
447
543
|
if (tokens.length === 0) throw new XLEParseError('Empty node', line, 1);
|
|
@@ -487,10 +583,17 @@ function parseOutlineNodeSegment(segment, line) {
|
|
|
487
583
|
return node;
|
|
488
584
|
}
|
|
489
585
|
|
|
586
|
+
/**
|
|
587
|
+
* @param {string} source
|
|
588
|
+
* @returns {import('./xle-ast').XLEDoc}
|
|
589
|
+
*/
|
|
490
590
|
export function parseOutline(source) {
|
|
591
|
+
/** @type {import('./xle-ast').XLEItem[]} */
|
|
491
592
|
const roots = [];
|
|
593
|
+
/** @type {import('./xle-ast').XLEItem[]} */
|
|
492
594
|
const overlays = [];
|
|
493
595
|
// Stack frames: {indent, container: array, node|null}
|
|
596
|
+
/** @type {Array<{indent: number, container: import('./xle-ast').XLEItem[], node: import('./xle-ast').XLENode | null}>} */
|
|
494
597
|
const stack = [{indent: -1, container: roots, node: null}];
|
|
495
598
|
let inOverlays = false;
|
|
496
599
|
|
|
@@ -499,7 +602,7 @@ export function parseOutline(source) {
|
|
|
499
602
|
const raw = lines[li];
|
|
500
603
|
const lineNo = li + 1;
|
|
501
604
|
if (raw.trim() === '' || raw.trim().startsWith('#') || raw.trim().startsWith('//')) continue;
|
|
502
|
-
const indent = raw.match(/^[ \t]*/)[0].replace(/\t/g, ' ').length;
|
|
605
|
+
const indent = /** @type {RegExpMatchArray} */ (raw.match(/^[ \t]*/))[0].replace(/\t/g, ' ').length;
|
|
503
606
|
const text = raw.trim();
|
|
504
607
|
|
|
505
608
|
if (text === 'overlays:') {
|
|
@@ -530,6 +633,7 @@ export function parseOutline(source) {
|
|
|
530
633
|
`Slot '${slotMatch[1]}:' has no parent component`, lineNo, indent + 1,
|
|
531
634
|
);
|
|
532
635
|
}
|
|
636
|
+
/** @type {import('./xle-ast').Slot & {value: {subexpr: import('./xle-ast').XLEItem[]}}} */
|
|
533
637
|
const slot = {kind: 'slot', key: slotMatch[1], value: {subexpr: []}, line: lineNo, col: indent + 1};
|
|
534
638
|
parent.node.slots.push(slot);
|
|
535
639
|
const inline = slotMatch[2].trim();
|
|
@@ -557,6 +661,8 @@ export function parseOutline(source) {
|
|
|
557
661
|
* Detect which surface the source uses. Multi-line input is outline
|
|
558
662
|
* unless every line break sits inside an operator chain (trailing
|
|
559
663
|
* `>`/`+`/`;;` or unclosed brackets), which is multi-line compact.
|
|
664
|
+
* @param {string} source
|
|
665
|
+
* @returns {'compact'|'outline'}
|
|
560
666
|
*/
|
|
561
667
|
export function detectForm(source) {
|
|
562
668
|
const lines = source.split('\n').map(l => l.trim()).filter(l => l !== '' && !l.startsWith('#') && !l.startsWith('//'));
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
* @position lib/xle — inverse of parse.mjs
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @param {import('./xle-ast').XLEValue} value
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
16
20
|
function valueText(value) {
|
|
17
21
|
if (typeof value === 'string') return /[\s,'"]/.test(value) ? `'${value}'` : value;
|
|
18
22
|
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
19
|
-
if (value && value.idref) return `#${value.idref}`;
|
|
23
|
+
if (value && /** @type {any} */ (value).idref) return `#${/** @type {any} */ (value).idref}`;
|
|
20
24
|
if (Array.isArray(value)) return `[${value.map(valueText).join(',')}]`;
|
|
21
25
|
if (typeof value === 'object' && value !== null) {
|
|
22
26
|
return `{${Object.entries(value)
|
|
@@ -26,6 +30,10 @@ function valueText(value) {
|
|
|
26
30
|
return String(value);
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @param {import('./xle-ast').Hint} hint
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
29
37
|
function hintText(hint) {
|
|
30
38
|
let out = hint.name;
|
|
31
39
|
for (const flag of hint.flags || []) out += ` +${flag}`;
|
|
@@ -33,6 +41,7 @@ function hintText(hint) {
|
|
|
33
41
|
return `{${out}}`;
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
/** @param {import('./xle-ast').XLENode} node */
|
|
36
45
|
function attrTokens(node) {
|
|
37
46
|
const tokens = [];
|
|
38
47
|
for (const attr of node.attrs) {
|
|
@@ -43,17 +52,22 @@ function attrTokens(node) {
|
|
|
43
52
|
return tokens;
|
|
44
53
|
}
|
|
45
54
|
|
|
55
|
+
/** @param {import('./xle-ast').XLENode} node */
|
|
46
56
|
function slotTokensCompact(node) {
|
|
47
57
|
return node.slots.map(slot => {
|
|
48
58
|
if (slot.value == null) return `@${slot.key}`;
|
|
49
59
|
if (typeof slot.value === 'string') return `@${slot.key}='${slot.value}'`;
|
|
50
|
-
if (slot.value
|
|
51
|
-
if (slot.value.idref) return `@${slot.key}=#${slot.value.idref}`;
|
|
52
|
-
if (slot.value
|
|
60
|
+
if ('hint' in slot.value) return `@${slot.key}=${hintText(slot.value.hint)}`;
|
|
61
|
+
if (/** @type {any} */ (slot.value).idref) return `@${slot.key}=#${/** @type {any} */ (slot.value).idref}`;
|
|
62
|
+
if ('subexpr' in slot.value) return `@${slot.key}=(${siblingsCompact(slot.value.subexpr)})`;
|
|
53
63
|
return `@${slot.key}`;
|
|
54
64
|
});
|
|
55
65
|
}
|
|
56
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @param {import('./xle-ast').XLENode} node
|
|
69
|
+
* @returns {string}
|
|
70
|
+
*/
|
|
57
71
|
function nodeCompact(node) {
|
|
58
72
|
let out = node.name || '';
|
|
59
73
|
if (node.id) out += `#${node.id}`;
|
|
@@ -72,6 +86,10 @@ function nodeCompact(node) {
|
|
|
72
86
|
return out;
|
|
73
87
|
}
|
|
74
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @param {import('./xle-ast').XLEItem} item
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
75
93
|
function termCompact(item) {
|
|
76
94
|
if (item.kind === 'group') {
|
|
77
95
|
let out = `(${siblingsCompact(item.children)})`;
|
|
@@ -82,6 +100,10 @@ function termCompact(item) {
|
|
|
82
100
|
return nodeCompact(item);
|
|
83
101
|
}
|
|
84
102
|
|
|
103
|
+
/**
|
|
104
|
+
* @param {import('./xle-ast').XLEItem[]} items
|
|
105
|
+
* @returns {string}
|
|
106
|
+
*/
|
|
85
107
|
function siblingsCompact(items) {
|
|
86
108
|
return items
|
|
87
109
|
.map((item, i) => {
|
|
@@ -96,6 +118,7 @@ function siblingsCompact(items) {
|
|
|
96
118
|
.join(' + ');
|
|
97
119
|
}
|
|
98
120
|
|
|
121
|
+
/** @param {import('./xle-ast').XLEDoc} doc */
|
|
99
122
|
export function toCompact(doc) {
|
|
100
123
|
let out = siblingsCompact(doc.roots);
|
|
101
124
|
for (const overlay of doc.overlays) {
|
|
@@ -106,6 +129,11 @@ export function toCompact(doc) {
|
|
|
106
129
|
|
|
107
130
|
// ── outline ────────────────────────────────────────────────────────────────
|
|
108
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @param {import('./xle-ast').XLENode} node
|
|
134
|
+
* @param {number} depth
|
|
135
|
+
* @returns {string[]}
|
|
136
|
+
*/
|
|
109
137
|
function nodeOutlineLines(node, depth) {
|
|
110
138
|
const pad = ' '.repeat(depth);
|
|
111
139
|
let line = node.name || '';
|
|
@@ -121,21 +149,23 @@ function nodeOutlineLines(node, depth) {
|
|
|
121
149
|
|
|
122
150
|
const lines = [pad + line.trimStart()];
|
|
123
151
|
for (const slot of node.slots) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
152
|
+
const sv = slot.value;
|
|
153
|
+
if (sv && typeof sv === 'object' && 'subexpr' in sv) {
|
|
154
|
+
const first = sv.subexpr[0];
|
|
155
|
+
if (sv.subexpr.length === 1 && first && isSimpleNode(first)) {
|
|
156
|
+
const sub = nodeOutlineLines(first, 0)[0];
|
|
127
157
|
lines.push(`${pad} ${slot.key}: ${sub}`);
|
|
128
158
|
// simple = no children, so the single line is complete
|
|
129
159
|
} else {
|
|
130
160
|
lines.push(`${pad} ${slot.key}:`);
|
|
131
|
-
for (const sub of
|
|
161
|
+
for (const sub of sv.subexpr) lines.push(...itemOutlineLines(sub, depth + 2));
|
|
132
162
|
}
|
|
133
|
-
} else if (typeof
|
|
134
|
-
lines.push(`${pad} ${slot.key}: "${
|
|
135
|
-
} else if (
|
|
136
|
-
lines.push(`${pad} ${slot.key}: ${hintText(
|
|
137
|
-
} else if (
|
|
138
|
-
lines.push(`${pad} ${slot.key}: #${
|
|
163
|
+
} else if (typeof sv === 'string') {
|
|
164
|
+
lines.push(`${pad} ${slot.key}: "${sv}"`);
|
|
165
|
+
} else if (sv && typeof sv === 'object' && 'hint' in sv) {
|
|
166
|
+
lines.push(`${pad} ${slot.key}: ${hintText(sv.hint)}`);
|
|
167
|
+
} else if (sv && /** @type {any} */ (sv).idref) {
|
|
168
|
+
lines.push(`${pad} ${slot.key}: #${/** @type {any} */ (sv).idref}`);
|
|
139
169
|
} else {
|
|
140
170
|
lines.push(`${pad} ${slot.key}:`);
|
|
141
171
|
}
|
|
@@ -144,10 +174,19 @@ function nodeOutlineLines(node, depth) {
|
|
|
144
174
|
return lines;
|
|
145
175
|
}
|
|
146
176
|
|
|
177
|
+
/**
|
|
178
|
+
* @param {import('./xle-ast').XLEItem} item
|
|
179
|
+
* @returns {item is import('./xle-ast').XLENode}
|
|
180
|
+
*/
|
|
147
181
|
function isSimpleNode(item) {
|
|
148
182
|
return item.kind === 'node' && item.children.length === 0 && item.slots.length === 0;
|
|
149
183
|
}
|
|
150
184
|
|
|
185
|
+
/**
|
|
186
|
+
* @param {import('./xle-ast').XLEItem} item
|
|
187
|
+
* @param {number} depth
|
|
188
|
+
* @returns {string[]}
|
|
189
|
+
*/
|
|
151
190
|
function itemOutlineLines(item, depth) {
|
|
152
191
|
if (item.kind === 'group') {
|
|
153
192
|
// A repeat-less group exists only to disambiguate compact-form
|
|
@@ -163,6 +202,7 @@ function itemOutlineLines(item, depth) {
|
|
|
163
202
|
return nodeOutlineLines(item, depth);
|
|
164
203
|
}
|
|
165
204
|
|
|
205
|
+
/** @param {import('./xle-ast').XLEDoc} doc */
|
|
166
206
|
export function toOutline(doc) {
|
|
167
207
|
const lines = [];
|
|
168
208
|
for (const item of doc.roots) lines.push(...itemOutlineLines(item, 0));
|
|
@@ -74,6 +74,8 @@ export const SPACING_STEPS = [0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10];
|
|
|
74
74
|
* Parse enum values from a doc.mjs prop type string.
|
|
75
75
|
* "'a' | 'b' | 'c'" → ['a','b','c']; "1|2|3" → [1,2,3];
|
|
76
76
|
* "SpacingStep" → SPACING_STEPS. Mixed/non-enum types → null.
|
|
77
|
+
* @param {string | undefined | null} type
|
|
78
|
+
* @returns {Array<string | number> | null}
|
|
77
79
|
*/
|
|
78
80
|
export function parseEnumValues(type) {
|
|
79
81
|
if (!type || typeof type !== 'string') return null;
|
|
@@ -83,6 +85,7 @@ export function parseEnumValues(type) {
|
|
|
83
85
|
}
|
|
84
86
|
const parts = t.split('|').map(p => p.trim());
|
|
85
87
|
if (parts.length < 2) return null;
|
|
88
|
+
/** @type {Array<string | number>} */
|
|
86
89
|
const values = [];
|
|
87
90
|
for (const part of parts) {
|
|
88
91
|
const str = part.match(/^'([^']*)'$/) || part.match(/^"([^"]*)"$/);
|
|
@@ -93,14 +96,21 @@ export function parseEnumValues(type) {
|
|
|
93
96
|
return values;
|
|
94
97
|
}
|
|
95
98
|
|
|
99
|
+
/** @param {string} name */
|
|
96
100
|
export function normalizeName(name) {
|
|
97
101
|
return name.replace(/^XDS/, '');
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
/**
|
|
101
105
|
* Index one doc entry's props into the registry component shape.
|
|
106
|
+
* @param {string} name
|
|
107
|
+
* @param {import('./xle-ast').DocProp[]} props
|
|
108
|
+
* @param {string} dirName
|
|
109
|
+
* @param {string} importPath
|
|
110
|
+
* @returns {import('./xle-ast').RegistryComponent}
|
|
102
111
|
*/
|
|
103
112
|
export function toComponentEntry(name, props, dirName, importPath) {
|
|
113
|
+
/** @type {Map<string, import('./xle-ast').RegistryProp>} */
|
|
104
114
|
const propMap = new Map();
|
|
105
115
|
for (const p of props || []) {
|
|
106
116
|
propMap.set(p.name, {
|
|
@@ -119,10 +129,14 @@ export function toComponentEntry(name, props, dirName, importPath) {
|
|
|
119
129
|
/**
|
|
120
130
|
* Resolve a node name (alias, bare name, or XDS-prefixed name) to a
|
|
121
131
|
* registry component entry, or null.
|
|
132
|
+
* @param {import('./xle-ast').Registry} registry
|
|
133
|
+
* @param {string | null} name
|
|
134
|
+
* @returns {import('./xle-ast').RegistryComponent | null}
|
|
122
135
|
*/
|
|
123
136
|
export function resolveComponent(registry, name) {
|
|
137
|
+
if (name == null) return null;
|
|
124
138
|
const viaAlias = registry.aliases.get(name);
|
|
125
|
-
if (viaAlias) return registry.components.get(viaAlias);
|
|
139
|
+
if (viaAlias) return registry.components.get(viaAlias) ?? null;
|
|
126
140
|
const bare = normalizeName(name);
|
|
127
141
|
return registry.components.get(bare) || null;
|
|
128
142
|
}
|
|
@@ -130,6 +144,8 @@ export function resolveComponent(registry, name) {
|
|
|
130
144
|
/**
|
|
131
145
|
* Serialize a built registry (with Map fields) to a plain JSON-safe object
|
|
132
146
|
* so a Node build step can ship it to the browser.
|
|
147
|
+
* @param {import('./xle-ast').Registry} registry
|
|
148
|
+
* @returns {import('./browser').SerializedRegistry}
|
|
133
149
|
*/
|
|
134
150
|
export function serializeRegistry(registry) {
|
|
135
151
|
return {
|
|
@@ -139,7 +155,7 @@ export function serializeRegistry(registry) {
|
|
|
139
155
|
dirName: c.dirName,
|
|
140
156
|
importPath: c.importPath,
|
|
141
157
|
undocumented: c.undocumented || false,
|
|
142
|
-
props: [...c.props.values()],
|
|
158
|
+
props: /** @type {Array<Record<string, unknown>>} */ (/** @type {unknown} */ ([...c.props.values()])),
|
|
143
159
|
})),
|
|
144
160
|
aliases: [...registry.aliases.entries()],
|
|
145
161
|
componentNames: registry.componentNames,
|
|
@@ -149,17 +165,26 @@ export function serializeRegistry(registry) {
|
|
|
149
165
|
/**
|
|
150
166
|
* Hydrate a serialized registry back into the Map-bearing shape that
|
|
151
167
|
* validate()/expand() expect. Inverse of serializeRegistry.
|
|
168
|
+
* @param {import('./browser').SerializedRegistry} json
|
|
169
|
+
* @returns {import('./xle-ast').Registry}
|
|
152
170
|
*/
|
|
153
171
|
export function hydrateRegistry(json) {
|
|
172
|
+
/** @type {Map<string, import('./xle-ast').RegistryComponent>} */
|
|
154
173
|
const components = new Map();
|
|
155
174
|
for (const c of json.components) {
|
|
175
|
+
/** @type {Map<string, import('./xle-ast').RegistryProp>} */
|
|
176
|
+
const props = new Map();
|
|
177
|
+
for (const p of c.props) {
|
|
178
|
+
const prop = /** @type {import('./xle-ast').RegistryProp} */ (/** @type {unknown} */ (p));
|
|
179
|
+
props.set(String(p.name), prop);
|
|
180
|
+
}
|
|
156
181
|
components.set(c.name, {
|
|
157
182
|
name: c.name,
|
|
158
183
|
exportName: c.exportName,
|
|
159
184
|
dirName: c.dirName,
|
|
160
185
|
importPath: c.importPath,
|
|
161
186
|
undocumented: c.undocumented || false,
|
|
162
|
-
props
|
|
187
|
+
props,
|
|
163
188
|
});
|
|
164
189
|
}
|
|
165
190
|
return {
|
|
@@ -40,6 +40,11 @@ export {
|
|
|
40
40
|
hydrateRegistry,
|
|
41
41
|
} from './registry-core.mjs';
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @param {Record<string, string[]>} grouped
|
|
45
|
+
* @param {string} member
|
|
46
|
+
* @returns {string|null}
|
|
47
|
+
*/
|
|
43
48
|
function findDirFor(grouped, member) {
|
|
44
49
|
for (const [dir, members] of Object.entries(grouped)) {
|
|
45
50
|
if (members.includes(member)) return dir;
|
|
@@ -90,7 +95,7 @@ function readDirExportedComponents(coreDir, dirName) {
|
|
|
90
95
|
return [...names];
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
let cachedRegistry = null;
|
|
98
|
+
let cachedRegistry = /** @type {import('./xle-ast').Registry | null} */ (null);
|
|
94
99
|
|
|
95
100
|
/**
|
|
96
101
|
* Build (and cache) the registry: every documented component keyed by its
|
|
@@ -123,7 +128,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
|
|
|
123
128
|
}
|
|
124
129
|
const importPath = resolveImportPath(coreDir, dirName);
|
|
125
130
|
|
|
126
|
-
const register = (rawName, props) => {
|
|
131
|
+
const register = (/** @type {string} */ rawName, /** @type {import('./xle-ast').DocProp[]} */ props) => {
|
|
127
132
|
const name = normalizeName(rawName);
|
|
128
133
|
const entry = toComponentEntry(name, props, dirName, importPath);
|
|
129
134
|
const existing = components.get(name);
|
|
@@ -147,7 +152,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
|
|
|
147
152
|
// props go missing and valid attrs (e.g. Heading[level=2]) get rejected.
|
|
148
153
|
// Read every .doc.mjs in each contributing dir and upgrade props, keyed to
|
|
149
154
|
// each component's own export subpath. Props-only: never adds empty entries.
|
|
150
|
-
const upgradeFromDoc = (rawName, props, fallbackDir) => {
|
|
155
|
+
const upgradeFromDoc = (/** @type {string} */ rawName, /** @type {import('./xle-ast').DocProp[]} */ props, /** @type {string} */ fallbackDir) => {
|
|
151
156
|
if (!props || props.length === 0) return;
|
|
152
157
|
const name = normalizeName(rawName);
|
|
153
158
|
// Prefer the component's own export subpath (Heading → @astryxdesign/core/Heading);
|
|
@@ -193,7 +198,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
|
|
|
193
198
|
// (TableHeader/Body/Footer became bare files with no own .doc.mjs after
|
|
194
199
|
// the un-prefix migration), so we recover them from the real export
|
|
195
200
|
// surface here.
|
|
196
|
-
const registerUndocumented = (name, dirName) => {
|
|
201
|
+
const registerUndocumented = (/** @type {string} */ name, /** @type {string} */ dirName) => {
|
|
197
202
|
if (components.has(name)) return;
|
|
198
203
|
const entry = toComponentEntry(name, [], dirName, resolveImportPath(coreDir, name));
|
|
199
204
|
entry.undocumented = true;
|