@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 +62 -52
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +62 -52
- package/package.json +1 -1
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/
|
|
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
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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,
|
|
511
|
-
var
|
|
512
|
-
var stripTrailingQuote = (text,
|
|
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
|
-
|
|
506
|
+
const trailingQuoteStart = lastNonSpaceIndex - quoteLength + 1;
|
|
507
|
+
if (trailingQuoteStart < 0 || !text.startsWith(quote, trailingQuoteStart)) {
|
|
518
508
|
return text;
|
|
519
509
|
}
|
|
520
|
-
return
|
|
510
|
+
return removeQuoteAt(text, trailingQuoteStart, quote);
|
|
521
511
|
};
|
|
522
|
-
var stripOuterQuotesRaw = (text,
|
|
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
|
|
526
|
-
|
|
527
|
-
|
|
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 =
|
|
531
|
-
return stripTrailingQuote(withoutLeading,
|
|
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
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
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
|
-
/**
|
|
226
|
+
/** Quote string used for quoting values. */
|
|
227
227
|
readonly quoteChar?: string;
|
|
228
|
-
/**
|
|
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
|
|
247
|
-
* @param options.quoteChar - The
|
|
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
|
-
/**
|
|
226
|
+
/** Quote string used for quoting values. */
|
|
227
227
|
readonly quoteChar?: string;
|
|
228
|
-
/**
|
|
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
|
|
247
|
-
* @param options.quoteChar - The
|
|
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/
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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,
|
|
477
|
-
var
|
|
478
|
-
var stripTrailingQuote = (text,
|
|
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
|
-
|
|
472
|
+
const trailingQuoteStart = lastNonSpaceIndex - quoteLength + 1;
|
|
473
|
+
if (trailingQuoteStart < 0 || !text.startsWith(quote, trailingQuoteStart)) {
|
|
484
474
|
return text;
|
|
485
475
|
}
|
|
486
|
-
return
|
|
476
|
+
return removeQuoteAt(text, trailingQuoteStart, quote);
|
|
487
477
|
};
|
|
488
|
-
var stripOuterQuotesRaw = (text,
|
|
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
|
|
492
|
-
|
|
493
|
-
|
|
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 =
|
|
497
|
-
return stripTrailingQuote(withoutLeading,
|
|
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
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
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 = {}) {
|