@devpad/api 1.0.1 → 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.
@@ -2,7 +2,7 @@ import { ApiClient as HttpClient } from "./request";
2
2
  import { wrap } from "./result";
3
3
  /**
4
4
  * API client with Result-wrapped operations for clean error handling
5
- * All methods return Result<T, name> types with context-aware property names
5
+ * All methods return ApiResult<T> types using @f0rbit/corpus Result
6
6
  */
7
7
  export class ApiClient {
8
8
  constructor(options) {
@@ -10,38 +10,12 @@ export class ApiClient {
10
10
  * Auth namespace with Result-wrapped operations
11
11
  */
12
12
  this.auth = {
13
- /**
14
- * Get current session information
15
- */
16
- session: () => wrap(() => this.clients.auth.get("/auth/session"), "session"),
17
- /**
18
- * Login (redirect to OAuth)
19
- */
20
- login: () => wrap(() => this.clients.auth.get("/auth/login"), "result"),
21
- /**
22
- * Logout
23
- */
24
- logout: () => wrap(() => this.clients.auth.get("/auth/logout"), "result"),
25
- /**
26
- * API key management
27
- */
13
+ session: () => wrap(() => this.clients.auth_root.get("/auth/session")),
28
14
  keys: {
29
- /**
30
- * List all API keys
31
- */
32
- list: () => wrap(() => this.clients.auth.get("/auth/keys"), "keys"),
33
- /**
34
- * Generate a new API key
35
- */
36
- create: (name) => wrap(() => this.clients.auth.post("/auth/keys", { body: name ? { name } : {} }), "key"),
37
- /**
38
- * Revoke an API key
39
- */
40
- revoke: (key_id) => wrap(() => this.clients.auth.delete(`/auth/keys/${key_id}`), "result"),
41
- /**
42
- * Remove an API key (alias for revoke)
43
- */
44
- remove: (key_id) => wrap(() => this.clients.auth.delete(`/auth/keys/${key_id}`), "result"),
15
+ list: () => wrap(() => this.clients.auth.get("/keys")),
16
+ create: (name) => wrap(() => this.clients.auth.post("/keys", { body: name ? { name } : {} })),
17
+ revoke: (key_id) => wrap(() => this.clients.auth.delete(`/keys/${key_id}`)),
18
+ remove: (key_id) => wrap(() => this.clients.auth.delete(`/keys/${key_id}`)),
45
19
  },
46
20
  };
47
21
  /**
@@ -51,35 +25,35 @@ export class ApiClient {
51
25
  /**
52
26
  * List projects with optional filtering
53
27
  */
54
- list: (filters) => wrap(() => this.clients.projects.get(filters?.private === false ? "/projects/public" : "/projects"), "projects"),
28
+ list: (filters) => wrap(() => this.clients.projects.get(filters?.private === false ? "/projects/public" : "/projects")),
55
29
  /**
56
30
  * Get project map
57
31
  */
58
32
  map: async (filters) => wrap(async () => {
59
- const { projects, error } = await this.projects.list(filters);
60
- if (error)
61
- throw new Error(error.message);
62
- return projects.reduce((acc, project) => {
63
- acc[project.project_id] = project;
33
+ const result = await this.projects.list(filters);
34
+ if (!result.ok)
35
+ throw new Error(result.error.message);
36
+ return result.value.reduce((acc, project) => {
37
+ acc[project.id] = project;
64
38
  return acc;
65
39
  }, {});
66
- }, "project_map"),
40
+ }),
67
41
  /**
68
42
  * Get project by ID
69
43
  */
70
- find: (id) => wrap(() => this.clients.projects.get("/projects", { query: { id } }), "project"),
44
+ find: (id) => wrap(() => this.clients.projects.get("/projects", { query: { id } })),
71
45
  /**
72
46
  * Get project by name
73
47
  */
74
- getByName: (name) => wrap(() => this.clients.projects.get("/projects", { query: { name } }), "project"),
48
+ getByName: (name) => wrap(() => this.clients.projects.get("/projects", { query: { name } })),
75
49
  /**
76
50
  * Get project by ID (throws if not found)
77
51
  */
78
- getById: (id) => wrap(() => this.clients.projects.get("/projects", { query: { id } }), "project"),
52
+ getById: (id) => wrap(() => this.clients.projects.get("/projects", { query: { id } })),
79
53
  /**
80
54
  * Create a new project
81
55
  */
82
- create: (data) => wrap(() => this.clients.projects.patch("/projects", { body: data }), "project"),
56
+ create: (data) => wrap(() => this.clients.projects.patch("/projects", { body: data })),
83
57
  /**
84
58
  * Update an existing project
85
59
  */
@@ -94,11 +68,12 @@ export class ApiClient {
94
68
  throw new Error("Changes parameter required for update");
95
69
  }
96
70
  // Fetch the existing project to get current values
97
- const { project, error } = await this.projects.find(id);
98
- if (error)
99
- throw new Error(error.message);
100
- if (!project)
71
+ const result = await this.projects.find(id);
72
+ if (!result.ok)
73
+ throw new Error(result.error.message);
74
+ if (!result.value)
101
75
  throw new Error(`Project with id ${id} not found`);
76
+ const project = result.value;
102
77
  // Merge changes with existing project data
103
78
  const updateData = {
104
79
  id: project.id,
@@ -119,7 +94,7 @@ export class ApiClient {
119
94
  ...changes,
120
95
  };
121
96
  return this.clients.projects.patch("/projects", { body: updateData });
122
- }, "project"),
97
+ }),
123
98
  /**
124
99
  * Project configuration operations
125
100
  */
