immosquare-cleaner 0.1.23 → 0.1.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/immosquare-cleaner/version.rb +1 -1
- data/linters/rubocop-3.2.2.yml +1 -0
- data/linters/rubocop.yml +2 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/LICENSE +19 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/README.md +71 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/conf/config-schema.js +79 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/conf/environments.js +215 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs +1104 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map +1 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/dist/eslintrc.cjs +4333 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map +1 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js +532 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/config-array.js +523 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js +115 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js +145 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js +238 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/index.js +19 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js +225 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/config-array-factory.js +1149 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/flat-compat.js +318 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/index-universal.js +29 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/index.js +56 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/ajv.js +191 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/config-ops.js +135 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/config-validator.js +325 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js +63 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/naming.js +96 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js +42 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/lib/shared/types.js +149 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/strip-json-comments/index.d.ts +36 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/strip-json-comments/index.js +77 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/strip-json-comments/license +9 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/strip-json-comments/package.json +47 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/node_modules/strip-json-comments/readme.md +78 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/package.json +82 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/eslintrc/universal.js +9 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/LICENSE +19 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/README.md +57 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/package.json +31 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/src/configs/eslint-all.js +278 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/src/configs/eslint-recommended.js +76 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@eslint/js/src/index.js +17 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/LICENSE +201 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/README.md +342 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/api.js +1061 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/CHANGELOG.md +8 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/LICENSE +29 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/README.md +234 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/package.json +33 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/src/index.js +7 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/src/merge-strategy.js +53 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/src/object-schema.js +235 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/src/validation-strategy.js +102 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/tests/merge-strategy.js +66 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/tests/object-schema.js +611 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema/tests/validation-strategy.js +186 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/LICENSE +15 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/README.md +224 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/minimatch.js +947 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/node_modules/brace-expansion/LICENSE +21 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/node_modules/brace-expansion/README.md +129 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/node_modules/brace-expansion/index.js +201 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/node_modules/brace-expansion/package.json +47 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/node_modules/minimatch/package.json +33 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/@humanwhocodes/config-array/package.json +61 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/index.d.ts +415 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/license +9 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/package.json +68 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/readme.md +341 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/source/index.js +229 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/source/templates.js +134 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/chalk/source/util.js +39 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/LICENSE +15 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/README.md +230 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/minimatch.js +947 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/node_modules/brace-expansion/LICENSE +21 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/node_modules/brace-expansion/README.md +129 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/node_modules/brace-expansion/index.js +201 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/node_modules/brace-expansion/package.json +47 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/minimatch/package.json +33 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/index.d.ts +17 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/index.js +4 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/license +9 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex/index.d.ts +37 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex/index.js +10 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex/license +9 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex/package.json +55 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/node_modules/ansi-regex/readme.md +78 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/package.json +54 -0
- data/node_modules/@eslint-community/eslint-utils/node_modules/eslint/node_modules/strip-ansi/readme.md +46 -0
- data/node_modules/eslint-plugin-import/node_modules/debug/node_modules/ms/index.js +162 -0
- data/node_modules/eslint-plugin-import/node_modules/debug/node_modules/ms/license.md +21 -0
- data/node_modules/eslint-plugin-import/node_modules/debug/node_modules/ms/package.json +38 -0
- data/node_modules/eslint-plugin-import/node_modules/debug/node_modules/ms/readme.md +59 -0
- data/node_modules/npm-check-updates/build/package.json +2 -3
- data/node_modules/npm-check-updates/build/src/lib/runGlobal.js +18 -11
- data/node_modules/npm-check-updates/build/src/lib/runGlobal.js.map +1 -1
- data/node_modules/npm-check-updates/build/src/package-managers/bun.js +2 -3
- data/node_modules/npm-check-updates/build/src/package-managers/bun.js.map +1 -1
- data/node_modules/npm-check-updates/build/src/package-managers/npm.js +12 -8
- data/node_modules/npm-check-updates/build/src/package-managers/npm.js.map +1 -1
- data/node_modules/npm-check-updates/build/src/package-managers/pnpm.js +37 -14
- data/node_modules/npm-check-updates/build/src/package-managers/pnpm.js.map +1 -1
- data/node_modules/npm-check-updates/build/src/package-managers/yarn.js +36 -11
- data/node_modules/npm-check-updates/build/src/package-managers/yarn.js.map +1 -1
- data/node_modules/npm-check-updates/package.json +2 -3
- data/node_modules/prettier/LICENSE +3 -3
- data/node_modules/prettier/index.cjs +1 -1
- data/node_modules/prettier/index.mjs +14 -22
- data/node_modules/prettier/package.json +1 -1
- data/node_modules/prettier/plugins/acorn.js +10 -10
- data/node_modules/prettier/plugins/acorn.mjs +10 -10
- data/node_modules/prettier/plugins/angular.js +1 -1
- data/node_modules/prettier/plugins/angular.mjs +1 -1
- data/node_modules/prettier/plugins/babel.js +8 -8
- data/node_modules/prettier/plugins/babel.mjs +8 -8
- data/node_modules/prettier/plugins/estree.js +24 -24
- data/node_modules/prettier/plugins/estree.mjs +24 -24
- data/node_modules/prettier/plugins/flow.js +17 -17
- data/node_modules/prettier/plugins/flow.mjs +17 -17
- data/node_modules/prettier/plugins/graphql.js +6 -6
- data/node_modules/prettier/plugins/graphql.mjs +6 -6
- data/node_modules/prettier/plugins/html.js +1 -1
- data/node_modules/prettier/plugins/html.mjs +1 -1
- data/node_modules/prettier/plugins/markdown.js +1 -1
- data/node_modules/prettier/plugins/markdown.mjs +1 -1
- data/node_modules/prettier/plugins/meriyah.js +4 -4
- data/node_modules/prettier/plugins/meriyah.mjs +4 -4
- data/node_modules/prettier/plugins/typescript.js +19 -19
- data/node_modules/prettier/plugins/typescript.mjs +19 -19
- data/node_modules/prettier/standalone.js +10 -10
- data/node_modules/prettier/standalone.mjs +9 -9
- data/package.json +2 -2
- metadata +95 -4
@@ -0,0 +1,8 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
### [1.2.1](https://www.github.com/humanwhocodes/object-schema/compare/v1.2.0...v1.2.1) (2021-11-02)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* Never return original object from individual config ([5463c5c](https://www.github.com/humanwhocodes/object-schema/commit/5463c5c6d2cb35a7b7948dffc37c899a41d1775f))
|
@@ -0,0 +1,29 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2019, Human Who Codes
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived from
|
18
|
+
this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# JavaScript ObjectSchema Package
|
2
|
+
|
3
|
+
by [Nicholas C. Zakas](https://humanwhocodes.com)
|
4
|
+
|
5
|
+
If you find this useful, please consider supporting my work with a [donation](https://humanwhocodes.com/donate).
|
6
|
+
|
7
|
+
## Overview
|
8
|
+
|
9
|
+
A JavaScript object merge/validation utility where you can define a different merge and validation strategy for each key. This is helpful when you need to validate complex data structures and then merge them in a way that is more complex than `Object.assign()`.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
You can install using either npm:
|
14
|
+
|
15
|
+
```
|
16
|
+
npm install @humanwhocodes/object-schema
|
17
|
+
```
|
18
|
+
|
19
|
+
Or Yarn:
|
20
|
+
|
21
|
+
```
|
22
|
+
yarn add @humanwhocodes/object-schema
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Use CommonJS to get access to the `ObjectSchema` constructor:
|
28
|
+
|
29
|
+
```js
|
30
|
+
const { ObjectSchema } = require("@humanwhocodes/object-schema");
|
31
|
+
|
32
|
+
const schema = new ObjectSchema({
|
33
|
+
|
34
|
+
// define a definition for the "downloads" key
|
35
|
+
downloads: {
|
36
|
+
required: true,
|
37
|
+
merge(value1, value2) {
|
38
|
+
return value1 + value2;
|
39
|
+
},
|
40
|
+
validate(value) {
|
41
|
+
if (typeof value !== "number") {
|
42
|
+
throw new Error("Expected downloads to be a number.");
|
43
|
+
}
|
44
|
+
}
|
45
|
+
},
|
46
|
+
|
47
|
+
// define a strategy for the "versions" key
|
48
|
+
version: {
|
49
|
+
required: true,
|
50
|
+
merge(value1, value2) {
|
51
|
+
return value1.concat(value2);
|
52
|
+
},
|
53
|
+
validate(value) {
|
54
|
+
if (!Array.isArray(value)) {
|
55
|
+
throw new Error("Expected versions to be an array.");
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
});
|
60
|
+
|
61
|
+
const record1 = {
|
62
|
+
downloads: 25,
|
63
|
+
versions: [
|
64
|
+
"v1.0.0",
|
65
|
+
"v1.1.0",
|
66
|
+
"v1.2.0"
|
67
|
+
]
|
68
|
+
};
|
69
|
+
|
70
|
+
const record2 = {
|
71
|
+
downloads: 125,
|
72
|
+
versions: [
|
73
|
+
"v2.0.0",
|
74
|
+
"v2.1.0",
|
75
|
+
"v3.0.0"
|
76
|
+
]
|
77
|
+
};
|
78
|
+
|
79
|
+
// make sure the records are valid
|
80
|
+
schema.validate(record1);
|
81
|
+
schema.validate(record2);
|
82
|
+
|
83
|
+
// merge together (schema.merge() accepts any number of objects)
|
84
|
+
const result = schema.merge(record1, record2);
|
85
|
+
|
86
|
+
// result looks like this:
|
87
|
+
|
88
|
+
const result = {
|
89
|
+
downloads: 75,
|
90
|
+
versions: [
|
91
|
+
"v1.0.0",
|
92
|
+
"v1.1.0",
|
93
|
+
"v1.2.0",
|
94
|
+
"v2.0.0",
|
95
|
+
"v2.1.0",
|
96
|
+
"v3.0.0"
|
97
|
+
]
|
98
|
+
};
|
99
|
+
```
|
100
|
+
|
101
|
+
## Tips and Tricks
|
102
|
+
|
103
|
+
### Named merge strategies
|
104
|
+
|
105
|
+
Instead of specifying a `merge()` method, you can specify one of the following strings to use a default merge strategy:
|
106
|
+
|
107
|
+
* `"assign"` - use `Object.assign()` to merge the two values into one object.
|
108
|
+
* `"overwrite"` - the second value always replaces the first.
|
109
|
+
* `"replace"` - the second value replaces the first if the second is not `undefined`.
|
110
|
+
|
111
|
+
For example:
|
112
|
+
|
113
|
+
```js
|
114
|
+
const schema = new ObjectSchema({
|
115
|
+
name: {
|
116
|
+
merge: "replace",
|
117
|
+
validate() {}
|
118
|
+
}
|
119
|
+
});
|
120
|
+
```
|
121
|
+
|
122
|
+
### Named validation strategies
|
123
|
+
|
124
|
+
Instead of specifying a `validate()` method, you can specify one of the following strings to use a default validation strategy:
|
125
|
+
|
126
|
+
* `"array"` - value must be an array.
|
127
|
+
* `"boolean"` - value must be a boolean.
|
128
|
+
* `"number"` - value must be a number.
|
129
|
+
* `"object"` - value must be an object.
|
130
|
+
* `"object?"` - value must be an object or null.
|
131
|
+
* `"string"` - value must be a string.
|
132
|
+
* `"string!"` - value must be a non-empty string.
|
133
|
+
|
134
|
+
For example:
|
135
|
+
|
136
|
+
```js
|
137
|
+
const schema = new ObjectSchema({
|
138
|
+
name: {
|
139
|
+
merge: "replace",
|
140
|
+
validate: "string"
|
141
|
+
}
|
142
|
+
});
|
143
|
+
```
|
144
|
+
|
145
|
+
### Subschemas
|
146
|
+
|
147
|
+
If you are defining a key that is, itself, an object, you can simplify the process by using a subschema. Instead of defining `merge()` and `validate()`, assign a `schema` key that contains a schema definition, like this:
|
148
|
+
|
149
|
+
```js
|
150
|
+
const schema = new ObjectSchema({
|
151
|
+
name: {
|
152
|
+
schema: {
|
153
|
+
first: {
|
154
|
+
merge: "replace",
|
155
|
+
validate: "string"
|
156
|
+
},
|
157
|
+
last: {
|
158
|
+
merge: "replace",
|
159
|
+
validate: "string"
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
});
|
164
|
+
|
165
|
+
schema.validate({
|
166
|
+
name: {
|
167
|
+
first: "n",
|
168
|
+
last: "z"
|
169
|
+
}
|
170
|
+
});
|
171
|
+
```
|
172
|
+
|
173
|
+
### Remove Keys During Merge
|
174
|
+
|
175
|
+
If the merge strategy for a key returns `undefined`, then the key will not appear in the final object. For example:
|
176
|
+
|
177
|
+
```js
|
178
|
+
const schema = new ObjectSchema({
|
179
|
+
date: {
|
180
|
+
merge() {
|
181
|
+
return undefined;
|
182
|
+
},
|
183
|
+
validate(value) {
|
184
|
+
Date.parse(value); // throws an error when invalid
|
185
|
+
}
|
186
|
+
}
|
187
|
+
});
|
188
|
+
|
189
|
+
const object1 = { date: "5/5/2005" };
|
190
|
+
const object2 = { date: "6/6/2006" };
|
191
|
+
|
192
|
+
const result = schema.merge(object1, object2);
|
193
|
+
|
194
|
+
console.log("date" in result); // false
|
195
|
+
```
|
196
|
+
|
197
|
+
### Requiring Another Key Be Present
|
198
|
+
|
199
|
+
If you'd like the presence of one key to require the presence of another key, you can use the `requires` property to specify an array of other properties that any key requires. For example:
|
200
|
+
|
201
|
+
```js
|
202
|
+
const schema = new ObjectSchema();
|
203
|
+
|
204
|
+
const schema = new ObjectSchema({
|
205
|
+
date: {
|
206
|
+
merge() {
|
207
|
+
return undefined;
|
208
|
+
},
|
209
|
+
validate(value) {
|
210
|
+
Date.parse(value); // throws an error when invalid
|
211
|
+
}
|
212
|
+
},
|
213
|
+
time: {
|
214
|
+
requires: ["date"],
|
215
|
+
merge(first, second) {
|
216
|
+
return second;
|
217
|
+
},
|
218
|
+
validate(value) {
|
219
|
+
// ...
|
220
|
+
}
|
221
|
+
}
|
222
|
+
});
|
223
|
+
|
224
|
+
// throws error: Key "time" requires keys "date"
|
225
|
+
schema.validate({
|
226
|
+
time: "13:45"
|
227
|
+
});
|
228
|
+
```
|
229
|
+
|
230
|
+
In this example, even though `date` is an optional key, it is required to be present whenever `time` is present.
|
231
|
+
|
232
|
+
## License
|
233
|
+
|
234
|
+
BSD 3-Clause
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"name": "@humanwhocodes/object-schema",
|
3
|
+
"version": "1.2.1",
|
4
|
+
"description": "An object schema merger/validator",
|
5
|
+
"main": "src/index.js",
|
6
|
+
"directories": {
|
7
|
+
"test": "tests"
|
8
|
+
},
|
9
|
+
"scripts": {
|
10
|
+
"test": "mocha tests/"
|
11
|
+
},
|
12
|
+
"repository": {
|
13
|
+
"type": "git",
|
14
|
+
"url": "git+https://github.com/humanwhocodes/object-schema.git"
|
15
|
+
},
|
16
|
+
"keywords": [
|
17
|
+
"object",
|
18
|
+
"validation",
|
19
|
+
"schema",
|
20
|
+
"merge"
|
21
|
+
],
|
22
|
+
"author": "Nicholas C. Zakas",
|
23
|
+
"license": "BSD-3-Clause",
|
24
|
+
"bugs": {
|
25
|
+
"url": "https://github.com/humanwhocodes/object-schema/issues"
|
26
|
+
},
|
27
|
+
"homepage": "https://github.com/humanwhocodes/object-schema#readme",
|
28
|
+
"devDependencies": {
|
29
|
+
"chai": "^4.2.0",
|
30
|
+
"eslint": "^5.13.0",
|
31
|
+
"mocha": "^5.2.0"
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* @filedescription Object Schema Package
|
3
|
+
*/
|
4
|
+
|
5
|
+
exports.ObjectSchema = require("./object-schema").ObjectSchema;
|
6
|
+
exports.MergeStrategy = require("./merge-strategy").MergeStrategy;
|
7
|
+
exports.ValidationStrategy = require("./validation-strategy").ValidationStrategy;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
/**
|
2
|
+
* @filedescription Merge Strategy
|
3
|
+
*/
|
4
|
+
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//-----------------------------------------------------------------------------
|
8
|
+
// Class
|
9
|
+
//-----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Container class for several different merge strategies.
|
13
|
+
*/
|
14
|
+
class MergeStrategy {
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Merges two keys by overwriting the first with the second.
|
18
|
+
* @param {*} value1 The value from the first object key.
|
19
|
+
* @param {*} value2 The value from the second object key.
|
20
|
+
* @returns {*} The second value.
|
21
|
+
*/
|
22
|
+
static overwrite(value1, value2) {
|
23
|
+
return value2;
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Merges two keys by replacing the first with the second only if the
|
28
|
+
* second is defined.
|
29
|
+
* @param {*} value1 The value from the first object key.
|
30
|
+
* @param {*} value2 The value from the second object key.
|
31
|
+
* @returns {*} The second value if it is defined.
|
32
|
+
*/
|
33
|
+
static replace(value1, value2) {
|
34
|
+
if (typeof value2 !== "undefined") {
|
35
|
+
return value2;
|
36
|
+
}
|
37
|
+
|
38
|
+
return value1;
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Merges two properties by assigning properties from the second to the first.
|
43
|
+
* @param {*} value1 The value from the first object key.
|
44
|
+
* @param {*} value2 The value from the second object key.
|
45
|
+
* @returns {*} A new object containing properties from both value1 and
|
46
|
+
* value2.
|
47
|
+
*/
|
48
|
+
static assign(value1, value2) {
|
49
|
+
return Object.assign({}, value1, value2);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
exports.MergeStrategy = MergeStrategy;
|
@@ -0,0 +1,235 @@
|
|
1
|
+
/**
|
2
|
+
* @filedescription Object Schema
|
3
|
+
*/
|
4
|
+
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//-----------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//-----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const { MergeStrategy } = require("./merge-strategy");
|
12
|
+
const { ValidationStrategy } = require("./validation-strategy");
|
13
|
+
|
14
|
+
//-----------------------------------------------------------------------------
|
15
|
+
// Private
|
16
|
+
//-----------------------------------------------------------------------------
|
17
|
+
|
18
|
+
const strategies = Symbol("strategies");
|
19
|
+
const requiredKeys = Symbol("requiredKeys");
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Validates a schema strategy.
|
23
|
+
* @param {string} name The name of the key this strategy is for.
|
24
|
+
* @param {Object} strategy The strategy for the object key.
|
25
|
+
* @param {boolean} [strategy.required=true] Whether the key is required.
|
26
|
+
* @param {string[]} [strategy.requires] Other keys that are required when
|
27
|
+
* this key is present.
|
28
|
+
* @param {Function} strategy.merge A method to call when merging two objects
|
29
|
+
* with the same key.
|
30
|
+
* @param {Function} strategy.validate A method to call when validating an
|
31
|
+
* object with the key.
|
32
|
+
* @returns {void}
|
33
|
+
* @throws {Error} When the strategy is missing a name.
|
34
|
+
* @throws {Error} When the strategy is missing a merge() method.
|
35
|
+
* @throws {Error} When the strategy is missing a validate() method.
|
36
|
+
*/
|
37
|
+
function validateDefinition(name, strategy) {
|
38
|
+
|
39
|
+
let hasSchema = false;
|
40
|
+
if (strategy.schema) {
|
41
|
+
if (typeof strategy.schema === "object") {
|
42
|
+
hasSchema = true;
|
43
|
+
} else {
|
44
|
+
throw new TypeError("Schema must be an object.");
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
if (typeof strategy.merge === "string") {
|
49
|
+
if (!(strategy.merge in MergeStrategy)) {
|
50
|
+
throw new TypeError(`Definition for key "${name}" missing valid merge strategy.`);
|
51
|
+
}
|
52
|
+
} else if (!hasSchema && typeof strategy.merge !== "function") {
|
53
|
+
throw new TypeError(`Definition for key "${name}" must have a merge property.`);
|
54
|
+
}
|
55
|
+
|
56
|
+
if (typeof strategy.validate === "string") {
|
57
|
+
if (!(strategy.validate in ValidationStrategy)) {
|
58
|
+
throw new TypeError(`Definition for key "${name}" missing valid validation strategy.`);
|
59
|
+
}
|
60
|
+
} else if (!hasSchema && typeof strategy.validate !== "function") {
|
61
|
+
throw new TypeError(`Definition for key "${name}" must have a validate() method.`);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
//-----------------------------------------------------------------------------
|
67
|
+
// Class
|
68
|
+
//-----------------------------------------------------------------------------
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Represents an object validation/merging schema.
|
72
|
+
*/
|
73
|
+
class ObjectSchema {
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Creates a new instance.
|
77
|
+
*/
|
78
|
+
constructor(definitions) {
|
79
|
+
|
80
|
+
if (!definitions) {
|
81
|
+
throw new Error("Schema definitions missing.");
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Track all strategies in the schema by key.
|
86
|
+
* @type {Map}
|
87
|
+
* @property strategies
|
88
|
+
*/
|
89
|
+
this[strategies] = new Map();
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Separately track any keys that are required for faster validation.
|
93
|
+
* @type {Map}
|
94
|
+
* @property requiredKeys
|
95
|
+
*/
|
96
|
+
this[requiredKeys] = new Map();
|
97
|
+
|
98
|
+
// add in all strategies
|
99
|
+
for (const key of Object.keys(definitions)) {
|
100
|
+
validateDefinition(key, definitions[key]);
|
101
|
+
|
102
|
+
// normalize merge and validate methods if subschema is present
|
103
|
+
if (typeof definitions[key].schema === "object") {
|
104
|
+
const schema = new ObjectSchema(definitions[key].schema);
|
105
|
+
definitions[key] = {
|
106
|
+
...definitions[key],
|
107
|
+
merge(first = {}, second = {}) {
|
108
|
+
return schema.merge(first, second);
|
109
|
+
},
|
110
|
+
validate(value) {
|
111
|
+
ValidationStrategy.object(value);
|
112
|
+
schema.validate(value);
|
113
|
+
}
|
114
|
+
};
|
115
|
+
}
|
116
|
+
|
117
|
+
// normalize the merge method in case there's a string
|
118
|
+
if (typeof definitions[key].merge === "string") {
|
119
|
+
definitions[key] = {
|
120
|
+
...definitions[key],
|
121
|
+
merge: MergeStrategy[definitions[key].merge]
|
122
|
+
};
|
123
|
+
};
|
124
|
+
|
125
|
+
// normalize the validate method in case there's a string
|
126
|
+
if (typeof definitions[key].validate === "string") {
|
127
|
+
definitions[key] = {
|
128
|
+
...definitions[key],
|
129
|
+
validate: ValidationStrategy[definitions[key].validate]
|
130
|
+
};
|
131
|
+
};
|
132
|
+
|
133
|
+
this[strategies].set(key, definitions[key]);
|
134
|
+
|
135
|
+
if (definitions[key].required) {
|
136
|
+
this[requiredKeys].set(key, definitions[key]);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Determines if a strategy has been registered for the given object key.
|
143
|
+
* @param {string} key The object key to find a strategy for.
|
144
|
+
* @returns {boolean} True if the key has a strategy registered, false if not.
|
145
|
+
*/
|
146
|
+
hasKey(key) {
|
147
|
+
return this[strategies].has(key);
|
148
|
+
}
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Merges objects together to create a new object comprised of the keys
|
152
|
+
* of the all objects. Keys are merged based on the each key's merge
|
153
|
+
* strategy.
|
154
|
+
* @param {...Object} objects The objects to merge.
|
155
|
+
* @returns {Object} A new object with a mix of all objects' keys.
|
156
|
+
* @throws {Error} If any object is invalid.
|
157
|
+
*/
|
158
|
+
merge(...objects) {
|
159
|
+
|
160
|
+
// double check arguments
|
161
|
+
if (objects.length < 2) {
|
162
|
+
throw new Error("merge() requires at least two arguments.");
|
163
|
+
}
|
164
|
+
|
165
|
+
if (objects.some(object => (object == null || typeof object !== "object"))) {
|
166
|
+
throw new Error("All arguments must be objects.");
|
167
|
+
}
|
168
|
+
|
169
|
+
return objects.reduce((result, object) => {
|
170
|
+
|
171
|
+
this.validate(object);
|
172
|
+
|
173
|
+
for (const [key, strategy] of this[strategies]) {
|
174
|
+
try {
|
175
|
+
if (key in result || key in object) {
|
176
|
+
const value = strategy.merge.call(this, result[key], object[key]);
|
177
|
+
if (value !== undefined) {
|
178
|
+
result[key] = value;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
} catch (ex) {
|
182
|
+
ex.message = `Key "${key}": ` + ex.message;
|
183
|
+
throw ex;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
return result;
|
187
|
+
}, {});
|
188
|
+
}
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Validates an object's keys based on the validate strategy for each key.
|
192
|
+
* @param {Object} object The object to validate.
|
193
|
+
* @returns {void}
|
194
|
+
* @throws {Error} When the object is invalid.
|
195
|
+
*/
|
196
|
+
validate(object) {
|
197
|
+
|
198
|
+
// check existing keys first
|
199
|
+
for (const key of Object.keys(object)) {
|
200
|
+
|
201
|
+
// check to see if the key is defined
|
202
|
+
if (!this.hasKey(key)) {
|
203
|
+
throw new Error(`Unexpected key "${key}" found.`);
|
204
|
+
}
|
205
|
+
|
206
|
+
// validate existing keys
|
207
|
+
const strategy = this[strategies].get(key);
|
208
|
+
|
209
|
+
// first check to see if any other keys are required
|
210
|
+
if (Array.isArray(strategy.requires)) {
|
211
|
+
if (!strategy.requires.every(otherKey => otherKey in object)) {
|
212
|
+
throw new Error(`Key "${key}" requires keys "${strategy.requires.join("\", \"")}".`);
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
// now apply remaining validation strategy
|
217
|
+
try {
|
218
|
+
strategy.validate.call(strategy, object[key]);
|
219
|
+
} catch (ex) {
|
220
|
+
ex.message = `Key "${key}": ` + ex.message;
|
221
|
+
throw ex;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
// ensure required keys aren't missing
|
226
|
+
for (const [key] of this[requiredKeys]) {
|
227
|
+
if (!(key in object)) {
|
228
|
+
throw new Error(`Missing required key "${key}".`);
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
exports.ObjectSchema = ObjectSchema;
|
@@ -0,0 +1,102 @@
|
|
1
|
+
/**
|
2
|
+
* @filedescription Validation Strategy
|
3
|
+
*/
|
4
|
+
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//-----------------------------------------------------------------------------
|
8
|
+
// Class
|
9
|
+
//-----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Container class for several different validation strategies.
|
13
|
+
*/
|
14
|
+
class ValidationStrategy {
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Validates that a value is an array.
|
18
|
+
* @param {*} value The value to validate.
|
19
|
+
* @returns {void}
|
20
|
+
* @throws {TypeError} If the value is invalid.
|
21
|
+
*/
|
22
|
+
static array(value) {
|
23
|
+
if (!Array.isArray(value)) {
|
24
|
+
throw new TypeError("Expected an array.");
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Validates that a value is a boolean.
|
30
|
+
* @param {*} value The value to validate.
|
31
|
+
* @returns {void}
|
32
|
+
* @throws {TypeError} If the value is invalid.
|
33
|
+
*/
|
34
|
+
static boolean(value) {
|
35
|
+
if (typeof value !== "boolean") {
|
36
|
+
throw new TypeError("Expected a Boolean.");
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Validates that a value is a number.
|
42
|
+
* @param {*} value The value to validate.
|
43
|
+
* @returns {void}
|
44
|
+
* @throws {TypeError} If the value is invalid.
|
45
|
+
*/
|
46
|
+
static number(value) {
|
47
|
+
if (typeof value !== "number") {
|
48
|
+
throw new TypeError("Expected a number.");
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Validates that a value is a object.
|
54
|
+
* @param {*} value The value to validate.
|
55
|
+
* @returns {void}
|
56
|
+
* @throws {TypeError} If the value is invalid.
|
57
|
+
*/
|
58
|
+
static object(value) {
|
59
|
+
if (!value || typeof value !== "object") {
|
60
|
+
throw new TypeError("Expected an object.");
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Validates that a value is a object or null.
|
66
|
+
* @param {*} value The value to validate.
|
67
|
+
* @returns {void}
|
68
|
+
* @throws {TypeError} If the value is invalid.
|
69
|
+
*/
|
70
|
+
static "object?"(value) {
|
71
|
+
if (typeof value !== "object") {
|
72
|
+
throw new TypeError("Expected an object or null.");
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Validates that a value is a string.
|
78
|
+
* @param {*} value The value to validate.
|
79
|
+
* @returns {void}
|
80
|
+
* @throws {TypeError} If the value is invalid.
|
81
|
+
*/
|
82
|
+
static string(value) {
|
83
|
+
if (typeof value !== "string") {
|
84
|
+
throw new TypeError("Expected a string.");
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Validates that a value is a non-empty string.
|
90
|
+
* @param {*} value The value to validate.
|
91
|
+
* @returns {void}
|
92
|
+
* @throws {TypeError} If the value is invalid.
|
93
|
+
*/
|
94
|
+
static "string!"(value) {
|
95
|
+
if (typeof value !== "string" || value.length === 0) {
|
96
|
+
throw new TypeError("Expected a non-empty string.");
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
}
|
101
|
+
|
102
|
+
exports.ValidationStrategy = ValidationStrategy;
|