@lunora/bindings 0.0.0 → 1.0.0-alpha.2
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/LICENSE.md +105 -0
- package/README.md +39 -1
- package/__assets__/package-og.svg +14 -0
- package/dist/analytics/index.d.mts +148 -0
- package/dist/analytics/index.d.ts +148 -0
- package/dist/analytics/index.mjs +2 -0
- package/dist/images/index.d.mts +338 -0
- package/dist/images/index.d.ts +338 -0
- package/dist/images/index.mjs +3 -0
- package/dist/kv/index.d.mts +177 -0
- package/dist/kv/index.d.ts +177 -0
- package/dist/kv/index.mjs +1 -0
- package/dist/packem_shared/AnalyticsSqlError-CGTdsi4H.mjs +42 -0
- package/dist/packem_shared/R2SqlError-DlDd_SrE.mjs +67 -0
- package/dist/packem_shared/SelectBuilder-DHaXZwn_.mjs +167 -0
- package/dist/packem_shared/SetOperation-RDHcxccj.mjs +80 -0
- package/dist/packem_shared/Sql-DceGtcUd.mjs +68 -0
- package/dist/packem_shared/WindowExpression-Cg9s2xcr.mjs +44 -0
- package/dist/packem_shared/WindowFunction-DA3pGC3N.mjs +82 -0
- package/dist/packem_shared/asc-Cur-xO8v.mjs +16 -0
- package/dist/packem_shared/buildImageDeliveryUrl-D1sVfIOP.mjs +30 -0
- package/dist/packem_shared/buildSignedImageUrl-Otdgc_jO.mjs +113 -0
- package/dist/packem_shared/concurrent-Dj5sOibv.mjs +23 -0
- package/dist/packem_shared/createAnalytics-CEEI69o9.mjs +57 -0
- package/dist/packem_shared/createContextVectors-BSizpmu5.mjs +140 -0
- package/dist/packem_shared/createImages-CJrvqX0u.mjs +80 -0
- package/dist/packem_shared/createKv-DTiSt216.mjs +141 -0
- package/dist/packem_shared/createPipelines-CfyJ6VGu.mjs +10 -0
- package/dist/packem_shared/createVectorAdminIntrospector-BJUOM6VW.mjs +51 -0
- package/dist/packem_shared/createVectors-LSpGoKCd.mjs +91 -0
- package/dist/pipelines/index.d.mts +41 -0
- package/dist/pipelines/index.d.ts +41 -0
- package/dist/pipelines/index.mjs +1 -0
- package/dist/r2sql/index.d.mts +383 -0
- package/dist/r2sql/index.d.ts +383 -0
- package/dist/r2sql/index.mjs +7 -0
- package/dist/vectors/index.d.mts +285 -0
- package/dist/vectors/index.d.ts +285 -0
- package/dist/vectors/index.mjs +3 -0
- package/package.json +54 -4
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural projections of the Cloudflare **Images** binding (`env.IMAGES`).
|
|
3
|
+
*
|
|
4
|
+
* Declared structurally — the same pattern `@lunora/storage` uses for
|
|
5
|
+
* `R2BucketLike` — so a unit test can pass a plain object double and the real
|
|
6
|
+
* `ImagesBinding` from `@cloudflare/workers-types` satisfies the same shape. We
|
|
7
|
+
* project only the slice of the chain we actually call
|
|
8
|
+
* (`input(stream).transform(opts).output(opts)` + `info(stream)`), not the full
|
|
9
|
+
* hosted-images CRUD surface.
|
|
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.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Porter-Duff compositing operation controlling how an overlay is blended onto
|
|
20
|
+
* the image beneath it. Mirrors the binding's `ImageCompositeMode`.
|
|
21
|
+
*
|
|
22
|
+
* - `over` — foreground drawn on top of the backdrop (default).
|
|
23
|
+
* - `in` — foreground shown only where the backdrop is opaque.
|
|
24
|
+
* - `atop` — foreground drawn on top, clipped to the backdrop's shape.
|
|
25
|
+
* - `out` — foreground shown only where the backdrop is transparent.
|
|
26
|
+
* - `xor` — foreground and backdrop visible only where the other is not.
|
|
27
|
+
* - `lighter` — foreground and backdrop channels added (brightening).
|
|
28
|
+
*/
|
|
29
|
+
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
|
+
/**
|
|
62
|
+
* Transform parameters threaded into `binding.input(stream).transform(...)`.
|
|
63
|
+
* A structural subset of the real `ImageTransform`; the keys here are the
|
|
64
|
+
* resize/format/optimize knobs apps reach for. Unknown extra keys on the real
|
|
65
|
+
* binding are still accepted because the binding owns the authoritative type.
|
|
66
|
+
*/
|
|
67
|
+
interface TransformOptions {
|
|
68
|
+
/** Background color (CSS color) painted under transparent images. */
|
|
69
|
+
background?: string;
|
|
70
|
+
/** Gaussian blur radius (1–250). */
|
|
71
|
+
blur?: number;
|
|
72
|
+
/** Brightness multiplier (1 = unchanged). */
|
|
73
|
+
brightness?: number;
|
|
74
|
+
/** Contrast multiplier (1 = unchanged). */
|
|
75
|
+
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
|
+
/**
|
|
84
|
+
* Resize mode. Affects how `width`/`height` are interpreted.
|
|
85
|
+
*
|
|
86
|
+
* - `scale-down` — contain, but never enlarges.
|
|
87
|
+
* - `contain` — fit within the box, preserving aspect ratio.
|
|
88
|
+
* - `cover` — fill the box, cropping overflow.
|
|
89
|
+
* - `crop` — shrink-and-crop to fit, but never enlarges.
|
|
90
|
+
* - `aspect-crop` — crop to the target aspect ratio, but never enlarges.
|
|
91
|
+
* - `pad` — fit within the box, padding the remainder with `background`.
|
|
92
|
+
* - `squeeze` — stretch to the exact box, distorting aspect ratio.
|
|
93
|
+
* - `scale-up` — enlarge to show the whole image, but never downscales.
|
|
94
|
+
*/
|
|
95
|
+
fit?: "aspect-crop" | "contain" | "cover" | "crop" | "pad" | "scale-down" | "scale-up" | "squeeze";
|
|
96
|
+
/** Mirror the image horizontally, vertically, or both. */
|
|
97
|
+
flip?: "h" | "hv" | "v";
|
|
98
|
+
/** Gamma multiplier (1 = unchanged). */
|
|
99
|
+
gamma?: number;
|
|
100
|
+
/** Crop anchor when `fit: "cover"`/`"crop"`. */
|
|
101
|
+
gravity?: "auto" | "bottom" | "center" | "entropy" | "face" | "left" | "right" | "top" | {
|
|
102
|
+
mode: "box-center" | "remainder";
|
|
103
|
+
x?: number;
|
|
104
|
+
y?: number;
|
|
105
|
+
};
|
|
106
|
+
/** Target height in pixels (integer). Clamped to the configured ceiling. */
|
|
107
|
+
height?: number;
|
|
108
|
+
/** Rotate by a fixed multiple of 90 degrees. `width`/`height` refer to axes after rotation. */
|
|
109
|
+
rotate?: 0 | 90 | 180 | 270;
|
|
110
|
+
/** Saturation multiplier (0 = greyscale, 1 = unchanged). */
|
|
111
|
+
saturation?: number;
|
|
112
|
+
/** AI segmentation — set non-`foreground` pixels transparent. */
|
|
113
|
+
segment?: "foreground";
|
|
114
|
+
/** Sharpen strength (0–10). */
|
|
115
|
+
sharpen?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Algorithm used when a transform enlarges the image (e.g. `fit: "scale-up"`).
|
|
118
|
+
*
|
|
119
|
+
* - `interpolate` — bicubic interpolation (default), may soften detail.
|
|
120
|
+
* - `generate` — AI upscaling for sharper, more detailed enlargements.
|
|
121
|
+
*/
|
|
122
|
+
upscale?: "generate" | "interpolate";
|
|
123
|
+
/** Target width in pixels (integer). Clamped to the configured ceiling. */
|
|
124
|
+
width?: number;
|
|
125
|
+
}
|
|
126
|
+
/** The output image formats Lunora permits (the binding allowlist plus `json` info). */
|
|
127
|
+
type ImageOutputFormat = "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp";
|
|
128
|
+
/** Options for the terminal `output(...)` call. */
|
|
129
|
+
interface OutputOptions {
|
|
130
|
+
/** Encode animated source frames into the output (WebP/GIF/AVIF). */
|
|
131
|
+
anim?: boolean;
|
|
132
|
+
/** Background color (CSS color) for formats without an alpha channel. */
|
|
133
|
+
background?: string;
|
|
134
|
+
/** Output MIME type. Validated against {@link ImageOutputFormat}. Default `image/webp`. */
|
|
135
|
+
format?: ImageOutputFormat;
|
|
136
|
+
/** Encoder quality 1–100 (lossy formats). */
|
|
137
|
+
quality?: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The result of `binding.input(...).transform(...).output(...)`. Mirrors the
|
|
141
|
+
* real `ImageTransformationResult` — a `Response`, the content type, and the
|
|
142
|
+
* raw byte stream.
|
|
143
|
+
*/
|
|
144
|
+
interface ImageTransformationResultLike {
|
|
145
|
+
contentType: () => string;
|
|
146
|
+
image: () => ReadableStream<Uint8Array>;
|
|
147
|
+
response: () => Response;
|
|
148
|
+
}
|
|
149
|
+
/** Metadata returned by `binding.info(...)` — format, and (for raster images) dimensions + size. */
|
|
150
|
+
type ImageInfoLike = {
|
|
151
|
+
fileSize: number;
|
|
152
|
+
format: string;
|
|
153
|
+
height: number;
|
|
154
|
+
width: number;
|
|
155
|
+
} | {
|
|
156
|
+
format: string;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* 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`.
|
|
163
|
+
*/
|
|
164
|
+
interface ImageDrawOptions {
|
|
165
|
+
/** Offset, in pixels, from the bottom edge. */
|
|
166
|
+
bottom?: number;
|
|
167
|
+
/** Blend mode for compositing this overlay onto the image. Default `over`. */
|
|
168
|
+
composite?: ImageCompositeMode;
|
|
169
|
+
/** Offset, in pixels, from the left edge. */
|
|
170
|
+
left?: number;
|
|
171
|
+
/** Overlay opacity, `0.0` (transparent) – `1.0` (opaque). */
|
|
172
|
+
opacity?: number;
|
|
173
|
+
/** Tile the overlay across the base image: `true`, or a single axis `"x"`/`"y"`. */
|
|
174
|
+
repeat?: "x" | "y" | boolean;
|
|
175
|
+
/** Offset, in pixels, from the right edge. */
|
|
176
|
+
right?: number;
|
|
177
|
+
/** Offset, in pixels, from the top edge. */
|
|
178
|
+
top?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* One overlay applied through the **binding** path (`Images.transform`'s
|
|
182
|
+
* `overlays` argument). The overlay bytes come from `image` (any {@link ImageInput});
|
|
183
|
+
* an optional `transform` pre-sizes/reformats the overlay before it is drawn.
|
|
184
|
+
*/
|
|
185
|
+
interface ImageOverlay extends ImageDrawOptions {
|
|
186
|
+
/** The overlay image bytes — a stream, buffer, `Blob`, or R2 object body. */
|
|
187
|
+
image: ImageInput;
|
|
188
|
+
/** Optional transform applied to the overlay before compositing (e.g. resize). */
|
|
189
|
+
transform?: TransformOptions;
|
|
190
|
+
}
|
|
191
|
+
/** One link in the transform chain: apply more transforms, draw an overlay, or finalize with `output`. */
|
|
192
|
+
interface ImageTransformerLike {
|
|
193
|
+
draw: (image: ImageTransformerLike | ReadableStream<Uint8Array>, options?: ImageDrawOptions) => ImageTransformerLike;
|
|
194
|
+
output: (options: OutputOptions) => Promise<ImageTransformationResultLike>;
|
|
195
|
+
transform: (transform: TransformOptions) => ImageTransformerLike;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Minimal projection of `ImagesBinding`. Declared structurally so unit tests can
|
|
199
|
+
* pass a plain object double; the real `env.IMAGES` binding satisfies the same
|
|
200
|
+
* shape. Only the input/transform/output chain and `info` are projected — the
|
|
201
|
+
* hosted-images CRUD surface is out of scope.
|
|
202
|
+
*/
|
|
203
|
+
interface ImagesBindingLike {
|
|
204
|
+
info: (stream: ReadableStream<Uint8Array>) => Promise<ImageInfoLike>;
|
|
205
|
+
input: (stream: ReadableStream<Uint8Array>) => ImageTransformerLike;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* An R2 object body (as returned by `ctx.storage.download(key)`) — first-class
|
|
209
|
+
* transform input. Only `.body` is read, so a structural projection is enough.
|
|
210
|
+
*/
|
|
211
|
+
interface R2ObjectBodyLike {
|
|
212
|
+
body: ReadableStream | null;
|
|
213
|
+
}
|
|
214
|
+
/** Anything `transform`/`info` accept as input bytes. R2 bodies are unwrapped to their stream. */
|
|
215
|
+
type ImageInput = ArrayBuffer | Blob | R2ObjectBodyLike | ReadableStream | Uint8Array;
|
|
216
|
+
interface LunoraImagesOptions {
|
|
217
|
+
/** The Cloudflare Images binding (`env.IMAGES`). */
|
|
218
|
+
binding: ImagesBindingLike;
|
|
219
|
+
/** Maximum pixel value any single `width`/`height` may request. Default 10000. */
|
|
220
|
+
maxDimension?: number;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The action-only Images client wired onto `ctx.images`.
|
|
224
|
+
*
|
|
225
|
+
* The binding-backed `transform`/`info` calls are non-deterministic network /
|
|
226
|
+
* compute I/O, so this lives on **ActionCtx only** — the same seam as `ctx.ai`.
|
|
227
|
+
* The pure URL/signed-URL builders are exported as free functions (see
|
|
228
|
+
* `index.ts`) and are safe to call from any handler.
|
|
229
|
+
*/
|
|
230
|
+
interface Images {
|
|
231
|
+
/**
|
|
232
|
+
* Probe an image for its format and (for raster formats) dimensions + byte
|
|
233
|
+
* size, without running a transform. Wraps `binding.info(...)`.
|
|
234
|
+
*/
|
|
235
|
+
info: (input: ImageInput) => Promise<ImageInfoLike>;
|
|
236
|
+
/**
|
|
237
|
+
* Resize / reformat / optimize `input`, returning the transformed result
|
|
238
|
+
* (a `Response`, content type, and byte stream). Accepts a raw stream/buffer,
|
|
239
|
+
* a `Blob`, or an R2 object body straight from `ctx.storage.download(key)`.
|
|
240
|
+
*
|
|
241
|
+
* `transform` dimensions are clamped to the configured ceiling and the output
|
|
242
|
+
* `format` is validated against the allowlist, so a hostile request can't
|
|
243
|
+
* mint a multi-gigapixel canvas or an unexpected content type.
|
|
244
|
+
*
|
|
245
|
+
* `overlays` are composited over the result in order (last on top) via the
|
|
246
|
+
* binding's `draw` step — each overlay's bytes come from its own `image`, with
|
|
247
|
+
* optional per-overlay `transform` (resize/reformat) and blend/position options.
|
|
248
|
+
*/
|
|
249
|
+
transform: (input: ImageInput, transform?: TransformOptions, output?: OutputOptions, overlays?: ImageOverlay[]) => Promise<ImageTransformationResultLike>;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Build the action-only {@link Images} client over a Cloudflare Images binding.
|
|
253
|
+
*
|
|
254
|
+
* ```ts
|
|
255
|
+
* const images = createImages({ binding: env.IMAGES });
|
|
256
|
+
* const result = await images.transform(
|
|
257
|
+
* await ctx.storage.download("uploads/avatar.png"),
|
|
258
|
+
* { width: 256, height: 256, fit: "cover" },
|
|
259
|
+
* { format: "image/webp", quality: 82 },
|
|
260
|
+
* );
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
declare const createImages: (options: LunoraImagesOptions) => Images;
|
|
264
|
+
interface ImageDeliveryUrlOptions {
|
|
265
|
+
/** Delivery / transform origin, e.g. `https://cdn.acme.test`. */
|
|
266
|
+
baseUrl: string;
|
|
267
|
+
/**
|
|
268
|
+
* Hosted-Images image id. When set, the **delivery-variant** form is built
|
|
269
|
+
* (`<baseUrl>/<imageId>/<variant>`) and `transform`/`key` are ignored.
|
|
270
|
+
*/
|
|
271
|
+
imageId?: string;
|
|
272
|
+
/**
|
|
273
|
+
* Source image — an absolute URL or an origin-relative key. Used by the
|
|
274
|
+
* `/cdn-cgi/image/...` transform form. Ignored when `imageId` is set.
|
|
275
|
+
*/
|
|
276
|
+
key?: string;
|
|
277
|
+
/** Transform options for the `/cdn-cgi/image/<options>/<source>` form. */
|
|
278
|
+
transform?: TransformOptions;
|
|
279
|
+
/** Named delivery variant (e.g. `public`, `thumbnail`). Used with `imageId`; default `public`. */
|
|
280
|
+
variant?: string;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Build a Cloudflare Images delivery / transform URL.
|
|
284
|
+
*
|
|
285
|
+
* - With `imageId`: `<baseUrl>/<imageId>/<variant>` (hosted delivery variant).
|
|
286
|
+
* - With `key`: `<baseUrl>/cdn-cgi/image/<options>/<source>` (URL-based transform).
|
|
287
|
+
*
|
|
288
|
+
* Pure and deterministic — usable from any handler.
|
|
289
|
+
*/
|
|
290
|
+
declare const buildImageDeliveryUrl: (options: ImageDeliveryUrlOptions) => string;
|
|
291
|
+
interface SignedImageUrlOptions {
|
|
292
|
+
/** Delivery / Worker origin the signed URL points at (e.g. `https://cdn.acme.test`). */
|
|
293
|
+
baseUrl: string;
|
|
294
|
+
/** Seconds the URL stays valid. Default 3600; capped at 7 days. */
|
|
295
|
+
expiresInSeconds?: number;
|
|
296
|
+
/** Image key/id resolved by the Worker route (the pathname). */
|
|
297
|
+
key: string;
|
|
298
|
+
/** HMAC secret. MUST NOT be shared across tenants. */
|
|
299
|
+
secret: string;
|
|
300
|
+
/**
|
|
301
|
+
* Transform requested by this URL. Bound into the signature, so a client
|
|
302
|
+
* can't alter the render without invalidating it. The Worker should apply
|
|
303
|
+
* exactly this (verified) transform via `ctx.images.transform(...)`.
|
|
304
|
+
*/
|
|
305
|
+
transform?: TransformOptions;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Mint a Worker-signed image URL: `baseUrl` joined to `key`, plus `exp` (unix
|
|
309
|
+
* seconds), the serialized `t` (transform), and `sig` (base64url HMAC). The
|
|
310
|
+
* canonical binds host + key + expiry + transform.
|
|
311
|
+
*
|
|
312
|
+
* The Worker handling the route should call {@link verifySignedImageUrl} to
|
|
313
|
+
* validate before serving / transforming.
|
|
314
|
+
*/
|
|
315
|
+
declare const buildSignedImageUrl: (options: SignedImageUrlOptions) => Promise<string>;
|
|
316
|
+
interface VerifyImageResult {
|
|
317
|
+
/** The verified image key (route pathname). */
|
|
318
|
+
key?: string;
|
|
319
|
+
/**
|
|
320
|
+
* Internal-only failure reason for server logs/diagnostics. **Do not echo to
|
|
321
|
+
* clients** — a precise reason ("expired" vs "bad_signature") is a signing
|
|
322
|
+
* oracle. Public responses should expose only `valid`.
|
|
323
|
+
*/
|
|
324
|
+
reason?: "bad_signature" | "expired" | "malformed";
|
|
325
|
+
/** The raw, verified transform string (the `t` query value), when present. */
|
|
326
|
+
transform?: string;
|
|
327
|
+
valid: boolean;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Verify a {@link buildSignedImageUrl} output. By default the signature is
|
|
331
|
+
* canonicalized against the inbound `url.host`; pass `expectedHost` for a
|
|
332
|
+
* CDN/host-rewrite topology where the Worker sees a different host than the one
|
|
333
|
+
* the URL was minted for.
|
|
334
|
+
*/
|
|
335
|
+
declare const verifySignedImageUrl: (input: string | URL, secret: string, options?: {
|
|
336
|
+
expectedHost?: string;
|
|
337
|
+
}) => 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 };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createImages } from '../packem_shared/createImages-CJrvqX0u.mjs';
|
|
2
|
+
export { buildImageDeliveryUrl } from '../packem_shared/buildImageDeliveryUrl-D1sVfIOP.mjs';
|
|
3
|
+
export { buildSignedImageUrl, verifySignedImageUrl } from '../packem_shared/buildSignedImageUrl-Otdgc_jO.mjs';
|
|
@@ -0,0 +1,177 @@
|
|
|
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
|
+
};
|
|
80
|
+
/** Construction options for the `createKv` factory. */
|
|
81
|
+
interface LunoraKvOptions {
|
|
82
|
+
/**
|
|
83
|
+
* Optional per-instance key prefix applied to every operation (get/put/
|
|
84
|
+
* delete/list). Use for multi-tenant key namespacing — equivalent to
|
|
85
|
+
* calling the `scopeKey` helper on every key. Combined via `scopeKey`, so a
|
|
86
|
+
* `..` or NUL in the prefix is rejected.
|
|
87
|
+
*/
|
|
88
|
+
keyPrefix?: string;
|
|
89
|
+
/** The bound KV namespace (`env.<BINDING>`). */
|
|
90
|
+
namespace: KVNamespaceLike;
|
|
91
|
+
}
|
|
92
|
+
/** Options for {@link Kv.put}. JSON-stringifies the value unless `raw` is set. */
|
|
93
|
+
interface KvPutOptions {
|
|
94
|
+
/** Absolute expiration as a Unix timestamp (seconds). Mutually exclusive with `expirationTtl`. */
|
|
95
|
+
expiration?: number;
|
|
96
|
+
/** Relative expiration in seconds from now (minimum 60). Mutually exclusive with `expiration`. */
|
|
97
|
+
expirationTtl?: number;
|
|
98
|
+
/** Arbitrary metadata stored alongside the value (returned by `getWithMetadata`/`list`). */
|
|
99
|
+
metadata?: unknown;
|
|
100
|
+
/**
|
|
101
|
+
* When true, write `value` to KV verbatim (no `JSON.stringify`). `value`
|
|
102
|
+
* must already be a KV-writable type (string/ArrayBuffer/stream).
|
|
103
|
+
*/
|
|
104
|
+
raw?: boolean;
|
|
105
|
+
}
|
|
106
|
+
/** Options for {@link Kv.list}. */
|
|
107
|
+
interface KvListOptions {
|
|
108
|
+
/** Opaque cursor from a previous truncated page. */
|
|
109
|
+
cursor?: string;
|
|
110
|
+
/** Max keys per page (KV caps at 1000). */
|
|
111
|
+
limit?: number;
|
|
112
|
+
/** Restrict to keys starting with this prefix (combined with any `keyPrefix`). */
|
|
113
|
+
prefix?: string;
|
|
114
|
+
}
|
|
115
|
+
/** A single page of {@link Kv.list} results. */
|
|
116
|
+
interface KvListResult<Metadata = unknown> {
|
|
117
|
+
/** Cursor for the next page; `undefined` when the listing is complete. */
|
|
118
|
+
cursor?: string;
|
|
119
|
+
/**
|
|
120
|
+
* The key names, with any instance `keyPrefix` stripped back off so callers
|
|
121
|
+
* see the same keys they wrote.
|
|
122
|
+
*/
|
|
123
|
+
keys: KvListKey<Metadata>[];
|
|
124
|
+
/** True when this is the final page (no further `cursor`). */
|
|
125
|
+
listComplete: boolean;
|
|
126
|
+
}
|
|
127
|
+
/** A value together with its stored metadata (from {@link Kv.getWithMetadata}). */
|
|
128
|
+
interface KvValueWithMetadata<Value, Metadata> {
|
|
129
|
+
/** The stored metadata, or `null` when none was set / the key is absent. */
|
|
130
|
+
metadata: Metadata | null;
|
|
131
|
+
/** The decoded value, or `null` when the key is absent. */
|
|
132
|
+
value: Value | null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The typed Workers KV client bound to `ctx.kv`. JSON-decodes/encodes by
|
|
136
|
+
* default; a raw escape hatch ({@link Kv.getRaw} / `put(..., { raw: true })`)
|
|
137
|
+
* handles text/binary/stream values.
|
|
138
|
+
*/
|
|
139
|
+
interface Kv {
|
|
140
|
+
/** Delete a key. No-op if absent. */
|
|
141
|
+
delete: (key: string) => Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Read a key and `JSON.parse` it into `T`. Returns `null` when the key is
|
|
144
|
+
* absent. Throws if the stored value isn't valid JSON — use
|
|
145
|
+
* {@link Kv.getRaw} for non-JSON values.
|
|
146
|
+
*/
|
|
147
|
+
get: <T = unknown>(key: string, options?: {
|
|
148
|
+
cacheTtl?: number;
|
|
149
|
+
}) => Promise<T | null>;
|
|
150
|
+
/** Read a raw value with an explicit decode `type` (default `"text"`). Returns `null` when absent. */
|
|
151
|
+
getRaw: <T = string>(key: string, options?: KvGetOptions) => Promise<T | null>;
|
|
152
|
+
/**
|
|
153
|
+
* Read a key's JSON value together with its metadata. Returns
|
|
154
|
+
* `{ value: null, metadata: null }` when the key is absent.
|
|
155
|
+
*/
|
|
156
|
+
getWithMetadata: <T = unknown, M = unknown>(key: string, options?: {
|
|
157
|
+
cacheTtl?: number;
|
|
158
|
+
}) => Promise<KvValueWithMetadata<T, M>>;
|
|
159
|
+
/** List keys (optionally `prefix`-filtered, paginated via `cursor`). */
|
|
160
|
+
list: <M = unknown>(options?: KvListOptions) => Promise<KvListResult<M>>;
|
|
161
|
+
/**
|
|
162
|
+
* Write `value` to `key`. JSON-stringifies `value` unless `options.raw` is
|
|
163
|
+
* set (in which case `value` must be a KV-writable type). Forwards
|
|
164
|
+
* `expirationTtl`/`expiration`/`metadata` to the binding.
|
|
165
|
+
*/
|
|
166
|
+
put: <T = unknown>(key: string, value: T, options?: KvPutOptions) => Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Compose a per-tenant key from a scope prefix and a caller-supplied key. Both
|
|
170
|
+
* halves are validated — the prefix may not contain `..` or NUL either, and the
|
|
171
|
+
* resulting key must stay under KV's length ceiling. Recommended for any
|
|
172
|
+
* multi-tenant deployment so client-supplied keys can't address peer data.
|
|
173
|
+
* Mirrors `scopeKey` from `@lunora/storage`.
|
|
174
|
+
*/
|
|
175
|
+
declare const scopeKey: (prefix: string, key: string) => string;
|
|
176
|
+
declare const createKv: (options: LunoraKvOptions) => Kv;
|
|
177
|
+
export { type KVNamespaceLike, type Kv, type KvGetOptions, type KvListKey, type KvListOptions, type KvListResult, type KvNamespaceListResult, type KvNamespacePutOptions, type KvPutOptions, type KvValue, type KvValueType, type KvValueWithMetadata, type LunoraKvOptions, createKv, scopeKey };
|