@nopaque/sdk 0.7.0 → 0.8.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/CHANGELOG.md +35 -1
- package/README.md +25 -0
- package/dist/index.cjs +174 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +271 -1
- package/dist/index.d.ts +271 -1
- package/dist/index.mjs +174 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -91,7 +91,7 @@ function resolveConfig(opts) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// src/version.ts
|
|
94
|
-
var VERSION = true ? "0.
|
|
94
|
+
var VERSION = true ? "0.8.0" : "0.0.0-dev";
|
|
95
95
|
|
|
96
96
|
// src/userAgent.ts
|
|
97
97
|
function composeUserAgent() {
|
|
@@ -232,7 +232,7 @@ async function classifyResponse(response) {
|
|
|
232
232
|
body = null;
|
|
233
233
|
}
|
|
234
234
|
const bodyObj = body && typeof body === "object" ? body : {};
|
|
235
|
-
const message = typeof bodyObj.error === "string" ? bodyObj.error : `HTTP ${response.status}`;
|
|
235
|
+
const message = typeof bodyObj.error === "string" ? bodyObj.error : typeof bodyObj.message === "string" ? bodyObj.message : `HTTP ${response.status}`;
|
|
236
236
|
const code = typeof bodyObj.code === "string" ? bodyObj.code : null;
|
|
237
237
|
const details = bodyObj.details ?? null;
|
|
238
238
|
const requestId = response.headers.get("x-request-id");
|
|
@@ -1275,6 +1275,176 @@ var SchedulerResource = class extends Resource {
|
|
|
1275
1275
|
}
|
|
1276
1276
|
};
|
|
1277
1277
|
|
|
1278
|
+
// src/resources/surveys.ts
|
|
1279
|
+
var TERMINAL_CAPTURE = /* @__PURE__ */ new Set(["final", "failed"]);
|
|
1280
|
+
var DEFAULT_NOT_FOUND_GRACE = 6e4;
|
|
1281
|
+
var CAPTURE_GRACE = 6e5;
|
|
1282
|
+
var SurveyResultsResource = class extends Resource {
|
|
1283
|
+
/** Paginated list of result summaries, newest first. Transcripts are omitted. */
|
|
1284
|
+
list(params = {}, requestOptions) {
|
|
1285
|
+
return new Paginator({
|
|
1286
|
+
fetchPage: async (p) => {
|
|
1287
|
+
const { nextToken, cursor, ...rest } = p;
|
|
1288
|
+
const raw = await this.transport.request(
|
|
1289
|
+
"GET",
|
|
1290
|
+
"/testing/survey-results",
|
|
1291
|
+
{
|
|
1292
|
+
// `nextToken` first: the Paginator advances by writing it, and a
|
|
1293
|
+
// caller-supplied `cursor` would otherwise pin every page to page one.
|
|
1294
|
+
params: { ...rest, cursor: nextToken ?? cursor },
|
|
1295
|
+
requestOptions
|
|
1296
|
+
}
|
|
1297
|
+
);
|
|
1298
|
+
return {
|
|
1299
|
+
items: raw.results ?? raw.items ?? [],
|
|
1300
|
+
nextToken: raw.nextCursor ?? raw.nextToken ?? null
|
|
1301
|
+
};
|
|
1302
|
+
},
|
|
1303
|
+
params: { ...params }
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
/** One page of result summaries. */
|
|
1307
|
+
async listPage(params = {}, requestOptions) {
|
|
1308
|
+
const { nextToken, cursor, ...rest } = params;
|
|
1309
|
+
const raw = await this.transport.request("GET", "/testing/survey-results", {
|
|
1310
|
+
params: { ...rest, cursor: nextToken ?? cursor },
|
|
1311
|
+
requestOptions
|
|
1312
|
+
});
|
|
1313
|
+
return new Page(raw.results ?? raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* One result with its conversation. While the test is live the capture may be
|
|
1317
|
+
* `provisional` and still grow.
|
|
1318
|
+
*/
|
|
1319
|
+
async get(runId, requestOptions) {
|
|
1320
|
+
return await this.transport.request("GET", `/testing/survey-results/${runId}`, {
|
|
1321
|
+
requestOptions
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1325
|
+
var SurveyConfigsResource = class extends Resource {
|
|
1326
|
+
async create(body, requestOptions) {
|
|
1327
|
+
return await this.transport.request("POST", "/testing/survey-test-configs", {
|
|
1328
|
+
body,
|
|
1329
|
+
requestOptions
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
/** Every config in the workspace. Not paginated; `mission` and `acceptance` are omitted. */
|
|
1333
|
+
async list(requestOptions) {
|
|
1334
|
+
const raw = await this.transport.request(
|
|
1335
|
+
"GET",
|
|
1336
|
+
"/testing/survey-test-configs",
|
|
1337
|
+
{ requestOptions }
|
|
1338
|
+
);
|
|
1339
|
+
return raw.configs ?? [];
|
|
1340
|
+
}
|
|
1341
|
+
async get(configId, requestOptions) {
|
|
1342
|
+
return await this.transport.request("GET", `/testing/survey-test-configs/${configId}`, {
|
|
1343
|
+
requestOptions
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
/** PATCH - only the fields passed are sent. `null` clears `description`, `tags` or `voiceId`. */
|
|
1347
|
+
async update(configId, body, requestOptions) {
|
|
1348
|
+
return await this.transport.request("PATCH", `/testing/survey-test-configs/${configId}`, {
|
|
1349
|
+
body,
|
|
1350
|
+
requestOptions
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
/** Tests already started from the config are unaffected. */
|
|
1354
|
+
async delete(configId, requestOptions) {
|
|
1355
|
+
await this.transport.request("DELETE", `/testing/survey-test-configs/${configId}`, {
|
|
1356
|
+
requestOptions
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
var SurveysResource = class extends Resource {
|
|
1361
|
+
results;
|
|
1362
|
+
configs;
|
|
1363
|
+
constructor(transport) {
|
|
1364
|
+
super(transport);
|
|
1365
|
+
this.results = new SurveyResultsResource(transport);
|
|
1366
|
+
this.configs = new SurveyConfigsResource(transport);
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Start a survey test. Nothing runs yet: nopaque begins WAITING for a survey
|
|
1370
|
+
* sent from `sender` to the returned `agentE164`, until `expiresAt`.
|
|
1371
|
+
*
|
|
1372
|
+
* Throws `ConflictError` (409) when the workspace has no live survey numbers,
|
|
1373
|
+
* or when every one of them is already running a test against this sender -
|
|
1374
|
+
* the message tells the two apart. `NotFoundError` (404) for an unknown
|
|
1375
|
+
* config. A 503 means the number could not be put into service and nothing
|
|
1376
|
+
* was reserved; it is safe to try again, but this method does not.
|
|
1377
|
+
*/
|
|
1378
|
+
async start(params, requestOptions) {
|
|
1379
|
+
const { configId, sender, windowSecs, expectedTurns, maxMessages } = params;
|
|
1380
|
+
const body = {
|
|
1381
|
+
configId,
|
|
1382
|
+
endUserE164: sender,
|
|
1383
|
+
...windowSecs !== void 0 && { windowSecs },
|
|
1384
|
+
...expectedTurns !== void 0 && { expectedTurns },
|
|
1385
|
+
...maxMessages !== void 0 && { maxMessages }
|
|
1386
|
+
};
|
|
1387
|
+
return await this.transport.request("POST", "/testing/survey-runs", { body, requestOptions });
|
|
1388
|
+
}
|
|
1389
|
+
/** Stop a test before its window closes, freeing its number. */
|
|
1390
|
+
async stop(runId, requestOptions) {
|
|
1391
|
+
await this.transport.request("DELETE", `/testing/survey-runs/${runId}`, { requestOptions });
|
|
1392
|
+
}
|
|
1393
|
+
/** Every survey test holding a number, plus how many numbers are free. Not paginated. */
|
|
1394
|
+
async list(requestOptions) {
|
|
1395
|
+
return await this.transport.request("GET", "/testing/survey-runs", { requestOptions });
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Poll `results.get(runId)` until the capture is `final` or `failed`, and
|
|
1399
|
+
* return the result either way. A `failed` capture is a RESULT, not an error -
|
|
1400
|
+
* inspect `capture.error`.
|
|
1401
|
+
*
|
|
1402
|
+
* The result row is written asynchronously after `start()`, so a 404 is
|
|
1403
|
+
* treated as "not yet" for `notFoundGrace` and rethrown after that. Throws
|
|
1404
|
+
* `NopaqueTimeoutError` on the deadline; the test itself is NOT stopped.
|
|
1405
|
+
*/
|
|
1406
|
+
async waitForResult(runId, opts = {}) {
|
|
1407
|
+
const notFoundGrace = opts.notFoundGrace ?? DEFAULT_NOT_FOUND_GRACE;
|
|
1408
|
+
const started = Date.now();
|
|
1409
|
+
let deadline = started + (opts.timeout ?? notFoundGrace);
|
|
1410
|
+
let deadlineDerived = opts.timeout !== void 0;
|
|
1411
|
+
let step = 0;
|
|
1412
|
+
while (true) {
|
|
1413
|
+
let result;
|
|
1414
|
+
try {
|
|
1415
|
+
result = await this.results.get(runId, opts.requestOptions);
|
|
1416
|
+
} catch (err) {
|
|
1417
|
+
if (!(err instanceof NotFoundError) || Date.now() - started >= notFoundGrace) throw err;
|
|
1418
|
+
}
|
|
1419
|
+
if (result) {
|
|
1420
|
+
if (opts.onUpdate) {
|
|
1421
|
+
try {
|
|
1422
|
+
opts.onUpdate(result);
|
|
1423
|
+
} catch {
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
if (TERMINAL_CAPTURE.has(result.capture?.status)) return result;
|
|
1427
|
+
if (!deadlineDerived) {
|
|
1428
|
+
deadline = result.expiresAt * 1e3 + CAPTURE_GRACE;
|
|
1429
|
+
deadlineDerived = true;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const now = Date.now();
|
|
1433
|
+
if (now >= deadline) {
|
|
1434
|
+
throw new NopaqueTimeoutError(
|
|
1435
|
+
`waitForResult timed out after ${now - started}ms waiting for survey result ${runId}`
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
const interval = Math.min(
|
|
1439
|
+
pollIntervalCurve(step, { base: opts.pollInterval, cap: opts.intervalCap }),
|
|
1440
|
+
Math.max(0, deadline - now)
|
|
1441
|
+
);
|
|
1442
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
1443
|
+
step++;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1278
1448
|
// src/resources/sweeps.ts
|
|
1279
1449
|
var RUN_TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
1280
1450
|
var SweepsResource = class extends Resource {
|
|
@@ -1507,6 +1677,7 @@ var Nopaque = class {
|
|
|
1507
1677
|
digitalTesting;
|
|
1508
1678
|
digitalTestConfigs;
|
|
1509
1679
|
digitalCompliance;
|
|
1680
|
+
surveys;
|
|
1510
1681
|
transport;
|
|
1511
1682
|
constructor(options = {}) {
|
|
1512
1683
|
const config = resolveConfig(options);
|
|
@@ -1527,6 +1698,7 @@ var Nopaque = class {
|
|
|
1527
1698
|
this.digitalTesting = new DigitalTestingResource(this.transport);
|
|
1528
1699
|
this.digitalTestConfigs = new DigitalTestConfigsResource(this.transport);
|
|
1529
1700
|
this.digitalCompliance = new DigitalComplianceResource(this.transport);
|
|
1701
|
+
this.surveys = new SurveysResource(this.transport);
|
|
1530
1702
|
}
|
|
1531
1703
|
close() {
|
|
1532
1704
|
}
|