Skip to content
This repository has been archived by the owner on Jun 5, 2020. It is now read-only.

Commit

Permalink
feat: validate maxFileSize (#3)
Browse files Browse the repository at this point in the history
* feat: validate `maxFileSize`
* feat: parse file size string like "512KB"
* feat: custom error messages
  • Loading branch information
teppeis committed Apr 8, 2017
1 parent 5f12b53 commit 2457acb
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
29 changes: 27 additions & 2 deletions index.js
@@ -1,6 +1,7 @@
'use strict';

const Ajv = require('ajv');
const bytes = require('bytes');
const jsonSchema = require('./manifest-schema.json');
const validateUrl = require('./src/validate-https-url');

Expand All @@ -11,10 +12,14 @@ const validateUrl = require('./src/validate-https-url');
*/
module.exports = function(json, options) {
options = options || {};
let relativePath = str => true;
if (options.relativePath) {
let relativePath = () => true;
let maxFileSize = () => true;
if (typeof options.relativePath === 'function') {
relativePath = options.relativePath;
}
if (typeof options.maxFileSize === 'function') {
maxFileSize = options.maxFileSize;
}
const ajv = new Ajv({
allErrors: true,
unknownFormats: true,
Expand All @@ -25,6 +30,26 @@ module.exports = function(json, options) {
'relative-path': relativePath,
},
});

ajv.addKeyword('maxFileSize', {
validate: function validateMaxFileSize(schema, data) {
// schema: max file size like "512KB" or 123 (in bytes)
// data: path to the file
const maxBytes = bytes.parse(schema);
const valid = maxFileSize(maxBytes, data);
if (!valid) {
validateMaxFileSize.errors = [{
keyword: 'maxFileSize',
message: `file size should be <= ${schema}`,
params: {
limit: maxBytes,
},
}];
}
return valid;
},
});

const validate = ajv.compile(jsonSchema);
const valid = validate(json);
return {valid: valid, errors: transformErrors(validate.errors)};
Expand Down
7 changes: 5 additions & 2 deletions manifest-schema.json
Expand Up @@ -65,7 +65,8 @@
"type": "string",
"description": "internal only",
"minLength": 1,
"format": "relative-path"
"format": "relative-path",
"maxFileSize": "512KB"
},
"homepage_url": {
"type": "object",
Expand Down Expand Up @@ -113,6 +114,7 @@
"description": "internal only",
"type": "string",
"format": "relative-path",
"maxFileSize": "65535B",
"minLength": 1
},
"js": {
Expand Down Expand Up @@ -149,7 +151,8 @@
"anyOf": [{
"format": "https-url"
}, {
"format": "relative-path"
"format": "relative-path",
"maxFileSize": "512KB"
}],
"maxItems": 30
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
},
"dependencies": {
"ajv": "^4.11.5",
"bytes": "^2.5.0",
"isomorphic-url": "1.0.0-alpha12"
},
"devDependencies": {
Expand Down
37 changes: 37 additions & 0 deletions test/index.js
Expand Up @@ -125,6 +125,43 @@ describe('validator', () => {
assert(actual.errors[1].keyword === 'format');
assert(actual.errors[2].keyword === 'anyOf');
});

describe('maxFileSize', () => {
it('valid file size', () => {
let called = 0;
const actual = validator(json({
}), {
maxFileSize(maxFileSizeInBytes, path) {
assert(maxFileSizeInBytes === 524288);
assert(path === 'image/icon.png');
called++;
return true;
},
});
assert(called === 1);
assert(actual.valid === true);
});

it('invalid file size', () => {
const actual = validator(json({
}), {
maxFileSize(maxFileSizeInBytes, path) {
return false;
},
});
assert(actual.valid === false);
assert(actual.errors.length === 1);
assert.deepEqual(actual.errors[0], {
dataPath: '.icon',
keyword: 'maxFileSize',
message: 'file size should be <= 512KB',
params: {
limit: 524288,
},
schemaPath: '#/properties/icon/maxFileSize',
});
});
});
});

/**
Expand Down
4 changes: 4 additions & 0 deletions yarn.lock
Expand Up @@ -122,6 +122,10 @@ builtin-modules@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"

bytes@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a"

call-matcher@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8"
Expand Down

0 comments on commit 2457acb

Please sign in to comment.