durcno 1.0.0-alpha.3 → 1.0.0-alpha.5

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.
Files changed (72) hide show
  1. package/README.md +4 -6
  2. package/dist/bin.cjs +36 -33
  3. package/dist/src/columns/common.d.mts +2 -1
  4. package/dist/src/columns/enum.d.mts +1 -1
  5. package/dist/src/columns/postgis/geography/linestring.d.mts +1 -0
  6. package/dist/src/columns/postgis/geography/multilinestring.d.mts +1 -0
  7. package/dist/src/columns/postgis/geography/multipoint.d.mts +1 -0
  8. package/dist/src/columns/postgis/geography/multipolygon.d.mts +1 -0
  9. package/dist/src/columns/postgis/geography/point.d.mts +1 -0
  10. package/dist/src/columns/postgis/geography/polygon.d.mts +1 -0
  11. package/dist/src/connectors/common.d.mts +19 -1
  12. package/dist/src/connectors/common.mjs +17 -0
  13. package/dist/src/connectors/pglite.d.mts +8 -0
  14. package/dist/src/connectors/pglite.mjs +8 -0
  15. package/dist/src/constraints/check.d.mts +1 -0
  16. package/dist/src/constraints/primary-key.d.mts +1 -0
  17. package/dist/src/constraints/unique.d.mts +1 -0
  18. package/dist/src/db.d.mts +17 -17
  19. package/dist/src/db.mjs +8 -8
  20. package/dist/src/filters/array.d.mts +2 -2
  21. package/dist/src/filters/array.mjs +10 -23
  22. package/dist/src/filters/custom.d.mts +1 -1
  23. package/dist/src/filters/index.d.mts +4 -3
  24. package/dist/src/index.d.mts +10 -18
  25. package/dist/src/indexes.d.mts +1 -0
  26. package/dist/src/logger.d.mts +8 -4
  27. package/dist/src/logger.mjs +8 -4
  28. package/dist/src/migration/ddl/enum.d.mts +100 -0
  29. package/dist/src/migration/ddl/enum.mjs +138 -0
  30. package/dist/src/migration/ddl/index.d.mts +211 -0
  31. package/dist/src/migration/ddl/index.mjs +81 -0
  32. package/dist/src/migration/ddl/indexes.d.mts +110 -0
  33. package/dist/src/migration/ddl/indexes.mjs +151 -0
  34. package/dist/src/migration/ddl/schema.d.mts +56 -0
  35. package/dist/src/migration/ddl/schema.mjs +62 -0
  36. package/dist/src/migration/ddl/sequence.d.mts +77 -0
  37. package/dist/src/migration/ddl/sequence.mjs +86 -0
  38. package/dist/src/migration/{statement.d.mts → ddl/statement.d.mts} +13 -10
  39. package/dist/src/migration/{statement.mjs → ddl/statement.mjs} +4 -4
  40. package/dist/src/migration/ddl/table.d.mts +305 -0
  41. package/dist/src/migration/{ddl.mjs → ddl/table.mjs} +8 -493
  42. package/dist/src/migration/ddl/types.d.mts +117 -0
  43. package/dist/src/migration/ddl/types.mjs +187 -0
  44. package/dist/src/migration/index.d.mts +2 -2
  45. package/dist/src/migration/index.mjs +2 -2
  46. package/dist/src/migration/snapshot.d.mts +1 -1
  47. package/dist/src/models.d.mts +1 -1
  48. package/dist/src/query-builders/aggregates.d.mts +5 -4
  49. package/dist/src/query-builders/aggregates.mjs +5 -2
  50. package/dist/src/query-builders/count.d.mts +4 -4
  51. package/dist/src/query-builders/count.mjs +5 -2
  52. package/dist/src/query-builders/delete.d.mts +3 -2
  53. package/dist/src/query-builders/distinct.d.mts +5 -4
  54. package/dist/src/query-builders/distinct.mjs +5 -2
  55. package/dist/src/query-builders/exists.d.mts +4 -4
  56. package/dist/src/query-builders/exists.mjs +5 -2
  57. package/dist/src/query-builders/first.d.mts +4 -4
  58. package/dist/src/query-builders/first.mjs +5 -2
  59. package/dist/src/query-builders/insert-returning.d.mts +2 -2
  60. package/dist/src/query-builders/insert.d.mts +3 -2
  61. package/dist/src/query-builders/insert.mjs +17 -27
  62. package/dist/src/query-builders/orderby-clause.d.mts +1 -0
  63. package/dist/src/query-builders/pre.d.mts +2 -2
  64. package/dist/src/query-builders/raw.d.mts +1 -1
  65. package/dist/src/query-builders/rq.d.mts +2 -2
  66. package/dist/src/query-builders/select.d.mts +3 -2
  67. package/dist/src/query-builders/update.d.mts +3 -2
  68. package/dist/src/sql.d.mts +1 -1
  69. package/dist/src/table.d.mts +3 -3
  70. package/dist/src/types.d.mts +8 -1
  71. package/package.json +4 -4
  72. package/dist/src/migration/ddl.d.mts +0 -764
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  <p align="center">
2
- <a href="https://npmjs.com/package/durcno" target="_blank">
3
- <img src="https://img.shields.io/npm/v/durcno?style=flat&logo=npm&color=339933" alt="npm version" />
4
- </a>
5
- <img src="https://img.shields.io/badge/Node.js-24%2B-339933?style=flat&logo=node.js&logoColor=white" alt="Node.js 24+" />
2
+ <img alt="NPM Downloads" src="https://img.shields.io/npm/dw/durcno" alt="Downloads" />
3
+ <img src="https://img.shields.io/badge/Node.js-24%2B-339935?style=flat&logo=node.js&logoColor=white" alt="Node.js 24+" />
6
4
  <img src="https://img.shields.io/badge/PostgreSQL-14%2B-336791?style=flat&logo=postgresql&logoColor=white" alt="PostgreSQL 14+" />
