From 2553f6a46b152e80648ce0d0b9b546549813c2a3 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 20:43:18 +0200 Subject: [PATCH 01/19] ci/cd: using minio to test s3 --- .../workflows/test.storage-s3-compatible.yml | 56 +++++++++++++++++++ .../storage-s3-compatible/package.json | 3 +- .../tests/storage.s3-compatible.test.js | 22 ++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.storage-s3-compatible.yml create mode 100644 packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml new file mode 100644 index 00000000..6b3ffa8f --- /dev/null +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -0,0 +1,56 @@ +name: S3 Compatible +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + + +jobs: + + test: + name: Test + env: + _access_key: minioadmin + _secret_key: minioadmin + _bucket: test_bucket + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [22.x] + steps: + - name: Setup minio + run: > + docker run -d -p 9000:9000 --name minio + -e MINIO_ACCESS_KEY=${{env._access_key}} + -e MINIO_SECRET_KEY=${{env._secret_key}} + -v /tmp/data:/data + -v /tmp/config:/root/.minio + minio/minio server /data + - run: wget https://dl.min.io/client/mc/release/linux-amd64/mc + - run: chmod +x ./mc + - run: ./mc alias set minio http://127.0.0.1:9000 ${{env._access_key}} ${{env._secret_key}} + - run: ./mc mb --ignore-existing minio/${{env._bucket}} + + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + working-directory: ./packages/storage/storage-s3-compatible + run: npm ci + + - name: Test + run: npm test + working-directory: ./packages/storage/storage-s3-compatible + env: + ACCESS_KEY_ID: ${{env._access_key}} + SECRET_ACCESS_KEY: ${{env._secret_key}} + BUCKET: ${{env._bucket}}, + ENDPOINT: http://127.0.0.1:9000 + \ No newline at end of file diff --git a/packages/storage/storage-s3-compatible/package.json b/packages/storage/storage-s3-compatible/package.json index ef80f98d..78e43f50 100644 --- a/packages/storage/storage-s3-compatible/package.json +++ b/packages/storage/storage-s3-compatible/package.json @@ -17,8 +17,7 @@ "storecraft" ], "scripts": { - "storage-s3-compatible:test": "uvu -c", - "test": "npm run storage-s3-compatible:test", + "test": "node ./tests/storage.s3-compatible.test.js", "prepublishOnly": "npm version patch --force" }, "type": "module", diff --git a/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js b/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js new file mode 100644 index 00000000..d9104cff --- /dev/null +++ b/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js @@ -0,0 +1,22 @@ +import 'dotenv/config'; +import { S3CompatibleStorage } from '@storecraft/storage-s3-compatible' +import { storage as storage_test_runner } from '@storecraft/core/test-runner' + +const FORCE_PATH_STYLE = true; + +const storage = new S3CompatibleStorage( + { + accessKeyId: process.env.ACCESS_KEY_ID, + secretAccessKey: process.env.SECRET_ACCESS_KEY, + bucket: process.env.BUCKET, + endpoint: process.env.ENDPOINT, + forcePathStyle: FORCE_PATH_STYLE, + region: undefined + } +); + +const suite = storage_test_runner.create(storage); + +suite.before(async () => { await storage.init(undefined) }); + +suite.run(); From fc5a5103d4abb1e634755ffc08276f4e3b4a19c5 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 20:46:54 +0200 Subject: [PATCH 02/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index 6b3ffa8f..fa522dd8 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -20,7 +20,7 @@ jobs: node-version: [22.x] steps: - name: Setup minio - run: > + run: >- docker run -d -p 9000:9000 --name minio -e MINIO_ACCESS_KEY=${{env._access_key}} -e MINIO_SECRET_KEY=${{env._secret_key}} From 16ee8ba565564c54ad99cef305c0504783ce2fa2 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 20:47:46 +0200 Subject: [PATCH 03/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index fa522dd8..a3a5514f 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -20,7 +20,7 @@ jobs: node-version: [22.x] steps: - name: Setup minio - run: >- + run: | docker run -d -p 9000:9000 --name minio -e MINIO_ACCESS_KEY=${{env._access_key}} -e MINIO_SECRET_KEY=${{env._secret_key}} From 8590cb752dc0fe73401defc7bf2ebc93b950778b Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 20:49:54 +0200 Subject: [PATCH 04/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index a3a5514f..c8f17577 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -20,13 +20,12 @@ jobs: node-version: [22.x] steps: - name: Setup minio - run: | + run: >- docker run -d -p 9000:9000 --name minio - -e MINIO_ACCESS_KEY=${{env._access_key}} - -e MINIO_SECRET_KEY=${{env._secret_key}} - -v /tmp/data:/data - -v /tmp/config:/root/.minio - minio/minio server /data + -e MINIO_ACCESS_KEY=${{env._access_key}} + -e MINIO_SECRET_KEY=${{env._secret_key}} + -v /tmp/data:/data -v /tmp/config:/root/.minio + minio/minio server /data - run: wget https://dl.min.io/client/mc/release/linux-amd64/mc - run: chmod +x ./mc - run: ./mc alias set minio http://127.0.0.1:9000 ${{env._access_key}} ${{env._secret_key}} From d90c310d96bd443b49c3e07da2876808c5fd0cdb Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 20:51:55 +0200 Subject: [PATCH 05/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index c8f17577..ee2d3513 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -29,7 +29,7 @@ jobs: - run: wget https://dl.min.io/client/mc/release/linux-amd64/mc - run: chmod +x ./mc - run: ./mc alias set minio http://127.0.0.1:9000 ${{env._access_key}} ${{env._secret_key}} - - run: ./mc mb --ignore-existing minio/${{env._bucket}} + - run: ./mc mb --ignore-existing http://127.0.0.1:9000/${{env._bucket}} - name: Check out repository code uses: actions/checkout@v4 From acd3fcfe583c6bb019044b8cb4853b31bbb23d5f Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:04:37 +0200 Subject: [PATCH 06/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index ee2d3513..aa9ea732 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -28,8 +28,8 @@ jobs: minio/minio server /data - run: wget https://dl.min.io/client/mc/release/linux-amd64/mc - run: chmod +x ./mc - - run: ./mc alias set minio http://127.0.0.1:9000 ${{env._access_key}} ${{env._secret_key}} - - run: ./mc mb --ignore-existing http://127.0.0.1:9000/${{env._bucket}} + - run: ./mc alias set myminio http://127.0.0.1:9000 ${{env._access_key}} ${{env._secret_key}} + - run: ./mc mb --ignore-existing myminio/${{env._bucket}} - name: Check out repository code uses: actions/checkout@v4 From c007541136d0d73f9160283c537a0b539b051423 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:14:49 +0200 Subject: [PATCH 07/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index aa9ea732..f714a764 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -13,7 +13,7 @@ jobs: env: _access_key: minioadmin _secret_key: minioadmin - _bucket: test_bucket + _bucket: test-bucket runs-on: ubuntu-latest strategy: matrix: From 7f52c3aa80213f494bc6f44fa8c61c109b895e15 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:34:16 +0200 Subject: [PATCH 08/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 1 + packages/core/test-runner/storage/index.js | 3 ++- .../storage-s3-compatible/tests/storage.s3-compatible.test.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index f714a764..9950ba6a 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -52,4 +52,5 @@ jobs: SECRET_ACCESS_KEY: ${{env._secret_key}} BUCKET: ${{env._bucket}}, ENDPOINT: http://127.0.0.1:9000 + REGION: us-east-1 \ No newline at end of file diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 6083d465..4552e74e 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -175,9 +175,10 @@ export const create = (storage, name) => { await storage.putArraybuffer(key, buffer); // await sleep(1000); await storage.remove(key); - // await sleep(1000); + await sleep(2000); const removed = await storage.getArraybuffer(key); + console.log('removed ', removed) assert.ok( (removed.value===undefined) || (removed.value.byteLength==0), diff --git a/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js b/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js index d9104cff..8728cb1f 100644 --- a/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js +++ b/packages/storage/storage-s3-compatible/tests/storage.s3-compatible.test.js @@ -11,7 +11,7 @@ const storage = new S3CompatibleStorage( bucket: process.env.BUCKET, endpoint: process.env.ENDPOINT, forcePathStyle: FORCE_PATH_STYLE, - region: undefined + region: process.env.REGION } ); From 3dbe0a0869f4ef1fe207b24bac98ac682b78a8ef Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:39:23 +0200 Subject: [PATCH 09/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 4552e74e..4d5cae6b 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -98,6 +98,9 @@ export const create = (storage, name) => { await storage.putArraybuffer(d.key, d.buffer); // read const { value } = await storage.getArraybuffer(d.key); + + console.log('d.buffer', d.buffer) + console.log('value', value) // compare const equal = areArrayBuffersEqual(d.buffer, value); assert.ok(equal, 'are not equal !!!'); @@ -106,6 +109,7 @@ export const create = (storage, name) => { }); + return s; s('BLOB put/get', async () => { From b0427bea78421cc7d20ddd35da1eb9368c7f6542 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:45:07 +0200 Subject: [PATCH 10/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 4d5cae6b..3239b187 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -25,6 +25,14 @@ const sleep = (ms=1000) => new Promise( } ) +function buffer_to_arraybuffer(buffer) { + const arrayBuffer = new ArrayBuffer(buffer.length); + const view = new Uint8Array(arrayBuffer); + for (let i = 0; i < buffer.length; ++i) { + view[i] = buffer[i]; + } + return arrayBuffer; +} /** * * @param {ReadableStream} stream @@ -94,15 +102,17 @@ export const create = (storage, name) => { const data = data_with_buffers; for (const d of data) { + + const ab = buffer_to_arraybuffer(d.buffer); - await storage.putArraybuffer(d.key, d.buffer); + await storage.putArraybuffer(d.key, ab); // read const { value } = await storage.getArraybuffer(d.key); console.log('d.buffer', d.buffer) console.log('value', value) // compare - const equal = areArrayBuffersEqual(d.buffer, value); + const equal = areArrayBuffersEqual(ab, value); assert.ok(equal, 'are not equal !!!'); } From 74e60d12b72ee6a614be93b3b7da97841450f841 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 21:47:38 +0200 Subject: [PATCH 11/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 3239b187..688b233c 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -103,16 +103,16 @@ export const create = (storage, name) => { for (const d of data) { - const ab = buffer_to_arraybuffer(d.buffer); + const as_array_buffer = buffer_to_arraybuffer(d.buffer); - await storage.putArraybuffer(d.key, ab); + await storage.putArraybuffer(d.key, as_array_buffer); // read const { value } = await storage.getArraybuffer(d.key); - console.log('d.buffer', d.buffer) + console.log('as_array_buffer', as_array_buffer) console.log('value', value) // compare - const equal = areArrayBuffersEqual(ab, value); + const equal = areArrayBuffersEqual(as_array_buffer, value); assert.ok(equal, 'are not equal !!!'); } From 2f568b84e7ad29dba652b98a9fe5ab4a2a6699ff Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:17:08 +0200 Subject: [PATCH 12/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 688b233c..f3958ad4 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -109,6 +109,7 @@ export const create = (storage, name) => { // read const { value } = await storage.getArraybuffer(d.key); + console.log('d.buffer.toString()', d.buffer.toString()) console.log('as_array_buffer', as_array_buffer) console.log('value', value) // compare From 9699b384736dc42701a34d5e65da0b1ee69a5a14 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:20:09 +0200 Subject: [PATCH 13/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index f3958ad4..6729853e 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -109,9 +109,9 @@ export const create = (storage, name) => { // read const { value } = await storage.getArraybuffer(d.key); - console.log('d.buffer.toString()', d.buffer.toString()) console.log('as_array_buffer', as_array_buffer) console.log('value', value) + console.log('decoded', new TextDecoder("utf-8").decode(value)) // compare const equal = areArrayBuffersEqual(as_array_buffer, value); assert.ok(equal, 'are not equal !!!'); From d04d09ec028c181bbc32c4ecc3a403162348e468 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:22:28 +0200 Subject: [PATCH 14/19] ci/cd: using minio to test s3 --- .github/workflows/test.storage-s3-compatible.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.storage-s3-compatible.yml b/.github/workflows/test.storage-s3-compatible.yml index 9950ba6a..1872cc95 100644 --- a/.github/workflows/test.storage-s3-compatible.yml +++ b/.github/workflows/test.storage-s3-compatible.yml @@ -50,7 +50,7 @@ jobs: env: ACCESS_KEY_ID: ${{env._access_key}} SECRET_ACCESS_KEY: ${{env._secret_key}} - BUCKET: ${{env._bucket}}, + BUCKET: ${{env._bucket}} ENDPOINT: http://127.0.0.1:9000 REGION: us-east-1 \ No newline at end of file From 6a2d29000aa36a09c472c39466b0f54ce7f407ae Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:44:13 +0200 Subject: [PATCH 15/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 19 ++++---- .../storage/storage-s3-compatible/adapter.js | 45 +++++++++---------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 6729853e..9a3d98b6 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -62,8 +62,8 @@ const readableStreamToArrayBuffer = async (stream) => { */ const areStreamsEqual = async (lhs, rhs) => { return areArrayBuffersEqual( - await readableStreamToArrayBuffer(lhs), - await readableStreamToArrayBuffer(rhs) + (await readableStreamToArrayBuffer(lhs)).buffer, + (await readableStreamToArrayBuffer(rhs)).buffer ); } /** @@ -109,9 +109,9 @@ export const create = (storage, name) => { // read const { value } = await storage.getArraybuffer(d.key); - console.log('as_array_buffer', as_array_buffer) - console.log('value', value) - console.log('decoded', new TextDecoder("utf-8").decode(value)) + // console.log('as_array_buffer', as_array_buffer) + // console.log('value', value) + // console.log('decoded', new TextDecoder("utf-8").decode(value)) // compare const equal = areArrayBuffersEqual(as_array_buffer, value); assert.ok(equal, 'are not equal !!!'); @@ -120,8 +120,6 @@ export const create = (storage, name) => { }); - return s; - s('BLOB put/get', async () => { const data = data_with_buffers.map( @@ -187,16 +185,15 @@ export const create = (storage, name) => { const key = 'folder-test/about_to_be_removed.png' const buffer = data_with_buffers[0].buffer; - await storage.putArraybuffer(key, buffer); + await storage.putArraybuffer(key, buffer_to_arraybuffer(buffer)); // await sleep(1000); await storage.remove(key); await sleep(2000); const removed = await storage.getArraybuffer(key); - console.log('removed ', removed) assert.ok( - (removed.value===undefined) || - (removed.value.byteLength==0), + (removed.error) || + (!Boolean(removed.value)), 'not removed !!!' ); }); diff --git a/packages/storage/storage-s3-compatible/adapter.js b/packages/storage/storage-s3-compatible/adapter.js index e2652589..bba8ee0e 100644 --- a/packages/storage/storage-s3-compatible/adapter.js +++ b/packages/storage/storage-s3-compatible/adapter.js @@ -110,8 +110,7 @@ export class S3CompatibleStorage { /** * - * @param {string} key - * @param {Blob} blob + * @type {storage["putBlob"]} */ async putBlob(key, blob) { return this.#put_internal(key, blob); @@ -119,8 +118,7 @@ export class S3CompatibleStorage { /** * - * @param {string} key - * @param {ArrayBuffer} buffer + * @type {storage["putArraybuffer"]} */ async putArraybuffer(key, buffer) { return this.#put_internal(key, buffer); @@ -128,17 +126,16 @@ export class S3CompatibleStorage { /** * - * @param {string} key - * @param {ReadableStream} stream + * @type {storage["putStream"]} */ async putStream(key, stream) { + // @ts-ignore return this.#put_internal(key, stream); } /** * - * @param {string} key - * @returns {ReturnType} + * @type {storage["putSigned"]} */ async putSigned(key) { const url = new URL(this.get_file_url(key)); @@ -171,14 +168,14 @@ export class S3CompatibleStorage { } /** - * - * @param {string} key + * @type {storage["getArraybuffer"]} */ async getArraybuffer(key) { const r = await this.#get_request(key); - const b = await r.arrayBuffer(); return { - value: b, + value: r.ok ? (await r.arrayBuffer()) : undefined, + error: !r.ok, + message: r.ok ? undefined : await r.text(), metadata: { contentType: infer_content_type(key) } @@ -187,13 +184,14 @@ export class S3CompatibleStorage { /** * - * @param {string} key + * @type {storage["getBlob"]} */ async getBlob(key) { const r = await this.#get_request(key); - const b = await r.blob(); return { - value: b, + value: r.ok ? (await r.blob()) : undefined, + error: !r.ok, + message: r.ok ? undefined : await r.text(), metadata: { contentType: infer_content_type(key) } @@ -201,15 +199,15 @@ export class S3CompatibleStorage { } /** - * - * @param {string} key - * @param {Response} key + * @type {storage["getStream"]} */ async getStream(key) { - - const s = (await this.#get_request(key)).body + const r = await this.#get_request(key); + const b = r.body; return { - value: s, + value: r.ok ? b : undefined, + error: !r.ok, + message: r.ok ? undefined : await r.text(), metadata: { contentType: infer_content_type(key) } @@ -218,8 +216,7 @@ export class S3CompatibleStorage { /** * - * @param {string} key - * @returns {ReturnType} + * @type {storage["getSigned"]} */ async getSigned(key) { const url = new URL(this.get_file_url(key)); @@ -244,7 +241,7 @@ export class S3CompatibleStorage { /** * - * @param {string} key + * @type {storage["remove"]} */ async remove(key) { const r = await this.client.fetch( From 9acd0762d653d438ced27e7778766af208e5b63b Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:47:36 +0200 Subject: [PATCH 16/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 9a3d98b6..79243e83 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -155,10 +155,12 @@ export const create = (storage, name) => { // @ts-ignore await storage.putStream(d.key, d.stream); // read - const { value } = await storage.getStream(d.key); + const get_stream = await storage.getStream(d.key); + + console.log('get_stream ', get_stream) // let's read - const reader = value.getReader(); + const reader = get_stream.value.getReader(); let stream_bytes_length = 0; while(true) { const {done, value: chunk } = await reader.read(); From c9be74d984ceb9ea447b6a59e073c83632c6abb8 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 22:52:42 +0200 Subject: [PATCH 17/19] ci/cd: using minio to test s3 --- packages/core/test-runner/storage/index.js | 5 +++-- packages/storage/storage-s3-compatible/adapter.js | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 79243e83..821446a4 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -153,11 +153,12 @@ export const create = (storage, name) => { for (const d of data) { // @ts-ignore - await storage.putStream(d.key, d.stream); + const success = await storage.putStream(d.key, d.stream); // read const get_stream = await storage.getStream(d.key); - console.log('get_stream ', get_stream) + console.log('success ', success); + console.log('get_stream ', get_stream); // let's read const reader = get_stream.value.getReader(); diff --git a/packages/storage/storage-s3-compatible/adapter.js b/packages/storage/storage-s3-compatible/adapter.js index bba8ee0e..1ed7d671 100644 --- a/packages/storage/storage-s3-compatible/adapter.js +++ b/packages/storage/storage-s3-compatible/adapter.js @@ -105,6 +105,12 @@ export class S3CompatibleStorage { } ); + if(!r.ok) { + console.log( + await r.text() + ); + } + return r.ok; } From 411f7d2a4dcbac0520b0b365bea34caef14692d1 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Tue, 14 Jan 2025 23:58:03 +0200 Subject: [PATCH 18/19] ci/cd: using minio to test s3 --- packages/core/rest/con.storage.routes.js | 1 + packages/core/test-runner/storage/index.js | 10 ++++++++-- packages/storage/storage-s3-compatible/adapter.js | 12 ++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/core/rest/con.storage.routes.js b/packages/core/rest/con.storage.routes.js index a5c15d17..e21c848e 100644 --- a/packages/core/rest/con.storage.routes.js +++ b/packages/core/rest/con.storage.routes.js @@ -56,6 +56,7 @@ export const create_routes = (app) => { res.headers.set(HEADER_PRESIGNED, 'true'); res.sendJson(r); } else { + await app.storage.putStream(file_key, req.body); res.headers.set(HEADER_PRESIGNED, 'false'); diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index 821446a4..ded44856 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -147,13 +147,19 @@ export const create = (storage, name) => { ...d, stream: Readable.toWeb(Readable.from(d.buffer)), // stream: Readable.toWeb(createReadStream('node.png')), - key: 'folder1/stream_node.png' + key: 'folder1/stream_node.png', + length: d.buffer.byteLength }) ); for (const d of data) { // @ts-ignore - const success = await storage.putStream(d.key, d.stream); + const success = await storage.putStream( + d.key, d.stream, + { + 'Content-Length': d.length + } + ); // read const get_stream = await storage.getStream(d.key); diff --git a/packages/storage/storage-s3-compatible/adapter.js b/packages/storage/storage-s3-compatible/adapter.js index 1ed7d671..8c16a7b7 100644 --- a/packages/storage/storage-s3-compatible/adapter.js +++ b/packages/storage/storage-s3-compatible/adapter.js @@ -95,13 +95,15 @@ export class S3CompatibleStorage { * * @param {string} key * @param {BodyInit} body + * @param {object} [headers={}] */ - async #put_internal(key, body) { + async #put_internal(key, body, headers={}) { const r = await this.client.fetch( this.get_file_url(key), { method: 'PUT', - body + body, + headers } ); @@ -134,9 +136,11 @@ export class S3CompatibleStorage { * * @type {storage["putStream"]} */ - async putStream(key, stream) { + async putStream(key, stream, meta) { // @ts-ignore - return this.#put_internal(key, stream); + return this.#put_internal( + key, stream, meta + ); } /** From c3ae7c2ac51e50ab408d3c0328b3590f286c1710 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Wed, 15 Jan 2025 00:21:32 +0200 Subject: [PATCH 19/19] ci/cd: using minio to test s3 --- README.md | 2 ++ package-lock.json | 8 ++++---- packages/core/rest/con.storage.routes.js | 5 ++++- packages/core/storage/types.storage.d.ts | 2 +- packages/core/test-runner/storage/index.js | 5 +---- packages/storage/storage-s3-compatible/README.md | 2 ++ packages/storage/storage-s3-compatible/adapter.js | 11 ++++++++--- packages/storage/storage-s3-compatible/package.json | 5 +++-- 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 284dcc57..d1b25633 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ [![Core](https://github.com/store-craft/storecraft/actions/workflows/test.core.yml/badge.svg)](https://github.com/store-craft/storecraft/actions/workflows/test.core.yml) [![MongoDB](https://github.com/store-craft/storecraft/actions/workflows/test.database-mongodb.yml/badge.svg)](https://github.com/store-craft/storecraft/actions/workflows/test.database-mongodb.yml)[![SQLite / Postgres / MySQL](https://github.com/store-craft/storecraft/actions/workflows/test.database-sql.yml/badge.svg)](https://github.com/store-craft/storecraft/actions/workflows/test.database-sql.yml) +[![S3 Compatible](https://github.com/store-craft/storecraft/actions/workflows/test.storage-s3-compatible.yml/badge.svg)](https://github.com/store-craft/storecraft/actions/workflows/test.storage-s3-compatible.yml) + # The mono-repo diff --git a/package-lock.json b/package-lock.json index db11aa39..41d6e1e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20159,9 +20159,9 @@ } }, "packages/cli/node_modules/@storecraft/storage-s3-compatible": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@storecraft/storage-s3-compatible/-/storage-s3-compatible-1.0.6.tgz", - "integrity": "sha512-9uxvMDwaEWeW7BHqrpeIICp8G7J+w8Kdw0CjgNLzTxyuhZ+Y9TU04TbiKoODB7qBDpp9AoXzPTVVHnVF0gFB+w==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@storecraft/storage-s3-compatible/-/storage-s3-compatible-1.0.7.tgz", + "integrity": "sha512-L0S+7r4AcqLurrh/57qtxC/LoQN2A/T615KHHyEpv6vaC7L3IbL/TlrW9hJZ2tXCRpvrrvR2jnMdbA+VhdvO3w==", "dev": true, "license": "MIT", "dependencies": { @@ -20579,7 +20579,7 @@ }, "packages/storage/storage-s3-compatible": { "name": "@storecraft/storage-s3-compatible", - "version": "1.0.7", + "version": "1.0.8", "license": "MIT", "dependencies": { "@storecraft/core": "^1.0.0" diff --git a/packages/core/rest/con.storage.routes.js b/packages/core/rest/con.storage.routes.js index e21c848e..71572921 100644 --- a/packages/core/rest/con.storage.routes.js +++ b/packages/core/rest/con.storage.routes.js @@ -57,7 +57,10 @@ export const create_routes = (app) => { res.sendJson(r); } else { - await app.storage.putStream(file_key, req.body); + await app.storage.putStream( + file_key, req.body, {}, + parseInt(req.headers.get("Content-Length") ?? '0') + ); res.headers.set(HEADER_PRESIGNED, 'false'); res.end(); diff --git a/packages/core/storage/types.storage.d.ts b/packages/core/storage/types.storage.d.ts index a486e5e5..98c1d27c 100644 --- a/packages/core/storage/types.storage.d.ts +++ b/packages/core/storage/types.storage.d.ts @@ -85,7 +85,7 @@ export declare interface storage_driver { */ putBlob: (key: string, blob: Blob, meta?: MetaData) => Promise; putArraybuffer: (key: string, buffer: ArrayBuffer, meta?: MetaData) => Promise; - putStream: (key: string, stream: Partial>, meta?: MetaData) => Promise; + putStream: (key: string, stream: Partial>, meta?: MetaData, bytesLength: number) => Promise; putSigned?: (key: string) => Promise; /** diff --git a/packages/core/test-runner/storage/index.js b/packages/core/test-runner/storage/index.js index ded44856..a93873c1 100644 --- a/packages/core/test-runner/storage/index.js +++ b/packages/core/test-runner/storage/index.js @@ -155,10 +155,7 @@ export const create = (storage, name) => { for (const d of data) { // @ts-ignore const success = await storage.putStream( - d.key, d.stream, - { - 'Content-Length': d.length - } + d.key, d.stream, {}, d.buffer.byteLength ); // read const get_stream = await storage.getStream(d.key); diff --git a/packages/storage/storage-s3-compatible/README.md b/packages/storage/storage-s3-compatible/README.md index 5db3c97c..32104a84 100644 --- a/packages/storage/storage-s3-compatible/README.md +++ b/packages/storage/storage-s3-compatible/README.md @@ -5,6 +5,8 @@ width='90%' />

