MCPcopy Index your code
hub / github.com/microsoft/TypeChat / createTypeScriptJsonValidator

Function createTypeScriptJsonValidator

typescript/src/ts/validate.ts:35–135  ·  view source on GitHub ↗
(schema: string, typeName: string)

Source from the content-addressed store, hash-verified

33 * @returns A `TypeChatJsonValidator<T>` instance.
34 */
35export function createTypeScriptJsonValidator<T extends object = object>(schema: string, typeName: string): TypeScriptJsonValidator<T> {
36 const options = {
37 ...ts.getDefaultCompilerOptions(),
38 strict: true,
39 skipLibCheck: true,
40 noLib: true,
41 types: []
42 };
43 const rootProgram = createProgramFromModuleText("");
44 const validator: TypeScriptJsonValidator<T> = {
45 getSchemaText: () => schema,
46 getTypeName: () => typeName,
47 createModuleTextFromJson,
48 validate
49 };
50 return validator;
51
52 function validate(jsonObject: object) {
53 const moduleResult = validator.createModuleTextFromJson(jsonObject);
54 if (!moduleResult.success) {
55 return moduleResult;
56 }
57 const program = createProgramFromModuleText(moduleResult.data, rootProgram);
58 const syntacticDiagnostics = program.getSyntacticDiagnostics();
59 const programDiagnostics = syntacticDiagnostics.length ? syntacticDiagnostics : program.getSemanticDiagnostics();
60 if (programDiagnostics.length) {
61 const checker = program.getTypeChecker();
62 const diagnostics = programDiagnostics.map(d => {
63 const message = ts.flattenDiagnosticMessageText(d.messageText, "\n");
64 // TS error 2740 truncates the missing-properties list to 4 items ("and N more").
65 // Use the type checker to reconstruct the full list of missing required properties.
66 if (d.code === 2740 && d.file && d.start !== undefined) {
67 return expandMissingPropertiesMessage(checker, d.file, d.start) ?? message;
68 }
69 return message;
70 }).join("\n");
71 return error(diagnostics);
72 }
73 return success(jsonObject as T);
74 }
75
76 /**
77 * For TypeScript error 2740 (missing required properties, truncated with "and N more"),
78 * uses the type checker to compute the full list of missing required properties from the
79 * variable declaration at `position` in `file`. Returns `undefined` if the declaration
80 * cannot be located or yields no missing properties (fallback to the original message).
81 */
82 function expandMissingPropertiesMessage(checker: ts.TypeChecker, file: ts.SourceFile, position: number): string | undefined {
83 for (const stmt of file.statements) {
84 if (ts.isVariableStatement(stmt)) {
85 for (const decl of stmt.declarationList.declarations) {
86 // Match the specific declaration that spans the diagnostic position.
87 // Use getStart() to exclude leading trivia from the range check.
88 if (decl.getStart(file) <= position && position <= decl.end &&
89 decl.type && ts.isTypeReferenceNode(decl.type) && decl.initializer) {
90 const targetType = checker.getTypeAtLocation(decl.type);
91 const sourceType = checker.getTypeAtLocation(decl.initializer);
92 const sourceProps = new Set(sourceType.getProperties().map(p => p.name));

Callers 11

createProgramTranslatorFunction · 0.90
main.tsFile · 0.90
main.tsFile · 0.90
main.tsFile · 0.90
main.tsFile · 0.90
main.tsFile · 0.90
createAgentRouterFunction · 0.90
createJsonPrintAgentFunction · 0.90
main.tsFile · 0.90
validatorForFunction · 0.85

Calls 1

Tested by 1

validatorForFunction · 0.68