@@ -127,37 +102,55 @@ export class ApiClient {
127
102
  /**
128
103
  * Get project configuration
129
104
  */
130
- load: (project_id) => wrap(() => this.clients.projects.get("/projects/config", { query: { project_id } }), "config"),
105
+ load: (project_id) => wrap(() => this.clients.projects.get("/projects/config", { query: { project_id } })),
131
106
  /**
132
107
  * Save project configuration
133
108
  */
134
- save: (request) => wrap(() => this.clients.projects.patch("/projects/save_config", { body: request }), "result"),
109
+ save: (request) => wrap(() => this.clients.projects.patch("/projects/save_config", { body: request })),
135
110
  },
136
111
  /**
137
112
  * Scanning operations
138
113
  */
139
114
  scan: {
140
115
  /**
141
- * Update scan status
116
+ * Initiate a repository scan (returns stream)
117
+ */
118
+ initiate: async (project_id) => {
119
+ const response = await fetch(`${this.clients.projects.url()}/projects/scan?project_id=${project_id}`, {
120
+ method: "POST",
121
+ headers: this.clients.projects.headers(),
122
+ });
123
+ if (!response.body) {
124
+ throw new Error("No response body");
125
+ }
126
+ const stream = response.body.pipeThrough(new TextDecoderStream());
127
+ return stream;
128
+ },
129
+ /**
130
+ * Get pending scan updates for a project
131
+ */
132
+ updates: (project_id) => wrap(() => this.clients.projects.get("/projects/updates", { query: { project_id } }).then(response => response.updates)),
133
+ /**
134
+ * Process scan results
142
135
  */
143
- updateStatus: (project_id, data) => wrap(() => this.clients.projects.post(`/projects/${project_id}/scan/status`, { body: data }), "result"),
136
+ update: (project_id, data) => wrap(() => this.clients.projects.post("/projects/scan_status", { query: { project_id }, body: data })),
144
137
  },
145
138
  /**
146
139
  * Get project history
147
140
  */
148
- history: (project_id) => wrap(() => this.clients.projects.get(`/projects/${project_id}/history`), "history"),
141
+ history: (project_id) => wrap(() => this.clients.projects.get(`/projects/${project_id}/history`)),
149
142
  /**
150
143
  * Legacy methods (keeping for compatibility)
151
144
  */
152
- upsert: (data) => wrap(() => this.clients.projects.patch("/projects", { body: data }), "project"),
145
+ upsert: (data) => wrap(() => this.clients.projects.patch("/projects", { body: data })),
153
146
  /**
154
147
  * Fetch project specification from GitHub
155
148
  */
