@showwhat/openfeature 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # @showwhat/openfeature
2
2
 
3
- [OpenFeature](https://openfeature.dev/) provider for **showwhat** - use showwhat's rule engine through the standard OpenFeature Server SDK.
3
+ [OpenFeature](https://openfeature.dev/) provider for **showwhat**.
4
+
5
+ Bridge showwhat's rule engine to the standard OpenFeature Server SDK. Evaluate flags and config through OpenFeature clients using showwhat definitions.
4
6
 
5
7
  ## Installation
6
8
 
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { Provider, EvaluationContext, ResolutionDetails, JsonValue } from '@openfeature/server-sdk';
2
- import { DefinitionReader, ConditionEvaluators, Logger, Context } from 'showwhat';
2
+ import { ShowWhatOptions, DefinitionReader, Dependencies, Logger, Context } from 'showwhat';
3
3
 
4
- type ShowwhatProviderOptions = {
4
+ type ShowwhatProviderOptions = Omit<ShowWhatOptions, "data"> & {
5
5
  data: DefinitionReader;
6
- evaluators?: ConditionEvaluators;
7
- logger?: Logger;
6
+ deps?: Dependencies;
8
7
  };
9
8
  declare class ShowwhatProvider implements Provider {
10
9
  #private;
package/dist/index.js CHANGED
@@ -83,22 +83,18 @@ function mapShowwhatError(error) {
83
83
  var ShowwhatProvider = class {
84
84
  metadata = { name: "showwhat" };
85
85
  runsOn = "server";
86
- #data;
87
- #evaluators;
88
- #logger;
86
+ #options;
89
87
  constructor(options) {
90
- this.#data = options.data;
91
- this.#evaluators = options.evaluators;
92
- this.#logger = options.logger;
88
+ this.#options = options;
93
89
  }
94
90
  async initialize() {
95
- if (this.#data.load) {
96
- await this.#data.load();
91
+ if (this.#options.data.load) {
92
+ await this.#options.data.load();
97
93
  }
98
94
  }
99
95
  async onClose() {
100
- if (this.#data.close) {
101
- await this.#data.close();
96
+ if (this.#options.data.close) {
97
+ await this.#options.data.close();
102
98
  }
103
99
  }
104
100
  async resolveBooleanEvaluation(flagKey, defaultValue, context) {
@@ -124,18 +120,25 @@ var ShowwhatProvider = class {
124
120
  );
125
121
  }
126
122
  async #resolve(flagKey, defaultValue, evalCtx, typeGuard) {
127
- const ctx = toShowwhatContext(evalCtx, this.#logger);
123
+ const ctx = toShowwhatContext(evalCtx, this.#options.logger);
128
124
  try {
129
- const resolution = await showwhat({
130
- key: flagKey,
125
+ const results = await showwhat({
126
+ keys: [flagKey],
131
127
  context: ctx,
132
- options: {
133
- data: this.#data,
134
- evaluators: this.#evaluators,
135
- logger: this.#logger
136
- }
128
+ deps: this.#options.deps,
129
+ options: this.#options
137
130
  });
138
- const value = resolution.value;
131
+ const entry = results[flagKey];
132
+ if (!entry.success) {
133
+ const mapped = mapShowwhatError(entry.error);
134
+ return {
135
+ value: defaultValue,
136
+ reason: StandardResolutionReasons.ERROR,
137
+ errorCode: mapped.errorCode,
138
+ errorMessage: mapped.errorMessage
139
+ };
140
+ }
141
+ const value = entry.value;
139
142
  if (!typeGuard(value)) {
140
143
  return {
141
144
  value: defaultValue,
@@ -144,10 +147,10 @@ var ShowwhatProvider = class {
144
147
  errorMessage: `Flag "${flagKey}" resolved to ${typeof value}, expected a compatible type`
145
148
  };
146
149
  }
147
- const hasConditions = resolution.meta.variation.conditionCount > 0;
150
+ const hasConditions = entry.meta.variation.conditionCount > 0;
148
151
  return {
149
152
  value,
150
- variant: resolution.meta.variation.id ?? String(resolution.meta.variation.index),
153
+ variant: entry.meta.variation.id ?? String(entry.meta.variation.index),
151
154
  reason: hasConditions ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC
152
155
  };
153
156
  } catch (error) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.ts","../src/context.ts","../src/errors.ts"],"sourcesContent":["import type {\n EvaluationContext,\n JsonValue,\n Provider,\n ResolutionDetails,\n} from \"@openfeature/server-sdk\";\nimport { ErrorCode, StandardResolutionReasons } from \"@openfeature/server-sdk\";\nimport type { ConditionEvaluators, DefinitionReader, Logger } from \"showwhat\";\nimport { showwhat } from \"showwhat\";\nimport { toShowwhatContext } from \"./context.js\";\nimport { mapShowwhatError } from \"./errors.js\";\n\nexport type ShowwhatProviderOptions = {\n data: DefinitionReader;\n evaluators?: ConditionEvaluators;\n logger?: Logger;\n};\n\nexport class ShowwhatProvider implements Provider {\n readonly metadata = { name: \"showwhat\" } as const;\n readonly runsOn = \"server\" as const;\n\n #data: DefinitionReader;\n #evaluators: ConditionEvaluators | undefined;\n #logger: Logger | undefined;\n\n constructor(options: ShowwhatProviderOptions) {\n this.#data = options.data;\n this.#evaluators = options.evaluators;\n this.#logger = options.logger;\n }\n\n async initialize(): Promise<void> {\n if (this.#data.load) {\n await this.#data.load();\n }\n }\n\n async onClose(): Promise<void> {\n if (this.#data.close) {\n await this.#data.close();\n }\n }\n\n async resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<boolean>> {\n return this.#resolve(\n flagKey,\n defaultValue,\n context,\n (v): v is boolean => typeof v === \"boolean\",\n );\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<string>> {\n return this.#resolve(flagKey, defaultValue, context, (v): v is string => typeof v === \"string\");\n }\n\n async resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<number>> {\n return this.#resolve(flagKey, defaultValue, context, (v): v is number => typeof v === \"number\");\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<T>> {\n return this.#resolve(\n flagKey,\n defaultValue,\n context,\n isJsonValue as (value: unknown) => value is T,\n );\n }\n\n async #resolve<T>(\n flagKey: string,\n defaultValue: T,\n evalCtx: EvaluationContext,\n typeGuard: (value: unknown) => value is T,\n ): Promise<ResolutionDetails<T>> {\n const ctx = toShowwhatContext(evalCtx, this.#logger);\n\n try {\n const resolution = await showwhat({\n key: flagKey,\n context: ctx,\n options: {\n data: this.#data,\n evaluators: this.#evaluators,\n logger: this.#logger,\n },\n });\n\n const value = resolution.value;\n\n if (!typeGuard(value)) {\n return {\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n errorCode: ErrorCode.TYPE_MISMATCH,\n errorMessage: `Flag \"${flagKey}\" resolved to ${typeof value}, expected a compatible type`,\n };\n }\n\n const hasConditions = resolution.meta.variation.conditionCount > 0;\n\n return {\n value,\n variant: resolution.meta.variation.id ?? String(resolution.meta.variation.index),\n reason: hasConditions\n ? StandardResolutionReasons.TARGETING_MATCH\n : StandardResolutionReasons.STATIC,\n };\n } catch (error: unknown) {\n const mapped = mapShowwhatError(error);\n return {\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n errorCode: mapped.errorCode,\n errorMessage: mapped.errorMessage,\n };\n }\n }\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n if (value === null) return true;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\")\n return true;\n if (Array.isArray(value)) return value.every(isJsonValue);\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n return false;\n}\n","import type { EvaluationContext, EvaluationContextValue } from \"@openfeature/server-sdk\";\nimport type { Context, ContextValue, Logger } from \"showwhat\";\nimport { noopLogger } from \"showwhat\";\n\n/**\n * Converts an OpenFeature EvaluationContextValue to a showwhat ContextValue.\n *\n * Primitives, primitive arrays, and nested objects of primitives are preserved.\n * Date and null values are not representable in JSON/YAML and are dropped.\n */\nfunction convertValue(value: EvaluationContextValue): ContextValue | undefined {\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n const result: (string | number | boolean)[] = [];\n for (const item of value) {\n if (typeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\") {\n result.push(item);\n } else {\n return undefined;\n }\n }\n return result;\n }\n\n if (value !== null && typeof value === \"object\" && !(value instanceof Date)) {\n const result: Record<string, ContextValue> = {};\n for (const [k, v] of Object.entries(value)) {\n const converted = convertValue(v);\n if (converted === undefined) {\n return undefined;\n }\n result[k] = converted;\n }\n return result;\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenFeature EvaluationContext into a showwhat Context.\n *\n * Primitives, primitive arrays, and nested objects of primitives are preserved.\n * Date and null values are dropped with a warning.\n */\nexport function toShowwhatContext(evalCtx: EvaluationContext, logger?: Logger): Context {\n const log = logger ?? noopLogger;\n const ctx: Context = {};\n\n for (const [key, value] of Object.entries(evalCtx)) {\n const converted = convertValue(value);\n if (converted !== undefined) {\n ctx[key] = converted;\n } else {\n log.warn(\"dropped unsupported context key\", { key });\n }\n }\n\n return ctx;\n}\n","import { ErrorCode } from \"@openfeature/server-sdk\";\nimport {\n DefinitionNotFoundError,\n DefinitionInactiveError,\n VariationNotFoundError,\n ValidationError,\n DataError,\n ShowwhatError,\n} from \"showwhat\";\n\ntype ErrorMapping = {\n errorCode: ErrorCode;\n errorMessage: string;\n};\n\nexport function mapShowwhatError(error: unknown): ErrorMapping {\n if (error instanceof DefinitionNotFoundError) {\n return { errorCode: ErrorCode.FLAG_NOT_FOUND, errorMessage: error.message };\n }\n\n if (error instanceof DefinitionInactiveError) {\n return { errorCode: ErrorCode.FLAG_NOT_FOUND, errorMessage: error.message };\n }\n\n if (error instanceof VariationNotFoundError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n if (error instanceof ValidationError) {\n return { errorCode: ErrorCode.INVALID_CONTEXT, errorMessage: error.message };\n }\n\n if (error instanceof DataError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n if (error instanceof ShowwhatError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return { errorCode: ErrorCode.GENERAL, errorMessage: message };\n}\n"],"mappings":"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","names":["ErrorCode","ErrorCode"]}
1
+ {"version":3,"sources":["../src/provider.ts","../src/context.ts","../src/errors.ts"],"sourcesContent":["import type {\n EvaluationContext,\n JsonValue,\n Provider,\n ResolutionDetails,\n} from \"@openfeature/server-sdk\";\nimport { ErrorCode, StandardResolutionReasons } from \"@openfeature/server-sdk\";\nimport type { DefinitionReader, Dependencies, ShowWhatOptions } from \"showwhat\";\nimport { showwhat } from \"showwhat\";\nimport { toShowwhatContext } from \"./context.js\";\nimport { mapShowwhatError } from \"./errors.js\";\n\nexport type ShowwhatProviderOptions = Omit<ShowWhatOptions, \"data\"> & {\n data: DefinitionReader;\n deps?: Dependencies;\n};\n\nexport class ShowwhatProvider implements Provider {\n readonly metadata = { name: \"showwhat\" } as const;\n readonly runsOn = \"server\" as const;\n\n #options: ShowwhatProviderOptions;\n\n constructor(options: ShowwhatProviderOptions) {\n this.#options = options;\n }\n\n async initialize(): Promise<void> {\n if (this.#options.data.load) {\n await this.#options.data.load();\n }\n }\n\n async onClose(): Promise<void> {\n if (this.#options.data.close) {\n await this.#options.data.close();\n }\n }\n\n async resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<boolean>> {\n return this.#resolve(\n flagKey,\n defaultValue,\n context,\n (v): v is boolean => typeof v === \"boolean\",\n );\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<string>> {\n return this.#resolve(flagKey, defaultValue, context, (v): v is string => typeof v === \"string\");\n }\n\n async resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<number>> {\n return this.#resolve(flagKey, defaultValue, context, (v): v is number => typeof v === \"number\");\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n ): Promise<ResolutionDetails<T>> {\n return this.#resolve(\n flagKey,\n defaultValue,\n context,\n isJsonValue as (value: unknown) => value is T,\n );\n }\n\n async #resolve<T>(\n flagKey: string,\n defaultValue: T,\n evalCtx: EvaluationContext,\n typeGuard: (value: unknown) => value is T,\n ): Promise<ResolutionDetails<T>> {\n const ctx = toShowwhatContext(evalCtx, this.#options.logger);\n\n try {\n const results = await showwhat({\n keys: [flagKey],\n context: ctx,\n deps: this.#options.deps,\n options: this.#options,\n });\n\n const entry = results[flagKey];\n\n if (!entry.success) {\n const mapped = mapShowwhatError(entry.error);\n return {\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n errorCode: mapped.errorCode,\n errorMessage: mapped.errorMessage,\n };\n }\n\n const value = entry.value;\n\n if (!typeGuard(value)) {\n return {\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n errorCode: ErrorCode.TYPE_MISMATCH,\n errorMessage: `Flag \"${flagKey}\" resolved to ${typeof value}, expected a compatible type`,\n };\n }\n\n const hasConditions = entry.meta.variation.conditionCount > 0;\n\n return {\n value,\n variant: entry.meta.variation.id ?? String(entry.meta.variation.index),\n reason: hasConditions\n ? StandardResolutionReasons.TARGETING_MATCH\n : StandardResolutionReasons.STATIC,\n };\n } catch (error: unknown) {\n const mapped = mapShowwhatError(error);\n return {\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n errorCode: mapped.errorCode,\n errorMessage: mapped.errorMessage,\n };\n }\n }\n}\n\nfunction isJsonValue(value: unknown): value is JsonValue {\n if (value === null) return true;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\")\n return true;\n if (Array.isArray(value)) return value.every(isJsonValue);\n if (typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(isJsonValue);\n }\n return false;\n}\n","import type { EvaluationContext, EvaluationContextValue } from \"@openfeature/server-sdk\";\nimport type { Context, ContextValue, Logger } from \"showwhat\";\nimport { noopLogger } from \"showwhat\";\n\n/**\n * Converts an OpenFeature EvaluationContextValue to a showwhat ContextValue.\n *\n * Primitives, primitive arrays, and nested objects of primitives are preserved.\n * Date and null values are not representable in JSON/YAML and are dropped.\n */\nfunction convertValue(value: EvaluationContextValue): ContextValue | undefined {\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n const result: (string | number | boolean)[] = [];\n for (const item of value) {\n if (typeof item === \"string\" || typeof item === \"number\" || typeof item === \"boolean\") {\n result.push(item);\n } else {\n return undefined;\n }\n }\n return result;\n }\n\n if (value !== null && typeof value === \"object\" && !(value instanceof Date)) {\n const result: Record<string, ContextValue> = {};\n for (const [k, v] of Object.entries(value)) {\n const converted = convertValue(v);\n if (converted === undefined) {\n return undefined;\n }\n result[k] = converted;\n }\n return result;\n }\n\n return undefined;\n}\n\n/**\n * Converts an OpenFeature EvaluationContext into a showwhat Context.\n *\n * Primitives, primitive arrays, and nested objects of primitives are preserved.\n * Date and null values are dropped with a warning.\n */\nexport function toShowwhatContext(evalCtx: EvaluationContext, logger?: Logger): Context {\n const log = logger ?? noopLogger;\n const ctx: Context = {};\n\n for (const [key, value] of Object.entries(evalCtx)) {\n const converted = convertValue(value);\n if (converted !== undefined) {\n ctx[key] = converted;\n } else {\n log.warn(\"dropped unsupported context key\", { key });\n }\n }\n\n return ctx;\n}\n","import { ErrorCode } from \"@openfeature/server-sdk\";\nimport {\n DefinitionNotFoundError,\n DefinitionInactiveError,\n VariationNotFoundError,\n ValidationError,\n DataError,\n ShowwhatError,\n} from \"showwhat\";\n\ntype ErrorMapping = {\n errorCode: ErrorCode;\n errorMessage: string;\n};\n\nexport function mapShowwhatError(error: unknown): ErrorMapping {\n if (error instanceof DefinitionNotFoundError) {\n return { errorCode: ErrorCode.FLAG_NOT_FOUND, errorMessage: error.message };\n }\n\n if (error instanceof DefinitionInactiveError) {\n return { errorCode: ErrorCode.FLAG_NOT_FOUND, errorMessage: error.message };\n }\n\n if (error instanceof VariationNotFoundError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n if (error instanceof ValidationError) {\n return { errorCode: ErrorCode.INVALID_CONTEXT, errorMessage: error.message };\n }\n\n if (error instanceof DataError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n if (error instanceof ShowwhatError) {\n return { errorCode: ErrorCode.GENERAL, errorMessage: error.message };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return { errorCode: ErrorCode.GENERAL, errorMessage: message };\n}\n"],"mappings":"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","names":["ErrorCode","ErrorCode"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@showwhat/openfeature",
3
- "version": "1.0.0",
4
- "description": "OpenFeature provider for showwhat",
3
+ "version": "2.0.0",
4
+ "description": "OpenFeature provider for showwhat library",
5
5
  "keywords": [
6
6
  "feature-flags",
7
7
  "openfeature",
@@ -35,18 +35,18 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "showwhat": "1.0.0"
38
+ "showwhat": "2.0.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@openfeature/server-sdk": "^1.0.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@openfeature/server-sdk": "^1.20.0",
45
- "@types/node": "^25.4.0",
46
- "@vitest/coverage-v8": "^4.0.0",
47
- "tsup": "^8.0.0",
48
- "typescript": "^5.4.0",
49
- "vitest": "^4.0.0"
44
+ "@openfeature/server-sdk": "^1.20.2",
45
+ "@types/node": "^25.5.0",
46
+ "@vitest/coverage-v8": "^4.1.2",
47
+ "tsup": "^8.5.1",
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.1.2"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup",