@cipherstash/stack 0.15.1 → 0.15.3

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.cjs CHANGED
@@ -387,8 +387,305 @@ var EncryptionErrorTypes = {
387
387
  CtsTokenError: "CtsTokenError"
388
388
  };
389
389
 
390
+ // ../../node_modules/.pnpm/evlog@1.9.0/node_modules/evlog/dist/utils.mjs
391
+ function formatDuration(ms) {
392
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
393
+ return `${(ms / 1e3).toFixed(2)}s`;
394
+ }
395
+ function isDev() {
396
+ if (typeof process !== "undefined") return process.env.NODE_ENV !== "production";
397
+ if (typeof window !== "undefined") return true;
398
+ return false;
399
+ }
400
+ function detectEnvironment() {
401
+ const env = typeof process !== "undefined" ? process.env : {};
402
+ const defaultEnvironment = isDev() ? "development" : "production";
403
+ return {
404
+ environment: env.NODE_ENV || defaultEnvironment,
405
+ service: env.SERVICE_NAME || "app",
406
+ version: env.APP_VERSION,
407
+ commitHash: env.COMMIT_SHA || env.GITHUB_SHA || env.VERCEL_GIT_COMMIT_SHA || env.CF_PAGES_COMMIT_SHA,
408
+ region: env.VERCEL_REGION || env.AWS_REGION || env.FLY_REGION || env.CF_REGION
409
+ };
410
+ }
411
+ function getConsoleMethod(level) {
412
+ return level;
413
+ }
414
+ var colors = {
415
+ reset: "\x1B[0m",
416
+ bold: "\x1B[1m",
417
+ dim: "\x1B[2m",
418
+ red: "\x1B[31m",
419
+ green: "\x1B[32m",
420
+ yellow: "\x1B[33m",
421
+ blue: "\x1B[34m",
422
+ magenta: "\x1B[35m",
423
+ cyan: "\x1B[36m",
424
+ white: "\x1B[37m",
425
+ gray: "\x1B[90m"
426
+ };
427
+ function getLevelColor(level) {
428
+ switch (level) {
429
+ case "error":
430
+ return colors.red;
431
+ case "warn":
432
+ return colors.yellow;
433
+ case "info":
434
+ return colors.cyan;
435
+ case "debug":
436
+ return colors.gray;
437
+ default:
438
+ return colors.white;
439
+ }
440
+ }
441
+ function matchesPattern(path, pattern) {
442
+ const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/{{GLOBSTAR}}/g, ".*").replace(/\?/g, "[^/]");
443
+ return new RegExp(`^${regexPattern}$`).test(path);
444
+ }
445
+
446
+ // ../../node_modules/.pnpm/evlog@1.9.0/node_modules/evlog/dist/logger.mjs
447
+ function isPlainObject(val) {
448
+ return val !== null && typeof val === "object" && !Array.isArray(val);
449
+ }
450
+ function deepDefaults(base, defaults) {
451
+ const result = { ...base };
452
+ for (const key in defaults) {
453
+ const baseVal = result[key];
454
+ const defaultVal = defaults[key];
455
+ if (baseVal === void 0 || baseVal === null) result[key] = defaultVal;
456
+ else if (isPlainObject(baseVal) && isPlainObject(defaultVal)) result[key] = deepDefaults(baseVal, defaultVal);
457
+ }
458
+ return result;
459
+ }
460
+ var globalEnv = {
461
+ service: "app",
462
+ environment: "development"
463
+ };
464
+ var globalPretty = isDev();
465
+ var globalSampling = {};
466
+ var globalStringify = true;
467
+ var globalDrain;
468
+ var globalEnabled = true;
469
+ function initLogger(config = {}) {
470
+ globalEnabled = config.enabled ?? true;
471
+ const detected = detectEnvironment();
472
+ globalEnv = {
473
+ service: config.env?.service ?? detected.service ?? "app",
474
+ environment: config.env?.environment ?? detected.environment ?? "development",
475
+ version: config.env?.version ?? detected.version,
476
+ commitHash: config.env?.commitHash ?? detected.commitHash,
477
+ region: config.env?.region ?? detected.region
478
+ };
479
+ globalPretty = config.pretty ?? isDev();
480
+ globalSampling = config.sampling ?? {};
481
+ globalStringify = config.stringify ?? true;
482
+ globalDrain = config.drain;
483
+ }
484
+ function shouldSample(level) {
485
+ const { rates } = globalSampling;
486
+ if (!rates) return true;
487
+ const percentage = level === "error" && rates.error === void 0 ? 100 : rates[level] ?? 100;
488
+ if (percentage <= 0) return false;
489
+ if (percentage >= 100) return true;
490
+ return Math.random() * 100 < percentage;
491
+ }
492
+ function shouldKeep(ctx) {
493
+ const { keep } = globalSampling;
494
+ if (!keep?.length) return false;
495
+ return keep.some((condition) => {
496
+ if (condition.status !== void 0 && ctx.status !== void 0 && ctx.status >= condition.status) return true;
497
+ if (condition.duration !== void 0 && ctx.duration !== void 0 && ctx.duration >= condition.duration) return true;
498
+ if (condition.path && ctx.path && matchesPattern(ctx.path, condition.path)) return true;
499
+ return false;
500
+ });
501
+ }
502
+ function emitWideEvent(level, event, skipSamplingCheck = false) {
503
+ if (!globalEnabled) return null;
504
+ if (!skipSamplingCheck && !shouldSample(level)) return null;
505
+ const formatted = {
506
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
507
+ level,
508
+ ...globalEnv,
509
+ ...event
510
+ };
511
+ if (globalPretty) prettyPrintWideEvent(formatted);
512
+ else if (globalStringify) console[getConsoleMethod(level)](JSON.stringify(formatted));
513
+ else console[getConsoleMethod(level)](formatted);
514
+ if (globalDrain) Promise.resolve(globalDrain({ event: formatted })).catch((err) => {
515
+ console.error("[evlog] drain failed:", err);
516
+ });
517
+ return formatted;
518
+ }
519
+ function emitTaggedLog(level, tag, message) {
520
+ if (!globalEnabled) return;
521
+ if (globalPretty) {
522
+ if (!shouldSample(level)) return;
523
+ const color = getLevelColor(level);
524
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
525
+ console.log(`${colors.dim}${timestamp}${colors.reset} ${color}[${tag}]${colors.reset} ${message}`);
526
+ return;
527
+ }
528
+ emitWideEvent(level, {
529
+ tag,
530
+ message
531
+ });
532
+ }
533
+ function formatValue(value) {
534
+ if (value === null || value === void 0) return String(value);
535
+ if (typeof value === "object") {
536
+ const pairs = [];
537
+ for (const [k, v] of Object.entries(value)) if (v !== void 0 && v !== null) if (typeof v === "object") pairs.push(`${k}=${JSON.stringify(v)}`);
538
+ else pairs.push(`${k}=${v}`);
539
+ return pairs.join(" ");
540
+ }
541
+ return String(value);
542
+ }
543
+ function prettyPrintWideEvent(event) {
544
+ const { timestamp, level, service, environment, version, ...rest } = event;
545
+ const levelColor = getLevelColor(level);
546
+ const ts = timestamp.slice(11, 23);
547
+ let header = `${colors.dim}${ts}${colors.reset} ${levelColor}${level.toUpperCase()}${colors.reset}`;
548
+ header += ` ${colors.cyan}[${service}]${colors.reset}`;
549
+ if (rest.method && rest.path) {
550
+ header += ` ${rest.method} ${rest.path}`;
551
+ delete rest.method;
552
+ delete rest.path;
553
+ }
554
+ if (rest.status) {
555
+ const statusColor = rest.status >= 400 ? colors.red : colors.green;
556
+ header += ` ${statusColor}${rest.status}${colors.reset}`;
557
+ delete rest.status;
558
+ }
559
+ if (rest.duration) {
560
+ header += ` ${colors.dim}in ${rest.duration}${colors.reset}`;
561
+ delete rest.duration;
562
+ }
563
+ console.log(header);
564
+ const entries = Object.entries(rest).filter(([_, v]) => v !== void 0);
565
+ const lastIndex = entries.length - 1;
566
+ entries.forEach(([key, value], index) => {
567
+ const prefix = index === lastIndex ? "\u2514\u2500" : "\u251C\u2500";
568
+ const formatted = formatValue(value);
569
+ console.log(` ${colors.dim}${prefix}${colors.reset} ${colors.cyan}${key}:${colors.reset} ${formatted}`);
570
+ });
571
+ }
572
+ function createLogMethod(level) {
573
+ return function logMethod(tagOrEvent, message) {
574
+ if (typeof tagOrEvent === "string" && message !== void 0) emitTaggedLog(level, tagOrEvent, message);
575
+ else if (typeof tagOrEvent === "object") emitWideEvent(level, tagOrEvent);
576
+ else emitTaggedLog(level, "log", String(tagOrEvent));
577
+ };
578
+ }
579
+ var _log = {
580
+ info: createLogMethod("info"),
581
+ error: createLogMethod("error"),
582
+ warn: createLogMethod("warn"),
583
+ debug: createLogMethod("debug")
584
+ };
585
+ var noopLogger = {
586
+ set() {
587
+ },
588
+ error() {
589
+ },
590
+ info() {
591
+ },
592
+ warn() {
593
+ },
594
+ emit() {
595
+ return null;
596
+ },
597
+ getContext() {
598
+ return {};
599
+ }
600
+ };
601
+ function createRequestLogger(options = {}) {
602
+ if (!globalEnabled) return noopLogger;
603
+ const startTime = Date.now();
604
+ let context = {
605
+ method: options.method,
606
+ path: options.path,
607
+ requestId: options.requestId
608
+ };
609
+ let hasError = false;
610
+ let hasWarn = false;
611
+ function addRequestLog(level, message) {
612
+ const entry = {
613
+ level,
614
+ message,
615
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
616
+ };
617
+ const requestLogs = Array.isArray(context.requestLogs) ? [...context.requestLogs, entry] : [entry];
618
+ context = {
619
+ ...context,
620
+ requestLogs
621
+ };
622
+ }
623
+ return {
624
+ set(data) {
625
+ context = deepDefaults(data, context);
626
+ },
627
+ error(error, errorContext) {
628
+ hasError = true;
629
+ const err = typeof error === "string" ? new Error(error) : error;
630
+ context = deepDefaults({
631
+ ...errorContext,
632
+ error: {
633
+ name: err.name,
634
+ message: err.message,
635
+ stack: err.stack,
636
+ ..."status" in err && { status: err.status },
637
+ ..."statusText" in err && { statusText: err.statusText },
638
+ ..."statusCode" in err && { statusCode: err.statusCode },
639
+ ..."statusMessage" in err && { statusMessage: err.statusMessage },
640
+ ..."data" in err && { data: err.data },
641
+ ..."cause" in err && { cause: err.cause }
642
+ }
643
+ }, context);
644
+ },
645
+ info(message, infoContext) {
646
+ addRequestLog("info", message);
647
+ if (infoContext) {
648
+ const { requestLogs: _, ...rest } = infoContext;
649
+ context = deepDefaults(rest, context);
650
+ }
651
+ },
652
+ warn(message, warnContext) {
653
+ hasWarn = true;
654
+ addRequestLog("warn", message);
655
+ if (warnContext) {
656
+ const { requestLogs: _, ...rest } = warnContext;
657
+ context = deepDefaults(rest, context);
658
+ }
659
+ },
660
+ emit(overrides) {
661
+ const durationMs = Date.now() - startTime;
662
+ const duration = formatDuration(durationMs);
663
+ const level = hasError ? "error" : hasWarn ? "warn" : "info";
664
+ const { _forceKeep, ...restOverrides } = overrides ?? {};
665
+ const tailCtx = {
666
+ status: context.status ?? restOverrides.status,
667
+ duration: durationMs,
668
+ path: context.path,
669
+ method: context.method,
670
+ context: {
671
+ ...context,
672
+ ...restOverrides
673
+ }
674
+ };
675
+ if (!(_forceKeep || shouldKeep(tailCtx)) && !shouldSample(level)) return null;
676
+ return emitWideEvent(level, {
677
+ ...context,
678
+ ...restOverrides,
679
+ duration
680
+ }, true);
681
+ },
682
+ getContext() {
683
+ return { ...context };
684
+ }
685
+ };
686
+ }
687
+
390
688
  // src/utils/logger/index.ts
