@lunora/bindings 1.0.0-alpha.9 → 1.0.0-alpha.90

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 (58) hide show
  1. package/dist/analytics/index.d.mts +21 -25
  2. package/dist/analytics/index.d.ts +21 -25
  3. package/dist/analytics/index.mjs +1 -2
  4. package/dist/images/index.d.mts +37 -52
  5. package/dist/images/index.d.ts +37 -52
  6. package/dist/images/index.mjs +1 -3
  7. package/dist/kv/index.d.mts +4 -81
  8. package/dist/kv/index.d.ts +4 -81
  9. package/dist/kv/index.mjs +1 -2
  10. package/dist/packem_shared/AnalyticsSqlError-CeQ3A5Eb.mjs +1 -0
  11. package/dist/packem_shared/R2SqlError-ZHgOWClB.mjs +1 -0
  12. package/dist/packem_shared/SelectBuilder-DJXNSdqC.mjs +1 -0
  13. package/dist/packem_shared/SetOperation-kiI5Wnlm.mjs +1 -0
  14. package/dist/packem_shared/Sql-BfnxRway.mjs +1 -0
  15. package/dist/packem_shared/WindowExpression-VX7EEV3h.mjs +1 -0
  16. package/dist/packem_shared/WindowFunction-CL4jYy2l.mjs +1 -0
  17. package/dist/packem_shared/asc-DP_WFiAE.mjs +1 -0
  18. package/dist/packem_shared/buildImageDeliveryUrl-Brqs-dcZ.mjs +1 -0
  19. package/dist/packem_shared/buildSignedImageUrl-BV-iSJKA.mjs +4 -0
  20. package/dist/packem_shared/cap-error-body-YBKO32BF.mjs +1 -0
  21. package/dist/packem_shared/concurrent-vRmSvRpF.mjs +1 -0
  22. package/dist/packem_shared/createAnalytics-BXTNc57d.mjs +1 -0
  23. package/dist/packem_shared/createContextVectors-DiyO3pZU.mjs +6 -0
  24. package/dist/packem_shared/createImages-D7JExfqF.mjs +1 -0
  25. package/dist/packem_shared/createKv-mAHanD5g.mjs +1 -0
  26. package/dist/packem_shared/createKvIntrospector-BpRiFRFQ.mjs +1 -0
  27. package/dist/packem_shared/createPipelines-CIvqrc7E.mjs +1 -0
  28. package/dist/packem_shared/createVectorAdminIntrospector-Ct8v6PxJ.mjs +1 -0
  29. package/dist/packem_shared/createVectors-Dzv0ilKE.mjs +1 -0
  30. package/dist/pipelines/index.d.mts +1 -1
  31. package/dist/pipelines/index.d.ts +1 -1
  32. package/dist/pipelines/index.mjs +1 -1
  33. package/dist/r2sql/index.d.mts +54 -10
  34. package/dist/r2sql/index.d.ts +54 -10
  35. package/dist/r2sql/index.mjs +1 -7
  36. package/dist/vectors/index.d.mts +236 -71
  37. package/dist/vectors/index.d.ts +236 -71
  38. package/dist/vectors/index.mjs +1 -3
  39. package/package.json +3 -2
  40. package/dist/packem_shared/AnalyticsSqlError-C2nz3jpH.mjs +0 -41
  41. package/dist/packem_shared/R2SqlError-drPKSCZ3.mjs +0 -65
  42. package/dist/packem_shared/SelectBuilder-BOqJQHEv.mjs +0 -168
  43. package/dist/packem_shared/SetOperation-DmPgUL8W.mjs +0 -81
  44. package/dist/packem_shared/Sql-B3zq2YGx.mjs +0 -74
  45. package/dist/packem_shared/WindowExpression-BT_uA6g1.mjs +0 -44
  46. package/dist/packem_shared/WindowFunction-DrnuZUF6.mjs +0 -82
  47. package/dist/packem_shared/asc-DZbQCxh1.mjs +0 -16
  48. package/dist/packem_shared/buildImageDeliveryUrl-qZ7XbqTL.mjs +0 -35
  49. package/dist/packem_shared/buildSignedImageUrl-DNUFfyGP.mjs +0 -130
  50. package/dist/packem_shared/concurrent-CkCEVwqP.mjs +0 -39
  51. package/dist/packem_shared/createAnalytics-CEEI69o9.mjs +0 -57
  52. package/dist/packem_shared/createContextVectors-DwZtnPeC.mjs +0 -140
  53. package/dist/packem_shared/createImages-BzRnsz3H.mjs +0 -85
  54. package/dist/packem_shared/createKv-C8Iyu5hD.mjs +0 -145
  55. package/dist/packem_shared/createKvIntrospector-Byk4GfsY.mjs +0 -77
  56. package/dist/packem_shared/createPipelines-CfyJ6VGu.mjs +0 -10
  57. package/dist/packem_shared/createVectorAdminIntrospector-DuSvcBa5.mjs +0 -53
  58. package/dist/packem_shared/createVectors-CTSrctiK.mjs +0 -95
@@ -1,3 +1,5 @@
1
+ import { AnalyticsEngineDataPoint, AnalyticsEngineDatasetLike } from '@lunora/platform';
2
+ export type { AnalyticsEngineDataPoint, AnalyticsEngineDatasetLike } from '@lunora/platform';
1
3
  import { LunoraError } from '@lunora/errors';
