@configdirector/nuxt-sdk 1.8.0 → 1.9.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/dist/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=4.0.0"
6
6
  },
7
- "version": "1.8.0"
7
+ "version": "1.9.0"
8
8
  }
@@ -7076,6 +7076,40 @@ var ConditionEvaluator = class {
7076
7076
  };
7077
7077
  const orAbsent = (value) => value === void 0 || value === null ? ABSENT : value;
7078
7078
  //#endregion
7079
+ //#region ../config-evaluator/src/SegmentEvaluator.ts
7080
+ var SegmentEvaluator = class {
7081
+ constructor(conditionEvaluator) {
7082
+ this.conditionEvaluator = conditionEvaluator;
7083
+ }
7084
+ explain(condition, segments, context) {
7085
+ const segment = segments?.[condition.segmentId];
7086
+ if (segment === void 0 || !holdsAttributeConditionsOnly(segment)) return {
7087
+ matched: false,
7088
+ segmentFound: false,
7089
+ matchedGroupIndex: void 0
7090
+ };
7091
+ const matchedGroupIndex = this.matchingGroupIndex(segment, context);
7092
+ const member = matchedGroupIndex !== void 0;
7093
+ return {
7094
+ matched: this.operatorHolds(condition, member),
7095
+ segmentFound: true,
7096
+ matchedGroupIndex
7097
+ };
7098
+ }
7099
+ operatorHolds(condition, member) {
7100
+ switch (condition.operator.toLowerCase()) {
7101
+ case "in": return member;
7102
+ case "not in": return !member;
7103
+ default: return false;
7104
+ }
7105
+ }
7106
+ matchingGroupIndex(segment, context) {
7107
+ const index = (segment.groups ?? []).findIndex((group) => (group ?? []).every((condition) => this.conditionEvaluator.evaluate(condition, context)));
7108
+ return index === -1 ? void 0 : index;
7109
+ }
7110
+ };
7111
+ const holdsAttributeConditionsOnly = (segment) => (segment.groups ?? []).every((group) => (group ?? []).every((condition) => condition.kind === void 0 || condition.kind === "attribute"));
7112
+ //#endregion
7079
7113
  //#region ../config-evaluator/src/percent-hashing.ts
7080
7114
  const SEED = 15426857351n;
