@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,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time GitHub docs puller.
|
|
3
|
+
*
|
|
4
|
+
* Given a list of remote GitHub repositories (or local directories), fetch the
|
|
5
|
+
* docs tree and write markdown + frontmatter files to a local directory. The
|
|
6
|
+
* output is consumed by `createStaticDataSource()` in the Solid runtime: files
|
|
7
|
+
* are organised under `docs/{collectionId}/...` and `sources.json` /
|
|
8
|
+
* `manifest.json` are emitted next to them.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
mkdirSync,
|
|
13
|
+
readdirSync,
|
|
14
|
+
readFileSync,
|
|
15
|
+
statSync,
|
|
16
|
+
writeFileSync,
|
|
17
|
+
} from "node:fs";
|
|
18
|
+
import * as path from "node:path";
|
|
19
|
+
import { parseFrontmatter } from "../../runtime/content";
|
|
20
|
+
|
|
21
|
+
export interface GitHubSource {
|
|
22
|
+
/** Collection id used in the URL and sidebar. */
|
|
23
|
+
id: string;
|
|
24
|
+
/** Human-readable label. Defaults to the repo name. */
|
|
25
|
+
label?: string;
|
|
26
|
+
/** Short description for the collection. */
|
|
27
|
+
description?: string;
|
|
28
|
+
/** Repository URL or `owner/repo`. */
|
|
29
|
+
repo: string;
|
|
30
|
+
/** Branch or tag. */
|
|
31
|
+
branch?: string;
|
|
32
|
+
/** Path inside the repo where the docs live. Defaults to `docs`. */
|
|
33
|
+
docsDir?: string;
|
|
34
|
+
/** Iconify icon class. */
|
|
35
|
+
icon?: string;
|
|
36
|
+
/** Optional local docs directory; when set, files are copied instead of fetching from GitHub. */
|
|
37
|
+
localDir?: string;
|
|
38
|
+
/** When true, continue with a warning if this source cannot be fetched. */
|
|
39
|
+
optional?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface GitHubPullOptions {
|
|
43
|
+
/** Output directory for pulled docs and the generated manifest. */
|
|
44
|
+
outDir: string;
|
|
45
|
+
/** GitHub sources. */
|
|
46
|
+
sources: GitHubSource[];
|
|
47
|
+
/** Optional token for private repositories and higher rate limits. */
|
|
48
|
+
token?: string;
|
|
49
|
+
/** Optional GitHub API base URL. */
|
|
50
|
+
apiBase?: string;
|
|
51
|
+
/** Optional raw base URL. */
|
|
52
|
+
rawBase?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface PullResult {
|
|
56
|
+
/** Collection metadata written to `sources.json`. */
|
|
57
|
+
collections: Array<{
|
|
58
|
+
id: string;
|
|
59
|
+
label: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
icon?: string;
|
|
62
|
+
repoUrl?: string;
|
|
63
|
+
}>;
|
|
64
|
+
/** Number of files written. */
|
|
65
|
+
filesWritten: number;
|
|
66
|
+
/** Output directory. */
|
|
67
|
+
outDir: string;
|
|
68
|
+
/** Manifest for SEO and server-side consumers. */
|
|
69
|
+
manifest: DocsManifest;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface DocsManifest {
|
|
73
|
+
collections: PullResult["collections"];
|
|
74
|
+
docs: Record<
|
|
75
|
+
string,
|
|
76
|
+
Array<{
|
|
77
|
+
id: string;
|
|
78
|
+
label: string;
|
|
79
|
+
category: string;
|
|
80
|
+
description: string;
|
|
81
|
+
path: string;
|
|
82
|
+
type: "md";
|
|
83
|
+
}>
|
|
84
|
+
>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface RepoRef {
|
|
88
|
+
owner: string;
|
|
89
|
+
name: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function parseRepo(repo: string): RepoRef {
|
|
93
|
+
const clean = repo
|
|
94
|
+
.replace(/https?:\/\/github\.com\//, "")
|
|
95
|
+
.replace(/\.git$/, "");
|
|
96
|
+
const parts = clean.split("/");
|
|
97
|
+
if (parts.length < 2) {
|
|
98
|
+
throw new Error(`Invalid repo: ${repo}`);
|
|
99
|
+
}
|
|
100
|
+
return { owner: parts[0] as string, name: parts[1] as string };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function authHeaders(token?: string): Record<string, string> {
|
|
104
|
+
const headers: Record<string, string> = {
|
|
105
|
+
Accept: "application/vnd.github+json",
|
|
106
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
107
|
+
"User-Agent": "create-docs",
|
|
108
|
+
};
|
|
109
|
+
if (token) {
|
|
110
|
+
headers.Authorization = `Bearer ${token}`;
|
|
111
|
+
}
|
|
112
|
+
return headers;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function toPosix(p: string): string {
|
|
116
|
+
return p.replace(/\\/g, "/");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function relativeWithinDocs(filePath: string, docsDir: string): string {
|
|
120
|
+
const normalized = toPosix(filePath).replace(/^\//, "");
|
|
121
|
+
const prefix = toPosix(docsDir).replace(/\/$/, "").replace(/^\//, "");
|
|
122
|
+
if (
|
|
123
|
+
prefix &&
|
|
124
|
+
(normalized === prefix || normalized.startsWith(`${prefix}/`))
|
|
125
|
+
) {
|
|
126
|
+
return normalized.slice(prefix.length + (prefix ? 1 : 0));
|
|
127
|
+
}
|
|
128
|
+
return normalized;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface TreeItem {
|
|
132
|
+
path: string;
|
|
133
|
+
mode: string;
|
|
134
|
+
type: string;
|
|
135
|
+
sha: string;
|
|
136
|
+
size?: number;
|
|
137
|
+
url: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function fetchTree(
|
|
141
|
+
ref: RepoRef,
|
|
142
|
+
branch: string,
|
|
143
|
+
token: string | undefined,
|
|
144
|
+
apiBase: string,
|
|
145
|
+
): Promise<TreeItem[]> {
|
|
146
|
+
const url = `${apiBase}/repos/${ref.owner}/${ref.name}/git/trees/${encodeURIComponent(branch)}?recursive=1`;
|
|
147
|
+
const res = await fetch(url, { headers: authHeaders(token) });
|
|
148
|
+
if (!res.ok) {
|
|
149
|
+
const text = await res.text();
|
|
150
|
+
throw new Error(`GitHub API error ${res.status}: ${text}`);
|
|
151
|
+
}
|
|
152
|
+
const data = (await res.json()) as { tree?: TreeItem[] };
|
|
153
|
+
return data.tree ?? [];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function fetchRaw(
|
|
157
|
+
ref: RepoRef,
|
|
158
|
+
branch: string,
|
|
159
|
+
filePath: string,
|
|
160
|
+
rawBase: string,
|
|
161
|
+
token: string | undefined,
|
|
162
|
+
): Promise<string> {
|
|
163
|
+
const url = `${rawBase}/${ref.owner}/${ref.name}/${encodeURIComponent(branch)}/${toPosix(filePath)}`;
|
|
164
|
+
const headers: Record<string, string> = {};
|
|
165
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
166
|
+
const res = await fetch(url, { headers });
|
|
167
|
+
if (!res.ok) {
|
|
168
|
+
throw new Error(`Failed to fetch ${url}: ${res.status}`);
|
|
169
|
+
}
|
|
170
|
+
return res.text();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function makeDocId(relativePath: string): string {
|
|
174
|
+
return relativePath.replace(/\.(md|mdx)$/i, "").replace(/[/\\]/g, "--");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
interface LocalFile {
|
|
178
|
+
relative: string;
|
|
179
|
+
absolute: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function scanLocalDir(dir: string, prefix = ""): LocalFile[] {
|
|
183
|
+
const items: LocalFile[] = [];
|
|
184
|
+
for (const name of readdirSync(dir)) {
|
|
185
|
+
const absolute = path.join(dir, name);
|
|
186
|
+
const relative = prefix ? `${prefix}/${name}` : name;
|
|
187
|
+
if (statSync(absolute).isDirectory()) {
|
|
188
|
+
items.push(...scanLocalDir(absolute, relative));
|
|
189
|
+
} else if (/\.(md|mdx)$/i.test(name) || /^_dir\.ya?ml$/i.test(name)) {
|
|
190
|
+
items.push({ relative, absolute });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return items;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function addDocToManifest(
|
|
197
|
+
docs: DocsManifest["docs"],
|
|
198
|
+
collectionId: string,
|
|
199
|
+
raw: string,
|
|
200
|
+
docPath: string,
|
|
201
|
+
): void {
|
|
202
|
+
const { data: fm, content } = parseFrontmatter(raw);
|
|
203
|
+
const parts = docPath.split("/");
|
|
204
|
+
const dir = parts.slice(0, -1).join("/");
|
|
205
|
+
const file = parts[parts.length - 1] ?? "";
|
|
206
|
+
const category =
|
|
207
|
+
fm.category ?? (dir ? dir.split("/").pop() : "Docs") ?? "Docs";
|
|
208
|
+
const label = fm.title ?? file.replace(/\.(md|mdx)$/i, "");
|
|
209
|
+
const description =
|
|
210
|
+
fm.description ??
|
|
211
|
+
content
|
|
212
|
+
.split("\n")
|
|
213
|
+
.find((l) => l.trim() && !l.startsWith("#"))
|
|
214
|
+
?.trim() ??
|
|
215
|
+
"";
|
|
216
|
+
|
|
217
|
+
docs[collectionId] ??= [];
|
|
218
|
+
const list = docs[collectionId];
|
|
219
|
+
list.push({
|
|
220
|
+
id: makeDocId(docPath),
|
|
221
|
+
label,
|
|
222
|
+
category,
|
|
223
|
+
description,
|
|
224
|
+
path: docPath,
|
|
225
|
+
type: "md",
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export async function pullFromGitHub(
|
|
230
|
+
options: GitHubPullOptions,
|
|
231
|
+
): Promise<PullResult> {
|
|
232
|
+
const {
|
|
233
|
+
outDir,
|
|
234
|
+
sources,
|
|
235
|
+
token = process.env.GITHUB_TOKEN,
|
|
236
|
+
apiBase = "https://api.github.com",
|
|
237
|
+
rawBase = "https://raw.githubusercontent.com",
|
|
238
|
+
} = options;
|
|
239
|
+
|
|
240
|
+
const resolvedOut = path.resolve(outDir);
|
|
241
|
+
const docsOut = path.join(resolvedOut, "docs");
|
|
242
|
+
const collections: PullResult["collections"] = [];
|
|
243
|
+
const docs: DocsManifest["docs"] = {};
|
|
244
|
+
let filesWritten = 0;
|
|
245
|
+
|
|
246
|
+
for (const source of sources) {
|
|
247
|
+
try {
|
|
248
|
+
const ref = parseRepo(source.repo);
|
|
249
|
+
const repoUrl = `https://github.com/${ref.owner}/${ref.name}`;
|
|
250
|
+
const branch = source.branch ?? "main";
|
|
251
|
+
const docsDir = source.docsDir ?? "docs";
|
|
252
|
+
const collectionId = source.id;
|
|
253
|
+
|
|
254
|
+
const collectionOut = path.join(docsOut, collectionId);
|
|
255
|
+
mkdirSync(collectionOut, { recursive: true });
|
|
256
|
+
|
|
257
|
+
// Local mode: copy files from a local directory.
|
|
258
|
+
if (source.localDir && statSync(source.localDir).isDirectory()) {
|
|
259
|
+
const localFiles = scanLocalDir(source.localDir);
|
|
260
|
+
for (const { relative, absolute } of localFiles) {
|
|
261
|
+
const content = readFileSync(absolute, "utf8");
|
|
262
|
+
const target = path.join(collectionOut, ...relative.split(/[/\\]/));
|
|
263
|
+
mkdirSync(path.dirname(target), { recursive: true });
|
|
264
|
+
writeFileSync(target, content, "utf8");
|
|
265
|
+
filesWritten++;
|
|
266
|
+
|
|
267
|
+
if (/\.(md|mdx)$/i.test(relative)) {
|
|
268
|
+
addDocToManifest(docs, collectionId, content, toPosix(relative));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
const tree = await fetchTree(ref, branch, token, apiBase);
|
|
273
|
+
|
|
274
|
+
// Collect markdown and _dir.yml files under docsDir.
|
|
275
|
+
const wanted: TreeItem[] = [];
|
|
276
|
+
for (const item of tree) {
|
|
277
|
+
if (item.type !== "blob") continue;
|
|
278
|
+
const relative = relativeWithinDocs(item.path, docsDir);
|
|
279
|
+
if (relative === item.path && docsDir !== "") continue;
|
|
280
|
+
if (
|
|
281
|
+
/\.(md|mdx)$/i.test(relative) ||
|
|
282
|
+
/^_dir\.ya?ml$/i.test(path.basename(relative))
|
|
283
|
+
) {
|
|
284
|
+
wanted.push(item);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
for (const item of wanted) {
|
|
289
|
+
const relative = relativeWithinDocs(item.path, docsDir);
|
|
290
|
+
const target = path.join(collectionOut, ...relative.split("/"));
|
|
291
|
+
mkdirSync(path.dirname(target), { recursive: true });
|
|
292
|
+
|
|
293
|
+
const raw = await fetchRaw(ref, branch, item.path, rawBase, token);
|
|
294
|
+
writeFileSync(target, raw, "utf8");
|
|
295
|
+
filesWritten++;
|
|
296
|
+
|
|
297
|
+
if (/\.(md|mdx)$/i.test(relative)) {
|
|
298
|
+
addDocToManifest(docs, collectionId, raw, toPosix(relative));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
docs[collectionId] = (docs[collectionId] ?? []).sort((a, b) =>
|
|
304
|
+
a.id.localeCompare(b.id),
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
collections.push({
|
|
308
|
+
id: collectionId,
|
|
309
|
+
label: source.label ?? ref.name,
|
|
310
|
+
description: source.description,
|
|
311
|
+
icon: source.icon,
|
|
312
|
+
repoUrl,
|
|
313
|
+
});
|
|
314
|
+
} catch (err) {
|
|
315
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
316
|
+
if (source.optional) {
|
|
317
|
+
console.warn(
|
|
318
|
+
`[create-docs] Skipped optional source "${source.id}": ${message}`,
|
|
319
|
+
);
|
|
320
|
+
} else {
|
|
321
|
+
throw new Error(`Failed to pull source "${source.id}": ${message}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
mkdirSync(resolvedOut, { recursive: true });
|
|
327
|
+
const manifest: DocsManifest = { collections, docs };
|
|
328
|
+
writeFileSync(
|
|
329
|
+
path.join(resolvedOut, "sources.json"),
|
|
330
|
+
JSON.stringify(collections, null, "\t"),
|
|
331
|
+
"utf8",
|
|
332
|
+
);
|
|
333
|
+
writeFileSync(
|
|
334
|
+
path.join(resolvedOut, "manifest.json"),
|
|
335
|
+
JSON.stringify(manifest, null, "\t"),
|
|
336
|
+
"utf8",
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
return { collections, filesWritten, outDir: resolvedOut, manifest };
|
|
340
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Velite Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adapter layer for Velite content processing.
|
|
5
|
+
* Wraps Velite's build function with framework-agnostic interface.
|
|
6
|
+
*
|
|
7
|
+
* ## Architecture
|
|
8
|
+
* - Adapter Layer: I/O implementation for Velite
|
|
9
|
+
* - No business logic, pure wrapper functions
|
|
10
|
+
* - Framework-agnostic content API
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { build } from "velite";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Velite adapter options
|
|
17
|
+
*/
|
|
18
|
+
export interface VeliteAdapterOptions {
|
|
19
|
+
/** Path to velite.config.ts file */
|
|
20
|
+
configPath?: string;
|
|
21
|
+
/** Watch mode for development */
|
|
22
|
+
watch?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Velite build result
|
|
27
|
+
*/
|
|
28
|
+
export interface VeliteBuildResult {
|
|
29
|
+
/** Success status */
|
|
30
|
+
success: boolean;
|
|
31
|
+
/** Error message if failed */
|
|
32
|
+
error?: string;
|
|
33
|
+
/** Output data directory */
|
|
34
|
+
outputDir?: string;
|
|
35
|
+
/** Assets output directory */
|
|
36
|
+
assetsDir?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Velite adapter interface
|
|
41
|
+
*/
|
|
42
|
+
export interface VeliteAdapter {
|
|
43
|
+
/** Run Velite build */
|
|
44
|
+
build: () => Promise<VeliteBuildResult>;
|
|
45
|
+
/** Path to velite.config.ts file */
|
|
46
|
+
configPath: string;
|
|
47
|
+
/** Watch mode for development */
|
|
48
|
+
watch: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create Velite adapter
|
|
53
|
+
*
|
|
54
|
+
* @param options - Adapter options
|
|
55
|
+
* @returns Build function
|
|
56
|
+
*/
|
|
57
|
+
export const createVeliteAdapter = (
|
|
58
|
+
options: VeliteAdapterOptions = {},
|
|
59
|
+
): VeliteAdapter => {
|
|
60
|
+
const { configPath = "velite.config.ts", watch = false } = options;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Run Velite build
|
|
64
|
+
*
|
|
65
|
+
* @returns Build result
|
|
66
|
+
*/
|
|
67
|
+
const buildVelite = async (): Promise<VeliteBuildResult> => {
|
|
68
|
+
try {
|
|
69
|
+
const buildOptions: Parameters<typeof build>[0] = {
|
|
70
|
+
config: configPath,
|
|
71
|
+
watch,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
await build(buildOptions);
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
outputDir: ".velite",
|
|
79
|
+
assetsDir: "public/static",
|
|
80
|
+
};
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: error instanceof Error ? error.message : String(error),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
build: buildVelite,
|
|
91
|
+
configPath,
|
|
92
|
+
watch,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Default Velite adapter instance
|
|
98
|
+
*/
|
|
99
|
+
export const defaultVeliteAdapter: VeliteAdapter = createVeliteAdapter();
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convenience function to build Velite content
|
|
103
|
+
*
|
|
104
|
+
* @param options - Build options
|
|
105
|
+
* @returns Build result
|
|
106
|
+
*/
|
|
107
|
+
export const buildVelite = async (
|
|
108
|
+
options: VeliteAdapterOptions = {},
|
|
109
|
+
): Promise<VeliteBuildResult> => {
|
|
110
|
+
const adapter = createVeliteAdapter(options);
|
|
111
|
+
return adapter.build();
|
|
112
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite server-backed docs watcher.
|
|
3
|
+
* Wires node:fs to the plugin's DocsWatcher port using the Vite dev server's
|
|
4
|
+
* own file-watching facility.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from "node:fs/promises";
|
|
7
|
+
import type { DocsWatcher } from "@create-docs/modules/plugin";
|
|
8
|
+
import { SUPPORTED_EXTENSIONS } from "@create-docs/shared/constants";
|
|
9
|
+
|
|
10
|
+
export const createNodeDocsWatcher = (): DocsWatcher => ({
|
|
11
|
+
watch(docsDir: string, onChange: (filePath: string) => void) {
|
|
12
|
+
const ac = new AbortController();
|
|
13
|
+
const iterator = fs
|
|
14
|
+
.watch(docsDir, { recursive: true, signal: ac.signal } as fs.WatchOptions)
|
|
15
|
+
[Symbol.asyncIterator]();
|
|
16
|
+
const consume = async (): Promise<void> => {
|
|
17
|
+
try {
|
|
18
|
+
for await (const event of iterator) {
|
|
19
|
+
const filename = (event as { filename?: unknown }).filename;
|
|
20
|
+
if (typeof filename !== "string") return;
|
|
21
|
+
if (!SUPPORTED_EXTENSIONS.some((ext) => filename.endsWith(ext)))
|
|
22
|
+
return;
|
|
23
|
+
onChange(filename);
|
|
24
|
+
}
|
|
25
|
+
} catch {
|
|
26
|
+
// aborted — exit silently
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
void consume();
|
|
30
|
+
return {
|
|
31
|
+
close: () => {
|
|
32
|
+
ac.abort();
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polling-based watcher fallback.
|
|
3
|
+
*
|
|
4
|
+
* `fs.watch` with `recursive: true` is unreliable on Linux (inotify misses
|
|
5
|
+
* sub-directory events until a file is touched). This walker periodically
|
|
6
|
+
* diffs the directory tree and emits change events for any file whose mtime
|
|
7
|
+
* or presence has changed since the last scan.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from "node:fs/promises";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { SUPPORTED_EXTENSIONS } from "@create-docs/shared/constants";
|
|
12
|
+
|
|
13
|
+
export interface PollingWatcherOptions {
|
|
14
|
+
readonly intervalMs?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface FileSnapshot {
|
|
18
|
+
readonly mtimeMs: number;
|
|
19
|
+
readonly size: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const isSupported = (name: string): boolean =>
|
|
23
|
+
SUPPORTED_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
24
|
+
|
|
25
|
+
const snapshotDir = async (dir: string): Promise<Map<string, FileSnapshot>> => {
|
|
26
|
+
const out = new Map<string, FileSnapshot>();
|
|
27
|
+
const walk = async (current: string): Promise<void> => {
|
|
28
|
+
let entries: import("node:fs").Dirent[];
|
|
29
|
+
try {
|
|
30
|
+
entries = await fs.readdir(current, { withFileTypes: true });
|
|
31
|
+
} catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const full = path.join(current, entry.name);
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
await walk(full);
|
|
38
|
+
} else if (entry.isFile() && isSupported(entry.name)) {
|
|
39
|
+
try {
|
|
40
|
+
const s = await fs.stat(full);
|
|
41
|
+
out.set(full, { mtimeMs: s.mtimeMs, size: s.size });
|
|
42
|
+
} catch {
|
|
43
|
+
// file vanished between readdir and stat - ignore
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
await walk(dir);
|
|
49
|
+
return out;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const createPollingWatcher = (
|
|
53
|
+
opts: PollingWatcherOptions = {},
|
|
54
|
+
): {
|
|
55
|
+
watch: (
|
|
56
|
+
dir: string,
|
|
57
|
+
onChange: (filePath: string) => void,
|
|
58
|
+
) => { close: () => void };
|
|
59
|
+
} => {
|
|
60
|
+
const interval = opts.intervalMs ?? 300;
|
|
61
|
+
return {
|
|
62
|
+
watch(dir, onChange) {
|
|
63
|
+
let stopped = false;
|
|
64
|
+
let prev: Promise<Map<string, FileSnapshot>> = snapshotDir(dir);
|
|
65
|
+
const tick = async (): Promise<void> => {
|
|
66
|
+
if (stopped) return;
|
|
67
|
+
const next = await snapshotDir(dir);
|
|
68
|
+
const before = await prev;
|
|
69
|
+
for (const [file, snap] of next) {
|
|
70
|
+
const old = before.get(file);
|
|
71
|
+
if (!old || old.mtimeMs !== snap.mtimeMs || old.size !== snap.size) {
|
|
72
|
+
onChange(file);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const file of before.keys()) {
|
|
76
|
+
if (!next.has(file)) onChange(file);
|
|
77
|
+
}
|
|
78
|
+
prev = Promise.resolve(next);
|
|
79
|
+
if (!stopped) setTimeout(tick, interval);
|
|
80
|
+
};
|
|
81
|
+
void tick();
|
|
82
|
+
return {
|
|
83
|
+
close: () => {
|
|
84
|
+
stopped = true;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type ApiConfig = unknown;
|
|
2
|
+
export type ApiEndpoint = unknown;
|
|
3
|
+
export type AuthType = unknown;
|
|
4
|
+
export type DocsConfig = unknown;
|
|
5
|
+
export type DocsPluginOptions = unknown;
|
|
6
|
+
export type EditLinkConfig = unknown;
|
|
7
|
+
export type HttpMethod = unknown;
|
|
8
|
+
export type LastUpdatedConfig = unknown;
|
|
9
|
+
export type ResolvedDocsConfig = unknown;
|
|
10
|
+
export type SearchConfig = unknown;
|
|
11
|
+
export type SiteConfig = unknown;
|
|
12
|
+
export type ThemeConfig = unknown;
|
|
13
|
+
export const defaultDocsConfig = () => null;
|
|
14
|
+
export const resolveConfig = () => null;
|
|
15
|
+
export const validateDocsConfig = () => null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type BadgeVariant = unknown;
|
|
2
|
+
export type DocFile = unknown;
|
|
3
|
+
export type DocId = unknown;
|
|
4
|
+
export type DocPage = unknown;
|
|
5
|
+
export type DocSlug = unknown;
|
|
6
|
+
export type FilePath = unknown;
|
|
7
|
+
export type Frontmatter = unknown;
|
|
8
|
+
export type ParsedContent = unknown;
|
|
9
|
+
export const buildDocPage = () => null;
|
|
10
|
+
export const buildDocPageFromRaw = () => null;
|
|
11
|
+
export const parseFrontmatter = () => null;
|