web-csv-toolbox 0.14.0-next-386eebeaafe5857e28c876345c14c9fe5f1a3774 → 0.14.0-next-e45bc4d089f1fb259a7596b9862b3b34e717dab7
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.
- package/dist/common/types.d.ts +43 -0
- package/dist/getCharsetValidation.constants.node.d.ts +11 -0
- package/dist/getCharsetValidation.constants.node.js +53 -0
- package/dist/getCharsetValidation.constants.node.js.map +1 -0
- package/dist/getCharsetValidation.constants.web.d.ts +36 -0
- package/dist/getCharsetValidation.constants.web.js +53 -0
- package/dist/getCharsetValidation.constants.web.js.map +1 -0
- package/dist/getOptionsFromResponse.js +17 -1
- package/dist/getOptionsFromResponse.js.map +1 -1
- package/dist/utils/convertBinaryToString.js +17 -4
- package/dist/utils/convertBinaryToString.js.map +1 -1
- package/dist/utils/parseMime.js +3 -1
- package/dist/utils/parseMime.js.map +1 -1
- package/package.json +7 -1
package/dist/common/types.d.ts
CHANGED
|
@@ -291,6 +291,49 @@ export interface BinaryOptions {
|
|
|
291
291
|
* ```
|
|
292
292
|
*/
|
|
293
293
|
allowExperimentalCompressions?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Allow non-standard character encodings not in the common charset list.
|
|
296
|
+
*
|
|
297
|
+
* @remarks
|
|
298
|
+
* When `true`, charset values from Content-Type headers that are not in the
|
|
299
|
+
* default supported list will be passed to the runtime's TextDecoder without
|
|
300
|
+
* validation. This allows using character encodings that may not be universally
|
|
301
|
+
* supported across all environments.
|
|
302
|
+
*
|
|
303
|
+
* ### Default Supported Charsets (commonly used)
|
|
304
|
+
*
|
|
305
|
+
* When `false` (default), only commonly used charsets are allowed, including:
|
|
306
|
+
* - **UTF**: `utf-8`, `utf-16le`, `utf-16be`
|
|
307
|
+
* - **ISO-8859**: `iso-8859-1` through `iso-8859-16`
|
|
308
|
+
* - **Windows**: `windows-1250` through `windows-1258`
|
|
309
|
+
* - **Asian**: `shift_jis`, `euc-jp`, `gb18030`, `euc-kr`, etc.
|
|
310
|
+
*
|
|
311
|
+
* ### Security Considerations
|
|
312
|
+
*
|
|
313
|
+
* **Use with caution**: Enabling this bypasses library validation and relies entirely
|
|
314
|
+
* on runtime error handling. Invalid or malicious charset values could cause:
|
|
315
|
+
* - Runtime exceptions from TextDecoder
|
|
316
|
+
* - Unexpected character decoding behavior
|
|
317
|
+
* - Potential security vulnerabilities
|
|
318
|
+
*
|
|
319
|
+
* It's recommended to validate charset values against your expected inputs before
|
|
320
|
+
* enabling this option.
|
|
321
|
+
*
|
|
322
|
+
* @default false
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* // Safe mode (default): Only commonly supported charsets
|
|
327
|
+
* const response = await fetch('data.csv');
|
|
328
|
+
* await parse(response); // charset must be in SUPPORTED_CHARSETS
|
|
329
|
+
*
|
|
330
|
+
* // Allow non-standard charset
|
|
331
|
+
* const response = await fetch('data.csv'); // Content-Type: text/csv; charset=custom-encoding
|
|
332
|
+
* await parse(response, { allowNonStandardCharsets: true });
|
|
333
|
+
* // ⚠️ May throw error if runtime doesn't support the charset
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
allowNonStandardCharsets?: boolean;
|
|
294
337
|
}
|
|
295
338
|
/**
|
|
296
339
|
* CSV Lexer Transformer Options.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commonly supported character encodings for CSV parsing in Node.js environments.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Node.js 20+ supports the WHATWG Encoding Standard through TextDecoder.
|
|
6
|
+
* This list includes the most commonly used encodings for CSV files.
|
|
7
|
+
*
|
|
8
|
+
* @see {@link https://nodejs.org/api/util.html#class-utiltextdecoder | Node.js TextDecoder}
|
|
9
|
+
* @see {@link https://encoding.spec.whatwg.org/#names-and-labels | WHATWG Encoding Standard}
|
|
10
|
+
*/
|
|
11
|
+
export declare const SUPPORTED_CHARSETS: ReadonlySet<string>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const SUPPORTED_CHARSETS = /* @__PURE__ */ new Set([
|
|
2
|
+
// UTF encodings
|
|
3
|
+
"utf-8",
|
|
4
|
+
"utf8",
|
|
5
|
+
"unicode-1-1-utf-8",
|
|
6
|
+
"utf-16le",
|
|
7
|
+
"utf-16be",
|
|
8
|
+
"utf-16",
|
|
9
|
+
// ISO-8859 series (Western European)
|
|
10
|
+
"iso-8859-1",
|
|
11
|
+
"iso-8859-2",
|
|
12
|
+
"iso-8859-3",
|
|
13
|
+
"iso-8859-4",
|
|
14
|
+
"iso-8859-5",
|
|
15
|
+
"iso-8859-6",
|
|
16
|
+
"iso-8859-7",
|
|
17
|
+
"iso-8859-8",
|
|
18
|
+
"iso-8859-9",
|
|
19
|
+
"iso-8859-10",
|
|
20
|
+
"iso-8859-13",
|
|
21
|
+
"iso-8859-14",
|
|
22
|
+
"iso-8859-15",
|
|
23
|
+
"iso-8859-16",
|
|
24
|
+
"latin1",
|
|
25
|
+
// Windows code pages
|
|
26
|
+
"windows-1250",
|
|
27
|
+
"windows-1251",
|
|
28
|
+
"windows-1252",
|
|
29
|
+
"windows-1253",
|
|
30
|
+
"windows-1254",
|
|
31
|
+
"windows-1255",
|
|
32
|
+
"windows-1256",
|
|
33
|
+
"windows-1257",
|
|
34
|
+
"windows-1258",
|
|
35
|
+
// Japanese
|
|
36
|
+
"shift_jis",
|
|
37
|
+
"shift-jis",
|
|
38
|
+
"sjis",
|
|
39
|
+
"euc-jp",
|
|
40
|
+
"iso-2022-jp",
|
|
41
|
+
// Chinese
|
|
42
|
+
"gb18030",
|
|
43
|
+
"gbk",
|
|
44
|
+
"gb2312",
|
|
45
|
+
// Korean
|
|
46
|
+
"euc-kr",
|
|
47
|
+
// Other
|
|
48
|
+
"ascii",
|
|
49
|
+
"us-ascii"
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
export { SUPPORTED_CHARSETS };
|
|
53
|
+
//# sourceMappingURL=getCharsetValidation.constants.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getCharsetValidation.constants.node.js","sources":["../src/getCharsetValidation.constants.node.ts"],"sourcesContent":["/**\n * Commonly supported character encodings for CSV parsing in Node.js environments.\n *\n * @remarks\n * Node.js 20+ supports the WHATWG Encoding Standard through TextDecoder.\n * This list includes the most commonly used encodings for CSV files.\n *\n * @see {@link https://nodejs.org/api/util.html#class-utiltextdecoder | Node.js TextDecoder}\n * @see {@link https://encoding.spec.whatwg.org/#names-and-labels | WHATWG Encoding Standard}\n */\nexport const SUPPORTED_CHARSETS: ReadonlySet<string> = new Set([\n // UTF encodings\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\",\n \"utf-16le\",\n \"utf-16be\",\n \"utf-16\",\n\n // ISO-8859 series (Western European)\n \"iso-8859-1\",\n \"iso-8859-2\",\n \"iso-8859-3\",\n \"iso-8859-4\",\n \"iso-8859-5\",\n \"iso-8859-6\",\n \"iso-8859-7\",\n \"iso-8859-8\",\n \"iso-8859-9\",\n \"iso-8859-10\",\n \"iso-8859-13\",\n \"iso-8859-14\",\n \"iso-8859-15\",\n \"iso-8859-16\",\n \"latin1\",\n\n // Windows code pages\n \"windows-1250\",\n \"windows-1251\",\n \"windows-1252\",\n \"windows-1253\",\n \"windows-1254\",\n \"windows-1255\",\n \"windows-1256\",\n \"windows-1257\",\n \"windows-1258\",\n\n // Japanese\n \"shift_jis\",\n \"shift-jis\",\n \"sjis\",\n \"euc-jp\",\n \"iso-2022-jp\",\n\n // Chinese\n \"gb18030\",\n \"gbk\",\n \"gb2312\",\n\n // Korean\n \"euc-kr\",\n\n // Other\n \"ascii\",\n \"us-ascii\",\n]);\n"],"names":[],"mappings":"AAUO,MAAM,kBAAA,uBAA8C,GAAA,CAAI;AAAA;AAAA,EAE7D,OAAA;AAAA,EACA,MAAA;AAAA,EACA,mBAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAGA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,QAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EACA;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commonly supported character encodings for CSV parsing in browser environments.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This list includes the most commonly used encodings that are supported across
|
|
6
|
+
* all modern browsers. TextDecoder supports additional encodings, but this list
|
|
7
|
+
* focuses on the most widely-used ones for CSV files.
|
|
8
|
+
*
|
|
9
|
+
* ### Common Character Encodings:
|
|
10
|
+
* - **UTF-8**: Universal encoding, recommended for all new content
|
|
11
|
+
* - **UTF-16LE/UTF-16BE**: Unicode encodings with byte order
|
|
12
|
+
* - **ISO-8859-X**: Legacy single-byte encodings for Western European languages
|
|
13
|
+
* - **Windows-125X**: Windows-specific legacy encodings
|
|
14
|
+
* - **Shift_JIS, EUC-JP, ISO-2022-JP**: Japanese encodings
|
|
15
|
+
* - **GB18030, GBK**: Chinese encodings
|
|
16
|
+
* - **EUC-KR**: Korean encoding
|
|
17
|
+
*
|
|
18
|
+
* ### Using Non-Standard Charsets
|
|
19
|
+
*
|
|
20
|
+
* If you need to use a charset not in this list, you can:
|
|
21
|
+
* 1. Set the `allowNonStandardCharsets` option to `true`
|
|
22
|
+
* 2. Be aware that this may cause errors if the browser doesn't support the encoding
|
|
23
|
+
* 3. Consider implementing fallback handling for unsupported charsets
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Use non-standard charset (may fail in some browsers)
|
|
28
|
+
* const records = parseResponse(response, {
|
|
29
|
+
* allowNonStandardCharsets: true
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @see {@link https://encoding.spec.whatwg.org/#names-and-labels | WHATWG Encoding Standard}
|
|
34
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/TextDecoder | TextDecoder}
|
|
35
|
+
*/
|
|
36
|
+
export declare const SUPPORTED_CHARSETS: ReadonlySet<string>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const SUPPORTED_CHARSETS = /* @__PURE__ */ new Set([
|
|
2
|
+
// UTF encodings
|
|
3
|
+
"utf-8",
|
|
4
|
+
"utf8",
|
|
5
|
+
"unicode-1-1-utf-8",
|
|
6
|
+
"utf-16le",
|
|
7
|
+
"utf-16be",
|
|
8
|
+
"utf-16",
|
|
9
|
+
// ISO-8859 series (Western European)
|
|
10
|
+
"iso-8859-1",
|
|
11
|
+
"iso-8859-2",
|
|
12
|
+
"iso-8859-3",
|
|
13
|
+
"iso-8859-4",
|
|
14
|
+
"iso-8859-5",
|
|
15
|
+
"iso-8859-6",
|
|
16
|
+
"iso-8859-7",
|
|
17
|
+
"iso-8859-8",
|
|
18
|
+
"iso-8859-9",
|
|
19
|
+
"iso-8859-10",
|
|
20
|
+
"iso-8859-13",
|
|
21
|
+
"iso-8859-14",
|
|
22
|
+
"iso-8859-15",
|
|
23
|
+
"iso-8859-16",
|
|
24
|
+
"latin1",
|
|
25
|
+
// Windows code pages
|
|
26
|
+
"windows-1250",
|
|
27
|
+
"windows-1251",
|
|
28
|
+
"windows-1252",
|
|
29
|
+
"windows-1253",
|
|
30
|
+
"windows-1254",
|
|
31
|
+
"windows-1255",
|
|
32
|
+
"windows-1256",
|
|
33
|
+
"windows-1257",
|
|
34
|
+
"windows-1258",
|
|
35
|
+
// Japanese
|
|
36
|
+
"shift_jis",
|
|
37
|
+
"shift-jis",
|
|
38
|
+
"sjis",
|
|
39
|
+
"euc-jp",
|
|
40
|
+
"iso-2022-jp",
|
|
41
|
+
// Chinese
|
|
42
|
+
"gb18030",
|
|
43
|
+
"gbk",
|
|
44
|
+
"gb2312",
|
|
45
|
+
// Korean
|
|
46
|
+
"euc-kr",
|
|
47
|
+
// Other
|
|
48
|
+
"ascii",
|
|
49
|
+
"us-ascii"
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
export { SUPPORTED_CHARSETS };
|
|
53
|
+
//# sourceMappingURL=getCharsetValidation.constants.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getCharsetValidation.constants.web.js","sources":["../src/getCharsetValidation.constants.web.ts"],"sourcesContent":["/**\n * Commonly supported character encodings for CSV parsing in browser environments.\n *\n * @remarks\n * This list includes the most commonly used encodings that are supported across\n * all modern browsers. TextDecoder supports additional encodings, but this list\n * focuses on the most widely-used ones for CSV files.\n *\n * ### Common Character Encodings:\n * - **UTF-8**: Universal encoding, recommended for all new content\n * - **UTF-16LE/UTF-16BE**: Unicode encodings with byte order\n * - **ISO-8859-X**: Legacy single-byte encodings for Western European languages\n * - **Windows-125X**: Windows-specific legacy encodings\n * - **Shift_JIS, EUC-JP, ISO-2022-JP**: Japanese encodings\n * - **GB18030, GBK**: Chinese encodings\n * - **EUC-KR**: Korean encoding\n *\n * ### Using Non-Standard Charsets\n *\n * If you need to use a charset not in this list, you can:\n * 1. Set the `allowNonStandardCharsets` option to `true`\n * 2. Be aware that this may cause errors if the browser doesn't support the encoding\n * 3. Consider implementing fallback handling for unsupported charsets\n *\n * @example\n * ```typescript\n * // Use non-standard charset (may fail in some browsers)\n * const records = parseResponse(response, {\n * allowNonStandardCharsets: true\n * });\n * ```\n *\n * @see {@link https://encoding.spec.whatwg.org/#names-and-labels | WHATWG Encoding Standard}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/TextDecoder | TextDecoder}\n */\nexport const SUPPORTED_CHARSETS: ReadonlySet<string> = new Set([\n // UTF encodings\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\",\n \"utf-16le\",\n \"utf-16be\",\n \"utf-16\",\n\n // ISO-8859 series (Western European)\n \"iso-8859-1\",\n \"iso-8859-2\",\n \"iso-8859-3\",\n \"iso-8859-4\",\n \"iso-8859-5\",\n \"iso-8859-6\",\n \"iso-8859-7\",\n \"iso-8859-8\",\n \"iso-8859-9\",\n \"iso-8859-10\",\n \"iso-8859-13\",\n \"iso-8859-14\",\n \"iso-8859-15\",\n \"iso-8859-16\",\n \"latin1\",\n\n // Windows code pages\n \"windows-1250\",\n \"windows-1251\",\n \"windows-1252\",\n \"windows-1253\",\n \"windows-1254\",\n \"windows-1255\",\n \"windows-1256\",\n \"windows-1257\",\n \"windows-1258\",\n\n // Japanese\n \"shift_jis\",\n \"shift-jis\",\n \"sjis\",\n \"euc-jp\",\n \"iso-2022-jp\",\n\n // Chinese\n \"gb18030\",\n \"gbk\",\n \"gb2312\",\n\n // Korean\n \"euc-kr\",\n\n // Other\n \"ascii\",\n \"us-ascii\",\n]);\n"],"names":[],"mappings":"AAmCO,MAAM,kBAAA,uBAA8C,GAAA,CAAI;AAAA;AAAA,EAE7D,OAAA;AAAA,EACA,MAAA;AAAA,EACA,mBAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA;AAAA,EAGA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA;AAAA,EAGA,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA;AAAA,EAGA,QAAA;AAAA;AAAA,EAGA,OAAA;AAAA,EACA;AACF,CAAC;;;;"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SUPPORTED_CHARSETS } from './getCharsetValidation.constants.web.js';
|
|
1
2
|
import { SUPPORTED_COMPRESSIONS } from './getOptionsFromResponse.constants.web.js';
|
|
2
3
|
import { parseMime } from './utils/parseMime.js';
|
|
3
4
|
|
|
@@ -29,7 +30,22 @@ function getOptionsFromResponse(response, options = {}) {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
const
|
|
33
|
+
const rawCharset = mime.parameters.charset ?? "utf-8";
|
|
34
|
+
const normalizedCharset = rawCharset.trim().toLowerCase();
|
|
35
|
+
let charset;
|
|
36
|
+
if (SUPPORTED_CHARSETS.has(normalizedCharset)) {
|
|
37
|
+
charset = normalizedCharset;
|
|
38
|
+
} else if (normalizedCharset) {
|
|
39
|
+
if (options.allowNonStandardCharsets) {
|
|
40
|
+
charset = normalizedCharset;
|
|
41
|
+
} else {
|
|
42
|
+
throw new TypeError(
|
|
43
|
+
`Unsupported charset: "${rawCharset}". Commonly supported charsets include: utf-8, utf-16le, iso-8859-1, windows-1252, shift_jis, gb18030, euc-kr, etc. To use non-standard charsets, set allowNonStandardCharsets: true`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
charset = "utf-8";
|
|
48
|
+
}
|
|
33
49
|
return {
|
|
34
50
|
decompression,
|
|
35
51
|
charset,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getOptionsFromResponse.js","sources":["../src/getOptionsFromResponse.ts"],"sourcesContent":["import { SUPPORTED_COMPRESSIONS } from \"#getOptionsFromResponse.constants.js\";\nimport type { ParseBinaryOptions } from \"./common/types.ts\";\nimport type { DEFAULT_DELIMITER, DEFAULT_QUOTATION } from \"./constants.ts\";\nimport { parseMime } from \"./utils/parseMime.ts\";\n\n/**\n * Extracts the options from the response object.\n *\n * @param response - The response object from which to extract the options.\n * @param options - The options to merge with the extracted options.\n * @returns The options extracted from the response.\n * @throws {TypeError} - The content type is not supported or the content-encoding is invalid.\n */\nexport function getOptionsFromResponse<\n Header extends ReadonlyArray<string>,\n Delimiter extends string = DEFAULT_DELIMITER,\n Quotation extends string = '\"',\n>(\n response: Response,\n options: ParseBinaryOptions<\n Header,\n Delimiter,\n Quotation\n > = {} as ParseBinaryOptions<Header, Delimiter, Quotation>,\n): ParseBinaryOptions<Header, Delimiter, Quotation> {\n const { headers } = response;\n const contentType = headers.get(\"content-type\") ?? \"text/csv\";\n const mime = parseMime(contentType);\n if (mime.type !== \"text/csv\") {\n throw new TypeError(`Invalid mime type: \"${contentType}\"`);\n }\n\n const contentEncoding = headers.get(\"content-encoding\");\n let decompression: CompressionFormat | undefined;\n\n if (contentEncoding) {\n const normalizedEncoding = contentEncoding.trim().toLowerCase();\n\n if (normalizedEncoding.includes(\",\")) {\n throw new TypeError(\n `Multiple content-encodings are not supported: \"${contentEncoding}\"`,\n );\n }\n\n if (SUPPORTED_COMPRESSIONS.has(normalizedEncoding as CompressionFormat)) {\n decompression = normalizedEncoding as CompressionFormat;\n } else if (normalizedEncoding) {\n // Unknown compression format\n if (options.allowExperimentalCompressions) {\n // Allow runtime to handle experimental/future formats\n decompression = normalizedEncoding as CompressionFormat;\n } else {\n throw new TypeError(\n `Unsupported content-encoding: \"${contentEncoding}\". Supported formats: ${Array.from(SUPPORTED_COMPRESSIONS).join(\", \")}. To use experimental formats, set allowExperimentalCompressions: true`,\n );\n }\n }\n }\n\n
|
|
1
|
+
{"version":3,"file":"getOptionsFromResponse.js","sources":["../src/getOptionsFromResponse.ts"],"sourcesContent":["import { SUPPORTED_CHARSETS } from \"#getCharsetValidation.constants.js\";\nimport { SUPPORTED_COMPRESSIONS } from \"#getOptionsFromResponse.constants.js\";\nimport type { ParseBinaryOptions } from \"./common/types.ts\";\nimport type { DEFAULT_DELIMITER, DEFAULT_QUOTATION } from \"./constants.ts\";\nimport { parseMime } from \"./utils/parseMime.ts\";\n\n/**\n * Extracts the options from the response object.\n *\n * @param response - The response object from which to extract the options.\n * @param options - The options to merge with the extracted options.\n * @returns The options extracted from the response.\n * @throws {TypeError} - The content type is not supported or the content-encoding is invalid.\n */\nexport function getOptionsFromResponse<\n Header extends ReadonlyArray<string>,\n Delimiter extends string = DEFAULT_DELIMITER,\n Quotation extends string = '\"',\n>(\n response: Response,\n options: ParseBinaryOptions<\n Header,\n Delimiter,\n Quotation\n > = {} as ParseBinaryOptions<Header, Delimiter, Quotation>,\n): ParseBinaryOptions<Header, Delimiter, Quotation> {\n const { headers } = response;\n const contentType = headers.get(\"content-type\") ?? \"text/csv\";\n const mime = parseMime(contentType);\n if (mime.type !== \"text/csv\") {\n throw new TypeError(`Invalid mime type: \"${contentType}\"`);\n }\n\n const contentEncoding = headers.get(\"content-encoding\");\n let decompression: CompressionFormat | undefined;\n\n if (contentEncoding) {\n const normalizedEncoding = contentEncoding.trim().toLowerCase();\n\n if (normalizedEncoding.includes(\",\")) {\n throw new TypeError(\n `Multiple content-encodings are not supported: \"${contentEncoding}\"`,\n );\n }\n\n if (SUPPORTED_COMPRESSIONS.has(normalizedEncoding as CompressionFormat)) {\n decompression = normalizedEncoding as CompressionFormat;\n } else if (normalizedEncoding) {\n // Unknown compression format\n if (options.allowExperimentalCompressions) {\n // Allow runtime to handle experimental/future formats\n decompression = normalizedEncoding as CompressionFormat;\n } else {\n throw new TypeError(\n `Unsupported content-encoding: \"${contentEncoding}\". Supported formats: ${Array.from(SUPPORTED_COMPRESSIONS).join(\", \")}. To use experimental formats, set allowExperimentalCompressions: true`,\n );\n }\n }\n }\n\n // Validate and normalize charset\n const rawCharset = mime.parameters.charset ?? \"utf-8\";\n const normalizedCharset = rawCharset.trim().toLowerCase();\n\n let charset: string;\n if (SUPPORTED_CHARSETS.has(normalizedCharset)) {\n charset = normalizedCharset;\n } else if (normalizedCharset) {\n // Unknown charset\n if (options.allowNonStandardCharsets) {\n // Allow runtime to handle non-standard charsets\n charset = normalizedCharset;\n } else {\n throw new TypeError(\n `Unsupported charset: \"${rawCharset}\". Commonly supported charsets include: utf-8, utf-16le, iso-8859-1, windows-1252, shift_jis, gb18030, euc-kr, etc. To use non-standard charsets, set allowNonStandardCharsets: true`,\n );\n }\n } else {\n charset = \"utf-8\";\n }\n\n // TODO: Support header=present and header=absent\n // const header = mime.parameters.header ?? \"present\";\n return {\n decompression,\n charset,\n ...options,\n };\n}\n"],"names":[],"mappings":";;;;AAcO,SAAS,sBAAA,CAKd,QAAA,EACA,OAAA,GAII,EAAC,EAC6C;AAClD,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AACpB,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,UAAA;AACnD,EAAA,MAAM,IAAA,GAAO,UAAU,WAAW,CAAA;AAClC,EAAA,IAAI,IAAA,CAAK,SAAS,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,oBAAA,EAAuB,WAAW,CAAA,CAAA,CAAG,CAAA;AAAA,EAC3D;AAEA,EAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA;AACtD,EAAA,IAAI,aAAA;AAEJ,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,MAAM,kBAAA,GAAqB,eAAA,CAAgB,IAAA,EAAK,CAAE,WAAA,EAAY;AAE9D,IAAA,IAAI,kBAAA,CAAmB,QAAA,CAAS,GAAG,CAAA,EAAG;AACpC,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,kDAAkD,eAAe,CAAA,CAAA;AAAA,OACnE;AAAA,IACF;AAEA,IAAA,IAAI,sBAAA,CAAuB,GAAA,CAAI,kBAAuC,CAAA,EAAG;AACvE,MAAA,aAAA,GAAgB,kBAAA;AAAA,IAClB,WAAW,kBAAA,EAAoB;AAE7B,MAAA,IAAI,QAAQ,6BAAA,EAA+B;AAEzC,QAAA,aAAA,GAAgB,kBAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,MAAM,IAAI,SAAA;AAAA,UACR,CAAA,+BAAA,EAAkC,eAAe,CAAA,sBAAA,EAAyB,KAAA,CAAM,KAAK,sBAAsB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,sEAAA;AAAA,SACzH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,UAAA,CAAW,OAAA,IAAW,OAAA;AAC9C,EAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,IAAA,EAAK,CAAE,WAAA,EAAY;AAExD,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,iBAAiB,CAAA,EAAG;AAC7C,IAAA,OAAA,GAAU,iBAAA;AAAA,EACZ,WAAW,iBAAA,EAAmB;AAE5B,IAAA,IAAI,QAAQ,wBAAA,EAA0B;AAEpC,MAAA,OAAA,GAAU,iBAAA;AAAA,IACZ,CAAA,MAAO;AACL,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,yBAAyB,UAAU,CAAA,oLAAA;AAAA,OACrC;AAAA,IACF;AAAA,EACF,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,OAAA;AAAA,EACZ;AAIA,EAAA,OAAO;AAAA,IACL,aAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAG;AAAA,GACL;AACF;;;;"}
|
|
@@ -11,10 +11,23 @@ function convertBinaryToString(binary, options) {
|
|
|
11
11
|
`Binary size (${binary.byteLength} bytes) exceeded maximum allowed size of ${maxBinarySize} bytes`
|
|
12
12
|
);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
let decoder;
|
|
15
|
+
try {
|
|
16
|
+
decoder = new TextDecoder(options?.charset, {
|
|
17
|
+
ignoreBOM: options?.ignoreBOM,
|
|
18
|
+
fatal: options?.fatal
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (error instanceof RangeError || error instanceof TypeError) {
|
|
22
|
+
throw new RangeError(
|
|
23
|
+
`Invalid or unsupported charset: "${options?.charset}". Please specify a valid charset or enable allowNonStandardCharsets option.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
return decoder.decode(
|
|
29
|
+
binary instanceof ArrayBuffer ? new Uint8Array(binary) : binary
|
|
30
|
+
);
|
|
18
31
|
}
|
|
19
32
|
|
|
20
33
|
export { convertBinaryToString };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertBinaryToString.js","sources":["../../src/utils/convertBinaryToString.ts"],"sourcesContent":["import type { BinaryOptions } from \"../common/types.ts\";\n\n/**\n * Default maximum binary size in bytes (100MB).\n */\nconst DEFAULT_MAX_BINARY_SIZE = 100 * 1024 * 1024;\n\n/**\n * Converts a binary string to a string.\n *\n * @param binary - The binary string to convert.\n * @param options - The options for parsing the binary string.\n * @returns The converted string.\n * @throws {RangeError} The given charset is not supported or binary size exceeds the limit.\n * @throws {TypeError} The encoded data was not valid.\n */\nexport function convertBinaryToString(\n binary: Uint8Array | ArrayBuffer,\n options: BinaryOptions,\n): string {\n const maxBinarySize = options?.maxBinarySize ?? DEFAULT_MAX_BINARY_SIZE;\n\n // Validate maxBinarySize\n if (\n !(\n Number.isFinite(maxBinarySize) ||\n maxBinarySize === Number.POSITIVE_INFINITY\n ) ||\n (Number.isFinite(maxBinarySize) && maxBinarySize < 0)\n ) {\n throw new RangeError(\n \"maxBinarySize must be a non-negative number or Number.POSITIVE_INFINITY\",\n );\n }\n\n // Check binary size\n if (Number.isFinite(maxBinarySize) && binary.byteLength > maxBinarySize) {\n throw new RangeError(\n `Binary size (${binary.byteLength} bytes) exceeded maximum allowed size of ${maxBinarySize} bytes`,\n );\n }\n\n
|
|
1
|
+
{"version":3,"file":"convertBinaryToString.js","sources":["../../src/utils/convertBinaryToString.ts"],"sourcesContent":["import type { BinaryOptions } from \"../common/types.ts\";\n\n/**\n * Default maximum binary size in bytes (100MB).\n */\nconst DEFAULT_MAX_BINARY_SIZE = 100 * 1024 * 1024;\n\n/**\n * Converts a binary string to a string.\n *\n * @param binary - The binary string to convert.\n * @param options - The options for parsing the binary string.\n * @returns The converted string.\n * @throws {RangeError} The given charset is not supported or binary size exceeds the limit.\n * @throws {TypeError} The encoded data was not valid.\n */\nexport function convertBinaryToString(\n binary: Uint8Array | ArrayBuffer,\n options: BinaryOptions,\n): string {\n const maxBinarySize = options?.maxBinarySize ?? DEFAULT_MAX_BINARY_SIZE;\n\n // Validate maxBinarySize\n if (\n !(\n Number.isFinite(maxBinarySize) ||\n maxBinarySize === Number.POSITIVE_INFINITY\n ) ||\n (Number.isFinite(maxBinarySize) && maxBinarySize < 0)\n ) {\n throw new RangeError(\n \"maxBinarySize must be a non-negative number or Number.POSITIVE_INFINITY\",\n );\n }\n\n // Check binary size\n if (Number.isFinite(maxBinarySize) && binary.byteLength > maxBinarySize) {\n throw new RangeError(\n `Binary size (${binary.byteLength} bytes) exceeded maximum allowed size of ${maxBinarySize} bytes`,\n );\n }\n\n // Try to create TextDecoder with error handling for invalid charsets\n let decoder: TextDecoder;\n try {\n decoder = new TextDecoder(options?.charset, {\n ignoreBOM: options?.ignoreBOM,\n fatal: options?.fatal,\n });\n } catch (error) {\n // If charset is invalid, provide clear error message\n if (error instanceof RangeError || error instanceof TypeError) {\n throw new RangeError(\n `Invalid or unsupported charset: \"${options?.charset}\". Please specify a valid charset or enable allowNonStandardCharsets option.`,\n );\n }\n throw error;\n }\n\n return decoder.decode(\n binary instanceof ArrayBuffer ? new Uint8Array(binary) : binary,\n );\n}\n"],"names":[],"mappings":"AAKA,MAAM,uBAAA,GAA0B,MAAM,IAAA,GAAO,IAAA;AAWtC,SAAS,qBAAA,CACd,QACA,OAAA,EACQ;AACR,EAAA,MAAM,aAAA,GAAgB,SAAS,aAAA,IAAiB,uBAAA;AAGhD,EAAA,IACE,EACE,MAAA,CAAO,QAAA,CAAS,aAAa,CAAA,IAC7B,aAAA,KAAkB,MAAA,CAAO,iBAAA,CAAA,IAE1B,MAAA,CAAO,QAAA,CAAS,aAAa,CAAA,IAAK,gBAAgB,CAAA,EACnD;AACA,IAAA,MAAM,IAAI,UAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,QAAA,CAAS,aAAa,CAAA,IAAK,MAAA,CAAO,aAAa,aAAA,EAAe;AACvE,IAAA,MAAM,IAAI,UAAA;AAAA,MACR,CAAA,aAAA,EAAgB,MAAA,CAAO,UAAU,CAAA,yCAAA,EAA4C,aAAa,CAAA,MAAA;AAAA,KAC5F;AAAA,EACF;AAGA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,IAAI,WAAA,CAAY,OAAA,EAAS,OAAA,EAAS;AAAA,MAC1C,WAAW,OAAA,EAAS,SAAA;AAAA,MACpB,OAAO,OAAA,EAAS;AAAA,KACjB,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AAEd,IAAA,IAAI,KAAA,YAAiB,UAAA,IAAc,KAAA,YAAiB,SAAA,EAAW;AAC7D,MAAA,MAAM,IAAI,UAAA;AAAA,QACR,CAAA,iCAAA,EAAoC,SAAS,OAAO,CAAA,4EAAA;AAAA,OACtD;AAAA,IACF;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AAEA,EAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,IACb,MAAA,YAAkB,WAAA,GAAc,IAAI,UAAA,CAAW,MAAM,CAAA,GAAI;AAAA,GAC3D;AACF;;;;"}
|
package/dist/utils/parseMime.js
CHANGED
|
@@ -6,7 +6,9 @@ function parseMime(contentType) {
|
|
|
6
6
|
};
|
|
7
7
|
for (const paramator of parameters) {
|
|
8
8
|
const [key, value] = paramator.split("=");
|
|
9
|
-
|
|
9
|
+
if (value !== void 0) {
|
|
10
|
+
result.parameters[key.trim()] = value.trim();
|
|
11
|
+
}
|
|
10
12
|
}
|
|
11
13
|
return result;
|
|
12
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseMime.js","sources":["../../src/utils/parseMime.ts"],"sourcesContent":["export interface ParseMimeResult {\n type: string;\n parameters: {\n [key: string]: string;\n };\n}\n\nexport function parseMime(contentType: string) {\n const [type, ...parameters] = contentType.split(\";\");\n const result: ParseMimeResult = {\n type: type.trim(),\n parameters: {},\n };\n for (const paramator of parameters) {\n const [key, value] = paramator.split(\"=\");\n result.parameters[key.trim()] = value.trim();\n }\n return result;\n}\n"],"names":[],"mappings":"AAOO,SAAS,UAAU,WAAA,EAAqB;AAC7C,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,UAAU,CAAA,GAAI,WAAA,CAAY,MAAM,GAAG,CAAA;AACnD,EAAA,MAAM,MAAA,GAA0B;AAAA,IAC9B,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,IAChB,YAAY;AAAC,GACf;AACA,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,CAAC,GAAA,EAAK,KAAK,CAAA,GAAI,SAAA,CAAU,MAAM,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"parseMime.js","sources":["../../src/utils/parseMime.ts"],"sourcesContent":["export interface ParseMimeResult {\n type: string;\n parameters: {\n [key: string]: string;\n };\n}\n\nexport function parseMime(contentType: string) {\n const [type, ...parameters] = contentType.split(\";\");\n const result: ParseMimeResult = {\n type: type.trim(),\n parameters: {},\n };\n for (const paramator of parameters) {\n const [key, value] = paramator.split(\"=\");\n // Skip parameters without values to prevent undefined.trim() errors\n if (value !== undefined) {\n result.parameters[key.trim()] = value.trim();\n }\n }\n return result;\n}\n"],"names":[],"mappings":"AAOO,SAAS,UAAU,WAAA,EAAqB;AAC7C,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,UAAU,CAAA,GAAI,WAAA,CAAY,MAAM,GAAG,CAAA;AACnD,EAAA,MAAM,MAAA,GAA0B;AAAA,IAC9B,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,IAChB,YAAY;AAAC,GACf;AACA,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,CAAC,GAAA,EAAK,KAAK,CAAA,GAAI,SAAA,CAAU,MAAM,GAAG,CAAA;AAExC,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,MAAA,CAAO,WAAW,GAAA,CAAI,IAAA,EAAM,CAAA,GAAI,MAAM,IAAA,EAAK;AAAA,IAC7C;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-csv-toolbox",
|
|
3
|
-
"version": "0.14.0-next-
|
|
3
|
+
"version": "0.14.0-next-e45bc4d089f1fb259a7596b9862b3b34e717dab7",
|
|
4
4
|
"description": "A CSV Toolbox utilizing Web Standard APIs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "dist/web-csv-toolbox.js",
|
|
@@ -56,6 +56,12 @@
|
|
|
56
56
|
"browser": "./dist/getOptionsFromResponse.constants.web.js",
|
|
57
57
|
"default": "./dist/getOptionsFromResponse.constants.web.js"
|
|
58
58
|
},
|
|
59
|
+
"#getCharsetValidation.constants.js": {
|
|
60
|
+
"types": "./dist/getCharsetValidation.constants.d.ts",
|
|
61
|
+
"node": "./dist/getCharsetValidation.constants.node.js",
|
|
62
|
+
"browser": "./dist/getCharsetValidation.constants.web.js",
|
|
63
|
+
"default": "./dist/getCharsetValidation.constants.web.js"
|
|
64
|
+
},
|
|
59
65
|
"#execution/worker/parseStringInWorker.js": {
|
|
60
66
|
"types": "./dist/execution/worker/parseStringInWorker.d.ts",
|
|
61
67
|
"node": "./dist/execution/worker/parseStringInWorker.node.js",
|