Skip to content
Open
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: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ RUN make install

# Copy source and config
COPY openfeature-provider/js/src ./src/
COPY openfeature-provider/js/tsconfig.json openfeature-provider/js/tsdown.config.ts openfeature-provider/js/vitest.config.ts ./
COPY openfeature-provider/js/tsconfig.json openfeature-provider/js/tsdown.config.ts openfeature-provider/js/vitest.config.ts openfeature-provider/js/prettier.config.cjs openfeature-provider/js/.prettierignore ./
COPY openfeature-provider/js/Makefile ./

# Copy WASM module
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if lint should happen during build rather than test?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could do both.

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
```
6 changes: 6 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,15 @@
"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",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"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,30 +4,29 @@ 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
});
});

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

it('should resolve a boolean e2e', async () => {
const client = OpenFeature.getClient();
Expand Down Expand Up @@ -87,24 +86,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