@ayepi/aws 0.4.1 → 0.5.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/ayepi-aws.md +4 -2
- package/dist/s3.cjs +7 -3
- package/dist/s3.d.cts +1 -1
- package/dist/s3.d.ts +1 -1
- package/dist/s3.js +7 -3
- package/package.json +8 -8
package/ayepi-aws.md
CHANGED
|
@@ -55,7 +55,7 @@ interface S3FilesOptions extends ResilientOptions {
|
|
|
55
55
|
/** @internal Upload seam (default: `@aws-sdk/lib-storage` multipart `Upload`) — injectable for tests. */
|
|
56
56
|
readonly upload?: (key: string, body: FileBody, contentType?: string, metadata?: Record<string, string>) => Promise<void>;
|
|
57
57
|
/** @internal Presign seam (default: `@aws-sdk/s3-request-presigner`) — injectable for tests. */
|
|
58
|
-
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string) => Promise<string>;
|
|
58
|
+
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string, sha256?: string) => Promise<string>;
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
@@ -110,7 +110,9 @@ Behavior of each method:
|
|
|
110
110
|
`modifiedAt` but **no `contentType`** (ListObjectsV2 doesn't return it).
|
|
111
111
|
- **`presignDownload(key, opts?)`** — a presigned `GET` URL (default expiry **900 s**).
|
|
112
112
|
- **`presignUpload(key, opts?)`** — a presigned `PUT` URL (default expiry **900 s**); `opts.contentType`
|
|
113
|
-
pins the `Content-Type` the upload must use.
|
|
113
|
+
pins the `Content-Type` the upload must use; `opts.sha256` (hex) is signed as the object's
|
|
114
|
+
`x-amz-checksum-sha256`, so S3 refuses bytes that hash otherwise. A presigned `PUT` cannot cap a
|
|
115
|
+
body, so `opts.maxSize` rejects (use the files server, or a size check after upload).
|
|
114
116
|
|
|
115
117
|
**Not-found handling.** S3 surfaces a missing key differently per op (`NoSuchKey` on GET,
|
|
116
118
|
`NotFound` on HEAD). The store treats an error as not-found when its `name` is `NoSuchKey` or
|
package/dist/s3.cjs
CHANGED
|
@@ -53,13 +53,14 @@ function s3Files(opts) {
|
|
|
53
53
|
Metadata: metadata
|
|
54
54
|
}
|
|
55
55
|
}).done().then(() => void 0);
|
|
56
|
-
const sdkPresign = (kind, key, expiresIn, contentType) => (0, _aws_sdk_s3_request_presigner.getSignedUrl)(client, kind === "get" ? new _aws_sdk_client_s3.GetObjectCommand({
|
|
56
|
+
const sdkPresign = (kind, key, expiresIn, contentType, sha256) => (0, _aws_sdk_s3_request_presigner.getSignedUrl)(client, kind === "get" ? new _aws_sdk_client_s3.GetObjectCommand({
|
|
57
57
|
Bucket: bucket,
|
|
58
58
|
Key: k(key)
|
|
59
59
|
}) : new _aws_sdk_client_s3.PutObjectCommand({
|
|
60
60
|
Bucket: bucket,
|
|
61
61
|
Key: k(key),
|
|
62
|
-
ContentType: contentType
|
|
62
|
+
ContentType: contentType,
|
|
63
|
+
ChecksumSHA256: sha256 === void 0 ? void 0 : Buffer.from(sha256, "hex").toString("base64")
|
|
63
64
|
}), { expiresIn });
|
|
64
65
|
/* v8 ignore stop */
|
|
65
66
|
const upload = opts.upload ?? sdkUpload;
|
|
@@ -131,7 +132,10 @@ function s3Files(opts) {
|
|
|
131
132
|
};
|
|
132
133
|
}),
|
|
133
134
|
presignDownload: (key, o) => presign("get", key, o?.expiresIn ?? DEFAULT_EXPIRES_IN),
|
|
134
|
-
presignUpload: (key, o) =>
|
|
135
|
+
presignUpload: (key, o) => {
|
|
136
|
+
if (o?.maxSize !== void 0) return Promise.reject(/* @__PURE__ */ new Error("s3Files: a presigned PUT cannot cap the upload size (maxSize)"));
|
|
137
|
+
return presign("put", key, o?.expiresIn ?? DEFAULT_EXPIRES_IN, o?.contentType, o?.sha256?.toLowerCase());
|
|
138
|
+
}
|
|
135
139
|
};
|
|
136
140
|
}
|
|
137
141
|
//#endregion
|
package/dist/s3.d.cts
CHANGED
|
@@ -15,7 +15,7 @@ interface S3FilesOptions extends ResilientOptions {
|
|
|
15
15
|
/** @internal Upload seam (default: `@aws-sdk/lib-storage` multipart `Upload`) — injectable for tests. */
|
|
16
16
|
readonly upload?: (key: string, body: FileBody, contentType?: string, metadata?: Record<string, string>) => Promise<void>;
|
|
17
17
|
/** @internal Presign seam (default: `@aws-sdk/s3-request-presigner`) — injectable for tests. */
|
|
18
|
-
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string) => Promise<string>;
|
|
18
|
+
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string, sha256?: string) => Promise<string>;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Create an S3-backed {@link FileStore} (and {@link Presigner}). Pass a configured `S3Client`
|
package/dist/s3.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ interface S3FilesOptions extends ResilientOptions {
|
|
|
15
15
|
/** @internal Upload seam (default: `@aws-sdk/lib-storage` multipart `Upload`) — injectable for tests. */
|
|
16
16
|
readonly upload?: (key: string, body: FileBody, contentType?: string, metadata?: Record<string, string>) => Promise<void>;
|
|
17
17
|
/** @internal Presign seam (default: `@aws-sdk/s3-request-presigner`) — injectable for tests. */
|
|
18
|
-
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string) => Promise<string>;
|
|
18
|
+
readonly presign?: (kind: 'get' | 'put', key: string, expiresIn: number, contentType?: string, sha256?: string) => Promise<string>;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Create an S3-backed {@link FileStore} (and {@link Presigner}). Pass a configured `S3Client`
|
package/dist/s3.js
CHANGED
|
@@ -52,13 +52,14 @@ function s3Files(opts) {
|
|
|
52
52
|
Metadata: metadata
|
|
53
53
|
}
|
|
54
54
|
}).done().then(() => void 0);
|
|
55
|
-
const sdkPresign = (kind, key, expiresIn, contentType) => getSignedUrl(client, kind === "get" ? new GetObjectCommand({
|
|
55
|
+
const sdkPresign = (kind, key, expiresIn, contentType, sha256) => getSignedUrl(client, kind === "get" ? new GetObjectCommand({
|
|
56
56
|
Bucket: bucket,
|
|
57
57
|
Key: k(key)
|
|
58
58
|
}) : new PutObjectCommand({
|
|
59
59
|
Bucket: bucket,
|
|
60
60
|
Key: k(key),
|
|
61
|
-
ContentType: contentType
|
|
61
|
+
ContentType: contentType,
|
|
62
|
+
ChecksumSHA256: sha256 === void 0 ? void 0 : Buffer.from(sha256, "hex").toString("base64")
|
|
62
63
|
}), { expiresIn });
|
|
63
64
|
/* v8 ignore stop */
|
|
64
65
|
const upload = opts.upload ?? sdkUpload;
|
|
@@ -130,7 +131,10 @@ function s3Files(opts) {
|
|
|
130
131
|
};
|
|
131
132
|
}),
|
|
132
133
|
presignDownload: (key, o) => presign("get", key, o?.expiresIn ?? DEFAULT_EXPIRES_IN),
|
|
133
|
-
presignUpload: (key, o) =>
|
|
134
|
+
presignUpload: (key, o) => {
|
|
135
|
+
if (o?.maxSize !== void 0) return Promise.reject(/* @__PURE__ */ new Error("s3Files: a presigned PUT cannot cap the upload size (maxSize)"));
|
|
136
|
+
return presign("put", key, o?.expiresIn ?? DEFAULT_EXPIRES_IN, o?.contentType, o?.sha256?.toLowerCase());
|
|
137
|
+
}
|
|
134
138
|
};
|
|
135
139
|
}
|
|
136
140
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ayepi/aws",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "AWS backends for ayepi — an SQS @ayepi/work queue (large payloads offloaded to S3) and an S3 @ayepi/files store, all retry-wrapped for throttle resilience",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"@aws-sdk/lib-storage": "^3",
|
|
74
74
|
"@aws-sdk/s3-request-presigner": "^3",
|
|
75
75
|
"@smithy/node-http-handler": "^4",
|
|
76
|
-
"@ayepi/core": "^0.
|
|
77
|
-
"@ayepi/files": "^0.
|
|
78
|
-
"@ayepi/work": "^0.
|
|
76
|
+
"@ayepi/core": "^0.5.0",
|
|
77
|
+
"@ayepi/files": "^0.5.0",
|
|
78
|
+
"@ayepi/work": "^0.5.0"
|
|
79
79
|
},
|
|
80
80
|
"peerDependenciesMeta": {
|
|
81
81
|
"@ayepi/work": {
|
|
@@ -111,10 +111,10 @@
|
|
|
111
111
|
"testcontainers": "^10.13.0",
|
|
112
112
|
"tsdown": "^0.12.0",
|
|
113
113
|
"vitest": "^2.1.8",
|
|
114
|
-
"zod": "^4.
|
|
115
|
-
"@ayepi/
|
|
116
|
-
"@ayepi/
|
|
117
|
-
"@ayepi/
|
|
114
|
+
"zod": "^4.6.7",
|
|
115
|
+
"@ayepi/work": "0.5.0",
|
|
116
|
+
"@ayepi/files": "0.5.0",
|
|
117
|
+
"@ayepi/core": "0.5.0"
|
|
118
118
|
},
|
|
119
119
|
"keywords": [
|
|
120
120
|
"ayepi",
|