@openpkg-ts/fumadocs-adapter 0.2.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/CHANGELOG.md +39 -0
- package/bunup.config.ts +9 -0
- package/dist/components/index.d.ts +27 -0
- package/dist/components/index.js +44 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +80 -0
- package/dist/shared/chunk-a91ch1vp.js +100 -0
- package/examples/01-basic-usage.ts +103 -0
- package/package.json +29 -0
- package/src/components/coverage-badge.tsx +110 -0
- package/src/components/index.ts +42 -0
- package/src/index.ts +83 -0
- package/src/styles/docskit.css +131 -0
- package/tsconfig.json +20 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @openpkg-ts/fumadocs-adapter
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Rename package from @doccov/fumadocs-adapter to @openpkg-ts/fumadocs-adapter
|
|
8
|
+
|
|
9
|
+
## 0.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Initial release of @openpkg-ts/doc-generator
|
|
14
|
+
|
|
15
|
+
- Core API: createDocs(), loadSpec() for loading OpenPkg specs
|
|
16
|
+
- Query utilities: formatSchema(), buildSignatureString(), member filtering and sorting
|
|
17
|
+
- Renderers: Markdown/MDX, HTML, JSON output formats
|
|
18
|
+
- Navigation: Fumadocs, Docusaurus, and generic nav generation
|
|
19
|
+
- Search: Pagefind and Algolia compatible indexes
|
|
20
|
+
- React components: Headless (unstyled) and styled (Tailwind v4) variants
|
|
21
|
+
- CLI: generate, build, dev commands
|
|
22
|
+
- Adapter architecture: Extensible framework integration pattern
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @openpkg-ts/doc-generator@0.1.0
|
|
28
|
+
|
|
29
|
+
## 0.0.3
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Remove deprecated `tsType` field in favor of `schema`, add CLI warning when `--runtime` requested without built code
|
|
34
|
+
|
|
35
|
+
## 0.0.2
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- update components and configuration
|
package/bunup.config.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CollapsibleMethod, CollapsibleMethodProps, ExampleBlock, ExampleBlockProps, ExpandableProperty, ExpandablePropertyProps, MemberRow, MemberRowProps, MembersTable, MembersTableProps, NestedProperty, NestedPropertyProps, ParamRow, ParamRowProps, ParamTable, ParamTableProps, Signature, SignatureProps, TypeTable, TypeTableProps } from "@openpkg-ts/doc-generator/react";
|
|
2
|
+
import { APIPage, APIPageProps, ClassPage, ClassPageProps, EnumPage, EnumPageProps, FunctionPage, FunctionPageProps, InterfacePage, InterfacePageProps, VariablePage, VariablePageProps } from "@openpkg-ts/doc-generator/react/styled";
|
|
3
|
+
/**
|
|
4
|
+
* Documentation drift information.
|
|
5
|
+
* Describes a mismatch between docs and code.
|
|
6
|
+
*/
|
|
7
|
+
interface DocDrift {
|
|
8
|
+
type: string;
|
|
9
|
+
issue: string;
|
|
10
|
+
suggestion?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Documentation metadata for an export.
|
|
14
|
+
* Contains coverage score, missing docs, and drift issues.
|
|
15
|
+
*/
|
|
16
|
+
interface DocsMetadata {
|
|
17
|
+
coverageScore?: number;
|
|
18
|
+
missing?: string[];
|
|
19
|
+
drift?: DocDrift[];
|
|
20
|
+
}
|
|
21
|
+
interface CoverageBadgeProps {
|
|
22
|
+
docs: DocsMetadata;
|
|
23
|
+
showMissing?: boolean;
|
|
24
|
+
showDrift?: boolean;
|
|
25
|
+
}
|
|
26
|
+
declare function CoverageBadge({ docs, showMissing, showDrift }: CoverageBadgeProps): React.ReactNode;
|
|
27
|
+
export { VariablePageProps, VariablePage, TypeTableProps, TypeTable, SignatureProps, Signature, ParamTableProps, ParamTable, ParamRowProps, ParamRow, NestedPropertyProps, NestedProperty, MembersTableProps, MembersTable, MemberRowProps, MemberRow, InterfacePageProps, InterfacePage, FunctionPageProps, FunctionPage, ExpandablePropertyProps, ExpandableProperty, ExampleBlockProps, ExampleBlock, EnumPageProps, EnumPage, DocsMetadata, DocDrift, CoverageBadgeProps, CoverageBadge, CollapsibleMethodProps, CollapsibleMethod, ClassPageProps, ClassPage, APIPageProps, APIPage };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CoverageBadge
|
|
3
|
+
} from "../shared/chunk-a91ch1vp.js";
|
|
4
|
+
|
|
5
|
+
// src/components/index.ts
|
|
6
|
+
import {
|
|
7
|
+
CollapsibleMethod,
|
|
8
|
+
ExampleBlock,
|
|
9
|
+
ExpandableProperty,
|
|
10
|
+
MemberRow,
|
|
11
|
+
MembersTable,
|
|
12
|
+
NestedProperty,
|
|
13
|
+
ParamRow,
|
|
14
|
+
ParamTable,
|
|
15
|
+
Signature,
|
|
16
|
+
TypeTable
|
|
17
|
+
} from "@openpkg-ts/doc-generator/react";
|
|
18
|
+
import {
|
|
19
|
+
APIPage,
|
|
20
|
+
ClassPage,
|
|
21
|
+
EnumPage,
|
|
22
|
+
FunctionPage,
|
|
23
|
+
InterfacePage,
|
|
24
|
+
VariablePage
|
|
25
|
+
} from "@openpkg-ts/doc-generator/react/styled";
|
|
26
|
+
export {
|
|
27
|
+
VariablePage,
|
|
28
|
+
TypeTable,
|
|
29
|
+
Signature,
|
|
30
|
+
ParamTable,
|
|
31
|
+
ParamRow,
|
|
32
|
+
NestedProperty,
|
|
33
|
+
MembersTable,
|
|
34
|
+
MemberRow,
|
|
35
|
+
InterfacePage,
|
|
36
|
+
FunctionPage,
|
|
37
|
+
ExpandableProperty,
|
|
38
|
+
ExampleBlock,
|
|
39
|
+
EnumPage,
|
|
40
|
+
CoverageBadge,
|
|
41
|
+
CollapsibleMethod,
|
|
42
|
+
ClassPage,
|
|
43
|
+
APIPage
|
|
44
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DocsInstance, LoadOptions, OpenPkg, SpecExample, SpecExport, SpecExportKind, SpecMember, SpecSchema, SpecSignature, SpecSignatureParameter, SpecTag, SpecType, SpecTypeKind, SpecTypeParameter } from "@openpkg-ts/doc-generator";
|
|
2
|
+
import { AlgoliaRecord, buildSignatureString, createDocs, createDocs as createDocs2, DocsInstance as DocsInstance2, ExportMarkdownOptions, exportToMarkdown, formatParameters, formatReturnType, formatSchema, formatTypeParameters, getMethods, getProperties, groupByVisibility, HTMLOptions, isMethod, isProperty, JSONOptions, LoadOptions as LoadOptions2, loadSpec, MarkdownOptions, NavOptions, PagefindRecord, resolveTypeRef, SearchIndex, SearchOptions, SearchRecord, sortByKindThenName, sortByName, toAlgoliaRecords, toDocusaurusSidebarJS, toFumadocsMetaJSON, toHTML, toJSON, toJSONString, toMarkdown, toNavigation, toPagefindRecords, toSearchIndex, toSearchIndexJSON } from "@openpkg-ts/doc-generator";
|
|
3
|
+
import { APIPage, APIPageProps, ClassPage, ClassPageProps, EnumPage, EnumPageProps, FunctionPage, FunctionPageProps, InterfacePage, InterfacePageProps, VariablePage, VariablePageProps } from "@openpkg-ts/doc-generator/react/styled";
|
|
4
|
+
/**
|
|
5
|
+
* Documentation drift information.
|
|
6
|
+
* Describes a mismatch between docs and code.
|
|
7
|
+
*/
|
|
8
|
+
interface DocDrift {
|
|
9
|
+
type: string;
|
|
10
|
+
issue: string;
|
|
11
|
+
suggestion?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Documentation metadata for an export.
|
|
15
|
+
* Contains coverage score, missing docs, and drift issues.
|
|
16
|
+
*/
|
|
17
|
+
interface DocsMetadata {
|
|
18
|
+
coverageScore?: number;
|
|
19
|
+
missing?: string[];
|
|
20
|
+
drift?: DocDrift[];
|
|
21
|
+
}
|
|
22
|
+
interface CoverageBadgeProps {
|
|
23
|
+
docs: DocsMetadata;
|
|
24
|
+
showMissing?: boolean;
|
|
25
|
+
showDrift?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare function CoverageBadge({ docs, showMissing, showDrift }: CoverageBadgeProps): React.ReactNode;
|
|
28
|
+
export { toSearchIndexJSON, toSearchIndex, toPagefindRecords, toNavigation, toMarkdown, toJSONString, toJSON, toHTML, toFumadocsMetaJSON, toDocusaurusSidebarJS, toAlgoliaRecords, sortByName, sortByKindThenName, resolveTypeRef, loadSpec, isProperty, isMethod, groupByVisibility, getProperties, getMethods, formatTypeParameters, formatSchema, formatReturnType, formatParameters, exportToMarkdown, createDocs2 as createOpenPkg, createDocs, buildSignatureString, VariablePageProps, VariablePage, SpecTypeParameter, SpecTypeKind, SpecType, SpecTag, SpecSignatureParameter, SpecSignature, SpecSchema, SpecMember, SpecExportKind, SpecExport, SpecExample, SearchRecord, SearchOptions, SearchIndex, PagefindRecord, LoadOptions as OpenPkgOptions, DocsInstance as OpenPkgInstance, OpenPkg, NavOptions, MarkdownOptions, LoadOptions2 as LoadOptions, JSONOptions, InterfacePageProps, InterfacePage, HTMLOptions, FunctionPageProps, FunctionPage, ExportMarkdownOptions, EnumPageProps, EnumPage, DocsMetadata, DocsInstance2 as DocsInstance, DocDrift, CoverageBadgeProps, CoverageBadge, ClassPageProps, ClassPage, AlgoliaRecord, APIPageProps, APIPage };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CoverageBadge
|
|
3
|
+
} from "./shared/chunk-a91ch1vp.js";
|
|
4
|
+
|
|
5
|
+
// src/index.ts
|
|
6
|
+
import {
|
|
7
|
+
buildSignatureString,
|
|
8
|
+
createDocs,
|
|
9
|
+
createDocs as createDocs2,
|
|
10
|
+
exportToMarkdown,
|
|
11
|
+
formatParameters,
|
|
12
|
+
formatReturnType,
|
|
13
|
+
formatSchema,
|
|
14
|
+
formatTypeParameters,
|
|
15
|
+
getMethods,
|
|
16
|
+
getProperties,
|
|
17
|
+
groupByVisibility,
|
|
18
|
+
isMethod,
|
|
19
|
+
isProperty,
|
|
20
|
+
loadSpec,
|
|
21
|
+
resolveTypeRef,
|
|
22
|
+
sortByKindThenName,
|
|
23
|
+
sortByName,
|
|
24
|
+
toAlgoliaRecords,
|
|
25
|
+
toDocusaurusSidebarJS,
|
|
26
|
+
toFumadocsMetaJSON,
|
|
27
|
+
toHTML,
|
|
28
|
+
toJSON,
|
|
29
|
+
toJSONString,
|
|
30
|
+
toMarkdown,
|
|
31
|
+
toNavigation,
|
|
32
|
+
toPagefindRecords,
|
|
33
|
+
toSearchIndex,
|
|
34
|
+
toSearchIndexJSON
|
|
35
|
+
} from "@openpkg-ts/doc-generator";
|
|
36
|
+
import {
|
|
37
|
+
APIPage,
|
|
38
|
+
ClassPage,
|
|
39
|
+
EnumPage,
|
|
40
|
+
FunctionPage,
|
|
41
|
+
InterfacePage,
|
|
42
|
+
VariablePage
|
|
43
|
+
} from "@openpkg-ts/doc-generator/react/styled";
|
|
44
|
+
export {
|
|
45
|
+
toSearchIndexJSON,
|
|
46
|
+
toSearchIndex,
|
|
47
|
+
toPagefindRecords,
|
|
48
|
+
toNavigation,
|
|
49
|
+
toMarkdown,
|
|
50
|
+
toJSONString,
|
|
51
|
+
toJSON,
|
|
52
|
+
toHTML,
|
|
53
|
+
toFumadocsMetaJSON,
|
|
54
|
+
toDocusaurusSidebarJS,
|
|
55
|
+
toAlgoliaRecords,
|
|
56
|
+
sortByName,
|
|
57
|
+
sortByKindThenName,
|
|
58
|
+
resolveTypeRef,
|
|
59
|
+
loadSpec,
|
|
60
|
+
isProperty,
|
|
61
|
+
isMethod,
|
|
62
|
+
groupByVisibility,
|
|
63
|
+
getProperties,
|
|
64
|
+
getMethods,
|
|
65
|
+
formatTypeParameters,
|
|
66
|
+
formatSchema,
|
|
67
|
+
formatReturnType,
|
|
68
|
+
formatParameters,
|
|
69
|
+
exportToMarkdown,
|
|
70
|
+
createDocs2 as createOpenPkg,
|
|
71
|
+
createDocs,
|
|
72
|
+
buildSignatureString,
|
|
73
|
+
VariablePage,
|
|
74
|
+
InterfacePage,
|
|
75
|
+
FunctionPage,
|
|
76
|
+
EnumPage,
|
|
77
|
+
CoverageBadge,
|
|
78
|
+
ClassPage,
|
|
79
|
+
APIPage
|
|
80
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/components/coverage-badge.tsx
|
|
3
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
4
|
+
|
|
5
|
+
function getScoreColor(score) {
|
|
6
|
+
if (score >= 80)
|
|
7
|
+
return "text-green-600 dark:text-green-400 bg-green-500/10 border-green-500/20";
|
|
8
|
+
if (score >= 60)
|
|
9
|
+
return "text-yellow-600 dark:text-yellow-400 bg-yellow-500/10 border-yellow-500/20";
|
|
10
|
+
return "text-red-600 dark:text-red-400 bg-red-500/10 border-red-500/20";
|
|
11
|
+
}
|
|
12
|
+
function formatSignal(signal) {
|
|
13
|
+
return signal.charAt(0).toUpperCase() + signal.slice(1);
|
|
14
|
+
}
|
|
15
|
+
function CoverageBadge({
|
|
16
|
+
docs,
|
|
17
|
+
showMissing = true,
|
|
18
|
+
showDrift = true
|
|
19
|
+
}) {
|
|
20
|
+
const score = docs.coverageScore;
|
|
21
|
+
const hasMissing = showMissing && docs.missing && docs.missing.length > 0;
|
|
22
|
+
const hasDrift = showDrift && docs.drift && docs.drift.length > 0;
|
|
23
|
+
if (score == null && !hasMissing && !hasDrift)
|
|
24
|
+
return null;
|
|
25
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
26
|
+
className: "my-6 space-y-3",
|
|
27
|
+
children: [
|
|
28
|
+
score != null && /* @__PURE__ */ jsxDEV("div", {
|
|
29
|
+
className: `inline-flex items-center gap-2 px-3 py-1.5 rounded-md border text-sm font-medium ${getScoreColor(score)}`,
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsxDEV("svg", {
|
|
32
|
+
className: "w-4 h-4",
|
|
33
|
+
fill: "none",
|
|
34
|
+
stroke: "currentColor",
|
|
35
|
+
viewBox: "0 0 24 24",
|
|
36
|
+
"aria-hidden": "true",
|
|
37
|
+
children: /* @__PURE__ */ jsxDEV("path", {
|
|
38
|
+
strokeLinecap: "round",
|
|
39
|
+
strokeLinejoin: "round",
|
|
40
|
+
strokeWidth: 2,
|
|
41
|
+
d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
42
|
+
}, undefined, false, undefined, this)
|
|
43
|
+
}, undefined, false, undefined, this),
|
|
44
|
+
"Coverage: ",
|
|
45
|
+
score,
|
|
46
|
+
"%"
|
|
47
|
+
]
|
|
48
|
+
}, undefined, true, undefined, this),
|
|
49
|
+
hasMissing && /* @__PURE__ */ jsxDEV("div", {
|
|
50
|
+
className: "rounded-md bg-yellow-500/10 border border-yellow-500/20 px-3 py-2",
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
53
|
+
className: "text-sm font-medium text-yellow-600 dark:text-yellow-400 mb-1",
|
|
54
|
+
children: "Missing Documentation"
|
|
55
|
+
}, undefined, false, undefined, this),
|
|
56
|
+
/* @__PURE__ */ jsxDEV("ul", {
|
|
57
|
+
className: "text-sm text-yellow-600/80 dark:text-yellow-400/80 list-disc list-inside",
|
|
58
|
+
children: docs.missing.map((signal) => /* @__PURE__ */ jsxDEV("li", {
|
|
59
|
+
children: formatSignal(signal)
|
|
60
|
+
}, signal, false, undefined, this))
|
|
61
|
+
}, undefined, false, undefined, this)
|
|
62
|
+
]
|
|
63
|
+
}, undefined, true, undefined, this),
|
|
64
|
+
hasDrift && /* @__PURE__ */ jsxDEV("div", {
|
|
65
|
+
className: "rounded-md bg-red-500/10 border border-red-500/20 px-3 py-2",
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
68
|
+
className: "text-sm font-medium text-red-600 dark:text-red-400 mb-1",
|
|
69
|
+
children: "Documentation Drift"
|
|
70
|
+
}, undefined, false, undefined, this),
|
|
71
|
+
/* @__PURE__ */ jsxDEV("ul", {
|
|
72
|
+
className: "text-sm text-red-600/80 dark:text-red-400/80 space-y-1",
|
|
73
|
+
children: docs.drift.map((drift) => /* @__PURE__ */ jsxDEV("li", {
|
|
74
|
+
className: "flex flex-col",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
77
|
+
className: "font-medium",
|
|
78
|
+
children: drift.type
|
|
79
|
+
}, undefined, false, undefined, this),
|
|
80
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
81
|
+
className: "text-xs opacity-80",
|
|
82
|
+
children: drift.issue
|
|
83
|
+
}, undefined, false, undefined, this),
|
|
84
|
+
drift.suggestion && /* @__PURE__ */ jsxDEV("span", {
|
|
85
|
+
className: "text-xs text-fd-muted-foreground mt-0.5",
|
|
86
|
+
children: [
|
|
87
|
+
"Suggestion: ",
|
|
88
|
+
drift.suggestion
|
|
89
|
+
]
|
|
90
|
+
}, undefined, true, undefined, this)
|
|
91
|
+
]
|
|
92
|
+
}, `${drift.type}-${drift.issue}`, true, undefined, this))
|
|
93
|
+
}, undefined, false, undefined, this)
|
|
94
|
+
]
|
|
95
|
+
}, undefined, true, undefined, this)
|
|
96
|
+
]
|
|
97
|
+
}, undefined, true, undefined, this);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { CoverageBadge };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Fumadocs Adapter Basic Usage
|
|
3
|
+
*
|
|
4
|
+
* Run from fumadocs-adapter: bun examples/01-basic-usage.ts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
buildSignatureString,
|
|
9
|
+
// Core API (re-exported from doc-generator)
|
|
10
|
+
createDocs,
|
|
11
|
+
createOpenPkg, // backward compat alias
|
|
12
|
+
// Query utilities
|
|
13
|
+
formatSchema,
|
|
14
|
+
getMethods,
|
|
15
|
+
getProperties,
|
|
16
|
+
toFumadocsMetaJSON,
|
|
17
|
+
// Render utilities
|
|
18
|
+
toMarkdown,
|
|
19
|
+
toNavigation,
|
|
20
|
+
// Search
|
|
21
|
+
toSearchIndex,
|
|
22
|
+
} from '../src/index';
|
|
23
|
+
|
|
24
|
+
// Sample spec for testing
|
|
25
|
+
const sampleSpec = {
|
|
26
|
+
openpkg: '0.4.0',
|
|
27
|
+
meta: {
|
|
28
|
+
ecosystem: 'js/ts',
|
|
29
|
+
name: 'test-package',
|
|
30
|
+
version: '1.0.0',
|
|
31
|
+
},
|
|
32
|
+
exports: [
|
|
33
|
+
{
|
|
34
|
+
id: 'hello',
|
|
35
|
+
name: 'hello',
|
|
36
|
+
kind: 'function',
|
|
37
|
+
description: 'Say hello',
|
|
38
|
+
signatures: [
|
|
39
|
+
{
|
|
40
|
+
parameters: [{ name: 'name', required: true, schema: { type: 'string' } }],
|
|
41
|
+
returns: { schema: { type: 'string' } },
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'Config',
|
|
47
|
+
name: 'Config',
|
|
48
|
+
kind: 'interface',
|
|
49
|
+
description: 'Configuration interface',
|
|
50
|
+
members: [
|
|
51
|
+
{ name: 'debug', kind: 'property', schema: { type: 'boolean' }, optional: true },
|
|
52
|
+
{ name: 'timeout', kind: 'property', schema: { type: 'number' } },
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
types: [],
|
|
57
|
+
} as any;
|
|
58
|
+
|
|
59
|
+
console.log('=== Fumadocs Adapter Usage ===\n');
|
|
60
|
+
|
|
61
|
+
// Use createDocs (preferred)
|
|
62
|
+
const docs = createDocs(sampleSpec);
|
|
63
|
+
console.log('Package:', docs.spec.meta.name);
|
|
64
|
+
console.log('Exports:', docs.getAllExports().length);
|
|
65
|
+
|
|
66
|
+
// Or use createOpenPkg (backward compat)
|
|
67
|
+
const openpkg = createOpenPkg(sampleSpec);
|
|
68
|
+
console.log('\nUsing createOpenPkg (backward compat):');
|
|
69
|
+
console.log('Same API:', openpkg.spec.meta.name);
|
|
70
|
+
|
|
71
|
+
// Query
|
|
72
|
+
console.log('\n--- Query ---');
|
|
73
|
+
const hello = docs.getExport('hello');
|
|
74
|
+
if (hello) {
|
|
75
|
+
console.log('Signature:', buildSignatureString(hello));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const config = docs.getExport('Config');
|
|
79
|
+
if (config?.members) {
|
|
80
|
+
console.log(
|
|
81
|
+
'Config properties:',
|
|
82
|
+
getProperties(config.members)
|
|
83
|
+
.map((p) => p.name)
|
|
84
|
+
.join(', '),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Render
|
|
89
|
+
console.log('\n--- Render ---');
|
|
90
|
+
const md = docs.toMarkdown({ export: 'hello' });
|
|
91
|
+
console.log('Markdown:\n', md);
|
|
92
|
+
|
|
93
|
+
// Navigation for Fumadocs
|
|
94
|
+
console.log('\n--- Fumadocs Navigation ---');
|
|
95
|
+
const meta = toFumadocsMetaJSON(sampleSpec, { basePath: '/api' });
|
|
96
|
+
console.log(meta);
|
|
97
|
+
|
|
98
|
+
// Search index
|
|
99
|
+
console.log('\n--- Search Index ---');
|
|
100
|
+
const searchIndex = toSearchIndex(sampleSpec);
|
|
101
|
+
console.log('Records:', searchIndex.records.length);
|
|
102
|
+
|
|
103
|
+
console.log('\n=== Done ===');
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openpkg-ts/fumadocs-adapter",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Fumadocs integration for OpenPkg API documentation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.ts",
|
|
9
|
+
"./components": "./src/components/index.ts",
|
|
10
|
+
"./css": "./src/styles/docskit.css"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "bunup",
|
|
14
|
+
"lint": "biome check src/",
|
|
15
|
+
"lint:fix": "biome check --write src/",
|
|
16
|
+
"typecheck": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@openpkg-ts/doc-generator": "^0.1.0"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"react": "^18 || ^19"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/react": "^19.0.0",
|
|
26
|
+
"bunup": "^0.11.5",
|
|
27
|
+
"typescript": "^5.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Documentation drift information.
|
|
5
|
+
* Describes a mismatch between docs and code.
|
|
6
|
+
*/
|
|
7
|
+
export interface DocDrift {
|
|
8
|
+
type: string;
|
|
9
|
+
issue: string;
|
|
10
|
+
suggestion?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Documentation metadata for an export.
|
|
15
|
+
* Contains coverage score, missing docs, and drift issues.
|
|
16
|
+
*/
|
|
17
|
+
export interface DocsMetadata {
|
|
18
|
+
coverageScore?: number;
|
|
19
|
+
missing?: string[];
|
|
20
|
+
drift?: DocDrift[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CoverageBadgeProps {
|
|
24
|
+
docs: DocsMetadata;
|
|
25
|
+
showMissing?: boolean;
|
|
26
|
+
showDrift?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getScoreColor(score: number): string {
|
|
30
|
+
if (score >= 80) return 'text-green-600 dark:text-green-400 bg-green-500/10 border-green-500/20';
|
|
31
|
+
if (score >= 60)
|
|
32
|
+
return 'text-yellow-600 dark:text-yellow-400 bg-yellow-500/10 border-yellow-500/20';
|
|
33
|
+
return 'text-red-600 dark:text-red-400 bg-red-500/10 border-red-500/20';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatSignal(signal: string): string {
|
|
37
|
+
return signal.charAt(0).toUpperCase() + signal.slice(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function CoverageBadge({
|
|
41
|
+
docs,
|
|
42
|
+
showMissing = true,
|
|
43
|
+
showDrift = true,
|
|
44
|
+
}: CoverageBadgeProps): React.ReactNode {
|
|
45
|
+
const score = docs.coverageScore;
|
|
46
|
+
const hasMissing = showMissing && docs.missing && docs.missing.length > 0;
|
|
47
|
+
const hasDrift = showDrift && docs.drift && docs.drift.length > 0;
|
|
48
|
+
|
|
49
|
+
if (score == null && !hasMissing && !hasDrift) return null;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div className="my-6 space-y-3">
|
|
53
|
+
{score != null && (
|
|
54
|
+
<div
|
|
55
|
+
className={`inline-flex items-center gap-2 px-3 py-1.5 rounded-md border text-sm font-medium ${getScoreColor(score)}`}
|
|
56
|
+
>
|
|
57
|
+
<svg
|
|
58
|
+
className="w-4 h-4"
|
|
59
|
+
fill="none"
|
|
60
|
+
stroke="currentColor"
|
|
61
|
+
viewBox="0 0 24 24"
|
|
62
|
+
aria-hidden="true"
|
|
63
|
+
>
|
|
64
|
+
<path
|
|
65
|
+
strokeLinecap="round"
|
|
66
|
+
strokeLinejoin="round"
|
|
67
|
+
strokeWidth={2}
|
|
68
|
+
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
Coverage: {score}%
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
|
|
75
|
+
{hasMissing && (
|
|
76
|
+
<div className="rounded-md bg-yellow-500/10 border border-yellow-500/20 px-3 py-2">
|
|
77
|
+
<p className="text-sm font-medium text-yellow-600 dark:text-yellow-400 mb-1">
|
|
78
|
+
Missing Documentation
|
|
79
|
+
</p>
|
|
80
|
+
<ul className="text-sm text-yellow-600/80 dark:text-yellow-400/80 list-disc list-inside">
|
|
81
|
+
{docs.missing!.map((signal) => (
|
|
82
|
+
<li key={signal}>{formatSignal(signal)}</li>
|
|
83
|
+
))}
|
|
84
|
+
</ul>
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
|
|
88
|
+
{hasDrift && (
|
|
89
|
+
<div className="rounded-md bg-red-500/10 border border-red-500/20 px-3 py-2">
|
|
90
|
+
<p className="text-sm font-medium text-red-600 dark:text-red-400 mb-1">
|
|
91
|
+
Documentation Drift
|
|
92
|
+
</p>
|
|
93
|
+
<ul className="text-sm text-red-600/80 dark:text-red-400/80 space-y-1">
|
|
94
|
+
{docs.drift!.map((drift) => (
|
|
95
|
+
<li key={`${drift.type}-${drift.issue}`} className="flex flex-col">
|
|
96
|
+
<span className="font-medium">{drift.type}</span>
|
|
97
|
+
<span className="text-xs opacity-80">{drift.issue}</span>
|
|
98
|
+
{drift.suggestion && (
|
|
99
|
+
<span className="text-xs text-fd-muted-foreground mt-0.5">
|
|
100
|
+
Suggestion: {drift.suggestion}
|
|
101
|
+
</span>
|
|
102
|
+
)}
|
|
103
|
+
</li>
|
|
104
|
+
))}
|
|
105
|
+
</ul>
|
|
106
|
+
</div>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// CoverageBadge is doccov-specific, stays in fumadocs-adapter
|
|
2
|
+
|
|
3
|
+
// Re-export headless components from doc-generator
|
|
4
|
+
export {
|
|
5
|
+
CollapsibleMethod,
|
|
6
|
+
type CollapsibleMethodProps,
|
|
7
|
+
ExampleBlock,
|
|
8
|
+
type ExampleBlockProps,
|
|
9
|
+
ExpandableProperty,
|
|
10
|
+
type ExpandablePropertyProps,
|
|
11
|
+
MemberRow,
|
|
12
|
+
type MemberRowProps,
|
|
13
|
+
MembersTable,
|
|
14
|
+
type MembersTableProps,
|
|
15
|
+
NestedProperty,
|
|
16
|
+
type NestedPropertyProps,
|
|
17
|
+
ParamRow,
|
|
18
|
+
type ParamRowProps,
|
|
19
|
+
ParamTable,
|
|
20
|
+
type ParamTableProps,
|
|
21
|
+
Signature,
|
|
22
|
+
type SignatureProps,
|
|
23
|
+
TypeTable,
|
|
24
|
+
type TypeTableProps,
|
|
25
|
+
} from '@openpkg-ts/doc-generator/react';
|
|
26
|
+
// Re-export all styled components from doc-generator
|
|
27
|
+
export {
|
|
28
|
+
APIPage,
|
|
29
|
+
type APIPageProps,
|
|
30
|
+
ClassPage,
|
|
31
|
+
type ClassPageProps,
|
|
32
|
+
EnumPage,
|
|
33
|
+
type EnumPageProps,
|
|
34
|
+
FunctionPage,
|
|
35
|
+
type FunctionPageProps,
|
|
36
|
+
InterfacePage,
|
|
37
|
+
type InterfacePageProps,
|
|
38
|
+
VariablePage,
|
|
39
|
+
type VariablePageProps,
|
|
40
|
+
} from '@openpkg-ts/doc-generator/react/styled';
|
|
41
|
+
export type { CoverageBadgeProps, DocDrift, DocsMetadata } from './coverage-badge';
|
|
42
|
+
export { CoverageBadge } from './coverage-badge';
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Re-export core from @openpkg-ts/doc-generator
|
|
2
|
+
|
|
3
|
+
// Re-export spec types for convenience
|
|
4
|
+
export type {
|
|
5
|
+
DocsInstance as OpenPkgInstance,
|
|
6
|
+
LoadOptions as OpenPkgOptions,
|
|
7
|
+
OpenPkg,
|
|
8
|
+
SpecExample,
|
|
9
|
+
SpecExport,
|
|
10
|
+
SpecExportKind,
|
|
11
|
+
SpecMember,
|
|
12
|
+
SpecSchema,
|
|
13
|
+
SpecSignature,
|
|
14
|
+
SpecSignatureParameter,
|
|
15
|
+
SpecTag,
|
|
16
|
+
SpecType,
|
|
17
|
+
SpecTypeKind,
|
|
18
|
+
SpecTypeParameter,
|
|
19
|
+
} from '@openpkg-ts/doc-generator';
|
|
20
|
+
export {
|
|
21
|
+
type AlgoliaRecord,
|
|
22
|
+
buildSignatureString,
|
|
23
|
+
createDocs,
|
|
24
|
+
createDocs as createOpenPkg,
|
|
25
|
+
type DocsInstance,
|
|
26
|
+
type ExportMarkdownOptions,
|
|
27
|
+
exportToMarkdown,
|
|
28
|
+
formatParameters,
|
|
29
|
+
formatReturnType,
|
|
30
|
+
formatSchema,
|
|
31
|
+
formatTypeParameters,
|
|
32
|
+
getMethods,
|
|
33
|
+
getProperties,
|
|
34
|
+
groupByVisibility,
|
|
35
|
+
type HTMLOptions,
|
|
36
|
+
isMethod,
|
|
37
|
+
isProperty,
|
|
38
|
+
type JSONOptions,
|
|
39
|
+
type LoadOptions,
|
|
40
|
+
loadSpec,
|
|
41
|
+
type MarkdownOptions,
|
|
42
|
+
type NavOptions,
|
|
43
|
+
type PagefindRecord,
|
|
44
|
+
resolveTypeRef,
|
|
45
|
+
type SearchIndex,
|
|
46
|
+
type SearchOptions,
|
|
47
|
+
type SearchRecord,
|
|
48
|
+
sortByKindThenName,
|
|
49
|
+
sortByName,
|
|
50
|
+
toAlgoliaRecords,
|
|
51
|
+
toDocusaurusSidebarJS,
|
|
52
|
+
toFumadocsMetaJSON,
|
|
53
|
+
toHTML,
|
|
54
|
+
toJSON,
|
|
55
|
+
toJSONString,
|
|
56
|
+
toMarkdown,
|
|
57
|
+
toNavigation,
|
|
58
|
+
toPagefindRecords,
|
|
59
|
+
toSearchIndex,
|
|
60
|
+
toSearchIndexJSON,
|
|
61
|
+
} from '@openpkg-ts/doc-generator';
|
|
62
|
+
// Re-export styled components (most common use case)
|
|
63
|
+
export {
|
|
64
|
+
APIPage,
|
|
65
|
+
type APIPageProps,
|
|
66
|
+
ClassPage,
|
|
67
|
+
type ClassPageProps,
|
|
68
|
+
EnumPage,
|
|
69
|
+
type EnumPageProps,
|
|
70
|
+
FunctionPage,
|
|
71
|
+
type FunctionPageProps,
|
|
72
|
+
InterfacePage,
|
|
73
|
+
type InterfacePageProps,
|
|
74
|
+
VariablePage,
|
|
75
|
+
type VariablePageProps,
|
|
76
|
+
} from '@openpkg-ts/doc-generator/react/styled';
|
|
77
|
+
// Re-export CoverageBadge (doccov-specific)
|
|
78
|
+
export {
|
|
79
|
+
CoverageBadge,
|
|
80
|
+
type CoverageBadgeProps,
|
|
81
|
+
type DocDrift,
|
|
82
|
+
type DocsMetadata,
|
|
83
|
+
} from './components/coverage-badge';
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docskit CSS Variables for Fumadocs
|
|
3
|
+
*
|
|
4
|
+
* This file defines the CSS variables needed for @doccov/ui docskit components
|
|
5
|
+
* to work within Fumadocs themes.
|
|
6
|
+
*
|
|
7
|
+
* Import this in your global CSS:
|
|
8
|
+
* @import '@openpkg-ts/fumadocs-adapter/css';
|
|
9
|
+
*
|
|
10
|
+
* Or add these variables to your Tailwind CSS:
|
|
11
|
+
* @import 'tailwindcss';
|
|
12
|
+
* @import 'fumadocs-ui/css/neutral.css';
|
|
13
|
+
* @import 'fumadocs-ui/css/preset.css';
|
|
14
|
+
* @import '@openpkg-ts/fumadocs-adapter/css';
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
@layer base {
|
|
18
|
+
:root {
|
|
19
|
+
/* Docskit code block colors - mapped to Fumadocs variables */
|
|
20
|
+
--dk-background: var(--color-fd-card, hsl(0 0% 3%));
|
|
21
|
+
--dk-border: var(--color-fd-border, hsl(0 0% 18%));
|
|
22
|
+
--dk-tabs-background: var(--color-fd-muted, hsl(0 0% 10%));
|
|
23
|
+
--dk-tab-inactive-foreground: var(--color-fd-muted-foreground, hsl(0 0% 60%));
|
|
24
|
+
--dk-tab-active-foreground: var(--color-fd-foreground, hsl(0 0% 98%));
|
|
25
|
+
--dk-selection: var(--color-fd-primary, hsl(220 70% 50%));
|
|
26
|
+
|
|
27
|
+
/* Line highlight colors */
|
|
28
|
+
--dk-line-bg: transparent;
|
|
29
|
+
--dk-line-border: transparent;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Light mode overrides if needed */
|
|
33
|
+
.light,
|
|
34
|
+
[data-theme="light"] {
|
|
35
|
+
--dk-background: var(--color-fd-card, hsl(0 0% 98%));
|
|
36
|
+
--dk-border: var(--color-fd-border, hsl(0 0% 85%));
|
|
37
|
+
--dk-tabs-background: var(--color-fd-muted, hsl(0 0% 95%));
|
|
38
|
+
--dk-tab-inactive-foreground: var(--color-fd-muted-foreground, hsl(0 0% 45%));
|
|
39
|
+
--dk-tab-active-foreground: var(--color-fd-foreground, hsl(0 0% 10%));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Tailwind utility classes for docskit */
|
|
44
|
+
@layer utilities {
|
|
45
|
+
.bg-dk-background {
|
|
46
|
+
background-color: var(--dk-background);
|
|
47
|
+
}
|
|
48
|
+
.bg-dk-tabs-background {
|
|
49
|
+
background-color: var(--dk-tabs-background);
|
|
50
|
+
}
|
|
51
|
+
.border-dk-border {
|
|
52
|
+
border-color: var(--dk-border);
|
|
53
|
+
}
|
|
54
|
+
.text-dk-tab-inactive-foreground {
|
|
55
|
+
color: var(--dk-tab-inactive-foreground);
|
|
56
|
+
}
|
|
57
|
+
.text-dk-tab-active-foreground {
|
|
58
|
+
color: var(--dk-tab-active-foreground);
|
|
59
|
+
}
|
|
60
|
+
.selection\:bg-dk-selection::selection,
|
|
61
|
+
.selection\:bg-dk-selection *::selection {
|
|
62
|
+
background-color: var(--dk-selection);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* CodeHike syntax highlighting theme - github-from-css */
|
|
67
|
+
/* These --ch-* variables are required for the "github-from-css" theme */
|
|
68
|
+
@layer base {
|
|
69
|
+
/* GitHub Dark theme (default) */
|
|
70
|
+
:root {
|
|
71
|
+
--ch-0: #e6edf3; /* default text */
|
|
72
|
+
--ch-1: #ff7b72; /* strings, inherited class */
|
|
73
|
+
--ch-2: #a5d6ff; /* string literals */
|
|
74
|
+
--ch-3: #79c0ff; /* keywords, function names */
|
|
75
|
+
--ch-4: #a5d6ff; /* constants */
|
|
76
|
+
--ch-5: #d2a8ff; /* entity names, types */
|
|
77
|
+
--ch-6: #ffa657; /* variables, tag names */
|
|
78
|
+
--ch-7: #8b949e; /* comments */
|
|
79
|
+
--ch-8: #79c0ff; /* support */
|
|
80
|
+
--ch-9: #e6edf3; /* punctuation */
|
|
81
|
+
--ch-10: #f0f6fc;
|
|
82
|
+
--ch-11: #490202;
|
|
83
|
+
--ch-12: #04260f;
|
|
84
|
+
--ch-13: #5a1e02;
|
|
85
|
+
--ch-14: #161b22;
|
|
86
|
+
--ch-15: #8b949e;
|
|
87
|
+
--ch-16: #0d1117;
|
|
88
|
+
--ch-17: #6e76811a;
|
|
89
|
+
--ch-18: #ffffff0b;
|
|
90
|
+
--ch-19: #3794ff;
|
|
91
|
+
--ch-20: #264f78;
|
|
92
|
+
--ch-21: #1f6feb;
|
|
93
|
+
--ch-22: #010409;
|
|
94
|
+
--ch-23: #30363d;
|
|
95
|
+
--ch-24: #6e7681;
|
|
96
|
+
--ch-25: #6e768166;
|
|
97
|
+
--ch-26: #0d1117e6;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* GitHub Light theme */
|
|
101
|
+
.light,
|
|
102
|
+
[data-theme="light"] {
|
|
103
|
+
--ch-0: #24292f; /* default text */
|
|
104
|
+
--ch-1: #cf222e; /* strings, inherited class */
|
|
105
|
+
--ch-2: #116329; /* string literals */
|
|
106
|
+
--ch-3: #0550ae; /* keywords, function names */
|
|
107
|
+
--ch-4: #0a3069; /* constants */
|
|
108
|
+
--ch-5: #8250df; /* entity names, types */
|
|
109
|
+
--ch-6: #953800; /* variables, tag names */
|
|
110
|
+
--ch-7: #6e7781; /* comments */
|
|
111
|
+
--ch-8: #0550ae; /* support */
|
|
112
|
+
--ch-9: #24292f; /* punctuation */
|
|
113
|
+
--ch-10: #f6f8fa;
|
|
114
|
+
--ch-11: #ffebe9;
|
|
115
|
+
--ch-12: #dafbe1;
|
|
116
|
+
--ch-13: #ffd8b5;
|
|
117
|
+
--ch-14: #eaeef2;
|
|
118
|
+
--ch-15: #57606a;
|
|
119
|
+
--ch-16: #ffffff;
|
|
120
|
+
--ch-17: #eaeef280;
|
|
121
|
+
--ch-18: #fdff0033;
|
|
122
|
+
--ch-19: #1a85ff;
|
|
123
|
+
--ch-20: #add6ff;
|
|
124
|
+
--ch-21: #0969da;
|
|
125
|
+
--ch-22: #f6f8fa;
|
|
126
|
+
--ch-23: #d0d7de;
|
|
127
|
+
--ch-24: #8c959f;
|
|
128
|
+
--ch-25: #afb8c133;
|
|
129
|
+
--ch-26: #ffffffe6;
|
|
130
|
+
}
|
|
131
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM"],
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"outDir": "./dist",
|
|
15
|
+
"rootDir": "./src",
|
|
16
|
+
"resolveJsonModule": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|