web-csv-toolbox 0.2.0 → 0.3.0

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/lib/index.js CHANGED
@@ -1,13 +1,11 @@
1
1
  const FieldDelimiter = Symbol.for("web-streams-csv.FieldDelimiter");
2
2
  const RecordDelimiter = Symbol.for("web-streams-csv.RecordDelimiter");
3
3
  const Field = Symbol.for("web-streams-csv.Field");
4
-
5
4
  const CR = "\r";
6
5
  const CRLF = "\r\n";
7
6
  const LF = "\n";
8
7
  const COMMA = ",";
9
8
  const DOUBLE_QUATE = '"';
10
-
11
9
  function assertCommonOptions(options) {
12
10
  if (typeof options.quotation === "string" && options.quotation.length === 0) {
13
11
  throw new Error("quotation must not be empty");
@@ -30,11 +28,9 @@ function assertCommonOptions(options) {
30
28
  );
31
29
  }
32
30
  }
33
-
34
31
  function escapeRegExp(v) {
35
32
  return v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36
33
  }
37
-
38
34
  class LexerTransformer extends TransformStream {
39
35
  #demiliter;
40
36
  #demiliterLength;
@@ -166,7 +162,6 @@ class LexerTransformer extends TransformStream {
166
162
  return null;
167
163
  }
168
164
  }
169
-
170
165
  class RecordAssemblerTransformar extends TransformStream {
171
166
  #fieldIndex = 0;
172
167
  #row = [];
@@ -229,7 +224,6 @@ class RecordAssemblerTransformar extends TransformStream {
229
224
  }
230
225
  }
231
226
  }
