@awesomeness-js/utils 1.0.20 → 1.0.21

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.
package/index.js CHANGED
@@ -10,7 +10,6 @@ import _clean_integer from './src/clean/integer.js';
10
10
  import _clean_number from './src/clean/number.js';
11
11
  import _clean_object from './src/clean/object.js';
12
12
  import _clean_string from './src/clean/string.js';
13
- import _clean_thing from './src/clean/thing.js';
14
13
  import _clean_timestamp from './src/clean/timestamp.js';
15
14
  import _clean_uuid from './src/clean/uuid.js';
16
15
  import _combineFiles from './src/combineFiles.js';
@@ -31,6 +30,7 @@ import _thingType from './src/thingType.js';
31
30
  import _toPennies from './src/toPennies.js';
32
31
  import _utils_buildExportsTree from './src/utils/buildExportsTree.js';
33
32
  import _utils_buildFileDataList from './src/utils/buildFileDataList.js';
33
+ import _utils_clean from './src/utils/clean.js';
34
34
  import _utils_extractJSDocComment from './src/utils/extractJSDocComment.js';
35
35
  import _utils_generateFile from './src/utils/generateFile.js';
36
36
  import _utils_generateFlatExportLines from './src/utils/generateFlatExportLines.js';
@@ -111,7 +111,6 @@ export default {
111
111
  number: _clean_number,
112
112
  object: _clean_object,
113
113
  string: _clean_string,
114
- thing: _clean_thing,
115
114
  timestamp: _clean_timestamp,
116
115
  uuid: _clean_uuid,
117
116
  },