+[![S3 Compatible](https://github.com/store-craft/storecraft/actions/workflows/test.storage-s3-compatible.yml/badge.svg)](https://github.com/store-craft/storecraft/actions/workflows/test.storage-s3-compatible.yml) + `fetch` ready support for an `S3` like storage: - `Amazon S3` - `Cloudflare R2` diff --git a/packages/storage/storage-s3-compatible/adapter.js b/packages/storage/storage-s3-compatible/adapter.js index 8c16a7b7..8589da0b 100644 --- a/packages/storage/storage-s3-compatible/adapter.js +++ b/packages/storage/storage-s3-compatible/adapter.js @@ -136,10 +136,15 @@ export class S3CompatibleStorage { * * @type {storage["putStream"]} */ - async putStream(key, stream, meta) { - // @ts-ignore + async putStream(key, stream, meta={}, bytesLength=0) { + const extra_headers = {}; + if(Boolean(bytesLength)) { + extra_headers["Content-Length"] = bytesLength; + } + return this.#put_internal( - key, stream, meta + // @ts-ignore + key, stream, extra_headers ); } diff --git a/packages/storage/storage-s3-compatible/package.json b/packages/storage/storage-s3-compatible/package.json index 78e43f50..c7597ff3 100644 --- a/packages/storage/storage-s3-compatible/package.json +++ b/packages/storage/storage-s3-compatible/package.json @@ -1,6 +1,6 @@ { "name": "@storecraft/storage-s3-compatible", - "version": "1.0.7", + "version": "1.0.8", "description": "Official S3-Compatible Storage adapter for storecraft", "license": "MIT", "author": "Tomer Shalev (https://github.com/store-craft)", @@ -18,7 +18,8 @@ ], "scripts": { "test": "node ./tests/storage.s3-compatible.test.js", - "prepublishOnly": "npm version patch --force" + "prepublishOnly": "npm version patch --force", + "sc-publish": "npm publish" }, "type": "module", "main": "adapter.js",