@ellipticltd/aml-utils 0.16.27 → 0.16.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +11 -43
  2. package/lib/errors/errors.js +19 -30
  3. package/lib/errors/errors.js.map +1 -0
  4. package/{dist → lib}/file-parser/errors.js +1 -1
  5. package/lib/file-parser/errors.js.map +1 -0
  6. package/{dist → lib}/file-parser/file-parser.d.ts +2 -4
  7. package/lib/file-parser/file-parser.js +59 -0
  8. package/lib/file-parser/file-parser.js.map +1 -0
  9. package/{dist/structured-file-parser → lib/file-parser}/parse-row.js +2 -1
  10. package/lib/file-parser/parse-row.js.map +1 -0
  11. package/{dist/file-parser/sanitzeRows.d.ts → lib/file-parser/sanitizeRows.d.ts} +3 -1
  12. package/lib/file-parser/sanitizeRows.js +15 -0
  13. package/lib/file-parser/sanitizeRows.js.map +1 -0
  14. package/lib/formatting/formatting.js +11 -12
  15. package/lib/formatting/formatting.js.map +1 -0
  16. package/{dist → lib}/index.d.ts +1 -1
  17. package/lib/index.js +21 -0
  18. package/lib/index.js.map +1 -0
  19. package/lib/middleware/middleware.js +14 -17
  20. package/lib/middleware/middleware.js.map +1 -0
  21. package/lib/orm-helpers/ormHelpers.js +12 -13
  22. package/lib/orm-helpers/ormHelpers.js.map +1 -0
  23. package/{dist → lib}/structured-file-parser/errors.js +1 -0
  24. package/lib/structured-file-parser/errors.js.map +1 -0
  25. package/{dist/file-parser → lib/structured-file-parser}/parse-row.js +2 -1
  26. package/lib/structured-file-parser/parse-row.js.map +1 -0
  27. package/{dist → lib}/structured-file-parser/sanitize-rows.js +3 -4
  28. package/lib/structured-file-parser/sanitize-rows.js.map +1 -0
  29. package/{dist → lib}/structured-file-parser/structured-file-parser.d.ts +2 -2
  30. package/lib/structured-file-parser/structured-file-parser.js +95 -0
  31. package/lib/structured-file-parser/structured-file-parser.js.map +1 -0
  32. package/{dist → lib}/types/types.d.ts +0 -6
  33. package/lib/types/types.js +191 -203
  34. package/lib/types/types.js.map +1 -0
  35. package/{dist → lib}/validations/validations.d.ts +133 -82
  36. package/lib/validations/validations.js +673 -458
  37. package/lib/validations/validations.js.map +1 -0
  38. package/package.json +7 -61
  39. package/.circleci/config.yml +0 -87
  40. package/.claude/settings.local.json +0 -7
  41. package/.eslintrc +0 -45
  42. package/.huskyrc +0 -5
  43. package/.mocharc.json +0 -3
  44. package/.nvmrc +0 -1
  45. package/.nycrc.json +0 -11
  46. package/.releaserc.json +0 -18
  47. package/.snyk +0 -12
  48. package/codecov.yml +0 -29
  49. package/commitlint.config.js +0 -1
  50. package/dist/errors/errors.js +0 -42
  51. package/dist/errors/errors.spec.d.ts +0 -1
  52. package/dist/errors/errors.spec.js +0 -23
  53. package/dist/file-parser/__tests/file-parser.spec.d.ts +0 -1
  54. package/dist/file-parser/__tests/file-parser.spec.js +0 -109
  55. package/dist/file-parser/__tests/parse-row.spec.d.ts +0 -1
  56. package/dist/file-parser/__tests/parse-row.spec.js +0 -29
  57. package/dist/file-parser/__tests/sanitize-rows.spec.d.ts +0 -1
  58. package/dist/file-parser/__tests/sanitize-rows.spec.js +0 -78
  59. package/dist/file-parser/file-parser.js +0 -55
  60. package/dist/file-parser/sanitzeRows.js +0 -18
  61. package/dist/formatting/formatting.js +0 -17
  62. package/dist/formatting/formatting.spec.d.ts +0 -1
  63. package/dist/formatting/formatting.spec.js +0 -37
  64. package/dist/index.js +0 -22
  65. package/dist/middleware/middleware.js +0 -22
  66. package/dist/orm-helpers/ormHelpers.js +0 -17
  67. package/dist/orm-helpers/ormHelpers.spec.d.ts +0 -1
  68. package/dist/orm-helpers/ormHelpers.spec.js +0 -38
  69. package/dist/structured-file-parser/structured-file-parser.js +0 -98
  70. package/dist/types/types.js +0 -203
  71. package/dist/validations/validations.js +0 -470
  72. package/dist/validations/validations.spec.d.ts +0 -1
  73. package/dist/validations/validations.spec.js +0 -463
  74. package/lib/errors/errors.spec.js +0 -37
  75. package/lib/file-parser/__tests/file-parser.spec.js +0 -107
  76. package/lib/file-parser/__tests/parse-row.spec.js +0 -35
  77. package/lib/file-parser/__tests/sanitize-rows.spec.js +0 -88
  78. package/lib/file-parser/errors.ts +0 -7
  79. package/lib/file-parser/file-parser.ts +0 -84
  80. package/lib/file-parser/parse-row.ts +0 -52
  81. package/lib/file-parser/sanitzeRows.ts +0 -32
  82. package/lib/formatting/formatting.spec.js +0 -45
  83. package/lib/index.ts +0 -19
  84. package/lib/orm-helpers/ormHelpers.spec.js +0 -41
  85. package/lib/structured-file-parser/errors.ts +0 -25
  86. package/lib/structured-file-parser/parse-row.ts +0 -52
  87. package/lib/structured-file-parser/sanitize-rows.ts +0 -24
  88. package/lib/structured-file-parser/structured-file-parser.ts +0 -155
  89. package/lib/validations/validations.spec.js +0 -603
  90. package/tsconfig.json +0 -26
  91. /package/{dist → lib}/errors/errors.d.ts +0 -0
  92. /package/{dist → lib}/file-parser/errors.d.ts +0 -0
  93. /package/{dist → lib}/file-parser/parse-row.d.ts +0 -0
  94. /package/{dist → lib}/formatting/formatting.d.ts +0 -0
  95. /package/{dist → lib}/middleware/middleware.d.ts +0 -0
  96. /package/{dist → lib}/orm-helpers/ormHelpers.d.ts +0 -0
  97. /package/{dist → lib}/structured-file-parser/errors.d.ts +0 -0
  98. /package/{dist → lib}/structured-file-parser/parse-row.d.ts +0 -0
  99. /package/{dist → lib}/structured-file-parser/sanitize-rows.d.ts +0 -0