232
-
233
227
  class SingleValueReadableStream extends ReadableStream {
234
228
  constructor(value) {
235
229
  super({
@@ -240,7 +234,6 @@ class SingleValueReadableStream extends ReadableStream {
240
234
  });
241
235
  }
242
236
  }
243
-
244
237
  async function toArray(...args) {
245
238
  const rows = [];
246
239
  for await (const row of this(...args)) {
@@ -248,7 +241,6 @@ async function toArray(...args) {
248
241
  }
249
242
  return rows;
250
243
  }
251
-
252
244
  async function* parseStringStream(stream, options) {
253
245
  let controller;
254
246
  const readable = new ReadableStream({
@@ -277,14 +269,12 @@ async function* parseStringStream(stream, options) {
277
269
  ((parseStringStream) => {
278
270
  parseStringStream.toArray = toArray;
279
271
  })(parseStringStream || (parseStringStream = {}));
280
-
281
272
  async function* parseString(csv, options) {
282
273
  yield* parseStringStream(new SingleValueReadableStream(csv), options);
283
274
  }
284
275
  ((parseString) => {
285
276
  parseString.toArray = toArray;
286
277
  })(parseString || (parseString = {}));
287
-
288
278
  async function* parseBinaryStream(stream, options) {
289
279
  const { charset, fatal, ignoreBOM, decomposition } = options ?? {};
290
280
  yield* parseStringStream(
@@ -298,7 +288,6 @@ async function* parseBinaryStream(stream, options) {
298
288
  ((parseBinaryStream) => {
299
289
  parseBinaryStream.toArray = toArray;
300
290
  })(parseBinaryStream || (parseBinaryStream = {}));
301
-
302
291
  function parseMime(contentType) {
303
292
  const [type, ...parameters] = contentType.split(";");
304
293
  const result = {
@@ -311,7 +300,6 @@ function parseMime(contentType) {
311
300
  }
312
301
  return result;
313
302
  }
314
-
315
303
  function parseResponse(response, options) {
316
304
  const { headers } = response;
317
305
  const contentType = headers.get("content-type") ?? "text/csv";
@@ -333,7 +321,6 @@ function parseResponse(response, options) {
333
321
  ((parseResponse) => {
334
322
  parseResponse.toArray = toArray;
335
323
  })(parseResponse || (parseResponse = {}));
336
-
337
324
  async function* parseStream(stream, options) {
338
325
  const [branch1, branch2] = stream.tee();
339
326
  const reader1 = branch1.getReader();
@@ -348,7 +335,6 @@ async function* parseStream(stream, options) {
348
335
  ((parseStream) => {
349
336
  parseStream.toArray = toArray;
350
337
  })(parseStream || (parseStream = {}));
351
-
352
338
  async function* parse(csv, options) {
353
339
  if (typeof csv === "string") {
354
340
  yield* parseString(csv, options);
@@ -361,7 +347,6 @@ async function* parse(csv, options) {
361
347
  ((parse) => {
362
348
  parse.toArray = toArray;
363
349
  })(parse || (parse = {}));
364
-
365
350
  export {
366
351
  Field,
367
352
  FieldDelimiter,
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).CSV={})}(this,(function(e){"use strict";const t=Symbol.for("web-streams-csv.FieldDelimiter"),i=Symbol.for("web-streams-csv.RecordDelimiter"),r=Symbol.for("web-streams-csv.Field"),n="\n";function s(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}class o extends TransformStream{#e;#t;#i;#r;#n;#s="";get demiliter(){return this.#e}get quotation(){return this.#i}constructor({demiliter:e=",",quotation:t='"'}={}){!function(e){if("string"==typeof e.quotation&&0===e.quotation.length)throw new Error("quotation must not be empty");if("string"==typeof e.demiliter&&0===e.demiliter.length)throw new Error("demiliter must not be empty");if(e.quotation.includes(n)||e.quotation.includes("\r"))throw new Error("quotation must not include CR or LF");if(e.demiliter.includes(n)||e.demiliter.includes("\r"))throw new Error("demiliter must not include CR or LF");if(e.demiliter.includes(e.quotation)||e.quotation.includes(e.demiliter))throw new Error("demiliter and quotation must not include each other as a substring")}({demiliter:e,quotation:t}),super({transform:(e,t)=>{if(0!==e.length){this.#s+=e;for(const e of this.#o({flush:!1}))t.enqueue(e)}},flush:e=>{for(const t of this.#o({flush:!0}))e.enqueue(t)}}),this.#e=e,this.#t=e.length,this.#i=t,this.#r=t.length;const i=s(e),r=s(t);this.#n=new RegExp(`^(?:(?!${r})(?!${i})(?![\\r\\n]))([\\S\\s\\uFEFF\\xA0]+?)(?=${r}|${i}|\\r|\\n|$)`)}*#o({flush:e}){let n=null;for(let s;s=this.#a({flush:e});)switch(s.type){case r:n?n.value+=s.value:n=s;break;case t:case i:n&&(yield n,n=null),yield s}n&&(yield n)}#a({flush:e=!1}={}){if(0===this.#s.length)return null;if(this.#s.startsWith("\r\n"))return this.#s=this.#s.slice(2),{type:i,value:"\r\n"};if(this.#s.startsWith(n))return this.#s=this.#s.slice(1),{type:i,value:n};if(this.#s.startsWith(this.#e))return this.#s=this.#s.slice(this.#t),{type:t,value:this.#e};if(this.#s.startsWith(this.#i))return!1===e&&this.#s.endsWith(this.#i)?null:this.extractQuotedString();const s=this.#n.exec(this.#s);return s?!1===e&&s[0].length===this.#s.length?null:(this.#s=this.#s.slice(s[0].length),{type:r,value:s[0]}):null}extractQuotedString(){let e=this.#r,t="";for(;e<this.#s.length;)if(this.#s.slice(e,e+this.#r)!==this.quotation||this.#s.slice(e+this.#r,e+2*this.#r)!==this.quotation){if(this.#s.slice(e,e+this.#r)===this.quotation)return this.#s=this.#s.slice(e+this.#r),{type:r,value:t};t+=this.#s[e],e++}else t+=this.quotation,e+=2*this.#r;return null}}class a extends TransformStream{#u=0;#h=[];#l;#f=!1;constructor(e={}){super({transform:(e,n)=>{switch(e.type){case r:this.#f=!0,this.#h[this.#u]=e.value;break;case t:this.#u++;break;case i:if(void 0===this.#l)this.#d(this.#h);else if(this.#f){const e=Object.fromEntries(this.#l.filter((e=>e)).map(((e,t)=>[e,this.#h.at(t)])));n.enqueue(e)}this.#u=0,this.#h=new Array(this.#l?.length),this.#f=!1}},flush:e=>{if(0!==this.#u&&void 0!==this.#l&&this.#f){const t=Object.fromEntries(this.#l.filter((e=>e)).map(((e,t)=>[e,this.#h.at(t)])));e.enqueue(t)}}}),void 0!==e.header&&Array.isArray(e.header)&&this.#d(e.header)}#d(e){if(this.#l=e,0===this.#l.length)throw new Error("The header must not be empty.");if(new Set(this.#l).size!==this.#l.length)throw new Error("The header must not contain duplicate fields.")}}class u extends ReadableStream{constructor(e){super({start(t){t.enqueue(e),t.close()}})}}async function h(...e){const t=[];for await(const i of this(...e))t.push(i);return t}async function*l(e,t){let i;const r=new ReadableStream({start:e=>i=e});await e.pipeThrough(new o(t)).pipeThrough(new a(t)).pipeTo(new WritableStream({write:e=>i.enqueue(e),close:()=>i.close()}));const n=r.getReader();try{for(;;){const{value:e,done:t}=await n.read();if(t)break;yield e}}finally{n.releaseLock()}}async function*f(e,t){yield*l(new u(e),t)}async function*d(e,t){const{charset:i,fatal:r,ignoreBOM:n,decomposition:s}=t??{};yield*l([...s?[new DecompressionStream(s)]:[],new TextDecoderStream(i,{fatal:r,ignoreBOM:n})].reduce(((e,t)=>e.pipeThrough(t)),e),t)}function c(e,t){const{headers:i}=e,r=i.get("content-type")??"text/csv",n=function(e){const[t,...i]=e.split(";"),r={type:t.trim(),parameters:{}};for(const e of i){const[t,i]=e.split("=");r.parameters[t.trim()]=i.trim()}return r}(r);if("text/csv"!==n.type)throw new Error(`Invalid mime type: ${r}`);const s=i.get("content-encoding")??void 0,o=n.parameters.charset??"utf-8";if(null===e.body)throw new Error("Response body is null");return d(e.body,{decomposition:s,charset:o,...t})}async function*m(e,t){const[i,r]=e.tee(),n=i.getReader(),{value:s}=await n.read();n.releaseLock(),"string"==typeof s?yield*l(r,t):s instanceof Uint8Array&&(yield*d(r,t))}async function*y(e,t){"string"==typeof e?yield*f(e,t):e instanceof ReadableStream?yield*m(e,t):e instanceof Response&&(yield*c(e,t))}!function(e){e.toArray=h}(l||(l={})),function(e){e.toArray=h}(f||(f={})),function(e){e.toArray=h}(d||(d={})),function(e){e.toArray=h}(c||(c={})),function(e){e.toArray=h}(m||(m={})),function(e){e.toArray=h}(y||(y={})),e.Field=r,e.FieldDelimiter=t,e.LexerTransformer=o,e.RecordAssemblerTransformar=a,e.RecordDelimiter=i,e.parse=y,e.parseBinaryStream=d,e.parseResponse=c,e.parseStream=m,e.parseString=f,e.parseStringStream=l}));
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "web-csv-toolbox",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A CSV Toolbox utilizing Web Standard APIs.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "module": "lib/index.js",
8
8
  "types": "lib/index.d.ts",
9
+ "unpkg": "lib/index.umd.js",
9
10
  "engines": {
10
11
  "node": ">=18.0.0"
11
12
  },
@@ -51,6 +52,7 @@
51
52
  "@changesets/changelog-github": "^0.5.0",
52
53
  "@changesets/cli": "^2.27.1",
53
54
  "@fast-check/vitest": "^0.0.9",
55
+ "@rollup/plugin-terser": "^0.4.4",
54
56
  "changesets-github-release": "^0.1.0",
55
57
  "husky": "^8.0.0",
56
58
  "jsdom": "^23.0.1",