radiant-docs 0.1.56 → 0.1.57

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.
Files changed (33) hide show
  1. package/dist/index.js +3 -76
  2. package/package.json +2 -4
  3. package/template/astro.config.mjs +16 -26
  4. package/template/package-lock.json +18 -0
  5. package/template/package.json +1 -1
  6. package/template/src/components/Footer.astro +13 -4
  7. package/template/src/components/Header.astro +26 -6
  8. package/template/src/components/SidebarLink.astro +3 -2
  9. package/template/src/components/SidebarSubgroup.astro +14 -13
  10. package/template/src/components/sidebar/SidebarEndpointLink.astro +13 -3
  11. package/template/src/components/sidebar/SidebarOpenApi.astro +2 -0
  12. package/template/src/components/sidebar/SidebarOpenApiPageLink.astro +1 -0
  13. package/template/src/components/user/Accordion.astro +0 -13
  14. package/template/src/components/user/Callout.astro +0 -29
  15. package/template/src/components/user/Card.astro +31 -204
  16. package/template/src/components/user/CardGradient.astro +8 -1
  17. package/template/src/components/user/Column.astro +0 -17
  18. package/template/src/components/user/Columns.astro +4 -153
  19. package/template/src/components/user/Image.astro +0 -28
  20. package/template/src/components/user/Step.astro +0 -10
  21. package/template/src/components/user/Tab.astro +0 -12
  22. package/template/src/components/user/Tabs.astro +2 -9
  23. package/template/src/content.config.ts +1 -1
  24. package/template/src/lib/code/code-block.ts +1 -1
  25. package/template/src/lib/mdx/remark-code-block-component.ts +1 -20
  26. package/template/src/lib/mdx/remark-resolve-internal-links.ts +150 -204
  27. package/template/src/lib/routes.ts +150 -29
  28. package/template/src/lib/utils.ts +127 -12
  29. package/template/src/lib/validation.ts +5 -2826
  30. package/template/src/pages/[...slug].astro +16 -0
  31. package/template/src/lib/code/shiki-theme-config.ts +0 -16
  32. package/template/src/lib/component-error.ts +0 -202
  33. package/template/src/lib/frontmatter-schema.ts +0 -10
@@ -99,6 +99,8 @@ export async function getStaticPaths(): Promise<GetStaticPathsResult> {
99
99
  const homeRoute: Route = {
100
100
  type: "mdx",
101
101
  slug: "/",
102
+ preferredSlug: "/",
103
+ routeIdentity: `mdx:${config.home}`,
102
104
  filePath: config.home,
103
105
  title:
104
106
  existingHomeRoute?.title ??
@@ -122,6 +124,20 @@ export async function getStaticPaths(): Promise<GetStaticPathsResult> {
122
124
  homePath: config.home,
123
125
  },
124
126
  });
127
+ } else {
128
+ const firstVisibleRoute = visibleRoutes[0];
129
+ if (firstVisibleRoute) {
130
+ paths.push({
131
+ params: { slug: "/" },
132
+ props: {
133
+ route: {
134
+ ...firstVisibleRoute,
135
+ slug: "/",
136
+ preferredSlug: "/",
137
+ },
138
+ },
139
+ });
140
+ }
125
141
  }
126
142
 
127
143
  return paths;
