@igstack/app-catalog-backend-core 0.2.0 → 0.3.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.
package/dist/index.js CHANGED
@@ -3,17 +3,16 @@ import * as path$1 from "node:path";
3
3
  import { extname, join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import * as runtime from "@prisma/client/runtime/client";
6
+ import { PrismaPg } from "@prisma/adapter-pg";
6
7
  import { group, mapValues, omit, pick } from "radashi";
7
- import { z } from "zod";
8
+ import { TRPCError, initTRPC } from "@trpc/server";
9
+ import { betterAuth } from "better-auth";
10
+ import { prismaAdapter } from "better-auth/adapters/prisma";
8
11
  import { tableSync } from "@igstack/app-catalog-table-sync";
9
12
  import { readFile, readdir, stat } from "node:fs/promises";
10
13
  import { createHash } from "node:crypto";
11
14
  import sharp from "sharp";
12
- import { TRPCError, initTRPC } from "@trpc/server";
13
- import { betterAuth } from "better-auth";
14
- import { prismaAdapter } from "better-auth/adapters/prisma";
15
15
  import { toNodeHandler } from "better-auth/node";
16
- import { stepCountIs, streamText, tool } from "ai";
17
16
  import multer from "multer";
18
17
  import { readFileSync, readdirSync } from "node:fs";
19
18
  import express, { Router } from "express";
@@ -21,7 +20,7 @@ import * as trpcExpress from "@trpc/server/adapters/express";
21
20
 
22
21
  //#region rolldown:runtime
23
22
  var __create = Object.create;
24
- var __defProp$1 = Object.defineProperty;
23
+ var __defProp = Object.defineProperty;
25
24
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
26
25
  var __getOwnPropNames = Object.getOwnPropertyNames;
27
26
  var __getProtoOf = Object.getPrototypeOf;
@@ -32,14 +31,14 @@ var __commonJS = (cb, mod) => function() {
32
31
  var __copyProps = (to, from, except, desc) => {
33
32
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
34
33
  key = keys[i];
35
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp$1(to, key, {
34
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
36
35
  get: ((k) => from[k]).bind(null, key),
37
36
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
38
37
  });
39
38
  }
40
39
  return to;
41
40
  };
42
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
41
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
43
42
  value: mod,
44
43
  enumerable: true
45
44
  }) : target, mod));
@@ -85,63 +84,6 @@ function getPrismaClientClass() {
85
84
  return runtime.getPrismaClient(config);
86
85
  }
87
86
 
88
- //#endregion
89
- //#region src/generated/prisma/internal/prismaNamespace.ts
90
- /**
91
- * Prisma Errors
92
- */
93
- const PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError;
94
- const PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError;
95
- const PrismaClientRustPanicError = runtime.PrismaClientRustPanicError;
96
- const PrismaClientInitializationError = runtime.PrismaClientInitializationError;
97
- const PrismaClientValidationError = runtime.PrismaClientValidationError;
98
- /**
99
- * Re-export of sql-template-tag
100
- */
101
- const sql = runtime.sqltag;
102
- const empty = runtime.empty;
103
- const join$1 = runtime.join;
104
- const raw = runtime.raw;
105
- const Sql = runtime.Sql;
106
- /**
107
- * Decimal.js
108
- */
109
- const Decimal = runtime.Decimal;
110
- const getExtensionContext = runtime.Extensions.getExtensionContext;
111
- const NullTypes = {
112
- DbNull: runtime.NullTypes.DbNull,
113
- JsonNull: runtime.NullTypes.JsonNull,
114
- AnyNull: runtime.NullTypes.AnyNull
115
- };
116
- /**
117
- * Helper for filtering JSON entries that have `null` on the database (empty on the db)
118
- *
119
- * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
120
- */
121
- const DbNull = runtime.DbNull;
122
- /**
123
- * Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
124
- *
125
- * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
126
- */
127
- const JsonNull = runtime.JsonNull;
128
- /**
129
- * Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
130
- *
131
- * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
132
- */
133
- const AnyNull = runtime.AnyNull;
134
- /**
135
- * Enums
136
- */
137
- const TransactionIsolationLevel = runtime.makeStrictEnum({
138
- ReadUncommitted: "ReadUncommitted",
139
- ReadCommitted: "ReadCommitted",
140
- RepeatableRead: "RepeatableRead",
141
- Serializable: "Serializable"
142
- });
143
- const defineExtension = runtime.Extensions.defineExtension;
144
-
145
87
  //#endregion
146
88
  //#region src/generated/prisma/client.ts
147
89
  globalThis["__dirname"] = path$1.dirname(fileURLToPath(import.meta.url));
@@ -162,225 +104,9 @@ globalThis["__dirname"] = path$1.dirname(fileURLToPath(import.meta.url));
162
104
  */
163
105
  const PrismaClient = getPrismaClientClass();
164
106
 
165
- //#endregion
166
- //#region ../../node_modules/.pnpm/@prisma+debug@7.4.2/node_modules/@prisma/debug/dist/index.mjs
167
- var __defProp = Object.defineProperty;
168
- var __export = (target, all) => {
169
- for (var name$1 in all) __defProp(target, name$1, {
170
- get: all[name$1],
171
- enumerable: true
172
- });
173
- };
174
- var colors_exports = {};
175
- __export(colors_exports, {
176
- $: () => $,
177
- bgBlack: () => bgBlack,
178
- bgBlue: () => bgBlue,
179
- bgCyan: () => bgCyan,
180
- bgGreen: () => bgGreen,
181
- bgMagenta: () => bgMagenta,
182
- bgRed: () => bgRed,
183
- bgWhite: () => bgWhite,
184
- bgYellow: () => bgYellow,
185
- black: () => black,
186
- blue: () => blue,
187
- bold: () => bold,
188
- cyan: () => cyan,
189
- dim: () => dim,
190
- gray: () => gray,
191
- green: () => green,
192
- grey: () => grey,
193
- hidden: () => hidden,
194
- inverse: () => inverse,
195
- italic: () => italic,
196
- magenta: () => magenta,
197
- red: () => red,
198
- reset: () => reset,
199
- strikethrough: () => strikethrough,
200
- underline: () => underline,
201
- white: () => white,
202
- yellow: () => yellow
203
- });
204
- var FORCE_COLOR;
205
- var NODE_DISABLE_COLORS;
206
- var NO_COLOR;
207
- var TERM;
208
- var isTTY = true;
209
- if (typeof process !== "undefined") {
210
- ({FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM} = process.env || {});
211
- isTTY = process.stdout && process.stdout.isTTY;
212
- }
213
- var $ = { enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY) };
214
- function init$2(x, y) {
215
- let rgx = new RegExp(`\\x1b\\[${y}m`, "g");
216
- let open = `\x1B[${x}m`, close$1 = `\x1B[${y}m`;
217
- return function(txt) {
218
- if (!$.enabled || txt == null) return txt;
219
- return open + (!!~("" + txt).indexOf(close$1) ? txt.replace(rgx, close$1 + open) : txt) + close$1;
220
- };
221
- }
222
- var reset = init$2(0, 0);
223
- var bold = init$2(1, 22);
224
- var dim = init$2(2, 22);
225
- var italic = init$2(3, 23);
226
- var underline = init$2(4, 24);
227
- var inverse = init$2(7, 27);
228
- var hidden = init$2(8, 28);
229
- var strikethrough = init$2(9, 29);
230
- var black = init$2(30, 39);
231
- var red = init$2(31, 39);
232
- var green = init$2(32, 39);
233
- var yellow = init$2(33, 39);
234
- var blue = init$2(34, 39);
235
- var magenta = init$2(35, 39);
236
- var cyan = init$2(36, 39);
237
- var white = init$2(37, 39);
238
- var gray = init$2(90, 39);
239
- var grey = init$2(90, 39);
240
- var bgBlack = init$2(40, 49);
241
- var bgRed = init$2(41, 49);
242
- var bgGreen = init$2(42, 49);
243
- var bgYellow = init$2(43, 49);
244
- var bgBlue = init$2(44, 49);
245
- var bgMagenta = init$2(45, 49);
246
- var bgCyan = init$2(46, 49);
247
- var bgWhite = init$2(47, 49);
248
- var MAX_ARGS_HISTORY = 100;
249
- var COLORS = [
250
- "green",
251
- "yellow",
252
- "blue",
253
- "magenta",
254
- "cyan",
255
- "red"
256
- ];
257
- var argsHistory = [];
258
- var lastTimestamp = Date.now();
259
- var lastColor = 0;
260
- var processEnv = typeof process !== "undefined" ? process.env : {};
261
- globalThis.DEBUG ??= processEnv.DEBUG ?? "";
262
- globalThis.DEBUG_COLORS ??= processEnv.DEBUG_COLORS ? processEnv.DEBUG_COLORS === "true" : true;
263
- var topProps = {
264
- enable(namespace) {
265
- if (typeof namespace === "string") globalThis.DEBUG = namespace;
266
- },
267
- disable() {
268
- const prev = globalThis.DEBUG;
269
- globalThis.DEBUG = "";
270
- return prev;
271
- },
272
- enabled(namespace) {
273
- const listenedNamespaces = globalThis.DEBUG.split(",").map((s) => {
274
- return s.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
275
- });
276
- const isListened = listenedNamespaces.some((listenedNamespace) => {
277
- if (listenedNamespace === "" || listenedNamespace[0] === "-") return false;
278
- return namespace.match(RegExp(listenedNamespace.split("*").join(".*") + "$"));
279
- });
280
- const isExcluded = listenedNamespaces.some((listenedNamespace) => {
281
- if (listenedNamespace === "" || listenedNamespace[0] !== "-") return false;
282
- return namespace.match(RegExp(listenedNamespace.slice(1).split("*").join(".*") + "$"));
283
- });
284
- return isListened && !isExcluded;
285
- },
286
- log: (...args) => {
287
- const [namespace, format, ...rest] = args;
288
- (console.warn ?? console.log)(`${namespace} ${format}`, ...rest);
289
- },
290
- formatters: {}
291
- };
292
- function debugCreate(namespace) {
293
- const instanceProps = {
294
- color: COLORS[lastColor++ % COLORS.length],
295
- enabled: topProps.enabled(namespace),
296
- namespace,
297
- log: topProps.log,
298
- extend: () => {}
299
- };
300
- const debugCall = (...args) => {
301
- const { enabled, namespace: namespace2, color, log } = instanceProps;
302
- if (args.length !== 0) argsHistory.push([namespace2, ...args]);
303
- if (argsHistory.length > MAX_ARGS_HISTORY) argsHistory.shift();
304
- if (topProps.enabled(namespace2) || enabled) {
305
- const stringArgs = args.map((arg) => {
306
- if (typeof arg === "string") return arg;
307
- return safeStringify(arg);
308
- });
309
- const ms = `+${Date.now() - lastTimestamp}ms`;
310
- lastTimestamp = Date.now();
311
- if (globalThis.DEBUG_COLORS) log(colors_exports[color](bold(namespace2)), ...stringArgs, colors_exports[color](ms));
312
- else log(namespace2, ...stringArgs, ms);
313
- }
314
- };
315
- return new Proxy(debugCall, {
316
- get: (_, prop) => instanceProps[prop],
317
- set: (_, prop, value) => instanceProps[prop] = value
318
- });
319
- }
320
- var Debug = new Proxy(debugCreate, {
321
- get: (_, prop) => topProps[prop],
322
- set: (_, prop, value) => topProps[prop] = value
323
- });
324
- function safeStringify(value, indent = 2) {
325
- const cache = /* @__PURE__ */ new Set();
326
- return JSON.stringify(value, (key, value2) => {
327
- if (typeof value2 === "object" && value2 !== null) {
328
- if (cache.has(value2)) return `[Circular *]`;
329
- cache.add(value2);
330
- } else if (typeof value2 === "bigint") return value2.toString();
331
- return value2;
332
- }, indent);
333
- }
334
-
335
- //#endregion
336
- //#region ../../node_modules/.pnpm/@prisma+driver-adapter-utils@7.4.2/node_modules/@prisma/driver-adapter-utils/dist/index.mjs
337
- var DriverAdapterError = class extends Error {
338
- name = "DriverAdapterError";
339
- cause;
340
- constructor(payload) {
341
- super(typeof payload["message"] === "string" ? payload["message"] : payload.kind);
342
- this.cause = payload;
343
- }
344
- };
345
- var debug$1 = Debug("driver-adapter-utils");
346
- var ColumnTypeEnum = {
347
- Int32: 0,
348
- Int64: 1,
349
- Float: 2,
350
- Double: 3,
351
- Numeric: 4,
352
- Boolean: 5,
353
- Character: 6,
354
- Text: 7,
355
- Date: 8,
356
- Time: 9,
357
- DateTime: 10,
358
- Json: 11,
359
- Enum: 12,
360
- Bytes: 13,
361
- Set: 14,
362
- Uuid: 15,
363
- Int32Array: 64,
364
- Int64Array: 65,
365
- FloatArray: 66,
366
- DoubleArray: 67,
367
- NumericArray: 68,
368
- BooleanArray: 69,
369
- CharacterArray: 70,
370
- TextArray: 71,
371
- DateArray: 72,
372
- TimeArray: 73,
373
- DateTimeArray: 74,
374
- JsonArray: 75,
375
- EnumArray: 76,
376
- BytesArray: 77,
377
- UuidArray: 78,
378
- UnknownNumber: 128
379
- };
380
-
381
107
  //#endregion
382
108
  //#region ../../node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js
383
- var require_postgres_array$1 = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js": ((exports) => {
109
+ var require_postgres_array = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js": ((exports) => {
384
110
  exports.parse = function(source, transform$1) {
385
111
  return new ArrayParser(source, transform$1).parse();
386
112
  };