2
4
  /**
3
5
  * Structural types for the Analytics Engine write path.
@@ -8,29 +10,6 @@ import { LunoraError } from '@lunora/errors';
8
10
  * approach `@lunora/d1` takes with `D1DatabaseLike`
9
11
  * (`packages/d1/src/d1-client.ts`).
10
12
  */
11
- /**
12
- * One Analytics Engine data point, mirroring the positional shape
13
- * `writeDataPoint` accepts. AE stores up to 20 string `blobs`, up to 20 numeric
14
- * `doubles`, and exactly **one** `index` (the high-cardinality sampling key) per
15
- * data point — the SQL API later exposes them as `blob1..blob20`,
16
- * `double1..double20`, and `index1`.
17
- */
18
- interface AnalyticsEngineDataPoint {
19
- /** String columns, mapped positionally to `blob1..blob20`. */
20
- blobs?: (ArrayBuffer | null | string)[];
21
- /** Numeric columns, mapped positionally to `double1..double20`. */
22
- doubles?: number[];
23
- /** Sampling key, exposed as `index1`. AE accepts at most one. */
24
- indexes?: (ArrayBuffer | string)[];
25
- }
26
- /**
27
- * Minimal structural projection of workers-types' `AnalyticsEngineDataset`,
28
- * kept loose enough for a plain-object fake in unit tests. `writeDataPoint` is
29
- * fire-and-forget: it returns `void` and never throws on the hot path.
30
- */
31
- interface AnalyticsEngineDatasetLike {
32
- writeDataPoint: (event: AnalyticsEngineDataPoint) => void;
33
- }
34
13
  /**
35
14
  * Named-field event handed to {@link AnalyticsClient.track}. Each field is
36
15
  * mapped to a positional AE column and the mapping recorded in a returned
@@ -112,6 +91,16 @@ interface AnalyticsSqlConfig {
112
91
  * so the SQL path never touches the network.
113
92
  */
114
93
  fetch?: typeof globalThis.fetch;
94
+ /**
95
+ * Milliseconds before an in-flight query (the fetch AND its body read) is
96
+ * aborted and surfaced as an `AnalyticsSqlError` with status 504. Defaults
97
+ * to 60_000 — analytical scans legitimately run tens of seconds.
98
+ * `undefined` means the default, not unbounded.
99
+ *
100
+ * The deadline is carried by the request's `signal`, so a custom `fetch`
101
+ * (above) that ignores `signal` leaves the query unbounded.
102
+ */
103
+ timeoutMs?: number;
115
104
  }
116
105
  /**
117
106
  * One column descriptor in a SQL-API response's `meta` array: the column `name`
@@ -131,7 +120,14 @@ interface AnalyticsSqlResult {
131
120
  rowCount: number;
132
121
  rows: Record<string, unknown>[];
133
122
  }
134
- /** Thrown when the SQL API responds with a non-2xx status; a `LunoraError` subclass carrying the HTTP `status` + body for the caller to surface. */
123
+ /**
124
+ * Thrown when the SQL API responds with a non-2xx status; a `LunoraError`
125
+ * subclass carrying the HTTP `status` + a capped body preview, with the full
126
+ * body on `cause`.
127
+ *
128
+ * The preview is capped because AE's SQL error text quotes the query back, and
129
+ * `ANALYTICS_SQL_ERROR` is non-internal — the message reaches the browser.
130
+ */
135
131
  declare class AnalyticsSqlError extends LunoraError {
136
132
  constructor(status: number, body: string);
137
133
  }
