functions/pagination-parameters.js (153 lines of code) (raw):

// Check conformance to Azure guidelines for pagination parameters: // - if present, `top` must be an integer, optional, with no default value // - if present, `skip` must be an integer, optional, with a default value of 0 // - if present, `maxpagesize` must be an integer, optional, with no default value // - if present, `filter` must be a string and optional // - if present, `orderby` should be be an array of strings and optional // - if present, `select` should be be an array of strings and optional // - if present, `expand` should be be an array of strings and optional module.exports = (operation, _opts, paths) => { // operation should be a get or post operation if (operation === null || typeof operation !== 'object') { return []; } const path = paths.path || paths.target || []; // If the operation has no parameters, there is nothing to check if (!operation.parameters) { return []; } const errors = []; // Check the top parameter const topIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'top'); if (topIndex !== -1) { const top = operation.parameters[topIndex]; // Improper casing of top will be flagged by the az-parameter-names-convention rule // Check that top is an integer if (top.type !== 'integer') { errors.push({ message: 'top parameter must be type: integer', path: [...path, 'parameters', topIndex, 'type'], }); } // Check that top is optional if (top.required) { errors.push({ message: 'top parameter must be optional', path: [...path, 'parameters', topIndex, 'required'], }); } // Check that top has no default value if (top.default !== undefined) { errors.push({ message: 'top parameter must have no default value', path: [...path, 'parameters', topIndex, 'default'], }); } } // Check skip parameter const skipIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'skip'); if (skipIndex !== -1) { const skip = operation.parameters[skipIndex]; // Improper casing of skip will be flagged by the az-parameter-names-convention rule // Check that skip is an integer if (skip.type !== 'integer') { errors.push({ message: 'skip parameter must be type: integer', path: [...path, 'parameters', skipIndex, 'type'], }); } // Check that skip is optional if (skip.required) { errors.push({ message: 'skip parameter must be optional', path: [...path, 'parameters', skipIndex, 'required'], }); } // Check that skip has a default value of 0 if (skip.default !== 0) { errors.push({ message: 'skip parameter must have a default value of 0', path: [...path, 'parameters', skipIndex, 'default'], }); } } // Check maxpagesize parameter const maxpagesizeIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'maxpagesize'); if (maxpagesizeIndex !== -1) { const maxpagesize = operation.parameters[maxpagesizeIndex]; // Check case convention for maxpagesize if (maxpagesize.name !== 'maxpagesize') { errors.push({ message: 'maxpagesize parameter must be named "maxpagesize" (all lowercase)', path: [...path, 'parameters', maxpagesizeIndex, 'name'], }); } // Check that maxpagesize is an integer if (maxpagesize.type !== 'integer') { errors.push({ message: 'maxpagesize parameter must be type: integer', path: [...path, 'parameters', maxpagesizeIndex, 'type'], }); } // Check that maxpagesize is optional if (maxpagesize.required) { errors.push({ message: 'maxpagesize parameter must be optional', path: [...path, 'parameters', maxpagesizeIndex, 'required'], }); } // Check that maxpagesize has no default value if (maxpagesize.default !== undefined) { errors.push({ message: 'maxpagesize parameter must have no default value', path: [...path, 'parameters', maxpagesizeIndex, 'default'], }); } } // Check filter parameter const filterIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'filter'); if (filterIndex !== -1) { const filter = operation.parameters[filterIndex]; // Improper casing of filter will be flagged by the az-parameter-names-convention rule // Check that filter is a string if (filter.type !== 'string') { errors.push({ message: 'filter parameter must be type: string', path: [...path, 'parameters', filterIndex, 'type'], }); } // Check that filter is optional if (filter.required) { errors.push({ message: 'filter parameter must be optional', path: [...path, 'parameters', filterIndex, 'required'], }); } } // Check orderby parameter const orderbyIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'orderby'); if (orderbyIndex !== -1) { const orderby = operation.parameters[orderbyIndex]; // Check case convention for orderby if (orderby.name !== 'orderby') { errors.push({ message: 'orderby parameter must be named "orderby" (all lowercase)', path: [...path, 'parameters', orderbyIndex, 'name'], }); } // Check that orderby is an array of strings if (orderby.type !== 'array' || orderby.items?.type !== 'string') { errors.push({ message: 'orderby parameter must be type: array with items of type: string', path: [...path, 'parameters', orderbyIndex, 'type'], }); } // Check that orderby is optional if (orderby.required) { errors.push({ message: 'orderby parameter must be optional', path: [...path, 'parameters', orderbyIndex, 'required'], }); } } // Check select parameter const selectIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'select'); if (selectIndex !== -1) { const select = operation.parameters[selectIndex]; // Improper casing of select will be flagged by the az-parameter-names-convention rule // Check that select is an array of strings if (select.type !== 'array' || select.items?.type !== 'string') { errors.push({ message: 'select parameter must be type: array with items of type: string', path: [...path, 'parameters', selectIndex, 'type'], }); } // Check that select is optional if (select.required) { errors.push({ message: 'select parameter must be optional', path: [...path, 'parameters', selectIndex, 'required'], }); } } // Check expand parameter const expandIndex = operation.parameters.findIndex((param) => param.name?.toLowerCase() === 'expand'); if (expandIndex !== -1) { const expand = operation.parameters[expandIndex]; // Improper casing of expand will be flagged by the az-parameter-names-convention rule // Check that expand is an array of strings if (expand.type !== 'array' || expand.items?.type !== 'string') { errors.push({ message: 'expand parameter must be type: array with items of type: string', path: [...path, 'parameters', expandIndex, 'type'], }); } // Check that expand is optional if (expand.required) { errors.push({ message: 'expand parameter must be optional', path: [...path, 'parameters', expandIndex, 'required'], }); } } return errors; };