7
5
  <img src="https://img.shields.io/badge/License-Apache%202.0-blue?style=flat" alt="License" />
8
6
  <img src="https://img.shields.io/badge/vitest--green?logo=vitest" alt="License" />
@@ -31,7 +29,7 @@
31
29
  ## Setup
32
30
 
33
31
  ```bash
34
- npm install durcno
32
+ npm add durcno@alpha
35
33
  ```
36
34
 
37
35
  ```bash
@@ -42,7 +40,7 @@ npm exec durcno init
42
40
 
43
41
  Get started with Durcno by following our comprehensive documentation.
44
42
 
45
- **[Read the Documentation](https://durcno.dev/docs)**
43
+ **[Read the Documentation](https://durcno.dev/docs/latest/intro)**
46
44
 
47
45
  > [!WARNING]
48
46
  > Durcno is currently in the alpha stage.
package/dist/bin.cjs CHANGED
@@ -8961,25 +8961,24 @@ async function runDownMigration(migrationDirName, isFirstMigration, migrationsDi
8961
8961
  const options = migrationModule.options ?? {};
8962
8962
  const useTransaction = options.transaction ?? true;
8963
8963
  const execution = options.execution ?? "joined";
8964
- if (useTransaction) {
8965
- await client.query("BEGIN;");
8966
- }
8967
8964
  try {
8968
8965
  if (statements.length > 0) {
8969
8966
  if (execution === "sequential") {
8967
+ if (useTransaction) await client.query("BEGIN;");
8970
8968
  for (const st of statements) {
8971
8969
  await client.query(st.toSQL());
8972
8970
  }
8971
+ if (useTransaction) await client.query("COMMIT;");
8973
8972
  } else {
8974
- const sql = `${statements.map((st) => st.toSQL()).join("\n")}`;
8973
+ let sql = "";
8974
+ if (useTransaction) sql += "BEGIN;\n";
8975
+ sql += statements.map((st) => st.toSQL()).join("\n");
8976
+ if (useTransaction) sql += "\nCOMMIT;";
8975
8977
  await client.query(sql);
8976
8978
  }
8977
8979
  }
8978
- if (useTransaction) {
8979
- await client.query("COMMIT;");
8980
- }
8981
8980
  } catch (e) {
8982
- if (useTransaction) {
8981
+ if (useTransaction && execution === "sequential") {
8983
8982
  await client.query("ROLLBACK;");
8984
8983
  }
8985
8984
  throw e;
@@ -12275,12 +12274,14 @@ async function generate(options) {
12275
12274
  ssCurrent,
12276
12275
  renamedTables
12277
12276
  );
12277
+ const connectorMigrationOpts = config2.connector.constructor.migrationOptions;
12278
12278
  const migrationUpTs = generateMigration(
12279
12279
  ssPrevious,
12280
12280
  ssCurrent,
12281
12281
  "up",
12282
12282
  renamedTables,
12283
- renamedColumns
12283
+ renamedColumns,
12284
+ connectorMigrationOpts
12284
12285
  );
12285
12286
  const reverseRenamedTables = {};
12286
12287
  for (const [oldKey, newKey] of Object.entries(renamedTables)) {
@@ -12299,7 +12300,8 @@ async function generate(options) {
12299
12300
  ssPrevious,
12300
12301
  "down",
12301
12302
  reverseRenamedTables,
12302
- reverseRenamedColumns
12303
+ reverseRenamedColumns,
12304
+ connectorMigrationOpts
12303
12305
  );
12304
12306
  if (migrationUpTs === null) {
12305
12307
  console.log(yellow3("No changes detected. Skipping migration creation."));
@@ -12311,14 +12313,14 @@ async function generate(options) {
12311
12313
  (0, import_node_fs2.writeFileSync)((0, import_node_path4.resolve)(migrationDir, "up.ts"), migrationUpTs);
12312
12314
  (0, import_node_fs2.writeFileSync)(
12313
12315
  (0, import_node_path4.resolve)(migrationDir, "down.ts"),
12314
- migrationDnTs ?? generateNoOpMigration()
12316
+ migrationDnTs ?? generateNoOpMigration(connectorMigrationOpts)
12315
12317
  );
12316
12318
  const migrationsRelativePath = (0, import_node_path4.relative)(process.cwd(), migrationsDir);
12317
12319
  console.log(
12318
12320
  `${bgGreen2.white.bold("[CREATED]")} ${cyan3(migrationName)} at ${cyan3(`${migrationsRelativePath}/`)}`
12319
12321
  );
12320
12322
  }
12321
- function generateMigration(prev, curr, direction, renamedTables = {}, renamedColumns = {}) {
12323
+ function generateMigration(prev, curr, direction, renamedTables = {}, renamedColumns = {}, defaultOptions) {
12322
12324
  const statements = [];
12323
12325
  const renamedFromKeys = new Set(Object.keys(renamedTables));
12324
12326
  const renamedToKeys = new Set(Object.values(renamedTables));
@@ -12351,7 +12353,7 @@ function generateMigration(prev, curr, direction, renamedTables = {}, renamedCol
12351
12353
  for (const enumName in prev.enums) {
12352
12354
  if (!(enumName in curr.enums)) {
12353
12355
  const enm = prev.enums[enumName];
12354
- statements.push(`ddl.dropEnum("${enm.schema}", "${enm.name}")`);
12356
+ statements.push(`ddl.dropType("${enm.schema}", "${enm.name}")`);
12355
12357
  }
12356
12358
  }
12357
12359
  for (const enumName in curr.enums) {
@@ -12359,7 +12361,7 @@ function generateMigration(prev, curr, direction, renamedTables = {}, renamedCol
12359
12361
  const enm = curr.enums[enumName];
12360
12362
  const values = enm.values.map((v) => `"${v}"`).join(", ");
12361
12363
  statements.push(
12362
- `ddl.createEnum("${enm.schema}", "${enm.name}", [${values}])`
12364
+ `ddl.createType("${enm.schema}", "${enm.name}", { asEnum: [${values}] })`
12363
12365
  );
12364
12366
  } else {
12365
12367
  const prevValues = prev.enums[enumName].values;
@@ -12417,15 +12419,15 @@ function generateMigration(prev, curr, direction, renamedTables = {}, renamedCol
12417
12419
  }
12418
12420
  if (afterValue !== null) {
12419
12421
  statements.push(
12420
- `ddl.alterEnumAddValue("${enm.schema}", "${enm.name}", "${addedValue}", { after: "${afterValue}" })`
12422
+ `ddl.alterType("${enm.schema}", "${enm.name}").addValue("${addedValue}", { after: "${afterValue}" })`
12421
12423
  );
12422
12424
  } else if (beforeValue !== null) {
12423
12425
  statements.push(
12424
- `ddl.alterEnumAddValue("${enm.schema}", "${enm.name}", "${addedValue}", { before: "${beforeValue}" })`
12426
+ `ddl.alterType("${enm.schema}", "${enm.name}").addValue("${addedValue}", { before: "${beforeValue}" })`
12425
12427
  );
12426
12428
  } else {
12427
12429
  statements.push(
12428
- `ddl.alterEnumAddValue("${enm.schema}", "${enm.name}", "${addedValue}")`
12430
+ `ddl.alterType("${enm.schema}", "${enm.name}").addValue("${addedValue}")`
12429
12431
  );
12430
12432
  }
12431
12433
  }
@@ -12524,25 +12526,25 @@ function generateMigration(prev, curr, direction, renamedTables = {}, renamedCol
12524
12526
  if (statements.length === 0) return null;
12525
12527
  return `import { type DDLStatement, ddl, type MigrationOptions } from "durcno/migration";
