Skip to content

Commit

Permalink
feat: Validator summary function (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgamez authored Aug 14, 2024
1 parent f88e0f6 commit 39fd956
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 5 deletions.
72 changes: 67 additions & 5 deletions docs/gbfs-validator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -162,7 +185,7 @@ components:
tokenUrl:
type: string
required:
- url
- url
FeedRequest:
required:
- url
Expand All @@ -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
114 changes: 114 additions & 0 deletions functions/validator-summary.js
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)
})
})
}

0 comments on commit 39fd956

Please sign in to comment.