archicore-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/LICENSE +21 -0
- package/README.md +221 -0
- package/dist/index.d.mts +258 -0
- package/dist/index.d.ts +258 -0
- package/dist/index.js +337 -0
- package/dist/index.mjs +307 -0
- package/package.json +61 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var ArchiCoreError = class extends Error {
|
|
3
|
+
constructor(message, code, statusCode) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "ArchiCoreError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.statusCode = statusCode;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var AuthenticationError = class extends ArchiCoreError {
|
|
11
|
+
constructor(message = "Invalid or missing API key") {
|
|
12
|
+
super(message, "UNAUTHORIZED", 401);
|
|
13
|
+
this.name = "AuthenticationError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var RateLimitError = class extends ArchiCoreError {
|
|
17
|
+
constructor(message = "Rate limit exceeded", retryAfter, limit, remaining) {
|
|
18
|
+
super(message, "RATE_LIMITED", 429);
|
|
19
|
+
this.name = "RateLimitError";
|
|
20
|
+
this.retryAfter = retryAfter;
|
|
21
|
+
this.limit = limit;
|
|
22
|
+
this.remaining = remaining;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var NotFoundError = class extends ArchiCoreError {
|
|
26
|
+
constructor(message = "Resource not found") {
|
|
27
|
+
super(message, "NOT_FOUND", 404);
|
|
28
|
+
this.name = "NotFoundError";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var ValidationError = class extends ArchiCoreError {
|
|
32
|
+
constructor(message = "Invalid request parameters") {
|
|
33
|
+
super(message, "VALIDATION_ERROR", 400);
|
|
34
|
+
this.name = "ValidationError";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
async function httpRequest(url, options) {
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timeout = options.timeout || 3e4;
|
|
40
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url, {
|
|
43
|
+
...options,
|
|
44
|
+
signal: controller.signal
|
|
45
|
+
});
|
|
46
|
+
clearTimeout(timeoutId);
|
|
47
|
+
return handleResponse(response);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
51
|
+
throw new ArchiCoreError("Request timed out", "TIMEOUT");
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function handleResponse(response) {
|
|
57
|
+
const rateLimitInfo = {
|
|
58
|
+
limit: response.headers.get("X-RateLimit-Limit"),
|
|
59
|
+
remaining: response.headers.get("X-RateLimit-Remaining"),
|
|
60
|
+
reset: response.headers.get("X-RateLimit-Reset")
|
|
61
|
+
};
|
|
62
|
+
if (response.ok) {
|
|
63
|
+
if (response.status === 204) {
|
|
64
|
+
return { success: true };
|
|
65
|
+
}
|
|
66
|
+
const text = await response.text();
|
|
67
|
+
return text ? JSON.parse(text) : { success: true };
|
|
68
|
+
}
|
|
69
|
+
let errorMessage = "Unknown error";
|
|
70
|
+
let errorCode;
|
|
71
|
+
try {
|
|
72
|
+
const errorData = await response.json();
|
|
73
|
+
errorMessage = errorData.error || errorData.message || errorMessage;
|
|
74
|
+
errorCode = errorData.code;
|
|
75
|
+
} catch {
|
|
76
|
+
errorMessage = response.statusText || errorMessage;
|
|
77
|
+
}
|
|
78
|
+
switch (response.status) {
|
|
79
|
+
case 401:
|
|
80
|
+
throw new AuthenticationError(errorMessage);
|
|
81
|
+
case 403:
|
|
82
|
+
throw new ArchiCoreError(errorMessage, "FORBIDDEN", 403);
|
|
83
|
+
case 404:
|
|
84
|
+
throw new NotFoundError(errorMessage);
|
|
85
|
+
case 429:
|
|
86
|
+
throw new RateLimitError(
|
|
87
|
+
errorMessage,
|
|
88
|
+
parseInt(response.headers.get("Retry-After") || "60", 10),
|
|
89
|
+
rateLimitInfo.limit ? parseInt(rateLimitInfo.limit, 10) : void 0,
|
|
90
|
+
rateLimitInfo.remaining ? parseInt(rateLimitInfo.remaining, 10) : void 0
|
|
91
|
+
);
|
|
92
|
+
case 400:
|
|
93
|
+
throw new ValidationError(errorMessage);
|
|
94
|
+
default:
|
|
95
|
+
if (response.status >= 500) {
|
|
96
|
+
throw new ArchiCoreError(errorMessage, "SERVER_ERROR", response.status);
|
|
97
|
+
}
|
|
98
|
+
throw new ArchiCoreError(errorMessage, errorCode, response.status);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
var ProjectsResource = class {
|
|
102
|
+
constructor(client) {
|
|
103
|
+
this.client = client;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* List all projects.
|
|
107
|
+
*/
|
|
108
|
+
async list() {
|
|
109
|
+
const response = await this.client.request("GET", "/projects");
|
|
110
|
+
return response.data || response.projects || [];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get a specific project by ID.
|
|
114
|
+
*/
|
|
115
|
+
async get(projectId) {
|
|
116
|
+
const response = await this.client.request("GET", `/projects/${projectId}`);
|
|
117
|
+
return response.data || response.project || response;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create a new project.
|
|
121
|
+
*/
|
|
122
|
+
async create(options) {
|
|
123
|
+
const response = await this.client.request("POST", "/projects", options);
|
|
124
|
+
return response.data || response.project || response;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Delete a project.
|
|
128
|
+
*/
|
|
129
|
+
async delete(projectId) {
|
|
130
|
+
await this.client.request("DELETE", `/projects/${projectId}`);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Trigger project indexing.
|
|
134
|
+
*/
|
|
135
|
+
async index(projectId, options) {
|
|
136
|
+
const response = await this.client.request(
|
|
137
|
+
"POST",
|
|
138
|
+
`/projects/${projectId}/index`,
|
|
139
|
+
options
|
|
140
|
+
);
|
|
141
|
+
return response.data || response;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Semantic search in project code.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const results = await client.projects.search('project-id', {
|
|
149
|
+
* query: 'authentication middleware'
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
async search(projectId, options) {
|
|
154
|
+
const response = await this.client.request(
|
|
155
|
+
"POST",
|
|
156
|
+
`/projects/${projectId}/search`,
|
|
157
|
+
options
|
|
158
|
+
);
|
|
159
|
+
return response.data || response.results || [];
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Ask AI assistant about the project.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const answer = await client.projects.ask('project-id', {
|
|
167
|
+
* question: 'How does the auth system work?'
|
|
168
|
+
* });
|
|
169
|
+
* console.log(answer.response);
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
async ask(projectId, options) {
|
|
173
|
+
const response = await this.client.request(
|
|
174
|
+
"POST",
|
|
175
|
+
`/projects/${projectId}/ask`,
|
|
176
|
+
options
|
|
177
|
+
);
|
|
178
|
+
return response.data || response;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get code metrics for a project.
|
|
182
|
+
*/
|
|
183
|
+
async metrics(projectId) {
|
|
184
|
+
const response = await this.client.request(
|
|
185
|
+
"GET",
|
|
186
|
+
`/projects/${projectId}/metrics`
|
|
187
|
+
);
|
|
188
|
+
return response.data || response.metrics || response;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get security scan results.
|
|
192
|
+
*/
|
|
193
|
+
async security(projectId) {
|
|
194
|
+
const response = await this.client.request(
|
|
195
|
+
"GET",
|
|
196
|
+
`/projects/${projectId}/security`
|
|
197
|
+
);
|
|
198
|
+
return response.data || response.security || response;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Perform impact analysis.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* const impact = await client.projects.analyze('project-id', {
|
|
206
|
+
* files: ['src/auth/login.ts']
|
|
207
|
+
* });
|
|
208
|
+
* console.log(`Affected: ${impact.affectedFiles.length} files`);
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
async analyze(projectId, options) {
|
|
212
|
+
const response = await this.client.request(
|
|
213
|
+
"POST",
|
|
214
|
+
`/projects/${projectId}/analyze`,
|
|
215
|
+
options
|
|
216
|
+
);
|
|
217
|
+
return response.data || response;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
var WebhooksResource = class {
|
|
221
|
+
constructor(client) {
|
|
222
|
+
this.client = client;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* List all webhooks.
|
|
226
|
+
*/
|
|
227
|
+
async list() {
|
|
228
|
+
const response = await this.client.request("GET", "/webhooks");
|
|
229
|
+
return response.data || response.webhooks || [];
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create a new webhook.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* const webhook = await client.webhooks.create({
|
|
237
|
+
* url: 'https://example.com/webhook',
|
|
238
|
+
* events: ['project.indexed', 'analysis.complete']
|
|
239
|
+
* });
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
async create(options) {
|
|
243
|
+
const response = await this.client.request("POST", "/webhooks", options);
|
|
244
|
+
return response.data || response.webhook || response;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Delete a webhook.
|
|
248
|
+
*/
|
|
249
|
+
async delete(webhookId) {
|
|
250
|
+
await this.client.request("DELETE", `/webhooks/${webhookId}`);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
var ArchiCore = class {
|
|
254
|
+
/**
|
|
255
|
+
* Create a new ArchiCore client.
|
|
256
|
+
*
|
|
257
|
+
* @param config - Client configuration
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const client = new ArchiCore({
|
|
262
|
+
* apiKey: 'your-api-key',
|
|
263
|
+
* baseUrl: 'https://api.archicore.io/api/v1' // optional
|
|
264
|
+
* });
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
constructor(config) {
|
|
268
|
+
if (!config.apiKey) {
|
|
269
|
+
throw new Error("apiKey is required");
|
|
270
|
+
}
|
|
271
|
+
this.apiKey = config.apiKey;
|
|
272
|
+
this.baseUrl = (config.baseUrl || "https://api.archicore.io/api/v1").replace(/\/+$/, "");
|
|
273
|
+
this.timeout = config.timeout || 3e4;
|
|
274
|
+
this.projects = new ProjectsResource(this);
|
|
275
|
+
this.webhooks = new WebhooksResource(this);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Make an API request.
|
|
279
|
+
* @internal
|
|
280
|
+
*/
|
|
281
|
+
async request(method, endpoint, data) {
|
|
282
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
283
|
+
const options = {
|
|
284
|
+
method,
|
|
285
|
+
headers: {
|
|
286
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
287
|
+
"Content-Type": "application/json",
|
|
288
|
+
"User-Agent": "@archicore/sdk/0.1.0"
|
|
289
|
+
},
|
|
290
|
+
timeout: this.timeout
|
|
291
|
+
};
|
|
292
|
+
if (data && ["POST", "PUT", "PATCH"].includes(method)) {
|
|
293
|
+
options.body = JSON.stringify(data);
|
|
294
|
+
}
|
|
295
|
+
return httpRequest(url, options);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
var index_default = ArchiCore;
|
|
299
|
+
export {
|
|
300
|
+
ArchiCore,
|
|
301
|
+
ArchiCoreError,
|
|
302
|
+
AuthenticationError,
|
|
303
|
+
NotFoundError,
|
|
304
|
+
RateLimitError,
|
|
305
|
+
ValidationError,
|
|
306
|
+
index_default as default
|
|
307
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "archicore-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official TypeScript/JavaScript SDK for ArchiCore Architecture Analysis API",
|
|
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
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
22
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"lint": "eslint src --ext .ts",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"archicore",
|
|
31
|
+
"architecture",
|
|
32
|
+
"code-analysis",
|
|
33
|
+
"api",
|
|
34
|
+
"sdk",
|
|
35
|
+
"typescript",
|
|
36
|
+
"ai",
|
|
37
|
+
"llm"
|
|
38
|
+
],
|
|
39
|
+
"author": "ArchiCore Team <support@archicore.io>",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/archicore/archicore-js.git"
|
|
44
|
+
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/archicore/archicore-js/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://archicore.io",
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=16.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^20.10.0",
|
|
54
|
+
"tsup": "^8.0.0",
|
|
55
|
+
"typescript": "^5.3.0",
|
|
56
|
+
"vitest": "^1.0.0",
|
|
57
|
+
"eslint": "^8.55.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
59
|
+
"@typescript-eslint/parser": "^6.13.0"
|
|
60
|
+
}
|
|
61
|
+
}
|