@bool-ts/guard-sdk 1.0.2-beta.5 → 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 +9 -11
- 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/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
package/src/instances/client.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { TApiResponse } from "../interfaces/base";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
IClient,
|
|
4
|
+
TClientCredential,
|
|
5
|
+
TClientDefinition,
|
|
6
|
+
TClientOptions
|
|
7
|
+
} from "../interfaces/client.interface";
|
|
3
8
|
|
|
4
9
|
import { SignJWT } from "jose";
|
|
5
10
|
import { email } from "zod/v4";
|
|
@@ -7,6 +12,7 @@ import { Enums } from "../constants";
|
|
|
7
12
|
|
|
8
13
|
export class Client implements IClient {
|
|
9
14
|
readonly #baseUri = Enums.ETokenAudiences.SYSTEM;
|
|
15
|
+
readonly #defaultVersion: number = 1;
|
|
10
16
|
|
|
11
17
|
private token: string | undefined;
|
|
12
18
|
|
|
@@ -16,8 +22,11 @@ export class Client implements IClient {
|
|
|
16
22
|
* @param options
|
|
17
23
|
*/
|
|
18
24
|
constructor(
|
|
19
|
-
private readonly
|
|
20
|
-
|
|
25
|
+
private readonly params: Readonly<{
|
|
26
|
+
credential: TClientCredential;
|
|
27
|
+
definition?: TClientDefinition;
|
|
28
|
+
options?: TClientOptions;
|
|
29
|
+
}>
|
|
21
30
|
) {}
|
|
22
31
|
|
|
23
32
|
/**
|
|
@@ -25,8 +34,16 @@ export class Client implements IClient {
|
|
|
25
34
|
* @returns
|
|
26
35
|
*/
|
|
27
36
|
async signToken() {
|
|
37
|
+
const {
|
|
38
|
+
params: {
|
|
39
|
+
credential: { tenantId, appId, modeId, secretKey },
|
|
40
|
+
options
|
|
41
|
+
}
|
|
42
|
+
} = this;
|
|
43
|
+
|
|
28
44
|
try {
|
|
29
|
-
const rawKey = new Uint8Array(Buffer.from(
|
|
45
|
+
const rawKey = new Uint8Array(Buffer.from(secretKey, "base64"));
|
|
46
|
+
|
|
30
47
|
const privateKey = await crypto.subtle.importKey(
|
|
31
48
|
"raw",
|
|
32
49
|
rawKey,
|
|
@@ -36,10 +53,10 @@ export class Client implements IClient {
|
|
|
36
53
|
);
|
|
37
54
|
|
|
38
55
|
const jwt = await new SignJWT({
|
|
39
|
-
tenantId:
|
|
40
|
-
appId:
|
|
41
|
-
modeId:
|
|
42
|
-
iss:
|
|
56
|
+
tenantId: tenantId,
|
|
57
|
+
appId: appId,
|
|
58
|
+
modeId: modeId,
|
|
59
|
+
iss: tenantId,
|
|
43
60
|
aud: Enums.ETokenAudiences.SYSTEM
|
|
44
61
|
})
|
|
45
62
|
.setProtectedHeader({ alg: "HS512" })
|
|
@@ -49,7 +66,7 @@ export class Client implements IClient {
|
|
|
49
66
|
|
|
50
67
|
return jwt;
|
|
51
68
|
} catch (error) {
|
|
52
|
-
if (
|
|
69
|
+
if (options?.logs) {
|
|
53
70
|
console.error("[BoolGuard] Sign token error:", error);
|
|
54
71
|
}
|
|
55
72
|
|
|
@@ -63,17 +80,27 @@ export class Client implements IClient {
|
|
|
63
80
|
* @returns
|
|
64
81
|
*/
|
|
65
82
|
async ping() {
|
|
66
|
-
|
|
67
|
-
|
|
83
|
+
const {
|
|
84
|
+
token,
|
|
85
|
+
params: {
|
|
86
|
+
credential: { tenantId, appId, modeId },
|
|
87
|
+
options
|
|
88
|
+
}
|
|
89
|
+
} = this;
|
|
68
90
|
|
|
91
|
+
try {
|
|
92
|
+
const authToken = token || (await this.signToken());
|
|
69
93
|
const requestHeaders = new Headers();
|
|
70
|
-
|
|
71
|
-
requestHeaders.append("X-
|
|
72
|
-
requestHeaders.append("X-
|
|
94
|
+
|
|
95
|
+
requestHeaders.append("X-Tenant-ID", tenantId);
|
|
96
|
+
requestHeaders.append("X-App-ID", appId);
|
|
97
|
+
requestHeaders.append("X-Mode-ID", modeId);
|
|
73
98
|
requestHeaders.append("Authorization", `Bearer ${authToken}`);
|
|
74
99
|
|
|
75
100
|
const response = await fetch(
|
|
76
|
-
`${this.#baseUri}/v${
|
|
101
|
+
`${this.#baseUri}/v${
|
|
102
|
+
options?.version || this.#defaultVersion
|
|
103
|
+
}/tenant-app-modes/ping`,
|
|
77
104
|
{
|
|
78
105
|
method: "GET",
|
|
79
106
|
headers: requestHeaders
|
|
@@ -86,7 +113,7 @@ export class Client implements IClient {
|
|
|
86
113
|
|
|
87
114
|
return response.ok;
|
|
88
115
|
} catch (error) {
|
|
89
|
-
if (
|
|
116
|
+
if (options?.logs) {
|
|
90
117
|
console.error("[BoolGuard] Ping error:", error);
|
|
91
118
|
}
|
|
92
119
|
|
|
@@ -106,28 +133,38 @@ export class Client implements IClient {
|
|
|
106
133
|
}: Parameters<IClient["createPlainAccount"]>[number]): ReturnType<
|
|
107
134
|
IClient["createPlainAccount"]
|
|
108
135
|
> {
|
|
109
|
-
|
|
110
|
-
|
|
136
|
+
const {
|
|
137
|
+
token,
|
|
138
|
+
params: {
|
|
139
|
+
credential: { tenantId, appId, modeId },
|
|
140
|
+
options
|
|
141
|
+
}
|
|
142
|
+
} = this;
|
|
111
143
|
|
|
144
|
+
try {
|
|
145
|
+
const authToken = token || (await this.signToken());
|
|
112
146
|
const requestHeaders = new Headers();
|
|
113
|
-
|
|
114
|
-
requestHeaders.append("X-
|
|
115
|
-
requestHeaders.append("X-
|
|
147
|
+
|
|
148
|
+
requestHeaders.append("X-Tenant-ID", tenantId);
|
|
149
|
+
requestHeaders.append("X-App-ID", appId);
|
|
150
|
+
requestHeaders.append("X-Mode-ID", modeId);
|
|
116
151
|
requestHeaders.append("Authorization", `Bearer ${authToken}`);
|
|
117
152
|
requestHeaders.append("Content-Type", "application/json");
|
|
118
153
|
|
|
119
154
|
const response = await fetch(
|
|
120
|
-
`${this.#baseUri}/v${
|
|
155
|
+
`${this.#baseUri}/v${
|
|
156
|
+
options?.version || this.#defaultVersion
|
|
157
|
+
}/tenant-app-mode-accounts`,
|
|
121
158
|
{
|
|
122
159
|
method: "POST",
|
|
123
160
|
headers: requestHeaders,
|
|
124
161
|
body: JSON.stringify({
|
|
125
|
-
data: {
|
|
162
|
+
data: Object.freeze({
|
|
126
163
|
type: "plain",
|
|
127
164
|
identity: identity,
|
|
128
165
|
password: password,
|
|
129
166
|
metadata: metadata
|
|
130
|
-
}
|
|
167
|
+
})
|
|
131
168
|
})
|
|
132
169
|
}
|
|
133
170
|
);
|
|
@@ -136,14 +173,16 @@ export class Client implements IClient {
|
|
|
136
173
|
throw await response.json();
|
|
137
174
|
}
|
|
138
175
|
|
|
139
|
-
const { data } = (await response.json()) as TApiResponse<
|
|
176
|
+
const { data } = (await response.json()) as TApiResponse<
|
|
177
|
+
IClient["createPlainAccount"]
|
|
178
|
+
>;
|
|
140
179
|
|
|
141
180
|
return Object.freeze({
|
|
142
181
|
account: data.account,
|
|
143
182
|
credential: data.credential
|
|
144
183
|
});
|
|
145
184
|
} catch (error) {
|
|
146
|
-
if (
|
|
185
|
+
if (options?.logs) {
|
|
147
186
|
console.error("[BoolGuard] Create plain account error:", error);
|
|
148
187
|
}
|
|
149
188
|
|
|
@@ -163,28 +202,38 @@ export class Client implements IClient {
|
|
|
163
202
|
}: Parameters<IClient["createEmailAccount"]>[number]): ReturnType<
|
|
164
203
|
IClient["createEmailAccount"]
|
|
165
204
|
> {
|
|
166
|
-
|
|
167
|
-
|
|
205
|
+
const {
|
|
206
|
+
token,
|
|
207
|
+
params: {
|
|
208
|
+
credential: { tenantId, appId, modeId },
|
|
209
|
+
options
|
|
210
|
+
}
|
|
211
|
+
} = this;
|
|
168
212
|
|
|
213
|
+
try {
|
|
214
|
+
const authToken = token || (await this.signToken());
|
|
169
215
|
const requestHeaders = new Headers();
|
|
170
|
-
|
|
171
|
-
requestHeaders.append("X-
|
|
172
|
-
requestHeaders.append("X-
|
|
216
|
+
|
|
217
|
+
requestHeaders.append("X-Tenant-ID", tenantId);
|
|
218
|
+
requestHeaders.append("X-App-ID", appId);
|
|
219
|
+
requestHeaders.append("X-Mode-ID", modeId);
|
|
173
220
|
requestHeaders.append("Authorization", `Bearer ${authToken}`);
|
|
174
221
|
requestHeaders.append("Content-Type", "application/json");
|
|
175
222
|
|
|
176
223
|
const response = await fetch(
|
|
177
|
-
`${this.#baseUri}/v${
|
|
224
|
+
`${this.#baseUri}/v${
|
|
225
|
+
options?.version || this.#defaultVersion
|
|
226
|
+
}/tenant-app-mode-accounts`,
|
|
178
227
|
{
|
|
179
228
|
method: "POST",
|
|
180
229
|
headers: requestHeaders,
|
|
181
230
|
body: JSON.stringify({
|
|
182
|
-
data: {
|
|
231
|
+
data: Object.freeze({
|
|
183
232
|
type: "email",
|
|
184
233
|
identity: identity,
|
|
185
234
|
password: password,
|
|
186
235
|
metadata: metadata
|
|
187
|
-
}
|
|
236
|
+
})
|
|
188
237
|
})
|
|
189
238
|
}
|
|
190
239
|
);
|
|
@@ -193,14 +242,16 @@ export class Client implements IClient {
|
|
|
193
242
|
throw await response.json();
|
|
194
243
|
}
|
|
195
244
|
|
|
196
|
-
const { data } = (await response.json()) as TApiResponse<
|
|
245
|
+
const { data } = (await response.json()) as TApiResponse<
|
|
246
|
+
IClient["createEmailAccount"]
|
|
247
|
+
>;
|
|
197
248
|
|
|
198
249
|
return Object.freeze({
|
|
199
250
|
account: data.account,
|
|
200
251
|
credential: data.credential
|
|
201
252
|
});
|
|
202
253
|
} catch (error) {
|
|
203
|
-
if (
|
|
254
|
+
if (options?.logs) {
|
|
204
255
|
console.error("[BoolGuard] Create email account error:", error);
|
|
205
256
|
}
|
|
206
257
|
|
|
@@ -216,29 +267,41 @@ export class Client implements IClient {
|
|
|
216
267
|
async authenticate({
|
|
217
268
|
identity,
|
|
218
269
|
password
|
|
219
|
-
}: Parameters<IClient["authenticate"]>[number]): ReturnType<
|
|
270
|
+
}: Parameters<IClient["authenticate"]>[number]): ReturnType<
|
|
271
|
+
IClient["authenticate"]
|
|
272
|
+
> {
|
|
273
|
+
const {
|
|
274
|
+
token,
|
|
275
|
+
params: {
|
|
276
|
+
credential: { tenantId, appId, modeId },
|
|
277
|
+
options
|
|
278
|
+
}
|
|
279
|
+
} = this;
|
|
280
|
+
|
|
220
281
|
try {
|
|
221
|
-
const authToken =
|
|
282
|
+
const authToken = token || (await this.signToken());
|
|
222
283
|
const emailValidation = await email().safeParseAsync(identity);
|
|
223
|
-
|
|
224
284
|
const requestHeaders = new Headers();
|
|
225
|
-
|
|
226
|
-
requestHeaders.append("X-
|
|
227
|
-
requestHeaders.append("X-
|
|
285
|
+
|
|
286
|
+
requestHeaders.append("X-Tenant-ID", tenantId);
|
|
287
|
+
requestHeaders.append("X-App-ID", appId);
|
|
288
|
+
requestHeaders.append("X-Mode-ID", modeId);
|
|
228
289
|
requestHeaders.append("Authorization", `Bearer ${authToken}`);
|
|
229
290
|
requestHeaders.append("Content-Type", "application/json");
|
|
230
291
|
|
|
231
292
|
const response = await fetch(
|
|
232
|
-
`${this.#baseUri}/v${
|
|
293
|
+
`${this.#baseUri}/v${
|
|
294
|
+
options?.version || this.#defaultVersion
|
|
295
|
+
}/tenant-app-mode-accounts/authenticate`,
|
|
233
296
|
{
|
|
234
297
|
method: "POST",
|
|
235
298
|
headers: requestHeaders,
|
|
236
299
|
body: JSON.stringify({
|
|
237
|
-
data: {
|
|
300
|
+
data: Object.freeze({
|
|
238
301
|
type: !emailValidation.success ? "plain" : "email",
|
|
239
302
|
identity: identity,
|
|
240
303
|
password: password
|
|
241
|
-
}
|
|
304
|
+
})
|
|
242
305
|
})
|
|
243
306
|
}
|
|
244
307
|
);
|
|
@@ -247,7 +310,9 @@ export class Client implements IClient {
|
|
|
247
310
|
throw await response.json();
|
|
248
311
|
}
|
|
249
312
|
|
|
250
|
-
const { data } = (await response.json()) as TApiResponse<
|
|
313
|
+
const { data } = (await response.json()) as TApiResponse<
|
|
314
|
+
IClient["authenticate"]
|
|
315
|
+
>;
|
|
251
316
|
|
|
252
317
|
return Object.freeze({
|
|
253
318
|
account: data.account,
|
|
@@ -255,7 +320,7 @@ export class Client implements IClient {
|
|
|
255
320
|
token: data.token
|
|
256
321
|
});
|
|
257
322
|
} catch (error) {
|
|
258
|
-
if (
|
|
323
|
+
if (options?.logs) {
|
|
259
324
|
console.error("[BoolGuard] Authenticate error:", error);
|
|
260
325
|
}
|
|
261
326
|
|
|
@@ -269,26 +334,37 @@ export class Client implements IClient {
|
|
|
269
334
|
*/
|
|
270
335
|
async verifyToken({
|
|
271
336
|
token
|
|
272
|
-
}: Parameters<IClient["verifyToken"]>[number]): ReturnType<
|
|
337
|
+
}: Parameters<IClient["verifyToken"]>[number]): ReturnType<
|
|
338
|
+
IClient["verifyToken"]
|
|
339
|
+
> {
|
|
340
|
+
const {
|
|
341
|
+
params: {
|
|
342
|
+
credential: { tenantId, appId, modeId },
|
|
343
|
+
options
|
|
344
|
+
}
|
|
345
|
+
} = this;
|
|
346
|
+
|
|
273
347
|
try {
|
|
274
348
|
const authToken = this.token || (await this.signToken());
|
|
275
|
-
|
|
276
349
|
const requestHeaders = new Headers();
|
|
277
|
-
|
|
278
|
-
requestHeaders.append("X-
|
|
279
|
-
requestHeaders.append("X-
|
|
350
|
+
|
|
351
|
+
requestHeaders.append("X-Tenant-ID", tenantId);
|
|
352
|
+
requestHeaders.append("X-App-ID", appId);
|
|
353
|
+
requestHeaders.append("X-Mode-ID", modeId);
|
|
280
354
|
requestHeaders.append("Authorization", `Bearer ${authToken}`);
|
|
281
355
|
requestHeaders.append("Content-Type", "application/json");
|
|
282
356
|
|
|
283
357
|
const response = await fetch(
|
|
284
|
-
`${this.#baseUri}/v${
|
|
358
|
+
`${this.#baseUri}/v${
|
|
359
|
+
options?.version || this.#defaultVersion
|
|
360
|
+
}/tenant-app-mode-accounts/verify`,
|
|
285
361
|
{
|
|
286
362
|
method: "POST",
|
|
287
363
|
headers: requestHeaders,
|
|
288
364
|
body: JSON.stringify({
|
|
289
|
-
data: {
|
|
365
|
+
data: Object.freeze({
|
|
290
366
|
token: token
|
|
291
|
-
}
|
|
367
|
+
})
|
|
292
368
|
})
|
|
293
369
|
}
|
|
294
370
|
);
|
|
@@ -297,14 +373,16 @@ export class Client implements IClient {
|
|
|
297
373
|
throw await response.json();
|
|
298
374
|
}
|
|
299
375
|
|
|
300
|
-
const { data } = (await response.json()) as TApiResponse<
|
|
376
|
+
const { data } = (await response.json()) as TApiResponse<
|
|
377
|
+
IClient["verifyToken"]
|
|
378
|
+
>;
|
|
301
379
|
|
|
302
380
|
return Object.freeze({
|
|
303
381
|
account: data.account,
|
|
304
382
|
credential: data.credential
|
|
305
383
|
});
|
|
306
384
|
} catch (error) {
|
|
307
|
-
if (
|
|
385
|
+
if (options?.logs) {
|
|
308
386
|
console.error("[BoolGuard] Verify token error:", error);
|
|
309
387
|
}
|
|
310
388
|
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
import type { defineResources } from "../definers";
|
|
1
2
|
import type { IAccount, TDefaultAccountMetadata } from "./account.interface";
|
|
2
3
|
import type { IAccountCredential } from "./accountCredential.interface";
|
|
3
4
|
|
|
4
|
-
export type
|
|
5
|
+
export type TClientCredential = Readonly<{
|
|
5
6
|
tenantId: string;
|
|
6
7
|
appId: string;
|
|
7
8
|
modeId: string;
|
|
8
9
|
secretKey: string;
|
|
9
|
-
}
|
|
10
|
+
}>;
|
|
11
|
+
|
|
12
|
+
export type TClientDefinition = Readonly<{
|
|
13
|
+
resources: ReturnType<typeof defineResources>["resources"];
|
|
14
|
+
policies: ReturnType<ReturnType<typeof defineResources>["definePolicies"]>;
|
|
15
|
+
}>;
|
|
10
16
|
|
|
11
|
-
export type TClientOptions = {
|
|
17
|
+
export type TClientOptions = Readonly<{
|
|
12
18
|
version?: 1;
|
|
13
19
|
logs?: boolean;
|
|
14
|
-
}
|
|
20
|
+
}>;
|
|
15
21
|
|
|
16
22
|
export interface IClient<
|
|
17
23
|
TAccountMetadata extends TDefaultAccountMetadata = TDefaultAccountMetadata
|
|
@@ -36,14 +42,20 @@ export interface IClient<
|
|
|
36
42
|
credential: IAccountCredential;
|
|
37
43
|
}>
|
|
38
44
|
>;
|
|
39
|
-
authenticate(args: {
|
|
45
|
+
authenticate(args: {
|
|
46
|
+
identity: string;
|
|
47
|
+
password?: string | null;
|
|
48
|
+
}): Promise<{
|
|
40
49
|
token: string;
|
|
41
50
|
account: IAccount<TAccountMetadata>;
|
|
42
51
|
credential: IAccountCredential;
|
|
43
52
|
}>;
|
|
44
53
|
verifyToken(args: {
|
|
45
54
|
token: string;
|
|
46
|
-
}): Promise<{
|
|
55
|
+
}): Promise<{
|
|
56
|
+
account: IAccount<TAccountMetadata>;
|
|
57
|
+
credential: IAccountCredential;
|
|
58
|
+
}>;
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
export type TAuthState = {
|
package/src/interfaces/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
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";
|
|
5
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TOptionalTupleUnorderedNonEmpty } from "../ultils/types";
|
|
2
|
+
import type { TResourceDefinition } from "./resources";
|
|
3
|
+
|
|
4
|
+
export type TActionGuardOptions<T extends readonly TResourceDefinition[]> = {
|
|
5
|
+
[R in T[number] as R["type"]]: {
|
|
6
|
+
resource: R["type"];
|
|
7
|
+
action:
|
|
8
|
+
| R["actions"][number]
|
|
9
|
+
| TOptionalTupleUnorderedNonEmpty<R["actions"]>;
|
|
10
|
+
};
|
|
11
|
+
}[T[number]["type"]];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TResourceDefinition } from "./resources";
|
|
2
|
+
|
|
3
|
+
export type TPolicyDefinition<
|
|
4
|
+
T extends readonly TResourceDefinition[] = readonly TResourceDefinition[]
|
|
5
|
+
> = {
|
|
6
|
+
readonly alias: string;
|
|
7
|
+
readonly effect: "permit" | "deny";
|
|
8
|
+
readonly [key: string]: unknown;
|
|
9
|
+
} & {
|
|
10
|
+
[R in T[number] as R["type"]]: {
|
|
11
|
+
readonly resource: R["type"];
|
|
12
|
+
readonly action: R["actions"][number];
|
|
13
|
+
};
|
|
14
|
+
}[T[number]["type"]];
|
|
15
|
+
|
|
16
|
+
// export type TPolicyAttributes<
|
|
17
|
+
// T extends readonly TResourceDefinition[],
|
|
18
|
+
// K extends readonly TPolicyDefinition[] = readonly TPolicyDefinition[]
|
|
19
|
+
// > = {
|
|
20
|
+
// [R in K[number] as R["alias"]]: {
|
|
21
|
+
// readonly alias: string;
|
|
22
|
+
// readonly effect: "permit" | "deny";
|
|
23
|
+
// } & {
|
|
24
|
+
// [R in T[number] as R["type"]]: {
|
|
25
|
+
// readonly resource: R["type"];
|
|
26
|
+
// readonly action: R["actions"][number];
|
|
27
|
+
// };
|
|
28
|
+
// }[T[number]["type"]];
|
|
29
|
+
// }[K[number]["alias"]];
|
|
30
|
+
|
|
31
|
+
// {
|
|
32
|
+
// [R in K[number] as R["type"]]: {
|
|
33
|
+
// readonly resource: R["type"];
|
|
34
|
+
// readonly action: R["actions"][number];
|
|
35
|
+
// };
|
|
36
|
+
// }[K[number]["type"]];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TNonEmptyArray } from "../ultils/types";
|
|
2
|
+
|
|
3
|
+
export type TResourceDefinition<
|
|
4
|
+
T extends string = string,
|
|
5
|
+
A extends TNonEmptyArray<string> = TNonEmptyArray<string>
|
|
6
|
+
> = {
|
|
7
|
+
readonly type: T;
|
|
8
|
+
readonly actions: A;
|
|
9
|
+
readonly [key: string]: unknown;
|
|
10
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type DeepReadonly<T> = T extends (...args: any[]) => any
|
|
2
|
+
? T
|
|
3
|
+
: T extends readonly any[]
|
|
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
|
+
|
|
9
|
+
export function deepFreeze<const T>(obj: T): DeepReadonly<T> {
|
|
10
|
+
if (typeof obj !== "object" || obj === null) return obj as any;
|
|
11
|
+
Object.freeze(obj);
|
|
12
|
+
for (const key of Object.keys(obj)) {
|
|
13
|
+
const val = (obj as any)[key];
|
|
14
|
+
if (typeof val === "object" && val !== null && !Object.isFrozen(val)) {
|
|
15
|
+
deepFreeze(val);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return obj as any;
|
|
19
|
+
}
|
|
@@ -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,30 @@
|
|
|
1
|
+
type ValuesOfKey<Arr extends any[], K extends keyof any> = Arr extends [
|
|
2
|
+
infer Head,
|
|
3
|
+
...infer Tail
|
|
4
|
+
]
|
|
5
|
+
? Head extends Record<K, any>
|
|
6
|
+
? [Head[K], ...ValuesOfKey<Tail, K>]
|
|
7
|
+
: ValuesOfKey<Tail, K>
|
|
8
|
+
: [];
|
|
9
|
+
|
|
10
|
+
type Includes<Arr extends any[], V> = Arr extends [infer H, ...infer R]
|
|
11
|
+
? [V] extends [H]
|
|
12
|
+
? true
|
|
13
|
+
: Includes<R, V>
|
|
14
|
+
: false;
|
|
15
|
+
|
|
16
|
+
type HasDuplicate<
|
|
17
|
+
Arr extends readonly any[],
|
|
18
|
+
K extends keyof any
|
|
19
|
+
> = Arr extends [infer Head, ...infer Tail]
|
|
20
|
+
? Head extends Record<K, any>
|
|
21
|
+
? Includes<ValuesOfKey<Tail, K>, Head[K]> extends true
|
|
22
|
+
? true
|
|
23
|
+
: HasDuplicate<Tail, K>
|
|
24
|
+
: HasDuplicate<Tail, K>
|
|
25
|
+
: false;
|
|
26
|
+
|
|
27
|
+
export type TEnforceUnique<
|
|
28
|
+
Arr extends readonly any[],
|
|
29
|
+
K extends keyof Arr[number]
|
|
30
|
+
> = HasDuplicate<Arr, K> extends true ? ["Duplicate key found"] : Arr;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TError<Message extends string> = { __error__: Message };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ExtractTuple<T> = T extends readonly [...infer U] ? U : never;
|
|
@@ -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,8 @@
|
|
|
1
|
+
import type { TPartialTuple } from "./partialTuple";
|
|
2
|
+
import type { TPermutationTuple } from "./permutationTuple";
|
|
3
|
+
|
|
4
|
+
export type TPartialTupleUnordered<T extends readonly any[]> = TPartialTuple<T> extends infer S
|
|
5
|
+
? S extends readonly any[]
|
|
6
|
+
? TPermutationTuple<S[number]>
|
|
7
|
+
: never
|
|
8
|
+
: never;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TPartialTupleNonEmpty } from "./partialTurpleNonEmpty";
|
|
2
|
+
import type { TPermutationTuple } from "./permutationTuple";
|
|
3
|
+
|
|
4
|
+
export type TOptionalTupleUnorderedNonEmpty<T extends readonly any[]> =
|
|
5
|
+
TPartialTupleNonEmpty<T> extends infer S
|
|
6
|
+
? S extends readonly any[]
|
|
7
|
+
? TPermutationTuple<S[number]>
|
|
8
|
+
: never
|
|
9
|
+
: never;
|