| 180 | } |
| 181 | |
| 182 | function applyOmit(target: Record<string, unknown>, paths: string[]) { |
| 183 | omitLoop: for (const omit of paths) { |
| 184 | const parts = omit.split("."); |
| 185 | const parents: Array<{ |
| 186 | value: Record<string, unknown>; |
| 187 | key: string; |
| 188 | }> = []; |
| 189 | let current = target; |
| 190 | |
| 191 | for (const part of parts.slice(0, -1)) { |
| 192 | const next = current[part]; |
| 193 | if ( |
| 194 | next === undefined || |
| 195 | next === null || |
| 196 | typeof next !== "object" || |
| 197 | Array.isArray(next) |
| 198 | ) { |
| 199 | continue omitLoop; |
| 200 | } |
| 201 | parents.push({ value: current, key: part }); |
| 202 | current = next as Record<string, unknown>; |
| 203 | } |
| 204 | |
| 205 | const lastPart = parts.at(-1); |
| 206 | if (lastPart === undefined || !(lastPart in current)) { |
| 207 | continue; |
| 208 | } |
| 209 | |
| 210 | delete current[lastPart]; |
| 211 | |
| 212 | for (let index = parents.length - 1; index >= 0; index--) { |
| 213 | const parent = parents[index]; |
| 214 | if (parent === undefined) continue; |
| 215 | const value = parent.value[parent.key]; |
| 216 | if ( |
| 217 | value === null || |
| 218 | value === undefined || |
| 219 | typeof value !== "object" || |
| 220 | Array.isArray(value) || |
| 221 | Object.keys(value).length > 0 |
| 222 | ) { |
| 223 | break; |
| 224 | } |
| 225 | delete parent.value[parent.key]; |
| 226 | } |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | function normalizeModelCost(model: z.infer<typeof AuthoredModel>): Model { |
| 231 | return normalizeCost(model) as Model; |