@lunora/bindings 1.0.0-alpha.9 → 1.0.0-alpha.91
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/README.md +11 -9
- package/dist/ai-search/index.d.mts +741 -0
- package/dist/ai-search/index.d.ts +741 -0
- package/dist/ai-search/index.mjs +0 -0
- package/dist/analytics/index.d.mts +21 -25
- package/dist/analytics/index.d.ts +21 -25
- package/dist/analytics/index.mjs +1 -2
- package/dist/artifacts/index.d.mts +426 -0
- package/dist/artifacts/index.d.ts +426 -0
- package/dist/artifacts/index.mjs +1 -0
- package/dist/images/index.d.mts +37 -52
- package/dist/images/index.d.ts +37 -52
- package/dist/images/index.mjs +1 -3
- package/dist/kv/index.d.mts +4 -81
- package/dist/kv/index.d.ts +4 -81
- package/dist/kv/index.mjs +1 -2
- package/dist/packem_shared/AnalyticsSqlError-CeQ3A5Eb.mjs +1 -0
- package/dist/packem_shared/R2SqlError-ZHgOWClB.mjs +1 -0
- package/dist/packem_shared/SelectBuilder-DJXNSdqC.mjs +1 -0
- package/dist/packem_shared/SetOperation-kiI5Wnlm.mjs +1 -0
- package/dist/packem_shared/Sql-BfnxRway.mjs +1 -0
- package/dist/packem_shared/WindowExpression-VX7EEV3h.mjs +1 -0
- package/dist/packem_shared/WindowFunction-CL4jYy2l.mjs +1 -0
- package/dist/packem_shared/asc-DP_WFiAE.mjs +1 -0
- package/dist/packem_shared/authenticatedRemote-CPm87dLq.mjs +1 -0
- package/dist/packem_shared/buildImageDeliveryUrl-Brqs-dcZ.mjs +1 -0
- package/dist/packem_shared/buildSignedImageUrl-BV-iSJKA.mjs +4 -0
- package/dist/packem_shared/cap-error-body-YBKO32BF.mjs +1 -0
- package/dist/packem_shared/concurrent-vRmSvRpF.mjs +1 -0
- package/dist/packem_shared/createAnalytics-BXTNc57d.mjs +1 -0
- package/dist/packem_shared/createArtifacts-cXCusYbi.mjs +1 -0
- package/dist/packem_shared/createContextVectors-DiyO3pZU.mjs +6 -0
- package/dist/packem_shared/createImages-D7JExfqF.mjs +1 -0
- package/dist/packem_shared/createKv-mAHanD5g.mjs +1 -0
- package/dist/packem_shared/createKvIntrospector-BpRiFRFQ.mjs +1 -0
- package/dist/packem_shared/createPipelines-CIvqrc7E.mjs +1 -0
- package/dist/packem_shared/createVectorAdminIntrospector-Ct8v6PxJ.mjs +1 -0
- package/dist/packem_shared/createVectors-Dzv0ilKE.mjs +1 -0
- package/dist/pipelines/index.d.mts +1 -1
- package/dist/pipelines/index.d.ts +1 -1
- package/dist/pipelines/index.mjs +1 -1
- package/dist/r2sql/index.d.mts +54 -10
- package/dist/r2sql/index.d.ts +54 -10
- package/dist/r2sql/index.mjs +1 -7
- package/dist/vectors/index.d.mts +236 -71
- package/dist/vectors/index.d.ts +236 -71
- package/dist/vectors/index.mjs +1 -3
- package/package.json +14 -3
- package/dist/packem_shared/AnalyticsSqlError-C2nz3jpH.mjs +0 -41
- package/dist/packem_shared/R2SqlError-drPKSCZ3.mjs +0 -65
- package/dist/packem_shared/SelectBuilder-BOqJQHEv.mjs +0 -168
- package/dist/packem_shared/SetOperation-DmPgUL8W.mjs +0 -81
- package/dist/packem_shared/Sql-B3zq2YGx.mjs +0 -74
- package/dist/packem_shared/WindowExpression-BT_uA6g1.mjs +0 -44
- package/dist/packem_shared/WindowFunction-DrnuZUF6.mjs +0 -82
- package/dist/packem_shared/asc-DZbQCxh1.mjs +0 -16
- package/dist/packem_shared/buildImageDeliveryUrl-qZ7XbqTL.mjs +0 -35
- package/dist/packem_shared/buildSignedImageUrl-DNUFfyGP.mjs +0 -130
- package/dist/packem_shared/concurrent-CkCEVwqP.mjs +0 -39
- package/dist/packem_shared/createAnalytics-CEEI69o9.mjs +0 -57
- package/dist/packem_shared/createContextVectors-DwZtnPeC.mjs +0 -140
- package/dist/packem_shared/createImages-BzRnsz3H.mjs +0 -85
- package/dist/packem_shared/createKv-C8Iyu5hD.mjs +0 -145
- package/dist/packem_shared/createKvIntrospector-Byk4GfsY.mjs +0 -77
- package/dist/packem_shared/createPipelines-CfyJ6VGu.mjs +0 -10
- package/dist/packem_shared/createVectorAdminIntrospector-DuSvcBa5.mjs +0 -53
- package/dist/packem_shared/createVectors-CTSrctiK.mjs +0 -95
package/dist/images/index.d.ts
CHANGED
|
@@ -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
|
|
12
|
-
* /
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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.
|
|
161
|
-
*
|
|
162
|
-
*
|
|
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
|
-
* (
|
|
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
|
|
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`:
|
|
286
|
-
* - With `key`:
|
|
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
|
|
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 };
|
package/dist/images/index.mjs
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
|
|
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};
|
package/dist/kv/index.d.mts
CHANGED
|
@@ -1,82 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
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
|
|
194
|
+
export { type CreateKvIntrospectorOptions, type Kv, type KvIntrospectorLike, type KvListOptions, type KvListResult, type KvPutOptions, type KvValueWithMetadata, type LunoraKvOptions, createKv, createKvIntrospector, createKvIntrospectorFromEnv, scopeKey };
|
package/dist/kv/index.d.ts
CHANGED
|
@@ -1,82 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
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
|
|
194
|
+
export { type CreateKvIntrospectorOptions, type Kv, type KvIntrospectorLike, type KvListOptions, type KvListResult, type KvPutOptions, type KvValueWithMetadata, type LunoraKvOptions, createKv, createKvIntrospector, createKvIntrospectorFromEnv, scopeKey };
|
package/dist/kv/index.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { createKvIntrospector, createKvIntrospectorFromEnv } from '../packem_shared/createKvIntrospector-Byk4GfsY.mjs';
|
|
1
|
+
import{createKv as o,scopeKey as t}from"../packem_shared/createKv-mAHanD5g.mjs";import{createKvIntrospector as p,createKvIntrospectorFromEnv as v}from"../packem_shared/createKvIntrospector-BpRiFRFQ.mjs";export{o as createKv,p as createKvIntrospector,v as createKvIntrospectorFromEnv,t as scopeKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as y}from"@lunora/errors";import{c as h}from"./cap-error-body-YBKO32BF.mjs";const w="https://api.cloudflare.com/client/v4/accounts",S=6e4;class a extends y{constructor(r,o){super("ANALYTICS_SQL_ERROR",`Analytics Engine SQL API returned ${String(r)}: ${h(o)}`,{cause:o,name:"AnalyticsSqlError",status:r})}}const b=e=>{const r=e.fetch??globalThis.fetch,o=`${w}/${encodeURIComponent(e.accountId)}/analytics_engine/sql`,c=e.timeoutMs??S;return{query:async u=>{const n=new AbortController,d=setTimeout(()=>{n.abort()},c);try{const t=await r(o,{body:u,headers:{Authorization:`Bearer ${e.apiToken}`,"Content-Type":"text/plain"},method:"POST",signal:n.signal});if(!t.ok)throw new a(t.status,await t.text().catch(()=>"<error body unavailable: the request deadline fired before it was read>"));let i;try{i=await t.json()}catch(m){throw n.signal.aborted?m:new a(t.status,"Analytics Engine SQL API returned a non-JSON body.")}const s=i,l=s.data??[];return{columns:s.meta??[],rowCount:s.rows??l.length,rows:l}}catch(t){throw n.signal.aborted&&!(t instanceof a)?new a(504,`query timed out after ${String(c)}ms (AnalyticsSqlConfig.timeoutMs)`):t}finally{clearTimeout(d)}}}};export{a as AnalyticsSqlError,b as createAnalyticsSqlClient};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as f}from"@lunora/errors";import{c as b}from"./cap-error-body-YBKO32BF.mjs";import R from"./SelectBuilder-DJXNSdqC.mjs";import{ident as m,toText as h}from"./Sql-BfnxRway.mjs";const T="https://api.sql.cloudflarestorage.com/api/v1/accounts",E=6e4,$=e=>e[0]===void 0?[]:Object.keys(e[0]).map(s=>({name:s}));class c extends f{constructor(s,i){super("R2_SQL_ERROR",`R2 SQL query failed (${String(s)}): ${b(i)}`,{cause:i,name:"R2SqlError",status:s})}}const C=e=>{const s=e.fetch??globalThis.fetch,S=`${e.endpoint??T}/${encodeURIComponent(e.accountId)}/r2-sql/query/${encodeURIComponent(e.bucket)}`,p=`${e.accountId}_${e.bucket}`,l=e.timeoutMs??E,n=async t=>{const a=new AbortController,w=setTimeout(()=>{a.abort()},l);try{const r=await s(S,{body:JSON.stringify({query:t,warehouse:p}),headers:{Authorization:`Bearer ${e.apiToken}`,"Content-Type":"application/json"},method:"POST",signal:a.signal});if(!r.ok)throw new c(r.status,await r.text().catch(()=>"<error body unavailable: the request deadline fired before it was read>"));let d;try{d=await r.json()}catch(y){throw a.signal.aborted?y:new c(r.status,"R2 SQL returned a non-JSON body.")}const o=d;if(o.success===!1||o.errors!==void 0&&o.errors.length>0)throw new c(r.status,JSON.stringify(o.errors??o));const u=o.result?.rows??[];return{columns:o.result?.schema??$(u),rowCount:u.length,rows:u}}catch(r){throw a.signal.aborted&&!(r instanceof c)?new c(504,`query timed out after ${String(l)}ms (R2SqlConfig.timeoutMs)`):r}finally{clearTimeout(w)}};return{describe:async t=>n(`DESCRIBE ${m(t)}`),explain:async(t,a)=>n(`EXPLAIN ${a?.format==="json"?"FORMAT JSON ":""}${h(t)}`),from:t=>new R(n,t),query:async t=>n(h(t)),showDatabases:async()=>n("SHOW DATABASES"),showTables:async t=>n(`SHOW TABLES IN ${m(t)}`)}};export{c as R2SqlError,C as createR2Sql};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{renderOrderTerm as u}from"./asc-DP_WFiAE.mjs";import l from"./SetOperation-kiI5Wnlm.mjs";import{tableRef as n,toText as e,assertLimit as a,lit as d}from"./Sql-BfnxRway.mjs";const r={cross:"CROSS JOIN",full:"FULL OUTER JOIN",inner:"INNER JOIN",left:"LEFT JOIN",right:"RIGHT JOIN"},h=s=>s.length>1?s.map(t=>`(${t})`).join(" AND "):s.join(" AND ");class c{exec;table;selectItems=[];distinctFlag=!1;distinctOnItems=[];joins=[];whereConditions=[];groupByItems=[];havingConditions=[];qualifyCondition;orderByItems=[];limitValue;constructor(t,i){this.exec=t,this.table=n(i)}select(...t){return this.selectItems.push(...t.map(i=>e(i))),this}distinct(){return this.distinctFlag=!0,this}distinctOn(...t){return this.distinctOnItems.push(...t.map(i=>e(i))),this}innerJoin(t,i){return this.addJoin("inner",t,i)}leftJoin(t,i){return this.addJoin("left",t,i)}rightJoin(t,i){return this.addJoin("right",t,i)}fullJoin(t,i){return this.addJoin("full",t,i)}crossJoin(t){return this.addJoin("cross",t)}where(...t){return this.whereConditions.push(...t.map(i=>e(i))),this}groupBy(...t){return this.groupByItems.push(...t.map(i=>e(i))),this}having(...t){return this.havingConditions.push(...t.map(i=>e(i))),this}qualify(t){return this.qualifyCondition=e(t),this}orderBy(...t){return this.orderByItems.push(...t.map(i=>u(i))),this}limit(t){return a(t),this.limitValue=t,this}returns(){return this}union(t){return this.setOperation("UNION",t)}unionAll(t){return this.setOperation("UNION ALL",t)}intersect(t){return this.setOperation("INTERSECT",t)}except(t){return this.setOperation("EXCEPT",t)}get needsWrapForSetOperation(){return this.orderByItems.length>0||this.limitValue!==void 0}toSQL(){const t=[`${this.renderHead()} ${this.selectItems.length>0?this.selectItems.join(", "):"*"}`,`FROM ${this.table}`];for(const i of this.joins)t.push(i.on===void 0?`${r[i.kind]} ${i.table}`:`${r[i.kind]} ${i.table} ON ${e(i.on)}`);return this.whereConditions.length>0&&t.push(`WHERE ${h(this.whereConditions)}`),this.groupByItems.length>0&&t.push(`GROUP BY ${this.groupByItems.join(", ")}`),this.havingConditions.length>0&&t.push(`HAVING ${h(this.havingConditions)}`),this.qualifyCondition!==void 0&&t.push(`QUALIFY ${this.qualifyCondition}`),this.orderByItems.length>0&&t.push(`ORDER BY ${this.orderByItems.join(", ")}`),this.limitValue!==void 0&&t.push(`LIMIT ${d(this.limitValue)}`),t.join(" ")}async run(){return this.exec(this.toSQL())}renderHead(){return this.distinctOnItems.length>0?`SELECT DISTINCT ON (${this.distinctOnItems.join(", ")})`:this.distinctFlag?"SELECT DISTINCT":"SELECT"}addJoin(t,i,o){return this.joins.push({kind:t,on:o,table:n(i)}),this}setOperation(t,i){return new l(this.exec,[{query:this},{operator:t,query:i}])}}export{c as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{renderOrderTerm as o}from"./asc-DP_WFiAE.mjs";import{assertLimit as u,lit as a}from"./Sql-BfnxRway.mjs";const h=s=>{const t=s.toSQL();return s.needsWrapForSetOperation===!0?`(${t})`:t};class p{needsWrapForSetOperation=!0;exec;members;orderByItems=[];limitValue;constructor(t,r){this.exec=t,this.members=r}union(t){return this.add("UNION",t)}unionAll(t){return this.add("UNION ALL",t)}intersect(t){return this.add("INTERSECT",t)}except(t){return this.add("EXCEPT",t)}orderBy(...t){return this.orderByItems.push(...t.map(r=>o(r))),this}limit(t){return u(t),this.limitValue=t,this}returns(){return this}toSQL(){const r=this.members.map(i=>{const n=h(i.query);return i.operator===void 0?n:`${i.operator} ${n}`}).join(" "),e=[];return this.orderByItems.length>0&&e.push(`ORDER BY ${this.orderByItems.join(", ")}`),this.limitValue!==void 0&&e.push(`LIMIT ${a(this.limitValue)}`),e.length>0?`${r} ${e.join(" ")}`:r}async run(){return this.exec(this.toSQL())}add(t,r){return this.members.push({operator:t,query:r}),this}}export{p as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=t=>`'${t.replaceAll("'","''")}'`,c=/^\w+(?:\.\w+)*$/,p=/^\w+(?:\.\w+)*(?:\s+(?:as\s+)?\w+)?$/i;class n{text;constructor(r){this.text=r}toString(){return this.text}}const s=t=>t instanceof n,l=t=>new n(t),w=t=>s(t)?t.text:t,y=t=>{if(typeof t!="string"||!c.test(t))throw new TypeError(`r2sql: invalid identifier ${JSON.stringify(t)} — expected dotted [A-Za-z0-9_] segments (e.g. "namespace.table").`);return t},g=t=>{if(typeof t!="string"||!p.test(t))throw new TypeError(`r2sql: invalid table reference ${JSON.stringify(t)} — expected "namespace.table" with an optional "[AS] alias".`);return t},a=t=>{if(t==null)return"NULL";if(typeof t=="boolean")return t?"true":"false";if(typeof t=="bigint")return t.toString();if(typeof t=="number"){if(!Number.isFinite(t))throw new TypeError(`r2sql: cannot inline a non-finite number (${String(t)}) as a SQL literal.`);return String(t)}if(typeof t=="string")return o(t);if(t instanceof Date){if(Number.isNaN(t.getTime()))throw new TypeError("r2sql: cannot inline an invalid Date — it has no RFC3339 form. Check the value parsed before building the query.");return o(t.toISOString())}if(Array.isArray(t)){if(t.length===0)throw new TypeError("r2sql: cannot inline an empty array — `IN ()` is not valid SQL. Guard the empty case before building the query.");return`(${t.map(r=>a(r)).join(", ")})`}throw new TypeError(`r2sql: cannot inline a value of type ${typeof t} as a SQL literal. Wrap trusted SQL with raw(), or pass a primitive/Date/array.`)},S=(t,...r)=>{let e=t[0]??"";for(const[f,i]of r.entries())e+=s(i)?i.text:a(i),e+=t[f+1]??"";return new n(e)},d=(t,r)=>new n(t.map(e=>w(e)).join(r)),h=t=>{if(!Number.isInteger(t)||t<1||t>1e4)throw new RangeError(`r2sql: limit must be an integer between 1 and ${String(1e4)} (got ${String(t)}).`)};export{n as Sql,h as assertLimit,y as ident,s as isSql,d as joinSql,a as lit,l as raw,S as sql,g as tableRef,w as toText};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Sql as r,lit as i}from"./Sql-BfnxRway.mjs";const n=/^[A-Z_][\w$]*$/i,o=t=>{if(!n.test(t))throw new TypeError(`r2sql: invalid identifier ${JSON.stringify(t)} — expected a simple SQL name (letters, digits, underscore).`);return t};class p extends r{as(e){return new r(`${this.text} AS ${o(e)}`)}between(e,s){return new r(`${this.text} BETWEEN ${i(e)} AND ${i(s)}`)}eq(e){return this.compare("=",e)}gt(e){return this.compare(">",e)}gte(e){return this.compare(">=",e)}lt(e){return this.compare("<",e)}lte(e){return this.compare("<=",e)}compare(e,s){return new r(`${this.text} ${e} ${i(s)}`)}}export{p as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{renderOrderTerm as $}from"./asc-DP_WFiAE.mjs";import{toText as o,lit as s}from"./Sql-BfnxRway.mjs";import A from"./WindowExpression-VX7EEV3h.mjs";const u=r=>r===void 0?[]:Array.isArray(r)?r:[r],c=r=>{const t=[],i=u(r.partitionBy).map(a=>o(a));i.length>0&&t.push(`PARTITION BY ${i.join(", ")}`);const e=u(r.orderBy).map(a=>$(a));return e.length>0&&t.push(`ORDER BY ${e.join(", ")}`),r.frame!==void 0&&r.frame.length>0&&t.push(r.frame),`OVER (${t.join(" ")})`},m=(r,t,i)=>{const e=[o(r)];return t!==void 0&&e.push(s(t)),i!==void 0&&e.push(s(i)),e.join(", ")};class d{callText;constructor(t){this.callText=t}over(t={}){return new A(`${this.callText} ${c(t)}`)}}const n=r=>new d(r),l={avg:r=>n(`AVG(${o(r)})`),count:r=>n(`COUNT(${r===void 0?"*":o(r)})`),cumeDist:()=>n("CUME_DIST()"),denseRank:()=>n("DENSE_RANK()"),firstValue:r=>n(`FIRST_VALUE(${o(r)})`),lag:(r,t,i)=>n(`LAG(${m(r,t,i)})`),lastValue:r=>n(`LAST_VALUE(${o(r)})`),lead:(r,t,i)=>n(`LEAD(${m(r,t,i)})`),max:r=>n(`MAX(${o(r)})`),min:r=>n(`MIN(${o(r)})`),nthValue:(r,t)=>n(`NTH_VALUE(${o(r)}, ${s(t)})`),ntile:r=>n(`NTILE(${s(r)})`),percentRank:()=>n("PERCENT_RANK()"),rank:()=>n("RANK()"),rowNumber:()=>n("ROW_NUMBER()"),sum:r=>n(`SUM(${o(r)})`)};export{d as WindowFunction,l as fn};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Sql as e,toText as n}from"./Sql-BfnxRway.mjs";const o=r=>({dir:"ASC",expr:r}),i=r=>({dir:"DESC",expr:r}),s=r=>typeof r=="string"||r instanceof e?n(r):`${n(r.expr)} ${r.dir}`;export{o as asc,i as desc,s as renderOrderTerm};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as e}from"@lunora/errors";const s=(n,r)=>{const[o=""]=r.split("?expires=");if(o==="")throw new e("BAD_REQUEST","@lunora/bindings/artifacts: authenticatedRemote needs a non-empty token");let t;try{t=new URL(n)}catch{throw new e("BAD_REQUEST","@lunora/bindings/artifacts: authenticatedRemote needs the repo's absolute `remote` URL")}if(t.protocol!=="https:")throw new e("BAD_REQUEST",`@lunora/bindings/artifacts: authenticatedRemote needs an https remote, got "${t.protocol}"`);return t.username="x",t.password=o,t.toString()};export{s as authenticatedRemote};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as a}from"@lunora/errors";const s=/^[a-z][a-z\d+\-.]*:\/\//i,c=[",","=","#","?","/"],d=e=>e.endsWith("/")?e.slice(0,-1):e,g=e=>e.startsWith("/")?e.slice(1):e,m=e=>Object.entries(e).filter(([,r])=>r!==void 0&&(typeof r=="string"||typeof r=="number")).map(([r,i])=>{const n=String(i),t=c.find(o=>n.includes(o));if(t!==void 0)throw new a("INTERNAL",`@lunora/bindings/images: transform option \`${r}\` value \`${n}\` contains a \`${t}\`, which the /cdn-cgi/image/ option path cannot represent (\`,\`/\`=\` are the option/key-value separators; \`#\`/\`?\`/\`/\` are URL-structural). Percent-encode the value — for colors use \`%23RRGGBB\`, not \`#RRGGBB\` or \`rgb(r,g,b)\`.`);return`${r}=${n}`}).join(","),l=e=>e.split("/").map(r=>encodeURIComponent(r)).join("/"),h=e=>{const r=d(e.baseUrl);if(e.imageId!==void 0){const o=e.variant??"public";return`${r}/${encodeURIComponent(e.imageId)}/${encodeURIComponent(o)}`}if(e.key===void 0)throw new a("INTERNAL","@lunora/bindings/images: buildImageDeliveryUrl requires either `imageId` or `key`");const i=e.transform===void 0?"":m(e.transform),n=s.test(e.key)?e.key:l(g(e.key)),t=i===""?"/cdn-cgi/image":`/cdn-cgi/image/${i}`;return`${r}${t}/${n}`};export{h as buildImageDeliveryUrl};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const w=e=>{const t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n+=1)r[n]=t.codePointAt(n)??0;return r},a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",E=e=>{let t="",r=0;const n=e.length-2;for(;r<n;r+=3){const s=e[r]<<16|e[r+1]<<8|e[r+2];t+=a.charAt(s>>18&63)+a.charAt(s>>12&63)+a.charAt(s>>6&63)+a.charAt(s&63)}const o=e.length-r;if(o===1){const s=e[r]<<16;t+=a.charAt(s>>18&63)+a.charAt(s>>12&63)}else if(o===2){const s=e[r]<<16|e[r+1]<<8;t+=a.charAt(s>>18&63)+a.charAt(s>>12&63)+a.charAt(s>>6&63)}return t},v=e=>{const t=e.replaceAll("-","+").replaceAll("_","/"),r=t+"=".repeat((4-t.length%4)%4);return w(r)},R=(e,t)=>{if(e.size<t)return;const r=e.keys().next().value;r!==void 0&&e.delete(r)},_=(e,t,r,n)=>{const o=e.get(t);if(o!==void 0)return o;R(e,n);const s=r().catch(i=>{throw e.get(t)===s&&e.delete(t),i});return e.set(t,s),s},f=new TextEncoder,T=10080*60,$=/^[a-z][a-z0-9+\-.]*:\/\//i,x=Array.from({length:32},(e,t)=>t),C=new RegExp(`[${x.map(e=>String.fromCodePoint(e)).join("")}]`,"u"),U=64,N=new Map,h=async e=>_(N,e,async()=>crypto.subtle.importKey("raw",f.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),U),p=e=>{try{return new URL(e).host}catch{return e.replace($,"").split("/")[0]??""}},y=e=>{if(C.test(e))throw new TypeError("hmac-url: value must not contain control characters (including CR/LF)")},L=/^\/+$/u,O=e=>L.test(e),H=(e,t)=>{if(!Number.isFinite(e)||e<=0)return"expiresInSeconds must be a positive finite number";if(e>t){const r=` (${String(t/86400)} days)`;return`expiresInSeconds must not exceed ${String(t)} seconds${r}`}},I=async(e,t)=>{const r=await h(e),n=await crypto.subtle.sign("HMAC",r,f.encode(t));return E(new Uint8Array(n))},K=async(e,t,r)=>{const n=await h(e);return crypto.subtle.verify("HMAC",n,r,f.encode(t))},b=/^\//,P=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},D=e=>e.replaceAll("&","%26").replaceAll("=","%3D"),M=e=>e.replaceAll("%3D","=").replaceAll("%26","&"),j=e=>e===void 0?"":Object.entries(e).filter(([,t])=>t!==void 0).toSorted(([t],[r])=>(t>r?1:0)-(t<r?1:0)).map(([t,r])=>`${t}=${D(typeof r=="object"?JSON.stringify(r):String(r))}`).join("&"),k={background:"string",blur:"number",brightness:"number",contrast:"number",fit:"string",flip:"string",gamma:"number",gravity:"string-or-json",height:"number",rotate:"number",saturation:"number",segment:"string",sharpen:"number",upscale:"string",width:"number"},z=new Map(Object.entries(k)),B=(e,t,r)=>{if(t==="string"||t==="string-or-json"&&!r.startsWith("{"))return r;if(t==="number"){const n=Number(r);if(r===""||!Number.isFinite(n))throw new TypeError(`@lunora/bindings/images: transform key "${e}" expects a number, got "${r}"`);return n}try{return JSON.parse(r)}catch{throw new TypeError(`@lunora/bindings/images: transform key "${e}" carries malformed JSON`)}},A=(e,t,r,n)=>`${e.toLowerCase()}
|
|
2
|
+
${t}
|
|
3
|
+
${String(r)}
|
|
4
|
+
${n}`,F=e=>e.split("/").map(t=>encodeURIComponent(t)).join("/"),Y=e=>{if(e==="")return{};const t={};for(const r of e.split("&")){const n=r.indexOf("=");if(n===-1)throw new TypeError(`@lunora/bindings/images: malformed transform segment "${r}" — expected key=value`);const o=r.slice(0,n),s=z.get(o);if(s===void 0)throw new TypeError(`@lunora/bindings/images: unknown transform key "${o}" — the serialized transform does not match this version's TransformOptions`);t[o]=B(o,s,M(r.slice(n+1)))}return t},J=async e=>{const t=e.expiresInSeconds??3600,r=H(t,T);if(r!==void 0)throw new TypeError(`@lunora/bindings/images: ${r}`);let n="";try{n=new URL(e.baseUrl).pathname}catch{}if(n!==""&&!O(n))throw new TypeError(`@lunora/bindings/images: baseUrl must not carry a path ("${n}") — the key is verified from the full URL pathname, so a subpath base would make every signed URL fail verification`);const o=Math.floor(Date.now()/1e3)+t,s=p(e.baseUrl),i=j(e.transform),c=e.key.replace(b,"");y(c);const l=await I(e.secret,A(s,c,o,i)),m=P(e.baseUrl),d=F(c),g=i===""?"":`&t=${encodeURIComponent(i)}`;return`${m}/${d}?exp=${String(o)}&sig=${l}${g}`},V=async(e,t,r)=>{let n;try{n=e instanceof URL?e:new URL(e)}catch{return{reason:"malformed",valid:!1}}const o=n.searchParams.get("exp"),s=o===null?Number.NaN:Number(o),i=n.searchParams.get("sig"),c=n.searchParams.get("t")??"";if(!i||!Number.isInteger(s))return{reason:"malformed",valid:!1};if(s<Math.floor(Date.now()/1e3))return{reason:"expired",valid:!1};let l,m;try{l=n.pathname.replace(b,"").split("/").map(S=>decodeURIComponent(S)).join("/"),y(l),m=v(i)}catch{return{reason:"malformed",valid:!1}}const d=r?.expectedHost===void 0?n.host:p(r.expectedHost);if(!await K(t,A(d,l,s,c),m))return{reason:"bad_signature",valid:!1};if(c==="")return{key:l,valid:!0};let u;try{u=Y(c)}catch{u=void 0}return{key:l,transform:c,transformOptions:u,valid:!0}};export{J as buildSignedImageUrl,Y as parseSignedTransform,V as verifySignedImageUrl};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const _=R=>R.length>256?`${R.slice(0,256)}… (truncated)`:R;export{_ as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const h=8,u=async(r,c,l)=>{if(r.length===0)return[];const f=Math.max(1,Math.min(c,r.length)),n=Array.from({length:r.length});let a=0,t=!1,o;const s=Array.from({length:f},async()=>{for(;;){if(t)return;const e=a;if(a+=1,e>=r.length)return;try{n[e]=await l(r[e],e)}catch(i){t||(t=!0,o=i);return}}});if(await Promise.all(s),t)throw o;return n};export{h as U,u as c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const _=new TextEncoder,l=n=>n===null?0:typeof n=="string"?_.encode(n).length:n.byteLength,a=(n,o,r)=>{if(o>r)throw new RangeError(`@lunora/bindings/analytics: a data point may carry at most ${String(r)} ${n} (got ${String(o)}).`)},b=(n,o,r)=>{if(o>r)throw new RangeError(`@lunora/bindings/analytics: a data point's ${n} may total at most ${String(r)} bytes (got ${String(o)}).`)},m=n=>{const o=t=>{a("blobs",t.blobs?.length??0,20),a("doubles",t.doubles?.length??0,20),a("indexes",t.indexes?.length??0,1);const s=(t.blobs??[]).reduce((e,c)=>e+l(c),0);b("blobs",s,16384);for(const e of t.indexes??[])b("index",l(e),96);n.writeDataPoint(t)};return{track:(t,s={})=>{const e=Object.entries(s.dimensions??{}),c=Object.entries(s.metrics??{}),E=[t,...e.map(([,i])=>i)],g=c.map(([,i])=>i),u=s.index===void 0?[]:[s.index];o({blobs:E,doubles:g,indexes:u});const B=e.map(([i],d)=>({column:`blob${String(d+2)}`,field:i})),S=c.map(([i],d)=>({column:`double${String(d+1)}`,field:i})),X=s.index===void 0?null:{column:"index1",field:"index"};return{dimensions:B,index:X,metrics:S,name:t}},writeDataPoint:o}};export{m as createAnalytics};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as c}from"@lunora/errors";import{authenticatedRemote as i}from"./authenticatedRemote-CPm87dLq.mjs";const s={ALREADY_EXISTS:"CONFLICT",CREATE_IN_PROGRESS:"CONFLICT",FORK_IN_PROGRESS:"CONFLICT",IMPORT_IN_PROGRESS:"CONFLICT",INTERNAL_ERROR:"INTERNAL",INVALID_INPUT:"BAD_REQUEST",INVALID_REPO_NAME:"BAD_REQUEST",INVALID_TTL:"BAD_REQUEST",INVALID_URL:"BAD_REQUEST",MEMORY_LIMIT:"INTERNAL",NOT_FOUND:"NOT_FOUND",REMOTE_AUTH_REQUIRED:"FORBIDDEN",UPSTREAM_UNAVAILABLE:"INTERNAL"},y=n=>{if(typeof n!="object"||n===null)return;const{code:e,name:t,numericCode:a}=n;if(typeof e!="string")return;const r=Object.hasOwn(s,e)?s[e]:void 0;if(!(r===void 0&&t!=="ArtifactsError"))return{data:typeof a=="number"?{code:e,numericCode:a}:{code:e},lunoraCode:r??"INTERNAL"}},E=(n,e)=>{const t=y(e);if(t===void 0)return e;const{data:a,lunoraCode:r}=t;return new c(r,`@lunora/bindings/artifacts: ${n} failed (${a.code})`,{cause:e,data:a})},o=async(n,e)=>{try{return await e()}catch(t){throw E(n,t)}},R=n=>{typeof Symbol.dispose=="symbol"&&n[Symbol.dispose]?.()},T=n=>({createToken:async(e,t)=>o("createToken",async()=>n.createToken(e,t)),fork:async(e,t)=>o("fork",async()=>n.fork(e,t)),info:async()=>o("info",async()=>n.info()),listTokens:async()=>o("listTokens",async()=>n.listTokens()),log:async e=>o("log",async()=>n.log(e)),readBlob:async e=>o("readBlob",async()=>n.readBlob(e)),readCommit:async e=>o("readCommit",async()=>n.readCommit(e)),readFile:async e=>o("readFile",async()=>n.readFile(e)),readTree:async e=>o("readTree",async()=>n.readTree(e)),revokeToken:async e=>o("revokeToken",async()=>n.revokeToken(e))}),d=n=>async(e,t)=>{const a=await o("get",async()=>n.get(e));try{return await t(T(a))}finally{R(a)}},I=n=>{const{binding:e}=n,t=d(e);return{authenticatedRemote:i,create:async(a,r)=>o("create",async()=>e.create(a,r)),delete:async a=>o("delete",async()=>e.delete(a)),import:async a=>o("import",async()=>e.import(a)),info:async a=>t(a,async r=>r.info()),list:async a=>o("list",async()=>e.list(a)),withRepo:t}};export{I as createArtifacts};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{LunoraError as x}from"@lunora/errors";import{c as b,U as g}from"./concurrent-vRmSvRpF.mjs";const B=(t,a)=>{if(!a.includes("."))return t[a];let s=t;for(const e of a.split(".")){if(s===null||typeof s!="object"||Array.isArray(s))return;s=s[e]}return s},T=(t,a)=>{const s=a?.namespace,e=new Set(a?.shardedIndexNames),n=(c,l)=>{if(l!==void 0)return l;if(e.has(c)){if(s!==void 0)return s;throw new Error(`@lunora/bindings/vectors: index "${c}" belongs to a sharded table, but this DO instance has no shard key (it is the root/default DO) and no explicit namespace was given. A namespace-less operation here would reach every tenant's vectors — Vectorize indexes are account-global. Pass an explicit namespace, or issue this call from the sharded DO instance that owns the tenant.`)}},i=a?.deferAfterCommit,d=async(c,l,u)=>{await t.upsert(c,{embed:l.embed,id:l.id,input:l.input,metadata:l.metadata,namespace:u})},f=async(c,l)=>{await d(c,l,n(c,l.namespace))},o=i===void 0?f:async(c,l)=>{const u=n(c,l.namespace);await i(async()=>d(c,l,u))},r=async(c,l,u)=>{const m=await t.getByIds(c,l);return u===void 0?m:m.filter(h=>h.namespace===u)};return{deleteByIds:async(c,l,u)=>{const m=n(c,u);if(m===void 0){await t.deleteByIds(c,l);return}const h=await r(c,l,m);h.length!==0&&await t.deleteByIds(c,h.map(p=>p.id))},getByIds:async(c,l,u)=>{const m=n(c,u);return(await r(c,l,m)).map(p=>({id:p.id,metadata:p.metadata,namespace:p.namespace,values:[...p.values]}))},query:async(c,l)=>{const u=await t.query(c,{embed:l.embed,filter:l.filter,input:l.input,namespace:n(c,l.namespace),returnMetadata:l.returnMetadata??"indexed",topK:l.topK,vector:l.vector});return{count:u.count,matches:u.matches.map(m=>({id:m.id,metadata:m.metadata,score:m.score}))}},upsert:o,upsertNow:f}},w=new Set,I=t=>{w.has(t)||(w.add(t),console.warn(`[@lunora/bindings/vectors] index "${t}" syncs vectors without a namespace — in a
|
|
2
|
+
multi-tenant/sharded app this exposes one tenant's vectors (and any captured
|
|
3
|
+
metadata) to every other tenant, since Vectorize indexes are account-global.
|
|
4
|
+
Pass \`namespace\` (the shard/tenant key) on both write and query — query-side
|
|
5
|
+
namespace filtering is mandatory for multi-tenant apps. Single-tenant apps that
|
|
6
|
+
legitimately have no tenant key suppress this via { allowSharedNamespace: true }.`))},A=(t,a)=>{const s={};for(const e of a)e in t&&(s[e]=t[e]);return s},v=(t,a)=>{a.input.trim()===""?t.deletes.push(a.name):t.upserts.push(a)},C=(t,a,s)=>{const e=B(t,a.field);if(e!=null){if(typeof e!="string")throw new TypeError(`@lunora/bindings/vectors: inline index "${a.name}" expects a string source at "${a.field}" on table "${s}" (got ${typeof e}); use a standalone defineVectorIndex with a select() to derive text from non-string columns`);return e}},k=(t,a)=>{const s=t.tables[a.table],e=s?.vectorIndexes??[],n=Object.entries(t.vectorIndexes).filter(([,r])=>r.table===a.table);if(e.length===0&&n.length===0)return;const i=s?.softDeleteMode?.field,d=i!==void 0&&a.doc?.[i]!==void 0&&a.doc[i]!==null;if(a.op==="delete"||d)return{deletes:[...e.map(r=>r.name),...n.map(([r])=>r)],upserts:[]};const f=a.doc;if(!f)return;const o={deletes:[],upserts:[]};for(const r of e){const c=C(f,r,a.table);c===void 0?o.deletes.push(r.name):v(o,{embed:r.embed,input:c,metadata:r.metadata?A(f,r.metadata):void 0,name:r.name})}for(const[r,c]of n)v(o,{embed:c.embed,input:c.select(f),metadata:c.metadata?.(f),name:r});return o},j=t=>{const{allowSharedNamespace:a,namespace:s,schema:e,vectors:n}=t;return async i=>{const d=k(e,i);if(!d)return;const f=[...d.deletes.map(o=>async()=>{await n.deleteByIds(o,[i.id])}),...d.upserts.map(o=>async()=>{!a&&s===void 0&&I(o.name),await n.upsertNow(o.name,{embed:o.embed,id:i.id,input:o.input,metadata:o.metadata,namespace:s})})];await b(f,g,async o=>o())}},S=1e3,E=(t,a)=>{const s=[];for(let e=0;e<t.length;e+=a)s.push(t.slice(e,e+a));return s},y=t=>{if(typeof t!="object"||t===null)return"unknown";const{name:a,status:s,statusCode:e}=t,n=typeof s=="number"?s:e;if(typeof n=="number"){if(n>=500||n===401||n===403||n===408||n===429)return"service";if(n>=400)return"row"}return a==="TimeoutError"||a==="AbortError"?"service":t instanceof TypeError||t instanceof RangeError?"row":"unknown"},M=async(t,a)=>{const s=await b(t,g,async d=>{try{return{item:d,ok:!0,value:await a(d)}}catch(f){return{error:f,item:d,ok:!1}}}),e=s.flatMap(d=>d.ok?[{item:d.item,value:d.value}]:[]),n=s.flatMap(d=>d.ok?[]:[{error:d.error,item:d.item}]),i=n.find(({error:d})=>y(d)==="service");if(i)throw i.error;if(t.length>=2&&e.length===0&&n.some(({error:d})=>y(d)!=="row"))throw n[0]?.error;return{failed:n,ok:e}},D=(t,a,s,e)=>{const n=new Map,i=[];for(const{doc:d,id:f}of s){let o;try{o=k(t,{doc:d,id:f,op:"update",table:a})}catch(r){e.set(f,r);continue}for(const r of o?.deletes??[])n.set(r,[...n.get(r)??[],f]);for(const r of o?.upserts??[])i.push({id:f,upsert:r})}return{deletes:n,pending:i}},O=async(t,a,s,e)=>{const{allowSharedNamespace:n,namespace:i,upsertMany:d,vectors:f}=t;!n&&i===void 0&&I(a);const o=s.map(({id:r,upsert:c,values:l})=>({embed:()=>l,id:r,input:c.input,metadata:c.metadata,namespace:i}));for(const r of E(o,S))try{await d(a,r)}catch{const c=await M(r,async l=>f.upsertNow(a,l));for(const{error:l,item:u}of c.failed)e.set(u.id,l)}},V=async(t,a,s)=>{const e=new Map,{deletes:n,pending:i}=D(t.schema,a,s,e),d=await M(i,async({upsert:o})=>o.embed(o.input)),f=new Map;for(const{error:o,item:r}of d.failed)e.set(r.id,o);for(const{item:o,value:r}of d.ok)f.set(o.upsert.name,[...f.get(o.upsert.name)??[],{...o,values:r}]);for(const[o,r]of n)for(const c of E(r,S))await t.vectors.deleteByIds(o,c);for(const[o,r]of f)await O(t,o,r,e);return[...e].map(([o,r])=>({error:r,id:o}))},P=t=>async(a,s)=>{try{return await V(t,a,s)}catch(e){throw y(e)==="service"?new x("SERVICE_UNAVAILABLE",e instanceof Error?e.message:String(e),{cause:e}):e}},$=t=>{const a=new Map,s=(e,n,i)=>{const d=i===void 0?n:[...n,i];a.set(e,[...a.get(e)??[],JSON.stringify(d)])};for(const[e,n]of Object.entries(t.tables))for(const i of n.vectorIndexes??[])s(e,[i.name,i.field,i.dimensions,i.metric,i.metadata??[]],i.model);for(const[e,n]of Object.entries(t.vectorIndexes))s(n.table,[e,"(select)",n.dimensions,n.metric],n.model);return[...a].map(([e,n])=>{const i=t.tables[e]?.softDeleteMode?.field;return{profile:(i===void 0?n:[...n,JSON.stringify(["(softDelete)",i])]).toSorted((f,o)=>f.localeCompare(o)).join("|"),table:e}})};export{T as createContextVectors,P as createVectorBackfillSync,j as createVectorSyncHook,$ as vectorBackfillTargets};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as f}from"@lunora/errors";const m=new Set(["image/avif","image/gif","image/jpeg","image/png","image/webp"]),T=1e4,A="image/webp",O=e=>typeof e!="object"?!1:"body"in e&&!(e instanceof ArrayBuffer)&&!(e instanceof Uint8Array),r=e=>{if(e instanceof ReadableStream)return e;if(O(e)){if(e.body===null)throw new f("INTERNAL","@lunora/bindings/images: R2 object body is null (object missing or already consumed)");return e.body}if(e instanceof Blob)return e.stream();const n=e instanceof Uint8Array?e:new Uint8Array(e);return new ReadableStream({start(t){t.enqueue(n),t.close()}})},c=(e,n)=>{if(e===void 0)return{};const t=o=>{if(!Number.isFinite(o)||o<=0)throw new TypeError("@lunora/bindings/images: width/height must be a positive finite number");return Math.max(1,Math.min(Math.floor(o),n))};return{...e,...e.width===void 0?{}:{width:t(e.width)},...e.height===void 0?{}:{height:t(e.height)}}},v=e=>{const{image:n,transform:t,...o}=e;return{drawOptions:o,image:n,transform:t}},U=e=>{const n=e?.format??A;if(!m.has(n))throw new f("INTERNAL",`@lunora/bindings/images: unsupported output format "${n}" (allowed: ${[...m].join(", ")})`);return{...e,format:n}},p=e=>{const{binding:n}=e,t=e.maxDimension??T;return{info:async o=>n.info(r(o)),transform:async(o,d,g,b)=>{const u=c(d,t),l=U(g);let i=n.input(r(o)).transform(u);for(const h of b??[]){const{drawOptions:w,image:a,transform:s}=v(h),y=s===void 0?r(a):n.input(r(a)).transform(c(s,t));i=i.draw(y,w)}return i.output(l)}}};export{p as createImages};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as c}from"@lunora/errors";const d=512,T=1e3,v=1024,f=new TextEncoder,m=t=>f.encode(t).length,h=(t,e)=>{if(m(t)>d)throw new c("BAD_REQUEST",`@lunora/bindings/kv: ${e} exceeds ${String(d)}-byte limit`);if(t.includes("\0"))throw new c("BAD_REQUEST",`@lunora/bindings/kv: ${e} contains NUL byte`);for(const a of t.split("/"))if(a==="."||a==="..")throw new c("BAD_REQUEST",`@lunora/bindings/kv: ${e} contains a \`.\`/\`..\` path component`)},u=t=>{if(typeof t!="string"||t.length===0)throw new TypeError("@lunora/bindings/kv: key must be a non-empty string");h(t,"key")},g=t=>{t.length>0&&h(t,"prefix")},E=(t,e)=>{u(t),u(e);const o=`${t.endsWith("/")?t.slice(0,-1):t}/${e}`;if(m(o)>d)throw new c("BAD_REQUEST",`@lunora/bindings/kv: scoped key exceeds ${String(d)}-byte limit`);return o},b=t=>{if(t.expiration!==void 0&&t.expirationTtl!==void 0)throw new c("BAD_REQUEST","@lunora/bindings/kv: `expiration` and `expirationTtl` are mutually exclusive")},x=t=>{let e;try{e=JSON.stringify(t)}catch{throw new c("BAD_REQUEST","@lunora/bindings/kv: metadata is not JSON-serializable (cyclic value, bigint, or similar)")}if(m(e)>v)throw new c("BAD_REQUEST",`@lunora/bindings/kv: metadata exceeds ${String(v)}-byte limit`)},p=t=>{const e={};return b(t),t.expiration!==void 0&&(e.expiration=t.expiration),t.expirationTtl!==void 0&&(e.expirationTtl=t.expirationTtl),t.metadata!==void 0&&(x(t.metadata),e.metadata=t.metadata),Object.keys(e).length>0?e:void 0},D=t=>{if(!t.namespace)throw new TypeError("@lunora/bindings/kv: `namespace` is required");const{keyPrefix:e,namespace:a}=t;e!==void 0&&u(e);const o=i=>e===void 0?(u(i),i):E(e,i),y=i=>{if(e===void 0)return i;const n=e.endsWith("/")?e:`${e}/`;return i.startsWith(n)?i.slice(n.length):i};return{delete:async i=>{await a.delete(o(i))},get:async(i,n={})=>await a.get(o(i),{cacheTtl:n.cacheTtl,type:"json"})??null,getRaw:async(i,n={})=>await a.get(o(i),{cacheTtl:n.cacheTtl,type:n.type??"text"})??null,getWithMetadata:async(i,n={})=>{const r=await a.getWithMetadata(o(i),{cacheTtl:n.cacheTtl,type:"json"});return{metadata:r.metadata??null,value:r.value??null}},list:async(i={})=>{if(i.limit!==void 0&&(!Number.isInteger(i.limit)||i.limit<=0))throw new TypeError("@lunora/bindings/kv: `limit` must be a positive integer");let{prefix:n}=i;if(n!==void 0&&g(n),e!==void 0){const l=e.endsWith("/")?e:`${e}/`;n=i.prefix===void 0?l:`${l}${i.prefix}`,g(n)}const r=i.limit===void 0?void 0:Math.min(i.limit,T),s=await a.list({cursor:i.cursor,limit:r,prefix:n}),w=s.keys.map(l=>({...l,name:y(l.name)}));return{cursor:s.list_complete?void 0:s.cursor,keys:w,listComplete:s.list_complete}},put:async(i,n,r={})=>{const s=r.raw?n:JSON.stringify(n);await a.put(o(i),s,p(r))}}};export{x as assertMetadataWithinLimit,b as assertOneExpirationForm,D as createKv,E as scopeKey,u as validateKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertOneExpirationForm as m,validateKey as i,assertMetadataWithinLimit as u}from"./createKv-mAHanD5g.mjs";import{LunoraError as d}from"@lunora/errors";const f=t=>{const{namespaces:a}=t,s=e=>{const r=a[e];if(!Object.hasOwn(a,e)||r===void 0)throw new d("BAD_REQUEST",`@lunora/bindings/kv: no namespace registered under binding "${e}"`);return r};return{deleteKey:async e=>{const r=s(e.namespace);i(e.key),await r.delete(e.key)},getValue:async e=>{const r=s(e.namespace);i(e.key);const n=await r.getWithMetadata(e.key,"text");return{metadata:n.metadata??null,value:n.value??null}},listKeys:async e=>{const n=await s(e.namespace).list({cursor:e.cursor,limit:e.limit,prefix:e.prefix}),l=n.keys.map(o=>({expiration:o.expiration,metadata:o.metadata,name:o.name}));return{cursor:n.list_complete?void 0:n.cursor,keys:l,listComplete:n.list_complete}},listNamespaces:()=>Promise.resolve(Object.keys(a).map(e=>({binding:e}))),putValue:async e=>{const r=s(e.namespace);m(e),i(e.key),e.metadata!==void 0&&u(e.metadata),await r.put(e.key,e.value,{expiration:e.expiration,expirationTtl:e.expirationTtl,metadata:e.metadata})}}},y=t=>{if(typeof t!="object"||t===null)return!1;const a=t;return typeof a.getWithMetadata=="function"&&typeof a.list=="function"&&typeof a.put=="function"&&typeof a.delete=="function"},b=t=>{const a={};if(typeof t=="object"&&t!==null)for(const[s,c]of Object.entries(t))y(c)&&(a[s]=c);return f({namespaces:a})};export{f as createKvIntrospector,b as createKvIntrospectorFromEnv};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i=a=>{const{binding:e}=a;return{send:async n=>{await e.send(Array.isArray(n)?n:[n])}}};export{i as createPipelines};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as a}from"@lunora/errors";const u=50,m=10,p=b=>{const{embedders:t,indexes:s,registry:g}=b,i=async()=>Promise.all(g.map(async e=>{const n=s[e.name];if(n?.describe===void 0)return{...e};try{const r=await n.describe();return{...e,dimensions:e.dimensions??r.dimensions,processedUpToMutation:r.processedUpToMutation===void 0?void 0:String(r.processedUpToMutation),vectorsCount:r.vectorCount??r.vectorsCount}}catch{return{...e}}}));return t!==void 0&&Object.keys(t).length>0?{listIndexes:i,queryIndex:async({name:e,text:n,topK:r})=>{const d=s[e];if(!Object.hasOwn(s,e)||d===void 0)throw new a("INTERNAL",`@lunora/bindings/vectors: no Vectorize binding registered for index "${e}"`);const c=t[e];if(!Object.hasOwn(t,e)||c===void 0)throw new a("INTERNAL",`@lunora/bindings/vectors: no embedder registered for index "${e}" — it lists read-only`);if(r!==void 0&&(!Number.isInteger(r)||r<1||r>u))throw new RangeError(`@lunora/bindings/vectors: topK must be an integer in [1, ${String(u)}] (got ${String(r)})`);const l=await c(n);return{matches:(await d.query(l,{returnMetadata:"all",topK:r??m})).matches.map(o=>({id:o.id,metadata:o.metadata,score:o.score}))}}}:{listIndexes:i}};export{p as createVectorAdminIntrospector};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as b}from"@lunora/errors";import{c as w,U as h}from"./concurrent-vRmSvRpF.mjs";const a=(t,o)=>{const d=t[o];if(!Object.hasOwn(t,o)||d===void 0)throw new b("INTERNAL",`@lunora/bindings/vectors: no index registered for "${o}". Known indexes: ${Object.keys(t).join(", ")||"(none)"}`);return d},g=async t=>{const o=await t.embed(t.input);return{id:t.id,metadata:t.metadata,namespace:t.namespace,values:o}},m=100,u=50,c=1e3,y=1e3,K=t=>{if(Object.keys(t.indexes).length===0)throw new TypeError("@lunora/bindings/vectors: at least one index binding is required");return{deleteByIds:async(n,e)=>{const r=a(t.indexes,n);if(e.length>c)throw new RangeError(`@lunora/bindings/vectors: deleteByIds accepts at most ${String(c)} ids (got ${String(e.length)})`);return r.deleteByIds(e)},describe:async n=>{const e=a(t.indexes,n);if(!e.describe)throw new b("INTERNAL",`@lunora/bindings/vectors: binding for "${n}" does not implement describe()`);const r=await e.describe(),s=r.vectorCount??r.vectorsCount;return{...r,vectorCount:s,vectorsCount:s}},getByIds:async(n,e)=>{const r=a(t.indexes,n);if(e.length>c)throw new RangeError(`@lunora/bindings/vectors: getByIds accepts at most ${String(c)} ids (got ${String(e.length)})`);return r.getByIds(e)},query:async(n,e)=>{const r=a(t.indexes,n),s=e.returnValues===!0||e.returnMetadata==="all",l=s?u:m;if(e.topK!==void 0&&(!Number.isInteger(e.topK)||e.topK<1||e.topK>l)){const v=s?` (lowered to ${String(u)} because returnValues/returnMetadata:"all" is set)`:"";throw new RangeError(`@lunora/bindings/vectors: topK must be an integer in [1, ${String(l)}]${v} (got ${String(e.topK)})`)}let i;if(e.vector&&e.vector.length>0)i=e.vector;else{if(!e.embed||e.input===void 0)throw new TypeError("@lunora/bindings/vectors: query requires either `vector` or both `input` and `embed`");i=await e.embed(e.input)}return r.query(i,{filter:e.filter,namespace:e.namespace,returnMetadata:e.returnMetadata,returnValues:e.returnValues,topK:e.topK})},upsert:async(n,e)=>{const r=a(t.indexes,n),s=await g(e);return r.upsert([s])},upsertMany:async(n,e)=>{const r=a(t.indexes,n);if(e.length>y)throw new RangeError(`@lunora/bindings/vectors: upsertMany batch exceeds ${String(y)} (got ${String(e.length)}) — split across calls`);const s=await w(e,h,g);return r.upsert(s)}}};export{K as default};
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/** One Pipelines record — a JSON object matching the stream's schema. */
|
|
9
9
|
type PipelineRecord = Record<string, unknown>;
|
|
10
10
|
/**
|
|
11
|
-
* Minimal structural projection of workers-types' `Pipeline
|
|
11
|
+
* Minimal structural projection of workers-types' `Pipeline<T>` binding. The
|
|
12
12
|
* real binding's `send` takes an array of records and resolves once accepted.
|
|
13
13
|
*/
|
|
14
14
|
interface PipelineBindingLike<T extends PipelineRecord = PipelineRecord> {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/** One Pipelines record — a JSON object matching the stream's schema. */
|
|
9
9
|
type PipelineRecord = Record<string, unknown>;
|
|
10
10
|
/**
|
|
11
|
-
* Minimal structural projection of workers-types' `Pipeline
|
|
11
|
+
* Minimal structural projection of workers-types' `Pipeline<T>` binding. The
|
|
12
12
|
* real binding's `send` takes an array of records and resolves once accepted.
|
|
13
13
|
*/
|
|
14
14
|
interface PipelineBindingLike<T extends PipelineRecord = PipelineRecord> {
|
package/dist/pipelines/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{createPipelines as i}from"../packem_shared/createPipelines-CIvqrc7E.mjs";export{i as createPipelines};
|