You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					57 lines
				
				1.8 KiB
			
		
		
			
		
	
	
					57 lines
				
				1.8 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								import type {
							 | 
						||
| 
								 | 
							
								  CodeKeywordDefinition,
							 | 
						||
| 
								 | 
							
								  ErrorObject,
							 | 
						||
| 
								 | 
							
								  KeywordErrorDefinition,
							 | 
						||
| 
								 | 
							
								  AnySchema,
							 | 
						||
| 
								 | 
							
								} from "../../types"
							 | 
						||
| 
								 | 
							
								import type {KeywordCxt} from "../../compile/validate"
							 | 
						||
| 
								 | 
							
								import {_, str, not, Name} from "../../compile/codegen"
							 | 
						||
| 
								 | 
							
								import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export type AdditionalItemsError = ErrorObject<"additionalItems", {limit: number}, AnySchema>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const error: KeywordErrorDefinition = {
							 | 
						||
| 
								 | 
							
								  message: ({params: {len}}) => str`must NOT have more than ${len} items`,
							 | 
						||
| 
								 | 
							
								  params: ({params: {len}}) => _`{limit: ${len}}`,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const def: CodeKeywordDefinition = {
							 | 
						||
| 
								 | 
							
								  keyword: "additionalItems" as const,
							 | 
						||
| 
								 | 
							
								  type: "array",
							 | 
						||
| 
								 | 
							
								  schemaType: ["boolean", "object"],
							 | 
						||
| 
								 | 
							
								  before: "uniqueItems",
							 | 
						||
| 
								 | 
							
								  error,
							 | 
						||
| 
								 | 
							
								  code(cxt: KeywordCxt) {
							 | 
						||
| 
								 | 
							
								    const {parentSchema, it} = cxt
							 | 
						||
| 
								 | 
							
								    const {items} = parentSchema
							 | 
						||
| 
								 | 
							
								    if (!Array.isArray(items)) {
							 | 
						||
| 
								 | 
							
								      checkStrictMode(it, '"additionalItems" is ignored when "items" is not an array of schemas')
							 | 
						||
| 
								 | 
							
								      return
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    validateAdditionalItems(cxt, items)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): void {
							 | 
						||
| 
								 | 
							
								  const {gen, schema, data, keyword, it} = cxt
							 | 
						||
| 
								 | 
							
								  it.items = true
							 | 
						||
| 
								 | 
							
								  const len = gen.const("len", _`${data}.length`)
							 | 
						||
| 
								 | 
							
								  if (schema === false) {
							 | 
						||
| 
								 | 
							
								    cxt.setParams({len: items.length})
							 | 
						||
| 
								 | 
							
								    cxt.pass(_`${len} <= ${items.length}`)
							 | 
						||
| 
								 | 
							
								  } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
							 | 
						||
| 
								 | 
							
								    const valid = gen.var("valid", _`${len} <= ${items.length}`) // TODO var
							 | 
						||
| 
								 | 
							
								    gen.if(not(valid), () => validateItems(valid))
							 | 
						||
| 
								 | 
							
								    cxt.ok(valid)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function validateItems(valid: Name): void {
							 | 
						||
| 
								 | 
							
								    gen.forRange("i", items.length, len, (i) => {
							 | 
						||
| 
								 | 
							
								      cxt.subschema({keyword, dataProp: i, dataPropType: Type.Num}, valid)
							 | 
						||
| 
								 | 
							
								      if (!it.allErrors) gen.if(not(valid), () => gen.break())
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default def
							 |