@@ -145,4 +141,4 @@ interface AnalyticsSqlClient {
145
141
  * normalises AE's `{ meta, data, rows }` body into {@link AnalyticsSqlResult}.
146
142
  */
147
143
  declare const createAnalyticsSqlClient: (config: AnalyticsSqlConfig) => AnalyticsSqlClient;
148
- export { type AnalyticsClient, type AnalyticsEngineDataPoint, type AnalyticsEngineDatasetLike, type AnalyticsSqlClient, type AnalyticsSqlColumnMeta, type AnalyticsSqlConfig, AnalyticsSqlError, type AnalyticsSqlResult, type TrackColumn, type TrackEvent, type TrackSchema, createAnalytics, createAnalyticsSqlClient };
144
+ export { type AnalyticsClient, type AnalyticsSqlClient, type AnalyticsSqlColumnMeta, type AnalyticsSqlConfig, AnalyticsSqlError, type AnalyticsSqlResult, type TrackColumn, type TrackEvent, type TrackSchema, createAnalytics, createAnalyticsSqlClient };
@@ -1,3 +1,5 @@
1
+ import { AnalyticsEngineDataPoint, AnalyticsEngineDatasetLike } from '@lunora/platform';
2
+ export type { AnalyticsEngineDataPoint, AnalyticsEngineDatasetLike } from '@lunora/platform';
1
3
  import { LunoraError } from '@lunora/errors';
2
4
  /**
3
5
  * Structural types for the Analytics Engine write path.
@@ -8,29 +10,6 @@ import { LunoraError } from '@lunora/errors';
8
10
  * approach `@lunora/d1` takes with `D1DatabaseLike`
9
11
  * (`packages/d1/src/d1-client.ts`).
10
12
  */
11
- /**
12
- * One Analytics Engine data point, mirroring the positional shape
13
- * `writeDataPoint` accepts. AE stores up to 20 string `blobs`, up to 20 numeric
14
- * `doubles`, and exactly **one** `index` (the high-cardinality sampling key) per
15
- * data point — the SQL API later exposes them as `blob1..blob20`,
16
- * `double1..double20`, and `index1`.
17
- */
18
- interface AnalyticsEngineDataPoint {
19
- /** String columns, mapped positionally to `blob1..blob20`. */
20
- blobs?: (ArrayBuffer | null | string)[];
21
- /** Numeric columns, mapped positionally to `double1..double20`. */
22
- doubles?: number[];
23
- /** Sampling key, exposed as `index1`. AE accepts at most one. */
24
- indexes?: (ArrayBuffer | string)[];
25
- }
26
- /**
27
- * Minimal structural projection of workers-types' `AnalyticsEngineDataset`,
28
- * kept loose enough for a plain-object fake in unit tests. `writeDataPoint` is
29
- * fire-and-forget: it returns `void` and never throws on the hot path.
30
- */
31
- interface AnalyticsEngineDatasetLike {
32
- writeDataPoint: (event: AnalyticsEngineDataPoint) => void;
33
- }
34
13
  /**
35
14
  * Named-field event handed to {@link AnalyticsClient.track}. Each field is
36
15
  * mapped to a positional AE column and the mapping recorded in a returned
@@ -112,6 +91,16 @@ interface AnalyticsSqlConfig {
112
91
  * so the SQL path never touches the network.
113
92
  */
114
93
  fetch?: typeof globalThis.fetch;
94
+ /**
95
+ * Milliseconds before an in-flight query (the fetch AND its body read) is
96
+ * aborted and surfaced as an `AnalyticsSqlError` with status 504. Defaults
97
+ * to 60_000 — analytical scans legitimately run tens of seconds.
98
+ * `undefined` means the default, not unbounded.
99
+ *
100
+ * The deadline is carried by the request's `signal`, so a custom `fetch`
101
+ * (above) that ignores `signal` leaves the query unbounded.
102
+ */
103
+ timeoutMs?: number;
115
104
  }
116
105
  /**
117
106
  * One column descriptor in a SQL-API response's `meta` array: the column `name`
@@ -131,7 +120,14 @@ interface AnalyticsSqlResult {
131
120
  rowCount: number;
132
121
  rows: Record<string, unknown>[];
133
122
  }
134
- /** Thrown when the SQL API responds with a non-2xx status; a `LunoraError` subclass carrying the HTTP `status` + body for the caller to surface. */
123
+ /**
124
+ * Thrown when the SQL API responds with a non-2xx status; a `LunoraError`
125
+ * subclass carrying the HTTP `status` + a capped body preview, with the full
126
+ * body on `cause`.
127
+ *
128
+ * The preview is capped because AE's SQL error text quotes the query back, and
129
+ * `ANALYTICS_SQL_ERROR` is non-internal — the message reaches the browser.
130
+ */
135
131
  declare class AnalyticsSqlError extends LunoraError {
136
132
  constructor(status: number, body: string);
137
133
  }
