@specglass/theme-default 0.0.2 → 0.0.4
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/dist/__tests__/api-endpoint-fallback.test.d.ts +1 -0
- package/dist/__tests__/api-endpoint-fallback.test.js +153 -0
- package/dist/__tests__/code-tabs.test.d.ts +0 -1
- package/dist/__tests__/code-tabs.test.js +0 -1
- package/dist/__tests__/copy-button.test.d.ts +0 -1
- package/dist/__tests__/copy-button.test.js +0 -1
- package/dist/__tests__/search-palette.test.d.ts +0 -1
- package/dist/__tests__/search-palette.test.js +0 -1
- package/dist/__tests__/shiki.test.d.ts +0 -1
- package/dist/__tests__/shiki.test.js +0 -1
- package/dist/__tests__/theme-css.test.d.ts +0 -1
- package/dist/__tests__/theme-css.test.js +0 -1
- package/dist/__tests__/theme-helpers.test.d.ts +0 -1
- package/dist/__tests__/theme-helpers.test.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/islands/CodeTabs.d.ts +0 -1
- package/dist/islands/CodeTabs.js +0 -1
- package/dist/islands/CopyButton.d.ts +0 -1
- package/dist/islands/CopyButton.js +0 -1
- package/dist/islands/SearchPalette.d.ts +0 -1
- package/dist/islands/SearchPalette.js +0 -1
- package/dist/islands/SearchResults.d.ts +0 -1
- package/dist/islands/SearchResults.js +0 -1
- package/dist/islands/ThemeToggle.d.ts +0 -1
- package/dist/islands/ThemeToggle.js +0 -1
- package/dist/layouts/DocPage.test.d.ts +0 -1
- package/dist/layouts/DocPage.test.js +0 -1
- package/dist/lib/utils.d.ts +0 -1
- package/dist/lib/utils.js +0 -1
- package/dist/scripts/code-block-enhancer.d.ts +0 -1
- package/dist/scripts/code-block-enhancer.js +0 -1
- package/dist/ui/command.d.ts +0 -1
- package/dist/ui/command.js +0 -1
- package/dist/ui/dialog.d.ts +0 -1
- package/dist/ui/dialog.js +0 -1
- package/dist/utils/parse-highlight-range.d.ts +0 -1
- package/dist/utils/parse-highlight-range.js +0 -1
- package/dist/utils/parse-highlight-range.test.d.ts +0 -1
- package/dist/utils/parse-highlight-range.test.js +0 -1
- package/dist/utils/schema-renderer.d.ts +0 -1
- package/dist/utils/schema-renderer.js +0 -1
- package/dist/utils/schema-renderer.test.d.ts +0 -1
- package/dist/utils/schema-renderer.test.js +0 -1
- package/dist/utils/shiki.d.ts +0 -1
- package/dist/utils/shiki.js +0 -1
- package/dist/utils/sidebar-helpers.d.ts +0 -1
- package/dist/utils/sidebar-helpers.js +0 -1
- package/dist/utils/theme-css.d.ts +0 -1
- package/dist/utils/theme-css.js +0 -1
- package/dist/utils/theme-helpers.d.ts +0 -1
- package/dist/utils/theme-helpers.js +0 -1
- package/dist/utils/toc-helpers.d.ts +0 -1
- package/dist/utils/toc-helpers.js +0 -1
- package/package.json +7 -3
- package/src/components/ApiEndpointFallback.astro +102 -0
- package/src/components/ApiExampleRequest.astro +192 -0
- package/src/components/ApiExampleResponse.astro +145 -0
- package/src/components/ApiNavigation.astro +70 -3
- package/src/layouts/ApiReferencePage.astro +75 -38
- package/src/scripts/code-block-enhancer.ts +59 -0
- package/src/ui/command.tsx +183 -0
- package/src/ui/dialog.tsx +133 -0
- package/dist/__tests__/code-tabs.test.d.ts.map +0 -1
- package/dist/__tests__/code-tabs.test.js.map +0 -1
- package/dist/__tests__/copy-button.test.d.ts.map +0 -1
- package/dist/__tests__/copy-button.test.js.map +0 -1
- package/dist/__tests__/search-palette.test.d.ts.map +0 -1
- package/dist/__tests__/search-palette.test.js.map +0 -1
- package/dist/__tests__/shiki.test.d.ts.map +0 -1
- package/dist/__tests__/shiki.test.js.map +0 -1
- package/dist/__tests__/theme-css.test.d.ts.map +0 -1
- package/dist/__tests__/theme-css.test.js.map +0 -1
- package/dist/__tests__/theme-helpers.test.d.ts.map +0 -1
- package/dist/__tests__/theme-helpers.test.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/islands/CodeTabs.d.ts.map +0 -1
- package/dist/islands/CodeTabs.js.map +0 -1
- package/dist/islands/CopyButton.d.ts.map +0 -1
- package/dist/islands/CopyButton.js.map +0 -1
- package/dist/islands/SearchPalette.d.ts.map +0 -1
- package/dist/islands/SearchPalette.js.map +0 -1
- package/dist/islands/SearchResults.d.ts.map +0 -1
- package/dist/islands/SearchResults.js.map +0 -1
- package/dist/islands/ThemeToggle.d.ts.map +0 -1
- package/dist/islands/ThemeToggle.js.map +0 -1
- package/dist/layouts/DocPage.test.d.ts.map +0 -1
- package/dist/layouts/DocPage.test.js.map +0 -1
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/utils.js.map +0 -1
- package/dist/scripts/code-block-enhancer.d.ts.map +0 -1
- package/dist/scripts/code-block-enhancer.js.map +0 -1
- package/dist/ui/command.d.ts.map +0 -1
- package/dist/ui/command.js.map +0 -1
- package/dist/ui/dialog.d.ts.map +0 -1
- package/dist/ui/dialog.js.map +0 -1
- package/dist/utils/parse-highlight-range.d.ts.map +0 -1
- package/dist/utils/parse-highlight-range.js.map +0 -1
- package/dist/utils/parse-highlight-range.test.d.ts.map +0 -1
- package/dist/utils/parse-highlight-range.test.js.map +0 -1
- package/dist/utils/schema-renderer.d.ts.map +0 -1
- package/dist/utils/schema-renderer.js.map +0 -1
- package/dist/utils/schema-renderer.test.d.ts.map +0 -1
- package/dist/utils/schema-renderer.test.js.map +0 -1
- package/dist/utils/shiki.d.ts.map +0 -1
- package/dist/utils/shiki.js.map +0 -1
- package/dist/utils/sidebar-helpers.d.ts.map +0 -1
- package/dist/utils/sidebar-helpers.js.map +0 -1
- package/dist/utils/theme-css.d.ts.map +0 -1
- package/dist/utils/theme-css.js.map +0 -1
- package/dist/utils/theme-helpers.d.ts.map +0 -1
- package/dist/utils/theme-helpers.js.map +0 -1
- package/dist/utils/toc-helpers.d.ts.map +0 -1
- package/dist/utils/toc-helpers.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for error endpoint slug generation, data contract, and
|
|
3
|
+
* the shared buildErrorEndpointSlug utility from @specglass/core.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect } from "vitest";
|
|
6
|
+
import { buildEndpointSlug, buildErrorEndpointSlug, buildEndpointId } from "@specglass/core";
|
|
7
|
+
describe("buildErrorEndpointSlug", () => {
|
|
8
|
+
it("generates correct slug for a simple errored endpoint", () => {
|
|
9
|
+
const error = {
|
|
10
|
+
path: "/pets",
|
|
11
|
+
method: "get",
|
|
12
|
+
reason: "Complex polymorphism not supported",
|
|
13
|
+
rawSpec: { get: { summary: "List pets" } },
|
|
14
|
+
};
|
|
15
|
+
expect(buildErrorEndpointSlug(error)).toBe("_unsupported/get-pets");
|
|
16
|
+
});
|
|
17
|
+
it("generates correct slug for nested path with parameters", () => {
|
|
18
|
+
const error = {
|
|
19
|
+
path: "/users/{userId}/orders/{orderId}",
|
|
20
|
+
method: "patch",
|
|
21
|
+
reason: "Unsupported allOf/oneOf",
|
|
22
|
+
rawSpec: {},
|
|
23
|
+
};
|
|
24
|
+
expect(buildErrorEndpointSlug(error)).toBe("_unsupported/patch-users-userId-orders-orderId");
|
|
25
|
+
});
|
|
26
|
+
it("generates correct slug for root path", () => {
|
|
27
|
+
const error = {
|
|
28
|
+
path: "/",
|
|
29
|
+
method: "get",
|
|
30
|
+
reason: "Unsupported extension",
|
|
31
|
+
rawSpec: {},
|
|
32
|
+
};
|
|
33
|
+
expect(buildErrorEndpointSlug(error)).toBe("_unsupported/get-");
|
|
34
|
+
});
|
|
35
|
+
it("uses _unsupported prefix to avoid collision with valid endpoint slugs", () => {
|
|
36
|
+
// An errored endpoint at /pets GET should NOT collide with a valid
|
|
37
|
+
// endpoint at /pets GET (which gets slug "default/get-pets")
|
|
38
|
+
const error = {
|
|
39
|
+
path: "/pets",
|
|
40
|
+
method: "get",
|
|
41
|
+
reason: "test",
|
|
42
|
+
rawSpec: {},
|
|
43
|
+
};
|
|
44
|
+
const validEndpoint = {
|
|
45
|
+
path: "/pets",
|
|
46
|
+
method: "get",
|
|
47
|
+
tags: [],
|
|
48
|
+
summary: "",
|
|
49
|
+
description: "",
|
|
50
|
+
operationId: "",
|
|
51
|
+
deprecated: false,
|
|
52
|
+
parameters: [],
|
|
53
|
+
responses: [],
|
|
54
|
+
security: [],
|
|
55
|
+
requestBody: undefined,
|
|
56
|
+
};
|
|
57
|
+
const errorSlug = buildErrorEndpointSlug(error);
|
|
58
|
+
const validSlug = buildEndpointSlug(validEndpoint);
|
|
59
|
+
expect(errorSlug).not.toBe(validSlug);
|
|
60
|
+
expect(errorSlug).toContain("_unsupported/");
|
|
61
|
+
expect(validSlug).toContain("default/");
|
|
62
|
+
});
|
|
63
|
+
it("generates unique IDs for errored endpoints", () => {
|
|
64
|
+
const error = {
|
|
65
|
+
path: "/pets/{petId}",
|
|
66
|
+
method: "delete",
|
|
67
|
+
reason: "test",
|
|
68
|
+
rawSpec: {},
|
|
69
|
+
};
|
|
70
|
+
const errId = `${error.method}-${error.path}`;
|
|
71
|
+
expect(errId).toBe("delete-/pets/{petId}");
|
|
72
|
+
// This matches buildEndpointId behavior
|
|
73
|
+
const validEndpoint = {
|
|
74
|
+
path: "/pets/{petId}",
|
|
75
|
+
method: "delete",
|
|
76
|
+
tags: [],
|
|
77
|
+
summary: "",
|
|
78
|
+
description: "",
|
|
79
|
+
operationId: "",
|
|
80
|
+
deprecated: false,
|
|
81
|
+
parameters: [],
|
|
82
|
+
responses: [],
|
|
83
|
+
security: [],
|
|
84
|
+
requestBody: undefined,
|
|
85
|
+
};
|
|
86
|
+
expect(errId).toBe(buildEndpointId(validEndpoint));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe("ApiEndpointError data contract", () => {
|
|
90
|
+
it("has all required fields for rendering", () => {
|
|
91
|
+
const error = {
|
|
92
|
+
path: "/complex-endpoint",
|
|
93
|
+
method: "post",
|
|
94
|
+
reason: "Complex polymorphism (allOf with discriminator) is not supported",
|
|
95
|
+
rawSpec: {
|
|
96
|
+
post: {
|
|
97
|
+
summary: "Create complex resource",
|
|
98
|
+
requestBody: {
|
|
99
|
+
content: {
|
|
100
|
+
"application/json": {
|
|
101
|
+
schema: {
|
|
102
|
+
allOf: [{ $ref: "#/components/schemas/Base" }],
|
|
103
|
+
discriminator: { propertyName: "type" },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
// Verify all fields exist and are the correct types
|
|
112
|
+
expect(typeof error.path).toBe("string");
|
|
113
|
+
expect(typeof error.method).toBe("string");
|
|
114
|
+
expect(typeof error.reason).toBe("string");
|
|
115
|
+
expect(error.rawSpec).toBeDefined();
|
|
116
|
+
expect(typeof error.rawSpec).toBe("object");
|
|
117
|
+
});
|
|
118
|
+
it("rawSpec serializes to valid JSON for display", () => {
|
|
119
|
+
const error = {
|
|
120
|
+
path: "/test",
|
|
121
|
+
method: "get",
|
|
122
|
+
reason: "test",
|
|
123
|
+
rawSpec: {
|
|
124
|
+
nested: { deeply: { value: [1, 2, 3] } },
|
|
125
|
+
special: 'chars "in" strings',
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
const json = JSON.stringify(error.rawSpec, null, 2);
|
|
129
|
+
expect(() => JSON.parse(json)).not.toThrow();
|
|
130
|
+
expect(json).toContain("nested");
|
|
131
|
+
expect(json).toContain("deeply");
|
|
132
|
+
});
|
|
133
|
+
it("handles empty rawSpec gracefully", () => {
|
|
134
|
+
const error = {
|
|
135
|
+
path: "/test",
|
|
136
|
+
method: "get",
|
|
137
|
+
reason: "test",
|
|
138
|
+
rawSpec: {},
|
|
139
|
+
};
|
|
140
|
+
const json = JSON.stringify(error.rawSpec, null, 2);
|
|
141
|
+
expect(json).toBe("{}");
|
|
142
|
+
});
|
|
143
|
+
it("handles null rawSpec gracefully", () => {
|
|
144
|
+
const error = {
|
|
145
|
+
path: "/test",
|
|
146
|
+
method: "get",
|
|
147
|
+
reason: "test",
|
|
148
|
+
rawSpec: null,
|
|
149
|
+
};
|
|
150
|
+
const json = JSON.stringify(error.rawSpec, null, 2);
|
|
151
|
+
expect(json).toBe("null");
|
|
152
|
+
});
|
|
153
|
+
});
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,4 +10,3 @@ export { getStoredTheme, getEffectiveTheme, applyTheme, THEME_STORAGE_KEY, DEFAU
|
|
|
10
10
|
export { ThemeToggle } from "./islands/ThemeToggle.js";
|
|
11
11
|
export { CopyButton } from "./islands/CopyButton.js";
|
|
12
12
|
export { CodeTabs } from "./islands/CodeTabs.js";
|
|
13
|
-
//# sourceMappingURL=index.js.map
|
package/dist/islands/CodeTabs.js
CHANGED
|
@@ -122,4 +122,3 @@ function CodeTabs({ tabs, syncKey = "sdk-language", ariaLabel = "SDK language ta
|
|
|
122
122
|
return (_jsxs("div", { className: "my-6 border border-border rounded-lg overflow-hidden", children: [_jsx("div", { role: "tablist", "aria-label": ariaLabel, className: "flex border-b border-border bg-surface-raised", onKeyDown: handleKeyDown, children: tabs.map((tab, i) => (_jsx("button", { id: `${groupId}-tab-${i}`, role: "tab", "aria-selected": i === activeIndex, "aria-controls": `${groupId}-panel-${i}`, tabIndex: i === activeIndex ? 0 : -1, className: cn("px-4 py-2 border-b-2 border-transparent text-[0.8125rem] font-medium font-mono", "text-text-muted cursor-pointer whitespace-nowrap bg-transparent", "transition-colors duration-150 hover:text-text", "focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-2", i === activeIndex && "text-text border-b-primary"), onClick: () => setTab(i), children: tab.label }, tab.language))) }), tabs.map((tab, i) => (_jsx("div", { id: `${groupId}-panel-${i}`, role: "tabpanel", "aria-labelledby": `${groupId}-tab-${i}`, tabIndex: 0, className: "code-tabs-panel", style: { display: i === activeIndex ? undefined : "none" }, dangerouslySetInnerHTML: { __html: tab.content } }, tab.language)))] }));
|
|
123
123
|
}
|
|
124
124
|
export { CodeTabs };
|
|
125
|
-
//# sourceMappingURL=CodeTabs.js.map
|
|
@@ -51,4 +51,3 @@ export function CopyButton({ code }) {
|
|
|
51
51
|
/* Copy icon */
|
|
52
52
|
_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }), _jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })] })) }));
|
|
53
53
|
}
|
|
54
|
-
//# sourceMappingURL=CopyButton.js.map
|
|
@@ -106,4 +106,3 @@ export function SearchPalette() {
|
|
|
106
106
|
__html: result.sub_results?.[0]?.excerpt ?? result.excerpt ?? "",
|
|
107
107
|
} })] }, result.id)))] }), (results.length > 0 || query.trim().length > 0) && !isUnavailable && (_jsx("div", { className: "flex items-center justify-between border-t border-border px-3 py-2 text-xs text-text-muted", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "\u2191\u2193" }), "navigate"] }), _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "\u21B5" }), "open"] }), _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "esc" }), "close"] })] }) }))] })] }));
|
|
108
108
|
}
|
|
109
|
-
//# sourceMappingURL=SearchPalette.js.map
|
|
@@ -40,4 +40,3 @@ export function ThemeToggle() {
|
|
|
40
40
|
}, []);
|
|
41
41
|
return (_jsx("button", { type: "button", onClick: toggleTheme, "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", className: "inline-flex items-center justify-center rounded-md p-2 text-text-muted hover:text-(--color-text) hover:bg-hover-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-primary transition-colors", children: _jsxs("span", { className: "relative inline-flex items-center justify-center w-5 h-5", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: `absolute inset-0 transition-transform duration-300 ${isDark ? "rotate-0 scale-100" : "-rotate-90 scale-0"}`, children: [_jsx("circle", { cx: "12", cy: "12", r: "4" }), _jsx("path", { d: "M12 2v2" }), _jsx("path", { d: "M12 20v2" }), _jsx("path", { d: "m4.93 4.93 1.41 1.41" }), _jsx("path", { d: "m17.66 17.66 1.41 1.41" }), _jsx("path", { d: "M2 12h2" }), _jsx("path", { d: "M20 12h2" }), _jsx("path", { d: "m6.34 17.66-1.41 1.41" }), _jsx("path", { d: "m19.07 4.93-1.41 1.41" })] }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: `absolute inset-0 transition-transform duration-300 ${!isDark ? "rotate-0 scale-100" : "rotate-90 scale-0"}`, children: _jsx("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) })] }) }));
|
|
42
42
|
}
|
|
43
|
-
//# sourceMappingURL=ThemeToggle.js.map
|
package/dist/lib/utils.d.ts
CHANGED
package/dist/lib/utils.js
CHANGED
package/dist/ui/command.d.ts
CHANGED
package/dist/ui/command.js
CHANGED
|
@@ -25,4 +25,3 @@ const CommandShortcut = ({ className, ...props }) => {
|
|
|
25
25
|
};
|
|
26
26
|
CommandShortcut.displayName = "CommandShortcut";
|
|
27
27
|
export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, };
|
|
28
|
-
//# sourceMappingURL=command.js.map
|
package/dist/ui/dialog.d.ts
CHANGED
|
@@ -17,4 +17,3 @@ declare const DialogFooter: {
|
|
|
17
17
|
declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
18
18
|
declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
19
19
|
export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
|
|
20
|
-
//# sourceMappingURL=dialog.d.ts.map
|
package/dist/ui/dialog.js
CHANGED
|
@@ -19,4 +19,3 @@ DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
|
19
19
|
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, className: cn("text-sm text-text-muted", className), ...props })));
|
|
20
20
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
21
21
|
export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
|
|
22
|
-
//# sourceMappingURL=dialog.js.map
|
|
@@ -35,4 +35,3 @@ export declare function renderTypeString(schema: ApiSchema | undefined): string;
|
|
|
35
35
|
* suitable for rendering in a table. Only expands 1 level deep for MVP.
|
|
36
36
|
*/
|
|
37
37
|
export declare function flattenSchemaProperties(schema: ApiSchema | undefined, requiredFields?: string[], maxDepth?: number): SchemaProperty[];
|
|
38
|
-
//# sourceMappingURL=schema-renderer.d.ts.map
|
package/dist/utils/shiki.d.ts
CHANGED
package/dist/utils/shiki.js
CHANGED
|
@@ -7,4 +7,3 @@ import type { NavItem } from "@specglass/core";
|
|
|
7
7
|
export declare function filterVisibleItems(items: NavItem[]): NavItem[];
|
|
8
8
|
/** Check if this item or any descendant is the current page. */
|
|
9
9
|
export declare function isActiveOrAncestor(item: NavItem, currentSlug: string): boolean;
|
|
10
|
-
//# sourceMappingURL=sidebar-helpers.d.ts.map
|
package/dist/utils/theme-css.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specglass/theme-default",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Default theme for Specglass — layouts, components, React islands, and styles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"./layouts/*": "./src/layouts/*",
|
|
24
24
|
"./lib/*": "./src/lib/*",
|
|
25
25
|
"./styles/*": "./src/styles/*",
|
|
26
|
-
"./utils/*": "./src/utils/*"
|
|
26
|
+
"./utils/*": "./src/utils/*",
|
|
27
|
+
"./ui/*": "./src/ui/*",
|
|
28
|
+
"./scripts/*": "./src/scripts/*"
|
|
27
29
|
},
|
|
28
30
|
"files": [
|
|
29
31
|
"dist",
|
|
@@ -32,7 +34,9 @@
|
|
|
32
34
|
"src/layouts",
|
|
33
35
|
"src/lib",
|
|
34
36
|
"src/styles",
|
|
35
|
-
"src/utils"
|
|
37
|
+
"src/utils",
|
|
38
|
+
"src/ui",
|
|
39
|
+
"src/scripts"
|
|
36
40
|
],
|
|
37
41
|
"scripts": {
|
|
38
42
|
"build": "tsc",
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* ApiEndpointFallback.astro — Renders a "Manual Documentation Required" placeholder
|
|
4
|
+
* for endpoints where the OpenAPI parser encountered unsupported spec patterns (FR40).
|
|
5
|
+
*
|
|
6
|
+
* Shows the error reason and raw spec data in a collapsible, syntax-highlighted block.
|
|
7
|
+
*/
|
|
8
|
+
import type { ApiEndpointError } from "@specglass/core";
|
|
9
|
+
import { CopyButton } from "../islands/CopyButton";
|
|
10
|
+
import { highlight } from "../utils/shiki";
|
|
11
|
+
|
|
12
|
+
export interface Props {
|
|
13
|
+
error: ApiEndpointError;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { error } = Astro.props;
|
|
17
|
+
|
|
18
|
+
const methodColors: Record<string, string> = {
|
|
19
|
+
get: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border-emerald-500/30",
|
|
20
|
+
post: "bg-blue-500/15 text-blue-700 dark:text-blue-400 border-blue-500/30",
|
|
21
|
+
put: "bg-amber-500/15 text-amber-700 dark:text-amber-400 border-amber-500/30",
|
|
22
|
+
patch: "bg-yellow-500/15 text-yellow-700 dark:text-yellow-400 border-yellow-500/30",
|
|
23
|
+
delete: "bg-red-500/15 text-red-700 dark:text-red-400 border-red-500/30",
|
|
24
|
+
options: "bg-purple-500/15 text-purple-700 dark:text-purple-400 border-purple-500/30",
|
|
25
|
+
head: "bg-gray-500/15 text-gray-700 dark:text-gray-400 border-gray-500/30",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const methodColor = methodColors[error.method.toLowerCase()] ?? methodColors.get;
|
|
29
|
+
const rawSpecJson = JSON.stringify(error.rawSpec, null, 2);
|
|
30
|
+
const highlightedSpec = await highlight(rawSpecJson, "json");
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<div id={`endpoint-${error.method}-${error.path.replace(/[{}\\\/]/g, "-")}`} class="mb-8">
|
|
34
|
+
{/* Method + Path header */}
|
|
35
|
+
<div class="flex items-center gap-3 mb-4">
|
|
36
|
+
<span
|
|
37
|
+
class:list={[
|
|
38
|
+
"inline-flex items-center px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider border",
|
|
39
|
+
methodColor,
|
|
40
|
+
]}
|
|
41
|
+
>
|
|
42
|
+
{error.method.toUpperCase()}
|
|
43
|
+
</span>
|
|
44
|
+
<code class="text-lg font-mono text-text font-semibold break-all">
|
|
45
|
+
{error.path}
|
|
46
|
+
</code>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{/* Warning alert */}
|
|
50
|
+
<div
|
|
51
|
+
role="alert"
|
|
52
|
+
class="rounded-lg border border-amber-500/30 bg-amber-50 dark:bg-amber-950/20 px-5 py-4 mb-6"
|
|
53
|
+
>
|
|
54
|
+
<div class="flex items-start gap-3">
|
|
55
|
+
<span class="text-amber-600 dark:text-amber-400 text-xl mt-0.5" aria-hidden="true">⚠️</span>
|
|
56
|
+
<div>
|
|
57
|
+
<h3 class="text-base font-semibold text-amber-800 dark:text-amber-200 mt-0 mb-1">
|
|
58
|
+
Manual Documentation Required
|
|
59
|
+
</h3>
|
|
60
|
+
<p class="text-sm text-amber-700 dark:text-amber-300 leading-relaxed m-0">
|
|
61
|
+
This endpoint uses an OpenAPI spec pattern that couldn't be fully parsed.
|
|
62
|
+
{
|
|
63
|
+
error.reason && (
|
|
64
|
+
<span class="block mt-1 text-amber-600 dark:text-amber-400 font-medium">
|
|
65
|
+
{error.reason}
|
|
66
|
+
</span>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
{/* Raw spec data — collapsed by default */}
|
|
75
|
+
<details class="rounded-lg border border-border bg-surface-code overflow-hidden">
|
|
76
|
+
<summary
|
|
77
|
+
class="cursor-pointer px-4 py-3 text-sm font-medium text-text-muted hover:text-text transition-colors select-none flex items-center gap-2"
|
|
78
|
+
>
|
|
79
|
+
<svg
|
|
80
|
+
class="w-4 h-4 transition-transform open:rotate-90"
|
|
81
|
+
viewBox="0 0 20 20"
|
|
82
|
+
fill="currentColor"
|
|
83
|
+
aria-hidden="true"
|
|
84
|
+
>
|
|
85
|
+
<path
|
|
86
|
+
fill-rule="evenodd"
|
|
87
|
+
d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
|
|
88
|
+
clip-rule="evenodd"></path>
|
|
89
|
+
</svg>
|
|
90
|
+
View raw OpenAPI spec data
|
|
91
|
+
</summary>
|
|
92
|
+
<div class="relative group border-t border-border">
|
|
93
|
+
<div
|
|
94
|
+
class="[&_pre]:overflow-x-auto [&_pre]:p-4 [&_pre]:text-sm [&_pre]:leading-relaxed [&_pre]:m-0"
|
|
95
|
+
set:html={highlightedSpec}
|
|
96
|
+
/>
|
|
97
|
+
<div class="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
98
|
+
<CopyButton client:idle code={rawSpecJson} />
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</details>
|
|
102
|
+
</div>
|