UNPKG

flagpole

Version:

Simple and fast DOM integration, headless or headful browser, and REST API testing framework.

258 lines 9.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const util_1 = require("./util"); const _1 = require("."); const fs_extra_1 = require("fs-extra"); const path_1 = require("path"); function getSchemaPath(schemaName) { let path; if (schemaName.startsWith("@") && schemaName.length > 1) { const schemasFolder = _1.FlagpoleExecution.global.config.getSchemasFolder(); if (!schemasFolder) { throw "Flagpole schema folder path not found."; } fs_extra_1.ensureDirSync(schemasFolder); path = path_1.resolve(schemasFolder, `${schemaName.substr(1)}.json`); } else { path = path_1.resolve(schemaName); } fs_extra_1.ensureFileSync(path); return path; } exports.getSchemaPath = getSchemaPath; function getSchema(schemaName) { const schemaPath = getSchemaPath(schemaName); if (fs_extra_1.existsSync(schemaPath)) { const content = fs_extra_1.readFileSync(schemaPath, "utf8"); return JSON.parse(content); } throw `Schema file ${schemaPath} does not exist`; } exports.getSchema = getSchema; function writeSchema(input, schemaName) { const schema = generateAjvSchema(input); fs_extra_1.writeFileSync(getSchemaPath(schemaName), JSON.stringify(schema, null, 2)); return schema; } exports.writeSchema = writeSchema; function generateAjvSchema(json) { const ajvTypes = [ "string", "number", "boolean", "array", "object", "null", ]; function parseItem(item) { const schema = {}; const myType = util_1.toType(item); if (ajvTypes.includes(myType)) { schema.type = myType; } if (myType === "object") { schema.properties = {}; Object.keys(item).forEach((key) => { schema.properties[key] = parseItem(item[key]); }); } else if (myType == "array") { const arr = item; if (arr.length > 0) { const containsAllObjects = arr.every((row) => { return util_1.toType(row) === "object"; }); if (containsAllObjects) { schema.items = { type: "object", properties: {}, }; arr.forEach((row) => { const rowSchema = parseItem(row); if (rowSchema.properties) { Object.keys(rowSchema.properties).forEach((key) => { const prevItem = schema.items.properties[key]; const newItem = rowSchema.properties[key]; if (!prevItem) { schema.items.properties[key] = { type: newItem.type, }; } else { const prevType = typeof schema.items.properties[key].type === "string" ? [schema.items.properties[key].type] : schema.items.properties[key].type; if (!prevType.includes(newItem.type)) { schema.items.properties[key].type = prevType.concat([ newItem.type, ]); } } }); } }); } else { schema.items = []; item.forEach((value) => { schema.items.push(util_1.toType(value)); }); schema.items = schema.items.filter((v, i, a) => a.indexOf(v) === i); } } } return schema; } return parseItem(json); } exports.generateAjvSchema = generateAjvSchema; class AssertionSchema { constructor() { this._errors = []; this._root = null; } get errors() { return this._errors; } validate(schema, root) { this._errors = []; this._schema = schema; this._root = root; return new Promise((resolve) => { resolve(this._isValid(this._schema, this._root, "$")); }); } _logError(message) { const err = new Error(message); this._errors.push(err); } _matchesType(schema, document, path) { const schemaType = util_1.toType(schema); const docType = util_1.toType(document); if (schemaType != "undefined") { if (schemaType == "string") { if (docType != schema) { this._logError(`typeOf ${path} was ${docType}, which did not match ${schema}`); return false; } } else if (schemaType == "array") { const allowedTypes = schema; if (allowedTypes.indexOf(docType) < 0) { this._logError(`${path} was ${docType}, which did not match ${allowedTypes.join(" | ")}`); return false; } } } return true; } _matchesEnum(schema, document, path) { if (util_1.toType(schema) == "array") { if (schema.indexOf(document) < 0) { this._logError(`${path} value ${document} is not in enum ${schema.join(", ")}`); return false; } } return true; } _matchesPattern(schema, document, path) { const schemaType = util_1.toType(schema); if (schemaType != "undefined" && !new RegExp(schema).test(String(document))) { this._logError(`${path} value ${document} did not match ${String(schema)}`); return false; } return true; } _matchesTest(schema, document, path) { const schemaType = util_1.toType(schema); if (schemaType == "function") { let opts = { path: path, parent: document, root: this._root, }; if (!schema(document, opts)) { this._logError(`${path} did not pass the test`); return false; } } return true; } _matchesItems(schema, document, path) { const schemaType = util_1.toType(schema); const docType = util_1.toType(document); if (schemaType != "undefined") { if (docType != "array") { this._logError(`${path} was not an array, but schema defines items.`); return false; } return document.every((subItem, index) => { if (schemaType == "string" || schemaType == "array") { return this._matchesType(schema, subItem, `${path}[${index}]`); } else if (schemaType == "object") { return this._isValid(schema, subItem, `${path}[${index}]`); } return true; }); } return true; } _matchesProperties(schema, document, path) { const schemaType = util_1.toType(schema); const docType = util_1.toType(document); if (schemaType != "undefined") { if (docType != "object") { this._logError(`${path} was not an object, but schema defines properties.`); return false; } if (schemaType == "string" || schemaType == "array") { return Object.keys(document).every((key) => { return this._matchesType(schema, document[key], `${path}.${key}`); }); } if (schemaType == "object") { return Object.keys(schema).every((key) => { return this._isValid(schema[key], document[key], `${path}.${key}`); }); } } return true; } _isValid(schema, document, path) { const schemaType = util_1.toType(schema); const docType = util_1.toType(document); if (schemaType == "string" || schemaType == "array") { if (!this._matchesType(schema, document, path)) { return false; } } else if (schemaType == "object") { if (!this._matchesType(schema.type, document, path)) { if (!schema.optional || typeof document != "undefined") { return false; } } if (!this._matchesEnum(schema.enum, document, path)) { return false; } if (!this._matchesPattern(schema.matches, document, path)) { return false; } if (!this._matchesTest(schema.test, document, path)) { return false; } if (!this._matchesItems(schema.items, document, path)) { return false; } if (!this._matchesProperties(schema.properties, document, path)) { return false; } } return true; } } exports.AssertionSchema = AssertionSchema; //# sourceMappingURL=assertionschema.js.map