@oneblink/storage 2.0.1 → 2.1.0-beta.2

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.
@@ -0,0 +1,91 @@
1
+ import { DownloadOptions, StorageConstructorOptions } from './types';
2
+ import { SubmissionTypes } from '@oneblink/types';
3
+ /**
4
+ * Used to create an instance of the OneBlinkDownloader, exposing methods to
5
+ * download submissions and other types of files
6
+ */
7
+ export default class OneBlinkDownloader {
8
+ apiOrigin: StorageConstructorOptions['apiOrigin'];
9
+ region: StorageConstructorOptions['region'];
10
+ getBearerToken: StorageConstructorOptions['getBearerToken'];
11
+ /**
12
+ * #### Example
13
+ *
14
+ * ```typescript
15
+ * import { OneBlinkDownloader } from '@oneblink/storage'
16
+ *
17
+ * const downloader = new OneBlinkDownloader({
18
+ * apiOrigin: 'https://auth-api.blinkm.io',
19
+ * region: 'ap-southeast-2',
20
+ * getBearerToken: () => getAccessToken(),
21
+ * })
22
+ * ```
23
+ */
24
+ constructor(props: StorageConstructorOptions);
25
+ /**
26
+ * Download a form submission.
27
+ *
28
+ * #### Example
29
+ *
30
+ * ```ts
31
+ * const result = await downloader.downloadSubmission({
32
+ * submissionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
33
+ * formId: 1,
34
+ * abortSignal: new AbortController().signal,
35
+ * })
36
+ * ```
37
+ *
38
+ * @param data The submission upload data and options
39
+ * @returns The submission
40
+ */
41
+ downloadSubmission({ submissionId, formId, abortSignal, }: DownloadOptions & {
42
+ /** The identifier of the submission. */
43
+ submissionId: string;
44
+ /** The identifier of the form associated with the submission. */
45
+ formId: number;
46
+ }): Promise<SubmissionTypes.S3SubmissionData | undefined>;
47
+ /**
48
+ * Download a draft form submission.
49
+ *
50
+ * #### Example
51
+ *
52
+ * ```ts
53
+ * const result = await downloader.downloadDraftSubmission({
54
+ * formSubmissionDraftVersionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
55
+ * formId: 1,
56
+ * abortSignal: new AbortController().signal,
57
+ * })
58
+ * ```
59
+ *
60
+ * @param data The submission upload data and options
61
+ * @returns The submission
62
+ */
63
+ downloadDraftSubmission({ formSubmissionDraftVersionId, formId, abortSignal, }: DownloadOptions & {
64
+ /** The identifier of the draft form submission version. */
65
+ formSubmissionDraftVersionId: string;
66
+ /** The identifier of the form associated with the draft submission. */
67
+ formId: number;
68
+ }): Promise<SubmissionTypes.S3SubmissionData | undefined>;
69
+ /**
70
+ * Download pre-fill form submission data.
71
+ *
72
+ * #### Example
73
+ *
74
+ * ```ts
75
+ * const result = await downloader.downloadPrefillData({
76
+ * preFillFormDataId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
77
+ * formId: 1,
78
+ * abortSignal: new AbortController().signal,
79
+ * })
80
+ * ```
81
+ *
82
+ * @param data The submission upload data and options
83
+ * @returns The submission
84
+ */
85
+ downloadPrefillData<T extends Record<string, unknown>>({ preFillFormDataId, formId, abortSignal, }: DownloadOptions & {
86
+ /** The identifier of the pre-fill data. */
87
+ preFillFormDataId: string;
88
+ /** The identifier of the form associated with the pre-fill data. */
89
+ formId: number;
90
+ }): Promise<T | undefined>;
91
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const downloadJsonFromS3_1 = __importDefault(require("./downloadJsonFromS3"));
7
+ /**
8
+ * Used to create an instance of the OneBlinkDownloader, exposing methods to
9
+ * download submissions and other types of files
10
+ */
11
+ class OneBlinkDownloader {
12
+ /**
13
+ * #### Example
14
+ *
15
+ * ```typescript
16
+ * import { OneBlinkDownloader } from '@oneblink/storage'
17
+ *
18
+ * const downloader = new OneBlinkDownloader({
19
+ * apiOrigin: 'https://auth-api.blinkm.io',
20
+ * region: 'ap-southeast-2',
21
+ * getBearerToken: () => getAccessToken(),
22
+ * })
23
+ * ```
24
+ */
25
+ constructor(props) {
26
+ this.apiOrigin = props.apiOrigin;
27
+ this.region = props.region;
28
+ this.getBearerToken = props.getBearerToken;
29
+ }
30
+ /**
31
+ * Download a form submission.
32
+ *
33
+ * #### Example
34
+ *
35
+ * ```ts
36
+ * const result = await downloader.downloadSubmission({
37
+ * submissionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
38
+ * formId: 1,
39
+ * abortSignal: new AbortController().signal,
40
+ * })
41
+ * ```
42
+ *
43
+ * @param data The submission upload data and options
44
+ * @returns The submission
45
+ */
46
+ async downloadSubmission({ submissionId, formId, abortSignal, }) {
47
+ return await (0, downloadJsonFromS3_1.default)({
48
+ ...this,
49
+ key: `forms/${formId}/submissions/${submissionId}`,
50
+ abortSignal,
51
+ });
52
+ }
53
+ /**
54
+ * Download a draft form submission.
55
+ *
56
+ * #### Example
57
+ *
58
+ * ```ts
59
+ * const result = await downloader.downloadDraftSubmission({
60
+ * formSubmissionDraftVersionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
61
+ * formId: 1,
62
+ * abortSignal: new AbortController().signal,
63
+ * })
64
+ * ```
65
+ *
66
+ * @param data The submission upload data and options
67
+ * @returns The submission
68
+ */
69
+ async downloadDraftSubmission({ formSubmissionDraftVersionId, formId, abortSignal, }) {
70
+ return await (0, downloadJsonFromS3_1.default)({
71
+ ...this,
72
+ key: `forms/${formId}/drafts/${formSubmissionDraftVersionId}`,
73
+ abortSignal,
74
+ });
75
+ }
76
+ /**
77
+ * Download pre-fill form submission data.
78
+ *
79
+ * #### Example
80
+ *
81
+ * ```ts
82
+ * const result = await downloader.downloadPrefillData({
83
+ * preFillFormDataId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',
84
+ * formId: 1,
85
+ * abortSignal: new AbortController().signal,
86
+ * })
87
+ * ```
88
+ *
89
+ * @param data The submission upload data and options
90
+ * @returns The submission
91
+ */
92
+ async downloadPrefillData({ preFillFormDataId, formId, abortSignal, }) {
93
+ return await (0, downloadJsonFromS3_1.default)({
94
+ ...this,
95
+ key: `forms/${formId}/pre-fill/${preFillFormDataId}`,
96
+ abortSignal,
97
+ });
98
+ }
99
+ }
100
+ exports.default = OneBlinkDownloader;
101
+ //# sourceMappingURL=OneBlinkDownloader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OneBlinkDownloader.js","sourceRoot":"","sources":["../src/OneBlinkDownloader.ts"],"names":[],"mappings":";;;;;AACA,8EAAqD;AAErD;;;GAGG;AACH,MAAqB,kBAAkB;IAKrC;;;;;;;;;;;;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,cAAc,GAAG,KAAK,CAAC,cAAc,CAAA;IAC5C,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,kBAAkB,CAAC,EACvB,YAAY,EACZ,MAAM,EACN,WAAW,GAMZ;QACC,OAAO,MAAM,IAAA,4BAAkB,EAAmC;YAChE,GAAG,IAAI;YACP,GAAG,EAAE,SAAS,MAAM,gBAAgB,YAAY,EAAE;YAClD,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,uBAAuB,CAAC,EAC5B,4BAA4B,EAC5B,MAAM,EACN,WAAW,GAMZ;QACC,OAAO,MAAM,IAAA,4BAAkB,EAAmC;YAChE,GAAG,IAAI;YACP,GAAG,EAAE,SAAS,MAAM,WAAW,4BAA4B,EAAE;YAC7D,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,mBAAmB,CAAoC,EAC3D,iBAAiB,EACjB,MAAM,EACN,WAAW,GAMZ;QACC,OAAO,MAAM,IAAA,4BAAkB,EAAI;YACjC,GAAG,IAAI;YACP,GAAG,EAAE,SAAS,MAAM,aAAa,iBAAiB,EAAE;YACpD,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;CACF;AA1HD,qCA0HC","sourcesContent":["import { DownloadOptions, StorageConstructorOptions } from './types'\nimport downloadJsonFromS3 from './downloadJsonFromS3'\nimport { SubmissionTypes } from '@oneblink/types'\n/**\n * Used to create an instance of the OneBlinkDownloader, exposing methods to\n * download submissions and other types of files\n */\nexport default class OneBlinkDownloader {\n apiOrigin: StorageConstructorOptions['apiOrigin']\n region: StorageConstructorOptions['region']\n getBearerToken: StorageConstructorOptions['getBearerToken']\n\n /**\n * #### Example\n *\n * ```typescript\n * import { OneBlinkDownloader } from '@oneblink/storage'\n *\n * const downloader = new OneBlinkDownloader({\n * apiOrigin: 'https://auth-api.blinkm.io',\n * region: 'ap-southeast-2',\n * getBearerToken: () => getAccessToken(),\n * })\n * ```\n */\n constructor(props: StorageConstructorOptions) {\n this.apiOrigin = props.apiOrigin\n this.region = props.region\n this.getBearerToken = props.getBearerToken\n }\n\n /**\n * Download a form submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await downloader.downloadSubmission({\n * submissionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',\n * formId: 1,\n * abortSignal: new AbortController().signal,\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The submission\n */\n async downloadSubmission({\n submissionId,\n formId,\n abortSignal,\n }: DownloadOptions & {\n /** The identifier of the submission. */\n submissionId: string\n /** The identifier of the form associated with the submission. */\n formId: number\n }) {\n return await downloadJsonFromS3<SubmissionTypes.S3SubmissionData>({\n ...this,\n key: `forms/${formId}/submissions/${submissionId}`,\n abortSignal,\n })\n }\n\n /**\n * Download a draft form submission.\n *\n * #### Example\n *\n * ```ts\n * const result = await downloader.downloadDraftSubmission({\n * formSubmissionDraftVersionId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',\n * formId: 1,\n * abortSignal: new AbortController().signal,\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The submission\n */\n async downloadDraftSubmission({\n formSubmissionDraftVersionId,\n formId,\n abortSignal,\n }: DownloadOptions & {\n /** The identifier of the draft form submission version. */\n formSubmissionDraftVersionId: string\n /** The identifier of the form associated with the draft submission. */\n formId: number\n }) {\n return await downloadJsonFromS3<SubmissionTypes.S3SubmissionData>({\n ...this,\n key: `forms/${formId}/drafts/${formSubmissionDraftVersionId}`,\n abortSignal,\n })\n }\n\n /**\n * Download pre-fill form submission data.\n *\n * #### Example\n *\n * ```ts\n * const result = await downloader.downloadPrefillData({\n * preFillFormDataId: '5ad46e62-f466-451c-8cd6-29ba23ac50b7',\n * formId: 1,\n * abortSignal: new AbortController().signal,\n * })\n * ```\n *\n * @param data The submission upload data and options\n * @returns The submission\n */\n async downloadPrefillData<T extends Record<string, unknown>>({\n preFillFormDataId,\n formId,\n abortSignal,\n }: DownloadOptions & {\n /** The identifier of the pre-fill data. */\n preFillFormDataId: string\n /** The identifier of the form associated with the pre-fill data. */\n formId: number\n }) {\n return await downloadJsonFromS3<T>({\n ...this,\n key: `forms/${formId}/pre-fill/${preFillFormDataId}`,\n abortSignal,\n })\n }\n}\n"]}
@@ -15,4 +15,5 @@ export declare class OneBlinkRequestHandler<T> implements RequestHandler<HttpReq
15
15
  handle(request: HttpRequest): Promise<{
16
16
  response: HttpResponse;
17
17
  }>;
18
+ sendS3Command<O>(sender: () => Promise<O>): Promise<O>;
18
19
  }
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.OneBlinkRequestHandler = void 0;
7
+ const OneBlinkStorageError_1 = __importDefault(require("./OneBlinkStorageError"));
4
8
  /**
5
9
  * Our own custom request handler to allow the response header which includes
6
10
  * dynamic data from the lambda at edge to be retrieved and held for later when
@@ -19,9 +23,9 @@ class OneBlinkRequestHandler {
19
23
  request.query['key'] = this.oneblinkResponse.s3.key;
20
24
  }
21
25
  const requestUrl = `${request.method} ${request.protocol}//${request.hostname}${request.path}?${new URLSearchParams(request.query).toString()}`;
22
- console.log('Starting storage upload request', requestUrl);
26
+ console.log('Starting storage request', requestUrl);
23
27
  const response = await this.oneBlinkHttpHandler.handleRequest(request);
24
- console.log('Finished storage upload request', requestUrl);
28
+ console.log('Finished storage request', requestUrl);
25
29
  const oneblinkResponse = response.headers['x-oneblink-response'];
26
30
  if (typeof oneblinkResponse === 'string') {
27
31
  this.oneblinkResponse = JSON.parse(oneblinkResponse);
@@ -34,6 +38,20 @@ class OneBlinkRequestHandler {
34
38
  response,
35
39
  };
36
40
  }
41
+ async sendS3Command(sender) {
42
+ try {
43
+ return await sender();
44
+ }
45
+ catch (error) {
46
+ if (this.failResponse) {
47
+ throw new OneBlinkStorageError_1.default(this.failResponse.message, {
48
+ httpStatusCode: this.failResponse.statusCode,
49
+ originalError: error instanceof Error ? error : undefined,
50
+ });
51
+ }
52
+ throw error;
53
+ }
54
+ }
37
55
  }
38
56
  exports.OneBlinkRequestHandler = OneBlinkRequestHandler;
39
57
  //# sourceMappingURL=OneBlinkRequestHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OneBlinkRequestHandler.js","sourceRoot":"","sources":["../src/OneBlinkRequestHandler.ts"],"names":[],"mappings":";;;AASA;;;;GAIG;AACH,MAAa,sBAAsB;IAQjC,YACE,mBAAyC,EACzC,iBAAqC;QAErC,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAA;QAC9C,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAoB;QAC/B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,SAAS,CACzD,IAAI,CAAC,iBAAiB,CACvB,CAAA;QACH,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAA;QACrD,CAAC;QAED,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,eAAe,CAAC,OAAO,CAAC,KAA+B,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAA;QACzK,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,UAAU,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACtE,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,UAAU,CAAC,CAAA;QAE1D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;QAChE,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;QACtD,CAAC;QAED,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY;gBACf,MAAM,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO;YACL,QAAQ;SACT,CAAA;IACH,CAAC;CACF;AA9CD,wDA8CC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { RequestHandler } from '@smithy/types'\nimport {\n RequestBodyHeader,\n IOneBlinkHttpHandler,\n OneBlinkResponse,\n FailResponse,\n} from './http-handlers/types'\n\n/**\n * Our own custom request handler to allow the response header which includes\n * dynamic data from the lambda at edge to be retrieved and held for later when\n * the upload has completed.\n */\nexport class OneBlinkRequestHandler<T>\n implements RequestHandler<HttpRequest, HttpResponse>\n{\n requestBodyHeader?: RequestBodyHeader\n oneBlinkHttpHandler: IOneBlinkHttpHandler\n oneblinkResponse?: OneBlinkResponse<T>\n failResponse?: FailResponse\n\n constructor(\n oneBlinkHttpHandler: IOneBlinkHttpHandler,\n requestBodyHeader?: RequestBodyHeader,\n ) {\n this.oneBlinkHttpHandler = oneBlinkHttpHandler\n this.requestBodyHeader = requestBodyHeader\n }\n\n async handle(request: HttpRequest) {\n if (this.requestBodyHeader) {\n request.headers['x-oneblink-request-body'] = JSON.stringify(\n this.requestBodyHeader,\n )\n }\n\n if (this.oneblinkResponse) {\n request.query['key'] = this.oneblinkResponse.s3.key\n }\n\n const requestUrl = `${request.method} ${request.protocol}//${request.hostname}${request.path}?${new URLSearchParams(request.query as Record<string, string>).toString()}`\n console.log('Starting storage upload request', requestUrl)\n const response = await this.oneBlinkHttpHandler.handleRequest(request)\n console.log('Finished storage upload request', requestUrl)\n\n const oneblinkResponse = response.headers['x-oneblink-response']\n if (typeof oneblinkResponse === 'string') {\n this.oneblinkResponse = JSON.parse(oneblinkResponse)\n }\n\n if (response.statusCode >= 400) {\n this.failResponse =\n await this.oneBlinkHttpHandler.handleFailResponse(response)\n }\n\n return {\n response,\n }\n }\n}\n"]}
1
+ {"version":3,"file":"OneBlinkRequestHandler.js","sourceRoot":"","sources":["../src/OneBlinkRequestHandler.ts"],"names":[],"mappings":";;;;;;AAQA,kFAAyD;AAEzD;;;;GAIG;AACH,MAAa,sBAAsB;IAQjC,YACE,mBAAyC,EACzC,iBAAqC;QAErC,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAA;QAC9C,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAoB;QAC/B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,SAAS,CACzD,IAAI,CAAC,iBAAiB,CACvB,CAAA;QACH,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAA;QACrD,CAAC;QAED,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,eAAe,CAAC,OAAO,CAAC,KAA+B,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAA;QACzK,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;QACtE,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAA;QAEnD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAA;QAChE,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;QACtD,CAAC;QAED,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY;gBACf,MAAM,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO;YACL,QAAQ;SACT,CAAA;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAI,MAAwB;QAC7C,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,EAAE,CAAA;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,MAAM,IAAI,8BAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;oBACxD,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU;oBAC5C,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;iBAC1D,CAAC,CAAA;YACJ,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;CACF;AA5DD,wDA4DC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { RequestHandler } from '@smithy/types'\nimport {\n RequestBodyHeader,\n IOneBlinkHttpHandler,\n OneBlinkResponse,\n FailResponse,\n} from './http-handlers/types'\nimport OneBlinkStorageError from './OneBlinkStorageError'\n\n/**\n * Our own custom request handler to allow the response header which includes\n * dynamic data from the lambda at edge to be retrieved and held for later when\n * the upload has completed.\n */\nexport class OneBlinkRequestHandler<T>\n implements RequestHandler<HttpRequest, HttpResponse>\n{\n requestBodyHeader?: RequestBodyHeader\n oneBlinkHttpHandler: IOneBlinkHttpHandler\n oneblinkResponse?: OneBlinkResponse<T>\n failResponse?: FailResponse\n\n constructor(\n oneBlinkHttpHandler: IOneBlinkHttpHandler,\n requestBodyHeader?: RequestBodyHeader,\n ) {\n this.oneBlinkHttpHandler = oneBlinkHttpHandler\n this.requestBodyHeader = requestBodyHeader\n }\n\n async handle(request: HttpRequest) {\n if (this.requestBodyHeader) {\n request.headers['x-oneblink-request-body'] = JSON.stringify(\n this.requestBodyHeader,\n )\n }\n\n if (this.oneblinkResponse) {\n request.query['key'] = this.oneblinkResponse.s3.key\n }\n\n const requestUrl = `${request.method} ${request.protocol}//${request.hostname}${request.path}?${new URLSearchParams(request.query as Record<string, string>).toString()}`\n console.log('Starting storage request', requestUrl)\n const response = await this.oneBlinkHttpHandler.handleRequest(request)\n console.log('Finished storage request', requestUrl)\n\n const oneblinkResponse = response.headers['x-oneblink-response']\n if (typeof oneblinkResponse === 'string') {\n this.oneblinkResponse = JSON.parse(oneblinkResponse)\n }\n\n if (response.statusCode >= 400) {\n this.failResponse =\n await this.oneBlinkHttpHandler.handleFailResponse(response)\n }\n\n return {\n response,\n }\n }\n\n async sendS3Command<O>(sender: () => Promise<O>): Promise<O> {\n try {\n return await sender()\n } catch (error) {\n if (this.failResponse) {\n throw new OneBlinkStorageError(this.failResponse.message, {\n httpStatusCode: this.failResponse.statusCode,\n originalError: error instanceof Error ? error : undefined,\n })\n }\n throw error\n }\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { DownloadOptions, StorageConstructorOptions } from './types';
2
+ export default function downloadJsonFromS3<T>({ key, abortSignal, ...storageConstructorOptions }: DownloadOptions & StorageConstructorOptions & {
3
+ key: string;
4
+ }): Promise<T | undefined>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const client_s3_1 = require("@aws-sdk/client-s3");
7
+ const generateS3Client_1 = require("./generateS3Client");
8
+ const OneBlinkStorageError_1 = __importDefault(require("./OneBlinkStorageError"));
9
+ async function downloadJsonFromS3({ key, abortSignal, ...storageConstructorOptions }) {
10
+ const { s3Client, bucket, oneBlinkRequestHandler } = (0, generateS3Client_1.generateS3Client)({
11
+ ...storageConstructorOptions,
12
+ requestBodyHeader: undefined,
13
+ });
14
+ try {
15
+ const getObjectCommandOutput = await oneBlinkRequestHandler.sendS3Command(async () => await s3Client.send(new client_s3_1.GetObjectCommand({
16
+ Bucket: bucket,
17
+ Key: key,
18
+ }), {
19
+ abortSignal,
20
+ }));
21
+ return oneBlinkRequestHandler.oneBlinkHttpHandler.parseGetObjectCommandOutputAsJson(getObjectCommandOutput);
22
+ }
23
+ catch (error) {
24
+ if (error instanceof OneBlinkStorageError_1.default && error.httpStatusCode === 403) {
25
+ return;
26
+ }
27
+ else {
28
+ throw error;
29
+ }
30
+ }
31
+ }
32
+ exports.default = downloadJsonFromS3;
33
+ //# sourceMappingURL=downloadJsonFromS3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloadJsonFromS3.js","sourceRoot":"","sources":["../src/downloadJsonFromS3.ts"],"names":[],"mappings":";;;;;AAAA,kDAA6E;AAE7E,yDAAqD;AACrD,kFAAyD;AAE1C,KAAK,UAAU,kBAAkB,CAAI,EAClD,GAAG,EACH,WAAW,EACX,GAAG,yBAAyB,EAI3B;IACD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAA,mCAAgB,EAAC;QACpE,GAAG,yBAAyB;QAC5B,iBAAiB,EAAE,SAAS;KAC7B,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,MAAM,sBAAsB,GAC1B,MAAM,sBAAsB,CAAC,aAAa,CACxC,KAAK,IAAI,EAAE,CACT,MAAM,QAAQ,CAAC,IAAI,CACjB,IAAI,4BAAgB,CAAC;YACnB,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,GAAG;SACT,CAAC,EACF;YACE,WAAW;SACZ,CACF,CACJ,CAAA;QAEH,OAAO,sBAAsB,CAAC,mBAAmB,CAAC,iCAAiC,CACjF,sBAAsB,CACvB,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,8BAAoB,IAAI,KAAK,CAAC,cAAc,KAAK,GAAG,EAAE,CAAC;YAC1E,OAAM;QACR,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAtCD,qCAsCC","sourcesContent":["import { GetObjectCommand, GetObjectCommandOutput } from '@aws-sdk/client-s3'\nimport { DownloadOptions, StorageConstructorOptions } from './types'\nimport { generateS3Client } from './generateS3Client'\nimport OneBlinkStorageError from './OneBlinkStorageError'\n\nexport default async function downloadJsonFromS3<T>({\n key,\n abortSignal,\n ...storageConstructorOptions\n}: DownloadOptions &\n StorageConstructorOptions & {\n key: string\n }): Promise<T | undefined> {\n const { s3Client, bucket, oneBlinkRequestHandler } = generateS3Client({\n ...storageConstructorOptions,\n requestBodyHeader: undefined,\n })\n\n try {\n const getObjectCommandOutput =\n await oneBlinkRequestHandler.sendS3Command<GetObjectCommandOutput>(\n async () =>\n await s3Client.send(\n new GetObjectCommand({\n Bucket: bucket,\n Key: key,\n }),\n {\n abortSignal,\n },\n ),\n )\n\n return oneBlinkRequestHandler.oneBlinkHttpHandler.parseGetObjectCommandOutputAsJson<T>(\n getObjectCommandOutput,\n )\n } catch (error) {\n if (error instanceof OneBlinkStorageError && error.httpStatusCode === 403) {\n return\n } else {\n throw error\n }\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { S3Client } from '@aws-sdk/client-s3';
2
+ import { StorageConstructorOptions } from './types';
3
+ import { OneBlinkRequestHandler } from './OneBlinkRequestHandler';
4
+ import { RequestBodyHeader } from './http-handlers/types';
5
+ export declare function generateS3Client<T>({ region, apiOrigin, getBearerToken, requestBodyHeader, }: StorageConstructorOptions & {
6
+ requestBodyHeader?: RequestBodyHeader;
7
+ }): {
8
+ bucket: string;
9
+ oneBlinkRequestHandler: OneBlinkRequestHandler<T>;
10
+ s3Client: S3Client;
11
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateS3Client = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const http_handlers_1 = require("./http-handlers");
6
+ const OneBlinkRequestHandler_1 = require("./OneBlinkRequestHandler");
7
+ const RETRY_ATTEMPTS = 3;
8
+ function generateS3Client({ region, apiOrigin, getBearerToken, requestBodyHeader, }) {
9
+ const oneBlinkHttpHandler = (0, http_handlers_1.getOneBlinkHttpHandler)();
10
+ const oneBlinkRequestHandler = new OneBlinkRequestHandler_1.OneBlinkRequestHandler(oneBlinkHttpHandler, requestBodyHeader);
11
+ // The endpoint we use instead of the the AWS S3 endpoint is
12
+ // formatted internally by the AWS S3 SDK. It will add the Bucket
13
+ // parameter below as the subdomain to the URL (as long as the
14
+ // bucket does not contain a `.`). The logic below allows the final
15
+ // URL used to upload the object to be the origin that is passed in.
16
+ // The suffix on the end is important as it will allow us to route
17
+ // traffic to S3 via lambda at edge instead of going to our API.
18
+ const url = new URL(apiOrigin);
19
+ url.pathname = '/storage';
20
+ const [bucket, ...domainParts] = url.hostname.split('.');
21
+ url.hostname = domainParts.join('.');
22
+ return {
23
+ bucket,
24
+ oneBlinkRequestHandler,
25
+ s3Client: new client_s3_1.S3Client({
26
+ endpoint: url.href,
27
+ region,
28
+ maxAttempts: RETRY_ATTEMPTS,
29
+ requestHandler: oneBlinkRequestHandler,
30
+ // Sign requests with our own Authorization header instead
31
+ // of letting AWS SDK attempt to generate credentials
32
+ signer: {
33
+ sign: async (request) => {
34
+ const token = await getBearerToken();
35
+ if (token) {
36
+ request.headers['authorization'] = 'Bearer ' + token;
37
+ }
38
+ return request;
39
+ },
40
+ },
41
+ }),
42
+ };
43
+ }
44
+ exports.generateS3Client = generateS3Client;
45
+ //# sourceMappingURL=generateS3Client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateS3Client.js","sourceRoot":"","sources":["../src/generateS3Client.ts"],"names":[],"mappings":";;;AAAA,kDAA6C;AAE7C,mDAAwD;AACxD,qEAAiE;AAGjE,MAAM,cAAc,GAAG,CAAC,CAAA;AAExB,SAAgB,gBAAgB,CAAI,EAClC,MAAM,EACN,SAAS,EACT,cAAc,EACd,iBAAiB,GAGlB;IACC,MAAM,mBAAmB,GAAG,IAAA,sCAAsB,GAAE,CAAA;IACpD,MAAM,sBAAsB,GAAG,IAAI,+CAAsB,CACvD,mBAAmB,EACnB,iBAAiB,CAClB,CAAA;IAED,4DAA4D;IAC5D,iEAAiE;IACjE,8DAA8D;IAC9D,mEAAmE;IACnE,oEAAoE;IACpE,kEAAkE;IAClE,gEAAgE;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IAC9B,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAA;IACzB,MAAM,CAAC,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxD,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEpC,OAAO;QACL,MAAM;QACN,sBAAsB;QACtB,QAAQ,EAAE,IAAI,oBAAQ,CAAC;YACrB,QAAQ,EAAE,GAAG,CAAC,IAAI;YAClB,MAAM;YACN,WAAW,EAAE,cAAc;YAC3B,cAAc,EAAE,sBAAsB;YACtC,0DAA0D;YAC1D,qDAAqD;YACrD,MAAM,EAAE;gBACN,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBACtB,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAA;oBACpC,IAAI,KAAK,EAAE,CAAC;wBACV,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,GAAG,KAAK,CAAA;oBACtD,CAAC;oBAED,OAAO,OAAO,CAAA;gBAChB,CAAC;aACF;SACF,CAAC;KACH,CAAA;AACH,CAAC;AAhDD,4CAgDC","sourcesContent":["import { S3Client } from '@aws-sdk/client-s3'\nimport { StorageConstructorOptions } from './types'\nimport { getOneBlinkHttpHandler } from './http-handlers'\nimport { OneBlinkRequestHandler } from './OneBlinkRequestHandler'\nimport { RequestBodyHeader } from './http-handlers/types'\n\nconst RETRY_ATTEMPTS = 3\n\nexport function generateS3Client<T>({\n region,\n apiOrigin,\n getBearerToken,\n requestBodyHeader,\n}: StorageConstructorOptions & {\n requestBodyHeader?: RequestBodyHeader\n}) {\n const oneBlinkHttpHandler = getOneBlinkHttpHandler()\n const oneBlinkRequestHandler = new OneBlinkRequestHandler<T>(\n oneBlinkHttpHandler,\n requestBodyHeader,\n )\n\n // The endpoint we use instead of the the AWS S3 endpoint is\n // formatted internally by the AWS S3 SDK. It will add the Bucket\n // parameter below as the subdomain to the URL (as long as the\n // bucket does not contain a `.`). The logic below allows the final\n // URL used to upload the object to be the origin that is passed in.\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 const url = new URL(apiOrigin)\n url.pathname = '/storage'\n const [bucket, ...domainParts] = url.hostname.split('.')\n url.hostname = domainParts.join('.')\n\n return {\n bucket,\n oneBlinkRequestHandler,\n s3Client: new S3Client({\n endpoint: url.href,\n region,\n maxAttempts: RETRY_ATTEMPTS,\n requestHandler: oneBlinkRequestHandler,\n // Sign requests with our own Authorization header instead\n // of letting AWS SDK attempt to generate credentials\n signer: {\n sign: async (request) => {\n const token = await getBearerToken()\n if (token) {\n request.headers['authorization'] = 'Bearer ' + token\n }\n\n return request\n },\n },\n }),\n }\n}\n"]}
@@ -1,11 +1,13 @@
1
1
  import { HttpRequest, HttpResponse } from '@smithy/protocol-http';
2
2
  import { HttpHandlerOptions } from '@smithy/types';
3
3
  import { IOneBlinkHttpHandler } from './types';
4
+ import { GetObjectCommandOutput } from '@aws-sdk/client-s3';
4
5
  export declare class OneBlinkFetchHandler implements IOneBlinkHttpHandler {
5
6
  handleRequest(request: HttpRequest, options?: HttpHandlerOptions): Promise<HttpResponse>;
6
7
  handleFailResponse(response: HttpResponse): Promise<{
7
8
  statusCode: number;
8
9
  message: any;
9
10
  }>;
10
- determineQueueSize(): 1 | 2 | 10;
11
+ parseGetObjectCommandOutputAsJson<T>(getObjectCommandOutput: GetObjectCommandOutput): Promise<T | undefined>;
12
+ determineUploadQueueSize(): 1 | 2 | 10;
11
13
  }
@@ -26,7 +26,14 @@ class OneBlinkFetchHandler {
26
26
  }
27
27
  }
28
28
  }
