From f5fc18bfdf1aefeec8e22a872dfaf51179ee28d4 Mon Sep 17 00:00:00 2001 From: Jules Casteran Date: Thu, 18 Jul 2024 10:59:23 +0200 Subject: [PATCH 1/3] feat(scw): add blob to scw file marshaler --- .../clients/src/scw/custom-marshalling.ts | 14 ++ packages/clients/src/vendor/base64/LICENSE | 21 +++ packages/clients/src/vendor/base64/README.md | 3 + packages/clients/src/vendor/base64/index.d.ts | 3 + packages/clients/src/vendor/base64/index.js | 150 ++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 packages/clients/src/vendor/base64/LICENSE create mode 100644 packages/clients/src/vendor/base64/README.md create mode 100644 packages/clients/src/vendor/base64/index.d.ts create mode 100644 packages/clients/src/vendor/base64/index.js diff --git a/packages/clients/src/scw/custom-marshalling.ts b/packages/clients/src/scw/custom-marshalling.ts index 28f0dc64c..f2cc13e4e 100644 --- a/packages/clients/src/scw/custom-marshalling.ts +++ b/packages/clients/src/scw/custom-marshalling.ts @@ -1,5 +1,6 @@ import { isJSONObject } from '../helpers/json' import { unmarshalArrayOfObject, unmarshalDate } from '../helpers/marshalling' +import { fromByteArray } from '../vendor/base64' import type { Money, ScwFile, @@ -134,6 +135,19 @@ export const marshalScwFile = (obj: ScwFile): Record => ({ name: obj.name, }) +/** + * Marshals {@link Blob}. + * + * @internal + */ +export const marshalBlobToScwFile = async ( + blob: Blob, +): Promise> => ({ + content: fromByteArray(new Uint8Array(await blob.arrayBuffer())), + content_type: blob.type, + name: 'file', +}) + /** * Marshals {@link Money} * diff --git a/packages/clients/src/vendor/base64/LICENSE b/packages/clients/src/vendor/base64/LICENSE new file mode 100644 index 000000000..6d52b8acf --- /dev/null +++ b/packages/clients/src/vendor/base64/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jameson Little + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/clients/src/vendor/base64/README.md b/packages/clients/src/vendor/base64/README.md new file mode 100644 index 000000000..84a043cb6 --- /dev/null +++ b/packages/clients/src/vendor/base64/README.md @@ -0,0 +1,3 @@ +# base64 + +This code is vendored from [github](https://github.com/beatgammit/base64-js) diff --git a/packages/clients/src/vendor/base64/index.d.ts b/packages/clients/src/vendor/base64/index.d.ts new file mode 100644 index 000000000..5566e9e2f --- /dev/null +++ b/packages/clients/src/vendor/base64/index.d.ts @@ -0,0 +1,3 @@ +export function byteLength(b64: string): number +export function toByteArray(b64: string): Uint8Array +export function fromByteArray(uint8: Uint8Array): string diff --git a/packages/clients/src/vendor/base64/index.js b/packages/clients/src/vendor/base64/index.js new file mode 100644 index 000000000..0599f3e4a --- /dev/null +++ b/packages/clients/src/vendor/base64/index.js @@ -0,0 +1,150 @@ +'use strict' + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +// Support decoding URL-safe base64 strings, as Node.js does. +// See: https://en.wikipedia.org/wiki/Base64#URL_applications +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function getLens (b64) { + var len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + var validLen = b64.indexOf('=') + if (validLen === -1) validLen = len + + var placeHoldersLen = validLen === len + ? 0 + : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] +} + +// base64 is 4/3 + up to two characters of the original data +function byteLength (b64) { + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function _byteLength (b64, validLen, placeHoldersLen) { + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function toByteArray (b64) { + var tmp + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + + var curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + var len = placeHoldersLen > 0 + ? validLen - 4 + : validLen + + var i + for (i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xFF + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 2) { + tmp = + (revLookup[b64.charCodeAt(i)] << 2) | + (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + + lookup[num >> 12 & 0x3F] + + lookup[num >> 6 & 0x3F] + + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = + ((uint8[i] << 16) & 0xFF0000) + + ((uint8[i + 1] << 8) & 0xFF00) + + (uint8[i + 2] & 0xFF) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push( + lookup[tmp >> 2] + + lookup[(tmp << 4) & 0x3F] + + '==' + ) + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push( + lookup[tmp >> 10] + + lookup[(tmp >> 4) & 0x3F] + + lookup[(tmp << 2) & 0x3F] + + '=' + ) + } + + return parts.join('') +} From 6f482774424c6d13879773c6133be69182906b69 Mon Sep 17 00:00:00 2001 From: Jules Casteran Date: Thu, 18 Jul 2024 11:02:57 +0200 Subject: [PATCH 2/3] fix: vendor imports --- packages/clients/src/vendor/base64/index.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/clients/src/vendor/base64/index.js b/packages/clients/src/vendor/base64/index.js index 0599f3e4a..c031871ac 100644 --- a/packages/clients/src/vendor/base64/index.js +++ b/packages/clients/src/vendor/base64/index.js @@ -1,9 +1,5 @@ 'use strict' -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - var lookup = [] var revLookup = [] var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array @@ -39,7 +35,7 @@ function getLens (b64) { } // base64 is 4/3 + up to two characters of the original data -function byteLength (b64) { +export function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] @@ -50,7 +46,7 @@ function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } -function toByteArray (b64) { +export function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] @@ -116,7 +112,7 @@ function encodeChunk (uint8, start, end) { return output.join('') } -function fromByteArray (uint8) { +export function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes From de8c9d6dfaee72ad0cf5cf035bb9ea1623a10f5c Mon Sep 17 00:00:00 2001 From: Jules Casteran Date: Thu, 18 Jul 2024 11:06:54 +0200 Subject: [PATCH 3/3] fix: add exports --- packages/clients/src/bridge.ts | 1 + packages/clients/src/internals.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/clients/src/bridge.ts b/packages/clients/src/bridge.ts index 2f48c0919..f43c30ba9 100644 --- a/packages/clients/src/bridge.ts +++ b/packages/clients/src/bridge.ts @@ -16,6 +16,7 @@ export { marshalMoney, marshalTimeSeries, marshalDecimal, + marshalBlobToScwFile, unmarshalMoney, unmarshalScwFile, unmarshalServiceInfo, diff --git a/packages/clients/src/internals.ts b/packages/clients/src/internals.ts index 2487d4c83..925290ea2 100644 --- a/packages/clients/src/internals.ts +++ b/packages/clients/src/internals.ts @@ -15,6 +15,7 @@ export { marshalScwFile, marshalMoney, marshalTimeSeries, + marshalBlobToScwFile, unmarshalDecimal, unmarshalMoney, unmarshalScwFile,