@declarion/react 0.1.91 → 0.1.92
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-lib/{DraggableChildrenTable-BNjHMCeC.js → DraggableChildrenTable-IfspXSFA.js} +41 -41
- package/dist-lib/{DraggableChildrenTable-BNjHMCeC.js.map → DraggableChildrenTable-IfspXSFA.js.map} +1 -1
- package/dist-lib/Grid-C69-4exi.js +405 -0
- package/dist-lib/Grid-C69-4exi.js.map +1 -0
- package/dist-lib/api/data.d.ts +1 -0
- package/dist-lib/api/events.d.ts +14 -0
- package/dist-lib/components/detail-layout/AssociatedBlock.d.ts +4 -1
- package/dist-lib/components/file-widgets/helpers.d.ts +2 -0
- package/dist-lib/components/file-widgets/useEmbedFileSrc.d.ts +42 -0
- package/dist-lib/declarion-react.css +1 -1
- package/dist-lib/embed/EmbedAuthBootstrap.d.ts +8 -0
- package/dist-lib/embed/EmbedContext.d.ts +50 -0
- package/dist-lib/embed/EmbedDirtyReporter.d.ts +10 -0
- package/dist-lib/embed/EmbedLocationReporter.d.ts +8 -0
- package/dist-lib/embed/EmbedResizeReporter.d.ts +6 -0
- package/dist-lib/embed/EmbedUnsavedGuard.d.ts +7 -0
- package/dist-lib/embed/embed-dirty.d.ts +24 -0
- package/dist-lib/embed/embed-nav-guard.d.ts +20 -0
- package/dist-lib/embed/file-src.d.ts +63 -0
- package/dist-lib/embed/handshake.d.ts +57 -0
- package/dist-lib/embed/index.d.ts +15 -0
- package/dist-lib/embed/params.d.ts +75 -0
- package/dist-lib/embed/protocol.d.ts +138 -0
- package/dist-lib/embed/screen-location.d.ts +20 -0
- package/dist-lib/embed/theme.d.ts +34 -0
- package/dist-lib/embed/token.d.ts +57 -0
- package/dist-lib/embed/useEmbedNavigate.d.ts +27 -0
- package/dist-lib/index.js +4678 -4261
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/{useUserLocale-DyXRSWj9.js → useUserLocale-GBIXbEE6.js} +1656 -1659
- package/dist-lib/useUserLocale-GBIXbEE6.js.map +1 -0
- package/dist-lib/value-DFpIiSZ-.js +739 -0
- package/dist-lib/value-DFpIiSZ-.js.map +1 -0
- package/package.json +1 -1
- package/dist-lib/Grid-BJAiAeHo.js +0 -405
- package/dist-lib/Grid-BJAiAeHo.js.map +0 -1
- package/dist-lib/useUserLocale-DyXRSWj9.js.map +0 -1
- package/dist-lib/value-Bhy_PJo2.js +0 -535
- package/dist-lib/value-Bhy_PJo2.js.map +0 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `source` discriminator stamped on every embed frame. The host SDK and
|
|
3
|
+
* the iframe both filter inbound messages on this value so unrelated
|
|
4
|
+
* `postMessage` traffic (browser extensions, other widgets) is ignored.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EMBED_MESSAGE_SOURCE: "declarion-embed";
|
|
7
|
+
/**
|
|
8
|
+
* The protocol version. Bumped only on a breaking envelope/payload change.
|
|
9
|
+
* The host SDK warns when its version and the iframe's version differ.
|
|
10
|
+
*/
|
|
11
|
+
export declare const EMBED_PROTOCOL_VERSION: 1;
|
|
12
|
+
/**
|
|
13
|
+
* Every protocol message `type`. The object key is the camelCase name used in
|
|
14
|
+
* code; the value is the on-wire string. Events (iframe -> host) are past
|
|
15
|
+
* tense; commands (host -> iframe) are imperative - see the naming contract
|
|
16
|
+
* at the top of this file.
|
|
17
|
+
*/
|
|
18
|
+
export declare const EMBED_MESSAGE_TYPES: {
|
|
19
|
+
/** iframe -> host: SDK mounted, requests the first token. */
|
|
20
|
+
readonly ready: "ready";
|
|
21
|
+
/** host -> iframe: deliver or refresh the embed token. */
|
|
22
|
+
readonly setToken: "set-token";
|
|
23
|
+
/** iframe -> host: token rejected or near expiry. */
|
|
24
|
+
readonly tokenExpired: "token-expired";
|
|
25
|
+
/** iframe -> host: the iframe must be reloaded. */
|
|
26
|
+
readonly reloadRequired: "reload-required";
|
|
27
|
+
/** iframe -> host: embed content height changed. */
|
|
28
|
+
readonly resized: "resized";
|
|
29
|
+
/** iframe -> host: `self` mode internal navigation happened. */
|
|
30
|
+
readonly navigated: "navigated";
|
|
31
|
+
/** iframe -> host: `delegated` mode navigation requested, iframe stayed. */
|
|
32
|
+
readonly navigationRequested: "navigation-requested";
|
|
33
|
+
/** iframe -> host: the embedded screen's unsaved-edits state flipped. */
|
|
34
|
+
readonly dirtyChanged: "dirty-changed";
|
|
35
|
+
/** host -> iframe: drive the iframe to a screen (deep-linking). */
|
|
36
|
+
readonly navigate: "navigate";
|
|
37
|
+
/** host -> iframe: runtime theme switch. */
|
|
38
|
+
readonly setTheme: "set-theme";
|
|
39
|
+
};
|
|
40
|
+
/** The union of all on-wire message `type` strings. */
|
|
41
|
+
export type EmbedMessageType = (typeof EMBED_MESSAGE_TYPES)[keyof typeof EMBED_MESSAGE_TYPES];
|
|
42
|
+
/** `ready` payload: empty - the frame itself is the signal. */
|
|
43
|
+
export type EmbedReadyPayload = Record<string, never>;
|
|
44
|
+
/** `set-token` payload: the embed token and its absolute expiry. */
|
|
45
|
+
export interface EmbedSetTokenPayload {
|
|
46
|
+
/** The scoped, refresh-less embed JWT. */
|
|
47
|
+
readonly token: string;
|
|
48
|
+
/** RFC 3339 expiry timestamp of the token. */
|
|
49
|
+
readonly expires_at: string;
|
|
50
|
+
}
|
|
51
|
+
/** `token-expired` payload: empty - the host re-mints via `getToken`. */
|
|
52
|
+
export type EmbedTokenExpiredPayload = Record<string, never>;
|
|
53
|
+
/** `reload-required` payload: a human-readable reason for the reload. */
|
|
54
|
+
export interface EmbedReloadRequiredPayload {
|
|
55
|
+
/** Why the iframe must be reloaded (asset drift, terminal auth failure). */
|
|
56
|
+
readonly reason: string;
|
|
57
|
+
}
|
|
58
|
+
/** `resized` payload: the measured content height in CSS pixels. */
|
|
59
|
+
export interface EmbedResizedPayload {
|
|
60
|
+
/** Content height in CSS pixels. */
|
|
61
|
+
readonly height: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* `navigated` / `navigation-requested` payload: the screen route and, when
|
|
65
|
+
* resolvable, the bound entity code and record id.
|
|
66
|
+
*
|
|
67
|
+
* `entity` and `recordId` are optional: a `custom` screen has no entity, and
|
|
68
|
+
* a list route has no record id.
|
|
69
|
+
*/
|
|
70
|
+
export interface EmbedNavigationPayload {
|
|
71
|
+
/** The Declarion screen route path the navigation targets. */
|
|
72
|
+
readonly route: string;
|
|
73
|
+
/** The bound entity code, when the route resolves to one. */
|
|
74
|
+
readonly entity?: string;
|
|
75
|
+
/** The record id, when the route is a detail route with an id. */
|
|
76
|
+
readonly recordId?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* `dirty-changed` payload: whether the embedded screen currently has unsaved
|
|
80
|
+
* edits. The host tracks this so it can guard its own navigation (its menu,
|
|
81
|
+
* a host-initiated `navigate`) before moving the iframe away from a dirty
|
|
82
|
+
* screen - the iframe never pops a dialog for host-driven navigation.
|
|
83
|
+
*/
|
|
84
|
+
export interface EmbedDirtyChangedPayload {
|
|
85
|
+
/** True when the embedded screen has unsaved edits. */
|
|
86
|
+
readonly dirty: boolean;
|
|
87
|
+
}
|
|
88
|
+
/** `navigate` payload: the route the host drives the iframe to. */
|
|
89
|
+
export interface EmbedNavigatePayload {
|
|
90
|
+
/** The Declarion screen route the host wants opened. */
|
|
91
|
+
readonly route: string;
|
|
92
|
+
}
|
|
93
|
+
/** `set-theme` payload: the theme the host switches the iframe to. */
|
|
94
|
+
export interface EmbedSetThemePayload {
|
|
95
|
+
/** The requested theme. */
|
|
96
|
+
readonly theme: "light" | "dark";
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Maps each message type to its payload shape. Used to type `postToParent`
|
|
100
|
+
* so the payload argument is checked against the message type.
|
|
101
|
+
*/
|
|
102
|
+
export interface EmbedMessagePayloadMap {
|
|
103
|
+
[EMBED_MESSAGE_TYPES.ready]: EmbedReadyPayload;
|
|
104
|
+
[EMBED_MESSAGE_TYPES.setToken]: EmbedSetTokenPayload;
|
|
105
|
+
[EMBED_MESSAGE_TYPES.tokenExpired]: EmbedTokenExpiredPayload;
|
|
106
|
+
[EMBED_MESSAGE_TYPES.reloadRequired]: EmbedReloadRequiredPayload;
|
|
107
|
+
[EMBED_MESSAGE_TYPES.resized]: EmbedResizedPayload;
|
|
108
|
+
[EMBED_MESSAGE_TYPES.navigated]: EmbedNavigationPayload;
|
|
109
|
+
[EMBED_MESSAGE_TYPES.navigationRequested]: EmbedNavigationPayload;
|
|
110
|
+
[EMBED_MESSAGE_TYPES.dirtyChanged]: EmbedDirtyChangedPayload;
|
|
111
|
+
[EMBED_MESSAGE_TYPES.navigate]: EmbedNavigatePayload;
|
|
112
|
+
[EMBED_MESSAGE_TYPES.setTheme]: EmbedSetThemePayload;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The wire envelope. Every embed frame is exactly this shape: a fixed
|
|
116
|
+
* `source` + `protocol` pair, a discriminating `type`, and the typed
|
|
117
|
+
* `payload` for that type.
|
|
118
|
+
*/
|
|
119
|
+
export interface EmbedMessage<T extends EmbedMessageType = EmbedMessageType> {
|
|
120
|
+
readonly source: typeof EMBED_MESSAGE_SOURCE;
|
|
121
|
+
readonly protocol: typeof EMBED_PROTOCOL_VERSION;
|
|
122
|
+
readonly type: T;
|
|
123
|
+
readonly payload: EmbedMessagePayloadMap[T];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Post an enveloped embed message to the host page.
|
|
127
|
+
*
|
|
128
|
+
* Targets the EXACT `parentOrigin` - never `"*"` - so a malicious page that
|
|
129
|
+
* re-frames the iframe cannot intercept auth or navigation frames.
|
|
130
|
+
*
|
|
131
|
+
* No-op (returns false) when:
|
|
132
|
+
* - `parentOrigin` is null or empty (no trusted origin to target), or
|
|
133
|
+
* - the document is not framed (`window.parent === window`), or
|
|
134
|
+
* - there is no `window` (SSR / unit environment without a DOM).
|
|
135
|
+
*
|
|
136
|
+
* Returns true when a message was posted.
|
|
137
|
+
*/
|
|
138
|
+
export declare function postToParent<T extends EmbedMessageType>(parentOrigin: string | null, type: T, payload: EmbedMessagePayloadMap[T]): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EmbedNavigationPayload } from "./protocol";
|
|
2
|
+
import type { Screen } from "../types/schema";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the embed navigation payload for a router pathname.
|
|
5
|
+
*
|
|
6
|
+
* Matches the pathname against every registered screen route. An exact
|
|
7
|
+
* (wildcard-free) route wins over a `:param` route, mirroring
|
|
8
|
+
* `screenTitleForPath`, so `/cases` resolves to the list screen even though
|
|
9
|
+
* the detail route `/cases/:id` also shares the prefix.
|
|
10
|
+
*
|
|
11
|
+
* - `route` is the matched screen's own route pattern, or the raw pathname
|
|
12
|
+
* when no screen owns it (a route always exists in the payload).
|
|
13
|
+
* - `entity` is the matched screen's bound entity code, when it has one.
|
|
14
|
+
* - `recordId` is the last path segment for a detail (`:param`) route, when
|
|
15
|
+
* that segment is present and non-empty.
|
|
16
|
+
*
|
|
17
|
+
* `screens` may be undefined (schema not yet loaded); the payload then
|
|
18
|
+
* carries just the raw pathname as `route`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveEmbedNavigationPayload(pathname: string, screens: Record<string, Screen> | undefined): EmbedNavigationPayload;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type EmbedTheme } from "./params";
|
|
2
|
+
/**
|
|
3
|
+
* Apply an embed theme to <html> immediately, WITHOUT persisting it.
|
|
4
|
+
*
|
|
5
|
+
* The single theme-apply path for embed mode: the pre-paint URL bootstrap
|
|
6
|
+
* (`applyEmbedThemeFromQuery`) and the runtime `theme` postMessage handler
|
|
7
|
+
* both route through here, so they can never diverge.
|
|
8
|
+
*
|
|
9
|
+
* `applyAppearance` is the single writer of <html> theme attributes; it
|
|
10
|
+
* keeps accent / density / etc. intact. The appearance store slice is then
|
|
11
|
+
* set directly (not via `setMany`) so later reads stay consistent WITHOUT
|
|
12
|
+
* writing localStorage - the embed theme is a host-supplied, ephemeral hint,
|
|
13
|
+
* not a user choice.
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyEmbedTheme(theme: EmbedTheme): void;
|
|
16
|
+
/**
|
|
17
|
+
* Read the embed `theme` param from the given query string and, when it is a
|
|
18
|
+
* valid `light`/`dark` value under an active `embed=1`, apply it to
|
|
19
|
+
* <html> immediately.
|
|
20
|
+
*
|
|
21
|
+
* Returns true when an embed theme was applied, false otherwise.
|
|
22
|
+
*
|
|
23
|
+
* Apply path: routes through `applyEmbedTheme`, which writes `data-theme` and
|
|
24
|
+
* updates the appearance store but deliberately does NOT touch localStorage.
|
|
25
|
+
*/
|
|
26
|
+
export declare function applyEmbedThemeFromQuery(query: string | URLSearchParams): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Apply the embed theme from `window.location.search` at module load.
|
|
29
|
+
*
|
|
30
|
+
* Called once from the embed barrel so importing the embed entry point is
|
|
31
|
+
* enough to get pre-paint theming, exactly like the appearance module's
|
|
32
|
+
* own module-load `applyAppearance(initial)`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function applyEmbedThemeFromLocation(): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activate embed token mode. Called once at bootstrap by the embed auth
|
|
3
|
+
* handshake. `parentOrigin` is the exact host origin that `token-expired`
|
|
4
|
+
* frames are emitted to.
|
|
5
|
+
*
|
|
6
|
+
* Idempotent: re-activation only refreshes the parent origin.
|
|
7
|
+
*/
|
|
8
|
+
export declare function initEmbedTokenMode(parentOrigin: string | null): void;
|
|
9
|
+
/**
|
|
10
|
+
* True when embed token mode is active. Transports branch on this to switch
|
|
11
|
+
* from the cookie path to the Bearer path. False everywhere outside an
|
|
12
|
+
* embed iframe, so the cookie path stays byte-equivalent to today.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isEmbedTokenMode(): boolean;
|
|
15
|
+
/** The current embed token string, or null before the first `auth` frame. */
|
|
16
|
+
export declare function getEmbedToken(): string | null;
|
|
17
|
+
/**
|
|
18
|
+
* The exact parent origin embed frames are emitted to, or null before
|
|
19
|
+
* `initEmbedTokenMode` runs. Used by transports outside this module (e.g.
|
|
20
|
+
* the version probe) that need to post a frame to the host.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getEmbedParentOrigin(): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Store a token delivered by the host's `auth` frame.
|
|
25
|
+
*
|
|
26
|
+
* Resolves any in-flight `awaitEmbedToken()` wait so every transport that
|
|
27
|
+
* was blocked on a fresh token unblocks at once. A malformed payload
|
|
28
|
+
* (missing token, unparseable expiry) is ignored - the wait stays pending
|
|
29
|
+
* until a well-formed frame arrives or the timeout fires.
|
|
30
|
+
*/
|
|
31
|
+
export declare function setEmbedToken(payload: {
|
|
32
|
+
token: string;
|
|
33
|
+
expires_at: string;
|
|
34
|
+
}): void;
|
|
35
|
+
/**
|
|
36
|
+
* Clear the held token. Used when a terminal failure makes the current
|
|
37
|
+
* token unusable; the next transport call will await a fresh one.
|
|
38
|
+
*/
|
|
39
|
+
export declare function clearEmbedToken(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Return a usable embed token, requesting a fresh one from the host when
|
|
42
|
+
* needed.
|
|
43
|
+
*
|
|
44
|
+
* SINGLE-FLIGHT: when the held token is still usable it resolves
|
|
45
|
+
* immediately. When the token is missing or stale, it emits exactly one
|
|
46
|
+
* `token-expired` frame to the host and waits for the next `auth` frame.
|
|
47
|
+
* Concurrent callers during that window share the one in-flight wait - the
|
|
48
|
+
* `token-expired` frame is emitted once, not once per caller.
|
|
49
|
+
*
|
|
50
|
+
* The wait is bounded by `TOKEN_WAIT_TIMEOUT_MS`; on timeout the promise
|
|
51
|
+
* rejects so the transport caller fails loudly instead of hanging.
|
|
52
|
+
*/
|
|
53
|
+
export declare function awaitEmbedToken(): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Test-only: reset all module state. Not exposed via package exports.
|
|
56
|
+
*/
|
|
57
|
+
export declare function __resetEmbedTokenForTests(): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type NavigateOptions } from "react-router-dom";
|
|
2
|
+
/**
|
|
3
|
+
* The shared embed navigation policy, decoupled from React Router's hook.
|
|
4
|
+
*
|
|
5
|
+
* `rawNavigate` is the underlying navigator (`useNavigate()`'s return value
|
|
6
|
+
* for `useEmbedNavigate`, the same for `useTabNavigate`). The returned
|
|
7
|
+
* `screenNavigate` applies the embed branch and reports whether it actually
|
|
8
|
+
* navigated:
|
|
9
|
+
*
|
|
10
|
+
* - returns `false` in `delegated` embed mode (intercepted; iframe stayed),
|
|
11
|
+
* - returns `true` otherwise (a real navigation happened).
|
|
12
|
+
*
|
|
13
|
+
* Callers in embed mode use the boolean to skip side effects (opening a tab)
|
|
14
|
+
* that only make sense for a navigation that actually moved.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useEmbedScreenNavigate(): (to: string, opts?: NavigateOptions) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Embed-aware replacement for `useNavigate` at internal screen-route call
|
|
19
|
+
* sites. Returns a `navigate(to, opts)` function with the embed branch
|
|
20
|
+
* applied. Outside embed mode it is `useNavigate()` unchanged.
|
|
21
|
+
*
|
|
22
|
+
* Use this for every raw screen transition (cancel-edit, save success,
|
|
23
|
+
* delete success, Back). Do NOT use it for non-route navigation (anchors,
|
|
24
|
+
* external URLs); those are not screen routes and embed mode does not touch
|
|
25
|
+
* them.
|
|
26
|
+
*/
|
|
27
|
+
export declare function useEmbedNavigate(): (to: string, opts?: NavigateOptions) => void;
|