deep-guards 1.0.0 → 1.0.1
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/README.md +39 -2
- package/dist/structures.js +4 -4
- package/dist/structures.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +42 -41
- package/src/types.ts +9 -5
package/README.md
CHANGED
|
@@ -32,12 +32,12 @@ const vehicleGuard = isUnionOf(carGuard, bikeGuard);
|
|
|
32
32
|
const value: unknown = { ... };
|
|
33
33
|
|
|
34
34
|
if (vehicleGuard(value)) {
|
|
35
|
-
value.wheels;
|
|
35
|
+
console.log(value.wheels);
|
|
36
36
|
|
|
37
37
|
if (value.type === "car") {
|
|
38
38
|
// value is a Car
|
|
39
39
|
} else {
|
|
40
|
-
// value is a
|
|
40
|
+
// value is a Bike
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
```
|
|
@@ -59,6 +59,8 @@ if (vehicleGuard(value)) {
|
|
|
59
59
|
3. [isArrayOf](#isarrayof)
|
|
60
60
|
4. [isRecordOf](#isrecordof)
|
|
61
61
|
5. [isObjectOf](#isobjectof)
|
|
62
|
+
4. [guardOrThrow](#guardorthrow)
|
|
63
|
+
5. [TypeFromGuard](#typefromguard)
|
|
62
64
|
|
|
63
65
|
## Terminology
|
|
64
66
|
|
|
@@ -165,3 +167,38 @@ As seen in the example at the start of this readme, you can do all sorts of comp
|
|
|
165
167
|
|
|
166
168
|
NOTE: This throws an error if you give it an empty object.\
|
|
167
169
|
It will also accept an object which contains keys which are not specified.
|
|
170
|
+
|
|
171
|
+
## guardOrThrow
|
|
172
|
+
|
|
173
|
+
This package also includes a `guardOrThrow` method which when given an incoming value, a guard, and an optional hint message, will return a narrowed version of the value, or throw a `GuardError` containing that hint message.
|
|
174
|
+
|
|
175
|
+
You can then do things like:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
const cars = guardOrThrow(
|
|
179
|
+
JSON.parse(readFileSync("cars.json").toString()),
|
|
180
|
+
isArrayOf(isCar),
|
|
181
|
+
"Invalid car format"
|
|
182
|
+
);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## TypeFromGuard
|
|
186
|
+
|
|
187
|
+
This is a helper type, which will extract the type from a guard function to then let you use the type for other purposes.
|
|
188
|
+
|
|
189
|
+
An example use case for this is:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
const carGuard = isObjectOf({
|
|
193
|
+
type: isExact("car"),
|
|
194
|
+
wheels: isExact(4),
|
|
195
|
+
owner: isString,
|
|
196
|
+
passengers: isArrayOf(
|
|
197
|
+
isObjectOf({
|
|
198
|
+
name: isString,
|
|
199
|
+
})
|
|
200
|
+
),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
type Car = TypeFromGuard<typeof carGuard>;
|
|
204
|
+
```
|
package/dist/structures.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
function objectKeys(obj) {
|
|
2
2
|
return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
|
|
3
3
|
}
|
|
4
|
-
export const isAnyArray = value => Array.isArray(value);
|
|
4
|
+
export const isAnyArray = (value) => Array.isArray(value);
|
|
5
5
|
export const isAnyRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
6
6
|
export function isArrayOf(guard) {
|
|
7
7
|
if (typeof guard !== "function") {
|
|
@@ -19,7 +19,7 @@ export function isRecordOf(keyGuard, valueGuard) {
|
|
|
19
19
|
return (value) => value != null &&
|
|
20
20
|
typeof value === "object" &&
|
|
21
21
|
!Array.isArray(value) &&
|
|
22
|
-
objectKeys(value).every(key => keyGuard(key) && (valueGuard?.(value[key]) ?? true));
|
|
22
|
+
objectKeys(value).every((key) => keyGuard(key) && (valueGuard?.(value[key]) ?? true));
|
|
23
23
|
}
|
|
24
24
|
export function isObjectOf(schema) {
|
|
25
25
|
const schemaKeys = objectKeys(schema);
|
|
@@ -30,12 +30,12 @@ export function isObjectOf(schema) {
|
|
|
30
30
|
else if (schemaUnknown == null ||
|
|
31
31
|
typeof schemaUnknown !== "object" ||
|
|
32
32
|
Array.isArray(schemaUnknown) ||
|
|
33
|
-
schemaKeys.some(key => typeof schemaUnknown[key] !== "function")) {
|
|
33
|
+
schemaKeys.some((key) => typeof schemaUnknown[key] !== "function")) {
|
|
34
34
|
throw new TypeError(`isObjectOf expects a guard schema. Got instead: ${schemaUnknown}`);
|
|
35
35
|
}
|
|
36
36
|
return ((value) => value != null &&
|
|
37
37
|
typeof value === "object" &&
|
|
38
38
|
!Array.isArray(value) &&
|
|
39
|
-
schemaKeys.every(key => key in value && schema[key](value[key])));
|
|
39
|
+
schemaKeys.every((key) => key in value && schema[key](value[key])));
|
|
40
40
|
}
|
|
41
41
|
//# sourceMappingURL=structures.js.map
|
package/dist/structures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structures.js","sourceRoot":"src/","sources":["structures.ts"],"names":[],"mappings":"AAIA,SAAS,UAAU,CAAsB,GAAuB;IAC9D,OAAQ,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAS,CAAC,MAAM,CACpD,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAQ,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAqB,KAAK,
|
|
1
|
+
{"version":3,"file":"structures.js","sourceRoot":"src/","sources":["structures.ts"],"names":[],"mappings":"AAIA,SAAS,UAAU,CAAsB,GAAuB;IAC9D,OAAQ,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAS,CAAC,MAAM,CACpD,MAAM,CAAC,qBAAqB,CAAC,GAAG,CAAQ,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5E,MAAM,CAAC,MAAM,WAAW,GAAsC,CAC5D,KAAK,EACgC,EAAE,CACvC,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEtE,MAAM,UAAU,SAAS,CAAI,KAAe;IAC1C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,qDAAqD,KAAK,EAAE,CAC7D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAgB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AASD,MAAM,UAAU,UAAU,CACxB,QAAkB,EAClB,UAAqB;IAErB,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CACjB,+DAA+D,QAAQ,EAAE,CAC1E,CAAC;IACJ,CAAC;SAAM,IAAI,UAAU,IAAI,IAAI,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CACjB,2EAA2E,UAAU,EAAE,CACxF,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,EAAyB,EAAE,CACtC,KAAK,IAAI,IAAI;QACb,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CACrB,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAC7D,CAAC;AACN,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,MAAwB;IAExB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,aAAa,GAAG,MAAiB,CAAC;IACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;SAAM,IACL,aAAa,IAAI,IAAI;QACrB,OAAO,aAAa,KAAK,QAAQ;QACjC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAQ,aAAmB,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,EACzE,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,mDAAmD,aAAa,EAAE,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,CAAC,KAAK,EAAc,EAAE,CAC5B,KAAK,IAAI,IAAI;QACb,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,UAAU,CAAC,KAAK,CACd,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAE,KAAW,CAAC,GAAG,CAAC,CAAC,CACxD,CAA2C,CAAC;AACjD,CAAC"}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,41 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"author": "eniallator",
|
|
3
|
-
"description": "Deep guarding package",
|
|
4
|
-
"license": "Apache-2.0",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"name": "deep-guards",
|
|
7
|
-
"packageManager": "yarn@3.8.2",
|
|
8
|
-
"type": "module",
|
|
9
|
-
"types": "dist/index.d.ts",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"@babel/
|
|
21
|
-
"@babel/preset-
|
|
22
|
-
"@
|
|
23
|
-
"@eslint/
|
|
24
|
-
"@
|
|
25
|
-
"@
|
|
26
|
-
"@types/
|
|
27
|
-
"@types/
|
|
28
|
-
"@types/
|
|
29
|
-
"@types/
|
|
30
|
-
"@
|
|
31
|
-
"@typescript-eslint/
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"eslint
|
|
35
|
-
"eslint-plugin-
|
|
36
|
-
"eslint-plugin-
|
|
37
|
-
"jest": "^
|
|
38
|
-
"
|
|
39
|
-
"typescript
|
|
40
|
-
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"author": "eniallator",
|
|
3
|
+
"description": "Deep guarding package",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"name": "deep-guards",
|
|
7
|
+
"packageManager": "yarn@3.8.2",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"homepage": "https://github.com/eniallator/Deep-Guards",
|
|
11
|
+
"version": "1.0.1",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"lint": "eslint ./src",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"findissues": "yarn typecheck && yarn lint"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@babel/core": "^7.26.0",
|
|
21
|
+
"@babel/preset-env": "^7.26.0",
|
|
22
|
+
"@babel/preset-typescript": "^7.26.0",
|
|
23
|
+
"@eslint/compat": "^1.2.3",
|
|
24
|
+
"@eslint/js": "^9.15.0",
|
|
25
|
+
"@jest/globals": "^29.7.0",
|
|
26
|
+
"@types/babel__core": "^7.20.5",
|
|
27
|
+
"@types/babel__preset-env": "^7.9.7",
|
|
28
|
+
"@types/eslint": "^9.6.1",
|
|
29
|
+
"@types/eslint__js": "^8.42.3",
|
|
30
|
+
"@types/jest": "^29.5.14",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.15.0",
|
|
33
|
+
"babel-jest": "^29.7.0",
|
|
34
|
+
"eslint": "^9.15.0",
|
|
35
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
36
|
+
"eslint-plugin-import": "^2.31.0",
|
|
37
|
+
"eslint-plugin-jest": "^28.9.0",
|
|
38
|
+
"jest": "^29.7.0",
|
|
39
|
+
"typescript": "^5.6.3",
|
|
40
|
+
"typescript-eslint": "^8.15.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export type Guard<T> = (value: unknown) => value is T;
|
|
2
|
-
|
|
3
|
-
export type GuardSchemaOf<O extends object> = {
|
|
4
|
-
[K in keyof O]: Guard<O[K]>;
|
|
5
|
-
};
|
|
1
|
+
export type Guard<T> = (value: unknown) => value is T;
|
|
2
|
+
|
|
3
|
+
export type GuardSchemaOf<O extends object> = {
|
|
4
|
+
[K in keyof O]: Guard<O[K]>;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type TypeFromGuard<G extends Guard<unknown>> = G extends Guard<infer T>
|
|
8
|
+
? T
|
|
9
|
+
: never;
|