ascertain 0.13.4 → 0.14.0

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.
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ $keys: function() {
13
+ return $keys;
14
+ },
15
+ $values: function() {
16
+ return $values;
17
+ },
18
+ and: function() {
19
+ return and;
20
+ },
21
+ as: function() {
22
+ return as;
23
+ },
24
+ ascertain: function() {
25
+ return ascertain;
26
+ },
27
+ default: function() {
28
+ return _default;
29
+ },
30
+ fromBase64: function() {
31
+ return fromBase64;
32
+ },
33
+ optional: function() {
34
+ return optional;
35
+ },
36
+ or: function() {
37
+ return or;
38
+ }
39
+ });
40
+ let AssertError = class AssertError {
41
+ constructor(value, expected, path, subject = 'value'){
42
+ this.value = value;
43
+ this.expected = expected;
44
+ this.path = path;
45
+ this.subject = subject;
46
+ }
47
+ toString() {
48
+ return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;
49
+ }
50
+ };
51
+ function findFirstError(array, map) {
52
+ for(let i = 0; i < array.length; i++){
53
+ const error = map(array[i], i);
54
+ if (error) {
55
+ return error;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ function findNotError(array, map) {
61
+ const errors = [];
62
+ for(let i = 0; i < array.length; i++){
63
+ const error = map(array[i], i);
64
+ if (!error) {
65
+ return false;
66
+ } else {
67
+ errors.push(error);
68
+ }
69
+ }
70
+ return errors.reduce((result, error)=>{
71
+ return new AssertError(result.value, [
72
+ result.expected,
73
+ error.expected
74
+ ].join(' or '), result.path, result.string);
75
+ });
76
+ }
77
+ function Optional(schema) {
78
+ this.schema = schema;
79
+ }
80
+ function And(schema) {
81
+ this.schema = schema;
82
+ }
83
+ function Or(schema) {
84
+ this.schema = schema;
85
+ }
86
+ const optional = (schema)=>{
87
+ return new Optional(schema);
88
+ };
89
+ const and = (...schema)=>{
90
+ return new And(schema);
91
+ };
92
+ const or = (...schema)=>{
93
+ return new Or(schema);
94
+ };
95
+ const $keys = Symbol.for('@@keys');
96
+ const $values = Symbol.for('@@values');
97
+ const fromBase64 = typeof Buffer === 'undefined' ? (value)=>atob(value) : (value)=>Buffer.from(value, 'base64').toString('utf-8');
98
+ const MULTIPLIERS = {
99
+ ms: 1,
100
+ s: 1000,
101
+ m: 60000,
102
+ h: 3600000,
103
+ d: 86400000,
104
+ w: 604800000
105
+ };
106
+ const as = {
107
+ string: (value)=>{
108
+ return typeof value === 'string' ? value : undefined;
109
+ },
110
+ number: (value)=>{
111
+ const result = parseFloat(value);
112
+ return Number.isFinite(result) ? result : undefined;
113
+ },
114
+ date: (value)=>{
115
+ const result = Date.parse(value);
116
+ return Number.isFinite(result) ? new Date(result) : undefined;
117
+ },
118
+ time: (value)=>{
119
+ const matches = value?.match(/^(\d+)(ms|s|m|h|d|w)?$/);
120
+ if (matches) {
121
+ const [_, amount, unit = 'ms'] = matches;
122
+ return parseInt(amount, 10) * MULTIPLIERS[unit];
123
+ }
124
+ return undefined;
125
+ },
126
+ boolean: (value)=>/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined,
127
+ array: (value, delimiter)=>value?.split(delimiter) ?? undefined,
128
+ json: (value)=>{
129
+ try {
130
+ return JSON.parse(value);
131
+ } catch (e) {
132
+ return undefined;
133
+ }
134
+ },
135
+ base64: (value)=>{
136
+ try {
137
+ return fromBase64(value);
138
+ } catch (e) {
139
+ return undefined;
140
+ }
141
+ }
142
+ };
143
+ function certain(target, schema, path, optional) {
144
+ if (schema === null || typeof schema === 'undefined') {
145
+ return new AssertError(schema, 'any value', path, 'schema value');
146
+ }
147
+ if (schema instanceof Optional) {
148
+ return certain(target, schema.schema, path, true);
149
+ }
150
+ const isValue = target !== null && typeof target !== 'undefined';
151
+ if (!isValue && optional) {
152
+ return;
153
+ }
154
+ if (schema instanceof Or) {
155
+ if (!schema.schema.length) {
156
+ return new AssertError(target, 'values', path, 'OR schema');
157
+ }
158
+ return findNotError(schema.schema, (schema)=>certain(target, schema, path));
159
+ }
160
+ if (schema instanceof And) {
161
+ if (!schema.schema.length) {
162
+ return new AssertError(target, 'values', path, 'AND schema');
163
+ }
164
+ return findFirstError(schema.schema, (schema)=>certain(target, schema, path));
165
+ }
166
+ if (typeof schema === 'function') {
167
+ if (!isValue) {
168
+ return new AssertError(target, schema.name, path);
169
+ }
170
+ if (typeof target === 'object' && !(target instanceof schema)) {
171
+ return new AssertError(target, schema.name, path);
172
+ }
173
+ if (typeof target !== 'object' && target.constructor !== schema) {
174
+ return new AssertError(target, schema.name, path);
175
+ }
176
+ } else if (Array.isArray(schema)) {
177
+ if (!Array.isArray(target)) {
178
+ return new AssertError(target, schema.constructor.name, path);
179
+ }
180
+ return findFirstError(target, (value, idx)=>{
181
+ return findNotError(schema, (itemSchemaType)=>certain(value, itemSchemaType, `${path}.${idx}`));
182
+ });
183
+ } else if (typeof schema === 'object') {
184
+ if (schema instanceof RegExp) {
185
+ if (!schema.test('' + target)) {
186
+ return new AssertError(target, `matching /${schema.source}/`, path);
187
+ }
188
+ } else {
189
+ if (typeof target !== 'object') {
190
+ return new AssertError(target, schema.constructor.name, path);
191
+ }
192
+ if (target === null) {
193
+ return new AssertError(target, 'an object', path);
194
+ }
195
+ if ($keys in schema) {
196
+ const targetKeys = Object.keys(target);
197
+ const assertError = findFirstError(targetKeys, (targetKey)=>certain(targetKey, schema[$keys], `${path}.${targetKey}`));
198
+ if (assertError) {
199
+ return assertError;
200
+ }
201
+ }
202
+ if ($values in schema) {
203
+ const targetKeys = Object.keys(target);
204
+ const assertError = findFirstError(targetKeys, (targetKey)=>certain(target[targetKey], schema[$values], `${path}.${targetKey}`));
205
+ if (assertError) {
206
+ return assertError;
207
+ }
208
+ }
209
+ return findFirstError(Object.keys(schema), (key)=>certain(target[key], schema[key], `${path}.${key}`));
210
+ }
211
+ } else if (target !== schema) {
212
+ return new AssertError(target, schema, path);
213
+ }
214
+ }
215
+ const ascertain = (schema, data, rootName = '[root]')=>{
216
+ const result = certain(data, schema, rootName);
217
+ if (result instanceof AssertError) {
218
+ throw new TypeError(result.toString());
219
+ }
220
+ };
221
+ const _default = ascertain;
222
+
223
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.js"],"sourcesContent":["class AssertError {\n constructor(value, expected, path, subject = 'value') {\n this.value = value;\n this.expected = expected;\n this.path = path;\n this.subject = subject;\n }\n\n toString() {\n return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;\n }\n}\n\nfunction findFirstError(array, map) {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n}\n\nfunction findNotError(array, map) {\n const errors = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);\n });\n}\n\nfunction Optional(schema) {\n this.schema = schema;\n}\n\nfunction And(schema) {\n this.schema = schema;\n}\n\nfunction Or(schema) {\n this.schema = schema;\n}\n\nexport const optional = (schema) => {\n return new Optional(schema);\n};\n\nexport const and = (...schema) => {\n return new And(schema);\n};\n\nexport const or = (...schema) => {\n return new Or(schema);\n};\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\n\nexport const fromBase64 =\n typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value) => {\n const result = parseFloat(value);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value) => {\n const result = Date.parse(value);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [_, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit];\n }\n return undefined;\n },\n boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),\n array: (value, delimiter) => value?.split(delimiter) ?? undefined,\n json: (value) => {\n try {\n return JSON.parse(value);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value) => {\n try {\n return fromBase64(value);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nfunction certain(target, schema, path, optional) {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return certain(target, schema.schema, path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schema, (schema) => certain(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schema, (schema) => certain(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(targetKey, schema[$keys], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(target[targetKey], schema[$values], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n}\n\nexport const ascertain = (schema, data, rootName = '[root]') => {\n const result = certain(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n\nexport default ascertain;\n"],"names":["$keys","$values","and","as","ascertain","fromBase64","optional","or","AssertError","constructor","value","expected","path","subject","toString","JSON","stringify","findFirstError","array","map","i","length","error","findNotError","errors","push","reduce","result","join","string","Optional","schema","And","Or","Symbol","for","Buffer","atob","from","MULTIPLIERS","ms","s","m","h","d","w","undefined","number","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","_","amount","unit","parseInt","boolean","test","delimiter","split","json","e","base64","certain","target","isValue","name","Array","isArray","idx","itemSchemaType","RegExp","source","targetKeys","Object","keys","assertError","targetKey","key","data","rootName","TypeError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
package/build/index.js CHANGED
@@ -1,42 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: all[name]
9
- });
10
- }
11
- _export(exports, {
12
- $keys: function() {
13
- return $keys;
14
- },
15
- $values: function() {
16
- return $values;
17
- },
18
- and: function() {
19
- return and;
20
- },
21
- as: function() {
22
- return as;
23
- },
24
- ascertain: function() {
25
- return ascertain;
26
- },
27
- default: function() {
28
- return _default;
29
- },
30
- fromBase64: function() {
31
- return fromBase64;
32
- },
33
- optional: function() {
34
- return optional;
35
- },
36
- or: function() {
37
- return or;
38
- }
39
- });
40
1
  let AssertError = class AssertError {
41
2
  constructor(value, expected, path, subject = 'value'){
42
3
  this.value = value;
@@ -83,18 +44,18 @@ function And(schema) {
83
44
  function Or(schema) {
84
45
  this.schema = schema;
85
46
  }
86
- const optional = (schema)=>{
47
+ export const optional = (schema)=>{
87
48
  return new Optional(schema);
88
49
  };
89
- const and = (...schema)=>{
50
+ export const and = (...schema)=>{
90
51
  return new And(schema);
91
52
  };
92
- const or = (...schema)=>{
53
+ export const or = (...schema)=>{
93
54
  return new Or(schema);
94
55
  };
95
- const $keys = Symbol.for('@@keys');
96
- const $values = Symbol.for('@@values');
97
- const fromBase64 = typeof Buffer === 'undefined' ? (value)=>atob(value) : (value)=>Buffer.from(value, 'base64').toString('utf-8');
56
+ export const $keys = Symbol.for('@@keys');
57
+ export const $values = Symbol.for('@@values');
58
+ export const fromBase64 = typeof Buffer === 'undefined' ? (value)=>atob(value) : (value)=>Buffer.from(value, 'base64').toString('utf-8');
98
59
  const MULTIPLIERS = {
99
60
  ms: 1,
100
61
  s: 1000,
@@ -103,7 +64,7 @@ const MULTIPLIERS = {
103
64
  d: 86400000,
104
65
  w: 604800000
105
66
  };
106
- const as = {
67
+ export const as = {
107
68
  string: (value)=>{
108
69
  return typeof value === 'string' ? value : undefined;
109
70
  },
@@ -212,10 +173,12 @@ function certain(target, schema, path, optional) {
212
173
  return new AssertError(target, schema, path);
213
174
  }
214
175
  }
215
- const ascertain = (schema, data, rootName = '[root]')=>{
176
+ export const ascertain = (schema, data, rootName = '[root]')=>{
216
177
  const result = certain(data, schema, rootName);
217
178
  if (result instanceof AssertError) {
218
179
  throw new TypeError(result.toString());
219
180
  }
220
181
  };
221
- const _default = ascertain;
182
+ export default ascertain;
183
+
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.js"],"sourcesContent":["class AssertError {\n constructor(value, expected, path, subject = 'value') {\n this.value = value;\n this.expected = expected;\n this.path = path;\n this.subject = subject;\n }\n\n toString() {\n return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;\n }\n}\n\nfunction findFirstError(array, map) {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n}\n\nfunction findNotError(array, map) {\n const errors = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);\n });\n}\n\nfunction Optional(schema) {\n this.schema = schema;\n}\n\nfunction And(schema) {\n this.schema = schema;\n}\n\nfunction Or(schema) {\n this.schema = schema;\n}\n\nexport const optional = (schema) => {\n return new Optional(schema);\n};\n\nexport const and = (...schema) => {\n return new And(schema);\n};\n\nexport const or = (...schema) => {\n return new Or(schema);\n};\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\n\nexport const fromBase64 =\n typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value) => {\n const result = parseFloat(value);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value) => {\n const result = Date.parse(value);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [_, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit];\n }\n return undefined;\n },\n boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),\n array: (value, delimiter) => value?.split(delimiter) ?? undefined,\n json: (value) => {\n try {\n return JSON.parse(value);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value) => {\n try {\n return fromBase64(value);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nfunction certain(target, schema, path, optional) {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return certain(target, schema.schema, path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schema, (schema) => certain(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schema, (schema) => certain(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(targetKey, schema[$keys], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(target[targetKey], schema[$values], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n}\n\nexport const ascertain = (schema, data, rootName = '[root]') => {\n const result = certain(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n\nexport default ascertain;\n"],"names":["AssertError","constructor","value","expected","path","subject","toString","JSON","stringify","findFirstError","array","map","i","length","error","findNotError","errors","push","reduce","result","join","string","Optional","schema","And","Or","optional","and","or","$keys","Symbol","for","$values","fromBase64","Buffer","atob","from","MULTIPLIERS","ms","s","m","h","d","w","as","undefined","number","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","_","amount","unit","parseInt","boolean","test","delimiter","split","json","e","base64","certain","target","isValue","name","Array","isArray","idx","itemSchemaType","RegExp","source","targetKeys","Object","keys","assertError","targetKey","key","ascertain","data","rootName","TypeError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "ascertain",
3
- "version": "0.13.4",
3
+ "version": "0.14.0",
4
4
  "description": "0-Deps, simple, fast, for browser and node js object schema validator",
5
- "main": "build/index.js",
5
+ "type": "module",
6
6
  "types": "build/index.d.ts",
7
- "scripts": {
8
- "build": "NODE_ENV=production swc src/index.js -d build --ignore **/__tests__,**/__fixtures__ --strip-leading-paths && cp src/index.d.ts build",
9
- "test": "NODE_ENV=test jest",
10
- "test:cov": "COVERAGE=1 NODE_ENV=test jest"
7
+ "main": "build/index.cjs",
8
+ "module": "build/index.js",
9
+ "exports": {
10
+ "require": "./build/index.cjs",
11
+ "import": "./build/index.js"
11
12
  },
13
+ "files": [
14
+ "build",
15
+ "src/index.js"
16
+ ],
12
17
  "repository": {
13
18
  "type": "git",
14
19
  "url": "git+https://github.com/3axap4eHko/ascertain.git"
@@ -36,6 +41,13 @@
36
41
  "@swc/cli": "^0.3.12",
37
42
  "@swc/core": "^1.4.12",
38
43
  "@swc/jest": "^0.2.36",
44
+ "inop": "^0.6.0",
39
45
  "jest": "^29.7.0"
46
+ },
47
+ "scripts": {
48
+ "build": "rm -rf build && NODE_ENV=production inop src/ build -t js -i __tests__ && cp src/index.d.ts build",
49
+ "build:2": "NODE_ENV=production swc src/index.js -d build --ignore **/__tests__,**/__fixtures__ --strip-leading-paths && cp src/index.d.ts build",
50
+ "test": "NODE_ENV=test jest",
51
+ "test:cov": "COVERAGE=1 NODE_ENV=test jest"
40
52
  }
41
- }
53
+ }
package/src/index.js ADDED
@@ -0,0 +1,201 @@
1
+ class AssertError {
2
+ constructor(value, expected, path, subject = 'value') {
3
+ this.value = value;
4
+ this.expected = expected;
5
+ this.path = path;
6
+ this.subject = subject;
7
+ }
8
+
9
+ toString() {
10
+ return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;
11
+ }
12
+ }
13
+
14
+ function findFirstError(array, map) {
15
+ for (let i = 0; i < array.length; i++) {
16
+ const error = map(array[i], i);
17
+ if (error) {
18
+ return error;
19
+ }
20
+ }
21
+ return false;
22
+ }
23
+
24
+ function findNotError(array, map) {
25
+ const errors = [];
26
+ for (let i = 0; i < array.length; i++) {
27
+ const error = map(array[i], i);
28
+ if (!error) {
29
+ return false;
30
+ } else {
31
+ errors.push(error);
32
+ }
33
+ }
34
+ return errors.reduce((result, error) => {
35
+ return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);
36
+ });
37
+ }
38
+
39
+ function Optional(schema) {
40
+ this.schema = schema;
41
+ }
42
+
43
+ function And(schema) {
44
+ this.schema = schema;
45
+ }
46
+
47
+ function Or(schema) {
48
+ this.schema = schema;
49
+ }
50
+
51
+ export const optional = (schema) => {
52
+ return new Optional(schema);
53
+ };
54
+
55
+ export const and = (...schema) => {
56
+ return new And(schema);
57
+ };
58
+
59
+ export const or = (...schema) => {
60
+ return new Or(schema);
61
+ };
62
+
63
+ export const $keys = Symbol.for('@@keys');
64
+ export const $values = Symbol.for('@@values');
65
+
66
+ export const fromBase64 =
67
+ typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');
68
+
69
+ const MULTIPLIERS = {
70
+ ms: 1,
71
+ s: 1000,
72
+ m: 60000,
73
+ h: 3600000,
74
+ d: 86400000,
75
+ w: 604800000,
76
+ };
77
+
78
+ export const as = {
79
+ string: (value) => {
80
+ return typeof value === 'string' ? value : undefined;
81
+ },
82
+ number: (value) => {
83
+ const result = parseFloat(value);
84
+ return Number.isFinite(result) ? result : undefined;
85
+ },
86
+ date: (value) => {
87
+ const result = Date.parse(value);
88
+ return Number.isFinite(result) ? new Date(result) : undefined;
89
+ },
90
+ time: (value) => {
91
+ const matches = value?.match(/^(\d+)(ms|s|m|h|d|w)?$/);
92
+ if (matches) {
93
+ const [_, amount, unit = 'ms'] = matches;
94
+ return parseInt(amount, 10) * MULTIPLIERS[unit];
95
+ }
96
+ return undefined;
97
+ },
98
+ boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),
99
+ array: (value, delimiter) => value?.split(delimiter) ?? undefined,
100
+ json: (value) => {
101
+ try {
102
+ return JSON.parse(value);
103
+ } catch (e) {
104
+ return undefined;
105
+ }
106
+ },
107
+ base64: (value) => {
108
+ try {
109
+ return fromBase64(value);
110
+ } catch (e) {
111
+ return undefined;
112
+ }
113
+ },
114
+ };
115
+
116
+ function certain(target, schema, path, optional) {
117
+ if (schema === null || typeof schema === 'undefined') {
118
+ return new AssertError(schema, 'any value', path, 'schema value');
119
+ }
120
+ if (schema instanceof Optional) {
121
+ return certain(target, schema.schema, path, true);
122
+ }
123
+ const isValue = target !== null && typeof target !== 'undefined';
124
+ if (!isValue && optional) {
125
+ return;
126
+ }
127
+ if (schema instanceof Or) {
128
+ if (!schema.schema.length) {
129
+ return new AssertError(target, 'values', path, 'OR schema');
130
+ }
131
+ return findNotError(schema.schema, (schema) => certain(target, schema, path));
132
+ }
133
+ if (schema instanceof And) {
134
+ if (!schema.schema.length) {
135
+ return new AssertError(target, 'values', path, 'AND schema');
136
+ }
137
+ return findFirstError(schema.schema, (schema) => certain(target, schema, path));
138
+ }
139
+
140
+ if (typeof schema === 'function') {
141
+ if (!isValue) {
142
+ return new AssertError(target, schema.name, path);
143
+ }
144
+ if (typeof target === 'object' && !(target instanceof schema)) {
145
+ return new AssertError(target, schema.name, path);
146
+ }
147
+ if (typeof target !== 'object' && target.constructor !== schema) {
148
+ return new AssertError(target, schema.name, path);
149
+ }
150
+ } else if (Array.isArray(schema)) {
151
+ if (!Array.isArray(target)) {
152
+ return new AssertError(target, schema.constructor.name, path);
153
+ }
154
+ return findFirstError(target, (value, idx) => {
155
+ return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));
156
+ });
157
+ } else if (typeof schema === 'object') {
158
+ if (schema instanceof RegExp) {
159
+ if (!schema.test('' + target)) {
160
+ return new AssertError(target, `matching /${schema.source}/`, path);
161
+ }
162
+ } else {
163
+ if (typeof target !== 'object') {
164
+ return new AssertError(target, schema.constructor.name, path);
165
+ }
166
+ if (target === null) {
167
+ return new AssertError(target, 'an object', path);
168
+ }
169
+ if ($keys in schema) {
170
+ const targetKeys = Object.keys(target);
171
+ const assertError = findFirstError(targetKeys, (targetKey) =>
172
+ certain(targetKey, schema[$keys], `${path}.${targetKey}`)
173
+ );
174
+ if (assertError) {
175
+ return assertError;
176
+ }
177
+ }
178
+ if ($values in schema) {
179
+ const targetKeys = Object.keys(target);
180
+ const assertError = findFirstError(targetKeys, (targetKey) =>
181
+ certain(target[targetKey], schema[$values], `${path}.${targetKey}`)
182
+ );
183
+ if (assertError) {
184
+ return assertError;
185
+ }
186
+ }
187
+ return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));
188
+ }
189
+ } else if (target !== schema) {
190
+ return new AssertError(target, schema, path);
191
+ }
192
+ }
193
+
194
+ export const ascertain = (schema, data, rootName = '[root]') => {
195
+ const result = certain(data, schema, rootName);
196
+ if (result instanceof AssertError) {
197
+ throw new TypeError(result.toString());
198
+ }
199
+ };
200
+
201
+ export default ascertain;
package/.swcrc DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/swcrc",
3
- "module": {
4
- "type": "commonjs",
5
- "strict": true,
6
- "strictMode": true
7
- },
8
- "jsc": {
9
- "target": "es2022",
10
- "parser": {
11
- "syntax": "ecmascript"
12
- },
13
- "externalHelpers": false,
14
- "keepClassNames": true
15
- }
16
- }