@forklaunch/infrastructure-s3 0.0.7 → 0.0.8

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.
@@ -163,12 +163,12 @@ export class S3ObjectStore implements ObjectStore<S3Client> {
163
163
  const resp = await this.s3.send(
164
164
  new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })
165
165
  );
166
- const body = resp.Body as Readable;
167
- const chunks: Buffer[] = [];
168
- for await (const chunk of body) {
169
- chunks.push(chunk);
166
+
167
+ if (!resp.Body) {
168
+ throw new Error('S3 did not return a body');
170
169
  }
171
- return JSON.parse(Buffer.concat(chunks).toString()) as T;
170
+
171
+ return JSON.parse(await resp.Body.transformToString()) as T;
172
172
  }
173
173
 
174
174
  /**
package/lib/index.js CHANGED
@@ -134,12 +134,10 @@ var S3ObjectStore = class {
134
134
  const resp = await this.s3.send(
135
135
  new import_client_s3.GetObjectCommand({ Bucket: this.bucket, Key: objectKey })
136
136
  );
137
- const body = resp.Body;
138
- const chunks = [];
139
- for await (const chunk of body) {
140
- chunks.push(chunk);
137
+ if (!resp.Body) {
138
+ throw new Error("S3 did not return a body");
141
139
  }
142
- return JSON.parse(Buffer.concat(chunks).toString());
140
+ return JSON.parse(await resp.Body.transformToString());
143
141
  }
144
142
  /**
145
143
  * Reads multiple objects from the S3 bucket.
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n DeleteObjectCommand,\n DeleteObjectsCommand,\n DeleteObjectsCommandInput,\n GetObjectCommand,\n PutObjectCommand,\n PutObjectCommandInput,\n S3Client\n} from '@aws-sdk/client-s3';\nimport {\n MetricsDefinition,\n OpenTelemetryCollector,\n TelemetryOptions\n} from '@forklaunch/core/http';\nimport { ObjectStore } from '@forklaunch/core/objectstore';\nimport { Readable } from 'stream';\n\n/**\n * Options for configuring the S3ObjectStore.\n *\n * @example\n * const options: S3ObjectStoreOptions = {\n * bucket: 'my-bucket',\n * clientConfig: { region: 'us-west-2' }\n * };\n */\ninterface S3ObjectStoreOptions {\n /** The S3 bucket name. */\n bucket: string;\n /** Optional existing S3 client instance. */\n client?: S3Client;\n /** Optional configuration for creating a new S3 client. */\n clientConfig?: ConstructorParameters<typeof S3Client>[0];\n}\n\n/**\n * S3-backed implementation of the ObjectStore interface.\n * Provides methods for storing, retrieving, streaming, and deleting objects in S3.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n * const user = await store.readObject<{ name: string }>('user-1');\n */\nexport class S3ObjectStore implements ObjectStore<S3Client> {\n private s3: S3Client;\n private bucket: string;\n\n /**\n * Creates a new S3ObjectStore instance.\n * @param openTelemetryCollector - Collector for OpenTelemetry metrics.\n * @param options - S3 configuration options.\n * @param telemetryOptions - Telemetry configuration options.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n */\n constructor(\n private openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,\n options: S3ObjectStoreOptions,\n private telemetryOptions: TelemetryOptions\n ) {\n this.s3 = options.client || new S3Client(options.clientConfig || {});\n this.bucket = options.bucket;\n }\n\n /**\n * Stores an object in the S3 bucket.\n * @template T - The type of the object being stored.\n * @param object - The object to store. Must include a `key` property.\n *\n * @example\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n */\n async putObject<T>(object: T & { key: string }): Promise<void> {\n const { key, ...rest } = object;\n const params: PutObjectCommandInput = {\n Bucket: this.bucket,\n Key: key,\n Body: JSON.stringify(rest),\n ContentType: 'application/json'\n };\n await this.s3.send(new PutObjectCommand(params));\n }\n\n /**\n * Stores multiple objects in the S3 bucket.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to store. Each must include a `key` property.\n *\n * @example\n * await store.putBatchObjects([\n * { key: 'user-1', name: 'Alice' },\n * { key: 'user-2', name: 'Bob' }\n * ]);\n */\n async putBatchObjects<T>(objects: (T & { key: string })[]): Promise<void> {\n await Promise.all(objects.map((obj) => this.putObject(obj)));\n }\n\n /**\n * Streams an object upload to the S3 bucket.\n * For compatibility; uses putObject internally.\n * @template T - The type of the object being stored.\n * @param object - The object to stream-upload. Must include a `key` property.\n */\n async streamUploadObject<T>(object: T & { key: string }): Promise<void> {\n await this.putObject(object);\n }\n\n /**\n * Streams multiple object uploads to the S3 bucket.\n * For compatibility; uses putBatchObjects internally.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to stream-upload. Each must include a `key` property.\n */\n async streamUploadBatchObjects<T>(\n objects: (T & { key: string })[]\n ): Promise<void> {\n await this.putBatchObjects(objects);\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param objectKey - The key of the object to delete.\n *\n * @example\n * await store.deleteObject('user-1');\n */\n async deleteObject(objectKey: string): Promise<void> {\n await this.s3.send(\n new DeleteObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n }\n\n /**\n * Deletes multiple objects from the S3 bucket.\n * @param objectKeys - The keys of the objects to delete.\n *\n * @example\n * await store.deleteBatchObjects(['user-1', 'user-2']);\n */\n async deleteBatchObjects(objectKeys: string[]): Promise<void> {\n const params: DeleteObjectsCommandInput = {\n Bucket: this.bucket,\n Delete: {\n Objects: objectKeys.map((Key) => ({ Key }))\n }\n };\n await this.s3.send(new DeleteObjectsCommand(params));\n }\n\n /**\n * Reads an object from the S3 bucket.\n * @template T - The expected type of the object.\n * @param objectKey - The key of the object to read.\n * @returns The parsed object.\n *\n * @example\n * const user = await store.readObject<{ name: string }>('user-1');\n */\n async readObject<T>(objectKey: string): Promise<T> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n const body = resp.Body as Readable;\n const chunks: Buffer[] = [];\n for await (const chunk of body) {\n chunks.push(chunk);\n }\n return JSON.parse(Buffer.concat(chunks).toString()) as T;\n }\n\n /**\n * Reads multiple objects from the S3 bucket.\n * @template T - The expected type of the objects.\n * @param objectKeys - The keys of the objects to read.\n * @returns An array of parsed objects.\n *\n * @example\n * const users = await store.readBatchObjects<{ name: string }>(['user-1', 'user-2']);\n */\n async readBatchObjects<T>(objectKeys: string[]): Promise<T[]> {\n return Promise.all(objectKeys.map((key) => this.readObject<T>(key)));\n }\n\n /**\n * Streams an object download from the S3 bucket.\n * @param objectKey - The key of the object to download.\n * @returns A readable stream of the object's contents.\n * @throws If the S3 response does not include a readable stream.\n *\n * @example\n * const stream = await store.streamDownloadObject('user-1');\n * stream.pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadObject(objectKey: string): Promise<Readable> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n if (!resp.Body || !(resp.Body instanceof Readable)) {\n throw new Error('S3 did not return a stream');\n }\n return resp.Body;\n }\n\n /**\n * Streams multiple object downloads from the S3 bucket.\n * @param objectKeys - The keys of the objects to download.\n * @returns An array of readable streams.\n *\n * @example\n * const streams = await store.streamDownloadBatchObjects(['user-1', 'user-2']);\n * streams[0].pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadBatchObjects(objectKeys: string[]): Promise<Readable[]> {\n return Promise.all(objectKeys.map((key) => this.streamDownloadObject(key)));\n }\n\n /**\n * Gets the underlying S3 client instance.\n * @returns The S3Client instance used by this store.\n *\n * @example\n * const s3Client = store.getClient();\n */\n getClient(): S3Client {\n return this.s3;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n DeleteObjectCommand,\n DeleteObjectsCommand,\n DeleteObjectsCommandInput,\n GetObjectCommand,\n PutObjectCommand,\n PutObjectCommandInput,\n S3Client\n} from '@aws-sdk/client-s3';\nimport {\n MetricsDefinition,\n OpenTelemetryCollector,\n TelemetryOptions\n} from '@forklaunch/core/http';\nimport { ObjectStore } from '@forklaunch/core/objectstore';\nimport { Readable } from 'stream';\n\n/**\n * Options for configuring the S3ObjectStore.\n *\n * @example\n * const options: S3ObjectStoreOptions = {\n * bucket: 'my-bucket',\n * clientConfig: { region: 'us-west-2' }\n * };\n */\ninterface S3ObjectStoreOptions {\n /** The S3 bucket name. */\n bucket: string;\n /** Optional existing S3 client instance. */\n client?: S3Client;\n /** Optional configuration for creating a new S3 client. */\n clientConfig?: ConstructorParameters<typeof S3Client>[0];\n}\n\n/**\n * S3-backed implementation of the ObjectStore interface.\n * Provides methods for storing, retrieving, streaming, and deleting objects in S3.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n * const user = await store.readObject<{ name: string }>('user-1');\n */\nexport class S3ObjectStore implements ObjectStore<S3Client> {\n private s3: S3Client;\n private bucket: string;\n\n /**\n * Creates a new S3ObjectStore instance.\n * @param openTelemetryCollector - Collector for OpenTelemetry metrics.\n * @param options - S3 configuration options.\n * @param telemetryOptions - Telemetry configuration options.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n */\n constructor(\n private openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,\n options: S3ObjectStoreOptions,\n private telemetryOptions: TelemetryOptions\n ) {\n this.s3 = options.client || new S3Client(options.clientConfig || {});\n this.bucket = options.bucket;\n }\n\n /**\n * Stores an object in the S3 bucket.\n * @template T - The type of the object being stored.\n * @param object - The object to store. Must include a `key` property.\n *\n * @example\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n */\n async putObject<T>(object: T & { key: string }): Promise<void> {\n const { key, ...rest } = object;\n const params: PutObjectCommandInput = {\n Bucket: this.bucket,\n Key: key,\n Body: JSON.stringify(rest),\n ContentType: 'application/json'\n };\n await this.s3.send(new PutObjectCommand(params));\n }\n\n /**\n * Stores multiple objects in the S3 bucket.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to store. Each must include a `key` property.\n *\n * @example\n * await store.putBatchObjects([\n * { key: 'user-1', name: 'Alice' },\n * { key: 'user-2', name: 'Bob' }\n * ]);\n */\n async putBatchObjects<T>(objects: (T & { key: string })[]): Promise<void> {\n await Promise.all(objects.map((obj) => this.putObject(obj)));\n }\n\n /**\n * Streams an object upload to the S3 bucket.\n * For compatibility; uses putObject internally.\n * @template T - The type of the object being stored.\n * @param object - The object to stream-upload. Must include a `key` property.\n */\n async streamUploadObject<T>(object: T & { key: string }): Promise<void> {\n await this.putObject(object);\n }\n\n /**\n * Streams multiple object uploads to the S3 bucket.\n * For compatibility; uses putBatchObjects internally.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to stream-upload. Each must include a `key` property.\n */\n async streamUploadBatchObjects<T>(\n objects: (T & { key: string })[]\n ): Promise<void> {\n await this.putBatchObjects(objects);\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param objectKey - The key of the object to delete.\n *\n * @example\n * await store.deleteObject('user-1');\n */\n async deleteObject(objectKey: string): Promise<void> {\n await this.s3.send(\n new DeleteObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n }\n\n /**\n * Deletes multiple objects from the S3 bucket.\n * @param objectKeys - The keys of the objects to delete.\n *\n * @example\n * await store.deleteBatchObjects(['user-1', 'user-2']);\n */\n async deleteBatchObjects(objectKeys: string[]): Promise<void> {\n const params: DeleteObjectsCommandInput = {\n Bucket: this.bucket,\n Delete: {\n Objects: objectKeys.map((Key) => ({ Key }))\n }\n };\n await this.s3.send(new DeleteObjectsCommand(params));\n }\n\n /**\n * Reads an object from the S3 bucket.\n * @template T - The expected type of the object.\n * @param objectKey - The key of the object to read.\n * @returns The parsed object.\n *\n * @example\n * const user = await store.readObject<{ name: string }>('user-1');\n */\n async readObject<T>(objectKey: string): Promise<T> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n\n if (!resp.Body) {\n throw new Error('S3 did not return a body');\n }\n\n return JSON.parse(await resp.Body.transformToString()) as T;\n }\n\n /**\n * Reads multiple objects from the S3 bucket.\n * @template T - The expected type of the objects.\n * @param objectKeys - The keys of the objects to read.\n * @returns An array of parsed objects.\n *\n * @example\n * const users = await store.readBatchObjects<{ name: string }>(['user-1', 'user-2']);\n */\n async readBatchObjects<T>(objectKeys: string[]): Promise<T[]> {\n return Promise.all(objectKeys.map((key) => this.readObject<T>(key)));\n }\n\n /**\n * Streams an object download from the S3 bucket.\n * @param objectKey - The key of the object to download.\n * @returns A readable stream of the object's contents.\n * @throws If the S3 response does not include a readable stream.\n *\n * @example\n * const stream = await store.streamDownloadObject('user-1');\n * stream.pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadObject(objectKey: string): Promise<Readable> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n if (!resp.Body || !(resp.Body instanceof Readable)) {\n throw new Error('S3 did not return a stream');\n }\n return resp.Body;\n }\n\n /**\n * Streams multiple object downloads from the S3 bucket.\n * @param objectKeys - The keys of the objects to download.\n * @returns An array of readable streams.\n *\n * @example\n * const streams = await store.streamDownloadBatchObjects(['user-1', 'user-2']);\n * streams[0].pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadBatchObjects(objectKeys: string[]): Promise<Readable[]> {\n return Promise.all(objectKeys.map((key) => this.streamDownloadObject(key)));\n }\n\n /**\n * Gets the underlying S3 client instance.\n * @returns The S3Client instance used by this store.\n *\n * @example\n * const s3Client = store.getClient();\n */\n getClient(): S3Client {\n return this.s3;\n }\n}\n"],"mappings":"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","names":[]}
package/lib/index.mjs CHANGED
@@ -116,12 +116,10 @@ var S3ObjectStore = class {
116
116
  const resp = await this.s3.send(
117
117
  new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })
118
118
  );
119
- const body = resp.Body;
120
- const chunks = [];
121
- for await (const chunk of body) {
122
- chunks.push(chunk);
119
+ if (!resp.Body) {
120
+ throw new Error("S3 did not return a body");
123
121
  }
124
- return JSON.parse(Buffer.concat(chunks).toString());
122
+ return JSON.parse(await resp.Body.transformToString());
125
123
  }
126
124
  /**
127
125
  * Reads multiple objects from the S3 bucket.
package/lib/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n DeleteObjectCommand,\n DeleteObjectsCommand,\n DeleteObjectsCommandInput,\n GetObjectCommand,\n PutObjectCommand,\n PutObjectCommandInput,\n S3Client\n} from '@aws-sdk/client-s3';\nimport {\n MetricsDefinition,\n OpenTelemetryCollector,\n TelemetryOptions\n} from '@forklaunch/core/http';\nimport { ObjectStore } from '@forklaunch/core/objectstore';\nimport { Readable } from 'stream';\n\n/**\n * Options for configuring the S3ObjectStore.\n *\n * @example\n * const options: S3ObjectStoreOptions = {\n * bucket: 'my-bucket',\n * clientConfig: { region: 'us-west-2' }\n * };\n */\ninterface S3ObjectStoreOptions {\n /** The S3 bucket name. */\n bucket: string;\n /** Optional existing S3 client instance. */\n client?: S3Client;\n /** Optional configuration for creating a new S3 client. */\n clientConfig?: ConstructorParameters<typeof S3Client>[0];\n}\n\n/**\n * S3-backed implementation of the ObjectStore interface.\n * Provides methods for storing, retrieving, streaming, and deleting objects in S3.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n * const user = await store.readObject<{ name: string }>('user-1');\n */\nexport class S3ObjectStore implements ObjectStore<S3Client> {\n private s3: S3Client;\n private bucket: string;\n\n /**\n * Creates a new S3ObjectStore instance.\n * @param openTelemetryCollector - Collector for OpenTelemetry metrics.\n * @param options - S3 configuration options.\n * @param telemetryOptions - Telemetry configuration options.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n */\n constructor(\n private openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,\n options: S3ObjectStoreOptions,\n private telemetryOptions: TelemetryOptions\n ) {\n this.s3 = options.client || new S3Client(options.clientConfig || {});\n this.bucket = options.bucket;\n }\n\n /**\n * Stores an object in the S3 bucket.\n * @template T - The type of the object being stored.\n * @param object - The object to store. Must include a `key` property.\n *\n * @example\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n */\n async putObject<T>(object: T & { key: string }): Promise<void> {\n const { key, ...rest } = object;\n const params: PutObjectCommandInput = {\n Bucket: this.bucket,\n Key: key,\n Body: JSON.stringify(rest),\n ContentType: 'application/json'\n };\n await this.s3.send(new PutObjectCommand(params));\n }\n\n /**\n * Stores multiple objects in the S3 bucket.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to store. Each must include a `key` property.\n *\n * @example\n * await store.putBatchObjects([\n * { key: 'user-1', name: 'Alice' },\n * { key: 'user-2', name: 'Bob' }\n * ]);\n */\n async putBatchObjects<T>(objects: (T & { key: string })[]): Promise<void> {\n await Promise.all(objects.map((obj) => this.putObject(obj)));\n }\n\n /**\n * Streams an object upload to the S3 bucket.\n * For compatibility; uses putObject internally.\n * @template T - The type of the object being stored.\n * @param object - The object to stream-upload. Must include a `key` property.\n */\n async streamUploadObject<T>(object: T & { key: string }): Promise<void> {\n await this.putObject(object);\n }\n\n /**\n * Streams multiple object uploads to the S3 bucket.\n * For compatibility; uses putBatchObjects internally.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to stream-upload. Each must include a `key` property.\n */\n async streamUploadBatchObjects<T>(\n objects: (T & { key: string })[]\n ): Promise<void> {\n await this.putBatchObjects(objects);\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param objectKey - The key of the object to delete.\n *\n * @example\n * await store.deleteObject('user-1');\n */\n async deleteObject(objectKey: string): Promise<void> {\n await this.s3.send(\n new DeleteObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n }\n\n /**\n * Deletes multiple objects from the S3 bucket.\n * @param objectKeys - The keys of the objects to delete.\n *\n * @example\n * await store.deleteBatchObjects(['user-1', 'user-2']);\n */\n async deleteBatchObjects(objectKeys: string[]): Promise<void> {\n const params: DeleteObjectsCommandInput = {\n Bucket: this.bucket,\n Delete: {\n Objects: objectKeys.map((Key) => ({ Key }))\n }\n };\n await this.s3.send(new DeleteObjectsCommand(params));\n }\n\n /**\n * Reads an object from the S3 bucket.\n * @template T - The expected type of the object.\n * @param objectKey - The key of the object to read.\n * @returns The parsed object.\n *\n * @example\n * const user = await store.readObject<{ name: string }>('user-1');\n */\n async readObject<T>(objectKey: string): Promise<T> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n const body = resp.Body as Readable;\n const chunks: Buffer[] = [];\n for await (const chunk of body) {\n chunks.push(chunk);\n }\n return JSON.parse(Buffer.concat(chunks).toString()) as T;\n }\n\n /**\n * Reads multiple objects from the S3 bucket.\n * @template T - The expected type of the objects.\n * @param objectKeys - The keys of the objects to read.\n * @returns An array of parsed objects.\n *\n * @example\n * const users = await store.readBatchObjects<{ name: string }>(['user-1', 'user-2']);\n */\n async readBatchObjects<T>(objectKeys: string[]): Promise<T[]> {\n return Promise.all(objectKeys.map((key) => this.readObject<T>(key)));\n }\n\n /**\n * Streams an object download from the S3 bucket.\n * @param objectKey - The key of the object to download.\n * @returns A readable stream of the object's contents.\n * @throws If the S3 response does not include a readable stream.\n *\n * @example\n * const stream = await store.streamDownloadObject('user-1');\n * stream.pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadObject(objectKey: string): Promise<Readable> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n if (!resp.Body || !(resp.Body instanceof Readable)) {\n throw new Error('S3 did not return a stream');\n }\n return resp.Body;\n }\n\n /**\n * Streams multiple object downloads from the S3 bucket.\n * @param objectKeys - The keys of the objects to download.\n * @returns An array of readable streams.\n *\n * @example\n * const streams = await store.streamDownloadBatchObjects(['user-1', 'user-2']);\n * streams[0].pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadBatchObjects(objectKeys: string[]): Promise<Readable[]> {\n return Promise.all(objectKeys.map((key) => this.streamDownloadObject(key)));\n }\n\n /**\n * Gets the underlying S3 client instance.\n * @returns The S3Client instance used by this store.\n *\n * @example\n * const s3Client = store.getClient();\n */\n getClient(): S3Client {\n return this.s3;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n DeleteObjectCommand,\n DeleteObjectsCommand,\n DeleteObjectsCommandInput,\n GetObjectCommand,\n PutObjectCommand,\n PutObjectCommandInput,\n S3Client\n} from '@aws-sdk/client-s3';\nimport {\n MetricsDefinition,\n OpenTelemetryCollector,\n TelemetryOptions\n} from '@forklaunch/core/http';\nimport { ObjectStore } from '@forklaunch/core/objectstore';\nimport { Readable } from 'stream';\n\n/**\n * Options for configuring the S3ObjectStore.\n *\n * @example\n * const options: S3ObjectStoreOptions = {\n * bucket: 'my-bucket',\n * clientConfig: { region: 'us-west-2' }\n * };\n */\ninterface S3ObjectStoreOptions {\n /** The S3 bucket name. */\n bucket: string;\n /** Optional existing S3 client instance. */\n client?: S3Client;\n /** Optional configuration for creating a new S3 client. */\n clientConfig?: ConstructorParameters<typeof S3Client>[0];\n}\n\n/**\n * S3-backed implementation of the ObjectStore interface.\n * Provides methods for storing, retrieving, streaming, and deleting objects in S3.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n * const user = await store.readObject<{ name: string }>('user-1');\n */\nexport class S3ObjectStore implements ObjectStore<S3Client> {\n private s3: S3Client;\n private bucket: string;\n\n /**\n * Creates a new S3ObjectStore instance.\n * @param openTelemetryCollector - Collector for OpenTelemetry metrics.\n * @param options - S3 configuration options.\n * @param telemetryOptions - Telemetry configuration options.\n *\n * @example\n * const store = new S3ObjectStore(otelCollector, { bucket: 'my-bucket' }, telemetryOptions);\n */\n constructor(\n private openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,\n options: S3ObjectStoreOptions,\n private telemetryOptions: TelemetryOptions\n ) {\n this.s3 = options.client || new S3Client(options.clientConfig || {});\n this.bucket = options.bucket;\n }\n\n /**\n * Stores an object in the S3 bucket.\n * @template T - The type of the object being stored.\n * @param object - The object to store. Must include a `key` property.\n *\n * @example\n * await store.putObject({ key: 'user-1', name: 'Alice' });\n */\n async putObject<T>(object: T & { key: string }): Promise<void> {\n const { key, ...rest } = object;\n const params: PutObjectCommandInput = {\n Bucket: this.bucket,\n Key: key,\n Body: JSON.stringify(rest),\n ContentType: 'application/json'\n };\n await this.s3.send(new PutObjectCommand(params));\n }\n\n /**\n * Stores multiple objects in the S3 bucket.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to store. Each must include a `key` property.\n *\n * @example\n * await store.putBatchObjects([\n * { key: 'user-1', name: 'Alice' },\n * { key: 'user-2', name: 'Bob' }\n * ]);\n */\n async putBatchObjects<T>(objects: (T & { key: string })[]): Promise<void> {\n await Promise.all(objects.map((obj) => this.putObject(obj)));\n }\n\n /**\n * Streams an object upload to the S3 bucket.\n * For compatibility; uses putObject internally.\n * @template T - The type of the object being stored.\n * @param object - The object to stream-upload. Must include a `key` property.\n */\n async streamUploadObject<T>(object: T & { key: string }): Promise<void> {\n await this.putObject(object);\n }\n\n /**\n * Streams multiple object uploads to the S3 bucket.\n * For compatibility; uses putBatchObjects internally.\n * @template T - The type of the objects being stored.\n * @param objects - The objects to stream-upload. Each must include a `key` property.\n */\n async streamUploadBatchObjects<T>(\n objects: (T & { key: string })[]\n ): Promise<void> {\n await this.putBatchObjects(objects);\n }\n\n /**\n * Deletes an object from the S3 bucket.\n * @param objectKey - The key of the object to delete.\n *\n * @example\n * await store.deleteObject('user-1');\n */\n async deleteObject(objectKey: string): Promise<void> {\n await this.s3.send(\n new DeleteObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n }\n\n /**\n * Deletes multiple objects from the S3 bucket.\n * @param objectKeys - The keys of the objects to delete.\n *\n * @example\n * await store.deleteBatchObjects(['user-1', 'user-2']);\n */\n async deleteBatchObjects(objectKeys: string[]): Promise<void> {\n const params: DeleteObjectsCommandInput = {\n Bucket: this.bucket,\n Delete: {\n Objects: objectKeys.map((Key) => ({ Key }))\n }\n };\n await this.s3.send(new DeleteObjectsCommand(params));\n }\n\n /**\n * Reads an object from the S3 bucket.\n * @template T - The expected type of the object.\n * @param objectKey - The key of the object to read.\n * @returns The parsed object.\n *\n * @example\n * const user = await store.readObject<{ name: string }>('user-1');\n */\n async readObject<T>(objectKey: string): Promise<T> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n\n if (!resp.Body) {\n throw new Error('S3 did not return a body');\n }\n\n return JSON.parse(await resp.Body.transformToString()) as T;\n }\n\n /**\n * Reads multiple objects from the S3 bucket.\n * @template T - The expected type of the objects.\n * @param objectKeys - The keys of the objects to read.\n * @returns An array of parsed objects.\n *\n * @example\n * const users = await store.readBatchObjects<{ name: string }>(['user-1', 'user-2']);\n */\n async readBatchObjects<T>(objectKeys: string[]): Promise<T[]> {\n return Promise.all(objectKeys.map((key) => this.readObject<T>(key)));\n }\n\n /**\n * Streams an object download from the S3 bucket.\n * @param objectKey - The key of the object to download.\n * @returns A readable stream of the object's contents.\n * @throws If the S3 response does not include a readable stream.\n *\n * @example\n * const stream = await store.streamDownloadObject('user-1');\n * stream.pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadObject(objectKey: string): Promise<Readable> {\n const resp = await this.s3.send(\n new GetObjectCommand({ Bucket: this.bucket, Key: objectKey })\n );\n if (!resp.Body || !(resp.Body instanceof Readable)) {\n throw new Error('S3 did not return a stream');\n }\n return resp.Body;\n }\n\n /**\n * Streams multiple object downloads from the S3 bucket.\n * @param objectKeys - The keys of the objects to download.\n * @returns An array of readable streams.\n *\n * @example\n * const streams = await store.streamDownloadBatchObjects(['user-1', 'user-2']);\n * streams[0].pipe(fs.createWriteStream('user-1.json'));\n */\n async streamDownloadBatchObjects(objectKeys: string[]): Promise<Readable[]> {\n return Promise.all(objectKeys.map((key) => this.streamDownloadObject(key)));\n }\n\n /**\n * Gets the underlying S3 client instance.\n * @returns The S3Client instance used by this store.\n *\n * @example\n * const s3Client = store.getClient();\n */\n getClient(): S3Client {\n return this.s3;\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/infrastructure-s3",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "S3 infrastructure for ForkLaunch components.",
5
5
  "homepage": "https://github.com/forklaunch/forklaunch-js#readme",
6
6
  "bugs": {
@@ -28,14 +28,14 @@
28
28
  "lib/**"
29
29
  ],
30
30
  "dependencies": {
31
- "@aws-sdk/client-s3": "^3.824.0",
32
- "@forklaunch/common": "0.3.6",
33
- "@forklaunch/core": "0.8.8"
31
+ "@aws-sdk/client-s3": "^3.826.0",
32
+ "@forklaunch/core": "0.8.9",
33
+ "@forklaunch/common": "0.3.7"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@eslint/js": "^9.28.0",
37
37
  "@types/jest": "^29.5.14",
38
- "@typescript/native-preview": "7.0.0-dev.20250605.1",
38
+ "@typescript/native-preview": "7.0.0-dev.20250609.1",
39
39
  "globals": "^16.2.0",
40
40
  "jest": "^29.7.0",
41
41
  "prettier": "^3.5.3",