156
- specification: (project_id) => wrap(() => this.clients.projects.get("/projects/fetch_spec", { query: { project_id } }), "specification"),
149
+ specification: (project_id) => wrap(() => this.clients.projects.get("/projects/fetch_spec", { query: { project_id } })),
157
150
  /**
158
151
  * Delete project (soft delete)
159
152
  */
160
- deleteProject: (project) => wrap(() => this.clients.projects.patch("/projects", { body: { ...project, deleted: true } }), "result"),
153
+ deleteProject: (project) => wrap(() => this.clients.projects.patch("/projects", { body: { ...project, deleted: true } })),
161
154
  };
162
155
  /**
163
156
  * Milestones namespace with Result-wrapped operations
@@ -166,11 +159,11 @@ export class ApiClient {
166
159
  /**
167
160
  * List milestones for authenticated user
168
161
  */
169
- list: () => wrap(() => this.clients.milestones.get("/milestones"), "milestones"),
162
+ list: () => wrap(() => this.clients.milestones.get("/milestones")),
170
163
  /**
171
164
  * Get milestones by project ID
172
165
  */
173
- getByProject: (project_id) => wrap(() => this.clients.milestones.get(`/projects/${project_id}/milestones`), "milestones"),
166
+ getByProject: (project_id) => wrap(() => this.clients.milestones.get(`/projects/${project_id}/milestones`)),
174
167
  /**
175
168
  * Get milestone by ID
176
169
  */
@@ -181,21 +174,22 @@ export class ApiClient {
181
174
  catch (error) {
182
175
  return null;
183
176
  }
184
- }, "milestone"),
177
+ }),
185
178
  /**
186
179
  * Create new milestone
187
180
  */
188
- create: (data) => wrap(() => this.clients.milestones.post("/milestones", { body: data }), "milestone"),
181
+ create: (data) => wrap(() => this.clients.milestones.post("/milestones", { body: data })),
189
182
  /**
190
183
  * Update milestone
191
184
  */
192
185
  update: async (id, data) => wrap(async () => {
193
186
  // Fetch the existing milestone to get required fields
194
- const { milestone, error } = await this.milestones.find(id);
195
- if (error)
196
- throw new Error(error.message);
197
- if (!milestone)
187
+ const result = await this.milestones.find(id);
188
+ if (!result.ok)
189
+ throw new Error(result.error.message);
190
+ if (!result.value)
198
191
  throw new Error(`Milestone with id ${id} not found`);
192
+ const milestone = result.value;
199
193
  // Merge changes with existing milestone data
200
194
  const updateData = {
201
195
  id: milestone.id,
@@ -206,15 +200,15 @@ export class ApiClient {
206
200
  target_version: data.target_version ?? milestone.target_version,
207
201
  };
208
202
  return this.clients.milestones.patch(`/milestones/${id}`, { body: updateData });
209
- }, "milestone"),
203
+ }),
210
204
  /**
211
205
  * Delete milestone (soft delete)
212
206
  */
213
- delete: (id) => wrap(() => this.clients.milestones.delete(`/milestones/${id}`), "result"),
207
+ delete: (id) => wrap(() => this.clients.milestones.delete(`/milestones/${id}`)),
214
208
  /**
215
209
  * Get goals for a milestone
216
210
  */
217
- goals: (id) => wrap(() => this.clients.milestones.get(`/milestones/${id}/goals`), "goals"),
211
+ goals: (id) => wrap(() => this.clients.milestones.get(`/milestones/${id}/goals`)),
218
212
  };
219
213
  /**
220
214
  * Goals namespace with Result-wrapped operations
@@ -223,25 +217,26 @@ export class ApiClient {
223
217
  /**
224
218
  * List goals for authenticated user
225
219
  */
226
- list: () => wrap(() => this.clients.goals.get("/goals"), "goals"),
220
+ list: () => wrap(() => this.clients.goals.get("/goals")),
227
221
  /**
228
222
  * Get goal by ID
229
223
  */
230
- find: (id) => wrap(() => this.clients.goals.get(`/goals/${id}`), "goal"),
224
+ find: (id) => wrap(() => this.clients.goals.get(`/goals/${id}`)),
231
225
  /**
232
226
  * Create new goal
233
227
  */
