Skip to content

Commit d4f9e0d

Browse files
committed
fix: use Queryable interface instead of Pool for pgsql-test compatibility
- ModuleConfigLoader accepts any object with query() method - Works with both pg.Pool (production) and PgTestClient (testing) - Fix seed adapters to use ctx.pg instead of ctx.pool - Make pg an optional peer dependency
1 parent f9a79c9 commit d4f9e0d

7 files changed

Lines changed: 31 additions & 27 deletions

File tree

packages/module-loader/__tests__/module-loader.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
*/
1515
const metaSchemaSeed: SeedAdapter = {
1616
async seed(ctx) {
17-
const { pool } = ctx;
17+
const pool = ctx.pg;
1818

1919
await pool.query(`
2020
CREATE SCHEMA IF NOT EXISTS metaschema_public;
@@ -111,7 +111,7 @@ const metaSchemaSeed: SeedAdapter = {
111111
*/
112112
const testDataSeed: SeedAdapter = {
113113
async seed(ctx) {
114-
const { pool } = ctx;
114+
const pool = ctx.pg;
115115

116116
// Create a test database entry
117117
await pool.query(`
@@ -198,7 +198,7 @@ describe('ModuleLoader', () => {
198198
let loader: ModuleLoader;
199199

200200
beforeEach(() => {
201-
loader = new ModuleLoader({ pool: pg.pool, ttlMs: 0 });
201+
loader = new ModuleLoader({ pool: pg, ttlMs: 0 });
202202
});
203203

204204
describe('function module', () => {
@@ -303,7 +303,7 @@ describe('ModuleLoader', () => {
303303

304304
describe('caching', () => {
305305
it('caches results within TTL', async () => {
306-
const loaderWithTtl = new ModuleLoader({ pool: pg.pool, ttlMs: 60_000 });
306+
const loaderWithTtl = new ModuleLoader({ pool: pg, ttlMs: 60_000 });
307307

308308
const first = await loaderWithTtl.function.loadAll(TEST_DB_ID);
309309
const second = await loaderWithTtl.function.loadAll(TEST_DB_ID);
@@ -317,7 +317,7 @@ describe('ModuleLoader', () => {
317317
});
318318

319319
it('invalidate clears cache for specific database', async () => {
320-
const loaderWithTtl = new ModuleLoader({ pool: pg.pool, ttlMs: 60_000 });
320+
const loaderWithTtl = new ModuleLoader({ pool: pg, ttlMs: 60_000 });
321321

322322
const first = await loaderWithTtl.function.loadAll(TEST_DB_ID);
323323
loaderWithTtl.function.invalidate(TEST_DB_ID);
@@ -326,7 +326,7 @@ describe('ModuleLoader', () => {
326326
});
327327

328328
it('facade invalidate clears all sub-loader caches', async () => {
329-
const loaderWithTtl = new ModuleLoader({ pool: pg.pool, ttlMs: 60_000 });
329+
const loaderWithTtl = new ModuleLoader({ pool: pg, ttlMs: 60_000 });
330330

331331
await loaderWithTtl.function.loadAll(TEST_DB_ID);
332332
await loaderWithTtl.namespace.loadAll(TEST_DB_ID);

packages/module-loader/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020
"lint": "eslint . --fix",
2121
"test": "jest"
2222
},
23-
"dependencies": {
24-
"pg": "^8.13.0"
23+
"dependencies": {},
24+
"peerDependencies": {
25+
"pg": ">=8.0.0"
26+
},
27+
"peerDependenciesMeta": {
28+
"pg": { "optional": true }
2529
},
2630
"devDependencies": {
2731
"@types/node": "^22.10.4",

packages/module-loader/src/generic-loader.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import type { Pool } from 'pg';
1+
/** Minimal query interface compatible with both pg.Pool and pg.Client. */
2+
export interface Queryable {
3+
query(text: string, values?: unknown[]): Promise<{ rows: Record<string, unknown>[] }>;
4+
}
25

36
export interface ScopedModuleConfig {
47
scope: string;
@@ -37,20 +40,20 @@ interface CacheEntry<T> {
3740
*/
3841
export class ModuleConfigLoader<T extends ScopedModuleConfig> {
3942
private cache = new Map<string, CacheEntry<T>>();
40-
private pool: Pool;
43+
private queryable: Queryable;
4144
private sql: string;
4245
private moduleName: string;
4346
private mapper: (row: Record<string, unknown>) => T;
4447
private ttlMs: number;
4548

4649
constructor(opts: {
47-
pool: Pool;
50+
pool: Queryable;
4851
sql: string;
4952
moduleName: string;
5053
mapper: (row: Record<string, unknown>) => T;
5154
ttlMs?: number;
5255
}) {
53-
this.pool = opts.pool;
56+
this.queryable = opts.pool;
5457
this.sql = opts.sql;
5558
this.moduleName = opts.moduleName;
5659
this.mapper = opts.mapper;
@@ -66,7 +69,7 @@ export class ModuleConfigLoader<T extends ScopedModuleConfig> {
6669
return cached.data;
6770
}
6871

69-
const { rows } = await this.pool.query(this.sql, [databaseId]);
72+
const { rows } = await this.queryable.query(this.sql, [databaseId]);
7073
const configs = rows.map(this.mapper);
7174
this.cache.set(databaseId, { data: configs, expiresAt: Date.now() + this.ttlMs });
7275
return configs;

packages/module-loader/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export type { ScopedModuleConfig } from './generic-loader';
2-
export { AmbiguousScopeError,ModuleConfigLoader, ModuleNotProvisionedError } from './generic-loader';
1+
export type { Queryable, ScopedModuleConfig } from './generic-loader';
2+
export { AmbiguousScopeError, ModuleConfigLoader, ModuleNotProvisionedError } from './generic-loader';
33
export type {
44
FunctionModuleConfig,
55
InvocationModuleConfig,

packages/module-loader/src/loaders.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { Pool } from 'pg';
2-
1+
import type { Queryable } from './generic-loader';
32
import { ModuleConfigLoader } from './generic-loader';
43

54
// ─── Config Types ────────────────────────────────────────────────────────────
@@ -108,7 +107,7 @@ const INVOCATION_MODULE_SQL = `
108107

109108
// ─── Loader Factories ────────────────────────────────────────────────────────
110109

111-
export function createFunctionLoader(pool: Pool, ttlMs?: number) {
110+
export function createFunctionLoader(pool: Queryable, ttlMs?: number) {
112111
return new ModuleConfigLoader<FunctionModuleConfig>({
113112
pool,
114113
sql: FUNCTION_MODULE_SQL,
@@ -124,7 +123,7 @@ export function createFunctionLoader(pool: Pool, ttlMs?: number) {
124123
});
125124
}
126125

127-
export function createNamespaceLoader(pool: Pool, ttlMs?: number) {
126+
export function createNamespaceLoader(pool: Queryable, ttlMs?: number) {
128127
return new ModuleConfigLoader<NamespaceModuleConfig>({
129128
pool,
130129
sql: NAMESPACE_MODULE_SQL,
@@ -140,7 +139,7 @@ export function createNamespaceLoader(pool: Pool, ttlMs?: number) {
140139
});
141140
}
142141

143-
export function createSecretsLoader(pool: Pool, ttlMs?: number) {
142+
export function createSecretsLoader(pool: Queryable, ttlMs?: number) {
144143
return new ModuleConfigLoader<SecretsModuleConfig>({
145144
pool,
146145
sql: SECRETS_MODULE_SQL,
@@ -155,7 +154,7 @@ export function createSecretsLoader(pool: Pool, ttlMs?: number) {
155154
});
156155
}
157156

158-
export function createStorageLoader(pool: Pool, ttlMs?: number) {
157+
export function createStorageLoader(pool: Queryable, ttlMs?: number) {
159158
return new ModuleConfigLoader<StorageModuleConfig>({
160159
pool,
161160
sql: STORAGE_MODULE_SQL,
@@ -171,7 +170,7 @@ export function createStorageLoader(pool: Pool, ttlMs?: number) {
171170
});
172171
}
173172

174-
export function createInvocationLoader(pool: Pool, ttlMs?: number) {
173+
export function createInvocationLoader(pool: Queryable, ttlMs?: number) {
175174
return new ModuleConfigLoader<InvocationModuleConfig>({
176175
pool,
177176
sql: INVOCATION_MODULE_SQL,

packages/module-loader/src/module-loader.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import type { Pool } from 'pg';
2-
3-
import type { ModuleConfigLoader } from './generic-loader';
1+
import type { ModuleConfigLoader, Queryable } from './generic-loader';
42
import type {
53
FunctionModuleConfig,
64
InvocationModuleConfig,
@@ -17,7 +15,7 @@ import {
1715
} from './loaders';
1816

1917
export interface ModuleLoaderOptions {
20-
pool: Pool;
18+
pool: Queryable;
2119
ttlMs?: number;
2220
}
2321

pnpm-lock.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)