mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-06 01:15:28 +02:00
* Feat: return reasons why a feature evaluated to true or false
Note: this is very rough and just straight ripped from the nodejs
client. It will need a lot of work, but is a good place to start
* Feat: add suggested shape for new payload
* Chore: minor cleanup
* Wip: make server compile again
* Remove unused schema ref
* Export new schemas
* Chore: fix some tests to use sub property
* Fix: fix some tests
* Refactor: rename some variables, uncomment some stuff
* Add segments type to bootstrap options
* Add segments capability to offline feature evaluator
* Fix function calls after turning params into an option abject
* Feat: test strategy order, etc
* Feat: add test to check that all strats are returned correctly
* Feat: allow you to include strategy ids in clients
* Wip: hook up segments in the offline client.
Note: compared to regular clients, they still fail
* Feat: add segments validation
* Fix: fix test case invariant.
* Chore: revert to returning only `boolean` from strategies.
This _should_ make it work with custom strategies too 🤞
* Feat: make more properties of the returned feature required
* Wip: add some comments and unfinished tests for edge cases
* Feat: add `isEnabledInCurrentEnvironment` prop
* Feat: consider more strategy failure cases
* Feat: test that isenabledinenvironment matches expectations
* Feat: add unknown strategies
* Fix: fix property access typo
* Feat: add unknown strategy for fallback purposes
* Feat: test edge case: all unknown strategies
* Feat: add custom strategy to arbitrary
* Feat: test that features can be true, even if not enabled in env
* Chore: add some comments
* Wip: fix sdk tests
* Remove comments, improve test logging
* Feat: add descriptions and examples to playground feature schema
* Switch `examples` for `example`
* Update schemas with descriptions and examples
* Fix: update snapshot
* Fix: openapi example
* Fix: merge issues
* Fix: fix issue where feature evaluation state was wrong
* Chore: update openapi spec
* Fix: fix broken offline client tests
* Refactor: move schemas into separate files
* Refactor: remove "reason" for incomplete evaluation.
The only instances where evaluation is incomplete is when we don't
know what the strategy is.
* Refactor: move unleash node client into test and dev dependencies
* Wip: further removal of stuff
* Chore: remove a bunch of code that we don't use
* Chore: remove comment
* Chore: remove unused code
* Fix: fix some prettier errors
* Type parameters in strategies to avoid `any`
* Fix: remove commented out code
* Feat: make `id` required on playground strategies
* Chore: remove redundant type
* Fix: remove redundant if and fix fallback evaluation
* Refactor: reduce nesting and remove duplication
* Fix: remove unused helper function
* Refactor: type `parameters` as `unknown`
* Chore: remove redundant comment
* Refactor: move constraint code into a separate file
* Refactor: rename `unleash` -> `feature-evaluator`
* Rename class `Unleash` -> `FeatureEvaluator`
* Refactor: remove this.ready and sync logic from feature evaluator
* Refactor: remove unused code, rename config type
* Refactor: remove event emission from the Unleash client
* Remove unlistened-for events in feature evaluator
* Refactor: make offline client synchronous; remove code
* Fix: update openapi snapshot after adding required strategy ids
* Feat: change `strategies` format.
This commit changes the format of a playground feature's `strategies`
properties from a list of strategies to an object with properties
`result` and `data`. It looks a bit like this:
```ts
type Strategies = {
result: boolean | "unknown",
data: Strategy[]
}
```
The reason is that this allows us to avoid the breaking change that
was previously suggested in the PR:
`feature.isEnabled` used to be a straight boolean. Then, when we found
out we couldn't necessarily evaluate all strategies (custom strats are
hard!) we changed it to `boolean | 'unevaluated'`. However, this is
confusing on a few levels as the playground results are no longer the
same as the SDK would be, nor are they strictly boolean anymore.
This change reverts the `isEnabled` functionality to what it was
before (so it's always a mirror of what the SDK would show).
The equivalent of `feature.isEnabled === 'unevaluated'` now becomes
`feature.isEnabled && strategy.result === 'unknown'`.
* Fix: Fold long string descriptions over multiple lines.
* Fix: update snapshot after adding line breaks to descriptions
140 lines
5.6 KiB
TypeScript
140 lines
5.6 KiB
TypeScript
import { FromSchema } from 'json-schema-to-ts';
|
|
import { parametersSchema } from './parameters-schema';
|
|
import { variantSchema } from './variant-schema';
|
|
import { overrideSchema } from './override-schema';
|
|
import {
|
|
playgroundStrategyEvaluation,
|
|
playgroundStrategySchema,
|
|
} from './playground-strategy-schema';
|
|
import { playgroundConstraintSchema } from './playground-constraint-schema';
|
|
import { playgroundSegmentSchema } from './playground-segment-schema';
|
|
|
|
export const unknownFeatureEvaluationResult = 'unevaluated' as const;
|
|
|
|
export const playgroundFeatureSchema = {
|
|
$id: '#/components/schemas/playgroundFeatureSchema',
|
|
description:
|
|
'A simplified feature toggle model intended for the Unleash playground.',
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: [
|
|
'name',
|
|
'projectId',
|
|
'isEnabled',
|
|
'isEnabledInCurrentEnvironment',
|
|
'variant',
|
|
'variants',
|
|
'strategies',
|
|
],
|
|
properties: {
|
|
name: {
|
|
type: 'string',
|
|
example: 'my-feature',
|
|
description: "The feature's name.",
|
|
},
|
|
projectId: {
|
|
type: 'string',
|
|
example: 'my-project',
|
|
description: 'The ID of the project that contains this feature.',
|
|
},
|
|
strategies: {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['result', 'data'],
|
|
properties: {
|
|
result: {
|
|
description: `The cumulative results of all the feature's strategies. Can be \`true\`,
|
|
\`false\`, or \`${playgroundStrategyEvaluation.unknownResult}\`.
|
|
This property will only be \`${playgroundStrategyEvaluation.unknownResult}\`
|
|
if one or more of the strategies can't be fully evaluated and the rest of the strategies
|
|
all resolve to \`false\`.`,
|
|
anyOf: [
|
|
{ type: 'boolean' },
|
|
{
|
|
type: 'string',
|
|
enum: [playgroundStrategyEvaluation.unknownResult],
|
|
},
|
|
],
|
|
},
|
|
data: {
|
|
description: 'The strategies that apply to this feature.',
|
|
type: 'array',
|
|
items: {
|
|
$ref: playgroundStrategySchema.$id,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
isEnabledInCurrentEnvironment: {
|
|
type: 'boolean',
|
|
description:
|
|
'Whether the feature is active and would be evaluated in the provided environment in a normal SDK context.',
|
|
},
|
|
isEnabled: {
|
|
description: `Whether this feature is enabled or not in the current environment.
|
|
If a feature can't be fully evaluated (that is, \`strategies.result\` is \`${playgroundStrategyEvaluation.unknownResult}\`),
|
|
this will be \`false\` to align with how client SDKs treat unresolved feature states.`,
|
|
type: 'boolean',
|
|
example: true,
|
|
},
|
|
variant: {
|
|
description: `The feature variant you receive based on the provided context or the _disabled
|
|
variant_. If a feature is disabled or doesn't have any
|
|
variants, you would get the _disabled variant_.
|
|
Otherwise, you'll get one of thefeature's defined variants.`,
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['name', 'enabled'],
|
|
properties: {
|
|
name: {
|
|
type: 'string',
|
|
description:
|
|
"The variant's name. If there is no variant or if the toggle is disabled, this will be `disabled`",
|
|
example: 'red-variant',
|
|
},
|
|
enabled: {
|
|
type: 'boolean',
|
|
description:
|
|
"Whether the variant is enabled or not. If the feature is disabled or if it doesn't have variants, this property will be `false`",
|
|
},
|
|
payload: {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['type', 'value'],
|
|
description: 'An optional payload attached to the variant.',
|
|
properties: {
|
|
type: {
|
|
description: 'The format of the payload.',
|
|
type: 'string',
|
|
enum: ['json', 'csv', 'string'],
|
|
},
|
|
value: {
|
|
type: 'string',
|
|
description: 'The payload value stringified.',
|
|
example: '{"property": "value"}',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nullable: true,
|
|
example: { name: 'green', enabled: true },
|
|
},
|
|
variants: { type: 'array', items: { $ref: variantSchema.$id } },
|
|
},
|
|
components: {
|
|
schemas: {
|
|
playgroundStrategySchema,
|
|
playgroundConstraintSchema,
|
|
playgroundSegmentSchema,
|
|
parametersSchema,
|
|
variantSchema,
|
|
overrideSchema,
|
|
},
|
|
variants: { type: 'array', items: { $ref: variantSchema.$id } },
|
|
},
|
|
} as const;
|
|
|
|
export type PlaygroundFeatureSchema = FromSchema<
|
|
typeof playgroundFeatureSchema
|
|
>;
|