zudoku 0.0.0-monetization-standalone.zd1543a39 → 0.0.0-monetization-standalone.zada7f04c
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/app/main.js +1 -1
- package/dist/app/main.js.map +1 -1
- package/dist/config/create-plugin.d.ts +1 -1
- package/dist/config/create-plugin.js +7 -5
- package/dist/config/create-plugin.js.map +1 -1
- package/dist/config/loader.js +2 -2
- package/dist/config/loader.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/components/Slot.test.js +1 -1
- package/dist/lib/components/Slot.test.js.map +1 -1
- package/dist/lib/components/Zudoku.d.ts +4 -1
- package/dist/lib/components/Zudoku.js +2 -2
- package/dist/lib/components/Zudoku.js.map +1 -1
- package/dist/lib/components/index.d.ts +3 -1
- package/dist/lib/core/ZudokuContext.d.ts +2 -1
- package/dist/lib/core/ZudokuContext.js +3 -1
- package/dist/lib/core/ZudokuContext.js.map +1 -1
- package/dist/lib/core/__internal.d.ts +1 -0
- package/dist/lib/core/__internal.js +2 -0
- package/dist/lib/core/__internal.js.map +1 -1
- package/dist/lib/core/plugins.d.ts +5 -1
- package/dist/lib/core/plugins.js.map +1 -1
- package/dist/lib/core/transform-config.d.ts +3 -1
- package/dist/lib/core/transform-config.js +33 -13
- package/dist/lib/core/transform-config.js.map +1 -1
- package/dist/lib/core/transform-config.test.d.ts +1 -0
- package/dist/lib/core/transform-config.test.js +83 -0
- package/dist/lib/core/transform-config.test.js.map +1 -0
- package/dist/lib/hooks/useEvent.test.js +1 -1
- package/dist/lib/hooks/useEvent.test.js.map +1 -1
- package/dist/vite/config.js +5 -2
- package/dist/vite/config.js.map +1 -1
- package/dist/vite/plugin-config.js +16 -4
- package/dist/vite/plugin-config.js.map +1 -1
- package/lib/{ClaudeLogo-CUaQXKLK.js → ClaudeLogo-K64Qm6gS.js} +2 -2
- package/lib/{ClaudeLogo-CUaQXKLK.js.map → ClaudeLogo-K64Qm6gS.js.map} +1 -1
- package/lib/{MdxPage-BiAVpP8K.js → MdxPage-Cr99RARi.js} +5 -5
- package/lib/{MdxPage-BiAVpP8K.js.map → MdxPage-Cr99RARi.js.map} +1 -1
- package/lib/{OAuthErrorPage-DhJo-O2B.js → OAuthErrorPage-BRXS5AMu.js} +3 -3
- package/lib/{OAuthErrorPage-DhJo-O2B.js.map → OAuthErrorPage-BRXS5AMu.js.map} +1 -1
- package/lib/{OasProvider-DFMZwyNn.js → OasProvider-sP_SqSM7.js} +2 -2
- package/lib/{OasProvider-DFMZwyNn.js.map → OasProvider-sP_SqSM7.js.map} +1 -1
- package/lib/{OperationList-CnmLfOuu.js → OperationList-DR0APPhk.js} +5 -5
- package/lib/{OperationList-CnmLfOuu.js.map → OperationList-DR0APPhk.js.map} +1 -1
- package/lib/{SchemaList-B5ikunUd.js → SchemaList-DgqAAHSI.js} +6 -6
- package/lib/{SchemaList-B5ikunUd.js.map → SchemaList-DgqAAHSI.js.map} +1 -1
- package/lib/{SchemaView-rjji7zMf.js → SchemaView-7IyQYEqk.js} +3 -3
- package/lib/{SchemaView-rjji7zMf.js.map → SchemaView-7IyQYEqk.js.map} +1 -1
- package/lib/{SignUp-DHWDXat-.js → SignUp-D3zhMk7q.js} +2 -2
- package/lib/{SignUp-DHWDXat-.js.map → SignUp-D3zhMk7q.js.map} +1 -1
- package/lib/{Toc-vMbSQCkj.js → Toc-GluXkcIk.js} +2 -2
- package/lib/{Toc-vMbSQCkj.js.map → Toc-GluXkcIk.js.map} +1 -1
- package/lib/{circular-CLhJAE3S.js → circular-Bunzbpsy.js} +2 -2
- package/lib/{circular-CLhJAE3S.js.map → circular-Bunzbpsy.js.map} +1 -1
- package/lib/{createServer-BYtu5Pcr.js → createServer-Dl4Xwsm4.js} +4 -4
- package/lib/{createServer-BYtu5Pcr.js.map → createServer-Dl4Xwsm4.js.map} +1 -1
- package/lib/{errors-DkJIl45d.js → errors-D2NINcVk.js} +2 -2
- package/lib/{errors-DkJIl45d.js.map → errors-D2NINcVk.js.map} +1 -1
- package/lib/{firebase-CmsW0j7-.js → firebase-BVAmGV_v.js} +10 -10
- package/lib/{firebase-CmsW0j7-.js.map → firebase-BVAmGV_v.js.map} +1 -1
- package/lib/{index-k0PVZBYl.js → index-BfTLawvZ.js} +7 -7
- package/lib/{index-k0PVZBYl.js.map → index-BfTLawvZ.js.map} +1 -1
- package/lib/{index-D35F-SCL.js → index-DTjrb36R.js} +2 -2
- package/lib/{index-D35F-SCL.js.map → index-DTjrb36R.js.map} +1 -1
- package/lib/{index-ofqkdEjL.js → index-DYfX9H7i.js} +34 -29
- package/lib/{index-ofqkdEjL.js.map → index-DYfX9H7i.js.map} +1 -1
- package/lib/{index.esm-DFzsB75P.js → index.esm-GMDd_9gw.js} +2 -2
- package/lib/index.esm-GMDd_9gw.js.map +1 -0
- package/lib/zudoku.__internal.js +494 -471
- package/lib/zudoku.__internal.js.map +1 -1
- package/lib/zudoku.auth-azureb2c.js +3 -3
- package/lib/zudoku.auth-clerk.js +1 -1
- package/lib/zudoku.auth-firebase.js +3 -3
- package/lib/zudoku.auth-openid.js +3 -3
- package/lib/zudoku.auth-supabase.js +3 -3
- package/lib/zudoku.components.js +1 -1
- package/lib/zudoku.plugin-api-catalog.js +2 -2
- package/lib/zudoku.plugin-api-keys.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/lib/zudoku.plugins.js.map +1 -1
- package/package.json +1 -2
- package/src/app/main.tsx +1 -1
- package/src/lib/components/Slot.test.tsx +1 -1
- package/src/lib/components/Zudoku.tsx +13 -3
- package/src/lib/core/ZudokuContext.ts +7 -1
- package/src/lib/core/__internal.tsx +2 -0
- package/src/lib/core/plugins.ts +7 -3
- package/src/lib/core/transform-config.test.tsx +99 -0
- package/src/lib/core/transform-config.ts +52 -14
- package/src/lib/hooks/useEvent.test.tsx +1 -1
- package/lib/index.esm-DFzsB75P.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { j as n } from "./jsx-runtime-BzflLqGi.js";
|
|
2
2
|
import { PublicClientApplication as A, EventType as f } from "@azure/msal-browser";
|
|
3
|
-
import { E as I } from "./index-
|
|
3
|
+
import { E as I } from "./index-DYfX9H7i.js";
|
|
4
4
|
import { C as T } from "./ClientOnly-E7hGysn1.js";
|
|
5
5
|
import { j as S, u as h } from "./ZudokuContext-CnEI8jPU.js";
|
|
6
|
-
import { C, A as c } from "./errors-
|
|
7
|
-
import { C as k, O as w } from "./OAuthErrorPage-
|
|
6
|
+
import { C, A as c } from "./errors-D2NINcVk.js";
|
|
7
|
+
import { C as k, O as w } from "./OAuthErrorPage-BRXS5AMu.js";
|
|
8
8
|
const u = "/oauth/callback";
|
|
9
9
|
class y extends C {
|
|
10
10
|
msalInstance;
|
package/lib/zudoku.auth-clerk.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as a } from "./jsx-runtime-BzflLqGi.js";
|
|
2
2
|
import { LogOutIcon as m } from "lucide-react";
|
|
3
|
-
import { S as p, a as f, b as h } from "./SignUp-
|
|
3
|
+
import { S as p, a as f, b as h } from "./SignUp-D3zhMk7q.js";
|
|
4
4
|
import { u as r } from "./ZudokuContext-CnEI8jPU.js";
|
|
5
5
|
const R = ({
|
|
6
6
|
clerkPubKey: u,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./jsx-runtime-BzflLqGi.js";
|
|
2
|
-
import { y as e } from "./firebase-
|
|
2
|
+
import { y as e } from "./firebase-BVAmGV_v.js";
|
|
3
3
|
import "./invariant-BJAl77rw.js";
|
|
4
|
-
import "./errors-
|
|
5
|
-
import "./SignUp-
|
|
4
|
+
import "./errors-D2NINcVk.js";
|
|
5
|
+
import "./SignUp-D3zhMk7q.js";
|
|
6
6
|
import "./ZudokuContext-CnEI8jPU.js";
|
|
7
7
|
export {
|
|
8
8
|
e as default
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { j as D } from "./jsx-runtime-BzflLqGi.js";
|
|
2
2
|
import { a as Le } from "./invariant-BJAl77rw.js";
|
|
3
|
-
import { E as Ue } from "./index-
|
|
3
|
+
import { E as Ue } from "./index-DYfX9H7i.js";
|
|
4
4
|
import { C as xe } from "./ClientOnly-E7hGysn1.js";
|
|
5
5
|
import { j as Ce, u as S } from "./ZudokuContext-CnEI8jPU.js";
|
|
6
|
-
import { C as Ie, O as re, A as R } from "./errors-
|
|
7
|
-
import { C as je, O as Oe } from "./OAuthErrorPage-
|
|
6
|
+
import { C as Ie, O as re, A as R } from "./errors-D2NINcVk.js";
|
|
7
|
+
import { C as je, O as Oe } from "./OAuthErrorPage-BRXS5AMu.js";
|
|
8
8
|
var J = { exports: {} }, De = J.exports, oe;
|
|
9
9
|
function Je() {
|
|
10
10
|
return oe || (oe = 1, (function(t) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { j as a } from "./jsx-runtime-BzflLqGi.js";
|
|
2
2
|
import { createClient as g } from "@supabase/supabase-js";
|
|
3
|
-
import { C as m, A as h } from "./errors-
|
|
4
|
-
import { S as f } from "./SignUp-
|
|
3
|
+
import { C as m, A as h } from "./errors-D2NINcVk.js";
|
|
4
|
+
import { S as f } from "./SignUp-D3zhMk7q.js";
|
|
5
5
|
import { u } from "./ZudokuContext-CnEI8jPU.js";
|
|
6
6
|
import { Auth as v } from "@supabase/auth-ui-react";
|
|
7
7
|
import { ThemeSupa as S } from "@supabase/auth-ui-shared";
|
|
8
8
|
import { b as T } from "./chunk-EPOLDU6W-C6C8jAwd.js";
|
|
9
|
-
import { H as A } from "./index-
|
|
9
|
+
import { H as A } from "./index-DYfX9H7i.js";
|
|
10
10
|
const c = ({
|
|
11
11
|
client: i,
|
|
12
12
|
config: e,
|
package/lib/zudoku.components.js
CHANGED
|
@@ -7,7 +7,7 @@ import "./ui/Callout.js";
|
|
|
7
7
|
import "./invariant-BJAl77rw.js";
|
|
8
8
|
import "./ClientOnly-E7hGysn1.js";
|
|
9
9
|
import "./ZudokuContext-CnEI8jPU.js";
|
|
10
|
-
import { B as d, y as k, C as l, p as h, n as y, o as S, L as Z, m as E, r as H, S as g, q as w, Z as x, t as A, w as B, x as L, v as M, z as T, a as c } from "./index-
|
|
10
|
+
import { B as d, y as k, C as l, p as h, n as y, o as S, L as Z, m as E, r as H, S as g, q as w, Z as x, t as A, w as B, x as L, v as M, z as T, a as c } from "./index-DYfX9H7i.js";
|
|
11
11
|
import "./Spinner-CI6bRyZw.js";
|
|
12
12
|
export {
|
|
13
13
|
d as Button,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { j as t } from "./jsx-runtime-BzflLqGi.js";
|
|
2
|
-
import { s as f } from "./index-
|
|
2
|
+
import { s as f } from "./index-DTjrb36R.js";
|
|
3
3
|
import { c as b, m as j } from "./chunk-EPOLDU6W-C6C8jAwd.js";
|
|
4
4
|
import { u as x, j as d } from "./ZudokuContext-CnEI8jPU.js";
|
|
5
5
|
import { u as v } from "./useSuspenseQuery-CSB_rVek.js";
|
|
6
6
|
import { H as y } from "./index.esm-B_0dvNjB.js";
|
|
7
|
-
import { H as N, L as k, M as S } from "./index-
|
|
7
|
+
import { H as N, L as k, M as S } from "./index-DYfX9H7i.js";
|
|
8
8
|
const w = ({
|
|
9
9
|
items: o,
|
|
10
10
|
filterCatalogItems: r = (i) => i,
|
|
@@ -3,7 +3,7 @@ import { TrashIcon as me, CircleSlashIcon as z, CheckIcon as xe, XIcon as ye, Pe
|
|
|
3
3
|
import { Z as M, i as E } from "./invariant-BJAl77rw.js";
|
|
4
4
|
import * as F from "react";
|
|
5
5
|
import { createContext as Q, useRef as A, useLayoutEffect as Ce, useEffect as ie, useId as H, useContext as V, useInsertionEffect as we, useMemo as L, useCallback as ke, Children as Ee, isValidElement as Ie, useState as I } from "react";
|
|
6
|
-
import { D as be, c as ee, B as Ke, E as De } from "./index-
|
|
6
|
+
import { D as be, c as ee, B as Ke, E as De } from "./index-DYfX9H7i.js";
|
|
7
7
|
import { b as re } from "./index-Ba6RP577.js";
|
|
8
8
|
import { F as Pe, g as Ae, j as Se, h as Re, d as Ne, I as Oe, a as Te, b as qe, k as Me, c as Fe } from "./Frame-DKlOmSkU.js";
|
|
9
9
|
import { A as D, a as P, b as ae } from "./Mermaid-DEztDKFw.js";
|
|
@@ -4,7 +4,7 @@ const p = (t) => ({
|
|
|
4
4
|
([e, a]) => ({
|
|
5
5
|
path: e,
|
|
6
6
|
lazy: async () => {
|
|
7
|
-
const { MdxPage: n } = await import("./MdxPage-
|
|
7
|
+
const { MdxPage: n } = await import("./MdxPage-Cr99RARi.js"), { default: o, ...s } = await a();
|
|
8
8
|
return {
|
|
9
9
|
element: /* @__PURE__ */ r.jsx(
|
|
10
10
|
n,
|
|
@@ -3,7 +3,7 @@ import "lucide-react";
|
|
|
3
3
|
import "./chunk-EPOLDU6W-C6C8jAwd.js";
|
|
4
4
|
import "./ui/Button.js";
|
|
5
5
|
import "./ZudokuContext-CnEI8jPU.js";
|
|
6
|
-
import { y as e, U as n, z as s } from "./index-
|
|
6
|
+
import { y as e, U as n, z as s } from "./index-BfTLawvZ.js";
|
|
7
7
|
export {
|
|
8
8
|
e as GetNavigationOperationsQuery,
|
|
9
9
|
n as UNTAGGED_PATH,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugins.js","sources":["../src/lib/core/plugins.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport type { Location, RouteObject } from \"react-router\";\nimport type { Navigation } from \"../../config/validators/NavigationSchema.js\";\nimport type { ProtectedRoutesInput } from \"../../config/validators/ProtectedRoutesSchema.js\";\nimport type { ZudokuConfig } from \"../../config/validators/validate.js\";\nimport type { AuthenticationPlugin } from \"../authentication/authentication.js\";\nimport type { MdxComponentsType } from \"../util/MdxComponents.js\";\nimport type {\n ApiIdentity,\n ZudokuContext,\n ZudokuEvents,\n} from \"./ZudokuContext.js\";\n\nexport type ZudokuPlugin =\n | CommonPlugin\n | ProfileMenuPlugin\n | NavigationPlugin\n | ApiIdentityPlugin\n | SearchProviderPlugin\n | EventConsumerPlugin\n | AuthenticationPlugin\n | TransformConfigPlugin;\n\nexport type { AuthenticationPlugin, RouteObject };\n\nexport interface NavigationPlugin {\n getRoutes: () => RouteObject[];\n getNavigation?: (path: string, context: ZudokuContext) => Promise<Navigation>;\n getProtectedRoutes?: () => ProtectedRoutesInput;\n}\n\nexport const createApiIdentityPlugin = (\n plugin: ApiIdentityPlugin,\n): ApiIdentityPlugin => plugin;\n\nexport const createProfileMenuPlugin = (\n plugin: ProfileMenuPlugin,\n): ProfileMenuPlugin => plugin;\n\nexport interface ApiIdentityPlugin {\n getIdentities: (context: ZudokuContext) => Promise<ApiIdentity[]>;\n}\n\nexport interface SearchProviderPlugin {\n renderSearch: (o: {\n isOpen: boolean;\n onClose: () => void;\n }) => React.JSX.Element | null;\n}\n\nexport interface ProfileMenuPlugin {\n getProfileMenuItems: (context: ZudokuContext) => ProfileNavigationItem[];\n}\n\nexport type ProfileNavigationItem = {\n label: string;\n path?: string;\n weight?: number;\n category?: \"top\" | \"middle\" | \"bottom\";\n children?: ProfileNavigationItem[];\n icon?: LucideIcon;\n};\n\nexport interface ConfigHookContext {\n mode: typeof process.env.ZUDOKU_ENV;\n rootDir: string;\n configPath: string;\n}\n\nexport interface TransformConfigPlugin {\n transformConfig?: (\n
|
|
1
|
+
{"version":3,"file":"zudoku.plugins.js","sources":["../src/lib/core/plugins.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport type { Location, RouteObject } from \"react-router\";\nimport type { Navigation } from \"../../config/validators/NavigationSchema.js\";\nimport type { ProtectedRoutesInput } from \"../../config/validators/ProtectedRoutesSchema.js\";\nimport type { ZudokuConfig } from \"../../config/validators/validate.js\";\nimport type { AuthenticationPlugin } from \"../authentication/authentication.js\";\nimport type { MdxComponentsType } from \"../util/MdxComponents.js\";\nimport type {\n ApiIdentity,\n ZudokuContext,\n ZudokuEvents,\n} from \"./ZudokuContext.js\";\n\nexport type ZudokuPlugin =\n | CommonPlugin\n | ProfileMenuPlugin\n | NavigationPlugin\n | ApiIdentityPlugin\n | SearchProviderPlugin\n | EventConsumerPlugin\n | AuthenticationPlugin\n | TransformConfigPlugin;\n\nexport type { AuthenticationPlugin, RouteObject };\n\nexport interface NavigationPlugin {\n getRoutes: () => RouteObject[];\n getNavigation?: (path: string, context: ZudokuContext) => Promise<Navigation>;\n getProtectedRoutes?: () => ProtectedRoutesInput;\n}\n\nexport const createApiIdentityPlugin = (\n plugin: ApiIdentityPlugin,\n): ApiIdentityPlugin => plugin;\n\nexport const createProfileMenuPlugin = (\n plugin: ProfileMenuPlugin,\n): ProfileMenuPlugin => plugin;\n\nexport interface ApiIdentityPlugin {\n getIdentities: (context: ZudokuContext) => Promise<ApiIdentity[]>;\n}\n\nexport interface SearchProviderPlugin {\n renderSearch: (o: {\n isOpen: boolean;\n onClose: () => void;\n }) => React.JSX.Element | null;\n}\n\nexport interface ProfileMenuPlugin {\n getProfileMenuItems: (context: ZudokuContext) => ProfileNavigationItem[];\n}\n\nexport type ProfileNavigationItem = {\n label: string;\n path?: string;\n weight?: number;\n category?: \"top\" | \"middle\" | \"bottom\";\n children?: ProfileNavigationItem[];\n icon?: LucideIcon;\n};\n\nexport interface ConfigHookContext {\n mode: typeof process.env.ZUDOKU_ENV;\n rootDir: string;\n configPath: string;\n}\n\nexport interface TransformConfigContext {\n config: ZudokuConfig;\n merge: <T extends Partial<ZudokuConfig>>(partial: T) => ZudokuConfig & T;\n}\n\nexport interface TransformConfigPlugin {\n transformConfig?: (\n context: TransformConfigContext,\n ) => ZudokuConfig | void | Promise<ZudokuConfig | void>;\n}\n\nexport interface CommonPlugin {\n initialize?: (\n context: ZudokuContext,\n ) => Promise<void | boolean> | void | boolean;\n getHead?: (args: { location: Location }) => ReactNode | undefined;\n getMdxComponents?: () => MdxComponentsType;\n}\n\nexport type EventConsumerPlugin<Event extends ZudokuEvents = ZudokuEvents> = {\n events: { [K in keyof Event]?: Event[K] };\n};\n\nexport const isEventConsumerPlugin = (\n obj: ZudokuPlugin,\n): obj is EventConsumerPlugin =>\n \"events\" in obj && typeof obj.events === \"object\";\n\nexport const isProfileMenuPlugin = (\n obj: ZudokuPlugin,\n): obj is ProfileMenuPlugin =>\n \"getProfileMenuItems\" in obj && typeof obj.getProfileMenuItems === \"function\";\n\nexport const isNavigationPlugin = (\n obj: ZudokuPlugin,\n): obj is NavigationPlugin =>\n \"getRoutes\" in obj && typeof obj.getRoutes === \"function\";\n\nexport const isAuthenticationPlugin = (\n obj: ZudokuPlugin,\n): obj is AuthenticationPlugin =>\n \"signUp\" in obj && typeof obj.signUp === \"function\";\n\nexport const isSearchPlugin = (\n obj: ZudokuPlugin,\n): obj is SearchProviderPlugin =>\n \"renderSearch\" in obj && typeof obj.renderSearch === \"function\";\n\nexport const needsInitialization = (obj: ZudokuPlugin): obj is CommonPlugin =>\n \"initialize\" in obj && typeof obj.initialize === \"function\";\n\nexport const hasHead = (obj: ZudokuPlugin): obj is CommonPlugin =>\n \"getHead\" in obj && typeof obj.getHead === \"function\";\n\nexport const isMdxProviderPlugin = (obj: ZudokuPlugin): obj is CommonPlugin =>\n \"getMdxComponents\" in obj && typeof obj.getMdxComponents === \"function\";\n\nexport const isApiIdentityPlugin = (\n obj: ZudokuPlugin,\n): obj is ApiIdentityPlugin =>\n \"getIdentities\" in obj && typeof obj.getIdentities === \"function\";\n\nexport const isTransformConfigPlugin = (\n obj: ZudokuPlugin,\n): obj is TransformConfigPlugin =>\n \"transformConfig\" in obj && typeof obj.transformConfig === \"function\";\n"],"names":["createApiIdentityPlugin","plugin","createProfileMenuPlugin","isEventConsumerPlugin","obj","isProfileMenuPlugin","isNavigationPlugin","isAuthenticationPlugin","isSearchPlugin","needsInitialization","hasHead","isMdxProviderPlugin","isApiIdentityPlugin","isTransformConfigPlugin"],"mappings":"AAgCO,MAAMA,IAA0B,CACrCC,MACsBA,GAEXC,IAA0B,CACrCD,MACsBA,GAuDXE,IAAwB,CACnCC,MAEA,YAAYA,KAAO,OAAOA,EAAI,UAAW,UAE9BC,IAAsB,CACjCD,MAEA,yBAAyBA,KAAO,OAAOA,EAAI,uBAAwB,YAExDE,IAAqB,CAChCF,MAEA,eAAeA,KAAO,OAAOA,EAAI,aAAc,YAEpCG,IAAyB,CACpCH,MAEA,YAAYA,KAAO,OAAOA,EAAI,UAAW,YAE9BI,IAAiB,CAC5BJ,MAEA,kBAAkBA,KAAO,OAAOA,EAAI,gBAAiB,YAE1CK,IAAsB,CAACL,MAClC,gBAAgBA,KAAO,OAAOA,EAAI,cAAe,YAEtCM,IAAU,CAACN,MACtB,aAAaA,KAAO,OAAOA,EAAI,WAAY,YAEhCO,IAAsB,CAACP,MAClC,sBAAsBA,KAAO,OAAOA,EAAI,oBAAqB,YAElDQ,IAAsB,CACjCR,MAEA,mBAAmBA,KAAO,OAAOA,EAAI,iBAAkB,YAE5CS,IAA0B,CACrCT,MAEA,qBAAqBA,KAAO,OAAOA,EAAI,mBAAoB;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.0.0-monetization-standalone.
|
|
3
|
+
"version": "0.0.0-monetization-standalone.zada7f04c",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -154,7 +154,6 @@
|
|
|
154
154
|
"dependencies": {
|
|
155
155
|
"@apidevtools/json-schema-ref-parser": "14.1.1",
|
|
156
156
|
"@envelop/core": "5.3.2",
|
|
157
|
-
"@fastify/deepmerge": "3.1.0",
|
|
158
157
|
"@graphql-typed-document-node/core": "3.2.0",
|
|
159
158
|
"@lekoarts/rehype-meta-as-attributes": "3.0.3",
|
|
160
159
|
"@mdx-js/react": "3.1.1",
|
package/src/app/main.tsx
CHANGED
|
@@ -111,7 +111,7 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
|
|
|
111
111
|
return [
|
|
112
112
|
{
|
|
113
113
|
element: (
|
|
114
|
-
<Zudoku {...options}>
|
|
114
|
+
<Zudoku {...options} env={import.meta.env}>
|
|
115
115
|
<BuildCheck
|
|
116
116
|
buildId={import.meta.env.ZUPLO_BUILD_ID}
|
|
117
117
|
environmentType={import.meta.env.ZUPLO_ENVIRONMENT_TYPE}
|
|
@@ -20,7 +20,7 @@ import { Slot } from "./Slot.js";
|
|
|
20
20
|
|
|
21
21
|
const createWrapper = (slots: Record<string, ReactNode> = {}) => {
|
|
22
22
|
const queryClient = new QueryClient();
|
|
23
|
-
const context = new ZudokuContext({}, queryClient);
|
|
23
|
+
const context = new ZudokuContext({}, queryClient, {});
|
|
24
24
|
|
|
25
25
|
const wrapper = ({ children }: PropsWithChildren) => (
|
|
26
26
|
<MemoryRouter initialEntries={["/", "/page"]}>
|
|
@@ -32,7 +32,13 @@ import { ZudokuProvider } from "./context/ZudokuProvider.js";
|
|
|
32
32
|
let zudokuContext: ZudokuContext | undefined;
|
|
33
33
|
|
|
34
34
|
const ZudokuInner = memo(
|
|
35
|
-
({
|
|
35
|
+
({
|
|
36
|
+
children,
|
|
37
|
+
env,
|
|
38
|
+
...props
|
|
39
|
+
}: PropsWithChildren<
|
|
40
|
+
ZudokuContextOptions & { env: Record<string, string> }
|
|
41
|
+
>) => {
|
|
36
42
|
const components = useMemo(
|
|
37
43
|
() => ({ ...DEFAULT_COMPONENTS, ...props.overrides }),
|
|
38
44
|
[props.overrides],
|
|
@@ -66,7 +72,7 @@ const ZudokuInner = memo(
|
|
|
66
72
|
setDidNavigate(true);
|
|
67
73
|
}, [didNavigate, navigation.location]);
|
|
68
74
|
|
|
69
|
-
zudokuContext ??= new ZudokuContext(props, queryClient);
|
|
75
|
+
zudokuContext ??= new ZudokuContext(props, queryClient, env);
|
|
70
76
|
|
|
71
77
|
const heads = props.plugins?.flatMap((plugin) =>
|
|
72
78
|
hasHead(plugin) ? (plugin.getHead?.({ location }) ?? []) : [],
|
|
@@ -98,7 +104,11 @@ const ZudokuInner = memo(
|
|
|
98
104
|
|
|
99
105
|
ZudokuInner.displayName = "ZudokuInner";
|
|
100
106
|
|
|
101
|
-
const Zudoku = (
|
|
107
|
+
const Zudoku = (
|
|
108
|
+
props: PropsWithChildren<
|
|
109
|
+
ZudokuContextOptions & { env: Record<string, string> }
|
|
110
|
+
>,
|
|
111
|
+
) => {
|
|
102
112
|
return (
|
|
103
113
|
<ErrorBoundary FallbackComponent={TopLevelError}>
|
|
104
114
|
<ZudokuInner {...props} />
|
|
@@ -132,10 +132,15 @@ export class ZudokuContext {
|
|
|
132
132
|
public readonly getAuthState: () => AuthState;
|
|
133
133
|
public readonly queryClient: QueryClient;
|
|
134
134
|
public readonly options: ZudokuContextOptions;
|
|
135
|
+
public readonly env: Record<string, string | undefined>;
|
|
135
136
|
private readonly navigationPlugins: NavigationPlugin[];
|
|
136
137
|
private emitter = createNanoEvents<ZudokuEvents>();
|
|
137
138
|
|
|
138
|
-
constructor(
|
|
139
|
+
constructor(
|
|
140
|
+
options: ZudokuContextOptions,
|
|
141
|
+
queryClient: QueryClient,
|
|
142
|
+
env: Record<string, string | undefined>,
|
|
143
|
+
) {
|
|
139
144
|
const pluginProtectedRoutes = Object.fromEntries(
|
|
140
145
|
(options.plugins ?? []).flatMap((plugin) => {
|
|
141
146
|
if (!isNavigationPlugin(plugin)) return [];
|
|
@@ -152,6 +157,7 @@ export class ZudokuContext {
|
|
|
152
157
|
};
|
|
153
158
|
|
|
154
159
|
this.queryClient = queryClient;
|
|
160
|
+
this.env = env;
|
|
155
161
|
this.options = { ...options, protectedRoutes };
|
|
156
162
|
this.plugins = options.plugins ?? [];
|
|
157
163
|
this.navigation = options.navigation ?? [];
|
|
@@ -17,6 +17,7 @@ import { StatusPage as StatusPageImport } from "../components/StatusPage.js";
|
|
|
17
17
|
import { RouterError as RouterErrorImport } from "../errors/RouterError.js";
|
|
18
18
|
import { ServerError as ServerErrorImport } from "../errors/ServerError.js";
|
|
19
19
|
import { RouteGuard as RouteGuardImport } from "./RouteGuard.js";
|
|
20
|
+
import { runPluginTransformConfig as runPluginTransformConfigImport } from "./transform-config.js";
|
|
20
21
|
|
|
21
22
|
export const Layout = LayoutImport;
|
|
22
23
|
export const RouterError = RouterErrorImport;
|
|
@@ -28,3 +29,4 @@ export const Head = Helmet;
|
|
|
28
29
|
export const StatusPage = StatusPageImport;
|
|
29
30
|
export const BuildCheck = BuildCheckImport;
|
|
30
31
|
export const Meta = MetaImport;
|
|
32
|
+
export const runPluginTransformConfig = runPluginTransformConfigImport;
|
package/src/lib/core/plugins.ts
CHANGED
|
@@ -68,11 +68,15 @@ export interface ConfigHookContext {
|
|
|
68
68
|
configPath: string;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
export interface TransformConfigContext {
|
|
72
|
+
config: ZudokuConfig;
|
|
73
|
+
merge: <T extends Partial<ZudokuConfig>>(partial: T) => ZudokuConfig & T;
|
|
74
|
+
}
|
|
75
|
+
|
|
71
76
|
export interface TransformConfigPlugin {
|
|
72
77
|
transformConfig?: (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
) => Partial<ZudokuConfig> | void | Promise<Partial<ZudokuConfig> | void>;
|
|
78
|
+
context: TransformConfigContext,
|
|
79
|
+
) => ZudokuConfig | void | Promise<ZudokuConfig | void>;
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
export interface CommonPlugin {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { isPlainObject, mergeConfig } from "./transform-config.js";
|
|
3
|
+
|
|
4
|
+
describe("isPlainObject", () => {
|
|
5
|
+
test("returns true for plain objects", () => {
|
|
6
|
+
expect(isPlainObject({})).toBe(true);
|
|
7
|
+
expect(isPlainObject({ a: 1 })).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test("returns false for arrays", () => {
|
|
11
|
+
expect(isPlainObject([])).toBe(false);
|
|
12
|
+
expect(isPlainObject([1, 2, 3])).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("returns false for null and undefined", () => {
|
|
16
|
+
expect(isPlainObject(null)).toBe(false);
|
|
17
|
+
expect(isPlainObject(undefined)).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("returns false for class instances", () => {
|
|
21
|
+
expect(isPlainObject(new Date())).toBe(false);
|
|
22
|
+
expect(isPlainObject(new Map())).toBe(false);
|
|
23
|
+
expect(isPlainObject(/regex/)).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("mergeConfig", () => {
|
|
28
|
+
test("merges flat objects", () => {
|
|
29
|
+
const target = { a: 1, b: 2 };
|
|
30
|
+
const source = { b: 3, c: 4 };
|
|
31
|
+
expect(mergeConfig(target, source)).toEqual({ a: 1, b: 3, c: 4 });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("merges nested objects", () => {
|
|
35
|
+
const target = { nested: { a: 1, b: 2 } } as Record<string, unknown>;
|
|
36
|
+
const source = { nested: { b: 3, c: 4 } };
|
|
37
|
+
expect(mergeConfig(target, source)).toEqual({
|
|
38
|
+
nested: { a: 1, b: 3, c: 4 },
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("replaces arrays instead of merging", () => {
|
|
43
|
+
const target = { arr: [1, 2, 3] };
|
|
44
|
+
const source = { arr: [4, 5] };
|
|
45
|
+
expect(mergeConfig(target, source)).toEqual({ arr: [4, 5] });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("preserves React elements without deep cloning", () => {
|
|
49
|
+
const element = <div className="test">Hello</div>;
|
|
50
|
+
const target = { banner: { message: "old" } };
|
|
51
|
+
const source = { banner: { message: element } };
|
|
52
|
+
|
|
53
|
+
const result = mergeConfig(target, source);
|
|
54
|
+
|
|
55
|
+
// Should be the exact same reference, not a clone
|
|
56
|
+
expect(result.banner.message).toBe(element);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("does not clone React element children", () => {
|
|
60
|
+
const child = <strong>Bold</strong>;
|
|
61
|
+
const element = <div>{child} text</div>;
|
|
62
|
+
const target = { site: { banner: {} } };
|
|
63
|
+
const source = { site: { banner: { message: element } } };
|
|
64
|
+
|
|
65
|
+
const result = mergeConfig(target, source);
|
|
66
|
+
|
|
67
|
+
// The element should be identical (same reference)
|
|
68
|
+
expect(result.site.banner.message).toBe(element);
|
|
69
|
+
// Children should be preserved exactly
|
|
70
|
+
expect(result.site.banner.message.props.children).toBe(
|
|
71
|
+
element.props.children,
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("handles null and undefined values", () => {
|
|
76
|
+
const target = { a: 1, b: 2 };
|
|
77
|
+
const source = { a: null, c: undefined };
|
|
78
|
+
expect(mergeConfig(target, source)).toEqual({
|
|
79
|
+
a: null,
|
|
80
|
+
b: 2,
|
|
81
|
+
c: undefined,
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("replaces non-plain objects", () => {
|
|
86
|
+
const date = new Date("2024-01-01");
|
|
87
|
+
const target = { date: new Date("2020-01-01") };
|
|
88
|
+
const source = { date };
|
|
89
|
+
const result = mergeConfig(target, source);
|
|
90
|
+
expect(result.date).toBe(date);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("does not mutate target", () => {
|
|
94
|
+
const target = { a: 1, nested: { b: 2 } };
|
|
95
|
+
const source = { a: 2, nested: { c: 3 } };
|
|
96
|
+
mergeConfig(target, source);
|
|
97
|
+
expect(target).toEqual({ a: 1, nested: { b: 2 } });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -1,28 +1,66 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
2
|
import type { ConfigWithMeta } from "../../config/loader.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isTransformConfigPlugin } from "./plugins.js";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export const isPlainObject = (
|
|
6
|
+
value: unknown,
|
|
7
|
+
): value is Record<string, unknown> =>
|
|
8
|
+
typeof value === "object" &&
|
|
9
|
+
value !== null &&
|
|
10
|
+
!Array.isArray(value) &&
|
|
11
|
+
Object.getPrototypeOf(value) === Object.prototype;
|
|
8
12
|
|
|
9
|
-
export const
|
|
13
|
+
export const mergeConfig = <
|
|
14
|
+
T extends Record<string, unknown>,
|
|
15
|
+
S extends Record<string, unknown>,
|
|
16
|
+
>(
|
|
17
|
+
target: T,
|
|
18
|
+
source: S,
|
|
19
|
+
): T & S => {
|
|
20
|
+
const result = { ...target } as T & S;
|
|
21
|
+
|
|
22
|
+
for (const key of Object.keys(source) as (keyof S)[]) {
|
|
23
|
+
const sourceValue = source[key];
|
|
24
|
+
const targetValue = target[key as keyof T];
|
|
25
|
+
|
|
26
|
+
// Don't merge React elements, arrays, or non-plain objects - just replace
|
|
27
|
+
if (
|
|
28
|
+
isValidElement(sourceValue) ||
|
|
29
|
+
Array.isArray(sourceValue) ||
|
|
30
|
+
!isPlainObject(sourceValue)
|
|
31
|
+
) {
|
|
32
|
+
(result as Record<string, unknown>)[key as string] = sourceValue;
|
|
33
|
+
} else if (isPlainObject(targetValue)) {
|
|
34
|
+
(result as Record<string, unknown>)[key as string] = mergeConfig(
|
|
35
|
+
targetValue,
|
|
36
|
+
sourceValue,
|
|
37
|
+
);
|
|
38
|
+
} else {
|
|
39
|
+
(result as Record<string, unknown>)[key as string] = sourceValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const runPluginTransformConfig = async (
|
|
10
47
|
config: ConfigWithMeta,
|
|
11
48
|
): Promise<ConfigWithMeta> => {
|
|
12
|
-
const ctx = {
|
|
13
|
-
mode: config.__meta.mode,
|
|
14
|
-
rootDir: config.__meta.rootDir,
|
|
15
|
-
configPath: config.__meta.configPath,
|
|
16
|
-
} satisfies ConfigHookContext;
|
|
17
49
|
const plugins = config.plugins ?? [];
|
|
18
50
|
|
|
19
51
|
let result = config;
|
|
20
52
|
|
|
21
53
|
for (const plugin of plugins.filter(isTransformConfigPlugin)) {
|
|
22
|
-
const
|
|
23
|
-
|
|
54
|
+
const merge = <T extends Record<string, unknown>>(partial: T) =>
|
|
55
|
+
mergeConfig(result, partial);
|
|
56
|
+
|
|
57
|
+
const transformed = await plugin.transformConfig?.({
|
|
58
|
+
config: result,
|
|
59
|
+
merge,
|
|
60
|
+
});
|
|
61
|
+
if (!transformed) continue;
|
|
24
62
|
|
|
25
|
-
result =
|
|
63
|
+
result = transformed as ConfigWithMeta;
|
|
26
64
|
}
|
|
27
65
|
|
|
28
66
|
return result;
|
|
@@ -13,7 +13,7 @@ import { useEvent } from "./useEvent.js";
|
|
|
13
13
|
|
|
14
14
|
const createTestContext = () => {
|
|
15
15
|
const queryClient = new QueryClient();
|
|
16
|
-
const context = new ZudokuContext({}, queryClient);
|
|
16
|
+
const context = new ZudokuContext({}, queryClient, {});
|
|
17
17
|
const wrapper = ({ children }: PropsWithChildren) => (
|
|
18
18
|
<QueryClientProvider client={queryClient}>
|
|
19
19
|
<ZudokuProvider context={context}>{children}</ZudokuProvider>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm-DFzsB75P.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|