@@ -1,16 +0,0 @@
1
- import { bundledThemes } from "shiki";
2
-
3
- export const DEFAULT_SHIKI_LIGHT_THEME = "github-light";
4
- export const DEFAULT_SHIKI_DARK_THEME = "github-dark";
5
-
6
- export type CodeSyntaxThemeByMode = {
7
- light: string;
8
- dark: string;
9
- };
10
-
11
- export const SHIKI_BUNDLED_THEME_NAMES = Object.keys(bundledThemes).sort();
12
- const SHIKI_BUNDLED_THEME_NAME_SET = new Set(SHIKI_BUNDLED_THEME_NAMES);
13
-
14
- export function isBundledShikiThemeName(value: string): boolean {
15
- return SHIKI_BUNDLED_THEME_NAME_SET.has(value);
16
- }
@@ -1,202 +0,0 @@
1
- /**
2
- * Component validation utilities for user-facing MDX components.
3
- * All errors are tagged with [USER_ERROR] for proper error handling in runner.ts
4
- */
5
-
6
- /**
7
- * Derives the source MDX file path from an Astro URL pathname
8
- */
9
- function getSourceFile(pathname: string): string {
10
- const pagePath = pathname
11
- .replace(/^\/documentation\//, "") // Remove base path
12
- .replace(/\/$/, ""); // Remove trailing slash
13
- return `${pagePath}.mdx`;
14
- }
15
-
16
- /**
17
- * Formats a user-friendly error message with file location
18
- */
19
- function formatError(
20
- componentName: string,
21
- message: string,
22
- sourceFile: string
23
- ): string {
24
- return `[USER_ERROR]: <${componentName}>: ${message} (in ${sourceFile})`;
25
- }
26
-
27
- /**
28
- * Validates that a prop value is one of the allowed values
29
- *
30
- * @example
31
- * validateEnum("Callout", "type", type, ["warning", "info", "tip"], Astro.url.pathname);
32
- */
33
- export function validateEnum<T extends string>(
34
- componentName: string,
35
- propName: string,
36
- value: T,
37
- validValues: readonly T[],
38
- pathname: string
39
- ): void {
40
- if (!validValues.includes(value)) {
41
- const sourceFile = getSourceFile(pathname);
42
- throw new Error(
43
- formatError(
44
- componentName,
45
- `Invalid prop ${propName}="${value}". Expected one of: ${validValues.join(
46
- ", "
47
- )}`,
48
- sourceFile
49
- )
50
- );
51
- }
52
- }
53
-
54
- /**
55
- * Validates that a required prop is provided and not empty
56
- *
57
- * @example
58
- * validateRequired("Step", "title", title, Astro.url.pathname);
59
- */
60
- export function validateRequired(
61
- componentName: string,
62
- propName: string,
63
- value: unknown,
64
- pathname: string
65
- ): void {
66
- if (value === undefined || value === null || value === "") {
67
- const sourceFile = getSourceFile(pathname);
68
- throw new Error(
69
- formatError(
70
- componentName,
71
- `Missing required prop "${propName}"`,
72
- sourceFile
73
- )
74
- );
75
- }
76
- }
77
-
78
- /**
79
- * Validates that a prop is of the expected type
80
- *
81
- * @example
82
- * validateType("Accordion", "defaultOpen", defaultOpen, "boolean", Astro.url.pathname);
83
- */
84
- export function validateType(
85
- componentName: string,
86
- propName: string,
87
- value: unknown,
88
- expectedType:
89
- | "string"
90
- | "number"
91
- | "boolean"
92
- | "object"
93
- | "array"
94
- | readonly ("string" | "number" | "boolean" | "object" | "array")[],
95
- pathname: string
96
- ): void {
97
- // Skip if undefined (optional props)
98
- if (value === undefined) return;
99
-
100
- const expectedTypes = Array.isArray(expectedType)
101
- ? expectedType
102
- : [expectedType];
103
- const isValid = expectedTypes.some((type) =>
104
- type === "array" ? Array.isArray(value) : typeof value === type
105
- );
106
-
107
- if (!isValid) {
108
- const sourceFile = getSourceFile(pathname);
109
- const actualType = Array.isArray(value) ? "array" : typeof value;
110
- const expectedTypeLabel = expectedTypes.join(" or ");
111
- throw new Error(
112
- formatError(
113
- componentName,
114
- `Invalid prop "${propName}": expected ${expectedTypeLabel}, got ${actualType}`,
115
- sourceFile
116
- )
117
- );
118
- }
119
- }
120
-
121
- /**
122
- * Validates multiple props at once using a schema object
123
- *
124
- * @example
125
- * validateProps("Callout", Astro.props, {
126
- * type: { enum: ["warning", "info", "tip", "danger", "success"] },
127
- * title: { type: "string" },
128
- * }, Astro.url.pathname);
129
- */
130
- export type PropSchema = {
131
- required?: boolean;
132
- type?:
133
- | "string"
134
- | "number"
135
- | "boolean"
136
- | "object"
137
- | "array"
138
- | readonly ("string" | "number" | "boolean" | "object" | "array")[];
139
- enum?: readonly string[];
140
- };
141
-
142
- /**
143
- * Validates that no unsupported props are passed to a component.
144
- */
145
- export function validateNoUnknownProps(
146
- componentName: string,
147
- props: Record<string, unknown>,
148
- allowedProps: readonly string[],
149
- pathname: string
150
- ): void {
151
- const allowed = new Set(allowedProps);
152
- const unknownProps = Object.keys(props).filter((key) => !allowed.has(key));
153
-
154
- if (unknownProps.length === 0) return;
155
-
156
- const sourceFile = getSourceFile(pathname);
157
- const unknownLabel = unknownProps.map((name) => `"${name}"`).join(", ");
158
- const allowedLabel = allowedProps.map((name) => `"${name}"`).join(", ");
159
- const propLabel = unknownProps.length === 1 ? "prop" : "props";
160
- throw new Error(
161
- formatError(
162
- componentName,
163
- `Unsupported ${propLabel}: ${unknownLabel}. Allowed props: ${allowedLabel}`,
164
- sourceFile
165
- )
166
- );
167
- }
168
-
169
- export function validateProps(
170
- componentName: string,
171
- props: Record<string, unknown>,
172
- schema: Record<string, PropSchema>,
173
- pathname: string
174
- ): void {
175
- for (const [propName, rules] of Object.entries(schema)) {
176
- const value = props[propName];
177
-
178
- // Check required
179
- if (rules.required) {
180
- validateRequired(componentName, propName, value, pathname);
181
- }
182
-
183
- // Skip further checks if value is undefined (optional)
184
- if (value === undefined) continue;
185
-
186
- // Check type
187
- if (rules.type) {
188
- validateType(componentName, propName, value, rules.type, pathname);
189
- }
190
-
191
- // Check enum
192
- if (rules.enum) {
193
- validateEnum(
194
- componentName,
195
- propName,
196
- value as string,
197
- rules.enum,
198
- pathname
199
- );
200
- }
201
- }
202
- }
@@ -1,10 +0,0 @@
1
- import { z } from "zod";
2
-
3
- // Frontmatter schema for MDX files.
4
- // `title` controls the rendered page title (not navigation labels).
5
- export const docsSchema = z
6
- .object({
7
- title: z.string().optional(),
8
- description: z.string().optional(),
9
- })
10
- .passthrough();