@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.
Files changed (44) hide show
  1. package/dist/cli/cli.js +794 -248
  2. package/dist/declarations/app/entry.server.d.ts +2 -2
  3. package/dist/declarations/app/main.d.ts +3 -1
  4. package/dist/declarations/cli/platform/client/platform-api.d.ts +16 -5
  5. package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +1 -1
  6. package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -1
  7. package/dist/declarations/cli/platform/helpers/platform-plan.d.ts +1 -1
  8. package/dist/declarations/cli/platform/helpers/zip.d.ts +1 -1
  9. package/dist/declarations/cli/platform/tools/infrastructure.d.ts +0 -4
  10. package/dist/declarations/config/effective-redirects.d.ts +6 -0
  11. package/dist/declarations/config/header-navigation-guard.d.ts +2 -0
  12. package/dist/declarations/config/resolve-modules.d.ts +1 -4
  13. package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +1 -2
  14. package/docs/cli/commands.md +151 -75
  15. package/docs/cli/go-live.md +135 -123
  16. package/docs/cli/walkthrough.md +40 -1
  17. package/docs/configuration/gateway.md +52 -0
  18. package/docs/guides/customer-account.md +33 -2
  19. package/docs/mcp/tools.md +101 -102
  20. package/package.json +2 -1
  21. package/src/app/demo.tsx +78 -77
  22. package/src/app/entry.client.tsx +115 -107
  23. package/src/app/entry.server.tsx +164 -160
  24. package/src/app/main.tsx +175 -167
  25. package/src/app/standalone.tsx +61 -60
  26. package/src/config/effective-redirects.ts +31 -0
  27. package/src/config/header-navigation-guard.ts +13 -0
  28. package/src/config/resolve-modules.ts +331 -354
  29. package/src/config/v2/home-redirect.ts +104 -98
  30. package/src/config/v2/index.ts +127 -126
  31. package/src/config/v2/ledger.ts +242 -235
  32. package/src/config/v2/resolve.ts +12 -4
  33. package/src/config/v2/rules.ts +716 -714
  34. package/src/config/v2/services.ts +799 -663
  35. package/src/config/v2/workspace.ts +17 -1
  36. package/src/config/validators/HeaderNavigationSchema.ts +42 -44
  37. package/src/lib/assets/powered-by-icon.png +0 -0
  38. package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +667 -602
  39. package/src/lib/authentication/providers/dev-portal.tsx +476 -448
  40. package/src/lib/components/HeaderNavigation.tsx +176 -176
  41. package/src/lib/components/MobileTopNavigation.tsx +283 -283
  42. package/src/lib/components/navigation/PoweredByZudoku.tsx +42 -39
  43. package/src/vite/plugin-offroot-resolve.ts +68 -67
  44. package/src/vite/prerender/prerender.ts +242 -242
