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