datasette-ts 0.0.16 → 0.0.18

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 CHANGED
@@ -24,31 +24,22 @@ Open `http://127.0.0.1:8001`.
24
24
  datasette-ts inspect ./my.db --inspect-file inspect-data.json
25
25
  ```
26
26
 
27
- ## Deploy to Cloudflare (Alchemy)
27
+ ## Deploy to Cloudflare
28
28
 
29
- Prereqs:
30
- - `sqlite3` available on your PATH
31
- - Alchemy configured and logged in (`alchemy configure`, `alchemy login`)
32
-
33
- Basic deploy (worker/D1 names default to the SQLite basename):
29
+ Prereqs: Alchemy configured (`npx alchemy login`)
34
30
 
35
31
  ```bash
32
+ # Deploy with name derived from filename
36
33
  datasette-ts deploy cloudflare ./my.db
37
- ```
38
34
 
39
- Explicit names + profile:
35
+ # Deploy with explicit name
36
+ datasette-ts deploy cloudflare ./my.db --name my-app
40
37
 
41
- ```bash
42
- datasette-ts deploy cloudflare ./my.db \
43
- --worker my-datasette \
44
- --d1 my-datasette-db \
45
- --db-name mydb \
46
- --profile prod
38
+ # Deploy with specific Cloudflare profile
39
+ datasette-ts deploy cloudflare ./my.db --name my-app --profile prod
47
40
  ```
48
41
 
49
- Notes:
50
- - The CLI generates a D1 import SQL file at `.datasette-ts/imports/<db-name>.sql`.
51
- - Use `--no-precompute-inspect` if you want to skip inspect metadata generation.
42
+ This creates a Cloudflare Worker and D1 database with your data.
52
43
 
53
44
  ## CLI help
54
45
 
package/dist/cli.js CHANGED
@@ -23686,12 +23686,13 @@ var init_node4 = __esm({
23686
23686
  });
23687
23687
 
23688
23688
  // src/cli.ts
23689
- import { parseArgs as parseArgs2 } from "node:util";
23689
+ import { parseArgs as parseArgs3 } from "node:util";
23690
23690
 
23691
23691
  // src/cli/deploy-cloudflare.ts
23692
23692
  import { mkdir as mkdir2, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
23693
23693
  import { dirname, extname, join, relative, resolve } from "node:path";
23694
23694
  import { fileURLToPath } from "node:url";
23695
+ import { parseArgs } from "node:util";
23695
23696
  import alchemy from "alchemy";
23696
23697
  import { Assets, D1Database, Worker } from "alchemy/cloudflare";
23697
23698
 
@@ -23783,6 +23784,9 @@ function escapeSqlValue(value) {
23783
23784
  if (value === null || value === void 0) {
23784
23785
  return "NULL";
23785
23786
  }
23787
+ if (typeof value === "bigint") {
23788
+ return String(value);
23789
+ }
23786
23790
  if (typeof value === "number") {
23787
23791
  return Number.isFinite(value) ? String(value) : "NULL";
23788
23792
  }
@@ -23927,7 +23931,11 @@ async function countTables(dbFile) {
23927
23931
  }
23928
23932
  }
23929
23933
  function createReadonlyClient(dbFile) {
23930
- return createClient({ url: pathToFileURL(dbFile).toString() });
23934
+ return createClient({
23935
+ url: pathToFileURL(dbFile).toString(),
23936
+ intMode: "bigint"
23937
+ // Handle integers > MAX_SAFE_INTEGER
23938
+ });
23931
23939
  }
23932
23940
  async function executeRows(db, sql2, args = []) {
23933
23941
  const result = await db.execute({ sql: sql2, args });
@@ -24058,138 +24066,48 @@ async function runCloudflareDeploy(args) {
24058
24066
  logStep(`Done in ${formatDuration(Date.now() - startedAt)}`);
24059
24067
  }
24060
24068
  function parseDeployArgs(args) {
24061
- const positional = [];
24062
- let dbFile;
24063
- let dbName;
24064
- let workerName;
24065
- let d1Name;
24066
- let profile;
24067
- let precomputeInspect = true;
24068
- let importsDir;
24069
- for (let index = 0; index < args.length; index += 1) {
24070
- const arg = args[index];
24071
- if (!arg) {
24072
- continue;
24073
- }
24074
- if (arg === "--precompute-inspect") {
24075
- precomputeInspect = true;
24076
- continue;
24077
- }
24078
- if (arg === "--no-precompute-inspect") {
24079
- precomputeInspect = false;
24080
- continue;
24081
- }
24082
- const parsedArg = parseNamedArg(arg, args[index + 1]);
24083
- if (!parsedArg) {
24084
- positional.push(arg);
24085
- continue;
24086
- }
24087
- const { key, value } = parsedArg;
24088
- switch (key) {
24089
- case "db":
24090
- case "db-file":
24091
- dbFile = value ?? dbFile;
24092
- if (!arg.includes("=")) {
24093
- index += 1;
24094
- }
24095
- break;
24096
- case "db-name":
24097
- dbName = value ?? dbName;
24098
- if (!arg.includes("=")) {
24099
- index += 1;
24100
- }
24101
- break;
24102
- case "worker":
24103
- workerName = value ?? workerName;
24104
- if (!arg.includes("=")) {
24105
- index += 1;
24106
- }
24107
- break;
24108
- case "d1":
24109
- d1Name = value ?? d1Name;
24110
- if (!arg.includes("=")) {
24111
- index += 1;
24112
- }
24113
- break;
24114
- case "profile":
24115
- profile = value ?? profile;
24116
- if (!arg.includes("=")) {
24117
- index += 1;
24118
- }
24119
- break;
24120
- case "imports-dir":
24121
- importsDir = value ?? importsDir;
24122
- if (!arg.includes("=")) {
24123
- index += 1;
24124
- }
24125
- break;
24126
- case "precompute-inspect":
24127
- precomputeInspect = parseBooleanFlag(value, true);
24128
- if (!arg.includes("=")) {
24129
- index += 1;
24130
- }
24131
- break;
24132
- default:
24133
- break;
24069
+ const { values, positionals } = parseArgs({
24070
+ args,
24071
+ allowPositionals: true,
24072
+ strict: false,
24073
+ options: {
24074
+ name: { type: "string", short: "n" },
24075
+ worker: { type: "string" },
24076
+ d1: { type: "string" },
24077
+ "db-name": { type: "string" },
24078
+ profile: { type: "string", short: "p" },
24079
+ "imports-dir": { type: "string" },
24080
+ "precompute-inspect": { type: "boolean", default: true },
24081
+ "no-precompute-inspect": { type: "boolean" }
24134
24082
  }
24135
- }
24136
- if (!dbFile && positional.length > 0) {
24137
- dbFile = positional[0];
24138
- }
24083
+ });
24084
+ const dbFile = positionals[0];
24139
24085
  if (!dbFile) {
24140
- throw new Error("Missing SQLite database path.");
24086
+ throw new Error("Missing SQLite database path.\n\nUsage: datasette-ts deploy cloudflare <db-file> [--name <name>]");
24141
24087
  }
24142
24088
  const resolvedDbFile = resolve(dbFile);
24143
- const derivedDbName = deriveName(resolvedDbFile);
24144
- const derivedResourceName = normalizeResourceName(derivedDbName);
24145
- const resolvedImportsDir = resolve(importsDir ?? DEFAULT_IMPORTS_DIR);
24089
+ const derivedName = deriveNameFromPath(resolvedDbFile);
24090
+ const normalizedName = normalizeResourceName(values.name ?? derivedName);
24091
+ const precomputeInspect = values["no-precompute-inspect"] ? false : values["precompute-inspect"] !== false;
24146
24092
  return {
24147
24093
  dbFile: resolvedDbFile,
24148
- dbName: dbName ?? derivedDbName,
24149
- workerName: workerName ?? derivedResourceName,
24150
- d1Name: d1Name ?? derivedResourceName,
24151
- profile,
24094
+ dbName: values["db-name"] ?? values.name ?? derivedName,
24095
+ workerName: values.worker ?? normalizedName,
24096
+ d1Name: values.d1 ?? normalizedName,
24097
+ profile: values.profile,
24152
24098
  precomputeInspect,
24153
- importsDir: resolvedImportsDir
24099
+ importsDir: resolve(values["imports-dir"] ?? DEFAULT_IMPORTS_DIR)
24154
24100
  };
24155
24101
  }
24156
- function deriveName(path7) {
24157
- const base = path7.split(/[\\/]/).pop() ?? path7;
24158
- const name = base.replace(new RegExp(`${escapeRegex(extname(base))}$`), "");
24159
- return name === "" ? "db" : name;
24102
+ function deriveNameFromPath(filePath) {
24103
+ const base = filePath.split(/[\\/]/).pop() ?? filePath;
24104
+ const ext = extname(base);
24105
+ const name = ext ? base.slice(0, -ext.length) : base;
24106
+ return name || "db";
24160
24107
  }
24161
24108
  function normalizeResourceName(name) {
24162
24109
  const normalized = name.trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
24163
- return normalized === "" ? "db" : normalized;
24164
- }
24165
- function escapeRegex(value) {
24166
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24167
- }
24168
- function parseNamedArg(arg, nextValue) {
24169
- if (!arg.startsWith("--")) {
24170
- return null;
24171
- }
24172
- const [key, value] = arg.slice(2).split("=");
24173
- if (!key) {
24174
- return null;
24175
- }
24176
- if (value !== void 0) {
24177
- return { key, value };
24178
- }
24179
- return { key, value: nextValue };
24180
- }
24181
- function parseBooleanFlag(value, defaultValue) {
24182
- if (value == null) {
24183
- return defaultValue;
24184
- }
24185
- const normalized = value.trim().toLowerCase();
24186
- if (["0", "false", "no", "off"].includes(normalized)) {
24187
- return false;
24188
- }
24189
- if (["1", "true", "yes", "on"].includes(normalized)) {
24190
- return true;
24191
- }
24192
- return defaultValue;
24110
+ return normalized || "db";
24193
24111
  }
24194
24112
  async function resolvePackageRoot() {
24195
24113
  let current = dirname(fileURLToPath(import.meta.url));
@@ -24314,7 +24232,7 @@ async function loadInspectData(inspectFile) {
24314
24232
  async function inspectDatabases(databasePaths) {
24315
24233
  const results = {};
24316
24234
  for (const filename of databasePaths) {
24317
- const name = deriveName2(filename);
24235
+ const name = deriveName(filename);
24318
24236
  results[name] = await inspectDatabase(filename);
24319
24237
  }
24320
24238
  return results;
@@ -24370,7 +24288,7 @@ function escapeIdentifier3(name) {
24370
24288
  const escaped = name.replace(/"/g, '""');
24371
24289
  return `"${escaped}"`;
24372
24290
  }
24373
- function deriveName2(path7) {
24291
+ function deriveName(path7) {
24374
24292
  const parts = path7.split(/[\\/]/);
24375
24293
  const last = parts[parts.length - 1] ?? path7;
24376
24294
  const name = last.replace(/\.[^/.]+$/, "");
@@ -24413,7 +24331,7 @@ async function startServer(options) {
24413
24331
  // src/cli/serve.ts
24414
24332
  var DEFAULT_DB = "data.db";
24415
24333
  async function runServeCommand(args) {
24416
- const options = await parseArgs(args);
24334
+ const options = await parseArgs2(args);
24417
24335
  const registry = new DatabaseRegistry(
24418
24336
  options.databases,
24419
24337
  options.metadata ?? null,
@@ -24450,7 +24368,7 @@ async function runInspectCommand(args) {
24450
24368
  if (!arg) {
24451
24369
  continue;
24452
24370
  }
24453
- const parsedArg = parseNamedArg2(arg, args[index + 1]);
24371
+ const parsedArg = parseNamedArg(arg, args[index + 1]);
24454
24372
  if (parsedArg?.key === "inspect-file") {
24455
24373
  if (parsedArg.value) {
24456
24374
  inspectFile = parsedArg.value;
@@ -24474,7 +24392,7 @@ async function runInspectCommand(args) {
24474
24392
  process.stdout.write(`${json}