@@ -145,4 +141,4 @@ interface AnalyticsSqlClient {
145
141
  * normalises AE's `{ meta, data, rows }` body into {@link AnalyticsSqlResult}.
146
142
  */
147
143
  declare const createAnalyticsSqlClient: (config: AnalyticsSqlConfig) => AnalyticsSqlClient;
148
- export { type AnalyticsClient, type AnalyticsEngineDataPoint, type AnalyticsEngineDatasetLike, type AnalyticsSqlClient, type AnalyticsSqlColumnMeta, type AnalyticsSqlConfig, AnalyticsSqlError, type AnalyticsSqlResult, type TrackColumn, type TrackEvent, type TrackSchema, createAnalytics, createAnalyticsSqlClient };
144
+ export { type AnalyticsClient, type AnalyticsSqlClient, type AnalyticsSqlColumnMeta, type AnalyticsSqlConfig, AnalyticsSqlError, type AnalyticsSqlResult, type TrackColumn, type TrackEvent, type TrackSchema, createAnalytics, createAnalyticsSqlClient };
@@ -1,2 +1 @@
1
- export { createAnalytics } from '../packem_shared/createAnalytics-CEEI69o9.mjs';
2
- export { AnalyticsSqlError, createAnalyticsSqlClient } from '../packem_shared/AnalyticsSqlError-C2nz3jpH.mjs';
1
+ import{createAnalytics as e}from"../packem_shared/createAnalytics-BXTNc57d.mjs";import{AnalyticsSqlError as a,createAnalyticsSqlClient as c}from"../packem_shared/AnalyticsSqlError-CeQ3A5Eb.mjs";export{a as AnalyticsSqlError,e as createAnalytics,c as createAnalyticsSqlClient};
@@ -8,12 +8,11 @@
8
8
  * (`input(stream).transform(opts).output(opts)` + `info(stream)`), not the full
9
9
  * hosted-images CRUD surface.
10
10
  *
11
- * TODO(workers-types): the 2026-06-16 optimization features — the `aspect-crop`
12
- * / `scale-up` fit modes and the `upscale` param — are modeled here by hand
13
- * because `@cloudflare/workers-types` (through 4.20260616.1) does not type them
14
- * yet. Re-check on the next `@cloudflare/workers-types` bump: once `ImageTransform`
15
- * carries `fit: "aspect-crop" | "scale-up"` and `upscale`, drop our hand-rolled
16
- * additions and lean on the upstream type.
11
+ * TODO(workers-types): the `aspect-crop` fit mode is modeled here by hand because
12
+ * `@cloudflare/workers-types` still does not type it — checked at the pinned
13
+ * 5.20260811.1, whose `ImageTransform` now carries `fit: "scale-up"` and `upscale`.
14
+ * Re-check on the next bump: once `ImageTransform` also carries
15
+ * `fit: "aspect-crop"`, drop our hand-rolled addition and lean on the upstream type.
17
16
  */
18
17
  /**
19
18
  * Porter-Duff compositing operation controlling how an overlay is blended onto
@@ -27,37 +26,6 @@
27
26
  * - `lighter` — foreground and backdrop channels added (brightening).
28
27
  */
29
28
  type ImageCompositeMode = "atop" | "in" | "lighter" | "out" | "over" | "xor";
30
- /**
31
- * One overlay in a {@link TransformOptions.draw} list — the **URL-form** overlay
32
- * (the `cf.image.draw` / `/cdn-cgi/image` shape), where the overlay image is
33
- * referenced by absolute `url`. For the **binding** path use {@link ImageOverlay}
34
- * instead, which carries the overlay bytes as a stream.
35
- *
36
- * `width`/`height` accept either an integer (pixels) or a decimal in `(0, 1]`
37
- * interpreted as a fraction of the base image's corresponding dimension.
38
- */
39
- interface DrawOverlay {
40
- /** Offset, in pixels, from the bottom edge. */
41
- bottom?: number;
42
- /** Blend mode for compositing this overlay onto the image. Default `over`. */
43
- composite?: ImageCompositeMode;
44
- /** Overlay height — pixels (integer) or a `0–1` fraction of the base height. */
45
- height?: number;
46
- /** Offset, in pixels, from the left edge. */
47
- left?: number;
48
- /** Overlay opacity, `0.0` (transparent) – `1.0` (opaque). */
49
- opacity?: number;
50
- /** Tile the overlay across the base image: `true`, or a single axis `"x"`/`"y"`. */
51
- repeat?: "x" | "y" | boolean;
52
- /** Offset, in pixels, from the right edge. */
53
- right?: number;
54
- /** Offset, in pixels, from the top edge. */
55
- top?: number;
56
- /** Absolute URL of the overlay image. */
57
- url: string;
58
- /** Overlay width — pixels (integer) or a `0–1` fraction of the base width. */
59
- width?: number;
60
- }
61
29
  /**
62
30
  * Transform parameters threaded into `binding.input(stream).transform(...)`.
63
31
  * A structural subset of the real `ImageTransform`; the keys here are the
@@ -73,13 +41,6 @@ interface TransformOptions {
73
41
  brightness?: number;
74
42
  /** Contrast multiplier (1 = unchanged). */
75
43
  contrast?: number;
76
- /**
77
- * URL-form overlays composited over the result, in paint order (last entry on
78
- * top). Consumed by the URL builders ({@link DrawOverlay} references each
79
- * overlay by `url`); the binding path applies overlays via the `overlays`
80
- * argument to `Images.transform` instead, so this key is ignored there.
81
- */
82
- draw?: DrawOverlay[];
83
44
  /**
84
45
  * Resize mode. Affects how `width`/`height` are interpreted.
85
46
  *
@@ -157,9 +118,9 @@ type ImageInfoLike = {
157
118
  };
158
119
  /**
159
120
  * Binding-side overlay options for `transformer.draw(image, options)` — the
160
- * blend/position/opacity knobs. Unlike {@link DrawOverlay} there is no `url`
161
- * (the overlay bytes are passed as the stream) and no `width`/`height` (the
162
- * overlay is pre-sized via its own transform); mirrors `ImageDrawOptions`.
121
+ * blend/position/opacity knobs. There is no `url` (the overlay bytes are passed
122
+ * as the stream) and no `width`/`height` (the overlay is pre-sized via its own
123
+ * transform); mirrors `ImageDrawOptions`.
163
124
  */
164
125
  interface ImageDrawOptions {
165
126
  /** Offset, in pixels, from the bottom edge. */
@@ -266,7 +227,7 @@ interface ImageDeliveryUrlOptions {
266
227
  baseUrl: string;
267
228
  /**
268
229
  * Hosted-Images image id. When set, the **delivery-variant** form is built
269
- * (`&lt;baseUrl>/&lt;imageId>/&lt;variant>`) and `transform`/`key` are ignored.
230
+ * (`<baseUrl>/<imageId>/<variant>`) and `transform`/`key` are ignored.
270
231
  */
271
232
  imageId?: string;
272
233
  /**
@@ -274,7 +235,7 @@ interface ImageDeliveryUrlOptions {
274
235
  * `/cdn-cgi/image/...` transform form. Ignored when `imageId` is set.
275
236
  */
276
237
  key?: string;
277
- /** Transform options for the `/cdn-cgi/image/&lt;options>/&lt;source>` form. */
238
+ /** Transform options for the `/cdn-cgi/image/<options>/<source>` form. */
278
239
  transform?: TransformOptions;
279
240
  /** Named delivery variant (e.g. `public`, `thumbnail`). Used with `imageId`; default `public`. */
280
241
  variant?: string;
@@ -282,12 +243,27 @@ interface ImageDeliveryUrlOptions {
282
243
  /**
283
244
  * Build a Cloudflare Images delivery / transform URL.
284
245
  *
285
- * - With `imageId`: `&lt;baseUrl>/&lt;imageId>/&lt;variant>` (hosted delivery variant).
286
- * - With `key`: `&lt;baseUrl>/cdn-cgi/image/&lt;options>/&lt;source>` (URL-based transform).
246
+ * - With `imageId`: `<baseUrl>/<imageId>/<variant>` (hosted delivery variant).
247
+ * - With `key`: `<baseUrl>/cdn-cgi/image/<options>/<source>` (URL-based transform).
287
248
  *
288
249
  * Pure and deterministic — usable from any handler.
289
250
  */
290
251
  declare const buildImageDeliveryUrl: (options: ImageDeliveryUrlOptions) => string;
252
+ /**
253
+ * Parse a verified transform string (the `t` query value handed back by
254
+ * {@link verifySignedImageUrl}) back into the {@link TransformOptions} it was
255
+ * serialized from, so the Worker can apply exactly the signed transform via
256
+ * `ctx.images.transform(...)` without hand-writing the inverse encoding.
257
+ *
258
+ * The exact inverse of `serializeTransform` above — the two MUST evolve
259
+ * together (the round-trip test in
260
+ * `__tests__/images/signed-delivery-url.test.ts` pins the pairing). Throws a
261
+ * `TypeError` on an unknown key or an uncoercible value: the input is meant to
262
+ * be a string whose HMAC already verified, so a parse failure means
263
+ * encoder/decoder drift in the library, never user input — fail loud rather
264
+ * than silently un-binding the transform the signature protects.
265
+ */
266
+ declare const parseSignedTransform: (t: string) => TransformOptions;
291
267
  interface SignedImageUrlOptions {
292
268
  /** Delivery / Worker origin the signed URL points at (e.g. `https://cdn.acme.test`). */
293
269
  baseUrl: string;
@@ -324,6 +300,15 @@ interface VerifyImageResult {
324
300
  reason?: "bad_signature" | "expired" | "malformed";
325
301
  /** The raw, verified transform string (the `t` query value), when present. */
326
302
  transform?: string;
303
+ /**
304
+ * The verified transform decoded back into the options object to pass to
305
+ * `ctx.images.transform(...)` — {@link parseSignedTransform} applied to
306
+ * `transform`. Left `undefined` when `transform` is absent, and also when a
307
+ * genuinely signed transform carries a key this build does not know (an
308
+ * old URL minted before a key was renamed): the request stays `valid`, the
309
+ * raw `transform` is still returned, and the caller decides.
310
+ */
311
+ transformOptions?: TransformOptions;
327
312
  valid: boolean;
328
313
  }
329
314
  /**
@@ -335,4 +320,4 @@ interface VerifyImageResult {
335
320
  declare const verifySignedImageUrl: (input: string | URL, secret: string, options?: {
336
321
  expectedHost?: string;
337
322
  }) => Promise<VerifyImageResult>;
338
- export { type DrawOverlay, type ImageCompositeMode, type ImageDeliveryUrlOptions, type ImageDrawOptions, type ImageInfoLike, type ImageInput, type ImageOutputFormat, type ImageOverlay, type ImageTransformationResultLike, type ImageTransformerLike, type Images, type ImagesBindingLike, type LunoraImagesOptions, type OutputOptions, type R2ObjectBodyLike, type SignedImageUrlOptions, type TransformOptions, type VerifyImageResult, buildImageDeliveryUrl, buildSignedImageUrl, createImages, verifySignedImageUrl };
323
+ export { type ImageCompositeMode, type ImageDeliveryUrlOptions, type ImageDrawOptions, type ImageInfoLike, type ImageInput, type ImageOutputFormat, type ImageOverlay, type ImageTransformationResultLike, type ImageTransformerLike, type Images, type ImagesBindingLike, type LunoraImagesOptions, type OutputOptions, type R2ObjectBodyLike, type SignedImageUrlOptions, type TransformOptions, type VerifyImageResult, buildImageDeliveryUrl, buildSignedImageUrl, createImages, parseSignedTransform, verifySignedImageUrl };
@@ -8,12 +8,11 @@
8
8
  * (`input(stream).transform(opts).output(opts)` + `info(stream)`), not the full
9
9
  * hosted-images CRUD surface.
10
10
  *
11
- * TODO(workers-types): the 2026-06-16 optimization features — the `aspect-crop`
12
- * / `scale-up` fit modes and the `upscale` param — are modeled here by hand
13
- * because `@cloudflare/workers-types` (through 4.20260616.1) does not type them
14
- * yet. Re-check on the next `@cloudflare/workers-types` bump: once `ImageTransform`
15
- * carries `fit: "aspect-crop" | "scale-up"` and `upscale`, drop our hand-rolled
16
- * additions and lean on the upstream type.
11
+ * TODO(workers-types): the `aspect-crop` fit mode is modeled here by hand because
12
+ * `@cloudflare/workers-types` still does not type it — checked at the pinned
13
+ * 5.20260811.1, whose `ImageTransform` now carries `fit: "scale-up"` and `upscale`.
14
+ * Re-check on the next bump: once `ImageTransform` also carries
15
+ * `fit: "aspect-crop"`, drop our hand-rolled addition and lean on the upstream type.
17
16
  */
18
17
  /**
19
18
  * Porter-Duff compositing operation controlling how an overlay is blended onto
@@ -27,37 +26,6 @@
27
26
  * - `lighter` — foreground and backdrop channels added (brightening).
28
27
  */
29
28
  type ImageCompositeMode = "atop" | "in" | "lighter" | "out" | "over" | "xor";
30
- /**
31
- * One overlay in a {@link TransformOptions.draw} list — the **URL-form** overlay
32
- * (the `cf.image.draw` / `/cdn-cgi/image` shape), where the overlay image is
33
- * referenced by absolute `url`. For the **binding** path use {@link ImageOverlay}
34
- * instead, which carries the overlay bytes as a stream.
35
- *
36
- * `width`/`height` accept either an integer (pixels) or a decimal in `(0, 1]`
37
- * interpreted as a fraction of the base image's corresponding dimension.
38
- */
39
- interface DrawOverlay {
40
- /** Offset, in pixels, from the bottom edge. */
41
- bottom?: number;
42
- /** Blend mode for compositing this overlay onto the image. Default `over`. */
43
- composite?: ImageCompositeMode;
44
- /** Overlay height — pixels (integer) or a `0–1` fraction of the base height. */
45
- height?: number;
46
- /** Offset, in pixels, from the left edge. */
47
- left?: number;
48
- /** Overlay opacity, `0.0` (transparent) – `1.0` (opaque). */
49
- opacity?: number;
50
- /** Tile the overlay across the base image: `true`, or a single axis `"x"`/`"y"`. */
51
- repeat?: "x" | "y" | boolean;
52
- /** Offset, in pixels, from the right edge. */
53
- right?: number;
54
- /** Offset, in pixels, from the top edge. */
55
- top?: number;
56
- /** Absolute URL of the overlay image. */
57
- url: string;
58
- /** Overlay width — pixels (integer) or a `0–1` fraction of the base width. */
59
- width?: number;
60
- }
61
29
  /**
62
30
  * Transform parameters threaded into `binding.input(stream).transform(...)`.
63
31
  * A structural subset of the real `ImageTransform`; the keys here are the
@@ -73,13 +41,6 @@ interface TransformOptions {
73
41
  brightness?: number;
74
42
  /** Contrast multiplier (1 = unchanged). */
75
43
  contrast?: number;
76
- /**
77
- * URL-form overlays composited over the result, in paint order (last entry on
78
- * top). Consumed by the URL builders ({@link DrawOverlay} references each
79
- * overlay by `url`); the binding path applies overlays via the `overlays`
80
- * argument to `Images.transform` instead, so this key is ignored there.
81
- */
82
- draw?: DrawOverlay[];
83
44
  /**
84
45
  * Resize mode. Affects how `width`/`height` are interpreted.
85
46
  *
@@ -157,9 +118,9 @@ type ImageInfoLike = {
157
118
  };
158
119
  /**
159
120
  * Binding-side overlay options for `transformer.draw(image, options)` — the
160
- * blend/position/opacity knobs. Unlike {@link DrawOverlay} there is no `url`
161
- * (the overlay bytes are passed as the stream) and no `width`/`height` (the
162
- * overlay is pre-sized via its own transform); mirrors `ImageDrawOptions`.
121
+ * blend/position/opacity knobs. There is no `url` (the overlay bytes are passed
122
+ * as the stream) and no `width`/`height` (the overlay is pre-sized via its own
123
+ * transform); mirrors `ImageDrawOptions`.
163
124
  */
164
125
  interface ImageDrawOptions {
165
126
  /** Offset, in pixels, from the bottom edge. */
@@ -266,7 +227,7 @@ interface ImageDeliveryUrlOptions {
266
227
  baseUrl: string;
267
228
  /**
268
229
  * Hosted-Images image id. When set, the **delivery-variant** form is built
269
- * (`&lt;baseUrl>/&lt;imageId>/&lt;variant>`) and `transform`/`key` are ignored.
230
+ * (`<baseUrl>/<imageId>/<variant>`) and `transform`/`key` are ignored.
270
231
  */
271
232
  imageId?: string;
272
233
  /**
@@ -274,7 +235,7 @@ interface ImageDeliveryUrlOptions {
274
235
  * `/cdn-cgi/image/...` transform form. Ignored when `imageId` is set.
275
236
  */
276
237
  key?: string;
277
- /** Transform options for the `/cdn-cgi/image/&lt;options>/&lt;source>` form. */
238
+ /** Transform options for the `/cdn-cgi/image/<options>/<source>` form. */
278
239
  transform?: TransformOptions;
279
240
  /** Named delivery variant (e.g. `public`, `thumbnail`). Used with `imageId`; default `public`. */
280
241
  variant?: string;
@@ -282,12 +243,27 @@ interface ImageDeliveryUrlOptions {
282
243
  /**
283
244
  * Build a Cloudflare Images delivery / transform URL.
284
245
  *
285
- * - With `imageId`: `&lt;baseUrl>/&lt;imageId>/&lt;variant>` (hosted delivery variant).
286
- * - With `key`: `&lt;baseUrl>/cdn-cgi/image/&lt;options>/&lt;source>` (URL-based transform).
246
+ * - With `imageId`: `<baseUrl>/<imageId>/<variant>` (hosted delivery variant).
247
+ * - With `key`: `<baseUrl>/cdn-cgi/image/<options>/<source>` (URL-based transform).
287
248
  *
288
249
  * Pure and deterministic — usable from any handler.
289
250
  */
290
251
  declare const buildImageDeliveryUrl: (options: ImageDeliveryUrlOptions) => string;
252
+ /**
253
+ * Parse a verified transform string (the `t` query value handed back by
254
+ * {@link verifySignedImageUrl}) back into the {@link TransformOptions} it was
255
+ * serialized from, so the Worker can apply exactly the signed transform via
256
+ * `ctx.images.transform(...)` without hand-writing the inverse encoding.
257
+ *
258
+ * The exact inverse of `serializeTransform` above — the two MUST evolve
259
+ * together (the round-trip test in
260
+ * `__tests__/images/signed-delivery-url.test.ts` pins the pairing). Throws a
261
+ * `TypeError` on an unknown key or an uncoercible value: the input is meant to
262
+ * be a string whose HMAC already verified, so a parse failure means
263
+ * encoder/decoder drift in the library, never user input — fail loud rather
264
+ * than silently un-binding the transform the signature protects.
265
+ */
266
+ declare const parseSignedTransform: (t: string) => TransformOptions;
291
267
  interface SignedImageUrlOptions {
292
268
  /** Delivery / Worker origin the signed URL points at (e.g. `https://cdn.acme.test`). */
293
269
  baseUrl: string;
@@ -324,6 +300,15 @@ interface VerifyImageResult {
324
300
  reason?: "bad_signature" | "expired" | "malformed";
325
301
  /** The raw, verified transform string (the `t` query value), when present. */
326
302
  transform?: string;
303
+ /**
304
+ * The verified transform decoded back into the options object to pass to
305
+ * `ctx.images.transform(...)` — {@link parseSignedTransform} applied to
306
+ * `transform`. Left `undefined` when `transform` is absent, and also when a
307
+ * genuinely signed transform carries a key this build does not know (an
308
+ * old URL minted before a key was renamed): the request stays `valid`, the
309
+ * raw `transform` is still returned, and the caller decides.
310
+ */
311
+ transformOptions?: TransformOptions;
327
312
  valid: boolean;
328
313
  }
329
314
  /**
@@ -335,4 +320,4 @@ interface VerifyImageResult {
335
320
  declare const verifySignedImageUrl: (input: string | URL, secret: string, options?: {
336
321
  expectedHost?: string;
337
322
  }) => Promise<VerifyImageResult>;
338
- export { type DrawOverlay, type ImageCompositeMode, type ImageDeliveryUrlOptions, type ImageDrawOptions, type ImageInfoLike, type ImageInput, type ImageOutputFormat, type ImageOverlay, type ImageTransformationResultLike, type ImageTransformerLike, type Images, type ImagesBindingLike, type LunoraImagesOptions, type OutputOptions, type R2ObjectBodyLike, type SignedImageUrlOptions, type TransformOptions, type VerifyImageResult, buildImageDeliveryUrl, buildSignedImageUrl, createImages, verifySignedImageUrl };
323
+ export { type ImageCompositeMode, type ImageDeliveryUrlOptions, type ImageDrawOptions, type ImageInfoLike, type ImageInput, type ImageOutputFormat, type ImageOverlay, type ImageTransformationResultLike, type ImageTransformerLike, type Images, type ImagesBindingLike, type LunoraImagesOptions, type OutputOptions, type R2ObjectBodyLike, type SignedImageUrlOptions, type TransformOptions, type VerifyImageResult, buildImageDeliveryUrl, buildSignedImageUrl, createImages, parseSignedTransform, verifySignedImageUrl };
@@ -1,3 +1 @@
1
- export { createImages } from '../packem_shared/createImages-BzRnsz3H.mjs';
2
- export { buildImageDeliveryUrl } from '../packem_shared/buildImageDeliveryUrl-qZ7XbqTL.mjs';
3
- export { buildSignedImageUrl, verifySignedImageUrl } from '../packem_shared/buildSignedImageUrl-DNUFfyGP.mjs';
1
+ import{createImages as m}from"../packem_shared/createImages-D7JExfqF.mjs";import{buildImageDeliveryUrl as g}from"../packem_shared/buildImageDeliveryUrl-Brqs-dcZ.mjs";import{buildSignedImageUrl as o,parseSignedTransform as l,verifySignedImageUrl as d}from"../packem_shared/buildSignedImageUrl-BV-iSJKA.mjs";export{g as buildImageDeliveryUrl,o as buildSignedImageUrl,m as createImages,l as parseSignedTransform,d as verifySignedImageUrl};
@@ -1,82 +1,5 @@
1
- /**
2
- * The value types Workers KV can store / return. Mirrors Cloudflare's
3
- * `KVNamespace` `get`/`put` body unions; declared here so the package stays
4
- * runtime-agnostic and the `*Like` interfaces don't pull in
5
- * `@cloudflare/workers-types` at runtime.
6
- */
7
- type KvValue = ReadableStream | ArrayBuffer | ArrayBufferView | string;
8
- /** How a raw KV read should decode the stored value. Mirrors KV's `type` option. */
9
- type KvValueType = "text" | "json" | "arrayBuffer" | "stream";
10
- /**
11
- * Per-read options forwarded to the binding. `cacheTtl` is KV's edge-cache TTL
12
- * (seconds, min 60); `type` selects the decode mode for {@link Kv.getRaw}.
13
- */
14
- interface KvGetOptions {
15
- /** KV edge-cache TTL in seconds (minimum 60). Forwarded verbatim. */
16
- cacheTtl?: number;
17
- /** Decode mode for a raw read. {@link Kv.get} always uses `"json"`. */
18
- type?: KvValueType;
19
- }
20
- /**
21
- * Minimal projection of Cloudflare's `KVNamespace`. Declared structurally so
22
- * unit tests can pass a plain `Map`-backed double; the real binding satisfies
23
- * the same shape. Mirrors `R2BucketLike` in `@lunora/storage`.
24
- */
25
- interface KVNamespaceLike {
26
- /** Delete a key. No-op if the key is absent. */
27
- delete: (key: string) => Promise<void>;
28
- /**
29
- * Read a value. The real binding overloads on `options.type`; declared here
30
- * as the broad union so a structural double need only return the value (or
31
- * `null` when absent).
32
- */
33
- get: (key: string, options?: KvGetOptions | KvValueType) => Promise<unknown>;
34
- /**
35
- * Read a value together with its associated metadata. Returns
36
- * `{ value: null, metadata: null }` when the key is absent.
37
- */
38
- getWithMetadata: (key: string, options?: KvGetOptions | KvValueType) => Promise<{
39
- metadata: unknown;
40
- value: unknown;
41
- }>;
42
- /** List keys, optionally filtered by `prefix` and paginated via `cursor`. */
43
- list: (options?: {
44
- cursor?: string;
45
- limit?: number;
46
- prefix?: string;
47
- }) => Promise<KvNamespaceListResult>;
48
- /** Write a value, optionally with TTL/expiration and metadata. */
49
- put: (key: string, value: KvValue, options?: KvNamespacePutOptions) => Promise<void>;
50
- }
51
- /** The raw put options the KV binding accepts (mirrors `KVNamespacePutOptions`). */
52
- interface KvNamespacePutOptions {
53
- /** Absolute expiration as a Unix timestamp (seconds). Mutually exclusive with `expirationTtl`. */
54
- expiration?: number;
55
- /** Relative expiration in seconds from now (minimum 60). Mutually exclusive with `expiration`. */
56
- expirationTtl?: number;
57
- /** Arbitrary JSON metadata stored alongside the value, returned by `getWithMetadata`/`list`. */
58
- metadata?: unknown;
59
- }
60
- /** One key entry as returned by the KV binding's `list`. */
61
- interface KvListKey<Metadata = unknown> {
62
- /** Absolute expiration (Unix seconds), when the key has one. */
63
- expiration?: number;
64
- /** The key's metadata, when set at write time. */
65
- metadata?: Metadata;
66
- /** The key name. */
67
- name: string;
68
- }
69
- /** The raw `list` result shape returned by the KV binding. */
70
- type KvNamespaceListResult<Metadata = unknown> = {
71
- cacheStatus?: string | null;
72
- cursor: string;
73
- keys: KvListKey<Metadata>[];
74
- list_complete: false;
75
- } | {
76
- cacheStatus?: string | null;
77
- keys: KvListKey<Metadata>[];
78
- list_complete: true;
79
- };
1
+ import { KvGetOptions, KvListKey, KVNamespaceLike } from '@lunora/platform';
2
+ export type { KVNamespaceLike, KvGetOptions, KvListKey, KvNamespaceListResult, KvNamespacePutOptions, KvValue, KvValueType } from '@lunora/platform';
80
3
  /** Construction options for the `createKv` factory. */
81
4
  interface LunoraKvOptions {
82
5
  /**
@@ -86,7 +9,7 @@ interface LunoraKvOptions {
86
9
  * `..` or NUL in the prefix is rejected.
87
10
  */
88
11
  keyPrefix?: string;
89
- /** The bound KV namespace (`env.&lt;BINDING>`). */
12
+ /** The bound KV namespace (`env.<BINDING>`). */
90
13
  namespace: KVNamespaceLike;
91
14
  }
92
15
  /** Options for {@link Kv.put}. JSON-stringifies the value unless `raw` is set. */
@@ -268,4 +191,4 @@ declare const createKvIntrospector: (options: CreateKvIntrospectorOptions) => Kv
268
191
  * ```
269
192
  */
270
193
  declare const createKvIntrospectorFromEnv: (env: unknown) => KvIntrospectorLike;
271
- export { type CreateKvIntrospectorOptions, type KVNamespaceLike, type Kv, type KvGetOptions, type KvIntrospectorLike, type KvListKey, type KvListOptions, type KvListResult, type KvNamespaceListResult, type KvNamespacePutOptions, type KvPutOptions, type KvValue, type KvValueType, type KvValueWithMetadata, type LunoraKvOptions, createKv, createKvIntrospector, createKvIntrospectorFromEnv, scopeKey };
194
+ export { type CreateKvIntrospectorOptions, type Kv, type KvIntrospectorLike, type KvListOptions, type KvListResult, type KvPutOptions, type KvValueWithMetadata, type LunoraKvOptions, createKv, createKvIntrospector, createKvIntrospectorFromEnv, scopeKey };