@nyaomaru/divider 2.0.7 → 2.0.8

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/index.cjs CHANGED
@@ -443,11 +443,7 @@ function dividerNumberString(input, options) {
443
443
  return transformDividerInput(input, divideNumberString, options);
444
444
  }
445
445
 
446
- // src/utils/quoted.ts
447
- function dividePreserve(input, separator) {
448
- if (isEmptyString(input)) return [""];
449
- return divider(input, separator, { preserveEmpty: true });
450
- }
446
+ // src/utils/count-unescaped.ts
451
447
  var countUnescapedSingleChar = (text, quote) => {
452
448
  let count = 0;
453
449
  for (let index = 0; index < text.length; index++) {
@@ -484,22 +480,14 @@ function countUnescaped(text, quote) {
484
480
  if (quote.length === 1) return countUnescapedSingleChar(text, quote);
485
481
  return countUnescapedMultiChar(text, quote);
486
482
  }
487
- function stripOuterQuotes(text, quoteChar, { lenient = true } = {}) {
488
- const escapedPair = quoteChar + quoteChar;
489
- const isWhitespace = (char) => char === WHITE_SPACE || char === TAB;
490
- const restoreEscapedQuotes = (fieldText) => fieldText.split(escapedPair).join(quoteChar);
491
- const stripped = stripOuterQuotesRaw(text, quoteChar, lenient, isWhitespace);
492
- return restoreEscapedQuotes(stripped);
493
- }
494
- function quotedDivide(line, {
495
- delimiter = ",",
496
- quote = '"',
497
- trim = false,
498
- lenient = true
499
- } = {}) {
500
- if (isEmptyString(line)) return [""];
501
- return buildQuotedFields(line, delimiter, quote, trim, lenient);
483
+
484
+ // src/utils/divide-preserve.ts
485
+ function dividePreserve(input, separator) {
486
+ if (isEmptyString(input)) return [""];
487
+ return divider(input, separator, { preserveEmpty: true });
502
488
  }
489
+
490
+ // src/utils/strip-outer-quotes.ts
503
491
  var findNonSpaceBounds = (text, isWhitespace) => {
504
492
  let left = 0;
505
493
  let right = text.length - 1;
@@ -507,44 +495,42 @@ var findNonSpaceBounds = (text, isWhitespace) => {
507
495
  while (right >= left && isWhitespace(text[right])) right--;
508
496
  return { left, right };
509
497
  };
510
- var stripMatchedOuterQuotes = (text, left, right) => text.slice(0, left) + text.slice(left + 1, right) + text.slice(right + 1);
511
- var removeCharAt = (text, index) => text.slice(0, index) + text.slice(index + 1);
512
- var stripTrailingQuote = (text, quoteChar, isWhitespace) => {
498
+ var stripMatchedOuterQuotes = (text, left, rightQuoteStart, quote) => text.slice(0, left) + text.slice(left + quote.length, rightQuoteStart) + text.slice(rightQuoteStart + quote.length);
499
+ var removeQuoteAt = (text, start, quote) => text.slice(0, start) + text.slice(start + quote.length);
500
+ var stripTrailingQuote = (text, quote, isWhitespace) => {
501
+ const quoteLength = quote.length;
513
502
  let lastNonSpaceIndex = text.length - 1;
514
503
  while (lastNonSpaceIndex >= 0 && isWhitespace(text[lastNonSpaceIndex])) {
515
504
  lastNonSpaceIndex--;
516
505
  }
517
- if (lastNonSpaceIndex < 0 || text[lastNonSpaceIndex] !== quoteChar) {
506
+ const trailingQuoteStart = lastNonSpaceIndex - quoteLength + 1;
507
+ if (trailingQuoteStart < 0 || !text.startsWith(quote, trailingQuoteStart)) {
518
508
  return text;
519
509
  }
520
- return removeCharAt(text, lastNonSpaceIndex);
510
+ return removeQuoteAt(text, trailingQuoteStart, quote);
521
511
  };
522
- var stripOuterQuotesRaw = (text, quoteChar, lenient, isWhitespace) => {
512
+ var stripOuterQuotesRaw = (text, quote, lenient, isWhitespace) => {
513
+ if (quote.length === 0) return text;
523
514
  const { left, right } = findNonSpaceBounds(text, isWhitespace);
524
515
  if (left > right) return text;
525
- if (text[left] !== quoteChar) return text;
526
- if (text[right] === quoteChar && right > left) {
527
- return stripMatchedOuterQuotes(text, left, right);
516
+ if (!text.startsWith(quote, left)) return text;
517
+ const rightQuoteStart = right - quote.length + 1;
518
+ if (rightQuoteStart >= left + quote.length && text.startsWith(quote, rightQuoteStart)) {
519
+ return stripMatchedOuterQuotes(text, left, rightQuoteStart, quote);
528
520
  }
529
521
  if (!lenient) return text;
530
- const withoutLeading = removeCharAt(text, left);
531
- return stripTrailingQuote(withoutLeading, quoteChar, isWhitespace);
532
- };
533
- var buildQuotedFields = (line, delimiter, quote, trim, lenient) => {
534
- const pieces = dividePreserve(line, delimiter);
535
- const state = {
536
- fields: [],
537
- current: "",
538
- insideQuotes: false
539
- };
540
- for (const piece of pieces) {
541
- appendPiece(state, piece, delimiter, quote, trim, lenient);
542
- }
543
- if (!isEmptyString(state.current)) {
544
- flushField(state, quote, trim, lenient);
545
- }
546
- return state.fields;
522
+ const withoutLeading = removeQuoteAt(text, left, quote);
523
+ return stripTrailingQuote(withoutLeading, quote, isWhitespace);
547
524
  };
525
+ function stripOuterQuotes(text, quoteChar, { lenient = true } = {}) {
526
+ const isWhitespace = (char) => char === WHITE_SPACE || char === TAB;
527
+ const stripped = stripOuterQuotesRaw(text, quoteChar, lenient, isWhitespace);
528
+ if (quoteChar.length === 0) return stripped;
529
+ const escapedPair = quoteChar + quoteChar;
530
+ return stripped.split(escapedPair).join(quoteChar);
531
+ }
532
+
533
+ // src/utils/quoted-parser.ts
548
534
  var advanceQuoteState = (insideQuotes, segment, quote) => {
549
535
  let nextInsideQuotes = insideQuotes;
550
536
  for (const char of segment) {
@@ -552,6 +538,13 @@ var advanceQuoteState = (insideQuotes, segment, quote) => {
552
538
  }
553
539
  return nextInsideQuotes;
554
540
  };
541
+ var flushField = (state, quote, trim, lenient) => {
542
+ let fieldValue = stripOuterQuotes(state.current, quote, { lenient });
543
+ if (trim) fieldValue = fieldValue.trim();
544
+ state.fields.push(fieldValue);
545
+ state.current = "";
546
+ state.insideQuotes = false;
547
+ };
555
548
  var appendPiece = (state, piece, delimiter, quote, trim, lenient) => {
556
549
  const segment = isEmptyString(state.current) ? piece : delimiter + piece;
557
550
  state.current += segment;
@@ -560,13 +553,30 @@ var appendPiece = (state, piece, delimiter, quote, trim, lenient) => {
560
553
  flushField(state, quote, trim, lenient);
561
554
  }
562
555
  };
563
- var flushField = (state, quote, trim, lenient) => {
564
- let fieldValue = stripOuterQuotes(state.current, quote, { lenient });
565
- if (trim) fieldValue = fieldValue.trim();
566
- state.fields.push(fieldValue);
567
- state.current = "";
568
- state.insideQuotes = false;
556
+ var buildQuotedFields = (line, delimiter, quote, trim, lenient) => {
557
+ const pieces = dividePreserve(line, delimiter);
558
+ const state = {
559
+ fields: [],
560
+ current: "",
561
+ insideQuotes: false
562
+ };
563
+ for (const piece of pieces) {
564
+ appendPiece(state, piece, delimiter, quote, trim, lenient);
565
+ }
566
+ if (!isEmptyString(state.current)) {
567
+ flushField(state, quote, trim, lenient);
568
+ }
569
+ return state.fields;
569
570
  };
571
+ function quotedDivide(line, {
572
+ delimiter = ",",
573
+ quote = '"',
574
+ trim = false,
575
+ lenient = true
576
+ } = {}) {
577
+ if (isEmptyString(line)) return [""];
578
+ return buildQuotedFields(line, delimiter, quote, trim, lenient);
579
+ }
570
580
 
571
581
  // src/presets/csv-divider.ts
572
582
  function csvDivider(line, options = {}) {
package/dist/index.d.cts CHANGED
@@ -223,9 +223,9 @@ type EmailDividerOptions = Pick<DividerOptions, 'trim'> & {
223
223
  readonly splitTLD?: boolean;
224
224
  };
225
225
  type CsvDividerOptions = Pick<DividerOptions, 'trim'> & {
226
- /** Character used for quoting values. */
226
+ /** Quote string used for quoting values. */
227
227
  readonly quoteChar?: string;
228
- /** Character used to separate CSV fields. */
228
+ /** Delimiter string used to separate CSV fields. */
229
229
  readonly delimiter?: string;
230
230
  };
231
231
  type PathDividerOptions = Pick<DividerOptions, 'trim'> & {
@@ -243,8 +243,8 @@ type QueryDividerOptions = Pick<DividerOptions, 'trim'> & {
243
243
  *
244
244
  * @param line - The CSV line string to be divided into fields
245
245
  * @param options - Configuration options for CSV parsing
246
- * @param options.delimiter - The character used to separate fields (default: ',')
247
- * @param options.quoteChar - The character used to quote fields containing delimiters or newlines (default: '"')
246
+ * @param options.delimiter - The delimiter string used to separate fields (default: ',')
247
+ * @param options.quoteChar - The quote string used to wrap fields containing delimiters or newlines (default: '"')
248
248
  * @param options.trim - Whether to trim whitespace from field values (default: false)
249
249
  * @returns A DividerStringResult containing the parsed CSV fields
250
250
  */
package/dist/index.d.ts CHANGED
@@ -223,9 +223,9 @@ type EmailDividerOptions = Pick<DividerOptions, 'trim'> & {
223
223
  readonly splitTLD?: boolean;
224
224
  };
225
225
  type CsvDividerOptions = Pick<DividerOptions, 'trim'> & {
226
- /** Character used for quoting values. */
226
+ /** Quote string used for quoting values. */
227
227
  readonly quoteChar?: string;
228
- /** Character used to separate CSV fields. */
228
+ /** Delimiter string used to separate CSV fields. */
229
229
  readonly delimiter?: string;
230
230
  };
231
231
  type PathDividerOptions = Pick<DividerOptions, 'trim'> & {
@@ -243,8 +243,8 @@ type QueryDividerOptions = Pick<DividerOptions, 'trim'> & {
243
243
  *
244
244
  * @param line - The CSV line string to be divided into fields
245
245
  * @param options - Configuration options for CSV parsing
246
- * @param options.delimiter - The character used to separate fields (default: ',')
247
- * @param options.quoteChar - The character used to quote fields containing delimiters or newlines (default: '"')
246
+ * @param options.delimiter - The delimiter string used to separate fields (default: ',')
247
+ * @param options.quoteChar - The quote string used to wrap fields containing delimiters or newlines (default: '"')
248
248
  * @param options.trim - Whether to trim whitespace from field values (default: false)
249
249
  * @returns A DividerStringResult containing the parsed CSV fields
250
250
  */
package/dist/index.js CHANGED
@@ -409,11 +409,7 @@ function dividerNumberString(input, options) {
409
409
  return transformDividerInput(input, divideNumberString, options);
410
410
  }
411
411
 
412
- // src/utils/quoted.ts
413
- function dividePreserve(input, separator) {
414
- if (isEmptyString(input)) return [""];
415
- return divider(input, separator, { preserveEmpty: true });
416
- }
412
+ // src/utils/count-unescaped.ts
417
413
  var countUnescapedSingleChar = (text, quote) => {
418
414
  let count = 0;
419
415
  for (let index = 0; index < text.length; index++) {
@@ -450,22 +446,14 @@ function countUnescaped(text, quote) {
450
446
  if (quote.length === 1) return countUnescapedSingleChar(text, quote);
451
447
  return countUnescapedMultiChar(text, quote);
452
448
  }
453
- function stripOuterQuotes(text, quoteChar, { lenient = true } = {}) {
454
- const escapedPair = quoteChar + quoteChar;
455
- const isWhitespace = (char) => char === WHITE_SPACE || char === TAB;
456
- const restoreEscapedQuotes = (fieldText) => fieldText.split(escapedPair).join(quoteChar);
457
- const stripped = stripOuterQuotesRaw(text, quoteChar, lenient, isWhitespace);
458
- return restoreEscapedQuotes(stripped);
459
- }
460
- function quotedDivide(line, {
461
- delimiter = ",",
462
- quote = '"',
463
- trim = false,
464
- lenient = true
465
- } = {}) {
466
- if (isEmptyString(line)) return [""];
467
- return buildQuotedFields(line, delimiter, quote, trim, lenient);
449
+
450
+ // src/utils/divide-preserve.ts
451
+ function dividePreserve(input, separator) {
452
+ if (isEmptyString(input)) return [""];
453
+ return divider(input, separator, { preserveEmpty: true });
468
454
  }
455
+
456
+ // src/utils/strip-outer-quotes.ts
469
457
  var findNonSpaceBounds = (text, isWhitespace) => {
470
458
  let left = 0;
471
459
  let right = text.length - 1;
@@ -473,44 +461,42 @@ var findNonSpaceBounds = (text, isWhitespace) => {
473
461
  while (right >= left && isWhitespace(text[right])) right--;
474
462
  return { left, right };
475
463
  };
476
- var stripMatchedOuterQuotes = (text, left, right) => text.slice(0, left) + text.slice(left + 1, right) + text.slice(right + 1);
477
- var removeCharAt = (text, index) => text.slice(0, index) + text.slice(index + 1);
478
- var stripTrailingQuote = (text, quoteChar, isWhitespace) => {
464
+ var stripMatchedOuterQuotes = (text, left, rightQuoteStart, quote) => text.slice(0, left) + text.slice(left + quote.length, rightQuoteStart) + text.slice(rightQuoteStart + quote.length);
465
+ var removeQuoteAt = (text, start, quote) => text.slice(0, start) + text.slice(start + quote.length);
466
+ var stripTrailingQuote = (text, quote, isWhitespace) => {
467
+ const quoteLength = quote.length;
479
468
  let lastNonSpaceIndex = text.length - 1;
480
469
  while (lastNonSpaceIndex >= 0 && isWhitespace(text[lastNonSpaceIndex])) {
481
470
  lastNonSpaceIndex--;
482
471
  }
483
- if (lastNonSpaceIndex < 0 || text[lastNonSpaceIndex] !== quoteChar) {
472
+ const trailingQuoteStart = lastNonSpaceIndex - quoteLength + 1;
473
+ if (trailingQuoteStart < 0 || !text.startsWith(quote, trailingQuoteStart)) {
484
474
  return text;
485
475
  }
486
- return removeCharAt(text, lastNonSpaceIndex);
476
+ return removeQuoteAt(text, trailingQuoteStart, quote);
487
477
  };
488
- var stripOuterQuotesRaw = (text, quoteChar, lenient, isWhitespace) => {
478
+ var stripOuterQuotesRaw = (text, quote, lenient, isWhitespace) => {
479
+ if (quote.length === 0) return text;
489
480
  const { left, right } = findNonSpaceBounds(text, isWhitespace);
490
481
  if (left > right) return text;
491
- if (text[left] !== quoteChar) return text;
492
- if (text[right] === quoteChar && right > left) {
493
- return stripMatchedOuterQuotes(text, left, right);
482
+ if (!text.startsWith(quote, left)) return text;
483
+ const rightQuoteStart = right - quote.length + 1;
484
+ if (rightQuoteStart >= left + quote.length && text.startsWith(quote, rightQuoteStart)) {
485
+ return stripMatchedOuterQuotes(text, left, rightQuoteStart, quote);
494
486
  }
495
487
  if (!lenient) return text;
496
- const withoutLeading = removeCharAt(text, left);
497
- return stripTrailingQuote(withoutLeading, quoteChar, isWhitespace);
498
- };
499
- var buildQuotedFields = (line, delimiter, quote, trim, lenient) => {
500
- const pieces = dividePreserve(line, delimiter);
501
- const state = {
502
- fields: [],
503
- current: "",
504
- insideQuotes: false
505
- };
506
- for (const piece of pieces) {
507
- appendPiece(state, piece, delimiter, quote, trim, lenient);
508
- }
509
- if (!isEmptyString(state.current)) {
510
- flushField(state, quote, trim, lenient);
511
- }
512
- return state.fields;
488
+ const withoutLeading = removeQuoteAt(text, left, quote);
489
+ return stripTrailingQuote(withoutLeading, quote, isWhitespace);
513
490
  };
491
+ function stripOuterQuotes(text, quoteChar, { lenient = true } = {}) {
492
+ const isWhitespace = (char) => char === WHITE_SPACE || char === TAB;
493
+ const stripped = stripOuterQuotesRaw(text, quoteChar, lenient, isWhitespace);
494
+ if (quoteChar.length === 0) return stripped;
495
+ const escapedPair = quoteChar + quoteChar;
496
+ return stripped.split(escapedPair).join(quoteChar);
497
+ }
498
+
499
+ // src/utils/quoted-parser.ts
514
500
  var advanceQuoteState = (insideQuotes, segment, quote) => {
515
501
  let nextInsideQuotes = insideQuotes;
516
502
  for (const char of segment) {
@@ -518,6 +504,13 @@ var advanceQuoteState = (insideQuotes, segment, quote) => {
518
504
  }
519
505
  return nextInsideQuotes;
520
506
  };
507
+ var flushField = (state, quote, trim, lenient) => {
508
+ let fieldValue = stripOuterQuotes(state.current, quote, { lenient });
509
+ if (trim) fieldValue = fieldValue.trim();
510
+ state.fields.push(fieldValue);
511
+ state.current = "";
512
+ state.insideQuotes = false;
513
+ };
521
514
  var appendPiece = (state, piece, delimiter, quote, trim, lenient) => {
522
515
  const segment = isEmptyString(state.current) ? piece : delimiter + piece;
523
516
  state.current += segment;
@@ -526,13 +519,30 @@ var appendPiece = (state, piece, delimiter, quote, trim, lenient) => {
526
519
  flushField(state, quote, trim, lenient);
527
520
  }
528
521
  };
529
- var flushField = (state, quote, trim, lenient) => {
530
- let fieldValue = stripOuterQuotes(state.current, quote, { lenient });
531
- if (trim) fieldValue = fieldValue.trim();
532
- state.fields.push(fieldValue);
533
- state.current = "";
534
- state.insideQuotes = false;
522
+ var buildQuotedFields = (line, delimiter, quote, trim, lenient) => {
523
+ const pieces = dividePreserve(line, delimiter);
524
+ const state = {
525
+ fields: [],
526
+ current: "",
527
+ insideQuotes: false
528
+ };
529
+ for (const piece of pieces) {
530
+ appendPiece(state, piece, delimiter, quote, trim, lenient);
531
+ }
532
+ if (!isEmptyString(state.current)) {
533
+ flushField(state, quote, trim, lenient);
534
+ }
535
+ return state.fields;
535
536
  };
537
+ function quotedDivide(line, {
538
+ delimiter = ",",
539
+ quote = '"',
540
+ trim = false,
541
+ lenient = true
542
+ } = {}) {
543
+ if (isEmptyString(line)) return [""];
544
+ return buildQuotedFields(line, delimiter, quote, trim, lenient);
545
+ }
536
546
 
537
547
  // src/presets/csv-divider.ts
538
548
  function csvDivider(line, options = {}) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nyaomaru/divider",
3
3
  "type": "module",
4
- "version": "2.0.7",
4
+ "version": "2.0.8",
5
5
  "description": "To divide string or string[] with a given separator",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",