@forg3t/sdk 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 +192 -0
- package/dist/index.d.ts +192 -0
- package/dist/index.js +363 -0
- package/dist/index.mjs +331 -0
- package/package.json +50 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
interface Forg3tClientOptions {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
}
|
|
6
|
+
interface PaginationParams {
|
|
7
|
+
limit?: number;
|
|
8
|
+
offset?: number;
|
|
9
|
+
cursor?: string;
|
|
10
|
+
}
|
|
11
|
+
interface Project {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
tenantId: string;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
interface ApiKey {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
keyPrefix: string;
|
|
22
|
+
status: 'active' | 'revoked';
|
|
23
|
+
createdAt: string;
|
|
24
|
+
revokedAt?: string | null;
|
|
25
|
+
lastUsedAt?: string | null;
|
|
26
|
+
expiresAt?: string | null;
|
|
27
|
+
}
|
|
28
|
+
interface CreateApiKeyRequest {
|
|
29
|
+
name: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
}
|
|
32
|
+
interface CreateApiKeyResponse extends ApiKey {
|
|
33
|
+
plaintextKey: string;
|
|
34
|
+
}
|
|
35
|
+
interface AuditEvent {
|
|
36
|
+
id: string;
|
|
37
|
+
action: string;
|
|
38
|
+
resourceType: string;
|
|
39
|
+
resourceId: string;
|
|
40
|
+
ip: string;
|
|
41
|
+
userAgent: string;
|
|
42
|
+
createdAt: string;
|
|
43
|
+
metadata: Record<string, unknown> | null;
|
|
44
|
+
}
|
|
45
|
+
interface AuditEventFilters {
|
|
46
|
+
action?: string;
|
|
47
|
+
resourceType?: string;
|
|
48
|
+
resourceId?: string;
|
|
49
|
+
from?: string;
|
|
50
|
+
to?: string;
|
|
51
|
+
limit?: number;
|
|
52
|
+
cursor?: string;
|
|
53
|
+
}
|
|
54
|
+
interface AuditEventListResponse {
|
|
55
|
+
events: AuditEvent[];
|
|
56
|
+
nextCursor?: string;
|
|
57
|
+
}
|
|
58
|
+
interface Job {
|
|
59
|
+
id: string;
|
|
60
|
+
projectId: string;
|
|
61
|
+
type: string;
|
|
62
|
+
status: 'pending' | 'processing' | 'completed' | 'failed' | 'dead';
|
|
63
|
+
payload: Record<string, unknown>;
|
|
64
|
+
result?: Record<string, unknown> | null;
|
|
65
|
+
error?: Record<string, unknown> | null;
|
|
66
|
+
idempotencyKey?: string | null;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
startedAt?: string | null;
|
|
70
|
+
completedAt?: string | null;
|
|
71
|
+
}
|
|
72
|
+
interface SubmitJobRequest {
|
|
73
|
+
type: string;
|
|
74
|
+
payload: Record<string, unknown>;
|
|
75
|
+
idempotencyKey?: string;
|
|
76
|
+
}
|
|
77
|
+
interface ClaimJobsRequest {
|
|
78
|
+
limit?: number;
|
|
79
|
+
}
|
|
80
|
+
interface JobResult {
|
|
81
|
+
result: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
interface JobError {
|
|
84
|
+
error: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
interface Webhook {
|
|
87
|
+
id: string;
|
|
88
|
+
projectId: string;
|
|
89
|
+
url: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
secretPrefix?: string;
|
|
93
|
+
createdAt: string;
|
|
94
|
+
updatedAt: string;
|
|
95
|
+
}
|
|
96
|
+
interface CreateWebhookRequest {
|
|
97
|
+
url: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
}
|
|
100
|
+
interface UpdateWebhookRequest {
|
|
101
|
+
url?: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
}
|
|
105
|
+
interface WebhookDelivery {
|
|
106
|
+
id: string;
|
|
107
|
+
webhookId: string;
|
|
108
|
+
eventId: string;
|
|
109
|
+
eventType: string;
|
|
110
|
+
status: 'success' | 'failed' | 'pending';
|
|
111
|
+
requestHeaders: Record<string, string>;
|
|
112
|
+
requestBody: Record<string, unknown>;
|
|
113
|
+
responseStatus?: number;
|
|
114
|
+
responseBody?: string;
|
|
115
|
+
createdAt: string;
|
|
116
|
+
attemptCount: number;
|
|
117
|
+
}
|
|
118
|
+
interface WebhookDeliveryFilters extends PaginationParams {
|
|
119
|
+
status?: 'success' | 'failed' | 'pending' | 'dead';
|
|
120
|
+
eventType?: string;
|
|
121
|
+
}
|
|
122
|
+
interface EvidenceArtifact {
|
|
123
|
+
id: string;
|
|
124
|
+
jobId: string;
|
|
125
|
+
type: string;
|
|
126
|
+
content: string;
|
|
127
|
+
signature: string;
|
|
128
|
+
publicKey: string;
|
|
129
|
+
createdAt: string;
|
|
130
|
+
artifacts: unknown[];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
declare class Forg3tClient {
|
|
134
|
+
private transport;
|
|
135
|
+
constructor(options?: Forg3tClientOptions);
|
|
136
|
+
getProjectOverview(projectId: string, requestId?: string): Promise<Project>;
|
|
137
|
+
listAuditEvents(projectId: string, filters?: AuditEventFilters, requestId?: string): Promise<AuditEventListResponse>;
|
|
138
|
+
listApiKeys(projectId: string, requestId?: string): Promise<ApiKey[]>;
|
|
139
|
+
createApiKey(projectId: string, data: CreateApiKeyRequest, requestId?: string): Promise<CreateApiKeyResponse>;
|
|
140
|
+
rotateApiKey(keyId: string, requestId?: string): Promise<CreateApiKeyResponse>;
|
|
141
|
+
revokeApiKey(keyId: string, requestId?: string): Promise<ApiKey>;
|
|
142
|
+
submitJob(projectId: string, data: SubmitJobRequest, requestId?: string): Promise<Job>;
|
|
143
|
+
getJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
144
|
+
listJobs(projectId: string, query?: {
|
|
145
|
+
status?: string;
|
|
146
|
+
limit?: number;
|
|
147
|
+
offset?: number;
|
|
148
|
+
}, requestId?: string): Promise<Job[]>;
|
|
149
|
+
claimJobs(projectId: string, data?: ClaimJobsRequest, requestId?: string): Promise<Job[]>;
|
|
150
|
+
heartbeatJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
151
|
+
completeJob(projectId: string, jobId: string, result: JobResult, requestId?: string): Promise<Job>;
|
|
152
|
+
failJob(projectId: string, jobId: string, error: JobError, requestId?: string): Promise<Job>;
|
|
153
|
+
listDeadJobs(projectId: string, requestId?: string): Promise<Job[]>;
|
|
154
|
+
replayJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
155
|
+
getEvidence(jobId: string, requestId?: string): Promise<EvidenceArtifact>;
|
|
156
|
+
/**
|
|
157
|
+
* @deprecated The current Control Plane version does not support direct artifact downloads.
|
|
158
|
+
* Please use getEvidence() to retrieve the artifact metadata and content.
|
|
159
|
+
*/
|
|
160
|
+
downloadEvidenceArtifact(jobId: string, requestId?: string): Promise<void>;
|
|
161
|
+
listWebhooks(projectId: string, requestId?: string): Promise<Webhook[]>;
|
|
162
|
+
createWebhook(projectId: string, data: CreateWebhookRequest, requestId?: string): Promise<Webhook>;
|
|
163
|
+
updateWebhook(webhookId: string, data: UpdateWebhookRequest, requestId?: string): Promise<Webhook>;
|
|
164
|
+
deleteWebhook(webhookId: string, requestId?: string): Promise<void>;
|
|
165
|
+
rotateWebhookSecret(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
166
|
+
enableWebhook(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
167
|
+
disableWebhook(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
168
|
+
listWebhookDeliveries(webhookId: string, filters?: WebhookDeliveryFilters, requestId?: string): Promise<WebhookDelivery[]>;
|
|
169
|
+
replayWebhookDelivery(deliveryId: string, requestId?: string): Promise<WebhookDelivery>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
declare class Forg3tError extends Error {
|
|
173
|
+
status?: number | undefined;
|
|
174
|
+
code?: string | undefined;
|
|
175
|
+
requestId?: string | undefined;
|
|
176
|
+
details?: Record<string, unknown> | undefined;
|
|
177
|
+
constructor(message: string, status?: number | undefined, code?: string | undefined, requestId?: string | undefined, details?: Record<string, unknown> | undefined);
|
|
178
|
+
}
|
|
179
|
+
declare class Forg3tAuthenticationError extends Forg3tError {
|
|
180
|
+
constructor(message: string, requestId?: string);
|
|
181
|
+
}
|
|
182
|
+
declare class Forg3tNotFoundError extends Forg3tError {
|
|
183
|
+
constructor(message: string, requestId?: string);
|
|
184
|
+
}
|
|
185
|
+
declare class Forg3tRateLimitError extends Forg3tError {
|
|
186
|
+
constructor(message: string, requestId?: string);
|
|
187
|
+
}
|
|
188
|
+
declare class Forg3tApiConnectionError extends Forg3tError {
|
|
189
|
+
constructor(message: string);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export { type ApiKey, type AuditEvent, type AuditEventFilters, type AuditEventListResponse, type ClaimJobsRequest, type CreateApiKeyRequest, type CreateApiKeyResponse, type CreateWebhookRequest, type EvidenceArtifact, Forg3tApiConnectionError, Forg3tAuthenticationError, Forg3tClient, type Forg3tClientOptions, Forg3tError, Forg3tNotFoundError, Forg3tRateLimitError, type Job, type JobError, type JobResult, type PaginationParams, type Project, type SubmitJobRequest, type UpdateWebhookRequest, type Webhook, type WebhookDelivery, type WebhookDeliveryFilters };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
interface Forg3tClientOptions {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
}
|
|
6
|
+
interface PaginationParams {
|
|
7
|
+
limit?: number;
|
|
8
|
+
offset?: number;
|
|
9
|
+
cursor?: string;
|
|
10
|
+
}
|
|
11
|
+
interface Project {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
tenantId: string;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
}
|
|
18
|
+
interface ApiKey {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
keyPrefix: string;
|
|
22
|
+
status: 'active' | 'revoked';
|
|
23
|
+
createdAt: string;
|
|
24
|
+
revokedAt?: string | null;
|
|
25
|
+
lastUsedAt?: string | null;
|
|
26
|
+
expiresAt?: string | null;
|
|
27
|
+
}
|
|
28
|
+
interface CreateApiKeyRequest {
|
|
29
|
+
name: string;
|
|
30
|
+
expiresAt?: string;
|
|
31
|
+
}
|
|
32
|
+
interface CreateApiKeyResponse extends ApiKey {
|
|
33
|
+
plaintextKey: string;
|
|
34
|
+
}
|
|
35
|
+
interface AuditEvent {
|
|
36
|
+
id: string;
|
|
37
|
+
action: string;
|
|
38
|
+
resourceType: string;
|
|
39
|
+
resourceId: string;
|
|
40
|
+
ip: string;
|
|
41
|
+
userAgent: string;
|
|
42
|
+
createdAt: string;
|
|
43
|
+
metadata: Record<string, unknown> | null;
|
|
44
|
+
}
|
|
45
|
+
interface AuditEventFilters {
|
|
46
|
+
action?: string;
|
|
47
|
+
resourceType?: string;
|
|
48
|
+
resourceId?: string;
|
|
49
|
+
from?: string;
|
|
50
|
+
to?: string;
|
|
51
|
+
limit?: number;
|
|
52
|
+
cursor?: string;
|
|
53
|
+
}
|
|
54
|
+
interface AuditEventListResponse {
|
|
55
|
+
events: AuditEvent[];
|
|
56
|
+
nextCursor?: string;
|
|
57
|
+
}
|
|
58
|
+
interface Job {
|
|
59
|
+
id: string;
|
|
60
|
+
projectId: string;
|
|
61
|
+
type: string;
|
|
62
|
+
status: 'pending' | 'processing' | 'completed' | 'failed' | 'dead';
|
|
63
|
+
payload: Record<string, unknown>;
|
|
64
|
+
result?: Record<string, unknown> | null;
|
|
65
|
+
error?: Record<string, unknown> | null;
|
|
66
|
+
idempotencyKey?: string | null;
|
|
67
|
+
createdAt: string;
|
|
68
|
+
updatedAt: string;
|
|
69
|
+
startedAt?: string | null;
|
|
70
|
+
completedAt?: string | null;
|
|
71
|
+
}
|
|
72
|
+
interface SubmitJobRequest {
|
|
73
|
+
type: string;
|
|
74
|
+
payload: Record<string, unknown>;
|
|
75
|
+
idempotencyKey?: string;
|
|
76
|
+
}
|
|
77
|
+
interface ClaimJobsRequest {
|
|
78
|
+
limit?: number;
|
|
79
|
+
}
|
|
80
|
+
interface JobResult {
|
|
81
|
+
result: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
interface JobError {
|
|
84
|
+
error: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
interface Webhook {
|
|
87
|
+
id: string;
|
|
88
|
+
projectId: string;
|
|
89
|
+
url: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
secretPrefix?: string;
|
|
93
|
+
createdAt: string;
|
|
94
|
+
updatedAt: string;
|
|
95
|
+
}
|
|
96
|
+
interface CreateWebhookRequest {
|
|
97
|
+
url: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
}
|
|
100
|
+
interface UpdateWebhookRequest {
|
|
101
|
+
url?: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
}
|
|
105
|
+
interface WebhookDelivery {
|
|
106
|
+
id: string;
|
|
107
|
+
webhookId: string;
|
|
108
|
+
eventId: string;
|
|
109
|
+
eventType: string;
|
|
110
|
+
status: 'success' | 'failed' | 'pending';
|
|
111
|
+
requestHeaders: Record<string, string>;
|
|
112
|
+
requestBody: Record<string, unknown>;
|
|
113
|
+
responseStatus?: number;
|
|
114
|
+
responseBody?: string;
|
|
115
|
+
createdAt: string;
|
|
116
|
+
attemptCount: number;
|
|
117
|
+
}
|
|
118
|
+
interface WebhookDeliveryFilters extends PaginationParams {
|
|
119
|
+
status?: 'success' | 'failed' | 'pending' | 'dead';
|
|
120
|
+
eventType?: string;
|
|
121
|
+
}
|
|
122
|
+
interface EvidenceArtifact {
|
|
123
|
+
id: string;
|
|
124
|
+
jobId: string;
|
|
125
|
+
type: string;
|
|
126
|
+
content: string;
|
|
127
|
+
signature: string;
|
|
128
|
+
publicKey: string;
|
|
129
|
+
createdAt: string;
|
|
130
|
+
artifacts: unknown[];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
declare class Forg3tClient {
|
|
134
|
+
private transport;
|
|
135
|
+
constructor(options?: Forg3tClientOptions);
|
|
136
|
+
getProjectOverview(projectId: string, requestId?: string): Promise<Project>;
|
|
137
|
+
listAuditEvents(projectId: string, filters?: AuditEventFilters, requestId?: string): Promise<AuditEventListResponse>;
|
|
138
|
+
listApiKeys(projectId: string, requestId?: string): Promise<ApiKey[]>;
|
|
139
|
+
createApiKey(projectId: string, data: CreateApiKeyRequest, requestId?: string): Promise<CreateApiKeyResponse>;
|
|
140
|
+
rotateApiKey(keyId: string, requestId?: string): Promise<CreateApiKeyResponse>;
|
|
141
|
+
revokeApiKey(keyId: string, requestId?: string): Promise<ApiKey>;
|
|
142
|
+
submitJob(projectId: string, data: SubmitJobRequest, requestId?: string): Promise<Job>;
|
|
143
|
+
getJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
144
|
+
listJobs(projectId: string, query?: {
|
|
145
|
+
status?: string;
|
|
146
|
+
limit?: number;
|
|
147
|
+
offset?: number;
|
|
148
|
+
}, requestId?: string): Promise<Job[]>;
|
|
149
|
+
claimJobs(projectId: string, data?: ClaimJobsRequest, requestId?: string): Promise<Job[]>;
|
|
150
|
+
heartbeatJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
151
|
+
completeJob(projectId: string, jobId: string, result: JobResult, requestId?: string): Promise<Job>;
|
|
152
|
+
failJob(projectId: string, jobId: string, error: JobError, requestId?: string): Promise<Job>;
|
|
153
|
+
listDeadJobs(projectId: string, requestId?: string): Promise<Job[]>;
|
|
154
|
+
replayJob(projectId: string, jobId: string, requestId?: string): Promise<Job>;
|
|
155
|
+
getEvidence(jobId: string, requestId?: string): Promise<EvidenceArtifact>;
|
|
156
|
+
/**
|
|
157
|
+
* @deprecated The current Control Plane version does not support direct artifact downloads.
|
|
158
|
+
* Please use getEvidence() to retrieve the artifact metadata and content.
|
|
159
|
+
*/
|
|
160
|
+
downloadEvidenceArtifact(jobId: string, requestId?: string): Promise<void>;
|
|
161
|
+
listWebhooks(projectId: string, requestId?: string): Promise<Webhook[]>;
|
|
162
|
+
createWebhook(projectId: string, data: CreateWebhookRequest, requestId?: string): Promise<Webhook>;
|
|
163
|
+
updateWebhook(webhookId: string, data: UpdateWebhookRequest, requestId?: string): Promise<Webhook>;
|
|
164
|
+
deleteWebhook(webhookId: string, requestId?: string): Promise<void>;
|
|
165
|
+
rotateWebhookSecret(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
166
|
+
enableWebhook(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
167
|
+
disableWebhook(webhookId: string, requestId?: string): Promise<Webhook>;
|
|
168
|
+
listWebhookDeliveries(webhookId: string, filters?: WebhookDeliveryFilters, requestId?: string): Promise<WebhookDelivery[]>;
|
|
169
|
+
replayWebhookDelivery(deliveryId: string, requestId?: string): Promise<WebhookDelivery>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
declare class Forg3tError extends Error {
|
|
173
|
+
status?: number | undefined;
|
|
174
|
+
code?: string | undefined;
|
|
175
|
+
requestId?: string | undefined;
|
|
176
|
+
details?: Record<string, unknown> | undefined;
|
|
177
|
+
constructor(message: string, status?: number | undefined, code?: string | undefined, requestId?: string | undefined, details?: Record<string, unknown> | undefined);
|
|
178
|
+
}
|
|
179
|
+
declare class Forg3tAuthenticationError extends Forg3tError {
|
|
180
|
+
constructor(message: string, requestId?: string);
|
|
181
|
+
}
|
|
182
|
+
declare class Forg3tNotFoundError extends Forg3tError {
|
|
183
|
+
constructor(message: string, requestId?: string);
|
|
184
|
+
}
|
|
185
|
+
declare class Forg3tRateLimitError extends Forg3tError {
|
|
186
|
+
constructor(message: string, requestId?: string);
|
|
187
|
+
}
|
|
188
|
+
declare class Forg3tApiConnectionError extends Forg3tError {
|
|
189
|
+
constructor(message: string);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export { type ApiKey, type AuditEvent, type AuditEventFilters, type AuditEventListResponse, type ClaimJobsRequest, type CreateApiKeyRequest, type CreateApiKeyResponse, type CreateWebhookRequest, type EvidenceArtifact, Forg3tApiConnectionError, Forg3tAuthenticationError, Forg3tClient, type Forg3tClientOptions, Forg3tError, Forg3tNotFoundError, Forg3tRateLimitError, type Job, type JobError, type JobResult, type PaginationParams, type Project, type SubmitJobRequest, type UpdateWebhookRequest, type Webhook, type WebhookDelivery, type WebhookDeliveryFilters };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
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 index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
Forg3tApiConnectionError: () => Forg3tApiConnectionError,
|
|
24
|
+
Forg3tAuthenticationError: () => Forg3tAuthenticationError,
|
|
25
|
+
Forg3tClient: () => Forg3tClient,
|
|
26
|
+
Forg3tError: () => Forg3tError,
|
|
27
|
+
Forg3tNotFoundError: () => Forg3tNotFoundError,
|
|
28
|
+
Forg3tRateLimitError: () => Forg3tRateLimitError
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(index_exports);
|
|
31
|
+
|
|
32
|
+
// src/errors.ts
|
|
33
|
+
var Forg3tError = class extends Error {
|
|
34
|
+
constructor(message, status, code, requestId, details) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.status = status;
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.requestId = requestId;
|
|
39
|
+
this.details = details;
|
|
40
|
+
this.name = "Forg3tError";
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var Forg3tAuthenticationError = class extends Forg3tError {
|
|
44
|
+
constructor(message, requestId) {
|
|
45
|
+
super(message, 401, "AUTHENTICATION_ERROR", requestId);
|
|
46
|
+
this.name = "Forg3tAuthenticationError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var Forg3tNotFoundError = class extends Forg3tError {
|
|
50
|
+
constructor(message, requestId) {
|
|
51
|
+
super(message, 404, "NOT_FOUND", requestId);
|
|
52
|
+
this.name = "Forg3tNotFoundError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
var Forg3tRateLimitError = class extends Forg3tError {
|
|
56
|
+
constructor(message, requestId) {
|
|
57
|
+
super(message, 429, "RATE_LIMIT_EXCEEDED", requestId);
|
|
58
|
+
this.name = "Forg3tRateLimitError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var Forg3tApiConnectionError = class extends Forg3tError {
|
|
62
|
+
constructor(message) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "Forg3tApiConnectionError";
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/transport.ts
|
|
69
|
+
var Transport = class {
|
|
70
|
+
constructor(config) {
|
|
71
|
+
this.baseUrl = config.baseUrl || typeof process !== "undefined" && process.env.FORG3T_API_URL || "";
|
|
72
|
+
if (!this.baseUrl) {
|
|
73
|
+
throw new Error("Forg3tClient: apiUrl option or FORG3T_API_URL environment variable is required");
|
|
74
|
+
}
|
|
75
|
+
if (this.baseUrl.endsWith("/")) {
|
|
76
|
+
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
77
|
+
}
|
|
78
|
+
this.apiKey = config.apiKey || (typeof process !== "undefined" ? process.env.FORG3T_API_KEY : void 0);
|
|
79
|
+
this.timeoutMs = config.timeoutMs || 3e4;
|
|
80
|
+
}
|
|
81
|
+
getBaseUrl() {
|
|
82
|
+
return this.baseUrl;
|
|
83
|
+
}
|
|
84
|
+
async request(path, options = {}, requestId) {
|
|
85
|
+
const url = `${this.baseUrl}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
86
|
+
const headers = {
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
"Accept": "application/json",
|
|
89
|
+
...options.headers || {}
|
|
90
|
+
};
|
|
91
|
+
if (this.apiKey) {
|
|
92
|
+
headers["x-api-key"] = this.apiKey;
|
|
93
|
+
}
|
|
94
|
+
if (requestId) {
|
|
95
|
+
headers["x-request-id"] = requestId;
|
|
96
|
+
}
|
|
97
|
+
const controller = new AbortController();
|
|
98
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
99
|
+
const signal = controller.signal;
|
|
100
|
+
try {
|
|
101
|
+
const response = await fetch(url, {
|
|
102
|
+
...options,
|
|
103
|
+
headers,
|
|
104
|
+
signal
|
|
105
|
+
// Add the abort signal
|
|
106
|
+
});
|
|
107
|
+
clearTimeout(timeoutId);
|
|
108
|
+
const responseRequestId = response.headers.get("x-request-id") || requestId;
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
let errorData = {};
|
|
111
|
+
try {
|
|
112
|
+
errorData = await response.json();
|
|
113
|
+
} catch {
|
|
114
|
+
errorData = { error: response.statusText };
|
|
115
|
+
}
|
|
116
|
+
const message = errorData.error || errorData.message || "Unknown error occurred";
|
|
117
|
+
if (response.status === 401 || response.status === 403) {
|
|
118
|
+
throw new Forg3tAuthenticationError(message, responseRequestId);
|
|
119
|
+
}
|
|
120
|
+
if (response.status === 404) {
|
|
121
|
+
throw new Forg3tNotFoundError(message, responseRequestId);
|
|
122
|
+
}
|
|
123
|
+
if (response.status === 429) {
|
|
124
|
+
throw new Forg3tRateLimitError(message, responseRequestId);
|
|
125
|
+
}
|
|
126
|
+
throw new Forg3tError(
|
|
127
|
+
message,
|
|
128
|
+
response.status,
|
|
129
|
+
errorData.code,
|
|
130
|
+
responseRequestId,
|
|
131
|
+
errorData
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
if (response.status === 204) {
|
|
135
|
+
return {};
|
|
136
|
+
}
|
|
137
|
+
return await response.json();
|
|
138
|
+
} catch (error) {
|
|
139
|
+
clearTimeout(timeoutId);
|
|
140
|
+
if (error instanceof Forg3tError) {
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
144
|
+
throw new Forg3tApiConnectionError(`Request timeout after ${this.timeoutMs}ms`);
|
|
145
|
+
}
|
|
146
|
+
throw new Forg3tApiConnectionError(error instanceof Error ? error.message : "Network error");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async download(url, requestId) {
|
|
150
|
+
const headers = {
|
|
151
|
+
"Accept": "*/*"
|
|
152
|
+
// Accept any type for downloads
|
|
153
|
+
};
|
|
154
|
+
if (this.apiKey) {
|
|
155
|
+
headers["x-api-key"] = this.apiKey;
|
|
156
|
+
}
|
|
157
|
+
if (requestId) {
|
|
158
|
+
headers["x-request-id"] = requestId;
|
|
159
|
+
}
|
|
160
|
+
const controller = new AbortController();
|
|
161
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
162
|
+
const signal = controller.signal;
|
|
163
|
+
try {
|
|
164
|
+
const response = await fetch(url, {
|
|
165
|
+
method: "GET",
|
|
166
|
+
headers,
|
|
167
|
+
signal
|
|
168
|
+
// Add the abort signal
|
|
169
|
+
});
|
|
170
|
+
clearTimeout(timeoutId);
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
let errorData = {};
|
|
173
|
+
try {
|
|
174
|
+
errorData = await response.json();
|
|
175
|
+
} catch {
|
|
176
|
+
errorData = { error: response.statusText };
|
|
177
|
+
}
|
|
178
|
+
const message = errorData.error || errorData.message || "Unknown error occurred";
|
|
179
|
+
if (response.status === 401 || response.status === 403) {
|
|
180
|
+
throw new Forg3tAuthenticationError(message, requestId);
|
|
181
|
+
}
|
|
182
|
+
if (response.status === 404) {
|
|
183
|
+
throw new Forg3tNotFoundError(message, requestId);
|
|
184
|
+
}
|
|
185
|
+
if (response.status === 429) {
|
|
186
|
+
throw new Forg3tRateLimitError(message, requestId);
|
|
187
|
+
}
|
|
188
|
+
throw new Forg3tError(
|
|
189
|
+
message,
|
|
190
|
+
response.status,
|
|
191
|
+
errorData.code,
|
|
192
|
+
requestId,
|
|
193
|
+
errorData
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return await response.blob();
|
|
197
|
+
} catch (error) {
|
|
198
|
+
clearTimeout(timeoutId);
|
|
199
|
+
if (error instanceof Forg3tError) {
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
203
|
+
throw new Forg3tApiConnectionError(`Download timeout after ${this.timeoutMs}ms`);
|
|
204
|
+
}
|
|
205
|
+
throw new Forg3tApiConnectionError(error instanceof Error ? error.message : "Network error");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/client.ts
|
|
211
|
+
var Forg3tClient = class {
|
|
212
|
+
constructor(options = {}) {
|
|
213
|
+
this.transport = new Transport({
|
|
214
|
+
baseUrl: options.apiUrl,
|
|
215
|
+
apiKey: options.apiKey,
|
|
216
|
+
timeoutMs: options.timeoutMs
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// --- Projects ---
|
|
220
|
+
async getProjectOverview(projectId, requestId) {
|
|
221
|
+
return this.transport.request(`/v1/projects/${projectId}/overview`, { method: "GET" }, requestId);
|
|
222
|
+
}
|
|
223
|
+
async listAuditEvents(projectId, filters = {}, requestId) {
|
|
224
|
+
const params = new URLSearchParams();
|
|
225
|
+
if (filters.action) params.append("action", filters.action);
|
|
226
|
+
if (filters.resourceType) params.append("resourceType", filters.resourceType);
|
|
227
|
+
if (filters.resourceId) params.append("resourceId", filters.resourceId);
|
|
228
|
+
if (filters.from) params.append("from", filters.from);
|
|
229
|
+
if (filters.to) params.append("to", filters.to);
|
|
230
|
+
if (filters.limit) params.append("limit", filters.limit.toString());
|
|
231
|
+
if (filters.cursor) params.append("cursor", filters.cursor);
|
|
232
|
+
return this.transport.request(`/v1/projects/${projectId}/audit?${params.toString()}`, { method: "GET" }, requestId);
|
|
233
|
+
}
|
|
234
|
+
// --- API Keys ---
|
|
235
|
+
async listApiKeys(projectId, requestId) {
|
|
236
|
+
return this.transport.request(`/v1/projects/${projectId}/api-keys`, { method: "GET" }, requestId);
|
|
237
|
+
}
|
|
238
|
+
async createApiKey(projectId, data, requestId) {
|
|
239
|
+
return this.transport.request(`/v1/projects/${projectId}/api-keys`, {
|
|
240
|
+
method: "POST",
|
|
241
|
+
body: JSON.stringify(data)
|
|
242
|
+
}, requestId);
|
|
243
|
+
}
|
|
244
|
+
async rotateApiKey(keyId, requestId) {
|
|
245
|
+
return this.transport.request(`/v1/api-keys/${keyId}/rotate`, { method: "POST" }, requestId);
|
|
246
|
+
}
|
|
247
|
+
async revokeApiKey(keyId, requestId) {
|
|
248
|
+
return this.transport.request(`/v1/api-keys/${keyId}/revoke`, { method: "POST" }, requestId);
|
|
249
|
+
}
|
|
250
|
+
// --- Jobs ---
|
|
251
|
+
async submitJob(projectId, data, requestId) {
|
|
252
|
+
const res = await this.transport.request(`/v1/projects/${projectId}/jobs`, {
|
|
253
|
+
method: "POST",
|
|
254
|
+
body: JSON.stringify(data)
|
|
255
|
+
}, requestId);
|
|
256
|
+
if (res && res.jobId && !res.id) {
|
|
257
|
+
return {
|
|
258
|
+
...res,
|
|
259
|
+
id: res.jobId,
|
|
260
|
+
projectId
|
|
261
|
+
// Ensure projectId is present if server omits it in minimal response
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return res;
|
|
265
|
+
}
|
|
266
|
+
async getJob(projectId, jobId, requestId) {
|
|
267
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}`, { method: "GET" }, requestId);
|
|
268
|
+
}
|
|
269
|
+
async listJobs(projectId, query, requestId) {
|
|
270
|
+
const params = new URLSearchParams();
|
|
271
|
+
if (query?.status) params.append("status", query.status);
|
|
272
|
+
if (query?.limit) params.append("limit", query.limit.toString());
|
|
273
|
+
if (query?.offset) params.append("offset", query.offset.toString());
|
|
274
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs?${params.toString()}`, { method: "GET" }, requestId);
|
|
275
|
+
}
|
|
276
|
+
async claimJobs(projectId, data = {}, requestId) {
|
|
277
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/claim`, {
|
|
278
|
+
method: "POST",
|
|
279
|
+
body: JSON.stringify(data)
|
|
280
|
+
}, requestId);
|
|
281
|
+
}
|
|
282
|
+
async heartbeatJob(projectId, jobId, requestId) {
|
|
283
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/heartbeat`, { method: "POST" }, requestId);
|
|
284
|
+
}
|
|
285
|
+
async completeJob(projectId, jobId, result, requestId) {
|
|
286
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/complete`, {
|
|
287
|
+
method: "POST",
|
|
288
|
+
body: JSON.stringify(result)
|
|
289
|
+
}, requestId);
|
|
290
|
+
}
|
|
291
|
+
async failJob(projectId, jobId, error, requestId) {
|
|
292
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/fail`, {
|
|
293
|
+
method: "POST",
|
|
294
|
+
body: JSON.stringify(error)
|
|
295
|
+
}, requestId);
|
|
296
|
+
}
|
|
297
|
+
async listDeadJobs(projectId, requestId) {
|
|
298
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/dead`, { method: "GET" }, requestId);
|
|
299
|
+
}
|
|
300
|
+
async replayJob(projectId, jobId, requestId) {
|
|
301
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/replay`, { method: "POST" }, requestId);
|
|
302
|
+
}
|
|
303
|
+
// --- Evidence ---
|
|
304
|
+
async getEvidence(jobId, requestId) {
|
|
305
|
+
return this.transport.request(`/v1/jobs/evidence/${jobId}`, { method: "GET" }, requestId);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* @deprecated The current Control Plane version does not support direct artifact downloads.
|
|
309
|
+
* Please use getEvidence() to retrieve the artifact metadata and content.
|
|
310
|
+
*/
|
|
311
|
+
async downloadEvidenceArtifact(jobId, requestId) {
|
|
312
|
+
throw new Error("Artifact download not supported by current API version. Use getEvidence() to retrieve content.");
|
|
313
|
+
}
|
|
314
|
+
// --- Webhooks ---
|
|
315
|
+
async listWebhooks(projectId, requestId) {
|
|
316
|
+
return this.transport.request(`/v1/projects/${projectId}/webhooks`, { method: "GET" }, requestId);
|
|
317
|
+
}
|
|
318
|
+
async createWebhook(projectId, data, requestId) {
|
|
319
|
+
return this.transport.request(`/v1/projects/${projectId}/webhooks`, {
|
|
320
|
+
method: "POST",
|
|
321
|
+
body: JSON.stringify(data)
|
|
322
|
+
}, requestId);
|
|
323
|
+
}
|
|
324
|
+
async updateWebhook(webhookId, data, requestId) {
|
|
325
|
+
return this.transport.request(`/v1/webhooks/${webhookId}`, {
|
|
326
|
+
method: "PATCH",
|
|
327
|
+
body: JSON.stringify(data)
|
|
328
|
+
}, requestId);
|
|
329
|
+
}
|
|
330
|
+
async deleteWebhook(webhookId, requestId) {
|
|
331
|
+
return this.transport.request(`/v1/webhooks/${webhookId}`, { method: "DELETE" }, requestId);
|
|
332
|
+
}
|
|
333
|
+
async rotateWebhookSecret(webhookId, requestId) {
|
|
334
|
+
return this.transport.request(`/v1/webhooks/${webhookId}/rotate-secret`, { method: "POST" }, requestId);
|
|
335
|
+
}
|
|
336
|
+
async enableWebhook(webhookId, requestId) {
|
|
337
|
+
return this.updateWebhook(webhookId, { enabled: true }, requestId);
|
|
338
|
+
}
|
|
339
|
+
async disableWebhook(webhookId, requestId) {
|
|
340
|
+
return this.updateWebhook(webhookId, { enabled: false }, requestId);
|
|
341
|
+
}
|
|
342
|
+
// --- Webhook Deliveries ---
|
|
343
|
+
async listWebhookDeliveries(webhookId, filters = {}, requestId) {
|
|
344
|
+
const params = new URLSearchParams();
|
|
345
|
+
if (filters.status) params.append("status", filters.status);
|
|
346
|
+
if (filters.eventType) params.append("eventType", filters.eventType);
|
|
347
|
+
if (filters.limit) params.append("limit", filters.limit.toString());
|
|
348
|
+
if (filters.offset) params.append("offset", filters.offset.toString());
|
|
349
|
+
return this.transport.request(`/v1/webhooks/${webhookId}/deliveries?${params.toString()}`, { method: "GET" }, requestId);
|
|
350
|
+
}
|
|
351
|
+
async replayWebhookDelivery(deliveryId, requestId) {
|
|
352
|
+
return this.transport.request(`/v1/webhook-deliveries/${deliveryId}/replay`, { method: "POST" }, requestId);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
356
|
+
0 && (module.exports = {
|
|
357
|
+
Forg3tApiConnectionError,
|
|
358
|
+
Forg3tAuthenticationError,
|
|
359
|
+
Forg3tClient,
|
|
360
|
+
Forg3tError,
|
|
361
|
+
Forg3tNotFoundError,
|
|
362
|
+
Forg3tRateLimitError
|
|
363
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var Forg3tError = class extends Error {
|
|
3
|
+
constructor(message, status, code, requestId, details) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.status = status;
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.requestId = requestId;
|
|
8
|
+
this.details = details;
|
|
9
|
+
this.name = "Forg3tError";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var Forg3tAuthenticationError = class extends Forg3tError {
|
|
13
|
+
constructor(message, requestId) {
|
|
14
|
+
super(message, 401, "AUTHENTICATION_ERROR", requestId);
|
|
15
|
+
this.name = "Forg3tAuthenticationError";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var Forg3tNotFoundError = class extends Forg3tError {
|
|
19
|
+
constructor(message, requestId) {
|
|
20
|
+
super(message, 404, "NOT_FOUND", requestId);
|
|
21
|
+
this.name = "Forg3tNotFoundError";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var Forg3tRateLimitError = class extends Forg3tError {
|
|
25
|
+
constructor(message, requestId) {
|
|
26
|
+
super(message, 429, "RATE_LIMIT_EXCEEDED", requestId);
|
|
27
|
+
this.name = "Forg3tRateLimitError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var Forg3tApiConnectionError = class extends Forg3tError {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "Forg3tApiConnectionError";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/transport.ts
|
|
38
|
+
var Transport = class {
|
|
39
|
+
constructor(config) {
|
|
40
|
+
this.baseUrl = config.baseUrl || typeof process !== "undefined" && process.env.FORG3T_API_URL || "";
|
|
41
|
+
if (!this.baseUrl) {
|
|
42
|
+
throw new Error("Forg3tClient: apiUrl option or FORG3T_API_URL environment variable is required");
|
|
43
|
+
}
|
|
44
|
+
if (this.baseUrl.endsWith("/")) {
|
|
45
|
+
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
46
|
+
}
|
|
47
|
+
this.apiKey = config.apiKey || (typeof process !== "undefined" ? process.env.FORG3T_API_KEY : void 0);
|
|
48
|
+
this.timeoutMs = config.timeoutMs || 3e4;
|
|
49
|
+
}
|
|
50
|
+
getBaseUrl() {
|
|
51
|
+
return this.baseUrl;
|
|
52
|
+
}
|
|
53
|
+
async request(path, options = {}, requestId) {
|
|
54
|
+
const url = `${this.baseUrl}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
55
|
+
const headers = {
|
|
56
|
+
"Content-Type": "application/json",
|
|
57
|
+
"Accept": "application/json",
|
|
58
|
+
...options.headers || {}
|
|
59
|
+
};
|
|
60
|
+
if (this.apiKey) {
|
|
61
|
+
headers["x-api-key"] = this.apiKey;
|
|
62
|
+
}
|
|
63
|
+
if (requestId) {
|
|
64
|
+
headers["x-request-id"] = requestId;
|
|
65
|
+
}
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
68
|
+
const signal = controller.signal;
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(url, {
|
|
71
|
+
...options,
|
|
72
|
+
headers,
|
|
73
|
+
signal
|
|
74
|
+
// Add the abort signal
|
|
75
|
+
});
|
|
76
|
+
clearTimeout(timeoutId);
|
|
77
|
+
const responseRequestId = response.headers.get("x-request-id") || requestId;
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
let errorData = {};
|
|
80
|
+
try {
|
|
81
|
+
errorData = await response.json();
|
|
82
|
+
} catch {
|
|
83
|
+
errorData = { error: response.statusText };
|
|
84
|
+
}
|
|
85
|
+
const message = errorData.error || errorData.message || "Unknown error occurred";
|
|
86
|
+
if (response.status === 401 || response.status === 403) {
|
|
87
|
+
throw new Forg3tAuthenticationError(message, responseRequestId);
|
|
88
|
+
}
|
|
89
|
+
if (response.status === 404) {
|
|
90
|
+
throw new Forg3tNotFoundError(message, responseRequestId);
|
|
91
|
+
}
|
|
92
|
+
if (response.status === 429) {
|
|
93
|
+
throw new Forg3tRateLimitError(message, responseRequestId);
|
|
94
|
+
}
|
|
95
|
+
throw new Forg3tError(
|
|
96
|
+
message,
|
|
97
|
+
response.status,
|
|
98
|
+
errorData.code,
|
|
99
|
+
responseRequestId,
|
|
100
|
+
errorData
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
if (response.status === 204) {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
return await response.json();
|
|
107
|
+
} catch (error) {
|
|
108
|
+
clearTimeout(timeoutId);
|
|
109
|
+
if (error instanceof Forg3tError) {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
113
|
+
throw new Forg3tApiConnectionError(`Request timeout after ${this.timeoutMs}ms`);
|
|
114
|
+
}
|
|
115
|
+
throw new Forg3tApiConnectionError(error instanceof Error ? error.message : "Network error");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async download(url, requestId) {
|
|
119
|
+
const headers = {
|
|
120
|
+
"Accept": "*/*"
|
|
121
|
+
// Accept any type for downloads
|
|
122
|
+
};
|
|
123
|
+
if (this.apiKey) {
|
|
124
|
+
headers["x-api-key"] = this.apiKey;
|
|
125
|
+
}
|
|
126
|
+
if (requestId) {
|
|
127
|
+
headers["x-request-id"] = requestId;
|
|
128
|
+
}
|
|
129
|
+
const controller = new AbortController();
|
|
130
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
131
|
+
const signal = controller.signal;
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch(url, {
|
|
134
|
+
method: "GET",
|
|
135
|
+
headers,
|
|
136
|
+
signal
|
|
137
|
+
// Add the abort signal
|
|
138
|
+
});
|
|
139
|
+
clearTimeout(timeoutId);
|
|
140
|
+
if (!response.ok) {
|
|
141
|
+
let errorData = {};
|
|
142
|
+
try {
|
|
143
|
+
errorData = await response.json();
|
|
144
|
+
} catch {
|
|
145
|
+
errorData = { error: response.statusText };
|
|
146
|
+
}
|
|
147
|
+
const message = errorData.error || errorData.message || "Unknown error occurred";
|
|
148
|
+
if (response.status === 401 || response.status === 403) {
|
|
149
|
+
throw new Forg3tAuthenticationError(message, requestId);
|
|
150
|
+
}
|
|
151
|
+
if (response.status === 404) {
|
|
152
|
+
throw new Forg3tNotFoundError(message, requestId);
|
|
153
|
+
}
|
|
154
|
+
if (response.status === 429) {
|
|
155
|
+
throw new Forg3tRateLimitError(message, requestId);
|
|
156
|
+
}
|
|
157
|
+
throw new Forg3tError(
|
|
158
|
+
message,
|
|
159
|
+
response.status,
|
|
160
|
+
errorData.code,
|
|
161
|
+
requestId,
|
|
162
|
+
errorData
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return await response.blob();
|
|
166
|
+
} catch (error) {
|
|
167
|
+
clearTimeout(timeoutId);
|
|
168
|
+
if (error instanceof Forg3tError) {
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
172
|
+
throw new Forg3tApiConnectionError(`Download timeout after ${this.timeoutMs}ms`);
|
|
173
|
+
}
|
|
174
|
+
throw new Forg3tApiConnectionError(error instanceof Error ? error.message : "Network error");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/client.ts
|
|
180
|
+
var Forg3tClient = class {
|
|
181
|
+
constructor(options = {}) {
|
|
182
|
+
this.transport = new Transport({
|
|
183
|
+
baseUrl: options.apiUrl,
|
|
184
|
+
apiKey: options.apiKey,
|
|
185
|
+
timeoutMs: options.timeoutMs
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// --- Projects ---
|
|
189
|
+
async getProjectOverview(projectId, requestId) {
|
|
190
|
+
return this.transport.request(`/v1/projects/${projectId}/overview`, { method: "GET" }, requestId);
|
|
191
|
+
}
|
|
192
|
+
async listAuditEvents(projectId, filters = {}, requestId) {
|
|
193
|
+
const params = new URLSearchParams();
|
|
194
|
+
if (filters.action) params.append("action", filters.action);
|
|
195
|
+
if (filters.resourceType) params.append("resourceType", filters.resourceType);
|
|
196
|
+
if (filters.resourceId) params.append("resourceId", filters.resourceId);
|
|
197
|
+
if (filters.from) params.append("from", filters.from);
|
|
198
|
+
if (filters.to) params.append("to", filters.to);
|
|
199
|
+
if (filters.limit) params.append("limit", filters.limit.toString());
|
|
200
|
+
if (filters.cursor) params.append("cursor", filters.cursor);
|
|
201
|
+
return this.transport.request(`/v1/projects/${projectId}/audit?${params.toString()}`, { method: "GET" }, requestId);
|
|
202
|
+
}
|
|
203
|
+
// --- API Keys ---
|
|
204
|
+
async listApiKeys(projectId, requestId) {
|
|
205
|
+
return this.transport.request(`/v1/projects/${projectId}/api-keys`, { method: "GET" }, requestId);
|
|
206
|
+
}
|
|
207
|
+
async createApiKey(projectId, data, requestId) {
|
|
208
|
+
return this.transport.request(`/v1/projects/${projectId}/api-keys`, {
|
|
209
|
+
method: "POST",
|
|
210
|
+
body: JSON.stringify(data)
|
|
211
|
+
}, requestId);
|
|
212
|
+
}
|
|
213
|
+
async rotateApiKey(keyId, requestId) {
|
|
214
|
+
return this.transport.request(`/v1/api-keys/${keyId}/rotate`, { method: "POST" }, requestId);
|
|
215
|
+
}
|
|
216
|
+
async revokeApiKey(keyId, requestId) {
|
|
217
|
+
return this.transport.request(`/v1/api-keys/${keyId}/revoke`, { method: "POST" }, requestId);
|
|
218
|
+
}
|
|
219
|
+
// --- Jobs ---
|
|
220
|
+
async submitJob(projectId, data, requestId) {
|
|
221
|
+
const res = await this.transport.request(`/v1/projects/${projectId}/jobs`, {
|
|
222
|
+
method: "POST",
|
|
223
|
+
body: JSON.stringify(data)
|
|
224
|
+
}, requestId);
|
|
225
|
+
if (res && res.jobId && !res.id) {
|
|
226
|
+
return {
|
|
227
|
+
...res,
|
|
228
|
+
id: res.jobId,
|
|
229
|
+
projectId
|
|
230
|
+
// Ensure projectId is present if server omits it in minimal response
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return res;
|
|
234
|
+
}
|
|
235
|
+
async getJob(projectId, jobId, requestId) {
|
|
236
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}`, { method: "GET" }, requestId);
|
|
237
|
+
}
|
|
238
|
+
async listJobs(projectId, query, requestId) {
|
|
239
|
+
const params = new URLSearchParams();
|
|
240
|
+
if (query?.status) params.append("status", query.status);
|
|
241
|
+
if (query?.limit) params.append("limit", query.limit.toString());
|
|
242
|
+
if (query?.offset) params.append("offset", query.offset.toString());
|
|
243
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs?${params.toString()}`, { method: "GET" }, requestId);
|
|
244
|
+
}
|
|
245
|
+
async claimJobs(projectId, data = {}, requestId) {
|
|
246
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/claim`, {
|
|
247
|
+
method: "POST",
|
|
248
|
+
body: JSON.stringify(data)
|
|
249
|
+
}, requestId);
|
|
250
|
+
}
|
|
251
|
+
async heartbeatJob(projectId, jobId, requestId) {
|
|
252
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/heartbeat`, { method: "POST" }, requestId);
|
|
253
|
+
}
|
|
254
|
+
async completeJob(projectId, jobId, result, requestId) {
|
|
255
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/complete`, {
|
|
256
|
+
method: "POST",
|
|
257
|
+
body: JSON.stringify(result)
|
|
258
|
+
}, requestId);
|
|
259
|
+
}
|
|
260
|
+
async failJob(projectId, jobId, error, requestId) {
|
|
261
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/fail`, {
|
|
262
|
+
method: "POST",
|
|
263
|
+
body: JSON.stringify(error)
|
|
264
|
+
}, requestId);
|
|
265
|
+
}
|
|
266
|
+
async listDeadJobs(projectId, requestId) {
|
|
267
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/dead`, { method: "GET" }, requestId);
|
|
268
|
+
}
|
|
269
|
+
async replayJob(projectId, jobId, requestId) {
|
|
270
|
+
return this.transport.request(`/v1/projects/${projectId}/jobs/${jobId}/replay`, { method: "POST" }, requestId);
|
|
271
|
+
}
|
|
272
|
+
// --- Evidence ---
|
|
273
|
+
async getEvidence(jobId, requestId) {
|
|
274
|
+
return this.transport.request(`/v1/jobs/evidence/${jobId}`, { method: "GET" }, requestId);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* @deprecated The current Control Plane version does not support direct artifact downloads.
|
|
278
|
+
* Please use getEvidence() to retrieve the artifact metadata and content.
|
|
279
|
+
*/
|
|
280
|
+
async downloadEvidenceArtifact(jobId, requestId) {
|
|
281
|
+
throw new Error("Artifact download not supported by current API version. Use getEvidence() to retrieve content.");
|
|
282
|
+
}
|
|
283
|
+
// --- Webhooks ---
|
|
284
|
+
async listWebhooks(projectId, requestId) {
|
|
285
|
+
return this.transport.request(`/v1/projects/${projectId}/webhooks`, { method: "GET" }, requestId);
|
|
286
|
+
}
|
|
287
|
+
async createWebhook(projectId, data, requestId) {
|
|
288
|
+
return this.transport.request(`/v1/projects/${projectId}/webhooks`, {
|
|
289
|
+
method: "POST",
|
|
290
|
+
body: JSON.stringify(data)
|
|
291
|
+
}, requestId);
|
|
292
|
+
}
|
|
293
|
+
async updateWebhook(webhookId, data, requestId) {
|
|
294
|
+
return this.transport.request(`/v1/webhooks/${webhookId}`, {
|
|
295
|
+
method: "PATCH",
|
|
296
|
+
body: JSON.stringify(data)
|
|
297
|
+
}, requestId);
|
|
298
|
+
}
|
|
299
|
+
async deleteWebhook(webhookId, requestId) {
|
|
300
|
+
return this.transport.request(`/v1/webhooks/${webhookId}`, { method: "DELETE" }, requestId);
|
|
301
|
+
}
|
|
302
|
+
async rotateWebhookSecret(webhookId, requestId) {
|
|
303
|
+
return this.transport.request(`/v1/webhooks/${webhookId}/rotate-secret`, { method: "POST" }, requestId);
|
|
304
|
+
}
|
|
305
|
+
async enableWebhook(webhookId, requestId) {
|
|
306
|
+
return this.updateWebhook(webhookId, { enabled: true }, requestId);
|
|
307
|
+
}
|
|
308
|
+
async disableWebhook(webhookId, requestId) {
|
|
309
|
+
return this.updateWebhook(webhookId, { enabled: false }, requestId);
|
|
310
|
+
}
|
|
311
|
+
// --- Webhook Deliveries ---
|
|
312
|
+
async listWebhookDeliveries(webhookId, filters = {}, requestId) {
|
|
313
|
+
const params = new URLSearchParams();
|
|
314
|
+
if (filters.status) params.append("status", filters.status);
|
|
315
|
+
if (filters.eventType) params.append("eventType", filters.eventType);
|
|
316
|
+
if (filters.limit) params.append("limit", filters.limit.toString());
|
|
317
|
+
if (filters.offset) params.append("offset", filters.offset.toString());
|
|
318
|
+
return this.transport.request(`/v1/webhooks/${webhookId}/deliveries?${params.toString()}`, { method: "GET" }, requestId);
|
|
319
|
+
}
|
|
320
|
+
async replayWebhookDelivery(deliveryId, requestId) {
|
|
321
|
+
return this.transport.request(`/v1/webhook-deliveries/${deliveryId}/replay`, { method: "POST" }, requestId);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
export {
|
|
325
|
+
Forg3tApiConnectionError,
|
|
326
|
+
Forg3tAuthenticationError,
|
|
327
|
+
Forg3tClient,
|
|
328
|
+
Forg3tError,
|
|
329
|
+
Forg3tNotFoundError,
|
|
330
|
+
Forg3tRateLimitError
|
|
331
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forg3t/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official TypeScript SDK for Forg3t Protocol",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
25
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
26
|
+
"lint": "eslint src/",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"test": "npm run typecheck && npm run lint:cleanroom && npm run lint:no-localhost && npm run test:contract && npm run test:exports && npm run test:types",
|
|
29
|
+
"test:contract": "node tools/probe_contract.mjs",
|
|
30
|
+
"test:exports": "node tools/exports_smoke_esm.mjs && node tools/exports_smoke_cjs.cjs",
|
|
31
|
+
"test:types": "npx tsc tools/types_smoke.ts --noEmit",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"lint:cleanroom": "node scripts/cleanroom_check.js",
|
|
34
|
+
"lint:no-localhost": "node scripts/no_localhost_check.js",
|
|
35
|
+
"pack:check": "npm pack --dry-run"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"forg3t",
|
|
39
|
+
"sdk",
|
|
40
|
+
"unlearning"
|
|
41
|
+
],
|
|
42
|
+
"author": "Forg3t Inc.",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.0.0",
|
|
47
|
+
"@types/node": "^20.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {}
|
|
50
|
+
}
|