From 2958fa98411ae8efc0dd54f26b115ac5e1ac2873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Iv=C3=A1n=20Vieitez=20Parra?= <3857362+corrideat@users.noreply.github.com> Date: Thu, 18 May 2023 00:19:39 +0200 Subject: [PATCH] Fixed types --- README.md | 8 ++++---- package-lock.json | 4 ++-- package.json | 3 ++- src/encodeMultipartMessage.ts | 25 ++++++++++++++++++------- src/index.ts | 14 +++++++------- src/lib/createBufferStream.ts | 2 ++ src/lib/findIndex.ts | 2 ++ src/lib/mergeTypedArrays.ts | 2 ++ src/parseMessage.ts | 2 +- src/parseMultipartMessage.ts | 11 ++++++----- src/types/index.ts | 25 +++++++++++++++++++++++++ tsconfig.json | 5 ++++- types/global/index.d.ts | 11 ----------- 13 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 src/types/index.ts diff --git a/README.md b/README.md index 96e3af3..dfe370d 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ A regular expression that can be used to validate a boundary string. A regular expression that can be used to extract a boundary string from a `Content-Type` header. -#### `encodeMultipartMessage(boundary: string, msg: TDecodedMultipartMessage[]): ReadableStream<ArrayBuffer>` +#### `encodeMultipartMessage(boundary: string, msg: AsyncIterable): ReadableStream` This function takes a boundary string and an array of messages as arguments and returns a `ReadableStream` that can be read to obtain a multipart message. @@ -65,9 +65,9 @@ This function takes a boundary string and an array of messages as arguments and * `headers`: a `Headers` object containing the headers of the current part * `body` (optional): The body of the current part, or `null` if the part is empty. It can be any of the following types: `ArrayBuffer`, `Blob`, `ReadableStream` or any typed array, such as `Uint8Array`. - * `parts` (optional): An array of one element or more of the same type - (`TDecodedMultipartMessage`), for nested messages. If both `body` and - `parts` are specified, `body` takes precedence. + * `parts` (optional): An async or sync iterable of one element or more of + the same type (`TDecodedMultipartMessage`), for nested messages. If both + `body` and `parts` are specified, `body` takes precedence. ### Example diff --git a/package-lock.json b/package-lock.json index e77293f..940dd6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@exact-realty/multipart-parser", - "version": "1.0.0", + "version": "1.0.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@exact-realty/multipart-parser", - "version": "1.0.0", + "version": "1.0.6", "hasInstallScript": true, "license": "ISC", "devDependencies": { diff --git a/package.json b/package.json index a91fc42..33ebd22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exact-realty/multipart-parser", - "version": "1.0.4", + "version": "1.0.6", "description": "TypeScript streaming parser for MIME multipart messages", "main": "dist/index.js", "module": "./dist/index.mjs", @@ -29,6 +29,7 @@ }, "author": "Exact Realty Limited", "license": "ISC", + "keywords": ["form-data", "formdata", "mime", "mime", "multipart", "multipart/form-data", "multipart/mixed", "multipart/related", "parser", "rfc2046", "rfc2388", "rfc7568"], "devDependencies": { "@types/mocha": "^10.0.1", "@types/node": "^18.0.0", diff --git a/src/encodeMultipartMessage.ts b/src/encodeMultipartMessage.ts index f0b9dee..5423868 100644 --- a/src/encodeMultipartMessage.ts +++ b/src/encodeMultipartMessage.ts @@ -13,13 +13,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ -import { boundaryMatchRegex } from './lib/boundaryRegex'; -import createBufferStream from './lib/createBufferStream'; +import { boundaryMatchRegex } from './lib/boundaryRegex.js'; +import createBufferStream from './lib/createBufferStream.js'; +import type { TTypedArray } from './types/index.js'; + +type TIterable = AsyncIterable | Iterable; export type TDecodedMultipartMessage = { headers: Headers; body?: TTypedArray | ArrayBuffer | Blob | ReadableStream | null; - parts?: TDecodedMultipartMessage[]; + parts?: TIterable; }; const textEncoder = new TextEncoder(); @@ -49,17 +52,20 @@ const pipeToOptions = { async function* asyncEncoderGenerator( boundary: string, - msg: TDecodedMultipartMessage[], + msg: TIterable, ws: WritableStream, ): AsyncGenerator { const encodedBoundary = textEncoder.encode(`\r\n--${boundary}`); - if (!Array.isArray(msg) || msg.length < 1) { + if (Array.isArray(msg) && msg.length < 1) { await ws.abort(Error('At least one part is required')); return; } - for (const part of msg) { + let count = 0; + + for await (const part of msg) { + count++; let subBoundary: string | undefined; let partContentType: string | null | undefined; @@ -166,13 +172,18 @@ async function* asyncEncoderGenerator( } } + if (!count) { + await ws.abort(Error('At least one part is required')); + return; + } + const encodedEndBoundary = textEncoder.encode(`\r\n--${boundary}--`); await createBufferStream(encodedEndBoundary).pipeTo(ws, pipeToOptions); } const encodeMultipartMessage = ( boundary: string, - msg: TDecodedMultipartMessage[], + msg: TIterable, ): ReadableStream => { const transformStream = new TransformStream(); diff --git a/src/index.ts b/src/index.ts index d47d4f9..5927fde 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,10 +13,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -export { default as encodeMultipartMessage } from './encodeMultipartMessage'; -export type { TDecodedMultipartMessage } from './encodeMultipartMessage'; -export { boundaryMatchRegex, boundaryRegex } from './lib/boundaryRegex'; -export { default as parseMessage } from './parseMessage'; -export type { TMessage } from './parseMessage'; -export * from './parseMultipartMessage'; -export { default } from './parseMultipartMessage'; +export { default as encodeMultipartMessage } from './encodeMultipartMessage.js'; +export type { TDecodedMultipartMessage } from './encodeMultipartMessage.js'; +export { boundaryMatchRegex, boundaryRegex } from './lib/boundaryRegex.js'; +export { default as parseMessage } from './parseMessage.js'; +export type { TMessage } from './parseMessage.js'; +export * from './parseMultipartMessage.js'; +export { default } from './parseMultipartMessage.js'; diff --git a/src/lib/createBufferStream.ts b/src/lib/createBufferStream.ts index ba27632..1600268 100644 --- a/src/lib/createBufferStream.ts +++ b/src/lib/createBufferStream.ts @@ -13,6 +13,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +import type { TTypedArray } from '../types/index.js'; + const createBufferStream = (buffer: T) => { const readableStream = new ReadableStream({ pull(controller) { diff --git a/src/lib/findIndex.ts b/src/lib/findIndex.ts index 39f3407..b6b3cac 100644 --- a/src/lib/findIndex.ts +++ b/src/lib/findIndex.ts @@ -13,6 +13,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +import type { TTypedArray } from '../types/index.js'; + // Helper function to find the index of a Uint8Array within another Uint8Array const findIndex = (buffer: T, delimiter: T): number => { outerLoop: for (let i = 0; i <= buffer.length - delimiter.length; i++) { diff --git a/src/lib/mergeTypedArrays.ts b/src/lib/mergeTypedArrays.ts index 60ce676..b1e3189 100644 --- a/src/lib/mergeTypedArrays.ts +++ b/src/lib/mergeTypedArrays.ts @@ -11,6 +11,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +import type { TTypedArray } from '../types/index.js'; + const mergeTypedArrays = ( input0: T, ...input: T[] diff --git a/src/parseMessage.ts b/src/parseMessage.ts index 5e22dd6..82595d8 100644 --- a/src/parseMessage.ts +++ b/src/parseMessage.ts @@ -11,7 +11,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -import findIndex from './lib/findIndex'; +import findIndex from './lib/findIndex.js'; const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); diff --git a/src/parseMultipartMessage.ts b/src/parseMultipartMessage.ts index 8e6cd67..2e8760d 100644 --- a/src/parseMultipartMessage.ts +++ b/src/parseMultipartMessage.ts @@ -13,11 +13,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -import { boundaryMatchRegex, boundaryRegex } from './lib/boundaryRegex'; -import createBufferStream from './lib/createBufferStream'; -import findIndex from './lib/findIndex'; -import mergeTypedArrays from './lib/mergeTypedArrays'; -import parseMessage from './parseMessage'; +import { boundaryMatchRegex, boundaryRegex } from './lib/boundaryRegex.js'; +import createBufferStream from './lib/createBufferStream.js'; +import findIndex from './lib/findIndex.js'; +import mergeTypedArrays from './lib/mergeTypedArrays.js'; +import parseMessage from './parseMessage.js'; +import type { TTypedArray } from './types/index.js'; enum EState { PREAMBLE, diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..2f542fb --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,25 @@ +/* Copyright © 2023 Exact Realty Limited. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +export type TTypedArray = + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array; diff --git a/tsconfig.json b/tsconfig.json index d58094a..f844da5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,10 @@ "allowJs": true, "checkJs": true, "lib": ["ES2019.object", "ES2019.array", "dom"], - "typeRoots": ["./node_modules/@types", "./types"] + "typeRoots": ["./node_modules/@types", "./@types"] + }, + "ts-node": { + "experimentalResolver": true }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"] diff --git a/types/global/index.d.ts b/types/global/index.d.ts index ef0d9f8..92e8e40 100644 --- a/types/global/index.d.ts +++ b/types/global/index.d.ts @@ -12,14 +12,3 @@ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ - -declare type TTypedArray = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array;