12526
12528
 
12527
- export const options: MigrationOptions = {
12528
- transaction: true,
12529
- };
12529
+ export const options: MigrationOptions = ${stringifyMigrationOpts(defaultOptions ?? { transaction: true })};
12530
12530
 
12531
12531
  export const statements: DDLStatement[] = [
12532
12532
  ${statements.join(",\n ")},
12533
12533
  ];
12534
12534
  `;
12535
12535
  }
12536
- function generateNoOpMigration() {
12536
+ function generateNoOpMigration(defaultOptions) {
12537
12537
  return `import { type DDLStatement, ddl, type MigrationOptions } from "durcno/migration";
12538
12538
 
12539
- export const options: MigrationOptions = {
12540
- transaction: true,
12541
- };
12539
+ export const options: MigrationOptions = ${stringifyMigrationOpts(defaultOptions ?? { transaction: true })};
12542
12540
 
12543
12541
  export const statements: DDLStatement[] = [];
12544
12542
  `;
12545
12543
  }
12544
+ function stringifyMigrationOpts(opts) {
12545
+ if (opts.transaction === void 0) opts.transaction = true;
12546
+ return JSON.stringify(opts, null, 2);
12547
+ }
12546
12548
  function generateAlterTableStmts(prevTable, currTable, tableName, curr, statements, columnRenames) {
12547
12549
  const alterStatements = [];
12548
12550
  const renamedFromCols = new Set(
@@ -13060,23 +13062,22 @@ async function runUpMigration(migrationDirName, migrationsDir, client, config2)
13060
13062
  const options = migrationModule.options ?? {};
13061
13063
  const useTransaction = options.transaction ?? true;
13062
13064
  const execution = options.execution ?? "joined";
13063
- if (useTransaction) {
13064
- await client.query("BEGIN;");
13065
- }
13066
13065
  try {
13067
13066
  if (statements.length > 0) {
13068
13067
  if (execution === "sequential") {
13068
+ if (useTransaction) await client.query("BEGIN;");
13069
13069
  for (const st of statements) {
13070
13070
  await client.query(st.toSQL());
13071
13071
  }
13072
+ if (useTransaction) await client.query("COMMIT;");
13072
13073
  } else {
13073
- const sql = `${statements.map((st) => st.toSQL()).join("\n")}`;
13074
+ let sql = "";
13075
+ if (useTransaction) sql += "BEGIN;\n";
13076
+ sql += statements.map((st) => st.toSQL()).join("\n");
13077
+ if (useTransaction) sql += "\nCOMMIT;";
13074
13078
  await client.query(sql);
13075
13079
  }
13076
13080
  }
13077
- if (useTransaction) {
13078
- await client.query("COMMIT;");
13079
- }
13080
13081
  console.log(
13081
13082
  bgGreen3.white.bold("[APPLIED]") + " " + green2(`Migration ${cyan5(migrationDirName)}`) + dim3(".")
13082
13083
  );
@@ -13089,7 +13090,7 @@ async function runUpMigration(migrationDirName, migrationsDir, client, config2)
13089
13090
  });
13090
13091
  await db.close();
13091
13092
  } catch (e) {
13092
- if (useTransaction) {
13093
+ if (useTransaction && execution === "sequential") {
13093
13094
  await client.query("ROLLBACK;");
13094
13095
  }
13095
13096
  throw e;
@@ -13472,6 +13473,8 @@ async function status(options) {
13472
13473
  console.log(source_default.yellow("No migrations found."));
13473
13474
  process.exit(0);
13474
13475
  }
13476
+ connector.pool = { ...connector.pool, max: 1 };
13477
+ connector.logger = void 0;
13475
13478
  const db = (0, import_durcno4.database)({ Migrations: import_durcno4.Migrations }, config2);
13476
13479
  const migrationsQuery = db.from(import_durcno4.Migrations).select();
13477
13480
  let migrations;
@@ -13505,7 +13508,7 @@ async function status(options) {
13505
13508
  }
13506
13509
 
13507
13510
  // src/cli/index.ts
13508
- program.version("1.0.0-alpha.2");
13511
+ program.version("1.0.0-alpha.4");
13509
13512
  var Options = {
13510
13513
  config: ["--config <path>", "Path to the config file"]
13511
13514
  };
@@ -1,7 +1,8 @@
1
+ import { Key } from "../types.mjs";
1
2
  import { Sql } from "../sql.mjs";
2
3
  import { entityType } from "../symbols.mjs";
3
- import { StdTableColumn, TableColumn } from "../table.mjs";
4
4
  import { Arg } from "../query-builders/pre.mjs";
5
+ import { StdTableColumn, TableColumn } from "../table.mjs";
5
6
  import * as z from "zod";
6
7
 
7
8
  //#region src/columns/common.d.ts
@@ -1,6 +1,6 @@
1
1
  import { Sql } from "../sql.mjs";
2
- import { Column, ColumnConfig } from "./common.mjs";
3
2
  import { Enum } from "../enumtype.mjs";
3
+ import { Column, ColumnConfig } from "./common.mjs";
4
4
  import * as z from "zod";
5
5
 
6
6
  //#region src/columns/enum.d.ts
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,3 +1,4 @@
1
+ import { SelfOrReadonly } from "../../../types.mjs";
1
2
  import { Sql } from "../../../sql.mjs";
2
3
  import { Column, ColumnConfig } from "../../common.mjs";
3
4
  import * as z from "zod";
@@ -1,5 +1,6 @@
1
1
  import { DurcnoLogger } from "../logger.mjs";
2
2
  import { Query } from "../query-builders/query.mjs";
3
+ import { MigrationOptions } from "../migration/index.mjs";
3
4
  import { ConnectionOptions } from "node:tls";
4
5
 
5
6
  //#region src/connectors/common.d.ts
@@ -55,6 +56,23 @@ type ConnectorOptions = {
55
56
  * @abstract
56
57
  */
57
58
  declare abstract class Connector {
59
+ /**
60
+ * Default migration options applied to generated migration files for this
61
+ * connector. When set, the `generate` CLI command will use these values as
62
+ * the `options` export in the produced `up.ts` / `down.ts` files instead of
63
+ * the built-in defaults.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * class MyConnector extends Connector {
68
+ * static override migrationOptions: MigrationOptions = {
69
+ * transaction: false,
70
+ * execution: "sequential",
71
+ * };
72
+ * }
73
+ * ```
74
+ */
75
+ static migrationOptions?: MigrationOptions;
58
76
  /**
59
77
  * The original options passed to the connector constructor.
60
78
  * Provides full access to `dbCredentials`, `pool`, and `logger`.
@@ -207,4 +225,4 @@ declare abstract class $Pool extends $QueryExecutor {
207
225
  */
