@lukoweb/apitogo 0.1.1 → 0.1.3
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/cli/cli.js +168 -57
- package/dist/declarations/lib/ui/Command.d.ts +1 -1
- package/dist/declarations/lib/util/MdxComponents.d.ts +1 -1
- package/package.json +2 -1
- package/src/app/main.tsx +150 -150
- package/src/config/loader.ts +245 -245
- package/src/index.ts +33 -33
- package/src/lib/authentication/components/CallbackHandler.tsx +45 -45
- package/src/lib/authentication/components/SignIn.tsx +46 -46
- package/src/lib/authentication/components/SignUp.tsx +48 -48
- package/src/lib/authentication/providers/clerk.tsx +224 -224
- package/src/lib/authentication/ui/AuthCard.tsx +7 -7
- package/src/lib/authentication/ui/EmailLinkCallbackUi.tsx +129 -125
- package/src/lib/authentication/ui/EmailLinkSentUi.tsx +105 -101
- package/src/lib/authentication/ui/EmailLinkSignInUi.tsx +100 -96
- package/src/lib/authentication/ui/EmailVerificationUi.tsx +128 -124
- package/src/lib/authentication/ui/ZudokuAuthUi.tsx +620 -616
- package/src/lib/components/AiAssistantMenuItems.tsx +102 -102
- package/src/lib/components/Autocomplete.tsx +123 -123
- package/src/lib/components/DeveloperHint.tsx +39 -35
- package/src/lib/components/Header.tsx +260 -260
- package/src/lib/components/Layout.tsx +53 -53
- package/src/lib/components/Main.tsx +51 -51
- package/src/lib/components/Mermaid.tsx +74 -70
- package/src/lib/components/MobileTopNavigation.tsx +276 -276
- package/src/lib/components/MultiSelect.tsx +86 -82
- package/src/lib/components/TopNavigation.tsx +103 -103
- package/src/lib/components/index.ts +26 -26
- package/src/lib/components/navigation/NavigationCategory.tsx +157 -157
- package/src/lib/components/navigation/NavigationFilterInput.tsx +35 -35
- package/src/lib/components/navigation/NavigationItem.tsx +181 -177
- package/src/lib/core/RouteGuard.tsx +193 -193
- package/src/lib/errors/ErrorMessage.tsx +50 -46
- package/src/lib/plugins/api-catalog/Catalog.tsx +80 -80
- package/src/lib/plugins/api-keys/CreateApiKey.tsx +128 -124
- package/src/lib/plugins/api-keys/CreateApiKeyDialog.tsx +49 -49
- package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +72 -72
- package/src/lib/plugins/api-keys/settings/ApiKeyItem.tsx +342 -342
- package/src/lib/plugins/api-keys/settings/RevealApiKey.tsx +127 -127
- package/src/lib/plugins/markdown/MdxPage.tsx +285 -285
- package/src/lib/plugins/openapi/ApiHeader.tsx +96 -96
- package/src/lib/plugins/openapi/CollapsibleCode.tsx +88 -88
- package/src/lib/plugins/openapi/DownloadSchemaButton.tsx +94 -94
- package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +52 -52
- package/src/lib/plugins/openapi/OperationListItem.tsx +183 -183
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +63 -63
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +120 -117
- package/src/lib/plugins/openapi/SchemaInfo.tsx +344 -344
- package/src/lib/plugins/openapi/SchemaList.tsx +113 -113
- package/src/lib/plugins/openapi/Sidecar.tsx +312 -309
- package/src/lib/plugins/openapi/SidecarExamples.tsx +177 -174
- package/src/lib/plugins/openapi/components/EnumValues.tsx +58 -58
- package/src/lib/plugins/openapi/components/ResponseContent.tsx +117 -114
- package/src/lib/plugins/openapi/playground/BodyPanel.tsx +274 -271
- package/src/lib/plugins/openapi/playground/CollapsibleHeader.tsx +51 -51
- package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +60 -60
- package/src/lib/plugins/openapi/playground/Headers.tsx +188 -181
- package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +75 -75
- package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +38 -38
- package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +45 -45
- package/src/lib/plugins/openapi/playground/Playground.tsx +602 -599
- package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +56 -56
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +151 -148
- package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +70 -70
- package/src/lib/plugins/openapi/playground/request-panel/MultipartField.tsx +91 -91
- package/src/lib/plugins/openapi/playground/result-panel/AudioPlayer.tsx +50 -50
- package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +355 -355
- package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +106 -102
- package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +189 -184
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +299 -299
- package/src/lib/plugins/search-pagefind/IndexingDialog.tsx +162 -162
- package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +202 -202
- package/src/lib/plugins/search-pagefind/ResultList.tsx +122 -118
- package/src/lib/ui/ActionButton.tsx +21 -21
- package/src/lib/ui/Command.tsx +191 -191
- package/src/lib/util/MdxComponents.tsx +150 -150
- package/src/vite/config.ts +234 -231
- package/src/vite/dev-server.ts +291 -291
- package/src/vite/plugin-api-keys.ts +50 -50
- package/src/vite/plugin-api.ts +320 -318
- package/src/vite/plugin-auth.ts +38 -38
- package/src/vite/plugin-component.ts +45 -39
- package/src/vite/plugin-config.ts +75 -75
- package/src/vite/plugin-custom-pages.ts +36 -36
- package/src/vite/plugin-docs.ts +202 -202
- package/src/vite/plugin-markdown-export.ts +214 -214
- package/src/vite/plugin-mdx.ts +149 -149
- package/src/vite/plugin-navigation.ts +106 -106
- package/src/vite/plugin-search.ts +47 -47
- package/src/vite/plugin.ts +42 -42
- package/src/vite/prerender/prerender.ts +233 -233
package/src/vite/plugin-docs.ts
CHANGED
|
@@ -1,202 +1,202 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { glob } from "glob";
|
|
3
|
-
import globParent from "glob-parent";
|
|
4
|
-
import type { Plugin } from "vite";
|
|
5
|
-
import { type ConfigWithMeta, getCurrentConfig } from "../config/loader.js";
|
|
6
|
-
import {
|
|
7
|
-
type NavigationItem,
|
|
8
|
-
NavigationResolver,
|
|
9
|
-
} from "../config/validators/NavigationSchema.js";
|
|
10
|
-
import { DocsConfigSchema } from "../config/validators/ZudokuConfig.js";
|
|
11
|
-
import { traverseNavigation } from "../lib/components/navigation/utils.js";
|
|
12
|
-
import { joinUrl } from "../lib/util/joinUrl.js";
|
|
13
|
-
import { readFrontmatter } from "../lib/util/readFrontmatter.js";
|
|
14
|
-
import { writePluginDebugCode } from "./debug.js";
|
|
15
|
-
|
|
16
|
-
const ensureLeadingSlash = joinUrl;
|
|
17
|
-
|
|
18
|
-
// Glob markdown files and returns a mapping of route paths to file paths.
|
|
19
|
-
export const globMarkdownFiles = async (
|
|
20
|
-
config: ConfigWithMeta,
|
|
21
|
-
options: { absolute: boolean } = { absolute: false },
|
|
22
|
-
): Promise<Record<string, string>> => {
|
|
23
|
-
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
24
|
-
const fileMapping: Record<string, string> = {};
|
|
25
|
-
|
|
26
|
-
for (const globPattern of docsConfig.files) {
|
|
27
|
-
const globbedFiles = await glob(globPattern, {
|
|
28
|
-
root: config.__meta.rootDir,
|
|
29
|
-
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
30
|
-
// Always glob with relative paths to avoid issues on different OS
|
|
31
|
-
absolute: false,
|
|
32
|
-
posix: true,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Normalize parent by removing leading `./` or `/`
|
|
36
|
-
const parent = globParent(globPattern).replace(/^\.?\//, "");
|
|
37
|
-
|
|
38
|
-
// Precompute draft status for all files in production mode to avoid serial I/O
|
|
39
|
-
let draftFiles = new Set<string>();
|
|
40
|
-
if (process.env.NODE_ENV !== "development") {
|
|
41
|
-
const draftStatuses = await Promise.all(
|
|
42
|
-
globbedFiles.map(async (file) => {
|
|
43
|
-
const absolutePath = path.resolve(config.__meta.rootDir, file);
|
|
44
|
-
const { data } = await readFrontmatter(absolutePath);
|
|
45
|
-
return { file, isDraft: data.draft === true };
|
|
46
|
-
}),
|
|
47
|
-
);
|
|
48
|
-
draftFiles = new Set(
|
|
49
|
-
draftStatuses
|
|
50
|
-
.filter((entry) => entry.isDraft)
|
|
51
|
-
.map((entry) => entry.file),
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
for (const file of globbedFiles) {
|
|
56
|
-
// Skip draft documents in production mode
|
|
57
|
-
if (draftFiles.has(file)) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const relativePath = path.posix.relative(parent, file);
|
|
62
|
-
const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
|
|
63
|
-
// Resolve to absolute path if requested, using path.resolve to handle cross-platform paths
|
|
64
|
-
const filePath = options.absolute
|
|
65
|
-
? path.resolve(config.__meta.rootDir, file)
|
|
66
|
-
: file;
|
|
67
|
-
fileMapping[routePath] = filePath;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return fileMapping;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Resolves custom navigation paths and returns an updated file mapping.
|
|
76
|
-
* Handles cases where navigation defines custom paths for documents.
|
|
77
|
-
*/
|
|
78
|
-
export const resolveCustomNavigationPaths = async (
|
|
79
|
-
config: ConfigWithMeta,
|
|
80
|
-
fileMapping: Record<string, string>,
|
|
81
|
-
): Promise<Record<string, string>> => {
|
|
82
|
-
if (!config.navigation && !config.navigationRules) return fileMapping;
|
|
83
|
-
|
|
84
|
-
const resolver = new NavigationResolver(config);
|
|
85
|
-
const mapping = { ...fileMapping };
|
|
86
|
-
|
|
87
|
-
const processItem = (item: NavigationItem) => {
|
|
88
|
-
const doc =
|
|
89
|
-
item.type === "doc"
|
|
90
|
-
? { file: item.file, path: item.path }
|
|
91
|
-
: item.type === "category" && item.link
|
|
92
|
-
? { file: item.link.file, path: item.link.path }
|
|
93
|
-
: undefined;
|
|
94
|
-
|
|
95
|
-
// Only continue if the doc has a custom path
|
|
96
|
-
if (!doc || doc.path === doc.file) return;
|
|
97
|
-
|
|
98
|
-
const fileRoutePath = ensureLeadingSlash(doc.file.replace(/\.mdx?$/, ""));
|
|
99
|
-
const filePath = mapping[fileRoutePath];
|
|
100
|
-
if (!filePath) return;
|
|
101
|
-
|
|
102
|
-
const customPath = ensureLeadingSlash(doc.path);
|
|
103
|
-
mapping[customPath] = filePath;
|
|
104
|
-
delete mapping[fileRoutePath];
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
if (config.navigation) {
|
|
108
|
-
const resolvedNavigation = await resolver.resolve();
|
|
109
|
-
traverseNavigation(resolvedNavigation, processItem);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (config.navigationRules) {
|
|
113
|
-
const resolvedRules = await resolver.resolveRules(config.navigationRules);
|
|
114
|
-
for (const rule of resolvedRules) {
|
|
115
|
-
if (rule.type === "insert") {
|
|
116
|
-
traverseNavigation(rule.items, processItem);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return mapping;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const viteDocsPlugin = (): Plugin => {
|
|
125
|
-
const virtualModuleId = "virtual:zudoku-docs-plugin";
|
|
126
|
-
const resolvedVirtualModuleId = `\0${virtualModuleId}`;
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
name: "zudoku-docs-plugin",
|
|
130
|
-
resolveId(id) {
|
|
131
|
-
if (id === virtualModuleId) {
|
|
132
|
-
return resolvedVirtualModuleId;
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
async load(id) {
|
|
136
|
-
if (id !== resolvedVirtualModuleId) return;
|
|
137
|
-
|
|
138
|
-
const config = getCurrentConfig();
|
|
139
|
-
|
|
140
|
-
if (config.__meta.mode === "standalone") {
|
|
141
|
-
return `export const configuredDocsPlugin = undefined;`;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const code: string[] = [
|
|
145
|
-
// IMPORTANT! This path here is important, we MUST resolve
|
|
146
|
-
// files here as Typescript from the appDir
|
|
147
|
-
config.__meta.mode === "internal"
|
|
148
|
-
? `import { markdownPlugin } from "${config.__meta.moduleDir}/src/lib/plugins/markdown/index.tsx";`
|
|
149
|
-
: `import { markdownPlugin } from "@lukoweb/apitogo/plugins/markdown";`,
|
|
150
|
-
];
|
|
151
|
-
|
|
152
|
-
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
153
|
-
|
|
154
|
-
// This is a workaround for a bug(?) in Vite where `import.meta.glob` failed us:
|
|
155
|
-
// - Root dir is `/path/to/docs`
|
|
156
|
-
// - The Markdown docs config is `/docs/**/*.md`
|
|
157
|
-
// - The basePath config is set to `/docs`
|
|
158
|
-
// This results in:
|
|
159
|
-
// > `Internal server error: Failed to resolve import "/some.md" from "virtual:zudoku-docs-plugins". Does the file exist?`
|
|
160
|
-
// Mind that the `docs` part that should be prepended is not in there
|
|
161
|
-
//
|
|
162
|
-
// This does only happen in dev SSR environments, so for prod the `basePath` is not added
|
|
163
|
-
const globImportBasePath =
|
|
164
|
-
process.env.NODE_ENV === "development" ? (config.basePath ?? "") : "";
|
|
165
|
-
|
|
166
|
-
// Glob markdown files and resolve custom navigation paths
|
|
167
|
-
const fileMapping = await resolveCustomNavigationPaths(
|
|
168
|
-
config,
|
|
169
|
-
await globMarkdownFiles(config, { absolute: false }),
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
// Transform file paths to import paths
|
|
173
|
-
const globbedDocuments: Record<string, string> = {};
|
|
174
|
-
for (const [routePath, file] of Object.entries(fileMapping)) {
|
|
175
|
-
const importPath = ensureLeadingSlash(
|
|
176
|
-
path.posix.join(globImportBasePath, file),
|
|
177
|
-
);
|
|
178
|
-
globbedDocuments[routePath] = importPath;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
code.push(
|
|
182
|
-
`const fileImports = {`,
|
|
183
|
-
...Object.entries(globbedDocuments).map(
|
|
184
|
-
([routePath, importPath]) =>
|
|
185
|
-
` "${routePath}": () => import("${importPath}"),`,
|
|
186
|
-
),
|
|
187
|
-
`};`,
|
|
188
|
-
`export const configuredDocsPlugin = markdownPlugin({`,
|
|
189
|
-
` basePath: "${config.basePath ?? ""}",`,
|
|
190
|
-
` fileImports,`,
|
|
191
|
-
` defaultOptions: ${JSON.stringify(docsConfig.defaultOptions)},`,
|
|
192
|
-
`});`,
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
await writePluginDebugCode(config.__meta.rootDir, "docs-plugin", code);
|
|
196
|
-
|
|
197
|
-
return code.join("\n");
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
export default viteDocsPlugin;
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { glob } from "glob";
|
|
3
|
+
import globParent from "glob-parent";
|
|
4
|
+
import type { Plugin } from "vite";
|
|
5
|
+
import { type ConfigWithMeta, getCurrentConfig } from "../config/loader.js";
|
|
6
|
+
import {
|
|
7
|
+
type NavigationItem,
|
|
8
|
+
NavigationResolver,
|
|
9
|
+
} from "../config/validators/NavigationSchema.js";
|
|
10
|
+
import { DocsConfigSchema } from "../config/validators/ZudokuConfig.js";
|
|
11
|
+
import { traverseNavigation } from "../lib/components/navigation/utils.js";
|
|
12
|
+
import { joinUrl } from "../lib/util/joinUrl.js";
|
|
13
|
+
import { readFrontmatter } from "../lib/util/readFrontmatter.js";
|
|
14
|
+
import { writePluginDebugCode } from "./debug.js";
|
|
15
|
+
|
|
16
|
+
const ensureLeadingSlash = joinUrl;
|
|
17
|
+
|
|
18
|
+
// Glob markdown files and returns a mapping of route paths to file paths.
|
|
19
|
+
export const globMarkdownFiles = async (
|
|
20
|
+
config: ConfigWithMeta,
|
|
21
|
+
options: { absolute: boolean } = { absolute: false },
|
|
22
|
+
): Promise<Record<string, string>> => {
|
|
23
|
+
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
24
|
+
const fileMapping: Record<string, string> = {};
|
|
25
|
+
|
|
26
|
+
for (const globPattern of docsConfig.files) {
|
|
27
|
+
const globbedFiles = await glob(globPattern, {
|
|
28
|
+
root: config.__meta.rootDir,
|
|
29
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
30
|
+
// Always glob with relative paths to avoid issues on different OS
|
|
31
|
+
absolute: false,
|
|
32
|
+
posix: true,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Normalize parent by removing leading `./` or `/`
|
|
36
|
+
const parent = globParent(globPattern).replace(/^\.?\//, "");
|
|
37
|
+
|
|
38
|
+
// Precompute draft status for all files in production mode to avoid serial I/O
|
|
39
|
+
let draftFiles = new Set<string>();
|
|
40
|
+
if (process.env.NODE_ENV !== "development") {
|
|
41
|
+
const draftStatuses = await Promise.all(
|
|
42
|
+
globbedFiles.map(async (file) => {
|
|
43
|
+
const absolutePath = path.resolve(config.__meta.rootDir, file);
|
|
44
|
+
const { data } = await readFrontmatter(absolutePath);
|
|
45
|
+
return { file, isDraft: data.draft === true };
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
draftFiles = new Set(
|
|
49
|
+
draftStatuses
|
|
50
|
+
.filter((entry) => entry.isDraft)
|
|
51
|
+
.map((entry) => entry.file),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const file of globbedFiles) {
|
|
56
|
+
// Skip draft documents in production mode
|
|
57
|
+
if (draftFiles.has(file)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const relativePath = path.posix.relative(parent, file);
|
|
62
|
+
const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
|
|
63
|
+
// Resolve to absolute path if requested, using path.resolve to handle cross-platform paths
|
|
64
|
+
const filePath = options.absolute
|
|
65
|
+
? path.resolve(config.__meta.rootDir, file)
|
|
66
|
+
: file;
|
|
67
|
+
fileMapping[routePath] = filePath;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return fileMapping;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Resolves custom navigation paths and returns an updated file mapping.
|
|
76
|
+
* Handles cases where navigation defines custom paths for documents.
|
|
77
|
+
*/
|
|
78
|
+
export const resolveCustomNavigationPaths = async (
|
|
79
|
+
config: ConfigWithMeta,
|
|
80
|
+
fileMapping: Record<string, string>,
|
|
81
|
+
): Promise<Record<string, string>> => {
|
|
82
|
+
if (!config.navigation && !config.navigationRules) return fileMapping;
|
|
83
|
+
|
|
84
|
+
const resolver = new NavigationResolver(config);
|
|
85
|
+
const mapping = { ...fileMapping };
|
|
86
|
+
|
|
87
|
+
const processItem = (item: NavigationItem) => {
|
|
88
|
+
const doc =
|
|
89
|
+
item.type === "doc"
|
|
90
|
+
? { file: item.file, path: item.path }
|
|
91
|
+
: item.type === "category" && item.link
|
|
92
|
+
? { file: item.link.file, path: item.link.path }
|
|
93
|
+
: undefined;
|
|
94
|
+
|
|
95
|
+
// Only continue if the doc has a custom path
|
|
96
|
+
if (!doc || doc.path === doc.file) return;
|
|
97
|
+
|
|
98
|
+
const fileRoutePath = ensureLeadingSlash(doc.file.replace(/\.mdx?$/, ""));
|
|
99
|
+
const filePath = mapping[fileRoutePath];
|
|
100
|
+
if (!filePath) return;
|
|
101
|
+
|
|
102
|
+
const customPath = ensureLeadingSlash(doc.path);
|
|
103
|
+
mapping[customPath] = filePath;
|
|
104
|
+
delete mapping[fileRoutePath];
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (config.navigation) {
|
|
108
|
+
const resolvedNavigation = await resolver.resolve();
|
|
109
|
+
traverseNavigation(resolvedNavigation, processItem);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (config.navigationRules) {
|
|
113
|
+
const resolvedRules = await resolver.resolveRules(config.navigationRules);
|
|
114
|
+
for (const rule of resolvedRules) {
|
|
115
|
+
if (rule.type === "insert") {
|
|
116
|
+
traverseNavigation(rule.items, processItem);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return mapping;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const viteDocsPlugin = (): Plugin => {
|
|
125
|
+
const virtualModuleId = "virtual:zudoku-docs-plugin";
|
|
126
|
+
const resolvedVirtualModuleId = `\0${virtualModuleId}`;
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
name: "zudoku-docs-plugin",
|
|
130
|
+
resolveId(id) {
|
|
131
|
+
if (id === virtualModuleId) {
|
|
132
|
+
return resolvedVirtualModuleId;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
async load(id) {
|
|
136
|
+
if (id !== resolvedVirtualModuleId) return;
|
|
137
|
+
|
|
138
|
+
const config = getCurrentConfig();
|
|
139
|
+
|
|
140
|
+
if (config.__meta.mode === "standalone") {
|
|
141
|
+
return `export const configuredDocsPlugin = undefined;`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const code: string[] = [
|
|
145
|
+
// IMPORTANT! This path here is important, we MUST resolve
|
|
146
|
+
// files here as Typescript from the appDir
|
|
147
|
+
config.__meta.mode === "internal"
|
|
148
|
+
? `import { markdownPlugin } from "${config.__meta.moduleDir}/src/lib/plugins/markdown/index.tsx";`
|
|
149
|
+
: `import { markdownPlugin } from "@lukoweb/apitogo/plugins/markdown";`,
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
153
|
+
|
|
154
|
+
// This is a workaround for a bug(?) in Vite where `import.meta.glob` failed us:
|
|
155
|
+
// - Root dir is `/path/to/docs`
|
|
156
|
+
// - The Markdown docs config is `/docs/**/*.md`
|
|
157
|
+
// - The basePath config is set to `/docs`
|
|
158
|
+
// This results in:
|
|
159
|
+
// > `Internal server error: Failed to resolve import "/some.md" from "virtual:zudoku-docs-plugins". Does the file exist?`
|
|
160
|
+
// Mind that the `docs` part that should be prepended is not in there
|
|
161
|
+
//
|
|
162
|
+
// This does only happen in dev SSR environments, so for prod the `basePath` is not added
|
|
163
|
+
const globImportBasePath =
|
|
164
|
+
process.env.NODE_ENV === "development" ? (config.basePath ?? "") : "";
|
|
165
|
+
|
|
166
|
+
// Glob markdown files and resolve custom navigation paths
|
|
167
|
+
const fileMapping = await resolveCustomNavigationPaths(
|
|
168
|
+
config,
|
|
169
|
+
await globMarkdownFiles(config, { absolute: false }),
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// Transform file paths to import paths
|
|
173
|
+
const globbedDocuments: Record<string, string> = {};
|
|
174
|
+
for (const [routePath, file] of Object.entries(fileMapping)) {
|
|
175
|
+
const importPath = ensureLeadingSlash(
|
|
176
|
+
path.posix.join(globImportBasePath, file),
|
|
177
|
+
);
|
|
178
|
+
globbedDocuments[routePath] = importPath;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
code.push(
|
|
182
|
+
`const fileImports = {`,
|
|
183
|
+
...Object.entries(globbedDocuments).map(
|
|
184
|
+
([routePath, importPath]) =>
|
|
185
|
+
` "${routePath}": () => import("${importPath}"),`,
|
|
186
|
+
),
|
|
187
|
+
`};`,
|
|
188
|
+
`export const configuredDocsPlugin = markdownPlugin({`,
|
|
189
|
+
` basePath: "${config.basePath ?? ""}",`,
|
|
190
|
+
` fileImports,`,
|
|
191
|
+
` defaultOptions: ${JSON.stringify(docsConfig.defaultOptions)},`,
|
|
192
|
+
`});`,
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
await writePluginDebugCode(config.__meta.rootDir, "docs-plugin", code);
|
|
196
|
+
|
|
197
|
+
return code.join("\n");
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export default viteDocsPlugin;
|