@relkit/providers-standard 0.0.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/factories.d.ts +3 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +97 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/redis-client.d.ts +20 -0
- package/dist/redis-client.d.ts.map +1 -0
- package/dist/redis-client.js +60 -0
- package/dist/redis-client.js.map +1 -0
- package/dist/redis.d.ts +30 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +123 -0
- package/dist/redis.js.map +1 -0
- package/dist/s3-url.d.ts +4 -0
- package/dist/s3-url.d.ts.map +1 -0
- package/dist/s3-url.js +29 -0
- package/dist/s3-url.js.map +1 -0
- package/dist/s3-xml.d.ts +4 -0
- package/dist/s3-xml.d.ts.map +1 -0
- package/dist/s3-xml.js +25 -0
- package/dist/s3-xml.js.map +1 -0
- package/dist/s3.d.ts +36 -0
- package/dist/s3.d.ts.map +1 -0
- package/dist/s3.js +139 -0
- package/dist/s3.js.map +1 -0
- package/dist/signing.d.ts +18 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +145 -0
- package/dist/signing.js.map +1 -0
- package/package.json +44 -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 @@
|
|
|
1
|
+
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../src/factories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAA2C,MAAM,gBAAgB,CAAC;AA8DjG,eAAO,MAAM,yBAAyB,EAAE,iBAItC,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createModelProviderRegistry } from "@relkit/agents";
|
|
2
|
+
import { createRedisCacheProvider } from "./redis.js";
|
|
3
|
+
import { createS3BucketProvider } from "./s3.js";
|
|
4
|
+
const s3Factory = Object.freeze({
|
|
5
|
+
capability: "buckets",
|
|
6
|
+
adapter: "s3",
|
|
7
|
+
create: (context) => {
|
|
8
|
+
const configuration = context.configuration;
|
|
9
|
+
const credentials = s3Credentials(record(configuration.credentials));
|
|
10
|
+
const provider = createS3BucketProvider({
|
|
11
|
+
endpoint: urlText(configuration.endpoint, "S3 endpoint"),
|
|
12
|
+
bucketName: text(configuration.bucketName, "S3 bucketName"),
|
|
13
|
+
region: text(configuration.region, "S3 region"),
|
|
14
|
+
...(credentials === undefined ? {} : { credentials }),
|
|
15
|
+
...(configuration.forcePathStyle === undefined
|
|
16
|
+
? {}
|
|
17
|
+
: { forcePathStyle: boolean(configuration.forcePathStyle, "S3 forcePathStyle") }),
|
|
18
|
+
...(configuration.signedUrlTtlSeconds === undefined
|
|
19
|
+
? {}
|
|
20
|
+
: {
|
|
21
|
+
signedUrlTtlSeconds: integer(configuration.signedUrlTtlSeconds, "S3 signedUrlTtlSeconds"),
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
return Object.freeze({ value: provider });
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const redisFactory = Object.freeze({
|
|
28
|
+
capability: "cache",
|
|
29
|
+
adapter: "redis",
|
|
30
|
+
create: (context) => {
|
|
31
|
+
const provider = createRedisCacheProvider({
|
|
32
|
+
url: text(context.configuration.url, "Redis URL"),
|
|
33
|
+
cacheId: context.profile,
|
|
34
|
+
...(context.configuration.connectionTimeoutMs === undefined
|
|
35
|
+
? {}
|
|
36
|
+
: {
|
|
37
|
+
connectionTimeoutMs: integer(context.configuration.connectionTimeoutMs, "Redis connectionTimeoutMs"),
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
return Object.freeze({ value: provider, ready: provider.ready, release: provider.close });
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const modelsFactory = Object.freeze({
|
|
44
|
+
capability: "models",
|
|
45
|
+
adapter: "ai-sdk",
|
|
46
|
+
create: async (context) => {
|
|
47
|
+
const modelRegistry = await createModelProviderRegistry({
|
|
48
|
+
configuration: context.configuration,
|
|
49
|
+
});
|
|
50
|
+
return Object.freeze({ modelRegistry });
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
export const standardProviderFactories = Object.freeze({
|
|
54
|
+
"buckets:s3": s3Factory,
|
|
55
|
+
"cache:redis": redisFactory,
|
|
56
|
+
"models:ai-sdk": modelsFactory,
|
|
57
|
+
});
|
|
58
|
+
function record(value) {
|
|
59
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
60
|
+
? value
|
|
61
|
+
: undefined;
|
|
62
|
+
}
|
|
63
|
+
function s3Credentials(value) {
|
|
64
|
+
if (value === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
const accessKeyId = optionalText(value.accessKeyId, "S3 accessKeyId");
|
|
67
|
+
const secretAccessKey = optionalText(value.secretAccessKey, "S3 secretAccessKey");
|
|
68
|
+
const sessionToken = optionalText(value.sessionToken, "S3 sessionToken");
|
|
69
|
+
if (accessKeyId === undefined && secretAccessKey === undefined && sessionToken === undefined)
|
|
70
|
+
return undefined;
|
|
71
|
+
if (accessKeyId === undefined || secretAccessKey === undefined) {
|
|
72
|
+
throw new TypeError("S3 credentials require both accessKeyId and secretAccessKey");
|
|
73
|
+
}
|
|
74
|
+
return { accessKeyId, secretAccessKey, ...(sessionToken === undefined ? {} : { sessionToken }) };
|
|
75
|
+
}
|
|
76
|
+
function optionalText(value, label) {
|
|
77
|
+
return value === undefined ? undefined : text(value, label);
|
|
78
|
+
}
|
|
79
|
+
function urlText(value, label) {
|
|
80
|
+
return value instanceof URL ? value.toString() : text(value, label);
|
|
81
|
+
}
|
|
82
|
+
function text(value, label) {
|
|
83
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
84
|
+
throw new TypeError(`${label} is invalid`);
|
|
85
|
+
return value.trim();
|
|
86
|
+
}
|
|
87
|
+
function boolean(value, label) {
|
|
88
|
+
if (typeof value !== "boolean")
|
|
89
|
+
throw new TypeError(`${label} is invalid`);
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
function integer(value, label) {
|
|
93
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
94
|
+
throw new TypeError(`${label} is invalid`);
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=factories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factories.js","sourceRoot":"","sources":["../src/factories.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,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,mBAAmB,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface StandardRedisClientOptions {
|
|
2
|
+
readonly url: string;
|
|
3
|
+
readonly connectionTimeoutMs?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface StandardRedisClient {
|
|
6
|
+
readonly connected: boolean;
|
|
7
|
+
connect(): Promise<void>;
|
|
8
|
+
close(): void;
|
|
9
|
+
ping(): Promise<boolean>;
|
|
10
|
+
get(key: string): Promise<string | null>;
|
|
11
|
+
set(key: string, value: string, ttlMs?: number): Promise<void>;
|
|
12
|
+
delete(key: string): Promise<number>;
|
|
13
|
+
has(key: string): Promise<boolean>;
|
|
14
|
+
increment(key: string, amount?: number): Promise<number>;
|
|
15
|
+
scan(cursor: string, pattern: string, count: number): Promise<readonly [string, readonly string[]]>;
|
|
16
|
+
type(key: string): Promise<string>;
|
|
17
|
+
ttl(key: string): Promise<number>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createRedisClient(options: StandardRedisClientOptions): StandardRedisClient;
|
|
20
|
+
//# sourceMappingURL=redis-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-client.d.ts","sourceRoot":"","sources":["../src/redis-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CACF,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,0BAA0B,GAAG,mBAAmB,CA+C1F"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { RedisClient } from "bun";
|
|
2
|
+
export function createRedisClient(options) {
|
|
3
|
+
const url = validateUrl(options.url);
|
|
4
|
+
if (options.connectionTimeoutMs !== undefined &&
|
|
5
|
+
(!Number.isSafeInteger(options.connectionTimeoutMs) || options.connectionTimeoutMs < 1)) {
|
|
6
|
+
throw new RangeError("Redis connectionTimeoutMs must be a positive integer");
|
|
7
|
+
}
|
|
8
|
+
const client = new RedisClient(url, {
|
|
9
|
+
tls: url.startsWith("rediss://"),
|
|
10
|
+
...(options.connectionTimeoutMs === undefined
|
|
11
|
+
? {}
|
|
12
|
+
: { connectionTimeout: options.connectionTimeoutMs }),
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
get connected() {
|
|
16
|
+
return client.connected;
|
|
17
|
+
},
|
|
18
|
+
connect: () => client.connect(),
|
|
19
|
+
close: () => client.close(),
|
|
20
|
+
ping: async () => String(await client.send("PING", [])) === "PONG",
|
|
21
|
+
get: (key) => client.get(key),
|
|
22
|
+
set: async (key, value, ttlMs) => {
|
|
23
|
+
if (ttlMs === undefined)
|
|
24
|
+
await client.set(key, value);
|
|
25
|
+
else {
|
|
26
|
+
if (!Number.isSafeInteger(ttlMs) || ttlMs < 1) {
|
|
27
|
+
throw new RangeError("Redis ttlMs must be a positive integer");
|
|
28
|
+
}
|
|
29
|
+
await client.set(key, value, "PX", ttlMs);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
delete: (key) => client.del(key),
|
|
33
|
+
has: (key) => client.exists(key),
|
|
34
|
+
increment: (key, amount = 1) => {
|
|
35
|
+
if (!Number.isSafeInteger(amount))
|
|
36
|
+
throw new RangeError("Redis increment must be an integer");
|
|
37
|
+
return client.incrby(key, amount);
|
|
38
|
+
},
|
|
39
|
+
scan: async (cursor, pattern, count) => {
|
|
40
|
+
const result = await client.send("SCAN", [cursor, "MATCH", pattern, "COUNT", String(count)]);
|
|
41
|
+
if (!Array.isArray(result) || result.length !== 2 || !Array.isArray(result[1])) {
|
|
42
|
+
throw new Error("Redis SCAN returned an invalid response");
|
|
43
|
+
}
|
|
44
|
+
return [String(result[0]), result[1].map(String)];
|
|
45
|
+
},
|
|
46
|
+
type: async (key) => String(await client.send("TYPE", [key])),
|
|
47
|
+
ttl: async (key) => Number(await client.send("PTTL", [key])),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function validateUrl(value) {
|
|
51
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
52
|
+
throw new TypeError("Redis URL must not be empty");
|
|
53
|
+
}
|
|
54
|
+
const url = new URL(value);
|
|
55
|
+
if (url.protocol !== "redis:" && url.protocol !== "rediss:") {
|
|
56
|
+
throw new TypeError("Redis URL must use redis:// or rediss://");
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=redis-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../src/redis-client.ts"],"names":[],"mappings":"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"}
|
package/dist/redis.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CacheProvider } from "@relkit/cache";
|
|
2
|
+
import { type StandardRedisClient } from "./redis-client.js";
|
|
3
|
+
export interface RedisCacheOptions {
|
|
4
|
+
readonly url: string;
|
|
5
|
+
readonly cacheId: string;
|
|
6
|
+
readonly connectionTimeoutMs?: number;
|
|
7
|
+
readonly client?: StandardRedisClient;
|
|
8
|
+
}
|
|
9
|
+
export interface RedisCacheProvider extends CacheProvider {
|
|
10
|
+
readonly ready: () => Promise<void>;
|
|
11
|
+
readonly close: () => Promise<void>;
|
|
12
|
+
readonly inspector: {
|
|
13
|
+
readonly scan: (request: {
|
|
14
|
+
readonly search?: string;
|
|
15
|
+
readonly cursor?: string;
|
|
16
|
+
readonly limit: number;
|
|
17
|
+
readonly signal: AbortSignal;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
readonly items: readonly unknown[];
|
|
20
|
+
readonly nextCursor?: string;
|
|
21
|
+
}>;
|
|
22
|
+
readonly value: (request: {
|
|
23
|
+
readonly key: string;
|
|
24
|
+
readonly limit: number;
|
|
25
|
+
readonly signal: AbortSignal;
|
|
26
|
+
}) => Promise<unknown | undefined>;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export declare function createRedisCacheProvider(options: RedisCacheOptions): RedisCacheProvider;
|
|
30
|
+
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgD,aAAa,EAAE,MAAM,eAAe,CAAC;AAEjG,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;YACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;SAC9B,KAAK,OAAO,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;YAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpF,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE;YACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;YACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;SAC9B,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;KACpC,CAAC;CACH;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,GAAG,kBAAkB,CAyHvF"}
|
package/dist/redis.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { canonicalJson } from "@relkit/contracts";
|
|
2
|
+
import { createRedisClient } from "./redis-client.js";
|
|
3
|
+
export function createRedisCacheProvider(options) {
|
|
4
|
+
const client = options.client ??
|
|
5
|
+
createRedisClient({
|
|
6
|
+
url: options.url,
|
|
7
|
+
...(options.connectionTimeoutMs === undefined
|
|
8
|
+
? {}
|
|
9
|
+
: { connectionTimeoutMs: options.connectionTimeoutMs }),
|
|
10
|
+
});
|
|
11
|
+
const flights = new Map();
|
|
12
|
+
const encoded = (key) => `${options.cacheId}:${canonicalJson(key)}`;
|
|
13
|
+
const connect = async () => {
|
|
14
|
+
if (!client.connected)
|
|
15
|
+
await client.connect();
|
|
16
|
+
return client;
|
|
17
|
+
};
|
|
18
|
+
const get = async (key, context) => {
|
|
19
|
+
check(context);
|
|
20
|
+
const value = await (await connect()).get(encoded(key));
|
|
21
|
+
return value === null ? undefined : JSON.parse(value);
|
|
22
|
+
};
|
|
23
|
+
const set = async (key, value, settings, context) => {
|
|
24
|
+
check(context);
|
|
25
|
+
await (await connect()).set(encoded(key), canonicalJson(value), settings?.ttlMs);
|
|
26
|
+
};
|
|
27
|
+
const remove = async (key, context) => {
|
|
28
|
+
check(context);
|
|
29
|
+
await (await connect()).delete(encoded(key));
|
|
30
|
+
};
|
|
31
|
+
const increment = async (key, amount = 1, settings, context) => {
|
|
32
|
+
check(context);
|
|
33
|
+
const value = await (await connect()).increment(encoded(key), amount);
|
|
34
|
+
if (settings?.ttlMs !== undefined) {
|
|
35
|
+
await (await connect()).set(encoded(key), String(value), settings.ttlMs);
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
};
|
|
39
|
+
const getOrSet = async (key, produce, settings, context) => {
|
|
40
|
+
const cached = await get(key, context);
|
|
41
|
+
if (cached !== undefined)
|
|
42
|
+
return cached;
|
|
43
|
+
const cacheKey = encoded(key);
|
|
44
|
+
const existing = flights.get(cacheKey);
|
|
45
|
+
if (existing !== undefined)
|
|
46
|
+
return existing;
|
|
47
|
+
const flight = Promise.resolve(produce()).then(async (value) => {
|
|
48
|
+
await set(key, value, settings, context);
|
|
49
|
+
return value;
|
|
50
|
+
});
|
|
51
|
+
flights.set(cacheKey, flight);
|
|
52
|
+
try {
|
|
53
|
+
return await flight;
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
if (flights.get(cacheKey) === flight)
|
|
57
|
+
flights.delete(cacheKey);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const inspector = Object.freeze({
|
|
61
|
+
scan: async (request) => {
|
|
62
|
+
check({ operation: "get", signal: request.signal });
|
|
63
|
+
const redis = await connect();
|
|
64
|
+
const pattern = `${options.cacheId}:*${redisPattern(request.search ?? "")}*`;
|
|
65
|
+
const [nextCursor, keys] = await redis.scan(request.cursor ?? "0", pattern, request.limit);
|
|
66
|
+
const items = await Promise.all(keys.slice(0, request.limit).map(async (key) => ({
|
|
67
|
+
key: key.slice(options.cacheId.length + 1),
|
|
68
|
+
type: await redis.type(key),
|
|
69
|
+
ttlMs: normalizeTtl(await redis.ttl(key)),
|
|
70
|
+
bytes: new TextEncoder().encode((await redis.get(key)) ?? "").byteLength,
|
|
71
|
+
})));
|
|
72
|
+
return { items, ...(nextCursor === "0" ? {} : { nextCursor }) };
|
|
73
|
+
},
|
|
74
|
+
value: async (request) => {
|
|
75
|
+
check({ operation: "get", signal: request.signal });
|
|
76
|
+
const redis = await connect();
|
|
77
|
+
const key = `${options.cacheId}:${request.key}`;
|
|
78
|
+
const value = await redis.get(key);
|
|
79
|
+
if (value === null)
|
|
80
|
+
return undefined;
|
|
81
|
+
const bytes = new TextEncoder().encode(value).byteLength;
|
|
82
|
+
return {
|
|
83
|
+
key: request.key,
|
|
84
|
+
type: await redis.type(key),
|
|
85
|
+
ttlMs: normalizeTtl(await redis.ttl(key)),
|
|
86
|
+
bytes,
|
|
87
|
+
...(bytes > request.limit
|
|
88
|
+
? { truncated: true }
|
|
89
|
+
: { value: JSON.parse(value), truncated: false }),
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return Object.freeze({
|
|
94
|
+
capabilities: Object.freeze({ increment: true }),
|
|
95
|
+
get,
|
|
96
|
+
set,
|
|
97
|
+
delete: remove,
|
|
98
|
+
has: async (key, context) => (await get(key, context)) !== undefined,
|
|
99
|
+
getOrSet,
|
|
100
|
+
increment,
|
|
101
|
+
inspector,
|
|
102
|
+
ready: async () => {
|
|
103
|
+
check(undefined);
|
|
104
|
+
if (!(await (await connect()).ping()))
|
|
105
|
+
throw new Error("Redis readiness check failed");
|
|
106
|
+
},
|
|
107
|
+
close: async () => {
|
|
108
|
+
flights.clear();
|
|
109
|
+
client.close();
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function redisPattern(value) {
|
|
114
|
+
return value.replace(/[\\*?\[\]]/g, "\\$&");
|
|
115
|
+
}
|
|
116
|
+
function normalizeTtl(value) {
|
|
117
|
+
return value < 0 ? null : value;
|
|
118
|
+
}
|
|
119
|
+
function check(context) {
|
|
120
|
+
if (context?.signal.aborted)
|
|
121
|
+
throw context.signal.reason ?? new Error("Cache operation cancelled");
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../src/redis.ts"],"names":[],"mappings":"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"}
|
package/dist/s3-url.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function objectUrl(endpoint: string, bucket: string, key: string, pathStyle: boolean): string;
|
|
2
|
+
export declare function endpointFor(value: string): string;
|
|
3
|
+
export declare function requiredText(value: unknown, label: string): string;
|
|
4
|
+
//# sourceMappingURL=s3-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-url.d.ts","sourceRoot":"","sources":["../src/s3-url.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,OAAO,GACjB,MAAM,CAUR;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlE"}
|
package/dist/s3-url.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function objectUrl(endpoint, bucket, key, pathStyle) {
|
|
2
|
+
const parsed = new URL(endpoint);
|
|
3
|
+
const keySuffix = key === "" ? "" : `/${keyPath(key)}`;
|
|
4
|
+
if (pathStyle) {
|
|
5
|
+
parsed.pathname = `${parsed.pathname.replace(/\/$/, "")}/${encodeURIComponent(bucket)}${keySuffix}`;
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
parsed.hostname = `${bucket}.${parsed.hostname}`;
|
|
9
|
+
parsed.pathname = `${parsed.pathname.replace(/\/$/, "")}${keySuffix || "/"}`;
|
|
10
|
+
}
|
|
11
|
+
return parsed.toString().replace(/\/$/, key === "" ? "/" : "");
|
|
12
|
+
}
|
|
13
|
+
export function endpointFor(value) {
|
|
14
|
+
const endpoint = requiredText(value, "S3 endpoint");
|
|
15
|
+
const parsed = new URL(endpoint);
|
|
16
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
17
|
+
throw new TypeError("S3 endpoint must use http or https");
|
|
18
|
+
}
|
|
19
|
+
return parsed.toString().replace(/\/$/, "");
|
|
20
|
+
}
|
|
21
|
+
export function requiredText(value, label) {
|
|
22
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
23
|
+
throw new TypeError(`${label} is invalid`);
|
|
24
|
+
return value.trim();
|
|
25
|
+
}
|
|
26
|
+
function keyPath(value) {
|
|
27
|
+
return value.split("/").map(encodeURIComponent).join("/");
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=s3-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-url.js","sourceRoot":"","sources":["../src/s3-url.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,MAAc,EACd,GAAW,EACX,SAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IACvD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,QAAQ,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;IACtG,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,QAAQ,GAAG,GAAG,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,CAAC,QAAQ,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,SAAS,IAAI,GAAG,EAAE,CAAC;IAC/E,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,SAAS,CAAC,oCAAoC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,KAAa;IACxD,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,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5D,CAAC"}
|
package/dist/s3-xml.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-xml.d.ts","sourceRoot":"","sources":["../src/s3-xml.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAgB9D"}
|
package/dist/s3-xml.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function decodeS3Xml(value) {
|
|
2
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
3
|
+
}
|
|
4
|
+
export function s3XmlValue(xml, name) {
|
|
5
|
+
return new RegExp(`<${name}>([\\s\\S]*?)<\\/${name}>`).exec(xml)?.[1];
|
|
6
|
+
}
|
|
7
|
+
export function s3ErrorDetail(body) {
|
|
8
|
+
const xml = [s3XmlValue(body, "Code"), s3XmlValue(body, "Message")]
|
|
9
|
+
.filter((value) => value !== undefined)
|
|
10
|
+
.map(decodeS3Xml);
|
|
11
|
+
if (xml.length > 0)
|
|
12
|
+
return xml.join(": ").slice(0, 500);
|
|
13
|
+
const text = body.trim().replace(/\s+/g, " ");
|
|
14
|
+
if (text === "")
|
|
15
|
+
return undefined;
|
|
16
|
+
try {
|
|
17
|
+
const value = JSON.parse(text);
|
|
18
|
+
const detail = [value.code, value.message, value.error].find((entry) => typeof entry === "string" && entry.trim() !== "");
|
|
19
|
+
return detail?.slice(0, 500) ?? text.slice(0, 500);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return text.slice(0, 500);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=s3-xml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-xml.js","sourceRoot":"","sources":["../src/s3-xml.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IAClD,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,oBAAoB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;SAChE,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;SACvD,GAAG,CAAC,WAAW,CAAC,CAAC;IACpB,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;QAC1D,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAC1D,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAC7E,CAAC;QACF,OAAO,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
|
package/dist/s3.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BucketProvider } from "@relkit/buckets";
|
|
2
|
+
import { type S3Credentials } from "./signing.js";
|
|
3
|
+
export interface S3BucketOptions {
|
|
4
|
+
readonly endpoint: string;
|
|
5
|
+
readonly bucketName: string;
|
|
6
|
+
readonly region: string;
|
|
7
|
+
readonly credentials?: S3Credentials;
|
|
8
|
+
readonly forcePathStyle?: boolean;
|
|
9
|
+
readonly signedUrlTtlSeconds?: number;
|
|
10
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
11
|
+
}
|
|
12
|
+
export interface S3BucketProvider extends BucketProvider {
|
|
13
|
+
readonly inspector: {
|
|
14
|
+
readonly list: (request: {
|
|
15
|
+
readonly prefix?: string;
|
|
16
|
+
readonly cursor?: string;
|
|
17
|
+
readonly limit: number;
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
readonly items: readonly unknown[];
|
|
21
|
+
readonly nextCursor?: string;
|
|
22
|
+
}>;
|
|
23
|
+
readonly preview: (request: {
|
|
24
|
+
readonly key: string;
|
|
25
|
+
readonly offset: number;
|
|
26
|
+
readonly limit: number;
|
|
27
|
+
readonly signal: AbortSignal;
|
|
28
|
+
}) => Promise<{
|
|
29
|
+
readonly bytes: Uint8Array;
|
|
30
|
+
readonly metadata: unknown;
|
|
31
|
+
readonly totalBytes: number;
|
|
32
|
+
} | undefined>;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export declare function createS3BucketProvider(options: S3BucketOptions): S3BucketProvider;
|
|
36
|
+
//# sourceMappingURL=s3.d.ts.map
|
package/dist/s3.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA0B,cAAc,EAAoB,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,cAAc,CAAC;AAItB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE;YACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;SAC9B,KAAK,OAAO,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;YAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpF,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE;YAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;YACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;YACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;SAC9B,KAAK,OAAO,CACT;YAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;YAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;YAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;SAAE,GACvF,SAAS,CACZ,CAAC;KACH,CAAC;CACH;AACD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,eAAe,GAAG,gBAAgB,CAuJjF"}
|
package/dist/s3.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { assertResponse, presignS3Url, signedRequest, } from "./signing.js";
|
|
2
|
+
import { decodeS3Xml, s3XmlValue } from "./s3-xml.js";
|
|
3
|
+
import { endpointFor, objectUrl, requiredText } from "./s3-url.js";
|
|
4
|
+
export function createS3BucketProvider(options) {
|
|
5
|
+
const endpoint = endpointFor(options.endpoint);
|
|
6
|
+
const bucket = requiredText(options.bucketName, "S3 bucketName");
|
|
7
|
+
const region = requiredText(options.region, "S3 region");
|
|
8
|
+
const forcePathStyle = options.forcePathStyle ?? false;
|
|
9
|
+
const expires = options.signedUrlTtlSeconds ?? 900;
|
|
10
|
+
if (!Number.isSafeInteger(expires) || expires < 1 || expires > 604_800) {
|
|
11
|
+
throw new RangeError("S3 signedUrlTtlSeconds must be between 1 and 604800");
|
|
12
|
+
}
|
|
13
|
+
const url = (key = "") => objectUrl(endpoint, bucket, key, forcePathStyle);
|
|
14
|
+
const request = (key, init, context) => signedRequest(url(key), {
|
|
15
|
+
region,
|
|
16
|
+
...(options.credentials === undefined ? {} : { credentials: options.credentials }),
|
|
17
|
+
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
|
|
18
|
+
init: { ...init, ...(context === undefined ? {} : { signal: context.signal }) },
|
|
19
|
+
});
|
|
20
|
+
const inspector = Object.freeze({
|
|
21
|
+
list: async (input) => {
|
|
22
|
+
const listUrl = new URL(url());
|
|
23
|
+
listUrl.searchParams.set("list-type", "2");
|
|
24
|
+
listUrl.searchParams.set("max-keys", String(input.limit));
|
|
25
|
+
if (input.prefix !== undefined)
|
|
26
|
+
listUrl.searchParams.set("prefix", input.prefix);
|
|
27
|
+
if (input.cursor !== undefined)
|
|
28
|
+
listUrl.searchParams.set("continuation-token", input.cursor);
|
|
29
|
+
const response = await signedRequest(listUrl.toString(), {
|
|
30
|
+
region,
|
|
31
|
+
...(options.credentials === undefined ? {} : { credentials: options.credentials }),
|
|
32
|
+
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
|
|
33
|
+
init: { method: "GET", signal: input.signal },
|
|
34
|
+
});
|
|
35
|
+
await assertResponse(response, "S3 inspector list");
|
|
36
|
+
const xml = await response.text();
|
|
37
|
+
const items = [...xml.matchAll(/<Contents>([\s\S]*?)<\/Contents>/g)].map((match) => ({
|
|
38
|
+
key: decodeS3Xml(s3XmlValue(match[1], "Key") ?? ""),
|
|
39
|
+
size: Number(s3XmlValue(match[1], "Size") ?? 0),
|
|
40
|
+
etag: (s3XmlValue(match[1], "ETag") ?? "").replaceAll('"', ""),
|
|
41
|
+
lastModified: s3XmlValue(match[1], "LastModified") ?? undefined,
|
|
42
|
+
}));
|
|
43
|
+
const nextCursor = s3XmlValue(xml, "NextContinuationToken");
|
|
44
|
+
return {
|
|
45
|
+
items,
|
|
46
|
+
...(nextCursor === undefined ? {} : { nextCursor: decodeS3Xml(nextCursor) }),
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
preview: async (input) => {
|
|
50
|
+
const response = await request(input.key, {
|
|
51
|
+
method: "GET",
|
|
52
|
+
headers: { range: `bytes=${input.offset}-${input.offset + input.limit - 1}` },
|
|
53
|
+
}, { operation: "get", signal: input.signal });
|
|
54
|
+
if (response.status === 404)
|
|
55
|
+
return undefined;
|
|
56
|
+
await assertResponse(response, "S3 inspector preview");
|
|
57
|
+
const range = response.headers.get("content-range")?.match(/\/(\d+)$/);
|
|
58
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
59
|
+
return {
|
|
60
|
+
bytes,
|
|
61
|
+
totalBytes: range === undefined || range === null ? bytes.byteLength : Number(range[1]),
|
|
62
|
+
metadata: {
|
|
63
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
64
|
+
etag: response.headers.get("etag")?.replaceAll('"', "") ?? "",
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
capabilities: Object.freeze({ signedReadUrl: true, signedWriteUrl: true }),
|
|
71
|
+
put: async (key, bytes, putOptions, context) => {
|
|
72
|
+
const headers = new Headers();
|
|
73
|
+
if (putOptions?.contentType !== undefined)
|
|
74
|
+
headers.set("content-type", putOptions.contentType);
|
|
75
|
+
for (const [name, value] of Object.entries(putOptions?.metadata ?? {})) {
|
|
76
|
+
headers.set(`x-amz-meta-${name}`, value);
|
|
77
|
+
}
|
|
78
|
+
await assertResponse(await request(key, { method: "PUT", headers, body: bytes }, context), "S3 put");
|
|
79
|
+
},
|
|
80
|
+
get: async (key, context) => {
|
|
81
|
+
const response = await request(key, { method: "GET" }, context);
|
|
82
|
+
if (response.status === 404)
|
|
83
|
+
return undefined;
|
|
84
|
+
await assertResponse(response, "S3 get");
|
|
85
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
86
|
+
},
|
|
87
|
+
head: async (key, context) => {
|
|
88
|
+
const response = await request(key, { method: "HEAD" }, context);
|
|
89
|
+
if (response.status === 404)
|
|
90
|
+
return undefined;
|
|
91
|
+
await assertResponse(response, "S3 head");
|
|
92
|
+
const metadata = {};
|
|
93
|
+
response.headers.forEach((value, name) => {
|
|
94
|
+
if (name.startsWith("x-amz-meta-"))
|
|
95
|
+
metadata[name.slice(11)] = value;
|
|
96
|
+
});
|
|
97
|
+
const size = Number(response.headers.get("content-length"));
|
|
98
|
+
return {
|
|
99
|
+
etag: response.headers.get("etag")?.replaceAll('"', "") ?? "",
|
|
100
|
+
...(response.headers.get("x-amz-checksum-sha256") === null
|
|
101
|
+
? {}
|
|
102
|
+
: { contentHash: response.headers.get("x-amz-checksum-sha256") }),
|
|
103
|
+
...(response.headers.get("content-type") === null
|
|
104
|
+
? {}
|
|
105
|
+
: { contentType: response.headers.get("content-type") }),
|
|
106
|
+
...(Number.isFinite(size) ? { size } : {}),
|
|
107
|
+
metadata,
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
delete: async (key, context) => {
|
|
111
|
+
await assertResponse(await request(key, { method: "DELETE" }, context), "S3 delete");
|
|
112
|
+
},
|
|
113
|
+
exists: async (key, context) => (await request(key, { method: "HEAD" }, context)).ok,
|
|
114
|
+
list: async (prefix, context) => {
|
|
115
|
+
const listUrl = new URL(url());
|
|
116
|
+
listUrl.searchParams.set("list-type", "2");
|
|
117
|
+
if (prefix !== undefined)
|
|
118
|
+
listUrl.searchParams.set("prefix", prefix);
|
|
119
|
+
const response = await signedRequest(listUrl.toString(), {
|
|
120
|
+
region,
|
|
121
|
+
...(options.credentials === undefined ? {} : { credentials: options.credentials }),
|
|
122
|
+
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
|
|
123
|
+
init: { method: "GET", ...(context === undefined ? {} : { signal: context.signal }) },
|
|
124
|
+
});
|
|
125
|
+
await assertResponse(response, "S3 list");
|
|
126
|
+
return Object.freeze([...(await response.text()).matchAll(/<Key>([^<]*)<\/Key>/g)].map((match) => decodeS3Xml(match[1])));
|
|
127
|
+
},
|
|
128
|
+
createReadUrl: (key) => presignS3Url(url(key), "GET", region, expires, {
|
|
129
|
+
...(options.credentials === undefined ? {} : { credentials: options.credentials }),
|
|
130
|
+
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
|
|
131
|
+
}),
|
|
132
|
+
createWriteUrl: (key) => presignS3Url(url(key), "PUT", region, expires, {
|
|
133
|
+
...(options.credentials === undefined ? {} : { credentials: options.credentials }),
|
|
134
|
+
...(options.fetch === undefined ? {} : { fetch: options.fetch }),
|
|
135
|
+
}),
|
|
136
|
+
inspector,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=s3.js.map
|
package/dist/s3.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.js","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface S3Credentials {
|
|
2
|
+
readonly accessKeyId: string;
|
|
3
|
+
readonly secretAccessKey: string;
|
|
4
|
+
readonly sessionToken?: string;
|
|
5
|
+
}
|
|
6
|
+
export type SignedRequestInit = Omit<RequestInit, "body"> & {
|
|
7
|
+
readonly body?: string | Uint8Array | null;
|
|
8
|
+
};
|
|
9
|
+
export interface SignedRequestOptions {
|
|
10
|
+
readonly region: string;
|
|
11
|
+
readonly credentials?: S3Credentials;
|
|
12
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
13
|
+
readonly init?: SignedRequestInit;
|
|
14
|
+
}
|
|
15
|
+
export declare function signedRequest(url: string, options: SignedRequestOptions): Promise<Response>;
|
|
16
|
+
export declare function presignS3Url(url: string, method: "GET" | "PUT", region: string, expiresSeconds: number, options?: Pick<SignedRequestOptions, "credentials" | "fetch">): Promise<string>;
|
|
17
|
+
export declare function assertResponse(response: Response, operation: string): Promise<Response>;
|
|
18
|
+
//# sourceMappingURL=signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAcjG;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,KAAK,GAAG,KAAK,EACrB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,aAAa,GAAG,OAAO,CAAM,GAChE,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAkCD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAM7F"}
|
package/dist/signing.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { s3ErrorDetail } from "./s3-xml.js";
|
|
2
|
+
export async function signedRequest(url, options) {
|
|
3
|
+
const request = options.init ?? {};
|
|
4
|
+
const headers = new Headers(request.headers);
|
|
5
|
+
const body = request.body ?? "";
|
|
6
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
7
|
+
const credentials = options.credentials ?? (await workloadCredentials(fetcher));
|
|
8
|
+
if (credentials !== undefined)
|
|
9
|
+
await signHeaders(url, options.region, credentials, headers, body, request.method);
|
|
10
|
+
const { body: requestBody, ...withoutBody } = request;
|
|
11
|
+
return fetcher(url, {
|
|
12
|
+
...withoutBody,
|
|
13
|
+
...(requestBody === undefined ? {} : { body: requestBody }),
|
|
14
|
+
headers,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function presignS3Url(url, method, region, expiresSeconds, options = {}) {
|
|
18
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
19
|
+
const credentials = options.credentials ?? (await workloadCredentials(fetcher));
|
|
20
|
+
if (credentials === undefined)
|
|
21
|
+
throw new Error("S3 signed URLs require credentials");
|
|
22
|
+
const now = new Date();
|
|
23
|
+
const amzDate = timestamp(now);
|
|
24
|
+
const date = amzDate.slice(0, 8);
|
|
25
|
+
const scope = `${date}/${region}/s3/aws4_request`;
|
|
26
|
+
const parsed = new URL(url);
|
|
27
|
+
parsed.searchParams.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
|
|
28
|
+
parsed.searchParams.set("X-Amz-Credential", `${credentials.accessKeyId}/${scope}`);
|
|
29
|
+
parsed.searchParams.set("X-Amz-Date", amzDate);
|
|
30
|
+
parsed.searchParams.set("X-Amz-Expires", String(expiresSeconds));
|
|
31
|
+
parsed.searchParams.set("X-Amz-SignedHeaders", "host");
|
|
32
|
+
if (credentials.sessionToken !== undefined) {
|
|
33
|
+
parsed.searchParams.set("X-Amz-Security-Token", credentials.sessionToken);
|
|
34
|
+
}
|
|
35
|
+
const canonical = [
|
|
36
|
+
method,
|
|
37
|
+
parsed.pathname || "/",
|
|
38
|
+
canonicalQuery(parsed.searchParams),
|
|
39
|
+
`host:${parsed.host}\n`,
|
|
40
|
+
"host",
|
|
41
|
+
"UNSIGNED-PAYLOAD",
|
|
42
|
+
].join("\n");
|
|
43
|
+
const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${scope}\n${await hash(canonical)}`;
|
|
44
|
+
const signingKey = await deriveKey(credentials.secretAccessKey, date, region, "s3");
|
|
45
|
+
parsed.searchParams.set("X-Amz-Signature", hex(await hmac(signingKey, stringToSign)));
|
|
46
|
+
return parsed.toString();
|
|
47
|
+
}
|
|
48
|
+
let cachedCredentials;
|
|
49
|
+
async function workloadCredentials(fetcher) {
|
|
50
|
+
const path = process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI;
|
|
51
|
+
if (path === undefined || !path.startsWith("/"))
|
|
52
|
+
return undefined;
|
|
53
|
+
if (cachedCredentials !== undefined && cachedCredentials.expiresAt > Date.now() + 60_000) {
|
|
54
|
+
return cachedCredentials.value;
|
|
55
|
+
}
|
|
56
|
+
const headers = new Headers();
|
|
57
|
+
const token = process.env.AWS_CONTAINER_AUTHORIZATION_TOKEN;
|
|
58
|
+
if (token !== undefined)
|
|
59
|
+
headers.set("authorization", token);
|
|
60
|
+
const response = await fetcher(`http://169.254.170.2${path}`, { headers });
|
|
61
|
+
await assertResponse(response, "container credentials");
|
|
62
|
+
const result = (await response.json());
|
|
63
|
+
if (typeof result.AccessKeyId !== "string" || typeof result.SecretAccessKey !== "string") {
|
|
64
|
+
throw new Error("AWS container credentials response is invalid");
|
|
65
|
+
}
|
|
66
|
+
const value = {
|
|
67
|
+
accessKeyId: result.AccessKeyId,
|
|
68
|
+
secretAccessKey: result.SecretAccessKey,
|
|
69
|
+
...(typeof result.Token === "string" ? { sessionToken: result.Token } : {}),
|
|
70
|
+
};
|
|
71
|
+
const expiration = typeof result.Expiration === "string" ? Date.parse(result.Expiration) : NaN;
|
|
72
|
+
cachedCredentials = {
|
|
73
|
+
value,
|
|
74
|
+
expiresAt: Number.isFinite(expiration) ? expiration : Date.now() + 300_000,
|
|
75
|
+
};
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
export async function assertResponse(response, operation) {
|
|
79
|
+
if (response.ok)
|
|
80
|
+
return response;
|
|
81
|
+
const detail = s3ErrorDetail(await response.text());
|
|
82
|
+
throw new Error(`${operation} failed with status ${response.status}${detail ? `: ${detail}` : ""}`);
|
|
83
|
+
}
|
|
84
|
+
async function signHeaders(url, region, credentials, headers, body, method = "GET") {
|
|
85
|
+
const amzDate = timestamp(new Date());
|
|
86
|
+
const date = amzDate.slice(0, 8);
|
|
87
|
+
const parsed = new URL(url);
|
|
88
|
+
const payloadHash = await hash(body);
|
|
89
|
+
headers.set("host", parsed.host);
|
|
90
|
+
headers.set("x-amz-date", amzDate);
|
|
91
|
+
headers.set("x-amz-content-sha256", payloadHash);
|
|
92
|
+
if (credentials.sessionToken !== undefined)
|
|
93
|
+
headers.set("x-amz-security-token", credentials.sessionToken);
|
|
94
|
+
const canonicalHeaders = [...headers.entries()]
|
|
95
|
+
.map(([name, value]) => [name.toLowerCase(), value.trim().replace(/\s+/g, " ")])
|
|
96
|
+
.sort(([left], [right]) => left.localeCompare(right));
|
|
97
|
+
const signedHeaders = canonicalHeaders.map(([name]) => name).join(";");
|
|
98
|
+
const canonical = [
|
|
99
|
+
method.toUpperCase(),
|
|
100
|
+
parsed.pathname || "/",
|
|
101
|
+
canonicalQuery(parsed.searchParams),
|
|
102
|
+
canonicalHeaders.map(([name, value]) => `${name}:${value}\n`).join(""),
|
|
103
|
+
signedHeaders,
|
|
104
|
+
payloadHash,
|
|
105
|
+
].join("\n");
|
|
106
|
+
const scope = `${date}/${region}/s3/aws4_request`;
|
|
107
|
+
const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${scope}\n${await hash(canonical)}`;
|
|
108
|
+
const signingKey = await deriveKey(credentials.secretAccessKey, date, region, "s3");
|
|
109
|
+
const signature = hex(await hmac(signingKey, stringToSign));
|
|
110
|
+
headers.set("authorization", `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`);
|
|
111
|
+
}
|
|
112
|
+
function canonicalQuery(params) {
|
|
113
|
+
return [...params.entries()]
|
|
114
|
+
.map(([name, value]) => [encode(name), encode(value)])
|
|
115
|
+
.sort(([aName, aValue], [bName, bValue]) => aName.localeCompare(bName) || aValue.localeCompare(bValue))
|
|
116
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
117
|
+
.join("&");
|
|
118
|
+
}
|
|
119
|
+
function encode(value) {
|
|
120
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
121
|
+
}
|
|
122
|
+
function timestamp(value) {
|
|
123
|
+
return value.toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
124
|
+
}
|
|
125
|
+
async function deriveKey(secret, date, region, service) {
|
|
126
|
+
let value = await hmac(`AWS4${secret}`, date);
|
|
127
|
+
value = await hmac(value, region);
|
|
128
|
+
value = await hmac(value, service);
|
|
129
|
+
return hmac(value, "aws4_request");
|
|
130
|
+
}
|
|
131
|
+
async function hmac(keyValue, value) {
|
|
132
|
+
const data = typeof keyValue === "string" ? new TextEncoder().encode(keyValue) : keyValue;
|
|
133
|
+
const key = await crypto.subtle.importKey("raw", data, { name: "HMAC", hash: "SHA-256" }, false, [
|
|
134
|
+
"sign",
|
|
135
|
+
]);
|
|
136
|
+
return crypto.subtle.sign("HMAC", key, new TextEncoder().encode(value));
|
|
137
|
+
}
|
|
138
|
+
async function hash(value) {
|
|
139
|
+
const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
|
|
140
|
+
return hex(await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes)));
|
|
141
|
+
}
|
|
142
|
+
function hex(value) {
|
|
143
|
+
return [...new Uint8Array(value)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@relkit/providers-standard",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Standard provider adapters for RELKIT applications.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/rel-kit/relkit.git",
|
|
9
|
+
"directory": "packages/providers-standard"
|
|
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
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@relkit/agents": "0.0.0",
|
|
33
|
+
"@relkit/app": "0.0.0",
|
|
34
|
+
"@relkit/buckets": "0.0.0",
|
|
35
|
+
"@relkit/cache": "0.0.0",
|
|
36
|
+
"@relkit/contracts": "0.0.0",
|
|
37
|
+
"@relkit/engine": "0.0.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc -b",
|
|
41
|
+
"check": "tsc -b --pretty false",
|
|
42
|
+
"typecheck": "tsc -b --pretty false"
|
|
43
|
+
}
|
|
44
|
+
}
|