semaphoreco 1.0.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/README.md +435 -0
- package/dist/index.cjs +520 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +507 -0
- package/dist/index.d.ts +507 -0
- package/dist/index.js +508 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
// src/errors/errors.ts
|
|
2
|
+
var SemaphoreError = class _SemaphoreError extends Error {
|
|
3
|
+
statusCode;
|
|
4
|
+
code;
|
|
5
|
+
constructor(message, statusCode, code) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.statusCode = statusCode;
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = "SemaphoreError";
|
|
10
|
+
Object.setPrototypeOf(this, _SemaphoreError.prototype);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var AuthenticationError = class _AuthenticationError extends SemaphoreError {
|
|
14
|
+
constructor(message = "Invalid or missing API key") {
|
|
15
|
+
super(message, 401, "authentication_error");
|
|
16
|
+
this.name = "AuthenticationError";
|
|
17
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var RateLimitError = class _RateLimitError extends SemaphoreError {
|
|
21
|
+
retryAfter;
|
|
22
|
+
constructor(message = "Rate limit exceeded", retryAfter) {
|
|
23
|
+
super(message, 429, "rate_limit_error");
|
|
24
|
+
this.retryAfter = retryAfter;
|
|
25
|
+
this.name = "RateLimitError";
|
|
26
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var ValidationError = class _ValidationError extends SemaphoreError {
|
|
30
|
+
field;
|
|
31
|
+
constructor(message, field) {
|
|
32
|
+
super(message, 400, "validation_error");
|
|
33
|
+
this.field = field;
|
|
34
|
+
this.name = "ValidationError";
|
|
35
|
+
Object.setPrototypeOf(this, _ValidationError.prototype);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var NetworkError = class _NetworkError extends SemaphoreError {
|
|
39
|
+
request;
|
|
40
|
+
cause;
|
|
41
|
+
constructor(message, request, cause) {
|
|
42
|
+
super(message, void 0, "network_error");
|
|
43
|
+
this.request = request;
|
|
44
|
+
this.cause = cause;
|
|
45
|
+
this.name = "NetworkError";
|
|
46
|
+
Object.setPrototypeOf(this, _NetworkError.prototype);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var TimeoutError = class _TimeoutError extends SemaphoreError {
|
|
50
|
+
request;
|
|
51
|
+
timeoutMs;
|
|
52
|
+
constructor(message, request, timeoutMs) {
|
|
53
|
+
super(message, void 0, "timeout_error");
|
|
54
|
+
this.request = request;
|
|
55
|
+
this.timeoutMs = timeoutMs;
|
|
56
|
+
this.name = "TimeoutError";
|
|
57
|
+
Object.setPrototypeOf(this, _TimeoutError.prototype);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// src/http/client.ts
|
|
62
|
+
function parseRetryAfter(header, defaultMs = 1e3) {
|
|
63
|
+
if (!header) {
|
|
64
|
+
return defaultMs;
|
|
65
|
+
}
|
|
66
|
+
const seconds = parseFloat(header);
|
|
67
|
+
if (!isNaN(seconds) && seconds >= 0) {
|
|
68
|
+
return Math.round(seconds * 1e3);
|
|
69
|
+
}
|
|
70
|
+
const date = new Date(header);
|
|
71
|
+
if (!isNaN(date.getTime())) {
|
|
72
|
+
const delayMs = date.getTime() - Date.now();
|
|
73
|
+
return Math.max(0, delayMs);
|
|
74
|
+
}
|
|
75
|
+
return defaultMs;
|
|
76
|
+
}
|
|
77
|
+
function sanitizeUrl(url) {
|
|
78
|
+
try {
|
|
79
|
+
const urlObj = new URL(url);
|
|
80
|
+
urlObj.searchParams.delete("apikey");
|
|
81
|
+
return urlObj.toString();
|
|
82
|
+
} catch {
|
|
83
|
+
return url;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
var HttpClient = class {
|
|
87
|
+
baseUrl;
|
|
88
|
+
apiKey;
|
|
89
|
+
timeout;
|
|
90
|
+
maxRetries;
|
|
91
|
+
onRetry;
|
|
92
|
+
constructor(config) {
|
|
93
|
+
this.baseUrl = config.baseUrl;
|
|
94
|
+
this.apiKey = config.apiKey;
|
|
95
|
+
this.timeout = config.timeout;
|
|
96
|
+
this.maxRetries = config.maxRetries ?? 3;
|
|
97
|
+
this.onRetry = config.onRetry;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Map HTTP response to appropriate error class.
|
|
101
|
+
*
|
|
102
|
+
* @param response - The HTTP response
|
|
103
|
+
* @param bodyText - Response body text (first 500 chars)
|
|
104
|
+
* @returns Appropriate error instance
|
|
105
|
+
*/
|
|
106
|
+
mapResponseToError(response, bodyText) {
|
|
107
|
+
const status = response.status;
|
|
108
|
+
const truncatedBody = bodyText.length > 500 ? bodyText.slice(0, 500) + "..." : bodyText;
|
|
109
|
+
const message = `HTTP ${status}: ${truncatedBody || response.statusText}`;
|
|
110
|
+
if (status === 401) {
|
|
111
|
+
return new AuthenticationError(message);
|
|
112
|
+
}
|
|
113
|
+
if (status === 429) {
|
|
114
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
115
|
+
const retryAfterSeconds = retryAfter ? parseRetryAfter(retryAfter) / 1e3 : void 0;
|
|
116
|
+
return new RateLimitError(message, retryAfterSeconds);
|
|
117
|
+
}
|
|
118
|
+
if (status >= 400 && status < 500) {
|
|
119
|
+
return new ValidationError(message);
|
|
120
|
+
}
|
|
121
|
+
return new SemaphoreError(message, status);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Make an HTTP request to the Semaphore API.
|
|
125
|
+
*
|
|
126
|
+
* @param path - API path (e.g., "/messages")
|
|
127
|
+
* @param options - Request and retry options
|
|
128
|
+
* @returns Parsed JSON response
|
|
129
|
+
* @throws {NetworkError} On connection failures
|
|
130
|
+
* @throws {TimeoutError} On request timeout
|
|
131
|
+
* @throws {AuthenticationError} On 401 responses
|
|
132
|
+
* @throws {RateLimitError} On 429 responses (after retries exhausted)
|
|
133
|
+
* @throws {ValidationError} On 4xx responses
|
|
134
|
+
* @throws {SemaphoreError} On 5xx responses
|
|
135
|
+
*/
|
|
136
|
+
async request(path, options = {}) {
|
|
137
|
+
const {
|
|
138
|
+
method = "GET",
|
|
139
|
+
body,
|
|
140
|
+
timeout = this.timeout,
|
|
141
|
+
headers = {},
|
|
142
|
+
maxRetries = this.maxRetries,
|
|
143
|
+
onRetry = this.onRetry
|
|
144
|
+
} = options;
|
|
145
|
+
const url = `${this.baseUrl}${path}`;
|
|
146
|
+
const sanitizedUrl = sanitizeUrl(url);
|
|
147
|
+
const requestContext = {
|
|
148
|
+
url: sanitizedUrl,
|
|
149
|
+
method
|
|
150
|
+
};
|
|
151
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
152
|
+
try {
|
|
153
|
+
const response = await fetch(url, {
|
|
154
|
+
method,
|
|
155
|
+
headers: {
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
158
|
+
...headers
|
|
159
|
+
},
|
|
160
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
161
|
+
signal: AbortSignal.timeout(timeout)
|
|
162
|
+
});
|
|
163
|
+
if (!response.ok) {
|
|
164
|
+
let bodyText = "";
|
|
165
|
+
try {
|
|
166
|
+
bodyText = await response.text();
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
if (response.status === 429 && attempt < maxRetries) {
|
|
170
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
171
|
+
const delayMs = parseRetryAfter(retryAfter);
|
|
172
|
+
onRetry?.(attempt, delayMs);
|
|
173
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
throw this.mapResponseToError(response, bodyText);
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
return await response.json();
|
|
180
|
+
} catch (parseError) {
|
|
181
|
+
throw new SemaphoreError(
|
|
182
|
+
`Failed to parse response JSON: ${parseError instanceof Error ? parseError.message : "Unknown error"}`,
|
|
183
|
+
response.status
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
if (error instanceof SemaphoreError) {
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
if (error instanceof Error) {
|
|
191
|
+
if (error.name === "TimeoutError") {
|
|
192
|
+
throw new TimeoutError(
|
|
193
|
+
`Request timed out after ${timeout}ms`,
|
|
194
|
+
requestContext,
|
|
195
|
+
timeout
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
throw new NetworkError(
|
|
199
|
+
`Network error: ${error.message}`,
|
|
200
|
+
requestContext,
|
|
201
|
+
error
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
throw new RateLimitError("Rate limit exceeded after max retries");
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// src/resources/messages.ts
|
|
212
|
+
var MessagesResource = class {
|
|
213
|
+
/**
|
|
214
|
+
* Create a new MessagesResource instance.
|
|
215
|
+
*
|
|
216
|
+
* @param http - HttpClient instance for making API requests
|
|
217
|
+
*/
|
|
218
|
+
constructor(http) {
|
|
219
|
+
this.http = http;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Send an SMS message to one or more recipients.
|
|
223
|
+
*
|
|
224
|
+
* When sending to multiple recipients (up to 1000), pass an array of numbers.
|
|
225
|
+
* The API will return an array of responses, one for each recipient.
|
|
226
|
+
*
|
|
227
|
+
* @param params - Message parameters including recipient(s), message content, and sender name
|
|
228
|
+
* @returns Single response for one recipient, array of responses for multiple recipients
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* // Send to single recipient
|
|
233
|
+
* const response = await client.messages.send({
|
|
234
|
+
* number: '09171234567',
|
|
235
|
+
* message: 'Hello!',
|
|
236
|
+
* sendername: 'SEMAPHORE',
|
|
237
|
+
* });
|
|
238
|
+
* console.log(response.message_id);
|
|
239
|
+
*
|
|
240
|
+
* // Send to multiple recipients (bulk)
|
|
241
|
+
* const responses = await client.messages.send({
|
|
242
|
+
* number: ['09171234567', '09181234567'],
|
|
243
|
+
* message: 'Hello everyone!',
|
|
244
|
+
* sendername: 'SEMAPHORE',
|
|
245
|
+
* });
|
|
246
|
+
* console.log(responses.length); // 2
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
async send(params) {
|
|
250
|
+
const number = Array.isArray(params.number) ? params.number.join(",") : params.number;
|
|
251
|
+
const body = {
|
|
252
|
+
number,
|
|
253
|
+
message: params.message,
|
|
254
|
+
sendername: params.sendername
|
|
255
|
+
};
|
|
256
|
+
return this.http.request(
|
|
257
|
+
"/messages",
|
|
258
|
+
{
|
|
259
|
+
method: "POST",
|
|
260
|
+
body
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* List sent messages with optional filtering.
|
|
266
|
+
*
|
|
267
|
+
* Supports pagination and filtering by date range, network, status, and sender name.
|
|
268
|
+
*
|
|
269
|
+
* @param params - Optional filter parameters
|
|
270
|
+
* @returns Array of message objects
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* // List all messages
|
|
275
|
+
* const messages = await client.messages.list();
|
|
276
|
+
*
|
|
277
|
+
* // List with filters
|
|
278
|
+
* const filtered = await client.messages.list({
|
|
279
|
+
* page: 1,
|
|
280
|
+
* limit: 50,
|
|
281
|
+
* status: 'Sent',
|
|
282
|
+
* startDate: '2024-01-01',
|
|
283
|
+
* endDate: '2024-01-31',
|
|
284
|
+
* });
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
async list(params) {
|
|
288
|
+
const queryString = this.buildQueryString(params);
|
|
289
|
+
return this.http.request(`/messages${queryString}`, {
|
|
290
|
+
method: "GET"
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get a specific message by ID.
|
|
295
|
+
*
|
|
296
|
+
* @param id - The message ID to retrieve
|
|
297
|
+
* @returns The message object
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const message = await client.messages.get(12345);
|
|
302
|
+
* console.log(message.status); // 'Sent'
|
|
303
|
+
* console.log(message.recipient); // '09171234567'
|
|
304
|
+
* ```
|
|
305
|
+
*/
|
|
306
|
+
async get(id) {
|
|
307
|
+
return this.http.request(`/messages/${id}`, {
|
|
308
|
+
method: "GET"
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Build query string from optional MessageListRequest parameters.
|
|
313
|
+
*
|
|
314
|
+
* @param params - Optional filter parameters
|
|
315
|
+
* @returns Query string including leading '?' if params exist, empty string otherwise
|
|
316
|
+
*/
|
|
317
|
+
buildQueryString(params) {
|
|
318
|
+
if (!params) {
|
|
319
|
+
return "";
|
|
320
|
+
}
|
|
321
|
+
const searchParams = new URLSearchParams();
|
|
322
|
+
if (params.page !== void 0) {
|
|
323
|
+
searchParams.set("page", String(params.page));
|
|
324
|
+
}
|
|
325
|
+
if (params.limit !== void 0) {
|
|
326
|
+
searchParams.set("limit", String(params.limit));
|
|
327
|
+
}
|
|
328
|
+
if (params.startDate !== void 0) {
|
|
329
|
+
searchParams.set("startDate", params.startDate);
|
|
330
|
+
}
|
|
331
|
+
if (params.endDate !== void 0) {
|
|
332
|
+
searchParams.set("endDate", params.endDate);
|
|
333
|
+
}
|
|
334
|
+
if (params.network !== void 0) {
|
|
335
|
+
searchParams.set("network", params.network);
|
|
336
|
+
}
|
|
337
|
+
if (params.status !== void 0) {
|
|
338
|
+
searchParams.set("status", params.status);
|
|
339
|
+
}
|
|
340
|
+
if (params.sendername !== void 0) {
|
|
341
|
+
searchParams.set("sendername", params.sendername);
|
|
342
|
+
}
|
|
343
|
+
const queryString = searchParams.toString();
|
|
344
|
+
return queryString ? `?${queryString}` : "";
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// src/resources/otp.ts
|
|
349
|
+
var OtpResource = class {
|
|
350
|
+
constructor(http) {
|
|
351
|
+
this.http = http;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Send an OTP message to a recipient.
|
|
355
|
+
*
|
|
356
|
+
* Uses priority route - no rate limit, 2 credits per 160-char message.
|
|
357
|
+
* The API generates the OTP code and replaces the {otp} placeholder in your message.
|
|
358
|
+
*
|
|
359
|
+
* @param params - OTP parameters including recipient, message template, sender name
|
|
360
|
+
* @returns Response including the generated OTP code
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```typescript
|
|
364
|
+
* const response = await client.otp.send({
|
|
365
|
+
* number: '+639171234567',
|
|
366
|
+
* message: 'Your verification code is {otp}',
|
|
367
|
+
* sendername: 'MyApp',
|
|
368
|
+
* });
|
|
369
|
+
* console.log('OTP sent:', response.code);
|
|
370
|
+
* ```
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```typescript
|
|
374
|
+
* // With custom code length
|
|
375
|
+
* const response = await client.otp.send({
|
|
376
|
+
* number: '+639171234567',
|
|
377
|
+
* message: 'Your code is {otp}',
|
|
378
|
+
* sendername: 'MyApp',
|
|
379
|
+
* code_length: 4,
|
|
380
|
+
* });
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
async send(params) {
|
|
384
|
+
return this.http.request("/otp", {
|
|
385
|
+
method: "POST",
|
|
386
|
+
body: params
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
// src/resources/account.ts
|
|
392
|
+
var AccountResource = class {
|
|
393
|
+
constructor(http) {
|
|
394
|
+
this.http = http;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Get account information including credit balance.
|
|
398
|
+
*
|
|
399
|
+
* @returns Account info with balance
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```typescript
|
|
403
|
+
* const info = await client.account.info();
|
|
404
|
+
* console.log('Account:', info.account_name);
|
|
405
|
+
* console.log('Balance:', info.credit_balance);
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
async info() {
|
|
409
|
+
return this.http.request("/account");
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Get transaction history.
|
|
413
|
+
*
|
|
414
|
+
* @param params - Optional pagination and date filter parameters
|
|
415
|
+
* @returns Array of transactions
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```typescript
|
|
419
|
+
* // Get all transactions
|
|
420
|
+
* const transactions = await client.account.transactions();
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```typescript
|
|
425
|
+
* // Get paginated transactions with date range
|
|
426
|
+
* const transactions = await client.account.transactions({
|
|
427
|
+
* page: 1,
|
|
428
|
+
* limit: 50,
|
|
429
|
+
* startDate: '2026-01-01',
|
|
430
|
+
* endDate: '2026-01-31',
|
|
431
|
+
* });
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
async transactions(params) {
|
|
435
|
+
const query = this.buildQueryString(params);
|
|
436
|
+
return this.http.request(`/account/transactions${query}`);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get list of approved sender names.
|
|
440
|
+
*
|
|
441
|
+
* @returns Array of sender names with status
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```typescript
|
|
445
|
+
* const senderNames = await client.account.senderNames();
|
|
446
|
+
* for (const sender of senderNames) {
|
|
447
|
+
* console.log(`${sender.name}: ${sender.status}`);
|
|
448
|
+
* }
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
451
|
+
async senderNames() {
|
|
452
|
+
return this.http.request("/account/sendernames");
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Build query string from optional transaction list parameters.
|
|
456
|
+
*
|
|
457
|
+
* @param params - Optional filter parameters
|
|
458
|
+
* @returns Query string (empty string or ?param1=value1¶m2=value2)
|
|
459
|
+
*/
|
|
460
|
+
buildQueryString(params) {
|
|
461
|
+
if (!params) return "";
|
|
462
|
+
const searchParams = new URLSearchParams();
|
|
463
|
+
if (params.page !== void 0) searchParams.set("page", String(params.page));
|
|
464
|
+
if (params.limit !== void 0) searchParams.set("limit", String(params.limit));
|
|
465
|
+
if (params.startDate) searchParams.set("startDate", params.startDate);
|
|
466
|
+
if (params.endDate) searchParams.set("endDate", params.endDate);
|
|
467
|
+
const str = searchParams.toString();
|
|
468
|
+
return str ? `?${str}` : "";
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
// src/client.ts
|
|
473
|
+
var SemaphoreClient = class {
|
|
474
|
+
/** @internal HTTP client used by resource classes. */
|
|
475
|
+
http;
|
|
476
|
+
/** SMS message operations */
|
|
477
|
+
messages;
|
|
478
|
+
/** OTP message operations (priority route, no rate limit) */
|
|
479
|
+
otp;
|
|
480
|
+
/** Account information operations */
|
|
481
|
+
account;
|
|
482
|
+
constructor(options = {}) {
|
|
483
|
+
let apiKey = options.apiKey;
|
|
484
|
+
if (!apiKey && typeof process !== "undefined" && process.env) {
|
|
485
|
+
apiKey = process.env.SEMAPHORE_API_KEY;
|
|
486
|
+
}
|
|
487
|
+
if (!apiKey) {
|
|
488
|
+
throw new AuthenticationError(
|
|
489
|
+
'Missing API key. Pass it to the constructor `new SemaphoreClient({ apiKey: "..." })` or set the SEMAPHORE_API_KEY environment variable.'
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const baseUrl = options.baseUrl ?? "https://api.semaphore.co/api/v4";
|
|
493
|
+
const timeout = options.timeout ?? 3e4;
|
|
494
|
+
this.http = new HttpClient({
|
|
495
|
+
baseUrl,
|
|
496
|
+
apiKey,
|
|
497
|
+
timeout,
|
|
498
|
+
onRetry: options.onRetry
|
|
499
|
+
});
|
|
500
|
+
this.messages = new MessagesResource(this.http);
|
|
501
|
+
this.otp = new OtpResource(this.http);
|
|
502
|
+
this.account = new AccountResource(this.http);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
export { AccountResource, AuthenticationError, HttpClient, MessagesResource, NetworkError, OtpResource, RateLimitError, SemaphoreClient, SemaphoreError, TimeoutError, ValidationError };
|
|
507
|
+
//# sourceMappingURL=index.js.map
|
|
508
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors/errors.ts","../src/http/client.ts","../src/resources/messages.ts","../src/resources/otp.ts","../src/resources/account.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { RequestContext } from '../types/http.js';\n\n/**\n * Base error class for all Semaphore API errors.\n * Extend this for specific error types.\n */\nexport class SemaphoreError extends Error {\n public readonly statusCode?: number;\n public readonly code?: string;\n\n constructor(message: string, statusCode?: number, code?: string) {\n super(message);\n this.statusCode = statusCode;\n this.code = code;\n this.name = 'SemaphoreError';\n // Required for proper instanceof checks with Error subclasses\n Object.setPrototypeOf(this, SemaphoreError.prototype);\n }\n}\n\n/**\n * Thrown when the API key is invalid or missing.\n */\nexport class AuthenticationError extends SemaphoreError {\n constructor(message: string = 'Invalid or missing API key') {\n super(message, 401, 'authentication_error');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Thrown when rate limits are exceeded.\n * Check `retryAfter` for seconds to wait before retrying.\n */\nexport class RateLimitError extends SemaphoreError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = 'Rate limit exceeded',\n retryAfter?: number\n ) {\n super(message, 429, 'rate_limit_error');\n this.retryAfter = retryAfter;\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\n/**\n * Thrown when request parameters are invalid.\n */\nexport class ValidationError extends SemaphoreError {\n public readonly field?: string;\n\n constructor(message: string, field?: string) {\n super(message, 400, 'validation_error');\n this.field = field;\n this.name = 'ValidationError';\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\n/**\n * Thrown when a network error occurs (connection failure, DNS resolution, etc.).\n * The `request` property contains context about the failed request.\n * The `cause` property contains the underlying error if available.\n */\nexport class NetworkError extends SemaphoreError {\n public readonly request: RequestContext;\n public readonly cause?: Error;\n\n constructor(message: string, request: RequestContext, cause?: Error) {\n super(message, undefined, 'network_error');\n this.request = request;\n this.cause = cause;\n this.name = 'NetworkError';\n Object.setPrototypeOf(this, NetworkError.prototype);\n }\n}\n\n/**\n * Thrown when a request times out.\n * The `request` property contains context about the timed-out request.\n * The `timeoutMs` property indicates the timeout duration that was exceeded.\n */\nexport class TimeoutError extends SemaphoreError {\n public readonly request: RequestContext;\n public readonly timeoutMs: number;\n\n constructor(message: string, request: RequestContext, timeoutMs: number) {\n super(message, undefined, 'timeout_error');\n this.request = request;\n this.timeoutMs = timeoutMs;\n this.name = 'TimeoutError';\n Object.setPrototypeOf(this, TimeoutError.prototype);\n }\n}\n","import type { RequestContext, HttpRequestOptions, RetryOptions } from '../types/http.js';\nimport {\n SemaphoreError,\n AuthenticationError,\n RateLimitError,\n ValidationError,\n NetworkError,\n TimeoutError,\n} from '../errors/index.js';\n\n/**\n * Configuration for HttpClient.\n */\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n timeout: number;\n maxRetries?: number;\n onRetry?: (attempt: number, delayMs: number) => void;\n}\n\n/**\n * Parse Retry-After header value to milliseconds.\n * Supports both seconds format (\"120\") and HTTP-date format (\"Wed, 21 Oct 2015 07:28:00 GMT\").\n *\n * @param header - The Retry-After header value\n * @param defaultMs - Default delay in milliseconds when header is missing or invalid\n * @returns Delay in milliseconds\n */\nexport function parseRetryAfter(header: string | null, defaultMs: number = 1000): number {\n if (!header) {\n return defaultMs;\n }\n\n // Format 1: delay-seconds (e.g., \"120\")\n const seconds = parseFloat(header);\n if (!isNaN(seconds) && seconds >= 0) {\n return Math.round(seconds * 1000);\n }\n\n // Format 2: http-date (e.g., \"Wed, 21 Oct 2015 07:28:00 GMT\")\n const date = new Date(header);\n if (!isNaN(date.getTime())) {\n const delayMs = date.getTime() - Date.now();\n return Math.max(0, delayMs);\n }\n\n return defaultMs;\n}\n\n/**\n * Remove sensitive information from URL for error messages.\n * Removes apikey query parameter if present.\n *\n * @param url - The URL to sanitize\n * @returns URL with sensitive parameters removed\n */\nexport function sanitizeUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n urlObj.searchParams.delete('apikey');\n return urlObj.toString();\n } catch {\n // If URL parsing fails, return original (it may be a relative path)\n return url;\n }\n}\n\n/**\n * HTTP client with timeout and retry support for the Semaphore API.\n *\n * Features:\n * - Configurable timeout using AbortSignal.timeout()\n * - Automatic retry on 429 (rate limit) responses with Retry-After header support\n * - Maps HTTP status codes to typed error classes\n * - Includes sanitized request context in errors for debugging\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n private readonly maxRetries: number;\n private readonly onRetry?: (attempt: number, delayMs: number) => void;\n\n constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.timeout = config.timeout;\n this.maxRetries = config.maxRetries ?? 3;\n this.onRetry = config.onRetry;\n }\n\n /**\n * Map HTTP response to appropriate error class.\n *\n * @param response - The HTTP response\n * @param bodyText - Response body text (first 500 chars)\n * @returns Appropriate error instance\n */\n private mapResponseToError(\n response: Response,\n bodyText: string\n ): SemaphoreError {\n const status = response.status;\n const truncatedBody = bodyText.length > 500 ? bodyText.slice(0, 500) + '...' : bodyText;\n const message = `HTTP ${status}: ${truncatedBody || response.statusText}`;\n\n if (status === 401) {\n return new AuthenticationError(message);\n }\n\n if (status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const retryAfterSeconds = retryAfter ? parseRetryAfter(retryAfter) / 1000 : undefined;\n return new RateLimitError(message, retryAfterSeconds);\n }\n\n if (status >= 400 && status < 500) {\n return new ValidationError(message);\n }\n\n // 500+ server errors\n return new SemaphoreError(message, status);\n }\n\n /**\n * Make an HTTP request to the Semaphore API.\n *\n * @param path - API path (e.g., \"/messages\")\n * @param options - Request and retry options\n * @returns Parsed JSON response\n * @throws {NetworkError} On connection failures\n * @throws {TimeoutError} On request timeout\n * @throws {AuthenticationError} On 401 responses\n * @throws {RateLimitError} On 429 responses (after retries exhausted)\n * @throws {ValidationError} On 4xx responses\n * @throws {SemaphoreError} On 5xx responses\n */\n async request<T>(\n path: string,\n options: HttpRequestOptions & RetryOptions = {}\n ): Promise<T> {\n const {\n method = 'GET',\n body,\n timeout = this.timeout,\n headers = {},\n maxRetries = this.maxRetries,\n onRetry = this.onRetry,\n } = options;\n\n const url = `${this.baseUrl}${path}`;\n const sanitizedUrl = sanitizeUrl(url);\n const requestContext: RequestContext = {\n url: sanitizedUrl,\n method,\n };\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n ...headers,\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(timeout),\n });\n\n if (!response.ok) {\n // Read response body for error message\n let bodyText = '';\n try {\n bodyText = await response.text();\n } catch {\n // Ignore body read errors\n }\n\n // Handle 429 rate limit with retry\n if (response.status === 429 && attempt < maxRetries) {\n const retryAfter = response.headers.get('Retry-After');\n const delayMs = parseRetryAfter(retryAfter);\n onRetry?.(attempt, delayMs);\n await new Promise(resolve => setTimeout(resolve, delayMs));\n continue;\n }\n\n // Throw mapped error for all other cases\n throw this.mapResponseToError(response, bodyText);\n }\n\n // Parse successful response\n try {\n return await response.json() as T;\n } catch (parseError) {\n throw new SemaphoreError(\n `Failed to parse response JSON: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`,\n response.status\n );\n }\n\n } catch (error) {\n // Re-throw our own errors\n if (error instanceof SemaphoreError) {\n throw error;\n }\n\n if (error instanceof Error) {\n // Handle timeout errors from AbortSignal.timeout()\n if (error.name === 'TimeoutError') {\n throw new TimeoutError(\n `Request timed out after ${timeout}ms`,\n requestContext,\n timeout\n );\n }\n\n // Handle network errors (connection refused, DNS failure, etc.)\n throw new NetworkError(\n `Network error: ${error.message}`,\n requestContext,\n error\n );\n }\n\n // Re-throw unknown errors\n throw error;\n }\n }\n\n // All retries exhausted on 429\n throw new RateLimitError('Rate limit exceeded after max retries');\n }\n}\n","import type { HttpClient } from '../http/index.js';\nimport type {\n SendMessageRequest,\n SendMessageResponse,\n BulkSendMessageResponse,\n MessageListRequest,\n Message,\n} from '../types/index.js';\n\n/**\n * Resource class for SMS message operations.\n *\n * Provides methods for sending messages, listing sent messages,\n * and retrieving message details by ID.\n *\n * @example\n * ```typescript\n * const client = new SemaphoreClient({ apiKey: 'your-api-key' });\n *\n * // Send a single message\n * const response = await client.messages.send({\n * number: '09171234567',\n * message: 'Hello!',\n * sendername: 'SEMAPHORE',\n * });\n * ```\n */\nexport class MessagesResource {\n /**\n * Create a new MessagesResource instance.\n *\n * @param http - HttpClient instance for making API requests\n */\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Send an SMS message to one or more recipients.\n *\n * When sending to multiple recipients (up to 1000), pass an array of numbers.\n * The API will return an array of responses, one for each recipient.\n *\n * @param params - Message parameters including recipient(s), message content, and sender name\n * @returns Single response for one recipient, array of responses for multiple recipients\n *\n * @example\n * ```typescript\n * // Send to single recipient\n * const response = await client.messages.send({\n * number: '09171234567',\n * message: 'Hello!',\n * sendername: 'SEMAPHORE',\n * });\n * console.log(response.message_id);\n *\n * // Send to multiple recipients (bulk)\n * const responses = await client.messages.send({\n * number: ['09171234567', '09181234567'],\n * message: 'Hello everyone!',\n * sendername: 'SEMAPHORE',\n * });\n * console.log(responses.length); // 2\n * ```\n */\n async send(\n params: SendMessageRequest\n ): Promise<SendMessageResponse | BulkSendMessageResponse> {\n // Convert number array to comma-separated string for API\n const number = Array.isArray(params.number)\n ? params.number.join(',')\n : params.number;\n\n const body = {\n number,\n message: params.message,\n sendername: params.sendername,\n };\n\n return this.http.request<SendMessageResponse | BulkSendMessageResponse>(\n '/messages',\n {\n method: 'POST',\n body,\n }\n );\n }\n\n /**\n * List sent messages with optional filtering.\n *\n * Supports pagination and filtering by date range, network, status, and sender name.\n *\n * @param params - Optional filter parameters\n * @returns Array of message objects\n *\n * @example\n * ```typescript\n * // List all messages\n * const messages = await client.messages.list();\n *\n * // List with filters\n * const filtered = await client.messages.list({\n * page: 1,\n * limit: 50,\n * status: 'Sent',\n * startDate: '2024-01-01',\n * endDate: '2024-01-31',\n * });\n * ```\n */\n async list(params?: MessageListRequest): Promise<Message[]> {\n const queryString = this.buildQueryString(params);\n return this.http.request<Message[]>(`/messages${queryString}`, {\n method: 'GET',\n });\n }\n\n /**\n * Get a specific message by ID.\n *\n * @param id - The message ID to retrieve\n * @returns The message object\n *\n * @example\n * ```typescript\n * const message = await client.messages.get(12345);\n * console.log(message.status); // 'Sent'\n * console.log(message.recipient); // '09171234567'\n * ```\n */\n async get(id: number): Promise<Message> {\n return this.http.request<Message>(`/messages/${id}`, {\n method: 'GET',\n });\n }\n\n /**\n * Build query string from optional MessageListRequest parameters.\n *\n * @param params - Optional filter parameters\n * @returns Query string including leading '?' if params exist, empty string otherwise\n */\n private buildQueryString(params?: MessageListRequest): string {\n if (!params) {\n return '';\n }\n\n const searchParams = new URLSearchParams();\n\n if (params.page !== undefined) {\n searchParams.set('page', String(params.page));\n }\n if (params.limit !== undefined) {\n searchParams.set('limit', String(params.limit));\n }\n if (params.startDate !== undefined) {\n searchParams.set('startDate', params.startDate);\n }\n if (params.endDate !== undefined) {\n searchParams.set('endDate', params.endDate);\n }\n if (params.network !== undefined) {\n searchParams.set('network', params.network);\n }\n if (params.status !== undefined) {\n searchParams.set('status', params.status);\n }\n if (params.sendername !== undefined) {\n searchParams.set('sendername', params.sendername);\n }\n\n const queryString = searchParams.toString();\n return queryString ? `?${queryString}` : '';\n }\n}\n","import type { HttpClient } from '../http/index.js';\nimport type { SendOtpRequest, SendOtpResponse } from '../types/index.js';\n\n/**\n * Resource for sending OTP (One-Time Password) messages.\n *\n * OTP messages use a priority route with no rate limit.\n * Each message costs 2 credits per 160 characters.\n */\nexport class OtpResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Send an OTP message to a recipient.\n *\n * Uses priority route - no rate limit, 2 credits per 160-char message.\n * The API generates the OTP code and replaces the {otp} placeholder in your message.\n *\n * @param params - OTP parameters including recipient, message template, sender name\n * @returns Response including the generated OTP code\n *\n * @example\n * ```typescript\n * const response = await client.otp.send({\n * number: '+639171234567',\n * message: 'Your verification code is {otp}',\n * sendername: 'MyApp',\n * });\n * console.log('OTP sent:', response.code);\n * ```\n *\n * @example\n * ```typescript\n * // With custom code length\n * const response = await client.otp.send({\n * number: '+639171234567',\n * message: 'Your code is {otp}',\n * sendername: 'MyApp',\n * code_length: 4,\n * });\n * ```\n */\n async send(params: SendOtpRequest): Promise<SendOtpResponse> {\n return this.http.request<SendOtpResponse>('/otp', {\n method: 'POST',\n body: params,\n });\n }\n}\n","import type { HttpClient } from '../http/index.js';\nimport type {\n AccountInfo,\n Transaction,\n TransactionListRequest,\n SenderName,\n} from '../types/index.js';\n\n/**\n * Resource for retrieving account information.\n */\nexport class AccountResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Get account information including credit balance.\n *\n * @returns Account info with balance\n *\n * @example\n * ```typescript\n * const info = await client.account.info();\n * console.log('Account:', info.account_name);\n * console.log('Balance:', info.credit_balance);\n * ```\n */\n async info(): Promise<AccountInfo> {\n return this.http.request<AccountInfo>('/account');\n }\n\n /**\n * Get transaction history.\n *\n * @param params - Optional pagination and date filter parameters\n * @returns Array of transactions\n *\n * @example\n * ```typescript\n * // Get all transactions\n * const transactions = await client.account.transactions();\n * ```\n *\n * @example\n * ```typescript\n * // Get paginated transactions with date range\n * const transactions = await client.account.transactions({\n * page: 1,\n * limit: 50,\n * startDate: '2026-01-01',\n * endDate: '2026-01-31',\n * });\n * ```\n */\n async transactions(params?: TransactionListRequest): Promise<Transaction[]> {\n const query = this.buildQueryString(params);\n return this.http.request<Transaction[]>(`/account/transactions${query}`);\n }\n\n /**\n * Get list of approved sender names.\n *\n * @returns Array of sender names with status\n *\n * @example\n * ```typescript\n * const senderNames = await client.account.senderNames();\n * for (const sender of senderNames) {\n * console.log(`${sender.name}: ${sender.status}`);\n * }\n * ```\n */\n async senderNames(): Promise<SenderName[]> {\n return this.http.request<SenderName[]>('/account/sendernames');\n }\n\n /**\n * Build query string from optional transaction list parameters.\n *\n * @param params - Optional filter parameters\n * @returns Query string (empty string or ?param1=value1¶m2=value2)\n */\n private buildQueryString(params?: TransactionListRequest): string {\n if (!params) return '';\n\n const searchParams = new URLSearchParams();\n\n if (params.page !== undefined) searchParams.set('page', String(params.page));\n if (params.limit !== undefined) searchParams.set('limit', String(params.limit));\n if (params.startDate) searchParams.set('startDate', params.startDate);\n if (params.endDate) searchParams.set('endDate', params.endDate);\n\n const str = searchParams.toString();\n return str ? `?${str}` : '';\n }\n}\n","import { AuthenticationError } from './errors/index.js';\nimport { HttpClient } from './http/index.js';\nimport { MessagesResource } from './resources/messages.js';\nimport { OtpResource } from './resources/otp.js';\nimport { AccountResource } from './resources/account.js';\nimport type { SemaphoreClientOptions } from './types/common.js';\n\n/**\n * Semaphore API client for sending SMS and OTP messages.\n *\n * @example\n * ```typescript\n * // Send SMS\n * const client = new SemaphoreClient({ apiKey: 'your-api-key' });\n * await client.messages.send({\n * number: '+639171234567',\n * message: 'Hello!',\n * sendername: 'MyApp',\n * });\n *\n * // Check balance\n * const info = await client.account.info();\n * console.log('Balance:', info.credit_balance);\n * ```\n */\nexport class SemaphoreClient {\n /** @internal HTTP client used by resource classes. */\n protected readonly http: HttpClient;\n\n /** SMS message operations */\n readonly messages: MessagesResource;\n\n /** OTP message operations (priority route, no rate limit) */\n readonly otp: OtpResource;\n\n /** Account information operations */\n readonly account: AccountResource;\n\n constructor(options: SemaphoreClientOptions = {}) {\n // Environment variable fallback (cross-runtime compatible)\n let apiKey = options.apiKey;\n if (!apiKey && typeof process !== 'undefined' && process.env) {\n apiKey = process.env.SEMAPHORE_API_KEY;\n }\n\n // Fail fast on missing API key (constructor-time validation)\n if (!apiKey) {\n throw new AuthenticationError(\n 'Missing API key. Pass it to the constructor `new SemaphoreClient({ apiKey: \"...\" })` ' +\n 'or set the SEMAPHORE_API_KEY environment variable.'\n );\n }\n\n const baseUrl = options.baseUrl ?? 'https://api.semaphore.co/api/v4';\n const timeout = options.timeout ?? 30000;\n\n this.http = new HttpClient({\n baseUrl,\n apiKey,\n timeout,\n onRetry: options.onRetry,\n });\n\n // Instantiate resource classes with HTTP client access\n this.messages = new MessagesResource(this.http);\n this.otp = new OtpResource(this.http);\n this.account = new AccountResource(this.http);\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "semaphoreco",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official TypeScript/JavaScript client for Semaphore.co - Philippines SMS Gateway API for sending SMS and OTP messages",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint:package": "publint && attw --pack .",
|
|
29
|
+
"prepublishOnly": "npm run build && npm run lint:package"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"semaphore",
|
|
33
|
+
"semaphore-co",
|
|
34
|
+
"semaphore.co",
|
|
35
|
+
"sms",
|
|
36
|
+
"sms-api",
|
|
37
|
+
"sms-gateway",
|
|
38
|
+
"otp",
|
|
39
|
+
"otp-verification",
|
|
40
|
+
"philippines",
|
|
41
|
+
"philippines-sms",
|
|
42
|
+
"api-client",
|
|
43
|
+
"typescript",
|
|
44
|
+
"text-messaging",
|
|
45
|
+
"bulk-sms"
|
|
46
|
+
],
|
|
47
|
+
"author": "",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/rohjli/semaphore-client-js.git"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/rohjli/semaphore-client-js/issues"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://semaphore.co",
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
59
|
+
"@types/node": "^25.0.10",
|
|
60
|
+
"publint": "^0.3.17",
|
|
61
|
+
"tsup": "^8.5.1",
|
|
62
|
+
"typescript": "^5.9.3"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=18.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|