@oneblink/storage 1.0.0-beta.3 → 1.0.0-beta.4
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/dist/uploadToS3.js +1 -1
- package/dist/uploadToS3.js.map +1 -1
- package/package.json +1 -1
package/dist/uploadToS3.js
CHANGED
|
@@ -77,7 +77,7 @@ async function uploadToS3({ region, apiOrigin, key, body, requestBodyHeader, tag
|
|
|
77
77
|
ServerSideEncryption: 'AES256',
|
|
78
78
|
Expires: new Date(new Date().setFullYear(new Date().getFullYear() + 1)), // Max 1 year
|
|
79
79
|
CacheControl: 'max-age=31536000', // Max 1 year(365 days),
|
|
80
|
-
ACL: isPublic ? 'public-read' : '
|
|
80
|
+
ACL: isPublic ? 'public-read' : 'bucket-owner-full-control',
|
|
81
81
|
Tagging: tags === null || tags === void 0 ? void 0 : tags.toString(),
|
|
82
82
|
},
|
|
83
83
|
});
|
package/dist/uploadToS3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadToS3.js","sourceRoot":"","sources":["../src/uploadToS3.ts"],"names":[],"mappings":"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","sourcesContent":["import { PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'\nimport { Upload, Progress } from '@aws-sdk/lib-storage'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { HttpRequest } from '@smithy/protocol-http'\nimport { FetchHttpHandler } from '@smithy/fetch-http-handler'\nimport { StorageConstructorOptions, BaseResponse, UploadOptions } from './types'\n\nconst RETRY_ATTEMPTS = 3\n\ntype RequestBodyHeader = Record<string, unknown>\n// Our own custom request handler to allow setting customer headers for\n// authentication. Also allow the response header which includes dynamic\n// data from the lambda at edge to be retrieved and held for later when\n// the upload has completed.\nclass OBRequestHandler<T> extends FetchHttpHandler {\n constructor({\n getIdToken,\n requestBodyHeader,\n }: {\n getIdToken: StorageConstructorOptions['getIdToken']\n requestBodyHeader?: RequestBodyHeader\n }) {\n super()\n this.getIdToken = getIdToken\n this.requestBodyHeader = requestBodyHeader\n }\n\n getIdToken: StorageConstructorOptions['getIdToken']\n requestBodyHeader?: RequestBodyHeader\n response?: T & BaseResponse\n\n async handle(request: HttpRequest, options?: HttpHandlerOptions) {\n const token = await this.getIdToken()\n if (token) {\n request.headers['x-oneblink-authorization'] = 'Bearer ' + token\n }\n if (this.requestBodyHeader) {\n request.headers['x-oneblink-request-body'] = JSON.stringify(\n this.requestBodyHeader,\n )\n }\n if (this.response) {\n request.query['key'] = this.response.s3.key\n }\n const result = await super.handle(request, options)\n console.log('result', result)\n const response = result.response.headers['x-oneblink-response'] as\n | string\n | undefined\n if (response) {\n this.response = JSON.parse(response)\n }\n return result\n }\n}\n\nconst endpointSuffix = '/storage'\n\n/** The properties to be passed to the uploadToS3 function */\ninterface UploadToS3Props extends UploadOptions, StorageConstructorOptions {\n /** The key of the file that is being uploaded. */\n key: string\n /**\n * The body of the request. This can be a string, a Buffer, a Blob, a\n * ReadableStream, or a Readable.\n */\n body: PutObjectCommandInput['Body']\n /** Optional header to be included in the request to the OneBlink API */\n requestBodyHeader?: RequestBodyHeader\n /** An optional set of tags that will be applied to the uploaded file */\n tags?: URLSearchParams\n /** A standard MIME type describing the format of the contents */\n contentType: PutObjectCommandInput['ContentType']\n /** Set to `true` to make the upload available to download publicly */\n isPublic?: boolean\n}\n\nasync function uploadToS3<T>({\n region,\n apiOrigin,\n key,\n body,\n requestBodyHeader,\n tags,\n getIdToken,\n onProgress,\n abortSignal,\n contentType,\n isPublic,\n}: UploadToS3Props) {\n const requestHandler = new OBRequestHandler<T>({\n getIdToken,\n requestBodyHeader,\n })\n\n const s3Client = new S3Client({\n // The suffix on the end is important as it will allow us to route\n // traffic to S3 via lambda at edge instead of going to our API\n endpoint: `${apiOrigin}${endpointSuffix}`,\n region: region,\n requestHandler,\n // Have to put something here otherwise the SDK throws errors.\n // Might be able to remove the validation from the middleware somehow?\n credentials: {\n accessKeyId: 'AWS_ACCESS_KEY_ID',\n secretAccessKey: 'AWS_SECRET_ACCESS_KEY',\n },\n maxAttempts: RETRY_ATTEMPTS,\n })\n\n const managedUpload = new Upload({\n client: s3Client,\n partSize: 5 * 1024 * 1024,\n queueSize: determineQueueSize(),\n //Related github issue: https://github.com/aws/aws-sdk-js-v3/issues/2311\n //This is a variable that is set to false by default, setting it to true\n //means that it will force the upload to fail when one part fails on\n //an upload. The S3 client has built in retry logic to retry uploads by default\n leavePartsOnError: true,\n params: {\n // Bucket needs to have something to avoid client side errors\n // Also needs to have a `.` in it to prevent SDK from using the\n // new S3 bucket domain concept with includes the bucket in the\n // domain instead of the path. We need it in the path to use the\n // API as the domain.\n Bucket: 'storage.oneblink.io',\n Key: key,\n Body: body,\n ContentType: contentType,\n ServerSideEncryption: 'AES256',\n Expires: new Date(new Date().setFullYear(new Date().getFullYear() + 1)), // Max 1 year\n CacheControl: 'max-age=31536000', // Max 1 year(365 days),\n ACL: isPublic ? 'public-read' : 'private',\n Tagging: tags?.toString(),\n },\n })\n\n managedUpload.on('httpUploadProgress', (progress) => {\n console.log('Progress', progress)\n if (onProgress && progress.total) {\n const percent = determineUploadProgressAsPercentage({\n ...progress,\n total: progress.total,\n })\n onProgress({ progress: percent, total: 100 })\n }\n })\n\n abortSignal?.addEventListener('abort', () => {\n managedUpload.abort()\n })\n\n await managedUpload.done()\n\n if (!requestHandler.response) {\n throw new Error(\n 'No response from server. Something went wrong in the OneBlink/uploads SDK.',\n )\n }\n return requestHandler.response\n}\n\nexport default uploadToS3\n\nexport const determineQueueSize = () => {\n let queueSize = 1 // default to 1 as the lowest common denominator\n // Return as though using highest speed for Node environments\n if (!window) return 10\n if (\n window.navigator &&\n 'connection' in window.navigator &&\n !!window.navigator.connection &&\n // @ts-expect-error effectiveType prop is still in draft\n window.navigator.connection.effectiveType\n ) {\n // @ts-expect-error effectiveType prop is still in draft\n switch (window.navigator.connection.effectiveType) {\n case 'slow-2g':\n case '2g':\n queueSize = 1\n break\n case '3g':\n queueSize = 2\n break\n case '4g':\n queueSize = 10\n break\n }\n }\n\n return queueSize\n}\n\nexport const determineUploadProgressAsPercentage = (\n progress: Required<Pick<Progress, 'total'>> & Omit<Progress, 'total'>,\n) => {\n const percent = ((progress.loaded || 0) / progress.total) * 100\n return Math.floor(percent)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"uploadToS3.js","sourceRoot":"","sources":["../src/uploadToS3.ts"],"names":[],"mappings":"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","sourcesContent":["import { PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'\nimport { Upload, Progress } from '@aws-sdk/lib-storage'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { HttpRequest } from '@smithy/protocol-http'\nimport { FetchHttpHandler } from '@smithy/fetch-http-handler'\nimport { StorageConstructorOptions, BaseResponse, UploadOptions } from './types'\n\nconst RETRY_ATTEMPTS = 3\n\ntype RequestBodyHeader = Record<string, unknown>\n// Our own custom request handler to allow setting customer headers for\n// authentication. Also allow the response header which includes dynamic\n// data from the lambda at edge to be retrieved and held for later when\n// the upload has completed.\nclass OBRequestHandler<T> extends FetchHttpHandler {\n constructor({\n getIdToken,\n requestBodyHeader,\n }: {\n getIdToken: StorageConstructorOptions['getIdToken']\n requestBodyHeader?: RequestBodyHeader\n }) {\n super()\n this.getIdToken = getIdToken\n this.requestBodyHeader = requestBodyHeader\n }\n\n getIdToken: StorageConstructorOptions['getIdToken']\n requestBodyHeader?: RequestBodyHeader\n response?: T & BaseResponse\n\n async handle(request: HttpRequest, options?: HttpHandlerOptions) {\n const token = await this.getIdToken()\n if (token) {\n request.headers['x-oneblink-authorization'] = 'Bearer ' + token\n }\n if (this.requestBodyHeader) {\n request.headers['x-oneblink-request-body'] = JSON.stringify(\n this.requestBodyHeader,\n )\n }\n if (this.response) {\n request.query['key'] = this.response.s3.key\n }\n const result = await super.handle(request, options)\n console.log('result', result)\n const response = result.response.headers['x-oneblink-response'] as\n | string\n | undefined\n if (response) {\n this.response = JSON.parse(response)\n }\n return result\n }\n}\n\nconst endpointSuffix = '/storage'\n\n/** The properties to be passed to the uploadToS3 function */\ninterface UploadToS3Props extends UploadOptions, StorageConstructorOptions {\n /** The key of the file that is being uploaded. */\n key: string\n /**\n * The body of the request. This can be a string, a Buffer, a Blob, a\n * ReadableStream, or a Readable.\n */\n body: PutObjectCommandInput['Body']\n /** Optional header to be included in the request to the OneBlink API */\n requestBodyHeader?: RequestBodyHeader\n /** An optional set of tags that will be applied to the uploaded file */\n tags?: URLSearchParams\n /** A standard MIME type describing the format of the contents */\n contentType: PutObjectCommandInput['ContentType']\n /** Set to `true` to make the upload available to download publicly */\n isPublic?: boolean\n}\n\nasync function uploadToS3<T>({\n region,\n apiOrigin,\n key,\n body,\n requestBodyHeader,\n tags,\n getIdToken,\n onProgress,\n abortSignal,\n contentType,\n isPublic,\n}: UploadToS3Props) {\n const requestHandler = new OBRequestHandler<T>({\n getIdToken,\n requestBodyHeader,\n })\n\n const s3Client = new S3Client({\n // The suffix on the end is important as it will allow us to route\n // traffic to S3 via lambda at edge instead of going to our API\n endpoint: `${apiOrigin}${endpointSuffix}`,\n region: region,\n requestHandler,\n // Have to put something here otherwise the SDK throws errors.\n // Might be able to remove the validation from the middleware somehow?\n credentials: {\n accessKeyId: 'AWS_ACCESS_KEY_ID',\n secretAccessKey: 'AWS_SECRET_ACCESS_KEY',\n },\n maxAttempts: RETRY_ATTEMPTS,\n })\n\n const managedUpload = new Upload({\n client: s3Client,\n partSize: 5 * 1024 * 1024,\n queueSize: determineQueueSize(),\n //Related github issue: https://github.com/aws/aws-sdk-js-v3/issues/2311\n //This is a variable that is set to false by default, setting it to true\n //means that it will force the upload to fail when one part fails on\n //an upload. The S3 client has built in retry logic to retry uploads by default\n leavePartsOnError: true,\n params: {\n // Bucket needs to have something to avoid client side errors\n // Also needs to have a `.` in it to prevent SDK from using the\n // new S3 bucket domain concept with includes the bucket in the\n // domain instead of the path. We need it in the path to use the\n // API as the domain.\n Bucket: 'storage.oneblink.io',\n Key: key,\n Body: body,\n ContentType: contentType,\n ServerSideEncryption: 'AES256',\n Expires: new Date(new Date().setFullYear(new Date().getFullYear() + 1)), // Max 1 year\n CacheControl: 'max-age=31536000', // Max 1 year(365 days),\n ACL: isPublic ? 'public-read' : 'bucket-owner-full-control',\n Tagging: tags?.toString(),\n },\n })\n\n managedUpload.on('httpUploadProgress', (progress) => {\n console.log('Progress', progress)\n if (onProgress && progress.total) {\n const percent = determineUploadProgressAsPercentage({\n ...progress,\n total: progress.total,\n })\n onProgress({ progress: percent, total: 100 })\n }\n })\n\n abortSignal?.addEventListener('abort', () => {\n managedUpload.abort()\n })\n\n await managedUpload.done()\n\n if (!requestHandler.response) {\n throw new Error(\n 'No response from server. Something went wrong in the OneBlink/uploads SDK.',\n )\n }\n return requestHandler.response\n}\n\nexport default uploadToS3\n\nexport const determineQueueSize = () => {\n let queueSize = 1 // default to 1 as the lowest common denominator\n // Return as though using highest speed for Node environments\n if (!window) return 10\n if (\n window.navigator &&\n 'connection' in window.navigator &&\n !!window.navigator.connection &&\n // @ts-expect-error effectiveType prop is still in draft\n window.navigator.connection.effectiveType\n ) {\n // @ts-expect-error effectiveType prop is still in draft\n switch (window.navigator.connection.effectiveType) {\n case 'slow-2g':\n case '2g':\n queueSize = 1\n break\n case '3g':\n queueSize = 2\n break\n case '4g':\n queueSize = 10\n break\n }\n }\n\n return queueSize\n}\n\nexport const determineUploadProgressAsPercentage = (\n progress: Required<Pick<Progress, 'total'>> & Omit<Progress, 'total'>,\n) => {\n const percent = ((progress.loaded || 0) / progress.total) * 100\n return Math.floor(percent)\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneblink/storage",
|
|
3
3
|
"description": "SDK for managing storage files in the OneBlink ecosystem",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.4",
|
|
5
5
|
"author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/oneblink/storage/issues"
|