@scalemule/nextjs 0.1.17 → 0.1.19

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.
@@ -2,7 +2,7 @@ import { createMoneyClient } from '@scalemule/money';
2
2
  import { cookies, headers } from 'next/headers';
3
3
  import { NextResponse } from 'next/server';
4
4
  import { LedveryClient } from '@scalemule/ledvery';
5
- import { createHmac, timingSafeEqual, createHash } from 'crypto';
5
+ import { createHmac, timingSafeEqual } from 'crypto';
6
6
 
7
7
  var __create = Object.create;
8
8
  var __defProp = Object.defineProperty;
@@ -10,7 +10,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
10
  var __getOwnPropNames = Object.getOwnPropertyNames;
11
11
  var __getProtoOf = Object.getPrototypeOf;
12
12
  var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __commonJS = (cb, mod) => function __require() {
13
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
14
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
15
+ }) : x)(function(x) {
16
+ if (typeof require !== "undefined") return require.apply(this, arguments);
17
+ throw Error('Dynamic require of "' + x + '" is not supported');
18
+ });
19
+ var __commonJS = (cb, mod) => function __require2() {
14
20
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
21
  };
16
22
  var __copyProps = (to, from, except, desc) => {
@@ -26,13 +32,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
32
  // file that has been converted to a CommonJS file using a Babel-
27
33
  // compatible transform (i.e. "__esModule" has not been set), then set
28
34
  // "default" to the CommonJS "module.exports" for node compatibility.
29
- __defProp(target, "default", { value: mod, enumerable: true }) ,
35
+ !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
36
  mod
31
37
  ));
32
38
 
