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
						
					
					
				| 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
 |