@hiliosai/sdk 0.1.11 → 0.1.14
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/index.d.ts +904 -0
- package/dist/index.js +1809 -0
- package/package.json +12 -7
- package/src/configs/constants.ts +0 -135
- package/src/configs/index.ts +0 -2
- package/src/configs/moleculer/bulkhead.ts +0 -8
- package/src/configs/moleculer/channels.ts +0 -102
- package/src/configs/moleculer/circuit-breaker.ts +0 -17
- package/src/configs/moleculer/index.ts +0 -85
- package/src/configs/moleculer/logger.ts +0 -17
- package/src/configs/moleculer/metrics.ts +0 -20
- package/src/configs/moleculer/registry.ts +0 -7
- package/src/configs/moleculer/retry-policy.ts +0 -17
- package/src/configs/moleculer/tracing.ts +0 -6
- package/src/configs/moleculer/tracking.ts +0 -6
- package/src/configs/permissions.ts +0 -109
- package/src/datasources/base.datasource.ts +0 -111
- package/src/datasources/extensions/index.ts +0 -11
- package/src/datasources/extensions/retry.extension.ts +0 -91
- package/src/datasources/extensions/soft-delete.extension.ts +0 -113
- package/src/datasources/extensions/tenant.extension.ts +0 -104
- package/src/datasources/index.ts +0 -3
- package/src/datasources/prisma.datasource.ts +0 -317
- package/src/env.ts +0 -12
- package/src/errors/auth.error.ts +0 -33
- package/src/errors/index.ts +0 -2
- package/src/errors/permission.error.ts +0 -17
- package/src/index.ts +0 -9
- package/src/middlewares/context-helpers.middleware.ts +0 -162
- package/src/middlewares/datasource.middleware.ts +0 -73
- package/src/middlewares/health.middleware.ts +0 -134
- package/src/middlewares/index.ts +0 -5
- package/src/middlewares/memoize.middleware.ts +0 -33
- package/src/middlewares/permissions.middleware.ts +0 -162
- package/src/mixins/datasource.mixin.ts +0 -111
- package/src/mixins/index.ts +0 -1
- package/src/service/define-integration.ts +0 -404
- package/src/service/define-service.ts +0 -61
- package/src/types/channels.ts +0 -60
- package/src/types/context.ts +0 -64
- package/src/types/datasource.ts +0 -23
- package/src/types/index.ts +0 -9
- package/src/types/integration.ts +0 -28
- package/src/types/message.ts +0 -128
- package/src/types/platform.ts +0 -39
- package/src/types/service.ts +0 -209
- package/src/types/tenant.ts +0 -4
- package/src/types/user.ts +0 -16
- package/src/utils/context-cache.ts +0 -70
- package/src/utils/permission-calculator.ts +0 -62
- package/tsconfig.json +0 -13
- package/tsup.config.ts +0 -6
package/src/types/message.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import type {IntegrationPlatform} from './platform';
|
|
3
|
-
|
|
4
|
-
export interface MessageParticipant {
|
|
5
|
-
id: string;
|
|
6
|
-
name?: string;
|
|
7
|
-
avatar?: string;
|
|
8
|
-
metadata?: Record<string, any>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export enum MessageContentType {
|
|
12
|
-
TEXT = 'text',
|
|
13
|
-
IMAGE = 'image',
|
|
14
|
-
VIDEO = 'video',
|
|
15
|
-
AUDIO = 'audio',
|
|
16
|
-
FILE = 'file',
|
|
17
|
-
LOCATION = 'location',
|
|
18
|
-
BUTTONS = 'buttons',
|
|
19
|
-
CAROUSEL = 'carousel',
|
|
20
|
-
REACTION = 'reaction',
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface MessageContent {
|
|
24
|
-
type: MessageContentType;
|
|
25
|
-
text?: string;
|
|
26
|
-
media?: {
|
|
27
|
-
url: string;
|
|
28
|
-
mimeType?: string;
|
|
29
|
-
size?: number;
|
|
30
|
-
thumbnail?: string;
|
|
31
|
-
};
|
|
32
|
-
location?: {
|
|
33
|
-
latitude: number;
|
|
34
|
-
longitude: number;
|
|
35
|
-
address?: string;
|
|
36
|
-
};
|
|
37
|
-
buttons?: MessageButton[];
|
|
38
|
-
carousel?: CarouselItem[];
|
|
39
|
-
reaction?: {
|
|
40
|
-
emoji: string;
|
|
41
|
-
messageId: string;
|
|
42
|
-
};
|
|
43
|
-
metadata?: Record<string, any>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface MessageButton {
|
|
47
|
-
id: string;
|
|
48
|
-
text: string;
|
|
49
|
-
type: 'postback' | 'url' | 'call';
|
|
50
|
-
payload?: string;
|
|
51
|
-
url?: string;
|
|
52
|
-
phoneNumber?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface CarouselItem {
|
|
56
|
-
title: string;
|
|
57
|
-
subtitle?: string;
|
|
58
|
-
imageUrl?: string;
|
|
59
|
-
buttons?: MessageButton[];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export type MessageDirection = 'incoming' | 'outgoing' | 'internal';
|
|
63
|
-
|
|
64
|
-
export type MessageType =
|
|
65
|
-
| 'text'
|
|
66
|
-
| 'image'
|
|
67
|
-
| 'file'
|
|
68
|
-
| 'audio'
|
|
69
|
-
| 'video'
|
|
70
|
-
| 'location'
|
|
71
|
-
| 'contact'
|
|
72
|
-
| 'sticker'
|
|
73
|
-
| 'template';
|
|
74
|
-
|
|
75
|
-
export type MessageStatus =
|
|
76
|
-
| 'pending'
|
|
77
|
-
| 'sent'
|
|
78
|
-
| 'delivered'
|
|
79
|
-
| 'read'
|
|
80
|
-
| 'failed';
|
|
81
|
-
|
|
82
|
-
export interface Message {
|
|
83
|
-
id: string;
|
|
84
|
-
conversationId: string;
|
|
85
|
-
from: MessageParticipant;
|
|
86
|
-
to: MessageParticipant;
|
|
87
|
-
content: MessageContent;
|
|
88
|
-
direction: MessageDirection;
|
|
89
|
-
type: MessageType;
|
|
90
|
-
status: MessageStatus;
|
|
91
|
-
timestamp: number;
|
|
92
|
-
platform: IntegrationPlatform;
|
|
93
|
-
replyTo?: string;
|
|
94
|
-
threadId?: string;
|
|
95
|
-
attachments?: MessageAttachment[];
|
|
96
|
-
metadata?: Record<string, any>;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface MessageAttachment {
|
|
100
|
-
id: string;
|
|
101
|
-
name: string;
|
|
102
|
-
type: string;
|
|
103
|
-
size: number;
|
|
104
|
-
url: string;
|
|
105
|
-
thumbnail?: string;
|
|
106
|
-
metadata?: Record<string, any>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface PlatformMessage<P = any> {
|
|
110
|
-
platform: IntegrationPlatform;
|
|
111
|
-
payload: P;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export interface WebhookEvent<TPayload = any> {
|
|
115
|
-
tenantId: string;
|
|
116
|
-
channelId: string;
|
|
117
|
-
platform: IntegrationPlatform;
|
|
118
|
-
payload: TPayload;
|
|
119
|
-
headers: Record<string, string>;
|
|
120
|
-
timestamp: number;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface SendResult {
|
|
124
|
-
success: boolean;
|
|
125
|
-
messageId?: string;
|
|
126
|
-
error?: Error;
|
|
127
|
-
metadata?: Record<string, any>;
|
|
128
|
-
}
|
package/src/types/platform.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export enum IntegrationPlatform {
|
|
2
|
-
WHATSAPP = 'whatsapp',
|
|
3
|
-
TELEGRAM = 'telegram',
|
|
4
|
-
SLACK = 'slack',
|
|
5
|
-
EMAIL = 'email',
|
|
6
|
-
SMS = 'sms',
|
|
7
|
-
INSTAGRAM = 'instagram',
|
|
8
|
-
FACEBOOK = 'facebook',
|
|
9
|
-
DISCORD = 'discord',
|
|
10
|
-
WEBCHAT = 'webchat',
|
|
11
|
-
CUSTOM = 'custom',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export enum IntegrationStatus {
|
|
15
|
-
CONFIGURED = 'CONFIGURED',
|
|
16
|
-
ACTIVE = 'ACTIVE',
|
|
17
|
-
INACTIVE = 'INACTIVE',
|
|
18
|
-
ERROR = 'ERROR',
|
|
19
|
-
SUSPENDED = 'SUSPENDED',
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export enum IntegrationCapability {
|
|
23
|
-
SEND_MESSAGE = 'send_message',
|
|
24
|
-
RECEIVE_MESSAGE = 'receive_message',
|
|
25
|
-
SEND_IMAGE = 'send_image',
|
|
26
|
-
SEND_VIDEO = 'send_video',
|
|
27
|
-
SEND_AUDIO = 'send_audio',
|
|
28
|
-
SEND_FILE = 'send_file',
|
|
29
|
-
SEND_LOCATION = 'send_location',
|
|
30
|
-
SEND_BUTTONS = 'send_buttons',
|
|
31
|
-
SEND_CAROUSEL = 'send_carousel',
|
|
32
|
-
TYPING_INDICATOR = 'typing_indicator',
|
|
33
|
-
READ_RECEIPT = 'read_receipt',
|
|
34
|
-
GROUP_CHAT = 'group_chat',
|
|
35
|
-
REACTIONS = 'reactions',
|
|
36
|
-
THREADS = 'threads',
|
|
37
|
-
VOICE_CALL = 'voice_call',
|
|
38
|
-
VIDEO_CALL = 'video_call',
|
|
39
|
-
}
|
package/src/types/service.ts
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import type {
|
|
3
|
-
ActionSchema,
|
|
4
|
-
ServiceSchema as MoleculerServiceSchema,
|
|
5
|
-
ServiceEvents,
|
|
6
|
-
ServiceHooks,
|
|
7
|
-
ServiceMethods,
|
|
8
|
-
} from 'moleculer';
|
|
9
|
-
|
|
10
|
-
import type {DatasourceConstructorRegistry} from '../middlewares/datasource.middleware';
|
|
11
|
-
import type {AppContext} from './context';
|
|
12
|
-
import type {DatasourceInstanceTypes} from './datasource';
|
|
13
|
-
import type {BaseSpec, IntegrationConfig} from './integration';
|
|
14
|
-
import type {Message, SendResult, WebhookEvent} from './message';
|
|
15
|
-
|
|
16
|
-
// Type to infer TypeScript types from Moleculer parameter schemas
|
|
17
|
-
type InferParamsType<T> = T extends Record<string, any>
|
|
18
|
-
? {
|
|
19
|
-
[K in keyof T]: T[K] extends 'string'
|
|
20
|
-
? string
|
|
21
|
-
: T[K] extends 'number'
|
|
22
|
-
? number
|
|
23
|
-
: T[K] extends 'boolean'
|
|
24
|
-
? boolean
|
|
25
|
-
: T[K] extends 'array'
|
|
26
|
-
? any[]
|
|
27
|
-
: T[K] extends 'object'
|
|
28
|
-
? Record<string, any>
|
|
29
|
-
: T[K] extends {type: 'string'}
|
|
30
|
-
? string
|
|
31
|
-
: T[K] extends {type: 'number'}
|
|
32
|
-
? number
|
|
33
|
-
: T[K] extends {type: 'boolean'}
|
|
34
|
-
? boolean
|
|
35
|
-
: T[K] extends {type: 'array'}
|
|
36
|
-
? any[]
|
|
37
|
-
: T[K] extends {type: 'object'}
|
|
38
|
-
? Record<string, any>
|
|
39
|
-
: unknown;
|
|
40
|
-
}
|
|
41
|
-
: unknown;
|
|
42
|
-
|
|
43
|
-
// Action schema with automatic parameter type inference
|
|
44
|
-
export type ActionSchemaWithContext<
|
|
45
|
-
TDatasources = unknown,
|
|
46
|
-
TParams = unknown
|
|
47
|
-
> = Pick<
|
|
48
|
-
ActionSchema,
|
|
49
|
-
| 'name'
|
|
50
|
-
| 'rest'
|
|
51
|
-
| 'visibility'
|
|
52
|
-
| 'service'
|
|
53
|
-
| 'cache'
|
|
54
|
-
| 'tracing'
|
|
55
|
-
| 'bulkhead'
|
|
56
|
-
| 'circuitBreaker'
|
|
57
|
-
| 'retryPolicy'
|
|
58
|
-
| 'fallback'
|
|
59
|
-
| 'hooks'
|
|
60
|
-
> & {
|
|
61
|
-
params?: TParams;
|
|
62
|
-
handler: (
|
|
63
|
-
ctx: AppContext<TDatasources, InferParamsType<TParams>>
|
|
64
|
-
) => Promise<unknown> | unknown;
|
|
65
|
-
permissions?: string | string[];
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// Direct action handler type
|
|
69
|
-
export type ActionHandler<TDatasources = unknown> = (
|
|
70
|
-
ctx: AppContext<TDatasources>
|
|
71
|
-
) => Promise<unknown> | unknown;
|
|
72
|
-
|
|
73
|
-
// Service actions - individual action type will handle inference
|
|
74
|
-
export type ServiceActionsSchema<TDatasources = unknown> = {
|
|
75
|
-
[key: string]:
|
|
76
|
-
| ({
|
|
77
|
-
params?: any;
|
|
78
|
-
handler: (
|
|
79
|
-
ctx: AppContext<TDatasources, any>
|
|
80
|
-
) => Promise<unknown> | unknown;
|
|
81
|
-
permissions?: string | string[];
|
|
82
|
-
} & Pick<
|
|
83
|
-
ActionSchema,
|
|
84
|
-
| 'name'
|
|
85
|
-
| 'rest'
|
|
86
|
-
| 'visibility'
|
|
87
|
-
| 'service'
|
|
88
|
-
| 'cache'
|
|
89
|
-
| 'tracing'
|
|
90
|
-
| 'bulkhead'
|
|
91
|
-
| 'circuitBreaker'
|
|
92
|
-
| 'retryPolicy'
|
|
93
|
-
| 'fallback'
|
|
94
|
-
| 'hooks'
|
|
95
|
-
>)
|
|
96
|
-
| ActionHandler<TDatasources>
|
|
97
|
-
| false;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// Custom ServiceSchema that uses our action schema
|
|
101
|
-
export interface ServiceSchema<TSettings = unknown, TDatasources = unknown>
|
|
102
|
-
extends Omit<MoleculerServiceSchema<TSettings>, 'actions'> {
|
|
103
|
-
name: string;
|
|
104
|
-
version?: string | number;
|
|
105
|
-
settings?: TSettings;
|
|
106
|
-
actions?: ServiceActionsSchema<TDatasources>;
|
|
107
|
-
events?: ServiceEvents;
|
|
108
|
-
methods?: ServiceMethods;
|
|
109
|
-
hooks?: ServiceHooks;
|
|
110
|
-
dependencies?: string | string[];
|
|
111
|
-
metadata?: Record<string, any>;
|
|
112
|
-
created?: (this: MoleculerServiceSchema<TSettings>) => void | Promise<void>;
|
|
113
|
-
started?: (this: MoleculerServiceSchema<TSettings>) => void | Promise<void>;
|
|
114
|
-
stopped?: (this: MoleculerServiceSchema<TSettings>) => void | Promise<void>;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// ServiceConfig is what users provide to defineService
|
|
118
|
-
export type ServiceConfig<
|
|
119
|
-
TSettings = unknown,
|
|
120
|
-
TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry
|
|
121
|
-
> = ServiceSchema<
|
|
122
|
-
TSettings,
|
|
123
|
-
DatasourceInstanceTypes<TDatasourceConstructors>
|
|
124
|
-
> & {
|
|
125
|
-
datasources: TDatasourceConstructors;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// Integration-specific types
|
|
129
|
-
export interface IntegrationServiceConfig<
|
|
130
|
-
TSettings = unknown,
|
|
131
|
-
TDatasourceConstructors extends DatasourceConstructorRegistry = DatasourceConstructorRegistry,
|
|
132
|
-
TContext extends AppContext<
|
|
133
|
-
DatasourceInstanceTypes<TDatasourceConstructors>
|
|
134
|
-
> = AppContext<DatasourceInstanceTypes<TDatasourceConstructors>>
|
|
135
|
-
> extends ServiceConfig<TSettings, TDatasourceConstructors> {
|
|
136
|
-
name: string;
|
|
137
|
-
spec: BaseSpec;
|
|
138
|
-
|
|
139
|
-
// Core integration methods
|
|
140
|
-
normalize<TPayload = any>(
|
|
141
|
-
webhook: WebhookEvent<TPayload>
|
|
142
|
-
): Promise<Message[]>;
|
|
143
|
-
getChannelConfig(
|
|
144
|
-
ctx: TContext,
|
|
145
|
-
channelId: string
|
|
146
|
-
): Promise<IntegrationConfig | null>;
|
|
147
|
-
validateWebhook?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
|
|
148
|
-
sendMessage(
|
|
149
|
-
ctx: TContext,
|
|
150
|
-
message: Message,
|
|
151
|
-
config: IntegrationConfig
|
|
152
|
-
): Promise<SendResult>;
|
|
153
|
-
|
|
154
|
-
// Optional webhook verification
|
|
155
|
-
verifyWebhook?(params: {
|
|
156
|
-
mode: string;
|
|
157
|
-
token: string;
|
|
158
|
-
challenge: string;
|
|
159
|
-
}): string | null;
|
|
160
|
-
|
|
161
|
-
// Optional health check
|
|
162
|
-
checkHealth?(
|
|
163
|
-
ctx: TContext,
|
|
164
|
-
config: IntegrationConfig
|
|
165
|
-
): Promise<{
|
|
166
|
-
status: 'healthy' | 'unhealthy' | 'degraded';
|
|
167
|
-
message?: string;
|
|
168
|
-
details?: Record<string, any>;
|
|
169
|
-
}>;
|
|
170
|
-
|
|
171
|
-
// Optional credential validation
|
|
172
|
-
validateCredentials?(credentials: Record<string, string>): Promise<boolean>;
|
|
173
|
-
|
|
174
|
-
// Optional signature validation
|
|
175
|
-
validateSignature?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export interface IntegrationServiceSchema<TSettings = unknown>
|
|
179
|
-
extends MoleculerServiceSchema<TSettings> {
|
|
180
|
-
spec: BaseSpec;
|
|
181
|
-
normalize<TPayload = any>(
|
|
182
|
-
webhook: WebhookEvent<TPayload>
|
|
183
|
-
): Promise<Message[]>;
|
|
184
|
-
getChannelConfig(
|
|
185
|
-
ctx: AppContext,
|
|
186
|
-
channelId: string
|
|
187
|
-
): Promise<IntegrationConfig | null>;
|
|
188
|
-
validateWebhook?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
|
|
189
|
-
sendMessage(
|
|
190
|
-
ctx: AppContext,
|
|
191
|
-
message: Message,
|
|
192
|
-
config: IntegrationConfig
|
|
193
|
-
): Promise<SendResult>;
|
|
194
|
-
verifyWebhook?(params: {
|
|
195
|
-
mode: string;
|
|
196
|
-
token: string;
|
|
197
|
-
challenge: string;
|
|
198
|
-
}): string | null;
|
|
199
|
-
checkHealth?(
|
|
200
|
-
ctx: AppContext,
|
|
201
|
-
config: IntegrationConfig
|
|
202
|
-
): Promise<{
|
|
203
|
-
status: 'healthy' | 'unhealthy' | 'degraded';
|
|
204
|
-
message?: string;
|
|
205
|
-
details?: Record<string, any>;
|
|
206
|
-
}>;
|
|
207
|
-
validateCredentials?(credentials: Record<string, string>): Promise<boolean>;
|
|
208
|
-
validateSignature?<TPayload = any>(webhook: WebhookEvent<TPayload>): boolean;
|
|
209
|
-
}
|
package/src/types/tenant.ts
DELETED
package/src/types/user.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export const UserRole = {
|
|
2
|
-
OWNER: 'OWNER',
|
|
3
|
-
ADMIN: 'ADMIN',
|
|
4
|
-
MANAGER: 'MANAGER',
|
|
5
|
-
AGENT: 'AGENT',
|
|
6
|
-
VIEWER: 'VIEWER',
|
|
7
|
-
} as const;
|
|
8
|
-
|
|
9
|
-
export interface User {
|
|
10
|
-
id: string;
|
|
11
|
-
email: string;
|
|
12
|
-
roles: string[];
|
|
13
|
-
permissions: string[];
|
|
14
|
-
tenantId: string;
|
|
15
|
-
name: string;
|
|
16
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
interface CacheEntry {
|
|
2
|
-
value: unknown;
|
|
3
|
-
timestamp: number;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export class ContextCache {
|
|
7
|
-
private static instance: ContextCache;
|
|
8
|
-
private memoryCache = new Map<string, CacheEntry>();
|
|
9
|
-
private readonly TTL = 5 * 60 * 1000; // 5 minutes
|
|
10
|
-
private cleanupInterval: NodeJS.Timeout;
|
|
11
|
-
|
|
12
|
-
private constructor() {
|
|
13
|
-
// Cleanup expired entries every minute
|
|
14
|
-
this.cleanupInterval = setInterval(() => this.cleanup(), 60 * 1000);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static getInstance(): ContextCache {
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
19
|
-
if (!ContextCache.instance) {
|
|
20
|
-
ContextCache.instance = new ContextCache();
|
|
21
|
-
}
|
|
22
|
-
return ContextCache.instance;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async get<T>(key: string, factory: () => Promise<T> | T): Promise<T> {
|
|
26
|
-
const cached = this.memoryCache.get(key);
|
|
27
|
-
|
|
28
|
-
if (cached && Date.now() - cached.timestamp < this.TTL) {
|
|
29
|
-
return cached.value as T;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const value = await factory();
|
|
33
|
-
this.memoryCache.set(key, {value, timestamp: Date.now()});
|
|
34
|
-
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
set<T>(key: string, value: T): void {
|
|
39
|
-
this.memoryCache.set(key, {value, timestamp: Date.now()});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
delete(key: string): boolean {
|
|
43
|
-
return this.memoryCache.delete(key);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
clear(): void {
|
|
47
|
-
this.memoryCache.clear();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private cleanup(): void {
|
|
51
|
-
const now = Date.now();
|
|
52
|
-
const keysToDelete: string[] = [];
|
|
53
|
-
|
|
54
|
-
this.memoryCache.forEach((entry, key) => {
|
|
55
|
-
if (now - entry.timestamp > this.TTL) {
|
|
56
|
-
keysToDelete.push(key);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
keysToDelete.forEach((key) => this.memoryCache.delete(key));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
destroy(): void {
|
|
64
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
65
|
-
if (this.cleanupInterval) {
|
|
66
|
-
clearInterval(this.cleanupInterval);
|
|
67
|
-
}
|
|
68
|
-
this.clear();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import {ROLE_PERMISSIONS} from '../configs';
|
|
2
|
-
import type {User} from '../types';
|
|
3
|
-
|
|
4
|
-
export class PermissionCalculator {
|
|
5
|
-
static calculateUserPermissions(user: User): string[] {
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
7
|
-
if (!user || !Array.isArray(user.roles)) {
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Combine explicit permissions with role-based permissions
|
|
12
|
-
const explicitPermissions = Array.isArray(user.permissions)
|
|
13
|
-
? user.permissions
|
|
14
|
-
: [];
|
|
15
|
-
|
|
16
|
-
// Get all permissions from user's roles
|
|
17
|
-
const rolePermissions = user.roles.flatMap((role: string) => {
|
|
18
|
-
return ROLE_PERMISSIONS[role] ?? [];
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// Remove duplicates and return
|
|
22
|
-
const allPermissions = [...explicitPermissions, ...rolePermissions];
|
|
23
|
-
const uniquePermissions: string[] = [];
|
|
24
|
-
|
|
25
|
-
allPermissions.forEach((permission) => {
|
|
26
|
-
if (!uniquePermissions.includes(permission)) {
|
|
27
|
-
uniquePermissions.push(permission);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
return uniquePermissions;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static hasPermission(user: User, permission: string): boolean {
|
|
35
|
-
if (typeof permission !== 'string' || !permission.trim()) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
40
|
-
if (!user || typeof user !== 'object') {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!Array.isArray(user.roles)) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Check explicit permissions first
|
|
49
|
-
if (
|
|
50
|
-
Array.isArray(user.permissions) &&
|
|
51
|
-
user.permissions.includes(permission)
|
|
52
|
-
) {
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Check role-based permissions
|
|
57
|
-
return user.roles.some((role: string) => {
|
|
58
|
-
const rolePermissions = ROLE_PERMISSIONS[role] ?? [];
|
|
59
|
-
return rolePermissions.includes(permission);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "@hiliosai/typescript/base.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"incremental": true,
|
|
5
|
-
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json",
|
|
6
|
-
"paths": {
|
|
7
|
-
"@pkg/*": ["../*/dist"]
|
|
8
|
-
},
|
|
9
|
-
"baseUrl": "."
|
|
10
|
-
},
|
|
11
|
-
"include": ["*.ts", "src", "src/types/**/*"],
|
|
12
|
-
"exclude": ["node_modules"]
|
|
13
|
-
}
|