234
- create: (data) => wrap(() => this.clients.goals.post("/goals", { body: data }), "goal"),
228
+ create: (data) => wrap(() => this.clients.goals.post("/goals", { body: data })),
235
229
  /**
236
230
  * Update goal
237
231
  */
238
232
  update: async (id, data) => wrap(async () => {
239
233
  // Fetch the existing goal to get required fields
240
- const { goal, error } = await this.goals.find(id);
241
- if (error)
242
- throw new Error(error.message);
243
- if (!goal)
234
+ const result = await this.goals.find(id);
235
+ if (!result.ok)
236
+ throw new Error(result.error.message);
237
+ if (!result.value)
244
238
  throw new Error(`Goal with id ${id} not found`);
239
+ const goal = result.value;
245
240
  // Merge changes with existing goal data
246
241
  const updateData = {
247
242
  id: goal.id,
@@ -251,11 +246,11 @@ export class ApiClient {
251
246
  target_time: data.target_time ?? goal.target_time,
252
247
  };
253
248
  return this.clients.goals.patch(`/goals/${id}`, { body: updateData });
254
- }, "goal"),
249
+ }),
255
250
  /**
256
251
  * Delete goal (soft delete)
257
252
  */
258
- delete: (id) => wrap(() => this.clients.goals.delete(`/goals/${id}`), "result"),
253
+ delete: (id) => wrap(() => this.clients.goals.delete(`/goals/${id}`)),
259
254
  };
260
255
  /**
261
256
  * Tasks namespace with Result-wrapped operations
@@ -271,29 +266,30 @@ export class ApiClient {
271
266
  if (filters?.tag_id)
272
267
  query.tag = filters.tag_id;
273
268
  return this.clients.tasks.get("/tasks", Object.keys(query).length > 0 ? { query } : {});
274
- }, "tasks"),
269
+ }),
275
270
  /**
276
271
  * Get task by ID
277
272
  */
278
- find: (id) => wrap(() => this.clients.tasks.get("/tasks", { query: { id } }), "task"),
273
+ find: (id) => wrap(() => this.clients.tasks.get("/tasks", { query: { id } })),
279
274
  /**
280
275
  * Get tasks by project ID
281
276
  */
282
- getByProject: (project_id) => wrap(() => this.clients.tasks.get(`/tasks`, { query: { project: project_id } }), "tasks"),
277
+ getByProject: (project_id) => wrap(() => this.clients.tasks.get(`/tasks`, { query: { project: project_id } })),
283
278
  /**
284
279
  * Create a new task
285
280
  */
286
- create: (data) => wrap(() => this.clients.tasks.patch("/tasks", { body: data }), "task"),
281
+ create: (data) => wrap(() => this.clients.tasks.patch("/tasks", { body: data })),
287
282
  /**
288
283
  * Update an existing task
289
284
  */
290
285
  update: async (id, changes) => wrap(async () => {
291
286
  // Fetch existing task to merge changes
292
- const { task, error } = await this.tasks.find(id);
293
- if (error)
294
- throw new Error(error.message);
295
- if (!task)
287
+ const result = await this.tasks.find(id);
288
+ if (!result.ok)
289
+ throw new Error(result.error.message);
290
+ if (!result.value)
296
291
  throw new Error(`Task with id ${id} not found`);
292
+ const task = result.value;
297
293
  const updateData = {
298
294
  id,
299
295
  title: task.task.title,
@@ -309,19 +305,19 @@ export class ApiClient {
309
305
  ...changes,
310
306
  };
311
307
  return this.clients.tasks.patch("/tasks", { body: updateData });
312
- }, "task"),
308
+ }),
313
309
  /**
314
310
  * Upsert task (create or update)
315
311
  */
316
- upsert: (data) => wrap(() => this.clients.tasks.patch("/tasks", { body: data }), "task"),
312
+ upsert: (data) => wrap(() => this.clients.tasks.patch("/tasks", { body: data })),
317
313
  /**
318
314
  * Save tags for tasks
319
315
  */
