@usequeek/app-sdk 0.4.0 → 0.5.1

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 CHANGED
@@ -2,6 +2,48 @@
2
2
 
3
3
  All notable changes to `@usequeek/app-sdk` are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
4
 
5
+ ## [0.5.1] - 2026-09-29
6
+
7
+ Patch: `APP_PRIVATE_KEY` accepts the one-line form env files need.
8
+
9
+ ### Changed
10
+
11
+ - `loadAppCredential` accepts `APP_PRIVATE_KEY` as base64 of the full PEM text (one line, no
12
+ wrapping — what the Developer page shows), a one-line PEM with literal `\n` escapes, or raw
13
+ PEM as before. Detection: a trimmed value starting with `-----BEGIN` is PEM; anything else is
14
+ base64-decoded and must decode to `-----BEGIN…`. Same RSA validation afterwards; errors name
15
+ the accepted forms and never echo the value.
16
+
17
+ ## [0.5.0] - 2026-09-29
18
+
19
+ Framework-agnostic core: the install handoff and webhook receivers no longer require Hono.
20
+
21
+ ### Changed
22
+
23
+ - **BREAKING:** `createInstallHandlers` and `createWebhookHandler` moved from the package root to
24
+ the `@usequeek/app-sdk/hono` subpath (thin wrappers over the new core — same options objects,
25
+ same behaviour, same errors/status codes). Migration:
26
+ `import { createInstallHandlers } from "@usequeek/app-sdk/hono"`. `hono` is now an optional
27
+ peer (`peerDependenciesMeta: { hono: { optional: true } }`), so non-Hono apps install zero
28
+ framework code. `./server` keeps working as today.
29
+ - The root entry is framework-free in three thin layers, each a wrapper over the one below:
30
+ layer 1 `handleInstallDelivery(input, options)` / `handleWebhookDelivery(input, options)` take
31
+ untouched body bytes + headers (`Record` or `Headers`, case-insensitive, array-tolerant) plus
32
+ method/path where the install endpoints genuinely need them, and return plain
33
+ `{ status, body }` — zero request/response types, so whatever request object each framework
34
+ supports works; layer 2 `handleInstallRequest` / `handleWebhookRequest` adapt the Web-standard
35
+ `Request` → `Response` onto layer 1; layer 3 `@usequeek/app-sdk/hono` adapts Hono onto layer 2.
36
+
37
+ ### Added
38
+
39
+ - `delivery.ts`: `CoreDelivery` / `InstallDelivery` / `DeliveryResult` / `CoreHeaders` plus
40
+ `readHeader`, `decodeBody`, `toResponse`.
41
+ - `hono.ts` behind the `./hono` export: the Hono wrappers.
42
+ - `scripts/verify-package.mjs` now proves the split in two sandboxes: the root entry plus
43
+ `./server` work with NO `hono` installed and NO framework at all (layer 1 is called directly
44
+ with a `Buffer` + plain headers; importing `/hono` there fails — the proof the root carries
45
+ zero framework imports), while `/hono` works with it.
46
+
5
47
  ## [0.2.0] - 2026-09-25
6
48
 
