pqb 0.68.1 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +19 -12
- package/dist/index.js +470 -470
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +470 -470
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +35 -28
- package/dist/node-postgres.js +9 -15
- package/dist/node-postgres.js.map +1 -1
- package/dist/node-postgres.mjs +9 -15
- package/dist/node-postgres.mjs.map +1 -1
- package/dist/postgres-js.js +64 -0
- package/dist/postgres-js.js.map +1 -1
- package/dist/postgres-js.mjs +64 -0
- package/dist/postgres-js.mjs.map +1 -1
- package/package.json +1 -1
package/dist/internal.d.ts
CHANGED
|
@@ -1645,6 +1645,8 @@ declare class BooleanColumn$1<Schema extends ColumnSchemaConfig$1> extends Colum
|
|
|
1645
1645
|
querySchema: ReturnType<Schema['boolean']>;
|
|
1646
1646
|
private static _instance;
|
|
1647
1647
|
static get instance(): BooleanColumn$1<DefaultSchemaConfig$1>;
|
|
1648
|
+
private static _instanceSkipValueToArray;
|
|
1649
|
+
static get instanceSkipValueToArray(): BooleanColumn$1<DefaultSchemaConfig$1>;
|
|
1648
1650
|
constructor(schema: Schema);
|
|
1649
1651
|
toCode(ctx: ColumnToCodeCtx$1, key: string): Code$1;
|
|
1650
1652
|
}
|
|
@@ -2150,21 +2152,23 @@ declare class UnsafeSqlExpression extends Expression$1 {
|
|
|
2150
2152
|
constructor(sql: string | number | boolean);
|
|
2151
2153
|
makeSQL(): string;
|
|
2152
2154
|
}
|
|
2153
|
-
type getValueKey = typeof getValueKey;
|
|
2154
|
-
declare const getValueKey: unique symbol;
|
|
2155
2155
|
interface PickQueryDataParsers {
|
|
2156
2156
|
defaultParsers?: ColumnsParsers;
|
|
2157
2157
|
parsers?: ColumnsParsers;
|
|
2158
2158
|
batchParsers?: BatchParsers;
|
|
2159
2159
|
}
|
|
2160
2160
|
type ColumnParser = FnUnknownToUnknown;
|
|
2161
|
+
interface BatchParserPathEntry {
|
|
2162
|
+
key: string;
|
|
2163
|
+
returnType: QueryReturnType$1;
|
|
2164
|
+
}
|
|
2161
2165
|
interface BatchParser {
|
|
2162
|
-
path:
|
|
2163
|
-
fn: (path:
|
|
2166
|
+
path: BatchParserPathEntry[];
|
|
2167
|
+
fn: (path: BatchParserPathEntry[], queryResult: {
|
|
2164
2168
|
rows: unknown[];
|
|
2165
2169
|
}) => MaybePromise$1<void>;
|
|
2166
2170
|
}
|
|
2167
|
-
type ColumnsParsers = { [K in string
|
|
2171
|
+
type ColumnsParsers = { [K in string]?: ColumnParser };
|
|
2168
2172
|
type BatchParsers = BatchParser[];
|
|
2169
2173
|
interface QueryThen<T> {
|
|
2170
2174
|
<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
|
@@ -5264,6 +5268,7 @@ interface ExpressionData$1 extends HasBeforeAndBeforeSet {
|
|
|
5264
5268
|
expr?: Expression$1;
|
|
5265
5269
|
before?: QueryBeforeHook$1[];
|
|
5266
5270
|
dynamicBefore?: boolean;
|
|
5271
|
+
getColumn?: Column$1;
|
|
5267
5272
|
}
|
|
5268
5273
|
declare abstract class Expression$1<T extends Column$1.Pick.QueryColumn = Column$1.Pick.QueryColumn> {
|
|
5269
5274
|
abstract result: {
|
|
@@ -7252,37 +7257,37 @@ declare namespace Column$1 {
|
|
|
7252
7257
|
unique: Name;
|
|
7253
7258
|
};
|
|
7254
7259
|
};
|
|
7255
|
-
export type Nullable<T extends Column
|
|
7260
|
+
export type Nullable<T extends Column.Pick.ForNullable, InputSchema, OutputSchema, QuerySchema> = { [K in keyof T]: K extends '__type' ? T['__type'] | null : K extends '__inputType' ? T['__inputType'] | null : K extends 'inputSchema' ? InputSchema : K extends '__outputType' ? T['__outputType'] | (unknown extends T['__nullType'] ? null : T['__nullType']) : K extends 'outputSchema' ? OutputSchema : K extends '__queryType' ? T['__queryType'] | null : K extends 'querySchema' ? QuerySchema : K extends 'data' ? T['data'] & DataNullable : K extends 'operators' ? { [K in keyof T['operators']]: K extends 'equals' | 'not' | 'isDistinctFrom' | 'isNotDistinctFrom' ? Operator<T['__queryType'] | null, T> : T['operators'][K] } : T[K] };
|
|
7256
7261
|
export type QueryColumnToNullable<C> = { [K in keyof C]: K extends '__outputType' | '__queryType' ? C[K] | null : C[K] };
|
|
7257
7262
|
export type QueryColumnToOptional<C> = { [K in keyof C]: K extends '__outputType' ? C[K] | undefined : C[K] };
|
|
7258
7263
|
interface DataNullable {
|
|
7259
7264
|
isNullable: true;
|
|
7260
7265
|
optional: true;
|
|
7261
7266
|
}
|
|
7262
|
-
export interface OperatorsNullable<
|
|
7263
|
-
equals: Operator<
|
|
7264
|
-
not: Operator<
|
|
7265
|
-
isDistinctFrom: Operator<
|
|
7266
|
-
isNotDistinctFrom: Operator<
|
|
7267
|
+
export interface OperatorsNullable<Column extends Column.Pick.QueryColumn> {
|
|
7268
|
+
equals: Operator<Column['__queryType'] | null, Column>;
|
|
7269
|
+
not: Operator<Column['__queryType'] | null, Column>;
|
|
7270
|
+
isDistinctFrom: Operator<Column['__queryType'] | null, Column>;
|
|
7271
|
+
isNotDistinctFrom: Operator<Column['__queryType'] | null, Column>;
|
|
7267
7272
|
}
|
|
7268
7273
|
export type Encode<T, InputSchema, Input> = { [K in keyof T]: K extends '__inputType' ? Input : K extends 'inputSchema' ? InputSchema : T[K] };
|
|
7269
7274
|
export type Parse<T extends Pick.ForParse, OutputSchema, Output> = { [K in keyof T]: K extends '__outputType' ? null extends T['__type'] ? (Output extends null ? never : Output) | (unknown extends T['__nullType'] ? null : T['__nullType']) : Output : K extends 'outputSchema' ? null extends T['__type'] ? OutputSchema | T['nullSchema'] : OutputSchema : T[K] };
|
|
7270
|
-
export type ParseNull<T extends Column
|
|
7271
|
-
type DefaultData<T extends Column
|
|
7272
|
-
export type Default<T extends Column
|
|
7273
|
-
type DefaultSelectData<T extends Column
|
|
7274
|
-
export type DefaultSelect<T extends Column
|
|
7275
|
+
export type ParseNull<T extends Column.Pick.ForParseNull, NullSchema, NullType> = { [K in keyof T]: K extends '__outputType' ? null extends T['__type'] ? Exclude<T['__outputType'], null> | NullType : T['__outputType'] : K extends '__nullType' ? NullType : K extends 'outputSchema' ? null extends T['__type'] ? T['outputSchema'] | NullSchema : T['outputSchema'] : K extends 'nullSchema' ? NullSchema : T[K] };
|
|
7276
|
+
type DefaultData<T extends Column.Data, Value> = { [K in keyof T]: K extends 'default' ? Value extends null ? never : Value : K extends 'optional' ? true : T[K] };
|
|
7277
|
+
export type Default<T extends Column.Pick.Data, Value> = { [K in keyof T]: K extends 'data' ? DefaultData<T['data'], Value> : T[K] };
|
|
7278
|
+
type DefaultSelectData<T extends Column.Data, Value> = { [K in keyof T]: K extends 'explicitSelect' ? Value extends true ? false : true : T[K] };
|
|
7279
|
+
export type DefaultSelect<T extends Column.Pick.Data, Value extends boolean> = { [K in keyof T]: K extends 'data' ? DefaultSelectData<T['data'], Value> : T[K] };
|
|
7275
7280
|
export interface IsAppReadOnly {
|
|
7276
7281
|
data: {
|
|
7277
7282
|
appReadOnly: true;
|
|
7278
7283
|
};
|
|
7279
7284
|
}
|
|
7280
|
-
export type Generated<T extends Column
|
|
7285
|
+
export type Generated<T extends Column.Pick.Data> = { [K in keyof T]: K extends 'data' ? { [K in keyof T['data']]: K extends 'default' ? true : T['data'][K] } : K extends '__inputType' ? never : T[K] };
|
|
7281
7286
|
export {};
|
|
7282
7287
|
}
|
|
7283
7288
|
export namespace Pick {
|
|
7284
7289
|
interface Data {
|
|
7285
|
-
data: Column
|
|
7290
|
+
data: Column.Data;
|
|
7286
7291
|
}
|
|
7287
7292
|
interface Type {
|
|
7288
7293
|
__type: unknown;
|
|
@@ -7327,7 +7332,7 @@ declare namespace Column$1 {
|
|
|
7327
7332
|
dataType: T;
|
|
7328
7333
|
}
|
|
7329
7334
|
interface QueryInit extends QueryColumn, InputType {
|
|
7330
|
-
data: Column
|
|
7335
|
+
data: Column.QueryData;
|
|
7331
7336
|
}
|
|
7332
7337
|
interface OutputSchema {
|
|
7333
7338
|
outputSchema: any;
|
|
@@ -7350,17 +7355,17 @@ declare namespace Column$1 {
|
|
|
7350
7355
|
}
|
|
7351
7356
|
export namespace Shape {
|
|
7352
7357
|
interface Data {
|
|
7353
|
-
[K: string]: Column
|
|
7358
|
+
[K: string]: Column.Pick.Data;
|
|
7354
7359
|
}
|
|
7355
7360
|
interface QueryInit {
|
|
7356
|
-
[K: string]: Column
|
|
7361
|
+
[K: string]: Column.Pick.QueryInit;
|
|
7357
7362
|
}
|
|
7358
7363
|
interface ForValidation {
|
|
7359
|
-
[K: string]: Column
|
|
7364
|
+
[K: string]: Column.Pick.ForValidation;
|
|
7360
7365
|
}
|
|
7361
7366
|
}
|
|
7362
7367
|
export interface QueryColumns {
|
|
7363
|
-
[K: string]: Column
|
|
7368
|
+
[K: string]: Column.Pick.QueryColumn;
|
|
7364
7369
|
}
|
|
7365
7370
|
export interface QueryColumnsInit {
|
|
7366
7371
|
[K: string]: Pick.QueryInit;
|
|
@@ -7374,7 +7379,7 @@ declare namespace Column$1 {
|
|
|
7374
7379
|
interface TableParam {
|
|
7375
7380
|
new (): TableParamInstance;
|
|
7376
7381
|
}
|
|
7377
|
-
type ColumnNameOfTable<Table extends Column
|
|
7382
|
+
type ColumnNameOfTable<Table extends Column.ForeignKey.TableParam> = Table extends (new () => {
|
|
7378
7383
|
columns: {
|
|
7379
7384
|
shape: infer R;
|
|
7380
7385
|
};
|
|
@@ -7421,10 +7426,10 @@ declare namespace Column$1 {
|
|
|
7421
7426
|
defaultDefault: unknown;
|
|
7422
7427
|
runtimeDefault?(): unknown;
|
|
7423
7428
|
explicitSelect?: boolean;
|
|
7424
|
-
as?: Column
|
|
7429
|
+
as?: Column.Pick.Data;
|
|
7425
7430
|
unique?: string;
|
|
7426
|
-
modifyQuery?(q: Query, column: Column
|
|
7427
|
-
checks?: Column
|
|
7431
|
+
modifyQuery?(q: Query, column: Column.Pick.Data): void;
|
|
7432
|
+
checks?: Column.Data.Check[];
|
|
7428
7433
|
isOfCustomType?: boolean;
|
|
7429
7434
|
errors?: RecordString$1;
|
|
7430
7435
|
defaultTimestamp?: 'createdAt' | 'updatedAt';
|
|
@@ -7456,6 +7461,8 @@ declare namespace Column$1 {
|
|
|
7456
7461
|
identity?: TableData$1.Identity;
|
|
7457
7462
|
generated?: Data.Generated;
|
|
7458
7463
|
readonly?: boolean;
|
|
7464
|
+
valueToArray?: boolean;
|
|
7465
|
+
skipValueToArray?: boolean;
|
|
7459
7466
|
}
|
|
7460
7467
|
export namespace Data {
|
|
7461
7468
|
interface Check {
|
|
@@ -8349,7 +8356,7 @@ type SelectAllColumn = string | SelectAllColumnExpression;
|
|
|
8349
8356
|
interface QueryData$1 extends QueryDataAliases, PickQueryDataParsers, HasHookSelect, MutativeQueriesSelectRelationsQueryData {
|
|
8350
8357
|
type: QueryType;
|
|
8351
8358
|
adapter: Adapter$1;
|
|
8352
|
-
|
|
8359
|
+
selectShape: ColumnsShape$1;
|
|
8353
8360
|
handleResult: HandleResult;
|
|
8354
8361
|
catch?: boolean;
|
|
8355
8362
|
returnType: QueryReturnType$1;
|
package/dist/node-postgres.js
CHANGED
|
@@ -37,19 +37,13 @@ const createDb = ({ log, ...options }) => {
|
|
|
37
37
|
});
|
|
38
38
|
};
|
|
39
39
|
const { types } = pg.default;
|
|
40
|
-
const defaultTypeParsers = {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
types.builtins.TIMESTAMP,
|
|
48
|
-
types.builtins.TIMESTAMPTZ,
|
|
49
|
-
types.builtins.CIRCLE
|
|
50
|
-
].forEach((id) => {
|
|
51
|
-
delete defaultTypeParsers[id];
|
|
52
|
-
});
|
|
40
|
+
const defaultTypeParsers = {
|
|
41
|
+
[types.builtins.DATE]: pqb_internal.returnArg,
|
|
42
|
+
[types.builtins.TIMESTAMP]: pqb_internal.returnArg,
|
|
43
|
+
[types.builtins.TIMESTAMPTZ]: pqb_internal.returnArg,
|
|
44
|
+
[types.builtins.CIRCLE]: pqb_internal.returnArg,
|
|
45
|
+
600: pqb_internal.returnArg
|
|
46
|
+
};
|
|
53
47
|
const queryClient = (client, text, values, arraysMode) => {
|
|
54
48
|
const params = {
|
|
55
49
|
text,
|
|
@@ -192,8 +186,8 @@ const NodePostgresAdapter = {
|
|
|
192
186
|
return pool.end();
|
|
193
187
|
}
|
|
194
188
|
};
|
|
195
|
-
const defaultTypesConfig = { getTypeParser(id) {
|
|
196
|
-
return defaultTypeParsers[id] ||
|
|
189
|
+
const defaultTypesConfig = { getTypeParser(id, format) {
|
|
190
|
+
return defaultTypeParsers[id] || types.getTypeParser(id, format);
|
|
197
191
|
} };
|
|
198
192
|
const normalizeArraysResult = (result) => {
|
|
199
193
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-postgres.js","names":["AdapterClass","noop","DatabaseError","returnArg"],"sources":["../src/adapters/node-postgres.ts"],"sourcesContent":["import pg, { DatabaseError, Pool, PoolClient, PoolConfig } from 'pg';\nimport {\n AdapterConfigBase,\n ColumnSchemaConfig,\n noop,\n QueryResult,\n QueryResultRow,\n RecordUnknown,\n returnArg,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbOptions,\n DbResult,\n QuerySchema,\n AdapterClass,\n DriverAdapter,\n defaultSchemaConfig,\n quoteIdentifier,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n jsonEncodedByDriver: false,\n};\n\nexport const nodePostgresSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: DbOptions<SchemaConfig, ColumnTypes> &\n Omit<NodePostgresAdapterOptions, 'log'>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: nodePostgresSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: NodePostgresAdapter,\n config: options,\n }),\n });\n};\n\nconst { types } = pg;\n\nexport interface TypeParsers {\n [K: number]: (input: string) => unknown;\n}\n\nconst defaultTypeParsers: TypeParsers = {};\n\nfor (const key in types.builtins) {\n const id = types.builtins[key as keyof typeof types.builtins];\n defaultTypeParsers[id] = types.getTypeParser(id);\n}\n\n[\n types.builtins.DATE,\n types.builtins.TIMESTAMP,\n types.builtins.TIMESTAMPTZ,\n types.builtins.CIRCLE,\n].forEach((id) => {\n delete defaultTypeParsers[id];\n});\n\nexport interface AdapterConfig\n extends\n Omit<AdapterConfigBase, 'searchPath' | 'ssl'>,\n Omit<PoolConfig, 'types' | 'connectionString'> {\n databaseURL?: string;\n}\n\nexport interface NodePostgresAdapterOptions extends Omit<AdapterConfig, 'log'> {\n schema?: QuerySchema;\n}\n\nconst queryClient = <T = QueryResultRow>(\n client: PoolClient,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const params: any = {\n text,\n values,\n rowMode: arraysMode ? 'array' : undefined,\n types: defaultTypesConfig,\n };\n\n // When using save points (it's in transaction), need to perform a single query at a time.\n // stating 1 then 2 then releasing 1 would fail.\n // Start 1, release 1, start 2, release 2, and so on.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: () => void | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = () => {\n res();\n };\n });\n\n return __lock.then(() => {\n const promise = client.query(params) as Promise<QueryResult>;\n promise.then(resolve, resolve);\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n });\n }\n\n const promise = client.query(params) as Promise<QueryResult>;\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n};\n\nexport const NodePostgresAdapter: DriverAdapter = {\n manualPool: true,\n schemaConfig,\n errorClass: DatabaseError,\n errorFields: {\n message: 'message',\n length: 'length',\n name: 'name',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: NodePostgresAdapterOptions): pg.Pool {\n if (config.databaseURL) {\n (config as PoolConfig).connectionString = config.databaseURL;\n }\n\n if (config.setConfig?.search_path) {\n config = {\n ...config,\n options: `${config.options ? `${config.options} ` : ''}-c search_path=\"${config.setConfig.search_path}\"`,\n };\n }\n\n return new pg.Pool(config);\n },\n\n queryClient,\n\n borrow(pool: Pool): Promise<PoolClient> {\n return pool.connect();\n },\n\n release(client: PoolClient): void {\n client.release();\n },\n\n async begin<DriverClient, Result>(\n pool: Pool,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await pool.connect();\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n client.release();\n }\n },\n\n async savepoint<T>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = state.name.replaceAll('\"', '\"\"');\n\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve!(res as QueryResult<T>);\n } catch (err) {\n resultReject!(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: Pool): Promise<void> {\n return pool.end();\n },\n};\n\nconst defaultTypesConfig = {\n getTypeParser(id: number) {\n return defaultTypeParsers[id] || returnArg;\n },\n};\n\nconst normalizeArraysResult = <\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[] = any[],\n>(\n result: QueryResult,\n): QueryResult<R> => {\n return result as unknown as QueryResult<R>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,eAA2C,EAC/C,qBAAqB,OACtB;AAED,MAAa,2BAA2B,OAAO,cAAA,GAAA,aAAA,qBACnB,aAAa,EACvC,aACD;AAED,MAAa,YAGX,EACA,KACA,GAAG,cAEgE;AACnE,SAAA,GAAA,IAAA,qBAA2B;EACzB,cAAc;EACd,GAAG;EACH;EACA,SAAS,IAAIA,aAAAA,aAAa;GACxB,eAAe;GACf,QAAQ;GACT,CAAC;EACH,CAAC;;AAGJ,MAAM,EAAE,UAAU,GAAA;AAMlB,MAAM,qBAAkC,EAAE;AAE1C,KAAK,MAAM,OAAO,MAAM,UAAU;CAChC,MAAM,KAAK,MAAM,SAAS;AAC1B,oBAAmB,MAAM,MAAM,cAAc,GAAG;;AAGlD;CACE,MAAM,SAAS;CACf,MAAM,SAAS;CACf,MAAM,SAAS;CACf,MAAM,SAAS;CAChB,CAAC,SAAS,OAAO;AAChB,QAAO,mBAAmB;EAC1B;AAaF,MAAM,eACJ,QACA,MACA,QACA,eAC4B;CAE5B,MAAM,SAAc;EAClB;EACA;EACA,SAAS,aAAa,UAAU,KAAA;EAChC,OAAO;EACR;CAKD,MAAM,EAAE,WAAW;AACnB,KAAI,QAAQ;EACV,IAAI;AACH,SAAoC,SAAS,IAAI,SAAe,QAAQ;AACvE,mBAAgB;AACd,SAAK;;IAEP;AAEF,SAAO,OAAO,WAAW;GACvB,MAAM,UAAU,OAAO,MAAM,OAAO;AACpC,WAAQ,KAAK,SAAS,QAAQ;AAC9B,UAAO,QAAQ,MAAM,WACnB,aAAa,sBAAsB,OAAO,GAAG,OAC9C;IACD;;CAGJ,MAAM,UAAU,OAAO,MAAM,OAAO;AAEnC,QAAoD,SACnD,QAAQ,MAAMC,aAAAA,KAAK;AAErB,QAAO,QAAQ,MAAM,WACnB,aAAa,sBAAsB,OAAO,GAAG,OAC9C;;AAGH,MAAa,sBAAqC;CAChD,YAAY;CACZ;CACA,YAAYC,GAAAA;CACZ,aAAa;EACX,SAAS;EACT,QAAQ;EACR,MAAM;EACN,UAAU;EACV,MAAM;EACN,QAAQ;EACR,MAAM;EACN,UAAU;EACV,kBAAkB;EAClB,eAAe;EACf,OAAO;EACP,QAAQ;EACR,OAAO;EACP,QAAQ;EACR,UAAU;EACV,YAAY;EACZ,MAAM;EACN,MAAM;EACN,SAAS;EACV;CAED,UAAU,QAA6C;AACrD,MAAI,OAAO,YACR,QAAsB,mBAAmB,OAAO;AAGnD,MAAI,OAAO,WAAW,YACpB,UAAS;GACP,GAAG;GACH,SAAS,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,KAAK,GAAG,kBAAkB,OAAO,UAAU,YAAY;GACvG;AAGH,SAAO,IAAI,GAAA,QAAG,KAAK,OAAO;;CAG5B;CAEA,OAAO,MAAiC;AACtC,SAAO,KAAK,SAAS;;CAGvB,QAAQ,QAA0B;AAChC,SAAO,SAAS;;CAGlB,MAAM,MACJ,MACA,IACA,SACiB;EACjB,MAAM,SAAS,MAAM,KAAK,SAAS;AAEnC,MAAI;AACF,SAAM,YAAY,QAAQ,UAAU,WAAW,UAAU,QAAQ;GAEjE,IAAI;AACJ,OAAI;AACF,aAAS,MAAM,GAAG,OAAuB;YAClC,KAAK;AACZ,UAAM,YAAY,QAAQ,WAAW;AACrC,UAAM;;AAER,SAAM,YAAY,QAAQ,SAAS;AACnC,UAAO;YACC;AACR,UAAO,SAAS;;;CAIpB,MAAM,UACJ,QAEA,YACA,MACA,IACY;EACZ,MAAM,YAAA,GAAA,aAAA,iBAA2B,KAAK;AACtC,MAAI;AACF,SAAM,YAAY,QAAQ,aAAa,WAAW;GAClD,MAAM,MAAM,MAAM,IAAI;AACtB,SAAM,YAAY,QAAQ,qBAAqB,WAAW;AAC1D,UAAO;WACA,KAAK;AACZ,SAAM,YAAY,QAAQ,yBAAyB,WAAW;AAC9D,SAAM;;;CAIV,MAAM,eACJ,QAEA,YACA,OACA,MACA,QACA,YACyB;EACzB,MAAM,WAAW,MAAM,KAAK,WAAW,MAAK,OAAK;EAEjD,IAAI;EACJ,IAAI;EACJ,MAAM,UAAU,IAAI,SAAe,KAAK,QAAQ;AAC9C,aAAU;AACV,YAAS;IACT;EAEF,IAAI;EACJ,IAAI;EACJ,MAAM,gBAAgB,IAAI,SAAyB,KAAK,QAAQ;AAC9D,mBAAgB;AAChB,kBAAe;IACf;EAEF,MAAM,oBAAoB,YAAY;AACpC,OAAI;AACF,UAAM,YAAY,QAAQ,aAAa,WAAW;AAElD,QAAI;KACF,MAAM,MAAM,MAAM,YAAe,QAAQ,MAAM,QAAQ,WAAW;AAClE,mBAAe,IAAsB;aAC9B,KAAK;AACZ,kBAAc,IAAI;AAClB,WAAM;;IAGR,MAAM,SAAS,MAAM;AACrB,UAAM,YAAY,QAAQ,qBAAqB,WAAW;AAC1D,WAAO;YACA,KAAK;AACZ,UAAM,YAAY,QAAQ,yBAAyB,WAAW;AAC9D,UAAM;;MAEN;AAEJ,QAAM,kBAAkB;GACtB,MAAM,UAAU;AACd,aAAS;AACT,UAAM;;GAER,MAAM,SAAS,KAAK;AAClB,WAAO,IAAI;AACX,UAAM,iBAAiB,MAAMD,aAAAA,KAAK;;GAErC;AAED,SAAO;;CAGT,MAAM,MAA2B;AAC/B,SAAO,KAAK,KAAK;;CAEpB;AAED,MAAM,qBAAqB,EACzB,cAAc,IAAY;AACxB,QAAO,mBAAmB,OAAOE,aAAAA;GAEpC;AAED,MAAM,yBAIJ,WACmB;AACnB,QAAO"}
|
|
1
|
+
{"version":3,"file":"node-postgres.js","names":["AdapterClass","returnArg","noop","DatabaseError"],"sources":["../src/adapters/node-postgres.ts"],"sourcesContent":["import pg, { DatabaseError, Pool, PoolClient, PoolConfig } from 'pg';\nimport {\n AdapterConfigBase,\n ColumnSchemaConfig,\n noop,\n QueryResult,\n QueryResultRow,\n RecordUnknown,\n returnArg,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbOptions,\n DbResult,\n QuerySchema,\n AdapterClass,\n DriverAdapter,\n defaultSchemaConfig,\n quoteIdentifier,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n jsonEncodedByDriver: false,\n};\n\nexport const nodePostgresSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: DbOptions<SchemaConfig, ColumnTypes> &\n Omit<NodePostgresAdapterOptions, 'log'>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: nodePostgresSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: NodePostgresAdapter,\n config: options,\n }),\n });\n};\n\nconst { types } = pg;\n\nexport interface TypeParsers {\n [K: number]: (input: string) => unknown;\n}\n\nconst defaultTypeParsers: TypeParsers = {\n [types.builtins.DATE]: returnArg,\n [types.builtins.TIMESTAMP]: returnArg,\n [types.builtins.TIMESTAMPTZ]: returnArg,\n [types.builtins.CIRCLE]: returnArg,\n 600: returnArg, // point\n};\n\nexport interface AdapterConfig\n extends\n Omit<AdapterConfigBase, 'searchPath' | 'ssl'>,\n Omit<PoolConfig, 'types' | 'connectionString'> {\n databaseURL?: string;\n}\n\nexport interface NodePostgresAdapterOptions extends Omit<AdapterConfig, 'log'> {\n schema?: QuerySchema;\n}\n\nconst queryClient = <T = QueryResultRow>(\n client: PoolClient,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const params: any = {\n text,\n values,\n rowMode: arraysMode ? 'array' : undefined,\n types: defaultTypesConfig,\n };\n\n // When using save points (it's in transaction), need to perform a single query at a time.\n // stating 1 then 2 then releasing 1 would fail.\n // Start 1, release 1, start 2, release 2, and so on.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: () => void | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = () => {\n res();\n };\n });\n\n return __lock.then(() => {\n const promise = client.query(params) as Promise<QueryResult>;\n promise.then(resolve, resolve);\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n });\n }\n\n const promise = client.query(params) as Promise<QueryResult>;\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n};\n\nexport const NodePostgresAdapter: DriverAdapter = {\n manualPool: true,\n schemaConfig,\n errorClass: DatabaseError,\n errorFields: {\n message: 'message',\n length: 'length',\n name: 'name',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: NodePostgresAdapterOptions): pg.Pool {\n if (config.databaseURL) {\n (config as PoolConfig).connectionString = config.databaseURL;\n }\n\n if (config.setConfig?.search_path) {\n config = {\n ...config,\n options: `${config.options ? `${config.options} ` : ''}-c search_path=\"${config.setConfig.search_path}\"`,\n };\n }\n\n return new pg.Pool(config);\n },\n\n queryClient,\n\n borrow(pool: Pool): Promise<PoolClient> {\n return pool.connect();\n },\n\n release(client: PoolClient): void {\n client.release();\n },\n\n async begin<DriverClient, Result>(\n pool: Pool,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await pool.connect();\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n client.release();\n }\n },\n\n async savepoint<T>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = state.name.replaceAll('\"', '\"\"');\n\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve!(res as QueryResult<T>);\n } catch (err) {\n resultReject!(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: Pool): Promise<void> {\n return pool.end();\n },\n};\n\nconst defaultTypesConfig = {\n getTypeParser(id: number, format?: 'text' | 'binary') {\n return defaultTypeParsers[id] || types.getTypeParser(id, format as 'text');\n },\n};\n\nconst normalizeArraysResult = <\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[] = any[],\n>(\n result: QueryResult,\n): QueryResult<R> => {\n return result as unknown as QueryResult<R>;\n};\n"],"mappings":"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"}
|
package/dist/node-postgres.mjs
CHANGED
|
@@ -15,19 +15,13 @@ const createDb = ({ log, ...options }) => {
|
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
const { types } = pg;
|
|
18
|
-
const defaultTypeParsers = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
types.builtins.TIMESTAMP,
|
|
26
|
-
types.builtins.TIMESTAMPTZ,
|
|
27
|
-
types.builtins.CIRCLE
|
|
28
|
-
].forEach((id) => {
|
|
29
|
-
delete defaultTypeParsers[id];
|
|
30
|
-
});
|
|
18
|
+
const defaultTypeParsers = {
|
|
19
|
+
[types.builtins.DATE]: returnArg,
|
|
20
|
+
[types.builtins.TIMESTAMP]: returnArg,
|
|
21
|
+
[types.builtins.TIMESTAMPTZ]: returnArg,
|
|
22
|
+
[types.builtins.CIRCLE]: returnArg,
|
|
23
|
+
600: returnArg
|
|
24
|
+
};
|
|
31
25
|
const queryClient = (client, text, values, arraysMode) => {
|
|
32
26
|
const params = {
|
|
33
27
|
text,
|
|
@@ -170,8 +164,8 @@ const NodePostgresAdapter = {
|
|
|
170
164
|
return pool.end();
|
|
171
165
|
}
|
|
172
166
|
};
|
|
173
|
-
const defaultTypesConfig = { getTypeParser(id) {
|
|
174
|
-
return defaultTypeParsers[id] ||
|
|
167
|
+
const defaultTypesConfig = { getTypeParser(id, format) {
|
|
168
|
+
return defaultTypeParsers[id] || types.getTypeParser(id, format);
|
|
175
169
|
} };
|
|
176
170
|
const normalizeArraysResult = (result) => {
|
|
177
171
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-postgres.mjs","names":[],"sources":["../src/adapters/node-postgres.ts"],"sourcesContent":["import pg, { DatabaseError, Pool, PoolClient, PoolConfig } from 'pg';\nimport {\n AdapterConfigBase,\n ColumnSchemaConfig,\n noop,\n QueryResult,\n QueryResultRow,\n RecordUnknown,\n returnArg,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbOptions,\n DbResult,\n QuerySchema,\n AdapterClass,\n DriverAdapter,\n defaultSchemaConfig,\n quoteIdentifier,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n jsonEncodedByDriver: false,\n};\n\nexport const nodePostgresSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: DbOptions<SchemaConfig, ColumnTypes> &\n Omit<NodePostgresAdapterOptions, 'log'>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: nodePostgresSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: NodePostgresAdapter,\n config: options,\n }),\n });\n};\n\nconst { types } = pg;\n\nexport interface TypeParsers {\n [K: number]: (input: string) => unknown;\n}\n\nconst defaultTypeParsers: TypeParsers = {};\n\nfor (const key in types.builtins) {\n const id = types.builtins[key as keyof typeof types.builtins];\n defaultTypeParsers[id] = types.getTypeParser(id);\n}\n\n[\n types.builtins.DATE,\n types.builtins.TIMESTAMP,\n types.builtins.TIMESTAMPTZ,\n types.builtins.CIRCLE,\n].forEach((id) => {\n delete defaultTypeParsers[id];\n});\n\nexport interface AdapterConfig\n extends\n Omit<AdapterConfigBase, 'searchPath' | 'ssl'>,\n Omit<PoolConfig, 'types' | 'connectionString'> {\n databaseURL?: string;\n}\n\nexport interface NodePostgresAdapterOptions extends Omit<AdapterConfig, 'log'> {\n schema?: QuerySchema;\n}\n\nconst queryClient = <T = QueryResultRow>(\n client: PoolClient,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const params: any = {\n text,\n values,\n rowMode: arraysMode ? 'array' : undefined,\n types: defaultTypesConfig,\n };\n\n // When using save points (it's in transaction), need to perform a single query at a time.\n // stating 1 then 2 then releasing 1 would fail.\n // Start 1, release 1, start 2, release 2, and so on.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: () => void | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = () => {\n res();\n };\n });\n\n return __lock.then(() => {\n const promise = client.query(params) as Promise<QueryResult>;\n promise.then(resolve, resolve);\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n });\n }\n\n const promise = client.query(params) as Promise<QueryResult>;\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n};\n\nexport const NodePostgresAdapter: DriverAdapter = {\n manualPool: true,\n schemaConfig,\n errorClass: DatabaseError,\n errorFields: {\n message: 'message',\n length: 'length',\n name: 'name',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: NodePostgresAdapterOptions): pg.Pool {\n if (config.databaseURL) {\n (config as PoolConfig).connectionString = config.databaseURL;\n }\n\n if (config.setConfig?.search_path) {\n config = {\n ...config,\n options: `${config.options ? `${config.options} ` : ''}-c search_path=\"${config.setConfig.search_path}\"`,\n };\n }\n\n return new pg.Pool(config);\n },\n\n queryClient,\n\n borrow(pool: Pool): Promise<PoolClient> {\n return pool.connect();\n },\n\n release(client: PoolClient): void {\n client.release();\n },\n\n async begin<DriverClient, Result>(\n pool: Pool,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await pool.connect();\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n client.release();\n }\n },\n\n async savepoint<T>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = state.name.replaceAll('\"', '\"\"');\n\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve!(res as QueryResult<T>);\n } catch (err) {\n resultReject!(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: Pool): Promise<void> {\n return pool.end();\n },\n};\n\nconst defaultTypesConfig = {\n getTypeParser(id: number) {\n return defaultTypeParsers[id] || returnArg;\n },\n};\n\nconst normalizeArraysResult = <\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[] = any[],\n>(\n result: QueryResult,\n): QueryResult<R> => {\n return result as unknown as QueryResult<R>;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node-postgres.mjs","names":[],"sources":["../src/adapters/node-postgres.ts"],"sourcesContent":["import pg, { DatabaseError, Pool, PoolClient, PoolConfig } from 'pg';\nimport {\n AdapterConfigBase,\n ColumnSchemaConfig,\n noop,\n QueryResult,\n QueryResultRow,\n RecordUnknown,\n returnArg,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbOptions,\n DbResult,\n QuerySchema,\n AdapterClass,\n DriverAdapter,\n defaultSchemaConfig,\n quoteIdentifier,\n AdapterSchemaConfigOptions,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\n\nconst schemaConfig: AdapterSchemaConfigOptions = {\n jsonEncodedByDriver: false,\n};\n\nexport const nodePostgresSchemaConfig = Object.assign(\n () => defaultSchemaConfig(schemaConfig),\n schemaConfig,\n);\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>({\n log,\n ...options\n}: DbOptions<SchemaConfig, ColumnTypes> &\n Omit<NodePostgresAdapterOptions, 'log'>): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n schemaConfig: nodePostgresSchemaConfig as unknown as () => SchemaConfig,\n ...options,\n log,\n adapter: new AdapterClass({\n driverAdapter: NodePostgresAdapter,\n config: options,\n }),\n });\n};\n\nconst { types } = pg;\n\nexport interface TypeParsers {\n [K: number]: (input: string) => unknown;\n}\n\nconst defaultTypeParsers: TypeParsers = {\n [types.builtins.DATE]: returnArg,\n [types.builtins.TIMESTAMP]: returnArg,\n [types.builtins.TIMESTAMPTZ]: returnArg,\n [types.builtins.CIRCLE]: returnArg,\n 600: returnArg, // point\n};\n\nexport interface AdapterConfig\n extends\n Omit<AdapterConfigBase, 'searchPath' | 'ssl'>,\n Omit<PoolConfig, 'types' | 'connectionString'> {\n databaseURL?: string;\n}\n\nexport interface NodePostgresAdapterOptions extends Omit<AdapterConfig, 'log'> {\n schema?: QuerySchema;\n}\n\nconst queryClient = <T = QueryResultRow>(\n client: PoolClient,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n): Promise<QueryResult<T>> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const params: any = {\n text,\n values,\n rowMode: arraysMode ? 'array' : undefined,\n types: defaultTypesConfig,\n };\n\n // When using save points (it's in transaction), need to perform a single query at a time.\n // stating 1 then 2 then releasing 1 would fail.\n // Start 1, release 1, start 2, release 2, and so on.\n const { __lock } = client as unknown as { __lock?: Promise<unknown> };\n if (__lock) {\n let resolve: () => void | undefined;\n (client as unknown as RecordUnknown).__lock = new Promise<void>((res) => {\n resolve = () => {\n res();\n };\n });\n\n return __lock.then(() => {\n const promise = client.query(params) as Promise<QueryResult>;\n promise.then(resolve, resolve);\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n });\n }\n\n const promise = client.query(params) as Promise<QueryResult>;\n\n (client as unknown as { __lock?: Promise<unknown> }).__lock =\n promise.catch(noop);\n\n return promise.then((result) =>\n arraysMode ? normalizeArraysResult(result) : result,\n ) as Promise<QueryResult<T>>;\n};\n\nexport const NodePostgresAdapter: DriverAdapter = {\n manualPool: true,\n schemaConfig,\n errorClass: DatabaseError,\n errorFields: {\n message: 'message',\n length: 'length',\n name: 'name',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n hint: 'hint',\n position: 'position',\n internalPosition: 'internalPosition',\n internalQuery: 'internalQuery',\n where: 'where',\n schema: 'schema',\n table: 'table',\n column: 'column',\n dataType: 'dataType',\n constraint: 'constraint',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(config: NodePostgresAdapterOptions): pg.Pool {\n if (config.databaseURL) {\n (config as PoolConfig).connectionString = config.databaseURL;\n }\n\n if (config.setConfig?.search_path) {\n config = {\n ...config,\n options: `${config.options ? `${config.options} ` : ''}-c search_path=\"${config.setConfig.search_path}\"`,\n };\n }\n\n return new pg.Pool(config);\n },\n\n queryClient,\n\n borrow(pool: Pool): Promise<PoolClient> {\n return pool.connect();\n },\n\n release(client: PoolClient): void {\n client.release();\n },\n\n async begin<DriverClient, Result>(\n pool: Pool,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n const client = await pool.connect();\n\n try {\n await queryClient(client, options ? 'BEGIN ' + options : 'BEGIN');\n\n let result;\n try {\n result = await cb(client as DriverClient);\n } catch (err) {\n await queryClient(client, 'ROLLBACK');\n throw err;\n }\n await queryClient(client, 'COMMIT');\n return result as Result;\n } finally {\n client.release();\n }\n },\n\n async savepoint<T>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n const safeName = quoteIdentifier(name);\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n const res = await cb();\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return res;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: PoolClient,\n // node-postgres doesn't need to switch the client in a savepoint\n _setClient: (client: PoolClient) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n const safeName = state.name.replaceAll('\"', '\"\"');\n\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = (async () => {\n try {\n await queryClient(client, `SAVEPOINT ${safeName}`);\n\n try {\n const res = await queryClient<T>(client, text, values, arraysMode);\n resultResolve!(res as QueryResult<T>);\n } catch (err) {\n resultReject!(err);\n throw err;\n }\n\n const result = await promise;\n await queryClient(client, `RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (err) {\n await queryClient(client, `ROLLBACK TO SAVEPOINT ${safeName}`);\n throw err;\n }\n })();\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(pool: Pool): Promise<void> {\n return pool.end();\n },\n};\n\nconst defaultTypesConfig = {\n getTypeParser(id: number, format?: 'text' | 'binary') {\n return defaultTypeParsers[id] || types.getTypeParser(id, format as 'text');\n },\n};\n\nconst normalizeArraysResult = <\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[] = any[],\n>(\n result: QueryResult,\n): QueryResult<R> => {\n return result as unknown as QueryResult<R>;\n};\n"],"mappings":"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"}
|
package/dist/postgres-js.js
CHANGED
|
@@ -39,6 +39,69 @@ const parseInterval = (str) => {
|
|
|
39
39
|
milliseconds: Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1e6) / 1e3
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
|
+
const patchPostgresJsArrayParsers = (sql) => {
|
|
43
|
+
const options = sql.options;
|
|
44
|
+
const { parsers } = options;
|
|
45
|
+
const serializers = options.serializers;
|
|
46
|
+
options.serializers = new Proxy(serializers, { set(target, property, value, receiver) {
|
|
47
|
+
const result = Reflect.set(target, property, value, receiver);
|
|
48
|
+
if (typeof property === "symbol") return result;
|
|
49
|
+
const typarray = Number(property);
|
|
50
|
+
if (!Number.isInteger(typarray) || !parsers[typarray]?.array) return result;
|
|
51
|
+
const oid = findTypeOidByArrayOid(options.shared.typeArrayMap, typarray);
|
|
52
|
+
if (!oid) return result;
|
|
53
|
+
const itemParser = parsers[oid];
|
|
54
|
+
const arrayParser = (input) => parsePostgresArray(input, itemParser, typarray);
|
|
55
|
+
arrayParser.array = true;
|
|
56
|
+
parsers[typarray] = arrayParser;
|
|
57
|
+
return result;
|
|
58
|
+
} });
|
|
59
|
+
};
|
|
60
|
+
const findTypeOidByArrayOid = (typeArrayMap, typarray) => {
|
|
61
|
+
for (const oid in typeArrayMap) if (typeArrayMap[oid] === typarray) return Number(oid);
|
|
62
|
+
};
|
|
63
|
+
const parsePostgresArray = (input, parser, typarray) => {
|
|
64
|
+
return parsePostgresArrayLoop({
|
|
65
|
+
i: 0,
|
|
66
|
+
char: null,
|
|
67
|
+
str: "",
|
|
68
|
+
quoted: false,
|
|
69
|
+
last: 0
|
|
70
|
+
}, input, parser, typarray);
|
|
71
|
+
};
|
|
72
|
+
const parsePostgresArrayLoop = (state, input, parser, typarray) => {
|
|
73
|
+
const result = [];
|
|
74
|
+
const delimiter = typarray === 1020 ? ";" : ",";
|
|
75
|
+
for (; state.i < input.length; state.i++) {
|
|
76
|
+
state.char = input[state.i];
|
|
77
|
+
if (state.quoted) if (state.char === "\\") state.str += input[++state.i];
|
|
78
|
+
else if (state.char === "\"") {
|
|
79
|
+
result.push(parser ? parser(state.str) : state.str);
|
|
80
|
+
state.str = "";
|
|
81
|
+
state.quoted = input[state.i + 1] === "\"";
|
|
82
|
+
state.last = state.i + 2;
|
|
83
|
+
} else state.str += state.char;
|
|
84
|
+
else if (state.char === "\"") state.quoted = true;
|
|
85
|
+
else if (state.char === "{") {
|
|
86
|
+
state.last = ++state.i;
|
|
87
|
+
result.push(parsePostgresArrayLoop(state, input, parser, typarray));
|
|
88
|
+
} else if (state.char === "}") {
|
|
89
|
+
state.quoted = false;
|
|
90
|
+
if (state.last < state.i) result.push(parseArrayValue(input.slice(state.last, state.i), parser));
|
|
91
|
+
state.last = state.i + 1;
|
|
92
|
+
break;
|
|
93
|
+
} else if (state.char === delimiter && state.p !== "}" && state.p !== "\"") {
|
|
94
|
+
result.push(parseArrayValue(input.slice(state.last, state.i), parser));
|
|
95
|
+
state.last = state.i + 1;
|
|
96
|
+
}
|
|
97
|
+
state.p = state.char;
|
|
98
|
+
}
|
|
99
|
+
if (state.last < state.i) result.push(parseArrayValue(input.slice(state.last, state.i + 1), parser));
|
|
100
|
+
return result;
|
|
101
|
+
};
|
|
102
|
+
const parseArrayValue = (input, parser) => {
|
|
103
|
+
return input === "NULL" ? null : parser ? parser(input) : input;
|
|
104
|
+
};
|
|
42
105
|
const createDb = (options) => {
|
|
43
106
|
return (0, pqb.createDbWithAdapter)({
|
|
44
107
|
...options,
|
|
@@ -121,6 +184,7 @@ const PostgresJsAdapter = {
|
|
|
121
184
|
let sql;
|
|
122
185
|
if (config.databaseURL) sql = (0, postgres.default)(config.databaseURL, config);
|
|
123
186
|
else sql = (0, postgres.default)(config);
|
|
187
|
+
patchPostgresJsArrayParsers(sql);
|
|
124
188
|
return sql;
|
|
125
189
|
},
|
|
126
190
|
async queryClient(client, text, values, arraysMode) {
|
package/dist/postgres-js.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-js.js","names":["AdapterClass","returnArg","noop"],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/postgres-js.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import postgres, { Row, RowList, TransactionSql } from 'postgres';\nimport {\n AdapterConfigBase,\n QueryResult,\n QueryResultRow,\n returnArg,\n DbOptions,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbResult,\n ColumnSchemaConfig,\n AdapterClass,\n DriverAdapter,\n QuerySchema,\n noop,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\n\nexport interface CreatePostgresJsDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends PostgresJsAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>(\n options: CreatePostgresJsDbOptions<SchemaConfig, ColumnTypes>,\n): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n ...options,\n adapter: new AdapterClass({\n driverAdapter: PostgresJsAdapter,\n config: options,\n }),\n });\n};\n\nexport interface PostgresJsAdapterOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n extends postgres.Options<any>, Omit<AdapterConfigBase, 'searchPath' | 'ssl'> {\n databaseURL?: string;\n schema?: QuerySchema;\n}\n\ntype RawResult = RowList<(Row & Iterable<Row>)[]>;\n\nclass PostgresJsResult<T extends QueryResultRow> implements QueryResult<T> {\n rowCount: number;\n rows: T[];\n fields: QueryResult<T>['fields'];\n\n constructor(result: RawResult) {\n this.rowCount = result.count;\n this.rows = result as never;\n this.fields = result.statement?.columns;\n }\n}\n\nclass PostgresJsArraysResult<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[],\n> implements QueryResult<R> {\n rowCount: number;\n rows: R[];\n fields: QueryResult['fields'];\n\n constructor(result: RawResult) {\n this.rowCount = result.count;\n this.rows = result as never;\n this.fields = result.statement.columns;\n }\n}\n\nconst types: Record<string, Partial<postgres.PostgresType>> = {\n bytea: {\n to: 17,\n from: 17 as never,\n serialize: (x) => '\\\\x' + Buffer.from(x).toString('hex'),\n parse: (x: string) => Buffer.from(x.slice(2), 'hex'),\n },\n dateAndTimestampAsStrings: {\n to: 25,\n from: [1082, 1114, 1184],\n parse: returnArg,\n },\n interval: {\n from: [1186],\n serialize: returnArg,\n parse: parseInterval,\n },\n json: {\n to: 114,\n from: [114, 3802],\n parse: (x) => {\n return JSON.parse(x);\n },\n },\n};\n\nexport const PostgresJsAdapter: DriverAdapter = {\n manualPool: false,\n\n errorClass: postgres.PostgresError,\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n schema: 'schema_name',\n table: 'table_name',\n constraint: 'constraint_name',\n hint: 'hint',\n position: 'position',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(params: PostgresJsAdapterOptions): postgres.Sql {\n const config: PostgresJsAdapterOptions = {\n ...params,\n types,\n };\n\n if (config.setConfig?.search_path) {\n config.connection = {\n ...config.connection,\n search_path: config.setConfig.search_path,\n };\n }\n\n let sql;\n if (config.databaseURL) {\n sql = postgres(config.databaseURL, config);\n } else {\n sql = postgres(config);\n }\n\n return sql;\n },\n\n async queryClient<T = QueryResultRow>(\n client: TransactionSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let query = client.unsafe(text, values as never) as any;\n\n if (arraysMode) query = query.values();\n\n const result = await query;\n if (result.constructor === Array) {\n return (result as RawResult[]).map((res) =>\n makePostgresJsResult(res, arraysMode),\n ) as never;\n } else {\n return makePostgresJsResult(\n result as RawResult,\n arraysMode,\n ) as QueryResult<T>;\n }\n },\n\n borrow(client: postgres.Sql): Promise<postgres.ReservedSql> {\n return client.reserve();\n },\n\n release(client: postgres.ReservedSql): void {\n client.release();\n },\n\n begin<DriverClient, Result>(\n client: postgres.Sql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n let ok: boolean | undefined;\n let result: unknown;\n\n const fn = (sql: TransactionSql): Promise<Result> =>\n cb(sql as DriverClient).then((res) => {\n ok = true;\n return (result = res);\n });\n\n return (options ? client.begin(options, fn) : client.begin(fn)).catch(\n (err) => {\n if (ok) return result;\n\n throw err;\n },\n ) as never;\n },\n\n async savepoint<T>(\n client: postgres.TransactionSql,\n setClient: (client: postgres.TransactionSql) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n let result: T | undefined;\n await client\n .savepoint(name, async (savepointClient) => {\n setClient(savepointClient);\n result = await cb();\n })\n .finally(() => {\n setClient(client);\n });\n return result as T;\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: postgres.TransactionSql,\n setClient: (client: postgres.TransactionSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = client\n .savepoint<void>(state.name, async (savepointClient) => {\n try {\n setClient(savepointClient);\n\n const res = await this.queryClient<T>(\n savepointClient,\n text,\n values,\n arraysMode,\n );\n resultResolve(res as QueryResult<T>);\n } catch (err) {\n resultReject(err);\n throw err;\n }\n\n return promise;\n })\n .finally(() => {\n setClient(client);\n });\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(client: postgres.Sql): Promise<void> {\n return client.end();\n },\n};\n\nconst makePostgresJsResult = (\n result: RawResult,\n arraysMode?: boolean,\n): QueryResult => {\n return arraysMode\n ? new PostgresJsArraysResult(result)\n : new PostgresJsResult(result);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"postgres-js.js","names":["AdapterClass","returnArg","noop"],"sources":["../src/adapters/driver-adapter-shared.ts","../src/adapters/postgres-js-array-parser-patch.ts","../src/adapters/postgres-js.ts"],"sourcesContent":["export interface PostgresInterval {\n years: number;\n months: number;\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n milliseconds: number;\n}\n\nconst intervalRegExp =\n /^\\s*(?:([+-]?\\d+)\\s+years?)?\\s*(?:([+-]?\\d+)\\s+mons?)?\\s*(?:([+-]?\\d+)\\s+days?)?\\s*(?:([+-])?(\\d+):(\\d\\d):(\\d\\d(?:\\.\\d{1,6})?))?\\s*$/;\n\nexport const parseInterval = (str: string): PostgresInterval => {\n const [, years, months, days, timeSign, hours, minutes, seconds] =\n intervalRegExp.exec(str) || [];\n const timeMultiplier = timeSign === '-' ? -1 : 1;\n const secondsFloat = Number(seconds) || 0;\n const wholeSeconds = Math.floor(secondsFloat);\n\n return {\n years: years ? Number(years) : 0,\n months: months ? Number(months) : 0,\n days: days ? Number(days) : 0,\n hours: hours ? timeMultiplier * Number(hours) : 0,\n minutes: minutes ? timeMultiplier * Number(minutes) : 0,\n seconds: timeMultiplier * wholeSeconds,\n milliseconds:\n Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1000000) /\n 1000,\n };\n};\n","import postgres from 'postgres';\n\ninterface PostgresJsParser {\n (input: string): unknown;\n array?: boolean;\n}\n\ninterface PostgresJsOptionsWithArrays extends postgres.ParsedOptions {\n shared: {\n typeArrayMap: Record<number, number>;\n };\n parsers: Record<number, PostgresJsParser>;\n}\n\nexport const patchPostgresJsArrayParsers = (sql: postgres.Sql): void => {\n const options = sql.options as PostgresJsOptionsWithArrays;\n const { parsers } = options;\n const serializers = options.serializers;\n\n options.serializers = new Proxy(serializers, {\n set(target, property, value, receiver) {\n const result = Reflect.set(target, property, value, receiver);\n if (typeof property === 'symbol') return result;\n\n const typarray = Number(property);\n if (!Number.isInteger(typarray) || !parsers[typarray]?.array) {\n return result;\n }\n\n const oid = findTypeOidByArrayOid(options.shared.typeArrayMap, typarray);\n if (!oid) return result;\n\n const itemParser = parsers[oid];\n const arrayParser: PostgresJsParser = (input) =>\n parsePostgresArray(input, itemParser, typarray);\n arrayParser.array = true;\n parsers[typarray] = arrayParser;\n\n return result;\n },\n });\n};\n\nconst findTypeOidByArrayOid = (\n typeArrayMap: Record<number, number>,\n typarray: number,\n): number | undefined => {\n for (const oid in typeArrayMap) {\n if (typeArrayMap[oid] === typarray) return Number(oid);\n }\n\n return undefined;\n};\n\ninterface ArrayParserState {\n i: number;\n char: string | null;\n str: string;\n quoted: boolean;\n last: number;\n p?: string | null;\n}\n\nconst parsePostgresArray = (\n input: string,\n parser: PostgresJsParser | undefined,\n typarray: number,\n): unknown[] => {\n return parsePostgresArrayLoop(\n {\n i: 0,\n char: null,\n str: '',\n quoted: false,\n last: 0,\n },\n input,\n parser,\n typarray,\n );\n};\n\nconst parsePostgresArrayLoop = (\n state: ArrayParserState,\n input: string,\n parser: PostgresJsParser | undefined,\n typarray: number,\n): unknown[] => {\n const result: unknown[] = [];\n // Only _box (1020) has the ';' delimiter for arrays, all other types use ','.\n const delimiter = typarray === 1020 ? ';' : ',';\n\n for (; state.i < input.length; state.i++) {\n state.char = input[state.i];\n if (state.quoted) {\n if (state.char === '\\\\') {\n state.str += input[++state.i];\n } else if (state.char === '\"') {\n result.push(parser ? parser(state.str) : state.str);\n state.str = '';\n state.quoted = input[state.i + 1] === '\"';\n state.last = state.i + 2;\n } else {\n state.str += state.char;\n }\n } else if (state.char === '\"') {\n state.quoted = true;\n } else if (state.char === '{') {\n state.last = ++state.i;\n result.push(parsePostgresArrayLoop(state, input, parser, typarray));\n } else if (state.char === '}') {\n state.quoted = false;\n if (state.last < state.i) {\n result.push(parseArrayValue(input.slice(state.last, state.i), parser));\n }\n state.last = state.i + 1;\n break;\n } else if (state.char === delimiter && state.p !== '}' && state.p !== '\"') {\n result.push(parseArrayValue(input.slice(state.last, state.i), parser));\n state.last = state.i + 1;\n }\n\n state.p = state.char;\n }\n\n if (state.last < state.i) {\n result.push(parseArrayValue(input.slice(state.last, state.i + 1), parser));\n }\n\n return result;\n};\n\nconst parseArrayValue = (\n input: string,\n parser: PostgresJsParser | undefined,\n): unknown => {\n return input === 'NULL' ? null : parser ? parser(input) : input;\n};\n","import postgres, { Row, RowList, TransactionSql } from 'postgres';\nimport {\n AdapterConfigBase,\n QueryResult,\n QueryResultRow,\n returnArg,\n DbOptions,\n DefaultColumnTypes,\n DefaultSchemaConfig,\n DbResult,\n ColumnSchemaConfig,\n AdapterClass,\n DriverAdapter,\n QuerySchema,\n noop,\n} from 'pqb/internal';\nimport { createDbWithAdapter } from 'pqb';\nimport { HackySavepointState } from './adapter';\nimport { parseInterval } from './driver-adapter-shared';\nimport { patchPostgresJsArrayParsers } from './postgres-js-array-parser-patch';\n\nexport interface CreatePostgresJsDbOptions<\n SchemaConfig extends ColumnSchemaConfig,\n ColumnTypes,\n>\n extends PostgresJsAdapterOptions, DbOptions<SchemaConfig, ColumnTypes> {}\n\nexport const createDb = <\n SchemaConfig extends ColumnSchemaConfig = DefaultSchemaConfig,\n ColumnTypes = DefaultColumnTypes<SchemaConfig>,\n>(\n options: CreatePostgresJsDbOptions<SchemaConfig, ColumnTypes>,\n): DbResult<ColumnTypes> => {\n return createDbWithAdapter({\n ...options,\n adapter: new AdapterClass({\n driverAdapter: PostgresJsAdapter,\n config: options,\n }),\n });\n};\n\nexport interface PostgresJsAdapterOptions\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n extends postgres.Options<any>, Omit<AdapterConfigBase, 'searchPath' | 'ssl'> {\n databaseURL?: string;\n schema?: QuerySchema;\n}\n\ntype RawResult = RowList<(Row & Iterable<Row>)[]>;\n\nclass PostgresJsResult<T extends QueryResultRow> implements QueryResult<T> {\n rowCount: number;\n rows: T[];\n fields: QueryResult<T>['fields'];\n\n constructor(result: RawResult) {\n this.rowCount = result.count;\n this.rows = result as never;\n this.fields = result.statement?.columns;\n }\n}\n\nclass PostgresJsArraysResult<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n R extends any[],\n> implements QueryResult<R> {\n rowCount: number;\n rows: R[];\n fields: QueryResult['fields'];\n\n constructor(result: RawResult) {\n this.rowCount = result.count;\n this.rows = result as never;\n this.fields = result.statement.columns;\n }\n}\n\nconst types: Record<string, Partial<postgres.PostgresType>> = {\n bytea: {\n to: 17,\n from: 17 as never,\n serialize: (x) => '\\\\x' + Buffer.from(x).toString('hex'),\n parse: (x: string) => Buffer.from(x.slice(2), 'hex'),\n },\n dateAndTimestampAsStrings: {\n to: 25,\n from: [1082, 1114, 1184],\n parse: returnArg,\n },\n interval: {\n from: [1186],\n serialize: returnArg,\n parse: parseInterval,\n },\n json: {\n to: 114,\n from: [114, 3802],\n parse: (x) => {\n return JSON.parse(x);\n },\n },\n};\n\nexport const PostgresJsAdapter: DriverAdapter = {\n manualPool: false,\n\n errorClass: postgres.PostgresError,\n errorFields: {\n message: 'message',\n severity: 'severity',\n code: 'code',\n detail: 'detail',\n schema: 'schema_name',\n table: 'table_name',\n constraint: 'constraint_name',\n hint: 'hint',\n position: 'position',\n where: 'where',\n file: 'file',\n line: 'line',\n routine: 'routine',\n },\n\n configure(params: PostgresJsAdapterOptions): postgres.Sql {\n const config: PostgresJsAdapterOptions = {\n ...params,\n types,\n };\n\n if (config.setConfig?.search_path) {\n config.connection = {\n ...config.connection,\n search_path: config.setConfig.search_path,\n };\n }\n\n let sql;\n if (config.databaseURL) {\n sql = postgres(config.databaseURL, config);\n } else {\n sql = postgres(config);\n }\n\n patchPostgresJsArrayParsers(sql);\n\n return sql;\n },\n\n async queryClient<T = QueryResultRow>(\n client: TransactionSql,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let query = client.unsafe(text, values as never) as any;\n\n if (arraysMode) query = query.values();\n\n const result = await query;\n if (result.constructor === Array) {\n return (result as RawResult[]).map((res) =>\n makePostgresJsResult(res, arraysMode),\n ) as never;\n } else {\n return makePostgresJsResult(\n result as RawResult,\n arraysMode,\n ) as QueryResult<T>;\n }\n },\n\n borrow(client: postgres.Sql): Promise<postgres.ReservedSql> {\n return client.reserve();\n },\n\n release(client: postgres.ReservedSql): void {\n client.release();\n },\n\n begin<DriverClient, Result>(\n client: postgres.Sql,\n cb: (adapter: DriverClient) => Promise<Result>,\n options?: string,\n ): Promise<Result> {\n let ok: boolean | undefined;\n let result: unknown;\n\n const fn = (sql: TransactionSql): Promise<Result> =>\n cb(sql as DriverClient).then((res) => {\n ok = true;\n return (result = res);\n });\n\n return (options ? client.begin(options, fn) : client.begin(fn)).catch(\n (err) => {\n if (ok) return result;\n\n throw err;\n },\n ) as never;\n },\n\n async savepoint<T>(\n client: postgres.TransactionSql,\n setClient: (client: postgres.TransactionSql) => void,\n name: string,\n cb: () => Promise<T>,\n ): Promise<T> {\n let result: T | undefined;\n await client\n .savepoint(name, async (savepointClient) => {\n setClient(savepointClient);\n result = await cb();\n })\n .finally(() => {\n setClient(client);\n });\n return result as T;\n },\n\n async hackySavepoint<T extends QueryResultRow>(\n client: postgres.TransactionSql,\n setClient: (client: postgres.TransactionSql) => void,\n state: HackySavepointState,\n text: string,\n values?: unknown[],\n arraysMode?: boolean,\n ): Promise<QueryResult<T>> {\n let resolve: () => void;\n let reject: (err: unknown) => void;\n const promise = new Promise<void>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n let resultResolve: (res: QueryResult<T>) => void;\n let resultReject: (err: unknown) => void;\n const resultPromise = new Promise<QueryResult<T>>((res, rej) => {\n resultResolve = res;\n resultReject = rej;\n });\n\n const savepointPromise = client\n .savepoint<void>(state.name, async (savepointClient) => {\n try {\n setClient(savepointClient);\n\n const res = await this.queryClient<T>(\n savepointClient,\n text,\n values,\n arraysMode,\n );\n resultResolve(res as QueryResult<T>);\n } catch (err) {\n resultReject(err);\n throw err;\n }\n\n return promise;\n })\n .finally(() => {\n setClient(client);\n });\n\n state.activeSavepoint = {\n async release() {\n resolve();\n await savepointPromise;\n },\n async rollback(err) {\n reject(err);\n await savepointPromise.catch(noop);\n },\n };\n\n return resultPromise;\n },\n\n close(client: postgres.Sql): Promise<void> {\n return client.end();\n },\n};\n\nconst makePostgresJsResult = (\n result: RawResult,\n arraysMode?: boolean,\n): QueryResult => {\n return arraysMode\n ? new PostgresJsArraysResult(result)\n : new PostgresJsResult(result);\n};\n"],"mappings":"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"}
|
package/dist/postgres-js.mjs
CHANGED
|
@@ -17,6 +17,69 @@ const parseInterval = (str) => {
|
|
|
17
17
|
milliseconds: Math.round(timeMultiplier * (secondsFloat - wholeSeconds) * 1e6) / 1e3
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
+
const patchPostgresJsArrayParsers = (sql) => {
|
|
21
|
+
const options = sql.options;
|
|
22
|
+
const { parsers } = options;
|
|
23
|
+
const serializers = options.serializers;
|
|
24
|
+
options.serializers = new Proxy(serializers, { set(target, property, value, receiver) {
|
|
25
|
+
const result = Reflect.set(target, property, value, receiver);
|
|
26
|
+
if (typeof property === "symbol") return result;
|
|
27
|
+
const typarray = Number(property);
|
|
28
|
+
if (!Number.isInteger(typarray) || !parsers[typarray]?.array) return result;
|
|
29
|
+
const oid = findTypeOidByArrayOid(options.shared.typeArrayMap, typarray);
|
|
30
|
+
if (!oid) return result;
|
|
31
|
+
const itemParser = parsers[oid];
|
|
32
|
+
const arrayParser = (input) => parsePostgresArray(input, itemParser, typarray);
|
|
33
|
+
arrayParser.array = true;
|
|
34
|
+
parsers[typarray] = arrayParser;
|
|
35
|
+
return result;
|
|
36
|
+
} });
|
|
37
|
+
};
|
|
38
|
+
const findTypeOidByArrayOid = (typeArrayMap, typarray) => {
|
|
39
|
+
for (const oid in typeArrayMap) if (typeArrayMap[oid] === typarray) return Number(oid);
|
|
40
|
+
};
|
|
41
|
+
const parsePostgresArray = (input, parser, typarray) => {
|
|
42
|
+
return parsePostgresArrayLoop({
|
|
43
|
+
i: 0,
|
|
44
|
+
char: null,
|
|
45
|
+
str: "",
|
|
46
|
+
quoted: false,
|
|
47
|
+
last: 0
|
|
48
|
+
}, input, parser, typarray);
|
|
49
|
+
};
|
|
50
|
+
const parsePostgresArrayLoop = (state, input, parser, typarray) => {
|
|
51
|
+
const result = [];
|
|
52
|
+
const delimiter = typarray === 1020 ? ";" : ",";
|
|
53
|
+
for (; state.i < input.length; state.i++) {
|
|
54
|
+
state.char = input[state.i];
|
|
55
|
+
if (state.quoted) if (state.char === "\\") state.str += input[++state.i];
|
|
56
|
+
else if (state.char === "\"") {
|
|
57
|
+
result.push(parser ? parser(state.str) : state.str);
|
|
58
|
+
state.str = "";
|
|
59
|
+
state.quoted = input[state.i + 1] === "\"";
|
|
60
|
+
state.last = state.i + 2;
|
|
61
|
+
} else state.str += state.char;
|
|
62
|
+
else if (state.char === "\"") state.quoted = true;
|
|
63
|
+
else if (state.char === "{") {
|
|
64
|
+
state.last = ++state.i;
|
|
65
|
+
result.push(parsePostgresArrayLoop(state, input, parser, typarray));
|
|
66
|
+
} else if (state.char === "}") {
|
|
67
|
+
state.quoted = false;
|
|
68
|
+
if (state.last < state.i) result.push(parseArrayValue(input.slice(state.last, state.i), parser));
|
|
69
|
+
state.last = state.i + 1;
|
|
70
|
+
break;
|
|
71
|
+
} else if (state.char === delimiter && state.p !== "}" && state.p !== "\"") {
|
|
72
|
+
result.push(parseArrayValue(input.slice(state.last, state.i), parser));
|
|
73
|
+
state.last = state.i + 1;
|
|
74
|
+
}
|
|
75
|
+
state.p = state.char;
|
|
76
|
+
}
|
|
77
|
+
if (state.last < state.i) result.push(parseArrayValue(input.slice(state.last, state.i + 1), parser));
|
|
78
|
+
return result;
|
|
79
|
+
};
|
|
80
|
+
const parseArrayValue = (input, parser) => {
|
|
81
|
+
return input === "NULL" ? null : parser ? parser(input) : input;
|
|
82
|
+
};
|
|
20
83
|
const createDb = (options) => {
|
|
21
84
|
return createDbWithAdapter({
|
|
22
85
|
...options,
|
|
@@ -99,6 +162,7 @@ const PostgresJsAdapter = {
|
|
|
99
162
|
let sql;
|
|
100
163
|
if (config.databaseURL) sql = postgres(config.databaseURL, config);
|
|
101
164
|
else sql = postgres(config);
|
|
165
|
+
patchPostgresJsArrayParsers(sql);
|
|
102
166
|
return sql;
|
|
103
167
|
},
|
|
104
168
|
async queryClient(client, text, values, arraysMode) {
|