datasette-ts 0.0.2 → 0.0.4
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/cli.js +77 -32
- package/dist/cli.js.map +3 -3
- package/package.json +1 -1
- package/scripts/build.mjs +8 -0
- package/scripts/cloudflare-deploy-helpers.mjs +77 -30
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
|
|
2
5
|
var __create = Object.create;
|
|
3
6
|
var __defProp = Object.defineProperty;
|
|
4
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -23670,22 +23673,27 @@ import alchemy from "alchemy";
|
|
|
23670
23673
|
import { Assets, D1Database, Worker } from "alchemy/cloudflare";
|
|
23671
23674
|
|
|
23672
23675
|
// scripts/cloudflare-deploy-helpers.mjs
|
|
23673
|
-
import {
|
|
23676
|
+
import { spawn } from "node:child_process";
|
|
23674
23677
|
import { createHash } from "node:crypto";
|
|
23675
|
-
import { createReadStream } from "node:fs";
|
|
23676
|
-
import { mkdir, stat,
|
|
23678
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
23679
|
+
import { mkdir, stat, unlink } from "node:fs/promises";
|
|
23680
|
+
import { once } from "node:events";
|
|
23677
23681
|
import path from "node:path";
|
|
23682
|
+
import { createInterface } from "node:readline";
|
|
23683
|
+
import { pipeline } from "node:stream/promises";
|
|
23678
23684
|
import { pathToFileURL } from "node:url";
|
|
23679
23685
|
import { createClient } from "@libsql/client";
|
|
23680
23686
|
async function dumpSqliteForD1(options) {
|
|
23681
23687
|
const baseName = options.outputName ?? path.basename(options.dbFile, path.extname(options.dbFile));
|
|
23682
23688
|
const outputPath = path.join(options.outputDir, `${baseName}.sql`);
|
|
23689
|
+
const rawPath = path.join(options.outputDir, `${baseName}.raw.sql`);
|
|
23683
23690
|
await mkdir(options.outputDir, { recursive: true });
|
|
23684
|
-
|
|
23685
|
-
|
|
23686
|
-
|
|
23687
|
-
|
|
23688
|
-
|
|
23691
|
+
await dumpSqliteToFile(options.dbFile, rawPath);
|
|
23692
|
+
try {
|
|
23693
|
+
await normalizeDumpFile(rawPath, outputPath);
|
|
23694
|
+
} finally {
|
|
23695
|
+
await unlink(rawPath).catch(() => void 0);
|
|
23696
|
+
}
|
|
23689
23697
|
return outputPath;
|
|
23690
23698
|
}
|
|
23691
23699
|
async function loadSchemaFromFile(dbFile) {
|
|
@@ -23808,48 +23816,85 @@ function escapeIdentifier(name) {
|
|
|
23808
23816
|
const escaped = String(name).replace(/"/g, '""');
|
|
23809
23817
|
return `"${escaped}"`;
|
|
23810
23818
|
}
|
|
23811
|
-
function
|
|
23812
|
-
const lines = rawDump.split("\n");
|
|
23813
|
-
const output = [];
|
|
23819
|
+
async function normalizeDumpFile(inputPath, outputPath) {
|
|
23814
23820
|
const tablesInOrder = [];
|
|
23815
23821
|
const viewsInOrder = [];
|
|
23816
|
-
|
|
23822
|
+
await forEachLine(inputPath, (line) => {
|
|
23817
23823
|
const tableMatch = line.match(/^CREATE TABLE\s+("?[^"]+"?)/i);
|
|
23818
23824
|
if (tableMatch) {
|
|
23819
23825
|
tablesInOrder.push(tableMatch[1].replace(/\s*\($/, ""));
|
|
23820
|
-
|
|
23826
|
+
return;
|
|
23821
23827
|
}
|
|
23822
23828
|
const viewMatch = line.match(/^CREATE VIEW\s+("?[^"]+"?)/i);
|
|
23823
23829
|
if (viewMatch) {
|
|
23824
23830
|
viewsInOrder.push(viewMatch[1].replace(/\s*\($/, ""));
|
|
23825
23831
|
}
|
|
23826
|
-
}
|
|
23832
|
+
});
|
|
23833
|
+
const outputStream = createWriteStream(outputPath, { encoding: "utf8" });
|
|
23827
23834
|
for (const viewName of viewsInOrder.reverse()) {
|
|
23828
|
-
|
|
23835
|
+
await writeLine(outputStream, `DROP VIEW IF EXISTS ${viewName};`);
|
|
23829
23836
|
}
|
|
23830
23837
|
for (const tableName of tablesInOrder.reverse()) {
|
|
23831
|
-
|
|
23838
|
+
await writeLine(outputStream, `DROP TABLE IF EXISTS ${tableName};`);
|
|
23832
23839
|
}
|
|
23833
|
-
|
|
23840
|
+
await forEachLine(inputPath, async (line) => {
|
|
23834
23841
|
if (line === "BEGIN TRANSACTION;" || line === "COMMIT;") {
|
|
23835
|
-
|
|
23842
|
+
return;
|
|
23836
23843
|
}
|
|
23837
23844
|
if (line.startsWith("PRAGMA foreign_keys=")) {
|
|
23838
|
-
|
|
23839
|
-
}
|
|
23840
|
-
const tableMatch = line.match(/^CREATE TABLE\s+("?[^"]+"?)/i);
|
|
23841
|
-
if (tableMatch) {
|
|
23842
|
-
output.push(line);
|
|
23843
|
-
continue;
|
|
23845
|
+
return;
|
|
23844
23846
|
}
|
|
23845
|
-
|
|
23846
|
-
|
|
23847
|
-
|
|
23848
|
-
|
|
23847
|
+
await writeLine(outputStream, line);
|
|
23848
|
+
});
|
|
23849
|
+
outputStream.end();
|
|
23850
|
+
await once(outputStream, "finish");
|
|
23851
|
+
}
|
|
23852
|
+
async function dumpSqliteToFile(dbFile, outputPath) {
|
|
23853
|
+
const child = spawn("sqlite3", [dbFile, ".dump"], {
|
|
23854
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
23855
|
+
});
|
|
23856
|
+
let stderr = "";
|
|
23857
|
+
if (child.stderr) {
|
|
23858
|
+
child.stderr.setEncoding("utf8");
|
|
23859
|
+
child.stderr.on("data", (chunk) => {
|
|
23860
|
+
stderr += chunk;
|
|
23861
|
+
});
|
|
23862
|
+
}
|
|
23863
|
+
const stdout = child.stdout;
|
|
23864
|
+
if (!stdout) {
|
|
23865
|
+
const [error] = await once(child, "error");
|
|
23866
|
+
throw error ?? new Error("sqlite3 stdout is unavailable.");
|
|
23867
|
+
}
|
|
23868
|
+
const outputStream = createWriteStream(outputPath, { encoding: "utf8" });
|
|
23869
|
+
child.once("error", (error) => {
|
|
23870
|
+
stdout.destroy(error);
|
|
23871
|
+
outputStream.destroy(error);
|
|
23872
|
+
});
|
|
23873
|
+
await pipeline(stdout, outputStream);
|
|
23874
|
+
const [code, signal] = await once(child, "close");
|
|
23875
|
+
if (code !== 0) {
|
|
23876
|
+
const suffix = signal ? ` (signal ${signal})` : "";
|
|
23877
|
+
const message = stderr.trim() || `sqlite3 exited with code ${code ?? "unknown"}${suffix}`;
|
|
23878
|
+
throw new Error(message);
|
|
23879
|
+
}
|
|
23880
|
+
}
|
|
23881
|
+
async function forEachLine(filePath, handler) {
|
|
23882
|
+
const stream = createReadStream(filePath, { encoding: "utf8" });
|
|
23883
|
+
const rl = createInterface({ input: stream, crlfDelay: Infinity });
|
|
23884
|
+
try {
|
|
23885
|
+
for await (const line of rl) {
|
|
23886
|
+
await handler(line);
|
|
23849
23887
|
}
|
|
23850
|
-
|
|
23888
|
+
} finally {
|
|
23889
|
+
rl.close();
|
|
23890
|
+
stream.close();
|
|
23891
|
+
}
|
|
23892
|
+
}
|
|
23893
|
+
async function writeLine(stream, line) {
|
|
23894
|
+
if (!stream.write(`${line}
|
|
23895
|
+
`)) {
|
|
23896
|
+
await once(stream, "drain");
|
|
23851
23897
|
}
|
|
23852
|
-
return output.join("\n");
|
|
23853
23898
|
}
|
|
23854
23899
|
async function hashFile(filePath) {
|
|
23855
23900
|
return new Promise((resolve2, reject) => {
|
|
@@ -24164,7 +24209,7 @@ function isSqliteCliMissing(error) {
|
|
|
24164
24209
|
|
|
24165
24210
|
// src/cli/serve.ts
|
|
24166
24211
|
init_registry();
|
|
24167
|
-
import { stat as stat5, writeFile
|
|
24212
|
+
import { stat as stat5, writeFile } from "node:fs/promises";
|
|
24168
24213
|
import { join as join2 } from "node:path";
|
|
24169
24214
|
|
|
24170
24215
|
// src/core/inspect.ts
|
|
@@ -24337,7 +24382,7 @@ async function runInspectCommand(args) {
|
|
|
24337
24382
|
const data = await inspectDatabases(databasePaths);
|
|
24338
24383
|
const json = JSON.stringify(data, null, 2);
|
|
24339
24384
|
if (inspectFile) {
|
|
24340
|
-
await
|
|
24385
|
+
await writeFile(inspectFile, json, "utf8");
|
|
24341
24386
|
return;
|
|
24342
24387
|
}
|
|
24343
24388
|
process.stdout.write(`${json}
|