@vankyle/storage-s3 0.1.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/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # @vankyle-hub/storage-s3
2
+
3
+ `IStorage` implementation for any S3-compatible object storage backend.
4
+
5
+ ## Supported backends
6
+
7
+ - AWS S3
8
+ - Cloudflare R2 (S3-compatible HTTP API)
9
+ - MinIO
10
+ - DigitalOcean Spaces
11
+ - Backblaze B2 (S3-compatible)
12
+ - Any storage that speaks the S3 signature protocol
13
+
14
+ > **Cloudflare R2 Worker Binding:** If you are running inside a Cloudflare Worker and want to use `env.BUCKET` directly, use [`@vankyle-hub/storage-cloudflare`](../cloudflare/README.md) instead.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pnpm add @vankyle-hub/storage-s3 @vankyle-hub/storage-core @vankyle-hub/storage-shared
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### AWS S3
25
+
26
+ ```typescript
27
+ import { S3Storage } from "@vankyle-hub/storage-s3";
28
+
29
+ const storage = new S3Storage({
30
+ clientConfig: {
31
+ region: "us-east-1",
32
+ credentials: {
33
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
34
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
35
+ },
36
+ },
37
+ });
38
+ ```
39
+
40
+ ### Cloudflare R2 (S3 API)
41
+
42
+ ```typescript
43
+ const storage = new S3Storage({
44
+ clientConfig: {
45
+ region: "auto",
46
+ endpoint: `https://${process.env.CF_ACCOUNT_ID}.r2.cloudflarestorage.com`,
47
+ credentials: {
48
+ accessKeyId: process.env.R2_ACCESS_KEY_ID!,
49
+ secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
50
+ },
51
+ },
52
+ forcePathStyle: true,
53
+ });
54
+ ```
55
+
56
+ ### MinIO
57
+
58
+ ```typescript
59
+ const storage = new S3Storage({
60
+ clientConfig: {
61
+ region: "us-east-1",
62
+ endpoint: "http://localhost:9000",
63
+ credentials: {
64
+ accessKeyId: "minioadmin",
65
+ secretAccessKey: "minioadmin",
66
+ },
67
+ },
68
+ forcePathStyle: true,
69
+ });
70
+ ```
71
+
72
+ ## Capabilities
73
+
74
+ | Capability | Supported |
75
+ |---|---|
76
+ | `multipartUpload` | ✓ |
77
+ | `signedReadUrl` | ✓ |
78
+ | `signedPutUrl` | ✓ |
79
+ | `signedPartUrl` | ✓ |
80
+ | `serverSideCopy` | ✗ |
81
+
82
+ All four URL types use `@aws-sdk/s3-request-presigner`.
83
+
84
+ ## Options reference
85
+
86
+ ```typescript
87
+ interface S3StorageOptions {
88
+ /**
89
+ * Passed directly to the AWS SDK S3Client constructor.
90
+ * Set endpoint, region, credentials, etc. here.
91
+ */
92
+ clientConfig: S3ClientConfig;
93
+
94
+ /**
95
+ * Use path-style URLs instead of virtual-hosted style.
96
+ * Required for MinIO and some S3-compatible services.
97
+ * Default: false
98
+ */
99
+ forcePathStyle?: boolean;
100
+ }
101
+ ```
102
+
103
+ ## Multipart upload
104
+
105
+ `S3Storage` maps the `IStorage` multipart lifecycle directly to S3 multipart:
106
+
107
+ | `IStorage` method | S3 API |
108
+ |---|---|
109
+ | `initUploadSession` | `CreateMultipartUpload` |
110
+ | `uploadPart` | `UploadPart` |
111
+ | `completeUploadSession` | `CompleteMultipartUpload` |
112
+ | `abortUploadSession` | `AbortMultipartUpload` |
113
+
114
+ The `providerUploadId` field on `InitUploadSessionResult` is the S3 `UploadId`.
@@ -0,0 +1,3 @@
1
+ export { S3Storage } from "./storage/index.js";
2
+ export type { S3StorageOptions } from "./types/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { S3Storage } from "./storage/index.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { mapS3HeadToCore } from "./s3-head-to-core.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mappers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { mapS3HeadToCore } from "./s3-head-to-core.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mappers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { HeadObjectCommandOutput } from "@aws-sdk/client-s3";
2
+ import type { HeadObjectResult } from "@vankyle-hub/storage-core";
3
+ export declare function mapS3HeadToCore(output: HeadObjectCommandOutput): HeadObjectResult;
4
+ //# sourceMappingURL=s3-head-to-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-head-to-core.d.ts","sourceRoot":"","sources":["../../src/mappers/s3-head-to-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wBAAgB,eAAe,CAAC,MAAM,EAAE,uBAAuB,GAAG,gBAAgB,CAQjF"}
@@ -0,0 +1,10 @@
1
+ export function mapS3HeadToCore(output) {
2
+ return {
3
+ contentType: output.ContentType,
4
+ contentLength: output.ContentLength,
5
+ etag: output.ETag,
6
+ lastModified: output.LastModified,
7
+ metadata: output.Metadata,
8
+ };
9
+ }
10
+ //# sourceMappingURL=s3-head-to-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-head-to-core.js","sourceRoot":"","sources":["../../src/mappers/s3-head-to-core.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,MAA+B;IAC7D,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { S3Storage } from "./s3-storage.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { S3Storage } from "./s3-storage.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type IStorage, type StorageCapabilities, type PutObjectInput, type PutObjectResult, type GetObjectInput, type GetObjectResult, type HeadObjectInput, type HeadObjectResult, type DeleteObjectInput, type InitUploadSessionInput, type InitUploadSessionResult, type UploadPartInput, type UploadPartResult, type CompleteUploadSessionInput, type CompleteUploadSessionResult, type AbortUploadSessionInput, type CreateReadUrlInput, type CreatePutUrlInput, type CreateUploadPartUrlInput, type SignedAccess } from "@vankyle-hub/storage-core";
2
+ import type { S3StorageOptions } from "../types/s3-options.js";
3
+ export declare class S3Storage implements IStorage {
4
+ readonly provider: "s3";
5
+ readonly capabilities: StorageCapabilities;
6
+ private readonly client;
7
+ constructor(options: S3StorageOptions);
8
+ putObject(input: PutObjectInput): Promise<PutObjectResult>;
9
+ getObject(input: GetObjectInput): Promise<GetObjectResult>;
10
+ headObject(input: HeadObjectInput): Promise<HeadObjectResult>;
11
+ deleteObject(input: DeleteObjectInput): Promise<void>;
12
+ initUploadSession(input: InitUploadSessionInput): Promise<InitUploadSessionResult>;
13
+ uploadPart(input: UploadPartInput): Promise<UploadPartResult>;
14
+ completeUploadSession(input: CompleteUploadSessionInput): Promise<CompleteUploadSessionResult>;
15
+ abortUploadSession(input: AbortUploadSessionInput): Promise<void>;
16
+ createReadUrl(input: CreateReadUrlInput): Promise<SignedAccess>;
17
+ createPutUrl(input: CreatePutUrlInput): Promise<SignedAccess>;
18
+ createUploadPartUrl(input: CreateUploadPartUrlInput): Promise<SignedAccess>;
19
+ }
20
+ //# sourceMappingURL=s3-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-storage.d.ts","sourceRoot":"","sources":["../../src/storage/s3-storage.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EAClB,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D,qBAAa,SAAU,YAAW,QAAQ;IACxC,QAAQ,CAAC,QAAQ,OAAsB;IACvC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAKxC;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;gBAEtB,OAAO,EAAE,gBAAgB;IAU/B,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAuB1D,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA0B1D,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiB7D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD,iBAAiB,CACrB,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;IAmB7B,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4B7D,qBAAqB,CACzB,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,2BAA2B,CAAC;IAqBjC,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjE,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IAkB/D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAiB7D,mBAAmB,CACvB,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,YAAY,CAAC;CAiBzB"}
@@ -0,0 +1,214 @@
1
+ import { S3Client, PutObjectCommand, GetObjectCommand, HeadObjectCommand, DeleteObjectCommand, CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand, AbortMultipartUploadCommand, } from "@aws-sdk/client-s3";
2
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
3
+ import { StorageProvider, } from "@vankyle-hub/storage-core";
4
+ import { StorageError, StorageObjectNotFoundError, } from "@vankyle-hub/storage-shared";
5
+ import { mapS3HeadToCore } from "../mappers/s3-head-to-core.js";
6
+ const DEFAULT_EXPIRES_IN = 3600; // 1 hour
7
+ export class S3Storage {
8
+ provider = StorageProvider.S3;
9
+ capabilities = {
10
+ multipartUpload: true,
11
+ signedReadUrl: true,
12
+ signedPutUrl: true,
13
+ signedPartUrl: true,
14
+ };
15
+ client;
16
+ constructor(options) {
17
+ const config = {
18
+ ...options.clientConfig,
19
+ };
20
+ if (options.forcePathStyle !== undefined) {
21
+ config.forcePathStyle = options.forcePathStyle;
22
+ }
23
+ this.client = new S3Client(config);
24
+ }
25
+ async putObject(input) {
26
+ const body = input.body instanceof Uint8Array
27
+ ? input.body
28
+ : await streamToBuffer(input.body);
29
+ const result = await this.client.send(new PutObjectCommand({
30
+ Bucket: input.bucket,
31
+ Key: input.objectKey,
32
+ Body: body,
33
+ ContentType: input.contentType,
34
+ ContentLength: input.contentLength,
35
+ ChecksumSHA256: input.sha256,
36
+ Metadata: input.metadata,
37
+ }));
38
+ return {
39
+ etag: result.ETag,
40
+ versionId: result.VersionId,
41
+ };
42
+ }
43
+ async getObject(input) {
44
+ const range = input.range
45
+ ? `bytes=${input.range.start}-${input.range.end ?? ""}`
46
+ : undefined;
47
+ const result = await this.client.send(new GetObjectCommand({
48
+ Bucket: input.bucket,
49
+ Key: input.objectKey,
50
+ Range: range,
51
+ }));
52
+ if (!result.Body) {
53
+ throw new StorageObjectNotFoundError(input.bucket, input.objectKey);
54
+ }
55
+ return {
56
+ body: result.Body.transformToWebStream(),
57
+ contentType: result.ContentType,
58
+ contentLength: result.ContentLength,
59
+ etag: result.ETag,
60
+ metadata: result.Metadata,
61
+ };
62
+ }
63
+ async headObject(input) {
64
+ try {
65
+ const result = await this.client.send(new HeadObjectCommand({
66
+ Bucket: input.bucket,
67
+ Key: input.objectKey,
68
+ }));
69
+ return mapS3HeadToCore(result);
70
+ }
71
+ catch (error) {
72
+ if (isNotFoundError(error)) {
73
+ throw new StorageObjectNotFoundError(input.bucket, input.objectKey, { cause: error });
74
+ }
75
+ throw new StorageError("Failed to head object", { cause: error });
76
+ }
77
+ }
78
+ async deleteObject(input) {
79
+ await this.client.send(new DeleteObjectCommand({
80
+ Bucket: input.bucket,
81
+ Key: input.objectKey,
82
+ }));
83
+ }
84
+ async initUploadSession(input) {
85
+ const result = await this.client.send(new CreateMultipartUploadCommand({
86
+ Bucket: input.bucket,
87
+ Key: input.objectKey,
88
+ ContentType: input.contentType,
89
+ Metadata: input.metadata,
90
+ }));
91
+ if (!result.UploadId) {
92
+ throw new StorageError("Failed to create multipart upload: no UploadId returned");
93
+ }
94
+ return {
95
+ providerUploadId: result.UploadId,
96
+ };
97
+ }
98
+ async uploadPart(input) {
99
+ const body = input.body instanceof Uint8Array
100
+ ? input.body
101
+ : await streamToBuffer(input.body);
102
+ const result = await this.client.send(new UploadPartCommand({
103
+ Bucket: input.bucket,
104
+ Key: input.objectKey,
105
+ UploadId: input.providerUploadId,
106
+ PartNumber: input.partNumber,
107
+ Body: body,
108
+ ContentLength: input.contentLength,
109
+ }));
110
+ if (!result.ETag) {
111
+ throw new StorageError("Failed to upload part: no ETag returned");
112
+ }
113
+ return {
114
+ etag: result.ETag,
115
+ partNumber: input.partNumber,
116
+ size: body.byteLength,
117
+ checksumSha256: result.ChecksumSHA256,
118
+ };
119
+ }
120
+ async completeUploadSession(input) {
121
+ const result = await this.client.send(new CompleteMultipartUploadCommand({
122
+ Bucket: input.bucket,
123
+ Key: input.objectKey,
124
+ UploadId: input.providerUploadId,
125
+ MultipartUpload: {
126
+ Parts: input.parts.map((p) => ({
127
+ PartNumber: p.partNumber,
128
+ ETag: p.etag,
129
+ })),
130
+ },
131
+ }));
132
+ return {
133
+ etag: result.ETag,
134
+ versionId: result.VersionId,
135
+ };
136
+ }
137
+ async abortUploadSession(input) {
138
+ await this.client.send(new AbortMultipartUploadCommand({
139
+ Bucket: input.bucket,
140
+ Key: input.objectKey,
141
+ UploadId: input.providerUploadId,
142
+ }));
143
+ }
144
+ async createReadUrl(input) {
145
+ const expiresIn = input.expiresInSeconds ?? DEFAULT_EXPIRES_IN;
146
+ const command = new GetObjectCommand({
147
+ Bucket: input.bucket,
148
+ Key: input.objectKey,
149
+ ResponseContentType: input.responseContentType,
150
+ ResponseContentDisposition: input.responseContentDisposition,
151
+ });
152
+ const url = await getSignedUrl(this.client, command, { expiresIn });
153
+ return {
154
+ url,
155
+ method: "GET",
156
+ expiresAt: new Date(Date.now() + expiresIn * 1000),
157
+ };
158
+ }
159
+ async createPutUrl(input) {
160
+ const expiresIn = input.expiresInSeconds ?? DEFAULT_EXPIRES_IN;
161
+ const command = new PutObjectCommand({
162
+ Bucket: input.bucket,
163
+ Key: input.objectKey,
164
+ ContentType: input.contentType,
165
+ });
166
+ const url = await getSignedUrl(this.client, command, { expiresIn });
167
+ return {
168
+ url,
169
+ method: "PUT",
170
+ expiresAt: new Date(Date.now() + expiresIn * 1000),
171
+ };
172
+ }
173
+ async createUploadPartUrl(input) {
174
+ const expiresIn = input.expiresInSeconds ?? DEFAULT_EXPIRES_IN;
175
+ const command = new UploadPartCommand({
176
+ Bucket: input.bucket,
177
+ Key: input.objectKey,
178
+ UploadId: input.providerUploadId,
179
+ PartNumber: input.partNumber,
180
+ });
181
+ const url = await getSignedUrl(this.client, command, { expiresIn });
182
+ return {
183
+ url,
184
+ method: "PUT",
185
+ expiresAt: new Date(Date.now() + expiresIn * 1000),
186
+ };
187
+ }
188
+ }
189
+ async function streamToBuffer(stream) {
190
+ const reader = stream.getReader();
191
+ const chunks = [];
192
+ let totalLength = 0;
193
+ for (;;) {
194
+ const { done, value } = await reader.read();
195
+ if (done)
196
+ break;
197
+ chunks.push(value);
198
+ totalLength += value.byteLength;
199
+ }
200
+ const result = new Uint8Array(totalLength);
201
+ let offset = 0;
202
+ for (const chunk of chunks) {
203
+ result.set(chunk, offset);
204
+ offset += chunk.byteLength;
205
+ }
206
+ return result;
207
+ }
208
+ function isNotFoundError(error) {
209
+ return (typeof error === "object" &&
210
+ error !== null &&
211
+ "name" in error &&
212
+ error.name === "NotFound");
213
+ }
214
+ //# sourceMappingURL=s3-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-storage.js","sourceRoot":"","sources":["../../src/storage/s3-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export type { S3StorageOptions } from "./s3-options.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { S3ClientConfig } from "@aws-sdk/client-s3";
2
+ export interface S3StorageOptions {
3
+ readonly clientConfig: S3ClientConfig;
4
+ readonly forcePathStyle?: boolean | undefined;
5
+ }
6
+ //# sourceMappingURL=s3-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-options.d.ts","sourceRoot":"","sources":["../../src/types/s3-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=s3-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-options.js","sourceRoot":"","sources":["../../src/types/s3-options.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@vankyle/storage-s3",
3
+ "version": "0.1.0",
4
+ "description": "S3-compatible object storage adapter for vankyle-storage.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc -b tsconfig.json --force",
19
+ "clean": "rimraf dist tsconfig.tsbuildinfo",
20
+ "typecheck": "tsc -p tsconfig.json --noEmit"
21
+ },
22
+ "license": "MPL-2.0",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/Vankyle-Hub/storage-ts.git",
26
+ "directory": "packages/s3"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/Vankyle-Hub/storage-ts/issues"
30
+ },
31
+ "homepage": "https://github.com/Vankyle-Hub/storage-ts",
32
+ "packageManager": "pnpm@10.28.2",
33
+ "dependencies": {
34
+ "@vankyle/storage-core": "0.1.0",
35
+ "@vankyle/storage-shared": "0.1.0",
36
+ "@aws-sdk/client-s3": "^3.1006.0",
37
+ "@aws-sdk/s3-request-presigner": "^3.1006.0"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ }
42
+ }