@datadog/openfeature-node-server 0.1.0-preview.10

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.
Files changed (66) hide show
  1. package/README.md +3 -0
  2. package/cjs/configuration/evaluateForSubject.d.ts +7 -0
  3. package/cjs/configuration/evaluateForSubject.d.ts.map +1 -0
  4. package/cjs/configuration/evaluateForSubject.js +159 -0
  5. package/cjs/configuration/evaluateForSubject.js.map +1 -0
  6. package/cjs/configuration/evaluation.d.ts +5 -0
  7. package/cjs/configuration/evaluation.d.ts.map +1 -0
  8. package/cjs/configuration/evaluation.js +40 -0
  9. package/cjs/configuration/evaluation.js.map +1 -0
  10. package/cjs/configuration/ufc-v1.d.ts +53 -0
  11. package/cjs/configuration/ufc-v1.d.ts.map +1 -0
  12. package/cjs/configuration/ufc-v1.js +19 -0
  13. package/cjs/configuration/ufc-v1.js.map +1 -0
  14. package/cjs/index.d.ts +3 -0
  15. package/cjs/index.d.ts.map +1 -0
  16. package/cjs/index.js +20 -0
  17. package/cjs/index.js.map +1 -0
  18. package/cjs/provider.d.ts +52 -0
  19. package/cjs/provider.d.ts.map +1 -0
  20. package/cjs/provider.js +128 -0
  21. package/cjs/provider.js.map +1 -0
  22. package/cjs/rules/rules.d.ts +51 -0
  23. package/cjs/rules/rules.d.ts.map +1 -0
  24. package/cjs/rules/rules.js +71 -0
  25. package/cjs/rules/rules.js.map +1 -0
  26. package/cjs/shards/matchesShard.d.ts +4 -0
  27. package/cjs/shards/matchesShard.d.ts.map +1 -0
  28. package/cjs/shards/matchesShard.js +16 -0
  29. package/cjs/shards/matchesShard.js.map +1 -0
  30. package/cjs/shards/sharders.d.ts +12 -0
  31. package/cjs/shards/sharders.d.ts.map +1 -0
  32. package/cjs/shards/sharders.js +30 -0
  33. package/cjs/shards/sharders.js.map +1 -0
  34. package/esm/configuration/evaluateForSubject.d.ts +7 -0
  35. package/esm/configuration/evaluateForSubject.d.ts.map +1 -0
  36. package/esm/configuration/evaluateForSubject.js +155 -0
  37. package/esm/configuration/evaluateForSubject.js.map +1 -0
  38. package/esm/configuration/evaluation.d.ts +5 -0
  39. package/esm/configuration/evaluation.d.ts.map +1 -0
  40. package/esm/configuration/evaluation.js +37 -0
  41. package/esm/configuration/evaluation.js.map +1 -0
  42. package/esm/configuration/ufc-v1.d.ts +53 -0
  43. package/esm/configuration/ufc-v1.d.ts.map +1 -0
  44. package/esm/configuration/ufc-v1.js +16 -0
  45. package/esm/configuration/ufc-v1.js.map +1 -0
  46. package/esm/index.d.ts +3 -0
  47. package/esm/index.d.ts.map +1 -0
  48. package/esm/index.js +4 -0
  49. package/esm/index.js.map +1 -0
  50. package/esm/provider.d.ts +52 -0
  51. package/esm/provider.d.ts.map +1 -0
  52. package/esm/provider.js +124 -0
  53. package/esm/provider.js.map +1 -0
  54. package/esm/rules/rules.d.ts +51 -0
  55. package/esm/rules/rules.d.ts.map +1 -0
  56. package/esm/rules/rules.js +67 -0
  57. package/esm/rules/rules.js.map +1 -0
  58. package/esm/shards/matchesShard.d.ts +4 -0
  59. package/esm/shards/matchesShard.d.ts.map +1 -0
  60. package/esm/shards/matchesShard.js +13 -0
  61. package/esm/shards/matchesShard.js.map +1 -0
  62. package/esm/shards/sharders.d.ts +12 -0
  63. package/esm/shards/sharders.d.ts.map +1 -0
  64. package/esm/shards/sharders.js +24 -0
  65. package/esm/shards/sharders.js.map +1 -0
  66. package/package.json +55 -0
