durcno 1.0.0-alpha.15 → 1.0.0-alpha.16

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/bin.cjs CHANGED
@@ -10455,7 +10455,7 @@ async function status(options) {
10455
10455
  }
10456
10456
 
10457
10457
  // src/cli/index.ts
10458
- program.version("1.0.0-alpha.14");
10458
+ program.version("1.0.0-alpha.15");
10459
10459
  var Options = {
10460
10460
  config: ["--config <path>", "Path to the config file"]
10461
10461
  };
@@ -0,0 +1,61 @@
1
+ import { Column, OnDeleteAction } from "../columns/common.mjs";
2
+ import { AnyColumn, StdTableColumn } from "../table.mjs";
3
+
4
+ //#region src/constraints/foreign-key.d.ts
5
+ /**
6
+ * Intermediate builder returned by `fk(column)`.
7
+ * Call `.references(refColumn)` to finalise into a `ForeignKey`.
8
+ */
9
+ declare class ForeignKeyBuilder<TCol extends AnyColumn> {
10
+ #private;
11
+ constructor(column: StdTableColumn<TCol>);
12
+ /**
13
+ * Specify the referenced column.
14
+ * The referenced column's value type must match the source column's value type.
15
+ */
16
+ references<TRefCol extends Column<any, TCol["ValType"]>>(ref: StdTableColumn<TRefCol>): ForeignKey;
17
+ }
18
+ /**
19
+ * Represents a finalised table-level foreign key constraint.
20
+ * Created via `fk(column).references(refColumn)`.
21
+ */
22
+ declare class ForeignKey {
23
+ #private;
24
+ constructor(column: StdTableColumn, reference: StdTableColumn, onDelete: OnDeleteAction);
25
+ /**
26
+ * Override the default `CASCADE` delete action.
27
+ *
28
+ * @param action - The `ON DELETE` action to apply.
29
+ * @returns `this` for chaining.
30
+ */
31
+ onDelete(action: OnDeleteAction): this;
32
+ _: {
33
+ /** Returns the source column of the foreign key. */getColumn: () => StdTableColumn; /** Returns the referenced column of the foreign key. */
34
+ getReference: () => StdTableColumn; /** Returns the configured `ON DELETE` action. */
35
+ getOnDelete: () => OnDeleteAction;
36
+ };
37
+ }
38
+ /**
39
+ * Entry point for defining a table-level foreign key constraint.
40
+ * Use inside the `foreignKeys` callback in `TableExtra`.
41
+ *
42
+ * Because `foreignKeys` receives the fully-constructed table as a typed
43
+ * parameter `t`, column references are already resolved — no thunk needed.
44
+ *
45
+ * @param column - The source column on this table.
46
+ * @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * table("public", "comments", { ... }, {
51
+ * foreignKeys: (t, fk) => [
52
+ * fk(t.parentId).references(t.id).onDelete("SET NULL"),
53
+ * ],
54
+ * });
55
+ * ```
56
+ */
57
+ declare function fk<TCol extends AnyColumn>(column: StdTableColumn<TCol>): ForeignKeyBuilder<TCol>;
58
+ /** The type of the `fk` helper injected into the `foreignKeys` callback. */
59
+ type ForeignKeyFn = typeof fk;
60
+ //#endregion
61
+ export { ForeignKey, ForeignKeyFn };
@@ -0,0 +1,74 @@
1
+ //#region src/constraints/foreign-key.ts
2
+ /**
3
+ * Intermediate builder returned by `fk(column)`.
4
+ * Call `.references(refColumn)` to finalise into a `ForeignKey`.
5
+ */
6
+ var ForeignKeyBuilder = class {
7
+ #column;
8
+ constructor(column) {
9
+ this.#column = column;
10
+ }
11
+ /**
12
+ * Specify the referenced column.
13
+ * The referenced column's value type must match the source column's value type.
14
+ */
15
+ references(ref) {
16
+ return new ForeignKey(this.#column, ref, "CASCADE");
17
+ }
18
+ };
19
+ /**
20
+ * Represents a finalised table-level foreign key constraint.
21
+ * Created via `fk(column).references(refColumn)`.
22
+ */
23
+ var ForeignKey = class {
24
+ #column;
25
+ #reference;
26
+ #onDelete;
27
+ constructor(column, reference, onDelete) {
28
+ this.#column = column;
29
+ this.#reference = reference;
30
+ this.#onDelete = onDelete;
31
+ }
32
+ /**
33
+ * Override the default `CASCADE` delete action.
34
+ *
35
+ * @param action - The `ON DELETE` action to apply.
36
+ * @returns `this` for chaining.
37
+ */
38
+ onDelete(action) {
39
+ this.#onDelete = action;
40
+ return this;
41
+ }
42
+ _ = {
43
+ /** Returns the source column of the foreign key. */
44
+ getColumn: () => this.#column,
45
+ /** Returns the referenced column of the foreign key. */
46
+ getReference: () => this.#reference,
47
+ /** Returns the configured `ON DELETE` action. */
48
+ getOnDelete: () => this.#onDelete
49
+ };
50
+ };
51
+ /**
52
+ * Entry point for defining a table-level foreign key constraint.
53
+ * Use inside the `foreignKeys` callback in `TableExtra`.
54
+ *
55
+ * Because `foreignKeys` receives the fully-constructed table as a typed
56
+ * parameter `t`, column references are already resolved — no thunk needed.
57
+ *
58
+ * @param column - The source column on this table.
59
+ * @returns A `ForeignKeyBuilder` to chain `.references(refColumn)` on.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * table("public", "comments", { ... }, {
64
+ * foreignKeys: (t, fk) => [
65
+ * fk(t.parentId).references(t.id).onDelete("SET NULL"),
66
+ * ],
67
+ * });
68
+ * ```
69
+ */
70
+ function fk(column) {
71
+ return new ForeignKeyBuilder(column);
72
+ }
73
+ //#endregion
74
+ export { fk };
@@ -9,6 +9,7 @@ import { Enum } from "../enumtype.mjs";
9
9
  import { Sequence } from "../sequence.mjs";
10
10
  import chalk from "../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.mjs";
11
11
  import { check } from "../constraints/check.mjs";
12
+ import { fk } from "../constraints/foreign-key.mjs";
12
13
  //#region src/migration/snapshot.ts
13
14
  const { red } = chalk;
14
15
  /**
@@ -72,6 +73,18 @@ function snapshot(entities) {
72
73
  as: col.getGeneratedAs
73
74
  };
74
75
  });
76
+ const tableFks = table._.extra.foreignKeys?.(table, fk) ?? [];
77
+ for (const foreignKey of tableFks) {
78
+ const srcCol = foreignKey._.getColumn();
79
+ const refCol = foreignKey._.getReference();
80
+ const colEntry = ss.tables[`${table._.schemaSql}.${table._.nameSql}`].columns[srcCol.nameSql];
81
+ if (colEntry) colEntry.references = {
82
+ schema: refCol.table._.schemaSql,
83
+ table: refCol.table._.nameSql,
84
+ column: refCol.nameSql,
85
+ onDelete: foreignKey._.getOnDelete()
86
+ };
87
+ }
75
88
  (table._.extra.indexes?.(table) ?? []).forEach((index) => {
76
89
  ss.tables[`${table._.schemaSql}.${table._.nameSql}`].indexes[index._.getName(table)] = {
77
90
  name: index._.getName(table),
@@ -2,6 +2,7 @@ import { CamelToSnake, Key, SnakeCase, Valueof } from "./types.mjs";
2
2
  import { Check, CheckExpression } from "./constraints/check.mjs";
3
3
  import { entityType } from "./symbols.mjs";
4
4
  import { Column } from "./columns/common.mjs";
5
+ import { ForeignKey, ForeignKeyFn } from "./constraints/foreign-key.mjs";
5
6
  import { PrimaryKeyConstraint, PrimaryKeyConstraintFn } from "./constraints/primary-key.mjs";
6
7
  import { UniqueConstraint, UniqueConstraintFn } from "./constraints/unique.mjs";
7
8
  import { Index } from "./indexes.mjs";
@@ -13,6 +14,7 @@ type TableExtra<TSchema extends string, TName extends string, TColumns extends R
13
14
  primaryKeyConstraint?: (table: TableWithColumns<TSchema, TName, TColumns>, primaryKey: PrimaryKeyConstraintFn) => PrimaryKeyConstraint;
14
15
  uniqueConstraints?: (table: TableWithColumns<TSchema, TName, TColumns>, unique: UniqueConstraintFn) => UniqueConstraint[];
15
16
  checkConstraints?: (table: TableWithColumns<TSchema, TName, TColumns>, check: (name: string, expr: CheckExpression<Valueof<TableWithColumns<TSchema, TName, TColumns>["_"]["columns"]>>) => Check) => Check[];
17
+ foreignKeys?: (table: TableWithColumns<TSchema, TName, TColumns>, fk: ForeignKeyFn) => ForeignKey[];
16
18
  };
17
19
  type TableConfig<TSchema extends string, TName extends string, TColumns extends Record<string, AnyColumn>> = {
18
20
  /** The raw table name as provided by the user (may be camelCase). */readonly name: TName; /** The snake_case version of {@link TableConfig.name} used in generated SQL. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "durcno",
3
- "version": "1.0.0-alpha.15",
3
+ "version": "1.0.0-alpha.16",
4
4
  "description": "A PostgreSQL Query Builder and Migration Manager for TypeScript, from the future.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://durcno.dev",