@bedrockio/yada 1.0.20 → 1.0.22

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.
@@ -204,15 +204,9 @@ class Schema {
204
204
  default: defaultValue
205
205
  } = this.meta;
206
206
  return {
207
- ...(required && {
208
- required: true
209
- }),
210
- ...(defaultValue && {
211
- default: defaultValue
212
- }),
213
- ...(format && {
214
- format
215
- }),
207
+ required,
208
+ default: defaultValue,
209
+ format,
216
210
  ...this.enumToOpenApi(),
217
211
  ...tags,
218
212
  ...extra
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.PASSWORD_DEFAULTS = void 0;
6
+ exports.getPasswordOptions = getPasswordOptions;
7
7
  exports.validateLength = validateLength;
8
8
  exports.validateUppercase = exports.validateSymbols = exports.validateNumbers = exports.validateLowercase = void 0;
9
9
  var _errors = require("./errors");
@@ -18,7 +18,16 @@ const PASSWORD_DEFAULTS = {
18
18
  minNumbers: 0,
19
19
  minSymbols: 0
20
20
  };
21
- exports.PASSWORD_DEFAULTS = PASSWORD_DEFAULTS;
21
+ function getPasswordOptions(options) {
22
+ options = {
23
+ ...PASSWORD_DEFAULTS,
24
+ ...options
25
+ };
26
+ return {
27
+ ...options,
28
+ description: generatePasswordDescription(options)
29
+ };
30
+ }
22
31
  function validateLength(expected) {
23
32
  return (str = '') => {
24
33
  if (str.length < expected) {
@@ -51,4 +60,55 @@ function validateRegex(reg, message) {
51
60
  }
52
61
  };
53
62
  };
63
+ }
64
+ function generatePasswordDescription(options) {
65
+ const {
66
+ minLength
67
+ } = options;
68
+ const contains = generatePasswordContains(options);
69
+ if (minLength) {
70
+ const plural = pluralize(minLength, 'character');
71
+ return `A password of at least ${plural}${contains}.`;
72
+ } else {
73
+ return `A password${contains}.`;
74
+ }
75
+ }
76
+ function generatePasswordContains(options) {
77
+ const {
78
+ minLowercase,
79
+ minUppercase,
80
+ minNumbers,
81
+ minSymbols
82
+ } = options;
83
+ const arr = [];
84
+ if (minLowercase) {
85
+ arr.push(`${minLowercase} lowercase`);
86
+ }
87
+ if (minUppercase) {
88
+ arr.push(`${minUppercase} uppercase`);
89
+ }
90
+ if (minNumbers) {
91
+ arr.push(`${pluralize(minNumbers, 'number')}`);
92
+ }
93
+ if (minSymbols) {
94
+ arr.push(`${pluralize(minSymbols, 'symbol')}`);
95
+ }
96
+ if (arr.length) {
97
+ return ` containing ${and(arr)}`;
98
+ } else {
99
+ return '';
100
+ }
101
+ }
102
+ function pluralize(n, str) {
103
+ const s = n === 1 ? '' : 's';
104
+ return `${n} ${str}${s}`;
105
+ }
106
+ function and(arr) {
107
+ if (arr.length <= 2) {
108
+ return arr.join(' and ');
109
+ } else {
110
+ const last = arr.pop();
111
+ const joined = arr.join(', ');
112
+ return `${joined}, and ${last}`;
113
+ }
54
114
  }
@@ -11,6 +11,7 @@ var _password = require("./password");
11
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
12
  const SLUG_REG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
13
13
  const PHONE_REG = /^\+?[1-9]\d{1,14}$/;
14
+ const PHONE_DESCRIPTION = 'A phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.';
14
15
  class StringSchema extends _TypeSchema.default {
15
16
  constructor() {
16
17
  super(String);
@@ -132,7 +133,7 @@ class StringSchema extends _TypeSchema.default {
132
133
  if (!PHONE_REG.test(str)) {
133
134
  throw new _errors.LocalizedError('Must be a valid phone number.');
134
135
  }
135
- });
136
+ }).description(PHONE_DESCRIPTION);
136
137
  }
