@scalemule/nextjs 0.1.31 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +113 -0
- package/dist/index.mjs +113 -0
- package/dist/server/index.js +673 -636
- package/dist/server/index.mjs +674 -637
- package/package.json +2 -2
package/dist/server/index.js
CHANGED
|
@@ -12,7 +12,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
12
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
13
|
var __getProtoOf = Object.getPrototypeOf;
|
|
14
14
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
-
var
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
21
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
16
22
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
17
23
|
};
|
|
18
24
|
var __copyProps = (to, from, except, desc) => {
|
|
@@ -28,13 +34,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
34
|
// file that has been converted to a CommonJS file using a Babel-
|
|
29
35
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
30
36
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
31
|
-
__defProp(target, "default", { value: mod, enumerable: true }) ,
|
|
37
|
+
!mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
32
38
|
mod
|
|
33
39
|
));
|
|
34
40
|
|
|
35
|
-
// node_modules/semver/internal/constants.js
|
|
41
|
+
// ../sdk/node_modules/semver/internal/constants.js
|
|
36
42
|
var require_constants = __commonJS({
|
|
37
|
-
"node_modules/semver/internal/constants.js"(exports$1, module) {
|
|
43
|
+
"../sdk/node_modules/semver/internal/constants.js"(exports$1, module) {
|
|
38
44
|
var SEMVER_SPEC_VERSION = "2.0.0";
|
|
39
45
|
var MAX_LENGTH = 256;
|
|
40
46
|
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */
|
|
@@ -63,18 +69,18 @@ var require_constants = __commonJS({
|
|
|
63
69
|
}
|
|
64
70
|
});
|
|
65
71
|
|
|
66
|
-
// node_modules/semver/internal/debug.js
|
|
72
|
+
// ../sdk/node_modules/semver/internal/debug.js
|
|
67
73
|
var require_debug = __commonJS({
|
|
68
|
-
"node_modules/semver/internal/debug.js"(exports$1, module) {
|
|
74
|
+
"../sdk/node_modules/semver/internal/debug.js"(exports$1, module) {
|
|
69
75
|
var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
|
|
70
76
|
};
|
|
71
77
|
module.exports = debug;
|
|
72
78
|
}
|
|
73
79
|
});
|
|
74
80
|
|
|
75
|
-
// node_modules/semver/internal/re.js
|
|
81
|
+
// ../sdk/node_modules/semver/internal/re.js
|
|
76
82
|
var require_re = __commonJS({
|
|
77
|
-
"node_modules/semver/internal/re.js"(exports$1, module) {
|
|
83
|
+
"../sdk/node_modules/semver/internal/re.js"(exports$1, module) {
|
|
78
84
|
var {
|
|
79
85
|
MAX_SAFE_COMPONENT_LENGTH,
|
|
80
86
|
MAX_SAFE_BUILD_LENGTH,
|
|
@@ -159,9 +165,9 @@ var require_re = __commonJS({
|
|
|
159
165
|
}
|
|
160
166
|
});
|
|
161
167
|
|
|
162
|
-
// node_modules/semver/internal/parse-options.js
|
|
168
|
+
// ../sdk/node_modules/semver/internal/parse-options.js
|
|
163
169
|
var require_parse_options = __commonJS({
|
|
164
|
-
"node_modules/semver/internal/parse-options.js"(exports$1, module) {
|
|
170
|
+
"../sdk/node_modules/semver/internal/parse-options.js"(exports$1, module) {
|
|
165
171
|
var looseOption = Object.freeze({ loose: true });
|
|
166
172
|
var emptyOpts = Object.freeze({});
|
|
167
173
|
var parseOptions = (options) => {
|
|
@@ -177,9 +183,9 @@ var require_parse_options = __commonJS({
|
|
|
177
183
|
}
|
|
178
184
|
});
|
|
179
185
|
|
|
180
|
-
// node_modules/semver/internal/identifiers.js
|
|
186
|
+
// ../sdk/node_modules/semver/internal/identifiers.js
|
|
181
187
|
var require_identifiers = __commonJS({
|
|
182
|
-
"node_modules/semver/internal/identifiers.js"(exports$1, module) {
|
|
188
|
+
"../sdk/node_modules/semver/internal/identifiers.js"(exports$1, module) {
|
|
183
189
|
var numeric = /^[0-9]+$/;
|
|
184
190
|
var compareIdentifiers = (a, b) => {
|
|
185
191
|
if (typeof a === "number" && typeof b === "number") {
|
|
@@ -201,9 +207,9 @@ var require_identifiers = __commonJS({
|
|
|
201
207
|
}
|
|
202
208
|
});
|
|
203
209
|
|
|
204
|
-
// node_modules/semver/classes/semver.js
|
|
210
|
+
// ../sdk/node_modules/semver/classes/semver.js
|
|
205
211
|
var require_semver = __commonJS({
|
|
206
|
-
"node_modules/semver/classes/semver.js"(exports$1, module) {
|
|
212
|
+
"../sdk/node_modules/semver/classes/semver.js"(exports$1, module) {
|
|
207
213
|
var debug = require_debug();
|
|
208
214
|
var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
|
|
209
215
|
var { safeRe: re, t } = require_re();
|
|
@@ -479,9 +485,9 @@ var require_semver = __commonJS({
|
|
|
479
485
|
}
|
|
480
486
|
});
|
|
481
487
|
|
|
482
|
-
// node_modules/semver/functions/parse.js
|
|
488
|
+
// ../sdk/node_modules/semver/functions/parse.js
|
|
483
489
|
var require_parse = __commonJS({
|
|
484
|
-
"node_modules/semver/functions/parse.js"(exports$1, module) {
|
|
490
|
+
"../sdk/node_modules/semver/functions/parse.js"(exports$1, module) {
|
|
485
491
|
var SemVer = require_semver();
|
|
486
492
|
var parse = (version, options, throwErrors = false) => {
|
|
487
493
|
if (version instanceof SemVer) {
|
|
@@ -500,9 +506,9 @@ var require_parse = __commonJS({
|
|
|
500
506
|
}
|
|
501
507
|
});
|
|
502
508
|
|
|
503
|
-
// node_modules/semver/functions/valid.js
|
|
509
|
+
// ../sdk/node_modules/semver/functions/valid.js
|
|
504
510
|
var require_valid = __commonJS({
|
|
505
|
-
"node_modules/semver/functions/valid.js"(exports$1, module) {
|
|
511
|
+
"../sdk/node_modules/semver/functions/valid.js"(exports$1, module) {
|
|
506
512
|
var parse = require_parse();
|
|
507
513
|
var valid = (version, options) => {
|
|
508
514
|
const v = parse(version, options);
|
|
@@ -512,9 +518,9 @@ var require_valid = __commonJS({
|
|
|
512
518
|
}
|
|
513
519
|
});
|
|
514
520
|
|
|
515
|
-
// node_modules/semver/functions/clean.js
|
|
521
|
+
// ../sdk/node_modules/semver/functions/clean.js
|
|
516
522
|
var require_clean = __commonJS({
|
|
517
|
-
"node_modules/semver/functions/clean.js"(exports$1, module) {
|
|
523
|
+
"../sdk/node_modules/semver/functions/clean.js"(exports$1, module) {
|
|
518
524
|
var parse = require_parse();
|
|
519
525
|
var clean = (version, options) => {
|
|
520
526
|
const s = parse(version.trim().replace(/^[=v]+/, ""), options);
|
|
@@ -524,9 +530,9 @@ var require_clean = __commonJS({
|
|
|
524
530
|
}
|
|
525
531
|
});
|
|
526
532
|
|
|
527
|
-
// node_modules/semver/functions/inc.js
|
|
533
|
+
// ../sdk/node_modules/semver/functions/inc.js
|
|
528
534
|
var require_inc = __commonJS({
|
|
529
|
-
"node_modules/semver/functions/inc.js"(exports$1, module) {
|
|
535
|
+
"../sdk/node_modules/semver/functions/inc.js"(exports$1, module) {
|
|
530
536
|
var SemVer = require_semver();
|
|
531
537
|
var inc = (version, release, options, identifier, identifierBase) => {
|
|
532
538
|
if (typeof options === "string") {
|
|
@@ -547,9 +553,9 @@ var require_inc = __commonJS({
|
|
|
547
553
|
}
|
|
548
554
|
});
|
|
549
555
|
|
|
550
|
-
// node_modules/semver/functions/diff.js
|
|
556
|
+
// ../sdk/node_modules/semver/functions/diff.js
|
|
551
557
|
var require_diff = __commonJS({
|
|
552
|
-
"node_modules/semver/functions/diff.js"(exports$1, module) {
|
|
558
|
+
"../sdk/node_modules/semver/functions/diff.js"(exports$1, module) {
|
|
553
559
|
var parse = require_parse();
|
|
554
560
|
var diff = (version1, version2) => {
|
|
555
561
|
const v1 = parse(version1, null, true);
|
|
@@ -590,36 +596,36 @@ var require_diff = __commonJS({
|
|
|
590
596
|
}
|
|
591
597
|
});
|
|
592
598
|
|
|
593
|
-
// node_modules/semver/functions/major.js
|
|
599
|
+
// ../sdk/node_modules/semver/functions/major.js
|
|
594
600
|
var require_major = __commonJS({
|
|
595
|
-
"node_modules/semver/functions/major.js"(exports$1, module) {
|
|
601
|
+
"../sdk/node_modules/semver/functions/major.js"(exports$1, module) {
|
|
596
602
|
var SemVer = require_semver();
|
|
597
603
|
var major = (a, loose) => new SemVer(a, loose).major;
|
|
598
604
|
module.exports = major;
|
|
599
605
|
}
|
|
600
606
|
});
|
|
601
607
|
|
|
602
|
-
// node_modules/semver/functions/minor.js
|
|
608
|
+
// ../sdk/node_modules/semver/functions/minor.js
|
|
603
609
|
var require_minor = __commonJS({
|
|
604
|
-
"node_modules/semver/functions/minor.js"(exports$1, module) {
|
|
610
|
+
"../sdk/node_modules/semver/functions/minor.js"(exports$1, module) {
|
|
605
611
|
var SemVer = require_semver();
|
|
606
612
|
var minor = (a, loose) => new SemVer(a, loose).minor;
|
|
607
613
|
module.exports = minor;
|
|
608
614
|
}
|
|
609
615
|
});
|
|
610
616
|
|
|
611
|
-
// node_modules/semver/functions/patch.js
|
|
617
|
+
// ../sdk/node_modules/semver/functions/patch.js
|
|
612
618
|
var require_patch = __commonJS({
|
|
613
|
-
"node_modules/semver/functions/patch.js"(exports$1, module) {
|
|
619
|
+
"../sdk/node_modules/semver/functions/patch.js"(exports$1, module) {
|
|
614
620
|
var SemVer = require_semver();
|
|
615
621
|
var patch = (a, loose) => new SemVer(a, loose).patch;
|
|
616
622
|
module.exports = patch;
|
|
617
623
|
}
|
|
618
624
|
});
|
|
619
625
|
|
|
620
|
-
// node_modules/semver/functions/prerelease.js
|
|
626
|
+
// ../sdk/node_modules/semver/functions/prerelease.js
|
|
621
627
|
var require_prerelease = __commonJS({
|
|
622
|
-
"node_modules/semver/functions/prerelease.js"(exports$1, module) {
|
|
628
|
+
"../sdk/node_modules/semver/functions/prerelease.js"(exports$1, module) {
|
|
623
629
|
var parse = require_parse();
|
|
624
630
|
var prerelease = (version, options) => {
|
|
625
631
|
const parsed = parse(version, options);
|
|
@@ -629,36 +635,36 @@ var require_prerelease = __commonJS({
|
|
|
629
635
|
}
|
|
630
636
|
});
|
|
631
637
|
|
|
632
|
-
// node_modules/semver/functions/compare.js
|
|
638
|
+
// ../sdk/node_modules/semver/functions/compare.js
|
|
633
639
|
var require_compare = __commonJS({
|
|
634
|
-
"node_modules/semver/functions/compare.js"(exports$1, module) {
|
|
640
|
+
"../sdk/node_modules/semver/functions/compare.js"(exports$1, module) {
|
|
635
641
|
var SemVer = require_semver();
|
|
636
642
|
var compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
|
|
637
643
|
module.exports = compare;
|
|
638
644
|
}
|
|
639
645
|
});
|
|
640
646
|
|
|
641
|
-
// node_modules/semver/functions/rcompare.js
|
|
647
|
+
// ../sdk/node_modules/semver/functions/rcompare.js
|
|
642
648
|
var require_rcompare = __commonJS({
|
|
643
|
-
"node_modules/semver/functions/rcompare.js"(exports$1, module) {
|
|
649
|
+
"../sdk/node_modules/semver/functions/rcompare.js"(exports$1, module) {
|
|
644
650
|
var compare = require_compare();
|
|
645
651
|
var rcompare = (a, b, loose) => compare(b, a, loose);
|
|
646
652
|
module.exports = rcompare;
|
|
647
653
|
}
|
|
648
654
|
});
|
|
649
655
|
|
|
650
|
-
// node_modules/semver/functions/compare-loose.js
|
|
656
|
+
// ../sdk/node_modules/semver/functions/compare-loose.js
|
|
651
657
|
var require_compare_loose = __commonJS({
|
|
652
|
-
"node_modules/semver/functions/compare-loose.js"(exports$1, module) {
|
|
658
|
+
"../sdk/node_modules/semver/functions/compare-loose.js"(exports$1, module) {
|
|
653
659
|
var compare = require_compare();
|
|
654
660
|
var compareLoose = (a, b) => compare(a, b, true);
|
|
655
661
|
module.exports = compareLoose;
|
|
656
662
|
}
|
|
657
663
|
});
|
|
658
664
|
|
|
659
|
-
// node_modules/semver/functions/compare-build.js
|
|
665
|
+
// ../sdk/node_modules/semver/functions/compare-build.js
|
|
660
666
|
var require_compare_build = __commonJS({
|
|
661
|
-
"node_modules/semver/functions/compare-build.js"(exports$1, module) {
|
|
667
|
+
"../sdk/node_modules/semver/functions/compare-build.js"(exports$1, module) {
|
|
662
668
|
var SemVer = require_semver();
|
|
663
669
|
var compareBuild = (a, b, loose) => {
|
|
664
670
|
const versionA = new SemVer(a, loose);
|
|
@@ -669,81 +675,81 @@ var require_compare_build = __commonJS({
|
|
|
669
675
|
}
|
|
670
676
|
});
|
|
671
677
|
|
|
672
|
-
// node_modules/semver/functions/sort.js
|
|
678
|
+
// ../sdk/node_modules/semver/functions/sort.js
|
|
673
679
|
var require_sort = __commonJS({
|
|
674
|
-
"node_modules/semver/functions/sort.js"(exports$1, module) {
|
|
680
|
+
"../sdk/node_modules/semver/functions/sort.js"(exports$1, module) {
|
|
675
681
|
var compareBuild = require_compare_build();
|
|
676
682
|
var sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose));
|
|
677
683
|
module.exports = sort;
|
|
678
684
|
}
|
|
679
685
|
});
|
|
680
686
|
|
|
681
|
-
// node_modules/semver/functions/rsort.js
|
|
687
|
+
// ../sdk/node_modules/semver/functions/rsort.js
|
|
682
688
|
var require_rsort = __commonJS({
|
|
683
|
-
"node_modules/semver/functions/rsort.js"(exports$1, module) {
|
|
689
|
+
"../sdk/node_modules/semver/functions/rsort.js"(exports$1, module) {
|
|
684
690
|
var compareBuild = require_compare_build();
|
|
685
691
|
var rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose));
|
|
686
692
|
module.exports = rsort;
|
|
687
693
|
}
|
|
688
694
|
});
|
|
689
695
|
|
|
690
|
-
// node_modules/semver/functions/gt.js
|
|
696
|
+
// ../sdk/node_modules/semver/functions/gt.js
|
|
691
697
|
var require_gt = __commonJS({
|
|
692
|
-
"node_modules/semver/functions/gt.js"(exports$1, module) {
|
|
698
|
+
"../sdk/node_modules/semver/functions/gt.js"(exports$1, module) {
|
|
693
699
|
var compare = require_compare();
|
|
694
700
|
var gt = (a, b, loose) => compare(a, b, loose) > 0;
|
|
695
701
|
module.exports = gt;
|
|
696
702
|
}
|
|
697
703
|
});
|
|
698
704
|
|
|
699
|
-
// node_modules/semver/functions/lt.js
|
|
705
|
+
// ../sdk/node_modules/semver/functions/lt.js
|
|
700
706
|
var require_lt = __commonJS({
|
|
701
|
-
"node_modules/semver/functions/lt.js"(exports$1, module) {
|
|
707
|
+
"../sdk/node_modules/semver/functions/lt.js"(exports$1, module) {
|
|
702
708
|
var compare = require_compare();
|
|
703
709
|
var lt = (a, b, loose) => compare(a, b, loose) < 0;
|
|
704
710
|
module.exports = lt;
|
|
705
711
|
}
|
|
706
712
|
});
|
|
707
713
|
|
|
708
|
-
// node_modules/semver/functions/eq.js
|
|
714
|
+
// ../sdk/node_modules/semver/functions/eq.js
|
|
709
715
|
var require_eq = __commonJS({
|
|
710
|
-
"node_modules/semver/functions/eq.js"(exports$1, module) {
|
|
716
|
+
"../sdk/node_modules/semver/functions/eq.js"(exports$1, module) {
|
|
711
717
|
var compare = require_compare();
|
|
712
718
|
var eq = (a, b, loose) => compare(a, b, loose) === 0;
|
|
713
719
|
module.exports = eq;
|
|
714
720
|
}
|
|
715
721
|
});
|
|
716
722
|
|
|
717
|
-
// node_modules/semver/functions/neq.js
|
|
723
|
+
// ../sdk/node_modules/semver/functions/neq.js
|
|
718
724
|
var require_neq = __commonJS({
|
|
719
|
-
"node_modules/semver/functions/neq.js"(exports$1, module) {
|
|
725
|
+
"../sdk/node_modules/semver/functions/neq.js"(exports$1, module) {
|
|
720
726
|
var compare = require_compare();
|
|
721
727
|
var neq = (a, b, loose) => compare(a, b, loose) !== 0;
|
|
722
728
|
module.exports = neq;
|
|
723
729
|
}
|
|
724
730
|
});
|
|
725
731
|
|
|
726
|
-
// node_modules/semver/functions/gte.js
|
|
732
|
+
// ../sdk/node_modules/semver/functions/gte.js
|
|
727
733
|
var require_gte = __commonJS({
|
|
728
|
-
"node_modules/semver/functions/gte.js"(exports$1, module) {
|
|
734
|
+
"../sdk/node_modules/semver/functions/gte.js"(exports$1, module) {
|
|
729
735
|
var compare = require_compare();
|
|
730
736
|
var gte = (a, b, loose) => compare(a, b, loose) >= 0;
|
|
731
737
|
module.exports = gte;
|
|
732
738
|
}
|
|
733
739
|
});
|
|
734
740
|
|
|
735
|
-
// node_modules/semver/functions/lte.js
|
|
741
|
+
// ../sdk/node_modules/semver/functions/lte.js
|
|
736
742
|
var require_lte = __commonJS({
|
|
737
|
-
"node_modules/semver/functions/lte.js"(exports$1, module) {
|
|
743
|
+
"../sdk/node_modules/semver/functions/lte.js"(exports$1, module) {
|
|
738
744
|
var compare = require_compare();
|
|
739
745
|
var lte = (a, b, loose) => compare(a, b, loose) <= 0;
|
|
740
746
|
module.exports = lte;
|
|
741
747
|
}
|
|
742
748
|
});
|
|
743
749
|
|
|
744
|
-
// node_modules/semver/functions/cmp.js
|
|
750
|
+
// ../sdk/node_modules/semver/functions/cmp.js
|
|
745
751
|
var require_cmp = __commonJS({
|
|
746
|
-
"node_modules/semver/functions/cmp.js"(exports$1, module) {
|
|
752
|
+
"../sdk/node_modules/semver/functions/cmp.js"(exports$1, module) {
|
|
747
753
|
var eq = require_eq();
|
|
748
754
|
var neq = require_neq();
|
|
749
755
|
var gt = require_gt();
|
|
@@ -790,9 +796,9 @@ var require_cmp = __commonJS({
|
|
|
790
796
|
}
|
|
791
797
|
});
|
|
792
798
|
|
|
793
|
-
// node_modules/semver/functions/coerce.js
|
|
799
|
+
// ../sdk/node_modules/semver/functions/coerce.js
|
|
794
800
|
var require_coerce = __commonJS({
|
|
795
|
-
"node_modules/semver/functions/coerce.js"(exports$1, module) {
|
|
801
|
+
"../sdk/node_modules/semver/functions/coerce.js"(exports$1, module) {
|
|
796
802
|
var SemVer = require_semver();
|
|
797
803
|
var parse = require_parse();
|
|
798
804
|
var { safeRe: re, t } = require_re();
|
|
@@ -835,9 +841,9 @@ var require_coerce = __commonJS({
|
|
|
835
841
|
}
|
|
836
842
|
});
|
|
837
843
|
|
|
838
|
-
// node_modules/semver/internal/lrucache.js
|
|
844
|
+
// ../sdk/node_modules/semver/internal/lrucache.js
|
|
839
845
|
var require_lrucache = __commonJS({
|
|
840
|
-
"node_modules/semver/internal/lrucache.js"(exports$1, module) {
|
|
846
|
+
"../sdk/node_modules/semver/internal/lrucache.js"(exports$1, module) {
|
|
841
847
|
var LRUCache = class {
|
|
842
848
|
constructor() {
|
|
843
849
|
this.max = 1e3;
|
|
@@ -872,9 +878,9 @@ var require_lrucache = __commonJS({
|
|
|
872
878
|
}
|
|
873
879
|
});
|
|
874
880
|
|
|
875
|
-
// node_modules/semver/classes/range.js
|
|
881
|
+
// ../sdk/node_modules/semver/classes/range.js
|
|
876
882
|
var require_range = __commonJS({
|
|
877
|
-
"node_modules/semver/classes/range.js"(exports$1, module) {
|
|
883
|
+
"../sdk/node_modules/semver/classes/range.js"(exports$1, module) {
|
|
878
884
|
var SPACE_CHARACTERS = /\s+/g;
|
|
879
885
|
var Range = class _Range {
|
|
880
886
|
constructor(range, options) {
|
|
@@ -976,9 +982,9 @@ var require_range = __commonJS({
|
|
|
976
982
|
if (rangeMap.size > 1 && rangeMap.has("")) {
|
|
977
983
|
rangeMap.delete("");
|
|
978
984
|
}
|
|
979
|
-
const
|
|
980
|
-
cache.set(memoKey,
|
|
981
|
-
return
|
|
985
|
+
const result = [...rangeMap.values()];
|
|
986
|
+
cache.set(memoKey, result);
|
|
987
|
+
return result;
|
|
982
988
|
}
|
|
983
989
|
intersects(range, options) {
|
|
984
990
|
if (!(range instanceof _Range)) {
|
|
@@ -1032,16 +1038,16 @@ var require_range = __commonJS({
|
|
|
1032
1038
|
var isNullSet = (c) => c.value === "<0.0.0-0";
|
|
1033
1039
|
var isAny = (c) => c.value === "";
|
|
1034
1040
|
var isSatisfiable = (comparators, options) => {
|
|
1035
|
-
let
|
|
1041
|
+
let result = true;
|
|
1036
1042
|
const remainingComparators = comparators.slice();
|
|
1037
1043
|
let testComparator = remainingComparators.pop();
|
|
1038
|
-
while (
|
|
1039
|
-
|
|
1044
|
+
while (result && remainingComparators.length) {
|
|
1045
|
+
result = remainingComparators.every((otherComparator) => {
|
|
1040
1046
|
return testComparator.intersects(otherComparator, options);
|
|
1041
1047
|
});
|
|
1042
1048
|
testComparator = remainingComparators.pop();
|
|
1043
1049
|
}
|
|
1044
|
-
return
|
|
1050
|
+
return result;
|
|
1045
1051
|
};
|
|
1046
1052
|
var parseComparator = (comp, options) => {
|
|
1047
1053
|
comp = comp.replace(re[t.BUILD], "");
|
|
@@ -1248,9 +1254,9 @@ var require_range = __commonJS({
|
|
|
1248
1254
|
}
|
|
1249
1255
|
});
|
|
1250
1256
|
|
|
1251
|
-
// node_modules/semver/classes/comparator.js
|
|
1257
|
+
// ../sdk/node_modules/semver/classes/comparator.js
|
|
1252
1258
|
var require_comparator = __commonJS({
|
|
1253
|
-
"node_modules/semver/classes/comparator.js"(exports$1, module) {
|
|
1259
|
+
"../sdk/node_modules/semver/classes/comparator.js"(exports$1, module) {
|
|
1254
1260
|
var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
|
|
1255
1261
|
var Comparator = class _Comparator {
|
|
1256
1262
|
static get ANY() {
|
|
@@ -1360,9 +1366,9 @@ var require_comparator = __commonJS({
|
|
|
1360
1366
|
}
|
|
1361
1367
|
});
|
|
1362
1368
|
|
|
1363
|
-
// node_modules/semver/functions/satisfies.js
|
|
1369
|
+
// ../sdk/node_modules/semver/functions/satisfies.js
|
|
1364
1370
|
var require_satisfies = __commonJS({
|
|
1365
|
-
"node_modules/semver/functions/satisfies.js"(exports$1, module) {
|
|
1371
|
+
"../sdk/node_modules/semver/functions/satisfies.js"(exports$1, module) {
|
|
1366
1372
|
var Range = require_range();
|
|
1367
1373
|
var satisfies = (version, range, options) => {
|
|
1368
1374
|
try {
|
|
@@ -1376,18 +1382,18 @@ var require_satisfies = __commonJS({
|
|
|
1376
1382
|
}
|
|
1377
1383
|
});
|
|
1378
1384
|
|
|
1379
|
-
// node_modules/semver/ranges/to-comparators.js
|
|
1385
|
+
// ../sdk/node_modules/semver/ranges/to-comparators.js
|
|
1380
1386
|
var require_to_comparators = __commonJS({
|
|
1381
|
-
"node_modules/semver/ranges/to-comparators.js"(exports$1, module) {
|
|
1387
|
+
"../sdk/node_modules/semver/ranges/to-comparators.js"(exports$1, module) {
|
|
1382
1388
|
var Range = require_range();
|
|
1383
1389
|
var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" "));
|
|
1384
1390
|
module.exports = toComparators;
|
|
1385
1391
|
}
|
|
1386
1392
|
});
|
|
1387
1393
|
|
|
1388
|
-
// node_modules/semver/ranges/max-satisfying.js
|
|
1394
|
+
// ../sdk/node_modules/semver/ranges/max-satisfying.js
|
|
1389
1395
|
var require_max_satisfying = __commonJS({
|
|
1390
|
-
"node_modules/semver/ranges/max-satisfying.js"(exports$1, module) {
|
|
1396
|
+
"../sdk/node_modules/semver/ranges/max-satisfying.js"(exports$1, module) {
|
|
1391
1397
|
var SemVer = require_semver();
|
|
1392
1398
|
var Range = require_range();
|
|
1393
1399
|
var maxSatisfying = (versions, range, options) => {
|
|
@@ -1413,9 +1419,9 @@ var require_max_satisfying = __commonJS({
|
|
|
1413
1419
|
}
|
|
1414
1420
|
});
|
|
1415
1421
|
|
|
1416
|
-
// node_modules/semver/ranges/min-satisfying.js
|
|
1422
|
+
// ../sdk/node_modules/semver/ranges/min-satisfying.js
|
|
1417
1423
|
var require_min_satisfying = __commonJS({
|
|
1418
|
-
"node_modules/semver/ranges/min-satisfying.js"(exports$1, module) {
|
|
1424
|
+
"../sdk/node_modules/semver/ranges/min-satisfying.js"(exports$1, module) {
|
|
1419
1425
|
var SemVer = require_semver();
|
|
1420
1426
|
var Range = require_range();
|
|
1421
1427
|
var minSatisfying = (versions, range, options) => {
|
|
@@ -1441,9 +1447,9 @@ var require_min_satisfying = __commonJS({
|
|
|
1441
1447
|
}
|
|
1442
1448
|
});
|
|
1443
1449
|
|
|
1444
|
-
// node_modules/semver/ranges/min-version.js
|
|
1450
|
+
// ../sdk/node_modules/semver/ranges/min-version.js
|
|
1445
1451
|
var require_min_version = __commonJS({
|
|
1446
|
-
"node_modules/semver/ranges/min-version.js"(exports$1, module) {
|
|
1452
|
+
"../sdk/node_modules/semver/ranges/min-version.js"(exports$1, module) {
|
|
1447
1453
|
var SemVer = require_semver();
|
|
1448
1454
|
var Range = require_range();
|
|
1449
1455
|
var gt = require_gt();
|
|
@@ -1499,9 +1505,9 @@ var require_min_version = __commonJS({
|
|
|
1499
1505
|
}
|
|
1500
1506
|
});
|
|
1501
1507
|
|
|
1502
|
-
// node_modules/semver/ranges/valid.js
|
|
1508
|
+
// ../sdk/node_modules/semver/ranges/valid.js
|
|
1503
1509
|
var require_valid2 = __commonJS({
|
|
1504
|
-
"node_modules/semver/ranges/valid.js"(exports$1, module) {
|
|
1510
|
+
"../sdk/node_modules/semver/ranges/valid.js"(exports$1, module) {
|
|
1505
1511
|
var Range = require_range();
|
|
1506
1512
|
var validRange = (range, options) => {
|
|
1507
1513
|
try {
|
|
@@ -1514,9 +1520,9 @@ var require_valid2 = __commonJS({
|
|
|
1514
1520
|
}
|
|
1515
1521
|
});
|
|
1516
1522
|
|
|
1517
|
-
// node_modules/semver/ranges/outside.js
|
|
1523
|
+
// ../sdk/node_modules/semver/ranges/outside.js
|
|
1518
1524
|
var require_outside = __commonJS({
|
|
1519
|
-
"node_modules/semver/ranges/outside.js"(exports$1, module) {
|
|
1525
|
+
"../sdk/node_modules/semver/ranges/outside.js"(exports$1, module) {
|
|
1520
1526
|
var SemVer = require_semver();
|
|
1521
1527
|
var Comparator = require_comparator();
|
|
1522
1528
|
var { ANY } = Comparator;
|
|
@@ -1582,27 +1588,27 @@ var require_outside = __commonJS({
|
|
|
1582
1588
|
}
|
|
1583
1589
|
});
|
|
1584
1590
|
|
|
1585
|
-
// node_modules/semver/ranges/gtr.js
|
|
1591
|
+
// ../sdk/node_modules/semver/ranges/gtr.js
|
|
1586
1592
|
var require_gtr = __commonJS({
|
|
1587
|
-
"node_modules/semver/ranges/gtr.js"(exports$1, module) {
|
|
1593
|
+
"../sdk/node_modules/semver/ranges/gtr.js"(exports$1, module) {
|
|
1588
1594
|
var outside = require_outside();
|
|
1589
1595
|
var gtr = (version, range, options) => outside(version, range, ">", options);
|
|
1590
1596
|
module.exports = gtr;
|
|
1591
1597
|
}
|
|
1592
1598
|
});
|
|
1593
1599
|
|
|
1594
|
-
// node_modules/semver/ranges/ltr.js
|
|
1600
|
+
// ../sdk/node_modules/semver/ranges/ltr.js
|
|
1595
1601
|
var require_ltr = __commonJS({
|
|
1596
|
-
"node_modules/semver/ranges/ltr.js"(exports$1, module) {
|
|
1602
|
+
"../sdk/node_modules/semver/ranges/ltr.js"(exports$1, module) {
|
|
1597
1603
|
var outside = require_outside();
|
|
1598
1604
|
var ltr = (version, range, options) => outside(version, range, "<", options);
|
|
1599
1605
|
module.exports = ltr;
|
|
1600
1606
|
}
|
|
1601
1607
|
});
|
|
1602
1608
|
|
|
1603
|
-
// node_modules/semver/ranges/intersects.js
|
|
1609
|
+
// ../sdk/node_modules/semver/ranges/intersects.js
|
|
1604
1610
|
var require_intersects = __commonJS({
|
|
1605
|
-
"node_modules/semver/ranges/intersects.js"(exports$1, module) {
|
|
1611
|
+
"../sdk/node_modules/semver/ranges/intersects.js"(exports$1, module) {
|
|
1606
1612
|
var Range = require_range();
|
|
1607
1613
|
var intersects = (r1, r2, options) => {
|
|
1608
1614
|
r1 = new Range(r1, options);
|
|
@@ -1613,9 +1619,9 @@ var require_intersects = __commonJS({
|
|
|
1613
1619
|
}
|
|
1614
1620
|
});
|
|
1615
1621
|
|
|
1616
|
-
// node_modules/semver/ranges/simplify.js
|
|
1622
|
+
// ../sdk/node_modules/semver/ranges/simplify.js
|
|
1617
1623
|
var require_simplify = __commonJS({
|
|
1618
|
-
"node_modules/semver/ranges/simplify.js"(exports$1, module) {
|
|
1624
|
+
"../sdk/node_modules/semver/ranges/simplify.js"(exports$1, module) {
|
|
1619
1625
|
var satisfies = require_satisfies();
|
|
1620
1626
|
var compare = require_compare();
|
|
1621
1627
|
module.exports = (versions, range, options) => {
|
|
@@ -1662,9 +1668,9 @@ var require_simplify = __commonJS({
|
|
|
1662
1668
|
}
|
|
1663
1669
|
});
|
|
1664
1670
|
|
|
1665
|
-
// node_modules/semver/ranges/subset.js
|
|
1671
|
+
// ../sdk/node_modules/semver/ranges/subset.js
|
|
1666
1672
|
var require_subset = __commonJS({
|
|
1667
|
-
"node_modules/semver/ranges/subset.js"(exports$1, module) {
|
|
1673
|
+
"../sdk/node_modules/semver/ranges/subset.js"(exports$1, module) {
|
|
1668
1674
|
var Range = require_range();
|
|
1669
1675
|
var Comparator = require_comparator();
|
|
1670
1676
|
var { ANY } = Comparator;
|
|
@@ -1823,9 +1829,9 @@ var require_subset = __commonJS({
|
|
|
1823
1829
|
}
|
|
1824
1830
|
});
|
|
1825
1831
|
|
|
1826
|
-
// node_modules/semver/index.js
|
|
1832
|
+
// ../sdk/node_modules/semver/index.js
|
|
1827
1833
|
var require_semver2 = __commonJS({
|
|
1828
|
-
"node_modules/semver/index.js"(exports$1, module) {
|
|
1834
|
+
"../sdk/node_modules/semver/index.js"(exports$1, module) {
|
|
1829
1835
|
var internalRe = require_re();
|
|
1830
1836
|
var constants = require_constants();
|
|
1831
1837
|
var SemVer = require_semver();
|
|
@@ -1917,6 +1923,546 @@ var require_semver2 = __commonJS({
|
|
|
1917
1923
|
}
|
|
1918
1924
|
});
|
|
1919
1925
|
|
|
1926
|
+
// ../sdk/dist/flags/server.js
|
|
1927
|
+
var require_server = __commonJS({
|
|
1928
|
+
"../sdk/dist/flags/server.js"(exports$1, module) {
|
|
1929
|
+
var __defProp2 = Object.defineProperty;
|
|
1930
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
1931
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
1932
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
1933
|
+
var __export = (target, all) => {
|
|
1934
|
+
for (var name in all)
|
|
1935
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
1936
|
+
};
|
|
1937
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
1938
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
1939
|
+
for (let key of __getOwnPropNames2(from))
|
|
1940
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
1941
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
1942
|
+
}
|
|
1943
|
+
return to;
|
|
1944
|
+
};
|
|
1945
|
+
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
1946
|
+
var server_exports = {};
|
|
1947
|
+
__export(server_exports, {
|
|
1948
|
+
FlagClient: () => FlagClient2,
|
|
1949
|
+
allConditionsMatch: () => allConditionsMatch,
|
|
1950
|
+
evaluateFlag: () => evaluateFlag,
|
|
1951
|
+
hashToBucket: () => hashToBucket
|
|
1952
|
+
});
|
|
1953
|
+
module.exports = __toCommonJS(server_exports);
|
|
1954
|
+
var import_node_crypto = __require("crypto");
|
|
1955
|
+
function hashToBucket(flagKey, identifier, salt) {
|
|
1956
|
+
const hash = (0, import_node_crypto.createHash)("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
|
|
1957
|
+
return hash.readUInt32BE(0) % 1e4;
|
|
1958
|
+
}
|
|
1959
|
+
var import_semver = require_semver2();
|
|
1960
|
+
function allConditionsMatch(conditions, context) {
|
|
1961
|
+
return conditions.every((c) => conditionMatches(c, context));
|
|
1962
|
+
}
|
|
1963
|
+
function conditionMatches(condition, context) {
|
|
1964
|
+
const attributeValue = getAttribute(context, condition.attribute);
|
|
1965
|
+
const op = condition.operator;
|
|
1966
|
+
if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
|
|
1967
|
+
if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
|
|
1968
|
+
if (attributeValue === void 0 || attributeValue === null) return false;
|
|
1969
|
+
switch (op) {
|
|
1970
|
+
case "eq":
|
|
1971
|
+
return compareValues(attributeValue, condition.value) === 0;
|
|
1972
|
+
case "neq":
|
|
1973
|
+
return compareValues(attributeValue, condition.value) !== 0;
|
|
1974
|
+
case "in":
|
|
1975
|
+
return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
1976
|
+
case "not_in":
|
|
1977
|
+
return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
1978
|
+
case "contains":
|
|
1979
|
+
return containsValue(attributeValue, condition.value);
|
|
1980
|
+
case "starts_with":
|
|
1981
|
+
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
|
|
1982
|
+
case "ends_with":
|
|
1983
|
+
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
|
|
1984
|
+
case "gt":
|
|
1985
|
+
return compareValues(attributeValue, condition.value) === 1;
|
|
1986
|
+
case "gte": {
|
|
1987
|
+
const cmp = compareValues(attributeValue, condition.value);
|
|
1988
|
+
return cmp === 1 || cmp === 0;
|
|
1989
|
+
}
|
|
1990
|
+
case "lt":
|
|
1991
|
+
return compareValues(attributeValue, condition.value) === -1;
|
|
1992
|
+
case "lte": {
|
|
1993
|
+
const cmp = compareValues(attributeValue, condition.value);
|
|
1994
|
+
return cmp === -1 || cmp === 0;
|
|
1995
|
+
}
|
|
1996
|
+
case "regex": {
|
|
1997
|
+
if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
|
|
1998
|
+
try {
|
|
1999
|
+
return new RegExp(condition.value).test(attributeValue);
|
|
2000
|
+
} catch {
|
|
2001
|
+
return false;
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
case "semver_eq":
|
|
2005
|
+
return semverCmp(attributeValue, condition.value) === 0;
|
|
2006
|
+
case "semver_neq":
|
|
2007
|
+
return semverCmp(attributeValue, condition.value) !== 0;
|
|
2008
|
+
case "semver_gt":
|
|
2009
|
+
return semverCmp(attributeValue, condition.value) === 1;
|
|
2010
|
+
case "semver_gte": {
|
|
2011
|
+
const cmp = semverCmp(attributeValue, condition.value);
|
|
2012
|
+
return cmp === 1 || cmp === 0;
|
|
2013
|
+
}
|
|
2014
|
+
case "semver_lt":
|
|
2015
|
+
return semverCmp(attributeValue, condition.value) === -1;
|
|
2016
|
+
case "semver_lte": {
|
|
2017
|
+
const cmp = semverCmp(attributeValue, condition.value);
|
|
2018
|
+
return cmp === -1 || cmp === 0;
|
|
2019
|
+
}
|
|
2020
|
+
default:
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
function getAttribute(context, key) {
|
|
2025
|
+
switch (key) {
|
|
2026
|
+
case "user_id":
|
|
2027
|
+
return context.user_id;
|
|
2028
|
+
case "email":
|
|
2029
|
+
return context.email;
|
|
2030
|
+
case "session_id":
|
|
2031
|
+
return context.session_id;
|
|
2032
|
+
case "ip_address":
|
|
2033
|
+
return context.ip_address;
|
|
2034
|
+
case "user_agent":
|
|
2035
|
+
return context.user_agent;
|
|
2036
|
+
case "timestamp":
|
|
2037
|
+
return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2038
|
+
default:
|
|
2039
|
+
return context[key];
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
function candidateValues(condition) {
|
|
2043
|
+
if (condition.values && condition.values.length > 0) return condition.values;
|
|
2044
|
+
if (condition.value === void 0 || condition.value === null) return [];
|
|
2045
|
+
if (Array.isArray(condition.value)) return condition.value;
|
|
2046
|
+
return [condition.value];
|
|
2047
|
+
}
|
|
2048
|
+
function compareValues(actual, expected) {
|
|
2049
|
+
if (expected === void 0 || expected === null) return null;
|
|
2050
|
+
const numA = toNumber(actual);
|
|
2051
|
+
const numB = toNumber(expected);
|
|
2052
|
+
if (numA !== null && numB !== null) {
|
|
2053
|
+
if (numA < numB) return -1;
|
|
2054
|
+
if (numA > numB) return 1;
|
|
2055
|
+
return 0;
|
|
2056
|
+
}
|
|
2057
|
+
if (typeof actual === "boolean" && typeof expected === "boolean") {
|
|
2058
|
+
if (actual === expected) return 0;
|
|
2059
|
+
return actual ? 1 : -1;
|
|
2060
|
+
}
|
|
2061
|
+
const strA = toString(actual);
|
|
2062
|
+
const strB = toString(expected);
|
|
2063
|
+
if (strA !== null && strB !== null) {
|
|
2064
|
+
if (strA < strB) return -1;
|
|
2065
|
+
if (strA > strB) return 1;
|
|
2066
|
+
return 0;
|
|
2067
|
+
}
|
|
2068
|
+
return null;
|
|
2069
|
+
}
|
|
2070
|
+
function containsValue(actual, expected) {
|
|
2071
|
+
if (expected === void 0 || expected === null) return false;
|
|
2072
|
+
if (Array.isArray(actual)) {
|
|
2073
|
+
return actual.some((item) => compareValues(item, expected) === 0);
|
|
2074
|
+
}
|
|
2075
|
+
if (typeof actual === "string" && typeof expected === "string") {
|
|
2076
|
+
return actual.includes(expected);
|
|
2077
|
+
}
|
|
2078
|
+
return false;
|
|
2079
|
+
}
|
|
2080
|
+
function toNumber(value) {
|
|
2081
|
+
if (typeof value === "number") return value;
|
|
2082
|
+
if (typeof value === "string") {
|
|
2083
|
+
const n = Number(value);
|
|
2084
|
+
return isNaN(n) ? null : n;
|
|
2085
|
+
}
|
|
2086
|
+
return null;
|
|
2087
|
+
}
|
|
2088
|
+
function toString(value) {
|
|
2089
|
+
if (typeof value === "string") return value;
|
|
2090
|
+
return null;
|
|
2091
|
+
}
|
|
2092
|
+
function semverCmp(actual, expected) {
|
|
2093
|
+
if (typeof actual !== "string" || typeof expected !== "string") return null;
|
|
2094
|
+
try {
|
|
2095
|
+
const a = (0, import_semver.parse)(actual);
|
|
2096
|
+
const b = (0, import_semver.parse)(expected);
|
|
2097
|
+
if (!a || !b) return null;
|
|
2098
|
+
return (0, import_semver.compare)(a, b);
|
|
2099
|
+
} catch {
|
|
2100
|
+
return null;
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
function evaluateFlag(flag, config, context, segmentIndex) {
|
|
2104
|
+
const effectiveDefault = flag.environment_default_value ?? flag.default_value;
|
|
2105
|
+
if (flag.status !== "active") {
|
|
2106
|
+
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
2107
|
+
}
|
|
2108
|
+
if (!flag.environment_enabled) {
|
|
2109
|
+
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
2110
|
+
}
|
|
2111
|
+
const bucketIdentifier = getBucketIdentifier(context);
|
|
2112
|
+
for (const rule of flag.rules) {
|
|
2113
|
+
if (!rule.enabled) continue;
|
|
2114
|
+
if (rule.segment_ids.length > 0) {
|
|
2115
|
+
const segmentMatched = rule.segment_ids.some((segId) => {
|
|
2116
|
+
const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
|
|
2117
|
+
if (!segment) return false;
|
|
2118
|
+
return userMatchesSegment(segment, context);
|
|
2119
|
+
});
|
|
2120
|
+
if (!segmentMatched) continue;
|
|
2121
|
+
}
|
|
2122
|
+
if (!allConditionsMatch(rule.conditions, context)) continue;
|
|
2123
|
+
if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
|
|
2124
|
+
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
2125
|
+
if (bucket >= rule.rollout_percentage) continue;
|
|
2126
|
+
return {
|
|
2127
|
+
flag_id: flag.flag_id,
|
|
2128
|
+
flag_key: flag.flag_key,
|
|
2129
|
+
environment: config.environment,
|
|
2130
|
+
value: rule.serve_value,
|
|
2131
|
+
reason: "rule_match",
|
|
2132
|
+
matched_rule_id: rule.id,
|
|
2133
|
+
variant_key: null,
|
|
2134
|
+
bucket
|
|
2135
|
+
};
|
|
2136
|
+
}
|
|
2137
|
+
return {
|
|
2138
|
+
flag_id: flag.flag_id,
|
|
2139
|
+
flag_key: flag.flag_key,
|
|
2140
|
+
environment: config.environment,
|
|
2141
|
+
value: rule.serve_value,
|
|
2142
|
+
reason: "rule_match",
|
|
2143
|
+
matched_rule_id: rule.id,
|
|
2144
|
+
variant_key: null,
|
|
2145
|
+
bucket: null
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
if (flag.variants.length > 0) {
|
|
2149
|
+
const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
|
|
2150
|
+
if (totalWeight > 0) {
|
|
2151
|
+
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
2152
|
+
const scaled = Math.floor(bucket * totalWeight / 1e4);
|
|
2153
|
+
let cursor = 0;
|
|
2154
|
+
for (const variant of flag.variants) {
|
|
2155
|
+
cursor += variant.weight;
|
|
2156
|
+
if (scaled < cursor) {
|
|
2157
|
+
return {
|
|
2158
|
+
flag_id: flag.flag_id,
|
|
2159
|
+
flag_key: flag.flag_key,
|
|
2160
|
+
environment: config.environment,
|
|
2161
|
+
value: variant.value,
|
|
2162
|
+
reason: "variant",
|
|
2163
|
+
matched_rule_id: null,
|
|
2164
|
+
variant_key: variant.variant_key,
|
|
2165
|
+
bucket
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
return result(flag, config.environment, effectiveDefault, "default");
|
|
2172
|
+
}
|
|
2173
|
+
function getBucketIdentifier(context) {
|
|
2174
|
+
return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
|
|
2175
|
+
}
|
|
2176
|
+
function userMatchesSegment(segment, context) {
|
|
2177
|
+
const identifiers = [context.user_id, context.email, context.session_id].filter(
|
|
2178
|
+
(v) => v !== void 0 && v !== null
|
|
2179
|
+
);
|
|
2180
|
+
if (identifiers.some((id) => segment.excluded_users.includes(id))) {
|
|
2181
|
+
return false;
|
|
2182
|
+
}
|
|
2183
|
+
if (identifiers.some((id) => segment.included_users.includes(id))) {
|
|
2184
|
+
return true;
|
|
2185
|
+
}
|
|
2186
|
+
return allConditionsMatch(segment.conditions, context);
|
|
2187
|
+
}
|
|
2188
|
+
function result(flag, environment, value, reason) {
|
|
2189
|
+
return {
|
|
2190
|
+
flag_id: flag.flag_id,
|
|
2191
|
+
flag_key: flag.flag_key,
|
|
2192
|
+
environment,
|
|
2193
|
+
value,
|
|
2194
|
+
reason,
|
|
2195
|
+
matched_rule_id: null,
|
|
2196
|
+
variant_key: null,
|
|
2197
|
+
bucket: null
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
2200
|
+
var FlagClient2 = class {
|
|
2201
|
+
constructor(options) {
|
|
2202
|
+
this.config = null;
|
|
2203
|
+
this.flagIndex = /* @__PURE__ */ new Map();
|
|
2204
|
+
this.segmentIndex = /* @__PURE__ */ new Map();
|
|
2205
|
+
this.lastETag = "";
|
|
2206
|
+
this.streamState = "idle";
|
|
2207
|
+
this.pollTimer = null;
|
|
2208
|
+
this.reconnectTimer = null;
|
|
2209
|
+
this.telemetryTimer = null;
|
|
2210
|
+
this.abortController = null;
|
|
2211
|
+
this.initPromise = null;
|
|
2212
|
+
this.telemetryCounters = /* @__PURE__ */ new Map();
|
|
2213
|
+
this.isShuttingDown = false;
|
|
2214
|
+
this.streamConnectInFlight = false;
|
|
2215
|
+
this.apiKey = options.apiKey;
|
|
2216
|
+
this.environment = options.environment;
|
|
2217
|
+
this.gatewayUrl = options.gatewayUrl;
|
|
2218
|
+
}
|
|
2219
|
+
async init() {
|
|
2220
|
+
this.isShuttingDown = false;
|
|
2221
|
+
if (this.config) return;
|
|
2222
|
+
if (this.initPromise) return this.initPromise;
|
|
2223
|
+
this.initPromise = this.doInit();
|
|
2224
|
+
try {
|
|
2225
|
+
await this.initPromise;
|
|
2226
|
+
} finally {
|
|
2227
|
+
this.initPromise = null;
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
async doInit() {
|
|
2231
|
+
const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
|
|
2232
|
+
headers: { "x-api-key": this.apiKey }
|
|
2233
|
+
});
|
|
2234
|
+
if (resp.status === 403) throw new Error("Secret API key required for /config");
|
|
2235
|
+
if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
|
|
2236
|
+
const json = await resp.json();
|
|
2237
|
+
this.config = json.data;
|
|
2238
|
+
this.buildIndexes();
|
|
2239
|
+
this.lastETag = resp.headers.get("etag") || "";
|
|
2240
|
+
this.connectStream();
|
|
2241
|
+
this.startTelemetryFlush();
|
|
2242
|
+
}
|
|
2243
|
+
buildIndexes() {
|
|
2244
|
+
this.flagIndex.clear();
|
|
2245
|
+
this.segmentIndex.clear();
|
|
2246
|
+
if (!this.config) return;
|
|
2247
|
+
for (const flag of this.config.flags) {
|
|
2248
|
+
this.flagIndex.set(flag.flag_key, flag);
|
|
2249
|
+
}
|
|
2250
|
+
for (const segment of this.config.segments) {
|
|
2251
|
+
this.segmentIndex.set(segment.id, segment);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
evaluate(flagKey, context) {
|
|
2255
|
+
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
2256
|
+
const flagConfig = this.flagIndex.get(flagKey);
|
|
2257
|
+
if (!flagConfig) {
|
|
2258
|
+
return {
|
|
2259
|
+
flag_id: "",
|
|
2260
|
+
flag_key: flagKey,
|
|
2261
|
+
environment: this.environment,
|
|
2262
|
+
value: null,
|
|
2263
|
+
reason: "not_found",
|
|
2264
|
+
matched_rule_id: null,
|
|
2265
|
+
variant_key: null,
|
|
2266
|
+
bucket: null
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
2270
|
+
this.recordTelemetry(result2);
|
|
2271
|
+
return result2;
|
|
2272
|
+
}
|
|
2273
|
+
evaluateBatch(flagKeys, context) {
|
|
2274
|
+
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
2275
|
+
const results = {};
|
|
2276
|
+
for (const key of flagKeys) {
|
|
2277
|
+
const flagConfig = this.flagIndex.get(key);
|
|
2278
|
+
if (flagConfig) {
|
|
2279
|
+
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
2280
|
+
this.recordTelemetry(result2);
|
|
2281
|
+
results[key] = result2;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
return results;
|
|
2285
|
+
}
|
|
2286
|
+
async shutdown() {
|
|
2287
|
+
this.isShuttingDown = true;
|
|
2288
|
+
this.streamState = "idle";
|
|
2289
|
+
this.abortController?.abort();
|
|
2290
|
+
this.abortController = null;
|
|
2291
|
+
if (this.pollTimer) {
|
|
2292
|
+
clearInterval(this.pollTimer);
|
|
2293
|
+
this.pollTimer = null;
|
|
2294
|
+
}
|
|
2295
|
+
if (this.reconnectTimer) {
|
|
2296
|
+
clearInterval(this.reconnectTimer);
|
|
2297
|
+
this.reconnectTimer = null;
|
|
2298
|
+
}
|
|
2299
|
+
if (this.telemetryTimer) {
|
|
2300
|
+
clearInterval(this.telemetryTimer);
|
|
2301
|
+
this.telemetryTimer = null;
|
|
2302
|
+
}
|
|
2303
|
+
await this.flushTelemetry();
|
|
2304
|
+
}
|
|
2305
|
+
// ======== SSE Streaming ========
|
|
2306
|
+
async connectStream() {
|
|
2307
|
+
if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
|
|
2308
|
+
this.streamConnectInFlight = true;
|
|
2309
|
+
this.abortController?.abort();
|
|
2310
|
+
const abortController = new AbortController();
|
|
2311
|
+
this.abortController = abortController;
|
|
2312
|
+
const shouldResumePolling = this.streamState !== "polling";
|
|
2313
|
+
let startPolling = shouldResumePolling;
|
|
2314
|
+
try {
|
|
2315
|
+
const resp = await fetch(
|
|
2316
|
+
`${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
|
|
2317
|
+
{
|
|
2318
|
+
headers: {
|
|
2319
|
+
"x-api-key": this.apiKey,
|
|
2320
|
+
"Last-Event-ID": String(this.config?.version ?? 0)
|
|
2321
|
+
},
|
|
2322
|
+
signal: abortController.signal
|
|
2323
|
+
}
|
|
2324
|
+
);
|
|
2325
|
+
if (resp.ok && resp.body) {
|
|
2326
|
+
this.streamState = "streaming";
|
|
2327
|
+
this.stopPolling();
|
|
2328
|
+
startPolling = false;
|
|
2329
|
+
const reader = resp.body.getReader();
|
|
2330
|
+
const decoder = new TextDecoder();
|
|
2331
|
+
let buffer = "";
|
|
2332
|
+
while (true) {
|
|
2333
|
+
const { done, value } = await reader.read();
|
|
2334
|
+
if (done) break;
|
|
2335
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2336
|
+
let idx;
|
|
2337
|
+
while ((idx = buffer.indexOf("\n\n")) !== -1) {
|
|
2338
|
+
const frame = buffer.slice(0, idx);
|
|
2339
|
+
buffer = buffer.slice(idx + 2);
|
|
2340
|
+
this.handleSseFrame(frame);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
if (this.streamState === "streaming") {
|
|
2344
|
+
this.streamState = "idle";
|
|
2345
|
+
startPolling = true;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
} catch {
|
|
2349
|
+
startPolling = !abortController.signal.aborted && shouldResumePolling;
|
|
2350
|
+
} finally {
|
|
2351
|
+
this.streamConnectInFlight = false;
|
|
2352
|
+
}
|
|
2353
|
+
if (!this.isShuttingDown && startPolling) {
|
|
2354
|
+
this.startPolling();
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
handleSseFrame(frame) {
|
|
2358
|
+
let eventType = "";
|
|
2359
|
+
let data = "";
|
|
2360
|
+
for (const line of frame.split("\n")) {
|
|
2361
|
+
if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
2362
|
+
else if (line.startsWith("data:")) data += line.slice(5).trim();
|
|
2363
|
+
}
|
|
2364
|
+
if (eventType === "config" && data) {
|
|
2365
|
+
try {
|
|
2366
|
+
const parsed = JSON.parse(data);
|
|
2367
|
+
const newConfig = parsed.data;
|
|
2368
|
+
if (newConfig && newConfig.version !== void 0) {
|
|
2369
|
+
this.config = newConfig;
|
|
2370
|
+
this.buildIndexes();
|
|
2371
|
+
}
|
|
2372
|
+
} catch {
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
// ======== Polling Fallback ========
|
|
2377
|
+
startPolling() {
|
|
2378
|
+
if (this.streamState === "polling") return;
|
|
2379
|
+
this.streamState = "polling";
|
|
2380
|
+
this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
|
|
2381
|
+
this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
|
|
2382
|
+
}
|
|
2383
|
+
stopPolling() {
|
|
2384
|
+
if (this.pollTimer) {
|
|
2385
|
+
clearInterval(this.pollTimer);
|
|
2386
|
+
this.pollTimer = null;
|
|
2387
|
+
}
|
|
2388
|
+
if (this.reconnectTimer) {
|
|
2389
|
+
clearInterval(this.reconnectTimer);
|
|
2390
|
+
this.reconnectTimer = null;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
async pollConfig() {
|
|
2394
|
+
try {
|
|
2395
|
+
const headers2 = { "x-api-key": this.apiKey };
|
|
2396
|
+
if (this.lastETag) headers2["if-none-match"] = this.lastETag;
|
|
2397
|
+
const resp = await fetch(
|
|
2398
|
+
`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
|
|
2399
|
+
{ headers: headers2 }
|
|
2400
|
+
);
|
|
2401
|
+
if (resp.status === 304) return;
|
|
2402
|
+
if (!resp.ok) return;
|
|
2403
|
+
const json = await resp.json();
|
|
2404
|
+
this.config = json.data;
|
|
2405
|
+
this.buildIndexes();
|
|
2406
|
+
this.lastETag = resp.headers.get("etag") || "";
|
|
2407
|
+
} catch {
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
// ======== Telemetry ========
|
|
2411
|
+
recordTelemetry(evaluation) {
|
|
2412
|
+
const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
|
|
2413
|
+
const existing = this.telemetryCounters.get(key);
|
|
2414
|
+
if (existing) {
|
|
2415
|
+
existing.count++;
|
|
2416
|
+
if (evaluation.value === true) existing.true_count++;
|
|
2417
|
+
else if (evaluation.value === false) existing.false_count++;
|
|
2418
|
+
} else {
|
|
2419
|
+
this.telemetryCounters.set(key, {
|
|
2420
|
+
flag_key: evaluation.flag_key,
|
|
2421
|
+
flag_id: evaluation.flag_id,
|
|
2422
|
+
reason: evaluation.reason,
|
|
2423
|
+
count: 1,
|
|
2424
|
+
true_count: evaluation.value === true ? 1 : 0,
|
|
2425
|
+
false_count: evaluation.value === false ? 1 : 0
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
startTelemetryFlush() {
|
|
2430
|
+
this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
|
|
2431
|
+
}
|
|
2432
|
+
async flushTelemetry() {
|
|
2433
|
+
if (this.telemetryCounters.size === 0) return;
|
|
2434
|
+
const evaluations = Array.from(this.telemetryCounters.values());
|
|
2435
|
+
this.telemetryCounters.clear();
|
|
2436
|
+
try {
|
|
2437
|
+
await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
|
|
2438
|
+
method: "POST",
|
|
2439
|
+
headers: {
|
|
2440
|
+
"Content-Type": "application/json",
|
|
2441
|
+
"x-api-key": this.apiKey
|
|
2442
|
+
},
|
|
2443
|
+
body: JSON.stringify({
|
|
2444
|
+
environment: this.environment,
|
|
2445
|
+
evaluations
|
|
2446
|
+
})
|
|
2447
|
+
});
|
|
2448
|
+
} catch {
|
|
2449
|
+
for (const counter of evaluations) {
|
|
2450
|
+
const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
|
|
2451
|
+
const existing = this.telemetryCounters.get(key);
|
|
2452
|
+
if (existing) {
|
|
2453
|
+
existing.count += counter.count;
|
|
2454
|
+
existing.true_count += counter.true_count;
|
|
2455
|
+
existing.false_count += counter.false_count;
|
|
2456
|
+
} else {
|
|
2457
|
+
this.telemetryCounters.set(key, counter);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
};
|
|
2463
|
+
}
|
|
2464
|
+
});
|
|
2465
|
+
|
|
1920
2466
|
// src/types/index.ts
|
|
1921
2467
|
var ScaleMuleApiError = class extends Error {
|
|
1922
2468
|
constructor(error, status) {
|
|
@@ -3322,7 +3868,7 @@ function createAuthRoutes(config = {}) {
|
|
|
3322
3868
|
if (!email) {
|
|
3323
3869
|
return errorResponse("VALIDATION_ERROR", "Email required", 400);
|
|
3324
3870
|
}
|
|
3325
|
-
const
|
|
3871
|
+
const result = await sm.auth.forgotPassword(email, { clientContext });
|
|
3326
3872
|
return successResponse({ message: "If an account exists, a reset email has been sent" });
|
|
3327
3873
|
}
|
|
3328
3874
|
// ==================== Reset Password ====================
|
|
@@ -4467,9 +5013,9 @@ var CODE_TO_STATUS = {
|
|
|
4467
5013
|
function errorCodeToStatus(code) {
|
|
4468
5014
|
return CODE_TO_STATUS[code.toLowerCase()] || 400;
|
|
4469
5015
|
}
|
|
4470
|
-
function unwrap(
|
|
4471
|
-
if (
|
|
4472
|
-
const envelope =
|
|
5016
|
+
function unwrap(result) {
|
|
5017
|
+
if (result !== null && result !== void 0 && typeof result === "object" && ("success" in result || "error" in result) && "data" in result) {
|
|
5018
|
+
const envelope = result;
|
|
4473
5019
|
if (envelope.error || envelope.success === false) {
|
|
4474
5020
|
const err = envelope.error;
|
|
4475
5021
|
const code = err?.code || "UNKNOWN_ERROR";
|
|
@@ -4483,7 +5029,7 @@ function unwrap(result2) {
|
|
|
4483
5029
|
}
|
|
4484
5030
|
return envelope.data;
|
|
4485
5031
|
}
|
|
4486
|
-
return
|
|
5032
|
+
return result;
|
|
4487
5033
|
}
|
|
4488
5034
|
|
|
4489
5035
|
// src/server/handler.ts
|
|
@@ -4510,10 +5056,10 @@ function apiHandler(handler, options) {
|
|
|
4510
5056
|
searchParams: request.nextUrl.searchParams,
|
|
4511
5057
|
session
|
|
4512
5058
|
};
|
|
4513
|
-
const
|
|
4514
|
-
if (
|
|
4515
|
-
if (
|
|
4516
|
-
return Response.json({ success: true, data:
|
|
5059
|
+
const result = await handler(request, context);
|
|
5060
|
+
if (result instanceof Response) return result;
|
|
5061
|
+
if (result !== void 0) {
|
|
5062
|
+
return Response.json({ success: true, data: result }, { status: 200 });
|
|
4517
5063
|
}
|
|
4518
5064
|
return new Response(null, { status: 204 });
|
|
4519
5065
|
} catch (error) {
|
|
@@ -4560,14 +5106,14 @@ function parseWebhookEvent(payload) {
|
|
|
4560
5106
|
}
|
|
4561
5107
|
async function registerVideoWebhook(url, options) {
|
|
4562
5108
|
const sm = createServerClient(options?.clientConfig);
|
|
4563
|
-
const
|
|
5109
|
+
const result = await sm.webhooks.create({
|
|
4564
5110
|
webhook_name: options?.name || "Video Status Webhook",
|
|
4565
5111
|
url,
|
|
4566
5112
|
events: options?.events || ["video.ready", "video.failed"]
|
|
4567
5113
|
});
|
|
4568
5114
|
return {
|
|
4569
|
-
id:
|
|
4570
|
-
secret:
|
|
5115
|
+
id: result.id,
|
|
5116
|
+
secret: result.secret
|
|
4571
5117
|
};
|
|
4572
5118
|
}
|
|
4573
5119
|
function createWebhookRoutes(config = {}) {
|
|
@@ -4655,517 +5201,8 @@ function createWebhookHandler(config = {}) {
|
|
|
4655
5201
|
};
|
|
4656
5202
|
}
|
|
4657
5203
|
|
|
4658
|
-
// node_modules/@scalemule/sdk/dist/flags/server.mjs
|
|
4659
|
-
var import_semver = __toESM(require_semver2());
|
|
4660
|
-
function hashToBucket(flagKey, identifier, salt) {
|
|
4661
|
-
const hash = crypto$1.createHash("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
|
|
4662
|
-
return hash.readUInt32BE(0) % 1e4;
|
|
4663
|
-
}
|
|
4664
|
-
function allConditionsMatch(conditions, context) {
|
|
4665
|
-
return conditions.every((c) => conditionMatches(c, context));
|
|
4666
|
-
}
|
|
4667
|
-
function conditionMatches(condition, context) {
|
|
4668
|
-
const attributeValue = getAttribute(context, condition.attribute);
|
|
4669
|
-
const op = condition.operator;
|
|
4670
|
-
if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
|
|
4671
|
-
if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
|
|
4672
|
-
if (attributeValue === void 0 || attributeValue === null) return false;
|
|
4673
|
-
switch (op) {
|
|
4674
|
-
case "eq":
|
|
4675
|
-
return compareValues(attributeValue, condition.value) === 0;
|
|
4676
|
-
case "neq":
|
|
4677
|
-
return compareValues(attributeValue, condition.value) !== 0;
|
|
4678
|
-
case "in":
|
|
4679
|
-
return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4680
|
-
case "not_in":
|
|
4681
|
-
return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4682
|
-
case "contains":
|
|
4683
|
-
return containsValue(attributeValue, condition.value);
|
|
4684
|
-
case "starts_with":
|
|
4685
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
|
|
4686
|
-
case "ends_with":
|
|
4687
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
|
|
4688
|
-
case "gt":
|
|
4689
|
-
return compareValues(attributeValue, condition.value) === 1;
|
|
4690
|
-
case "gte": {
|
|
4691
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4692
|
-
return cmp === 1 || cmp === 0;
|
|
4693
|
-
}
|
|
4694
|
-
case "lt":
|
|
4695
|
-
return compareValues(attributeValue, condition.value) === -1;
|
|
4696
|
-
case "lte": {
|
|
4697
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4698
|
-
return cmp === -1 || cmp === 0;
|
|
4699
|
-
}
|
|
4700
|
-
case "regex": {
|
|
4701
|
-
if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
|
|
4702
|
-
try {
|
|
4703
|
-
return new RegExp(condition.value).test(attributeValue);
|
|
4704
|
-
} catch {
|
|
4705
|
-
return false;
|
|
4706
|
-
}
|
|
4707
|
-
}
|
|
4708
|
-
case "semver_eq":
|
|
4709
|
-
return semverCmp(attributeValue, condition.value) === 0;
|
|
4710
|
-
case "semver_neq":
|
|
4711
|
-
return semverCmp(attributeValue, condition.value) !== 0;
|
|
4712
|
-
case "semver_gt":
|
|
4713
|
-
return semverCmp(attributeValue, condition.value) === 1;
|
|
4714
|
-
case "semver_gte": {
|
|
4715
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4716
|
-
return cmp === 1 || cmp === 0;
|
|
4717
|
-
}
|
|
4718
|
-
case "semver_lt":
|
|
4719
|
-
return semverCmp(attributeValue, condition.value) === -1;
|
|
4720
|
-
case "semver_lte": {
|
|
4721
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4722
|
-
return cmp === -1 || cmp === 0;
|
|
4723
|
-
}
|
|
4724
|
-
default:
|
|
4725
|
-
return false;
|
|
4726
|
-
}
|
|
4727
|
-
}
|
|
4728
|
-
function getAttribute(context, key) {
|
|
4729
|
-
switch (key) {
|
|
4730
|
-
case "user_id":
|
|
4731
|
-
return context.user_id;
|
|
4732
|
-
case "email":
|
|
4733
|
-
return context.email;
|
|
4734
|
-
case "session_id":
|
|
4735
|
-
return context.session_id;
|
|
4736
|
-
case "ip_address":
|
|
4737
|
-
return context.ip_address;
|
|
4738
|
-
case "user_agent":
|
|
4739
|
-
return context.user_agent;
|
|
4740
|
-
case "timestamp":
|
|
4741
|
-
return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4742
|
-
default:
|
|
4743
|
-
return context[key];
|
|
4744
|
-
}
|
|
4745
|
-
}
|
|
4746
|
-
function candidateValues(condition) {
|
|
4747
|
-
if (condition.values && condition.values.length > 0) return condition.values;
|
|
4748
|
-
if (condition.value === void 0 || condition.value === null) return [];
|
|
4749
|
-
if (Array.isArray(condition.value)) return condition.value;
|
|
4750
|
-
return [condition.value];
|
|
4751
|
-
}
|
|
4752
|
-
function compareValues(actual, expected) {
|
|
4753
|
-
if (expected === void 0 || expected === null) return null;
|
|
4754
|
-
const numA = toNumber(actual);
|
|
4755
|
-
const numB = toNumber(expected);
|
|
4756
|
-
if (numA !== null && numB !== null) {
|
|
4757
|
-
if (numA < numB) return -1;
|
|
4758
|
-
if (numA > numB) return 1;
|
|
4759
|
-
return 0;
|
|
4760
|
-
}
|
|
4761
|
-
if (typeof actual === "boolean" && typeof expected === "boolean") {
|
|
4762
|
-
if (actual === expected) return 0;
|
|
4763
|
-
return actual ? 1 : -1;
|
|
4764
|
-
}
|
|
4765
|
-
const strA = toString(actual);
|
|
4766
|
-
const strB = toString(expected);
|
|
4767
|
-
if (strA !== null && strB !== null) {
|
|
4768
|
-
if (strA < strB) return -1;
|
|
4769
|
-
if (strA > strB) return 1;
|
|
4770
|
-
return 0;
|
|
4771
|
-
}
|
|
4772
|
-
return null;
|
|
4773
|
-
}
|
|
4774
|
-
function containsValue(actual, expected) {
|
|
4775
|
-
if (expected === void 0 || expected === null) return false;
|
|
4776
|
-
if (Array.isArray(actual)) {
|
|
4777
|
-
return actual.some((item) => compareValues(item, expected) === 0);
|
|
4778
|
-
}
|
|
4779
|
-
if (typeof actual === "string" && typeof expected === "string") {
|
|
4780
|
-
return actual.includes(expected);
|
|
4781
|
-
}
|
|
4782
|
-
return false;
|
|
4783
|
-
}
|
|
4784
|
-
function toNumber(value) {
|
|
4785
|
-
if (typeof value === "number") return value;
|
|
4786
|
-
if (typeof value === "string") {
|
|
4787
|
-
const n = Number(value);
|
|
4788
|
-
return isNaN(n) ? null : n;
|
|
4789
|
-
}
|
|
4790
|
-
return null;
|
|
4791
|
-
}
|
|
4792
|
-
function toString(value) {
|
|
4793
|
-
if (typeof value === "string") return value;
|
|
4794
|
-
return null;
|
|
4795
|
-
}
|
|
4796
|
-
function semverCmp(actual, expected) {
|
|
4797
|
-
if (typeof actual !== "string" || typeof expected !== "string") return null;
|
|
4798
|
-
try {
|
|
4799
|
-
const a = (0, import_semver.parse)(actual);
|
|
4800
|
-
const b = (0, import_semver.parse)(expected);
|
|
4801
|
-
if (!a || !b) return null;
|
|
4802
|
-
return (0, import_semver.compare)(a, b);
|
|
4803
|
-
} catch {
|
|
4804
|
-
return null;
|
|
4805
|
-
}
|
|
4806
|
-
}
|
|
4807
|
-
function evaluateFlag(flag, config, context, segmentIndex) {
|
|
4808
|
-
const effectiveDefault = flag.environment_default_value ?? flag.default_value;
|
|
4809
|
-
if (flag.status !== "active") {
|
|
4810
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4811
|
-
}
|
|
4812
|
-
if (!flag.environment_enabled) {
|
|
4813
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4814
|
-
}
|
|
4815
|
-
const bucketIdentifier = getBucketIdentifier(context);
|
|
4816
|
-
for (const rule of flag.rules) {
|
|
4817
|
-
if (!rule.enabled) continue;
|
|
4818
|
-
if (rule.segment_ids.length > 0) {
|
|
4819
|
-
const segmentMatched = rule.segment_ids.some((segId) => {
|
|
4820
|
-
const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
|
|
4821
|
-
if (!segment) return false;
|
|
4822
|
-
return userMatchesSegment(segment, context);
|
|
4823
|
-
});
|
|
4824
|
-
if (!segmentMatched) continue;
|
|
4825
|
-
}
|
|
4826
|
-
if (!allConditionsMatch(rule.conditions, context)) continue;
|
|
4827
|
-
if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
|
|
4828
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4829
|
-
if (bucket >= rule.rollout_percentage) continue;
|
|
4830
|
-
return {
|
|
4831
|
-
flag_id: flag.flag_id,
|
|
4832
|
-
flag_key: flag.flag_key,
|
|
4833
|
-
environment: config.environment,
|
|
4834
|
-
value: rule.serve_value,
|
|
4835
|
-
reason: "rule_match",
|
|
4836
|
-
matched_rule_id: rule.id,
|
|
4837
|
-
variant_key: null,
|
|
4838
|
-
bucket
|
|
4839
|
-
};
|
|
4840
|
-
}
|
|
4841
|
-
return {
|
|
4842
|
-
flag_id: flag.flag_id,
|
|
4843
|
-
flag_key: flag.flag_key,
|
|
4844
|
-
environment: config.environment,
|
|
4845
|
-
value: rule.serve_value,
|
|
4846
|
-
reason: "rule_match",
|
|
4847
|
-
matched_rule_id: rule.id,
|
|
4848
|
-
variant_key: null,
|
|
4849
|
-
bucket: null
|
|
4850
|
-
};
|
|
4851
|
-
}
|
|
4852
|
-
if (flag.variants.length > 0) {
|
|
4853
|
-
const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
|
|
4854
|
-
if (totalWeight > 0) {
|
|
4855
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4856
|
-
const scaled = Math.floor(bucket * totalWeight / 1e4);
|
|
4857
|
-
let cursor = 0;
|
|
4858
|
-
for (const variant of flag.variants) {
|
|
4859
|
-
cursor += variant.weight;
|
|
4860
|
-
if (scaled < cursor) {
|
|
4861
|
-
return {
|
|
4862
|
-
flag_id: flag.flag_id,
|
|
4863
|
-
flag_key: flag.flag_key,
|
|
4864
|
-
environment: config.environment,
|
|
4865
|
-
value: variant.value,
|
|
4866
|
-
reason: "variant",
|
|
4867
|
-
matched_rule_id: null,
|
|
4868
|
-
variant_key: variant.variant_key,
|
|
4869
|
-
bucket
|
|
4870
|
-
};
|
|
4871
|
-
}
|
|
4872
|
-
}
|
|
4873
|
-
}
|
|
4874
|
-
}
|
|
4875
|
-
return result(flag, config.environment, effectiveDefault, "default");
|
|
4876
|
-
}
|
|
4877
|
-
function getBucketIdentifier(context) {
|
|
4878
|
-
return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
|
|
4879
|
-
}
|
|
4880
|
-
function userMatchesSegment(segment, context) {
|
|
4881
|
-
const identifiers = [context.user_id, context.email, context.session_id].filter(
|
|
4882
|
-
(v) => v !== void 0 && v !== null
|
|
4883
|
-
);
|
|
4884
|
-
if (identifiers.some((id) => segment.excluded_users.includes(id))) {
|
|
4885
|
-
return false;
|
|
4886
|
-
}
|
|
4887
|
-
if (identifiers.some((id) => segment.included_users.includes(id))) {
|
|
4888
|
-
return true;
|
|
4889
|
-
}
|
|
4890
|
-
return allConditionsMatch(segment.conditions, context);
|
|
4891
|
-
}
|
|
4892
|
-
function result(flag, environment, value, reason) {
|
|
4893
|
-
return {
|
|
4894
|
-
flag_id: flag.flag_id,
|
|
4895
|
-
flag_key: flag.flag_key,
|
|
4896
|
-
environment,
|
|
4897
|
-
value,
|
|
4898
|
-
reason,
|
|
4899
|
-
matched_rule_id: null,
|
|
4900
|
-
variant_key: null,
|
|
4901
|
-
bucket: null
|
|
4902
|
-
};
|
|
4903
|
-
}
|
|
4904
|
-
var FlagClient = class {
|
|
4905
|
-
constructor(options) {
|
|
4906
|
-
this.config = null;
|
|
4907
|
-
this.flagIndex = /* @__PURE__ */ new Map();
|
|
4908
|
-
this.segmentIndex = /* @__PURE__ */ new Map();
|
|
4909
|
-
this.lastETag = "";
|
|
4910
|
-
this.streamState = "idle";
|
|
4911
|
-
this.pollTimer = null;
|
|
4912
|
-
this.reconnectTimer = null;
|
|
4913
|
-
this.telemetryTimer = null;
|
|
4914
|
-
this.abortController = null;
|
|
4915
|
-
this.initPromise = null;
|
|
4916
|
-
this.telemetryCounters = /* @__PURE__ */ new Map();
|
|
4917
|
-
this.isShuttingDown = false;
|
|
4918
|
-
this.streamConnectInFlight = false;
|
|
4919
|
-
this.apiKey = options.apiKey;
|
|
4920
|
-
this.environment = options.environment;
|
|
4921
|
-
this.gatewayUrl = options.gatewayUrl;
|
|
4922
|
-
}
|
|
4923
|
-
async init() {
|
|
4924
|
-
this.isShuttingDown = false;
|
|
4925
|
-
if (this.config) return;
|
|
4926
|
-
if (this.initPromise) return this.initPromise;
|
|
4927
|
-
this.initPromise = this.doInit();
|
|
4928
|
-
try {
|
|
4929
|
-
await this.initPromise;
|
|
4930
|
-
} finally {
|
|
4931
|
-
this.initPromise = null;
|
|
4932
|
-
}
|
|
4933
|
-
}
|
|
4934
|
-
async doInit() {
|
|
4935
|
-
const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
|
|
4936
|
-
headers: { "x-api-key": this.apiKey }
|
|
4937
|
-
});
|
|
4938
|
-
if (resp.status === 403) throw new Error("Secret API key required for /config");
|
|
4939
|
-
if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
|
|
4940
|
-
const json = await resp.json();
|
|
4941
|
-
this.config = json.data;
|
|
4942
|
-
this.buildIndexes();
|
|
4943
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
4944
|
-
this.connectStream();
|
|
4945
|
-
this.startTelemetryFlush();
|
|
4946
|
-
}
|
|
4947
|
-
buildIndexes() {
|
|
4948
|
-
this.flagIndex.clear();
|
|
4949
|
-
this.segmentIndex.clear();
|
|
4950
|
-
if (!this.config) return;
|
|
4951
|
-
for (const flag of this.config.flags) {
|
|
4952
|
-
this.flagIndex.set(flag.flag_key, flag);
|
|
4953
|
-
}
|
|
4954
|
-
for (const segment of this.config.segments) {
|
|
4955
|
-
this.segmentIndex.set(segment.id, segment);
|
|
4956
|
-
}
|
|
4957
|
-
}
|
|
4958
|
-
evaluate(flagKey, context) {
|
|
4959
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4960
|
-
const flagConfig = this.flagIndex.get(flagKey);
|
|
4961
|
-
if (!flagConfig) {
|
|
4962
|
-
return {
|
|
4963
|
-
flag_id: "",
|
|
4964
|
-
flag_key: flagKey,
|
|
4965
|
-
environment: this.environment,
|
|
4966
|
-
value: null,
|
|
4967
|
-
reason: "not_found",
|
|
4968
|
-
matched_rule_id: null,
|
|
4969
|
-
variant_key: null,
|
|
4970
|
-
bucket: null
|
|
4971
|
-
};
|
|
4972
|
-
}
|
|
4973
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4974
|
-
this.recordTelemetry(result2);
|
|
4975
|
-
return result2;
|
|
4976
|
-
}
|
|
4977
|
-
evaluateBatch(flagKeys, context) {
|
|
4978
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4979
|
-
const results = {};
|
|
4980
|
-
for (const key of flagKeys) {
|
|
4981
|
-
const flagConfig = this.flagIndex.get(key);
|
|
4982
|
-
if (flagConfig) {
|
|
4983
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4984
|
-
this.recordTelemetry(result2);
|
|
4985
|
-
results[key] = result2;
|
|
4986
|
-
}
|
|
4987
|
-
}
|
|
4988
|
-
return results;
|
|
4989
|
-
}
|
|
4990
|
-
async shutdown() {
|
|
4991
|
-
this.isShuttingDown = true;
|
|
4992
|
-
this.streamState = "idle";
|
|
4993
|
-
this.abortController?.abort();
|
|
4994
|
-
this.abortController = null;
|
|
4995
|
-
if (this.pollTimer) {
|
|
4996
|
-
clearInterval(this.pollTimer);
|
|
4997
|
-
this.pollTimer = null;
|
|
4998
|
-
}
|
|
4999
|
-
if (this.reconnectTimer) {
|
|
5000
|
-
clearInterval(this.reconnectTimer);
|
|
5001
|
-
this.reconnectTimer = null;
|
|
5002
|
-
}
|
|
5003
|
-
if (this.telemetryTimer) {
|
|
5004
|
-
clearInterval(this.telemetryTimer);
|
|
5005
|
-
this.telemetryTimer = null;
|
|
5006
|
-
}
|
|
5007
|
-
await this.flushTelemetry();
|
|
5008
|
-
}
|
|
5009
|
-
// ======== SSE Streaming ========
|
|
5010
|
-
async connectStream() {
|
|
5011
|
-
if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
|
|
5012
|
-
this.streamConnectInFlight = true;
|
|
5013
|
-
this.abortController?.abort();
|
|
5014
|
-
const abortController = new AbortController();
|
|
5015
|
-
this.abortController = abortController;
|
|
5016
|
-
const shouldResumePolling = this.streamState !== "polling";
|
|
5017
|
-
let startPolling = shouldResumePolling;
|
|
5018
|
-
try {
|
|
5019
|
-
const resp = await fetch(
|
|
5020
|
-
`${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
|
|
5021
|
-
{
|
|
5022
|
-
headers: {
|
|
5023
|
-
"x-api-key": this.apiKey,
|
|
5024
|
-
"Last-Event-ID": String(this.config?.version ?? 0)
|
|
5025
|
-
},
|
|
5026
|
-
signal: abortController.signal
|
|
5027
|
-
}
|
|
5028
|
-
);
|
|
5029
|
-
if (resp.ok && resp.body) {
|
|
5030
|
-
this.streamState = "streaming";
|
|
5031
|
-
this.stopPolling();
|
|
5032
|
-
startPolling = false;
|
|
5033
|
-
const reader = resp.body.getReader();
|
|
5034
|
-
const decoder = new TextDecoder();
|
|
5035
|
-
let buffer = "";
|
|
5036
|
-
while (true) {
|
|
5037
|
-
const { done, value } = await reader.read();
|
|
5038
|
-
if (done) break;
|
|
5039
|
-
buffer += decoder.decode(value, { stream: true });
|
|
5040
|
-
let idx;
|
|
5041
|
-
while ((idx = buffer.indexOf("\n\n")) !== -1) {
|
|
5042
|
-
const frame = buffer.slice(0, idx);
|
|
5043
|
-
buffer = buffer.slice(idx + 2);
|
|
5044
|
-
this.handleSseFrame(frame);
|
|
5045
|
-
}
|
|
5046
|
-
}
|
|
5047
|
-
if (this.streamState === "streaming") {
|
|
5048
|
-
this.streamState = "idle";
|
|
5049
|
-
startPolling = true;
|
|
5050
|
-
}
|
|
5051
|
-
}
|
|
5052
|
-
} catch {
|
|
5053
|
-
startPolling = !abortController.signal.aborted && shouldResumePolling;
|
|
5054
|
-
} finally {
|
|
5055
|
-
this.streamConnectInFlight = false;
|
|
5056
|
-
}
|
|
5057
|
-
if (!this.isShuttingDown && startPolling) {
|
|
5058
|
-
this.startPolling();
|
|
5059
|
-
}
|
|
5060
|
-
}
|
|
5061
|
-
handleSseFrame(frame) {
|
|
5062
|
-
let eventType = "";
|
|
5063
|
-
let data = "";
|
|
5064
|
-
for (const line of frame.split("\n")) {
|
|
5065
|
-
if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
5066
|
-
else if (line.startsWith("data:")) data += line.slice(5).trim();
|
|
5067
|
-
}
|
|
5068
|
-
if (eventType === "config" && data) {
|
|
5069
|
-
try {
|
|
5070
|
-
const parsed = JSON.parse(data);
|
|
5071
|
-
const newConfig = parsed.data;
|
|
5072
|
-
if (newConfig && newConfig.version !== void 0) {
|
|
5073
|
-
this.config = newConfig;
|
|
5074
|
-
this.buildIndexes();
|
|
5075
|
-
}
|
|
5076
|
-
} catch {
|
|
5077
|
-
}
|
|
5078
|
-
}
|
|
5079
|
-
}
|
|
5080
|
-
// ======== Polling Fallback ========
|
|
5081
|
-
startPolling() {
|
|
5082
|
-
if (this.streamState === "polling") return;
|
|
5083
|
-
this.streamState = "polling";
|
|
5084
|
-
this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
|
|
5085
|
-
this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
|
|
5086
|
-
}
|
|
5087
|
-
stopPolling() {
|
|
5088
|
-
if (this.pollTimer) {
|
|
5089
|
-
clearInterval(this.pollTimer);
|
|
5090
|
-
this.pollTimer = null;
|
|
5091
|
-
}
|
|
5092
|
-
if (this.reconnectTimer) {
|
|
5093
|
-
clearInterval(this.reconnectTimer);
|
|
5094
|
-
this.reconnectTimer = null;
|
|
5095
|
-
}
|
|
5096
|
-
}
|
|
5097
|
-
async pollConfig() {
|
|
5098
|
-
try {
|
|
5099
|
-
const headers2 = { "x-api-key": this.apiKey };
|
|
5100
|
-
if (this.lastETag) headers2["if-none-match"] = this.lastETag;
|
|
5101
|
-
const resp = await fetch(
|
|
5102
|
-
`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
|
|
5103
|
-
{ headers: headers2 }
|
|
5104
|
-
);
|
|
5105
|
-
if (resp.status === 304) return;
|
|
5106
|
-
if (!resp.ok) return;
|
|
5107
|
-
const json = await resp.json();
|
|
5108
|
-
this.config = json.data;
|
|
5109
|
-
this.buildIndexes();
|
|
5110
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
5111
|
-
} catch {
|
|
5112
|
-
}
|
|
5113
|
-
}
|
|
5114
|
-
// ======== Telemetry ========
|
|
5115
|
-
recordTelemetry(evaluation) {
|
|
5116
|
-
const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
|
|
5117
|
-
const existing = this.telemetryCounters.get(key);
|
|
5118
|
-
if (existing) {
|
|
5119
|
-
existing.count++;
|
|
5120
|
-
if (evaluation.value === true) existing.true_count++;
|
|
5121
|
-
else if (evaluation.value === false) existing.false_count++;
|
|
5122
|
-
} else {
|
|
5123
|
-
this.telemetryCounters.set(key, {
|
|
5124
|
-
flag_key: evaluation.flag_key,
|
|
5125
|
-
flag_id: evaluation.flag_id,
|
|
5126
|
-
reason: evaluation.reason,
|
|
5127
|
-
count: 1,
|
|
5128
|
-
true_count: evaluation.value === true ? 1 : 0,
|
|
5129
|
-
false_count: evaluation.value === false ? 1 : 0
|
|
5130
|
-
});
|
|
5131
|
-
}
|
|
5132
|
-
}
|
|
5133
|
-
startTelemetryFlush() {
|
|
5134
|
-
this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
|
|
5135
|
-
}
|
|
5136
|
-
async flushTelemetry() {
|
|
5137
|
-
if (this.telemetryCounters.size === 0) return;
|
|
5138
|
-
const evaluations = Array.from(this.telemetryCounters.values());
|
|
5139
|
-
this.telemetryCounters.clear();
|
|
5140
|
-
try {
|
|
5141
|
-
await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
|
|
5142
|
-
method: "POST",
|
|
5143
|
-
headers: {
|
|
5144
|
-
"Content-Type": "application/json",
|
|
5145
|
-
"x-api-key": this.apiKey
|
|
5146
|
-
},
|
|
5147
|
-
body: JSON.stringify({
|
|
5148
|
-
environment: this.environment,
|
|
5149
|
-
evaluations
|
|
5150
|
-
})
|
|
5151
|
-
});
|
|
5152
|
-
} catch {
|
|
5153
|
-
for (const counter of evaluations) {
|
|
5154
|
-
const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
|
|
5155
|
-
const existing = this.telemetryCounters.get(key);
|
|
5156
|
-
if (existing) {
|
|
5157
|
-
existing.count += counter.count;
|
|
5158
|
-
existing.true_count += counter.true_count;
|
|
5159
|
-
existing.false_count += counter.false_count;
|
|
5160
|
-
} else {
|
|
5161
|
-
this.telemetryCounters.set(key, counter);
|
|
5162
|
-
}
|
|
5163
|
-
}
|
|
5164
|
-
}
|
|
5165
|
-
}
|
|
5166
|
-
};
|
|
5167
|
-
|
|
5168
5204
|
// src/server/bootstrap-flags.ts
|
|
5205
|
+
var import_server2 = __toESM(require_server());
|
|
5169
5206
|
var _clients = /* @__PURE__ */ new Map();
|
|
5170
5207
|
var _initPromises = /* @__PURE__ */ new Map();
|
|
5171
5208
|
var _serverClient = null;
|
|
@@ -5193,7 +5230,7 @@ async function getFlagClient(environment) {
|
|
|
5193
5230
|
const pending = _initPromises.get(key);
|
|
5194
5231
|
if (pending) return pending;
|
|
5195
5232
|
const promise = (async () => {
|
|
5196
|
-
const client = new FlagClient({ apiKey, environment, gatewayUrl });
|
|
5233
|
+
const client = new import_server2.FlagClient({ apiKey, environment, gatewayUrl });
|
|
5197
5234
|
await Promise.race([
|
|
5198
5235
|
client.init(),
|
|
5199
5236
|
new Promise(
|
|
@@ -5242,8 +5279,8 @@ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext =
|
|
|
5242
5279
|
const clientIp = extractClientIp(hdrs);
|
|
5243
5280
|
const context = { ...extraContext };
|
|
5244
5281
|
if (clientIp) context.ip_address = clientIp;
|
|
5245
|
-
const
|
|
5246
|
-
return
|
|
5282
|
+
const result = await getServerClient().flags.evaluateBatch(flagKeys, context, environment);
|
|
5283
|
+
return result || {};
|
|
5247
5284
|
} catch {
|
|
5248
5285
|
return {};
|
|
5249
5286
|
}
|
|
@@ -5393,15 +5430,15 @@ async function getAppSecret(key) {
|
|
|
5393
5430
|
}
|
|
5394
5431
|
try {
|
|
5395
5432
|
const client = createServerClient();
|
|
5396
|
-
const
|
|
5397
|
-
if (!noCache &&
|
|
5433
|
+
const result = await client.secrets.get(key);
|
|
5434
|
+
if (!noCache && result) {
|
|
5398
5435
|
secretsCache[key] = {
|
|
5399
|
-
value:
|
|
5400
|
-
version:
|
|
5436
|
+
value: result.value,
|
|
5437
|
+
version: result.version,
|
|
5401
5438
|
cachedAt: Date.now()
|
|
5402
5439
|
};
|
|
5403
5440
|
}
|
|
5404
|
-
return
|
|
5441
|
+
return result?.value;
|
|
5405
5442
|
} catch (error) {
|
|
5406
5443
|
if (error instanceof ScaleMuleApiError && error.code === "SECRET_NOT_FOUND") {
|
|
5407
5444
|
return void 0;
|
|
@@ -5452,17 +5489,17 @@ async function getBundle(key, resolve = true) {
|
|
|
5452
5489
|
}
|
|
5453
5490
|
try {
|
|
5454
5491
|
const client = createServerClient();
|
|
5455
|
-
const
|
|
5456
|
-
if (!noCache &&
|
|
5492
|
+
const result = await client.bundles.get(key, resolve);
|
|
5493
|
+
if (!noCache && result) {
|
|
5457
5494
|
bundlesCache[key] = {
|
|
5458
|
-
type:
|
|
5459
|
-
data:
|
|
5460
|
-
version:
|
|
5461
|
-
inheritsFrom:
|
|
5495
|
+
type: result.type,
|
|
5496
|
+
data: result.data,
|
|
5497
|
+
version: result.version,
|
|
5498
|
+
inheritsFrom: result.inherits_from,
|
|
5462
5499
|
cachedAt: Date.now()
|
|
5463
5500
|
};
|
|
5464
5501
|
}
|
|
5465
|
-
return
|
|
5502
|
+
return result?.data;
|
|
5466
5503
|
} catch (error) {
|
|
5467
5504
|
if (error instanceof ScaleMuleApiError && error.code === "BUNDLE_NOT_FOUND") {
|
|
5468
5505
|
return void 0;
|