2023-10-03 11:14:36 +08:00
"use strict" ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
exports . CodeGen = exports . Name = exports . nil = exports . stringify = exports . str = exports . _ = exports . KeywordCxt = void 0 ;
const context _1 = require ( "./compile/context" ) ;
exports . KeywordCxt = context _1 . default ;
var codegen _1 = require ( "./compile/codegen" ) ;
Object . defineProperty ( exports , "_" , { enumerable : true , get : function ( ) { return codegen _1 . _ ; } } ) ;
Object . defineProperty ( exports , "str" , { enumerable : true , get : function ( ) { return codegen _1 . str ; } } ) ;
Object . defineProperty ( exports , "stringify" , { enumerable : true , get : function ( ) { return codegen _1 . stringify ; } } ) ;
Object . defineProperty ( exports , "nil" , { enumerable : true , get : function ( ) { return codegen _1 . nil ; } } ) ;
Object . defineProperty ( exports , "Name" , { enumerable : true , get : function ( ) { return codegen _1 . Name ; } } ) ;
Object . defineProperty ( exports , "CodeGen" , { enumerable : true , get : function ( ) { return codegen _1 . CodeGen ; } } ) ;
const error _classes _1 = require ( "./compile/error_classes" ) ;
const rules _1 = require ( "./compile/rules" ) ;
const compile _1 = require ( "./compile" ) ;
const codegen _2 = require ( "./compile/codegen" ) ;
const resolve _1 = require ( "./compile/resolve" ) ;
const dataType _1 = require ( "./compile/validate/dataType" ) ;
const util _1 = require ( "./compile/util" ) ;
const $dataRefSchema = require ( "./refs/data.json" ) ;
const META _IGNORE _OPTIONS = [ "removeAdditional" , "useDefaults" , "coerceTypes" ] ;
const EXT _SCOPE _NAMES = new Set ( [
"validate" ,
"serialize" ,
"parse" ,
"wrapper" ,
"root" ,
"schema" ,
"keyword" ,
"pattern" ,
"formats" ,
"validate$data" ,
"func" ,
"obj" ,
"Error" ,
] ) ;
const removedOptions = {
errorDataPath : "" ,
format : "`validateFormats: false` can be used instead." ,
nullable : '"nullable" keyword is supported by default.' ,
jsonPointers : "Deprecated jsPropertySyntax can be used instead." ,
extendRefs : "Deprecated ignoreKeywordsWithRef can be used instead." ,
missingRefs : "Pass empty schema with $id that should be ignored to ajv.addSchema." ,
processCode : "Use option `code: {process: (code, schemaEnv: object) => string}`" ,
sourceCode : "Use option `code: {source: true}`" ,
schemaId : "JSON Schema draft-04 is not supported in Ajv v7." ,
strictDefaults : "It is default now, see option `strict`." ,
strictKeywords : "It is default now, see option `strict`." ,
strictNumbers : "It is default now, see option `strict`." ,
uniqueItems : '"uniqueItems" keyword is always validated.' ,
unknownFormats : "Disable strict mode or pass `true` to `ajv.addFormat` (or `formats` option)." ,
cache : "Map is used as cache, schema object as key." ,
serialize : "Map is used as cache, schema object as key." ,
} ;
const deprecatedOptions = {
ignoreKeywordsWithRef : "" ,
jsPropertySyntax : "" ,
unicode : '"minLength"/"maxLength" account for unicode characters by default.' ,
} ;
function requiredOptions ( o ) {
var _a , _b , _c , _d , _e , _f , _g , _h , _j , _k , _l , _m ;
const strict = ( _a = o . strict ) !== null && _a !== void 0 ? _a : true ;
const strictLog = strict ? "log" : false ;
const _optz = ( _b = o . code ) === null || _b === void 0 ? void 0 : _b . optimize ;
const optimize = _optz === true || _optz === undefined ? 1 : _optz || 0 ;
return {
strict ,
strictTypes : ( _c = o . strictTypes ) !== null && _c !== void 0 ? _c : strictLog ,
strictTuples : ( _d = o . strictTuples ) !== null && _d !== void 0 ? _d : strictLog ,
code : o . code ? { ... o . code , optimize } : { optimize } ,
loopRequired : ( _e = o . loopRequired ) !== null && _e !== void 0 ? _e : Infinity ,
loopEnum : ( _f = o . loopEnum ) !== null && _f !== void 0 ? _f : Infinity ,
meta : ( _g = o . meta ) !== null && _g !== void 0 ? _g : true ,
messages : ( _h = o . messages ) !== null && _h !== void 0 ? _h : true ,
inlineRefs : ( _j = o . inlineRefs ) !== null && _j !== void 0 ? _j : true ,
addUsedSchema : ( _k = o . addUsedSchema ) !== null && _k !== void 0 ? _k : true ,
validateSchema : ( _l = o . validateSchema ) !== null && _l !== void 0 ? _l : true ,
validateFormats : ( _m = o . validateFormats ) !== null && _m !== void 0 ? _m : true ,
} ;
}
class Ajv {
constructor ( opts = { } ) {
this . schemas = { } ;
this . refs = { } ;
this . formats = { } ;
this . _compilations = new Set ( ) ;
this . _loading = { } ;
this . _cache = new Map ( ) ;
opts = this . opts = { ... opts , ... requiredOptions ( opts ) } ;
const { es5 , lines } = this . opts . code ;
this . scope = new codegen _2 . ValueScope ( { scope : { } , prefixes : EXT _SCOPE _NAMES , es5 , lines } ) ;
this . logger = getLogger ( opts . logger ) ;
const formatOpt = opts . validateFormats ;
opts . validateFormats = false ;
this . RULES = rules _1 . getRules ( ) ;
checkOptions . call ( this , removedOptions , opts , "NOT SUPPORTED" ) ;
checkOptions . call ( this , deprecatedOptions , opts , "DEPRECATED" , "warn" ) ;
this . _metaOpts = getMetaSchemaOptions . call ( this ) ;
if ( opts . formats )
addInitialFormats . call ( this ) ;
this . _addVocabularies ( ) ;
this . _addDefaultMetaSchema ( ) ;
if ( opts . keywords )
addInitialKeywords . call ( this , opts . keywords ) ;
if ( typeof opts . meta == "object" )
this . addMetaSchema ( opts . meta ) ;
addInitialSchemas . call ( this ) ;
opts . validateFormats = formatOpt ;
}
_addVocabularies ( ) {
this . addKeyword ( "$async" ) ;
}
_addDefaultMetaSchema ( ) {
const { $data , meta } = this . opts ;
if ( meta && $data )
this . addMetaSchema ( $dataRefSchema , $dataRefSchema . $id , false ) ;
}
defaultMeta ( ) {
const { meta } = this . opts ;
return ( this . opts . defaultMeta = typeof meta == "object" ? meta . $id || meta : undefined ) ;
}
validate ( schemaKeyRef , // key, ref or schema object
data // to be validated
) {
let v ;
if ( typeof schemaKeyRef == "string" ) {
v = this . getSchema ( schemaKeyRef ) ;
if ( ! v )
throw new Error ( ` no schema with key or ref " ${ schemaKeyRef } " ` ) ;
}
else {
v = this . compile ( schemaKeyRef ) ;
}
const valid = v ( data ) ;
if ( ! ( "$async" in v ) )
this . errors = v . errors ;
return valid ;
}
compile ( schema , _meta ) {
const sch = this . _addSchema ( schema , _meta ) ;
return ( sch . validate || this . _compileSchemaEnv ( sch ) ) ;
}
compileAsync ( schema , meta ) {
if ( typeof this . opts . loadSchema != "function" ) {
throw new Error ( "options.loadSchema should be a function" ) ;
}
const { loadSchema } = this . opts ;
return runCompileAsync . call ( this , schema , meta ) ;
async function runCompileAsync ( _schema , _meta ) {
await loadMetaSchema . call ( this , _schema . $schema ) ;
const sch = this . _addSchema ( _schema , _meta ) ;
return sch . validate || _compileAsync . call ( this , sch ) ;
}
async function loadMetaSchema ( $ref ) {
if ( $ref && ! this . getSchema ( $ref ) ) {
await runCompileAsync . call ( this , { $ref } , true ) ;
}
}
async function _compileAsync ( sch ) {
try {
return this . _compileSchemaEnv ( sch ) ;
}
catch ( e ) {
if ( ! ( e instanceof error _classes _1 . MissingRefError ) )
throw e ;
checkLoaded . call ( this , e ) ;
await loadMissingSchema . call ( this , e . missingSchema ) ;
return _compileAsync . call ( this , sch ) ;
}
}
function checkLoaded ( { missingSchema : ref , missingRef } ) {
if ( this . refs [ ref ] ) {
throw new Error ( ` AnySchema ${ ref } is loaded but ${ missingRef } cannot be resolved ` ) ;
}
}
async function loadMissingSchema ( ref ) {
const _schema = await _loadSchema . call ( this , ref ) ;
if ( ! this . refs [ ref ] )
await loadMetaSchema . call ( this , _schema . $schema ) ;
if ( ! this . refs [ ref ] )
this . addSchema ( _schema , ref , meta ) ;
}
async function _loadSchema ( ref ) {
const p = this . _loading [ ref ] ;
if ( p )
return p ;
try {
return await ( this . _loading [ ref ] = loadSchema ( ref ) ) ;
}
finally {
delete this . _loading [ ref ] ;
}
}
}
// Adds schema to the instance
addSchema ( schema , // If array is passed, `key` will be ignored
key , // Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
_meta , // true if schema is a meta-schema. Used internally, addMetaSchema should be used instead.
_validateSchema = this . opts . validateSchema // false to skip schema validation. Used internally, option validateSchema should be used instead.
) {
if ( Array . isArray ( schema ) ) {
for ( const sch of schema )
this . addSchema ( sch , undefined , _meta , _validateSchema ) ;
return this ;
}
let id ;
if ( typeof schema === "object" ) {
id = schema . $id ;
if ( id !== undefined && typeof id != "string" )
throw new Error ( "schema id must be string" ) ;
}
key = resolve _1 . normalizeId ( key || id ) ;
this . _checkUnique ( key ) ;
this . schemas [ key ] = this . _addSchema ( schema , _meta , _validateSchema , true ) ;
return this ;
}
// Add schema that will be used to validate other schemas
// options in META_IGNORE_OPTIONS are alway set to false
addMetaSchema ( schema , key , // schema key
_validateSchema = this . opts . validateSchema // false to skip schema validation, can be used to override validateSchema option for meta-schema
) {
this . addSchema ( schema , key , true , _validateSchema ) ;
return this ;
}
// Validate schema against its meta-schema
validateSchema ( schema , throwOrLogError ) {
if ( typeof schema == "boolean" )
return true ;
let $schema ;
$schema = schema . $schema ;
if ( $schema !== undefined && typeof $schema != "string" ) {
throw new Error ( "$schema must be a string" ) ;
}
$schema = $schema || this . opts . defaultMeta || this . defaultMeta ( ) ;
if ( ! $schema ) {
this . logger . warn ( "meta-schema not available" ) ;
this . errors = null ;
return true ;
}
const valid = this . validate ( $schema , schema ) ;
if ( ! valid && throwOrLogError ) {
const message = "schema is invalid: " + this . errorsText ( ) ;
if ( this . opts . validateSchema === "log" )
this . logger . error ( message ) ;
else
throw new Error ( message ) ;
}
return valid ;
}
// Get compiled schema by `key` or `ref`.
// (`key` that was passed to `addSchema` or full schema reference - `schema.$id` or resolved id)
getSchema ( keyRef ) {
let sch ;
while ( typeof ( sch = getSchEnv . call ( this , keyRef ) ) == "string" )
keyRef = sch ;
if ( sch === undefined ) {
const root = new compile _1 . SchemaEnv ( { schema : { } } ) ;
sch = compile _1 . resolveSchema . call ( this , root , keyRef ) ;
if ( ! sch )
return ;
this . refs [ keyRef ] = sch ;
}
return ( sch . validate || this . _compileSchemaEnv ( sch ) ) ;
}
// Remove cached schema(s).
// If no parameter is passed all schemas but meta-schemas are removed.
// If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
// Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
removeSchema ( schemaKeyRef ) {
if ( schemaKeyRef instanceof RegExp ) {
this . _removeAllSchemas ( this . schemas , schemaKeyRef ) ;
this . _removeAllSchemas ( this . refs , schemaKeyRef ) ;
return this ;
}
switch ( typeof schemaKeyRef ) {
case "undefined" :
this . _removeAllSchemas ( this . schemas ) ;
this . _removeAllSchemas ( this . refs ) ;
this . _cache . clear ( ) ;
return this ;
case "string" : {
const sch = getSchEnv . call ( this , schemaKeyRef ) ;
if ( typeof sch == "object" )
this . _cache . delete ( sch . schema ) ;
delete this . schemas [ schemaKeyRef ] ;
delete this . refs [ schemaKeyRef ] ;
return this ;
}
case "object" : {
const cacheKey = schemaKeyRef ;
this . _cache . delete ( cacheKey ) ;
let id = schemaKeyRef . $id ;
if ( id ) {
id = resolve _1 . normalizeId ( id ) ;
delete this . schemas [ id ] ;
delete this . refs [ id ] ;
}
return this ;
}
default :
throw new Error ( "ajv.removeSchema: invalid parameter" ) ;
}
}
// add "vocabulary" - a collection of keywords
addVocabulary ( definitions ) {
for ( const def of definitions )
this . addKeyword ( def ) ;
return this ;
}
addKeyword ( kwdOrDef , def // deprecated
) {
let keyword ;
if ( typeof kwdOrDef == "string" ) {
keyword = kwdOrDef ;
if ( typeof def == "object" ) {
this . logger . warn ( "these parameters are deprecated, see docs for addKeyword" ) ;
def . keyword = keyword ;
}
}
else if ( typeof kwdOrDef == "object" && def === undefined ) {
def = kwdOrDef ;
keyword = def . keyword ;
if ( Array . isArray ( keyword ) && ! keyword . length ) {
throw new Error ( "addKeywords: keyword must be string or non-empty array" ) ;
}
}
else {
throw new Error ( "invalid addKeywords parameters" ) ;
}
checkKeyword . call ( this , keyword , def ) ;
if ( ! def ) {
util _1 . eachItem ( keyword , ( kwd ) => addRule . call ( this , kwd ) ) ;
return this ;
}
keywordMetaschema . call ( this , def ) ;
const definition = {
... def ,
type : dataType _1 . getJSONTypes ( def . type ) ,
schemaType : dataType _1 . getJSONTypes ( def . schemaType ) ,
} ;
util _1 . eachItem ( keyword , definition . type . length === 0
? ( k ) => addRule . call ( this , k , definition )
: ( k ) => definition . type . forEach ( ( t ) => addRule . call ( this , k , definition , t ) ) ) ;
return this ;
}
getKeyword ( keyword ) {
const rule = this . RULES . all [ keyword ] ;
return typeof rule == "object" ? rule . definition : ! ! rule ;
}
// Remove keyword
removeKeyword ( keyword ) {
// TODO return type should be Ajv
const { RULES } = this ;
delete RULES . keywords [ keyword ] ;
delete RULES . all [ keyword ] ;
for ( const group of RULES . rules ) {
const i = group . rules . findIndex ( ( rule ) => rule . keyword === keyword ) ;
if ( i >= 0 )
group . rules . splice ( i , 1 ) ;
}
return this ;
}
// Add format
addFormat ( name , format ) {
if ( typeof format == "string" )
format = new RegExp ( format ) ;
this . formats [ name ] = format ;
return this ;
}
errorsText ( errors = this . errors , // optional array of validation errors
{ separator = ", " , dataVar = "data" } = { } // optional options with properties `separator` and `dataVar`
) {
if ( ! errors || errors . length === 0 )
return "No errors" ;
return errors
. map ( ( e ) => ` ${ dataVar } ${ e . dataPath } ${ e . message } ` )
. reduce ( ( text , msg ) => text + separator + msg ) ;
}
$dataMetaSchema ( metaSchema , keywordsJsonPointers ) {
const rules = this . RULES . all ;
metaSchema = JSON . parse ( JSON . stringify ( metaSchema ) ) ;
for ( const jsonPointer of keywordsJsonPointers ) {
const segments = jsonPointer . split ( "/" ) . slice ( 1 ) ; // first segment is an empty string
let keywords = metaSchema ;
for ( const seg of segments )
keywords = keywords [ seg ] ;
for ( const key in rules ) {
const rule = rules [ key ] ;
if ( typeof rule != "object" )
continue ;
const { $data } = rule . definition ;
const schema = keywords [ key ] ;
if ( $data && schema )
keywords [ key ] = schemaOrData ( schema ) ;
}
}
return metaSchema ;
}
_removeAllSchemas ( schemas , regex ) {
for ( const keyRef in schemas ) {
const sch = schemas [ keyRef ] ;
if ( ! regex || regex . test ( keyRef ) ) {
if ( typeof sch == "string" ) {
delete schemas [ keyRef ] ;
}
else if ( sch && ! sch . meta ) {
this . _cache . delete ( sch . schema ) ;
delete schemas [ keyRef ] ;
}
}
}
}
_addSchema ( schema , meta , validateSchema = this . opts . validateSchema , addSchema = this . opts . addUsedSchema ) {
if ( typeof schema != "object" ) {
if ( this . opts . jtd )
throw new Error ( "schema must be object" ) ;
else if ( typeof schema != "boolean" )
throw new Error ( "schema must be object or boolean" ) ;
}
let sch = this . _cache . get ( schema ) ;
if ( sch !== undefined )
return sch ;
const localRefs = resolve _1 . getSchemaRefs . call ( this , schema ) ;
sch = new compile _1 . SchemaEnv ( { schema , meta , localRefs } ) ;
this . _cache . set ( sch . schema , sch ) ;
const id = sch . baseId ;
if ( addSchema && ! id . startsWith ( "#" ) ) {
// TODO atm it is allowed to overwrite schemas without id (instead of not adding them)
if ( id )
this . _checkUnique ( id ) ;
this . refs [ id ] = sch ;
}
if ( validateSchema )
this . validateSchema ( schema , true ) ;
return sch ;
}
_checkUnique ( id ) {
if ( this . schemas [ id ] || this . refs [ id ] ) {
throw new Error ( ` schema with key or id " ${ id } " already exists ` ) ;
}
}
_compileSchemaEnv ( sch ) {
if ( sch . meta )
this . _compileMetaSchema ( sch ) ;
else
compile _1 . compileSchema . call ( this , sch ) ;
/* istanbul ignore if */
if ( ! sch . validate )
throw new Error ( "ajv implementation error" ) ;
return sch . validate ;
}
_compileMetaSchema ( sch ) {
const currentOpts = this . opts ;
this . opts = this . _metaOpts ;
try {
compile _1 . compileSchema . call ( this , sch ) ;
}
finally {
this . opts = currentOpts ;
}
}
}
exports . default = Ajv ;
Ajv . ValidationError = error _classes _1 . ValidationError ;
Ajv . MissingRefError = error _classes _1 . MissingRefError ;
function checkOptions ( checkOpts , options , msg , log = "error" ) {
for ( const key in checkOpts ) {
const opt = key ;
if ( opt in options )
this . logger [ log ] ( ` ${ msg } : option ${ key } . ${ checkOpts [ opt ] } ` ) ;
}
}
function getSchEnv ( keyRef ) {
keyRef = resolve _1 . normalizeId ( keyRef ) ; // TODO tests fail without this line
return this . schemas [ keyRef ] || this . refs [ keyRef ] ;
}
function addInitialSchemas ( ) {
const optsSchemas = this . opts . schemas ;
if ( ! optsSchemas )
return ;
if ( Array . isArray ( optsSchemas ) )
this . addSchema ( optsSchemas ) ;
else
for ( const key in optsSchemas )
this . addSchema ( optsSchemas [ key ] , key ) ;
}
function addInitialFormats ( ) {
for ( const name in this . opts . formats ) {
const format = this . opts . formats [ name ] ;
if ( format )
this . addFormat ( name , format ) ;
}
}
function addInitialKeywords ( defs ) {
if ( Array . isArray ( defs ) ) {
this . addVocabulary ( defs ) ;
return ;
}
this . logger . warn ( "keywords option as map is deprecated, pass array" ) ;
for ( const keyword in defs ) {
const def = defs [ keyword ] ;
if ( ! def . keyword )
def . keyword = keyword ;
this . addKeyword ( def ) ;
}
}
function getMetaSchemaOptions ( ) {
const metaOpts = { ... this . opts } ;
for ( const opt of META _IGNORE _OPTIONS )
delete metaOpts [ opt ] ;
return metaOpts ;
}
const noLogs = { log ( ) { } , warn ( ) { } , error ( ) { } } ;
function getLogger ( logger ) {
if ( logger === false )
return noLogs ;
if ( logger === undefined )
return console ;
if ( logger . log && logger . warn && logger . error )
return logger ;
throw new Error ( "logger must implement log, warn and error methods" ) ;
}
const KEYWORD _NAME = /^[a-z_$][a-z0-9_$:-]*$/i ;
function checkKeyword ( keyword , def ) {
const { RULES } = this ;
util _1 . eachItem ( keyword , ( kwd ) => {
if ( RULES . keywords [ kwd ] )
throw new Error ( ` Keyword ${ kwd } is already defined ` ) ;
if ( ! KEYWORD _NAME . test ( kwd ) )
throw new Error ( ` Keyword ${ kwd } has invalid name ` ) ;
} ) ;
if ( ! def )
return ;
if ( def . $data && ! ( "code" in def || "validate" in def ) ) {
throw new Error ( '$data keyword must have "code" or "validate" function' ) ;
}
}
function addRule ( keyword , definition , dataType ) {
var _a ;
const post = definition === null || definition === void 0 ? void 0 : definition . post ;
if ( dataType && post )
throw new Error ( 'keyword with "post" flag cannot have "type"' ) ;
const { RULES } = this ;
let ruleGroup = post ? RULES . post : RULES . rules . find ( ( { type : t } ) => t === dataType ) ;
if ( ! ruleGroup ) {
ruleGroup = { type : dataType , rules : [ ] } ;
RULES . rules . push ( ruleGroup ) ;
}
RULES . keywords [ keyword ] = true ;
if ( ! definition )
return ;
const rule = {
keyword ,
definition : {
... definition ,
type : dataType _1 . getJSONTypes ( definition . type ) ,
schemaType : dataType _1 . getJSONTypes ( definition . schemaType ) ,
} ,
} ;
if ( definition . before )
addBeforeRule . call ( this , ruleGroup , rule , definition . before ) ;
else
ruleGroup . rules . push ( rule ) ;
RULES . all [ keyword ] = rule ;
( _a = definition . implements ) === null || _a === void 0 ? void 0 : _a . forEach ( ( kwd ) => this . addKeyword ( kwd ) ) ;
}
function addBeforeRule ( ruleGroup , rule , before ) {
const i = ruleGroup . rules . findIndex ( ( _rule ) => _rule . keyword === before ) ;
if ( i >= 0 ) {
ruleGroup . rules . splice ( i , 0 , rule ) ;
}
else {
ruleGroup . rules . push ( rule ) ;
this . logger . warn ( ` rule ${ before } is not defined ` ) ;
}
}
function keywordMetaschema ( def ) {
let { metaSchema } = def ;
if ( metaSchema === undefined )
return ;
if ( def . $data && this . opts . $data )
metaSchema = schemaOrData ( metaSchema ) ;
def . validateSchema = this . compile ( metaSchema , true ) ;
}
const $dataRef = {
$ref : "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#" ,
} ;
function schemaOrData ( schema ) {
return { anyOf : [ schema , $dataRef ] } ;
}
2023-09-25 15:58:56 +08:00
//# sourceMappingURL=core.js.map