320
- saveTags: (data) => wrap(() => this.clients.tasks.post("/tasks/save_tags", { body: data }), "result"),
316
+ saveTags: (data) => wrap(() => this.clients.tasks.patch("/tasks/save_tags", { body: data })),
321
317
  /**
322
318
  * Delete task (soft delete)
323
319
  */
324
- deleteTask: (task) => wrap(() => this.clients.tasks.patch("/tasks", { body: { ...task.task, deleted: true } }), "result"),
320
+ deleteTask: (task) => wrap(() => this.clients.tasks.patch("/tasks", { body: { ...task.task, deleted: true } })),
325
321
  /**
326
322
  * Task history operations
327
323
  */
@@ -329,7 +325,7 @@ export class ApiClient {
329
325
  /**
330
326
  * Get task history by task ID
331
327
  */
332
- get: (task_id) => wrap(() => this.clients.tasks.get(`/tasks/history/${task_id}`), "history"),
328
+ get: (task_id) => wrap(() => this.clients.tasks.get(`/tasks/history/${task_id}`)),
333
329
  },
334
330
  };
335
331
  /**
@@ -339,7 +335,7 @@ export class ApiClient {
339
335
  /**
340
336
  * List tags for authenticated user
341
337
  */
342
- list: () => wrap(() => this.clients.tags.get("/tags"), "tags"),
338
+ list: () => wrap(() => this.clients.tags.get("/tags")),
343
339
  };
344
340
  /**
345
341
  * GitHub namespace with Result-wrapped operations
@@ -348,11 +344,131 @@ export class ApiClient {
348
344
  /**
349
345
  * List repositories for authenticated user
350
346
  */
351
- repos: () => wrap(() => this.clients.github.get("/repos"), "repos"),
347
+ repos: () => wrap(() => this.clients.github.get("/repos")),
352
348
  /**
353
349
  * List branches for a GitHub repository
354
350
  */
