@carlonicora/nextjs-jsonapi 6.12.2 → 6.13.1
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/{ApiData-DPKNfY-9.d.mts → ApiData-Be8yxCOX.d.mts} +2 -0
- package/dist/{ApiData-DPKNfY-9.d.ts → ApiData-Be8yxCOX.d.ts} +2 -0
- package/dist/{BlockNoteEditor-7M5QW2YQ.js → BlockNoteEditor-UBVEUFNR.js} +34 -22
- package/dist/BlockNoteEditor-UBVEUFNR.js.map +1 -0
- package/dist/{BlockNoteEditor-75ED2CN2.mjs → BlockNoteEditor-VXMDSQAA.mjs} +20 -8
- package/dist/BlockNoteEditor-VXMDSQAA.mjs.map +1 -0
- package/dist/{BlockNoteViewer-WGCDB7IJ.js → BlockNoteViewer-2XYASA5Y.js} +8 -5
- package/dist/BlockNoteViewer-2XYASA5Y.js.map +1 -0
- package/dist/{BlockNoteViewer-MTGS6YJV.mjs → BlockNoteViewer-NBW2H6LC.mjs} +7 -4
- package/dist/{BlockNoteViewer-MTGS6YJV.mjs.map → BlockNoteViewer-NBW2H6LC.mjs.map} +1 -1
- package/dist/{JsonApiRequest-A66XK5WT.mjs → JsonApiRequest-F6TMJ42G.mjs} +2 -2
- package/dist/JsonApiRequest-WISJZSDE.js +26 -0
- package/dist/{JsonApiRequest-FZGPLNUF.js.map → JsonApiRequest-WISJZSDE.js.map} +1 -1
- package/dist/billing/index.js +499 -494
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +13 -8
- package/dist/billing/index.mjs.map +1 -1
- package/dist/chunk-27LQDGNP.mjs +317 -0
- package/dist/chunk-27LQDGNP.mjs.map +1 -0
- package/dist/{chunk-KSYQEKJX.js → chunk-2SV4SS6N.js} +14 -14
- package/dist/{chunk-KSYQEKJX.js.map → chunk-2SV4SS6N.js.map} +1 -1
- package/dist/{chunk-4FNGWALA.mjs → chunk-47BBY5KA.mjs} +6 -4
- package/dist/{chunk-4FNGWALA.mjs.map → chunk-47BBY5KA.mjs.map} +1 -1
- package/dist/chunk-6JUCIWDC.mjs +570 -0
- package/dist/chunk-6JUCIWDC.mjs.map +1 -0
- package/dist/chunk-7DBJTNSU.mjs +1049 -0
- package/dist/chunk-7DBJTNSU.mjs.map +1 -0
- package/dist/chunk-7JZHPMGW.mjs +704 -0
- package/dist/chunk-7JZHPMGW.mjs.map +1 -0
- package/dist/{chunk-L6PYFQTO.js → chunk-7ZHTPFFT.js} +16 -14
- package/dist/chunk-7ZHTPFFT.js.map +1 -0
- package/dist/chunk-B6JGKDP2.js +214 -0
- package/dist/chunk-B6JGKDP2.js.map +1 -0
- package/dist/{chunk-3YW35YHQ.mjs → chunk-BH6JWIKI.mjs} +5 -5
- package/dist/chunk-BZ5J2FIV.js +570 -0
- package/dist/chunk-BZ5J2FIV.js.map +1 -0
- package/dist/{chunk-V5MI7RNB.mjs → chunk-DGWOVYEC.mjs} +2 -2
- package/dist/chunk-DOCIFE6A.mjs +212 -0
- package/dist/chunk-DOCIFE6A.mjs.map +1 -0
- package/dist/chunk-GB6DBFYY.js +25 -0
- package/dist/chunk-GB6DBFYY.js.map +1 -0
- package/dist/{chunk-EWCY6QJA.mjs → chunk-JJMMT24D.mjs} +37 -3
- package/dist/chunk-JJMMT24D.mjs.map +1 -0
- package/dist/{chunk-JTPRJNT2.js → chunk-KMW7UNL2.js} +38 -3
- package/dist/chunk-KMW7UNL2.js.map +1 -0
- package/dist/chunk-MHB36MYE.js +317 -0
- package/dist/chunk-MHB36MYE.js.map +1 -0
- package/dist/{chunk-FF4EIQ6H.js → chunk-MOGEGWXW.js} +1039 -1680
- package/dist/chunk-MOGEGWXW.js.map +1 -0
- package/dist/{chunk-RXQYEEKZ.mjs → chunk-N4RZZKL5.mjs} +58 -25
- package/dist/chunk-N4RZZKL5.mjs.map +1 -0
- package/dist/{chunk-AA52ORW2.mjs → chunk-P445QGOC.mjs} +61 -702
- package/dist/chunk-P445QGOC.mjs.map +1 -0
- package/dist/chunk-PV4Z5W6V.js +212 -0
- package/dist/chunk-PV4Z5W6V.js.map +1 -0
- package/dist/chunk-PXDUJ47N.js +1049 -0
- package/dist/chunk-PXDUJ47N.js.map +1 -0
- package/dist/{chunk-V3YDVJ63.js → chunk-PYRZCKC2.js} +1209 -1176
- package/dist/chunk-PYRZCKC2.js.map +1 -0
- package/dist/{chunk-GHE4VT2R.js → chunk-QKNGZDSQ.js} +2 -2
- package/dist/{chunk-GHE4VT2R.js.map → chunk-QKNGZDSQ.js.map} +1 -1
- package/dist/chunk-W62MHDWM.js +704 -0
- package/dist/chunk-W62MHDWM.js.map +1 -0
- package/dist/chunk-XXP3TQHF.mjs +25 -0
- package/dist/chunk-XXP3TQHF.mjs.map +1 -0
- package/dist/chunk-YRKIFYOE.mjs +214 -0
- package/dist/chunk-YRKIFYOE.mjs.map +1 -0
- package/dist/{chunk-O3PDL2CV.js → chunk-Z4POQWFG.js} +40 -6
- package/dist/chunk-Z4POQWFG.js.map +1 -0
- package/dist/{chunk-PI56A4DG.mjs → chunk-ZLTOUZN2.mjs} +37 -2
- package/dist/chunk-ZLTOUZN2.mjs.map +1 -0
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +14 -9
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +24 -19
- package/dist/components/index.d.mts +7 -1
- package/dist/components/index.d.ts +7 -1
- package/dist/components/index.js +11 -7
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +10 -6
- package/dist/contexts/index.d.mts +1 -1
- package/dist/contexts/index.d.ts +1 -1
- package/dist/contexts/index.js +11 -7
- package/dist/contexts/index.js.map +1 -1
- package/dist/contexts/index.mjs +10 -6
- package/dist/core/index.d.mts +128 -2
- package/dist/core/index.d.ts +128 -2
- package/dist/core/index.js +17 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +22 -9
- package/dist/email-automations/index.js +101 -96
- package/dist/email-automations/index.js.map +1 -1
- package/dist/email-automations/index.mjs +13 -8
- package/dist/email-automations/index.mjs.map +1 -1
- package/dist/features/analytics/index.js +128 -123
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/index.mjs +13 -8
- package/dist/features/analytics/index.mjs.map +1 -1
- package/dist/features/analytics/server.js +11 -8
- package/dist/features/analytics/server.js.map +1 -1
- package/dist/features/analytics/server.mjs +9 -6
- package/dist/features/analytics/server.mjs.map +1 -1
- package/dist/features/blog/index.js +158 -153
- package/dist/features/blog/index.js.map +1 -1
- package/dist/features/blog/index.mjs +14 -9
- package/dist/features/blog/index.mjs.map +1 -1
- package/dist/features/blog/server.js +30 -26
- package/dist/features/blog/server.js.map +1 -1
- package/dist/features/blog/server.mjs +10 -6
- package/dist/features/blog/server.mjs.map +1 -1
- package/dist/features/help/index.js +44 -40
- package/dist/features/help/index.js.map +1 -1
- package/dist/features/help/index.mjs +10 -6
- package/dist/features/help/index.mjs.map +1 -1
- package/dist/features/tokenusage/index.js +134 -129
- package/dist/features/tokenusage/index.js.map +1 -1
- package/dist/features/tokenusage/index.mjs +13 -8
- package/dist/features/tokenusage/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +18 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -11
- package/dist/lifecycle-4GUOTB46.js +23 -0
- package/dist/lifecycle-4GUOTB46.js.map +1 -0
- package/dist/lifecycle-LKGPRBS7.mjs +23 -0
- package/dist/local-transport-7H3SPZSA.js +15 -0
- package/dist/local-transport-7H3SPZSA.js.map +1 -0
- package/dist/local-transport-QYFKA6AN.mjs +15 -0
- package/dist/local-transport-QYFKA6AN.mjs.map +1 -0
- package/dist/offline/index.d.mts +607 -0
- package/dist/offline/index.d.ts +607 -0
- package/dist/offline/index.js +1052 -0
- package/dist/offline/index.js.map +1 -0
- package/dist/offline/index.mjs +1052 -0
- package/dist/offline/index.mjs.map +1 -0
- package/dist/offline/sqlite/device-worker.mjs +62 -0
- package/dist/offline/sqlite/index.mjs +17392 -0
- package/dist/offline/sqlite/sqlite3-opfs-async-proxy.js +881 -0
- package/dist/offline/sqlite/sqlite3.wasm +0 -0
- package/dist/request-KTBV6HHH.js +10 -0
- package/dist/request-KTBV6HHH.js.map +1 -0
- package/dist/request-SQOUNWZ4.mjs +10 -0
- package/dist/request-SQOUNWZ4.mjs.map +1 -0
- package/dist/server/cachedGet.d.mts +1 -1
- package/dist/server/cachedGet.d.ts +1 -1
- package/dist/server/cachedGet.stub.d.mts +1 -1
- package/dist/server/cachedGet.stub.d.ts +1 -1
- package/dist/server/index.d.mts +28 -2
- package/dist/server/index.d.ts +28 -2
- package/dist/server/index.js +18 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +18 -8
- package/dist/{useSocket-IRHtk2xc.d.ts → useSocket-Bo9M0t0J.d.ts} +3 -1
- package/dist/{useSocket-C8fqU4od.d.mts → useSocket-J5qanQPN.d.mts} +3 -1
- package/dist/write-through-FDQ7N4YI.js +15 -0
- package/dist/write-through-FDQ7N4YI.js.map +1 -0
- package/dist/write-through-R25VQMH6.mjs +15 -0
- package/dist/write-through-R25VQMH6.mjs.map +1 -0
- package/package.json +7 -1
- package/pwa/sw.js +277 -26
- package/src/client/request.ts +37 -0
- package/src/components/editors/BlockNoteEditor.tsx +14 -0
- package/src/components/editors/__tests__/BlockNoteEditor.empty-change.spec.tsx +205 -0
- package/src/contexts/SocketContext.tsx +7 -1
- package/src/contexts/__tests__/SocketContext.session.spec.tsx +52 -5
- package/src/core/factories/RehydrationFactory.ts +28 -8
- package/src/core/factories/__tests__/RehydrationFactory.spec.ts +33 -0
- package/src/core/index.ts +3 -0
- package/src/core/interfaces/ApiData.ts +2 -0
- package/src/core/registry/ModuleRegistry.ts +3 -0
- package/src/features/auth/components/forms/Logout.tsx +8 -1
- package/src/features/auth/components/forms/__tests__/Logout.spec.tsx +62 -0
- package/src/features/onboarding/contexts/OnboardingContext.spec.tsx +42 -1
- package/src/features/onboarding/contexts/OnboardingContext.tsx +11 -1
- package/src/hooks/__tests__/useSocket.pause.spec.ts +39 -0
- package/src/hooks/useSocket.ts +20 -1
- package/src/offline/__tests__/answer-builders.spec.ts +176 -0
- package/src/offline/__tests__/device-switch.spec.ts +179 -0
- package/src/offline/__tests__/generic-answers.spec.ts +380 -0
- package/src/offline/__tests__/local-transport.spec.ts +150 -0
- package/src/offline/__tests__/logout.spec.ts +122 -0
- package/src/offline/__tests__/offline-fixtures.ts +89 -0
- package/src/offline/__tests__/router.spec.ts +56 -0
- package/src/offline/__tests__/state.spec.ts +62 -0
- package/src/offline/__tests__/write-through.spec.ts +137 -0
- package/src/offline/config.ts +229 -0
- package/src/offline/configure.ts +14 -0
- package/src/offline/device-switch.ts +75 -0
- package/src/offline/generic-answers.ts +706 -0
- package/src/offline/index.ts +67 -0
- package/src/offline/local-transport.ts +189 -0
- package/src/offline/logout.ts +41 -0
- package/src/offline/router.ts +41 -0
- package/src/offline/server/__tests__/build-offline-manifest.spec.ts +76 -0
- package/src/offline/server/build-offline-manifest.ts +49 -0
- package/src/offline/state-hooks.ts +10 -0
- package/src/offline/state.ts +143 -0
- package/src/offline/store/DeviceStore.ts +112 -0
- package/src/offline/store/__tests__/device-store-lifecycle.spec.ts +343 -0
- package/src/offline/store/__tests__/shared-database.spec.ts +151 -0
- package/src/offline/store/__tests__/sql-device-store.spec.ts +399 -0
- package/src/offline/store/lifecycle.ts +315 -0
- package/src/offline/store/schema.ts +101 -0
- package/src/offline/store/shared-database.ts +321 -0
- package/src/offline/store/sql-device-store.ts +469 -0
- package/src/offline/store/worker-client.ts +71 -0
- package/src/offline/store/worker.ts +87 -0
- package/src/offline/sync/__tests__/conflicts.spec.ts +185 -0
- package/src/offline/sync/__tests__/queue-drain.spec.ts +364 -0
- package/src/offline/sync/__tests__/runtime.spec.ts +337 -0
- package/src/offline/sync/__tests__/sync-fixtures.ts +103 -0
- package/src/offline/sync/__tests__/sync-root.spec.ts +727 -0
- package/src/offline/sync/artwork-cache.ts +67 -0
- package/src/offline/sync/conflicts.ts +211 -0
- package/src/offline/sync/counts.ts +39 -0
- package/src/offline/sync/drain-queue.ts +246 -0
- package/src/offline/sync/known-roots.ts +37 -0
- package/src/offline/sync/models/OfflineChangeSet.ts +34 -0
- package/src/offline/sync/models/OfflineChangeSetInterface.ts +54 -0
- package/src/offline/sync/models/RootSync.ts +68 -0
- package/src/offline/sync/models/RootSyncInterface.ts +20 -0
- package/src/offline/sync/models/__tests__/OfflineChangeSet.spec.ts +47 -0
- package/src/offline/sync/models/__tests__/RootSync.spec.ts +54 -0
- package/src/offline/sync/models/index.ts +5 -0
- package/src/offline/sync/models/offline.modules.ts +14 -0
- package/src/offline/sync/runtime.ts +226 -0
- package/src/offline/sync/session-refresh.ts +32 -0
- package/src/offline/sync/sync-root.ts +336 -0
- package/src/offline/sync/waiting.ts +40 -0
- package/src/offline/types.ts +115 -0
- package/src/offline/write-through.ts +189 -0
- package/src/pwa/__tests__/sw.spec.ts +358 -1
- package/src/server/index.ts +5 -0
- package/src/unified/__tests__/JsonApiRequest.offline.spec.ts +243 -0
- package/dist/BlockNoteEditor-75ED2CN2.mjs.map +0 -1
- package/dist/BlockNoteEditor-7M5QW2YQ.js.map +0 -1
- package/dist/BlockNoteViewer-WGCDB7IJ.js.map +0 -1
- package/dist/JsonApiRequest-FZGPLNUF.js +0 -26
- package/dist/chunk-AA52ORW2.mjs.map +0 -1
- package/dist/chunk-EWCY6QJA.mjs.map +0 -1
- package/dist/chunk-FF4EIQ6H.js.map +0 -1
- package/dist/chunk-JTPRJNT2.js.map +0 -1
- package/dist/chunk-L6PYFQTO.js.map +0 -1
- package/dist/chunk-O3PDL2CV.js.map +0 -1
- package/dist/chunk-PI56A4DG.mjs.map +0 -1
- package/dist/chunk-RXQYEEKZ.mjs.map +0 -1
- package/dist/chunk-V3YDVJ63.js.map +0 -1
- package/dist/request-5RLK2AM3.mjs +0 -9
- package/dist/request-EUGTI3BE.js +0 -9
- package/dist/request-EUGTI3BE.js.map +0 -1
- /package/dist/{JsonApiRequest-A66XK5WT.mjs.map → JsonApiRequest-F6TMJ42G.mjs.map} +0 -0
- /package/dist/{chunk-3YW35YHQ.mjs.map → chunk-BH6JWIKI.mjs.map} +0 -0
- /package/dist/{chunk-V5MI7RNB.mjs.map → chunk-DGWOVYEC.mjs.map} +0 -0
- /package/dist/{request-5RLK2AM3.mjs.map → lifecycle-LKGPRBS7.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/registry/helpStore.ts","../src/client/config.ts","../src/login/config.ts","../src/features/waitlist/config/waitlist.config.ts","../src/features/referral/config.ts","../src/features/signup-source/signup-source.ts","../src/features/rbac/data/RbacTypes.ts","../src/features/rbac/data/RbacService.ts"],"sourcesContent":["/**\n * Centralized help-content store accessible from client and server contexts.\n * Uses a globalThis Symbol key to persist across HMR/Turbopack reloads and to\n * bridge between the client-side `configureJsonApi` (in `client/config.ts`)\n * and the HelpProvider context. Holds the brand-only HelpContentConfig.\n *\n * NO external dependencies to avoid circular imports.\n *\n * Pattern mirrors `bootstrapStore.ts`.\n */\n\nconst HELP_CONTENT_KEY = Symbol.for(\"nextjs-jsonapi:helpContent\");\n\nconst globalStore = globalThis as unknown as {\n [HELP_CONTENT_KEY]?: unknown | null;\n};\n\nif (globalStore[HELP_CONTENT_KEY] === undefined) {\n globalStore[HELP_CONTENT_KEY] = null;\n}\n\nexport function _setStaticHelpContent(cfg: unknown | null): void {\n globalStore[HELP_CONTENT_KEY] = cfg;\n}\n\nexport function _getStaticHelpContent<T = unknown>(): T | null {\n return (globalStore[HELP_CONTENT_KEY] as T | null) ?? null;\n}\n","\"use client\";\n\nimport { ModuleWithPermissions } from \"../permissions/types\";\nimport { ENV } from \"../core/env\";\nimport { setBootstrapper } from \"../core/registry/bootstrapStore\";\nimport { _setStaticHelpContent } from \"../core/registry/helpStore\";\nimport type { HelpContentConfig } from \"../features/help/interfaces/help-content-config.interface\";\n\n// Config storage for client-side contexts\nlet _clientConfig: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n stripePublishableKey?: string;\n} | null = null;\n\n/**\n * Configure the JSON:API client. This is the main configuration function.\n * This is typically called during app initialization.\n * @param config.helpContent - Optional help-content config (brand only). Forwarded to the help feature's globalThis-backed store; not stored on the client config.\n */\nexport function configureJsonApi(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n stripePublishableKey?: string;\n helpContent?: HelpContentConfig;\n}): void {\n const { helpContent, ...rest } = config;\n _clientConfig = rest;\n if (helpContent) {\n _setStaticHelpContent(helpContent);\n }\n // Register and call bootstrapper to register all modules\n if (config.bootstrapper) {\n setBootstrapper(config.bootstrapper);\n config.bootstrapper();\n }\n}\n\n/**\n * Configure the client config. This is typically called during app initialization.\n * @deprecated Use configureJsonApi instead\n */\nexport function configureClientConfig(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n}): void {\n _clientConfig = config;\n}\n\n/**\n * Get the configured API URL.\n *\n * This may resolve to an internal/private host (e.g. a docker-network\n * hostname) when configured to do so for SSR fetches. Do NOT use this for\n * URLs that are rendered into HTML and followed by the browser — use\n * `getPublicApiUrl()` instead.\n */\nexport function getApiUrl(): string {\n if (_clientConfig?.apiUrl) {\n return _clientConfig.apiUrl;\n }\n return ENV.API_URL;\n}\n\n/**\n * Get the public-facing API URL.\n *\n * Always sourced from `NEXT_PUBLIC_API_URL` so it is identical on server\n * and client, and reachable from the user's browser. Use for any URL that\n * gets rendered into HTML the browser will navigate to (links, redirects,\n * OAuth hrefs).\n */\nexport function getPublicApiUrl(): string {\n return ENV.API_URL;\n}\n\n/**\n * Get the configured app URL.\n */\nexport function getAppUrl(): string {\n if (_clientConfig?.appUrl) {\n return _clientConfig.appUrl;\n }\n if (ENV.APP_URL_ALTERNATE) {\n return ENV.APP_URL_ALTERNATE;\n }\n if (typeof window !== \"undefined\") {\n return window.location.origin;\n }\n return \"\";\n}\n\n/**\n * Get the configured trackable pages.\n */\nexport function getTrackablePages(): ModuleWithPermissions[] {\n return _clientConfig?.trackablePages ?? [];\n}\n\n/**\n * Get the configured Stripe publishable key.\n */\nexport function getStripePublishableKey(): string | undefined {\n return _clientConfig?.stripePublishableKey;\n}\n","let _useDiscordAuth: boolean = false;\nlet _useGoogleAuth: boolean = false;\nlet _useInternalAuth: boolean = true;\nlet _allowRegistration: boolean = true;\nlet _registrationMode: \"open\" | \"closed\" | \"waitlist\" = \"open\";\n\nexport type RegistrationMode = \"open\" | \"closed\" | \"waitlist\";\n\nexport interface LoginConfig {\n discordClientId?: string;\n googleClientId?: string;\n useInternalAuth?: boolean;\n allowRegistration?: boolean;\n registrationMode?: RegistrationMode;\n}\n\nexport function configureLogin(params: LoginConfig): void {\n _useDiscordAuth = !!params.discordClientId;\n _useGoogleAuth = !!params.googleClientId;\n _useInternalAuth = params.useInternalAuth ?? true;\n _allowRegistration = params.allowRegistration ?? true;\n _registrationMode = params.registrationMode ?? \"open\";\n}\n\nexport function isDiscordAuthEnabled(): boolean {\n return _useDiscordAuth;\n}\n\nexport function isGoogleAuthEnabled(): boolean {\n return _useGoogleAuth;\n}\n\nexport function isInternalAuthEnabled(): boolean {\n return _useInternalAuth;\n}\n\nexport function isRegistrationAllowed(): boolean {\n return _allowRegistration;\n}\n\nexport function getRegistrationMode(): RegistrationMode {\n return _registrationMode;\n}\n","import { useI18nTranslations } from \"../../../i18n\";\n\nexport type QuestionnaireFieldType = \"text\" | \"textarea\" | \"select\" | \"checkbox\";\n\nexport interface QuestionnaireOption {\n value: string;\n label: string;\n description?: string;\n}\n\nexport interface QuestionnaireField {\n id: string;\n type: QuestionnaireFieldType;\n label: string;\n description?: string;\n placeholder?: string;\n required?: boolean;\n options?: QuestionnaireOption[];\n}\n\nexport interface WaitlistConfig {\n questionnaire?: QuestionnaireField[];\n heroTitle?: string;\n heroSubtitle?: string;\n heroDescription?: string;\n benefits?: string[];\n /**\n * When true, every text above (hero title, subtitle, description, benefits and\n * the questionnaire's labels, descriptions, placeholders and option labels) is\n * a message key and renders through `t()`. Defaults to false: the strings\n * render as given.\n */\n translate?: boolean;\n}\n\nlet _waitlistConfig: WaitlistConfig = {};\n\nexport function configureWaitlist(config: WaitlistConfig): void {\n _waitlistConfig = config;\n}\n\nexport function getWaitlistConfig(): WaitlistConfig {\n return _waitlistConfig;\n}\n\n/**\n * Resolves a waitlist config text: `t(value)` when the config sets\n * `translate`, the value itself otherwise. Empty values stay undefined.\n */\nexport function useWaitlistText(): (value?: string) => string | undefined {\n const t = useI18nTranslations();\n const translate = getWaitlistConfig().translate === true;\n\n return (value?: string) => {\n if (!value) return undefined;\n return translate ? t(value) : value;\n };\n}\n","/**\n * Configuration interface for frontend referral feature.\n */\nexport interface ReferralConfig {\n /**\n * Whether the referral feature is enabled.\n * When false, components render nothing and hooks return null.\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Name of the cookie used to store referral codes.\n * @default \"referral_code\"\n */\n cookieName?: string;\n\n /**\n * Number of days the referral cookie is valid.\n * @default 30\n */\n cookieDays?: number;\n\n /**\n * Query parameter name for referral code in URL.\n * @default \"ref\"\n */\n urlParamName?: string;\n\n /**\n * Base URL for referral links.\n * @default window.location.origin (client-side only)\n */\n referralUrlBase?: string;\n\n /**\n * Path to append to base URL for referral links.\n * @default \"/\"\n */\n referralPath?: string;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_REFERRAL_CONFIG: Required<ReferralConfig> = {\n enabled: false,\n cookieName: \"referral_code\",\n cookieDays: 30,\n urlParamName: \"ref\",\n referralUrlBase: \"\",\n referralPath: \"/\",\n};\n\n// Private storage for configuration\nlet _referralConfig: Required<ReferralConfig> = { ...DEFAULT_REFERRAL_CONFIG };\n\n/**\n * Configure referral feature settings.\n * Call this at app startup to enable and configure referral functionality.\n *\n * @example\n * ```typescript\n * import { configureReferral } from \"@carlonicora/nextjs-jsonapi\";\n *\n * configureReferral({\n * enabled: process.env.NEXT_PUBLIC_REFERRAL_ENABLED === 'true',\n * cookieDays: 30,\n * });\n * ```\n */\nexport function configureReferral(config: ReferralConfig): void {\n _referralConfig = { ...DEFAULT_REFERRAL_CONFIG, ...config };\n}\n\n/**\n * Get the current referral configuration.\n * @internal\n */\nexport function getReferralConfig(): Required<ReferralConfig> {\n return _referralConfig;\n}\n\n/**\n * Check if referral feature is enabled.\n */\nexport function isReferralEnabled(): boolean {\n return _referralConfig.enabled;\n}\n","export type SignupSource = {\n sourceRef?: string;\n sourceUtmSource?: string;\n sourceUtmMedium?: string;\n sourceUtmCampaign?: string;\n sourceReferrer?: string;\n sourceLandingPath?: string;\n};\n\nexport const SIGNUP_SOURCE_COOKIE = \"signup_source\";\nexport const SIGNUP_SOURCE_COOKIE_MAX_AGE = 2592000;\n\n/** The six source fields, in display order. */\nexport const SIGNUP_SOURCE_FIELDS: readonly (keyof SignupSource)[] = [\n \"sourceRef\",\n \"sourceUtmSource\",\n \"sourceUtmMedium\",\n \"sourceUtmCampaign\",\n \"sourceReferrer\",\n \"sourceLandingPath\",\n];\n\nconst SIGNUP_SOURCE_MAX_LENGTH = 200;\n\n// First touch for the current page session. Survives client navigations, lost on a full reload.\nlet memorySource: SignupSource | undefined;\n\nfunction clean(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n return trimmed.slice(0, SIGNUP_SOURCE_MAX_LENGTH);\n}\n\nfunction sanitise(input: unknown): SignupSource | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const result: SignupSource = {};\n for (const field of SIGNUP_SOURCE_FIELDS) {\n const value = clean((input as Record<string, unknown>)[field]);\n if (value !== undefined) result[field] = value;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Pure. Reads ref and utm_source/medium/campaign from the URL, the referrer host when it is not ownHost,\n * and the landing path. Returns undefined for a direct visit (no ref, no UTM, no external referrer).\n */\nexport function readSignupSourceFromLocation(params: {\n url: string;\n referrer: string;\n ownHost: string;\n}): SignupSource | undefined {\n let url: URL;\n try {\n url = new URL(params.url);\n } catch {\n return undefined;\n }\n\n const sourceRef = clean(url.searchParams.get(\"ref\"));\n const sourceUtmSource = clean(url.searchParams.get(\"utm_source\"));\n const sourceUtmMedium = clean(url.searchParams.get(\"utm_medium\"));\n const sourceUtmCampaign = clean(url.searchParams.get(\"utm_campaign\"));\n\n let sourceReferrer: string | undefined;\n if (params.referrer) {\n try {\n const referrerHost = new URL(params.referrer).host;\n if (referrerHost && referrerHost !== params.ownHost) sourceReferrer = clean(referrerHost);\n } catch {\n sourceReferrer = undefined;\n }\n }\n\n if (!sourceRef && !sourceUtmSource && !sourceUtmMedium && !sourceUtmCampaign && !sourceReferrer) return undefined;\n\n return sanitise({\n sourceRef,\n sourceUtmSource,\n sourceUtmMedium,\n sourceUtmCampaign,\n sourceReferrer,\n sourceLandingPath: url.pathname,\n });\n}\n\nfunction readSignupSourceCookie(): SignupSource | undefined {\n if (typeof document === \"undefined\") return undefined;\n const cookies = document.cookie ? document.cookie.split(\"; \") : [];\n for (const cookie of cookies) {\n const separator = cookie.indexOf(\"=\");\n if (separator === -1) continue;\n if (cookie.slice(0, separator) !== SIGNUP_SOURCE_COOKIE) continue;\n const value = cookie.slice(separator + 1);\n if (!value) return undefined;\n try {\n return sanitise(JSON.parse(decodeURIComponent(value)));\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nfunction writeSignupSourceCookie(source: SignupSource): void {\n document.cookie = `${SIGNUP_SOURCE_COOKIE}=${encodeURIComponent(JSON.stringify(source))}; path=/; max-age=${SIGNUP_SOURCE_COOKIE_MAX_AGE}; SameSite=Lax`;\n}\n\n/**\n * First touch: an existing in-memory value or cookie is never overwritten.\n * Writes the cookie only when persist is true and no cookie exists yet.\n */\nexport function captureSignupSource(params: { persist: boolean }): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return;\n\n const existingCookie = readSignupSourceCookie();\n\n if (!memorySource) {\n memorySource =\n existingCookie ??\n readSignupSourceFromLocation({\n url: window.location.href,\n referrer: document.referrer,\n ownHost: window.location.host,\n });\n }\n\n if (params.persist && !existingCookie && memorySource) writeSignupSourceCookie(memorySource);\n}\n\n/** The in-memory value, else the cookie value, else undefined. */\nexport function getSignupSource(): SignupSource | undefined {\n return memorySource ?? readSignupSourceCookie();\n}\n","export const COMPANY_ADMINISTRATOR_ROLE_ID = \"2e1eee00-6cba-4506-9059-ccd24e4ea5b0\";\n\nexport type PermissionValue = boolean | string;\n\nexport type ActionType = \"read\" | \"create\" | \"update\" | \"delete\";\n\nexport const ACTION_TYPES: ActionType[] = [\"read\", \"create\", \"update\", \"delete\"];\n\n/** The permissions object shape used by both Module and PermissionMapping entities */\nexport type PermissionsMap = {\n create?: PermissionValue;\n read?: PermissionValue;\n update?: PermissionValue;\n delete?: PermissionValue;\n};\n\n/**\n * Declarative-RBAC matrix types.\n *\n * Mirror of the library types defined in\n * `packages/nestjs-neo4jsonapi/src/foundations/rbac/dsl/types.ts`.\n * Frontend does not import from backend, so the shape is redefined here.\n *\n * A `PermToken` represents a single permission entry:\n * - `scope: true` → unconditional (e.g. full read of the module)\n * - `scope: false` → nothing (rarely used, mostly a placeholder)\n * - `scope: \"path\"` → scoped by relationship path (e.g. \"orders.account\")\n */\nexport type PermToken = { action: string; scope: boolean | string };\n\n/**\n * A per-module block of the matrix. Always has a `default` row (permissions\n * granted to every role). Additional keys are role IDs → role-specific\n * permission tokens that are unioned with `default` to produce the effective\n * permissions for that role in that module.\n */\nexport type RbacModuleBlock = { default: PermToken[] } & Record<string, PermToken[]>;\n\n/**\n * The full RBAC matrix as served by the dev endpoint `GET /_dev/rbac/matrix`.\n * Keys are module IDs; values are module blocks.\n */\nexport type RbacMatrix = Record<string, RbacModuleBlock>;\n","import { AbstractService, EndpointCreator, HttpMethod, Modules } from \"../../../core\";\nimport type { RbacMatrixModel } from \"./RbacMatrixModel\";\nimport type { RbacMatrix } from \"./RbacTypes\";\n\n/**\n * RbacService — fetches RBAC configuration for the admin UI.\n *\n * Declarative-matrix methods (`fetchMatrix`, `saveMatrix`) talk to the\n * dev-only endpoints added in\n * `packages/nestjs-neo4jsonapi/.../rbac-dev.controller.ts`. The controller\n * speaks JSON:API (singleton resource with `type: \"rbac-matrix\"`, `id:\n * \"singleton\"`), so these methods go through the standard `callApi()`\n * pipeline like every other service in the codebase.\n *\n * The backend only registers these routes when `devMode` is enabled on\n * `RbacModule.register` (see `apps/api/src/features/features.modules.ts`).\n * In production the routes return 404; callers should guard with a dev-mode\n * check.\n */\nexport class RbacService extends AbstractService {\n /**\n * Fetch the current RBAC matrix plus each module's known BFS relationship\n * paths (used by the permission picker as scope suggestions).\n *\n * Dev-only endpoint — see class header.\n */\n static async fetchMatrix(): Promise<{\n matrix: RbacMatrix;\n modulePaths: Record<string, readonly string[]>;\n }> {\n const endpoint = new EndpointCreator({ endpoint: Modules.RbacMatrix }).generate();\n\n const model = await this.callApi<RbacMatrixModel>({\n type: Modules.RbacMatrix,\n method: HttpMethod.GET,\n endpoint,\n });\n\n return {\n matrix: model.matrix ?? {},\n modulePaths: model.modulePaths ?? {},\n };\n }\n\n /**\n * Persist a matrix back to the declarative `permissions.ts` file.\n *\n * The backend serializes the matrix to formatted TypeScript using the\n * provided `roleNames` / `moduleNames` lookup tables (so the emitted file\n * references `RoleId.X` / `ModuleId.X` rather than raw UUIDs) and writes\n * it to `outputPath` (absolute, or relative to the repo root).\n *\n * Dev-only endpoint — see class header.\n */\n static async saveMatrix(args: {\n matrix: RbacMatrix;\n roleNames: Record<string, string>;\n moduleNames: Record<string, string>;\n outputPath: string;\n }): Promise<{ bytesWritten: number; path: string }> {\n const endpoint = new EndpointCreator({ endpoint: Modules.RbacMatrix }).generate();\n\n const model = await this.callApi<RbacMatrixModel>({\n type: Modules.RbacMatrix,\n method: HttpMethod.PUT,\n endpoint,\n input: args,\n });\n\n return {\n bytesWritten: model.bytesWritten ?? 0,\n path: model.path ?? \"\",\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/registry/helpStore.ts","../src/client/config.ts","../src/login/config.ts","../src/features/waitlist/config/waitlist.config.ts","../src/features/referral/config.ts","../src/features/signup-source/signup-source.ts","../src/features/rbac/data/RbacTypes.ts","../src/features/rbac/data/RbacService.ts"],"sourcesContent":["/**\n * Centralized help-content store accessible from client and server contexts.\n * Uses a globalThis Symbol key to persist across HMR/Turbopack reloads and to\n * bridge between the client-side `configureJsonApi` (in `client/config.ts`)\n * and the HelpProvider context. Holds the brand-only HelpContentConfig.\n *\n * NO external dependencies to avoid circular imports.\n *\n * Pattern mirrors `bootstrapStore.ts`.\n */\n\nconst HELP_CONTENT_KEY = Symbol.for(\"nextjs-jsonapi:helpContent\");\n\nconst globalStore = globalThis as unknown as {\n [HELP_CONTENT_KEY]?: unknown | null;\n};\n\nif (globalStore[HELP_CONTENT_KEY] === undefined) {\n globalStore[HELP_CONTENT_KEY] = null;\n}\n\nexport function _setStaticHelpContent(cfg: unknown | null): void {\n globalStore[HELP_CONTENT_KEY] = cfg;\n}\n\nexport function _getStaticHelpContent<T = unknown>(): T | null {\n return (globalStore[HELP_CONTENT_KEY] as T | null) ?? null;\n}\n","\"use client\";\n\nimport { ModuleWithPermissions } from \"../permissions/types\";\nimport { ENV } from \"../core/env\";\nimport { setBootstrapper } from \"../core/registry/bootstrapStore\";\nimport { _setStaticHelpContent } from \"../core/registry/helpStore\";\nimport type { HelpContentConfig } from \"../features/help/interfaces/help-content-config.interface\";\n\n// Config storage for client-side contexts\nlet _clientConfig: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n stripePublishableKey?: string;\n} | null = null;\n\n/**\n * Configure the JSON:API client. This is the main configuration function.\n * This is typically called during app initialization.\n * @param config.helpContent - Optional help-content config (brand only). Forwarded to the help feature's globalThis-backed store; not stored on the client config.\n */\nexport function configureJsonApi(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n stripePublishableKey?: string;\n helpContent?: HelpContentConfig;\n}): void {\n const { helpContent, ...rest } = config;\n _clientConfig = rest;\n if (helpContent) {\n _setStaticHelpContent(helpContent);\n }\n // Register and call bootstrapper to register all modules\n if (config.bootstrapper) {\n setBootstrapper(config.bootstrapper);\n config.bootstrapper();\n }\n}\n\n/**\n * Configure the client config. This is typically called during app initialization.\n * @deprecated Use configureJsonApi instead\n */\nexport function configureClientConfig(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n}): void {\n _clientConfig = config;\n}\n\n/**\n * Get the configured API URL.\n *\n * This may resolve to an internal/private host (e.g. a docker-network\n * hostname) when configured to do so for SSR fetches. Do NOT use this for\n * URLs that are rendered into HTML and followed by the browser — use\n * `getPublicApiUrl()` instead.\n */\nexport function getApiUrl(): string {\n if (_clientConfig?.apiUrl) {\n return _clientConfig.apiUrl;\n }\n return ENV.API_URL;\n}\n\n/**\n * Get the public-facing API URL.\n *\n * Always sourced from `NEXT_PUBLIC_API_URL` so it is identical on server\n * and client, and reachable from the user's browser. Use for any URL that\n * gets rendered into HTML the browser will navigate to (links, redirects,\n * OAuth hrefs).\n */\nexport function getPublicApiUrl(): string {\n return ENV.API_URL;\n}\n\n/**\n * Get the configured app URL.\n */\nexport function getAppUrl(): string {\n if (_clientConfig?.appUrl) {\n return _clientConfig.appUrl;\n }\n if (ENV.APP_URL_ALTERNATE) {\n return ENV.APP_URL_ALTERNATE;\n }\n if (typeof window !== \"undefined\") {\n return window.location.origin;\n }\n return \"\";\n}\n\n/**\n * Get the configured trackable pages.\n */\nexport function getTrackablePages(): ModuleWithPermissions[] {\n return _clientConfig?.trackablePages ?? [];\n}\n\n/**\n * Get the configured Stripe publishable key.\n */\nexport function getStripePublishableKey(): string | undefined {\n return _clientConfig?.stripePublishableKey;\n}\n","let _useDiscordAuth: boolean = false;\nlet _useGoogleAuth: boolean = false;\nlet _useInternalAuth: boolean = true;\nlet _allowRegistration: boolean = true;\nlet _registrationMode: \"open\" | \"closed\" | \"waitlist\" = \"open\";\n\nexport type RegistrationMode = \"open\" | \"closed\" | \"waitlist\";\n\nexport interface LoginConfig {\n discordClientId?: string;\n googleClientId?: string;\n useInternalAuth?: boolean;\n allowRegistration?: boolean;\n registrationMode?: RegistrationMode;\n}\n\nexport function configureLogin(params: LoginConfig): void {\n _useDiscordAuth = !!params.discordClientId;\n _useGoogleAuth = !!params.googleClientId;\n _useInternalAuth = params.useInternalAuth ?? true;\n _allowRegistration = params.allowRegistration ?? true;\n _registrationMode = params.registrationMode ?? \"open\";\n}\n\nexport function isDiscordAuthEnabled(): boolean {\n return _useDiscordAuth;\n}\n\nexport function isGoogleAuthEnabled(): boolean {\n return _useGoogleAuth;\n}\n\nexport function isInternalAuthEnabled(): boolean {\n return _useInternalAuth;\n}\n\nexport function isRegistrationAllowed(): boolean {\n return _allowRegistration;\n}\n\nexport function getRegistrationMode(): RegistrationMode {\n return _registrationMode;\n}\n","import { useI18nTranslations } from \"../../../i18n\";\n\nexport type QuestionnaireFieldType = \"text\" | \"textarea\" | \"select\" | \"checkbox\";\n\nexport interface QuestionnaireOption {\n value: string;\n label: string;\n description?: string;\n}\n\nexport interface QuestionnaireField {\n id: string;\n type: QuestionnaireFieldType;\n label: string;\n description?: string;\n placeholder?: string;\n required?: boolean;\n options?: QuestionnaireOption[];\n}\n\nexport interface WaitlistConfig {\n questionnaire?: QuestionnaireField[];\n heroTitle?: string;\n heroSubtitle?: string;\n heroDescription?: string;\n benefits?: string[];\n /**\n * When true, every text above (hero title, subtitle, description, benefits and\n * the questionnaire's labels, descriptions, placeholders and option labels) is\n * a message key and renders through `t()`. Defaults to false: the strings\n * render as given.\n */\n translate?: boolean;\n}\n\nlet _waitlistConfig: WaitlistConfig = {};\n\nexport function configureWaitlist(config: WaitlistConfig): void {\n _waitlistConfig = config;\n}\n\nexport function getWaitlistConfig(): WaitlistConfig {\n return _waitlistConfig;\n}\n\n/**\n * Resolves a waitlist config text: `t(value)` when the config sets\n * `translate`, the value itself otherwise. Empty values stay undefined.\n */\nexport function useWaitlistText(): (value?: string) => string | undefined {\n const t = useI18nTranslations();\n const translate = getWaitlistConfig().translate === true;\n\n return (value?: string) => {\n if (!value) return undefined;\n return translate ? t(value) : value;\n };\n}\n","/**\n * Configuration interface for frontend referral feature.\n */\nexport interface ReferralConfig {\n /**\n * Whether the referral feature is enabled.\n * When false, components render nothing and hooks return null.\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Name of the cookie used to store referral codes.\n * @default \"referral_code\"\n */\n cookieName?: string;\n\n /**\n * Number of days the referral cookie is valid.\n * @default 30\n */\n cookieDays?: number;\n\n /**\n * Query parameter name for referral code in URL.\n * @default \"ref\"\n */\n urlParamName?: string;\n\n /**\n * Base URL for referral links.\n * @default window.location.origin (client-side only)\n */\n referralUrlBase?: string;\n\n /**\n * Path to append to base URL for referral links.\n * @default \"/\"\n */\n referralPath?: string;\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_REFERRAL_CONFIG: Required<ReferralConfig> = {\n enabled: false,\n cookieName: \"referral_code\",\n cookieDays: 30,\n urlParamName: \"ref\",\n referralUrlBase: \"\",\n referralPath: \"/\",\n};\n\n// Private storage for configuration\nlet _referralConfig: Required<ReferralConfig> = { ...DEFAULT_REFERRAL_CONFIG };\n\n/**\n * Configure referral feature settings.\n * Call this at app startup to enable and configure referral functionality.\n *\n * @example\n * ```typescript\n * import { configureReferral } from \"@carlonicora/nextjs-jsonapi\";\n *\n * configureReferral({\n * enabled: process.env.NEXT_PUBLIC_REFERRAL_ENABLED === 'true',\n * cookieDays: 30,\n * });\n * ```\n */\nexport function configureReferral(config: ReferralConfig): void {\n _referralConfig = { ...DEFAULT_REFERRAL_CONFIG, ...config };\n}\n\n/**\n * Get the current referral configuration.\n * @internal\n */\nexport function getReferralConfig(): Required<ReferralConfig> {\n return _referralConfig;\n}\n\n/**\n * Check if referral feature is enabled.\n */\nexport function isReferralEnabled(): boolean {\n return _referralConfig.enabled;\n}\n","export type SignupSource = {\n sourceRef?: string;\n sourceUtmSource?: string;\n sourceUtmMedium?: string;\n sourceUtmCampaign?: string;\n sourceReferrer?: string;\n sourceLandingPath?: string;\n};\n\nexport const SIGNUP_SOURCE_COOKIE = \"signup_source\";\nexport const SIGNUP_SOURCE_COOKIE_MAX_AGE = 2592000;\n\n/** The six source fields, in display order. */\nexport const SIGNUP_SOURCE_FIELDS: readonly (keyof SignupSource)[] = [\n \"sourceRef\",\n \"sourceUtmSource\",\n \"sourceUtmMedium\",\n \"sourceUtmCampaign\",\n \"sourceReferrer\",\n \"sourceLandingPath\",\n];\n\nconst SIGNUP_SOURCE_MAX_LENGTH = 200;\n\n// First touch for the current page session. Survives client navigations, lost on a full reload.\nlet memorySource: SignupSource | undefined;\n\nfunction clean(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n return trimmed.slice(0, SIGNUP_SOURCE_MAX_LENGTH);\n}\n\nfunction sanitise(input: unknown): SignupSource | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const result: SignupSource = {};\n for (const field of SIGNUP_SOURCE_FIELDS) {\n const value = clean((input as Record<string, unknown>)[field]);\n if (value !== undefined) result[field] = value;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/**\n * Pure. Reads ref and utm_source/medium/campaign from the URL, the referrer host when it is not ownHost,\n * and the landing path. Returns undefined for a direct visit (no ref, no UTM, no external referrer).\n */\nexport function readSignupSourceFromLocation(params: {\n url: string;\n referrer: string;\n ownHost: string;\n}): SignupSource | undefined {\n let url: URL;\n try {\n url = new URL(params.url);\n } catch {\n return undefined;\n }\n\n const sourceRef = clean(url.searchParams.get(\"ref\"));\n const sourceUtmSource = clean(url.searchParams.get(\"utm_source\"));\n const sourceUtmMedium = clean(url.searchParams.get(\"utm_medium\"));\n const sourceUtmCampaign = clean(url.searchParams.get(\"utm_campaign\"));\n\n let sourceReferrer: string | undefined;\n if (params.referrer) {\n try {\n const referrerHost = new URL(params.referrer).host;\n if (referrerHost && referrerHost !== params.ownHost) sourceReferrer = clean(referrerHost);\n } catch {\n sourceReferrer = undefined;\n }\n }\n\n if (!sourceRef && !sourceUtmSource && !sourceUtmMedium && !sourceUtmCampaign && !sourceReferrer) return undefined;\n\n return sanitise({\n sourceRef,\n sourceUtmSource,\n sourceUtmMedium,\n sourceUtmCampaign,\n sourceReferrer,\n sourceLandingPath: url.pathname,\n });\n}\n\nfunction readSignupSourceCookie(): SignupSource | undefined {\n if (typeof document === \"undefined\") return undefined;\n const cookies = document.cookie ? document.cookie.split(\"; \") : [];\n for (const cookie of cookies) {\n const separator = cookie.indexOf(\"=\");\n if (separator === -1) continue;\n if (cookie.slice(0, separator) !== SIGNUP_SOURCE_COOKIE) continue;\n const value = cookie.slice(separator + 1);\n if (!value) return undefined;\n try {\n return sanitise(JSON.parse(decodeURIComponent(value)));\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nfunction writeSignupSourceCookie(source: SignupSource): void {\n document.cookie = `${SIGNUP_SOURCE_COOKIE}=${encodeURIComponent(JSON.stringify(source))}; path=/; max-age=${SIGNUP_SOURCE_COOKIE_MAX_AGE}; SameSite=Lax`;\n}\n\n/**\n * First touch: an existing in-memory value or cookie is never overwritten.\n * Writes the cookie only when persist is true and no cookie exists yet.\n */\nexport function captureSignupSource(params: { persist: boolean }): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return;\n\n const existingCookie = readSignupSourceCookie();\n\n if (!memorySource) {\n memorySource =\n existingCookie ??\n readSignupSourceFromLocation({\n url: window.location.href,\n referrer: document.referrer,\n ownHost: window.location.host,\n });\n }\n\n if (params.persist && !existingCookie && memorySource) writeSignupSourceCookie(memorySource);\n}\n\n/** The in-memory value, else the cookie value, else undefined. */\nexport function getSignupSource(): SignupSource | undefined {\n return memorySource ?? readSignupSourceCookie();\n}\n","export const COMPANY_ADMINISTRATOR_ROLE_ID = \"2e1eee00-6cba-4506-9059-ccd24e4ea5b0\";\n\nexport type PermissionValue = boolean | string;\n\nexport type ActionType = \"read\" | \"create\" | \"update\" | \"delete\";\n\nexport const ACTION_TYPES: ActionType[] = [\"read\", \"create\", \"update\", \"delete\"];\n\n/** The permissions object shape used by both Module and PermissionMapping entities */\nexport type PermissionsMap = {\n create?: PermissionValue;\n read?: PermissionValue;\n update?: PermissionValue;\n delete?: PermissionValue;\n};\n\n/**\n * Declarative-RBAC matrix types.\n *\n * Mirror of the library types defined in\n * `packages/nestjs-neo4jsonapi/src/foundations/rbac/dsl/types.ts`.\n * Frontend does not import from backend, so the shape is redefined here.\n *\n * A `PermToken` represents a single permission entry:\n * - `scope: true` → unconditional (e.g. full read of the module)\n * - `scope: false` → nothing (rarely used, mostly a placeholder)\n * - `scope: \"path\"` → scoped by relationship path (e.g. \"orders.account\")\n */\nexport type PermToken = { action: string; scope: boolean | string };\n\n/**\n * A per-module block of the matrix. Always has a `default` row (permissions\n * granted to every role). Additional keys are role IDs → role-specific\n * permission tokens that are unioned with `default` to produce the effective\n * permissions for that role in that module.\n */\nexport type RbacModuleBlock = { default: PermToken[] } & Record<string, PermToken[]>;\n\n/**\n * The full RBAC matrix as served by the dev endpoint `GET /_dev/rbac/matrix`.\n * Keys are module IDs; values are module blocks.\n */\nexport type RbacMatrix = Record<string, RbacModuleBlock>;\n","import { AbstractService, EndpointCreator, HttpMethod, Modules } from \"../../../core\";\nimport type { RbacMatrixModel } from \"./RbacMatrixModel\";\nimport type { RbacMatrix } from \"./RbacTypes\";\n\n/**\n * RbacService — fetches RBAC configuration for the admin UI.\n *\n * Declarative-matrix methods (`fetchMatrix`, `saveMatrix`) talk to the\n * dev-only endpoints added in\n * `packages/nestjs-neo4jsonapi/.../rbac-dev.controller.ts`. The controller\n * speaks JSON:API (singleton resource with `type: \"rbac-matrix\"`, `id:\n * \"singleton\"`), so these methods go through the standard `callApi()`\n * pipeline like every other service in the codebase.\n *\n * The backend only registers these routes when `devMode` is enabled on\n * `RbacModule.register` (see `apps/api/src/features/features.modules.ts`).\n * In production the routes return 404; callers should guard with a dev-mode\n * check.\n */\nexport class RbacService extends AbstractService {\n /**\n * Fetch the current RBAC matrix plus each module's known BFS relationship\n * paths (used by the permission picker as scope suggestions).\n *\n * Dev-only endpoint — see class header.\n */\n static async fetchMatrix(): Promise<{\n matrix: RbacMatrix;\n modulePaths: Record<string, readonly string[]>;\n }> {\n const endpoint = new EndpointCreator({ endpoint: Modules.RbacMatrix }).generate();\n\n const model = await this.callApi<RbacMatrixModel>({\n type: Modules.RbacMatrix,\n method: HttpMethod.GET,\n endpoint,\n });\n\n return {\n matrix: model.matrix ?? {},\n modulePaths: model.modulePaths ?? {},\n };\n }\n\n /**\n * Persist a matrix back to the declarative `permissions.ts` file.\n *\n * The backend serializes the matrix to formatted TypeScript using the\n * provided `roleNames` / `moduleNames` lookup tables (so the emitted file\n * references `RoleId.X` / `ModuleId.X` rather than raw UUIDs) and writes\n * it to `outputPath` (absolute, or relative to the repo root).\n *\n * Dev-only endpoint — see class header.\n */\n static async saveMatrix(args: {\n matrix: RbacMatrix;\n roleNames: Record<string, string>;\n moduleNames: Record<string, string>;\n outputPath: string;\n }): Promise<{ bytesWritten: number; path: string }> {\n const endpoint = new EndpointCreator({ endpoint: Modules.RbacMatrix }).generate();\n\n const model = await this.callApi<RbacMatrixModel>({\n type: Modules.RbacMatrix,\n method: HttpMethod.PUT,\n endpoint,\n input: args,\n });\n\n return {\n bytesWritten: model.bytesWritten ?? 0,\n path: model.path ?? \"\",\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataClassRegistry,
|
|
3
|
+
hasBootstrapper,
|
|
4
|
+
tryBootstrap
|
|
5
|
+
} from "./chunk-DGWOVYEC.mjs";
|
|
6
|
+
import {
|
|
7
|
+
__name
|
|
8
|
+
} from "./chunk-PAWJFY3S.mjs";
|
|
9
|
+
|
|
10
|
+
// src/core/factories/RehydrationFactory.ts
|
|
11
|
+
var inProgress = /* @__PURE__ */ new Set();
|
|
12
|
+
var keyOf = /* @__PURE__ */ __name((data) => {
|
|
13
|
+
const resource = data?.jsonApi;
|
|
14
|
+
return resource?.type && resource?.id ? `${resource.type}:${resource.id}` : void 0;
|
|
15
|
+
}, "keyOf");
|
|
16
|
+
function guarded(data, run) {
|
|
17
|
+
const key = keyOf(data);
|
|
18
|
+
if (!key) return run();
|
|
19
|
+
if (inProgress.has(key)) return void 0;
|
|
20
|
+
inProgress.add(key);
|
|
21
|
+
try {
|
|
22
|
+
return run();
|
|
23
|
+
} finally {
|
|
24
|
+
inProgress.delete(key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
__name(guarded, "guarded");
|
|
28
|
+
var RehydrationFactory = class {
|
|
29
|
+
static {
|
|
30
|
+
__name(this, "RehydrationFactory");
|
|
31
|
+
}
|
|
32
|
+
static rehydrate(classKey, data) {
|
|
33
|
+
const factoryClass = DataClassRegistry.get(classKey);
|
|
34
|
+
return guarded(data, () => new factoryClass().rehydrate(data));
|
|
35
|
+
}
|
|
36
|
+
static rehydrateList(classKey, data) {
|
|
37
|
+
const factoryClass = DataClassRegistry.get(classKey);
|
|
38
|
+
return data.map(
|
|
39
|
+
(item) => guarded(item, () => new factoryClass().rehydrate(item))
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/core/abstracts/AbstractApiData.ts
|
|
45
|
+
var AbstractApiData = class _AbstractApiData {
|
|
46
|
+
static {
|
|
47
|
+
__name(this, "AbstractApiData");
|
|
48
|
+
}
|
|
49
|
+
static identifierFields = ["name"];
|
|
50
|
+
get identifier() {
|
|
51
|
+
const fields = this.constructor.identifierFields;
|
|
52
|
+
return fields.map((field) => this._jsonApi?.attributes?.[field]).filter((v) => v != null && v !== "").join(" ");
|
|
53
|
+
}
|
|
54
|
+
_jsonApi;
|
|
55
|
+
_included;
|
|
56
|
+
_id;
|
|
57
|
+
_type;
|
|
58
|
+
_createdAt;
|
|
59
|
+
_updatedAt;
|
|
60
|
+
_self;
|
|
61
|
+
get type() {
|
|
62
|
+
if (!this._type) throw new Error("Type is not set.");
|
|
63
|
+
return this._type;
|
|
64
|
+
}
|
|
65
|
+
get id() {
|
|
66
|
+
if (!this._id) throw new Error("Id is not set.");
|
|
67
|
+
return this._id;
|
|
68
|
+
}
|
|
69
|
+
get self() {
|
|
70
|
+
return this._self;
|
|
71
|
+
}
|
|
72
|
+
get createdAt() {
|
|
73
|
+
return this._createdAt ?? /* @__PURE__ */ new Date();
|
|
74
|
+
}
|
|
75
|
+
get updatedAt() {
|
|
76
|
+
return this._updatedAt ?? /* @__PURE__ */ new Date();
|
|
77
|
+
}
|
|
78
|
+
get included() {
|
|
79
|
+
return this._included ?? [];
|
|
80
|
+
}
|
|
81
|
+
get jsonApi() {
|
|
82
|
+
return this._jsonApi;
|
|
83
|
+
}
|
|
84
|
+
ingestJsonApi(_data) {
|
|
85
|
+
}
|
|
86
|
+
generateApiUrl(_params) {
|
|
87
|
+
throw new Error("Method not implemented.");
|
|
88
|
+
}
|
|
89
|
+
createJsonApi(_data) {
|
|
90
|
+
throw new Error("Method not implemented.");
|
|
91
|
+
}
|
|
92
|
+
_readIncluded(data, type, dataType) {
|
|
93
|
+
if (data.included === void 0 || data.included.length === 0 || data.jsonApi.relationships === void 0 || data.jsonApi.relationships[type] === void 0 || data.jsonApi.relationships[type].data === void 0) {
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(data.jsonApi.relationships[type].data)) {
|
|
97
|
+
const response = data.jsonApi.relationships[type].data.map((jsonApiData) => {
|
|
98
|
+
const includedData2 = data.included.find(
|
|
99
|
+
(includedData3) => includedData3.id === jsonApiData.id && includedData3.type === jsonApiData.type
|
|
100
|
+
);
|
|
101
|
+
if (includedData2 === void 0) return void 0;
|
|
102
|
+
return RehydrationFactory.rehydrate(dataType, {
|
|
103
|
+
jsonApi: includedData2,
|
|
104
|
+
included: data.included
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
return response.filter((item) => item !== void 0);
|
|
108
|
+
}
|
|
109
|
+
const includedData = data.included.find(
|
|
110
|
+
(includedData2) => includedData2.id === data.jsonApi.relationships[type].data.id && includedData2.type === data.jsonApi.relationships[type].data.type
|
|
111
|
+
);
|
|
112
|
+
if (includedData === void 0 && data.allData !== void 0) {
|
|
113
|
+
const fallbackData = data.allData.find(
|
|
114
|
+
(includedData2) => includedData2.id === data.jsonApi.relationships[type].data.id && includedData2.type === data.jsonApi.relationships[type].data.type
|
|
115
|
+
);
|
|
116
|
+
if (fallbackData !== void 0) {
|
|
117
|
+
return RehydrationFactory.rehydrate(dataType, {
|
|
118
|
+
jsonApi: fallbackData,
|
|
119
|
+
included: data.included
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (includedData === void 0) return void 0;
|
|
124
|
+
return RehydrationFactory.rehydrate(dataType, {
|
|
125
|
+
jsonApi: includedData,
|
|
126
|
+
included: data.included
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Read included relationships with polymorphic type resolution.
|
|
131
|
+
* Determines the correct model class based on the JSON:API type in included data.
|
|
132
|
+
*/
|
|
133
|
+
_readIncludedPolymorphic(data, relationshipKey, candidateModules) {
|
|
134
|
+
if (!data.included?.length || !data.jsonApi.relationships?.[relationshipKey]?.data) {
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
const relData = data.jsonApi.relationships[relationshipKey].data;
|
|
138
|
+
const typeToModule = /* @__PURE__ */ new Map();
|
|
139
|
+
for (const mod of candidateModules) {
|
|
140
|
+
typeToModule.set(mod.name, mod);
|
|
141
|
+
}
|
|
142
|
+
if (Array.isArray(relData)) {
|
|
143
|
+
const result = [];
|
|
144
|
+
for (const item of relData) {
|
|
145
|
+
const includedItem2 = data.included.find((inc) => inc.id === item.id && inc.type === item.type);
|
|
146
|
+
if (!includedItem2) continue;
|
|
147
|
+
const module2 = typeToModule.get(includedItem2.type);
|
|
148
|
+
if (!module2) continue;
|
|
149
|
+
result.push(
|
|
150
|
+
RehydrationFactory.rehydrate(module2, {
|
|
151
|
+
jsonApi: includedItem2,
|
|
152
|
+
included: data.included
|
|
153
|
+
})
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return result.length > 0 ? result : void 0;
|
|
157
|
+
}
|
|
158
|
+
const includedItem = data.included.find((inc) => inc.id === relData.id && inc.type === relData.type);
|
|
159
|
+
if (!includedItem) return void 0;
|
|
160
|
+
const module = typeToModule.get(includedItem.type);
|
|
161
|
+
if (!module) return void 0;
|
|
162
|
+
return RehydrationFactory.rehydrate(module, {
|
|
163
|
+
jsonApi: includedItem,
|
|
164
|
+
included: data.included
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Read included relationship data and augment with relationship meta properties.
|
|
169
|
+
* Handles both single relationships (one-to-one) and array relationships (one-to-many).
|
|
170
|
+
*
|
|
171
|
+
* For single relationships: meta is read from `relationships[type].meta`
|
|
172
|
+
* For array relationships: per-item meta is read from `relationships[type].data[].meta`
|
|
173
|
+
*
|
|
174
|
+
* @param data - Hydrated JSON:API data
|
|
175
|
+
* @param type - Relationship type key (e.g., "guide", "persons")
|
|
176
|
+
* @param dataType - Module reference for rehydration
|
|
177
|
+
* @returns Related object(s) augmented with meta properties, or undefined
|
|
178
|
+
*/
|
|
179
|
+
_readIncludedWithMeta(data, type, dataType) {
|
|
180
|
+
if (data.included === void 0 || data.included.length === 0 || data.jsonApi.relationships === void 0 || data.jsonApi.relationships[type] === void 0 || data.jsonApi.relationships[type].data === void 0) {
|
|
181
|
+
return void 0;
|
|
182
|
+
}
|
|
183
|
+
const relationshipData = data.jsonApi.relationships[type].data;
|
|
184
|
+
if (Array.isArray(relationshipData)) {
|
|
185
|
+
const result = [];
|
|
186
|
+
for (const item of relationshipData) {
|
|
187
|
+
const includedData2 = data.included.find((inc) => inc.id === item.id && inc.type === item.type);
|
|
188
|
+
if (!includedData2) continue;
|
|
189
|
+
const entity2 = RehydrationFactory.rehydrate(dataType, {
|
|
190
|
+
jsonApi: includedData2,
|
|
191
|
+
included: data.included
|
|
192
|
+
});
|
|
193
|
+
if (item.meta) {
|
|
194
|
+
_AbstractApiData._mergeMeta(entity2, item.meta);
|
|
195
|
+
}
|
|
196
|
+
result.push(entity2);
|
|
197
|
+
}
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
const includedData = data.included.find(
|
|
201
|
+
(inc) => inc.id === relationshipData.id && inc.type === relationshipData.type
|
|
202
|
+
);
|
|
203
|
+
if (!includedData) {
|
|
204
|
+
if (data.allData !== void 0) {
|
|
205
|
+
const fallbackData = data.allData.find(
|
|
206
|
+
(inc) => inc.id === relationshipData.id && inc.type === relationshipData.type
|
|
207
|
+
);
|
|
208
|
+
if (fallbackData) {
|
|
209
|
+
const entity2 = RehydrationFactory.rehydrate(dataType, {
|
|
210
|
+
jsonApi: fallbackData,
|
|
211
|
+
included: data.included
|
|
212
|
+
});
|
|
213
|
+
const relationshipMeta2 = data.jsonApi.relationships[type].meta;
|
|
214
|
+
if (relationshipMeta2) {
|
|
215
|
+
_AbstractApiData._mergeMeta(entity2, relationshipMeta2);
|
|
216
|
+
}
|
|
217
|
+
return entity2;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return void 0;
|
|
221
|
+
}
|
|
222
|
+
const entity = RehydrationFactory.rehydrate(dataType, {
|
|
223
|
+
jsonApi: includedData,
|
|
224
|
+
included: data.included
|
|
225
|
+
});
|
|
226
|
+
const relationshipMeta = data.jsonApi.relationships[type].meta;
|
|
227
|
+
if (relationshipMeta) {
|
|
228
|
+
_AbstractApiData._mergeMeta(entity, relationshipMeta);
|
|
229
|
+
}
|
|
230
|
+
return entity;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Copies relationship meta onto a rehydrated entity as own data properties. Object.assign throws
|
|
234
|
+
* when the model declares a getter-only accessor of the same name (an app's `Chunk` with
|
|
235
|
+
* `get relevance()`); an own property shadows that getter, so the model reads the meta value.
|
|
236
|
+
*/
|
|
237
|
+
static _mergeMeta(entity, meta) {
|
|
238
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
239
|
+
Object.defineProperty(entity, key, { value, writable: true, enumerable: true, configurable: true });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
dehydrate() {
|
|
243
|
+
return {
|
|
244
|
+
jsonApi: this._jsonApi,
|
|
245
|
+
included: this._included ?? []
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
rehydrate(data) {
|
|
249
|
+
this._jsonApi = data.jsonApi;
|
|
250
|
+
this._included = data.included;
|
|
251
|
+
this._type = this._jsonApi.type;
|
|
252
|
+
this._id = this._jsonApi.id;
|
|
253
|
+
this._createdAt = this._jsonApi.meta?.createdAt !== void 0 ? new Date(this._jsonApi.meta.createdAt) : void 0;
|
|
254
|
+
this._updatedAt = this._jsonApi.meta?.updatedAt !== void 0 ? new Date(this._jsonApi.meta.updatedAt) : void 0;
|
|
255
|
+
this._self = this._jsonApi.links?.self ?? void 0;
|
|
256
|
+
return this;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/i18n/config.ts
|
|
261
|
+
var _config = null;
|
|
262
|
+
function configureI18n(config) {
|
|
263
|
+
_config = config;
|
|
264
|
+
}
|
|
265
|
+
__name(configureI18n, "configureI18n");
|
|
266
|
+
function useI18nRouter() {
|
|
267
|
+
if (!_config?.useRouter) {
|
|
268
|
+
throw new Error("i18n not configured. Call configureI18n() at app startup.");
|
|
269
|
+
}
|
|
270
|
+
return _config.useRouter();
|
|
271
|
+
}
|
|
272
|
+
__name(useI18nRouter, "useI18nRouter");
|
|
273
|
+
function useI18nTranslations(namespace) {
|
|
274
|
+
if (!_config?.useTranslations) {
|
|
275
|
+
return (key) => key;
|
|
276
|
+
}
|
|
277
|
+
return _config.useTranslations(namespace);
|
|
278
|
+
}
|
|
279
|
+
__name(useI18nTranslations, "useI18nTranslations");
|
|
280
|
+
function getI18nLink() {
|
|
281
|
+
if (!_config?.Link) {
|
|
282
|
+
throw new Error("i18n not configured. Call configureI18n() at app startup.");
|
|
283
|
+
}
|
|
284
|
+
return _config.Link;
|
|
285
|
+
}
|
|
286
|
+
__name(getI18nLink, "getI18nLink");
|
|
287
|
+
function useI18nLocale() {
|
|
288
|
+
if (_config?.useLocale) {
|
|
289
|
+
return _config.useLocale();
|
|
290
|
+
}
|
|
291
|
+
return "en";
|
|
292
|
+
}
|
|
293
|
+
__name(useI18nLocale, "useI18nLocale");
|
|
294
|
+
async function getI18nServerLocale() {
|
|
295
|
+
if (!_config?.getLocale) {
|
|
296
|
+
throw new Error("i18n not configured. Call configureI18n() with getLocale at app startup.");
|
|
297
|
+
}
|
|
298
|
+
return _config.getLocale();
|
|
299
|
+
}
|
|
300
|
+
__name(getI18nServerLocale, "getI18nServerLocale");
|
|
301
|
+
function useI18nDateFnsLocale() {
|
|
302
|
+
if (_config?.useDateFnsLocale) {
|
|
303
|
+
return _config.useDateFnsLocale();
|
|
304
|
+
}
|
|
305
|
+
return void 0;
|
|
306
|
+
}
|
|
307
|
+
__name(useI18nDateFnsLocale, "useI18nDateFnsLocale");
|
|
308
|
+
function getI18nSupportedLocales() {
|
|
309
|
+
if (_config?.supportedLocales && _config.supportedLocales.length > 0) {
|
|
310
|
+
return _config.supportedLocales;
|
|
311
|
+
}
|
|
312
|
+
return ["en"];
|
|
313
|
+
}
|
|
314
|
+
__name(getI18nSupportedLocales, "getI18nSupportedLocales");
|
|
315
|
+
function getI18nDefaultLocale() {
|
|
316
|
+
return getI18nSupportedLocales()[0];
|
|
317
|
+
}
|
|
318
|
+
__name(getI18nDefaultLocale, "getI18nDefaultLocale");
|
|
319
|
+
|
|
320
|
+
// src/core/registry/ModuleRegistry.ts
|
|
321
|
+
var MODULES_KEY = /* @__PURE__ */ Symbol.for("nextjs-jsonapi:modules");
|
|
322
|
+
var globalStore = globalThis;
|
|
323
|
+
if (!globalStore[MODULES_KEY]) {
|
|
324
|
+
globalStore[MODULES_KEY] = /* @__PURE__ */ new Map();
|
|
325
|
+
}
|
|
326
|
+
var ModuleRegistryClass = class {
|
|
327
|
+
static {
|
|
328
|
+
__name(this, "ModuleRegistryClass");
|
|
329
|
+
}
|
|
330
|
+
get _modules() {
|
|
331
|
+
return globalStore[MODULES_KEY];
|
|
332
|
+
}
|
|
333
|
+
register(name, module) {
|
|
334
|
+
this._modules.set(name, module);
|
|
335
|
+
}
|
|
336
|
+
get(name) {
|
|
337
|
+
let module = this._modules.get(name);
|
|
338
|
+
if (!module) {
|
|
339
|
+
const didBootstrap = tryBootstrap();
|
|
340
|
+
if (didBootstrap) {
|
|
341
|
+
module = this._modules.get(name);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (!module) {
|
|
345
|
+
const hint = hasBootstrapper() ? "Bootstrap was called but module still not found. Check module registration." : "No bootstrapper registered. Ensure configureJsonApi({ bootstrapper }) is called before accessing modules.";
|
|
346
|
+
throw new Error(`Module "${String(name)}" not registered. ${hint}`);
|
|
347
|
+
}
|
|
348
|
+
return module;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* True when a module is registered under `name`. Never throws, so a component
|
|
352
|
+
* can check for an opt-in module the app may not have registered.
|
|
353
|
+
*/
|
|
354
|
+
has(name) {
|
|
355
|
+
if (this._modules.size === 0) tryBootstrap();
|
|
356
|
+
return this._modules.has(name);
|
|
357
|
+
}
|
|
358
|
+
findByName(moduleName) {
|
|
359
|
+
if (this._modules.size === 0) {
|
|
360
|
+
tryBootstrap();
|
|
361
|
+
}
|
|
362
|
+
for (const module of this._modules.values()) {
|
|
363
|
+
if (module.name === moduleName) {
|
|
364
|
+
return module;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
throw new Error(`Module not found: ${moduleName}`);
|
|
368
|
+
}
|
|
369
|
+
getAllPageUrls() {
|
|
370
|
+
if (this._modules.size === 0) {
|
|
371
|
+
tryBootstrap();
|
|
372
|
+
}
|
|
373
|
+
const seen = /* @__PURE__ */ new Set();
|
|
374
|
+
const result = [];
|
|
375
|
+
for (const [key, module] of this._modules.entries()) {
|
|
376
|
+
const m = module;
|
|
377
|
+
if (m.pageUrl && !seen.has(m.pageUrl)) {
|
|
378
|
+
seen.add(m.pageUrl);
|
|
379
|
+
result.push({ id: m.pageUrl, text: key });
|
|
380
|
+
result.push({ id: `${m.pageUrl}/:id`, text: `${key} (detail)` });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return result.sort((a, b) => a.text.localeCompare(b.text));
|
|
384
|
+
}
|
|
385
|
+
findByModelName(modelName) {
|
|
386
|
+
let module = this._modules.get(modelName);
|
|
387
|
+
if (!module) {
|
|
388
|
+
const didBootstrap = tryBootstrap();
|
|
389
|
+
if (didBootstrap) {
|
|
390
|
+
module = this._modules.get(modelName);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (!module) {
|
|
394
|
+
throw new Error(`Module not found for model: ${modelName}`);
|
|
395
|
+
}
|
|
396
|
+
return module;
|
|
397
|
+
}
|
|
398
|
+
findByFeature(feature) {
|
|
399
|
+
const response = [];
|
|
400
|
+
for (const module of this._modules.values()) {
|
|
401
|
+
const m = module;
|
|
402
|
+
if (m.feature === feature) {
|
|
403
|
+
response.push(m);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return response;
|
|
407
|
+
}
|
|
408
|
+
getAll() {
|
|
409
|
+
if (this._modules.size === 0) {
|
|
410
|
+
tryBootstrap();
|
|
411
|
+
}
|
|
412
|
+
return Array.from(this._modules.values());
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
var ModuleRegistry = new ModuleRegistryClass();
|
|
416
|
+
var Modules = new Proxy({}, {
|
|
417
|
+
get(_, prop) {
|
|
418
|
+
if (prop === "findByName") {
|
|
419
|
+
return (name) => ModuleRegistry.findByName(name);
|
|
420
|
+
}
|
|
421
|
+
if (prop === "findByModelName") {
|
|
422
|
+
return (name) => ModuleRegistry.findByModelName(name);
|
|
423
|
+
}
|
|
424
|
+
if (prop === "findByFeature") {
|
|
425
|
+
return (feature) => ModuleRegistry.findByFeature(feature);
|
|
426
|
+
}
|
|
427
|
+
return ModuleRegistry.get(prop);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// src/core/endpoint/EndpointCreator.ts
|
|
432
|
+
var EndpointCreator = class {
|
|
433
|
+
static {
|
|
434
|
+
__name(this, "EndpointCreator");
|
|
435
|
+
}
|
|
436
|
+
_endpoint;
|
|
437
|
+
constructor(params) {
|
|
438
|
+
this._endpoint = {
|
|
439
|
+
endpoint: params.endpoint,
|
|
440
|
+
id: params.id,
|
|
441
|
+
childEndpoint: params.childEndpoint,
|
|
442
|
+
childId: params.childId,
|
|
443
|
+
additionalParams: params.additionalParams ?? []
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
endpoint(value) {
|
|
447
|
+
this._endpoint.endpoint = value;
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
id(value) {
|
|
451
|
+
this._endpoint.id = value;
|
|
452
|
+
return this;
|
|
453
|
+
}
|
|
454
|
+
childEndpoint(value) {
|
|
455
|
+
this._endpoint.childEndpoint = value;
|
|
456
|
+
return this;
|
|
457
|
+
}
|
|
458
|
+
childId(value) {
|
|
459
|
+
this._endpoint.childId = value;
|
|
460
|
+
return this;
|
|
461
|
+
}
|
|
462
|
+
set additionalParams(value) {
|
|
463
|
+
this._endpoint.additionalParams = value;
|
|
464
|
+
}
|
|
465
|
+
addAdditionalParam(key, value) {
|
|
466
|
+
if (!this._endpoint.additionalParams) this._endpoint.additionalParams = [];
|
|
467
|
+
this._endpoint.additionalParams.push({ key, value });
|
|
468
|
+
return this;
|
|
469
|
+
}
|
|
470
|
+
limitToType(selectors) {
|
|
471
|
+
this.addAdditionalParam(`include`, selectors.join(","));
|
|
472
|
+
return this;
|
|
473
|
+
}
|
|
474
|
+
limitToFields(selectors) {
|
|
475
|
+
if (selectors.length === 0) return this;
|
|
476
|
+
selectors.forEach((selector) => {
|
|
477
|
+
const fieldString = selector.fields.join(",");
|
|
478
|
+
this.addAdditionalParam(`fields[${selector.type}]`, fieldString);
|
|
479
|
+
});
|
|
480
|
+
return this;
|
|
481
|
+
}
|
|
482
|
+
generate() {
|
|
483
|
+
let additionalParams = "";
|
|
484
|
+
if (this._endpoint.additionalParams) {
|
|
485
|
+
additionalParams = this._endpoint.additionalParams.map((param) => `${param.key}=${param.value}`).join("&");
|
|
486
|
+
}
|
|
487
|
+
let response = ``;
|
|
488
|
+
response += `${typeof this._endpoint.endpoint === "string" ? this._endpoint.endpoint : this._endpoint.endpoint.name}`;
|
|
489
|
+
if (this._endpoint.id) response += `/${this._endpoint.id}`;
|
|
490
|
+
if (this._endpoint.childEndpoint) {
|
|
491
|
+
response += `/${typeof this._endpoint.childEndpoint === "string" ? this._endpoint.childEndpoint : this._endpoint.childEndpoint.name}`;
|
|
492
|
+
}
|
|
493
|
+
if (this._endpoint.childId) response += `/${this._endpoint.childId}`;
|
|
494
|
+
if (additionalParams) response += `?${additionalParams}`;
|
|
495
|
+
return response;
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// src/offline/sync/models/RootSync.ts
|
|
500
|
+
var ROOT_SYNC_ENDPOINT = "sync";
|
|
501
|
+
var RootSync = class extends AbstractApiData {
|
|
502
|
+
static {
|
|
503
|
+
__name(this, "RootSync");
|
|
504
|
+
}
|
|
505
|
+
_serverTime;
|
|
506
|
+
_locked = false;
|
|
507
|
+
_lockedFrom;
|
|
508
|
+
_entries;
|
|
509
|
+
_links;
|
|
510
|
+
get serverTime() {
|
|
511
|
+
if (!this._serverTime) throw new Error("serverTime is not set.");
|
|
512
|
+
return this._serverTime;
|
|
513
|
+
}
|
|
514
|
+
get locked() {
|
|
515
|
+
return this._locked;
|
|
516
|
+
}
|
|
517
|
+
get lockedFrom() {
|
|
518
|
+
return this._lockedFrom;
|
|
519
|
+
}
|
|
520
|
+
get entries() {
|
|
521
|
+
return this._entries ?? [];
|
|
522
|
+
}
|
|
523
|
+
get links() {
|
|
524
|
+
return this._links ?? [];
|
|
525
|
+
}
|
|
526
|
+
rehydrate(data) {
|
|
527
|
+
super.rehydrate(data);
|
|
528
|
+
const attributes = data.jsonApi.attributes ?? {};
|
|
529
|
+
this._serverTime = attributes.serverTime ? new Date(attributes.serverTime) : void 0;
|
|
530
|
+
this._locked = Boolean(attributes.locked);
|
|
531
|
+
this._lockedFrom = attributes.lockedFrom ? new Date(attributes.lockedFrom) : void 0;
|
|
532
|
+
this._entries = (attributes.entries ?? []).map((entry) => ({
|
|
533
|
+
type: entry.type,
|
|
534
|
+
id: entry.id,
|
|
535
|
+
updatedAt: new Date(entry.updatedAt)
|
|
536
|
+
}));
|
|
537
|
+
this._links = (attributes.links ?? []).map((link) => ({
|
|
538
|
+
fromType: link.fromType,
|
|
539
|
+
fromId: link.fromId,
|
|
540
|
+
toType: link.toType,
|
|
541
|
+
toId: link.toId,
|
|
542
|
+
kind: link.kind,
|
|
543
|
+
props: link.props ?? {}
|
|
544
|
+
}));
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
547
|
+
createJsonApi(_data) {
|
|
548
|
+
throw new Error("RootSync is read-only and cannot be created");
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
export {
|
|
553
|
+
RehydrationFactory,
|
|
554
|
+
AbstractApiData,
|
|
555
|
+
configureI18n,
|
|
556
|
+
useI18nRouter,
|
|
557
|
+
useI18nTranslations,
|
|
558
|
+
getI18nLink,
|
|
559
|
+
useI18nLocale,
|
|
560
|
+
getI18nServerLocale,
|
|
561
|
+
useI18nDateFnsLocale,
|
|
562
|
+
getI18nSupportedLocales,
|
|
563
|
+
getI18nDefaultLocale,
|
|
564
|
+
ModuleRegistry,
|
|
565
|
+
Modules,
|
|
566
|
+
EndpointCreator,
|
|
567
|
+
ROOT_SYNC_ENDPOINT,
|
|
568
|
+
RootSync
|
|
569
|
+
};
|
|
570
|
+
//# sourceMappingURL=chunk-6JUCIWDC.mjs.map
|