Skip to content

Commit c8857f2

Browse files
committed
fix(effect-schema): validate boolean strings
1 parent fc5fc2b commit c8857f2

3 files changed

Lines changed: 13 additions & 2 deletions

File tree

packages/quicktype-core/src/language/TypeScriptEffectSchema/TypeScriptEffectSchemaRenderer.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer {
100100
return ["S.optional(", this.typeMapTypeFor(p.type), ")"];
101101
}
102102

103-
private typeMapTypeFor(t: Type, required = true): Sourcelike {
103+
private typeMapTypeFor(
104+
t: Type,
105+
required = true,
106+
coerceStrings = false,
107+
): Sourcelike {
104108
if (t.kind === "class" || t.kind === "object" || t.kind === "enum") {
105109
const name = this.nameForNamedType(t);
106110
if (this.emittedObjects.has(name)) {
@@ -143,6 +147,7 @@ export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer {
143147
(_enumType) => panic("Should already be handled."),
144148
(unionType) => {
145149
const types = Array.from(unionType.getChildren());
150+
const coerce = types.some((type) => type.kind === "bool");
146151
const rank = (type: Type): number =>
147152
type.kind === "class" || type.kind === "object" ? 1 : 0;
148153
types.sort((a, b) => rank(a) - rank(b));
@@ -152,7 +157,7 @@ export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer {
152157
if (type.kind === "null") {
153158
nullable = true;
154159
} else {
155-
children.push(this.typeMapTypeFor(type, false));
160+
children.push(this.typeMapTypeFor(type, false, coerce));
156161
}
157162
}
158163

@@ -168,6 +173,10 @@ export class TypeScriptEffectSchemaRenderer extends ConvenienceRenderer {
168173
},
169174
(_transformedStringType) => {
170175
if (_transformedStringType.kind === "uuid") return "S.UUID";
176+
if (_transformedStringType.kind === "bool-string")
177+
return coerceStrings
178+
? 'S.transform(S.Literal("true", "false"), S.Boolean, { strict: true, decode: (value) => value === "true", encode: (value) => value ? "true" : "false" })'
179+
: 'S.Literal("true", "false")';
171180
return "S.String";
172181
},
173182
);

packages/quicktype-core/src/language/TypeScriptEffectSchema/language.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export class TypeScriptEffectSchemaTargetLanguage extends TargetLanguage<
3737
PrimitiveStringTypeKind
3838
>();
3939
mapping.set("uuid", "uuid");
40+
mapping.set("bool-string", "bool-string");
4041
return mapping;
4142
}
4243

test/languages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,7 @@ export const TypeScriptEffectSchemaLanguage: Language = {
17391739
"strict-optional",
17401740
"minmaxitems",
17411741
"uuid",
1742+
"bool-string",
17421743
],
17431744
output: "TopLevel.ts",
17441745
topLevel: "TopLevel",

0 commit comments

Comments
 (0)