29
- determineQueueSize() {
29
+ async parseGetObjectCommandOutputAsJson(getObjectCommandOutput) {
30
+ if (getObjectCommandOutput.Body instanceof Blob ||
31
+ (window.ReadableStream &&
32
+ getObjectCommandOutput.Body instanceof window.ReadableStream)) {
33
+ return (await new Response(getObjectCommandOutput.Body).json());
34
+ }
35
+ }
36
+ determineUploadQueueSize() {
30
37
  const effectiveType = window.navigator &&
31
38
  'connection' in window.navigator &&
32
39
  !!window.navigator.connection &&
@@ -1 +1 @@
1
- {"version":3,"file":"FetchHandler.js","sourceRoot":"","sources":["../../src/http-handlers/FetchHandler.ts"],"names":[],"mappings":";;;AAIA,MAAa,oBAAoB;IAC/B,KAAK,CAAC,aAAa,CAAC,OAAoB,EAAE,OAA4B;QACpE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAA;QACvE,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAA;QAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACpE,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAsB;QAC7C,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEjD,QAAQ,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,KAAK,iCAAiC,CAAC;YACvC,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,OAAO;oBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO;iBAC9C,CAAA;YACH,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO;oBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,MAAM,aAAa,CAAC,IAAI,EAAE;iBACpC,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB;QAChB,MAAM,aAAa,GACjB,MAAM,CAAC,SAAS;YAChB,YAAY,IAAI,MAAM,CAAC,SAAS;YAChC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU;YAC7B,OAAO,MAAM,CAAC,SAAS,CAAC,UAAU,KAAK,QAAQ;YAC/C,eAAe,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU;YAC5C,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,aAAa;YAC3C,CAAC,CAAC,SAAS,CAAA;QACf,QAAQ,aAAa,EAAE,CAAC;YACtB,KAAK,IAAI;gBACP,OAAO,EAAE,CAAA;YACX,KAAK,IAAI;gBACP,OAAO,CAAC,CAAA;YACV,KAAK,SAAS,CAAC;YACf,KAAK,IAAI,CAAC;YACV,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,CAAC,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAjDD,oDAiDC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { IOneBlinkHttpHandler } from './types'\n\nexport class OneBlinkFetchHandler implements IOneBlinkHttpHandler {\n async handleRequest(request: HttpRequest, options?: HttpHandlerOptions) {\n const { FetchHttpHandler } = await import('@smithy/fetch-http-handler')\n const fetchHttpHandler = new FetchHttpHandler()\n const { response } = await fetchHttpHandler.handle(request, options)\n return response\n }\n\n async handleFailResponse(response: HttpResponse) {\n const fetchResponse = new Response(response.body)\n\n switch (response.headers['content-type']) {\n case 'application/json; charset=utf-8':\n case 'application/json': {\n return {\n statusCode: response.statusCode,\n message: (await fetchResponse.json()).message,\n }\n }\n default: {\n return {\n statusCode: response.statusCode,\n message: await fetchResponse.text(),\n }\n }\n }\n }\n\n determineQueueSize() {\n const effectiveType =\n window.navigator &&\n 'connection' in window.navigator &&\n !!window.navigator.connection &&\n typeof window.navigator.connection === 'object' &&\n 'effectiveType' in window.navigator.connection\n ? window.navigator.connection.effectiveType\n : undefined\n switch (effectiveType) {\n case '4g':\n return 10\n case '3g':\n return 2\n case 'slow-2g':\n case '2g':\n default: {\n return 1\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"FetchHandler.js","sourceRoot":"","sources":["../../src/http-handlers/FetchHandler.ts"],"names":[],"mappings":";;;AAKA,MAAa,oBAAoB;IAC/B,KAAK,CAAC,aAAa,CAAC,OAAoB,EAAE,OAA4B;QACpE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAA;QACvE,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAA;QAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACpE,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAsB;QAC7C,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEjD,QAAQ,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,KAAK,iCAAiC,CAAC;YACvC,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,OAAO;oBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO;iBAC9C,CAAA;YACH,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO;oBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,MAAM,aAAa,CAAC,IAAI,EAAE;iBACpC,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iCAAiC,CACrC,sBAA8C;QAE9C,IACE,sBAAsB,CAAC,IAAI,YAAY,IAAI;YAC3C,CAAC,MAAM,CAAC,cAAc;gBACpB,sBAAsB,CAAC,IAAI,YAAY,MAAM,CAAC,cAAc,CAAC,EAC/D,CAAC;YACD,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAM,CAAA;QACtE,CAAC;IACH,CAAC;IAED,wBAAwB;QACtB,MAAM,aAAa,GACjB,MAAM,CAAC,SAAS;YAChB,YAAY,IAAI,MAAM,CAAC,SAAS;YAChC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU;YAC7B,OAAO,MAAM,CAAC,SAAS,CAAC,UAAU,KAAK,QAAQ;YAC/C,eAAe,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU;YAC5C,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,aAAa;YAC3C,CAAC,CAAC,SAAS,CAAA;QACf,QAAQ,aAAa,EAAE,CAAC;YACtB,KAAK,IAAI;gBACP,OAAO,EAAE,CAAA;YACX,KAAK,IAAI;gBACP,OAAO,CAAC,CAAA;YACV,KAAK,SAAS,CAAC;YACf,KAAK,IAAI,CAAC;YACV,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,CAAC,CAAA;YACV,CAAC;QACH,CAAC;IACH,CAAC;CACF;AA7DD,oDA6DC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { IOneBlinkHttpHandler } from './types'\nimport { GetObjectCommandOutput } from '@aws-sdk/client-s3'\n\nexport class OneBlinkFetchHandler implements IOneBlinkHttpHandler {\n async handleRequest(request: HttpRequest, options?: HttpHandlerOptions) {\n const { FetchHttpHandler } = await import('@smithy/fetch-http-handler')\n const fetchHttpHandler = new FetchHttpHandler()\n const { response } = await fetchHttpHandler.handle(request, options)\n return response\n }\n\n async handleFailResponse(response: HttpResponse) {\n const fetchResponse = new Response(response.body)\n\n switch (response.headers['content-type']) {\n case 'application/json; charset=utf-8':\n case 'application/json': {\n return {\n statusCode: response.statusCode,\n message: (await fetchResponse.json()).message,\n }\n }\n default: {\n return {\n statusCode: response.statusCode,\n message: await fetchResponse.text(),\n }\n }\n }\n }\n\n async parseGetObjectCommandOutputAsJson<T>(\n getObjectCommandOutput: GetObjectCommandOutput,\n ): Promise<T | undefined> {\n if (\n getObjectCommandOutput.Body instanceof Blob ||\n (window.ReadableStream &&\n getObjectCommandOutput.Body instanceof window.ReadableStream)\n ) {\n return (await new Response(getObjectCommandOutput.Body).json()) as T\n }\n }\n\n determineUploadQueueSize() {\n const effectiveType =\n window.navigator &&\n 'connection' in window.navigator &&\n !!window.navigator.connection &&\n typeof window.navigator.connection === 'object' &&\n 'effectiveType' in window.navigator.connection\n ? window.navigator.connection.effectiveType\n : undefined\n switch (effectiveType) {\n case '4g':\n return 10\n case '3g':\n return 2\n case 'slow-2g':\n case '2g':\n default: {\n return 1\n }\n }\n }\n}\n"]}
@@ -1,11 +1,13 @@
1
1
  import { HttpRequest, HttpResponse } from '@smithy/protocol-http';
2
2
  import { HttpHandlerOptions } from '@smithy/types';
3
3
  import { IOneBlinkHttpHandler } from './types';
4
+ import { GetObjectCommandOutput } from '@aws-sdk/client-s3';
4
5
  export declare class OneBlinkNodeJsHandler implements IOneBlinkHttpHandler {
5
6
  handleRequest(request: HttpRequest, options?: HttpHandlerOptions | undefined): Promise<HttpResponse>;
6
7
  handleFailResponse(response: HttpResponse): Promise<{
7
8
  statusCode: number;
8
9
  message: any;
9
10
  } | undefined>;
10
- determineQueueSize(): number;
11
+ parseGetObjectCommandOutputAsJson<T>(getObjectCommandOutput: GetObjectCommandOutput): Promise<T | undefined>;
12
+ determineUploadQueueSize(): number;
11
13
  }
@@ -29,9 +29,10 @@ class OneBlinkNodeJsHandler {
29
29
  }
30
30
  break;
31
31
  }
32
- case 'text/html': {
33
- const { Readable, consumers } = await import('stream');
32
+ default: {
33
+ const { Readable } = await import('stream');
34
34
  if (response.body instanceof Readable) {
35
+ const consumers = await import('stream/consumers');
35
36
  return {
36
37
  statusCode: response.statusCode,
37
38
  message: await consumers.text(response.body),
@@ -47,7 +48,14 @@ class OneBlinkNodeJsHandler {
47
48
  }
48
49
  }
49
50
  }
50
- determineQueueSize() {
51
+ async parseGetObjectCommandOutputAsJson(getObjectCommandOutput) {
52
+ const { Readable } = await import('stream');
53
+ if (getObjectCommandOutput.Body instanceof Readable) {
54
+ const consumers = await import('stream/consumers');
55
+ return (await consumers.json(getObjectCommandOutput.Body));
56
+ }
57
+ }
58
+ determineUploadQueueSize() {
51
59
  return 10;
52
60
  }
53
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NodeJsHandler.js","sourceRoot":"","sources":["../../src/http-handlers/NodeJsHandler.ts"],"names":[],"mappings":";;;AAIA,MAAa,qBAAqB;IAChC,KAAK,CAAC,aAAa,CACjB,OAAoB,EACpB,OAAwC;QAExC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAA;QACrE,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC7C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACnE,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAsB;QAC7C,QAAQ,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,KAAK,iCAAiC,CAAC;YACvC,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAC3C,IAAI,QAAQ,CAAC,IAAI,YAAY,QAAQ,EAAE,CAAC;oBACtC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;oBAClD,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAkB;6BAC7D,OAAO;qBACX,CAAA;gBACH,CAAC;gBAED,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtC,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO;qBAC3C,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;gBACtD,IAAI,QAAQ,CAAC,IAAI,YAAY,QAAQ,EAAE,CAAC;oBACtC,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;qBAC7C,CAAA;gBACH,CAAC;gBAED,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtC,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,QAAQ,CAAC,IAAI;qBACvB,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB;QAChB,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAxDD,sDAwDC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { IOneBlinkHttpHandler, FailResponse } from './types'\n\nexport class OneBlinkNodeJsHandler implements IOneBlinkHttpHandler {\n async handleRequest(\n request: HttpRequest,\n options?: HttpHandlerOptions | undefined,\n ) {\n const { NodeHttpHandler } = await import('@smithy/node-http-handler')\n const nodeHttpHandler = new NodeHttpHandler()\n const { response } = await nodeHttpHandler.handle(request, options)\n return response\n }\n\n async handleFailResponse(response: HttpResponse) {\n switch (response.headers['content-type']) {\n case 'application/json; charset=utf-8':\n case 'application/json': {\n const { Readable } = await import('stream')\n if (response.body instanceof Readable) {\n const consumers = await import('stream/consumers')\n return {\n statusCode: response.statusCode,\n message: ((await consumers.json(response.body)) as FailResponse)\n .message,\n }\n }\n\n if (typeof response.body === 'string') {\n return {\n statusCode: response.statusCode,\n message: JSON.parse(response.body).message,\n }\n }\n break\n }\n case 'text/html': {\n const { Readable, consumers } = await import('stream')\n if (response.body instanceof Readable) {\n return {\n statusCode: response.statusCode,\n message: await consumers.text(response.body),\n }\n }\n\n if (typeof response.body === 'string') {\n return {\n statusCode: response.statusCode,\n message: response.body,\n }\n }\n break\n }\n }\n }\n\n determineQueueSize() {\n return 10\n }\n}\n"]}
1
+ {"version":3,"file":"NodeJsHandler.js","sourceRoot":"","sources":["../../src/http-handlers/NodeJsHandler.ts"],"names":[],"mappings":";;;AAKA,MAAa,qBAAqB;IAChC,KAAK,CAAC,aAAa,CACjB,OAAoB,EACpB,OAAwC;QAExC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAA;QACrE,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC7C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACnE,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAsB;QAC7C,QAAQ,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,KAAK,iCAAiC,CAAC;YACvC,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAC3C,IAAI,QAAQ,CAAC,IAAI,YAAY,QAAQ,EAAE,CAAC;oBACtC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;oBAClD,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAkB;6BAC7D,OAAO;qBACX,CAAA;gBACH,CAAC;gBAED,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtC,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO;qBAC3C,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAC3C,IAAI,QAAQ,CAAC,IAAI,YAAY,QAAQ,EAAE,CAAC;oBACtC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;oBAClD,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;qBAC7C,CAAA;gBACH,CAAC;gBAED,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtC,OAAO;wBACL,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,OAAO,EAAE,QAAQ,CAAC,IAAI;qBACvB,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iCAAiC,CACrC,sBAA8C;QAE9C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC3C,IAAI,sBAAsB,CAAC,IAAI,YAAY,QAAQ,EAAE,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;YAClD,OAAO,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAM,CAAA;QACjE,CAAC;IACH,CAAC;IAED,wBAAwB;QACtB,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAnED,sDAmEC","sourcesContent":["import { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\nimport { IOneBlinkHttpHandler, FailResponse } from './types'\nimport { GetObjectCommandOutput } from '@aws-sdk/client-s3'\n\nexport class OneBlinkNodeJsHandler implements IOneBlinkHttpHandler {\n async handleRequest(\n request: HttpRequest,\n options?: HttpHandlerOptions | undefined,\n ) {\n const { NodeHttpHandler } = await import('@smithy/node-http-handler')\n const nodeHttpHandler = new NodeHttpHandler()\n const { response } = await nodeHttpHandler.handle(request, options)\n return response\n }\n\n async handleFailResponse(response: HttpResponse) {\n switch (response.headers['content-type']) {\n case 'application/json; charset=utf-8':\n case 'application/json': {\n const { Readable } = await import('stream')\n if (response.body instanceof Readable) {\n const consumers = await import('stream/consumers')\n return {\n statusCode: response.statusCode,\n message: ((await consumers.json(response.body)) as FailResponse)\n .message,\n }\n }\n\n if (typeof response.body === 'string') {\n return {\n statusCode: response.statusCode,\n message: JSON.parse(response.body).message,\n }\n }\n break\n }\n default: {\n const { Readable } = await import('stream')\n if (response.body instanceof Readable) {\n const consumers = await import('stream/consumers')\n return {\n statusCode: response.statusCode,\n message: await consumers.text(response.body),\n }\n }\n\n if (typeof response.body === 'string') {\n return {\n statusCode: response.statusCode,\n message: response.body,\n }\n }\n break\n }\n }\n }\n\n async parseGetObjectCommandOutputAsJson<T>(\n getObjectCommandOutput: GetObjectCommandOutput,\n ): Promise<T | undefined> {\n const { Readable } = await import('stream')\n if (getObjectCommandOutput.Body instanceof Readable) {\n const consumers = await import('stream/consumers')\n return (await consumers.json(getObjectCommandOutput.Body)) as T\n }\n }\n\n determineUploadQueueSize() {\n return 10\n }\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { GetObjectCommandOutput } from '@aws-sdk/client-s3';
1
2
  import { AWSTypes } from '@oneblink/types';
2
3
  import { HttpRequest, HttpResponse } from '@smithy/protocol-http';
3
4
  import { HttpHandlerOptions } from '@smithy/types';
@@ -11,6 +12,7 @@ export type FailResponse = {
11
12
  };
12
13
  export interface IOneBlinkHttpHandler {
13
14
  handleRequest: (request: HttpRequest, options?: HttpHandlerOptions) => Promise<HttpResponse>;
15
+ parseGetObjectCommandOutputAsJson: <T>(getObjectCommandOutput: GetObjectCommandOutput) => Promise<T | undefined>;
14
16
  handleFailResponse: (response: HttpResponse) => Promise<FailResponse | undefined>;
15
- determineQueueSize: () => number;
17
+ determineUploadQueueSize: () => number;
16
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http-handlers/types.ts"],"names":[],"mappings":"","sourcesContent":["import { AWSTypes } from '@oneblink/types'\nimport { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\n\nexport type RequestBodyHeader = Record<string, unknown>\n\nexport type OneBlinkResponse<T> = T & {\n s3: AWSTypes.S3Configuration\n}\nexport type FailResponse = {\n statusCode: number\n message: string\n}\n\nexport interface IOneBlinkHttpHandler {\n handleRequest: (\n request: HttpRequest,\n options?: HttpHandlerOptions,\n ) => Promise<HttpResponse>\n handleFailResponse: (\n response: HttpResponse,\n ) => Promise<FailResponse | undefined>\n determineQueueSize: () => number\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/http-handlers/types.ts"],"names":[],"mappings":"","sourcesContent":["import { GetObjectCommandOutput } from '@aws-sdk/client-s3'\nimport { AWSTypes } from '@oneblink/types'\nimport { HttpRequest, HttpResponse } from '@smithy/protocol-http'\nimport { HttpHandlerOptions } from '@smithy/types'\n\nexport type RequestBodyHeader = Record<string, unknown>\n\nexport type OneBlinkResponse<T> = T & {\n s3: AWSTypes.S3Configuration\n}\nexport type FailResponse = {\n statusCode: number\n message: string\n}\n\nexport interface IOneBlinkHttpHandler {\n handleRequest: (\n request: HttpRequest,\n options?: HttpHandlerOptions,\n ) => Promise<HttpResponse>\n parseGetObjectCommandOutputAsJson: <T>(\n getObjectCommandOutput: GetObjectCommandOutput,\n ) => Promise<T | undefined>\n handleFailResponse: (\n response: HttpResponse,\n ) => Promise<FailResponse | undefined>\n determineUploadQueueSize: () => number\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as OneBlinkStorageError } from './OneBlinkStorageError';
2
2
  export { default as OneBlinkUploader } from './OneBlinkUploader';
3
+ export { default as OneBlinkDownloader } from './OneBlinkDownloader';
3
4
  export * from './types';
package/dist/index.js CHANGED
@@ -17,10 +17,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.OneBlinkUploader = exports.OneBlinkStorageError = void 0;
20
+ exports.OneBlinkDownloader = exports.OneBlinkUploader = exports.OneBlinkStorageError = void 0;
21
21
  var OneBlinkStorageError_1 = require("./OneBlinkStorageError");
22
22
  Object.defineProperty(exports, "OneBlinkStorageError", { enumerable: true, get: function () { return __importDefault(OneBlinkStorageError_1).default; } });
23
23
  var OneBlinkUploader_1 = require("./OneBlinkUploader");
24
24
  Object.defineProperty(exports, "OneBlinkUploader", { enumerable: true, get: function () { return __importDefault(OneBlinkUploader_1).default; } });
25
+ var OneBlinkDownloader_1 = require("./OneBlinkDownloader");
26
+ Object.defineProperty(exports, "OneBlinkDownloader", { enumerable: true, get: function () { return __importDefault(OneBlinkDownloader_1).default; } });
25
27
  __exportStar(require("./types"), exports);
26
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,+DAAwE;AAA/D,6IAAA,OAAO,OAAwB;AACxC,uDAAgE;AAAvD,qIAAA,OAAO,OAAoB;AACpC,0CAAuB","sourcesContent":["export { default as OneBlinkStorageError } from './OneBlinkStorageError'\nexport { default as OneBlinkUploader } from './OneBlinkUploader'\nexport * from './types'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,+DAAwE;AAA/D,6IAAA,OAAO,OAAwB;AACxC,uDAAgE;AAAvD,qIAAA,OAAO,OAAoB;AACpC,2DAAoE;AAA3D,yIAAA,OAAO,OAAsB;AACtC,0CAAuB","sourcesContent":["export { default as OneBlinkStorageError } from './OneBlinkStorageError'\nexport { default as OneBlinkUploader } from './OneBlinkUploader'\nexport { default as OneBlinkDownloader } from './OneBlinkDownloader'\nexport * from './types'\n"]}
package/dist/types.d.ts CHANGED
@@ -18,12 +18,14 @@ export type StorageConstructorOptions = {
18
18
  */
19
19
  getBearerToken: () => Promise<string | undefined>;
20
20
  };
21
- export type UploadOptions = {
22
- /** An optional progress listener for tracking the progress of the upload */
23
- onProgress?: ProgressListener;
21
+ export type DownloadOptions = {
24
22
  /** An optional AbortSignal that can be used to abort the upload */
25
23
  abortSignal?: AbortSignal;
26
24
  };
25
+ export type UploadOptions = DownloadOptions & {
26
+ /** An optional progress listener for tracking the progress of the upload */
27
+ onProgress?: ProgressListener;
28
+ };
27
29
  export type AttachmentUploadData = NonNullable<PutObjectCommandInput['Body']>;
28
30
  export type UploadFormSubmissionOptions = UploadOptions & {
29
31
  /** The submission data */
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PutObjectCommandInput } from '@aws-sdk/client-s3'\nimport { SubmissionTypes } from '@oneblink/types'\n\nexport type ProgressListenerEvent = { progress: number; total: number }\nexport type ProgressListener = (progress: ProgressListenerEvent) => void\n\n/** The properties to be passed to the Storage class constructors */\nexport type StorageConstructorOptions = {\n /** The API origin URL used to communicate with the OneBlink API */\n apiOrigin: string\n /** The AWS region to upload the submission to */\n region: string\n /**\n * A function that returns a promise resolving to a Bearer token. If the\n * promise resolves to a truthy value, the `authorization` header will be set\n * with the value.\n */\n getBearerToken: () => Promise<string | undefined>\n}\n\nexport type UploadOptions = {\n /** An optional progress listener for tracking the progress of the upload */\n onProgress?: ProgressListener\n /** An optional AbortSignal that can be used to abort the upload */\n abortSignal?: AbortSignal\n}\n\nexport type AttachmentUploadData = NonNullable<PutObjectCommandInput['Body']>\n\nexport type UploadFormSubmissionOptions = UploadOptions & {\n /** The submission data */\n submission: SubmissionTypes.NewS3SubmissionData['submission']\n /** The form that is being submitted */\n definition: SubmissionTypes.NewS3SubmissionData['definition']\n /** The device the form is being submitted */\n device?: SubmissionTypes.NewS3SubmissionData['device']\n /** The identifier for the forms app that is being submitted from */\n formsAppId: number\n /** An encrypted token that represents the user */\n userToken?: string\n /** The external identifier that represents the submission */\n externalId?: string\n /**\n * The identifier for the previous FormSubmissionApproval that lead to a\n * clarification request\n */\n previousFormSubmissionApprovalId?: string\n /** The identifier of the job that will be marked as submitted */\n jobId?: string\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}\n\nexport type UploadAssetOptions = UploadOptions & {\n /** The file data to upload */\n data: AttachmentUploadData\n /** A standard MIME type describing the format of the contents */\n contentType: string\n /** The name of the file being uploaded */\n fileName: string\n}\n\nexport type UploadPDFConversionOptions = UploadOptions & {\n /** The PDF File to upload */\n data: AttachmentUploadData\n /** The id of the Form that the PDF Conversion is occurring on */\n formId: number\n}\n\nexport type UploadEmailAttachmentOptions = UploadAssetOptions\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { PutObjectCommandInput } from '@aws-sdk/client-s3'\nimport { SubmissionTypes } from '@oneblink/types'\n\nexport type ProgressListenerEvent = { progress: number; total: number }\nexport type ProgressListener = (progress: ProgressListenerEvent) => void\n\n/** The properties to be passed to the Storage class constructors */\nexport type StorageConstructorOptions = {\n /** The API origin URL used to communicate with the OneBlink API */\n apiOrigin: string\n /** The AWS region to upload the submission to */\n region: string\n /**\n * A function that returns a promise resolving to a Bearer token. If the\n * promise resolves to a truthy value, the `authorization` header will be set\n * with the value.\n */\n getBearerToken: () => Promise<string | undefined>\n}\n\nexport type DownloadOptions = {\n /** An optional AbortSignal that can be used to abort the upload */\n abortSignal?: AbortSignal\n}\n\nexport type UploadOptions = DownloadOptions & {\n /** An optional progress listener for tracking the progress of the upload */\n onProgress?: ProgressListener\n}\n\nexport type AttachmentUploadData = NonNullable<PutObjectCommandInput['Body']>\n\nexport type UploadFormSubmissionOptions = UploadOptions & {\n /** The submission data */\n submission: SubmissionTypes.NewS3SubmissionData['submission']\n /** The form that is being submitted */\n definition: SubmissionTypes.NewS3SubmissionData['definition']\n /** The device the form is being submitted */\n device?: SubmissionTypes.NewS3SubmissionData['device']\n /** The identifier for the forms app that is being submitted from */\n formsAppId: number\n /** An encrypted token that represents the user */\n userToken?: string\n /** The external identifier that represents the submission */\n externalId?: string\n /**\n * The identifier for the previous FormSubmissionApproval that lead to a\n * clarification request\n */\n previousFormSubmissionApprovalId?: string\n /** The identifier of the job that will be marked as submitted */\n jobId?: string\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}\n\nexport type UploadAssetOptions = UploadOptions & {\n /** The file data to upload */\n data: AttachmentUploadData\n /** A standard MIME type describing the format of the contents */\n contentType: string\n /** The name of the file being uploaded */\n fileName: string\n}\n\nexport type UploadPDFConversionOptions = UploadOptions & {\n /** The PDF File to upload */\n data: AttachmentUploadData\n /** The id of the Form that the PDF Conversion is occurring on */\n formId: number\n}\n\nexport type UploadEmailAttachmentOptions = UploadAssetOptions\n"]}
@@ -20,6 +20,6 @@ interface UploadToS3Props extends UploadOptions, StorageConstructorOptions {
20
20
  /** Set to `true` to make the upload available to download publicly */
21
21
  isPublic?: boolean;
22
22
  }
23
- declare function uploadToS3<T>({ region, apiOrigin, key, body, requestBodyHeader, tags, getBearerToken, onProgress, abortSignal, contentType, isPublic, }: UploadToS3Props): Promise<import("./http-handlers/types").OneBlinkResponse<T>>;
23
+ declare function uploadToS3<T>({ key, body, tags, onProgress, abortSignal, contentType, isPublic, ...storageConstructorOptions }: UploadToS3Props): Promise<import("./http-handlers/types").OneBlinkResponse<T>>;
24
24
  export default uploadToS3;
25
25
  export declare const determineUploadProgressAsPercentage: (progress: Required<Pick<Progress, 'total'>> & Omit<Progress, 'total'>) => number;
@@ -1,53 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.determineUploadProgressAsPercentage = void 0;
7
- const client_s3_1 = require("@aws-sdk/client-s3");
8
4
  const lib_storage_1 = require("@aws-sdk/lib-storage");
9
- const OneBlinkStorageError_1 = __importDefault(require("./OneBlinkStorageError"));
10
- const http_handlers_1 = require("./http-handlers");
11
- const OneBlinkRequestHandler_1 = require("./OneBlinkRequestHandler");
12
- const RETRY_ATTEMPTS = 3;
13
- const endpointSuffix = '/storage';
14
- async function uploadToS3({ region, apiOrigin, key, body, requestBodyHeader, tags = new URLSearchParams(), getBearerToken, onProgress, abortSignal, contentType, isPublic, }) {
15
- const oneBlinkHttpHandler = (0, http_handlers_1.getOneBlinkHttpHandler)();
16
- const oneBlinkRequestHandler = new OneBlinkRequestHandler_1.OneBlinkRequestHandler(oneBlinkHttpHandler, requestBodyHeader);
17
- // The endpoint we use instead of the the AWS S3 endpoint is
18
- // formatted internally by the AWS S3 SDK. It will add the Bucket
19
- // parameter below as the subdomain to the URL (as long as the
20
- // bucket does not contain a `.`). The logic below allows the final
21
- // URL used to upload the object to be the origin that is passed in.
22
- // The suffix on the end is important as it will allow us to route
23
- // traffic to S3 via lambda at edge instead of going to our API.
24
- const url = new URL(endpointSuffix, apiOrigin);
25
- const [bucket, ...domainParts] = url.hostname.split('.');
26
- url.hostname = domainParts.join('.');
27
- const s3Client = new client_s3_1.S3Client({
28
- endpoint: url.href,
29
- region: region,
30
- maxAttempts: RETRY_ATTEMPTS,
31
- requestHandler: oneBlinkRequestHandler,
32
- // Sign requests with our own Authorization header instead
33
- // of letting AWS SDK attempt to generate credentials
34
- signer: {
35
- sign: async (request) => {
36
- const token = await getBearerToken();
37
- if (token) {
38
- request.headers['authorization'] = 'Bearer ' + token;
39
- }
40
- return request;
41
- },
42
- },
43
- });
5
+ const generateS3Client_1 = require("./generateS3Client");
6
+ async function uploadToS3({ key, body, tags = new URLSearchParams(), onProgress, abortSignal, contentType, isPublic, ...storageConstructorOptions }) {
7
+ const { s3Client, bucket, oneBlinkRequestHandler } = (0, generateS3Client_1.generateS3Client)(storageConstructorOptions);
44
8
  if (isPublic) {
45
9
  tags.append('public-read', 'yes');
46
10
  }
47
11
  const managedUpload = new lib_storage_1.Upload({
48
12
  client: s3Client,
49
13
  partSize: 5 * 1024 * 1024,
50
- queueSize: oneBlinkHttpHandler.determineQueueSize(),
14
+ queueSize: oneBlinkRequestHandler.oneBlinkHttpHandler.determineUploadQueueSize(),
51
15
  // Related github issue: https://github.com/aws/aws-sdk-js-v3/issues/2311
52
16
  // This is a variable that is set to false by default, setting it to true
53
17
  // means that it will force the upload to fail when one part fails on
@@ -73,20 +37,9 @@ async function uploadToS3({ region, apiOrigin, key, body, requestBodyHeader, tag
73
37
  abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener('abort', () => {
74
38
  managedUpload.abort();
75
39
  });
76
- try {
77
- await managedUpload.done();
78
- }
79
- catch (error) {
80
- if (oneBlinkRequestHandler.failResponse) {
81
- throw new OneBlinkStorageError_1.default(oneBlinkRequestHandler.failResponse.message, {
82
- httpStatusCode: oneBlinkRequestHandler.failResponse.statusCode,
83
- originalError: error instanceof Error ? error : undefined,
84
- });
85
- }
86
- throw error;
87
- }
40
+ await oneBlinkRequestHandler.sendS3Command(async () => await managedUpload.done());
88
41
  if (!oneBlinkRequestHandler.oneblinkResponse) {
89
- throw new Error('No response from server. Something went wrong in "@oneblink/uploads".');
42
+ throw new Error('No response from server. Something went wrong in "@oneblink/storage".');
90
43
  }
91
44
  return oneBlinkRequestHandler.oneblinkResponse;
92
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uploadToS3.js","sourceRoot":"","sources":["../src/uploadToS3.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAoE;AACpE,sDAAuD;AAEvD,kFAAyD;AAEzD,mDAAwD;AACxD,qEAAiE;AAEjE,MAAM,cAAc,GAAG,CAAC,CAAA;AAExB,MAAM,cAAc,GAAG,UAAU,CAAA;AAqBjC,KAAK,UAAU,UAAU,CAAI,EAC3B,MAAM,EACN,SAAS,EACT,GAAG,EACH,IAAI,EACJ,iBAAiB,EACjB,IAAI,GAAG,IAAI,eAAe,EAAE,EAC5B,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,GACQ;IAChB,MAAM,mBAAmB,GAAG,IAAA,sCAAsB,GAAE,CAAA;IACpD,MAAM,sBAAsB,GAAG,IAAI,+CAAsB,CACvD,mBAAmB,EACnB,iBAAiB,CAClB,CAAA;IAED,4DAA4D;IAC5D,iEAAiE;IACjE,8DAA8D;IAC9D,mEAAmE;IACnE,oEAAoE;IACpE,kEAAkE;IAClE,gEAAgE;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;IAC9C,MAAM,CAAC,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxD,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEpC,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAAC;QAC5B,QAAQ,EAAE,GAAG,CAAC,IAAI;QAClB,MAAM,EAAE,MAAM;QACd,WAAW,EAAE,cAAc;QAC3B,cAAc,EAAE,sBAAsB;QACtC,0DAA0D;QAC1D,qDAAqD;QACrD,MAAM,EAAE;YACN,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBACtB,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAA;gBACpC,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,SAAS,GAAG,KAAK,CAAA;gBACtD,CAAC;gBAED,OAAO,OAAO,CAAA;YAChB,CAAC;SACF;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,oBAAM,CAAC;QAC/B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;QACzB,SAAS,EAAE,mBAAmB,CAAC,kBAAkB,EAAE;QACnD,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,gFAAgF;QAChF,iBAAiB,EAAE,IAAI;QACvB,MAAM,EAAE;YACN,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,WAAW;YACxB,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE;SACzB;KACF,CAAC,CAAA;IAEF,aAAa,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE;QAClD,IAAI,UAAU,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,IAAA,2CAAmC,EAAC;gBAClD,GAAG,QAAQ;gBACX,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAC,CAAA;YACF,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QAC1C,aAAa,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,sBAAsB,CAAC,YAAY,EAAE,CAAC;YACxC,MAAM,IAAI,8BAAoB,CAC5B,sBAAsB,CAAC,YAAY,CAAC,OAAO,EAC3C;gBACE,cAAc,EAAE,sBAAsB,CAAC,YAAY,CAAC,UAAU;gBAC9D,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;aAC1D,CACF,CAAA;QACH,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;IAED,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAA;IACH,CAAC;IACD,OAAO,sBAAsB,CAAC,gBAAgB,CAAA;AAChD,CAAC;AAED,kBAAe,UAAU,CAAA;AAElB,MAAM,mCAAmC,GAAG,CACjD,QAAqE,EACrE,EAAE;IACF,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA;IAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC,CAAA;AALY,QAAA,mCAAmC,uCAK/C","sourcesContent":["import { PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'\nimport { Upload, Progress } from '@aws-sdk/lib-storage'\nimport { StorageConstructorOptions, UploadOptions } from './types'\nimport OneBlinkStorageError from './OneBlinkStorageError'\nimport { RequestBodyHeader } from './http-handlers/types'\nimport { getOneBlinkHttpHandler } from './http-handlers'\nimport { OneBlinkRequestHandler } from './OneBlinkRequestHandler'\n\nconst RETRY_ATTEMPTS = 3\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 = new URLSearchParams(),\n getBearerToken,\n onProgress,\n abortSignal,\n contentType,\n isPublic,\n}: UploadToS3Props) {\n const oneBlinkHttpHandler = getOneBlinkHttpHandler()\n const oneBlinkRequestHandler = new OneBlinkRequestHandler<T>(\n oneBlinkHttpHandler,\n requestBodyHeader,\n )\n\n // The endpoint we use instead of the the AWS S3 endpoint is\n // formatted internally by the AWS S3 SDK. It will add the Bucket\n // parameter below as the subdomain to the URL (as long as the\n // bucket does not contain a `.`). The logic below allows the final\n // URL used to upload the object to be the origin that is passed in.\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 const url = new URL(endpointSuffix, apiOrigin)\n const [bucket, ...domainParts] = url.hostname.split('.')\n url.hostname = domainParts.join('.')\n\n const s3Client = new S3Client({\n endpoint: url.href,\n region: region,\n maxAttempts: RETRY_ATTEMPTS,\n requestHandler: oneBlinkRequestHandler,\n // Sign requests with our own Authorization header instead\n // of letting AWS SDK attempt to generate credentials\n signer: {\n sign: async (request) => {\n const token = await getBearerToken()\n if (token) {\n request.headers['authorization'] = 'Bearer ' + token\n }\n\n return request\n },\n },\n })\n\n if (isPublic) {\n tags.append('public-read', 'yes')\n }\n\n const managedUpload = new Upload({\n client: s3Client,\n partSize: 5 * 1024 * 1024,\n queueSize: oneBlinkHttpHandler.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: bucket,\n Key: key,\n Body: body,\n ContentType: contentType,\n Tagging: tags.toString(),\n },\n })\n\n managedUpload.on('httpUploadProgress', (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 try {\n await managedUpload.done()\n } catch (error) {\n if (oneBlinkRequestHandler.failResponse) {\n throw new OneBlinkStorageError(\n oneBlinkRequestHandler.failResponse.message,\n {\n httpStatusCode: oneBlinkRequestHandler.failResponse.statusCode,\n originalError: error instanceof Error ? error : undefined,\n },\n )\n }\n throw error\n }\n\n if (!oneBlinkRequestHandler.oneblinkResponse) {\n throw new Error(\n 'No response from server. Something went wrong in \"@oneblink/uploads\".',\n )\n }\n return oneBlinkRequestHandler.oneblinkResponse\n}\n\nexport default uploadToS3\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":";;;AACA,sDAAuD;AAGvD,yDAAqD;AAqBrD,KAAK,UAAU,UAAU,CAAI,EAC3B,GAAG,EACH,IAAI,EACJ,IAAI,GAAG,IAAI,eAAe,EAAE,EAC5B,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,GAAG,yBAAyB,EACZ;IAChB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAA,mCAAgB,EACnE,yBAAyB,CAC1B,CAAA;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,oBAAM,CAAC;QAC/B,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;QACzB,SAAS,EACP,sBAAsB,CAAC,mBAAmB,CAAC,wBAAwB,EAAE;QACvE,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,gFAAgF;QAChF,iBAAiB,EAAE,IAAI;QACvB,MAAM,EAAE;YACN,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,WAAW;YACxB,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE;SACzB;KACF,CAAC,CAAA;IAEF,aAAa,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE;QAClD,IAAI,UAAU,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,IAAA,2CAAmC,EAAC;gBAClD,GAAG,QAAQ;gBACX,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB,CAAC,CAAA;YACF,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QAC1C,aAAa,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC,CAAC,CAAA;IAEF,MAAM,sBAAsB,CAAC,aAAa,CACxC,KAAK,IAAI,EAAE,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CACvC,CAAA;IAED,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAA;IACH,CAAC;IACD,OAAO,sBAAsB,CAAC,gBAAgB,CAAA;AAChD,CAAC;AAED,kBAAe,UAAU,CAAA;AAElB,MAAM,mCAAmC,GAAG,CACjD,QAAqE,EACrE,EAAE;IACF,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA;IAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC,CAAA;AALY,QAAA,mCAAmC,uCAK/C","sourcesContent":["import { PutObjectCommandInput } from '@aws-sdk/client-s3'\nimport { Upload, Progress } from '@aws-sdk/lib-storage'\nimport { StorageConstructorOptions, UploadOptions } from './types'\nimport { RequestBodyHeader } from './http-handlers/types'\nimport { generateS3Client } from './generateS3Client'\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 key,\n body,\n tags = new URLSearchParams(),\n onProgress,\n abortSignal,\n contentType,\n isPublic,\n ...storageConstructorOptions\n}: UploadToS3Props) {\n const { s3Client, bucket, oneBlinkRequestHandler } = generateS3Client<T>(\n storageConstructorOptions,\n )\n\n if (isPublic) {\n tags.append('public-read', 'yes')\n }\n\n const managedUpload = new Upload({\n client: s3Client,\n partSize: 5 * 1024 * 1024,\n queueSize:\n oneBlinkRequestHandler.oneBlinkHttpHandler.determineUploadQueueSize(),\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: bucket,\n Key: key,\n Body: body,\n ContentType: contentType,\n Tagging: tags.toString(),\n },\n })\n\n managedUpload.on('httpUploadProgress', (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 oneBlinkRequestHandler.sendS3Command(\n async () => await managedUpload.done(),\n )\n\n if (!oneBlinkRequestHandler.oneblinkResponse) {\n throw new Error(\n 'No response from server. Something went wrong in \"@oneblink/storage\".',\n )\n }\n return oneBlinkRequestHandler.oneblinkResponse\n}\n\nexport default uploadToS3\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": "2.0.1",
4
+ "version": "2.1.0-beta.2",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/storage/issues"