Compare commits
19 Commits
main
...
open-telem
Author | SHA1 | Date |
---|---|---|
|
543df23111 | |
|
d2fe992871 | |
|
ea91cf4044 | |
|
97353c0e89 | |
|
cb25a0e571 | |
|
4e7edfeb23 | |
|
f38d302537 | |
|
2c0b892035 | |
|
63fa06b290 | |
|
ea6e51c997 | |
|
bf93c42c1b | |
|
56cb14630d | |
|
b9e620ac80 | |
|
30308f69ae | |
|
b941afed7b | |
|
936939ab0b | |
|
a8f3ef119c | |
|
2a1567d58b | |
|
f1d7c4cabd |
|
@ -1,9 +1,15 @@
|
|||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: ['main']
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- alpha
|
||||
pull_request:
|
||||
branches: ['main']
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
- alpha
|
||||
|
||||
jobs:
|
||||
main:
|
||||
|
@ -13,6 +19,7 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
- uses: nrwl/nx-set-shas@v2
|
||||
|
||||
- run: npm ci
|
||||
|
||||
- run: npx nx workspace-lint
|
||||
|
@ -20,3 +27,10 @@ jobs:
|
|||
- run: npx nx affected --target=lint --parallel=3
|
||||
- run: npx nx affected --target=test --parallel=3 --ci --code-coverage
|
||||
- run: npx nx affected --target=build --parallel=3
|
||||
|
||||
- name: Release
|
||||
if: ${{ success() && (github.event_name != 'pull_request' || github.event.action == 'closed' && github.event.pull_request.merged == true) }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npx nx affected --target release --output-style stream
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
name: "Lint PR"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
branches: [
|
||||
'main',
|
||||
{
|
||||
name: 'beta',
|
||||
prerelease: true,
|
||||
},
|
||||
{
|
||||
name: 'alpha',
|
||||
prerelease: true,
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
# [1.0.0-alpha.7](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.6...open-telemetry-v1.0.0-alpha.7) (2022-06-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Touch otel ([#19](https://github.com/open-feature/node-sdk-contrib/issues/19)) ([d2fe992](https://github.com/open-feature/node-sdk-contrib/commit/d2fe99287152d4a1bb12fcb0d9d7e82fafc087f5))
|
||||
|
||||
# [1.0.0-alpha.6](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.5...open-telemetry-v1.0.0-alpha.6) (2022-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Comment for clarity ([#18](https://github.com/open-feature/node-sdk-contrib/issues/18)) ([cb25a0e](https://github.com/open-feature/node-sdk-contrib/commit/cb25a0e57155a382891821d40b21b046b5e9a81f))
|
||||
|
||||
# [1.0.0-alpha.5](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.4...open-telemetry-v1.0.0-alpha.5) (2022-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Flagd tag fix ([#17](https://github.com/open-feature/node-sdk-contrib/issues/17)) ([2c0b892](https://github.com/open-feature/node-sdk-contrib/commit/2c0b8920359efd6d04e9300e1550808d5e09e5e4))
|
||||
|
||||
# [1.0.0-alpha.4](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.3...open-telemetry-v1.0.0-alpha.4) (2022-06-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Flagd http provider ([#15](https://github.com/open-feature/node-sdk-contrib/issues/15)) ([ea6e51c](https://github.com/open-feature/node-sdk-contrib/commit/ea6e51c9975224ab0238430d407af7b9d6d501ec))
|
||||
|
||||
# [1.0.0-alpha.3](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.2...open-telemetry-v1.0.0-alpha.3) (2022-06-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* set license to apache 2 ([#13](https://github.com/open-feature/node-sdk-contrib/issues/13)) ([56cb146](https://github.com/open-feature/node-sdk-contrib/commit/56cb14630d49cc8311049bb96edbfed93e6260d1))
|
||||
|
||||
# [1.0.0-alpha.2](https://github.com/open-feature/node-sdk-contrib/compare/open-telemetry-v1.0.0-alpha.1...open-telemetry-v1.0.0-alpha.2) (2022-06-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* set publish config access to public ([#12](https://github.com/open-feature/node-sdk-contrib/issues/12)) ([30308f6](https://github.com/open-feature/node-sdk-contrib/commit/30308f69ae0780019cf024fb504a07d09976b77f))
|
||||
|
||||
# 1.0.0-alpha.1 (2022-06-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* remove trace name and version ([#10](https://github.com/open-feature/node-sdk-contrib/issues/10)) ([a8f3ef1](https://github.com/open-feature/node-sdk-contrib/commit/a8f3ef119c2d141de49db5857c607b6b0b4776a6))
|
|
@ -8,7 +8,7 @@
|
|||
$ npm install @openfeature/open-telemetry-hook
|
||||
```
|
||||
|
||||
Required peer dependencies
|
||||
### Required peer dependencies
|
||||
|
||||
```
|
||||
$ npm install @openfeature/nodejs-sdk @opentelemetry/api
|
||||
|
@ -16,8 +16,8 @@ $ npm install @openfeature/nodejs-sdk @opentelemetry/api
|
|||
|
||||
## Building
|
||||
|
||||
Run `nx package hooks-open-telemetry` to build the library.
|
||||
Run `npx nx package hooks-open-telemetry` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test hooks-open-telemetry` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
Run `npx nx test hooks-open-telemetry` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
{
|
||||
"name": "@openfeature/open-telemetry-hook",
|
||||
"version": "0.0.1",
|
||||
"type": "commonjs"
|
||||
"version": "0.0.0-semantic-release",
|
||||
"type": "commonjs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/open-feature/node-sdk-contrib.git",
|
||||
"directory": "libs/hooks/open-telemetry"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
|
|
|
@ -65,6 +65,20 @@
|
|||
"jestConfig": "libs/hooks/open-telemetry/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"release": {
|
||||
"executor": "nx:run-commands",
|
||||
"outputs": [],
|
||||
"options": {
|
||||
"command": "npx semantic-release --extends ./libs/hooks/open-telemetry/release.config.js",
|
||||
"parallel": false
|
||||
},
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": "self",
|
||||
"target": "package"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
const name = 'open-telemetry';
|
||||
const srcRoot = `libs/hooks/${name}`;
|
||||
|
||||
module.exports = {
|
||||
pkgRoot: `dist/${srcRoot}`,
|
||||
tagFormat: name + '-v${version}',
|
||||
commitPaths: [`${srcRoot}/*`],
|
||||
plugins: [
|
||||
'@semantic-release/commit-analyzer',
|
||||
'@semantic-release/release-notes-generator',
|
||||
[
|
||||
'@semantic-release/changelog',
|
||||
{
|
||||
changelogFile: `${srcRoot}/CHANGELOG.md`,
|
||||
},
|
||||
],
|
||||
'@semantic-release/npm',
|
||||
[
|
||||
'@semantic-release/git',
|
||||
{
|
||||
assets: [`${srcRoot}/package.json`, `${srcRoot}/CHANGELOG.md`],
|
||||
message:
|
||||
`release(version): Release ${name} ` +
|
||||
'${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
|
@ -38,7 +38,7 @@ describe('OpenTelemetry Hooks', () => {
|
|||
let otelHook: OpenTelemetryHook;
|
||||
|
||||
beforeEach(() => {
|
||||
otelHook = new OpenTelemetryHook('test');
|
||||
otelHook = new OpenTelemetryHook();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
|
|
@ -19,8 +19,8 @@ export class OpenTelemetryHook implements Hook {
|
|||
private spanMap = new WeakMap<HookContext, Span>();
|
||||
private tracer: Tracer;
|
||||
|
||||
constructor(name: string, version?: string) {
|
||||
this.tracer = trace.getTracer(name, version);
|
||||
constructor() {
|
||||
this.tracer = trace.getTracer('@openfeature/open-telemetry-hook');
|
||||
}
|
||||
|
||||
before(hookContext: HookContext) {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"presets": [
|
||||
[
|
||||
"@nrwl/web/babel",
|
||||
{
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": ["../../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
# 1.0.0-alpha.1 (2022-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Comment for clarity ([#18](https://github.com/open-feature/node-sdk-contrib/issues/18)) ([cb25a0e](https://github.com/open-feature/node-sdk-contrib/commit/cb25a0e57155a382891821d40b21b046b5e9a81f))
|
||||
* Flagd tag fix ([#17](https://github.com/open-feature/node-sdk-contrib/issues/17)) ([2c0b892](https://github.com/open-feature/node-sdk-contrib/commit/2c0b8920359efd6d04e9300e1550808d5e09e5e4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Flagd http provider ([#15](https://github.com/open-feature/node-sdk-contrib/issues/15)) ([ea6e51c](https://github.com/open-feature/node-sdk-contrib/commit/ea6e51c9975224ab0238430d407af7b9d6d501ec))
|
||||
* remove trace name and version ([#10](https://github.com/open-feature/node-sdk-contrib/issues/10)) ([a8f3ef1](https://github.com/open-feature/node-sdk-contrib/commit/a8f3ef119c2d141de49db5857c607b6b0b4776a6))
|
||||
* set license to apache 2 ([#13](https://github.com/open-feature/node-sdk-contrib/issues/13)) ([56cb146](https://github.com/open-feature/node-sdk-contrib/commit/56cb14630d49cc8311049bb96edbfed93e6260d1))
|
||||
* set publish config access to public ([#12](https://github.com/open-feature/node-sdk-contrib/issues/12)) ([30308f6](https://github.com/open-feature/node-sdk-contrib/commit/30308f69ae0780019cf024fb504a07d09976b77f))
|
||||
|
||||
# 1.0.0-alpha.1 (2022-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Flagd tag fix ([#17](https://github.com/open-feature/node-sdk-contrib/issues/17)) ([2c0b892](https://github.com/open-feature/node-sdk-contrib/commit/2c0b8920359efd6d04e9300e1550808d5e09e5e4))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Flagd http provider ([#15](https://github.com/open-feature/node-sdk-contrib/issues/15)) ([ea6e51c](https://github.com/open-feature/node-sdk-contrib/commit/ea6e51c9975224ab0238430d407af7b9d6d501ec))
|
||||
* remove trace name and version ([#10](https://github.com/open-feature/node-sdk-contrib/issues/10)) ([a8f3ef1](https://github.com/open-feature/node-sdk-contrib/commit/a8f3ef119c2d141de49db5857c607b6b0b4776a6))
|
||||
* set license to apache 2 ([#13](https://github.com/open-feature/node-sdk-contrib/issues/13)) ([56cb146](https://github.com/open-feature/node-sdk-contrib/commit/56cb14630d49cc8311049bb96edbfed93e6260d1))
|
||||
* set publish config access to public ([#12](https://github.com/open-feature/node-sdk-contrib/issues/12)) ([30308f6](https://github.com/open-feature/node-sdk-contrib/commit/30308f69ae0780019cf024fb504a07d09976b77f))
|
|
@ -0,0 +1,23 @@
|
|||
# NodeJS Flagd REST Provider for OpenFeature
|
||||
|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install @openfeature/flagd-rest-provider
|
||||
```
|
||||
|
||||
### Peer dependencies
|
||||
|
||||
```
|
||||
$ npm install @openfeature/nodejs-sdk @openfeature/provider-rest-client
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Run `npx nx package providers-flagd-rest` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `npx nx test providers-flagd-rest` to execute the unit tests via [Jest](https://jestjs.io).
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["minify"]
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'providers-flagd-rest',
|
||||
preset: '../../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': 'ts-jest',
|
||||
},
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['ts', 'js', 'html'],
|
||||
coverageDirectory: '../../../coverage/libs/providers/flagd-rest',
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "@openfeature/flagd-rest-provider",
|
||||
"version": "0.0.1",
|
||||
"type": "commonjs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/open-feature/node-sdk-contrib.git",
|
||||
"directory": "libs/providers/flagd-rest"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "Apache-2.0"
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/providers/flagd-rest/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"publish": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"options": {
|
||||
"command": "node tools/scripts/publish.mjs providers-flagd-rest {args.ver} {args.tag}"
|
||||
},
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": "self",
|
||||
"target": "package"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["libs/providers/flagd-rest/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/libs/providers/flagd-rest"],
|
||||
"options": {
|
||||
"jestConfig": "libs/providers/flagd-rest/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"package": {
|
||||
"executor": "@nrwl/web:rollup",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"project": "libs/providers/flagd-rest/package.json",
|
||||
"outputPath": "dist/libs/providers/flagd-rest",
|
||||
"entryFile": "libs/providers/flagd-rest/src/index.ts",
|
||||
"tsConfig": "libs/providers/flagd-rest/tsconfig.lib.json",
|
||||
"compiler": "babel",
|
||||
"umdName": "Flagd REST",
|
||||
"external": ["typescript"],
|
||||
"format": ["cjs", "esm"],
|
||||
"assets": [
|
||||
{
|
||||
"glob": "LICENSE",
|
||||
"input": "./",
|
||||
"output": "./"
|
||||
},
|
||||
{
|
||||
"glob": "README.md",
|
||||
"input": "./libs/providers/flagd-rest",
|
||||
"output": "./"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"release": {
|
||||
"executor": "nx:run-commands",
|
||||
"outputs": [],
|
||||
"options": {
|
||||
"command": "npx semantic-release --extends ./libs/providers/flagd-rest/release.config.js",
|
||||
"parallel": false
|
||||
},
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": "self",
|
||||
"target": "package"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
const name = 'flagd-rest';
|
||||
const srcRoot = 'libs/providers/flagd-rest';
|
||||
|
||||
module.exports = {
|
||||
pkgRoot: `dist/${srcRoot}`,
|
||||
tagFormat: name + '-v${version}',
|
||||
commitPaths: [`${srcRoot}/*`],
|
||||
plugins: [
|
||||
'@semantic-release/commit-analyzer',
|
||||
'@semantic-release/release-notes-generator',
|
||||
[
|
||||
'@semantic-release/changelog',
|
||||
{
|
||||
changelogFile: `${srcRoot}/CHANGELOG.md`,
|
||||
},
|
||||
],
|
||||
'@semantic-release/npm',
|
||||
[
|
||||
'@semantic-release/git',
|
||||
{
|
||||
assets: [`${srcRoot}/package.json`, `${srcRoot}/CHANGELOG.md`],
|
||||
message:
|
||||
`release(version): Release ${name} ` +
|
||||
'${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export * from './lib/flagd-rest-provider';
|
|
@ -0,0 +1,159 @@
|
|||
import {
|
||||
ErrorCode,
|
||||
FlagValueType,
|
||||
TypeMismatchError,
|
||||
} from '@openfeature/nodejs-sdk';
|
||||
import * as nock from 'nock';
|
||||
import { FlagdRESTProvider } from './flagd-rest-provider';
|
||||
|
||||
type SuccessfulTest = {
|
||||
flagValueType: FlagValueType;
|
||||
defaultValue: any;
|
||||
reply: { code: number; body: { value: any } };
|
||||
expectedValue: { value: any };
|
||||
};
|
||||
|
||||
type ErrorTest = {
|
||||
flagValueType: FlagValueType;
|
||||
defaultValue: any;
|
||||
reply: { code: number; body: { errorCode?: string } };
|
||||
expectedValue: { new (...args: any[]): Error };
|
||||
};
|
||||
|
||||
describe('FlagdRESTProvider', () => {
|
||||
const flagName = 'testFlag';
|
||||
const flagdRESTProvider = new FlagdRESTProvider();
|
||||
|
||||
const successfulTests: Array<SuccessfulTest> = [
|
||||
{
|
||||
flagValueType: 'boolean',
|
||||
defaultValue: false,
|
||||
reply: { code: 200, body: { value: true } },
|
||||
expectedValue: { value: true },
|
||||
},
|
||||
{
|
||||
flagValueType: 'string',
|
||||
defaultValue: 'red',
|
||||
reply: { code: 200, body: { value: 'blue' } },
|
||||
expectedValue: { value: 'blue' },
|
||||
},
|
||||
{
|
||||
flagValueType: 'number',
|
||||
defaultValue: 0,
|
||||
reply: { code: 200, body: { value: 1 } },
|
||||
expectedValue: { value: 1 },
|
||||
},
|
||||
{
|
||||
flagValueType: 'object',
|
||||
defaultValue: { size: 'small' },
|
||||
reply: { code: 200, body: { value: { size: 'large' } } },
|
||||
expectedValue: { value: { size: 'large' } },
|
||||
},
|
||||
];
|
||||
|
||||
const errorTests: Array<ErrorTest> = [
|
||||
{
|
||||
flagValueType: 'boolean',
|
||||
defaultValue: false,
|
||||
reply: { code: 400, body: { errorCode: ErrorCode.TYPE_MISMATCH } },
|
||||
expectedValue: TypeMismatchError,
|
||||
},
|
||||
{
|
||||
flagValueType: 'string',
|
||||
defaultValue: 'red',
|
||||
reply: { code: 400, body: { errorCode: ErrorCode.TYPE_MISMATCH } },
|
||||
expectedValue: TypeMismatchError,
|
||||
},
|
||||
{
|
||||
flagValueType: 'number',
|
||||
defaultValue: 0,
|
||||
reply: { code: 400, body: { errorCode: ErrorCode.TYPE_MISMATCH } },
|
||||
expectedValue: TypeMismatchError,
|
||||
},
|
||||
{
|
||||
flagValueType: 'object',
|
||||
defaultValue: { size: 'small' },
|
||||
reply: { code: 400, body: { errorCode: ErrorCode.TYPE_MISMATCH } },
|
||||
expectedValue: TypeMismatchError,
|
||||
},
|
||||
];
|
||||
|
||||
function setupNock(flagValueType: string, code: number, body: any) {
|
||||
nock('http://localhost:8080')
|
||||
.post(`/flags/${flagName}/resolve/${flagValueType}`)
|
||||
// All query string will match
|
||||
.query(() => true)
|
||||
.reply(code, body);
|
||||
}
|
||||
|
||||
async function resolveValue(flagValueType: FlagValueType, defaultValue: any) {
|
||||
let output;
|
||||
|
||||
if (flagValueType === 'boolean') {
|
||||
output = await flagdRESTProvider.resolveBooleanEvaluation(
|
||||
flagName,
|
||||
defaultValue,
|
||||
{}
|
||||
);
|
||||
} else if (flagValueType === 'number') {
|
||||
output = await flagdRESTProvider.resolveNumberEvaluation(
|
||||
flagName,
|
||||
defaultValue,
|
||||
{}
|
||||
);
|
||||
} else if (flagValueType === 'string') {
|
||||
output = await flagdRESTProvider.resolveStringEvaluation(
|
||||
flagName,
|
||||
defaultValue,
|
||||
{}
|
||||
);
|
||||
} else if (flagValueType === 'object') {
|
||||
output = await flagdRESTProvider.resolveObjectEvaluation(
|
||||
flagName,
|
||||
defaultValue,
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
nock.disableNetConnect();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
nock.enableNetConnect();
|
||||
nock.cleanAll();
|
||||
nock.restore();
|
||||
});
|
||||
|
||||
successfulTests.forEach(
|
||||
({ flagValueType, defaultValue, reply, expectedValue }) => {
|
||||
it(`should return ${JSON.stringify(
|
||||
expectedValue.value
|
||||
)} for a successful ${flagValueType} evaluation`, async () => {
|
||||
setupNock(flagValueType, reply.code, reply.body);
|
||||
const output = await resolveValue(flagValueType, defaultValue);
|
||||
|
||||
expect(output).toStrictEqual(expectedValue);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
errorTests.forEach(
|
||||
({ flagValueType, defaultValue, reply, expectedValue }) => {
|
||||
it(`should throw because a status code of ${reply.code} was during a ${flagValueType} evaluation`, async () => {
|
||||
setupNock(flagValueType, reply.code, reply.body);
|
||||
|
||||
try {
|
||||
const output = await resolveValue(flagValueType, defaultValue);
|
||||
|
||||
expect(output).toBeUndefined();
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(expectedValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
|
@ -0,0 +1,100 @@
|
|||
import {
|
||||
ErrorCode,
|
||||
EvaluationContext,
|
||||
FlagNotFoundError,
|
||||
ParseError,
|
||||
Provider,
|
||||
ResolutionDetails,
|
||||
TypeMismatchError,
|
||||
} from '@openfeature/nodejs-sdk';
|
||||
import {
|
||||
BooleanFlagResolutionApi,
|
||||
NumericFlagResolutionApi,
|
||||
ObjectFlagResolutionApi,
|
||||
StringFlagResolutionApi,
|
||||
} from '@openfeature/provider-rest-client';
|
||||
import axios from 'axios';
|
||||
|
||||
export class FlagdRESTProvider implements Provider {
|
||||
metadata = {
|
||||
name: 'Flagd REST',
|
||||
};
|
||||
|
||||
private readonly booleanFlagResolutionApi: BooleanFlagResolutionApi;
|
||||
private readonly stringFlagResolutionApi: StringFlagResolutionApi;
|
||||
private readonly numberFlagResolutionApi: NumericFlagResolutionApi;
|
||||
private readonly objectFlagResolutionApi: ObjectFlagResolutionApi;
|
||||
|
||||
constructor() {
|
||||
this.booleanFlagResolutionApi = new BooleanFlagResolutionApi();
|
||||
this.stringFlagResolutionApi = new StringFlagResolutionApi();
|
||||
this.numberFlagResolutionApi = new NumericFlagResolutionApi();
|
||||
this.objectFlagResolutionApi = new ObjectFlagResolutionApi();
|
||||
}
|
||||
|
||||
async resolveBooleanEvaluation(
|
||||
flagKey: string,
|
||||
defaultValue: boolean,
|
||||
transformedContext: EvaluationContext
|
||||
): Promise<ResolutionDetails<boolean>> {
|
||||
return this.booleanFlagResolutionApi
|
||||
.resolveBoolean(flagKey, defaultValue, transformedContext)
|
||||
.then((res) => res.data)
|
||||
.catch(this.errorMapper);
|
||||
}
|
||||
|
||||
async resolveStringEvaluation(
|
||||
flagKey: string,
|
||||
defaultValue: string,
|
||||
transformedContext: EvaluationContext
|
||||
): Promise<ResolutionDetails<string>> {
|
||||
return this.stringFlagResolutionApi
|
||||
.resolveString(flagKey, defaultValue, transformedContext)
|
||||
.then((res) => res.data)
|
||||
.catch(this.errorMapper);
|
||||
}
|
||||
|
||||
async resolveNumberEvaluation(
|
||||
flagKey: string,
|
||||
defaultValue: number,
|
||||
transformedContext: EvaluationContext
|
||||
): Promise<ResolutionDetails<number>> {
|
||||
return this.numberFlagResolutionApi
|
||||
.resolveNumber(flagKey, defaultValue, transformedContext)
|
||||
.then((res) => res.data)
|
||||
.catch(this.errorMapper);
|
||||
}
|
||||
|
||||
async resolveObjectEvaluation<U extends object>(
|
||||
flagKey: string,
|
||||
defaultValue: U,
|
||||
transformedContext: EvaluationContext
|
||||
): Promise<ResolutionDetails<U>> {
|
||||
return (
|
||||
this.objectFlagResolutionApi
|
||||
.resolveObject(flagKey, defaultValue, transformedContext)
|
||||
// TODO correct types
|
||||
.then((res) => res.data as any)
|
||||
.catch(this.errorMapper)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map known error codes to OpenFeature errors.
|
||||
*/
|
||||
private errorMapper(err: unknown): never {
|
||||
if (axios.isAxiosError(err)) {
|
||||
const errorCode = err.response?.data?.errorCode ?? 'UNKNOWN';
|
||||
|
||||
switch (errorCode) {
|
||||
case ErrorCode.TYPE_MISMATCH:
|
||||
throw new TypeMismatchError();
|
||||
case ErrorCode.PARSE_ERROR:
|
||||
throw new ParseError();
|
||||
case ErrorCode.FLAG_NOT_FOUND:
|
||||
throw new FlagNotFoundError();
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "ES6",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": []
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "node-sdk-contrib",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"generate-hook": "nx workspace-generator open-feature hook",
|
||||
"generate-provider": "nx workspace-generator open-feature provider",
|
||||
|
@ -9,7 +9,8 @@
|
|||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@openfeature/nodejs-sdk": "0.0.1-alpha.10",
|
||||
"@openfeature/nodejs-sdk": "^0.0.1-alpha.16",
|
||||
"@openfeature/provider-rest-client": "^0.0.1",
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
|
@ -23,16 +24,22 @@
|
|||
"@nrwl/nx-cloud": "latest",
|
||||
"@nrwl/web": "^14.2.4",
|
||||
"@nrwl/workspace": "14.2.1",
|
||||
"@semantic-release/changelog": "^6.0.1",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/npm": "^9.0.1",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/node": "16.11.7",
|
||||
"@typescript-eslint/eslint-plugin": "~5.24.0",
|
||||
"@typescript-eslint/parser": "~5.24.0",
|
||||
"axios": "^0.26.1",
|
||||
"babel-preset-minify": "^0.5.2",
|
||||
"eslint": "~8.15.0",
|
||||
"eslint-config-prettier": "8.1.0",
|
||||
"jest": "27.5.1",
|
||||
"nock": "^13.2.6",
|
||||
"nx": "14.2.1",
|
||||
"prettier": "^2.6.2",
|
||||
"semantic-release": "^19.0.3",
|
||||
"ts-jest": "27.1.4",
|
||||
"ts-node": "~10.8.0",
|
||||
"typescript": "~4.7.2"
|
||||
|
|
|
@ -10,8 +10,8 @@ $ npm install <%= importPath %>
|
|||
|
||||
## Building
|
||||
|
||||
Run `nx package <%= nxProjectName %>` to build the library.
|
||||
Run `npx nx package <%= nxProjectName %>` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test <%= nxProjectName %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
Run `npx nx test <%= nxProjectName %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
|
|
|
@ -10,8 +10,8 @@ $ npm install <%= importPath %>
|
|||
|
||||
## Building
|
||||
|
||||
Run `nx package <%= nxProjectName %>` to build the library.
|
||||
Run `npx nx package <%= nxProjectName %>` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test <%= nxProjectName %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
Run `npx nx test <%= nxProjectName %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
cons = '<%= libFileName %>';
|
||||
const srcRoot = '<%= projectRoot %>';
|
||||
|
||||
module.exports = {
|
||||
pkgRoot: `dist/${srcRoot}`,
|
||||
tagFormat: name + '-v${version}',
|
||||
commitPaths: [`${srcRoot}/*`],
|
||||
plugins: [
|
||||
'@semantic-release/commit-analyzer',
|
||||
'@semantic-release/release-notes-generator',
|
||||
[
|
||||
'@semantic-release/changelog',
|
||||
{
|
||||
changelogFile: `${srcRoot}/CHANGELOG.md`,
|
||||
},
|
||||
],
|
||||
'@semantic-release/npm',
|
||||
[
|
||||
'@semantic-release/git',
|
||||
{
|
||||
assets: [`${srcRoot}/package.json`, `${srcRoot}/CHANGELOG.md`],
|
||||
message:
|
||||
`release(version): Release ${name} ` +
|
||||
'${nextRelease.version} [skip ci]\n\n${nextRelease.notes}',
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
|
@ -70,12 +70,14 @@ export default async function (tree: Tree, schema: SchemaOptions) {
|
|||
libClassName,
|
||||
importPath,
|
||||
nxProjectName,
|
||||
projectRoot,
|
||||
tmpl: '',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
updateProject(tree, projectRoot, name);
|
||||
updatePackageJson(tree, projectRoot);
|
||||
updateTsConfig(tree, projectRoot);
|
||||
await formatFiles(tree);
|
||||
|
||||
|
@ -143,6 +145,21 @@ function updateProject(tree: Tree, projectRoot: string, umdName: string) {
|
|||
},
|
||||
};
|
||||
|
||||
json.targets['release'] = {
|
||||
executor: 'nx:run-commands',
|
||||
outputs: [],
|
||||
options: {
|
||||
command: `npx semantic-release --extends ./${projectRoot}/release.config.js`,
|
||||
parallel: false,
|
||||
},
|
||||
dependsOn: [
|
||||
{
|
||||
projects: 'self',
|
||||
target: 'package',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
json.targets.publish.dependsOn[0].target = 'package';
|
||||
delete json.targets.build;
|
||||
|
||||
|
@ -150,6 +167,24 @@ function updateProject(tree: Tree, projectRoot: string, umdName: string) {
|
|||
});
|
||||
}
|
||||
|
||||
function updatePackageJson(tree: Tree, projectRoot: string) {
|
||||
updateJson(tree, joinPathFragments(projectRoot, 'package.json'), (json) => {
|
||||
json.repository = {
|
||||
type: 'git',
|
||||
url: 'https://github.com/open-feature/node-sdk-contrib.git',
|
||||
directory: projectRoot,
|
||||
};
|
||||
|
||||
json.publishConfig = {
|
||||
access: 'public',
|
||||
};
|
||||
|
||||
json.license = 'Apache-2.0';
|
||||
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
function updateTsConfig(tree: Tree, projectRoot: string) {
|
||||
updateJson(tree, joinPathFragments(projectRoot, 'tsconfig.json'), (json) => {
|
||||
json.compilerOptions.module = 'ES6';
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
"skipDefaultLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@openfeature/flagd-rest-provider": [
|
||||
"libs/providers/flagd-rest/src/index.ts"
|
||||
],
|
||||
"@openfeature/hooks-open-telemetry": [
|
||||
"libs/hooks/open-telemetry/src/index.ts"
|
||||
]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"$schema": "./node_modules/nx/schemas/workspace-schema.json",
|
||||
"version": 2,
|
||||
"projects": {
|
||||
"hooks-open-telemetry": "libs/hooks/open-telemetry"
|
||||
"hooks-open-telemetry": "libs/hooks/open-telemetry",
|
||||
"providers-flagd-rest": "libs/providers/flagd-rest"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue