@rebasepro/server-postgresql 0.6.1 → 0.7.0

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 (75) hide show
  1. package/package.json +24 -18
  2. package/src/PostgresBackendDriver.ts +65 -44
  3. package/src/PostgresBootstrapper.ts +34 -2
  4. package/src/auth/ensure-tables.ts +56 -1
  5. package/src/auth/services.ts +94 -1
  6. package/src/cli-errors.ts +162 -0
  7. package/src/cli-helpers.ts +183 -0
  8. package/src/cli.ts +198 -251
  9. package/src/schema/auth-default-policies.ts +90 -0
  10. package/src/schema/auth-schema.ts +25 -2
  11. package/src/schema/doctor.ts +2 -4
  12. package/src/schema/generate-drizzle-schema-logic.ts +4 -3
  13. package/src/schema/generate-drizzle-schema.ts +3 -5
  14. package/src/schema/generate-postgres-ddl-logic.ts +524 -0
  15. package/src/schema/generate-postgres-ddl.ts +116 -0
  16. package/src/services/EntityPersistService.ts +10 -8
  17. package/src/services/entityService.ts +28 -3
  18. package/src/utils/pg-error-utils.ts +16 -0
  19. package/src/utils/table-classification.ts +16 -0
  20. package/src/websocket.ts +9 -0
  21. package/test/auth-default-policies.test.ts +89 -0
  22. package/test/cli-helpers-extended.test.ts +324 -0
  23. package/test/cli-helpers.test.ts +59 -0
  24. package/test/connection.test.ts +292 -0
  25. package/test/databasePoolManager.test.ts +289 -0
  26. package/test/doctor-extended.test.ts +443 -0
  27. package/test/e2e/db-e2e.test.ts +293 -0
  28. package/test/e2e/pg-setup.ts +79 -0
  29. package/test/entity-persist-composite-keys.test.ts +451 -0
  30. package/test/generate-postgres-ddl-edge-cases.test.ts +716 -0
  31. package/test/generate-postgres-ddl.test.ts +300 -0
  32. package/test/mfa-service.test.ts +544 -0
  33. package/test/pg-error-utils.test.ts +50 -1
  34. package/test/realtimeService-channels.test.ts +696 -0
  35. package/test/unmapped-tables-safety.test.ts +55 -342
  36. package/vitest.e2e.config.ts +10 -0
  37. package/build-errors.txt +0 -37
  38. package/dist/PostgresAdapter.d.ts +0 -6
  39. package/dist/PostgresBackendDriver.d.ts +0 -110
  40. package/dist/PostgresBootstrapper.d.ts +0 -46
  41. package/dist/auth/ensure-tables.d.ts +0 -10
  42. package/dist/auth/services.d.ts +0 -231
  43. package/dist/cli.d.ts +0 -1
  44. package/dist/collections/PostgresCollectionRegistry.d.ts +0 -47
  45. package/dist/connection.d.ts +0 -65
  46. package/dist/data-transformer.d.ts +0 -55
  47. package/dist/databasePoolManager.d.ts +0 -20
  48. package/dist/history/HistoryService.d.ts +0 -71
  49. package/dist/history/ensure-history-table.d.ts +0 -7
  50. package/dist/index.d.ts +0 -14
  51. package/dist/index.es.js +0 -10803
  52. package/dist/index.es.js.map +0 -1
  53. package/dist/interfaces.d.ts +0 -18
  54. package/dist/schema/auth-schema.d.ts +0 -2149
  55. package/dist/schema/doctor-cli.d.ts +0 -2
  56. package/dist/schema/doctor.d.ts +0 -52
  57. package/dist/schema/generate-drizzle-schema-logic.d.ts +0 -2
  58. package/dist/schema/generate-drizzle-schema.d.ts +0 -1
  59. package/dist/schema/introspect-db-inference.d.ts +0 -5
  60. package/dist/schema/introspect-db-logic.d.ts +0 -118
  61. package/dist/schema/introspect-db.d.ts +0 -1
  62. package/dist/schema/test-schema.d.ts +0 -24
  63. package/dist/services/BranchService.d.ts +0 -47
  64. package/dist/services/EntityFetchService.d.ts +0 -214
  65. package/dist/services/EntityPersistService.d.ts +0 -40
  66. package/dist/services/RelationService.d.ts +0 -98
  67. package/dist/services/entity-helpers.d.ts +0 -38
  68. package/dist/services/entityService.d.ts +0 -110
  69. package/dist/services/index.d.ts +0 -4
  70. package/dist/services/realtimeService.d.ts +0 -220
  71. package/dist/types.d.ts +0 -3
  72. package/dist/utils/drizzle-conditions.d.ts +0 -138
  73. package/dist/utils/pg-array-null-patch.d.ts +0 -16
  74. package/dist/utils/pg-error-utils.d.ts +0 -55
  75. package/dist/websocket.d.ts +0 -11