137
138
  hex() {
138
139
  return this.format('hex', str => {
@@ -246,16 +247,14 @@ class StringSchema extends _TypeSchema.default {
246
247
  */
247
248
  password(options = {}) {
248
249
  const {
250
+ description,
249
251
  minLength,
250
252
  minNumbers,
251
253
  minSymbols,
252
254
  minLowercase,
253
255
  minUppercase
254
- } = {
255
- ..._password.PASSWORD_DEFAULTS,
256
- ...options
257
- };
258
- const schema = this.clone();
256
+ } = (0, _password.getPasswordOptions)(options);
257
+ const schema = this.clone().description(description);
259
258
  if (minLength) {
260
259
  schema.assert('password', (0, _password.validateLength)(minLength));
261
260
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrockio/yada",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "Validation library inspired by Joi.",
5
5
  "scripts": {
6
6
  "test": "jest",
package/src/Schema.js CHANGED
@@ -190,15 +190,9 @@ export default class Schema {
190
190
  toOpenApi(extra) {
191
191
  const { required, format, tags, default: defaultValue } = this.meta;
192
192
  return {
193
- ...(required && {
194
- required: true,
195
- }),
196
- ...(defaultValue && {
197
- default: defaultValue,
198
- }),
199
- ...(format && {
200
- format,
201
- }),
193
+ required,
194
+ default: defaultValue,
195
+ format,
202
196
  ...this.enumToOpenApi(),
203
197
  ...tags,
204
198
  ...extra,
package/src/password.js CHANGED
@@ -5,7 +5,7 @@ const UPPER_REG = /[A-Z]/g;
5
5
  const NUMBER_REG = /[0-9]/g;
6
6
  const SYMBOL_REG = /[!@#$%^&*]/g;
7
7
 
8
- export const PASSWORD_DEFAULTS = {
8
+ const PASSWORD_DEFAULTS = {
9
9
  minLength: 12,
10
10
  minLowercase: 0,
11
11
  minUppercase: 0,
@@ -13,6 +13,17 @@ export const PASSWORD_DEFAULTS = {
13
13
  minSymbols: 0,
14
14
  };
15
15
 
16
+ export function getPasswordOptions(options) {
17
+ options = {
18
+ ...PASSWORD_DEFAULTS,
19
+ ...options,
20
+ };
21
+ return {
22
+ ...options,
23
+ description: generatePasswordDescription(options),
24
+ };
25
+ }
26
+
16
27
  export function validateLength(expected) {
17
28
  return (str = '') => {
18
29
  if (str.length < expected) {
@@ -59,3 +70,51 @@ function validateRegex(reg, message) {
59
70
  };
60
71
  };
61
72
  }
73
+
74
+ function generatePasswordDescription(options) {
75
+ const { minLength } = options;
76
+ const contains = generatePasswordContains(options);
77
+ if (minLength) {
78
+ const plural = pluralize(minLength, 'character');
79
+ return `A password of at least ${plural}${contains}.`;
80
+ } else {
81
+ return `A password${contains}.`;
82
+ }
83
+ }
84
+
85
+ function generatePasswordContains(options) {
86
+ const { minLowercase, minUppercase, minNumbers, minSymbols } = options;
87
+ const arr = [];
88
+ if (minLowercase) {
89
+ arr.push(`${minLowercase} lowercase`);
90
+ }
91
+ if (minUppercase) {
92
+ arr.push(`${minUppercase} uppercase`);
93
+ }
94
+ if (minNumbers) {
95
+ arr.push(`${pluralize(minNumbers, 'number')}`);
96
+ }
97
+ if (minSymbols) {
98
+ arr.push(`${pluralize(minSymbols, 'symbol')}`);
99
+ }
100
+ if (arr.length) {
101
+ return ` containing ${and(arr)}`;
102
+ } else {
103
+ return '';
104
+ }
105
+ }
106
+
107
+ function pluralize(n, str) {
108
+ const s = n === 1 ? '' : 's';
109
+ return `${n} ${str}${s}`;
110
+ }
111
+
112
+ function and(arr) {
113
+ if (arr.length <= 2) {
114
+ return arr.join(' and ');
115
+ } else {
116
+ const last = arr.pop();
117
+ const joined = arr.join(', ');
118
+ return `${joined}, and ${last}`;
119
+ }
120
+ }
package/src/string.js CHANGED
@@ -2,17 +2,20 @@ import validator from 'validator';
2
2
  import TypeSchema from './TypeSchema';
3
3
  import { LocalizedError } from './errors';
4
4
  import {
5
- PASSWORD_DEFAULTS,
6
5
  validateLength,
7
6
  validateLowercase,
8
7
  validateUppercase,
9
8
  validateNumbers,
10
9
  validateSymbols,
10
+ getPasswordOptions,
11
11
  } from './password';
12
12
 
13
13
  const SLUG_REG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
14
14
  const PHONE_REG = /^\+?[1-9]\d{1,14}$/;
15
15
 
16
+ const PHONE_DESCRIPTION =
17
+ 'A phone number in [E.164](https://en.wikipedia.org/wiki/E.164) format.';
18
+
16
19
  class StringSchema extends TypeSchema {
17
20
  constructor() {
18
21
  super(String);
@@ -131,7 +134,7 @@ class StringSchema extends TypeSchema {
131
134
  if (!PHONE_REG.test(str)) {
132
135
  throw new LocalizedError('Must be a valid phone number.');
133
136
  }
134
- });
137
+ }).description(PHONE_DESCRIPTION);
135
138
  }
136
139
 
137
140
  hex() {
@@ -255,12 +258,16 @@ class StringSchema extends TypeSchema {
255
258
  * @param {number} [options.minUppercase]
256
259
  */
257
260
  password(options = {}) {
258
- const { minLength, minNumbers, minSymbols, minLowercase, minUppercase } = {
259
- ...PASSWORD_DEFAULTS,
260
- ...options,
261
- };
262
-
263
- const schema = this.clone();
261
+ const {
262
+ description,
263
+ minLength,
264
+ minNumbers,
265
+ minSymbols,
266
+ minLowercase,
267
+ minUppercase,
268
+ } = getPasswordOptions(options);
269
+
270
+ const schema = this.clone().description(description);
264
271
 
265
272
  if (minLength) {
266
273
  schema.assert('password', validateLength(minLength));
@@ -1 +1 @@
1
- {"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../src/Schema.js"],"names":[],"mappings":"AA4UA,4CAEC;AAnUD;;GAEG;AAEH;IACE,uBAGC;IAFC,kBAAoB;IACpB,SAAgB;IAKlB;;OAEG;IACH,YAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,qBAFa,IAAI,CAQhB;IAED;;;;OAIG;IACH,gBAHW,eAAe,GACb,IAAI,CAmBhB;IAED;;;;OAIG;IACH,mBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,sBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,gBAFa,IAAI,CAShB;IAED;;OAEG;IACH,+BAFa,IAAI,CAMhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED,iDAqCC;IAED;;OAEG;IACH,kBAFa,IAAI,CAOhB;IAED;;;OAGG;IACH,qBAFa,IAAI,CAMhB;IAED,2BAgBC;IAID;;OAEG;IACH,kCAFa,IAAI,CAgChB;IAED;;OAEG;IACH,4BAFa,IAAI,CAUhB;IAED,oCAKC;IAED;;OAEG;IACH,oBAFa,IAAI,CAShB;IAED,gCAGC;IAED,qEAUC;IAED;;;;;;;;MAoCC;CACF;8BA9TY,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC"}
1
+ {"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../src/Schema.js"],"names":[],"mappings":"AAsUA,4CAEC;AA7TD;;GAEG;AAEH;IACE,uBAGC;IAFC,kBAAoB;IACpB,SAAgB;IAKlB;;OAEG;IACH,YAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,qBAFa,IAAI,CAQhB;IAED;;;;OAIG;IACH,gBAHW,eAAe,GACb,IAAI,CAmBhB;IAED;;;;OAIG;IACH,mBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,sBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,gBAFa,IAAI,CAShB;IAED;;OAEG;IACH,+BAFa,IAAI,CAMhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED,iDAqCC;IAED;;OAEG;IACH,kBAFa,IAAI,CAOhB;IAED;;;OAGG;IACH,qBAFa,IAAI,CAMhB;IAED,2BAUC;IAID;;OAEG;IACH,kCAFa,IAAI,CAgChB;IAED;;OAEG;IACH,4BAFa,IAAI,CAUhB;IAED,oCAKC;IAED;;OAEG;IACH,oBAFa,IAAI,CAShB;IAED,gCAGC;IAED,qEAUC;IAED;;;;;;;;MAoCC;CACF;8BAxTY,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC"}
@@ -1,11 +1,5 @@
1
+ export function getPasswordOptions(options: any): any;
1
2
  export function validateLength(expected: any): (str?: string) => void;
2
- export namespace PASSWORD_DEFAULTS {
3
- const minLength: number;
4
- const minLowercase: number;
5
- const minUppercase: number;
6
- const minNumbers: number;
7
- const minSymbols: number;
8
- }
9
3
  export function validateLowercase(expected: any): (str?: string) => void;
10
4
  export function validateUppercase(expected: any): (str?: string) => void;
11
5
  export function validateNumbers(expected: any): (str?: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../src/password.js"],"names":[],"mappings":"AAeA,sEAUC;;;;;;;;AAuBQ,yEAWN;AAXM,yEAWN;AAXM,uEAWN;AAXM,uEAWN"}
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../src/password.js"],"names":[],"mappings":"AAeA,sDASC;AAED,sEAUC;AAuBQ,yEAWN;AAXM,yEAWN;AAXM,uEAWN;AAXM,uEAWN"}
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.js"],"names":[],"mappings":"AAyXA;;GAEG;AACH,iDAEC;AA/WD;IACE,cAWC;IAED;;OAEG;IACH,eAFW,MAAM,gBAUhB;IAED;;OAEG;IACH,YAFW,MAAM,gBAUhB;IAED;;OAEG;IACH,YAFW,MAAM,gBAUhB;IAED,qBAIC;IAED;;OAEG;IACH,mBAFW,OAAO,gBAYjB;IAED;;OAEG;IACH,mBAFW,OAAO,gBAYjB;IAED;;OAEG;IACH,WAFW,MAAM,gBAahB;IAED,sBAMC;IAED,sBAMC;IAED,oBAMC;IAED,oBAMC;IAED,qBAMC;IAED,sBAMC;IAED;;;OAGG;IACH;QAF6B,OAAO,GAAzB,OAAO;qBAQjB;IAED,2BAMC;IAED,mBAMC;IAED,wBAMC;IAED,uBAMC;IAED,oBAMC;IAED,qBAOC;IAED,uBAMC;IAED;;OAEG;IACH,oBAFW,MAAM,gBAQhB;IAED;;;;;;;OAOG;IACH;QAN4B,SAAS,GAA1B,MAAM;QACW,UAAU,GAA3B,MAAM;QACW,UAAU,GAA3B,MAAM;QACW,YAAY,GAA7B,MAAM;QACW,YAAY,GAA7B,MAAM;qBA2BhB;IAED;;;;;;;;;;;OAWG;IACH;QAV6B,gBAAgB,GAAlC,OAAO;QACW,sBAAsB,GAAxC,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,4BAA4B,GAA9C,OAAO;QACW,eAAe,GAAjC,OAAO;QACW,sBAAsB,GAAxC,OAAO;QACW,eAAe,GAAjC,OAAO;QACY,SAAS,GAA5B,MAAM,EAAE;qBAQlB;IAED;;;;;;;;OAQG;IACH;QAP6B,WAAW,GAA7B,OAAO;QACW,iBAAiB,GAAnC,OAAO;QACW,kBAAkB,GAApC,OAAO;QACW,iBAAiB,GAAnC,OAAO;QACW,cAAc,GAAhC,OAAO;QACW,iBAAiB,GAAnC,OAAO;qBAQjB;IAED;;OAEG;IACH,eAFW,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAQ3B;IAED,oBAMC;IAED,oBAMC;IAED,sBAMC;IAED,sBAMC;CAcF"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.js"],"names":[],"mappings":"AAgYA;;GAEG;AACH,iDAEC;AAnXD;IACE,cAWC;IAED;;OAEG;IACH,eAFW,MAAM,gBAUhB;IAED;;OAEG;IACH,YAFW,MAAM,gBAUhB;IAED;;OAEG;IACH,YAFW,MAAM,gBAUhB;IAED,qBAIC;IAED;;OAEG;IACH,mBAFW,OAAO,gBAYjB;IAED;;OAEG;IACH,mBAFW,OAAO,gBAYjB;IAED;;OAEG;IACH,WAFW,MAAM,gBAahB;IAED,sBAMC;IAED,sBAMC;IAED,oBAMC;IAED,oBAMC;IAED,qBAMC;IAED,sBAMC;IAED;;;OAGG;IACH;QAF6B,OAAO,GAAzB,OAAO;qBAQjB;IAED,2BAMC;IAED,mBAMC;IAED,wBAMC;IAED,uBAMC;IAED,oBAMC;IAED,qBAOC;IAED,uBAMC;IAED;;OAEG;IACH,oBAFW,MAAM,gBAQhB;IAED;;;;;;;OAOG;IACH;QAN4B,SAAS,GAA1B,MAAM;QACW,UAAU,GAA3B,MAAM;QACW,UAAU,GAA3B,MAAM;QACW,YAAY,GAA7B,MAAM;QACW,YAAY,GAA7B,MAAM;qBA+BhB;IAED;;;;;;;;;;;OAWG;IACH;QAV6B,gBAAgB,GAAlC,OAAO;QACW,sBAAsB,GAAxC,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,4BAA4B,GAA9C,OAAO;QACW,eAAe,GAAjC,OAAO;QACW,sBAAsB,GAAxC,OAAO;QACW,eAAe,GAAjC,OAAO;QACY,SAAS,GAA5B,MAAM,EAAE;qBAQlB;IAED;;;;;;;;OAQG;IACH;QAP6B,WAAW,GAA7B,OAAO;QACW,iBAAiB,GAAnC,OAAO;QACW,kBAAkB,GAApC,OAAO;QACW,iBAAiB,GAAnC,OAAO;QACW,cAAc,GAAhC,OAAO;QACW,iBAAiB,GAAnC,OAAO;qBAQjB;IAED;;OAEG;IACH,eAFW,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAQ3B;IAED,oBAMC;IAED,oBAMC;IAED,sBAMC;IAED,sBAMC;CAcF"}