2 Object.defineProperty(exports, "__esModule", { value: true });
3 exports.reportTypeError = exports.checkDataTypes = exports.checkDataType = exports.coerceAndCheckDataType = exports.getJSONTypes = exports.getSchemaTypes = exports.DataType = void 0;
4 const rules_1 = require("../rules");
5 const applicability_1 = require("./applicability");
6 const errors_1 = require("../errors");
7 const codegen_1 = require("../codegen");
8 const util_1 = require("../util");
10 (function (DataType) {
11 DataType[DataType["Correct"] = 0] = "Correct";
12 DataType[DataType["Wrong"] = 1] = "Wrong";
13 })(DataType = exports.DataType || (exports.DataType = {}));
14 function getSchemaTypes(schema) {
15 const types = getJSONTypes(schema.type);
16 const hasNull = types.includes("null");
18 if (schema.nullable === false)
19 throw new Error("type: null contradicts nullable: false");
22 if (!types.length && schema.nullable !== undefined) {
23 throw new Error('"nullable" cannot be used without "type"');
25 if (schema.nullable === true)
30 exports.getSchemaTypes = getSchemaTypes;
31 function getJSONTypes(ts) {
32 const types = Array.isArray(ts) ? ts : ts ? [ts] : [];
33 if (types.every(rules_1.isJSONType))
35 throw new Error("type must be JSONType or JSONType[]: " + types.join(","));
37 exports.getJSONTypes = getJSONTypes;
38 function coerceAndCheckDataType(it, types) {
39 const { gen, data, opts } = it;
40 const coerceTo = coerceToTypes(types, opts.coerceTypes);
41 const checkTypes = types.length > 0 &&
42 !(coerceTo.length === 0 && types.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types[0]));
44 const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong);
45 gen.if(wrongType, () => {
47 coerceData(it, types, coerceTo);
54 exports.coerceAndCheckDataType = coerceAndCheckDataType;
55 const COERCIBLE = new Set(["string", "number", "integer", "boolean", "null"]);
56 function coerceToTypes(types, coerceTypes) {
58 ? types.filter((t) => COERCIBLE.has(t) || (coerceTypes === "array" && t === "array"))
61 function coerceData(it, types, coerceTo) {
62 const { gen, data, opts } = it;
63 const dataType = gen.let("dataType", (0, codegen_1._) `typeof ${data}`);
64 const coerced = gen.let("coerced", (0, codegen_1._) `undefined`);
65 if (opts.coerceTypes === "array") {
66 gen.if((0, codegen_1._) `${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen
67 .assign(data, (0, codegen_1._) `${data}[0]`)
68 .assign(dataType, (0, codegen_1._) `typeof ${data}`)
69 .if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)));
71 gen.if((0, codegen_1._) `${coerced} !== undefined`);
72 for (const t of coerceTo) {
73 if (COERCIBLE.has(t) || (t === "array" && opts.coerceTypes === "array")) {
74 coerceSpecificType(t);
80 gen.if((0, codegen_1._) `${coerced} !== undefined`, () => {
81 gen.assign(data, coerced);
82 assignParentData(it, coerced);
84 function coerceSpecificType(t) {
88 .elseIf((0, codegen_1._) `${dataType} == "number" || ${dataType} == "boolean"`)
89 .assign(coerced, (0, codegen_1._) `"" + ${data}`)
90 .elseIf((0, codegen_1._) `${data} === null`)
91 .assign(coerced, (0, codegen_1._) `""`);
95 .elseIf((0, codegen_1._) `${dataType} == "boolean" || ${data} === null
96 || (${dataType} == "string" && ${data} && ${data} == +${data})`)
97 .assign(coerced, (0, codegen_1._) `+${data}`);
101 .elseIf((0, codegen_1._) `${dataType} === "boolean" || ${data} === null
102 || (${dataType} === "string" && ${data} && ${data} == +${data} && !(${data} % 1))`)
103 .assign(coerced, (0, codegen_1._) `+${data}`);
107 .elseIf((0, codegen_1._) `${data} === "false" || ${data} === 0 || ${data} === null`)
108 .assign(coerced, false)
109 .elseIf((0, codegen_1._) `${data} === "true" || ${data} === 1`)
110 .assign(coerced, true);
113 gen.elseIf((0, codegen_1._) `${data} === "" || ${data} === 0 || ${data} === false`);
114 gen.assign(coerced, null);
118 .elseIf((0, codegen_1._) `${dataType} === "string" || ${dataType} === "number"
119 || ${dataType} === "boolean" || ${data} === null`)
120 .assign(coerced, (0, codegen_1._) `[${data}]`);
124 function assignParentData({ gen, parentData, parentDataProperty }, expr) {
125 // TODO use gen.property
126 gen.if((0, codegen_1._) `${parentData} !== undefined`, () => gen.assign((0, codegen_1._) `${parentData}[${parentDataProperty}]`, expr));
128 function checkDataType(dataType, data, strictNums, correct = DataType.Correct) {
129 const EQ = correct === DataType.Correct ? codegen_1.operators.EQ : codegen_1.operators.NEQ;
133 return (0, codegen_1._) `${data} ${EQ} null`;
135 cond = (0, codegen_1._) `Array.isArray(${data})`;
138 cond = (0, codegen_1._) `${data} && typeof ${data} == "object" && !Array.isArray(${data})`;
141 cond = numCond((0, codegen_1._) `!(${data} % 1) && !isNaN(${data})`);
147 return (0, codegen_1._) `typeof ${data} ${EQ} ${dataType}`;
149 return correct === DataType.Correct ? cond : (0, codegen_1.not)(cond);
150 function numCond(_cond = codegen_1.nil) {
151 return (0, codegen_1.and)((0, codegen_1._) `typeof ${data} == "number"`, _cond, strictNums ? (0, codegen_1._) `isFinite(${data})` : codegen_1.nil);
154 exports.checkDataType = checkDataType;
155 function checkDataTypes(dataTypes, data, strictNums, correct) {
156 if (dataTypes.length === 1) {
157 return checkDataType(dataTypes[0], data, strictNums, correct);
160 const types = (0, util_1.toHash)(dataTypes);
161 if (types.array && types.object) {
162 const notObj = (0, codegen_1._) `typeof ${data} != "object"`;
163 cond = types.null ? notObj : (0, codegen_1._) `!${data} || ${notObj}`;
169 cond = codegen_1.nil;
172 delete types.integer;
173 for (const t in types)
174 cond = (0, codegen_1.and)(cond, checkDataType(t, data, strictNums, correct));
177 exports.checkDataTypes = checkDataTypes;
179 message: ({ schema }) => `must be ${schema}`,
180 params: ({ schema, schemaValue }) => typeof schema == "string" ? (0, codegen_1._) `{type: ${schema}}` : (0, codegen_1._) `{type: ${schemaValue}}`,
182 function reportTypeError(it) {
183 const cxt = getTypeErrorContext(it);
184 (0, errors_1.reportError)(cxt, typeError);
186 exports.reportTypeError = reportTypeError;
187 function getTypeErrorContext(it) {
188 const { gen, data, schema } = it;
189 const schemaCode = (0, util_1.schemaRefOrVal)(it, schema, "type");
196 schemaValue: schemaCode,
197 parentSchema: schema,
202 //# sourceMappingURL=dataType.js.map