@@ -1,231 +0,0 @@
1
- import { NodePgDatabase } from "drizzle-orm/node-postgres";
2
- import type { RebasePgTable } from "../types";
3
- import { UserRepository, TokenRepository, MfaRepository, AuthRepository, UserData, CreateUserData, RoleData, CreateRoleData, RefreshTokenInfo, PasswordResetTokenInfo, UserIdentityData, ListUsersOptions, PaginatedUsersResult, MfaFactor, MfaChallengeInfo, RoleData as Role } from "@rebasepro/server-core";
4
- export type { Role };
5
- export interface AuthSchemaTables {
6
- users: RebasePgTable;
7
- refreshTokens: RebasePgTable;
8
- passwordResetTokens: RebasePgTable;
9
- appConfig: RebasePgTable;
10
- userIdentities: RebasePgTable;
11
- }
12
- /**
13
- * PostgreSQL implementation of UserRepository.
14
- * Handles all user-related database operations using Drizzle ORM.
15
- */
16
- export declare class UserService implements UserRepository {
17
- private db;
18
- private usersTable;
19
- private userIdentitiesTable;
20
- constructor(db: NodePgDatabase, tableOrTables?: RebasePgTable | Partial<AuthSchemaTables>);
21
- private getQualifiedUsersTableName;
22
- private mapRowToUser;
23
- private mapPayload;
24
- createUser(data: CreateUserData): Promise<UserData>;
25
- getUserById(id: string): Promise<UserData | null>;
26
- getUserByEmail(email: string): Promise<UserData | null>;
27
- getUserByIdentity(provider: string, providerId: string): Promise<UserData | null>;
28
- getUserIdentities(userId: string): Promise<UserIdentityData[]>;
29
- linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void>;
30
- updateUser(id: string, data: Partial<Omit<CreateUserData, "id">>): Promise<UserData | null>;
31
- deleteUser(id: string): Promise<void>;
32
- listUsers(): Promise<UserData[]>;
33
- listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult>;
34
- /**
35
- * Update user's password hash
36
- */
37
- updatePassword(id: string, passwordHash: string): Promise<void>;
38
- /**
39
- * Set email verification status
40
- */
41
- setEmailVerified(id: string, verified: boolean): Promise<void>;
42
- /**
43
- * Set email verification token
44
- */
45
- setVerificationToken(id: string, token: string | null): Promise<void>;
46
- /**
47
- * Find user by email verification token
48
- */
49
- getUserByVerificationToken(token: string): Promise<UserData | null>;
50
- /**
51
- * Get roles for a user from database (inline TEXT[] column)
52
- */
53
- getUserRoles(userId: string): Promise<Role[]>;
54
- /**
55
- * Get role IDs for a user
56
- */
57
- getUserRoleIds(userId: string): Promise<string[]>;
58
- /**
59
- * Set roles for a user (replaces existing roles)
60
- */
61
- setUserRoles(userId: string, roleIds: string[]): Promise<void>;
62
- /**
63
- * Assign a specific role to new user (appends if not present)
64
- */
65
- assignDefaultRole(userId: string, roleId: string): Promise<void>;
66
- /**
67
- * Get user with their roles
68
- */
69
- getUserWithRoles(userId: string): Promise<{
70
- user: UserData;
71
- roles: Role[];
72
- } | null>;
73
- }
74
- export declare class RefreshTokenService {
75
- private db;
76
- private refreshTokensTable;
77
- constructor(db: NodePgDatabase, tableOrTables?: RebasePgTable | Partial<AuthSchemaTables>);
78
- private getQualifiedRefreshTokensTableName;
79
- createToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void>;
80
- findByHash(tokenHash: string): Promise<RefreshTokenInfo | null>;
81
- deleteByHash(tokenHash: string): Promise<void>;
82
- deleteAllForUser(userId: string): Promise<void>;
83
- listForUser(userId: string): Promise<RefreshTokenInfo[]>;
84
- deleteById(id: string, userId: string): Promise<void>;
85
- }
86
- /**
87
- * Password reset token service
88
- */
89
- export declare class PasswordResetTokenService {
90
- private db;
91
- private passwordResetTokensTable;
92
- constructor(db: NodePgDatabase, tableOrTables?: RebasePgTable | Partial<AuthSchemaTables>);
93
- private getQualifiedPasswordResetTokensTableName;
94
- /**
95
- * Create a password reset token
96
- */
97
- createToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
98
- /**
99
- * Find a valid (not expired, not used) token by hash
100
- */
101
- findValidByHash(tokenHash: string): Promise<{
102
- userId: string;
103
- expiresAt: Date;
104
- } | null>;
105
- /**
106
- * Mark token as used
107
- */
108
- markAsUsed(tokenHash: string): Promise<void>;
109
- /**
110
- * Delete all tokens for a user
111
- */
112
- deleteAllForUser(userId: string): Promise<void>;
113
- /**
114
- * Clean up expired tokens
115
- */
116
- deleteExpired(): Promise<void>;
117
- }
118
- /**
119
- * PostgreSQL implementation of TokenRepository.
120
- * Combines refresh token and password reset token operations.
121
- */
122
- export declare class PostgresTokenRepository implements TokenRepository {
123
- private db;
124
- private refreshTokenService;
125
- private passwordResetTokenService;
126
- constructor(db: NodePgDatabase, tableOrTables?: RebasePgTable | Partial<AuthSchemaTables>);
127
- createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void>;
128
- findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null>;
129
- deleteRefreshToken(tokenHash: string): Promise<void>;
130
- deleteAllRefreshTokensForUser(userId: string): Promise<void>;
131
- listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]>;
132
- deleteRefreshTokenById(id: string, userId: string): Promise<void>;
133
- createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
134
- findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null>;
135
- markPasswordResetTokenUsed(tokenHash: string): Promise<void>;
136
- deleteAllPasswordResetTokensForUser(userId: string): Promise<void>;
137
- deleteExpiredTokens(): Promise<void>;
138
- }
139
- /**
140
- * PostgreSQL implementation of AuthRepository.
141
- * Combines user, role, and token repository operations.
142
- * This provides a convenient single-class interface for all auth operations.
143
- */
144
- export declare class PostgresAuthRepository implements AuthRepository {
145
- private db;
146
- private userService;
147
- private tokenRepository;
148
- constructor(db: NodePgDatabase, tableOrTables?: RebasePgTable | Partial<AuthSchemaTables>);
149
- createUser(data: CreateUserData): Promise<UserData>;
150
- getUserById(id: string): Promise<UserData | null>;
151
- getUserByEmail(email: string): Promise<UserData | null>;
152
- getUserByIdentity(provider: string, providerId: string): Promise<UserData | null>;
153
- getUserIdentities(userId: string): Promise<UserIdentityData[]>;
154
- linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void>;
155
- updateUser(id: string, data: Partial<Omit<CreateUserData, "id">>): Promise<UserData | null>;
156
- deleteUser(id: string): Promise<void>;
157
- listUsers(): Promise<UserData[]>;
158
- listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult>;
159
- updatePassword(id: string, passwordHash: string): Promise<void>;
160
- setEmailVerified(id: string, verified: boolean): Promise<void>;
161
- setVerificationToken(id: string, token: string | null): Promise<void>;
162
- getUserByVerificationToken(token: string): Promise<UserData | null>;
163
- getUserRoles(userId: string): Promise<RoleData[]>;
164
- getUserRoleIds(userId: string): Promise<string[]>;
165
- setUserRoles(userId: string, roleIds: string[]): Promise<void>;
166
- assignDefaultRole(userId: string, roleId: string): Promise<void>;
167
- getUserWithRoles(userId: string): Promise<{
168
- user: UserData;
169
- roles: RoleData[];
170
- } | null>;
171
- getRoleById(id: string): Promise<RoleData | null>;
172
- listRoles(): Promise<RoleData[]>;
173
- createRole(_data: CreateRoleData): Promise<RoleData>;
174
- updateRole(id: string, data: Partial<Omit<RoleData, "id">>): Promise<RoleData | null>;
175
- deleteRole(_id: string): Promise<void>;
176
- createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void>;
177
- findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null>;
178
- deleteRefreshToken(tokenHash: string): Promise<void>;
179
- deleteAllRefreshTokensForUser(userId: string): Promise<void>;
180
- listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]>;
181
- deleteRefreshTokenById(id: string, userId: string): Promise<void>;
182
- createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
183
- findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null>;
184
- markPasswordResetTokenUsed(tokenHash: string): Promise<void>;
185
- deleteAllPasswordResetTokensForUser(userId: string): Promise<void>;
186
- deleteExpiredTokens(): Promise<void>;
187
- private _mfaService;
188
- private getMfaService;
189
- createMfaFactor(userId: string, factorType: "totp", secretEncrypted: string, friendlyName?: string): Promise<MfaFactor>;
190
- getMfaFactors(userId: string): Promise<MfaFactor[]>;
191
- getMfaFactorById(factorId: string): Promise<(MfaFactor & {
192
- secretEncrypted: string;
193
- }) | null>;
194
- verifyMfaFactor(factorId: string): Promise<void>;
195
- deleteMfaFactor(factorId: string, userId: string): Promise<void>;
196
- createMfaChallenge(factorId: string, ipAddress?: string): Promise<MfaChallengeInfo>;
197
- getMfaChallengeById(challengeId: string): Promise<MfaChallengeInfo | null>;
198
- verifyMfaChallenge(challengeId: string): Promise<void>;
199
- createRecoveryCodes(userId: string, codeHashes: string[]): Promise<void>;
200
- useRecoveryCode(userId: string, codeHash: string): Promise<boolean>;
201
- getUnusedRecoveryCodeCount(userId: string): Promise<number>;
202
- deleteAllRecoveryCodes(userId: string): Promise<void>;
203
- hasVerifiedMfaFactors(userId: string): Promise<boolean>;
204
- }
205
- /**
206
- * PostgreSQL implementation of MfaRepository.
207
- * Handles all MFA-related database operations.
208
- */
209
- export declare class MfaService implements MfaRepository {
210
- private db;
211
- private schemaName;
212
- constructor(db: NodePgDatabase, schemaName?: string);
213
- private qualify;
214
- createMfaFactor(userId: string, factorType: "totp", secretEncrypted: string, friendlyName?: string): Promise<MfaFactor>;
215
- getMfaFactors(userId: string): Promise<MfaFactor[]>;
216
- getMfaFactorById(factorId: string): Promise<(MfaFactor & {
217
- secretEncrypted: string;
218
- }) | null>;
219
- verifyMfaFactor(factorId: string): Promise<void>;
220
- deleteMfaFactor(factorId: string, userId: string): Promise<void>;
221
- createMfaChallenge(factorId: string, ipAddress?: string): Promise<MfaChallengeInfo>;
222
- getMfaChallengeById(challengeId: string): Promise<MfaChallengeInfo | null>;
223
- verifyMfaChallenge(challengeId: string): Promise<void>;
224
- createRecoveryCodes(userId: string, codeHashes: string[]): Promise<void>;
225
- useRecoveryCode(userId: string, codeHash: string): Promise<boolean>;
226
- getUnusedRecoveryCodeCount(userId: string): Promise<number>;
227
- deleteAllRecoveryCodes(userId: string): Promise<void>;
228
- hasVerifiedMfaFactors(userId: string): Promise<boolean>;
229
- }
230
- /** PostgreSQL user repository implementation */
231
- export type PostgresUserRepository = UserService;
package/dist/cli.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function runPluginCommand(args: string[]): Promise<void>;
@@ -1,47 +0,0 @@
1
- import { CollectionRegistry } from "@rebasepro/common";
2
- import { type EntityCollection } from "@rebasepro/types";
3
- import { PgEnum, PgTable } from "drizzle-orm/pg-core";
4
- import { Relations } from "drizzle-orm";
5
- import { CollectionRegistryInterface } from "../interfaces";
6
- /**
7
- * PostgreSQL-specific collection registry.
8
- * Extends the base CollectionRegistry with support for Drizzle ORM tables, enums, and relations.
9
- *
10
- * Satisfies CollectionRegistryInterface through inheritance from CollectionRegistry.
11
- */
12
- export declare class PostgresCollectionRegistry extends CollectionRegistry implements CollectionRegistryInterface {
13
- private tables;
14
- private enums;
15
- private relations;
16
- registerTable(table: PgTable, tableName: string): void;
17
- getTable(tableName: string): PgTable | undefined;
18
- /**
19
- * Checks if a specific collection has a registered table
20
- */
21
- hasTableForCollection(tableName: string): boolean;
22
- /**
23
- * Returns all registered table names.
24
- */
25
- getTableNames(): string[];
26
- /**
27
- * Finds collections assigned to a specific driver that do not have a registered table.
28
- */
29
- getCollectionsWithoutTables(driverId?: string): EntityCollection[];
30
- registerEnums(enums: Record<string, PgEnum<[string, ...string[]]>>): void;
31
- registerRelations(relations: Record<string, Relations>): void;
32
- getEnum(name: string): PgEnum<[string, ...string[]]> | undefined;
33
- getRelation(name: string): Relations | undefined;
34
- getAllEnums(): Record<string, PgEnum<[string, ...string[]]>>;
35
- getAllRelations(): Record<string, Relations>;
36
- /**
37
- * Get the merged schema object (tables + relations) for use with Drizzle's
38
- * relational query API (`db.query`).
39
- */
40
- getMergedSchema(): Record<string, unknown>;
41
- /**
42
- * Get the available Drizzle relation keys for a given collection path.
43
- * Maps from the collection's relation property names to the Drizzle relation names
44
- * defined in the schema.
45
- */
46
- getRelationKeysForCollection(collectionPath: string): string[];
47
- }
@@ -1,65 +0,0 @@
1
- import { Pool } from "pg";
2
- /**
3
- * Configuration for the Postgres connection pool.
4
- *
5
- * Sensible defaults are provided for production Cloud Run / single-instance
6
- * deployments. Override via environment variables or explicit config.
7
- */
8
- export interface PostgresPoolConfig {
9
- /** Maximum number of connections in the pool (default: 20) */
10
- max?: number;
11
- /** Close idle connections after this many ms (default: 30 000) */
12
- idleTimeoutMillis?: number;
13
- /** Abort connection attempts after this many ms (default: 10 000) */
14
- connectionTimeoutMillis?: number;
15
- /** Per-query timeout in ms (default: 30 000) */
16
- queryTimeout?: number;
17
- /** Per-statement timeout in ms (default: 30 000) */
18
- statementTimeout?: number;
19
- /** Enable TCP keep-alive (default: true) */
20
- keepAlive?: boolean;
21
- }
22
- /**
23
- * Create a Drizzle-backed Postgres connection with a production-grade
24
- * connection pool.
25
- *
26
- * @param connectionString Postgres connection URL
27
- * @param schema Optional Drizzle schema for the relational API
28
- * @param poolConfig Optional pool tuning (merged over defaults)
29
- *
30
- * @returns `{ db, pool, connectionString }` — the `pool` is exposed so
31
- * callers can register shutdown hooks (`pool.end()`) or monitor
32
- * pool metrics.
33
- */
34
- export declare function createPostgresDatabaseConnection(connectionString: string, schema?: Record<string, unknown>, poolConfig?: PostgresPoolConfig): {
35
- db: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, unknown>> & {
36
- $client: Pool;
37
- };
38
- pool: Pool;
39
- connectionString: string;
40
- };
41
- /**
42
- * Create a direct (non-pooled) connection for operations that require
43
- * session-level features incompatible with PgBouncer transaction mode,
44
- * such as LISTEN/NOTIFY, prepared statements, or advisory locks.
45
- *
46
- * Uses a smaller pool since this is only for specific use cases.
47
- */
48
- export declare function createDirectDatabaseConnection(connectionString: string, schema?: Record<string, unknown>, poolConfig?: PostgresPoolConfig): {
49
- db: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, unknown>> & {
50
- $client: Pool;
51
- };
52
- pool: Pool;
53
- connectionString: string;
54
- };
55
- /**
56
- * Create a read-only connection for routing read queries to replicas.
57
- * Uses a moderate pool size since reads are distributed across replicas.
58
- */
59
- export declare function createReadReplicaConnection(connectionString: string, schema?: Record<string, unknown>, poolConfig?: PostgresPoolConfig): {
60
- db: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, unknown>> & {
61
- $client: Pool;
62
- };
63
- pool: Pool;
64
- connectionString: string;
65
- };
@@ -1,55 +0,0 @@
1
- import { NodePgDatabase } from "drizzle-orm/node-postgres";
2
- import { EntityCollection, Properties, Property, Relation } from "@rebasepro/types";
3
- import { PostgresCollectionRegistry } from "./collections/PostgresCollectionRegistry";
4
- /**
5
- * Data transformation utilities for converting between frontend and database formats.
6
- */
7
- /**
8
- * Typed result from `serializeDataToServer`.
9
- * Replaces the hidden `__inverseRelationUpdates` / `__joinPathRelationUpdates`
10
- * dunder-property mutation pattern with explicit, typed state management.
11
- */
12
- export interface SerializedEntityData {
13
- /** Scalar column values ready for INSERT/UPDATE. */
14
- scalarData: Record<string, unknown>;
15
- /** Inverse relation updates that must be applied to target tables. */
16
- inverseRelationUpdates: Array<{
17
- relationKey: string;
18
- relation: Relation;
19
- newValue: unknown;
20
- currentEntityId?: string | number;
21
- }>;
22
- /** JoinPath relation updates that require multi-hop writes. */
23
- joinPathRelationUpdates: Array<{
24
- relationKey: string;
25
- relation: Relation;
26
- newTargetId: string | number | null;
27
- }>;
28
- }
29
- /**
30
- * Helper function to sanitize and convert dates to ISO strings
31
- */
32
- export declare function sanitizeAndConvertDates(obj: unknown): unknown;
33
- /**
34
- * Transform relations for database storage (relation objects to IDs)
35
- */
36
- export declare function serializeDataToServer<M extends Record<string, unknown>>(entity: M, properties: Properties, collection?: EntityCollection, registry?: PostgresCollectionRegistry): SerializedEntityData;
37
- /**
38
- * Serialize a single property value for database storage
39
- */
40
- export declare function serializePropertyToServer(value: unknown, property: Property): unknown;
41
- /**
42
- * Transform IDs back to relation objects for frontend
43
- */
44
- export declare function parseDataFromServer<M extends Record<string, unknown>>(data: M, collection: EntityCollection, db?: NodePgDatabase<Record<string, unknown>>, registry?: PostgresCollectionRegistry): Promise<M>;
45
- export declare function parsePropertyFromServer(value: unknown, property: Property, collection: EntityCollection, propertyKey?: string): unknown;
46
- /**
47
- * Lightweight value normalization for db.query results.
48
- * Only handles type coercion (dates, numbers, NaN) and property filtering.
49
- * Does NOT query the database for relations — those are already resolved
50
- * by Drizzle's relational query API.
51
- *
52
- * Use this instead of `parseDataFromServer` when processing results from
53
- * `db.query.findFirst/findMany` which return pre-hydrated relation data.
54
- */
55
- export declare function normalizeDbValues<M extends Record<string, unknown>>(data: M, collection: EntityCollection): M;
@@ -1,20 +0,0 @@
1
- import { Pool } from "pg";
2
- import { NodePgDatabase } from "drizzle-orm/node-postgres";
3
- export declare class DatabasePoolManager {
4
- private pools;
5
- private drizzleInstances;
6
- readonly defaultDatabaseName: string;
7
- private readonly rootConnectionString;
8
- constructor(adminConnectionString: string);
9
- getDrizzle(databaseName: string): NodePgDatabase<Record<string, never>>;
10
- getPool(databaseName: string): Pool;
11
- /**
12
- * Disconnect and remove the pool for a specific database.
13
- * Required before `CREATE DATABASE ... TEMPLATE` or `DROP DATABASE`,
14
- * which need exclusive access to the target database.
15
- */
16
- disconnectDatabase(databaseName: string): Promise<void>;
17
- /** Check if a pool exists for a given database name. */
18
- hasPool(databaseName: string): boolean;
19
- shutdown(): Promise<void>;
20
- }
@@ -1,71 +0,0 @@
1
- import { NodePgDatabase } from "drizzle-orm/node-postgres";
2
- export interface HistoryEntry {
3
- id: string;
4
- table_name: string;
5
- entity_id: string;
6
- action: "create" | "update" | "delete";
7
- changed_fields: string[] | null;
8
- values: Record<string, unknown> | null;
9
- previous_values: Record<string, unknown> | null;
10
- updated_by: string | null;
11
- updated_at: string;
12
- }
13
- export interface RecordHistoryParams {
14
- tableName: string;
15
- entityId: string;
16
- action: "create" | "update" | "delete";
17
- values?: Record<string, unknown> | null;
18
- previousValues?: Record<string, unknown> | null;
19
- updatedBy?: string | null;
20
- }
21
- export interface FetchHistoryOptions {
22
- limit?: number;
23
- offset?: number;
24
- }
25
- export interface HistoryRetentionConfig {
26
- /** Max entries per entity. Oldest pruned first. Default 200. */
27
- maxEntries: number;
28
- /** Entries older than this many days are pruned. Default 90. */
29
- ttlDays: number;
30
- }
31
- /**
32
- * Service for recording and querying entity change history.
33
- * Stores snapshots in the `rebase.entity_history` table.
34
- */
35
- export declare class HistoryService {
36
- private db;
37
- retention: HistoryRetentionConfig;
38
- constructor(db: NodePgDatabase, retention?: Partial<HistoryRetentionConfig>);
39
- /**
40
- * Record a history entry for an entity change.
41
- * This is intentionally fire-and-forget safe — errors are logged but never
42
- * bubble up to block the main save/delete operation.
43
- *
44
- * After inserting, kicks off a non-blocking pruning pass for this entity.
45
- */
46
- recordHistory(params: RecordHistoryParams): Promise<void>;
47
- /**
48
- * Fetch history entries for an entity, ordered by most recent first.
49
- */
50
- fetchHistory(tableName: string, entityId: string, options?: FetchHistoryOptions): Promise<{
51
- data: HistoryEntry[];
52
- total: number;
53
- }>;
54
- /**
55
- * Fetch a single history entry by ID.
56
- */
57
- fetchHistoryEntry(historyId: string): Promise<HistoryEntry | null>;
58
- /**
59
- * Prune history for a single entity: enforce maxEntries and TTL.
60
- */
61
- pruneEntity(tableName: string, entityId: string): Promise<number>;
62
- /**
63
- * Global prune: enforce TTL across ALL entities in a single sweep.
64
- * Intended to be called periodically (e.g. once per hour or daily).
65
- */
66
- pruneExpired(): Promise<number>;
67
- }
68
- /**
69
- * Shallow comparison to find top-level keys that changed between two objects.
70
- */
71
- export declare function findChangedFields(oldValues: Record<string, unknown>, newValues: Record<string, unknown>): string[] | null;
@@ -1,7 +0,0 @@
1
- import { NodePgDatabase } from "drizzle-orm/node-postgres";
2
- /**
3
- * Auto-create the entity history table if it doesn't exist.
4
- * This runs on startup when history is enabled, following the same
5
- * pattern as `ensureAuthTablesExist`.
6
- */
7
- export declare function ensureHistoryTableExists(db: NodePgDatabase): Promise<void>;
package/dist/index.d.ts DELETED
@@ -1,14 +0,0 @@
1
- export * from "./connection";
2
- export * from "./interfaces";
3
- export * from "./PostgresBackendDriver";
4
- export * from "./databasePoolManager";
5
- export * from "./schema/auth-schema";
6
- export * from "./schema/generate-drizzle-schema-logic";
7
- export * from "./schema/generate-drizzle-schema";
8
- export * from "./utils/drizzle-conditions";
9
- export * from "./services/realtimeService";
10
- export * from "./websocket";
11
- export * from "./collections/PostgresCollectionRegistry";
12
- export * from "./services/BranchService";
13
- export * from "./PostgresBootstrapper";
14
- export * from "./PostgresAdapter";