'use strict'; var pglite = require('@electric-sql/pglite'); var driverAdapterUtils = require('@prisma/driver-adapter-utils'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var pglite__namespace = /*#__PURE__*/_interopNamespaceDefault(pglite); var name = "pglite-prisma-adapter"; const ScalarColumnType = pglite.types; const ArrayColumnType = { BYTEA: 1001, CHAR: 1002, INT8: 1016, INT2: 1005, INT4: 1007, TEXT: 1009, OID: 1028, JSON: 199, FLOAT4: 1021, FLOAT8: 1022, VARCHAR: 1015, JSONB: 3807, DATE: 1182, TIMESTAMP: 1115, TIMESTAMPTZ: 1116 }; class UnsupportedNativeDataType extends Error { // map of type codes to type names static typeNames = { 16: "bool", 17: "bytea", 18: "char", 19: "name", 20: "int8", 21: "int2", 22: "int2vector", 23: "int4", 24: "regproc", 25: "text", 26: "oid", 27: "tid", 28: "xid", 29: "cid", 30: "oidvector", 32: "pg_ddl_command", 71: "pg_type", 75: "pg_attribute", 81: "pg_proc", 83: "pg_class", 114: "json", 142: "xml", 194: "pg_node_tree", 269: "table_am_handler", 325: "index_am_handler", 600: "point", 601: "lseg", 602: "path", 603: "box", 604: "polygon", 628: "line", 650: "cidr", 700: "float4", 701: "float8", 705: "unknown", 718: "circle", 774: "macaddr8", 790: "money", 829: "macaddr", 869: "inet", 1033: "aclitem", 1042: "bpchar", 1043: "varchar", 1082: "date", 1083: "time", 1114: "timestamp", 1184: "timestamptz", 1186: "interval", 1266: "timetz", 1560: "bit", 1562: "varbit", 1700: "numeric", 1790: "refcursor", 2202: "regprocedure", 2203: "regoper", 2204: "regoperator", 2205: "regclass", 2206: "regtype", 2249: "record", 2275: "cstring", 2276: "any", 2277: "anyarray", 2278: "void", 2279: "trigger", 2280: "language_handler", 2281: "internal", 2283: "anyelement", 2287: "_record", 2776: "anynonarray", 2950: "uuid", 2970: "txid_snapshot", 3115: "fdw_handler", 3220: "pg_lsn", 3310: "tsm_handler", 3361: "pg_ndistinct", 3402: "pg_dependencies", 3500: "anyenum", 3614: "tsvector", 3615: "tsquery", 3642: "gtsvector", 3734: "regconfig", 3769: "regdictionary", 3802: "jsonb", 3831: "anyrange", 3838: "event_trigger", 3904: "int4range", 3906: "numrange", 3908: "tsrange", 3910: "tstzrange", 3912: "daterange", 3926: "int8range", 4072: "jsonpath", 4089: "regnamespace", 4096: "regrole", 4191: "regcollation", 4451: "int4multirange", 4532: "nummultirange", 4533: "tsmultirange", 4534: "tstzmultirange", 4535: "datemultirange", 4536: "int8multirange", 4537: "anymultirange", 4538: "anycompatiblemultirange", 4600: "pg_brin_bloom_summary", 4601: "pg_brin_minmax_multi_summary", 5017: "pg_mcv_list", 5038: "pg_snapshot", 5069: "xid8", 5077: "anycompatible", 5078: "anycompatiblearray", 5079: "anycompatiblenonarray", 5080: "anycompatiblerange" }; type; constructor(code) { super(); this.type = UnsupportedNativeDataType.typeNames[code] || "Unknown"; this.message = `Unsupported column type ${this.type}`; } } function fieldToColumnType(fieldTypeId) { switch (fieldTypeId) { case ScalarColumnType.INT2: case ScalarColumnType.INT4: return driverAdapterUtils.ColumnTypeEnum.Int32; case ScalarColumnType.INT8: return driverAdapterUtils.ColumnTypeEnum.Int64; case ScalarColumnType.FLOAT4: return driverAdapterUtils.ColumnTypeEnum.Float; case ScalarColumnType.FLOAT8: return driverAdapterUtils.ColumnTypeEnum.Double; case ScalarColumnType.BOOL: return driverAdapterUtils.ColumnTypeEnum.Boolean; case ScalarColumnType.DATE: return driverAdapterUtils.ColumnTypeEnum.Date; case ScalarColumnType.TIME: case ScalarColumnType.TIMETZ: return driverAdapterUtils.ColumnTypeEnum.Time; case ScalarColumnType.TIMESTAMP: case ScalarColumnType.TIMESTAMPTZ: return driverAdapterUtils.ColumnTypeEnum.DateTime; case ScalarColumnType.NUMERIC: case ScalarColumnType.MONEY: return driverAdapterUtils.ColumnTypeEnum.Numeric; case ScalarColumnType.JSON: case ScalarColumnType.JSONB: return driverAdapterUtils.ColumnTypeEnum.Json; case ScalarColumnType.UUID: return driverAdapterUtils.ColumnTypeEnum.Uuid; case ScalarColumnType.OID: return driverAdapterUtils.ColumnTypeEnum.Int64; case ScalarColumnType.BPCHAR: case ScalarColumnType.TEXT: case ScalarColumnType.VARCHAR: case ScalarColumnType.BIT: case ScalarColumnType.VARBIT: case ScalarColumnType.INET: case ScalarColumnType.CIDR: case ScalarColumnType.XML: return driverAdapterUtils.ColumnTypeEnum.Text; case ScalarColumnType.BYTEA: return driverAdapterUtils.ColumnTypeEnum.Bytes; case ArrayColumnType.INT2: case ArrayColumnType.INT4: return driverAdapterUtils.ColumnTypeEnum.Int32Array; case ArrayColumnType.FLOAT4: return driverAdapterUtils.ColumnTypeEnum.FloatArray; case ArrayColumnType.FLOAT8: return driverAdapterUtils.ColumnTypeEnum.DoubleArray; case ArrayColumnType.CHAR: return driverAdapterUtils.ColumnTypeEnum.CharacterArray; case ArrayColumnType.TEXT: case ArrayColumnType.VARCHAR: return driverAdapterUtils.ColumnTypeEnum.TextArray; case ArrayColumnType.DATE: return driverAdapterUtils.ColumnTypeEnum.DateArray; case ArrayColumnType.TIMESTAMP: case ArrayColumnType.TIMESTAMPTZ: return driverAdapterUtils.ColumnTypeEnum.DateTimeArray; case ArrayColumnType.JSON: case ArrayColumnType.JSONB: return driverAdapterUtils.ColumnTypeEnum.JsonArray; case ArrayColumnType.BYTEA: return driverAdapterUtils.ColumnTypeEnum.BytesArray; case ArrayColumnType.OID: case ArrayColumnType.INT8: return driverAdapterUtils.ColumnTypeEnum.Int64Array; default: if (fieldTypeId >= 1e4) { return driverAdapterUtils.ColumnTypeEnum.Text; } throw new UnsupportedNativeDataType(fieldTypeId); } } function normalize_array(element_normalizer) { return (str) => pglite.types.parseArray(str, element_normalizer); } function normalize_numeric(numeric) { return numeric; } function normalize_date(date) { return date; } function normalize_timestamp(time) { return time; } function normalize_timestampz(time) { return time.split("+")[0]; } function normalize_time(time) { return time; } function normalize_timez(time) { return time.split("+")[0]; } function normalize_money(money) { return money.slice(1); } function toJson(json) { return json; } function encodeBuffer(buffer) { return Array.from(new Uint8Array(buffer)); } const parsePgBytes = (x) => Buffer.from(x.slice(2), "hex"); function convertBytes(serializedBytes) { const buffer = parsePgBytes(serializedBytes); return encodeBuffer(buffer); } const customParsers = { [ScalarColumnType.NUMERIC]: normalize_numeric, [ScalarColumnType.TIME]: normalize_time, [ScalarColumnType.TIMETZ]: normalize_timez, [ScalarColumnType.DATE]: normalize_date, [ArrayColumnType.DATE]: normalize_array(normalize_date), [ScalarColumnType.TIMESTAMP]: normalize_timestamp, [ArrayColumnType.TIMESTAMP]: normalize_array(normalize_timestamp), [ScalarColumnType.TIMESTAMPTZ]: normalize_timestampz, [ArrayColumnType.TIMESTAMPTZ]: normalize_array(normalize_timestampz), [ScalarColumnType.MONEY]: normalize_money, [ScalarColumnType.JSON]: toJson, [ScalarColumnType.JSONB]: toJson, [ScalarColumnType.BYTEA]: convertBytes, [ArrayColumnType.BYTEA]: normalize_array(convertBytes) }; function fixArrayBufferValues(values) { for (let i = 0; i < values.length; i++) { const list = values[i]; if (!Array.isArray(list)) { continue; } for (let j = 0; j < list.length; j++) { const listItem = list[j]; if (ArrayBuffer.isView(listItem)) { list[j] = Buffer.from( listItem.buffer, listItem.byteOffset, listItem.byteLength ); } } } return values; } function createDeferred() { const deferred = {}; return [ deferred, new Promise((resolve, reject) => { deferred.resolve = resolve; deferred.reject = reject; }) ]; } const debug = driverAdapterUtils.Debug("prisma:driver-adapter:pglite"); class PGliteQueryable { constructor(client) { this.client = client; } provider = "postgres"; adapterName = name; async queryRaw(query) { const tag = "[js::query_raw]"; debug(`${tag} %O`, query); const res = await this.performIO(query); if (!res.ok) { return driverAdapterUtils.err(res.error); } const { fields, rows } = res.value; const columnNames = fields.map((field) => field.name); let columnTypes = []; try { columnTypes = fields.map((field) => fieldToColumnType(field.dataTypeID)); } catch (e) { if (e instanceof UnsupportedNativeDataType) { return driverAdapterUtils.err({ kind: "UnsupportedNativeDataType", type: e.type }); } throw e; } return driverAdapterUtils.ok({ columnNames, columnTypes, rows }); } async executeRaw(query) { const tag = "[js::execute_raw]"; debug(`${tag} %O`, query); return (await this.performIO(query)).map( ({ affectedRows }) => affectedRows ?? 0 ); } async performIO(query) { const { sql, args: values } = query; try { const result = await this.client.query( sql, fixArrayBufferValues(values), { rowMode: "array", parsers: customParsers } ); return driverAdapterUtils.ok(result); } catch (e) { const error = e; debug("Error in performIO: %O", error); if (typeof e === "object" && typeof e.code === "string" && typeof e.severity === "string" && typeof e.message === "string") { return driverAdapterUtils.err({ kind: "Postgres", code: e.code, severity: e.severity, message: e.message, detail: e.detail, column: e.column, hint: e.hint }); } throw error; } } } class PGliteTransaction extends PGliteQueryable { constructor(client, options, txDeferred, txResultPromise) { super(client); this.options = options; this.txDeferred = txDeferred; this.txResultPromise = txResultPromise; } async commit() { debug("[js::commit]"); this.txDeferred.resolve(); return driverAdapterUtils.ok(await this.txResultPromise); } async rollback() { debug("[js::rollback]"); this.client.rollback(); this.txDeferred.resolve(); return driverAdapterUtils.ok(await this.txResultPromise); } } class PGliteTransactionContext extends PGliteQueryable { constructor(conn) { super(conn); this.conn = conn; } async startTransaction() { const options = { usePhantomQuery: true }; const tag = "[js::startTransaction]"; debug("%s options: %O", tag, options); return new Promise((resolve, reject) => { const txResultPromise = this.conn.transaction(async (tx) => { const [txDeferred, deferredPromise] = createDeferred(); const txWrapper = new PGliteTransaction( tx, options, txDeferred, txResultPromise ); resolve(driverAdapterUtils.ok(txWrapper)); return deferredPromise; }).catch((error) => { return reject(error); }); }); } } class PrismaPGlite extends PGliteQueryable { constructor(client, options) { if (!(client instanceof pglite__namespace.PGlite)) { throw new TypeError( "PrismaPGlite must be initialized with an instance of PGlite" ); } super(client); this.options = options; } getConnectionInfo() { return driverAdapterUtils.ok({ schemaName: this.options?.schema }); } async transactionContext() { await this.client.waitReady; return driverAdapterUtils.ok(new PGliteTransactionContext(this.client)); } } exports.PrismaPGlite = PrismaPGlite;