Skip to content

fix: better error handling and more config options #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ function mapValidatorErrors(validatorErrors: ErrorObject[] | null | undefined, s
title: ajvErr.message ?? ET_VALIDATION,
}

if (ajvErr.schemaPath) {
mappedErr.source = {
pointer: ajvErr.schemaPath,
if (ajvErr.schemaPath || ajvErr.params) {
mappedErr.source = {}

if (ajvErr.schemaPath) {
mappedErr.source.pointer = ajvErr.schemaPath
}
if (ajvErr.params) {
const filteredParams = Object.entries(ajvErr.params).filter(([key]) => key === 'additionalProperty' || key === 'missingProperty')
if (filteredParams.length > 0) {
mappedErr.source.parameter = Object.values(ajvErr.params).join(', ')
}
}
}

mapped.push(mappedErr)
})
return mapped
Expand Down Expand Up @@ -320,6 +329,9 @@ export class AjvOpenApiValidator {
if (this.validatorOpts.setAdditionalPropertiesToFalse) {
if (!isValidReferenceObject(schema) && schema.additionalProperties === undefined && schema.discriminator === undefined) {
schema.additionalProperties = false
if (schema.type === undefined) {
schema.type = 'object' // avoid missing type "object" for keyword "additionalProperties" error
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function unserializeParameters(parameters: Record<string, Primitive>): Re
const lastKeyIndex = splitKey.length - 1

splitKey.forEach((part, index) => {
const cleanPart = part.replace(']', '')
const cleanPart = part.replace(/]/g, '')

if (index === lastKeyIndex) {
target[cleanPart] = value
Expand All @@ -156,6 +156,7 @@ export function unserializeParameters(parameters: Record<string, Primitive>): Re
})
}
}

return result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ module.exports = {
},
extends: ["../.eslintrc.js"],
rules: {
"@typescript-eslint/no-magic-numbers": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-non-null-assertion": "off",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ paths:
schema:
$ref: '#/components/schemas/OneOfExample'

'/one-of-example-list':
get:
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/OneOfExampleList'

'/all-of-example':
post:
requestBody:
Expand Down Expand Up @@ -113,6 +123,86 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/OffsetPagination'

'/multipart':
post:
requestBody:
content:
image/gif:
schema:
type: string
format: binary
multipart/form-data:
schema:
type: object
additionalProperties: true

'/users/{uid}/state/{sid}':
put:
operationId: put-user-state
summary: Upserts a user state
parameters:
- name: uid
in: path
required: true
schema:
type: string
- name: sid
in: path
description: The state id or key
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserStateValue'
required: true
responses:
'200':
description: OK
patch:
operationId: patch-user-state
summary: Patch a user state
parameters:
- name: uid
in: path
required: true
schema:
type: string
- name: sid
in: path
description: The state id or key
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PatchUserStateValue'

/webhooks/mytest/{provision}:
post:
parameters:
- name: provision
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MyTestProvisionResponse'
required: true
responses:
'200':
description: OK

components:
responses:
ResponseError:
Expand Down Expand Up @@ -309,6 +399,14 @@ components:
discriminator:
propertyName: objType

OneOfExampleList:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/OneOfExample'

AllOfExample:
type: object
description: Example using allOf
Expand All @@ -320,4 +418,161 @@ components:
status:
type: string
enum: [pending, approved, rejected]


UserStateValue:
type: "object"
oneOf:
- $ref: '#/components/schemas/UserStateCoffeeCx'
- $ref: '#/components/schemas/UserUploads'
- $ref: '#/components/schemas/UserStateWidgets'
discriminator:
propertyName: type
UserStateCoffeeCx:
type: object
required:
- type
- enabled
properties:
type:
type: string
enum: [coffeeCx]
enabled:
type: boolean
description: Whether a certain flag, feature, etc. is enabled or not
nullableTest:
type: string
nullable: true
UserUploads:
type: object
required:
- type
- entries
properties:
type:
type: string
enum: [userUploads]
entries:
type: array
maxItems: 1000
items:
$ref: '#/components/schemas/UserUploadEntry'
UserUploadEntry:
type: object
required:
- id
- status
- name
- communityId
properties:
id:
type: string
uploadId:
type: string
status:
type: string
enum:
- ongoing
- completed
- error
name:
type: string
communityId:
type: string
path:
description: >-
path to which the file will be uploaded (e.g. General (default), BCP
Article Files...)
$ref: '#/components/schemas/SafePath'
blobUrl:
type: string
url:
type: string
SafePath:
type: string
pattern: (?=(^(?!.*\.\.\/).+))(?=(^(?!.*\/\/).+))
description: >-
A valid path that matches any sequence of characters except if it
contains '../', '//' (to avoid directory traversal attacks)
maxLength: 255
UserStateWidgets:
type: object
required:
- type
- widgets
properties:
type:
type: string
enum:
- widgets
widgets:
type: array
items:
type: string
oneOf:
- minItems: 4
maxItems: 4
- minItems: 3
maxItems: 3
- minItems: 2
maxItems: 2
AnyValue:
description: Accepts any valid JSON value
additionalProperties: true
oneOf:
- type: string
- type: number
- type: integer
- type: boolean
- type: array
items:
$ref: '#/components/schemas/AnyValue'
- type: object
additionalProperties: true
PatchUserStateValue:
type: object
required:
- op
- path
- value
properties:
op:
type: string
enum:
- replace
- add
- remove
path:
type: string
value:
$ref: '#/components/schemas/AnyValue'
MyTestProvisionResponse:
type: object
required:
- taskId
properties:
taskId:
type: string
stateBag:
type: object
required:
- contentEntryId
properties:
contentEntryId:
type: string
guestUserUid:
type: string
siteInfo:
type: object
required:
- url
properties:
url:
type: string
teamId:
type: string
groupId:
type: string
errorMessage:
description: Reason why the job failed.
type: string

Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ module.exports = {
{
"code": "Validation-additionalProperties",
"source": {
"parameter": "bark",
"pointer": "#/components/schemas/Cat/additionalProperties",
},
"status": 400,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module.exports = {
{
"code": "Validation-required",
"source": {
"parameter": "age",
"pointer": "#/components/schemas/PetByAge/required",
},
"status": 400,
Expand All @@ -84,6 +85,7 @@ module.exports = {
{
"code": "Validation-required",
"source": {
"parameter": "pet_type",
"pointer": "#/components/schemas/PetByType/required",
},
"status": 400,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ module.exports = {
},
},
expectedErrors: [
{"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"}
{"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"}
]
};
Loading