diff --git a/src/packages/pongo/src/main/client.ts b/src/packages/pongo/src/main/client.ts index 64b1bf9..ebd31de 100644 --- a/src/packages/pongo/src/main/client.ts +++ b/src/packages/pongo/src/main/client.ts @@ -1,5 +1,5 @@ import { getDbClient } from './dbClient'; -import type { PongoClient, PongoDb } from './typing'; +import type { PongoClient, PongoDb } from './typing/operations'; export const pongoClient = (connectionString: string): PongoClient => { const dbClient = getDbClient(connectionString); diff --git a/src/packages/pongo/src/main/dbClient.ts b/src/packages/pongo/src/main/dbClient.ts index fa31ead..6e79ade 100644 --- a/src/packages/pongo/src/main/dbClient.ts +++ b/src/packages/pongo/src/main/dbClient.ts @@ -1,5 +1,5 @@ import { postgresClient } from '../postgres'; -import type { PongoCollection } from './typing'; +import type { PongoCollection } from './typing/operations'; export interface DbClient { connect(): Promise; diff --git a/src/packages/pongo/src/main/index.ts b/src/packages/pongo/src/main/index.ts index cbc1b7c..5e2854d 100644 --- a/src/packages/pongo/src/main/index.ts +++ b/src/packages/pongo/src/main/index.ts @@ -1,3 +1,3 @@ export * from './client'; export * from './dbClient'; -export * from './typing'; +export * from './typing/operations'; diff --git a/src/packages/pongo/src/main/typing/entries.ts b/src/packages/pongo/src/main/typing/entries.ts new file mode 100644 index 0000000..c6c3a58 --- /dev/null +++ b/src/packages/pongo/src/main/typing/entries.ts @@ -0,0 +1,12 @@ +type Entry = { + [K in keyof Required]: [K, Required[K]]; +}[keyof Required]; + +type IterableEntry = Entry & { + [Symbol.iterator](): Iterator>; +}; + +export const entries = (obj: T): IterableEntry[] => + Object.entries(obj).map(([key, value]) => [key as keyof T, value]); + +export type NonPartial = { [K in keyof Required]: T[K] }; diff --git a/src/packages/pongo/src/main/typing/index.ts b/src/packages/pongo/src/main/typing/index.ts new file mode 100644 index 0000000..d158c1b --- /dev/null +++ b/src/packages/pongo/src/main/typing/index.ts @@ -0,0 +1,2 @@ +export * from './entries'; +export * from './operations'; diff --git a/src/packages/pongo/src/main/typing.ts b/src/packages/pongo/src/main/typing/operations.ts similarity index 100% rename from src/packages/pongo/src/main/typing.ts rename to src/packages/pongo/src/main/typing/operations.ts diff --git a/src/packages/pongo/src/postgres/filter/index.ts b/src/packages/pongo/src/postgres/filter/index.ts index 2c08a14..f0532e2 100644 --- a/src/packages/pongo/src/postgres/filter/index.ts +++ b/src/packages/pongo/src/postgres/filter/index.ts @@ -1,4 +1,5 @@ import type { PongoFilter } from '../../main'; +import { entries } from '../../main/typing'; import { Operators, handleOperator, hasOperators } from './queryOperators'; const AND = 'AND'; @@ -18,7 +19,7 @@ const constructComplexFilterQuery = ( ): string => { const isEquality = !hasOperators(value); - return Object.entries(value) + return entries(value) .map( ([nestedKey, val]) => isEquality diff --git a/src/packages/pongo/src/postgres/filter/queryOperators.ts b/src/packages/pongo/src/postgres/filter/queryOperators.ts index e546331..fe5d3a7 100644 --- a/src/packages/pongo/src/postgres/filter/queryOperators.ts +++ b/src/packages/pongo/src/postgres/filter/queryOperators.ts @@ -1,4 +1,5 @@ import format from 'pg-format'; +import { entries } from '../../main/typing'; export const Operators = { $eq: '$eq', @@ -67,7 +68,7 @@ export const handleOperator = ( (value as unknown[]).map((v) => format('%L', v)).join(', '), ); case '$elemMatch': { - const subQuery = Object.entries(value as Record) + const subQuery = entries(value as Record) .map(([subKey, subValue]) => format(`@."%s" == %s`, subKey, JSON.stringify(subValue)), ) diff --git a/src/packages/pongo/src/postgres/update/index.ts b/src/packages/pongo/src/postgres/update/index.ts index e634a95..08ea174 100644 --- a/src/packages/pongo/src/postgres/update/index.ts +++ b/src/packages/pongo/src/postgres/update/index.ts @@ -1,7 +1,24 @@ import type { $inc, $push, $set, $unset, PongoUpdate } from '../../main'; +import { entries } from '../../main/typing'; import { sql, type SQL } from '../sql'; -export const buildUpdateQuery = (update: PongoUpdate): SQL => { +export const buildUpdateQuery = (update: PongoUpdate): SQL => + entries(update).reduce((currentUpdateQuery, [op, value]) => { + switch (op) { + case '$set': + return buildSetQuery(value, currentUpdateQuery); + case '$unset': + return buildUnsetQuery(value, currentUpdateQuery); + case '$inc': + return buildIncQuery(value, currentUpdateQuery); + case '$push': + return buildPushQuery(value, currentUpdateQuery); + default: + return currentUpdateQuery; + } + }, sql('data')); + +export const buildUpdateQueryOld = (update: PongoUpdate): SQL => { let updateQuery = sql('data'); if ('$set' in update && update.$set) diff --git a/src/tsconfig.shared.json b/src/tsconfig.shared.json index 4b62eb4..ccce864 100644 --- a/src/tsconfig.shared.json +++ b/src/tsconfig.shared.json @@ -39,6 +39,7 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ + "exactOptionalPropertyTypes": true, "noUnusedLocals": false /* Report errors on unused locals. */, "noUnusedParameters": false /* Report errors on unused parameters. */, "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,