208
226
  type QueryExecutor = $Client | $Pool;
209
227
  //#endregion
210
- export { $Pool, Connector, ConnectorOptions, QueryExecutor };
228
+ export { $Client, $Pool, Connector, ConnectorOptions, QueryExecutor };
@@ -30,6 +30,23 @@ function getUrlFromDbCredentials(dbCredentials) {
30
30
  * @abstract
31
31
  */
32
32
  var Connector = class {
33
+ /**
34
+ * Default migration options applied to generated migration files for this
35
+ * connector. When set, the `generate` CLI command will use these values as
36
+ * the `options` export in the produced `up.ts` / `down.ts` files instead of
37
+ * the built-in defaults.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * class MyConnector extends Connector {
42
+ * static override migrationOptions: MigrationOptions = {
43
+ * transaction: false,
44
+ * execution: "sequential",
45
+ * };
46
+ * }
47
+ * ```
48
+ */
49
+ static migrationOptions;
33
50
  /**
34
51
  * The original options passed to the connector constructor.
35
52
  * Provides full access to `dbCredentials`, `pool`, and `logger`.
@@ -14,6 +14,14 @@ import { PGliteOptions } from "@electric-sql/pglite";
14
14
  */
15
15
  declare class PgLiteConnector extends Connector {
16
16
  #private;
17
+ /**
18
+ * PGlite does not support DDL statements inside transactions and requires
19
+ * sequential execution, so migrations are generated with these defaults.
20
+ */
21
+ static migrationOptions: {
22
+ transaction: boolean;
23
+ execution: "sequential";
24
+ };
17
25
  constructor(options: ConnectorOptions, driverOptions?: PGliteOptions);
18
26
  getClient(): PgLiteClient;
19
27
  getPool(): PgLitePool;
@@ -12,6 +12,14 @@ import { PGlite } from "@electric-sql/pglite";
12
12
  * @see https://www.npmjs.com/package/@electric-sql/pglite
13
13
  */
14
14
  var PgLiteConnector = class extends Connector {
15
+ /**
16
+ * PGlite does not support DDL statements inside transactions and requires
17
+ * sequential execution, so migrations are generated with these defaults.
18
+ */
19
+ static migrationOptions = {
20
+ transaction: false,
21
+ execution: "sequential"
22
+ };
15
23
  #driverOptions;
16
24
  constructor(options, driverOptions) {
17
25
  super(options);
@@ -1,3 +1,4 @@
1
+ import { Key } from "../types.mjs";
1
2
  import { AnyColumn, TableColumn } from "../table.mjs";
2
3
 
3
4
  //#region src/constraints/check.d.ts
@@ -1,3 +1,4 @@
1
+ import { Key } from "../types.mjs";
1
2
  import { AnyColumn, AnyTableWithColumns, TableColumn } from "../table.mjs";
2
3
 
3
4
  //#region src/constraints/primary-key.d.ts
@@ -1,3 +1,4 @@
1
+ import { Key } from "../types.mjs";
1
2
  import { AnyColumn, AnyTableWithColumns, TableColumn } from "../table.mjs";
2
3
 
3
4
  //#region src/constraints/unique.d.ts
package/dist/src/db.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- import { AnyColumn, AnyRelations, IsTableWC, Relations, TColsToLeftRight, TableWCorNever, TableWithColumns } from "./table.mjs";
2
1
  import { SelectBuilder } from "./query-builders/select.mjs";
3
2
  import { BuildFilterExpression } from "./filters/index.mjs";
4
3
  import { Config } from "./index.mjs";
@@ -13,6 +12,7 @@ import { InsertReturningQuery } from "./query-builders/insert-returning.mjs";
13
12
  import { RawQuery } from "./query-builders/raw.mjs";
14
13
  import { RelationQueryBuilder } from "./query-builders/rq.mjs";
15
14
  import { UpdateBuilder } from "./query-builders/update.mjs";
15
+ import { AnyColumn, AnyRelations, IsTableWC, Relations, TColsToLeftRight, TableWCorNever, TableWithColumns } from "./table.mjs";
16
16
  import { $Pool, QueryExecutor } from "./connectors/common.mjs";
17
17
 
18
18
  //#region src/db.d.ts
@@ -60,24 +60,24 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
60
60
  * @param where Optional where clause to filter rows
61
61
  * @returns Promise<number> - the count of matching rows
62
62
  */
63
- $count<TTable extends TTables[keyof TTables]>(table: TTable): CountQuery<TTable>;
64
- $count<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, where: TWhere): CountQuery<TTable>;
63
+ $count<TTable extends TTables[keyof TTables]>(table: TTable): CountQuery<TTable, TPrepare>;
64
+ $count<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, where: TWhere): CountQuery<TTable, TPrepare>;
65
65
  /**
66
66
  * Check if any rows exist in a table, optionally filtered by a where clause.
67
67
  * @param table The table to check
68
68
  * @param where Optional where clause to filter rows
69
69
  * @returns Promise<boolean> - true if at least one row exists
70
70
  */
71
- $exists<TTable extends TTables[keyof TTables]>(table: TTable): ExistsQuery<TTable>;
72
- $exists<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, where: TWhere): ExistsQuery<TTable>;
71
+ $exists<TTable extends TTables[keyof TTables]>(table: TTable): ExistsQuery<TTable, TPrepare>;
72
+ $exists<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, where: TWhere): ExistsQuery<TTable, TPrepare>;
73
73
  /**
74
74
  * Get the first row from a table, optionally filtered by a where clause.
75
75
  * @param table The table to query
76
76
  * @param where Optional where clause to filter rows
77
77
  * @returns Promise<T | null> - the first row or null if no rows match
78
78
  */
79
- $first<TTable extends TTables[keyof TTables]>(table: TTable): FirstQuery<TTable>;
80
- $first<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, where: TWhere): FirstQuery<TTable>;
79
+ $first<TTable extends TTables[keyof TTables]>(table: TTable): FirstQuery<TTable, TPrepare>;
80
+ $first<TTable extends TTables[keyof TTables], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, where: TWhere): FirstQuery<TTable, TPrepare>;
81
81
  /**
82
82
  * Calculate the sum of a numeric column.
83
83
  * @param table The table to query
@@ -85,8 +85,8 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
85
85
  * @param where Optional where clause to filter rows
86
86
  * @returns Promise<number | null> - the sum or null if no rows match
87
87
  */