7081
7115
  const assignPercentage = (data) => {
@@ -7086,26 +7120,28 @@ const assignPercentage = (data) => {
7086
7120
  //#region ../config-evaluator/src/ConfigEvaluator.ts
7087
7121
  var ConfigEvaluator = class {
7088
7122
  conditionEvaluator = new ConditionEvaluator();
7123
+ segmentEvaluator = new SegmentEvaluator(this.conditionEvaluator);
7089
7124
  constructor(logger) {
7090
7125
  this.logger = logger;
7091
7126
  if (!logger || !logger.warn || !logger.error || !logger.info) throw new TypeError("The provided logger is not a valid 'ConfigDirectorLogger'");
7092
7127
  this.logger = logger;
7093
7128
  }
7094
- evaluate(config, context) {
7129
+ evaluate(config, context, segments) {
7095
7130
  return {
7096
7131
  id: config.id,
7097
7132
  key: config.key,
7098
7133
  type: config.type,
7099
- value: this.explain(config, context).value
7134
+ value: this.explain(config, context, segments).value
7100
7135
  };
7101
7136
  }
7102
7137
  /**
7103
7138
  * Evaluate a config for a context and record how the value was reached: every rule in the
7104
7139
  * order it was walked with its outcome, the conditions that were checked with what they
7105
7140
  * resolved to, and the share a rollout assigned the context to. `evaluate` is this walk with
7106
- * only the value kept, so the two cannot disagree.
7141
+ * only the value kept, so the two cannot disagree. `segments` is the payload's segments map,
7142
+ * which a segment condition looks its segment up in; a segment it does not hold never matches.
7107
7143
  */
7108
- explain(config, context) {
7144
+ explain(config, context, segments) {
7109
7145
  const rules = [...config.target?.rules ?? []].sort((a, b) => (a.order ?? Number.MAX_SAFE_INTEGER) - (b.order ?? Number.MAX_SAFE_INTEGER));
7110
7146
  const explanations = [];
7111
7147
  let served;
@@ -7119,7 +7155,7 @@ var ConfigEvaluator = class {
7119
7155
  });
7120
7156
  continue;
7121
7157
  }
7122
- const result = this.explainRule(rule, config, context);
7158
+ const result = this.explainRule(rule, config, context, segments);
7123
7159
  explanations.push(result.explanation);
7124
7160
  if (result.value !== void 0) served = {
7125
7161
  ruleId: rule.id,
@@ -7135,7 +7171,7 @@ var ConfigEvaluator = class {
7135
7171
  rules: explanations
7136
7172
  };
7137
7173
  }
7138
- explainRule(rule, config, context) {
7174
+ explainRule(rule, config, context, segments) {
7139
7175
  const explanation = {
7140
7176
  ruleId: rule.id,
7141
7177
  outcome: "not-matched",
@@ -7145,7 +7181,7 @@ var ConfigEvaluator = class {
7145
7181
  try {
7146
7182
  let value;
7147
7183
  if (rule.type == "percentage") value = this.explainPercentage(rule.percentages ?? [], config, context, explanation);
7148
- else if (rule.type == "conditional") value = this.explainConditionalRule(rule, config, context, explanation);
7184
+ else if (rule.type == "conditional") value = this.explainConditionalRule(rule, config, context, segments, explanation);
7149
7185
  if (value !== void 0) explanation.outcome = "matched";
7150
7186
  return {
7151
7187
  explanation,
@@ -7197,7 +7233,7 @@ var ConfigEvaluator = class {
7197
7233
  };
7198
7234
  return selected?.value != null ? selected.value.toString() : void 0;
7199
7235
  }
7200
- explainConditionalRule(rule, config, context, explanation) {
7236
+ explainConditionalRule(rule, config, context, segments, explanation) {
7201
7237
  let failed = false;
7202
7238
  for (const condition of rule.conditions ?? []) {
7203
7239
  if (failed) {
@@ -7207,19 +7243,35 @@ var ConfigEvaluator = class {
7207
7243
  });
7208
7244
  continue;
7209
7245
  }
7210
- const check = this.conditionEvaluator.explain(condition, context);
7211
- explanation.conditions.push({
7212
- conditionId: condition.id,
7213
- outcome: check.matched ? "matched" : "not-matched",
7214
- resolvedValue: check.resolvedValue,
7215
- resolvedType: check.resolvedType
7216
- });
7217
- failed = !check.matched;
7246
+ const checked = this.explainCondition(condition, context, segments);
7247
+ explanation.conditions.push(checked);
7248
+ failed = checked.outcome !== "matched";
7218
7249
  }
7219
7250
  if (failed) return;
7220
7251
  if (rule.target == "value") return rule.value != null ? rule.value.toString() : void 0;
7221
7252
  if (rule.target == "percentage") return this.explainPercentage(rule.percentages ?? [], config, context, explanation);
7222
7253
  }
7254
+ explainCondition(condition, context, segments) {
7255
+ if (condition.kind === "segment") {
7256
+ const check = this.segmentEvaluator.explain(condition, segments, context);
7257
+ return {
7258
+ conditionId: condition.id,
7259
+ kind: "segment",
7260
+ outcome: check.matched ? "matched" : "not-matched",
7261
+ segmentId: condition.segmentId,
7262
+ segmentFound: check.segmentFound,
7263
+ matchedGroupIndex: check.matchedGroupIndex
7264
+ };
7265
+ }
7266
+ const check = this.conditionEvaluator.explain(condition, context);
7267
+ return {
7268
+ conditionId: condition.id,
7269
+ kind: "attribute",
7270
+ outcome: check.matched ? "matched" : "not-matched",
7271
+ resolvedValue: check.resolvedValue,
7272
+ resolvedType: check.resolvedType
7273
+ };
7274
+ }
7223
7275
  };
7224
7276
  //#endregion
7225
7277
  //#region ../shared/src/value-parser.ts
@@ -7880,10 +7932,16 @@ var DefaultConfigDirectorClient = class {
7880
7932
  this.readyResolve?.(false);
7881
7933
  const removedKeys = this.findKeysRemovedBy(configBundle);
7882
7934
  if (!this.configSet || configBundle.kind == "full") this.configSet = configBundle;
7883
- else this.configSet.configs = {
7884
- ...this.configSet.configs,
7885
- ...configBundle.configs
7886
- };
7935
+ else {
7936
+ this.configSet.configs = {
7937
+ ...this.configSet.configs,
7938
+ ...configBundle.configs
7939
+ };
7940
+ this.configSet.segments = {
7941
+ ...this.configSet.segments,
7942
+ ...configBundle.segments
7943
+ };
7944
+ }
7887
7945
  const keys = Object.keys(configBundle.configs);
7888
7946
  this.eventEmitter.emit("configsUpdated", {
7889
7947
  keys,
@@ -8027,7 +8085,7 @@ var DefaultConfigDirectorClient = class {
8027
8085
  const configState = this.configEvaluator.evaluate(configDefinition, {
8028
8086
  context,
8029
8087
  metadata: this.metaContext
8030
- });
8088
+ }, this.configSet?.segments);
8031
8089
  const parseResult = parseConfigValue(configState, defaultValue);
8032
8090
  this.usageEventCollector.evaluatedConfig({
8033
8091
  context,
@@ -8119,7 +8177,7 @@ var DefaultConfigDirectorClient = class {
8119
8177
  return Object.fromEntries(filtered.map(([key, config]) => [key, this.configEvaluator.evaluate(config, {
8120
8178
  context: options?.context,
8121
8179
  metadata: this.metaContext
8122
- })]));
8180
+ }, this.configSet?.segments)]));
8123
8181
  }
8124
8182
  closeConnection() {
8125
8183
  this.logger.debug("[ConfigDirectorClient] closeConnection() has been called, closing connection to server");
@@ -8161,7 +8219,7 @@ var plugin_default = defineNitroPlugin((nitroApp) => {
8161
8219
  const { serverSdkKey, baseUrl, connection } = runtimeConfig.configdirector;
8162
8220
  const client = new DefaultConfigDirectorClient(serverSdkKey, {
8163
8221
  sdkName: "nuxt-sdk",
8164
- sdkVersion: "1.8.0"
8222
+ sdkVersion: "1.9.0"
8165
8223
  }, {
8166
8224
  logger,
8167
8225
  connection: {
@@ -1597,7 +1597,7 @@ const buildClient = (configdirector, logger) => {
1597
1597
  const { clientSdkKey, appName, appVersion, baseUrl, connection } = configdirector;
1598
1598
  return createBrowserClient(clientSdkKey, {
1599
1599
  sdkName: "nuxt-sdk",
1600
- sdkVersion: "1.8.0"
1600
+ sdkVersion: "1.9.0"
1601
1601
  }, {
1602
1602
  metadata: {
1603
1603
  appName,
package/dist/testing.mjs CHANGED
@@ -1638,7 +1638,7 @@ const installTestClient = (testClient) => {
1638
1638
  const createTestClient = (options) => {
1639
1639
  return createTestClient$1({
1640
1640
  sdkName: "nuxt-sdk",
1641
- sdkVersion: "1.8.0"
1641
+ sdkVersion: "1.9.0"
1642
1642
  }, options);
1643
1643
  };
1644
1644
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configdirector/nuxt-sdk",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Nuxt SDK for ConfigDirector. ConfigDirector is a remote configuration and feature flag service.",
5
5
  "license": "MIT",
6
6
  "author": "ConfigDirector",