@multiplatform.one/core 7.84.2 → 7.84.4
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/cjs/app/CreateApp.cjs +118 -110
- package/dist/cjs/app/CreateApp.native.js +127 -123
- package/dist/cjs/app/CreateApp.native.js.map +1 -1
- package/dist/esm/app/CreateApp.mjs +118 -110
- package/dist/esm/app/CreateApp.mjs.map +1 -1
- package/dist/esm/app/CreateApp.native.js +127 -123
- package/dist/esm/app/CreateApp.native.js.map +1 -1
- package/package.json +12 -12
- package/src/app/CreateApp.providers.spec.tsx +317 -0
- package/src/app/CreateApp.tsx +204 -196
- package/types/app/CreateApp.d.ts.map +1 -1
package/src/app/CreateApp.tsx
CHANGED
|
@@ -250,6 +250,206 @@ export interface AppProviderProps extends PropsWithChildren {
|
|
|
250
250
|
|
|
251
251
|
const AppConfigContext = createContext<CreateAppConfig>({});
|
|
252
252
|
|
|
253
|
+
// -- TanStack (outermost built-in, eagerly loaded) -------------------------
|
|
254
|
+
function tanstackBuiltin(
|
|
255
|
+
tanstack: TanstackConfig | true,
|
|
256
|
+
theme: CreateAppConfig["theme"],
|
|
257
|
+
): ProviderComponent {
|
|
258
|
+
const cfg: TanstackConfig = tanstack === true ? {} : { ...tanstack };
|
|
259
|
+
// Inject the Tamagui config so the devtools panel can read theme colors
|
|
260
|
+
if (theme?.tamagui && !cfg.tamaguiConfig) {
|
|
261
|
+
cfg.tamaguiConfig = theme.tamagui;
|
|
262
|
+
}
|
|
263
|
+
return createTanstackProvider(cfg);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// -- Web3 (lazy-loaded) ----------------------------------------------------
|
|
267
|
+
function web3Builtin(web3: Web3AppConfig | true): ProviderComponent {
|
|
268
|
+
const cfg: Web3AppConfig = web3 === true ? {} : web3;
|
|
269
|
+
|
|
270
|
+
function Web3Provider({ children }: PropsWithChildren) {
|
|
271
|
+
const enabled = cfg.enabled ?? config.get("WEB3_ENABLED") === "1";
|
|
272
|
+
if (!enabled) return children;
|
|
273
|
+
|
|
274
|
+
// On web the WagmiProvider must NOT sit above the router: it can't be
|
|
275
|
+
// server-rendered (wagmi/connectkit throw under the SSR ESM evaluator), so
|
|
276
|
+
// mounting it only on the client changes the element type above the
|
|
277
|
+
// navigator on hydration and remounts it → "Another navigator is already
|
|
278
|
+
// registered". Instead, web mounts the provider at screen scope (below the
|
|
279
|
+
// navigator) — see features/wallet/screen.tsx. Native has no SSR/navigator
|
|
280
|
+
// conflict, so it keeps the global provider here. Config is still available
|
|
281
|
+
// to the screen via useAppConfig().web3.
|
|
282
|
+
if (isWeb) return children;
|
|
283
|
+
|
|
284
|
+
const testnetsEnabled = cfg.enableTestnets ?? config.get("WEB3_TESTNETS_ENABLED") === "1";
|
|
285
|
+
|
|
286
|
+
const WalletWithChildren = LazyWalletProvider as unknown as ComponentType<
|
|
287
|
+
PropsWithChildren<{ config: Record<string, unknown> }>
|
|
288
|
+
>;
|
|
289
|
+
return (
|
|
290
|
+
// fallback must NOT be `children`: rendering web3-consuming screens before
|
|
291
|
+
// the lazy WagmiProvider loads throws "useConfig must be used within WagmiProvider".
|
|
292
|
+
<Suspense fallback={null}>
|
|
293
|
+
<WalletWithChildren
|
|
294
|
+
config={{
|
|
295
|
+
appName: cfg.appName || "Multiplatform.one",
|
|
296
|
+
appDescription: cfg.appDescription || "Connect your wallet",
|
|
297
|
+
appUrl:
|
|
298
|
+
cfg.appUrl || (isWeb && typeof window !== "undefined" ? window.location.origin : ""),
|
|
299
|
+
appIcon: cfg.appIcon,
|
|
300
|
+
enableTestnets: testnetsEnabled,
|
|
301
|
+
localnet: cfg.localnet ?? config.get("WEB3_LOCALNET_ENABLED") === "1",
|
|
302
|
+
localnetRpcUrl: cfg.localnetRpcUrl || config.get("WEB3_EVM_RPC") || undefined,
|
|
303
|
+
solanaRpcUrl: cfg.solanaRpcUrl || config.get("WEB3_SOLANA_RPC") || undefined,
|
|
304
|
+
suiRpcUrl: cfg.suiRpcUrl || config.get("WEB3_SUI_RPC") || undefined,
|
|
305
|
+
webViewUrl: cfg.webViewUrl || config.get("WEB3_WEBVIEW_URL") || undefined,
|
|
306
|
+
mockWallet: cfg.mockWallet ?? config.get("WEB3_MOCK_WALLET") === "1",
|
|
307
|
+
}}
|
|
308
|
+
>
|
|
309
|
+
{children}
|
|
310
|
+
</WalletWithChildren>
|
|
311
|
+
</Suspense>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
Web3Provider.displayName = "Web3Provider";
|
|
315
|
+
return Web3Provider;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// -- Keycloak (lazy-loaded) ------------------------------------------------
|
|
319
|
+
function keycloakBuiltin(keycloak: KeycloakConfig | true): ProviderComponent {
|
|
320
|
+
const cfg: KeycloakConfig = keycloak === true ? {} : keycloak;
|
|
321
|
+
const LazyKeycloakProvider = lazy(async () => {
|
|
322
|
+
const mod = await import("@multiplatform.one/keycloak");
|
|
323
|
+
return {
|
|
324
|
+
default: mod.KeycloakProvider as ComponentType<
|
|
325
|
+
PropsWithChildren<{
|
|
326
|
+
disabled?: boolean;
|
|
327
|
+
debug?: boolean;
|
|
328
|
+
baseUrl?: string;
|
|
329
|
+
clientId?: string;
|
|
330
|
+
publicClientId?: string;
|
|
331
|
+
realm?: string;
|
|
332
|
+
iframeSso?: boolean;
|
|
333
|
+
loginRedirectUri?: string;
|
|
334
|
+
messageHandlerKeys?: string[];
|
|
335
|
+
betterAuthBaseUrl?: string;
|
|
336
|
+
expoScheme?: string;
|
|
337
|
+
loadingComponent?: ComponentType;
|
|
338
|
+
}>
|
|
339
|
+
>,
|
|
340
|
+
};
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
function KeycloakProviderWrapper({ children }: PropsWithChildren) {
|
|
344
|
+
const enabled = cfg.enabled ?? config.get("KEYCLOAK_ENABLED") === "1";
|
|
345
|
+
if (!enabled) return children;
|
|
346
|
+
|
|
347
|
+
return (
|
|
348
|
+
<Suspense fallback={children}>
|
|
349
|
+
<LazyKeycloakProvider
|
|
350
|
+
disabled={false}
|
|
351
|
+
debug={cfg.debug ?? config.get("DEBUG") === "1"}
|
|
352
|
+
baseUrl={
|
|
353
|
+
cfg.baseUrl || config.get("KEYCLOAK_BASE_URL") || `${config.get("BASE_URL") || ""}/auth`
|
|
354
|
+
}
|
|
355
|
+
clientId={cfg.clientId || config.get("KEYCLOAK_CLIENT_ID")}
|
|
356
|
+
publicClientId={cfg.publicClientId || config.get("KEYCLOAK_PUBLIC_CLIENT_ID")}
|
|
357
|
+
realm={cfg.realm || config.get("KEYCLOAK_REALM") || ""}
|
|
358
|
+
iframeSso={cfg.iframeSso}
|
|
359
|
+
loginRedirectUri={cfg.loginRedirectUri}
|
|
360
|
+
messageHandlerKeys={cfg.messageHandlerKeys || []}
|
|
361
|
+
betterAuthBaseUrl={
|
|
362
|
+
cfg.betterAuthBaseUrl ||
|
|
363
|
+
config.get("BETTER_AUTH_BASE_URL") ||
|
|
364
|
+
config.get("BASE_URL") ||
|
|
365
|
+
undefined
|
|
366
|
+
}
|
|
367
|
+
expoScheme={cfg.expoScheme}
|
|
368
|
+
loadingComponent={cfg.loadingComponent}
|
|
369
|
+
>
|
|
370
|
+
{children}
|
|
371
|
+
</LazyKeycloakProvider>
|
|
372
|
+
</Suspense>
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
KeycloakProviderWrapper.displayName = "KeycloakProvider";
|
|
376
|
+
return KeycloakProviderWrapper;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// -- Frappe (eagerly imported) ---------------------------------------------
|
|
380
|
+
// NOT lazy: a lazy()+Suspense boundary here remounts the router subtree when
|
|
381
|
+
// the (large) frappe-ui chunk resolves, which resets one's navigation to the
|
|
382
|
+
// index route — so deep-loading e.g. /wallet snapped back to /. (fallback=null
|
|
383
|
+
// doesn't help; the remount is from the lazy boundary resolving, not the
|
|
384
|
+
// fallback content.) frappe-ui is on the critical path for this app anyway.
|
|
385
|
+
function frappeBuiltin(frappe: FrappeConfig | true, withKeycloak: boolean): ProviderComponent {
|
|
386
|
+
const cfg: FrappeConfig = frappe === true ? {} : frappe;
|
|
387
|
+
|
|
388
|
+
// Keycloak auth uses ONE transport on every platform: the HttpClient
|
|
389
|
+
// and the Socket.IO handshake send `Authorization: Bearer <keycloak
|
|
390
|
+
// access token>`, fetched lazily from better-auth's /get-access-token
|
|
391
|
+
// (which refreshes server-side; SecureStore jar on native, session
|
|
392
|
+
// cookie on web). The bench's frappe_keycloak auth hook validates the
|
|
393
|
+
// JWT. Cookies alone can't cover realtime: frappe's socketio middleware
|
|
394
|
+
// only accepts a frappe `sid` cookie or an Authorization header, so the
|
|
395
|
+
// better-auth account cookie never authenticated the socket on web.
|
|
396
|
+
// When signed out the getter resolves undefined and requests fall back
|
|
397
|
+
// to guest.
|
|
398
|
+
const auth =
|
|
399
|
+
cfg.auth ??
|
|
400
|
+
(withKeycloak
|
|
401
|
+
? {
|
|
402
|
+
useToken: true,
|
|
403
|
+
type: "Bearer",
|
|
404
|
+
token: async () => {
|
|
405
|
+
const mod = await import("@multiplatform.one/keycloak");
|
|
406
|
+
return (await mod.getKeycloakBearerToken()) || "";
|
|
407
|
+
},
|
|
408
|
+
}
|
|
409
|
+
: undefined);
|
|
410
|
+
|
|
411
|
+
function FrappeProviderWrapper({ children }: PropsWithChildren) {
|
|
412
|
+
const configuredCatchUp = config.get("FRAPPE_CATCH_UP_STRATEGY");
|
|
413
|
+
const configuredWrite = config.get("FRAPPE_WRITE_STRATEGY");
|
|
414
|
+
const syncOptions = useMemo(
|
|
415
|
+
() => frappeSyncOptions(cfg.syncOptions, configuredCatchUp, configuredWrite),
|
|
416
|
+
[configuredCatchUp, configuredWrite],
|
|
417
|
+
);
|
|
418
|
+
// A fixture corpus is an explicit opt-in, so it enables the provider
|
|
419
|
+
// without FRAPPE_ENABLED=1 in .env.
|
|
420
|
+
const enabled = cfg.enabled ?? (!!cfg.fixtures || config.get("FRAPPE_ENABLED") === "1");
|
|
421
|
+
if (!enabled) return children;
|
|
422
|
+
|
|
423
|
+
// LAN dev: a loopback-configured bench follows the page origin's host
|
|
424
|
+
// (the Socket.IO URL derives from baseURL too, so realtime follows).
|
|
425
|
+
// Fixture mode takes NO fallback: BASE_URL is the app's own origin and
|
|
426
|
+
// localhost:8000 is a bench that is not running, and dialling either
|
|
427
|
+
// would turn a fixtures-only app's misses into failed requests.
|
|
428
|
+
const configured = cfg.fixtures
|
|
429
|
+
? cfg.baseURL
|
|
430
|
+
: cfg.baseURL || config.get("BASE_URL") || "http://localhost:8000";
|
|
431
|
+
const baseURL = configured ? followPageOriginForLoopback(configured) : undefined;
|
|
432
|
+
const socketPort =
|
|
433
|
+
cfg.socketPort ?? frappeSocketPort(config.get("FRAPPE_SOCKETIO_PORT"), baseURL);
|
|
434
|
+
|
|
435
|
+
return (
|
|
436
|
+
<FrappeProvider
|
|
437
|
+
baseURL={baseURL}
|
|
438
|
+
realtime={cfg.realtime}
|
|
439
|
+
socketPort={socketPort}
|
|
440
|
+
auth={auth}
|
|
441
|
+
syncOptions={syncOptions}
|
|
442
|
+
fixtures={cfg.fixtures}
|
|
443
|
+
navigation={oneFrappeNavigation}
|
|
444
|
+
>
|
|
445
|
+
{children}
|
|
446
|
+
</FrappeProvider>
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
FrappeProviderWrapper.displayName = "FrappeProvider";
|
|
450
|
+
return FrappeProviderWrapper;
|
|
451
|
+
}
|
|
452
|
+
|
|
253
453
|
// ---------------------------------------------------------------------------
|
|
254
454
|
// createApp
|
|
255
455
|
// ---------------------------------------------------------------------------
|
|
@@ -264,205 +464,13 @@ const AppConfigContext = createContext<CreateAppConfig>({});
|
|
|
264
464
|
*/
|
|
265
465
|
export function createApp(appConfig: CreateAppConfig) {
|
|
266
466
|
const builtinProviders: ProviderComponent[] = [];
|
|
267
|
-
|
|
268
|
-
// -- TanStack (outermost built-in, eagerly loaded) -------------------------
|
|
269
467
|
if (appConfig.tanstack) {
|
|
270
|
-
|
|
271
|
-
// Inject the Tamagui config so the devtools panel can read theme colors
|
|
272
|
-
if (appConfig.theme?.tamagui && !cfg.tamaguiConfig) {
|
|
273
|
-
cfg.tamaguiConfig = appConfig.theme.tamagui;
|
|
274
|
-
}
|
|
275
|
-
builtinProviders.push(createTanstackProvider(cfg));
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// -- Web3 (lazy-loaded) ----------------------------------------------------
|
|
279
|
-
if (appConfig.web3) {
|
|
280
|
-
const cfg: Web3AppConfig = appConfig.web3 === true ? {} : appConfig.web3;
|
|
281
|
-
|
|
282
|
-
function Web3Provider({ children }: PropsWithChildren) {
|
|
283
|
-
const enabled = cfg.enabled ?? config.get("WEB3_ENABLED") === "1";
|
|
284
|
-
if (!enabled) return children;
|
|
285
|
-
|
|
286
|
-
// On web the WagmiProvider must NOT sit above the router: it can't be
|
|
287
|
-
// server-rendered (wagmi/connectkit throw under the SSR ESM evaluator), so
|
|
288
|
-
// mounting it only on the client changes the element type above the
|
|
289
|
-
// navigator on hydration and remounts it → "Another navigator is already
|
|
290
|
-
// registered". Instead, web mounts the provider at screen scope (below the
|
|
291
|
-
// navigator) — see features/wallet/screen.tsx. Native has no SSR/navigator
|
|
292
|
-
// conflict, so it keeps the global provider here. Config is still available
|
|
293
|
-
// to the screen via useAppConfig().web3.
|
|
294
|
-
if (isWeb) return children;
|
|
295
|
-
|
|
296
|
-
const testnetsEnabled = cfg.enableTestnets ?? config.get("WEB3_TESTNETS_ENABLED") === "1";
|
|
297
|
-
|
|
298
|
-
const WalletWithChildren = LazyWalletProvider as unknown as ComponentType<
|
|
299
|
-
PropsWithChildren<{ config: Record<string, unknown> }>
|
|
300
|
-
>;
|
|
301
|
-
return (
|
|
302
|
-
// fallback must NOT be `children`: rendering web3-consuming screens before
|
|
303
|
-
// the lazy WagmiProvider loads throws "useConfig must be used within WagmiProvider".
|
|
304
|
-
<Suspense fallback={null}>
|
|
305
|
-
<WalletWithChildren
|
|
306
|
-
config={{
|
|
307
|
-
appName: cfg.appName || "Multiplatform.one",
|
|
308
|
-
appDescription: cfg.appDescription || "Connect your wallet",
|
|
309
|
-
appUrl:
|
|
310
|
-
cfg.appUrl ||
|
|
311
|
-
(isWeb && typeof window !== "undefined" ? window.location.origin : ""),
|
|
312
|
-
appIcon: cfg.appIcon,
|
|
313
|
-
enableTestnets: testnetsEnabled,
|
|
314
|
-
localnet: cfg.localnet ?? config.get("WEB3_LOCALNET_ENABLED") === "1",
|
|
315
|
-
localnetRpcUrl: cfg.localnetRpcUrl || config.get("WEB3_EVM_RPC") || undefined,
|
|
316
|
-
solanaRpcUrl: cfg.solanaRpcUrl || config.get("WEB3_SOLANA_RPC") || undefined,
|
|
317
|
-
suiRpcUrl: cfg.suiRpcUrl || config.get("WEB3_SUI_RPC") || undefined,
|
|
318
|
-
webViewUrl: cfg.webViewUrl || config.get("WEB3_WEBVIEW_URL") || undefined,
|
|
319
|
-
mockWallet: cfg.mockWallet ?? config.get("WEB3_MOCK_WALLET") === "1",
|
|
320
|
-
}}
|
|
321
|
-
>
|
|
322
|
-
{children}
|
|
323
|
-
</WalletWithChildren>
|
|
324
|
-
</Suspense>
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
Web3Provider.displayName = "Web3Provider";
|
|
328
|
-
builtinProviders.push(Web3Provider);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// -- Keycloak (lazy-loaded) ------------------------------------------------
|
|
332
|
-
if (appConfig.keycloak) {
|
|
333
|
-
const cfg: KeycloakConfig = appConfig.keycloak === true ? {} : appConfig.keycloak;
|
|
334
|
-
const LazyKeycloakProvider = lazy(async () => {
|
|
335
|
-
const mod = await import("@multiplatform.one/keycloak");
|
|
336
|
-
return {
|
|
337
|
-
default: mod.KeycloakProvider as ComponentType<
|
|
338
|
-
PropsWithChildren<{
|
|
339
|
-
disabled?: boolean;
|
|
340
|
-
debug?: boolean;
|
|
341
|
-
baseUrl?: string;
|
|
342
|
-
clientId?: string;
|
|
343
|
-
publicClientId?: string;
|
|
344
|
-
realm?: string;
|
|
345
|
-
iframeSso?: boolean;
|
|
346
|
-
loginRedirectUri?: string;
|
|
347
|
-
messageHandlerKeys?: string[];
|
|
348
|
-
betterAuthBaseUrl?: string;
|
|
349
|
-
expoScheme?: string;
|
|
350
|
-
loadingComponent?: ComponentType;
|
|
351
|
-
}>
|
|
352
|
-
>,
|
|
353
|
-
};
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
function KeycloakProviderWrapper({ children }: PropsWithChildren) {
|
|
357
|
-
const enabled = cfg.enabled ?? config.get("KEYCLOAK_ENABLED") === "1";
|
|
358
|
-
if (!enabled) return children;
|
|
359
|
-
|
|
360
|
-
return (
|
|
361
|
-
<Suspense fallback={children}>
|
|
362
|
-
<LazyKeycloakProvider
|
|
363
|
-
disabled={false}
|
|
364
|
-
debug={cfg.debug ?? config.get("DEBUG") === "1"}
|
|
365
|
-
baseUrl={
|
|
366
|
-
cfg.baseUrl ||
|
|
367
|
-
config.get("KEYCLOAK_BASE_URL") ||
|
|
368
|
-
`${config.get("BASE_URL") || ""}/auth`
|
|
369
|
-
}
|
|
370
|
-
clientId={cfg.clientId || config.get("KEYCLOAK_CLIENT_ID")}
|
|
371
|
-
publicClientId={cfg.publicClientId || config.get("KEYCLOAK_PUBLIC_CLIENT_ID")}
|
|
372
|
-
realm={cfg.realm || config.get("KEYCLOAK_REALM") || ""}
|
|
373
|
-
iframeSso={cfg.iframeSso}
|
|
374
|
-
loginRedirectUri={cfg.loginRedirectUri}
|
|
375
|
-
messageHandlerKeys={cfg.messageHandlerKeys || []}
|
|
376
|
-
betterAuthBaseUrl={
|
|
377
|
-
cfg.betterAuthBaseUrl ||
|
|
378
|
-
config.get("BETTER_AUTH_BASE_URL") ||
|
|
379
|
-
config.get("BASE_URL") ||
|
|
380
|
-
undefined
|
|
381
|
-
}
|
|
382
|
-
expoScheme={cfg.expoScheme}
|
|
383
|
-
loadingComponent={cfg.loadingComponent}
|
|
384
|
-
>
|
|
385
|
-
{children}
|
|
386
|
-
</LazyKeycloakProvider>
|
|
387
|
-
</Suspense>
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
KeycloakProviderWrapper.displayName = "KeycloakProvider";
|
|
391
|
-
builtinProviders.push(KeycloakProviderWrapper);
|
|
468
|
+
builtinProviders.push(tanstackBuiltin(appConfig.tanstack, appConfig.theme));
|
|
392
469
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
// NOT lazy: a lazy()+Suspense boundary here remounts the router subtree when
|
|
396
|
-
// the (large) frappe-ui chunk resolves, which resets one's navigation to the
|
|
397
|
-
// index route — so deep-loading e.g. /wallet snapped back to /. (fallback=null
|
|
398
|
-
// doesn't help; the remount is from the lazy boundary resolving, not the
|
|
399
|
-
// fallback content.) frappe-ui is on the critical path for this app anyway.
|
|
470
|
+
if (appConfig.web3) builtinProviders.push(web3Builtin(appConfig.web3));
|
|
471
|
+
if (appConfig.keycloak) builtinProviders.push(keycloakBuiltin(appConfig.keycloak));
|
|
400
472
|
if (appConfig.frappe) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
// Keycloak auth uses ONE transport on every platform: the HttpClient
|
|
404
|
-
// and the Socket.IO handshake send `Authorization: Bearer <keycloak
|
|
405
|
-
// access token>`, fetched lazily from better-auth's /get-access-token
|
|
406
|
-
// (which refreshes server-side; SecureStore jar on native, session
|
|
407
|
-
// cookie on web). The bench's frappe_keycloak auth hook validates the
|
|
408
|
-
// JWT. Cookies alone can't cover realtime: frappe's socketio middleware
|
|
409
|
-
// only accepts a frappe `sid` cookie or an Authorization header, so the
|
|
410
|
-
// better-auth account cookie never authenticated the socket on web.
|
|
411
|
-
// When signed out the getter resolves undefined and requests fall back
|
|
412
|
-
// to guest.
|
|
413
|
-
const auth =
|
|
414
|
-
cfg.auth ??
|
|
415
|
-
(appConfig.keycloak
|
|
416
|
-
? {
|
|
417
|
-
useToken: true,
|
|
418
|
-
type: "Bearer",
|
|
419
|
-
token: async () => {
|
|
420
|
-
const mod = await import("@multiplatform.one/keycloak");
|
|
421
|
-
return (await mod.getKeycloakBearerToken()) || "";
|
|
422
|
-
},
|
|
423
|
-
}
|
|
424
|
-
: undefined);
|
|
425
|
-
|
|
426
|
-
function FrappeProviderWrapper({ children }: PropsWithChildren) {
|
|
427
|
-
const configuredCatchUp = config.get("FRAPPE_CATCH_UP_STRATEGY");
|
|
428
|
-
const configuredWrite = config.get("FRAPPE_WRITE_STRATEGY");
|
|
429
|
-
const syncOptions = useMemo(
|
|
430
|
-
() => frappeSyncOptions(cfg.syncOptions, configuredCatchUp, configuredWrite),
|
|
431
|
-
[configuredCatchUp, configuredWrite],
|
|
432
|
-
);
|
|
433
|
-
// A fixture corpus is an explicit opt-in, so it enables the provider
|
|
434
|
-
// without FRAPPE_ENABLED=1 in .env.
|
|
435
|
-
const enabled = cfg.enabled ?? (!!cfg.fixtures || config.get("FRAPPE_ENABLED") === "1");
|
|
436
|
-
if (!enabled) return children;
|
|
437
|
-
|
|
438
|
-
// LAN dev: a loopback-configured bench follows the page origin's host
|
|
439
|
-
// (the Socket.IO URL derives from baseURL too, so realtime follows).
|
|
440
|
-
// Fixture mode takes NO fallback: BASE_URL is the app's own origin and
|
|
441
|
-
// localhost:8000 is a bench that is not running, and dialling either
|
|
442
|
-
// would turn a fixtures-only app's misses into failed requests.
|
|
443
|
-
const configured = cfg.fixtures
|
|
444
|
-
? cfg.baseURL
|
|
445
|
-
: cfg.baseURL || config.get("BASE_URL") || "http://localhost:8000";
|
|
446
|
-
const baseURL = configured ? followPageOriginForLoopback(configured) : undefined;
|
|
447
|
-
const socketPort =
|
|
448
|
-
cfg.socketPort ?? frappeSocketPort(config.get("FRAPPE_SOCKETIO_PORT"), baseURL);
|
|
449
|
-
|
|
450
|
-
return (
|
|
451
|
-
<FrappeProvider
|
|
452
|
-
baseURL={baseURL}
|
|
453
|
-
realtime={cfg.realtime}
|
|
454
|
-
socketPort={socketPort}
|
|
455
|
-
auth={auth}
|
|
456
|
-
syncOptions={syncOptions}
|
|
457
|
-
fixtures={cfg.fixtures}
|
|
458
|
-
navigation={oneFrappeNavigation}
|
|
459
|
-
>
|
|
460
|
-
{children}
|
|
461
|
-
</FrappeProvider>
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
FrappeProviderWrapper.displayName = "FrappeProvider";
|
|
465
|
-
builtinProviders.push(FrappeProviderWrapper);
|
|
473
|
+
builtinProviders.push(frappeBuiltin(appConfig.frappe, Boolean(appConfig.keycloak)));
|
|
466
474
|
}
|
|
467
475
|
|
|
468
476
|
// -- Combine: builtin → custom providers (theme is innermost) --------------
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateApp.d.ts","sourceRoot":"","sources":["../../src/app/CreateApp.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"CreateApp.d.ts","sourceRoot":"","sources":["../../src/app/CreateApp.tsx"],"names":[],"mappings":"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"}
|