@alloy-framework/core 0.3.0 → 0.14.0

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/src/index.d.ts DELETED
@@ -1,345 +0,0 @@
1
- // Type definitions for @alloy/core
2
- // Provides IDE autocompletion and type checking for the Alloy Framework SDK
3
-
4
- import Joi from 'joi';
5
-
6
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7
- // App
8
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9
-
10
- export interface AlloyPlugin {
11
- name: string;
12
- onRequest?(req: any, res: any): void | Promise<void>;
13
- }
14
-
15
- export class AlloyApp {
16
- readonly native: any;
17
- readonly appDir: string;
18
- readonly router: AlloyRouter;
19
- readonly wsClients: Map<string, AlloyWebSocket>;
20
-
21
- constructor(meta: ImportMeta);
22
-
23
- /** 플러그인 등록 */
24
- use(plugin: AlloyPlugin): this;
25
-
26
- /** 등록된 플러그인 조회 */
27
- getPlugin(name: string): AlloyPlugin | undefined;
28
-
29
- /** WebSocket 이벤트 핸들러 등록 */
30
- ws(handlers: {
31
- onConnect?(socket: AlloyWebSocket): void | Promise<void>;
32
- onMessage?(socket: AlloyWebSocket, message: string): void | Promise<void>;
33
- onDisconnect?(socket: AlloyWebSocket): void | Promise<void>;
34
- }): void;
35
-
36
- /** 앱 부트스트래핑 (오버라이드용) */
37
- boot(): Promise<void>;
38
-
39
- /** 미들웨어 등록 훅 (오버라이드용) */
40
- middleware?(router: AlloyRouter): void;
41
-
42
- /** 앱 시작 (오버라이드용) */
43
- start(): Promise<void>;
44
- }
45
-
46
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
47
- // Config
48
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
49
-
50
- export class AlloyConfig {
51
- /** 설정 전체 로드 */
52
- static load(): Record<string, any>;
53
-
54
- /** 캐시 무효화 후 재로드 */
55
- static reload(): Record<string, any>;
56
-
57
- /** dot-notation 키로 설정값 조회 */
58
- static get<T = any>(key: string, defaultValue?: T): T;
59
-
60
- /** 데이터베이스 설정 조회 */
61
- static getDatabase(name: string): {
62
- name: string;
63
- driver: string;
64
- url: string;
65
- max_pool_size?: number;
66
- } | undefined;
67
- }
68
-
69
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
70
- // HTTP
71
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
72
-
73
- export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
74
-
75
- export class AlloyController {
76
- readonly req: any;
77
-
78
- /** 요청 URL */
79
- get url(): string;
80
- /** HTTP 메서드 */
81
- get method(): string;
82
- /** 클라이언트 IP */
83
- get ip(): string;
84
- /** URL 파라미터 */
85
- get params(): Record<string, string>;
86
- /** 쿼리 파라미터 */
87
- get query(): Record<string, string>;
88
- /** 요청 헤더 */
89
- get headers(): Record<string, string>;
90
- /** 파싱된 요청 바디 */
91
- get body(): any;
92
-
93
- /** 세션 데이터 설정 */
94
- setSession(key: string, value: string): void;
95
- /** 세션 데이터 조회 */
96
- getSession(key: string): string | null;
97
-
98
- /** 응답 상태 코드 설정 */
99
- status(code: number): this;
100
- /** 응답 헤더 설정 */
101
- setHeader(name: string, value: string): this;
102
- /** 특정 헤더 조회 */
103
- header(name: string): string | undefined;
104
-
105
- /** JSON 응답 */
106
- json(data: any): void;
107
- /** HTML 응답 */
108
- html(content: string): void;
109
- /** Tera 템플릿 렌더링 */
110
- render(template: string, context?: Record<string, any>): void;
111
- /** 리다이렉트 */
112
- redirect(url: string, statusCode?: number): void;
113
-
114
- /** 표준 성공 응답 */
115
- success(data?: any, message?: string): void;
116
- /** 표준 에러 응답 */
117
- error(code: string, message?: string, statusCode?: number): void;
118
- }
119
-
120
- /** Controller 클래스를 라우트 디스크립터로 변환 */
121
- export function createController(ControllerClass: typeof AlloyController): any;
122
-
123
- export class AlloyRouter {
124
- /** GET 라우트 등록 */
125
- get(path: string, ...args: any[]): void;
126
- /** POST 라우트 등록 */
127
- post(path: string, ...args: any[]): void;
128
- /** PUT 라우트 등록 */
129
- put(path: string, ...args: any[]): void;
130
- /** DELETE 라우트 등록 */
131
- delete(path: string, ...args: any[]): void;
132
- /** 미들웨어 등록 */
133
- use(...middleware: Function[]): void;
134
- /** 라우트 그룹 */
135
- group(prefix: string, callback: (router: AlloyRouter) => void): void;
136
- }
137
-
138
- export class Validator {
139
- static validate<T = any>(schema: Joi.Schema, data: any, partial?: boolean): T;
140
- }
141
-
142
- export { Joi };
143
-
144
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
145
- // Data
146
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
147
-
148
- export class AlloyModel {
149
- /** 스키마 정의 (서브클래스에서 오버라이드) */
150
- static schema?: any;
151
- /** 스토어 이름 */
152
- static store?: string;
153
- /** 테이블/컬렉션 이름 */
154
- static table?: string;
155
-
156
- /** SELECT 필드 지정 */
157
- select(...fields: string[]): this;
158
- /** WHERE 조건 */
159
- where(field: string, op: string, value: any): this;
160
- /** OR WHERE 조건 */
161
- orWhere(field: string, op: string, value: any): this;
162
- /** WHERE IN 조건 */
163
- whereIn(field: string, values: any[]): this;
164
- /** WHERE NULL 조건 */
165
- whereNull(field: string): this;
166
- /** WHERE NOT NULL 조건 */
167
- whereNotNull(field: string): this;
168
- /** 결과 행 수 제한 */
169
- limit(n: number): this;
170
- /** 시작 오프셋 */
171
- offset(n: number): this;
172
- /** 정렬 */
173
- orderBy(field: string, direction?: 'asc' | 'desc'): this;
174
- /** GROUP BY */
175
- groupBy(field: string): this;
176
-
177
- /** 조건에 맞는 행 조회 */
178
- get(): Promise<any[]>;
179
- /** 첫 번째 행 조회 */
180
- first(): Promise<any | null>;
181
- /** 데이터 삽입 */
182
- save(data: Record<string, any>): Promise<any>;
183
- /** 데이터 수정 */
184
- update(data: Record<string, any>): Promise<any>;
185
- /** 데이터 삭제 */
186
- delete(): Promise<any>;
187
-
188
- /** 행 수 카운트 */
189
- count(): Promise<number>;
190
- /** SUM 집계 */
191
- sum(field: string): Promise<number>;
192
- /** AVG 집계 */
193
- avg(field: string): Promise<number>;
194
- /** MIN 집계 */
195
- min(field: string): Promise<number>;
196
- /** MAX 집계 */
197
- max(field: string): Promise<number>;
198
-
199
- /** Raw SQL 실행 */
200
- query(sql: string, params?: any[]): Promise<any[]>;
201
- /** 스토어드 프로시저 호출 */
202
- callProcedure(name: string, params?: any[]): Promise<any[]>;
203
- }
204
-
205
- /** AlloyModel 별칭 */
206
- export const AlloyMariaModel: typeof AlloyModel;
207
-
208
- export class AlloyMongoModel extends AlloyModel {
209
- /** MongoDB find */
210
- find(filter?: object, options?: { projection?: object; sort?: object; limit?: number; skip?: number }): Promise<any[]>;
211
- /** MongoDB findOne */
212
- findOne(filter?: object, options?: { projection?: object }): Promise<any | null>;
213
- /** 단일 문서 삽입 */
214
- insertOne(doc: Record<string, any>): Promise<{ ok: boolean; n: number }>;
215
- /** 다중 문서 삽입 */
216
- insertMany(docs: Record<string, any>[], options?: { ordered?: boolean }): Promise<{ ok: boolean; n: number }>;
217
- /** 단일 문서 수정 */
218
- updateOne(filter: object, update: object, options?: { upsert?: boolean; arrayFilters?: any[]; hint?: object; collation?: object }): Promise<{ ok: boolean; nModified: number; upserted?: any }>;
219
- /** 다중 문서 수정 */
220
- updateMany(filter: object, update: object, options?: { upsert?: boolean; arrayFilters?: any[] }): Promise<{ ok: boolean; nModified: number }>;
221
- /** 단일 문서 삭제 */
222
- deleteOne(filter: object): Promise<{ ok: boolean; n: number }>;
223
- /** 다중 문서 삭제 */
224
- deleteMany(filter: object): Promise<{ ok: boolean; n: number }>;
225
- /** Aggregation Pipeline */
226
- aggregate(pipeline: object[]): Promise<any[]>;
227
- }
228
-
229
- export class AlloyRedisModel {
230
- /** String SET */
231
- set(key: string, value: string, ttl?: number): Promise<void>;
232
- /** String GET */
233
- get(key: string): Promise<string | null>;
234
- /** DEL */
235
- del(key: string): Promise<void>;
236
- /** EXISTS */
237
- exists(key: string): Promise<boolean>;
238
-
239
- /** Hash SET */
240
- hset(key: string, field: string, value: string): Promise<void>;
241
- /** Hash GET */
242
- hget(key: string, field: string): Promise<string | null>;
243
- /** Hash DEL */
244
- hdel(key: string, field: string): Promise<void>;
245
- /** Hash GETALL */
246
- hgetall(key: string): Promise<Record<string, string>>;
247
-
248
- /** List LPUSH */
249
- lpush(key: string, value: string): Promise<void>;
250
- /** List RPUSH */
251
- rpush(key: string, value: string): Promise<void>;
252
- /** List LRANGE */
253
- lrange(key: string, start: number, stop: number): Promise<string[]>;
254
-
255
- /** Raw Redis command */
256
- command(cmd: string, args?: string[]): Promise<any>;
257
- }
258
-
259
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
260
- // Service
261
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
262
-
263
- export class AlloyService {
264
- /** 에코 테스트 */
265
- echo(msg: string): string;
266
- /** CPU 집약적 작업 실행 */
267
- runTask(name: string, difficulty: number): Promise<string>;
268
- /** 병렬 실행 */
269
- runParallel<T>(items: T[], fn?: (item: T, index: number) => Promise<any>, options?: { settled?: boolean }): Promise<any[]>;
270
-
271
- /** 캐시 저장 */
272
- setCache(key: string, value: string, ttlSeconds: number): Promise<void>;
273
- /** 캐시 조회 */
274
- getCache(key: string): Promise<string | null>;
275
- /** 캐시 래퍼 (miss 시 fetcher 호출) */
276
- withCache<T>(key: string, ttlSeconds: number, fetcher: () => Promise<T>): Promise<T>;
277
-
278
- /** 네트워크 분산 락 획득 */
279
- acquireNetworkLock(resource: string, ttlMs?: number): Promise<boolean>;
280
- /** 네트워크 분산 락 해제 */
281
- releaseNetworkLock(resource: string): Promise<void>;
282
- /** 로컬 프로세스 락 획득 */
283
- acquireLocalLock(resource: string, ttlMs?: number): boolean;
284
- /** 로컬 프로세스 락 해제 */
285
- releaseLocalLock(resource: string): void;
286
- }
287
-
288
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
289
- // Security
290
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
291
-
292
- export class AlloyCrypto {
293
- uuid(): string;
294
- md5(input: string): string;
295
- sha256(input: string): string;
296
- encryptAes(key: string, plainText: string): string;
297
- decryptAes(key: string, encryptedBase64: string): string;
298
- encryptCustom(key: string, plainText: string): string;
299
- decryptCustom(key: string, encryptedBase64: string): string;
300
- }
301
-
302
- export class AlloySession {
303
- static plugin(options?: { cookieName?: string; ttl?: number }): AlloyPlugin;
304
- }
305
-
306
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
307
- // WebSocket
308
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
309
-
310
- export class AlloyWebSocket {
311
- readonly id: string;
312
- readonly connectionType: string;
313
- readonly clientIp: string;
314
- readonly connectedAt: string;
315
- readonly server: string | null;
316
- readonly cookies: Record<string, string>;
317
-
318
- send(msg: string | object): void;
319
- broadcast(msg: string | object): void;
320
- sendTo(targetId: string, msg: string | object): void;
321
- sendToMany(ids: string[], msg: string | object): void;
322
- getOnlineClients(): string[];
323
- getOnlineClientsDetail(): Array<{ id: string; connectionType: string }>;
324
- getOnlineCount(): number;
325
- disconnectClient(targetId: string): boolean;
326
- }
327
-
328
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
329
- // Util
330
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
331
-
332
- export class AlloyError extends Error {
333
- readonly code: string;
334
- readonly statusCode: number;
335
- constructor(code: string, message?: string, statusCode?: number);
336
- }
337
-
338
- export function paginate(page?: number, size?: number): { offset: number; limit: number };
339
- export function buildResponse(items: any[], total: number, page: number, size: number): {
340
- items: any[];
341
- total: number;
342
- page: number;
343
- size: number;
344
- totalPages: number;
345
- };
package/src/index.js DELETED
@@ -1,43 +0,0 @@
1
- /**
2
- * 🚀 @alloy/core — Alloy Framework SDK
3
- *
4
- * Rust N-API 네이티브 엔진(@alloy/rust) 위에 구축된 고성능 Node.js 프레임워크 SDK입니다.
5
- *
6
- * @example
7
- * import { AlloyApp, AlloyModel, AlloyService, AlloyCrypto } from '@alloy-framework/core';
8
- */
9
-
10
- // ── Config (설정값 접근) ──
11
- export { AlloyConfig } from './config/AlloyConfig.js';
12
-
13
- // ── App (부트스트래퍼) ──
14
- export { AlloyApp } from './app/AlloyApp.js';
15
-
16
- // ── HTTP (컨트롤러/라우터/검증) ──
17
- export { AlloyController, createController } from './http/AlloyController.js';
18
- export { AlloyRouter } from './http/AlloyRouter.js';
19
- export { Validator, Joi } from './http/Validator.js';
20
-
21
- // ── Data (모델) ──
22
- export { AlloyModel, AlloyMariaModel } from './data/AlloyModel.js';
23
- export { AlloyMongoModel } from './data/AlloyMongoModel.js';
24
- export { AlloyRedisModel } from './data/AlloyRedisModel.js';
25
-
26
- // ── WebSocket ──
27
- export { AlloyWebSocket } from './ws/AlloyWebSocket.js';
28
-
29
- // ── Service ──
30
- export { AlloyService } from './service/AlloyService.js';
31
-
32
- // ── Security ──
33
- export { AlloyCrypto } from './security/AlloyCrypto.js';
34
- export { AlloySession } from './security/AlloySession.js';
35
-
36
- // ── Util ──
37
- export { AlloyError } from './util/AlloyError.js';
38
- export { paginate, buildResponse } from './util/Pagination.js';
39
-
40
- // ── Native re-export (직접 접근 필요 시) ──
41
- import native from '@alloy-framework/rust';
42
- export const { NativeCache, NativeLock } = native;
43
- export default native;
@@ -1,96 +0,0 @@
1
- import native from '@alloy-framework/rust';
2
-
3
- /**
4
- * 🔐 Alloy 암호화 래퍼
5
- * Rust N-API의 NativeCrypto를 직관적인 JS API로 제공합니다.
6
- *
7
- * @example
8
- * const crypto = new AlloyCrypto();
9
- * const uuid = crypto.uuid();
10
- * const hash = crypto.sha256('hello');
11
- * const encrypted = crypto.encryptAes('secret-key', 'plain text');
12
- */
13
- export class AlloyCrypto {
14
- constructor() {
15
- /** @type {import('@alloy/rust').NativeCrypto} 네이티브 암호화 인스턴스 */
16
- this._native = new native.NativeCrypto();
17
- }
18
-
19
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
20
- // 🆔 UUID
21
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22
-
23
- /**
24
- * UUID v4 생성
25
- * @returns {string} UUID 문자열
26
- */
27
- uuid() {
28
- return this._native.uuid();
29
- }
30
-
31
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
- // 🔍 해싱
33
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
34
-
35
- /**
36
- * MD5 해시 (hex 출력)
37
- * @param {string} input - 입력 문자열
38
- * @returns {string} hex 해시
39
- */
40
- md5(input) {
41
- return this._native.md5(input);
42
- }
43
-
44
- /**
45
- * SHA-256 해시 (hex 출력)
46
- * @param {string} input - 입력 문자열
47
- * @returns {string} hex 해시
48
- */
49
- sha256(input) {
50
- return this._native.sha256(input);
51
- }
52
-
53
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
- // 🔒 AES-256-GCM 암호화
55
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
56
-
57
- /**
58
- * AES-256-GCM 암호화 (표준)
59
- * @param {string} key - 암호화 키 (SHA256으로 32바이트 변환)
60
- * @param {string} plainText - 평문
61
- * @returns {string} Base64 인코딩된 암호문
62
- */
63
- encryptAes(key, plainText) {
64
- return this._native.encryptAes(key, plainText);
65
- }
66
-
67
- /**
68
- * AES-256-GCM 복호화 (표준)
69
- * @param {string} key - 복호화 키
70
- * @param {string} encryptedBase64 - Base64 암호문
71
- * @returns {string} 평문
72
- */
73
- decryptAes(key, encryptedBase64) {
74
- return this._native.decryptAes(key, encryptedBase64);
75
- }
76
-
77
- /**
78
- * AES-256-GCM + 비트 셔플링 암호화 (커스텀 난독화)
79
- * @param {string} key - 암호화 키
80
- * @param {string} plainText - 평문
81
- * @returns {string} 난독화된 Base64 암호문
82
- */
83
- encryptCustom(key, plainText) {
84
- return this._native.encryptCustom(key, plainText);
85
- }
86
-
87
- /**
88
- * AES-256-GCM + 비트 셔플링 복호화 (커스텀 난독화)
89
- * @param {string} key - 복호화 키
90
- * @param {string} encryptedBase64 - 난독화된 Base64 암호문
91
- * @returns {string} 평문
92
- */
93
- decryptCustom(key, encryptedBase64) {
94
- return this._native.decryptCustom(key, encryptedBase64);
95
- }
96
- }
@@ -1,81 +0,0 @@
1
- import native from '@alloy-framework/rust';
2
-
3
- /**
4
- * 🔒 Alloy 세션 미들웨어
5
- * Rust N-API의 sessionRead/sessionWrite를 활용한 Redis 세션 관리입니다.
6
- *
7
- * 요청마다 쿠키에서 세션 ID를 추출하고, Redis에서 세션 데이터를 복원합니다.
8
- * 응답 시 변경된 세션을 Redis에 자동 저장합니다.
9
- *
10
- * @example
11
- * // AlloyApp 플러그인으로 등록
12
- * app.use(AlloySession.plugin({ cookieName: 'alloy_sid', ttl: 3600 }));
13
- */
14
- export class AlloySession {
15
- /**
16
- * 세션 플러그인 생성 (AlloyApp.use() 호환)
17
- * @param {object} [options] - 세션 옵션
18
- * @param {string} [options.cookieName='alloy_sid'] - 쿠키 이름
19
- * @param {number} [options.ttl=3600] - TTL (초)
20
- * @returns {object} 플러그인 객체 { name, onRequest }
21
- */
22
- static plugin(options = {}) {
23
- const cookieName = options.cookieName || 'alloy_sid';
24
- const ttl = options.ttl || 3600;
25
-
26
- return {
27
- name: 'session',
28
-
29
- /**
30
- * 요청 전처리 — 세션 복원
31
- * @param {object} req - 요청 객체
32
- * @param {object} res - 응답 객체
33
- */
34
- async onRequest(req, res) {
35
- // 쿠키에서 세션 ID 추출
36
- const cookies = AlloySession._parseCookies(req.headers?.cookie || '');
37
- const sessionId = cookies[cookieName];
38
-
39
- /** @type {object} 세션 데이터 */
40
- req.session = {};
41
- /** @type {string|null} 세션 ID */
42
- req.sessionId = sessionId || null;
43
-
44
- if (sessionId) {
45
- try {
46
- // Rust N-API를 통해 Redis에서 세션 읽기
47
- const json = await native.sessionRead(sessionId);
48
- if (json) {
49
- req.session = JSON.parse(json);
50
- }
51
- } catch (e) {
52
- console.warn('⚠️ [AlloySession] 세션 읽기 실패:', e.message);
53
- }
54
- }
55
- },
56
-
57
- // 💡 세션 Write-Back은 Rust handler.rs에서 자동 처리됩니다.
58
- // AlloyController.send()가 completer.done({ session }) 으로 변경된 세션을
59
- // Rust에 전달하면, Rust가 Redis에 자동 저장합니다.
60
- // JS 측에서 별도의 onResponse 훅이 필요하지 않습니다.
61
- };
62
- }
63
-
64
- /**
65
- * 쿠키 문자열 파싱
66
- * @param {string} cookieStr - raw Cookie 헤더 문자열
67
- * @returns {object} 키-값 쌍
68
- * @private
69
- */
70
- static _parseCookies(cookieStr) {
71
- const cookies = {};
72
- for (const pair of cookieStr.split(';')) {
73
- const trimmed = pair.trim();
74
- const [key, ...rest] = trimmed.split('=');
75
- if (key) {
76
- cookies[key.trim()] = rest.join('=').trim(); // 값에 = 포함될 수 있음
77
- }
78
- }
79
- return cookies;
80
- }
81
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * 🔐 보안 모듈 통합 export
3
- */
4
- export { AlloyCrypto } from './AlloyCrypto.js';
5
- export { AlloySession } from './AlloySession.js';