@elysiumjs/drizzle 0.0.0-stage → 0.1.1
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/CHANGELOG.md +19 -0
- package/README.md +252 -2
- package/dist/built-table.d.ts +17 -0
- package/dist/bun-require.d.ts +7 -0
- package/dist/cache.d.ts +60 -0
- package/dist/cerberus.d.ts +36 -0
- package/dist/commands/migration_generate.command.d.ts +14 -0
- package/dist/commands/migration_run.command.d.ts +26 -0
- package/dist/commands/project.d.ts +11 -0
- package/dist/commands/schema.d.ts +48 -0
- package/dist/database.d.ts +137 -0
- package/dist/driver.d.ts +53 -0
- package/dist/drivers/bun-sql.d.ts +25 -0
- package/dist/drivers/bun-sql.js +1 -0
- package/dist/drivers/hyperdrive.d.ts +46 -0
- package/dist/drivers/hyperdrive.js +1 -0
- package/dist/drivers/node-postgres.d.ts +23 -0
- package/dist/drivers/node-postgres.js +1 -0
- package/dist/drivers/postgres-js.d.ts +25 -0
- package/dist/drivers/postgres-js.js +1 -0
- package/dist/drizzle.module.d.ts +40 -0
- package/dist/hermes.d.ts +57 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +16 -0
- package/dist/lock.d.ts +33 -0
- package/dist/migration-clients.d.ts +37 -0
- package/dist/migration.d.ts +120 -0
- package/dist/migrations.d.ts +45 -0
- package/dist/model.d.ts +62 -0
- package/dist/moirai.d.ts +193 -0
- package/dist/pithos.d.ts +62 -0
- package/dist/query.d.ts +28 -0
- package/dist/repository.d.ts +20 -0
- package/dist/table-markers.d.ts +97 -0
- package/dist/table.d.ts +21 -0
- package/dist/tenancy.d.ts +105 -0
- package/package.json +102 -5
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { SQL } from 'drizzle-orm';
|
|
2
|
+
import { Service } from '@elysiumjs/olympus';
|
|
3
|
+
/**
|
|
4
|
+
* Where `migration:run` runs SQL: a transaction, or the connection outside of one. Every driver
|
|
5
|
+
* gives one through `DrizzleDriver.migrations()`.
|
|
6
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
7
|
+
*/
|
|
8
|
+
export interface MigrationDatabase {
|
|
9
|
+
/**
|
|
10
|
+
* Runs one statement, with its parameters.
|
|
11
|
+
* @param query The statement, from the `sql` template of Drizzle.
|
|
12
|
+
* @returns The rows of the statement.
|
|
13
|
+
*/
|
|
14
|
+
execute<T = Record<string, unknown>>(query: SQL): Promise<T[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Runs a script of several statements, without parameters, such as a migration file.
|
|
17
|
+
* @param text The script.
|
|
18
|
+
*/
|
|
19
|
+
script(text: string): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The connection `migration:run` works on, from the driver of a Drizzle connection.
|
|
23
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
24
|
+
*/
|
|
25
|
+
export interface MigrationConnection extends MigrationDatabase {
|
|
26
|
+
/**
|
|
27
|
+
* Runs a function in a transaction, committed when it resolves and rolled back when it
|
|
28
|
+
* throws.
|
|
29
|
+
* @param fn Receives the transaction.
|
|
30
|
+
*/
|
|
31
|
+
transaction<T>(fn: (db: MigrationDatabase) => Promise<T>): Promise<T>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A run of `migration:run`, as its hooks see it.
|
|
35
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
36
|
+
*/
|
|
37
|
+
export type MigrationRun = {
|
|
38
|
+
/** The transaction of the run. */
|
|
39
|
+
readonly db: MigrationDatabase;
|
|
40
|
+
/** The tenant the migrations run in: the schema set as `search_path`. */
|
|
41
|
+
readonly tenant: string;
|
|
42
|
+
/** The name of the connection the migrations run on. */
|
|
43
|
+
readonly connection: string;
|
|
44
|
+
/** The batch number of the migrations applied by this run. */
|
|
45
|
+
readonly batch: number;
|
|
46
|
+
/** The names of the migrations this run applies, in order. Empty when none is pending. */
|
|
47
|
+
readonly pending: readonly string[];
|
|
48
|
+
/** The names of the migrations applied so far by this run, in order. */
|
|
49
|
+
readonly applied: readonly string[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* One migration of a run, as the hooks see it.
|
|
53
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
54
|
+
*/
|
|
55
|
+
export type MigrationStep = {
|
|
56
|
+
/** The transaction of the run. */
|
|
57
|
+
readonly db: MigrationDatabase;
|
|
58
|
+
/** The name of the migration. */
|
|
59
|
+
readonly name: string;
|
|
60
|
+
/** The absolute path of the migration file. */
|
|
61
|
+
readonly path: string;
|
|
62
|
+
/** The run the migration is part of. */
|
|
63
|
+
readonly run: MigrationRun;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Runs SQL around the migrations of `migration:run`, inside its transaction and after its lock:
|
|
67
|
+
* what fails rolls the whole run back. Every method is optional.
|
|
68
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
69
|
+
*/
|
|
70
|
+
export interface MigrationHook {
|
|
71
|
+
/**
|
|
72
|
+
* Runs before the pending migrations, once the tenant schema and the migrations table exist.
|
|
73
|
+
* @param run The run.
|
|
74
|
+
*/
|
|
75
|
+
before?(run: MigrationRun): Promise<void> | void;
|
|
76
|
+
/**
|
|
77
|
+
* Runs before each migration.
|
|
78
|
+
* @param step The migration about to be applied.
|
|
79
|
+
*/
|
|
80
|
+
beforeEach?(step: MigrationStep): Promise<void> | void;
|
|
81
|
+
/**
|
|
82
|
+
* Runs after each migration, once it is recorded, before the next one.
|
|
83
|
+
* @param step The migration just applied.
|
|
84
|
+
*/
|
|
85
|
+
afterEach?(step: MigrationStep): Promise<void> | void;
|
|
86
|
+
/**
|
|
87
|
+
* Runs after the pending migrations, also when there is none.
|
|
88
|
+
* @param run The run.
|
|
89
|
+
*/
|
|
90
|
+
after?(run: MigrationRun): Promise<void> | void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Migrations: the hooks that `migration:run` calls around them.
|
|
94
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
95
|
+
*/
|
|
96
|
+
export declare namespace Migration {
|
|
97
|
+
/**
|
|
98
|
+
* The tag of the migration hooks.
|
|
99
|
+
*/
|
|
100
|
+
const Hooks: import("@elysiumjs/olympus").ServiceTag<MigrationHook>;
|
|
101
|
+
/**
|
|
102
|
+
* Registers a service as a migration hook. Hooks run in the order the modules register them,
|
|
103
|
+
* for every tenant: read `run.tenant` to act on some of them only.
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* @Migration.hook()
|
|
107
|
+
* export class GrantsHook implements MigrationHook {
|
|
108
|
+
* public async after({ db, tenant }: MigrationRun) {
|
|
109
|
+
* await db.execute(sql`GRANT USAGE ON SCHEMA ${sql.identifier(tenant)} TO app`);
|
|
110
|
+
* }
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
114
|
+
* @param props The service options.
|
|
115
|
+
*/
|
|
116
|
+
const hook: (props?: Parameters<typeof Service.register>[0]) => (target: {
|
|
117
|
+
new (...arguments_: any[]): any;
|
|
118
|
+
prototype: Pick<any, string | number | symbol>;
|
|
119
|
+
}) => void;
|
|
120
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** A migration recorded as applied in `elysium_migrations`. */
|
|
2
|
+
export type AppliedMigration = {
|
|
3
|
+
name: string;
|
|
4
|
+
appliedAt: Date;
|
|
5
|
+
};
|
|
6
|
+
/** The migrations to run, and the applied records to rename to their new names. */
|
|
7
|
+
export type MigrationPlan = {
|
|
8
|
+
pending: string[];
|
|
9
|
+
renames: {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Gets the name under which a migration file is tracked. Drizzle Kit 1.0 stores each migration
|
|
16
|
+
* as `<folder>/migration.sql`, in which case the folder name identifies the migration.
|
|
17
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
18
|
+
* @param path The path of the migration file.
|
|
19
|
+
*/
|
|
20
|
+
export declare const getMigrationName: (path: string) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Decides which migration files to run.
|
|
23
|
+
*
|
|
24
|
+
* `drizzle-kit up` moves each flat `<prefix>_<name>.sql` file into a
|
|
25
|
+
* `<timestamp>_<name>/migration.sql` folder, where the timestamp is when the migration was
|
|
26
|
+
* generated. An applied record whose flat file is gone is matched, in order, to a folder with
|
|
27
|
+
* the same `<name>` generated before the record was applied; that folder is not run again and
|
|
28
|
+
* the record is renamed. Folders generated later are new migrations and run.
|
|
29
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
30
|
+
* @param files The paths of the migration files.
|
|
31
|
+
* @param applied The applied migrations.
|
|
32
|
+
*/
|
|
33
|
+
export declare const planMigrations: (files: string[], applied: AppliedMigration[]) => MigrationPlan;
|
|
34
|
+
/**
|
|
35
|
+
* Removes the `"public".` qualifier Drizzle Kit writes before identifiers, so that a migration
|
|
36
|
+
* runs in the schema selected by the `search_path` (the tenant schema).
|
|
37
|
+
*
|
|
38
|
+
* Only identifier qualifiers are changed: string literals, dollar-quoted bodies (functions, `DO`
|
|
39
|
+
* blocks), comments and other quoted identifiers are kept as is. Qualifiers inside a `DO` block
|
|
40
|
+
* are therefore kept: such blocks are not rewritten, since their contents are not parsed here.
|
|
41
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
42
|
+
* @param sql The migration SQL.
|
|
43
|
+
* @returns The SQL without the public schema qualifiers.
|
|
44
|
+
*/
|
|
45
|
+
export declare const stripPublicSchema: (sql: string) => string;
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ModelAdapter } from '@elysiumjs/olympus/mnemosyne';
|
|
2
|
+
import type { PgTable, PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
3
|
+
/**
|
|
4
|
+
* Drizzle-specific model adapter.
|
|
5
|
+
*
|
|
6
|
+
* Bridges Drizzle's `PgTableWithColumns` to the framework's
|
|
7
|
+
* normalized model metadata.
|
|
8
|
+
*
|
|
9
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
10
|
+
*/
|
|
11
|
+
export declare const drizzleAdapter: ModelAdapter<PgTableWithColumns<any>>;
|
|
12
|
+
/**
|
|
13
|
+
* Creates Elysia validation schemas from a Drizzle table.
|
|
14
|
+
*
|
|
15
|
+
* This is a convenience wrapper around `createSchemaFromModel` that
|
|
16
|
+
* automatically extracts column metadata via the `drizzleAdapter`.
|
|
17
|
+
*
|
|
18
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
19
|
+
* @param table The Drizzle table to generate schemas for.
|
|
20
|
+
* @param opts Schema generation options.
|
|
21
|
+
* @returns An Elysia validation schema.
|
|
22
|
+
*/
|
|
23
|
+
export declare const createSchemaFromDrizzle: (table: PgTableWithColumns<any>, opts?: {
|
|
24
|
+
mode?: 'create' | 'update' | 'select';
|
|
25
|
+
}) => import("typebox").TObject<{}>;
|
|
26
|
+
/**
|
|
27
|
+
* Options for creating a DrizzleModel.
|
|
28
|
+
*/
|
|
29
|
+
export interface DrizzleModelOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Enable tenant schema support for this model.
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
supportTenancy?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates a model class backed by a Drizzle pgTable.
|
|
38
|
+
*
|
|
39
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
40
|
+
* @param table The Drizzle table (created with enhanced pgTable).
|
|
41
|
+
* @param options Model configuration options.
|
|
42
|
+
* @returns A model class with Drizzle-backed static metadata.
|
|
43
|
+
*/
|
|
44
|
+
export declare const DrizzleModel: <TTable extends PgTable>(table: TTable, options?: DrizzleModelOptions) => {
|
|
45
|
+
new (): {};
|
|
46
|
+
readonly $inferSelect: unknown;
|
|
47
|
+
readonly $inferInsert: unknown;
|
|
48
|
+
readonly $inferUpdate: unknown;
|
|
49
|
+
readonly table: TTable;
|
|
50
|
+
readonly tableName: string;
|
|
51
|
+
readonly columns: Record<string, import("drizzle-orm/pg-core").AnyPgColumnBuilder>;
|
|
52
|
+
readonly insertSchema: import("typebox").TObject<{}>;
|
|
53
|
+
readonly updateSchema: import("typebox").TObject<{}>;
|
|
54
|
+
readonly selectSchema: import("typebox").TObject<{}>;
|
|
55
|
+
readonly supportTenancy: boolean;
|
|
56
|
+
readonly adapter: ModelAdapter<TTable>;
|
|
57
|
+
} & {
|
|
58
|
+
readonly $inferSelect: { [Key in keyof TTable["_"]["columns"] & string]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
59
|
+
readonly $inferInsert: { [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").RequiredKeyOnly<Key, TTable["_"]["columns"][Key]>]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } & { [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").OptionalKeyOnly<Key, TTable["_"]["columns"][Key], false>]?: (TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null) | undefined; } extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never;
|
|
60
|
+
readonly $inferUpdate: Partial<{ [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").RequiredKeyOnly<Key, TTable["_"]["columns"][Key]>]: TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null; } & { [Key in keyof TTable["_"]["columns"] & string as import("drizzle-orm").OptionalKeyOnly<Key, TTable["_"]["columns"][Key], false>]?: (TTable["_"]["columns"][Key]["_"]["notNull"] extends true ? TTable["_"]["columns"][Key]["_"]["data"] : TTable["_"]["columns"][Key]["_"]["data"] | null) | undefined; } extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never>;
|
|
61
|
+
readonly table: TTable;
|
|
62
|
+
};
|
package/dist/moirai.d.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { EventReadFilter, EventStore, IdempotencyRecord, IdempotencyStore, InboxStore, OutboxClaim, OutboxRow, OutboxStore, ProjectionStorage, StoredEventRecord } from '@elysiumjs/olympus/moirai';
|
|
2
|
+
import type { BuiltPgTable } from './built-table';
|
|
3
|
+
import { PgColumn, PgTable } from 'drizzle-orm/pg-core';
|
|
4
|
+
/**
|
|
5
|
+
* How `moiraiTables()` builds the tables.
|
|
6
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
7
|
+
*/
|
|
8
|
+
export type MoiraiTablesOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* Partitions `events` by range of `occurred_at` and `outbox` by range of `created_at`: their
|
|
11
|
+
* primary and unique keys then include that column, and `migration:generate` creates them
|
|
12
|
+
* with `PARTITION BY RANGE`. The partitions themselves are left to the app, for example in
|
|
13
|
+
* a migration hook.
|
|
14
|
+
*/
|
|
15
|
+
partitioned?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** The columns of `idempotency_keys`. */
|
|
18
|
+
declare const idempotencyKeyColumns: () => {
|
|
19
|
+
key: import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
20
|
+
action: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
21
|
+
requestHash: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
22
|
+
response: import("drizzle-orm/pg-core").PgJsonbBuilder;
|
|
23
|
+
createdAt: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>>;
|
|
24
|
+
};
|
|
25
|
+
/** The columns of `outbox`; a partitioned table keys its rows with `created_at` too. */
|
|
26
|
+
declare const outboxColumns: (partitioned: boolean) => {
|
|
27
|
+
id: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgUUIDBuilder>;
|
|
28
|
+
kind: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
29
|
+
payload: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgJsonbBuilder>;
|
|
30
|
+
createdAt: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>>;
|
|
31
|
+
availableAt: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>>;
|
|
32
|
+
attempts: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>>;
|
|
33
|
+
lastError: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
34
|
+
dispatchedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
35
|
+
deadAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
36
|
+
};
|
|
37
|
+
/** The columns of `inbox`. */
|
|
38
|
+
declare const inboxColumns: () => {
|
|
39
|
+
messageId: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
40
|
+
consumer: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
41
|
+
recordedAt: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>>;
|
|
42
|
+
};
|
|
43
|
+
/** The columns of `events`; a partitioned table keys its rows with `occurred_at` too. */
|
|
44
|
+
declare const eventColumns: (partitioned: boolean) => {
|
|
45
|
+
position: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBigSerial64Builder>;
|
|
46
|
+
transactionId: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgCustomColumnBuilder<{
|
|
47
|
+
dataType: 'custom';
|
|
48
|
+
data: string;
|
|
49
|
+
driverParam: unknown;
|
|
50
|
+
}>>>;
|
|
51
|
+
aggregateId: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
52
|
+
aggregateType: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
53
|
+
version: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>;
|
|
54
|
+
type: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
55
|
+
schemaVersion: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>>;
|
|
56
|
+
data: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgJsonbBuilder>;
|
|
57
|
+
metadata: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgJsonbBuilder>;
|
|
58
|
+
occurredAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
59
|
+
};
|
|
60
|
+
/** The columns of `projections`. */
|
|
61
|
+
declare const projectionColumns: () => {
|
|
62
|
+
name: import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
63
|
+
version: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>;
|
|
64
|
+
builtAt: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>>;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The tables `moiraiTables()` builds.
|
|
68
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
69
|
+
*/
|
|
70
|
+
export type MoiraiTables = {
|
|
71
|
+
idempotencyKeys: BuiltPgTable<'idempotency_keys', undefined, ReturnType<typeof idempotencyKeyColumns>>;
|
|
72
|
+
outbox: BuiltPgTable<'outbox', undefined, ReturnType<typeof outboxColumns>>;
|
|
73
|
+
inbox: BuiltPgTable<'inbox', undefined, ReturnType<typeof inboxColumns>>;
|
|
74
|
+
events: BuiltPgTable<'events', undefined, ReturnType<typeof eventColumns>>;
|
|
75
|
+
projections: BuiltPgTable<'projections', undefined, ReturnType<typeof projectionColumns>>;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Builds the tables of the moirai stores: `idempotency_keys`, `outbox`, `inbox` and `events`, in a schema
|
|
79
|
+
* when one is given (one set of tables per domain schema, for example). Export them from the
|
|
80
|
+
* Drizzle schema so that `migration:generate` creates them.
|
|
81
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
82
|
+
* @param schema The Postgres schema of the tables. Defaults to the search path.
|
|
83
|
+
* @param options How the tables are built.
|
|
84
|
+
*/
|
|
85
|
+
export declare const moiraiTables: (schema?: string, options?: MoiraiTablesOptions) => MoiraiTables;
|
|
86
|
+
/**
|
|
87
|
+
* Where a Drizzle store works: its table, and the connection whose open transaction it joins.
|
|
88
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
89
|
+
*/
|
|
90
|
+
export type DrizzleStoreOptions<T> = {
|
|
91
|
+
table: T;
|
|
92
|
+
connection?: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* A table a store accepts: any Postgres table, in any schema, with the columns of the moirai table
|
|
96
|
+
* `T` under the same property names, such as a table of a domain schema whose key also spans the
|
|
97
|
+
* partition column.
|
|
98
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
99
|
+
*/
|
|
100
|
+
export type StoreTable<T extends PgTable> = PgTable & {
|
|
101
|
+
[K in keyof T['_']['columns']]: PgColumn;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Keeps idempotency records in a Postgres table, in the action's transaction.
|
|
105
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
106
|
+
*/
|
|
107
|
+
export declare class DrizzleIdempotencyStore implements IdempotencyStore {
|
|
108
|
+
private readonly options;
|
|
109
|
+
constructor(options: DrizzleStoreOptions<StoreTable<MoiraiTables['idempotencyKeys']>>);
|
|
110
|
+
/** The table, read through the columns of the moirai table, which it has. */
|
|
111
|
+
private get table();
|
|
112
|
+
get(key: string): Promise<IdempotencyRecord | undefined>;
|
|
113
|
+
put(record: IdempotencyRecord): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Keeps the outbox in a Postgres table. Claims lock the rows (`FOR UPDATE SKIP LOCKED`) until the
|
|
117
|
+
* relay's transaction ends, so that concurrent relays share the work.
|
|
118
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
119
|
+
*/
|
|
120
|
+
export declare class DrizzleOutboxStore implements OutboxStore {
|
|
121
|
+
#private;
|
|
122
|
+
private readonly options;
|
|
123
|
+
constructor(options: DrizzleStoreOptions<StoreTable<MoiraiTables['outbox']>>);
|
|
124
|
+
/** The table, read through the columns of the moirai table, which it has. */
|
|
125
|
+
private get table();
|
|
126
|
+
private get db();
|
|
127
|
+
insert(rows: readonly OutboxRow[]): Promise<void>;
|
|
128
|
+
claimDue(claim: OutboxClaim): Promise<readonly OutboxRow[]>;
|
|
129
|
+
markDispatched(id: string, dispatchedAt: Date): Promise<void>;
|
|
130
|
+
markFailed(id: string, update: {
|
|
131
|
+
attempts: number;
|
|
132
|
+
lastError: string;
|
|
133
|
+
availableAt: Date;
|
|
134
|
+
}): Promise<void>;
|
|
135
|
+
markDead(id: string, update: {
|
|
136
|
+
attempts: number;
|
|
137
|
+
lastError: string;
|
|
138
|
+
deadAt: Date;
|
|
139
|
+
}): Promise<void>;
|
|
140
|
+
replacePayload(id: string, payload: unknown): Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Keeps the inbox in a Postgres table: one row per message and consumer.
|
|
144
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
145
|
+
*/
|
|
146
|
+
export declare class DrizzleInboxStore implements InboxStore {
|
|
147
|
+
private readonly options;
|
|
148
|
+
constructor(options: DrizzleStoreOptions<StoreTable<MoiraiTables['inbox']>>);
|
|
149
|
+
/** The table, read through the columns of the moirai table, which it has. */
|
|
150
|
+
private get table();
|
|
151
|
+
record(messageId: string, consumer: string): Promise<boolean>;
|
|
152
|
+
/**
|
|
153
|
+
* Deletes the records older than a date, such as from a daily cron.
|
|
154
|
+
* @param cutoff The date before which records go.
|
|
155
|
+
* @returns The number of records deleted.
|
|
156
|
+
*/
|
|
157
|
+
pruneBefore(cutoff: Date): Promise<number>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Keeps event streams in a Postgres table, in the open transaction. An append locks each stream
|
|
161
|
+
* it writes with an advisory lock held until the transaction ends, and checks that the stream
|
|
162
|
+
* ends right before the first appended version, so a stale writer gets a
|
|
163
|
+
* `ConcurrencyConflictError` even when the unique key of the table spans more columns, such as a
|
|
164
|
+
* partition key. `position` and `transaction_id` are given by Postgres.
|
|
165
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
166
|
+
*/
|
|
167
|
+
export declare class DrizzleEventStore implements EventStore {
|
|
168
|
+
private readonly options;
|
|
169
|
+
constructor(options: DrizzleStoreOptions<StoreTable<MoiraiTables['events']>>);
|
|
170
|
+
/** The table, read through the columns of the moirai table, which it has. */
|
|
171
|
+
private get table();
|
|
172
|
+
private get db();
|
|
173
|
+
load(aggregateId: string, afterVersion?: number): Promise<readonly StoredEventRecord[]>;
|
|
174
|
+
readAll(filter: EventReadFilter): Promise<readonly StoredEventRecord[]>;
|
|
175
|
+
append(records: readonly StoredEventRecord[]): Promise<void>;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Resets the tables of Drizzle models for projection rebuilds, and keeps the version each
|
|
179
|
+
* projection was built with in a Postgres table. The reset deletes the rows in the open
|
|
180
|
+
* transaction, so readers see them until the rebuild commits.
|
|
181
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
182
|
+
*/
|
|
183
|
+
export declare class DrizzleProjectionStorage implements ProjectionStorage {
|
|
184
|
+
private readonly options;
|
|
185
|
+
constructor(options: DrizzleStoreOptions<StoreTable<MoiraiTables['projections']>>);
|
|
186
|
+
/** The table, read through the columns of the moirai table, which it has. */
|
|
187
|
+
private get table();
|
|
188
|
+
private get db();
|
|
189
|
+
reset(models: readonly object[]): Promise<void>;
|
|
190
|
+
version(name: string): Promise<number | undefined>;
|
|
191
|
+
built(name: string, version: number): Promise<void>;
|
|
192
|
+
}
|
|
193
|
+
export {};
|
package/dist/pithos.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FileCondition, FilePatch, FileRecord, FileStatus, FileStoreDriver } from '@elysiumjs/olympus/pithos';
|
|
2
|
+
import type { BuiltPgTable } from './built-table';
|
|
3
|
+
import type { DrizzleStoreOptions, StoreTable } from './moirai';
|
|
4
|
+
declare module '@elysiumjs/olympus' {
|
|
5
|
+
interface PortDrivers {
|
|
6
|
+
'file-store:drizzle': typeof DrizzleFileStore;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/** The columns of the files table. */
|
|
10
|
+
declare const fileColumns: () => {
|
|
11
|
+
id: import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
12
|
+
purpose: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
13
|
+
disk: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
14
|
+
key: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
15
|
+
contentType: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
16
|
+
size: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBigInt53Builder>;
|
|
17
|
+
ownerType: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
18
|
+
ownerId: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
19
|
+
createdBy: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
20
|
+
status: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>, FileStatus>>;
|
|
21
|
+
createdAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
22
|
+
readyAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
23
|
+
claimedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
24
|
+
releasedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
25
|
+
expiresAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
26
|
+
deletedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
27
|
+
rejection: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Builds the table of the file store, in a schema when one is given. Export it from the Drizzle
|
|
31
|
+
* schema so that `migration:generate` creates it.
|
|
32
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
33
|
+
* @param name The name of the table. Defaults to `files`.
|
|
34
|
+
* @param schema The Postgres schema of the table. Defaults to the search path.
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* export const files = filesTable();
|
|
38
|
+
*
|
|
39
|
+
* PithosModule.with({ disks, files: { store: () => FileStore.for('drizzle', { table: files }) } });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const filesTable: (name?: string, schema?: string) => FilesTable;
|
|
43
|
+
/** The table `filesTable()` builds. */
|
|
44
|
+
export type FilesTable = BuiltPgTable<string, undefined, ReturnType<typeof fileColumns>>;
|
|
45
|
+
/**
|
|
46
|
+
* Keeps file records in a Postgres table, built with `filesTable()` or any table with its
|
|
47
|
+
* columns. Each transition is one conditional `UPDATE`, so only one of two racing requests wins.
|
|
48
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
49
|
+
*/
|
|
50
|
+
export declare class DrizzleFileStore implements FileStoreDriver {
|
|
51
|
+
private readonly options;
|
|
52
|
+
constructor(options: DrizzleStoreOptions<StoreTable<FilesTable>>);
|
|
53
|
+
/** The table, read through the columns of the files table, which it has. */
|
|
54
|
+
private get table();
|
|
55
|
+
private get db();
|
|
56
|
+
insert({ owner, ...record }: FileRecord): Promise<void>;
|
|
57
|
+
find(id: string): Promise<FileRecord | null>;
|
|
58
|
+
transition(id: string, when: FileCondition, patch: FilePatch): Promise<FileRecord | null>;
|
|
59
|
+
countPending(createdBy: string, now: Date): Promise<number>;
|
|
60
|
+
due(now: Date, limit: number): Promise<FileRecord[]>;
|
|
61
|
+
}
|
|
62
|
+
export {};
|
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ParsedFilter, ParsedQuery } from '@elysiumjs/olympus/mnemosyne';
|
|
2
|
+
import type { SQL } from 'drizzle-orm';
|
|
3
|
+
import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
4
|
+
/**
|
|
5
|
+
* Compiles one filter of a parsed query to a Drizzle condition.
|
|
6
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
7
|
+
* @param table The table queried.
|
|
8
|
+
* @param filter The filter.
|
|
9
|
+
*/
|
|
10
|
+
export declare const compileFilter: (table: PgTableWithColumns<any>, filter: ParsedFilter) => SQL;
|
|
11
|
+
/**
|
|
12
|
+
* Compiles the condition that keeps the rows after the cursor, in sort order: a keyset condition
|
|
13
|
+
* over every sort key, the row key last.
|
|
14
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
15
|
+
* @param table The table queried.
|
|
16
|
+
* @param query The parsed query, with `after` set.
|
|
17
|
+
*/
|
|
18
|
+
export declare const compileAfter: (table: PgTableWithColumns<any>, query: ParsedQuery) => SQL | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Compiles a parsed query: the `where` condition (filters and cursor) and the `order by`.
|
|
21
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
22
|
+
* @param table The table queried.
|
|
23
|
+
* @param query The parsed query.
|
|
24
|
+
*/
|
|
25
|
+
export declare const compileQuery: (table: PgTableWithColumns<any>, query: ParsedQuery) => {
|
|
26
|
+
where: SQL<unknown> | undefined;
|
|
27
|
+
orderBy: SQL<unknown>[];
|
|
28
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RepositoryAdapter } from '@elysiumjs/olympus/mnemosyne';
|
|
2
|
+
import type { SQL } from 'drizzle-orm';
|
|
3
|
+
import type { PgTable } from 'drizzle-orm/pg-core';
|
|
4
|
+
import type { DrizzleConnection } from './database';
|
|
5
|
+
declare module '@elysiumjs/olympus/mnemosyne' {
|
|
6
|
+
interface RepositoryDrivers {
|
|
7
|
+
drizzle: {
|
|
8
|
+
table: PgTable;
|
|
9
|
+
connection: DrizzleConnection;
|
|
10
|
+
scope: SQL;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The repository adapter of Drizzle: `Repository(Model)` runs on it for the models of
|
|
16
|
+
* `DrizzleModel()`. Statements join the transaction open on the connection, and honour the
|
|
17
|
+
* tenant isolation of row-level security.
|
|
18
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
19
|
+
*/
|
|
20
|
+
export declare const drizzleRepositoryAdapter: RepositoryAdapter<PgTable, DrizzleConnection, SQL>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { SQL } from 'drizzle-orm';
|
|
2
|
+
import type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core';
|
|
3
|
+
/**
|
|
4
|
+
* A table as the SQL that follows its creation sees it.
|
|
5
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
6
|
+
*/
|
|
7
|
+
export type CreatedTable = {
|
|
8
|
+
/** The Postgres schema of the table, `undefined` for `public`. */
|
|
9
|
+
readonly schema: string | undefined;
|
|
10
|
+
/** The name of the table. */
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/** The quoted, schema-qualified name of the table: `"kernel"."audit"`. */
|
|
13
|
+
readonly qualified: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A column a partition key is made of: its name in the database, or a function returning the
|
|
17
|
+
* column of the table.
|
|
18
|
+
*/
|
|
19
|
+
export type PartitionColumn = string | ((table: any) => AnyPgColumn);
|
|
20
|
+
/**
|
|
21
|
+
* What `migration:generate` adds to the migration that creates a table.
|
|
22
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
23
|
+
*/
|
|
24
|
+
export type TableMarker = {
|
|
25
|
+
/** The columns of the range partition key. */
|
|
26
|
+
readonly range?: readonly PartitionColumn[];
|
|
27
|
+
/** The SQL to run after the table is created. */
|
|
28
|
+
readonly afterCreate?: ReadonlyArray<(table: CreatedTable) => string | SQL>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Attaches markers to a table, after the ones it already has.
|
|
32
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
33
|
+
* @param table The table.
|
|
34
|
+
* @param markers The markers.
|
|
35
|
+
* @returns The table.
|
|
36
|
+
*/
|
|
37
|
+
export declare const markTable: <T extends PgTable>(table: T, markers: readonly TableMarker[]) => T;
|
|
38
|
+
/**
|
|
39
|
+
* Reads the markers of a table.
|
|
40
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
41
|
+
* @param table The table.
|
|
42
|
+
* @returns The markers merged into one, or `undefined` when the table has none.
|
|
43
|
+
*/
|
|
44
|
+
export declare const getTableMarker: (table: object) => TableMarker | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Applies the markers of the given tables to the migration that creates them: the partition key
|
|
47
|
+
* after `CREATE TABLE`, then the SQL to run after it, each as its own statement. A table the
|
|
48
|
+
* migration does not create is left as it is.
|
|
49
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
50
|
+
* @param sql The SQL of the migration, without the `public` qualifiers.
|
|
51
|
+
* @param tables The tables of the app.
|
|
52
|
+
* @returns The SQL with the markers applied.
|
|
53
|
+
*/
|
|
54
|
+
export declare const applyTableMarkers: (sql: string, tables: Iterable<PgTable>) => string;
|
|
55
|
+
/**
|
|
56
|
+
* Drizzle tables: the markers that `migration:generate` applies to the migration creating a table.
|
|
57
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
58
|
+
*/
|
|
59
|
+
export declare namespace DrizzleTable {
|
|
60
|
+
/**
|
|
61
|
+
* Marks a table with what `migration:generate` adds to the migration that creates it. Later
|
|
62
|
+
* migrations, and tables created before the markers were added, are left as they are.
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* export const audit = DrizzleTable.define(
|
|
66
|
+
* DrizzleTable.partitioned({ range: 'recorded_at' }),
|
|
67
|
+
* DrizzleTable.afterCreate(
|
|
68
|
+
* ({ qualified }) =>
|
|
69
|
+
* `CREATE TRIGGER audit_append_only BEFORE UPDATE OR DELETE ON ${qualified} FOR EACH ROW EXECUTE FUNCTION forbid_change()`
|
|
70
|
+
* )
|
|
71
|
+
* )(
|
|
72
|
+
* kernel.table('audit', { ... }, (t) => [primaryKey({ columns: [t.id, t.recordedAt] })])
|
|
73
|
+
* );
|
|
74
|
+
* ```
|
|
75
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
76
|
+
* @param markers The markers, from `DrizzleTable.partitioned()` and `DrizzleTable.afterCreate()`.
|
|
77
|
+
* @returns A function marking the table and returning it.
|
|
78
|
+
*/
|
|
79
|
+
const define: (...markers: TableMarker[]) => <T extends PgTable>(target: T) => T;
|
|
80
|
+
/**
|
|
81
|
+
* Creates the table partitioned by range: `PARTITION BY RANGE (...)` follows its `CREATE TABLE`.
|
|
82
|
+
* The primary key and the unique constraints of the table must include the partition columns.
|
|
83
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
84
|
+
* @param options The partition key: a column name in the database, a function returning the
|
|
85
|
+
* column, or several of them.
|
|
86
|
+
*/
|
|
87
|
+
const partitioned: (options: {
|
|
88
|
+
range: PartitionColumn | readonly PartitionColumn[];
|
|
89
|
+
}) => TableMarker;
|
|
90
|
+
/**
|
|
91
|
+
* Runs SQL right after the table is created, in the same migration: partitions, triggers or
|
|
92
|
+
* grants that belong to the table.
|
|
93
|
+
* @author Axel Nana <ax.lnana@outlook.com>
|
|
94
|
+
* @param build Returns the SQL, as a string or a `sql` template, from the created table.
|
|
95
|
+
*/
|
|
96
|
+
const afterCreate: (build: (table: CreatedTable) => string | SQL) => TableMarker;
|
|
97
|
+
}
|
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AnyPgColumnBuilder, PgTableWithColumns } from 'drizzle-orm/pg-core';
|
|
2
|
+
import type { BuiltPgTable } from './built-table';
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves the original column builders for a table.
|
|
5
|
+
* @param table The table created with enhanced pgTable.
|
|
6
|
+
* @returns The original column builder definitions, or `undefined`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getTableBuilders: (table: PgTableWithColumns<any>) => Record<string, AnyPgColumnBuilder> | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a PostgreSQL table with automatic column builder registration.
|
|
11
|
+
*
|
|
12
|
+
* This is an enhanced version of Drizzle's `pgTable` that automatically
|
|
13
|
+
* registers column builders for tenancy support. It has the exact same
|
|
14
|
+
* signature and behavior as the original.
|
|
15
|
+
*
|
|
16
|
+
* @param tableName The name of the database table.
|
|
17
|
+
* @param columns The column definitions.
|
|
18
|
+
* @param extraConfig Optional extra Drizzle table configuration.
|
|
19
|
+
* @returns A Drizzle PostgreSQL table with registered column builders.
|
|
20
|
+
*/
|
|
21
|
+
export declare const pgTable: <TTableName extends string, TColumns extends Record<string, AnyPgColumnBuilder>>(tableName: TTableName, columns: TColumns, extraConfig?: (table: any) => any) => BuiltPgTable<TTableName, undefined, TColumns>;
|