355
- branches: (owner, repo) => wrap(() => this.clients.github.get(`/repos/${owner}/${repo}/branches`), "branches"),
351
+ branches: (owner, repo) => wrap(() => this.clients.github.get(`/repos/${owner}/${repo}/branches`)),
352
+ };
353
+ this.blog = {
354
+ posts: {
355
+ list: (params) => wrap(() => {
356
+ const query = {};
357
+ if (params?.category)
358
+ query.category = params.category;
359
+ if (params?.tag)
360
+ query.tag = params.tag;
361
+ if (params?.project)
362
+ query.project = params.project;
363
+ if (params?.status)
364
+ query.status = params.status;
365
+ if (params?.archived !== undefined)
366
+ query.archived = String(params.archived);
367
+ if (params?.limit)
368
+ query.limit = String(params.limit);
369
+ if (params?.offset !== undefined)
370
+ query.offset = String(params.offset);
371
+ if (params?.sort)
372
+ query.sort = params.sort;
373
+ return this.clients.blog.get("/blog/posts", Object.keys(query).length ? { query } : {});
374
+ }),
375
+ getBySlug: (slug) => wrap(() => this.clients.blog.get(`/blog/posts/${slug}`)),
376
+ create: (data) => wrap(() => this.clients.blog.post("/blog/posts", { body: data })),
377
+ update: (uuid, data) => wrap(() => this.clients.blog.put(`/blog/posts/${uuid}`, { body: data })),
378
+ delete: (uuid) => wrap(() => this.clients.blog.delete(`/blog/posts/${uuid}`)),
379
+ versions: (uuid) => wrap(() => this.clients.blog.get(`/blog/posts/${uuid}/versions`)),
380
+ version: (uuid, hash) => wrap(() => this.clients.blog.get(`/blog/posts/${uuid}/version/${hash}`)),
381
+ restore: (uuid, hash) => wrap(() => this.clients.blog.post(`/blog/posts/${uuid}/restore/${hash}`)),
382
+ },
383
+ tags: {
384
+ list: () => wrap(() => this.clients.blog.get("/blog/tags")),
385
+ getForPost: (uuid) => wrap(() => this.clients.blog.get(`/blog/tags/posts/${uuid}/tags`)),
386
+ setForPost: (uuid, tags) => wrap(() => this.clients.blog.put(`/blog/tags/posts/${uuid}/tags`, { body: { tags } })),
387
+ addToPost: (uuid, tags) => wrap(() => this.clients.blog.post(`/blog/tags/posts/${uuid}/tags`, { body: { tags } })),
388
+ removeFromPost: (uuid, tag) => wrap(() => this.clients.blog.delete(`/blog/tags/posts/${uuid}/tags/${tag}`)),
389
+ },
390
+ categories: {
391
+ tree: () => wrap(() => this.clients.blog.get("/blog/categories")),
392
+ create: (data) => wrap(() => this.clients.blog.post("/blog/categories", { body: data })),
393
+ update: (name, data) => wrap(() => this.clients.blog.put(`/blog/categories/${name}`, { body: data })),
394
+ delete: (name) => wrap(() => this.clients.blog.delete(`/blog/categories/${name}`)),
395
+ },
396
+ tokens: {
397
+ list: () => wrap(() => this.clients.blog.get("/blog/tokens")),
398
+ create: (data) => wrap(() => this.clients.blog.post("/blog/tokens", { body: data })),
399
+ update: (id, data) => wrap(() => this.clients.blog.put(`/blog/tokens/${id}`, { body: data })),
400
+ delete: (id) => wrap(() => this.clients.blog.delete(`/blog/tokens/${id}`)),
401
+ },
402
+ };
403
+ this.media = {
404
+ profiles: {
405
+ list: () => wrap(async () => {
406
+ const res = await this.clients.media.get("/profiles");
407
+ return res.profiles;
408
+ }),
409
+ create: (data) => wrap(() => this.clients.media.post("/profiles", { body: data })),
410
+ get: (id) => wrap(() => this.clients.media.get(`/profiles/${id}`)),
411
+ update: (id, data) => wrap(() => this.clients.media.patch(`/profiles/${id}`, { body: data })),
412
+ delete: (id) => wrap(() => this.clients.media.delete(`/profiles/${id}`)),
413
+ filters: {
414
+ list: (profile_id) => wrap(async () => {
415
+ const res = await this.clients.media.get(`/profiles/${profile_id}/filters`);
416
+ return res.filters;
417
+ }),
418
+ add: (profile_id, data) => wrap(() => this.clients.media.post(`/profiles/${profile_id}/filters`, { body: data })),
419
+ remove: (profile_id, filter_id) => wrap(() => this.clients.media.delete(`/profiles/${profile_id}/filters/${filter_id}`)),
420
+ },
421
+ timeline: (slug, params) => wrap(() => {
422
+ const query = {};
423
+ if (params?.limit)
424
+ query.limit = String(params.limit);
425
+ if (params?.before)
426
+ query.before = params.before;
427
+ return this.clients.media.get(`/profiles/${slug}/timeline`, Object.keys(query).length ? { query } : {});
428
+ }),
429
+ },
430
+ connections: {
431
+ list: (profile_id, options) => wrap(async () => {
432
+ const query = { profile_id };
433
+ if (options?.include_settings)
434
+ query.include_settings = "true";
435
+ const res = await this.clients.media.get("/connections", { query });
436
+ return res.accounts;
437
+ }),
438
+ create: (data) => wrap(() => this.clients.media.post("/connections", { body: data })),
439
+ delete: (account_id) => wrap(() => this.clients.media.delete(`/connections/${account_id}`)),
440
+ refresh: (account_id) => wrap(() => this.clients.media.post(`/connections/${account_id}/refresh`)),
441
+ refreshAll: () => wrap(() => this.clients.media.post("/connections/refresh-all")),
442
+ updateStatus: (account_id, is_active) => wrap(() => this.clients.media.patch(`/connections/${account_id}`, { body: { is_active } })),
443
+ settings: {
444
+ get: (account_id) => wrap(() => this.clients.media.get(`/connections/${account_id}/settings`)),
445
+ update: (account_id, settings) => wrap(() => this.clients.media.put(`/connections/${account_id}/settings`, { body: { settings } })),
446
+ },
447
+ repos: (account_id) => wrap(async () => {
448
+ const res = await this.clients.media.get(`/connections/${account_id}/repos`);
449
+ return res.repos;
450
+ }),
451
+ subreddits: (account_id) => wrap(async () => {
452
+ const res = await this.clients.media.get(`/connections/${account_id}/subreddits`);
453
+ return res.subreddits;
454
+ }),
455
+ },
456
+ credentials: {
457
+ check: (platform, profile_id) => wrap(() => this.clients.media.get(`/credentials/${platform}`, { query: { profile_id } })),
458
+ save: (platform, data) => wrap(() => this.clients.media.post(`/credentials/${platform}`, { body: data })),
459
+ delete: (platform, profile_id) => wrap(() => this.clients.media.delete(`/credentials/${platform}`, { query: { profile_id } })),
460
+ },
461
+ timeline: {
462
+ get: (user_id, params) => wrap(() => {
463
+ const query = {};
464
+ if (params?.from)
465
+ query.from = params.from;
466
+ if (params?.to)
467
+ query.to = params.to;
468
+ return this.clients.media.get(`/timeline/${user_id}`, Object.keys(query).length ? { query } : {});
469
+ }),
470
+ getRaw: (user_id, platform, account_id) => wrap(() => this.clients.media.get(`/timeline/${user_id}/raw/${platform}`, { query: { account_id } })),
471
+ },
356
472
  };
