@bool-ts/guard-sdk 1.0.2-beta.3 → 1.1.0-beta.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/dist/decorators/actionGuard.decorator.d.ts +3 -1
- package/dist/decorators/controllerGuard.decorator.d.ts +2 -1
- package/dist/decorators/index.d.ts +0 -2
- package/dist/definers/index.d.ts +1 -0
- package/dist/definers/policies.d.ts +5 -0
- package/dist/definers/resources.d.ts +8 -0
- package/dist/entities/loader.d.ts +7 -2
- package/dist/index.js +12 -12
- package/dist/index.js.map +10 -12
- package/dist/instances/client.d.ts +7 -4
- package/dist/interfaces/client.interface.d.ts +9 -4
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/types/actionGuard.d.ts +8 -0
- package/dist/types/controllerGuard.d.ts +6 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/policies.d.ts +11 -0
- package/dist/types/resources.d.ts +6 -0
- package/dist/ultils/functions/deepFreeze.d.ts +7 -0
- package/dist/ultils/functions/index.d.ts +1 -0
- package/dist/ultils/types/constructor.d.ts +1 -0
- package/dist/ultils/types/enforceUnique.d.ts +8 -0
- package/dist/ultils/types/error.d.ts +3 -0
- package/dist/ultils/types/extractTuple.d.ts +1 -0
- package/dist/ultils/types/inArray.d.ts +1 -0
- package/dist/ultils/types/index.d.ts +14 -0
- package/dist/ultils/types/mergeTuple.d.ts +3 -0
- package/dist/ultils/types/noneEmptyArray.d.ts +1 -0
- package/dist/ultils/types/partialTuple.d.ts +1 -0
- package/dist/ultils/types/partialTupleUnordered.d.ts +3 -0
- package/dist/ultils/types/partialTupleUnorderedNonEmpty.d.ts +3 -0
- package/dist/ultils/types/partialTurpleNonEmpty.d.ts +5 -0
- package/dist/ultils/types/permutationTuple.d.ts +1 -0
- package/dist/ultils/types/shuffleTuple.d.ts +5 -0
- package/dist/ultils/types/strictPartial.d.ts +5 -0
- package/package.json +4 -4
- package/src/decorators/actionGuard.decorator.ts +18 -3
- package/src/decorators/controllerGuard.decorator.ts +7 -3
- package/src/decorators/index.ts +0 -2
- package/src/definers/index.ts +1 -0
- package/src/definers/policies.ts +24 -0
- package/src/definers/resources.ts +47 -0
- package/src/entities/loader.ts +17 -3
- package/src/entities/middleware.ts +1 -2
- package/src/instances/client.ts +135 -57
- package/src/interfaces/client.interface.ts +18 -6
- package/src/interfaces/index.ts +2 -1
- package/src/types/actionGuard.ts +11 -0
- package/src/types/controllerGuard.ts +8 -0
- package/src/types/index.ts +3 -0
- package/src/types/policies.ts +36 -0
- package/src/types/resources.ts +10 -0
- package/src/ultils/functions/deepFreeze.ts +19 -0
- package/src/ultils/functions/index.ts +1 -0
- package/src/ultils/types/constructor.ts +1 -0
- package/src/ultils/types/enforceUnique.ts +30 -0
- package/src/ultils/types/error.ts +1 -0
- package/src/ultils/types/extractTuple.ts +1 -0
- package/src/ultils/types/inArray.ts +7 -0
- package/src/ultils/types/index.ts +14 -0
- package/src/ultils/types/mergeTuple.ts +3 -0
- package/src/ultils/types/noneEmptyArray.ts +1 -0
- package/src/ultils/types/partialTuple.ts +3 -0
- package/src/ultils/types/partialTupleUnordered.ts +8 -0
- package/src/ultils/types/partialTupleUnorderedNonEmpty.ts +9 -0
- package/src/ultils/types/partialTurpleNonEmpty.ts +8 -0
- package/src/ultils/types/permutationTuple.ts +5 -0
- package/src/ultils/types/shuffleTuple.ts +7 -0
- package/src/ultils/types/strictPartial.ts +5 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import type { IClient,
|
|
1
|
+
import type { IClient, TClientCredential, TClientDefinition, TClientOptions } from "../interfaces/client.interface";
|
|
2
2
|
export declare class Client implements IClient {
|
|
3
3
|
#private;
|
|
4
|
-
private readonly
|
|
5
|
-
private readonly options?;
|
|
4
|
+
private readonly params;
|
|
6
5
|
private token;
|
|
7
6
|
/**
|
|
8
7
|
* Initialize BoolGuard client instance
|
|
9
8
|
* @param configs
|
|
10
9
|
* @param options
|
|
11
10
|
*/
|
|
12
|
-
constructor(
|
|
11
|
+
constructor(params: Readonly<{
|
|
12
|
+
credential: TClientCredential;
|
|
13
|
+
definition?: TClientDefinition;
|
|
14
|
+
options?: TClientOptions;
|
|
15
|
+
}>);
|
|
13
16
|
/**
|
|
14
17
|
* Sign JWT token with Ed25519 algorithm
|
|
15
18
|
* @returns
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import type { defineResources } from "../definers";
|
|
1
2
|
import type { IAccount, TDefaultAccountMetadata } from "./account.interface";
|
|
2
3
|
import type { IAccountCredential } from "./accountCredential.interface";
|
|
3
|
-
export type
|
|
4
|
+
export type TClientCredential = Readonly<{
|
|
4
5
|
tenantId: string;
|
|
5
6
|
appId: string;
|
|
6
7
|
modeId: string;
|
|
7
8
|
secretKey: string;
|
|
8
|
-
}
|
|
9
|
-
export type
|
|
9
|
+
}>;
|
|
10
|
+
export type TClientDefinition = Readonly<{
|
|
11
|
+
resources: ReturnType<typeof defineResources>["resources"];
|
|
12
|
+
policies: ReturnType<ReturnType<typeof defineResources>["definePolicies"]>;
|
|
13
|
+
}>;
|
|
14
|
+
export type TClientOptions = Readonly<{
|
|
10
15
|
version?: 1;
|
|
11
16
|
logs?: boolean;
|
|
12
|
-
}
|
|
17
|
+
}>;
|
|
13
18
|
export interface IClient<TAccountMetadata extends TDefaultAccountMetadata = TDefaultAccountMetadata> {
|
|
14
19
|
createPlainAccount(args: {
|
|
15
20
|
identity: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
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 { IClient, TAuthState, TClientConfigs, TClientOptions } from "./client.interface";
|
|
4
|
+
export type { IClient, TAuthState, TClientCredential as TClientConfigs, TClientOptions } from "./client.interface";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TOptionalTupleUnorderedNonEmpty } from "../ultils/types";
|
|
2
|
+
import type { TResourceDefinition } from "./resources";
|
|
3
|
+
export type TActionGuardOptions<T extends readonly TResourceDefinition[]> = {
|
|
4
|
+
[R in T[number] as R["type"]]: {
|
|
5
|
+
resource: R["type"];
|
|
6
|
+
action: R["actions"][number] | TOptionalTupleUnorderedNonEmpty<R["actions"]>;
|
|
7
|
+
};
|
|
8
|
+
}[T[number]["type"]];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TResourceDefinition } from "./resources";
|
|
2
|
+
export type TPolicyDefinition<T extends readonly TResourceDefinition[] = readonly TResourceDefinition[]> = {
|
|
3
|
+
readonly alias: string;
|
|
4
|
+
readonly effect: "permit" | "deny";
|
|
5
|
+
readonly [key: string]: unknown;
|
|
6
|
+
} & {
|
|
7
|
+
[R in T[number] as R["type"]]: {
|
|
8
|
+
readonly resource: R["type"];
|
|
9
|
+
readonly action: R["actions"][number];
|
|
10
|
+
};
|
|
11
|
+
}[T[number]["type"]];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type DeepReadonly<T> = T extends (...args: any[]) => any ? T : T extends readonly any[] ? {
|
|
2
|
+
readonly [K in keyof T]: DeepReadonly<T[K]>;
|
|
3
|
+
} : T extends object ? {
|
|
4
|
+
readonly [K in keyof T]: DeepReadonly<T[K]>;
|
|
5
|
+
} : T;
|
|
6
|
+
export declare function deepFreeze<const T>(obj: T): DeepReadonly<T>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { deepFreeze } from "./deepFreeze";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TConstructor<T, K extends any[] = any[]> = new (...args: K) => T;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ValuesOfKey<Arr extends any[], K extends keyof any> = Arr extends [
|
|
2
|
+
infer Head,
|
|
3
|
+
...infer Tail
|
|
4
|
+
] ? Head extends Record<K, any> ? [Head[K], ...ValuesOfKey<Tail, K>] : ValuesOfKey<Tail, K> : [];
|
|
5
|
+
type Includes<Arr extends any[], V> = Arr extends [infer H, ...infer R] ? [V] extends [H] ? true : Includes<R, V> : false;
|
|
6
|
+
type HasDuplicate<Arr extends readonly any[], K extends keyof any> = Arr extends [infer Head, ...infer Tail] ? Head extends Record<K, any> ? Includes<ValuesOfKey<Tail, K>, Head[K]> extends true ? true : HasDuplicate<Tail, K> : HasDuplicate<Tail, K> : false;
|
|
7
|
+
export type TEnforceUnique<Arr extends readonly any[], K extends keyof Arr[number]> = HasDuplicate<Arr, K> extends true ? ["Duplicate key found"] : Arr;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ExtractTuple<T> = T extends readonly [...infer U] ? U : never;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TInArray<T, X> = T extends readonly [X, ...infer _Rest] ? true : T extends readonly [X] ? true : T extends readonly [infer _, ...infer Rest] ? TInArray<Rest, X> : false;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type { TConstructor } from "./constructor";
|
|
2
|
+
export type { TEnforceUnique } from "./enforceUnique";
|
|
3
|
+
export type { TError } from "./error";
|
|
4
|
+
export type { ExtractTuple } from "./extractTuple";
|
|
5
|
+
export type { TInArray } from "./inArray";
|
|
6
|
+
export type { MergeTuple } from "./mergeTuple";
|
|
7
|
+
export type { TNonEmptyArray } from "./noneEmptyArray";
|
|
8
|
+
export type { TPartialTuple } from "./partialTuple";
|
|
9
|
+
export type { TPartialTupleUnordered as TOptionalTupleUnordered } from "./partialTupleUnordered";
|
|
10
|
+
export type { TOptionalTupleUnorderedNonEmpty } from "./partialTupleUnorderedNonEmpty";
|
|
11
|
+
export type { TPartialTupleNonEmpty } from "./partialTurpleNonEmpty";
|
|
12
|
+
export type { TPermutationTuple } from "./permutationTuple";
|
|
13
|
+
export type { TShuffleTuple } from "./shuffleTuple";
|
|
14
|
+
export type { TStrictPartial } from "./strictPartial";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TNonEmptyArray<T> = readonly [T, ...T[]];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TPartialTuple<T extends readonly any[]> = T extends readonly [infer Head, ...infer Tail] ? TPartialTuple<Tail> | [Head, ...TPartialTuple<Tail>] : [];
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TPartialTuple } from "./partialTuple";
|
|
2
|
+
import type { TPermutationTuple } from "./permutationTuple";
|
|
3
|
+
export type TPartialTupleUnordered<T extends readonly any[]> = TPartialTuple<T> extends infer S ? S extends readonly any[] ? TPermutationTuple<S[number]> : never : never;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TPartialTupleNonEmpty } from "./partialTurpleNonEmpty";
|
|
2
|
+
import type { TPermutationTuple } from "./permutationTuple";
|
|
3
|
+
export type TOptionalTupleUnorderedNonEmpty<T extends readonly any[]> = TPartialTupleNonEmpty<T> extends infer S ? S extends readonly any[] ? TPermutationTuple<S[number]> : never : never;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TPermutationTuple<T, K = T> = [T] extends [never] ? [] : T extends any ? [T, ...TPermutationTuple<Exclude<K, T>>] : never;
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"jose": "^6.1.0",
|
|
8
|
-
"zod": "^4.1.
|
|
8
|
+
"zod": "^4.1.12"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@types/bun": "latest",
|
|
12
|
-
"typescript": "^5.9.
|
|
12
|
+
"typescript": "^5.9.3"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"./dist",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"test": "bun --hot run __test/index.ts"
|
|
47
47
|
},
|
|
48
48
|
"types": "./dist/index.d.ts",
|
|
49
|
-
"version": "1.0
|
|
50
|
-
}
|
|
49
|
+
"version": "1.1.0-beta.1"
|
|
50
|
+
}
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import type { TActionGuardOptions, TResourceDefinition } from "../types";
|
|
2
|
+
import type { TConstructor } from "../ultils/types";
|
|
3
|
+
|
|
1
4
|
import { Keys } from "../constants";
|
|
2
5
|
|
|
3
|
-
export const ActionGuard =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
export const ActionGuard =
|
|
7
|
+
<
|
|
8
|
+
const T extends readonly TResourceDefinition[] = readonly TResourceDefinition[],
|
|
9
|
+
K extends TConstructor<Object> | Object = Object
|
|
10
|
+
>(
|
|
11
|
+
options?: TActionGuardOptions<T>
|
|
12
|
+
) =>
|
|
13
|
+
(target: K, methodName: string) => {
|
|
14
|
+
Reflect.defineMetadata(
|
|
15
|
+
Keys.guardMetadata,
|
|
16
|
+
options,
|
|
17
|
+
target.constructor,
|
|
18
|
+
methodName
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { TConstructor } from "../ultils/types";
|
|
2
|
+
|
|
1
3
|
import { Keys } from "../constants";
|
|
2
4
|
|
|
3
|
-
export const ControllerGuard =
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
export const ControllerGuard =
|
|
6
|
+
<T extends TConstructor<Object>>() =>
|
|
7
|
+
(target: T) => {
|
|
8
|
+
Reflect.defineMetadata(Keys.guardMetadata, undefined, target);
|
|
9
|
+
};
|
package/src/decorators/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defineResources } from "./resources";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { TPolicyDefinition } from "../types";
|
|
2
|
+
import type { TEnforceUnique } from "../ultils/types";
|
|
3
|
+
|
|
4
|
+
import { deepFreeze } from "../ultils/functions";
|
|
5
|
+
|
|
6
|
+
export const definePolicies = <const K extends readonly TPolicyDefinition[]>(
|
|
7
|
+
policies: TEnforceUnique<K, "alias">
|
|
8
|
+
) => {
|
|
9
|
+
if (
|
|
10
|
+
new Set([
|
|
11
|
+
...policies
|
|
12
|
+
.map((policy) =>
|
|
13
|
+
typeof policy === "string" ? undefined : policy.alias
|
|
14
|
+
)
|
|
15
|
+
.filter((policyAlias) => typeof policyAlias !== "undefined")
|
|
16
|
+
]).size !== policies.length
|
|
17
|
+
) {
|
|
18
|
+
throw new Error("Duplicated policy alias.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return Object.freeze({
|
|
22
|
+
policies: deepFreeze(policies)
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { TPolicyDefinition, TResourceDefinition } from "../types";
|
|
2
|
+
import type { TEnforceUnique } from "../ultils/types";
|
|
3
|
+
|
|
4
|
+
import { deepFreeze } from "../ultils/functions";
|
|
5
|
+
|
|
6
|
+
export const defineResources = <const T extends readonly TResourceDefinition[]>(
|
|
7
|
+
resources: TEnforceUnique<T, "type">
|
|
8
|
+
) => {
|
|
9
|
+
if (
|
|
10
|
+
new Set([
|
|
11
|
+
...resources
|
|
12
|
+
.map((resource) =>
|
|
13
|
+
typeof resource === "string" ? undefined : resource.type
|
|
14
|
+
)
|
|
15
|
+
.filter((resourceType) => typeof resourceType !== "undefined")
|
|
16
|
+
]).size !== resources.length
|
|
17
|
+
) {
|
|
18
|
+
throw new Error("Duplicated resource type.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return Object.freeze({
|
|
22
|
+
resources: deepFreeze(resources),
|
|
23
|
+
definePolicies: <const K extends readonly TPolicyDefinition<T>[]>(
|
|
24
|
+
policies: TEnforceUnique<K, "alias">
|
|
25
|
+
) => {
|
|
26
|
+
if (
|
|
27
|
+
new Set([
|
|
28
|
+
...policies
|
|
29
|
+
.map((policy) =>
|
|
30
|
+
typeof policy === "string"
|
|
31
|
+
? undefined
|
|
32
|
+
: policy.alias
|
|
33
|
+
)
|
|
34
|
+
.filter(
|
|
35
|
+
(policyAlias) => typeof policyAlias !== "undefined"
|
|
36
|
+
)
|
|
37
|
+
]).size !== policies.length
|
|
38
|
+
) {
|
|
39
|
+
throw new Error("Duplicated policy alias.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
policies: deepFreeze(policies)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
};
|
package/src/entities/loader.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
TClientCredential,
|
|
3
|
+
TClientDefinition,
|
|
4
|
+
TClientOptions
|
|
5
|
+
} from "../interfaces/client.interface";
|
|
2
6
|
|
|
3
7
|
import { Keys } from "../constants";
|
|
4
8
|
import { Client } from "../instances/client";
|
|
5
9
|
|
|
6
|
-
export
|
|
7
|
-
|
|
10
|
+
export type TLoaderParameters = {
|
|
11
|
+
credential: TClientCredential;
|
|
12
|
+
definition?: TClientDefinition;
|
|
13
|
+
options?: TClientOptions;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const loader = async ({
|
|
17
|
+
credential,
|
|
18
|
+
definition,
|
|
19
|
+
options
|
|
20
|
+
}: TLoaderParameters) => {
|
|
21
|
+
const boolGuardClient = new Client({ credential, definition, options });
|
|
8
22
|
|
|
9
23
|
await boolGuardClient.signToken();
|
|
10
24
|
|
|
@@ -4,7 +4,6 @@ import type { IClient, TAuthState } from "../interfaces/client.interface";
|
|
|
4
4
|
import { Middleware as BoolMiddleware, Context, Inject, RequestHeaders } from "@bool-ts/core";
|
|
5
5
|
import { object, string } from "zod/v4";
|
|
6
6
|
import { Keys } from "../constants";
|
|
7
|
-
import { Client } from "../instances";
|
|
8
7
|
|
|
9
8
|
const headersSchema = object({
|
|
10
9
|
authorization: string()
|
|
@@ -30,7 +29,7 @@ export class Middleware implements IMiddleware {
|
|
|
30
29
|
* @param tenantAppModesService
|
|
31
30
|
*/
|
|
32
31
|
constructor(
|
|
33
|
-
@Inject(
|
|
32
|
+
@Inject(Keys.guardClient)
|
|
34
33
|
private readonly clientInstance: IClient
|
|
35
34
|
) {}
|
|
36
35
|
|