@restura/core 0.1.0-alpha.14 → 0.1.0-alpha.16

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.mjs CHANGED
@@ -748,7 +748,7 @@ var joinDataSchema = z3.object({
748
748
  var requestDataSchema = z3.object({
749
749
  name: z3.string(),
750
750
  required: z3.boolean(),
751
- isNullable: z3.boolean().optional().default(false),
751
+ isNullable: z3.boolean().optional(),
752
752
  validator: z3.array(validatorDataSchema)
753
753
  }).strict();
754
754
  var responseDataSchema = z3.object({
@@ -834,6 +834,12 @@ var postgresColumnDateTypesSchema = z3.enum([
834
834
  "INTERVAL"
835
835
  // time span
836
836
  ]);
837
+ var postgresColumnJsonTypesSchema = z3.enum([
838
+ "JSON",
839
+ // stores JSON data as raw text
840
+ "JSONB"
841
+ // stores JSON data in a binary format, optimized for query performance
842
+ ]);
837
843
  var mariaDbColumnNumericTypesSchema = z3.enum([
838
844
  "BOOLEAN",
839
845
  // 1-byte A synonym for "TINYINT(1)". Supported from version 1.2.0 onwards.
@@ -896,6 +902,7 @@ var columnDataSchema = z3.object({
896
902
  postgresColumnNumericTypesSchema,
897
903
  postgresColumnStringTypesSchema,
898
904
  postgresColumnDateTypesSchema,
905
+ postgresColumnJsonTypesSchema,
899
906
  mariaDbColumnNumericTypesSchema,
900
907
  mariaDbColumnStringTypesSchema,
901
908
  mariaDbColumnDateTypesSchema
@@ -1203,10 +1210,16 @@ function convertTable(table) {
1203
1210
 
1204
1211
  // src/restura/sql/PsqlEngine.ts
1205
1212
  import { ObjectUtils as ObjectUtils4 } from "@redskytech/core-utils";
1213
+ import getDiff from "@wmfs/pg-diff-sync";
1214
+ import pgInfo from "@wmfs/pg-info";
1215
+ import pg2 from "pg";
1206
1216
 
1207
1217
  // src/restura/sql/PsqlPool.ts
1208
1218
  import pg from "pg";
1209
1219
 
1220
+ // src/restura/sql/PsqlConnection.ts
1221
+ import format3 from "pg-format";
1222
+
1210
1223
  // src/restura/sql/PsqlUtils.ts
1211
1224
  import format2 from "pg-format";
1212
1225
  function escapeColumnName(columnName) {
@@ -1222,7 +1235,8 @@ function insertObjectQuery(table, obj) {
1222
1235
  const params = Object.values(obj);
1223
1236
  const columns = keys.map((column) => escapeColumnName(column)).join(", ");
1224
1237
  const values = params.map((value) => SQL`${value}`).join(", ");
1225
- const query = `INSERT INTO "${table}" (${columns})
1238
+ const query = `
1239
+ INSERT INTO "${table}" (${columns})
1226
1240
  VALUES (${values})
1227
1241
  RETURNING *`;
1228
1242
  return query;
@@ -1232,7 +1246,8 @@ function updateObjectQuery(table, obj, whereStatement) {
1232
1246
  for (const i in obj) {
1233
1247
  setArray.push(`${escapeColumnName(i)} = ` + SQL`${obj[i]}`);
1234
1248
  }
1235
- return `UPDATE ${escapeColumnName(table)}
1249
+ return `
1250
+ UPDATE ${escapeColumnName(table)}
1236
1251
  SET ${setArray.join(", ")} ${whereStatement}
1237
1252
  RETURNING *`;
1238
1253
  }
@@ -1255,7 +1270,6 @@ function SQL(strings, ...values) {
1255
1270
  }
1256
1271
 
1257
1272
  // src/restura/sql/PsqlConnection.ts
1258
- import format3 from "pg-format";
1259
1273
  var PsqlConnection = class {
1260
1274
  constructor() {
1261
1275
  }
@@ -1263,8 +1277,10 @@ var PsqlConnection = class {
1263
1277
  async queryOne(query, options, requesterDetails) {
1264
1278
  const formattedQuery = questionMarksToOrderedParams(query);
1265
1279
  this.logSqlStatement(formattedQuery, options, requesterDetails);
1280
+ const queryMetadata = `--QUERY_METADATA(${JSON.stringify(requesterDetails)})
1281
+ `;
1266
1282
  try {
1267
- const response = await this.query(formattedQuery, options);
1283
+ const response = await this.query(queryMetadata + formattedQuery, options);
1268
1284
  if (response.rows.length === 0) throw new RsError("NOT_FOUND", "No results found");
1269
1285
  else if (response.rows.length > 1) throw new RsError("DUPLICATE", "More than one result found");
1270
1286
  return response.rows[0];
@@ -1281,8 +1297,10 @@ var PsqlConnection = class {
1281
1297
  async runQuery(query, options, requesterDetails) {
1282
1298
  const formattedQuery = questionMarksToOrderedParams(query);
1283
1299
  this.logSqlStatement(formattedQuery, options, requesterDetails);
1300
+ const queryMetadata = `--QUERY_METADATA(${JSON.stringify(requesterDetails)})
1301
+ `;
1284
1302
  try {
1285
- const response = await this.query(formattedQuery, options);
1303
+ const response = await this.query(queryMetadata + formattedQuery, options);
1286
1304
  return response.rows;
1287
1305
  } catch (error) {
1288
1306
  console.error(error, query, options);
@@ -1533,10 +1551,112 @@ var filterPsqlParser = peg.generate(filterSqlGrammar, {
1533
1551
  });
1534
1552
  var filterPsqlParser_default = filterPsqlParser;
1535
1553
 
1554
+ // src/restura/eventManager.ts
1555
+ import Bluebird from "bluebird";
1556
+ var EventManager = class {
1557
+ constructor() {
1558
+ this.actionHandlers = {
1559
+ DATABASE_ROW_DELETE: [],
1560
+ DATABASE_ROW_INSERT: [],
1561
+ DATABASE_COLUMN_UPDATE: []
1562
+ };
1563
+ }
1564
+ addRowInsertHandler(onInsert, filter) {
1565
+ this.actionHandlers.DATABASE_ROW_INSERT.push({
1566
+ callback: onInsert,
1567
+ filter
1568
+ });
1569
+ }
1570
+ addColumnChangeHandler(onUpdate, filter) {
1571
+ this.actionHandlers.DATABASE_COLUMN_UPDATE.push({
1572
+ callback: onUpdate,
1573
+ filter
1574
+ });
1575
+ }
1576
+ addRowDeleteHandler(onDelete, filter) {
1577
+ this.actionHandlers.DATABASE_ROW_DELETE.push({
1578
+ callback: onDelete,
1579
+ filter
1580
+ });
1581
+ }
1582
+ async fireActionFromDbTrigger(sqlMutationData, result) {
1583
+ if (sqlMutationData.mutationType === "INSERT") {
1584
+ await this.fireInsertActions(sqlMutationData, result);
1585
+ } else if (sqlMutationData.mutationType === "UPDATE") {
1586
+ await this.fireUpdateActions(sqlMutationData, result);
1587
+ } else if (sqlMutationData.mutationType === "DELETE") {
1588
+ await this.fireDeleteActions(sqlMutationData, result);
1589
+ }
1590
+ }
1591
+ async fireInsertActions(data, triggerResult) {
1592
+ await Bluebird.map(
1593
+ this.actionHandlers.DATABASE_ROW_INSERT,
1594
+ ({ callback, filter }) => {
1595
+ if (!this.hasHandlersForEventType("DATABASE_ROW_INSERT", filter, triggerResult)) return;
1596
+ const insertData = {
1597
+ tableName: triggerResult.table,
1598
+ insertId: triggerResult.record.id,
1599
+ insertObject: triggerResult.record,
1600
+ requesterDetails: data.requesterDetails
1601
+ };
1602
+ callback(insertData, data.requesterDetails);
1603
+ },
1604
+ { concurrency: 10 }
1605
+ );
1606
+ }
1607
+ async fireDeleteActions(data, triggerResult) {
1608
+ await Bluebird.map(
1609
+ this.actionHandlers.DATABASE_ROW_DELETE,
1610
+ ({ callback, filter }) => {
1611
+ if (!this.hasHandlersForEventType("DATABASE_ROW_DELETE", filter, triggerResult)) return;
1612
+ const deleteData = {
1613
+ tableName: triggerResult.table,
1614
+ deletedRow: triggerResult.previousRecord,
1615
+ requesterDetails: data.requesterDetails
1616
+ };
1617
+ callback(deleteData, data.requesterDetails);
1618
+ },
1619
+ { concurrency: 10 }
1620
+ );
1621
+ }
1622
+ async fireUpdateActions(data, triggerResult) {
1623
+ await Bluebird.map(
1624
+ this.actionHandlers.DATABASE_COLUMN_UPDATE,
1625
+ ({ callback, filter }) => {
1626
+ if (!this.hasHandlersForEventType("DATABASE_COLUMN_UPDATE", filter, triggerResult)) return;
1627
+ const columnChangeData = {
1628
+ tableName: triggerResult.table,
1629
+ rowId: triggerResult.record.id,
1630
+ newData: triggerResult.record,
1631
+ oldData: triggerResult.previousRecord,
1632
+ requesterDetails: data.requesterDetails
1633
+ };
1634
+ callback(columnChangeData, data.requesterDetails);
1635
+ },
1636
+ { concurrency: 10 }
1637
+ );
1638
+ }
1639
+ hasHandlersForEventType(eventType, filter, triggerResult) {
1640
+ if (filter) {
1641
+ switch (eventType) {
1642
+ case "DATABASE_ROW_INSERT":
1643
+ case "DATABASE_ROW_DELETE":
1644
+ if (filter.tableName && filter.tableName !== triggerResult.table) return false;
1645
+ break;
1646
+ case "DATABASE_COLUMN_UPDATE":
1647
+ const filterColumnChange = filter;
1648
+ if (filterColumnChange.tableName !== filter.tableName) return false;
1649
+ break;
1650
+ }
1651
+ }
1652
+ return true;
1653
+ }
1654
+ };
1655
+ var eventManager = new EventManager();
1656
+ var eventManager_default = eventManager;
1657
+
1536
1658
  // src/restura/sql/PsqlEngine.ts
1537
- import getDiff from "@wmfs/pg-diff-sync";
1538
- import pgInfo from "@wmfs/pg-info";
1539
- var { Client } = "pg";
1659
+ var { Client } = pg2;
1540
1660
  var systemUser = {
1541
1661
  role: "",
1542
1662
  host: "",
@@ -1544,9 +1664,49 @@ var systemUser = {
1544
1664
  isSystemUser: true
1545
1665
  };
1546
1666
  var PsqlEngine = class extends SqlEngine {
1547
- constructor(psqlConnectionPool) {
1667
+ constructor(psqlConnectionPool, shouldListenForDbTriggers = false) {
1548
1668
  super();
1549
1669
  this.psqlConnectionPool = psqlConnectionPool;
1670
+ if (shouldListenForDbTriggers) {
1671
+ this.setupTriggerListeners = this.listenForDbTriggers();
1672
+ }
1673
+ }
1674
+ async close() {
1675
+ if (this.triggerClient) {
1676
+ await this.triggerClient.end();
1677
+ }
1678
+ }
1679
+ async listenForDbTriggers() {
1680
+ this.triggerClient = new Client({
1681
+ user: this.psqlConnectionPool.poolConfig.user,
1682
+ host: this.psqlConnectionPool.poolConfig.host,
1683
+ database: this.psqlConnectionPool.poolConfig.database,
1684
+ password: this.psqlConnectionPool.poolConfig.password,
1685
+ port: this.psqlConnectionPool.poolConfig.port,
1686
+ connectionTimeoutMillis: 2e3
1687
+ });
1688
+ await this.triggerClient.connect();
1689
+ const promises = [];
1690
+ promises.push(this.triggerClient.query("LISTEN insert"));
1691
+ promises.push(this.triggerClient.query("LISTEN update"));
1692
+ promises.push(this.triggerClient.query("LISTEN delete"));
1693
+ await Promise.all(promises);
1694
+ this.triggerClient.on("notification", async (msg) => {
1695
+ if (msg.channel === "insert" || msg.channel === "update" || msg.channel === "delete") {
1696
+ const payload = JSON.parse(msg.payload);
1697
+ await this.handleTrigger(payload, msg.channel.toUpperCase());
1698
+ }
1699
+ });
1700
+ }
1701
+ async handleTrigger(payload, mutationType) {
1702
+ const findRequesterDetailsRegex = /^--QUERY_METADATA\(\{.*\}\)/;
1703
+ let requesterDetails = {};
1704
+ const match = payload.query.match(findRequesterDetailsRegex);
1705
+ if (match) {
1706
+ const jsonString = match[0].slice(match[0].indexOf("{"), match[0].lastIndexOf("}") + 1);
1707
+ requesterDetails = ObjectUtils4.safeParse(jsonString);
1708
+ await eventManager_default.fireActionFromDbTrigger({ requesterDetails, mutationType }, payload);
1709
+ }
1550
1710
  }
1551
1711
  async createDatabaseFromSchema(schema, connection) {
1552
1712
  const sqlFullStatement = this.generateDatabaseSchemaFromSchema(schema);
@@ -1557,7 +1717,11 @@ var PsqlEngine = class extends SqlEngine {
1557
1717
  const sqlStatements = [];
1558
1718
  const enums = [];
1559
1719
  const indexes = [];
1720
+ const triggers = [];
1560
1721
  for (const table of schema.database) {
1722
+ triggers.push(this.createInsertTriggers(table.name));
1723
+ triggers.push(this.createUpdateTrigger(table.name));
1724
+ triggers.push(this.createDeleteTrigger(table.name));
1561
1725
  let sql = `CREATE TABLE "${table.name}"
1562
1726
  ( `;
1563
1727
  const tableColumns = [];
@@ -1584,7 +1748,7 @@ var PsqlEngine = class extends SqlEngine {
1584
1748
  }
1585
1749
  if (column.isNullable) columnSql += " NULL";
1586
1750
  else columnSql += " NOT NULL";
1587
- if (column.default) columnSql += ` DEFAULT '${column.default}'`;
1751
+ if (column.default) columnSql += ` DEFAULT ${column.default}`;
1588
1752
  tableColumns.push(columnSql);
1589
1753
  }
1590
1754
  sql += tableColumns.join(", \n");
@@ -1595,7 +1759,7 @@ var PsqlEngine = class extends SqlEngine {
1595
1759
  indexes.push(
1596
1760
  ` CREATE ${unique}INDEX "${index.name}" ON "${table.name}" (${index.columns.map((item) => {
1597
1761
  return `"${item}" ${index.order}`;
1598
- }).join(", ")})`
1762
+ }).join(", ")});`
1599
1763
  );
1600
1764
  }
1601
1765
  }
@@ -1625,7 +1789,8 @@ var PsqlEngine = class extends SqlEngine {
1625
1789
  }
1626
1790
  sqlStatements.push(sql + constraints.join(",\n") + ";");
1627
1791
  }
1628
- sqlStatements.push(indexes.join(";\n"));
1792
+ sqlStatements.push(indexes.join("\n"));
1793
+ sqlStatements.push(triggers.join("\n"));
1629
1794
  return enums.join("\n") + "\n" + sqlStatements.join("\n\n");
1630
1795
  }
1631
1796
  async getScratchPool() {
@@ -1671,12 +1836,10 @@ var PsqlEngine = class extends SqlEngine {
1671
1836
  await originalClient.connect();
1672
1837
  await scratchClient.connect();
1673
1838
  const info1 = await pgInfo({
1674
- client: originalClient,
1675
- schema: "public"
1839
+ client: originalClient
1676
1840
  });
1677
1841
  const info2 = await pgInfo({
1678
- client: scratchClient,
1679
- schema: "public"
1842
+ client: scratchClient
1680
1843
  });
1681
1844
  const diff = getDiff(info1, info2);
1682
1845
  await originalClient.end();
@@ -1695,8 +1858,7 @@ var PsqlEngine = class extends SqlEngine {
1695
1858
  )) {
1696
1859
  return "'[]'";
1697
1860
  }
1698
- return `COALESCE((
1699
- SELECT JSON_AGG(JSON_BUILD_OBJECT(
1861
+ return `COALESCE((SELECT JSON_AGG(JSON_BUILD_OBJECT(
1700
1862
  ${item.subquery.properties.map((nestedItem) => {
1701
1863
  if (!this.doesRoleHavePermissionToColumn(req.requesterDetails.role, schema, nestedItem, [
1702
1864
  ...routeData.joins,
@@ -1705,7 +1867,7 @@ var PsqlEngine = class extends SqlEngine {
1705
1867
  return;
1706
1868
  }
1707
1869
  if (nestedItem.subquery) {
1708
- return `"${nestedItem.name}", ${this.createNestedSelect(
1870
+ return `'${nestedItem.name}', ${this.createNestedSelect(
1709
1871
  // recursion
1710
1872
  req,
1711
1873
  schema,
@@ -1716,7 +1878,7 @@ var PsqlEngine = class extends SqlEngine {
1716
1878
  )}`;
1717
1879
  }
1718
1880
  return `'${nestedItem.name}', ${escapeColumnName(nestedItem.selector)}`;
1719
- }).filter(Boolean).join(",")}
1881
+ }).filter(Boolean).join(", ")}
1720
1882
  ))
1721
1883
  FROM
1722
1884
  "${item.subquery.table}"
@@ -1844,10 +2006,12 @@ var PsqlEngine = class extends SqlEngine {
1844
2006
  req.requesterDetails.role,
1845
2007
  sqlParams
1846
2008
  );
1847
- let deleteStatement = `DELETE
1848
- FROM "${routeData.table}" ${joinStatement}`;
1849
- deleteStatement += this.generateWhereClause(req, routeData.where, routeData, sqlParams);
1850
- deleteStatement += ";";
2009
+ const whereClause = this.generateWhereClause(req, routeData.where, routeData, sqlParams);
2010
+ if (whereClause.replace(/\s/g, "") === "") {
2011
+ throw new RsError("DELETE_FORBIDDEN", "Deletes need a where clause");
2012
+ }
2013
+ const deleteStatement = `
2014
+ DELETE FROM "${routeData.table}" ${joinStatement} ${whereClause}`;
1851
2015
  await this.psqlConnectionPool.runQuery(deleteStatement, sqlParams, req.requesterDetails);
1852
2016
  return true;
1853
2017
  }
@@ -1910,17 +2074,17 @@ var PsqlEngine = class extends SqlEngine {
1910
2074
  );
1911
2075
  let operator = item.operator;
1912
2076
  if (operator === "LIKE") {
1913
- sqlParams[sqlParams.length - 1] = `%${sqlParams[sqlParams.length - 1]}%`;
2077
+ item.value = `%${item.value}%`;
1914
2078
  } else if (operator === "STARTS WITH") {
1915
2079
  operator = "LIKE";
1916
- sqlParams[sqlParams.length - 1] = `${sqlParams[sqlParams.length - 1]}%`;
2080
+ item.value = `${item.value}%`;
1917
2081
  } else if (operator === "ENDS WITH") {
1918
2082
  operator = "LIKE";
1919
- sqlParams[sqlParams.length - 1] = `%${sqlParams[sqlParams.length - 1]}`;
2083
+ item.value = `%${item.value}`;
1920
2084
  }
1921
2085
  const replacedValue = this.replaceParamKeywords(item.value, routeData, req, sqlParams);
1922
2086
  const escapedValue = SQL`${replacedValue}`;
1923
- whereClause += ` ${item.conjunction || ""} "${item.tableName}"."${item.columnName}" ${operator} ${["IN", "NOT IN"].includes(operator) ? `(${escapedValue})` : escapedValue}
2087
+ whereClause += ` ${item.conjunction || ""} "${item.tableName}"."${item.columnName}" ${operator.replace("LIKE", "ILIKE")} ${["IN", "NOT IN"].includes(operator) ? `(${escapedValue})` : escapedValue}
1924
2088
  `;
1925
2089
  });
1926
2090
  const data = req.data;
@@ -1954,63 +2118,94 @@ var PsqlEngine = class extends SqlEngine {
1954
2118
  }
1955
2119
  return whereClause;
1956
2120
  }
2121
+ createUpdateTrigger(tableName) {
2122
+ return `
2123
+ CREATE OR REPLACE FUNCTION notify_${tableName}_update()
2124
+ RETURNS TRIGGER AS $$
2125
+ BEGIN
2126
+ PERFORM pg_notify('update', JSON_BUILD_OBJECT('table', '${tableName}', 'query', current_query(), 'record', NEW, 'previousRecord', OLD)::text);
2127
+ RETURN NEW;
2128
+ END;
2129
+ $$ LANGUAGE plpgsql;
2130
+
2131
+ CREATE OR REPLACE TRIGGER ${tableName}_update
2132
+ AFTER UPDATE ON "${tableName}"
2133
+ FOR EACH ROW
2134
+ EXECUTE FUNCTION notify_${tableName}_update();
2135
+ `;
2136
+ }
2137
+ createDeleteTrigger(tableName) {
2138
+ return `
2139
+ CREATE OR REPLACE FUNCTION notify_${tableName}_delete()
2140
+ RETURNS TRIGGER AS $$
2141
+ BEGIN
2142
+ PERFORM pg_notify('delete', JSON_BUILD_OBJECT('table', '${tableName}', 'query', current_query(), 'record', NEW, 'previousRecord', OLD)::text);
2143
+ RETURN NEW;
2144
+ END;
2145
+ $$ LANGUAGE plpgsql;
2146
+
2147
+ CREATE OR REPLACE TRIGGER "${tableName}_delete"
2148
+ AFTER DELETE ON "${tableName}"
2149
+ FOR EACH ROW
2150
+ EXECUTE FUNCTION notify_${tableName}_delete();
2151
+ `;
2152
+ }
2153
+ createInsertTriggers(tableName) {
2154
+ return `
2155
+ CREATE OR REPLACE FUNCTION notify_${tableName}_insert()
2156
+ RETURNS TRIGGER AS $$
2157
+ BEGIN
2158
+ PERFORM pg_notify('insert', JSON_BUILD_OBJECT('table', '${tableName}', 'query', current_query(), 'record', NEW, 'previousRecord', OLD)::text);
2159
+ RETURN NEW;
2160
+ END;
2161
+ $$ LANGUAGE plpgsql;
2162
+
2163
+ CREATE TRIGGER "${tableName}_insert"
2164
+ AFTER INSERT ON "${tableName}"
2165
+ FOR EACH ROW
2166
+ EXECUTE FUNCTION notify_${tableName}_insert();
2167
+ `;
2168
+ }
1957
2169
  };
1958
- var schemaToPsqlType = (column, tableName) => {
2170
+ __decorateClass([
2171
+ boundMethod
2172
+ ], PsqlEngine.prototype, "handleTrigger", 1);
2173
+ __decorateClass([
2174
+ boundMethod
2175
+ ], PsqlEngine.prototype, "createUpdateTrigger", 1);
2176
+ __decorateClass([
2177
+ boundMethod
2178
+ ], PsqlEngine.prototype, "createDeleteTrigger", 1);
2179
+ __decorateClass([
2180
+ boundMethod
2181
+ ], PsqlEngine.prototype, "createInsertTriggers", 1);
2182
+ function schemaToPsqlType(column, tableName) {
1959
2183
  if (column.hasAutoIncrement) return "BIGSERIAL";
1960
2184
  if (column.type === "ENUM") return `"${tableName}_${column.name}_enum"`;
1961
2185
  if (column.type === "DATETIME") return "TIMESTAMPTZ";
1962
2186
  if (column.type === "MEDIUMINT") return "INT";
1963
2187
  return column.type;
1964
- };
1965
-
1966
- // src/restura/sql/PsqlTransaction.ts
1967
- import pg2 from "pg";
1968
- var { Client: Client2 } = pg2;
1969
- var PsqlTransaction = class extends PsqlConnection {
1970
- constructor(clientConfig) {
1971
- super();
1972
- this.clientConfig = clientConfig;
1973
- this.client = new Client2(clientConfig);
1974
- this.beginTransactionPromise = this.beginTransaction();
1975
- }
1976
- async beginTransaction() {
1977
- return this.query("BEGIN");
1978
- }
1979
- async rollback() {
1980
- return this.query("ROLLBACK");
1981
- }
1982
- async commit() {
1983
- return this.query("COMMIT");
1984
- }
1985
- async release() {
1986
- return this.client.end();
1987
- }
1988
- async query(query, values) {
1989
- await this.client.connect();
1990
- await this.beginTransactionPromise;
1991
- return this.client.query(query, values);
1992
- }
1993
- };
2188
+ }
1994
2189
 
1995
2190
  // src/restura/compareSchema.ts
1996
2191
  import cloneDeep from "lodash.clonedeep";
1997
2192
  var CompareSchema = class {
1998
2193
  async diffSchema(newSchema, latestSchema, psqlEngine) {
1999
- let endPoints = this.diffEndPoints(newSchema.endpoints[0].routes, latestSchema.endpoints[0].routes);
2000
- let globalParams = this.diffStringArray(newSchema.globalParams, latestSchema.globalParams);
2001
- let roles = this.diffStringArray(newSchema.roles, latestSchema.roles);
2194
+ const endPoints = this.diffEndPoints(newSchema.endpoints[0].routes, latestSchema.endpoints[0].routes);
2195
+ const globalParams = this.diffStringArray(newSchema.globalParams, latestSchema.globalParams);
2196
+ const roles = this.diffStringArray(newSchema.roles, latestSchema.roles);
2002
2197
  let commands = "";
2003
2198
  if (JSON.stringify(newSchema.database) !== JSON.stringify(latestSchema.database))
2004
2199
  commands = await psqlEngine.diffDatabaseToSchema(newSchema);
2005
- let customTypes = newSchema.customTypes !== latestSchema.customTypes;
2200
+ const customTypes = newSchema.customTypes !== latestSchema.customTypes;
2006
2201
  const schemaPreview = { endPoints, globalParams, roles, commands, customTypes };
2007
2202
  return schemaPreview;
2008
2203
  }
2009
2204
  diffStringArray(newArray, originalArray) {
2010
- let stringsDiff = [];
2011
- let originalClone = new Set(originalArray);
2205
+ const stringsDiff = [];
2206
+ const originalClone = new Set(originalArray);
2012
2207
  newArray.forEach((item) => {
2013
- let originalIndex = originalClone.has(item);
2208
+ const originalIndex = originalClone.has(item);
2014
2209
  if (!originalIndex) {
2015
2210
  stringsDiff.push({
2016
2211
  name: item,
@@ -2029,11 +2224,11 @@ var CompareSchema = class {
2029
2224
  return stringsDiff;
2030
2225
  }
2031
2226
  diffEndPoints(newEndPoints, originalEndpoints) {
2032
- let originalClone = cloneDeep(originalEndpoints);
2033
- let diffObj = [];
2227
+ const originalClone = cloneDeep(originalEndpoints);
2228
+ const diffObj = [];
2034
2229
  newEndPoints.forEach((endPoint) => {
2035
- let { path: path4, method } = endPoint;
2036
- let endPointIndex = originalClone.findIndex((original) => {
2230
+ const { path: path4, method } = endPoint;
2231
+ const endPointIndex = originalClone.findIndex((original) => {
2037
2232
  return original.path === endPoint.path && original.method === endPoint.method;
2038
2233
  });
2039
2234
  if (endPointIndex === -1) {
@@ -2042,7 +2237,7 @@ var CompareSchema = class {
2042
2237
  changeType: "NEW"
2043
2238
  });
2044
2239
  } else {
2045
- let original = originalClone.findIndex((original2) => {
2240
+ const original = originalClone.findIndex((original2) => {
2046
2241
  return this.compareEndPoints(endPoint, original2);
2047
2242
  });
2048
2243
  if (original === -1) {
@@ -2055,7 +2250,7 @@ var CompareSchema = class {
2055
2250
  }
2056
2251
  });
2057
2252
  originalClone.forEach((original) => {
2058
- let { path: path4, method } = original;
2253
+ const { path: path4, method } = original;
2059
2254
  diffObj.push({
2060
2255
  name: `${method} ${path4}`,
2061
2256
  changeType: "DELETED"
@@ -2458,11 +2653,13 @@ var setupPgReturnTypes = () => {
2458
2653
  };
2459
2654
  setupPgReturnTypes();
2460
2655
  var restura = new ResturaEngine();
2656
+
2657
+ // src/restura/sql/PsqlTransaction.ts
2658
+ import pg4 from "pg";
2659
+ var { Client: Client2 } = pg4;
2461
2660
  export {
2462
2661
  HtmlStatusCodes,
2463
- PsqlConnection,
2464
2662
  PsqlPool,
2465
- PsqlTransaction,
2466
2663
  RsError,
2467
2664
  SQL,
2468
2665
  escapeColumnName,