33
- // node_modules/semver/internal/constants.js
39
+ // ../sdk/node_modules/semver/internal/constants.js
34
40
  var require_constants = __commonJS({
35
- "node_modules/semver/internal/constants.js"(exports$1, module) {
41
+ "../sdk/node_modules/semver/internal/constants.js"(exports$1, module) {
36
42
  var SEMVER_SPEC_VERSION = "2.0.0";
37
43
  var MAX_LENGTH = 256;
38
44
  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */
@@ -61,18 +67,18 @@ var require_constants = __commonJS({
61
67
  }
62
68
  });
63
69
 
64
- // node_modules/semver/internal/debug.js
70
+ // ../sdk/node_modules/semver/internal/debug.js
65
71
  var require_debug = __commonJS({
66
- "node_modules/semver/internal/debug.js"(exports$1, module) {
72
+ "../sdk/node_modules/semver/internal/debug.js"(exports$1, module) {
67
73
  var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
68
74
  };
69
75
  module.exports = debug;
70
76
  }
71
77
  });
72
78
 
73
- // node_modules/semver/internal/re.js
79
+ // ../sdk/node_modules/semver/internal/re.js
74
80
  var require_re = __commonJS({
75
- "node_modules/semver/internal/re.js"(exports$1, module) {
81
+ "../sdk/node_modules/semver/internal/re.js"(exports$1, module) {
76
82
  var {
77
83
  MAX_SAFE_COMPONENT_LENGTH,
78
84
  MAX_SAFE_BUILD_LENGTH,
@@ -157,9 +163,9 @@ var require_re = __commonJS({
157
163
  }
158
164
  });
159
165
 
160
- // node_modules/semver/internal/parse-options.js
166
+ // ../sdk/node_modules/semver/internal/parse-options.js
161
167
  var require_parse_options = __commonJS({
162
- "node_modules/semver/internal/parse-options.js"(exports$1, module) {
168
+ "../sdk/node_modules/semver/internal/parse-options.js"(exports$1, module) {
163
169
  var looseOption = Object.freeze({ loose: true });
164
170
  var emptyOpts = Object.freeze({});
165
171
  var parseOptions = (options) => {
@@ -175,9 +181,9 @@ var require_parse_options = __commonJS({
175
181
  }
176
182
  });
177
183
 
178
- // node_modules/semver/internal/identifiers.js
184
+ // ../sdk/node_modules/semver/internal/identifiers.js
179
185
  var require_identifiers = __commonJS({
180
- "node_modules/semver/internal/identifiers.js"(exports$1, module) {
186
+ "../sdk/node_modules/semver/internal/identifiers.js"(exports$1, module) {
181
187
  var numeric = /^[0-9]+$/;
182
188
  var compareIdentifiers = (a, b) => {
183
189
  if (typeof a === "number" && typeof b === "number") {
@@ -199,9 +205,9 @@ var require_identifiers = __commonJS({
199
205
  }
200
206
  });
201
207
 
202
- // node_modules/semver/classes/semver.js
208
+ // ../sdk/node_modules/semver/classes/semver.js
203
209
  var require_semver = __commonJS({
204
- "node_modules/semver/classes/semver.js"(exports$1, module) {
210
+ "../sdk/node_modules/semver/classes/semver.js"(exports$1, module) {
205
211
  var debug = require_debug();
206
212
  var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
207
213
  var { safeRe: re, t } = require_re();
@@ -477,9 +483,9 @@ var require_semver = __commonJS({
477
483
  }
478
484
  });
479
485
 
480
- // node_modules/semver/functions/parse.js
486
+ // ../sdk/node_modules/semver/functions/parse.js
481
487
  var require_parse = __commonJS({
482
- "node_modules/semver/functions/parse.js"(exports$1, module) {
488
+ "../sdk/node_modules/semver/functions/parse.js"(exports$1, module) {
483
489
  var SemVer = require_semver();
484
490
  var parse = (version, options, throwErrors = false) => {
485
491
  if (version instanceof SemVer) {
@@ -498,9 +504,9 @@ var require_parse = __commonJS({
498
504
  }
499
505
  });
500
506
 
501
- // node_modules/semver/functions/valid.js
507
+ // ../sdk/node_modules/semver/functions/valid.js
502
508
  var require_valid = __commonJS({
503
- "node_modules/semver/functions/valid.js"(exports$1, module) {
509
+ "../sdk/node_modules/semver/functions/valid.js"(exports$1, module) {
504
510
  var parse = require_parse();
505
511
  var valid = (version, options) => {
506
512
  const v = parse(version, options);
@@ -510,9 +516,9 @@ var require_valid = __commonJS({
510
516
  }
511
517
  });
512
518
 
513
- // node_modules/semver/functions/clean.js
519
+ // ../sdk/node_modules/semver/functions/clean.js
514
520
  var require_clean = __commonJS({
515
- "node_modules/semver/functions/clean.js"(exports$1, module) {
521
+ "../sdk/node_modules/semver/functions/clean.js"(exports$1, module) {
516
522
  var parse = require_parse();
517
523
  var clean = (version, options) => {
518
524
  const s = parse(version.trim().replace(/^[=v]+/, ""), options);
@@ -522,9 +528,9 @@ var require_clean = __commonJS({
522
528
  }
523
529
  });
524
530
 
525
- // node_modules/semver/functions/inc.js
531
+ // ../sdk/node_modules/semver/functions/inc.js
526
532
  var require_inc = __commonJS({
527
- "node_modules/semver/functions/inc.js"(exports$1, module) {
533
+ "../sdk/node_modules/semver/functions/inc.js"(exports$1, module) {
528
534
  var SemVer = require_semver();
529
535
  var inc = (version, release, options, identifier, identifierBase) => {
530
536
  if (typeof options === "string") {
@@ -545,9 +551,9 @@ var require_inc = __commonJS({
545
551
  }
546
552
  });
547
553
 
548
- // node_modules/semver/functions/diff.js
554
+ // ../sdk/node_modules/semver/functions/diff.js
549
555
  var require_diff = __commonJS({
550
- "node_modules/semver/functions/diff.js"(exports$1, module) {
556
+ "../sdk/node_modules/semver/functions/diff.js"(exports$1, module) {
551
557
  var parse = require_parse();
552
558
  var diff = (version1, version2) => {
553
559
  const v1 = parse(version1, null, true);
@@ -588,36 +594,36 @@ var require_diff = __commonJS({
588
594
  }
589
595
  });
590
596
 
591
- // node_modules/semver/functions/major.js
597
+ // ../sdk/node_modules/semver/functions/major.js
592
598
  var require_major = __commonJS({
593
- "node_modules/semver/functions/major.js"(exports$1, module) {
599
+ "../sdk/node_modules/semver/functions/major.js"(exports$1, module) {
594
600
  var SemVer = require_semver();
595
601
  var major = (a, loose) => new SemVer(a, loose).major;
596
602
  module.exports = major;
597
603
  }
598
604
  });
599
605
 
600
- // node_modules/semver/functions/minor.js
606
+ // ../sdk/node_modules/semver/functions/minor.js
601
607
  var require_minor = __commonJS({
602
- "node_modules/semver/functions/minor.js"(exports$1, module) {
608
+ "../sdk/node_modules/semver/functions/minor.js"(exports$1, module) {
603
609
  var SemVer = require_semver();
604
610
  var minor = (a, loose) => new SemVer(a, loose).minor;
605
611
  module.exports = minor;
606
612
  }
607
613
  });
608
614
 
609
- // node_modules/semver/functions/patch.js
615
+ // ../sdk/node_modules/semver/functions/patch.js
610
616
  var require_patch = __commonJS({
611
- "node_modules/semver/functions/patch.js"(exports$1, module) {
617
+ "../sdk/node_modules/semver/functions/patch.js"(exports$1, module) {
612
618
  var SemVer = require_semver();
613
619
  var patch = (a, loose) => new SemVer(a, loose).patch;
614
620
  module.exports = patch;
615
621
  }
616
622
  });
617
623
 
618
- // node_modules/semver/functions/prerelease.js
624
+ // ../sdk/node_modules/semver/functions/prerelease.js
619
625
  var require_prerelease = __commonJS({
620
- "node_modules/semver/functions/prerelease.js"(exports$1, module) {
626
+ "../sdk/node_modules/semver/functions/prerelease.js"(exports$1, module) {
621
627
  var parse = require_parse();
622
628
  var prerelease = (version, options) => {
623
629
  const parsed = parse(version, options);
@@ -627,36 +633,36 @@ var require_prerelease = __commonJS({
627
633
  }
628
634
  });
629
635
 
630
- // node_modules/semver/functions/compare.js
636
+ // ../sdk/node_modules/semver/functions/compare.js
631
637
  var require_compare = __commonJS({
632
- "node_modules/semver/functions/compare.js"(exports$1, module) {
638
+ "../sdk/node_modules/semver/functions/compare.js"(exports$1, module) {
633
639
  var SemVer = require_semver();
634
640
  var compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
635
641
  module.exports = compare;
636
642
  }
637
643
  });
638
644
 
639
- // node_modules/semver/functions/rcompare.js
645
+ // ../sdk/node_modules/semver/functions/rcompare.js
640
646
  var require_rcompare = __commonJS({
641
- "node_modules/semver/functions/rcompare.js"(exports$1, module) {
647
+ "../sdk/node_modules/semver/functions/rcompare.js"(exports$1, module) {
642
648
  var compare = require_compare();
643
649
  var rcompare = (a, b, loose) => compare(b, a, loose);
644
650
  module.exports = rcompare;
645
651
  }
646
652
  });
647
653
 
648
- // node_modules/semver/functions/compare-loose.js
654
+ // ../sdk/node_modules/semver/functions/compare-loose.js
649
655
  var require_compare_loose = __commonJS({
650
- "node_modules/semver/functions/compare-loose.js"(exports$1, module) {
656
+ "../sdk/node_modules/semver/functions/compare-loose.js"(exports$1, module) {
651
657
  var compare = require_compare();
652
658
  var compareLoose = (a, b) => compare(a, b, true);
653
659
  module.exports = compareLoose;
654
660
  }
655
661
  });
656
662
 
657
- // node_modules/semver/functions/compare-build.js
663
+ // ../sdk/node_modules/semver/functions/compare-build.js
658
664
  var require_compare_build = __commonJS({
659
- "node_modules/semver/functions/compare-build.js"(exports$1, module) {
665
+ "../sdk/node_modules/semver/functions/compare-build.js"(exports$1, module) {
660
666
  var SemVer = require_semver();
661
667
  var compareBuild = (a, b, loose) => {
662
668
  const versionA = new SemVer(a, loose);
@@ -667,81 +673,81 @@ var require_compare_build = __commonJS({
667
673
  }
668
674
  });
669
675
 
670
- // node_modules/semver/functions/sort.js
676
+ // ../sdk/node_modules/semver/functions/sort.js
671
677
  var require_sort = __commonJS({
672
- "node_modules/semver/functions/sort.js"(exports$1, module) {
678
+ "../sdk/node_modules/semver/functions/sort.js"(exports$1, module) {
673
679
  var compareBuild = require_compare_build();
674
680
  var sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose));
675
681
  module.exports = sort;
676
682
  }
677
683
  });
678
684
 
679
- // node_modules/semver/functions/rsort.js
685
+ // ../sdk/node_modules/semver/functions/rsort.js
680
686
  var require_rsort = __commonJS({
681
- "node_modules/semver/functions/rsort.js"(exports$1, module) {
687
+ "../sdk/node_modules/semver/functions/rsort.js"(exports$1, module) {
682
688
  var compareBuild = require_compare_build();
683
689
  var rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose));
684
690
  module.exports = rsort;
685
691
  }
686
692
  });
687
693
 
688
- // node_modules/semver/functions/gt.js
694
+ // ../sdk/node_modules/semver/functions/gt.js
689
695
  var require_gt = __commonJS({
690
- "node_modules/semver/functions/gt.js"(exports$1, module) {
696
+ "../sdk/node_modules/semver/functions/gt.js"(exports$1, module) {
691
697
  var compare = require_compare();
692
698
  var gt = (a, b, loose) => compare(a, b, loose) > 0;
693
699
  module.exports = gt;
694
700
  }
695
701
  });
696
702
 
697
- // node_modules/semver/functions/lt.js
703
+ // ../sdk/node_modules/semver/functions/lt.js
698
704
  var require_lt = __commonJS({
699
- "node_modules/semver/functions/lt.js"(exports$1, module) {
705
+ "../sdk/node_modules/semver/functions/lt.js"(exports$1, module) {
700
706
  var compare = require_compare();
701
707
  var lt = (a, b, loose) => compare(a, b, loose) < 0;
702
708
  module.exports = lt;
703
709
  }
704
710
  });
705
711
 
706
- // node_modules/semver/functions/eq.js
712
+ // ../sdk/node_modules/semver/functions/eq.js
707
713
  var require_eq = __commonJS({
708
- "node_modules/semver/functions/eq.js"(exports$1, module) {
714
+ "../sdk/node_modules/semver/functions/eq.js"(exports$1, module) {
709
715
  var compare = require_compare();
710
716
  var eq = (a, b, loose) => compare(a, b, loose) === 0;
711
717
  module.exports = eq;
712
718
  }
713
719
  });
714
720
 
715
- // node_modules/semver/functions/neq.js
721
+ // ../sdk/node_modules/semver/functions/neq.js
716
722
  var require_neq = __commonJS({
717
- "node_modules/semver/functions/neq.js"(exports$1, module) {
723
+ "../sdk/node_modules/semver/functions/neq.js"(exports$1, module) {
718
724
  var compare = require_compare();
719
725
  var neq = (a, b, loose) => compare(a, b, loose) !== 0;
720
726
  module.exports = neq;
721
727
  }
722
728
  });
723
729
 
724
- // node_modules/semver/functions/gte.js
730
+ // ../sdk/node_modules/semver/functions/gte.js
725
731
  var require_gte = __commonJS({
726
- "node_modules/semver/functions/gte.js"(exports$1, module) {
732
+ "../sdk/node_modules/semver/functions/gte.js"(exports$1, module) {
727
733
  var compare = require_compare();
728
734
  var gte = (a, b, loose) => compare(a, b, loose) >= 0;
729
735
  module.exports = gte;
730
736
  }
731
737
  });
732
738
 
733
- // node_modules/semver/functions/lte.js
739
+ // ../sdk/node_modules/semver/functions/lte.js
734
740
  var require_lte = __commonJS({
735
- "node_modules/semver/functions/lte.js"(exports$1, module) {
741
+ "../sdk/node_modules/semver/functions/lte.js"(exports$1, module) {
736
742
  var compare = require_compare();
737
743
  var lte = (a, b, loose) => compare(a, b, loose) <= 0;
738
744
  module.exports = lte;
739
745
  }
740
746
  });
741
747
 
742
- // node_modules/semver/functions/cmp.js
748
+ // ../sdk/node_modules/semver/functions/cmp.js
743
749
  var require_cmp = __commonJS({
744
- "node_modules/semver/functions/cmp.js"(exports$1, module) {
750
+ "../sdk/node_modules/semver/functions/cmp.js"(exports$1, module) {
745
751
  var eq = require_eq();
746
752
  var neq = require_neq();
747
753
  var gt = require_gt();
@@ -788,9 +794,9 @@ var require_cmp = __commonJS({
788
794
  }
789
795
  });
790
796
 
791
- // node_modules/semver/functions/coerce.js
797
+ // ../sdk/node_modules/semver/functions/coerce.js
792
798
  var require_coerce = __commonJS({
793
- "node_modules/semver/functions/coerce.js"(exports$1, module) {
799
+ "../sdk/node_modules/semver/functions/coerce.js"(exports$1, module) {
794
800
  var SemVer = require_semver();
795
801
  var parse = require_parse();
796
802
  var { safeRe: re, t } = require_re();
@@ -833,9 +839,9 @@ var require_coerce = __commonJS({
833
839
  }
834
840
  });
835
841
 
836
- // node_modules/semver/internal/lrucache.js
842
+ // ../sdk/node_modules/semver/internal/lrucache.js
837
843
  var require_lrucache = __commonJS({
838
- "node_modules/semver/internal/lrucache.js"(exports$1, module) {
844
+ "../sdk/node_modules/semver/internal/lrucache.js"(exports$1, module) {
839
845
  var LRUCache = class {
840
846
  constructor() {
841
847
  this.max = 1e3;
@@ -870,9 +876,9 @@ var require_lrucache = __commonJS({
870
876
  }
871
877
  });
872
878
 
873
- // node_modules/semver/classes/range.js
879
+ // ../sdk/node_modules/semver/classes/range.js
874
880
  var require_range = __commonJS({
875
- "node_modules/semver/classes/range.js"(exports$1, module) {
881
+ "../sdk/node_modules/semver/classes/range.js"(exports$1, module) {
876
882
  var SPACE_CHARACTERS = /\s+/g;
877
883
  var Range = class _Range {
878
884
  constructor(range, options) {
@@ -974,9 +980,9 @@ var require_range = __commonJS({
974
980
  if (rangeMap.size > 1 && rangeMap.has("")) {
975
981
  rangeMap.delete("");
976
982
  }
977
- const result2 = [...rangeMap.values()];
978
- cache.set(memoKey, result2);
979
- return result2;
983
+ const result = [...rangeMap.values()];
984
+ cache.set(memoKey, result);
985
+ return result;
980
986
  }
981
987
  intersects(range, options) {
982
988
  if (!(range instanceof _Range)) {
@@ -1030,16 +1036,16 @@ var require_range = __commonJS({
1030
1036
  var isNullSet = (c) => c.value === "<0.0.0-0";
1031
1037
  var isAny = (c) => c.value === "";
1032
1038
  var isSatisfiable = (comparators, options) => {
1033
- let result2 = true;
1039
+ let result = true;
1034
1040
  const remainingComparators = comparators.slice();
1035
1041
  let testComparator = remainingComparators.pop();
1036
- while (result2 && remainingComparators.length) {
1037
- result2 = remainingComparators.every((otherComparator) => {
1042
+ while (result && remainingComparators.length) {
1043
+ result = remainingComparators.every((otherComparator) => {
1038
1044
  return testComparator.intersects(otherComparator, options);
1039
1045
  });
1040
1046
  testComparator = remainingComparators.pop();
1041
1047
  }
1042
- return result2;
1048
+ return result;
1043
1049
  };
1044
1050
  var parseComparator = (comp, options) => {
1045
1051
  comp = comp.replace(re[t.BUILD], "");
@@ -1246,9 +1252,9 @@ var require_range = __commonJS({
1246
1252
  }
1247
1253
  });
1248
1254
 
1249
- // node_modules/semver/classes/comparator.js
1255
+ // ../sdk/node_modules/semver/classes/comparator.js
1250
1256
  var require_comparator = __commonJS({
1251
- "node_modules/semver/classes/comparator.js"(exports$1, module) {
1257
+ "../sdk/node_modules/semver/classes/comparator.js"(exports$1, module) {
1252
1258
  var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
1253
1259
  var Comparator = class _Comparator {
1254
1260
  static get ANY() {
@@ -1358,9 +1364,9 @@ var require_comparator = __commonJS({
1358
1364
  }
1359
1365
  });
1360
1366
 
1361
- // node_modules/semver/functions/satisfies.js
1367
+ // ../sdk/node_modules/semver/functions/satisfies.js
1362
1368
  var require_satisfies = __commonJS({
1363
- "node_modules/semver/functions/satisfies.js"(exports$1, module) {
1369
+ "../sdk/node_modules/semver/functions/satisfies.js"(exports$1, module) {
1364
1370
  var Range = require_range();
1365
1371
  var satisfies = (version, range, options) => {
1366
1372
  try {
@@ -1374,18 +1380,18 @@ var require_satisfies = __commonJS({
1374
1380
  }
1375
1381
  });
1376
1382
 
1377
- // node_modules/semver/ranges/to-comparators.js
1383
+ // ../sdk/node_modules/semver/ranges/to-comparators.js
1378
1384
  var require_to_comparators = __commonJS({
1379
- "node_modules/semver/ranges/to-comparators.js"(exports$1, module) {
1385
+ "../sdk/node_modules/semver/ranges/to-comparators.js"(exports$1, module) {
1380
1386
  var Range = require_range();
1381
1387
  var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" "));
1382
1388
  module.exports = toComparators;
1383
1389
  }
1384
1390
  });
1385
1391
 
1386
- // node_modules/semver/ranges/max-satisfying.js
1392
+ // ../sdk/node_modules/semver/ranges/max-satisfying.js
1387
1393
  var require_max_satisfying = __commonJS({
1388
- "node_modules/semver/ranges/max-satisfying.js"(exports$1, module) {
1394
+ "../sdk/node_modules/semver/ranges/max-satisfying.js"(exports$1, module) {
1389
1395
  var SemVer = require_semver();
1390
1396
  var Range = require_range();
1391
1397
  var maxSatisfying = (versions, range, options) => {
@@ -1411,9 +1417,9 @@ var require_max_satisfying = __commonJS({
1411
1417
  }
1412
1418
  });
1413
1419
 
1414
- // node_modules/semver/ranges/min-satisfying.js
1420
+ // ../sdk/node_modules/semver/ranges/min-satisfying.js
1415
1421
  var require_min_satisfying = __commonJS({
1416
- "node_modules/semver/ranges/min-satisfying.js"(exports$1, module) {
1422
+ "../sdk/node_modules/semver/ranges/min-satisfying.js"(exports$1, module) {
1417
1423
  var SemVer = require_semver();
1418
1424
  var Range = require_range();
1419
1425
  var minSatisfying = (versions, range, options) => {
@@ -1439,9 +1445,9 @@ var require_min_satisfying = __commonJS({
1439
1445
  }
1440
1446
  });
1441
1447
 
1442
- // node_modules/semver/ranges/min-version.js
1448
+ // ../sdk/node_modules/semver/ranges/min-version.js
1443
1449
  var require_min_version = __commonJS({
1444
- "node_modules/semver/ranges/min-version.js"(exports$1, module) {
1450
+ "../sdk/node_modules/semver/ranges/min-version.js"(exports$1, module) {
1445
1451
  var SemVer = require_semver();
1446
1452
  var Range = require_range();
1447
1453
  var gt = require_gt();
@@ -1497,9 +1503,9 @@ var require_min_version = __commonJS({
1497
1503
  }
1498
1504
  });
1499
1505
 
1500
- // node_modules/semver/ranges/valid.js
1506
+ // ../sdk/node_modules/semver/ranges/valid.js
1501
1507
  var require_valid2 = __commonJS({
1502
- "node_modules/semver/ranges/valid.js"(exports$1, module) {
1508
+ "../sdk/node_modules/semver/ranges/valid.js"(exports$1, module) {
1503
1509
  var Range = require_range();
1504
1510
  var validRange = (range, options) => {
1505
1511
  try {
@@ -1512,9 +1518,9 @@ var require_valid2 = __commonJS({
1512
1518
  }
1513
1519
  });
1514
1520
 
1515
- // node_modules/semver/ranges/outside.js
1521
+ // ../sdk/node_modules/semver/ranges/outside.js
1516
1522
  var require_outside = __commonJS({
1517
- "node_modules/semver/ranges/outside.js"(exports$1, module) {
1523
+ "../sdk/node_modules/semver/ranges/outside.js"(exports$1, module) {
1518
1524
  var SemVer = require_semver();
1519
1525
  var Comparator = require_comparator();
1520
1526
  var { ANY } = Comparator;
@@ -1580,27 +1586,27 @@ var require_outside = __commonJS({
1580
1586
  }
1581
1587
  });
1582
1588
 
1583
- // node_modules/semver/ranges/gtr.js
1589
+ // ../sdk/node_modules/semver/ranges/gtr.js
1584
1590
  var require_gtr = __commonJS({
1585
- "node_modules/semver/ranges/gtr.js"(exports$1, module) {
1591
+ "../sdk/node_modules/semver/ranges/gtr.js"(exports$1, module) {
1586
1592
  var outside = require_outside();
1587
1593
  var gtr = (version, range, options) => outside(version, range, ">", options);
1588
1594
  module.exports = gtr;
1589
1595
  }
1590
1596
  });
1591
1597
 
1592
- // node_modules/semver/ranges/ltr.js
1598
+ // ../sdk/node_modules/semver/ranges/ltr.js
1593
1599
  var require_ltr = __commonJS({
1594
- "node_modules/semver/ranges/ltr.js"(exports$1, module) {
1600
+ "../sdk/node_modules/semver/ranges/ltr.js"(exports$1, module) {
1595
1601
  var outside = require_outside();
1596
1602
  var ltr = (version, range, options) => outside(version, range, "<", options);
1597
1603
  module.exports = ltr;
1598
1604
  }
1599
1605
  });
1600
1606
 
1601
- // node_modules/semver/ranges/intersects.js
1607
+ // ../sdk/node_modules/semver/ranges/intersects.js
1602
1608
  var require_intersects = __commonJS({
1603
- "node_modules/semver/ranges/intersects.js"(exports$1, module) {
1609
+ "../sdk/node_modules/semver/ranges/intersects.js"(exports$1, module) {
1604
1610
  var Range = require_range();
1605
1611
  var intersects = (r1, r2, options) => {
1606
1612
  r1 = new Range(r1, options);
@@ -1611,9 +1617,9 @@ var require_intersects = __commonJS({
1611
1617
  }
1612
1618
  });
1613
1619
 
1614
- // node_modules/semver/ranges/simplify.js
1620
+ // ../sdk/node_modules/semver/ranges/simplify.js
1615
1621
  var require_simplify = __commonJS({
1616
- "node_modules/semver/ranges/simplify.js"(exports$1, module) {
1622
+ "../sdk/node_modules/semver/ranges/simplify.js"(exports$1, module) {
1617
1623
  var satisfies = require_satisfies();
1618
1624
  var compare = require_compare();
1619
1625
  module.exports = (versions, range, options) => {
@@ -1660,9 +1666,9 @@ var require_simplify = __commonJS({
1660
1666
  }
1661
1667
  });
1662
1668
 
1663
- // node_modules/semver/ranges/subset.js
1669
+ // ../sdk/node_modules/semver/ranges/subset.js
1664
1670
  var require_subset = __commonJS({
1665
- "node_modules/semver/ranges/subset.js"(exports$1, module) {
1671
+ "../sdk/node_modules/semver/ranges/subset.js"(exports$1, module) {
1666
1672
  var Range = require_range();
1667
1673
  var Comparator = require_comparator();
1668
1674
  var { ANY } = Comparator;
@@ -1821,9 +1827,9 @@ var require_subset = __commonJS({
1821
1827
  }
1822
1828
  });
1823
1829
 
1824
- // node_modules/semver/index.js
1830
+ // ../sdk/node_modules/semver/index.js
1825
1831
  var require_semver2 = __commonJS({
1826
- "node_modules/semver/index.js"(exports$1, module) {
1832
+ "../sdk/node_modules/semver/index.js"(exports$1, module) {
1827
1833
  var internalRe = require_re();
1828
1834
  var constants = require_constants();
1829
1835
  var SemVer = require_semver();
@@ -1915,6 +1921,546 @@ var require_semver2 = __commonJS({
1915
1921
  }
1916
1922
  });
1917
1923
 
1924
+ // ../sdk/dist/flags/server.js
1925
+ var require_server = __commonJS({
1926
+ "../sdk/dist/flags/server.js"(exports$1, module) {
1927
+ var __defProp2 = Object.defineProperty;
1928
+ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
1929
+ var __getOwnPropNames2 = Object.getOwnPropertyNames;
1930
+ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
1931
+ var __export = (target, all) => {
1932
+ for (var name in all)
1933
+ __defProp2(target, name, { get: all[name], enumerable: true });
1934
+ };
1935
+ var __copyProps2 = (to, from, except, desc) => {
1936
+ if (from && typeof from === "object" || typeof from === "function") {
1937
+ for (let key of __getOwnPropNames2(from))
1938
+ if (!__hasOwnProp2.call(to, key) && key !== except)
1939
+ __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
1940
+ }
1941
+ return to;
1942
+ };
1943
+ var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
1944
+ var server_exports = {};
1945
+ __export(server_exports, {
1946
+ FlagClient: () => FlagClient2,
1947
+ allConditionsMatch: () => allConditionsMatch,
1948
+ evaluateFlag: () => evaluateFlag,
1949
+ hashToBucket: () => hashToBucket
1950
+ });
1951
+ module.exports = __toCommonJS(server_exports);
1952
+ var import_node_crypto = __require("crypto");
1953
+ function hashToBucket(flagKey, identifier, salt) {
1954
+ const hash = (0, import_node_crypto.createHash)("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
1955
+ return hash.readUInt32BE(0) % 1e4;
1956
+ }
1957
+ var import_semver = require_semver2();
1958
+ function allConditionsMatch(conditions, context) {
1959
+ return conditions.every((c) => conditionMatches(c, context));
1960
+ }
1961
+ function conditionMatches(condition, context) {
1962
+ const attributeValue = getAttribute(context, condition.attribute);
1963
+ const op = condition.operator;
1964
+ if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
1965
+ if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
1966
+ if (attributeValue === void 0 || attributeValue === null) return false;
1967
+ switch (op) {
1968
+ case "eq":
1969
+ return compareValues(attributeValue, condition.value) === 0;
1970
+ case "neq":
1971
+ return compareValues(attributeValue, condition.value) !== 0;
1972
+ case "in":
1973
+ return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
1974
+ case "not_in":
1975
+ return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
1976
+ case "contains":
1977
+ return containsValue(attributeValue, condition.value);
1978
+ case "starts_with":
1979
+ return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
1980
+ case "ends_with":
1981
+ return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
1982
+ case "gt":
1983
+ return compareValues(attributeValue, condition.value) === 1;
1984
+ case "gte": {
1985
+ const cmp = compareValues(attributeValue, condition.value);
1986
+ return cmp === 1 || cmp === 0;
1987
+ }
1988
+ case "lt":
1989
+ return compareValues(attributeValue, condition.value) === -1;
1990
+ case "lte": {
1991
+ const cmp = compareValues(attributeValue, condition.value);
1992
+ return cmp === -1 || cmp === 0;
1993
+ }
1994
+ case "regex": {
1995
+ if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
1996
+ try {
1997
+ return new RegExp(condition.value).test(attributeValue);
1998
+ } catch {
1999
+ return false;
2000
+ }
2001
+ }
2002
+ case "semver_eq":
2003
+ return semverCmp(attributeValue, condition.value) === 0;
2004
+ case "semver_neq":
2005
+ return semverCmp(attributeValue, condition.value) !== 0;
2006
+ case "semver_gt":
2007
+ return semverCmp(attributeValue, condition.value) === 1;
2008
+ case "semver_gte": {
2009
+ const cmp = semverCmp(attributeValue, condition.value);
2010
+ return cmp === 1 || cmp === 0;
2011
+ }
2012
+ case "semver_lt":
2013
+ return semverCmp(attributeValue, condition.value) === -1;
2014
+ case "semver_lte": {
2015
+ const cmp = semverCmp(attributeValue, condition.value);
2016
+ return cmp === -1 || cmp === 0;
2017
+ }
2018
+ default:
2019
+ return false;
2020
+ }
2021
+ }
2022
+ function getAttribute(context, key) {
2023
+ switch (key) {
2024
+ case "user_id":
2025
+ return context.user_id;
2026
+ case "email":
2027
+ return context.email;
2028
+ case "session_id":
2029
+ return context.session_id;
2030
+ case "ip_address":
2031
+ return context.ip_address;
2032
+ case "user_agent":
2033
+ return context.user_agent;
2034
+ case "timestamp":
2035
+ return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
2036
+ default:
2037
+ return context[key];
2038
+ }
2039
+ }
2040
+ function candidateValues(condition) {
2041
+ if (condition.values && condition.values.length > 0) return condition.values;
2042
+ if (condition.value === void 0 || condition.value === null) return [];
2043
+ if (Array.isArray(condition.value)) return condition.value;
2044
+ return [condition.value];
2045
+ }
2046
+ function compareValues(actual, expected) {
2047
+ if (expected === void 0 || expected === null) return null;
2048
+ const numA = toNumber(actual);
2049
+ const numB = toNumber(expected);
2050
+ if (numA !== null && numB !== null) {
2051
+ if (numA < numB) return -1;
2052
+ if (numA > numB) return 1;
2053
+ return 0;
2054
+ }
2055
+ if (typeof actual === "boolean" && typeof expected === "boolean") {
2056
+ if (actual === expected) return 0;
2057
+ return actual ? 1 : -1;
2058
+ }
2059
+ const strA = toString(actual);
2060
+ const strB = toString(expected);
2061
+ if (strA !== null && strB !== null) {
2062
+ if (strA < strB) return -1;
2063
+ if (strA > strB) return 1;
2064
+ return 0;
2065
+ }
2066
+ return null;
2067
+ }
2068
+ function containsValue(actual, expected) {
2069
+ if (expected === void 0 || expected === null) return false;
2070
+ if (Array.isArray(actual)) {
2071
+ return actual.some((item) => compareValues(item, expected) === 0);
2072
+ }
2073
+ if (typeof actual === "string" && typeof expected === "string") {
2074
+ return actual.includes(expected);
2075
+ }
2076
+ return false;
2077
+ }
2078
+ function toNumber(value) {
2079
+ if (typeof value === "number") return value;
2080
+ if (typeof value === "string") {
2081
+ const n = Number(value);
2082
+ return isNaN(n) ? null : n;
2083
+ }
2084
+ return null;
2085
+ }
2086
+ function toString(value) {
2087
+ if (typeof value === "string") return value;
2088
+ return null;
2089
+ }
2090
+ function semverCmp(actual, expected) {
2091
+ if (typeof actual !== "string" || typeof expected !== "string") return null;
2092
+ try {
2093
+ const a = (0, import_semver.parse)(actual);
2094
+ const b = (0, import_semver.parse)(expected);
2095
+ if (!a || !b) return null;
2096
+ return (0, import_semver.compare)(a, b);
2097
+ } catch {
2098
+ return null;
2099
+ }
2100
+ }
2101
+ function evaluateFlag(flag, config, context, segmentIndex) {
2102
+ const effectiveDefault = flag.environment_default_value ?? flag.default_value;
2103
+ if (flag.status !== "active") {
2104
+ return result(flag, config.environment, effectiveDefault, "disabled");
2105
+ }
2106
+ if (!flag.environment_enabled) {
2107
+ return result(flag, config.environment, effectiveDefault, "disabled");
2108
+ }
2109
+ const bucketIdentifier = getBucketIdentifier(context);
2110
+ for (const rule of flag.rules) {
2111
+ if (!rule.enabled) continue;
2112
+ if (rule.segment_ids.length > 0) {
2113
+ const segmentMatched = rule.segment_ids.some((segId) => {
2114
+ const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
2115
+ if (!segment) return false;
2116
+ return userMatchesSegment(segment, context);
2117
+ });
2118
+ if (!segmentMatched) continue;
2119
+ }
2120
+ if (!allConditionsMatch(rule.conditions, context)) continue;
2121
+ if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
2122
+ const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
2123
+ if (bucket >= rule.rollout_percentage) continue;
2124
+ return {
2125
+ flag_id: flag.flag_id,
2126
+ flag_key: flag.flag_key,
2127
+ environment: config.environment,
2128
+ value: rule.serve_value,
2129
+ reason: "rule_match",
2130
+ matched_rule_id: rule.id,
2131
+ variant_key: null,
2132
+ bucket
2133
+ };
2134
+ }
2135
+ return {
2136
+ flag_id: flag.flag_id,
2137
+ flag_key: flag.flag_key,
2138
+ environment: config.environment,
2139
+ value: rule.serve_value,
2140
+ reason: "rule_match",
2141
+ matched_rule_id: rule.id,
2142
+ variant_key: null,
2143
+ bucket: null
2144
+ };
2145
+ }
2146
+ if (flag.variants.length > 0) {
2147
+ const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
2148
+ if (totalWeight > 0) {
2149
+ const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
2150
+ const scaled = Math.floor(bucket * totalWeight / 1e4);
2151
+ let cursor = 0;
2152
+ for (const variant of flag.variants) {
2153
+ cursor += variant.weight;
2154
+ if (scaled < cursor) {
2155
+ return {
2156
+ flag_id: flag.flag_id,
2157
+ flag_key: flag.flag_key,
2158
+ environment: config.environment,
2159
+ value: variant.value,
2160
+ reason: "variant",
2161
+ matched_rule_id: null,
2162
+ variant_key: variant.variant_key,
2163
+ bucket
2164
+ };
2165
+ }
2166
+ }
2167
+ }
2168
+ }
2169
+ return result(flag, config.environment, effectiveDefault, "default");
2170
+ }
2171
+ function getBucketIdentifier(context) {
2172
+ return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
2173
+ }
2174
+ function userMatchesSegment(segment, context) {
2175
+ const identifiers = [context.user_id, context.email, context.session_id].filter(
2176
+ (v) => v !== void 0 && v !== null
2177
+ );
2178
+ if (identifiers.some((id) => segment.excluded_users.includes(id))) {
2179
+ return false;
2180
+ }
2181
+ if (identifiers.some((id) => segment.included_users.includes(id))) {
2182
+ return true;
2183
+ }
2184
+ return allConditionsMatch(segment.conditions, context);
2185
+ }
2186
+ function result(flag, environment, value, reason) {
2187
+ return {
2188
+ flag_id: flag.flag_id,
2189
+ flag_key: flag.flag_key,
2190
+ environment,
2191
+ value,
2192
+ reason,
2193
+ matched_rule_id: null,
2194
+ variant_key: null,
2195
+ bucket: null
2196
+ };
2197
+ }
2198
+ var FlagClient2 = class {
2199
+ constructor(options) {
2200
+ this.config = null;
2201
+ this.flagIndex = /* @__PURE__ */ new Map();
2202
+ this.segmentIndex = /* @__PURE__ */ new Map();
2203
+ this.lastETag = "";
2204
+ this.streamState = "idle";
2205
+ this.pollTimer = null;
2206
+ this.reconnectTimer = null;
2207
+ this.telemetryTimer = null;
2208
+ this.abortController = null;
2209
+ this.initPromise = null;
2210
+ this.telemetryCounters = /* @__PURE__ */ new Map();
2211
+ this.isShuttingDown = false;
2212
+ this.streamConnectInFlight = false;
2213
+ this.apiKey = options.apiKey;
2214
+ this.environment = options.environment;
2215
+ this.gatewayUrl = options.gatewayUrl;
2216
+ }
2217
+ async init() {
2218
+ this.isShuttingDown = false;
2219
+ if (this.config) return;
2220
+ if (this.initPromise) return this.initPromise;
2221
+ this.initPromise = this.doInit();
2222
+ try {
2223
+ await this.initPromise;
2224
+ } finally {
2225
+ this.initPromise = null;
2226
+ }
2227
+ }
2228
+ async doInit() {
2229
+ const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
2230
+ headers: { "x-api-key": this.apiKey }
2231
+ });
2232
+ if (resp.status === 403) throw new Error("Secret API key required for /config");
2233
+ if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
2234
+ const json = await resp.json();
2235
+ this.config = json.data;
2236
+ this.buildIndexes();
2237
+ this.lastETag = resp.headers.get("etag") || "";
2238
+ this.connectStream();
2239
+ this.startTelemetryFlush();
2240
+ }
2241
+ buildIndexes() {
2242
+ this.flagIndex.clear();
2243
+ this.segmentIndex.clear();
2244
+ if (!this.config) return;
2245
+ for (const flag of this.config.flags) {
2246
+ this.flagIndex.set(flag.flag_key, flag);
2247
+ }
2248
+ for (const segment of this.config.segments) {
2249
+ this.segmentIndex.set(segment.id, segment);
2250
+ }
2251
+ }
2252
+ evaluate(flagKey, context) {
2253
+ if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
2254
+ const flagConfig = this.flagIndex.get(flagKey);
2255
+ if (!flagConfig) {
2256
+ return {
2257
+ flag_id: "",
2258
+ flag_key: flagKey,
2259
+ environment: this.environment,
2260
+ value: null,
2261
+ reason: "not_found",
2262
+ matched_rule_id: null,
2263
+ variant_key: null,
2264
+ bucket: null
2265
+ };
2266
+ }
2267
+ const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
2268
+ this.recordTelemetry(result2);
2269
+ return result2;
2270
+ }
2271
+ evaluateBatch(flagKeys, context) {
2272
+ if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
2273
+ const results = {};
2274
+ for (const key of flagKeys) {
2275
+ const flagConfig = this.flagIndex.get(key);
2276
+ if (flagConfig) {
2277
+ const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
2278
+ this.recordTelemetry(result2);
2279
+ results[key] = result2;
2280
+ }
2281
+ }
2282
+ return results;
2283
+ }
2284
+ async shutdown() {
2285
+ this.isShuttingDown = true;
2286
+ this.streamState = "idle";
2287
+ this.abortController?.abort();
2288
+ this.abortController = null;
2289
+ if (this.pollTimer) {
2290
+ clearInterval(this.pollTimer);
2291
+ this.pollTimer = null;
2292
+ }
2293
+ if (this.reconnectTimer) {
2294
+ clearInterval(this.reconnectTimer);
2295
+ this.reconnectTimer = null;
2296
+ }
2297
+ if (this.telemetryTimer) {
2298
+ clearInterval(this.telemetryTimer);
2299
+ this.telemetryTimer = null;
2300
+ }
2301
+ await this.flushTelemetry();
2302
+ }
2303
+ // ======== SSE Streaming ========
2304
+ async connectStream() {
2305
+ if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
2306
+ this.streamConnectInFlight = true;
2307
+ this.abortController?.abort();
2308
+ const abortController = new AbortController();
2309
+ this.abortController = abortController;
2310
+ const shouldResumePolling = this.streamState !== "polling";
2311
+ let startPolling = shouldResumePolling;
2312
+ try {
2313
+ const resp = await fetch(
2314
+ `${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
2315
+ {
2316
+ headers: {
2317
+ "x-api-key": this.apiKey,
2318
+ "Last-Event-ID": String(this.config?.version ?? 0)
2319
+ },
2320
+ signal: abortController.signal
2321
+ }
2322
+ );
2323
+ if (resp.ok && resp.body) {
2324
+ this.streamState = "streaming";
2325
+ this.stopPolling();
2326
+ startPolling = false;
2327
+ const reader = resp.body.getReader();
2328
+ const decoder = new TextDecoder();
2329
+ let buffer = "";
2330
+ while (true) {
2331
+ const { done, value } = await reader.read();
2332
+ if (done) break;
2333
+ buffer += decoder.decode(value, { stream: true });
2334
+ let idx;
2335
+ while ((idx = buffer.indexOf("\n\n")) !== -1) {
2336
+ const frame = buffer.slice(0, idx);
2337
+ buffer = buffer.slice(idx + 2);
2338
+ this.handleSseFrame(frame);
2339
+ }
2340
+ }
2341
+ if (this.streamState === "streaming") {
2342
+ this.streamState = "idle";
2343
+ startPolling = true;
2344
+ }
2345
+ }
2346
+ } catch {
2347
+ startPolling = !abortController.signal.aborted && shouldResumePolling;
2348
+ } finally {
2349
+ this.streamConnectInFlight = false;
2350
+ }
2351
+ if (!this.isShuttingDown && startPolling) {
2352
+ this.startPolling();
2353
+ }
2354
+ }
2355
+ handleSseFrame(frame) {
2356
+ let eventType = "";
2357
+ let data = "";
2358
+ for (const line of frame.split("\n")) {
2359
+ if (line.startsWith("event:")) eventType = line.slice(6).trim();
2360
+ else if (line.startsWith("data:")) data += line.slice(5).trim();
2361
+ }
2362
+ if (eventType === "config" && data) {
2363
+ try {
2364
+ const parsed = JSON.parse(data);
2365
+ const newConfig = parsed.data;
2366
+ if (newConfig && newConfig.version !== void 0) {
2367
+ this.config = newConfig;
2368
+ this.buildIndexes();
2369
+ }
2370
+ } catch {
2371
+ }
2372
+ }
2373
+ }
2374
+ // ======== Polling Fallback ========
2375
+ startPolling() {
2376
+ if (this.streamState === "polling") return;
2377
+ this.streamState = "polling";
2378
+ this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
2379
+ this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
2380
+ }
2381
+ stopPolling() {
2382
+ if (this.pollTimer) {
2383
+ clearInterval(this.pollTimer);
2384
+ this.pollTimer = null;
2385
+ }
2386
+ if (this.reconnectTimer) {
2387
+ clearInterval(this.reconnectTimer);
2388
+ this.reconnectTimer = null;
2389
+ }
2390
+ }
2391
+ async pollConfig() {
2392
+ try {
2393
+ const headers2 = { "x-api-key": this.apiKey };
2394
+ if (this.lastETag) headers2["if-none-match"] = this.lastETag;
2395
+ const resp = await fetch(
2396
+ `${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
2397
+ { headers: headers2 }
2398
+ );
2399
+ if (resp.status === 304) return;
2400
+ if (!resp.ok) return;
2401
+ const json = await resp.json();
2402
+ this.config = json.data;
2403
+ this.buildIndexes();
2404
+ this.lastETag = resp.headers.get("etag") || "";
2405
+ } catch {
2406
+ }
2407
+ }
2408
+ // ======== Telemetry ========
2409
+ recordTelemetry(evaluation) {
2410
+ const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
2411
+ const existing = this.telemetryCounters.get(key);
2412
+ if (existing) {
2413
+ existing.count++;
2414
+ if (evaluation.value === true) existing.true_count++;
2415
+ else if (evaluation.value === false) existing.false_count++;
2416
+ } else {
2417
+ this.telemetryCounters.set(key, {
2418
+ flag_key: evaluation.flag_key,
2419
+ flag_id: evaluation.flag_id,
2420
+ reason: evaluation.reason,
2421
+ count: 1,
2422
+ true_count: evaluation.value === true ? 1 : 0,
2423
+ false_count: evaluation.value === false ? 1 : 0
2424
+ });
2425
+ }
2426
+ }
2427
+ startTelemetryFlush() {
2428
+ this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
2429
+ }
2430
+ async flushTelemetry() {
2431
+ if (this.telemetryCounters.size === 0) return;
2432
+ const evaluations = Array.from(this.telemetryCounters.values());
2433
+ this.telemetryCounters.clear();
2434
+ try {
2435
+ await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
2436
+ method: "POST",
2437
+ headers: {
2438
+ "Content-Type": "application/json",
2439
+ "x-api-key": this.apiKey
2440
+ },
2441
+ body: JSON.stringify({
2442
+ environment: this.environment,
2443
+ evaluations
2444
+ })
2445
+ });
2446
+ } catch {
2447
+ for (const counter of evaluations) {
2448
+ const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
2449
+ const existing = this.telemetryCounters.get(key);
2450
+ if (existing) {
2451
+ existing.count += counter.count;
2452
+ existing.true_count += counter.true_count;
2453
+ existing.false_count += counter.false_count;
2454
+ } else {
2455
+ this.telemetryCounters.set(key, counter);
2456
+ }
2457
+ }
2458
+ }
2459
+ }
2460
+ };
2461
+ }
2462
+ });
2463
+
1918
2464
  // src/types/index.ts
1919
2465
  var ScaleMuleApiError = class extends Error {
1920
2466
  constructor(error, status) {
@@ -2109,23 +2655,31 @@ var ScaleMuleServer = class {
2109
2655
  /**
2110
2656
  * Logout user
2111
2657
  */
2112
- logout: async (sessionToken) => {
2658
+ logout: async (sessionToken, options) => {
2113
2659
  return this.request("POST", "/v1/auth/logout", {
2114
- body: { session_token: sessionToken }
2660
+ sessionToken,
2661
+ body: { session_token: sessionToken },
2662
+ onTokenRotated: options?.onTokenRotated
2115
2663
  });
2116
2664
  },
2117
2665
  /**
2118
2666
  * Get current user from session token
2119
2667
  */
2120
- me: async (sessionToken) => {
2121
- return this.request("GET", "/v1/auth/me", { sessionToken });
2668
+ me: async (sessionToken, options) => {
2669
+ return this.request("GET", "/v1/auth/me", {
2670
+ sessionToken,
2671
+ onTokenRotated: options?.onTokenRotated
2672
+ });
2122
2673
  },
2123
2674
  /**
2124
2675
  * Refresh session token
2125
2676
  */
2126
- refresh: async (sessionToken) => {
2677
+ refresh: async (sessionToken, options) => {
2127
2678
  return this.request("POST", "/v1/auth/refresh", {
2128
- body: { session_token: sessionToken }
2679
+ sessionToken,
2680
+ clientContext: options?.clientContext,
2681
+ isAutoRefresh: options?.isAutoRefresh,
2682
+ onTokenRotated: options?.onTokenRotated
2129
2683
  });
2130
2684
  },
2131
2685
  /**
@@ -2157,7 +2711,8 @@ var ScaleMuleServer = class {
2157
2711
  if (options?.email) {
2158
2712
  return this.request("POST", "/v1/auth/resend-verification", {
2159
2713
  sessionToken: sessionTokenOrEmail,
2160
- body: { email: options.email }
2714
+ body: { email: options.email },
2715
+ onTokenRotated: options?.onTokenRotated
2161
2716
  });
2162
2717
  }
2163
2718
  if (sessionTokenOrEmail.includes("@")) {
@@ -2166,7 +2721,8 @@ var ScaleMuleServer = class {
2166
2721
  });
2167
2722
  }
2168
2723
  return this.request("POST", "/v1/auth/resend-verification", {
2169
- sessionToken: sessionTokenOrEmail
2724
+ sessionToken: sessionTokenOrEmail,
2725
+ onTokenRotated: options?.onTokenRotated
2170
2726
  });
2171
2727
  }
2172
2728
  };
@@ -2177,37 +2733,41 @@ var ScaleMuleServer = class {
2177
2733
  /**
2178
2734
  * Update user profile
2179
2735
  */
2180
- update: async (sessionToken, data) => {
2736
+ update: async (sessionToken, data, options) => {
2181
2737
  return this.request("PATCH", "/v1/auth/profile", {
2182
2738
  sessionToken,
2183
- body: data
2739
+ body: data,
2740
+ onTokenRotated: options?.onTokenRotated
2184
2741
  });
2185
2742
  },
2186
2743
  /**
2187
2744
  * Change password
2188
2745
  */
2189
- changePassword: async (sessionToken, currentPassword, newPassword) => {
2746
+ changePassword: async (sessionToken, currentPassword, newPassword, options) => {
2190
2747
  return this.request("POST", "/v1/auth/change-password", {
2191
2748
  sessionToken,
2192
- body: { current_password: currentPassword, new_password: newPassword }
2749
+ body: { current_password: currentPassword, new_password: newPassword },
2750
+ onTokenRotated: options?.onTokenRotated
2193
2751
  });
2194
2752
  },
2195
2753
  /**
2196
2754
  * Change email
2197
2755
  */
2198
- changeEmail: async (sessionToken, newEmail, password) => {
2756
+ changeEmail: async (sessionToken, newEmail, password, options) => {
2199
2757
  return this.request("POST", "/v1/auth/change-email", {
2200
2758
  sessionToken,
2201
- body: { new_email: newEmail, password }
2759
+ body: { new_email: newEmail, password },
2760
+ onTokenRotated: options?.onTokenRotated
2202
2761
  });
2203
2762
  },
2204
2763
  /**
2205
2764
  * Delete account
2206
2765
  */
2207
- deleteAccount: async (sessionToken, password) => {
2766
+ deleteAccount: async (sessionToken, password, options) => {
2208
2767
  return this.request("DELETE", "/v1/auth/me", {
2209
2768
  sessionToken,
2210
- body: { password }
2769
+ body: { password },
2770
+ onTokenRotated: options?.onTokenRotated
2211
2771
  });
2212
2772
  }
2213
2773
  };
@@ -2668,6 +3228,9 @@ var ScaleMuleServer = class {
2668
3228
  this.apiKey = config.apiKey;
2669
3229
  this.gatewayUrl = resolveGatewayUrl(config);
2670
3230
  this.debug = config.debug || false;
3231
+ this.onRefreshStart = config.onRefreshStart;
3232
+ this.onRefreshEnd = config.onRefreshEnd;
3233
+ this.onAutoRefreshFailed = config.onAutoRefreshFailed;
2671
3234
  this.money = createMoneyClient({
2672
3235
  apiKey: this.apiKey,
2673
3236
  gatewayUrl: this.gatewayUrl,
@@ -2711,6 +3274,10 @@ var ScaleMuleServer = class {
2711
3274
  headers: headers2,
2712
3275
  body: options.body ? JSON.stringify(options.body) : void 0
2713
3276
  });
3277
+ const rotated = response.headers.get("x-rotated-session-token");
3278
+ if (rotated && options.onTokenRotated) {
3279
+ options.onTokenRotated(rotated);
3280
+ }
2714
3281
  const text = await response.text();
2715
3282
  let responseData = null;
2716
3283
  try {
@@ -2722,6 +3289,33 @@ var ScaleMuleServer = class {
2722
3289
  code: `HTTP_${response.status}`,
2723
3290
  message: responseData?.message || text || response.statusText
2724
3291
  };
3292
+ if (response.status === 401 && options.sessionToken && !options.isAutoRefresh) {
3293
+ if (this.debug) console.log("[ScaleMule Server] 401 received, attempting auto-refresh...");
3294
+ try {
3295
+ this.onRefreshStart?.();
3296
+ const refreshData = await this.auth.refresh(options.sessionToken, {
3297
+ clientContext: options.clientContext,
3298
+ isAutoRefresh: true
3299
+ // Prevent infinite loops
3300
+ });
3301
+ const newToken = refreshData.session_token;
3302
+ if (this.debug) console.log("[ScaleMule Server] Auto-refresh succeeded, retrying original request...");
3303
+ options.onTokenRotated?.(newToken);
3304
+ return this.request(method, path, {
3305
+ ...options,
3306
+ sessionToken: newToken,
3307
+ isAutoRefresh: true
3308
+ // Don't refresh again on this retry
3309
+ });
3310
+ } catch (refreshErr) {
3311
+ if (this.debug) console.error("[ScaleMule Server] Auto-refresh failed:", refreshErr);
3312
+ const refreshApiError = refreshErr instanceof ScaleMuleApiError ? { code: refreshErr.code, message: refreshErr.message } : { code: "REFRESH_FAILED", message: "Auto-refresh failed" };
3313
+ this.onAutoRefreshFailed?.(refreshApiError);
3314
+ throw new ScaleMuleApiError(error);
3315
+ } finally {
3316
+ this.onRefreshEnd?.();
3317
+ }
3318
+ }
2725
3319
  throw new ScaleMuleApiError(error);
2726
3320
  }
2727
3321
  const data = responseData?.data !== void 0 ? responseData.data : responseData;
@@ -3243,8 +3837,16 @@ function createAuthRoutes(config = {}) {
3243
3837
  // ==================== Logout ====================
3244
3838
  case "logout": {
3245
3839
  const session = await getSession();
3840
+ let rotated = null;
3246
3841
  if (session) {
3247
- await sm.auth.logout(session.sessionToken);
3842
+ try {
3843
+ await sm.auth.logout(session.sessionToken, {
3844
+ onTokenRotated: (newToken) => {
3845
+ rotated = newToken;
3846
+ }
3847
+ });
3848
+ } catch {
3849
+ }
3248
3850
  }
3249
3851
  if (config.onLogout) {
3250
3852
  await config.onLogout();
@@ -3257,7 +3859,7 @@ function createAuthRoutes(config = {}) {
3257
3859
  if (!email) {
3258
3860
  return errorResponse("VALIDATION_ERROR", "Email required", 400);
3259
3861
  }
3260
- const result2 = await sm.auth.forgotPassword(email, { clientContext });
3862
+ const result = await sm.auth.forgotPassword(email, { clientContext });
3261
3863
  return successResponse({ message: "If an account exists, a reset email has been sent" });
3262
3864
  }
3263
3865
  // ==================== Reset Password ====================
@@ -3309,6 +3911,7 @@ function createAuthRoutes(config = {}) {
3309
3911
  case "resend-verification": {
3310
3912
  const { email } = body;
3311
3913
  const session = await getSession();
3914
+ let rotated = null;
3312
3915
  if (email) {
3313
3916
  try {
3314
3917
  await sm.auth.resendVerification(email);
@@ -3326,7 +3929,11 @@ function createAuthRoutes(config = {}) {
3326
3929
  return errorResponse("UNAUTHORIZED", "Email or session required", 401);
3327
3930
  }
3328
3931
  try {
3329
- await sm.auth.resendVerification(session.sessionToken);
3932
+ await sm.auth.resendVerification(session.sessionToken, {
3933
+ onTokenRotated: (newToken) => {
3934
+ rotated = newToken;
3935
+ }
3936
+ });
3330
3937
  } catch (err) {
3331
3938
  const apiErr = err instanceof ScaleMuleApiError ? err : null;
3332
3939
  return errorResponse(
@@ -3335,6 +3942,14 @@ function createAuthRoutes(config = {}) {
3335
3942
  400
3336
3943
  );
3337
3944
  }
3945
+ if (rotated) {
3946
+ return withRefreshedSession(
3947
+ rotated,
3948
+ session.userId,
3949
+ { success: true, data: { message: "Verification email sent" } },
3950
+ cookieOptions
3951
+ );
3952
+ }
3338
3953
  return successResponse({ message: "Verification email sent" });
3339
3954
  }
3340
3955
  // ==================== Refresh Session ====================
@@ -3369,11 +3984,17 @@ function createAuthRoutes(config = {}) {
3369
3984
  if (!current_password || !new_password) {
3370
3985
  return errorResponse("VALIDATION_ERROR", "Current and new password required", 400);
3371
3986
  }
3987
+ let rotated = null;
3372
3988
  try {
3373
3989
  await sm.user.changePassword(
3374
3990
  session.sessionToken,
3375
3991
  current_password,
3376
- new_password
3992
+ new_password,
3993
+ {
3994
+ onTokenRotated: (newToken) => {
3995
+ rotated = newToken;
3996
+ }
3997
+ }
3377
3998
  );
3378
3999
  } catch (err) {
3379
4000
  const apiErr = err instanceof ScaleMuleApiError ? err : null;
@@ -3383,6 +4004,14 @@ function createAuthRoutes(config = {}) {
3383
4004
  400
3384
4005
  );
3385
4006
  }
4007
+ if (rotated) {
4008
+ return withRefreshedSession(
4009
+ rotated,
4010
+ session.userId,
4011
+ { success: true, data: { message: "Password changed successfully" } },
4012
+ cookieOptions
4013
+ );
4014
+ }
3386
4015
  return successResponse({ message: "Password changed successfully" });
3387
4016
  }
3388
4017
  // ==================== Switch Account ====================
@@ -3463,14 +4092,27 @@ function createAuthRoutes(config = {}) {
3463
4092
  return withNorm(errorResponse("UNAUTHORIZED", "Authentication required", 401));
3464
4093
  }
3465
4094
  let userData;
4095
+ let rotated = null;
3466
4096
  try {
3467
- userData = await sm.auth.me(session.sessionToken);
4097
+ userData = await sm.auth.me(session.sessionToken, {
4098
+ onTokenRotated: (newToken) => {
4099
+ rotated = newToken;
4100
+ }
4101
+ });
3468
4102
  } catch {
3469
4103
  return withNorm(clearSession(
3470
4104
  { error: { code: "SESSION_EXPIRED", message: "Session expired" } },
3471
4105
  cookieOptions
3472
4106
  ));
3473
4107
  }
4108
+ if (rotated) {
4109
+ return withNorm(withRefreshedSession(
4110
+ rotated,
4111
+ session.userId,
4112
+ { user: userData, sessionToken: rotated, userId: session.userId },
4113
+ cookieOptions
4114
+ ));
4115
+ }
3474
4116
  return withNorm(successResponse({ user: userData, sessionToken: session.sessionToken, userId: session.userId }));
3475
4117
  }
3476
4118
  // ==================== Get Session Status ====================
@@ -3549,8 +4191,13 @@ function createAuthRoutes(config = {}) {
3549
4191
  const body = await request.json().catch(() => ({}));
3550
4192
  const { full_name, avatar_url } = body;
3551
4193
  let updatedUser;
4194
+ let rotated = null;
3552
4195
  try {
3553
- updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url });
4196
+ updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url }, {
4197
+ onTokenRotated: (newToken) => {
4198
+ rotated = newToken;
4199
+ }
4200
+ });
3554
4201
  } catch (err) {
3555
4202
  const apiErr = err instanceof ScaleMuleApiError ? err : null;
3556
4203
  return errorResponse(
@@ -3559,6 +4206,14 @@ function createAuthRoutes(config = {}) {
3559
4206
  400
3560
4207
  );
3561
4208
  }
4209
+ if (rotated) {
4210
+ return withRefreshedSession(
4211
+ rotated,
4212
+ session.userId,
4213
+ { success: true, data: { user: updatedUser } },
4214
+ cookieOptions
4215
+ );
4216
+ }
3562
4217
  return successResponse({ user: updatedUser });
3563
4218
  }
3564
4219
  default:
@@ -3844,8 +4499,10 @@ function getLedverySession(request) {
3844
4499
  if (!raw) return null;
3845
4500
  try {
3846
4501
  const parsed = JSON.parse(raw);
4502
+ const accessToken = getCookie(request, SM_LEDVERY_ACCESS_TOKEN_COOKIE);
3847
4503
  return {
3848
4504
  idToken: parsed.idToken || "",
4505
+ accessToken,
3849
4506
  claims: parsed.claims,
3850
4507
  expiresAt: parsed.expiresAt
3851
4508
  };
@@ -3947,9 +4604,11 @@ function createLedveryRoutes(config) {
3947
4604
  async function handleLogin(request) {
3948
4605
  const url = new URL(request.url);
3949
4606
  const returnTo = url.searchParams.get("returnTo");
4607
+ const provider = url.searchParams.get("provider");
3950
4608
  const validatedReturnTo = validateSafeRedirect(returnTo, { defaultPath: postLoginRedirect });
3951
4609
  const authResult = await client.createAuthorizationUrl({
3952
- scope: defaultScope
4610
+ scope: defaultScope,
4611
+ extraParams: provider ? { upstream: provider } : void 0
3953
4612
  });
3954
4613
  const response = new Response(null, {
3955
4614
  status: 302,
@@ -4349,9 +5008,9 @@ var CODE_TO_STATUS = {
4349
5008
  function errorCodeToStatus(code) {
4350
5009
  return CODE_TO_STATUS[code.toLowerCase()] || 400;
4351
5010
  }
4352
- function unwrap(result2) {
4353
- if (result2 !== null && result2 !== void 0 && typeof result2 === "object" && ("success" in result2 || "error" in result2) && "data" in result2) {
4354
- const envelope = result2;
5011
+ function unwrap(result) {
5012
+ if (result !== null && result !== void 0 && typeof result === "object" && ("success" in result || "error" in result) && "data" in result) {
5013
+ const envelope = result;
4355
5014
  if (envelope.error || envelope.success === false) {
4356
5015
  const err = envelope.error;
4357
5016
  const code = err?.code || "UNKNOWN_ERROR";
@@ -4365,7 +5024,7 @@ function unwrap(result2) {
4365
5024
  }
4366
5025
  return envelope.data;
4367
5026
  }
4368
- return result2;
5027
+ return result;
4369
5028
  }
4370
5029
 
4371
5030
  // src/server/handler.ts
@@ -4392,10 +5051,10 @@ function apiHandler(handler, options) {
4392
5051
  searchParams: request.nextUrl.searchParams,
4393
5052
  session
4394
5053
  };
4395
- const result2 = await handler(request, context);
4396
- if (result2 instanceof Response) return result2;
4397
- if (result2 !== void 0) {
4398
- return Response.json({ success: true, data: result2 }, { status: 200 });
5054
+ const result = await handler(request, context);
5055
+ if (result instanceof Response) return result;
5056
+ if (result !== void 0) {
5057
+ return Response.json({ success: true, data: result }, { status: 200 });
4399
5058
  }
4400
5059
  return new Response(null, { status: 204 });
4401
5060
  } catch (error) {
@@ -4442,14 +5101,14 @@ function parseWebhookEvent(payload) {
4442
5101
  }
4443
5102
  async function registerVideoWebhook(url, options) {
4444
5103
  const sm = createServerClient(options?.clientConfig);
4445
- const result2 = await sm.webhooks.create({
5104
+ const result = await sm.webhooks.create({
4446
5105
  webhook_name: options?.name || "Video Status Webhook",
4447
5106
  url,
4448
5107
  events: options?.events || ["video.ready", "video.failed"]
4449
5108
  });
4450
5109
  return {
4451
- id: result2.id,
4452
- secret: result2.secret
5110
+ id: result.id,
5111
+ secret: result.secret
4453
5112
  };
4454
5113
  }
4455
5114
  function createWebhookRoutes(config = {}) {
@@ -4537,517 +5196,8 @@ function createWebhookHandler(config = {}) {
4537
5196
  };
4538
5197
  }
4539
5198
 
4540
- // node_modules/@scalemule/sdk/dist/flags/server.mjs
4541
- var import_semver = __toESM(require_semver2());
4542
- function hashToBucket(flagKey, identifier, salt) {
4543
- const hash = createHash("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
4544
- return hash.readUInt32BE(0) % 1e4;
4545
- }
4546
- function allConditionsMatch(conditions, context) {
4547
- return conditions.every((c) => conditionMatches(c, context));
4548
- }
4549
- function conditionMatches(condition, context) {
4550
- const attributeValue = getAttribute(context, condition.attribute);
4551
- const op = condition.operator;
4552
- if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
4553
- if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
4554
- if (attributeValue === void 0 || attributeValue === null) return false;
4555
- switch (op) {
4556
- case "eq":
4557
- return compareValues(attributeValue, condition.value) === 0;
4558
- case "neq":
4559
- return compareValues(attributeValue, condition.value) !== 0;
4560
- case "in":
4561
- return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
4562
- case "not_in":
4563
- return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
4564
- case "contains":
4565
- return containsValue(attributeValue, condition.value);
4566
- case "starts_with":
4567
- return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
4568
- case "ends_with":
4569
- return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
4570
- case "gt":
4571
- return compareValues(attributeValue, condition.value) === 1;
4572
- case "gte": {
4573
- const cmp = compareValues(attributeValue, condition.value);
4574
- return cmp === 1 || cmp === 0;
4575
- }
4576
- case "lt":
4577
- return compareValues(attributeValue, condition.value) === -1;
4578
- case "lte": {
4579
- const cmp = compareValues(attributeValue, condition.value);
4580
- return cmp === -1 || cmp === 0;
4581
- }
4582
- case "regex": {
4583
- if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
4584
- try {
4585
- return new RegExp(condition.value).test(attributeValue);
4586
- } catch {
4587
- return false;
4588
- }
4589
- }
4590
- case "semver_eq":
4591
- return semverCmp(attributeValue, condition.value) === 0;
4592
- case "semver_neq":
4593
- return semverCmp(attributeValue, condition.value) !== 0;
4594
- case "semver_gt":
4595
- return semverCmp(attributeValue, condition.value) === 1;
4596
- case "semver_gte": {
4597
- const cmp = semverCmp(attributeValue, condition.value);
4598
- return cmp === 1 || cmp === 0;
4599
- }
4600
- case "semver_lt":
4601
- return semverCmp(attributeValue, condition.value) === -1;
4602
- case "semver_lte": {
4603
- const cmp = semverCmp(attributeValue, condition.value);
4604
- return cmp === -1 || cmp === 0;
4605
- }
4606
- default:
4607
- return false;
4608
- }
4609
- }
4610
- function getAttribute(context, key) {
4611
- switch (key) {
4612
- case "user_id":
4613
- return context.user_id;
4614
- case "email":
4615
- return context.email;
4616
- case "session_id":
4617
- return context.session_id;
4618
- case "ip_address":
4619
- return context.ip_address;
4620
- case "user_agent":
4621
- return context.user_agent;
4622
- case "timestamp":
4623
- return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
4624
- default:
4625
- return context[key];
4626
- }
4627
- }
4628
- function candidateValues(condition) {
4629
- if (condition.values && condition.values.length > 0) return condition.values;
4630
- if (condition.value === void 0 || condition.value === null) return [];
4631
- if (Array.isArray(condition.value)) return condition.value;
4632
- return [condition.value];
4633
- }
4634
- function compareValues(actual, expected) {
4635
- if (expected === void 0 || expected === null) return null;
4636
- const numA = toNumber(actual);
4637
- const numB = toNumber(expected);
4638
- if (numA !== null && numB !== null) {
4639
- if (numA < numB) return -1;
4640
- if (numA > numB) return 1;
4641
- return 0;
4642
- }
4643
- if (typeof actual === "boolean" && typeof expected === "boolean") {
4644
- if (actual === expected) return 0;
4645
- return actual ? 1 : -1;
4646
- }
4647
- const strA = toString(actual);
4648
- const strB = toString(expected);
4649
- if (strA !== null && strB !== null) {
4650
- if (strA < strB) return -1;
4651
- if (strA > strB) return 1;
4652
- return 0;
4653
- }
4654
- return null;
4655
- }
4656
- function containsValue(actual, expected) {
4657
- if (expected === void 0 || expected === null) return false;
4658
- if (Array.isArray(actual)) {
4659
- return actual.some((item) => compareValues(item, expected) === 0);
4660
- }
4661
- if (typeof actual === "string" && typeof expected === "string") {
4662
- return actual.includes(expected);
4663
- }
4664
- return false;
4665
- }
4666
- function toNumber(value) {
4667
- if (typeof value === "number") return value;
4668
- if (typeof value === "string") {
4669
- const n = Number(value);
4670
- return isNaN(n) ? null : n;
4671
- }
4672
- return null;
4673
- }
4674
- function toString(value) {
4675
- if (typeof value === "string") return value;
4676
- return null;
4677
- }
4678
- function semverCmp(actual, expected) {
4679
- if (typeof actual !== "string" || typeof expected !== "string") return null;
4680
- try {
4681
- const a = (0, import_semver.parse)(actual);
4682
- const b = (0, import_semver.parse)(expected);
4683
- if (!a || !b) return null;
4684
- return (0, import_semver.compare)(a, b);
4685
- } catch {
4686
- return null;
4687
- }
4688
- }
4689
- function evaluateFlag(flag, config, context, segmentIndex) {
4690
- const effectiveDefault = flag.environment_default_value ?? flag.default_value;
4691
- if (flag.status !== "active") {
4692
- return result(flag, config.environment, effectiveDefault, "disabled");
4693
- }
4694
- if (!flag.environment_enabled) {
4695
- return result(flag, config.environment, effectiveDefault, "disabled");
4696
- }
4697
- const bucketIdentifier = getBucketIdentifier(context);
4698
- for (const rule of flag.rules) {
4699
- if (!rule.enabled) continue;
4700
- if (rule.segment_ids.length > 0) {
4701
- const segmentMatched = rule.segment_ids.some((segId) => {
4702
- const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
4703
- if (!segment) return false;
4704
- return userMatchesSegment(segment, context);
4705
- });
4706
- if (!segmentMatched) continue;
4707
- }
4708
- if (!allConditionsMatch(rule.conditions, context)) continue;
4709
- if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
4710
- const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
4711
- if (bucket >= rule.rollout_percentage) continue;
4712
- return {
4713
- flag_id: flag.flag_id,
4714
- flag_key: flag.flag_key,
4715
- environment: config.environment,
4716
- value: rule.serve_value,
4717
- reason: "rule_match",
4718
- matched_rule_id: rule.id,
4719
- variant_key: null,
4720
- bucket
4721
- };
4722
- }
4723
- return {
4724
- flag_id: flag.flag_id,
4725
- flag_key: flag.flag_key,
4726
- environment: config.environment,
4727
- value: rule.serve_value,
4728
- reason: "rule_match",
4729
- matched_rule_id: rule.id,
4730
- variant_key: null,
4731
- bucket: null
4732
- };
4733
- }
4734
- if (flag.variants.length > 0) {
4735
- const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
4736
- if (totalWeight > 0) {
4737
- const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
4738
- const scaled = Math.floor(bucket * totalWeight / 1e4);
4739
- let cursor = 0;
4740
- for (const variant of flag.variants) {
4741
- cursor += variant.weight;
4742
- if (scaled < cursor) {
4743
- return {
4744
- flag_id: flag.flag_id,
4745
- flag_key: flag.flag_key,
4746
- environment: config.environment,
4747
- value: variant.value,
4748
- reason: "variant",
4749
- matched_rule_id: null,
4750
- variant_key: variant.variant_key,
4751
- bucket
4752
- };
4753
- }
4754
- }
4755
- }
4756
- }
4757
- return result(flag, config.environment, effectiveDefault, "default");
4758
- }
4759
- function getBucketIdentifier(context) {
4760
- return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
4761
- }
4762
- function userMatchesSegment(segment, context) {
4763
- const identifiers = [context.user_id, context.email, context.session_id].filter(
4764
- (v) => v !== void 0 && v !== null
4765
- );
4766
- if (identifiers.some((id) => segment.excluded_users.includes(id))) {
4767
- return false;
4768
- }
4769
- if (identifiers.some((id) => segment.included_users.includes(id))) {
4770
- return true;
4771
- }
4772
- return allConditionsMatch(segment.conditions, context);
4773
- }
4774
- function result(flag, environment, value, reason) {
4775
- return {
4776
- flag_id: flag.flag_id,
4777
- flag_key: flag.flag_key,
4778
- environment,
4779
- value,
4780
- reason,
4781
- matched_rule_id: null,
4782
- variant_key: null,
4783
- bucket: null
4784
- };
4785
- }
4786
- var FlagClient = class {
4787
- constructor(options) {
4788
- this.config = null;
4789
- this.flagIndex = /* @__PURE__ */ new Map();
4790
- this.segmentIndex = /* @__PURE__ */ new Map();
4791
- this.lastETag = "";
4792
- this.streamState = "idle";
4793
- this.pollTimer = null;
4794
- this.reconnectTimer = null;
4795
- this.telemetryTimer = null;
4796
- this.abortController = null;
4797
- this.initPromise = null;
4798
- this.telemetryCounters = /* @__PURE__ */ new Map();
4799
- this.isShuttingDown = false;
4800
- this.streamConnectInFlight = false;
4801
- this.apiKey = options.apiKey;
4802
- this.environment = options.environment;
4803
- this.gatewayUrl = options.gatewayUrl;
4804
- }
4805
- async init() {
4806
- this.isShuttingDown = false;
4807
- if (this.config) return;
4808
- if (this.initPromise) return this.initPromise;
4809
- this.initPromise = this.doInit();
4810
- try {
4811
- await this.initPromise;
4812
- } finally {
4813
- this.initPromise = null;
4814
- }
4815
- }
4816
- async doInit() {
4817
- const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
4818
- headers: { "x-api-key": this.apiKey }
4819
- });
4820
- if (resp.status === 403) throw new Error("Secret API key required for /config");
4821
- if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
4822
- const json = await resp.json();
4823
- this.config = json.data;
4824
- this.buildIndexes();
4825
- this.lastETag = resp.headers.get("etag") || "";
4826
- this.connectStream();
4827
- this.startTelemetryFlush();
4828
- }
4829
- buildIndexes() {
4830
- this.flagIndex.clear();
4831
- this.segmentIndex.clear();
4832
- if (!this.config) return;
4833
- for (const flag of this.config.flags) {
4834
- this.flagIndex.set(flag.flag_key, flag);
4835
- }
4836
- for (const segment of this.config.segments) {
4837
- this.segmentIndex.set(segment.id, segment);
4838
- }
4839
- }
4840
- evaluate(flagKey, context) {
4841
- if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
4842
- const flagConfig = this.flagIndex.get(flagKey);
4843
- if (!flagConfig) {
4844
- return {
4845
- flag_id: "",
4846
- flag_key: flagKey,
4847
- environment: this.environment,
4848
- value: null,
4849
- reason: "not_found",
4850
- matched_rule_id: null,
4851
- variant_key: null,
4852
- bucket: null
4853
- };
4854
- }
4855
- const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
4856
- this.recordTelemetry(result2);
4857
- return result2;
4858
- }
4859
- evaluateBatch(flagKeys, context) {
4860
- if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
4861
- const results = {};
4862
- for (const key of flagKeys) {
4863
- const flagConfig = this.flagIndex.get(key);
4864
- if (flagConfig) {
4865
- const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
4866
- this.recordTelemetry(result2);
4867
- results[key] = result2;
4868
- }
4869
- }
4870
- return results;
4871
- }
4872
- async shutdown() {
4873
- this.isShuttingDown = true;
4874
- this.streamState = "idle";
4875
- this.abortController?.abort();
4876
- this.abortController = null;
4877
- if (this.pollTimer) {
4878
- clearInterval(this.pollTimer);
4879
- this.pollTimer = null;
4880
- }
4881
- if (this.reconnectTimer) {
4882
- clearInterval(this.reconnectTimer);
4883
- this.reconnectTimer = null;
4884
- }
4885
- if (this.telemetryTimer) {
4886
- clearInterval(this.telemetryTimer);
4887
- this.telemetryTimer = null;
4888
- }
4889
- await this.flushTelemetry();
4890
- }
4891
- // ======== SSE Streaming ========
4892
- async connectStream() {
4893
- if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
4894
- this.streamConnectInFlight = true;
4895
- this.abortController?.abort();
4896
- const abortController = new AbortController();
4897
- this.abortController = abortController;
4898
- const shouldResumePolling = this.streamState !== "polling";
4899
- let startPolling = shouldResumePolling;
4900
- try {
4901
- const resp = await fetch(
4902
- `${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
4903
- {
4904
- headers: {
4905
- "x-api-key": this.apiKey,
4906
- "Last-Event-ID": String(this.config?.version ?? 0)
4907
- },
4908
- signal: abortController.signal
4909
- }
4910
- );
4911
- if (resp.ok && resp.body) {
4912
- this.streamState = "streaming";
4913
- this.stopPolling();
4914
- startPolling = false;
4915
- const reader = resp.body.getReader();
4916
- const decoder = new TextDecoder();
4917
- let buffer = "";
4918
- while (true) {
4919
- const { done, value } = await reader.read();
4920
- if (done) break;
4921
- buffer += decoder.decode(value, { stream: true });
4922
- let idx;
4923
- while ((idx = buffer.indexOf("\n\n")) !== -1) {
4924
- const frame = buffer.slice(0, idx);
4925
- buffer = buffer.slice(idx + 2);
4926
- this.handleSseFrame(frame);
4927
- }
4928
- }
4929
- if (this.streamState === "streaming") {
4930
- this.streamState = "idle";
4931
- startPolling = true;
4932
- }
4933
- }
4934
- } catch {
4935
- startPolling = !abortController.signal.aborted && shouldResumePolling;
4936
- } finally {
4937
- this.streamConnectInFlight = false;
4938
- }
4939
- if (!this.isShuttingDown && startPolling) {
4940
- this.startPolling();
4941
- }
4942
- }
4943
- handleSseFrame(frame) {
4944
- let eventType = "";
4945
- let data = "";
4946
- for (const line of frame.split("\n")) {
4947
- if (line.startsWith("event:")) eventType = line.slice(6).trim();
4948
- else if (line.startsWith("data:")) data += line.slice(5).trim();
4949
- }
4950
- if (eventType === "config" && data) {
4951
- try {
4952
- const parsed = JSON.parse(data);
4953
- const newConfig = parsed.data;
4954
- if (newConfig && newConfig.version !== void 0) {
4955
- this.config = newConfig;
4956
- this.buildIndexes();
4957
- }
4958
- } catch {
4959
- }
4960
- }
4961
- }
4962
- // ======== Polling Fallback ========
4963
- startPolling() {
4964
- if (this.streamState === "polling") return;
4965
- this.streamState = "polling";
4966
- this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
4967
- this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
4968
- }
4969
- stopPolling() {
4970
- if (this.pollTimer) {
4971
- clearInterval(this.pollTimer);
4972
- this.pollTimer = null;
4973
- }
4974
- if (this.reconnectTimer) {
4975
- clearInterval(this.reconnectTimer);
4976
- this.reconnectTimer = null;
4977
- }
4978
- }
4979
- async pollConfig() {
4980
- try {
4981
- const headers2 = { "x-api-key": this.apiKey };
4982
- if (this.lastETag) headers2["if-none-match"] = this.lastETag;
4983
- const resp = await fetch(
4984
- `${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
4985
- { headers: headers2 }
4986
- );
4987
- if (resp.status === 304) return;
4988
- if (!resp.ok) return;
4989
- const json = await resp.json();
4990
- this.config = json.data;
4991
- this.buildIndexes();
4992
- this.lastETag = resp.headers.get("etag") || "";
4993
- } catch {
4994
- }
4995
- }
4996
- // ======== Telemetry ========
4997
- recordTelemetry(evaluation) {
4998
- const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
4999
- const existing = this.telemetryCounters.get(key);
5000
- if (existing) {
5001
- existing.count++;
5002
- if (evaluation.value === true) existing.true_count++;
5003
- else if (evaluation.value === false) existing.false_count++;
5004
- } else {
5005
- this.telemetryCounters.set(key, {
5006
- flag_key: evaluation.flag_key,
5007
- flag_id: evaluation.flag_id,
5008
- reason: evaluation.reason,
5009
- count: 1,
5010
- true_count: evaluation.value === true ? 1 : 0,
5011
- false_count: evaluation.value === false ? 1 : 0
5012
- });
5013
- }
5014
- }
5015
- startTelemetryFlush() {
5016
- this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
5017
- }
5018
- async flushTelemetry() {
5019
- if (this.telemetryCounters.size === 0) return;
5020
- const evaluations = Array.from(this.telemetryCounters.values());
5021
- this.telemetryCounters.clear();
5022
- try {
5023
- await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
5024
- method: "POST",
5025
- headers: {
5026
- "Content-Type": "application/json",
5027
- "x-api-key": this.apiKey
5028
- },
5029
- body: JSON.stringify({
5030
- environment: this.environment,
5031
- evaluations
5032
- })
5033
- });
5034
- } catch {
5035
- for (const counter of evaluations) {
5036
- const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
5037
- const existing = this.telemetryCounters.get(key);
5038
- if (existing) {
5039
- existing.count += counter.count;
5040
- existing.true_count += counter.true_count;
5041
- existing.false_count += counter.false_count;
5042
- } else {
5043
- this.telemetryCounters.set(key, counter);
5044
- }
5045
- }
5046
- }
5047
- }
5048
- };
5049
-
5050
5199
  // src/server/bootstrap-flags.ts
5200
+ var import_server2 = __toESM(require_server());
5051
5201
  var _clients = /* @__PURE__ */ new Map();
5052
5202
  var _initPromises = /* @__PURE__ */ new Map();
5053
5203
  var _serverClient = null;
@@ -5075,7 +5225,7 @@ async function getFlagClient(environment) {
5075
5225
  const pending = _initPromises.get(key);
5076
5226
  if (pending) return pending;
5077
5227
  const promise = (async () => {
5078
- const client = new FlagClient({ apiKey, environment, gatewayUrl });
5228
+ const client = new import_server2.FlagClient({ apiKey, environment, gatewayUrl });
5079
5229
  await Promise.race([
5080
5230
  client.init(),
5081
5231
  new Promise(
@@ -5124,8 +5274,8 @@ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext =
5124
5274
  const clientIp = extractClientIp(hdrs);
5125
5275
  const context = { ...extraContext };
5126
5276
  if (clientIp) context.ip_address = clientIp;
5127
- const result2 = await getServerClient().flags.evaluateBatch(flagKeys, context, environment);
5128
- return result2 || {};
5277
+ const result = await getServerClient().flags.evaluateBatch(flagKeys, context, environment);
5278
+ return result || {};
5129
5279
  } catch {
5130
5280
  return {};
5131
5281
  }
@@ -5275,15 +5425,15 @@ async function getAppSecret(key) {
5275
5425
  }
5276
5426
  try {
5277
5427
  const client = createServerClient();
5278
- const result2 = await client.secrets.get(key);
5279
- if (!noCache && result2) {
5428
+ const result = await client.secrets.get(key);
5429
+ if (!noCache && result) {
5280
5430
  secretsCache[key] = {
5281
- value: result2.value,
5282
- version: result2.version,
5431
+ value: result.value,
5432
+ version: result.version,
5283
5433
  cachedAt: Date.now()
5284
5434
  };
5285
5435
  }
5286
- return result2?.value;
5436
+ return result?.value;
5287
5437
  } catch (error) {
5288
5438
  if (error instanceof ScaleMuleApiError && error.code === "SECRET_NOT_FOUND") {
5289
5439
  return void 0;
@@ -5334,17 +5484,17 @@ async function getBundle(key, resolve = true) {
5334
5484
  }
5335
5485
  try {
5336
5486
  const client = createServerClient();
5337
- const result2 = await client.bundles.get(key, resolve);
5338
- if (!noCache && result2) {
5487
+ const result = await client.bundles.get(key, resolve);
5488
+ if (!noCache && result) {
5339
5489
  bundlesCache[key] = {
5340
- type: result2.type,
5341
- data: result2.data,
5342
- version: result2.version,
5343
- inheritsFrom: result2.inherits_from,
5490
+ type: result.type,
5491
+ data: result.data,
5492
+ version: result.version,
5493
+ inheritsFrom: result.inherits_from,
5344
5494
  cachedAt: Date.now()
5345
5495
  };
5346
5496
  }
5347
- return result2?.data;
5497
+ return result?.data;
5348
5498
  } catch (error) {
5349
5499
  if (error instanceof ScaleMuleApiError && error.code === "BUNDLE_NOT_FOUND") {
5350
5500
  return void 0;