@usequeek/app-sdk 0.4.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.
- package/CHANGELOG.md +120 -0
- package/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/app-auth.d.ts +139 -0
- package/dist/app-auth.d.ts.map +1 -0
- package/dist/app-auth.js +205 -0
- package/dist/app-auth.js.map +1 -0
- package/dist/background.d.ts +68 -0
- package/dist/background.d.ts.map +1 -0
- package/dist/background.js +78 -0
- package/dist/background.js.map +1 -0
- package/dist/client.d.ts +148 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +269 -0
- package/dist/client.js.map +1 -0
- package/dist/collected.d.ts +103 -0
- package/dist/collected.d.ts.map +1 -0
- package/dist/collected.js +59 -0
- package/dist/collected.js.map +1 -0
- package/dist/crypto.d.ts +6 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +76 -0
- package/dist/crypto.js.map +1 -0
- package/dist/frame.d.ts +58 -0
- package/dist/frame.d.ts.map +1 -0
- package/dist/frame.js +56 -0
- package/dist/frame.js.map +1 -0
- package/dist/handoff.d.ts +113 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +29 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/install-handlers.d.ts +62 -0
- package/dist/install-handlers.d.ts.map +1 -0
- package/dist/install-handlers.js +238 -0
- package/dist/install-handlers.js.map +1 -0
- package/dist/logger.d.ts +27 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +75 -0
- package/dist/logger.js.map +1 -0
- package/dist/merchant-schema.d.ts +13963 -0
- package/dist/merchant-schema.d.ts.map +1 -0
- package/dist/merchant-schema.js +11 -0
- package/dist/merchant-schema.js.map +1 -0
- package/dist/resync.d.ts +80 -0
- package/dist/resync.d.ts.map +1 -0
- package/dist/resync.js +203 -0
- package/dist/resync.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +66 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +155 -0
- package/dist/session.js.map +1 -0
- package/dist/signatures.d.ts +55 -0
- package/dist/signatures.d.ts.map +1 -0
- package/dist/signatures.js +74 -0
- package/dist/signatures.js.map +1 -0
- package/dist/store.d.ts +278 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +610 -0
- package/dist/store.js.map +1 -0
- package/dist/tokens.d.ts +162 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +411 -0
- package/dist/tokens.js.map +1 -0
- package/dist/webhooks.d.ts +60 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +125 -0
- package/dist/webhooks.js.map +1 -0
- package/openapi/merchant.json +21452 -0
- package/package.json +63 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
/** Path of the public Merchant API below the store host. */
|
|
3
|
+
export const MERCHANT_API_PATH = "/api/v1/merchant";
|
|
4
|
+
/** Hosts a handoff `api_base` may point at without extra configuration. */
|
|
5
|
+
export const DEFAULT_API_HOSTS = ["api.usequeek.com"];
|
|
6
|
+
/** Thrown at client construction when `apiBase` fails validation — before any fetch. */
|
|
7
|
+
export class InvalidApiBaseError extends Error {
|
|
8
|
+
code = "invalid_api_base";
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "InvalidApiBaseError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const ENV_HOSTS_VAR = "QUEEK_API_HOSTS";
|
|
15
|
+
const ENV_DEV_HOSTS_VAR = "QUEEK_DEV_API_HOSTS";
|
|
16
|
+
const HOSTNAME_RE = /^(?=.{1,253}$)[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
17
|
+
function parseHostList(raw, varName) {
|
|
18
|
+
return raw.split(",").map((entry) => {
|
|
19
|
+
const host = entry.trim().toLowerCase();
|
|
20
|
+
if (!HOSTNAME_RE.test(host)) {
|
|
21
|
+
throw new InvalidApiBaseError(`Invalid ${varName} entry ${JSON.stringify(entry)}: must be a bare hostname (no scheme, port or path).`);
|
|
22
|
+
}
|
|
23
|
+
return host;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extra allowed `apiBase` hosts for test/local backends, from
|
|
28
|
+
* `QUEEK_API_HOSTS` (comma-separated bare hostnames). Parsed strictly: any
|
|
29
|
+
* entry that is not a bare hostname throws — nothing is silently skipped.
|
|
30
|
+
*/
|
|
31
|
+
export function apiHostsFromEnv(env = process.env) {
|
|
32
|
+
const raw = env[ENV_HOSTS_VAR];
|
|
33
|
+
if (raw === undefined || raw.trim() === "")
|
|
34
|
+
return [];
|
|
35
|
+
return parseHostList(raw, ENV_HOSTS_VAR);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* DEV-ONLY extra allowed hosts (e.g. an HTTPS tunnel to a local backend),
|
|
39
|
+
* from `QUEEK_DEV_API_HOSTS`. REFUSED when NODE_ENV=production: a dev
|
|
40
|
+
* tunnel host must never be allowlisted in production, even by accident.
|
|
41
|
+
* Throws at client construction, before any fetch.
|
|
42
|
+
*/
|
|
43
|
+
export function devApiHostsFromEnv(env = process.env) {
|
|
44
|
+
const raw = env[ENV_DEV_HOSTS_VAR];
|
|
45
|
+
if (raw === undefined || raw.trim() === "")
|
|
46
|
+
return [];
|
|
47
|
+
if ((env.NODE_ENV ?? "") === "production") {
|
|
48
|
+
throw new InvalidApiBaseError(`${ENV_DEV_HOSTS_VAR} is set but NODE_ENV=production: dev tunnel hosts are refused in production.`);
|
|
49
|
+
}
|
|
50
|
+
return parseHostList(raw, ENV_DEV_HOSTS_VAR);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate the handoff `apiBase` and normalize it to the full merchant base.
|
|
54
|
+
* Throws `InvalidApiBaseError` on: unparseable URL, non-https scheme,
|
|
55
|
+
* embedded credentials, an explicit port on a DEFAULT host (production
|
|
56
|
+
* hosts are 443 — ports ride only on dev/test hosts), or a host outside
|
|
57
|
+
* `DEFAULT_API_HOSTS + allowedApiHosts + QUEEK_API_HOSTS +
|
|
58
|
+
* QUEEK_DEV_API_HOSTS`.
|
|
59
|
+
*/
|
|
60
|
+
export function resolveApiBase(raw, allowedApiHosts = []) {
|
|
61
|
+
let url;
|
|
62
|
+
try {
|
|
63
|
+
url = new URL(raw);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw new InvalidApiBaseError(`Invalid api_base ${JSON.stringify(raw)}: not a URL.`);
|
|
67
|
+
}
|
|
68
|
+
if (url.protocol !== "https:") {
|
|
69
|
+
throw new InvalidApiBaseError(`Invalid api_base ${JSON.stringify(raw)}: https only.`);
|
|
70
|
+
}
|
|
71
|
+
if (url.username !== "" || url.password !== "") {
|
|
72
|
+
throw new InvalidApiBaseError("Invalid api_base: embedded credentials are never allowed.");
|
|
73
|
+
}
|
|
74
|
+
const host = url.hostname.toLowerCase();
|
|
75
|
+
if (DEFAULT_API_HOSTS.includes(host) && url.port !== "") {
|
|
76
|
+
throw new InvalidApiBaseError(`Invalid api_base ${JSON.stringify(raw)}: the production host takes no port (443).`);
|
|
77
|
+
}
|
|
78
|
+
const allowlist = new Set([
|
|
79
|
+
...DEFAULT_API_HOSTS,
|
|
80
|
+
...allowedApiHosts.map((h) => h.toLowerCase()),
|
|
81
|
+
...apiHostsFromEnv(),
|
|
82
|
+
...devApiHostsFromEnv(),
|
|
83
|
+
]);
|
|
84
|
+
if (!allowlist.has(host)) {
|
|
85
|
+
throw new InvalidApiBaseError(`Invalid api_base host ${JSON.stringify(host)}: not on the allowlist (add test hosts via ${ENV_HOSTS_VAR}).`);
|
|
86
|
+
}
|
|
87
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
88
|
+
const merchantPath = path.endsWith(MERCHANT_API_PATH) ? path : `${path}${MERCHANT_API_PATH}`;
|
|
89
|
+
return `https://${host}${url.port !== "" ? `:${url.port}` : ""}${merchantPath}`;
|
|
90
|
+
}
|
|
91
|
+
const WRITE_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
92
|
+
export function newIdempotencyKey() {
|
|
93
|
+
return randomUUID();
|
|
94
|
+
}
|
|
95
|
+
function parseRetryAfterMs(value) {
|
|
96
|
+
if (!value)
|
|
97
|
+
return null;
|
|
98
|
+
const trimmed = value.trim();
|
|
99
|
+
const seconds = Number(trimmed);
|
|
100
|
+
if (Number.isFinite(seconds) && trimmed !== "") {
|
|
101
|
+
return Math.max(0, seconds * 1000);
|
|
102
|
+
}
|
|
103
|
+
const dateMs = Date.parse(trimmed);
|
|
104
|
+
if (!Number.isNaN(dateMs)) {
|
|
105
|
+
return Math.max(0, dateMs - Date.now());
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
export class QueekApiError extends Error {
|
|
110
|
+
status;
|
|
111
|
+
code;
|
|
112
|
+
field;
|
|
113
|
+
errors;
|
|
114
|
+
docUrl;
|
|
115
|
+
requestId;
|
|
116
|
+
/** Set on 429s (and only there): how long to wait before retrying. */
|
|
117
|
+
retryAfterMs;
|
|
118
|
+
constructor(details) {
|
|
119
|
+
super(details.message);
|
|
120
|
+
this.name = "QueekApiError";
|
|
121
|
+
this.status = details.status;
|
|
122
|
+
this.code = details.code;
|
|
123
|
+
this.field = details.field;
|
|
124
|
+
this.errors = details.errors;
|
|
125
|
+
this.docUrl = details.docUrl;
|
|
126
|
+
this.requestId = details.requestId;
|
|
127
|
+
this.retryAfterMs = details.retryAfterMs;
|
|
128
|
+
}
|
|
129
|
+
get isRateLimited() {
|
|
130
|
+
return this.status === 429;
|
|
131
|
+
}
|
|
132
|
+
get isAuthFailure() {
|
|
133
|
+
return this.status === 401 || this.status === 403;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Build a `QueekApiError` from a status + parsed body + headers. Shared
|
|
138
|
+
* with the installation-token mint path (`tokens.ts`), so the merchant and
|
|
139
|
+
* app-credential endpoints parse errors identically.
|
|
140
|
+
*/
|
|
141
|
+
export function queekApiErrorFromResponse(status, body, headers) {
|
|
142
|
+
const record = (typeof body === "object" && body !== null ? body : {});
|
|
143
|
+
const envelope = (typeof record.error === "object" && record.error !== null ? record.error : {});
|
|
144
|
+
const firstString = (...candidates) => {
|
|
145
|
+
for (const candidate of candidates) {
|
|
146
|
+
if (typeof candidate === "string" && candidate.trim() !== "")
|
|
147
|
+
return candidate;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
};
|
|
151
|
+
const code = firstString(envelope.code, record.error_code) ?? (status === 429 ? "too_many_requests" : "server_error");
|
|
152
|
+
const message = firstString(envelope.message, record.message) ?? `Queek API error ${status}`;
|
|
153
|
+
const details = {
|
|
154
|
+
status,
|
|
155
|
+
code,
|
|
156
|
+
message,
|
|
157
|
+
field: firstString(envelope.field),
|
|
158
|
+
errors: (envelope.errors ?? record.errors),
|
|
159
|
+
docUrl: firstString(envelope.doc_url),
|
|
160
|
+
requestId: firstString(envelope.request_id, record.request_id, headers.get("x-request-id")),
|
|
161
|
+
};
|
|
162
|
+
if (details.errors === undefined)
|
|
163
|
+
delete details.errors;
|
|
164
|
+
if (details.field === undefined)
|
|
165
|
+
delete details.field;
|
|
166
|
+
if (details.docUrl === undefined)
|
|
167
|
+
delete details.docUrl;
|
|
168
|
+
if (details.requestId === undefined)
|
|
169
|
+
delete details.requestId;
|
|
170
|
+
if (status === 429) {
|
|
171
|
+
const retryAfterMs = parseRetryAfterMs(headers.get("retry-after"));
|
|
172
|
+
if (retryAfterMs !== null)
|
|
173
|
+
details.retryAfterMs = retryAfterMs;
|
|
174
|
+
}
|
|
175
|
+
return new QueekApiError(details);
|
|
176
|
+
}
|
|
177
|
+
function defaultSleep(ms) {
|
|
178
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
179
|
+
}
|
|
180
|
+
function isRetryable(error) {
|
|
181
|
+
return error instanceof QueekApiError && (error.isRateLimited || error.code === "network_error");
|
|
182
|
+
}
|
|
183
|
+
function retryDelayMs(error, attempt, baseDelayMs, maxDelayMs) {
|
|
184
|
+
if (error.isRateLimited && error.retryAfterMs !== undefined)
|
|
185
|
+
return error.retryAfterMs;
|
|
186
|
+
return Math.min(maxDelayMs, baseDelayMs * 2 ** attempt);
|
|
187
|
+
}
|
|
188
|
+
export function createQueekClient(clientOptions) {
|
|
189
|
+
const base = resolveApiBase(clientOptions.apiBase, clientOptions.allowedApiHosts ?? []);
|
|
190
|
+
const fetchImpl = clientOptions.fetchImpl ?? fetch;
|
|
191
|
+
const userAgent = clientOptions.userAgent ?? "queek-app/1.0";
|
|
192
|
+
async function request(method, path, options = {}) {
|
|
193
|
+
const upper = method.toUpperCase();
|
|
194
|
+
const url = new URL(`${base}${path.startsWith("/") ? path : `/${path}`}`);
|
|
195
|
+
if (options.query) {
|
|
196
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
197
|
+
if (value !== undefined)
|
|
198
|
+
url.searchParams.set(key, String(value));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const headers = new Headers();
|
|
202
|
+
headers.set("X-Client-Key", clientOptions.apiKey);
|
|
203
|
+
headers.set("Accept", "application/json");
|
|
204
|
+
headers.set("User-Agent", userAgent);
|
|
205
|
+
headers.set("X-Request-Id", options.requestId ?? randomUUID());
|
|
206
|
+
let body;
|
|
207
|
+
if (options.body !== undefined) {
|
|
208
|
+
headers.set("Content-Type", "application/json");
|
|
209
|
+
body = JSON.stringify(options.body);
|
|
210
|
+
}
|
|
211
|
+
if (WRITE_METHODS.has(upper)) {
|
|
212
|
+
headers.set("Idempotency-Key", options.idempotencyKey ?? newIdempotencyKey());
|
|
213
|
+
}
|
|
214
|
+
let response;
|
|
215
|
+
try {
|
|
216
|
+
response = await fetchImpl(url.toString(), { method: upper, headers, body, signal: options.signal });
|
|
217
|
+
}
|
|
218
|
+
catch (cause) {
|
|
219
|
+
throw new QueekApiError({
|
|
220
|
+
status: 0,
|
|
221
|
+
code: "network_error",
|
|
222
|
+
message: cause instanceof Error ? `Could not reach Queek: ${cause.message}` : "Could not reach Queek.",
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const text = await response.text();
|
|
226
|
+
const parsed = text === "" ? null : tryParseJson(text);
|
|
227
|
+
if (!response.ok) {
|
|
228
|
+
throw queekApiErrorFromResponse(response.status, parsed, response.headers);
|
|
229
|
+
}
|
|
230
|
+
return parsed;
|
|
231
|
+
}
|
|
232
|
+
async function requestWithRetry(method, path, options = {}) {
|
|
233
|
+
const maxAttempts = Math.max(1, Math.floor(options.maxAttempts ?? 3));
|
|
234
|
+
const baseDelayMs = options.baseDelayMs ?? 250;
|
|
235
|
+
const maxDelayMs = options.maxDelayMs ?? 5000;
|
|
236
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
237
|
+
// One key for every attempt: Queek replays same-key+same-body writes
|
|
238
|
+
// instead of duplicating them, so retrying a write is safe.
|
|
239
|
+
const idempotencyKey = options.idempotencyKey ?? (WRITE_METHODS.has(method.toUpperCase()) ? newIdempotencyKey() : undefined);
|
|
240
|
+
let lastError;
|
|
241
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
242
|
+
try {
|
|
243
|
+
return await request(method, path, { ...options, idempotencyKey });
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
lastError = error;
|
|
247
|
+
const retryable = error instanceof QueekApiError && isRetryable(error);
|
|
248
|
+
if (!retryable || attempt === maxAttempts - 1)
|
|
249
|
+
throw error;
|
|
250
|
+
await sleep(retryDelayMs(error, attempt, baseDelayMs, maxDelayMs));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
throw lastError;
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
getStore: (signal) => request("GET", "/store", { signal }),
|
|
257
|
+
request,
|
|
258
|
+
requestWithRetry,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function tryParseJson(text) {
|
|
262
|
+
try {
|
|
263
|
+
return JSON.parse(text);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
return { message: text.slice(0, 500) };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { QueekClient } from "./client.js";
|
|
2
|
+
import type { components } from "./merchant-schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* Installation-bound app writes (S3a): the setup notice, merchant alerts,
|
|
5
|
+
* collected definitions and record submits. Every helper takes a
|
|
6
|
+
* `QueekClient` built from the installation's own key — the backend
|
|
7
|
+
* resolves the installation from that key, never from the body — and
|
|
8
|
+
* returns the decoded `data` payload of the success envelope.
|
|
9
|
+
*
|
|
10
|
+
* Contracts: config/vendor_api_keys.php (Apps group + Forms proof path)
|
|
11
|
+
* at queek_backend@c1fa1c31; request shapes below are the generated
|
|
12
|
+
* `components` schemas from the same backend's merchant export.
|
|
13
|
+
*/
|
|
14
|
+
type Schemas = components["schemas"];
|
|
15
|
+
export interface SuccessEnvelope<T> {
|
|
16
|
+
status: "success";
|
|
17
|
+
message: string;
|
|
18
|
+
data: T;
|
|
19
|
+
}
|
|
20
|
+
/** PUT app/setup — full-body write, so callers send the whole sheet every time. */
|
|
21
|
+
export type SetupNoticeStatus = "incomplete" | "complete";
|
|
22
|
+
export interface SetupNoticeItem {
|
|
23
|
+
key: string;
|
|
24
|
+
label: string;
|
|
25
|
+
value: string;
|
|
26
|
+
sensitive: boolean;
|
|
27
|
+
copyable: boolean;
|
|
28
|
+
instructions?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface SetupNotice {
|
|
31
|
+
status: SetupNoticeStatus;
|
|
32
|
+
items: SetupNoticeItem[];
|
|
33
|
+
}
|
|
34
|
+
export type SetupNoticeBody = Schemas["UpdateAppSetupNoticeRequest"];
|
|
35
|
+
export declare function setSetupNotice(client: QueekClient, notice: SetupNotice, options?: {
|
|
36
|
+
idempotencyKey?: string;
|
|
37
|
+
}): Promise<unknown>;
|
|
38
|
+
/** POST app/alerts — pages the merchant through the bell (in-app only). */
|
|
39
|
+
export type AlertSeverity = "info" | "warning" | "error";
|
|
40
|
+
export interface MerchantAlert {
|
|
41
|
+
severity: AlertSeverity;
|
|
42
|
+
title: string;
|
|
43
|
+
message: string;
|
|
44
|
+
dedupe_key?: string;
|
|
45
|
+
meta?: string[];
|
|
46
|
+
}
|
|
47
|
+
export type AlertBody = Schemas["SendAppAlertRequest"];
|
|
48
|
+
export declare function sendAlert(client: QueekClient, alert: MerchantAlert, options?: {
|
|
49
|
+
idempotencyKey?: string;
|
|
50
|
+
}): Promise<unknown>;
|
|
51
|
+
/** Collected definitions owned by the calling installation. */
|
|
52
|
+
export type CollectedField = Schemas["CollectedDefinitionRequest"]["fields"][number];
|
|
53
|
+
export interface CollectedDefinitionCreate {
|
|
54
|
+
/** Must start with the installation's `app_{slug}_{p_id}_` prefix (403 otherwise). */
|
|
55
|
+
type: string;
|
|
56
|
+
name: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
display_field: string;
|
|
59
|
+
fields: CollectedField[];
|
|
60
|
+
}
|
|
61
|
+
export interface CollectedDefinitionUpdate {
|
|
62
|
+
name?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
display_field?: string;
|
|
65
|
+
fields?: CollectedField[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A collected definition as the Merchant API returns it: the generated
|
|
69
|
+
* MetaobjectDefinitionResource (typed since bf7329af) with the create
|
|
70
|
+
* endpoint's field vocabulary for `fields` (the generated `unknown[]`
|
|
71
|
+
* carries no field shape).
|
|
72
|
+
*/
|
|
73
|
+
export type CollectedDefinition = Omit<Schemas["MetaobjectDefinitionResource"], "fields"> & {
|
|
74
|
+
fields: CollectedField[];
|
|
75
|
+
};
|
|
76
|
+
export declare const collectedDefinitions: {
|
|
77
|
+
/** GET collected-definitions — only the calling installation's own types. */
|
|
78
|
+
list(client: QueekClient): Promise<CollectedDefinition[]>;
|
|
79
|
+
/** POST collected-definitions — class forced collected, stamped to the installation. */
|
|
80
|
+
create(client: QueekClient, definition: CollectedDefinitionCreate, options?: {
|
|
81
|
+
idempotencyKey?: string;
|
|
82
|
+
}): Promise<CollectedDefinition>;
|
|
83
|
+
/** PATCH collected-definitions/{p_id} — the type itself is immutable. */
|
|
84
|
+
update(client: QueekClient, pId: number, patch: CollectedDefinitionUpdate, options?: {
|
|
85
|
+
idempotencyKey?: string;
|
|
86
|
+
}): Promise<CollectedDefinition>;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* POST records — one record under the installation's own type.
|
|
90
|
+
*
|
|
91
|
+
* `values` is a `{field_key: value}` object (spec-correct since
|
|
92
|
+
* bf7329af: object + additionalProperties; the writer validates pairs). A
|
|
93
|
+
* fresh Idempotency-Key is generated per call unless the caller passes
|
|
94
|
+
* one — no two submits ever share a key.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createRecord(client: QueekClient, submit: {
|
|
97
|
+
definition: string;
|
|
98
|
+
values: Record<string, unknown>;
|
|
99
|
+
}, options?: {
|
|
100
|
+
idempotencyKey?: string;
|
|
101
|
+
}): Promise<unknown>;
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=collected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collected.d.ts","sourceRoot":"","sources":["../src/collected.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export async function setSetupNotice(client, notice, options = {}) {
|
|
2
|
+
const body = {
|
|
3
|
+
status: notice.status,
|
|
4
|
+
items: notice.items.map((item) => ({
|
|
5
|
+
...item,
|
|
6
|
+
instructions: item.instructions ?? null,
|
|
7
|
+
})),
|
|
8
|
+
};
|
|
9
|
+
const response = await client.request("PUT", "/app/setup", {
|
|
10
|
+
body,
|
|
11
|
+
idempotencyKey: options.idempotencyKey,
|
|
12
|
+
});
|
|
13
|
+
return response.data;
|
|
14
|
+
}
|
|
15
|
+
export async function sendAlert(client, alert, options = {}) {
|
|
16
|
+
const body = {
|
|
17
|
+
...alert,
|
|
18
|
+
dedupe_key: alert.dedupe_key ?? null,
|
|
19
|
+
meta: alert.meta ?? null,
|
|
20
|
+
};
|
|
21
|
+
const response = await client.request("POST", "/app/alerts", {
|
|
22
|
+
body,
|
|
23
|
+
idempotencyKey: options.idempotencyKey,
|
|
24
|
+
});
|
|
25
|
+
return response.data;
|
|
26
|
+
}
|
|
27
|
+
export const collectedDefinitions = {
|
|
28
|
+
/** GET collected-definitions — only the calling installation's own types. */
|
|
29
|
+
async list(client) {
|
|
30
|
+
const response = await client.request("GET", "/collected-definitions");
|
|
31
|
+
return response.data;
|
|
32
|
+
},
|
|
33
|
+
/** POST collected-definitions — class forced collected, stamped to the installation. */
|
|
34
|
+
async create(client, definition, options = {}) {
|
|
35
|
+
const response = await client.request("POST", "/collected-definitions", { body: definition, idempotencyKey: options.idempotencyKey });
|
|
36
|
+
return response.data;
|
|
37
|
+
},
|
|
38
|
+
/** PATCH collected-definitions/{p_id} — the type itself is immutable. */
|
|
39
|
+
async update(client, pId, patch, options = {}) {
|
|
40
|
+
const response = await client.request("PATCH", `/collected-definitions/${pId}`, { body: patch, idempotencyKey: options.idempotencyKey });
|
|
41
|
+
return response.data;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* POST records — one record under the installation's own type.
|
|
46
|
+
*
|
|
47
|
+
* `values` is a `{field_key: value}` object (spec-correct since
|
|
48
|
+
* bf7329af: object + additionalProperties; the writer validates pairs). A
|
|
49
|
+
* fresh Idempotency-Key is generated per call unless the caller passes
|
|
50
|
+
* one — no two submits ever share a key.
|
|
51
|
+
*/
|
|
52
|
+
export async function createRecord(client, submit, options = {}) {
|
|
53
|
+
const response = await client.request("POST", "/records", {
|
|
54
|
+
body: submit,
|
|
55
|
+
idempotencyKey: options.idempotencyKey,
|
|
56
|
+
});
|
|
57
|
+
return response.data;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=collected.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collected.js","sourceRoot":"","sources":["../src/collected.ts"],"names":[],"mappings":"AA0CA,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAmB,EACnB,MAAmB,EACnB,UAAuC,EAAE;IAEzC,MAAM,IAAI,GAAoB;QAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjC,GAAG,IAAI;YACP,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;SACxC,CAAC,CAAC;KACJ,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAA2B,KAAK,EAAE,YAAY,EAAE;QACnF,IAAI;QACJ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AAeD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAmB,EACnB,KAAoB,EACpB,UAAuC,EAAE;IAEzC,MAAM,IAAI,GAAc;QACtB,GAAG,KAAK;QACR,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACpC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI;KACzB,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAA2B,MAAM,EAAE,aAAa,EAAE;QACrF,IAAI;QACJ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC;AA+BD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,6EAA6E;IAC7E,KAAK,CAAC,IAAI,CAAC,MAAmB;QAC5B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,KAAK,EACL,wBAAwB,CACzB,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,wFAAwF;IACxF,KAAK,CAAC,MAAM,CACV,MAAmB,EACnB,UAAqC,EACrC,UAAuC,EAAE;QAEzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,MAAM,EACN,wBAAwB,EACxB,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAC7D,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,MAAM,CACV,MAAmB,EACnB,GAAW,EACX,KAAgC,EAChC,UAAuC,EAAE;QAEzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,OAAO,EACP,0BAA0B,GAAG,EAAE,EAC/B,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CACxD,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAmB,EACnB,MAA+D,EAC/D,UAAuC,EAAE;IAEzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAA2B,MAAM,EAAE,UAAU,EAAE;QAClF,IAAI,EAAE,MAAM;QACZ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACvB,CAAC"}
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function parseStoreKey(raw: string | undefined): Buffer;
|
|
2
|
+
/** Non-secret fingerprint for logs (first 4 bytes, hex). Reveals nothing usable. */
|
|
3
|
+
export declare function storeKeyFingerprint(key: Buffer): string;
|
|
4
|
+
export declare function encryptSecret(plaintext: string, key: Buffer): string;
|
|
5
|
+
export declare function decryptSecret(envelope: string, key: Buffer): string;
|
|
6
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAgBA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA8B7D;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CASpE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBnE"}
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* AES-256-GCM envelope encryption for secrets at rest (installation api_key
|
|
4
|
+
* and webhook_secret). One random 96-bit IV per value; the stored string is
|
|
5
|
+
* `v1.<base64 iv>.<base64 ciphertext+tag>`.
|
|
6
|
+
*
|
|
7
|
+
* The 32-byte data key comes from the environment (`APP_ENCRYPTION_KEY`, base64
|
|
8
|
+
* or hex of 32 bytes) and is parsed by `parseStoreKey()`. The key itself is
|
|
9
|
+
* NEVER logged — only its 8-char fingerprint (first bytes, hex) may appear in
|
|
10
|
+
* logs to prove which key a ciphertext belongs to.
|
|
11
|
+
*/
|
|
12
|
+
const ENVELOPE_VERSION = "v1";
|
|
13
|
+
const IV_BYTES = 12;
|
|
14
|
+
export function parseStoreKey(raw) {
|
|
15
|
+
if (!raw || raw.trim() === "") {
|
|
16
|
+
throw new Error("Missing store encryption key: set APP_ENCRYPTION_KEY to base64 or hex of 32 random bytes.");
|
|
17
|
+
}
|
|
18
|
+
const value = raw.trim();
|
|
19
|
+
const candidates = [];
|
|
20
|
+
// Base64 only when it looks like base64 (length multiple of 4); a raw
|
|
21
|
+
// 32-char passphrase must NOT be misread as base64.
|
|
22
|
+
if (/^[A-Za-z0-9+/]+={0,2}$/.test(value) && value.length % 4 === 0) {
|
|
23
|
+
try {
|
|
24
|
+
candidates.push(Buffer.from(value, "base64"));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// fall through to hex/utf8
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (/^[0-9a-fA-F]+$/.test(value)) {
|
|
31
|
+
try {
|
|
32
|
+
candidates.push(Buffer.from(value, "hex"));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// fall through
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
candidates.push(Buffer.from(value, "utf8"));
|
|
39
|
+
const key = candidates.find((candidate) => candidate.length === 32);
|
|
40
|
+
if (!key) {
|
|
41
|
+
throw new Error("Invalid APP_ENCRYPTION_KEY: must decode to exactly 32 bytes (base64 or hex).");
|
|
42
|
+
}
|
|
43
|
+
return key;
|
|
44
|
+
}
|
|
45
|
+
/** Non-secret fingerprint for logs (first 4 bytes, hex). Reveals nothing usable. */
|
|
46
|
+
export function storeKeyFingerprint(key) {
|
|
47
|
+
return key.subarray(0, 4).toString("hex");
|
|
48
|
+
}
|
|
49
|
+
export function encryptSecret(plaintext, key) {
|
|
50
|
+
if (key.length !== 32)
|
|
51
|
+
throw new Error("Encryption key must be 32 bytes.");
|
|
52
|
+
const iv = randomBytes(IV_BYTES);
|
|
53
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
54
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
55
|
+
const tag = cipher.getAuthTag();
|
|
56
|
+
return [ENVELOPE_VERSION, iv.toString("base64"), Buffer.concat([ciphertext, tag]).toString("base64")].join(".");
|
|
57
|
+
}
|
|
58
|
+
export function decryptSecret(envelope, key) {
|
|
59
|
+
if (key.length !== 32)
|
|
60
|
+
throw new Error("Encryption key must be 32 bytes.");
|
|
61
|
+
const parts = envelope.split(".");
|
|
62
|
+
if (parts.length !== 3 || parts[0] !== ENVELOPE_VERSION) {
|
|
63
|
+
throw new Error("Unrecognized secret envelope (expected v1.<iv>.<ciphertext>).");
|
|
64
|
+
}
|
|
65
|
+
const iv = Buffer.from(parts[1], "base64");
|
|
66
|
+
const raw = Buffer.from(parts[2], "base64");
|
|
67
|
+
if (iv.length !== IV_BYTES || raw.length < 17) {
|
|
68
|
+
throw new Error("Corrupt secret envelope.");
|
|
69
|
+
}
|
|
70
|
+
const tag = raw.subarray(raw.length - 16);
|
|
71
|
+
const ciphertext = raw.subarray(0, raw.length - 16);
|
|
72
|
+
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
73
|
+
decipher.setAuthTag(tag);
|
|
74
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/frame.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framed-page handshake client (S4 stage 2): the browser-safe half of the
|
|
3
|
+
* dashboard bridge. Carries NO secret and performs NO verification — it only
|
|
4
|
+
* shapes and addresses messages. The dashboard (queek-merchant) enforces
|
|
5
|
+
* origin+source binding and mints tokens; the app backend verifies them via
|
|
6
|
+
* `./server` (`verifySessionToken`).
|
|
7
|
+
*
|
|
8
|
+
* DOM-free by design (structural minimal types): the app passes its own
|
|
9
|
+
* window/parent in, so this module needs no DOM lib and stays import-safe
|
|
10
|
+
* in edge runtimes.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DASHBOARD_SOURCE = "queek-merchant";
|
|
13
|
+
export declare const APP_SOURCE = "queek-app";
|
|
14
|
+
export type AppOutboundMessage = {
|
|
15
|
+
source: typeof APP_SOURCE;
|
|
16
|
+
type: "ready";
|
|
17
|
+
} | {
|
|
18
|
+
source: typeof APP_SOURCE;
|
|
19
|
+
type: "resize";
|
|
20
|
+
height: number;
|
|
21
|
+
} | {
|
|
22
|
+
source: typeof APP_SOURCE;
|
|
23
|
+
type: "ack";
|
|
24
|
+
};
|
|
25
|
+
export type AppInboundMessage = {
|
|
26
|
+
source: typeof DASHBOARD_SOURCE;
|
|
27
|
+
type: "token";
|
|
28
|
+
token: string;
|
|
29
|
+
} | {
|
|
30
|
+
source: typeof DASHBOARD_SOURCE;
|
|
31
|
+
type: "resize-ack";
|
|
32
|
+
};
|
|
33
|
+
export interface EmbedEvent {
|
|
34
|
+
origin: string;
|
|
35
|
+
data: unknown;
|
|
36
|
+
}
|
|
37
|
+
export interface EmbedEventTarget {
|
|
38
|
+
addEventListener(type: "message", listener: (event: EmbedEvent) => void): void;
|
|
39
|
+
removeEventListener(type: "message", listener: (event: EmbedEvent) => void): void;
|
|
40
|
+
}
|
|
41
|
+
export interface EmbedPostTarget {
|
|
42
|
+
postMessage(message: unknown, targetOrigin: string): void;
|
|
43
|
+
}
|
|
44
|
+
export interface FrameBridgeOptions {
|
|
45
|
+
/** Exact dashboard origin (e.g. from the embed query or app config). */
|
|
46
|
+
dashboardOrigin: string;
|
|
47
|
+
target?: EmbedEventTarget;
|
|
48
|
+
onToken?: (token: string) => void;
|
|
49
|
+
onResizeAck?: () => void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Listen for dashboard messages, accepting only the exact dashboard
|
|
53
|
+
* origin. Returns an unsubscribe function. Never touches any secret.
|
|
54
|
+
*/
|
|
55
|
+
export declare function listenToDashboard(options: FrameBridgeOptions): () => void;
|
|
56
|
+
/** Announce readiness to the exact dashboard origin — never `"*"`. */
|
|
57
|
+
export declare function sendReady(dashboardOrigin: string, target?: EmbedPostTarget): void;
|
|
58
|
+
//# sourceMappingURL=frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AACjD,eAAO,MAAM,UAAU,cAAc,CAAC;AAEtC,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,OAAO,UAAU,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,OAAO,UAAU,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,MAAM,EAAE,OAAO,UAAU,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAE/C,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/E,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACnF;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAgBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAkBzE;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAGjF"}
|