@lukoweb/apitogo 0.2.54 → 0.2.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 (82) hide show
  1. package/dist/cli/cli.js +2196 -1352
  2. package/dist/declarations/cli/platform/client/platform-api.d.ts +29 -0
  3. package/dist/declarations/cli/platform/helpers/platform-plan-catalog.d.ts +6 -0
  4. package/dist/declarations/config/validators/ZudokuConfig.d.ts +2 -0
  5. package/dist/declarations/lib/authentication/providers/openid.d.ts +2 -1
  6. package/dist/declarations/lib/plugins/markdown/index.d.ts +2 -1
  7. package/dist/flat-config.d.ts +1 -0
  8. package/docs/cli/commands.md +50 -32
  9. package/docs/cli/go-live.md +66 -93
  10. package/docs/cli/overview.md +18 -17
  11. package/docs/cli/setup.md +130 -141
  12. package/docs/cli/shape.md +94 -11
  13. package/docs/cli/walkthrough.md +1 -1
  14. package/docs/components/slot.mdx +116 -119
  15. package/docs/configuration/api-reference.md +98 -397
  16. package/docs/configuration/authentication.md +118 -159
  17. package/docs/configuration/footer.mdx +89 -118
  18. package/docs/configuration/make-config.mdx +2 -2
  19. package/docs/configuration/overview.md +97 -166
  20. package/docs/configuration/plans.md +100 -110
  21. package/docs/configuration/portal.md +116 -0
  22. package/docs/customization/colors-theme.mdx +255 -278
  23. package/docs/customization/fonts.md +105 -110
  24. package/docs/customization/landing-page.md +189 -188
  25. package/docs/deploy/apitogo.md +13 -17
  26. package/docs/deployment.md +15 -9
  27. package/docs/guides/stripe-setup.mdx +123 -0
  28. package/docs/markdown/frontmatter.md +172 -173
  29. package/docs/mcp/go-live.md +100 -100
  30. package/docs/mcp/overview.md +76 -76
  31. package/docs/quickstart.md +88 -72
  32. package/docs/writing.mdx +68 -72
  33. package/package.json +1 -1
  34. package/src/config/v2/docs-navigation.ts +7 -2
  35. package/src/config/v2/index.ts +1 -0
  36. package/src/config/v2/resolve.ts +28 -0
  37. package/src/config/v2/rules.ts +32 -1
  38. package/src/config/v2/schema.ts +9 -0
  39. package/src/config/v2/services.ts +90 -15
  40. package/src/config/v2/starter-landing.ts +41 -0
  41. package/src/config/v2/wrapper.ts +141 -7
  42. package/src/config/validators/ZudokuConfig.ts +794 -792
  43. package/src/lib/authentication/providers/openid.tsx +6 -1
  44. package/src/lib/plugins/markdown/index.tsx +86 -82
  45. package/src/vite/dev-server.ts +9 -1
  46. package/src/vite/dev-ssr-config.ts +32 -0
  47. package/src/vite/plugin-config.ts +4 -2
  48. package/src/vite/plugin-docs.ts +213 -205
  49. package/docs/concepts/auth-provider-api-identities.md +0 -105
  50. package/docs/configuration/ai-assistants.md +0 -65
  51. package/docs/configuration/api-catalog.md +0 -109
  52. package/docs/configuration/authentication-auth0.md +0 -181
  53. package/docs/configuration/authentication-azure-ad.md +0 -245
  54. package/docs/configuration/authentication-clerk.md +0 -117
  55. package/docs/configuration/authentication-firebase.md +0 -69
  56. package/docs/configuration/authentication-pingfederate.md +0 -143
  57. package/docs/configuration/authentication-supabase.md +0 -233
  58. package/docs/configuration/build-configuration.mdx +0 -147
  59. package/docs/configuration/docs.md +0 -282
  60. package/docs/configuration/llms.md +0 -90
  61. package/docs/configuration/manifest.md +0 -129
  62. package/docs/configuration/navigation.mdx +0 -415
  63. package/docs/configuration/protected-routes.md +0 -150
  64. package/docs/configuration/search.md +0 -164
  65. package/docs/configuration/sentry.mdx +0 -44
  66. package/docs/configuration/site.md +0 -124
  67. package/docs/configuration/slots.mdx +0 -125
  68. package/docs/configuration/vite-config.md +0 -18
  69. package/docs/custom-plugins.md +0 -285
  70. package/docs/deploy/apache-nginx.md +0 -41
  71. package/docs/deploy/cloudflare-pages.md +0 -74
  72. package/docs/deploy/direct-upload.md +0 -17
  73. package/docs/deploy/github-pages.md +0 -49
  74. package/docs/deploy/vercel.md +0 -101
  75. package/docs/extending/events.md +0 -124
  76. package/docs/guides/environment-variables.md +0 -94
  77. package/docs/guides/managing-api-keys-and-identities.md +0 -89
  78. package/docs/guides/navigation-rules.mdx +0 -203
  79. package/docs/guides/processors.mdx +0 -234
  80. package/docs/guides/transforming-examples.md +0 -156
  81. package/docs/guides/using-multiple-apis.md +0 -87
  82. package/docs/plugins.md +0 -24
