pqb 0.68.1 → 0.70.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.
@@ -37,19 +37,13 @@ const createDb = ({ log, ...options }) => {
37
37
  });
38
38
  };
39
39
  const { types } = pg.default;
40
- const defaultTypeParsers = {};
41
- for (const key in types.builtins) {
42
- const id = types.builtins[key];
43
- defaultTypeParsers[id] = types.getTypeParser(id);
44
- }
45
- [
46
- types.builtins.DATE,
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] || pqb_internal.returnArg;
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":"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"}
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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"}
@@ -15,19 +15,13 @@ const createDb = ({ log, ...options }) => {
15
15
  });
16
16
  };
17
17
  const { types } = pg;
18
- const defaultTypeParsers = {};
19
- for (const key in types.builtins) {
20
- const id = types.builtins[key];
21
- defaultTypeParsers[id] = types.getTypeParser(id);
22
- }
23
- [
24
- types.builtins.DATE,
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] || returnArg;
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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"}
@@ -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) {
@@ -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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"}
@@ -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) {
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-js.mjs","names":[],"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.mjs","names":[],"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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pqb",
3
- "version": "0.68.1",
3
+ "version": "0.70.0",
4
4
  "description": "Postgres query builder",
5
5
  "keywords": [
6
6
  "pg",