@codmir/client 2.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.d.mts +81 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +267 -0
- package/dist/index.mjs +238 -0
- package/package.json +34 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ChatRequest, ChatResponse, PaginatedResponse, TicketResponse, ApiResponse, CreateTicketRequest, UpdateTicketRequest, ProjectResponse, CreateProjectRequest, ExecuteAgentRequest, AgentExecutionResponse, ApiError as ApiError$1 } from '@codmir/types';
|
|
2
|
+
export { AgentExecutionResponse, ApiResponse, ChatRequest, ChatResponse, CreateProjectRequest, CreateTicketRequest, ExecuteAgentRequest, PaginatedResponse, ProjectResponse, TicketResponse } from '@codmir/types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Client Configuration Types
|
|
6
|
+
*/
|
|
7
|
+
interface ClientConfig {
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
onError?: (error: Error) => void;
|
|
13
|
+
onRequest?: (request: RequestInit) => RequestInit;
|
|
14
|
+
onResponse?: (response: Response) => Response;
|
|
15
|
+
}
|
|
16
|
+
interface RequestOptions {
|
|
17
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
body?: unknown;
|
|
20
|
+
timeout?: number;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Codmir API Client
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
declare class CodmirClient {
|
|
30
|
+
private config;
|
|
31
|
+
constructor(config?: ClientConfig);
|
|
32
|
+
private request;
|
|
33
|
+
private stream;
|
|
34
|
+
private buildUrl;
|
|
35
|
+
private buildHeaders;
|
|
36
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
37
|
+
chatStream(request: ChatRequest & {
|
|
38
|
+
stream: true;
|
|
39
|
+
}): AsyncGenerator<string, void, unknown>;
|
|
40
|
+
getTickets(params?: {
|
|
41
|
+
projectId?: string;
|
|
42
|
+
status?: string;
|
|
43
|
+
page?: number;
|
|
44
|
+
limit?: number;
|
|
45
|
+
}): Promise<PaginatedResponse<TicketResponse>>;
|
|
46
|
+
getTicket(id: string): Promise<ApiResponse<TicketResponse>>;
|
|
47
|
+
createTicket(data: CreateTicketRequest): Promise<ApiResponse<TicketResponse>>;
|
|
48
|
+
updateTicket(id: string, data: UpdateTicketRequest): Promise<ApiResponse<TicketResponse>>;
|
|
49
|
+
deleteTicket(id: string): Promise<ApiResponse<void>>;
|
|
50
|
+
getProjects(params?: {
|
|
51
|
+
workspaceId?: string;
|
|
52
|
+
page?: number;
|
|
53
|
+
limit?: number;
|
|
54
|
+
}): Promise<PaginatedResponse<ProjectResponse>>;
|
|
55
|
+
getProject(id: string): Promise<ApiResponse<ProjectResponse>>;
|
|
56
|
+
createProject(data: CreateProjectRequest): Promise<ApiResponse<ProjectResponse>>;
|
|
57
|
+
executeAgent(data: ExecuteAgentRequest): Promise<ApiResponse<AgentExecutionResponse>>;
|
|
58
|
+
getAgentExecution(id: string): Promise<ApiResponse<AgentExecutionResponse>>;
|
|
59
|
+
health(): Promise<{
|
|
60
|
+
status: string;
|
|
61
|
+
version: string;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
declare function createClient(config?: ClientConfig): CodmirClient;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* API Error Class
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
declare class ApiError extends Error implements ApiError$1 {
|
|
71
|
+
code: string;
|
|
72
|
+
status: number;
|
|
73
|
+
details?: Record<string, unknown>;
|
|
74
|
+
requestId?: string;
|
|
75
|
+
timestamp?: string;
|
|
76
|
+
constructor(error: ApiError$1);
|
|
77
|
+
static fromResponse(status: number, body: unknown): ApiError;
|
|
78
|
+
toJSON(): ApiError$1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { ApiError, type ClientConfig, CodmirClient, type RequestOptions, createClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ChatRequest, ChatResponse, PaginatedResponse, TicketResponse, ApiResponse, CreateTicketRequest, UpdateTicketRequest, ProjectResponse, CreateProjectRequest, ExecuteAgentRequest, AgentExecutionResponse, ApiError as ApiError$1 } from '@codmir/types';
|
|
2
|
+
export { AgentExecutionResponse, ApiResponse, ChatRequest, ChatResponse, CreateProjectRequest, CreateTicketRequest, ExecuteAgentRequest, PaginatedResponse, ProjectResponse, TicketResponse } from '@codmir/types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Client Configuration Types
|
|
6
|
+
*/
|
|
7
|
+
interface ClientConfig {
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
onError?: (error: Error) => void;
|
|
13
|
+
onRequest?: (request: RequestInit) => RequestInit;
|
|
14
|
+
onResponse?: (response: Response) => Response;
|
|
15
|
+
}
|
|
16
|
+
interface RequestOptions {
|
|
17
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
body?: unknown;
|
|
20
|
+
timeout?: number;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Codmir API Client
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
declare class CodmirClient {
|
|
30
|
+
private config;
|
|
31
|
+
constructor(config?: ClientConfig);
|
|
32
|
+
private request;
|
|
33
|
+
private stream;
|
|
34
|
+
private buildUrl;
|
|
35
|
+
private buildHeaders;
|
|
36
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
37
|
+
chatStream(request: ChatRequest & {
|
|
38
|
+
stream: true;
|
|
39
|
+
}): AsyncGenerator<string, void, unknown>;
|
|
40
|
+
getTickets(params?: {
|
|
41
|
+
projectId?: string;
|
|
42
|
+
status?: string;
|
|
43
|
+
page?: number;
|
|
44
|
+
limit?: number;
|
|
45
|
+
}): Promise<PaginatedResponse<TicketResponse>>;
|
|
46
|
+
getTicket(id: string): Promise<ApiResponse<TicketResponse>>;
|
|
47
|
+
createTicket(data: CreateTicketRequest): Promise<ApiResponse<TicketResponse>>;
|
|
48
|
+
updateTicket(id: string, data: UpdateTicketRequest): Promise<ApiResponse<TicketResponse>>;
|
|
49
|
+
deleteTicket(id: string): Promise<ApiResponse<void>>;
|
|
50
|
+
getProjects(params?: {
|
|
51
|
+
workspaceId?: string;
|
|
52
|
+
page?: number;
|
|
53
|
+
limit?: number;
|
|
54
|
+
}): Promise<PaginatedResponse<ProjectResponse>>;
|
|
55
|
+
getProject(id: string): Promise<ApiResponse<ProjectResponse>>;
|
|
56
|
+
createProject(data: CreateProjectRequest): Promise<ApiResponse<ProjectResponse>>;
|
|
57
|
+
executeAgent(data: ExecuteAgentRequest): Promise<ApiResponse<AgentExecutionResponse>>;
|
|
58
|
+
getAgentExecution(id: string): Promise<ApiResponse<AgentExecutionResponse>>;
|
|
59
|
+
health(): Promise<{
|
|
60
|
+
status: string;
|
|
61
|
+
version: string;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
declare function createClient(config?: ClientConfig): CodmirClient;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* API Error Class
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
declare class ApiError extends Error implements ApiError$1 {
|
|
71
|
+
code: string;
|
|
72
|
+
status: number;
|
|
73
|
+
details?: Record<string, unknown>;
|
|
74
|
+
requestId?: string;
|
|
75
|
+
timestamp?: string;
|
|
76
|
+
constructor(error: ApiError$1);
|
|
77
|
+
static fromResponse(status: number, body: unknown): ApiError;
|
|
78
|
+
toJSON(): ApiError$1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { ApiError, type ClientConfig, CodmirClient, type RequestOptions, createClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
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
|
+
ApiError: () => ApiError,
|
|
24
|
+
CodmirClient: () => CodmirClient,
|
|
25
|
+
createClient: () => createClient
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/error.ts
|
|
30
|
+
var ApiError = class _ApiError extends Error {
|
|
31
|
+
code;
|
|
32
|
+
status;
|
|
33
|
+
details;
|
|
34
|
+
requestId;
|
|
35
|
+
timestamp;
|
|
36
|
+
constructor(error) {
|
|
37
|
+
super(error.message);
|
|
38
|
+
this.name = "ApiError";
|
|
39
|
+
this.code = error.code;
|
|
40
|
+
this.status = error.status;
|
|
41
|
+
this.details = error.details;
|
|
42
|
+
this.requestId = error.requestId;
|
|
43
|
+
this.timestamp = error.timestamp;
|
|
44
|
+
}
|
|
45
|
+
static fromResponse(status, body) {
|
|
46
|
+
if (body && typeof body === "object" && "code" in body && "message" in body) {
|
|
47
|
+
return new _ApiError(body);
|
|
48
|
+
}
|
|
49
|
+
const defaultMessages = {
|
|
50
|
+
400: "Bad Request",
|
|
51
|
+
401: "Unauthorized",
|
|
52
|
+
403: "Forbidden",
|
|
53
|
+
404: "Not Found",
|
|
54
|
+
429: "Too Many Requests",
|
|
55
|
+
500: "Internal Server Error",
|
|
56
|
+
503: "Service Unavailable"
|
|
57
|
+
};
|
|
58
|
+
return new _ApiError({
|
|
59
|
+
code: `HTTP_${status}`,
|
|
60
|
+
message: defaultMessages[status] || `HTTP Error ${status}`,
|
|
61
|
+
status
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
toJSON() {
|
|
65
|
+
return {
|
|
66
|
+
code: this.code,
|
|
67
|
+
message: this.message,
|
|
68
|
+
status: this.status,
|
|
69
|
+
details: this.details,
|
|
70
|
+
requestId: this.requestId,
|
|
71
|
+
timestamp: this.timestamp
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// src/types.ts
|
|
77
|
+
var DEFAULT_CONFIG = {
|
|
78
|
+
baseUrl: typeof window !== "undefined" ? "" : "https://api.codmir.com",
|
|
79
|
+
timeout: 3e4
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// src/client.ts
|
|
83
|
+
var CodmirClient = class {
|
|
84
|
+
config;
|
|
85
|
+
constructor(config = {}) {
|
|
86
|
+
this.config = {
|
|
87
|
+
...DEFAULT_CONFIG,
|
|
88
|
+
...config
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async request(path, options = {}) {
|
|
92
|
+
const url = this.buildUrl(path, options.params);
|
|
93
|
+
const headers = this.buildHeaders(options.headers);
|
|
94
|
+
const controller = new AbortController();
|
|
95
|
+
const timeout = options.timeout ?? this.config.timeout ?? DEFAULT_CONFIG.timeout;
|
|
96
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
97
|
+
try {
|
|
98
|
+
let init = {
|
|
99
|
+
method: options.method || "GET",
|
|
100
|
+
headers,
|
|
101
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
102
|
+
signal: options.signal ?? controller.signal
|
|
103
|
+
};
|
|
104
|
+
if (this.config.onRequest) {
|
|
105
|
+
init = this.config.onRequest(init);
|
|
106
|
+
}
|
|
107
|
+
let response = await fetch(url, init);
|
|
108
|
+
if (this.config.onResponse) {
|
|
109
|
+
response = this.config.onResponse(response);
|
|
110
|
+
}
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
const body = await response.json().catch(() => null);
|
|
113
|
+
throw ApiError.fromResponse(response.status, body);
|
|
114
|
+
}
|
|
115
|
+
const data = await response.json();
|
|
116
|
+
return data;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (error instanceof ApiError) {
|
|
119
|
+
this.config.onError?.(error);
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
if (error instanceof Error) {
|
|
123
|
+
if (error.name === "AbortError") {
|
|
124
|
+
const timeoutError = new ApiError({
|
|
125
|
+
code: "TIMEOUT",
|
|
126
|
+
message: "Request timed out",
|
|
127
|
+
status: 504
|
|
128
|
+
});
|
|
129
|
+
this.config.onError?.(timeoutError);
|
|
130
|
+
throw timeoutError;
|
|
131
|
+
}
|
|
132
|
+
this.config.onError?.(error);
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
} finally {
|
|
136
|
+
clearTimeout(timeoutId);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async *stream(path, options = {}) {
|
|
140
|
+
const url = this.buildUrl(path, options.params);
|
|
141
|
+
const headers = this.buildHeaders(options.headers);
|
|
142
|
+
const response = await fetch(url, {
|
|
143
|
+
method: options.method || "POST",
|
|
144
|
+
headers,
|
|
145
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
146
|
+
signal: options.signal
|
|
147
|
+
});
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
const body = await response.json().catch(() => null);
|
|
150
|
+
throw ApiError.fromResponse(response.status, body);
|
|
151
|
+
}
|
|
152
|
+
const reader = response.body?.getReader();
|
|
153
|
+
if (!reader) throw new Error("No response body");
|
|
154
|
+
const decoder = new TextDecoder();
|
|
155
|
+
try {
|
|
156
|
+
while (true) {
|
|
157
|
+
const { done, value } = await reader.read();
|
|
158
|
+
if (done) break;
|
|
159
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
160
|
+
options.onChunk?.(chunk);
|
|
161
|
+
yield chunk;
|
|
162
|
+
}
|
|
163
|
+
options.onDone?.();
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if (error instanceof Error) {
|
|
166
|
+
options.onError?.(error);
|
|
167
|
+
}
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
buildUrl(path, params) {
|
|
172
|
+
const base = this.config.baseUrl || DEFAULT_CONFIG.baseUrl;
|
|
173
|
+
const url = new URL(path, base);
|
|
174
|
+
if (params) {
|
|
175
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
176
|
+
if (value !== void 0) {
|
|
177
|
+
url.searchParams.set(key, String(value));
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return url.toString();
|
|
182
|
+
}
|
|
183
|
+
buildHeaders(additional) {
|
|
184
|
+
const headers = {
|
|
185
|
+
"Content-Type": "application/json",
|
|
186
|
+
...this.config.headers,
|
|
187
|
+
...additional
|
|
188
|
+
};
|
|
189
|
+
if (this.config.apiKey) {
|
|
190
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
191
|
+
}
|
|
192
|
+
return headers;
|
|
193
|
+
}
|
|
194
|
+
// ============ Chat API ============
|
|
195
|
+
async chat(request) {
|
|
196
|
+
return this.request("/api/chat", {
|
|
197
|
+
method: "POST",
|
|
198
|
+
body: request
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
async *chatStream(request) {
|
|
202
|
+
yield* this.stream("/api/chat", {
|
|
203
|
+
method: "POST",
|
|
204
|
+
body: request
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// ============ Tickets API ============
|
|
208
|
+
async getTickets(params) {
|
|
209
|
+
return this.request("/api/tickets", { params });
|
|
210
|
+
}
|
|
211
|
+
async getTicket(id) {
|
|
212
|
+
return this.request(`/api/tickets/${id}`);
|
|
213
|
+
}
|
|
214
|
+
async createTicket(data) {
|
|
215
|
+
return this.request("/api/tickets", {
|
|
216
|
+
method: "POST",
|
|
217
|
+
body: data
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
async updateTicket(id, data) {
|
|
221
|
+
return this.request(`/api/tickets/${id}`, {
|
|
222
|
+
method: "PATCH",
|
|
223
|
+
body: data
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async deleteTicket(id) {
|
|
227
|
+
return this.request(`/api/tickets/${id}`, {
|
|
228
|
+
method: "DELETE"
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
// ============ Projects API ============
|
|
232
|
+
async getProjects(params) {
|
|
233
|
+
return this.request("/api/projects", { params });
|
|
234
|
+
}
|
|
235
|
+
async getProject(id) {
|
|
236
|
+
return this.request(`/api/projects/${id}`);
|
|
237
|
+
}
|
|
238
|
+
async createProject(data) {
|
|
239
|
+
return this.request("/api/projects", {
|
|
240
|
+
method: "POST",
|
|
241
|
+
body: data
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
// ============ Agent API ============
|
|
245
|
+
async executeAgent(data) {
|
|
246
|
+
return this.request("/api/agents/execute", {
|
|
247
|
+
method: "POST",
|
|
248
|
+
body: data
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
async getAgentExecution(id) {
|
|
252
|
+
return this.request(`/api/agents/executions/${id}`);
|
|
253
|
+
}
|
|
254
|
+
// ============ Health API ============
|
|
255
|
+
async health() {
|
|
256
|
+
return this.request("/api/health");
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
function createClient(config) {
|
|
260
|
+
return new CodmirClient(config);
|
|
261
|
+
}
|
|
262
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
263
|
+
0 && (module.exports = {
|
|
264
|
+
ApiError,
|
|
265
|
+
CodmirClient,
|
|
266
|
+
createClient
|
|
267
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
// src/error.ts
|
|
2
|
+
var ApiError = class _ApiError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
status;
|
|
5
|
+
details;
|
|
6
|
+
requestId;
|
|
7
|
+
timestamp;
|
|
8
|
+
constructor(error) {
|
|
9
|
+
super(error.message);
|
|
10
|
+
this.name = "ApiError";
|
|
11
|
+
this.code = error.code;
|
|
12
|
+
this.status = error.status;
|
|
13
|
+
this.details = error.details;
|
|
14
|
+
this.requestId = error.requestId;
|
|
15
|
+
this.timestamp = error.timestamp;
|
|
16
|
+
}
|
|
17
|
+
static fromResponse(status, body) {
|
|
18
|
+
if (body && typeof body === "object" && "code" in body && "message" in body) {
|
|
19
|
+
return new _ApiError(body);
|
|
20
|
+
}
|
|
21
|
+
const defaultMessages = {
|
|
22
|
+
400: "Bad Request",
|
|
23
|
+
401: "Unauthorized",
|
|
24
|
+
403: "Forbidden",
|
|
25
|
+
404: "Not Found",
|
|
26
|
+
429: "Too Many Requests",
|
|
27
|
+
500: "Internal Server Error",
|
|
28
|
+
503: "Service Unavailable"
|
|
29
|
+
};
|
|
30
|
+
return new _ApiError({
|
|
31
|
+
code: `HTTP_${status}`,
|
|
32
|
+
message: defaultMessages[status] || `HTTP Error ${status}`,
|
|
33
|
+
status
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
toJSON() {
|
|
37
|
+
return {
|
|
38
|
+
code: this.code,
|
|
39
|
+
message: this.message,
|
|
40
|
+
status: this.status,
|
|
41
|
+
details: this.details,
|
|
42
|
+
requestId: this.requestId,
|
|
43
|
+
timestamp: this.timestamp
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/types.ts
|
|
49
|
+
var DEFAULT_CONFIG = {
|
|
50
|
+
baseUrl: typeof window !== "undefined" ? "" : "https://api.codmir.com",
|
|
51
|
+
timeout: 3e4
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/client.ts
|
|
55
|
+
var CodmirClient = class {
|
|
56
|
+
config;
|
|
57
|
+
constructor(config = {}) {
|
|
58
|
+
this.config = {
|
|
59
|
+
...DEFAULT_CONFIG,
|
|
60
|
+
...config
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async request(path, options = {}) {
|
|
64
|
+
const url = this.buildUrl(path, options.params);
|
|
65
|
+
const headers = this.buildHeaders(options.headers);
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
const timeout = options.timeout ?? this.config.timeout ?? DEFAULT_CONFIG.timeout;
|
|
68
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
69
|
+
try {
|
|
70
|
+
let init = {
|
|
71
|
+
method: options.method || "GET",
|
|
72
|
+
headers,
|
|
73
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
74
|
+
signal: options.signal ?? controller.signal
|
|
75
|
+
};
|
|
76
|
+
if (this.config.onRequest) {
|
|
77
|
+
init = this.config.onRequest(init);
|
|
78
|
+
}
|
|
79
|
+
let response = await fetch(url, init);
|
|
80
|
+
if (this.config.onResponse) {
|
|
81
|
+
response = this.config.onResponse(response);
|
|
82
|
+
}
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
const body = await response.json().catch(() => null);
|
|
85
|
+
throw ApiError.fromResponse(response.status, body);
|
|
86
|
+
}
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
return data;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (error instanceof ApiError) {
|
|
91
|
+
this.config.onError?.(error);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
if (error instanceof Error) {
|
|
95
|
+
if (error.name === "AbortError") {
|
|
96
|
+
const timeoutError = new ApiError({
|
|
97
|
+
code: "TIMEOUT",
|
|
98
|
+
message: "Request timed out",
|
|
99
|
+
status: 504
|
|
100
|
+
});
|
|
101
|
+
this.config.onError?.(timeoutError);
|
|
102
|
+
throw timeoutError;
|
|
103
|
+
}
|
|
104
|
+
this.config.onError?.(error);
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
} finally {
|
|
108
|
+
clearTimeout(timeoutId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async *stream(path, options = {}) {
|
|
112
|
+
const url = this.buildUrl(path, options.params);
|
|
113
|
+
const headers = this.buildHeaders(options.headers);
|
|
114
|
+
const response = await fetch(url, {
|
|
115
|
+
method: options.method || "POST",
|
|
116
|
+
headers,
|
|
117
|
+
body: options.body ? JSON.stringify(options.body) : void 0,
|
|
118
|
+
signal: options.signal
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const body = await response.json().catch(() => null);
|
|
122
|
+
throw ApiError.fromResponse(response.status, body);
|
|
123
|
+
}
|
|
124
|
+
const reader = response.body?.getReader();
|
|
125
|
+
if (!reader) throw new Error("No response body");
|
|
126
|
+
const decoder = new TextDecoder();
|
|
127
|
+
try {
|
|
128
|
+
while (true) {
|
|
129
|
+
const { done, value } = await reader.read();
|
|
130
|
+
if (done) break;
|
|
131
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
132
|
+
options.onChunk?.(chunk);
|
|
133
|
+
yield chunk;
|
|
134
|
+
}
|
|
135
|
+
options.onDone?.();
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error instanceof Error) {
|
|
138
|
+
options.onError?.(error);
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
buildUrl(path, params) {
|
|
144
|
+
const base = this.config.baseUrl || DEFAULT_CONFIG.baseUrl;
|
|
145
|
+
const url = new URL(path, base);
|
|
146
|
+
if (params) {
|
|
147
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
148
|
+
if (value !== void 0) {
|
|
149
|
+
url.searchParams.set(key, String(value));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return url.toString();
|
|
154
|
+
}
|
|
155
|
+
buildHeaders(additional) {
|
|
156
|
+
const headers = {
|
|
157
|
+
"Content-Type": "application/json",
|
|
158
|
+
...this.config.headers,
|
|
159
|
+
...additional
|
|
160
|
+
};
|
|
161
|
+
if (this.config.apiKey) {
|
|
162
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
163
|
+
}
|
|
164
|
+
return headers;
|
|
165
|
+
}
|
|
166
|
+
// ============ Chat API ============
|
|
167
|
+
async chat(request) {
|
|
168
|
+
return this.request("/api/chat", {
|
|
169
|
+
method: "POST",
|
|
170
|
+
body: request
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async *chatStream(request) {
|
|
174
|
+
yield* this.stream("/api/chat", {
|
|
175
|
+
method: "POST",
|
|
176
|
+
body: request
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// ============ Tickets API ============
|
|
180
|
+
async getTickets(params) {
|
|
181
|
+
return this.request("/api/tickets", { params });
|
|
182
|
+
}
|
|
183
|
+
async getTicket(id) {
|
|
184
|
+
return this.request(`/api/tickets/${id}`);
|
|
185
|
+
}
|
|
186
|
+
async createTicket(data) {
|
|
187
|
+
return this.request("/api/tickets", {
|
|
188
|
+
method: "POST",
|
|
189
|
+
body: data
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async updateTicket(id, data) {
|
|
193
|
+
return this.request(`/api/tickets/${id}`, {
|
|
194
|
+
method: "PATCH",
|
|
195
|
+
body: data
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async deleteTicket(id) {
|
|
199
|
+
return this.request(`/api/tickets/${id}`, {
|
|
200
|
+
method: "DELETE"
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// ============ Projects API ============
|
|
204
|
+
async getProjects(params) {
|
|
205
|
+
return this.request("/api/projects", { params });
|
|
206
|
+
}
|
|
207
|
+
async getProject(id) {
|
|
208
|
+
return this.request(`/api/projects/${id}`);
|
|
209
|
+
}
|
|
210
|
+
async createProject(data) {
|
|
211
|
+
return this.request("/api/projects", {
|
|
212
|
+
method: "POST",
|
|
213
|
+
body: data
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
// ============ Agent API ============
|
|
217
|
+
async executeAgent(data) {
|
|
218
|
+
return this.request("/api/agents/execute", {
|
|
219
|
+
method: "POST",
|
|
220
|
+
body: data
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async getAgentExecution(id) {
|
|
224
|
+
return this.request(`/api/agents/executions/${id}`);
|
|
225
|
+
}
|
|
226
|
+
// ============ Health API ============
|
|
227
|
+
async health() {
|
|
228
|
+
return this.request("/api/health");
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
function createClient(config) {
|
|
232
|
+
return new CodmirClient(config);
|
|
233
|
+
}
|
|
234
|
+
export {
|
|
235
|
+
ApiError,
|
|
236
|
+
CodmirClient,
|
|
237
|
+
createClient
|
|
238
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codmir/client",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Codmir API client for browser and Node.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
17
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@codmir/types": "workspace:*"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^22.10.1",
|
|
28
|
+
"tsup": "^8.3.0",
|
|
29
|
+
"typescript": "^5.8.3"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|