@nshiab/simple-data-analysis-core 2.0.5 → 2.0.6
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 +118 -12
- package/esm/class/Simple.d.ts +8 -2
- package/esm/class/Simple.d.ts.map +1 -1
- package/esm/class/Simple.js +9 -3
- package/esm/class/SimpleDB.d.ts +72 -1
- package/esm/class/SimpleDB.d.ts.map +1 -1
- package/esm/class/SimpleDB.js +81 -1
- package/esm/class/SimpleTable.d.ts +251 -274
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +248 -325
- package/esm/helpers/LogValue.d.ts +8 -0
- package/esm/helpers/LogValue.d.ts.map +1 -0
- package/esm/helpers/LogValue.js +23 -0
- package/esm/helpers/cacheTableDependencies.d.ts +9 -0
- package/esm/helpers/cacheTableDependencies.d.ts.map +1 -1
- package/esm/helpers/cacheTableDependencies.js +131 -21
- package/esm/helpers/cleanSQL.d.ts +1 -1
- package/esm/helpers/cleanSQL.d.ts.map +1 -1
- package/esm/helpers/cleanSQL.js +268 -23
- package/esm/helpers/flushAllTables.d.ts.map +1 -1
- package/esm/helpers/flushAllTables.js +23 -28
- package/esm/helpers/foldIdentifier.d.ts +3 -0
- package/esm/helpers/foldIdentifier.d.ts.map +1 -0
- package/esm/helpers/foldIdentifier.js +4 -0
- package/esm/helpers/geometryFromJSON.d.ts +3 -0
- package/esm/helpers/geometryFromJSON.d.ts.map +1 -0
- package/esm/helpers/geometryFromJSON.js +4 -0
- package/esm/helpers/index.d.ts +1 -0
- package/esm/helpers/index.d.ts.map +1 -1
- package/esm/helpers/index.js +1 -0
- package/esm/helpers/logData.d.ts.map +1 -1
- package/esm/helpers/logData.js +45 -44
- package/esm/helpers/makeLogConverter.d.ts +5 -0
- package/esm/helpers/makeLogConverter.d.ts.map +1 -0
- package/esm/helpers/makeLogConverter.js +64 -0
- package/esm/helpers/osmFiles.d.ts.map +1 -1
- package/esm/helpers/parseTypes.d.ts +1 -1
- package/esm/helpers/parseTypes.d.ts.map +1 -1
- package/esm/helpers/parseTypes.js +4 -0
- package/esm/helpers/pendingOps.d.ts +4 -2
- package/esm/helpers/pendingOps.d.ts.map +1 -1
- package/esm/helpers/prepareGeometry.d.ts +3 -0
- package/esm/helpers/prepareGeometry.d.ts.map +1 -0
- package/esm/helpers/prepareGeometry.js +99 -0
- package/esm/helpers/prepareJSON.d.ts +3 -0
- package/esm/helpers/prepareJSON.d.ts.map +1 -0
- package/esm/helpers/prepareJSON.js +50 -0
- package/esm/helpers/printTable.d.ts +5 -4
- package/esm/helpers/printTable.d.ts.map +1 -1
- package/esm/helpers/printTable.js +32 -36
- package/esm/helpers/queryDB.js +1 -1
- package/esm/helpers/queueAsyncBarrier.d.ts +4 -0
- package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/esm/helpers/queueAsyncBarrier.js +4 -0
- package/esm/helpers/queueOp.d.ts.map +1 -1
- package/esm/helpers/queueOp.js +5 -3
- package/esm/helpers/readMutationRows.d.ts +9 -0
- package/esm/helpers/readMutationRows.d.ts.map +1 -0
- package/esm/helpers/readMutationRows.js +94 -0
- package/esm/helpers/referencedTables.d.ts +9 -0
- package/esm/helpers/referencedTables.d.ts.map +1 -0
- package/esm/helpers/referencedTables.js +22 -0
- package/esm/helpers/runQuery.d.ts.map +1 -1
- package/esm/helpers/runQuery.js +11 -13
- package/esm/helpers/scanSQL.d.ts +7 -0
- package/esm/helpers/scanSQL.d.ts.map +1 -0
- package/esm/helpers/scanSQL.js +71 -0
- package/esm/helpers/tableRegistry.d.ts +2 -0
- package/esm/helpers/tableRegistry.d.ts.map +1 -1
- package/esm/helpers/tableRegistry.js +12 -4
- package/esm/helpers/updateColumnsWithJS.d.ts +52 -0
- package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -0
- package/esm/helpers/updateColumnsWithJS.js +139 -0
- package/esm/methods/addColumn.d.ts +1 -1
- package/esm/methods/addColumn.d.ts.map +1 -1
- package/esm/methods/bm25.d.ts.map +1 -1
- package/esm/methods/bm25.js +1 -2
- package/esm/methods/cache.d.ts.map +1 -1
- package/esm/methods/cache.js +4 -6
- package/esm/methods/convert.d.ts +2 -2
- package/esm/methods/convert.d.ts.map +1 -1
- package/esm/methods/convert.js +5 -0
- package/esm/methods/getBottom.d.ts +1 -1
- package/esm/methods/getBottom.d.ts.map +1 -1
- package/esm/methods/getBottom.js +2 -2
- package/esm/methods/getData.d.ts +1 -1
- package/esm/methods/getData.d.ts.map +1 -1
- package/esm/methods/getData.js +2 -2
- package/esm/methods/join.d.ts.map +1 -1
- package/esm/methods/join.js +8 -16
- package/esm/methods/joinGeo.d.ts.map +1 -1
- package/esm/methods/joinGeo.js +10 -19
- package/esm/methods/loadArray.d.ts +1 -1
- package/esm/methods/loadArray.d.ts.map +1 -1
- package/esm/methods/loadArray.js +74 -19
- package/esm/methods/loadData.js +3 -0
- package/esm/methods/log.d.ts +7 -0
- package/esm/methods/log.d.ts.map +1 -0
- package/esm/methods/log.js +58 -0
- package/esm/methods/logBottom.d.ts +5 -0
- package/esm/methods/logBottom.d.ts.map +1 -0
- package/esm/methods/logBottom.js +9 -0
- package/esm/methods/removeTable.d.ts.map +1 -1
- package/esm/methods/removeTable.js +2 -0
- package/esm/methods/removeTables.d.ts.map +1 -1
- package/esm/methods/removeTables.js +7 -0
- package/esm/methods/renameTable.d.ts.map +1 -1
- package/esm/methods/renameTable.js +4 -0
- package/esm/methods/rowToText.js +2 -2
- package/esm/methods/selectTables.d.ts.map +1 -1
- package/esm/methods/selectTables.js +6 -0
- package/esm/methods/setTypes.d.ts +1 -1
- package/esm/methods/setTypes.d.ts.map +1 -1
- package/esm/methods/stream.d.ts.map +1 -1
- package/esm/methods/stream.js +2 -1
- package/esm/methods/updateWithJS.d.ts +1 -3
- package/esm/methods/updateWithJS.d.ts.map +1 -1
- package/esm/methods/updateWithJS.js +123 -37
- package/llm.md +337 -444
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/Simple.d.ts +8 -2
- package/script/class/Simple.d.ts.map +1 -1
- package/script/class/Simple.js +9 -3
- package/script/class/SimpleDB.d.ts +72 -1
- package/script/class/SimpleDB.d.ts.map +1 -1
- package/script/class/SimpleDB.js +81 -1
- package/script/class/SimpleTable.d.ts +251 -274
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +248 -325
- package/script/helpers/LogValue.d.ts +8 -0
- package/script/helpers/LogValue.d.ts.map +1 -0
- package/script/helpers/LogValue.js +26 -0
- package/script/helpers/cacheTableDependencies.d.ts +9 -0
- package/script/helpers/cacheTableDependencies.d.ts.map +1 -1
- package/script/helpers/cacheTableDependencies.js +170 -20
- package/script/helpers/cleanSQL.d.ts +1 -1
- package/script/helpers/cleanSQL.d.ts.map +1 -1
- package/script/helpers/cleanSQL.js +271 -23
- package/script/helpers/flushAllTables.d.ts.map +1 -1
- package/script/helpers/flushAllTables.js +24 -29
- package/script/helpers/foldIdentifier.d.ts +3 -0
- package/script/helpers/foldIdentifier.d.ts.map +1 -0
- package/script/helpers/foldIdentifier.js +7 -0
- package/script/helpers/geometryFromJSON.d.ts +3 -0
- package/script/helpers/geometryFromJSON.d.ts.map +1 -0
- package/script/helpers/geometryFromJSON.js +7 -0
- package/script/helpers/index.d.ts +1 -0
- package/script/helpers/index.d.ts.map +1 -1
- package/script/helpers/index.js +3 -1
- package/script/helpers/logData.d.ts.map +1 -1
- package/script/helpers/logData.js +45 -44
- package/script/helpers/makeLogConverter.d.ts +5 -0
- package/script/helpers/makeLogConverter.d.ts.map +1 -0
- package/script/helpers/makeLogConverter.js +70 -0
- package/script/helpers/osmFiles.d.ts.map +1 -1
- package/script/helpers/parseTypes.d.ts +1 -1
- package/script/helpers/parseTypes.d.ts.map +1 -1
- package/script/helpers/parseTypes.js +4 -0
- package/script/helpers/pendingOps.d.ts +4 -2
- package/script/helpers/pendingOps.d.ts.map +1 -1
- package/script/helpers/prepareGeometry.d.ts +3 -0
- package/script/helpers/prepareGeometry.d.ts.map +1 -0
- package/script/helpers/prepareGeometry.js +102 -0
- package/script/helpers/prepareJSON.d.ts +3 -0
- package/script/helpers/prepareJSON.d.ts.map +1 -0
- package/script/helpers/prepareJSON.js +53 -0
- package/script/helpers/printTable.d.ts +5 -4
- package/script/helpers/printTable.d.ts.map +1 -1
- package/script/helpers/printTable.js +32 -36
- package/script/helpers/queryDB.js +1 -1
- package/script/helpers/queueAsyncBarrier.d.ts +4 -0
- package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/script/helpers/queueAsyncBarrier.js +4 -0
- package/script/helpers/queueOp.d.ts.map +1 -1
- package/script/helpers/queueOp.js +4 -2
- package/script/helpers/readMutationRows.d.ts +9 -0
- package/script/helpers/readMutationRows.d.ts.map +1 -0
- package/script/helpers/readMutationRows.js +97 -0
- package/script/helpers/referencedTables.d.ts +9 -0
- package/script/helpers/referencedTables.d.ts.map +1 -0
- package/script/helpers/referencedTables.js +28 -0
- package/script/helpers/runQuery.d.ts.map +1 -1
- package/script/helpers/runQuery.js +11 -13
- package/script/helpers/scanSQL.d.ts +7 -0
- package/script/helpers/scanSQL.d.ts.map +1 -0
- package/script/helpers/scanSQL.js +74 -0
- package/script/helpers/tableRegistry.d.ts +2 -0
- package/script/helpers/tableRegistry.d.ts.map +1 -1
- package/script/helpers/tableRegistry.js +16 -4
- package/script/helpers/updateColumnsWithJS.d.ts +52 -0
- package/script/helpers/updateColumnsWithJS.d.ts.map +1 -0
- package/script/helpers/updateColumnsWithJS.js +145 -0
- package/script/methods/addColumn.d.ts +1 -1
- package/script/methods/addColumn.d.ts.map +1 -1
- package/script/methods/bm25.d.ts.map +1 -1
- package/script/methods/bm25.js +1 -2
- package/script/methods/cache.d.ts.map +1 -1
- package/script/methods/cache.js +3 -5
- package/script/methods/convert.d.ts +2 -2
- package/script/methods/convert.d.ts.map +1 -1
- package/script/methods/convert.js +5 -0
- package/script/methods/getBottom.d.ts +1 -1
- package/script/methods/getBottom.d.ts.map +1 -1
- package/script/methods/getBottom.js +2 -2
- package/script/methods/getData.d.ts +1 -1
- package/script/methods/getData.d.ts.map +1 -1
- package/script/methods/getData.js +2 -2
- package/script/methods/join.d.ts.map +1 -1
- package/script/methods/join.js +8 -16
- package/script/methods/joinGeo.d.ts.map +1 -1
- package/script/methods/joinGeo.js +10 -19
- package/script/methods/loadArray.d.ts +1 -1
- package/script/methods/loadArray.d.ts.map +1 -1
- package/script/methods/loadArray.js +74 -19
- package/script/methods/loadData.js +3 -0
- package/script/methods/log.d.ts +7 -0
- package/script/methods/log.d.ts.map +1 -0
- package/script/methods/log.js +64 -0
- package/script/methods/logBottom.d.ts +5 -0
- package/script/methods/logBottom.d.ts.map +1 -0
- package/script/methods/logBottom.js +15 -0
- package/script/methods/removeTable.d.ts.map +1 -1
- package/script/methods/removeTable.js +2 -0
- package/script/methods/removeTables.d.ts.map +1 -1
- package/script/methods/removeTables.js +7 -0
- package/script/methods/renameTable.d.ts.map +1 -1
- package/script/methods/renameTable.js +4 -0
- package/script/methods/rowToText.js +2 -2
- package/script/methods/selectTables.d.ts.map +1 -1
- package/script/methods/selectTables.js +6 -0
- package/script/methods/setTypes.d.ts +1 -1
- package/script/methods/setTypes.d.ts.map +1 -1
- package/script/methods/stream.d.ts.map +1 -1
- package/script/methods/stream.js +2 -1
- package/script/methods/updateWithJS.d.ts +1 -3
- package/script/methods/updateWithJS.d.ts.map +1 -1
- package/script/methods/updateWithJS.js +122 -36
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import cleanSQL from "./cleanSQL.js";
|
|
3
|
+
import referencedTables from "./referencedTables.js";
|
|
3
4
|
import ensureSpatial from "./ensureSpatial.js";
|
|
4
5
|
import extractTypes from "./extractTypes.js";
|
|
5
6
|
import mergeOptions from "./mergeOptions.js";
|
|
@@ -141,7 +142,7 @@ async function replayEntries(sdb, pendingEntries) {
|
|
|
141
142
|
const reads = op.rawSQL === undefined
|
|
142
143
|
? []
|
|
143
144
|
: referencedTables(op.rawSQL, sdb);
|
|
144
|
-
if (reads.includes(table)) {
|
|
145
|
+
if (op.kind === "fusable" && reads.includes(table)) {
|
|
145
146
|
// User-supplied SQL referencing the operation's own table must read
|
|
146
147
|
// the state produced by the previous steps, which a fused chain
|
|
147
148
|
// can't provide (the name would resolve to the pre-chain table). So
|
|
@@ -177,7 +178,8 @@ async function replayEntries(sdb, pendingEntries) {
|
|
|
177
178
|
if (op.kind === "source") {
|
|
178
179
|
// A source replaces the target table from an external relation. It
|
|
179
180
|
// starts a new segment rather than consuming any segment already open
|
|
180
|
-
// on the same table.
|
|
181
|
+
// on the same table. A source may read that materialized table itself
|
|
182
|
+
// (for example, an in-place join) and still fuse with downstream steps.
|
|
181
183
|
await runOpenSegment();
|
|
182
184
|
open = { table, ops: [op] };
|
|
183
185
|
current = null;
|
|
@@ -256,23 +258,6 @@ async function drainAsyncOperationFrame(frame) {
|
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Returns the tables of the database whose names appear in the given SQL
|
|
261
|
-
* fragments. Matching is conservative (a column sharing a table's name
|
|
262
|
-
* counts as a reference): a false positive only costs fusion, never
|
|
263
|
-
* correctness.
|
|
264
|
-
*/
|
|
265
|
-
function referencedTables(rawSQL, sdb) {
|
|
266
|
-
const referenced = [];
|
|
267
|
-
for (const table of getRegisteredTables(sdb)) {
|
|
268
|
-
const escaped = table.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
269
|
-
const pattern = new RegExp(`(?<![\\w"])"?${escaped}"?(?![\\w"])`, "i");
|
|
270
|
-
if (rawSQL.some((sql) => pattern.test(sql))) {
|
|
271
|
-
referenced.push(table);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return referenced;
|
|
275
|
-
}
|
|
276
261
|
async function runSegment(table, ops) {
|
|
277
262
|
if (ops.length === 1) {
|
|
278
263
|
await runStepwise(table, ops[0]);
|
|
@@ -281,8 +266,7 @@ async function runSegment(table, ops) {
|
|
|
281
266
|
if (ops.some(needsSpatial)) {
|
|
282
267
|
await ensureSpatial(table);
|
|
283
268
|
}
|
|
284
|
-
//
|
|
285
|
-
// cross fragment boundaries once they are composed into one statement.
|
|
269
|
+
// Normalize each fragment once using the database syntax before composition.
|
|
286
270
|
const ctes = [];
|
|
287
271
|
// The schema of the next fragment's input, reused while operations declare
|
|
288
272
|
// they preserve it, so a run of same-shape steps costs at most one
|
|
@@ -309,11 +293,21 @@ async function runSegment(table, ops) {
|
|
|
309
293
|
await executeFused(table, ops, ctes);
|
|
310
294
|
}
|
|
311
295
|
async function compileOp(table, op, ctes, schema) {
|
|
296
|
+
// Source relations can read tables named s1, s2, etc. A generated CTE must
|
|
297
|
+
// not shadow those physical inputs, including in later chain fragments.
|
|
298
|
+
const usedNames = new Set([
|
|
299
|
+
...getRegisteredTables(table.sdb).map((input) => input.name.toLowerCase()),
|
|
300
|
+
...ctes.map((cte) => cte.alias),
|
|
301
|
+
]);
|
|
302
|
+
let aliasIndex = ctes.length + 1;
|
|
303
|
+
while (usedNames.has(`s${aliasIndex}`))
|
|
304
|
+
aliasIndex++;
|
|
305
|
+
const alias = `s${aliasIndex}`;
|
|
312
306
|
if (op.kind === "source") {
|
|
313
307
|
return {
|
|
314
308
|
cte: {
|
|
315
|
-
alias
|
|
316
|
-
select: cleanSQL(op.buildSelect()),
|
|
309
|
+
alias,
|
|
310
|
+
select: cleanSQL(await op.buildSelect(), table.sdb.expressionSyntax),
|
|
317
311
|
values: [],
|
|
318
312
|
},
|
|
319
313
|
schema: op.schema ?? null,
|
|
@@ -335,15 +329,16 @@ async function compileOp(table, op, ctes, schema) {
|
|
|
335
329
|
: null;
|
|
336
330
|
return {
|
|
337
331
|
cte: {
|
|
338
|
-
alias
|
|
339
|
-
select: cleanSQL(op.buildSelect(input, buildSchema)),
|
|
332
|
+
alias,
|
|
333
|
+
select: cleanSQL(op.buildSelect(input, buildSchema), table.sdb.expressionSyntax),
|
|
340
334
|
values: resolveValues(op, buildSchema),
|
|
341
335
|
},
|
|
342
336
|
schema: outputSchema,
|
|
343
337
|
};
|
|
344
338
|
}
|
|
345
339
|
async function executeFused(table, ops, ctes) {
|
|
346
|
-
|
|
340
|
+
// A trailing line comment must end before the generated CTE delimiter.
|
|
341
|
+
const query = `CREATE OR REPLACE TABLE ${quoteIdentifier(table.name)} AS WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select}\n)`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
|
|
347
342
|
try {
|
|
348
343
|
await queryDB(table, query, mergeOptions(table, {
|
|
349
344
|
table: table.name,
|
|
@@ -381,7 +376,7 @@ async function runStepwise(table, op) {
|
|
|
381
376
|
}));
|
|
382
377
|
}
|
|
383
378
|
function needsSpatial(op) {
|
|
384
|
-
return op.
|
|
379
|
+
return op.needsSpatial === true;
|
|
385
380
|
}
|
|
386
381
|
function resolveValues(op, schema) {
|
|
387
382
|
return typeof op.values === "function" ? op.values(schema) : op.values ?? [];
|
|
@@ -394,7 +389,7 @@ function resolveValues(op, schema) {
|
|
|
394
389
|
async function describeChain(table, ctes) {
|
|
395
390
|
const select = ctes.length === 0
|
|
396
391
|
? `SELECT * FROM ${quoteIdentifier(table.name)}`
|
|
397
|
-
: `WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select})`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
|
|
392
|
+
: `WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select}\n)`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
|
|
398
393
|
const query = ctes.length === 0
|
|
399
394
|
? `DESCRIBE ${quoteIdentifier(table.name)}`
|
|
400
395
|
: `DESCRIBE ${select}`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foldIdentifier.d.ts","sourceRoot":"","sources":["../../src/helpers/foldIdentifier.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometryFromJSON.d.ts","sourceRoot":"","sources":["../../src/helpers/geometryFromJSON.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnE"}
|
package/esm/helpers/index.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export { default as queryDB } from "./queryDB.js";
|
|
|
20
20
|
export { default as queueAsyncBarrier } from "./queueAsyncBarrier.js";
|
|
21
21
|
export { default as quoteIdentifier } from "./quoteIdentifier.js";
|
|
22
22
|
export { default as stringToArray } from "./stringToArray.js";
|
|
23
|
+
export { default as updateColumnsWithJS } from "./updateColumnsWithJS.js";
|
|
23
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/esm/helpers/index.js
CHANGED
|
@@ -20,3 +20,4 @@ export { default as queryDB } from "./queryDB.js";
|
|
|
20
20
|
export { default as queueAsyncBarrier } from "./queueAsyncBarrier.js";
|
|
21
21
|
export { default as quoteIdentifier } from "./quoteIdentifier.js";
|
|
22
22
|
export { default as stringToArray } from "./stringToArray.js";
|
|
23
|
+
export { default as updateColumnsWithJS } from "./updateColumnsWithJS.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logData.d.ts","sourceRoot":"","sources":["../../src/helpers/logData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logData.d.ts","sourceRoot":"","sources":["../../src/helpers/logData.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,IAAI,EACvC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,GAAG,IAAI,EACzC,UAAU,CAAC,EAAE,MAAM,QAkEpB"}
|
package/esm/helpers/logData.js
CHANGED
|
@@ -1,53 +1,54 @@
|
|
|
1
|
+
import LogValue from "./LogValue.js";
|
|
1
2
|
import printTable from "./printTable.js";
|
|
2
3
|
export default function logData(types, data, charsToLog) {
|
|
3
4
|
if (data === null) {
|
|
4
5
|
console.log("Data is null");
|
|
6
|
+
return;
|
|
5
7
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
if (data.length === 0) {
|
|
9
|
+
console.log(data);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const formatted = data.map((row) => Object.fromEntries(Object.entries(row).map(([key, value]) => {
|
|
13
|
+
const nested = value !== null && typeof value === "object" &&
|
|
14
|
+
!(value instanceof Date) && !(value instanceof LogValue);
|
|
15
|
+
let text = value instanceof LogValue
|
|
16
|
+
? value.text
|
|
17
|
+
: nested
|
|
18
|
+
? JSON.stringify(value)
|
|
19
|
+
: value;
|
|
20
|
+
const truncatable = !(value instanceof LogValue) ||
|
|
21
|
+
value.category === "string";
|
|
22
|
+
if (truncatable && typeof text === "string" &&
|
|
23
|
+
typeof charsToLog === "number" && text.length > charsToLog) {
|
|
24
|
+
const limit = Math.max(0, Math.floor(charsToLog));
|
|
25
|
+
text = text.slice(0, Math.max(0, limit - 3)) + "...".slice(0, limit);
|
|
9
26
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
dataToBeLogged.push(newItem);
|
|
26
|
-
}
|
|
27
|
-
let hasTypesRow = false;
|
|
28
|
-
if (types !== null) {
|
|
29
|
-
const columns = Object.keys(types);
|
|
30
|
-
if (columns.length > 0) {
|
|
31
|
-
for (const col of columns) {
|
|
32
|
-
if (data[0][col] === "<Geometry>") {
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
types[col] = types[col] + "/" +
|
|
37
|
-
(data[0][col] === null ? null : typeof data[0][col]);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Add types as the first row
|
|
41
|
-
dataToBeLogged.unshift(types);
|
|
42
|
-
hasTypesRow = true;
|
|
27
|
+
return [
|
|
28
|
+
key,
|
|
29
|
+
value instanceof LogValue
|
|
30
|
+
? new LogValue(String(text), value.jsType, value.category)
|
|
31
|
+
: text,
|
|
32
|
+
];
|
|
33
|
+
})));
|
|
34
|
+
const hasTypes = types !== null && Object.keys(types).length > 0;
|
|
35
|
+
if (hasTypes) {
|
|
36
|
+
formatted.unshift(Object.fromEntries(Object.entries(types).map(([key, sqlType]) => {
|
|
37
|
+
const representations = new Set(data.flatMap((row) => {
|
|
38
|
+
const value = row[key];
|
|
39
|
+
if (value instanceof LogValue) {
|
|
40
|
+
return value.category === "null" ? [] : [value.jsType];
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
return value === null || value === undefined ? [] : [typeof value];
|
|
43
|
+
}));
|
|
44
|
+
const first = data[0][key];
|
|
45
|
+
const representation = representations.size > 0
|
|
46
|
+
? [...representations].join("|")
|
|
47
|
+
: first instanceof LogValue
|
|
48
|
+
? first.jsType
|
|
49
|
+
: "null";
|
|
50
|
+
return [key, `${sqlType}/${representation}`];
|
|
51
|
+
})));
|
|
52
52
|
}
|
|
53
|
+
printTable(formatted, hasTypes ? { typesRowIndex: 0 } : undefined);
|
|
53
54
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type DuckDBType, type DuckDBValue } from "@duckdb/node-api";
|
|
2
|
+
import LogValue from "./LogValue.js";
|
|
3
|
+
/** Formats native temporal values before extraction can discard precision. */
|
|
4
|
+
export default function makeLogConverter(type: DuckDBType, convert: (value: DuckDBValue) => unknown): (value: DuckDBValue) => LogValue;
|
|
5
|
+
//# sourceMappingURL=makeLogConverter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeLogConverter.d.ts","sourceRoot":"","sources":["../../src/helpers/makeLogConverter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,8EAA8E;AAC9E,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,GACvC,CAAC,KAAK,EAAE,WAAW,KAAK,QAAQ,CA8DlC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { DuckDBTypeId, } from "@duckdb/node-api";
|
|
2
|
+
import LogValue from "./LogValue.js";
|
|
3
|
+
/** Formats native temporal values before extraction can discard precision. */
|
|
4
|
+
export default function makeLogConverter(type, convert) {
|
|
5
|
+
const sqlType = type.toString();
|
|
6
|
+
const floatArray = sqlType.includes("FLOAT[");
|
|
7
|
+
const placeholder = sqlType.toLowerCase().includes("geometry") ||
|
|
8
|
+
floatArray;
|
|
9
|
+
const temporal = [
|
|
10
|
+
DuckDBTypeId.DATE,
|
|
11
|
+
DuckDBTypeId.TIME,
|
|
12
|
+
DuckDBTypeId.TIME_TZ,
|
|
13
|
+
DuckDBTypeId.TIME_NS,
|
|
14
|
+
DuckDBTypeId.TIMESTAMP,
|
|
15
|
+
DuckDBTypeId.TIMESTAMP_TZ,
|
|
16
|
+
DuckDBTypeId.TIMESTAMP_S,
|
|
17
|
+
DuckDBTypeId.TIMESTAMP_MS,
|
|
18
|
+
DuckDBTypeId.TIMESTAMP_NS,
|
|
19
|
+
].includes(type.typeId);
|
|
20
|
+
const numeric = !placeholder &&
|
|
21
|
+
/^(TINYINT|SMALLINT|INTEGER|BIGINT|HUGEINT|UTINYINT|USMALLINT|UINTEGER|UBIGINT|UHUGEINT|FLOAT|DOUBLE|DECIMAL|BIGNUM)(\(|$)/
|
|
22
|
+
.test(sqlType);
|
|
23
|
+
const jsType = placeholder ? "string" : type.typeId === DuckDBTypeId.DATE ||
|
|
24
|
+
type.typeId === DuckDBTypeId.TIMESTAMP
|
|
25
|
+
? "object"
|
|
26
|
+
: temporal
|
|
27
|
+
? "string"
|
|
28
|
+
: type.typeId === DuckDBTypeId.BOOLEAN
|
|
29
|
+
? "boolean"
|
|
30
|
+
: numeric
|
|
31
|
+
? (/^(DECIMAL|BIGNUM)/.test(sqlType) ? "string" : "number")
|
|
32
|
+
: [
|
|
33
|
+
DuckDBTypeId.LIST,
|
|
34
|
+
DuckDBTypeId.ARRAY,
|
|
35
|
+
DuckDBTypeId.STRUCT,
|
|
36
|
+
DuckDBTypeId.MAP,
|
|
37
|
+
DuckDBTypeId.UNION,
|
|
38
|
+
DuckDBTypeId.INTERVAL,
|
|
39
|
+
].includes(type.typeId)
|
|
40
|
+
? "object"
|
|
41
|
+
: "string";
|
|
42
|
+
return (value) => {
|
|
43
|
+
if (value === null)
|
|
44
|
+
return new LogValue("null", jsType, "null");
|
|
45
|
+
// TIMESTAMPTZ uses the existing UTC converter, independent of process timezone.
|
|
46
|
+
const converted = floatArray
|
|
47
|
+
? `<${sqlType}>`
|
|
48
|
+
: temporal && type.typeId !== DuckDBTypeId.TIMESTAMP_TZ
|
|
49
|
+
? String(value)
|
|
50
|
+
: convert(value);
|
|
51
|
+
const text = typeof converted === "object" && converted !== null
|
|
52
|
+
? JSON.stringify(converted)
|
|
53
|
+
: String(converted);
|
|
54
|
+
return new LogValue(text,
|
|
55
|
+
// NaN and infinities are strings in the public JSON conversion.
|
|
56
|
+
temporal ? jsType : typeof converted, temporal
|
|
57
|
+
? "date"
|
|
58
|
+
: numeric
|
|
59
|
+
? "number"
|
|
60
|
+
: jsType === "boolean"
|
|
61
|
+
? "boolean"
|
|
62
|
+
: "string");
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osmFiles.d.ts","sourceRoot":"","sources":["../../src/helpers/osmFiles.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAShD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMnE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBrD;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IACP,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,GACA,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"osmFiles.d.ts","sourceRoot":"","sources":["../../src/helpers/osmFiles.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAShD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMnE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBrD;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IACP,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,GACA,OAAO,CAAC,MAAM,CAAC,CAqHjB;AAgMD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export default function parseType(type: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | `geometry('${string}')` | `GEOMETRY('${string}')`): string;
|
|
1
|
+
export default function parseType(type: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | "json" | "JSON" | `float[${number}]` | `FLOAT[${number}]` | `geometry('${string}')` | `GEOMETRY('${string}')`): string;
|
|
2
2
|
//# sourceMappingURL=parseTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseTypes.d.ts","sourceRoot":"","sources":["../../src/helpers/parseTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,IAAI,EACA,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"parseTypes.d.ts","sourceRoot":"","sources":["../../src/helpers/parseTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,IAAI,EACA,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,MAAM,GAAG,GAClB,SAAS,MAAM,GAAG,GAClB,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,UAmC5B"}
|
|
@@ -25,9 +25,13 @@ export default function parseType(type) {
|
|
|
25
25
|
"timestamp",
|
|
26
26
|
"timestamp with time zone",
|
|
27
27
|
"boolean",
|
|
28
|
+
"json",
|
|
28
29
|
].includes(typeLowerCase)) {
|
|
29
30
|
return type.toUpperCase();
|
|
30
31
|
}
|
|
32
|
+
else if (/^float\[[1-9]\d*\]$/.test(typeLowerCase)) {
|
|
33
|
+
return type.toUpperCase();
|
|
34
|
+
}
|
|
31
35
|
else if (typeLowerCase.includes("geometry")) {
|
|
32
36
|
return type.toUpperCase();
|
|
33
37
|
}
|
|
@@ -94,8 +94,10 @@ export type SourceOp = {
|
|
|
94
94
|
rawSQL?: string[];
|
|
95
95
|
/** A schema known from explicit source options, when inference is unnecessary. */
|
|
96
96
|
schema?: TableSchema;
|
|
97
|
-
/**
|
|
98
|
-
|
|
97
|
+
/** Whether the source uses spatial functions. */
|
|
98
|
+
needsSpatial?: boolean;
|
|
99
|
+
/** Returns a composable SELECT, optionally inspecting materialized inputs. */
|
|
100
|
+
buildSelect: () => string | Promise<string>;
|
|
99
101
|
};
|
|
100
102
|
/** A relational operation that can participate in a fused segment. */
|
|
101
103
|
export type RelationalOp = SourceOp | FusableOp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pendingOps.d.ts","sourceRoot":"","sources":["../../src/helpers/pendingOps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,SAAS,CAAC;IAChB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,KAAK,WAAW,EAAE,CAAC,CAAC;IAClE;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,WAAW,CAAC;IACnD;;;OAGG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"pendingOps.d.ts","sourceRoot":"","sources":["../../src/helpers/pendingOps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepareGeometry.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGeometry.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CA+Gf"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/** Validates and snapshots a two-dimensional WGS84 GeoJSON geometry cell. */
|
|
2
|
+
export default function prepareGeometry(value, column, row) {
|
|
3
|
+
if (value === null)
|
|
4
|
+
return null;
|
|
5
|
+
const fail = (message) => {
|
|
6
|
+
throw new Error(`Column ${JSON.stringify(column)}, row ${row}: ${message}`);
|
|
7
|
+
};
|
|
8
|
+
const active = new Set();
|
|
9
|
+
let hasSignedZero = false;
|
|
10
|
+
function position(value) {
|
|
11
|
+
if (!Array.isArray(value) || value.length !== 2 ||
|
|
12
|
+
!Array.from(value).every((n) => typeof n === "number" && Number.isFinite(n))) {
|
|
13
|
+
fail("Expected a finite two-dimensional [longitude, latitude] position; Z/M coordinates are unsupported.");
|
|
14
|
+
}
|
|
15
|
+
const point = value;
|
|
16
|
+
if (Math.abs(point[0]) > 180 || Math.abs(point[1]) > 90) {
|
|
17
|
+
fail("Expected WGS84 longitude [-180, 180] and latitude [-90, 90]; reproject the input first.");
|
|
18
|
+
}
|
|
19
|
+
hasSignedZero ||= Object.is(point[0], -0) || Object.is(point[1], -0);
|
|
20
|
+
return [...point];
|
|
21
|
+
}
|
|
22
|
+
function list(value, convert) {
|
|
23
|
+
if (!Array.isArray(value))
|
|
24
|
+
fail("Expected a coordinate array.");
|
|
25
|
+
return Array.from(value, convert);
|
|
26
|
+
}
|
|
27
|
+
function line(value) {
|
|
28
|
+
const points = list(value, position);
|
|
29
|
+
if (points.length < 2) {
|
|
30
|
+
fail("A LineString must contain at least two positions.");
|
|
31
|
+
}
|
|
32
|
+
return points;
|
|
33
|
+
}
|
|
34
|
+
function ring(value) {
|
|
35
|
+
const points = list(value, position);
|
|
36
|
+
if (points.length < 4 || points[0][0] !== points.at(-1)[0] ||
|
|
37
|
+
points[0][1] !== points.at(-1)[1]) {
|
|
38
|
+
fail("A polygon ring must contain at least four positions and be closed.");
|
|
39
|
+
}
|
|
40
|
+
return points;
|
|
41
|
+
}
|
|
42
|
+
function geometry(value) {
|
|
43
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
44
|
+
fail("Expected a GeoJSON geometry object or null.");
|
|
45
|
+
}
|
|
46
|
+
const object = value;
|
|
47
|
+
if (active.has(object))
|
|
48
|
+
fail("Cyclic GeometryCollections are unsupported.");
|
|
49
|
+
if (active.size >= 100) {
|
|
50
|
+
fail("GeometryCollections may nest at most 100 levels.");
|
|
51
|
+
}
|
|
52
|
+
active.add(object);
|
|
53
|
+
try {
|
|
54
|
+
const type = object.type;
|
|
55
|
+
if (type === "Feature" || type === "FeatureCollection") {
|
|
56
|
+
fail("Expected a GeoJSON geometry object, not a Feature or FeatureCollection; extract each feature's geometry first.");
|
|
57
|
+
}
|
|
58
|
+
if ("crs" in object) {
|
|
59
|
+
fail("Geometry crs members are unsupported; supply WGS84 coordinates and declare GEOMETRY('EPSG:4326').");
|
|
60
|
+
}
|
|
61
|
+
let coordinates;
|
|
62
|
+
switch (type) {
|
|
63
|
+
case "Point":
|
|
64
|
+
coordinates = position(object.coordinates);
|
|
65
|
+
break;
|
|
66
|
+
case "MultiPoint":
|
|
67
|
+
coordinates = list(object.coordinates, position);
|
|
68
|
+
break;
|
|
69
|
+
case "LineString":
|
|
70
|
+
coordinates = line(object.coordinates);
|
|
71
|
+
break;
|
|
72
|
+
case "MultiLineString":
|
|
73
|
+
coordinates = list(object.coordinates, line);
|
|
74
|
+
break;
|
|
75
|
+
case "Polygon":
|
|
76
|
+
coordinates = list(object.coordinates, ring);
|
|
77
|
+
break;
|
|
78
|
+
case "MultiPolygon":
|
|
79
|
+
coordinates = list(object.coordinates, (v) => list(v, ring));
|
|
80
|
+
break;
|
|
81
|
+
case "GeometryCollection":
|
|
82
|
+
return { type, geometries: list(object.geometries, geometry) };
|
|
83
|
+
default:
|
|
84
|
+
fail("Expected a supported GeoJSON geometry type.");
|
|
85
|
+
}
|
|
86
|
+
return { type, coordinates };
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
active.delete(object);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const prepared = geometry(value);
|
|
93
|
+
if (!hasSignedZero)
|
|
94
|
+
return JSON.stringify(prepared);
|
|
95
|
+
// JSON.stringify normalizes -0. Only supported geometry type names survive
|
|
96
|
+
// validation as strings, so the "-0" marker cannot collide with input text.
|
|
97
|
+
// Emit a decimal literal so DuckDB also preserves its sign when parsing JSON.
|
|
98
|
+
return JSON.stringify(prepared, (_key, cell) => Object.is(cell, -0) ? "-0" : cell).replaceAll('"-0"', "-0.0");
|
|
99
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepareJSON.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareJSON.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAmEf"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Validates and snapshots a JavaScript JSON value without dropping information. */
|
|
2
|
+
export default function prepareJSON(value, column, row) {
|
|
3
|
+
if (value === null || value === undefined)
|
|
4
|
+
return null;
|
|
5
|
+
const active = new Set();
|
|
6
|
+
const fail = (path, message) => {
|
|
7
|
+
throw new Error(`Column ${JSON.stringify(column)}, row ${row}, ${path}: ${message}`);
|
|
8
|
+
};
|
|
9
|
+
function serialize(value, path) {
|
|
10
|
+
if (value === null)
|
|
11
|
+
return "null";
|
|
12
|
+
if (typeof value === "string" || typeof value === "boolean") {
|
|
13
|
+
return JSON.stringify(value);
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
16
|
+
return Object.is(value, -0) ? "-0.0" : JSON.stringify(value);
|
|
17
|
+
}
|
|
18
|
+
if (typeof value !== "object") {
|
|
19
|
+
return fail(path, "Expected a JSON value: finite numbers, strings, booleans, null, arrays, or plain objects.");
|
|
20
|
+
}
|
|
21
|
+
if (active.has(value)) {
|
|
22
|
+
return fail(path, "Cyclic JSON values are unsupported.");
|
|
23
|
+
}
|
|
24
|
+
if (active.size >= 100) {
|
|
25
|
+
return fail(path, "JSON values may nest at most 100 levels.");
|
|
26
|
+
}
|
|
27
|
+
const array = Array.isArray(value);
|
|
28
|
+
if (!array && Object.getPrototypeOf(value) !== Object.prototype &&
|
|
29
|
+
Object.getPrototypeOf(value) !== null) {
|
|
30
|
+
return fail(path, "Expected a plain JSON object; convert class instances to JSON values first.");
|
|
31
|
+
}
|
|
32
|
+
if (Object.getOwnPropertySymbols(value).length) {
|
|
33
|
+
return fail(path, "JSON cannot represent symbol keys.");
|
|
34
|
+
}
|
|
35
|
+
active.add(value);
|
|
36
|
+
try {
|
|
37
|
+
if (array) {
|
|
38
|
+
if (Object.keys(value).length !== value.length) {
|
|
39
|
+
return fail(path, "JSON arrays must be dense and have no extra properties.");
|
|
40
|
+
}
|
|
41
|
+
return `[${Array.from(value, (item, i) => serialize(item, `${path}[${i}]`)).join(",")}]`;
|
|
42
|
+
}
|
|
43
|
+
return `{${Object.entries(value).map(([key, item]) => `${JSON.stringify(key)}:${serialize(item, `${path}[${JSON.stringify(key)}]`)}`).join(",")}}`;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
active.delete(value);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return serialize(value, "$");
|
|
50
|
+
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Prints a formatted table to the console with support for word wrapping
|
|
3
|
-
* within cells. Unlike `console.table()`, this function properly
|
|
4
|
-
* multi-line content
|
|
5
|
-
*
|
|
3
|
+
* within headers and cells. Unlike `console.table()`, this function properly
|
|
4
|
+
* handles multi-line content, making it ideal for displaying data with long
|
|
5
|
+
* column names and text values.
|
|
6
6
|
*
|
|
7
7
|
* @param data - An array of objects representing the rows of the table. Each
|
|
8
8
|
* object should have string keys.
|
|
9
9
|
* @param options - Optional configuration for table rendering.
|
|
10
10
|
* @param options.maxColumnWidth - The maximum width for any column (default:
|
|
11
|
-
* `75`).
|
|
11
|
+
* `75`). Headers and values exceeding this width will be wrapped at word
|
|
12
|
+
* boundaries.
|
|
12
13
|
* @param options.minColumnWidth - The minimum width for any column (default:
|
|
13
14
|
* `3`).
|
|
14
15
|
* @param options.typesRowIndex - The index of a row that contains type
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,EAClC,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CAgNN"}
|