@shirokuma-library/shirokuma-docs 0.1.0-alpha.10
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.
Potentially problematic release.
This version of @shirokuma-library/shirokuma-docs might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.en.md +346 -0
- package/README.md +346 -0
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/bin/shirokuma-docs +2 -0
- package/dist/analyzers/details-test-analysis.d.ts +31 -0
- package/dist/analyzers/details-test-analysis.d.ts.map +1 -0
- package/dist/analyzers/details-test-analysis.js +174 -0
- package/dist/analyzers/details-test-analysis.js.map +1 -0
- package/dist/analyzers/feature-map-builder.d.ts +20 -0
- package/dist/analyzers/feature-map-builder.d.ts.map +1 -0
- package/dist/analyzers/feature-map-builder.js +154 -0
- package/dist/analyzers/feature-map-builder.js.map +1 -0
- package/dist/analyzers/feature-map-references.d.ts +34 -0
- package/dist/analyzers/feature-map-references.d.ts.map +1 -0
- package/dist/analyzers/feature-map-references.js +249 -0
- package/dist/analyzers/feature-map-references.js.map +1 -0
- package/dist/analyzers/reference-analyzer.d.ts +95 -0
- package/dist/analyzers/reference-analyzer.d.ts.map +1 -0
- package/dist/analyzers/reference-analyzer.js +372 -0
- package/dist/analyzers/reference-analyzer.js.map +1 -0
- package/dist/commands/adr.d.ts +26 -0
- package/dist/commands/adr.d.ts.map +1 -0
- package/dist/commands/adr.js +129 -0
- package/dist/commands/adr.js.map +1 -0
- package/dist/commands/api-tools.d.ts +83 -0
- package/dist/commands/api-tools.d.ts.map +1 -0
- package/dist/commands/api-tools.js +775 -0
- package/dist/commands/api-tools.js.map +1 -0
- package/dist/commands/coverage.d.ts +139 -0
- package/dist/commands/coverage.d.ts.map +1 -0
- package/dist/commands/coverage.js +481 -0
- package/dist/commands/coverage.js.map +1 -0
- package/dist/commands/deps.d.ts +24 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +211 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/details-context.d.ts +38 -0
- package/dist/commands/details-context.d.ts.map +1 -0
- package/dist/commands/details-context.js +195 -0
- package/dist/commands/details-context.js.map +1 -0
- package/dist/commands/details-types.d.ts +315 -0
- package/dist/commands/details-types.d.ts.map +1 -0
- package/dist/commands/details-types.js +7 -0
- package/dist/commands/details-types.js.map +1 -0
- package/dist/commands/details.d.ts +24 -0
- package/dist/commands/details.d.ts.map +1 -0
- package/dist/commands/details.js +299 -0
- package/dist/commands/details.js.map +1 -0
- package/dist/commands/discussion-templates.d.ts +26 -0
- package/dist/commands/discussion-templates.d.ts.map +1 -0
- package/dist/commands/discussion-templates.js +270 -0
- package/dist/commands/discussion-templates.js.map +1 -0
- package/dist/commands/discussions.d.ts +31 -0
- package/dist/commands/discussions.d.ts.map +1 -0
- package/dist/commands/discussions.js +744 -0
- package/dist/commands/discussions.js.map +1 -0
- package/dist/commands/feature-map-types.d.ts +294 -0
- package/dist/commands/feature-map-types.d.ts.map +1 -0
- package/dist/commands/feature-map-types.js +8 -0
- package/dist/commands/feature-map-types.js.map +1 -0
- package/dist/commands/feature-map.d.ts +30 -0
- package/dist/commands/feature-map.d.ts.map +1 -0
- package/dist/commands/feature-map.js +137 -0
- package/dist/commands/feature-map.js.map +1 -0
- package/dist/commands/generate.d.ts +16 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +88 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/gh-discussions.d.ts +31 -0
- package/dist/commands/gh-discussions.d.ts.map +1 -0
- package/dist/commands/gh-discussions.js +743 -0
- package/dist/commands/gh-discussions.js.map +1 -0
- package/dist/commands/gh-issues-pr.d.ts +74 -0
- package/dist/commands/gh-issues-pr.d.ts.map +1 -0
- package/dist/commands/gh-issues-pr.js +417 -0
- package/dist/commands/gh-issues-pr.js.map +1 -0
- package/dist/commands/gh-issues.d.ts +90 -0
- package/dist/commands/gh-issues.d.ts.map +1 -0
- package/dist/commands/gh-issues.js +1297 -0
- package/dist/commands/gh-issues.js.map +1 -0
- package/dist/commands/gh-projects.d.ts +54 -0
- package/dist/commands/gh-projects.d.ts.map +1 -0
- package/dist/commands/gh-projects.js +966 -0
- package/dist/commands/gh-projects.js.map +1 -0
- package/dist/commands/gh-repo.d.ts +18 -0
- package/dist/commands/gh-repo.d.ts.map +1 -0
- package/dist/commands/gh-repo.js +253 -0
- package/dist/commands/gh-repo.js.map +1 -0
- package/dist/commands/github-data.d.ts +67 -0
- package/dist/commands/github-data.d.ts.map +1 -0
- package/dist/commands/github-data.js +361 -0
- package/dist/commands/github-data.js.map +1 -0
- package/dist/commands/i18n.d.ts +102 -0
- package/dist/commands/i18n.d.ts.map +1 -0
- package/dist/commands/i18n.js +829 -0
- package/dist/commands/i18n.js.map +1 -0
- package/dist/commands/impact.d.ts +14 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +263 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/init.d.ts +53 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +468 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/issues-pr.d.ts +83 -0
- package/dist/commands/issues-pr.d.ts.map +1 -0
- package/dist/commands/issues-pr.js +572 -0
- package/dist/commands/issues-pr.js.map +1 -0
- package/dist/commands/issues.d.ts +78 -0
- package/dist/commands/issues.d.ts.map +1 -0
- package/dist/commands/issues.js +1541 -0
- package/dist/commands/issues.js.map +1 -0
- package/dist/commands/link-docs.d.ts +21 -0
- package/dist/commands/link-docs.d.ts.map +1 -0
- package/dist/commands/link-docs.js +990 -0
- package/dist/commands/link-docs.js.map +1 -0
- package/dist/commands/lint-annotations.d.ts +28 -0
- package/dist/commands/lint-annotations.d.ts.map +1 -0
- package/dist/commands/lint-annotations.js +511 -0
- package/dist/commands/lint-annotations.js.map +1 -0
- package/dist/commands/lint-code.d.ts +26 -0
- package/dist/commands/lint-code.d.ts.map +1 -0
- package/dist/commands/lint-code.js +428 -0
- package/dist/commands/lint-code.js.map +1 -0
- package/dist/commands/lint-coverage.d.ts +33 -0
- package/dist/commands/lint-coverage.d.ts.map +1 -0
- package/dist/commands/lint-coverage.js +379 -0
- package/dist/commands/lint-coverage.js.map +1 -0
- package/dist/commands/lint-docs.d.ts +23 -0
- package/dist/commands/lint-docs.d.ts.map +1 -0
- package/dist/commands/lint-docs.js +338 -0
- package/dist/commands/lint-docs.js.map +1 -0
- package/dist/commands/lint-structure.d.ts +38 -0
- package/dist/commands/lint-structure.d.ts.map +1 -0
- package/dist/commands/lint-structure.js +350 -0
- package/dist/commands/lint-structure.js.map +1 -0
- package/dist/commands/lint-tests.d.ts +25 -0
- package/dist/commands/lint-tests.d.ts.map +1 -0
- package/dist/commands/lint-tests.js +105 -0
- package/dist/commands/lint-tests.js.map +1 -0
- package/dist/commands/lint-workflow.d.ts +36 -0
- package/dist/commands/lint-workflow.d.ts.map +1 -0
- package/dist/commands/lint-workflow.js +255 -0
- package/dist/commands/lint-workflow.js.map +1 -0
- package/dist/commands/overview.d.ts +21 -0
- package/dist/commands/overview.d.ts.map +1 -0
- package/dist/commands/overview.js +1300 -0
- package/dist/commands/overview.js.map +1 -0
- package/dist/commands/packages.d.ts +107 -0
- package/dist/commands/packages.d.ts.map +1 -0
- package/dist/commands/packages.js +308 -0
- package/dist/commands/packages.js.map +1 -0
- package/dist/commands/portal-nextjs.d.ts +23 -0
- package/dist/commands/portal-nextjs.d.ts.map +1 -0
- package/dist/commands/portal-nextjs.js +336 -0
- package/dist/commands/portal-nextjs.js.map +1 -0
- package/dist/commands/portal.d.ts +24 -0
- package/dist/commands/portal.d.ts.map +1 -0
- package/dist/commands/portal.js +16 -0
- package/dist/commands/portal.js.map +1 -0
- package/dist/commands/projects.d.ts +54 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +1191 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/repo-pairs.d.ts +19 -0
- package/dist/commands/repo-pairs.d.ts.map +1 -0
- package/dist/commands/repo-pairs.js +529 -0
- package/dist/commands/repo-pairs.js.map +1 -0
- package/dist/commands/repo.d.ts +18 -0
- package/dist/commands/repo.d.ts.map +1 -0
- package/dist/commands/repo.js +253 -0
- package/dist/commands/repo.js.map +1 -0
- package/dist/commands/schema.d.ts +49 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +830 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/screenshots.d.ts +203 -0
- package/dist/commands/screenshots.d.ts.map +1 -0
- package/dist/commands/screenshots.js +1234 -0
- package/dist/commands/screenshots.js.map +1 -0
- package/dist/commands/search-index.d.ts +83 -0
- package/dist/commands/search-index.d.ts.map +1 -0
- package/dist/commands/search-index.js +389 -0
- package/dist/commands/search-index.js.map +1 -0
- package/dist/commands/search.d.ts +24 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +254 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/session.d.ts +159 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +1274 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/test-cases-types.d.ts +154 -0
- package/dist/commands/test-cases-types.d.ts.map +1 -0
- package/dist/commands/test-cases-types.js +7 -0
- package/dist/commands/test-cases-types.js.map +1 -0
- package/dist/commands/test-cases.d.ts +28 -0
- package/dist/commands/test-cases.d.ts.map +1 -0
- package/dist/commands/test-cases.js +192 -0
- package/dist/commands/test-cases.js.map +1 -0
- package/dist/commands/typedoc.d.ts +21 -0
- package/dist/commands/typedoc.d.ts.map +1 -0
- package/dist/commands/typedoc.js +192 -0
- package/dist/commands/typedoc.js.map +1 -0
- package/dist/commands/update-skills.d.ts +56 -0
- package/dist/commands/update-skills.d.ts.map +1 -0
- package/dist/commands/update-skills.js +626 -0
- package/dist/commands/update-skills.js.map +1 -0
- package/dist/generators/details-entity-pages.d.ts +40 -0
- package/dist/generators/details-entity-pages.d.ts.map +1 -0
- package/dist/generators/details-entity-pages.js +301 -0
- package/dist/generators/details-entity-pages.js.map +1 -0
- package/dist/generators/details-html.d.ts +23 -0
- package/dist/generators/details-html.d.ts.map +1 -0
- package/dist/generators/details-html.js +324 -0
- package/dist/generators/details-html.js.map +1 -0
- package/dist/generators/details-module-page.d.ts +33 -0
- package/dist/generators/details-module-page.d.ts.map +1 -0
- package/dist/generators/details-module-page.js +408 -0
- package/dist/generators/details-module-page.js.map +1 -0
- package/dist/generators/details-styles.d.ts +39 -0
- package/dist/generators/details-styles.d.ts.map +1 -0
- package/dist/generators/details-styles.js +409 -0
- package/dist/generators/details-styles.js.map +1 -0
- package/dist/generators/feature-map-html.d.ts +66 -0
- package/dist/generators/feature-map-html.d.ts.map +1 -0
- package/dist/generators/feature-map-html.js +569 -0
- package/dist/generators/feature-map-html.js.map +1 -0
- package/dist/generators/feature-map-styles.d.ts +39 -0
- package/dist/generators/feature-map-styles.d.ts.map +1 -0
- package/dist/generators/feature-map-styles.js +449 -0
- package/dist/generators/feature-map-styles.js.map +1 -0
- package/dist/generators/test-cases-hierarchy.d.ts +21 -0
- package/dist/generators/test-cases-hierarchy.d.ts.map +1 -0
- package/dist/generators/test-cases-hierarchy.js +336 -0
- package/dist/generators/test-cases-hierarchy.js.map +1 -0
- package/dist/generators/test-cases-main.d.ts +20 -0
- package/dist/generators/test-cases-main.d.ts.map +1 -0
- package/dist/generators/test-cases-main.js +439 -0
- package/dist/generators/test-cases-main.js.map +1 -0
- package/dist/generators/test-cases-styles.d.ts +64 -0
- package/dist/generators/test-cases-styles.d.ts.map +1 -0
- package/dist/generators/test-cases-styles.js +1277 -0
- package/dist/generators/test-cases-styles.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +600 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/annotation-lint.d.ts +198 -0
- package/dist/lint/annotation-lint.d.ts.map +1 -0
- package/dist/lint/annotation-lint.js +510 -0
- package/dist/lint/annotation-lint.js.map +1 -0
- package/dist/lint/annotation-types.d.ts +161 -0
- package/dist/lint/annotation-types.d.ts.map +1 -0
- package/dist/lint/annotation-types.js +31 -0
- package/dist/lint/annotation-types.js.map +1 -0
- package/dist/lint/code-types.d.ts +135 -0
- package/dist/lint/code-types.d.ts.map +1 -0
- package/dist/lint/code-types.js +25 -0
- package/dist/lint/code-types.js.map +1 -0
- package/dist/lint/coverage-types.d.ts +128 -0
- package/dist/lint/coverage-types.d.ts.map +1 -0
- package/dist/lint/coverage-types.js +24 -0
- package/dist/lint/coverage-types.js.map +1 -0
- package/dist/lint/docs-types.d.ts +214 -0
- package/dist/lint/docs-types.d.ts.map +1 -0
- package/dist/lint/docs-types.js +18 -0
- package/dist/lint/docs-types.js.map +1 -0
- package/dist/lint/formatters/index.d.ts +14 -0
- package/dist/lint/formatters/index.d.ts.map +1 -0
- package/dist/lint/formatters/index.js +28 -0
- package/dist/lint/formatters/index.js.map +1 -0
- package/dist/lint/formatters/json.d.ts +11 -0
- package/dist/lint/formatters/json.d.ts.map +1 -0
- package/dist/lint/formatters/json.js +12 -0
- package/dist/lint/formatters/json.js.map +1 -0
- package/dist/lint/formatters/summary.d.ts +11 -0
- package/dist/lint/formatters/summary.d.ts.map +1 -0
- package/dist/lint/formatters/summary.js +37 -0
- package/dist/lint/formatters/summary.js.map +1 -0
- package/dist/lint/formatters/terminal.d.ts +11 -0
- package/dist/lint/formatters/terminal.d.ts.map +1 -0
- package/dist/lint/formatters/terminal.js +99 -0
- package/dist/lint/formatters/terminal.js.map +1 -0
- package/dist/lint/index.d.ts +18 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +103 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/lint/rules/annotation-required.d.ts +35 -0
- package/dist/lint/rules/annotation-required.d.ts.map +1 -0
- package/dist/lint/rules/annotation-required.js +127 -0
- package/dist/lint/rules/annotation-required.js.map +1 -0
- package/dist/lint/rules/code-rules.d.ts +12 -0
- package/dist/lint/rules/code-rules.d.ts.map +1 -0
- package/dist/lint/rules/code-rules.js +11 -0
- package/dist/lint/rules/code-rules.js.map +1 -0
- package/dist/lint/rules/describe-coverage.d.ts +8 -0
- package/dist/lint/rules/describe-coverage.d.ts.map +1 -0
- package/dist/lint/rules/describe-coverage.js +43 -0
- package/dist/lint/rules/describe-coverage.js.map +1 -0
- package/dist/lint/rules/duplicate-testdoc.d.ts +8 -0
- package/dist/lint/rules/duplicate-testdoc.d.ts.map +1 -0
- package/dist/lint/rules/duplicate-testdoc.js +38 -0
- package/dist/lint/rules/duplicate-testdoc.js.map +1 -0
- package/dist/lint/rules/index.d.ts +29 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/index.js +55 -0
- package/dist/lint/rules/index.js.map +1 -0
- package/dist/lint/rules/server-action-structure.d.ts +37 -0
- package/dist/lint/rules/server-action-structure.d.ts.map +1 -0
- package/dist/lint/rules/server-action-structure.js +152 -0
- package/dist/lint/rules/server-action-structure.js.map +1 -0
- package/dist/lint/rules/skipped-test-report.d.ts +11 -0
- package/dist/lint/rules/skipped-test-report.d.ts.map +1 -0
- package/dist/lint/rules/skipped-test-report.js +31 -0
- package/dist/lint/rules/skipped-test-report.js.map +1 -0
- package/dist/lint/rules/structure-rules.d.ts +67 -0
- package/dist/lint/rules/structure-rules.d.ts.map +1 -0
- package/dist/lint/rules/structure-rules.js +617 -0
- package/dist/lint/rules/structure-rules.js.map +1 -0
- package/dist/lint/rules/testdoc-japanese.d.ts +8 -0
- package/dist/lint/rules/testdoc-japanese.d.ts.map +1 -0
- package/dist/lint/rules/testdoc-japanese.js +31 -0
- package/dist/lint/rules/testdoc-japanese.js.map +1 -0
- package/dist/lint/rules/testdoc-min-length.d.ts +8 -0
- package/dist/lint/rules/testdoc-min-length.d.ts.map +1 -0
- package/dist/lint/rules/testdoc-min-length.js +31 -0
- package/dist/lint/rules/testdoc-min-length.js.map +1 -0
- package/dist/lint/rules/testdoc-required.d.ts +8 -0
- package/dist/lint/rules/testdoc-required.d.ts.map +1 -0
- package/dist/lint/rules/testdoc-required.js +27 -0
- package/dist/lint/rules/testdoc-required.js.map +1 -0
- package/dist/lint/rules/workflow-branch-naming.d.ts +20 -0
- package/dist/lint/rules/workflow-branch-naming.d.ts.map +1 -0
- package/dist/lint/rules/workflow-branch-naming.js +85 -0
- package/dist/lint/rules/workflow-branch-naming.js.map +1 -0
- package/dist/lint/rules/workflow-commit-format.d.ts +27 -0
- package/dist/lint/rules/workflow-commit-format.d.ts.map +1 -0
- package/dist/lint/rules/workflow-commit-format.js +92 -0
- package/dist/lint/rules/workflow-commit-format.js.map +1 -0
- package/dist/lint/rules/workflow-issue-fields.d.ts +24 -0
- package/dist/lint/rules/workflow-issue-fields.d.ts.map +1 -0
- package/dist/lint/rules/workflow-issue-fields.js +89 -0
- package/dist/lint/rules/workflow-issue-fields.js.map +1 -0
- package/dist/lint/rules/workflow-main-protection.d.ts +32 -0
- package/dist/lint/rules/workflow-main-protection.d.ts.map +1 -0
- package/dist/lint/rules/workflow-main-protection.js +114 -0
- package/dist/lint/rules/workflow-main-protection.js.map +1 -0
- package/dist/lint/structure-types.d.ts +216 -0
- package/dist/lint/structure-types.d.ts.map +1 -0
- package/dist/lint/structure-types.js +96 -0
- package/dist/lint/structure-types.js.map +1 -0
- package/dist/lint/types.d.ts +154 -0
- package/dist/lint/types.d.ts.map +1 -0
- package/dist/lint/types.js +21 -0
- package/dist/lint/types.js.map +1 -0
- package/dist/lint/workflow-types.d.ts +90 -0
- package/dist/lint/workflow-types.d.ts.map +1 -0
- package/dist/lint/workflow-types.js +7 -0
- package/dist/lint/workflow-types.js.map +1 -0
- package/dist/md/analyzer/index.d.ts +46 -0
- package/dist/md/analyzer/index.d.ts.map +1 -0
- package/dist/md/analyzer/index.js +288 -0
- package/dist/md/analyzer/index.js.map +1 -0
- package/dist/md/builder/index.d.ts +91 -0
- package/dist/md/builder/index.d.ts.map +1 -0
- package/dist/md/builder/index.js +446 -0
- package/dist/md/builder/index.js.map +1 -0
- package/dist/md/cli/analyze.d.ts +11 -0
- package/dist/md/cli/analyze.d.ts.map +1 -0
- package/dist/md/cli/analyze.js +118 -0
- package/dist/md/cli/analyze.js.map +1 -0
- package/dist/md/cli/build.d.ts +11 -0
- package/dist/md/cli/build.d.ts.map +1 -0
- package/dist/md/cli/build.js +74 -0
- package/dist/md/cli/build.js.map +1 -0
- package/dist/md/cli/extract.d.ts +25 -0
- package/dist/md/cli/extract.d.ts.map +1 -0
- package/dist/md/cli/extract.js +230 -0
- package/dist/md/cli/extract.js.map +1 -0
- package/dist/md/cli/index.d.ts +3 -0
- package/dist/md/cli/index.d.ts.map +1 -0
- package/dist/md/cli/index.js +99 -0
- package/dist/md/cli/index.js.map +1 -0
- package/dist/md/cli/lint.d.ts +11 -0
- package/dist/md/cli/lint.d.ts.map +1 -0
- package/dist/md/cli/lint.js +165 -0
- package/dist/md/cli/lint.js.map +1 -0
- package/dist/md/cli/list.d.ts +16 -0
- package/dist/md/cli/list.d.ts.map +1 -0
- package/dist/md/cli/list.js +85 -0
- package/dist/md/cli/list.js.map +1 -0
- package/dist/md/cli/program.d.ts +11 -0
- package/dist/md/cli/program.d.ts.map +1 -0
- package/dist/md/cli/program.js +104 -0
- package/dist/md/cli/program.js.map +1 -0
- package/dist/md/cli/validate.d.ts +8 -0
- package/dist/md/cli/validate.d.ts.map +1 -0
- package/dist/md/cli/validate.js +82 -0
- package/dist/md/cli/validate.js.map +1 -0
- package/dist/md/constants.d.ts +69 -0
- package/dist/md/constants.d.ts.map +1 -0
- package/dist/md/constants.js +69 -0
- package/dist/md/constants.js.map +1 -0
- package/dist/md/extractor/index.d.ts +57 -0
- package/dist/md/extractor/index.d.ts.map +1 -0
- package/dist/md/extractor/index.js +365 -0
- package/dist/md/extractor/index.js.map +1 -0
- package/dist/md/index.d.ts +26 -0
- package/dist/md/index.d.ts.map +1 -0
- package/dist/md/index.js +30 -0
- package/dist/md/index.js.map +1 -0
- package/dist/md/linter/index.d.ts +20 -0
- package/dist/md/linter/index.d.ts.map +1 -0
- package/dist/md/linter/index.js +421 -0
- package/dist/md/linter/index.js.map +1 -0
- package/dist/md/linter/token-optimizer.d.ts +66 -0
- package/dist/md/linter/token-optimizer.d.ts.map +1 -0
- package/dist/md/linter/token-optimizer.js +292 -0
- package/dist/md/linter/token-optimizer.js.map +1 -0
- package/dist/md/lister/index.d.ts +42 -0
- package/dist/md/lister/index.d.ts.map +1 -0
- package/dist/md/lister/index.js +317 -0
- package/dist/md/lister/index.js.map +1 -0
- package/dist/md/parser/heading-numbers.d.ts +43 -0
- package/dist/md/parser/heading-numbers.d.ts.map +1 -0
- package/dist/md/parser/heading-numbers.js +97 -0
- package/dist/md/parser/heading-numbers.js.map +1 -0
- package/dist/md/parser/section-meta.d.ts +50 -0
- package/dist/md/parser/section-meta.d.ts.map +1 -0
- package/dist/md/parser/section-meta.js +212 -0
- package/dist/md/parser/section-meta.js.map +1 -0
- package/dist/md/parser/template.d.ts +56 -0
- package/dist/md/parser/template.d.ts.map +1 -0
- package/dist/md/parser/template.js +122 -0
- package/dist/md/parser/template.js.map +1 -0
- package/dist/md/plugins/loader.d.ts +15 -0
- package/dist/md/plugins/loader.d.ts.map +1 -0
- package/dist/md/plugins/loader.js +80 -0
- package/dist/md/plugins/loader.js.map +1 -0
- package/dist/md/plugins/normalize-headings.d.ts +43 -0
- package/dist/md/plugins/normalize-headings.d.ts.map +1 -0
- package/dist/md/plugins/normalize-headings.js +51 -0
- package/dist/md/plugins/normalize-headings.js.map +1 -0
- package/dist/md/plugins/normalize-whitespace.d.ts +46 -0
- package/dist/md/plugins/normalize-whitespace.d.ts.map +1 -0
- package/dist/md/plugins/normalize-whitespace.js +86 -0
- package/dist/md/plugins/normalize-whitespace.js.map +1 -0
- package/dist/md/plugins/remove-badges.d.ts +36 -0
- package/dist/md/plugins/remove-badges.d.ts.map +1 -0
- package/dist/md/plugins/remove-badges.js +59 -0
- package/dist/md/plugins/remove-badges.js.map +1 -0
- package/dist/md/plugins/remove-comments.d.ts +27 -0
- package/dist/md/plugins/remove-comments.d.ts.map +1 -0
- package/dist/md/plugins/remove-comments.js +40 -0
- package/dist/md/plugins/remove-comments.js.map +1 -0
- package/dist/md/plugins/remove-duplicates.d.ts +40 -0
- package/dist/md/plugins/remove-duplicates.d.ts.map +1 -0
- package/dist/md/plugins/remove-duplicates.js +72 -0
- package/dist/md/plugins/remove-duplicates.js.map +1 -0
- package/dist/md/plugins/remove-internal-links.d.ts +38 -0
- package/dist/md/plugins/remove-internal-links.d.ts.map +1 -0
- package/dist/md/plugins/remove-internal-links.js +66 -0
- package/dist/md/plugins/remove-internal-links.js.map +1 -0
- package/dist/md/plugins/strip-heading-numbers.d.ts +35 -0
- package/dist/md/plugins/strip-heading-numbers.d.ts.map +1 -0
- package/dist/md/plugins/strip-heading-numbers.js +59 -0
- package/dist/md/plugins/strip-heading-numbers.js.map +1 -0
- package/dist/md/plugins/strip-section-meta.d.ts +37 -0
- package/dist/md/plugins/strip-section-meta.d.ts.map +1 -0
- package/dist/md/plugins/strip-section-meta.js +62 -0
- package/dist/md/plugins/strip-section-meta.js.map +1 -0
- package/dist/md/types/config.d.ts +260 -0
- package/dist/md/types/config.d.ts.map +1 -0
- package/dist/md/types/config.js +156 -0
- package/dist/md/types/config.js.map +1 -0
- package/dist/md/types/document.d.ts +37 -0
- package/dist/md/types/document.d.ts.map +1 -0
- package/dist/md/types/document.js +2 -0
- package/dist/md/types/document.js.map +1 -0
- package/dist/md/types/validation.d.ts +107 -0
- package/dist/md/types/validation.d.ts.map +1 -0
- package/dist/md/types/validation.js +2 -0
- package/dist/md/types/validation.js.map +1 -0
- package/dist/md/utils/code-blocks.d.ts +136 -0
- package/dist/md/utils/code-blocks.d.ts.map +1 -0
- package/dist/md/utils/code-blocks.js +178 -0
- package/dist/md/utils/code-blocks.js.map +1 -0
- package/dist/md/utils/config.d.ts +10 -0
- package/dist/md/utils/config.d.ts.map +1 -0
- package/dist/md/utils/config.js +99 -0
- package/dist/md/utils/config.js.map +1 -0
- package/dist/md/utils/file-collector.d.ts +78 -0
- package/dist/md/utils/file-collector.d.ts.map +1 -0
- package/dist/md/utils/file-collector.js +100 -0
- package/dist/md/utils/file-collector.js.map +1 -0
- package/dist/md/utils/markdown.d.ts +18 -0
- package/dist/md/utils/markdown.d.ts.map +1 -0
- package/dist/md/utils/markdown.js +93 -0
- package/dist/md/utils/markdown.js.map +1 -0
- package/dist/md/utils/remark.d.ts +91 -0
- package/dist/md/utils/remark.d.ts.map +1 -0
- package/dist/md/utils/remark.js +125 -0
- package/dist/md/utils/remark.js.map +1 -0
- package/dist/md/utils/tokens.d.ts +9 -0
- package/dist/md/utils/tokens.d.ts.map +1 -0
- package/dist/md/utils/tokens.js +31 -0
- package/dist/md/utils/tokens.js.map +1 -0
- package/dist/md/validator/index.d.ts +40 -0
- package/dist/md/validator/index.d.ts.map +1 -0
- package/dist/md/validator/index.js +299 -0
- package/dist/md/validator/index.js.map +1 -0
- package/dist/parsers/details-jsdoc.d.ts +42 -0
- package/dist/parsers/details-jsdoc.d.ts.map +1 -0
- package/dist/parsers/details-jsdoc.js +256 -0
- package/dist/parsers/details-jsdoc.js.map +1 -0
- package/dist/parsers/details-zod.d.ts +22 -0
- package/dist/parsers/details-zod.d.ts.map +1 -0
- package/dist/parsers/details-zod.js +146 -0
- package/dist/parsers/details-zod.js.map +1 -0
- package/dist/parsers/drizzle-schema.d.ts +92 -0
- package/dist/parsers/drizzle-schema.d.ts.map +1 -0
- package/dist/parsers/drizzle-schema.js +376 -0
- package/dist/parsers/drizzle-schema.js.map +1 -0
- package/dist/parsers/feature-map-tags.d.ts +45 -0
- package/dist/parsers/feature-map-tags.d.ts.map +1 -0
- package/dist/parsers/feature-map-tags.js +292 -0
- package/dist/parsers/feature-map-tags.js.map +1 -0
- package/dist/parsers/feature-map-type-extraction.d.ts +62 -0
- package/dist/parsers/feature-map-type-extraction.d.ts.map +1 -0
- package/dist/parsers/feature-map-type-extraction.js +347 -0
- package/dist/parsers/feature-map-type-extraction.js.map +1 -0
- package/dist/parsers/feature-map-utils.d.ts +34 -0
- package/dist/parsers/feature-map-utils.d.ts.map +1 -0
- package/dist/parsers/feature-map-utils.js +101 -0
- package/dist/parsers/feature-map-utils.js.map +1 -0
- package/dist/parsers/jsdoc-common.d.ts +209 -0
- package/dist/parsers/jsdoc-common.d.ts.map +1 -0
- package/dist/parsers/jsdoc-common.js +650 -0
- package/dist/parsers/jsdoc-common.js.map +1 -0
- package/dist/parsers/jsdoc.d.ts +76 -0
- package/dist/parsers/jsdoc.d.ts.map +1 -0
- package/dist/parsers/jsdoc.js +238 -0
- package/dist/parsers/jsdoc.js.map +1 -0
- package/dist/parsers/screenshot-annotations.d.ts +96 -0
- package/dist/parsers/screenshot-annotations.d.ts.map +1 -0
- package/dist/parsers/screenshot-annotations.js +227 -0
- package/dist/parsers/screenshot-annotations.js.map +1 -0
- package/dist/parsers/test-annotations.d.ts +46 -0
- package/dist/parsers/test-annotations.d.ts.map +1 -0
- package/dist/parsers/test-annotations.js +393 -0
- package/dist/parsers/test-annotations.js.map +1 -0
- package/dist/parsers/test-categorization.d.ts +42 -0
- package/dist/parsers/test-categorization.d.ts.map +1 -0
- package/dist/parsers/test-categorization.js +182 -0
- package/dist/parsers/test-categorization.js.map +1 -0
- package/dist/parsers/zod-schema.d.ts +105 -0
- package/dist/parsers/zod-schema.d.ts.map +1 -0
- package/dist/parsers/zod-schema.js +271 -0
- package/dist/parsers/zod-schema.js.map +1 -0
- package/dist/utils/action-inference.d.ts +23 -0
- package/dist/utils/action-inference.d.ts.map +1 -0
- package/dist/utils/action-inference.js +36 -0
- package/dist/utils/action-inference.js.map +1 -0
- package/dist/utils/app-inference.d.ts +31 -0
- package/dist/utils/app-inference.d.ts.map +1 -0
- package/dist/utils/app-inference.js +41 -0
- package/dist/utils/app-inference.js.map +1 -0
- package/dist/utils/auto-infer.d.ts +93 -0
- package/dist/utils/auto-infer.d.ts.map +1 -0
- package/dist/utils/auto-infer.js +184 -0
- package/dist/utils/auto-infer.js.map +1 -0
- package/dist/utils/config.d.ts +709 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +504 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/file.d.ts +46 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +103 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/formatters.d.ts +123 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +199 -0
- package/dist/utils/formatters.js.map +1 -0
- package/dist/utils/gh-config.d.ts +99 -0
- package/dist/utils/gh-config.d.ts.map +1 -0
- package/dist/utils/gh-config.js +247 -0
- package/dist/utils/gh-config.js.map +1 -0
- package/dist/utils/github.d.ts +108 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +320 -0
- package/dist/utils/github.js.map +1 -0
- package/dist/utils/html.d.ts +107 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +376 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/i18n.d.ts +40 -0
- package/dist/utils/i18n.d.ts.map +1 -0
- package/dist/utils/i18n.js +148 -0
- package/dist/utils/i18n.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +49 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/project-fields.d.ts +71 -0
- package/dist/utils/project-fields.d.ts.map +1 -0
- package/dist/utils/project-fields.js +318 -0
- package/dist/utils/project-fields.js.map +1 -0
- package/dist/utils/repo-pairs.d.ts +94 -0
- package/dist/utils/repo-pairs.d.ts.map +1 -0
- package/dist/utils/repo-pairs.js +196 -0
- package/dist/utils/repo-pairs.js.map +1 -0
- package/dist/utils/route-inference.d.ts +81 -0
- package/dist/utils/route-inference.d.ts.map +1 -0
- package/dist/utils/route-inference.js +137 -0
- package/dist/utils/route-inference.js.map +1 -0
- package/dist/utils/sanitize.d.ts +27 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +38 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/dist/utils/setup-check.d.ts +48 -0
- package/dist/utils/setup-check.d.ts.map +1 -0
- package/dist/utils/setup-check.js +226 -0
- package/dist/utils/setup-check.js.map +1 -0
- package/dist/utils/shirokumaignore.d.ts +55 -0
- package/dist/utils/shirokumaignore.d.ts.map +1 -0
- package/dist/utils/shirokumaignore.js +94 -0
- package/dist/utils/shirokumaignore.js.map +1 -0
- package/dist/utils/skills-repo.d.ts +353 -0
- package/dist/utils/skills-repo.d.ts.map +1 -0
- package/dist/utils/skills-repo.js +793 -0
- package/dist/utils/skills-repo.js.map +1 -0
- package/dist/utils/status-workflow.d.ts +54 -0
- package/dist/utils/status-workflow.d.ts.map +1 -0
- package/dist/utils/status-workflow.js +103 -0
- package/dist/utils/status-workflow.js.map +1 -0
- package/dist/validators/frontmatter.d.ts +41 -0
- package/dist/validators/frontmatter.d.ts.map +1 -0
- package/dist/validators/frontmatter.js +117 -0
- package/dist/validators/frontmatter.js.map +1 -0
- package/dist/validators/link-checker.d.ts +48 -0
- package/dist/validators/link-checker.d.ts.map +1 -0
- package/dist/validators/link-checker.js +108 -0
- package/dist/validators/link-checker.js.map +1 -0
- package/dist/validators/markdown-structure.d.ts +50 -0
- package/dist/validators/markdown-structure.d.ts.map +1 -0
- package/dist/validators/markdown-structure.js +253 -0
- package/dist/validators/markdown-structure.js.map +1 -0
- package/i18n/cli/en.json +164 -0
- package/i18n/cli/ja.json +164 -0
- package/i18n/discussion/en.json +191 -0
- package/i18n/discussion/ja.json +191 -0
- package/package.json +113 -0
- package/portal/app/api-tools/api-tools-client.tsx +411 -0
- package/portal/app/api-tools/api-tools-document.tsx +240 -0
- package/portal/app/api-tools/page.tsx +56 -0
- package/portal/app/api-tools/swagger-view.tsx +114 -0
- package/portal/app/apps/[appId]/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
- package/portal/app/apps/[appId]/[type]/[module]/[item]/page.tsx +1422 -0
- package/portal/app/apps/[appId]/[type]/[module]/page.tsx +373 -0
- package/portal/app/apps/[appId]/feature-map/feature-map-app-document.tsx +298 -0
- package/portal/app/apps/[appId]/feature-map/page.tsx +224 -0
- package/portal/app/apps/[appId]/i18n/page.tsx +139 -0
- package/portal/app/apps/[appId]/test-cases/page.tsx +840 -0
- package/portal/app/apps/[appId]/tools/[tool]/page.tsx +351 -0
- package/portal/app/apps/[appId]/tools/api-tools-client.tsx +429 -0
- package/portal/app/apps/[appId]/tools/page.tsx +119 -0
- package/portal/app/db-schema/[db]/[table]/page.tsx +235 -0
- package/portal/app/db-schema/[db]/diagram/page.tsx +81 -0
- package/portal/app/db-schema/[db]/page.tsx +148 -0
- package/portal/app/db-schema/db-schema-document.tsx +100 -0
- package/portal/app/db-schema/diagram/client.tsx +211 -0
- package/portal/app/db-schema/diagram/page.tsx +20 -0
- package/portal/app/db-schema/page.tsx +145 -0
- package/portal/app/db-schema/table-detail-document.tsx +710 -0
- package/portal/app/db-schema/table-detail.tsx +747 -0
- package/portal/app/db-schema/table-list-document.tsx +224 -0
- package/portal/app/db-schema/table-list.tsx +247 -0
- package/portal/app/details/[type]/[module]/[item]/item-tabs-client.tsx +71 -0
- package/portal/app/details/[type]/[module]/[item]/page.tsx +1286 -0
- package/portal/app/details/[type]/[module]/page.tsx +884 -0
- package/portal/app/feature-map/feature-map-client.tsx +681 -0
- package/portal/app/feature-map/feature-map-document.tsx +313 -0
- package/portal/app/feature-map/page.tsx +438 -0
- package/portal/app/globals.css +205 -0
- package/portal/app/i18n/[...namespace]/page.tsx +190 -0
- package/portal/app/i18n/i18n-client.tsx +369 -0
- package/portal/app/i18n/page.tsx +339 -0
- package/portal/app/layout.tsx +37 -0
- package/portal/app/overview/page.tsx +65 -0
- package/portal/app/packages/[packageId]/page.tsx +201 -0
- package/portal/app/packages/page.tsx +148 -0
- package/portal/app/page.tsx +568 -0
- package/portal/app/test-cases/[file]/[line]/page.tsx +455 -0
- package/portal/app/test-cases/[file]/[line]/test-detail-document.tsx +335 -0
- package/portal/app/test-cases/[file]/page.tsx +323 -0
- package/portal/app/test-cases/[file]/test-file-document.tsx +335 -0
- package/portal/app/test-cases/page.tsx +546 -0
- package/portal/app/test-cases/test-cases-document.tsx +384 -0
- package/portal/components/code-block.tsx +57 -0
- package/portal/components/document/doc-params-table.tsx +71 -0
- package/portal/components/document/doc-section.tsx +133 -0
- package/portal/components/document/doc-table.tsx +119 -0
- package/portal/components/document/index.ts +9 -0
- package/portal/components/drawflow-er-diagram.tsx +607 -0
- package/portal/components/interactive-er-diagram.tsx +228 -0
- package/portal/components/layout/app-sidebar.tsx +490 -0
- package/portal/components/layout/er-sidebar.tsx +116 -0
- package/portal/components/layout/global-header.tsx +117 -0
- package/portal/components/layout/layout-content.tsx +48 -0
- package/portal/components/markdown-content.tsx +120 -0
- package/portal/components/mermaid-diagram.tsx +83 -0
- package/portal/components/reactflow-er-diagram.tsx +475 -0
- package/portal/components/search-dialog.tsx +268 -0
- package/portal/components/shared/coverage-score-bar.tsx +144 -0
- package/portal/components/swagger/endpoint-accordion.tsx +117 -0
- package/portal/components/swagger/index.ts +7 -0
- package/portal/components/swagger/method-badge.tsx +55 -0
- package/portal/components/swagger/params-table.tsx +78 -0
- package/portal/components/tabs-with-hash.tsx +43 -0
- package/portal/components/test/index.ts +2 -0
- package/portal/components/test/test-bdd-card.tsx +192 -0
- package/portal/components/test/test-matrix.tsx +242 -0
- package/portal/components/ui/accordion.tsx +66 -0
- package/portal/components/ui/badge.tsx +46 -0
- package/portal/components/ui/breadcrumb.tsx +109 -0
- package/portal/components/ui/button.tsx +62 -0
- package/portal/components/ui/card.tsx +92 -0
- package/portal/components/ui/collapsible.tsx +33 -0
- package/portal/components/ui/dialog.tsx +118 -0
- package/portal/components/ui/progress.tsx +28 -0
- package/portal/components/ui/scroll-area.tsx +58 -0
- package/portal/components/ui/sheet.tsx +139 -0
- package/portal/components/ui/table.tsx +116 -0
- package/portal/components/ui/tabs.tsx +66 -0
- package/portal/components.json +21 -0
- package/portal/lib/constants/test-categories.ts +186 -0
- package/portal/lib/data-loader.ts +1181 -0
- package/portal/lib/db-schema-utils.ts +182 -0
- package/portal/lib/format.ts +43 -0
- package/portal/lib/hooks/use-hash-tab.ts +144 -0
- package/portal/lib/path-utils.ts +25 -0
- package/portal/lib/search-index-generator.ts +214 -0
- package/portal/lib/search.ts +126 -0
- package/portal/lib/sidebar-context.tsx +111 -0
- package/portal/lib/types.ts +740 -0
- package/portal/lib/utils.ts +6 -0
- package/portal/next.config.ts +18 -0
- package/portal/package.json +45 -0
- package/portal/postcss.config.mjs +8 -0
- package/portal/tsconfig.json +42 -0
- package/portal/types/drawflow.d.ts +80 -0
- package/templates/README.md +73 -0
- package/templates/coverage.html +367 -0
- package/templates/dark-theme.css +443 -0
- package/templates/discussion/adr.yml.hbs +65 -0
- package/templates/discussion/handovers.yml.hbs +57 -0
- package/templates/discussion/knowledge.yml.hbs +60 -0
- package/templates/discussion/reports.yml.hbs +68 -0
- package/templates/discussion/research.yml.hbs +61 -0
|
@@ -0,0 +1,1181 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* GitHub Data Types (from github-data.json)
|
|
6
|
+
*/
|
|
7
|
+
export interface GithubIssue {
|
|
8
|
+
number: number;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
state: string;
|
|
12
|
+
labels: string[];
|
|
13
|
+
status: string | null;
|
|
14
|
+
priority: string | null;
|
|
15
|
+
type: string | null;
|
|
16
|
+
size: string | null;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface GithubDiscussion {
|
|
22
|
+
number: number;
|
|
23
|
+
title: string;
|
|
24
|
+
url: string;
|
|
25
|
+
category: string;
|
|
26
|
+
author: string;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
body?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface GithubRepoInfo {
|
|
33
|
+
owner: string;
|
|
34
|
+
name: string;
|
|
35
|
+
fullName: string;
|
|
36
|
+
description: string | null;
|
|
37
|
+
url: string;
|
|
38
|
+
defaultBranch: string;
|
|
39
|
+
visibility: string;
|
|
40
|
+
stargazers: number;
|
|
41
|
+
forks: number;
|
|
42
|
+
issues: number;
|
|
43
|
+
pullRequests: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GithubData {
|
|
47
|
+
repository: GithubRepoInfo;
|
|
48
|
+
issues: {
|
|
49
|
+
inProgress: GithubIssue[];
|
|
50
|
+
ready: GithubIssue[];
|
|
51
|
+
backlog: GithubIssue[];
|
|
52
|
+
icebox: GithubIssue[];
|
|
53
|
+
done: GithubIssue[];
|
|
54
|
+
total: number;
|
|
55
|
+
};
|
|
56
|
+
handovers: GithubDiscussion[];
|
|
57
|
+
specs: GithubDiscussion[];
|
|
58
|
+
fetchedAt: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
import type {
|
|
62
|
+
TestCasesData,
|
|
63
|
+
FeatureMapData,
|
|
64
|
+
DbSchemaData,
|
|
65
|
+
DatabaseInfo,
|
|
66
|
+
LinkedDocsData,
|
|
67
|
+
PortalConfig,
|
|
68
|
+
DetailsData,
|
|
69
|
+
DetailItem,
|
|
70
|
+
ApplicationsData,
|
|
71
|
+
ApiToolsData,
|
|
72
|
+
AppConfig,
|
|
73
|
+
AppStats,
|
|
74
|
+
AppType,
|
|
75
|
+
ApiProtocol,
|
|
76
|
+
SectionType,
|
|
77
|
+
I18nData,
|
|
78
|
+
PackagesData,
|
|
79
|
+
PackageInfo,
|
|
80
|
+
} from "./types";
|
|
81
|
+
import type { SearchIndex } from "./search";
|
|
82
|
+
import { generateSearchIndex } from "./search-index-generator";
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Configuration-based application definition (from shirokuma-docs.config.yaml)
|
|
86
|
+
*/
|
|
87
|
+
interface ConfiguredApplication {
|
|
88
|
+
id: string;
|
|
89
|
+
type: AppType;
|
|
90
|
+
name: string;
|
|
91
|
+
description?: string;
|
|
92
|
+
source?: string;
|
|
93
|
+
icon?: string;
|
|
94
|
+
color?: string;
|
|
95
|
+
protocol?: ApiProtocol;
|
|
96
|
+
toolsFile?: string;
|
|
97
|
+
sections?: Array<{
|
|
98
|
+
type: SectionType;
|
|
99
|
+
label?: string;
|
|
100
|
+
icon?: string;
|
|
101
|
+
filter?: { paths?: string[] };
|
|
102
|
+
}>;
|
|
103
|
+
dbTables?: string[];
|
|
104
|
+
tests?: { match: string[] };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get the project root directory (where OVERVIEW.md might be)
|
|
109
|
+
*/
|
|
110
|
+
function getProjectRoot(): string {
|
|
111
|
+
return process.env.PROJECT_ROOT || "./";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Load overview markdown content
|
|
116
|
+
*/
|
|
117
|
+
export async function loadOverview(): Promise<{ content: string; title: string } | null> {
|
|
118
|
+
const projectRoot = getProjectRoot();
|
|
119
|
+
const possiblePaths = [
|
|
120
|
+
path.join(projectRoot, "docs", "OVERVIEW.md"),
|
|
121
|
+
path.join(projectRoot, "OVERVIEW.md"),
|
|
122
|
+
path.join(projectRoot, "README.md"),
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
for (const filePath of possiblePaths) {
|
|
126
|
+
try {
|
|
127
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
128
|
+
// Extract title from first h1
|
|
129
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
130
|
+
const title = titleMatch ? titleMatch[1] : "Overview";
|
|
131
|
+
return { content, title };
|
|
132
|
+
} catch {
|
|
133
|
+
// Try next path
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Try from data directory as fallback
|
|
138
|
+
try {
|
|
139
|
+
const dataPath = path.join(getDataDir(), "overview.md");
|
|
140
|
+
const content = await fs.readFile(dataPath, "utf-8");
|
|
141
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
142
|
+
const title = titleMatch ? titleMatch[1] : "Overview";
|
|
143
|
+
return { content, title };
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get the data directory path from environment or default
|
|
151
|
+
*/
|
|
152
|
+
function getDataDir(): string {
|
|
153
|
+
if (process.env.PORTAL_DATA_DIR) {
|
|
154
|
+
return process.env.PORTAL_DATA_DIR;
|
|
155
|
+
}
|
|
156
|
+
// Use absolute path relative to project root
|
|
157
|
+
return path.join(process.cwd(), "data");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Read and parse a JSON file
|
|
162
|
+
*/
|
|
163
|
+
async function readJsonFile<T>(filename: string): Promise<T | null> {
|
|
164
|
+
try {
|
|
165
|
+
const filePath = path.join(getDataDir(), filename);
|
|
166
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
167
|
+
return JSON.parse(content) as T;
|
|
168
|
+
} catch {
|
|
169
|
+
console.warn(`Failed to load ${filename}`);
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Check if a file exists
|
|
176
|
+
*/
|
|
177
|
+
async function fileExists(filename: string): Promise<boolean> {
|
|
178
|
+
try {
|
|
179
|
+
const filePath = path.join(getDataDir(), filename);
|
|
180
|
+
await fs.access(filePath);
|
|
181
|
+
return true;
|
|
182
|
+
} catch {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Load test cases data
|
|
189
|
+
*/
|
|
190
|
+
export async function loadTestCases(): Promise<TestCasesData | null> {
|
|
191
|
+
return readJsonFile<TestCasesData>("test-cases.json");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Load feature map data
|
|
196
|
+
*/
|
|
197
|
+
export async function loadFeatureMap(): Promise<FeatureMapData | null> {
|
|
198
|
+
return readJsonFile<FeatureMapData>("feature-map.json");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Load database schema data
|
|
203
|
+
*
|
|
204
|
+
* @param dbName - Database name (required for filtering by specific DB)
|
|
205
|
+
* If provided, returns only that database's tables
|
|
206
|
+
* If not provided, returns all tables
|
|
207
|
+
*/
|
|
208
|
+
export async function loadDbSchema(dbName?: string): Promise<DbSchemaData | null> {
|
|
209
|
+
const data = await readJsonFile<DbSchemaData>("db-schema.json");
|
|
210
|
+
if (!data) return null;
|
|
211
|
+
|
|
212
|
+
// If no specific DB requested, return all data
|
|
213
|
+
if (!dbName) return data;
|
|
214
|
+
|
|
215
|
+
// Filter tables for the specific database
|
|
216
|
+
const filteredTables = data.tables.filter((t) => t.database === dbName);
|
|
217
|
+
|
|
218
|
+
// Find the database info
|
|
219
|
+
const dbInfo = data.databases?.find((db) => db.name === dbName);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
databases: dbInfo ? [dbInfo] : undefined,
|
|
223
|
+
tables: filteredTables,
|
|
224
|
+
generatedAt: data.generatedAt,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get list of databases
|
|
230
|
+
* Always returns at least one database (default "database" if not specified)
|
|
231
|
+
*/
|
|
232
|
+
export async function getDbList(): Promise<DatabaseInfo[]> {
|
|
233
|
+
const data = await readJsonFile<DbSchemaData>("db-schema.json");
|
|
234
|
+
if (!data) return [];
|
|
235
|
+
|
|
236
|
+
// If databases array exists, return it
|
|
237
|
+
if (data.databases && data.databases.length > 0) {
|
|
238
|
+
return data.databases;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Fallback for old format without databases array
|
|
242
|
+
// Create a single "database" entry
|
|
243
|
+
return [{
|
|
244
|
+
name: "database",
|
|
245
|
+
tableCount: data.tables.length,
|
|
246
|
+
}];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Load linked docs data
|
|
251
|
+
*/
|
|
252
|
+
export async function loadLinkedDocs(): Promise<LinkedDocsData | null> {
|
|
253
|
+
return readJsonFile<LinkedDocsData>("linked-docs.json");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Load details data (generated by details command)
|
|
258
|
+
*/
|
|
259
|
+
export async function loadDetails(): Promise<DetailsData | null> {
|
|
260
|
+
return readJsonFile<DetailsData>("details.json");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Load MCP tools data
|
|
265
|
+
*/
|
|
266
|
+
export async function loadApiTools(): Promise<ApiToolsData | null> {
|
|
267
|
+
return readJsonFile<ApiToolsData>("api-tools.json");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Load i18n documentation data
|
|
272
|
+
*/
|
|
273
|
+
export async function loadI18n(): Promise<I18nData | null> {
|
|
274
|
+
return readJsonFile<I18nData>("i18n.json");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Load packages data (monorepo shared packages)
|
|
279
|
+
*/
|
|
280
|
+
export async function loadPackages(): Promise<PackagesData | null> {
|
|
281
|
+
return readJsonFile<PackagesData>("packages.json");
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Load GitHub data (issues, discussions, repository info)
|
|
286
|
+
*/
|
|
287
|
+
export async function loadGithubData(): Promise<GithubData | null> {
|
|
288
|
+
return readJsonFile<GithubData>("github-data.json");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Get list of all packages
|
|
293
|
+
*/
|
|
294
|
+
export async function getPackageList(): Promise<PackageInfo[]> {
|
|
295
|
+
const data = await loadPackages();
|
|
296
|
+
return data?.packages ?? [];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Get a single package by name
|
|
301
|
+
*/
|
|
302
|
+
export async function getPackage(name: string): Promise<PackageInfo | null> {
|
|
303
|
+
const data = await loadPackages();
|
|
304
|
+
if (!data) return null;
|
|
305
|
+
return data.packages.find((pkg) => pkg.name === name) ?? null;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Screenshot manifest entry
|
|
310
|
+
*/
|
|
311
|
+
export interface ScreenshotEntry {
|
|
312
|
+
/** Screen name */
|
|
313
|
+
name: string;
|
|
314
|
+
/** File name (relative path within screenshots directory) */
|
|
315
|
+
fileName: string;
|
|
316
|
+
/** Route path */
|
|
317
|
+
route: string;
|
|
318
|
+
/** Description */
|
|
319
|
+
description?: string;
|
|
320
|
+
/** Source file path */
|
|
321
|
+
sourcePath?: string;
|
|
322
|
+
/** Account (for multi-account mode) */
|
|
323
|
+
account?: string;
|
|
324
|
+
/** Viewport size */
|
|
325
|
+
viewport?: { width: number; height: number };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Screenshot manifest data (per-app format)
|
|
330
|
+
*/
|
|
331
|
+
export interface ScreenshotsData {
|
|
332
|
+
/** Generation timestamp */
|
|
333
|
+
generatedAt: string;
|
|
334
|
+
/** Configuration */
|
|
335
|
+
config: {
|
|
336
|
+
baseUrl: string;
|
|
337
|
+
viewport: { width: number; height: number };
|
|
338
|
+
outputDir: string;
|
|
339
|
+
};
|
|
340
|
+
/** Screenshots by screen name */
|
|
341
|
+
screenshots: Record<string, ScreenshotEntry>;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Multi-app screenshot index
|
|
346
|
+
*/
|
|
347
|
+
export interface MultiAppScreenshotsIndex {
|
|
348
|
+
/** Generation timestamp */
|
|
349
|
+
generatedAt: string;
|
|
350
|
+
/** App IDs */
|
|
351
|
+
apps: string[];
|
|
352
|
+
/** Per-app manifests */
|
|
353
|
+
manifests: Record<string, ScreenshotsData>;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Load multi-app screenshots index
|
|
358
|
+
* Returns the combined index.json if available, otherwise null
|
|
359
|
+
*/
|
|
360
|
+
export async function loadScreenshotsIndex(): Promise<MultiAppScreenshotsIndex | null> {
|
|
361
|
+
try {
|
|
362
|
+
const indexPath = path.join(getDataDir(), "screenshots", "index.json");
|
|
363
|
+
const content = await fs.readFile(indexPath, "utf-8");
|
|
364
|
+
return JSON.parse(content) as MultiAppScreenshotsIndex;
|
|
365
|
+
} catch {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Load screenshots manifest data for a specific app
|
|
372
|
+
* @param appId - App ID (e.g., "admin", "public")
|
|
373
|
+
* @returns Screenshots data for the app or null if not found
|
|
374
|
+
*/
|
|
375
|
+
export async function loadScreenshotsForApp(appId: string): Promise<ScreenshotsData | null> {
|
|
376
|
+
try {
|
|
377
|
+
// Try app-specific path first
|
|
378
|
+
const appPath = path.join(getDataDir(), "screenshots", appId, "screenshots.json");
|
|
379
|
+
const content = await fs.readFile(appPath, "utf-8");
|
|
380
|
+
return JSON.parse(content) as ScreenshotsData;
|
|
381
|
+
} catch {
|
|
382
|
+
// Fall back to multi-app index
|
|
383
|
+
const index = await loadScreenshotsIndex();
|
|
384
|
+
if (index?.manifests[appId]) {
|
|
385
|
+
return index.manifests[appId];
|
|
386
|
+
}
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Load screenshots manifest data (legacy single-app format or first available app)
|
|
393
|
+
* Screenshots manifest is copied to data/screenshots/ during portal build
|
|
394
|
+
*/
|
|
395
|
+
export async function loadScreenshots(): Promise<ScreenshotsData | null> {
|
|
396
|
+
try {
|
|
397
|
+
// Try legacy format first
|
|
398
|
+
const screenshotsPath = path.join(getDataDir(), "screenshots", "screenshots.json");
|
|
399
|
+
const content = await fs.readFile(screenshotsPath, "utf-8");
|
|
400
|
+
return JSON.parse(content) as ScreenshotsData;
|
|
401
|
+
} catch {
|
|
402
|
+
// Fall back to multi-app index, return first app's data
|
|
403
|
+
const index = await loadScreenshotsIndex();
|
|
404
|
+
if (index && index.apps.length > 0) {
|
|
405
|
+
const firstAppId = index.apps[0];
|
|
406
|
+
return index.manifests[firstAppId] || null;
|
|
407
|
+
}
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Get screenshot for a specific screen
|
|
414
|
+
* @param screenName - Name of the screen
|
|
415
|
+
* @param appId - Optional app ID to search in specific app
|
|
416
|
+
* @returns Screenshot entry or null if not found
|
|
417
|
+
*/
|
|
418
|
+
export async function getScreenshotForScreen(
|
|
419
|
+
screenName: string,
|
|
420
|
+
appId?: string
|
|
421
|
+
): Promise<{ entry: ScreenshotEntry; appId: string } | null> {
|
|
422
|
+
// If appId specified, search only in that app
|
|
423
|
+
if (appId) {
|
|
424
|
+
const data = await loadScreenshotsForApp(appId);
|
|
425
|
+
if (data?.screenshots[screenName]) {
|
|
426
|
+
return { entry: data.screenshots[screenName], appId };
|
|
427
|
+
}
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Search across all apps
|
|
432
|
+
const index = await loadScreenshotsIndex();
|
|
433
|
+
if (index) {
|
|
434
|
+
for (const app of index.apps) {
|
|
435
|
+
const manifest = index.manifests[app];
|
|
436
|
+
if (manifest?.screenshots[screenName]) {
|
|
437
|
+
return { entry: manifest.screenshots[screenName], appId: app };
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Fall back to legacy format
|
|
443
|
+
const data = await loadScreenshots();
|
|
444
|
+
if (data?.screenshots[screenName]) {
|
|
445
|
+
return { entry: data.screenshots[screenName], appId: "default" };
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Get all available app IDs with screenshots
|
|
453
|
+
*/
|
|
454
|
+
export async function getScreenshotAppIds(): Promise<string[]> {
|
|
455
|
+
const index = await loadScreenshotsIndex();
|
|
456
|
+
if (index) {
|
|
457
|
+
return index.apps;
|
|
458
|
+
}
|
|
459
|
+
// Legacy format - return empty or single default
|
|
460
|
+
const legacy = await loadScreenshots();
|
|
461
|
+
return legacy ? ["default"] : [];
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Coverage report data structure from lint-coverage
|
|
466
|
+
*/
|
|
467
|
+
export interface CoverageData {
|
|
468
|
+
results: Array<{
|
|
469
|
+
source: string;
|
|
470
|
+
test?: string;
|
|
471
|
+
testCount: number;
|
|
472
|
+
status: "covered" | "skipped" | "missing";
|
|
473
|
+
skipReason?: string;
|
|
474
|
+
}>;
|
|
475
|
+
orphans: Array<{
|
|
476
|
+
test: string;
|
|
477
|
+
expectedSource: string;
|
|
478
|
+
}>;
|
|
479
|
+
summary: {
|
|
480
|
+
totalSources: number;
|
|
481
|
+
coveredCount: number;
|
|
482
|
+
skippedCount: number;
|
|
483
|
+
missingCount: number;
|
|
484
|
+
orphanCount: number;
|
|
485
|
+
coveragePercent: number;
|
|
486
|
+
};
|
|
487
|
+
passed: boolean;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Load coverage data (from lint-coverage)
|
|
492
|
+
*/
|
|
493
|
+
export async function loadCoverage(): Promise<CoverageData | null> {
|
|
494
|
+
return readJsonFile<CoverageData>("coverage.json");
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Load applications configuration (or generate from available data)
|
|
499
|
+
*/
|
|
500
|
+
export async function loadApplications(): Promise<ApplicationsData | null> {
|
|
501
|
+
// Try to load pre-configured applications.json first
|
|
502
|
+
const configured = await readJsonFile<ApplicationsData>("applications.json");
|
|
503
|
+
if (configured) {
|
|
504
|
+
return configured;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Auto-generate from available data
|
|
508
|
+
return autoGenerateApplications();
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Auto-generate applications data from available JSON files
|
|
513
|
+
*/
|
|
514
|
+
async function autoGenerateApplications(): Promise<ApplicationsData> {
|
|
515
|
+
const [available, featureMap, testCases, dbSchema, mcpTools] = await Promise.all([
|
|
516
|
+
getAvailableData(),
|
|
517
|
+
loadFeatureMap(),
|
|
518
|
+
loadTestCases(),
|
|
519
|
+
loadDbSchema(),
|
|
520
|
+
loadApiTools(),
|
|
521
|
+
]);
|
|
522
|
+
|
|
523
|
+
// Calculate web app stats
|
|
524
|
+
const webStats: AppStats = { screens: 0, components: 0, actions: 0, tests: 0 };
|
|
525
|
+
if (featureMap) {
|
|
526
|
+
for (const group of Object.values(featureMap.features)) {
|
|
527
|
+
webStats.screens! += group.screens?.length || 0;
|
|
528
|
+
webStats.components! += group.components?.length || 0;
|
|
529
|
+
webStats.actions! += group.actions?.length || 0;
|
|
530
|
+
}
|
|
531
|
+
webStats.screens! += featureMap.uncategorized.screens?.length || 0;
|
|
532
|
+
webStats.components! += featureMap.uncategorized.components?.length || 0;
|
|
533
|
+
webStats.actions! += featureMap.uncategorized.actions?.length || 0;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Count web tests (non-MCP tests)
|
|
537
|
+
if (testCases) {
|
|
538
|
+
const mcpTestCount = testCases.testCases.filter((t) =>
|
|
539
|
+
t.file.includes("/mcp/") || t.file.includes("apps/mcp/")
|
|
540
|
+
).length;
|
|
541
|
+
webStats.tests = testCases.summary.totalTests - mcpTestCount;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Calculate MCP/API stats
|
|
545
|
+
const mcpStats: AppStats = {
|
|
546
|
+
tools: mcpTools?.summary?.totalTools || mcpTools?.tools?.length || 0,
|
|
547
|
+
tests:
|
|
548
|
+
testCases?.testCases.filter((t) =>
|
|
549
|
+
t.file.includes("/mcp/") || t.file.includes("apps/mcp/")
|
|
550
|
+
).length || 0,
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
const apps: AppConfig[] = [];
|
|
554
|
+
|
|
555
|
+
// Add Web app if feature map exists
|
|
556
|
+
if (available.hasFeatureMap) {
|
|
557
|
+
apps.push({
|
|
558
|
+
id: "web",
|
|
559
|
+
name: "Web アプリ",
|
|
560
|
+
description: "メインアプリケーション",
|
|
561
|
+
type: "web",
|
|
562
|
+
icon: "globe",
|
|
563
|
+
color: "blue",
|
|
564
|
+
source: "apps/web",
|
|
565
|
+
stats: webStats,
|
|
566
|
+
sections: [{ type: "featureMap", label: "機能マップ", icon: "layers", available: true }],
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Add API app if API tools exist (MCP, REST, etc.)
|
|
571
|
+
if (available.hasApiTools) {
|
|
572
|
+
// Determine API type from tools data (could be extended to detect REST/GraphQL)
|
|
573
|
+
const apiProtocol = mcpTools?.protocol || "mcp";
|
|
574
|
+
const apiName = mcpTools?.name || "API Server";
|
|
575
|
+
const apiDescription = mcpTools?.description || "API ツール一覧";
|
|
576
|
+
|
|
577
|
+
apps.push({
|
|
578
|
+
id: "mcp", // Keep ID for backward compatibility
|
|
579
|
+
name: apiName,
|
|
580
|
+
description: apiDescription,
|
|
581
|
+
type: "api",
|
|
582
|
+
protocol: apiProtocol,
|
|
583
|
+
icon: "bot",
|
|
584
|
+
color: "purple",
|
|
585
|
+
source: "apps/mcp",
|
|
586
|
+
stats: mcpStats,
|
|
587
|
+
sections: [
|
|
588
|
+
{
|
|
589
|
+
type: "tools",
|
|
590
|
+
label: "ツール一覧",
|
|
591
|
+
icon: "wrench",
|
|
592
|
+
available: true,
|
|
593
|
+
count: mcpStats.tools,
|
|
594
|
+
},
|
|
595
|
+
],
|
|
596
|
+
} as AppConfig);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Calculate total tests
|
|
600
|
+
const totalTests = testCases?.summary.totalTests || 0;
|
|
601
|
+
|
|
602
|
+
return {
|
|
603
|
+
shared: {
|
|
604
|
+
sections: [
|
|
605
|
+
{
|
|
606
|
+
type: "overview",
|
|
607
|
+
label: "プロジェクト概要",
|
|
608
|
+
icon: "file-text",
|
|
609
|
+
available: available.hasOverview,
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
type: "dbSchema",
|
|
613
|
+
label: "データベーススキーマ",
|
|
614
|
+
icon: "database",
|
|
615
|
+
available: available.hasDbSchema,
|
|
616
|
+
count: dbSchema?.tables.length,
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
type: "testCases",
|
|
620
|
+
label: "テストケース",
|
|
621
|
+
icon: "check-circle",
|
|
622
|
+
available: available.hasTestCases,
|
|
623
|
+
count: totalTests,
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
},
|
|
627
|
+
apps,
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Get application by ID
|
|
633
|
+
*/
|
|
634
|
+
export async function getApplicationById(appId: string): Promise<AppConfig | null> {
|
|
635
|
+
const apps = await loadApplications();
|
|
636
|
+
if (!apps) return null;
|
|
637
|
+
return apps.apps.find((app) => app.id === appId) || null;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Check if an application is an API type
|
|
642
|
+
*/
|
|
643
|
+
export function isApiApplication(app: AppConfig): boolean {
|
|
644
|
+
return app.type === "api";
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Get API protocol for an application (if it's an API type)
|
|
649
|
+
*/
|
|
650
|
+
export function getApiProtocol(app: AppConfig): ApiProtocol | null {
|
|
651
|
+
if (app.type === "api" && "protocol" in app) {
|
|
652
|
+
return (app as { protocol: ApiProtocol }).protocol;
|
|
653
|
+
}
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Get a specific detail item by key
|
|
659
|
+
* Key format: "{type}/{moduleName}/{name}" (e.g., "action/entities/getEntities")
|
|
660
|
+
*/
|
|
661
|
+
export async function getDetailItem(key: string): Promise<DetailItem | null> {
|
|
662
|
+
const details = await loadDetails();
|
|
663
|
+
if (!details) return null;
|
|
664
|
+
return details.details[key] || null;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Find detail item by type, module, and name
|
|
669
|
+
*/
|
|
670
|
+
export async function findDetailItem(
|
|
671
|
+
type: string,
|
|
672
|
+
moduleName: string,
|
|
673
|
+
name: string
|
|
674
|
+
): Promise<DetailItem | null> {
|
|
675
|
+
const key = `${type}/${moduleName}/${name}`;
|
|
676
|
+
return getDetailItem(key);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Load portal configuration (from YAML config, converted to JSON)
|
|
681
|
+
*/
|
|
682
|
+
export async function loadPortalConfig(): Promise<PortalConfig | null> {
|
|
683
|
+
return readJsonFile<PortalConfig>("portal-config.json");
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Get project name from environment
|
|
688
|
+
*/
|
|
689
|
+
export function getProjectName(): string {
|
|
690
|
+
return process.env.PROJECT_NAME || "Documentation";
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Check if a screenshot manifest file exists
|
|
695
|
+
*/
|
|
696
|
+
async function screenshotsExist(): Promise<boolean> {
|
|
697
|
+
try {
|
|
698
|
+
const screenshotsPath = path.join(getDataDir(), "screenshots", "screenshots.json");
|
|
699
|
+
await fs.access(screenshotsPath);
|
|
700
|
+
return true;
|
|
701
|
+
} catch {
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Check available data files
|
|
708
|
+
*/
|
|
709
|
+
export async function getAvailableData(): Promise<{
|
|
710
|
+
hasTestCases: boolean;
|
|
711
|
+
hasFeatureMap: boolean;
|
|
712
|
+
hasDbSchema: boolean;
|
|
713
|
+
hasOverview: boolean;
|
|
714
|
+
hasApiTools: boolean;
|
|
715
|
+
hasI18n: boolean;
|
|
716
|
+
hasScreenshots: boolean;
|
|
717
|
+
hasPackages: boolean;
|
|
718
|
+
hasGithubData: boolean;
|
|
719
|
+
}> {
|
|
720
|
+
const [hasTestCases, hasFeatureMap, hasDbSchema, hasApiTools, hasI18n, hasScreenshots, hasPackages, hasGithubData, overview] = await Promise.all([
|
|
721
|
+
fileExists("test-cases.json"),
|
|
722
|
+
fileExists("feature-map.json"),
|
|
723
|
+
fileExists("db-schema.json"),
|
|
724
|
+
fileExists("api-tools.json"),
|
|
725
|
+
fileExists("i18n.json"),
|
|
726
|
+
screenshotsExist(),
|
|
727
|
+
fileExists("packages.json"),
|
|
728
|
+
fileExists("github-data.json"),
|
|
729
|
+
loadOverview(),
|
|
730
|
+
]);
|
|
731
|
+
|
|
732
|
+
return { hasTestCases, hasFeatureMap, hasDbSchema, hasApiTools, hasI18n, hasScreenshots, hasPackages, hasGithubData, hasOverview: overview !== null };
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Get test case categories from data
|
|
737
|
+
*/
|
|
738
|
+
export function getTestCategories(data: TestCasesData): string[] {
|
|
739
|
+
const categories = new Set<string>();
|
|
740
|
+
for (const tc of data.testCases) {
|
|
741
|
+
// Group by framework or custom category
|
|
742
|
+
if (tc.framework === "playwright") {
|
|
743
|
+
categories.add("e2e");
|
|
744
|
+
} else {
|
|
745
|
+
// Infer category from file path
|
|
746
|
+
if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
|
|
747
|
+
categories.add("server-actions");
|
|
748
|
+
} else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
|
|
749
|
+
categories.add("components");
|
|
750
|
+
} else {
|
|
751
|
+
categories.add("other");
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return Array.from(categories).sort();
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Get test files for a category
|
|
760
|
+
*/
|
|
761
|
+
export function getTestFilesByCategory(
|
|
762
|
+
data: TestCasesData,
|
|
763
|
+
category: string
|
|
764
|
+
): { file: string; tests: number; firstTest: import("./types").TestCase }[] {
|
|
765
|
+
const fileMap = new Map<string, { count: number; first: import("./types").TestCase }>();
|
|
766
|
+
|
|
767
|
+
for (const tc of data.testCases) {
|
|
768
|
+
let tcCategory: string;
|
|
769
|
+
if (tc.framework === "playwright") {
|
|
770
|
+
tcCategory = "e2e";
|
|
771
|
+
} else if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
|
|
772
|
+
tcCategory = "server-actions";
|
|
773
|
+
} else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
|
|
774
|
+
tcCategory = "components";
|
|
775
|
+
} else {
|
|
776
|
+
tcCategory = "other";
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (tcCategory === category) {
|
|
780
|
+
const existing = fileMap.get(tc.file);
|
|
781
|
+
if (existing) {
|
|
782
|
+
existing.count++;
|
|
783
|
+
} else {
|
|
784
|
+
fileMap.set(tc.file, { count: 1, first: tc });
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
return Array.from(fileMap.entries())
|
|
790
|
+
.map(([file, { count, first }]) => ({ file, tests: count, firstTest: first }))
|
|
791
|
+
.sort((a, b) => a.file.localeCompare(b.file));
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Get tests for a specific file
|
|
796
|
+
*/
|
|
797
|
+
export function getTestsByFile(data: TestCasesData, file: string): import("./types").TestCase[] {
|
|
798
|
+
return data.testCases.filter((tc) => tc.file === file);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Extract file slug from path
|
|
803
|
+
*/
|
|
804
|
+
export function fileToSlug(file: string): string {
|
|
805
|
+
return path.basename(file).replace(/\.(test|spec)\.(ts|tsx|js)$/, "");
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Convert category to URL slug
|
|
810
|
+
*/
|
|
811
|
+
export function categoryToSlug(category: string): string {
|
|
812
|
+
return category.toLowerCase().replace(/\s+/g, "-");
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Get test coverage for a feature item from details.json
|
|
817
|
+
* Returns coverage info if found in details, otherwise null
|
|
818
|
+
*/
|
|
819
|
+
export async function getTestCoverageForItem(
|
|
820
|
+
type: string,
|
|
821
|
+
moduleName: string,
|
|
822
|
+
itemName: string
|
|
823
|
+
): Promise<{
|
|
824
|
+
hasTest: boolean;
|
|
825
|
+
totalTests: number;
|
|
826
|
+
coverageScore: number;
|
|
827
|
+
} | null> {
|
|
828
|
+
const details = await loadDetails();
|
|
829
|
+
if (!details) return null;
|
|
830
|
+
|
|
831
|
+
// Try different key patterns (details.json uses various formats)
|
|
832
|
+
const possibleKeys = [
|
|
833
|
+
`${type}/${moduleName}/${itemName}`,
|
|
834
|
+
`${type.toLowerCase()}/${moduleName}/${itemName}`,
|
|
835
|
+
];
|
|
836
|
+
|
|
837
|
+
for (const key of possibleKeys) {
|
|
838
|
+
const item = details.details[key];
|
|
839
|
+
if (item?.testCoverage) {
|
|
840
|
+
return {
|
|
841
|
+
hasTest: item.testCoverage.hasTest,
|
|
842
|
+
totalTests: item.testCoverage.totalTests,
|
|
843
|
+
coverageScore: item.testCoverage.coverageScore,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
return null;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Extract file module from item path
|
|
853
|
+
* e.g., "apps/web/lib/actions/projects.ts" -> "projects"
|
|
854
|
+
*/
|
|
855
|
+
function extractFileModule(itemPath: string | undefined): string | null {
|
|
856
|
+
if (!itemPath) return null;
|
|
857
|
+
const fileName = itemPath.split("/").pop();
|
|
858
|
+
if (!fileName) return null;
|
|
859
|
+
return fileName.replace(/\.(ts|tsx)$/, "");
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* Get aggregated test coverage for a module
|
|
864
|
+
* Sums up coverage from all items in the module
|
|
865
|
+
*/
|
|
866
|
+
export async function getModuleTestCoverage(
|
|
867
|
+
moduleName: string
|
|
868
|
+
): Promise<{
|
|
869
|
+
totalTests: number;
|
|
870
|
+
testedItems: number;
|
|
871
|
+
totalItems: number;
|
|
872
|
+
averageCoverage: number;
|
|
873
|
+
}> {
|
|
874
|
+
const [details, featureMap] = await Promise.all([
|
|
875
|
+
loadDetails(),
|
|
876
|
+
loadFeatureMap(),
|
|
877
|
+
]);
|
|
878
|
+
|
|
879
|
+
if (!details || !featureMap) {
|
|
880
|
+
return { totalTests: 0, testedItems: 0, totalItems: 0, averageCoverage: 0 };
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
const moduleGroup = featureMap.features[moduleName];
|
|
884
|
+
if (!moduleGroup) {
|
|
885
|
+
return { totalTests: 0, testedItems: 0, totalItems: 0, averageCoverage: 0 };
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
let totalTests = 0;
|
|
889
|
+
let testedItems = 0;
|
|
890
|
+
let totalCoverage = 0;
|
|
891
|
+
let totalItems = 0;
|
|
892
|
+
|
|
893
|
+
// Check all item types - include path for correct key lookup
|
|
894
|
+
const itemTypes: Array<{ type: string; items: Array<{ name: string; path?: string }> }> = [
|
|
895
|
+
{ type: "screen", items: moduleGroup.screens || [] },
|
|
896
|
+
{ type: "component", items: moduleGroup.components || [] },
|
|
897
|
+
{ type: "action", items: moduleGroup.actions || [] },
|
|
898
|
+
{ type: "table", items: moduleGroup.tables || [] },
|
|
899
|
+
];
|
|
900
|
+
|
|
901
|
+
for (const { type, items } of itemTypes) {
|
|
902
|
+
for (const item of items) {
|
|
903
|
+
totalItems++;
|
|
904
|
+
|
|
905
|
+
// Extract file module from item path (details.json uses file module as key)
|
|
906
|
+
const fileModule = extractFileModule(item.path);
|
|
907
|
+
|
|
908
|
+
// Try multiple key formats
|
|
909
|
+
const possibleKeys = [
|
|
910
|
+
fileModule ? `${type}/${fileModule}/${item.name}` : null,
|
|
911
|
+
`${type}/${moduleName}/${item.name}`,
|
|
912
|
+
].filter((k): k is string => k !== null);
|
|
913
|
+
|
|
914
|
+
let found = false;
|
|
915
|
+
for (const key of possibleKeys) {
|
|
916
|
+
const detail = details.details[key];
|
|
917
|
+
if (detail?.testCoverage) {
|
|
918
|
+
totalTests += detail.testCoverage.totalTests;
|
|
919
|
+
if (detail.testCoverage.hasTest) {
|
|
920
|
+
testedItems++;
|
|
921
|
+
totalCoverage += detail.testCoverage.coverageScore;
|
|
922
|
+
}
|
|
923
|
+
found = true;
|
|
924
|
+
break;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
return {
|
|
931
|
+
totalTests,
|
|
932
|
+
testedItems,
|
|
933
|
+
totalItems,
|
|
934
|
+
averageCoverage: testedItems > 0 ? Math.round(totalCoverage / testedItems) : 0,
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Group tests by feature module
|
|
940
|
+
* Returns tests organized by module name instead of file path
|
|
941
|
+
*/
|
|
942
|
+
export async function getTestsByModule(): Promise<
|
|
943
|
+
Map<string, {
|
|
944
|
+
moduleName: string;
|
|
945
|
+
tests: import("./types").TestCase[];
|
|
946
|
+
coverage: { totalTests: number; testedItems: number; totalItems: number };
|
|
947
|
+
}>
|
|
948
|
+
> {
|
|
949
|
+
const [testCases, details, featureMap] = await Promise.all([
|
|
950
|
+
loadTestCases(),
|
|
951
|
+
loadDetails(),
|
|
952
|
+
loadFeatureMap(),
|
|
953
|
+
]);
|
|
954
|
+
|
|
955
|
+
const moduleTests = new Map<string, {
|
|
956
|
+
moduleName: string;
|
|
957
|
+
tests: import("./types").TestCase[];
|
|
958
|
+
coverage: { totalTests: number; testedItems: number; totalItems: number };
|
|
959
|
+
}>();
|
|
960
|
+
|
|
961
|
+
if (!testCases || !featureMap) return moduleTests;
|
|
962
|
+
|
|
963
|
+
// Build a map of source file path -> module name
|
|
964
|
+
const pathToModule = new Map<string, string>();
|
|
965
|
+
|
|
966
|
+
for (const [moduleName, group] of Object.entries(featureMap.features)) {
|
|
967
|
+
const allItems = [
|
|
968
|
+
...(group.screens || []),
|
|
969
|
+
...(group.components || []),
|
|
970
|
+
...(group.actions || []),
|
|
971
|
+
...(group.tables || []),
|
|
972
|
+
];
|
|
973
|
+
for (const item of allItems) {
|
|
974
|
+
if ("path" in item && item.path) {
|
|
975
|
+
pathToModule.set(item.path, moduleName);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Group tests by module based on their source file
|
|
981
|
+
for (const tc of testCases.testCases) {
|
|
982
|
+
// Find module from test file's associated source
|
|
983
|
+
let moduleName = "Uncategorized";
|
|
984
|
+
|
|
985
|
+
// Try to infer module from test file path
|
|
986
|
+
const testPath = tc.file;
|
|
987
|
+
// E2E tests often test specific modules
|
|
988
|
+
for (const [srcPath, module] of pathToModule.entries()) {
|
|
989
|
+
const srcFileName = srcPath.split("/").pop()?.replace(/\.(ts|tsx)$/, "");
|
|
990
|
+
if (srcFileName && testPath.includes(srcFileName)) {
|
|
991
|
+
moduleName = module;
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Also check based on linked-docs if available
|
|
997
|
+
if (details) {
|
|
998
|
+
for (const [key, item] of Object.entries(details.details)) {
|
|
999
|
+
if (item.testCoverage?.byCategory) {
|
|
1000
|
+
for (const tests of Object.values(item.testCoverage.byCategory)) {
|
|
1001
|
+
for (const t of tests) {
|
|
1002
|
+
if (t.file === tc.file && t.name === tc.it) {
|
|
1003
|
+
const keyParts = key.split("/");
|
|
1004
|
+
if (keyParts.length >= 2) {
|
|
1005
|
+
moduleName = keyParts[1];
|
|
1006
|
+
}
|
|
1007
|
+
break;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
if (!moduleTests.has(moduleName)) {
|
|
1016
|
+
moduleTests.set(moduleName, {
|
|
1017
|
+
moduleName,
|
|
1018
|
+
tests: [],
|
|
1019
|
+
coverage: { totalTests: 0, testedItems: 0, totalItems: 0 },
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
moduleTests.get(moduleName)!.tests.push(tc);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// Update coverage stats
|
|
1026
|
+
for (const [moduleName, data] of moduleTests.entries()) {
|
|
1027
|
+
const moduleCoverage = await getModuleTestCoverage(moduleName);
|
|
1028
|
+
data.coverage = {
|
|
1029
|
+
totalTests: data.tests.length,
|
|
1030
|
+
testedItems: moduleCoverage.testedItems,
|
|
1031
|
+
totalItems: moduleCoverage.totalItems,
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
return moduleTests;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Get sidebar navigation data
|
|
1040
|
+
*/
|
|
1041
|
+
export async function getSidebarNavData(): Promise<{
|
|
1042
|
+
modules: { name: string; screens: number; components: number; actions: number; tables: number }[];
|
|
1043
|
+
testCategories: { name: string; slug: string; count: number }[];
|
|
1044
|
+
packages: { name: string; prefix: string; moduleCount: number; exportCount: number }[];
|
|
1045
|
+
hasFeatureMap: boolean;
|
|
1046
|
+
hasDbSchema: boolean;
|
|
1047
|
+
hasTestCases: boolean;
|
|
1048
|
+
hasOverview: boolean;
|
|
1049
|
+
hasApiTools: boolean;
|
|
1050
|
+
hasI18n: boolean;
|
|
1051
|
+
hasPackages: boolean;
|
|
1052
|
+
applications: ApplicationsData | null;
|
|
1053
|
+
}> {
|
|
1054
|
+
const [featureMap, testCases, available, applications, packagesData] = await Promise.all([
|
|
1055
|
+
loadFeatureMap(),
|
|
1056
|
+
loadTestCases(),
|
|
1057
|
+
getAvailableData(),
|
|
1058
|
+
loadApplications(),
|
|
1059
|
+
loadPackages(),
|
|
1060
|
+
]);
|
|
1061
|
+
|
|
1062
|
+
// Extract modules from feature map
|
|
1063
|
+
const modules: { name: string; screens: number; components: number; actions: number; tables: number }[] = [];
|
|
1064
|
+
|
|
1065
|
+
if (featureMap) {
|
|
1066
|
+
for (const [name, group] of Object.entries(featureMap.features)) {
|
|
1067
|
+
modules.push({
|
|
1068
|
+
name,
|
|
1069
|
+
screens: group.screens?.length || 0,
|
|
1070
|
+
components: group.components?.length || 0,
|
|
1071
|
+
actions: group.actions?.length || 0,
|
|
1072
|
+
tables: group.tables?.length || 0,
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// Add uncategorized if it has items
|
|
1077
|
+
const uncategorized = featureMap.uncategorized;
|
|
1078
|
+
if (uncategorized.screens?.length || uncategorized.components?.length ||
|
|
1079
|
+
uncategorized.actions?.length || uncategorized.tables?.length) {
|
|
1080
|
+
modules.push({
|
|
1081
|
+
name: "Uncategorized",
|
|
1082
|
+
screens: uncategorized.screens?.length || 0,
|
|
1083
|
+
components: uncategorized.components?.length || 0,
|
|
1084
|
+
actions: uncategorized.actions?.length || 0,
|
|
1085
|
+
tables: uncategorized.tables?.length || 0,
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// Extract test categories
|
|
1091
|
+
const testCategories: { name: string; slug: string; count: number }[] = [];
|
|
1092
|
+
|
|
1093
|
+
if (testCases) {
|
|
1094
|
+
const categoryCounts = new Map<string, number>();
|
|
1095
|
+
|
|
1096
|
+
for (const tc of testCases.testCases) {
|
|
1097
|
+
let category: string;
|
|
1098
|
+
if (tc.framework === "playwright") {
|
|
1099
|
+
category = "e2e";
|
|
1100
|
+
} else if (tc.file.includes("/actions/") || tc.file.includes("__tests__/lib/actions/")) {
|
|
1101
|
+
category = "server-actions";
|
|
1102
|
+
} else if (tc.file.includes("/components/") || tc.file.includes("__tests__/components/")) {
|
|
1103
|
+
category = "components";
|
|
1104
|
+
} else {
|
|
1105
|
+
category = "other";
|
|
1106
|
+
}
|
|
1107
|
+
categoryCounts.set(category, (categoryCounts.get(category) || 0) + 1);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
const categoryLabels: Record<string, string> = {
|
|
1111
|
+
"e2e": "E2E テスト",
|
|
1112
|
+
"server-actions": "Server Actions",
|
|
1113
|
+
"components": "Components",
|
|
1114
|
+
"other": "その他",
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
for (const [slug, count] of categoryCounts.entries()) {
|
|
1118
|
+
testCategories.push({
|
|
1119
|
+
name: categoryLabels[slug] || slug,
|
|
1120
|
+
slug,
|
|
1121
|
+
count,
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// Sort by count descending
|
|
1126
|
+
testCategories.sort((a, b) => b.count - a.count);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// Extract packages data
|
|
1130
|
+
const packages: { name: string; prefix: string; moduleCount: number; exportCount: number }[] = [];
|
|
1131
|
+
if (packagesData) {
|
|
1132
|
+
for (const pkg of packagesData.packages) {
|
|
1133
|
+
packages.push({
|
|
1134
|
+
name: pkg.name,
|
|
1135
|
+
prefix: pkg.prefix,
|
|
1136
|
+
moduleCount: pkg.stats.moduleCount,
|
|
1137
|
+
exportCount: pkg.stats.exportCount,
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
return {
|
|
1143
|
+
modules,
|
|
1144
|
+
testCategories,
|
|
1145
|
+
packages,
|
|
1146
|
+
hasFeatureMap: available.hasFeatureMap,
|
|
1147
|
+
hasDbSchema: available.hasDbSchema,
|
|
1148
|
+
hasTestCases: available.hasTestCases,
|
|
1149
|
+
hasOverview: available.hasOverview,
|
|
1150
|
+
hasApiTools: available.hasApiTools,
|
|
1151
|
+
hasI18n: available.hasI18n,
|
|
1152
|
+
hasPackages: available.hasPackages,
|
|
1153
|
+
applications,
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/**
|
|
1158
|
+
* Load or generate search index
|
|
1159
|
+
*/
|
|
1160
|
+
export async function loadSearchIndex(): Promise<SearchIndex | null> {
|
|
1161
|
+
try {
|
|
1162
|
+
// Try to load pre-generated search index first
|
|
1163
|
+
const cached = await readJsonFile<SearchIndex>("search-index.json");
|
|
1164
|
+
if (cached) {
|
|
1165
|
+
return cached;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// Generate search index from available data
|
|
1169
|
+
const [featureMap, dbSchema, testCases, details] = await Promise.all([
|
|
1170
|
+
loadFeatureMap(),
|
|
1171
|
+
loadDbSchema(),
|
|
1172
|
+
loadTestCases(),
|
|
1173
|
+
loadDetails(),
|
|
1174
|
+
]);
|
|
1175
|
+
|
|
1176
|
+
return generateSearchIndex(featureMap, dbSchema, testCases, details);
|
|
1177
|
+
} catch (error) {
|
|
1178
|
+
console.warn("Failed to load search index:", error);
|
|
1179
|
+
return null;
|
|
1180
|
+
}
|
|
1181
|
+
}
|