88
- $sum<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null>;
89
- $sum<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null>;
88
+ $sum<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
89
+ $sum<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
90
90
  /**
91
91
  * Calculate the average of a numeric column.
92
92
  * @param table The table to query
@@ -94,8 +94,8 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
94
94
  * @param where Optional where clause to filter rows
95
95
  * @returns Promise<number | null> - the average or null if no rows match
96
96
  */
97
- $avg<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null>;
98
- $avg<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null>;
97
+ $avg<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
98
+ $avg<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
99
99
  /**
100
100
  * Find the minimum value of a column.
101
101
  * @param table The table to query
@@ -103,8 +103,8 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
103
103
  * @param where Optional where clause to filter rows
104
104
  * @returns Promise<number | null> - the minimum value or null if no rows match
105
105
  */
106
- $min<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null>;
107
- $min<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null>;
106
+ $min<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
107
+ $min<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
108
108
  /**
109
109
  * Find the maximum value of a column.
110
110
  * @param table The table to query
@@ -112,8 +112,8 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
112
112
  * @param where Optional where clause to filter rows
113
113
  * @returns Promise<number | null> - the maximum value or null if no rows match
114
114
  */
115
- $max<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null>;
116
- $max<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null>;
115
+ $max<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
116
+ $max<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, column: TColumn, where: TWhere): AggregateQuery<TTable, TColumn, number | null, TPrepare>;
117
117
  /**
118
118
  * Get distinct values of a column.
119
119
  * @param table The table to query
@@ -121,8 +121,8 @@ declare class Base<TTName extends string, TTables extends Record<TTName, TableWi
121
121
  * @param where Optional where clause to filter rows
122
122
  * @returns Promise<T[]> - array of distinct values
123
123
  */
