Skip to content

Commit 9f2ffc0

Browse files
authored
Merge pull request #18 from restfulhead/main
chore: release
2 parents 9e7ce46 + af41312 commit 9f2ffc0

17 files changed

+962
-97
lines changed

package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ajv-openapi-request-response-validator/src/ajv-openapi-request-response-validator.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,20 @@ function mapValidatorErrors(validatorErrors: ErrorObject[] | null | undefined, s
6363
title: ajvErr.message ?? ET_VALIDATION,
6464
}
6565

66-
if (ajvErr.schemaPath) {
67-
mappedErr.source = {
68-
pointer: ajvErr.schemaPath,
66+
if (ajvErr.schemaPath || ajvErr.params) {
67+
mappedErr.source = {}
68+
69+
if (ajvErr.schemaPath) {
70+
mappedErr.source.pointer = ajvErr.schemaPath
71+
}
72+
if (ajvErr.params) {
73+
const filteredParams = Object.entries(ajvErr.params).filter(([key]) => key === 'additionalProperty' || key === 'missingProperty')
74+
if (filteredParams.length > 0) {
75+
mappedErr.source.parameter = Object.values(ajvErr.params).join(', ')
76+
}
6977
}
7078
}
79+
7180
mapped.push(mappedErr)
7281
})
7382
return mapped
@@ -320,6 +329,9 @@ export class AjvOpenApiValidator {
320329
if (this.validatorOpts.setAdditionalPropertiesToFalse) {
321330
if (!isValidReferenceObject(schema) && schema.additionalProperties === undefined && schema.discriminator === undefined) {
322331
schema.additionalProperties = false
332+
if (schema.type === undefined) {
333+
schema.type = 'object' // avoid missing type "object" for keyword "additionalProperties" error
334+
}
323335
}
324336
}
325337

packages/ajv-openapi-request-response-validator/src/openapi-validator.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export function unserializeParameters(parameters: Record<string, Primitive>): Re
143143
const lastKeyIndex = splitKey.length - 1
144144

145145
splitKey.forEach((part, index) => {
146-
const cleanPart = part.replace(']', '')
146+
const cleanPart = part.replace(/]/g, '')
147147

148148
if (index === lastKeyIndex) {
149149
target[cleanPart] = value
@@ -156,6 +156,7 @@ export function unserializeParameters(parameters: Record<string, Primitive>): Re
156156
})
157157
}
158158
}
159+
159160
return result
160161
}
161162

packages/ajv-openapi-request-response-validator/test/.eslintrc.js

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ module.exports = {
77
},
88
extends: ["../.eslintrc.js"],
99
rules: {
10+
"@typescript-eslint/no-magic-numbers": "off",
11+
"@typescript-eslint/no-explicit-any": "off",
12+
"no-console": "off",
1013
"@typescript-eslint/naming-convention": "off",
1114
"@typescript-eslint/no-non-null-assertion": "off",
1215
}

packages/ajv-openapi-request-response-validator/test/fixtures/example-api.yaml

+256-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ paths:
7676
schema:
7777
$ref: '#/components/schemas/OneOfExample'
7878

