durcno 1.0.0-alpha.10 → 1.0.0-alpha.12

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 (71) hide show
  1. package/dist/bin.cjs +54 -5
  2. package/dist/src/columns/common.d.mts +76 -32
  3. package/dist/src/columns/common.mjs +77 -20
  4. package/dist/src/columns/enum.mjs +1 -1
  5. package/dist/src/constraints/check.d.mts +8 -3
  6. package/dist/src/constraints/check.mjs +24 -34
  7. package/dist/src/constraints/primary-key.d.mts +7 -4
  8. package/dist/src/constraints/primary-key.mjs +8 -5
  9. package/dist/src/constraints/unique.d.mts +9 -7
  10. package/dist/src/constraints/unique.mjs +8 -5
  11. package/dist/src/db.d.mts +2 -2
  12. package/dist/src/entity.mjs +1 -1
  13. package/dist/src/enumtype.d.mts +13 -5
  14. package/dist/src/enumtype.mjs +18 -16
  15. package/dist/src/filters/array.d.mts +6 -6
  16. package/dist/src/filters/array.mjs +17 -10
  17. package/dist/src/filters/index.d.mts +10 -10
  18. package/dist/src/filters/index.mjs +25 -20
  19. package/dist/src/filters/postgis.d.mts +7 -7
  20. package/dist/src/filters/postgis.mjs +16 -8
  21. package/dist/src/filters/string.d.mts +7 -7
  22. package/dist/src/filters/string.mjs +13 -8
  23. package/dist/src/functions/aggregate.d.mts +8 -8
  24. package/dist/src/functions/aggregate.mjs +13 -13
  25. package/dist/src/functions/index.d.mts +2 -2
  26. package/dist/src/functions/numeric.d.mts +6 -6
  27. package/dist/src/functions/numeric.mjs +10 -10
  28. package/dist/src/functions/postgis.d.mts +2 -2
  29. package/dist/src/functions/postgis.mjs +4 -2
  30. package/dist/src/functions/string.d.mts +8 -8
  31. package/dist/src/functions/string.mjs +14 -14
  32. package/dist/src/index.d.mts +3 -3
  33. package/dist/src/index.mjs +2 -2
  34. package/dist/src/indexes.d.mts +5 -6
  35. package/dist/src/indexes.mjs +1 -1
  36. package/dist/src/migration/ddl/enum.d.mts +4 -4
  37. package/dist/src/migration/ddl/enum.mjs +16 -6
  38. package/dist/src/migration/ddl/index.d.mts +1 -1
  39. package/dist/src/migration/ddl/indexes.mjs +0 -1
  40. package/dist/src/migration/ddl/sequence.d.mts +3 -3
  41. package/dist/src/migration/ddl/sequence.mjs +8 -4
  42. package/dist/src/migration/ddl/table.d.mts +5 -5
  43. package/dist/src/migration/ddl/table.mjs +28 -18
  44. package/dist/src/migration/ddl/types.d.mts +3 -3
  45. package/dist/src/migration/ddl/types.mjs +14 -6
  46. package/dist/src/migration/snapshot.d.mts +10 -11
  47. package/dist/src/migration/snapshot.mjs +26 -27
  48. package/dist/src/query-builders/delete.mjs +2 -3
  49. package/dist/src/query-builders/first.mjs +2 -3
  50. package/dist/src/query-builders/insert-returning.mjs +2 -3
  51. package/dist/src/query-builders/insert.mjs +4 -5
  52. package/dist/src/query-builders/orderby-clause.d.mts +5 -5
  53. package/dist/src/query-builders/orderby-clause.mjs +7 -4
  54. package/dist/src/query-builders/query.d.mts +17 -1
  55. package/dist/src/query-builders/rq.d.mts +2 -2
  56. package/dist/src/query-builders/rq.mjs +16 -16
  57. package/dist/src/query-builders/select.d.mts +3 -3
  58. package/dist/src/query-builders/select.mjs +4 -6
  59. package/dist/src/query-builders/update.d.mts +1 -1
  60. package/dist/src/query-builders/update.mjs +4 -5
  61. package/dist/src/sequence.d.mts +13 -5
  62. package/dist/src/sequence.mjs +21 -19
  63. package/dist/src/sql.d.mts +2 -2
  64. package/dist/src/sql.mjs +1 -1
  65. package/dist/src/table.d.mts +22 -15
  66. package/dist/src/table.mjs +5 -1
  67. package/dist/src/types.d.mts +7 -1
  68. package/dist/src/utils.mjs +8 -1
  69. package/dist/src/validators/zod.d.mts +3 -13
  70. package/dist/src/validators/zod.mjs +14 -9
  71. package/package.json +1 -1
