@oneblink/storage 1.0.0-beta.2 → 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.
@@ -76,7 +76,7 @@ class OneBlinkUploader {
76
76
  taskId,
77
77
  taskActionId,
78
78
  taskGroupInstanceId,
79
- recaptchas: recaptchas || {},
79
+ recaptchas: recaptchas || [],
80
80
  jobId,
81
81
  previousFormSubmissionApprovalId,
82
82
  },
@@ -1 +1 @@
1
- {"version":3,"file":"OneBlinkUploader.js","sourceRoot":"","sources":["../src/OneBlinkUploader.ts"],"names":[],"mappings":";;;;;AAAA,8DAAqC;AAQrC,8FAAqE;AAErE;;;GAGG;AACH,MAAqB,gBAAgB;IAKnC;;;;;;;;;;;;OAYG;IACH,YAAY,KAAgC;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC1B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAA;IACpC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,gBAAgB,CAAC,EACrB,UAAU,EACV,UAAU,EACV,MAAM,EACN,SAAS,EACT,gCAAgC,EAChC,KAAK,EACL,UAAU,EACV,UAAU,EACV,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,WAAW,GAgBZ;QACC,MAAM,mBAAmB,GAAwC;YAC/D,UAAU;YACV,UAAU;YACV,MAAM;SACP,CAAA;QACD,MAAM,IAAI,GAAG,IAAA,oCAA0B,EAAC;YACtC,SAAS;YACT,gCAAgC;YAChC,KAAK;SACN,CAAC,CAAA;QAEF,OAAO,MAAM,IAAA,oBAAU,EAKpB;YACD,GAAG,IAAI;YACP,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;YACzC,GAAG,EAAE,SAAS,UAAU,CAAC,EAAE,cAAc;YACzC,IAAI;YACJ,WAAW;YACX,UAAU;YACV,iBAAiB,EAAE;gBACjB,UAAU;gBACV,UAAU;gBACV,MAAM;gBACN,YAAY;gBACZ,mBAAmB;gBACnB,UAAU,EAAE,UAAU,IAAI,EAAE;gBAC5B,KAAK;gBACL,gCAAgC;aACjC;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,gBAAgB,CAAC,EACrB,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,WAAW,GAcZ;QACC,OAAO,MAAM,IAAA,oBAAU,EAIpB;YACD,GAAG,IAAI;YACP,WAAW;YACX,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,SAAS,MAAM,cAAc;YAClC,WAAW;YACX,UAAU;YACV,QAAQ,EAAE,CAAC,SAAS;YACpB,kBAAkB,EAAE,gCAAgC,kBAAkB,CAAC,QAAQ,CAAC,EAAE;YAClF,iBAAiB,EAAE;gBACjB,QAAQ;gBACR,QAAQ;aACT;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,qBAAqB,CAAC,EAC1B,UAAU,EACV,UAAU,EACV,MAAM,EACN,SAAS,EACT,gCAAgC,EAChC,KAAK,EACL,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,WAAW,GAIZ;QACC,OAAO,MAAM,IAAA,oBAAU,EAGpB;YACD,GAAG,IAAI;YACP,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU;gBACV,UAAU;gBACV,UAAU;gBACV,kBAAkB;gBAClB,UAAU;gBACV,MAAM;aACP,CAAC;YACF,GAAG,EAAE,SAAS,UAAU,CAAC,EAAE,SAAS;YACpC,IAAI,EAAE,IAAA,oCAA0B,EAAC;gBAC/B,SAAS;gBACT,KAAK;gBACL,gCAAgC;aACjC,CAAC;YACF,WAAW;YACX,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;CACF;AAnPD,mCAmPC","sourcesContent":["import uploadToS3 from './uploadToS3'\nimport {\n AttachmentUploadData,\n StorageConstructorOptions,\n UploadFormSubmissionOptions,\n UploadOptions,\n} from './types'\nimport { SubmissionTypes } from '@oneblink/types'\nimport generateFormSubmissionTags from './generateFormSubmissionTags'\n\n/**\n * Used to create an instance of the OneBlinkUploader, exposing methods to\n * upload submissions and other types of files\n */\nexport default class OneBlinkUploader {\n apiOrigin: StorageConstructorOptions['apiOrigin']\n region: StorageConstructorOptions['region']\n getIdToken: StorageConstructorOptions['getIdToken']\n\n /**\n * #### Example\n *\n * ```typescript\n * import { OneBlinkUploader } from '@oneblink/uploads'\n *\n * const uploader = new OneBlinkUploader({\n * apiOrigin: 'https://auth-api.blinkm.io',\n * region: 'ap-southeast-2',\n * getIdToken: () => getAccessToken(),\n * })\n * ```\n */\n constructor(props: StorageConstructorOptions) {\n this.apiOrigin = props.apiOrigin\n this.region = props.region\n this.getIdToken = props.getIdToken\n }\n\n /**\n * Upload a submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await uploader.uploadSubmission({\n * submission: {\n * // ...\n * },\n * definition: {\n * // ...\n * },\n * formsAppId: 1,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The upload result\n */\n async uploadSubmission({\n submission,\n definition,\n device,\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n formsAppId,\n externalId,\n taskId,\n taskActionId,\n taskGroupInstanceId,\n recaptchas,\n onProgress,\n abortSignal,\n }: UploadFormSubmissionOptions & {\n /** The identifier of the task that will be marked as completed */\n taskId?: string\n /** The identifier of the task action that was used to complete the task */\n taskActionId?: string\n /**\n * The identifier of the task group instance that the completed task is\n * associated with\n */\n taskGroupInstanceId?: string\n /** The reCAPTCHA tokens to validate the submission */\n recaptchas?: {\n /** A reCAPTCHA token */\n token: string\n }[]\n }) {\n const newS3SubmissionData: SubmissionTypes.NewS3SubmissionData = {\n submission,\n definition,\n device,\n }\n const tags = generateFormSubmissionTags({\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n })\n\n return await uploadToS3<{\n submissionTimestamp: string\n submissionId: string\n pdfAccessToken?: string\n preventPayment: boolean\n }>({\n ...this,\n contentType: 'application/json',\n body: JSON.stringify(newS3SubmissionData),\n key: `forms/${definition.id}/submissions`,\n tags,\n abortSignal,\n onProgress,\n requestBodyHeader: {\n formsAppId,\n externalId,\n taskId,\n taskActionId,\n taskGroupInstanceId,\n recaptchas: recaptchas || {},\n jobId,\n previousFormSubmissionApprovalId,\n },\n })\n }\n\n /**\n * Upload an form submission attachment.\n *\n * #### Example\n *\n * ```ts\n * const abortController = new AbortController()\n * const result = await uploader.uploadAttachment({\n * formId: 1,\n * data: new Blob(['a string of data'], {\n * type: 'text/plain',\n * }),\n * fileName: 'file.txt',\n * contentType: 'text/plain',\n * isPrivate: true,\n * abortSignal: abortController.signal,\n * })\n * ```\n *\n * @param data The attachment upload data and options\n * @returns The upload result\n */\n async uploadAttachment({\n formId,\n fileName,\n contentType,\n isPrivate,\n data,\n username,\n onProgress,\n abortSignal,\n }: UploadOptions & {\n /** The identifier for the form that is being completed */\n formId: number\n /** The name of the file being uploaded */\n fileName: string\n /** A standard MIME type describing the format of the contents */\n contentType: string\n /** Set to `true` to prevent the file from being downloaded publicly */\n isPrivate: boolean\n /** The file data to upload */\n data: AttachmentUploadData\n /** A username to allow a single user to download the attachment file */\n username?: string\n }) {\n return await uploadToS3<{\n url: string\n attachmentDataId: string\n uploadedAt: string\n }>({\n ...this,\n contentType,\n body: data,\n key: `forms/${formId}/attachments`,\n abortSignal,\n onProgress,\n isPublic: !isPrivate,\n contentDisposition: `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`,\n requestBodyHeader: {\n username,\n fileName,\n },\n })\n }\n\n /**\n * Upload a draft submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await uploader.uploadDraftSubmission({\n * submission: {\n * // ...\n * },\n * definition: {\n * // ...\n * },\n * formsAppId: 1,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The upload result\n */\n async uploadDraftSubmission({\n submission,\n definition,\n device,\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n formsAppId,\n externalId,\n lastElementUpdated,\n onProgress,\n abortSignal,\n }: UploadFormSubmissionOptions & {\n /** The identifier for the last element that was used before saving draft */\n lastElementUpdated?: SubmissionTypes.NewS3SubmissionData['lastElementUpdated']\n }) {\n return await uploadToS3<{\n submissionTimestamp: string\n draftDataId: string\n }>({\n ...this,\n contentType: 'application/json',\n body: JSON.stringify({\n definition,\n submission,\n formsAppId,\n lastElementUpdated,\n externalId,\n device,\n }),\n key: `forms/${definition.id}/drafts`,\n tags: generateFormSubmissionTags({\n userToken,\n jobId,\n previousFormSubmissionApprovalId,\n }),\n abortSignal,\n onProgress,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"OneBlinkUploader.js","sourceRoot":"","sources":["../src/OneBlinkUploader.ts"],"names":[],"mappings":";;;;;AAAA,8DAAqC;AAQrC,8FAAqE;AAErE;;;GAGG;AACH,MAAqB,gBAAgB;IAKnC;;;;;;;;;;;;OAYG;IACH,YAAY,KAAgC;QAC1C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC1B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAA;IACpC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,gBAAgB,CAAC,EACrB,UAAU,EACV,UAAU,EACV,MAAM,EACN,SAAS,EACT,gCAAgC,EAChC,KAAK,EACL,UAAU,EACV,UAAU,EACV,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,UAAU,EACV,WAAW,GAgBZ;QACC,MAAM,mBAAmB,GAAwC;YAC/D,UAAU;YACV,UAAU;YACV,MAAM;SACP,CAAA;QACD,MAAM,IAAI,GAAG,IAAA,oCAA0B,EAAC;YACtC,SAAS;YACT,gCAAgC;YAChC,KAAK;SACN,CAAC,CAAA;QAEF,OAAO,MAAM,IAAA,oBAAU,EAKpB;YACD,GAAG,IAAI;YACP,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;YACzC,GAAG,EAAE,SAAS,UAAU,CAAC,EAAE,cAAc;YACzC,IAAI;YACJ,WAAW;YACX,UAAU;YACV,iBAAiB,EAAE;gBACjB,UAAU;gBACV,UAAU;gBACV,MAAM;gBACN,YAAY;gBACZ,mBAAmB;gBACnB,UAAU,EAAE,UAAU,IAAI,EAAE;gBAC5B,KAAK;gBACL,gCAAgC;aACjC;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,gBAAgB,CAAC,EACrB,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,WAAW,GAcZ;QACC,OAAO,MAAM,IAAA,oBAAU,EAIpB;YACD,GAAG,IAAI;YACP,WAAW;YACX,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,SAAS,MAAM,cAAc;YAClC,WAAW;YACX,UAAU;YACV,QAAQ,EAAE,CAAC,SAAS;YACpB,kBAAkB,EAAE,gCAAgC,kBAAkB,CAAC,QAAQ,CAAC,EAAE;YAClF,iBAAiB,EAAE;gBACjB,QAAQ;gBACR,QAAQ;aACT;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,qBAAqB,CAAC,EAC1B,UAAU,EACV,UAAU,EACV,MAAM,EACN,SAAS,EACT,gCAAgC,EAChC,KAAK,EACL,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,WAAW,GAIZ;QACC,OAAO,MAAM,IAAA,oBAAU,EAGpB;YACD,GAAG,IAAI;YACP,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU;gBACV,UAAU;gBACV,UAAU;gBACV,kBAAkB;gBAClB,UAAU;gBACV,MAAM;aACP,CAAC;YACF,GAAG,EAAE,SAAS,UAAU,CAAC,EAAE,SAAS;YACpC,IAAI,EAAE,IAAA,oCAA0B,EAAC;gBAC/B,SAAS;gBACT,KAAK;gBACL,gCAAgC;aACjC,CAAC;YACF,WAAW;YACX,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;CACF;AAnPD,mCAmPC","sourcesContent":["import uploadToS3 from './uploadToS3'\nimport {\n AttachmentUploadData,\n StorageConstructorOptions,\n UploadFormSubmissionOptions,\n UploadOptions,\n} from './types'\nimport { SubmissionTypes } from '@oneblink/types'\nimport generateFormSubmissionTags from './generateFormSubmissionTags'\n\n/**\n * Used to create an instance of the OneBlinkUploader, exposing methods to\n * upload submissions and other types of files\n */\nexport default class OneBlinkUploader {\n apiOrigin: StorageConstructorOptions['apiOrigin']\n region: StorageConstructorOptions['region']\n getIdToken: StorageConstructorOptions['getIdToken']\n\n /**\n * #### Example\n *\n * ```typescript\n * import { OneBlinkUploader } from '@oneblink/uploads'\n *\n * const uploader = new OneBlinkUploader({\n * apiOrigin: 'https://auth-api.blinkm.io',\n * region: 'ap-southeast-2',\n * getIdToken: () => getAccessToken(),\n * })\n * ```\n */\n constructor(props: StorageConstructorOptions) {\n this.apiOrigin = props.apiOrigin\n this.region = props.region\n this.getIdToken = props.getIdToken\n }\n\n /**\n * Upload a submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await uploader.uploadSubmission({\n * submission: {\n * // ...\n * },\n * definition: {\n * // ...\n * },\n * formsAppId: 1,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The upload result\n */\n async uploadSubmission({\n submission,\n definition,\n device,\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n formsAppId,\n externalId,\n taskId,\n taskActionId,\n taskGroupInstanceId,\n recaptchas,\n onProgress,\n abortSignal,\n }: UploadFormSubmissionOptions & {\n /** The identifier of the task that will be marked as completed */\n taskId?: string\n /** The identifier of the task action that was used to complete the task */\n taskActionId?: string\n /**\n * The identifier of the task group instance that the completed task is\n * associated with\n */\n taskGroupInstanceId?: string\n /** The reCAPTCHA tokens to validate the submission */\n recaptchas?: {\n /** A reCAPTCHA token */\n token: string\n }[]\n }) {\n const newS3SubmissionData: SubmissionTypes.NewS3SubmissionData = {\n submission,\n definition,\n device,\n }\n const tags = generateFormSubmissionTags({\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n })\n\n return await uploadToS3<{\n submissionTimestamp: string\n submissionId: string\n pdfAccessToken?: string\n preventPayment: boolean\n }>({\n ...this,\n contentType: 'application/json',\n body: JSON.stringify(newS3SubmissionData),\n key: `forms/${definition.id}/submissions`,\n tags,\n abortSignal,\n onProgress,\n requestBodyHeader: {\n formsAppId,\n externalId,\n taskId,\n taskActionId,\n taskGroupInstanceId,\n recaptchas: recaptchas || [],\n jobId,\n previousFormSubmissionApprovalId,\n },\n })\n }\n\n /**\n * Upload an form submission attachment.\n *\n * #### Example\n *\n * ```ts\n * const abortController = new AbortController()\n * const result = await uploader.uploadAttachment({\n * formId: 1,\n * data: new Blob(['a string of data'], {\n * type: 'text/plain',\n * }),\n * fileName: 'file.txt',\n * contentType: 'text/plain',\n * isPrivate: true,\n * abortSignal: abortController.signal,\n * })\n * ```\n *\n * @param data The attachment upload data and options\n * @returns The upload result\n */\n async uploadAttachment({\n formId,\n fileName,\n contentType,\n isPrivate,\n data,\n username,\n onProgress,\n abortSignal,\n }: UploadOptions & {\n /** The identifier for the form that is being completed */\n formId: number\n /** The name of the file being uploaded */\n fileName: string\n /** A standard MIME type describing the format of the contents */\n contentType: string\n /** Set to `true` to prevent the file from being downloaded publicly */\n isPrivate: boolean\n /** The file data to upload */\n data: AttachmentUploadData\n /** A username to allow a single user to download the attachment file */\n username?: string\n }) {\n return await uploadToS3<{\n url: string\n attachmentDataId: string\n uploadedAt: string\n }>({\n ...this,\n contentType,\n body: data,\n key: `forms/${formId}/attachments`,\n abortSignal,\n onProgress,\n isPublic: !isPrivate,\n contentDisposition: `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`,\n requestBodyHeader: {\n username,\n fileName,\n },\n })\n }\n\n /**\n * Upload a draft submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await uploader.uploadDraftSubmission({\n * submission: {\n * // ...\n * },\n * definition: {\n * // ...\n * },\n * formsAppId: 1,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The upload result\n */\n async uploadDraftSubmission({\n submission,\n definition,\n device,\n userToken,\n previousFormSubmissionApprovalId,\n jobId,\n formsAppId,\n externalId,\n lastElementUpdated,\n onProgress,\n abortSignal,\n }: UploadFormSubmissionOptions & {\n /** The identifier for the last element that was used before saving draft */\n lastElementUpdated?: SubmissionTypes.NewS3SubmissionData['lastElementUpdated']\n }) {\n return await uploadToS3<{\n submissionTimestamp: string\n draftDataId: string\n }>({\n ...this,\n contentType: 'application/json',\n body: JSON.stringify({\n definition,\n submission,\n formsAppId,\n lastElementUpdated,\n externalId,\n device,\n }),\n key: `forms/${definition.id}/drafts`,\n tags: generateFormSubmissionTags({\n userToken,\n jobId,\n previousFormSubmissionApprovalId,\n }),\n abortSignal,\n onProgress,\n })\n }\n}\n"]}
@@ -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' : 'private',
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
  });
@@ -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.2",
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"