@jadedm/nestjs-verify-twilio 0.1.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/dist/index.d.mts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +46 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +53 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SmsProvider, SmsSendParams, SmsSendResult } from '@jadedm/nestjs-verify';
|
|
2
|
+
|
|
3
|
+
interface TwilioSmsProviderOptions {
|
|
4
|
+
accountSid: string;
|
|
5
|
+
authToken: string;
|
|
6
|
+
/** E.164 sender number, or Messaging Service SID (starts with MG…). */
|
|
7
|
+
from: string;
|
|
8
|
+
/** Retry budget for transient (5xx, network) failures. Default 2. */
|
|
9
|
+
maxRetries?: number;
|
|
10
|
+
/** Base delay in ms for exponential backoff. Default 250. */
|
|
11
|
+
retryBaseMs?: number;
|
|
12
|
+
}
|
|
13
|
+
declare class TwilioSmsProvider implements SmsProvider {
|
|
14
|
+
readonly name = "twilio";
|
|
15
|
+
private readonly client;
|
|
16
|
+
private readonly from;
|
|
17
|
+
private readonly maxRetries;
|
|
18
|
+
private readonly retryBaseMs;
|
|
19
|
+
constructor(opts: TwilioSmsProviderOptions);
|
|
20
|
+
send(params: SmsSendParams): Promise<SmsSendResult>;
|
|
21
|
+
private sleep;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { TwilioSmsProvider, type TwilioSmsProviderOptions };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SmsProvider, SmsSendParams, SmsSendResult } from '@jadedm/nestjs-verify';
|
|
2
|
+
|
|
3
|
+
interface TwilioSmsProviderOptions {
|
|
4
|
+
accountSid: string;
|
|
5
|
+
authToken: string;
|
|
6
|
+
/** E.164 sender number, or Messaging Service SID (starts with MG…). */
|
|
7
|
+
from: string;
|
|
8
|
+
/** Retry budget for transient (5xx, network) failures. Default 2. */
|
|
9
|
+
maxRetries?: number;
|
|
10
|
+
/** Base delay in ms for exponential backoff. Default 250. */
|
|
11
|
+
retryBaseMs?: number;
|
|
12
|
+
}
|
|
13
|
+
declare class TwilioSmsProvider implements SmsProvider {
|
|
14
|
+
readonly name = "twilio";
|
|
15
|
+
private readonly client;
|
|
16
|
+
private readonly from;
|
|
17
|
+
private readonly maxRetries;
|
|
18
|
+
private readonly retryBaseMs;
|
|
19
|
+
constructor(opts: TwilioSmsProviderOptions);
|
|
20
|
+
send(params: SmsSendParams): Promise<SmsSendResult>;
|
|
21
|
+
private sleep;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { TwilioSmsProvider, type TwilioSmsProviderOptions };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
TwilioSmsProvider: () => TwilioSmsProvider
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/twilio-sms.provider.ts
|
|
28
|
+
var import_twilio = require("twilio");
|
|
29
|
+
var TRANSIENT_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
30
|
+
var TwilioSmsProvider = class {
|
|
31
|
+
name = "twilio";
|
|
32
|
+
client;
|
|
33
|
+
from;
|
|
34
|
+
maxRetries;
|
|
35
|
+
retryBaseMs;
|
|
36
|
+
constructor(opts) {
|
|
37
|
+
this.client = new import_twilio.Twilio(opts.accountSid, opts.authToken);
|
|
38
|
+
this.from = opts.from;
|
|
39
|
+
this.maxRetries = opts.maxRetries ?? 2;
|
|
40
|
+
this.retryBaseMs = opts.retryBaseMs ?? 250;
|
|
41
|
+
}
|
|
42
|
+
async send(params) {
|
|
43
|
+
const useMessagingService = this.from.startsWith("MG");
|
|
44
|
+
let attempt = 0;
|
|
45
|
+
let lastErr;
|
|
46
|
+
while (attempt <= this.maxRetries) {
|
|
47
|
+
try {
|
|
48
|
+
const message = await this.client.messages.create({
|
|
49
|
+
to: params.to,
|
|
50
|
+
body: params.body,
|
|
51
|
+
...useMessagingService ? { messagingServiceSid: this.from } : { from: this.from }
|
|
52
|
+
});
|
|
53
|
+
return { providerMessageId: message.sid, provider: this.name };
|
|
54
|
+
} catch (err) {
|
|
55
|
+
lastErr = err;
|
|
56
|
+
const status = err.status;
|
|
57
|
+
if (status && !TRANSIENT_STATUS_CODES.has(status)) throw err;
|
|
58
|
+
if (attempt === this.maxRetries) break;
|
|
59
|
+
await this.sleep(this.retryBaseMs * 2 ** attempt);
|
|
60
|
+
attempt++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw lastErr;
|
|
64
|
+
}
|
|
65
|
+
sleep(ms) {
|
|
66
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
70
|
+
0 && (module.exports = {
|
|
71
|
+
TwilioSmsProvider
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/twilio-sms.provider.ts"],"sourcesContent":["export * from './twilio-sms.provider.js';\n","import type {\n SmsProvider,\n SmsSendParams,\n SmsSendResult,\n} from '@jadedm/nestjs-verify';\nimport { Twilio } from 'twilio';\n\nexport interface TwilioSmsProviderOptions {\n accountSid: string;\n authToken: string;\n /** E.164 sender number, or Messaging Service SID (starts with MG…). */\n from: string;\n /** Retry budget for transient (5xx, network) failures. Default 2. */\n maxRetries?: number;\n /** Base delay in ms for exponential backoff. Default 250. */\n retryBaseMs?: number;\n}\n\n/**\n * Errors Twilio considers transient — worth retrying. Everything else\n * (invalid number, blocked recipient, geo-permission) is terminal.\n */\nconst TRANSIENT_STATUS_CODES = new Set([429, 500, 502, 503, 504]);\n\nexport class TwilioSmsProvider implements SmsProvider {\n readonly name = 'twilio';\n private readonly client: Twilio;\n private readonly from: string;\n private readonly maxRetries: number;\n private readonly retryBaseMs: number;\n\n constructor(opts: TwilioSmsProviderOptions) {\n this.client = new Twilio(opts.accountSid, opts.authToken);\n this.from = opts.from;\n this.maxRetries = opts.maxRetries ?? 2;\n this.retryBaseMs = opts.retryBaseMs ?? 250;\n }\n\n async send(params: SmsSendParams): Promise<SmsSendResult> {\n const useMessagingService = this.from.startsWith('MG');\n let attempt = 0;\n let lastErr: unknown;\n while (attempt <= this.maxRetries) {\n try {\n const message = await this.client.messages.create({\n to: params.to,\n body: params.body,\n ...(useMessagingService\n ? { messagingServiceSid: this.from }\n : { from: this.from }),\n });\n return { providerMessageId: message.sid, provider: this.name };\n } catch (err) {\n lastErr = err;\n const status = (err as { status?: number }).status;\n if (status && !TRANSIENT_STATUS_CODES.has(status)) throw err;\n if (attempt === this.maxRetries) break;\n await this.sleep(this.retryBaseMs * 2 ** attempt);\n attempt++;\n }\n }\n throw lastErr;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,oBAAuB;AAiBvB,IAAM,yBAAyB,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAEzD,IAAM,oBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAgC;AAC1C,SAAK,SAAS,IAAI,qBAAO,KAAK,YAAY,KAAK,SAAS;AACxD,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,cAAc,KAAK,eAAe;AAAA,EACzC;AAAA,EAEA,MAAM,KAAK,QAA+C;AACxD,UAAM,sBAAsB,KAAK,KAAK,WAAW,IAAI;AACrD,QAAI,UAAU;AACd,QAAI;AACJ,WAAO,WAAW,KAAK,YAAY;AACjC,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,OAAO,SAAS,OAAO;AAAA,UAChD,IAAI,OAAO;AAAA,UACX,MAAM,OAAO;AAAA,UACb,GAAI,sBACA,EAAE,qBAAqB,KAAK,KAAK,IACjC,EAAE,MAAM,KAAK,KAAK;AAAA,QACxB,CAAC;AACD,eAAO,EAAE,mBAAmB,QAAQ,KAAK,UAAU,KAAK,KAAK;AAAA,MAC/D,SAAS,KAAK;AACZ,kBAAU;AACV,cAAM,SAAU,IAA4B;AAC5C,YAAI,UAAU,CAAC,uBAAuB,IAAI,MAAM,EAAG,OAAM;AACzD,YAAI,YAAY,KAAK,WAAY;AACjC,cAAM,KAAK,MAAM,KAAK,cAAc,KAAK,OAAO;AAChD;AAAA,MACF;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAAA,EAEQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,EAC7C;AACF;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/twilio-sms.provider.ts
|
|
2
|
+
import { Twilio } from "twilio";
|
|
3
|
+
var TRANSIENT_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
4
|
+
var TwilioSmsProvider = class {
|
|
5
|
+
name = "twilio";
|
|
6
|
+
client;
|
|
7
|
+
from;
|
|
8
|
+
maxRetries;
|
|
9
|
+
retryBaseMs;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.client = new Twilio(opts.accountSid, opts.authToken);
|
|
12
|
+
this.from = opts.from;
|
|
13
|
+
this.maxRetries = opts.maxRetries ?? 2;
|
|
14
|
+
this.retryBaseMs = opts.retryBaseMs ?? 250;
|
|
15
|
+
}
|
|
16
|
+
async send(params) {
|
|
17
|
+
const useMessagingService = this.from.startsWith("MG");
|
|
18
|
+
let attempt = 0;
|
|
19
|
+
let lastErr;
|
|
20
|
+
while (attempt <= this.maxRetries) {
|
|
21
|
+
try {
|
|
22
|
+
const message = await this.client.messages.create({
|
|
23
|
+
to: params.to,
|
|
24
|
+
body: params.body,
|
|
25
|
+
...useMessagingService ? { messagingServiceSid: this.from } : { from: this.from }
|
|
26
|
+
});
|
|
27
|
+
return { providerMessageId: message.sid, provider: this.name };
|
|
28
|
+
} catch (err) {
|
|
29
|
+
lastErr = err;
|
|
30
|
+
const status = err.status;
|
|
31
|
+
if (status && !TRANSIENT_STATUS_CODES.has(status)) throw err;
|
|
32
|
+
if (attempt === this.maxRetries) break;
|
|
33
|
+
await this.sleep(this.retryBaseMs * 2 ** attempt);
|
|
34
|
+
attempt++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
throw lastErr;
|
|
38
|
+
}
|
|
39
|
+
sleep(ms) {
|
|
40
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
TwilioSmsProvider
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/twilio-sms.provider.ts"],"sourcesContent":["import type {\n SmsProvider,\n SmsSendParams,\n SmsSendResult,\n} from '@jadedm/nestjs-verify';\nimport { Twilio } from 'twilio';\n\nexport interface TwilioSmsProviderOptions {\n accountSid: string;\n authToken: string;\n /** E.164 sender number, or Messaging Service SID (starts with MG…). */\n from: string;\n /** Retry budget for transient (5xx, network) failures. Default 2. */\n maxRetries?: number;\n /** Base delay in ms for exponential backoff. Default 250. */\n retryBaseMs?: number;\n}\n\n/**\n * Errors Twilio considers transient — worth retrying. Everything else\n * (invalid number, blocked recipient, geo-permission) is terminal.\n */\nconst TRANSIENT_STATUS_CODES = new Set([429, 500, 502, 503, 504]);\n\nexport class TwilioSmsProvider implements SmsProvider {\n readonly name = 'twilio';\n private readonly client: Twilio;\n private readonly from: string;\n private readonly maxRetries: number;\n private readonly retryBaseMs: number;\n\n constructor(opts: TwilioSmsProviderOptions) {\n this.client = new Twilio(opts.accountSid, opts.authToken);\n this.from = opts.from;\n this.maxRetries = opts.maxRetries ?? 2;\n this.retryBaseMs = opts.retryBaseMs ?? 250;\n }\n\n async send(params: SmsSendParams): Promise<SmsSendResult> {\n const useMessagingService = this.from.startsWith('MG');\n let attempt = 0;\n let lastErr: unknown;\n while (attempt <= this.maxRetries) {\n try {\n const message = await this.client.messages.create({\n to: params.to,\n body: params.body,\n ...(useMessagingService\n ? { messagingServiceSid: this.from }\n : { from: this.from }),\n });\n return { providerMessageId: message.sid, provider: this.name };\n } catch (err) {\n lastErr = err;\n const status = (err as { status?: number }).status;\n if (status && !TRANSIENT_STATUS_CODES.has(status)) throw err;\n if (attempt === this.maxRetries) break;\n await this.sleep(this.retryBaseMs * 2 ** attempt);\n attempt++;\n }\n }\n throw lastErr;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n }\n}\n"],"mappings":";AAKA,SAAS,cAAc;AAiBvB,IAAM,yBAAyB,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAEzD,IAAM,oBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAgC;AAC1C,SAAK,SAAS,IAAI,OAAO,KAAK,YAAY,KAAK,SAAS;AACxD,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,cAAc,KAAK,eAAe;AAAA,EACzC;AAAA,EAEA,MAAM,KAAK,QAA+C;AACxD,UAAM,sBAAsB,KAAK,KAAK,WAAW,IAAI;AACrD,QAAI,UAAU;AACd,QAAI;AACJ,WAAO,WAAW,KAAK,YAAY;AACjC,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,OAAO,SAAS,OAAO;AAAA,UAChD,IAAI,OAAO;AAAA,UACX,MAAM,OAAO;AAAA,UACb,GAAI,sBACA,EAAE,qBAAqB,KAAK,KAAK,IACjC,EAAE,MAAM,KAAK,KAAK;AAAA,QACxB,CAAC;AACD,eAAO,EAAE,mBAAmB,QAAQ,KAAK,UAAU,KAAK,KAAK;AAAA,MAC/D,SAAS,KAAK;AACZ,kBAAU;AACV,cAAM,SAAU,IAA4B;AAC5C,YAAI,UAAU,CAAC,uBAAuB,IAAI,MAAM,EAAG,OAAM;AACzD,YAAI,YAAY,KAAK,WAAY;AACjC,cAAM,KAAK,MAAM,KAAK,cAAc,KAAK,OAAO;AAChD;AAAA,MACF;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAAA,EAEQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,EAC7C;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jadedm/nestjs-verify-twilio",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Twilio SMS provider adapter for @jadedm/nestjs-verify.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nestjs",
|
|
7
|
+
"otp",
|
|
8
|
+
"verify",
|
|
9
|
+
"twilio",
|
|
10
|
+
"sms"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "jadedm <jadedmanish@gmail.com>",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/jadedm/nestjs-verify.git",
|
|
17
|
+
"directory": "packages/provider-twilio"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"module": "./dist/index.mjs",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
26
|
+
"default": "./dist/index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"test": "vitest run --passWithNoTests",
|
|
43
|
+
"clean": "rm -rf dist"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@jadedm/nestjs-verify": "workspace:^",
|
|
47
|
+
"twilio": "^4.0.0 || ^5.0.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@jadedm/nestjs-verify": "workspace:*",
|
|
51
|
+
"twilio": "^5.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|