@claritylabs/cl-sdk 3.1.4 → 3.1.5

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/index.mjs CHANGED
@@ -80,53 +80,70 @@ function sanitizeNulls(obj) {
80
80
 
81
81
  // src/core/strict-schema.ts
82
82
  import { z } from "zod";
83
+ function schemaDef(schema) {
84
+ return schema._zod?.def ?? schema._def ?? {};
85
+ }
86
+ function schemaKind(schema) {
87
+ const def = schemaDef(schema);
88
+ const raw = typeof def.type === "string" ? def.type : typeof def.typeName === "string" ? def.typeName : typeof schema.type === "string" ? schema.type : void 0;
89
+ return raw?.replace(/^Zod/, "").toLowerCase();
90
+ }
91
+ function schemaDescription(schema) {
92
+ const def = schemaDef(schema);
93
+ return schema.description ?? def.description;
94
+ }
95
+ function objectShape(schema) {
96
+ const def = schemaDef(schema);
97
+ const shape = schema.shape ?? def.shape;
98
+ return typeof shape === "function" ? shape() : shape;
99
+ }
100
+ function withDescription(schema, description) {
101
+ return description ? schema.describe(description) : schema;
102
+ }
83
103
  function toStrictSchema(schema) {
84
- const def = schema._zod?.def;
85
- const typeName = def?.type ?? schema.type;
86
- if (typeName === "object") {
87
- const shape = schema.shape;
104
+ const kind = schemaKind(schema);
105
+ const def = schemaDef(schema);
106
+ if (kind === "object") {
107
+ const shape = objectShape(schema);
88
108
  if (!shape) return schema;
89
109
  const newShape = {};
90
110
  for (const [key, value] of Object.entries(shape)) {
91
111
  const field = value;
92
- const fieldDef = field._zod?.def;
93
- const fieldType = fieldDef?.type ?? field.type;
94
- if (fieldType === "optional") {
112
+ const fieldDef = schemaDef(field);
113
+ const fieldKind = schemaKind(field);
114
+ if (fieldKind === "optional") {
95
115
  const innerType = fieldDef?.innerType;
96
- const description = field.description ?? fieldDef?.description ?? field._zod?.def?.description;
116
+ const description = schemaDescription(field);
97
117
  if (innerType) {
98
118
  const transformed = toStrictSchema(innerType);
99
- let nullable = z.nullable(transformed);
100
- if (description) nullable = nullable.describe(description);
101
- newShape[key] = nullable;
119
+ newShape[key] = withDescription(z.nullable(transformed), description);
102
120
  } else {
103
- let nullable = z.nullable(field);
104
- if (description) nullable = nullable.describe(description);
105
- newShape[key] = nullable;
121
+ newShape[key] = withDescription(z.nullable(field), description);
106
122
  }
107
123
  } else {
108
124
  newShape[key] = toStrictSchema(field);
109
125
  }
110
126
  }
111
- const objDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
112
- const result = z.object(newShape);
113
- return objDesc ? result.describe(objDesc) : result;
127
+ return withDescription(z.object(newShape), schemaDescription(schema));
114
128
  }
115
- if (typeName === "array") {
116
- const element = def?.element ?? schema.element;
129
+ if (kind === "array") {
130
+ const element = def.element ?? def.type ?? schema.element;
117
131
  if (element) {
118
- const arrDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
119
- const result = z.array(toStrictSchema(element));
120
- return arrDesc ? result.describe(arrDesc) : result;
132
+ return withDescription(z.array(toStrictSchema(element)), schemaDescription(schema));
121
133
  }
122
134
  return schema;
123
135
  }
124
- if (typeName === "nullable") {
136
+ if (kind === "nullable") {
125
137
  const innerType = def?.innerType;
126
138
  if (innerType) {
127
- const nullDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
128
- const result = z.nullable(toStrictSchema(innerType));
129
- return nullDesc ? result.describe(nullDesc) : result;
139
+ return withDescription(z.nullable(toStrictSchema(innerType)), schemaDescription(schema));
140
+ }
141
+ return schema;
142
+ }
143
+ if (kind === "default") {
144
+ const innerType = def?.innerType;
145
+ if (innerType) {
146
+ return withDescription(z.nullable(toStrictSchema(innerType)), schemaDescription(schema));
130
147
  }
131
148
  return schema;
132
149
  }
@@ -9849,6 +9866,8 @@ Rules:
9849
9866
  - Keep a coverage when it is a real operational coverage/benefit even if only one term needs cleanup.
9850
9867
  - When changing a term's semantic meaning, set kind to the corrected normalized term kind.
9851
9868
  - Do not add new coverage rows or new terms; this pass cleans the existing projection.
9869
+ - Include every JSON key in each decision. Use null for scalar fields you are not changing and [] for source ID lists you are not changing.
9870
+ - For each coverage decision, always include termDecisions. Use [] when no terms need cleanup.
9852
9871
  - Keep reasons concise and factual.
9853
9872
 
9854
9873
  Candidate projection:
@@ -9859,9 +9878,6 @@ ${JSON.stringify(nodes, null, 2)}
9859
9878
 
9860
9879
  Return JSON with coverageDecisions and warnings only.`;
9861
9880
  }
9862
- function hasOwn(object, key) {
9863
- return Object.prototype.hasOwnProperty.call(object, key);
9864
- }
9865
9881
  function uniqueStrings(values) {
9866
9882
  return [...new Set(values.filter((value) => value.length > 0))];
9867
9883
  }
@@ -9936,18 +9952,16 @@ function applyTermCleanupDecision(term, decision, validNodeIds, validSpanIds) {
9936
9952
  sourceSpanIds: cleanupIds(decision.sourceSpanIds, validSpanIds, term.sourceSpanIds)
9937
9953
  };
9938
9954
  if (next.sourceNodeIds.length === 0 && next.sourceSpanIds.length === 0) return term;
9939
- if (hasOwn(decision, "amount")) {
9940
- if (typeof decision.amount === "number" && Number.isFinite(decision.amount)) next.amount = decision.amount;
9941
- else delete next.amount;
9955
+ if (typeof decision.amount === "number" && Number.isFinite(decision.amount)) {
9956
+ next.amount = decision.amount;
9942
9957
  } else if (decision.value || decision.kind) {
9943
9958
  const amount = next.kind === "retroactive_date" ? void 0 : amountFromOperationalValue(next.value);
9944
9959
  if (amount === void 0) delete next.amount;
9945
9960
  else next.amount = amount;
9946
9961
  }
9947
- if (hasOwn(decision, "appliesTo")) {
9962
+ if (decision.appliesTo != null) {
9948
9963
  const appliesTo = cleanProfileValue(decision.appliesTo);
9949
9964
  if (appliesTo) next.appliesTo = appliesTo;
9950
- else delete next.appliesTo;
9951
9965
  }
9952
9966
  return next;
9953
9967
  }
@@ -9966,46 +9980,42 @@ function applyCoverageCleanupDecision(coverage, decision, validNodeIds, validSpa
9966
9980
  const name = cleanProfileValue(decision.name);
9967
9981
  if (name) next.name = name;
9968
9982
  if (decision.coverageOrigin) next.coverageOrigin = decision.coverageOrigin;
9969
- if (hasOwn(decision, "limit")) {
9983
+ if (decision.limit != null) {
9970
9984
  const value = cleanProfileValue(decision.limit);
9971
9985
  if (value) next.limit = value;
9972
- else delete next.limit;
9973
9986
  }
9974
- if (hasOwn(decision, "deductible")) {
9987
+ if (decision.deductible != null) {
9975
9988
  const value = cleanProfileValue(decision.deductible);
9976
9989
  if (value) next.deductible = value;
9977
- else delete next.deductible;
9978
9990
  }
9979
- if (hasOwn(decision, "premium")) {
9991
+ if (decision.premium != null) {
9980
9992
  const value = cleanProfileValue(decision.premium);
9981
9993
  if (value) next.premium = value;
9982
- else delete next.premium;
9983
9994
  }
9984
- if (hasOwn(decision, "retroactiveDate")) {
9995
+ if (decision.retroactiveDate != null) {
9985
9996
  const value = cleanProfileValue(decision.retroactiveDate);
9986
9997
  if (value) next.retroactiveDate = value;
9987
- else delete next.retroactiveDate;
9988
9998
  }
9989
9999
  const termDecisions = (decision.termDecisions ?? []).filter((termDecision) => termDecision.termIndex < coverage.limits.length);
9990
10000
  const termDecisionByIndex = new Map(termDecisions.map((termDecision) => [termDecision.termIndex, termDecision]));
9991
10001
  next.limits = coverage.limits.map((term, index) => applyTermCleanupDecision(term, termDecisionByIndex.get(index), validNodeIds, validSpanIds)).filter((term) => Boolean(term));
9992
10002
  if (termDecisions.length > 0) {
9993
- if (!hasOwn(decision, "limit") && termDecisionsTouch(coverage, termDecisions, isLimitTerm)) {
10003
+ if (decision.limit == null && termDecisionsTouch(coverage, termDecisions, isLimitTerm)) {
9994
10004
  const value = primaryLimitFromTerms(next.limits);
9995
10005
  if (value) next.limit = value;
9996
10006
  else delete next.limit;
9997
10007
  }
9998
- if (!hasOwn(decision, "deductible") && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
10008
+ if (decision.deductible == null && termDecisionsTouch(coverage, termDecisions, isDeductibleTerm)) {
9999
10009
  const value = deductibleFromTerms(next.limits);
10000
10010
  if (value) next.deductible = value;
10001
10011
  else delete next.deductible;
10002
10012
  }
10003
- if (!hasOwn(decision, "premium") && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
10013
+ if (decision.premium == null && termDecisionsTouch(coverage, termDecisions, isPremiumTerm)) {
10004
10014
  const value = premiumFromTerms(next.limits);
10005
10015
  if (value) next.premium = value;
10006
10016
  else delete next.premium;
10007
10017
  }
10008
- if (!hasOwn(decision, "retroactiveDate") && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
10018
+ if (decision.retroactiveDate == null && termDecisionsTouch(coverage, termDecisions, isRetroactiveDateTerm)) {
10009
10019
  const value = retroactiveDateFromTerms(next.limits);
10010
10020
  if (value) next.retroactiveDate = value;
10011
10021
  else delete next.retroactiveDate;