diff --git a/src/package-lock.json b/src/package-lock.json index e5818a9..b704189 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@event-driven-io/pongo-core", - "version": "0.14.1", + "version": "0.14.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@event-driven-io/pongo-core", - "version": "0.14.1", + "version": "0.14.2", "workspaces": [ "packages/dumbo", "packages/pongo" @@ -8611,7 +8611,7 @@ }, "packages/pongo": { "name": "@event-driven-io/pongo", - "version": "0.14.1", + "version": "0.14.2", "dependencies": { "pg-connection-string": "^2.6.4" }, diff --git a/src/package.json b/src/package.json index cb1eb20..8a56138 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "@event-driven-io/pongo-core", - "version": "0.14.1", + "version": "0.14.2", "description": "Pongo - Mongo with strong consistency on top of Postgres", "type": "module", "engines": { diff --git a/src/packages/pongo/package.json b/src/packages/pongo/package.json index 5803ca8..1c84524 100644 --- a/src/packages/pongo/package.json +++ b/src/packages/pongo/package.json @@ -1,6 +1,6 @@ { "name": "@event-driven-io/pongo", - "version": "0.14.1", + "version": "0.14.2", "description": "Pongo - Mongo with strong consistency on top of Postgres", "type": "module", "scripts": { diff --git a/src/packages/pongo/src/commandLine/configFile.ts b/src/packages/pongo/src/commandLine/configFile.ts index ab7766e..0bec5d3 100644 --- a/src/packages/pongo/src/commandLine/configFile.ts +++ b/src/packages/pongo/src/commandLine/configFile.ts @@ -1,10 +1,11 @@ import { Command } from 'commander'; import fs from 'node:fs'; -import { objectEntries, type PongoSchemaConfig } from '../core'; import { + objectEntries, toDbSchemaMetadata, type PongoDbSchemaMetadata, -} from '../core/typing/schema'; + type PongoSchemaConfig, +} from '../core'; const formatTypeName = (input: string): string => { if (input.length === 0) { diff --git a/src/packages/pongo/src/core/pongoClient.ts b/src/packages/pongo/src/core/pongoClient.ts index a296f24..d964274 100644 --- a/src/packages/pongo/src/core/pongoClient.ts +++ b/src/packages/pongo/src/core/pongoClient.ts @@ -7,12 +7,12 @@ import pg from 'pg'; import type { PostgresDbClientOptions } from '../postgres'; import { getPongoDb, type AllowedDbClientOptions } from './pongoDb'; import { pongoSession } from './pongoSession'; -import type { PongoClient, PongoDb, PongoSession } from './typing/operations'; import { proxyClientWithSchema, type PongoClientSchema, type PongoClientWithSchema, -} from './typing/schema'; +} from './schema'; +import type { PongoClient, PongoDb, PongoSession } from './typing'; export type PooledPongoClientOptions = | { diff --git a/src/packages/pongo/src/core/schema/index.ts b/src/packages/pongo/src/core/schema/index.ts index 74b1e9c..121f91a 100644 --- a/src/packages/pongo/src/core/schema/index.ts +++ b/src/packages/pongo/src/core/schema/index.ts @@ -1,4 +1,191 @@ -import type { PongoClientSchema } from '../typing/schema'; +import { + type Document, + type PongoClient, + type PongoCollection, + type PongoDb, + type PongoDocument, + objectEntries, +} from '../typing'; + +export interface PongoCollectionSchema< + // eslint-disable-next-line @typescript-eslint/no-unused-vars + T extends PongoDocument = PongoDocument, +> { + name: string; +} + +// Database schema interface +export interface PongoDbSchema< + T extends Record = Record< + string, + PongoCollectionSchema + >, +> { + name?: string; + collections: T; +} + +export interface PongoClientSchema< + T extends Record = Record, +> { + dbs: T; +} + +export type CollectionsMap> = { + [K in keyof T]: PongoCollection< + T[K] extends PongoCollectionSchema ? U : PongoDocument + >; +}; + +export type PongoDbWithSchema< + T extends Record, + ConnectorType extends string = string, +> = CollectionsMap & PongoDb; + +export type DBsMap> = { + [K in keyof T]: CollectionsMap; +}; + +export type PongoClientWithSchema = DBsMap< + T['dbs'] +> & + PongoClient; + +const pongoCollectionSchema = ( + name: string, +): PongoCollectionSchema => ({ + name, +}); + +function pongoDbSchema>( + collections: T, +): PongoDbSchema; +function pongoDbSchema>( + name: string, + collections: T, +): PongoDbSchema; +function pongoDbSchema>( + nameOrCollections: string | T, + collections?: T | undefined, +): PongoDbSchema { + if (collections === undefined) { + if (typeof nameOrCollections === 'string') { + throw new Error('You need to provide colleciton definition'); + } + return { + collections: nameOrCollections, + }; + } + + return nameOrCollections && typeof nameOrCollections === 'string' + ? { + name: nameOrCollections, + collections, + } + : { collections: collections }; +} + +const pongoClientSchema = >( + dbs: T, +): PongoClientSchema => ({ + dbs, +}); + +export const pongoSchema = { + client: pongoClientSchema, + db: pongoDbSchema, + collection: pongoCollectionSchema, +}; + +// Factory function to create DB instances +export const proxyPongoDbWithSchema = < + T extends Record, + ConnectorType extends string = string, +>( + pongoDb: PongoDb, + dbSchema: PongoDbSchema, + collections: Map>, +): PongoDbWithSchema => { + const collectionNames = Object.keys(dbSchema.collections); + + for (const collectionName of collectionNames) { + collections.set(collectionName, pongoDb.collection(collectionName)); + } + + return new Proxy( + pongoDb as PongoDb & { + [key: string]: unknown; + }, + { + get(target, prop: string) { + return collections.get(prop) ?? target[prop]; + }, + }, + ) as PongoDbWithSchema; +}; + +// Factory function to create Client instances +export const proxyClientWithSchema = < + TypedClientSchema extends PongoClientSchema, +>( + client: PongoClient, + schema: TypedClientSchema | undefined, +): PongoClientWithSchema => { + if (!schema) return client as PongoClientWithSchema; + + const dbNames = Object.keys(schema.dbs); + + return new Proxy( + client as PongoClient & { + [key: string]: unknown; + }, + { + get(target, prop: string) { + if (dbNames.includes(prop)) return client.db(schema.dbs[prop]?.name); + + return target[prop]; + }, + }, + ) as PongoClientWithSchema; +}; + +export type PongoCollectionSchemaMetadata = { + name: string; +}; + +export type PongoDbSchemaMetadata = { + name?: string | undefined; + collections: PongoCollectionSchemaMetadata[]; +}; + +export type PongoClientSchemaMetadata = { + databases: PongoDbSchemaMetadata[]; + database: (name?: string) => PongoDbSchemaMetadata | undefined; +}; + +export const toDbSchemaMetadata = ( + schema: TypedDbSchema, +): PongoDbSchemaMetadata => ({ + name: schema.name, + collections: objectEntries(schema.collections).map((c) => ({ + name: c[1].name, + })), +}); + +export const toClientSchemaMetadata = < + TypedClientSchema extends PongoClientSchema, +>( + schema: TypedClientSchema, +): PongoClientSchemaMetadata => { + const databases = objectEntries(schema.dbs).map((e) => + toDbSchemaMetadata(e[1]), + ); + + return { + databases, + database: (name) => databases.find((db) => db.name === name), + }; +}; export interface PongoSchemaConfig< TypedClientSchema extends PongoClientSchema = PongoClientSchema, diff --git a/src/packages/pongo/src/core/typing/schema.ts b/src/packages/pongo/src/core/typing/schema.ts deleted file mode 100644 index 0cf06b6..0000000 --- a/src/packages/pongo/src/core/typing/schema.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { objectEntries } from './entries'; -import { - type Document, - type PongoClient, - type PongoCollection, - type PongoDb, - type PongoDocument, -} from './operations'; - -export interface PongoCollectionSchema< - // eslint-disable-next-line @typescript-eslint/no-unused-vars - T extends PongoDocument = PongoDocument, -> { - name: string; -} - -// Database schema interface -export interface PongoDbSchema< - T extends Record = Record< - string, - PongoCollectionSchema - >, -> { - name?: string; - collections: T; -} - -export interface PongoClientSchema< - T extends Record = Record, -> { - dbs: T; -} - -export type CollectionsMap> = { - [K in keyof T]: PongoCollection< - T[K] extends PongoCollectionSchema ? U : PongoDocument - >; -}; - -export type PongoDbWithSchema< - T extends Record, - ConnectorType extends string = string, -> = CollectionsMap & PongoDb; - -export type DBsMap> = { - [K in keyof T]: CollectionsMap; -}; - -export type PongoClientWithSchema = DBsMap< - T['dbs'] -> & - PongoClient; - -const pongoCollectionSchema = ( - name: string, -): PongoCollectionSchema => ({ - name, -}); - -function pongoDbSchema>( - collections: T, -): PongoDbSchema; -function pongoDbSchema>( - name: string, - collections: T, -): PongoDbSchema; -function pongoDbSchema>( - nameOrCollections: string | T, - collections?: T | undefined, -): PongoDbSchema { - if (collections === undefined) { - if (typeof nameOrCollections === 'string') { - throw new Error('You need to provide colleciton definition'); - } - return { - collections: nameOrCollections, - }; - } - - return nameOrCollections && typeof nameOrCollections === 'string' - ? { - name: nameOrCollections, - collections, - } - : { collections: collections }; -} - -const pongoClientSchema = >( - dbs: T, -): PongoClientSchema => ({ - dbs, -}); - -export const pongoSchema = { - client: pongoClientSchema, - db: pongoDbSchema, - collection: pongoCollectionSchema, -}; - -// Factory function to create DB instances -export const proxyPongoDbWithSchema = < - T extends Record, - ConnectorType extends string = string, ->( - pongoDb: PongoDb, - dbSchema: PongoDbSchema, - collections: Map>, -): PongoDbWithSchema => { - const collectionNames = Object.keys(dbSchema.collections); - - for (const collectionName of collectionNames) { - collections.set(collectionName, pongoDb.collection(collectionName)); - } - - return new Proxy( - pongoDb as PongoDb & { - [key: string]: unknown; - }, - { - get(target, prop: string) { - return collections.get(prop) ?? target[prop]; - }, - }, - ) as PongoDbWithSchema; -}; - -// Factory function to create Client instances -export const proxyClientWithSchema = < - TypedClientSchema extends PongoClientSchema, ->( - client: PongoClient, - schema: TypedClientSchema | undefined, -): PongoClientWithSchema => { - if (!schema) return client as PongoClientWithSchema; - - const dbNames = Object.keys(schema.dbs); - - return new Proxy( - client as PongoClient & { - [key: string]: unknown; - }, - { - get(target, prop: string) { - if (dbNames.includes(prop)) return client.db(schema.dbs[prop]?.name); - - return target[prop]; - }, - }, - ) as PongoClientWithSchema; -}; - -export type PongoCollectionSchemaMetadata = { - name: string; -}; - -export type PongoDbSchemaMetadata = { - name?: string | undefined; - collections: PongoCollectionSchemaMetadata[]; -}; - -export type PongoClientSchemaMetadata = { - databases: PongoDbSchemaMetadata[]; - database: (name?: string) => PongoDbSchemaMetadata | undefined; -}; - -export const toDbSchemaMetadata = ( - schema: TypedDbSchema, -): PongoDbSchemaMetadata => ({ - name: schema.name, - collections: objectEntries(schema.collections).map((c) => ({ - name: c[1].name, - })), -}); - -export const toClientSchemaMetadata = < - TypedClientSchema extends PongoClientSchema, ->( - schema: TypedClientSchema, -): PongoClientSchemaMetadata => { - const databases = objectEntries(schema.dbs).map((e) => - toDbSchemaMetadata(e[1]), - ); - - return { - databases, - database: (name) => databases.find((db) => db.name === name), - }; -}; diff --git a/src/packages/pongo/src/e2e/cli-config.ts b/src/packages/pongo/src/e2e/cli-config.ts index 9a622c9..87856a1 100644 --- a/src/packages/pongo/src/e2e/cli-config.ts +++ b/src/packages/pongo/src/e2e/cli-config.ts @@ -1,4 +1,4 @@ -import { pongoSchema } from '../core/typing/schema'; +import { pongoSchema } from '../core'; type User = { name: string }; diff --git a/src/packages/pongo/src/e2e/postgres.e2e.spec.ts b/src/packages/pongo/src/e2e/postgres.e2e.spec.ts index 48a4359..4e481d0 100644 --- a/src/packages/pongo/src/e2e/postgres.e2e.spec.ts +++ b/src/packages/pongo/src/e2e/postgres.e2e.spec.ts @@ -12,7 +12,7 @@ import { type PongoClient, type PongoDb, } from '../'; -import { pongoSchema } from '../core/typing/schema'; +import { pongoSchema } from '../core'; import { MongoClient, type Db } from '../shim'; type History = { street: string }; diff --git a/src/packages/pongo/src/postgres/dbClient.ts b/src/packages/pongo/src/postgres/dbClient.ts index 15bcae2..ebbb76c 100644 --- a/src/packages/pongo/src/postgres/dbClient.ts +++ b/src/packages/pongo/src/postgres/dbClient.ts @@ -13,11 +13,11 @@ import { objectEntries, pongoCollection, pongoCollectionSchemaComponent, + proxyPongoDbWithSchema, type PongoCollection, type PongoDb, type PongoDbClientOptions, } from '../core'; -import { proxyPongoDbWithSchema } from '../core/typing/schema'; import { postgresSQLBuilder } from './sqlBuilder'; export type PostgresDbClientOptions = PongoDbClientOptions; diff --git a/src/packages/pongo/src/postgres/migrations/migrations.int.spec.ts b/src/packages/pongo/src/postgres/migrations/migrations.int.spec.ts index 7afbd02..00d56b2 100644 --- a/src/packages/pongo/src/postgres/migrations/migrations.int.spec.ts +++ b/src/packages/pongo/src/postgres/migrations/migrations.int.spec.ts @@ -5,8 +5,7 @@ import { } from '@testcontainers/postgresql'; import assert from 'assert'; import { after, before, beforeEach, describe, it } from 'node:test'; -import { pongoClient, type PongoClient } from '../../core'; -import { pongoSchema } from '../../core/typing/schema'; +import { pongoClient, type PongoClient, pongoSchema } from '../../core'; void describe('Migration Integration Tests', () => { let pool: Dumbo;