@usequeek/app-sdk 0.5.1 → 0.6.0

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.
Files changed (74) hide show
  1. package/README.md +166 -12
  2. package/dist/app-auth.d.ts +9 -1
  3. package/dist/app-auth.d.ts.map +1 -1
  4. package/dist/app-auth.js +11 -1
  5. package/dist/app-auth.js.map +1 -1
  6. package/dist/auth-fetch.d.ts +90 -0
  7. package/dist/auth-fetch.d.ts.map +1 -0
  8. package/dist/auth-fetch.js +261 -0
  9. package/dist/auth-fetch.js.map +1 -0
  10. package/dist/client.d.ts +32 -10
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +6 -2
  13. package/dist/client.js.map +1 -1
  14. package/dist/frame.d.ts +233 -4
  15. package/dist/frame.d.ts.map +1 -1
  16. package/dist/frame.js +694 -19
  17. package/dist/frame.js.map +1 -1
  18. package/dist/handoff.d.ts +32 -2
  19. package/dist/handoff.d.ts.map +1 -1
  20. package/dist/handoff.js +2 -1
  21. package/dist/handoff.js.map +1 -1
  22. package/dist/hono.d.ts +13 -0
  23. package/dist/hono.d.ts.map +1 -1
  24. package/dist/hono.js +15 -0
  25. package/dist/hono.js.map +1 -1
  26. package/dist/index.d.ts +11 -7
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +10 -6
  29. package/dist/index.js.map +1 -1
  30. package/dist/install-handlers.d.ts +33 -8
  31. package/dist/install-handlers.d.ts.map +1 -1
  32. package/dist/install-handlers.js +133 -15
  33. package/dist/install-handlers.js.map +1 -1
  34. package/dist/merchant-schema.d.ts +1550 -68
  35. package/dist/merchant-schema.d.ts.map +1 -1
  36. package/dist/merchant-schema.js +1 -1
  37. package/dist/proxy.d.ts +122 -0
  38. package/dist/proxy.d.ts.map +1 -0
  39. package/dist/proxy.js +204 -0
  40. package/dist/proxy.js.map +1 -0
  41. package/dist/react.d.ts +78 -0
  42. package/dist/react.d.ts.map +1 -0
  43. package/dist/react.js +262 -0
  44. package/dist/react.js.map +1 -0
  45. package/dist/scopes.d.ts +174 -0
  46. package/dist/scopes.d.ts.map +1 -0
  47. package/dist/scopes.js +297 -0
  48. package/dist/scopes.js.map +1 -0
  49. package/dist/server.d.ts +2 -2
  50. package/dist/server.d.ts.map +1 -1
  51. package/dist/server.js +1 -1
  52. package/dist/server.js.map +1 -1
  53. package/dist/session.d.ts +52 -2
  54. package/dist/session.d.ts.map +1 -1
  55. package/dist/session.js +99 -12
  56. package/dist/session.js.map +1 -1
  57. package/dist/store.d.ts +33 -0
  58. package/dist/store.d.ts.map +1 -1
  59. package/dist/store.js +114 -4
  60. package/dist/store.js.map +1 -1
  61. package/dist/theme.d.ts +96 -0
  62. package/dist/theme.d.ts.map +1 -0
  63. package/dist/theme.js +158 -0
  64. package/dist/theme.js.map +1 -0
  65. package/dist/tokens.d.ts +30 -15
  66. package/dist/tokens.d.ts.map +1 -1
  67. package/dist/tokens.js +57 -19
  68. package/dist/tokens.js.map +1 -1
  69. package/dist/webhooks.d.ts.map +1 -1
  70. package/dist/webhooks.js +1 -1
  71. package/dist/webhooks.js.map +1 -1
  72. package/package.json +17 -5
  73. package/CHANGELOG.md +0 -162
  74. package/openapi/merchant.json +0 -21452
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * GENERATED from openapi/merchant.json — do not edit by hand.
3
- * Refresh with: pnpm --filter @usequeek/app-sdk gen:merchant [url-or-path]
3
+ * Refresh with: npm run gen:merchant [url-or-path]
4
4
  * See scripts/gen-merchant-types.mjs for source precedence.
5
5
  */
