@wrikka/create-docs 0.1.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 +137 -0
- package/bin/cli.js +408 -0
- package/dist/index.cjs +20 -0
- package/dist/index.d.cts +475 -0
- package/dist/index.d.ts +475 -0
- package/dist/index.js +20 -0
- package/docs/_dir.yml +2 -0
- package/docs/config.md +75 -0
- package/docs/data-sources.md +88 -0
- package/docs/deploy.md +38 -0
- package/docs/features.md +51 -0
- package/docs/getting-started.md +42 -0
- package/docs/index.md +34 -0
- package/docs/markdown.md +154 -0
- package/docs/theming.md +53 -0
- package/package.json +142 -0
- package/scripts/generate-docs-index.ts +111 -0
- package/scripts/github-pull.ts +124 -0
- package/src/adapters/config/index.ts +1 -0
- package/src/adapters/config/node-config-loader.ts +36 -0
- package/src/adapters/fs/fs-docs-loader.ts +31 -0
- package/src/adapters/fs/index.ts +12 -0
- package/src/adapters/fs/memory-fs.ts +60 -0
- package/src/adapters/fs/node-fs.ts +116 -0
- package/src/adapters/git/index.ts +164 -0
- package/src/adapters/github/github-pull.ts +340 -0
- package/src/adapters/index.ts +6 -0
- package/src/adapters/velite.ts +112 -0
- package/src/adapters/vite/docs-watcher.ts +36 -0
- package/src/adapters/vite/index.ts +2 -0
- package/src/adapters/vite/polling-watcher.ts +89 -0
- package/src/code-block-enhancements/index.ts +3 -0
- package/src/config/index.ts +15 -0
- package/src/content/index.ts +11 -0
- package/src/content-validation/index.ts +5 -0
- package/src/index.ts +174 -0
- package/src/live-editor/index.ts +7 -0
- package/src/modules/analytics/application/plausible-adapter.ts +103 -0
- package/src/modules/analytics/application/umami-adapter.ts +109 -0
- package/src/modules/analytics/domain/events/index.ts +37 -0
- package/src/modules/analytics/domain/models/index.ts +35 -0
- package/src/modules/analytics/domain/operations/analytics-operations.ts +67 -0
- package/src/modules/analytics/domain/validators/index.ts +50 -0
- package/src/modules/analytics/index.ts +9 -0
- package/src/modules/analytics/ports/analytics-port.ts +17 -0
- package/src/modules/analytics/types/analytics.ts +16 -0
- package/src/modules/api-docs/application/type-docs-adapter.ts +34 -0
- package/src/modules/api-docs/domain/events/index.ts +42 -0
- package/src/modules/api-docs/domain/models/index.ts +40 -0
- package/src/modules/api-docs/domain/operations/api-docs-operations.ts +59 -0
- package/src/modules/api-docs/domain/validators/index.ts +56 -0
- package/src/modules/api-docs/index.ts +8 -0
- package/src/modules/api-docs/ports/api-docs-port.ts +21 -0
- package/src/modules/api-docs/types/api-docs.ts +15 -0
- package/src/modules/api-reference/openapi.ts +166 -0
- package/src/modules/api-reference/orpc.ts +94 -0
- package/src/modules/code-block-enhancements/application/usecases/index.ts +39 -0
- package/src/modules/code-block-enhancements/domain/code-operations.ts +72 -0
- package/src/modules/code-block-enhancements/domain/events/index.ts +58 -0
- package/src/modules/code-block-enhancements/domain/index.ts +11 -0
- package/src/modules/code-block-enhancements/domain/models/index.ts +36 -0
- package/src/modules/code-block-enhancements/domain/validators/index.ts +50 -0
- package/src/modules/code-block-enhancements/index.ts +10 -0
- package/src/modules/code-block-enhancements/ports/index.ts +18 -0
- package/src/modules/code-block-enhancements/types/index.ts +37 -0
- package/src/modules/code-execution/application/sandbox-adapter.ts +44 -0
- package/src/modules/code-execution/domain/events/index.ts +58 -0
- package/src/modules/code-execution/domain/models/index.ts +33 -0
- package/src/modules/code-execution/domain/operations/execution-operations.ts +60 -0
- package/src/modules/code-execution/domain/validators/index.ts +50 -0
- package/src/modules/code-execution/index.ts +8 -0
- package/src/modules/code-execution/ports/execution-port.ts +15 -0
- package/src/modules/code-execution/types/execution.ts +15 -0
- package/src/modules/comments/application/giscus-adapter.ts +55 -0
- package/src/modules/comments/domain/events/index.ts +55 -0
- package/src/modules/comments/domain/models/index.ts +30 -0
- package/src/modules/comments/domain/operations/comment-operations.ts +46 -0
- package/src/modules/comments/domain/validators/index.ts +50 -0
- package/src/modules/comments/index.ts +8 -0
- package/src/modules/comments/ports/comment-port.ts +18 -0
- package/src/modules/comments/types/comments.ts +19 -0
- package/src/modules/config/application/usecases/index.ts +1 -0
- package/src/modules/config/application/usecases/loadConfig.ts +38 -0
- package/src/modules/config/application/workflows/index.ts +1 -0
- package/src/modules/config/application/workflows/validateConfig.ts +14 -0
- package/src/modules/config/domain/events/index.ts +50 -0
- package/src/modules/config/domain/models/index.ts +9 -0
- package/src/modules/config/domain/operations/defaults.ts +74 -0
- package/src/modules/config/domain/operations/index.ts +2 -0
- package/src/modules/config/domain/operations/resolve.ts +40 -0
- package/src/modules/config/domain/validators/index.ts +152 -0
- package/src/modules/config/index.ts +23 -0
- package/src/modules/config/ports/index.ts +15 -0
- package/src/modules/config/types/index.ts +113 -0
- package/src/modules/config/types/public.ts +19 -0
- package/src/modules/content/application/cache/index.ts +6 -0
- package/src/modules/content/application/cache/parse-cache.ts +6 -0
- package/src/modules/content/application/cache/parseCache.ts +56 -0
- package/src/modules/content/application/usecases/index.ts +2 -0
- package/src/modules/content/application/usecases/load-doc-page.ts +1 -0
- package/src/modules/content/application/usecases/loadDocPage.ts +111 -0
- package/src/modules/content/application/usecases/scanDocsDir.ts +105 -0
- package/src/modules/content/application/workflows/index.ts +1 -0
- package/src/modules/content/application/workflows/processDocs.ts +51 -0
- package/src/modules/content/domain/events/index.ts +61 -0
- package/src/modules/content/domain/models/index.ts +13 -0
- package/src/modules/content/domain/operations/build-page.ts +146 -0
- package/src/modules/content/domain/operations/buildPage.ts +93 -0
- package/src/modules/content/domain/operations/index.ts +17 -0
- package/src/modules/content/domain/operations/parse.ts +241 -0
- package/src/modules/content/domain/validators/frontmatter.ts +82 -0
- package/src/modules/content/domain/validators/index.ts +6 -0
- package/src/modules/content/index.ts +27 -0
- package/src/modules/content/ports/index.ts +45 -0
- package/src/modules/content/ports/velite.ts +134 -0
- package/src/modules/content/types/index.ts +76 -0
- package/src/modules/content/types/public.ts +1 -0
- package/src/modules/content-linting/application/builtin-linting-adapter.ts +82 -0
- package/src/modules/content-linting/domain/events/index.ts +58 -0
- package/src/modules/content-linting/domain/models/index.ts +46 -0
- package/src/modules/content-linting/domain/operations/linting-operations.ts +82 -0
- package/src/modules/content-linting/domain/validators/index.ts +50 -0
- package/src/modules/content-linting/index.ts +8 -0
- package/src/modules/content-linting/ports/linting-port.ts +21 -0
- package/src/modules/content-linting/types/linting.ts +18 -0
- package/src/modules/content-validation/application/usecases/index.ts +18 -0
- package/src/modules/content-validation/domain/events/index.ts +7 -0
- package/src/modules/content-validation/domain/index.ts +16 -0
- package/src/modules/content-validation/domain/models/index.ts +33 -0
- package/src/modules/content-validation/domain/operations/index.ts +157 -0
- package/src/modules/content-validation/domain/types/index.ts +17 -0
- package/src/modules/content-validation/domain/validators/index.ts +8 -0
- package/src/modules/content-validation/index.ts +9 -0
- package/src/modules/content-validation/ports/index.ts +15 -0
- package/src/modules/content-validation/types/index.ts +5 -0
- package/src/modules/export/application/puppeteer-export-adapter.ts +63 -0
- package/src/modules/export/domain/events/index.ts +55 -0
- package/src/modules/export/domain/models/index.ts +38 -0
- package/src/modules/export/domain/operations/export-operations.ts +56 -0
- package/src/modules/export/domain/validators/index.ts +52 -0
- package/src/modules/export/index.ts +8 -0
- package/src/modules/export/ports/export-port.ts +15 -0
- package/src/modules/export/types/export.ts +15 -0
- package/src/modules/external-search/application/algolia-adapter.ts +182 -0
- package/src/modules/external-search/application/meilisearch-adapter.ts +161 -0
- package/src/modules/external-search/domain/events/index.ts +42 -0
- package/src/modules/external-search/domain/models/index.ts +42 -0
- package/src/modules/external-search/domain/operations/search-operations.ts +53 -0
- package/src/modules/external-search/domain/validators/index.ts +55 -0
- package/src/modules/external-search/index.ts +9 -0
- package/src/modules/external-search/ports/external-search-port.ts +23 -0
- package/src/modules/external-search/types/search.ts +19 -0
- package/src/modules/git-history/application/simple-git-adapter.ts +46 -0
- package/src/modules/git-history/domain/events/index.ts +34 -0
- package/src/modules/git-history/domain/models/index.ts +25 -0
- package/src/modules/git-history/domain/operations/git-history-operations.ts +56 -0
- package/src/modules/git-history/domain/validators/index.ts +52 -0
- package/src/modules/git-history/index.ts +8 -0
- package/src/modules/git-history/ports/git-history-port.ts +21 -0
- package/src/modules/git-history/types/git-history.ts +15 -0
- package/src/modules/i18n/application/fs-locale-loader.ts +39 -0
- package/src/modules/i18n/domain/events/index.ts +34 -0
- package/src/modules/i18n/domain/models/index.ts +34 -0
- package/src/modules/i18n/domain/operations/locale-operations.ts +74 -0
- package/src/modules/i18n/domain/validators/index.ts +52 -0
- package/src/modules/i18n/index.ts +8 -0
- package/src/modules/i18n/ports/locale-loader-port.ts +18 -0
- package/src/modules/i18n/types/locale.ts +17 -0
- package/src/modules/image-optimization/application/sharp-adapter.ts +58 -0
- package/src/modules/image-optimization/domain/events/index.ts +39 -0
- package/src/modules/image-optimization/domain/models/index.ts +27 -0
- package/src/modules/image-optimization/domain/operations/image-operations.ts +65 -0
- package/src/modules/image-optimization/domain/validators/index.ts +52 -0
- package/src/modules/image-optimization/index.ts +8 -0
- package/src/modules/image-optimization/ports/image-optimizer-port.ts +15 -0
- package/src/modules/image-optimization/types/image.ts +17 -0
- package/src/modules/live-editor/application/usecases/index.ts +60 -0
- package/src/modules/live-editor/domain/events/index.ts +37 -0
- package/src/modules/live-editor/domain/gitOperations.ts +110 -0
- package/src/modules/live-editor/domain/index.ts +15 -0
- package/src/modules/live-editor/domain/models/index.ts +21 -0
- package/src/modules/live-editor/domain/validators/index.ts +55 -0
- package/src/modules/live-editor/index.ts +14 -0
- package/src/modules/live-editor/ports/index.ts +49 -0
- package/src/modules/live-editor/types/index.ts +80 -0
- package/src/modules/live-preview/application/vite-preview-adapter.ts +20 -0
- package/src/modules/live-preview/domain/operations/preview-operations.ts +56 -0
- package/src/modules/live-preview/index.ts +8 -0
- package/src/modules/live-preview/ports/preview-port.ts +20 -0
- package/src/modules/live-preview/types/preview.ts +16 -0
- package/src/modules/mdx/application/mdx-js-adapter.ts +38 -0
- package/src/modules/mdx/domain/operations/parse-mdx.ts +43 -0
- package/src/modules/mdx/index.ts +8 -0
- package/src/modules/mdx/ports/mdx-parser-port.ts +15 -0
- package/src/modules/mdx/types/mdx.ts +14 -0
- package/src/modules/navigation/application/usecases/buildNav.ts +15 -0
- package/src/modules/navigation/application/usecases/buildSidebar.ts +45 -0
- package/src/modules/navigation/application/usecases/index.ts +2 -0
- package/src/modules/navigation/domain/events/index.ts +30 -0
- package/src/modules/navigation/domain/models/index.ts +7 -0
- package/src/modules/navigation/domain/operations/group.ts +79 -0
- package/src/modules/navigation/domain/operations/index.ts +10 -0
- package/src/modules/navigation/domain/operations/sort.ts +27 -0
- package/src/modules/navigation/domain/shared/utils/array.ts +39 -0
- package/src/modules/navigation/domain/validators/index.ts +88 -0
- package/src/modules/navigation/index.ts +15 -0
- package/src/modules/navigation/ports/index.ts +9 -0
- package/src/modules/navigation/types/index.ts +38 -0
- package/src/modules/navigation/types/public.ts +9 -0
- package/src/modules/openapi/application/swagger-parser-adapter.ts +178 -0
- package/src/modules/openapi/domain/operations/parse-openapi.ts +46 -0
- package/src/modules/openapi/index.ts +8 -0
- package/src/modules/openapi/ports/openapi-parser-port.ts +15 -0
- package/src/modules/openapi/types/openapi.ts +37 -0
- package/src/modules/plugin/application/usecases/build-virtual-modules.ts +53 -0
- package/src/modules/plugin/application/usecases/index.ts +1 -0
- package/src/modules/plugin/application/workflows/build-docs.ts +79 -0
- package/src/modules/plugin/application/workflows/index.ts +1 -0
- package/src/modules/plugin/domain/events/index.ts +62 -0
- package/src/modules/plugin/domain/models/index.ts +1 -0
- package/src/modules/plugin/domain/operations/build-virtual.ts +76 -0
- package/src/modules/plugin/domain/operations/index.ts +11 -0
- package/src/modules/plugin/domain/validators/index.ts +30 -0
- package/src/modules/plugin/index.ts +14 -0
- package/src/modules/plugin/ports/index.ts +21 -0
- package/src/modules/plugin/types/index.ts +27 -0
- package/src/modules/plugin/types/public.ts +1 -0
- package/src/modules/search/application/usecases/index.ts +1 -0
- package/src/modules/search/application/usecases/indexPages.ts +15 -0
- package/src/modules/search/domain/events/index.ts +32 -0
- package/src/modules/search/domain/models/index.ts +1 -0
- package/src/modules/search/domain/operations/build-index.ts +6 -0
- package/src/modules/search/domain/operations/buildIndex.ts +70 -0
- package/src/modules/search/domain/operations/index.ts +7 -0
- package/src/modules/search/domain/operations/query.ts +186 -0
- package/src/modules/search/domain/validators/index.ts +32 -0
- package/src/modules/search/index.ts +9 -0
- package/src/modules/search/types/index.ts +22 -0
- package/src/modules/search/types/public.ts +1 -0
- package/src/modules/search-analytics/application/local-storage-adapter.ts +68 -0
- package/src/modules/search-analytics/domain/operations/search-analytics-operations.ts +74 -0
- package/src/modules/search-analytics/index.ts +8 -0
- package/src/modules/search-analytics/ports/search-analytics-port.ts +20 -0
- package/src/modules/search-analytics/types/search-analytics.ts +16 -0
- package/src/modules/search-highlighting/application/dom-highlighting-adapter.ts +36 -0
- package/src/modules/search-highlighting/domain/operations/highlighting-operations.ts +72 -0
- package/src/modules/search-highlighting/index.ts +8 -0
- package/src/modules/search-highlighting/ports/highlighting-port.ts +14 -0
- package/src/modules/search-highlighting/types/highlighting.ts +15 -0
- package/src/modules/seo-optimization/application/usecases/index.ts +18 -0
- package/src/modules/seo-optimization/domain/index.ts +12 -0
- package/src/modules/seo-optimization/domain/seoOperations.ts +92 -0
- package/src/modules/seo-optimization/index.ts +8 -0
- package/src/modules/seo-optimization/ports/index.ts +18 -0
- package/src/modules/seo-optimization/types/index.ts +41 -0
- package/src/modules/theme/application/css-theme-adapter.ts +50 -0
- package/src/modules/theme/domain/operations/theme-operations.ts +68 -0
- package/src/modules/theme/index.ts +8 -0
- package/src/modules/theme/ports/theme-port.ts +8 -0
- package/src/modules/theme/types/theme.ts +12 -0
- package/src/modules/toc/application/markdown-toc-adapter.ts +106 -0
- package/src/modules/toc/domain/operations/toc-operations.ts +92 -0
- package/src/modules/toc/index.ts +8 -0
- package/src/modules/toc/ports/toc-port.ts +21 -0
- package/src/modules/toc/types/toc.ts +17 -0
- package/src/modules/toc-generator/application/usecases/index.ts +30 -0
- package/src/modules/toc-generator/domain/index.ts +12 -0
- package/src/modules/toc-generator/domain/tocOperations.ts +104 -0
- package/src/modules/toc-generator/index.ts +9 -0
- package/src/modules/toc-generator/ports/index.ts +20 -0
- package/src/modules/toc-generator/types/index.ts +50 -0
- package/src/modules/version-control/domain/events/index.ts +39 -0
- package/src/modules/version-control/domain/models/index.ts +25 -0
- package/src/modules/version-control/domain/validators/index.ts +50 -0
- package/src/modules/versioning/application/fs-version-loader.ts +44 -0
- package/src/modules/versioning/domain/operations/versioning-operations.ts +80 -0
- package/src/modules/versioning/index.ts +8 -0
- package/src/modules/versioning/ports/version-loader-port.ts +18 -0
- package/src/modules/versioning/types/versioning.ts +17 -0
- package/src/modules/workflow/domain/events/index.ts +55 -0
- package/src/modules/workflow/domain/models/index.ts +40 -0
- package/src/modules/workflow/domain/validators/index.ts +50 -0
- package/src/modules/yaml-parser/application/js-yaml-adapter.ts +34 -0
- package/src/modules/yaml-parser/domain/operations/parse-yaml.ts +58 -0
- package/src/modules/yaml-parser/index.ts +7 -0
- package/src/modules/yaml-parser/ports/yaml-parser-port.ts +18 -0
- package/src/navigation/index.ts +9 -0
- package/src/plugin/index.ts +4 -0
- package/src/presentation/index.ts +1 -0
- package/src/presentation/live-editor/index.ts +22 -0
- package/src/presentation/live-editor/live-editor-component.ts +219 -0
- package/src/presentation/live-editor/virtual-module.ts +16 -0
- package/src/presentation/solid/CodeBlock.tsx +120 -0
- package/src/presentation/solid/Toc.tsx +58 -0
- package/src/presentation/solid/index.ts +11 -0
- package/src/presentation/vite-plugin/docs-plugin.ts +212 -0
- package/src/presentation/vite-plugin/index.ts +9 -0
- package/src/presentation/vite-plugin/transform-markdown.ts +26 -0
- package/src/runtime/analytics.ts +59 -0
- package/src/runtime/api-diff.ts +115 -0
- package/src/runtime/app.tsx +32 -0
- package/src/runtime/components/AccentPicker.tsx +114 -0
- package/src/runtime/components/ApiPlayground.tsx +332 -0
- package/src/runtime/components/AskAiDialog.tsx +127 -0
- package/src/runtime/components/BackToTop.tsx +38 -0
- package/src/runtime/components/Banner.tsx +75 -0
- package/src/runtime/components/Breadcrumbs.tsx +42 -0
- package/src/runtime/components/CollectionDropdown.tsx +85 -0
- package/src/runtime/components/CustomizeDrawer.tsx +195 -0
- package/src/runtime/components/DocMarkdown.tsx +579 -0
- package/src/runtime/components/DocPrevNext.tsx +54 -0
- package/src/runtime/components/DocToc.tsx +147 -0
- package/src/runtime/components/DocsDropdown.tsx +184 -0
- package/src/runtime/components/Footer.tsx +52 -0
- package/src/runtime/components/GitHubAuth.tsx +82 -0
- package/src/runtime/components/GitHubStats.tsx +73 -0
- package/src/runtime/components/Head.tsx +225 -0
- package/src/runtime/components/LocaleDropdown.tsx +75 -0
- package/src/runtime/components/MobileBottomNav.tsx +111 -0
- package/src/runtime/components/NotFound.tsx +139 -0
- package/src/runtime/components/PageActions.tsx +144 -0
- package/src/runtime/components/RelatedDocs.tsx +50 -0
- package/src/runtime/components/ScrollProgress.tsx +32 -0
- package/src/runtime/components/SearchPalette.tsx +333 -0
- package/src/runtime/components/ShowcaseCard.tsx +87 -0
- package/src/runtime/components/SidebarNav.tsx +237 -0
- package/src/runtime/components/Skeleton.tsx +39 -0
- package/src/runtime/components/ThemeToggle.tsx +26 -0
- package/src/runtime/components/TopNav.tsx +270 -0
- package/src/runtime/components/VersionDropdown.tsx +189 -0
- package/src/runtime/components/markdown/components.ts +280 -0
- package/src/runtime/config.ts +225 -0
- package/src/runtime/content.ts +451 -0
- package/src/runtime/context.tsx +30 -0
- package/src/runtime/data.ts +93 -0
- package/src/runtime/github.ts +226 -0
- package/src/runtime/icons.ts +32 -0
- package/src/runtime/index.ts +153 -0
- package/src/runtime/layouts/DocsLayout.tsx +144 -0
- package/src/runtime/markdown-content.css +996 -0
- package/src/runtime/pages/AbTestPage.tsx +88 -0
- package/src/runtime/pages/AnalyticsPage.tsx +90 -0
- package/src/runtime/pages/ApiDiffPage.tsx +86 -0
- package/src/runtime/pages/ApiEndpointPage.tsx +248 -0
- package/src/runtime/pages/BuilderPage.tsx +150 -0
- package/src/runtime/pages/ChangelogPage.tsx +210 -0
- package/src/runtime/pages/CollectionPage.tsx +140 -0
- package/src/runtime/pages/CommunityPage.tsx +384 -0
- package/src/runtime/pages/CreatePage.tsx +448 -0
- package/src/runtime/pages/DocPage.tsx +193 -0
- package/src/runtime/pages/EditPage.tsx +201 -0
- package/src/runtime/pages/HomePage.tsx +187 -0
- package/src/runtime/pages/IssuesPage.tsx +140 -0
- package/src/runtime/pages/OAuthCallbackPage.tsx +80 -0
- package/src/runtime/pages/PluginsPage.tsx +249 -0
- package/src/runtime/pages/ShowcasePage.tsx +202 -0
- package/src/runtime/pwa.ts +39 -0
- package/src/runtime/router.tsx +192 -0
- package/src/runtime/seo.ts +192 -0
- package/src/runtime/theme.css +175 -0
- package/src/runtime/theme.ts +224 -0
- package/src/runtime/types.ts +217 -0
- package/src/search/index.ts +6 -0
- package/src/seo-optimization/index.ts +4 -0
- package/src/shared/constants/index.ts +26 -0
- package/src/shared/errors/index.ts +195 -0
- package/src/shared/index.ts +27 -0
- package/src/shared/types/brand.ts +14 -0
- package/src/shared/types/client.d.ts +45 -0
- package/src/shared/types/either.ts +38 -0
- package/src/shared/types/index.ts +42 -0
- package/src/shared/types/option.ts +52 -0
- package/src/shared/types/result.ts +81 -0
- package/src/shared/utils/array.ts +97 -0
- package/src/shared/utils/index.ts +46 -0
- package/src/shared/utils/object.ts +47 -0
- package/src/shared/utils/string.ts +74 -0
- package/src/toc-generator/index.ts +1 -0
- package/src/types/js-yaml.d.ts +42 -0
- package/src/worker.ts +462 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Workflow Domain Schemas - Arktype validation schemas
|
|
2
|
+
// Following /follow-arktype workflow for type-safe runtime validation
|
|
3
|
+
|
|
4
|
+
import { type Type, type } from "arktype";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Step Name Schema
|
|
8
|
+
*/
|
|
9
|
+
export const stepNameSchema: Type = type("string >= 1");
|
|
10
|
+
|
|
11
|
+
export type StepName = typeof stepNameSchema.infer;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Workflow Name Schema
|
|
15
|
+
*/
|
|
16
|
+
export const workflowNameSchema: Type = type("string >= 1");
|
|
17
|
+
|
|
18
|
+
export type WorkflowName = typeof workflowNameSchema.infer;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Validation errors
|
|
22
|
+
*/
|
|
23
|
+
export class ValidationError extends Error {
|
|
24
|
+
constructor(message: string) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = "ValidationError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validate step name using Arktype
|
|
32
|
+
*/
|
|
33
|
+
export const validateStepName = (name: unknown): StepName => {
|
|
34
|
+
const result = stepNameSchema(name);
|
|
35
|
+
if (result instanceof type.errors) {
|
|
36
|
+
throw new ValidationError("Step name must be a non-empty string");
|
|
37
|
+
}
|
|
38
|
+
return result as StepName;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validate workflow name using Arktype
|
|
43
|
+
*/
|
|
44
|
+
export const validateWorkflowName = (name: unknown): WorkflowName => {
|
|
45
|
+
const result = workflowNameSchema(name);
|
|
46
|
+
if (result instanceof type.errors) {
|
|
47
|
+
throw new ValidationError("Workflow name must be a non-empty string");
|
|
48
|
+
}
|
|
49
|
+
return result as WorkflowName;
|
|
50
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* js-yaml adapter implementation.
|
|
3
|
+
* Provides full YAML 1.2 support with safe mode.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ioError, parseError } from "@create-docs/shared/errors";
|
|
7
|
+
import yaml from "js-yaml";
|
|
8
|
+
import type { YamlParserPort } from "../ports/yaml-parser-port";
|
|
9
|
+
|
|
10
|
+
export const createJsYamlAdapter = (): YamlParserPort => ({
|
|
11
|
+
parse: async (raw: string) => {
|
|
12
|
+
try {
|
|
13
|
+
return yaml.load(raw, {
|
|
14
|
+
schema: yaml.DEFAULT_SCHEMA,
|
|
15
|
+
// Safe mode - no eval, no function scalars
|
|
16
|
+
});
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw parseError("<input>", "YAML parsing failed", error);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
stringify: async (value: unknown) => {
|
|
23
|
+
try {
|
|
24
|
+
return yaml.dump(value, {
|
|
25
|
+
schema: yaml.DEFAULT_SCHEMA,
|
|
26
|
+
indent: 2,
|
|
27
|
+
lineWidth: -1,
|
|
28
|
+
noRefs: true,
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
throw ioError("<output>", "YAML stringification failed", error);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure YAML 1.2 parser operations.
|
|
3
|
+
* No I/O. No exceptions thrown. Returns Result types.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Result } from "@create-docs/shared/types";
|
|
7
|
+
import { err, ok } from "@create-docs/shared/types";
|
|
8
|
+
import { dump, JSON_SCHEMA, load, YAMLException } from "js-yaml";
|
|
9
|
+
|
|
10
|
+
export type YamlParseError = {
|
|
11
|
+
readonly kind: "yaml-parse-error";
|
|
12
|
+
readonly message: string;
|
|
13
|
+
readonly line?: number;
|
|
14
|
+
readonly column?: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parse YAML string with safe YAML 1.2 schema.
|
|
19
|
+
*/
|
|
20
|
+
export const parseYaml = (raw: string): Result<unknown, YamlParseError> => {
|
|
21
|
+
try {
|
|
22
|
+
const value = load(raw, { schema: JSON_SCHEMA });
|
|
23
|
+
return ok(value);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
26
|
+
const line = error instanceof YAMLException ? error.mark?.line : undefined;
|
|
27
|
+
const column =
|
|
28
|
+
error instanceof YAMLException ? error.mark?.column : undefined;
|
|
29
|
+
return err({
|
|
30
|
+
kind: "yaml-parse-error",
|
|
31
|
+
message,
|
|
32
|
+
line,
|
|
33
|
+
column,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Stringify object to YAML.
|
|
40
|
+
*/
|
|
41
|
+
export const stringifyYaml = (
|
|
42
|
+
value: unknown,
|
|
43
|
+
): Result<string, YamlParseError> => {
|
|
44
|
+
try {
|
|
45
|
+
const result = dump(value, {
|
|
46
|
+
schema: JSON_SCHEMA,
|
|
47
|
+
indent: 2,
|
|
48
|
+
lineWidth: -1,
|
|
49
|
+
noRefs: true,
|
|
50
|
+
});
|
|
51
|
+
return ok(result);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return err({
|
|
54
|
+
kind: "yaml-parse-error",
|
|
55
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port for YAML parsing operations.
|
|
3
|
+
* Defines the interface for YAML adapter implementations.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type YamlParserPort = {
|
|
7
|
+
/**
|
|
8
|
+
* Parse YAML string with full YAML 1.2 support.
|
|
9
|
+
* Safe mode enabled - no eval, no function scalars.
|
|
10
|
+
*/
|
|
11
|
+
readonly parse: (raw: string) => Promise<unknown>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Stringify object to YAML with full YAML 1.2 support.
|
|
15
|
+
* Safe mode enabled - no eval, no function scalars.
|
|
16
|
+
*/
|
|
17
|
+
readonly stringify: (value: unknown) => Promise<string>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type NavItem = unknown;
|
|
2
|
+
export type NavSection = unknown;
|
|
3
|
+
export type Sidebar = unknown;
|
|
4
|
+
export type SidebarGroup = unknown;
|
|
5
|
+
export type SidebarItem = unknown;
|
|
6
|
+
export const buildNav = () => null;
|
|
7
|
+
export const buildSidebar = () => null;
|
|
8
|
+
export const formatGroupTitle = () => null;
|
|
9
|
+
export const groupDocsByFolder = () => null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./vite-plugin";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Editor Presentation
|
|
3
|
+
*
|
|
4
|
+
* Presentation layer for live editor with Git integration
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
createLiveEditorState,
|
|
9
|
+
type EditorMode,
|
|
10
|
+
type LiveEditorOptions,
|
|
11
|
+
type LiveEditorState,
|
|
12
|
+
liveEditorAttachEventListeners,
|
|
13
|
+
liveEditorDestroy,
|
|
14
|
+
liveEditorInitEditor,
|
|
15
|
+
liveEditorRender,
|
|
16
|
+
liveEditorSetMode,
|
|
17
|
+
liveEditorUpdateGitStatus,
|
|
18
|
+
} from "./live-editor-component";
|
|
19
|
+
export {
|
|
20
|
+
LIVE_EDITOR_MODULE_ID,
|
|
21
|
+
liveEditorVirtualModuleCode,
|
|
22
|
+
} from "./virtual-module";
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Editor Component (Vanilla JS)
|
|
3
|
+
*
|
|
4
|
+
* Live editor with split view (preview/edit) using CodeMirror
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { basicSetup } from "@codemirror/basic-setup";
|
|
8
|
+
import { markdown } from "@codemirror/lang-markdown";
|
|
9
|
+
import { EditorState } from "@codemirror/state";
|
|
10
|
+
import { EditorView } from "@codemirror/view";
|
|
11
|
+
import type { CommitOptions, GitStatus } from "../../modules/live-editor/types";
|
|
12
|
+
|
|
13
|
+
export interface LiveEditorOptions {
|
|
14
|
+
/** Container element */
|
|
15
|
+
container: HTMLElement;
|
|
16
|
+
/** Initial content */
|
|
17
|
+
initialContent: string;
|
|
18
|
+
/** Git status */
|
|
19
|
+
gitStatus?: GitStatus;
|
|
20
|
+
/** On save callback */
|
|
21
|
+
onSave?: (content: string) => Promise<void>;
|
|
22
|
+
/** On commit callback */
|
|
23
|
+
onCommit?: (options: CommitOptions) => Promise<void>;
|
|
24
|
+
/** On push callback */
|
|
25
|
+
onPush?: () => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type EditorMode = "preview" | "edit" | "split";
|
|
29
|
+
|
|
30
|
+
// Live editor state
|
|
31
|
+
export interface LiveEditorState {
|
|
32
|
+
readonly container: HTMLElement;
|
|
33
|
+
readonly editorView: EditorView | null;
|
|
34
|
+
readonly previewElement: HTMLElement;
|
|
35
|
+
readonly content: string;
|
|
36
|
+
readonly gitStatus?: GitStatus;
|
|
37
|
+
readonly onSave?: (content: string) => Promise<void>;
|
|
38
|
+
readonly onCommit?: (options: CommitOptions) => Promise<void>;
|
|
39
|
+
readonly onPush?: () => Promise<void>;
|
|
40
|
+
readonly mode: EditorMode;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const createLiveEditorState = (
|
|
44
|
+
options: LiveEditorOptions,
|
|
45
|
+
): LiveEditorState => ({
|
|
46
|
+
container: options.container,
|
|
47
|
+
editorView: null,
|
|
48
|
+
previewElement: document.createElement("div"),
|
|
49
|
+
content: options.initialContent,
|
|
50
|
+
gitStatus: options.gitStatus,
|
|
51
|
+
onSave: options.onSave,
|
|
52
|
+
onCommit: options.onCommit,
|
|
53
|
+
onPush: options.onPush,
|
|
54
|
+
mode: "split",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const liveEditorRender = (state: LiveEditorState): LiveEditorState => {
|
|
58
|
+
state.container.innerHTML = "";
|
|
59
|
+
|
|
60
|
+
// Toolbar
|
|
61
|
+
const toolbar = document.createElement("div");
|
|
62
|
+
toolbar.className = "live-editor-toolbar";
|
|
63
|
+
toolbar.innerHTML = `
|
|
64
|
+
<div class="toolbar-left">
|
|
65
|
+
<button data-mode="preview" class="${state.mode === "preview" ? "active" : ""}">Preview</button>
|
|
66
|
+
<button data-mode="edit" class="${state.mode === "edit" ? "active" : ""}">Edit</button>
|
|
67
|
+
<button data-mode="split" class="${state.mode === "split" ? "active" : ""}">Split</button>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="toolbar-right">
|
|
70
|
+
${state.gitStatus ? `<span class="git-status">${state.gitStatus.branch} ${state.gitStatus.hasChanges ? "(modified)" : ""}</span>` : ""}
|
|
71
|
+
<button class="save-btn">Save</button>
|
|
72
|
+
<button class="commit-btn">Commit</button>
|
|
73
|
+
<button class="push-btn">Push</button>
|
|
74
|
+
</div>
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
// Commit input
|
|
78
|
+
const commitInput = document.createElement("div");
|
|
79
|
+
commitInput.className = "commit-input";
|
|
80
|
+
commitInput.innerHTML = `
|
|
81
|
+
<input type="text" placeholder="Commit message..." class="commit-message-input">
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
// Content area
|
|
85
|
+
const contentArea = document.createElement("div");
|
|
86
|
+
contentArea.className = `live-editor-content mode-${state.mode}`;
|
|
87
|
+
|
|
88
|
+
// Editor pane
|
|
89
|
+
const editorPane = document.createElement("div");
|
|
90
|
+
editorPane.className = "editor-pane";
|
|
91
|
+
|
|
92
|
+
// Preview pane
|
|
93
|
+
const previewElement = document.createElement("div");
|
|
94
|
+
previewElement.className = "preview-pane";
|
|
95
|
+
previewElement.innerHTML = state.content;
|
|
96
|
+
|
|
97
|
+
contentArea.appendChild(editorPane);
|
|
98
|
+
contentArea.appendChild(previewElement);
|
|
99
|
+
|
|
100
|
+
state.container.appendChild(toolbar);
|
|
101
|
+
state.container.appendChild(commitInput);
|
|
102
|
+
state.container.appendChild(contentArea);
|
|
103
|
+
|
|
104
|
+
// Initialize CodeMirror
|
|
105
|
+
const editorView = liveEditorInitEditor(state, editorPane);
|
|
106
|
+
|
|
107
|
+
// Event listeners
|
|
108
|
+
liveEditorAttachEventListeners(state, toolbar, commitInput);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...state,
|
|
112
|
+
editorView,
|
|
113
|
+
previewElement,
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const liveEditorInitEditor = (
|
|
118
|
+
state: LiveEditorState,
|
|
119
|
+
container: HTMLElement,
|
|
120
|
+
): EditorView => {
|
|
121
|
+
const editorState = EditorState.create({
|
|
122
|
+
doc: state.content,
|
|
123
|
+
extensions: [basicSetup, markdown()],
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const editorView = new EditorView({
|
|
127
|
+
state: editorState,
|
|
128
|
+
parent: container,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
editorView.contentDOM.addEventListener("input", () => {
|
|
132
|
+
// Content update would be handled by state update
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return editorView;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export const liveEditorAttachEventListeners = (
|
|
139
|
+
state: LiveEditorState,
|
|
140
|
+
toolbar: HTMLElement,
|
|
141
|
+
commitInput: HTMLElement,
|
|
142
|
+
): void => {
|
|
143
|
+
// Mode buttons
|
|
144
|
+
toolbar.querySelectorAll("[data-mode]").forEach((btn) => {
|
|
145
|
+
btn.addEventListener("click", (e) => {
|
|
146
|
+
void ((e.target as HTMLElement).dataset.mode as EditorMode);
|
|
147
|
+
// Mode change would be handled by state update
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Save button
|
|
152
|
+
toolbar.querySelector(".save-btn")?.addEventListener("click", async () => {
|
|
153
|
+
if (state.onSave) {
|
|
154
|
+
await state.onSave(state.content);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Commit button
|
|
159
|
+
toolbar.querySelector(".commit-btn")?.addEventListener("click", async () => {
|
|
160
|
+
const input = commitInput.querySelector(
|
|
161
|
+
".commit-message-input",
|
|
162
|
+
) as HTMLInputElement;
|
|
163
|
+
const message = input.value;
|
|
164
|
+
if (state.onCommit && message) {
|
|
165
|
+
await state.onCommit({ message });
|
|
166
|
+
input.value = "";
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Push button
|
|
171
|
+
toolbar.querySelector(".push-btn")?.addEventListener("click", async () => {
|
|
172
|
+
if (state.onPush) {
|
|
173
|
+
await state.onPush();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export const liveEditorSetMode = (
|
|
179
|
+
state: LiveEditorState,
|
|
180
|
+
mode: EditorMode,
|
|
181
|
+
): LiveEditorState => {
|
|
182
|
+
const contentArea = state.container.querySelector(
|
|
183
|
+
".live-editor-content",
|
|
184
|
+
) as HTMLElement;
|
|
185
|
+
contentArea.className = `live-editor-content mode-${mode}`;
|
|
186
|
+
|
|
187
|
+
// Update active button
|
|
188
|
+
state.container.querySelectorAll("[data-mode]").forEach((btn) => {
|
|
189
|
+
const btnMode = (btn as HTMLElement).dataset.mode;
|
|
190
|
+
if (btnMode) {
|
|
191
|
+
(btn as HTMLElement).classList.toggle("active", btnMode === mode);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
...state,
|
|
197
|
+
mode,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const liveEditorUpdateGitStatus = (
|
|
202
|
+
state: LiveEditorState,
|
|
203
|
+
status: GitStatus,
|
|
204
|
+
): LiveEditorState => {
|
|
205
|
+
const statusEl = state.container.querySelector(".git-status");
|
|
206
|
+
if (statusEl) {
|
|
207
|
+
statusEl.textContent = `${status.branch} ${status.hasChanges ? "(modified)" : ""}`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
...state,
|
|
212
|
+
gitStatus: status,
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const liveEditorDestroy = (state: LiveEditorState): void => {
|
|
217
|
+
state.editorView?.destroy();
|
|
218
|
+
state.container.innerHTML = "";
|
|
219
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Editor Virtual Module
|
|
3
|
+
*
|
|
4
|
+
* Virtual module that provides live editor UI components
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const LIVE_EDITOR_MODULE_ID = "virtual:create-docs-live-editor";
|
|
8
|
+
|
|
9
|
+
export const liveEditorVirtualModuleCode = `
|
|
10
|
+
import { loader } from '@monaco-editor/react';
|
|
11
|
+
import * as monaco from 'monaco-editor';
|
|
12
|
+
|
|
13
|
+
loader.config({ monaco });
|
|
14
|
+
|
|
15
|
+
export { default } from './live-editor-component';
|
|
16
|
+
`;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solid CodeBlock Component
|
|
3
|
+
*
|
|
4
|
+
* Code block component with syntax highlighting and copy functionality
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createSignal, For, onMount, Show } from "solid-js";
|
|
8
|
+
import type { CodeBlockOptions } from "../../modules/code-block-enhancements";
|
|
9
|
+
|
|
10
|
+
export interface CodeBlockProps extends CodeBlockOptions {
|
|
11
|
+
/** Code content */
|
|
12
|
+
code: string;
|
|
13
|
+
/** Language */
|
|
14
|
+
language?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const CodeBlock = (props: CodeBlockProps) => {
|
|
18
|
+
const [copied, setCopied] = createSignal(false);
|
|
19
|
+
const [highlightedCode, setHighlightedCode] = createSignal("");
|
|
20
|
+
|
|
21
|
+
const handleCopy = async () => {
|
|
22
|
+
try {
|
|
23
|
+
await navigator.clipboard.writeText(props.code);
|
|
24
|
+
setCopied(true);
|
|
25
|
+
setTimeout(() => setCopied(false), 2000);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error("Failed to copy code:", err);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
onMount(() => {
|
|
32
|
+
// Lightweight syntax highlighter. For full language support add Shiki.
|
|
33
|
+
let highlighted = props.code
|
|
34
|
+
.replace(/&/g, "&")
|
|
35
|
+
.replace(/</g, "<")
|
|
36
|
+
.replace(/>/g, ">");
|
|
37
|
+
|
|
38
|
+
// Simple keyword highlighting for common languages
|
|
39
|
+
if (props.language === "typescript" || props.language === "ts") {
|
|
40
|
+
highlighted = highlighted
|
|
41
|
+
.replace(
|
|
42
|
+
/\b(const|let|var|function|return|if|else|for|while|import|export|from|interface|type|class|extends|implements)\b/g,
|
|
43
|
+
'<span class="keyword">$1</span>',
|
|
44
|
+
)
|
|
45
|
+
.replace(
|
|
46
|
+
/\b(string|number|boolean|void|any|never)\b/g,
|
|
47
|
+
'<span class="type">$1</span>',
|
|
48
|
+
);
|
|
49
|
+
} else if (props.language === "javascript" || props.language === "js") {
|
|
50
|
+
highlighted = highlighted.replace(
|
|
51
|
+
/\b(const|let|var|function|return|if|else|for|while|import|export|from|class|extends)\b/g,
|
|
52
|
+
'<span class="keyword">$1</span>',
|
|
53
|
+
);
|
|
54
|
+
} else if (props.language === "json") {
|
|
55
|
+
highlighted = highlighted
|
|
56
|
+
.replace(/"([^"\\]*)"/g, '<span class="string">"$1"</span>')
|
|
57
|
+
.replace(/\b(true|false|null)\b/g, '<span class="keyword">$1</span>');
|
|
58
|
+
} else if (props.language === "bash" || props.language === "shell") {
|
|
59
|
+
highlighted = highlighted.replace(
|
|
60
|
+
/(^|\s)(bun|npm|pnpm|yarn|node|cd|ls|cat|mkdir|rm|cp|mv|git)(?=\s|$)/g,
|
|
61
|
+
'$1<span class="keyword">$2</span>',
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
setHighlightedCode(highlighted);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const lineNumbers = () => {
|
|
69
|
+
if (!props.lineNumbers) return null;
|
|
70
|
+
const lines = props.code.split("\n");
|
|
71
|
+
return (
|
|
72
|
+
<div class="code-block-line-numbers">
|
|
73
|
+
<For each={lines}>
|
|
74
|
+
{(_, i) => <div class="line-number">{i() + 1}</div>}
|
|
75
|
+
</For>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const highlightLines = () => {
|
|
81
|
+
if (!props.highlightLines || props.highlightLines.length === 0) return "";
|
|
82
|
+
return props.highlightLines.map((line) => `.line-${line}`).join(", ");
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
class="code-block"
|
|
88
|
+
classList={{
|
|
89
|
+
"code-block-dark": props.theme === "dark" || props.theme === "auto",
|
|
90
|
+
}}
|
|
91
|
+
>
|
|
92
|
+
<Show when={props.filename || props.copyButton !== false}>
|
|
93
|
+
<div class="code-block-header">
|
|
94
|
+
<Show when={props.filename}>
|
|
95
|
+
<span class="code-block-filename">{props.filename}</span>
|
|
96
|
+
</Show>
|
|
97
|
+
<Show when={props.copyButton !== false}>
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
class="code-block-copy"
|
|
101
|
+
onClick={handleCopy}
|
|
102
|
+
aria-label={copied() ? "Copied!" : "Copy code"}
|
|
103
|
+
>
|
|
104
|
+
{copied() ? "✓" : "📋"}
|
|
105
|
+
</button>
|
|
106
|
+
</Show>
|
|
107
|
+
</div>
|
|
108
|
+
</Show>
|
|
109
|
+
<div class="code-block-content">
|
|
110
|
+
{lineNumbers()}
|
|
111
|
+
<pre class="code-block-pre">
|
|
112
|
+
<code
|
|
113
|
+
class={`code-block-code language-${props.language || "text"} ${highlightLines()}`}
|
|
114
|
+
innerHTML={highlightedCode()}
|
|
115
|
+
/>
|
|
116
|
+
</pre>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solid TOC Component
|
|
3
|
+
*
|
|
4
|
+
* Table of contents component for Solid
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { For, Show } from "solid-js";
|
|
8
|
+
import type { TocItem } from "../../modules/toc-generator";
|
|
9
|
+
|
|
10
|
+
export interface TocProps {
|
|
11
|
+
/** TOC items */
|
|
12
|
+
items: TocItem[];
|
|
13
|
+
/** Active item ID */
|
|
14
|
+
activeId?: string;
|
|
15
|
+
/** On item click */
|
|
16
|
+
onItemClick?: (id: string) => void;
|
|
17
|
+
/** Max depth to show */
|
|
18
|
+
maxDepth?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const Toc = (props: TocProps) => {
|
|
22
|
+
const renderItem = (item: TocItem, depth = 0) => {
|
|
23
|
+
if (depth >= (props.maxDepth || 6)) return null;
|
|
24
|
+
|
|
25
|
+
const isActive = () => props.activeId === item.id;
|
|
26
|
+
const hasChildren = () => item.children && item.children.length > 0;
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<li class={`toc-item toc-level-${item.level}`}>
|
|
30
|
+
<a
|
|
31
|
+
href={`#${item.id}`}
|
|
32
|
+
class={`toc-link ${isActive() ? "toc-link-active" : ""}`}
|
|
33
|
+
onClick={(e) => {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
props.onItemClick?.(item.id);
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
{item.text}
|
|
39
|
+
</a>
|
|
40
|
+
<Show when={hasChildren()}>
|
|
41
|
+
<ul class="toc-children">
|
|
42
|
+
<For each={item.children}>
|
|
43
|
+
{(child) => <>{renderItem(child, depth + 1)}</>}
|
|
44
|
+
</For>
|
|
45
|
+
</ul>
|
|
46
|
+
</Show>
|
|
47
|
+
</li>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<nav class="toc">
|
|
53
|
+
<ul class="toc-list">
|
|
54
|
+
<For each={props.items}>{(item) => <>{renderItem(item)}</>}</For>
|
|
55
|
+
</ul>
|
|
56
|
+
</nav>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solid Presentation Components
|
|
3
|
+
*
|
|
4
|
+
* Framework-specific UI components for Solid
|
|
5
|
+
*
|
|
6
|
+
* Note: Components are .tsx files and should be imported directly in Solid projects
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type { TocItem } from "../../modules/toc-generator";
|
|
10
|
+
export { CodeBlock } from "./CodeBlock";
|
|
11
|
+
export { Toc } from "./Toc";
|