391
- var import_evlog = require("evlog");
392
689
  var validLevels = ["debug", "info", "error"];
393
690
  function levelFromEnv() {
394
691
  const env = process.env.STASH_STACK_LOG;
@@ -412,7 +709,7 @@ function initStackLogger() {
412
709
  initialized = true;
413
710
  const level = levelFromEnv();
414
711
  const rates = samplingRatesForLevel(level);
415
- (0, import_evlog.initLogger)({
712
+ initLogger({
416
713
  env: { service: "@cipherstash/stack" },
417
714
  enabled: true,
418
715
  sampling: { rates }
@@ -424,7 +721,7 @@ function safeMessage(args) {
424
721
  }
425
722
  var logger = {
426
723
  debug(...args) {
427
- const log = (0, import_evlog.createRequestLogger)();
724
+ const log = createRequestLogger();
428
725
  log.set({
429
726
  level: "debug",
430
727
  source: "@cipherstash/stack",
@@ -433,18 +730,18 @@ var logger = {
433
730
  log.emit();
434
731
  },
435
732
  info(...args) {
436
- const log = (0, import_evlog.createRequestLogger)();
733
+ const log = createRequestLogger();
437
734
  log.set({ source: "@cipherstash/stack" });
438
735
  log.info(safeMessage(args));
439
736
  log.emit();
440
737
  },
441
738
  warn(...args) {
442
- const log = (0, import_evlog.createRequestLogger)();
739
+ const log = createRequestLogger();
443
740
  log.warn(safeMessage(args));
444
741
  log.emit();
445
742
  },
446
743
  error(...args) {
447
- const log = (0, import_evlog.createRequestLogger)();
744
+ const log = createRequestLogger();
448
745
  log.error(safeMessage(args));
449
746
  log.emit();
450
747
  }
@@ -687,7 +984,7 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
687
984
  );
688
985
  }
689
986
  async execute() {
690
- const log = (0, import_evlog.createRequestLogger)();
987
+ const log = createRequestLogger();
691
988
  log.set({
692
989
  op: "batchEncryptQuery",
693
990
  count: this.terms.length,
@@ -732,7 +1029,7 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
732
1029
  this.auditMetadata = auditMetadata;
733
1030
  }
734
1031
  async execute() {
735
- const log = (0, import_evlog.createRequestLogger)();
1032
+ const log = createRequestLogger();
736
1033
  log.set({
737
1034
  op: "batchEncryptQuery",
738
1035
  count: this.terms.length,
@@ -812,7 +1109,7 @@ var BulkDecryptOperation = class extends EncryptionOperation {
812
1109
  return new BulkDecryptOperationWithLockContext(this, lockContext);
813
1110
  }
814
1111
  async execute() {
815
- const log = (0, import_evlog.createRequestLogger)();
1112
+ const log = createRequestLogger();
816
1113
  log.set({
817
1114
  op: "bulkDecrypt",
818
1115
  count: this.encryptedPayloads?.length ?? 0,
@@ -864,7 +1161,7 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
864
1161
  }
865
1162
  async execute() {
866
1163
  const { client, encryptedPayloads } = this.operation.getOperation();
867
- const log = (0, import_evlog.createRequestLogger)();
1164
+ const log = createRequestLogger();
868
1165
  log.set({
869
1166
  op: "bulkDecrypt",
870
1167
  count: encryptedPayloads?.length ?? 0,
@@ -1435,7 +1732,7 @@ var BulkDecryptModelsOperation = class extends EncryptionOperation {
1435
1732
  return new BulkDecryptModelsOperationWithLockContext(this, lockContext);
1436
1733
  }
1437
1734
  async execute() {
1438
- const log = (0, import_evlog.createRequestLogger)();
1735
+ const log = createRequestLogger();
1439
1736
  log.set({
1440
1737
  op: "bulkDecryptModels",
1441
1738
  count: this.models.length,
@@ -1482,7 +1779,7 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
1482
1779
  }
1483
1780
  async execute() {
1484
1781
  const { client, models } = this.operation.getOperation();
1485
- const log = (0, import_evlog.createRequestLogger)();
1782
+ const log = createRequestLogger();
1486
1783
  log.set({
1487
1784
  op: "bulkDecryptModels",
1488
1785
  count: models.length,
@@ -1547,7 +1844,7 @@ var BulkEncryptOperation = class extends EncryptionOperation {
1547
1844
  return new BulkEncryptOperationWithLockContext(this, lockContext);
1548
1845
  }
1549
1846
  async execute() {
1550
- const log = (0, import_evlog.createRequestLogger)();
1847
+ const log = createRequestLogger();
1551
1848
  log.set({
1552
1849
  op: "bulkEncrypt",
1553
1850
  table: this.table.tableName,
@@ -1613,7 +1910,7 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
1613
1910
  }
1614
1911
  async execute() {
1615
1912
  const { client, plaintexts, column, table } = this.operation.getOperation();
1616
- const log = (0, import_evlog.createRequestLogger)();
1913
+ const log = createRequestLogger();
1617
1914
  log.set({
1618
1915
  op: "bulkEncrypt",
1619
1916
  table: table.tableName,
@@ -1680,7 +1977,7 @@ var BulkEncryptModelsOperation = class extends EncryptionOperation {
1680
1977
  return new BulkEncryptModelsOperationWithLockContext(this, lockContext);
1681
1978
  }
1682
1979
  async execute() {
1683
- const log = (0, import_evlog.createRequestLogger)();
1980
+ const log = createRequestLogger();
1684
1981
  log.set({
1685
1982
  op: "bulkEncryptModels",
1686
1983
  table: this.table.tableName,
@@ -1734,7 +2031,7 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
1734
2031
  }
1735
2032
  async execute() {
1736
2033
  const { client, models, table } = this.operation.getOperation();
1737
- const log = (0, import_evlog.createRequestLogger)();
2034
+ const log = createRequestLogger();
1738
2035
  log.set({
1739
2036
  op: "bulkEncryptModels",
1740
2037
  table: table.tableName,
@@ -1788,7 +2085,7 @@ var DecryptOperation = class extends EncryptionOperation {
1788
2085
  return new DecryptOperationWithLockContext(this, lockContext);
1789
2086
  }
1790
2087
  async execute() {
1791
- const log = (0, import_evlog.createRequestLogger)();
2088
+ const log = createRequestLogger();
1792
2089
  log.set({
1793
2090
  op: "decrypt",
1794
2091
  lockContext: false
@@ -1837,7 +2134,7 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
1837
2134
  }
1838
2135
  }
1839
2136
  async execute() {
1840
- const log = (0, import_evlog.createRequestLogger)();
2137
+ const log = createRequestLogger();
1841
2138
  log.set({
1842
2139
  op: "decrypt",
1843
2140
  lockContext: true
@@ -1888,7 +2185,7 @@ var DecryptModelOperation = class extends EncryptionOperation {
1888
2185
  return new DecryptModelOperationWithLockContext(this, lockContext);
1889
2186
  }
1890
2187
  async execute() {
1891
- const log = (0, import_evlog.createRequestLogger)();
2188
+ const log = createRequestLogger();
1892
2189
  log.set({
1893
2190
  op: "decryptModel",
1894
2191
  lockContext: false
@@ -1933,7 +2230,7 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
1933
2230
  }
1934
2231
  }
1935
2232
  async execute() {
1936
- const log = (0, import_evlog.createRequestLogger)();
2233
+ const log = createRequestLogger();
1937
2234
  log.set({
1938
2235
  op: "decryptModel",
1939
2236
  lockContext: true
@@ -1989,7 +2286,7 @@ var EncryptOperation = class extends EncryptionOperation {
1989
2286
  return new EncryptOperationWithLockContext(this, lockContext);
1990
2287
  }
1991
2288
  async execute() {
1992
- const log = (0, import_evlog.createRequestLogger)();
2289
+ const log = createRequestLogger();
1993
2290
  log.set({
1994
2291
  op: "encrypt",
1995
2292
  table: this.table.tableName,
@@ -2050,7 +2347,7 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
2050
2347
  }
2051
2348
  async execute() {
2052
2349
  const { client, plaintext, column, table } = this.operation.getOperation();
2053
- const log = (0, import_evlog.createRequestLogger)();
2350
+ const log = createRequestLogger();
2054
2351
  log.set({
2055
2352
  op: "encrypt",
2056
2353
  table: table.tableName,
@@ -2106,7 +2403,7 @@ var EncryptModelOperation = class extends EncryptionOperation {
2106
2403
  return new EncryptModelOperationWithLockContext(this, lockContext);
2107
2404
  }
2108
2405
  async execute() {
2109
- const log = (0, import_evlog.createRequestLogger)();
2406
+ const log = createRequestLogger();
2110
2407
  log.set({
2111
2408
  op: "encryptModel",
2112
2409
  table: this.table.tableName,
@@ -2159,7 +2456,7 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
2159
2456
  }
2160
2457
  async execute() {
2161
2458
  const { client, model, table } = this.operation.getOperation();
2162
- const log = (0, import_evlog.createRequestLogger)();
2459
+ const log = createRequestLogger();
2163
2460
  log.set({
2164
2461
  op: "encryptModel",
2165
2462
  table: table.tableName,
@@ -2217,7 +2514,7 @@ var EncryptQueryOperation = class extends EncryptionOperation {
2217
2514
  );
2218
2515
  }
2219
2516
  async execute() {
2220
- const log = (0, import_evlog.createRequestLogger)();
2517
+ const log = createRequestLogger();
2221
2518
  log.set({
2222
2519
  op: "encryptQuery",
2223
2520
  table: this.opts.table.tableName,
@@ -2280,7 +2577,7 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
2280
2577
  this.auditMetadata = auditMetadata;
2281
2578
  }
2282
2579
  async execute() {
2283
- const log = (0, import_evlog.createRequestLogger)();
2580
+ const log = createRequestLogger();
2284
2581
  log.set({
2285
2582
  op: "encryptQuery",
2286
2583
  table: this.opts.table.tableName,