@k-msg/channel 0.1.0 → 0.1.2

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.
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Phone Number Verification System
3
+ * 발신번호 인증 및 검증 시스템
4
+ */
5
+ import { EventEmitter } from "events";
6
+ export interface PhoneVerificationRequest {
7
+ id: string;
8
+ senderNumberId: string;
9
+ phoneNumber: string;
10
+ verificationType: VerificationType;
11
+ verificationCode: string;
12
+ status: PhoneVerificationStatus;
13
+ attempts: VerificationAttempt[];
14
+ expiresAt: Date;
15
+ createdAt: Date;
16
+ completedAt?: Date;
17
+ metadata: {
18
+ userAgent?: string;
19
+ ipAddress?: string;
20
+ deviceId?: string;
21
+ smsProvider?: string;
22
+ callProvider?: string;
23
+ };
24
+ }
25
+ export interface VerificationAttempt {
26
+ attemptNumber: number;
27
+ attemptedAt: Date;
28
+ method: VerificationMethod;
29
+ status: "sent" | "delivered" | "failed" | "verified" | "expired";
30
+ failureReason?: string;
31
+ responseTime?: number;
32
+ }
33
+ export declare enum VerificationType {
34
+ SMS = "sms",
35
+ VOICE_CALL = "voice_call",
36
+ HYBRID = "hybrid"
37
+ }
38
+ export declare enum VerificationMethod {
39
+ SMS = "sms",
40
+ VOICE_CALL = "voice_call",
41
+ MISSED_CALL = "missed_call"
42
+ }
43
+ export declare enum PhoneVerificationStatus {
44
+ PENDING = "pending",
45
+ CODE_SENT = "code_sent",
46
+ VERIFIED = "verified",
47
+ FAILED = "failed",
48
+ EXPIRED = "expired",
49
+ BLOCKED = "blocked"
50
+ }
51
+ export interface NumberVerifierOptions {
52
+ codeLength: number;
53
+ codeExpiryMinutes: number;
54
+ maxAttempts: number;
55
+ maxDailyAttempts: number;
56
+ smsTemplate: string;
57
+ voiceTemplate: string;
58
+ rateLimitMinutes: number;
59
+ enableVoiceFallback: boolean;
60
+ enableMissedCallVerification: boolean;
61
+ blockedNumbers: string[];
62
+ allowedCountries: string[];
63
+ smsProvider?: SMSProvider;
64
+ voiceProvider?: VoiceProvider;
65
+ }
66
+ export interface SMSProvider {
67
+ id: string;
68
+ name: string;
69
+ sendSMS(phoneNumber: string, message: string, options?: any): Promise<SMSResult>;
70
+ getDeliveryStatus?(messageId: string): Promise<DeliveryStatus>;
71
+ }
72
+ export interface VoiceProvider {
73
+ id: string;
74
+ name: string;
75
+ makeCall(phoneNumber: string, message: string, options?: any): Promise<VoiceResult>;
76
+ makeMissedCall?(phoneNumber: string, options?: any): Promise<MissedCallResult>;
77
+ }
78
+ export interface SMSResult {
79
+ messageId: string;
80
+ status: "sent" | "failed";
81
+ cost?: number;
82
+ error?: string;
83
+ }
84
+ export interface VoiceResult {
85
+ callId: string;
86
+ status: "initiated" | "answered" | "failed" | "busy" | "no_answer";
87
+ duration?: number;
88
+ cost?: number;
89
+ error?: string;
90
+ }
91
+ export interface MissedCallResult {
92
+ callId: string;
93
+ status: "initiated" | "completed" | "failed";
94
+ missedCallNumber?: string;
95
+ error?: string;
96
+ }
97
+ export interface DeliveryStatus {
98
+ messageId: string;
99
+ status: "pending" | "delivered" | "failed" | "expired";
100
+ deliveredAt?: Date;
101
+ failureReason?: string;
102
+ }
103
+ export interface PhoneNumberInfo {
104
+ phoneNumber: string;
105
+ countryCode: string;
106
+ nationalNumber: string;
107
+ carrier?: string;
108
+ lineType?: "mobile" | "landline" | "voip" | "unknown";
109
+ isValid: boolean;
110
+ isPossible: boolean;
111
+ region?: string;
112
+ }
113
+ export declare class NumberVerifier extends EventEmitter {
114
+ private options;
115
+ private verificationRequests;
116
+ private phoneNumberCache;
117
+ private rateLimitTracker;
118
+ private dailyAttemptTracker;
119
+ private blockedNumbers;
120
+ private defaultOptions;
121
+ constructor(options?: Partial<NumberVerifierOptions>);
122
+ /**
123
+ * Start phone number verification process
124
+ */
125
+ startVerification(senderNumberId: string, phoneNumber: string, verificationType?: VerificationType, metadata?: PhoneVerificationRequest["metadata"]): Promise<PhoneVerificationRequest>;
126
+ /**
127
+ * Verify the provided code
128
+ */
129
+ verifyCode(requestId: string, providedCode: string): Promise<{
130
+ success: boolean;
131
+ status: PhoneVerificationStatus;
132
+ message: string;
133
+ }>;
134
+ /**
135
+ * Resend verification code
136
+ */
137
+ resendCode(requestId: string, method?: VerificationMethod): Promise<PhoneVerificationRequest>;
138
+ /**
139
+ * Get verification request status
140
+ */
141
+ getVerificationStatus(requestId: string): PhoneVerificationRequest | null;
142
+ /**
143
+ * Cancel verification request
144
+ */
145
+ cancelVerification(requestId: string): Promise<boolean>;
146
+ /**
147
+ * Block a phone number from verification
148
+ */
149
+ blockPhoneNumber(phoneNumber: string, reason?: string): void;
150
+ /**
151
+ * Unblock a phone number
152
+ */
153
+ unblockPhoneNumber(phoneNumber: string): void;
154
+ /**
155
+ * Get verification statistics
156
+ */
157
+ getVerificationStats(): {
158
+ total: number;
159
+ byStatus: Record<string, number>;
160
+ byMethod: Record<string, number>;
161
+ successRate: number;
162
+ averageCompletionTime: number;
163
+ };
164
+ /**
165
+ * Clean up expired verification requests
166
+ */
167
+ cleanup(): number;
168
+ private sendVerificationCode;
169
+ private sendVerificationByMethod;
170
+ private sendSMS;
171
+ private sendVoiceCall;
172
+ private sendMissedCall;
173
+ private getPhoneNumberInfo;
174
+ private parseKoreanPhoneNumber;
175
+ private isNumberBlocked;
176
+ private isRateLimited;
177
+ private isDailyLimitExceeded;
178
+ private updateRateLimit;
179
+ private updateDailyAttempts;
180
+ private validateCode;
181
+ private generateVerificationCode;
182
+ private generateRequestId;
183
+ }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@k-msg/channel",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
+ "packageManager": "bun@1.3.8",
4
5
  "description": "AlimTalk channel and sender number management",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
