From 31fb449e17dd7cbc36d9d95cd4ed637eb15449d1 Mon Sep 17 00:00:00 2001 From: cm-ayf Date: Sat, 11 May 2024 10:13:56 +0900 Subject: [PATCH 1/2] escape characters on convertiny template literal --- typescript-json-schema.ts | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/typescript-json-schema.ts b/typescript-json-schema.ts index 68c34bf..5e54fe0 100644 --- a/typescript-json-schema.ts +++ b/typescript-json-schema.ts @@ -751,40 +751,48 @@ export class JsonSchemaGenerator { definition.type = "string"; // @ts-ignore const {texts, types} = propertyType; - const pattern = []; + let pattern = "^"; for (let i = 0; i < texts.length; i++) { - const text = texts[i]; - const type = types[i]; - - if (i === 0) { - pattern.push(`^`); + const text: string = texts[i]; + const type: ts.Type = types[i]; + + // https://json-schema.org/understanding-json-schema/reference/regular_expressions + // `-` should not be escaped; + // it is escaped only if it is used like `[a-z]`, which never happens here. + const control = ["[", "]", "(", ")", "{", "}", "^", "$", ".", "|", "?", "*", "+", "!"]; + const escaped: { [char: string]: string } = { "\n": "\\n", "\r": "\\r", "\t": "\\t" }; + for (const char of text) { + if (control.includes(char)) { + pattern += `\\${char}`; + } else if (escaped[char]) { + pattern += escaped[char]; + } else { + pattern += char; + } } if (type) { if (type.flags & ts.TypeFlags.String) { - pattern.push(`${text}.*`); + pattern += ".*"; } if (type.flags & ts.TypeFlags.Number || type.flags & ts.TypeFlags.BigInt) { - pattern.push(`${text}[0-9]*`); + pattern += "[0-9]*"; } if (type.flags & ts.TypeFlags.Undefined) { - pattern.push(`${text}undefined`); + pattern += "undefined"; } if (type.flags & ts.TypeFlags.Null) { - pattern.push(`${text}null`); + pattern += "null"; } } - - - if (i === texts.length - 1) { - pattern.push(`${text}$`); - } } - definition.pattern = pattern.join(""); + + pattern += "$"; + definition.pattern = pattern; } else { definition.type = "array"; if (!definition.items) { From c60886de45c2538c0b4d8f949ffc3529938a5223 Mon Sep 17 00:00:00 2001 From: cm-ayf Date: Sat, 11 May 2024 10:14:45 +0900 Subject: [PATCH 2/2] add test for template literal patterns --- test/programs/string-template-literal/main.ts | 3 +++ .../string-template-literal/schema.json | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/programs/string-template-literal/main.ts b/test/programs/string-template-literal/main.ts index 4b0745b..adfb457 100644 --- a/test/programs/string-template-literal/main.ts +++ b/test/programs/string-template-literal/main.ts @@ -8,4 +8,7 @@ interface MyObject { g: `${string}@`, h: `${number}@`, i: `${string}@${number}`, + j: `{{${string}}}` + k: `${string}\n` + l: `${string}-${string}` } \ No newline at end of file diff --git a/test/programs/string-template-literal/schema.json b/test/programs/string-template-literal/schema.json index cc39dd2..bb0149f 100644 --- a/test/programs/string-template-literal/schema.json +++ b/test/programs/string-template-literal/schema.json @@ -39,6 +39,18 @@ "i": { "type": "string", "pattern": "^.*@[0-9]*$" + }, + "j": { + "pattern": "^\\{\\{.*\\}\\}$", + "type": "string" + }, + "k": { + "pattern": "^.*\\n$", + "type": "string" + }, + "l": { + "pattern": "^.*-.*$", + "type": "string" } }, "additionalProperties": false, @@ -51,7 +63,10 @@ "f", "g", "h", - "i" + "i", + "j", + "k", + "l" ], "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file