79+
'/one-of-example-list':
80+
get:
81+
responses:
82+
'200':
83+
description: Ok
84+
content:
85+
application/json:
86+
schema:
87+
$ref: '#/components/schemas/OneOfExampleList'
88+
7989
'/all-of-example':
8090
post:
8191
requestBody:
@@ -113,6 +123,86 @@ paths:
113123
application/json:
114124
schema:
115125
$ref: '#/components/schemas/OffsetPagination'
126+
127+
'/multipart':
128+
post:
129+
requestBody:
130+
content:
131+
image/gif:
132+
schema:
133+
type: string
134+
format: binary
135+
multipart/form-data:
136+
schema:
137+
type: object
138+
additionalProperties: true
139+
140+
'/users/{uid}/state/{sid}':
141+
put:
142+
operationId: put-user-state
143+
summary: Upserts a user state
144+
parameters:
145+
- name: uid
146+
in: path
147+
required: true
148+
schema:
149+
type: string
150+
- name: sid
151+
in: path
152+
description: The state id or key
153+
required: true
154+
schema:
155+
type: string
156+
requestBody:
157+
content:
158+
application/json:
159+
schema:
160+
$ref: '#/components/schemas/UserStateValue'
161+
required: true
162+
responses:
163+
'200':
164+
description: OK
165+
patch:
166+
operationId: patch-user-state
167+
summary: Patch a user state
168+
parameters:
169+
- name: uid
170+
in: path
171+
required: true
172+
schema:
173+
type: string
174+
- name: sid
175+
in: path
176+
description: The state id or key
177+
required: true
178+
schema:
179+
type: string
180+
requestBody:
181+
content:
182+
application/json:
183+
schema:
184+
type: array
185+
items:
186+
$ref: '#/components/schemas/PatchUserStateValue'
187+
188+
/webhooks/mytest/{provision}:
189+
post:
190+
parameters:
191+
- name: provision
192+
in: path
193+
required: true
194+
schema:
195+
type: string
196+
requestBody:
197+
content:
198+
application/json:
199+
schema:
200+
$ref: '#/components/schemas/MyTestProvisionResponse'
201+
required: true
202+
responses:
203+
'200':
204+
description: OK
205+
116206
components:
117207
responses:
118208
ResponseError:
@@ -309,6 +399,14 @@ components:
309399
discriminator:
310400
propertyName: objType
311401

402+
OneOfExampleList:
403+
type: object
404+
properties:
405+
items:
406+
type: array
407+
items:
408+
$ref: '#/components/schemas/OneOfExample'
409+
312410
AllOfExample:
313411
type: object
314412
description: Example using allOf
@@ -320,4 +418,161 @@ components:
320418
status:
321419
type: string
322420
enum: [pending, approved, rejected]
323-
421+
422+
UserStateValue:
423+
type: "object"
424+
oneOf:
425+
- $ref: '#/components/schemas/UserStateCoffeeCx'
426+
- $ref: '#/components/schemas/UserUploads'
427+
- $ref: '#/components/schemas/UserStateWidgets'
428+
discriminator:
429+
propertyName: type
430+
UserStateCoffeeCx:
431+
type: object
432+
required:
433+
- type
434+
- enabled
435+
properties:
436+
type:
437+
type: string
438+
enum: [coffeeCx]
439+
enabled:
440+
type: boolean
441+
description: Whether a certain flag, feature, etc. is enabled or not
442+
nullableTest:
443+
type: string
444+
nullable: true
445+
UserUploads:
446+
type: object
447+
required:
448+
- type
449+
- entries
450+
properties:
451+
type:
452+
type: string
453+
enum: [userUploads]
454+
entries:
455+
type: array
456+
maxItems: 1000
457+
items:
458+
$ref: '#/components/schemas/UserUploadEntry'
459+
UserUploadEntry:
460+
type: object
461+
required:
462+
- id
463+
- status
464+
- name
465+
- communityId
466+
properties:
467+
id:
468+
type: string
469+
uploadId:
470+
type: string
471+
status:
472+
type: string
473+
enum:
474+
- ongoing
475+
- completed
476+
- error
477+
name:
478+
type: string
479+
communityId:
480+
type: string
481+
path:
482+
description: >-
483+
path to which the file will be uploaded (e.g. General (default), BCP
484+
Article Files...)
485+
$ref: '#/components/schemas/SafePath'
486+
blobUrl:
487+
type: string
488+
url:
489+
type: string
490+
SafePath:
491+
type: string
492+
pattern: (?=(^(?!.*\.\.\/).+))(?=(^(?!.*\/\/).+))
493+
description: >-
494+
A valid path that matches any sequence of characters except if it
495+
contains '../', '//' (to avoid directory traversal attacks)
496+
maxLength: 255
497+
UserStateWidgets:
498+
type: object
499+
required:
500+
- type
501+
- widgets
502+
properties:
503+
type:
504+
type: string
505+
enum:
506+
- widgets
507+
widgets:
508+
type: array
509+
items:
510+
type: string
511+
oneOf:
512+
- minItems: 4
513+
maxItems: 4
514+
- minItems: 3
515+
maxItems: 3
516+
- minItems: 2
517+
maxItems: 2
518+
AnyValue:
519+
description: Accepts any valid JSON value
520+
additionalProperties: true
521+
oneOf:
522+
- type: string
523+
- type: number
524+
- type: integer
525+
- type: boolean
526+
- type: array
527+
items:
528+
$ref: '#/components/schemas/AnyValue'
529+
- type: object
530+
additionalProperties: true
531+
PatchUserStateValue:
532+
type: object
533+
required:
534+
- op
535+
- path
536+
- value
537+
properties:
538+
op:
539+
type: string
540+
enum:
541+
- replace
542+
- add
543+
- remove
544+
path:
545+
type: string
546+
value:
547+
$ref: '#/components/schemas/AnyValue'
548+
MyTestProvisionResponse:
549+
type: object
550+
required:
551+
- taskId
552+
properties:
553+
taskId:
554+
type: string
555+
stateBag:
556+
type: object
557+
required:
558+
- contentEntryId
559+
properties:
560+
contentEntryId:
561+
type: string
562+
guestUserUid:
563+
type: string
564+
siteInfo:
565+
type: object
566+
required:
567+
- url
568+
properties:
569+
url:
570+
type: string
571+
teamId:
572+
type: string
573+
groupId:
574+
type: string
575+
errorMessage:
576+
description: Reason why the job failed.
577+
type: string
578+

