@digilogiclabs/platform-core 1.3.0 → 1.5.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.mjs CHANGED
@@ -1,5 +1,11 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
3
9
  var __esm = (fn, res) => function __init() {
4
10
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
11
  };
@@ -387,6 +393,7 @@ var init_IAI = __esm({
387
393
  });
388
394
 
389
395
  // src/interfaces/IRAG.ts
396
+ import { randomBytes as randomBytes13 } from "crypto";
390
397
  var ChunkingPresets, MemoryRAG;
391
398
  var init_IRAG = __esm({
392
399
  "src/interfaces/IRAG.ts"() {
@@ -516,7 +523,7 @@ var init_IRAG = __esm({
516
523
  }
517
524
  async ingestOne(collection, document, options) {
518
525
  const startTime = Date.now();
519
- const docId = `doc_${Date.now()}_${Math.random().toString(36).substring(7)}`;
526
+ const docId = `doc_${Date.now()}_${randomBytes13(4).toString("hex")}`;
520
527
  const now = /* @__PURE__ */ new Date();
521
528
  try {
522
529
  const col = await this.getCollection(collection);
@@ -1059,6 +1066,7 @@ var PostgresDatabase_exports = {};
1059
1066
  __export(PostgresDatabase_exports, {
1060
1067
  PostgresDatabase: () => PostgresDatabase
1061
1068
  });
1069
+ import { randomBytes as randomBytes22 } from "crypto";
1062
1070
  function toPoolConfig(config) {
1063
1071
  const poolConfig = {};
1064
1072
  if (config.connectionString) {
@@ -1209,7 +1217,7 @@ var init_PostgresDatabase = __esm({
1209
1217
  }
1210
1218
  }
1211
1219
  async transaction(fn) {
1212
- const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2)}`;
1220
+ const savepointName = `sp_${Date.now()}_${randomBytes22(4).toString("hex")}`;
1213
1221
  try {
1214
1222
  await this.client.query(`SAVEPOINT ${savepointName}`);
1215
1223
  const result = await fn(this);
@@ -1737,7 +1745,7 @@ var init_RedisCache = __esm({
1737
1745
  * Create a RedisCache from configuration
1738
1746
  */
1739
1747
  static async create(config) {
1740
- const { default: Redis } = await import("ioredis");
1748
+ const { default: Redis2 } = await import("ioredis");
1741
1749
  let client;
1742
1750
  if (config.cluster) {
1743
1751
  const { Cluster } = await import("ioredis");
@@ -1750,7 +1758,7 @@ var init_RedisCache = __esm({
1750
1758
  }
1751
1759
  });
1752
1760
  } else if (config.sentinel) {
1753
- client = new Redis({
1761
+ client = new Redis2({
1754
1762
  sentinels: config.sentinel.sentinels,
1755
1763
  name: config.sentinel.name,
1756
1764
  password: config.password,
@@ -1759,7 +1767,7 @@ var init_RedisCache = __esm({
1759
1767
  });
1760
1768
  } else {
1761
1769
  const options = toIORedisOptions(config);
1762
- client = typeof options === "string" ? new Redis(options) : new Redis(options);
1770
+ client = typeof options === "string" ? new Redis2(options) : new Redis2(options);
1763
1771
  }
1764
1772
  if (!config.lazyConnect) {
1765
1773
  await new Promise((resolve, reject) => {
@@ -1893,9 +1901,9 @@ var init_RedisCache = __esm({
1893
1901
  }
1894
1902
  async subscribe(channel, callback) {
1895
1903
  if (!this.subscriberClient) {
1896
- const { default: Redis } = await import("ioredis");
1904
+ const { default: Redis2 } = await import("ioredis");
1897
1905
  const options = toIORedisOptions(this.config);
1898
- this.subscriberClient = typeof options === "string" ? new Redis(options) : new Redis(options);
1906
+ this.subscriberClient = typeof options === "string" ? new Redis2(options) : new Redis2(options);
1899
1907
  this.subscriberClient.on("message", (ch, message) => {
1900
1908
  const callbacks = this.subscriptions.get(ch);
1901
1909
  if (callbacks) {
@@ -5445,6 +5453,7 @@ __export(PineconeRAG_exports, {
5445
5453
  PineconeRAG: () => PineconeRAG,
5446
5454
  createPineconeRAG: () => createPineconeRAG
5447
5455
  });
5456
+ import { randomBytes as randomBytes23 } from "crypto";
5448
5457
  function createPineconeRAG(config) {
5449
5458
  return new PineconeRAG(config);
5450
5459
  }
@@ -5602,7 +5611,7 @@ var init_PineconeRAG = __esm({
5602
5611
  throw new Error(`Collection ${collection} not found`);
5603
5612
  }
5604
5613
  const now = /* @__PURE__ */ new Date();
5605
- const documentId = `doc_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
5614
+ const documentId = `doc_${Date.now()}_${randomBytes23(4).toString("hex")}`;
5606
5615
  const doc = {
5607
5616
  id: documentId,
5608
5617
  source: document.source,
@@ -6166,6 +6175,7 @@ __export(WeaviateRAG_exports, {
6166
6175
  WeaviateRAG: () => WeaviateRAG,
6167
6176
  createWeaviateRAG: () => createWeaviateRAG
6168
6177
  });
6178
+ import { randomBytes as randomBytes24 } from "crypto";
6169
6179
  function createWeaviateRAG(config) {
6170
6180
  return new WeaviateRAG(config);
6171
6181
  }
@@ -6360,7 +6370,7 @@ var init_WeaviateRAG = __esm({
6360
6370
  const client = await this.getClient();
6361
6371
  const className = this.getClassName(collection);
6362
6372
  const now = /* @__PURE__ */ new Date();
6363
- const documentId = `doc_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
6373
+ const documentId = `doc_${Date.now()}_${randomBytes24(4).toString("hex")}`;
6364
6374
  const doc = {
6365
6375
  id: documentId,
6366
6376
  source: document.source,
@@ -6935,7 +6945,183 @@ var init_WeaviateRAG = __esm({
6935
6945
  }
6936
6946
  });
6937
6947
 
6948
+ // src/adapters/node-crypto/NodeCrypto.ts
6949
+ var NodeCrypto_exports = {};
6950
+ __export(NodeCrypto_exports, {
6951
+ NodeCrypto: () => NodeCrypto
6952
+ });
6953
+ import {
6954
+ randomBytes as randomBytes25,
6955
+ createCipheriv as createCipheriv2,
6956
+ createDecipheriv as createDecipheriv2,
6957
+ createHmac as createHmac2,
6958
+ hkdfSync
6959
+ } from "crypto";
6960
+ var NodeCrypto;
6961
+ var init_NodeCrypto = __esm({
6962
+ "src/adapters/node-crypto/NodeCrypto.ts"() {
6963
+ "use strict";
6964
+ NodeCrypto = class {
6965
+ masterKey;
6966
+ hmacKey;
6967
+ keys = /* @__PURE__ */ new Map();
6968
+ activeKeyId;
6969
+ keyCounter = 0;
6970
+ constructor(config) {
6971
+ if (!config.masterKey || config.masterKey.length < 64) {
6972
+ throw new Error(
6973
+ "NodeCrypto requires a 256-bit master key (64 hex characters)"
6974
+ );
6975
+ }
6976
+ this.masterKey = Buffer.from(config.masterKey, "hex");
6977
+ this.hmacKey = config.hmacKey ? Buffer.from(config.hmacKey, "hex") : Buffer.from(hkdfSync("sha256", this.masterKey, "", "hmac-key", 32));
6978
+ const keyId = this.generateKeyId();
6979
+ const dek = this.deriveDEK(keyId);
6980
+ this.keys.set(keyId, {
6981
+ id: keyId,
6982
+ dek,
6983
+ status: "active",
6984
+ createdAt: /* @__PURE__ */ new Date()
6985
+ });
6986
+ this.activeKeyId = keyId;
6987
+ }
6988
+ async encrypt(plaintext, options) {
6989
+ const keyId = options?.keyId || this.activeKeyId;
6990
+ const stored = this.keys.get(keyId);
6991
+ if (!stored) {
6992
+ throw new Error(`Key not found: ${keyId}`);
6993
+ }
6994
+ if (stored.status === "retired") {
6995
+ throw new Error(`Key is retired and cannot encrypt: ${keyId}`);
6996
+ }
6997
+ if (stored.status === "decrypt-only" && !options?.keyId) {
6998
+ throw new Error(`Key is decrypt-only: ${keyId}`);
6999
+ }
7000
+ const iv = randomBytes25(12);
7001
+ const cipher = createCipheriv2("aes-256-gcm", stored.dek, iv);
7002
+ if (options?.aad) {
7003
+ cipher.setAAD(Buffer.from(options.aad, "utf8"));
7004
+ }
7005
+ const encrypted = Buffer.concat([
7006
+ cipher.update(plaintext, "utf8"),
7007
+ cipher.final()
7008
+ ]);
7009
+ const tag = cipher.getAuthTag();
7010
+ return {
7011
+ ciphertext: encrypted.toString("base64"),
7012
+ iv: iv.toString("base64"),
7013
+ tag: tag.toString("base64"),
7014
+ keyId,
7015
+ algorithm: "aes-256-gcm",
7016
+ version: 1
7017
+ };
7018
+ }
7019
+ async decrypt(field, options) {
7020
+ const stored = this.keys.get(field.keyId);
7021
+ if (!stored) {
7022
+ throw new Error(`Key not found: ${field.keyId}`);
7023
+ }
7024
+ if (stored.status === "retired") {
7025
+ throw new Error(`Key is retired and cannot decrypt: ${field.keyId}`);
7026
+ }
7027
+ const decipher = createDecipheriv2(
7028
+ "aes-256-gcm",
7029
+ stored.dek,
7030
+ Buffer.from(field.iv, "base64")
7031
+ );
7032
+ decipher.setAuthTag(Buffer.from(field.tag, "base64"));
7033
+ if (options?.aad) {
7034
+ decipher.setAAD(Buffer.from(options.aad, "utf8"));
7035
+ }
7036
+ const decrypted = Buffer.concat([
7037
+ decipher.update(Buffer.from(field.ciphertext, "base64")),
7038
+ decipher.final()
7039
+ ]);
7040
+ return decrypted.toString("utf8");
7041
+ }
7042
+ async encryptDeterministic(plaintext, options) {
7043
+ const hash = await this.computeHash(plaintext);
7044
+ const encrypted = await this.encrypt(plaintext, options);
7045
+ return { hash, encrypted };
7046
+ }
7047
+ async computeHash(plaintext) {
7048
+ return createHmac2("sha256", this.hmacKey).update(plaintext, "utf8").digest("hex");
7049
+ }
7050
+ async encryptBatch(fields, options) {
7051
+ const result = {};
7052
+ for (const [key, value] of Object.entries(fields)) {
7053
+ result[key] = await this.encrypt(value, options);
7054
+ }
7055
+ return result;
7056
+ }
7057
+ async decryptBatch(fields, options) {
7058
+ const result = {};
7059
+ for (const [key, value] of Object.entries(fields)) {
7060
+ result[key] = await this.decrypt(value, options);
7061
+ }
7062
+ return result;
7063
+ }
7064
+ async rotateKey() {
7065
+ const previousKeyId = this.activeKeyId;
7066
+ const currentKey = this.keys.get(previousKeyId);
7067
+ if (currentKey) {
7068
+ currentKey.status = "decrypt-only";
7069
+ }
7070
+ const newKeyId = this.generateKeyId();
7071
+ const dek = this.deriveDEK(newKeyId);
7072
+ this.keys.set(newKeyId, {
7073
+ id: newKeyId,
7074
+ dek,
7075
+ status: "active",
7076
+ createdAt: /* @__PURE__ */ new Date()
7077
+ });
7078
+ this.activeKeyId = newKeyId;
7079
+ return { newKeyId, previousKeyId };
7080
+ }
7081
+ async reEncrypt(field, options) {
7082
+ const plaintext = await this.decrypt(field);
7083
+ return this.encrypt(plaintext, options);
7084
+ }
7085
+ async listKeys() {
7086
+ return Array.from(this.keys.values()).map((k) => ({
7087
+ keyId: k.id,
7088
+ createdAt: k.createdAt,
7089
+ status: k.status
7090
+ }));
7091
+ }
7092
+ async getActiveKeyId() {
7093
+ return this.activeKeyId;
7094
+ }
7095
+ async healthCheck() {
7096
+ try {
7097
+ const testPlain = "health-check-" + randomBytes25(4).toString("hex");
7098
+ const encrypted = await this.encrypt(testPlain);
7099
+ const decrypted = await this.decrypt(encrypted);
7100
+ return decrypted === testPlain;
7101
+ } catch {
7102
+ return false;
7103
+ }
7104
+ }
7105
+ /**
7106
+ * Derive a Data Encryption Key from the master key using HKDF.
7107
+ */
7108
+ deriveDEK(keyId) {
7109
+ return Buffer.from(
7110
+ hkdfSync("sha256", this.masterKey, keyId, "dek-derivation", 32)
7111
+ );
7112
+ }
7113
+ generateKeyId() {
7114
+ this.keyCounter++;
7115
+ const timestamp = Date.now().toString(36);
7116
+ const random = randomBytes25(4).toString("hex");
7117
+ return `dek_${timestamp}_${random}_${this.keyCounter}`;
7118
+ }
7119
+ };
7120
+ }
7121
+ });
7122
+
6938
7123
  // src/interfaces/IQueue.ts
7124
+ import { randomBytes } from "crypto";
6939
7125
  function calculateBackoff(attempt, options) {
6940
7126
  if (options.type === "fixed") {
6941
7127
  return options.delay;
@@ -6946,7 +7132,7 @@ function calculateBackoff(attempt, options) {
6946
7132
  }
6947
7133
  function generateJobId() {
6948
7134
  const timestamp = Date.now().toString(36);
6949
- const random = Math.random().toString(36).substring(2, 10);
7135
+ const random = randomBytes(4).toString("hex");
6950
7136
  return `job_${timestamp}_${random}`;
6951
7137
  }
6952
7138
 
@@ -7297,6 +7483,7 @@ function createScopedMetrics(metrics, prefix, defaultTags = {}) {
7297
7483
  }
7298
7484
 
7299
7485
  // src/interfaces/ISecrets.ts
7486
+ import { randomBytes as randomBytes2 } from "crypto";
7300
7487
  var EnvSecrets = class {
7301
7488
  prefix;
7302
7489
  cache = /* @__PURE__ */ new Map();
@@ -7497,12 +7684,7 @@ var MemorySecrets = class {
7497
7684
  return true;
7498
7685
  }
7499
7686
  generateSecureValue(length = 32) {
7500
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
7501
- let result = "";
7502
- for (let i = 0; i < length; i++) {
7503
- result += chars[Math.floor(Math.random() * chars.length)];
7504
- }
7505
- return result;
7687
+ return randomBytes2(length).toString("base64url").slice(0, length);
7506
7688
  }
7507
7689
  /**
7508
7690
  * Clear all secrets (for testing)
@@ -7520,6 +7702,7 @@ var MemorySecrets = class {
7520
7702
  };
7521
7703
 
7522
7704
  // src/interfaces/ITracing.ts
7705
+ import { randomBytes as randomBytes3 } from "crypto";
7523
7706
  var MemorySpan = class {
7524
7707
  name;
7525
7708
  context;
@@ -7539,7 +7722,7 @@ var MemorySpan = class {
7539
7722
  };
7540
7723
  }
7541
7724
  generateSpanId() {
7542
- return Math.random().toString(16).substring(2, 18).padStart(16, "0");
7725
+ return randomBytes3(8).toString("hex");
7543
7726
  }
7544
7727
  setAttribute(key, value) {
7545
7728
  this._attributes[key] = value;
@@ -7599,7 +7782,7 @@ var MemoryTracing = class {
7599
7782
  this.traceId = this.generateTraceId();
7600
7783
  }
7601
7784
  generateTraceId() {
7602
- return Math.random().toString(16).substring(2, 34).padStart(32, "0");
7785
+ return randomBytes3(16).toString("hex");
7603
7786
  }
7604
7787
  startSpan(name, options) {
7605
7788
  const span = new MemorySpan(
@@ -7752,9 +7935,10 @@ var NoopTracing = class {
7752
7935
  };
7753
7936
 
7754
7937
  // src/interfaces/IErrorReporter.ts
7938
+ import { randomBytes as randomBytes4 } from "crypto";
7755
7939
  function generateErrorId() {
7756
7940
  const timestamp = Date.now().toString(36);
7757
- const random = Math.random().toString(36).substring(2, 10);
7941
+ const random = randomBytes4(4).toString("hex");
7758
7942
  return `err_${timestamp}_${random}`;
7759
7943
  }
7760
7944
  function generateFingerprint(error) {
@@ -7798,9 +7982,10 @@ function createErrorReport(error, context, options) {
7798
7982
  }
7799
7983
 
7800
7984
  // src/interfaces/IAuditLog.ts
7985
+ import { randomBytes as randomBytes5 } from "crypto";
7801
7986
  function generateAuditId() {
7802
7987
  const timestamp = Date.now().toString(36);
7803
- const random = Math.random().toString(36).substring(2, 10);
7988
+ const random = randomBytes5(4).toString("hex");
7804
7989
  return `aud_${timestamp}${random}`;
7805
7990
  }
7806
7991
  function generateChecksum(event) {
@@ -7966,9 +8151,10 @@ var AuditEvents = {
7966
8151
  };
7967
8152
 
7968
8153
  // src/interfaces/IScheduler.ts
8154
+ import { randomBytes as randomBytes6 } from "crypto";
7969
8155
  function generateScheduleId() {
7970
8156
  const timestamp = Date.now().toString(36);
7971
- const random = Math.random().toString(36).substring(2, 8);
8157
+ const random = randomBytes6(4).toString("hex");
7972
8158
  return `sch_${timestamp}${random}`;
7973
8159
  }
7974
8160
  function getNextCronRun(cron, after = /* @__PURE__ */ new Date(), timezone) {
@@ -8027,28 +8213,24 @@ function describeCron(cron) {
8027
8213
  }
8028
8214
 
8029
8215
  // src/interfaces/IWebhook.ts
8216
+ import { randomBytes as randomBytes7 } from "crypto";
8030
8217
  function generateWebhookId() {
8031
8218
  const timestamp = Date.now().toString(36);
8032
- const random = Math.random().toString(36).substring(2, 10);
8219
+ const random = randomBytes7(6).toString("hex");
8033
8220
  return `wh_${timestamp}${random}`;
8034
8221
  }
8035
8222
  function generateDeliveryId() {
8036
8223
  const timestamp = Date.now().toString(36);
8037
- const random = Math.random().toString(36).substring(2, 10);
8224
+ const random = randomBytes7(6).toString("hex");
8038
8225
  return `del_${timestamp}${random}`;
8039
8226
  }
8040
8227
  function generateEventId() {
8041
8228
  const timestamp = Date.now().toString(36);
8042
- const random = Math.random().toString(36).substring(2, 10);
8229
+ const random = randomBytes7(6).toString("hex");
8043
8230
  return `evt_${timestamp}${random}`;
8044
8231
  }
8045
8232
  function generateWebhookSecret(length = 32) {
8046
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
8047
- let secret = "whsec_";
8048
- for (let i = 0; i < length; i++) {
8049
- secret += chars.charAt(Math.floor(Math.random() * chars.length));
8050
- }
8051
- return secret;
8233
+ return `whsec_${randomBytes7(length).toString("base64url").slice(0, length)}`;
8052
8234
  }
8053
8235
  function matchEventType(eventType, pattern) {
8054
8236
  if (eventType === pattern || pattern === "*" || pattern === "**") {
@@ -8125,9 +8307,10 @@ var WebhookEventTypes = {
8125
8307
  };
8126
8308
 
8127
8309
  // src/interfaces/INotification.ts
8310
+ import { randomBytes as randomBytes8 } from "crypto";
8128
8311
  function generateNotificationId() {
8129
8312
  const timestamp = Date.now().toString(36);
8130
- const random = Math.random().toString(36).substring(2, 10);
8313
+ const random = randomBytes8(4).toString("hex");
8131
8314
  return `notif_${timestamp}${random}`;
8132
8315
  }
8133
8316
  function isInQuietHours(preferences) {
@@ -8617,6 +8800,7 @@ var MemoryAuth = class {
8617
8800
  };
8618
8801
 
8619
8802
  // src/interfaces/IPayment.ts
8803
+ import { randomBytes as randomBytes9 } from "crypto";
8620
8804
  function createPaymentError(code, message, originalError) {
8621
8805
  return { code, message, originalError };
8622
8806
  }
@@ -8648,7 +8832,7 @@ function formatAmount(amount, currency, locale = "en-US") {
8648
8832
  }
8649
8833
  function generatePaymentId(prefix = "pi") {
8650
8834
  const timestamp = Date.now().toString(36);
8651
- const random = Math.random().toString(36).substring(2, 10);
8835
+ const random = randomBytes9(8).toString("hex");
8652
8836
  return `${prefix}_${timestamp}${random}`;
8653
8837
  }
8654
8838
  var MemoryPayment = class {
@@ -8706,7 +8890,7 @@ var MemoryPayment = class {
8706
8890
  amount: options.amount,
8707
8891
  currency: options.currency,
8708
8892
  status: options.paymentMethodId ? "requires_confirmation" : "requires_payment_method",
8709
- clientSecret: `${id}_secret_${Math.random().toString(36).substring(2, 15)}`,
8893
+ clientSecret: `${id}_secret_${randomBytes9(16).toString("base64url")}`,
8710
8894
  metadata: options.metadata,
8711
8895
  description: options.description,
8712
8896
  receiptEmail: options.receiptEmail,
@@ -9021,6 +9205,7 @@ var MemoryPayment = class {
9021
9205
  };
9022
9206
 
9023
9207
  // src/interfaces/IAuthSSO.ts
9208
+ import { randomBytes as randomBytes10 } from "crypto";
9024
9209
  var MemoryAuthSSO = class {
9025
9210
  samlConfigs = /* @__PURE__ */ new Map();
9026
9211
  oidcConfigs = /* @__PURE__ */ new Map();
@@ -9052,7 +9237,7 @@ var MemoryAuthSSO = class {
9052
9237
  if (!config) {
9053
9238
  throw new Error("SAML not configured for tenant");
9054
9239
  }
9055
- const id = `_${Math.random().toString(36).substring(2)}`;
9240
+ const id = `_${randomBytes10(8).toString("hex")}`;
9056
9241
  return {
9057
9242
  id,
9058
9243
  redirectUrl: `${config.ssoUrl}?SAMLRequest=mock_request&RelayState=${options.relayState ?? ""}`,
@@ -9064,7 +9249,7 @@ var MemoryAuthSSO = class {
9064
9249
  }
9065
9250
  async processSamlResponse(_samlResponse, _relayState) {
9066
9251
  const user = {
9067
- id: `saml_${Math.random().toString(36).substring(2)}`,
9252
+ id: `saml_${randomBytes10(8).toString("hex")}`,
9068
9253
  email: "saml.user@example.com",
9069
9254
  emailVerified: true,
9070
9255
  metadata: { ssoProvider: "saml" },
@@ -9074,7 +9259,7 @@ var MemoryAuthSSO = class {
9074
9259
  success: true,
9075
9260
  user,
9076
9261
  session: {
9077
- accessToken: `saml_token_${Math.random().toString(36)}`,
9262
+ accessToken: `saml_token_${randomBytes10(8).toString("hex")}`,
9078
9263
  expiresAt: new Date(Date.now() + 36e5),
9079
9264
  user
9080
9265
  },
@@ -9111,8 +9296,8 @@ var MemoryAuthSSO = class {
9111
9296
  }
9112
9297
  // OIDC Authentication
9113
9298
  async initiateOidcLogin(options) {
9114
- const state = options.state ?? Math.random().toString(36).substring(2);
9115
- const nonce = Math.random().toString(36).substring(2);
9299
+ const state = options.state ?? randomBytes10(8).toString("hex");
9300
+ const nonce = randomBytes10(8).toString("hex");
9116
9301
  return {
9117
9302
  state,
9118
9303
  redirectUrl: `https://idp.example.com/authorize?client_id=mock&redirect_uri=${encodeURIComponent(options.redirectUri)}&state=${state}`,
@@ -9123,7 +9308,7 @@ var MemoryAuthSSO = class {
9123
9308
  }
9124
9309
  async processOidcCallback(_code, _state, _codeVerifier) {
9125
9310
  const user = {
9126
- id: `oidc_${Math.random().toString(36).substring(2)}`,
9311
+ id: `oidc_${randomBytes10(8).toString("hex")}`,
9127
9312
  email: "oidc.user@example.com",
9128
9313
  emailVerified: true,
9129
9314
  metadata: { ssoProvider: "oidc" },
@@ -9133,7 +9318,7 @@ var MemoryAuthSSO = class {
9133
9318
  success: true,
9134
9319
  user,
9135
9320
  session: {
9136
- accessToken: `oidc_token_${Math.random().toString(36)}`,
9321
+ accessToken: `oidc_token_${randomBytes10(8).toString("hex")}`,
9137
9322
  expiresAt: new Date(Date.now() + 36e5),
9138
9323
  user
9139
9324
  },
@@ -9142,7 +9327,7 @@ var MemoryAuthSSO = class {
9142
9327
  }
9143
9328
  async refreshOidcTokens(_refreshToken, _tenantId) {
9144
9329
  return {
9145
- accessToken: `refreshed_token_${Math.random().toString(36)}`,
9330
+ accessToken: `refreshed_token_${randomBytes10(8).toString("hex")}`,
9146
9331
  expiresIn: 3600
9147
9332
  };
9148
9333
  }
@@ -9172,7 +9357,7 @@ var MemoryAuthSSO = class {
9172
9357
  }
9173
9358
  // SCIM
9174
9359
  async configureScim(config) {
9175
- const token = `scim_token_${Math.random().toString(36)}`;
9360
+ const token = `scim_token_${randomBytes10(8).toString("hex")}`;
9176
9361
  this.scimConfigs.set(config.tenantId, { ...config, bearerToken: token });
9177
9362
  return { bearerToken: token };
9178
9363
  }
@@ -9185,7 +9370,7 @@ var MemoryAuthSSO = class {
9185
9370
  async regenerateScimToken(tenantId) {
9186
9371
  const config = this.scimConfigs.get(tenantId);
9187
9372
  if (!config) throw new Error("SCIM not configured");
9188
- const token = `scim_token_${Math.random().toString(36)}`;
9373
+ const token = `scim_token_${randomBytes10(8).toString("hex")}`;
9189
9374
  config.bearerToken = token;
9190
9375
  return { bearerToken: token };
9191
9376
  }
@@ -9194,7 +9379,7 @@ var MemoryAuthSSO = class {
9194
9379
  }
9195
9380
  // Domain Verification
9196
9381
  async initiateDomainVerification(tenantId, domain) {
9197
- const token = `dll-verify-${Math.random().toString(36).substring(2)}`;
9382
+ const token = `dll-verify-${randomBytes10(8).toString("hex")}`;
9198
9383
  this.pendingVerifications.set(`${tenantId}:${domain}`, { domain, token });
9199
9384
  return {
9200
9385
  verificationMethod: "dns_txt",
@@ -9260,6 +9445,7 @@ var MemoryAuthSSO = class {
9260
9445
  };
9261
9446
 
9262
9447
  // src/interfaces/ITenant.ts
9448
+ import { randomBytes as randomBytes11 } from "crypto";
9263
9449
  var tenantContextStorage = /* @__PURE__ */ new Map();
9264
9450
  var contextIdCounter = 0;
9265
9451
  var currentContextId = null;
@@ -9327,7 +9513,7 @@ var MemoryTenant = class {
9327
9513
  // Tenant CRUD
9328
9514
  async createTenant(options) {
9329
9515
  const tenant = {
9330
- id: `tenant_${Math.random().toString(36).substring(2)}`,
9516
+ id: `tenant_${randomBytes11(8).toString("hex")}`,
9331
9517
  slug: options.slug,
9332
9518
  name: options.name,
9333
9519
  status: "active",
@@ -9448,7 +9634,7 @@ var MemoryTenant = class {
9448
9634
  }
9449
9635
  async addMember(tenantId, userId, role) {
9450
9636
  const member = {
9451
- id: `member_${Math.random().toString(36).substring(2)}`,
9637
+ id: `member_${randomBytes11(8).toString("hex")}`,
9452
9638
  tenantId,
9453
9639
  userId,
9454
9640
  role,
@@ -9489,12 +9675,12 @@ var MemoryTenant = class {
9489
9675
  }
9490
9676
  async inviteMember(tenantId, options) {
9491
9677
  const invitation = {
9492
- id: `inv_${Math.random().toString(36).substring(2)}`,
9678
+ id: `inv_${randomBytes11(8).toString("hex")}`,
9493
9679
  tenantId,
9494
9680
  email: options.email,
9495
9681
  role: options.role,
9496
9682
  invitedBy: "system",
9497
- token: Math.random().toString(36).substring(2),
9683
+ token: randomBytes11(16).toString("base64url"),
9498
9684
  status: "pending",
9499
9685
  createdAt: /* @__PURE__ */ new Date(),
9500
9686
  expiresAt: new Date(
@@ -9655,6 +9841,7 @@ var MemoryTenant = class {
9655
9841
  init_IAI();
9656
9842
 
9657
9843
  // src/interfaces/IPromptStore.ts
9844
+ import { randomBytes as randomBytes12 } from "crypto";
9658
9845
  var MemoryPromptStore = class {
9659
9846
  // userId -> variantId
9660
9847
  constructor(config = {}) {
@@ -9670,7 +9857,7 @@ var MemoryPromptStore = class {
9670
9857
  // Prompt CRUD
9671
9858
  // ─────────────────────────────────────────────────────────────
9672
9859
  async create(prompt) {
9673
- const id = `prompt_${Date.now()}_${Math.random().toString(36).substring(7)}`;
9860
+ const id = `prompt_${Date.now()}_${randomBytes12(4).toString("hex")}`;
9674
9861
  const now = /* @__PURE__ */ new Date();
9675
9862
  const newPrompt = {
9676
9863
  ...prompt,
@@ -9685,7 +9872,7 @@ var MemoryPromptStore = class {
9685
9872
  this.prompts.set(id, newPrompt);
9686
9873
  this.prompts.set(prompt.slug, newPrompt);
9687
9874
  const version = {
9688
- id: `pv_${Date.now()}_${Math.random().toString(36).substring(7)}`,
9875
+ id: `pv_${Date.now()}_${randomBytes12(4).toString("hex")}`,
9689
9876
  promptId: id,
9690
9877
  version: 1,
9691
9878
  content: prompt.content,
@@ -9720,7 +9907,7 @@ var MemoryPromptStore = class {
9720
9907
  latestVersion.isLatest = false;
9721
9908
  }
9722
9909
  const newVersion = {
9723
- id: `pv_${Date.now()}_${Math.random().toString(36).substring(7)}`,
9910
+ id: `pv_${Date.now()}_${randomBytes12(4).toString("hex")}`,
9724
9911
  promptId: prompt.id,
9725
9912
  version: versions.length + 1,
9726
9913
  content: updates.content,
@@ -9965,7 +10152,7 @@ ${v2.content}`;
9965
10152
  // A/B Testing
9966
10153
  // ─────────────────────────────────────────────────────────────
9967
10154
  async createExperiment(experiment) {
9968
- const id = `exp_${Date.now()}_${Math.random().toString(36).substring(7)}`;
10155
+ const id = `exp_${Date.now()}_${randomBytes12(4).toString("hex")}`;
9969
10156
  const now = /* @__PURE__ */ new Date();
9970
10157
  const newExperiment = {
9971
10158
  ...experiment,
@@ -10042,7 +10229,7 @@ ${v2.content}`;
10042
10229
  // Prompt Chains
10043
10230
  // ─────────────────────────────────────────────────────────────
10044
10231
  async createChain(chain) {
10045
- const id = `chain_${Date.now()}_${Math.random().toString(36).substring(7)}`;
10232
+ const id = `chain_${Date.now()}_${randomBytes12(4).toString("hex")}`;
10046
10233
  const now = /* @__PURE__ */ new Date();
10047
10234
  const newChain = {
10048
10235
  ...chain,
@@ -10133,7 +10320,7 @@ ${v2.content}`;
10133
10320
  async recordUsage(record) {
10134
10321
  const usageRecord = {
10135
10322
  ...record,
10136
- id: `usage_${Date.now()}_${Math.random().toString(36).substring(7)}`,
10323
+ id: `usage_${Date.now()}_${randomBytes12(4).toString("hex")}`,
10137
10324
  createdAt: /* @__PURE__ */ new Date()
10138
10325
  };
10139
10326
  if (this.config.trackUsage !== false) {
@@ -10237,6 +10424,7 @@ ${v2.content}`;
10237
10424
  init_IRAG();
10238
10425
 
10239
10426
  // src/interfaces/IAIUsage.ts
10427
+ import { randomBytes as randomBytes14 } from "crypto";
10240
10428
  var MemoryAIUsage = class {
10241
10429
  constructor(config = {}) {
10242
10430
  this.config = config;
@@ -10270,7 +10458,7 @@ var MemoryAIUsage = class {
10270
10458
  async record(record) {
10271
10459
  const newRecord = {
10272
10460
  ...record,
10273
- id: `usage_${Date.now()}_${Math.random().toString(36).substring(7)}`,
10461
+ id: `usage_${Date.now()}_${randomBytes14(4).toString("hex")}`,
10274
10462
  createdAt: /* @__PURE__ */ new Date()
10275
10463
  };
10276
10464
  this.records.push(newRecord);
@@ -10351,7 +10539,7 @@ var MemoryAIUsage = class {
10351
10539
  const period = this.getPeriodBounds(quota.period, /* @__PURE__ */ new Date());
10352
10540
  const newQuota = {
10353
10541
  ...quota,
10354
- id: existingQuota?.id || `quota_${Date.now()}_${Math.random().toString(36).substring(7)}`,
10542
+ id: existingQuota?.id || `quota_${Date.now()}_${randomBytes14(4).toString("hex")}`,
10355
10543
  used: existingQuota?.used || 0,
10356
10544
  periodStart: period.start,
10357
10545
  periodEnd: period.end
@@ -10445,7 +10633,7 @@ var MemoryAIUsage = class {
10445
10633
  const period = this.getPeriodBounds(budget.period, /* @__PURE__ */ new Date());
10446
10634
  const newBudget = {
10447
10635
  ...budget,
10448
- id: existingBudget?.id || `budget_${Date.now()}_${Math.random().toString(36).substring(7)}`,
10636
+ id: existingBudget?.id || `budget_${Date.now()}_${randomBytes14(4).toString("hex")}`,
10449
10637
  spent: existingBudget?.spent || 0,
10450
10638
  periodStart: period.start,
10451
10639
  periodEnd: period.end
@@ -10709,7 +10897,7 @@ var MemoryAIUsage = class {
10709
10897
  const items = Array.from(itemsMap.values());
10710
10898
  const subtotal = items.reduce((sum, item) => sum + item.costUsd, 0);
10711
10899
  const invoice = {
10712
- id: `inv_${Date.now()}_${Math.random().toString(36).substring(7)}`,
10900
+ id: `inv_${Date.now()}_${randomBytes14(4).toString("hex")}`,
10713
10901
  tenantId,
10714
10902
  periodStart,
10715
10903
  periodEnd,
@@ -10922,7 +11110,7 @@ var MemoryAIUsage = class {
10922
11110
  );
10923
11111
  if (existingAlert) return;
10924
11112
  this.alerts.push({
10925
- id: `alert_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11113
+ id: `alert_${Date.now()}_${randomBytes14(4).toString("hex")}`,
10926
11114
  tenantId,
10927
11115
  type,
10928
11116
  severity,
@@ -11051,6 +11239,7 @@ var MemoryAIUsage = class {
11051
11239
  };
11052
11240
 
11053
11241
  // src/interfaces/IDevice.ts
11242
+ import { randomBytes as randomBytes15 } from "crypto";
11054
11243
  var MemoryDevice = class {
11055
11244
  constructor(config = {}) {
11056
11245
  this.config = config;
@@ -11075,7 +11264,7 @@ var MemoryDevice = class {
11075
11264
  const now = /* @__PURE__ */ new Date();
11076
11265
  const newDevice = {
11077
11266
  ...device,
11078
- id: `dev_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11267
+ id: `dev_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11079
11268
  status: "active",
11080
11269
  connectionState: "disconnected",
11081
11270
  tags: device.tags || [],
@@ -11198,7 +11387,7 @@ var MemoryDevice = class {
11198
11387
  // Provisioning
11199
11388
  // ─────────────────────────────────────────────────────────────
11200
11389
  async provision(request) {
11201
- const id = `prov_${Date.now()}_${Math.random().toString(36).substring(7)}`;
11390
+ const id = `prov_${Date.now()}_${randomBytes15(4).toString("hex")}`;
11202
11391
  const newRequest = {
11203
11392
  ...request,
11204
11393
  id,
@@ -11210,7 +11399,7 @@ var MemoryDevice = class {
11210
11399
  const result = {
11211
11400
  credentials: {
11212
11401
  type: request.config.authMethod || "token",
11213
- token: `tok_${Date.now()}_${Math.random().toString(36).substring(7)}`
11402
+ token: `tok_${Date.now()}_${randomBytes15(16).toString("hex")}`
11214
11403
  },
11215
11404
  endpoint: "mqtt://localhost:1883",
11216
11405
  mqttBroker: "mqtt://localhost:1883"
@@ -11253,7 +11442,7 @@ var MemoryDevice = class {
11253
11442
  }
11254
11443
  }
11255
11444
  async generateRegistrationCode(deviceType, tenantId, expiresInHours = 24) {
11256
- const code = `REG_${Math.random().toString(36).substring(2, 10).toUpperCase()}`;
11445
+ const code = `REG_${randomBytes15(4).toString("hex").toUpperCase()}`;
11257
11446
  this.registrationCodes.set(code, {
11258
11447
  deviceType,
11259
11448
  tenantId,
@@ -11353,7 +11542,7 @@ var MemoryDevice = class {
11353
11542
  async ingestTelemetry(message) {
11354
11543
  const newMessage = {
11355
11544
  ...message,
11356
- id: `tel_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11545
+ id: `tel_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11357
11546
  receivedAt: /* @__PURE__ */ new Date()
11358
11547
  };
11359
11548
  if (this.config.storeTelemetry !== false) {
@@ -11433,7 +11622,7 @@ var MemoryDevice = class {
11433
11622
  // ─────────────────────────────────────────────────────────────
11434
11623
  async sendCommand(deviceId, name, payload, options) {
11435
11624
  const command = {
11436
- id: `cmd_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11625
+ id: `cmd_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11437
11626
  deviceId,
11438
11627
  name,
11439
11628
  payload,
@@ -11496,7 +11685,7 @@ var MemoryDevice = class {
11496
11685
  async createFirmware(firmware) {
11497
11686
  const newFirmware = {
11498
11687
  ...firmware,
11499
- id: `fw_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11688
+ id: `fw_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11500
11689
  status: "draft",
11501
11690
  createdAt: /* @__PURE__ */ new Date()
11502
11691
  };
@@ -11548,7 +11737,7 @@ var MemoryDevice = class {
11548
11737
  throw new Error(`Firmware not found: ${firmwareVersionId}`);
11549
11738
  }
11550
11739
  const update = {
11551
- id: `upd_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11740
+ id: `upd_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11552
11741
  deviceId,
11553
11742
  firmwareVersionId,
11554
11743
  targetVersion: firmware.version,
@@ -11602,7 +11791,7 @@ var MemoryDevice = class {
11602
11791
  const now = /* @__PURE__ */ new Date();
11603
11792
  const newGroup = {
11604
11793
  ...group,
11605
- id: `grp_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11794
+ id: `grp_${Date.now()}_${randomBytes15(4).toString("hex")}`,
11606
11795
  deviceCount: 0,
11607
11796
  tags: group.tags || [],
11608
11797
  attributes: group.attributes || {},
@@ -11722,6 +11911,7 @@ var MemoryDevice = class {
11722
11911
  };
11723
11912
 
11724
11913
  // src/interfaces/IBilling.ts
11914
+ import { randomBytes as randomBytes16 } from "crypto";
11725
11915
  var MemoryBilling = class {
11726
11916
  constructor(config = {}) {
11727
11917
  this.config = config;
@@ -11742,7 +11932,7 @@ var MemoryBilling = class {
11742
11932
  async createProduct(product) {
11743
11933
  const newProduct = {
11744
11934
  ...product,
11745
- id: `prod_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11935
+ id: `prod_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11746
11936
  features: product.features || [],
11747
11937
  metadata: product.metadata || {},
11748
11938
  createdAt: /* @__PURE__ */ new Date(),
@@ -11770,7 +11960,7 @@ var MemoryBilling = class {
11770
11960
  async createPrice(price) {
11771
11961
  const newPrice = {
11772
11962
  ...price,
11773
- id: `price_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11963
+ id: `price_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11774
11964
  metadata: price.metadata || {},
11775
11965
  createdAt: /* @__PURE__ */ new Date(),
11776
11966
  updatedAt: /* @__PURE__ */ new Date()
@@ -11801,7 +11991,7 @@ var MemoryBilling = class {
11801
11991
  async createMeter(meter) {
11802
11992
  const newMeter = {
11803
11993
  ...meter,
11804
- id: `meter_${Date.now()}_${Math.random().toString(36).substring(7)}`,
11994
+ id: `meter_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11805
11995
  createdAt: /* @__PURE__ */ new Date(),
11806
11996
  updatedAt: /* @__PURE__ */ new Date()
11807
11997
  };
@@ -11835,13 +12025,13 @@ var MemoryBilling = class {
11835
12025
  const trialDays = options.trialDays ?? price.trialDays ?? 0;
11836
12026
  const periodEnd = this.addPeriod(now, price.billingPeriod);
11837
12027
  const subscription = {
11838
- id: `sub_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12028
+ id: `sub_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11839
12029
  customerId: options.customerId,
11840
12030
  tenantId: options.tenantId,
11841
12031
  status: trialDays > 0 ? "trialing" : "active",
11842
12032
  items: [
11843
12033
  {
11844
- id: `si_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12034
+ id: `si_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11845
12035
  priceId: options.priceId,
11846
12036
  quantity: options.quantity || 1
11847
12037
  }
@@ -11932,7 +12122,7 @@ var MemoryBilling = class {
11932
12122
  const sub = await this.getSubscription(subscriptionId);
11933
12123
  if (!sub) throw new Error(`Subscription not found: ${subscriptionId}`);
11934
12124
  sub.items.push({
11935
- id: `si_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12125
+ id: `si_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11936
12126
  priceId,
11937
12127
  quantity: quantity || 1
11938
12128
  });
@@ -11984,7 +12174,7 @@ var MemoryBilling = class {
11984
12174
  if (existing) return existing;
11985
12175
  }
11986
12176
  const event = {
11987
- id: `ue_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12177
+ id: `ue_${Date.now()}_${randomBytes16(4).toString("hex")}`,
11988
12178
  subscriptionId,
11989
12179
  customerId: sub.customerId,
11990
12180
  meterId: meter.id,
@@ -12055,7 +12245,7 @@ var MemoryBilling = class {
12055
12245
  if (price) {
12056
12246
  const unitAmount = price.unitAmount || 0;
12057
12247
  lineItems.push({
12058
- id: `ii_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12248
+ id: `ii_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12059
12249
  priceId: item.priceId,
12060
12250
  description: price.name,
12061
12251
  quantity: item.quantity,
@@ -12070,7 +12260,7 @@ var MemoryBilling = class {
12070
12260
  const usageSummary = await this.getUsageSummary(subscriptionId);
12071
12261
  for (const usage of usageSummary) {
12072
12262
  lineItems.push({
12073
- id: `ii_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12263
+ id: `ii_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12074
12264
  description: `${usage.meterName}: ${usage.total} ${usage.unit}`,
12075
12265
  quantity: usage.total,
12076
12266
  unitAmount: usage.cost / usage.total,
@@ -12093,7 +12283,7 @@ var MemoryBilling = class {
12093
12283
  const tax = (subtotal - discount) * (taxRate / 100);
12094
12284
  const total = subtotal - discount + tax;
12095
12285
  const invoice = {
12096
- id: `inv_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12286
+ id: `inv_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12097
12287
  customerId: sub.customerId,
12098
12288
  subscriptionId,
12099
12289
  tenantId: sub.tenantId,
@@ -12124,14 +12314,14 @@ var MemoryBilling = class {
12124
12314
  async createInvoice(options) {
12125
12315
  const lineItems = options.lineItems.map((item) => ({
12126
12316
  ...item,
12127
- id: `ii_${Date.now()}_${Math.random().toString(36).substring(7)}`
12317
+ id: `ii_${Date.now()}_${randomBytes16(4).toString("hex")}`
12128
12318
  }));
12129
12319
  const subtotal = lineItems.reduce((sum, item) => sum + item.amount, 0);
12130
12320
  const taxRate = this.config.defaultTaxRate || 0;
12131
12321
  const tax = subtotal * (taxRate / 100);
12132
12322
  const total = subtotal + tax;
12133
12323
  const invoice = {
12134
- id: `inv_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12324
+ id: `inv_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12135
12325
  customerId: options.customerId,
12136
12326
  tenantId: options.tenantId,
12137
12327
  number: `${this.config.invoiceNumberPrefix || "INV-"}${++this.invoiceCounter}`,
@@ -12220,7 +12410,7 @@ var MemoryBilling = class {
12220
12410
  async createDunningConfig(config) {
12221
12411
  const newConfig = {
12222
12412
  ...config,
12223
- id: `dun_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12413
+ id: `dun_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12224
12414
  createdAt: /* @__PURE__ */ new Date(),
12225
12415
  updatedAt: /* @__PURE__ */ new Date()
12226
12416
  };
@@ -12246,7 +12436,7 @@ var MemoryBilling = class {
12246
12436
  const invoice = await this.getInvoice(invoiceId);
12247
12437
  if (!invoice) throw new Error(`Invoice not found: ${invoiceId}`);
12248
12438
  const attempt = {
12249
- id: `da_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12439
+ id: `da_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12250
12440
  invoiceId,
12251
12441
  attemptNumber: invoice.attemptCount + 1,
12252
12442
  action: "retry_payment",
@@ -12278,7 +12468,7 @@ var MemoryBilling = class {
12278
12468
  balance.updatedAt = /* @__PURE__ */ new Date();
12279
12469
  this.creditBalances.set(customerId, balance);
12280
12470
  const transaction = {
12281
- id: `ct_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12471
+ id: `ct_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12282
12472
  customerId,
12283
12473
  type: options?.type || "manual",
12284
12474
  amount,
@@ -12303,7 +12493,7 @@ var MemoryBilling = class {
12303
12493
  balance.updatedAt = /* @__PURE__ */ new Date();
12304
12494
  this.creditBalances.set(customerId, balance);
12305
12495
  const transaction = {
12306
- id: `ct_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12496
+ id: `ct_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12307
12497
  customerId,
12308
12498
  type: "manual",
12309
12499
  amount: -amount,
@@ -12327,7 +12517,7 @@ var MemoryBilling = class {
12327
12517
  async createCoupon(coupon) {
12328
12518
  const newCoupon = {
12329
12519
  ...coupon,
12330
- id: `coup_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12520
+ id: `coup_${Date.now()}_${randomBytes16(4).toString("hex")}`,
12331
12521
  timesRedeemed: 0,
12332
12522
  createdAt: /* @__PURE__ */ new Date(),
12333
12523
  updatedAt: /* @__PURE__ */ new Date()
@@ -12563,6 +12753,7 @@ var MemoryBilling = class {
12563
12753
  };
12564
12754
 
12565
12755
  // src/interfaces/IDevPortal.ts
12756
+ import { randomBytes as randomBytes17 } from "crypto";
12566
12757
  var MemoryDevPortal = class {
12567
12758
  constructor(config = {}) {
12568
12759
  this.config = config;
@@ -12575,8 +12766,9 @@ var MemoryDevPortal = class {
12575
12766
  usageRecords = [];
12576
12767
  // API Key Management
12577
12768
  async createApiKey(options, userId) {
12578
- const id = `key_${Date.now()}_${Math.random().toString(36).substring(7)}`;
12579
- const secret = `sk_${options.type}_${Math.random().toString(36).substring(2)}${Math.random().toString(36).substring(2)}`;
12769
+ const { randomBytes: randomBytes37, createHash: createHash2 } = await import("crypto");
12770
+ const id = `key_${Date.now()}_${randomBytes37(8).toString("hex")}`;
12771
+ const secret = `sk_${options.type}_${randomBytes37(24).toString("base64url")}`;
12580
12772
  const prefix = secret.substring(0, 12);
12581
12773
  const key = {
12582
12774
  id,
@@ -12663,7 +12855,7 @@ var MemoryDevPortal = class {
12663
12855
  // API Documentation
12664
12856
  async generateDocumentation(endpoints, config) {
12665
12857
  const doc = {
12666
- id: `doc_${Date.now()}_${Math.random().toString(36).substring(7)}`,
12858
+ id: `doc_${Date.now()}_${randomBytes17(4).toString("hex")}`,
12667
12859
  title: config.title,
12668
12860
  version: config.version,
12669
12861
  baseUrl: config.baseUrl,
@@ -12719,7 +12911,7 @@ var MemoryDevPortal = class {
12719
12911
  if (!doc) throw new Error(`Documentation not found: ${docId}`);
12720
12912
  const newEndpoint = {
12721
12913
  ...endpoint,
12722
- id: `ep_${Date.now()}_${Math.random().toString(36).substring(7)}`
12914
+ id: `ep_${Date.now()}_${randomBytes17(4).toString("hex")}`
12723
12915
  };
12724
12916
  doc.endpoints.push(newEndpoint);
12725
12917
  return newEndpoint;
@@ -12815,7 +13007,7 @@ SDK for ${documentation.title}`,
12815
13007
  });
12816
13008
  }
12817
13009
  const sdk = {
12818
- id: `sdk_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13010
+ id: `sdk_${Date.now()}_${randomBytes17(4).toString("hex")}`,
12819
13011
  language: config.language,
12820
13012
  packageName: config.packageName,
12821
13013
  version: config.version,
@@ -12842,7 +13034,7 @@ SDK for ${documentation.title}`,
12842
13034
  }
12843
13035
  // Sandbox / Playground
12844
13036
  async createSandbox(options, userId) {
12845
- const id = `sandbox_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13037
+ const id = `sandbox_${Date.now()}_${randomBytes17(4).toString("hex")}`;
12846
13038
  const lifetimeHours = options.lifetimeHours || this.config.sandboxDefaultLifetimeHours || 24;
12847
13039
  const sandbox = {
12848
13040
  id,
@@ -12851,7 +13043,7 @@ SDK for ${documentation.title}`,
12851
13043
  tenantId: options.tenantId,
12852
13044
  status: "active",
12853
13045
  baseUrl: `https://sandbox-${id}.example.com`,
12854
- apiKey: `sandbox_${Math.random().toString(36).substring(2)}`,
13046
+ apiKey: `sandbox_${randomBytes17(8).toString("hex")}`,
12855
13047
  seedDataLoaded: options.seedData || [],
12856
13048
  config: options.config || {},
12857
13049
  limits: {
@@ -12988,7 +13180,7 @@ SDK for ${documentation.title}`,
12988
13180
  }
12989
13181
  // Webhook Testing
12990
13182
  async createWebhookTestEndpoint(userId, maxEvents = 100) {
12991
- const id = `wh_test_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13183
+ const id = `wh_test_${Date.now()}_${randomBytes17(4).toString("hex")}`;
12992
13184
  const endpoint = {
12993
13185
  id,
12994
13186
  url: `https://webhook-test.example.com/${id}`,
@@ -13025,18 +13217,13 @@ SDK for ${documentation.title}`,
13025
13217
  statusCode: 200,
13026
13218
  headers: { "content-type": "application/json" },
13027
13219
  body: { received: true },
13028
- latencyMs: Math.random() * 100
13220
+ latencyMs: 0
13029
13221
  };
13030
13222
  }
13031
13223
  // Private helpers
13032
13224
  hashKey(key) {
13033
- let hash = 0;
13034
- for (let i = 0; i < key.length; i++) {
13035
- const char = key.charCodeAt(i);
13036
- hash = (hash << 5) - hash + char;
13037
- hash = hash & hash;
13038
- }
13039
- return `hashed_${Math.abs(hash).toString(36)}`;
13225
+ const { createHash: createHash2 } = __require("crypto");
13226
+ return createHash2("sha256").update(key).digest("hex");
13040
13227
  }
13041
13228
  endpointsToOpenApiPaths(endpoints) {
13042
13229
  const paths = {};
@@ -13128,6 +13315,7 @@ class ApiClient:
13128
13315
  };
13129
13316
 
13130
13317
  // src/interfaces/ICompliance.ts
13318
+ import { randomBytes as randomBytes18 } from "crypto";
13131
13319
  var MemoryCompliance = class {
13132
13320
  constructor(config = {}) {
13133
13321
  this.config = config;
@@ -13144,13 +13332,13 @@ var MemoryCompliance = class {
13144
13332
  breaches = /* @__PURE__ */ new Map();
13145
13333
  // DSAR Management
13146
13334
  async createDsar(options) {
13147
- const id = `dsar_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13335
+ const id = `dsar_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13148
13336
  const dsar = {
13149
13337
  id,
13150
13338
  type: options.type,
13151
13339
  subjectId: options.subjectId || options.subjectEmail,
13152
13340
  subjectEmail: options.subjectEmail,
13153
- verificationToken: `verify_${Math.random().toString(36).substring(2)}`,
13341
+ verificationToken: `verify_${randomBytes18(8).toString("hex")}`,
13154
13342
  verified: false,
13155
13343
  status: "pending_verification",
13156
13344
  tenantId: options.tenantId,
@@ -13201,7 +13389,7 @@ var MemoryCompliance = class {
13201
13389
  dsar.updatedAt = /* @__PURE__ */ new Date();
13202
13390
  if (notes) {
13203
13391
  dsar.notes.push({
13204
- id: `note_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13392
+ id: `note_${Date.now()}_${randomBytes18(4).toString("hex")}`,
13205
13393
  content: notes,
13206
13394
  authorId: "system",
13207
13395
  createdAt: /* @__PURE__ */ new Date()
@@ -13213,7 +13401,7 @@ var MemoryCompliance = class {
13213
13401
  const dsar = await this.getDsar(dsarId);
13214
13402
  if (!dsar) throw new Error(`DSAR not found: ${dsarId}`);
13215
13403
  const note = {
13216
- id: `note_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13404
+ id: `note_${Date.now()}_${randomBytes18(4).toString("hex")}`,
13217
13405
  content,
13218
13406
  authorId,
13219
13407
  createdAt: /* @__PURE__ */ new Date()
@@ -13227,7 +13415,7 @@ var MemoryCompliance = class {
13227
13415
  if (!dsar) throw new Error(`DSAR not found: ${dsarId}`);
13228
13416
  const att = {
13229
13417
  ...attachment,
13230
- id: `att_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13418
+ id: `att_${Date.now()}_${randomBytes18(4).toString("hex")}`,
13231
13419
  createdAt: /* @__PURE__ */ new Date()
13232
13420
  };
13233
13421
  dsar.attachments.push(att);
@@ -13268,7 +13456,7 @@ var MemoryCompliance = class {
13268
13456
  }
13269
13457
  // Consent Management
13270
13458
  async recordConsent(options) {
13271
- const id = `consent_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13459
+ const id = `consent_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13272
13460
  const consent = {
13273
13461
  id,
13274
13462
  subjectId: options.subjectId,
@@ -13343,7 +13531,7 @@ var MemoryCompliance = class {
13343
13531
  }
13344
13532
  // Retention Policies
13345
13533
  async createRetentionPolicy(policy) {
13346
- const id = `rp_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13534
+ const id = `rp_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13347
13535
  const newPolicy = {
13348
13536
  ...policy,
13349
13537
  id,
@@ -13376,7 +13564,7 @@ var MemoryCompliance = class {
13376
13564
  if (!policy) throw new Error(`Policy not found: ${policyId}`);
13377
13565
  const startedAt = /* @__PURE__ */ new Date();
13378
13566
  const execution = {
13379
- id: `re_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13567
+ id: `re_${Date.now()}_${randomBytes18(4).toString("hex")}`,
13380
13568
  policyId,
13381
13569
  recordsProcessed: 100,
13382
13570
  recordsAffected: 15,
@@ -13395,7 +13583,7 @@ var MemoryCompliance = class {
13395
13583
  }
13396
13584
  // Data Inventory
13397
13585
  async addDataInventoryItem(item) {
13398
- const id = `di_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13586
+ const id = `di_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13399
13587
  const newItem = {
13400
13588
  ...item,
13401
13589
  id,
@@ -13456,7 +13644,7 @@ var MemoryCompliance = class {
13456
13644
  }
13457
13645
  // Audit Evidence
13458
13646
  async addEvidence(evidence) {
13459
- const id = `ev_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13647
+ const id = `ev_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13460
13648
  const newEvidence = {
13461
13649
  ...evidence,
13462
13650
  id,
@@ -13532,7 +13720,7 @@ var MemoryCompliance = class {
13532
13720
  }
13533
13721
  // PIAs
13534
13722
  async createPia(pia) {
13535
- const id = `pia_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13723
+ const id = `pia_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13536
13724
  const newPia = {
13537
13725
  ...pia,
13538
13726
  id,
@@ -13564,7 +13752,7 @@ var MemoryCompliance = class {
13564
13752
  if (!pia) throw new Error(`PIA not found: ${piaId}`);
13565
13753
  const newRisk = {
13566
13754
  ...risk,
13567
- id: `risk_${Date.now()}_${Math.random().toString(36).substring(7)}`
13755
+ id: `risk_${Date.now()}_${randomBytes18(4).toString("hex")}`
13568
13756
  };
13569
13757
  pia.risks.push(newRisk);
13570
13758
  pia.updatedAt = /* @__PURE__ */ new Date();
@@ -13575,7 +13763,7 @@ var MemoryCompliance = class {
13575
13763
  if (!pia) throw new Error(`PIA not found: ${piaId}`);
13576
13764
  const newMitigation = {
13577
13765
  ...mitigation,
13578
- id: `mit_${Date.now()}_${Math.random().toString(36).substring(7)}`
13766
+ id: `mit_${Date.now()}_${randomBytes18(4).toString("hex")}`
13579
13767
  };
13580
13768
  pia.mitigations.push(newMitigation);
13581
13769
  pia.updatedAt = /* @__PURE__ */ new Date();
@@ -13612,7 +13800,7 @@ var MemoryCompliance = class {
13612
13800
  (c) => c.status === "non_compliant"
13613
13801
  ).length;
13614
13802
  const report = {
13615
- id: `report_${Date.now()}_${Math.random().toString(36).substring(7)}`,
13803
+ id: `report_${Date.now()}_${randomBytes18(4).toString("hex")}`,
13616
13804
  title: `${framework.toUpperCase()} Compliance Report`,
13617
13805
  framework,
13618
13806
  period,
@@ -13663,7 +13851,7 @@ var MemoryCompliance = class {
13663
13851
  }
13664
13852
  // Breach Management
13665
13853
  async recordBreach(breach) {
13666
- const id = `breach_${Date.now()}_${Math.random().toString(36).substring(7)}`;
13854
+ const id = `breach_${Date.now()}_${randomBytes18(4).toString("hex")}`;
13667
13855
  const newBreach = {
13668
13856
  ...breach,
13669
13857
  id,
@@ -13902,6 +14090,27 @@ var RAGConfigSchema = z.object({
13902
14090
  message: "Pinecone requires apiKey and indexName; Weaviate requires host"
13903
14091
  }
13904
14092
  );
14093
+ var CryptoConfigSchema = z.object({
14094
+ enabled: z.boolean().default(false).describe("Enable field-level encryption"),
14095
+ masterKey: z.string().optional().describe("256-bit master key as hex (64 chars). Required when enabled."),
14096
+ hmacKey: z.string().optional().describe(
14097
+ "HMAC key for deterministic hashing (derived from master key if not provided)"
14098
+ )
14099
+ }).refine(
14100
+ (data) => {
14101
+ if (data.enabled) {
14102
+ return data.masterKey && data.masterKey.length >= 64;
14103
+ }
14104
+ return true;
14105
+ },
14106
+ {
14107
+ message: "Crypto requires a 256-bit master key (64 hex characters) when enabled"
14108
+ }
14109
+ );
14110
+ var SecurityConfigSchema = z.object({
14111
+ enforceTls: z.boolean().default(true).describe("Enforce TLS for production connections"),
14112
+ tlsWarnOnly: z.boolean().default(false).describe("Warn instead of throwing when TLS is missing in production")
14113
+ });
13905
14114
  var RetryConfigSchema = z.object({
13906
14115
  enabled: z.boolean().default(true).describe("Enable retry for failed operations"),
13907
14116
  maxAttempts: z.number().int().min(1).max(10).default(3).describe("Maximum retry attempts"),
@@ -13991,6 +14200,10 @@ var PlatformConfigSchema = z.object({
13991
14200
  // AI configurations
13992
14201
  ai: AIConfigSchema.default({ enabled: false }),
13993
14202
  rag: RAGConfigSchema.default({ enabled: false }),
14203
+ // Crypto configuration
14204
+ crypto: CryptoConfigSchema.default({ enabled: false }),
14205
+ // Security configuration
14206
+ security: SecurityConfigSchema.default({}),
13994
14207
  // Resilience configuration
13995
14208
  resilience: ResilienceConfigSchema.default({}),
13996
14209
  // Observability configuration
@@ -14068,6 +14281,15 @@ function loadConfig() {
14068
14281
  embeddingApiKey: process.env.EMBEDDING_API_KEY || process.env.OPENAI_API_KEY,
14069
14282
  embeddingModel: process.env.EMBEDDING_MODEL
14070
14283
  },
14284
+ crypto: {
14285
+ enabled: process.env.CRYPTO_ENABLED === "true",
14286
+ masterKey: process.env.CRYPTO_MASTER_KEY,
14287
+ hmacKey: process.env.CRYPTO_HMAC_KEY
14288
+ },
14289
+ security: {
14290
+ enforceTls: process.env.SECURITY_ENFORCE_TLS !== "false",
14291
+ tlsWarnOnly: process.env.SECURITY_TLS_WARN_ONLY === "true"
14292
+ },
14071
14293
  resilience: {
14072
14294
  retry: {
14073
14295
  enabled: process.env.RESILIENCE_RETRY_ENABLED !== "false",
@@ -14474,13 +14696,14 @@ var MemoryEmail = class {
14474
14696
 
14475
14697
  // src/context/CorrelationContext.ts
14476
14698
  import { AsyncLocalStorage } from "async_hooks";
14699
+ import { randomBytes as randomBytes19 } from "crypto";
14477
14700
  var CorrelationContextManager = class {
14478
14701
  storage = new AsyncLocalStorage();
14479
14702
  idGenerator;
14480
14703
  constructor() {
14481
14704
  this.idGenerator = () => {
14482
14705
  const timestamp = Date.now().toString(36);
14483
- const random = Math.random().toString(36).substring(2, 10);
14706
+ const random = randomBytes19(4).toString("hex");
14484
14707
  return `${timestamp}-${random}`;
14485
14708
  };
14486
14709
  }
@@ -15110,10 +15333,11 @@ var MemoryQueue = class {
15110
15333
  };
15111
15334
 
15112
15335
  // src/adapters/console/ConsoleEmail.ts
15336
+ import { randomBytes as randomBytes20 } from "crypto";
15113
15337
  var ConsoleEmail = class {
15114
15338
  sentEmails = [];
15115
15339
  async send(message) {
15116
- const id = `console_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
15340
+ const id = `console_${Date.now()}_${randomBytes20(4).toString("hex")}`;
15117
15341
  console.log("\n" + "=".repeat(60));
15118
15342
  console.log("\u{1F4E7} EMAIL SENT (Console Adapter)");
15119
15343
  console.log("=".repeat(60));
@@ -15190,6 +15414,152 @@ var ConsoleEmail = class {
15190
15414
  // src/factory.ts
15191
15415
  init_IAI();
15192
15416
  init_IRAG();
15417
+
15418
+ // src/adapters/memory/MemoryCrypto.ts
15419
+ import {
15420
+ randomBytes as randomBytes21,
15421
+ createCipheriv,
15422
+ createDecipheriv,
15423
+ createHmac
15424
+ } from "crypto";
15425
+ var MemoryCrypto = class {
15426
+ keys = /* @__PURE__ */ new Map();
15427
+ activeKeyId;
15428
+ hmacKey;
15429
+ constructor(options) {
15430
+ const masterKeyBuf = options?.masterKey ? Buffer.from(options.masterKey, "hex") : randomBytes21(32);
15431
+ this.hmacKey = options?.hmacKey ? Buffer.from(options.hmacKey, "hex") : randomBytes21(32);
15432
+ const keyId = this.generateKeyId();
15433
+ this.keys.set(keyId, {
15434
+ id: keyId,
15435
+ key: masterKeyBuf,
15436
+ status: "active",
15437
+ createdAt: /* @__PURE__ */ new Date()
15438
+ });
15439
+ this.activeKeyId = keyId;
15440
+ }
15441
+ async encrypt(plaintext, options) {
15442
+ const keyId = options?.keyId || this.activeKeyId;
15443
+ const stored = this.keys.get(keyId);
15444
+ if (!stored) {
15445
+ throw new Error(`Key not found: ${keyId}`);
15446
+ }
15447
+ if (stored.status === "retired") {
15448
+ throw new Error(`Key is retired: ${keyId}`);
15449
+ }
15450
+ if (stored.status === "decrypt-only" && !options?.keyId) {
15451
+ throw new Error(`Key is decrypt-only: ${keyId}`);
15452
+ }
15453
+ const iv = randomBytes21(12);
15454
+ const cipher = createCipheriv("aes-256-gcm", stored.key, iv);
15455
+ if (options?.aad) {
15456
+ cipher.setAAD(Buffer.from(options.aad, "utf8"));
15457
+ }
15458
+ const encrypted = Buffer.concat([
15459
+ cipher.update(plaintext, "utf8"),
15460
+ cipher.final()
15461
+ ]);
15462
+ const tag = cipher.getAuthTag();
15463
+ return {
15464
+ ciphertext: encrypted.toString("base64"),
15465
+ iv: iv.toString("base64"),
15466
+ tag: tag.toString("base64"),
15467
+ keyId,
15468
+ algorithm: "aes-256-gcm",
15469
+ version: 1
15470
+ };
15471
+ }
15472
+ async decrypt(field, options) {
15473
+ const stored = this.keys.get(field.keyId);
15474
+ if (!stored) {
15475
+ throw new Error(`Key not found: ${field.keyId}`);
15476
+ }
15477
+ if (stored.status === "retired") {
15478
+ throw new Error(`Key is retired and cannot decrypt: ${field.keyId}`);
15479
+ }
15480
+ const decipher = createDecipheriv(
15481
+ "aes-256-gcm",
15482
+ stored.key,
15483
+ Buffer.from(field.iv, "base64")
15484
+ );
15485
+ decipher.setAuthTag(Buffer.from(field.tag, "base64"));
15486
+ if (options?.aad) {
15487
+ decipher.setAAD(Buffer.from(options.aad, "utf8"));
15488
+ }
15489
+ const decrypted = Buffer.concat([
15490
+ decipher.update(Buffer.from(field.ciphertext, "base64")),
15491
+ decipher.final()
15492
+ ]);
15493
+ return decrypted.toString("utf8");
15494
+ }
15495
+ async encryptDeterministic(plaintext, options) {
15496
+ const hash = await this.computeHash(plaintext);
15497
+ const encrypted = await this.encrypt(plaintext, options);
15498
+ return { hash, encrypted };
15499
+ }
15500
+ async computeHash(plaintext) {
15501
+ return createHmac("sha256", this.hmacKey).update(plaintext, "utf8").digest("hex");
15502
+ }
15503
+ async encryptBatch(fields, options) {
15504
+ const result = {};
15505
+ for (const [key, value] of Object.entries(fields)) {
15506
+ result[key] = await this.encrypt(value, options);
15507
+ }
15508
+ return result;
15509
+ }
15510
+ async decryptBatch(fields, options) {
15511
+ const result = {};
15512
+ for (const [key, value] of Object.entries(fields)) {
15513
+ result[key] = await this.decrypt(value, options);
15514
+ }
15515
+ return result;
15516
+ }
15517
+ async rotateKey() {
15518
+ const previousKeyId = this.activeKeyId;
15519
+ const currentKey = this.keys.get(previousKeyId);
15520
+ if (currentKey) {
15521
+ currentKey.status = "decrypt-only";
15522
+ }
15523
+ const newKeyId = this.generateKeyId();
15524
+ this.keys.set(newKeyId, {
15525
+ id: newKeyId,
15526
+ key: randomBytes21(32),
15527
+ status: "active",
15528
+ createdAt: /* @__PURE__ */ new Date()
15529
+ });
15530
+ this.activeKeyId = newKeyId;
15531
+ return { newKeyId, previousKeyId };
15532
+ }
15533
+ async reEncrypt(field, options) {
15534
+ const plaintext = await this.decrypt(field);
15535
+ return this.encrypt(plaintext, options);
15536
+ }
15537
+ async listKeys() {
15538
+ return Array.from(this.keys.values()).map((k) => ({
15539
+ keyId: k.id,
15540
+ createdAt: k.createdAt,
15541
+ status: k.status
15542
+ }));
15543
+ }
15544
+ async getActiveKeyId() {
15545
+ return this.activeKeyId;
15546
+ }
15547
+ async healthCheck() {
15548
+ try {
15549
+ const testPlain = "health-check-test";
15550
+ const encrypted = await this.encrypt(testPlain);
15551
+ const decrypted = await this.decrypt(encrypted);
15552
+ return decrypted === testPlain;
15553
+ } catch {
15554
+ return false;
15555
+ }
15556
+ }
15557
+ generateKeyId() {
15558
+ return `key_${randomBytes21(8).toString("hex")}`;
15559
+ }
15560
+ };
15561
+
15562
+ // src/factory.ts
15193
15563
  async function createDatabaseAdapter(config) {
15194
15564
  switch (config.database.provider) {
15195
15565
  case "postgres": {
@@ -15245,9 +15615,9 @@ async function createCacheAdapter(config) {
15245
15615
  "Upstash requires UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN environment variables"
15246
15616
  );
15247
15617
  }
15248
- const { Redis } = await import("@upstash/redis");
15618
+ const { Redis: Redis2 } = await import("@upstash/redis");
15249
15619
  const { UpstashCache: UpstashCache2 } = await Promise.resolve().then(() => (init_UpstashCache(), UpstashCache_exports));
15250
- const client = new Redis({
15620
+ const client = new Redis2({
15251
15621
  url: config.cache.upstashUrl,
15252
15622
  token: config.cache.upstashToken
15253
15623
  });
@@ -15490,16 +15860,73 @@ async function createRAGAdapter(config, ai) {
15490
15860
  return new MemoryRAG();
15491
15861
  }
15492
15862
  }
15863
+ async function createCryptoAdapter(config) {
15864
+ if (!config.crypto.enabled) {
15865
+ return null;
15866
+ }
15867
+ if (config.crypto.masterKey && config.crypto.masterKey.length >= 64) {
15868
+ const { NodeCrypto: NodeCrypto2 } = await Promise.resolve().then(() => (init_NodeCrypto(), NodeCrypto_exports));
15869
+ return new NodeCrypto2({
15870
+ masterKey: config.crypto.masterKey,
15871
+ hmacKey: config.crypto.hmacKey
15872
+ });
15873
+ }
15874
+ return new MemoryCrypto();
15875
+ }
15876
+ function validateTlsSecurity(config) {
15877
+ const isProduction = process.env.NODE_ENV === "production";
15878
+ if (!isProduction || !config.security.enforceTls) {
15879
+ return;
15880
+ }
15881
+ const warnings = [];
15882
+ if (config.database.provider === "postgres") {
15883
+ const connStr = config.database.connectionString || config.database.url || "";
15884
+ const hasSSL = config.database.ssl || connStr.includes("sslmode=require") || connStr.includes("sslmode=verify");
15885
+ if (!hasSSL) {
15886
+ warnings.push(
15887
+ "PostgreSQL: TLS/SSL not configured. Set database.ssl=true or add sslmode=require to connection string."
15888
+ );
15889
+ }
15890
+ }
15891
+ if (config.cache.provider === "redis") {
15892
+ const url = config.cache.url || "";
15893
+ if (url && !url.startsWith("rediss://")) {
15894
+ warnings.push(
15895
+ "Redis: Connection URL uses redis:// instead of rediss:// (TLS). Consider enabling TLS."
15896
+ );
15897
+ }
15898
+ }
15899
+ if (config.email.provider === "smtp") {
15900
+ if (!config.email.secure) {
15901
+ warnings.push(
15902
+ "SMTP: secure=false in production. Set email.secure=true for TLS."
15903
+ );
15904
+ }
15905
+ }
15906
+ if (warnings.length > 0) {
15907
+ const message = `[Security] TLS warnings in production:
15908
+ - ${warnings.join("\n - ")}`;
15909
+ if (config.security.tlsWarnOnly) {
15910
+ console.warn(message);
15911
+ } else {
15912
+ throw new Error(message);
15913
+ }
15914
+ }
15915
+ }
15493
15916
  async function createPlatformAsync(config) {
15494
15917
  const finalConfig = config ? deepMerge(loadConfig(), config) : loadConfig();
15495
- const [db, cache, storage, email, queue, tracing] = await Promise.all([
15496
- createDatabaseAdapter(finalConfig),
15497
- createCacheAdapter(finalConfig),
15498
- createStorageAdapter(finalConfig),
15499
- createEmailAdapter(finalConfig),
15500
- createQueueAdapter(finalConfig),
15501
- createTracingAdapter(finalConfig)
15502
- ]);
15918
+ validateTlsSecurity(finalConfig);
15919
+ const [db, cache, storage, email, queue, tracing, crypto2] = await Promise.all(
15920
+ [
15921
+ createDatabaseAdapter(finalConfig),
15922
+ createCacheAdapter(finalConfig),
15923
+ createStorageAdapter(finalConfig),
15924
+ createEmailAdapter(finalConfig),
15925
+ createQueueAdapter(finalConfig),
15926
+ createTracingAdapter(finalConfig),
15927
+ createCryptoAdapter(finalConfig)
15928
+ ]
15929
+ );
15503
15930
  const logger = createLogger(finalConfig);
15504
15931
  const metrics = createMetrics(finalConfig);
15505
15932
  const ai = await createAIAdapter(finalConfig);
@@ -15514,7 +15941,8 @@ async function createPlatformAsync(config) {
15514
15941
  metrics,
15515
15942
  tracing,
15516
15943
  ai,
15517
- rag
15944
+ rag,
15945
+ crypto2
15518
15946
  );
15519
15947
  }
15520
15948
  function createPlatform(config) {
@@ -15535,6 +15963,7 @@ function createPlatform(config) {
15535
15963
  const tracing = finalConfig.observability.tracing.provider === "memory" ? new MemoryTracing() : new NoopTracing();
15536
15964
  const ai = finalConfig.ai.enabled ? new MemoryAI() : null;
15537
15965
  const rag = finalConfig.rag.enabled ? new MemoryRAG() : null;
15966
+ const crypto2 = finalConfig.crypto.enabled ? new MemoryCrypto() : null;
15538
15967
  return createPlatformFromAdapters(
15539
15968
  db,
15540
15969
  cache,
@@ -15545,10 +15974,11 @@ function createPlatform(config) {
15545
15974
  metrics,
15546
15975
  tracing,
15547
15976
  ai,
15548
- rag
15977
+ rag,
15978
+ crypto2
15549
15979
  );
15550
15980
  }
15551
- function createPlatformFromAdapters(db, cache, storage, email, queue, logger, metrics, tracing, ai, rag) {
15981
+ function createPlatformFromAdapters(db, cache, storage, email, queue, logger, metrics, tracing, ai, rag, crypto2) {
15552
15982
  const platform = {
15553
15983
  db,
15554
15984
  cache,
@@ -15602,6 +16032,9 @@ function createPlatformFromAdapters(db, cache, storage, email, queue, logger, me
15602
16032
  if (rag) {
15603
16033
  platform.rag = rag;
15604
16034
  }
16035
+ if (crypto2) {
16036
+ platform.crypto = crypto2;
16037
+ }
15605
16038
  return platform;
15606
16039
  }
15607
16040
  function deepMerge(target, source) {
@@ -17073,6 +17506,7 @@ var FallbackStrategies = {
17073
17506
  };
17074
17507
 
17075
17508
  // src/security.ts
17509
+ import { timingSafeEqual } from "crypto";
17076
17510
  var URL_PROTOCOL_PATTERN = /(https?:\/\/|ftp:\/\/|www\.)\S+/i;
17077
17511
  var URL_DOMAIN_PATTERN = /\b[\w.-]+\.(com|net|org|io|co|dev|app|xyz|info|biz|me|us|uk|edu|gov)\b/i;
17078
17512
  var HTML_TAG_PATTERN = /<[^>]*>/;
@@ -17097,6 +17531,144 @@ function defangUrl(str) {
17097
17531
  function sanitizeForEmail(str) {
17098
17532
  return escapeHtml(str);
17099
17533
  }
17534
+ function constantTimeEqual(a, b) {
17535
+ try {
17536
+ const aBuf = Buffer.from(a, "utf-8");
17537
+ const bBuf = Buffer.from(b, "utf-8");
17538
+ if (aBuf.length !== bBuf.length) return false;
17539
+ return timingSafeEqual(aBuf, bBuf);
17540
+ } catch {
17541
+ return false;
17542
+ }
17543
+ }
17544
+ function sanitizeApiError(error, statusCode, isDevelopment = false) {
17545
+ if (statusCode >= 400 && statusCode < 500) {
17546
+ const message = error instanceof Error ? error.message : String(error || "Bad request");
17547
+ return { message };
17548
+ }
17549
+ const result = {
17550
+ message: "An internal error occurred. Please try again later.",
17551
+ code: "INTERNAL_ERROR"
17552
+ };
17553
+ if (isDevelopment && error instanceof Error) {
17554
+ result.stack = error.stack;
17555
+ }
17556
+ return result;
17557
+ }
17558
+ function getCorrelationId2(headers) {
17559
+ const get = typeof headers === "function" ? headers : (name) => {
17560
+ const val = headers[name] ?? headers[name.toLowerCase()];
17561
+ return Array.isArray(val) ? val[0] : val;
17562
+ };
17563
+ return get("x-request-id") || get("X-Request-ID") || get("x-correlation-id") || get("X-Correlation-ID") || crypto.randomUUID();
17564
+ }
17565
+
17566
+ // src/security-headers.ts
17567
+ var SecurityHeaderPresets = {
17568
+ /** Minimal: basic headers only, no CSP */
17569
+ minimal: {
17570
+ csp: false,
17571
+ hsts: false
17572
+ },
17573
+ /** Standard: full CSP + HSTS for most apps */
17574
+ standard: {
17575
+ csp: true,
17576
+ hsts: true,
17577
+ frameOptions: "DENY"
17578
+ },
17579
+ /** Strict: deny all permissions, strict CSP, no frame embedding */
17580
+ strict: {
17581
+ csp: true,
17582
+ hsts: true,
17583
+ hstsMaxAge: 63072e3,
17584
+ // 2 years
17585
+ frameOptions: "DENY"
17586
+ }
17587
+ };
17588
+ function generateSecurityHeaders(config = {}) {
17589
+ const isProduction = config.isProduction ?? process.env.NODE_ENV === "production";
17590
+ const frameOptions = config.frameOptions ?? "DENY";
17591
+ const enableCsp = config.csp ?? true;
17592
+ const enableHsts = config.hsts ?? true;
17593
+ const hstsMaxAge = config.hstsMaxAge ?? 31536e3;
17594
+ const baseHeaders = [
17595
+ { key: "X-Frame-Options", value: frameOptions },
17596
+ { key: "X-Content-Type-Options", value: "nosniff" },
17597
+ // Modern browsers use CSP, not XSS-Protection. Value '0' disables the
17598
+ // legacy filter which can itself introduce vulnerabilities.
17599
+ { key: "X-XSS-Protection", value: "0" },
17600
+ {
17601
+ key: "Referrer-Policy",
17602
+ value: "strict-origin-when-cross-origin"
17603
+ },
17604
+ {
17605
+ key: "Permissions-Policy",
17606
+ value: "camera=(), microphone=(), geolocation=()"
17607
+ }
17608
+ ];
17609
+ const entries = [
17610
+ { source: "/:path*", headers: baseHeaders }
17611
+ ];
17612
+ if (isProduction) {
17613
+ const prodHeaders = [];
17614
+ if (enableHsts) {
17615
+ prodHeaders.push({
17616
+ key: "Strict-Transport-Security",
17617
+ value: `max-age=${hstsMaxAge}; includeSubDomains`
17618
+ });
17619
+ }
17620
+ if (enableCsp) {
17621
+ const csp = buildCsp(config);
17622
+ prodHeaders.push({ key: "Content-Security-Policy", value: csp });
17623
+ }
17624
+ if (prodHeaders.length > 0) {
17625
+ entries.push({ source: "/:path*", headers: prodHeaders });
17626
+ }
17627
+ }
17628
+ return entries;
17629
+ }
17630
+ function buildCsp(config) {
17631
+ const scriptSrc = [
17632
+ "'self'",
17633
+ "'unsafe-inline'",
17634
+ "'unsafe-eval'",
17635
+ ...config.cspScriptSrc ?? []
17636
+ ];
17637
+ const styleSrc = [
17638
+ "'self'",
17639
+ "'unsafe-inline'",
17640
+ "https://fonts.googleapis.com",
17641
+ ...config.cspStyleSrc ?? []
17642
+ ];
17643
+ const imgSrc = [
17644
+ "'self'",
17645
+ "data:",
17646
+ "https:",
17647
+ "blob:",
17648
+ ...config.cspImgSrc ?? []
17649
+ ];
17650
+ const fontSrc = ["'self'", "data:", "https://fonts.gstatic.com"];
17651
+ const connectSrc = ["'self'", ...config.cspConnectSrc ?? []];
17652
+ const frameSrc = [...config.cspFrameSrc ?? []];
17653
+ const directives = [
17654
+ `default-src 'self'`,
17655
+ `script-src ${scriptSrc.join(" ")}`,
17656
+ `style-src ${styleSrc.join(" ")}`,
17657
+ `img-src ${imgSrc.join(" ")}`,
17658
+ `font-src ${fontSrc.join(" ")}`,
17659
+ `connect-src ${connectSrc.join(" ")}`
17660
+ ];
17661
+ if (frameSrc.length > 0) {
17662
+ directives.push(`frame-src ${frameSrc.join(" ")}`);
17663
+ }
17664
+ directives.push(
17665
+ `object-src 'none'`,
17666
+ `base-uri 'self'`,
17667
+ `form-action 'self'`,
17668
+ `frame-ancestors 'none'`
17669
+ );
17670
+ return directives.join("; ");
17671
+ }
17100
17672
 
17101
17673
  // src/api.ts
17102
17674
  var ApiErrorCode = {
@@ -17223,6 +17795,850 @@ function buildPagination(page, limit, total) {
17223
17795
  };
17224
17796
  }
17225
17797
 
17798
+ // src/auth/keycloak.ts
17799
+ var KEYCLOAK_DEFAULT_ROLES = [
17800
+ "offline_access",
17801
+ "uma_authorization"
17802
+ ];
17803
+ function parseKeycloakRoles(accessToken, additionalDefaultRoles = []) {
17804
+ if (!accessToken) return [];
17805
+ try {
17806
+ const parts = accessToken.split(".");
17807
+ if (parts.length !== 3) return [];
17808
+ const payload = parts[1];
17809
+ const decoded = JSON.parse(atob(payload));
17810
+ const realmRoles = decoded.realm_roles ?? decoded.realm_access?.roles;
17811
+ if (!Array.isArray(realmRoles)) return [];
17812
+ const filterSet = /* @__PURE__ */ new Set([
17813
+ ...KEYCLOAK_DEFAULT_ROLES,
17814
+ ...additionalDefaultRoles
17815
+ ]);
17816
+ return realmRoles.filter(
17817
+ (role) => typeof role === "string" && !filterSet.has(role)
17818
+ );
17819
+ } catch {
17820
+ return [];
17821
+ }
17822
+ }
17823
+ function hasRole(roles, role) {
17824
+ return roles?.includes(role) ?? false;
17825
+ }
17826
+ function hasAnyRole(roles, requiredRoles) {
17827
+ if (!roles || roles.length === 0) return false;
17828
+ return requiredRoles.some((role) => roles.includes(role));
17829
+ }
17830
+ function hasAllRoles(roles, requiredRoles) {
17831
+ if (!roles || roles.length === 0) return false;
17832
+ return requiredRoles.every((role) => roles.includes(role));
17833
+ }
17834
+ function isTokenExpired(expiresAt, bufferMs = 6e4) {
17835
+ if (!expiresAt) return true;
17836
+ return Date.now() >= expiresAt - bufferMs;
17837
+ }
17838
+ function buildTokenRefreshParams(config, refreshToken) {
17839
+ return new URLSearchParams({
17840
+ grant_type: "refresh_token",
17841
+ client_id: config.clientId,
17842
+ client_secret: config.clientSecret,
17843
+ refresh_token: refreshToken
17844
+ });
17845
+ }
17846
+ function getTokenEndpoint(issuer) {
17847
+ const base = issuer.endsWith("/") ? issuer.slice(0, -1) : issuer;
17848
+ return `${base}/protocol/openid-connect/token`;
17849
+ }
17850
+ function getEndSessionEndpoint(issuer) {
17851
+ const base = issuer.endsWith("/") ? issuer.slice(0, -1) : issuer;
17852
+ return `${base}/protocol/openid-connect/logout`;
17853
+ }
17854
+ async function refreshKeycloakToken(config, refreshToken, additionalDefaultRoles) {
17855
+ try {
17856
+ const endpoint = getTokenEndpoint(config.issuer);
17857
+ const params = buildTokenRefreshParams(config, refreshToken);
17858
+ const response = await fetch(endpoint, {
17859
+ method: "POST",
17860
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
17861
+ body: params
17862
+ });
17863
+ if (!response.ok) {
17864
+ const body = await response.text().catch(() => "");
17865
+ return {
17866
+ ok: false,
17867
+ error: `Token refresh failed: HTTP ${response.status} - ${body}`
17868
+ };
17869
+ }
17870
+ const data = await response.json();
17871
+ return {
17872
+ ok: true,
17873
+ tokens: {
17874
+ accessToken: data.access_token,
17875
+ refreshToken: data.refresh_token ?? refreshToken,
17876
+ idToken: data.id_token,
17877
+ expiresAt: Date.now() + data.expires_in * 1e3,
17878
+ roles: parseKeycloakRoles(data.access_token, additionalDefaultRoles)
17879
+ }
17880
+ };
17881
+ } catch (error) {
17882
+ return {
17883
+ ok: false,
17884
+ error: error instanceof Error ? error.message : "Token refresh failed"
17885
+ };
17886
+ }
17887
+ }
17888
+
17889
+ // src/auth/nextjs-keycloak.ts
17890
+ function buildAuthCookies(config = {}) {
17891
+ const { domain, sessionToken = true, callbackUrl = true } = config;
17892
+ const isProduction = process.env.NODE_ENV === "production";
17893
+ const cookieDomain = isProduction ? domain : void 0;
17894
+ const baseOptions = {
17895
+ httpOnly: true,
17896
+ sameSite: "lax",
17897
+ path: "/",
17898
+ secure: isProduction,
17899
+ domain: cookieDomain
17900
+ };
17901
+ const cookies = {
17902
+ pkceCodeVerifier: {
17903
+ name: "authjs.pkce.code_verifier",
17904
+ options: { ...baseOptions }
17905
+ },
17906
+ state: {
17907
+ name: "authjs.state",
17908
+ options: { ...baseOptions }
17909
+ }
17910
+ };
17911
+ if (sessionToken) {
17912
+ cookies.sessionToken = {
17913
+ name: isProduction ? "__Secure-authjs.session-token" : "authjs.session-token",
17914
+ options: { ...baseOptions }
17915
+ };
17916
+ }
17917
+ if (callbackUrl) {
17918
+ cookies.callbackUrl = {
17919
+ name: isProduction ? "__Secure-authjs.callback-url" : "authjs.callback-url",
17920
+ options: { ...baseOptions }
17921
+ };
17922
+ }
17923
+ return cookies;
17924
+ }
17925
+ function buildRedirectCallback(config = {}) {
17926
+ const { allowWwwVariant = false } = config;
17927
+ return async ({ url, baseUrl }) => {
17928
+ if (url.startsWith("/")) return `${baseUrl}${url}`;
17929
+ try {
17930
+ if (new URL(url).origin === baseUrl) return url;
17931
+ } catch {
17932
+ return baseUrl;
17933
+ }
17934
+ if (allowWwwVariant) {
17935
+ try {
17936
+ const urlHost = new URL(url).hostname;
17937
+ const baseHost = new URL(baseUrl).hostname;
17938
+ if (urlHost === `www.${baseHost}` || baseHost === `www.${urlHost}`) {
17939
+ return url;
17940
+ }
17941
+ } catch {
17942
+ }
17943
+ }
17944
+ return baseUrl;
17945
+ };
17946
+ }
17947
+ function buildKeycloakCallbacks(config) {
17948
+ const {
17949
+ issuer,
17950
+ clientId,
17951
+ clientSecret,
17952
+ defaultRoles = [],
17953
+ debug = process.env.NODE_ENV === "development"
17954
+ } = config;
17955
+ const kcConfig = { issuer, clientId, clientSecret };
17956
+ function log(message, meta) {
17957
+ if (debug) {
17958
+ console.log(`[Auth] ${message}`, meta ? JSON.stringify(meta) : "");
17959
+ }
17960
+ }
17961
+ return {
17962
+ /**
17963
+ * JWT callback — stores Keycloak tokens and handles refresh.
17964
+ *
17965
+ * Compatible with Auth.js v5 JWT callback signature.
17966
+ */
17967
+ async jwt({
17968
+ token,
17969
+ user,
17970
+ account
17971
+ }) {
17972
+ if (user) {
17973
+ token.id = token.sub ?? user.id;
17974
+ }
17975
+ if (account?.provider === "keycloak") {
17976
+ token.accessToken = account.access_token;
17977
+ token.refreshToken = account.refresh_token;
17978
+ token.idToken = account.id_token;
17979
+ token.roles = parseKeycloakRoles(
17980
+ account.access_token,
17981
+ defaultRoles
17982
+ );
17983
+ token.accessTokenExpires = account.expires_at ? account.expires_at * 1e3 : Date.now() + 3e5;
17984
+ return token;
17985
+ }
17986
+ if (!isTokenExpired(token.accessTokenExpires)) {
17987
+ return token;
17988
+ }
17989
+ if (token.refreshToken) {
17990
+ log("Token expired, attempting refresh...");
17991
+ const result = await refreshKeycloakToken(
17992
+ kcConfig,
17993
+ token.refreshToken,
17994
+ defaultRoles
17995
+ );
17996
+ if (result.ok) {
17997
+ token.accessToken = result.tokens.accessToken;
17998
+ token.idToken = result.tokens.idToken ?? token.idToken;
17999
+ token.refreshToken = result.tokens.refreshToken ?? token.refreshToken;
18000
+ token.accessTokenExpires = result.tokens.expiresAt;
18001
+ token.roles = result.tokens.roles;
18002
+ delete token.error;
18003
+ log("Token refreshed OK");
18004
+ return token;
18005
+ }
18006
+ log("Token refresh failed", { error: result.error });
18007
+ return { ...token, error: "RefreshTokenError" };
18008
+ }
18009
+ log("Token expired but no refresh token available");
18010
+ return { ...token, error: "RefreshTokenError" };
18011
+ },
18012
+ /**
18013
+ * Session callback — maps JWT fields to the session object.
18014
+ *
18015
+ * Compatible with Auth.js v5 session callback signature.
18016
+ */
18017
+ async session({
18018
+ session,
18019
+ token
18020
+ }) {
18021
+ const user = session.user;
18022
+ if (user) {
18023
+ user.id = token.id || token.sub;
18024
+ user.roles = token.roles || [];
18025
+ }
18026
+ session.idToken = token.idToken;
18027
+ session.accessToken = token.accessToken;
18028
+ if (token.error) {
18029
+ session.error = token.error;
18030
+ }
18031
+ return session;
18032
+ }
18033
+ };
18034
+ }
18035
+
18036
+ // src/auth/api-security.ts
18037
+ var StandardRateLimitPresets = {
18038
+ /** General API: 100/min, 200/min authenticated */
18039
+ apiGeneral: {
18040
+ limit: 100,
18041
+ windowSeconds: 60,
18042
+ authenticatedLimit: 200
18043
+ },
18044
+ /** Admin operations: 100/min (admins are trusted) */
18045
+ adminAction: {
18046
+ limit: 100,
18047
+ windowSeconds: 60
18048
+ },
18049
+ /** AI/expensive operations: 20/hour, 50/hour authenticated */
18050
+ aiRequest: {
18051
+ limit: 20,
18052
+ windowSeconds: 3600,
18053
+ authenticatedLimit: 50
18054
+ },
18055
+ /** Auth attempts: 5/15min with 15min block */
18056
+ authAttempt: {
18057
+ limit: 5,
18058
+ windowSeconds: 900,
18059
+ blockDurationSeconds: 900
18060
+ },
18061
+ /** Contact/public forms: 10/hour */
18062
+ publicForm: {
18063
+ limit: 10,
18064
+ windowSeconds: 3600,
18065
+ blockDurationSeconds: 1800
18066
+ },
18067
+ /** Checkout/billing: 10/hour with 1hr block */
18068
+ checkout: {
18069
+ limit: 10,
18070
+ windowSeconds: 3600,
18071
+ blockDurationSeconds: 3600
18072
+ }
18073
+ };
18074
+ function resolveRateLimitIdentifier(session, clientIp) {
18075
+ if (session?.user?.id) {
18076
+ return { identifier: `user:${session.user.id}`, isAuthenticated: true };
18077
+ }
18078
+ if (session?.user?.email) {
18079
+ return {
18080
+ identifier: `email:${session.user.email}`,
18081
+ isAuthenticated: true
18082
+ };
18083
+ }
18084
+ return { identifier: `ip:${clientIp}`, isAuthenticated: false };
18085
+ }
18086
+ function extractClientIp(getHeader) {
18087
+ return getHeader("cf-connecting-ip") || getHeader("x-real-ip") || getHeader("x-forwarded-for")?.split(",")[0]?.trim() || "unknown";
18088
+ }
18089
+ function buildRateLimitHeaders(limit, remaining, resetAtMs) {
18090
+ return {
18091
+ "X-RateLimit-Limit": String(limit),
18092
+ "X-RateLimit-Remaining": String(Math.max(0, remaining)),
18093
+ "X-RateLimit-Reset": String(Math.ceil(resetAtMs / 1e3))
18094
+ };
18095
+ }
18096
+ function buildErrorBody(error, extra) {
18097
+ return { error, ...extra };
18098
+ }
18099
+ var WrapperPresets = {
18100
+ /** Public route: no auth, rate limited */
18101
+ public: {
18102
+ requireAuth: false,
18103
+ requireAdmin: false,
18104
+ rateLimit: "apiGeneral"
18105
+ },
18106
+ /** Authenticated route: requires session */
18107
+ authenticated: {
18108
+ requireAuth: true,
18109
+ requireAdmin: false,
18110
+ rateLimit: "apiGeneral"
18111
+ },
18112
+ /** Admin route: requires session with admin role */
18113
+ admin: {
18114
+ requireAuth: true,
18115
+ requireAdmin: true,
18116
+ rateLimit: "adminAction"
18117
+ },
18118
+ /** Legacy admin: accepts session OR bearer token */
18119
+ legacyAdmin: {
18120
+ requireAuth: true,
18121
+ requireAdmin: true,
18122
+ allowBearerToken: true,
18123
+ rateLimit: "adminAction"
18124
+ },
18125
+ /** AI/expensive: requires auth, strict rate limit */
18126
+ ai: {
18127
+ requireAuth: true,
18128
+ requireAdmin: false,
18129
+ rateLimit: "aiRequest"
18130
+ },
18131
+ /** Cron: no rate limit, admin-level access */
18132
+ cron: {
18133
+ requireAuth: true,
18134
+ requireAdmin: false,
18135
+ skipRateLimit: true,
18136
+ skipAudit: false
18137
+ }
18138
+ };
18139
+
18140
+ // src/auth/schemas.ts
18141
+ import { z as z2 } from "zod";
18142
+ var EmailSchema = z2.string().trim().toLowerCase().email("Invalid email address");
18143
+ var PasswordSchema = z2.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters");
18144
+ var SlugSchema = z2.string().min(1, "Slug is required").max(100, "Slug must be less than 100 characters").regex(
18145
+ /^[a-z0-9-]+$/,
18146
+ "Slug can only contain lowercase letters, numbers, and hyphens"
18147
+ );
18148
+ var PhoneSchema = z2.string().regex(/^[\d\s()+.\-]{7,20}$/, "Invalid phone number format");
18149
+ var PersonNameSchema = z2.string().min(2, "Name must be at least 2 characters").max(100, "Name must be less than 100 characters").regex(
18150
+ /^[a-zA-Z\s\-']+$/,
18151
+ "Name can only contain letters, spaces, hyphens and apostrophes"
18152
+ );
18153
+ function createSafeTextSchema(options) {
18154
+ const {
18155
+ min,
18156
+ max,
18157
+ allowHtml = false,
18158
+ allowUrls = false,
18159
+ fieldName = "Text"
18160
+ } = options ?? {};
18161
+ let schema = z2.string();
18162
+ if (min !== void 0)
18163
+ schema = schema.min(min, `${fieldName} must be at least ${min} characters`);
18164
+ if (max !== void 0)
18165
+ schema = schema.max(
18166
+ max,
18167
+ `${fieldName} must be less than ${max} characters`
18168
+ );
18169
+ if (!allowHtml && !allowUrls) {
18170
+ return schema.refine((val) => !HTML_TAG_PATTERN.test(val), "HTML tags are not allowed").refine(
18171
+ (val) => !URL_PROTOCOL_PATTERN.test(val),
18172
+ "Links are not allowed for security reasons"
18173
+ ).refine(
18174
+ (val) => !URL_DOMAIN_PATTERN.test(val),
18175
+ "Links are not allowed for security reasons"
18176
+ );
18177
+ }
18178
+ if (!allowHtml) {
18179
+ return schema.refine(
18180
+ (val) => !HTML_TAG_PATTERN.test(val),
18181
+ "HTML tags are not allowed"
18182
+ );
18183
+ }
18184
+ if (!allowUrls) {
18185
+ return schema.refine(
18186
+ (val) => !URL_PROTOCOL_PATTERN.test(val),
18187
+ "Links are not allowed for security reasons"
18188
+ ).refine(
18189
+ (val) => !URL_DOMAIN_PATTERN.test(val),
18190
+ "Links are not allowed for security reasons"
18191
+ );
18192
+ }
18193
+ return schema;
18194
+ }
18195
+ var PaginationSchema = z2.object({
18196
+ page: z2.coerce.number().int().positive().default(1),
18197
+ limit: z2.coerce.number().int().positive().max(100).default(20),
18198
+ sortBy: z2.string().optional(),
18199
+ sortOrder: z2.enum(["asc", "desc"]).default("desc")
18200
+ });
18201
+ var DateRangeSchema = z2.object({
18202
+ startDate: z2.string().datetime(),
18203
+ endDate: z2.string().datetime()
18204
+ }).refine((data) => new Date(data.startDate) <= new Date(data.endDate), {
18205
+ message: "Start date must be before end date"
18206
+ });
18207
+ var SearchQuerySchema = z2.object({
18208
+ query: z2.string().min(1).max(200).trim(),
18209
+ page: z2.coerce.number().int().positive().default(1),
18210
+ limit: z2.coerce.number().int().positive().max(50).default(10)
18211
+ });
18212
+ var LoginSchema = z2.object({
18213
+ email: EmailSchema,
18214
+ password: PasswordSchema
18215
+ });
18216
+ var SignupSchema = z2.object({
18217
+ email: EmailSchema,
18218
+ password: PasswordSchema,
18219
+ name: z2.string().min(2).max(100).optional()
18220
+ });
18221
+
18222
+ // src/auth/feature-flags.ts
18223
+ function detectStage() {
18224
+ const stage = process.env.DEPLOYMENT_STAGE;
18225
+ if (stage === "staging" || stage === "preview") return stage;
18226
+ if (process.env.NODE_ENV === "production") return "production";
18227
+ return "development";
18228
+ }
18229
+ function resolveFlagValue(value) {
18230
+ if (typeof value === "boolean") return value;
18231
+ const envValue = process.env[value.envVar];
18232
+ if (envValue === void 0 || envValue === "") {
18233
+ return value.default ?? false;
18234
+ }
18235
+ return envValue === "true" || envValue === "1";
18236
+ }
18237
+ function createFeatureFlags(definitions) {
18238
+ return {
18239
+ /**
18240
+ * Resolve all flags for the current environment.
18241
+ * Call this once at startup or per-request for dynamic flags.
18242
+ */
18243
+ resolve(stage) {
18244
+ const currentStage = stage ?? detectStage();
18245
+ const resolved = {};
18246
+ for (const [key, def] of Object.entries(definitions)) {
18247
+ const stageKey = currentStage === "preview" ? "staging" : currentStage;
18248
+ resolved[key] = resolveFlagValue(def[stageKey]);
18249
+ }
18250
+ return resolved;
18251
+ },
18252
+ /**
18253
+ * Check if a single flag is enabled.
18254
+ */
18255
+ isEnabled(flag, stage) {
18256
+ const currentStage = stage ?? detectStage();
18257
+ const def = definitions[flag];
18258
+ const stageKey = currentStage === "preview" ? "staging" : currentStage;
18259
+ return resolveFlagValue(def[stageKey]);
18260
+ },
18261
+ /**
18262
+ * Get the flag definitions (for introspection/admin UI).
18263
+ */
18264
+ definitions
18265
+ };
18266
+ }
18267
+ function buildAllowlist(config) {
18268
+ const fromEnv = config.envVar ? process.env[config.envVar]?.split(",").map((e) => e.trim().toLowerCase()).filter(Boolean) ?? [] : [];
18269
+ const fallback = config.fallback?.map((e) => e.toLowerCase()) ?? [];
18270
+ return [.../* @__PURE__ */ new Set([...fromEnv, ...fallback])];
18271
+ }
18272
+ function isAllowlisted(email, allowlist) {
18273
+ return allowlist.includes(email.toLowerCase());
18274
+ }
18275
+
18276
+ // src/auth/rate-limiter.ts
18277
+ var CommonRateLimits = {
18278
+ /** General API: 100/min, 200/min authenticated */
18279
+ apiGeneral: {
18280
+ limit: 100,
18281
+ windowSeconds: 60,
18282
+ authenticatedLimit: 200
18283
+ },
18284
+ /** Admin actions: 100/min */
18285
+ adminAction: {
18286
+ limit: 100,
18287
+ windowSeconds: 60
18288
+ },
18289
+ /** Auth attempts: 10/15min with 30min block */
18290
+ authAttempt: {
18291
+ limit: 10,
18292
+ windowSeconds: 900,
18293
+ blockDurationSeconds: 1800
18294
+ },
18295
+ /** AI/expensive requests: 20/hour, 50/hour authenticated */
18296
+ aiRequest: {
18297
+ limit: 20,
18298
+ windowSeconds: 3600,
18299
+ authenticatedLimit: 50
18300
+ },
18301
+ /** Public form submissions: 5/hour with 1hr block */
18302
+ publicForm: {
18303
+ limit: 5,
18304
+ windowSeconds: 3600,
18305
+ blockDurationSeconds: 3600
18306
+ },
18307
+ /** Checkout/billing: 10/hour with 1hr block */
18308
+ checkout: {
18309
+ limit: 10,
18310
+ windowSeconds: 3600,
18311
+ blockDurationSeconds: 3600
18312
+ }
18313
+ };
18314
+ function createMemoryRateLimitStore() {
18315
+ const windows = /* @__PURE__ */ new Map();
18316
+ const blocks = /* @__PURE__ */ new Map();
18317
+ const cleanupInterval = setInterval(() => {
18318
+ const now = Date.now();
18319
+ for (const [key, entry] of windows) {
18320
+ if (entry.expiresAt < now) windows.delete(key);
18321
+ }
18322
+ for (const [key, expiry] of blocks) {
18323
+ if (expiry < now) blocks.delete(key);
18324
+ }
18325
+ }, 60 * 1e3);
18326
+ if (cleanupInterval.unref) {
18327
+ cleanupInterval.unref();
18328
+ }
18329
+ return {
18330
+ async increment(key, windowMs, now) {
18331
+ const windowStart = now - windowMs;
18332
+ let entry = windows.get(key);
18333
+ if (!entry) {
18334
+ entry = { timestamps: [], expiresAt: now + windowMs + 6e4 };
18335
+ windows.set(key, entry);
18336
+ }
18337
+ entry.timestamps = entry.timestamps.filter((t) => t > windowStart);
18338
+ entry.timestamps.push(now);
18339
+ entry.expiresAt = now + windowMs + 6e4;
18340
+ return { count: entry.timestamps.length };
18341
+ },
18342
+ async isBlocked(key) {
18343
+ const expiry = blocks.get(key);
18344
+ if (!expiry || expiry < Date.now()) {
18345
+ blocks.delete(key);
18346
+ return { blocked: false, ttlMs: 0 };
18347
+ }
18348
+ return { blocked: true, ttlMs: expiry - Date.now() };
18349
+ },
18350
+ async setBlock(key, durationSeconds) {
18351
+ blocks.set(key, Date.now() + durationSeconds * 1e3);
18352
+ },
18353
+ async reset(key) {
18354
+ windows.delete(key);
18355
+ blocks.delete(`block:${key}`);
18356
+ blocks.delete(key);
18357
+ }
18358
+ };
18359
+ }
18360
+ var defaultStore;
18361
+ function getDefaultStore() {
18362
+ if (!defaultStore) {
18363
+ defaultStore = createMemoryRateLimitStore();
18364
+ }
18365
+ return defaultStore;
18366
+ }
18367
+ async function checkRateLimit(operation, identifier, rule, options = {}) {
18368
+ const store = options.store ?? getDefaultStore();
18369
+ const limit = options.isAuthenticated && rule.authenticatedLimit ? rule.authenticatedLimit : rule.limit;
18370
+ const now = Date.now();
18371
+ const windowMs = rule.windowSeconds * 1e3;
18372
+ const resetAt = now + windowMs;
18373
+ const key = `ratelimit:${operation}:${identifier}`;
18374
+ const blockKey = `ratelimit:block:${operation}:${identifier}`;
18375
+ try {
18376
+ if (rule.blockDurationSeconds) {
18377
+ const blockStatus = await store.isBlocked(blockKey);
18378
+ if (blockStatus.blocked) {
18379
+ return {
18380
+ allowed: false,
18381
+ remaining: 0,
18382
+ resetAt: now + blockStatus.ttlMs,
18383
+ current: limit + 1,
18384
+ limit,
18385
+ retryAfterSeconds: Math.ceil(blockStatus.ttlMs / 1e3)
18386
+ };
18387
+ }
18388
+ }
18389
+ const { count } = await store.increment(key, windowMs, now);
18390
+ if (count > limit) {
18391
+ options.logger?.warn("Rate limit exceeded", {
18392
+ operation,
18393
+ identifier,
18394
+ current: count,
18395
+ limit
18396
+ });
18397
+ if (rule.blockDurationSeconds) {
18398
+ await store.setBlock(blockKey, rule.blockDurationSeconds);
18399
+ }
18400
+ return {
18401
+ allowed: false,
18402
+ remaining: 0,
18403
+ resetAt,
18404
+ current: count,
18405
+ limit,
18406
+ retryAfterSeconds: Math.ceil(windowMs / 1e3)
18407
+ };
18408
+ }
18409
+ return {
18410
+ allowed: true,
18411
+ remaining: limit - count,
18412
+ resetAt,
18413
+ current: count,
18414
+ limit,
18415
+ retryAfterSeconds: 0
18416
+ };
18417
+ } catch (error) {
18418
+ options.logger?.error("Rate limit check failed, allowing request", {
18419
+ error: error instanceof Error ? error.message : String(error),
18420
+ operation,
18421
+ identifier
18422
+ });
18423
+ return {
18424
+ allowed: true,
18425
+ remaining: limit,
18426
+ resetAt,
18427
+ current: 0,
18428
+ limit,
18429
+ retryAfterSeconds: 0
18430
+ };
18431
+ }
18432
+ }
18433
+ async function getRateLimitStatus(operation, identifier, rule, store) {
18434
+ const s = store ?? getDefaultStore();
18435
+ const key = `ratelimit:${operation}:${identifier}`;
18436
+ const now = Date.now();
18437
+ const windowMs = rule.windowSeconds * 1e3;
18438
+ try {
18439
+ const { count } = await s.increment(key, windowMs, now);
18440
+ return {
18441
+ allowed: count <= rule.limit,
18442
+ remaining: Math.max(0, rule.limit - count),
18443
+ resetAt: now + windowMs,
18444
+ current: count,
18445
+ limit: rule.limit,
18446
+ retryAfterSeconds: count > rule.limit ? Math.ceil(windowMs / 1e3) : 0
18447
+ };
18448
+ } catch {
18449
+ return null;
18450
+ }
18451
+ }
18452
+ async function resetRateLimitForKey(operation, identifier, store) {
18453
+ const s = store ?? getDefaultStore();
18454
+ const key = `ratelimit:${operation}:${identifier}`;
18455
+ const blockKey = `ratelimit:block:${operation}:${identifier}`;
18456
+ await s.reset(key);
18457
+ await s.reset(blockKey);
18458
+ }
18459
+ function buildRateLimitResponseHeaders(result) {
18460
+ const headers = {
18461
+ "X-RateLimit-Limit": String(result.limit),
18462
+ "X-RateLimit-Remaining": String(result.remaining),
18463
+ "X-RateLimit-Reset": String(Math.ceil(result.resetAt / 1e3))
18464
+ };
18465
+ if (!result.allowed) {
18466
+ headers["Retry-After"] = String(result.retryAfterSeconds);
18467
+ }
18468
+ return headers;
18469
+ }
18470
+ function resolveIdentifier(session, clientIp) {
18471
+ if (session?.user?.id) {
18472
+ return { identifier: `user:${session.user.id}`, isAuthenticated: true };
18473
+ }
18474
+ if (session?.user?.email) {
18475
+ return {
18476
+ identifier: `email:${session.user.email}`,
18477
+ isAuthenticated: true
18478
+ };
18479
+ }
18480
+ return { identifier: `ip:${clientIp ?? "unknown"}`, isAuthenticated: false };
18481
+ }
18482
+
18483
+ // src/auth/audit.ts
18484
+ var StandardAuditActions = {
18485
+ // Authentication
18486
+ LOGIN_SUCCESS: "auth.login.success",
18487
+ LOGIN_FAILURE: "auth.login.failure",
18488
+ LOGOUT: "auth.logout",
18489
+ SESSION_REFRESH: "auth.session.refresh",
18490
+ PASSWORD_CHANGE: "auth.password.change",
18491
+ PASSWORD_RESET: "auth.password.reset",
18492
+ // Billing
18493
+ CHECKOUT_START: "billing.checkout.start",
18494
+ CHECKOUT_COMPLETE: "billing.checkout.complete",
18495
+ SUBSCRIPTION_CREATE: "billing.subscription.create",
18496
+ SUBSCRIPTION_CANCEL: "billing.subscription.cancel",
18497
+ SUBSCRIPTION_UPDATE: "billing.subscription.update",
18498
+ PAYMENT_FAILED: "billing.payment.failed",
18499
+ // Admin
18500
+ ADMIN_LOGIN: "admin.login",
18501
+ ADMIN_USER_VIEW: "admin.user.view",
18502
+ ADMIN_USER_UPDATE: "admin.user.update",
18503
+ ADMIN_CONFIG_CHANGE: "admin.config.change",
18504
+ // Security Events
18505
+ RATE_LIMIT_EXCEEDED: "security.rate_limit.exceeded",
18506
+ INVALID_INPUT: "security.input.invalid",
18507
+ UNAUTHORIZED_ACCESS: "security.access.unauthorized",
18508
+ OWNERSHIP_VIOLATION: "security.ownership.violation",
18509
+ WEBHOOK_SIGNATURE_INVALID: "security.webhook.signature_invalid",
18510
+ // Data
18511
+ DATA_EXPORT: "data.export",
18512
+ DATA_DELETE: "data.delete",
18513
+ DATA_UPDATE: "data.update"
18514
+ };
18515
+ function extractAuditIp(request) {
18516
+ if (!request) return void 0;
18517
+ const headers = [
18518
+ "cf-connecting-ip",
18519
+ // Cloudflare
18520
+ "x-real-ip",
18521
+ // Nginx
18522
+ "x-forwarded-for",
18523
+ // Standard proxy
18524
+ "x-client-ip"
18525
+ // Apache
18526
+ ];
18527
+ for (const header of headers) {
18528
+ const value = request.headers.get(header);
18529
+ if (value) {
18530
+ return value.split(",")[0]?.trim();
18531
+ }
18532
+ }
18533
+ return void 0;
18534
+ }
18535
+ function extractAuditUserAgent(request) {
18536
+ return request?.headers.get("user-agent") ?? void 0;
18537
+ }
18538
+ function extractAuditRequestId(request) {
18539
+ return request?.headers.get("x-request-id") ?? crypto.randomUUID();
18540
+ }
18541
+ function createAuditActor(session) {
18542
+ if (!session?.user) {
18543
+ return { id: "anonymous", type: "anonymous" };
18544
+ }
18545
+ return {
18546
+ id: session.user.id ?? session.user.email ?? "unknown",
18547
+ email: session.user.email ?? void 0,
18548
+ type: "user"
18549
+ };
18550
+ }
18551
+ var defaultLogger = {
18552
+ info: (msg, meta) => console.log(msg, meta ? JSON.stringify(meta) : ""),
18553
+ warn: (msg, meta) => console.warn(msg, meta ? JSON.stringify(meta) : ""),
18554
+ error: (msg, meta) => console.error(msg, meta ? JSON.stringify(meta) : "")
18555
+ };
18556
+ function createAuditLogger(options = {}) {
18557
+ const { persist, logger = defaultLogger } = options;
18558
+ async function log(event, request) {
18559
+ const record = {
18560
+ id: crypto.randomUUID(),
18561
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
18562
+ ip: extractAuditIp(request),
18563
+ userAgent: extractAuditUserAgent(request),
18564
+ requestId: extractAuditRequestId(request),
18565
+ ...event
18566
+ };
18567
+ const logFn = event.outcome === "failure" || event.outcome === "blocked" ? logger.warn : logger.info;
18568
+ logFn(`[AUDIT] ${event.action}`, {
18569
+ auditId: record.id,
18570
+ actor: record.actor,
18571
+ action: record.action,
18572
+ resource: record.resource,
18573
+ outcome: record.outcome,
18574
+ ip: record.ip,
18575
+ metadata: record.metadata,
18576
+ reason: record.reason
18577
+ });
18578
+ if (persist) {
18579
+ try {
18580
+ await persist(record);
18581
+ } catch (error) {
18582
+ logger.error("Failed to persist audit log", {
18583
+ error: error instanceof Error ? error.message : String(error),
18584
+ auditId: record.id
18585
+ });
18586
+ }
18587
+ }
18588
+ return record;
18589
+ }
18590
+ function createTimedAudit(event, request) {
18591
+ const startTime = Date.now();
18592
+ return {
18593
+ success: async (metadata) => {
18594
+ return log(
18595
+ {
18596
+ ...event,
18597
+ outcome: "success",
18598
+ metadata: {
18599
+ ...event.metadata,
18600
+ ...metadata,
18601
+ durationMs: Date.now() - startTime
18602
+ }
18603
+ },
18604
+ request
18605
+ );
18606
+ },
18607
+ failure: async (reason, metadata) => {
18608
+ return log(
18609
+ {
18610
+ ...event,
18611
+ outcome: "failure",
18612
+ reason,
18613
+ metadata: {
18614
+ ...event.metadata,
18615
+ ...metadata,
18616
+ durationMs: Date.now() - startTime
18617
+ }
18618
+ },
18619
+ request
18620
+ );
18621
+ },
18622
+ blocked: async (reason, metadata) => {
18623
+ return log(
18624
+ {
18625
+ ...event,
18626
+ outcome: "blocked",
18627
+ reason,
18628
+ metadata: {
18629
+ ...event.metadata,
18630
+ ...metadata,
18631
+ durationMs: Date.now() - startTime
18632
+ }
18633
+ },
18634
+ request
18635
+ );
18636
+ }
18637
+ };
18638
+ }
18639
+ return { log, createTimedAudit };
18640
+ }
18641
+
17226
18642
  // src/http/health.ts
17227
18643
  function createHealthEndpoints(platform, options = {}) {
17228
18644
  const {
@@ -18301,7 +19717,7 @@ var MemoryAuditLog = class {
18301
19717
  };
18302
19718
 
18303
19719
  // src/adapters/memory/MemoryWebhook.ts
18304
- import { createHmac } from "crypto";
19720
+ import { createHmac as createHmac3, randomBytes as randomBytes26 } from "crypto";
18305
19721
  var MemoryWebhook = class {
18306
19722
  endpoints = /* @__PURE__ */ new Map();
18307
19723
  deliveries = /* @__PURE__ */ new Map();
@@ -18583,7 +19999,7 @@ var MemoryWebhook = class {
18583
19999
  config.secret,
18584
20000
  algorithm
18585
20001
  );
18586
- const providedSig = signature.replace(/^(sha256=|sha512=|sha1=)/, "");
20002
+ const providedSig = signature.replace(/^(sha256=|sha512=)/, "");
18587
20003
  if (providedSig !== expectedSignature) {
18588
20004
  return { valid: false, error: "Invalid signature" };
18589
20005
  }
@@ -18688,7 +20104,7 @@ var MemoryWebhook = class {
18688
20104
  this.deliveries.set(delivery.id, delivery);
18689
20105
  }
18690
20106
  async executeDelivery(endpoint, event, attemptNumber) {
18691
- const attemptId = `att_${Date.now().toString(36)}${Math.random().toString(36).substring(2, 8)}`;
20107
+ const attemptId = `att_${Date.now().toString(36)}${randomBytes26(4).toString("hex")}`;
18692
20108
  const startTime = Date.now();
18693
20109
  if (this.config.simulatedDelay > 0) {
18694
20110
  await new Promise(
@@ -18742,7 +20158,7 @@ var MemoryWebhook = class {
18742
20158
  this.endpoints.set(endpoint.id, endpoint);
18743
20159
  }
18744
20160
  computeSignature(payload, secret, algorithm) {
18745
- return createHmac(algorithm, secret).update(payload).digest("hex");
20161
+ return createHmac3(algorithm, secret).update(payload).digest("hex");
18746
20162
  }
18747
20163
  };
18748
20164
 
@@ -19093,6 +20509,7 @@ var MemoryNotification = class {
19093
20509
  };
19094
20510
 
19095
20511
  // src/adapters/memory/MemoryScheduler.ts
20512
+ import { randomBytes as randomBytes27 } from "crypto";
19096
20513
  var MemoryScheduler = class {
19097
20514
  config;
19098
20515
  schedules = /* @__PURE__ */ new Map();
@@ -19376,7 +20793,7 @@ var MemoryScheduler = class {
19376
20793
  }
19377
20794
  }
19378
20795
  async executeSchedule(schedule) {
19379
- const executionId = `exec_${Date.now().toString(36)}${Math.random().toString(36).substring(2, 8)}`;
20796
+ const executionId = `exec_${Date.now().toString(36)}${randomBytes27(4).toString("hex")}`;
19380
20797
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
19381
20798
  const execution = {
19382
20799
  id: executionId,
@@ -19856,6 +21273,7 @@ CREATE INDEX IF NOT EXISTS idx_${tableName}_trace_id ON ${tableName}((context->>
19856
21273
  };
19857
21274
 
19858
21275
  // src/adapters/database/DatabaseErrorReporter.ts
21276
+ import { randomBytes as randomBytes28 } from "crypto";
19859
21277
  var DatabaseErrorReporter = class {
19860
21278
  db;
19861
21279
  errorsTable;
@@ -20150,7 +21568,7 @@ CREATE INDEX IF NOT EXISTS idx_${breadcrumbsTable}_error ON ${breadcrumbsTable}(
20150
21568
  if (report.breadcrumbs && report.breadcrumbs.length > 0) {
20151
21569
  for (const crumb of report.breadcrumbs) {
20152
21570
  await this.db.from(this.breadcrumbsTable).insert({
20153
- id: `bc_${Date.now().toString(36)}${Math.random().toString(36).substring(2, 8)}`,
21571
+ id: `bc_${Date.now().toString(36)}${randomBytes28(4).toString("hex")}`,
20154
21572
  error_id: report.id,
20155
21573
  category: crumb.category,
20156
21574
  message: crumb.message,
@@ -20190,6 +21608,7 @@ CREATE INDEX IF NOT EXISTS idx_${breadcrumbsTable}_error ON ${breadcrumbsTable}(
20190
21608
  };
20191
21609
 
20192
21610
  // src/adapters/database/DatabasePromptStore.ts
21611
+ import { randomBytes as randomBytes29 } from "crypto";
20193
21612
  var DatabasePromptStore = class {
20194
21613
  db;
20195
21614
  cache;
@@ -20329,7 +21748,7 @@ CREATE INDEX IF NOT EXISTS idx_${tablePrefix}usage_experiment ON ${tablePrefix}p
20329
21748
  // Prompt CRUD
20330
21749
  // ═══════════════════════════════════════════════════════════════
20331
21750
  async create(prompt) {
20332
- const id = `prompt_${Date.now()}_${Math.random().toString(36).substring(7)}`;
21751
+ const id = `prompt_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20333
21752
  const now = /* @__PURE__ */ new Date();
20334
21753
  const newPrompt = {
20335
21754
  ...prompt,
@@ -20357,7 +21776,7 @@ CREATE INDEX IF NOT EXISTS idx_${tablePrefix}usage_experiment ON ${tablePrefix}p
20357
21776
  created_by: newPrompt.createdBy,
20358
21777
  updated_by: newPrompt.updatedBy
20359
21778
  }).execute();
20360
- const versionId = `pv_${Date.now()}_${Math.random().toString(36).substring(7)}`;
21779
+ const versionId = `pv_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20361
21780
  await this.db.from(this.versionsTable).insert({
20362
21781
  id: versionId,
20363
21782
  prompt_id: id,
@@ -20426,7 +21845,7 @@ CREATE INDEX IF NOT EXISTS idx_${tablePrefix}usage_experiment ON ${tablePrefix}p
20426
21845
  await this.db.from(this.versionsTable).update({ is_latest: false }).where("prompt_id", "=", prompt.id).execute();
20427
21846
  const versionsResult = await this.db.from(this.versionsTable).where("prompt_id", "=", prompt.id).execute();
20428
21847
  const newVersionNum = versionsResult.data.length + 1;
20429
- const versionId = `pv_${Date.now()}_${Math.random().toString(36).substring(7)}`;
21848
+ const versionId = `pv_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20430
21849
  await this.db.from(this.versionsTable).insert({
20431
21850
  id: versionId,
20432
21851
  prompt_id: prompt.id,
@@ -20681,7 +22100,7 @@ ${v2.content}`;
20681
22100
  // A/B Testing
20682
22101
  // ═══════════════════════════════════════════════════════════════
20683
22102
  async createExperiment(experiment) {
20684
- const id = `exp_${Date.now()}_${Math.random().toString(36).substring(7)}`;
22103
+ const id = `exp_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20685
22104
  const now = /* @__PURE__ */ new Date();
20686
22105
  const newExperiment = {
20687
22106
  ...experiment,
@@ -20795,7 +22214,7 @@ ${v2.content}`;
20795
22214
  // Prompt Chains
20796
22215
  // ═══════════════════════════════════════════════════════════════
20797
22216
  async createChain(chain) {
20798
- const id = `chain_${Date.now()}_${Math.random().toString(36).substring(7)}`;
22217
+ const id = `chain_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20799
22218
  const now = /* @__PURE__ */ new Date();
20800
22219
  const newChain = {
20801
22220
  ...chain,
@@ -20893,7 +22312,7 @@ ${v2.content}`;
20893
22312
  // Usage & Analytics
20894
22313
  // ═══════════════════════════════════════════════════════════════
20895
22314
  async recordUsage(record) {
20896
- const id = `usage_${Date.now()}_${Math.random().toString(36).substring(7)}`;
22315
+ const id = `usage_${Date.now()}_${randomBytes29(4).toString("hex")}`;
20897
22316
  const now = /* @__PURE__ */ new Date();
20898
22317
  const usageRecord = {
20899
22318
  ...record,
@@ -21079,8 +22498,9 @@ ${v2.content}`;
21079
22498
  };
21080
22499
 
21081
22500
  // src/adapters/database/DatabaseCompliance.ts
22501
+ import { randomBytes as randomBytes30 } from "crypto";
21082
22502
  function generateId(prefix) {
21083
- return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
22503
+ return `${prefix}_${Date.now()}_${randomBytes30(4).toString("hex")}`;
21084
22504
  }
21085
22505
  function toDate(value) {
21086
22506
  return value ? new Date(value) : void 0;
@@ -21271,7 +22691,7 @@ var DatabaseCompliance = class {
21271
22691
  async createDsar(options) {
21272
22692
  const id = generateId("dsar");
21273
22693
  const now = (/* @__PURE__ */ new Date()).toISOString();
21274
- const verificationToken = `verify_${Math.random().toString(36).substring(2)}`;
22694
+ const verificationToken = `verify_${randomBytes30(16).toString("hex")}`;
21275
22695
  const result = await this.db.from("compliance_dsars").insert({
21276
22696
  id,
21277
22697
  type: options.type,
@@ -22210,6 +23630,7 @@ var DatabaseCompliance = class {
22210
23630
  };
22211
23631
 
22212
23632
  // src/adapters/database/DatabaseAIUsage.ts
23633
+ import { randomBytes as randomBytes31 } from "crypto";
22213
23634
  var DatabaseAIUsage = class {
22214
23635
  db;
22215
23636
  config;
@@ -22223,7 +23644,7 @@ var DatabaseAIUsage = class {
22223
23644
  // Usage Recording
22224
23645
  // ─────────────────────────────────────────────────────────────
22225
23646
  async record(record) {
22226
- const id = `usage_${Date.now()}_${Math.random().toString(36).substring(7)}`;
23647
+ const id = `usage_${Date.now()}_${randomBytes31(4).toString("hex")}`;
22227
23648
  const now = /* @__PURE__ */ new Date();
22228
23649
  await this.db.from(`${this.prefix}records`).insert({
22229
23650
  id,
@@ -22330,7 +23751,7 @@ var DatabaseAIUsage = class {
22330
23751
  quota.category
22331
23752
  );
22332
23753
  const period = this.getPeriodBounds(quota.period, /* @__PURE__ */ new Date());
22333
- const id = existing?.id || `quota_${Date.now()}_${Math.random().toString(36).substring(7)}`;
23754
+ const id = existing?.id || `quota_${Date.now()}_${randomBytes31(4).toString("hex")}`;
22334
23755
  const data = {
22335
23756
  id,
22336
23757
  tenant_id: quota.tenantId,
@@ -22467,7 +23888,7 @@ var DatabaseAIUsage = class {
22467
23888
  existingResult.data[0]
22468
23889
  ) : null;
22469
23890
  const period = this.getPeriodBounds(budget.period, /* @__PURE__ */ new Date());
22470
- const id = existing?.id || `budget_${Date.now()}_${Math.random().toString(36).substring(7)}`;
23891
+ const id = existing?.id || `budget_${Date.now()}_${randomBytes31(4).toString("hex")}`;
22471
23892
  const data = {
22472
23893
  id,
22473
23894
  tenant_id: budget.tenantId,
@@ -22766,7 +24187,7 @@ var DatabaseAIUsage = class {
22766
24187
  }
22767
24188
  const items = Array.from(itemsMap.values());
22768
24189
  const subtotal = items.reduce((sum, item) => sum + item.costUsd, 0);
22769
- const id = `inv_${Date.now()}_${Math.random().toString(36).substring(7)}`;
24190
+ const id = `inv_${Date.now()}_${randomBytes31(4).toString("hex")}`;
22770
24191
  const now = /* @__PURE__ */ new Date();
22771
24192
  await this.db.from(`${this.prefix}invoices`).insert({
22772
24193
  id,
@@ -22988,7 +24409,7 @@ var DatabaseAIUsage = class {
22988
24409
  }
22989
24410
  }
22990
24411
  async createAlert(tenantId, type, severity, message, metadata) {
22991
- const id = `alert_${Date.now()}_${Math.random().toString(36).substring(7)}`;
24412
+ const id = `alert_${Date.now()}_${randomBytes31(4).toString("hex")}`;
22992
24413
  await this.db.from(`${this.prefix}alerts`).insert({
22993
24414
  id,
22994
24415
  tenant_id: tenantId,
@@ -23194,6 +24615,7 @@ var DatabaseAIUsage = class {
23194
24615
  };
23195
24616
 
23196
24617
  // src/adapters/database/DatabaseNotification.ts
24618
+ import { randomBytes as randomBytes32 } from "crypto";
23197
24619
  var DatabaseNotification = class {
23198
24620
  db;
23199
24621
  email;
@@ -23431,7 +24853,7 @@ var DatabaseNotification = class {
23431
24853
  // PUSH SUBSCRIPTIONS
23432
24854
  // ═══════════════════════════════════════════════════════════════
23433
24855
  async registerPushSubscription(userId, subscription) {
23434
- const id = `push_${Date.now()}_${Math.random().toString(36).substring(7)}`;
24856
+ const id = `push_${Date.now()}_${randomBytes32(4).toString("hex")}`;
23435
24857
  const existing = await this.db.from(`${this.prefix}push_subscriptions`).where("user_id", "=", userId).where("endpoint", "=", subscription.endpoint).execute();
23436
24858
  if (existing.data && existing.data.length > 0) {
23437
24859
  await this.db.from(`${this.prefix}push_subscriptions`).where("user_id", "=", userId).where("endpoint", "=", subscription.endpoint).update({
@@ -23529,7 +24951,7 @@ var DatabaseNotification = class {
23529
24951
  // TOPICS
23530
24952
  // ═══════════════════════════════════════════════════════════════
23531
24953
  async subscribeToTopic(userId, topic) {
23532
- const id = `topic_${Date.now()}_${Math.random().toString(36).substring(7)}`;
24954
+ const id = `topic_${Date.now()}_${randomBytes32(4).toString("hex")}`;
23533
24955
  const existing = await this.db.from(`${this.prefix}notification_topic_subs`).where("user_id", "=", userId).where("topic", "=", topic).execute();
23534
24956
  if (!existing.data || existing.data.length === 0) {
23535
24957
  await this.db.from(`${this.prefix}notification_topic_subs`).insert({
@@ -23610,7 +25032,7 @@ var DatabaseNotification = class {
23610
25032
  // PRIVATE HELPERS
23611
25033
  // ═══════════════════════════════════════════════════════════════
23612
25034
  async logDelivery(notificationId, channel, status, messageId, error) {
23613
- const id = `del_${Date.now()}_${Math.random().toString(36).substring(7)}`;
25035
+ const id = `del_${Date.now()}_${randomBytes32(4).toString("hex")}`;
23614
25036
  try {
23615
25037
  await this.db.from(`${this.prefix}notification_delivery_log`).insert({
23616
25038
  id,
@@ -23672,6 +25094,7 @@ var DatabaseNotification = class {
23672
25094
  };
23673
25095
 
23674
25096
  // src/adapters/database/DatabaseBilling.ts
25097
+ import { randomBytes as randomBytes33 } from "crypto";
23675
25098
  var DatabaseBilling = class {
23676
25099
  db;
23677
25100
  prefix;
@@ -23694,7 +25117,7 @@ var DatabaseBilling = class {
23694
25117
  return `${this.prefix}${name}`;
23695
25118
  }
23696
25119
  generateId(prefix) {
23697
- return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
25120
+ return `${prefix}_${Date.now()}_${randomBytes33(4).toString("hex")}`;
23698
25121
  }
23699
25122
  // ─────────────────────────────────────────────────────────────
23700
25123
  // Product & Price Management
@@ -25192,6 +26615,7 @@ var DatabaseBilling = class {
25192
26615
  };
25193
26616
 
25194
26617
  // src/adapters/scheduler/QueueScheduler.ts
26618
+ import { randomBytes as randomBytes34 } from "crypto";
25195
26619
  var QueueScheduler = class {
25196
26620
  queue;
25197
26621
  db;
@@ -25607,7 +27031,7 @@ CREATE INDEX IF NOT EXISTS idx_${executionsTable}_started ON ${executionsTable}(
25607
27031
  }
25608
27032
  }
25609
27033
  async executeSchedule(schedule) {
25610
- const executionId = `exec_${Date.now().toString(36)}${Math.random().toString(36).substring(2, 8)}`;
27034
+ const executionId = `exec_${Date.now().toString(36)}${randomBytes34(4).toString("hex")}`;
25611
27035
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
25612
27036
  const execution = {
25613
27037
  id: executionId,
@@ -25770,7 +27194,7 @@ CREATE INDEX IF NOT EXISTS idx_${executionsTable}_started ON ${executionsTable}(
25770
27194
  };
25771
27195
 
25772
27196
  // src/adapters/webhook/HttpWebhook.ts
25773
- import { createHmac as createHmac2, timingSafeEqual } from "crypto";
27197
+ import { createHmac as createHmac4, timingSafeEqual as timingSafeEqual2, randomBytes as randomBytes35 } from "crypto";
25774
27198
  var HttpWebhook = class {
25775
27199
  db;
25776
27200
  queue;
@@ -26112,14 +27536,14 @@ var HttpWebhook = class {
26112
27536
  config.secret,
26113
27537
  algorithm
26114
27538
  );
26115
- const providedSig = signature.replace(/^(sha256=|sha512=|sha1=)/, "");
27539
+ const providedSig = signature.replace(/^(sha256=|sha512=)/, "");
26116
27540
  try {
26117
27541
  const providedBuffer = Buffer.from(providedSig, "hex");
26118
27542
  const expectedBuffer = Buffer.from(expectedSignature, "hex");
26119
27543
  if (providedBuffer.length !== expectedBuffer.length) {
26120
27544
  return { valid: false, error: "Invalid signature" };
26121
27545
  }
26122
- if (!timingSafeEqual(providedBuffer, expectedBuffer)) {
27546
+ if (!timingSafeEqual2(providedBuffer, expectedBuffer)) {
26123
27547
  return { valid: false, error: "Invalid signature" };
26124
27548
  }
26125
27549
  } catch {
@@ -26368,7 +27792,7 @@ CREATE INDEX IF NOT EXISTS idx_${attemptsTable}_delivery ON ${attemptsTable}(del
26368
27792
  await this.saveDelivery(delivery);
26369
27793
  }
26370
27794
  async executeDelivery(endpoint, event, attemptNumber) {
26371
- const attemptId = `att_${Date.now().toString(36)}${Math.random().toString(36).substring(2, 8)}`;
27795
+ const attemptId = `att_${Date.now().toString(36)}${randomBytes35(4).toString("hex")}`;
26372
27796
  const startTime = Date.now();
26373
27797
  const payloadStr = JSON.stringify(event);
26374
27798
  const signature = this.computeSignature(
@@ -26472,7 +27896,7 @@ CREATE INDEX IF NOT EXISTS idx_${attemptsTable}_delivery ON ${attemptsTable}(del
26472
27896
  await this.saveEndpoint(endpoint);
26473
27897
  }
26474
27898
  computeSignature(payload, secret, algorithm) {
26475
- return createHmac2(algorithm, secret).update(payload).digest("hex");
27899
+ return createHmac4(algorithm, secret).update(payload).digest("hex");
26476
27900
  }
26477
27901
  endpointToRow(endpoint) {
26478
27902
  return {
@@ -27794,6 +29218,9 @@ init_PineconeRAG();
27794
29218
  // src/adapters/weaviate/index.ts
27795
29219
  init_WeaviateRAG();
27796
29220
 
29221
+ // src/index.ts
29222
+ init_NodeCrypto();
29223
+
27797
29224
  // src/adapters/oidc/GenericOIDCAuthSSO.ts
27798
29225
  function generateRandomString(length) {
27799
29226
  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -28387,6 +29814,7 @@ var GenericOIDCAuthSSO = class {
28387
29814
  };
28388
29815
 
28389
29816
  // src/adapters/postgres-tenant/PostgresTenant.ts
29817
+ import { randomBytes as randomBytes36 } from "crypto";
28390
29818
  var tenantContextMap = /* @__PURE__ */ new Map();
28391
29819
  var contextIdCounter2 = 0;
28392
29820
  var currentContextId2 = null;
@@ -29168,7 +30596,273 @@ var PostgresTenant = class {
29168
30596
  }
29169
30597
  };
29170
30598
  function generateId2() {
29171
- return Math.random().toString(36).substring(2) + Date.now().toString(36);
30599
+ return randomBytes36(8).toString("hex") + Date.now().toString(36);
30600
+ }
30601
+
30602
+ // src/env.ts
30603
+ function getRequiredEnv(key) {
30604
+ const value = process.env[key];
30605
+ if (!value) {
30606
+ throw new Error(`Missing required environment variable: ${key}`);
30607
+ }
30608
+ return value;
30609
+ }
30610
+ function getOptionalEnv(key, defaultValue) {
30611
+ return process.env[key] || defaultValue;
30612
+ }
30613
+ function getBoolEnv(key, defaultValue = false) {
30614
+ const value = process.env[key];
30615
+ if (value === void 0 || value === "") return defaultValue;
30616
+ return value === "true" || value === "1";
30617
+ }
30618
+ function getIntEnv(key, defaultValue) {
30619
+ const value = process.env[key];
30620
+ if (value === void 0 || value === "") return defaultValue;
30621
+ const parsed = parseInt(value, 10);
30622
+ return isNaN(parsed) ? defaultValue : parsed;
30623
+ }
30624
+ function validateEnvVars(config) {
30625
+ const result = checkEnvVars(config);
30626
+ if (!result.valid) {
30627
+ const lines = [];
30628
+ if (result.missing.length > 0) {
30629
+ lines.push(
30630
+ "Missing required environment variables:",
30631
+ ...result.missing.map((v) => ` - ${v}`)
30632
+ );
30633
+ }
30634
+ if (result.missingOneOf.length > 0) {
30635
+ for (const group of result.missingOneOf) {
30636
+ lines.push(`Missing one of: ${group.join(" | ")}`);
30637
+ }
30638
+ }
30639
+ if (result.invalid.length > 0) {
30640
+ lines.push(
30641
+ "Invalid environment variables:",
30642
+ ...result.invalid.map((v) => ` - ${v.key}: ${v.reason}`)
30643
+ );
30644
+ }
30645
+ throw new Error(lines.join("\n"));
30646
+ }
30647
+ }
30648
+ function checkEnvVars(config) {
30649
+ const missing = [];
30650
+ const invalid = [];
30651
+ const missingOneOf = [];
30652
+ if (config.required) {
30653
+ for (const key of config.required) {
30654
+ if (!process.env[key]) {
30655
+ missing.push(key);
30656
+ }
30657
+ }
30658
+ }
30659
+ if (config.requireOneOf) {
30660
+ for (const group of config.requireOneOf) {
30661
+ const hasAny = group.some((key) => !!process.env[key]);
30662
+ if (!hasAny) {
30663
+ missingOneOf.push(group);
30664
+ }
30665
+ }
30666
+ }
30667
+ if (config.validators) {
30668
+ for (const [key, validator] of Object.entries(config.validators)) {
30669
+ const value = process.env[key];
30670
+ if (value) {
30671
+ const result = validator(value);
30672
+ if (result !== true) {
30673
+ invalid.push({ key, reason: result });
30674
+ }
30675
+ }
30676
+ }
30677
+ }
30678
+ return {
30679
+ valid: missing.length === 0 && invalid.length === 0 && missingOneOf.length === 0,
30680
+ missing,
30681
+ invalid,
30682
+ missingOneOf
30683
+ };
30684
+ }
30685
+ function getEnvSummary(keys) {
30686
+ const summary = {};
30687
+ for (const key of keys) {
30688
+ summary[key] = !!process.env[key];
30689
+ }
30690
+ return summary;
30691
+ }
30692
+
30693
+ // src/app-logger.ts
30694
+ var LEVEL_PRIORITY2 = {
30695
+ debug: 0,
30696
+ info: 1,
30697
+ warn: 2,
30698
+ error: 3
30699
+ };
30700
+ function defaultOutput(level, message, context) {
30701
+ const isProduction = process.env.NODE_ENV === "production";
30702
+ if (isProduction) {
30703
+ const entry = { level, message, ...context };
30704
+ const method = level === "error" ? "error" : level === "warn" ? "warn" : "log";
30705
+ console[method](JSON.stringify(entry));
30706
+ } else {
30707
+ const prefix = `[${level.toUpperCase()}]`;
30708
+ const ctx = Object.keys(context).length > 0 ? " " + JSON.stringify(context) : "";
30709
+ const method = level === "error" ? "error" : level === "warn" ? "warn" : level === "debug" ? "debug" : "log";
30710
+ console[method](`${prefix} ${message}${ctx}`);
30711
+ }
30712
+ }
30713
+ var AppLoggerImpl = class _AppLoggerImpl {
30714
+ baseContext;
30715
+ minLevelPriority;
30716
+ outputFn;
30717
+ onErrorFn;
30718
+ constructor(baseContext, options) {
30719
+ this.baseContext = baseContext;
30720
+ this.minLevelPriority = LEVEL_PRIORITY2[options.minLevel] ?? 0;
30721
+ this.outputFn = options.output;
30722
+ this.onErrorFn = options.onError;
30723
+ }
30724
+ log(level, message, context) {
30725
+ if ((LEVEL_PRIORITY2[level] ?? 0) < this.minLevelPriority) return;
30726
+ const merged = {
30727
+ ...this.baseContext,
30728
+ ...context,
30729
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
30730
+ };
30731
+ this.outputFn(level, message, merged);
30732
+ }
30733
+ debug(message, context) {
30734
+ this.log("debug", message, context);
30735
+ }
30736
+ info(message, context) {
30737
+ this.log("info", message, context);
30738
+ }
30739
+ warn(message, context) {
30740
+ this.log("warn", message, context);
30741
+ }
30742
+ error(message, context) {
30743
+ this.log("error", message, context);
30744
+ if (this.onErrorFn) {
30745
+ try {
30746
+ this.onErrorFn(message, { ...this.baseContext, ...context });
30747
+ } catch {
30748
+ }
30749
+ }
30750
+ }
30751
+ child(context) {
30752
+ return new _AppLoggerImpl(
30753
+ { ...this.baseContext, ...context },
30754
+ {
30755
+ minLevel: Object.entries(LEVEL_PRIORITY2).find(
30756
+ ([, v]) => v === this.minLevelPriority
30757
+ )?.[0] ?? "debug",
30758
+ output: this.outputFn,
30759
+ onError: this.onErrorFn
30760
+ }
30761
+ );
30762
+ }
30763
+ forRequest(request, operation) {
30764
+ const requestId = request.headers.get("x-request-id") ?? request.headers.get("x-correlation-id") ?? crypto.randomUUID();
30765
+ let path;
30766
+ try {
30767
+ path = new URL(request.url).pathname;
30768
+ } catch {
30769
+ path = request.url;
30770
+ }
30771
+ return this.child({
30772
+ requestId,
30773
+ operation,
30774
+ method: request.method,
30775
+ path
30776
+ });
30777
+ }
30778
+ forJob(jobType, jobId, context) {
30779
+ return this.child({ jobType, jobId, ...context });
30780
+ }
30781
+ async timed(operation, fn, context) {
30782
+ const opLogger = this.child({ operation, ...context });
30783
+ opLogger.debug("Operation started");
30784
+ const start = Date.now();
30785
+ try {
30786
+ const result = await fn();
30787
+ opLogger.info("Operation completed", {
30788
+ durationMs: Date.now() - start
30789
+ });
30790
+ return result;
30791
+ } catch (error) {
30792
+ opLogger.error("Operation failed", {
30793
+ durationMs: Date.now() - start,
30794
+ error: error instanceof Error ? error.message : String(error)
30795
+ });
30796
+ throw error;
30797
+ }
30798
+ }
30799
+ };
30800
+ function createAppLogger(options) {
30801
+ const {
30802
+ service,
30803
+ minLevel = process.env.NODE_ENV === "production" ? "info" : "debug",
30804
+ output = defaultOutput,
30805
+ onError
30806
+ } = options;
30807
+ return new AppLoggerImpl({ service }, { minLevel, output, onError });
30808
+ }
30809
+
30810
+ // src/redis-client.ts
30811
+ import Redis from "ioredis";
30812
+ function createRedisClient(options) {
30813
+ const {
30814
+ url,
30815
+ keyPrefix,
30816
+ maxRetries = 3,
30817
+ lazyConnect = true,
30818
+ silent = false
30819
+ } = options;
30820
+ const logger = options.logger ?? {
30821
+ error: console.error
30822
+ };
30823
+ const client = new Redis(url, {
30824
+ keyPrefix,
30825
+ maxRetriesPerRequest: maxRetries,
30826
+ retryStrategy(times) {
30827
+ if (times > maxRetries) return null;
30828
+ return Math.min(times * 200, 2e3);
30829
+ },
30830
+ lazyConnect
30831
+ });
30832
+ if (!silent) {
30833
+ client.on("error", (err) => {
30834
+ logger.error("[redis] Connection error", { message: err.message });
30835
+ });
30836
+ if (logger.info) {
30837
+ const logInfo = logger.info;
30838
+ client.on("connect", () => {
30839
+ logInfo("[redis] Connected");
30840
+ });
30841
+ }
30842
+ }
30843
+ if (lazyConnect) {
30844
+ client.connect().catch(() => {
30845
+ });
30846
+ }
30847
+ return client;
30848
+ }
30849
+ var sharedClient = null;
30850
+ function getSharedRedis() {
30851
+ if (sharedClient) return sharedClient;
30852
+ const url = process.env.REDIS_URL;
30853
+ if (!url) return null;
30854
+ sharedClient = createRedisClient({
30855
+ url,
30856
+ keyPrefix: process.env.REDIS_KEY_PREFIX,
30857
+ silent: process.env.NODE_ENV === "test"
30858
+ });
30859
+ return sharedClient;
30860
+ }
30861
+ async function closeSharedRedis() {
30862
+ if (sharedClient) {
30863
+ await sharedClient.quit();
30864
+ sharedClient = null;
30865
+ }
29172
30866
  }
29173
30867
 
29174
30868
  // src/migrations/Migrator.ts
@@ -29947,9 +31641,11 @@ export {
29947
31641
  CircuitBreakerRegistry,
29948
31642
  CircuitOpenError,
29949
31643
  CommonApiErrors,
31644
+ CommonRateLimits,
29950
31645
  ConsoleEmail,
29951
31646
  ConsoleLogger,
29952
31647
  CronPresets,
31648
+ CryptoConfigSchema,
29953
31649
  DEFAULT_BULKHEAD_OPTIONS,
29954
31650
  DEFAULT_CIRCUIT_BREAKER_OPTIONS,
29955
31651
  DEFAULT_RETRY_OPTIONS,
@@ -29962,17 +31658,21 @@ export {
29962
31658
  DatabaseNotification,
29963
31659
  DatabasePromptStore,
29964
31660
  DatabaseProviderSchema,
31661
+ DateRangeSchema,
29965
31662
  DefaultTimeouts,
29966
31663
  EmailConfigSchema,
29967
31664
  EmailProviderSchema,
31665
+ EmailSchema,
29968
31666
  EnvSecrets,
29969
31667
  FallbackStrategies,
29970
31668
  GenericOIDCAuthSSO,
29971
31669
  GoogleAIAdapter,
29972
31670
  HTML_TAG_PATTERN,
29973
31671
  HttpWebhook,
31672
+ KEYCLOAK_DEFAULT_ROLES,
29974
31673
  LogLevelSchema,
29975
31674
  LoggingConfigSchema,
31675
+ LoginSchema,
29976
31676
  MemoryAI,
29977
31677
  MemoryAIUsage,
29978
31678
  MemoryAuditLog,
@@ -29981,6 +31681,7 @@ export {
29981
31681
  MemoryBilling,
29982
31682
  MemoryCache,
29983
31683
  MemoryCompliance,
31684
+ MemoryCrypto,
29984
31685
  MemoryDatabase,
29985
31686
  MemoryDevPortal,
29986
31687
  MemoryDevice,
@@ -30002,6 +31703,7 @@ export {
30002
31703
  MetricsConfigSchema,
30003
31704
  MiddlewareConfigSchema,
30004
31705
  Migrator,
31706
+ NodeCrypto,
30005
31707
  NoopLogger,
30006
31708
  NoopMetrics,
30007
31709
  NoopTracing,
@@ -30009,7 +31711,11 @@ export {
30009
31711
  ObservabilityConfigSchema,
30010
31712
  OpenAIAdapter,
30011
31713
  PG_ERROR_MAP,
31714
+ PaginationSchema,
31715
+ PasswordSchema,
30012
31716
  PaymentErrorMessages,
31717
+ PersonNameSchema,
31718
+ PhoneSchema,
30013
31719
  PineconeRAG,
30014
31720
  PlatformConfigSchema,
30015
31721
  PostgresDatabase,
@@ -30029,7 +31735,14 @@ export {
30029
31735
  RetryPredicates,
30030
31736
  S3Storage,
30031
31737
  SQL,
31738
+ SearchQuerySchema,
31739
+ SecurityConfigSchema,
31740
+ SecurityHeaderPresets,
31741
+ SignupSchema,
31742
+ SlugSchema,
30032
31743
  SmtpEmail,
31744
+ StandardAuditActions,
31745
+ StandardRateLimitPresets,
30033
31746
  StorageConfigSchema,
30034
31747
  StorageProviderSchema,
30035
31748
  StripePayment,
@@ -30045,16 +31758,32 @@ export {
30045
31758
  UpstashCache,
30046
31759
  WeaviateRAG,
30047
31760
  WebhookEventTypes,
31761
+ WrapperPresets,
31762
+ buildAllowlist,
31763
+ buildAuthCookies,
31764
+ buildErrorBody,
31765
+ buildKeycloakCallbacks,
30048
31766
  buildPagination,
31767
+ buildRateLimitHeaders,
31768
+ buildRateLimitResponseHeaders,
31769
+ buildRedirectCallback,
31770
+ buildTokenRefreshParams,
30049
31771
  calculateBackoff,
30050
31772
  calculateRetryDelay,
31773
+ checkEnvVars,
31774
+ checkRateLimit,
30051
31775
  classifyError,
31776
+ closeSharedRedis,
30052
31777
  composeHookRegistries,
31778
+ constantTimeEqual,
30053
31779
  containsHtml,
30054
31780
  containsUrls,
30055
31781
  correlationContext,
30056
31782
  createAIError,
30057
31783
  createAnthropicAdapter,
31784
+ createAppLogger,
31785
+ createAuditActor,
31786
+ createAuditLogger,
30058
31787
  createAuthError,
30059
31788
  createBulkhead,
30060
31789
  createCacheMiddleware,
@@ -30065,6 +31794,7 @@ export {
30065
31794
  createErrorReport,
30066
31795
  createExpressHealthHandlers,
30067
31796
  createExpressMetricsHandler,
31797
+ createFeatureFlags,
30068
31798
  createGoogleAIAdapter,
30069
31799
  createHealthEndpoints,
30070
31800
  createHealthServer,
@@ -30072,6 +31802,7 @@ export {
30072
31802
  createIpKeyGenerator,
30073
31803
  createJobContext,
30074
31804
  createLoggingMiddleware,
31805
+ createMemoryRateLimitStore,
30075
31806
  createMetricsEndpoint,
30076
31807
  createMetricsMiddleware,
30077
31808
  createMetricsServer,
@@ -30085,8 +31816,10 @@ export {
30085
31816
  createPlatform,
30086
31817
  createPlatformAsync,
30087
31818
  createRateLimitMiddleware,
31819
+ createRedisClient,
30088
31820
  createRequestContext,
30089
31821
  createRequestIdMiddleware,
31822
+ createSafeTextSchema,
30090
31823
  createScopedMetrics,
30091
31824
  createSlowQueryMiddleware,
30092
31825
  createSsoOidcConfigsTable,
@@ -30103,8 +31836,13 @@ export {
30103
31836
  defangUrl,
30104
31837
  defineMigration,
30105
31838
  describeCron,
31839
+ detectStage,
30106
31840
  enterpriseMigrations,
30107
31841
  escapeHtml,
31842
+ extractAuditIp,
31843
+ extractAuditRequestId,
31844
+ extractAuditUserAgent,
31845
+ extractClientIp,
30108
31846
  filterChannelsByPreferences,
30109
31847
  formatAmount,
30110
31848
  generateAuditId,
@@ -30118,40 +31856,62 @@ export {
30118
31856
  generatePaymentId,
30119
31857
  generateScheduleId,
30120
31858
  generateSecureToken,
31859
+ generateSecurityHeaders,
30121
31860
  generateVersion,
30122
31861
  generateWebhookId,
30123
31862
  generateWebhookSecret,
31863
+ getBoolEnv,
30124
31864
  getContext,
30125
- getCorrelationId,
31865
+ getCorrelationId2 as getCorrelationId,
30126
31866
  getDefaultConfig,
31867
+ getEndSessionEndpoint,
30127
31868
  getEnterpriseMigrations,
31869
+ getEnvSummary,
31870
+ getIntEnv,
30128
31871
  getLogMeta,
30129
31872
  getNextCronRun,
31873
+ getOptionalEnv,
31874
+ getRateLimitStatus,
30130
31875
  getRequestId,
31876
+ getRequiredEnv,
31877
+ getSharedRedis,
30131
31878
  getTenantId,
31879
+ getTokenEndpoint,
30132
31880
  getTraceId,
30133
31881
  getUserId,
31882
+ hasAllRoles,
31883
+ hasAnyRole,
31884
+ hasRole,
30134
31885
  isAIError,
31886
+ isAllowlisted,
30135
31887
  isApiError,
30136
31888
  isAuthError,
30137
31889
  isInContext,
30138
31890
  isInQuietHours,
30139
31891
  isPaymentError,
31892
+ isTokenExpired,
30140
31893
  isValidCron,
30141
31894
  loadConfig,
30142
31895
  matchAction,
30143
31896
  matchEventType,
31897
+ parseKeycloakRoles,
30144
31898
  raceTimeout,
31899
+ refreshKeycloakToken,
31900
+ resetRateLimitForKey,
31901
+ resolveIdentifier,
31902
+ resolveRateLimitIdentifier,
30145
31903
  retryable,
30146
31904
  runWithContext,
30147
31905
  runWithContextAsync,
30148
31906
  safeValidateConfig,
31907
+ sanitizeApiError,
30149
31908
  sanitizeForEmail,
30150
31909
  sqlMigration,
30151
31910
  stripHtml,
30152
31911
  timedHealthCheck,
30153
31912
  toHealthCheckResult,
30154
31913
  validateConfig,
31914
+ validateEnvVars,
30155
31915
  withCorrelation,
30156
31916
  withCorrelationAsync,
30157
31917
  withFallback,