@@ -1,78 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const chai_1 = require("chai");
7
- const sinon_1 = __importDefault(require("sinon"));
8
- const sanitzeRows_1 = __importDefault(require("../sanitzeRows"));
9
- describe('sanitize-rows', () => {
10
- it('should remove empty rows at the start of the array', () => {
11
- const input = [
12
- ['', '', ''],
13
- ['this', 'is', 'valid'],
14
- ['this', 'is', 'valid'],
15
- ];
16
- const result = sanitzeRows_1.default(input, () => ({
17
- isValid: true,
18
- }));
19
- chai_1.expect(result).to.have.length(2);
20
- });
21
- it('should remove empty rows at the end of the array', () => {
22
- const input = [
23
- ['this', 'is', 'valid'],
24
- ['this', 'is', 'valid'],
25
- ['', '', ''],
26
- ];
27
- const result = sanitzeRows_1.default(input, () => ({
28
- isValid: true,
29
- }));
30
- chai_1.expect(result).to.have.length(2);
31
- });
32
- it('should remove empty rows at the start and end of the array', () => {
33
- const input = [
34
- ['', '', ''],
35
- ['', '', ''],
36
- ['', '', ''],
37
- ['this', 'is', 'valid'],
38
- ['this', 'is', 'valid'],
39
- ['', '', ''],
40
- ['', '', ''],
41
- ['', '', ''],
42
- ];
43
- const result = sanitzeRows_1.default(input, () => ({
44
- isValid: true,
45
- }));
46
- chai_1.expect(result).to.have.length(2);
47
- });
48
- it('should remove the first row if it is not empty and not valid', () => {
49
- const input = [
50
- ['', '', ''],
51
- ['this', 'is', 'invalid'],
52
- ['this', 'is', 'valid'],
53
- ['this', 'is', 'valid'],
54
- ['', '', ''],
55
- ['', '', ''],
56
- ['', '', ''],
57
- ];
58
- const returnsFalseOnce = sinon_1.default.stub();
59
- returnsFalseOnce.returns(true);
60
- returnsFalseOnce.onFirstCall().returns(false);
61
- const result = sanitzeRows_1.default(input, returnsFalseOnce);
62
- chai_1.expect(result).to.have.length(2);
63
- });
64
- it('should allow rows with some empty values', () => {
65
- const input = [
66
- ['this', 'is', 'invalid'],
67
- ['this', 'is', 'valid'],
68
- ['this', 'is', 'valid'],
69
- ['valid', '', ''],
70
- ['', '', ''],
71
- ['', '', ''],
72
- ];
73
- const result = sanitzeRows_1.default(input, () => ({
74
- isValid: true,
75
- }));
76
- chai_1.expect(result).to.have.length(4);
77
- });
78
- });
@@ -1,55 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const parse_row_1 = __importDefault(require("./parse-row"));
7
- const errors_1 = require("./errors");
8
- const sanitzeRows_1 = __importDefault(require("./sanitzeRows"));
9
- function chunk(array, size) {
10
- if (!array.length) {
11
- return [];
12
- }
13
- const head = array.slice(0, size);
14
- const tail = array.slice(size);
15
- return [head, ...chunk(tail, size)];
16
- }
17
- async function processChunk(parsedRows, dependencies) {
18
- const { processRow } = dependencies;
19
- return new Promise((resolve, reject) => {
20
- setTimeout(() => {
21
- try {
22
- const processedRows = parsedRows.map(processRow);
23
- resolve(processedRows);
24
- }
25
- catch (ex) {
26
- reject(ex);
27
- }
28
- }, 0);
29
- });
30
- }
31
- async function parseFile(fileContent, maxRows, dependencies) {
32
- const { processRow } = dependencies;
33
- if (fileContent === 'invalidFileType') {
34
- throw Error('Invalid file type');
35
- }
36
- const rows = fileContent.split('\n');
37
- const parsedRows = rows.map(parse_row_1.default);
38
- const sanitizedRows = sanitzeRows_1.default(parsedRows, processRow);
39
- if (sanitizedRows.length > maxRows) {
40
- throw new errors_1.TooManyRowsError();
41
- }
42
- if (sanitizedRows.length === 0) {
43
- throw new Error('No rows');
44
- }
45
- const parsedRowChunks = chunk(sanitizedRows, 30);
46
- let results = [];
47
- // eslint-disable-next-line no-restricted-syntax
48
- for (const currentRowChunk of parsedRowChunks) {
49
- // eslint-disable-next-line no-await-in-loop
50
- const chunkResult = await processChunk(currentRowChunk, dependencies);
51
- results = results.concat(chunkResult);
52
- }
53
- return results;
54
- }
55
- exports.default = parseFile;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const sensicalRowCheck = (cells) => (cells.some((cell) => !!cell));
4
- function sanitizeRows(parsedRows, processRow) {
5
- const firstSensicalRowIndex = parsedRows
6
- .findIndex(sensicalRowCheck);
7
- const lastSensicalRowIndex = [...parsedRows]
8
- .reverse()
9
- .findIndex(sensicalRowCheck);
10
- const sanitizedRows = parsedRows
11
- .splice(firstSensicalRowIndex, parsedRows.length - firstSensicalRowIndex - lastSensicalRowIndex);
12
- const firstRow = processRow(sanitizedRows[0]);
13
- if (firstRow.isValid) {
14
- return sanitizedRows;
15
- }
16
- return sanitizedRows.splice(1);
17
- }
18
- exports.default = sanitizeRows;
@@ -1,17 +0,0 @@
1
- "use strict";
2
- const _ = require('lodash');
3
- const rethrowError = (fnName, e) => {
4
- let formattedError;
5
- if (_.isPlainObject(e.error) || _.isArray(e.error)) {
6
- formattedError = `\n${JSON.stringify(e.error, null, 2)}`;
7
- }
8
- else {
9
- formattedError = e.error;
10
- }
11
- return `${fnName} - ${e.name}: ${e.statusCode} - ${formattedError}`;
12
- };
13
- const sqlEscapeWildcard = (str) => str.replace(/_|%|\\/g, (x) => `\\${x}`);
14
- module.exports = {
15
- rethrowError,
16
- sqlEscapeWildcard,
17
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,37 +0,0 @@
1
- "use strict";
2
- const chai = require('chai');
3
- const { sqlEscapeWildcard, rethrowError } = require('./formatting');
4
- const { expect } = chai;
5
- describe('formatting.sqlEscapeWildcard', () => {
6
- describe('when passed an empty string', () => {
7
- it('returns an empty string', () => sqlEscapeWildcard('').should.equal(''));
8
- });
9
- describe('when passed a string with no sql wildcards', () => {
10
- it('returns the same string', () => {
11
- const str = 'foo bar';
12
- return sqlEscapeWildcard(str).should.equal(str);
13
- });
14
- });
15
- return describe('when passed a string with sql wildcards', () => {
16
- it('returns the string with \\ % _ escaped', () => {
17
- const str = 'foo\\dfs_erwr%rewr';
18
- return sqlEscapeWildcard(str).should.equal('foo\\\\dfs\\_erwr\\%rewr');
19
- });
20
- });
21
- });
22
- describe('rethrowError', () => {
23
- it('returns an error when given a string', () => rethrowError('myFunc', { error: 'Oh dear, myFunc is broken' })
24
- .should.equal('myFunc - undefined: undefined - Oh dear, myFunc is broken'));
25
- it('returns an error when passed an error object', () => rethrowError('myFunc', {
26
- name: "I'm a teapot",
27
- statusCode: 418,
28
- error: "I'm a little teapot, short and stout",
29
- }).should.equal("myFunc - I'm a teapot: 418 - I'm a little teapot, short and stout"));
30
- it('accepts an array containing an error', () => {
31
- const thrownError = rethrowError('myFunc', {
32
- error: ["I'm a teapot", 418, "I'm a little teapot, short and stout"],
33
- });
34
- const expected = JSON.stringify('myFunc - undefined: undefined - \n[\n "I\'m a teapot",\n 418,\n "I\'m a little teapot, short and stout"\n]');
35
- expect(JSON.stringify(thrownError)).to.equal(expected);
36
- });
37
- });
package/dist/index.js DELETED
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ormHelpers = exports.middleware = exports.structuredFileParser = exports.fileParser = exports.formatting = exports.errors = exports.validations = exports.types = void 0;
7
- const types_1 = __importDefault(require("./types/types"));
8
- exports.types = types_1.default;
9
- const validations_1 = __importDefault(require("./validations/validations"));
10
- exports.validations = validations_1.default;
11
- const errors_1 = __importDefault(require("./errors/errors"));
12
- exports.errors = errors_1.default;
13
- const formatting_1 = __importDefault(require("./formatting/formatting"));
14
- exports.formatting = formatting_1.default;
15
- const middleware_1 = __importDefault(require("./middleware/middleware"));
16
- exports.middleware = middleware_1.default;
17
- const ormHelpers_1 = __importDefault(require("./orm-helpers/ormHelpers"));
18
- exports.ormHelpers = ormHelpers_1.default;
19
- const file_parser_1 = __importDefault(require("./file-parser/file-parser"));
20
- exports.fileParser = file_parser_1.default;
21
- const structured_file_parser_1 = __importDefault(require("./structured-file-parser/structured-file-parser"));
22
- exports.structuredFileParser = structured_file_parser_1.default;
@@ -1,22 +0,0 @@
1
- "use strict";
2
- const T = require('../types/types');
3
- const ensureType = (type) => (req, res, next, id, name) => {
4
- let error;
5
- try {
6
- T.ensureType(type, id, `Invalid ${name}`);
7
- return next();
8
- }
9
- catch (error1) {
10
- error = error1;
11
- return next(error);
12
- }
13
- };
14
- const ensureUUID = ensureType('UUID');
15
- const ensureHex32 = ensureType('Hex32');
16
- const ensureInteger = ensureType('IntString');
17
- module.exports = {
18
- ensureType,
19
- ensureUUID,
20
- ensureHex32,
21
- ensureInteger,
22
- };
@@ -1,17 +0,0 @@
1
- "use strict";
2
- const _ = require('lodash');
3
- const includeNested = (orm, models) => _.map(_.toPairs(models), (arg) => {
4
- const [modelName, inclusion] = arg;
5
- const include = includeNested(orm, inclusion);
6
- const model = orm[modelName];
7
- if (_.isEmpty(include)) {
8
- return model;
9
- }
10
- return {
11
- model,
12
- include,
13
- };
14
- });
15
- module.exports = {
16
- includeNested,
17
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,38 +0,0 @@
1
- "use strict";
2
- const { includeNested } = require('./ormHelpers');
3
- describe('ormIncludeNested', () => {
4
- const orm = {
5
- a: 'a',
6
- b: 'b',
7
- c: 'c',
8
- d: 'd',
9
- };
10
- describe('when passed an empty object', () => {
11
- it('returns an empty array', () => includeNested(orm, {}).should.deep.equal([]));
12
- });
13
- describe('when passed an object with no inclusions', () => {
14
- it('returns an array of just the key', () => includeNested(orm, {
15
- a: {},
16
- }).should.deep.equal(['a']));
17
- });
18
- describe('when passed a hierarchy of inclusions', () => {
19
- it('should nest them in sequelize style', () => includeNested(orm, {
20
- a: {
21
- b: {
22
- c: {},
23
- d: {},
24
- },
25
- },
26
- }).should.deep.equal([
27
- {
28
- model: 'a',
29
- include: [
30
- {
31
- model: 'b',
32
- include: ['c', 'd'],
33
- },
34
- ],
35
- },
36
- ]));
37
- });
38
- });
@@ -1,98 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isHeaderRowValid = exports.hasHeaderRow = void 0;
7
- /* eslint-disable no-await-in-loop */
8
- /* eslint-disable no-restricted-syntax */
9
- const parse_row_1 = __importDefault(require("./parse-row"));
10
- const errors_1 = require("./errors");
11
- const sanitize_rows_1 = __importDefault(require("./sanitize-rows"));
12
- function chunk(array, size) {
13
- if (!array.length) {
14
- return [];
15
- }
16
- const head = array.slice(0, size);
17
- const tail = array.slice(size);
18
- return [head, ...chunk(tail, size)];
19
- }
20
- async function processChunk(parsedRows, dependencies) {
21
- const { processRow, headers } = dependencies;
22
- // @ts-ignore
23
- return new Promise((resolve, reject) => {
24
- setTimeout(() => {
25
- try {
26
- const processedRows = parsedRows.map((row) => processRow(row, headers));
27
- resolve(processedRows);
28
- }
29
- catch (ex) {
30
- // @ts-ignore
31
- reject(ex);
32
- }
33
- }, 0);
34
- });
35
- }
36
- // a row is said to contain headers if two valid header names are present
37
- exports.hasHeaderRow = (rows, requiredHeaderNames) => {
38
- const firstRow = rows[0];
39
- if (!firstRow) {
40
- return false;
41
- }
42
- const foundIndex = firstRow.findIndex((value) => requiredHeaderNames.includes(value.toLowerCase()));
43
- if (foundIndex < 0) {
44
- return false;
45
- }
46
- const containsSecondHeader = firstRow
47
- .filter((_val, i) => i !== foundIndex)
48
- .some((value) => requiredHeaderNames.includes(value.toLowerCase()));
49
- return containsSecondHeader;
50
- };
51
- exports.isHeaderRowValid = (rows, requiredHeaderNames) => {
52
- const firstRow = rows[0];
53
- if (!firstRow) {
54
- return false;
55
- }
56
- return (requiredHeaderNames.every((header) => firstRow.map((value) => value.toLowerCase()).includes(header)) && requiredHeaderNames.length === firstRow.length);
57
- };
58
- async function parseFile(fileContent, maxRows, requiredHeaderNames, dependencies) {
59
- if (fileContent === 'invalidFileType') {
60
- throw new errors_1.InvalidFileError();
61
- }
62
- const rows = fileContent.split('\n');
63
- const parsedRows = rows.map(parse_row_1.default);
64
- const sanitizedRows = sanitize_rows_1.default(parsedRows);
65
- if (sanitizedRows.length > maxRows) {
66
- throw new errors_1.TooManyRowsError();
67
- }
68
- if (sanitizedRows.length === 0) {
69
- throw new errors_1.NoRowsError();
70
- }
71
- const containsHeaders = exports.hasHeaderRow(sanitizedRows, requiredHeaderNames);
72
- if (containsHeaders
73
- && !exports.isHeaderRowValid(sanitizedRows, requiredHeaderNames)) {
74
- throw new errors_1.InvalidHeadersError();
75
- }
76
- const firstSanitizedRow = sanitizedRows[0];
77
- if (!firstSanitizedRow) {
78
- throw new errors_1.NoRowsError();
79
- }
80
- const headers = containsHeaders
81
- ? firstSanitizedRow.map((value) => value.toLowerCase())
82
- : requiredHeaderNames;
83
- const dataRows = containsHeaders ? sanitizedRows.splice(1) : sanitizedRows;
84
- if (dataRows.length === 0) {
85
- throw new errors_1.NoRowsError();
86
- }
87
- const parsedRowChunks = chunk(dataRows, 30);
88
- let results = [];
89
- for (const currentRowChunk of parsedRowChunks) {
90
- const chunkResult = await processChunk(currentRowChunk, {
91
- ...dependencies,
92
- headers,
93
- });
94
- results = results.concat(chunkResult);
95
- }
96
- return results;
97
- }
98
- exports.default = parseFile;
@@ -1,203 +0,0 @@
1
- "use strict";
2
- const TC = require('type-check');
3
- const _ = require('lodash');
4
- const E = require('../errors/errors');
5
- const V = require('../validations/validations');
6
- const customTypes = {
7
- Integer: {
8
- typeOf: 'Number',
9
- validate(x) {
10
- return x % 1 === 0;
11
- },
12
- },
13
- IntString: {
14
- typeOf: 'String',
15
- validate: V.isInt,
16
- },
17
- BoolString: {
18
- typeOf: 'String',
19
- validate: V.isBoolean,
20
- },
21
- Hex32: {
22
- typeOf: 'String',
23
- validate(x) {
24
- return V.isHexadecimal(x) && x.length === 32;
25
- },
26
- },
27
- Email: {
28
- typeOf: 'String',
29
- validate: V.isEmail,
30
- },
31
- UUID: {
32
- typeOf: 'String',
33
- validate: V.isUUID,
34
- },
35
- UUIDv4: {
36
- typeOf: 'String',
37
- validate(x) {
38
- return V.isUUID(x, 4);
39
- },
40
- },
41
- JSON: {
42
- typeOf: 'String',
43
- validate: V.isJSON,
44
- },
45
- Url: {
46
- typeOf: 'String',
47
- validate: V.isURL,
48
- },
49
- DateString: {
50
- typeOf: 'String',
51
- validate: V.isDate,
52
- },
53
- NonEmptyArray: {
54
- typeOf: 'Array',
55
- validate: V.nonEmpty,
56
- },
57
- NonNullString: {
58
- typeOf: 'String',
59
- validate: V.nonEmpty,
60
- },
61
- CustomerReference: {
62
- typeOf: 'String',
63
- validate: V.isCustomerReference,
64
- },
65
- CustomerLabelName: {
66
- typeOf: 'String',
67
- validate: V.isCustomerLabelName,
68
- },
69
- BitcoinAddress: {
70
- typeOf: 'String',
71
- validate: V.bitcoin.isAddress,
72
- },
73
- EthereumAddress: {
74
- typeOf: 'String',
75
- validate: V.ethereum.isAddress,
76
- },
77
- EthereumTx: {
78
- typeOf: 'String',
79
- validate: V.ethereum.isTxHash,
80
- },
81
- EthereumBlockHash: {
82
- typeOf: 'String',
83
- validate: V.ethereum.isBlockHash,
84
- },
85
- EthereumWeiAmount: {
86
- typeOf: 'String',
87
- validate: V.ethereum.isValidWeiAmount,
88
- },
89
- EthereumAddressCode: {
90
- typeOf: 'String',
91
- validate: V.ethereum.isAddressCode,
92
- },
93
- MineId: {
94
- typeOf: 'String',
95
- validate(x) {
96
- return x === 'mine';
97
- },
98
- },
99
- BitcoinTxHash: {
100
- typeOf: 'String',
101
- validate: V.bitcoin.isTxHash,
102
- },
103
- BitcoinAddressArray: {
104
- typeOf: 'Array',
105
- validate(as) {
106
- return _.every(as, V.bitcoin.isAddress);
107
- },
108
- },
109
- BitcoinTxHashArray: {
110
- typeOf: 'Array',
111
- validate(as) {
112
- return _.every(as, V.bitcoin.isTxHash);
113
- },
114
- },
115
- BitcoinTxHex: {
116
- typeOf: 'String',
117
- validate: V.bitcoin.isTxHex,
118
- },
119
- BitcoinScriptHex: {
120
- typeOf: 'String',
121
- validate: V.bitcoin.isScriptHex,
122
- },
123
- BitcoinHDPath: {
124
- typeOf: 'String',
125
- validate: V.bitcoin.isHDPath,
126
- },
127
- BitcoinPublicKey: {
128
- typeOf: 'String',
129
- validate: V.bitcoin.isPublicKey,
130
- },
131
- BitcoinXpub: {
132
- typeOf: 'String',
133
- validate: V.bitcoin.isHDPublicKey,
134
- },
135
- BitcoinTxSignature: {
136
- typeOf: 'String',
137
- validate: V.bitcoin.isTxSignature,
138
- },
139
- BitcoinBlockHeight: {
140
- typeOf: 'Number',
141
- validate: V.bitcoin.isBlockHeight,
142
- },
143
- };
144
- // add support for nullable properties
145
- const withNullable = Object.keys(customTypes).reduce((acc, _type) => {
146
- acc[_type] = customTypes[_type];
147
- const { typeOf, validate } = customTypes[_type];
148
- // for every type, add Nullable+type. A nullable string can also be empty
149
- acc[`Nullable${_type}`] = Object.assign({}, customTypes[_type], {
150
- validate: (x) => x == null || (typeOf === 'String' && x === '') || validate(x),
151
- });
152
- return acc;
153
- }, {});
154
- module.exports = {
155
- parseType(str) {
156
- return TC.parseType(str);
157
- },
158
- parsedTypeCheck(type, obj) {
159
- return TC.parsedTypeCheck(type, obj, this.opts);
160
- },
161
- typeCheck(type, obj) {
162
- return TC.typeCheck(type, obj, this.opts);
163
- },
164
- opts: {
165
- customTypes: withNullable,
166
- },
167
- ensureType(type, obj, msg) {
168
- return V.ensure(this.typeCheck(type, obj), msg);
169
- },
170
- checkArg(obj, prop, type, msg) {
171
- let message;
172
- if (msg == null) {
173
- message = `Invalid ${prop}`;
174
- }
175
- else {
176
- message = msg;
177
- }
178
- this.ensureType(type, obj[prop], message);
179
- return obj[prop];
180
- },
181
- checkArgs(input, types) {
182
- const inputKeys = {};
183
- const [typ] = types;
184
- const fields = typ.of;
185
- let numInputKeys = 0;
186
- let numKeys;
187
- Object.keys(input).forEach((k) => {
188
- inputKeys[k] = true;
189
- numInputKeys += 1;
190
- });
191
- numKeys = 0;
192
- Object.keys(fields).forEach((key) => {
193
- const objTypes = fields[key];
194
- V.ensure(this.parsedTypeCheck(objTypes, input[key]), `Invalid ${key}`);
195
- if (inputKeys[key]) {
196
- numKeys += 1;
197
- }
198
- });
199
- if (!(typ.subset || numInputKeys === numKeys)) {
200
- throw new E.BadRequest('invalid extra arguments are present');
201
- }
202
- },
203
- };