Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ FROM openfeature-provider-js-base AS openfeature-provider-js.test
# Copy confidence-resolver protos (needed by some tests for proto parsing)
COPY confidence-resolver/protos ../../../confidence-resolver/protos
COPY wasm/resolver_state.pb ../../../wasm/resolver_state.pb
COPY openfeature-provider/js/prettier.config.cjs ./
COPY openfeature-provider/js/.prettierignore ./

RUN make test

Expand Down
9 changes: 9 additions & 0 deletions openfeature-provider/js/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules/
dist/
src/proto/
.idea
coverage/*
*.log
api/*
CHANGELOG.md
README.md
1 change: 1 addition & 0 deletions openfeature-provider/js/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ install: $(INSTALL_STAMP) $(GEN_TS)
build: $(BUILD_STAMP)

test: $(WASM_ARTIFACT) $(INSTALL_STAMP) $(GEN_TS)
yarn format:check
yarn test --run --exclude='**/*.e2e.test.ts'

test-e2e: $(WASM_ARTIFACT) $(INSTALL_STAMP) $(GEN_TS)
Expand Down
8 changes: 8 additions & 0 deletions openfeature-provider/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,11 @@ The package exports a browser ESM build that compiles the WASM via streaming and
## License

See the root `LICENSE`.

## Formatting

Code is formatted using prettier, you can format all files by running

```sh
yarn format
```
4 changes: 4 additions & 0 deletions openfeature-provider/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"scripts": {
"build": "tsdown",
"dev": "tsdown --watch",
"format": "prettier --config prettier.config.cjs -w .",
"format:check": "prettier --config prettier.config.cjs -c .",
"test": "vitest",
"proto:gen": "rm -rf src/proto && mkdir -p src/proto && protoc --plugin=node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt useOptionals=messages --ts_proto_opt esModuleInterop=true --ts_proto_out src/proto -Iproto api.proto messages.proto test-only.proto"
},
Expand All @@ -41,11 +43,13 @@
"devDependencies": {
"@openfeature/core": "^1.9.0",
"@openfeature/server-sdk": "^1.19.0",
"@spotify/prettier-config": "^15.0.0",
"@types/debug": "^4",
"@types/node": "^24.0.1",
"@vitest/coverage-v8": "^3.2.4",
"debug": "^4.4.3",
"dotenv": "^17.2.2",
"prettier": "^2.8.8",
"rolldown": "1.0.0-beta.38",
"ts-proto": "^2.7.3",
"tsdown": "latest",
Expand Down
8 changes: 8 additions & 0 deletions openfeature-provider/js/prettier.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const baseConfig = require('@spotify/prettier-config');

module.exports = {
...baseConfig,
tabWidth: 2,
useTabs: false,
printWidth: 120,
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@ import { ConfidenceServerProviderLocal } from './ConfidenceServerProviderLocal';
import { readFileSync } from 'node:fs';
import { WasmResolver } from './WasmResolver';

const {
JS_E2E_CONFIDENCE_API_CLIENT_ID,
JS_E2E_CONFIDENCE_API_CLIENT_SECRET,
} = requireEnv('JS_E2E_CONFIDENCE_API_CLIENT_ID', 'JS_E2E_CONFIDENCE_API_CLIENT_SECRET');
const { JS_E2E_CONFIDENCE_API_CLIENT_ID, JS_E2E_CONFIDENCE_API_CLIENT_SECRET } = requireEnv(
'JS_E2E_CONFIDENCE_API_CLIENT_ID',
'JS_E2E_CONFIDENCE_API_CLIENT_SECRET',
);

const moduleBytes = readFileSync(__dirname + '/../../../wasm/confidence_resolver.wasm');
const module = new WebAssembly.Module(moduleBytes);
const resolver = new WasmResolver(module);
const confidenceProvider = new ConfidenceServerProviderLocal(resolver, {
flagClientSecret: 'RxDVTrXvc6op1XxiQ4OaR31dKbJ39aYV',
apiClientId: JS_E2E_CONFIDENCE_API_CLIENT_ID,
apiClientSecret: JS_E2E_CONFIDENCE_API_CLIENT_SECRET
apiClientSecret: JS_E2E_CONFIDENCE_API_CLIENT_SECRET,
});

describe('ConfidenceServerProvider E2E tests', () => {
beforeAll( async () => {

beforeAll(async () => {
await OpenFeature.setProviderAndWait(confidenceProvider);
OpenFeature.setContext({
targetingKey: 'test-a', // control
sticky: false,
});
});

afterAll(() => OpenFeature.close())
afterAll(() => OpenFeature.close());

it('should resolve a boolean e2e', async () => {
const client = OpenFeature.getClient();
Expand Down Expand Up @@ -88,24 +87,26 @@ describe('ConfidenceServerProvider E2E tests', () => {

it('should resolve a flag with a sticky resolve', async () => {
const client = OpenFeature.getClient();
const result = await client.getNumberDetails('web-sdk-e2e-flag.double', -1, { targetingKey: 'test-a', sticky: true });

const result = await client.getNumberDetails('web-sdk-e2e-flag.double', -1, {
targetingKey: 'test-a',
sticky: true,
});

// The flag has a running experiment with a sticky assignment. The intake is paused but we should still get the sticky assignment.
// If this test breaks it could mean that the experiment was removed or that the bigtable materialization was cleaned out.
expect(result.value).toBe(99.99);
expect(result.variant).toBe('flags/web-sdk-e2e-flag/variants/sticky');
expect(result.reason).toBe('MATCH');

});
});

function requireEnv<const N extends string[]>(...names:N): Record<N[number],string> {
function requireEnv<const N extends string[]>(...names: N): Record<N[number], string> {
return names.reduce((acc, name) => {
const value = process.env[name];
if(!value) throw new Error(`Missing environment variable ${name}`)
if (!value) throw new Error(`Missing environment variable ${name}`);
return {
...acc,
[name]: value
[name]: value,
};
}, {}) as Record<N[number],string>;
}
}, {}) as Record<N[number], string>;
}
Loading
Loading