@relkit/cloudflare 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/cloudflare.d.ts +40 -0
- package/dist/cloudflare.d.ts.map +1 -0
- package/dist/cloudflare.js +97 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/index.d.ts +25 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +50 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/kv.d.ts +14 -0
- package/dist/runtime/kv.d.ts.map +1 -0
- package/dist/runtime/kv.js +103 -0
- package/dist/runtime/kv.js.map +1 -0
- package/dist/runtime/r2-signing.d.ts +11 -0
- package/dist/runtime/r2-signing.d.ts.map +1 -0
- package/dist/runtime/r2-signing.js +105 -0
- package/dist/runtime/r2-signing.js.map +1 -0
- package/dist/runtime/r2.d.ts +10 -0
- package/dist/runtime/r2.d.ts.map +1 -0
- package/dist/runtime/r2.js +86 -0
- package/dist/runtime/r2.js.map +1 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rel-kit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type BindingValueRef, type ProviderAdapter, type ProviderBehavior, type ProviderConnectionValues } from "@relkit/provider";
|
|
2
|
+
declare const cache: import("@relkit/provider").ProviderCapability<"cache">;
|
|
3
|
+
declare const bucket: import("@relkit/provider").ProviderCapability<"bucket">;
|
|
4
|
+
type TextReference = BindingValueRef<string, string, "string">;
|
|
5
|
+
type SecretReference = BindingValueRef<string, string, "secret-string">;
|
|
6
|
+
type TextValue = string | TextReference;
|
|
7
|
+
export interface CloudflareKvOptions {
|
|
8
|
+
readonly accountId: TextValue;
|
|
9
|
+
readonly namespaceId: TextValue;
|
|
10
|
+
readonly apiToken: SecretReference;
|
|
11
|
+
}
|
|
12
|
+
export interface CloudflareR2Options {
|
|
13
|
+
readonly accountId: TextValue;
|
|
14
|
+
readonly bucketName: TextValue;
|
|
15
|
+
readonly credentials: Readonly<{
|
|
16
|
+
accessKeyId: SecretReference;
|
|
17
|
+
secretAccessKey: SecretReference;
|
|
18
|
+
}>;
|
|
19
|
+
readonly signedUrlTtlSeconds?: number;
|
|
20
|
+
}
|
|
21
|
+
export type CloudflareKvAdapter = ProviderAdapter<typeof cache, "cloudflare-kv", ProviderConnectionValues, ProviderBehavior<Readonly<{
|
|
22
|
+
minimumTtlMs: 60_000;
|
|
23
|
+
}>>>;
|
|
24
|
+
export type CloudflareR2Adapter = ProviderAdapter<typeof bucket, "cloudflare-r2", ProviderConnectionValues, ProviderBehavior<Readonly<{
|
|
25
|
+
signedUrlTtlSeconds: number;
|
|
26
|
+
}>>>;
|
|
27
|
+
/**
|
|
28
|
+
* Defines a connected Cloudflare Workers KV cache.
|
|
29
|
+
* @category Integrations
|
|
30
|
+
* @since 0.2.0
|
|
31
|
+
*/
|
|
32
|
+
export declare function kv(options: CloudflareKvOptions): CloudflareKvAdapter;
|
|
33
|
+
/**
|
|
34
|
+
* Defines a connected Cloudflare R2 bucket through its S3-compatible API.
|
|
35
|
+
* @category Integrations
|
|
36
|
+
* @since 0.2.0
|
|
37
|
+
*/
|
|
38
|
+
export declare function r2(options: CloudflareR2Options): CloudflareR2Adapter;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAC;AAE1B,QAAA,MAAM,KAAK,wDAAoC,CAAC;AAChD,QAAA,MAAM,MAAM,yDAAqC,CAAC;AAgBlD,KAAK,aAAa,GAAG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC/D,KAAK,eAAe,GAAG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;AACxE,KAAK,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC;QAC7B,WAAW,EAAE,eAAe,CAAC;QAC7B,eAAe,EAAE,eAAe,CAAC;KAClC,CAAC,CAAC;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAC/C,OAAO,KAAK,EACZ,eAAe,EACf,wBAAwB,EACxB,gBAAgB,CAAC,QAAQ,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CACrD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAC/C,OAAO,MAAM,EACb,eAAe,EACf,wBAAwB,EACxB,gBAAgB,CAAC,QAAQ,CAAC;IAAE,mBAAmB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAC5D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CAkBpE;AAED;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CA8BpE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { defineConnectionContract, defineIntegrationReference, defineProviderAdapter, defineProviderBehavior, defineProviderCapability, defineProviderFeature, isBindingValueRef, } from "@relkit/provider";
|
|
2
|
+
const cache = defineProviderCapability("cache");
|
|
3
|
+
const bucket = defineProviderCapability("bucket");
|
|
4
|
+
const integration = defineIntegrationReference("cloudflare");
|
|
5
|
+
const signedReadUrl = defineProviderFeature(bucket, "signedReadUrl");
|
|
6
|
+
const signedWriteUrl = defineProviderFeature(bucket, "signedWriteUrl");
|
|
7
|
+
const kvContract = defineConnectionContract({
|
|
8
|
+
accountId: {},
|
|
9
|
+
namespaceId: {},
|
|
10
|
+
apiToken: { sensitive: true },
|
|
11
|
+
});
|
|
12
|
+
const r2Contract = defineConnectionContract({
|
|
13
|
+
accountId: {},
|
|
14
|
+
bucketName: {},
|
|
15
|
+
accessKeyId: { sensitive: true },
|
|
16
|
+
secretAccessKey: { sensitive: true },
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Defines a connected Cloudflare Workers KV cache.
|
|
20
|
+
* @category Integrations
|
|
21
|
+
* @since 0.2.0
|
|
22
|
+
*/
|
|
23
|
+
export function kv(options) {
|
|
24
|
+
assertRecord(options, "Cloudflare KV options");
|
|
25
|
+
assertKeys(options, ["accountId", "namespaceId", "apiToken"], "Cloudflare KV option");
|
|
26
|
+
textValue(options.accountId, "Cloudflare KV accountId");
|
|
27
|
+
textValue(options.namespaceId, "Cloudflare KV namespaceId");
|
|
28
|
+
secret(options.apiToken, "Cloudflare KV apiToken");
|
|
29
|
+
return defineProviderAdapter({
|
|
30
|
+
integration,
|
|
31
|
+
capability: cache,
|
|
32
|
+
adapterId: "cloudflare-kv",
|
|
33
|
+
connectionContract: kvContract,
|
|
34
|
+
connection: {
|
|
35
|
+
accountId: options.accountId,
|
|
36
|
+
namespaceId: options.namespaceId,
|
|
37
|
+
apiToken: options.apiToken,
|
|
38
|
+
},
|
|
39
|
+
behavior: defineProviderBehavior({ minimumTtlMs: 60_000 }),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Defines a connected Cloudflare R2 bucket through its S3-compatible API.
|
|
44
|
+
* @category Integrations
|
|
45
|
+
* @since 0.2.0
|
|
46
|
+
*/
|
|
47
|
+
export function r2(options) {
|
|
48
|
+
assertRecord(options, "Cloudflare R2 options");
|
|
49
|
+
assertKeys(options, ["accountId", "bucketName", "credentials", "signedUrlTtlSeconds"], "Cloudflare R2 option");
|
|
50
|
+
textValue(options.accountId, "Cloudflare R2 accountId");
|
|
51
|
+
textValue(options.bucketName, "Cloudflare R2 bucketName");
|
|
52
|
+
assertRecord(options.credentials, "Cloudflare R2 credentials");
|
|
53
|
+
assertKeys(options.credentials, ["accessKeyId", "secretAccessKey"], "Cloudflare R2 credential");
|
|
54
|
+
secret(options.credentials.accessKeyId, "Cloudflare R2 credentials.accessKeyId");
|
|
55
|
+
secret(options.credentials.secretAccessKey, "Cloudflare R2 credentials.secretAccessKey");
|
|
56
|
+
const ttl = options.signedUrlTtlSeconds ?? 900;
|
|
57
|
+
if (!Number.isSafeInteger(ttl) || ttl < 1 || ttl > 604_800)
|
|
58
|
+
throw new RangeError("Cloudflare R2 signedUrlTtlSeconds must be between 1 and 604800");
|
|
59
|
+
return defineProviderAdapter({
|
|
60
|
+
integration,
|
|
61
|
+
capability: bucket,
|
|
62
|
+
adapterId: "cloudflare-r2",
|
|
63
|
+
connectionContract: r2Contract,
|
|
64
|
+
connection: {
|
|
65
|
+
accountId: options.accountId,
|
|
66
|
+
bucketName: options.bucketName,
|
|
67
|
+
accessKeyId: options.credentials.accessKeyId,
|
|
68
|
+
secretAccessKey: options.credentials.secretAccessKey,
|
|
69
|
+
},
|
|
70
|
+
behavior: defineProviderBehavior({ signedUrlTtlSeconds: ttl }),
|
|
71
|
+
features: [signedReadUrl, signedWriteUrl],
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function textValue(value, label) {
|
|
75
|
+
if (isBindingValueRef(value)) {
|
|
76
|
+
if (value.type !== "string" || value.sensitive)
|
|
77
|
+
throw new TypeError(`${label} must be text or a named text binding value`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
81
|
+
throw new TypeError(`${label} must be non-empty text`);
|
|
82
|
+
}
|
|
83
|
+
function secret(value, label) {
|
|
84
|
+
if (!isBindingValueRef(value) || value.type !== "secret-string" || !value.sensitive)
|
|
85
|
+
throw new TypeError(`${label} must be a named secret binding value`);
|
|
86
|
+
}
|
|
87
|
+
function assertRecord(value, label) {
|
|
88
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
89
|
+
throw new TypeError(`${label} must be an object`);
|
|
90
|
+
}
|
|
91
|
+
function assertKeys(value, allowed, label) {
|
|
92
|
+
const keys = new Set(allowed);
|
|
93
|
+
for (const key of Object.keys(value))
|
|
94
|
+
if (!keys.has(key))
|
|
95
|
+
throw new TypeError(`Unknown ${label} "${key}"`);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=cloudflare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RuntimeProviderContext } from "@relkit/provider";
|
|
2
|
+
export * from "./kv.js";
|
|
3
|
+
export * from "./r2.js";
|
|
4
|
+
export declare const runtimeIntegration: Readonly<{
|
|
5
|
+
kind: "runtime-integration";
|
|
6
|
+
integrationId: "cloudflare";
|
|
7
|
+
registrations: readonly ({
|
|
8
|
+
capability: string;
|
|
9
|
+
adapterId: string;
|
|
10
|
+
protocolVersion: number;
|
|
11
|
+
create: ({ connection, behavior }: RuntimeProviderContext) => {
|
|
12
|
+
value: import("@relkit/buckets").BucketProvider;
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
capability: string;
|
|
16
|
+
adapterId: string;
|
|
17
|
+
protocolVersion: number;
|
|
18
|
+
create: ({ profile, connection }: RuntimeProviderContext) => {
|
|
19
|
+
value: import("./kv.js").CloudflareKvCacheProvider;
|
|
20
|
+
ready: () => Promise<void>;
|
|
21
|
+
release: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
})[];
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAA8B,MAAM,kBAAkB,CAAC;AAI3F,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;2CAQU,sBAAsB;;;;;;;0CAevB,sBAAsB;;;;;;EAWT,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createCloudflareKvCacheProvider } from "./kv.js";
|
|
2
|
+
import { createCloudflareR2BucketProvider } from "./r2.js";
|
|
3
|
+
export * from "./kv.js";
|
|
4
|
+
export * from "./r2.js";
|
|
5
|
+
export const runtimeIntegration = Object.freeze({
|
|
6
|
+
kind: "runtime-integration",
|
|
7
|
+
integrationId: "cloudflare",
|
|
8
|
+
registrations: Object.freeze([
|
|
9
|
+
{
|
|
10
|
+
capability: "bucket",
|
|
11
|
+
adapterId: "cloudflare-r2",
|
|
12
|
+
protocolVersion: 1,
|
|
13
|
+
create: ({ connection, behavior }) => ({
|
|
14
|
+
value: createCloudflareR2BucketProvider({
|
|
15
|
+
accountId: text(connection.accountId, "Cloudflare R2 accountId"),
|
|
16
|
+
bucketName: text(connection.bucketName, "Cloudflare R2 bucketName"),
|
|
17
|
+
accessKeyId: text(connection.accessKeyId, "Cloudflare R2 accessKeyId"),
|
|
18
|
+
secretAccessKey: text(connection.secretAccessKey, "Cloudflare R2 secretAccessKey"),
|
|
19
|
+
signedUrlTtlSeconds: record(behavior, "Cloudflare R2 behavior")
|
|
20
|
+
.signedUrlTtlSeconds,
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
capability: "cache",
|
|
26
|
+
adapterId: "cloudflare-kv",
|
|
27
|
+
protocolVersion: 1,
|
|
28
|
+
create: ({ profile, connection }) => {
|
|
29
|
+
const provider = createCloudflareKvCacheProvider({
|
|
30
|
+
accountId: text(connection.accountId, "Cloudflare KV accountId"),
|
|
31
|
+
namespaceId: text(connection.namespaceId, "Cloudflare KV namespaceId"),
|
|
32
|
+
apiToken: text(connection.apiToken, "Cloudflare KV apiToken"),
|
|
33
|
+
cacheId: profile,
|
|
34
|
+
});
|
|
35
|
+
return { value: provider, ready: provider.ready, release: provider.close };
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
]),
|
|
39
|
+
});
|
|
40
|
+
function text(value, label) {
|
|
41
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
42
|
+
throw new TypeError(`${label} is invalid`);
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
function record(value, label) {
|
|
46
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
47
|
+
throw new TypeError(`${label} is invalid`);
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;AAE3D,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,IAAI,EAAE,qBAAqB;IAC3B,aAAa,EAAE,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;QAC3B;YACE,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,eAAe;YAC1B,eAAe,EAAE,CAAC;YAClB,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAA0B,EAAE,EAAE,CAAC,CAAC;gBAC7D,KAAK,EAAE,gCAAgC,CAAC;oBACtC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,yBAAyB,CAAC;oBAChE,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,0BAA0B,CAAC;oBACnE,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,2BAA2B,CAAC;oBACtE,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,+BAA+B,CAAC;oBAClF,mBAAmB,EAAE,MAAM,CAAC,QAAQ,EAAE,wBAAwB,CAAC;yBAC5D,mBAA6B;iBACjC,CAAC;aACH,CAAC;SACH;QACD;YACE,UAAU,EAAE,OAAO;YACnB,SAAS,EAAE,eAAe;YAC1B,eAAe,EAAE,CAAC;YAClB,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAA0B,EAAE,EAAE;gBAC1D,MAAM,QAAQ,GAAG,+BAA+B,CAAC;oBAC/C,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,yBAAyB,CAAC;oBAChE,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,2BAA2B,CAAC;oBACtE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,wBAAwB,CAAC;oBAC7D,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;gBACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC7E,CAAC;SACF;KACF,CAAC;CACH,CAAoD,CAAC;AAEtD,SAAS,IAAI,CAAC,KAAc,EAAE,KAAa;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC;IACjG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa;IAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrE,MAAM,IAAI,SAAS,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC;IAC7C,OAAO,KAA0C,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CacheProvider } from "@relkit/cache";
|
|
2
|
+
export interface CloudflareKvCacheOptions {
|
|
3
|
+
readonly accountId: string;
|
|
4
|
+
readonly namespaceId: string;
|
|
5
|
+
readonly apiToken: string;
|
|
6
|
+
readonly cacheId: string;
|
|
7
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
8
|
+
}
|
|
9
|
+
export interface CloudflareKvCacheProvider extends CacheProvider {
|
|
10
|
+
readonly ready: () => Promise<void>;
|
|
11
|
+
readonly close: () => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createCloudflareKvCacheProvider(options: CloudflareKvCacheOptions): CloudflareKvCacheProvider;
|
|
14
|
+
//# sourceMappingURL=kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../../src/runtime/kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgD,aAAa,EAAE,MAAM,eAAe,CAAC;AAGjG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC1C;AAED,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,wBAAwB,GAChC,yBAAyB,CA0G3B"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { canonicalJson } from "@relkit/contracts";
|
|
2
|
+
export function createCloudflareKvCacheProvider(options) {
|
|
3
|
+
const accountId = required(options.accountId, "accountId");
|
|
4
|
+
const namespaceId = required(options.namespaceId, "namespaceId");
|
|
5
|
+
const token = required(options.apiToken, "apiToken");
|
|
6
|
+
const cacheId = required(options.cacheId, "cacheId");
|
|
7
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
8
|
+
const root = `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(accountId)}/storage/kv/namespaces/${encodeURIComponent(namespaceId)}`;
|
|
9
|
+
const flights = new Map();
|
|
10
|
+
let closed = false;
|
|
11
|
+
const encoded = (key) => {
|
|
12
|
+
const value = `${cacheId}:${canonicalJson(key)}`;
|
|
13
|
+
if (new TextEncoder().encode(value).byteLength > 512)
|
|
14
|
+
throw new RangeError("Cloudflare KV key exceeds 512 bytes");
|
|
15
|
+
return value;
|
|
16
|
+
};
|
|
17
|
+
const request = async (path, init = {}, context) => {
|
|
18
|
+
if (closed)
|
|
19
|
+
throw new Error("Cloudflare KV cache provider is closed");
|
|
20
|
+
if (context?.signal.aborted)
|
|
21
|
+
throw context.signal.reason ?? new Error("Cache operation cancelled");
|
|
22
|
+
const headers = new Headers(init.headers);
|
|
23
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
24
|
+
return fetcher(`${root}${path}`, {
|
|
25
|
+
...init,
|
|
26
|
+
headers,
|
|
27
|
+
...(context === undefined ? {} : { signal: context.signal }),
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const get = async (key, context) => {
|
|
31
|
+
const response = await request(`/values/${encodeURIComponent(encoded(key))}`, {}, context);
|
|
32
|
+
if (response.status === 404)
|
|
33
|
+
return undefined;
|
|
34
|
+
await assertResponse(response, "Cloudflare KV get");
|
|
35
|
+
return JSON.parse(await response.text());
|
|
36
|
+
};
|
|
37
|
+
const set = async (key, value, settings, context) => {
|
|
38
|
+
const url = new URL(`${root}/values/${encodeURIComponent(encoded(key))}`);
|
|
39
|
+
if (settings?.ttlMs !== undefined) {
|
|
40
|
+
if (settings.ttlMs < 60_000)
|
|
41
|
+
throw new RangeError("Cloudflare KV ttlMs must be at least 60000");
|
|
42
|
+
url.searchParams.set("expiration_ttl", String(Math.ceil(settings.ttlMs / 1_000)));
|
|
43
|
+
}
|
|
44
|
+
const response = await request(url.toString().slice(root.length), {
|
|
45
|
+
method: "PUT",
|
|
46
|
+
headers: { "content-type": "application/json" },
|
|
47
|
+
body: canonicalJson(value),
|
|
48
|
+
}, context);
|
|
49
|
+
await assertResponse(response, "Cloudflare KV set");
|
|
50
|
+
};
|
|
51
|
+
const remove = async (key, context) => {
|
|
52
|
+
const response = await request(`/values/${encodeURIComponent(encoded(key))}`, { method: "DELETE" }, context);
|
|
53
|
+
await assertResponse(response, "Cloudflare KV delete");
|
|
54
|
+
};
|
|
55
|
+
const getOrSet = async (key, produce, settings, context) => {
|
|
56
|
+
const cached = await get(key, context);
|
|
57
|
+
if (cached !== undefined)
|
|
58
|
+
return cached;
|
|
59
|
+
const cacheKey = encoded(key);
|
|
60
|
+
const active = flights.get(cacheKey);
|
|
61
|
+
if (active !== undefined)
|
|
62
|
+
return active;
|
|
63
|
+
const flight = Promise.resolve(produce()).then(async (value) => {
|
|
64
|
+
await set(key, value, settings, context);
|
|
65
|
+
return value;
|
|
66
|
+
});
|
|
67
|
+
flights.set(cacheKey, flight);
|
|
68
|
+
try {
|
|
69
|
+
return await flight;
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
if (flights.get(cacheKey) === flight)
|
|
73
|
+
flights.delete(cacheKey);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
capabilities: Object.freeze({ increment: false }),
|
|
78
|
+
get,
|
|
79
|
+
set,
|
|
80
|
+
delete: remove,
|
|
81
|
+
has: async (key, context) => (await get(key, context)) !== undefined,
|
|
82
|
+
getOrSet,
|
|
83
|
+
ready: async () => {
|
|
84
|
+
await assertResponse(await request(""), "Cloudflare KV readiness");
|
|
85
|
+
},
|
|
86
|
+
close: async () => {
|
|
87
|
+
closed = true;
|
|
88
|
+
flights.clear();
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function assertResponse(response, operation) {
|
|
93
|
+
if (response.ok)
|
|
94
|
+
return;
|
|
95
|
+
const text = (await response.text()).trim().replace(/\s+/g, " ").slice(0, 500);
|
|
96
|
+
throw new Error(`${operation} failed with status ${response.status}${text ? `: ${text}` : ""}`);
|
|
97
|
+
}
|
|
98
|
+
function required(value, name) {
|
|
99
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
100
|
+
throw new TypeError(`Cloudflare KV ${name} is invalid`);
|
|
101
|
+
return value.trim();
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.js","sourceRoot":"","sources":["../../src/runtime/kv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface R2Credentials {
|
|
2
|
+
readonly accessKeyId: string;
|
|
3
|
+
readonly secretAccessKey: string;
|
|
4
|
+
}
|
|
5
|
+
export type R2RequestInit = Omit<RequestInit, "body"> & {
|
|
6
|
+
readonly body?: string | Uint8Array | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function signedR2Request(url: string, credentials: R2Credentials, init?: R2RequestInit, fetcher?: typeof globalThis.fetch): Promise<Response>;
|
|
9
|
+
export declare function presignR2Url(url: string, method: "GET" | "PUT", credentials: R2Credentials, expiresSeconds: number): Promise<string>;
|
|
10
|
+
export declare function assertR2Response(response: Response, operation: string): Promise<Response>;
|
|
11
|
+
//# sourceMappingURL=r2-signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2-signing.d.ts","sourceRoot":"","sources":["../../src/runtime/r2-signing.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,aAAa,EAC1B,IAAI,GAAE,aAAkB,EACxB,OAAO,GAAE,OAAO,UAAU,CAAC,KAAwB,GAClD,OAAO,CAAC,QAAQ,CAAC,CAUnB;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,KAAK,GAAG,KAAK,EACrB,WAAW,EAAE,aAAa,EAC1B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAY/F"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export async function signedR2Request(url, credentials, init = {}, fetcher = globalThis.fetch) {
|
|
2
|
+
const headers = new Headers(init.headers);
|
|
3
|
+
const body = init.body ?? "";
|
|
4
|
+
await signHeaders(url, credentials, headers, body, init.method);
|
|
5
|
+
const { body: requestBody, ...request } = init;
|
|
6
|
+
return fetcher(url, {
|
|
7
|
+
...request,
|
|
8
|
+
...(requestBody === undefined ? {} : { body: requestBody }),
|
|
9
|
+
headers,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export async function presignR2Url(url, method, credentials, expiresSeconds) {
|
|
13
|
+
const amzDate = timestamp(new Date());
|
|
14
|
+
const date = amzDate.slice(0, 8);
|
|
15
|
+
const scope = `${date}/auto/s3/aws4_request`;
|
|
16
|
+
const parsed = new URL(url);
|
|
17
|
+
parsed.searchParams.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
|
|
18
|
+
parsed.searchParams.set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD");
|
|
19
|
+
parsed.searchParams.set("X-Amz-Credential", `${credentials.accessKeyId}/${scope}`);
|
|
20
|
+
parsed.searchParams.set("X-Amz-Date", amzDate);
|
|
21
|
+
parsed.searchParams.set("X-Amz-Expires", String(expiresSeconds));
|
|
22
|
+
parsed.searchParams.set("X-Amz-SignedHeaders", "host");
|
|
23
|
+
const canonical = [
|
|
24
|
+
method,
|
|
25
|
+
parsed.pathname || "/",
|
|
26
|
+
canonicalQuery(parsed.searchParams),
|
|
27
|
+
`host:${parsed.host}\n`,
|
|
28
|
+
"host",
|
|
29
|
+
"UNSIGNED-PAYLOAD",
|
|
30
|
+
].join("\n");
|
|
31
|
+
const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${scope}\n${await hash(canonical)}`;
|
|
32
|
+
const key = await deriveKey(credentials.secretAccessKey, date);
|
|
33
|
+
parsed.searchParams.set("X-Amz-Signature", hex(await hmac(key, stringToSign)));
|
|
34
|
+
return parsed.toString();
|
|
35
|
+
}
|
|
36
|
+
export async function assertR2Response(response, operation) {
|
|
37
|
+
if (response.ok)
|
|
38
|
+
return response;
|
|
39
|
+
const body = (await response.text()).trim();
|
|
40
|
+
const code = xmlValue(body, "Code");
|
|
41
|
+
const message = xmlValue(body, "Message");
|
|
42
|
+
const detail = (code || message ? [code, message].filter(Boolean).join(": ") : body).slice(0, 500);
|
|
43
|
+
throw new Error(`${operation} failed with status ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
44
|
+
}
|
|
45
|
+
async function signHeaders(url, credentials, headers, body, method = "GET") {
|
|
46
|
+
const amzDate = timestamp(new Date());
|
|
47
|
+
const date = amzDate.slice(0, 8);
|
|
48
|
+
const parsed = new URL(url);
|
|
49
|
+
const payloadHash = await hash(body);
|
|
50
|
+
headers.set("host", parsed.host);
|
|
51
|
+
headers.set("x-amz-date", amzDate);
|
|
52
|
+
headers.set("x-amz-content-sha256", payloadHash);
|
|
53
|
+
const canonicalHeaders = [...headers.entries()]
|
|
54
|
+
.map(([name, value]) => [name.toLowerCase(), value.trim().replace(/\s+/g, " ")])
|
|
55
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
56
|
+
const signedHeaders = canonicalHeaders.map(([name]) => name).join(";");
|
|
57
|
+
const canonical = [
|
|
58
|
+
method.toUpperCase(),
|
|
59
|
+
parsed.pathname || "/",
|
|
60
|
+
canonicalQuery(parsed.searchParams),
|
|
61
|
+
canonicalHeaders.map(([name, value]) => `${name}:${value}\n`).join(""),
|
|
62
|
+
signedHeaders,
|
|
63
|
+
payloadHash,
|
|
64
|
+
].join("\n");
|
|
65
|
+
const scope = `${date}/auto/s3/aws4_request`;
|
|
66
|
+
const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${scope}\n${await hash(canonical)}`;
|
|
67
|
+
const key = await deriveKey(credentials.secretAccessKey, date);
|
|
68
|
+
const signature = hex(await hmac(key, stringToSign));
|
|
69
|
+
headers.set("authorization", `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`);
|
|
70
|
+
}
|
|
71
|
+
function canonicalQuery(params) {
|
|
72
|
+
return [...params.entries()]
|
|
73
|
+
.map(([name, value]) => [encode(name), encode(value)])
|
|
74
|
+
.sort(([aName, aValue], [bName, bValue]) => aName.localeCompare(bName) || aValue.localeCompare(bValue))
|
|
75
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
76
|
+
.join("&");
|
|
77
|
+
}
|
|
78
|
+
function encode(value) {
|
|
79
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
80
|
+
}
|
|
81
|
+
function timestamp(value) {
|
|
82
|
+
return value.toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
83
|
+
}
|
|
84
|
+
async function deriveKey(secret, date) {
|
|
85
|
+
let value = await hmac(`AWS4${secret}`, date);
|
|
86
|
+
value = await hmac(value, "auto");
|
|
87
|
+
value = await hmac(value, "s3");
|
|
88
|
+
return hmac(value, "aws4_request");
|
|
89
|
+
}
|
|
90
|
+
async function hmac(keyValue, value) {
|
|
91
|
+
const bytes = typeof keyValue === "string" ? new TextEncoder().encode(keyValue) : keyValue;
|
|
92
|
+
const key = await crypto.subtle.importKey("raw", bytes, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
93
|
+
return crypto.subtle.sign("HMAC", key, new TextEncoder().encode(value));
|
|
94
|
+
}
|
|
95
|
+
async function hash(value) {
|
|
96
|
+
const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
|
|
97
|
+
return hex(await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes)));
|
|
98
|
+
}
|
|
99
|
+
function hex(value) {
|
|
100
|
+
return [...new Uint8Array(value)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
101
|
+
}
|
|
102
|
+
function xmlValue(xml, name) {
|
|
103
|
+
return new RegExp(`<${name}>([\\s\\S]*?)<\\/${name}>`).exec(xml)?.[1];
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=r2-signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2-signing.js","sourceRoot":"","sources":["../../src/runtime/r2-signing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BucketProvider } from "@relkit/buckets";
|
|
2
|
+
import { type R2Credentials } from "./r2-signing.js";
|
|
3
|
+
export interface CloudflareR2BucketOptions extends R2Credentials {
|
|
4
|
+
readonly accountId: string;
|
|
5
|
+
readonly bucketName: string;
|
|
6
|
+
readonly signedUrlTtlSeconds?: number;
|
|
7
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
8
|
+
}
|
|
9
|
+
export declare function createCloudflareR2BucketProvider(options: CloudflareR2BucketOptions): BucketProvider;
|
|
10
|
+
//# sourceMappingURL=r2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../src/runtime/r2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA0B,cAAc,EAAoB,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,yBAA0B,SAAQ,aAAa;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC1C;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,yBAAyB,GACjC,cAAc,CAiGhB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { assertR2Response, presignR2Url, signedR2Request, } from "./r2-signing.js";
|
|
2
|
+
export function createCloudflareR2BucketProvider(options) {
|
|
3
|
+
const accountId = required(options.accountId, "accountId");
|
|
4
|
+
const bucket = required(options.bucketName, "bucketName");
|
|
5
|
+
const credentials = {
|
|
6
|
+
accessKeyId: required(options.accessKeyId, "accessKeyId"),
|
|
7
|
+
secretAccessKey: required(options.secretAccessKey, "secretAccessKey"),
|
|
8
|
+
};
|
|
9
|
+
const expires = options.signedUrlTtlSeconds ?? 900;
|
|
10
|
+
if (!Number.isSafeInteger(expires) || expires < 1 || expires > 604_800)
|
|
11
|
+
throw new RangeError("Cloudflare R2 signedUrlTtlSeconds must be between 1 and 604800");
|
|
12
|
+
const root = `https://${accountId}.r2.cloudflarestorage.com/${encodeURIComponent(bucket)}`;
|
|
13
|
+
const url = (key = "") => `${root}${key === "" ? "/" : `/${keyPath(key)}`}`;
|
|
14
|
+
const request = (key, init, context) => signedR2Request(url(key), credentials, { ...init, ...(context === undefined ? {} : { signal: context.signal }) }, options.fetch);
|
|
15
|
+
return Object.freeze({
|
|
16
|
+
capabilities: Object.freeze({ signedReadUrl: true, signedWriteUrl: true }),
|
|
17
|
+
put: async (key, bytes, putOptions, context) => {
|
|
18
|
+
const headers = new Headers();
|
|
19
|
+
if (putOptions?.contentType !== undefined)
|
|
20
|
+
headers.set("content-type", putOptions.contentType);
|
|
21
|
+
for (const [name, value] of Object.entries(putOptions?.metadata ?? {}))
|
|
22
|
+
headers.set(`x-amz-meta-${name}`, value);
|
|
23
|
+
await assertR2Response(await request(key, { method: "PUT", headers, body: bytes }, context), "Cloudflare R2 put");
|
|
24
|
+
},
|
|
25
|
+
get: async (key, context) => {
|
|
26
|
+
const response = await request(key, { method: "GET" }, context);
|
|
27
|
+
if (response.status === 404)
|
|
28
|
+
return undefined;
|
|
29
|
+
await assertR2Response(response, "Cloudflare R2 get");
|
|
30
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
31
|
+
},
|
|
32
|
+
head: async (key, context) => {
|
|
33
|
+
const response = await request(key, { method: "HEAD" }, context);
|
|
34
|
+
if (response.status === 404)
|
|
35
|
+
return undefined;
|
|
36
|
+
await assertR2Response(response, "Cloudflare R2 head");
|
|
37
|
+
const metadata = {};
|
|
38
|
+
response.headers.forEach((value, name) => {
|
|
39
|
+
if (name.startsWith("x-amz-meta-"))
|
|
40
|
+
metadata[name.slice(11)] = value;
|
|
41
|
+
});
|
|
42
|
+
const size = Number(response.headers.get("content-length"));
|
|
43
|
+
return {
|
|
44
|
+
etag: response.headers.get("etag")?.replaceAll('"', "") ?? "",
|
|
45
|
+
...(response.headers.get("content-type") === null
|
|
46
|
+
? {}
|
|
47
|
+
: { contentType: response.headers.get("content-type") }),
|
|
48
|
+
...(Number.isFinite(size) ? { size } : {}),
|
|
49
|
+
metadata,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
delete: async (key, context) => {
|
|
53
|
+
await assertR2Response(await request(key, { method: "DELETE" }, context), "Cloudflare R2 delete");
|
|
54
|
+
},
|
|
55
|
+
exists: async (key, context) => {
|
|
56
|
+
const response = await request(key, { method: "HEAD" }, context);
|
|
57
|
+
if (response.status === 404)
|
|
58
|
+
return false;
|
|
59
|
+
await assertR2Response(response, "Cloudflare R2 exists");
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
list: async (prefix, context) => {
|
|
63
|
+
const listUrl = new URL(url());
|
|
64
|
+
listUrl.searchParams.set("list-type", "2");
|
|
65
|
+
if (prefix !== undefined)
|
|
66
|
+
listUrl.searchParams.set("prefix", prefix);
|
|
67
|
+
const response = await signedR2Request(listUrl.toString(), credentials, { method: "GET", ...(context === undefined ? {} : { signal: context.signal }) }, options.fetch);
|
|
68
|
+
await assertR2Response(response, "Cloudflare R2 list");
|
|
69
|
+
return Object.freeze([...(await response.text()).matchAll(/<Key>([^<]*)<\/Key>/g)].map((match) => decodeXml(match[1])));
|
|
70
|
+
},
|
|
71
|
+
createReadUrl: (key) => presignR2Url(url(key), "GET", credentials, expires),
|
|
72
|
+
createWriteUrl: (key) => presignR2Url(url(key), "PUT", credentials, expires),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function required(value, name) {
|
|
76
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
77
|
+
throw new TypeError(`Cloudflare R2 ${name} is invalid`);
|
|
78
|
+
return value.trim();
|
|
79
|
+
}
|
|
80
|
+
function keyPath(value) {
|
|
81
|
+
return value.split("/").map(encodeURIComponent).join("/");
|
|
82
|
+
}
|
|
83
|
+
function decodeXml(value) {
|
|
84
|
+
return value.replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=r2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../../src/runtime/r2.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@relkit/cloudflare",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Cloudflare integration for RELKIT.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/rel-kit/relkit.git",
|
|
9
|
+
"directory": "integrations/packages/cloudflare"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/rel-kit/relkit#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/rel-kit/relkit/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"bun": ">=1.3.10"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./runtime": {
|
|
31
|
+
"types": "./dist/runtime/index.d.ts",
|
|
32
|
+
"import": "./dist/runtime/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"relkit": {
|
|
36
|
+
"integration": {
|
|
37
|
+
"id": "cloudflare",
|
|
38
|
+
"exports": {
|
|
39
|
+
"authoring": ".",
|
|
40
|
+
"runtime": {
|
|
41
|
+
"export": "./runtime",
|
|
42
|
+
"registrations": [
|
|
43
|
+
{
|
|
44
|
+
"capability": "bucket",
|
|
45
|
+
"adapterId": "cloudflare-r2",
|
|
46
|
+
"protocolVersion": 1
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"capability": "cache",
|
|
50
|
+
"adapterId": "cloudflare-kv",
|
|
51
|
+
"protocolVersion": 1
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsc -b",
|
|
60
|
+
"check": "tsc -b --pretty false",
|
|
61
|
+
"typecheck": "tsc -b --pretty false"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@relkit/buckets": "0.3.0",
|
|
65
|
+
"@relkit/cache": "0.3.0",
|
|
66
|
+
"@relkit/contracts": "0.3.0",
|
|
67
|
+
"@relkit/provider": "0.3.0"
|
|
68
|
+
}
|
|
69
|
+
}
|