package/dist/bin.cjs CHANGED
@@ -10247,6 +10247,7 @@ function formatValue(value) {
10247
10247
  // src/cli/commands/squash.ts
10248
10248
  var import_node_fs4 = require("node:fs");
10249
10249
  var import_node_path7 = require("node:path");
10250
+ var import_durcno4 = require("durcno");
10250
10251
  var import_migration3 = require("durcno/migration");
10251
10252
  var { bgGreen: bgGreen4, bgRed: bgRed2, yellow: yellow7, red: red5, green: green4, cyan: cyan7, gray: gray6 } = source_default;
10252
10253
  async function squash(start, end, options) {
@@ -10286,6 +10287,35 @@ async function squash(start, end, options) {
10286
10287
  console.log(yellow7("Only one migration in range. Nothing to squash."));
10287
10288
  process.exit(0);
10288
10289
  }
10290
+ let client = null;
10291
+ let rangeAllApplied = false;
10292
+ if (!options.skipDb) {
10293
+ client = config.connector.getClient();
10294
+ await client.connect();
10295
+ if (await migrationsTableExists(client)) {
10296
+ config.connector.options.pool = {
10297
+ ...config.connector.options.pool,
10298
+ max: 1
10299
+ };
10300
+ config.connector.options.logger = void 0;
10301
+ const db = (0, import_durcno4.database)({ Migrations: import_durcno4.Migrations }, config);
10302
+ const records = await db.from(import_durcno4.Migrations).select();
10303
+ await db.close();
10304
+ const appliedNames = new Set(records.map((r) => r.name));
10305
+ const appliedInRange = range.filter((m) => appliedNames.has(m));
10306
+ const unappliedInRange = range.filter((m) => !appliedNames.has(m));
10307
+ if (appliedInRange.length > 0 && unappliedInRange.length > 0) {
10308
+ await client.close();
10309
+ console.error(
10310
+ bgRed2.white("[ERROR]") + " " + red5("Cannot squash a mix of applied and unapplied migrations.") + gray6(`
10311
+ Applied in range: ${appliedInRange.join(", ")}`) + gray6(`
10312
+ Unapplied in range: ${unappliedInRange.join(", ")}`)
10313
+ );
10314
+ process.exit(1);
10315
+ }
10316
+ rangeAllApplied = unappliedInRange.length === 0;
10317
+ }
10318
+ }
10289
10319
  let hasCustomStatements = false;
10290
10320
  for (const migrationDirName of range) {
10291
10321
  const upPath = (0, import_node_path7.join)(migrationsDir, migrationDirName, "up.ts");
@@ -10346,6 +10376,22 @@ async function squash(start, end, options) {
10346
10376
  (0, import_node_fs4.mkdirSync)(squashedDir, { recursive: true });
10347
10377
  (0, import_node_fs4.writeFileSync)((0, import_node_path7.join)(squashedDir, "up.ts"), squashedUpTs);
10348
10378
  (0, import_node_fs4.writeFileSync)((0, import_node_path7.join)(squashedDir, "down.ts"), squashedDownTs);
10379
+ if (client !== null && rangeAllApplied) {
10380
+ config.connector.options.pool = {
10381
+ ...config.connector.options.pool,
10382
+ max: 1
10383
+ };
10384
+ config.connector.options.logger = void 0;
10385
+ const db = (0, import_durcno4.database)({ Migrations: import_durcno4.Migrations }, config);
10386
+ for (const migrationName of range) {
10387
+ await db.delete(import_durcno4.Migrations).where((0, import_durcno4.eq)(import_durcno4.Migrations.name, migrationName));
10388
+ }
10389
+ await db.insert(import_durcno4.Migrations).values({ name: start, createdAt: /* @__PURE__ */ new Date() });
10390
+ await db.close();
10391
+ }
10392
+ if (client !== null) {
10393
+ await client.close();
10394
+ }
10349
10395
  console.log(
10350
10396
  bgGreen4.white.bold("[SQUASHED]") + " " + green4(`${cyan7(String(range.length))} migrations into ${cyan7(start)}.`)
10351
10397
  );
@@ -10354,7 +10400,7 @@ async function squash(start, end, options) {
10354
10400
 
10355
10401
  // src/cli/commands/status.ts
10356
10402
  var import_node_path8 = require("node:path");
10357
- var import_durcno4 = require("durcno");
10403
+ var import_durcno5 = require("durcno");
10358
10404
  var { dim: dim4, cyan: cyan8, yellow: yellow8, green: green5 } = source_default;
10359
10405
  async function status(options) {
10360
10406
  const configPath = resolveConfigPath(options.config);
@@ -10372,8 +10418,8 @@ async function status(options) {
10372
10418
  }
10373
10419
  connector.options.pool = { ...connector.options.pool, max: 1 };
10374
10420
  connector.options.logger = void 0;
10375
- const db = (0, import_durcno4.database)({ Migrations: import_durcno4.Migrations }, config);
10376
- const migrationsQuery = db.from(import_durcno4.Migrations).select();
10421
+ const db = (0, import_durcno5.database)({ Migrations: import_durcno5.Migrations }, config);
10422
+ const migrationsQuery = db.from(import_durcno5.Migrations).select();
10377
10423
  let migrations;
10378
10424
  const client = connector.getClient();
10379
10425
  await client.connect();
@@ -10405,7 +10451,7 @@ async function status(options) {
10405
10451
  }
10406
10452
 
10407
10453
  // src/cli/index.ts
10408
- program.version("1.0.0-alpha.9");
10454
+ program.version("1.0.0-alpha.11");
10409
10455
  var Options = {
10410
10456
  config: ["--config <path>", "Path to the config file"]
10411
10457
  };
@@ -10430,7 +10476,10 @@ program.command("status").alias("stat").option(...Options.config).description("s
10430
10476
  program.command("down <migration>").option(...Options.config).description("down a specific migration").action(async (migration, opts) => {
10431
10477
  await down(migration, opts);
10432
10478
  });
10433
- program.command("squash <start> <end>").option(...Options.config).option("--force", "Squash even if custom statements exist").description("squash a range of migrations into a single migration").action(
10479
+ program.command("squash <start> <end>").option(...Options.config).option("--force", "Squash even if custom statements exist").option(
10480
+ "--skip-db",
10481
+ "Skip all database interaction (no validation, no tracking update)"
10482
+ ).description("squash a range of migrations into a single migration").action(
10434
10483
  async (start, end, opts) => {
10435
10484
  await squash(start, end, opts);
10436
10485
  }
@@ -1,8 +1,7 @@
1
1
  import { entityType } from "../symbols.mjs";
2
- import { Key } from "../types.mjs";
3
- import { StdTable, StdTableColumn, TableColumn } from "../table.mjs";
2
+ import { StdTable, StdTableColumn } from "../table.mjs";
4
3
  import { Arg } from "../query-builders/pre.mjs";
5
- import { Query } from "../query-builders/query.mjs";
4
+ import { Query, QueryContext } from "../query-builders/query.mjs";
6
5
  import { Sql } from "../sql.mjs";
7
6
  import * as z from "zod";
8
7
 
@@ -10,19 +9,59 @@ import * as z from "zod";
10
9
  declare const notNull: true;
11
10
  declare const unique: true;
12
11
  declare const primaryKey: true;
12
+ /**
13
+ * Represents the dimension configuration for an array column.
14
+ */
15
+ declare class Dimension<TDims extends readonly (number | null)[]> {
16
+ /** The raw dimension tuple (first = innermost dimension). */
17
+ readonly dims: TDims;
18
+ constructor(dims: TDims);
19
+ /**
20
+ * Appends a variable-length (unbounded) outer dimension.
21
+ * SQL equivalent: `type[]`
22
+ */
23
+ array(): Dimension<readonly [...TDims, null]>;
24
+ /**
25
+ * Appends a fixed-length outer dimension of `size` elements.
26
+ * SQL equivalent: `type[N]`
27
+ */
28
+ tuple<const L extends number>(size: L): Dimension<readonly [...TDims, L]>;
29
+ }
30
+ /**
31
+ * Creates a variable-length (unbounded) 1D array dimension.
32
+ * SQL equivalent: `type[]`
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * tags: varchar({ length: 50, dimension: array() })
37
+ * ```
38
+ */
39
+ declare function array(): Dimension<readonly [null]>;
40
+ /**
41
+ * Creates a fixed-length 1D array dimension of `size` elements.
42
+ * SQL equivalent: `type[N]`
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * coordinates: integer({ dimension: tuple(3) })
47
+ * ```
48
+ */
49
+ declare function tuple<const L extends number>(size: L): Dimension<readonly [L]>;
13
50
  type Tuple<T, L extends number, Acc extends T[] = []> = Acc["length"] extends L ? Acc : Tuple<T, L, [...Acc, T]>;
14
51
  type MultiDimValueArray<T, D extends readonly (number | null)[]> = D extends readonly [infer First, ...infer Rest] ? First extends number ? Rest extends readonly (number | null)[] ? MultiDimValueArray<Tuple<T, First>, Rest> : never : First extends null ? Rest extends readonly (number | null)[] ? MultiDimValueArray<T[], Rest> : never : never : T;
15
52
  type GetValueArray<T, TConfig> = TConfig extends {
16
- dimension: infer D;
17
- } ? D extends readonly (number | null)[] ? MultiDimValueArray<T, D> : T : T;
53
+ dimension: Dimension<infer Dims>;
54
+ } ? Dims extends readonly (number | null)[] ? MultiDimValueArray<T, Dims> : T : T;
18
55
  type MultiDimZodTypeArray<T extends z.ZodType, D extends readonly (number | null)[]> = D extends readonly [infer First, ...infer Rest] ? First extends number ? Rest extends readonly (number | null)[] ? MultiDimZodTypeArray<z.ZodTuple<Tuple<T, First>, null>, Rest> : never : First extends null ? Rest extends readonly (number | null)[] ? MultiDimZodTypeArray<z.ZodArray<T>, Rest> : never : never : T;
19
56
  type GetZodTypeArray<T extends z.ZodType, TConfig> = TConfig extends {
20
- dimension: infer D;
21
- } ? D extends readonly (number | null)[] ? MultiDimZodTypeArray<T, D> : T : T;
57
+ dimension: Dimension<infer Dims>;
58
+ } ? Dims extends readonly (number | null)[] ? MultiDimZodTypeArray<T, Dims> : T : T;
22
59
  interface TableLike {
23
60
  _: {
24
61
  schema: string;
25
62
  name: string;
63
+ schemaSql: string;
64
+ nameSql: string;
26
65
  };
27
66
  }
28
67
  declare const OnDeleteActions: readonly ["CASCADE", "SET NULL", "SET DEFAULT", "RESTRICT", "NO ACTION"];
@@ -42,8 +81,9 @@ type ColumnConfig = {
42
81
  notNull?: true;
43
82
  /**
44
83
  * The dimension of the array column.
84
+ * Use the `array()` or `tuple(size)` helpers to define dimensions.
45
85
  */
46
- dimension?: Readonly<[number | null, ...(number | null)[]]>;
86
+ dimension?: Dimension<readonly (number | null)[]>;
47
87
  };
48
88
  /**
49
89
  * Type that augments C with a `hasDefault` property set to true.
@@ -77,8 +117,8 @@ type HasUpdateFn<C> = C & {
77
117
  * Supports either a direct column resolver function or an object with
78
118
  * a resolver and optional `onDelete` action.
79
119
  */
80
- type BuildRef<ValType> = (() => TableColumn<string, string, Key, Column<any, ValType, any>>) | {
81
- column: () => TableColumn<string, string, Key, Column<any, ValType, any>>;
120
+ type BuildRef<ValType> = (() => StdTableColumn<Column<any, ValType>>) | {
121
+ column: () => StdTableColumn<Column<any, ValType>>;
82
122
  onDelete?: OnDeleteAction;
83
123
  };
84
124
  /**
@@ -104,37 +144,37 @@ declare abstract class Column<TConfig extends ColumnConfig, TColVal, TPgType ext
104
144
  readonly $: {
105
145
  /** Phantom discriminant id for this entity kind. */kind: "column"; /** The PostgreSQL type category for this column. */
106
146
  PgType: TPgType; /** The TypeScript type for this column's value. */
107
- TsType: TColVal;
108
- TsTypeScalar: TColVal;
109
- ValTypeBase: GetValueArray<TColVal, TConfig>;
147
+ TsType: TColVal; /** Phantom schema and table references for this column. */
148
+ schema: string | undefined;
149
+ table: string | undefined;
110
150
  HasValTypeOverridde: {};
111
151
  ValTypeOverride: {};
112
152
  };
113
- readonly ValType: this["$"]["HasValTypeOverridde"] extends true ? this["$"]["ValTypeOverride"] : this["$"]["ValTypeBase"];
153
+ readonly ValType: this["$"]["HasValTypeOverridde"] extends true ? GetValueArray<this["$"]["ValTypeOverride"], TConfig> : GetValueArray<TColVal, TConfig>;
114
154
  readonly ValTypeInsert: this extends {
115
155
  isGeneratedAlways: true;
116
156
  } ? never : this extends {
117
157
  isGeneratedByDefault: true;
118
158
  } ? this["ValType"] | undefined : this extends {
119
- hasDefault: true;
120
- } ? this["ValType"] | Sql | null | undefined : this extends {
159
+ isNotNull: true;
160
+ } ? this extends {
121
161
  hasInsertFn: true;
122
- } ? this["ValType"] | Sql | null | undefined : TConfig extends {
123
- notNull: true;
124
- } ? this["ValType"] | Sql : this["ValType"] | Sql | null | undefined;
125
- readonly ValTypeUpdate: TConfig extends {
126
- primaryKey: true;
127
- } ? never : TConfig extends {
128
- notNull: true;
129
- } ? this["ValType"] : this["ValType"] | null;
130
- readonly ValTypeSelect: TConfig extends {
162
+ } | {
163
+ hasDefault: true;
164
+ } ? this["ValType"] | Sql | undefined : this["ValType"] | Sql : this["ValType"] | Sql | null | undefined;
165
+ readonly ValTypeUpdate: this extends {
166
+ isPrimaryKey: true;
167
+ } ? never : this extends {
168
+ isNotNull: true;
169
+ } ? this["ValType"] | undefined : this["ValType"] | undefined | null;
170
+ readonly ValTypeSelect: this extends {
131
171
  isGeneratedAlways: true;
132
172
  } | {
133
173
  isGeneratedByDefault: true;
134
- } ? this["ValType"] : TConfig extends {
135
- primaryKey: true;
136
- } ? this["ValType"] : TConfig extends {
137
- notNull: true;
174
+ } | {
175
+ isPrimaryKey: true;
176
+ } | {
177
+ isNotNull: true;
138
178
  } ? this["ValType"] : this["ValType"] | null;
139
179
  constructor(config: TConfig);
140
180
  _: {
@@ -142,7 +182,7 @@ declare abstract class Column<TConfig extends ColumnConfig, TColVal, TPgType ext
142
182
  setTable: (table: StdTable) => void;
143
183
  };
144
184
  get name(): string | undefined;
145
- get nameSnake(): string | undefined;
185
+ get nameSql(): string | undefined;
146
186
  get table(): TableLike | undefined;
147
187
  get isPrimaryKey(): TConfig extends {
148
188
  primaryKey: true;
@@ -153,6 +193,10 @@ declare abstract class Column<TConfig extends ColumnConfig, TColVal, TPgType ext
153
193
  get isNotNull(): TConfig extends {
154
194
  notNull: true;
155
195
  } ? true : false;
196
+ /**
197
+ * Returns the raw dimension tuple from the column config, or `undefined` if not set.
198
+ */
199
+ get dimensions(): Readonly<[number | null, ...(number | null)[]]> | undefined;
156
200
  abstract get sqlTypeScalar(): string;
157
201
  get sqlType(): string;
158
202
  /** Returns the PostgreSQL cast type for this column's scalar value, or `null` if no cast is needed. */
@@ -166,7 +210,7 @@ declare abstract class Column<TConfig extends ColumnConfig, TColVal, TPgType ext
166
210
  * @returns string `"table"."column"`
167
211
  */
168
212
  get fullName(): string;
169
- toQuery(query: Query): void;
213
+ toQuery(query: Query, ctx?: QueryContext): void;
170
214
  abstract toDriverScalar(value: TColVal | Sql | null): string | number | null;
171
215
  abstract toSQLScalar(value: TColVal | Sql | null): string;
172
216
  abstract fromDriverScalar(value: unknown): TColVal | null;
@@ -257,4 +301,4 @@ declare abstract class Column<TConfig extends ColumnConfig, TColVal, TPgType ext
257
301
  arg(): Arg<this["ValType"]>;
258
302
  }
259
303
  //#endregion
260
- export { Column, ColumnConfig, GeneratedAlways, GeneratedByDefault, OnDeleteAction, notNull, primaryKey, unique };
304
+ export { Column, ColumnConfig, Dimension, GeneratedAlways, GeneratedByDefault, OnDeleteAction, array, notNull, primaryKey, tuple, unique };
@@ -9,6 +9,54 @@ const notNull = true;
9
9
  const unique = true;
10
10
  const primaryKey = true;
11
11
  const identity = "IDENTITY";
12
+ /**
13
+ * Represents the dimension configuration for an array column.
14
+ */
15
+ var Dimension = class Dimension {
16
+ /** The raw dimension tuple (first = innermost dimension). */
17
+ dims;
18
+ constructor(dims) {
19
+ this.dims = dims;
20
+ }
21
+ /**
22
+ * Appends a variable-length (unbounded) outer dimension.
23
+ * SQL equivalent: `type[]`
24
+ */
25
+ array() {
26
+ return new Dimension([...this.dims, null]);
27
+ }
28
+ /**
29
+ * Appends a fixed-length outer dimension of `size` elements.
30
+ * SQL equivalent: `type[N]`
31
+ */
32
+ tuple(size) {
33
+ return new Dimension([...this.dims, size]);
34
+ }
35
+ };
36
+ /**
37
+ * Creates a variable-length (unbounded) 1D array dimension.
38
+ * SQL equivalent: `type[]`
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * tags: varchar({ length: 50, dimension: array() })
43
+ * ```
44
+ */
45
+ function array() {
46
+ return new Dimension([null]);
47
+ }
48
+ /**
49
+ * Creates a fixed-length 1D array dimension of `size` elements.
50
+ * SQL equivalent: `type[N]`
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * coordinates: integer({ dimension: tuple(3) })
55
+ * ```
56
+ */
57
+ function tuple(size) {
58
+ return new Dimension([size]);
59
+ }
12
60
  var Column = class {
13
61
  static [entityType] = "Column";
14
62
  config;
@@ -27,7 +75,7 @@ var Column = class {
27
75
  #generatedAs;
28
76
  #references;
29
77
  #name;
30
- #nameSnake;
78
+ #nameSql;
31
79
  #table;
32
80
  constructor(config) {
33
81
  this.config = config;
@@ -38,7 +86,7 @@ var Column = class {
38
86
  _ = {
39
87
  setName: (name) => {
40
88
  this.#name = name;
41
- this.#nameSnake = camelToSnake(name);
89
+ this.#nameSql = camelToSnake(name);
42
90
  },
43
91
  setTable: (table) => {
44
92
  this.#table = table;
@@ -47,8 +95,8 @@ var Column = class {
47
95
  get name() {
48
96
  return this.#name;
49
97
  }
50
- get nameSnake() {
51
- return this.#nameSnake;
98
+ get nameSql() {
99
+ return this.#nameSql;
52
100
  }
53
101
  get table() {
54
102
  return this.#table;
@@ -62,22 +110,28 @@ var Column = class {
62
110
  get isNotNull() {
63
111
  return this.#notNull;
64
112
  }
113
+ /**
114
+ * Returns the raw dimension tuple from the column config, or `undefined` if not set.
115
+ */
116
+ get dimensions() {
117
+ return this.config.dimension?.dims;
118
+ }
65
119
  get sqlType() {
66
120
  const base = this.sqlTypeScalar;
67
- if (!this.config.dimension) return base;
68
- return `${base}${this.config.dimension.map((d) => d === null ? "[]" : `[${d}]`).join("")}`;
121
+ if (!this.dimensions) return base;
122
+ return `${base}${this.dimensions.map((d) => d === null ? "[]" : `[${d}]`).join("")}`;
69
123
  }
70
124
  /** Returns the full PostgreSQL cast type including array dimensions, or `null` if no cast is needed. */
71
125
  get sqlCast() {
72
126
  const base = this.sqlCastScalar;
73
127
  if (base === null) return null;
74
- if (!this.config.dimension) return base;
75
- return `${base}${this.config.dimension.map((d) => d === null ? "[]" : `[${d}]`).join("")}`;
128
+ if (!this.dimensions) return base;
129
+ return `${base}${this.dimensions.map((d) => d === null ? "[]" : `[${d}]`).join("")}`;
76
130
  }
77
131
  get zodType() {
78
132
  let schema = this.zodTypeScaler;
79
- if (!this.config.dimension) return schema;
80
- for (const dim of this.config.dimension) if (typeof dim === "number") schema = z.tuple(Array(dim).map(() => schema));
133
+ if (!this.dimensions) return schema;
134
+ for (const dim of this.dimensions) if (typeof dim === "number") schema = z.tuple(Array.from({ length: dim }, () => schema));
81
135
  else schema = z.array(schema);
82
136
  return schema;
83
137
  }
@@ -86,10 +140,13 @@ var Column = class {
86
140
  * @returns string `"table"."column"`
87
141
  */
88
142
  get fullName() {
89
- return `"${this.table?._.name}"."${this.nameSnake}"`;
143
+ return `"${this.table?._.nameSql}"."${this.nameSql}"`;
90
144
  }
91
- toQuery(query) {
92
- query.sql += this.fullName;
145
+ toQuery(query, ctx) {
146
+ const alias = ctx?.tableAliases?.get(`${this.table?._.schema}.${this.table?._.name}`);
147
+ if (alias === void 0) query.sql += this.fullName;
148
+ else if (alias === null) query.sql += `"${this.nameSql}"`;
149
+ else query.sql += `"${alias}"."${this.nameSql}"`;
93
150
  }
94
151
  /**
95
152
  * Converts a JavaScript value to the PostgreSQL driver format.
@@ -98,14 +155,14 @@ var Column = class {
98
155
  toDriver(value) {
99
156
  if (value === null) return null;
100
157
  if (value instanceof Sql) return value.string;
101
- if (!this.config.dimension) return this.toDriverScalar(value);
158
+ if (!this.dimensions) return this.toDriverScalar(value);
102
159
  return value.map((item) => this.#toDriverArrayElement(item, 0));
103
160
  }
104
161
  /**
105
162
  * Helper to recursively process multi-dimensional arrays for toDriver.
106
163
  */
107
164
  #toDriverArrayElement(value, dimIndex) {
108
- if (dimIndex >= this.config.dimension.length - 1) return this.toDriverScalar(value);
165
+ if (dimIndex >= this.dimensions.length - 1) return this.toDriverScalar(value);
109
166
  return value.map((item) => this.#toDriverArrayElement(item, dimIndex + 1));
110
167
  }
111
168
  /**
@@ -115,7 +172,7 @@ var Column = class {
115
172
  toSQL(value, options) {
116
173
  if (value === null) return "NULL";
117
174
  if (value instanceof Sql) return value.string;
118
- if (!this.config.dimension) {
175
+ if (!this.dimensions) {
119
176
  if (!options?.cast || !this.sqlCastScalar) return this.toSQLScalar(value);
120
177
  return `${this.toSQLScalar(value)}::${this.sqlCastScalar}`;
121
178
  }
@@ -125,7 +182,7 @@ var Column = class {
125
182
  * Helper to recursively process multi-dimensional arrays for toSQL.
126
183
  */
127
184
  #toSQLArray(arr, dimIndex, options) {
128
- const dimensions = this.config.dimension;
185
+ const dimensions = this.dimensions;
129
186
  if (arr.length === 0) return "'{}'";
130
187
  if (dimIndex >= dimensions.length - 1) return `ARRAY[${arr.map((item) => {
131
188
  if (!options?.cast || !this.sqlCastScalar) return this.toSQLScalar(item);
@@ -139,7 +196,7 @@ var Column = class {
139
196
  */
140
197
  fromDriver(value) {
141
198
  if (value === null) return null;
142
- if (!this.config.dimension) return this.fromDriverScalar(value);
199
+ if (!this.dimensions) return this.fromDriverScalar(value);
143
200
  let arr;
144
201
  if (typeof value === "string") arr = this.#parsePostgresArrayString(value);
145
202
  else arr = value;
@@ -188,7 +245,7 @@ var Column = class {
188
245
  * Helper to recursively process multi-dimensional arrays for fromDriver.
189
246
  */
190
247
  #fromDriverArray(arr, dimIndex) {
191
- if (dimIndex >= this.config.dimension.length - 1) return arr.map((item) => this.fromDriverScalar(item));
248
+ if (dimIndex >= this.dimensions.length - 1) return arr.map((item) => this.fromDriverScalar(item));
192
249
  return arr.map((item) => this.#fromDriverArray(item, dimIndex + 1));
193
250
  }
194
251
  /**
@@ -322,4 +379,4 @@ var Column = class {
322
379
  }
323
380
  };
324
381
  //#endregion
325
- export { Column, identity, notNull, primaryKey, unique };
382
+ export { Column, Dimension, array, identity, notNull, primaryKey, tuple, unique };
@@ -10,7 +10,7 @@ var EnumedColumn = class extends Column {
10
10
  this.#enum = enm;
11
11
  }
12
12
  get sqlTypeScalar() {
13
- return `"${this.#enum.schema}"."${this.#enum.name}"`;
13
+ return `"${this.#enum.schemaSql}"."${this.#enum.nameSql}"`;
14
14
  }
15
15
  get sqlCastScalar() {
16
16
  return this.sqlTypeScalar;
@@ -1,5 +1,6 @@
1
1
  import { TableAnyColumn } from "../table.mjs";
2
2
  import { AnyFilter, Filter } from "../filters/index.mjs";
3
+ import { QueryContext } from "../query-builders/query.mjs";
3
4
  import { Sql } from "../sql.mjs";
4
5
 
5
6
  //#region src/constraints/check.d.ts
@@ -12,10 +13,14 @@ type CheckExpression<TScopeColumns extends TableAnyColumn> = Filter<TScopeColumn
12
13
  declare class Check {
13
14
  #private;
14
15
  constructor(name: string, expr: AnyFilter | Sql);
15
- /** Returns the constraint name, appending `_check` suffix if not already present. */
16
+ /** Returns the constraint name as-is. */
16
17
  getName(): string;
17
- /** Renders the constraint expression to a SQL string. */
18
- toSQL(): string;
18
+ /**
19
+ * Renders the constraint expression to a SQL string.
20
+ * Pass a {@link QueryContext} with `null` alias entries to suppress table qualifiers
21
+ * on specific tables (used by the snapshot builder for CHECK constraint SQL).
22
+ */
23
+ toSQL(ctx?: QueryContext): string;
19
24
  }
20
25
  //#endregion
21
26
  export { Check, CheckExpression };
@@ -1,5 +1,4 @@
1
1
  import { Query } from "../query-builders/query.mjs";
2
- import { isTableCol } from "../entity.mjs";
3
2
  import { Sql } from "../sql.mjs";
4
3
  //#region src/constraints/check.ts
5
4
  /** A CHECK constraint for a table, storing its name and filter/SQL expression. */
@@ -10,47 +9,38 @@ var Check = class {
10
9
  this.#name = name;
11
10
  this.#expr = expr;
12
11
  }
13
- /** Returns the constraint name, appending `_check` suffix if not already present. */
12
+ /** Returns the constraint name as-is. */
14
13
  getName() {
15
- return this.#name.includes("check") ? this.#name : `${this.#name}_check`;
14
+ return this.#name;
16
15
  }
17
- /** Renders the constraint expression to a SQL string. */
18
- toSQL() {
16
+ /**
17
+ * Renders the constraint expression to a SQL string.
18
+ * Pass a {@link QueryContext} with `null` alias entries to suppress table qualifiers
19
+ * on specific tables (used by the snapshot builder for CHECK constraint SQL).
20
+ */
21
+ toSQL(ctx) {
19
22
  if (this.#expr instanceof Sql) return this.#expr.string;
20
23
  const query = new Query("", () => []);
21
- this.#expr.toQuery(query);
24
+ this.#expr.toQuery(query, ctx);
22
25
  return query.sql;
23
26
  }
24
27
  };
25
- /** Creates a {@link Check} constraint from a filter expression or raw SQL. */
26
- function check(name, expr) {
27
- return new Check(name, expr);
28
- }
29
- /**
30
- * Wraps a column proxy so that `fullName` returns the unqualified quoted name,
31
- * e.g. `"price"` instead of `"public"."price"`.
32
- * Required so filter conditions in check constraints emit unqualified column names.
33
- */
34
- function proxyColumnForCheck(col) {
35
- return new Proxy(col, { get(target, prop) {
36
- if (prop === "fullName") return `"${target.nameSnake}"`;
37
- if (prop === "toQuery") return (val) => val.sql += `"${target.nameSnake}"`;
38
- const val = Reflect.get(target, prop, target);
39
- if (typeof val === "function") return val.bind(target);
40
- return val;
41
- } });
42
- }
43
28
  /**
44
- * Wraps a table so that any column access returns a check-safe column proxy.
45
- * Pass the result to the `checkConstraints` callback so filters produce correct SQL.
29
+ * Creates a {@link Check} constraint from a filter expression or raw SQL.
30
+ *
31
+ * Convention: `check_<table>_<col>[_and_<col>]*[_<suffix>]?`
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * table("public", "projects", { name: varchar({ length: 255 }) }, {
36
+ * checkConstraints: (t, check) => [
37
+ * check("check_projects_name_length", gte(sql`char_length(${t.name})`, 1)),
38
+ * ],
39
+ * });
40
+ * ```
46
41
  */
47
- function createCheckTableProxy(table) {
48
- return new Proxy(table, { get(target, prop) {
49
- const val = Reflect.get(target, prop, target);
50
- if (isTableCol(val)) return proxyColumnForCheck(val);
51
- if (typeof val === "function") return val.bind(target);
52
- return val;
53
- } });
42
+ function check(name, expr) {
43
+ return new Check(name, expr);
54
44
  }
55
45
  //#endregion
56
- export { check, createCheckTableProxy };
46
+ export { check };
@@ -1,10 +1,11 @@
1
- import { StdTable, StdTableColumn } from "../table.mjs";
1
+ import { StdTableColumn } from "../table.mjs";
2
2
 
3
3
  //#region src/constraints/primary-key.d.ts
4
4
  declare class PrimaryKeyConstraint {
5
5
  #private;
6
6
  constructor(name: string, columns: StdTableColumn[]);
7
- getName(table: StdTable): string;
7
+ /** Returns the constraint name as-is. */
8
+ getName(): string;
8
9
  getColumns(): string[];
9
10
  }
10
11
  /**
@@ -14,11 +15,13 @@ declare class PrimaryKeyConstraint {
14
15
  *
15
16
  * This function is passed as the second parameter to the `primaryKeyConstraint` callback.
16
17
  *
18
+ * Convention: `pk_<table>`
19
+ *
17
20
  * @example
18
21
  * ```ts
19
- * table("public", "user_roles", { userId: bigint({}), roleId: bigint({}) }, {
22
+ * table("public", "userRoles", { userId: bigint({}), roleId: bigint({}) }, {
20
23
  * primaryKeyConstraint: (t, primaryKey) =>
21
- * primaryKey("pk", [t.userId, t.roleId]),
24
+ * primaryKey("pk_user_roles", [t.userId, t.roleId]),
22
25
  * });
23
26
  * ```
24
27
  */
@@ -7,11 +7,12 @@ var PrimaryKeyConstraint = class {
7
7
  this.#name = name;
8
8
  this.#columns = columns;
9
9
  }
10
- getName(table) {
11
- return this.#name.startsWith(`${table._.name}_`) ? this.#name : `${table._.name}_${this.#name}`;
10
+ /** Returns the constraint name as-is. */
11
+ getName() {
12
+ return this.#name;
12
13
  }
13
14
  getColumns() {
14
- return this.#columns.map((col) => col.nameSnake);
15
+ return this.#columns.map((col) => col.nameSql);
15
16
  }
16
17
  };
17
18
  /**
@@ -21,11 +22,13 @@ var PrimaryKeyConstraint = class {
21
22
  *
22
23
  * This function is passed as the second parameter to the `primaryKeyConstraint` callback.
23
24
  *
25
+ * Convention: `pk_<table>`
26
+ *
24
27
  * @example
25
28
  * ```ts
26
- * table("public", "user_roles", { userId: bigint({}), roleId: bigint({}) }, {
29
+ * table("public", "userRoles", { userId: bigint({}), roleId: bigint({}) }, {
27
30
  * primaryKeyConstraint: (t, primaryKey) =>
28
- * primaryKey("pk", [t.userId, t.roleId]),
31
+ * primaryKey("pk_user_roles", [t.userId, t.roleId]),
29
32
  * });
30
33
  * ```
31
34
  */