@bool-ts/guard-sdk 1.1.0-beta.3 → 1.1.0-beta.5
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/dist/decorators/index.d.ts +2 -0
- package/dist/entities/guard.d.ts +5 -0
- package/dist/entities/index.d.ts +1 -1
- package/dist/index.js +14 -14
- package/dist/index.js.map +10 -6
- package/dist/ultils/types/partialTuple.d.ts +4 -1
- package/dist/ultils/types/partialTurpleNonEmpty.d.ts +1 -4
- package/package.json +4 -2
- package/src/decorators/actionGuard.decorator.ts +2 -1
- package/src/decorators/index.ts +2 -0
- package/src/entities/guard.ts +35 -0
- package/src/entities/index.ts +1 -1
- package/src/entities/middleware.ts +23 -8
- package/src/interfaces/account.interface.ts +4 -1
- package/src/interfaces/base.ts +5 -1
- package/src/interfaces/client.interface.ts +1 -3
- package/src/interfaces/index.ts +6 -2
- package/src/ultils/functions/deepFreeze.ts +4 -4
- package/src/ultils/types/inArray.ts +4 -4
- package/src/ultils/types/partialTuple.ts +4 -1
- package/src/ultils/types/partialTupleUnordered.ts +6 -5
- package/src/ultils/types/partialTurpleNonEmpty.ts +4 -6
- package/src/ultils/types/permutationTuple.ts +2 -2
- package/src/entities/interceptor.ts +0 -47
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export type TPartialTuple<T extends readonly any[]> = T extends readonly [
|
|
1
|
+
export type TPartialTuple<T extends readonly any[]> = T extends readonly [
|
|
2
|
+
infer Head,
|
|
3
|
+
...infer Tail
|
|
4
|
+
] ? TPartialTuple<Tail> | [Head, ...TPartialTuple<Tail>] : [];
|
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
import type { TPartialTuple } from "./partialTuple";
|
|
2
|
-
export type TPartialTupleNonEmpty<T extends readonly any[]> = T extends readonly [
|
|
3
|
-
infer Head,
|
|
4
|
-
...infer Tail
|
|
5
|
-
] ? [Head, ...TPartialTuple<Tail>] | TPartialTupleNonEmpty<Tail> : never;
|
|
2
|
+
export type TPartialTupleNonEmpty<T extends readonly any[]> = T extends readonly [infer Head, ...infer Tail] ? [Head, ...TPartialTuple<Tail>] | TPartialTupleNonEmpty<Tail> : never;
|
package/package.json
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"zod": "^4.2.1"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@bool-ts/core": "^2.1.
|
|
12
|
+
"@bool-ts/core": "^2.1.3",
|
|
13
13
|
"@types/bun": "latest",
|
|
14
|
+
"prettier": "^3.7.4",
|
|
14
15
|
"typescript": "^5.9.3"
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
@@ -41,8 +42,9 @@
|
|
|
41
42
|
},
|
|
42
43
|
"scripts": {
|
|
43
44
|
"build": "tsc --emitDeclarationOnly && bun run app.build.ts",
|
|
45
|
+
"format": "prettier \"**/*.ts\" --write",
|
|
44
46
|
"test": "bun --hot run __test/index.ts"
|
|
45
47
|
},
|
|
46
48
|
"types": "./dist/index.d.ts",
|
|
47
|
-
"version": "1.1.0-beta.
|
|
49
|
+
"version": "1.1.0-beta.5"
|
|
48
50
|
}
|
|
@@ -5,7 +5,8 @@ import { Keys } from "../constants";
|
|
|
5
5
|
|
|
6
6
|
export const ActionGuard =
|
|
7
7
|
<
|
|
8
|
-
const T extends readonly TResourceDefinition[] =
|
|
8
|
+
const T extends readonly TResourceDefinition[] =
|
|
9
|
+
readonly TResourceDefinition[],
|
|
9
10
|
K extends TConstructor<Object> | Object = Object
|
|
10
11
|
>(
|
|
11
12
|
options?: TActionGuardOptions<T>
|
package/src/decorators/index.ts
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IGuard, THttpRouteModel } from "@bool-ts/core";
|
|
2
|
+
import type { TAuthState } from "../interfaces/client.interface";
|
|
3
|
+
|
|
4
|
+
import { Guard as BoolTsGuard, RouteModel } from "@bool-ts/core";
|
|
5
|
+
import { Keys } from "../constants";
|
|
6
|
+
import { AuthState } from "../decorators/authState.decorator";
|
|
7
|
+
|
|
8
|
+
@BoolTsGuard()
|
|
9
|
+
export class Guard implements IGuard {
|
|
10
|
+
enforce(
|
|
11
|
+
@RouteModel()
|
|
12
|
+
routeModel: THttpRouteModel,
|
|
13
|
+
@AuthState()
|
|
14
|
+
authState: TAuthState
|
|
15
|
+
) {
|
|
16
|
+
const actionMetadataKeys = Reflect.getOwnMetadataKeys(
|
|
17
|
+
routeModel.class,
|
|
18
|
+
routeModel.funcName
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (actionMetadataKeys.includes(Keys.guardMetadata)) {
|
|
22
|
+
return !authState ? false : true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const controllerMetadataKeys = Reflect.getOwnMetadataKeys(
|
|
26
|
+
routeModel.class
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (controllerMetadataKeys.includes(Keys.guardMetadata)) {
|
|
30
|
+
return !authState ? false : true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/entities/index.ts
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import type { IContext, IMiddleware } from "@bool-ts/core";
|
|
2
2
|
import type { IClient, TAuthState } from "../interfaces/client.interface";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
Middleware as BoolMiddleware,
|
|
6
|
+
Context,
|
|
7
|
+
Inject,
|
|
8
|
+
RequestHeaders
|
|
9
|
+
} from "@bool-ts/core";
|
|
10
|
+
import { jwt, NEVER, object, string } from "zod/v4";
|
|
6
11
|
import { Keys } from "../constants";
|
|
7
12
|
|
|
8
13
|
const headersSchema = object({
|
|
9
14
|
authorization: string()
|
|
10
15
|
.startsWith("Bearer ")
|
|
11
|
-
.
|
|
12
|
-
.transform((value) => {
|
|
16
|
+
.transform((value, ctx) => {
|
|
13
17
|
const [schema, token] = value.split(" ");
|
|
14
18
|
|
|
19
|
+
const jwtValidation = jwt().safeParse(token);
|
|
20
|
+
|
|
21
|
+
if (!jwtValidation.success) {
|
|
22
|
+
ctx.addIssue("Token must be match jsonwebtoken format.");
|
|
23
|
+
|
|
24
|
+
return NEVER;
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
return Object.freeze({
|
|
16
28
|
schema,
|
|
17
29
|
token
|
|
@@ -44,7 +56,9 @@ export class Middleware implements IMiddleware {
|
|
|
44
56
|
@RequestHeaders()
|
|
45
57
|
requestHeaders: Headers
|
|
46
58
|
) {
|
|
47
|
-
const headersValidation = await headersSchema.safeParseAsync(
|
|
59
|
+
const headersValidation = await headersSchema.safeParseAsync(
|
|
60
|
+
requestHeaders.toJSON()
|
|
61
|
+
);
|
|
48
62
|
|
|
49
63
|
if (!headersValidation.success) {
|
|
50
64
|
return context.set(Keys.authState, undefined);
|
|
@@ -54,9 +68,10 @@ export class Middleware implements IMiddleware {
|
|
|
54
68
|
} = headersValidation.data;
|
|
55
69
|
|
|
56
70
|
try {
|
|
57
|
-
const { account, credential } =
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
const { account, credential } =
|
|
72
|
+
await this.clientInstance.verifyToken({
|
|
73
|
+
token: token
|
|
74
|
+
});
|
|
60
75
|
|
|
61
76
|
const authState: TAuthState = Object.freeze({
|
|
62
77
|
account: account,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export type TDefaultAccountMetadata = Record<
|
|
1
|
+
export type TDefaultAccountMetadata = Record<
|
|
2
|
+
string,
|
|
3
|
+
string | number | Date | null | undefined
|
|
4
|
+
>;
|
|
2
5
|
|
|
3
6
|
export interface IAccount<T = TDefaultAccountMetadata> {
|
|
4
7
|
uuid: string;
|
package/src/interfaces/base.ts
CHANGED
|
@@ -50,9 +50,7 @@ export interface IClient<
|
|
|
50
50
|
account: IAccount<TAccountMetadata>;
|
|
51
51
|
credential: IAccountCredential;
|
|
52
52
|
}>;
|
|
53
|
-
verifyToken(args: {
|
|
54
|
-
token: string;
|
|
55
|
-
}): Promise<{
|
|
53
|
+
verifyToken(args: { token: string }): Promise<{
|
|
56
54
|
account: IAccount<TAccountMetadata>;
|
|
57
55
|
credential: IAccountCredential;
|
|
58
56
|
}>;
|
package/src/interfaces/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export type { IAccount } from "./account.interface";
|
|
2
2
|
export type { IAccountCredential } from "./accountCredential.interface";
|
|
3
3
|
export type { TApiResponse } from "./base";
|
|
4
|
-
export type {
|
|
5
|
-
|
|
4
|
+
export type {
|
|
5
|
+
IClient,
|
|
6
|
+
TAuthState,
|
|
7
|
+
TClientCredential as TClientConfigs,
|
|
8
|
+
TClientOptions
|
|
9
|
+
} from "./client.interface";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
type DeepReadonly<T> = T extends (...args: any[]) => any
|
|
2
2
|
? T
|
|
3
3
|
: T extends readonly any[]
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
|
5
|
+
: T extends object
|
|
6
|
+
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
|
7
|
+
: T;
|
|
8
8
|
|
|
9
9
|
export function deepFreeze<const T>(obj: T): DeepReadonly<T> {
|
|
10
10
|
if (typeof obj !== "object" || obj === null) return obj as any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type TInArray<T, X> = T extends readonly [X, ...infer _Rest]
|
|
2
2
|
? true
|
|
3
3
|
: T extends readonly [X]
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
? true
|
|
5
|
+
: T extends readonly [infer _, ...infer Rest]
|
|
6
|
+
? TInArray<Rest, X>
|
|
7
|
+
: false;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
export type TPartialTuple<T extends readonly any[]> = T extends readonly [
|
|
1
|
+
export type TPartialTuple<T extends readonly any[]> = T extends readonly [
|
|
2
|
+
infer Head,
|
|
3
|
+
...infer Tail
|
|
4
|
+
]
|
|
2
5
|
? TPartialTuple<Tail> | [Head, ...TPartialTuple<Tail>]
|
|
3
6
|
: [];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { TPartialTuple } from "./partialTuple";
|
|
2
2
|
import type { TPermutationTuple } from "./permutationTuple";
|
|
3
3
|
|
|
4
|
-
export type TPartialTupleUnordered<T extends readonly any[]> =
|
|
5
|
-
|
|
6
|
-
?
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export type TPartialTupleUnordered<T extends readonly any[]> =
|
|
5
|
+
TPartialTuple<T> extends infer S
|
|
6
|
+
? S extends readonly any[]
|
|
7
|
+
? TPermutationTuple<S[number]>
|
|
8
|
+
: never
|
|
9
|
+
: never;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { TPartialTuple } from "./partialTuple";
|
|
2
2
|
|
|
3
|
-
export type TPartialTupleNonEmpty<T extends readonly any[]> =
|
|
4
|
-
infer Head,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
? [Head, ...TPartialTuple<Tail>] | TPartialTupleNonEmpty<Tail>
|
|
8
|
-
: never;
|
|
3
|
+
export type TPartialTupleNonEmpty<T extends readonly any[]> =
|
|
4
|
+
T extends readonly [infer Head, ...infer Tail]
|
|
5
|
+
? [Head, ...TPartialTuple<Tail>] | TPartialTupleNonEmpty<Tail>
|
|
6
|
+
: never;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { IInterceptor, THttpRouteModel } from "@bool-ts/core";
|
|
2
|
-
import type { TAuthState } from "../interfaces/client.interface";
|
|
3
|
-
|
|
4
|
-
import { Interceptor as BoolInterceptor, HttpClientError, RouteModel } from "@bool-ts/core";
|
|
5
|
-
import { Keys } from "../constants";
|
|
6
|
-
import { AuthState } from "../decorators/authState.decorator";
|
|
7
|
-
|
|
8
|
-
@BoolInterceptor()
|
|
9
|
-
export class Interceptor implements IInterceptor {
|
|
10
|
-
open(
|
|
11
|
-
@RouteModel()
|
|
12
|
-
routeModel: THttpRouteModel,
|
|
13
|
-
@AuthState()
|
|
14
|
-
authState: TAuthState
|
|
15
|
-
) {
|
|
16
|
-
const actionMetadataKeys = Reflect.getOwnMetadataKeys(
|
|
17
|
-
routeModel.class.prototype,
|
|
18
|
-
routeModel.funcName
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
if (actionMetadataKeys.includes(Keys.authState)) {
|
|
22
|
-
if (!authState) {
|
|
23
|
-
throw new HttpClientError({
|
|
24
|
-
httpCode: 401,
|
|
25
|
-
message: "Unauthorized",
|
|
26
|
-
data: undefined
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const controllerMetadataKeys = Reflect.getOwnMetadataKeys(routeModel.class);
|
|
34
|
-
|
|
35
|
-
if (controllerMetadataKeys.includes(Keys.authState)) {
|
|
36
|
-
if (!authState) {
|
|
37
|
-
throw new HttpClientError({
|
|
38
|
-
httpCode: 401,
|
|
39
|
-
message: "Unauthorized",
|
|
40
|
-
data: undefined
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|