@restura/core 0.1.0-alpha.20 → 0.1.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -3,6 +3,7 @@ import * as express from 'express';
3
3
  import { z } from 'zod';
4
4
  import { QueryResultRow, QueryConfigValues, QueryResult, PoolConfig, Pool, ClientConfig, Client } from 'pg';
5
5
  import { IncomingHttpHeaders } from 'http2';
6
+ import { UUID } from 'crypto';
6
7
 
7
8
  declare const logger: winston.Logger;
8
9
 
@@ -2364,6 +2365,7 @@ interface AsyncExpressApplication {
2364
2365
  }
2365
2366
 
2366
2367
  declare abstract class PsqlConnection {
2368
+ readonly instanceId: UUID;
2367
2369
  protected constructor();
2368
2370
  protected abstract query<R extends QueryResultRow = QueryResultRow, T extends Array<unknown> = unknown[]>(query: string, values?: QueryConfigValues<T>): Promise<QueryResult<R>>;
2369
2371
  queryOne<T>(query: string, options: any[], requesterDetails: RequesterDetails): Promise<T>;
@@ -2543,11 +2545,11 @@ type EventType = 'DATABASE_ROW_DELETE' | 'DATABASE_ROW_INSERT' | 'DATABASE_COLUM
2543
2545
  type MutationType = 'INSERT' | 'UPDATE' | 'DELETE';
2544
2546
  interface SqlMutationData {
2545
2547
  mutationType: MutationType;
2546
- requesterDetails: RequesterDetails;
2548
+ queryMetadata: QueryMetadata;
2547
2549
  }
2548
2550
  interface DatabaseActionData {
2549
2551
  tableName: string;
2550
- requesterDetails: RequesterDetails;
2552
+ queryMetadata: QueryMetadata;
2551
2553
  }
2552
2554
  interface ActionRowInsertData<T = DynamicObject> extends DatabaseActionData {
2553
2555
  insertId: number;
@@ -2570,6 +2572,7 @@ interface ActionRowDeleteFilter {
2570
2572
  }
2571
2573
  interface ActionColumnChangeFilter {
2572
2574
  tableName: string;
2575
+ columns: string[];
2573
2576
  }
2574
2577
  type TriggerResult = {
2575
2578
  table: string;
@@ -2579,6 +2582,9 @@ type TriggerResult = {
2579
2582
  previousRecord: DynamicObject;
2580
2583
  requesterId: number;
2581
2584
  };
2585
+ type QueryMetadata = RequesterDetails & {
2586
+ connectionInstanceId: UUID;
2587
+ };
2582
2588
  declare class EventManager {
2583
2589
  private actionHandlers;
2584
2590
  addRowInsertHandler(onInsert: (data: ActionRowInsertData<unknown>) => Promise<void>, filter?: ActionRowInsertFilter): void;
@@ -2592,4 +2598,4 @@ declare class EventManager {
2592
2598
  }
2593
2599
  declare const eventManager: EventManager;
2594
2600
 
2595
- export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticationUserDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoginDetails, type MatchTypes, type MutationType, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type RequesterDetails, type ResponseType, type ResponseTypeMap, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, type ValidAuthenticationCallback, type ValidatorString, escapeColumnName, eventManager, insertObjectQuery, isValueNumber, logger, questionMarksToOrderedParams, restura, updateObjectQuery };
2601
+ export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticationUserDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoginDetails, type MatchTypes, type MutationType, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type QueryMetadata, type RequesterDetails, type ResponseType, type ResponseTypeMap, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, type ValidAuthenticationCallback, type ValidatorString, escapeColumnName, eventManager, insertObjectQuery, isValueNumber, logger, questionMarksToOrderedParams, restura, updateObjectQuery };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import * as express from 'express';
3
3
  import { z } from 'zod';
4
4
  import { QueryResultRow, QueryConfigValues, QueryResult, PoolConfig, Pool, ClientConfig, Client } from 'pg';
5
5
  import { IncomingHttpHeaders } from 'http2';
6
+ import { UUID } from 'crypto';
6
7
 
7
8
  declare const logger: winston.Logger;
8
9
 
@@ -2364,6 +2365,7 @@ interface AsyncExpressApplication {
2364
2365
  }
2365
2366
 
2366
2367
  declare abstract class PsqlConnection {
2368
+ readonly instanceId: UUID;
2367
2369
  protected constructor();
2368
2370
  protected abstract query<R extends QueryResultRow = QueryResultRow, T extends Array<unknown> = unknown[]>(query: string, values?: QueryConfigValues<T>): Promise<QueryResult<R>>;
2369
2371
  queryOne<T>(query: string, options: any[], requesterDetails: RequesterDetails): Promise<T>;
@@ -2543,11 +2545,11 @@ type EventType = 'DATABASE_ROW_DELETE' | 'DATABASE_ROW_INSERT' | 'DATABASE_COLUM
2543
2545
  type MutationType = 'INSERT' | 'UPDATE' | 'DELETE';
2544
2546
  interface SqlMutationData {
2545
2547
  mutationType: MutationType;
2546
- requesterDetails: RequesterDetails;
2548
+ queryMetadata: QueryMetadata;
2547
2549
  }
2548
2550
  interface DatabaseActionData {
2549
2551
  tableName: string;
2550
- requesterDetails: RequesterDetails;
2552
+ queryMetadata: QueryMetadata;
2551
2553
  }
2552
2554
  interface ActionRowInsertData<T = DynamicObject> extends DatabaseActionData {
2553
2555
  insertId: number;
@@ -2570,6 +2572,7 @@ interface ActionRowDeleteFilter {
2570
2572
  }
2571
2573
  interface ActionColumnChangeFilter {
2572
2574
  tableName: string;
2575
+ columns: string[];
2573
2576
  }
2574
2577
  type TriggerResult = {
2575
2578
  table: string;
@@ -2579,6 +2582,9 @@ type TriggerResult = {
2579
2582
  previousRecord: DynamicObject;
2580
2583
  requesterId: number;
2581
2584
  };
2585
+ type QueryMetadata = RequesterDetails & {
2586
+ connectionInstanceId: UUID;
2587
+ };
2582
2588
  declare class EventManager {
2583
2589
  private actionHandlers;
2584
2590
  addRowInsertHandler(onInsert: (data: ActionRowInsertData<unknown>) => Promise<void>, filter?: ActionRowInsertFilter): void;
@@ -2592,4 +2598,4 @@ declare class EventManager {
2592
2598
  }
2593
2599
  declare const eventManager: EventManager;
2594
2600
 
2595
- export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticationUserDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoginDetails, type MatchTypes, type MutationType, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type RequesterDetails, type ResponseType, type ResponseTypeMap, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, type ValidAuthenticationCallback, type ValidatorString, escapeColumnName, eventManager, insertObjectQuery, isValueNumber, logger, questionMarksToOrderedParams, restura, updateObjectQuery };
2601
+ export { type ActionColumnChangeData, type ActionColumnChangeFilter, type ActionRowDeleteData, type ActionRowDeleteFilter, type ActionRowInsertData, type ActionRowInsertFilter, type ApiMethod, type AsyncExpressApplication, type AuthenticateHandler, type AuthenticationUserDetails, type ConjunctionTypes, type DatabaseActionData, type DynamicObject, type ErrorCode, type EventType, HtmlStatusCodes, type LoginDetails, type MatchTypes, type MutationType, type PageQuery, PsqlConnection, PsqlEngine, PsqlPool, PsqlTransaction, type QueryMetadata, type RequesterDetails, type ResponseType, type ResponseTypeMap, RsError, type RsErrorData, type RsErrorInternalData, type RsHeaders, type RsPagedResponseData, type RsRequest, type RsResponse, type RsResponseData, type RsRouteHandler, SQL, type SchemaChangeValue, type SchemaPreview, type SqlMutationData, type StandardOrderTypes, type TriggerResult, type ValidAuthenticationCallback, type ValidatorString, escapeColumnName, eventManager, insertObjectQuery, isValueNumber, logger, questionMarksToOrderedParams, restura, updateObjectQuery };
package/dist/index.js CHANGED
@@ -263,7 +263,7 @@ function boundMethod(target, key, descriptor) {
263
263
  var import_body_parser = __toESM(require("body-parser"));
264
264
  var import_compression = __toESM(require("compression"));
265
265
  var import_cookie_parser = __toESM(require("cookie-parser"));
266
- var import_crypto = require("crypto");
266
+ var import_crypto2 = require("crypto");
267
267
  var express = __toESM(require("express"));
268
268
  var import_fs4 = __toESM(require("fs"));
269
269
  var import_path5 = __toESM(require("path"));
@@ -1329,14 +1329,17 @@ function SQL(strings, ...values) {
1329
1329
  }
1330
1330
 
1331
1331
  // src/restura/sql/PsqlConnection.ts
1332
+ var import_crypto = __toESM(require("crypto"));
1332
1333
  var PsqlConnection = class {
1333
1334
  constructor() {
1335
+ this.instanceId = import_crypto.default.randomUUID();
1334
1336
  }
1335
1337
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1336
1338
  async queryOne(query, options, requesterDetails) {
1337
1339
  const formattedQuery = questionMarksToOrderedParams(query);
1338
- this.logSqlStatement(formattedQuery, options, requesterDetails);
1339
- const queryMetadata = `--QUERY_METADATA(${JSON.stringify(requesterDetails)})
1340
+ const meta = __spreadValues({ connectionInstanceId: this.instanceId }, requesterDetails);
1341
+ this.logSqlStatement(formattedQuery, options, meta);
1342
+ const queryMetadata = `--QUERY_METADATA(${JSON.stringify(meta)})
1340
1343
  `;
1341
1344
  try {
1342
1345
  const response = await this.query(queryMetadata + formattedQuery, options);
@@ -1355,8 +1358,9 @@ var PsqlConnection = class {
1355
1358
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1356
1359
  async runQuery(query, options, requesterDetails) {
1357
1360
  const formattedQuery = questionMarksToOrderedParams(query);
1358
- this.logSqlStatement(formattedQuery, options, requesterDetails);
1359
- const queryMetadata = `--QUERY_METADATA(${JSON.stringify(requesterDetails)})
1361
+ const meta = __spreadValues({ connectionInstanceId: this.instanceId }, requesterDetails);
1362
+ this.logSqlStatement(formattedQuery, options, meta);
1363
+ const queryMetadata = `--QUERY_METADATA(${JSON.stringify(meta)})
1360
1364
  `;
1361
1365
  try {
1362
1366
  const response = await this.query(queryMetadata + formattedQuery, options);
@@ -1369,7 +1373,7 @@ var PsqlConnection = class {
1369
1373
  throw new RsError("DATABASE_ERROR", `${error.message}`);
1370
1374
  }
1371
1375
  }
1372
- logSqlStatement(query, options, requesterDetails, prefix = "") {
1376
+ logSqlStatement(query, options, queryMetadata, prefix = "") {
1373
1377
  if (logger.level !== "silly") return;
1374
1378
  let sqlStatement = "";
1375
1379
  if (options.length === 0) {
@@ -1383,9 +1387,9 @@ var PsqlConnection = class {
1383
1387
  });
1384
1388
  }
1385
1389
  let initiator = "Anonymous";
1386
- if ("userId" in requesterDetails && requesterDetails.userId)
1387
- initiator = `User Id (${requesterDetails.userId.toString()})`;
1388
- if ("isSystemUser" in requesterDetails && requesterDetails.isSystemUser) initiator = "SYSTEM";
1390
+ if ("userId" in queryMetadata && queryMetadata.userId)
1391
+ initiator = `User Id (${queryMetadata.userId.toString()})`;
1392
+ if ("isSystemUser" in queryMetadata && queryMetadata.isSystemUser) initiator = "SYSTEM";
1389
1393
  logger.silly(`${prefix}query by ${initiator}, Query ->
1390
1394
  ${sqlStatement}`);
1391
1395
  }
@@ -1567,13 +1571,15 @@ var filterSqlGrammar = `
1567
1571
 
1568
1572
  start = expressionList
1569
1573
 
1574
+ _ = [ \\t\\r\\n]* // Matches spaces, tabs, and line breaks
1575
+
1570
1576
  expressionList =
1571
- leftExpression:expression operator:operator rightExpression:expressionList
1577
+ leftExpression:expression _ operator:operator _ rightExpression:expressionList
1572
1578
  { return \`\${leftExpression} \${operator} \${rightExpression}\`;}
1573
1579
  / expression
1574
1580
 
1575
1581
  expression =
1576
- negate:negate?"(" "column:" column:column ","? value:value? ","? type:type? ")"
1582
+ negate:negate? _ "(" _ "column" _ ":" column:column _ ","? _ value:value? ","? _ type:type? _ ")"_
1577
1583
  {return \`\${negate? " NOT " : ""}(\${type? type(column, value) : \`\${column} = \${format.literal(value)}\`})\`;}
1578
1584
  /
1579
1585
  negate:negate?"("expression:expressionList")" { return \`\${negate? " NOT " : ""}(\${expression})\`; }
@@ -1588,9 +1594,9 @@ column = left:text "." right:text { return \`\${quoteSqlIdentity(left)}.\${quot
1588
1594
  text:text { return quoteSqlIdentity(text); }
1589
1595
 
1590
1596
 
1591
- text = text:[a-z0-9-_:@]i+ { return text.join("");}
1597
+ text = text:[a-z0-9 \\t\\r\\n\\-_:@]i+ { return text.join(""); }
1592
1598
 
1593
- type = "type:" type:typeString { return type; }
1599
+ type = "type" _ ":" _ type:typeString { return type; }
1594
1600
  typeString = text:"startsWith" { return function(column, value) { return \`\${column} ILIKE '\${format.literal(value).slice(1,-1)}%'\`; } } /
1595
1601
  text:"endsWith" { return function(column, value) { return \`\${column} ILIKE '%\${format.literal(value).slice(1,-1)}'\`; } } /
1596
1602
  text:"contains" { return function(column, value) { return \`\${column} ILIKE '%\${format.literal(value).slice(1,-1)}%'\`; } } /
@@ -1600,8 +1606,9 @@ typeString = text:"startsWith" { return function(column, value) { return \`\${co
1600
1606
  text:"lessThanEqual" { return function(column, value) { return \`\${column} <= '\${format.literal(value).slice(1,-1)}'\`; } } /
1601
1607
  text:"lessThan" { return function(column, value) { return \`\${column} < '\${format.literal(value).slice(1,-1)}'\`; } } /
1602
1608
  text:"isNull" { return function(column, value) { return \`isNull(\${column})\`; } }
1603
-
1604
- value = "value:" value:text { return value; }
1609
+
1610
+ value = "value" _ ":" value:text { return value; }
1611
+
1605
1612
 
1606
1613
  `;
1607
1614
  var filterPsqlParser = import_pegjs.default.generate(filterSqlGrammar, {
@@ -1656,9 +1663,9 @@ var EventManager = class {
1656
1663
  tableName: triggerResult.table,
1657
1664
  insertId: triggerResult.record.id,
1658
1665
  insertObject: triggerResult.record,
1659
- requesterDetails: data.requesterDetails
1666
+ queryMetadata: data.queryMetadata
1660
1667
  };
1661
- callback(insertData, data.requesterDetails);
1668
+ callback(insertData, data.queryMetadata);
1662
1669
  },
1663
1670
  { concurrency: 10 }
1664
1671
  );
@@ -1671,9 +1678,9 @@ var EventManager = class {
1671
1678
  const deleteData = {
1672
1679
  tableName: triggerResult.table,
1673
1680
  deletedRow: triggerResult.previousRecord,
1674
- requesterDetails: data.requesterDetails
1681
+ queryMetadata: data.queryMetadata
1675
1682
  };
1676
- callback(deleteData, data.requesterDetails);
1683
+ callback(deleteData, data.queryMetadata);
1677
1684
  },
1678
1685
  { concurrency: 10 }
1679
1686
  );
@@ -1688,9 +1695,9 @@ var EventManager = class {
1688
1695
  rowId: triggerResult.record.id,
1689
1696
  newData: triggerResult.record,
1690
1697
  oldData: triggerResult.previousRecord,
1691
- requesterDetails: data.requesterDetails
1698
+ queryMetadata: data.queryMetadata
1692
1699
  };
1693
- callback(columnChangeData, data.requesterDetails);
1700
+ callback(columnChangeData, data.queryMetadata);
1694
1701
  },
1695
1702
  { concurrency: 10 }
1696
1703
  );
@@ -1705,6 +1712,13 @@ var EventManager = class {
1705
1712
  case "DATABASE_COLUMN_UPDATE":
1706
1713
  const filterColumnChange = filter;
1707
1714
  if (filterColumnChange.tableName !== filter.tableName) return false;
1715
+ if (!filterColumnChange.columns.some((item) => {
1716
+ const updatedColumns = Object.keys(
1717
+ changedValues(triggerResult.record, triggerResult.previousRecord)
1718
+ );
1719
+ return updatedColumns.includes(item);
1720
+ }))
1721
+ return false;
1708
1722
  break;
1709
1723
  }
1710
1724
  }
@@ -1713,6 +1727,22 @@ var EventManager = class {
1713
1727
  };
1714
1728
  var eventManager = new EventManager();
1715
1729
  var eventManager_default = eventManager;
1730
+ function changedValues(record, previousRecord) {
1731
+ const changed = {};
1732
+ for (const i in previousRecord) {
1733
+ if (previousRecord[i] !== record[i]) {
1734
+ if (typeof previousRecord[i] === "object" && typeof record[i] === "object") {
1735
+ const nestedChanged = changedValues(record[i], previousRecord[i]);
1736
+ if (Object.keys(nestedChanged).length > 0) {
1737
+ changed[i] = record[i];
1738
+ }
1739
+ } else {
1740
+ changed[i] = record[i];
1741
+ }
1742
+ }
1743
+ }
1744
+ return changed;
1745
+ }
1716
1746
 
1717
1747
  // src/restura/sql/PsqlEngine.ts
1718
1748
  var { Client } = import_pg2.default;
@@ -1759,12 +1789,15 @@ var PsqlEngine = class extends SqlEngine {
1759
1789
  }
1760
1790
  async handleTrigger(payload, mutationType) {
1761
1791
  const findRequesterDetailsRegex = /^--QUERY_METADATA\(\{.*\}\)/;
1762
- let requesterDetails = {};
1763
1792
  const match = payload.query.match(findRequesterDetailsRegex);
1764
1793
  if (match) {
1765
1794
  const jsonString = match[0].slice(match[0].indexOf("{"), match[0].lastIndexOf("}") + 1);
1766
- requesterDetails = import_core_utils5.ObjectUtils.safeParse(jsonString);
1767
- await eventManager_default.fireActionFromDbTrigger({ requesterDetails, mutationType }, payload);
1795
+ const queryMetadata = import_core_utils5.ObjectUtils.safeParse(jsonString);
1796
+ const triggerFromThisInstance = queryMetadata.connectionInstanceId === this.psqlConnectionPool.instanceId;
1797
+ if (!triggerFromThisInstance) {
1798
+ return;
1799
+ }
1800
+ await eventManager_default.fireActionFromDbTrigger({ queryMetadata, mutationType }, payload);
1768
1801
  }
1769
1802
  }
1770
1803
  async createDatabaseFromSchema(schema, connection) {
@@ -1774,7 +1807,6 @@ var PsqlEngine = class extends SqlEngine {
1774
1807
  }
1775
1808
  generateDatabaseSchemaFromSchema(schema) {
1776
1809
  const sqlStatements = [];
1777
- const enums = [];
1778
1810
  const indexes = [];
1779
1811
  const triggers = [];
1780
1812
  for (const table of schema.database) {
@@ -1786,10 +1818,7 @@ var PsqlEngine = class extends SqlEngine {
1786
1818
  const tableColumns = [];
1787
1819
  for (const column of table.columns) {
1788
1820
  let columnSql = "";
1789
- if (column.type === "ENUM") {
1790
- enums.push(`CREATE TYPE ${schemaToPsqlType(column, table.name)} AS ENUM (${column.value});`);
1791
- }
1792
- columnSql += ` "${column.name}" ${schemaToPsqlType(column, table.name)}`;
1821
+ columnSql += ` "${column.name}" ${schemaToPsqlType(column)}`;
1793
1822
  let value = column.value;
1794
1823
  if (column.type === "JSON") value = "";
1795
1824
  if (column.type === "JSONB") value = "";
@@ -1808,6 +1837,9 @@ var PsqlEngine = class extends SqlEngine {
1808
1837
  if (column.isNullable) columnSql += " NULL";
1809
1838
  else columnSql += " NOT NULL";
1810
1839
  if (column.default) columnSql += ` DEFAULT ${column.default}`;
1840
+ if (value && column.type === "ENUM") {
1841
+ columnSql += ` CHECK ("${column.name}" IN (${value}))`;
1842
+ }
1811
1843
  tableColumns.push(columnSql);
1812
1844
  }
1813
1845
  sql += tableColumns.join(", \n");
@@ -1850,16 +1882,18 @@ var PsqlEngine = class extends SqlEngine {
1850
1882
  }
1851
1883
  sqlStatements.push(indexes.join("\n"));
1852
1884
  sqlStatements.push(triggers.join("\n"));
1853
- return enums.join("\n") + "\n" + sqlStatements.join("\n\n");
1885
+ return sqlStatements.join("\n\n");
1854
1886
  }
1855
1887
  async getScratchPool() {
1856
- const response = await this.psqlConnectionPool.runQuery(
1857
- `SELECT * FROM pg_database
1858
- WHERE datname = '${this.psqlConnectionPool.poolConfig.database}_scratch'`,
1888
+ var _a2, _b;
1889
+ const scratchDbExists = await this.psqlConnectionPool.runQuery(
1890
+ `SELECT *
1891
+ FROM pg_database
1892
+ WHERE datname = '${this.psqlConnectionPool.poolConfig.database}_scratch';`,
1859
1893
  [],
1860
1894
  systemUser
1861
1895
  );
1862
- if (response.length === 0) {
1896
+ if (scratchDbExists.length === 0) {
1863
1897
  await this.psqlConnectionPool.runQuery(
1864
1898
  `CREATE DATABASE ${this.psqlConnectionPool.poolConfig.database}_scratch;`,
1865
1899
  [],
@@ -1876,12 +1910,27 @@ var PsqlEngine = class extends SqlEngine {
1876
1910
  idleTimeoutMillis: this.psqlConnectionPool.poolConfig.idleTimeoutMillis,
1877
1911
  connectionTimeoutMillis: this.psqlConnectionPool.poolConfig.connectionTimeoutMillis
1878
1912
  });
1879
- await scratchPool.runQuery(`drop schema public cascade;`, [], systemUser);
1913
+ await scratchPool.runQuery(`DROP SCHEMA public CASCADE;`, [], systemUser);
1880
1914
  await scratchPool.runQuery(
1881
- `create schema public authorization ${this.psqlConnectionPool.poolConfig.user};`,
1915
+ `CREATE SCHEMA public AUTHORIZATION ${this.psqlConnectionPool.poolConfig.user};`,
1916
+ [],
1917
+ systemUser
1918
+ );
1919
+ const schemaComment = await this.psqlConnectionPool.runQuery(
1920
+ `SELECT pg_description.description
1921
+ FROM pg_description
1922
+ JOIN pg_namespace ON pg_namespace.oid = pg_description.objoid
1923
+ WHERE pg_namespace.nspname = 'public';`,
1882
1924
  [],
1883
1925
  systemUser
1884
1926
  );
1927
+ if ((_a2 = schemaComment[0]) == null ? void 0 : _a2.description) {
1928
+ await scratchPool.runQuery(
1929
+ `COMMENT ON SCHEMA public IS '${(_b = schemaComment[0]) == null ? void 0 : _b.description}';`,
1930
+ [],
1931
+ systemUser
1932
+ );
1933
+ }
1885
1934
  return scratchPool;
1886
1935
  }
1887
1936
  async diffDatabaseToSchema(schema) {
@@ -2251,9 +2300,9 @@ __decorateClass([
2251
2300
  __decorateClass([
2252
2301
  boundMethod
2253
2302
  ], PsqlEngine.prototype, "createInsertTriggers", 1);
2254
- function schemaToPsqlType(column, tableName) {
2303
+ function schemaToPsqlType(column) {
2255
2304
  if (column.hasAutoIncrement) return "BIGSERIAL";
2256
- if (column.type === "ENUM") return `"${tableName}_${column.name}_enum"`;
2305
+ if (column.type === "ENUM") return `TEXT`;
2257
2306
  if (column.type === "DATETIME") return "TIMESTAMPTZ";
2258
2307
  if (column.type === "MEDIUMINT") return "INT";
2259
2308
  return column.type;
@@ -2727,7 +2776,7 @@ var ResturaEngine = class {
2727
2776
  printWidth: 120,
2728
2777
  singleQuote: true
2729
2778
  }));
2730
- return (0, import_crypto.createHash)("sha256").update(schemaPrettyStr).digest("hex");
2779
+ return (0, import_crypto2.createHash)("sha256").update(schemaPrettyStr).digest("hex");
2731
2780
  }
2732
2781
  async storeFileSystemSchema() {
2733
2782
  const schemaPrettyStr = await prettier3.format(JSON.stringify(this.schema), __spreadValues({
@@ -2796,7 +2845,7 @@ __decorateClass([
2796
2845
  __decorateClass([
2797
2846
  boundMethod
2798
2847
  ], ResturaEngine.prototype, "runCustomRouteLogic", 1);
2799
- var setupPgReturnTypes = () => {
2848
+ function setupPgReturnTypes() {
2800
2849
  const TIMESTAMPTZ_OID = 1184;
2801
2850
  types.setTypeParser(TIMESTAMPTZ_OID, (val) => {
2802
2851
  return val === null ? null : new Date(val).toISOString();
@@ -2805,7 +2854,7 @@ var setupPgReturnTypes = () => {
2805
2854
  types.setTypeParser(BIGINT_OID, (val) => {
2806
2855
  return val === null ? null : Number(val);
2807
2856
  });
2808
- };
2857
+ }
2809
2858
  setupPgReturnTypes();
2810
2859
  var restura = new ResturaEngine();
2811
2860