|
1 | 1 | import { z, type ZodRawShape, type ZodTypeAny } from "zod"; |
2 | 2 | import { DmPolicySchema } from "../../config/zod-schema.core.js"; |
| 3 | +import { validateJsonSchemaValue } from "../../plugins/schema-validator.js"; |
3 | 4 | import type { JsonSchemaObject } from "../../shared/json-schema.types.js"; |
4 | 5 | import type { |
5 | 6 | ChannelConfigRuntimeIssue, |
@@ -41,6 +42,12 @@ type BuildChannelConfigSchemaOptions = { |
41 | 42 | uiHints?: Record<string, ChannelConfigUiHint>; |
42 | 43 | }; |
43 | 44 |
|
| 45 | +type BuildJsonChannelConfigSchemaOptions = { |
| 46 | + cacheKey?: string; |
| 47 | + uiHints?: Record<string, ChannelConfigUiHint>; |
| 48 | + runtime?: ChannelConfigSchema["runtime"]; |
| 49 | +}; |
| 50 | + |
44 | 51 | function cloneRuntimeIssue(issue: unknown): ChannelConfigRuntimeIssue { |
45 | 52 | const record = issue && typeof issue === "object" ? (issue as Record<string, unknown>) : {}; |
46 | 53 | const path = Array.isArray(record.path) |
@@ -72,6 +79,53 @@ function safeParseRuntimeSchema( |
72 | 79 | }; |
73 | 80 | } |
74 | 81 |
|
| 82 | +function toIssuePath(path: string): Array<string | number> { |
| 83 | + if (!path || path === "<root>") { |
| 84 | + return []; |
| 85 | + } |
| 86 | + return path.split(".").map((segment) => { |
| 87 | + const index = Number(segment); |
| 88 | + return Number.isInteger(index) && String(index) === segment ? index : segment; |
| 89 | + }); |
| 90 | +} |
| 91 | + |
| 92 | +function safeParseJsonSchema( |
| 93 | + schema: JsonSchemaObject, |
| 94 | + cacheKey: string, |
| 95 | + value: unknown, |
| 96 | +): ChannelConfigRuntimeParseResult { |
| 97 | + const result = validateJsonSchemaValue({ |
| 98 | + schema, |
| 99 | + cacheKey, |
| 100 | + value, |
| 101 | + applyDefaults: true, |
| 102 | + }); |
| 103 | + if (result.ok) { |
| 104 | + return { success: true, data: result.value }; |
| 105 | + } |
| 106 | + return { |
| 107 | + success: false, |
| 108 | + issues: result.errors.map((issue) => ({ |
| 109 | + path: toIssuePath(issue.path), |
| 110 | + message: issue.message, |
| 111 | + })), |
| 112 | + }; |
| 113 | +} |
| 114 | + |
| 115 | +export function buildJsonChannelConfigSchema( |
| 116 | + schema: JsonSchemaObject, |
| 117 | + options?: BuildJsonChannelConfigSchemaOptions, |
| 118 | +): ChannelConfigSchema { |
| 119 | + return { |
| 120 | + schema, |
| 121 | + ...(options?.uiHints ? { uiHints: options.uiHints } : {}), |
| 122 | + runtime: options?.runtime ?? { |
| 123 | + safeParse: (value) => |
| 124 | + safeParseJsonSchema(schema, options?.cacheKey ?? "channel-config-schema:json", value), |
| 125 | + }, |
| 126 | + }; |
| 127 | +} |
| 128 | + |
75 | 129 | export function buildChannelConfigSchema( |
76 | 130 | schema: ZodTypeAny, |
77 | 131 | options?: BuildChannelConfigSchemaOptions, |
|
0 commit comments