@datadog/openfeature-node-server 0.1.0-preview.3
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/cjs/configuration/evaluateForSubject.d.ts +7 -0
- package/cjs/configuration/evaluateForSubject.d.ts.map +1 -0
- package/cjs/configuration/evaluateForSubject.js +151 -0
- package/cjs/configuration/evaluateForSubject.js.map +1 -0
- package/cjs/configuration/evaluation.d.ts +5 -0
- package/cjs/configuration/evaluation.d.ts.map +1 -0
- package/cjs/configuration/evaluation.js +33 -0
- package/cjs/configuration/evaluation.js.map +1 -0
- package/cjs/configuration/ufc-v1.d.ts +52 -0
- package/cjs/configuration/ufc-v1.d.ts.map +1 -0
- package/cjs/configuration/ufc-v1.js +3 -0
- package/cjs/configuration/ufc-v1.js.map +1 -0
- package/cjs/index.d.ts +2 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +4 -0
- package/cjs/index.js.map +1 -0
- package/cjs/provider.d.ts +25 -0
- package/cjs/provider.d.ts.map +1 -0
- package/cjs/provider.js +42 -0
- package/cjs/provider.js.map +1 -0
- package/cjs/rules/rules.d.ts +51 -0
- package/cjs/rules/rules.d.ts.map +1 -0
- package/cjs/rules/rules.js +71 -0
- package/cjs/rules/rules.js.map +1 -0
- package/cjs/shards/matchesShard.d.ts +4 -0
- package/cjs/shards/matchesShard.d.ts.map +1 -0
- package/cjs/shards/matchesShard.js +16 -0
- package/cjs/shards/matchesShard.js.map +1 -0
- package/cjs/shards/obfuscation.d.ts +9 -0
- package/cjs/shards/obfuscation.d.ts.map +1 -0
- package/cjs/shards/obfuscation.js +23 -0
- package/cjs/shards/obfuscation.js.map +1 -0
- package/cjs/shards/sharders.d.ts +12 -0
- package/cjs/shards/sharders.d.ts.map +1 -0
- package/cjs/shards/sharders.js +30 -0
- package/cjs/shards/sharders.js.map +1 -0
- package/esm/configuration/evaluateForSubject.d.ts +7 -0
- package/esm/configuration/evaluateForSubject.d.ts.map +1 -0
- package/esm/configuration/evaluateForSubject.js +147 -0
- package/esm/configuration/evaluateForSubject.js.map +1 -0
- package/esm/configuration/evaluation.d.ts +5 -0
- package/esm/configuration/evaluation.d.ts.map +1 -0
- package/esm/configuration/evaluation.js +30 -0
- package/esm/configuration/evaluation.js.map +1 -0
- package/esm/configuration/ufc-v1.d.ts +52 -0
- package/esm/configuration/ufc-v1.d.ts.map +1 -0
- package/esm/configuration/ufc-v1.js +2 -0
- package/esm/configuration/ufc-v1.js.map +1 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +4 -0
- package/esm/index.js.map +1 -0
- package/esm/provider.d.ts +25 -0
- package/esm/provider.d.ts.map +1 -0
- package/esm/provider.js +38 -0
- package/esm/provider.js.map +1 -0
- package/esm/rules/rules.d.ts +51 -0
- package/esm/rules/rules.d.ts.map +1 -0
- package/esm/rules/rules.js +67 -0
- package/esm/rules/rules.js.map +1 -0
- package/esm/shards/matchesShard.d.ts +4 -0
- package/esm/shards/matchesShard.d.ts.map +1 -0
- package/esm/shards/matchesShard.js +13 -0
- package/esm/shards/matchesShard.js.map +1 -0
- package/esm/shards/obfuscation.d.ts +9 -0
- package/esm/shards/obfuscation.d.ts.map +1 -0
- package/esm/shards/obfuscation.js +16 -0
- package/esm/shards/obfuscation.js.map +1 -0
- package/esm/shards/sharders.d.ts +12 -0
- package/esm/shards/sharders.d.ts.map +1 -0
- package/esm/shards/sharders.js +24 -0
- package/esm/shards/sharders.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Rule } from '../rules/rules';
|
|
2
|
+
import { Flag } from './ufc-v1';
|
|
3
|
+
import { EvaluationContext, FlagValueType, Logger, ResolutionDetails } from '@openfeature/server-sdk';
|
|
4
|
+
import { FlagTypeToValue } from '@datadog/flagging-core';
|
|
5
|
+
export declare function evaluateForSubject<T extends FlagValueType>(flag: Flag | undefined, type: T, subjectKey: string, subjectAttributes: EvaluationContext, defaultValue: FlagTypeToValue<T>, logger: Logger): ResolutionDetails<FlagTypeToValue<T>>;
|
|
6
|
+
export declare function containsMatchingRule(rules: Rule[] | undefined, subjectAttributes: EvaluationContext, logger: Logger): boolean;
|
|
7
|
+
//# sourceMappingURL=evaluateForSubject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluateForSubject.d.ts","sourceRoot":"","sources":["../../src/configuration/evaluateForSubject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,IAAI,EAAsB,MAAM,UAAU,CAAA;AACnD,OAAO,EAAa,iBAAiB,EAAa,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAA6B,MAAM,yBAAyB,CAAA;AACtJ,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,aAAa,EACxD,IAAI,EAAE,IAAI,GAAG,SAAS,EACtB,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,GACb,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAuFvC;AAqBD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,EACzB,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAST"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateForSubject = evaluateForSubject;
|
|
4
|
+
exports.containsMatchingRule = containsMatchingRule;
|
|
5
|
+
const rules_1 = require("../rules/rules");
|
|
6
|
+
const matchesShard_1 = require("../shards/matchesShard");
|
|
7
|
+
const server_sdk_1 = require("@openfeature/server-sdk");
|
|
8
|
+
function evaluateForSubject(flag, type, subjectKey, subjectAttributes, defaultValue, logger) {
|
|
9
|
+
if (!(flag === null || flag === void 0 ? void 0 : flag.enabled)) {
|
|
10
|
+
logger.debug(`returning default assignment because flag is disabled`, {
|
|
11
|
+
flagKey: flag ? flag.key : 'undefined',
|
|
12
|
+
subjectKey,
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
value: defaultValue,
|
|
16
|
+
reason: server_sdk_1.StandardResolutionReasons.DISABLED,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const isValid = validateTypeMatch(type, flag.variationType);
|
|
20
|
+
if (!isValid) {
|
|
21
|
+
logger.debug(`variant value type mismatch, returning default value`, {
|
|
22
|
+
flagKey: flag.key,
|
|
23
|
+
subjectKey,
|
|
24
|
+
expectedType: type,
|
|
25
|
+
variantType: flag.variationType,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
value: defaultValue,
|
|
29
|
+
reason: server_sdk_1.StandardResolutionReasons.ERROR,
|
|
30
|
+
errorCode: server_sdk_1.ErrorCode.TYPE_MISMATCH,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const now = new Date();
|
|
34
|
+
for (const allocation of flag.allocations) {
|
|
35
|
+
if (allocation.startAt && now < new Date(allocation.startAt)) {
|
|
36
|
+
logger.debug(`allocation before start date`, {
|
|
37
|
+
flagKey: flag.key,
|
|
38
|
+
subjectKey,
|
|
39
|
+
allocationKey: allocation.key,
|
|
40
|
+
startAt: allocation.startAt,
|
|
41
|
+
});
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (allocation.endAt && now >= new Date(allocation.endAt)) {
|
|
45
|
+
logger.debug(`allocation after end date`, {
|
|
46
|
+
flagKey: flag.key,
|
|
47
|
+
subjectKey,
|
|
48
|
+
allocationKey: allocation.key,
|
|
49
|
+
endAt: allocation.endAt,
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const matched = containsMatchingRule(allocation.rules, subjectAttributes, logger);
|
|
54
|
+
if (!matched) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const selectedSplit = selectSplitUsingSharding(allocation.splits, subjectKey, flag.key, logger);
|
|
58
|
+
if (selectedSplit) {
|
|
59
|
+
const variation = flag.variations[selectedSplit.variationKey];
|
|
60
|
+
if (variation) {
|
|
61
|
+
logger.debug(`evaluated a flag`, {
|
|
62
|
+
flagKey: flag.key,
|
|
63
|
+
subjectKey,
|
|
64
|
+
assignment: variation.value,
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
value: variation.value,
|
|
68
|
+
reason: server_sdk_1.StandardResolutionReasons.TARGETING_MATCH,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logger.debug(`no matching split found for subject`, {
|
|
74
|
+
flagKey: flag.key,
|
|
75
|
+
subjectKey,
|
|
76
|
+
allocationKey: allocation.key,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
logger.debug(`returning default assignment because no allocation matched`, {
|
|
81
|
+
flagKey: flag.key,
|
|
82
|
+
subjectKey,
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
value: defaultValue,
|
|
86
|
+
reason: server_sdk_1.StandardResolutionReasons.DEFAULT,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function validateTypeMatch(expectedType, variantType) {
|
|
90
|
+
if (expectedType === 'boolean') {
|
|
91
|
+
return variantType === 'BOOLEAN';
|
|
92
|
+
}
|
|
93
|
+
if (expectedType === 'string') {
|
|
94
|
+
return variantType === 'STRING';
|
|
95
|
+
}
|
|
96
|
+
if (expectedType === 'number') {
|
|
97
|
+
return variantType === 'INTEGER' || variantType === 'NUMERIC';
|
|
98
|
+
}
|
|
99
|
+
if (expectedType === 'object') {
|
|
100
|
+
return variantType === 'JSON';
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`Invalid expected type: ${expectedType}`);
|
|
103
|
+
}
|
|
104
|
+
function containsMatchingRule(rules, subjectAttributes, logger) {
|
|
105
|
+
if (!(rules === null || rules === void 0 ? void 0 : rules.length)) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
logger.debug(`evaluating rules`, {
|
|
109
|
+
rules: JSON.stringify(rules),
|
|
110
|
+
subjectAttributes,
|
|
111
|
+
});
|
|
112
|
+
return rules.some((rule) => (0, rules_1.matchesRule)(rule, subjectAttributes));
|
|
113
|
+
}
|
|
114
|
+
function selectSplitUsingSharding(splits, subjectKey, flagKey, logger) {
|
|
115
|
+
if (!splits || splits.length === 0) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
for (const split of splits) {
|
|
119
|
+
logger.debug(`evaluating split sharding`, {
|
|
120
|
+
flagKey,
|
|
121
|
+
subjectKey,
|
|
122
|
+
variationKey: split.variationKey,
|
|
123
|
+
shards: split.shards,
|
|
124
|
+
});
|
|
125
|
+
const matches = split.shards.every((shard) => {
|
|
126
|
+
const shardMatches = (0, matchesShard_1.matchesShard)(shard, subjectKey);
|
|
127
|
+
logger.debug(`shard match result`, {
|
|
128
|
+
flagKey,
|
|
129
|
+
subjectKey,
|
|
130
|
+
variationKey: split.variationKey,
|
|
131
|
+
shard: shard,
|
|
132
|
+
matches: shardMatches,
|
|
133
|
+
});
|
|
134
|
+
return shardMatches;
|
|
135
|
+
});
|
|
136
|
+
if (matches) {
|
|
137
|
+
logger.debug(`subject matches split`, {
|
|
138
|
+
flagKey,
|
|
139
|
+
subjectKey,
|
|
140
|
+
variationKey: split.variationKey,
|
|
141
|
+
});
|
|
142
|
+
return split;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
logger.debug(`subject matches no splits`, {
|
|
146
|
+
flagKey,
|
|
147
|
+
subjectKey,
|
|
148
|
+
});
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=evaluateForSubject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluateForSubject.js","sourceRoot":"","sources":["../../src/configuration/evaluateForSubject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FlagTypeToValue } from '@datadog/flagging-core';
|
|
2
|
+
import { EvaluationContext, FlagValueType, Logger, ResolutionDetails } from '@openfeature/server-sdk';
|
|
3
|
+
import { UniversalFlagConfigurationV1 } from './ufc-v1';
|
|
4
|
+
export declare function evaluate<T extends FlagValueType>(config: UniversalFlagConfigurationV1, type: T, flagKey: string, defaultValue: FlagTypeToValue<T>, context: EvaluationContext, logger: Logger): ResolutionDetails<FlagTypeToValue<T>>;
|
|
5
|
+
//# sourceMappingURL=evaluation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation.d.ts","sourceRoot":"","sources":["../../src/configuration/evaluation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,MAAM,EACN,iBAAiB,EAElB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAA;AAGvD,wBAAgB,QAAQ,CAAC,CAAC,SAAS,aAAa,EAC9C,MAAM,EAAE,4BAA4B,EACpC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,EAChC,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,MAAM,GACb,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAiCvC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluate = evaluate;
|
|
4
|
+
const server_sdk_1 = require("@openfeature/server-sdk");
|
|
5
|
+
const evaluateForSubject_1 = require("./evaluateForSubject");
|
|
6
|
+
function evaluate(config, type, flagKey, defaultValue, context, logger) {
|
|
7
|
+
const { targetingKey: subjectKey, ...remainingContext } = context;
|
|
8
|
+
if (!subjectKey) {
|
|
9
|
+
return {
|
|
10
|
+
value: defaultValue,
|
|
11
|
+
reason: 'ERROR',
|
|
12
|
+
errorCode: server_sdk_1.ErrorCode.TARGETING_KEY_MISSING,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
// Include the subjectKey as an "id" attribute for rule matching
|
|
16
|
+
const subjectAttributes = {
|
|
17
|
+
id: subjectKey,
|
|
18
|
+
...remainingContext,
|
|
19
|
+
};
|
|
20
|
+
try {
|
|
21
|
+
const resultWithDetails = (0, evaluateForSubject_1.evaluateForSubject)(config.flags[flagKey], type, subjectKey, subjectAttributes, defaultValue, logger);
|
|
22
|
+
return resultWithDetails;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
logger.error('Error evaluating flag', { error });
|
|
26
|
+
return {
|
|
27
|
+
value: defaultValue,
|
|
28
|
+
reason: server_sdk_1.StandardResolutionReasons.ERROR,
|
|
29
|
+
errorCode: server_sdk_1.ErrorCode.GENERAL,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=evaluation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluation.js","sourceRoot":"","sources":["../../src/configuration/evaluation.ts"],"names":[],"mappings":";;AAYA,4BAwCC;AAnDD,wDAOgC;AAEhC,6DAAyD;AAEzD,SAAgB,QAAQ,CACtB,MAAoC,EACpC,IAAO,EACP,OAAe,EACf,YAAgC,EAChC,OAA0B,EAC1B,MAAc;IAEd,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAA;IACjE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,sBAAS,CAAC,qBAAqB;SAC3C,CAAA;IACH,CAAC;IAED,gEAAgE;IAChE,MAAM,iBAAiB,GAAG;QACxB,EAAE,EAAE,UAAU;QACd,GAAG,gBAAgB;KACpB,CAAA;IACD,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,IAAA,uCAAkB,EAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EACrB,IAAI,EACJ,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,MAAM,CACP,CAAA;QACD,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAChD,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,sCAAyB,CAAC,KAAK;YACvC,SAAS,EAAE,sBAAS,CAAC,OAAO;SAC7B,CAAA;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FlagValue } from '@openfeature/core';
|
|
2
|
+
import { Rule } from '../rules/rules';
|
|
3
|
+
export type VariantType = 'BOOLEAN' | 'INTEGER' | 'NUMERIC' | 'STRING' | 'JSON';
|
|
4
|
+
export interface VariantConfiguration {
|
|
5
|
+
key: string;
|
|
6
|
+
value: FlagValue;
|
|
7
|
+
}
|
|
8
|
+
export interface ShardRange {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}
|
|
12
|
+
export interface Shard {
|
|
13
|
+
salt: string;
|
|
14
|
+
ranges: ShardRange[];
|
|
15
|
+
totalShards: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Split {
|
|
18
|
+
variationKey: string;
|
|
19
|
+
shards: Shard[];
|
|
20
|
+
extraLogging?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
export interface Allocation {
|
|
23
|
+
key: string;
|
|
24
|
+
rules?: Rule[];
|
|
25
|
+
startAt?: Date;
|
|
26
|
+
endAt?: Date;
|
|
27
|
+
splits: Split[];
|
|
28
|
+
doLog?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface Flag {
|
|
31
|
+
key: string;
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
variationType: VariantType;
|
|
34
|
+
variations: Record<string, VariantConfiguration>;
|
|
35
|
+
allocations: Allocation[];
|
|
36
|
+
}
|
|
37
|
+
export interface UniversalFlagConfigurationV1 {
|
|
38
|
+
createdAt: string;
|
|
39
|
+
format: string;
|
|
40
|
+
environment: {
|
|
41
|
+
name: string;
|
|
42
|
+
};
|
|
43
|
+
flags: Record<string, Flag>;
|
|
44
|
+
}
|
|
45
|
+
export interface UniversalFlagConfigurationV1Response {
|
|
46
|
+
data: {
|
|
47
|
+
type: 'universal-flag-configuration';
|
|
48
|
+
id: string;
|
|
49
|
+
attributes: UniversalFlagConfigurationV1;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ufc-v1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ufc-v1.d.ts","sourceRoot":"","sources":["../../src/configuration/ufc-v1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAiB,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAErC,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE/E,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,KAAK;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,WAAW,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IAChD,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,oCAAoC;IACnD,IAAI,EAAE;QACJ,IAAI,EAAE,8BAA8B,CAAA;QACpC,EAAE,EAAE,MAAM,CAAA;QACV,UAAU,EAAE,4BAA4B,CAAA;KACzC,CAAA;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ufc-v1.js","sourceRoot":"","sources":["../../src/configuration/ufc-v1.ts"],"names":[],"mappings":""}
|
package/cjs/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,QAAA,MAAM,WAAW,QAA6B,CAAA"}
|
package/cjs/index.js
ADDED
package/cjs/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4CAA4C;AAC5C,MAAM,WAAW,GAAG,0BAA0B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { JsonValue, Logger, Provider, ProviderMetadata, ResolutionDetails, Paradigm, Hook } from '@openfeature/server-sdk';
|
|
2
|
+
import { EvaluationContext } from '@openfeature/core';
|
|
3
|
+
import { ProviderStatus } from '@openfeature/server-sdk';
|
|
4
|
+
import { UniversalFlagConfigurationV1 } from './configuration/ufc-v1';
|
|
5
|
+
export interface DatadogNodeServerProviderOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Remote config agent
|
|
8
|
+
*/
|
|
9
|
+
configuration: UniversalFlagConfigurationV1;
|
|
10
|
+
}
|
|
11
|
+
export declare class DatadogNodeServerProvider implements Provider {
|
|
12
|
+
readonly metadata: ProviderMetadata;
|
|
13
|
+
readonly runsOn: Paradigm;
|
|
14
|
+
hooks?: Hook[];
|
|
15
|
+
status: ProviderStatus;
|
|
16
|
+
private configuration;
|
|
17
|
+
constructor(options: DatadogNodeServerProviderOptions);
|
|
18
|
+
getConfiguration(): UniversalFlagConfigurationV1;
|
|
19
|
+
setConfiguration(configuration: UniversalFlagConfigurationV1): void;
|
|
20
|
+
resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<boolean>>;
|
|
21
|
+
resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<string>>;
|
|
22
|
+
resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<number>>;
|
|
23
|
+
resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<T>>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,IAAI,EACL,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AAErE,MAAM,WAAW,gCAAgC;IAC/C;;OAEG;IACH,aAAa,EAAE,4BAA4B,CAAA;CAC5C;AAED,qBAAa,yBAA0B,YAAW,QAAQ;IACxD,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAElC;IACD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAW;IACpC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IAEd,MAAM,EAAE,cAAc,CAA2B;IACjD,OAAO,CAAC,aAAa,CAA8B;gBAEvC,OAAO,EAAE,gCAAgC;IAKrD,gBAAgB;IAIhB,gBAAgB,CAAC,aAAa,EAAE,4BAA4B;IAItD,wBAAwB,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAIhC,uBAAuB,CAC3B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAI/B,uBAAuB,CAC3B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAI/B,uBAAuB,CAAC,CAAC,SAAS,SAAS,EAC/C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;CASjC"}
|
package/cjs/provider.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatadogNodeServerProvider = void 0;
|
|
4
|
+
const server_sdk_1 = require("@openfeature/server-sdk");
|
|
5
|
+
const evaluation_1 = require("./configuration/evaluation");
|
|
6
|
+
class DatadogNodeServerProvider {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.metadata = {
|
|
9
|
+
name: 'datadog-node-server',
|
|
10
|
+
};
|
|
11
|
+
this.runsOn = 'server';
|
|
12
|
+
this.status = server_sdk_1.ProviderStatus.NOT_READY;
|
|
13
|
+
this.configuration = options.configuration;
|
|
14
|
+
this.status = server_sdk_1.ProviderStatus.READY;
|
|
15
|
+
}
|
|
16
|
+
getConfiguration() {
|
|
17
|
+
return this.configuration;
|
|
18
|
+
}
|
|
19
|
+
setConfiguration(configuration) {
|
|
20
|
+
this.configuration = configuration;
|
|
21
|
+
}
|
|
22
|
+
async resolveBooleanEvaluation(flagKey, defaultValue, context, _logger) {
|
|
23
|
+
return (0, evaluation_1.evaluate)(this.configuration, 'boolean', flagKey, defaultValue, context, _logger);
|
|
24
|
+
}
|
|
25
|
+
async resolveStringEvaluation(flagKey, defaultValue, context, _logger) {
|
|
26
|
+
return (0, evaluation_1.evaluate)(this.configuration, 'string', flagKey, defaultValue, context, _logger);
|
|
27
|
+
}
|
|
28
|
+
async resolveNumberEvaluation(flagKey, defaultValue, context, _logger) {
|
|
29
|
+
return (0, evaluation_1.evaluate)(this.configuration, 'number', flagKey, defaultValue, context, _logger);
|
|
30
|
+
}
|
|
31
|
+
async resolveObjectEvaluation(flagKey, defaultValue, context, _logger) {
|
|
32
|
+
// type safety: OpenFeature interface requires us to return a
|
|
33
|
+
// specific T for *any* value of T (which could be any subtype of
|
|
34
|
+
// JsonValue). We can't even theoretically implement it in a
|
|
35
|
+
// type-sound way because there's no runtime information passed to
|
|
36
|
+
// learn what type the user expects. So it's up to the user to
|
|
37
|
+
// make sure they pass the appropriate type.
|
|
38
|
+
return (0, evaluation_1.evaluate)(this.configuration, 'object', flagKey, defaultValue, context, _logger);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.DatadogNodeServerProvider = DatadogNodeServerProvider;
|
|
42
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":";;;AAWA,wDAAwD;AACxD,2DAAqD;AAUrD,MAAa,yBAAyB;IAUpC,YAAY,OAAyC;QAT5C,aAAQ,GAAqB;YACpC,IAAI,EAAE,qBAAqB;SAC5B,CAAA;QACQ,WAAM,GAAa,QAAQ,CAAA;QAGpC,WAAM,GAAmB,2BAAc,CAAC,SAAS,CAAA;QAI/C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAA;QAC1C,IAAI,CAAC,MAAM,GAAG,2BAAc,CAAC,KAAK,CAAA;IACpC,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,aAAa,CAAA;IAC3B,CAAC;IAED,gBAAgB,CAAC,aAA2C;QAC1D,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,OAAe,EACf,YAAqB,EACrB,OAA0B,EAC1B,OAAe;QAEf,OAAO,IAAA,qBAAQ,EAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACzF,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,OAAe,EACf,YAAoB,EACpB,OAA0B,EAC1B,OAAe;QAEf,OAAO,IAAA,qBAAQ,EAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACxF,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,OAAe,EACf,YAAoB,EACpB,OAA0B,EAC1B,OAAe;QAEf,OAAO,IAAA,qBAAQ,EAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACxF,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,OAAe,EACf,YAAe,EACf,OAA0B,EAC1B,OAAe;QAEf,6DAA6D;QAC7D,iEAAiE;QACjE,4DAA4D;QAC5D,kEAAkE;QAClE,8DAA8D;QAC9D,4CAA4C;QAC5C,OAAO,IAAA,qBAAQ,EAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAyB,CAAA;IAChH,CAAC;CACF;AAhED,8DAgEC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { EvaluationContext, EvaluationContextValue } from "@openfeature/server-sdk";
|
|
2
|
+
export type ConditionValueType = EvaluationContextValue | EvaluationContextValue[];
|
|
3
|
+
export declare enum OperatorType {
|
|
4
|
+
MATCHES = "MATCHES",
|
|
5
|
+
NOT_MATCHES = "NOT_MATCHES",
|
|
6
|
+
GTE = "GTE",
|
|
7
|
+
GT = "GT",
|
|
8
|
+
LTE = "LTE",
|
|
9
|
+
LT = "LT",
|
|
10
|
+
ONE_OF = "ONE_OF",
|
|
11
|
+
NOT_ONE_OF = "NOT_ONE_OF",
|
|
12
|
+
IS_NULL = "IS_NULL"
|
|
13
|
+
}
|
|
14
|
+
type NumericOperator = OperatorType.GTE | OperatorType.GT | OperatorType.LTE | OperatorType.LT;
|
|
15
|
+
type MatchesCondition = {
|
|
16
|
+
operator: OperatorType.MATCHES;
|
|
17
|
+
attribute: string;
|
|
18
|
+
value: string;
|
|
19
|
+
};
|
|
20
|
+
type NotMatchesCondition = {
|
|
21
|
+
operator: OperatorType.NOT_MATCHES;
|
|
22
|
+
attribute: string;
|
|
23
|
+
value: string;
|
|
24
|
+
};
|
|
25
|
+
type OneOfCondition = {
|
|
26
|
+
operator: OperatorType.ONE_OF;
|
|
27
|
+
attribute: string;
|
|
28
|
+
value: string[];
|
|
29
|
+
};
|
|
30
|
+
type NotOneOfCondition = {
|
|
31
|
+
operator: OperatorType.NOT_ONE_OF;
|
|
32
|
+
attribute: string;
|
|
33
|
+
value: string[];
|
|
34
|
+
};
|
|
35
|
+
type NumericCondition = {
|
|
36
|
+
operator: NumericOperator;
|
|
37
|
+
attribute: string;
|
|
38
|
+
value: number;
|
|
39
|
+
};
|
|
40
|
+
type NullCondition = {
|
|
41
|
+
operator: OperatorType.IS_NULL;
|
|
42
|
+
attribute: string;
|
|
43
|
+
value: boolean;
|
|
44
|
+
};
|
|
45
|
+
export type Condition = MatchesCondition | NotMatchesCondition | OneOfCondition | NotOneOfCondition | NumericCondition | NullCondition;
|
|
46
|
+
export interface Rule {
|
|
47
|
+
conditions: Condition[];
|
|
48
|
+
}
|
|
49
|
+
export declare function matchesRule(rule: Rule, subjectAttributes: EvaluationContext): boolean;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAEnF,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,sBAAsB,EAAE,CAAA;AAElF,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,WAAW,gBAAgB;IAC3B,GAAG,QAAQ;IACX,EAAE,OAAO;IACT,GAAG,QAAQ;IACX,EAAE,OAAO;IACT,MAAM,WAAW;IACjB,UAAU,eAAe;IACzB,OAAO,YAAY;CACpB;AAED,KAAK,eAAe,GAAG,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,EAAE,GAAG,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,EAAE,CAAA;AAE9F,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,YAAY,CAAC,WAAW,CAAA;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAA;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,eAAe,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GACjB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,iBAAiB,GACjB,gBAAgB,GAChB,aAAa,CAAA;AAEjB,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,SAAS,EAAE,CAAA;CACxB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAIrF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OperatorType = void 0;
|
|
4
|
+
exports.matchesRule = matchesRule;
|
|
5
|
+
var OperatorType;
|
|
6
|
+
(function (OperatorType) {
|
|
7
|
+
OperatorType["MATCHES"] = "MATCHES";
|
|
8
|
+
OperatorType["NOT_MATCHES"] = "NOT_MATCHES";
|
|
9
|
+
OperatorType["GTE"] = "GTE";
|
|
10
|
+
OperatorType["GT"] = "GT";
|
|
11
|
+
OperatorType["LTE"] = "LTE";
|
|
12
|
+
OperatorType["LT"] = "LT";
|
|
13
|
+
OperatorType["ONE_OF"] = "ONE_OF";
|
|
14
|
+
OperatorType["NOT_ONE_OF"] = "NOT_ONE_OF";
|
|
15
|
+
OperatorType["IS_NULL"] = "IS_NULL";
|
|
16
|
+
})(OperatorType || (exports.OperatorType = OperatorType = {}));
|
|
17
|
+
function matchesRule(rule, subjectAttributes) {
|
|
18
|
+
const conditionEvaluations = evaluateRuleConditions(subjectAttributes, rule.conditions);
|
|
19
|
+
// TODO: short-circuit return when false condition is found
|
|
20
|
+
return !conditionEvaluations.includes(false);
|
|
21
|
+
}
|
|
22
|
+
function evaluateRuleConditions(subjectAttributes, conditions) {
|
|
23
|
+
return conditions.map((condition) => evaluateCondition(subjectAttributes, condition));
|
|
24
|
+
}
|
|
25
|
+
function evaluateCondition(subjectAttributes, condition) {
|
|
26
|
+
const value = subjectAttributes[condition.attribute];
|
|
27
|
+
if (condition.operator === OperatorType.IS_NULL) {
|
|
28
|
+
if (condition.value) {
|
|
29
|
+
return value === null || value === undefined;
|
|
30
|
+
}
|
|
31
|
+
return value !== null && value !== undefined;
|
|
32
|
+
}
|
|
33
|
+
if (value !== null && value !== undefined) {
|
|
34
|
+
switch (condition.operator) {
|
|
35
|
+
case OperatorType.GTE:
|
|
36
|
+
case OperatorType.GT:
|
|
37
|
+
case OperatorType.LTE:
|
|
38
|
+
case OperatorType.LT: {
|
|
39
|
+
const comparator = (a, b) => condition.operator === OperatorType.GTE
|
|
40
|
+
? a >= b
|
|
41
|
+
: condition.operator === OperatorType.GT
|
|
42
|
+
? a > b
|
|
43
|
+
: condition.operator === OperatorType.LTE
|
|
44
|
+
? a <= b
|
|
45
|
+
: a < b;
|
|
46
|
+
return compareNumber(value, condition.value, comparator);
|
|
47
|
+
}
|
|
48
|
+
case OperatorType.MATCHES:
|
|
49
|
+
// ReDoS mitigation should happen on user input to avoid event loop saturation (https://datadoghq.atlassian.net/browse/FFL-1060)
|
|
50
|
+
return new RegExp(condition.value).test(String(value)); // dd-iac-scan ignore-line
|
|
51
|
+
case OperatorType.NOT_MATCHES:
|
|
52
|
+
// ReDoS mitigation should happen on user input to avoid event loop saturation (https://datadoghq.atlassian.net/browse/FFL-1060)
|
|
53
|
+
return !new RegExp(condition.value).test(String(value)); // dd-iac-scan ignore-line
|
|
54
|
+
case OperatorType.ONE_OF:
|
|
55
|
+
return isOneOf(value.toString(), condition.value);
|
|
56
|
+
case OperatorType.NOT_ONE_OF:
|
|
57
|
+
return isNotOneOf(value.toString(), condition.value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
function isOneOf(attributeValue, conditionValues) {
|
|
63
|
+
return conditionValues.includes(attributeValue);
|
|
64
|
+
}
|
|
65
|
+
function isNotOneOf(attributeValue, conditionValues) {
|
|
66
|
+
return !isOneOf(attributeValue, conditionValues);
|
|
67
|
+
}
|
|
68
|
+
function compareNumber(attributeValue, conditionValue, compareFn) {
|
|
69
|
+
return compareFn(Number(attributeValue), Number(conditionValue));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchesShard.d.ts","sourceRoot":"","sources":["../../src/shards/matchesShard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAc,OAAO,EAAE,MAAM,YAAY,CAAA;AAEhD,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAI/F"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.matchesShard = matchesShard;
|
|
4
|
+
const sharders_1 = require("./sharders");
|
|
5
|
+
function matchesShard(shard, subjectKey, customSharder) {
|
|
6
|
+
const sharder = customSharder !== null && customSharder !== void 0 ? customSharder : new sharders_1.MD5Sharder();
|
|
7
|
+
const assignedShard = sharder.getShard(hashKey(shard.salt, subjectKey), shard.totalShards);
|
|
8
|
+
return shard.ranges.some((range) => isInShardRange(assignedShard, range));
|
|
9
|
+
}
|
|
10
|
+
function isInShardRange(shard, range) {
|
|
11
|
+
return range.start <= shard && shard < range.end;
|
|
12
|
+
}
|
|
13
|
+
function hashKey(salt, subjectKey) {
|
|
14
|
+
return `${salt}-${subjectKey}`;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=matchesShard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchesShard.js","sourceRoot":"","sources":["../../src/shards/matchesShard.ts"],"names":[],"mappings":";;AAGA,oCAIC;AAND,yCAAgD;AAEhD,SAAgB,YAAY,CAAC,KAAY,EAAE,UAAkB,EAAE,aAAuB;IACpF,MAAM,OAAO,GAAG,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,IAAI,qBAAU,EAAE,CAAA;IACjD,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAA;IAC1F,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAA;AAC3E,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,KAAiB;IACtD,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAA;AAClD,CAAC;AAED,SAAS,OAAO,CAAC,IAAY,EAAE,UAAkB;IAC/C,OAAO,GAAG,IAAI,IAAI,UAAU,EAAE,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function getMD5Hash(input: string, salt?: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Builds a storage key suffix from an API key.
|
|
4
|
+
* @param apiKey - The API key to build the suffix from
|
|
5
|
+
* @returns A string suffix for storage keys
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildStorageKeySuffix(apiKey: string): string;
|
|
9
|
+
//# sourceMappingURL=obfuscation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obfuscation.d.ts","sourceRoot":"","sources":["../../src/shards/obfuscation.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI5D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getMD5Hash = getMD5Hash;
|
|
7
|
+
exports.buildStorageKeySuffix = buildStorageKeySuffix;
|
|
8
|
+
const spark_md5_1 = __importDefault(require("spark-md5"));
|
|
9
|
+
function getMD5Hash(input, salt = '') {
|
|
10
|
+
return new spark_md5_1.default().append(salt).append(input).end();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Builds a storage key suffix from an API key.
|
|
14
|
+
* @param apiKey - The API key to build the suffix from
|
|
15
|
+
* @returns A string suffix for storage keys
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
function buildStorageKeySuffix(apiKey) {
|
|
19
|
+
// Note that we hash the API key and use the first 16 characters of the digest.
|
|
20
|
+
const hashed = getMD5Hash(apiKey);
|
|
21
|
+
return hashed.slice(0, 16);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=obfuscation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"obfuscation.js","sourceRoot":"","sources":["../../src/shards/obfuscation.ts"],"names":[],"mappings":";;;;;AAEA,gCAEC;AAQD,sDAIC;AAhBD,0DAAgC;AAEhC,SAAgB,UAAU,CAAC,KAAa,EAAE,IAAI,GAAG,EAAE;IACjD,OAAO,IAAI,mBAAQ,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAA;AACxD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,MAAc;IAClD,+EAA+E;IAC/E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IACjC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare abstract class Sharder {
|
|
2
|
+
abstract getShard(input: string, totalShards: number): number;
|
|
3
|
+
}
|
|
4
|
+
export declare class MD5Sharder extends Sharder {
|
|
5
|
+
getShard(input: string, totalShards: number): number;
|
|
6
|
+
}
|
|
7
|
+
export declare class DeterministicSharder extends Sharder {
|
|
8
|
+
private lookup;
|
|
9
|
+
constructor(lookup: Record<string, number>);
|
|
10
|
+
getShard(input: string, _totalShards: number): number;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=sharders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharders.d.ts","sourceRoot":"","sources":["../../src/shards/sharders.ts"],"names":[],"mappings":"AAEA,8BAAsB,OAAO;IAC3B,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAC9D;AAED,qBAAa,UAAW,SAAQ,OAAO;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAOrD;AAED,qBAAa,oBAAqB,SAAQ,OAAO;IAK/C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAM1C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;CAGtD"}
|