@nopaque/sdk 0.1.1 → 0.6.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.cjs CHANGED
@@ -133,7 +133,7 @@ function resolveConfig(opts) {
133
133
  }
134
134
 
135
135
  // src/version.ts
136
- var VERSION = true ? "0.1.1" : "0.0.0-dev";
136
+ var VERSION = true ? "0.6.0" : "0.0.0-dev";
137
137
 
138
138
  // src/userAgent.ts
139
139
  function composeUserAgent() {
@@ -491,7 +491,13 @@ var AudioResource = class extends Resource {
491
491
  const resolvedName = input.name ?? inferredName ?? "upload.bin";
492
492
  const resolvedType = input.contentType ?? sniffContentType(resolvedName);
493
493
  const presign = await this.createUploadUrl(
494
- { fileName: resolvedName, contentType: resolvedType },
494
+ {
495
+ filename: resolvedName,
496
+ contentType: resolvedType,
497
+ category: input.category,
498
+ ...input.associatedId && { associatedId: input.associatedId },
499
+ sizeBytes: bytes.byteLength
500
+ },
495
501
  requestOptions
496
502
  );
497
503
  await s3Put(presign.uploadUrl, bytes, {
@@ -616,6 +622,62 @@ var BatchesResource = class extends Resource {
616
622
  }
617
623
  };
618
624
 
625
+ // src/resources/compliance.ts
626
+ function encodePhone(phoneNumber) {
627
+ return encodeURIComponent(phoneNumber);
628
+ }
629
+ var ComplianceResource = class extends Resource {
630
+ async getCatalogue(params = {}, requestOptions) {
631
+ return await this.transport.request("GET", "/testing/compliance-catalogue", { params, requestOptions });
632
+ }
633
+ // Atomic batch dispatch. Server enforces compliancePickerLimits[tier] on
634
+ // testIds.length and returns 402 with code='BATCH_SIZE_EXCEEDS_TIER' on
635
+ // overflow. Surfaces as a typed NopaqueAPIError with code preserved.
636
+ async run(body, requestOptions) {
637
+ return await this.transport.request("POST", "/testing/compliance-runs", { body, requestOptions });
638
+ }
639
+ listReports(params = {}, requestOptions) {
640
+ return new Paginator({
641
+ fetchPage: async (p) => await this.transport.request("GET", "/testing/compliance-reports", { params: p, requestOptions }),
642
+ params: { ...params }
643
+ });
644
+ }
645
+ async listReportsPage(params = {}, requestOptions) {
646
+ const raw = await this.transport.request("GET", "/testing/compliance-reports", { params, requestOptions });
647
+ return new Page(raw.items, raw.nextToken);
648
+ }
649
+ async getReport(phoneNumber, requestOptions) {
650
+ return await this.transport.request(
651
+ "GET",
652
+ `/testing/compliance-reports/${encodePhone(phoneNumber)}`,
653
+ { requestOptions }
654
+ );
655
+ }
656
+ // Returns the presigned S3 URL the platform uploaded the PDF to. The 1 hour
657
+ // expiry is baked into the URL itself; the response body is `{ url }` only.
658
+ async generatePdfUrl(phoneNumber, body = {}, requestOptions) {
659
+ return await this.transport.request(
660
+ "POST",
661
+ `/testing/compliance-reports/${encodePhone(phoneNumber)}/pdf`,
662
+ { body, requestOptions }
663
+ );
664
+ }
665
+ // Convenience: get the URL, then fetch the bytes. For applications that
666
+ // already have an HTTP client, prefer generatePdfUrl() and fetch the URL
667
+ // with that client instead.
668
+ async downloadReportPdf(phoneNumber, body = {}, requestOptions) {
669
+ const { url } = await this.generatePdfUrl(phoneNumber, body, requestOptions);
670
+ const response = await this.transport.config.fetch(url);
671
+ if (!response.ok) {
672
+ throw new Error(`Failed to download PDF: ${response.status} ${response.statusText}`);
673
+ }
674
+ return new Uint8Array(await response.arrayBuffer());
675
+ }
676
+ async rerun(runId, requestOptions) {
677
+ return await this.transport.request("POST", `/testing/compliance-runs/${runId}/rerun`, { requestOptions });
678
+ }
679
+ };
680
+
619
681
  // src/resources/datasets.ts
620
682
  var DatasetsResource = class extends Resource {
621
683
  async create(body, requestOptions) {
@@ -648,6 +710,207 @@ var DatasetsResource = class extends Resource {
648
710
  }
649
711
  };
650
712
 
713
+ // src/resources/digitalCompliance.ts
714
+ var DigitalComplianceResource = class extends Resource {
715
+ /**
716
+ * List digital compliance audits, one entry per target.
717
+ *
718
+ * @beta Access is limited to beta workspaces during the beta period.
719
+ */
720
+ async listAudits(requestOptions) {
721
+ const raw = await this.transport.request(
722
+ "GET",
723
+ "/digital-testing/compliance-audits",
724
+ { requestOptions }
725
+ );
726
+ return raw.audits ?? [];
727
+ }
728
+ /**
729
+ * Compliance report for one digital target.
730
+ *
731
+ * `targetRef` goes in the QUERY STRING, not the path: a targetRef contains
732
+ * slashes (`acme/billing-bot`) and a single path segment cannot hold one. The
733
+ * API made the same choice for the same reason.
734
+ *
735
+ * Pass `{ sector }` to restrict the catalogue to tests applicable to that sector.
736
+ *
737
+ * @beta Access is limited to beta workspaces during the beta period.
738
+ */
739
+ async getReport(targetRef, params = {}, requestOptions) {
740
+ return await this.transport.request("GET", "/digital-testing/compliance-audits/report", {
741
+ params: { targetRef, ...params },
742
+ requestOptions
743
+ });
744
+ }
745
+ };
746
+
747
+ // src/resources/digitalTestConfigs.ts
748
+ var DigitalTestConfigsResource = class extends Resource {
749
+ /** @beta Access is limited to beta workspaces during the beta period. */
750
+ list(params = {}, requestOptions) {
751
+ return new Paginator({
752
+ fetchPage: async (p) => {
753
+ const { nextToken, cursor, ...rest } = p;
754
+ const raw = await this.transport.request(
755
+ "GET",
756
+ "/digital-testing/configs",
757
+ {
758
+ // `nextToken` first: the Paginator advances by writing it, and a
759
+ // caller-supplied `cursor` would otherwise pin every page to page one.
760
+ params: { ...rest, cursor: nextToken ?? cursor },
761
+ requestOptions
762
+ }
763
+ );
764
+ return {
765
+ items: raw.configs ?? raw.items ?? [],
766
+ nextToken: raw.nextCursor ?? raw.nextToken ?? null
767
+ };
768
+ },
769
+ params: { ...params }
770
+ });
771
+ }
772
+ /** @beta Access is limited to beta workspaces during the beta period. */
773
+ async listPage(params = {}, requestOptions) {
774
+ const { nextToken, cursor, ...rest } = params;
775
+ const raw = await this.transport.request("GET", "/digital-testing/configs", {
776
+ params: { ...rest, cursor: nextToken ?? cursor },
777
+ requestOptions
778
+ });
779
+ return new Page(raw.configs ?? raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
780
+ }
781
+ /**
782
+ * Save a digital test config. Per-kind rules are enforced at SAVE time, so a
783
+ * config that could never run is rejected with 400 rather than stored.
784
+ *
785
+ * @beta Access is limited to beta workspaces during the beta period.
786
+ */
787
+ async create(body, requestOptions) {
788
+ return await this.transport.request("POST", "/digital-testing/configs", {
789
+ body,
790
+ requestOptions
791
+ });
792
+ }
793
+ /** @beta Access is limited to beta workspaces during the beta period. */
794
+ async get(configId, requestOptions) {
795
+ return await this.transport.request("GET", `/digital-testing/configs/${configId}`, {
796
+ requestOptions
797
+ });
798
+ }
799
+ /** @beta Access is limited to beta workspaces during the beta period. */
800
+ async update(configId, body, requestOptions) {
801
+ return await this.transport.request("PATCH", `/digital-testing/configs/${configId}`, {
802
+ body,
803
+ requestOptions
804
+ });
805
+ }
806
+ /** @beta Access is limited to beta workspaces during the beta period. */
807
+ async delete(configId, requestOptions) {
808
+ await this.transport.request("DELETE", `/digital-testing/configs/${configId}`, {
809
+ requestOptions
810
+ });
811
+ }
812
+ /**
813
+ * Launch a run from a saved config. `target` and `targetRef` must be
814
+ * overridden together — a half-override is a 400.
815
+ *
816
+ * @beta Access is limited to beta workspaces during the beta period.
817
+ */
818
+ async launch(configId, body = {}, requestOptions) {
819
+ const raw = await this.transport.request("POST", `/digital-testing/configs/${configId}/runs`, { body, requestOptions });
820
+ return raw.run ?? raw;
821
+ }
822
+ };
823
+
824
+ // src/resources/digitalTesting.ts
825
+ var TERMINAL = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
826
+ var DigitalTestingResource = class extends Resource {
827
+ /**
828
+ * Queue a digital test run.
829
+ *
830
+ * @beta Access is limited to beta workspaces during the beta period.
831
+ */
832
+ async create(body, requestOptions) {
833
+ const raw = await this.transport.request("POST", "/digital-testing/runs", { body, requestOptions });
834
+ return raw.run ?? raw;
835
+ }
836
+ /**
837
+ * Paginated list of digital test runs, newest first.
838
+ *
839
+ * @beta Access is limited to beta workspaces during the beta period.
840
+ */
841
+ list(params = {}, requestOptions) {
842
+ return new Paginator({
843
+ fetchPage: async (p) => {
844
+ const { nextToken, cursor, ...rest } = p;
845
+ const raw = await this.transport.request("GET", "/digital-testing/runs", {
846
+ // `nextToken` first: the Paginator advances by writing it, and a
847
+ // caller-supplied `cursor` would otherwise pin every page to page one.
848
+ params: { ...rest, cursor: nextToken ?? cursor },
849
+ requestOptions
850
+ });
851
+ return {
852
+ items: raw.runs ?? raw.items ?? [],
853
+ nextToken: raw.nextCursor ?? raw.nextToken ?? null
854
+ };
855
+ },
856
+ params: { ...params }
857
+ });
858
+ }
859
+ /**
860
+ * One page of digital test runs.
861
+ *
862
+ * @beta Access is limited to beta workspaces during the beta period.
863
+ */
864
+ async listPage(params = {}, requestOptions) {
865
+ const { nextToken, cursor, ...rest } = params;
866
+ const raw = await this.transport.request("GET", "/digital-testing/runs", {
867
+ params: { ...rest, cursor: nextToken ?? cursor },
868
+ requestOptions
869
+ });
870
+ return new Page(raw.runs ?? raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
871
+ }
872
+ /**
873
+ * Get one digital test run.
874
+ *
875
+ * @beta Access is limited to beta workspaces during the beta period.
876
+ */
877
+ async get(runId, requestOptions) {
878
+ return await this.transport.request("GET", `/digital-testing/runs/${runId}`, {
879
+ requestOptions
880
+ });
881
+ }
882
+ /**
883
+ * Cancel a digital test run.
884
+ *
885
+ * @beta Access is limited to beta workspaces during the beta period.
886
+ */
887
+ async cancel(runId, requestOptions) {
888
+ return await this.transport.request("POST", `/digital-testing/runs/${runId}/cancel`, {
889
+ requestOptions
890
+ });
891
+ }
892
+ /**
893
+ * Poll until the run reaches a terminal state.
894
+ *
895
+ * Resolves on `completed`, `failed` and `cancelled` alike and returns the run.
896
+ * A bot that behaved badly is `completed` with `outcome: 'fail'`, which is a
897
+ * RESULT, not an error — this never throws on it. `failed` means the test could
898
+ * not be delivered.
899
+ *
900
+ * @beta Access is limited to beta workspaces during the beta period.
901
+ */
902
+ async waitForRun(runId, opts = {}) {
903
+ return await waitFor({
904
+ fetch: () => this.get(runId, opts.requestOptions),
905
+ isTerminal: (r) => TERMINAL.has(r.status),
906
+ timeout: opts.timeout,
907
+ initialInterval: opts.pollInterval,
908
+ intervalCap: opts.intervalCap,
909
+ onUpdate: opts.onUpdate
910
+ });
911
+ }
912
+ };
913
+
651
914
  // src/resources/enrichment.ts
652
915
  var EnrichmentResource = class extends Resource {
653
916
  async get(jobId, runId, type, requestOptions) {
@@ -762,17 +1025,24 @@ var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "limite
762
1025
  var MappingResource = class extends Resource {
763
1026
  list(params = {}, requestOptions) {
764
1027
  return new Paginator({
765
- fetchPage: async (p) => await this.transport.request("GET", "/mapping", { params: p, requestOptions }),
1028
+ fetchPage: async (p) => {
1029
+ const { nextToken, cursor, ...rest } = p;
1030
+ const raw = await this.transport.request("GET", "/mapping", {
1031
+ params: { ...rest, cursor: cursor ?? nextToken },
1032
+ requestOptions
1033
+ });
1034
+ return { items: raw.items ?? [], nextToken: raw.nextCursor ?? raw.nextToken ?? null };
1035
+ },
766
1036
  params: { ...params }
767
1037
  });
768
1038
  }
769
1039
  async listPage(params = {}, requestOptions) {
770
- const raw = await this.transport.request(
771
- "GET",
772
- "/mapping",
773
- { params, requestOptions }
774
- );
775
- return new Page(raw.items, raw.nextToken);
1040
+ const { nextToken, cursor, ...rest } = params;
1041
+ const raw = await this.transport.request("GET", "/mapping", {
1042
+ params: { ...rest, cursor: cursor ?? nextToken },
1043
+ requestOptions
1044
+ });
1045
+ return new Page(raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
776
1046
  }
777
1047
  async get(jobId, requestOptions) {
778
1048
  return await this.transport.request("GET", `/mapping/${jobId}`, { requestOptions });
@@ -798,6 +1068,16 @@ var MappingResource = class extends Resource {
798
1068
  requestOptions
799
1069
  });
800
1070
  }
1071
+ // Trigger on-demand security-probe analysis on a completed mapping run.
1072
+ // Returns the queue summary { message, probeCount }; poll the run / steps
1073
+ // afterwards to see classified results land.
1074
+ async probe(jobId, runId, requestOptions) {
1075
+ return await this.transport.request(
1076
+ "POST",
1077
+ `/mapping/${jobId}/runs/${runId}/probe`,
1078
+ { requestOptions }
1079
+ );
1080
+ }
801
1081
  steps(jobId, params = {}, requestOptions) {
802
1082
  return new Paginator({
803
1083
  fetchPage: async (p) => await this.transport.request("GET", `/mapping/${jobId}/steps`, {
@@ -854,13 +1134,6 @@ var MappingResource = class extends Resource {
854
1134
  { requestOptions }
855
1135
  );
856
1136
  }
857
- async probe(jobId, runId, body = {}, requestOptions) {
858
- return await this.transport.request(
859
- "POST",
860
- `/mapping/${jobId}/runs/${runId}/probe`,
861
- { body, requestOptions }
862
- );
863
- }
864
1137
  async waitForComplete(jobId, opts = {}) {
865
1138
  return await waitFor({
866
1139
  fetch: () => this.get(jobId, opts.requestOptions),
@@ -873,6 +1146,83 @@ var MappingResource = class extends Resource {
873
1146
  }
874
1147
  };
875
1148
 
1149
+ // src/resources/missionTestConfigs.ts
1150
+ var MissionTestConfigsResource = class extends Resource {
1151
+ list(params = {}, requestOptions) {
1152
+ return new Paginator({
1153
+ fetchPage: async (p) => {
1154
+ const { nextToken, cursor, ...rest } = p;
1155
+ const raw = await this.transport.request("GET", "/testing/mission-test-configs", {
1156
+ params: { ...rest, cursor: cursor ?? nextToken },
1157
+ requestOptions
1158
+ });
1159
+ return { items: raw.items ?? [], nextToken: raw.nextCursor ?? raw.nextToken ?? null };
1160
+ },
1161
+ params: { ...params }
1162
+ });
1163
+ }
1164
+ async listPage(params = {}, requestOptions) {
1165
+ const { nextToken, cursor, ...rest } = params;
1166
+ const raw = await this.transport.request("GET", "/testing/mission-test-configs", {
1167
+ params: { ...rest, cursor: cursor ?? nextToken },
1168
+ requestOptions
1169
+ });
1170
+ return new Page(raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
1171
+ }
1172
+ async create(body, requestOptions) {
1173
+ return await this.transport.request("POST", "/testing/mission-test-configs", { body, requestOptions });
1174
+ }
1175
+ async get(id, requestOptions) {
1176
+ return await this.transport.request("GET", `/testing/mission-test-configs/${id}`, { requestOptions });
1177
+ }
1178
+ async update(id, body, requestOptions) {
1179
+ return await this.transport.request("PATCH", `/testing/mission-test-configs/${id}`, {
1180
+ body,
1181
+ requestOptions
1182
+ });
1183
+ }
1184
+ async delete(id, requestOptions) {
1185
+ await this.transport.request("DELETE", `/testing/mission-test-configs/${id}`, { requestOptions });
1186
+ }
1187
+ // Launch a mission test run from a saved config. The returned run is freeform-shaped.
1188
+ async run(id, requestOptions) {
1189
+ return await this.transport.request("POST", `/testing/mission-test-configs/${id}/runs`, { requestOptions });
1190
+ }
1191
+ };
1192
+
1193
+ // src/resources/missionTests.ts
1194
+ var MissionTestsResource = class extends Resource {
1195
+ list(params = {}, requestOptions) {
1196
+ return new Paginator({
1197
+ fetchPage: async (p) => await this.transport.request("GET", "/testing/mission-tests", { params: p, requestOptions }),
1198
+ params: { ...params }
1199
+ });
1200
+ }
1201
+ async listPage(params = {}, requestOptions) {
1202
+ const raw = await this.transport.request(
1203
+ "GET",
1204
+ "/testing/mission-tests",
1205
+ { params, requestOptions }
1206
+ );
1207
+ return new Page(raw.items, raw.nextToken);
1208
+ }
1209
+ async create(body, requestOptions) {
1210
+ return await this.transport.request("POST", "/testing/mission-tests", { body, requestOptions });
1211
+ }
1212
+ // Returns 503 with code='CATALOG_NOT_READY' until the mission-tester service
1213
+ // publishes its SSM payload. Callers can catch and retry, or fall back to a
1214
+ // known-good default sector/mission/acceptance.
1215
+ async getDefaults(requestOptions) {
1216
+ return await this.transport.request("GET", "/testing/mission-tests/defaults", { requestOptions });
1217
+ }
1218
+ async get(id, requestOptions) {
1219
+ return await this.transport.request("GET", `/testing/mission-tests/${id}`, { requestOptions });
1220
+ }
1221
+ async cancel(id, requestOptions) {
1222
+ return await this.transport.request("POST", `/testing/mission-tests/${id}/cancel`, { requestOptions });
1223
+ }
1224
+ };
1225
+
876
1226
  // src/resources/profiles.ts
877
1227
  var ProfilesResource = class extends Resource {
878
1228
  async create(body, requestOptions) {
@@ -910,8 +1260,9 @@ var ProfilesResource = class extends Resource {
910
1260
  requestOptions
911
1261
  });
912
1262
  }
1263
+ /** Returns the updated profile, as all three item routes do. */
913
1264
  async deleteItem(profileId, itemId, requestOptions) {
914
- await this.transport.request(
1265
+ return await this.transport.request(
915
1266
  "DELETE",
916
1267
  `/profiles/${profileId}/items/${itemId}`,
917
1268
  { requestOptions }
@@ -1103,15 +1454,33 @@ var TestingRunsResource = class extends Resource {
1103
1454
  list(params = {}, requestOptions) {
1104
1455
  return new Paginator({
1105
1456
  fetchPage: async (p) => {
1106
- const raw = await this.transport.request("GET", "/testing/runs", { params: p, requestOptions });
1107
- return { items: raw.runs ?? raw.items ?? [], nextToken: null };
1457
+ const { nextToken, cursor, ...rest } = p;
1458
+ const raw = await this.transport.request("GET", "/testing/runs", {
1459
+ params: { ...rest, cursor: cursor ?? nextToken },
1460
+ requestOptions
1461
+ });
1462
+ return {
1463
+ items: raw.runs ?? raw.items ?? [],
1464
+ nextToken: raw.nextCursor ?? raw.nextToken ?? null
1465
+ };
1108
1466
  },
1109
1467
  params: { ...params }
1110
1468
  });
1111
1469
  }
1112
1470
  async listPage(params = {}, requestOptions) {
1113
- const raw = await this.transport.request("GET", "/testing/runs", { params, requestOptions });
1114
- return new Page(raw.runs ?? raw.items ?? [], raw.nextToken ?? null);
1471
+ const { nextToken, cursor, ...rest } = params;
1472
+ const raw = await this.transport.request("GET", "/testing/runs", {
1473
+ params: { ...rest, cursor: cursor ?? nextToken },
1474
+ requestOptions
1475
+ });
1476
+ return new Page(raw.runs ?? raw.items ?? [], raw.nextCursor ?? raw.nextToken ?? null);
1477
+ }
1478
+ /** GET /testing/runs/aggregate — grouped counts over test runs. */
1479
+ async aggregate(params, requestOptions) {
1480
+ return await this.transport.request("GET", "/testing/runs/aggregate", {
1481
+ params,
1482
+ requestOptions
1483
+ });
1115
1484
  }
1116
1485
  async get(runId, requestOptions) {
1117
1486
  return await this.transport.request("GET", `/testing/runs/${runId}`, { requestOptions });
@@ -1137,6 +1506,24 @@ var TestingResource = class extends Resource {
1137
1506
  this.jobs = new TestingJobsResource(transport);
1138
1507
  this.runs = new TestingRunsResource(transport);
1139
1508
  }
1509
+ /** Paginated, filtered list of test runs (alias for `testing.runs.list()`). */
1510
+ listRuns(params = {}, requestOptions) {
1511
+ return this.runs.list(params, requestOptions);
1512
+ }
1513
+ /** GET /testing/voices — operator-enabled voices a mission test may use. */
1514
+ async listVoices(requestOptions) {
1515
+ return await this.transport.request("GET", "/testing/voices", { requestOptions });
1516
+ }
1517
+ /** GET /testing/runs/aggregate — grouped counts over test runs. */
1518
+ async aggregateRuns(params, requestOptions) {
1519
+ return await this.runs.aggregate(params, requestOptions);
1520
+ }
1521
+ /** GET /testing/mission-test-runs/{id} — mission-strict run detail (no steps). */
1522
+ async getMissionTestRun(id, requestOptions) {
1523
+ return await this.transport.request("GET", `/testing/mission-test-runs/${id}`, {
1524
+ requestOptions
1525
+ });
1526
+ }
1140
1527
  };
1141
1528
 
1142
1529
  // src/client.ts
@@ -1151,6 +1538,12 @@ var Nopaque = class {
1151
1538
  loadTesting;
1152
1539
  scheduler;
1153
1540
  enrichment;
1541
+ missionTests;
1542
+ missionTestConfigs;
1543
+ compliance;
1544
+ digitalTesting;
1545
+ digitalTestConfigs;
1546
+ digitalCompliance;
1154
1547
  transport;
1155
1548
  constructor(options = {}) {
1156
1549
  const config = resolveConfig(options);
@@ -1165,6 +1558,12 @@ var Nopaque = class {
1165
1558
  this.loadTesting = new LoadTestingResource(this.transport);
1166
1559
  this.scheduler = new SchedulerResource(this.transport);
1167
1560
  this.enrichment = new EnrichmentResource(this.transport);
1561
+ this.missionTests = new MissionTestsResource(this.transport);
1562
+ this.missionTestConfigs = new MissionTestConfigsResource(this.transport);
1563
+ this.compliance = new ComplianceResource(this.transport);
1564
+ this.digitalTesting = new DigitalTestingResource(this.transport);
1565
+ this.digitalTestConfigs = new DigitalTestConfigsResource(this.transport);
1566
+ this.digitalCompliance = new DigitalComplianceResource(this.transport);
1168
1567
  }
1169
1568
  close() {
1170
1569
  }