@type32/tauri-sqlite-orm 0.1.9 → 0.1.11

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.d.mts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/cli.ts
5
+ var import_node_fs = require("fs");
6
+ var import_node_path = require("path");
7
+ var help = `
8
+ tauriorm-kit
9
+
10
+ Usage:
11
+ bunx tauriorm-kit generate --out ./src/lib/db-client.ts --schema ./src/lib/schema.ts
12
+
13
+ Options:
14
+ --out <file> Output file where a typed client factory will be written
15
+ --schema <file> Path to a module that exports your tables and optional relations
16
+ --driver <uri> Database URI (default: sqlite:app.db)
17
+ `;
18
+ async function main() {
19
+ const args = process.argv.slice(2);
20
+ if (args.length === 0 || args.includes("-h") || args.includes("--help")) {
21
+ console.log(help);
22
+ process.exit(0);
23
+ }
24
+ const cmd = args[0];
25
+ if (cmd !== "generate") {
26
+ console.error("Unknown command.\n" + help);
27
+ process.exit(1);
28
+ }
29
+ const outIdx = args.indexOf("--out");
30
+ const schemaIdx = args.indexOf("--schema");
31
+ const driverIdx = args.indexOf("--driver");
32
+ if (outIdx === -1 || schemaIdx === -1) {
33
+ console.error("Missing --out or --schema.\n" + help);
34
+ process.exit(1);
35
+ }
36
+ const outPath = (0, import_node_path.resolve)(process.cwd(), args[outIdx + 1]);
37
+ const schemaPath = (0, import_node_path.resolve)(process.cwd(), args[schemaIdx + 1]);
38
+ const driverUri = driverIdx !== -1 ? args[driverIdx + 1] : "sqlite:app.db";
39
+ const content = `
40
+ import { TauriORM } from "@type32/tauri-sqlite-orm";
41
+ import * as Schema from ${JSON.stringify(schemaPath)};
42
+
43
+ export function createDb() {
44
+ const db = new TauriORM(${JSON.stringify(driverUri)}).configure(
45
+ // collect tables: any export that looks like a table (has _tableName)
46
+ Object.fromEntries(
47
+ Object.entries(Schema).filter(([, v]) => v && typeof v === 'object' && '_tableName' in v)
48
+ ) as any,
49
+ // optional relations export
50
+ (Schema as any).relations || {}
51
+ );
52
+ return db;
53
+ }
54
+ `;
55
+ const dir = (0, import_node_path.resolve)(outPath, "..");
56
+ if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
57
+ (0, import_node_fs.writeFileSync)(outPath, content, "utf8");
58
+ console.log(`\u2714 Wrote ${outPath}`);
59
+ }
60
+ main().catch((err) => {
61
+ console.error(err);
62
+ process.exit(1);
63
+ });
package/dist/cli.mjs ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
5
+ import { resolve } from "path";
6
+ var help = `
7
+ tauriorm-kit
8
+
9
+ Usage:
10
+ bunx tauriorm-kit generate --out ./src/lib/db-client.ts --schema ./src/lib/schema.ts
11
+
12
+ Options:
13
+ --out <file> Output file where a typed client factory will be written
14
+ --schema <file> Path to a module that exports your tables and optional relations
15
+ --driver <uri> Database URI (default: sqlite:app.db)
16
+ `;
17
+ async function main() {
18
+ const args = process.argv.slice(2);
19
+ if (args.length === 0 || args.includes("-h") || args.includes("--help")) {
20
+ console.log(help);
21
+ process.exit(0);
22
+ }
23
+ const cmd = args[0];
24
+ if (cmd !== "generate") {
25
+ console.error("Unknown command.\n" + help);
26
+ process.exit(1);
27
+ }
28
+ const outIdx = args.indexOf("--out");
29
+ const schemaIdx = args.indexOf("--schema");
30
+ const driverIdx = args.indexOf("--driver");
31
+ if (outIdx === -1 || schemaIdx === -1) {
32
+ console.error("Missing --out or --schema.\n" + help);
33
+ process.exit(1);
34
+ }
35
+ const outPath = resolve(process.cwd(), args[outIdx + 1]);
36
+ const schemaPath = resolve(process.cwd(), args[schemaIdx + 1]);
37
+ const driverUri = driverIdx !== -1 ? args[driverIdx + 1] : "sqlite:app.db";
38
+ const content = `
39
+ import { TauriORM } from "@type32/tauri-sqlite-orm";
40
+ import * as Schema from ${JSON.stringify(schemaPath)};
41
+
42
+ export function createDb() {
43
+ const db = new TauriORM(${JSON.stringify(driverUri)}).configure(
44
+ // collect tables: any export that looks like a table (has _tableName)
45
+ Object.fromEntries(
46
+ Object.entries(Schema).filter(([, v]) => v && typeof v === 'object' && '_tableName' in v)
47
+ ) as any,
48
+ // optional relations export
49
+ (Schema as any).relations || {}
50
+ );
51
+ return db;
52
+ }
53
+ `;
54
+ const dir = resolve(outPath, "..");
55
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
56
+ writeFileSync(outPath, content, "utf8");
57
+ console.log(`\u2714 Wrote ${outPath}`);
58
+ }
59
+ main().catch((err) => {
60
+ console.error(err);
61
+ process.exit(1);
62
+ });
package/dist/index.js CHANGED
@@ -593,9 +593,11 @@ var SelectQueryBuilder = class {
593
593
  throw new Error("Cannot execute select query without a 'from' table.");
594
594
  }
