@lukoweb/apitogo 0.2.30 → 0.2.34
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 +794 -248
- package/dist/declarations/app/entry.server.d.ts +2 -2
- package/dist/declarations/app/main.d.ts +3 -1
- package/dist/declarations/cli/platform/client/platform-api.d.ts +16 -5
- package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/platform-plan.d.ts +1 -1
- package/dist/declarations/cli/platform/helpers/zip.d.ts +1 -1
- package/dist/declarations/cli/platform/tools/infrastructure.d.ts +0 -4
- package/dist/declarations/config/effective-redirects.d.ts +6 -0
- package/dist/declarations/config/header-navigation-guard.d.ts +2 -0
- package/dist/declarations/config/resolve-modules.d.ts +1 -4
- package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +1 -2
- package/docs/cli/commands.md +151 -75
- package/docs/cli/go-live.md +135 -123
- package/docs/cli/walkthrough.md +40 -1
- package/docs/configuration/gateway.md +52 -0
- package/docs/guides/customer-account.md +33 -2
- package/docs/mcp/tools.md +101 -102
- package/package.json +2 -1
- package/src/app/demo.tsx +78 -77
- package/src/app/entry.client.tsx +115 -107
- package/src/app/entry.server.tsx +164 -160
- package/src/app/main.tsx +175 -167
- package/src/app/standalone.tsx +61 -60
- package/src/config/effective-redirects.ts +31 -0
- package/src/config/header-navigation-guard.ts +13 -0
- package/src/config/resolve-modules.ts +331 -354
- package/src/config/v2/home-redirect.ts +104 -98
- package/src/config/v2/index.ts +127 -126
- package/src/config/v2/ledger.ts +242 -235
- package/src/config/v2/resolve.ts +12 -4
- package/src/config/v2/rules.ts +716 -714
- package/src/config/v2/services.ts +799 -663
- package/src/config/v2/workspace.ts +17 -1
- package/src/config/validators/HeaderNavigationSchema.ts +42 -44
- package/src/lib/assets/powered-by-icon.png +0 -0
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +667 -602
- package/src/lib/authentication/providers/dev-portal.tsx +476 -448
- package/src/lib/components/HeaderNavigation.tsx +176 -176
- package/src/lib/components/MobileTopNavigation.tsx +283 -283
- package/src/lib/components/navigation/PoweredByZudoku.tsx +42 -39
- package/src/vite/plugin-offroot-resolve.ts +68 -67
- package/src/vite/prerender/prerender.ts +242 -242
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukoweb/apitogo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.34",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css",
|
|
@@ -171,6 +171,7 @@
|
|
|
171
171
|
"build": "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
|
|
172
172
|
"postbuild": "tsx scripts/check-external-deps.ts",
|
|
173
173
|
"typecheck": "tsc --project tsconfig.app.json --noEmit",
|
|
174
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
174
175
|
"generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
|
|
175
176
|
"build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
|
|
176
177
|
"prepack": "npm run build && tsx scripts/generate-publish-exports.ts",
|
package/src/app/demo.tsx
CHANGED
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
import logger from "loglevel";
|
|
2
|
-
import { createRoot } from "react-dom/client";
|
|
3
|
-
import { createBrowserRouter } from "react-router";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import "../lib/util/logInit.js";
|
|
8
|
-
import "./main.css";
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// This
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
import logger from "loglevel";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { createBrowserRouter } from "react-router";
|
|
4
|
+
import { resolveModulesConfig } from "../config/resolve-modules.js";
|
|
5
|
+
import type { ZudokuConfig } from "../config/validators/ZudokuConfig.js";
|
|
6
|
+
import { Bootstrap } from "../lib/components/Bootstrap.js";
|
|
7
|
+
import "../lib/util/logInit.js";
|
|
8
|
+
import "./main.css";
|
|
9
|
+
import DemoAnnouncement from "../lib/demo/DemoAnnouncement.js";
|
|
10
|
+
import { openApiPlugin } from "../lib/plugins/openapi/index.js";
|
|
11
|
+
import { getRoutesByConfig } from "./main.js";
|
|
12
|
+
|
|
13
|
+
const apiUrl = new URL(window.location.href).searchParams.get("api-url");
|
|
14
|
+
const logoUrl = new URL(window.location.href).searchParams.get("logo-url");
|
|
15
|
+
const logoWidth = new URL(window.location.href).searchParams.get("logo-width");
|
|
16
|
+
const title =
|
|
17
|
+
new URL(window.location.href).searchParams.get("title") ?? "Zudoku Demo";
|
|
18
|
+
|
|
19
|
+
if (!apiUrl) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"No API URL in query parameters. Please provide an API URL using the `api-url` query parameter.",
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
logger.info(`API URL: ${apiUrl}`);
|
|
26
|
+
|
|
27
|
+
const root =
|
|
28
|
+
document.getElementById("zudoku") ?? document.getElementById("root");
|
|
29
|
+
|
|
30
|
+
if (!root) {
|
|
31
|
+
throw new Error("No div found with id root");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// IMPORTANT: This component must not contain tailwind classes
|
|
35
|
+
// This directory is not processed by the tailwind plugin
|
|
36
|
+
|
|
37
|
+
const config: ZudokuConfig = {
|
|
38
|
+
site: {
|
|
39
|
+
title,
|
|
40
|
+
banner: {
|
|
41
|
+
message: <DemoAnnouncement />,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
navigation: [
|
|
45
|
+
{
|
|
46
|
+
type: "link",
|
|
47
|
+
to: "/",
|
|
48
|
+
label: "API Reference",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
plugins: [
|
|
52
|
+
// Using the plugin directly because there's no config file to load in the virtual plugins
|
|
53
|
+
openApiPlugin({
|
|
54
|
+
type: "url",
|
|
55
|
+
input: apiUrl,
|
|
56
|
+
path: "/",
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
} satisfies ZudokuConfig;
|
|
60
|
+
|
|
61
|
+
if (logoUrl && logoWidth) {
|
|
62
|
+
config.site = {
|
|
63
|
+
...config.site,
|
|
64
|
+
logo: {
|
|
65
|
+
src: {
|
|
66
|
+
light: logoUrl,
|
|
67
|
+
dark: logoUrl,
|
|
68
|
+
},
|
|
69
|
+
width: logoWidth,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const routes = getRoutesByConfig(config, resolveModulesConfig);
|
|
75
|
+
const router = createBrowserRouter(routes, {
|
|
76
|
+
basename: window.location.pathname,
|
|
77
|
+
});
|
|
78
|
+
createRoot(root).render(<Bootstrap router={router} />);
|
package/src/app/entry.client.tsx
CHANGED
|
@@ -1,107 +1,115 @@
|
|
|
1
|
-
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
2
|
-
import {
|
|
3
|
-
createBrowserRouter,
|
|
4
|
-
matchRoutes,
|
|
5
|
-
type RouteObject,
|
|
6
|
-
} from "react-router";
|
|
7
|
-
import config from "virtual:zudoku-config";
|
|
8
|
-
import "vite/modulepreload-polyfill";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
1
|
+
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
2
|
+
import {
|
|
3
|
+
createBrowserRouter,
|
|
4
|
+
matchRoutes,
|
|
5
|
+
type RouteObject,
|
|
6
|
+
} from "react-router";
|
|
7
|
+
import config from "virtual:zudoku-config";
|
|
8
|
+
import "vite/modulepreload-polyfill";
|
|
9
|
+
import type { ResolvedModulesConfig } from "../config/validators/ModulesSchema.js";
|
|
10
|
+
import { Bootstrap } from "../lib/components/Bootstrap.js";
|
|
11
|
+
import { getRoutesByConfig } from "./main.js";
|
|
12
|
+
|
|
13
|
+
// The build resolved the modules and put them in the config; parsing them again would put zod in this bundle.
|
|
14
|
+
const routes = getRoutesByConfig(
|
|
15
|
+
config,
|
|
16
|
+
(c) => (c as { __resolvedModules: ResolvedModulesConfig }).__resolvedModules,
|
|
17
|
+
);
|
|
18
|
+
// biome-ignore lint/style/noNonNullAssertion: We know the root element exists
|
|
19
|
+
const root = document.getElementById("root")!;
|
|
20
|
+
|
|
21
|
+
declare global {
|
|
22
|
+
interface Window {
|
|
23
|
+
ZUDOKU_VERSION: string;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
window.ZUDOKU_VERSION = process.env.ZUDOKU_VERSION ?? "unknown";
|
|
28
|
+
|
|
29
|
+
if (process.env.SENTRY_DSN) {
|
|
30
|
+
void import("./sentry.js").then((mod) => {
|
|
31
|
+
mod.initSentry({ dsn: process.env.SENTRY_DSN as string });
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (root.childElementCount > 0) {
|
|
36
|
+
void hydrate(routes);
|
|
37
|
+
} else {
|
|
38
|
+
void render(routes);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (import.meta.env.IS_ZUPLO) {
|
|
42
|
+
// biome-ignore lint/suspicious/noConsole: Logging allowed here
|
|
43
|
+
console.log(
|
|
44
|
+
`%cPowered by Zuplo v${window.ZUDOKU_VERSION}`,
|
|
45
|
+
[
|
|
46
|
+
"color: #Df0097",
|
|
47
|
+
"line-height: 50px",
|
|
48
|
+
"font-weight: bolder",
|
|
49
|
+
"font-size: 15px",
|
|
50
|
+
"text-align: center",
|
|
51
|
+
"letter-spacing: 5px",
|
|
52
|
+
].join(" ;"),
|
|
53
|
+
);
|
|
54
|
+
} else {
|
|
55
|
+
// biome-ignore lint/suspicious/noConsole: Logging allowed here
|
|
56
|
+
console.log(
|
|
57
|
+
`%cAPITOGO v${window.ZUDOKU_VERSION}`,
|
|
58
|
+
[
|
|
59
|
+
"color: #0d9488",
|
|
60
|
+
"line-height: 50px",
|
|
61
|
+
"font-weight: bolder",
|
|
62
|
+
"font-size: 15px",
|
|
63
|
+
"text-align: center",
|
|
64
|
+
"letter-spacing: 5px",
|
|
65
|
+
].join(" ;"),
|
|
66
|
+
);
|
|
67
|
+
// biome-ignore lint/suspicious/noConsole: Logging allowed here
|
|
68
|
+
console.log("» Learn more at https://apitogo.com");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function hydrateLazyRoutes(routes: RouteObject[]) {
|
|
72
|
+
const path = window.location.pathname;
|
|
73
|
+
const lazyMatches = matchRoutes(routes, path, config.basePath)?.filter(
|
|
74
|
+
(m) => m.route.lazy,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (lazyMatches?.length) {
|
|
78
|
+
await Promise.all(
|
|
79
|
+
lazyMatches.map(async (m) => {
|
|
80
|
+
if (typeof m.route.lazy !== "function") return;
|
|
81
|
+
|
|
82
|
+
const routeModule = await m.route.lazy();
|
|
83
|
+
Object.assign(m.route, { ...routeModule, lazy: undefined });
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function render(routes: RouteObject[]) {
|
|
90
|
+
const router = createBrowserRouter(routes, {
|
|
91
|
+
basename: config.basePath,
|
|
92
|
+
});
|
|
93
|
+
createRoot(root).render(<Bootstrap router={router} />);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function hydrate(routes: RouteObject[]) {
|
|
97
|
+
// Only the route chunks are awaited. The highlighter keeps loading in the background: whatever needs it reads
|
|
98
|
+
// it with use() and waits on its own, with the prerendered HTML staying on screen, so a page without code
|
|
99
|
+
// (pricing, account, checkout) is not held back by ~260 KB of grammars it never uses.
|
|
100
|
+
await hydrateLazyRoutes(routes);
|
|
101
|
+
|
|
102
|
+
const router = createBrowserRouter(routes, {
|
|
103
|
+
basename: config.basePath,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
hydrateRoot(root, <Bootstrap hydrate router={router} />);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// This is a workaround to avoid version skewing
|
|
110
|
+
// See https://vite.dev/guide/build.html#load-error-handling
|
|
111
|
+
// TODO: Implement a more advanced solution if there are CDN urls or e.g. Vercel Skew Protection
|
|
112
|
+
window.addEventListener("vite:preloadError", (e) => {
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
window.location.reload();
|
|
115
|
+
});
|