@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.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
978
|
-
cache.set(memoKey,
|
|
979
|
-
return
|
|
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
|
|
1039
|
+
let result = true;
|
|
1034
1040
|
const remainingComparators = comparators.slice();
|
|
1035
1041
|
let testComparator = remainingComparators.pop();
|
|
1036
|
-
while (
|
|
1037
|
-
|
|
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
|
|
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) {
|
|
@@ -3320,7 +3866,7 @@ function createAuthRoutes(config = {}) {
|
|
|
3320
3866
|
if (!email) {
|
|
3321
3867
|
return errorResponse("VALIDATION_ERROR", "Email required", 400);
|
|
3322
3868
|
}
|
|
3323
|
-
const
|
|
3869
|
+
const result = await sm.auth.forgotPassword(email, { clientContext });
|
|
3324
3870
|
return successResponse({ message: "If an account exists, a reset email has been sent" });
|
|
3325
3871
|
}
|
|
3326
3872
|
// ==================== Reset Password ====================
|
|
@@ -4465,9 +5011,9 @@ var CODE_TO_STATUS = {
|
|
|
4465
5011
|
function errorCodeToStatus(code) {
|
|
4466
5012
|
return CODE_TO_STATUS[code.toLowerCase()] || 400;
|
|
4467
5013
|
}
|
|
4468
|
-
function unwrap(
|
|
4469
|
-
if (
|
|
4470
|
-
const envelope =
|
|
5014
|
+
function unwrap(result) {
|
|
5015
|
+
if (result !== null && result !== void 0 && typeof result === "object" && ("success" in result || "error" in result) && "data" in result) {
|
|
5016
|
+
const envelope = result;
|
|
4471
5017
|
if (envelope.error || envelope.success === false) {
|
|
4472
5018
|
const err = envelope.error;
|
|
4473
5019
|
const code = err?.code || "UNKNOWN_ERROR";
|
|
@@ -4481,7 +5027,7 @@ function unwrap(result2) {
|
|
|
4481
5027
|
}
|
|
4482
5028
|
return envelope.data;
|
|
4483
5029
|
}
|
|
4484
|
-
return
|
|
5030
|
+
return result;
|
|
4485
5031
|
}
|
|
4486
5032
|
|
|
4487
5033
|
// src/server/handler.ts
|
|
@@ -4508,10 +5054,10 @@ function apiHandler(handler, options) {
|
|
|
4508
5054
|
searchParams: request.nextUrl.searchParams,
|
|
4509
5055
|
session
|
|
4510
5056
|
};
|
|
4511
|
-
const
|
|
4512
|
-
if (
|
|
4513
|
-
if (
|
|
4514
|
-
return Response.json({ success: true, data:
|
|
5057
|
+
const result = await handler(request, context);
|
|
5058
|
+
if (result instanceof Response) return result;
|
|
5059
|
+
if (result !== void 0) {
|
|
5060
|
+
return Response.json({ success: true, data: result }, { status: 200 });
|
|
4515
5061
|
}
|
|
4516
5062
|
return new Response(null, { status: 204 });
|
|
4517
5063
|
} catch (error) {
|
|
@@ -4558,14 +5104,14 @@ function parseWebhookEvent(payload) {
|
|
|
4558
5104
|
}
|
|
4559
5105
|
async function registerVideoWebhook(url, options) {
|
|
4560
5106
|
const sm = createServerClient(options?.clientConfig);
|
|
4561
|
-
const
|
|
5107
|
+
const result = await sm.webhooks.create({
|
|
4562
5108
|
webhook_name: options?.name || "Video Status Webhook",
|
|
4563
5109
|
url,
|
|
4564
5110
|
events: options?.events || ["video.ready", "video.failed"]
|
|
4565
5111
|
});
|
|
4566
5112
|
return {
|
|
4567
|
-
id:
|
|
4568
|
-
secret:
|
|
5113
|
+
id: result.id,
|
|
5114
|
+
secret: result.secret
|
|
4569
5115
|
};
|
|
4570
5116
|
}
|
|
4571
5117
|
function createWebhookRoutes(config = {}) {
|
|
@@ -4653,517 +5199,8 @@ function createWebhookHandler(config = {}) {
|
|
|
4653
5199
|
};
|
|
4654
5200
|
}
|
|
4655
5201
|
|
|
4656
|
-
// node_modules/@scalemule/sdk/dist/flags/server.mjs
|
|
4657
|
-
var import_semver = __toESM(require_semver2());
|
|
4658
|
-
function hashToBucket(flagKey, identifier, salt) {
|
|
4659
|
-
const hash = createHash("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
|
|
4660
|
-
return hash.readUInt32BE(0) % 1e4;
|
|
4661
|
-
}
|
|
4662
|
-
function allConditionsMatch(conditions, context) {
|
|
4663
|
-
return conditions.every((c) => conditionMatches(c, context));
|
|
4664
|
-
}
|
|
4665
|
-
function conditionMatches(condition, context) {
|
|
4666
|
-
const attributeValue = getAttribute(context, condition.attribute);
|
|
4667
|
-
const op = condition.operator;
|
|
4668
|
-
if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
|
|
4669
|
-
if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
|
|
4670
|
-
if (attributeValue === void 0 || attributeValue === null) return false;
|
|
4671
|
-
switch (op) {
|
|
4672
|
-
case "eq":
|
|
4673
|
-
return compareValues(attributeValue, condition.value) === 0;
|
|
4674
|
-
case "neq":
|
|
4675
|
-
return compareValues(attributeValue, condition.value) !== 0;
|
|
4676
|
-
case "in":
|
|
4677
|
-
return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4678
|
-
case "not_in":
|
|
4679
|
-
return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4680
|
-
case "contains":
|
|
4681
|
-
return containsValue(attributeValue, condition.value);
|
|
4682
|
-
case "starts_with":
|
|
4683
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
|
|
4684
|
-
case "ends_with":
|
|
4685
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
|
|
4686
|
-
case "gt":
|
|
4687
|
-
return compareValues(attributeValue, condition.value) === 1;
|
|
4688
|
-
case "gte": {
|
|
4689
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4690
|
-
return cmp === 1 || cmp === 0;
|
|
4691
|
-
}
|
|
4692
|
-
case "lt":
|
|
4693
|
-
return compareValues(attributeValue, condition.value) === -1;
|
|
4694
|
-
case "lte": {
|
|
4695
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4696
|
-
return cmp === -1 || cmp === 0;
|
|
4697
|
-
}
|
|
4698
|
-
case "regex": {
|
|
4699
|
-
if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
|
|
4700
|
-
try {
|
|
4701
|
-
return new RegExp(condition.value).test(attributeValue);
|
|
4702
|
-
} catch {
|
|
4703
|
-
return false;
|
|
4704
|
-
}
|
|
4705
|
-
}
|
|
4706
|
-
case "semver_eq":
|
|
4707
|
-
return semverCmp(attributeValue, condition.value) === 0;
|
|
4708
|
-
case "semver_neq":
|
|
4709
|
-
return semverCmp(attributeValue, condition.value) !== 0;
|
|
4710
|
-
case "semver_gt":
|
|
4711
|
-
return semverCmp(attributeValue, condition.value) === 1;
|
|
4712
|
-
case "semver_gte": {
|
|
4713
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4714
|
-
return cmp === 1 || cmp === 0;
|
|
4715
|
-
}
|
|
4716
|
-
case "semver_lt":
|
|
4717
|
-
return semverCmp(attributeValue, condition.value) === -1;
|
|
4718
|
-
case "semver_lte": {
|
|
4719
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4720
|
-
return cmp === -1 || cmp === 0;
|
|
4721
|
-
}
|
|
4722
|
-
default:
|
|
4723
|
-
return false;
|
|
4724
|
-
}
|
|
4725
|
-
}
|
|
4726
|
-
function getAttribute(context, key) {
|
|
4727
|
-
switch (key) {
|
|
4728
|
-
case "user_id":
|
|
4729
|
-
return context.user_id;
|
|
4730
|
-
case "email":
|
|
4731
|
-
return context.email;
|
|
4732
|
-
case "session_id":
|
|
4733
|
-
return context.session_id;
|
|
4734
|
-
case "ip_address":
|
|
4735
|
-
return context.ip_address;
|
|
4736
|
-
case "user_agent":
|
|
4737
|
-
return context.user_agent;
|
|
4738
|
-
case "timestamp":
|
|
4739
|
-
return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4740
|
-
default:
|
|
4741
|
-
return context[key];
|
|
4742
|
-
}
|
|
4743
|
-
}
|
|
4744
|
-
function candidateValues(condition) {
|
|
4745
|
-
if (condition.values && condition.values.length > 0) return condition.values;
|
|
4746
|
-
if (condition.value === void 0 || condition.value === null) return [];
|
|
4747
|
-
if (Array.isArray(condition.value)) return condition.value;
|
|
4748
|
-
return [condition.value];
|
|
4749
|
-
}
|
|
4750
|
-
function compareValues(actual, expected) {
|
|
4751
|
-
if (expected === void 0 || expected === null) return null;
|
|
4752
|
-
const numA = toNumber(actual);
|
|
4753
|
-
const numB = toNumber(expected);
|
|
4754
|
-
if (numA !== null && numB !== null) {
|
|
4755
|
-
if (numA < numB) return -1;
|
|
4756
|
-
if (numA > numB) return 1;
|
|
4757
|
-
return 0;
|
|
4758
|
-
}
|
|
4759
|
-
if (typeof actual === "boolean" && typeof expected === "boolean") {
|
|
4760
|
-
if (actual === expected) return 0;
|
|
4761
|
-
return actual ? 1 : -1;
|
|
4762
|
-
}
|
|
4763
|
-
const strA = toString(actual);
|
|
4764
|
-
const strB = toString(expected);
|
|
4765
|
-
if (strA !== null && strB !== null) {
|
|
4766
|
-
if (strA < strB) return -1;
|
|
4767
|
-
if (strA > strB) return 1;
|
|
4768
|
-
return 0;
|
|
4769
|
-
}
|
|
4770
|
-
return null;
|
|
4771
|
-
}
|
|
4772
|
-
function containsValue(actual, expected) {
|
|
4773
|
-
if (expected === void 0 || expected === null) return false;
|
|
4774
|
-
if (Array.isArray(actual)) {
|
|
4775
|
-
return actual.some((item) => compareValues(item, expected) === 0);
|
|
4776
|
-
}
|
|
4777
|
-
if (typeof actual === "string" && typeof expected === "string") {
|
|
4778
|
-
return actual.includes(expected);
|
|
4779
|
-
}
|
|
4780
|
-
return false;
|
|
4781
|
-
}
|
|
4782
|
-
function toNumber(value) {
|
|
4783
|
-
if (typeof value === "number") return value;
|
|
4784
|
-
if (typeof value === "string") {
|
|
4785
|
-
const n = Number(value);
|
|
4786
|
-
return isNaN(n) ? null : n;
|
|
4787
|
-
}
|
|
4788
|
-
return null;
|
|
4789
|
-
}
|
|
4790
|
-
function toString(value) {
|
|
4791
|
-
if (typeof value === "string") return value;
|
|
4792
|
-
return null;
|
|
4793
|
-
}
|
|
4794
|
-
function semverCmp(actual, expected) {
|
|
4795
|
-
if (typeof actual !== "string" || typeof expected !== "string") return null;
|
|
4796
|
-
try {
|
|
4797
|
-
const a = (0, import_semver.parse)(actual);
|
|
4798
|
-
const b = (0, import_semver.parse)(expected);
|
|
4799
|
-
if (!a || !b) return null;
|
|
4800
|
-
return (0, import_semver.compare)(a, b);
|
|
4801
|
-
} catch {
|
|
4802
|
-
return null;
|
|
4803
|
-
}
|
|
4804
|
-
}
|
|
4805
|
-
function evaluateFlag(flag, config, context, segmentIndex) {
|
|
4806
|
-
const effectiveDefault = flag.environment_default_value ?? flag.default_value;
|
|
4807
|
-
if (flag.status !== "active") {
|
|
4808
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4809
|
-
}
|
|
4810
|
-
if (!flag.environment_enabled) {
|
|
4811
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4812
|
-
}
|
|
4813
|
-
const bucketIdentifier = getBucketIdentifier(context);
|
|
4814
|
-
for (const rule of flag.rules) {
|
|
4815
|
-
if (!rule.enabled) continue;
|
|
4816
|
-
if (rule.segment_ids.length > 0) {
|
|
4817
|
-
const segmentMatched = rule.segment_ids.some((segId) => {
|
|
4818
|
-
const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
|
|
4819
|
-
if (!segment) return false;
|
|
4820
|
-
return userMatchesSegment(segment, context);
|
|
4821
|
-
});
|
|
4822
|
-
if (!segmentMatched) continue;
|
|
4823
|
-
}
|
|
4824
|
-
if (!allConditionsMatch(rule.conditions, context)) continue;
|
|
4825
|
-
if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
|
|
4826
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4827
|
-
if (bucket >= rule.rollout_percentage) continue;
|
|
4828
|
-
return {
|
|
4829
|
-
flag_id: flag.flag_id,
|
|
4830
|
-
flag_key: flag.flag_key,
|
|
4831
|
-
environment: config.environment,
|
|
4832
|
-
value: rule.serve_value,
|
|
4833
|
-
reason: "rule_match",
|
|
4834
|
-
matched_rule_id: rule.id,
|
|
4835
|
-
variant_key: null,
|
|
4836
|
-
bucket
|
|
4837
|
-
};
|
|
4838
|
-
}
|
|
4839
|
-
return {
|
|
4840
|
-
flag_id: flag.flag_id,
|
|
4841
|
-
flag_key: flag.flag_key,
|
|
4842
|
-
environment: config.environment,
|
|
4843
|
-
value: rule.serve_value,
|
|
4844
|
-
reason: "rule_match",
|
|
4845
|
-
matched_rule_id: rule.id,
|
|
4846
|
-
variant_key: null,
|
|
4847
|
-
bucket: null
|
|
4848
|
-
};
|
|
4849
|
-
}
|
|
4850
|
-
if (flag.variants.length > 0) {
|
|
4851
|
-
const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
|
|
4852
|
-
if (totalWeight > 0) {
|
|
4853
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4854
|
-
const scaled = Math.floor(bucket * totalWeight / 1e4);
|
|
4855
|
-
let cursor = 0;
|
|
4856
|
-
for (const variant of flag.variants) {
|
|
4857
|
-
cursor += variant.weight;
|
|
4858
|
-
if (scaled < cursor) {
|
|
4859
|
-
return {
|
|
4860
|
-
flag_id: flag.flag_id,
|
|
4861
|
-
flag_key: flag.flag_key,
|
|
4862
|
-
environment: config.environment,
|
|
4863
|
-
value: variant.value,
|
|
4864
|
-
reason: "variant",
|
|
4865
|
-
matched_rule_id: null,
|
|
4866
|
-
variant_key: variant.variant_key,
|
|
4867
|
-
bucket
|
|
4868
|
-
};
|
|
4869
|
-
}
|
|
4870
|
-
}
|
|
4871
|
-
}
|
|
4872
|
-
}
|
|
4873
|
-
return result(flag, config.environment, effectiveDefault, "default");
|
|
4874
|
-
}
|
|
4875
|
-
function getBucketIdentifier(context) {
|
|
4876
|
-
return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
|
|
4877
|
-
}
|
|
4878
|
-
function userMatchesSegment(segment, context) {
|
|
4879
|
-
const identifiers = [context.user_id, context.email, context.session_id].filter(
|
|
4880
|
-
(v) => v !== void 0 && v !== null
|
|
4881
|
-
);
|
|
4882
|
-
if (identifiers.some((id) => segment.excluded_users.includes(id))) {
|
|
4883
|
-
return false;
|
|
4884
|
-
}
|
|
4885
|
-
if (identifiers.some((id) => segment.included_users.includes(id))) {
|
|
4886
|
-
return true;
|
|
4887
|
-
}
|
|
4888
|
-
return allConditionsMatch(segment.conditions, context);
|
|
4889
|
-
}
|
|
4890
|
-
function result(flag, environment, value, reason) {
|
|
4891
|
-
return {
|
|
4892
|
-
flag_id: flag.flag_id,
|
|
4893
|
-
flag_key: flag.flag_key,
|
|
4894
|
-
environment,
|
|
4895
|
-
value,
|
|
4896
|
-
reason,
|
|
4897
|
-
matched_rule_id: null,
|
|
4898
|
-
variant_key: null,
|
|
4899
|
-
bucket: null
|
|
4900
|
-
};
|
|
4901
|
-
}
|
|
4902
|
-
var FlagClient = class {
|
|
4903
|
-
constructor(options) {
|
|
4904
|
-
this.config = null;
|
|
4905
|
-
this.flagIndex = /* @__PURE__ */ new Map();
|
|
4906
|
-
this.segmentIndex = /* @__PURE__ */ new Map();
|
|
4907
|
-
this.lastETag = "";
|
|
4908
|
-
this.streamState = "idle";
|
|
4909
|
-
this.pollTimer = null;
|
|
4910
|
-
this.reconnectTimer = null;
|
|
4911
|
-
this.telemetryTimer = null;
|
|
4912
|
-
this.abortController = null;
|
|
4913
|
-
this.initPromise = null;
|
|
4914
|
-
this.telemetryCounters = /* @__PURE__ */ new Map();
|
|
4915
|
-
this.isShuttingDown = false;
|
|
4916
|
-
this.streamConnectInFlight = false;
|
|
4917
|
-
this.apiKey = options.apiKey;
|
|
4918
|
-
this.environment = options.environment;
|
|
4919
|
-
this.gatewayUrl = options.gatewayUrl;
|
|
4920
|
-
}
|
|
4921
|
-
async init() {
|
|
4922
|
-
this.isShuttingDown = false;
|
|
4923
|
-
if (this.config) return;
|
|
4924
|
-
if (this.initPromise) return this.initPromise;
|
|
4925
|
-
this.initPromise = this.doInit();
|
|
4926
|
-
try {
|
|
4927
|
-
await this.initPromise;
|
|
4928
|
-
} finally {
|
|
4929
|
-
this.initPromise = null;
|
|
4930
|
-
}
|
|
4931
|
-
}
|
|
4932
|
-
async doInit() {
|
|
4933
|
-
const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
|
|
4934
|
-
headers: { "x-api-key": this.apiKey }
|
|
4935
|
-
});
|
|
4936
|
-
if (resp.status === 403) throw new Error("Secret API key required for /config");
|
|
4937
|
-
if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
|
|
4938
|
-
const json = await resp.json();
|
|
4939
|
-
this.config = json.data;
|
|
4940
|
-
this.buildIndexes();
|
|
4941
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
4942
|
-
this.connectStream();
|
|
4943
|
-
this.startTelemetryFlush();
|
|
4944
|
-
}
|
|
4945
|
-
buildIndexes() {
|
|
4946
|
-
this.flagIndex.clear();
|
|
4947
|
-
this.segmentIndex.clear();
|
|
4948
|
-
if (!this.config) return;
|
|
4949
|
-
for (const flag of this.config.flags) {
|
|
4950
|
-
this.flagIndex.set(flag.flag_key, flag);
|
|
4951
|
-
}
|
|
4952
|
-
for (const segment of this.config.segments) {
|
|
4953
|
-
this.segmentIndex.set(segment.id, segment);
|
|
4954
|
-
}
|
|
4955
|
-
}
|
|
4956
|
-
evaluate(flagKey, context) {
|
|
4957
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4958
|
-
const flagConfig = this.flagIndex.get(flagKey);
|
|
4959
|
-
if (!flagConfig) {
|
|
4960
|
-
return {
|
|
4961
|
-
flag_id: "",
|
|
4962
|
-
flag_key: flagKey,
|
|
4963
|
-
environment: this.environment,
|
|
4964
|
-
value: null,
|
|
4965
|
-
reason: "not_found",
|
|
4966
|
-
matched_rule_id: null,
|
|
4967
|
-
variant_key: null,
|
|
4968
|
-
bucket: null
|
|
4969
|
-
};
|
|
4970
|
-
}
|
|
4971
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4972
|
-
this.recordTelemetry(result2);
|
|
4973
|
-
return result2;
|
|
4974
|
-
}
|
|
4975
|
-
evaluateBatch(flagKeys, context) {
|
|
4976
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4977
|
-
const results = {};
|
|
4978
|
-
for (const key of flagKeys) {
|
|
4979
|
-
const flagConfig = this.flagIndex.get(key);
|
|
4980
|
-
if (flagConfig) {
|
|
4981
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4982
|
-
this.recordTelemetry(result2);
|
|
4983
|
-
results[key] = result2;
|
|
4984
|
-
}
|
|
4985
|
-
}
|
|
4986
|
-
return results;
|
|
4987
|
-
}
|
|
4988
|
-
async shutdown() {
|
|
4989
|
-
this.isShuttingDown = true;
|
|
4990
|
-
this.streamState = "idle";
|
|
4991
|
-
this.abortController?.abort();
|
|
4992
|
-
this.abortController = null;
|
|
4993
|
-
if (this.pollTimer) {
|
|
4994
|
-
clearInterval(this.pollTimer);
|
|
4995
|
-
this.pollTimer = null;
|
|
4996
|
-
}
|
|
4997
|
-
if (this.reconnectTimer) {
|
|
4998
|
-
clearInterval(this.reconnectTimer);
|
|
4999
|
-
this.reconnectTimer = null;
|
|
5000
|
-
}
|
|
5001
|
-
if (this.telemetryTimer) {
|
|
5002
|
-
clearInterval(this.telemetryTimer);
|
|
5003
|
-
this.telemetryTimer = null;
|
|
5004
|
-
}
|
|
5005
|
-
await this.flushTelemetry();
|
|
5006
|
-
}
|
|
5007
|
-
// ======== SSE Streaming ========
|
|
5008
|
-
async connectStream() {
|
|
5009
|
-
if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
|
|
5010
|
-
this.streamConnectInFlight = true;
|
|
5011
|
-
this.abortController?.abort();
|
|
5012
|
-
const abortController = new AbortController();
|
|
5013
|
-
this.abortController = abortController;
|
|
5014
|
-
const shouldResumePolling = this.streamState !== "polling";
|
|
5015
|
-
let startPolling = shouldResumePolling;
|
|
5016
|
-
try {
|
|
5017
|
-
const resp = await fetch(
|
|
5018
|
-
`${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
|
|
5019
|
-
{
|
|
5020
|
-
headers: {
|
|
5021
|
-
"x-api-key": this.apiKey,
|
|
5022
|
-
"Last-Event-ID": String(this.config?.version ?? 0)
|
|
5023
|
-
},
|
|
5024
|
-
signal: abortController.signal
|
|
5025
|
-
}
|
|
5026
|
-
);
|
|
5027
|
-
if (resp.ok && resp.body) {
|
|
5028
|
-
this.streamState = "streaming";
|
|
5029
|
-
this.stopPolling();
|
|
5030
|
-
startPolling = false;
|
|
5031
|
-
const reader = resp.body.getReader();
|
|
5032
|
-
const decoder = new TextDecoder();
|
|
5033
|
-
let buffer = "";
|
|
5034
|
-
while (true) {
|
|
5035
|
-
const { done, value } = await reader.read();
|
|
5036
|
-
if (done) break;
|
|
5037
|
-
buffer += decoder.decode(value, { stream: true });
|
|
5038
|
-
let idx;
|
|
5039
|
-
while ((idx = buffer.indexOf("\n\n")) !== -1) {
|
|
5040
|
-
const frame = buffer.slice(0, idx);
|
|
5041
|
-
buffer = buffer.slice(idx + 2);
|
|
5042
|
-
this.handleSseFrame(frame);
|
|
5043
|
-
}
|
|
5044
|
-
}
|
|
5045
|
-
if (this.streamState === "streaming") {
|
|
5046
|
-
this.streamState = "idle";
|
|
5047
|
-
startPolling = true;
|
|
5048
|
-
}
|
|
5049
|
-
}
|
|
5050
|
-
} catch {
|
|
5051
|
-
startPolling = !abortController.signal.aborted && shouldResumePolling;
|
|
5052
|
-
} finally {
|
|
5053
|
-
this.streamConnectInFlight = false;
|
|
5054
|
-
}
|
|
5055
|
-
if (!this.isShuttingDown && startPolling) {
|
|
5056
|
-
this.startPolling();
|
|
5057
|
-
}
|
|
5058
|
-
}
|
|
5059
|
-
handleSseFrame(frame) {
|
|
5060
|
-
let eventType = "";
|
|
5061
|
-
let data = "";
|
|
5062
|
-
for (const line of frame.split("\n")) {
|
|
5063
|
-
if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
5064
|
-
else if (line.startsWith("data:")) data += line.slice(5).trim();
|
|
5065
|
-
}
|
|
5066
|
-
if (eventType === "config" && data) {
|
|
5067
|
-
try {
|
|
5068
|
-
const parsed = JSON.parse(data);
|
|
5069
|
-
const newConfig = parsed.data;
|
|
5070
|
-
if (newConfig && newConfig.version !== void 0) {
|
|
5071
|
-
this.config = newConfig;
|
|
5072
|
-
this.buildIndexes();
|
|
5073
|
-
}
|
|
5074
|
-
} catch {
|
|
5075
|
-
}
|
|
5076
|
-
}
|
|
5077
|
-
}
|
|
5078
|
-
// ======== Polling Fallback ========
|
|
5079
|
-
startPolling() {
|
|
5080
|
-
if (this.streamState === "polling") return;
|
|
5081
|
-
this.streamState = "polling";
|
|
5082
|
-
this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
|
|
5083
|
-
this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
|
|
5084
|
-
}
|
|
5085
|
-
stopPolling() {
|
|
5086
|
-
if (this.pollTimer) {
|
|
5087
|
-
clearInterval(this.pollTimer);
|
|
5088
|
-
this.pollTimer = null;
|
|
5089
|
-
}
|
|
5090
|
-
if (this.reconnectTimer) {
|
|
5091
|
-
clearInterval(this.reconnectTimer);
|
|
5092
|
-
this.reconnectTimer = null;
|
|
5093
|
-
}
|
|
5094
|
-
}
|
|
5095
|
-
async pollConfig() {
|
|
5096
|
-
try {
|
|
5097
|
-
const headers2 = { "x-api-key": this.apiKey };
|
|
5098
|
-
if (this.lastETag) headers2["if-none-match"] = this.lastETag;
|
|
5099
|
-
const resp = await fetch(
|
|
5100
|
-
`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
|
|
5101
|
-
{ headers: headers2 }
|
|
5102
|
-
);
|
|
5103
|
-
if (resp.status === 304) return;
|
|
5104
|
-
if (!resp.ok) return;
|
|
5105
|
-
const json = await resp.json();
|
|
5106
|
-
this.config = json.data;
|
|
5107
|
-
this.buildIndexes();
|
|
5108
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
5109
|
-
} catch {
|
|
5110
|
-
}
|
|
5111
|
-
}
|
|
5112
|
-
// ======== Telemetry ========
|
|
5113
|
-
recordTelemetry(evaluation) {
|
|
5114
|
-
const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
|
|
5115
|
-
const existing = this.telemetryCounters.get(key);
|
|
5116
|
-
if (existing) {
|
|
5117
|
-
existing.count++;
|
|
5118
|
-
if (evaluation.value === true) existing.true_count++;
|
|
5119
|
-
else if (evaluation.value === false) existing.false_count++;
|
|
5120
|
-
} else {
|
|
5121
|
-
this.telemetryCounters.set(key, {
|
|
5122
|
-
flag_key: evaluation.flag_key,
|
|
5123
|
-
flag_id: evaluation.flag_id,
|
|
5124
|
-
reason: evaluation.reason,
|
|
5125
|
-
count: 1,
|
|
5126
|
-
true_count: evaluation.value === true ? 1 : 0,
|
|
5127
|
-
false_count: evaluation.value === false ? 1 : 0
|
|
5128
|
-
});
|
|
5129
|
-
}
|
|
5130
|
-
}
|
|
5131
|
-
startTelemetryFlush() {
|
|
5132
|
-
this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
|
|
5133
|
-
}
|
|
5134
|
-
async flushTelemetry() {
|
|
5135
|
-
if (this.telemetryCounters.size === 0) return;
|
|
5136
|
-
const evaluations = Array.from(this.telemetryCounters.values());
|
|
5137
|
-
this.telemetryCounters.clear();
|
|
5138
|
-
try {
|
|
5139
|
-
await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
|
|
5140
|
-
method: "POST",
|
|
5141
|
-
headers: {
|
|
5142
|
-
"Content-Type": "application/json",
|
|
5143
|
-
"x-api-key": this.apiKey
|
|
5144
|
-
},
|
|
5145
|
-
body: JSON.stringify({
|
|
5146
|
-
environment: this.environment,
|
|
5147
|
-
evaluations
|
|
5148
|
-
})
|
|
5149
|
-
});
|
|
5150
|
-
} catch {
|
|
5151
|
-
for (const counter of evaluations) {
|
|
5152
|
-
const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
|
|
5153
|
-
const existing = this.telemetryCounters.get(key);
|
|
5154
|
-
if (existing) {
|
|
5155
|
-
existing.count += counter.count;
|
|
5156
|
-
existing.true_count += counter.true_count;
|
|
5157
|
-
existing.false_count += counter.false_count;
|
|
5158
|
-
} else {
|
|
5159
|
-
this.telemetryCounters.set(key, counter);
|
|
5160
|
-
}
|
|
5161
|
-
}
|
|
5162
|
-
}
|
|
5163
|
-
}
|
|
5164
|
-
};
|
|
5165
|
-
|
|
5166
5202
|
// src/server/bootstrap-flags.ts
|
|
5203
|
+
var import_server2 = __toESM(require_server());
|
|
5167
5204
|
var _clients = /* @__PURE__ */ new Map();
|
|
5168
5205
|
var _initPromises = /* @__PURE__ */ new Map();
|
|
5169
5206
|
var _serverClient = null;
|
|
@@ -5191,7 +5228,7 @@ async function getFlagClient(environment) {
|
|
|
5191
5228
|
const pending = _initPromises.get(key);
|
|
5192
5229
|
if (pending) return pending;
|
|
5193
5230
|
const promise = (async () => {
|
|
5194
|
-
const client = new FlagClient({ apiKey, environment, gatewayUrl });
|
|
5231
|
+
const client = new import_server2.FlagClient({ apiKey, environment, gatewayUrl });
|
|
5195
5232
|
await Promise.race([
|
|
5196
5233
|
client.init(),
|
|
5197
5234
|
new Promise(
|
|
@@ -5240,8 +5277,8 @@ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext =
|
|
|
5240
5277
|
const clientIp = extractClientIp(hdrs);
|
|
5241
5278
|
const context = { ...extraContext };
|
|
5242
5279
|
if (clientIp) context.ip_address = clientIp;
|
|
5243
|
-
const
|
|
5244
|
-
return
|
|
5280
|
+
const result = await getServerClient().flags.evaluateBatch(flagKeys, context, environment);
|
|
5281
|
+
return result || {};
|
|
5245
5282
|
} catch {
|
|
5246
5283
|
return {};
|
|
5247
5284
|
}
|
|
@@ -5391,15 +5428,15 @@ async function getAppSecret(key) {
|
|
|
5391
5428
|
}
|
|
5392
5429
|
try {
|
|
5393
5430
|
const client = createServerClient();
|
|
5394
|
-
const
|
|
5395
|
-
if (!noCache &&
|
|
5431
|
+
const result = await client.secrets.get(key);
|
|
5432
|
+
if (!noCache && result) {
|
|
5396
5433
|
secretsCache[key] = {
|
|
5397
|
-
value:
|
|
5398
|
-
version:
|
|
5434
|
+
value: result.value,
|
|
5435
|
+
version: result.version,
|
|
5399
5436
|
cachedAt: Date.now()
|
|
5400
5437
|
};
|
|
5401
5438
|
}
|
|
5402
|
-
return
|
|
5439
|
+
return result?.value;
|
|
5403
5440
|
} catch (error) {
|
|
5404
5441
|
if (error instanceof ScaleMuleApiError && error.code === "SECRET_NOT_FOUND") {
|
|
5405
5442
|
return void 0;
|
|
@@ -5450,17 +5487,17 @@ async function getBundle(key, resolve = true) {
|
|
|
5450
5487
|
}
|
|
5451
5488
|
try {
|
|
5452
5489
|
const client = createServerClient();
|
|
5453
|
-
const
|
|
5454
|
-
if (!noCache &&
|
|
5490
|
+
const result = await client.bundles.get(key, resolve);
|
|
5491
|
+
if (!noCache && result) {
|
|
5455
5492
|
bundlesCache[key] = {
|
|
5456
|
-
type:
|
|
5457
|
-
data:
|
|
5458
|
-
version:
|
|
5459
|
-
inheritsFrom:
|
|
5493
|
+
type: result.type,
|
|
5494
|
+
data: result.data,
|
|
5495
|
+
version: result.version,
|
|
5496
|
+
inheritsFrom: result.inherits_from,
|
|
5460
5497
|
cachedAt: Date.now()
|
|
5461
5498
|
};
|
|
5462
5499
|
}
|
|
5463
|
-
return
|
|
5500
|
+
return result?.data;
|
|
5464
5501
|
} catch (error) {
|
|
5465
5502
|
if (error instanceof ScaleMuleApiError && error.code === "BUNDLE_NOT_FOUND") {
|
|
5466
5503
|
return void 0;
|