@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README.md +210 -0
  4. package/dist/app-auth.d.ts +139 -0
  5. package/dist/app-auth.d.ts.map +1 -0
  6. package/dist/app-auth.js +205 -0
  7. package/dist/app-auth.js.map +1 -0
  8. package/dist/background.d.ts +68 -0
  9. package/dist/background.d.ts.map +1 -0
  10. package/dist/background.js +78 -0
  11. package/dist/background.js.map +1 -0
  12. package/dist/client.d.ts +148 -0
  13. package/dist/client.d.ts.map +1 -0
  14. package/dist/client.js +269 -0
  15. package/dist/client.js.map +1 -0
  16. package/dist/collected.d.ts +103 -0
  17. package/dist/collected.d.ts.map +1 -0
  18. package/dist/collected.js +59 -0
  19. package/dist/collected.js.map +1 -0
  20. package/dist/crypto.d.ts +6 -0
  21. package/dist/crypto.d.ts.map +1 -0
  22. package/dist/crypto.js +76 -0
  23. package/dist/crypto.js.map +1 -0
  24. package/dist/frame.d.ts +58 -0
  25. package/dist/frame.d.ts.map +1 -0
  26. package/dist/frame.js +56 -0
  27. package/dist/frame.js.map +1 -0
  28. package/dist/handoff.d.ts +113 -0
  29. package/dist/handoff.d.ts.map +1 -0
  30. package/dist/handoff.js +29 -0
  31. package/dist/handoff.js.map +1 -0
  32. package/dist/index.d.ts +25 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +25 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/install-handlers.d.ts +62 -0
  37. package/dist/install-handlers.d.ts.map +1 -0
  38. package/dist/install-handlers.js +238 -0
  39. package/dist/install-handlers.js.map +1 -0
  40. package/dist/logger.d.ts +27 -0
  41. package/dist/logger.d.ts.map +1 -0
  42. package/dist/logger.js +75 -0
  43. package/dist/logger.js.map +1 -0
  44. package/dist/merchant-schema.d.ts +13963 -0
  45. package/dist/merchant-schema.d.ts.map +1 -0
  46. package/dist/merchant-schema.js +11 -0
  47. package/dist/merchant-schema.js.map +1 -0
  48. package/dist/resync.d.ts +80 -0
  49. package/dist/resync.d.ts.map +1 -0
  50. package/dist/resync.js +203 -0
  51. package/dist/resync.js.map +1 -0
  52. package/dist/server.d.ts +9 -0
  53. package/dist/server.d.ts.map +1 -0
  54. package/dist/server.js +8 -0
  55. package/dist/server.js.map +1 -0
  56. package/dist/session.d.ts +66 -0
  57. package/dist/session.d.ts.map +1 -0
  58. package/dist/session.js +155 -0
  59. package/dist/session.js.map +1 -0
  60. package/dist/signatures.d.ts +55 -0
  61. package/dist/signatures.d.ts.map +1 -0
  62. package/dist/signatures.js +74 -0
  63. package/dist/signatures.js.map +1 -0
  64. package/dist/store.d.ts +278 -0
  65. package/dist/store.d.ts.map +1 -0
  66. package/dist/store.js +610 -0
  67. package/dist/store.js.map +1 -0
  68. package/dist/tokens.d.ts +162 -0
  69. package/dist/tokens.d.ts.map +1 -0
  70. package/dist/tokens.js +411 -0
  71. package/dist/tokens.js.map +1 -0
  72. package/dist/webhooks.d.ts +60 -0
  73. package/dist/webhooks.d.ts.map +1 -0
  74. package/dist/webhooks.js +125 -0
  75. package/dist/webhooks.js.map +1 -0
  76. package/openapi/merchant.json +21452 -0
  77. package/package.json +63 -0
