sourcey 2.0.2
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/LICENSE +23 -0
- package/README.md +254 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +197 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/copy.js +21 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/scroll-tracker.js +88 -0
- package/dist/client/search.js +164 -0
- package/dist/client/sidebar.js +54 -0
- package/dist/client/tabs.js +51 -0
- package/dist/client/theme-toggle.js +36 -0
- package/dist/components/App.d.ts +15 -0
- package/dist/components/App.d.ts.map +1 -0
- package/dist/components/App.js +13 -0
- package/dist/components/App.js.map +1 -0
- package/dist/components/layout/Head.d.ts +2 -0
- package/dist/components/layout/Head.d.ts.map +1 -0
- package/dist/components/layout/Head.js +29 -0
- package/dist/components/layout/Head.js.map +1 -0
- package/dist/components/layout/Header.d.ts +13 -0
- package/dist/components/layout/Header.d.ts.map +1 -0
- package/dist/components/layout/Header.js +38 -0
- package/dist/components/layout/Header.js.map +1 -0
- package/dist/components/layout/Page.d.ts +2 -0
- package/dist/components/layout/Page.d.ts.map +1 -0
- package/dist/components/layout/Page.js +29 -0
- package/dist/components/layout/Page.js.map +1 -0
- package/dist/components/layout/Sidebar.d.ts +9 -0
- package/dist/components/layout/Sidebar.d.ts.map +1 -0
- package/dist/components/layout/Sidebar.js +41 -0
- package/dist/components/layout/Sidebar.js.map +1 -0
- package/dist/components/layout/TableOfContents.d.ts +10 -0
- package/dist/components/layout/TableOfContents.d.ts.map +1 -0
- package/dist/components/layout/TableOfContents.js +12 -0
- package/dist/components/layout/TableOfContents.js.map +1 -0
- package/dist/components/openapi/CodeSamples.d.ts +11 -0
- package/dist/components/openapi/CodeSamples.d.ts.map +1 -0
- package/dist/components/openapi/CodeSamples.js +16 -0
- package/dist/components/openapi/CodeSamples.js.map +1 -0
- package/dist/components/openapi/Definition.d.ts +11 -0
- package/dist/components/openapi/Definition.d.ts.map +1 -0
- package/dist/components/openapi/Definition.js +12 -0
- package/dist/components/openapi/Definition.js.map +1 -0
- package/dist/components/openapi/EndpointBar.d.ts +12 -0
- package/dist/components/openapi/EndpointBar.d.ts.map +1 -0
- package/dist/components/openapi/EndpointBar.js +22 -0
- package/dist/components/openapi/EndpointBar.js.map +1 -0
- package/dist/components/openapi/Introduction.d.ts +6 -0
- package/dist/components/openapi/Introduction.d.ts.map +1 -0
- package/dist/components/openapi/Introduction.js +14 -0
- package/dist/components/openapi/Introduction.js.map +1 -0
- package/dist/components/openapi/Operation.d.ts +13 -0
- package/dist/components/openapi/Operation.d.ts.map +1 -0
- package/dist/components/openapi/Operation.js +23 -0
- package/dist/components/openapi/Operation.js.map +1 -0
- package/dist/components/openapi/Parameters.d.ts +7 -0
- package/dist/components/openapi/Parameters.d.ts.map +1 -0
- package/dist/components/openapi/Parameters.js +10 -0
- package/dist/components/openapi/Parameters.js.map +1 -0
- package/dist/components/openapi/RequestBody.d.ts +17 -0
- package/dist/components/openapi/RequestBody.d.ts.map +1 -0
- package/dist/components/openapi/RequestBody.js +27 -0
- package/dist/components/openapi/RequestBody.js.map +1 -0
- package/dist/components/openapi/Responses.d.ts +14 -0
- package/dist/components/openapi/Responses.d.ts.map +1 -0
- package/dist/components/openapi/Responses.js +60 -0
- package/dist/components/openapi/Responses.js.map +1 -0
- package/dist/components/openapi/Security.d.ts +14 -0
- package/dist/components/openapi/Security.d.ts.map +1 -0
- package/dist/components/openapi/Security.js +32 -0
- package/dist/components/openapi/Security.js.map +1 -0
- package/dist/components/openapi/Tags.d.ts +8 -0
- package/dist/components/openapi/Tags.d.ts.map +1 -0
- package/dist/components/openapi/Tags.js +10 -0
- package/dist/components/openapi/Tags.js.map +1 -0
- package/dist/components/schema/ExampleView.d.ts +11 -0
- package/dist/components/schema/ExampleView.d.ts.map +1 -0
- package/dist/components/schema/ExampleView.js +15 -0
- package/dist/components/schema/ExampleView.js.map +1 -0
- package/dist/components/schema/SchemaDatatype.d.ts +11 -0
- package/dist/components/schema/SchemaDatatype.d.ts.map +1 -0
- package/dist/components/schema/SchemaDatatype.js +36 -0
- package/dist/components/schema/SchemaDatatype.js.map +1 -0
- package/dist/components/schema/SchemaView.d.ts +14 -0
- package/dist/components/schema/SchemaView.d.ts.map +1 -0
- package/dist/components/schema/SchemaView.js +44 -0
- package/dist/components/schema/SchemaView.js.map +1 -0
- package/dist/components/ui/Badge.d.ts +11 -0
- package/dist/components/ui/Badge.d.ts.map +1 -0
- package/dist/components/ui/Badge.js +14 -0
- package/dist/components/ui/Badge.js.map +1 -0
- package/dist/components/ui/Markdown.d.ts +8 -0
- package/dist/components/ui/Markdown.d.ts.map +1 -0
- package/dist/components/ui/Markdown.js +13 -0
- package/dist/components/ui/Markdown.js.map +1 -0
- package/dist/components/ui/SectionLabel.d.ts +10 -0
- package/dist/components/ui/SectionLabel.d.ts.map +1 -0
- package/dist/components/ui/SectionLabel.js +9 -0
- package/dist/components/ui/SectionLabel.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +102 -0
- package/dist/config.js.map +1 -0
- package/dist/core/converter.d.ts +9 -0
- package/dist/core/converter.d.ts.map +1 -0
- package/dist/core/converter.js +29 -0
- package/dist/core/converter.js.map +1 -0
- package/dist/core/loader.d.ts +7 -0
- package/dist/core/loader.d.ts.map +1 -0
- package/dist/core/loader.js +92 -0
- package/dist/core/loader.js.map +1 -0
- package/dist/core/markdown-loader.d.ts +29 -0
- package/dist/core/markdown-loader.d.ts.map +1 -0
- package/dist/core/markdown-loader.js +65 -0
- package/dist/core/markdown-loader.js.map +1 -0
- package/dist/core/navigation.d.ts +51 -0
- package/dist/core/navigation.d.ts.map +1 -0
- package/dist/core/navigation.js +108 -0
- package/dist/core/navigation.js.map +1 -0
- package/dist/core/normalizer.d.ts +7 -0
- package/dist/core/normalizer.d.ts.map +1 -0
- package/dist/core/normalizer.js +472 -0
- package/dist/core/normalizer.js.map +1 -0
- package/dist/core/parser.d.ts +10 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +34 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/search-indexer.d.ts +25 -0
- package/dist/core/search-indexer.d.ts.map +1 -0
- package/dist/core/search-indexer.js +72 -0
- package/dist/core/search-indexer.js.map +1 -0
- package/dist/core/types.d.ts +236 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +7 -0
- package/dist/core/types.js.map +1 -0
- package/dist/dev-server.d.ts +17 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +202 -0
- package/dist/dev-server.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/renderer/context.d.ts +46 -0
- package/dist/renderer/context.d.ts.map +1 -0
- package/dist/renderer/context.js +22 -0
- package/dist/renderer/context.js.map +1 -0
- package/dist/renderer/html-builder.d.ts +37 -0
- package/dist/renderer/html-builder.d.ts.map +1 -0
- package/dist/renderer/html-builder.js +87 -0
- package/dist/renderer/html-builder.js.map +1 -0
- package/dist/renderer/static-renderer.d.ts +10 -0
- package/dist/renderer/static-renderer.d.ts.map +1 -0
- package/dist/renderer/static-renderer.js +17 -0
- package/dist/renderer/static-renderer.js.map +1 -0
- package/dist/themes/default/main.css +61 -0
- package/dist/themes/default/sourcey.css +425 -0
- package/dist/utils/code-samples.d.ts +8 -0
- package/dist/utils/code-samples.d.ts.map +1 -0
- package/dist/utils/code-samples.js +84 -0
- package/dist/utils/code-samples.js.map +1 -0
- package/dist/utils/example-generator.d.ts +12 -0
- package/dist/utils/example-generator.d.ts.map +1 -0
- package/dist/utils/example-generator.js +123 -0
- package/dist/utils/example-generator.js.map +1 -0
- package/dist/utils/highlighter.d.ts +10 -0
- package/dist/utils/highlighter.d.ts.map +1 -0
- package/dist/utils/highlighter.js +51 -0
- package/dist/utils/highlighter.js.map +1 -0
- package/dist/utils/html-id.d.ts +6 -0
- package/dist/utils/html-id.d.ts.map +1 -0
- package/dist/utils/html-id.js +11 -0
- package/dist/utils/html-id.js.map +1 -0
- package/dist/utils/http.d.ts +14 -0
- package/dist/utils/http.d.ts.map +1 -0
- package/dist/utils/http.js +97 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +18 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/vite-plugin.d.ts +16 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +92 -0
- package/dist/vite-plugin.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaDatatype.js","sourceRoot":"","sources":["../../../src/components/schema/SchemaDatatype.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMlD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAAuB;IAC5D,OAAO,CACL,8BACE,eAAM,KAAK,EAAC,oBAAoB,YAAE,cAAc,CAAC,MAAM,CAAC,GAAQ,EAC/D,MAAM,CAAC,MAAM,IAAI,CAChB,gBAAM,KAAK,EAAC,sBAAsB,mBAAI,MAAM,CAAC,MAAM,SAAS,CAC7D,EACA,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC;gBACtB,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EACjF,WAAW,CAAC,MAAM,CAAC,IAAI,CACtB,eAAM,KAAK,EAAC,qBAAqB,YAAE,WAAW,CAAC,MAAM,CAAC,GAAQ,CAC/D,EACA,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,CAC/B,eAAM,KAAK,EAAC,6BAA6B,YAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAQ,CAC1E,EACA,MAAM,CAAC,QAAQ,IAAI,eAAM,KAAK,EAAC,oBAAoB,wBAAe,IAClE,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,MAAkB;IACpC,IAAI,CAAC,MAAM,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,CACL,eAAM,KAAK,EAAC,oBAAoB,YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,eAAc,KAAK,EAAC,yBAAyB,YAC1C,MAAM,CAAC,CAAC,CAAC,IADD,CAAC,CAEL,CACR,CAAC,GACG,CACR,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAAwB;IAC9C,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,SAAS,QAAQ,GAAG,CAAC;IAC9B,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAChF,OAAO,IAAI,IAAI,KAAK,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NormalizedSchema } from "../../core/types.js";
|
|
2
|
+
interface SchemaViewProps {
|
|
3
|
+
schema: NormalizedSchema;
|
|
4
|
+
requiredFields?: string[];
|
|
5
|
+
depth?: number;
|
|
6
|
+
maxDepth?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Recursive schema renderer — stacked property layout.
|
|
10
|
+
* Each property: name + type on one line, description below, children indented.
|
|
11
|
+
*/
|
|
12
|
+
export declare function SchemaView({ schema, requiredFields, depth, maxDepth, }: SchemaViewProps): import("preact").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=SchemaView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaView.d.ts","sourceRoot":"","sources":["../../../src/components/schema/SchemaView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAK5D,UAAU,eAAe;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,cAAc,EACd,KAAS,EACT,QAAoB,GACrB,EAAE,eAAe,gCAmHjB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { Markdown } from "../ui/Markdown.js";
|
|
3
|
+
import { RequiredBadge, ReadOnlyBadge, DeprecatedBadge, Badge } from "../ui/Badge.js";
|
|
4
|
+
import { SchemaDatatype } from "./SchemaDatatype.js";
|
|
5
|
+
const MAX_DEPTH = 10;
|
|
6
|
+
/**
|
|
7
|
+
* Recursive schema renderer — stacked property layout.
|
|
8
|
+
* Each property: name + type on one line, description below, children indented.
|
|
9
|
+
*/
|
|
10
|
+
export function SchemaView({ schema, requiredFields, depth = 0, maxDepth = MAX_DEPTH, }) {
|
|
11
|
+
if (depth >= maxDepth) {
|
|
12
|
+
return _jsx("div", { class: "schema-max-depth", children: "Max depth reached" });
|
|
13
|
+
}
|
|
14
|
+
// Handle allOf composition
|
|
15
|
+
if (schema.allOf?.length) {
|
|
16
|
+
return (_jsxs("div", { class: "schema-composition", children: [schema.description && (_jsx("div", { class: "schema-description", children: _jsx(Markdown, { content: schema.description }) })), schema.allOf.map((sub, i) => (_jsx(SchemaView, { schema: sub, depth: depth, maxDepth: maxDepth }, i)))] }));
|
|
17
|
+
}
|
|
18
|
+
// Handle anyOf/oneOf
|
|
19
|
+
if (schema.oneOf?.length || schema.anyOf?.length) {
|
|
20
|
+
const variants = schema.oneOf ?? schema.anyOf ?? [];
|
|
21
|
+
const label = schema.oneOf ? "One of" : "Any of";
|
|
22
|
+
return (_jsxs("div", { class: "schema-variants", children: [schema.description && (_jsx("div", { class: "schema-description", children: _jsx(Markdown, { content: schema.description }) })), _jsx("div", { class: "schema-variant-label", children: label }), variants.map((sub, i) => (_jsx("div", { class: "schema-variant-option", children: _jsx(SchemaView, { schema: sub, depth: depth + 1, maxDepth: maxDepth }) }, i)))] }));
|
|
23
|
+
}
|
|
24
|
+
// Object with properties
|
|
25
|
+
if (schema.properties) {
|
|
26
|
+
const required = new Set(schema.required ?? requiredFields ?? []);
|
|
27
|
+
return (_jsxs("div", { children: [schema.description && (_jsx("div", { class: "schema-description", children: _jsx(Markdown, { content: schema.description }) })), _jsx("div", { class: "params-list", children: Object.entries(schema.properties).map(([name, prop]) => (_jsx(PropertyRow, { name: name, schema: prop, required: required.has(name), depth: depth, maxDepth: maxDepth }, name))) }), schema.additionalProperties &&
|
|
28
|
+
typeof schema.additionalProperties !== "boolean" && (_jsx("div", { class: "param-item", children: _jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: "[key: string]" }), _jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: schema.additionalProperties }) })] }) }))] }));
|
|
29
|
+
}
|
|
30
|
+
// Array
|
|
31
|
+
if (schema.type === "array" && schema.items) {
|
|
32
|
+
return (_jsxs("div", { children: [schema.description && (_jsx("div", { class: "schema-description", children: _jsx(Markdown, { content: schema.description }) })), _jsx("div", { class: "schema-array-info", children: _jsx(SchemaDatatype, { schema: schema }) }), schema.items.properties && (_jsx("div", { class: "schema-nested", children: _jsx(SchemaView, { schema: schema.items, depth: depth + 1, maxDepth: maxDepth }) }))] }));
|
|
33
|
+
}
|
|
34
|
+
// Simple type
|
|
35
|
+
return (_jsxs("div", { children: [schema.description && (_jsx("div", { class: "schema-description", children: _jsx(Markdown, { content: schema.description }) })), _jsx(SchemaDatatype, { schema: schema })] }));
|
|
36
|
+
}
|
|
37
|
+
function PropertyRow({ name, schema, required, depth, maxDepth, }) {
|
|
38
|
+
const hasInner = schema.properties ||
|
|
39
|
+
(schema.type === "array" &&
|
|
40
|
+
schema.items &&
|
|
41
|
+
(schema.items.properties || schema.items.allOf || schema.items.oneOf || schema.items.anyOf));
|
|
42
|
+
return (_jsxs("div", { class: "param-item", children: [_jsxs("div", { class: "param-header", children: [_jsx("code", { class: "param-name", children: name }), _jsx("span", { class: "param-type", children: _jsx(SchemaDatatype, { schema: schema }) }), required && _jsx(RequiredBadge, {}), schema.readOnly && _jsx(ReadOnlyBadge, {}), schema.writeOnly && _jsx(Badge, { children: "write only" }), schema.deprecated && _jsx(DeprecatedBadge, {})] }), schema.description && (_jsx("div", { class: "param-description", children: _jsx(Markdown, { content: schema.description }) })), hasInner && (_jsx("div", { class: "schema-nested", children: _jsx(SchemaView, { schema: schema.type === "array" && schema.items ? schema.items : schema, depth: depth + 1, maxDepth: maxDepth }) }))] }));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=SchemaView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaView.js","sourceRoot":"","sources":["../../../src/components/schema/SchemaView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface BadgeProps {
|
|
2
|
+
children: preact.ComponentChildren;
|
|
3
|
+
class?: string;
|
|
4
|
+
style?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export declare function Badge({ children, class: className, style }: BadgeProps): import("preact").JSX.Element;
|
|
7
|
+
export declare function RequiredBadge(): import("preact").JSX.Element;
|
|
8
|
+
export declare function DeprecatedBadge(): import("preact").JSX.Element;
|
|
9
|
+
export declare function ReadOnlyBadge(): import("preact").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC,iBAAiB,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,UAAU,gCAStE;AAED,wBAAgB,aAAa,iCAM5B;AAED,wBAAgB,eAAe,iCAM9B;AAED,wBAAgB,aAAa,iCAM5B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
export function Badge({ children, class: className, style }) {
|
|
3
|
+
return (_jsx("span", { class: `inline-flex items-center gap-1 break-all rounded-md px-2 py-0.5 text-xs font-medium ${className ?? "bg-[rgb(var(--color-gray-100)/0.5)] text-[rgb(var(--color-gray-600))] dark:bg-[rgb(var(--color-surface-dark-tint)/0.05)] dark:text-[rgb(var(--color-gray-200))]"}`, style: style, children: children }));
|
|
4
|
+
}
|
|
5
|
+
export function RequiredBadge() {
|
|
6
|
+
return (_jsx("span", { class: "whitespace-nowrap rounded-md bg-red-100/50 px-2 py-0.5 text-xs font-medium text-red-600 dark:bg-red-400/10 dark:text-red-300", children: "required" }));
|
|
7
|
+
}
|
|
8
|
+
export function DeprecatedBadge() {
|
|
9
|
+
return (_jsx("span", { class: "whitespace-nowrap rounded-md bg-amber-100/50 px-2 py-0.5 text-xs font-medium text-amber-600 dark:bg-amber-400/10 dark:text-amber-300", children: "deprecated" }));
|
|
10
|
+
}
|
|
11
|
+
export function ReadOnlyBadge() {
|
|
12
|
+
return (_jsx("span", { class: "whitespace-nowrap rounded-md bg-[rgb(var(--color-gray-100)/0.5)] px-2 py-0.5 text-xs font-medium text-[rgb(var(--color-gray-600))] dark:bg-[rgb(var(--color-surface-dark-tint)/0.05)] dark:text-[rgb(var(--color-gray-200))]", children: "read only" }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=Badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":";AAMA,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAc;IACrE,OAAO,CACL,eACE,KAAK,EAAE,uFAAuF,SAAS,IAAI,iKAAiK,EAAE,EAC9Q,KAAK,EAAE,KAAK,YAEX,QAAQ,GACJ,CACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,eAAM,KAAK,EAAC,8HAA8H,yBAEnI,CACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,eAAM,KAAK,EAAC,sIAAsI,2BAE3I,CACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,eAAM,KAAK,EAAC,8NAA8N,0BAEnO,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface MarkdownProps {
|
|
2
|
+
content?: string;
|
|
3
|
+
inline?: boolean;
|
|
4
|
+
class?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function Markdown({ content, inline, class: className }: MarkdownProps): import("preact").JSX.Element | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=Markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Markdown.tsx"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,aAAa,uCAa5E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { renderMarkdown, renderMarkdownInline } from "../../utils/markdown.js";
|
|
3
|
+
export function Markdown({ content, inline, class: className }) {
|
|
4
|
+
if (!content)
|
|
5
|
+
return null;
|
|
6
|
+
const html = inline ? renderMarkdownInline(content) : renderMarkdown(content);
|
|
7
|
+
if (inline) {
|
|
8
|
+
return _jsx("span", { class: className, dangerouslySetInnerHTML: { __html: html } });
|
|
9
|
+
}
|
|
10
|
+
const cls = className ? `prose ${className}` : "prose";
|
|
11
|
+
return (_jsx("div", { class: cls, dangerouslySetInnerHTML: { __html: html } }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=Markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../../src/components/ui/Markdown.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAQ/E,MAAM,UAAU,QAAQ,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAiB;IAC3E,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAE9E,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,eAAM,KAAK,EAAE,SAAS,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAI,CAAC;IAC/E,CAAC;IAED,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACvD,OAAO,CACL,cAAK,KAAK,EAAE,GAAG,EAAE,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAI,CAC/D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface SectionLabelProps {
|
|
2
|
+
children: preact.ComponentChildren;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Section heading with bottom border.
|
|
6
|
+
* Used for "Body", "Parameters", "Response" sections.
|
|
7
|
+
*/
|
|
8
|
+
export declare function SectionLabel({ children }: SectionLabelProps): import("preact").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=SectionLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionLabel.d.ts","sourceRoot":"","sources":["../../../src/components/ui/SectionLabel.tsx"],"names":[],"mappings":"AAAA,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC,iBAAiB,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,gCAM3D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Section heading with bottom border.
|
|
4
|
+
* Used for "Body", "Parameters", "Response" sections.
|
|
5
|
+
*/
|
|
6
|
+
export function SectionLabel({ children }) {
|
|
7
|
+
return (_jsx("div", { class: "flex items-baseline border-b pb-2.5 border-[rgb(var(--color-gray-100))] dark:border-[rgb(var(--color-gray-800))] w-full mb-4", children: _jsx("h4", { class: "flex-1 mb-0 text-sm font-semibold text-[rgb(var(--color-gray-900))] dark:text-[rgb(var(--color-gray-200))]", children: children }) }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=SectionLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionLabel.js","sourceRoot":"","sources":["../../../src/components/ui/SectionLabel.tsx"],"names":[],"mappings":";AAIA;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAqB;IAC1D,OAAO,CACL,cAAK,KAAK,EAAC,8HAA8H,YACvI,aAAI,KAAK,EAAC,4GAA4G,YAAE,QAAQ,GAAM,GAClI,CACP,CAAC;AACJ,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface NavigationTab {
|
|
2
|
+
/** Display name shown in the tab bar */
|
|
3
|
+
label: string;
|
|
4
|
+
/** URL path segment, e.g. "guides" or "api" */
|
|
5
|
+
slug: string;
|
|
6
|
+
/** Path to an OpenAPI spec file (makes this a spec tab) */
|
|
7
|
+
spec?: string;
|
|
8
|
+
/** Markdown page groups (mutually exclusive with spec) */
|
|
9
|
+
groups?: NavigationGroup[];
|
|
10
|
+
}
|
|
11
|
+
export interface NavigationGroup {
|
|
12
|
+
/** Group heading shown in sidebar */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Ordered list of markdown file paths, relative to sourcey.json */
|
|
15
|
+
pages: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface SourceyConfig {
|
|
18
|
+
/** Path to a custom logo image */
|
|
19
|
+
logo?: string;
|
|
20
|
+
/** Path to a custom favicon */
|
|
21
|
+
favicon?: string;
|
|
22
|
+
/** CSS custom property overrides */
|
|
23
|
+
theme?: Record<string, string>;
|
|
24
|
+
/** Navigation tabs. If absent, auto-generated from a spec file. */
|
|
25
|
+
navigation?: NavigationTab[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns true when the config defines explicit navigation.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hasNavigation(config: SourceyConfig): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Generate a minimal config for a standalone spec file.
|
|
33
|
+
* Wraps the spec in a single "API Reference" tab so it renders
|
|
34
|
+
* through the same modern layout as a multi-page site.
|
|
35
|
+
*/
|
|
36
|
+
export declare function configFromSpec(specPath: string, options?: {
|
|
37
|
+
logo?: string;
|
|
38
|
+
favicon?: string;
|
|
39
|
+
}): SourceyConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Load sourcey.json from the given directory (or cwd).
|
|
42
|
+
* Returns an empty config if no file is found.
|
|
43
|
+
* Throws on invalid config (parse errors, validation failures).
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadConfig(cwd?: string): Promise<SourceyConfig>;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAMD,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mEAAmE;IACnE,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAY7G;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBrE"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { readFile, access } from "node:fs/promises";
|
|
2
|
+
import { resolve, dirname } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Returns true when the config defines explicit navigation.
|
|
5
|
+
*/
|
|
6
|
+
export function hasNavigation(config) {
|
|
7
|
+
return Array.isArray(config.navigation) && config.navigation.length > 0;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a minimal config for a standalone spec file.
|
|
11
|
+
* Wraps the spec in a single "API Reference" tab so it renders
|
|
12
|
+
* through the same modern layout as a multi-page site.
|
|
13
|
+
*/
|
|
14
|
+
export function configFromSpec(specPath, options) {
|
|
15
|
+
return {
|
|
16
|
+
logo: options?.logo,
|
|
17
|
+
favicon: options?.favicon,
|
|
18
|
+
navigation: [
|
|
19
|
+
{
|
|
20
|
+
label: "API Reference",
|
|
21
|
+
slug: "api",
|
|
22
|
+
spec: specPath,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load sourcey.json from the given directory (or cwd).
|
|
29
|
+
* Returns an empty config if no file is found.
|
|
30
|
+
* Throws on invalid config (parse errors, validation failures).
|
|
31
|
+
*/
|
|
32
|
+
export async function loadConfig(cwd) {
|
|
33
|
+
const dir = cwd ?? process.cwd();
|
|
34
|
+
const configPath = resolve(dir, "sourcey.json");
|
|
35
|
+
let raw;
|
|
36
|
+
try {
|
|
37
|
+
raw = await readFile(configPath, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
const config = JSON.parse(raw);
|
|
43
|
+
if (hasNavigation(config)) {
|
|
44
|
+
await validateNavigation(config.navigation, dirname(configPath));
|
|
45
|
+
}
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validate navigation config. Throws descriptive errors on invalid input.
|
|
50
|
+
*/
|
|
51
|
+
async function validateNavigation(tabs, configDir) {
|
|
52
|
+
if (tabs.length === 0)
|
|
53
|
+
return;
|
|
54
|
+
const slugs = new Set();
|
|
55
|
+
for (const tab of tabs) {
|
|
56
|
+
// Required fields
|
|
57
|
+
if (!tab.label)
|
|
58
|
+
throw new Error(`Navigation tab missing "label"`);
|
|
59
|
+
if (!tab.slug)
|
|
60
|
+
throw new Error(`Navigation tab "${tab.label}" missing "slug"`);
|
|
61
|
+
// Unique slugs
|
|
62
|
+
if (slugs.has(tab.slug)) {
|
|
63
|
+
throw new Error(`Duplicate navigation tab slug "${tab.slug}"`);
|
|
64
|
+
}
|
|
65
|
+
slugs.add(tab.slug);
|
|
66
|
+
// Mutually exclusive: spec or groups, not both
|
|
67
|
+
if (tab.spec && tab.groups) {
|
|
68
|
+
throw new Error(`Tab "${tab.label}" has both "spec" and "groups"; use one or the other`);
|
|
69
|
+
}
|
|
70
|
+
if (!tab.spec && !tab.groups) {
|
|
71
|
+
throw new Error(`Tab "${tab.label}" needs either "spec" or "groups"`);
|
|
72
|
+
}
|
|
73
|
+
// Validate spec file exists
|
|
74
|
+
if (tab.spec) {
|
|
75
|
+
const specPath = resolve(configDir, tab.spec);
|
|
76
|
+
await assertFileExists(specPath, `Spec file "${tab.spec}" in tab "${tab.label}"`);
|
|
77
|
+
}
|
|
78
|
+
// Validate page files exist
|
|
79
|
+
if (tab.groups) {
|
|
80
|
+
for (const group of tab.groups) {
|
|
81
|
+
if (!group.label)
|
|
82
|
+
throw new Error(`Navigation group missing "label" in tab "${tab.label}"`);
|
|
83
|
+
if (!Array.isArray(group.pages) || group.pages.length === 0) {
|
|
84
|
+
throw new Error(`Navigation group "${group.label}" in tab "${tab.label}" has no pages`);
|
|
85
|
+
}
|
|
86
|
+
for (const pagePath of group.pages) {
|
|
87
|
+
const fullPath = resolve(configDir, pagePath);
|
|
88
|
+
await assertFileExists(fullPath, `Page "${pagePath}" in group "${group.label}"`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function assertFileExists(filePath, label) {
|
|
95
|
+
try {
|
|
96
|
+
await access(filePath);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
throw new Error(`${label} not found: ${filePath}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ParsedSpec } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convert a Swagger 2.0 spec to OpenAPI 3.0 format.
|
|
4
|
+
* If the spec is already OpenAPI 3.x, returns it as-is.
|
|
5
|
+
*
|
|
6
|
+
* Expects the spec to already be dereferenced (all $refs resolved).
|
|
7
|
+
*/
|
|
8
|
+
export declare function convertToOpenApi3(parsed: ParsedSpec): Promise<ParsedSpec>;
|
|
9
|
+
//# sourceMappingURL=converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/core/converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAyB/E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a Swagger 2.0 spec to OpenAPI 3.0 format.
|
|
3
|
+
* If the spec is already OpenAPI 3.x, returns it as-is.
|
|
4
|
+
*
|
|
5
|
+
* Expects the spec to already be dereferenced (all $refs resolved).
|
|
6
|
+
*/
|
|
7
|
+
export async function convertToOpenApi3(parsed) {
|
|
8
|
+
const doc = parsed.document;
|
|
9
|
+
// Already OpenAPI 3.x — return as-is
|
|
10
|
+
if (typeof doc.openapi === "string" && doc.openapi.startsWith("3.")) {
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
// Swagger 2.0 — convert to OpenAPI 3.0
|
|
14
|
+
const { convertObj } = await import("swagger2openapi");
|
|
15
|
+
// Break circular references (from dereferencing) before converting,
|
|
16
|
+
// and enable anchors mode so swagger2openapi handles any remaining ones.
|
|
17
|
+
const cleanDoc = JSON.parse(JSON.stringify(doc));
|
|
18
|
+
const result = await convertObj(cleanDoc, {
|
|
19
|
+
patch: true,
|
|
20
|
+
warnOnly: true,
|
|
21
|
+
direct: true,
|
|
22
|
+
anchors: true,
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
document: result,
|
|
26
|
+
source: parsed.source,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/core/converter.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAkB;IACxD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE5B,qCAAqC;IACrC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uCAAuC;IACvC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAEvD,oEAAoE;IACpE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAA4B,CAAC;IAC5E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE;QACxC,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,MAAgC;QAC1C,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LoadedSpec } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Load an OpenAPI/Swagger spec from a local file path or URL.
|
|
4
|
+
* Auto-detects JSON vs YAML and Swagger 2.0 vs OpenAPI 3.x.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadSpec(source: string): Promise<LoadedSpec>;
|
|
7
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/core/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAEtE;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQlE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readFile, access } from "node:fs/promises";
|
|
2
|
+
import { resolve, extname } from "node:path";
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
/**
|
|
5
|
+
* Load an OpenAPI/Swagger spec from a local file path or URL.
|
|
6
|
+
* Auto-detects JSON vs YAML and Swagger 2.0 vs OpenAPI 3.x.
|
|
7
|
+
*/
|
|
8
|
+
export async function loadSpec(source) {
|
|
9
|
+
const content = await fetchContent(source);
|
|
10
|
+
const format = detectFormat(source, content);
|
|
11
|
+
const raw = parseContent(content, format);
|
|
12
|
+
const version = detectVersion(raw);
|
|
13
|
+
const resolvedSource = isUrl(source) ? source : resolve(source);
|
|
14
|
+
return { raw, format, version, source: resolvedSource };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fetch raw content from a file path or URL.
|
|
18
|
+
*/
|
|
19
|
+
async function fetchContent(source) {
|
|
20
|
+
if (isUrl(source)) {
|
|
21
|
+
const response = await fetch(source);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`Failed to fetch spec from ${source}: ${response.status} ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
return response.text();
|
|
26
|
+
}
|
|
27
|
+
const filePath = resolve(source);
|
|
28
|
+
await access(filePath).catch(() => {
|
|
29
|
+
throw new Error(`Spec file not found: ${filePath}`);
|
|
30
|
+
});
|
|
31
|
+
return readFile(filePath, "utf-8");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Detect whether the content is JSON or YAML based on extension and content.
|
|
35
|
+
*/
|
|
36
|
+
function detectFormat(source, content) {
|
|
37
|
+
const ext = extname(source).toLowerCase();
|
|
38
|
+
if (ext === ".json")
|
|
39
|
+
return "json";
|
|
40
|
+
if (ext === ".yml" || ext === ".yaml")
|
|
41
|
+
return "yaml";
|
|
42
|
+
// Try to detect from content
|
|
43
|
+
const trimmed = content.trimStart();
|
|
44
|
+
if (trimmed.startsWith("{"))
|
|
45
|
+
return "json";
|
|
46
|
+
return "yaml";
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse raw string content into a JS object.
|
|
50
|
+
*/
|
|
51
|
+
function parseContent(content, format) {
|
|
52
|
+
if (format === "json") {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(content);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
throw new Error(`Failed to parse JSON spec: ${e.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const parsed = yaml.load(content);
|
|
62
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
63
|
+
throw new Error("YAML spec must be an object");
|
|
64
|
+
}
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
if (e instanceof yaml.YAMLException) {
|
|
69
|
+
throw new Error(`Failed to parse YAML spec: ${e.message}`);
|
|
70
|
+
}
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Detect the spec version from the parsed document.
|
|
76
|
+
*/
|
|
77
|
+
function detectVersion(raw) {
|
|
78
|
+
if (typeof raw.swagger === "string" && raw.swagger.startsWith("2.")) {
|
|
79
|
+
return "swagger-2.0";
|
|
80
|
+
}
|
|
81
|
+
if (typeof raw.openapi === "string") {
|
|
82
|
+
if (raw.openapi.startsWith("3.1"))
|
|
83
|
+
return "openapi-3.1";
|
|
84
|
+
if (raw.openapi.startsWith("3."))
|
|
85
|
+
return "openapi-3.0";
|
|
86
|
+
}
|
|
87
|
+
throw new Error('Unable to detect spec version. Expected "swagger": "2.0" or "openapi": "3.x.x"');
|
|
88
|
+
}
|
|
89
|
+
function isUrl(source) {
|
|
90
|
+
return source.startsWith("http://") || source.startsWith("https://");
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/core/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface MarkdownPage {
|
|
2
|
+
/** Page title from frontmatter */
|
|
3
|
+
title: string;
|
|
4
|
+
/** Page description from frontmatter */
|
|
5
|
+
description: string;
|
|
6
|
+
/** URL slug for this page (derived from filename) */
|
|
7
|
+
slug: string;
|
|
8
|
+
/** Rendered HTML body */
|
|
9
|
+
html: string;
|
|
10
|
+
/** Extracted h2/h3 headings for table of contents */
|
|
11
|
+
headings: PageHeading[];
|
|
12
|
+
/** Original file path (for error messages and dev server watching) */
|
|
13
|
+
sourcePath: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PageHeading {
|
|
16
|
+
level: 2 | 3;
|
|
17
|
+
text: string;
|
|
18
|
+
id: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load a single markdown file and return a MarkdownPage.
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadMarkdownPage(filePath: string, slug: string): Promise<MarkdownPage>;
|
|
24
|
+
/**
|
|
25
|
+
* Derive a URL slug from a file path.
|
|
26
|
+
* "docs/getting-started.md" → "getting-started"
|
|
27
|
+
*/
|
|
28
|
+
export declare function slugFromPath(filePath: string): string;
|
|
29
|
+
//# sourceMappingURL=markdown-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-loader.d.ts","sourceRoot":"","sources":["../../src/core/markdown-loader.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AA0DD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC,CAYvB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename, extname } from "node:path";
|
|
3
|
+
import { load as parseYaml } from "js-yaml";
|
|
4
|
+
import { Marked } from "marked";
|
|
5
|
+
import { highlightCode } from "../utils/highlighter.js";
|
|
6
|
+
import { htmlId } from "../utils/html-id.js";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Frontmatter parsing
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const FRONTMATTER_RE = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
|
|
11
|
+
function parseFrontmatter(raw) {
|
|
12
|
+
const match = raw.match(FRONTMATTER_RE);
|
|
13
|
+
if (!match) {
|
|
14
|
+
return { meta: {}, body: raw };
|
|
15
|
+
}
|
|
16
|
+
const meta = parseYaml(match[1]) ?? {};
|
|
17
|
+
return { meta, body: match[2] };
|
|
18
|
+
}
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Marked instance with Shiki highlighting and heading extraction
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
function createProseMarked(headings) {
|
|
23
|
+
const marked = new Marked();
|
|
24
|
+
marked.use({
|
|
25
|
+
renderer: {
|
|
26
|
+
code({ text, lang }) {
|
|
27
|
+
const language = lang?.split(/\s/)[0] ?? "";
|
|
28
|
+
return highlightCode(text, language);
|
|
29
|
+
},
|
|
30
|
+
heading({ tokens, depth }) {
|
|
31
|
+
const text = tokens.map(t => ("text" in t ? t.text : t.raw)).join("");
|
|
32
|
+
const id = htmlId(text);
|
|
33
|
+
if (depth === 2 || depth === 3) {
|
|
34
|
+
headings.push({ level: depth, text, id });
|
|
35
|
+
}
|
|
36
|
+
return `<h${depth} id="${id}">${this.parser.parseInline(tokens)}</h${depth}>\n`;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
return marked;
|
|
41
|
+
}
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Public API
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* Load a single markdown file and return a MarkdownPage.
|
|
47
|
+
*/
|
|
48
|
+
export async function loadMarkdownPage(filePath, slug) {
|
|
49
|
+
const raw = await readFile(filePath, "utf-8");
|
|
50
|
+
const { meta, body } = parseFrontmatter(raw);
|
|
51
|
+
const headings = [];
|
|
52
|
+
const marked = createProseMarked(headings);
|
|
53
|
+
const html = marked.parse(body, { async: false });
|
|
54
|
+
const title = meta.title ?? slug;
|
|
55
|
+
const description = meta.description ?? "";
|
|
56
|
+
return { title, description, slug, html, headings, sourcePath: filePath };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Derive a URL slug from a file path.
|
|
60
|
+
* "docs/getting-started.md" → "getting-started"
|
|
61
|
+
*/
|
|
62
|
+
export function slugFromPath(filePath) {
|
|
63
|
+
return htmlId(basename(filePath, extname(filePath)));
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=markdown-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-loader.js","sourceRoot":"","sources":["../../src/core/markdown-loader.ts"],"names":[],"mappings":"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"}
|