effect-cf 0.9.0 → 0.9.1
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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +11 -3
- package/dist/index.mjs +51 -18
- package/package.json +1 -1
- package/src/R2.ts +101 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#27](https://github.com/danieljvdm/effect-cf/pull/27) [`ac2fb0f`](https://github.com/danieljvdm/effect-cf/commit/ac2fb0f9b557c1f73d779ed024c03245c1850b02) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Wrap R2 object body reader methods in Effect so `json`, `text`, `bytes`, `arrayBuffer`, and `blob` report read failures as `R2OperationError`.
|
|
8
|
+
|
|
3
9
|
## 0.9.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1921,7 +1921,7 @@ declare const Tag$4: <Self>() => <Id extends string, Key, Value, EncodedValue>(i
|
|
|
1921
1921
|
readonly value: Schema.Codec<Value, EncodedValue>;
|
|
1922
1922
|
}) => TagClass$3<Self, Id, Key, Value, EncodedValue>;
|
|
1923
1923
|
declare namespace R2_d_exports {
|
|
1924
|
-
export { LayerOptions$2 as LayerOptions, R2Client, R2Definition, R2GetOptions, R2ListOptions, R2MultipartOptions, R2MultipartUploadClient, R2OperationError, R2PutOptions, R2PutValue, R2Service, R2UploadPartOptions, R2UploadPartValue, Tag$3 as Tag, TagClass$2 as TagClass, isR2Bucket, layer$1 as layer, make$2 as make, makeClient$1 as makeClient };
|
|
1924
|
+
export { LayerOptions$2 as LayerOptions, R2Client, R2Definition, R2GetOptions, R2ListOptions, R2MultipartOptions, R2MultipartUploadClient, R2ObjectBodyClient, R2OperationError, R2PutOptions, R2PutValue, R2Service, R2UploadPartOptions, R2UploadPartValue, Tag$3 as Tag, TagClass$2 as TagClass, isR2Bucket, layer$1 as layer, make$2 as make, makeClient$1 as makeClient };
|
|
1925
1925
|
}
|
|
1926
1926
|
declare const R2OperationError_base: new <A extends Record<string, any> = {}>(args: _$effect_Types0.VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => _$effect_Cause0.YieldableError & {
|
|
1927
1927
|
readonly _tag: "R2OperationError";
|
|
@@ -1944,6 +1944,14 @@ type R2MultipartOptions = globalThis.R2MultipartOptions;
|
|
|
1944
1944
|
type R2UploadPartOptions = globalThis.R2UploadPartOptions;
|
|
1945
1945
|
type R2PutValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob;
|
|
1946
1946
|
type R2UploadPartValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob;
|
|
1947
|
+
interface R2ObjectBodyClient extends Omit<globalThis.R2ObjectBody, "arrayBuffer" | "blob" | "bytes" | "json" | "text"> {
|
|
1948
|
+
readonly raw: globalThis.R2ObjectBody;
|
|
1949
|
+
readonly arrayBuffer: Effect.Effect<ArrayBuffer, R2OperationError>;
|
|
1950
|
+
readonly bytes: Effect.Effect<Uint8Array, R2OperationError>;
|
|
1951
|
+
readonly text: Effect.Effect<string, R2OperationError>;
|
|
1952
|
+
readonly json: <T = unknown>() => Effect.Effect<T, R2OperationError>;
|
|
1953
|
+
readonly blob: Effect.Effect<Blob, R2OperationError>;
|
|
1954
|
+
}
|
|
1947
1955
|
interface R2MultipartUploadClient {
|
|
1948
1956
|
readonly raw: globalThis.R2MultipartUpload;
|
|
1949
1957
|
readonly key: string;
|
|
@@ -1957,8 +1965,8 @@ interface R2Client {
|
|
|
1957
1965
|
readonly get: {
|
|
1958
1966
|
(key: string, options: R2GetOptions & {
|
|
1959
1967
|
readonly onlyIf: globalThis.R2Conditional | Headers;
|
|
1960
|
-
}): Effect.Effect<Option.Option<
|
|
1961
|
-
(key: string, options?: R2GetOptions): Effect.Effect<Option.Option<
|
|
1968
|
+
}): Effect.Effect<Option.Option<R2ObjectBodyClient | globalThis.R2Object>, R2OperationError>;
|
|
1969
|
+
(key: string, options?: R2GetOptions): Effect.Effect<Option.Option<R2ObjectBodyClient>, R2OperationError>;
|
|
1962
1970
|
};
|
|
1963
1971
|
readonly put: {
|
|
1964
1972
|
(key: string, value: R2PutValue, options: R2PutOptions & {
|
package/dist/index.mjs
CHANGED
|
@@ -1978,6 +1978,36 @@ const tryR2Sync = (binding, operation, evaluate) => Effect.try({
|
|
|
1978
1978
|
catch: (cause) => r2Error(binding, operation, cause)
|
|
1979
1979
|
});
|
|
1980
1980
|
const maybe = (value) => value === null ? Option.none() : Option.some(value);
|
|
1981
|
+
const isR2ObjectBody = (value) => "body" in value && typeof value.arrayBuffer === "function" && typeof value.bytes === "function" && typeof value.text === "function" && typeof value.json === "function" && typeof value.blob === "function";
|
|
1982
|
+
const wrapObjectBody = (binding, object) => ({
|
|
1983
|
+
key: object.key,
|
|
1984
|
+
version: object.version,
|
|
1985
|
+
size: object.size,
|
|
1986
|
+
etag: object.etag,
|
|
1987
|
+
httpEtag: object.httpEtag,
|
|
1988
|
+
checksums: object.checksums,
|
|
1989
|
+
uploaded: object.uploaded,
|
|
1990
|
+
httpMetadata: object.httpMetadata,
|
|
1991
|
+
customMetadata: object.customMetadata,
|
|
1992
|
+
range: object.range,
|
|
1993
|
+
storageClass: object.storageClass,
|
|
1994
|
+
ssecKeyMd5: object.ssecKeyMd5,
|
|
1995
|
+
writeHttpMetadata: (headers) => object.writeHttpMetadata(headers),
|
|
1996
|
+
raw: object,
|
|
1997
|
+
body: object.body,
|
|
1998
|
+
get bodyUsed() {
|
|
1999
|
+
return object.bodyUsed;
|
|
2000
|
+
},
|
|
2001
|
+
arrayBuffer: tryR2Promise(binding, "arrayBuffer", () => object.arrayBuffer()),
|
|
2002
|
+
bytes: tryR2Promise(binding, "bytes", () => object.bytes()),
|
|
2003
|
+
text: tryR2Promise(binding, "text", () => object.text()),
|
|
2004
|
+
json: () => tryR2Promise(binding, "json", () => object.json()),
|
|
2005
|
+
blob: tryR2Promise(binding, "blob", () => object.blob())
|
|
2006
|
+
});
|
|
2007
|
+
const wrapGetResult = (binding, object) => {
|
|
2008
|
+
if (object === null || !isR2ObjectBody(object)) return object;
|
|
2009
|
+
return wrapObjectBody(binding, object);
|
|
2010
|
+
};
|
|
1981
2011
|
const isR2Bucket = (value) => {
|
|
1982
2012
|
if (typeof value !== "object" || value === null) return false;
|
|
1983
2013
|
const resource = value;
|
|
@@ -1992,24 +2022,27 @@ const makeClient$1 = (definition) => {
|
|
|
1992
2022
|
abort: tryR2Promise(definition.binding, "abortMultipartUpload", () => upload.abort()),
|
|
1993
2023
|
complete: (uploadedParts) => tryR2Promise(definition.binding, "completeMultipartUpload", () => upload.complete([...uploadedParts]))
|
|
1994
2024
|
});
|
|
1995
|
-
return (bucket) =>
|
|
1996
|
-
definition,
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2025
|
+
return (bucket) => {
|
|
2026
|
+
const get = ((key, options) => tryR2Promise(definition.binding, "get", () => bucket.get(key, options)).pipe(Effect.map((object) => maybe(wrapGetResult(definition.binding, object)))));
|
|
2027
|
+
return {
|
|
2028
|
+
definition,
|
|
2029
|
+
head: (key) => tryR2Promise(definition.binding, "head", () => bucket.head(key)).pipe(Effect.map(maybe)),
|
|
2030
|
+
get,
|
|
2031
|
+
put: ((key, value, options) => tryR2Promise(definition.binding, "put", () => bucket.put(key, value, options)).pipe(Effect.map((object) => {
|
|
2032
|
+
if (object === null) return Option.none();
|
|
2033
|
+
if (options !== void 0 && "onlyIf" in options) return Option.some(object);
|
|
2034
|
+
return object;
|
|
2035
|
+
}))),
|
|
2036
|
+
createMultipartUpload: (key, options) => tryR2Promise(definition.binding, "createMultipartUpload", () => bucket.createMultipartUpload(key, options)).pipe(Effect.map(wrapUpload)),
|
|
2037
|
+
resumeMultipartUpload: (key, uploadId) => tryR2Sync(definition.binding, "resumeMultipartUpload", () => wrapUpload(bucket.resumeMultipartUpload(key, uploadId))),
|
|
2038
|
+
delete: (keys) => {
|
|
2039
|
+
const nativeKeys = typeof keys === "string" ? keys : [...keys];
|
|
2040
|
+
return tryR2Promise(definition.binding, "delete", () => bucket.delete(nativeKeys));
|
|
2041
|
+
},
|
|
2042
|
+
list: (options) => tryR2Promise(definition.binding, "list", () => bucket.list(options)),
|
|
2043
|
+
unsafeRaw: Effect.succeed(bucket)
|
|
2044
|
+
};
|
|
2045
|
+
};
|
|
2013
2046
|
};
|
|
2014
2047
|
const layer$1 = (tag, definition) => layer$8(tag, definition.binding, isR2Bucket, makeClient$1(definition));
|
|
2015
2048
|
const make$2 = (id) => Tag$2()(id);
|
package/package.json
CHANGED
package/src/R2.ts
CHANGED
|
@@ -24,6 +24,18 @@ export type R2UploadPartOptions = globalThis.R2UploadPartOptions;
|
|
|
24
24
|
export type R2PutValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | null | Blob;
|
|
25
25
|
export type R2UploadPartValue = ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob;
|
|
26
26
|
|
|
27
|
+
export interface R2ObjectBodyClient extends Omit<
|
|
28
|
+
globalThis.R2ObjectBody,
|
|
29
|
+
"arrayBuffer" | "blob" | "bytes" | "json" | "text"
|
|
30
|
+
> {
|
|
31
|
+
readonly raw: globalThis.R2ObjectBody;
|
|
32
|
+
readonly arrayBuffer: Effect.Effect<ArrayBuffer, R2OperationError>;
|
|
33
|
+
readonly bytes: Effect.Effect<Uint8Array, R2OperationError>;
|
|
34
|
+
readonly text: Effect.Effect<string, R2OperationError>;
|
|
35
|
+
readonly json: <T = unknown>() => Effect.Effect<T, R2OperationError>;
|
|
36
|
+
readonly blob: Effect.Effect<Blob, R2OperationError>;
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
export interface R2MultipartUploadClient {
|
|
28
40
|
readonly raw: globalThis.R2MultipartUpload;
|
|
29
41
|
readonly key: string;
|
|
@@ -47,14 +59,11 @@ export interface R2Client {
|
|
|
47
59
|
(
|
|
48
60
|
key: string,
|
|
49
61
|
options: R2GetOptions & { readonly onlyIf: globalThis.R2Conditional | Headers },
|
|
50
|
-
): Effect.Effect<
|
|
51
|
-
Option.Option<globalThis.R2ObjectBody | globalThis.R2Object>,
|
|
52
|
-
R2OperationError
|
|
53
|
-
>;
|
|
62
|
+
): Effect.Effect<Option.Option<R2ObjectBodyClient | globalThis.R2Object>, R2OperationError>;
|
|
54
63
|
(
|
|
55
64
|
key: string,
|
|
56
65
|
options?: R2GetOptions,
|
|
57
|
-
): Effect.Effect<Option.Option<
|
|
66
|
+
): Effect.Effect<Option.Option<R2ObjectBodyClient>, R2OperationError>;
|
|
58
67
|
};
|
|
59
68
|
readonly put: {
|
|
60
69
|
(
|
|
@@ -136,6 +145,53 @@ const tryR2Sync = <A>(
|
|
|
136
145
|
const maybe = <A>(value: A | null): Option.Option<A> =>
|
|
137
146
|
value === null ? Option.none() : Option.some(value);
|
|
138
147
|
|
|
148
|
+
const isR2ObjectBody = (
|
|
149
|
+
value: globalThis.R2ObjectBody | globalThis.R2Object,
|
|
150
|
+
): value is globalThis.R2ObjectBody =>
|
|
151
|
+
"body" in value &&
|
|
152
|
+
typeof (value as globalThis.R2ObjectBody).arrayBuffer === "function" &&
|
|
153
|
+
typeof (value as globalThis.R2ObjectBody).bytes === "function" &&
|
|
154
|
+
typeof (value as globalThis.R2ObjectBody).text === "function" &&
|
|
155
|
+
typeof (value as globalThis.R2ObjectBody).json === "function" &&
|
|
156
|
+
typeof (value as globalThis.R2ObjectBody).blob === "function";
|
|
157
|
+
|
|
158
|
+
const wrapObjectBody = (binding: string, object: globalThis.R2ObjectBody): R2ObjectBodyClient => ({
|
|
159
|
+
key: object.key,
|
|
160
|
+
version: object.version,
|
|
161
|
+
size: object.size,
|
|
162
|
+
etag: object.etag,
|
|
163
|
+
httpEtag: object.httpEtag,
|
|
164
|
+
checksums: object.checksums,
|
|
165
|
+
uploaded: object.uploaded,
|
|
166
|
+
httpMetadata: object.httpMetadata,
|
|
167
|
+
customMetadata: object.customMetadata,
|
|
168
|
+
range: object.range,
|
|
169
|
+
storageClass: object.storageClass,
|
|
170
|
+
ssecKeyMd5: object.ssecKeyMd5,
|
|
171
|
+
writeHttpMetadata: (headers) => object.writeHttpMetadata(headers),
|
|
172
|
+
raw: object,
|
|
173
|
+
body: object.body,
|
|
174
|
+
get bodyUsed() {
|
|
175
|
+
return object.bodyUsed;
|
|
176
|
+
},
|
|
177
|
+
arrayBuffer: tryR2Promise(binding, "arrayBuffer", () => object.arrayBuffer()),
|
|
178
|
+
bytes: tryR2Promise(binding, "bytes", () => object.bytes()),
|
|
179
|
+
text: tryR2Promise(binding, "text", () => object.text()),
|
|
180
|
+
json: <T = unknown>() => tryR2Promise(binding, "json", () => object.json<T>()),
|
|
181
|
+
blob: tryR2Promise(binding, "blob", () => object.blob()),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const wrapGetResult = (
|
|
185
|
+
binding: string,
|
|
186
|
+
object: globalThis.R2ObjectBody | globalThis.R2Object | null,
|
|
187
|
+
): R2ObjectBodyClient | globalThis.R2Object | null => {
|
|
188
|
+
if (object === null || !isR2ObjectBody(object)) {
|
|
189
|
+
return object;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return wrapObjectBody(binding, object);
|
|
193
|
+
};
|
|
194
|
+
|
|
139
195
|
export const isR2Bucket = (value: unknown): value is globalThis.R2Bucket => {
|
|
140
196
|
if (typeof value !== "object" || value === null) {
|
|
141
197
|
return false;
|
|
@@ -172,43 +228,47 @@ export const makeClient = (
|
|
|
172
228
|
),
|
|
173
229
|
});
|
|
174
230
|
|
|
175
|
-
return (bucket) =>
|
|
176
|
-
|
|
177
|
-
head: (key) =>
|
|
178
|
-
tryR2Promise(definition.binding, "head", () => bucket.head(key)).pipe(Effect.map(maybe)),
|
|
179
|
-
get: ((key: string, options?: R2GetOptions) =>
|
|
231
|
+
return (bucket) => {
|
|
232
|
+
const get = ((key: string, options?: R2GetOptions) =>
|
|
180
233
|
tryR2Promise(definition.binding, "get", () => bucket.get(key, options)).pipe(
|
|
181
|
-
Effect.map(maybe),
|
|
182
|
-
)) as R2Client["get"]
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
234
|
+
Effect.map((object) => maybe(wrapGetResult(definition.binding, object))),
|
|
235
|
+
)) as R2Client["get"];
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
definition,
|
|
239
|
+
head: (key) =>
|
|
240
|
+
tryR2Promise(definition.binding, "head", () => bucket.head(key)).pipe(Effect.map(maybe)),
|
|
241
|
+
get,
|
|
242
|
+
put: ((key: string, value: R2PutValue, options?: R2PutOptions) =>
|
|
243
|
+
tryR2Promise(definition.binding, "put", () => bucket.put(key, value, options)).pipe(
|
|
244
|
+
Effect.map((object) => {
|
|
245
|
+
if (object === null) {
|
|
246
|
+
return Option.none<globalThis.R2Object>();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (options !== undefined && "onlyIf" in options) {
|
|
250
|
+
return Option.some(object);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return object;
|
|
254
|
+
}),
|
|
255
|
+
)) as R2Client["put"],
|
|
256
|
+
createMultipartUpload: (key, options) =>
|
|
257
|
+
tryR2Promise(definition.binding, "createMultipartUpload", () =>
|
|
258
|
+
bucket.createMultipartUpload(key, options),
|
|
259
|
+
).pipe(Effect.map(wrapUpload)),
|
|
260
|
+
resumeMultipartUpload: (key, uploadId) =>
|
|
261
|
+
tryR2Sync(definition.binding, "resumeMultipartUpload", () =>
|
|
262
|
+
wrapUpload(bucket.resumeMultipartUpload(key, uploadId)),
|
|
263
|
+
),
|
|
264
|
+
delete: (keys) => {
|
|
265
|
+
const nativeKeys = typeof keys === "string" ? keys : [...keys];
|
|
266
|
+
return tryR2Promise(definition.binding, "delete", () => bucket.delete(nativeKeys));
|
|
267
|
+
},
|
|
268
|
+
list: (options) => tryR2Promise(definition.binding, "list", () => bucket.list(options)),
|
|
269
|
+
unsafeRaw: Effect.succeed(bucket),
|
|
270
|
+
};
|
|
271
|
+
};
|
|
212
272
|
};
|
|
213
273
|
|
|
214
274
|
export const layer = <Self>(tag: Context.Service<Self, R2Client>, definition: R2Definition) =>
|