@ayurak/sdk 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/dist/index.mjs ADDED
@@ -0,0 +1,750 @@
1
+ // src/errors.ts
2
+ var AribotError = class extends Error {
3
+ constructor(message, statusCode, response) {
4
+ super(message);
5
+ this.name = "AribotError";
6
+ this.statusCode = statusCode;
7
+ this.response = response;
8
+ }
9
+ };
10
+ var AuthenticationError = class extends AribotError {
11
+ constructor(message, statusCode, response) {
12
+ super(message, statusCode, response);
13
+ this.name = "AuthenticationError";
14
+ }
15
+ };
16
+ var RateLimitError = class extends AribotError {
17
+ constructor(message, retryAfter, statusCode, response) {
18
+ super(message, statusCode, response);
19
+ this.name = "RateLimitError";
20
+ this.retryAfter = retryAfter;
21
+ }
22
+ };
23
+ var ValidationError = class extends AribotError {
24
+ constructor(message, errors = [], statusCode, response) {
25
+ super(message, statusCode, response);
26
+ this.name = "ValidationError";
27
+ this.errors = errors;
28
+ }
29
+ };
30
+ var NotFoundError = class extends AribotError {
31
+ constructor(message, statusCode, response) {
32
+ super(message, statusCode, response);
33
+ this.name = "NotFoundError";
34
+ }
35
+ };
36
+ var ServerError = class extends AribotError {
37
+ constructor(message, statusCode, response) {
38
+ super(message, statusCode, response);
39
+ this.name = "ServerError";
40
+ }
41
+ };
42
+
43
+ // src/http.ts
44
+ var DEFAULT_BASE_URL = "https://api.aribot.ayurak.com/aribot-api";
45
+ var DEFAULT_TIMEOUT = 3e4;
46
+ var MAX_RETRIES = 3;
47
+ function sleep(ms) {
48
+ return new Promise((resolve) => setTimeout(resolve, ms));
49
+ }
50
+ var HttpClient = class {
51
+ constructor(options) {
52
+ this.apiKey = options.apiKey;
53
+ this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
54
+ this.timeout = options.timeout || DEFAULT_TIMEOUT;
55
+ }
56
+ async handleResponse(response) {
57
+ let data = {};
58
+ try {
59
+ const text = await response.text();
60
+ if (text) {
61
+ data = JSON.parse(text);
62
+ }
63
+ } catch {
64
+ data = {};
65
+ }
66
+ if (response.status === 401) {
67
+ throw new AuthenticationError(
68
+ data.detail || "Invalid API key",
69
+ 401,
70
+ data
71
+ );
72
+ }
73
+ if (response.status === 403) {
74
+ throw new AuthenticationError(
75
+ data.detail || "Access denied",
76
+ 403,
77
+ data
78
+ );
79
+ }
80
+ if (response.status === 404) {
81
+ throw new NotFoundError(
82
+ data.detail || "Resource not found",
83
+ 404,
84
+ data
85
+ );
86
+ }
87
+ if (response.status === 422) {
88
+ throw new ValidationError(
89
+ data.detail || "Validation error",
90
+ data.errors || [],
91
+ 422,
92
+ data
93
+ );
94
+ }
95
+ if (response.status === 429) {
96
+ const retryAfter = response.headers.get("Retry-After");
97
+ throw new RateLimitError(
98
+ data.detail || "Rate limit exceeded",
99
+ retryAfter ? parseInt(retryAfter, 10) : void 0,
100
+ 429,
101
+ data
102
+ );
103
+ }
104
+ if (response.status >= 500) {
105
+ throw new ServerError(
106
+ data.detail || "Server error",
107
+ response.status,
108
+ data
109
+ );
110
+ }
111
+ if (response.status >= 400) {
112
+ throw new AribotError(
113
+ data.detail || `Request failed with status ${response.status}`,
114
+ response.status,
115
+ data
116
+ );
117
+ }
118
+ return data;
119
+ }
120
+ async request(method, path, options = {}, retry = 0) {
121
+ const url = new URL(path, this.baseUrl);
122
+ if (options.params) {
123
+ for (const [key, value] of Object.entries(options.params)) {
124
+ url.searchParams.set(key, String(value));
125
+ }
126
+ }
127
+ const headers = {
128
+ "X-API-Key": this.apiKey,
129
+ "User-Agent": "aribot-js/1.0.0"
130
+ };
131
+ let body;
132
+ if (options.formData) {
133
+ body = options.formData;
134
+ } else if (options.body) {
135
+ headers["Content-Type"] = "application/json";
136
+ body = JSON.stringify(options.body);
137
+ }
138
+ const controller = new AbortController();
139
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
140
+ try {
141
+ const response = await fetch(url.toString(), {
142
+ method,
143
+ headers,
144
+ body,
145
+ signal: controller.signal
146
+ });
147
+ clearTimeout(timeoutId);
148
+ return await this.handleResponse(response);
149
+ } catch (error) {
150
+ clearTimeout(timeoutId);
151
+ if (error instanceof RateLimitError) {
152
+ if (retry < MAX_RETRIES && error.retryAfter) {
153
+ await sleep(Math.min(error.retryAfter * 1e3, 6e4));
154
+ return this.request(method, path, options, retry + 1);
155
+ }
156
+ throw error;
157
+ }
158
+ if (error instanceof AribotError) {
159
+ throw error;
160
+ }
161
+ if (error instanceof Error && error.name === "AbortError") {
162
+ if (retry < MAX_RETRIES) {
163
+ await sleep(Math.pow(2, retry) * 1e3);
164
+ return this.request(method, path, options, retry + 1);
165
+ }
166
+ throw new AribotError("Request timed out");
167
+ }
168
+ if (retry < MAX_RETRIES) {
169
+ await sleep(Math.pow(2, retry) * 1e3);
170
+ return this.request(method, path, options, retry + 1);
171
+ }
172
+ throw new AribotError("Connection error");
173
+ }
174
+ }
175
+ async get(path, params) {
176
+ return this.request("GET", path, { params });
177
+ }
178
+ async post(path, body, formData) {
179
+ return this.request("POST", path, { body, formData });
180
+ }
181
+ async put(path, body) {
182
+ return this.request("PUT", path, { body });
183
+ }
184
+ async patch(path, body) {
185
+ return this.request("PATCH", path, { body });
186
+ }
187
+ async delete(path) {
188
+ return this.request("DELETE", path);
189
+ }
190
+ };
191
+
192
+ // src/threat-modeling.ts
193
+ function sleep2(ms) {
194
+ return new Promise((resolve) => setTimeout(resolve, ms));
195
+ }
196
+ var ThreatModelingAPI = class {
197
+ constructor(http) {
198
+ this.http = http;
199
+ }
200
+ /**
201
+ * Upload and analyze a diagram for threats
202
+ */
203
+ async analyzeDiagram(file, options = {}) {
204
+ const {
205
+ filename = "diagram",
206
+ analysisDepth = "comprehensive",
207
+ wait = true,
208
+ timeout = 3e5
209
+ } = options;
210
+ const formData = new FormData();
211
+ formData.append("file", file, filename);
212
+ formData.append("filename", filename);
213
+ formData.append("analysis_depth", analysisDepth);
214
+ const result = await this.http.post(
215
+ "/v2/threat-modeling/diagrams/upload-and-analyze/",
216
+ void 0,
217
+ formData
218
+ );
219
+ if (!wait) {
220
+ return result;
221
+ }
222
+ const diagramId = result.diagram_id;
223
+ if (!diagramId) {
224
+ return result;
225
+ }
226
+ return this.waitForAnalysis(diagramId, timeout);
227
+ }
228
+ async waitForAnalysis(diagramId, timeout) {
229
+ const start = Date.now();
230
+ while (Date.now() - start < timeout) {
231
+ const diagram = await this.get(diagramId);
232
+ const status = diagram.status;
233
+ if (["completed", "analyzed", "done"].includes(status)) {
234
+ return diagram;
235
+ }
236
+ if (["failed", "error"].includes(status)) {
237
+ throw new Error(`Analysis failed: ${diagram.error || "Unknown error"}`);
238
+ }
239
+ await sleep2(5e3);
240
+ }
241
+ throw new Error(`Analysis did not complete within ${timeout}ms`);
242
+ }
243
+ /**
244
+ * List diagrams
245
+ */
246
+ async list(options = {}) {
247
+ const { page = 1, limit = 25, status, search } = options;
248
+ const params = { page, limit };
249
+ if (status) params.status = status;
250
+ if (search) params.search = search;
251
+ return await this.http.get("/v1/tm/diagrams/", params);
252
+ }
253
+ /**
254
+ * Get diagram details
255
+ */
256
+ async get(diagramId) {
257
+ return await this.http.get(`/v1/tm/diagrams/${diagramId}/`);
258
+ }
259
+ /**
260
+ * Get threats for a diagram
261
+ */
262
+ async getThreats(diagramId) {
263
+ const result = await this.http.get(`/v1/tm/diagrams/${diagramId}/threats/`);
264
+ if (Array.isArray(result)) {
265
+ return result;
266
+ }
267
+ const data = result;
268
+ return data.results || data.threats || [];
269
+ }
270
+ /**
271
+ * Get components detected in diagram
272
+ */
273
+ async getComponents(diagramId) {
274
+ const result = await this.http.get(`/v1/tm/diagrams/${diagramId}/components/`);
275
+ if (Array.isArray(result)) {
276
+ return result;
277
+ }
278
+ const data = result;
279
+ return data.results || data.components || [];
280
+ }
281
+ /**
282
+ * Run AI-powered analysis on diagram
283
+ */
284
+ async analyzeWithAI(diagramId, analysisTypes) {
285
+ const body = {};
286
+ if (analysisTypes) {
287
+ body.analysis_types = analysisTypes;
288
+ }
289
+ return await this.http.post(
290
+ `/v2/threat-modeling/diagrams/${diagramId}/analyze-with-ai/`,
291
+ body
292
+ );
293
+ }
294
+ /**
295
+ * Delete a diagram
296
+ */
297
+ async delete(diagramId) {
298
+ await this.http.delete(`/v1/tm/diagrams/${diagramId}/`);
299
+ }
300
+ /**
301
+ * Get threat modeling dashboard
302
+ */
303
+ async dashboard(period = "month", includeTrends = true) {
304
+ return await this.http.get("/v1/tm/dashboard/", {
305
+ period,
306
+ include_trends: includeTrends
307
+ });
308
+ }
309
+ };
310
+
311
+ // src/compliance.ts
312
+ var ComplianceAPI = class {
313
+ constructor(http) {
314
+ this.http = http;
315
+ }
316
+ /**
317
+ * Run compliance scan on a diagram
318
+ */
319
+ async scan(diagramId, options = {}) {
320
+ const { standards, includeRecommendations = true } = options;
321
+ const body = {
322
+ include_recommendations: includeRecommendations
323
+ };
324
+ if (standards) {
325
+ body.standards = standards;
326
+ }
327
+ return await this.http.post(
328
+ `/v2/compliances/diagram-compliance/${diagramId}/scan/`,
329
+ body
330
+ );
331
+ }
332
+ /**
333
+ * Get compliance report for a diagram
334
+ */
335
+ async getReport(diagramId, format = "json") {
336
+ return await this.http.get(
337
+ `/v2/compliances/diagram-compliance/${diagramId}/report/`,
338
+ { format }
339
+ );
340
+ }
341
+ /**
342
+ * List available compliance standards
343
+ */
344
+ async listStandards() {
345
+ const result = await this.http.get("/v2/compliances/standards/");
346
+ if (Array.isArray(result)) {
347
+ return result;
348
+ }
349
+ const data = result;
350
+ return data.results || data.standards || [];
351
+ }
352
+ /**
353
+ * Get details of a compliance standard
354
+ */
355
+ async getStandard(standardId) {
356
+ return await this.http.get(
357
+ `/v2/compliances/standards/${standardId}/`
358
+ );
359
+ }
360
+ /**
361
+ * List controls for a compliance standard
362
+ */
363
+ async listControls(standardId, category) {
364
+ const params = {};
365
+ if (category) params.category = category;
366
+ const result = await this.http.get(
367
+ `/v2/compliances/standards/${standardId}/controls/`,
368
+ params
369
+ );
370
+ if (Array.isArray(result)) {
371
+ return result;
372
+ }
373
+ const data = result;
374
+ return data.results || data.controls || [];
375
+ }
376
+ /**
377
+ * Get compliance gaps for a diagram
378
+ */
379
+ async getGaps(diagramId, standardId) {
380
+ const params = {};
381
+ if (standardId) params.standard = standardId;
382
+ const result = await this.http.get(
383
+ `/v2/compliances/diagram-compliance/${diagramId}/gaps/`,
384
+ params
385
+ );
386
+ if (Array.isArray(result)) {
387
+ return result;
388
+ }
389
+ const data = result;
390
+ return data.results || data.gaps || [];
391
+ }
392
+ /**
393
+ * Create a custom compliance standard
394
+ */
395
+ async addCustomStandard(name, description, controls) {
396
+ return await this.http.post("/v2/compliances/standards/", {
397
+ name,
398
+ description,
399
+ controls
400
+ });
401
+ }
402
+ /**
403
+ * Get compliance dashboard metrics
404
+ */
405
+ async dashboard(period = "month") {
406
+ return await this.http.get("/v2/compliances/dashboard/", {
407
+ period
408
+ });
409
+ }
410
+ };
411
+
412
+ // src/cloud.ts
413
+ var CloudSecurityAPI = class {
414
+ constructor(http) {
415
+ this.http = http;
416
+ }
417
+ /**
418
+ * Run cloud security scan
419
+ */
420
+ async scan(projectId, options = {}) {
421
+ const body = { project_id: projectId };
422
+ if (options.provider) body.provider = options.provider;
423
+ if (options.regions) body.regions = options.regions;
424
+ if (options.services) body.services = options.services;
425
+ if (options.complianceStandards) body.compliance_standards = options.complianceStandards;
426
+ return await this.http.post("/v2/cloud-security/scans/", body);
427
+ }
428
+ /**
429
+ * Get scan details and results
430
+ */
431
+ async getScan(scanId) {
432
+ return await this.http.get(`/v2/cloud-security/scans/${scanId}/`);
433
+ }
434
+ /**
435
+ * List cloud security scans
436
+ */
437
+ async listScans(options = {}) {
438
+ const { projectId, provider, status, page = 1, limit = 25 } = options;
439
+ const params = { page, limit };
440
+ if (projectId) params.project_id = projectId;
441
+ if (provider) params.provider = provider;
442
+ if (status) params.status = status;
443
+ return await this.http.get("/v2/cloud-security/scans/", params);
444
+ }
445
+ /**
446
+ * Get findings from a scan
447
+ */
448
+ async getFindings(scanId, options = {}) {
449
+ const { severity, service, status } = options;
450
+ const params = {};
451
+ if (severity) params.severity = severity;
452
+ if (service) params.service = service;
453
+ if (status) params.status = status;
454
+ const result = await this.http.get(`/v2/cloud-security/scans/${scanId}/findings/`, params);
455
+ if (Array.isArray(result)) {
456
+ return result;
457
+ }
458
+ const data = result;
459
+ return data.results || data.findings || [];
460
+ }
461
+ /**
462
+ * Connect a cloud account for scanning
463
+ */
464
+ async connectAccount(provider, credentials, options = {}) {
465
+ const body = {
466
+ provider,
467
+ credentials
468
+ };
469
+ if (options.name) body.name = options.name;
470
+ if (options.regions) body.regions = options.regions;
471
+ return await this.http.post("/v2/cloud-security/accounts/", body);
472
+ }
473
+ /**
474
+ * List connected cloud accounts
475
+ */
476
+ async listAccounts(provider) {
477
+ const params = {};
478
+ if (provider) params.provider = provider;
479
+ const result = await this.http.get("/v2/cloud-security/accounts/", params);
480
+ if (Array.isArray(result)) {
481
+ return result;
482
+ }
483
+ const data = result;
484
+ return data.results || data.accounts || [];
485
+ }
486
+ /**
487
+ * Disconnect a cloud account
488
+ */
489
+ async deleteAccount(accountId) {
490
+ await this.http.delete(`/v2/cloud-security/accounts/${accountId}/`);
491
+ }
492
+ /**
493
+ * Mark a finding as resolved
494
+ */
495
+ async resolveFinding(findingId, resolution, notes) {
496
+ const body = { resolution };
497
+ if (notes) body.notes = notes;
498
+ return await this.http.post(
499
+ `/v2/cloud-security/findings/${findingId}/resolve/`,
500
+ body
501
+ );
502
+ }
503
+ /**
504
+ * Suppress a finding
505
+ */
506
+ async suppressFinding(findingId, reason, durationDays) {
507
+ const body = { reason };
508
+ if (durationDays) body.duration_days = durationDays;
509
+ return await this.http.post(
510
+ `/v2/cloud-security/findings/${findingId}/suppress/`,
511
+ body
512
+ );
513
+ }
514
+ /**
515
+ * Get remediation steps for a finding
516
+ */
517
+ async getRemediation(findingId) {
518
+ return await this.http.get(
519
+ `/v2/cloud-security/findings/${findingId}/remediation/`
520
+ );
521
+ }
522
+ /**
523
+ * Get cloud security dashboard
524
+ */
525
+ async dashboard(projectId, period = "month") {
526
+ const params = { period };
527
+ if (projectId) params.project_id = projectId;
528
+ return await this.http.get("/v2/cloud-security/dashboard/", params);
529
+ }
530
+ };
531
+
532
+ // src/pipeline.ts
533
+ function sleep3(ms) {
534
+ return new Promise((resolve) => setTimeout(resolve, ms));
535
+ }
536
+ var PipelineAPI = class {
537
+ constructor(http) {
538
+ this.http = http;
539
+ }
540
+ /**
541
+ * Create a pipeline project
542
+ */
543
+ async createProject(name, options = {}) {
544
+ const body = {
545
+ name,
546
+ default_branch: options.defaultBranch || "main"
547
+ };
548
+ if (options.repositoryUrl) body.repository_url = options.repositoryUrl;
549
+ if (options.scanTypes) body.scan_types = options.scanTypes;
550
+ return await this.http.post("/v1/pipeline/projects/", body);
551
+ }
552
+ /**
553
+ * List pipeline projects
554
+ */
555
+ async listProjects(page = 1, limit = 25) {
556
+ return await this.http.get("/v1/pipeline/projects/", { page, limit });
557
+ }
558
+ /**
559
+ * Get project details
560
+ */
561
+ async getProject(projectId) {
562
+ return await this.http.get(`/v1/pipeline/projects/${projectId}/`);
563
+ }
564
+ /**
565
+ * Delete a pipeline project
566
+ */
567
+ async deleteProject(projectId) {
568
+ await this.http.delete(`/v1/pipeline/projects/${projectId}/`);
569
+ }
570
+ /**
571
+ * Run pipeline security scan
572
+ */
573
+ async scan(projectId, options = {}) {
574
+ const {
575
+ commitSha,
576
+ branch,
577
+ scanTypes,
578
+ failOnSeverity,
579
+ wait = false,
580
+ timeout = 6e5
581
+ } = options;
582
+ const body = { project_id: projectId };
583
+ if (commitSha) body.commit_sha = commitSha;
584
+ if (branch) body.branch = branch;
585
+ if (scanTypes) body.scan_types = scanTypes;
586
+ if (failOnSeverity) body.fail_on_severity = failOnSeverity;
587
+ const result = await this.http.post("/v1/pipeline/scans/", body);
588
+ if (!wait) {
589
+ return result;
590
+ }
591
+ const scanId = result.scan_id;
592
+ if (!scanId) {
593
+ return result;
594
+ }
595
+ return this.waitForScan(scanId, timeout);
596
+ }
597
+ async waitForScan(scanId, timeout) {
598
+ const start = Date.now();
599
+ while (Date.now() - start < timeout) {
600
+ const scan = await this.getScan(scanId);
601
+ const status = scan.status;
602
+ if (["completed", "passed", "failed"].includes(status)) {
603
+ return scan;
604
+ }
605
+ if (status === "error") {
606
+ throw new Error(`Scan error: ${scan.error || "Unknown error"}`);
607
+ }
608
+ await sleep3(5e3);
609
+ }
610
+ throw new Error(`Scan did not complete within ${timeout}ms`);
611
+ }
612
+ /**
613
+ * Get scan details and results
614
+ */
615
+ async getScan(scanId) {
616
+ return await this.http.get(`/v1/pipeline/scans/${scanId}/`);
617
+ }
618
+ /**
619
+ * List pipeline scans
620
+ */
621
+ async listScans(options = {}) {
622
+ const { projectId, status, branch, page = 1, limit = 25 } = options;
623
+ const params = { page, limit };
624
+ if (projectId) params.project_id = projectId;
625
+ if (status) params.status = status;
626
+ if (branch) params.branch = branch;
627
+ return await this.http.get("/v1/pipeline/scans/", params);
628
+ }
629
+ /**
630
+ * Get findings from a scan
631
+ */
632
+ async getFindings(scanId, options = {}) {
633
+ const { scanType, severity } = options;
634
+ const params = {};
635
+ if (scanType) params.type = scanType;
636
+ if (severity) params.severity = severity;
637
+ const result = await this.http.get(`/v1/pipeline/scans/${scanId}/findings/`, params);
638
+ if (Array.isArray(result)) {
639
+ return result;
640
+ }
641
+ const data = result;
642
+ return data.results || data.findings || [];
643
+ }
644
+ /**
645
+ * Get SAST (static analysis) findings
646
+ */
647
+ async getSastFindings(scanId) {
648
+ return this.getFindings(scanId, { scanType: "sast" });
649
+ }
650
+ /**
651
+ * Get SCA (dependency) findings
652
+ */
653
+ async getScaFindings(scanId) {
654
+ return this.getFindings(scanId, { scanType: "sca" });
655
+ }
656
+ /**
657
+ * Get secrets detection findings
658
+ */
659
+ async getSecretsFindings(scanId) {
660
+ return this.getFindings(scanId, { scanType: "secrets" });
661
+ }
662
+ /**
663
+ * Configure security gates for a project
664
+ */
665
+ async configureGates(projectId, gates) {
666
+ return await this.http.patch(
667
+ `/v1/pipeline/projects/${projectId}/gates/`,
668
+ gates
669
+ );
670
+ }
671
+ /**
672
+ * Set scan as baseline (suppress existing findings)
673
+ */
674
+ async addBaseline(projectId, scanId) {
675
+ return await this.http.post(`/v1/pipeline/projects/${projectId}/baseline/`, {
676
+ baseline_scan_id: scanId
677
+ });
678
+ }
679
+ /**
680
+ * Suppress a finding
681
+ */
682
+ async suppressFinding(findingId, reason, expiresAt) {
683
+ const body = { reason };
684
+ if (expiresAt) body.expires_at = expiresAt;
685
+ return await this.http.post(
686
+ `/v1/pipeline/findings/${findingId}/suppress/`,
687
+ body
688
+ );
689
+ }
690
+ /**
691
+ * Get pipeline security dashboard
692
+ */
693
+ async dashboard(projectId, period = "month") {
694
+ const params = { period };
695
+ if (projectId) params.project_id = projectId;
696
+ return await this.http.get("/v1/pipeline/dashboard/", params);
697
+ }
698
+ };
699
+
700
+ // src/client.ts
701
+ var Aribot = class {
702
+ /**
703
+ * Create Aribot client
704
+ *
705
+ * @param apiKey - Your Aribot API key
706
+ * @param options - Client configuration options
707
+ */
708
+ constructor(apiKey, options = {}) {
709
+ this.http = new HttpClient({
710
+ apiKey,
711
+ baseUrl: options.baseUrl,
712
+ timeout: options.timeout
713
+ });
714
+ this.threatModeling = new ThreatModelingAPI(this.http);
715
+ this.compliance = new ComplianceAPI(this.http);
716
+ this.cloud = new CloudSecurityAPI(this.http);
717
+ this.pipeline = new PipelineAPI(this.http);
718
+ }
719
+ /**
720
+ * Check API health status
721
+ */
722
+ async health() {
723
+ return await this.http.get("/health/");
724
+ }
725
+ /**
726
+ * Get current user/organization info
727
+ */
728
+ async me() {
729
+ return await this.http.get("/v1/users/me/");
730
+ }
731
+ /**
732
+ * Get API usage statistics
733
+ */
734
+ async usage(period = "month") {
735
+ return await this.http.get("/v1/usage/", { period });
736
+ }
737
+ };
738
+ export {
739
+ Aribot,
740
+ AribotError,
741
+ AuthenticationError,
742
+ CloudSecurityAPI,
743
+ ComplianceAPI,
744
+ NotFoundError,
745
+ PipelineAPI,
746
+ RateLimitError,
747
+ ServerError,
748
+ ThreatModelingAPI,
749
+ ValidationError
750
+ };