@@ -461,7 +187,7 @@ var require_postgres_array$1 = /* @__PURE__ */ __commonJS({ "../../node_modules/
461
187
  //#endregion
462
188
  //#region ../../node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js
463
189
  var require_arrayParser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js": ((exports, module) => {
464
- var array$1 = require_postgres_array$1();
190
+ var array$1 = require_postgres_array();
465
191
  module.exports = { create: function(source, transform$1) {
466
192
  return { parse: function() {
467
193
  return array$1.parse(source, transform$1);
@@ -549,9 +275,9 @@ var require_mutable = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/xte
549
275
  var require_postgres_interval = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/postgres-interval@1.2.0/node_modules/postgres-interval/index.js": ((exports, module) => {
550
276
  var extend = require_mutable();
551
277
  module.exports = PostgresInterval;
552
- function PostgresInterval(raw$1) {
553
- if (!(this instanceof PostgresInterval)) return new PostgresInterval(raw$1);
554
- extend(this, parse$5(raw$1));
278
+ function PostgresInterval(raw) {
279
+ if (!(this instanceof PostgresInterval)) return new PostgresInterval(raw);
280
+ extend(this, parse$5(raw));
555
281
  }
556
282
  var properties = [
557
283
  "seconds",
@@ -673,7 +399,7 @@ var require_postgres_bytea = /* @__PURE__ */ __commonJS({ "../../node_modules/.p
673
399
  //#endregion
674
400
  //#region ../../node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js
675
401
  var require_textParsers = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js": ((exports, module) => {
676
- var array = require_postgres_array$1();
402
+ var array = require_postgres_array();
677
403
  var arrayParser$1 = require_arrayParser();
678
404
  var parseDate$1 = require_postgres_date();
679
405
  var parseInterval = require_postgres_interval();
@@ -981,13 +707,13 @@ var require_binaryParsers = /* @__PURE__ */ __commonJS({ "../../node_modules/.pn
981
707
  };
982
708
  return result;
983
709
  };
984
- var parseArray$2 = function(value) {
985
- var dim$1 = parseBits(value, 32);
710
+ var parseArray = function(value) {
711
+ var dim = parseBits(value, 32);
986
712
  parseBits(value, 32, 32);
987
713
  var elementType = parseBits(value, 32, 64);
988
714
  var offset = 96;
989
715
  var dims = [];
990
- for (var i = 0; i < dim$1; i++) {
716
+ for (var i = 0; i < dim; i++) {
991
717
  dims[i] = parseBits(value, 32, offset);
992
718
  offset += 32;
993
719
  offset += 32;
@@ -1036,11 +762,11 @@ var require_binaryParsers = /* @__PURE__ */ __commonJS({ "../../node_modules/.pn
1036
762
  register(16, parseBool);
1037
763
  register(1114, parseDate.bind(null, false));
1038
764
  register(1184, parseDate.bind(null, true));
1039
- register(1e3, parseArray$2);
1040
- register(1007, parseArray$2);
1041
- register(1016, parseArray$2);
1042
- register(1008, parseArray$2);
1043
- register(1009, parseArray$2);
765
+ register(1e3, parseArray);
766
+ register(1007, parseArray);
767
+ register(1016, parseArray);
768
+ register(1008, parseArray);
769
+ register(1009, parseArray);
1044
770
  register(25, parseText);
1045
771
  };
1046
772
  module.exports = { init };
@@ -1130,7 +856,7 @@ var require_pg_types = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg
1130
856
  var binaryParsers = require_binaryParsers();
1131
857
  var arrayParser = require_arrayParser();
1132
858
  var builtinTypes = require_builtins();
1133
- exports.getTypeParser = getTypeParser$1;
859
+ exports.getTypeParser = getTypeParser;
1134
860
  exports.setTypeParser = setTypeParser;
1135
861
  exports.arrayParser = arrayParser;
1136
862
  exports.builtins = builtinTypes;
@@ -1141,7 +867,7 @@ var require_pg_types = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg
1141
867
  function noParse(val$1) {
1142
868
  return String(val$1);
1143
869
  }
1144
- function getTypeParser$1(oid, format) {
870
+ function getTypeParser(oid, format) {
1145
871
  format = format || "text";
1146
872
  if (!typeParsers[format]) return noParse;
1147
873
  return typeParsers[format][oid] || noParse;
@@ -1663,9 +1389,9 @@ var require_sasl = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg@8.2
1663
1389
  //#endregion
1664
1390
  //#region ../../node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js
1665
1391
  var require_type_overrides = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js": ((exports, module) => {
1666
- const types$3 = require_pg_types();
1392
+ const types$2 = require_pg_types();
1667
1393
  function TypeOverrides$4(userTypes) {
1668
- this._types = userTypes || types$3;
1394
+ this._types = userTypes || types$2;
1669
1395
  this.text = {};
1670
1396
  this.binary = {};
1671
1397
  }
@@ -1917,17 +1643,17 @@ var require_connection_parameters = /* @__PURE__ */ __commonJS({ "../../node_mod
1917
1643
  //#endregion
1918
1644
  //#region ../../node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js
1919
1645
  var require_result = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js": ((exports, module) => {
1920
- const types$2 = require_pg_types();
1646
+ const types$1 = require_pg_types();
1921
1647
  const matchRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/;
1922
1648
  var Result$3 = class {
1923
- constructor(rowMode, types$4) {
1649
+ constructor(rowMode, types$3) {
1924
1650
  this.command = null;
1925
1651
  this.rowCount = null;
1926
1652
  this.oid = null;
1927
1653
  this.rows = [];
1928
1654
  this.fields = [];
1929
1655
  this._parsers = void 0;
1930
- this._types = types$4;
1656
+ this._types = types$3;
1931
1657
  this.RowCtor = null;
1932
1658
  this.rowAsArray = rowMode === "array";
1933
1659
  if (this.rowAsArray) this.parseRow = this._parseRowAsArray;
@@ -1977,7 +1703,7 @@ var require_result = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg@8
1977
1703
  const desc = fieldDescriptions[i];
1978
1704
  row[desc.name] = null;
1979
1705
  if (this._types) this._parsers[i] = this._types.getTypeParser(desc.dataTypeID, desc.format || "text");
1980
- else this._parsers[i] = types$2.getTypeParser(desc.dataTypeID, desc.format || "text");
1706
+ else this._parsers[i] = types$1.getTypeParser(desc.dataTypeID, desc.format || "text");
1981
1707
  }
1982
1708
  this._prebuiltEmptyResultObject = { ...row };
1983
1709
  }
@@ -2168,10 +1894,10 @@ var require_messages = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg
2168
1894
  length: 4
2169
1895
  };
2170
1896
  var DatabaseError$2 = class extends Error {
2171
- constructor(message, length, name$1) {
1897
+ constructor(message, length, name) {
2172
1898
  super(message);
2173
1899
  this.length = length;
2174
- this.name = name$1;
1900
+ this.name = name;
2175
1901
  }
2176
1902
  };
2177
1903
  exports.DatabaseError = DatabaseError$2;
@@ -2184,17 +1910,17 @@ var require_messages = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg
2184
1910
  };
2185
1911
  exports.CopyDataMessage = CopyDataMessage;
2186
1912
  var CopyResponse = class {
2187
- constructor(length, name$1, binary, columnCount) {
1913
+ constructor(length, name, binary, columnCount) {
2188
1914
  this.length = length;
2189
- this.name = name$1;
1915
+ this.name = name;
2190
1916
  this.binary = binary;
2191
1917
  this.columnTypes = new Array(columnCount);
2192
1918
  }
2193
1919
  };
2194
1920
  exports.CopyResponse = CopyResponse;
2195
1921
  var Field = class {
2196
- constructor(name$1, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, format) {
2197
- this.name = name$1;
1922
+ constructor(name, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, format) {
1923
+ this.name = name;
2198
1924
  this.tableID = tableID;
2199
1925
  this.columnID = columnID;
2200
1926
  this.dataTypeID = dataTypeID;
@@ -2406,16 +2132,16 @@ var require_serializer = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/
2406
2132
  };
2407
2133
  const emptyArray = [];
2408
2134
  const parse$2 = (query$1) => {
2409
- const name$1 = query$1.name || "";
2410
- if (name$1.length > 63) {
2135
+ const name = query$1.name || "";
2136
+ if (name.length > 63) {
2411
2137
  console.error("Warning! Postgres only supports 63 characters for query names.");
2412
- console.error("You supplied %s (%s)", name$1, name$1.length);
2138
+ console.error("You supplied %s (%s)", name, name.length);
2413
2139
  console.error("This can cause conflicts and silent errors executing queries");
2414
2140
  }
2415
- const types$4 = query$1.types || emptyArray;
2416
- const len = types$4.length;
2417
- const buffer = writer.addCString(name$1).addCString(query$1.text).addInt16(len);
2418
- for (let i = 0; i < len; i++) buffer.addInt32(types$4[i]);
2141
+ const types$3 = query$1.types || emptyArray;
2142
+ const len = types$3.length;
2143
+ const buffer = writer.addCString(name).addCString(query$1.text).addInt16(len);
2144
+ for (let i = 0; i < len; i++) buffer.addInt32(types$3[i]);
2419
2145
  return writer.flush(80);
2420
2146
  };
2421
2147
  const paramWriter = new buffer_writer_1.Writer();
@@ -2777,14 +2503,14 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-p
2777
2503
  return message;
2778
2504
  };
2779
2505
  const parseField = (reader) => {
2780
- const name$1 = reader.cstring();
2506
+ const name = reader.cstring();
2781
2507
  const tableID = reader.uint32();
2782
2508
  const columnID = reader.int16();
2783
2509
  const dataTypeID = reader.uint32();
2784
2510
  const dataTypeSize = reader.int16();
2785
2511
  const dataTypeModifier = reader.int32();
2786
2512
  const mode = reader.int16() === 0 ? "text" : "binary";
2787
- return new messages_1$1.Field(name$1, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, mode);
2513
+ return new messages_1$1.Field(name, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, mode);
2788
2514
  };
2789
2515
  const parseParameterDescriptionMessage = (reader) => {
2790
2516
  const parameterCount = reader.int16();
@@ -2802,9 +2528,9 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-p
2802
2528
  return new messages_1$1.DataRowMessage(LATEINIT_LENGTH, fields);
2803
2529
  };
2804
2530
  const parseParameterStatusMessage = (reader) => {
2805
- const name$1 = reader.cstring();
2531
+ const name = reader.cstring();
2806
2532
  const value = reader.cstring();
2807
- return new messages_1$1.ParameterStatusMessage(LATEINIT_LENGTH, name$1, value);
2533
+ return new messages_1$1.ParameterStatusMessage(LATEINIT_LENGTH, name, value);
2808
2534
  };
2809
2535
  const parseBackendKeyData = (reader) => {
2810
2536
  const processID = reader.int32();
@@ -2852,7 +2578,7 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-p
2852
2578
  }
2853
2579
  return message;
2854
2580
  };
2855
- const parseErrorMessage = (reader, name$1) => {
2581
+ const parseErrorMessage = (reader, name) => {
2856
2582
  const fields = {};
2857
2583
  let fieldType = reader.string(1);
2858
2584
  while (fieldType !== "\0") {
@@ -2860,7 +2586,7 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pg-p
2860
2586
  fieldType = reader.string(1);
2861
2587
  }
2862
2588
  const messageValue = fields.M;
2863
- const message = name$1 === "notice" ? new messages_1$1.NoticeMessage(LATEINIT_LENGTH, messageValue) : new messages_1$1.DatabaseError(messageValue, LATEINIT_LENGTH, name$1);
2589
+ const message = name === "notice" ? new messages_1$1.NoticeMessage(LATEINIT_LENGTH, messageValue) : new messages_1$1.DatabaseError(messageValue, LATEINIT_LENGTH, name);
2864
2590
  message.severity = fields.S;
2865
2591
  message.code = fields.C;
2866
2592
  message.detail = fields.D;
@@ -4620,7 +4346,7 @@ var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
4620
4346
  const Client = import_lib.default.Client;
4621
4347
  const Pool = import_lib.default.Pool;
4622
4348
  const Connection = import_lib.default.Connection;
4623
- const types$1 = import_lib.default.types;
4349
+ const types = import_lib.default.types;
4624
4350
  const Query = import_lib.default.Query;
4625
4351
  const DatabaseError = import_lib.default.DatabaseError;
4626
4352
  const escapeIdentifier = import_lib.default.escapeIdentifier;
@@ -4630,764 +4356,6 @@ const TypeOverrides = import_lib.default.TypeOverrides;
4630
4356
  const defaults = import_lib.default.defaults;
4631
4357
  var esm_default = import_lib.default;
4632
4358
 
4633
- //#endregion
4634
- //#region ../../node_modules/.pnpm/postgres-array@3.0.4/node_modules/postgres-array/index.js
4635
- var require_postgres_array = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/postgres-array@3.0.4/node_modules/postgres-array/index.js": ((exports) => {
4636
- const BACKSLASH = "\\";
4637
- const DQUOT = "\"";
4638
- const LBRACE = "{";
4639
- const RBRACE = "}";
4640
- const LBRACKET = "[";
4641
- const EQUALS = "=";
4642
- const COMMA = ",";
4643
- /** When the raw value is this, it means a literal `null` */
4644
- const NULL_STRING = "NULL";
4645
- /**
4646
- * Parses an array according to
4647
- * https://www.postgresql.org/docs/17/arrays.html#ARRAYS-IO
4648
- *
4649
- * Trusts the data (mostly), so only hook up to trusted Postgres servers.
4650
- */
4651
- function makeParseArrayWithTransform(transform$1) {
4652
- const haveTransform = transform$1 != null;
4653
- return function parseArray$3(str) {
4654
- const rbraceIndex = str.length - 1;
4655
- if (rbraceIndex === 1) return [];
4656
- if (str[rbraceIndex] !== RBRACE) throw new Error("Invalid array text - must end with }");
4657
- let position = 0;
4658
- if (str[position] === LBRACKET) position = str.indexOf(EQUALS) + 1;
4659
- if (str[position++] !== LBRACE) throw new Error("Invalid array text - must start with {");
4660
- const output = [];
4661
- let current = output;
4662
- const stack = [];
4663
- let currentStringStart = position;
4664
- let currentString = "";
4665
- let expectValue = true;
4666
- for (; position < rbraceIndex; ++position) {
4667
- let char = str[position];
4668
- if (char === DQUOT) {
4669
- currentStringStart = ++position;
4670
- let dquot = str.indexOf(DQUOT, currentStringStart);
4671
- let backSlash = str.indexOf(BACKSLASH, currentStringStart);
4672
- while (backSlash !== -1 && backSlash < dquot) {
4673
- position = backSlash;
4674
- const part$1 = str.slice(currentStringStart, position);
4675
- currentString += part$1;
4676
- currentStringStart = ++position;
4677
- if (dquot === position++) dquot = str.indexOf(DQUOT, position);
4678
- backSlash = str.indexOf(BACKSLASH, position);
4679
- }
4680
- position = dquot;
4681
- const part = str.slice(currentStringStart, position);
4682
- currentString += part;
4683
- current.push(haveTransform ? transform$1(currentString) : currentString);
4684
- currentString = "";
4685
- expectValue = false;
4686
- } else if (char === LBRACE) {
4687
- const newArray = [];
4688
- current.push(newArray);
4689
- stack.push(current);
4690
- current = newArray;
4691
- currentStringStart = position + 1;
4692
- expectValue = true;
4693
- } else if (char === COMMA) expectValue = true;
4694
- else if (char === RBRACE) {
4695
- expectValue = false;
4696
- const arr = stack.pop();
4697
- if (arr === void 0) throw new Error("Invalid array text - too many '}'");
4698
- current = arr;
4699
- } else if (expectValue) {
4700
- currentStringStart = position;
4701
- while ((char = str[position]) !== COMMA && char !== RBRACE && position < rbraceIndex) ++position;
4702
- const part = str.slice(currentStringStart, position--);
4703
- current.push(part === NULL_STRING ? null : haveTransform ? transform$1(part) : part);
4704
- expectValue = false;
4705
- } else throw new Error("Was expecting delimeter");
4706
- }
4707
- return output;
4708
- };
4709
- }
4710
- const parseArray$1 = makeParseArrayWithTransform();
4711
- exports.parse = (source, transform$1) => transform$1 != null ? makeParseArrayWithTransform(transform$1)(source) : parseArray$1(source);
4712
- }) });
4713
-
4714
- //#endregion
4715
- //#region ../../node_modules/.pnpm/@prisma+adapter-pg@7.4.2/node_modules/@prisma/adapter-pg/dist/index.mjs
4716
- var import_postgres_array = /* @__PURE__ */ __toESM(require_postgres_array(), 1);
4717
- var name = "@prisma/adapter-pg";
4718
- var FIRST_NORMAL_OBJECT_ID = 16384;
4719
- var { types } = esm_default;
4720
- var { builtins: ScalarColumnType, getTypeParser } = types;
4721
- var AdditionalScalarColumnType = { NAME: 19 };
4722
- var ArrayColumnType = {
4723
- BIT_ARRAY: 1561,
4724
- BOOL_ARRAY: 1e3,
4725
- BYTEA_ARRAY: 1001,
4726
- BPCHAR_ARRAY: 1014,
4727
- CHAR_ARRAY: 1002,
4728
- CIDR_ARRAY: 651,
4729
- DATE_ARRAY: 1182,
4730
- FLOAT4_ARRAY: 1021,
4731
- FLOAT8_ARRAY: 1022,
4732
- INET_ARRAY: 1041,
4733
- INT2_ARRAY: 1005,
4734
- INT4_ARRAY: 1007,
4735
- INT8_ARRAY: 1016,
4736
- JSONB_ARRAY: 3807,
4737
- JSON_ARRAY: 199,
4738
- MONEY_ARRAY: 791,
4739
- NUMERIC_ARRAY: 1231,
4740
- OID_ARRAY: 1028,
4741
- TEXT_ARRAY: 1009,
4742
- TIMESTAMP_ARRAY: 1115,
4743
- TIMESTAMPTZ_ARRAY: 1185,
4744
- TIME_ARRAY: 1183,
4745
- UUID_ARRAY: 2951,
4746
- VARBIT_ARRAY: 1563,
4747
- VARCHAR_ARRAY: 1015,
4748
- XML_ARRAY: 143
4749
- };
4750
- var UnsupportedNativeDataType = class _UnsupportedNativeDataType extends Error {
4751
- static typeNames = {
4752
- 16: "bool",
4753
- 17: "bytea",
4754
- 18: "char",
4755
- 19: "name",
4756
- 20: "int8",
4757
- 21: "int2",
4758
- 22: "int2vector",
4759
- 23: "int4",
4760
- 24: "regproc",
4761
- 25: "text",
4762
- 26: "oid",
4763
- 27: "tid",
4764
- 28: "xid",
4765
- 29: "cid",
4766
- 30: "oidvector",
4767
- 32: "pg_ddl_command",
4768
- 71: "pg_type",
4769
- 75: "pg_attribute",
4770
- 81: "pg_proc",
4771
- 83: "pg_class",
4772
- 114: "json",
4773
- 142: "xml",
4774
- 194: "pg_node_tree",
4775
- 269: "table_am_handler",
4776
- 325: "index_am_handler",
4777
- 600: "point",
4778
- 601: "lseg",
4779
- 602: "path",
4780
- 603: "box",
4781
- 604: "polygon",
4782
- 628: "line",
4783
- 650: "cidr",
4784
- 700: "float4",
4785
- 701: "float8",
4786
- 705: "unknown",
4787
- 718: "circle",
4788
- 774: "macaddr8",
4789
- 790: "money",
4790
- 829: "macaddr",
4791
- 869: "inet",
4792
- 1033: "aclitem",
4793
- 1042: "bpchar",
4794
- 1043: "varchar",
4795
- 1082: "date",
4796
- 1083: "time",
4797
- 1114: "timestamp",
4798
- 1184: "timestamptz",
4799
- 1186: "interval",
4800
- 1266: "timetz",
4801
- 1560: "bit",
4802
- 1562: "varbit",
4803
- 1700: "numeric",
4804
- 1790: "refcursor",
4805
- 2202: "regprocedure",
4806
- 2203: "regoper",
4807
- 2204: "regoperator",
4808
- 2205: "regclass",
4809
- 2206: "regtype",
4810
- 2249: "record",
4811
- 2275: "cstring",
4812
- 2276: "any",
4813
- 2277: "anyarray",
4814
- 2278: "void",
4815
- 2279: "trigger",
4816
- 2280: "language_handler",
4817
- 2281: "internal",
4818
- 2283: "anyelement",
4819
- 2287: "_record",
4820
- 2776: "anynonarray",
4821
- 2950: "uuid",
4822
- 2970: "txid_snapshot",
4823
- 3115: "fdw_handler",
4824
- 3220: "pg_lsn",
4825
- 3310: "tsm_handler",
4826
- 3361: "pg_ndistinct",
4827
- 3402: "pg_dependencies",
4828
- 3500: "anyenum",
4829
- 3614: "tsvector",
4830
- 3615: "tsquery",
4831
- 3642: "gtsvector",
4832
- 3734: "regconfig",
4833
- 3769: "regdictionary",
4834
- 3802: "jsonb",
4835
- 3831: "anyrange",
4836
- 3838: "event_trigger",
4837
- 3904: "int4range",
4838
- 3906: "numrange",
4839
- 3908: "tsrange",
4840
- 3910: "tstzrange",
4841
- 3912: "daterange",
4842
- 3926: "int8range",
4843
- 4072: "jsonpath",
4844
- 4089: "regnamespace",
4845
- 4096: "regrole",
4846
- 4191: "regcollation",
4847
- 4451: "int4multirange",
4848
- 4532: "nummultirange",
4849
- 4533: "tsmultirange",
4850
- 4534: "tstzmultirange",
4851
- 4535: "datemultirange",
4852
- 4536: "int8multirange",
4853
- 4537: "anymultirange",
4854
- 4538: "anycompatiblemultirange",
4855
- 4600: "pg_brin_bloom_summary",
4856
- 4601: "pg_brin_minmax_multi_summary",
4857
- 5017: "pg_mcv_list",
4858
- 5038: "pg_snapshot",
4859
- 5069: "xid8",
4860
- 5077: "anycompatible",
4861
- 5078: "anycompatiblearray",
4862
- 5079: "anycompatiblenonarray",
4863
- 5080: "anycompatiblerange"
4864
- };
4865
- type;
4866
- constructor(code) {
4867
- super();
4868
- this.type = _UnsupportedNativeDataType.typeNames[code] || "Unknown";
4869
- this.message = `Unsupported column type ${this.type}`;
4870
- }
4871
- };
4872
- function fieldToColumnType(fieldTypeId) {
4873
- switch (fieldTypeId) {
4874
- case ScalarColumnType.INT2:
4875
- case ScalarColumnType.INT4: return ColumnTypeEnum.Int32;
4876
- case ScalarColumnType.INT8: return ColumnTypeEnum.Int64;
4877
- case ScalarColumnType.FLOAT4: return ColumnTypeEnum.Float;
4878
- case ScalarColumnType.FLOAT8: return ColumnTypeEnum.Double;
4879
- case ScalarColumnType.BOOL: return ColumnTypeEnum.Boolean;
4880
- case ScalarColumnType.DATE: return ColumnTypeEnum.Date;
4881
- case ScalarColumnType.TIME:
4882
- case ScalarColumnType.TIMETZ: return ColumnTypeEnum.Time;
4883
- case ScalarColumnType.TIMESTAMP:
4884
- case ScalarColumnType.TIMESTAMPTZ: return ColumnTypeEnum.DateTime;
4885
- case ScalarColumnType.NUMERIC:
4886
- case ScalarColumnType.MONEY: return ColumnTypeEnum.Numeric;
4887
- case ScalarColumnType.JSON:
4888
- case ScalarColumnType.JSONB: return ColumnTypeEnum.Json;
4889
- case ScalarColumnType.UUID: return ColumnTypeEnum.Uuid;
4890
- case ScalarColumnType.OID: return ColumnTypeEnum.Int64;
4891
- case ScalarColumnType.BPCHAR:
4892
- case ScalarColumnType.TEXT:
4893
- case ScalarColumnType.VARCHAR:
4894
- case ScalarColumnType.BIT:
4895
- case ScalarColumnType.VARBIT:
4896
- case ScalarColumnType.INET:
4897
- case ScalarColumnType.CIDR:
4898
- case ScalarColumnType.XML:
4899
- case AdditionalScalarColumnType.NAME: return ColumnTypeEnum.Text;
4900
- case ScalarColumnType.BYTEA: return ColumnTypeEnum.Bytes;
4901
- case ArrayColumnType.INT2_ARRAY:
4902
- case ArrayColumnType.INT4_ARRAY: return ColumnTypeEnum.Int32Array;
4903
- case ArrayColumnType.FLOAT4_ARRAY: return ColumnTypeEnum.FloatArray;
4904
- case ArrayColumnType.FLOAT8_ARRAY: return ColumnTypeEnum.DoubleArray;
4905
- case ArrayColumnType.NUMERIC_ARRAY:
4906
- case ArrayColumnType.MONEY_ARRAY: return ColumnTypeEnum.NumericArray;
4907
- case ArrayColumnType.BOOL_ARRAY: return ColumnTypeEnum.BooleanArray;
4908
- case ArrayColumnType.CHAR_ARRAY: return ColumnTypeEnum.CharacterArray;
4909
- case ArrayColumnType.BPCHAR_ARRAY:
4910
- case ArrayColumnType.TEXT_ARRAY:
4911
- case ArrayColumnType.VARCHAR_ARRAY:
4912
- case ArrayColumnType.VARBIT_ARRAY:
4913
- case ArrayColumnType.BIT_ARRAY:
4914
- case ArrayColumnType.INET_ARRAY:
4915
- case ArrayColumnType.CIDR_ARRAY:
4916
- case ArrayColumnType.XML_ARRAY: return ColumnTypeEnum.TextArray;
4917
- case ArrayColumnType.DATE_ARRAY: return ColumnTypeEnum.DateArray;
4918
- case ArrayColumnType.TIME_ARRAY: return ColumnTypeEnum.TimeArray;
4919
- case ArrayColumnType.TIMESTAMP_ARRAY: return ColumnTypeEnum.DateTimeArray;
4920
- case ArrayColumnType.TIMESTAMPTZ_ARRAY: return ColumnTypeEnum.DateTimeArray;
4921
- case ArrayColumnType.JSON_ARRAY:
4922
- case ArrayColumnType.JSONB_ARRAY: return ColumnTypeEnum.JsonArray;
4923
- case ArrayColumnType.BYTEA_ARRAY: return ColumnTypeEnum.BytesArray;
4924
- case ArrayColumnType.UUID_ARRAY: return ColumnTypeEnum.UuidArray;
4925
- case ArrayColumnType.INT8_ARRAY:
4926
- case ArrayColumnType.OID_ARRAY: return ColumnTypeEnum.Int64Array;
4927
- default:
4928
- if (fieldTypeId >= FIRST_NORMAL_OBJECT_ID) return ColumnTypeEnum.Text;
4929
- throw new UnsupportedNativeDataType(fieldTypeId);
4930
- }
4931
- }
4932
- function normalize_array(element_normalizer) {
4933
- return (str) => (0, import_postgres_array.parse)(str, element_normalizer);
4934
- }
4935
- function normalize_numeric(numeric) {
4936
- return numeric;
4937
- }
4938
- function normalize_date(date) {
4939
- return date;
4940
- }
4941
- function normalize_timestamp(time) {
4942
- return `${time.replace(" ", "T")}+00:00`;
4943
- }
4944
- function normalize_timestamptz(time) {
4945
- return time.replace(" ", "T").replace(/[+-]\d{2}(:\d{2})?$/, "+00:00");
4946
- }
4947
- function normalize_time(time) {
4948
- return time;
4949
- }
4950
- function normalize_timez(time) {
4951
- return time.replace(/[+-]\d{2}(:\d{2})?$/, "");
4952
- }
4953
- function normalize_money(money) {
4954
- return money.slice(1);
4955
- }
4956
- function normalize_xml(xml) {
4957
- return xml;
4958
- }
4959
- function toJson(json) {
4960
- return json;
4961
- }
4962
- var parsePgBytes = getTypeParser(ScalarColumnType.BYTEA);
4963
- var normalizeByteaArray = getTypeParser(ArrayColumnType.BYTEA_ARRAY);
4964
- function convertBytes(serializedBytes) {
4965
- return parsePgBytes(serializedBytes);
4966
- }
4967
- function normalizeBit(bit) {
4968
- return bit;
4969
- }
4970
- var customParsers = {
4971
- [ScalarColumnType.NUMERIC]: normalize_numeric,
4972
- [ArrayColumnType.NUMERIC_ARRAY]: normalize_array(normalize_numeric),
4973
- [ScalarColumnType.TIME]: normalize_time,
4974
- [ArrayColumnType.TIME_ARRAY]: normalize_array(normalize_time),
4975
- [ScalarColumnType.TIMETZ]: normalize_timez,
4976
- [ScalarColumnType.DATE]: normalize_date,
4977
- [ArrayColumnType.DATE_ARRAY]: normalize_array(normalize_date),
4978
- [ScalarColumnType.TIMESTAMP]: normalize_timestamp,
4979
- [ArrayColumnType.TIMESTAMP_ARRAY]: normalize_array(normalize_timestamp),
4980
- [ScalarColumnType.TIMESTAMPTZ]: normalize_timestamptz,
4981
- [ArrayColumnType.TIMESTAMPTZ_ARRAY]: normalize_array(normalize_timestamptz),
4982
- [ScalarColumnType.MONEY]: normalize_money,
4983
- [ArrayColumnType.MONEY_ARRAY]: normalize_array(normalize_money),
4984
- [ScalarColumnType.JSON]: toJson,
4985
- [ArrayColumnType.JSON_ARRAY]: normalize_array(toJson),
4986
- [ScalarColumnType.JSONB]: toJson,
4987
- [ArrayColumnType.JSONB_ARRAY]: normalize_array(toJson),
4988
- [ScalarColumnType.BYTEA]: convertBytes,
4989
- [ArrayColumnType.BYTEA_ARRAY]: normalizeByteaArray,
4990
- [ArrayColumnType.BIT_ARRAY]: normalize_array(normalizeBit),
4991
- [ArrayColumnType.VARBIT_ARRAY]: normalize_array(normalizeBit),
4992
- [ArrayColumnType.XML_ARRAY]: normalize_array(normalize_xml)
4993
- };
4994
- function mapArg(arg, argType) {
4995
- if (arg === null) return null;
4996
- if (Array.isArray(arg) && argType.arity === "list") return arg.map((value) => mapArg(value, argType));
4997
- if (typeof arg === "string" && argType.scalarType === "datetime") arg = new Date(arg);
4998
- if (arg instanceof Date) switch (argType.dbType) {
4999
- case "TIME":
5000
- case "TIMETZ": return formatTime(arg);
5001
- case "DATE": return formatDate(arg);
5002
- default: return formatDateTime(arg);
5003
- }
5004
- if (typeof arg === "string" && argType.scalarType === "bytes") return Buffer.from(arg, "base64");
5005
- if (ArrayBuffer.isView(arg)) return new Uint8Array(arg.buffer, arg.byteOffset, arg.byteLength);
5006
- return arg;
5007
- }
5008
- function formatDateTime(date) {
5009
- const pad = (n, z$1 = 2) => String(n).padStart(z$1, "0");
5010
- const ms = date.getUTCMilliseconds();
5011
- return pad(date.getUTCFullYear(), 4) + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate()) + " " + pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
5012
- }
5013
- function formatDate(date) {
5014
- const pad = (n, z$1 = 2) => String(n).padStart(z$1, "0");
5015
- return pad(date.getUTCFullYear(), 4) + "-" + pad(date.getUTCMonth() + 1) + "-" + pad(date.getUTCDate());
5016
- }
5017
- function formatTime(date) {
5018
- const pad = (n, z$1 = 2) => String(n).padStart(z$1, "0");
5019
- const ms = date.getUTCMilliseconds();
5020
- return pad(date.getUTCHours()) + ":" + pad(date.getUTCMinutes()) + ":" + pad(date.getUTCSeconds()) + (ms ? "." + String(ms).padStart(3, "0") : "");
5021
- }
5022
- var TLS_ERRORS = /* @__PURE__ */ new Set([
5023
- "UNABLE_TO_GET_ISSUER_CERT",
5024
- "UNABLE_TO_GET_CRL",
5025
- "UNABLE_TO_DECRYPT_CERT_SIGNATURE",
5026
- "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
5027
- "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",
5028
- "CERT_SIGNATURE_FAILURE",
5029
- "CRL_SIGNATURE_FAILURE",
5030
- "CERT_NOT_YET_VALID",
5031
- "CERT_HAS_EXPIRED",
5032
- "CRL_NOT_YET_VALID",
5033
- "CRL_HAS_EXPIRED",
5034
- "ERROR_IN_CERT_NOT_BEFORE_FIELD",
5035
- "ERROR_IN_CERT_NOT_AFTER_FIELD",
5036
- "ERROR_IN_CRL_LAST_UPDATE_FIELD",
5037
- "ERROR_IN_CRL_NEXT_UPDATE_FIELD",
5038
- "DEPTH_ZERO_SELF_SIGNED_CERT",
5039
- "SELF_SIGNED_CERT_IN_CHAIN",
5040
- "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
5041
- "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
5042
- "CERT_CHAIN_TOO_LONG",
5043
- "CERT_REVOKED",
5044
- "INVALID_CA",
5045
- "INVALID_PURPOSE",
5046
- "CERT_UNTRUSTED",
5047
- "CERT_REJECTED",
5048
- "HOSTNAME_MISMATCH",
5049
- "ERR_TLS_CERT_ALTNAME_FORMAT",
5050
- "ERR_TLS_CERT_ALTNAME_INVALID"
5051
- ]);
5052
- var SOCKET_ERRORS = /* @__PURE__ */ new Set([
5053
- "ENOTFOUND",
5054
- "ECONNREFUSED",
5055
- "ECONNRESET",
5056
- "ETIMEDOUT"
5057
- ]);
5058
- function convertDriverError(error) {
5059
- if (isSocketError(error)) return mapSocketError(error);
5060
- if (isTlsError(error)) return {
5061
- kind: "TlsConnectionError",
5062
- reason: error.message
5063
- };
5064
- if (isDriverError(error)) return {
5065
- originalCode: error.code,
5066
- originalMessage: error.message,
5067
- ...mapDriverError(error)
5068
- };
5069
- throw error;
5070
- }
5071
- function mapDriverError(error) {
5072
- switch (error.code) {
5073
- case "22001": return {
5074
- kind: "LengthMismatch",
5075
- column: error.column
5076
- };
5077
- case "22003": return {
5078
- kind: "ValueOutOfRange",
5079
- cause: error.message
5080
- };
5081
- case "22P02": return {
5082
- kind: "InvalidInputValue",
5083
- message: error.message
5084
- };
5085
- case "23505": {
5086
- var _error$detail;
5087
- const fields = (_error$detail = error.detail) === null || _error$detail === void 0 || (_error$detail = _error$detail.match(/Key \(([^)]+)\)/)) === null || _error$detail === void 0 || (_error$detail = _error$detail.at(1)) === null || _error$detail === void 0 ? void 0 : _error$detail.split(", ");
5088
- return {
5089
- kind: "UniqueConstraintViolation",
5090
- constraint: fields !== void 0 ? { fields } : void 0
5091
- };
5092
- }
5093
- case "23502": {
5094
- var _error$detail2;
5095
- const fields = (_error$detail2 = error.detail) === null || _error$detail2 === void 0 || (_error$detail2 = _error$detail2.match(/Key \(([^)]+)\)/)) === null || _error$detail2 === void 0 || (_error$detail2 = _error$detail2.at(1)) === null || _error$detail2 === void 0 ? void 0 : _error$detail2.split(", ");
5096
- return {
5097
- kind: "NullConstraintViolation",
5098
- constraint: fields !== void 0 ? { fields } : void 0
5099
- };
5100
- }
5101
- case "23503": {
5102
- let constraint;
5103
- if (error.column) constraint = { fields: [error.column] };
5104
- else if (error.constraint) constraint = { index: error.constraint };
5105
- return {
5106
- kind: "ForeignKeyConstraintViolation",
5107
- constraint
5108
- };
5109
- }
5110
- case "3D000":
5111
- var _error$message$split$;
5112
- return {
5113
- kind: "DatabaseDoesNotExist",
5114
- db: (_error$message$split$ = error.message.split(" ").at(1)) === null || _error$message$split$ === void 0 ? void 0 : _error$message$split$.split("\"").at(1)
5115
- };
5116
- case "28000":
5117
- var _error$message$split$2;
5118
- return {
5119
- kind: "DatabaseAccessDenied",
5120
- db: (_error$message$split$2 = error.message.split(",").find((s) => s.startsWith(" database"))) === null || _error$message$split$2 === void 0 ? void 0 : _error$message$split$2.split("\"").at(1)
5121
- };
5122
- case "28P01":
5123
- var _error$message$split$3;
5124
- return {
5125
- kind: "AuthenticationFailed",
5126
- user: (_error$message$split$3 = error.message.split(" ").pop()) === null || _error$message$split$3 === void 0 ? void 0 : _error$message$split$3.split("\"").at(1)
5127
- };
5128
- case "40001": return { kind: "TransactionWriteConflict" };
5129
- case "42P01":
5130
- var _error$message$split$4;
5131
- return {
5132
- kind: "TableDoesNotExist",
5133
- table: (_error$message$split$4 = error.message.split(" ").at(1)) === null || _error$message$split$4 === void 0 ? void 0 : _error$message$split$4.split("\"").at(1)
5134
- };
5135
- case "42703":
5136
- var _error$message$split$5;
5137
- return {
5138
- kind: "ColumnNotFound",
5139
- column: (_error$message$split$5 = error.message.split(" ").at(1)) === null || _error$message$split$5 === void 0 ? void 0 : _error$message$split$5.split("\"").at(1)
5140
- };
5141
- case "42P04":
5142
- var _error$message$split$6;
5143
- return {
5144
- kind: "DatabaseAlreadyExists",
5145
- db: (_error$message$split$6 = error.message.split(" ").at(1)) === null || _error$message$split$6 === void 0 ? void 0 : _error$message$split$6.split("\"").at(1)
5146
- };
5147
- case "53300": return {
5148
- kind: "TooManyConnections",
5149
- cause: error.message
5150
- };
5151
- default: return {
5152
- kind: "postgres",
5153
- code: error.code ?? "N/A",
5154
- severity: error.severity ?? "N/A",
5155
- message: error.message,
5156
- detail: error.detail,
5157
- column: error.column,
5158
- hint: error.hint
5159
- };
5160
- }
5161
- }
5162
- function isDriverError(error) {
5163
- return typeof error.code === "string" && typeof error.message === "string" && typeof error.severity === "string" && (typeof error.detail === "string" || error.detail === void 0) && (typeof error.column === "string" || error.column === void 0) && (typeof error.hint === "string" || error.hint === void 0);
5164
- }
5165
- function mapSocketError(error) {
5166
- switch (error.code) {
5167
- case "ENOTFOUND":
5168
- case "ECONNREFUSED": return {
5169
- kind: "DatabaseNotReachable",
5170
- host: error.address ?? error.hostname,
5171
- port: error.port
5172
- };
5173
- case "ECONNRESET": return { kind: "ConnectionClosed" };
5174
- case "ETIMEDOUT": return { kind: "SocketTimeout" };
5175
- }
5176
- }
5177
- function isSocketError(error) {
5178
- return typeof error.code === "string" && typeof error.syscall === "string" && typeof error.errno === "number" && SOCKET_ERRORS.has(error.code);
5179
- }
5180
- function isTlsError(error) {
5181
- if (typeof error.code === "string") return TLS_ERRORS.has(error.code);
5182
- switch (error.message) {
5183
- case "The server does not support SSL connections":
5184
- case "There was an error establishing an SSL connection": return true;
5185
- }
5186
- return false;
5187
- }
5188
- var types2 = esm_default.types;
5189
- var debug = Debug("prisma:driver-adapter:pg");
5190
- var PgQueryable = class {
5191
- constructor(client, pgOptions) {
5192
- this.client = client;
5193
- this.pgOptions = pgOptions;
5194
- }
5195
- provider = "postgres";
5196
- adapterName = name;
5197
- /**
5198
- * Execute a query given as SQL, interpolating the given parameters.
5199
- */
5200
- async queryRaw(query$1) {
5201
- var _this$pgOptions;
5202
- debug(`[js::query_raw] %O`, query$1);
5203
- const { fields, rows } = await this.performIO(query$1);
5204
- const columnNames = fields.map((field) => field.name);
5205
- let columnTypes = [];
5206
- try {
5207
- columnTypes = fields.map((field) => fieldToColumnType(field.dataTypeID));
5208
- } catch (e) {
5209
- if (e instanceof UnsupportedNativeDataType) throw new DriverAdapterError({
5210
- kind: "UnsupportedNativeDataType",
5211
- type: e.type
5212
- });
5213
- throw e;
5214
- }
5215
- const udtParser = (_this$pgOptions = this.pgOptions) === null || _this$pgOptions === void 0 ? void 0 : _this$pgOptions.userDefinedTypeParser;
5216
- if (udtParser) for (let i = 0; i < fields.length; i++) {
5217
- const field = fields[i];
5218
- if (field.dataTypeID >= FIRST_NORMAL_OBJECT_ID && !Object.hasOwn(customParsers, field.dataTypeID)) for (let j = 0; j < rows.length; j++) rows[j][i] = await udtParser(field.dataTypeID, rows[j][i], this);
5219
- }
5220
- return {
5221
- columnNames,
5222
- columnTypes,
5223
- rows
5224
- };
5225
- }
5226
- /**
5227
- * Execute a query given as SQL, interpolating the given parameters and
5228
- * returning the number of affected rows.
5229
- * Note: Queryable expects a u64, but napi.rs only supports u32.
5230
- */
5231
- async executeRaw(query$1) {
5232
- debug(`[js::execute_raw] %O`, query$1);
5233
- return (await this.performIO(query$1)).rowCount ?? 0;
5234
- }
5235
- /**
5236
- * Run a query against the database, returning the result set.
5237
- * Should the query fail due to a connection error, the connection is
5238
- * marked as unhealthy.
5239
- */
5240
- async performIO(query$1) {
5241
- const { sql: sql$1, args } = query$1;
5242
- const values = args.map((arg, i) => mapArg(arg, query$1.argTypes[i]));
5243
- try {
5244
- return await this.client.query({
5245
- text: sql$1,
5246
- values,
5247
- rowMode: "array",
5248
- types: { getTypeParser: (oid, format) => {
5249
- if (format === "text" && customParsers[oid]) return customParsers[oid];
5250
- return types2.getTypeParser(oid, format);
5251
- } }
5252
- }, values);
5253
- } catch (e) {
5254
- this.onError(e);
5255
- }
5256
- }
5257
- onError(error) {
5258
- debug("Error in performIO: %O", error);
5259
- throw new DriverAdapterError(convertDriverError(error));
5260
- }
5261
- };
5262
- var PgTransaction = class extends PgQueryable {
5263
- constructor(client, options, pgOptions, cleanup) {
5264
- super(client, pgOptions);
5265
- this.options = options;
5266
- this.pgOptions = pgOptions;
5267
- this.cleanup = cleanup;
5268
- }
5269
- async commit() {
5270
- var _this$cleanup;
5271
- debug(`[js::commit]`);
5272
- (_this$cleanup = this.cleanup) === null || _this$cleanup === void 0 || _this$cleanup.call(this);
5273
- this.client.release();
5274
- }
5275
- async rollback() {
5276
- var _this$cleanup2;
5277
- debug(`[js::rollback]`);
5278
- (_this$cleanup2 = this.cleanup) === null || _this$cleanup2 === void 0 || _this$cleanup2.call(this);
5279
- this.client.release();
5280
- }
5281
- };
5282
- var PrismaPgAdapter = class extends PgQueryable {
5283
- constructor(client, pgOptions, release) {
5284
- super(client);
5285
- this.pgOptions = pgOptions;
5286
- this.release = release;
5287
- }
5288
- async startTransaction(isolationLevel) {
5289
- const options = { usePhantomQuery: false };
5290
- debug("%s options: %O", "[js::startTransaction]", options);
5291
- const conn = await this.client.connect().catch((error) => this.onError(error));
5292
- const onError = (err) => {
5293
- var _this$pgOptions2, _this$pgOptions2$onCo;
5294
- debug(`Error from pool connection: ${err.message} %O`, err);
5295
- (_this$pgOptions2 = this.pgOptions) === null || _this$pgOptions2 === void 0 || (_this$pgOptions2$onCo = _this$pgOptions2.onConnectionError) === null || _this$pgOptions2$onCo === void 0 || _this$pgOptions2$onCo.call(_this$pgOptions2, err);
5296
- };
5297
- conn.on("error", onError);
5298
- const cleanup = () => {
5299
- conn.removeListener("error", onError);
5300
- };
5301
- try {
5302
- const tx = new PgTransaction(conn, options, this.pgOptions, cleanup);
5303
- await tx.executeRaw({
5304
- sql: "BEGIN",
5305
- args: [],
5306
- argTypes: []
5307
- });
5308
- if (isolationLevel) await tx.executeRaw({
5309
- sql: `SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`,
5310
- args: [],
5311
- argTypes: []
5312
- });
5313
- return tx;
5314
- } catch (error) {
5315
- cleanup();
5316
- conn.release(error);
5317
- this.onError(error);
5318
- }
5319
- }
5320
- async executeScript(script) {
5321
- const statements = script.split(";").map((stmt) => stmt.trim()).filter((stmt) => stmt.length > 0);
5322
- for (const stmt of statements) try {
5323
- await this.client.query(stmt);
5324
- } catch (error) {
5325
- this.onError(error);
5326
- }
5327
- }
5328
- getConnectionInfo() {
5329
- var _this$pgOptions3;
5330
- return {
5331
- schemaName: (_this$pgOptions3 = this.pgOptions) === null || _this$pgOptions3 === void 0 ? void 0 : _this$pgOptions3.schema,
5332
- supportsRelationJoins: true
5333
- };
5334
- }
5335
- async dispose() {
5336
- var _this$release;
5337
- return (_this$release = this.release) === null || _this$release === void 0 ? void 0 : _this$release.call(this);
5338
- }
5339
- underlyingDriver() {
5340
- return this.client;
5341
- }
5342
- };
5343
- var PrismaPgAdapterFactory = class {
5344
- constructor(poolOrConfig, options) {
5345
- this.options = options;
5346
- if (poolOrConfig instanceof esm_default.Pool) {
5347
- this.externalPool = poolOrConfig;
5348
- this.config = poolOrConfig.options;
5349
- } else {
5350
- this.externalPool = null;
5351
- this.config = poolOrConfig;
5352
- }
5353
- }
5354
- provider = "postgres";
5355
- adapterName = name;
5356
- config;
5357
- externalPool;
5358
- async connect() {
5359
- const client = this.externalPool ?? new esm_default.Pool(this.config);
5360
- const onIdleClientError = (err) => {
5361
- var _this$options, _this$options$onPoolE;
5362
- debug(`Error from idle pool client: ${err.message} %O`, err);
5363
- (_this$options = this.options) === null || _this$options === void 0 || (_this$options$onPoolE = _this$options.onPoolError) === null || _this$options$onPoolE === void 0 || _this$options$onPoolE.call(_this$options, err);
5364
- };
5365
- client.on("error", onIdleClientError);
5366
- return new PrismaPgAdapter(client, this.options, async () => {
5367
- if (this.externalPool) {
5368
- var _this$options2;
5369
- if ((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.disposeExternalPool) {
5370
- await this.externalPool.end();
5371
- this.externalPool = null;
5372
- } else this.externalPool.removeListener("error", onIdleClientError);
5373
- } else await client.end();
5374
- });
5375
- }
5376
- async connectToShadowDb() {
5377
- const conn = await this.connect();
5378
- const database = `prisma_migrate_shadow_db_${globalThis.crypto.randomUUID()}`;
5379
- await conn.executeScript(`CREATE DATABASE "${database}"`);
5380
- const client = new esm_default.Pool({
5381
- ...this.config,
5382
- database
5383
- });
5384
- return new PrismaPgAdapter(client, void 0, async () => {
5385
- await conn.executeScript(`DROP DATABASE "${database}"`);
5386
- await client.end();
5387
- });
5388
- }
5389
- };
5390
-
5391
4359
  //#endregion
5392
4360
  //#region src/db/client.ts
5393
4361
  let prismaClient = null;
@@ -5401,7 +4369,7 @@ function getDbClient() {
5401
4369
  const databaseUrl = process.env.AC_CORE_DATABASE_URL;
5402
4370
  if (!databaseUrl) throw new Error("AC_CORE_DATABASE_URL environment variable is required for PrismaClient initialization");
5403
4371
  pool = new esm_default.Pool({ connectionString: databaseUrl });
5404
- prismaClient = new PrismaClient({ adapter: new PrismaPgAdapterFactory(pool) });
4372
+ prismaClient = new PrismaClient({ adapter: new PrismaPg(pool) });
5405
4373
  }
5406
4374
  return prismaClient;
5407
4375
  }
@@ -5532,52 +4500,267 @@ async function getAppCatalogData(getAppsOptional) {
5532
4500
  }
5533
4501
 
5534
4502
  //#endregion
5535
- //#region src/db/tableSyncPrismaAdapter.ts
5536
- function getPrismaModelOperations(prisma, prismaModelName) {
5537
- return prisma[prismaModelName.slice(0, 1).toLowerCase() + prismaModelName.slice(1)];
5538
- }
5539
- function tableSyncPrisma(params) {
5540
- const { prisma, prismaModelName, uniqColumns, where: whereGlobal, upsertOnly } = params;
5541
- const prismOperations = getPrismaModelOperations(prisma, prismaModelName);
5542
- const idColumn = params.id ?? "id";
5543
- return tableSync({
5544
- id: idColumn,
5545
- uniqColumns,
5546
- readAll: async () => {
5547
- const findManyArgs = whereGlobal ? { where: whereGlobal } : {};
5548
- return await prismOperations.findMany(findManyArgs);
5549
- },
5550
- writeAll: async (createData, update, deleteIds) => {
5551
- const prismaUniqKey = params.uniqColumns.join("_");
5552
- const relationColumnList = params.relationColumns ?? [];
5553
- return prisma.$transaction(async (tx) => {
5554
- const txOps = getPrismaModelOperations(tx, prismaModelName);
5555
- for (const { data, where } of update) {
5556
- const uniqKeyWhere = Object.keys(where).length > 1 ? { [prismaUniqKey]: where } : where;
5557
- const dataScalar = omit(data, relationColumnList);
5558
- const dataRelations = mapValues(pick(data, relationColumnList), (value) => {
5559
- return { set: value };
5560
- });
5561
- await txOps.update({
5562
- data: {
5563
- ...dataScalar,
5564
- ...dataRelations
5565
- },
5566
- where: { ...uniqKeyWhere }
5567
- });
5568
- }
5569
- if (upsertOnly !== true) await txOps.deleteMany({ where: { [idColumn]: { in: deleteIds } } });
5570
- const createDataMapped = createData.map((data) => {
5571
- const dataScalar = omit(data, relationColumnList);
5572
- const dataRelations = mapValues(pick(data, relationColumnList), (value) => {
5573
- return { connect: value };
5574
- });
5575
- return {
5576
- ...dataScalar,
5577
- ...dataRelations
5578
- };
4503
+ //#region src/modules/auth/authRouter.ts
4504
+ /**
4505
+ * Create auth tRPC procedures
4506
+ * @param t - tRPC instance
4507
+ * @param auth - Better Auth instance (optional, for future extensions)
4508
+ * @returns tRPC router with auth procedures
4509
+ */
4510
+ function createAuthRouter(t$1, auth) {
4511
+ const router$1 = t$1.router;
4512
+ const publicProcedure$1 = t$1.procedure;
4513
+ return router$1({
4514
+ getSession: publicProcedure$1.query(async ({ ctx }) => {
4515
+ return {
4516
+ user: ctx.user ?? null,
4517
+ isAuthenticated: !!ctx.user
4518
+ };
4519
+ }),
4520
+ getProviders: publicProcedure$1.query(() => {
4521
+ const providers = [];
4522
+ const authOptions = auth === null || auth === void 0 ? void 0 : auth.options;
4523
+ if (authOptions === null || authOptions === void 0 ? void 0 : authOptions.socialProviders) {
4524
+ const socialProviders = authOptions.socialProviders;
4525
+ Object.keys(socialProviders).forEach((key) => {
4526
+ if (socialProviders[key]) providers.push(key);
5579
4527
  });
5580
- if (createDataMapped.length > 0) {
4528
+ }
4529
+ if (authOptions === null || authOptions === void 0 ? void 0 : authOptions.plugins) authOptions.plugins.forEach((plugin) => {
4530
+ var _pluginWithConfig$opt;
4531
+ const pluginWithConfig = plugin;
4532
+ if (pluginWithConfig.id === "generic-oauth" && ((_pluginWithConfig$opt = pluginWithConfig.options) === null || _pluginWithConfig$opt === void 0 ? void 0 : _pluginWithConfig$opt.config)) (Array.isArray(pluginWithConfig.options.config) ? pluginWithConfig.options.config : [pluginWithConfig.options.config]).forEach((config$1) => {
4533
+ if (config$1.providerId) providers.push(config$1.providerId);
4534
+ });
4535
+ });
4536
+ return { providers };
4537
+ })
4538
+ });
4539
+ }
4540
+
4541
+ //#endregion
4542
+ //#region src/modules/auth/authorizationUtils.ts
4543
+ /**
4544
+ * Extract groups from user object
4545
+ * Groups can be stored in different locations depending on the OAuth provider
4546
+ */
4547
+ function getUserGroups(user$1) {
4548
+ if (!user$1) {
4549
+ console.log("[getUserGroups] No user provided");
4550
+ return [];
4551
+ }
4552
+ console.log("[getUserGroups] === USER OBJECT DEBUG ===");
4553
+ console.log("[getUserGroups] User ID:", user$1.id);
4554
+ console.log("[getUserGroups] User email:", user$1.email);
4555
+ console.log("[getUserGroups] User.env_hopper_groups:", user$1.env_hopper_groups);
4556
+ console.log("[getUserGroups] User.groups:", user$1.groups);
4557
+ console.log("[getUserGroups] User.oktaGroups:", user$1.oktaGroups);
4558
+ console.log("[getUserGroups] User.roles:", user$1.roles);
4559
+ console.log("[getUserGroups] All user keys:", Object.keys(user$1));
4560
+ console.log("[getUserGroups] Full user object:", JSON.stringify(user$1, null, 2));
4561
+ const groups = user$1.env_hopper_groups || user$1.groups || user$1.oktaGroups || user$1.roles || [];
4562
+ const result = Array.isArray(groups) ? groups : [];
4563
+ console.log("[getUserGroups] Final groups result:", result);
4564
+ return result;
4565
+ }
4566
+ /**
4567
+ * Check if user is a member of any of the specified groups
4568
+ */
4569
+ function isMemberOfAnyGroup(user$1, allowedGroups) {
4570
+ const userGroups = getUserGroups(user$1);
4571
+ return allowedGroups.some((group$1) => userGroups.includes(group$1));
4572
+ }
4573
+ /**
4574
+ * Check if user is a member of all specified groups
4575
+ */
4576
+ function isMemberOfAllGroups(user$1, requiredGroups) {
4577
+ const userGroups = getUserGroups(user$1);
4578
+ return requiredGroups.every((group$1) => userGroups.includes(group$1));
4579
+ }
4580
+ /**
4581
+ * Check if user has admin permissions
4582
+ * @param user User object with groups
4583
+ * @param adminGroups List of admin group names (default: ['env_hopper_ui_super_admins'])
4584
+ */
4585
+ function isAdmin(user$1, adminGroups = ["env_hopper_ui_super_admins"]) {
4586
+ return isMemberOfAnyGroup(user$1, adminGroups);
4587
+ }
4588
+ /**
4589
+ * Require admin permissions - throws error if not admin
4590
+ * @param user User object with groups
4591
+ * @param adminGroups List of admin group names (default: ['env_hopper_ui_super_admins'])
4592
+ */
4593
+ function requireAdmin(user$1, adminGroups = ["env_hopper_ui_super_admins"]) {
4594
+ if (!isAdmin(user$1, adminGroups)) throw new Error("Forbidden: Admin access required");
4595
+ }
4596
+ /**
4597
+ * Require membership in specific groups - throws error if not member
4598
+ */
4599
+ function requireGroups(user$1, groups) {
4600
+ if (!isMemberOfAnyGroup(user$1, groups)) throw new Error(`Forbidden: Membership in one of these groups required: ${groups.join(", ")}`);
4601
+ }
4602
+
4603
+ //#endregion
4604
+ //#region src/server/trpcSetup.ts
4605
+ /**
4606
+ * Initialization of tRPC backend
4607
+ * Should be done only once per backend!
4608
+ */
4609
+ const t = initTRPC.context().create({ errorFormatter({ error, shape }) {
4610
+ var _data;
4611
+ console.error("[tRPC Error]", {
4612
+ path: (_data = shape.data) === null || _data === void 0 ? void 0 : _data.path,
4613
+ code: error.code,
4614
+ message: error.message,
4615
+ cause: error.cause,
4616
+ stack: error.stack
4617
+ });
4618
+ return shape;
4619
+ } });
4620
+ /**
4621
+ * Export reusable router and procedure helpers
4622
+ */
4623
+ const router = t.router;
4624
+ const publicProcedure = t.procedure;
4625
+ /**
4626
+ * Middleware to check if user is authenticated
4627
+ */
4628
+ const isAuthenticated = t.middleware(({ ctx, next }) => {
4629
+ if (!ctx.user) throw new TRPCError({
4630
+ code: "UNAUTHORIZED",
4631
+ message: "You must be logged in to access this resource"
4632
+ });
4633
+ return next({ ctx: {
4634
+ ...ctx,
4635
+ user: ctx.user
4636
+ } });
4637
+ });
4638
+ /**
4639
+ * Middleware to check if user is an admin
4640
+ */
4641
+ const isAdminMiddleware = t.middleware(({ ctx, next }) => {
4642
+ if (!ctx.user) throw new TRPCError({
4643
+ code: "UNAUTHORIZED",
4644
+ message: "You must be logged in to access this resource"
4645
+ });
4646
+ console.log("[isAdminMiddleware] === ADMIN CHECK DEBUG ===");
4647
+ console.log("[isAdminMiddleware] User:", ctx.user.email);
4648
+ console.log("[isAdminMiddleware] Required admin groups:", ctx.adminGroups);
4649
+ console.log("[isAdminMiddleware] Calling isAdmin()...");
4650
+ const hasAdminAccess = isAdmin(ctx.user, ctx.adminGroups);
4651
+ console.log("[isAdminMiddleware] Has admin access:", hasAdminAccess);
4652
+ if (!hasAdminAccess) throw new TRPCError({
4653
+ code: "FORBIDDEN",
4654
+ message: `You must be an admin to access this resource. Required groups: ${ctx.adminGroups.join(", ") || "env_hopper_ui_super_admins"}`
4655
+ });
4656
+ return next({ ctx: {
4657
+ ...ctx,
4658
+ user: ctx.user
4659
+ } });
4660
+ });
4661
+ /**
4662
+ * Admin procedure that requires admin permissions
4663
+ */
4664
+ const adminProcedure = t.procedure.use(isAdminMiddleware);
4665
+ /**
4666
+ * Protected procedure that requires authentication (but not admin)
4667
+ */
4668
+ const protectedProcedure = t.procedure.use(isAuthenticated);
4669
+
4670
+ //#endregion
4671
+ //#region src/server/controller.ts
4672
+ /**
4673
+ * Create the main tRPC router with optional auth instance
4674
+ * @param auth - Optional Better Auth instance for auth-related queries
4675
+ */
4676
+ function createTrpcRouter(auth) {
4677
+ return router({
4678
+ authConfig: publicProcedure.query(async ({ ctx }) => {
4679
+ return { adminGroups: ctx.adminGroups };
4680
+ }),
4681
+ appCatalog: publicProcedure.query(async ({ ctx }) => {
4682
+ var _ctx$companySpecificB, _ctx$companySpecificB2;
4683
+ const baseData = await getAppCatalogData();
4684
+ const appVersion = (_ctx$companySpecificB = (_ctx$companySpecificB2 = ctx.companySpecificBackend).getAppVersion) === null || _ctx$companySpecificB === void 0 ? void 0 : _ctx$companySpecificB.call(_ctx$companySpecificB2);
4685
+ return {
4686
+ ...baseData,
4687
+ ...appVersion && { appVersion }
4688
+ };
4689
+ }),
4690
+ auth: createAuthRouter(t, auth)
4691
+ });
4692
+ }
4693
+
4694
+ //#endregion
4695
+ //#region src/server/ehTrpcContext.ts
4696
+ function createEhTrpcContext({ companySpecificBackend, user: user$1 = null, adminGroups }) {
4697
+ return {
4698
+ companySpecificBackend,
4699
+ user: user$1,
4700
+ adminGroups
4701
+ };
4702
+ }
4703
+
4704
+ //#endregion
4705
+ //#region src/server/ehStaticControllerContract.ts
4706
+ const staticControllerContract = { methods: {
4707
+ getIcon: {
4708
+ method: "get",
4709
+ url: "icon/:icon"
4710
+ },
4711
+ getScreenshot: {
4712
+ method: "get",
4713
+ url: "screenshot/:id"
4714
+ }
4715
+ } };
4716
+
4717
+ //#endregion
4718
+ //#region src/db/tableSyncPrismaAdapter.ts
4719
+ function getPrismaModelOperations(prisma, prismaModelName) {
4720
+ return prisma[prismaModelName.slice(0, 1).toLowerCase() + prismaModelName.slice(1)];
4721
+ }
4722
+ function tableSyncPrisma(params) {
4723
+ const { prisma, prismaModelName, uniqColumns, where: whereGlobal, upsertOnly } = params;
4724
+ const prismOperations = getPrismaModelOperations(prisma, prismaModelName);
4725
+ const idColumn = params.id ?? "id";
4726
+ return tableSync({
4727
+ id: idColumn,
4728
+ uniqColumns,
4729
+ readAll: async () => {
4730
+ const findManyArgs = whereGlobal ? { where: whereGlobal } : {};
4731
+ return await prismOperations.findMany(findManyArgs);
4732
+ },
4733
+ writeAll: async (createData, update, deleteIds) => {
4734
+ const prismaUniqKey = params.uniqColumns.join("_");
4735
+ const relationColumnList = params.relationColumns ?? [];
4736
+ return prisma.$transaction(async (tx) => {
4737
+ const txOps = getPrismaModelOperations(tx, prismaModelName);
4738
+ for (const { data, where } of update) {
4739
+ const uniqKeyWhere = Object.keys(where).length > 1 ? { [prismaUniqKey]: where } : where;
4740
+ const dataScalar = omit(data, relationColumnList);
4741
+ const dataRelations = mapValues(pick(data, relationColumnList), (value) => {
4742
+ return { set: value };
4743
+ });
4744
+ await txOps.update({
4745
+ data: {
4746
+ ...dataScalar,
4747
+ ...dataRelations
4748
+ },
4749
+ where: { ...uniqKeyWhere }
4750
+ });
4751
+ }
4752
+ if (upsertOnly !== true) await txOps.deleteMany({ where: { [idColumn]: { in: deleteIds } } });
4753
+ const createDataMapped = createData.map((data) => {
4754
+ const dataScalar = omit(data, relationColumnList);
4755
+ const dataRelations = mapValues(pick(data, relationColumnList), (value) => {
4756
+ return { connect: value };
4757
+ });
4758
+ return {
4759
+ ...dataScalar,
4760
+ ...dataRelations
4761
+ };
4762
+ });
4763
+ if (createDataMapped.length > 0) {
5581
4764
  const uniqKeysInCreate = /* @__PURE__ */ new Set();
5582
4765
  const duplicateKeys = [];
5583
4766
  for (const data of createDataMapped) {
@@ -5709,15 +4892,15 @@ async function parseAssetMeta(p) {
5709
4892
 
5710
4893
  //#endregion
5711
4894
  //#region src/modules/assets/upsertAsset.ts
5712
- async function upsertAsset({ prisma, buffer, name: name$1, originalFilename, assetType }) {
4895
+ async function upsertAsset({ prisma, buffer, name, originalFilename, assetType }) {
5713
4896
  const { checksum, fileSize, width, height, mimeType } = await parseAssetMeta({
5714
4897
  buffer,
5715
4898
  originalFilename
5716
4899
  });
5717
- const existing = await prisma.dbAsset.findUnique({ where: { name: name$1 } });
4900
+ const existing = await prisma.dbAsset.findUnique({ where: { name } });
5718
4901
  if (existing) return existing.id;
5719
4902
  return (await prisma.dbAsset.create({ data: {
5720
- name: name$1,
4903
+ name,
5721
4904
  checksum,
5722
4905
  assetType,
5723
4906
  content: new Uint8Array(buffer),
@@ -5793,751 +4976,57 @@ async function syncAssetsFromFileSystem(apps, allAppsAssetsPath) {
5793
4976
  }
5794
4977
  /**
5795
4978
  * Syncs app catalog data to the database using table sync.
5796
- * This will create new apps, update existing ones, and delete any that are no longer in the input.
5797
- *
5798
- * Note: Call connectDb() before and disconnectDb() after if running in a script.
5799
- */
5800
- async function syncAppCatalog(apps, tagsDefinitions, approvalMethods, sreenshotsPath) {
5801
- try {
5802
- const prisma = getDbClient();
5803
- await tableSyncPrisma({
5804
- prisma,
5805
- ...TABLE_SYNC_MAGAZINE.DbApprovalMethod
5806
- }).sync(approvalMethods);
5807
- const sync = tableSyncPrisma({
5808
- prisma,
5809
- ...TABLE_SYNC_MAGAZINE.DbAppForCatalog
5810
- });
5811
- await tableSyncPrisma({
5812
- prisma,
5813
- ...TABLE_SYNC_MAGAZINE.DbAppTagDefinition
5814
- }).sync(tagsDefinitions);
5815
- const dbApps = apps.map((app) => {
5816
- return {
5817
- slug: app.slug || app.displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""),
5818
- displayName: app.displayName,
5819
- description: app.description,
5820
- teams: app.teams ?? [],
5821
- accessRequest: app.accessRequest ?? null,
5822
- notes: app.notes ?? null,
5823
- tags: app.tags ?? [],
5824
- appUrl: app.appUrl ?? null,
5825
- links: app.links ?? null,
5826
- iconName: app.iconName ?? null,
5827
- screenshotIds: app.screenshotIds ?? [],
5828
- sources: app.sources ?? [],
5829
- deprecated: app.deprecated ?? null
5830
- };
5831
- });
5832
- const actual = (await sync.sync(dbApps)).getActual();
5833
- if (sreenshotsPath) await syncAssetsFromFileSystem(apps, sreenshotsPath);
5834
- else console.warn("Do not sync screenhots");
5835
- return {
5836
- created: actual.length - apps.length + (apps.length - actual.length),
5837
- updated: 0,
5838
- deleted: 0,
5839
- total: actual.length
5840
- };
5841
- } catch (error) {
5842
- const errorMessage = error instanceof Error ? error.message : String(error);
5843
- const errorStack = error instanceof Error ? error.stack : void 0;
5844
- throw new Error(`Error syncing app catalog: ${errorMessage}\n\nDetails:\n${errorStack || "No stack trace available"}`);
5845
- }
5846
- }
5847
-
5848
- //#endregion
5849
- //#region src/modules/auth/authorizationUtils.ts
5850
- /**
5851
- * Extract groups from user object
5852
- * Groups can be stored in different locations depending on the OAuth provider
5853
- */
5854
- function getUserGroups(user$1) {
5855
- if (!user$1) {
5856
- console.log("[getUserGroups] No user provided");
5857
- return [];
5858
- }
5859
- console.log("[getUserGroups] === USER OBJECT DEBUG ===");
5860
- console.log("[getUserGroups] User ID:", user$1.id);
5861
- console.log("[getUserGroups] User email:", user$1.email);
5862
- console.log("[getUserGroups] User.env_hopper_groups:", user$1.env_hopper_groups);
5863
- console.log("[getUserGroups] User.groups:", user$1.groups);
5864
- console.log("[getUserGroups] User.oktaGroups:", user$1.oktaGroups);
5865
- console.log("[getUserGroups] User.roles:", user$1.roles);
5866
- console.log("[getUserGroups] All user keys:", Object.keys(user$1));
5867
- console.log("[getUserGroups] Full user object:", JSON.stringify(user$1, null, 2));
5868
- const groups = user$1.env_hopper_groups || user$1.groups || user$1.oktaGroups || user$1.roles || [];
5869
- const result = Array.isArray(groups) ? groups : [];
5870
- console.log("[getUserGroups] Final groups result:", result);
5871
- return result;
5872
- }
5873
- /**
5874
- * Check if user is a member of any of the specified groups
5875
- */
5876
- function isMemberOfAnyGroup(user$1, allowedGroups) {
5877
- const userGroups = getUserGroups(user$1);
5878
- return allowedGroups.some((group$1) => userGroups.includes(group$1));
5879
- }
5880
- /**
5881
- * Check if user is a member of all specified groups
5882
- */
5883
- function isMemberOfAllGroups(user$1, requiredGroups) {
5884
- const userGroups = getUserGroups(user$1);
5885
- return requiredGroups.every((group$1) => userGroups.includes(group$1));
5886
- }
5887
- /**
5888
- * Check if user has admin permissions
5889
- * @param user User object with groups
5890
- * @param adminGroups List of admin group names (default: ['env_hopper_ui_super_admins'])
5891
- */
5892
- function isAdmin(user$1, adminGroups = ["env_hopper_ui_super_admins"]) {
5893
- return isMemberOfAnyGroup(user$1, adminGroups);
5894
- }
5895
- /**
5896
- * Require admin permissions - throws error if not admin
5897
- * @param user User object with groups
5898
- * @param adminGroups List of admin group names (default: ['env_hopper_ui_super_admins'])
5899
- */
5900
- function requireAdmin(user$1, adminGroups = ["env_hopper_ui_super_admins"]) {
5901
- if (!isAdmin(user$1, adminGroups)) throw new Error("Forbidden: Admin access required");
5902
- }
5903
- /**
5904
- * Require membership in specific groups - throws error if not member
5905
- */
5906
- function requireGroups(user$1, groups) {
5907
- if (!isMemberOfAnyGroup(user$1, groups)) throw new Error(`Forbidden: Membership in one of these groups required: ${groups.join(", ")}`);
5908
- }
5909
-
5910
- //#endregion
5911
- //#region src/server/trpcSetup.ts
5912
- /**
5913
- * Initialization of tRPC backend
5914
- * Should be done only once per backend!
5915
- */
5916
- const t = initTRPC.context().create({ errorFormatter({ error, shape }) {
5917
- var _data;
5918
- console.error("[tRPC Error]", {
5919
- path: (_data = shape.data) === null || _data === void 0 ? void 0 : _data.path,
5920
- code: error.code,
5921
- message: error.message,
5922
- cause: error.cause,
5923
- stack: error.stack
5924
- });
5925
- return shape;
5926
- } });
5927
- /**
5928
- * Export reusable router and procedure helpers
5929
- */
5930
- const router = t.router;
5931
- const publicProcedure = t.procedure;
5932
- /**
5933
- * Middleware to check if user is authenticated
5934
- */
5935
- const isAuthenticated = t.middleware(({ ctx, next }) => {
5936
- if (!ctx.user) throw new TRPCError({
5937
- code: "UNAUTHORIZED",
5938
- message: "You must be logged in to access this resource"
5939
- });
5940
- return next({ ctx: {
5941
- ...ctx,
5942
- user: ctx.user
5943
- } });
5944
- });
5945
- /**
5946
- * Middleware to check if user is an admin
5947
- */
5948
- const isAdminMiddleware = t.middleware(({ ctx, next }) => {
5949
- if (!ctx.user) throw new TRPCError({
5950
- code: "UNAUTHORIZED",
5951
- message: "You must be logged in to access this resource"
5952
- });
5953
- console.log("[isAdminMiddleware] === ADMIN CHECK DEBUG ===");
5954
- console.log("[isAdminMiddleware] User:", ctx.user.email);
5955
- console.log("[isAdminMiddleware] Required admin groups:", ctx.adminGroups);
5956
- console.log("[isAdminMiddleware] Calling isAdmin()...");
5957
- const hasAdminAccess = isAdmin(ctx.user, ctx.adminGroups);
5958
- console.log("[isAdminMiddleware] Has admin access:", hasAdminAccess);
5959
- if (!hasAdminAccess) throw new TRPCError({
5960
- code: "FORBIDDEN",
5961
- message: `You must be an admin to access this resource. Required groups: ${ctx.adminGroups.join(", ") || "env_hopper_ui_super_admins"}`
5962
- });
5963
- return next({ ctx: {
5964
- ...ctx,
5965
- user: ctx.user
5966
- } });
5967
- });
5968
- /**
5969
- * Admin procedure that requires admin permissions
5970
- */
5971
- const adminProcedure = t.procedure.use(isAdminMiddleware);
5972
- /**
5973
- * Protected procedure that requires authentication (but not admin)
5974
- */
5975
- const protectedProcedure = t.procedure.use(isAuthenticated);
5976
-
5977
- //#endregion
5978
- //#region src/modules/appCatalogAdmin/appCatalogAdminRouter.ts
5979
- const AccessMethodSchema = z.object({ type: z.enum([
5980
- "bot",
5981
- "ticketing",
5982
- "email",
5983
- "self-service",
5984
- "documentation",
5985
- "manual"
5986
- ]) }).loose();
5987
- const AppLinkSchema = z.object({
5988
- displayName: z.string().optional(),
5989
- url: z.url()
5990
- });
5991
- const AppRoleSchema = z.object({
5992
- name: z.string(),
5993
- description: z.string().optional()
5994
- });
5995
- const ApproverContactSchema = z.object({
5996
- displayName: z.string(),
5997
- contact: z.string().optional()
5998
- });
5999
- const ApprovalUrlSchema = z.object({
6000
- label: z.string().optional(),
6001
- url: z.url()
6002
- });
6003
- const AppAccessRequestSchema = z.object({
6004
- approvalMethodId: z.string(),
6005
- comments: z.string().optional(),
6006
- requestPrompt: z.string().optional(),
6007
- postApprovalInstructions: z.string().optional(),
6008
- roles: z.array(AppRoleSchema).optional(),
6009
- approvers: z.array(ApproverContactSchema).optional(),
6010
- urls: z.array(ApprovalUrlSchema).optional(),
6011
- whoToReachOut: z.string().optional()
6012
- });
6013
- const CreateAppForCatalogSchema = z.object({
6014
- slug: z.string().min(1).regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with hyphens"),
6015
- displayName: z.string().min(1),
6016
- description: z.string(),
6017
- access: AccessMethodSchema.optional(),
6018
- teams: z.array(z.string()).optional(),
6019
- accessRequest: AppAccessRequestSchema.optional(),
6020
- notes: z.string().optional(),
6021
- tags: z.array(z.string()).optional(),
6022
- appUrl: z.url().optional(),
6023
- links: z.array(AppLinkSchema).optional(),
6024
- iconName: z.string().optional(),
6025
- screenshotIds: z.array(z.string()).optional()
6026
- });
6027
- const UpdateAppForCatalogSchema = CreateAppForCatalogSchema.partial().extend({ id: z.string() });
6028
- function createAppCatalogAdminRouter() {
6029
- const prisma = getDbClient();
6030
- return router({
6031
- list: adminProcedure.query(async () => {
6032
- return prisma.dbAppForCatalog.findMany({ orderBy: { displayName: "asc" } });
6033
- }),
6034
- getById: adminProcedure.input(z.object({ id: z.string() })).query(async ({ input }) => {
6035
- return prisma.dbAppForCatalog.findUnique({ where: { id: input.id } });
6036
- }),
6037
- getBySlug: adminProcedure.input(z.object({ slug: z.string() })).query(async ({ input }) => {
6038
- return prisma.dbAppForCatalog.findUnique({ where: { slug: input.slug } });
6039
- }),
6040
- create: adminProcedure.input(CreateAppForCatalogSchema).mutation(async ({ input }) => {
6041
- return prisma.dbAppForCatalog.create({ data: {
6042
- slug: input.slug,
6043
- displayName: input.displayName,
6044
- description: input.description,
6045
- teams: input.teams ?? [],
6046
- accessRequest: input.accessRequest,
6047
- notes: input.notes,
6048
- tags: input.tags ?? [],
6049
- appUrl: input.appUrl,
6050
- links: input.links,
6051
- iconName: input.iconName,
6052
- screenshotIds: input.screenshotIds ?? []
6053
- } });
6054
- }),
6055
- update: adminProcedure.input(UpdateAppForCatalogSchema).mutation(async ({ input }) => {
6056
- const { id,...updateData } = input;
6057
- return prisma.dbAppForCatalog.update({
6058
- where: { id },
6059
- data: {
6060
- ...updateData.slug !== void 0 && { slug: updateData.slug },
6061
- ...updateData.displayName !== void 0 && { displayName: updateData.displayName },
6062
- ...updateData.description !== void 0 && { description: updateData.description },
6063
- ...updateData.teams !== void 0 && { teams: updateData.teams },
6064
- ...updateData.accessRequest !== void 0 && { accessRequest: updateData.accessRequest },
6065
- ...updateData.notes !== void 0 && { notes: updateData.notes },
6066
- ...updateData.tags !== void 0 && { tags: updateData.tags },
6067
- ...updateData.appUrl !== void 0 && { appUrl: updateData.appUrl },
6068
- ...updateData.links !== void 0 && { links: updateData.links },
6069
- ...updateData.iconName !== void 0 && { iconName: updateData.iconName },
6070
- ...updateData.screenshotIds !== void 0 && { screenshotIds: updateData.screenshotIds }
6071
- }
6072
- });
6073
- }),
6074
- updateScreenshots: adminProcedure.input(z.object({
6075
- id: z.string(),
6076
- screenshotIds: z.array(z.string())
6077
- })).mutation(async ({ input }) => {
6078
- return prisma.dbAppForCatalog.update({
6079
- where: { id: input.id },
6080
- data: { screenshotIds: input.screenshotIds }
6081
- });
6082
- }),
6083
- delete: adminProcedure.input(z.object({ id: z.string() })).mutation(async ({ input }) => {
6084
- return prisma.dbAppForCatalog.delete({ where: { id: input.id } });
6085
- })
6086
- });
6087
- }
6088
-
6089
- //#endregion
6090
- //#region src/modules/approvalMethod/slugUtils.ts
6091
- /**
6092
- * Generates a URL-friendly slug from a display name.
6093
- * Converts to lowercase and replaces non-alphanumeric characters with hyphens.
6094
- *
6095
- * @param displayName - The display name to convert
6096
- * @returns A slug suitable for use as a primary key
6097
- *
6098
- * @example
6099
- * generateSlugFromDisplayName("My Service") // "my-service"
6100
- * generateSlugFromDisplayName("John's Team") // "john-s-team"
6101
- */
6102
- function generateSlugFromDisplayName(displayName) {
6103
- return displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
6104
- }
6105
-
6106
- //#endregion
6107
- //#region src/modules/approvalMethod/approvalMethodRouter.ts
6108
- const ReachOutContactSchema = z.object({
6109
- displayName: z.string(),
6110
- contact: z.string()
6111
- });
6112
- const ServiceConfigSchema = z.object({
6113
- url: z.url().optional(),
6114
- icon: z.string().optional()
6115
- });
6116
- const PersonTeamConfigSchema = z.object({ reachOutContacts: z.array(ReachOutContactSchema).optional() });
6117
- const CustomConfigSchema = z.object({});
6118
- const ApprovalMethodConfigSchema = z.union([
6119
- ServiceConfigSchema,
6120
- PersonTeamConfigSchema,
6121
- CustomConfigSchema
6122
- ]);
6123
- const CreateApprovalMethodSchema = z.object({
6124
- type: z.enum([
6125
- "service",
6126
- "personTeam",
6127
- "custom"
6128
- ]),
6129
- displayName: z.string().min(1),
6130
- config: ApprovalMethodConfigSchema.optional()
6131
- });
6132
- const UpdateApprovalMethodSchema = z.object({
6133
- slug: z.string(),
6134
- type: z.enum([
6135
- "service",
6136
- "personTeam",
6137
- "custom"
6138
- ]).optional(),
6139
- displayName: z.string().min(1).optional(),
6140
- config: ApprovalMethodConfigSchema.optional()
6141
- });
6142
- /**
6143
- * Convert Prisma DbApprovalMethod to our ApprovalMethod type.
6144
- * This ensures tRPC infers proper types for frontend consumers.
6145
- */
6146
- function toApprovalMethod(db) {
6147
- const baseFields = {
6148
- slug: db.slug,
6149
- displayName: db.displayName,
6150
- createdAt: db.createdAt,
6151
- updatedAt: db.updatedAt
6152
- };
6153
- const config$1 = db.config ?? {};
6154
- switch (db.type) {
6155
- case "service": return {
6156
- ...baseFields,
6157
- type: "service",
6158
- config: config$1
6159
- };
6160
- case "personTeam": return {
6161
- ...baseFields,
6162
- type: "personTeam",
6163
- config: config$1
6164
- };
6165
- case "custom": return {
6166
- ...baseFields,
6167
- type: "custom",
6168
- config: config$1
6169
- };
6170
- }
6171
- }
6172
- function createApprovalMethodRouter() {
6173
- return router({
6174
- list: publicProcedure.query(async () => {
6175
- return (await getDbClient().dbApprovalMethod.findMany({ orderBy: { displayName: "asc" } })).map(toApprovalMethod);
6176
- }),
6177
- getById: publicProcedure.input(z.object({ slug: z.string() })).query(async ({ input }) => {
6178
- const result = await getDbClient().dbApprovalMethod.findUnique({ where: { slug: input.slug } });
6179
- return result ? toApprovalMethod(result) : null;
6180
- }),
6181
- create: adminProcedure.input(CreateApprovalMethodSchema).mutation(async ({ input }) => {
6182
- return toApprovalMethod(await getDbClient().dbApprovalMethod.create({ data: {
6183
- slug: generateSlugFromDisplayName(input.displayName),
6184
- type: input.type,
6185
- displayName: input.displayName,
6186
- config: input.config ?? JsonNull
6187
- } }));
6188
- }),
6189
- update: adminProcedure.input(UpdateApprovalMethodSchema).mutation(async ({ input }) => {
6190
- const prisma = getDbClient();
6191
- const { slug,...updateData } = input;
6192
- return toApprovalMethod(await prisma.dbApprovalMethod.update({
6193
- where: { slug },
6194
- data: {
6195
- ...updateData.type !== void 0 && { type: updateData.type },
6196
- ...updateData.displayName !== void 0 && { displayName: updateData.displayName },
6197
- ...updateData.config !== void 0 && { config: updateData.config ?? JsonNull }
6198
- }
6199
- }));
6200
- }),
6201
- delete: adminProcedure.input(z.object({ slug: z.string() })).mutation(async ({ input }) => {
6202
- return toApprovalMethod(await getDbClient().dbApprovalMethod.delete({ where: { slug: input.slug } }));
6203
- }),
6204
- listByType: publicProcedure.input(z.object({ type: z.enum([
6205
- "service",
6206
- "personTeam",
6207
- "custom"
6208
- ]) })).query(async ({ input }) => {
6209
- return (await getDbClient().dbApprovalMethod.findMany({
6210
- where: { type: input.type },
6211
- orderBy: { displayName: "asc" }
6212
- })).map(toApprovalMethod);
6213
- })
6214
- });
6215
- }
6216
-
6217
- //#endregion
6218
- //#region src/modules/assets/screenshotRouter.ts
6219
- function createScreenshotRouter() {
6220
- return router({
6221
- list: publicProcedure.query(async () => {
6222
- return getDbClient().dbAsset.findMany({
6223
- where: { assetType: "screenshot" },
6224
- select: {
6225
- id: true,
6226
- name: true,
6227
- mimeType: true,
6228
- fileSize: true,
6229
- width: true,
6230
- height: true,
6231
- createdAt: true,
6232
- updatedAt: true
6233
- },
6234
- orderBy: { createdAt: "desc" }
6235
- });
6236
- }),
6237
- getOne: publicProcedure.input(z.object({ id: z.string() })).query(async ({ input }) => {
6238
- return getDbClient().dbAsset.findFirst({
6239
- where: {
6240
- id: input.id,
6241
- assetType: "screenshot"
6242
- },
6243
- select: {
6244
- id: true,
6245
- name: true,
6246
- mimeType: true,
6247
- fileSize: true,
6248
- width: true,
6249
- height: true,
6250
- createdAt: true,
6251
- updatedAt: true
6252
- }
6253
- });
6254
- }),
6255
- getByAppSlug: publicProcedure.input(z.object({ appSlug: z.string() })).query(async ({ input }) => {
6256
- const prisma = getDbClient();
6257
- const app = await prisma.dbAppForCatalog.findUnique({
6258
- where: { slug: input.appSlug },
6259
- select: { screenshotIds: true }
6260
- });
6261
- if (!app) return [];
6262
- return prisma.dbAsset.findMany({
6263
- where: {
6264
- id: { in: app.screenshotIds },
6265
- assetType: "screenshot"
6266
- },
6267
- select: {
6268
- id: true,
6269
- name: true,
6270
- mimeType: true,
6271
- fileSize: true,
6272
- width: true,
6273
- height: true,
6274
- createdAt: true,
6275
- updatedAt: true
6276
- }
6277
- });
6278
- }),
6279
- getFirstByAppSlug: publicProcedure.input(z.object({ appSlug: z.string() })).query(async ({ input }) => {
6280
- const prisma = getDbClient();
6281
- const app = await prisma.dbAppForCatalog.findUnique({
6282
- where: { slug: input.appSlug },
6283
- select: { screenshotIds: true }
6284
- });
6285
- if (!app || app.screenshotIds.length === 0) return null;
6286
- return prisma.dbAsset.findUnique({
6287
- where: { id: app.screenshotIds[0] },
6288
- select: {
6289
- id: true,
6290
- name: true,
6291
- mimeType: true,
6292
- fileSize: true,
6293
- width: true,
6294
- height: true,
6295
- createdAt: true,
6296
- updatedAt: true
6297
- }
6298
- });
6299
- })
6300
- });
6301
- }
6302
-
6303
- //#endregion
6304
- //#region src/modules/auth/authRouter.ts
6305
- /**
6306
- * Create auth tRPC procedures
6307
- * @param t - tRPC instance
6308
- * @param auth - Better Auth instance (optional, for future extensions)
6309
- * @returns tRPC router with auth procedures
6310
- */
6311
- function createAuthRouter(t$1, auth) {
6312
- const router$1 = t$1.router;
6313
- const publicProcedure$1 = t$1.procedure;
6314
- return router$1({
6315
- getSession: publicProcedure$1.query(async ({ ctx }) => {
6316
- return {
6317
- user: ctx.user ?? null,
6318
- isAuthenticated: !!ctx.user
6319
- };
6320
- }),
6321
- getProviders: publicProcedure$1.query(() => {
6322
- const providers = [];
6323
- const authOptions = auth === null || auth === void 0 ? void 0 : auth.options;
6324
- if (authOptions === null || authOptions === void 0 ? void 0 : authOptions.socialProviders) {
6325
- const socialProviders = authOptions.socialProviders;
6326
- Object.keys(socialProviders).forEach((key) => {
6327
- if (socialProviders[key]) providers.push(key);
6328
- });
6329
- }
6330
- if (authOptions === null || authOptions === void 0 ? void 0 : authOptions.plugins) authOptions.plugins.forEach((plugin) => {
6331
- var _pluginWithConfig$opt;
6332
- const pluginWithConfig = plugin;
6333
- if (pluginWithConfig.id === "generic-oauth" && ((_pluginWithConfig$opt = pluginWithConfig.options) === null || _pluginWithConfig$opt === void 0 ? void 0 : _pluginWithConfig$opt.config)) (Array.isArray(pluginWithConfig.options.config) ? pluginWithConfig.options.config : [pluginWithConfig.options.config]).forEach((config$1) => {
6334
- if (config$1.providerId) providers.push(config$1.providerId);
6335
- });
6336
- });
6337
- return { providers };
6338
- })
6339
- });
6340
- }
6341
-
6342
- //#endregion
6343
- //#region src/modules/icons/iconUtils.ts
6344
- /**
6345
- * Get file extension from MIME type
6346
- */
6347
- function getExtensionFromMimeType(mimeType) {
6348
- return {
6349
- "image/svg+xml": "svg",
6350
- "image/png": "png",
6351
- "image/jpeg": "jpg",
6352
- "image/jpg": "jpg",
6353
- "image/webp": "webp",
6354
- "image/gif": "gif",
6355
- "image/bmp": "bmp",
6356
- "image/tiff": "tiff",
6357
- "image/x-icon": "ico",
6358
- "image/vnd.microsoft.icon": "ico"
6359
- }[mimeType.toLowerCase()] || "bin";
6360
- }
6361
- /**
6362
- * Get file extension from filename
6363
- */
6364
- function getExtensionFromFilename(filename) {
6365
- var _match$;
6366
- const match = filename.match(/\.([^.]+)$/);
6367
- return (match === null || match === void 0 || (_match$ = match[1]) === null || _match$ === void 0 ? void 0 : _match$.toLowerCase()) || "";
6368
- }
6369
-
6370
- //#endregion
6371
- //#region src/modules/icons/iconRouter.ts
6372
- function createIconRouter() {
6373
- return router({
6374
- list: publicProcedure.query(async () => {
6375
- return getDbClient().dbAsset.findMany({
6376
- where: { assetType: "icon" },
6377
- select: {
6378
- id: true,
6379
- name: true,
6380
- mimeType: true,
6381
- fileSize: true,
6382
- createdAt: true,
6383
- updatedAt: true
6384
- },
6385
- orderBy: { name: "asc" }
6386
- });
6387
- }),
6388
- getOne: publicProcedure.input(z.object({ id: z.string() })).query(async ({ input }) => {
6389
- return getDbClient().dbAsset.findFirst({
6390
- where: {
6391
- id: input.id,
6392
- assetType: "icon"
6393
- },
6394
- select: {
6395
- id: true,
6396
- name: true,
6397
- mimeType: true,
6398
- fileSize: true,
6399
- createdAt: true,
6400
- updatedAt: true
6401
- }
6402
- });
6403
- }),
6404
- create: adminProcedure.input(z.object({
6405
- name: z.string().min(1),
6406
- content: z.string(),
6407
- mimeType: z.string(),
6408
- fileSize: z.number().int().positive()
6409
- })).mutation(async ({ input }) => {
6410
- const prisma = getDbClient();
6411
- const buffer = Buffer.from(input.content, "base64");
6412
- const checksum = generateChecksum(buffer);
6413
- const { width, height } = await getImageDimensions(buffer);
6414
- let name$1 = input.name;
6415
- if (!name$1.includes(".")) {
6416
- const extension = getExtensionFromMimeType(input.mimeType);
6417
- name$1 = `${name$1}.${extension}`;
6418
- }
6419
- const existing = await prisma.dbAsset.findFirst({ where: {
6420
- checksum,
6421
- assetType: "icon"
6422
- } });
6423
- if (existing) return existing;
6424
- return prisma.dbAsset.create({ data: {
6425
- name: name$1,
6426
- assetType: "icon",
6427
- content: new Uint8Array(buffer),
6428
- checksum,
6429
- mimeType: input.mimeType,
6430
- fileSize: input.fileSize,
6431
- width,
6432
- height
6433
- } });
6434
- }),
6435
- update: adminProcedure.input(z.object({
6436
- id: z.string(),
6437
- name: z.string().min(1).optional(),
6438
- content: z.string().optional(),
6439
- mimeType: z.string().optional(),
6440
- fileSize: z.number().int().positive().optional()
6441
- })).mutation(async ({ input }) => {
6442
- const prisma = getDbClient();
6443
- const { id, content, name: name$1,...rest } = input;
6444
- const data = { ...rest };
6445
- if (content) {
6446
- const buffer = Buffer.from(content, "base64");
6447
- data.content = new Uint8Array(buffer);
6448
- data.checksum = generateChecksum(buffer);
6449
- const { width, height } = await getImageDimensions(buffer);
6450
- data.width = width;
6451
- data.height = height;
6452
- }
6453
- if (name$1) if (!name$1.includes(".") && input.mimeType) data.name = `${name$1}.${getExtensionFromMimeType(input.mimeType)}`;
6454
- else data.name = name$1;
6455
- return prisma.dbAsset.update({
6456
- where: { id },
6457
- data
6458
- });
6459
- }),
6460
- delete: adminProcedure.input(z.object({ id: z.string() })).mutation(async ({ input }) => {
6461
- return getDbClient().dbAsset.delete({ where: { id: input.id } });
6462
- }),
6463
- deleteMany: adminProcedure.input(z.object({ ids: z.array(z.string()) })).mutation(async ({ input }) => {
6464
- return getDbClient().dbAsset.deleteMany({ where: {
6465
- id: { in: input.ids },
6466
- assetType: "icon"
6467
- } });
6468
- }),
6469
- getContent: publicProcedure.input(z.object({ id: z.string() })).query(async ({ input }) => {
6470
- const asset = await getDbClient().dbAsset.findFirst({
6471
- where: {
6472
- id: input.id,
6473
- assetType: "icon"
6474
- },
6475
- select: {
6476
- content: true,
6477
- mimeType: true,
6478
- name: true
6479
- }
6480
- });
6481
- if (!asset) throw new Error("Icon not found");
6482
- return {
6483
- content: Buffer.from(asset.content).toString("base64"),
6484
- mimeType: asset.mimeType,
6485
- name: asset.name
6486
- };
6487
- })
6488
- });
6489
- }
6490
-
6491
- //#endregion
6492
- //#region src/server/controller.ts
6493
- /**
6494
- * Create the main tRPC router with optional auth instance
6495
- * @param auth - Optional Better Auth instance for auth-related queries
6496
- */
6497
- function createTrpcRouter(auth) {
6498
- return router({
6499
- authConfig: publicProcedure.query(async ({ ctx }) => {
6500
- return { adminGroups: ctx.adminGroups };
6501
- }),
6502
- appCatalog: publicProcedure.query(async ({ ctx }) => {
6503
- var _ctx$companySpecificB, _ctx$companySpecificB2;
6504
- const baseData = await getAppCatalogData();
6505
- const appVersion = (_ctx$companySpecificB = (_ctx$companySpecificB2 = ctx.companySpecificBackend).getAppVersion) === null || _ctx$companySpecificB === void 0 ? void 0 : _ctx$companySpecificB.call(_ctx$companySpecificB2);
4979
+ * This will create new apps, update existing ones, and delete any that are no longer in the input.
4980
+ *
4981
+ * Note: Call connectDb() before and disconnectDb() after if running in a script.
4982
+ */
4983
+ async function syncAppCatalog(apps, tagsDefinitions, approvalMethods, sreenshotsPath) {
4984
+ try {
4985
+ const prisma = getDbClient();
4986
+ await tableSyncPrisma({
4987
+ prisma,
4988
+ ...TABLE_SYNC_MAGAZINE.DbApprovalMethod
4989
+ }).sync(approvalMethods);
4990
+ const sync = tableSyncPrisma({
4991
+ prisma,
4992
+ ...TABLE_SYNC_MAGAZINE.DbAppForCatalog
4993
+ });
4994
+ await tableSyncPrisma({
4995
+ prisma,
4996
+ ...TABLE_SYNC_MAGAZINE.DbAppTagDefinition
4997
+ }).sync(tagsDefinitions);
4998
+ const dbApps = apps.map((app) => {
6506
4999
  return {
6507
- ...baseData,
6508
- ...appVersion && { appVersion }
5000
+ slug: app.slug || app.displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""),
5001
+ displayName: app.displayName,
5002
+ description: app.description,
5003
+ teams: app.teams ?? [],
5004
+ accessRequest: app.accessRequest ?? null,
5005
+ notes: app.notes ?? null,
5006
+ tags: app.tags ?? [],
5007
+ appUrl: app.appUrl ?? null,
5008
+ links: app.links ?? null,
5009
+ iconName: app.iconName ?? null,
5010
+ screenshotIds: app.screenshotIds ?? [],
5011
+ sources: app.sources ?? [],
5012
+ deprecated: app.deprecated ?? null
6509
5013
  };
6510
- }),
6511
- icon: createIconRouter(),
6512
- screenshot: createScreenshotRouter(),
6513
- appCatalogAdmin: createAppCatalogAdminRouter(),
6514
- approvalMethod: createApprovalMethodRouter(),
6515
- auth: createAuthRouter(t, auth)
6516
- });
6517
- }
6518
-
6519
- //#endregion
6520
- //#region src/server/ehTrpcContext.ts
6521
- function createEhTrpcContext({ companySpecificBackend, user: user$1 = null, adminGroups }) {
6522
- return {
6523
- companySpecificBackend,
6524
- user: user$1,
6525
- adminGroups
6526
- };
6527
- }
6528
-
6529
- //#endregion
6530
- //#region src/server/ehStaticControllerContract.ts
6531
- const staticControllerContract = { methods: {
6532
- getIcon: {
6533
- method: "get",
6534
- url: "icon/:icon"
6535
- },
6536
- getScreenshot: {
6537
- method: "get",
6538
- url: "screenshot/:id"
5014
+ });
5015
+ const actual = (await sync.sync(dbApps)).getActual();
5016
+ if (sreenshotsPath) await syncAssetsFromFileSystem(apps, sreenshotsPath);
5017
+ else console.warn("Do not sync screenhots");
5018
+ return {
5019
+ created: actual.length - apps.length + (apps.length - actual.length),
5020
+ updated: 0,
5021
+ deleted: 0,
5022
+ total: actual.length
5023
+ };
5024
+ } catch (error) {
5025
+ const errorMessage = error instanceof Error ? error.message : String(error);
5026
+ const errorStack = error instanceof Error ? error.stack : void 0;
5027
+ throw new Error(`Error syncing app catalog: ${errorMessage}\n\nDetails:\n${errorStack || "No stack trace available"}`);
6539
5028
  }
6540
- } };
5029
+ }
6541
5030
 
6542
5031
  //#endregion
6543
5032
  //#region src/modules/auth/auth.ts
@@ -6588,256 +5077,32 @@ function registerAuthRoutes(app, auth) {
6588
5077
  }
6589
5078
 
6590
5079
  //#endregion
6591
- //#region src/modules/admin/chat/createAdminChatHandler.ts
6592
- function convertToCoreMessages(messages) {
6593
- return messages.map((msg) => {
6594
- var _msg$parts;
6595
- if (msg.content) return {
6596
- role: msg.role,
6597
- content: msg.content
6598
- };
6599
- const textContent = ((_msg$parts = msg.parts) === null || _msg$parts === void 0 ? void 0 : _msg$parts.filter((part) => part.type === "text").map((part) => part.text).join("")) ?? "";
6600
- return {
6601
- role: msg.role,
6602
- content: textContent
6603
- };
6604
- });
6605
- }
6606
- /**
6607
- * Creates an Express handler for the admin chat endpoint.
6608
- *
6609
- * Usage in thin wrappers:
6610
- *
6611
- * ```typescript
6612
- * // With OpenAI
6613
- * import { openai } from '@ai-sdk/openai'
6614
- * app.post('/api/admin/chat', createAdminChatHandler({
6615
- * model: openai('gpt-4o-mini'),
6616
- * }))
6617
- *
6618
- * // With Claude
6619
- * import { anthropic } from '@ai-sdk/anthropic'
6620
- * app.post('/api/admin/chat', createAdminChatHandler({
6621
- * model: anthropic('claude-sonnet-4-20250514'),
6622
- * }))
6623
- * ```
6624
- */
6625
- function createAdminChatHandler(options) {
6626
- const { model, systemPrompt = "You are a helpful admin assistant for the App Catalog application. Help users manage apps, data sources, and MCP server configurations.", tools = {}, validateConfig } = options;
6627
- return async (req, res) => {
6628
- try {
6629
- if (validateConfig) validateConfig();
6630
- const { messages } = req.body;
6631
- const coreMessages = convertToCoreMessages(messages);
6632
- console.log("[Admin Chat] Received messages:", JSON.stringify(coreMessages, null, 2));
6633
- console.log("[Admin Chat] Available tools:", Object.keys(tools));
6634
- const response = streamText({
6635
- model,
6636
- system: systemPrompt,
6637
- messages: coreMessages,
6638
- tools,
6639
- stopWhen: stepCountIs(5),
6640
- onFinish: (event) => {
6641
- console.log("[Admin Chat] Finished:", {
6642
- finishReason: event.finishReason,
6643
- usage: event.usage,
6644
- hasText: !!event.text,
6645
- textLength: event.text.length
6646
- });
6647
- }
6648
- }).toUIMessageStreamResponse();
6649
- response.headers.forEach((value, key) => {
6650
- res.setHeader(key, value);
6651
- });
6652
- if (response.body) {
6653
- const reader = response.body.getReader();
6654
- const pump = async () => {
6655
- const { done, value } = await reader.read();
6656
- if (done) {
6657
- res.end();
6658
- return;
6659
- }
6660
- res.write(value);
6661
- return pump();
6662
- };
6663
- await pump();
6664
- } else {
6665
- console.error("[Admin Chat] No response body");
6666
- res.status(500).json({ error: "No response from AI model" });
6667
- }
6668
- } catch (error) {
6669
- console.error("[Admin Chat] Error:", error);
6670
- res.status(500).json({ error: "Failed to process chat request" });
6671
- }
6672
- };
6673
- }
6674
-
6675
- //#endregion
6676
- //#region src/modules/admin/chat/createDatabaseTools.ts
5080
+ //#region src/modules/icons/iconUtils.ts
6677
5081
  /**
6678
- * Creates a DatabaseClient from a Prisma client.
5082
+ * Get file extension from MIME type
6679
5083
  */
6680
- function createPrismaDatabaseClient(prisma) {
5084
+ function getExtensionFromMimeType(mimeType) {
6681
5085
  return {
6682
- query: async (sql$1) => {
6683
- return await prisma.$queryRawUnsafe(sql$1);
6684
- },
6685
- execute: async (sql$1) => {
6686
- return { affectedRows: await prisma.$executeRawUnsafe(sql$1) };
6687
- },
6688
- getTables: async () => {
6689
- return (await prisma.$queryRawUnsafe(`SELECT tablename FROM pg_tables WHERE schemaname = 'public'`)).map((t$1) => t$1.tablename);
6690
- },
6691
- getColumns: async (tableName) => {
6692
- return (await prisma.$queryRawUnsafe(`SELECT column_name, data_type, is_nullable
6693
- FROM information_schema.columns
6694
- WHERE table_name = '${tableName}' AND table_schema = 'public'`)).map((c) => ({
6695
- name: c.column_name,
6696
- type: c.data_type,
6697
- nullable: c.is_nullable === "YES"
6698
- }));
6699
- }
6700
- };
6701
- }
6702
- const querySchema = z.object({ sql: z.string().describe("The SELECT SQL query to execute") });
6703
- const modifySchema = z.object({
6704
- sql: z.string().describe("The INSERT, UPDATE, or DELETE SQL query to execute"),
6705
- confirmed: z.boolean().describe("Must be true to execute destructive operations")
6706
- });
6707
- const schemaParamsSchema = z.object({ tableName: z.string().optional().describe("Specific table name to get columns for. If not provided, returns list of all tables.") });
6708
- /**
6709
- * Creates a DatabaseClient using the internal backend-core Prisma client.
6710
- * This is a convenience function for apps that don't need to pass their own Prisma client.
6711
- */
6712
- function createInternalDatabaseClient() {
6713
- return createPrismaDatabaseClient(getDbClient());
5086
+ "image/svg+xml": "svg",
5087
+ "image/png": "png",
5088
+ "image/jpeg": "jpg",
5089
+ "image/jpg": "jpg",
5090
+ "image/webp": "webp",
5091
+ "image/gif": "gif",
5092
+ "image/bmp": "bmp",
5093
+ "image/tiff": "tiff",
5094
+ "image/x-icon": "ico",
5095
+ "image/vnd.microsoft.icon": "ico"
5096
+ }[mimeType.toLowerCase()] || "bin";
6714
5097
  }
6715
5098
  /**
6716
- * Creates AI tools for generic database access.
6717
- *
6718
- * The AI uses these internally - users interact via natural language.
6719
- * Results are formatted as tables by the AI based on the system prompt.
6720
- * Uses the internal backend-core Prisma client automatically.
5099
+ * Get file extension from filename
6721
5100
  */
6722
- function createDatabaseTools() {
6723
- const db = createInternalDatabaseClient();
6724
- return {
6725
- queryDatabase: {
6726
- description: `Execute a SELECT query to read data from the database.
6727
- Use this to list, search, or filter records from any table.
6728
- Always use double quotes around table and column names for PostgreSQL (e.g., SELECT * FROM "App").
6729
- Return results will be formatted as a table for the user.`,
6730
- inputSchema: querySchema,
6731
- execute: async ({ sql: sql$1 }) => {
6732
- console.log(`Executing ${sql$1}`);
6733
- if (!sql$1.trim().toUpperCase().startsWith("SELECT")) return { error: "Only SELECT queries are allowed with queryDatabase. Use modifyDatabase for changes." };
6734
- try {
6735
- const results = await db.query(sql$1);
6736
- return {
6737
- success: true,
6738
- rowCount: Array.isArray(results) ? results.length : 0,
6739
- data: results
6740
- };
6741
- } catch (error) {
6742
- return {
6743
- success: false,
6744
- error: error instanceof Error ? error.message : "Query failed"
6745
- };
6746
- }
6747
- }
6748
- },
6749
- modifyDatabase: {
6750
- description: `Execute an INSERT, UPDATE, or DELETE query to modify data.
6751
- Use double quotes around table and column names for PostgreSQL.
6752
- IMPORTANT: Always ask for user confirmation before executing. Set confirmed=true only after user confirms.
6753
- For UPDATE/DELETE, always include a WHERE clause to avoid affecting all rows.`,
6754
- inputSchema: modifySchema,
6755
- execute: async ({ sql: sql$1, confirmed }) => {
6756
- if (!confirmed) return {
6757
- needsConfirmation: true,
6758
- message: "Please confirm you want to execute this operation.",
6759
- sql: sql$1
6760
- };
6761
- const normalizedSql = sql$1.trim().toUpperCase();
6762
- if (normalizedSql.startsWith("SELECT")) return { error: "Use queryDatabase for SELECT queries." };
6763
- if ((normalizedSql.startsWith("UPDATE") || normalizedSql.startsWith("DELETE")) && !normalizedSql.includes("WHERE")) return {
6764
- error: "UPDATE and DELETE queries must include a WHERE clause for safety.",
6765
- sql: sql$1
6766
- };
6767
- try {
6768
- const result = await db.execute(sql$1);
6769
- return {
6770
- success: true,
6771
- affectedRows: result.affectedRows,
6772
- message: `Operation completed. ${result.affectedRows} row(s) affected.`
6773
- };
6774
- } catch (error) {
6775
- return {
6776
- success: false,
6777
- error: error instanceof Error ? error.message : "Operation failed"
6778
- };
6779
- }
6780
- }
6781
- },
6782
- getDatabaseSchema: {
6783
- description: `Get information about database tables and their columns.
6784
- Use this to understand the database structure before writing queries.
6785
- Call without tableName to list all tables, or with tableName to get columns for a specific table.`,
6786
- inputSchema: schemaParamsSchema,
6787
- execute: async ({ tableName }) => {
6788
- try {
6789
- if (tableName) return {
6790
- success: true,
6791
- table: tableName,
6792
- columns: await db.getColumns(tableName)
6793
- };
6794
- else return {
6795
- success: true,
6796
- tables: await db.getTables()
6797
- };
6798
- } catch (error) {
6799
- return {
6800
- success: false,
6801
- error: error instanceof Error ? error.message : "Failed to get schema"
6802
- };
6803
- }
6804
- }
6805
- }
6806
- };
5101
+ function getExtensionFromFilename(filename) {
5102
+ var _match$;
5103
+ const match = filename.match(/\.([^.]+)$/);
5104
+ return (match === null || match === void 0 || (_match$ = match[1]) === null || _match$ === void 0 ? void 0 : _match$.toLowerCase()) || "";
6807
5105
  }
6808
- /**
6809
- * Default system prompt for the database admin assistant.
6810
- * Can be customized or extended.
6811
- */
6812
- const DEFAULT_ADMIN_SYSTEM_PROMPT = `You are a helpful database admin assistant. You help users view and manage data in the database.
6813
-
6814
- IMPORTANT RULES:
6815
- 1. When showing data, ALWAYS format it as a numbered ASCII table so users can reference rows by number
6816
- 2. NEVER show raw SQL to users - just describe what you're doing in plain language
6817
- 3. When users ask to modify data (update, delete, create), ALWAYS confirm before executing
6818
- 4. For updates, show the current value and ask for confirmation before changing
6819
- 5. Keep responses concise and focused on the data
6820
-
6821
- FORMATTING EXAMPLE:
6822
- When user asks "show me all apps", respond like:
6823
- "Here are all the apps:
6824
-
6825
- | # | ID | Slug | Display Name | Icon |
6826
- |---|----|---------|-----------------| -------|
6827
- | 1 | 1 | portal | Portal | portal |
6828
- | 2 | 2 | admin | Admin Dashboard | admin |
6829
- | 3 | 3 | api | API Service | null |
6830
-
6831
- Found 3 apps total."
6832
-
6833
- When user says "update row 2 display name to 'Admin Panel'":
6834
- 1. First confirm: "I'll update the app 'Admin Dashboard' (ID: 2) to have display name 'Admin Panel'. Proceed?"
6835
- 2. Only after user confirms, execute the update
6836
- 3. Then show the updated row
6837
-
6838
- AVAILABLE TABLES:
6839
- Use getDatabaseSchema tool to discover tables and their columns.
6840
- `;
6841
5106
 
6842
5107
  //#endregion
6843
5108
  //#region src/modules/icons/iconRestController.ts
@@ -6868,17 +5133,17 @@ function registerIconRestController(router$1, config$1) {
6868
5133
  res.status(400).json({ error: "No file uploaded" });
6869
5134
  return;
6870
5135
  }
6871
- let name$1 = req.body["name"];
6872
- if (!name$1) {
5136
+ let name = req.body["name"];
5137
+ if (!name) {
6873
5138
  res.status(400).json({ error: "Name is required" });
6874
5139
  return;
6875
5140
  }
6876
5141
  const extension = getExtensionFromFilename(req.file.originalname) || getExtensionFromMimeType(req.file.mimetype);
6877
- if (!name$1.includes(".")) name$1 = `${name$1}.${extension}`;
5142
+ if (!name.includes(".")) name = `${name}.${extension}`;
6878
5143
  const prisma = getDbClient();
6879
5144
  const checksum = createHash("sha256").update(req.file.buffer).digest("hex");
6880
5145
  const icon = await prisma.dbAsset.create({ data: {
6881
- name: name$1,
5146
+ name,
6882
5147
  assetType: "icon",
6883
5148
  content: new Uint8Array(req.file.buffer),
6884
5149
  mimeType: req.file.mimetype,
@@ -6899,10 +5164,10 @@ function registerIconRestController(router$1, config$1) {
6899
5164
  });
6900
5165
  router$1.get(`${basePath}/:name`, async (req, res) => {
6901
5166
  try {
6902
- const { name: name$1 } = req.params;
5167
+ const { name } = req.params;
6903
5168
  const icon = await getDbClient().dbAsset.findFirst({
6904
5169
  where: {
6905
- name: name$1,
5170
+ name,
6906
5171
  assetType: "icon"
6907
5172
  },
6908
5173
  select: {
@@ -6926,10 +5191,10 @@ function registerIconRestController(router$1, config$1) {
6926
5191
  });
6927
5192
  router$1.get(`${basePath}/:name/metadata`, async (req, res) => {
6928
5193
  try {
6929
- const { name: name$1 } = req.params;
5194
+ const { name } = req.params;
6930
5195
  const icon = await getDbClient().dbAsset.findFirst({
6931
5196
  where: {
6932
- name: name$1,
5197
+ name,
6933
5198
  assetType: "icon"
6934
5199
  },
6935
5200
  select: {
@@ -7002,9 +5267,9 @@ async function upsertIcons(icons) {
7002
5267
  * Get an asset (icon or screenshot) by name from the database.
7003
5268
  * Returns the asset content, mimeType, and name if found.
7004
5269
  */
7005
- async function getAssetByName(name$1) {
5270
+ async function getAssetByName(name) {
7006
5271
  return getDbClient().dbAsset.findUnique({
7007
- where: { name: name$1 },
5272
+ where: { name },
7008
5273
  select: {
7009
5274
  content: true,
7010
5275
  mimeType: true,
@@ -7044,16 +5309,16 @@ function registerAssetRestController(router$1, config$1) {
7044
5309
  res.status(400).json({ error: "No file uploaded" });
7045
5310
  return;
7046
5311
  }
7047
- const name$1 = req.body["name"];
5312
+ const name = req.body["name"];
7048
5313
  const assetType = req.body["assetType"];
7049
- if (!name$1) {
5314
+ if (!name) {
7050
5315
  res.status(400).json({ error: "Name is required" });
7051
5316
  return;
7052
5317
  }
7053
5318
  const id = await upsertAsset({
7054
5319
  prisma,
7055
5320
  buffer: req.file.buffer,
7056
- name: name$1,
5321
+ name,
7057
5322
  originalFilename: req.file.filename,
7058
5323
  assetType
7059
5324
  });
@@ -7129,9 +5394,9 @@ function registerAssetRestController(router$1, config$1) {
7129
5394
  });
7130
5395
  router$1.get(`${basePath}/by-name/:name`, async (req, res) => {
7131
5396
  try {
7132
- const { name: name$1 } = req.params;
5397
+ const { name } = req.params;
7133
5398
  const asset = await prisma.dbAsset.findUnique({
7134
- where: { name: name$1 },
5399
+ where: { name },
7135
5400
  select: {
7136
5401
  content: true,
7137
5402
  mimeType: true,
@@ -7685,29 +5950,6 @@ function printLinkCheckReport(report) {
7685
5950
  else console.log("\n✅ All links are working!");
7686
5951
  }
7687
5952
 
7688
- //#endregion
7689
- //#region src/modules/approvalMethod/syncApprovalMethods.ts
7690
- /**
7691
- * Syncs approval methods to the database using upsert logic based on type + displayName.
7692
- *
7693
- * @param prisma - The PrismaClient instance from the backend-core database
7694
- * @param methods - Array of approval methods to sync
7695
- */
7696
- async function syncApprovalMethods(prisma, methods) {
7697
- await prisma.$transaction(methods.map((method) => prisma.dbApprovalMethod.upsert({
7698
- where: { slug: method.slug },
7699
- update: {
7700
- displayName: method.displayName,
7701
- type: method.type
7702
- },
7703
- create: {
7704
- slug: method.slug,
7705
- type: method.type,
7706
- displayName: method.displayName
7707
- }
7708
- })));
7709
- }
7710
-
7711
5953
  //#endregion
7712
5954
  //#region src/middleware/database.ts
7713
5955
  /**
@@ -7737,7 +5979,7 @@ var EhDatabaseManager = class {
7737
5979
  const datasourceUrl = formatConnectionUrl(this.config);
7738
5980
  this.pool = new esm_default.Pool({ connectionString: datasourceUrl });
7739
5981
  this.client = new PrismaClient({
7740
- adapter: new PrismaPgAdapterFactory(this.pool),
5982
+ adapter: new PrismaPg(this.pool),
7741
5983
  log: process.env.NODE_ENV === "development" ? ["warn", "error"] : ["warn", "error"]
7742
5984
  });
7743
5985
  setDbClient(this.client);
@@ -7783,154 +6025,6 @@ function createBackendResolver(provider) {
7783
6025
  throw new Error("Invalid backend provider: must be an object implementing AppCatalogCompanySpecificBackend or a factory function");
7784
6026
  }
7785
6027
 
7786
- //#endregion
7787
- //#region src/modules/appCatalogAdmin/catalogBackupController.ts
7788
- /**
7789
- * Export the complete app catalog as JSON
7790
- * Includes all fields from DbAppForCatalog and DbApprovalMethod
7791
- */
7792
- async function exportCatalog(_req, res) {
7793
- try {
7794
- const prisma = getDbClient();
7795
- const apps = await prisma.dbAppForCatalog.findMany({ orderBy: { slug: "asc" } });
7796
- const approvalMethods = await prisma.dbApprovalMethod.findMany({ orderBy: { displayName: "asc" } });
7797
- res.json({
7798
- version: "2.0",
7799
- exportDate: (/* @__PURE__ */ new Date()).toISOString(),
7800
- apps,
7801
- approvalMethods
7802
- });
7803
- } catch (error) {
7804
- console.error("Error exporting catalog:", error);
7805
- res.status(500).json({ error: "Failed to export catalog" });
7806
- }
7807
- }
7808
- /**
7809
- * Import/restore the complete app catalog from JSON
7810
- * Overwrites existing data
7811
- */
7812
- async function importCatalog(req, res) {
7813
- try {
7814
- const prisma = getDbClient();
7815
- const { apps, approvalMethods } = req.body;
7816
- if (!Array.isArray(apps)) {
7817
- res.status(400).json({ error: "Invalid data format: apps must be an array" });
7818
- return;
7819
- }
7820
- await prisma.$transaction(async (tx) => {
7821
- if (Array.isArray(approvalMethods)) await tx.dbApprovalMethod.deleteMany({});
7822
- await tx.dbAppForCatalog.deleteMany({});
7823
- if (Array.isArray(approvalMethods)) for (const method of approvalMethods) {
7824
- const { id, createdAt, updatedAt,...methodData } = method;
7825
- await tx.dbApprovalMethod.create({ data: methodData });
7826
- }
7827
- for (const app of apps) {
7828
- const { id, createdAt, updatedAt,...appData } = app;
7829
- await tx.dbAppForCatalog.create({ data: appData });
7830
- }
7831
- });
7832
- res.json({
7833
- success: true,
7834
- imported: {
7835
- apps: apps.length,
7836
- approvalMethods: Array.isArray(approvalMethods) ? approvalMethods.length : 0
7837
- }
7838
- });
7839
- } catch (error) {
7840
- console.error("Error importing catalog:", error);
7841
- res.status(500).json({ error: "Failed to import catalog" });
7842
- }
7843
- }
7844
- /**
7845
- * Export an asset (icon or screenshot) by name
7846
- */
7847
- async function exportAsset(req, res) {
7848
- try {
7849
- const { name: name$1 } = req.params;
7850
- const asset = await getDbClient().dbAsset.findUnique({ where: { name: name$1 } });
7851
- if (!asset) {
7852
- res.status(404).json({ error: "Asset not found" });
7853
- return;
7854
- }
7855
- res.set("Content-Type", asset.mimeType);
7856
- res.set("Content-Disposition", `attachment; filename="${name$1}"`);
7857
- res.send(Buffer.from(asset.content));
7858
- } catch (error) {
7859
- console.error("Error exporting asset:", error);
7860
- res.status(500).json({ error: "Failed to export asset" });
7861
- }
7862
- }
7863
- /**
7864
- * List all assets with metadata
7865
- */
7866
- async function listAssets(_req, res) {
7867
- try {
7868
- const assets = await getDbClient().dbAsset.findMany({
7869
- select: {
7870
- id: true,
7871
- name: true,
7872
- assetType: true,
7873
- mimeType: true,
7874
- fileSize: true,
7875
- width: true,
7876
- height: true,
7877
- checksum: true
7878
- },
7879
- orderBy: { name: "asc" }
7880
- });
7881
- res.json({ assets });
7882
- } catch (error) {
7883
- console.error("Error listing assets:", error);
7884
- res.status(500).json({ error: "Failed to list assets" });
7885
- }
7886
- }
7887
- /**
7888
- * Import an asset (icon or screenshot)
7889
- */
7890
- async function importAsset(req, res) {
7891
- try {
7892
- const file = req.file;
7893
- const { name: name$1, assetType, mimeType, width, height } = req.body;
7894
- if (!file) {
7895
- res.status(400).json({ error: "No file uploaded" });
7896
- return;
7897
- }
7898
- const prisma = getDbClient();
7899
- const checksum = (await import("node:crypto")).createHash("sha256").update(file.buffer).digest("hex");
7900
- const content = new Uint8Array(file.buffer);
7901
- await prisma.dbAsset.upsert({
7902
- where: { name: name$1 },
7903
- update: {
7904
- content,
7905
- checksum,
7906
- mimeType: mimeType || file.mimetype,
7907
- fileSize: file.size,
7908
- width: width ? parseInt(width) : null,
7909
- height: height ? parseInt(height) : null,
7910
- assetType: assetType || "icon"
7911
- },
7912
- create: {
7913
- name: name$1,
7914
- content,
7915
- checksum,
7916
- mimeType: mimeType || file.mimetype,
7917
- fileSize: file.size,
7918
- width: width ? parseInt(width) : null,
7919
- height: height ? parseInt(height) : null,
7920
- assetType: assetType || "icon"
7921
- }
7922
- });
7923
- res.json({
7924
- success: true,
7925
- name: name$1,
7926
- size: file.size
7927
- });
7928
- } catch (error) {
7929
- console.error("Error importing asset:", error);
7930
- res.status(500).json({ error: "Failed to import asset" });
7931
- }
7932
- }
7933
-
7934
6028
  //#endregion
7935
6029
  //#region src/modules/auth/devMockUserUtils.ts
7936
6030
  /**
@@ -7974,64 +6068,54 @@ function createMockSessionResponse(devUser) {
7974
6068
 
7975
6069
  //#endregion
7976
6070
  //#region src/middleware/featureRegistry.ts
7977
- const FEATURES = [
7978
- {
7979
- name: "auth",
7980
- defaultEnabled: true,
7981
- register: (router$1, options, ctx) => {
7982
- const basePath = options.basePath;
7983
- router$1.get(`${basePath}/auth/session`, async (req, res) => {
7984
- try {
7985
- if (ctx.authConfig.devMockUser) {
7986
- res.json(createMockSessionResponse(ctx.authConfig.devMockUser));
7987
- return;
7988
- }
7989
- const session = await ctx.auth.api.getSession({ headers: req.headers });
7990
- if (session) res.json(session);
7991
- else res.status(401).json({ error: "Not authenticated" });
7992
- } catch (error) {
7993
- console.error("[Auth Session Error]", error);
7994
- res.status(500).json({ error: "Internal server error" });
7995
- }
7996
- });
7997
- const authHandler = toNodeHandler(ctx.auth);
7998
- router$1.all(`${basePath}/auth/{*any}`, authHandler);
7999
- }
8000
- },
8001
- {
8002
- name: "adminChat",
8003
- defaultEnabled: false,
8004
- register: (router$1, options) => {
8005
- if (options.adminChat) router$1.post(`${options.basePath}/admin/chat`, createAdminChatHandler(options.adminChat));
8006
- }
8007
- },
8008
- {
8009
- name: "legacyIconEndpoint",
8010
- defaultEnabled: false,
8011
- register: (router$1) => {
8012
- router$1.get("/static/icon/:icon", async (req, res) => {
8013
- const { icon } = req.params;
8014
- if (!icon || !/^[a-z0-9-]+$/i.test(icon)) {
8015
- res.status(400).send("Invalid icon name");
6071
+ const FEATURES = [{
6072
+ name: "auth",
6073
+ defaultEnabled: true,
6074
+ register: (router$1, options, ctx) => {
6075
+ const basePath = options.basePath;
6076
+ router$1.get(`${basePath}/auth/session`, async (req, res) => {
6077
+ try {
6078
+ if (ctx.authConfig.devMockUser) {
6079
+ res.json(createMockSessionResponse(ctx.authConfig.devMockUser));
8016
6080
  return;
8017
6081
  }
8018
- try {
8019
- const dbIcon = await getAssetByName(icon);
8020
- if (!dbIcon) {
8021
- res.status(404).send("Icon not found");
8022
- return;
8023
- }
8024
- res.setHeader("Content-Type", dbIcon.mimeType);
8025
- res.setHeader("Cache-Control", "public, max-age=86400");
8026
- res.send(dbIcon.content);
8027
- } catch (error) {
8028
- console.error("Error fetching icon:", error);
6082
+ const session = await ctx.auth.api.getSession({ headers: req.headers });
6083
+ if (session) res.json(session);
6084
+ else res.status(401).json({ error: "Not authenticated" });
6085
+ } catch (error) {
6086
+ console.error("[Auth Session Error]", error);
6087
+ res.status(500).json({ error: "Internal server error" });
6088
+ }
6089
+ });
6090
+ const authHandler = toNodeHandler(ctx.auth);
6091
+ router$1.all(`${basePath}/auth/{*any}`, authHandler);
6092
+ }
6093
+ }, {
6094
+ name: "legacyIconEndpoint",
6095
+ defaultEnabled: false,
6096
+ register: (router$1) => {
6097
+ router$1.get("/static/icon/:icon", async (req, res) => {
6098
+ const { icon } = req.params;
6099
+ if (!icon || !/^[a-z0-9-]+$/i.test(icon)) {
6100
+ res.status(400).send("Invalid icon name");
6101
+ return;
6102
+ }
6103
+ try {
6104
+ const dbIcon = await getAssetByName(icon);
6105
+ if (!dbIcon) {
8029
6106
  res.status(404).send("Icon not found");
6107
+ return;
8030
6108
  }
8031
- });
8032
- }
6109
+ res.setHeader("Content-Type", dbIcon.mimeType);
6110
+ res.setHeader("Cache-Control", "public, max-age=86400");
6111
+ res.send(dbIcon.content);
6112
+ } catch (error) {
6113
+ console.error("Error fetching icon:", error);
6114
+ res.status(404).send("Icon not found");
6115
+ }
6116
+ });
8033
6117
  }
8034
- ];
6118
+ }];
8035
6119
  /**
8036
6120
  * Registers all enabled features on the router.
8037
6121
  */
@@ -8040,18 +6124,8 @@ function registerFeatures(router$1, options, context) {
8040
6124
  registerIconRestController(router$1, { basePath: `${basePath}/icons` });
8041
6125
  registerAssetRestController(router$1, { basePath: `${basePath}/assets` });
8042
6126
  registerScreenshotRestController(router$1, { basePath: `${basePath}/screenshots` });
8043
- const upload$2 = multer({ storage: multer.memoryStorage() });
8044
- router$1.get(`${basePath}/catalog/backup/export`, exportCatalog);
8045
- router$1.post(`${basePath}/catalog/backup/import`, importCatalog);
8046
- router$1.get(`${basePath}/catalog/backup/assets`, listAssets);
8047
- router$1.get(`${basePath}/catalog/backup/assets/:name`, exportAsset);
8048
- router$1.post(`${basePath}/catalog/backup/assets`, upload$2.single("file"), importAsset);
8049
6127
  const toggles = options.features || {};
8050
- for (const feature of FEATURES) {
8051
- const isEnabled = toggles[feature.name] ?? feature.defaultEnabled;
8052
- if (feature.name === "adminChat" && !options.adminChat) continue;
8053
- if (isEnabled) feature.register(router$1, options, context);
8054
- }
6128
+ for (const feature of FEATURES) if (toggles[feature.name] ?? feature.defaultEnabled) feature.register(router$1, options, context);
8055
6129
  }
8056
6130
 
8057
6131
  //#endregion
@@ -8172,5 +6246,5 @@ function injectCustomScripts(html, scriptUrls) {
8172
6246
  }
8173
6247
 
8174
6248
  //#endregion
8175
- export { DEFAULT_ADMIN_SYSTEM_PROMPT, EhDatabaseManager, TABLE_SYNC_MAGAZINE, checkAllLinks, connectDb, createAdminChatHandler, createAppCatalogAdminRouter, createApprovalMethodRouter, createAuth, createAuthRouter, createDatabaseTools, createEhMiddleware, createEhTrpcContext, createPrismaDatabaseClient, createScreenshotRouter, createTrpcRouter, disconnectDb, getAssetByName, getDbClient, getUserGroups, injectCustomScripts, isAdmin, isMemberOfAllGroups, isMemberOfAnyGroup, printLinkCheckReport, registerAssetRestController, registerAuthRoutes, registerIconRestController, registerScreenshotRestController, requireAdmin, requireGroups, setDbClient, staticControllerContract, syncAppCatalog, syncApprovalMethods, syncAssets, tableSyncPrisma, tool, upsertIcon, upsertIcons };
6249
+ export { EhDatabaseManager, TABLE_SYNC_MAGAZINE, checkAllLinks, connectDb, createAuth, createAuthRouter, createEhMiddleware, createEhTrpcContext, createTrpcRouter, disconnectDb, getAssetByName, getDbClient, getUserGroups, injectCustomScripts, isAdmin, isMemberOfAllGroups, isMemberOfAnyGroup, printLinkCheckReport, registerAssetRestController, registerAuthRoutes, registerIconRestController, registerScreenshotRestController, requireAdmin, requireGroups, setDbClient, staticControllerContract, syncAppCatalog, syncAssets, tableSyncPrisma, upsertIcon, upsertIcons };
8176
6250
  //# sourceMappingURL=index.js.map