packages/ajv-openapi-request-response-validator/test/fixtures/fail-requestBody-allof-with-schema.js.txt

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ module.exports = {
109109
{
110110
"code": "Validation-additionalProperties",
111111
"source": {
112+
"parameter": "bark",
112113
"pointer": "#/components/schemas/Cat/additionalProperties",
113114
},
114115
"status": 400,

packages/ajv-openapi-request-response-validator/test/fixtures/fail-requestBody-anyof-with-schema.js.txt

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ module.exports = {
7676
{
7777
"code": "Validation-required",
7878
"source": {
79+
"parameter": "age",
7980
"pointer": "#/components/schemas/PetByAge/required",
8081
},
8182
"status": 400,
@@ -84,6 +85,7 @@ module.exports = {
8485
{
8586
"code": "Validation-required",
8687
"source": {
88+
"parameter": "pet_type",
8789
"pointer": "#/components/schemas/PetByType/required",
8890
},
8991
"status": 400,

packages/ajv-openapi-request-response-validator/test/fixtures/fail-requestBody-oneof-with-schema.js.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,6 @@ module.exports = {
6666
},
6767
},
6868
expectedErrors: [
69-
{"code": "Validation-additionalProperties", "source": {"pointer": "#/components/schemas/Cat/additionalProperties"}, "status": 400, "title": "must NOT have additional properties"}, {"code": "Validation-additionalProperties", "source": {"pointer": "#/components/schemas/Dog/additionalProperties"}, "status": 400, "title": "must NOT have additional properties"}, {"code": "Validation-oneOf", "source": {"pointer": "#/oneOf"}, "status": 400, "title": "must match exactly one schema in oneOf"}
69+
{"code": "Validation-additionalProperties", "source": {"pointer": "#/components/schemas/Cat/additionalProperties", "parameter": "breed",}, "status": 400, "title": "must NOT have additional properties"}, {"code": "Validation-additionalProperties", "source": {"pointer": "#/components/schemas/Dog/additionalProperties", "parameter": "age"}, "status": 400, "title": "must NOT have additional properties"}, {"code": "Validation-oneOf", "source": {"pointer": "#/oneOf"}, "status": 400, "title": "must match exactly one schema in oneOf"}
7070
]
7171
};

0 commit comments

Comments
 (0)