@@ -125,6 +124,7 @@ export default {
125
124
  utils: {
126
125
  buildExportsTree: _utils_buildExportsTree,
127
126
  buildFileDataList: _utils_buildFileDataList,
127
+ clean: _utils_clean,
128
128
  extractJSDocComment: _utils_extractJSDocComment,
129
129
  generateFile: _utils_generateFile,
130
130
  generateFlatExportLines: _utils_generateFlatExportLines,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomeness-js/utils",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "Awesomeness - Utils",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,43 +1,2 @@
1
- import thingType from '../thingType.js';
2
- function cleanArray(arr, schema = {}){
3
-
4
- if(!Array.isArray(arr)) {
5
- throw {
6
- name: 'TypeError',
7
- message: 'Input must be an array',
8
- arr
9
- };
10
- }
11
-
12
- validateSchema(schema);
13
-
14
- const cleanArrayItems = [];
15
-
16
- const supposedToBeType = schema.type;
17
-
18
- arr.forEach( item => {
19
-
20
- const itemType = thingType(item);
21
-
22
- if(itemType !== supposedToBeType){
23
-
24
- throw {
25
- message: 'type invalid',
26
- itemType,
27
- supposedToBeType
28
- };
29
-
30
- }
31
-
32
- const cleanFnImported = import(`./${supposedToBeType}.js`);
33
- const cleanItem = cleanFnImported(value, schema[key]);
34
-
35
- cleanArrayItems.push(cleanItem);
36
-
37
- });
38
-
39
- return cleanArrayItems;
40
-
41
- }
42
-
43
- export default cleanArray;
1
+ import clean from '../utils/clean.js';
2
+ export default clean.array;
@@ -1,5 +1,6 @@
1
1
  export default function cleanInt(x, {
2
2
  required = false,
3
+ convertString = true,
3
4
  min = false,
4
5
  max = false,
5
6
  } = {}){
@@ -9,8 +10,26 @@ export default function cleanInt(x, {
9
10
  if (typeof x !== 'number' || !Number.isInteger(x)) {
10
11
 
11
12
  // convert string to number if possible
12
- if (typeof x === 'string' && !isNaN(parseInt(x))) {
13
- x = parseInt(x);
13
+ // but not a decimal string
14
+ if (convertString && typeof x === 'string') {
15
+
16
+ if(x.includes('.')){
17
+ throw {
18
+ message: 'string contains decimal',
19
+ value: x
20
+ };
21
+ }
22
+
23
+ if(!isNaN(parseInt(x))){
24
+ x = parseInt(x);
25
+ } else {
26
+ throw {
27
+ message: 'string cannot be parsed to integer',
28
+ value: x
29
+ }
30
+ }
31
+
32
+
14
33
  } else {
15
34
  throw {
16
35
  message: 'Input must be an integer',
@@ -1,5 +1,6 @@
1
1
  export default function cleanNumber(x, {
2
2
  required = false,
3
+ convertString = true,
3
4
  min = false,
4
5
  max = false,
5
6
  maxDecimal = false,
@@ -11,8 +12,25 @@ export default function cleanNumber(x, {
11
12
  if (typeof x !== 'number') {
12
13
 
13
14
  // convert string to number if possible
14
- if (typeof x === 'string' && !isNaN(parseFloat(x))) {
15
- x = parseFloat(x);
15
+ if (convertString && typeof x === 'string') {
16
+
17
+ try {
18
+ x = parseFloat(x);
19
+ } catch(e){
20
+ throw {
21
+ message: 'Input cannot be parsed',
22
+ value: x
23
+ }
24
+ }
25
+
26
+
27
+ if(isNaN(x)){
28
+ throw {
29
+ message: 'Input cannot be parsed NaN',
30
+ value: x
31
+ }
32
+ }
33
+
16
34
  } else {
17
35
  throw {
18
36
  message: 'Input must be a number',
@@ -1,67 +1,3 @@
1
- import each from '../each.js';
2
- import validateSchema from '../validateSchema.js';
3
- import thingType from '../thingType.js';
4
-
5
- function cleanObject(obj, schema = {}){
6
-
7
- try {
8
-
9
- validateSchema(schema);
10
-
11
- if(typeof obj !== 'object' || obj === null){
12
- throw {
13
- message: 'Input must be an object',
14
- obj
15
- };
16
- }
17
-
18
- let keysPassed = Object.keys(obj);
19
- let keysSchema = Object.keys(schema.properties);
20
-
21
- const origLength = keysPassed.length;
22
- keysPassed = keysPassed.filter(key => keysSchema.includes(key));
23
-
24
- if(origLength !== keysPassed.length){
25
- throw {
26
- name: 'KeyError',
27
- message: 'Object contains keys not in schema',
28
- keysPassed,
29
- keysSchema
30
- };
31
- }
32
-
33
- const cleanObj = {};
34
-
35
- // Iterate over the schema keys
36
- each(obj, (value, key) => {
37
-
38
- const valType = thingType(value);
39
- const supposedToBeType = schema[key].type;
40
-
41
- if(valType !== supposedToBeType){
42
-
43
- throw {
44
- message: 'type invalid',
45
- valType,
46
- supposedToBeType
47
- };
48
-
49
- }
50
-
51
- const cleanFnImported = import(`./${supposedToBeType}.js`);
52
- cleanObj[key] = cleanFnImported(value, schema[key]);
53
-
54
- });
55
-
56
- return cleanObj;
57
-
58
- } catch(e){
59
-
60
- if(required) { throw e; } else { return null; }
61
-
62
- }
63
-
64
- }
65
-
66
- export default cleanObject;
1
+ import clean from '../utils/clean.js';
2
+ export default clean.object;
67
3
 
@@ -5,6 +5,8 @@ export default function cleanString(x, {
5
5
  allowHtml = false,
6
6
  allowScripts = false
7
7
  } = {}){
8
+
9
+ if(allowScripts && !allowHtml){ allowHtml = true; }
8
10
 
9
11
  try {
10
12
 
@@ -22,10 +22,6 @@ export default function cleanTimestamp( isoDateTimeString , {
22
22
  };
23
23
  }
24
24
 
25
- if(maxDaysInFuture === false && maxDaysInFPast === false) {
26
- return isoDateTimeString;
27
- }
28
-
29
25
  const now = new Date();
30
26
 
31
27
  if(maxDaysInFuture !== false && (date - now) > maxDaysInFuture * 24 * 60 * 60 * 1000) {
@@ -42,7 +38,7 @@ export default function cleanTimestamp( isoDateTimeString , {
42
38
  };
43
39
  }
44
40
 
45
- return isoDateTimeString;
41
+ return date.toISOString();
46
42
 
47
43
  } catch (e) {
48
44
 
package/src/thingType.js CHANGED
@@ -28,6 +28,8 @@ export default (thing) => {
28
28
  let is_iso_dateTime = thing && typeof thing === 'string' && thing.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/);
29
29
  if(is_iso_dateTime) { type = 'timestamp'; return type; }
30
30
 
31
+ return type;
32
+
31
33
 
32
34
  }
33
35
 
@@ -0,0 +1,183 @@
1
+ import thingType from '../thingType.js';
2
+ import validateSchema from '../validateSchema.js';
3
+ import each from '../each.js';
4
+
5
+ import cleanBoolean from '../clean/boolean.js';
6
+ import cleanInteger from '../clean/integer.js';
7
+ import cleanNumber from '../clean/number.js';
8
+ import cleanString from '../clean/string.js';
9
+ import cleanTimestamp from '../clean/timestamp.js';
10
+ import cleanUUID from '../clean/uuid.js';
11
+
12
+ function cleanArray(arr, schema = {}){
13
+
14
+ try {
15
+
16
+ if(!Array.isArray(arr)) {
17
+ throw {
18
+ message: 'Input must be an array',
19
+ arr
20
+ };
21
+ }
22
+
23
+ validateSchema(schema);
24
+
25
+ const cleanArrayItems = [];
26
+
27
+ const supposedToBeType = schema.items.type;
28
+
29
+ arr.forEach( (item, key) => {
30
+
31
+ const itemType = thingType(item);
32
+
33
+
34
+ if(itemType !== supposedToBeType){
35
+
36
+ throw {
37
+ message: 'type invalid',
38
+ itemType,
39
+ supposedToBeType
40
+ };
41
+
42
+ }
43
+
44
+ let cleanedItem = item;
45
+
46
+ if(supposedToBeType === 'boolean'){ cleanedItem = cleanBoolean(item); }
47
+ if(supposedToBeType === 'integer'){ cleanedItem = cleanInteger(item); }
48
+ if(supposedToBeType === 'number'){ cleanedItem = cleanNumber(item); }
49
+ if(supposedToBeType === 'string'){ cleanedItem = cleanString(item); }
50
+ if(supposedToBeType === 'timestamp'){ cleanedItem = cleanTimestamp(item); }
51
+ if(supposedToBeType === 'uuid'){ cleanedItem = cleanUUID(item); }
52
+
53
+ if(supposedToBeType === 'array'){
54
+ cleanedItem = cleanArray(item, schema.items);
55
+ }
56
+
57
+ if(supposedToBeType === 'object'){
58
+ cleanedItem = cleanObject(item, schema.items);
59
+ }
60
+
61
+ if(cleanedItem === null){
62
+ if(schema.required === true){
63
+ throw {
64
+ message: 'required item is null',
65
+ item,
66
+ key
67
+ };
68
+ } else {
69
+ return; // skip this item if it's not required and is null
70
+ }
71
+ }
72
+
73
+
74
+ cleanArrayItems.push(cleanedItem);
75
+
76
+ });
77
+
78
+ if(cleanArrayItems.length === 0){
79
+ throw {
80
+ message: 'array is empty',
81
+ arr
82
+ };
83
+ }
84
+
85
+ return cleanArrayItems;
86
+
87
+ } catch (e) {
88
+
89
+ if(schema.required === true){
90
+ throw e
91
+ } else {
92
+ return null;
93
+ }
94
+
95
+ }
96
+
97
+
98
+
99
+ }
100
+
101
+
102
+ function cleanObject(obj, schema){
103
+
104
+ validateSchema(schema);
105
+
106
+ if(typeof obj !== 'object' || obj === null){
107
+ throw {
108
+ message: 'Clean Object - Input must be an object',
109
+ obj,
110
+ schema
111
+ };
112
+ }
113
+
114
+ let keysPassed = Object.keys(obj);
115
+ let keysSchema = Object.keys(schema.properties);
116
+
117
+ const origLength = keysPassed.length;
118
+ keysPassed = keysPassed.filter(key => keysSchema.includes(key));
119
+
120
+ if(origLength !== keysPassed.length){
121
+ throw {
122
+ name: 'KeyError',
123
+ message: 'Object contains keys not in schema',
124
+ keysPassed,
125
+ keysSchema,
126
+ obj
127
+ };
128
+ }
129
+
130
+ const cleanObj = {};
131
+
132
+ // Iterate over the schema keys
133
+ each(obj, (value, key) => {
134
+
135
+ const valType = thingType(value);
136
+ const supposedToBeType = schema.properties[key].type;
137
+
138
+ if(valType !== supposedToBeType){
139
+
140
+ throw {
141
+ message: 'type invalid',
142
+ valType,
143
+ supposedToBeType,
144
+ key
145
+ };
146
+
147
+ }
148
+
149
+ let cleanedValue;
150
+
151
+ if(supposedToBeType === 'boolean'){ cleanedValue = cleanBoolean(value); }
152
+ if(supposedToBeType === 'integer'){ cleanedValue = cleanInteger(value); }
153
+ if(supposedToBeType === 'number'){ cleanedValue = cleanNumber(value); }
154
+ if(supposedToBeType === 'string'){ cleanedValue = cleanString(value); }
155
+ if(supposedToBeType === 'timestamp'){ cleanedValue = cleanTimestamp(value); }
156
+ if(supposedToBeType === 'uuid'){ cleanedValue = cleanUUID(value); }
157
+
158
+ if(supposedToBeType === 'object'){
159
+ cleanedValue = cleanObject(value, schema.properties[key]);
160
+ }
161
+
162
+ if(supposedToBeType === 'array'){
163
+ cleanedValue = cleanArray(value, schema.properties[key]);
164
+ }
165
+
166
+ cleanObj[key] = cleanedValue;
167
+
168
+ });
169
+
170
+ return cleanObj;
171
+
172
+ }
173
+
174
+ export default {
175
+ array: cleanArray,
176
+ object: cleanObject,
177
+ boolean: cleanBoolean,
178
+ integer: cleanInteger,
179
+ number: cleanNumber,
180
+ string: cleanString,
181
+ timestamp: cleanTimestamp,
182
+ uuid: cleanUUID
183
+ };
@@ -2,6 +2,13 @@ import each from './each.js';
2
2
 
3
3
  function validateSchema(schema){
4
4
 
5
+ if(!schema){
6
+ throw {
7
+ message: 'Schema is required.',
8
+ schema
9
+ };
10
+ }
11
+
5
12
  // ref todo
6
13
  if(schema.ref){ return true; }
7
14
 
@@ -9,8 +16,9 @@ function validateSchema(schema){
9
16
 
10
17
  if(schemaType !== 'object' || schema === null) {
11
18
  throw {
12
- message: 'Input must be an object',
13
- schema
19
+ message: 'Schema Invalid - Input must be an object',
20
+ schema,
21
+ schemaType
14
22
  };
15
23
  }
16
24
 
@@ -0,0 +1,154 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ const testStringArray = [ 'a', 'b', 'c' ];
6
+ const testIntegerArray = [ 1, 2, 3, 4, 5 ];
7
+ const testBooleanArray = [true, false, true, false];
8
+
9
+ const testArrayOfArraysOfIntegers = [
10
+ testIntegerArray,
11
+ testIntegerArray,
12
+ testIntegerArray
13
+ ];
14
+
15
+ const testArrayOfArraysOfStrings = [
16
+ testStringArray,
17
+ testStringArray,
18
+ testStringArray
19
+ ];
20
+
21
+ const schemaForStrings = {
22
+ type: 'array',
23
+ items: {
24
+ type: 'string'
25
+ }
26
+ };
27
+
28
+ const schemaForIntegers = {
29
+ type: 'array',
30
+ items: {
31
+ type: 'integer'
32
+ }
33
+ };
34
+
35
+
36
+ const schemaForBooleans = {
37
+ type: 'array',
38
+ items: {
39
+ type: 'boolean'
40
+ }
41
+ };
42
+
43
+ const schemaForArrayOfArrays_integers = {
44
+ type: 'array',
45
+ items: {
46
+ type: 'array',
47
+ items: { type: 'integer' }
48
+ }
49
+ };
50
+
51
+ const schemaForArrayOfArrays_strings = {
52
+ type: 'array',
53
+ items: {
54
+ type: 'array',
55
+ items: { type: 'string' }
56
+ }
57
+ };
58
+
59
+ const testObject = {
60
+ stringProp: 'a string',
61
+ integerProp: 42,
62
+ numberProp: 3.14,
63
+ booleanProp: true,
64
+ timestampProp: new Date().toISOString(),
65
+ uuidProp: utils.uuid(), // generate a valid UUID
66
+ };
67
+
68
+ const arrayOfObjects = [
69
+ { ...testObject },
70
+ { ...testObject },
71
+ { ...testObject }
72
+ ];
73
+
74
+ const objSchema = {
75
+ type: 'object',
76
+ properties: {
77
+ stringProp: { type: 'string', required: true },
78
+ integerProp: { type: 'integer', required: true },
79
+ numberProp: { type: 'number', required: true },
80
+ booleanProp: { type: 'boolean', required: true },
81
+ timestampProp: { type: 'timestamp', required: true },
82
+ uuidProp: { type: 'uuid', required: true },
83
+ optionalStringProp: { type: 'string', required: false },
84
+ optionalIntegerProp: { type: 'integer', required: false },
85
+ optionalNumberProp: { type: 'number', required: false },
86
+ optionalBooleanProp: { type: 'boolean', required: false },
87
+ optionalTimestampProp: { type: 'timestamp', required: false },
88
+ optionalUuidProp: { type: 'uuid', required: false }
89
+ },
90
+ };
91
+
92
+
93
+ const schemaForArrayOfObjects = {
94
+ type: 'array',
95
+ required: true,
96
+ items: {
97
+ ... objSchema,
98
+ }
99
+ };
100
+
101
+ test('testStringArray', () => {
102
+
103
+ const x = utils.clean.array(testStringArray, schemaForStrings);
104
+ expect(x).toStrictEqual(testStringArray);
105
+
106
+ });
107
+
108
+ test('testIntegerArray', () => {
109
+
110
+ const x = utils.clean.array(testIntegerArray, schemaForIntegers);
111
+ expect(x).toStrictEqual(testIntegerArray);
112
+
113
+ });
114
+
115
+ test('testBooleanArray', () => {
116
+
117
+ const x = utils.clean.array(testBooleanArray, schemaForBooleans);
118
+ expect(x).toStrictEqual(testBooleanArray);
119
+
120
+ });
121
+
122
+ test('testBooleanArray but pass different schema', () => {
123
+
124
+ expect(()=> utils.clean.array(testBooleanArray, { ... schemaForIntegers, required: true }) ).toThrow();
125
+
126
+ });
127
+
128
+ test('schemaForArrayOfArrays_integers', () => {
129
+
130
+ const x = utils.clean.array(testArrayOfArraysOfIntegers, schemaForArrayOfArrays_integers);
131
+ expect(x).toStrictEqual(testArrayOfArraysOfIntegers);
132
+
133
+ });
134
+
135
+ test('schemaForArrayOfArrays_strings', () => {
136
+
137
+ const x = utils.clean.array(testArrayOfArraysOfStrings, schemaForArrayOfArrays_strings);
138
+ expect(x).toStrictEqual(testArrayOfArraysOfStrings);
139
+
140
+ });
141
+
142
+ test('schemaForArrayOfArrays_strings wrong type', () => {
143
+
144
+ const x = utils.clean.array(testArrayOfArraysOfStrings, schemaForArrayOfArrays_integers);
145
+ expect(x).toBe(null);
146
+
147
+ });
148
+
149
+ test('schemaForArrayOfObjects', () => {
150
+
151
+ const x = utils.clean.array(arrayOfObjects, schemaForArrayOfObjects);
152
+ expect(x).toStrictEqual(arrayOfObjects);
153
+
154
+ });
@@ -0,0 +1,27 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ let x = true;
6
+ let y = false;
7
+ let z = 1;
8
+
9
+ test('boolean - true', () => {
10
+ expect(utils.clean.boolean(x)).toBe(true);
11
+ });
12
+
13
+ test('boolean - false', () => {
14
+ expect(utils.clean.boolean(y)).toBe(false);
15
+ });
16
+
17
+ test('boolean - number', () => {
18
+ expect(utils.clean.boolean(z)).toBe(null);
19
+ });
20
+
21
+ test('boolean - NOT to throw', () => {
22
+ expect(() => utils.clean.boolean(y, { required: true })).not.toThrow();
23
+ });
24
+
25
+ test('boolean - to throw', () => {
26
+ expect(() => utils.clean.boolean(z, { required: true })).toThrow();
27
+ });
@@ -0,0 +1,39 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ let x = 1;
6
+ let y = 1.2;
7
+ let z = '102';
8
+ let z2 = '102.45';
9
+ let z3 = 102.45;
10
+
11
+ test('integer - 1', () => {
12
+ expect(utils.clean.integer(x)).toBe(1);
13
+ });
14
+
15
+ test('integer - null', () => {
16
+ expect(utils.clean.integer(y)).toBe(null);
17
+ });
18
+
19
+
20
+ test('integer as string - 102', () => {
21
+ expect(utils.clean.integer(z)).toBe(102);
22
+ });
23
+
24
+ test('integer - NOT to throw - 102', () => {
25
+ expect(() => utils.clean.integer(z, { required: true })).not.toThrow();
26
+ });
27
+
28
+ test('integer - to throw', () => {
29
+ expect(() => utils.clean.integer(y, { required: true })).toThrow();
30
+ });
31
+
32
+ test('integer - to throw - "102.45"', () => {
33
+ expect(() => utils.clean.integer(z2, { required: true })).toThrow();
34
+ });
35
+
36
+ test('integer - to throw - 102.45', () => {
37
+ console.log(utils.clean.integer(z3));
38
+ expect(() => utils.clean.integer(z3, { required: true })).toThrow();
39
+ });
@@ -0,0 +1,49 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ let x = 1;
6
+ let y = 1.2;
7
+ let z = '102';
8
+ let z2 = '102.45';
9
+ let bad = 'bad';
10
+
11
+ test('number - 1', () => {
12
+ expect(utils.clean.number(x)).toBe(1);
13
+ });
14
+
15
+ test('number - 1.2', () => {
16
+ expect(utils.clean.number(y)).toBe(1.2);
17
+ });
18
+
19
+ test('number as string - 102', () => {
20
+ expect(utils.clean.number(z)).toBe(102);
21
+ });
22
+
23
+ test('number - string to 102', () => {
24
+ expect(utils.clean.number(z, { required: true })).toBe(102);
25
+ });
26
+
27
+ test('number - string to 102.45', () => {
28
+ console.log(utils.clean.number(z2));
29
+ expect(utils.clean.number(z2, { required: true })).toBe(102.45);
30
+ });
31
+
32
+ test('number as string - bad to null', () => {
33
+ expect(utils.clean.number(bad)).toBe(null);
34
+ });
35
+
36
+ test('number as string - bad to throw', () => {
37
+ expect(()=> utils.clean.number(bad, { required: true }) ).toThrow();
38
+ });
39
+
40
+ test('number is too high', () => {
41
+ expect(()=> utils.clean.number(100, { min: 1, max: 10, required: true }) ).toThrow();
42
+ expect(()=> utils.clean.number(100.11, { min: 1, max: 100.1, required: true }) ).toThrow();
43
+ });
44
+
45
+ test('number is too low', () => {
46
+ expect(()=> utils.clean.number(0, { min: 1, max: 10, required: true }) ).toThrow();
47
+ expect(()=> utils.clean.number(1.2, { min: 1.3, max: 10, required: true }) ).toThrow();
48
+ });
49
+
@@ -0,0 +1,172 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ const testObject = {
6
+ stringProp: 'a string',
7
+ integerProp: 42,
8
+ numberProp: 3.14,
9
+ booleanProp: true,
10
+ timestampProp: new Date().toISOString(),
11
+ uuidProp: utils.uuid(), // generate a valid UUID
12
+ };
13
+
14
+ const invalidTestObject = {
15
+ stringProp: 123, // should be a string
16
+ integerProp: 'not an integer', // should be an integer
17
+ numberProp: 'not a number', // should be a number
18
+ booleanProp: 'not a boolean', // should be a boolean
19
+ timestampProp: 'not a timestamp', // should be a timestamp
20
+ uuidProp: 'not a uuid', // should be a uuid
21
+ optionalStringProp: 456, // should be a string
22
+ optionalIntegerProp: 'not an integer', // should be an integer
23
+ optionalNumberProp: 'not a number', // should be a number
24
+ optionalBooleanProp: 'not a boolean', // should be a boolean
25
+ optionalTimestampProp: 'not a timestamp', // should be a timestamp
26
+ optionalUuidProp: 'not a uuid' // should be a uuid
27
+ };
28
+
29
+ const testObject2 = {
30
+ obj1: { ...testObject },
31
+ obj2: { ...testObject }
32
+ };
33
+
34
+ const invalidTestObject2 = {
35
+ obj1: { ...invalidTestObject },
36
+ obj2: { ...invalidTestObject }
37
+ };
38
+
39
+ const schema = {
40
+ type: 'object',
41
+ properties: {
42
+ stringProp: { type: 'string', required: true },
43
+ integerProp: { type: 'integer', required: true },
44
+ numberProp: { type: 'number', required: true },
45
+ booleanProp: { type: 'boolean', required: true },
46
+ timestampProp: { type: 'timestamp', required: true },
47
+ uuidProp: { type: 'uuid', required: true },
48
+ optionalStringProp: { type: 'string', required: false },
49
+ optionalIntegerProp: { type: 'integer', required: false },
50
+ optionalNumberProp: { type: 'number', required: false },
51
+ optionalBooleanProp: { type: 'boolean', required: false },
52
+ optionalTimestampProp: { type: 'timestamp', required: false },
53
+ optionalUuidProp: { type: 'uuid', required: false }
54
+ },
55
+ };
56
+
57
+ const schema2 = {
58
+ type: 'object',
59
+ properties: {
60
+ obj1: {
61
+ type: 'object',
62
+ required: true,
63
+ properties: { ... schema.properties }
64
+ },
65
+ obj2: {
66
+ type: 'object',
67
+ required: true,
68
+ properties: { ... schema.properties }
69
+ }
70
+ },
71
+ };
72
+
73
+
74
+ const testArraysOfIntegers = [
75
+ [1, 2, 3],
76
+ [4, 5, 6],
77
+ [7, 8, 9]
78
+ ];
79
+
80
+ const testStringArrayOfArrays = [
81
+ ['a', 'b', 'c'],
82
+ ['d', 'e', 'f'],
83
+ ['g', 'h', 'i'],
84
+ ];
85
+
86
+ const testArrayOfBooleans = [
87
+ [true, false, true],
88
+ [false, true, false],
89
+ [true, true, false]
90
+ ];
91
+
92
+ const objectOfArrays = {
93
+ testArraysOfIntegers: [...testArraysOfIntegers],
94
+ testStringArrayOfArrays: [...testStringArrayOfArrays],
95
+ testArrayOfBooleans: [...testArrayOfBooleans],
96
+ };
97
+
98
+ const objectOfArrays_schema = {
99
+ type: 'object',
100
+ properties: {
101
+ testArraysOfIntegers: {
102
+ type: 'array',
103
+ items: {
104
+ type: 'array',
105
+ items: { type: 'integer' }
106
+ }
107
+ },
108
+ testStringArrayOfArrays: {
109
+ type: 'array',
110
+ items: {
111
+ type: 'array',
112
+ items: { type: 'string' }
113
+ }
114
+ },
115
+ testArrayOfBooleans: {
116
+ type: 'array',
117
+ items: {
118
+ type: 'array',
119
+ items: { type: 'boolean' }
120
+ }
121
+ }
122
+ }
123
+ };
124
+
125
+ test('testObject', () => {
126
+ try {
127
+ const cleanedObject = utils.clean.object(testObject, schema);
128
+ expect(cleanedObject).toStrictEqual(testObject);
129
+ } catch (error) {
130
+ console.error('Error cleaning object:', error);
131
+ throw error; // rethrow to fail the test
132
+ }
133
+ });
134
+
135
+ test('invalidTestObject', () => {
136
+ try {
137
+ const cleanedObject = utils.clean.object(invalidTestObject, schema);
138
+ //console.log({ cleanedObject })
139
+ expect(cleanedObject).toStrictEqual(invalidTestObject);
140
+ } catch (error) {
141
+ //console.error('Error cleaning object:', error);
142
+ expect(error.message).toBe('type invalid');
143
+ }
144
+ });
145
+
146
+ test('testObject2', () => {
147
+ try {
148
+ const cleanedObject = utils.clean.object(testObject2, schema2);
149
+ //console.log('cleanedObject', cleanedObject);
150
+ expect(cleanedObject).toStrictEqual(testObject2);
151
+ } catch (error) {
152
+ console.error('Error cleaning object:', error);
153
+ throw error; // rethrow to fail the test
154
+ }
155
+ });
156
+
157
+
158
+ test('incorrect should throw', () => {
159
+ expect(()=> utils.clean.object(testObject, schema2)).toThrow();
160
+ });
161
+
162
+
163
+ test('object of arrays test', () => {
164
+ try {
165
+ const cleanedObject = utils.clean.object(objectOfArrays, objectOfArrays_schema);
166
+ //console.log('cleanedObject', cleanedObject);
167
+ expect(cleanedObject).toStrictEqual(objectOfArrays);
168
+ } catch (error) {
169
+ console.error('Error cleaning object:', error);
170
+ throw error; // rethrow to fail the test
171
+ }
172
+ });
@@ -0,0 +1,44 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ test('good string', () => {
6
+ expect(utils.clean.string('good string')).toBe('good string');
7
+ });
8
+
9
+ test('number', () => {
10
+ expect(utils.clean.string(123)).toBe(null);
11
+ expect(()=> utils.clean.string(123, { required: true })).toThrow();
12
+ });
13
+
14
+ test('string too short', () => {
15
+ expect(utils.clean.string('123456789', { minLength: 10 })).toBe(null);
16
+ expect(()=> utils.clean.string('123456789', { minLength: 10, required: true })).toThrow();
17
+ });
18
+
19
+ test('string too long', () => {
20
+ expect(utils.clean.string('123456789', { maxLength: 5 })).toBe(null);
21
+ expect(()=> utils.clean.string('123456789', { maxLength: 5, required: true })).toThrow();
22
+ });
23
+
24
+ test('no html', () => {
25
+ expect(utils.clean.string('<div>no go</div>')).toBe(null);
26
+ expect(()=> utils.clean.string('<div>no go</div>', { required: true })).toThrow();
27
+ });
28
+
29
+ test('no script', () => {
30
+ expect(utils.clean.string('<script>no go</script>')).toBe(null);
31
+ expect(()=> utils.clean.string('<script>no go</script>', { required: true })).toThrow();
32
+ });
33
+
34
+ test('allow html', () => {
35
+ let x = utils.clean.string('<div>all good/div>', { allowHtml: true });
36
+ expect(utils.clean.string('<div>all good</div>', { allowHtml: true })).toBe('<div>all good</div>');
37
+ expect(utils.clean.string('<div>all good</div>', { allowHtml: true, required: true })).toBe('<div>all good</div>');
38
+ });
39
+
40
+ test('allow script', () => {
41
+ expect(utils.clean.string('<script>all good</script>', { allowScripts: true })).toBe('<script>all good</script>');
42
+ expect(utils.clean.string('<script>all good</script>', { allowScripts: true, required: true })).toBe('<script>all good</script>');
43
+ });
44
+
@@ -0,0 +1,13 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ test('good timestamp', () => {
6
+ const x = utils.clean.timestamp('2024-12-30');
7
+ expect(x).toBe('2024-12-30T00:00:00.000Z');
8
+ });
9
+
10
+ test('bad timestamp', () => {
11
+ expect(utils.clean.timestamp('2024-12-32')).toBe(null);
12
+ expect(()=>utils.clean.timestamp('2024-12-32', { required: true })).toThrow();
13
+ });
@@ -0,0 +1,14 @@
1
+ // example.test.js
2
+ import { expect, test } from 'vitest'
3
+ import utils from '../../index.js';
4
+
5
+ test('good uuid', () => {
6
+ const id = utils.uuid();
7
+ const x = utils.clean.uuid(id);
8
+ expect(x).toBe(id);
9
+ });
10
+
11
+ test('bad uuid', () => {
12
+ expect(utils.clean.uuid('2024-12-32')).toBe(null);
13
+ expect(()=>utils.clean.uuid('2024-12-32', { required: true })).toThrow();
14
+ });
@@ -3,7 +3,7 @@ import { expect, test } from 'vitest'
3
3
  import utils from '../index.js';
4
4
 
5
5
  // set AWESOMENESS_ENCRYPTION_KEY
6
- //await utils.setLocalEnvs('./secrets/dev.env');
6
+ await utils.setLocalEnvs('./secrets/dev.env');
7
7
 
8
8
  const storedHash = utils.password.hash('mySecret123');
9
9
 
package/tsconfig.json CHANGED
@@ -6,7 +6,8 @@
6
6
  "outDir": "types", // Output directory for type files
7
7
  "moduleResolution": "node",
8
8
  "skipLibCheck": true,
9
- "esModuleInterop": true
9
+ "esModuleInterop": true,
10
+ "types": ["vitest/globals"]
10
11
  },
11
12
  "include": ["src/**/*"],
12
13
  "exclude": [
@@ -1,2 +1 @@
1
- export default cleanArray;
2
- declare function cleanArray(arr: any, schema?: {}): any[];
1
+ export {};
@@ -1,5 +1,6 @@
1
- export default function cleanInt(x: any, { required, min, max, }?: {
1
+ export default function cleanInt(x: any, { required, convertString, min, max, }?: {
2
2
  required?: boolean;
3
+ convertString?: boolean;
3
4
  min?: boolean;
4
5
  max?: boolean;
5
6
  }): any;
@@ -1,5 +1,6 @@
1
- export default function cleanNumber(x: any, { required, min, max, maxDecimal, minDecimal, }?: {
1
+ export default function cleanNumber(x: any, { required, convertString, min, max, maxDecimal, minDecimal, }?: {
2
2
  required?: boolean;
3
+ convertString?: boolean;
3
4
  min?: boolean;
4
5
  max?: boolean;
5
6
  maxDecimal?: boolean;
@@ -1,2 +1 @@
1
- export default cleanObject;
2
- declare function cleanObject(obj: any, schema?: {}): {};
1
+ export {};
package/types/index.d.ts CHANGED
@@ -10,7 +10,6 @@ import type _clean_integer from './clean/integer';
10
10
  import type _clean_number from './clean/number';
11
11
  import type _clean_object from './clean/object';
12
12
  import type _clean_string from './clean/string';
13
- import type _clean_thing from './clean/thing';
14
13
  import type _clean_timestamp from './clean/timestamp';
15
14
  import type _clean_uuid from './clean/uuid';
16
15
  import type _combineFiles from './combineFiles';
@@ -31,6 +30,7 @@ import type _thingType from './thingType';
31
30
  import type _toPennies from './toPennies';
32
31
  import type _utils_buildExportsTree from './utils/buildExportsTree';
33
32
  import type _utils_buildFileDataList from './utils/buildFileDataList';
33
+ import type _utils_clean from './utils/clean';
34
34
  import type _utils_extractJSDocComment from './utils/extractJSDocComment';
35
35
  import type _utils_generateFile from './utils/generateFile';
36
36
  import type _utils_generateFlatExportLines from './utils/generateFlatExportLines';
@@ -111,7 +111,6 @@ declare const _default: {
111
111
  number: typeof _clean_number,
112
112
  object: typeof _clean_object,
113
113
  string: typeof _clean_string,
114
- thing: typeof _clean_thing,
115
114
  timestamp: typeof _clean_timestamp,
116
115
  uuid: typeof _clean_uuid,
117
116
  },
@@ -125,6 +124,7 @@ declare const _default: {
125
124
  utils: {
126
125
  buildExportsTree: typeof _utils_buildExportsTree,
127
126
  buildFileDataList: typeof _utils_buildFileDataList,
127
+ clean: typeof _utils_clean,
128
128
  extractJSDocComment: typeof _utils_extractJSDocComment,
129
129
  generateFile: typeof _utils_generateFile,
130
130
  generateFlatExportLines: typeof _utils_generateFlatExportLines,
@@ -0,0 +1,2 @@
1
+ export default cleanArray;
2
+ declare function cleanArray(arr: any, schema?: {}): any[];
package/vitest.config.js CHANGED
@@ -1,6 +1,16 @@
1
1
  export default {
2
2
  test: {
3
3
  globals: true,
4
- environment: 'node', // Use 'jsdom' for browser-like testing
4
+ environment: 'node',
5
+ watchExclude: [
6
+ '**/node_modules/**',
7
+ '**/dist/**',
8
+ '**/coverage/**',
9
+ '**/.git/**',
10
+ '**/!(**/*.test.js)' // Ignore everything except test files
11
+ ],
12
+ testMatch: [
13
+ '**/*.test.js'
14
+ ]
5
15
  },
6
- }
16
+ }
@@ -1,31 +0,0 @@
1
- import thingType from '../thingType.js';
2
-
3
- export default (thing, schema) => {
4
-
5
- const type = thingType(thing);
6
-
7
- let validTypes = [
8
- 'array',
9
- 'boolean',
10
- 'integer',
11
- 'number',
12
- 'object',
13
- 'string',
14
- 'timestamp',
15
- 'uuid'
16
- ];
17
-
18
- if(!validTypes.includes(type)){
19
- throw {
20
- message: `Invalid type "${type}" for thing`,
21
- thing
22
- }
23
- }
24
-
25
- const cleanFnImported = import(`./${type}.js`);
26
- const cleanedThing = cleanFnImported(thing, schema);
27
-
28
- return cleanedThing;
29
-
30
- }
31
-