@dynamic-entity/server 2.1.1 → 2.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/README.md +12 -1
- package/express.d.mts +1 -1
- package/express.d.ts +1 -1
- package/express.js +48 -21
- package/express.js.map +1 -1
- package/express.mjs +49 -22
- package/express.mjs.map +1 -1
- package/index.d.mts +4 -22
- package/index.d.ts +4 -22
- package/index.js +51 -23
- package/index.js.map +1 -1
- package/index.mjs +49 -23
- package/index.mjs.map +1 -1
- package/package.json +2 -2
- package/{write-template-C2dCEp48.d.mts → write-template-B6KIIBRw.d.mts} +12 -1
- package/{write-template-C2dCEp48.d.ts → write-template-B6KIIBRw.d.ts} +12 -1
package/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { padRow, cellText, decimalMarkFor, arrayBoundFor, deriveImportColumns, suggestMapping, toCsv, escapeFormula, applyMapping, completeFirstLine, validateMappingPlan, detectDelimiter, createCsvReader } from '@dynamic-entity/core';
|
|
2
|
+
export { cellText as sampleText } from '@dynamic-entity/core';
|
|
1
3
|
import zlib from 'zlib';
|
|
2
4
|
import ExcelJS from 'exceljs';
|
|
3
5
|
import { Readable } from 'stream';
|
|
4
|
-
import { padRow, deriveImportColumns, suggestMapping, toCsv, escapeFormula, applyMapping, createCsvReader, validateMappingPlan } from '@dynamic-entity/core';
|
|
5
6
|
|
|
6
7
|
// src/limits.ts
|
|
7
8
|
var DEFAULT_LIMITS = {
|
|
@@ -133,17 +134,6 @@ function destroySource(source) {
|
|
|
133
134
|
} catch {
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
-
// src/cell-text.ts
|
|
138
|
-
function sampleText(raw) {
|
|
139
|
-
if (raw === null || raw === void 0) return "";
|
|
140
|
-
if (raw instanceof Date) {
|
|
141
|
-
if (Number.isNaN(raw.getTime())) return "";
|
|
142
|
-
const iso = raw.toISOString();
|
|
143
|
-
return raw.getTime() % 864e5 === 0 ? iso.slice(0, 10) : iso;
|
|
144
|
-
}
|
|
145
|
-
return typeof raw === "string" ? raw : String(raw);
|
|
146
|
-
}
|
|
147
137
|
var LOCAL_HEADER = 67324752;
|
|
148
138
|
var CENTRAL_HEADER = 33639248;
|
|
149
139
|
var END_OF_CENTRAL = 101010256;
|
|
@@ -460,6 +450,12 @@ async function guardZip(source, limits) {
|
|
|
460
450
|
}
|
|
461
451
|
}
|
|
462
452
|
if (!sheet) {
|
|
453
|
+
if (!kept.has("xl/workbook.xml")) {
|
|
454
|
+
throw new ImportError(
|
|
455
|
+
"UNSUPPORTED_FORMAT",
|
|
456
|
+
"This is a zip archive that is not an Excel workbook. Upload an .xlsx or .csv file."
|
|
457
|
+
);
|
|
458
|
+
}
|
|
463
459
|
throw new ImportError("MALFORMED_FILE", "This workbook has no worksheet.");
|
|
464
460
|
}
|
|
465
461
|
const ordered = [...WANTED, sheet.name].map((wanted) => kept.get(wanted)).filter((entry) => entry !== void 0);
|
|
@@ -550,13 +546,36 @@ function detectFormat(head) {
|
|
|
550
546
|
}
|
|
551
547
|
return "csv";
|
|
552
548
|
}
|
|
553
|
-
async function* csvRows(stream) {
|
|
549
|
+
async function* csvRows(stream, limits, found) {
|
|
554
550
|
const decoder = new TextDecoder("utf-8");
|
|
555
|
-
const
|
|
551
|
+
const maxHeader = limits.maxCellLength * limits.maxColumns + limits.maxColumns;
|
|
552
|
+
let held = "";
|
|
553
|
+
let reader = null;
|
|
554
|
+
const open = (headerLine) => {
|
|
555
|
+
found.delimiter = detectDelimiter(headerLine);
|
|
556
|
+
return createCsvReader({ delimiter: found.delimiter });
|
|
557
|
+
};
|
|
556
558
|
for await (const chunk of stream) {
|
|
557
|
-
|
|
559
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
560
|
+
if (!reader) {
|
|
561
|
+
held += text;
|
|
562
|
+
const line = completeFirstLine(held);
|
|
563
|
+
if (line === null) {
|
|
564
|
+
if (held.length > maxHeader) {
|
|
565
|
+
throw new ImportError("SHEET_TOO_LARGE", "The header row is longer than any row may be.");
|
|
566
|
+
}
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
reader = open(line);
|
|
570
|
+
for (const row of reader.push(held)) yield row;
|
|
571
|
+
held = "";
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
for (const row of reader.push(text)) yield row;
|
|
558
575
|
}
|
|
559
|
-
|
|
576
|
+
const rest = held + decoder.decode();
|
|
577
|
+
reader ??= open(completeFirstLine(rest) ?? rest);
|
|
578
|
+
for (const row of reader.push(rest)) yield row;
|
|
560
579
|
for (const row of reader.end()) yield row;
|
|
561
580
|
}
|
|
562
581
|
async function* guardRows(rows, width, limits) {
|
|
@@ -591,10 +610,11 @@ async function readSheet(options) {
|
|
|
591
610
|
const counted = limitBytes(toByteStream(options.stream), limits.maxBytes);
|
|
592
611
|
const { head, stream } = await peek(counted, MAGIC_BYTES);
|
|
593
612
|
const format = detectFormat(head);
|
|
594
|
-
const
|
|
613
|
+
const found = {};
|
|
614
|
+
const rows = format === "xlsx" ? xlsxRows(stream, limits) : csvRows(stream, limits, found);
|
|
595
615
|
const iterator = rows[Symbol.asyncIterator]();
|
|
596
616
|
const first = await iterator.next();
|
|
597
|
-
const headers = first.done ? [] : first.value.map(
|
|
617
|
+
const headers = first.done ? [] : first.value.map(cellText);
|
|
598
618
|
if (headers.length > limits.maxColumns) {
|
|
599
619
|
throw new ImportError(
|
|
600
620
|
"SHEET_TOO_LARGE",
|
|
@@ -605,7 +625,8 @@ async function readSheet(options) {
|
|
|
605
625
|
return {
|
|
606
626
|
format,
|
|
607
627
|
headers,
|
|
608
|
-
rows: closing(guardRows(remaining, headers.length, limits), options.stream)
|
|
628
|
+
rows: closing(guardRows(remaining, headers.length, limits), options.stream),
|
|
629
|
+
...found.delimiter ? { delimiter: found.delimiter } : {}
|
|
609
630
|
};
|
|
610
631
|
} catch (error) {
|
|
611
632
|
destroySource(options.stream);
|
|
@@ -657,6 +678,7 @@ async function runImport(options) {
|
|
|
657
678
|
filename: options.filename,
|
|
658
679
|
limits
|
|
659
680
|
});
|
|
681
|
+
const decimal = options.decimal ?? decimalMarkFor(sheet.delimiter);
|
|
660
682
|
const errors = [];
|
|
661
683
|
let errorCount = 0;
|
|
662
684
|
let imported = 0;
|
|
@@ -672,6 +694,7 @@ async function runImport(options) {
|
|
|
672
694
|
batch = [];
|
|
673
695
|
const result = applyMapping(rows, plan, config, {
|
|
674
696
|
lang: options.lang,
|
|
697
|
+
decimal,
|
|
675
698
|
rules: options.rules,
|
|
676
699
|
lookups: options.lookups,
|
|
677
700
|
firstRowNumber: firstRow
|
|
@@ -734,19 +757,22 @@ async function previewSheet(options) {
|
|
|
734
757
|
try {
|
|
735
758
|
for await (const row of sheet.rows) {
|
|
736
759
|
rowCount++;
|
|
737
|
-
if (sample.length < limits.sampleRows) sample.push(row.map(
|
|
760
|
+
if (sample.length < limits.sampleRows) sample.push(row.map(cellText));
|
|
738
761
|
}
|
|
739
762
|
} catch (error) {
|
|
740
763
|
destroySource(options.stream);
|
|
741
764
|
throw error;
|
|
742
765
|
}
|
|
743
|
-
const
|
|
766
|
+
const arrayBound = arrayBoundFor(sheet.headers, options.config, null, options.lang);
|
|
767
|
+
const { columns } = deriveImportColumns(options.config, { lang: options.lang, maxArrayRows: arrayBound });
|
|
744
768
|
return {
|
|
745
769
|
headers: sheet.headers,
|
|
746
770
|
sample,
|
|
747
771
|
rowCount,
|
|
748
772
|
suggestion: suggestMapping(sheet.headers, columns, options.config?.entity ?? ""),
|
|
749
|
-
format: sheet.format
|
|
773
|
+
format: sheet.format,
|
|
774
|
+
...sheet.delimiter ? { delimiter: sheet.delimiter } : {},
|
|
775
|
+
arrayBound
|
|
750
776
|
};
|
|
751
777
|
}
|
|
752
778
|
var TEMPLATE_EXTENSION = { csv: "csv", xlsx: "xlsx" };
|
|
@@ -795,6 +821,6 @@ function sheetName(name) {
|
|
|
795
821
|
return (cleaned || "Import").slice(0, 31);
|
|
796
822
|
}
|
|
797
823
|
|
|
798
|
-
export { DEFAULT_LIMITS, ImportError, TEMPLATE_EXTENSION, TEMPLATE_MEDIA_TYPE, cellValue, destroySource, detectFormat, guardRows, guardZip, limitBytes, peek, previewSheet, readSheet, resolveLimits, runImport,
|
|
824
|
+
export { DEFAULT_LIMITS, ImportError, TEMPLATE_EXTENSION, TEMPLATE_MEDIA_TYPE, cellValue, destroySource, detectFormat, guardRows, guardZip, limitBytes, peek, previewSheet, readSheet, resolveLimits, runImport, toByteStream, toErrorBody, writeTemplate, xlsxRows };
|
|
799
825
|
//# sourceMappingURL=index.mjs.map
|
|
800
826
|
//# sourceMappingURL=index.mjs.map
|