From 3cced96b1577fde09440997528120e3a4d15ca4c Mon Sep 17 00:00:00 2001 From: prostgles Date: Sun, 28 Apr 2024 18:42:48 +0300 Subject: [PATCH] add having --- examples/server/typescript/DBoGenerated.d.ts | 168 --------- .../server/typescript/DBoGenerated.d.ts.map | 1 - examples/server/typescript/DBoGenerated.js | 5 - .../server/typescript/DBoGenerated.js.map | 1 - examples/server/typescript/DBoGenerated.ts | 125 ------- examples/server/typescript/index.ts | 2 - lib/AuthHandler.ts | 1 + lib/DboBuilder/QueryBuilder/getNewQuery.ts | 11 +- lib/DboBuilder/QueryBuilder/prepareHaving.ts | 23 ++ lib/DboBuilder/TableHandler/TableHandler.ts | 28 +- lib/DboBuilder/TableHandler/upsert.ts | 32 ++ lib/DboBuilder/ViewHandler/ViewHandler.ts | 26 +- lib/DboBuilder/find.ts | 29 +- lib/DboBuilder/getCondition.ts | 12 +- lib/Filtering.ts | 40 ++- package-lock.json | 325 ++++++++++-------- package.json | 18 +- tests/client/package-lock.json | 16 +- tests/client/package.json | 2 +- tests/clientRestApi.spec.ts | 59 ++-- tests/isomorphicQueries.spec.ts | 32 +- tests/server/package-lock.json | 34 +- 22 files changed, 399 insertions(+), 591 deletions(-) delete mode 100644 examples/server/typescript/DBoGenerated.d.ts delete mode 100644 examples/server/typescript/DBoGenerated.d.ts.map delete mode 100644 examples/server/typescript/DBoGenerated.js delete mode 100644 examples/server/typescript/DBoGenerated.js.map delete mode 100644 examples/server/typescript/DBoGenerated.ts create mode 100644 lib/DboBuilder/QueryBuilder/prepareHaving.ts create mode 100644 lib/DboBuilder/TableHandler/upsert.ts diff --git a/examples/server/typescript/DBoGenerated.d.ts b/examples/server/typescript/DBoGenerated.d.ts deleted file mode 100644 index 4b64222e..00000000 --- a/examples/server/typescript/DBoGenerated.d.ts +++ /dev/null @@ -1,168 +0,0 @@ -export declare type Filter = object | {} | undefined; -export declare type GroupFilter = { - $and: Filter; -} | { - $or: Filter; -}; -export declare type FieldFilter = object | string[] | "*" | ""; -export declare type OrderBy = { - key: string; - asc: boolean; -}[] | { - [key: string]: boolean; -}[] | string | string[]; -export declare type SelectParams = { - select?: FieldFilter; - limit?: number; - offset?: number; - orderBy?: OrderBy; - expectOne?: boolean; -}; -export declare type UpdateParams = { - returning?: FieldFilter; - onConflictDoNothing?: boolean; - TxHandler: any; - fixIssues?: boolean; - multi?: boolean; -}; -export declare type InsertParams = { - returning?: FieldFilter; - onConflictDoNothing?: boolean; - fixIssues?: boolean; -}; -export declare type DeleteParams = { - returning?: FieldFilter; -}; -export declare type TxCB = { - (t: DBObj): (any | void | Promise<(any | void)>); -}; -export declare type Items = { - name?: string; - h?: Array; - id?: number; -}; -export declare type Items_Filter = Items | object | { - $and: (Items | object)[]; -} | { - $or: (Items | object)[]; -}; -export declare type Items2 = { - id?: number; - h?: Array; - name?: string; -}; -export declare type Items2_Filter = Items2 | object | { - $and: (Items2 | object)[]; -} | { - $or: (Items2 | object)[]; -}; -export declare type Items3 = { - h?: Array; - name?: string; - id?: number; -}; -export declare type Items3_Filter = Items3 | object | { - $and: (Items3 | object)[]; -} | { - $or: (Items3 | object)[]; -}; -export declare type Table = { - id?: string; -}; -export declare type Table_Filter = Table | object | { - $and: (Table | object)[]; -} | { - $or: (Table | object)[]; -}; -export declare type Transaction = { - id?: string; -}; -export declare type Transaction_Filter = Transaction | object | { - $and: (Transaction | object)[]; -} | { - $or: (Transaction | object)[]; -}; -export declare type DBO_items = { - find: (filter?: Items_Filter, selectParams?: SelectParams) => Promise; - findOne: (filter?: Items_Filter, selectParams?: SelectParams) => Promise; - subscribe: (filter: Items_Filter, params: SelectParams, onData: (items: Items[]) => any) => Promise<{ - unsubscribe: () => any; - }>; - subscribeOne: (filter: Items_Filter, params: SelectParams, onData: (item: Items) => any) => Promise<{ - unsubscribe: () => any; - }>; - count: (filter?: Items_Filter) => Promise; - update: (filter: Items_Filter, newData: Items, params?: UpdateParams) => Promise; - upsert: (filter: Items_Filter, newData: Items, params?: UpdateParams) => Promise; - insert: (data: (Items | Items[]), params?: InsertParams) => Promise; - delete: (filter: Items_Filter, params?: DeleteParams) => Promise; -}; -export declare type DBO_items2 = { - find: (filter?: Items2_Filter, selectParams?: SelectParams) => Promise; - findOne: (filter?: Items2_Filter, selectParams?: SelectParams) => Promise; - subscribe: (filter: Items2_Filter, params: SelectParams, onData: (items: Items2[]) => any) => Promise<{ - unsubscribe: () => any; - }>; - subscribeOne: (filter: Items2_Filter, params: SelectParams, onData: (item: Items2) => any) => Promise<{ - unsubscribe: () => any; - }>; - count: (filter?: Items2_Filter) => Promise; - update: (filter: Items2_Filter, newData: Items2, params?: UpdateParams) => Promise; - upsert: (filter: Items2_Filter, newData: Items2, params?: UpdateParams) => Promise; - insert: (data: (Items2 | Items2[]), params?: InsertParams) => Promise; - delete: (filter: Items2_Filter, params?: DeleteParams) => Promise; -}; -export declare type DBO_items3 = { - find: (filter?: Items3_Filter, selectParams?: SelectParams) => Promise; - findOne: (filter?: Items3_Filter, selectParams?: SelectParams) => Promise; - subscribe: (filter: Items3_Filter, params: SelectParams, onData: (items: Items3[]) => any) => Promise<{ - unsubscribe: () => any; - }>; - subscribeOne: (filter: Items3_Filter, params: SelectParams, onData: (item: Items3) => any) => Promise<{ - unsubscribe: () => any; - }>; - count: (filter?: Items3_Filter) => Promise; - update: (filter: Items3_Filter, newData: Items3, params?: UpdateParams) => Promise; - upsert: (filter: Items3_Filter, newData: Items3, params?: UpdateParams) => Promise; - insert: (data: (Items3 | Items3[]), params?: InsertParams) => Promise; - delete: (filter: Items3_Filter, params?: DeleteParams) => Promise; -}; -export declare type DBO_table = { - find: (filter?: Table_Filter, selectParams?: SelectParams) => Promise; - findOne: (filter?: Table_Filter, selectParams?: SelectParams) => Promise; - subscribe: (filter: Table_Filter, params: SelectParams, onData: (items: Table[]) => any) => Promise<{ - unsubscribe: () => any; - }>; - subscribeOne: (filter: Table_Filter, params: SelectParams, onData: (item: Table) => any) => Promise<{ - unsubscribe: () => any; - }>; - count: (filter?: Table_Filter) => Promise; - update: (filter: Table_Filter, newData: Table, params?: UpdateParams) => Promise; - upsert: (filter: Table_Filter, newData: Table, params?: UpdateParams) => Promise; - insert: (data: (Table | Table[]), params?: InsertParams) => Promise; - delete: (filter: Table_Filter, params?: DeleteParams) => Promise; -}; -export declare type DBO_transaction = { - find: (filter?: Transaction_Filter, selectParams?: SelectParams) => Promise; - findOne: (filter?: Transaction_Filter, selectParams?: SelectParams) => Promise; - subscribe: (filter: Transaction_Filter, params: SelectParams, onData: (items: Transaction[]) => any) => Promise<{ - unsubscribe: () => any; - }>; - subscribeOne: (filter: Transaction_Filter, params: SelectParams, onData: (item: Transaction) => any) => Promise<{ - unsubscribe: () => any; - }>; - count: (filter?: Transaction_Filter) => Promise; - update: (filter: Transaction_Filter, newData: Transaction, params?: UpdateParams) => Promise; - upsert: (filter: Transaction_Filter, newData: Transaction, params?: UpdateParams) => Promise; - insert: (data: (Transaction | Transaction[]), params?: InsertParams) => Promise; - delete: (filter: Transaction_Filter, params?: DeleteParams) => Promise; -}; -export declare type DBObj = { - items: DBO_items; - items2: DBO_items2; - items3: DBO_items3; - table: DBO_table; - transaction: DBO_transaction; - tt: (t: TxCB) => Promise; -}; -//# sourceMappingURL=DBoGenerated.d.ts.map \ No newline at end of file diff --git a/examples/server/typescript/DBoGenerated.d.ts.map b/examples/server/typescript/DBoGenerated.d.ts.map deleted file mode 100644 index 412eff59..00000000 --- a/examples/server/typescript/DBoGenerated.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DBoGenerated.d.ts","sourceRoot":"","sources":["DBoGenerated.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/examples/server/typescript/DBoGenerated.js b/examples/server/typescript/DBoGenerated.js deleted file mode 100644 index 4e5da5b9..00000000 --- a/examples/server/typescript/DBoGenerated.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; -/* This file was generated by Prostgles -*/ -Object.defineProperty(exports, "__esModule", { value: true }); -//# sourceMappingURL=DBoGenerated.js.map \ No newline at end of file diff --git a/examples/server/typescript/DBoGenerated.js.map b/examples/server/typescript/DBoGenerated.js.map deleted file mode 100644 index e5d70105..00000000 --- a/examples/server/typescript/DBoGenerated.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DBoGenerated.js","sourceRoot":"","sources":["DBoGenerated.ts"],"names":[],"mappings":";AAAA;EACE"} \ No newline at end of file diff --git a/examples/server/typescript/DBoGenerated.ts b/examples/server/typescript/DBoGenerated.ts deleted file mode 100644 index 63344c18..00000000 --- a/examples/server/typescript/DBoGenerated.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* This file was generated by Prostgles -*/ - - -export type Filter = object | {} | undefined; -export type GroupFilter = { $and: Filter } | { $or: Filter }; -export type FieldFilter = object | string[] | "*" | ""; -export type OrderBy = { key: string, asc: boolean }[] | { [key: string]: boolean }[] | string | string[]; - -export type SelectParams = { - select?: FieldFilter; - limit?: number; - offset?: number; - orderBy?: OrderBy; - expectOne?: boolean; -} -export type UpdateParams = { - returning?: FieldFilter; - onConflictDoNothing?: boolean;TxHandler - fixIssues?: boolean; - multi?: boolean; -} -export type InsertParams = { - returning?: FieldFilter; - onConflictDoNothing?: boolean; - fixIssues?: boolean; -} -export type DeleteParams = { - returning?: FieldFilter; -}; -export type TxCB = { - (t: DBObj): (any | void | Promise<(any | void)>) -}; - -export type Items = { - name?: string; - h?: Array; - id?: number; -}; -export type Items_Filter = Items | object | { $and: (Items | object)[] } | { $or: (Items | object)[] } -export type Items2 = { - id?: number; - h?: Array; - name?: string; -}; -export type Items2_Filter = Items2 | object | { $and: (Items2 | object)[] } | { $or: (Items2 | object)[] } -export type Items3 = { - h?: Array; - name?: string; - id?: number; -}; -export type Items3_Filter = Items3 | object | { $and: (Items3 | object)[] } | { $or: (Items3 | object)[] } -export type Table = { - id?: string; -}; -export type Table_Filter = Table | object | { $and: (Table | object)[] } | { $or: (Table | object)[] } -export type Transaction = { - id?: string; -}; -export type Transaction_Filter = Transaction | object | { $and: (Transaction | object)[] } | { $or: (Transaction | object)[] } - -export type DBO_items = { - find: (filter?: Items_Filter , selectParams?: SelectParams) => Promise; - findOne: (filter?: Items_Filter , selectParams?: SelectParams) => Promise; - subscribe: (filter: Items_Filter , params: SelectParams, onData: (items: Items[]) => any) => Promise<{ unsubscribe: () => any }>; - subscribeOne: (filter: Items_Filter , params: SelectParams, onData: (item: Items) => any) => Promise<{ unsubscribe: () => any }>; - count: (filter?: Items_Filter ) => Promise; - update: (filter: Items_Filter , newData: Items, params?: UpdateParams) => Promise; - upsert: (filter: Items_Filter , newData: Items, params?: UpdateParams) => Promise; - insert: (data: (Items | Items[]), params?: InsertParams) => Promise; - delete: (filter: Items_Filter , params?: DeleteParams) => Promise; -}; -export type DBO_items2 = { - find: (filter?: Items2_Filter , selectParams?: SelectParams) => Promise; - findOne: (filter?: Items2_Filter , selectParams?: SelectParams) => Promise; - subscribe: (filter: Items2_Filter , params: SelectParams, onData: (items: Items2[]) => any) => Promise<{ unsubscribe: () => any }>; - subscribeOne: (filter: Items2_Filter , params: SelectParams, onData: (item: Items2) => any) => Promise<{ unsubscribe: () => any }>; - count: (filter?: Items2_Filter ) => Promise; - update: (filter: Items2_Filter , newData: Items2, params?: UpdateParams) => Promise; - upsert: (filter: Items2_Filter , newData: Items2, params?: UpdateParams) => Promise; - insert: (data: (Items2 | Items2[]), params?: InsertParams) => Promise; - delete: (filter: Items2_Filter , params?: DeleteParams) => Promise; -}; -export type DBO_items3 = { - find: (filter?: Items3_Filter , selectParams?: SelectParams) => Promise; - findOne: (filter?: Items3_Filter , selectParams?: SelectParams) => Promise; - subscribe: (filter: Items3_Filter , params: SelectParams, onData: (items: Items3[]) => any) => Promise<{ unsubscribe: () => any }>; - subscribeOne: (filter: Items3_Filter , params: SelectParams, onData: (item: Items3) => any) => Promise<{ unsubscribe: () => any }>; - count: (filter?: Items3_Filter ) => Promise; - update: (filter: Items3_Filter , newData: Items3, params?: UpdateParams) => Promise; - upsert: (filter: Items3_Filter , newData: Items3, params?: UpdateParams) => Promise; - insert: (data: (Items3 | Items3[]), params?: InsertParams) => Promise; - delete: (filter: Items3_Filter , params?: DeleteParams) => Promise; -}; -export type DBO_table = { - find: (filter?: Table_Filter , selectParams?: SelectParams) => Promise; - findOne: (filter?: Table_Filter , selectParams?: SelectParams) => Promise
; - subscribe: (filter: Table_Filter , params: SelectParams, onData: (items: Table[]) => any) => Promise<{ unsubscribe: () => any }>; - subscribeOne: (filter: Table_Filter , params: SelectParams, onData: (item: Table) => any) => Promise<{ unsubscribe: () => any }>; - count: (filter?: Table_Filter ) => Promise; - update: (filter: Table_Filter , newData: Table, params?: UpdateParams) => Promise; - upsert: (filter: Table_Filter , newData: Table, params?: UpdateParams) => Promise; - insert: (data: (Table | Table[]), params?: InsertParams) => Promise; - delete: (filter: Table_Filter , params?: DeleteParams) => Promise; -}; -export type DBO_transaction = { - find: (filter?: Transaction_Filter , selectParams?: SelectParams) => Promise; - findOne: (filter?: Transaction_Filter , selectParams?: SelectParams) => Promise; - subscribe: (filter: Transaction_Filter , params: SelectParams, onData: (items: Transaction[]) => any) => Promise<{ unsubscribe: () => any }>; - subscribeOne: (filter: Transaction_Filter , params: SelectParams, onData: (item: Transaction) => any) => Promise<{ unsubscribe: () => any }>; - count: (filter?: Transaction_Filter ) => Promise; - update: (filter: Transaction_Filter , newData: Transaction, params?: UpdateParams) => Promise; - upsert: (filter: Transaction_Filter , newData: Transaction, params?: UpdateParams) => Promise; - insert: (data: (Transaction | Transaction[]), params?: InsertParams) => Promise; - delete: (filter: Transaction_Filter , params?: DeleteParams) => Promise; -}; - -export type DBObj = { - items: DBO_items; - items2: DBO_items2; - items3: DBO_items3; - table: DBO_table; - transaction: DBO_transaction; - tt: (t: TxCB) => Promise ; -}; diff --git a/examples/server/typescript/index.ts b/examples/server/typescript/index.ts index 6f88452a..7c4dd2e5 100644 --- a/examples/server/typescript/index.ts +++ b/examples/server/typescript/index.ts @@ -6,8 +6,6 @@ const http = require('http').createServer(app); const io = require("socket.io")(http); http.listen(3001); -import { DBObj } from "./DBoGenerated"; - prostgles({ dbConnection: { host: "localhost", diff --git a/lib/AuthHandler.ts b/lib/AuthHandler.ts index 75ab2764..61643317 100644 --- a/lib/AuthHandler.ts +++ b/lib/AuthHandler.ts @@ -65,6 +65,7 @@ export type AuthResult = SU & { sid: string; } | { export const getLoginClientInfo = (req: AuthClientRequest): AuthClientRequest & LoginClientInfo => { if("httpReq" in req){ const ip_address = req.httpReq.ip; + if(!ip_address) throw new Error("ip_address missing from req.httpReq"); const user_agent = req.httpReq.headers["user-agent"]; return { ...req, diff --git a/lib/DboBuilder/QueryBuilder/getNewQuery.ts b/lib/DboBuilder/QueryBuilder/getNewQuery.ts index 57dffcf5..cf645d12 100644 --- a/lib/DboBuilder/QueryBuilder/getNewQuery.ts +++ b/lib/DboBuilder/QueryBuilder/getNewQuery.ts @@ -6,6 +6,7 @@ import { parseJoinPath } from "../ViewHandler/parseJoinPath"; import { prepareSortItems } from "../ViewHandler/prepareSortItems"; import { COMPUTED_FIELDS, FUNCTIONS } from "./Functions"; import { NewQuery, NewQueryJoin, SelectItemBuilder } from "./QueryBuilder"; +import { prepareHaving } from "./prepareHaving"; const JOIN_KEYS = ["$innerJoin", "$leftJoin"] as const; type ParsedJoin = @@ -181,12 +182,13 @@ export async function getNewQuery( const select = sBuilder.select; + const tableAlias = selectParams.alias; const filterOpts = await _this.prepareWhere({ filter, select, forcedFilter: tableRules?.select?.forcedFilter, filterFields: tableRules?.select?.filterFields, - tableAlias: selectParams.alias, + tableAlias, localParams, tableRule: tableRules }); @@ -203,7 +205,12 @@ export async function getNewQuery( joins: joinQueries, where, whereOpts: filterOpts, - having: "", + having: prepareHaving({ + having: selectParams.having, + select, + tableAlias, + filterFieldNames: tableRules ? _this.parseFieldFilter(tableRules?.select?.filterFields) : _this.column_names.slice(0), + }), isLeftJoin: false, limit: _this.prepareLimitQuery(selectParams.limit, validatedRules), orderByItems: prepareSortItems(selectParams.orderBy, allowedOrderByFields, selectParams.alias, select, joinQueries), diff --git a/lib/DboBuilder/QueryBuilder/prepareHaving.ts b/lib/DboBuilder/QueryBuilder/prepareHaving.ts new file mode 100644 index 00000000..06033059 --- /dev/null +++ b/lib/DboBuilder/QueryBuilder/prepareHaving.ts @@ -0,0 +1,23 @@ +import { isEmpty } from "prostgles-types"; +import type { Filter } from "../DboBuilderTypes"; +import type { SelectItemValidated } from "./QueryBuilder"; +import { parseFilterItem } from "../../Filtering"; + +type Args = { + having: Filter | undefined; + select: SelectItemValidated[]; + tableAlias: string | undefined; + filterFieldNames: string[]; +} +export const prepareHaving = ({ having, select, tableAlias, filterFieldNames }: Args) => { + if(!having || isEmpty(having)) return ""; + const selectedItem = select + .find(s => s.alias); + const havingStr = parseFilterItem({ + filter: having, + select, + tableAlias, + allowedColumnNames: filterFieldNames, + }); + return havingStr; +} \ No newline at end of file diff --git a/lib/DboBuilder/TableHandler/TableHandler.ts b/lib/DboBuilder/TableHandler/TableHandler.ts index c6748160..0f28ce09 100644 --- a/lib/DboBuilder/TableHandler/TableHandler.ts +++ b/lib/DboBuilder/TableHandler/TableHandler.ts @@ -14,6 +14,7 @@ import { _delete } from "./delete"; import { insert } from "./insert"; import { update } from "./update"; import { updateBatch } from "./updateBatch"; +import { upsert } from "./upsert"; export type ValidatedParams = { @@ -94,32 +95,7 @@ export class TableHandler extends ViewHandler { return this.delete(filter, params, param3_unused, tableRules, localParams); } - async upsert(filter: Filter, newData: AnyObject, params?: UpdateParams, table_rules?: TableRule, localParams?: LocalParams): Promise { - try { - await this._log({ command: "upsert", localParams, data: { filter, newData, params } }); - const _upsert = async function (tblH: TableHandler) { - return tblH.find(filter, { select: "", limit: 1 }, undefined, table_rules, localParams) - .then(exists => { - if (exists && exists.length) { - return tblH.update(filter, newData, params, table_rules, localParams); - } else { - return tblH.insert({ ...newData, ...filter }, params, undefined, table_rules, localParams); - } - }); - } - - /* Do it within a transaction to ensure consisency */ - if (!this.tx) { - return this.dboBuilder.getTX(dbTX => _upsert(dbTX[this.name] as TableHandler)) - } else { - return _upsert(this); - } - - } catch (e) { - if (localParams && localParams.testRule) throw e; - throw parseError(e, `dbo.${this.name}.upsert()`); - } - } + upsert = upsert.bind(this); /* External request. Cannot sync from server */ async sync(filter: Filter, params: { select?: FieldFilter }, param3_unused: undefined, table_rules: TableRule, localParams: LocalParams) { diff --git a/lib/DboBuilder/TableHandler/upsert.ts b/lib/DboBuilder/TableHandler/upsert.ts new file mode 100644 index 00000000..3b5b1a2e --- /dev/null +++ b/lib/DboBuilder/TableHandler/upsert.ts @@ -0,0 +1,32 @@ +import { AnyObject, UpdateParams } from "prostgles-types"; +import { TableHandler } from "./TableHandler"; +import { Filter, LocalParams } from "../DboBuilderTypes"; +import { TableRule } from "../../PublishParser/publishTypesAndUtils"; +import { parseError } from "../dboBuilderUtils"; + +export const upsert = async function(this: TableHandler, filter: Filter, newData: AnyObject, params?: UpdateParams, table_rules?: TableRule, localParams?: LocalParams): Promise { + try { + await this._log({ command: "upsert", localParams, data: { filter, newData, params } }); + const _upsert = async function (tblH: TableHandler) { + return tblH.find(filter, { select: "", limit: 1 }, undefined, table_rules, localParams) + .then(exists => { + if (exists && exists.length) { + return tblH.update(filter, newData, params, table_rules, localParams); + } else { + return tblH.insert({ ...newData, ...filter }, params, undefined, table_rules, localParams); + } + }); + } + + /* Do it within a transaction to ensure consisency */ + if (!this.tx) { + return this.dboBuilder.getTX(dbTX => _upsert(dbTX[this.name] as TableHandler)) + } else { + return _upsert(this); + } + + } catch (e) { + if (localParams && localParams.testRule) throw e; + throw parseError(e, `dbo.${this.name}.upsert()`); + } +} \ No newline at end of file diff --git a/lib/DboBuilder/ViewHandler/ViewHandler.ts b/lib/DboBuilder/ViewHandler/ViewHandler.ts index 74825c7b..b5bf65f6 100644 --- a/lib/DboBuilder/ViewHandler/ViewHandler.ts +++ b/lib/DboBuilder/ViewHandler/ViewHandler.ts @@ -180,7 +180,6 @@ export class ViewHandler { getInfo: tableRules?.getColumns ?? true, } as ValidatedTableRules; - /* SELECT */ if (tableRules.select) { if (!tableRules.select.fields) return throwFieldsErr("select"); @@ -201,7 +200,6 @@ export class ViewHandler { }; } - /* UPDATE */ if (tableRules.update) { if (!tableRules.update.fields) return throwFieldsErr("update"); @@ -214,7 +212,6 @@ export class ViewHandler { } } - /* INSERT */ if (tableRules.insert) { if (!tableRules.insert.fields) return throwFieldsErr("insert"); @@ -225,7 +222,6 @@ export class ViewHandler { } } - /* DELETE */ if (tableRules.delete) { if (!tableRules.delete.filterFields) return throwFieldsErr("delete", "filterFields"); @@ -243,34 +239,34 @@ export class ViewHandler { return res; } else { - const all_cols = this.column_names.slice(0); + const allCols = this.column_names.slice(0); return { allColumns, getColumns: true, getInfo: true, select: { - fields: all_cols, - filterFields: all_cols, - orderByFields: all_cols, + fields: allCols, + filterFields: allCols, + orderByFields: allCols, forcedFilter: {}, maxLimit: null, }, update: { - fields: all_cols, - filterFields: all_cols, + fields: allCols, + filterFields: allCols, forcedFilter: {}, forcedData: {}, - returningFields: all_cols + returningFields: allCols }, insert: { - fields: all_cols, + fields: allCols, forcedData: {}, - returningFields: all_cols + returningFields: allCols }, delete: { - filterFields: all_cols, + filterFields: allCols, forcedFilter: {}, - returningFields: all_cols + returningFields: allCols } }; diff --git a/lib/DboBuilder/find.ts b/lib/DboBuilder/find.ts index 1abf0638..c48d7392 100644 --- a/lib/DboBuilder/find.ts +++ b/lib/DboBuilder/find.ts @@ -13,7 +13,11 @@ export const find = async function(this: ViewHandler, filter?: Filter, selectPar try { await this._log({ command: "find", localParams, data: { filter, selectParams } }); filter = filter || {}; - const allowedReturnTypes = Object.keys({ row: 1, statement: 1, value: 1, values: 1, "statement-no-rls": 1, "statement-where": 1 } satisfies Record["returnType"], 1>); + const allowedReturnTypes = Object.keys({ + row: 1, statement: 1, value: 1, values: 1, + "statement-no-rls": 1, "statement-where": 1, + } satisfies Record["returnType"], 1>); + const { returnType } = selectParams || {}; if (returnType && !allowedReturnTypes.includes(returnType)) { throw `returnType (${returnType}) can only be ${allowedReturnTypes.join(" OR ")}` @@ -23,12 +27,13 @@ export const find = async function(this: ViewHandler, filter?: Filter, selectPar if (testRule) return []; if (selectParams) { - const good_params = Object.keys({ - "select": 1, "orderBy": 1, "offset": 1, "limit": 1, "returnType": 1, "groupBy": 1 + const validParamNames = Object.keys({ + "select": 1, "orderBy": 1, "offset": 1, "limit": 1, + "returnType": 1, "groupBy": 1, "having": 1 } satisfies Record); - const bad_params = Object.keys(selectParams).filter(k => !good_params.includes(k as any)); - if (bad_params && bad_params.length) throw "Invalid params: " + bad_params.join(", ") + " \n Expecting: " + good_params.join(", "); + const invalidParams = Object.keys(selectParams).filter(k => !validParamNames.includes(k as any)); + if (invalidParams && invalidParams.length) throw "Invalid params: " + invalidParams.join(", ") + " \n Expecting: " + validParamNames.join(", "); } /* Validate publish */ @@ -38,9 +43,15 @@ export const find = async function(this: ViewHandler, filter?: Filter, selectPar const fields = tableRules.select.fields; const maxLimit = tableRules.select.maxLimit; - if (tableRules.select !== "*" && typeof tableRules.select !== "boolean" && !isObject(tableRules.select)) throw `\nINVALID publish.${this.name}.select\nExpecting any of: "*" | { fields: "*" } | true | false` - if (!fields) throw ` invalid ${this.name}.select rule -> fields (required) setting missing.\nExpecting any of: "*" | { col_name: false } | { col1: true, col2: true }`; - if (maxLimit && !Number.isInteger(maxLimit)) throw ` invalid publish.${this.name}.select.maxLimit -> expecting integer but got ` + maxLimit; + if (tableRules.select !== "*" && typeof tableRules.select !== "boolean" && !isObject(tableRules.select)) { + throw `\nInvalid publish.${this.name}.select\nExpecting any of: "*" | { fields: "*" } | true | false`; + } + if (!fields) { + throw ` invalid ${this.name}.select rule -> fields (required) setting missing.\nExpecting any of: "*" | { col_name: false } | { col1: true, col2: true }`; + } + if (maxLimit && !Number.isInteger(maxLimit)) { + throw ` invalid publish.${this.name}.select.maxLimit -> expecting integer but got ` + maxLimit; + } } const _selectParams = selectParams ?? {} @@ -68,7 +79,7 @@ export const find = async function(this: ViewHandler, filter?: Filter, selectPar return []; } catch (e) { console.error(e); - throw `INTERNAL ERROR: Publish config is not valid for publish.${this.name}.select ` + throw `Internal error: publish config is not valid for publish.${this.name}.select ` } } diff --git a/lib/DboBuilder/getCondition.ts b/lib/DboBuilder/getCondition.ts index 9f6ace17..57fcbc2d 100644 --- a/lib/DboBuilder/getCondition.ts +++ b/lib/DboBuilder/getCondition.ts @@ -57,7 +57,7 @@ export async function getCondition( existsCond = (await Promise.all(existsConfigs.map(async existsConfig => await getExistsCondition.bind(this)(existsConfig, localParams)))).join(" AND "); } - /* Computed field queries */ + /* Computed field queries ($rowhash) */ const p = this.getValidatedRules(tableRules, localParams); const computedFields = p.allColumns.filter(c => c.type === "computed"); const computedColConditions: string[] = []; @@ -85,8 +85,8 @@ export async function getCondition( if (select) { /* Allow filtering by selected fields/funcs */ allowedSelect = select.filter(s => { - /* */ if (["function", "computed", "column"].includes(s.type)) { + /* */ if (s.type !== "column" || allowed_colnames.includes(s.alias)) { return true; } @@ -202,6 +202,10 @@ export async function getCondition( )); if (invalidColumn) { + const selItem = select?.find(s => s.alias === invalidColumn); + if(selItem?.type === "aggregation"){ + throw new Error(`Filtering by ${invalidColumn} is not allowed. Aggregations cannot be filtered. Use HAVING clause instead.`); + } const allowedCols = allowedSelect.map(s => s.type === "column" ? s.getQuery() : s.alias).join(", "); const errMessage = `Table: ${this.name} -> disallowed/inexistent columns in filter: ${invalidColumn} \n Expecting one of: ${allowedCols}`; throw errMessage; @@ -214,8 +218,8 @@ export async function getCondition( const q = parseFilterItem({ filter: f, tableAlias, - pgp, - select: allowedSelect + select: allowedSelect, + allowedColumnNames: !tableRules? this.column_names.slice(0) : this.parseFieldFilter(tableRules.select?.filterFields ?? tableRules.select?.fields), }); let templates: string[] = [q].filter(q => q); diff --git a/lib/Filtering.ts b/lib/Filtering.ts index cf9ddb70..73e0b113 100644 --- a/lib/Filtering.ts +++ b/lib/Filtering.ts @@ -3,7 +3,7 @@ import { CompareFilterKeys, CompareInFilterKeys, - EXISTS_KEYS, FilterDataType, + FilterDataType, FullFilter, GeomFilterKeys, GeomFilter_Funcs, JsonbFilterKeys, @@ -14,14 +14,21 @@ import { isObject } from "prostgles-types"; import { SelectItem } from "./DboBuilder/QueryBuilder/QueryBuilder"; +import { pgp } from "./DboBuilder/DboBuilderTypes"; /** * Parse a single filter * Ensure only single key objects reach this point */ -type ParseFilterItemArgs = { filter: FullFilter, select?: SelectItem[], tableAlias?: string, pgp: any }; +type ParseFilterItemArgs = { + filter: FullFilter; + select: SelectItem[] | undefined; + tableAlias: string | undefined; + allowedColumnNames: string[]; +}; + export const parseFilterItem = (args: ParseFilterItemArgs): string => { - const { filter: _f, select, tableAlias, pgp } = args; + const { filter: _f, select, tableAlias, allowedColumnNames } = args; if(!_f || isEmpty(_f)) return ""; @@ -42,7 +49,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => { filter: { [fk]: _f[fk] }, select, tableAlias, - pgp, + allowedColumnNames, })) .sort() /* sorted to ensure duplicate subscription channels are not created due to different condition order */ .join(" AND ") @@ -50,17 +57,24 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => { const fKey: string = fKeys[0]!; - /* Exists filter */ - if(EXISTS_KEYS.find(k => k in _f)){ - // parseExistsFilter() - } - let selItem: SelectItem | undefined; - if(select) selItem = select.find(s => fKey === s.alias); + if(select) { + selItem = select.find(s => fKey === s.alias); + } let rightF: FilterDataType = (_f as any)[fKey]; + const validateSelectedItemFilter = (selectedItem: SelectItem | undefined) => { + const fields = selectedItem?.getFields(); + if(Array.isArray(fields) && fields.length > 1) { + const dissallowedFields = fields.filter(fname => !allowedColumnNames.includes(fname)); + if(dissallowedFields.length){ + throw new Error(`Invalid/disallowed columns found in filter: ${dissallowedFields}`) + } + } + } const getLeftQ = (selItm: SelectItem) => { - if(selItm.type === "function") return selItm.getQuery(); + validateSelectedItemFilter(selItem); + if(selItm.type === "function" || selItm.type === "aggregation") return selItm.getQuery(); return selItm.getQuery(tableAlias); } @@ -81,6 +95,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => { selItem = select.find(s => dot_notation_delims.find(delimiter => fKey.startsWith(s.alias + delimiter)) ); + validateSelectedItemFilter(selItem); } if(!selItem) { return mErr("Bad filter. Could not match to a column or alias or dot notation: "); @@ -135,7 +150,6 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => { nextSep = undefined; } - // console.log({ currSep, nextSep }) leftQ += currSep.sep + asValue(remainingStr.slice(currSep.idx + currSep.sep.length, nextIdx)); currSep = nextSep; } @@ -175,7 +189,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => { rightF = res; } else { - console.trace(141, select, selItem, remainingStr) + // console.trace(141, select, selItem, remainingStr) mErr("Bad filter. Could not find the valid col name or alias or col json path") } diff --git a/package-lock.json b/package-lock.json index 0a6cd8fb..20558992 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,31 +1,31 @@ { "name": "prostgles-server", - "version": "4.2.45", + "version": "4.2.46", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prostgles-server", - "version": "4.2.45", + "version": "4.2.46", "license": "MIT", "dependencies": { - "@types/express": "^4.17.13", - "@types/json-schema": "^7.0.11", - "@types/pg": "^8.10.9", "bluebird": "^3.7.2", "body-parser": "^1.20.2", - "check-disk-space": "^3.3.1", + "check-disk-space": "^3.4.0", "file-type": "^18.5.0", - "pg": "^8.11.3", - "pg-cursor": "^2.10.3", - "pg-promise": "^11.5.4", + "pg": "^8.11.5", + "pg-cursor": "^2.10.5", + "pg-promise": "^11.6.0", "prostgles-client": "^4.0.53", - "prostgles-types": "^4.0.74" + "prostgles-types": "^4.0.75" }, "devDependencies": { "@types/bluebird": "^3.5.36", + "@types/express": "^4.17.21", "@types/file-type": "^10.9.1", + "@types/json-schema": "^7.0.15", "@types/node": "^18.0.3", + "@types/pg": "^8.11.5", "@types/pg-cursor": "^2.7.2", "@types/sharp": "^0.30.4", "@types/socket.io": "^3.0.2", @@ -189,6 +189,7 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -198,6 +199,7 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, "dependencies": { "@types/node": "*" } @@ -218,24 +220,27 @@ } }, "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, "dependencies": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.29", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", - "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "node_modules/@types/file-type": { @@ -249,24 +254,28 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true }, "node_modules/@types/node": { "version": "18.0.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", - "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==" + "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", + "dev": true }, "node_modules/@types/pg": { - "version": "8.10.9", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", - "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-2xMjVviMxneZHDHX5p5S6tsRRs7TpDHeeK7kTTMe/kAC/mRRNjWHjZg0rkiY+e17jXSZV3zJYDxXV8Cy72/Vuw==", + "dev": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -287,6 +296,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dev": true, "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", @@ -304,6 +314,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true, "engines": { "node": ">=12" } @@ -312,6 +323,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, "dependencies": { "obuf": "~1.1.2" }, @@ -323,6 +335,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dev": true, "engines": { "node": ">=12" } @@ -331,19 +344,22 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true, "engines": { "node": ">=12" } }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true }, "node_modules/@types/semver": { "version": "7.5.4", @@ -351,10 +367,21 @@ "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "node_modules/@types/serve-static": { "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -742,14 +769,6 @@ "node": ">=8" } }, - "node_modules/buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", - "engines": { - "node": ">=4" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -802,11 +821,11 @@ } }, "node_modules/check-disk-space": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.3.1.tgz", - "integrity": "sha512-iOrT8yCZjSnyNZ43476FE2rnssvgw5hnuwOM0hm8Nj1qa0v4ieUUEbCyxxsEliaoDUb/75yCOL71zkDiDBLbMQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", + "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==", "engines": { - "node": ">=12" + "node": ">=16" } }, "node_modules/color-convert": { @@ -1845,7 +1864,8 @@ "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true }, "node_modules/on-finished": { "version": "2.4.1", @@ -1914,11 +1934,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1980,15 +1995,13 @@ } }, "node_modules/pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", "dependencies": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", - "pg-protocol": "^1.6.0", + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", "pg-types": "^2.1.0", "pgpass": "1.x" }, @@ -2014,14 +2027,14 @@ "optional": true }, "node_modules/pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==" }, "node_modules/pg-cursor": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.10.3.tgz", - "integrity": "sha512-rDyBVoqPVnx/PTmnwQAYgusSeAKlTL++gmpf5klVK+mYMFEqsOc6VHHZnPKc/4lOvr4r6fiMuoxSFuBF1dx4FQ==", + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.10.5.tgz", + "integrity": "sha512-wzgmyk+k9mwuYe30ylLA6qRWw2TBFSee4Bw23oTz66YL9RdRJjDi2TaROMMF+V3QB6QWB3FFCju22loDftjKkw==", "peerDependencies": { "pg": "^8" } @@ -2046,25 +2059,26 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dev": true, "engines": { "node": ">=4" } }, "node_modules/pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-promise": { - "version": "11.5.4", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.5.4.tgz", - "integrity": "sha512-esYSkDt2h6NQOkfotGAm1Ld5OjoITJLpB88Z1PIlcAU/RQ0XQE2PxW0bLJEOMHPGV5iaRnj1Y7ARznXbgN4FNw==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.6.0.tgz", + "integrity": "sha512-NDRPMfkv3ia89suWlJ4iGvP6X5YFrLJ2+9AIVISeBFFZ29Eb4FNXX9JaVb1p1OrpQkE2yT7igmXPL7UYQhk+6A==", "dependencies": { "assert-options": "0.8.1", - "pg": "8.11.3", + "pg": "8.11.5", "pg-minify": "1.6.3", "spex": "3.3.0" }, @@ -2073,9 +2087,9 @@ } }, "node_modules/pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" }, "node_modules/pg-types": { "version": "2.2.0", @@ -2150,7 +2164,8 @@ "node_modules/postgres-range": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", - "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==" + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -2178,9 +2193,9 @@ } }, "node_modules/prostgles-types": { - "version": "4.0.74", - "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.74.tgz", - "integrity": "sha512-6+MW7q1INIpO3JOkSCDD8oUG3U22VYbSWt2s0j3/0Uog4Dr90EzxX2TE7jV0NXmK+AAs+HHZ9u5olipMv0sHmQ==", + "version": "4.0.75", + "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.75.tgz", + "integrity": "sha512-s0v0NbLO2/w9kzsjxlC48ZyMtnUJ/5dhuH5eucAnGv41wwuJ+HjA2zsvVqBiStdEVA6AhwrWefmrO8GTkuiKhA==", "dependencies": { "json-schema": "^0.4.0" } @@ -2894,6 +2909,7 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, "requires": { "@types/connect": "*", "@types/node": "*" @@ -2903,6 +2919,7 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, "requires": { "@types/node": "*" } @@ -2923,24 +2940,27 @@ } }, "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, "requires": { "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", + "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "@types/express-serve-static-core": { - "version": "4.17.29", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", - "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "dev": true, "requires": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "@types/file-type": { @@ -2953,24 +2973,28 @@ } }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true }, "@types/node": { "version": "18.0.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.3.tgz", - "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==" + "integrity": "sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==", + "dev": true }, "@types/pg": { - "version": "8.10.9", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz", - "integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-2xMjVviMxneZHDHX5p5S6tsRRs7TpDHeeK7kTTMe/kAC/mRRNjWHjZg0rkiY+e17jXSZV3zJYDxXV8Cy72/Vuw==", + "dev": true, "requires": { "@types/node": "*", "pg-protocol": "*", @@ -2981,6 +3005,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz", "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==", + "dev": true, "requires": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", @@ -2994,12 +3019,14 @@ "postgres-array": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", - "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==" + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "dev": true }, "postgres-bytea": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "dev": true, "requires": { "obuf": "~1.1.2" } @@ -3007,12 +3034,14 @@ "postgres-date": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz", - "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==" + "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==", + "dev": true }, "postgres-interval": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", - "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==" + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "dev": true } } }, @@ -3027,14 +3056,16 @@ } }, "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "dev": true }, "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true }, "@types/semver": { "version": "7.5.4", @@ -3042,10 +3073,21 @@ "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/serve-static": { "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, "requires": { "@types/mime": "^1", "@types/node": "*" @@ -3305,11 +3347,6 @@ "fill-range": "^7.0.1" } }, - "buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" - }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -3344,9 +3381,9 @@ } }, "check-disk-space": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.3.1.tgz", - "integrity": "sha512-iOrT8yCZjSnyNZ43476FE2rnssvgw5hnuwOM0hm8Nj1qa0v4ieUUEbCyxxsEliaoDUb/75yCOL71zkDiDBLbMQ==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", + "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==" }, "color-convert": { "version": "2.0.1", @@ -4111,7 +4148,8 @@ "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true }, "on-finished": { "version": "2.4.1", @@ -4162,11 +4200,6 @@ "p-limit": "^3.0.2" } }, - "packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4206,16 +4239,14 @@ "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==" }, "pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", "requires": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", "pg-cloudflare": "^1.1.1", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", - "pg-protocol": "^1.6.0", + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", "pg-types": "^2.1.0", "pgpass": "1.x" } @@ -4227,14 +4258,14 @@ "optional": true }, "pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==" }, "pg-cursor": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.10.3.tgz", - "integrity": "sha512-rDyBVoqPVnx/PTmnwQAYgusSeAKlTL++gmpf5klVK+mYMFEqsOc6VHHZnPKc/4lOvr4r6fiMuoxSFuBF1dx4FQ==", + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/pg-cursor/-/pg-cursor-2.10.5.tgz", + "integrity": "sha512-wzgmyk+k9mwuYe30ylLA6qRWw2TBFSee4Bw23oTz66YL9RdRJjDi2TaROMMF+V3QB6QWB3FFCju22loDftjKkw==", "requires": {} }, "pg-int8": { @@ -4250,29 +4281,30 @@ "pg-numeric": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", - "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==" + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "dev": true }, "pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", "requires": {} }, "pg-promise": { - "version": "11.5.4", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.5.4.tgz", - "integrity": "sha512-esYSkDt2h6NQOkfotGAm1Ld5OjoITJLpB88Z1PIlcAU/RQ0XQE2PxW0bLJEOMHPGV5iaRnj1Y7ARznXbgN4FNw==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.6.0.tgz", + "integrity": "sha512-NDRPMfkv3ia89suWlJ4iGvP6X5YFrLJ2+9AIVISeBFFZ29Eb4FNXX9JaVb1p1OrpQkE2yT7igmXPL7UYQhk+6A==", "requires": { "assert-options": "0.8.1", - "pg": "8.11.3", + "pg": "8.11.5", "pg-minify": "1.6.3", "spex": "3.3.0" } }, "pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" }, "pg-types": { "version": "2.2.0", @@ -4326,7 +4358,8 @@ "postgres-range": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz", - "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==" + "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==", + "dev": true }, "prelude-ls": { "version": "1.2.1", @@ -4343,9 +4376,9 @@ } }, "prostgles-types": { - "version": "4.0.74", - "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.74.tgz", - "integrity": "sha512-6+MW7q1INIpO3JOkSCDD8oUG3U22VYbSWt2s0j3/0Uog4Dr90EzxX2TE7jV0NXmK+AAs+HHZ9u5olipMv0sHmQ==", + "version": "4.0.75", + "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.75.tgz", + "integrity": "sha512-s0v0NbLO2/w9kzsjxlC48ZyMtnUJ/5dhuH5eucAnGv41wwuJ+HjA2zsvVqBiStdEVA6AhwrWefmrO8GTkuiKhA==", "requires": { "json-schema": "^0.4.0" } diff --git a/package.json b/package.json index 490ca5b2..0f5d4d25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prostgles-server", - "version": "4.2.45", + "version": "4.2.46", "description": "", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -35,23 +35,23 @@ ], "homepage": "https://prostgles.com", "dependencies": { - "@types/express": "^4.17.13", - "@types/json-schema": "^7.0.11", - "@types/pg": "^8.10.9", "bluebird": "^3.7.2", "body-parser": "^1.20.2", - "check-disk-space": "^3.3.1", + "check-disk-space": "^3.4.0", "file-type": "^18.5.0", - "pg": "^8.11.3", - "pg-cursor": "^2.10.3", - "pg-promise": "^11.5.4", + "pg": "^8.11.5", + "pg-cursor": "^2.10.5", + "pg-promise": "^11.6.0", "prostgles-client": "^4.0.53", - "prostgles-types": "^4.0.74" + "prostgles-types": "^4.0.75" }, "devDependencies": { "@types/bluebird": "^3.5.36", + "@types/express": "^4.17.21", "@types/file-type": "^10.9.1", + "@types/json-schema": "^7.0.15", "@types/node": "^18.0.3", + "@types/pg": "^8.11.5", "@types/pg-cursor": "^2.7.2", "@types/sharp": "^0.30.4", "@types/socket.io": "^3.0.2", diff --git a/tests/client/package-lock.json b/tests/client/package-lock.json index 92009e86..effeec85 100644 --- a/tests/client/package-lock.json +++ b/tests/client/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@types/node": "^20.9.2", - "prostgles-client": "^4.0.115", + "prostgles-client": "^4.0.117", "prostgles-types": "^4.0.51", "socket.io-client": "^4.7.5" }, @@ -351,11 +351,11 @@ } }, "node_modules/prostgles-client": { - "version": "4.0.115", - "resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-4.0.115.tgz", - "integrity": "sha512-YMnWOY352K8v++eR8Nb2Ikmi+3U0bxaFbPlsHAa1XmFhGq3UqRponUMcgYLiXjbWrvMRULSVWdYezdMTZU/a/g==", + "version": "4.0.117", + "resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-4.0.117.tgz", + "integrity": "sha512-bhA/o84sWPrlqiYFpitNRqcn1bDgNN5yOuPGSaS805t4Gm6vooKI1K392qlrskK92j6qH7VnPsKxeF4Ul7vn/g==", "dependencies": { - "prostgles-types": "^4.0.74" + "prostgles-types": "^4.0.75" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", @@ -371,9 +371,9 @@ } }, "node_modules/prostgles-types": { - "version": "4.0.74", - "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.74.tgz", - "integrity": "sha512-6+MW7q1INIpO3JOkSCDD8oUG3U22VYbSWt2s0j3/0Uog4Dr90EzxX2TE7jV0NXmK+AAs+HHZ9u5olipMv0sHmQ==", + "version": "4.0.75", + "resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-4.0.75.tgz", + "integrity": "sha512-s0v0NbLO2/w9kzsjxlC48ZyMtnUJ/5dhuH5eucAnGv41wwuJ+HjA2zsvVqBiStdEVA6AhwrWefmrO8GTkuiKhA==", "dependencies": { "json-schema": "^0.4.0" } diff --git a/tests/client/package.json b/tests/client/package.json index 3af914de..a6bf7851 100644 --- a/tests/client/package.json +++ b/tests/client/package.json @@ -13,7 +13,7 @@ "license": "ISC", "dependencies": { "@types/node": "^20.9.2", - "prostgles-client": "^4.0.115", + "prostgles-client": "^4.0.117", "prostgles-types": "^4.0.51", "socket.io-client": "^4.7.5" }, diff --git a/tests/clientRestApi.spec.ts b/tests/clientRestApi.spec.ts index e87f0580..d135d20b 100644 --- a/tests/clientRestApi.spec.ts +++ b/tests/clientRestApi.spec.ts @@ -7,36 +7,11 @@ export const clientRestApi = async(db: DBHandlerClient, auth: Auth, log: (...arg await describe("clientRestApi", async () => { - const post = async ({ path, noAuth }: { path: string; noAuth?: boolean}, ...params: any[]) => { - const headers = new Headers({ - 'Authorization': `Bearer ${Buffer.from(noAuth? "noAuth" : token, "utf-8").toString("base64")}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }); - const res = await fetch(`http://127.0.0.1:3001/api/${path}`, { - method: "POST", - headers, - body: !params?.length? undefined : JSON.stringify(params) - }); - const resBodyJson = await res.text() - .then(text => { - try { - return JSON.parse(text); - } catch { - return text; - } - }); - - if(res.status !== 200){ - return Promise.reject(resBodyJson); - } - return resBodyJson; - } - const rest = async ({ tableName, command, noAuth }: { tableName: string; command: string; noAuth?: boolean; }, ...params: any[]) => post({ path: `db/${tableName}/${command}`, noAuth }, ...(params ?? [])) + const rest = async ({ tableName, command, noAuth }: { tableName: string; command: string; noAuth?: boolean; }, ...params: any[]) => post({ path: `db/${tableName}/${command}`, noAuth, token }, ...(params ?? [])) const dbRest = (tableName: string, command: string, ...params: any[]) => rest({ tableName, command }, ...(params ?? [])) const dbRestNoAuth = (tableName: string, command: string, ...params: any[]) => rest({ tableName, command, noAuth: true }, ...(params ?? [])); - const sqlRest = (query: string, ...params: any[]) => post({ path: `db/sql` }, query, ...(params ?? [])) - const sqlMethods = (methodName: string, ...params: any[]) => post({ path: `methods/${methodName}` }, ...(params ?? [])) + const sqlRest = (query: string, ...params: any[]) => post({ path: `db/sql`, token }, query, ...(params ?? [])) + const sqlMethods = (methodName: string, ...params: any[]) => post({ path: `methods/${methodName}`, token }, ...(params ?? [])) await test("Rest api test", async () => { const dataFilter = { id: 123123123, last_updated: Date.now() }; @@ -59,7 +34,7 @@ export const clientRestApi = async(db: DBHandlerClient, auth: Auth, log: (...arg const sqlRes = await sqlRest("select 1 as a", {}, { returnType: "rows" }); assert.deepStrictEqual(sqlRes, [{ a: 1 }]); - const restTableSchema = await post({ path: "schema" }); + const restTableSchema = await post({ path: "schema", token }); assert.deepStrictEqual(tableSchema, restTableSchema.tableSchema); await Promise.all(tableSchema.map(async tbl => { const cols = await db[tbl.name]?.getColumns?.(); @@ -78,4 +53,30 @@ export const clientRestApi = async(db: DBHandlerClient, auth: Auth, log: (...arg }); +} + +const post = async ({ path, noAuth, token }: { path: string; token: string; noAuth?: boolean}, ...params: any[]) => { + const headers = new Headers({ + 'Authorization': `Bearer ${Buffer.from(noAuth? "noAuth" : token, "utf-8").toString("base64")}`, + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }); + const res = await fetch(`http://127.0.0.1:3001/api/${path}`, { + method: "POST", + headers, + body: !params?.length? undefined : JSON.stringify(params) + }); + const resBodyJson = await res.text() + .then(text => { + try { + return JSON.parse(text); + } catch { + return text; + } + }); + + if(res.status !== 200){ + return Promise.reject(resBodyJson); + } + return resBodyJson; } \ No newline at end of file diff --git a/tests/isomorphicQueries.spec.ts b/tests/isomorphicQueries.spec.ts index fe6fdc09..f0a0b03d 100644 --- a/tests/isomorphicQueries.spec.ts +++ b/tests/isomorphicQueries.spec.ts @@ -2,7 +2,11 @@ import { strict as assert } from 'assert'; import * as fs from "fs"; import { DBOFullyTyped } from "../dist/DBSchemaBuilder"; import type { DBHandlerClient } from "./client"; -import { test, describe } from "node:test"; +import { + test, + //@ts-ignore + describe +} from "node:test"; import { pickKeys } from "prostgles-types"; @@ -78,12 +82,20 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log await db.sql("TRUNCATE files CASCADE"); }); + + await test("Having clause", async () => { + const res = await db.items.find!({}, { select: { name: 1, c: { $countAll: [] } }, having: { c: 2 } }); + assert.deepStrictEqual(res, [{ + c: '2', + name: 'a' + }]); + }) const json = { a: true, arr: "2", arr1: 3, arr2: [1], arrStr: ["1123.string"] } await test("merge json", async () => { const inserted = await db.tjson.insert!({ colOneOf: "a", json }, { returning: "*" }); const res = await db.tjson.update!({ colOneOf: "a" },{ json: { $merge: [{ a: false }] } }, { returning: "*" }); - assert.deepStrictEqual(res[0].json, { ...json, a: false }); + assert.deepStrictEqual(res?.[0].json, { ...json, a: false }); }); await test("json array converted to pg array filter bug", async () => { @@ -172,7 +184,7 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log const newF = await db.files.findOne!({ id: original.id }); - assert.equal(newF.original_name, newFile.name) + assert.equal(newF?.original_name, newFile.name) }); await test("getColumns definition", async () => { @@ -528,8 +540,8 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log await test("template_string function", async () => { const res = await db.various.findOne!({ name: 'abc9' }, { select: { tstr: { $template_string: ["{name} is hehe"] } } }); const res2 = await db.various.findOne!({ name: 'abc9' }, { select: { tstr: { $template_string: ["is hehe"] } } }); - assert.equal(res.tstr, "abc9 is hehe") - assert.equal(res2.tstr, "is hehe") + assert.equal(res?.tstr, "abc9 is hehe") + assert.equal(res2?.tstr, "is hehe") }); await test("Between filtering", async () => { @@ -577,8 +589,8 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log await test("Function example", async () => { const f = await db.items4.findOne!({}, { select: { public: 1, p_5: { $left: ["public", 3] } } }); - assert.equal(f.p_5.length, 3); - assert.equal(f.p_5, f.public.substr(0, 3)); + assert.equal(f?.p_5.length, 3); + assert.equal(f?.p_5, f.public.substr(0, 3)); // Nested function const fg = await db.items2.findOne!({}, { select: { id: 1, name: 1, items3: { name: "$upper" } } });// { $upper: ["public"] } } }); @@ -816,7 +828,7 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log select: { "*": 1, items2: "*", - items2j: db.leftJoin.items2({}, "*") + items2j: db.leftJoin?.items2({}, "*") } }); @@ -848,7 +860,7 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log /* $rowhash -> Custom column that returms md5(ctid + allowed select columns). Used in joins & CRUD to bypass PKey details */ await test("$rowhash example", async () => { const rowhash = await db.items.findOne!({}, { select: { $rowhash: 1, "*": 1 }}); - const f = { $rowhash: rowhash.$rowhash }; + const f = { $rowhash: rowhash?.$rowhash }; const rowhashView = await db.v_items.findOne!({}, { select: { $rowhash: 1 }}); const rh1 = await db.items.findOne!({ $rowhash: rowhash?.$rowhash }, { select: { $rowhash: 1 }}); const rhView = await db.v_items.findOne!({ $rowhash: rowhashView?.$rowhash }, { select: { $rowhash: 1 }}); @@ -1076,7 +1088,7 @@ export const isomorphicQueries = async (db: DBOFullyTyped | DBHandlerClient, log { select: { "*": 1, - i0: db.innerJoin.items_multi( + i0: db.innerJoin?.items_multi( { name: "multi0" }, "*", { path: [{ table: "items", on: [{ items0_id: "id" }] }] } diff --git a/tests/server/package-lock.json b/tests/server/package-lock.json index a7399365..817a1997 100644 --- a/tests/server/package-lock.json +++ b/tests/server/package-lock.json @@ -21,26 +21,26 @@ }, "../..": { "name": "prostgles-server", - "version": "4.2.45", + "version": "4.2.46", "license": "MIT", "dependencies": { - "@types/express": "^4.17.13", - "@types/json-schema": "^7.0.11", - "@types/pg": "^8.10.9", "bluebird": "^3.7.2", "body-parser": "^1.20.2", - "check-disk-space": "^3.3.1", + "check-disk-space": "^3.4.0", "file-type": "^18.5.0", - "pg": "^8.11.3", - "pg-cursor": "^2.10.3", - "pg-promise": "^11.5.4", + "pg": "^8.11.5", + "pg-cursor": "^2.10.5", + "pg-promise": "^11.6.0", "prostgles-client": "^4.0.53", - "prostgles-types": "^4.0.74" + "prostgles-types": "^4.0.75" }, "devDependencies": { "@types/bluebird": "^3.5.36", + "@types/express": "^4.17.21", "@types/file-type": "^10.9.1", + "@types/json-schema": "^7.0.15", "@types/node": "^18.0.3", + "@types/pg": "^8.11.5", "@types/pg-cursor": "^2.7.2", "@types/sharp": "^0.30.4", "@types/socket.io": "^3.0.2", @@ -1529,11 +1529,11 @@ "version": "file:../..", "requires": { "@types/bluebird": "^3.5.36", - "@types/express": "^4.17.13", + "@types/express": "^4.17.21", "@types/file-type": "^10.9.1", - "@types/json-schema": "^7.0.11", + "@types/json-schema": "^7.0.15", "@types/node": "^18.0.3", - "@types/pg": "^8.10.9", + "@types/pg": "^8.11.5", "@types/pg-cursor": "^2.7.2", "@types/sharp": "^0.30.4", "@types/socket.io": "^3.0.2", @@ -1541,14 +1541,14 @@ "@typescript-eslint/parser": "^5.62.0", "bluebird": "^3.7.2", "body-parser": "^1.20.2", - "check-disk-space": "^3.3.1", + "check-disk-space": "^3.4.0", "eslint": "^8.51.0", "file-type": "^18.5.0", - "pg": "^8.11.3", - "pg-cursor": "^2.10.3", - "pg-promise": "^11.5.4", + "pg": "^8.11.5", + "pg-cursor": "^2.10.5", + "pg-promise": "^11.6.0", "prostgles-client": "^4.0.53", - "prostgles-types": "^4.0.74", + "prostgles-types": "^4.0.75", "typescript": "^5.3.3" } },