357
473
  /**
358
474
  * User namespace with Result-wrapped operations
@@ -361,29 +477,36 @@ export class ApiClient {
361
477
  /**
362
478
  * Get user activity history
363
479
  */
364
- history: () => wrap(() => this.clients.auth.get("/user/history"), "history"),
480
+ history: () => wrap(() => this.clients.auth.get("/user/history")),
365
481
  /**
366
482
  * Update user preferences
367
483
  */
368
- preferences: (data) => wrap(() => this.clients.auth.patch("/user/preferences", { body: data }), "result"),
484
+ preferences: (data) => wrap(() => this.clients.auth.patch("/user/preferences", { body: data })),
369
485
  };
370
- const v0_base_url = options.base_url || "http://localhost:4321/api/v0";
371
- this._api_key = options.api_key;
372
- this._auth_mode = options.auth_mode || (options.api_key.startsWith("jwt:") ? "session" : "key");
373
- // Create category-specific HTTP clients
486
+ const base_url = options.base_url || "http://localhost:4321/api/v1";
487
+ this._api_key = options.api_key ?? "";
488
+ this._auth_mode = options.auth_mode ?? (options.api_key?.startsWith("jwt:") ? "session" : options.api_key ? "key" : "cookie");
374
489
  const clientOptions = {
375
- base_url: v0_base_url,
490
+ base_url,
376
491
  api_key: options.api_key,
377
492
  max_history_size: options.max_history_size,
493
+ auth_mode: this._auth_mode,
494
+ credentials: options.credentials,
495
+ default_headers: options.default_headers,
496
+ custom_fetch: options.custom_fetch,
378
497
  };
498
+ const auth_base_url = base_url.replace(/\/v1\/?$/, "");
379
499
  this.clients = {
380
500
  auth: new HttpClient({ ...clientOptions, category: "auth" }),
501
+ auth_root: new HttpClient({ ...clientOptions, base_url: auth_base_url, category: "auth" }),
381
502
  projects: new HttpClient({ ...clientOptions, category: "projects" }),
382
503
  tasks: new HttpClient({ ...clientOptions, category: "tasks" }),
383
504
  milestones: new HttpClient({ ...clientOptions, category: "milestones" }),
384
505
  goals: new HttpClient({ ...clientOptions, category: "goals" }),
385
506
  github: new HttpClient({ ...clientOptions, category: "github" }),
386
507
  tags: new HttpClient({ ...clientOptions, category: "tags" }),
508
+ blog: new HttpClient({ ...clientOptions, category: "blog" }),
509
+ media: new HttpClient({ ...clientOptions, category: "media" }),
387
510
  };
388
511
  }