24475
24393
  `);
24476
24394
  }
24477
- async function parseArgs(args) {
24395
+ async function parseArgs2(args) {
24478
24396
  const databasePaths = [];
24479
24397
  let port;
24480
24398
  let hostname;
@@ -24487,7 +24405,7 @@ async function parseArgs(args) {
24487
24405
  if (!arg) {
24488
24406
  continue;
24489
24407
  }
24490
- const parsedArg = parseNamedArg2(arg, args[index + 1]);
24408
+ const parsedArg = parseNamedArg(arg, args[index + 1]);
24491
24409
  if (parsedArg?.key === "port") {
24492
24410
  if (parsedArg.value) {
24493
24411
  port = Number(parsedArg.value);
@@ -24542,7 +24460,7 @@ async function parseArgs(args) {
24542
24460
  databasePaths.push(DEFAULT_DB);
24543
24461
  }
24544
24462
  const databases = databasePaths.map((filename) => ({
24545
- name: deriveName3(filename),
24463
+ name: deriveName2(filename),
24546
24464
  filename,
24547
24465
  mutable
24548
24466
  }));
@@ -24572,13 +24490,13 @@ async function parseArgs(args) {
24572
24490
  }
24573
24491
  return result;
24574
24492
  }
24575
- function deriveName3(path7) {
24493
+ function deriveName2(path7) {
24576
24494
  const parts = path7.split(/[\\/]/);
24577
24495
  const last = parts[parts.length - 1] ?? path7;
24578
24496
  const name = last.replace(/\.[^/.]+$/, "");
24579
24497
  return name === "" ? "db" : name;
24580
24498
  }
24581
- function parseNamedArg2(arg, nextValue) {
24499
+ function parseNamedArg(arg, nextValue) {
24582
24500
  if (!arg.startsWith("--")) {
24583
24501
  return null;
24584
24502
  }
@@ -24600,7 +24518,7 @@ mainPromise.catch((error) => {
24600
24518
  });
24601
24519
  async function main() {
24602
24520
  const args = process.argv.slice(2);
24603
- const parsed = parseArgs2({
24521
+ const parsed = parseArgs3({
24604
24522
  args,
24605
24523
  allowPositionals: true,
24606
24524
  strict: false,
@@ -24674,7 +24592,7 @@ function dropPositionals(args, positionalIndices, count) {
24674
24592
  return args.filter((_, index) => !remove.has(index));
24675
24593
  }
24676
24594
  function hasHelpFlag(args) {
24677
- const parsed = parseArgs2({
24595
+ const parsed = parseArgs3({
24678
24596
  args,
24679
24597
  allowPositionals: true,
24680
24598
  strict: false,
@@ -24715,14 +24633,18 @@ Options:
24715
24633
  function printDeployHelp() {
24716
24634
  console.log(`datasette-ts deploy cloudflare <db-file> [options]
24717
24635
 
24636
+ Examples:
24637
+ datasette-ts deploy cloudflare ./data.db
24638
+ datasette-ts deploy cloudflare ./data.db --name my-app
24639
+
24718
24640
  Options:
24719
- --db, --db-file <file> SQLite database file (positional works too)
24720
- --db-name <name> Datasette database name (default: sqlite basename)
24721
- --worker <name> Worker name (default: sqlite basename)
24722
- --d1 <name> D1 database name (default: sqlite basename)
24723
- --profile <name> Alchemy/Cloudflare profile to use
24724
- --imports-dir <dir> Output directory for D1 import SQL
24725
- --precompute-inspect Precompute inspect data (default)
24726
- --no-precompute-inspect Disable inspect precompute`);
24641
+ -n, --name <name> Name for worker and D1 database (default: db filename)
24642
+ -p, --profile <name> Cloudflare profile to use
24643
+
24644
+ Advanced:
24645
+ --worker <name> Override worker name
24646
+ --d1 <name> Override D1 database name
24647
+ --db-name <name> Override Datasette display name
24648
+ --no-precompute-inspect Skip precomputing inspect data`);
24727
24649
  }
24728
24650
  //# sourceMappingURL=cli.js.map