595
595
  const db = await this._dbProvider();
596
+ const baseTableName = this._table._tableName || this._table.tableName;
597
+ if (!baseTableName) throw new Error("Invalid table passed to select.from(): missing _tableName");
596
598
  const bindings = [];
597
- const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${this._table._tableName}.${c.name}`).join(", ");
598
- let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${this._table._tableName}`;
599
+ const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${baseTableName}.${c.name}`).join(", ");
600
+ let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${baseTableName}`;
599
601
  if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
600
602
  if (this._where.length > 0) {
601
603
  const whereClauses = this._where.map((condition) => {
@@ -722,30 +724,46 @@ var TauriORM = class {
722
724
  }
723
725
  async execute() {
724
726
  const db = await self.getDb();
727
+ const tableName = this._table._tableName || this._table.tableName;
728
+ if (!tableName) throw new Error("Invalid table passed to insert(): missing _tableName");
725
729
  if (this._selectSql) {
726
730
  const cols = Object.keys(this._table._schema);
727
- let query = `INSERT INTO ${this._table._tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
731
+ let query = `INSERT INTO ${tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
728
732
  const bindings = [...this._selectSql.bindings];
729
733
  query += this._buildConflictClause();
730
734
  const ret = await this._executeWithReturning(db, query, bindings);
731
735
  return ret;
732
736
  }
733
737
  for (const data of this._rows) {
738
+ let coerceValue2 = function(col, value) {
739
+ if (col && col.mode === "boolean") {
740
+ return value ? 1 : 0;
741
+ }
742
+ if (value instanceof Date) {
743
+ if (col && col.mode === "timestamp_ms")
744
+ return value.getTime();
745
+ if (col && col.mode === "timestamp")
746
+ return Math.floor(value.getTime() / 1e3);
747
+ }
748
+ return value;
749
+ };
750
+ var coerceValue = coerceValue2;
734
751
  const finalData = Object.assign({}, data);
735
752
  const schema = this._table._schema;
736
753
  for (const [key, col] of Object.entries(schema)) {
737
754
  if (finalData[key] === void 0) {
738
755
  if (col.defaultFn) {
739
- finalData[key] = col.defaultFn();
756
+ finalData[key] = coerceValue2(col, col.defaultFn());
740
757
  } else if (col.onUpdateFn) {
741
- finalData[key] = col.onUpdateFn();
758
+ finalData[key] = coerceValue2(col, col.onUpdateFn());
742
759
  }
743
760
  }
744
761
  }
745
- const keys = Object.keys(finalData);
746
- const values = Object.values(finalData);
762
+ const entries = Object.entries(finalData);
763
+ const keys = entries.map(([k]) => schema[k]?.name ?? k);
764
+ const values = entries.map(([k, v]) => coerceValue2(schema[k], v));
747
765
  const placeholders = values.map(() => "?").join(", ");
748
- let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
766
+ let query = `INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
749
767
  const bindings = [...values];
750
768
  query += this._buildConflictClause();
751
769
  const ret = await this._executeWithReturning(db, query, bindings);
@@ -837,11 +855,21 @@ var TauriORM = class {
837
855
  if (!this._data)
838
856
  throw new Error("Update requires set() before execute()");
839
857
  const db = await self.getDb();
858
+ const tableName = this._table._tableName || this._table.tableName;
859
+ if (!tableName) throw new Error("Invalid table passed to update(): missing _tableName");
840
860
  const schema = this._table._schema;
841
861
  const dataToSet = { ...this._data };
842
862
  for (const [key, col] of Object.entries(schema)) {
843
863
  if (!(key in dataToSet) && col.onUpdateFn) {
844
- dataToSet[key] = col.onUpdateFn();
864
+ const v = col.onUpdateFn();
865
+ if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
866
+ else if (v instanceof Date) {
867
+ if (col.mode === "timestamp_ms")
868
+ dataToSet[key] = v.getTime();
869
+ else if (col.mode === "timestamp")
870
+ dataToSet[key] = Math.floor(v.getTime() / 1e3);
871
+ else dataToSet[key] = v;
872
+ } else dataToSet[key] = v;
845
873
  }
846
874
  }
847
875
  const setParts = [];
@@ -850,14 +878,25 @@ var TauriORM = class {
850
878
  if (v === void 0) continue;
851
879
  if (v && typeof v === "object" && typeof v.toSQL === "function") {
852
880
  const s = v.toSQL();
853
- setParts.push(`${k} = ${s.clause}`);
881
+ const colName = schema[k]?.name ?? k;
882
+ setParts.push(`${colName} = ${s.clause}`);
854
883
  bindings.push(...s.bindings);
855
884
  } else {
856
- setParts.push(`${k} = ?`);
857
- bindings.push(v);
885
+ const colName = schema[k]?.name ?? k;
886
+ let val = v;
887
+ const col = schema[k];
888
+ if (col && col.mode === "boolean") val = v ? 1 : 0;
889
+ else if (v instanceof Date) {
890
+ if (col && col.mode === "timestamp_ms")
891
+ val = v.getTime();
892
+ else if (col && col.mode === "timestamp")
893
+ val = Math.floor(v.getTime() / 1e3);
894
+ }
895
+ setParts.push(`${colName} = ?`);
896
+ bindings.push(val);
858
897
  }
859
898
  }
860
- let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
899
+ let query = `UPDATE ${tableName} SET ${setParts.join(", ")}`;
861
900
  if (this._from) query += ` FROM ${this._from._tableName}`;
862
901
  if (this._where) {
863
902
  if (typeof this._where.toSQL === "function") {
@@ -867,7 +906,7 @@ var TauriORM = class {
867
906
  } else {
868
907
  const entries = Object.entries(this._where);
869
908
  if (entries.length > 0) {
870
- query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
909
+ query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
871
910
  bindings.push(...entries.map(([, v]) => v));
872
911
  }
873
912
  }
@@ -933,7 +972,9 @@ var TauriORM = class {
933
972
  }
934
973
  async execute() {
935
974
  const db = await self.getDb();
936
- let query = `DELETE FROM ${this._table._tableName}`;
975
+ const tableName = this._table._tableName || this._table.tableName;
976
+ if (!tableName) throw new Error("Invalid table passed to delete(): missing _tableName");
977
+ let query = `DELETE FROM ${tableName}`;
937
978
  const bindings = [];
938
979
  if (this._where) {
939
980
  if (typeof this._where.toSQL === "function") {
@@ -943,7 +984,8 @@ var TauriORM = class {
943
984
  } else {
944
985
  const entries = Object.entries(this._where);
945
986
  if (entries.length > 0) {
946
- query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
987
+ const schema = this._table._schema;
988
+ query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
947
989
  bindings.push(...entries.map(([, v]) => v));
948
990
  }
949
991
  }
package/dist/index.mjs CHANGED
@@ -515,9 +515,11 @@ var SelectQueryBuilder = class {
515
515
  throw new Error("Cannot execute select query without a 'from' table.");
516
516
  }
517
517
  const db = await this._dbProvider();
518
+ const baseTableName = this._table._tableName || this._table.tableName;
519
+ if (!baseTableName) throw new Error("Invalid table passed to select.from(): missing _tableName");
518
520
  const bindings = [];
519
- const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${this._table._tableName}.${c.name}`).join(", ");
520
- let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${this._table._tableName}`;
521
+ const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${baseTableName}.${c.name}`).join(", ");
522
+ let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${baseTableName}`;
521
523
  if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
522
524
  if (this._where.length > 0) {
523
525
  const whereClauses = this._where.map((condition) => {
@@ -644,30 +646,46 @@ var TauriORM = class {
644
646
  }
645
647
  async execute() {
646
648
  const db = await self.getDb();
649
+ const tableName = this._table._tableName || this._table.tableName;
650
+ if (!tableName) throw new Error("Invalid table passed to insert(): missing _tableName");
647
651
  if (this._selectSql) {
648
652
  const cols = Object.keys(this._table._schema);
649
- let query = `INSERT INTO ${this._table._tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
653
+ let query = `INSERT INTO ${tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
650
654
  const bindings = [...this._selectSql.bindings];
651
655
  query += this._buildConflictClause();
652
656
  const ret = await this._executeWithReturning(db, query, bindings);
653
657
  return ret;
654
658
  }
655
659
  for (const data of this._rows) {
660
+ let coerceValue2 = function(col, value) {
661
+ if (col && col.mode === "boolean") {
662
+ return value ? 1 : 0;
663
+ }
664
+ if (value instanceof Date) {
665
+ if (col && col.mode === "timestamp_ms")
666
+ return value.getTime();
667
+ if (col && col.mode === "timestamp")
668
+ return Math.floor(value.getTime() / 1e3);
669
+ }
670
+ return value;
671
+ };
672
+ var coerceValue = coerceValue2;
656
673
  const finalData = Object.assign({}, data);
657
674
  const schema = this._table._schema;
658
675
  for (const [key, col] of Object.entries(schema)) {
659
676
  if (finalData[key] === void 0) {
660
677
  if (col.defaultFn) {
661
- finalData[key] = col.defaultFn();
678
+ finalData[key] = coerceValue2(col, col.defaultFn());
662
679
  } else if (col.onUpdateFn) {
663
- finalData[key] = col.onUpdateFn();
680
+ finalData[key] = coerceValue2(col, col.onUpdateFn());
664
681
  }
665
682
  }
666
683
  }
667
- const keys = Object.keys(finalData);
668
- const values = Object.values(finalData);
684
+ const entries = Object.entries(finalData);
685
+ const keys = entries.map(([k]) => schema[k]?.name ?? k);
686
+ const values = entries.map(([k, v]) => coerceValue2(schema[k], v));
669
687
  const placeholders = values.map(() => "?").join(", ");
670
- let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
688
+ let query = `INSERT INTO ${tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
671
689
  const bindings = [...values];
672
690
  query += this._buildConflictClause();
673
691
  const ret = await this._executeWithReturning(db, query, bindings);
@@ -759,11 +777,21 @@ var TauriORM = class {
759
777
  if (!this._data)
760
778
  throw new Error("Update requires set() before execute()");
761
779
  const db = await self.getDb();
780
+ const tableName = this._table._tableName || this._table.tableName;
781
+ if (!tableName) throw new Error("Invalid table passed to update(): missing _tableName");
762
782
  const schema = this._table._schema;
763
783
  const dataToSet = { ...this._data };
764
784
  for (const [key, col] of Object.entries(schema)) {
765
785
  if (!(key in dataToSet) && col.onUpdateFn) {
766
- dataToSet[key] = col.onUpdateFn();
786
+ const v = col.onUpdateFn();
787
+ if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
788
+ else if (v instanceof Date) {
789
+ if (col.mode === "timestamp_ms")
790
+ dataToSet[key] = v.getTime();
791
+ else if (col.mode === "timestamp")
792
+ dataToSet[key] = Math.floor(v.getTime() / 1e3);
793
+ else dataToSet[key] = v;
794
+ } else dataToSet[key] = v;
767
795
  }
768
796
  }
769
797
  const setParts = [];
@@ -772,14 +800,25 @@ var TauriORM = class {
772
800
  if (v === void 0) continue;
773
801
  if (v && typeof v === "object" && typeof v.toSQL === "function") {
774
802
  const s = v.toSQL();
775
- setParts.push(`${k} = ${s.clause}`);
803
+ const colName = schema[k]?.name ?? k;
804
+ setParts.push(`${colName} = ${s.clause}`);
776
805
  bindings.push(...s.bindings);
777
806
  } else {
778
- setParts.push(`${k} = ?`);
779
- bindings.push(v);
807
+ const colName = schema[k]?.name ?? k;
808
+ let val = v;
809
+ const col = schema[k];
810
+ if (col && col.mode === "boolean") val = v ? 1 : 0;
811
+ else if (v instanceof Date) {
812
+ if (col && col.mode === "timestamp_ms")
813
+ val = v.getTime();
814
+ else if (col && col.mode === "timestamp")
815
+ val = Math.floor(v.getTime() / 1e3);
816
+ }
817
+ setParts.push(`${colName} = ?`);
818
+ bindings.push(val);
780
819
  }
781
820
  }
782
- let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
821
+ let query = `UPDATE ${tableName} SET ${setParts.join(", ")}`;
783
822
  if (this._from) query += ` FROM ${this._from._tableName}`;
784
823
  if (this._where) {
785
824
  if (typeof this._where.toSQL === "function") {
@@ -789,7 +828,7 @@ var TauriORM = class {
789
828
  } else {
790
829
  const entries = Object.entries(this._where);
791
830
  if (entries.length > 0) {
792
- query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
831
+ query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
793
832
  bindings.push(...entries.map(([, v]) => v));
794
833
  }
795
834
  }
@@ -855,7 +894,9 @@ var TauriORM = class {
855
894
  }
856
895
  async execute() {
857
896
  const db = await self.getDb();
858
- let query = `DELETE FROM ${this._table._tableName}`;
897
+ const tableName = this._table._tableName || this._table.tableName;
898
+ if (!tableName) throw new Error("Invalid table passed to delete(): missing _tableName");
899
+ let query = `DELETE FROM ${tableName}`;
859
900
  const bindings = [];
860
901
  if (this._where) {
861
902
  if (typeof this._where.toSQL === "function") {
@@ -865,7 +906,8 @@ var TauriORM = class {
865
906
  } else {
866
907
  const entries = Object.entries(this._where);
867
908
  if (entries.length > 0) {
868
- query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
909
+ const schema = this._table._schema;
910
+ query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
869
911
  bindings.push(...entries.map(([, v]) => v));
870
912
  }
871
913
  }
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@type32/tauri-sqlite-orm",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "A Drizzle-like ORM for Tauri v2's SQL JS API plugin.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "tauriorm-kit": "./dist/cli.mjs"
10
+ },
8
11
  "exports": {
9
12
  ".": {
10
13
  "import": "./dist/index.mjs",
@@ -15,8 +18,8 @@
15
18
  "dist"
16
19
  ],
17
20
  "scripts": {
18
- "build": "tsup src/index.ts --format esm,cjs --dts",
19
- "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
21
+ "build": "tsup src/index.ts src/cli.ts --format esm,cjs --dts",
22
+ "dev": "tsup src/index.ts src/cli.ts --format esm,cjs --dts --watch",
20
23
  "test": "echo \"Error: no test specified\" && exit 1"
21
24
  },
22
25
  "keywords": [