@statsig/js-local-overrides 0.0.1-beta.12 → 0.0.1-beta.13
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/package.json +2 -2
- package/src/LocalOverrideAdapter.d.ts +13 -0
- package/src/LocalOverrideAdapter.js +54 -0
- package/src/index.js +17 -0
- package/.eslintrc.json +0 -25
- package/jest.config.ts +0 -10
- package/project.json +0 -33
- package/src/LocalOverrideAdapter.ts +0 -101
- package/src/__tests__/LocalOverrides.test.ts +0 -45
- package/tsconfig.json +0 -14
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -17
- /package/src/{index.ts → index.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DynamicConfig, Experiment, FeatureGate, Layer, OverrideAdapter, StatsigUser } from '@statsig/client-core';
|
|
2
|
+
export declare class LocalOverrideAdapter implements OverrideAdapter {
|
|
3
|
+
private readonly _overrides;
|
|
4
|
+
overrideGate(name: string, value: boolean): void;
|
|
5
|
+
getGateOverride(current: FeatureGate, _user: StatsigUser): FeatureGate | null;
|
|
6
|
+
overrideDynamicConfig(name: string, value: Record<string, unknown>): void;
|
|
7
|
+
getDynamicConfigOverride(current: DynamicConfig, _user: StatsigUser): DynamicConfig | null;
|
|
8
|
+
overrideExperiment(name: string, value: Record<string, unknown>): void;
|
|
9
|
+
getExperimentOverride(current: Experiment, _user: StatsigUser): Experiment | null;
|
|
10
|
+
overrideLayer(name: string, value: Record<string, unknown>): void;
|
|
11
|
+
getLayerOverride(current: Layer, _user: StatsigUser): Layer | null;
|
|
12
|
+
private _getConfigOverride;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalOverrideAdapter = void 0;
|
|
4
|
+
const LOCAL_OVERRIDE_REASON = 'LocalOverride';
|
|
5
|
+
class LocalOverrideAdapter {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._overrides = {
|
|
8
|
+
gate: {},
|
|
9
|
+
dynamicConfig: {},
|
|
10
|
+
experiment: {},
|
|
11
|
+
layer: {},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
overrideGate(name, value) {
|
|
15
|
+
this._overrides.gate[name] = value;
|
|
16
|
+
}
|
|
17
|
+
getGateOverride(current, _user) {
|
|
18
|
+
const overridden = this._overrides.gate[current.name];
|
|
19
|
+
if (overridden == null) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return Object.assign(Object.assign({}, current), { value: overridden, details: Object.assign(Object.assign({}, current.details), { reason: LOCAL_OVERRIDE_REASON }) });
|
|
23
|
+
}
|
|
24
|
+
overrideDynamicConfig(name, value) {
|
|
25
|
+
this._overrides.dynamicConfig[name] = value;
|
|
26
|
+
}
|
|
27
|
+
getDynamicConfigOverride(current, _user) {
|
|
28
|
+
return this._getConfigOverride(current, this._overrides.dynamicConfig);
|
|
29
|
+
}
|
|
30
|
+
overrideExperiment(name, value) {
|
|
31
|
+
this._overrides.experiment[name] = value;
|
|
32
|
+
}
|
|
33
|
+
getExperimentOverride(current, _user) {
|
|
34
|
+
return this._getConfigOverride(current, this._overrides.experiment);
|
|
35
|
+
}
|
|
36
|
+
overrideLayer(name, value) {
|
|
37
|
+
this._overrides.layer[name] = value;
|
|
38
|
+
}
|
|
39
|
+
getLayerOverride(current, _user) {
|
|
40
|
+
const overridden = this._overrides.layer[current.name];
|
|
41
|
+
if (overridden == null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return Object.assign(Object.assign({}, current), { _value: overridden, details: Object.assign(Object.assign({}, current.details), { reason: LOCAL_OVERRIDE_REASON }) });
|
|
45
|
+
}
|
|
46
|
+
_getConfigOverride(current, lookup) {
|
|
47
|
+
const overridden = lookup[current.name];
|
|
48
|
+
if (overridden == null) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return Object.assign(Object.assign({}, current), { value: overridden, details: Object.assign(Object.assign({}, current.details), { reason: LOCAL_OVERRIDE_REASON }) });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.LocalOverrideAdapter = LocalOverrideAdapter;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./LocalOverrideAdapter"), exports);
|
package/.eslintrc.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": ["../../.eslintrc.json"],
|
|
3
|
-
"ignorePatterns": ["!**/*"],
|
|
4
|
-
"overrides": [
|
|
5
|
-
{
|
|
6
|
-
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
7
|
-
"rules": {}
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"files": ["*.ts", "*.tsx"],
|
|
11
|
-
"rules": {}
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"files": ["*.js", "*.jsx"],
|
|
15
|
-
"rules": {}
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"files": ["*.json"],
|
|
19
|
-
"parser": "jsonc-eslint-parser",
|
|
20
|
-
"rules": {
|
|
21
|
-
"@nx/dependency-checks": "error"
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
}
|
package/jest.config.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
export default {
|
|
3
|
-
displayName: 'js-local-overrides',
|
|
4
|
-
preset: '../../jest.preset.js',
|
|
5
|
-
transform: {
|
|
6
|
-
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
7
|
-
},
|
|
8
|
-
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
|
-
coverageDirectory: '../../coverage/packages/js-local-overrides',
|
|
10
|
-
};
|
package/project.json
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "js-local-overrides",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/js-local-overrides/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"targets": {
|
|
7
|
-
"build": {
|
|
8
|
-
"executor": "@nx/js:tsc",
|
|
9
|
-
"outputs": ["{options.outputPath}"],
|
|
10
|
-
"options": {
|
|
11
|
-
"outputPath": "dist/packages/js-local-overrides",
|
|
12
|
-
"main": "packages/js-local-overrides/src/index.ts",
|
|
13
|
-
"tsConfig": "packages/js-local-overrides/tsconfig.lib.json",
|
|
14
|
-
"assets": []
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"publish": {
|
|
18
|
-
"command": "ts-node ./tools/scripts/publish.ts js-local-overrides",
|
|
19
|
-
"dependsOn": ["build"]
|
|
20
|
-
},
|
|
21
|
-
"lint": {
|
|
22
|
-
"executor": "@nx/eslint:lint"
|
|
23
|
-
},
|
|
24
|
-
"test": {
|
|
25
|
-
"executor": "@nx/jest:jest",
|
|
26
|
-
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
27
|
-
"options": {
|
|
28
|
-
"jestConfig": "packages/js-local-overrides/jest.config.ts"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"tags": []
|
|
33
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DynamicConfig,
|
|
3
|
-
Experiment,
|
|
4
|
-
FeatureGate,
|
|
5
|
-
Layer,
|
|
6
|
-
OverrideAdapter,
|
|
7
|
-
StatsigUser,
|
|
8
|
-
} from '@statsig/client-core';
|
|
9
|
-
|
|
10
|
-
const LOCAL_OVERRIDE_REASON = 'LocalOverride';
|
|
11
|
-
|
|
12
|
-
type OverrideStore = {
|
|
13
|
-
gate: Record<string, boolean>;
|
|
14
|
-
dynamicConfig: Record<string, Record<string, unknown>>;
|
|
15
|
-
experiment: OverrideStore['dynamicConfig'];
|
|
16
|
-
layer: OverrideStore['dynamicConfig'];
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export class LocalOverrideAdapter implements OverrideAdapter {
|
|
20
|
-
private readonly _overrides: OverrideStore = {
|
|
21
|
-
gate: {},
|
|
22
|
-
dynamicConfig: {},
|
|
23
|
-
experiment: {},
|
|
24
|
-
layer: {},
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
overrideGate(name: string, value: boolean): void {
|
|
28
|
-
this._overrides.gate[name] = value;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getGateOverride(
|
|
32
|
-
current: FeatureGate,
|
|
33
|
-
_user: StatsigUser,
|
|
34
|
-
): FeatureGate | null {
|
|
35
|
-
const overridden = this._overrides.gate[current.name];
|
|
36
|
-
if (overridden == null) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
...current,
|
|
42
|
-
value: overridden,
|
|
43
|
-
details: { ...current.details, reason: LOCAL_OVERRIDE_REASON },
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
overrideDynamicConfig(name: string, value: Record<string, unknown>): void {
|
|
48
|
-
this._overrides.dynamicConfig[name] = value;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getDynamicConfigOverride(
|
|
52
|
-
current: DynamicConfig,
|
|
53
|
-
_user: StatsigUser,
|
|
54
|
-
): DynamicConfig | null {
|
|
55
|
-
return this._getConfigOverride(current, this._overrides.dynamicConfig);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
overrideExperiment(name: string, value: Record<string, unknown>): void {
|
|
59
|
-
this._overrides.experiment[name] = value;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
getExperimentOverride(
|
|
63
|
-
current: Experiment,
|
|
64
|
-
_user: StatsigUser,
|
|
65
|
-
): Experiment | null {
|
|
66
|
-
return this._getConfigOverride(current, this._overrides.experiment);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
overrideLayer(name: string, value: Record<string, unknown>): void {
|
|
70
|
-
this._overrides.layer[name] = value;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getLayerOverride(current: Layer, _user: StatsigUser): Layer | null {
|
|
74
|
-
const overridden = this._overrides.layer[current.name];
|
|
75
|
-
if (overridden == null) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
...current,
|
|
81
|
-
_value: overridden,
|
|
82
|
-
details: { ...current.details, reason: LOCAL_OVERRIDE_REASON },
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private _getConfigOverride<T extends Experiment | DynamicConfig>(
|
|
87
|
-
current: T,
|
|
88
|
-
lookup: Record<string, Record<string, unknown>>,
|
|
89
|
-
): T | null {
|
|
90
|
-
const overridden = lookup[current.name];
|
|
91
|
-
if (overridden == null) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
...current,
|
|
97
|
-
value: overridden,
|
|
98
|
-
details: { ...current.details, reason: LOCAL_OVERRIDE_REASON },
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
makeDynamicConfig,
|
|
3
|
-
makeFeatureGate,
|
|
4
|
-
makeLayer,
|
|
5
|
-
} from '@statsig/client-core';
|
|
6
|
-
|
|
7
|
-
import { LocalOverrideAdapter } from '../LocalOverrideAdapter';
|
|
8
|
-
|
|
9
|
-
describe('Local Overrides', () => {
|
|
10
|
-
const user = { userID: 'a-user' };
|
|
11
|
-
const gate = makeFeatureGate('a_gate', { reason: '' }, null);
|
|
12
|
-
const dynamicConfig = makeDynamicConfig('a_config', { reason: '' }, null);
|
|
13
|
-
const experiment = makeDynamicConfig('an_experiment', { reason: '' }, null);
|
|
14
|
-
const layer = makeLayer('a_layer', { reason: '' }, null);
|
|
15
|
-
|
|
16
|
-
let provider: LocalOverrideAdapter;
|
|
17
|
-
|
|
18
|
-
beforeAll(() => {
|
|
19
|
-
provider = new LocalOverrideAdapter();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('returns overidden gates', () => {
|
|
23
|
-
provider.overrideGate(gate.name, true);
|
|
24
|
-
const overridden = provider.getGateOverride(gate, user);
|
|
25
|
-
expect(overridden?.value).toBe(true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('returns overidden dynamic configs', () => {
|
|
29
|
-
provider.overrideDynamicConfig(dynamicConfig.name, { dc: 'value' });
|
|
30
|
-
const overridden = provider.getDynamicConfigOverride(dynamicConfig, user);
|
|
31
|
-
expect(overridden?.value).toEqual({ dc: 'value' });
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('returns overidden experiment', () => {
|
|
35
|
-
provider.overrideExperiment(experiment.name, { exp: 'value' });
|
|
36
|
-
const overridden = provider.getExperimentOverride(experiment, user);
|
|
37
|
-
expect(overridden?.value).toEqual({ exp: 'value' });
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('returns overidden layer', () => {
|
|
41
|
-
provider.overrideLayer(layer.name, { layer_key: 'value' });
|
|
42
|
-
const overridden = provider.getLayerOverride(layer, user);
|
|
43
|
-
expect(overridden?._value).toEqual({ layer_key: 'value' });
|
|
44
|
-
});
|
|
45
|
-
});
|
package/tsconfig.json
DELETED
package/tsconfig.lib.json
DELETED
package/tsconfig.spec.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "../../dist/out-tsc",
|
|
5
|
-
"module": "commonjs",
|
|
6
|
-
"types": ["jest", "node"],
|
|
7
|
-
"resolveJsonModule": true,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"sourceMap": true
|
|
10
|
-
},
|
|
11
|
-
"include": [
|
|
12
|
-
"jest.config.ts",
|
|
13
|
-
"src/**/*.test.ts",
|
|
14
|
-
"src/**/*.spec.ts",
|
|
15
|
-
"src/**/*.d.ts"
|
|
16
|
-
]
|
|
17
|
-
}
|
|
File without changes
|