@loaders.gl/csv 4.3.1 → 4.4.0-alpha.1
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/csv-arrow-loader.d.ts +37 -0
- package/dist/csv-arrow-loader.d.ts.map +1 -0
- package/dist/csv-arrow-loader.js +23 -0
- package/dist/csv-format.d.ts +10 -0
- package/dist/csv-format.d.ts.map +1 -0
- package/dist/csv-format.js +12 -0
- package/dist/csv-loader.d.ts +6 -6
- package/dist/csv-loader.d.ts.map +1 -1
- package/dist/csv-loader.js +53 -20
- package/dist/csv-writer.d.ts +6 -5
- package/dist/csv-writer.d.ts.map +1 -1
- package/dist/csv-writer.js +2 -5
- package/dist/dist.dev.js +13318 -449
- package/dist/dist.min.js +23 -20
- package/dist/index.cjs +317 -262
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/encoders/encode-csv.d.ts +1 -1
- package/dist/lib/encoders/encode-csv.d.ts.map +1 -1
- package/dist/lib/encoders/encode-csv.js +1 -1
- package/dist/papaparse/async-iterator-streamer.d.ts +1 -21
- package/dist/papaparse/async-iterator-streamer.d.ts.map +1 -1
- package/dist/papaparse/async-iterator-streamer.js +6 -6
- package/dist/papaparse/papa-constants.d.ts +12 -0
- package/dist/papaparse/papa-constants.d.ts.map +1 -0
- package/dist/papaparse/papa-constants.js +19 -0
- package/dist/papaparse/papa-parser.d.ts +110 -0
- package/dist/papaparse/papa-parser.d.ts.map +1 -0
- package/dist/papaparse/papa-parser.js +733 -0
- package/dist/papaparse/papa-writer.d.ts +22 -0
- package/dist/papaparse/papa-writer.d.ts.map +1 -0
- package/dist/papaparse/papa-writer.js +166 -0
- package/dist/papaparse/papaparse.d.ts +9 -113
- package/dist/papaparse/papaparse.d.ts.map +1 -1
- package/dist/papaparse/papaparse.js +13 -882
- package/package.json +5 -5
- package/src/csv-arrow-loader.ts +41 -0
- package/src/csv-format.ts +15 -0
- package/src/csv-loader.ts +58 -25
- package/src/csv-writer.ts +2 -5
- package/src/index.ts +3 -0
- package/src/lib/encoders/encode-csv.ts +2 -1
- package/src/papaparse/async-iterator-streamer.ts +6 -6
- package/src/papaparse/papa-constants.ts +23 -0
- package/src/papaparse/papa-parser.ts +872 -0
- package/src/papaparse/papa-writer.ts +219 -0
- package/src/papaparse/papaparse.ts +17 -1048
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
// Copyright (c) 2015 Matthew Holt
|
|
5
|
+
|
|
6
|
+
// This is a fork of papaparse v5.0.0-beta.0 under MIT license
|
|
7
|
+
// https://github.com/mholt/PapaParse
|
|
8
|
+
|
|
9
|
+
import {Papa} from './papa-constants';
|
|
10
|
+
|
|
11
|
+
export type CSVWriterConfig = {
|
|
12
|
+
chunk?: boolean;
|
|
13
|
+
chunkSize?: number | null;
|
|
14
|
+
preview?: number;
|
|
15
|
+
newline?: string;
|
|
16
|
+
comments?: boolean;
|
|
17
|
+
skipEmptyLines?: boolean | 'greedy';
|
|
18
|
+
delimitersToGuess?: string[];
|
|
19
|
+
quotes?: string[] | boolean;
|
|
20
|
+
quoteChar?: string;
|
|
21
|
+
escapeChar?: string;
|
|
22
|
+
delimiter?: string;
|
|
23
|
+
// Convert numbers and boolean values in rows from strings
|
|
24
|
+
fastMode?: boolean;
|
|
25
|
+
|
|
26
|
+
dynamicTyping?: boolean | {};
|
|
27
|
+
dynamicTypingFunction?: Function;
|
|
28
|
+
step?: Function;
|
|
29
|
+
transform?: Function;
|
|
30
|
+
|
|
31
|
+
header?: any;
|
|
32
|
+
columns?: any;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line complexity, max-statements
|
|
36
|
+
export function JsonToCsv(_input, _config: CSVWriterConfig = {}) {
|
|
37
|
+
// Default configuration
|
|
38
|
+
|
|
39
|
+
/** whether to surround every datum with quotes */
|
|
40
|
+
let _quotes: string[] | boolean = false;
|
|
41
|
+
|
|
42
|
+
/** whether to write headers */
|
|
43
|
+
let _writeHeader = true;
|
|
44
|
+
|
|
45
|
+
/** delimiting character(s) */
|
|
46
|
+
let _delimiter = ',';
|
|
47
|
+
|
|
48
|
+
/** newline character(s) */
|
|
49
|
+
let _newline = '\r\n';
|
|
50
|
+
|
|
51
|
+
/** quote character */
|
|
52
|
+
let _quoteChar = '"';
|
|
53
|
+
|
|
54
|
+
/** escaped quote character, either "" or <config.escapeChar>" */
|
|
55
|
+
let _escapedQuote = _quoteChar + _quoteChar;
|
|
56
|
+
|
|
57
|
+
/** whether to skip empty lines */
|
|
58
|
+
let _skipEmptyLines: 'greedy' | boolean = false;
|
|
59
|
+
|
|
60
|
+
/** the columns (keys) we expect when we unparse objects */
|
|
61
|
+
let _columns: any = null;
|
|
62
|
+
|
|
63
|
+
unpackConfig();
|
|
64
|
+
|
|
65
|
+
const quoteCharRegex = new RegExp(escapeRegExp(_quoteChar), 'g');
|
|
66
|
+
|
|
67
|
+
if (typeof _input === 'string') _input = JSON.parse(_input);
|
|
68
|
+
|
|
69
|
+
if (Array.isArray(_input)) {
|
|
70
|
+
if (!_input.length || Array.isArray(_input[0])) {
|
|
71
|
+
return serialize(null, _input, _skipEmptyLines);
|
|
72
|
+
} else if (typeof _input[0] === 'object') {
|
|
73
|
+
return serialize(_columns || Object.keys(_input[0]), _input, _skipEmptyLines);
|
|
74
|
+
}
|
|
75
|
+
} else if (typeof _input === 'object') {
|
|
76
|
+
if (typeof _input.data === 'string') {
|
|
77
|
+
_input.data = JSON.parse(_input.data);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (Array.isArray(_input.data)) {
|
|
81
|
+
if (!_input.fields) {
|
|
82
|
+
_input.fields = _input.meta && _input.meta.fields;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!_input.fields) {
|
|
86
|
+
_input.fields = Array.isArray(_input.data[0]) ? _input.fields : Object.keys(_input.data[0]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!Array.isArray(_input.data[0]) && typeof _input.data[0] !== 'object') {
|
|
90
|
+
_input.data = [_input.data]; // handles input like [1,2,3] or ['asdf']
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return serialize(_input.fields || [], _input.data || [], _skipEmptyLines);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Default (any valid paths should return before this)
|
|
98
|
+
throw new Error('Unable to serialize unrecognized input');
|
|
99
|
+
|
|
100
|
+
// eslint-disable-next-line complexity
|
|
101
|
+
function unpackConfig() {
|
|
102
|
+
if (typeof _config !== 'object') return;
|
|
103
|
+
|
|
104
|
+
if (
|
|
105
|
+
typeof _config.delimiter === 'string' &&
|
|
106
|
+
!Papa.BAD_DELIMITERS.filter(function (value) {
|
|
107
|
+
return _config.delimiter?.indexOf(value) !== -1;
|
|
108
|
+
}).length
|
|
109
|
+
) {
|
|
110
|
+
_delimiter = _config.delimiter;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (typeof _config.quotes === 'boolean' || Array.isArray(_config.quotes))
|
|
114
|
+
_quotes = _config.quotes;
|
|
115
|
+
|
|
116
|
+
if (typeof _config.skipEmptyLines === 'boolean' || _config.skipEmptyLines === 'greedy')
|
|
117
|
+
_skipEmptyLines = _config.skipEmptyLines;
|
|
118
|
+
|
|
119
|
+
if (typeof _config.newline === 'string') _newline = _config.newline;
|
|
120
|
+
|
|
121
|
+
if (typeof _config.quoteChar === 'string') _quoteChar = _config.quoteChar;
|
|
122
|
+
|
|
123
|
+
if (typeof _config.header === 'boolean') _writeHeader = _config.header;
|
|
124
|
+
|
|
125
|
+
if (Array.isArray(_config.columns)) {
|
|
126
|
+
if (_config.columns.length === 0) throw new Error('Option columns is empty');
|
|
127
|
+
|
|
128
|
+
_columns = _config.columns;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (_config.escapeChar !== undefined) {
|
|
132
|
+
_escapedQuote = _config.escapeChar + _quoteChar;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** The double for loop that iterates the data and writes out a CSV string including header row */
|
|
137
|
+
// eslint-disable-next-line complexity, max-statements
|
|
138
|
+
function serialize(fields, data, skipEmptyLines) {
|
|
139
|
+
let csv = '';
|
|
140
|
+
|
|
141
|
+
if (typeof fields === 'string') fields = JSON.parse(fields);
|
|
142
|
+
if (typeof data === 'string') data = JSON.parse(data);
|
|
143
|
+
|
|
144
|
+
const hasHeader = Array.isArray(fields) && fields.length > 0;
|
|
145
|
+
const dataKeyedByField = !Array.isArray(data[0]);
|
|
146
|
+
|
|
147
|
+
// If there a header row, write it first
|
|
148
|
+
if (hasHeader && _writeHeader) {
|
|
149
|
+
for (let i = 0; i < fields.length; i++) {
|
|
150
|
+
if (i > 0) csv += _delimiter;
|
|
151
|
+
csv += safe(fields[i], i);
|
|
152
|
+
}
|
|
153
|
+
if (data.length > 0) csv += _newline;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Then write out the data
|
|
157
|
+
for (let row = 0; row < data.length; row++) {
|
|
158
|
+
const maxCol = hasHeader ? fields.length : data[row].length;
|
|
159
|
+
|
|
160
|
+
let emptyLine = false;
|
|
161
|
+
const nullLine = hasHeader ? Object.keys(data[row]).length === 0 : data[row].length === 0;
|
|
162
|
+
if (skipEmptyLines && !hasHeader) {
|
|
163
|
+
emptyLine =
|
|
164
|
+
skipEmptyLines === 'greedy'
|
|
165
|
+
? data[row].join('').trim() === ''
|
|
166
|
+
: data[row].length === 1 && data[row][0].length === 0;
|
|
167
|
+
}
|
|
168
|
+
if (skipEmptyLines === 'greedy' && hasHeader) {
|
|
169
|
+
const line: string[] = [];
|
|
170
|
+
for (let c = 0; c < maxCol; c++) {
|
|
171
|
+
const cx = dataKeyedByField ? fields[c] : c;
|
|
172
|
+
line.push(data[row][cx]);
|
|
173
|
+
}
|
|
174
|
+
emptyLine = line.join('').trim() === '';
|
|
175
|
+
}
|
|
176
|
+
if (!emptyLine) {
|
|
177
|
+
for (let col = 0; col < maxCol; col++) {
|
|
178
|
+
if (col > 0 && !nullLine) csv += _delimiter;
|
|
179
|
+
const colIdx = hasHeader && dataKeyedByField ? fields[col] : col;
|
|
180
|
+
csv += safe(data[row][colIdx], col);
|
|
181
|
+
}
|
|
182
|
+
if (row < data.length - 1 && (!skipEmptyLines || (maxCol > 0 && !nullLine))) {
|
|
183
|
+
csv += _newline;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return csv;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Encloses a value around quotes if needed (makes a value safe for CSV insertion) */
|
|
191
|
+
// eslint-disable-next-line complexity
|
|
192
|
+
function safe(str, col) {
|
|
193
|
+
if (typeof str === 'undefined' || str === null) return '';
|
|
194
|
+
|
|
195
|
+
if (str.constructor === Date) return JSON.stringify(str).slice(1, 25);
|
|
196
|
+
|
|
197
|
+
str = str.toString().replace(quoteCharRegex, _escapedQuote);
|
|
198
|
+
|
|
199
|
+
const needsQuotes =
|
|
200
|
+
(typeof _quotes === 'boolean' && _quotes) ||
|
|
201
|
+
(Array.isArray(_quotes) && _quotes[col]) ||
|
|
202
|
+
hasAny(str, Papa.BAD_DELIMITERS) ||
|
|
203
|
+
str.indexOf(_delimiter) > -1 ||
|
|
204
|
+
str.charAt(0) === ' ' ||
|
|
205
|
+
str.charAt(str.length - 1) === ' ';
|
|
206
|
+
|
|
207
|
+
return needsQuotes ? _quoteChar + str + _quoteChar : str;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function hasAny(str, substrings) {
|
|
211
|
+
for (let i = 0; i < substrings.length; i++) if (str.indexOf(substrings[i]) > -1) return true;
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions */
|
|
217
|
+
function escapeRegExp(string) {
|
|
218
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
219
|
+
}
|