forgebook 0.3.3 → 0.4.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/README.md +914 -72
- package/dist/bin/forgebook/agentClient.d.ts +2 -1
- package/dist/bin/forgebook/agentClient.js +13 -6
- package/dist/bin/forgebook/agentGuide.d.ts +59 -0
- package/dist/bin/forgebook/agentGuide.js +203 -0
- package/dist/bin/forgebook/agentLoopCommands.mjs +22 -42
- package/dist/bin/forgebook/agentSetup/agentFiles.d.ts +55 -0
- package/dist/bin/forgebook/agentSetup/agentFiles.js +319 -0
- package/dist/bin/forgebook/agentSetup/assistantHooks.d.ts +71 -0
- package/dist/bin/forgebook/agentSetup/assistantHooks.js +125 -0
- package/dist/bin/forgebook/agentSetup/ciWorkflow.d.ts +23 -0
- package/dist/bin/forgebook/agentSetup/ciWorkflow.js +55 -0
- package/dist/bin/forgebook/agentSetup/drawCandidates.d.ts +25 -0
- package/dist/bin/forgebook/agentSetup/drawCandidates.js +116 -0
- package/dist/bin/forgebook/agentSetup/drawDiagnosis.d.ts +28 -0
- package/dist/bin/forgebook/agentSetup/drawDiagnosis.js +134 -0
- package/dist/bin/forgebook/agentSetup/drawRun.d.ts +91 -0
- package/dist/bin/forgebook/agentSetup/drawRun.js +353 -0
- package/dist/bin/forgebook/agentSetup/hookNames.d.ts +7 -0
- package/dist/bin/forgebook/agentSetup/hookNames.js +7 -0
- package/dist/bin/forgebook/agentSetup/initAgentSteps.d.ts +48 -0
- package/dist/bin/forgebook/agentSetup/initAgentSteps.js +104 -0
- package/dist/bin/forgebook/agentSetup/liftedProviders.d.ts +17 -0
- package/dist/bin/forgebook/agentSetup/liftedProviders.js +186 -0
- package/dist/bin/forgebook/agentSetup/projectRunner.d.ts +46 -0
- package/dist/bin/forgebook/agentSetup/projectRunner.js +85 -0
- package/dist/bin/forgebook/agentSetup/stopHook.d.ts +65 -0
- package/dist/bin/forgebook/agentSetup/stopHook.js +202 -0
- package/dist/bin/forgebook/agentSetup/uniformPicture.d.ts +7 -0
- package/dist/bin/forgebook/agentSetup/uniformPicture.js +98 -0
- package/dist/bin/forgebook/agentSetupCommands.d.mts +14 -0
- package/dist/bin/forgebook/agentSetupCommands.mjs +98 -0
- package/dist/bin/forgebook/agentText.d.ts +23 -3
- package/dist/bin/forgebook/agentText.js +175 -28
- package/dist/bin/forgebook/agents.md +20 -191
- package/dist/bin/forgebook/agentsText.js +2 -1
- package/dist/bin/forgebook/appBuild/appBuild.d.ts +59 -0
- package/dist/bin/forgebook/appBuild/appBuild.js +213 -0
- package/dist/bin/forgebook/appBuild/appViteConfig.d.ts +96 -0
- package/dist/bin/forgebook/appBuild/appViteConfig.js +320 -0
- package/dist/bin/forgebook/appBuild/tsconfigPaths.d.ts +14 -0
- package/dist/bin/forgebook/appBuild/tsconfigPaths.js +80 -0
- package/dist/bin/forgebook/auditCommand.d.mts +8 -0
- package/dist/bin/forgebook/auditCommand.mjs +75 -0
- package/dist/bin/forgebook/auditRun.d.ts +95 -0
- package/dist/bin/forgebook/auditRun.js +270 -0
- package/dist/bin/forgebook/browserRun.d.ts +21 -0
- package/dist/bin/forgebook/browserRun.js +57 -0
- package/dist/bin/forgebook/buildFailure.d.ts +7 -0
- package/dist/bin/forgebook/buildFailure.js +47 -0
- package/dist/bin/forgebook/buildWatch.d.ts +52 -0
- package/dist/bin/forgebook/buildWatch.js +137 -0
- package/dist/bin/forgebook/builtCatalogue.js +9 -5
- package/dist/bin/forgebook/catalogueCommands.d.ts +9 -0
- package/dist/bin/forgebook/catalogueCommands.js +23 -0
- package/dist/bin/forgebook/catalogueVite.d.ts +5 -1
- package/dist/bin/forgebook/catalogueVite.js +14 -6
- package/dist/bin/forgebook/commandCacheClaim.d.ts +18 -0
- package/dist/bin/forgebook/commandCacheClaim.js +170 -0
- package/dist/bin/forgebook/commandServer.d.ts +8 -0
- package/dist/bin/forgebook/commandServer.js +61 -13
- package/dist/bin/forgebook/forgebookCommands.mjs +105 -28
- package/dist/bin/forgebook/graphCommand.d.mts +8 -0
- package/dist/bin/forgebook/graphCommand.mjs +84 -0
- package/dist/bin/forgebook/guide/commands.md +57 -0
- package/dist/bin/forgebook/guide/devices.md +17 -0
- package/dist/bin/forgebook/guide/docs-pages.md +13 -0
- package/dist/bin/forgebook/guide/frameworks/angular.md +22 -0
- package/dist/bin/forgebook/guide/frameworks/html.md +22 -0
- package/dist/bin/forgebook/guide/frameworks/nextjs.md +23 -0
- package/dist/bin/forgebook/guide/frameworks/nuxt.md +22 -0
- package/dist/bin/forgebook/guide/frameworks/preact.md +16 -0
- package/dist/bin/forgebook/guide/frameworks/react-native-web.md +21 -0
- package/dist/bin/forgebook/guide/frameworks/react.md +16 -0
- package/dist/bin/forgebook/guide/frameworks/solid.md +18 -0
- package/dist/bin/forgebook/guide/frameworks/svelte.md +18 -0
- package/dist/bin/forgebook/guide/frameworks/sveltekit.md +23 -0
- package/dist/bin/forgebook/guide/frameworks/vue.md +18 -0
- package/dist/bin/forgebook/guide/frameworks/web-components.md +21 -0
- package/dist/bin/forgebook/guide/links.md +29 -0
- package/dist/bin/forgebook/guide/setup.md +23 -0
- package/dist/bin/forgebook/guide/stories.md +90 -0
- package/dist/bin/forgebook/guide/switches.md +43 -0
- package/dist/bin/forgebook/guideCommand.d.mts +13 -0
- package/dist/bin/forgebook/guideCommand.mjs +37 -0
- package/dist/bin/forgebook/importers/storybook.d.ts +21 -0
- package/dist/bin/forgebook/importers/storybook.js +11 -5
- package/dist/bin/forgebook/importers/storybookFrameworks.js +1 -1
- package/dist/bin/forgebook/initCommands.d.mts +11 -0
- package/dist/bin/forgebook/initCommands.mjs +51 -78
- package/dist/bin/forgebook/initConfig.d.ts +5 -3
- package/dist/bin/forgebook/initConfig.js +6 -3
- package/dist/bin/forgebook/initInstall.d.ts +15 -0
- package/dist/bin/forgebook/initInstall.js +77 -0
- package/dist/bin/forgebook/initPrint.d.ts +9 -0
- package/dist/bin/forgebook/initPrint.js +60 -0
- package/dist/bin/forgebook/initRefusals.d.ts +45 -0
- package/dist/bin/forgebook/initRefusals.js +91 -0
- package/dist/bin/forgebook/initRun.d.ts +28 -0
- package/dist/bin/forgebook/initRun.js +311 -0
- package/dist/bin/forgebook/mcpCommand.mjs +38 -4
- package/dist/bin/forgebook/mcpGraph.d.ts +13 -0
- package/dist/bin/forgebook/mcpGraph.js +24 -0
- package/dist/bin/forgebook/mcpTokens.d.ts +14 -0
- package/dist/bin/forgebook/mcpTokens.js +58 -0
- package/dist/bin/forgebook/mcpToolParts.d.ts +7 -0
- package/dist/bin/forgebook/mcpToolParts.js +10 -0
- package/dist/bin/forgebook/mcpTools.d.ts +13 -6
- package/dist/bin/forgebook/mcpTools.js +57 -90
- package/dist/bin/forgebook/mcpVerify.d.ts +16 -0
- package/dist/bin/forgebook/mcpVerify.js +36 -0
- package/dist/bin/forgebook/migrate/codemods.d.ts +11 -0
- package/dist/bin/forgebook/migrate/codemods.js +61 -0
- package/dist/bin/forgebook/migrate/migrate.types.d.ts +117 -0
- package/dist/bin/forgebook/migrate/migrate.types.js +5 -0
- package/dist/bin/forgebook/migrate/migrateCommand.d.mts +8 -0
- package/dist/bin/forgebook/migrate/migrateCommand.mjs +76 -0
- package/dist/bin/forgebook/migrate/migrateRun.d.ts +61 -0
- package/dist/bin/forgebook/migrate/migrateRun.js +210 -0
- package/dist/bin/forgebook/migrate/migrateText.d.ts +12 -0
- package/dist/bin/forgebook/migrate/migrateText.js +30 -0
- package/dist/bin/forgebook/migrate/migrateWrite.d.ts +27 -0
- package/dist/bin/forgebook/migrate/migrateWrite.js +66 -0
- package/dist/bin/forgebook/migrate/objectEdits.d.ts +70 -0
- package/dist/bin/forgebook/migrate/objectEdits.js +241 -0
- package/dist/bin/forgebook/migrate/playOnInBuilds.d.ts +3 -0
- package/dist/bin/forgebook/migrate/playOnInBuilds.js +86 -0
- package/dist/bin/forgebook/migrate/propGroupStrings.d.ts +5 -0
- package/dist/bin/forgebook/migrate/propGroupStrings.js +81 -0
- package/dist/bin/forgebook/newProject/newProject.d.ts +39 -0
- package/dist/bin/forgebook/newProject/newProject.js +180 -0
- package/dist/bin/forgebook/newProject/newProject.types.d.ts +97 -0
- package/dist/bin/forgebook/newProject/newProject.types.js +6 -0
- package/dist/bin/forgebook/newProject/packageManagers.d.ts +51 -0
- package/dist/bin/forgebook/newProject/packageManagers.js +121 -0
- package/dist/bin/forgebook/newProject/projectEntries.d.ts +62 -0
- package/dist/bin/forgebook/newProject/projectEntries.js +191 -0
- package/dist/bin/forgebook/newProject/projectFrameworks.d.ts +57 -0
- package/dist/bin/forgebook/newProject/projectFrameworks.js +148 -0
- package/dist/bin/forgebook/newProject/projectLook.d.ts +23 -0
- package/dist/bin/forgebook/newProject/projectLook.js +293 -0
- package/dist/bin/forgebook/newProject/projectPackages.d.ts +66 -0
- package/dist/bin/forgebook/newProject/projectPackages.js +178 -0
- package/dist/bin/forgebook/newRepair.d.ts +45 -0
- package/dist/bin/forgebook/newRepair.js +157 -0
- package/dist/bin/forgebook/newRepairRun.d.ts +69 -0
- package/dist/bin/forgebook/newRepairRun.js +148 -0
- package/dist/bin/forgebook/newStories.d.ts +23 -1
- package/dist/bin/forgebook/newStories.js +101 -11
- package/dist/bin/forgebook/newStoriesFile.d.ts +20 -1
- package/dist/bin/forgebook/newStoriesFile.js +43 -4
- package/dist/bin/forgebook/prebundleRun.d.ts +3 -1
- package/dist/bin/forgebook/prebundleRun.js +28 -8
- package/dist/bin/forgebook/proofCommand.d.mts +15 -0
- package/dist/bin/forgebook/proofCommand.mjs +212 -0
- package/dist/bin/forgebook/proofRun.d.ts +63 -0
- package/dist/bin/forgebook/proofRun.js +412 -0
- package/dist/bin/forgebook/proofText.d.ts +36 -0
- package/dist/bin/forgebook/proofText.js +131 -0
- package/dist/bin/forgebook/proofWorkflow.d.ts +29 -0
- package/dist/bin/forgebook/proofWorkflow.js +205 -0
- package/dist/bin/forgebook/setArgsTool.d.ts +8 -0
- package/dist/bin/forgebook/setArgsTool.js +70 -0
- package/dist/bin/forgebook/storyCheckCommands.mjs +42 -3
- package/dist/bin/forgebook/storyCheckRun.d.ts +50 -0
- package/dist/bin/forgebook/storyCheckRun.js +83 -9
- package/dist/bin/forgebook/storyFileIds.d.ts +15 -0
- package/dist/bin/forgebook/storyFileIds.js +14 -0
- package/dist/bin/forgebook/stressCases.d.ts +31 -0
- package/dist/bin/forgebook/stressCases.js +79 -0
- package/dist/bin/forgebook/stressRun.d.ts +12 -0
- package/dist/bin/forgebook/stressRun.js +61 -0
- package/dist/bin/forgebook/stressText.d.ts +27 -0
- package/dist/bin/forgebook/stressText.js +46 -0
- package/dist/bin/forgebook/verifyBase.d.ts +45 -0
- package/dist/bin/forgebook/verifyBase.js +196 -0
- package/dist/bin/forgebook/verifyCommand.d.mts +13 -0
- package/dist/bin/forgebook/verifyCommand.mjs +125 -0
- package/dist/bin/forgebook/verifyRun.d.ts +63 -0
- package/dist/bin/forgebook/verifyRun.js +108 -0
- package/dist/bin/forgebook/verifyVerdict.d.ts +40 -0
- package/dist/bin/forgebook/verifyVerdict.js +297 -0
- package/dist/bin/forgebook/workflowActions.d.ts +23 -0
- package/dist/bin/forgebook/workflowActions.js +23 -0
- package/dist/bin/forgebook-docs/catalogueMarkdown.js +12 -1
- package/dist/src/addressArgs.d.ts +29 -5
- package/dist/src/addressArgs.js +58 -16
- package/dist/src/addressArgsParam.d.ts +54 -0
- package/dist/src/addressArgsParam.js +51 -0
- package/dist/src/addressTexts.d.ts +14 -0
- package/dist/src/addressTexts.js +28 -21
- package/dist/src/agentIndexFile.d.ts +11 -0
- package/dist/src/agentIndexFile.js +11 -0
- package/dist/src/argConditions.d.ts +52 -0
- package/dist/src/argConditions.js +80 -0
- package/dist/src/argControl.d.ts +100 -0
- package/dist/src/argControl.js +0 -0
- package/dist/src/argExpression.d.ts +21 -0
- package/dist/src/argExpression.js +30 -0
- package/dist/src/argTypes.d.ts +40 -51
- package/dist/src/argTypes.js +66 -184
- package/dist/src/argsProps.d.ts +3 -3
- package/dist/src/argsProps.js +11 -5
- package/dist/src/bundlerErrors.d.ts +29 -0
- package/dist/src/bundlerErrors.js +49 -0
- package/dist/src/catalogue.d.ts +31 -0
- package/dist/src/catalogue.js +13 -2
- package/dist/src/catalogueRefs.d.ts +75 -0
- package/dist/src/catalogueRefs.js +122 -0
- package/dist/src/componentDocs.d.ts +71 -0
- package/dist/src/componentDocs.js +15 -2
- package/dist/src/frame/callValues.d.ts +19 -0
- package/dist/src/frame/callValues.js +58 -0
- package/dist/src/frame/canvasScheme.d.ts +33 -0
- package/dist/src/frame/canvasScheme.js +67 -0
- package/dist/src/frame/frame.css +36 -3
- package/dist/src/frame/frameStatus.d.ts +16 -1
- package/dist/src/frame/frameStatus.js +16 -1
- package/dist/src/frame/frameView.js +4 -3
- package/dist/src/frame/mountFrame.d.ts +7 -1
- package/dist/src/frame/mountFrame.js +153 -46
- package/dist/src/frame/panelValues.d.ts +35 -0
- package/dist/src/frame/panelValues.js +127 -0
- package/dist/src/frame/playActions.d.ts +39 -0
- package/dist/src/frame/playActions.js +98 -0
- package/dist/src/frame/playStepper.d.ts +28 -0
- package/dist/src/frame/playStepper.js +38 -0
- package/dist/src/frame/playStory.d.ts +9 -1
- package/dist/src/frame/playStory.js +49 -3
- package/dist/src/frame/renderer.d.ts +34 -1
- package/dist/src/frame/renderer.js +24 -0
- package/dist/src/frame/shellChannel.d.ts +1 -1
- package/dist/src/frame/shellChannel.js +1 -1
- package/dist/src/frame/shellCheck.d.ts +17 -0
- package/dist/src/frame/shellCheck.js +25 -0
- package/dist/src/frame/shellMessageCheck.d.ts +7 -0
- package/dist/src/frame/shellMessageCheck.js +53 -0
- package/dist/src/frame/storyContent.d.ts +50 -0
- package/dist/src/frame/storyContent.js +73 -0
- package/dist/src/frame/storyModule.d.ts +9 -0
- package/dist/src/frame/storyModule.js +20 -2
- package/dist/src/frame/storyRun.d.ts +15 -7
- package/dist/src/frame/storyRun.js +64 -15
- package/dist/src/frame/valueSheets.d.ts +35 -0
- package/dist/src/frame/valueSheets.js +99 -0
- package/dist/src/hotModules.d.ts +20 -0
- package/dist/src/hotModules.js +23 -0
- package/dist/src/jsxCode.d.ts +1 -14
- package/dist/src/jsxCode.js +46 -10
- package/dist/src/liveErrors.d.ts +30 -4
- package/dist/src/liveErrors.js +18 -3
- package/dist/src/messages.d.ts +77 -27
- package/dist/src/messages.js +58 -100
- package/dist/src/namedValues.d.ts +2 -26
- package/dist/src/namedValues.js +0 -47
- package/dist/src/pageConfig.d.ts +2 -0
- package/dist/src/playTrace.d.ts +19 -2
- package/dist/src/playTrace.js +10 -5
- package/dist/src/plugin.d.ts +10 -3
- package/dist/src/previewRelay.js +9 -1
- package/dist/src/printable.d.ts +12 -0
- package/dist/src/printable.js +22 -0
- package/dist/src/propsSignature.d.ts +37 -0
- package/dist/src/propsSignature.js +40 -0
- package/dist/src/search.d.ts +41 -5
- package/dist/src/search.js +93 -23
- package/dist/src/searchMatch.d.ts +4 -1
- package/dist/src/searchMatch.js +26 -5
- package/dist/src/searchTypos.d.ts +88 -0
- package/dist/src/searchTypos.js +178 -0
- package/dist/src/shapeValues.d.ts +86 -0
- package/dist/src/shapeValues.js +295 -0
- package/dist/src/shell/ApiReference.js +6 -3
- package/dist/src/shell/ApiTableBox.d.ts +15 -0
- package/dist/src/shell/ApiTableBox.js +11 -0
- package/dist/src/shell/AppearanceMenu.d.ts +4 -1
- package/dist/src/shell/AppearanceMenu.js +9 -6
- package/dist/src/shell/CodeTab.d.ts +3 -2
- package/dist/src/shell/CodeTab.js +3 -2
- package/dist/src/shell/CodeText.d.ts +1 -1
- package/dist/src/shell/CodeText.js +2 -3
- package/dist/src/shell/CompareGrid.js +1 -1
- package/dist/src/shell/ComponentPage.d.ts +1 -1
- package/dist/src/shell/ComponentPage.js +5 -1
- package/dist/src/shell/CustomControl.d.ts +34 -0
- package/dist/src/shell/CustomControl.js +132 -0
- package/dist/src/shell/DocContainers.js +1 -1
- package/dist/src/shell/DocPage.js +2 -2
- package/dist/src/shell/DroppedArgsList.d.ts +2 -2
- package/dist/src/shell/DroppedArgsList.js +1 -1
- package/dist/src/shell/EmbedPage.js +30 -12
- package/dist/src/shell/Example.d.ts +5 -1
- package/dist/src/shell/Example.js +16 -8
- package/dist/src/shell/FrameView.d.ts +6 -3
- package/dist/src/shell/FrameView.js +2 -2
- package/dist/src/shell/HomePage.d.ts +3 -1
- package/dist/src/shell/HomePage.js +16 -6
- package/dist/src/shell/InfoTip.js +2 -2
- package/dist/src/shell/InteractionsTab.d.ts +11 -4
- package/dist/src/shell/InteractionsTab.js +18 -2
- package/dist/src/shell/LazyPage.js +1 -1
- package/dist/src/shell/PackageHtml.js +3 -1
- package/dist/src/shell/PinnedControl.js +14 -62
- package/dist/src/shell/PinnedControlMenu.d.ts +44 -0
- package/dist/src/shell/PinnedControlMenu.js +72 -0
- package/dist/src/shell/PropFields.d.ts +3 -1
- package/dist/src/shell/PropFields.js +9 -6
- package/dist/src/shell/PropRows.d.ts +23 -2
- package/dist/src/shell/PropRows.js +58 -19
- package/dist/src/shell/PropsTab.d.ts +12 -5
- package/dist/src/shell/PropsTab.js +9 -21
- package/dist/src/shell/RefStoryPage.d.ts +33 -0
- package/dist/src/shell/RefStoryPage.js +123 -0
- package/dist/src/shell/SearchPanel.js +51 -24
- package/dist/src/shell/Shell.d.ts +18 -0
- package/dist/src/shell/Shell.js +137 -22
- package/dist/src/shell/ShortcutHelp.d.ts +22 -0
- package/dist/src/shell/ShortcutHelp.js +66 -0
- package/dist/src/shell/Sidebar.d.ts +17 -4
- package/dist/src/shell/Sidebar.js +92 -41
- package/dist/src/shell/SidebarDocs.js +2 -2
- package/dist/src/shell/SidebarEntries.js +5 -3
- package/dist/src/shell/SidebarHandle.d.ts +3 -5
- package/dist/src/shell/SidebarHandle.js +4 -4
- package/dist/src/shell/SidebarRefs.d.ts +39 -0
- package/dist/src/shell/SidebarRefs.js +99 -0
- package/dist/src/shell/SidebarSearch.js +37 -9
- package/dist/src/shell/SignatureReference.js +3 -1
- package/dist/src/shell/Stage.d.ts +10 -2
- package/dist/src/shell/Stage.js +29 -49
- package/dist/src/shell/StatusBadges.d.ts +54 -0
- package/dist/src/shell/StatusBadges.js +77 -0
- package/dist/src/shell/StoryCodeBlock.d.ts +8 -19
- package/dist/src/shell/StoryCodeBlock.js +7 -6
- package/dist/src/shell/SwitchGallery.d.ts +36 -0
- package/dist/src/shell/SwitchGallery.js +17 -0
- package/dist/src/shell/SwitchGalleryPanel.d.ts +37 -0
- package/dist/src/shell/SwitchGalleryPanel.js +99 -0
- package/dist/src/shell/TagFilter.d.ts +24 -0
- package/dist/src/shell/TagFilter.js +45 -0
- package/dist/src/shell/TagViews.d.ts +39 -0
- package/dist/src/shell/TagViews.js +20 -0
- package/dist/src/shell/Toolbar.d.ts +4 -1
- package/dist/src/shell/Toolbar.js +17 -7
- package/dist/src/shell/ToolbarControl.d.ts +3 -0
- package/dist/src/shell/ToolbarControl.js +23 -6
- package/dist/src/shell/ViewMenuPanel.js +6 -1
- package/dist/src/shell/argChecks.d.ts +22 -0
- package/dist/src/shell/argChecks.js +20 -0
- package/dist/src/shell/asideStory.js +7 -2
- package/dist/src/shell/audienceSections.css +9 -9
- package/dist/src/shell/catalogueContext.d.ts +1 -1
- package/dist/src/shell/catalogueContext.js +6 -1
- package/dist/src/shell/codeSpans.d.ts +27 -0
- package/dist/src/shell/codeSpans.js +76 -0
- package/dist/src/shell/compareVariants.d.ts +4 -2
- package/dist/src/shell/compareVariants.js +16 -8
- package/dist/src/shell/composition.d.ts +23 -0
- package/dist/src/shell/composition.js +26 -0
- package/dist/src/shell/controlCycle.d.ts +1 -1
- package/dist/src/shell/controlCycle.js +3 -2
- package/dist/src/shell/customControls.d.ts +55 -0
- package/dist/src/shell/customControls.js +70 -0
- package/dist/src/shell/docPage.css +22 -22
- package/dist/src/shell/dockTabs.d.ts +19 -3
- package/dist/src/shell/dockTabs.js +28 -20
- package/dist/src/shell/embed.css +7 -7
- package/dist/src/shell/framesOrigin.d.ts +7 -0
- package/dist/src/shell/framesOrigin.js +1 -1
- package/dist/src/shell/galleryPlace.d.ts +20 -0
- package/dist/src/shell/galleryPlace.js +26 -0
- package/dist/src/shell/icons.d.ts +1 -0
- package/dist/src/shell/icons.js +1 -0
- package/dist/src/shell/keyboard.d.ts +14 -12
- package/dist/src/shell/keyboard.js +21 -6
- package/dist/src/shell/laterStrings.d.ts +29 -0
- package/dist/src/shell/laterStrings.js +42 -3
- package/dist/src/shell/mountShell.js +3 -0
- package/dist/src/shell/pageStrings.d.ts +4 -0
- package/dist/src/shell/pageStrings.js +4 -0
- package/dist/src/shell/pageTagView.d.ts +18 -0
- package/dist/src/shell/pageTagView.js +10 -0
- package/dist/src/shell/playMemory.d.ts +14 -0
- package/dist/src/shell/playMemory.js +8 -0
- package/dist/src/shell/propNotes.d.ts +23 -0
- package/dist/src/shell/propNotes.js +37 -0
- package/dist/src/shell/refIndexLoad.d.ts +17 -0
- package/dist/src/shell/refIndexLoad.js +38 -0
- package/dist/src/shell/refParts.d.ts +34 -0
- package/dist/src/shell/refParts.js +9 -0
- package/dist/src/shell/refStory.css +21 -0
- package/dist/src/shell/refStrings.d.ts +13 -0
- package/dist/src/shell/refStrings.js +21 -0
- package/dist/src/shell/search.css +11 -11
- package/dist/src/shell/shell.css +348 -168
- package/dist/src/shell/shellScheme.js +2 -2
- package/dist/src/shell/shortcutHelp.css +64 -0
- package/dist/src/shell/stageArgs.d.ts +53 -0
- package/dist/src/shell/stageArgs.js +64 -0
- package/dist/src/shell/statusBadges.css +51 -0
- package/dist/src/shell/strings.d.ts +7 -16
- package/dist/src/shell/strings.js +12 -17
- package/dist/src/shell/switchGallery.css +104 -0
- package/dist/src/shell/tagFilter.css +46 -0
- package/dist/src/shell/tagView.d.ts +20 -0
- package/dist/src/shell/tagView.js +10 -0
- package/dist/src/shell/useAddressArgs.d.ts +9 -0
- package/dist/src/shell/useAddressArgs.js +56 -11
- package/dist/src/shell/useControlKeys.js +2 -2
- package/dist/src/shell/useEditedProblems.d.ts +6 -0
- package/dist/src/shell/useEditedProblems.js +40 -0
- package/dist/src/shell/useFrameMessages.js +3 -0
- package/dist/src/shell/useListedTree.d.ts +13 -0
- package/dist/src/shell/useListedTree.js +32 -0
- package/dist/src/shell/usePageFrames.js +2 -2
- package/dist/src/shell/usePopover.d.ts +5 -0
- package/dist/src/shell/usePopover.js +7 -1
- package/dist/src/shell/useRefIndex.d.ts +22 -0
- package/dist/src/shell/useRefIndex.js +36 -0
- package/dist/src/shell/useScrollStops.d.ts +20 -0
- package/dist/src/shell/useScrollStops.js +41 -0
- package/dist/src/shell/useShortcutHelp.d.ts +18 -0
- package/dist/src/shell/useShortcutHelp.js +32 -0
- package/dist/src/shell/useSidebarOverlay.d.ts +2 -1
- package/dist/src/shell/useSidebarOverlay.js +12 -4
- package/dist/src/shell/useStoryCode.d.ts +2 -1
- package/dist/src/shell/useStoryCode.js +12 -7
- package/dist/src/shell/useToolbarLayout.d.ts +5 -1
- package/dist/src/shell/useToolbarLayout.js +2 -2
- package/dist/src/shell/useWorstCase.d.ts +8 -2
- package/dist/src/shell/useWorstCase.js +2 -2
- package/dist/src/shell/valueEditors/FileEditor.d.ts +28 -0
- package/dist/src/shell/valueEditors/FileEditor.js +66 -0
- package/dist/src/shell/valueEditors/JsonEditor.d.ts +14 -0
- package/dist/src/shell/valueEditors/JsonEditor.js +53 -0
- package/dist/src/shell/valueEditors/ListEditor.d.ts +24 -0
- package/dist/src/shell/valueEditors/ListEditor.js +82 -0
- package/dist/src/shell/valueEditors/ObjectEditor.d.ts +32 -0
- package/dist/src/shell/valueEditors/ObjectEditor.js +70 -0
- package/dist/src/shell/valueEditors/PropEditor.d.ts +37 -0
- package/dist/src/shell/valueEditors/PropEditor.js +53 -0
- package/dist/src/shell/valueEditors/RecordEditor.d.ts +20 -0
- package/dist/src/shell/valueEditors/RecordEditor.js +84 -0
- package/dist/src/shell/valueEditors/SearchSelect.d.ts +42 -0
- package/dist/src/shell/valueEditors/SearchSelect.js +80 -0
- package/dist/src/shell/valueEditors/TokenEditor.d.ts +49 -0
- package/dist/src/shell/valueEditors/TokenEditor.js +74 -0
- package/dist/src/shell/valueEditors/UnionEditor.d.ts +20 -0
- package/dist/src/shell/valueEditors/UnionEditor.js +64 -0
- package/dist/src/shell/valueEditors/ValueField.d.ts +15 -0
- package/dist/src/shell/valueEditors/ValueField.js +147 -0
- package/dist/src/shell/valueEditors/editorStrings.d.ts +56 -0
- package/dist/src/shell/valueEditors/editorStrings.js +66 -0
- package/dist/src/shell/valueEditors/fieldTypes.d.ts +31 -0
- package/dist/src/shell/valueEditors/fieldTypes.js +0 -0
- package/dist/src/shell/valueEditors/valueEditors.css +153 -0
- package/dist/src/shell/worstArgs.d.ts +8 -5
- package/dist/src/shell/worstArgs.js +14 -7
- package/dist/src/shellTheme.d.ts +1 -1
- package/dist/src/shellTheme.js +15 -1
- package/dist/src/shellTheme.types.d.ts +4 -0
- package/dist/src/shellWord.d.ts +12 -0
- package/dist/src/shellWord.js +15 -0
- package/dist/src/sourceFiles.js +2 -1
- package/dist/src/storyArgTypes.d.ts +57 -0
- package/dist/src/storyArgTypes.js +195 -0
- package/dist/src/storyBackground.js +14 -3
- package/dist/src/storyCheck.d.ts +85 -3
- package/dist/src/storyCheck.js +23 -1
- package/dist/src/storyCodeText.d.ts +46 -0
- package/dist/src/storyCodeText.js +27 -0
- package/dist/src/storyControls.d.ts +100 -0
- package/dist/src/storyControls.js +100 -0
- package/dist/src/storyStatuses.d.ts +55 -0
- package/dist/src/storyStatuses.js +104 -0
- package/dist/src/storyTagNames.d.ts +25 -0
- package/dist/src/storyTagNames.js +25 -0
- package/dist/src/storyTags.d.ts +29 -0
- package/dist/src/storyTags.js +85 -0
- package/dist/src/storyTree.d.ts +13 -0
- package/dist/src/storyTree.js +24 -4
- package/dist/src/storybookArgs.d.ts +24 -0
- package/dist/src/storybookArgs.js +185 -0
- package/dist/src/switches.d.ts +66 -3
- package/dist/src/switches.js +42 -1
- package/dist/src/valueSchema.d.ts +28 -0
- package/dist/src/valueSchema.js +196 -0
- package/dist/src/valueShape.d.ts +94 -0
- package/dist/src/valueShape.js +25 -0
- package/dist/src/viewState.d.ts +8 -3
- package/dist/src/viewState.js +27 -10
- package/dist/src/vite/adapter.d.ts +40 -2
- package/dist/src/vite/adapter.js +1 -0
- package/dist/src/vite/agent.types.d.ts +347 -7
- package/dist/src/vite/agentApi.d.ts +23 -0
- package/dist/src/vite/agentApi.js +90 -17
- package/dist/src/vite/agentIndex.d.ts +0 -2
- package/dist/src/vite/agentIndex.js +5 -6
- package/dist/src/vite/agentRoutes.d.ts +20 -1
- package/dist/src/vite/agentRoutes.js +106 -65
- package/dist/src/vite/agentStatuses.d.ts +42 -0
- package/dist/src/vite/agentStatuses.js +67 -0
- package/dist/src/vite/agentStoryCode.d.ts +48 -0
- package/dist/src/vite/agentStoryCode.js +38 -0
- package/dist/src/vite/agentVisibility.d.ts +47 -0
- package/dist/src/vite/agentVisibility.js +174 -0
- package/dist/src/vite/appAudit.d.ts +134 -0
- package/dist/src/vite/appAudit.js +333 -0
- package/dist/src/vite/appBuildOption.d.ts +53 -0
- package/dist/src/vite/appBuildOption.js +55 -0
- package/dist/src/vite/appTokenFiles.d.ts +92 -0
- package/dist/src/vite/appTokenFiles.js +433 -0
- package/dist/src/vite/appTokens.d.ts +23 -0
- package/dist/src/vite/appTokens.js +275 -0
- package/dist/src/vite/builtTexts.d.ts +10 -0
- package/dist/src/vite/builtTexts.js +59 -22
- package/dist/src/vite/catalogueConfig.d.ts +3 -1
- package/dist/src/vite/catalogueConfig.js +15 -3
- package/dist/src/vite/changeCoverage.d.ts +74 -0
- package/dist/src/vite/changeCoverage.js +120 -0
- package/dist/src/vite/changedRoute.d.ts +30 -0
- package/dist/src/vite/changedRoute.js +197 -0
- package/dist/src/vite/checkCode.d.ts +105 -3
- package/dist/src/vite/checkCode.js +323 -36
- package/dist/src/vite/checkoutWatch.d.ts +97 -0
- package/dist/src/vite/checkoutWatch.js +287 -0
- package/dist/src/vite/closeWatch.d.ts +8 -0
- package/dist/src/vite/closeWatch.js +1 -1
- package/dist/src/vite/componentCache.d.ts +8 -0
- package/dist/src/vite/componentCache.js +66 -0
- package/dist/src/vite/componentGraph.d.ts +71 -0
- package/dist/src/vite/componentGraph.js +133 -0
- package/dist/src/vite/componentRules.d.ts +33 -0
- package/dist/src/vite/componentRules.js +105 -0
- package/dist/src/vite/componentScan.d.ts +69 -0
- package/dist/src/vite/componentScan.js +418 -0
- package/dist/src/vite/compositionCheck.d.ts +15 -0
- package/dist/src/vite/compositionCheck.js +243 -0
- package/dist/src/vite/config.d.ts +32 -1
- package/dist/src/vite/configFile.d.ts +14 -2
- package/dist/src/vite/configFile.js +124 -40
- package/dist/src/vite/configKeys.d.ts +15 -0
- package/dist/src/vite/configKeys.js +171 -0
- package/dist/src/vite/configLoadError.d.ts +23 -0
- package/dist/src/vite/configLoadError.js +71 -0
- package/dist/src/vite/cssDeclarations.d.ts +71 -0
- package/dist/src/vite/cssDeclarations.js +290 -0
- package/dist/src/vite/cssImports.d.ts +14 -0
- package/dist/src/vite/cssImports.js +48 -0
- package/dist/src/vite/cssReferences.d.ts +54 -0
- package/dist/src/vite/cssReferences.js +157 -0
- package/dist/src/vite/cssTokenValues.d.ts +50 -0
- package/dist/src/vite/cssTokenValues.js +233 -0
- package/dist/src/vite/designTokens.d.ts +24 -0
- package/dist/src/vite/designTokens.js +5 -1
- package/dist/src/vite/docsExtractor.d.ts +9 -3
- package/dist/src/vite/docsExtractor.js +11 -3
- package/dist/src/vite/docsProgram.d.ts +17 -4
- package/dist/src/vite/docsProgram.js +52 -11
- package/dist/src/vite/docsWorker.js +7 -2
- package/dist/src/vite/emptyStoryGlobs.d.ts +41 -0
- package/dist/src/vite/emptyStoryGlobs.js +52 -0
- package/dist/src/vite/fileImports.d.ts +17 -0
- package/dist/src/vite/fileImports.js +57 -0
- package/dist/src/vite/findComponent.d.ts +10 -2
- package/dist/src/vite/findComponent.js +27 -22
- package/dist/src/vite/findRoute.js +3 -2
- package/dist/src/vite/forcedStates.d.ts +9 -2
- package/dist/src/vite/forcedStates.js +12 -3
- package/dist/src/vite/forgebookPlugin.d.ts +2 -0
- package/dist/src/vite/forgebookPlugin.js +52 -72
- package/dist/src/vite/frameErrors.d.ts +19 -0
- package/dist/src/vite/frameErrors.js +70 -0
- package/dist/src/vite/framesServer.d.ts +12 -0
- package/dist/src/vite/framesServer.js +21 -4
- package/dist/src/vite/functionComponentDocs.js +81 -12
- package/dist/src/vite/generatedModules.js +4 -2
- package/dist/src/vite/gitChange.d.ts +38 -5
- package/dist/src/vite/gitChange.js +71 -11
- package/dist/src/vite/hiddenStoryFiles.d.ts +23 -0
- package/dist/src/vite/hiddenStoryFiles.js +107 -0
- package/dist/src/vite/hotSnippets.d.ts +38 -14
- package/dist/src/vite/hotSnippets.js +137 -39
- package/dist/src/vite/importedNames.d.ts +37 -0
- package/dist/src/vite/importedNames.js +138 -0
- package/dist/src/vite/indexFields.d.ts +6 -0
- package/dist/src/vite/indexFields.js +21 -0
- package/dist/src/vite/indexStoryFile.d.ts +8 -1
- package/dist/src/vite/indexStoryFile.js +22 -157
- package/dist/src/vite/jsxCallSites.d.ts +33 -0
- package/dist/src/vite/jsxCallSites.js +200 -0
- package/dist/src/vite/jsxInScripts.d.ts +67 -0
- package/dist/src/vite/jsxInScripts.js +138 -0
- package/dist/src/vite/jsxTree.d.ts +20 -0
- package/dist/src/vite/jsxTree.js +163 -0
- package/dist/src/vite/lineAndColumn.d.ts +13 -0
- package/dist/src/vite/lineAndColumn.js +18 -0
- package/dist/src/vite/lookAlikes.d.ts +65 -0
- package/dist/src/vite/lookAlikes.js +228 -0
- package/dist/src/vite/nearestToken.d.ts +17 -0
- package/dist/src/vite/nearestToken.js +9 -2
- package/dist/src/vite/packageEntries.d.ts +42 -0
- package/dist/src/vite/packageEntries.js +127 -0
- package/dist/src/vite/pages.d.ts +9 -1
- package/dist/src/vite/pages.js +108 -4
- package/dist/src/vite/pluginConfig.js +4 -0
- package/dist/src/vite/pluginIds.d.ts +2 -0
- package/dist/src/vite/pluginIds.js +5 -1
- package/dist/src/vite/pluginModules.d.ts +81 -11
- package/dist/src/vite/pluginModules.js +109 -21
- package/dist/src/vite/prebundled.d.ts +57 -15
- package/dist/src/vite/prebundled.js +80 -0
- package/dist/src/vite/previewTags.d.ts +25 -0
- package/dist/src/vite/previewTags.js +56 -0
- package/dist/src/vite/projectFiles.d.ts +54 -0
- package/dist/src/vite/projectFiles.js +116 -0
- package/dist/src/vite/projectPostcss.d.ts +70 -0
- package/dist/src/vite/projectPostcss.js +250 -0
- package/dist/src/vite/propDocs.d.ts +12 -0
- package/dist/src/vite/propDocs.js +130 -58
- package/dist/src/vite/propKind.d.ts +40 -0
- package/dist/src/vite/propKind.js +71 -0
- package/dist/src/vite/propTypeNotes.d.ts +22 -0
- package/dist/src/vite/propTypeNotes.js +51 -0
- package/dist/src/vite/publishedExports.d.ts +27 -0
- package/dist/src/vite/publishedExports.js +298 -0
- package/dist/src/vite/realFolder.d.ts +6 -0
- package/dist/src/vite/realFolder.js +25 -0
- package/dist/src/vite/refsConfig.d.ts +39 -0
- package/dist/src/vite/refsConfig.js +54 -0
- package/dist/src/vite/reuseCheck.d.ts +45 -0
- package/dist/src/vite/reuseCheck.js +260 -0
- package/dist/src/vite/runningVersions.d.ts +33 -0
- package/dist/src/vite/runningVersions.js +25 -0
- package/dist/src/vite/scriptProblems.d.ts +60 -0
- package/dist/src/vite/scriptProblems.js +155 -0
- package/dist/src/vite/searchModule.js +3 -2
- package/dist/src/vite/searchRoute.js +4 -2
- package/dist/src/vite/shapeDocs.d.ts +36 -0
- package/dist/src/vite/shapeDocs.js +177 -0
- package/dist/src/vite/singleFileComponent.d.ts +17 -0
- package/dist/src/vite/singleFileComponent.js +83 -0
- package/dist/src/vite/sourceText.d.ts +34 -0
- package/dist/src/vite/sourceText.js +72 -0
- package/dist/src/vite/sourceTokens.d.ts +7 -0
- package/dist/src/vite/sourceTokens.js +7 -2
- package/dist/src/vite/stackLines.d.ts +49 -0
- package/dist/src/vite/stackLines.js +96 -0
- package/dist/src/vite/storyCode.d.ts +22 -7
- package/dist/src/vite/storyCode.js +263 -37
- package/dist/src/vite/storyCoverage.d.ts +48 -0
- package/dist/src/vite/storyCoverage.js +179 -0
- package/dist/src/vite/storyFilesModule.d.ts +48 -3
- package/dist/src/vite/storyFilesModule.js +105 -15
- package/dist/src/vite/storyPatterns.d.ts +31 -0
- package/dist/src/vite/storyPatterns.js +140 -5
- package/dist/src/vite/storyReach.d.ts +10 -2
- package/dist/src/vite/storyReach.js +15 -11
- package/dist/src/vite/storyTopLevel.d.ts +51 -0
- package/dist/src/vite/storyTopLevel.js +146 -0
- package/dist/src/vite/storylessRoutes.d.ts +4 -3
- package/dist/src/vite/storylessRoutes.js +210 -19
- package/dist/src/vite/switchValuesCheck.d.ts +19 -0
- package/dist/src/vite/switchValuesCheck.js +164 -0
- package/dist/src/vite/switchesDocument.d.ts +15 -0
- package/dist/src/vite/switchesDocument.js +47 -0
- package/dist/src/vite/tailwindConfigTokens.d.ts +41 -0
- package/dist/src/vite/tailwindConfigTokens.js +306 -0
- package/dist/src/vite/textImports.d.ts +15 -0
- package/dist/src/vite/textImports.js +58 -0
- package/dist/src/vite/textModules.d.ts +6 -5
- package/dist/src/vite/textModules.js +13 -8
- package/dist/src/vite/tokenAnswers.d.ts +6 -2
- package/dist/src/vite/tokenAnswers.js +11 -7
- package/dist/src/vite/typeParameters.d.ts +83 -0
- package/dist/src/vite/typeParameters.js +270 -0
- package/dist/src/vite/unionProps.d.ts +37 -0
- package/dist/src/vite/unionProps.js +121 -0
- package/dist/src/vite/unresolvedTokens.d.ts +20 -0
- package/dist/src/vite/unresolvedTokens.js +193 -0
- package/dist/src/vite/usageGraph.js +10 -52
- package/dist/src/vite/usageGuidance.d.ts +9 -2
- package/dist/src/vite/usageGuidance.js +36 -8
- package/dist/src/vite/usageImports.d.ts +35 -0
- package/dist/src/vite/usageImports.js +280 -0
- package/dist/src/vite/visibilityRoute.d.ts +16 -0
- package/dist/src/vite/visibilityRoute.js +320 -0
- package/dist/src/worstCase.d.ts +2 -0
- package/dist/src/worstCase.js +2 -0
- package/package.json +28 -8
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a design system says to choose among its components and how they fit together, in a few TSDoc tags or a file beside
|
|
3
|
+
* the component. Whoever keeps a design system should not have to learn a language for this.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Pure. Each tag is one line a person can read without knowing Forgebook:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* /**
|
|
10
|
+
* * Pick one of a few options, all in view.
|
|
11
|
+
* *
|
|
12
|
+
* * \@intent choose-one: up to five options, all visible
|
|
13
|
+
* * \@parent Form, Fieldset
|
|
14
|
+
* * \@children Radio
|
|
15
|
+
* * \@insteadOf select
|
|
16
|
+
* *\/
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Components sharing an intent are the choices for it, and each one's text says when it is the right one. A file beside the
|
|
20
|
+
* component (`RadioGroup.rules.json`) says the same for one that cannot carry a comment, keyed by the component's name:
|
|
21
|
+
* `{ "RadioGroup": { "intent": ["choose-one: up to five options"], "parent": ["Form"] } }`.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import { plainWords } from "./sourceText.js";
|
|
26
|
+
/** An intent's name: words a person chose, with dashes for its spaces. */
|
|
27
|
+
const INTENT_NAME = /^[\w-]{1,60}$/;
|
|
28
|
+
/** How much of an intent an answer repeats. */
|
|
29
|
+
const LONGEST_INTENT = 260;
|
|
30
|
+
/** How many names one rule holds. */
|
|
31
|
+
const MOST_NAMES = 12;
|
|
32
|
+
/** A component's or an element's name, and no more: these reach an agent as its next step. */
|
|
33
|
+
const NAME = /^[A-Za-z][\w.-]{0,80}$/;
|
|
34
|
+
/** A list of names, keeping only what is a name. */
|
|
35
|
+
const namesOf = (written) => written
|
|
36
|
+
.flatMap((each) => each.split(/,|\s+or\s+/))
|
|
37
|
+
.map((each) => each.replaceAll("`", "").trim())
|
|
38
|
+
.filter((each) => NAME.test(each))
|
|
39
|
+
.slice(0, MOST_NAMES);
|
|
40
|
+
/** The intents written, keeping only what reads as one. */
|
|
41
|
+
const intentsOf = (written) => written.flatMap((each) => {
|
|
42
|
+
const text = plainWords(each, LONGEST_INTENT).trim();
|
|
43
|
+
const colon = text.indexOf(":");
|
|
44
|
+
const name = (colon === -1 ? text : text.slice(0, colon)).trim().replaceAll(/\s+/g, "-");
|
|
45
|
+
const when = colon === -1 ? "" : text.slice(colon + 1).trim();
|
|
46
|
+
if (!INTENT_NAME.test(name))
|
|
47
|
+
return [];
|
|
48
|
+
return [{ id: name, ...(when === "" ? {} : { when }) }];
|
|
49
|
+
});
|
|
50
|
+
/** Rules with what is empty left out, so most components carry nothing. */
|
|
51
|
+
const compact = (lists) => {
|
|
52
|
+
const rules = Object.fromEntries(Object.entries(lists).filter(([, list]) => list.length > 0));
|
|
53
|
+
return Object.keys(rules).length === 0 ? undefined : rules;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* A component's rules, from its tags.
|
|
57
|
+
*
|
|
58
|
+
* @param tags - its TSDoc tags.
|
|
59
|
+
*/
|
|
60
|
+
export const rulesOfTags = (tags) => {
|
|
61
|
+
const textsOf = (name) => tags.filter((tag) => tag.name === name).map((tag) => tag.text);
|
|
62
|
+
return compact({
|
|
63
|
+
intents: intentsOf(textsOf("intent")),
|
|
64
|
+
parents: namesOf(textsOf("parent")),
|
|
65
|
+
children: namesOf(textsOf("children")),
|
|
66
|
+
siblings: namesOf(textsOf("siblings")),
|
|
67
|
+
insteadOf: namesOf(textsOf("insteadOf"))
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
/** A field of a rules file as a list of strings. */
|
|
71
|
+
const textList = (fields, key) => {
|
|
72
|
+
const value = fields.get(key);
|
|
73
|
+
if (typeof value === "string")
|
|
74
|
+
return [value];
|
|
75
|
+
return Array.isArray(value) ? value.filter((each) => typeof each === "string") : [];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* What a rules file says, by component, read as data: one that cannot be read says nothing.
|
|
79
|
+
*
|
|
80
|
+
* @param text - the file's text.
|
|
81
|
+
*/
|
|
82
|
+
export const rulesOfFile = (text) => {
|
|
83
|
+
let parsed;
|
|
84
|
+
try {
|
|
85
|
+
parsed = JSON.parse(text);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return new Map();
|
|
89
|
+
}
|
|
90
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
91
|
+
return new Map();
|
|
92
|
+
return new Map(Object.entries(parsed).flatMap(([name, written]) => {
|
|
93
|
+
if (typeof written !== "object" || written === null)
|
|
94
|
+
return [];
|
|
95
|
+
const fields = new Map(Object.entries(written));
|
|
96
|
+
const rules = compact({
|
|
97
|
+
intents: intentsOf([...textList(fields, "intent"), ...textList(fields, "intents")]),
|
|
98
|
+
parents: namesOf([...textList(fields, "parent"), ...textList(fields, "parents")]),
|
|
99
|
+
children: namesOf(textList(fields, "children")),
|
|
100
|
+
siblings: namesOf(textList(fields, "siblings")),
|
|
101
|
+
insteadOf: namesOf(textList(fields, "insteadOf"))
|
|
102
|
+
});
|
|
103
|
+
return rules === undefined ? [] : [[name, rules]];
|
|
104
|
+
}));
|
|
105
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { UsageGuidance } from "../componentDocs.ts";
|
|
2
|
+
import { type ComponentRules } from "./componentRules.ts";
|
|
3
|
+
import type { ProjectFile } from "./projectFiles.ts";
|
|
4
|
+
/** A component, as far as its file says. */
|
|
5
|
+
export type ScannedComponent = {
|
|
6
|
+
/** Its name. */
|
|
7
|
+
readonly name: string;
|
|
8
|
+
/** Its file, relative to the project. */
|
|
9
|
+
readonly file: string;
|
|
10
|
+
/** Its line, from 1. */
|
|
11
|
+
readonly line: number;
|
|
12
|
+
/** What it renders at its root (`button`, `Slot`); none when that takes running it. */
|
|
13
|
+
readonly root?: string;
|
|
14
|
+
/** The props it takes, when written plainly. */
|
|
15
|
+
readonly props: readonly string[];
|
|
16
|
+
/** The classes on its root, when written plainly. */
|
|
17
|
+
readonly classes: readonly string[];
|
|
18
|
+
/** The components it renders. */
|
|
19
|
+
readonly renders: readonly string[];
|
|
20
|
+
/** When to use it and when not, from its documentation comment. */
|
|
21
|
+
readonly guidance?: UsageGuidance;
|
|
22
|
+
/** How it is chosen and how it fits with others, from its documentation comment or a file beside it. */
|
|
23
|
+
readonly rules?: ComponentRules;
|
|
24
|
+
/** Whether its file exports it, so something else can use it. */
|
|
25
|
+
readonly isExported: boolean;
|
|
26
|
+
/** Whether it is its file's default export. */
|
|
27
|
+
readonly isDefault?: boolean;
|
|
28
|
+
/** Its code with no spacing and its own name out, to tell a copy; none when too short to tell anything. */
|
|
29
|
+
readonly code?: string;
|
|
30
|
+
};
|
|
31
|
+
/** A file that can declare components. */
|
|
32
|
+
export declare const COMPONENT_FILE: RegExp;
|
|
33
|
+
/**
|
|
34
|
+
* A component's code as a copy of it would read: spacing and quotes do not matter, and neither does its name.
|
|
35
|
+
*
|
|
36
|
+
* @param source - its code.
|
|
37
|
+
* @param name - its name.
|
|
38
|
+
*/
|
|
39
|
+
export declare const codeKey: (source: string, name: string) => {
|
|
40
|
+
readonly code?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* When to use a component and when not, from a comment's text.
|
|
44
|
+
*
|
|
45
|
+
* @param comment - the comment; none gives nothing.
|
|
46
|
+
*/
|
|
47
|
+
export declare const guidanceOfComment: (comment: string | undefined) => {
|
|
48
|
+
readonly guidance?: UsageGuidance;
|
|
49
|
+
readonly rules?: ComponentRules;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* A word as a single-file component's file name makes a component name of it.
|
|
53
|
+
*
|
|
54
|
+
* @param file - the file.
|
|
55
|
+
*/
|
|
56
|
+
export declare const nameOfFile: (file: string) => string;
|
|
57
|
+
/**
|
|
58
|
+
* The components a file declares; a file that cannot be parsed declares none, since this reads a project as it is.
|
|
59
|
+
*
|
|
60
|
+
* @param file - its path, relative to the project.
|
|
61
|
+
* @param text - its text.
|
|
62
|
+
*/
|
|
63
|
+
export declare const scannedComponents: (file: string, text: string) => ScannedComponent[];
|
|
64
|
+
/**
|
|
65
|
+
* The components of a project's files, leaving out what is no component of its own (stories, tests).
|
|
66
|
+
*
|
|
67
|
+
* @param files - its files.
|
|
68
|
+
*/
|
|
69
|
+
export declare const projectComponents: (files: readonly ProjectFile[]) => ScannedComponent[];
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The components a project's files declare, read from their text: their names, what they render at their root, the props
|
|
3
|
+
* they take and the classes they carry.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Pure, and read without a type checker: this has to work on a project with no catalogue, in a moment, over every file.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { parseSync } from "vite";
|
|
12
|
+
import { LEFT_ALONE } from "./checkCode.js";
|
|
13
|
+
import { rulesOfTags } from "./componentRules.js";
|
|
14
|
+
import { singleFileComponent } from "./singleFileComponent.js";
|
|
15
|
+
import { isTooDeep, lineAt, lineStarts } from "./sourceText.js";
|
|
16
|
+
import { guidanceOfTags, tagsOfComment } from "./usageGuidance.js";
|
|
17
|
+
/** How many line comments may stand between a doc comment and what it documents. */
|
|
18
|
+
const MOST_COMMENTS_BACK = 3;
|
|
19
|
+
/** Shorter than this, two components' code being equal says nothing: every wrapper of a `div` reads alike. */
|
|
20
|
+
const SHORTEST_CODE = 120;
|
|
21
|
+
/** A file that can declare components. */
|
|
22
|
+
export const COMPONENT_FILE = /\.(?:tsx|jsx|vue|svelte|astro)$/;
|
|
23
|
+
/** A framework's own single-file component. */
|
|
24
|
+
const SINGLE_FILE = /\.(?:vue|svelte|astro)$/;
|
|
25
|
+
/** Whether a value is a node of the syntax tree. */
|
|
26
|
+
const isNode = (value) => typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
27
|
+
/** Visits a node and everything under it, until the visit says it found what it wanted. */
|
|
28
|
+
const someNode = (node, visit) => {
|
|
29
|
+
if (Array.isArray(node))
|
|
30
|
+
return node.some((each) => someNode(each, visit));
|
|
31
|
+
if (typeof node !== "object" || node === null)
|
|
32
|
+
return false;
|
|
33
|
+
if (isNode(node) && visit(node))
|
|
34
|
+
return true;
|
|
35
|
+
return Object.values(node).some((value) => typeof value === "object" && someNode(value, visit));
|
|
36
|
+
};
|
|
37
|
+
/** A JSX element's name: `button`, `Dialog`, `Dialog.Title`. */
|
|
38
|
+
const elementName = (name) => {
|
|
39
|
+
if (!isNode(name))
|
|
40
|
+
return undefined;
|
|
41
|
+
if (name.type === "JSXIdentifier" && typeof name["name"] === "string")
|
|
42
|
+
return name["name"];
|
|
43
|
+
if (name.type !== "JSXMemberExpression")
|
|
44
|
+
return undefined;
|
|
45
|
+
const [object, property] = [elementName(name["object"]), elementName(name["property"])];
|
|
46
|
+
return object === undefined || property === undefined ? undefined : `${object}.${property}`;
|
|
47
|
+
};
|
|
48
|
+
/** The classes of a `className` or `class` attribute, as a string or as a string in a helper's call. */
|
|
49
|
+
const classesOfAttribute = (value) => {
|
|
50
|
+
// the longest string: `cn(isOn && "on", "a b c")` holds the look in its second
|
|
51
|
+
let text = "";
|
|
52
|
+
someNode(value, (node) => {
|
|
53
|
+
if (node.type === "Literal" && typeof node["value"] === "string" && node["value"].length > text.length) {
|
|
54
|
+
text = node["value"];
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
});
|
|
58
|
+
return text.split(/\s+/).filter((each) => each !== "");
|
|
59
|
+
};
|
|
60
|
+
/** The classes on a JSX element. */
|
|
61
|
+
const classesOfElement = (element) => {
|
|
62
|
+
const attributes = Array.isArray(element["attributes"]) ? element["attributes"] : [];
|
|
63
|
+
const found = attributes.find((attribute) => {
|
|
64
|
+
const key = isNode(attribute) && isNode(attribute["name"]) ? attribute["name"]["name"] : undefined;
|
|
65
|
+
return key === "className" || key === "class";
|
|
66
|
+
});
|
|
67
|
+
return isNode(found) ? classesOfAttribute(found["value"]) : [];
|
|
68
|
+
};
|
|
69
|
+
/** Whether a node opens a function of its own, whose returns are not its parent's. */
|
|
70
|
+
const isFunctionNode = (node) => node.type === "ArrowFunctionExpression" ||
|
|
71
|
+
node.type === "FunctionExpression" ||
|
|
72
|
+
node.type === "FunctionDeclaration";
|
|
73
|
+
/** What a function's own returns give, in order, not those of the callbacks inside it. */
|
|
74
|
+
const returnedValues = (node) => {
|
|
75
|
+
if (Array.isArray(node))
|
|
76
|
+
return node.flatMap(returnedValues);
|
|
77
|
+
if (typeof node !== "object" || node === null)
|
|
78
|
+
return [];
|
|
79
|
+
if (isNode(node)) {
|
|
80
|
+
if (isFunctionNode(node))
|
|
81
|
+
return [];
|
|
82
|
+
if (node.type === "ReturnStatement")
|
|
83
|
+
return [node["argument"]];
|
|
84
|
+
}
|
|
85
|
+
return Object.values(node).flatMap((value) => (typeof value === "object" ? returnedValues(value) : []));
|
|
86
|
+
};
|
|
87
|
+
/** The element an expression comes to: through parentheses, a condition's last branch and a fragment's first child. */
|
|
88
|
+
const elementIn = (value) => {
|
|
89
|
+
if (!isNode(value))
|
|
90
|
+
return undefined;
|
|
91
|
+
if (value.type === "JSXElement")
|
|
92
|
+
return isNode(value["openingElement"]) ? value["openingElement"] : undefined;
|
|
93
|
+
if (value.type === "ParenthesizedExpression")
|
|
94
|
+
return elementIn(value["expression"]);
|
|
95
|
+
if (value.type === "ConditionalExpression")
|
|
96
|
+
return elementIn(value["alternate"]) ?? elementIn(value["consequent"]);
|
|
97
|
+
if (value.type === "LogicalExpression")
|
|
98
|
+
return elementIn(value["right"]);
|
|
99
|
+
if (value.type !== "JSXFragment" || !Array.isArray(value["children"]))
|
|
100
|
+
return undefined;
|
|
101
|
+
for (const child of value["children"]) {
|
|
102
|
+
const found = elementIn(child);
|
|
103
|
+
if (found !== undefined)
|
|
104
|
+
return found;
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
};
|
|
108
|
+
/** What a function renders at its root: what it returns last, since an early return is a loading or an empty state. */
|
|
109
|
+
const rootOf = (body) => {
|
|
110
|
+
if (!isNode(body) || body.type !== "BlockStatement")
|
|
111
|
+
return elementIn(body);
|
|
112
|
+
return returnedValues(body["body"])
|
|
113
|
+
.flatMap((value) => elementIn(value) ?? [])
|
|
114
|
+
.at(-1);
|
|
115
|
+
};
|
|
116
|
+
/** What a function renders: its root, its root's classes, and every component in it. */
|
|
117
|
+
const rendered = (body) => {
|
|
118
|
+
const renders = new Set();
|
|
119
|
+
let hasMarkup = false;
|
|
120
|
+
someNode(body, (node) => {
|
|
121
|
+
const name = node.type === "JSXOpeningElement" ? elementName(node["name"]) : undefined;
|
|
122
|
+
if (name === undefined)
|
|
123
|
+
return false;
|
|
124
|
+
hasMarkup = true;
|
|
125
|
+
if (/^[A-Z]/.test(name))
|
|
126
|
+
renders.add(name);
|
|
127
|
+
return false;
|
|
128
|
+
});
|
|
129
|
+
const element = rootOf(body);
|
|
130
|
+
const root = element === undefined ? undefined : elementName(element["name"]);
|
|
131
|
+
return {
|
|
132
|
+
...(root === undefined ? {} : { root }),
|
|
133
|
+
...(hasMarkup ? { hasMarkup } : {}),
|
|
134
|
+
classes: element === undefined ? [] : classesOfElement(element),
|
|
135
|
+
renders: [...renders]
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
/** The names a type's members give, for an object type or an interface's body. */
|
|
139
|
+
const memberNames = (members) => members.flatMap((member) => member.type === "TSPropertySignature" && member.key.type === "Identifier" ? [member.key.name] : []);
|
|
140
|
+
/** The object types and interfaces a file declares at its top, by name. */
|
|
141
|
+
const declaredTypes = (program) => {
|
|
142
|
+
const types = new Map();
|
|
143
|
+
for (const statement of program.body) {
|
|
144
|
+
const declaration = statement.type === "ExportNamedDeclaration" ? statement.declaration : statement;
|
|
145
|
+
if (declaration?.type === "TSInterfaceDeclaration") {
|
|
146
|
+
types.set(declaration.id.name, memberNames(declaration.body.body));
|
|
147
|
+
}
|
|
148
|
+
else if (declaration?.type === "TSTypeAliasDeclaration" &&
|
|
149
|
+
declaration.typeAnnotation.type === "TSTypeLiteral") {
|
|
150
|
+
types.set(declaration.id.name, memberNames(declaration.typeAnnotation.members));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return types;
|
|
154
|
+
};
|
|
155
|
+
/** The props a function's first parameter takes: names it destructures, or its type's members. */
|
|
156
|
+
const propsOf = (parameter, types) => {
|
|
157
|
+
if (!isNode(parameter))
|
|
158
|
+
return [];
|
|
159
|
+
const annotation = parameter["typeAnnotation"];
|
|
160
|
+
const inner = isNode(annotation) ? annotation["typeAnnotation"] : undefined;
|
|
161
|
+
if (isNode(inner) && inner.type === "TSTypeReference" && isNode(inner["typeName"])) {
|
|
162
|
+
const named = types.get(String(inner["typeName"]["name"]));
|
|
163
|
+
if (named !== undefined)
|
|
164
|
+
return named;
|
|
165
|
+
}
|
|
166
|
+
if (isNode(inner) && inner.type === "TSTypeLiteral" && Array.isArray(inner["members"])) {
|
|
167
|
+
return inner["members"].flatMap((member) => isNode(member) && isNode(member["key"]) && typeof member["key"]["name"] === "string"
|
|
168
|
+
? [member["key"]["name"]]
|
|
169
|
+
: []);
|
|
170
|
+
}
|
|
171
|
+
if (parameter.type !== "ObjectPattern" || !Array.isArray(parameter["properties"]))
|
|
172
|
+
return [];
|
|
173
|
+
return parameter["properties"].flatMap((property) => isNode(property) && isNode(property["key"]) && typeof property["key"]["name"] === "string"
|
|
174
|
+
? [property["key"]["name"]]
|
|
175
|
+
: []);
|
|
176
|
+
};
|
|
177
|
+
/** The function a declaration's value holds, through `forwardRef(…)` and `memo(…)`. */
|
|
178
|
+
const functionOf = (value) => {
|
|
179
|
+
if (!isNode(value))
|
|
180
|
+
return undefined;
|
|
181
|
+
if (value.type === "ArrowFunctionExpression" || value.type === "FunctionExpression")
|
|
182
|
+
return value;
|
|
183
|
+
if (value.type === "FunctionDeclaration")
|
|
184
|
+
return value;
|
|
185
|
+
if (value.type === "CallExpression" && Array.isArray(value["arguments"])) {
|
|
186
|
+
return functionOf(value["arguments"][0]);
|
|
187
|
+
}
|
|
188
|
+
return value.type === "TSAsExpression" || value.type === "TSSatisfiesExpression"
|
|
189
|
+
? functionOf(value["expression"])
|
|
190
|
+
: undefined;
|
|
191
|
+
};
|
|
192
|
+
/** A class component's `render`, as a function. */
|
|
193
|
+
const renderOfClass = (node) => {
|
|
194
|
+
const isComponent = isNode(node.superClass) && /Component$/.test(sourceName(node.superClass));
|
|
195
|
+
if (!isComponent || !isNode(node.body) || !Array.isArray(node.body["body"]))
|
|
196
|
+
return undefined;
|
|
197
|
+
const render = node.body["body"].find((member) => isNode(member) && isNode(member["key"]) && member["key"]["name"] === "render");
|
|
198
|
+
return isNode(render) ? render["value"] : undefined;
|
|
199
|
+
};
|
|
200
|
+
/** The last name of `React.Component` or `Component`. */
|
|
201
|
+
const sourceName = (node) => {
|
|
202
|
+
if (node.type === "Identifier" && typeof node["name"] === "string")
|
|
203
|
+
return node["name"];
|
|
204
|
+
return isNode(node["property"]) ? sourceName(node["property"]) : "";
|
|
205
|
+
};
|
|
206
|
+
/** The top function one statement declares. */
|
|
207
|
+
const topFunctionsOf = (declaration, file, isDefault) => {
|
|
208
|
+
const { start } = declaration;
|
|
209
|
+
if (declaration.type === "FunctionDeclaration") {
|
|
210
|
+
return [{ name: declaration.id?.name ?? nameOfFile(file), value: declaration, start }];
|
|
211
|
+
}
|
|
212
|
+
if (declaration.type === "ClassDeclaration") {
|
|
213
|
+
const value = renderOfClass(declaration);
|
|
214
|
+
return value === undefined ? [] : [{ name: declaration.id?.name ?? nameOfFile(file), value, start }];
|
|
215
|
+
}
|
|
216
|
+
if (isDefault && declaration.type === "CallExpression") {
|
|
217
|
+
return [{ name: nameOfFile(file), value: declaration, start }];
|
|
218
|
+
}
|
|
219
|
+
if (declaration.type !== "VariableDeclaration")
|
|
220
|
+
return [];
|
|
221
|
+
return declaration.declarations.flatMap((each) => each.id.type === "Identifier"
|
|
222
|
+
? [{ name: each.id.name, value: each.init, start: each.start, annotation: each.id.typeAnnotation }]
|
|
223
|
+
: []);
|
|
224
|
+
};
|
|
225
|
+
/** The named functions at a program's top; a default export with no name takes its file's. */
|
|
226
|
+
const topFunctions = (program, file) => program.body.flatMap((statement) => {
|
|
227
|
+
const isExport = statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration";
|
|
228
|
+
const declaration = isExport ? statement.declaration : statement;
|
|
229
|
+
return declaration === null || declaration === undefined
|
|
230
|
+
? []
|
|
231
|
+
: topFunctionsOf(declaration, file, statement.type === "ExportDefaultDeclaration").map((each) => ({
|
|
232
|
+
...each,
|
|
233
|
+
statement: statement.start,
|
|
234
|
+
isTop: isExport,
|
|
235
|
+
isDefaultStatement: statement.type === "ExportDefaultDeclaration"
|
|
236
|
+
}));
|
|
237
|
+
});
|
|
238
|
+
/** The type arguments of a type or a call, in order. */
|
|
239
|
+
const typeArgumentsOf = (node) => {
|
|
240
|
+
if (!isNode(node) || !isNode(node["typeArguments"]))
|
|
241
|
+
return [];
|
|
242
|
+
const { params } = node["typeArguments"];
|
|
243
|
+
return Array.isArray(params) ? params : [];
|
|
244
|
+
};
|
|
245
|
+
/** The type a component's props are written in, outside its parameter: `React.FC<P>`, `forwardRef<H, P>`. */
|
|
246
|
+
const typeOfValue = (value, annotation) => {
|
|
247
|
+
const declared = isNode(annotation) ? annotation["typeAnnotation"] : undefined;
|
|
248
|
+
const [fromAnnotation] = typeArgumentsOf(declared);
|
|
249
|
+
if (fromAnnotation !== undefined)
|
|
250
|
+
return fromAnnotation;
|
|
251
|
+
return typeArgumentsOf(value)[1];
|
|
252
|
+
};
|
|
253
|
+
/** The props a type's name or literal gives. */
|
|
254
|
+
const propsOfType = (type, types) => propsOf({ type: "Identifier", typeAnnotation: { type: "TSTypeAnnotation", typeAnnotation: type } }, types);
|
|
255
|
+
/**
|
|
256
|
+
* A component's code as a copy of it would read: spacing and quotes do not matter, and neither does its name.
|
|
257
|
+
*
|
|
258
|
+
* @param source - its code.
|
|
259
|
+
* @param name - its name.
|
|
260
|
+
*/
|
|
261
|
+
export const codeKey = (source, name) => {
|
|
262
|
+
const code = source.replaceAll(name, "").replace(/[\s;'"`]+/g, "");
|
|
263
|
+
// a digest: a project's components are held in memory between questions
|
|
264
|
+
return code.length < SHORTEST_CODE ? {} : { code: createHash("sha256").update(code).digest("base64url") };
|
|
265
|
+
};
|
|
266
|
+
/** What a file exports apart from the declarations themselves: `export { X }`, `export default X`. */
|
|
267
|
+
const exportedNames = (program) => {
|
|
268
|
+
const named = new Set();
|
|
269
|
+
let byDefault;
|
|
270
|
+
for (const statement of program.body) {
|
|
271
|
+
if (statement.type === "ExportDefaultDeclaration" && statement.declaration.type === "Identifier") {
|
|
272
|
+
byDefault = statement.declaration.name;
|
|
273
|
+
}
|
|
274
|
+
if (statement.type !== "ExportNamedDeclaration" || statement.source !== null)
|
|
275
|
+
continue;
|
|
276
|
+
for (const { local, exported } of statement.specifiers) {
|
|
277
|
+
const [from, as] = [local, exported].map((each) => "name" in each ? String(each.name) : String(each.value));
|
|
278
|
+
if (as === "default")
|
|
279
|
+
byDefault = from;
|
|
280
|
+
else if (from !== undefined)
|
|
281
|
+
named.add(from);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return { named, byDefault };
|
|
285
|
+
};
|
|
286
|
+
/** The names a file imports under another: rendering `Base` from `Button as Base` is rendering `Button`. */
|
|
287
|
+
const localImports = (program) => new Map(program.body.flatMap((statement) => statement.type !== "ImportDeclaration"
|
|
288
|
+
? []
|
|
289
|
+
: statement.specifiers.flatMap((each) => each.type === "ImportSpecifier" && "name" in each.imported
|
|
290
|
+
? [[each.local.name, String(each.imported.name)]]
|
|
291
|
+
: [])));
|
|
292
|
+
/** The doc comment before a statement, past line comments between them (`// eslint-disable-next-line`). */
|
|
293
|
+
const commentBefore = (text, start, comments) => {
|
|
294
|
+
let at = start;
|
|
295
|
+
for (let hops = 0; hops < MOST_COMMENTS_BACK; hops += 1) {
|
|
296
|
+
let end = at;
|
|
297
|
+
while (end > 0 && /\s/.test(text[end - 1] ?? ""))
|
|
298
|
+
end -= 1;
|
|
299
|
+
const comment = comments.get(end);
|
|
300
|
+
if (comment === undefined)
|
|
301
|
+
return undefined;
|
|
302
|
+
if (comment.type === "Block")
|
|
303
|
+
return comment.value;
|
|
304
|
+
at = comment.start;
|
|
305
|
+
}
|
|
306
|
+
return undefined;
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* When to use a component and when not, from a comment's text.
|
|
310
|
+
*
|
|
311
|
+
* @param comment - the comment; none gives nothing.
|
|
312
|
+
*/
|
|
313
|
+
export const guidanceOfComment = (comment) => {
|
|
314
|
+
if (comment === undefined)
|
|
315
|
+
return {};
|
|
316
|
+
const tags = tagsOfComment(comment);
|
|
317
|
+
const rules = rulesOfTags(tags);
|
|
318
|
+
return { ...guidanceOfTags(tags), ...(rules === undefined ? {} : { rules }) };
|
|
319
|
+
};
|
|
320
|
+
/** Whether a value is a part of a library, as `SelectPrimitive.Root`. */
|
|
321
|
+
const isPartOfALibrary = (value) => isNode(value) &&
|
|
322
|
+
value.type === "MemberExpression" &&
|
|
323
|
+
isNode(value["object"]) &&
|
|
324
|
+
value["object"].type === "Identifier" &&
|
|
325
|
+
/^[A-Z]/.test(String(value["object"]["name"]));
|
|
326
|
+
/** A library's part given a name: `export const Select = SelectPrimitive.Root` has no markup, yet can carry rules. */
|
|
327
|
+
const partOfALibrary = (top, context) => ({
|
|
328
|
+
name: top.name,
|
|
329
|
+
file: context.file,
|
|
330
|
+
line: lineAt(context.starts, top.start),
|
|
331
|
+
props: [],
|
|
332
|
+
classes: [],
|
|
333
|
+
renders: [],
|
|
334
|
+
isExported: top.isTop === true || context.exported.named.has(top.name),
|
|
335
|
+
...guidanceOfComment(commentBefore(context.text, top.statement ?? top.start, context.documented))
|
|
336
|
+
});
|
|
337
|
+
/** The component a function at a script's top is, when it is one: a capital name and markup of its own. */
|
|
338
|
+
const componentOf = (top, context) => {
|
|
339
|
+
const { name, value, start, annotation, statement, isTop, isDefaultStatement } = top;
|
|
340
|
+
const { file, text, types, documented, starts, exported, imported } = context;
|
|
341
|
+
const found = functionOf(value);
|
|
342
|
+
if (found === undefined && /^[A-Z]/.test(name) && isPartOfALibrary(value))
|
|
343
|
+
return [partOfALibrary(top, context)];
|
|
344
|
+
if (found === undefined || !/^[A-Z]/.test(name))
|
|
345
|
+
return [];
|
|
346
|
+
const { hasMarkup, ...drawn } = rendered(found["body"]);
|
|
347
|
+
if (hasMarkup !== true)
|
|
348
|
+
return [];
|
|
349
|
+
const parameters = Array.isArray(found["params"]) ? found["params"] : [];
|
|
350
|
+
const written = propsOf(parameters[0], types);
|
|
351
|
+
const isDefault = exported.byDefault === name || (isTop === true && isDefaultStatement === true);
|
|
352
|
+
const hasRange = isNode(value) && typeof value["start"] === "number" && typeof value["end"] === "number";
|
|
353
|
+
return [
|
|
354
|
+
{
|
|
355
|
+
name,
|
|
356
|
+
file,
|
|
357
|
+
line: lineAt(starts, start),
|
|
358
|
+
props: written.length > 0 ? written : propsOfType(typeOfValue(value, annotation), types),
|
|
359
|
+
...drawn,
|
|
360
|
+
renders: [...new Set(drawn.renders.flatMap((each) => [each, imported.get(each) ?? each]))],
|
|
361
|
+
isExported: isTop === true || exported.named.has(name) || isDefault,
|
|
362
|
+
...(isDefault ? { isDefault: true } : {}),
|
|
363
|
+
...guidanceOfComment(commentBefore(text, statement ?? start, documented)),
|
|
364
|
+
...(hasRange ? codeKey(text.slice(Number(value["start"]), Number(value["end"])), name) : {})
|
|
365
|
+
}
|
|
366
|
+
];
|
|
367
|
+
};
|
|
368
|
+
/** The components of a script with JSX. */
|
|
369
|
+
const scriptComponents = (file, text) => {
|
|
370
|
+
if (isTooDeep(text))
|
|
371
|
+
return [];
|
|
372
|
+
const { program, errors, comments } = parseSync(file, text);
|
|
373
|
+
if (errors.length > 0)
|
|
374
|
+
return [];
|
|
375
|
+
const context = {
|
|
376
|
+
file,
|
|
377
|
+
text,
|
|
378
|
+
types: declaredTypes(program),
|
|
379
|
+
documented: new Map(comments.map((comment) => [comment.end, comment])),
|
|
380
|
+
starts: lineStarts(text),
|
|
381
|
+
exported: exportedNames(program),
|
|
382
|
+
imported: localImports(program)
|
|
383
|
+
};
|
|
384
|
+
return topFunctions(program, file).flatMap((each) => componentOf(each, context));
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* A word as a single-file component's file name makes a component name of it.
|
|
388
|
+
*
|
|
389
|
+
* @param file - the file.
|
|
390
|
+
*/
|
|
391
|
+
export const nameOfFile = (file) => (file.split("/").at(-1) ?? "")
|
|
392
|
+
.replace(/\.[^.]+$/, "")
|
|
393
|
+
.split(/[-_.]/)
|
|
394
|
+
.map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
|
|
395
|
+
.join("")
|
|
396
|
+
// a file's name reaches an answer as a component's, and it can hold anything
|
|
397
|
+
.replace(/[^\w$]/g, "");
|
|
398
|
+
/**
|
|
399
|
+
* The components a file declares; a file that cannot be parsed declares none, since this reads a project as it is.
|
|
400
|
+
*
|
|
401
|
+
* @param file - its path, relative to the project.
|
|
402
|
+
* @param text - its text.
|
|
403
|
+
*/
|
|
404
|
+
export const scannedComponents = (file, text) => {
|
|
405
|
+
try {
|
|
406
|
+
return SINGLE_FILE.test(file) ? [singleFileComponent(file, text)] : scriptComponents(file, text);
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
// a stack overflow on a crafted file costs that file
|
|
410
|
+
return [];
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* The components of a project's files, leaving out what is no component of its own (stories, tests).
|
|
415
|
+
*
|
|
416
|
+
* @param files - its files.
|
|
417
|
+
*/
|
|
418
|
+
export const projectComponents = (files) => files.flatMap(({ file, text }) => !LEFT_ALONE.test(file) && COMPONENT_FILE.test(file) ? scannedComponents(file, text) : []);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AddedLine, CodeProblem, ExcusedValue } from "./checkCode.ts";
|
|
2
|
+
import type { ScannedComponent } from "./componentScan.ts";
|
|
3
|
+
import type { ProjectFile, WorkspacePackage } from "./projectFiles.ts";
|
|
4
|
+
/**
|
|
5
|
+
* What a change writes against how the system says its components fit together.
|
|
6
|
+
*
|
|
7
|
+
* @param added - the lines it adds.
|
|
8
|
+
* @param changed - the changed files as they are now.
|
|
9
|
+
* @param components - every component of the project.
|
|
10
|
+
* @param packages - the repository's packages, to tell a third party's component of the same name; none by default.
|
|
11
|
+
*/
|
|
12
|
+
export declare const compositionFindings: (added: readonly AddedLine[], changed: readonly ProjectFile[], components: readonly ScannedComponent[], packages?: readonly WorkspacePackage[]) => {
|
|
13
|
+
readonly problems: readonly CodeProblem[];
|
|
14
|
+
readonly excused: readonly ExcusedValue[];
|
|
15
|
+
};
|