@@ -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,4 @@
1
+ import type { Shard } from '../configuration/ufc-v1';
2
+ import { type Sharder } from './sharders';
3
+ export declare function matchesShard(shard: Shard, subjectKey: string, customSharder?: Sharder): boolean;
4
+ //# sourceMappingURL=matchesShard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchesShard.d.ts","sourceRoot":"","sources":["../../src/shards/matchesShard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,YAAY,CAAA;AAErD,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,yCAAqD;AAErD,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,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"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeterministicSharder = exports.MD5Sharder = exports.Sharder = void 0;
4
+ const flagging_core_1 = require("@datadog/flagging-core");
5
+ class Sharder {
6
+ }
7
+ exports.Sharder = Sharder;
8
+ class MD5Sharder extends Sharder {
9
+ getShard(input, totalShards) {
10
+ const hashOutput = (0, flagging_core_1.getMD5Hash)(input);
11
+ // get the first 4 bytes of the md5 hex string and parse it using base 16
12
+ // (8 hex characters represent 4 bytes, e.g. 0xffffffff represents the max 4-byte integer)
13
+ const intFromHash = parseInt(hashOutput.slice(0, 8), 16);
14
+ return intFromHash % totalShards;
15
+ }
16
+ }
17
+ exports.MD5Sharder = MD5Sharder;
18
+ class DeterministicSharder extends Sharder {
19
+ constructor(lookup) {
20
+ super();
21
+ this.lookup = lookup;
22
+ }
23
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
+ getShard(input, _totalShards) {
25
+ var _a;
26
+ return (_a = this.lookup[input]) !== null && _a !== void 0 ? _a : 0;
27
+ }
28
+ }
29
+ exports.DeterministicSharder = DeterministicSharder;
30
+ //# sourceMappingURL=sharders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharders.js","sourceRoot":"","sources":["../../src/shards/sharders.ts"],"names":[],"mappings":";;;AAAA,0DAAmD;AAEnD,MAAsB,OAAO;CAE5B;AAFD,0BAEC;AAED,MAAa,UAAW,SAAQ,OAAO;IACrC,QAAQ,CAAC,KAAa,EAAE,WAAmB;QACzC,MAAM,UAAU,GAAG,IAAA,0BAAU,EAAC,KAAK,CAAC,CAAA;QACpC,yEAAyE;QACzE,0FAA0F;QAC1F,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACxD,OAAO,WAAW,GAAG,WAAW,CAAA;IAClC,CAAC;CACF;AARD,gCAQC;AAED,MAAa,oBAAqB,SAAQ,OAAO;IAO/C,YAAY,MAA8B;QACxC,KAAK,EAAE,CAAA;QACP,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,6DAA6D;IAC7D,QAAQ,CAAC,KAAa,EAAE,YAAoB;;QAC1C,OAAO,MAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAA;IAChC,CAAC;CACF;AAhBD,oDAgBC"}
@@ -0,0 +1,7 @@
1
+ import type { FlagTypeToValue } from '@datadog/flagging-core';
2
+ import { type EvaluationContext, type FlagValueType, type Logger, type ResolutionDetails } from '@openfeature/server-sdk';
3
+ import { type Rule } from '../rules/rules';
4
+ import { type Flag } from './ufc-v1';
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,KAAK,EAAE,eAAe,EAA2B,MAAM,wBAAwB,CAAA;AACtF,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,KAAK,IAAI,EAA4D,MAAM,UAAU,CAAA;AAE9F,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,CA8FvC;AAkBD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,EACzB,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAST"}
@@ -0,0 +1,155 @@
1
+ import { ErrorCode, StandardResolutionReasons, } from '@openfeature/server-sdk';
2
+ import { matchesRule } from '../rules/rules';
3
+ import { matchesShard } from '../shards/matchesShard';
4
+ import { variantTypeToFlagValueType } from './ufc-v1';
5
+ export function evaluateForSubject(flag, type, subjectKey, subjectAttributes, defaultValue, logger) {
6
+ if (!(flag === null || flag === void 0 ? void 0 : flag.enabled)) {
7
+ logger.debug(`returning default assignment because flag is disabled`, {
8
+ flagKey: flag ? flag.key : 'undefined',
9
+ subjectKey,
10
+ });
11
+ return {
12
+ value: defaultValue,
13
+ reason: StandardResolutionReasons.DISABLED,
14
+ };
15
+ }
16
+ const isValid = validateTypeMatch(type, flag.variationType);
17
+ if (!isValid) {
18
+ logger.debug(`variant value type mismatch, returning default value`, {
19
+ flagKey: flag.key,
20
+ subjectKey,
21
+ expectedType: type,
22
+ variantType: flag.variationType,
23
+ });
24
+ return {
25
+ value: defaultValue,
26
+ reason: StandardResolutionReasons.ERROR,
27
+ errorCode: ErrorCode.TYPE_MISMATCH,
28
+ };
29
+ }
30
+ const now = new Date();
31
+ for (const allocation of flag.allocations) {
32
+ if (allocation.startAt && now < new Date(allocation.startAt)) {
33
+ logger.debug(`allocation before start date`, {
34
+ flagKey: flag.key,
35
+ subjectKey,
36
+ allocationKey: allocation.key,
37
+ startAt: allocation.startAt,
38
+ });
39
+ continue;
40
+ }
41
+ if (allocation.endAt && now >= new Date(allocation.endAt)) {
42
+ logger.debug(`allocation after end date`, {
43
+ flagKey: flag.key,
44
+ subjectKey,
45
+ allocationKey: allocation.key,
46
+ endAt: allocation.endAt,
47
+ });
48
+ continue;
49
+ }
50
+ const matched = containsMatchingRule(allocation.rules, subjectAttributes, logger);
51
+ if (!matched) {
52
+ continue;
53
+ }
54
+ const selectedSplit = selectSplitUsingSharding(allocation.splits, subjectKey, flag.key, logger);
55
+ if (selectedSplit) {
56
+ const variant = flag.variations[selectedSplit.variationKey];
57
+ if (variant) {
58
+ logger.debug(`evaluated a flag`, {
59
+ flagKey: flag.key,
60
+ subjectKey,
61
+ assignment: variant.value,
62
+ });
63
+ return {
64
+ value: variant.value,
65
+ reason: StandardResolutionReasons.TARGETING_MATCH,
66
+ variant: variant.key,
67
+ flagMetadata: {
68
+ allocationKey: allocation.key,
69
+ variationType: variantTypeToFlagValueType(flag.variationType),
70
+ doLog: !!allocation.doLog,
71
+ },
72
+ };
73
+ }
74
+ }
75
+ else {
76
+ logger.debug(`no matching split found for subject`, {
77
+ flagKey: flag.key,
78
+ subjectKey,
79
+ allocationKey: allocation.key,
80
+ });
81
+ }
82
+ }
83
+ // This shouldn't happen since a default allocation is generated by the server
84
+ logger.debug(`returning default assignment because no allocation matched`, {
85
+ flagKey: flag.key,
86
+ subjectKey,
87
+ });
88
+ return {
89
+ value: defaultValue,
90
+ reason: StandardResolutionReasons.DEFAULT,
91
+ };
92
+ }
93
+ function validateTypeMatch(expectedType, variantType) {
94
+ if (expectedType === 'boolean') {
95
+ return variantType === 'BOOLEAN';
96
+ }
97
+ if (expectedType === 'string') {
98
+ return variantType === 'STRING';
99
+ }
100
+ if (expectedType === 'number') {
101
+ return variantType === 'INTEGER' || variantType === 'NUMERIC';
102
+ }
103
+ if (expectedType === 'object') {
104
+ return variantType === 'JSON';
105
+ }
106
+ throw new Error(`Invalid expected type: ${expectedType}`);
107
+ }
108
+ export function containsMatchingRule(rules, subjectAttributes, logger) {
109
+ if (!(rules === null || rules === void 0 ? void 0 : rules.length)) {
110
+ return true;
111
+ }
112
+ logger.debug(`evaluating rules`, {
113
+ rules: JSON.stringify(rules),
114
+ subjectAttributes,
115
+ });
116
+ return rules.some((rule) => matchesRule(rule, subjectAttributes));
117
+ }
118
+ function selectSplitUsingSharding(splits, subjectKey, flagKey, logger) {
119
+ if (!splits || splits.length === 0) {
120
+ return null;
121
+ }
122
+ for (const split of splits) {
123
+ logger.debug(`evaluating split sharding`, {
124
+ flagKey,
125
+ subjectKey,
126
+ variationKey: split.variationKey,
127
+ shards: split.shards,
128
+ });
129
+ const matches = split.shards.every((shard) => {
130
+ const shardMatches = matchesShard(shard, subjectKey);
131
+ logger.debug(`shard match result`, {
132
+ flagKey,
133
+ subjectKey,
134
+ variationKey: split.variationKey,
135
+ shard: shard,
136
+ matches: shardMatches,
137
+ });
138
+ return shardMatches;
139
+ });
140
+ if (matches) {
141
+ logger.debug(`subject matches split`, {
142
+ flagKey,
143
+ subjectKey,
144
+ variationKey: split.variationKey,
145
+ });
146
+ return split;
147
+ }
148
+ }
149
+ logger.debug(`subject matches no splits`, {
150
+ flagKey,
151
+ subjectKey,
152
+ });
153
+ return null;
154
+ }
155
+ //# 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 { type EvaluationContext, type FlagValueType, type Logger, type ResolutionDetails } from '@openfeature/server-sdk';
3
+ import type { UniversalFlagConfigurationV1 } from './ufc-v1';
4
+ export declare function evaluate<T extends FlagValueType>(config: UniversalFlagConfigurationV1 | undefined, 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,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAA;AAE5D,wBAAgB,QAAQ,CAAC,CAAC,SAAS,aAAa,EAC9C,MAAM,EAAE,4BAA4B,GAAG,SAAS,EAChD,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,CAyCvC"}
@@ -0,0 +1,37 @@
1
+ import { ErrorCode, StandardResolutionReasons, } from '@openfeature/server-sdk';
2
+ import { evaluateForSubject } from './evaluateForSubject';
3
+ export function evaluate(config, type, flagKey, defaultValue, context, logger) {
4
+ if (!config) {
5
+ return {
6
+ value: defaultValue,
7
+ reason: 'ERROR',
8
+ errorCode: ErrorCode.PROVIDER_NOT_READY,
9
+ };
10
+ }
11
+ const { targetingKey: subjectKey, ...remainingContext } = context;
12
+ if (!subjectKey) {
13
+ return {
14
+ value: defaultValue,
15
+ reason: 'ERROR',
16
+ errorCode: ErrorCode.TARGETING_KEY_MISSING,
17
+ };
18
+ }
19
+ // Include the subjectKey as an "id" attribute for rule matching
20
+ const subjectAttributes = {
21
+ id: subjectKey,
22
+ ...remainingContext,
23
+ };
24
+ try {
25
+ const resultWithDetails = evaluateForSubject(config.flags[flagKey], type, subjectKey, subjectAttributes, defaultValue, logger);
26
+ return resultWithDetails;
27
+ }
28
+ catch (error) {
29
+ logger.error('Error evaluating flag', { error });
30
+ return {
31
+ value: defaultValue,
32
+ reason: StandardResolutionReasons.ERROR,
33
+ errorCode: ErrorCode.GENERAL,
34
+ };
35
+ }
36
+ }
37
+ //# sourceMappingURL=evaluation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluation.js","sourceRoot":"","sources":["../../src/configuration/evaluation.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EAKT,yBAAyB,GAC1B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAGzD,MAAM,UAAU,QAAQ,CACtB,MAAgD,EAChD,IAAO,EACP,OAAe,EACf,YAAgC,EAChC,OAA0B,EAC1B,MAAc;IAEd,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,SAAS,CAAC,kBAAkB;SACxC,CAAA;IACH,CAAC;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,SAAS,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,kBAAkB,CAC1C,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,yBAAyB,CAAC,KAAK;YACvC,SAAS,EAAE,SAAS,CAAC,OAAO;SAC7B,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { FlagValue, FlagValueType } from '@openfeature/core';
2
+ import type { 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
+ export declare function variantTypeToFlagValueType(variantType: VariantType): FlagValueType;
53
+ //# 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,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,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;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,CAclF"}
@@ -0,0 +1,16 @@
1
+ export function variantTypeToFlagValueType(variantType) {
2
+ if (variantType === 'BOOLEAN') {
3
+ return 'boolean';
4
+ }
5
+ if (variantType === 'STRING') {
6
+ return 'string';
7
+ }
8
+ if (variantType === 'INTEGER' || variantType === 'NUMERIC') {
9
+ return 'number';
10
+ }
11
+ if (variantType === 'JSON') {
12
+ return 'object';
13
+ }
14
+ throw new Error(`Cannot convert variant type to flag value type: ${variantType}`);
15
+ }
16
+ //# sourceMappingURL=ufc-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ufc-v1.js","sourceRoot":"","sources":["../../src/configuration/ufc-v1.ts"],"names":[],"mappings":"AA6DA,MAAM,UAAU,0BAA0B,CAAC,WAAwB;IACjE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,WAAW,EAAE,CAAC,CAAA;AACnF,CAAC"}
package/esm/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export type { UniversalFlagConfigurationV1 } from './configuration/ufc-v1';
2
+ export * from './provider';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AAC1E,cAAc,YAAY,CAAA"}
package/esm/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './provider';
2
+ // Build environment placeholder for testing
3
+ const _SDK_VERSION = "dev";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAE1B,4CAA4C;AAC5C,MAAM,YAAY,GAAG,0BAA0B,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type { Channel } from 'node:diagnostics_channel';
2
+ import { type ExposureEvent } from '@datadog/flagging-core';
3
+ import type { EvaluationContext } from '@openfeature/core';
4
+ import type { Hook, JsonValue, Logger, Paradigm, Provider, ProviderEventEmitter, ProviderMetadata, ResolutionDetails } from '@openfeature/server-sdk';
5
+ import { ProviderEvents } from '@openfeature/server-sdk';
6
+ import type { UniversalFlagConfigurationV1 } from './configuration/ufc-v1';
7
+ export interface DatadogNodeServerProviderOptions {
8
+ /**
9
+ * Log experiment exposures
10
+ */
11
+ exposureChannel: Channel<ExposureEvent>;
12
+ }
13
+ export declare class DatadogNodeServerProvider implements Provider {
14
+ private readonly options;
15
+ readonly metadata: ProviderMetadata;
16
+ readonly runsOn: Paradigm;
17
+ readonly hooks?: Hook[];
18
+ private resolveInitialization?;
19
+ private rejectInitialization?;
20
+ readonly events: ProviderEventEmitter<ProviderEvents>;
21
+ private readonly exposureCache;
22
+ private configuration?;
23
+ constructor(options: DatadogNodeServerProviderOptions);
24
+ /**
25
+ * Used by dd-source-js
26
+ */
27
+ getConfiguration(): UniversalFlagConfigurationV1 | undefined;
28
+ /**
29
+ * Used by dd-source-js
30
+ */
31
+ setConfiguration(configuration: UniversalFlagConfigurationV1): void;
32
+ /**
33
+ * Used by dd-source-js
34
+ */
35
+ setError(error: unknown): void;
36
+ /**
37
+ * Used by the OpenFeature SDK to set the status based on initialization.
38
+ * Status of 'PROVIDER_READY' is emitted with a resolved promise.
39
+ * Status of 'PROVIDER_ERROR' is emitted with a rejected promise.
40
+ *
41
+ * Since we aren't loading the configuration in this Provider, we will simulate
42
+ * loading functionality via resolveInitialization and rejectInitialization.
43
+ * See setConfiguration and setError for more details.
44
+ */
45
+ initialize(): Promise<void>;
46
+ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<boolean>>;
47
+ resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<string>>;
48
+ resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<number>>;
49
+ resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, _logger: Logger): Promise<ResolutionDetails<T>>;
50
+ private handleExposure;
51
+ }
52
+ //# 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,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAGV,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAA2B,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAEjF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAA;AAE1E,MAAM,WAAW,gCAAgC;IAC/C;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;CACxC;AAED,qBAAa,yBAA0B,YAAW,QAAQ;IAc5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAbpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAElC;IACD,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAW;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IAEvB,OAAO,CAAC,qBAAqB,CAAC,CAA4C;IAC1E,OAAO,CAAC,oBAAoB,CAAC,CAA4B;IACzD,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAA;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAE3D,OAAO,CAAC,aAAa,CAAC,CAA0C;gBAEnC,OAAO,EAAE,gCAAgC;IAMtE;;OAEG;IACH,gBAAgB;IAIhB;;OAEG;IACH,gBAAgB,CAAC,aAAa,EAAE,4BAA4B;IAmB5D;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO;IAUvB;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,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;IAMhC,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;IAM/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;IAM/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;IAmBhC,OAAO,CAAC,cAAc;CAwBvB"}