From ce87806a8029f9a08b058e2a365a5bdb20691233 Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Thu, 13 Jul 2023 13:50:03 +0200 Subject: [PATCH] feat: strategy variant schema openapi (#4232) --- src/lib/openapi/index.ts | 4 ++ src/lib/openapi/spec/client-feature-schema.ts | 2 + .../openapi/spec/client-features-schema.ts | 2 + .../spec/create-feature-strategy-schema.ts | 9 +++ .../spec/create-strategy-variant-schema.ts | 59 +++++++++++++++++++ .../spec/environment-project-schema.ts | 2 + src/lib/openapi/spec/export-result-schema.ts | 2 + .../spec/feature-environment-schema.ts | 2 + src/lib/openapi/spec/feature-schema.ts | 2 + .../openapi/spec/feature-strategy-schema.ts | 9 +++ src/lib/openapi/spec/features-schema.ts | 2 + .../openapi/spec/health-overview-schema.ts | 4 ++ src/lib/openapi/spec/import-toggles-schema.ts | 2 + src/lib/openapi/spec/index.ts | 2 + .../spec/project-environment-schema.ts | 2 + .../openapi/spec/project-overview-schema.ts | 4 ++ src/lib/openapi/spec/state-schema.ts | 2 + .../openapi/spec/strategy-variant-schema.ts | 17 ++++++ src/lib/openapi/spec/variant-schema.ts | 3 + 19 files changed, 131 insertions(+) create mode 100644 src/lib/openapi/spec/create-strategy-variant-schema.ts create mode 100644 src/lib/openapi/spec/strategy-variant-schema.ts diff --git a/src/lib/openapi/index.ts b/src/lib/openapi/index.ts index 0094a677b0..dea596dd27 100644 --- a/src/lib/openapi/index.ts +++ b/src/lib/openapi/index.ts @@ -148,6 +148,8 @@ import { versionSchema, advancedPlaygroundFeatureSchema, telemetrySettingsSchema, + strategyVariantSchema, + createStrategyVariantSchema, } from './spec'; import { IServerOption } from '../types'; import { mapValues, omitKeys } from '../util'; @@ -353,6 +355,8 @@ export const schemas: UnleashSchemas = { importTogglesValidateItemSchema, contextFieldStrategiesSchema, telemetrySettingsSchema, + strategyVariantSchema, + createStrategyVariantSchema, }; // Remove JSONSchema keys that would result in an invalid OpenAPI spec. diff --git a/src/lib/openapi/spec/client-feature-schema.ts b/src/lib/openapi/spec/client-feature-schema.ts index 116ae6a19b..106586c35c 100644 --- a/src/lib/openapi/spec/client-feature-schema.ts +++ b/src/lib/openapi/spec/client-feature-schema.ts @@ -4,6 +4,7 @@ import { parametersSchema } from './parameters-schema'; import { featureStrategySchema } from './feature-strategy-schema'; import { variantSchema } from './variant-schema'; import { overrideSchema } from './override-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const clientFeatureSchema = { $id: '#/components/schemas/clientFeatureSchema', @@ -78,6 +79,7 @@ export const clientFeatureSchema = { constraintSchema, parametersSchema, featureStrategySchema, + strategyVariantSchema, variantSchema, overrideSchema, }, diff --git a/src/lib/openapi/spec/client-features-schema.ts b/src/lib/openapi/spec/client-features-schema.ts index 4f4e3e4e17..44a795d73c 100644 --- a/src/lib/openapi/spec/client-features-schema.ts +++ b/src/lib/openapi/spec/client-features-schema.ts @@ -8,6 +8,7 @@ import { parametersSchema } from './parameters-schema'; import { featureStrategySchema } from './feature-strategy-schema'; import { clientFeatureSchema } from './client-feature-schema'; import { variantSchema } from './variant-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const clientFeaturesSchema = { $id: '#/components/schemas/clientFeaturesSchema', @@ -54,6 +55,7 @@ export const clientFeaturesSchema = { overrideSchema, parametersSchema, featureStrategySchema, + strategyVariantSchema, variantSchema, }, }, diff --git a/src/lib/openapi/spec/create-feature-strategy-schema.ts b/src/lib/openapi/spec/create-feature-strategy-schema.ts index cd319f5583..04b250bfd0 100644 --- a/src/lib/openapi/spec/create-feature-strategy-schema.ts +++ b/src/lib/openapi/spec/create-feature-strategy-schema.ts @@ -1,6 +1,7 @@ import { FromSchema } from 'json-schema-to-ts'; import { parametersSchema } from './parameters-schema'; import { constraintSchema } from './constraint-schema'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; export const createFeatureStrategySchema = { $id: '#/components/schemas/createFeatureStrategySchema', @@ -48,6 +49,13 @@ export const createFeatureStrategySchema = { $ref: '#/components/schemas/constraintSchema', }, }, + variants: { + type: 'array', + description: 'Strategy level variants', + items: { + $ref: '#/components/schemas/createStrategyVariantSchema', + }, + }, parameters: { description: 'An object containing the parameters for the strategy', example: { @@ -70,6 +78,7 @@ export const createFeatureStrategySchema = { schemas: { constraintSchema, parametersSchema, + createStrategyVariantSchema, }, }, } as const; diff --git a/src/lib/openapi/spec/create-strategy-variant-schema.ts b/src/lib/openapi/spec/create-strategy-variant-schema.ts new file mode 100644 index 0000000000..17e7318310 --- /dev/null +++ b/src/lib/openapi/spec/create-strategy-variant-schema.ts @@ -0,0 +1,59 @@ +import { FromSchema } from 'json-schema-to-ts'; + +export const createStrategyVariantSchema = { + $id: '#/components/schemas/createStrategyVariantSchema', + type: 'object', + additionalProperties: true, + description: + "This is an experimental property. It may change or be removed as we work on it. Please don't depend on it yet. A strategy variant allows you to attach any data to strategies instead of only returning `true`/`false`. Strategy variants take precedence over feature variants.", + required: ['name', 'weight', 'weightType', 'stickiness'], + properties: { + name: { + type: 'string', + description: + 'The variant name. Must be unique for this feature toggle', + example: 'blue_group', + }, + weight: { + type: 'integer', + description: + 'The weight is the likelihood of any one user getting this variant. It is an integer between 0 and 1000. See the section on [variant weights](https://docs.getunleash.io/reference/feature-toggle-variants#variant-weight) for more information', + minimum: 0, + maximum: 1000, + }, + weightType: { + description: + 'Set to `fix` if this variant must have exactly the weight allocated to it. If the type is `variable`, the weight will adjust so that the total weight of all variants adds up to 1000. Refer to the [variant weight documentation](https://docs.getunleash.io/reference/feature-toggle-variants#variant-weight).', + type: 'string', + example: 'fix', + }, + stickiness: { + type: 'string', + description: + 'The [stickiness](https://docs.getunleash.io/reference/feature-toggle-variants#variant-stickiness) to use for distribution of this variant. Stickiness is how Unleash guarantees that the same user gets the same variant every time', + example: 'custom.context.field', + }, + payload: { + type: 'object', + required: ['type', 'value'], + description: 'Extra data configured for this variant', + properties: { + type: { + description: + 'The type of the value. Commonly used types are string, json and csv.', + type: 'string', + }, + value: { + description: 'The actual value of payload', + type: 'string', + }, + }, + example: { type: 'json', value: '{color: red}' }, + }, + }, + components: {}, +} as const; + +export type CreateStrategyVariantSchema = FromSchema< + typeof createStrategyVariantSchema +>; diff --git a/src/lib/openapi/spec/environment-project-schema.ts b/src/lib/openapi/spec/environment-project-schema.ts index c8ba9a495c..0620cd697d 100644 --- a/src/lib/openapi/spec/environment-project-schema.ts +++ b/src/lib/openapi/spec/environment-project-schema.ts @@ -1,5 +1,6 @@ import { FromSchema } from 'json-schema-to-ts'; import { createFeatureStrategySchema } from './create-feature-strategy-schema'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; export const environmentProjectSchema = { $id: '#/components/schemas/environmentProjectSchema', @@ -60,6 +61,7 @@ export const environmentProjectSchema = { components: { schemas: { createFeatureStrategySchema, + createStrategyVariantSchema, }, }, } as const; diff --git a/src/lib/openapi/spec/export-result-schema.ts b/src/lib/openapi/spec/export-result-schema.ts index 4e325215bd..9404c638c7 100644 --- a/src/lib/openapi/spec/export-result-schema.ts +++ b/src/lib/openapi/spec/export-result-schema.ts @@ -11,6 +11,7 @@ import { overrideSchema } from './override-schema'; import { variantsSchema } from './variants-schema'; import { constraintSchema } from './constraint-schema'; import { tagTypeSchema } from './tag-type-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const exportResultSchema = { $id: '#/components/schemas/exportResultSchema', @@ -170,6 +171,7 @@ export const exportResultSchema = { schemas: { featureSchema, featureStrategySchema, + strategyVariantSchema, featureEnvironmentSchema, contextFieldSchema, featureTagSchema, diff --git a/src/lib/openapi/spec/feature-environment-schema.ts b/src/lib/openapi/spec/feature-environment-schema.ts index c3cb2558e1..c80c9c5d7a 100644 --- a/src/lib/openapi/spec/feature-environment-schema.ts +++ b/src/lib/openapi/spec/feature-environment-schema.ts @@ -3,6 +3,7 @@ import { constraintSchema } from './constraint-schema'; import { parametersSchema } from './parameters-schema'; import { featureStrategySchema } from './feature-strategy-schema'; import { variantSchema } from './variant-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const featureEnvironmentSchema = { $id: '#/components/schemas/featureEnvironmentSchema', @@ -65,6 +66,7 @@ export const featureEnvironmentSchema = { constraintSchema, parametersSchema, featureStrategySchema, + strategyVariantSchema, variantSchema, }, }, diff --git a/src/lib/openapi/spec/feature-schema.ts b/src/lib/openapi/spec/feature-schema.ts index 659755823c..2e51676988 100644 --- a/src/lib/openapi/spec/feature-schema.ts +++ b/src/lib/openapi/spec/feature-schema.ts @@ -6,6 +6,7 @@ import { parametersSchema } from './parameters-schema'; import { featureStrategySchema } from './feature-strategy-schema'; import { tagSchema } from './tag-schema'; import { featureEnvironmentSchema } from './feature-environment-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const featureSchema = { $id: '#/components/schemas/featureSchema', @@ -125,6 +126,7 @@ export const featureSchema = { constraintSchema, featureEnvironmentSchema, featureStrategySchema, + strategyVariantSchema, overrideSchema, parametersSchema, variantSchema, diff --git a/src/lib/openapi/spec/feature-strategy-schema.ts b/src/lib/openapi/spec/feature-strategy-schema.ts index c20a1a441f..1f15763fac 100644 --- a/src/lib/openapi/spec/feature-strategy-schema.ts +++ b/src/lib/openapi/spec/feature-strategy-schema.ts @@ -1,6 +1,7 @@ import { FromSchema } from 'json-schema-to-ts'; import { constraintSchema } from './constraint-schema'; import { parametersSchema } from './parameters-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const featureStrategySchema = { $id: '#/components/schemas/featureStrategySchema', @@ -59,6 +60,13 @@ export const featureStrategySchema = { $ref: '#/components/schemas/constraintSchema', }, }, + variants: { + type: 'array', + description: 'Strategy level variants', + items: { + $ref: '#/components/schemas/strategyVariantSchema', + }, + }, parameters: { $ref: '#/components/schemas/parametersSchema', }, @@ -67,6 +75,7 @@ export const featureStrategySchema = { schemas: { constraintSchema, parametersSchema, + strategyVariantSchema, }, }, } as const; diff --git a/src/lib/openapi/spec/features-schema.ts b/src/lib/openapi/spec/features-schema.ts index 0a39777642..67416896e1 100644 --- a/src/lib/openapi/spec/features-schema.ts +++ b/src/lib/openapi/spec/features-schema.ts @@ -7,6 +7,7 @@ import { constraintSchema } from './constraint-schema'; import { featureStrategySchema } from './feature-strategy-schema'; import { environmentSchema } from './environment-schema'; import { featureEnvironmentSchema } from './feature-environment-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const featuresSchema = { $id: '#/components/schemas/featuresSchema', @@ -32,6 +33,7 @@ export const featuresSchema = { overrideSchema, featureEnvironmentSchema, featureStrategySchema, + strategyVariantSchema, parametersSchema, variantSchema, }, diff --git a/src/lib/openapi/spec/health-overview-schema.ts b/src/lib/openapi/spec/health-overview-schema.ts index a5734095a9..4c2a7dc79b 100644 --- a/src/lib/openapi/spec/health-overview-schema.ts +++ b/src/lib/openapi/spec/health-overview-schema.ts @@ -10,6 +10,8 @@ import { featureEnvironmentSchema } from './feature-environment-schema'; import { projectStatsSchema } from './project-stats-schema'; import { createFeatureStrategySchema } from './create-feature-strategy-schema'; import { projectEnvironmentSchema } from './project-environment-schema'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const healthOverviewSchema = { $id: '#/components/schemas/healthOverviewSchema', @@ -121,12 +123,14 @@ export const healthOverviewSchema = { environmentSchema, projectEnvironmentSchema, createFeatureStrategySchema, + createStrategyVariantSchema, constraintSchema, featureSchema, featureEnvironmentSchema, overrideSchema, parametersSchema, featureStrategySchema, + strategyVariantSchema, variantSchema, projectStatsSchema, }, diff --git a/src/lib/openapi/spec/import-toggles-schema.ts b/src/lib/openapi/spec/import-toggles-schema.ts index 3c82019b1d..fb56be4005 100644 --- a/src/lib/openapi/spec/import-toggles-schema.ts +++ b/src/lib/openapi/spec/import-toggles-schema.ts @@ -13,6 +13,7 @@ import { parametersSchema } from './parameters-schema'; import { legalValueSchema } from './legal-value-schema'; import { tagTypeSchema } from './tag-type-schema'; import { featureEnvironmentSchema } from './feature-environment-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const importTogglesSchema = { $id: '#/components/schemas/importTogglesSchema', @@ -43,6 +44,7 @@ export const importTogglesSchema = { exportResultSchema, featureSchema, featureStrategySchema, + strategyVariantSchema, featureEnvironmentSchema, contextFieldSchema, featureTagSchema, diff --git a/src/lib/openapi/spec/index.ts b/src/lib/openapi/spec/index.ts index 35f8f64c58..2f271284ce 100644 --- a/src/lib/openapi/spec/index.ts +++ b/src/lib/openapi/spec/index.ts @@ -147,3 +147,5 @@ export * from './advanced-playground-feature-schema'; export * from './advanced-playground-response-schema'; export * from './advanced-playground-request-schema'; export * from './telemetry-settings-schema'; +export * from './create-strategy-variant-schema'; +export * from './strategy-variant-schema'; diff --git a/src/lib/openapi/spec/project-environment-schema.ts b/src/lib/openapi/spec/project-environment-schema.ts index b78915eeda..e306a8a3cc 100644 --- a/src/lib/openapi/spec/project-environment-schema.ts +++ b/src/lib/openapi/spec/project-environment-schema.ts @@ -1,5 +1,6 @@ import { FromSchema } from 'json-schema-to-ts'; import { createFeatureStrategySchema } from './create-feature-strategy-schema'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; export const projectEnvironmentSchema = { $id: '#/components/schemas/projectEnvironmentSchema', @@ -29,6 +30,7 @@ export const projectEnvironmentSchema = { components: { schemas: { createFeatureStrategySchema, + createStrategyVariantSchema, }, }, } as const; diff --git a/src/lib/openapi/spec/project-overview-schema.ts b/src/lib/openapi/spec/project-overview-schema.ts index 6cb3b4b156..52f83f5af0 100644 --- a/src/lib/openapi/spec/project-overview-schema.ts +++ b/src/lib/openapi/spec/project-overview-schema.ts @@ -10,6 +10,8 @@ import { featureEnvironmentSchema } from './feature-environment-schema'; import { projectStatsSchema } from './project-stats-schema'; import { createFeatureStrategySchema } from './create-feature-strategy-schema'; import { projectEnvironmentSchema } from './project-environment-schema'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const projectOverviewSchema = { $id: '#/components/schemas/projectOverviewSchema', @@ -123,12 +125,14 @@ export const projectOverviewSchema = { environmentSchema, projectEnvironmentSchema, createFeatureStrategySchema, + createStrategyVariantSchema, constraintSchema, featureSchema, featureEnvironmentSchema, overrideSchema, parametersSchema, featureStrategySchema, + strategyVariantSchema, variantSchema, projectStatsSchema, }, diff --git a/src/lib/openapi/spec/state-schema.ts b/src/lib/openapi/spec/state-schema.ts index 55d81df2ca..63e3b5af00 100644 --- a/src/lib/openapi/spec/state-schema.ts +++ b/src/lib/openapi/spec/state-schema.ts @@ -10,6 +10,7 @@ import { environmentSchema } from './environment-schema'; import { segmentSchema } from './segment-schema'; import { featureStrategySegmentSchema } from './feature-strategy-segment-schema'; import { strategySchema } from './strategy-schema'; +import { strategyVariantSchema } from './strategy-variant-schema'; export const stateSchema = { $id: '#/components/schemas/stateSchema', @@ -98,6 +99,7 @@ export const stateSchema = { featureTagSchema, projectSchema, featureStrategySchema, + strategyVariantSchema, featureEnvironmentSchema, environmentSchema, segmentSchema, diff --git a/src/lib/openapi/spec/strategy-variant-schema.ts b/src/lib/openapi/spec/strategy-variant-schema.ts new file mode 100644 index 0000000000..5cd6c27c80 --- /dev/null +++ b/src/lib/openapi/spec/strategy-variant-schema.ts @@ -0,0 +1,17 @@ +import { FromSchema } from 'json-schema-to-ts'; +import { createStrategyVariantSchema } from './create-strategy-variant-schema'; + +export const strategyVariantSchema = { + $id: '#/components/schemas/strategyVariantSchema', + type: 'object', + additionalProperties: false, + description: + "This is an experimental property. It may change or be removed as we work on it. Please don't depend on it yet. A strategy variant allows you to attach any data to strategies instead of only returning `true`/`false`. Strategy variants take precedence over feature variants.", + required: ['name', 'weight', 'weightType', 'stickiness'], + properties: { + ...createStrategyVariantSchema.properties, + }, + components: {}, +} as const; + +export type StrategyVariantSchema = FromSchema; diff --git a/src/lib/openapi/spec/variant-schema.ts b/src/lib/openapi/spec/variant-schema.ts index 6b91be0300..8052d82177 100644 --- a/src/lib/openapi/spec/variant-schema.ts +++ b/src/lib/openapi/spec/variant-schema.ts @@ -39,9 +39,12 @@ export const variantSchema = { description: 'Extra data configured for this variant', properties: { type: { + description: + 'The type of the value. Commonly used types are string, json and csv.', type: 'string', }, value: { + description: 'The actual value of payload', type: 'string', }, },