@@ -1,160 +1,164 @@
1
- import { dehydrate, QueryClient } from "@tanstack/react-query";
2
- import type { HelmetData } from "@zudoku/react-helmet-async";
3
- import logger from "loglevel";
4
- import { renderToReadableStream, renderToStaticMarkup } from "react-dom/server";
5
- import {
6
- createStaticHandler,
7
- createStaticRouter,
8
- isRouteErrorResponse,
9
- type RouteObject,
10
- } from "react-router";
11
- import "vite/modulepreload-polyfill";
12
- import { BootstrapStatic } from "../lib/components/Bootstrap.js";
13
- import { NO_DEHYDRATE } from "../lib/components/cache.js";
14
- import { ServerError } from "../lib/errors/ServerError.js";
15
- import { highlighterPromise } from "../lib/shiki.js";
16
- import { getRoutesByConfig } from "./main.js";
17
- export { getRoutesByConfig };
18
-
19
- // Statically importing shiki.ts here ensures it's in the SSR bundle.
20
- // main.tsx dynamically imports it instead to enable lazy loading on the client.
21
- await import("virtual:zudoku-shiki-register").then(
22
- async ({ registerShiki }) => {
23
- const highlighter = await highlighterPromise;
24
- await registerShiki(highlighter);
25
- },
26
- );
27
- export const handleRequest = async ({
28
- template,
29
- request,
30
- routes,
31
- basePath,
32
- bypassProtection,
33
- }: {
34
- template: string;
35
- request: Request;
36
- routes: RouteObject[];
37
- basePath?: string;
38
- bypassProtection?: boolean;
39
- }): Promise<Response> => {
40
- const { query, dataRoutes } = createStaticHandler(routes, {
41
- basename: basePath,
42
- });
43
- const queryClient = new QueryClient();
44
-
45
- const context = await query(request);
46
-
47
- if (context instanceof Response) {
48
- if ([301, 302, 303, 307, 308].includes(context.status)) {
49
- return new Response(null, {
50
- status: context.status,
51
- headers: { Location: context.headers.get("Location") ?? "" },
52
- });
53
- }
54
- throw context;
55
- }
56
-
57
- let status = 200;
58
- if (context.errors) {
59
- const firstError = Object.values(context.errors).find(isRouteErrorResponse);
60
- if (firstError?.status) {
61
- status = firstError.status;
62
- }
63
- }
64
-
65
- const router = createStaticRouter(dataRoutes, context);
66
- const helmetContext = {} as HelmetData["context"];
67
- const renderContext = {
68
- status: 200,
69
- bypassProtection: bypassProtection ?? false,
70
- };
71
-
72
- const App = (
73
- <BootstrapStatic
74
- router={router}
75
- context={context}
76
- queryClient={queryClient}
77
- helmetContext={helmetContext}
78
- bypassProtection={bypassProtection}
79
- renderContext={renderContext}
80
- />
81
- );
82
-
83
- try {
84
- const reactStream = await renderToReadableStream(App, {
85
- onError(error) {
86
- status = 500;
87
- if (import.meta.env.PROD) {
88
- logger.error("SSR Error:", error);
89
- }
90
- },
91
- });
92
-
93
- await reactStream.allReady;
94
-
95
- const [htmlStart, htmlEnd] = template.split("<!--app-html-->");
96
- if (!htmlStart) {
97
- throw new Error("No <!--app-html--> found in template");
98
- }
99
-
100
- const encoder = new TextEncoder();
101
- const reader = reactStream.getReader();
102
-
103
- const stream = new ReadableStream<Uint8Array>({
104
- async start(controller) {
105
- const helmetHtml = [
106
- helmetContext.helmet?.title?.toString() ?? "",
107
- helmetContext.helmet?.meta?.toString() ?? "",
108
- helmetContext.helmet?.link?.toString() ?? "",
109
- helmetContext.helmet?.style?.toString() ?? "",
110
- helmetContext.helmet?.script?.toString() ?? "",
111
- ].join("\n");
112
-
113
- controller.enqueue(
114
- encoder.encode(htmlStart.replace("<!--app-helmet-->", helmetHtml)),
115
- );
116
-
117
- while (true) {
118
- const { done, value } = await reader.read();
119
- if (done) break;
120
- controller.enqueue(value);
121
- }
122
-
123
- if (htmlEnd) {
124
- const dehydrated = dehydrate(queryClient, {
125
- shouldDehydrateQuery: (q) => !q.queryKey.includes(NO_DEHYDRATE),
126
- });
127
- const serialized = JSON.stringify(dehydrated)
128
- .replace(/</g, "\\u003c")
129
- .replace(/>/g, "\\u003e");
130
-
131
- const closingTag = "</body>";
132
- const idx = htmlEnd.lastIndexOf(closingTag);
133
-
134
- if (idx === -1) {
135
- controller.enqueue(encoder.encode(htmlEnd));
136
- } else {
137
- controller.enqueue(encoder.encode(htmlEnd.slice(0, idx)));
138
- controller.enqueue(
139
- encoder.encode(`<script>window.DATA=${serialized}</script>`),
140
- );
141
- controller.enqueue(encoder.encode(htmlEnd.slice(idx)));
142
- }
143
- }
144
-
145
- controller.close();
146
- },
147
- });
148
-
149
- return new Response(stream, {
150
- status: renderContext.status !== 200 ? renderContext.status : status,
151
- headers: { "Content-Type": "text/html; charset=utf-8" },
152
- });
153
- } catch (error) {
154
- const html = renderToStaticMarkup(<ServerError error={error} />);
155
- return new Response(html, {
156
- status: 500,
157
- headers: { "Content-Type": "text/html; charset=utf-8" },
158
- });
159
- }
160
- };
1
+ import { dehydrate, QueryClient } from "@tanstack/react-query";
2
+ import type { HelmetData } from "@zudoku/react-helmet-async";
3
+ import logger from "loglevel";
4
+ import { renderToReadableStream, renderToStaticMarkup } from "react-dom/server";
5
+ import {
6
+ createStaticHandler,
7
+ createStaticRouter,
8
+ isRouteErrorResponse,
9
+ type RouteObject,
10
+ } from "react-router";
11
+ import "vite/modulepreload-polyfill";
12
+ import type { ApitogoConfig } from "../config/config.js";
13
+ import { resolveModulesConfig } from "../config/resolve-modules.js";
14
+ import { BootstrapStatic } from "../lib/components/Bootstrap.js";
15
+ import { NO_DEHYDRATE } from "../lib/components/cache.js";
16
+ import { ServerError } from "../lib/errors/ServerError.js";
17
+ import { highlighterPromise } from "../lib/shiki.js";
18
+ import { getRoutesByConfig as routesByConfig } from "./main.js";
19
+
20
+ export const getRoutesByConfig = (config: ApitogoConfig) =>
21
+ routesByConfig(config, resolveModulesConfig);
22
+
23
+ // Statically importing shiki.ts here ensures it's in the SSR bundle.
24
+ // main.tsx dynamically imports it instead to enable lazy loading on the client.
25
+ await import("virtual:zudoku-shiki-register").then(
26
+ async ({ registerShiki }) => {
27
+ const highlighter = await highlighterPromise;
28
+ await registerShiki(highlighter);
29
+ },
30
+ );
31
+ export const handleRequest = async ({
32
+ template,
33
+ request,
34
+ routes,
35
+ basePath,
36
+ bypassProtection,
37
+ }: {
38
+ template: string;
39
+ request: Request;
40
+ routes: RouteObject[];
41
+ basePath?: string;
42
+ bypassProtection?: boolean;
43
+ }): Promise<Response> => {
44
+ const { query, dataRoutes } = createStaticHandler(routes, {
45
+ basename: basePath,
46
+ });
47
+ const queryClient = new QueryClient();
48
+
49
+ const context = await query(request);
50
+
51
+ if (context instanceof Response) {
52
+ if ([301, 302, 303, 307, 308].includes(context.status)) {
53
+ return new Response(null, {
54
+ status: context.status,
55
+ headers: { Location: context.headers.get("Location") ?? "" },
56
+ });
57
+ }
58
+ throw context;
59
+ }
60
+
61
+ let status = 200;
62
+ if (context.errors) {
63
+ const firstError = Object.values(context.errors).find(isRouteErrorResponse);
64
+ if (firstError?.status) {
65
+ status = firstError.status;
66
+ }
67
+ }
68
+
69
+ const router = createStaticRouter(dataRoutes, context);
70
+ const helmetContext = {} as HelmetData["context"];
71
+ const renderContext = {
72
+ status: 200,
73
+ bypassProtection: bypassProtection ?? false,
74
+ };
75
+
76
+ const App = (
77
+ <BootstrapStatic
78
+ router={router}
79
+ context={context}
80
+ queryClient={queryClient}
81
+ helmetContext={helmetContext}
82
+ bypassProtection={bypassProtection}
83
+ renderContext={renderContext}
84
+ />
85
+ );
86
+
87
+ try {
88
+ const reactStream = await renderToReadableStream(App, {
89
+ onError(error) {
90
+ status = 500;
91
+ if (import.meta.env.PROD) {
92
+ logger.error("SSR Error:", error);
93
+ }
94
+ },
95
+ });
96
+
97
+ await reactStream.allReady;
98
+
99
+ const [htmlStart, htmlEnd] = template.split("<!--app-html-->");
100
+ if (!htmlStart) {
101
+ throw new Error("No <!--app-html--> found in template");
102
+ }
103
+
104
+ const encoder = new TextEncoder();
105
+ const reader = reactStream.getReader();
106
+
107
+ const stream = new ReadableStream<Uint8Array>({
108
+ async start(controller) {
109
+ const helmetHtml = [
110
+ helmetContext.helmet?.title?.toString() ?? "",
111
+ helmetContext.helmet?.meta?.toString() ?? "",
112
+ helmetContext.helmet?.link?.toString() ?? "",
113
+ helmetContext.helmet?.style?.toString() ?? "",
114
+ helmetContext.helmet?.script?.toString() ?? "",
115
+ ].join("\n");
116
+
117
+ controller.enqueue(
118
+ encoder.encode(htmlStart.replace("<!--app-helmet-->", helmetHtml)),
119
+ );
120
+
121
+ while (true) {
122
+ const { done, value } = await reader.read();
123
+ if (done) break;
124
+ controller.enqueue(value);
125
+ }
126
+
127
+ if (htmlEnd) {
128
+ const dehydrated = dehydrate(queryClient, {
129
+ shouldDehydrateQuery: (q) => !q.queryKey.includes(NO_DEHYDRATE),
130
+ });
131
+ const serialized = JSON.stringify(dehydrated)
132
+ .replace(/</g, "\\u003c")
133
+ .replace(/>/g, "\\u003e");
134
+
135
+ const closingTag = "</body>";
136
+ const idx = htmlEnd.lastIndexOf(closingTag);
137
+
138
+ if (idx === -1) {
139
+ controller.enqueue(encoder.encode(htmlEnd));
140
+ } else {
141
+ controller.enqueue(encoder.encode(htmlEnd.slice(0, idx)));
142
+ controller.enqueue(
143
+ encoder.encode(`<script>window.DATA=${serialized}</script>`),
144
+ );
145
+ controller.enqueue(encoder.encode(htmlEnd.slice(idx)));
146
+ }
147
+ }
148
+
149
+ controller.close();
150
+ },
151
+ });
152
+
153
+ return new Response(stream, {
154
+ status: renderContext.status !== 200 ? renderContext.status : status,
155
+ headers: { "Content-Type": "text/html; charset=utf-8" },
156
+ });
157
+ } catch (error) {
158
+ const html = renderToStaticMarkup(<ServerError error={error} />);
159
+ return new Response(html, {
160
+ status: 500,
161
+ headers: { "Content-Type": "text/html; charset=utf-8" },
162
+ });
163
+ }
164
+ };