7
49
  GitHub-style app credentials (slice S1 of `app-credentials-and-databases`, built against the
package/README.md CHANGED
@@ -1,34 +1,147 @@
1
1
  # @usequeek/app-sdk
2
2
 
3
- The SDK for building a Queek app on the public Merchant API and signed webhooks. Hono route helpers for the install handoff and topic webhooks, a typed Merchant API client (types generated from the live contract), GitHub-style app credentials (one asymmetric key per app, short-lived per-installation tokens minted on demand), resync recovery, and an encrypted installation store (SQLite for local/test, Postgres in production).
3
+ The SDK for building a Queek app on the public Merchant API and signed webhooks. Framework-agnostic Web-standard handlers for the install handoff and topic webhooks (`Request` in, `Response` out — use them from Next.js route handlers, Express, or any runtime), a typed Merchant API client (types generated from the live contract), GitHub-style app credentials (one asymmetric key per app, short-lived per-installation tokens minted on demand), resync recovery, and an encrypted installation store (SQLite for local/test, Postgres in production). Optional Hono wrappers live under `@usequeek/app-sdk/hono`.
4
4
 
5
5
  ```sh
6
- npm i @usequeek/app-sdk hono pg
6
+ npm i @usequeek/app-sdk pg
7
7
  ```
8
8
 
9
- Requires Node `>=22.14`. `hono` is a peer dependency so your app never carries two copies. `pg` is a regular dependency (the production store).
9
+ Requires Node `>=22.14`. `pg` is a regular dependency (the production store). `hono` is an optional peer — install it (`npm i hono`) only if you use the Hono wrappers.
10
10
 
11
- ## Example
11
+ The shape follows [`@shopify/shopify-api`](https://github.com/Shopify/shopify-app-js/blob/main/packages/apps/shopify-api/README.md): the core "doesn't rely on any specific framework, so you can include it alongside your preferred stack" (runtime differences are covered by adapters such as `@shopify/shopify-api/adapters/node`), and framework integrations are separate packages in the [shopify-app-js monorepo](https://github.com/Shopify/shopify-app-js) (e.g. `@shopify/shopify-app-express` and `@shopify/shopify-app-remix` build on `@shopify/shopify-api`).
12
12
 
13
- A minimal app: health check, install/uninstall/settings handlers, and one webhook topic:
13
+ ## Example (any framework)
14
+
15
+ A minimal app with plain Web-standard handlers — no framework import:
14
16
 
15
17
  ```ts
16
18
  import {
17
19
  createAppTokenProvider,
18
- createInstallHandlers,
19
- createWebhookHandler,
20
+ handleInstallRequest,
21
+ handleWebhookRequest,
20
22
  loadAppCredential,
21
23
  SqliteInstallationStore,
22
24
  } from "@usequeek/app-sdk";
23
- import { Hono } from "hono";
24
25
 
25
26
  const store = new SqliteInstallationStore({
26
27
  path: "./data/installations.db",
27
28
  storeKey: process.env.APP_ENCRYPTION_KEY!,
28
29
  });
29
30
  const tokens = createAppTokenProvider({
30
- credential: loadAppCredential({ appSlug: "hello" }), // APP_SLUG/APP_KEY_ID/APP_PRIVATE_KEY
31
+ credential: loadAppCredential({ appSlug: "hello" }), // APP_SLUG/APP_KEY_ID/APP_PRIVATE_KEY (base64 of the PEM, one line)
32
+ store,
33
+ });
34
+ const installOptions = { appSecret: process.env.QUEEK_APP_SECRET!, store };
35
+ const webhookOptions = {
31
36
  store,
37
+ handlers: {
38
+ "orders/updated": async (envelope, context) => {
39
+ console.log("order update:", context.installation.storePid, envelope.data);
40
+ },
41
+ },
42
+ };
43
+ ```
44
+
45
+ Next.js App Router — one route file per handoff path (`handleInstallRequest` routes on the request URL's trailing `install` / `uninstall` / `settings` segment, so one shared options object serves all three):
46
+
47
+ ```ts
48
+ // app/api/install/route.ts (and uninstall/route.ts, settings/route.ts likewise)
49
+ import { installOptions } from "./options";
50
+
51
+ export async function POST(request: Request) {
52
+ return handleInstallRequest(request, installOptions);
53
+ }
54
+
55
+ // app/api/webhooks/route.ts
56
+ import { webhookOptions } from "./options";
57
+
58
+ export async function POST(request: Request) {
59
+ return handleWebhookRequest(request, webhookOptions);
60
+ }
61
+ ```
62
+
63
+ ### Express (no new package)
64
+
65
+ Express hands you whatever request object it supports — pass its raw body bytes and headers straight to the layer-1 core (no `Request` construction needed). Keep the untouched bytes Queek signed with the built-in `express.raw` parser:
66
+
67
+ ```ts
68
+ import express from "express";
69
+ import {
70
+ type DeliveryResult,
71
+ handleInstallDelivery,
72
+ handleWebhookDelivery,
73
+ } from "@usequeek/app-sdk";
74
+
75
+ const app = express();
76
+ app.use("/api", express.raw({ type: "application/json" }));
77
+
78
+ function reply(res: express.Response, result: DeliveryResult) {
79
+ res.status(result.status).json(result.body);
80
+ }
81
+
82
+ for (const route of ["install", "uninstall", "settings"]) {
83
+ app.post(`/api/${route}`, async (req, res) => {
84
+ reply(
85
+ res,
86
+ await handleInstallDelivery(
87
+ { rawBody: req.body as Buffer, headers: req.headers, method: req.method, path: req.path },
88
+ installOptions,
89
+ ),
90
+ );
91
+ });
92
+ }
93
+ app.post("/api/webhooks", async (req, res) => {
94
+ reply(
95
+ res,
96
+ await handleWebhookDelivery({ rawBody: req.body as Buffer, headers: req.headers }, webhookOptions),
97
+ );
98
+ });
99
+ ```
100
+
101
+ ### Fastify (no new package)
102
+
103
+ Same idea — keep the body raw with `addContentTypeParser`, then call the core directly:
104
+
105
+ ```ts
106
+ import Fastify from "fastify";
107
+ import { handleWebhookDelivery } from "@usequeek/app-sdk";
108
+
109
+ const fastify = Fastify();
110
+ fastify.addContentTypeParser("application/json", { parseAs: "buffer" }, (_req, body, done) => {
111
+ done(null, body);
112
+ });
113
+
114
+ fastify.post("/api/webhooks", async (req, reply) => {
115
+ const result = await handleWebhookDelivery(
116
+ { rawBody: req.body as Buffer, headers: req.headers },
117
+ webhookOptions,
118
+ );
119
+ return reply.status(result.status).send(result.body);
120
+ });
121
+ ```
122
+
123
+ ### Why the raw body matters
124
+
125
+ Signature verification covers the exact bytes Queek sent (`{id}.{timestamp}.{body}`), not the parsed JSON value — so the SDK takes the untouched body bytes at every layer. A parsed-then-restringified body has different bytes (spacing, key order) and will NOT verify. A string `rawBody` is used verbatim, so only pass a string when it is already the exact UTF-8 text — otherwise prefer `Buffer`/`Uint8Array` straight from `express.raw`, Fastify's `parseAs: "buffer"`, or `await request.arrayBuffer()`. This is Stripe's model (`stripe.webhooks.constructEvent(rawBody, sigHeader, secret)`): [their docs](https://docs.stripe.com/webhooks) put it bluntly — "Stripe requires the raw body of the request to perform signature verification… Any manipulation to the raw body of the request causes the verification to fail." In practice: Express needs `express.raw(...)` (never `express.json()`) on webhook routes, Fastify needs `addContentTypeParser` with `parseAs: "buffer"`, and in Next.js you read `await request.arrayBuffer()` (the SDK's layer 2 already does) rather than `await request.json()`.
126
+
127
+ ### Body-size posture
128
+
129
+ The SDK itself imposes no maximum body size (`arrayBuffer` / `TextDecoder` / `JSON.parse` are unbounded, as in 0.4.0) — the cap belongs to the framework parser in front of it, which already rejects oversized bodies before the SDK ever sees them. Queek deliveries are small JSON payloads, so the framework defaults are plenty; if you set them explicitly, `express.raw({ type: "application/json", limit: "1mb" })` and Fastify's default `bodyLimit` of 1 MiB are the recommended ceilings. No SDK option is needed unless Queek ever ships large deliveries.
130
+
131
+ (If you already run Hono on Node, `@hono/node-server`'s `getRequestListener` bridges serving for you — but the adapters above need no extra dependency.)
132
+
133
+ ### Hono
134
+
135
+ Prefer Hono? The thin wrappers under `@usequeek/app-sdk/hono` (same options, same behaviour, same errors/status codes) mount the same core:
136
+
137
+ ```ts
138
+ import { SqliteInstallationStore } from "@usequeek/app-sdk";
139
+ import { createInstallHandlers, createWebhookHandler } from "@usequeek/app-sdk/hono";
140
+ import { Hono } from "hono";
141
+
142
+ const store = new SqliteInstallationStore({
143
+ path: "./data/installations.db",
144
+ storeKey: process.env.APP_ENCRYPTION_KEY!,
32
145
  });
33
146
 
34
147
  const app = new Hono();
@@ -49,6 +162,8 @@ app.route(
49
162
  export default app;
50
163
  ```
51
164
 
165
+ > Migrating from 0.4.x: `import { createInstallHandlers } from "@usequeek/app-sdk/hono"` — the creators moved out of the root entry so non-Hono apps never install `hono`. The options objects are unchanged.
166
+
52
167
  Every Merchant API call goes through `createInstallationClient({ installationId, apiBase, tokens })`,
53
168
  which resolves the installation's token via `acquireToken()` and sends it as `X-Client-Key`.
54
169
 
@@ -72,7 +187,8 @@ One asymmetric credential per app — no per-installation secrets cross the hand
72
187
 
73
188
  Queek prints the app secret (`QUEEK_APP_SECRET`, verifies the handoff) and the key id
74
189
  (`APP_KEY_ID`, rides the JWT `kid` header). Configure the app with `APP_SLUG` (= `iss`),
75
- `APP_KEY_ID`, and `APP_PRIVATE_KEY` (the PEM — never logged, never shipped to clients).
190
+ `APP_KEY_ID`, and `APP_PRIVATE_KEY` (base64 of the private key PEM, one line — the
191
+ Developer page shows it; raw PEM also accepted — never logged, never shipped to clients).
76
192
 
77
193
  3. **Acquire / cache / re-mint.** `acquireToken(installationId)` serves the cached token while
78
194
  its expiry is more than 5 minutes away; otherwise it signs an RS256 app JWT
@@ -133,8 +249,9 @@ retries (~4 h) are gone; resync cannot backfill them. Full runbook: `docs/deploy
133
249
 
134
250
  ## API surface
135
251
 
136
- - **app-auth** (`app-auth.ts`): `loadAppCredential` (`APP_SLUG`/`APP_KEY_ID`/`APP_PRIVATE_KEY`,
137
- PEM validated at boot), `signAppJwt` (RS256, `iat` now − 60 s, `exp` window 540 s ≤ 600 s,
252
+ - **app-auth** (`app-auth.ts`): `loadAppCredential` (`APP_SLUG`/`APP_KEY_ID`/`APP_PRIVATE_KEY`
253
+ — base64 of the PEM, raw PEM, or `\n`-escaped one-line PEM; RSA validated at boot),
254
+ `signAppJwt` (RS256, `iat` now − 60 s, `exp` window 540 s ≤ 600 s,
138
255
  `kid` header), the wire-contract error codes in one place (`INVALID_CLIENT_CODE`,
139
256
  `APP_TOKEN_REVOKED_CODE`, `APP_INSTALLATION_GONE_CODE`, `APP_INSTALLATION_PENDING_CODE`,
140
257
  `RESYNC_COOLDOWN_CODE`, `TOO_MANY_REQUESTS_CODE`), `AppMintHaltedError`.
@@ -148,9 +265,10 @@ retries (~4 h) are gone; resync cannot backfill them. Full runbook: `docs/deploy
148
265
  429 `resync_cooldown` → skip + record; other 429 → backoff + retry) → drop tokens →
149
266
  purge absent except known-pending. Connectivity scope only.
150
267
  - **verify** (`signatures.ts`): `verifyQueekSignature` — Standard Webhooks verification (`webhook-id`, `webhook-timestamp`, `webhook-signature` over `{id}.{timestamp}.{body}`, keyed by the decoded `whsec_…` bytes), with timestamp-skew enforcement.
151
- - **install handlers** (`install-handlers.ts`): `createInstallHandlers({ appSecret, store, onInstall?, onUninstall?, onSettings? })` — serves the signed install/uninstall/settings handoff. Defaults persist the installation (encrypted) in the store; a redelivered install for an existing installation merges idempotently (`saveResyncedInstallation`).
268
+ - **delivery core** (`delivery.ts`): `CoreDelivery` (`rawBody` + `headers`) / `InstallDelivery` (+ `method`/`path`) / `DeliveryResult` (`{ status, body }`) / `CoreHeaders`, plus `readHeader` (case-insensitive, array-tolerant), `decodeBody`, and `toResponse`. Zero request/response types.
269
+ - **install handlers** (`install-handlers.ts`): layer 1 `handleInstallDelivery(input, { appSecret, store, onInstall?, onUninstall?, onSettings? })` serves the signed install/uninstall/settings handoff from raw bytes + headers (routes on the path's trailing segment); layer 2 `handleInstallRequest(request, …)` adapts `Request` → `Response` onto it. Defaults persist the installation (encrypted) in the store; a redelivered install for an existing installation merges idempotently (`saveResyncedInstallation`). The Hono wrapper `createInstallHandlers` lives under `@usequeek/app-sdk/hono` (`hono.ts`).
152
270
  - **client** (`client.ts`): `createQueekClient({ apiBase, apiKey })` — the low-level typed fetch client over the Merchant API (`X-Client-Key`), with `Idempotency-Key` on writes, typed `QueekApiError`s, and 429 retry helpers. Types come from `openapi/merchant.json`, the committed snapshot of the live contract. Prefer `createInstallationClient` in apps.
153
- - **webhooks** (`webhooks.ts`): `createWebhookHandler({ store, handlers })` — verifies each delivery against the installation's endpoint secret, dedupes on `webhook-id`, and dispatches `topic → handler` at most once.
271
+ - **webhooks** (`webhooks.ts`): layer 1 `handleWebhookDelivery(input, { store, handlers })` verifies each delivery against the installation's endpoint secret, dedupes on `webhook-id`, and dispatches `topic → handler` at most once; layer 2 `handleWebhookRequest(request, …)` adapts `Request` → `Response` onto it. The Hono wrapper `createWebhookHandler` lives under `@usequeek/app-sdk/hono` (`hono.ts`).
154
272
  - **store** (`store.ts`): `SqliteInstallationStore` (local/dev/test) and `PostgresInstallationStore`
155
273
  (`pg`, pool max 2, advisory-locked schema + `schema_version` row so two containers boot
156
274
  safely) — installations encrypted at rest (AES-GCM via `APP_ENCRYPTION_KEY`), plus the
@@ -117,9 +117,22 @@ export interface AppCredentialOptions {
117
117
  privateKeyPem?: string;
118
118
  env?: NodeJS.ProcessEnv;
119
119
  }
120
+ /**
121
+ * Accepted `APP_PRIVATE_KEY` forms (env files are one line per variable):
122
+ * raw PEM text, one-line PEM with literal `\n` escapes, or base64 of the
123
+ * full PEM text (one line, no wrapping — what the Developer page shows).
124
+ */
125
+ export declare const APP_PRIVATE_KEY_FORMS = "raw PEM text, one-line PEM with literal \\n escapes, or base64 of the PEM text";
126
+ /**
127
+ * Normalize an `APP_PRIVATE_KEY` value to PEM text. Detection: a trimmed
128
+ * value starting with `-----BEGIN` is PEM (literal `\n` unescaped first);
129
+ * anything else is base64-decoded and must decode to `-----BEGIN…`.
130
+ * Never echoes the value.
131
+ */
132
+ export declare function decodePrivateKeyInput(raw: string): string;
120
133
  /**
121
134
  * Load the app credential: explicit options win, otherwise `APP_SLUG`,
122
- * `APP_KEY_ID`, `APP_PRIVATE_KEY` from env. The PEM must parse as an RSA
135
+ * `APP_KEY_ID`, `APP_PRIVATE_KEY` from env. The key must parse as an RSA
123
136
  * private key here, once, so a broken key fails at boot — never mid-mint.
124
137
  * Throws `InvalidAppCredentialError` before any fetch.
125
138
  */
@@ -1 +1 @@
1
- {"version":3,"file":"app-auth.d.ts","sourceRoot":"","sources":["../src/app-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-auth.d.ts","sourceRoot":"","sources":["../src/app-auth.ts"],"names":[],"mappings":"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"}
package/dist/app-auth.js CHANGED
@@ -140,9 +140,32 @@ export class UnknownInstallationError extends Error {
140
140
  this.name = "UnknownInstallationError";
141
141
  }
142
142
  }
143
+ /**
144
+ * Accepted `APP_PRIVATE_KEY` forms (env files are one line per variable):
145
+ * raw PEM text, one-line PEM with literal `\n` escapes, or base64 of the
146
+ * full PEM text (one line, no wrapping — what the Developer page shows).
147
+ */
148
+ export const APP_PRIVATE_KEY_FORMS = "raw PEM text, one-line PEM with literal \\n escapes, or base64 of the PEM text";
149
+ /**
150
+ * Normalize an `APP_PRIVATE_KEY` value to PEM text. Detection: a trimmed
151
+ * value starting with `-----BEGIN` is PEM (literal `\n` unescaped first);
152
+ * anything else is base64-decoded and must decode to `-----BEGIN…`.
153
+ * Never echoes the value.
154
+ */
155
+ export function decodePrivateKeyInput(raw) {
156
+ const trimmed = raw.trim();
157
+ if (trimmed.startsWith("-----BEGIN")) {
158
+ return trimmed.replace(/\\n/g, "\n").trim();
159
+ }
160
+ const decoded = Buffer.from(trimmed, "base64").toString("utf8");
161
+ if (!decoded.trimStart().startsWith("-----BEGIN")) {
162
+ throw new InvalidAppCredentialError(`Invalid APP_PRIVATE_KEY: not a PEM and not base64 of a PEM. Accepted forms: ${APP_PRIVATE_KEY_FORMS}.`);
163
+ }
164
+ return decoded.trim();
165
+ }
143
166
  /**
144
167
  * Load the app credential: explicit options win, otherwise `APP_SLUG`,
145
- * `APP_KEY_ID`, `APP_PRIVATE_KEY` from env. The PEM must parse as an RSA
168
+ * `APP_KEY_ID`, `APP_PRIVATE_KEY` from env. The key must parse as an RSA
146
169
  * private key here, once, so a broken key fails at boot — never mid-mint.
147
170
  * Throws `InvalidAppCredentialError` before any fetch.
148
171
  */
@@ -156,10 +179,11 @@ export function loadAppCredential(options = {}) {
156
179
  if (keyId === "") {
157
180
  throw new InvalidAppCredentialError("Missing APP_KEY_ID: set it to the kid registered with Queek (`php artisan app:register --public-key=…`).");
158
181
  }
159
- const privateKeyPem = (options.privateKeyPem ?? env.APP_PRIVATE_KEY ?? "").trim();
160
- if (privateKeyPem === "") {
161
- throw new InvalidAppCredentialError("Missing APP_PRIVATE_KEY: set it to the app's PEM-encoded RSA private key.");
182
+ const privateKeyInput = (options.privateKeyPem ?? env.APP_PRIVATE_KEY ?? "").trim();
183
+ if (privateKeyInput === "") {
184
+ throw new InvalidAppCredentialError(`Missing APP_PRIVATE_KEY: set it to base64 of the app's RSA private key PEM (one line). Accepted forms: ${APP_PRIVATE_KEY_FORMS}.`);
162
185
  }
186
+ const privateKeyPem = decodePrivateKeyInput(privateKeyInput);
163
187
  try {
164
188
  const key = createPrivateKey(privateKeyPem);
165
189
  if (key.asymmetricKeyType !== "rsa") {
@@ -169,7 +193,7 @@ export function loadAppCredential(options = {}) {
169
193
  catch (error) {
170
194
  if (error instanceof InvalidAppCredentialError)
171
195
  throw error;
172
- throw new InvalidAppCredentialError(`Invalid APP_PRIVATE_KEY: not a parseable PEM private key (${error instanceof Error ? error.message : "undecodable"}).`);
196
+ throw new InvalidAppCredentialError(`Invalid APP_PRIVATE_KEY: not a parseable PEM private key (${error instanceof Error ? error.message : "undecodable"}). Accepted forms: ${APP_PRIVATE_KEY_FORMS}.`);
173
197
  }
174
198
  // The PEM stays in this object only; callers must never log it (see
175
199
  // `signAppJwt`: the only consumer, and it never emits the key).
@@ -1 +1 @@
1
- {"version":3,"file":"app-auth.js","sourceRoot":"","sources":["../src/app-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-auth.js","sourceRoot":"","sources":["../src/app-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Shared plumbing for the framework-free delivery core (layer 1).
3
+ *
4
+ * Layer 1 functions take plain data — untouched body bytes plus headers —
5
+ * and return plain `{ status, body }` results. They reference zero
6
+ * request/response types (no `Request`, no framework), so any framework
7
+ * that can hand over the raw body bytes can use them. Layer 2
8
+ * (`handleInstallRequest` / `handleWebhookRequest`) adapts the Web
9
+ * standard onto this core; `@usequeek/app-sdk/hono` adapts Hono onto
10
+ * layer 2.
11
+ *
12
+ * The raw-body rule (Stripe's model:
13
+ * `stripe.webhooks.constructEvent(rawBody, sigHeader, secret)` —
14
+ * https://docs.stripe.com/webhooks: "Stripe requires the raw body of the
15
+ * request to perform signature verification… Any manipulation to the raw
16
+ * body of the request causes the verification to fail"): `rawBody` must be
17
+ * the exact bytes Queek signed. Never pass a parsed-then-restringified
18
+ * body — JSON re-serialization changes bytes (spacing, key order) and the
19
+ * signature will not verify.
20
+ */
21
+ /** Headers as any framework holds them: a `Headers` instance, or a plain object (Express-style: lowercased keys, array values allowed). */
22
+ export type CoreHeaders = Record<string, string | string[] | undefined> | Headers;
23
+ /** The framework-free delivery input both core handlers take. */
24
+ export interface CoreDelivery {
25
+ /** The untouched body bytes Queek signed (string is used verbatim; binary is UTF-8-decoded). */
26
+ rawBody: Uint8Array | Buffer | string;
27
+ headers: CoreHeaders;
28
+ }
29
+ /** Layer-1 input for the install handoff, which genuinely needs routing. */
30
+ export interface InstallDelivery extends CoreDelivery {
31
+ /** Defaults to `"POST"`. Anything else answers 405. */
32
+ method?: string;
33
+ /** Request path (`/install`, …) or full URL — routes on the trailing `install` / `uninstall` / `settings` segment. */
34
+ path?: string;
35
+ }
36
+ /** What the layer-1 core returns: an HTTP status plus a JSON-serializable body. */
37
+ export interface DeliveryResult {
38
+ status: number;
39
+ body: unknown;
40
+ headers?: Record<string, string>;
41
+ }
42
+ /** Case-insensitive header lookup across `Headers` and plain (possibly lowercased, possibly array-valued) objects. */
43
+ export declare function readHeader(headers: CoreHeaders, name: string): string | undefined;
44
+ /** Decode untouched body bytes to the exact string Queek signed. */
45
+ export declare function decodeBody(rawBody: Uint8Array | Buffer | string): string;
46
+ /** Build the layer-2 `Response` from a layer-1 result. */
47
+ export declare function toResponse(result: DeliveryResult): Response;
48
+ //# sourceMappingURL=delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,2IAA2I;AAC3I,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC;AAElF,iEAAiE;AACjE,MAAM,WAAW,YAAY;IAC3B,gGAAgG;IAChG,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sHAAsH;IACtH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,sHAAsH;AACtH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYjF;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAGxE;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAE3D"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared plumbing for the framework-free delivery core (layer 1).
3
+ *
4
+ * Layer 1 functions take plain data — untouched body bytes plus headers —
5
+ * and return plain `{ status, body }` results. They reference zero
6
+ * request/response types (no `Request`, no framework), so any framework
7
+ * that can hand over the raw body bytes can use them. Layer 2
8
+ * (`handleInstallRequest` / `handleWebhookRequest`) adapts the Web
9
+ * standard onto this core; `@usequeek/app-sdk/hono` adapts Hono onto
10
+ * layer 2.
11
+ *
12
+ * The raw-body rule (Stripe's model:
13
+ * `stripe.webhooks.constructEvent(rawBody, sigHeader, secret)` —
14
+ * https://docs.stripe.com/webhooks: "Stripe requires the raw body of the
15
+ * request to perform signature verification… Any manipulation to the raw
16
+ * body of the request causes the verification to fail"): `rawBody` must be
17
+ * the exact bytes Queek signed. Never pass a parsed-then-restringified
18
+ * body — JSON re-serialization changes bytes (spacing, key order) and the
19
+ * signature will not verify.
20
+ */
21
+ /** Case-insensitive header lookup across `Headers` and plain (possibly lowercased, possibly array-valued) objects. */
22
+ export function readHeader(headers, name) {
23
+ if (headers instanceof Headers) {
24
+ return headers.get(name) ?? undefined;
25
+ }
26
+ const want = name.toLowerCase();
27
+ for (const [key, value] of Object.entries(headers)) {
28
+ if (key.toLowerCase() === want) {
29
+ if (value === undefined)
30
+ return undefined;
31
+ return Array.isArray(value) ? value[0] : value;
32
+ }
33
+ }
34
+ return undefined;
35
+ }
36
+ /** Decode untouched body bytes to the exact string Queek signed. */
37
+ export function decodeBody(rawBody) {
38
+ if (typeof rawBody === "string")
39
+ return rawBody;
40
+ return new TextDecoder("utf-8").decode(rawBody);
41
+ }
42
+ /** Build the layer-2 `Response` from a layer-1 result. */
43
+ export function toResponse(result) {
44
+ return Response.json(result.body, { status: result.status, headers: result.headers });
45
+ }
46
+ //# sourceMappingURL=delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery.js","sourceRoot":"","sources":["../src/delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA2BH,sHAAsH;AACtH,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,IAAY;IAC3D,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;IACxC,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;YAC/B,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,OAAqC;IAC9D,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,UAAU,CAAC,MAAsB;IAC/C,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AACxF,CAAC"}
package/dist/hono.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Optional Hono integration for `@usequeek/app-sdk`.
3
+ *
4
+ * Import from `@usequeek/app-sdk/hono` (requires the optional `hono` peer):
5
+ * `createInstallHandlers` and `createWebhookHandler` are thin wrappers
6
+ * built ONLY on the layer-2 Web-standard handlers (`handleInstallRequest`
7
+ * / `handleWebhookRequest` in the root entry) — same options objects, same
8
+ * behaviour, same errors/status codes.
9
+ */
10
+ import { Hono } from "hono";
11
+ import { type InstallHandlerOptions } from "./install-handlers.js";
12
+ import { type WebhookHandlerOptions } from "./webhooks.js";
13
+ export type { InstallCallbacks, InstallHandlerOptions } from "./install-handlers.js";
14
+ export type { QueekWebhookEnvelope, SecretResolution, WebhookHandlerContext, WebhookHandlerFn, WebhookHandlerOptions, } from "./webhooks.js";
15
+ /** Mount the signed install/uninstall/settings handoff (`POST /install`, `POST /uninstall`, `POST /settings`). */
16
+ export declare function createInstallHandlers(options: InstallHandlerOptions): Hono;
17
+ /** Mount the signed topic-delivery receiver (`POST /`). */
18
+ export declare function createWebhookHandler(options: WebhookHandlerOptions): Hono;
19
+ //# sourceMappingURL=hono.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../src/hono.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEjF,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,kHAAkH;AAClH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAM1E;AAED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAIzE"}
package/dist/hono.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Optional Hono integration for `@usequeek/app-sdk`.
3
+ *
4
+ * Import from `@usequeek/app-sdk/hono` (requires the optional `hono` peer):
5
+ * `createInstallHandlers` and `createWebhookHandler` are thin wrappers
6
+ * built ONLY on the layer-2 Web-standard handlers (`handleInstallRequest`
7
+ * / `handleWebhookRequest` in the root entry) — same options objects, same
8
+ * behaviour, same errors/status codes.
9
+ */
10
+ import { Hono } from "hono";
11
+ import { handleInstallRequest } from "./install-handlers.js";
12
+ import { handleWebhookRequest } from "./webhooks.js";
13
+ /** Mount the signed install/uninstall/settings handoff (`POST /install`, `POST /uninstall`, `POST /settings`). */
14
+ export function createInstallHandlers(options) {
15
+ const app = new Hono();
16
+ app.post("/install", (c) => handleInstallRequest(c.req.raw, options));
17
+ app.post("/uninstall", (c) => handleInstallRequest(c.req.raw, options));
18
+ app.post("/settings", (c) => handleInstallRequest(c.req.raw, options));
19
+ return app;
20
+ }
21
+ /** Mount the signed topic-delivery receiver (`POST /`). */
22
+ export function createWebhookHandler(options) {
23
+ const app = new Hono();
24
+ app.post("/", (c) => handleWebhookRequest(c.req.raw, options));
25
+ return app;
26
+ }
27
+ //# sourceMappingURL=hono.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono.js","sourceRoot":"","sources":["../src/hono.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAA8B,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAA8B,MAAM,eAAe,CAAC;AAWjF,kHAAkH;AAClH,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IACjE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/D,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/index.d.ts CHANGED
@@ -8,18 +8,19 @@
8
8
  * PER-INSTALLATION endpoint secret). The Merchant API takes the
9
9
  * installation credential as `X-Client-Key`.
10
10
  */
11
- export { API_KEY_EXPIRED_CODE, API_KEY_REVOKED_CODE, APP_INSTALLATION_GONE_CODE, APP_INSTALLATION_PENDING_CODE, APP_JWT_SKEW_SECONDS, APP_JWT_TTL_SECONDS, APP_TOKEN_REVOKED_CODE, type AppCredential, AppMintHaltedError, INVALID_CLIENT_CODE, INVALID_CLIENT_KEY_CODE, InvalidAppCredentialError, isAppTokenRevoked, isInstallationGone, isInstallationPending, isInvalidClient, isResyncCooldown, isTokenRefusal, loadAppCredential, MAX_MINT_ATTEMPTS, MINT_BACKOFF_BASE_MS, MINT_BACKOFF_MAX_MS, RESYNC_COOLDOWN_CODE, RETRY_JITTER_MAX_MS, type SignAppJwtOptions, signAppJwt, TOKEN_VALIDITY_SKEW_SECONDS, TOO_MANY_REQUESTS_CODE, UnknownInstallationError, } from "./app-auth.js";
11
+ export { API_KEY_EXPIRED_CODE, APP_PRIVATE_KEY_FORMS, decodePrivateKeyInput, API_KEY_REVOKED_CODE, APP_INSTALLATION_GONE_CODE, APP_INSTALLATION_PENDING_CODE, APP_JWT_SKEW_SECONDS, APP_JWT_TTL_SECONDS, APP_TOKEN_REVOKED_CODE, type AppCredential, AppMintHaltedError, INVALID_CLIENT_CODE, INVALID_CLIENT_KEY_CODE, InvalidAppCredentialError, isAppTokenRevoked, isInstallationGone, isInstallationPending, isInvalidClient, isResyncCooldown, isTokenRefusal, loadAppCredential, MAX_MINT_ATTEMPTS, MINT_BACKOFF_BASE_MS, MINT_BACKOFF_MAX_MS, RESYNC_COOLDOWN_CODE, RETRY_JITTER_MAX_MS, type SignAppJwtOptions, signAppJwt, TOKEN_VALIDITY_SKEW_SECONDS, TOO_MANY_REQUESTS_CODE, UnknownInstallationError, } from "./app-auth.js";
12
12
  export { backgroundTaskCount, type CatchupFailure, type CatchupInstallation, type CatchupOptions, type CatchupResult, type DetachOptions, detach, runInstallationCatchup, } from "./background.js";
13
13
  export { apiHostsFromEnv, createQueekClient, DEFAULT_API_HOSTS, devApiHostsFromEnv, InvalidApiBaseError, MERCHANT_API_PATH, type MerchantPaths, newIdempotencyKey, type OperationResponse, QueekApiError, type QueekClient, type QueekClientOptions, type QueekErrorDetails, queekApiErrorFromResponse, type RequestOptions, type RetryOptions, resolveApiBase, type StoreProfile, } from "./client.js";
14
14
  export { type AlertBody, type AlertSeverity, type CollectedDefinition, type CollectedDefinitionCreate, type CollectedDefinitionUpdate, type CollectedField, collectedDefinitions, createRecord, type MerchantAlert, type SetupNotice, type SetupNoticeBody, type SetupNoticeItem, type SetupNoticeStatus, type SuccessEnvelope, sendAlert, setSetupNotice, } from "./collected.js";
15
15
  export { decryptSecret, encryptSecret, parseStoreKey, storeKeyFingerprint, } from "./crypto.js";
16
+ export { type CoreDelivery, type CoreHeaders, decodeBody, type DeliveryResult, type InstallDelivery, readHeader, } from "./delivery.js";
16
17
  export { APP_SOURCE, type AppInboundMessage, type AppOutboundMessage, DASHBOARD_SOURCE, type FrameBridgeOptions, listenToDashboard, sendReady, } from "./frame.js";
17
18
  export { type HandoffEnvelope, type HandoffEnvelopeAny, type HandoffInstallationRef, type HandoffStore, INSTALL_EVENT, type InstallData, type InstallEnvelope, RESYNC_EVENT, type ResyncEnvelope, SETTINGS_EVENT, type SettingsData, type SettingsEnvelope, UNINSTALL_EVENT, type UninstallData, type UninstallEnvelope, } from "./handoff.js";
18
- export { buildInstallationRecord, createInstallHandlers, type InstallCallbacks, type InstallHandlerOptions, saveResyncedInstallation, } from "./install-handlers.js";
19
+ export { buildInstallationRecord, handleInstallDelivery, handleInstallRequest, type InstallCallbacks, type InstallHandlerOptions, saveResyncedInstallation, } from "./install-handlers.js";
19
20
  export { createLogger, type LogFields, type Logger, type LoggerOptions, type LogLevel, REDACTED, } from "./logger.js";
20
21
  export { type ResyncListItem, type ResyncOptions, type ResyncResult, resyncFromQueek, } from "./resync.js";
21
22
  export { MAX_TIMESTAMP_SKEW_SECONDS, SECRET_PREFIX, type SignatureFailure, type SignatureInput, secretKeyBytes, signQueekPayload, type VerifyOptions, verifyQueekSignature, verifyQueekSignatureDetailed, WEBHOOK_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, } from "./signatures.js";
22
23
  export { createInstallationStore, createPostgresPool, INSTALLATION_SCHEMA_VERSION, type InstallationRecord, type InstallationStore, type InstallationStoreSelector, PostgresInstallationStore, type PostgresStoreOptions, SqliteInstallationStore, type SqliteStoreOptions, type WebhookSecretCandidate, } from "./store.js";
23
24
  export { APP_API_PATH, AppTokenProvider, type AppTokens, createAppTokenProvider, createInstallationClient, type InstallationClientOptions, mintPath, resolveAppApiBase, type TokenProviderOptions, } from "./tokens.js";
24
- export { createWebhookHandler, QUEEK_TOPIC_HEADER, type QueekWebhookEnvelope, type SecretResolution, type WebhookHandlerContext, type WebhookHandlerFn, type WebhookHandlerOptions, } from "./webhooks.js";
25
+ export { handleWebhookDelivery, handleWebhookRequest, QUEEK_TOPIC_HEADER, type QueekWebhookEnvelope, type SecretResolution, type WebhookHandlerContext, type WebhookHandlerFn, type WebhookHandlerOptions, } from "./webhooks.js";
25
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,18 +8,19 @@
8
8
  * PER-INSTALLATION endpoint secret). The Merchant API takes the
9
9
  * installation credential as `X-Client-Key`.
10
10
  */
11
- export { API_KEY_EXPIRED_CODE, API_KEY_REVOKED_CODE, APP_INSTALLATION_GONE_CODE, APP_INSTALLATION_PENDING_CODE, APP_JWT_SKEW_SECONDS, APP_JWT_TTL_SECONDS, APP_TOKEN_REVOKED_CODE, AppMintHaltedError, INVALID_CLIENT_CODE, INVALID_CLIENT_KEY_CODE, InvalidAppCredentialError, isAppTokenRevoked, isInstallationGone, isInstallationPending, isInvalidClient, isResyncCooldown, isTokenRefusal, loadAppCredential, MAX_MINT_ATTEMPTS, MINT_BACKOFF_BASE_MS, MINT_BACKOFF_MAX_MS, RESYNC_COOLDOWN_CODE, RETRY_JITTER_MAX_MS, signAppJwt, TOKEN_VALIDITY_SKEW_SECONDS, TOO_MANY_REQUESTS_CODE, UnknownInstallationError, } from "./app-auth.js";
11
+ export { API_KEY_EXPIRED_CODE, APP_PRIVATE_KEY_FORMS, decodePrivateKeyInput, API_KEY_REVOKED_CODE, APP_INSTALLATION_GONE_CODE, APP_INSTALLATION_PENDING_CODE, APP_JWT_SKEW_SECONDS, APP_JWT_TTL_SECONDS, APP_TOKEN_REVOKED_CODE, AppMintHaltedError, INVALID_CLIENT_CODE, INVALID_CLIENT_KEY_CODE, InvalidAppCredentialError, isAppTokenRevoked, isInstallationGone, isInstallationPending, isInvalidClient, isResyncCooldown, isTokenRefusal, loadAppCredential, MAX_MINT_ATTEMPTS, MINT_BACKOFF_BASE_MS, MINT_BACKOFF_MAX_MS, RESYNC_COOLDOWN_CODE, RETRY_JITTER_MAX_MS, signAppJwt, TOKEN_VALIDITY_SKEW_SECONDS, TOO_MANY_REQUESTS_CODE, UnknownInstallationError, } from "./app-auth.js";
12
12
  export { backgroundTaskCount, detach, runInstallationCatchup, } from "./background.js";
13
13
  export { apiHostsFromEnv, createQueekClient, DEFAULT_API_HOSTS, devApiHostsFromEnv, InvalidApiBaseError, MERCHANT_API_PATH, newIdempotencyKey, QueekApiError, queekApiErrorFromResponse, resolveApiBase, } from "./client.js";
14
14
  export { collectedDefinitions, createRecord, sendAlert, setSetupNotice, } from "./collected.js";
15
15
  export { decryptSecret, encryptSecret, parseStoreKey, storeKeyFingerprint, } from "./crypto.js";
16
+ export { decodeBody, readHeader, } from "./delivery.js";
16
17
  export { APP_SOURCE, DASHBOARD_SOURCE, listenToDashboard, sendReady, } from "./frame.js";
17
18
  export { INSTALL_EVENT, RESYNC_EVENT, SETTINGS_EVENT, UNINSTALL_EVENT, } from "./handoff.js";
18
- export { buildInstallationRecord, createInstallHandlers, saveResyncedInstallation, } from "./install-handlers.js";
19
+ export { buildInstallationRecord, handleInstallDelivery, handleInstallRequest, saveResyncedInstallation, } from "./install-handlers.js";
19
20
  export { createLogger, REDACTED, } from "./logger.js";
20
21
  export { resyncFromQueek, } from "./resync.js";
21
22
  export { MAX_TIMESTAMP_SKEW_SECONDS, SECRET_PREFIX, secretKeyBytes, signQueekPayload, verifyQueekSignature, verifyQueekSignatureDetailed, WEBHOOK_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, } from "./signatures.js";
22
23
  export { createInstallationStore, createPostgresPool, INSTALLATION_SCHEMA_VERSION, PostgresInstallationStore, SqliteInstallationStore, } from "./store.js";
23
24
  export { APP_API_PATH, AppTokenProvider, createAppTokenProvider, createInstallationClient, mintPath, resolveAppApiBase, } from "./tokens.js";
24
- export { createWebhookHandler, QUEEK_TOPIC_HEADER, } from "./webhooks.js";
25
+ export { handleWebhookDelivery, handleWebhookRequest, QUEEK_TOPIC_HEADER, } from "./webhooks.js";
25
26
  //# sourceMappingURL=index.js.map