389
512
  /**
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import { ApiClient } from "./api-client";
2
2
  export type { Project, ProjectConfig, SaveConfigRequest, Task, TaskWithDetails, UpsertProject, UpsertTag, UpsertTodo, } from "@devpad/schema";
3
+ export type { AccessKey, Category, CategoryCreate, Post, PostContent, PostCreate, PostListParams, PostsResponse, PostUpdate, VersionInfo, } from "@devpad/schema/blog";
4
+ export type { Account, AddFilterInput, CreateProfileInput, PlatformSettings, Profile, ProfileFilter, Timeline, UpdateProfileInput, } from "@devpad/schema/media";
5
+ export type { AuthMode } from "./api-client";
3
6
  export { getUserFriendlyErrorMessage, parseZodErrors } from "./error-handlers";
4
7
  export type { ApiError, AuthenticationError, NetworkError, ValidationError } from "./errors";
5
8
  export type { RequestHistoryEntry, RequestOptions } from "./request";
6
- export type { AuthMode } from "./api-client";
7
- export { wrap, type Result, type Success, type Failure } from "./result";
8
- export { tools, getTool, toolNames, type ToolDefinition } from "./tools";
9
+ export { type ApiResult, type ApiResultError, err, ok, type Result, wrap } from "./result";
10
+ export { getTool, type ToolDefinition, toolNames, tools } from "./tools";
9
11
  export { ApiClient };
10
12
  export default ApiClient;
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,YAAY,EACX,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,eAAe,EACf,aAAa,EACb,SAAS,EACT,UAAU,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC7F,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACrE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,YAAY,EACX,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,IAAI,EACJ,eAAe,EACf,aAAa,EACb,SAAS,EACT,UAAU,GACV,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,SAAS,EACT,QAAQ,EACR,cAAc,EACd,IAAI,EACJ,WAAW,EACX,UAAU,EACV,cAAc,EACd,aAAa,EACb,UAAU,EACV,WAAW,GACX,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACX,OAAO,EACP,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,QAAQ,EACR,kBAAkB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC7F,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,eAAe,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ApiClient } from "./api-client";
2
2
  export { getUserFriendlyErrorMessage, parseZodErrors } from "./error-handlers";
3
- export { wrap } from "./result";
4
- export { tools, getTool, toolNames } from "./tools";
3
+ export { err, ok, wrap } from "./result";
4
+ export { getTool, toolNames, tools } from "./tools";
5
5
  export { ApiClient };
6
6
  export default ApiClient;
package/dist/request.d.ts CHANGED
@@ -20,11 +20,19 @@ export declare class ApiClient {
20
20
  private api_key;
21
21
  private request_history;
22
22
  private category;
23
+ private default_headers;
24
+ private custom_fetch?;
25
+ private credentials?;
26
+ private auth_mode;
23
27
  constructor(options: {
24
28
  base_url: string;
25
- api_key: string;
29
+ api_key?: string;
26
30
  max_history_size?: number;
27
31
  category?: string;
32
+ credentials?: "include" | "omit" | "same-origin";
33
+ auth_mode?: "session" | "key" | "cookie";
34
+ default_headers?: Record<string, string>;
35
+ custom_fetch?: typeof fetch;
28
36
  });
29
37
  private buildUrl;
30
38
  private generateRequestId;
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIxE,MAAM,MAAM,cAAc,GAAG;IAC5B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAiB;gBAErB,OAAO,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB;IAeD,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,iBAAiB;YAIX,OAAO;IA2Hd,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/E,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhF,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjF,OAAO;IAIP,GAAG,IAAI,MAAM;IAIb,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAgBxC"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIxE,MAAM,MAAM,cAAc,GAAG;IAC5B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,YAAY,CAAC,CAAe;IAEpC,OAAO,CAAC,WAAW,CAAC,CAAqC;IACzD,OAAO,CAAC,SAAS,CAA+B;gBAEpC,OAAO,EAAE;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;QACjD,SAAS,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;QACzC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,YAAY,CAAC,EAAE,OAAO,KAAK,CAAC;KAC5B;IAiBD,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,iBAAiB;YAIX,OAAO;IAyId,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/E,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhF,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjF,OAAO;IAIP,GAAG,IAAI,MAAM;IAIb,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAaxC"}