@@ -0,0 +1,278 @@
1
+ import { Pool } from "pg";
2
+ /**
3
+ * The app database holds INSTALLATIONS ONLY (decision
4
+ * 2026-09-23-queek-apps-separate-ts-hono-codebase-public-surface-only).
5
+ * Business data lives in Queek (product metafields,
6
+ * orders.integrator_metadata) — never here.
7
+ *
8
+ * S1 (SDK 0.2.0): no store-callable credential crosses the install handoff
9
+ * any more, so there is no `api_key` column. The app mints short-lived
10
+ * installation tokens with its asymmetric app key and caches ONE token per
11
+ * installation here (`token_enc` + `token_expires_at` + `token_kid`);
12
+ * `webhook_secret` AND the whole `settings` blob stay encrypted at rest
13
+ * (AES-256-GCM via node:crypto, key from `APP_ENCRYPTION_KEY`): manifests
14
+ * may declare `secret` settings (API keys, webhook secrets) and the backend
15
+ * encrypts those too, so the SDK must not be weaker. NOTHING secret is ever
16
+ * logged: only ids and the store p_id may appear in logs.
17
+ */
18
+ export interface InstallationRecord {
19
+ /** Queek installation id (string form of the backend UUID). */
20
+ installationId: string;
21
+ /** Queek installation p_id (short public id, safe to log). */
22
+ installationPid: string;
23
+ /** Vendor id (backend UUID, string form). */
24
+ vendorId: string;
25
+ /** Store p_id (safe to log). */
26
+ storePid: string | null;
27
+ /** Store name (safe to log). */
28
+ storeName: string;
29
+ /** Merchant API base handed over at install. */
30
+ apiBase: string;
31
+ /**
32
+ * Cached installation token — plaintext in memory only, persisted as
33
+ * `token_enc`, null when nothing is cached (fresh install, expiry,
34
+ * explicit drop, kill switch). Never logged.
35
+ */
36
+ token: string | null;
37
+ /** ISO-8601 expiry of the cached token, null when none is cached. */
38
+ tokenExpiresAt: string | null;
39
+ /** `kid` the cached token was minted under, null when none is cached. */
40
+ tokenKid: string | null;
41
+ /**
42
+ * True while Queek last answered 409 `app_installation_pending` for this
43
+ * installation (persisted column, survives restarts — the in-process-only
44
+ * mark could not). `GET installations` lists active installations only,
45
+ * so resync's purge-absent step keeps rows flagged here. Cleared when
46
+ * the installation is seen active (resync 202/redelivery) or its mint
47
+ * succeeds; the row's deletion (404 `app_installation_gone`) drops the
48
+ * flag with the row.
49
+ */
50
+ pending: boolean;
51
+ scopes: string[];
52
+ settings: Record<string, unknown>;
53
+ /** Plaintext per-installation webhook secret — memory only. */
54
+ webhookSecret: string | null;
55
+ /**
56
+ * Plaintext per-installation proxy secret — memory only, persisted as
57
+ * `proxy_secret_enc`, null when the app has no proxy. Signs
58
+ * slot-claims (booking app); never logged (the logger redacts
59
+ * secret-named keys).
60
+ */
61
+ proxySecret: string | null;
62
+ /**
63
+ * Plaintext per-installation embed secret (`embsec_…`) — memory only,
64
+ * persisted as `embed_secret_enc`, null when the app has no merchant
65
+ * page. Verifies dashboard session tokens; never logged.
66
+ */
67
+ embedSecret?: string | null;
68
+ /** The app's own id as Queek signs it into session tokens (`app_id`); not a secret. */
69
+ appId?: string | null;
70
+ webhookUrl: string | null;
71
+ webhookTopics: string[];
72
+ installedAt: string;
73
+ updatedAt: string;
74
+ }
75
+ export interface WebhookSecretCandidate {
76
+ installationId: string;
77
+ secret: string;
78
+ }
79
+ export interface InstallationStore {
80
+ saveInstallation(record: InstallationRecord): Promise<void> | void;
81
+ getInstallation(installationId: string): Promise<InstallationRecord | null> | InstallationRecord | null;
82
+ deleteInstallation(installationId: string): Promise<void> | void;
83
+ /** Every stored installation, ordered by id — resync and cron iterate this. */
84
+ listInstallations(): Promise<InstallationRecord[]> | InstallationRecord[];
85
+ /**
86
+ * Forget one installation's cached token (expiry, token-refusal re-mint,
87
+ * resync) while keeping the installation row: the next `acquireToken`
88
+ * mints fresh.
89
+ */
90
+ clearCachedToken(installationId: string): Promise<void> | void;
91
+ /** Forget EVERY cached token (kill switch) while keeping the rows. */
92
+ clearAllCachedTokens(): Promise<void> | void;
93
+ /**
94
+ * Persist the 409 `app_installation_pending` mark: Queek refused this
95
+ * installation as not-yet-active. The flag survives restarts (plain
96
+ * column, NOT NULL DEFAULT false) so a restart between the 409 and the
97
+ * next resync can never purge the in-flight row the active-only list
98
+ * omits. Idempotent.
99
+ */
100
+ markInstallationPending(installationId: string): Promise<void> | void;
101
+ /**
102
+ * Clear the pending mark: the installation answered active again
103
+ * (resync 202/redelivery) or its mint succeeded.
104
+ */
105
+ clearInstallationPending(installationId: string): Promise<void> | void;
106
+ /** True when the row carries the persisted pending mark (false when the row is missing). */
107
+ isKnownPending(installationId: string): Promise<boolean> | boolean;
108
+ /** Secrets only (no tokens) for webhook sender identification. */
109
+ listWebhookSecrets(): Promise<WebhookSecretCandidate[]> | WebhookSecretCandidate[];
110
+ /** Replay guard: true when this webhook-id was already processed. */
111
+ hasSeenWebhookId(webhookId: string): Promise<boolean> | boolean;
112
+ /** Record a processed webhook-id (entries expire after 24h). */
113
+ markWebhookSeen(webhookId: string): Promise<void> | void;
114
+ /**
115
+ * Atomically claim a webhook-id: records it and returns true only if no
116
+ * unexpired claim exists. Handlers claim BEFORE running the callback so
117
+ * two concurrent same-id deliveries cannot both execute; on callback
118
+ * failure they `releaseWebhookId` so a Queek retry can still land.
119
+ */
120
+ claimWebhookId(webhookId: string): Promise<boolean> | boolean;
121
+ /** Release a claim (callback failed; a retry may re-run). */
122
+ releaseWebhookId(webhookId: string): Promise<void> | void;
123
+ }
124
+ export interface SqliteStoreOptions {
125
+ /** Path to the sqlite file. Use `:memory:` for tests. */
126
+ path: string;
127
+ /** Raw `APP_ENCRYPTION_KEY` value (base64 or hex of 32 bytes). */
128
+ storeKey: string;
129
+ }
130
+ /**
131
+ * Default local/dev/test `InstallationStore`: SQLite through the Node 22
132
+ * built-in `node:sqlite` (`DatabaseSync` — synchronous, file-backed, WAL
133
+ * mode).
134
+ *
135
+ * Why not better-sqlite3: its prebuilt binary segfaults on the project's
136
+ * Node 22.12 runtime (observed, not theorised), and building from source
137
+ * would force a C++ toolchain into every environment — dev Macs, CI, and
138
+ * the slim alpine app images. `node:sqlite` is dependency-free with an
139
+ * identical synchronous shape.
140
+ *
141
+ * `node:sqlite` needs no flag since Node 22.13.0 (pinned runtime 22.23.3;
142
+ * an ExperimentalWarning on stderr remains — Stability 1.1). Devs on an
143
+ * older 22 minor set `NODE_OPTIONS=--experimental-sqlite` in their shell.
144
+ * Revisit when the apps run on a Node line where it is fully stable — the
145
+ * swap is contained here, behind `InstallationStore`.
146
+ *
147
+ * 0.1.x → 0.2.0 upgrade: databases created by SDK 0.1.x carry a legacy
148
+ * `api_key_enc` column (the handoff no longer delivers that key, so its
149
+ * value is dead — minted tokens replace it; resync restores connectivity).
150
+ * Opening such a database adds the token-cache columns and drops
151
+ * `api_key_enc`; the legacy ciphertext is discarded, never decrypted.
152
+ */
153
+ export declare class SqliteInstallationStore implements InstallationStore {
154
+ private readonly db;
155
+ private readonly key;
156
+ constructor(options: SqliteStoreOptions);
157
+ private migrateFromApiKeySchema;
158
+ saveInstallation(record: InstallationRecord): void;
159
+ getInstallation(installationId: string): InstallationRecord | null;
160
+ listInstallations(): InstallationRecord[];
161
+ clearCachedToken(installationId: string): void;
162
+ clearAllCachedTokens(): void;
163
+ deleteInstallation(installationId: string): void;
164
+ markInstallationPending(installationId: string): void;
165
+ clearInstallationPending(installationId: string): void;
166
+ isKnownPending(installationId: string): boolean;
167
+ listWebhookSecrets(): WebhookSecretCandidate[];
168
+ hasSeenWebhookId(webhookId: string): boolean;
169
+ markWebhookSeen(webhookId: string): void;
170
+ claimWebhookId(webhookId: string): boolean;
171
+ releaseWebhookId(webhookId: string): void;
172
+ private pruneSeenIds;
173
+ close(): void;
174
+ }
175
+ /**
176
+ * Current schema revision, stored as exactly one row in `schema_version`
177
+ * (Postgres) and enforced by column-presence migration (SQLite).
178
+ * v2 adds the persisted 409-pending mark (`pending`, NOT NULL DEFAULT
179
+ * false on both drivers); v3 the proxy secret; v4 the embed secret and
180
+ * app id that verify dashboard session tokens (all nullable).
181
+ */
182
+ export declare const INSTALLATION_SCHEMA_VERSION = 4;
183
+ export interface PostgresStoreOptions {
184
+ /**
185
+ * Postgres connection string (usually `DATABASE_URL`). Required unless
186
+ * `pool` is given (shared-pool wiring passes the pool instead).
187
+ */
188
+ connectionString?: string;
189
+ /** Raw `APP_ENCRYPTION_KEY` value (base64 or hex of 32 bytes). */
190
+ storeKey: string;
191
+ /**
192
+ * Pool ceiling when the store owns its pool (default 2). Apps that share one
193
+ * pool per process (`createPostgresPool`) size it there: each app role has
194
+ * CONNECTION LIMIT 10, so replicas × pool max must stay under it.
195
+ */
196
+ poolMax?: number;
197
+ /**
198
+ * An existing pool to run queries on (one shared `pg` Pool per process
199
+ * between the SDK store and the app's own store — see
200
+ * `createPostgresPool`). When given, the store never ends it: `close()`
201
+ * is a no-op and the pool owner shuts it down. Ignores `poolMax` and
202
+ * `connectionString`.
203
+ */
204
+ pool?: Pool;
205
+ }
206
+ /**
207
+ * Build one shared `pg` Pool for a process (the SDK store and the app's
208
+ * own store both run on it — total connections per app stay small: one
209
+ * pool of N per process instead of one pool per store). Attaches the same
210
+ * idle-client error guard the store constructors use, so a dropped idle
211
+ * connection never surfaces as an uncaught exception.
212
+ */
213
+ export declare function createPostgresPool(connectionString: string, max?: number): Pool;
214
+ /**
215
+ * Production `InstallationStore`: Postgres through `pg` (`Pool`, max 2).
216
+ *
217
+ * Schema safety when two containers boot together: the first statement of
218
+ * `ensureSchema()` takes a Postgres advisory lock, then creates the tables
219
+ * plus exactly one `schema_version` row, then releases the lock — so
220
+ * concurrent boots serialize instead of racing DDL. Every store method
221
+ * awaits the same cached init promise, so no query runs before the schema
222
+ * exists. The AES-256-GCM envelope is byte-identical to the SQLite store
223
+ * (same `encryptSecret`/`decryptSecret`, same `APP_ENCRYPTION_KEY`).
224
+ */
225
+ export declare class PostgresInstallationStore implements InstallationStore {
226
+ private readonly pool;
227
+ private readonly ownsPool;
228
+ private readonly key;
229
+ private readonly ready;
230
+ constructor(options: PostgresStoreOptions);
231
+ private ensureSchema;
232
+ saveInstallation(record: InstallationRecord): Promise<void>;
233
+ getInstallation(installationId: string): Promise<InstallationRecord | null>;
234
+ listInstallations(): Promise<InstallationRecord[]>;
235
+ clearCachedToken(installationId: string): Promise<void>;
236
+ clearAllCachedTokens(): Promise<void>;
237
+ deleteInstallation(installationId: string): Promise<void>;
238
+ markInstallationPending(installationId: string): Promise<void>;
239
+ clearInstallationPending(installationId: string): Promise<void>;
240
+ isKnownPending(installationId: string): Promise<boolean>;
241
+ listWebhookSecrets(): Promise<WebhookSecretCandidate[]>;
242
+ hasSeenWebhookId(webhookId: string): Promise<boolean>;
243
+ markWebhookSeen(webhookId: string): Promise<void>;
244
+ claimWebhookId(webhookId: string): Promise<boolean>;
245
+ releaseWebhookId(webhookId: string): Promise<void>;
246
+ private pruneSeenIds;
247
+ /**
248
+ * Drain the pool (tests and graceful shutdown). A no-op when the store
249
+ * runs on a shared pool it does not own — the pool owner ends it.
250
+ */
251
+ close(): Promise<void>;
252
+ }
253
+ export interface InstallationStoreSelector {
254
+ /** Raw `APP_ENCRYPTION_KEY` value (base64 or hex of 32 bytes). */
255
+ storeKey: string;
256
+ /**
257
+ * Postgres connection string. Defaults to `DATABASE_URL`; when set (and
258
+ * non-blank) the Postgres store wins, otherwise SQLite.
259
+ */
260
+ databaseUrl?: string;
261
+ /** SQLite file path. Defaults to `QUEEK_DB_PATH`, else `./data/installations.db`. */
262
+ sqlitePath?: string;
263
+ /** Postgres pool ceiling (default 2). */
264
+ poolMax?: number;
265
+ /**
266
+ * A shared pool from `createPostgresPool`. When given, Postgres wins
267
+ * regardless of `DATABASE_URL` (the pool already carries the DSN).
268
+ */
269
+ pool?: Pool;
270
+ }
271
+ /**
272
+ * Pick the installation store: `DATABASE_URL` set (or a shared `pool`
273
+ * given) → Postgres; otherwise SQLite — which production REFUSES (fail
274
+ * fast with a clear message: a live app must never run on a
275
+ * container-local database).
276
+ */
277
+ export declare function createInstallationStore(options: InstallationStoreSelector): InstallationStore;
278
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}