@drawbridge/drawbridge-utils 0.0.128 → 0.0.129
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/oauth/server.cjs +17 -1
- package/dist/oauth/server.d.cts +39 -2
- package/dist/oauth/server.d.ts +39 -2
- package/dist/oauth/server.js +16 -1
- package/dist/pricing.cjs +7 -0
- package/dist/pricing.d.cts +15 -1
- package/dist/pricing.d.ts +15 -1
- package/dist/pricing.js +6 -0
- package/dist/twilio.cjs +6 -2
- package/dist/twilio.d.cts +6 -2
- package/dist/twilio.d.ts +6 -2
- package/dist/twilio.js +6 -2
- package/package.json +1 -1
package/dist/oauth/server.cjs
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// lib/oauth/server.js
|
|
30
30
|
var server_exports = {};
|
|
31
31
|
__export(server_exports, {
|
|
32
|
+
ROTATION_GRACE_MS: () => ROTATION_GRACE_MS,
|
|
32
33
|
createClient: () => createClient,
|
|
33
34
|
createOAuthModel: () => createOAuthModel,
|
|
34
35
|
createOAuthServer: () => createOAuthServer
|
|
@@ -147,6 +148,7 @@ var generateToken = () => generate(32, "base64url");
|
|
|
147
148
|
|
|
148
149
|
// lib/oauth/server.js
|
|
149
150
|
var SUPPORTED_GRANTS = ["authorization_code", "client_credentials", "refresh_token"];
|
|
151
|
+
var ROTATION_GRACE_MS = 60 * 1e3;
|
|
150
152
|
var createOAuthModel = ({ controller }) => ({
|
|
151
153
|
getClient: async (clientId, clientSecret) => {
|
|
152
154
|
var _a;
|
|
@@ -328,12 +330,16 @@ var createOAuthModel = ({ controller }) => ({
|
|
|
328
330
|
const record = await controller.get({
|
|
329
331
|
collection: "token",
|
|
330
332
|
query: {
|
|
331
|
-
revoked: false,
|
|
332
333
|
tokenHash,
|
|
333
334
|
type: tokenTypes.refresh
|
|
334
335
|
}
|
|
335
336
|
});
|
|
336
337
|
if (!record) return false;
|
|
338
|
+
if (record.revoked) {
|
|
339
|
+
const rotatedAt = record.rotatedAt ? new Date(record.rotatedAt).getTime() : null;
|
|
340
|
+
if (!rotatedAt || Date.now() - rotatedAt > ROTATION_GRACE_MS) return false;
|
|
341
|
+
}
|
|
342
|
+
;
|
|
337
343
|
return {
|
|
338
344
|
client: { id: record.client },
|
|
339
345
|
refreshToken,
|
|
@@ -345,6 +351,15 @@ var createOAuthModel = ({ controller }) => ({
|
|
|
345
351
|
revokeToken: async (token) => {
|
|
346
352
|
const rawToken = token.refreshToken ?? token.accessToken;
|
|
347
353
|
const tokenHash = hashToken(rawToken);
|
|
354
|
+
await controller.update({
|
|
355
|
+
collection: "token",
|
|
356
|
+
data: {
|
|
357
|
+
$set: {
|
|
358
|
+
rotatedAt: /* @__PURE__ */ new Date()
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
query: { revoked: { $ne: true }, tokenHash }
|
|
362
|
+
});
|
|
348
363
|
await controller.update({
|
|
349
364
|
collection: "token",
|
|
350
365
|
data: {
|
|
@@ -443,6 +458,7 @@ var createClient = async ({
|
|
|
443
458
|
};
|
|
444
459
|
// Annotate the CommonJS export names for ESM import in node:
|
|
445
460
|
0 && (module.exports = {
|
|
461
|
+
ROTATION_GRACE_MS,
|
|
446
462
|
createClient,
|
|
447
463
|
createOAuthModel,
|
|
448
464
|
createOAuthServer
|
package/dist/oauth/server.d.cts
CHANGED
|
@@ -34,6 +34,11 @@ import 'crypto';
|
|
|
34
34
|
// ever need to, store `grants` on the oauth doc and read it here.
|
|
35
35
|
const SUPPORTED_GRANTS = [ 'authorization_code', 'client_credentials', 'refresh_token' ];
|
|
36
36
|
|
|
37
|
+
// How long a just-rotated refresh token keeps answering (see getRefreshToken).
|
|
38
|
+
// Long enough for the parallel requests of one navigation to all land; short
|
|
39
|
+
// enough that a stolen token replayed later is refused like any other.
|
|
40
|
+
const ROTATION_GRACE_MS = 60 * 1000;
|
|
41
|
+
|
|
37
42
|
const createOAuthModel = ({ controller }) => ({
|
|
38
43
|
|
|
39
44
|
getClient : async ( clientId, clientSecret ) => {
|
|
@@ -258,7 +263,6 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
258
263
|
const record = await controller.get({
|
|
259
264
|
collection : 'token',
|
|
260
265
|
query : {
|
|
261
|
-
revoked : false,
|
|
262
266
|
tokenHash,
|
|
263
267
|
type : tokenTypes.refresh
|
|
264
268
|
}
|
|
@@ -266,6 +270,25 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
266
270
|
|
|
267
271
|
if( ! record ) return false;
|
|
268
272
|
|
|
273
|
+
// ROTATION GRACE. Refresh tokens are single-use, and the dashboard's
|
|
274
|
+
// middleware refreshes on whichever request arrives first — Next fires
|
|
275
|
+
// several in parallel, so the losers present a token the winner just
|
|
276
|
+
// consumed. For a short window a JUST-ROTATED token still answers,
|
|
277
|
+
// so a race mints an extra pair instead of ending the session.
|
|
278
|
+
//
|
|
279
|
+
// `rotatedAt` is written ONCE, on the transition into revoked (see
|
|
280
|
+
// revokeToken) — a replay inside the window cannot refresh it, so the
|
|
281
|
+
// window closes sixty seconds after the first rotation no matter how
|
|
282
|
+
// often the old token is replayed. A token revoked WITHOUT rotatedAt
|
|
283
|
+
// was killed on purpose — signout, an admin, a deleted client — and
|
|
284
|
+
// gets no grace: those revocations must be absolute.
|
|
285
|
+
if( record.revoked ){
|
|
286
|
+
|
|
287
|
+
const rotatedAt = record.rotatedAt ? new Date( record.rotatedAt ).getTime() : null;
|
|
288
|
+
|
|
289
|
+
if( ! rotatedAt || ( Date.now() - rotatedAt ) > ROTATION_GRACE_MS ) return false;
|
|
290
|
+
|
|
291
|
+
}
|
|
269
292
|
return {
|
|
270
293
|
client : { id : record.client },
|
|
271
294
|
refreshToken,
|
|
@@ -281,6 +304,20 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
281
304
|
const rawToken = token.refreshToken ?? token.accessToken;
|
|
282
305
|
const tokenHash = hashToken( rawToken );
|
|
283
306
|
|
|
307
|
+
// rotatedAt marks that this revocation IS a rotation — the only kind
|
|
308
|
+
// getRefreshToken graces. Guarded on the transition (revoked $ne true)
|
|
309
|
+
// so a grace-window replay re-revoking the same row cannot move the
|
|
310
|
+
// stamp and hold the window open.
|
|
311
|
+
await controller.update({
|
|
312
|
+
collection : 'token',
|
|
313
|
+
data : {
|
|
314
|
+
$set : {
|
|
315
|
+
rotatedAt : new Date()
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
query : { revoked : { $ne : true }, tokenHash }
|
|
319
|
+
});
|
|
320
|
+
|
|
284
321
|
await controller.update({
|
|
285
322
|
collection : 'token',
|
|
286
323
|
data : {
|
|
@@ -411,4 +448,4 @@ const createClient = async ({
|
|
|
411
448
|
|
|
412
449
|
};
|
|
413
450
|
|
|
414
|
-
export { createClient, createOAuthModel, createOAuthServer };
|
|
451
|
+
export { ROTATION_GRACE_MS, createClient, createOAuthModel, createOAuthServer };
|
package/dist/oauth/server.d.ts
CHANGED
|
@@ -34,6 +34,11 @@ import 'crypto';
|
|
|
34
34
|
// ever need to, store `grants` on the oauth doc and read it here.
|
|
35
35
|
const SUPPORTED_GRANTS = [ 'authorization_code', 'client_credentials', 'refresh_token' ];
|
|
36
36
|
|
|
37
|
+
// How long a just-rotated refresh token keeps answering (see getRefreshToken).
|
|
38
|
+
// Long enough for the parallel requests of one navigation to all land; short
|
|
39
|
+
// enough that a stolen token replayed later is refused like any other.
|
|
40
|
+
const ROTATION_GRACE_MS = 60 * 1000;
|
|
41
|
+
|
|
37
42
|
const createOAuthModel = ({ controller }) => ({
|
|
38
43
|
|
|
39
44
|
getClient : async ( clientId, clientSecret ) => {
|
|
@@ -258,7 +263,6 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
258
263
|
const record = await controller.get({
|
|
259
264
|
collection : 'token',
|
|
260
265
|
query : {
|
|
261
|
-
revoked : false,
|
|
262
266
|
tokenHash,
|
|
263
267
|
type : tokenTypes.refresh
|
|
264
268
|
}
|
|
@@ -266,6 +270,25 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
266
270
|
|
|
267
271
|
if( ! record ) return false;
|
|
268
272
|
|
|
273
|
+
// ROTATION GRACE. Refresh tokens are single-use, and the dashboard's
|
|
274
|
+
// middleware refreshes on whichever request arrives first — Next fires
|
|
275
|
+
// several in parallel, so the losers present a token the winner just
|
|
276
|
+
// consumed. For a short window a JUST-ROTATED token still answers,
|
|
277
|
+
// so a race mints an extra pair instead of ending the session.
|
|
278
|
+
//
|
|
279
|
+
// `rotatedAt` is written ONCE, on the transition into revoked (see
|
|
280
|
+
// revokeToken) — a replay inside the window cannot refresh it, so the
|
|
281
|
+
// window closes sixty seconds after the first rotation no matter how
|
|
282
|
+
// often the old token is replayed. A token revoked WITHOUT rotatedAt
|
|
283
|
+
// was killed on purpose — signout, an admin, a deleted client — and
|
|
284
|
+
// gets no grace: those revocations must be absolute.
|
|
285
|
+
if( record.revoked ){
|
|
286
|
+
|
|
287
|
+
const rotatedAt = record.rotatedAt ? new Date( record.rotatedAt ).getTime() : null;
|
|
288
|
+
|
|
289
|
+
if( ! rotatedAt || ( Date.now() - rotatedAt ) > ROTATION_GRACE_MS ) return false;
|
|
290
|
+
|
|
291
|
+
}
|
|
269
292
|
return {
|
|
270
293
|
client : { id : record.client },
|
|
271
294
|
refreshToken,
|
|
@@ -281,6 +304,20 @@ const createOAuthModel = ({ controller }) => ({
|
|
|
281
304
|
const rawToken = token.refreshToken ?? token.accessToken;
|
|
282
305
|
const tokenHash = hashToken( rawToken );
|
|
283
306
|
|
|
307
|
+
// rotatedAt marks that this revocation IS a rotation — the only kind
|
|
308
|
+
// getRefreshToken graces. Guarded on the transition (revoked $ne true)
|
|
309
|
+
// so a grace-window replay re-revoking the same row cannot move the
|
|
310
|
+
// stamp and hold the window open.
|
|
311
|
+
await controller.update({
|
|
312
|
+
collection : 'token',
|
|
313
|
+
data : {
|
|
314
|
+
$set : {
|
|
315
|
+
rotatedAt : new Date()
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
query : { revoked : { $ne : true }, tokenHash }
|
|
319
|
+
});
|
|
320
|
+
|
|
284
321
|
await controller.update({
|
|
285
322
|
collection : 'token',
|
|
286
323
|
data : {
|
|
@@ -411,4 +448,4 @@ const createClient = async ({
|
|
|
411
448
|
|
|
412
449
|
};
|
|
413
450
|
|
|
414
|
-
export { createClient, createOAuthModel, createOAuthServer };
|
|
451
|
+
export { ROTATION_GRACE_MS, createClient, createOAuthModel, createOAuthServer };
|
package/dist/oauth/server.js
CHANGED
|
@@ -112,6 +112,7 @@ var generateToken = () => generate(32, "base64url");
|
|
|
112
112
|
|
|
113
113
|
// lib/oauth/server.js
|
|
114
114
|
var SUPPORTED_GRANTS = ["authorization_code", "client_credentials", "refresh_token"];
|
|
115
|
+
var ROTATION_GRACE_MS = 60 * 1e3;
|
|
115
116
|
var createOAuthModel = ({ controller }) => ({
|
|
116
117
|
getClient: async (clientId, clientSecret) => {
|
|
117
118
|
var _a;
|
|
@@ -293,12 +294,16 @@ var createOAuthModel = ({ controller }) => ({
|
|
|
293
294
|
const record = await controller.get({
|
|
294
295
|
collection: "token",
|
|
295
296
|
query: {
|
|
296
|
-
revoked: false,
|
|
297
297
|
tokenHash,
|
|
298
298
|
type: tokenTypes.refresh
|
|
299
299
|
}
|
|
300
300
|
});
|
|
301
301
|
if (!record) return false;
|
|
302
|
+
if (record.revoked) {
|
|
303
|
+
const rotatedAt = record.rotatedAt ? new Date(record.rotatedAt).getTime() : null;
|
|
304
|
+
if (!rotatedAt || Date.now() - rotatedAt > ROTATION_GRACE_MS) return false;
|
|
305
|
+
}
|
|
306
|
+
;
|
|
302
307
|
return {
|
|
303
308
|
client: { id: record.client },
|
|
304
309
|
refreshToken,
|
|
@@ -310,6 +315,15 @@ var createOAuthModel = ({ controller }) => ({
|
|
|
310
315
|
revokeToken: async (token) => {
|
|
311
316
|
const rawToken = token.refreshToken ?? token.accessToken;
|
|
312
317
|
const tokenHash = hashToken(rawToken);
|
|
318
|
+
await controller.update({
|
|
319
|
+
collection: "token",
|
|
320
|
+
data: {
|
|
321
|
+
$set: {
|
|
322
|
+
rotatedAt: /* @__PURE__ */ new Date()
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
query: { revoked: { $ne: true }, tokenHash }
|
|
326
|
+
});
|
|
313
327
|
await controller.update({
|
|
314
328
|
collection: "token",
|
|
315
329
|
data: {
|
|
@@ -407,6 +421,7 @@ var createClient = async ({
|
|
|
407
421
|
};
|
|
408
422
|
};
|
|
409
423
|
export {
|
|
424
|
+
ROTATION_GRACE_MS,
|
|
410
425
|
createClient,
|
|
411
426
|
createOAuthModel,
|
|
412
427
|
createOAuthServer
|
package/dist/pricing.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(pricing_exports, {
|
|
|
40
40
|
channels: () => channels,
|
|
41
41
|
conversionRate: () => conversionRate,
|
|
42
42
|
free: () => free,
|
|
43
|
+
numbers: () => numbers,
|
|
43
44
|
plans: () => plans,
|
|
44
45
|
resolvePlan: () => resolvePlan,
|
|
45
46
|
scrape: () => scrape,
|
|
@@ -883,6 +884,11 @@ var channels = {
|
|
|
883
884
|
includedInAllowance: false
|
|
884
885
|
}
|
|
885
886
|
};
|
|
887
|
+
var numbers = {
|
|
888
|
+
sms: {
|
|
889
|
+
monthlyCents: 500
|
|
890
|
+
}
|
|
891
|
+
};
|
|
886
892
|
// Annotate the CommonJS export names for ESM import in node:
|
|
887
893
|
0 && (module.exports = {
|
|
888
894
|
LOCAL_FLAT_CENTS,
|
|
@@ -896,6 +902,7 @@ var channels = {
|
|
|
896
902
|
channels,
|
|
897
903
|
conversionRate,
|
|
898
904
|
free,
|
|
905
|
+
numbers,
|
|
899
906
|
plans,
|
|
900
907
|
resolvePlan,
|
|
901
908
|
scrape,
|
package/dist/pricing.d.cts
CHANGED
|
@@ -189,4 +189,18 @@ const channels = {
|
|
|
189
189
|
}
|
|
190
190
|
};
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
// The dedicated SMS number — a RECURRING SUBSCRIPTION ITEM, not an action:
|
|
193
|
+
// the carrier bills for holding the number whether or not it sends, so it
|
|
194
|
+
// joins the organization's subscription as its own line and leaves when the
|
|
195
|
+
// number is released. CENTS per month, like every stored money value.
|
|
196
|
+
//
|
|
197
|
+
// The amount was not settled in the item-6 plan (only the mechanism was);
|
|
198
|
+
// $5 covers the ~$1.15 carrier cost with room for A2P registration fees.
|
|
199
|
+
// Changing it is this one line plus the matching Stripe Price.
|
|
200
|
+
const numbers = {
|
|
201
|
+
sms : {
|
|
202
|
+
monthlyCents : 500
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export { channels, numbers, sending };
|
package/dist/pricing.d.ts
CHANGED
|
@@ -189,4 +189,18 @@ const channels = {
|
|
|
189
189
|
}
|
|
190
190
|
};
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
// The dedicated SMS number — a RECURRING SUBSCRIPTION ITEM, not an action:
|
|
193
|
+
// the carrier bills for holding the number whether or not it sends, so it
|
|
194
|
+
// joins the organization's subscription as its own line and leaves when the
|
|
195
|
+
// number is released. CENTS per month, like every stored money value.
|
|
196
|
+
//
|
|
197
|
+
// The amount was not settled in the item-6 plan (only the mechanism was);
|
|
198
|
+
// $5 covers the ~$1.15 carrier cost with room for A2P registration fees.
|
|
199
|
+
// Changing it is this one line plus the matching Stripe Price.
|
|
200
|
+
const numbers = {
|
|
201
|
+
sms : {
|
|
202
|
+
monthlyCents : 500
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export { channels, numbers, sending };
|
package/dist/pricing.js
CHANGED
|
@@ -833,6 +833,11 @@ var channels = {
|
|
|
833
833
|
includedInAllowance: false
|
|
834
834
|
}
|
|
835
835
|
};
|
|
836
|
+
var numbers = {
|
|
837
|
+
sms: {
|
|
838
|
+
monthlyCents: 500
|
|
839
|
+
}
|
|
840
|
+
};
|
|
836
841
|
export {
|
|
837
842
|
LOCAL_FLAT_CENTS,
|
|
838
843
|
MARKUP,
|
|
@@ -845,6 +850,7 @@ export {
|
|
|
845
850
|
channels,
|
|
846
851
|
conversionRate,
|
|
847
852
|
free,
|
|
853
|
+
numbers,
|
|
848
854
|
plans,
|
|
849
855
|
resolvePlan,
|
|
850
856
|
scrape,
|
package/dist/twilio.cjs
CHANGED
|
@@ -113,7 +113,7 @@ var twilio = {
|
|
|
113
113
|
// body: PhoneNumber (E.164), SmsUrl, SmsMethod
|
|
114
114
|
// DELETE /2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{Sid}.json
|
|
115
115
|
// Basic auth throughout, like Messages.
|
|
116
|
-
searchNumbers: async ({ accountSid, areaCode, authToken, country = "US", limit = 10, request: request2 = request }) => {
|
|
116
|
+
searchNumbers: async ({ accountSid, areaCode, authToken, contains, country = "US", limit = 10, request: request2 = request }) => {
|
|
117
117
|
if (!accountSid || !authToken) throw new Error("Twilio credentials missing \u2014 accountSid, authToken");
|
|
118
118
|
const result = await request2({
|
|
119
119
|
method: "GET",
|
|
@@ -124,7 +124,11 @@ var twilio = {
|
|
|
124
124
|
query: {
|
|
125
125
|
SmsEnabled: true,
|
|
126
126
|
PageSize: limit,
|
|
127
|
-
...areaCode && { AreaCode: areaCode }
|
|
127
|
+
...areaCode && { AreaCode: areaCode },
|
|
128
|
+
// `Contains` is the vendor's matching-pattern filter — digits
|
|
129
|
+
// match anywhere in the number, so one search box serves "my
|
|
130
|
+
// area code" and "ends in 7777" alike.
|
|
131
|
+
...contains && { Contains: contains }
|
|
128
132
|
}
|
|
129
133
|
});
|
|
130
134
|
return ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
|
package/dist/twilio.d.cts
CHANGED
|
@@ -77,7 +77,7 @@ const twilio = {
|
|
|
77
77
|
// DELETE /2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{Sid}.json
|
|
78
78
|
// Basic auth throughout, like Messages.
|
|
79
79
|
|
|
80
|
-
searchNumbers : async ({ accountSid, areaCode, authToken, country = 'US', limit = 10, request: request$1 = request }) => {
|
|
80
|
+
searchNumbers : async ({ accountSid, areaCode, authToken, contains, country = 'US', limit = 10, request: request$1 = request }) => {
|
|
81
81
|
|
|
82
82
|
if( ! accountSid || ! authToken ) throw new Error( 'Twilio credentials missing — accountSid, authToken' );
|
|
83
83
|
|
|
@@ -90,7 +90,11 @@ const twilio = {
|
|
|
90
90
|
query : {
|
|
91
91
|
SmsEnabled : true,
|
|
92
92
|
PageSize : limit,
|
|
93
|
-
...( areaCode && { AreaCode : areaCode } )
|
|
93
|
+
...( areaCode && { AreaCode : areaCode } ),
|
|
94
|
+
// `Contains` is the vendor's matching-pattern filter — digits
|
|
95
|
+
// match anywhere in the number, so one search box serves "my
|
|
96
|
+
// area code" and "ends in 7777" alike.
|
|
97
|
+
...( contains && { Contains : contains } )
|
|
94
98
|
}
|
|
95
99
|
});
|
|
96
100
|
|
package/dist/twilio.d.ts
CHANGED
|
@@ -77,7 +77,7 @@ const twilio = {
|
|
|
77
77
|
// DELETE /2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{Sid}.json
|
|
78
78
|
// Basic auth throughout, like Messages.
|
|
79
79
|
|
|
80
|
-
searchNumbers : async ({ accountSid, areaCode, authToken, country = 'US', limit = 10, request: request$1 = request }) => {
|
|
80
|
+
searchNumbers : async ({ accountSid, areaCode, authToken, contains, country = 'US', limit = 10, request: request$1 = request }) => {
|
|
81
81
|
|
|
82
82
|
if( ! accountSid || ! authToken ) throw new Error( 'Twilio credentials missing — accountSid, authToken' );
|
|
83
83
|
|
|
@@ -90,7 +90,11 @@ const twilio = {
|
|
|
90
90
|
query : {
|
|
91
91
|
SmsEnabled : true,
|
|
92
92
|
PageSize : limit,
|
|
93
|
-
...( areaCode && { AreaCode : areaCode } )
|
|
93
|
+
...( areaCode && { AreaCode : areaCode } ),
|
|
94
|
+
// `Contains` is the vendor's matching-pattern filter — digits
|
|
95
|
+
// match anywhere in the number, so one search box serves "my
|
|
96
|
+
// area code" and "ends in 7777" alike.
|
|
97
|
+
...( contains && { Contains : contains } )
|
|
94
98
|
}
|
|
95
99
|
});
|
|
96
100
|
|
package/dist/twilio.js
CHANGED
|
@@ -88,7 +88,7 @@ var twilio = {
|
|
|
88
88
|
// body: PhoneNumber (E.164), SmsUrl, SmsMethod
|
|
89
89
|
// DELETE /2010-04-01/Accounts/{AccountSid}/IncomingPhoneNumbers/{Sid}.json
|
|
90
90
|
// Basic auth throughout, like Messages.
|
|
91
|
-
searchNumbers: async ({ accountSid, areaCode, authToken, country = "US", limit = 10, request: request2 = request }) => {
|
|
91
|
+
searchNumbers: async ({ accountSid, areaCode, authToken, contains, country = "US", limit = 10, request: request2 = request }) => {
|
|
92
92
|
if (!accountSid || !authToken) throw new Error("Twilio credentials missing \u2014 accountSid, authToken");
|
|
93
93
|
const result = await request2({
|
|
94
94
|
method: "GET",
|
|
@@ -99,7 +99,11 @@ var twilio = {
|
|
|
99
99
|
query: {
|
|
100
100
|
SmsEnabled: true,
|
|
101
101
|
PageSize: limit,
|
|
102
|
-
...areaCode && { AreaCode: areaCode }
|
|
102
|
+
...areaCode && { AreaCode: areaCode },
|
|
103
|
+
// `Contains` is the vendor's matching-pattern filter — digits
|
|
104
|
+
// match anywhere in the number, so one search box serves "my
|
|
105
|
+
// area code" and "ends in 7777" alike.
|
|
106
|
+
...contains && { Contains: contains }
|
|
103
107
|
}
|
|
104
108
|
});
|
|
105
109
|
return ((result == null ? void 0 : result.available_phone_numbers) || []).map((entry) => ({
|
package/package.json
CHANGED