@scalemule/nextjs 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +62 -3
- package/dist/index.mjs +62 -4
- package/dist/server/index.js +678 -637
- package/dist/server/index.mjs +679 -638
- package/package.json +2 -2
- package/dist/index-DTWyUcyd.d.mts +0 -919
- package/dist/index-DTWyUcyd.d.ts +0 -919
- package/dist/ledvery-CxPzZpxP.d.mts +0 -44
- package/dist/ledvery-CxPzZpxP.d.ts +0 -44
- package/dist/server/ledvery.d.mts +0 -1
- package/dist/server/ledvery.d.ts +0 -1
- package/dist/server/ledvery.js +0 -336
- package/dist/server/ledvery.mjs +0 -333
- package/dist/webhook-handler-CTx4Uh8u.d.ts +0 -808
- package/dist/webhook-handler-DsxJS_He.d.mts +0 -808
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) {
|
|
@@ -3313,7 +3859,7 @@ function createAuthRoutes(config = {}) {
|
|
|
3313
3859
|
if (!email) {
|
|
3314
3860
|
return errorResponse("VALIDATION_ERROR", "Email required", 400);
|
|
3315
3861
|
}
|
|
3316
|
-
const
|
|
3862
|
+
const result = await sm.auth.forgotPassword(email, { clientContext });
|
|
3317
3863
|
return successResponse({ message: "If an account exists, a reset email has been sent" });
|
|
3318
3864
|
}
|
|
3319
3865
|
// ==================== Reset Password ====================
|
|
@@ -3953,8 +4499,10 @@ function getLedverySession(request) {
|
|
|
3953
4499
|
if (!raw) return null;
|
|
3954
4500
|
try {
|
|
3955
4501
|
const parsed = JSON.parse(raw);
|
|
4502
|
+
const accessToken = getCookie(request, SM_LEDVERY_ACCESS_TOKEN_COOKIE);
|
|
3956
4503
|
return {
|
|
3957
4504
|
idToken: parsed.idToken || "",
|
|
4505
|
+
accessToken,
|
|
3958
4506
|
claims: parsed.claims,
|
|
3959
4507
|
expiresAt: parsed.expiresAt
|
|
3960
4508
|
};
|
|
@@ -4056,9 +4604,11 @@ function createLedveryRoutes(config) {
|
|
|
4056
4604
|
async function handleLogin(request) {
|
|
4057
4605
|
const url = new URL(request.url);
|
|
4058
4606
|
const returnTo = url.searchParams.get("returnTo");
|
|
4607
|
+
const provider = url.searchParams.get("provider");
|
|
4059
4608
|
const validatedReturnTo = validateSafeRedirect(returnTo, { defaultPath: postLoginRedirect });
|
|
4060
4609
|
const authResult = await client.createAuthorizationUrl({
|
|
4061
|
-
scope: defaultScope
|
|
4610
|
+
scope: defaultScope,
|
|
4611
|
+
extraParams: provider ? { upstream: provider } : void 0
|
|
4062
4612
|
});
|
|
4063
4613
|
const response = new Response(null, {
|
|
4064
4614
|
status: 302,
|
|
@@ -4458,9 +5008,9 @@ var CODE_TO_STATUS = {
|
|
|
4458
5008
|
function errorCodeToStatus(code) {
|
|
4459
5009
|
return CODE_TO_STATUS[code.toLowerCase()] || 400;
|
|
4460
5010
|
}
|
|
4461
|
-
function unwrap(
|
|
4462
|
-
if (
|
|
4463
|
-
const envelope =
|
|
5011
|
+
function unwrap(result) {
|
|
5012
|
+
if (result !== null && result !== void 0 && typeof result === "object" && ("success" in result || "error" in result) && "data" in result) {
|
|
5013
|
+
const envelope = result;
|
|
4464
5014
|
if (envelope.error || envelope.success === false) {
|
|
4465
5015
|
const err = envelope.error;
|
|
4466
5016
|
const code = err?.code || "UNKNOWN_ERROR";
|
|
@@ -4474,7 +5024,7 @@ function unwrap(result2) {
|
|
|
4474
5024
|
}
|
|
4475
5025
|
return envelope.data;
|
|
4476
5026
|
}
|
|
4477
|
-
return
|
|
5027
|
+
return result;
|
|
4478
5028
|
}
|
|
4479
5029
|
|
|
4480
5030
|
// src/server/handler.ts
|
|
@@ -4501,10 +5051,10 @@ function apiHandler(handler, options) {
|
|
|
4501
5051
|
searchParams: request.nextUrl.searchParams,
|
|
4502
5052
|
session
|
|
4503
5053
|
};
|
|
4504
|
-
const
|
|
4505
|
-
if (
|
|
4506
|
-
if (
|
|
4507
|
-
return Response.json({ success: true, data:
|
|
5054
|
+
const result = await handler(request, context);
|
|
5055
|
+
if (result instanceof Response) return result;
|
|
5056
|
+
if (result !== void 0) {
|
|
5057
|
+
return Response.json({ success: true, data: result }, { status: 200 });
|
|
4508
5058
|
}
|
|
4509
5059
|
return new Response(null, { status: 204 });
|
|
4510
5060
|
} catch (error) {
|
|
@@ -4551,14 +5101,14 @@ function parseWebhookEvent(payload) {
|
|
|
4551
5101
|
}
|
|
4552
5102
|
async function registerVideoWebhook(url, options) {
|
|
4553
5103
|
const sm = createServerClient(options?.clientConfig);
|
|
4554
|
-
const
|
|
5104
|
+
const result = await sm.webhooks.create({
|
|
4555
5105
|
webhook_name: options?.name || "Video Status Webhook",
|
|
4556
5106
|
url,
|
|
4557
5107
|
events: options?.events || ["video.ready", "video.failed"]
|
|
4558
5108
|
});
|
|
4559
5109
|
return {
|
|
4560
|
-
id:
|
|
4561
|
-
secret:
|
|
5110
|
+
id: result.id,
|
|
5111
|
+
secret: result.secret
|
|
4562
5112
|
};
|
|
4563
5113
|
}
|
|
4564
5114
|
function createWebhookRoutes(config = {}) {
|
|
@@ -4646,517 +5196,8 @@ function createWebhookHandler(config = {}) {
|
|
|
4646
5196
|
};
|
|
4647
5197
|
}
|
|
4648
5198
|
|
|
4649
|
-
// node_modules/@scalemule/sdk/dist/flags/server.mjs
|
|
4650
|
-
var import_semver = __toESM(require_semver2());
|
|
4651
|
-
function hashToBucket(flagKey, identifier, salt) {
|
|
4652
|
-
const hash = createHash("sha256").update(`${salt}.${flagKey}.${identifier}`).digest();
|
|
4653
|
-
return hash.readUInt32BE(0) % 1e4;
|
|
4654
|
-
}
|
|
4655
|
-
function allConditionsMatch(conditions, context) {
|
|
4656
|
-
return conditions.every((c) => conditionMatches(c, context));
|
|
4657
|
-
}
|
|
4658
|
-
function conditionMatches(condition, context) {
|
|
4659
|
-
const attributeValue = getAttribute(context, condition.attribute);
|
|
4660
|
-
const op = condition.operator;
|
|
4661
|
-
if (op === "exists") return attributeValue !== void 0 && attributeValue !== null;
|
|
4662
|
-
if (op === "not_exists") return attributeValue === void 0 || attributeValue === null;
|
|
4663
|
-
if (attributeValue === void 0 || attributeValue === null) return false;
|
|
4664
|
-
switch (op) {
|
|
4665
|
-
case "eq":
|
|
4666
|
-
return compareValues(attributeValue, condition.value) === 0;
|
|
4667
|
-
case "neq":
|
|
4668
|
-
return compareValues(attributeValue, condition.value) !== 0;
|
|
4669
|
-
case "in":
|
|
4670
|
-
return candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4671
|
-
case "not_in":
|
|
4672
|
-
return !candidateValues(condition).some((v) => compareValues(attributeValue, v) === 0);
|
|
4673
|
-
case "contains":
|
|
4674
|
-
return containsValue(attributeValue, condition.value);
|
|
4675
|
-
case "starts_with":
|
|
4676
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.startsWith(condition.value) : false;
|
|
4677
|
-
case "ends_with":
|
|
4678
|
-
return typeof attributeValue === "string" && typeof condition.value === "string" ? attributeValue.endsWith(condition.value) : false;
|
|
4679
|
-
case "gt":
|
|
4680
|
-
return compareValues(attributeValue, condition.value) === 1;
|
|
4681
|
-
case "gte": {
|
|
4682
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4683
|
-
return cmp === 1 || cmp === 0;
|
|
4684
|
-
}
|
|
4685
|
-
case "lt":
|
|
4686
|
-
return compareValues(attributeValue, condition.value) === -1;
|
|
4687
|
-
case "lte": {
|
|
4688
|
-
const cmp = compareValues(attributeValue, condition.value);
|
|
4689
|
-
return cmp === -1 || cmp === 0;
|
|
4690
|
-
}
|
|
4691
|
-
case "regex": {
|
|
4692
|
-
if (typeof attributeValue !== "string" || typeof condition.value !== "string") return false;
|
|
4693
|
-
try {
|
|
4694
|
-
return new RegExp(condition.value).test(attributeValue);
|
|
4695
|
-
} catch {
|
|
4696
|
-
return false;
|
|
4697
|
-
}
|
|
4698
|
-
}
|
|
4699
|
-
case "semver_eq":
|
|
4700
|
-
return semverCmp(attributeValue, condition.value) === 0;
|
|
4701
|
-
case "semver_neq":
|
|
4702
|
-
return semverCmp(attributeValue, condition.value) !== 0;
|
|
4703
|
-
case "semver_gt":
|
|
4704
|
-
return semverCmp(attributeValue, condition.value) === 1;
|
|
4705
|
-
case "semver_gte": {
|
|
4706
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4707
|
-
return cmp === 1 || cmp === 0;
|
|
4708
|
-
}
|
|
4709
|
-
case "semver_lt":
|
|
4710
|
-
return semverCmp(attributeValue, condition.value) === -1;
|
|
4711
|
-
case "semver_lte": {
|
|
4712
|
-
const cmp = semverCmp(attributeValue, condition.value);
|
|
4713
|
-
return cmp === -1 || cmp === 0;
|
|
4714
|
-
}
|
|
4715
|
-
default:
|
|
4716
|
-
return false;
|
|
4717
|
-
}
|
|
4718
|
-
}
|
|
4719
|
-
function getAttribute(context, key) {
|
|
4720
|
-
switch (key) {
|
|
4721
|
-
case "user_id":
|
|
4722
|
-
return context.user_id;
|
|
4723
|
-
case "email":
|
|
4724
|
-
return context.email;
|
|
4725
|
-
case "session_id":
|
|
4726
|
-
return context.session_id;
|
|
4727
|
-
case "ip_address":
|
|
4728
|
-
return context.ip_address;
|
|
4729
|
-
case "user_agent":
|
|
4730
|
-
return context.user_agent;
|
|
4731
|
-
case "timestamp":
|
|
4732
|
-
return context.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4733
|
-
default:
|
|
4734
|
-
return context[key];
|
|
4735
|
-
}
|
|
4736
|
-
}
|
|
4737
|
-
function candidateValues(condition) {
|
|
4738
|
-
if (condition.values && condition.values.length > 0) return condition.values;
|
|
4739
|
-
if (condition.value === void 0 || condition.value === null) return [];
|
|
4740
|
-
if (Array.isArray(condition.value)) return condition.value;
|
|
4741
|
-
return [condition.value];
|
|
4742
|
-
}
|
|
4743
|
-
function compareValues(actual, expected) {
|
|
4744
|
-
if (expected === void 0 || expected === null) return null;
|
|
4745
|
-
const numA = toNumber(actual);
|
|
4746
|
-
const numB = toNumber(expected);
|
|
4747
|
-
if (numA !== null && numB !== null) {
|
|
4748
|
-
if (numA < numB) return -1;
|
|
4749
|
-
if (numA > numB) return 1;
|
|
4750
|
-
return 0;
|
|
4751
|
-
}
|
|
4752
|
-
if (typeof actual === "boolean" && typeof expected === "boolean") {
|
|
4753
|
-
if (actual === expected) return 0;
|
|
4754
|
-
return actual ? 1 : -1;
|
|
4755
|
-
}
|
|
4756
|
-
const strA = toString(actual);
|
|
4757
|
-
const strB = toString(expected);
|
|
4758
|
-
if (strA !== null && strB !== null) {
|
|
4759
|
-
if (strA < strB) return -1;
|
|
4760
|
-
if (strA > strB) return 1;
|
|
4761
|
-
return 0;
|
|
4762
|
-
}
|
|
4763
|
-
return null;
|
|
4764
|
-
}
|
|
4765
|
-
function containsValue(actual, expected) {
|
|
4766
|
-
if (expected === void 0 || expected === null) return false;
|
|
4767
|
-
if (Array.isArray(actual)) {
|
|
4768
|
-
return actual.some((item) => compareValues(item, expected) === 0);
|
|
4769
|
-
}
|
|
4770
|
-
if (typeof actual === "string" && typeof expected === "string") {
|
|
4771
|
-
return actual.includes(expected);
|
|
4772
|
-
}
|
|
4773
|
-
return false;
|
|
4774
|
-
}
|
|
4775
|
-
function toNumber(value) {
|
|
4776
|
-
if (typeof value === "number") return value;
|
|
4777
|
-
if (typeof value === "string") {
|
|
4778
|
-
const n = Number(value);
|
|
4779
|
-
return isNaN(n) ? null : n;
|
|
4780
|
-
}
|
|
4781
|
-
return null;
|
|
4782
|
-
}
|
|
4783
|
-
function toString(value) {
|
|
4784
|
-
if (typeof value === "string") return value;
|
|
4785
|
-
return null;
|
|
4786
|
-
}
|
|
4787
|
-
function semverCmp(actual, expected) {
|
|
4788
|
-
if (typeof actual !== "string" || typeof expected !== "string") return null;
|
|
4789
|
-
try {
|
|
4790
|
-
const a = (0, import_semver.parse)(actual);
|
|
4791
|
-
const b = (0, import_semver.parse)(expected);
|
|
4792
|
-
if (!a || !b) return null;
|
|
4793
|
-
return (0, import_semver.compare)(a, b);
|
|
4794
|
-
} catch {
|
|
4795
|
-
return null;
|
|
4796
|
-
}
|
|
4797
|
-
}
|
|
4798
|
-
function evaluateFlag(flag, config, context, segmentIndex) {
|
|
4799
|
-
const effectiveDefault = flag.environment_default_value ?? flag.default_value;
|
|
4800
|
-
if (flag.status !== "active") {
|
|
4801
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4802
|
-
}
|
|
4803
|
-
if (!flag.environment_enabled) {
|
|
4804
|
-
return result(flag, config.environment, effectiveDefault, "disabled");
|
|
4805
|
-
}
|
|
4806
|
-
const bucketIdentifier = getBucketIdentifier(context);
|
|
4807
|
-
for (const rule of flag.rules) {
|
|
4808
|
-
if (!rule.enabled) continue;
|
|
4809
|
-
if (rule.segment_ids.length > 0) {
|
|
4810
|
-
const segmentMatched = rule.segment_ids.some((segId) => {
|
|
4811
|
-
const segment = segmentIndex ? segmentIndex.get(segId) : config.segments.find((s) => s.id === segId);
|
|
4812
|
-
if (!segment) return false;
|
|
4813
|
-
return userMatchesSegment(segment, context);
|
|
4814
|
-
});
|
|
4815
|
-
if (!segmentMatched) continue;
|
|
4816
|
-
}
|
|
4817
|
-
if (!allConditionsMatch(rule.conditions, context)) continue;
|
|
4818
|
-
if (rule.rollout_percentage !== null && rule.rollout_percentage !== void 0) {
|
|
4819
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4820
|
-
if (bucket >= rule.rollout_percentage) continue;
|
|
4821
|
-
return {
|
|
4822
|
-
flag_id: flag.flag_id,
|
|
4823
|
-
flag_key: flag.flag_key,
|
|
4824
|
-
environment: config.environment,
|
|
4825
|
-
value: rule.serve_value,
|
|
4826
|
-
reason: "rule_match",
|
|
4827
|
-
matched_rule_id: rule.id,
|
|
4828
|
-
variant_key: null,
|
|
4829
|
-
bucket
|
|
4830
|
-
};
|
|
4831
|
-
}
|
|
4832
|
-
return {
|
|
4833
|
-
flag_id: flag.flag_id,
|
|
4834
|
-
flag_key: flag.flag_key,
|
|
4835
|
-
environment: config.environment,
|
|
4836
|
-
value: rule.serve_value,
|
|
4837
|
-
reason: "rule_match",
|
|
4838
|
-
matched_rule_id: rule.id,
|
|
4839
|
-
variant_key: null,
|
|
4840
|
-
bucket: null
|
|
4841
|
-
};
|
|
4842
|
-
}
|
|
4843
|
-
if (flag.variants.length > 0) {
|
|
4844
|
-
const totalWeight = flag.variants.reduce((sum, v) => sum + v.weight, 0);
|
|
4845
|
-
if (totalWeight > 0) {
|
|
4846
|
-
const bucket = hashToBucket(flag.flag_key, bucketIdentifier, config.rollout_salt);
|
|
4847
|
-
const scaled = Math.floor(bucket * totalWeight / 1e4);
|
|
4848
|
-
let cursor = 0;
|
|
4849
|
-
for (const variant of flag.variants) {
|
|
4850
|
-
cursor += variant.weight;
|
|
4851
|
-
if (scaled < cursor) {
|
|
4852
|
-
return {
|
|
4853
|
-
flag_id: flag.flag_id,
|
|
4854
|
-
flag_key: flag.flag_key,
|
|
4855
|
-
environment: config.environment,
|
|
4856
|
-
value: variant.value,
|
|
4857
|
-
reason: "variant",
|
|
4858
|
-
matched_rule_id: null,
|
|
4859
|
-
variant_key: variant.variant_key,
|
|
4860
|
-
bucket
|
|
4861
|
-
};
|
|
4862
|
-
}
|
|
4863
|
-
}
|
|
4864
|
-
}
|
|
4865
|
-
}
|
|
4866
|
-
return result(flag, config.environment, effectiveDefault, "default");
|
|
4867
|
-
}
|
|
4868
|
-
function getBucketIdentifier(context) {
|
|
4869
|
-
return context.user_id ?? context.session_id ?? context.email ?? context.ip_address ?? "anonymous";
|
|
4870
|
-
}
|
|
4871
|
-
function userMatchesSegment(segment, context) {
|
|
4872
|
-
const identifiers = [context.user_id, context.email, context.session_id].filter(
|
|
4873
|
-
(v) => v !== void 0 && v !== null
|
|
4874
|
-
);
|
|
4875
|
-
if (identifiers.some((id) => segment.excluded_users.includes(id))) {
|
|
4876
|
-
return false;
|
|
4877
|
-
}
|
|
4878
|
-
if (identifiers.some((id) => segment.included_users.includes(id))) {
|
|
4879
|
-
return true;
|
|
4880
|
-
}
|
|
4881
|
-
return allConditionsMatch(segment.conditions, context);
|
|
4882
|
-
}
|
|
4883
|
-
function result(flag, environment, value, reason) {
|
|
4884
|
-
return {
|
|
4885
|
-
flag_id: flag.flag_id,
|
|
4886
|
-
flag_key: flag.flag_key,
|
|
4887
|
-
environment,
|
|
4888
|
-
value,
|
|
4889
|
-
reason,
|
|
4890
|
-
matched_rule_id: null,
|
|
4891
|
-
variant_key: null,
|
|
4892
|
-
bucket: null
|
|
4893
|
-
};
|
|
4894
|
-
}
|
|
4895
|
-
var FlagClient = class {
|
|
4896
|
-
constructor(options) {
|
|
4897
|
-
this.config = null;
|
|
4898
|
-
this.flagIndex = /* @__PURE__ */ new Map();
|
|
4899
|
-
this.segmentIndex = /* @__PURE__ */ new Map();
|
|
4900
|
-
this.lastETag = "";
|
|
4901
|
-
this.streamState = "idle";
|
|
4902
|
-
this.pollTimer = null;
|
|
4903
|
-
this.reconnectTimer = null;
|
|
4904
|
-
this.telemetryTimer = null;
|
|
4905
|
-
this.abortController = null;
|
|
4906
|
-
this.initPromise = null;
|
|
4907
|
-
this.telemetryCounters = /* @__PURE__ */ new Map();
|
|
4908
|
-
this.isShuttingDown = false;
|
|
4909
|
-
this.streamConnectInFlight = false;
|
|
4910
|
-
this.apiKey = options.apiKey;
|
|
4911
|
-
this.environment = options.environment;
|
|
4912
|
-
this.gatewayUrl = options.gatewayUrl;
|
|
4913
|
-
}
|
|
4914
|
-
async init() {
|
|
4915
|
-
this.isShuttingDown = false;
|
|
4916
|
-
if (this.config) return;
|
|
4917
|
-
if (this.initPromise) return this.initPromise;
|
|
4918
|
-
this.initPromise = this.doInit();
|
|
4919
|
-
try {
|
|
4920
|
-
await this.initPromise;
|
|
4921
|
-
} finally {
|
|
4922
|
-
this.initPromise = null;
|
|
4923
|
-
}
|
|
4924
|
-
}
|
|
4925
|
-
async doInit() {
|
|
4926
|
-
const resp = await fetch(`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`, {
|
|
4927
|
-
headers: { "x-api-key": this.apiKey }
|
|
4928
|
-
});
|
|
4929
|
-
if (resp.status === 403) throw new Error("Secret API key required for /config");
|
|
4930
|
-
if (!resp.ok) throw new Error(`Config fetch failed: ${resp.status}`);
|
|
4931
|
-
const json = await resp.json();
|
|
4932
|
-
this.config = json.data;
|
|
4933
|
-
this.buildIndexes();
|
|
4934
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
4935
|
-
this.connectStream();
|
|
4936
|
-
this.startTelemetryFlush();
|
|
4937
|
-
}
|
|
4938
|
-
buildIndexes() {
|
|
4939
|
-
this.flagIndex.clear();
|
|
4940
|
-
this.segmentIndex.clear();
|
|
4941
|
-
if (!this.config) return;
|
|
4942
|
-
for (const flag of this.config.flags) {
|
|
4943
|
-
this.flagIndex.set(flag.flag_key, flag);
|
|
4944
|
-
}
|
|
4945
|
-
for (const segment of this.config.segments) {
|
|
4946
|
-
this.segmentIndex.set(segment.id, segment);
|
|
4947
|
-
}
|
|
4948
|
-
}
|
|
4949
|
-
evaluate(flagKey, context) {
|
|
4950
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4951
|
-
const flagConfig = this.flagIndex.get(flagKey);
|
|
4952
|
-
if (!flagConfig) {
|
|
4953
|
-
return {
|
|
4954
|
-
flag_id: "",
|
|
4955
|
-
flag_key: flagKey,
|
|
4956
|
-
environment: this.environment,
|
|
4957
|
-
value: null,
|
|
4958
|
-
reason: "not_found",
|
|
4959
|
-
matched_rule_id: null,
|
|
4960
|
-
variant_key: null,
|
|
4961
|
-
bucket: null
|
|
4962
|
-
};
|
|
4963
|
-
}
|
|
4964
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4965
|
-
this.recordTelemetry(result2);
|
|
4966
|
-
return result2;
|
|
4967
|
-
}
|
|
4968
|
-
evaluateBatch(flagKeys, context) {
|
|
4969
|
-
if (!this.config) throw new Error("FlagClient not initialized \u2014 call init() first");
|
|
4970
|
-
const results = {};
|
|
4971
|
-
for (const key of flagKeys) {
|
|
4972
|
-
const flagConfig = this.flagIndex.get(key);
|
|
4973
|
-
if (flagConfig) {
|
|
4974
|
-
const result2 = evaluateFlag(flagConfig, this.config, context, this.segmentIndex);
|
|
4975
|
-
this.recordTelemetry(result2);
|
|
4976
|
-
results[key] = result2;
|
|
4977
|
-
}
|
|
4978
|
-
}
|
|
4979
|
-
return results;
|
|
4980
|
-
}
|
|
4981
|
-
async shutdown() {
|
|
4982
|
-
this.isShuttingDown = true;
|
|
4983
|
-
this.streamState = "idle";
|
|
4984
|
-
this.abortController?.abort();
|
|
4985
|
-
this.abortController = null;
|
|
4986
|
-
if (this.pollTimer) {
|
|
4987
|
-
clearInterval(this.pollTimer);
|
|
4988
|
-
this.pollTimer = null;
|
|
4989
|
-
}
|
|
4990
|
-
if (this.reconnectTimer) {
|
|
4991
|
-
clearInterval(this.reconnectTimer);
|
|
4992
|
-
this.reconnectTimer = null;
|
|
4993
|
-
}
|
|
4994
|
-
if (this.telemetryTimer) {
|
|
4995
|
-
clearInterval(this.telemetryTimer);
|
|
4996
|
-
this.telemetryTimer = null;
|
|
4997
|
-
}
|
|
4998
|
-
await this.flushTelemetry();
|
|
4999
|
-
}
|
|
5000
|
-
// ======== SSE Streaming ========
|
|
5001
|
-
async connectStream() {
|
|
5002
|
-
if (this.isShuttingDown || this.streamState === "streaming" || this.streamConnectInFlight) return;
|
|
5003
|
-
this.streamConnectInFlight = true;
|
|
5004
|
-
this.abortController?.abort();
|
|
5005
|
-
const abortController = new AbortController();
|
|
5006
|
-
this.abortController = abortController;
|
|
5007
|
-
const shouldResumePolling = this.streamState !== "polling";
|
|
5008
|
-
let startPolling = shouldResumePolling;
|
|
5009
|
-
try {
|
|
5010
|
-
const resp = await fetch(
|
|
5011
|
-
`${this.gatewayUrl}/v1/flags/stream?environment=${encodeURIComponent(this.environment)}`,
|
|
5012
|
-
{
|
|
5013
|
-
headers: {
|
|
5014
|
-
"x-api-key": this.apiKey,
|
|
5015
|
-
"Last-Event-ID": String(this.config?.version ?? 0)
|
|
5016
|
-
},
|
|
5017
|
-
signal: abortController.signal
|
|
5018
|
-
}
|
|
5019
|
-
);
|
|
5020
|
-
if (resp.ok && resp.body) {
|
|
5021
|
-
this.streamState = "streaming";
|
|
5022
|
-
this.stopPolling();
|
|
5023
|
-
startPolling = false;
|
|
5024
|
-
const reader = resp.body.getReader();
|
|
5025
|
-
const decoder = new TextDecoder();
|
|
5026
|
-
let buffer = "";
|
|
5027
|
-
while (true) {
|
|
5028
|
-
const { done, value } = await reader.read();
|
|
5029
|
-
if (done) break;
|
|
5030
|
-
buffer += decoder.decode(value, { stream: true });
|
|
5031
|
-
let idx;
|
|
5032
|
-
while ((idx = buffer.indexOf("\n\n")) !== -1) {
|
|
5033
|
-
const frame = buffer.slice(0, idx);
|
|
5034
|
-
buffer = buffer.slice(idx + 2);
|
|
5035
|
-
this.handleSseFrame(frame);
|
|
5036
|
-
}
|
|
5037
|
-
}
|
|
5038
|
-
if (this.streamState === "streaming") {
|
|
5039
|
-
this.streamState = "idle";
|
|
5040
|
-
startPolling = true;
|
|
5041
|
-
}
|
|
5042
|
-
}
|
|
5043
|
-
} catch {
|
|
5044
|
-
startPolling = !abortController.signal.aborted && shouldResumePolling;
|
|
5045
|
-
} finally {
|
|
5046
|
-
this.streamConnectInFlight = false;
|
|
5047
|
-
}
|
|
5048
|
-
if (!this.isShuttingDown && startPolling) {
|
|
5049
|
-
this.startPolling();
|
|
5050
|
-
}
|
|
5051
|
-
}
|
|
5052
|
-
handleSseFrame(frame) {
|
|
5053
|
-
let eventType = "";
|
|
5054
|
-
let data = "";
|
|
5055
|
-
for (const line of frame.split("\n")) {
|
|
5056
|
-
if (line.startsWith("event:")) eventType = line.slice(6).trim();
|
|
5057
|
-
else if (line.startsWith("data:")) data += line.slice(5).trim();
|
|
5058
|
-
}
|
|
5059
|
-
if (eventType === "config" && data) {
|
|
5060
|
-
try {
|
|
5061
|
-
const parsed = JSON.parse(data);
|
|
5062
|
-
const newConfig = parsed.data;
|
|
5063
|
-
if (newConfig && newConfig.version !== void 0) {
|
|
5064
|
-
this.config = newConfig;
|
|
5065
|
-
this.buildIndexes();
|
|
5066
|
-
}
|
|
5067
|
-
} catch {
|
|
5068
|
-
}
|
|
5069
|
-
}
|
|
5070
|
-
}
|
|
5071
|
-
// ======== Polling Fallback ========
|
|
5072
|
-
startPolling() {
|
|
5073
|
-
if (this.streamState === "polling") return;
|
|
5074
|
-
this.streamState = "polling";
|
|
5075
|
-
this.pollTimer = setInterval(() => void this.pollConfig(), 6e4);
|
|
5076
|
-
this.reconnectTimer = setInterval(() => void this.connectStream(), 3e5);
|
|
5077
|
-
}
|
|
5078
|
-
stopPolling() {
|
|
5079
|
-
if (this.pollTimer) {
|
|
5080
|
-
clearInterval(this.pollTimer);
|
|
5081
|
-
this.pollTimer = null;
|
|
5082
|
-
}
|
|
5083
|
-
if (this.reconnectTimer) {
|
|
5084
|
-
clearInterval(this.reconnectTimer);
|
|
5085
|
-
this.reconnectTimer = null;
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
|
-
async pollConfig() {
|
|
5089
|
-
try {
|
|
5090
|
-
const headers2 = { "x-api-key": this.apiKey };
|
|
5091
|
-
if (this.lastETag) headers2["if-none-match"] = this.lastETag;
|
|
5092
|
-
const resp = await fetch(
|
|
5093
|
-
`${this.gatewayUrl}/v1/flags/config?environment=${encodeURIComponent(this.environment)}`,
|
|
5094
|
-
{ headers: headers2 }
|
|
5095
|
-
);
|
|
5096
|
-
if (resp.status === 304) return;
|
|
5097
|
-
if (!resp.ok) return;
|
|
5098
|
-
const json = await resp.json();
|
|
5099
|
-
this.config = json.data;
|
|
5100
|
-
this.buildIndexes();
|
|
5101
|
-
this.lastETag = resp.headers.get("etag") || "";
|
|
5102
|
-
} catch {
|
|
5103
|
-
}
|
|
5104
|
-
}
|
|
5105
|
-
// ======== Telemetry ========
|
|
5106
|
-
recordTelemetry(evaluation) {
|
|
5107
|
-
const key = `${evaluation.flag_key}:${evaluation.reason}:${String(evaluation.value)}`;
|
|
5108
|
-
const existing = this.telemetryCounters.get(key);
|
|
5109
|
-
if (existing) {
|
|
5110
|
-
existing.count++;
|
|
5111
|
-
if (evaluation.value === true) existing.true_count++;
|
|
5112
|
-
else if (evaluation.value === false) existing.false_count++;
|
|
5113
|
-
} else {
|
|
5114
|
-
this.telemetryCounters.set(key, {
|
|
5115
|
-
flag_key: evaluation.flag_key,
|
|
5116
|
-
flag_id: evaluation.flag_id,
|
|
5117
|
-
reason: evaluation.reason,
|
|
5118
|
-
count: 1,
|
|
5119
|
-
true_count: evaluation.value === true ? 1 : 0,
|
|
5120
|
-
false_count: evaluation.value === false ? 1 : 0
|
|
5121
|
-
});
|
|
5122
|
-
}
|
|
5123
|
-
}
|
|
5124
|
-
startTelemetryFlush() {
|
|
5125
|
-
this.telemetryTimer = setInterval(() => void this.flushTelemetry(), 6e4);
|
|
5126
|
-
}
|
|
5127
|
-
async flushTelemetry() {
|
|
5128
|
-
if (this.telemetryCounters.size === 0) return;
|
|
5129
|
-
const evaluations = Array.from(this.telemetryCounters.values());
|
|
5130
|
-
this.telemetryCounters.clear();
|
|
5131
|
-
try {
|
|
5132
|
-
await fetch(`${this.gatewayUrl}/v1/flags/telemetry`, {
|
|
5133
|
-
method: "POST",
|
|
5134
|
-
headers: {
|
|
5135
|
-
"Content-Type": "application/json",
|
|
5136
|
-
"x-api-key": this.apiKey
|
|
5137
|
-
},
|
|
5138
|
-
body: JSON.stringify({
|
|
5139
|
-
environment: this.environment,
|
|
5140
|
-
evaluations
|
|
5141
|
-
})
|
|
5142
|
-
});
|
|
5143
|
-
} catch {
|
|
5144
|
-
for (const counter of evaluations) {
|
|
5145
|
-
const key = `${counter.flag_key}:${counter.reason}:${counter.count}`;
|
|
5146
|
-
const existing = this.telemetryCounters.get(key);
|
|
5147
|
-
if (existing) {
|
|
5148
|
-
existing.count += counter.count;
|
|
5149
|
-
existing.true_count += counter.true_count;
|
|
5150
|
-
existing.false_count += counter.false_count;
|
|
5151
|
-
} else {
|
|
5152
|
-
this.telemetryCounters.set(key, counter);
|
|
5153
|
-
}
|
|
5154
|
-
}
|
|
5155
|
-
}
|
|
5156
|
-
}
|
|
5157
|
-
};
|
|
5158
|
-
|
|
5159
5199
|
// src/server/bootstrap-flags.ts
|
|
5200
|
+
var import_server2 = __toESM(require_server());
|
|
5160
5201
|
var _clients = /* @__PURE__ */ new Map();
|
|
5161
5202
|
var _initPromises = /* @__PURE__ */ new Map();
|
|
5162
5203
|
var _serverClient = null;
|
|
@@ -5184,7 +5225,7 @@ async function getFlagClient(environment) {
|
|
|
5184
5225
|
const pending = _initPromises.get(key);
|
|
5185
5226
|
if (pending) return pending;
|
|
5186
5227
|
const promise = (async () => {
|
|
5187
|
-
const client = new FlagClient({ apiKey, environment, gatewayUrl });
|
|
5228
|
+
const client = new import_server2.FlagClient({ apiKey, environment, gatewayUrl });
|
|
5188
5229
|
await Promise.race([
|
|
5189
5230
|
client.init(),
|
|
5190
5231
|
new Promise(
|
|
@@ -5233,8 +5274,8 @@ async function getBootstrapFlags(flagKeys, environment = "prod", extraContext =
|
|
|
5233
5274
|
const clientIp = extractClientIp(hdrs);
|
|
5234
5275
|
const context = { ...extraContext };
|
|
5235
5276
|
if (clientIp) context.ip_address = clientIp;
|
|
5236
|
-
const
|
|
5237
|
-
return
|
|
5277
|
+
const result = await getServerClient().flags.evaluateBatch(flagKeys, context, environment);
|
|
5278
|
+
return result || {};
|
|
5238
5279
|
} catch {
|
|
5239
5280
|
return {};
|
|
5240
5281
|
}
|
|
@@ -5384,15 +5425,15 @@ async function getAppSecret(key) {
|
|
|
5384
5425
|
}
|
|
5385
5426
|
try {
|
|
5386
5427
|
const client = createServerClient();
|
|
5387
|
-
const
|
|
5388
|
-
if (!noCache &&
|
|
5428
|
+
const result = await client.secrets.get(key);
|
|
5429
|
+
if (!noCache && result) {
|
|
5389
5430
|
secretsCache[key] = {
|
|
5390
|
-
value:
|
|
5391
|
-
version:
|
|
5431
|
+
value: result.value,
|
|
5432
|
+
version: result.version,
|
|
5392
5433
|
cachedAt: Date.now()
|
|
5393
5434
|
};
|
|
5394
5435
|
}
|
|
5395
|
-
return
|
|
5436
|
+
return result?.value;
|
|
5396
5437
|
} catch (error) {
|
|
5397
5438
|
if (error instanceof ScaleMuleApiError && error.code === "SECRET_NOT_FOUND") {
|
|
5398
5439
|
return void 0;
|
|
@@ -5443,17 +5484,17 @@ async function getBundle(key, resolve = true) {
|
|
|
5443
5484
|
}
|
|
5444
5485
|
try {
|
|
5445
5486
|
const client = createServerClient();
|
|
5446
|
-
const
|
|
5447
|
-
if (!noCache &&
|
|
5487
|
+
const result = await client.bundles.get(key, resolve);
|
|
5488
|
+
if (!noCache && result) {
|
|
5448
5489
|
bundlesCache[key] = {
|
|
5449
|
-
type:
|
|
5450
|
-
data:
|
|
5451
|
-
version:
|
|
5452
|
-
inheritsFrom:
|
|
5490
|
+
type: result.type,
|
|
5491
|
+
data: result.data,
|
|
5492
|
+
version: result.version,
|
|
5493
|
+
inheritsFrom: result.inherits_from,
|
|
5453
5494
|
cachedAt: Date.now()
|
|
5454
5495
|
};
|
|
5455
5496
|
}
|
|
5456
|
-
return
|
|
5497
|
+
return result?.data;
|
|
5457
5498
|
} catch (error) {
|
|
5458
5499
|
if (error instanceof ScaleMuleApiError && error.code === "BUNDLE_NOT_FOUND") {
|
|
5459
5500
|
return void 0;
|