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

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
@@ -216,7 +216,7 @@ import { createHash } from "crypto";
216
216
  import * as express from "express";
217
217
  import fs3 from "fs";
218
218
  import path3 from "path";
219
- import pg2 from "pg";
219
+ import pg3 from "pg";
220
220
  import * as prettier3 from "prettier";
221
221
 
222
222
  // src/restura/sql/SqlUtils.ts
@@ -1206,7 +1206,6 @@ import { ObjectUtils as ObjectUtils4 } from "@redskytech/core-utils";
1206
1206
 
1207
1207
  // src/restura/sql/PsqlPool.ts
1208
1208
  import pg from "pg";
1209
- import format3 from "pg-format";
1210
1209
 
1211
1210
  // src/restura/sql/PsqlUtils.ts
1212
1211
  import format2 from "pg-format";
@@ -1255,25 +1254,17 @@ function SQL(strings, ...values) {
1255
1254
  return query;
1256
1255
  }
1257
1256
 
1258
- // src/restura/sql/PsqlPool.ts
1259
- var { Pool } = pg;
1260
- var PsqlPool = class {
1261
- constructor(poolConfig) {
1262
- this.poolConfig = poolConfig;
1263
- this.pool = new Pool(poolConfig);
1264
- this.queryOne("SELECT NOW();", [], { isSystemUser: true, role: "", host: "localhost", ipAddress: "" }).then(() => {
1265
- logger.info("Connected to PostgreSQL database");
1266
- }).catch((error) => {
1267
- logger.error("Error connecting to database", error);
1268
- process.exit(1);
1269
- });
1257
+ // src/restura/sql/PsqlConnection.ts
1258
+ import format3 from "pg-format";
1259
+ var PsqlConnection = class {
1260
+ constructor() {
1270
1261
  }
1271
1262
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1272
1263
  async queryOne(query, options, requesterDetails) {
1273
1264
  const formattedQuery = questionMarksToOrderedParams(query);
1274
1265
  this.logSqlStatement(formattedQuery, options, requesterDetails);
1275
1266
  try {
1276
- const response = await this.pool.query(formattedQuery, options);
1267
+ const response = await this.query(formattedQuery, options);
1277
1268
  if (response.rows.length === 0) throw new RsError("NOT_FOUND", "No results found");
1278
1269
  else if (response.rows.length > 1) throw new RsError("DUPLICATE", "More than one result found");
1279
1270
  return response.rows[0];
@@ -1290,10 +1281,8 @@ var PsqlPool = class {
1290
1281
  async runQuery(query, options, requesterDetails) {
1291
1282
  const formattedQuery = questionMarksToOrderedParams(query);
1292
1283
  this.logSqlStatement(formattedQuery, options, requesterDetails);
1293
- const queryUpdated = query.replace(/[\t\n]/g, " ");
1294
- console.log(queryUpdated, options);
1295
1284
  try {
1296
- const response = await this.pool.query(formattedQuery, options);
1285
+ const response = await this.query(formattedQuery, options);
1297
1286
  return response.rows;
1298
1287
  } catch (error) {
1299
1288
  console.error(error, query, options);
@@ -1325,6 +1314,25 @@ var PsqlPool = class {
1325
1314
  }
1326
1315
  };
1327
1316
 
1317
+ // src/restura/sql/PsqlPool.ts
1318
+ var { Pool } = pg;
1319
+ var PsqlPool = class extends PsqlConnection {
1320
+ constructor(poolConfig) {
1321
+ super();
1322
+ this.poolConfig = poolConfig;
1323
+ this.pool = new Pool(poolConfig);
1324
+ this.queryOne("SELECT NOW();", [], { isSystemUser: true, role: "", host: "localhost", ipAddress: "" }).then(() => {
1325
+ logger.info("Connected to PostgreSQL database");
1326
+ }).catch((error) => {
1327
+ logger.error("Error connecting to database", error);
1328
+ process.exit(1);
1329
+ });
1330
+ }
1331
+ async query(query, values) {
1332
+ return this.pool.query(query, values);
1333
+ }
1334
+ };
1335
+
1328
1336
  // src/restura/sql/SqlEngine.ts
1329
1337
  import { ObjectUtils as ObjectUtils3 } from "@redskytech/core-utils";
1330
1338
  var SqlEngine = class {
@@ -1489,9 +1497,9 @@ expressionList =
1489
1497
 
1490
1498
  expression =
1491
1499
  negate:negate?"(" "column:" column:column ","? value:value? ","? type:type? ")"
1492
- {return \`\${negate? "!" : ""}(\${type? type(column, value) : \`\${column} = \${format.literal(value)}\`})\`;}
1500
+ {return \`\${negate? " NOT " : ""}(\${type? type(column, value) : \`\${column} = \${format.literal(value)}\`})\`;}
1493
1501
  /
1494
- negate:negate?"("expression:expressionList")" { return \`\${negate? "!" : ""}(\${expression})\`; }
1502
+ negate:negate?"("expression:expressionList")" { return \`\${negate? " NOT " : ""}(\${expression})\`; }
1495
1503
 
1496
1504
  negate = "!"
1497
1505
 
@@ -1528,7 +1536,7 @@ var filterPsqlParser_default = filterPsqlParser;
1528
1536
  // src/restura/sql/PsqlEngine.ts
1529
1537
  import getDiff from "@wmfs/pg-diff-sync";
1530
1538
  import pgInfo from "@wmfs/pg-info";
1531
- import { Client } from "pg";
1539
+ var { Client } = "pg";
1532
1540
  var systemUser = {
1533
1541
  role: "",
1534
1542
  host: "",
@@ -1671,7 +1679,6 @@ var PsqlEngine = class extends SqlEngine {
1671
1679
  schema: "public"
1672
1680
  });
1673
1681
  const diff = getDiff(info1, info2);
1674
- console.log("Schema differences:", diff);
1675
1682
  await originalClient.end();
1676
1683
  await scratchClient.end();
1677
1684
  return diff.join("\n");
@@ -1785,22 +1792,20 @@ var PsqlEngine = class extends SqlEngine {
1785
1792
  );
1786
1793
  } else if (routeData.type === "PAGED") {
1787
1794
  const data = req.data;
1788
- const pageResults = await this.psqlConnectionPool.runQuery(
1789
- `${selectStatement}${sqlStatement}${groupByOrderByStatement} LIMIT ? OFFSET ?;SELECT COUNT(${routeData.groupBy ? `DISTINCT ${routeData.groupBy.tableName}.${routeData.groupBy.columnName}` : "*"}) AS total
1790
- ${sqlStatement};`,
1791
- [
1792
- ...sqlParams,
1793
- data.perPage || DEFAULT_PAGED_PER_PAGE_NUMBER,
1794
- (data.page - 1) * data.perPage || DEFAULT_PAGED_PAGE_NUMBER,
1795
- ...sqlParams
1796
- ],
1795
+ const pagePromise = this.psqlConnectionPool.runQuery(
1796
+ `${selectStatement}${sqlStatement}${groupByOrderByStatement}` + SQL`LIMIT ${data.perPage || DEFAULT_PAGED_PER_PAGE_NUMBER} OFFSET ${(data.page - 1) * data.perPage || DEFAULT_PAGED_PAGE_NUMBER};`,
1797
+ sqlParams,
1797
1798
  req.requesterDetails
1798
1799
  );
1800
+ const totalQuery = `SELECT COUNT(${routeData.groupBy ? `DISTINCT ${routeData.groupBy.tableName}.${routeData.groupBy.columnName}` : "*"}) AS total
1801
+ ${sqlStatement};`;
1802
+ const totalPromise = await this.psqlConnectionPool.runQuery(totalQuery, sqlParams, req.requesterDetails);
1803
+ const [pageResults, totalResponse] = await Promise.all([pagePromise, totalPromise]);
1799
1804
  let total = 0;
1800
- if (ObjectUtils4.isArrayWithData(pageResults)) {
1801
- total = pageResults[1][0].total;
1805
+ if (ObjectUtils4.isArrayWithData(totalResponse)) {
1806
+ total = totalResponse[0].total;
1802
1807
  }
1803
- return { data: pageResults[0], total };
1808
+ return { data: pageResults, total };
1804
1809
  } else {
1805
1810
  throw new RsError("UNKNOWN_ERROR", "Unknown route type.");
1806
1811
  }
@@ -1958,8 +1963,127 @@ var schemaToPsqlType = (column, tableName) => {
1958
1963
  return column.type;
1959
1964
  };
1960
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
+ };
1994
+
1995
+ // src/restura/compareSchema.ts
1996
+ import cloneDeep from "lodash.clonedeep";
1997
+ var CompareSchema = class {
1998
+ 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);
2002
+ let commands = "";
2003
+ if (JSON.stringify(newSchema.database) !== JSON.stringify(latestSchema.database))
2004
+ commands = await psqlEngine.diffDatabaseToSchema(newSchema);
2005
+ let customTypes = newSchema.customTypes !== latestSchema.customTypes;
2006
+ const schemaPreview = { endPoints, globalParams, roles, commands, customTypes };
2007
+ return schemaPreview;
2008
+ }
2009
+ diffStringArray(newArray, originalArray) {
2010
+ let stringsDiff = [];
2011
+ let originalClone = new Set(originalArray);
2012
+ newArray.forEach((item) => {
2013
+ let originalIndex = originalClone.has(item);
2014
+ if (!originalIndex) {
2015
+ stringsDiff.push({
2016
+ name: item,
2017
+ changeType: "NEW"
2018
+ });
2019
+ } else {
2020
+ originalClone.delete(item);
2021
+ }
2022
+ });
2023
+ originalClone.forEach((item) => {
2024
+ stringsDiff.push({
2025
+ name: item,
2026
+ changeType: "DELETED"
2027
+ });
2028
+ });
2029
+ return stringsDiff;
2030
+ }
2031
+ diffEndPoints(newEndPoints, originalEndpoints) {
2032
+ let originalClone = cloneDeep(originalEndpoints);
2033
+ let diffObj = [];
2034
+ newEndPoints.forEach((endPoint) => {
2035
+ let { path: path4, method } = endPoint;
2036
+ let endPointIndex = originalClone.findIndex((original) => {
2037
+ return original.path === endPoint.path && original.method === endPoint.method;
2038
+ });
2039
+ if (endPointIndex === -1) {
2040
+ diffObj.push({
2041
+ name: `${method} ${path4}`,
2042
+ changeType: "NEW"
2043
+ });
2044
+ } else {
2045
+ let original = originalClone.findIndex((original2) => {
2046
+ return this.compareEndPoints(endPoint, original2);
2047
+ });
2048
+ if (original === -1) {
2049
+ diffObj.push({
2050
+ name: `${method} ${path4}`,
2051
+ changeType: "MODIFIED"
2052
+ });
2053
+ }
2054
+ originalClone.splice(endPointIndex, 1);
2055
+ }
2056
+ });
2057
+ originalClone.forEach((original) => {
2058
+ let { path: path4, method } = original;
2059
+ diffObj.push({
2060
+ name: `${method} ${path4}`,
2061
+ changeType: "DELETED"
2062
+ });
2063
+ });
2064
+ return diffObj;
2065
+ }
2066
+ compareEndPoints(endPoint1, endPoint2) {
2067
+ return JSON.stringify(endPoint1) === JSON.stringify(endPoint2);
2068
+ }
2069
+ };
2070
+ __decorateClass([
2071
+ boundMethod
2072
+ ], CompareSchema.prototype, "diffSchema", 1);
2073
+ __decorateClass([
2074
+ boundMethod
2075
+ ], CompareSchema.prototype, "diffStringArray", 1);
2076
+ __decorateClass([
2077
+ boundMethod
2078
+ ], CompareSchema.prototype, "diffEndPoints", 1);
2079
+ __decorateClass([
2080
+ boundMethod
2081
+ ], CompareSchema.prototype, "compareEndPoints", 1);
2082
+ var compareSchema = new CompareSchema();
2083
+ var compareSchema_default = compareSchema;
2084
+
1961
2085
  // src/restura/restura.ts
1962
- var { types } = pg2;
2086
+ var { types } = pg3;
1963
2087
  var ResturaEngine = class {
1964
2088
  constructor() {
1965
2089
  this.publicEndpoints = {
@@ -2163,7 +2287,7 @@ var ResturaEngine = class {
2163
2287
  }
2164
2288
  async previewCreateSchema(req, res) {
2165
2289
  try {
2166
- const schemaDiff = { commands: "", endPoints: [], globalParams: [], roles: [], customTypes: false };
2290
+ const schemaDiff = await compareSchema_default.diffSchema(req.data, this.schema, this.psqlEngine);
2167
2291
  res.send({ data: schemaDiff });
2168
2292
  } catch (err) {
2169
2293
  res.status(400).send(err);
@@ -2336,7 +2460,9 @@ setupPgReturnTypes();
2336
2460
  var restura = new ResturaEngine();
2337
2461
  export {
2338
2462
  HtmlStatusCodes,
2463
+ PsqlConnection,
2339
2464
  PsqlPool,
2465
+ PsqlTransaction,
2340
2466
  RsError,
2341
2467
  SQL,
2342
2468
  escapeColumnName,