Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
parameterLocation: ParameterLocation,
parameterRequired: boolean,
propNameToFilter: string,
allowTypeCoercion: boolean
) : ValidatorFunction {
const {openApiDoc, jsonPointer: schemaPtr} = schemaContext;
const customFormats = schemaContext.options.customFormats;
let schema: any = jsonSchema.extractSchema(openApiDoc, schemaPtr);
_filterRequiredProperties(schema, propNameToFilter);
removeExamples(schema);
// TODO: Should we do this? Or should we rely on the schema being correct in the first place?
// _fixNullables(schema);
// So that we can replace the "root" value of the schema using ajv's type coercion...
traveseSchema(schema, node => {
if(node.$ref) {
node.$ref = `#/properties/value/${node.$ref.slice(1)}`;
}
});
schema = {
type: 'object',
properties: {
value: schema
}
};
const ajv = new Ajv({
useDefaults: true,
coerceTypes: allowTypeCoercion ? 'array' : false,
removeAdditional: allowTypeCoercion ? 'failing' : false,
jsonPointers: true,
function removeExamples(schema: any) {
// ajv will print "schema id ignored" to stdout if an example contains a filed
// named "id", so just axe all the examples.
traveseSchema(schema, (childSchema: any) => {
if(childSchema.example) {
delete childSchema.example;
}
});
}
) : JSONSchema4 | JSONSchema6 {
const subtreeObject = refResolver(subtreeRef);
if(!subtreeObject) {
throw new Error(`Could not find ref ${subtreeRef}`);
}
const result = ld.cloneDeep(subtreeObject);
const ctx = context || {
result: result,
replaced: {},
schemaCount: 0,
rootSubtreeRef: subtreeRef
};
traveseSchema(result, (
schema: any
) => {
if(schema.$ref && typeof(schema.$ref) === 'string') {
if(ctx.replaced[schema.$ref]) {
schema.$ref = ctx.replaced[schema.$ref];
} else if(jsonPaths.jsonPointerStartsWith(schema.$ref, ctx.rootSubtreeRef + '/')) {
ctx.replaced[schema.$ref] = jsonPaths.jsonPointerStripPrefix(schema.$ref, ctx.rootSubtreeRef);
schema.$ref = ctx.replaced[schema.$ref];
} else if(!refResolver(schema.$ref)) {
// Don't know how to resolve this ref
if(!options.skipUnknownRefs) {
throw new Error(`Can't find ref ${schema.$ref}`);
}
} else {
ctx.result.definitions = ctx.result.definitions || {};
const util = require('./util');
const traverse = require('json-schema-traverse');
const path = require('path');
traverse.skipKeywords.discriminator = true;
const folders = util.getFolders();
const stats = [];
const USAGE = {
boolSchema: 'boolean schema',
patternPropsAndProps: 'patternProperties and properties',
additionalPropsSchema: 'additionalProperties is schema',
additionalPropsSchemaAndProps: 'additionalProperties schema and properties',
itemsArray: 'items is array of schemas'
};
setUsageStats();
for (const folder of folders) {
const folderName = path.basename(folder);
if (folderName.indexOf('.template') === 0) continue;
export function _filterRequiredProperties(schema: any, propNameToFilter: string) {
traveseSchema(schema, (childSchema: any) => {
if(childSchema.properties && schema.required) {
for(const propName of Object.keys(childSchema.properties)) {
const prop = childSchema.properties[propName];
const resolvedProp = resolveRef(schema, prop);
if(resolvedProp[propNameToFilter]) {
schema.required = schema.required.filter((r: string) => r !== propName);
}
}
}
});
}
async _validateAssetsAsync(data: any) {
let assets = [];
traverse(this.schema, { allKeys: true }, (subSchema, jsonPointer, a, b, c, d, property) => {
if (property && subSchema.meta && subSchema.meta.asset) {
const fieldPath = schemaPointerToFieldPath(jsonPointer);
assets.push({
fieldPath,
data: _.get(data, fieldPath),
meta: subSchema.meta,
});
}
});
await Promise.all(assets.map(this._validateAssetAsync.bind(this)));
}
async _validateAssetsAsync(data: any) {
let assets: AssetField[] = [];
traverse(this.schema, { allKeys: true }, (subSchema, jsonPointer, a, b, c, d, property) => {
if (property && subSchema.meta && subSchema.meta.asset) {
const fieldPath = schemaPointerToFieldPath(jsonPointer);
assets.push({
fieldPath,
data: _.get(data, fieldPath),
meta: subSchema.meta,
});
}
});
await Promise.all(assets.map(this._validateAssetAsync.bind(this)));
}