124
- $distinct<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): DistinctQuery<TTable, TColumn, TColumn["ValTypeSelect"][]>;
125
- $distinct<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>>>(table: TTable, column: TColumn, where: TWhere): DistinctQuery<TTable, TColumn, TColumn["ValTypeSelect"][]>;
124
+ $distinct<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]]>(table: TTable, column: TColumn): DistinctQuery<TTable, TColumn, TColumn["ValTypeSelect"][], TPrepare>;
125
+ $distinct<TTable extends TTables[keyof TTables], TColumn extends TTable["_"]["columns"][keyof TTable["_"]["columns"]], TWhere extends BuildFilterExpression<TColsToLeftRight<TTable["_"]["columns"]>, TPrepare>>(table: TTable, column: TColumn, where: TWhere): DistinctQuery<TTable, TColumn, TColumn["ValTypeSelect"][], TPrepare>;
126
126
  /**
127
127
  * Insert a row and return the inserted row with all columns.
128
128
  * @param table The table to insert into
package/dist/src/db.mjs CHANGED
@@ -67,28 +67,28 @@ var Base = class {
67
67
  return new DeleteQuery(table, void 0, void 0, this.#getExecutor(), this.$.pre);
68
68
  }
69
69
  $count(table, where) {
70
- return new CountQuery(table, where, this.#getExecutor());
70
+ return new CountQuery(table, where, this.#getExecutor(), this.$.pre);
71
71
  }
72
72
  $exists(table, where) {
73
- return new ExistsQuery(table, where, this.#getExecutor());
73
+ return new ExistsQuery(table, where, this.#getExecutor(), this.$.pre);
74
74
  }
75
75
  $first(table, where) {
76
- return new FirstQuery(table, where, this.#getExecutor());
76
+ return new FirstQuery(table, where, this.#getExecutor(), this.$.pre);
77
77
  }
78
78
  $sum(table, column, where) {
79
- return new AggregateQuery(table, column, "SUM", where, this.#getExecutor());
79
+ return new AggregateQuery(table, column, "SUM", where, this.#getExecutor(), this.$.pre);
80
80
  }
81
81
  $avg(table, column, where) {
82
- return new AggregateQuery(table, column, "AVG", where, this.#getExecutor());
82
+ return new AggregateQuery(table, column, "AVG", where, this.#getExecutor(), this.$.pre);
83
83
  }
84
84
  $min(table, column, where) {
85
- return new AggregateQuery(table, column, "MIN", where, this.#getExecutor());
85
+ return new AggregateQuery(table, column, "MIN", where, this.#getExecutor(), this.$.pre);
86
86
  }
87
87
  $max(table, column, where) {
88
- return new AggregateQuery(table, column, "MAX", where, this.#getExecutor());
88
+ return new AggregateQuery(table, column, "MAX", where, this.#getExecutor(), this.$.pre);
89
89
  }
90
90
  $distinct(table, column, where) {
91
- return new DistinctQuery(table, column, where, this.#getExecutor());
91
+ return new DistinctQuery(table, column, where, this.#getExecutor(), this.$.pre);
92
92
  }
93
93
  /**
94
94
  * Insert a row and return the inserted row with all columns.
@@ -1,6 +1,6 @@
1
- import { AnyColumn, TableColumn } from "../table.mjs";
2
- import { Filter } from "./custom.mjs";
3
1
  import { Query } from "../query-builders/query.mjs";
2
+ import { Filter } from "./custom.mjs";
3
+ import { AnyColumn, TableColumn } from "../table.mjs";
4
4
 
5
5
  //#region src/filters/array.d.ts
6
6
  /** Shorthand for the Filter's TableColumn constraint. */
