-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Validator summary function (#101)
- Loading branch information
1 parent
f88e0f6
commit 39fd956
Showing
2 changed files
with
181 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,12 +8,12 @@ info: | |
email: [email protected] | ||
license: | ||
name: MobilityData License | ||
url: https://www.apache.org/licenses/LICENSE-2.0 | ||
url: https://www.apache.org/licenses/LICENSE-2.0 | ||
servers: | ||
- url: https://gbfs-validator.netlify.app/.netlify/functions | ||
description: Production release environment | ||
description: Production release environment | ||
- url: http://localhost:8888/.netlify/functions | ||
description: Local development environment | ||
description: Local development environment | ||
paths: | ||
/validator: | ||
post: | ||
|
@@ -41,7 +41,7 @@ paths: | |
/feed: | ||
post: | ||
summary: Get feed content | ||
description: Get content of all GBFS's files. Usefull to avoid CORS errors. | ||
description: Get content of all GBFS's files. Useful to avoid CORS errors. | ||
requestBody: | ||
content: | ||
application/json: | ||
|
@@ -61,6 +61,29 @@ paths: | |
application/json: | ||
schema: | ||
$ref: '#/components/schemas/Error' | ||
/validator-summary: | ||
post: | ||
summary: Get a summary of the validation results | ||
description: Returns a summary from the validator's response, including grouped error details. | ||
requestBody: | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/ValidatorRequest' | ||
required: true | ||
responses: | ||
'200': | ||
description: Validation summary | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/ValidationSummary' | ||
'500': | ||
description: Error | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/Error' | ||
components: | ||
schemas: | ||
Error: | ||
|
@@ -162,7 +185,7 @@ components: | |
tokenUrl: | ||
type: string | ||
required: | ||
- url | ||
- url | ||
FeedRequest: | ||
required: | ||
- url | ||
|
@@ -183,3 +206,42 @@ components: | |
type: array | ||
items: | ||
type: object | ||
ValidationSummary: | ||
type: object | ||
properties: | ||
summary: | ||
type: object | ||
filesSummary: | ||
type: array | ||
items: | ||
type: object | ||
properties: | ||
required: | ||
type: boolean | ||
exists: | ||
type: boolean | ||
file: | ||
type: string | ||
hasErrors: | ||
type: boolean | ||
errorsCount: | ||
type: number | ||
groupedErrors: | ||
type: array | ||
items: | ||
type: object | ||
properties: | ||
keyword: | ||
type: string | ||
message: | ||
type: string | ||
schemaPath: | ||
type: string | ||
count: | ||
type: number | ||
required: | ||
- required | ||
- exists | ||
- file | ||
- hasErrors | ||
- errorsCount |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
const GBFS = require('gbfs-validator') | ||
|
||
/** @typedef {{ | ||
* summary: { | ||
* validatorVersion: string, | ||
* hasErrors: boolean, | ||
* errorsCount: number, | ||
* version: { | ||
* detected: string, | ||
* validated: string | ||
* } | ||
* filesSummary: [ | ||
* { | ||
* required: boolean, | ||
* exists: boolean, | ||
* hasErrors: boolean, | ||
* file: string, | ||
* errorsCount: number, | ||
* groupedErrors: [ | ||
* { | ||
* keyword: string, | ||
* message: string, | ||
* schemaPath: string, | ||
* count: number | ||
* } | ||
* ] | ||
* } | ||
* ] | ||
* } | ||
* }} Summary | ||
*/ | ||
|
||
/** | ||
* This function returns a summary from the validator's response, stripping out the notices and grouping errors by message, keyword, and schemaPath. | ||
* | ||
* @param validationResult from the GBFS validator class | ||
* @returns { Summary } | ||
*/ | ||
const getSummary = (validationResult) => ( | ||
{ | ||
...validationResult, | ||
files: undefined, | ||
filesSummary: (validationResult.files || []).map(item => ({ | ||
required: item.required, | ||
exists: item.exists, | ||
file: item.file, | ||
hasErrors: item.hasErrors, | ||
errorsCount: item.errorsCount, | ||
groupedErrors: item.exists && item.languages && item.languages[0] && item.languages[0].errors | ||
? groupErrors(item.languages[0].errors) | ||
: [] | ||
})) | ||
} | ||
) | ||
|
||
/** | ||
* Groups errors by keyword, message, and schemaPath, adding a count for each group. | ||
* | ||
* @param errors array of error objects | ||
* @returns {Array} grouped errors with count | ||
*/ | ||
const groupErrors = (errors) => { | ||
const errorMap = {}; | ||
|
||
errors.forEach(error => { | ||
const key = `${error.keyword}-${error.message}-${error.schemaPath}`; | ||
if (errorMap[key]) { | ||
errorMap[key].count += 1; | ||
} else { | ||
errorMap[key] = { | ||
keyword: error.keyword, | ||
message: error.message, | ||
schemaPath: error.schemaPath, | ||
count: 1 | ||
}; | ||
} | ||
}); | ||
|
||
return Object.values(errorMap); | ||
}; | ||
|
||
|
||
/** | ||
* call the callback function with {@link Summary} | ||
*/ | ||
exports.handler = function (event, context, callback) { | ||
let body | ||
|
||
try { | ||
body = JSON.parse(event.body) | ||
} catch (err) { | ||
callback(err, { | ||
statusCode: 500, | ||
body: JSON.stringify(err) | ||
}) | ||
} | ||
|
||
const gbfs = new GBFS(body.url, body.options) | ||
|
||
gbfs | ||
.validation() | ||
.then(result => { | ||
callback(null, { | ||
statusCode: 200, | ||
body: JSON.stringify(getSummary(result)) | ||
}) | ||
}) | ||
.catch(err => { | ||
callback(null, { | ||
statusCode: 500, | ||
body: JSON.stringify(err.message) | ||
}) | ||
}) | ||
} |