@@ -1,205 +1,213 @@
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 (
141
- config.__meta.mode === "standalone" ||
142
- !config.__resolvedModules.docs.enabled
143
- ) {
144
- return `export const configuredDocsPlugin = undefined;`;
145
- }
146
-
147
- const code: string[] = [
148
- // IMPORTANT! This path here is important, we MUST resolve
149
- // files here as Typescript from the appDir
150
- config.__meta.mode === "internal"
151
- ? `import { markdownPlugin } from "${config.__meta.moduleDir}/src/lib/plugins/markdown/index.tsx";`
152
- : `import { markdownPlugin } from "@lukoweb/apitogo/plugins/markdown";`,
153
- ];
154
-
155
- const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
156
-
157
- // This is a workaround for a bug(?) in Vite where `import.meta.glob` failed us:
158
- // - Root dir is `/path/to/docs`
159
- // - The Markdown docs config is `/docs/**/*.md`
160
- // - The basePath config is set to `/docs`
161
- // This results in:
162
- // > `Internal server error: Failed to resolve import "/some.md" from "virtual:zudoku-docs-plugins". Does the file exist?`
163
- // Mind that the `docs` part that should be prepended is not in there
164
- //
165
- // This does only happen in dev SSR environments, so for prod the `basePath` is not added
166
- const globImportBasePath =
167
- process.env.NODE_ENV === "development" ? (config.basePath ?? "") : "";
168
-
169
- // Glob markdown files and resolve custom navigation paths
170
- const fileMapping = await resolveCustomNavigationPaths(
171
- config,
172
- await globMarkdownFiles(config, { absolute: false }),
173
- );
174
-
175
- // Transform file paths to import paths
176
- const globbedDocuments: Record<string, string> = {};
177
- for (const [routePath, file] of Object.entries(fileMapping)) {
178
- const importPath = ensureLeadingSlash(
179
- path.posix.join(globImportBasePath, file),
180
- );
181
- globbedDocuments[routePath] = importPath;
182
- }
183
-
184
- code.push(
185
- `const fileImports = {`,
186
- ...Object.entries(globbedDocuments).map(
187
- ([routePath, importPath]) =>
188
- ` "${routePath}": () => import("${importPath}"),`,
189
- ),
190
- `};`,
191
- `export const configuredDocsPlugin = markdownPlugin({`,
192
- ` basePath: "${config.basePath ?? ""}",`,
193
- ` fileImports,`,
194
- ` defaultOptions: ${JSON.stringify(docsConfig.defaultOptions)},`,
195
- `});`,
196
- );
197
-
198
- await writePluginDebugCode(config.__meta.rootDir, "docs-plugin", code);
199
-
200
- return code.join("\n");
201
- },
202
- };
203
- };
204
-
205
- 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
+ // A path that is the file's own route changes nothing; moving it would delete the page (`index` at `/index`, API-129).
104
+ if (customPath === fileRoutePath) return;
105
+ mapping[customPath] = filePath;
106
+ delete mapping[fileRoutePath];
107
+ };
108
+
109
+ if (config.navigation) {
110
+ const resolvedNavigation = await resolver.resolve();
111
+ traverseNavigation(resolvedNavigation, processItem);
112
+ }
113
+
114
+ if (config.navigationRules) {
115
+ const resolvedRules = await resolver.resolveRules(config.navigationRules);
116
+ for (const rule of resolvedRules) {
117
+ if (rule.type === "insert") {
118
+ traverseNavigation(rule.items, processItem);
119
+ }
120
+ }
121
+ }
122
+
123
+ return mapping;
124
+ };
125
+
126
+ const viteDocsPlugin = (): Plugin => {
127
+ const virtualModuleId = "virtual:zudoku-docs-plugin";
128
+ const resolvedVirtualModuleId = `\0${virtualModuleId}`;
129
+
130
+ return {
131
+ name: "zudoku-docs-plugin",
132
+ resolveId(id) {
133
+ if (id === virtualModuleId) {
134
+ return resolvedVirtualModuleId;
135
+ }
136
+ },
137
+ async load(id) {
138
+ if (id !== resolvedVirtualModuleId) return;
139
+
140
+ const config = getCurrentConfig();
141
+
142
+ if (
143
+ config.__meta.mode === "standalone" ||
144
+ !config.__resolvedModules.docs.enabled
145
+ ) {
146
+ return `export const configuredDocsPlugin = undefined;`;
147
+ }
148
+
149
+ const code: string[] = [
150
+ // IMPORTANT! This path here is important, we MUST resolve
151
+ // files here as Typescript from the appDir
152
+ config.__meta.mode === "internal"
153
+ ? `import { markdownPlugin } from "${config.__meta.moduleDir}/src/lib/plugins/markdown/index.tsx";`
154
+ : `import { markdownPlugin } from "@lukoweb/apitogo/plugins/markdown";`,
155
+ ];
156
+
157
+ const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
158
+
159
+ // This is a workaround for a bug(?) in Vite where `import.meta.glob` failed us:
160
+ // - Root dir is `/path/to/docs`
161
+ // - The Markdown docs config is `/docs/**/*.md`
162
+ // - The basePath config is set to `/docs`
163
+ // This results in:
164
+ // > `Internal server error: Failed to resolve import "/some.md" from "virtual:zudoku-docs-plugins". Does the file exist?`
165
+ // Mind that the `docs` part that should be prepended is not in there
166
+ //
167
+ // This does only happen in dev SSR environments, so for prod the `basePath` is not added
168
+ const globImportBasePath =
169
+ process.env.NODE_ENV === "development" ? (config.basePath ?? "") : "";
170
+
171
+ // Glob markdown files and resolve custom navigation paths
172
+ const fileMapping = await resolveCustomNavigationPaths(
173
+ config,
174
+ await globMarkdownFiles(config, { absolute: false }),
175
+ );
176
+
177
+ // Transform file paths to import paths
178
+ const globbedDocuments: Record<string, string> = {};
179
+ for (const [routePath, file] of Object.entries(fileMapping)) {
180
+ const importPath = ensureLeadingSlash(
181
+ path.posix.join(globImportBasePath, file),
182
+ );
183
+ globbedDocuments[routePath] = importPath;
184
+ }
185
+
186
+ code.push(
187
+ `const fileImports = {`,
188
+ ...Object.entries(globbedDocuments).map(
189
+ ([routePath, importPath]) =>
190
+ ` "${routePath}": () => import("${importPath}"),`,
191
+ ),
192
+ `};`,
193
+ `export const configuredDocsPlugin = markdownPlugin({`,
194
+ ` basePath: "${config.basePath ?? ""}",`,
195
+ ` fileImports,`,
196
+ // The home page owns its path, so `pages/index.md` does not take it over (API-129).
197
+ ...(config.__resolvedModules.landing.enabled
198
+ ? [
199
+ ` reservedPaths: ${JSON.stringify([config.__resolvedModules.landing.path])},`,
200
+ ]
201
+ : []),
202
+ ` defaultOptions: ${JSON.stringify(docsConfig.defaultOptions)},`,
203
+ `});`,
204
+ );
205
+
206
+ await writePluginDebugCode(config.__meta.rootDir, "docs-plugin", code);
207
+
208
+ return code.join("\n");
209
+ },
210
+ };
211
+ };
212
+
213
+ export default viteDocsPlugin;
@@ -1,105 +0,0 @@
1
- ---
2
- title: Authentication Providers & API Identities
3
- sidebar_label: Authentication and Identities
4
- ---
5
-
6
- When building an API documentation portal, you often need a way for users to authenticate API
7
- requests — API keys and other identities — separately from how they sign in to the portal. APIToGo
8
- splits **portal authentication** from **API identities**.
9
-
10
- ## Authentication Providers and API Identities
11
-
12
- :::tip
13
-
14
- **Authentication providers** allow your users to sign in to your documentation portal. **API
15
- Identities** allow your users to authenticate their API requests.
16
-
17
- :::
18
-
19
- Before diving into API Identities, it's important to understand that APIToGo separates user
20
- authentication from API authentication. Authentication providers handle how users sign in to your
21
- documentation portal, while API Identities manage how these users interact with your APIs.
22
-
23
- Portal products use [`dev-portal`](../configuration/authentication.md) auth (backend-delegated
24
- OIDC). SPA providers (Auth0, Clerk, …) are advanced for standalone docs sites. Providers handle:
25
-
26
- - User authentication for the documentation portal
27
- - Session management
28
- - User authorization and access control
29
-
30
- This separation allows you to:
31
-
32
- - Use different authentication methods for your portal and APIs
33
- - Manage API access independently of user authentication
34
- - Support multiple API authentication schemes simultaneously
35
-
36
- [Learn more about authentication providers](../configuration/authentication)
37
-
38
- ## Understanding API Identities
39
-
40
- API Identities in APIToGo represent different authentication contexts that can be used to make API
41
- requests. These could be different environments (production, staging), different authentication
42
- methods (API key, JWT), or different service accounts.
43
-
44
- ### The API Identity Interface
45
-
46
- ```typescript
47
- interface ApiIdentity {
48
- id: string;
49
- label: string;
50
- authorizeRequest: (request: Request) => Promise<Request> | Request;
51
- }
52
-
53
- interface ApiIdentityPlugin {
54
- getIdentities: () => Promise<ApiIdentity[]> | ApiIdentity[];
55
- }
56
- ```
57
-
58
- Each API Identity consists of:
59
-
60
- - `id`: A unique identifier for the identity
61
- - `label`: A human-readable name shown in the UI
62
- - `authorizeRequest`: A function that modifies requests to include the necessary authentication
63
-
64
- ## Implementing API Identities
65
-
66
- In this example, we'll use Auth0 as our authentication provider and implement an API Identity for a
67
- demo API.
68
-
69
- :::note
70
-
71
- For APItoGo-hosted portals, subscription keys come from the platform after `dev-portal` sign-in.
72
- Implement custom API Identities when the playground should attach your own keys or JWTs.
73
-
74
- :::
75
-
76
- To add API Identities, implement the `ApiIdentityPlugin` interface:
77
-
78
- ```typescript
79
- import { createApiIdentityPlugin } from "@lukoweb/apitogo/plugins";
80
-
81
- export default {
82
- authentication: {
83
- type: "auth0",
84
- domain: "my-domain.auth0.com",
85
- clientId: "my-client-id",
86
- },
87
- plugins: [
88
- createApiIdentityPlugin({
89
- getIdentities: async (context) => [
90
- {
91
- id: "api-key-one",
92
- label: "My API Key",
93
- authorizeRequest: (request) => {
94
- // We get the access token from the
95
- // authentication provider (Auth0) and add it to the request headers
96
- return context.authentication?.signRequest(request);
97
- },
98
- },
99
- ],
100
- }),
101
- ],
102
- };
103
- ```
104
-
105
- When implemented, this identity will appear in the APIToGo playground.
@@ -1,65 +0,0 @@
1
- ---
2
- title: AI Assistants
3
- sidebar_icon: bot
4
- description:
5
- Configure which AI assistant integrations appear in dropdown menus across your APIToGo
6
- documentation site, including built-in presets and custom providers.
7
- ---
8
-
9
- By default, APIToGo shows "Use in Claude" and "Use in ChatGPT" options in dropdown menus on both
10
- [API reference](./api-reference.md) and [documentation](./docs.md) pages. You can customize this
11
- behavior using the top-level `aiAssistants` configuration.
12
-
13
- ## Disable AI Assistants
14
-
15
- To remove all AI assistant options:
16
-
17
- ```ts title=config
18
- const config = {
19
- aiAssistants: false,
20
- // ...
21
- };
22
- ```
23
-
24
- ## Use Only Specific Presets
25
-
26
- ```ts title=config
27
- const config = {
28
- aiAssistants: ["claude"], // Only show Claude
29
- // ...
30
- };
31
- ```
32
-
33
- Available presets: `"claude"`, `"chatgpt"`
34
-
35
- ## Add Custom AI Assistants
36
-
37
- You can add custom entries with a label and URL. Use `{pageUrl}` as a placeholder in the URL string,
38
- or provide a callback for full control:
39
-
40
- ```ts title=config
41
- const config = {
42
- aiAssistants: [
43
- "claude", // built-in preset
44
- {
45
- label: "Open in MyAI",
46
- // Simple string with placeholder
47
- url: "https://myai.com/?context={pageUrl}",
48
- },
49
- {
50
- label: "Open in CustomAI",
51
- // Callback for full control
52
- url: ({ pageUrl, type }) => {
53
- if (type === "openapi") {
54
- return `https://custom.ai/?q=${encodeURIComponent("Explain this API: " + pageUrl)}`;
55
- }
56
- return `https://custom.ai/?q=${encodeURIComponent("Explain this page: " + pageUrl)}`;
57
- },
58
- },
59
- ],
60
- // ...
61
- };
62
- ```
63
-
64
- The callback receives `{ pageUrl: string, type: "docs" | "openapi" }` so you can customize behavior
65
- per context.