@@ -17,19 +18,23 @@
17
18
  "access": "public"
18
19
  },
19
20
  "scripts": {
20
- "build": "tsup",
21
+ "build": "bun run build:esm && bun run build:cjs && bun run build:types",
22
+ "build:esm": "bun build ./src/index.ts --outdir ./dist --format esm --minify --sourcemap --entry-naming '[name].mjs' --external 'bun:test'",
23
+ "build:cjs": "bun build ./src/index.ts --outdir ./dist --format cjs --minify --sourcemap --entry-naming '[name].js' --external 'bun:test'",
24
+ "build:types": "tsc",
21
25
  "dev": "tsc --watch",
22
26
  "test": "bun test",
23
- "clean": "rm -rf dist"
27
+ "clean": "rm -rf dist",
28
+ "pack": "bun pm pack",
29
+ "publish": "bun publish --access public"
24
30
  },
25
31
  "dependencies": {
26
- "zod": "catalog:"
32
+ "zod": "^4.0.14"
27
33
  },
28
34
  "devDependencies": {
29
- "typescript": "catalog:",
30
- "@types/bun": "catalog:",
31
- "@types/node": "catalog:",
32
- "tsup": "^8.5.0"
35
+ "typescript": "^5.7.2",
36
+ "@types/bun": "latest",
37
+ "@types/node": "^22.0.0"
33
38
  },
34
39
  "keywords": [
35
40
  "alimtalk",
@@ -44,12 +49,12 @@
44
49
  ],
45
50
  "repository": {
46
51
  "type": "git",
47
- "url": "git+https://github.com/k-otp/k-message.git"
52
+ "url": "git+https://github.com/k-otp/k-msg.git"
48
53
  },
49
- "homepage": "https://github.com/k-otp/k-message",
54
+ "homepage": "https://github.com/k-otp/k-msg",
50
55
  "bugs": {
51
- "url": "https://github.com/k-otp/k-message/issues"
56
+ "url": "https://github.com/k-otp/k-msg/issues"
52
57
  },
53
58
  "author": "imjlk",
54
59
  "license": "MIT"
55
- }
60
+ }