@frontera-sdk/core 1.50.82 → 1.50.83

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontera-sdk/core",
3
- "version": "1.50.82",
3
+ "version": "1.50.83",
4
4
  "description": "Frontera app runtime: the platform bridge client, app bootstrap and typed platform client.",
5
5
  "keywords": [
6
6
  "frontera",
@@ -36,6 +36,33 @@ export interface BridgeInit {
36
36
  */
37
37
  path?: string
38
38
  active?: boolean
39
+ /**
40
+ * The person who opened the app: what it may SHOW and use as a default —
41
+ * "you", "assigned to me", an owner field — without asking them to type
42
+ * who they are. `email` is the account email and may be null. Absent on a
43
+ * host that predates it and for an app hosted outside Frontera; null when no
44
+ * person is involved (a CLI key). Never an authorization input: what the app
45
+ * may do is decided server-side from the token.
46
+ */
47
+ viewer?: FronteraViewer | null
48
+ }
49
+
50
+ export interface FronteraViewer {
51
+ userId: string
52
+ name: string | null
53
+ email: string | null
54
+ }
55
+
56
+ /** A well-formed viewer, or null. The host is trusted; the shape still is not assumed. */
57
+ export function viewerOf(value: unknown): FronteraViewer | null {
58
+ if (!value || typeof value !== 'object') return null
59
+ const v = value as Record<string, unknown>
60
+ if (typeof v.userId !== 'string' || !v.userId) return null
61
+ return {
62
+ userId: v.userId,
63
+ name: typeof v.name === 'string' && v.name.trim() ? v.name : null,
64
+ email: typeof v.email === 'string' && v.email.includes('@') ? v.email : null,
65
+ }
39
66
  }
40
67
 
41
68
  export type HostMessage =
@@ -13,7 +13,7 @@ import { createRoot } from 'react-dom/client'
13
13
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
14
14
 
15
15
  import { connectToHost, type BridgeSession } from './bridge-client'
16
- import type { BridgeInit } from './bridge-protocol'
16
+ import { viewerOf, type BridgeInit, type FronteraViewer } from './bridge-protocol'
17
17
  import { FronteraClient } from './client'
18
18
  import { readRuntimeGlobal } from './config'
19
19
  import {
@@ -50,6 +50,12 @@ export interface FronteraAppValue {
50
50
  setUnsavedChanges(dirty: boolean): void
51
51
  /** Ask the platform to change its URL — the counterpart to `init.path`. */
52
52
  navigate(path: string): void
53
+ /**
54
+ * Who opened the app, from the host at handshake — or null when the host
55
+ * did not say (an older host, or no person, as with a CLI key). Use it to
56
+ * show and prefill; never to decide what the person may do.
57
+ */
58
+ viewer: FronteraViewer | null
53
59
  }
54
60
 
55
61
  const FronteraAppReactContext = createContext<FronteraAppValue | null>(null)
@@ -64,6 +70,16 @@ export function useFronteraApp(): FronteraAppValue {
64
70
  return value
65
71
  }
66
72
 
73
+ /**
74
+ * The person who opened the app, or null when the host did not say.
75
+ *
76
+ * Shorthand for `useFronteraApp().viewer`: the common read, so an app does not
77
+ * have to ask a person to type who they are.
78
+ */
79
+ export function useViewer(): FronteraViewer | null {
80
+ return useFronteraApp().viewer
81
+ }
82
+
67
83
  /**
68
84
  * A wrapper contributed by a domain package.
69
85
  *
@@ -404,6 +420,7 @@ function FronteraRoot({
404
420
  navigate: (path) => {
405
421
  if (mode === 'embedded') session.send({ type: 'frontera:navigate', path })
406
422
  },
423
+ viewer: viewerOf(init.viewer),
407
424
  }
408
425
 
409
426
  let tree: ReactNode = children
package/src/react.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  export {
2
2
  FronteraAppProvider,
3
3
  useFronteraApp,
4
+ useViewer,
4
5
  type FronteraAppProviderProps,
5
6
  type FronteraAppValue,
6
7
  type FronteraProvider,
7
8
  } from './create-frontera-app'
8
9
  export type { FronteraAppMode } from './app-session'
10
+ export type { FronteraViewer } from './bridge-protocol'
9
11
  export {
10
12
  AppUserSignInError,
11
13
  exchangeCustomerToken,