6
6
  /**
@@ -0,0 +1,122 @@
1
+ import { type InstallationRecord, type InstallationStore } from "./store.js";
2
+ /**
3
+ * Storefront app-proxy query verification, byte-for-byte compatible with
4
+ * Queek's `App\Services\Apps\AppProxyService` (queek_backend).
5
+ *
6
+ * Queek signs a READ fetch to the app's proxy handler with the installation's
7
+ * `proxy_secret` (`signQuery`): the app verifies server-side before answering
8
+ * the shopper. Canonical signature (Shopify-style, per-install secret):
9
+ *
10
+ * sig = hex HMAC-SHA256 over
11
+ * path + "\n" + shop + "\n" + ts + "\n" + sorted(k=v&...) (sig excluded),
12
+ *
13
+ * where each pair is `rawurlencode(key)=rawurlencode(value)` and keys sort
14
+ * byte-wise. The HMAC key is the FULL `whsec_…` string — no base64 decode
15
+ * step (the single most common integration bug cannot happen here).
16
+ *
17
+ * `path` is the QUEEK-side canonical path (`/apps/<subpath>/<rest>`, what
18
+ * the backend signs in `fetch()`), NOT the app's local route: pass it
19
+ * explicitly per route (see `handleProxyRequest`).
20
+ *
21
+ * Layering mirrors the install/webhook handlers: layer 1
22
+ * `verifyProxyDelivery` takes plain data (path + query) and returns a plain
23
+ * result — zero request/response types; layer 2 `handleProxyRequest` adapts
24
+ * the Web standard onto layer 1; `@usequeek/app-sdk/hono`
25
+ * `createProxyHandler` adapts Hono onto layer 2.
26
+ */
27
+ export declare const PROXY_SIGNATURE_PARAM = "sig";
28
+ export declare const PROXY_TIMESTAMP_PARAM = "ts";
29
+ export declare const PROXY_NONCE_PARAM = "jti";
30
+ export declare const PROXY_SHOP_PARAM = "shop";
31
+ export declare const PROXY_CUSTOMER_PARAM = "logged_in_customer_id";
32
+ export declare const PROXY_KID_PARAM = "kid";
33
+ /** Backend `apps.proxy_signature_skew_seconds` default; the floor (60s) below applies regardless. */
34
+ export declare const PROXY_MAX_SKEW_SECONDS = 300;
35
+ /** Query params as any framework holds them (duplicates collapse to the first value). */
36
+ export type ProxyQuery = Record<string, string | string[] | null | undefined>;
37
+ /** Failure reason when proxy verification rejects a query. */
38
+ export type ProxyFailure = "missing_params" | "stale_timestamp" | "missing_secret" | "signature_mismatch" | "unknown_installation" | "replayed";
39
+ /**
40
+ * The canonical string the MAC covers — mirrors `AppProxyService::signature()`
41
+ * exactly (sig excluded, keys byte-sorted, rawurlencoded pairs).
42
+ */
43
+ export declare function buildProxyCanonicalString(path: string, params: Record<string, string>): string;
44
+ /**
45
+ * One hex signature for one secret — mirrors `AppProxyService::signature()`.
46
+ * Exported so tests (and dev harnesses) can recompute a signature
47
+ * independently of the verifier; production traffic is signed by Queek.
48
+ */
49
+ export declare function signProxyQuery(path: string, params: Record<string, string>, secret: string): string;
50
+ export interface ProxyVerifyOptions {
51
+ /** Unix seconds to judge freshness against (defaults to now). Exposed for tests. */
52
+ nowSeconds?: number;
53
+ /** Allowed clock skew in seconds (defaults to PROXY_MAX_SKEW_SECONDS; floored at 60 like the backend). */
54
+ maxSkewSeconds?: number;
55
+ }
56
+ /**
57
+ * Pure verification over explicitly passed secrets — mirrors
58
+ * `AppProxyService::verifyQuery()` (structure → skew → secret presence →
59
+ * MAC over every active secret). No replay enforcement here: single-use
60
+ * `jti` needs storage, so the store-backed `verifyProxyDelivery` claims it
61
+ * (the framework-free translation of the backend's atomic `Cache::add`).
62
+ */
63
+ export declare function verifyProxyQueryDetailed(path: string, query: ProxyQuery, secrets: string[], options?: ProxyVerifyOptions): {
64
+ ok: true;
65
+ } | {
66
+ ok: false;
67
+ reason: ProxyFailure;
68
+ };
69
+ /** Boolean fast path over {@link verifyProxyQueryDetailed}. */
70
+ export declare function verifyProxyQuery(path: string, query: ProxyQuery, secrets: string[], options?: ProxyVerifyOptions): boolean;
71
+ export interface ProxyStoreOptions extends ProxyVerifyOptions {
72
+ store: InstallationStore;
73
+ /**
74
+ * Skip the single-use `jti` claim (NOT recommended; exposed for tests and
75
+ * for apps that enforce replay themselves). Defaults to enforcing, like
76
+ * the backend.
77
+ */
78
+ enforceReplay?: boolean;
79
+ }
80
+ export type ProxyVerification = {
81
+ ok: true;
82
+ installation: InstallationRecord;
83
+ params: Record<string, string>;
84
+ } | {
85
+ ok: false;
86
+ reason: ProxyFailure;
87
+ status: 401;
88
+ };
89
+ /**
90
+ * Layer 1: verify one signed proxy query from plain data — no `Request`, no
91
+ * framework. Resolves the installation from the existing store by the `kid`
92
+ * routing hint (the installation p_id Queek signs in); without a `kid` it
93
+ * falls back to trying each stored proxy secret, the signature naming the
94
+ * sender (same rationale as the webhook resolver). Freshness is enforced
95
+ * before attribution; a verified `jti` is claimed atomically so a captured
96
+ * read cannot be replayed.
97
+ */
98
+ export declare function verifyProxyDelivery(input: {
99
+ path: string;
100
+ query: ProxyQuery;
101
+ }, options: ProxyStoreOptions): Promise<ProxyVerification>;
102
+ export interface ProxyRequestOptions extends ProxyStoreOptions {
103
+ /**
104
+ * The Queek-side canonical path the backend signed
105
+ * (`/apps/<subpath>/<rest>`, e.g. `/apps/booking/availability`) — the
106
+ * app's local route is NOT it. Pass one per route.
107
+ */
108
+ path: string;
109
+ }
110
+ /** What the app answers once the query verifies (it owns the body — slots, JSON, …). */
111
+ export type ProxyResponder = (verified: {
112
+ installation: InstallationRecord;
113
+ params: Record<string, string>;
114
+ }) => Response | Promise<Response>;
115
+ /**
116
+ * Layer 2: the Web-standard wrapper, built ONLY on layer 1 — reads the query
117
+ * off the request URL, calls the core, builds the `Response`. Phase 1 is
118
+ * read-only by binding rule (the backend only ever sends GET), so only
119
+ * `GET` is served; anything else answers 405.
120
+ */
121
+ export declare function handleProxyRequest(request: Request, options: ProxyRequestOptions, onVerified: ProxyResponder): Promise<Response>;
122
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
package/dist/proxy.js ADDED
@@ -0,0 +1,204 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { toResponse } from "./delivery.js";
3
+ import { normalisePid } from "./store.js";
4
+ /**
5
+ * Storefront app-proxy query verification, byte-for-byte compatible with
6
+ * Queek's `App\Services\Apps\AppProxyService` (queek_backend).
7
+ *
8
+ * Queek signs a READ fetch to the app's proxy handler with the installation's
9
+ * `proxy_secret` (`signQuery`): the app verifies server-side before answering
10
+ * the shopper. Canonical signature (Shopify-style, per-install secret):
11
+ *
12
+ * sig = hex HMAC-SHA256 over
13
+ * path + "\n" + shop + "\n" + ts + "\n" + sorted(k=v&...) (sig excluded),
14
+ *
15
+ * where each pair is `rawurlencode(key)=rawurlencode(value)` and keys sort
16
+ * byte-wise. The HMAC key is the FULL `whsec_…` string — no base64 decode
17
+ * step (the single most common integration bug cannot happen here).
18
+ *
19
+ * `path` is the QUEEK-side canonical path (`/apps/<subpath>/<rest>`, what
20
+ * the backend signs in `fetch()`), NOT the app's local route: pass it
21
+ * explicitly per route (see `handleProxyRequest`).
22
+ *
23
+ * Layering mirrors the install/webhook handlers: layer 1
24
+ * `verifyProxyDelivery` takes plain data (path + query) and returns a plain
25
+ * result — zero request/response types; layer 2 `handleProxyRequest` adapts
26
+ * the Web standard onto layer 1; `@usequeek/app-sdk/hono`
27
+ * `createProxyHandler` adapts Hono onto layer 2.
28
+ */
29
+ export const PROXY_SIGNATURE_PARAM = "sig";
30
+ export const PROXY_TIMESTAMP_PARAM = "ts";
31
+ export const PROXY_NONCE_PARAM = "jti";
32
+ export const PROXY_SHOP_PARAM = "shop";
33
+ export const PROXY_CUSTOMER_PARAM = "logged_in_customer_id";
34
+ export const PROXY_KID_PARAM = "kid";
35
+ /** Backend `apps.proxy_signature_skew_seconds` default; the floor (60s) below applies regardless. */
36
+ export const PROXY_MAX_SKEW_SECONDS = 300;
37
+ /** PHP `rawurlencode`: everything except `[A-Za-z0-9-_.~]` is `%XX` (upper-case hex). */
38
+ function proxyEncode(value) {
39
+ return encodeURIComponent(value).replace(/[!'()*]/g, (ch) => {
40
+ return `%${ch.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`;
41
+ });
42
+ }
43
+ /** PHP `strval` for scalar query values: null/undefined become `""`, everything else stringifies. */
44
+ function proxyString(value) {
45
+ if (value === undefined)
46
+ return undefined;
47
+ if (value === null)
48
+ return "";
49
+ return Array.isArray(value) ? proxyString(value[0]) : String(value);
50
+ }
51
+ /** Collapse a query to plain strings (duplicates → first value, undefined → absent). */
52
+ function normalizeQuery(query) {
53
+ const out = {};
54
+ for (const [key, value] of Object.entries(query)) {
55
+ const flat = proxyString(value);
56
+ if (flat !== undefined)
57
+ out[key] = flat;
58
+ }
59
+ return out;
60
+ }
61
+ /**
62
+ * The canonical string the MAC covers — mirrors `AppProxyService::signature()`
63
+ * exactly (sig excluded, keys byte-sorted, rawurlencoded pairs).
64
+ */
65
+ export function buildProxyCanonicalString(path, params) {
66
+ const sorted = { ...params };
67
+ delete sorted[PROXY_SIGNATURE_PARAM];
68
+ const keys = Object.keys(sorted).sort();
69
+ const pairs = keys.map((key) => `${proxyEncode(key)}=${proxyEncode(sorted[key])}`);
70
+ return `${path}\n${sorted[PROXY_SHOP_PARAM] ?? ""}\n${sorted[PROXY_TIMESTAMP_PARAM] ?? ""}\n${pairs.join("&")}`;
71
+ }
72
+ /**
73
+ * One hex signature for one secret — mirrors `AppProxyService::signature()`.
74
+ * Exported so tests (and dev harnesses) can recompute a signature
75
+ * independently of the verifier; production traffic is signed by Queek.
76
+ */
77
+ export function signProxyQuery(path, params, secret) {
78
+ return createHmac("sha256", secret).update(buildProxyCanonicalString(path, params), "utf8").digest("hex");
79
+ }
80
+ function readProxyFields(params) {
81
+ return {
82
+ sig: params[PROXY_SIGNATURE_PARAM] ?? "",
83
+ ts: params[PROXY_TIMESTAMP_PARAM] ?? "",
84
+ jti: params[PROXY_NONCE_PARAM] ?? "",
85
+ };
86
+ }
87
+ function proxySkewExceeded(ts, options) {
88
+ const now = options.nowSeconds ?? Math.floor(Date.now() / 1000);
89
+ const maxSkew = Math.max(60, options.maxSkewSeconds ?? PROXY_MAX_SKEW_SECONDS);
90
+ return Math.abs(now - Number(ts)) > maxSkew;
91
+ }
92
+ function proxyMacMatches(path, params, sig, secret) {
93
+ if (secret === "")
94
+ return false;
95
+ const expected = signProxyQuery(path, params, secret);
96
+ const expectedBuf = Buffer.from(expected, "utf8");
97
+ const candidateBuf = Buffer.from(sig, "utf8");
98
+ return candidateBuf.length === expectedBuf.length && timingSafeEqual(candidateBuf, expectedBuf);
99
+ }
100
+ /**
101
+ * Pure verification over explicitly passed secrets — mirrors
102
+ * `AppProxyService::verifyQuery()` (structure → skew → secret presence →
103
+ * MAC over every active secret). No replay enforcement here: single-use
104
+ * `jti` needs storage, so the store-backed `verifyProxyDelivery` claims it
105
+ * (the framework-free translation of the backend's atomic `Cache::add`).
106
+ */
107
+ export function verifyProxyQueryDetailed(path, query, secrets, options = {}) {
108
+ const params = normalizeQuery(query);
109
+ const { sig, ts, jti } = readProxyFields(params);
110
+ if (sig === "" || ts === "" || jti === "" || !/^\d+$/.test(ts)) {
111
+ return { ok: false, reason: "missing_params" };
112
+ }
113
+ if (proxySkewExceeded(ts, options)) {
114
+ return { ok: false, reason: "stale_timestamp" };
115
+ }
116
+ if (secrets.length === 0 || secrets[0] === "") {
117
+ return { ok: false, reason: "missing_secret" };
118
+ }
119
+ for (const secret of secrets) {
120
+ if (proxyMacMatches(path, params, sig, secret)) {
121
+ return { ok: true };
122
+ }
123
+ }
124
+ return { ok: false, reason: "signature_mismatch" };
125
+ }
126
+ /** Boolean fast path over {@link verifyProxyQueryDetailed}. */
127
+ export function verifyProxyQuery(path, query, secrets, options = {}) {
128
+ return verifyProxyQueryDetailed(path, query, secrets, options).ok;
129
+ }
130
+ /**
131
+ * Layer 1: verify one signed proxy query from plain data — no `Request`, no
132
+ * framework. Resolves the installation from the existing store by the `kid`
133
+ * routing hint (the installation p_id Queek signs in); without a `kid` it
134
+ * falls back to trying each stored proxy secret, the signature naming the
135
+ * sender (same rationale as the webhook resolver). Freshness is enforced
136
+ * before attribution; a verified `jti` is claimed atomically so a captured
137
+ * read cannot be replayed.
138
+ */
139
+ export async function verifyProxyDelivery(input, options) {
140
+ const fail = (reason) => ({ ok: false, reason, status: 401 });
141
+ const params = normalizeQuery(input.query);
142
+ const { sig, ts, jti } = readProxyFields(params);
143
+ if (sig === "" || ts === "" || jti === "" || !/^\d+$/.test(ts)) {
144
+ return fail("missing_params");
145
+ }
146
+ if (proxySkewExceeded(ts, options)) {
147
+ return fail("stale_timestamp");
148
+ }
149
+ const kid = params[PROXY_KID_PARAM];
150
+ const rows = await options.store.listInstallations();
151
+ // Normalise the routing hint before comparing: stored pids are canonical
152
+ // integer strings, but the hint may arrive as a JSON integer or a
153
+ // non-canonical decimal string (`"1021.0"`); canonical strings compare
154
+ // exactly as before.
155
+ const candidates = kid !== undefined && kid !== ""
156
+ ? rows.filter((row) => row.installationPid === normalisePid(kid))
157
+ : rows.filter((row) => row.proxySecret !== null && row.proxySecret !== undefined);
158
+ if (candidates.length === 0) {
159
+ return fail("unknown_installation");
160
+ }
161
+ const secrets = candidates.map((row) => row.proxySecret ?? "");
162
+ if (secrets.length === 0 || secrets[0] === "") {
163
+ return fail("missing_secret");
164
+ }
165
+ let installation = null;
166
+ for (const candidate of candidates) {
167
+ if (proxyMacMatches(input.path, params, sig, candidate.proxySecret ?? "")) {
168
+ installation = candidate;
169
+ break;
170
+ }
171
+ }
172
+ if (!installation) {
173
+ return fail("signature_mismatch");
174
+ }
175
+ if (options.enforceReplay ?? true) {
176
+ if (!(await options.store.claimWebhookId(`proxy-jti:${jti}`))) {
177
+ return fail("replayed");
178
+ }
179
+ }
180
+ return { ok: true, installation, params };
181
+ }
182
+ /**
183
+ * Layer 2: the Web-standard wrapper, built ONLY on layer 1 — reads the query
184
+ * off the request URL, calls the core, builds the `Response`. Phase 1 is
185
+ * read-only by binding rule (the backend only ever sends GET), so only
186
+ * `GET` is served; anything else answers 405.
187
+ */
188
+ export async function handleProxyRequest(request, options, onVerified) {
189
+ if (request.method.toUpperCase() !== "GET") {
190
+ return toResponse({ status: 405, body: { ok: false, error: "method_not_allowed" } });
191
+ }
192
+ const url = new URL(request.url);
193
+ const query = {};
194
+ for (const key of url.searchParams.keys()) {
195
+ query[key] = url.searchParams.get(key);
196
+ }
197
+ const verified = await verifyProxyDelivery({ path: options.path, query }, options);
198
+ if (!verified.ok) {
199
+ const result = { status: verified.status, body: { ok: false, error: verified.reason } };
200
+ return toResponse(result);
201
+ }
202
+ return onVerified({ installation: verified.installation, params: verified.params });
203
+ }
204
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Optional React bindings for `@usequeek/app-sdk` (U2).
3
+ *
4
+ * Import from `@usequeek/app-sdk/react` (requires the optional `react`
5
+ * peer) — a thin layer built ONLY on the framework-free core (`frame.js` /
6
+ * `theme.js`): `<QueekProvider>` owns one bridge subscription, and
7
+ * `useQueek()` exposes `{ toast, saveBar, title, navigate, pickResource,
8
+ * theme }` over it.
9
+ *
10
+ * No JSX in this file (the build stays plain `tsc`, no `jsx` flag).
11
+ */
12
+ import { type ReactNode } from "react";
13
+ import { type BridgeTheme, type EmbedEventTarget, type EmbedPostTarget, type PickResourceRequest, type ResourceItem, type SaveBarAction, type SaveBarState, type TitleActionDef, type ToastTone } from "./frame.js";
14
+ import { type ThemeMode } from "./theme.js";
15
+ /** A pick with no dashboard answer settles after this long (never deadlocks). */
16
+ export declare const PICK_TIMEOUT_MS: number;
17
+ /**
18
+ * How long after `ready` the provider waits for the dashboard's capability
19
+ * handshake (on its `theme` message) before treating the dashboard as legacy.
20
+ */
21
+ export declare const HANDSHAKE_TIMEOUT_MS = 1500;
22
+ export type { BridgeTheme, PickResourceRequest, ResourceItem, SaveBarAction, SaveBarState, ThemeMode, TitleActionDef, ToastTone, };
23
+ export interface ToastOptions {
24
+ tone?: ToastTone;
25
+ durationMs?: number;
26
+ }
27
+ export interface TitleActions {
28
+ primaryAction?: TitleActionDef;
29
+ secondaryActions?: TitleActionDef[];
30
+ }
31
+ export interface SaveBarApi {
32
+ dirty: () => void;
33
+ clean: () => void;
34
+ onAction: (handler: (action: SaveBarAction) => void) => () => void;
35
+ }
36
+ export interface TitleApi {
37
+ set: (heading: string, actions?: TitleActions) => void;
38
+ onAction: (handler: (id: string) => void) => () => void;
39
+ }
40
+ export interface NavigateApi {
41
+ /** Report an in-app move so the dashboard mirrors it in its URL. */
42
+ report: (path: string) => void;
43
+ /** Follow dashboard-driven moves (back/forward, sidebar). */
44
+ onNavigate: (handler: (path: string) => void) => () => void;
45
+ /** Ask the dashboard to open a dashboard path or https URL. */
46
+ open: (target: string) => void;
47
+ }
48
+ export interface ThemeApi {
49
+ mode: ThemeMode;
50
+ }
51
+ export interface QueekApi {
52
+ toast: (message: string, options?: ToastOptions) => void;
53
+ saveBar: SaveBarApi;
54
+ title: TitleApi;
55
+ navigate: NavigateApi;
56
+ /** Resolve with the picked items, or null when the merchant cancels. */
57
+ pickResource: (request: PickResourceRequest) => Promise<ResourceItem[] | null>;
58
+ theme: ThemeApi;
59
+ }
60
+ export interface QueekProviderProps {
61
+ dashboardOrigin: string;
62
+ children?: ReactNode;
63
+ /** Declared in `ready{capabilities}` so old dashboards degrade gracefully. */
64
+ capabilities?: string[];
65
+ sdkVersion?: string;
66
+ postTarget?: EmbedPostTarget;
67
+ listenTarget?: EmbedEventTarget;
68
+ getHref?: () => string;
69
+ /**
70
+ * Required `event.source` for bridge messages. Defaults to the global
71
+ * window's parent when present; pass `null` to disable the source check.
72
+ */
73
+ expectSource?: unknown;
74
+ }
75
+ export declare function QueekProvider(props: QueekProviderProps): ReactNode;
76
+ /** Bridge actions + live theme over the framework-free core. */
77
+ export declare function useQueek(): QueekApi;
78
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}