@@ -1,18 +1,5 @@
1
1
  import { Filter } from "./custom.mjs";
2
2
  //#region src/filters/array.ts
3
- /** Converts an array of values to a PostgreSQL array literal. */
4
- function arrayToSql(values) {
5
- if (values.length === 0) return "'{}'";
6
- return `ARRAY[${values.map((v) => {
7
- if (typeof v === "string") return `'${v.replace(/'/g, "''")}'`;
8
- return String(v);
9
- }).join(", ")}]`;
10
- }
11
- /** Converts a single value to a SQL literal. */
12
- function valueToSql(value) {
13
- if (typeof value === "string") return `'${value.replace(/'/g, "''")}'`;
14
- return String(value);
15
- }
16
3
  /**
17
4
  * ArrayContains filter: col @> ARRAY[values]
18
5
  * Returns true if the array column contains all the specified values.
@@ -26,10 +13,10 @@ var ArrayContainsFilter = class extends Filter {
26
13
  this.right = values;
27
14
  }
28
15
  toSQL() {
29
- return `${this.left.fullName} @> ${arrayToSql(this.right)}`;
16
+ return `${this.left.fullName} @> ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
30
17
  }
31
18
  toQuery(query) {
32
- query.sql += `${this.left.fullName} @> ${arrayToSql(this.right)}`;
19
+ query.sql += `${this.left.fullName} @> ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
33
20
  }
34
21
  };
35
22
  /**
@@ -55,10 +42,10 @@ var ArrayContainedByFilter = class extends Filter {
55
42
  this.right = values;
56
43
  }
57
44
  toSQL() {
58
- return `${this.left.fullName} <@ ${arrayToSql(this.right)}`;
45
+ return `${this.left.fullName} <@ ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
59
46
  }
60
47
  toQuery(query) {
61
- query.sql += `${this.left.fullName} <@ ${arrayToSql(this.right)}`;
48
+ query.sql += `${this.left.fullName} <@ ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
62
49
  }
63
50
  };
64
51
  /**
@@ -81,10 +68,10 @@ var ArrayOverlapsFilter = class extends Filter {
81
68
  this.right = values;
82
69
  }
83
70
  toSQL() {
84
- return `${this.left.fullName} && ${arrayToSql(this.right)}`;
71
+ return `${this.left.fullName} && ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
85
72
  }
86
73
  toQuery(query) {
87
- query.sql += `${this.left.fullName} && ${arrayToSql(this.right)}`;
74
+ query.sql += `${this.left.fullName} && ${this.left.toSQL(this.right)}::${this.left.sqlType}`;
88
75
  }
89
76
  };
90
77
  /**
@@ -107,10 +94,10 @@ var ArrayHasFilter = class extends Filter {
107
94
  this.right = value;
108
95
  }
109
96
  toSQL() {
110
- return `${valueToSql(this.right)} = ANY(${this.left.fullName})`;
97
+ return `${this.left.toSQLScalar(this.right)} = ANY(${this.left.fullName})`;
111
98
  }
112
99
  toQuery(query) {
113
- query.sql += `${valueToSql(this.right)} = ANY(${this.left.fullName})`;
100
+ query.sql += `${this.left.toSQLScalar(this.right)} = ANY(${this.left.fullName})`;
114
101
  }
115
102
  };
116
103
  /**
@@ -133,10 +120,10 @@ var ArrayAllFilter = class extends Filter {
133
120
  this.right = value;
134
121
  }
135
122
  toSQL() {
136
- return `${valueToSql(this.right)} = ALL(${this.left.fullName})`;
123
+ return `${this.left.toSQLScalar(this.right)} = ALL(${this.left.fullName})`;
137
124
  }
138
125
  toQuery(query) {
139
- query.sql += `${valueToSql(this.right)} = ALL(${this.left.fullName})`;
126
+ query.sql += `${this.left.toSQLScalar(this.right)} = ALL(${this.left.fullName})`;
140
127
  }
141
128
  };
142
129
  /**
@@ -1,5 +1,5 @@
1
- import { AnyColumn, TableColumn } from "../table.mjs";
2
1
  import { Query } from "../query-builders/query.mjs";
2
+ import { AnyColumn, TableColumn } from "../table.mjs";
3
3
 
4
4
  //#region src/filters/custom.d.ts
5
5
  /** Abstract base class for SQL filter expressions used in `WHERE`/`ON` clauses. */