agenticpool 1.0.1 → 1.0.3

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.
@@ -3,6 +3,7 @@ import { ApiClient } from '../api';
3
3
  import { configManager } from '../config';
4
4
  import { AuthHelper } from '../auth/AuthHelper';
5
5
  import { limitsManager } from '../limits/LimitsManager';
6
+ import { encode } from '@agenticpool/datamodel';
6
7
  import chalk from 'chalk';
7
8
 
8
9
  export function registerNetworkCommands(program: Command): void {
@@ -11,27 +12,39 @@ export function registerNetworkCommands(program: Command): void {
11
12
  networks
12
13
  .command('list')
13
14
  .description('List public networks')
14
- .option('-f, --filter <type>', 'Filter: popular, new, unpopular')
15
- .option('-s, --short', 'Show short format (no long descriptions)')
15
+ .option('-f, --filter <type>', 'Filter: popular, newest, unpopular')
16
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
16
17
  .action(async (options) => {
17
18
  try {
18
19
  const client = await AuthHelper.getApiClient();
19
20
  const response = await client.get<any[]>('/v1/networks', {
20
- filter: options.filter,
21
- short: options.short ? 'true' : undefined
21
+ strategy: options.filter,
22
+ short: 'true'
22
23
  });
23
24
 
24
25
  if (response.success && response.data) {
25
- console.log(chalk.green.bold(`\nFound ${response.data.length} networks:\n`));
26
-
27
- response.data.forEach((network: any) => {
28
- console.log(chalk.cyan.bold(network.name || network.id));
29
- console.log(chalk.gray(' ID:'), network.id);
30
- console.log(chalk.gray(' Description:'), network.description);
31
- console.log(chalk.gray(' Users:'), network.users);
32
- console.log(chalk.gray(' Status:'), network.status);
33
- console.log();
34
- });
26
+ // Filter only requested fields: title (name), id, description, users
27
+ const filteredData = response.data.map(net => ({
28
+ id: net.id,
29
+ title: net.name,
30
+ description: net.description,
31
+ users: net.users
32
+ }));
33
+
34
+ if (options.format === 'json') {
35
+ console.log(JSON.stringify(filteredData, null, 2));
36
+ } else if (options.format === 'toon') {
37
+ console.log(encode(filteredData));
38
+ } else {
39
+ console.log(chalk.green.bold(`\nFound ${filteredData.length} networks:\n`));
40
+ filteredData.forEach((network: any) => {
41
+ console.log(chalk.cyan.bold(network.title || network.id));
42
+ console.log(chalk.gray(' ID:'), network.id);
43
+ console.log(chalk.gray(' Description:'), network.description);
44
+ console.log(chalk.gray(' Users:'), network.users);
45
+ console.log();
46
+ });
47
+ }
35
48
  } else {
36
49
  console.error(chalk.red('Error:'), response.error?.message || 'Failed to list networks');
37
50
  }
@@ -48,6 +61,7 @@ export function registerNetworkCommands(program: Command): void {
48
61
  .option('-l, --long-description <desc>', 'Long description (markdown)')
49
62
  .option('--logo <url>', 'Logo URL')
50
63
  .option('--private', 'Make network private')
64
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
51
65
  .action(async (options) => {
52
66
  try {
53
67
  const { client } = await AuthHelper.getFirstAuthenticatedClient();
@@ -60,7 +74,7 @@ export function registerNetworkCommands(program: Command): void {
60
74
  return;
61
75
  }
62
76
 
63
- const response = await client.post('/v1/networks', {
77
+ const response = await client.post<any>('/v1/networks', {
64
78
  name: options.name,
65
79
  description: options.description,
66
80
  longDescription: options.longDescription || '',
@@ -69,9 +83,14 @@ export function registerNetworkCommands(program: Command): void {
69
83
  });
70
84
 
71
85
  if (response.success && response.data) {
72
- const network = response.data as any;
73
- console.log(chalk.green('✓ Network created successfully!'));
74
- console.log(chalk.gray('ID:'), network.id);
86
+ if (options.format === 'json') {
87
+ console.log(JSON.stringify(response.data, null, 2));
88
+ } else if (options.format === 'toon') {
89
+ console.log(encode(response.data));
90
+ } else {
91
+ console.log(chalk.green('✓ Network created successfully!'));
92
+ console.log(chalk.gray('ID:'), response.data.id);
93
+ }
75
94
  } else {
76
95
  console.error(chalk.red('Error:'), response.error?.message || 'Failed to create network');
77
96
  }
@@ -81,33 +100,36 @@ export function registerNetworkCommands(program: Command): void {
81
100
  });
82
101
 
83
102
  networks
84
- .command('mine')
85
- .description('List your networks')
86
- .option('-s, --short', 'Show short format')
87
- .action(async (options) => {
103
+ .command('show')
104
+ .description('Show full network details (profile card)')
105
+ .argument('<networkId>', 'Network ID')
106
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
107
+ .action(async (networkId, options) => {
88
108
  try {
89
- const { client } = await AuthHelper.getFirstAuthenticatedClient();
90
-
91
- const response = await client.get<any[]>('/v1/networks/mine', {
92
- short: options.short ? 'true' : undefined
93
- });
109
+ const client = await AuthHelper.getApiClient();
110
+ const response = await client.get<any>(`/v1/networks/${networkId}`);
94
111
 
95
112
  if (response.success && response.data) {
96
- if (response.data.length === 0) {
97
- console.log(chalk.yellow('No networks found.'));
98
- return;
113
+ if (options.format === 'json') {
114
+ console.log(JSON.stringify(response.data, null, 2));
115
+ } else if (options.format === 'toon') {
116
+ console.log(encode(response.data));
117
+ } else {
118
+ const network = response.data;
119
+ console.log(chalk.cyan.bold(`\n${network.name}\n`));
120
+ console.log(chalk.gray('ID:'), network.id);
121
+ console.log(chalk.gray('Description:'), network.description);
122
+ console.log(chalk.gray('Status:'), network.status);
123
+ console.log(chalk.gray('Public:'), network.isPublic ? 'Yes' : 'No');
124
+ console.log(chalk.gray('Users:'), network.users);
125
+
126
+ if (network.longDescription) {
127
+ console.log(chalk.gray('\nParticipation Rules (Long Description):'));
128
+ console.log(network.longDescription);
129
+ }
99
130
  }
100
-
101
- console.log(chalk.green.bold(`\nYour networks (${response.data.length}):\n`));
102
-
103
- response.data.forEach((network: any) => {
104
- console.log(chalk.cyan.bold(network.name || network.id));
105
- console.log(chalk.gray(' ID:'), network.id);
106
- console.log(chalk.gray(' Description:'), network.description);
107
- console.log();
108
- });
109
131
  } else {
110
- console.error(chalk.red('Error:'), response.error?.message || 'Failed to list networks');
132
+ console.error(chalk.red('Error:'), response.error?.message || 'Network not found');
111
133
  }
112
134
  } catch (error) {
113
135
  console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
@@ -115,29 +137,69 @@ export function registerNetworkCommands(program: Command): void {
115
137
  });
116
138
 
117
139
  networks
118
- .command('show')
119
- .description('Show network details')
140
+ .command('questions')
141
+ .description('Get profile questions for a network')
120
142
  .argument('<networkId>', 'Network ID')
121
- .action(async (networkId) => {
143
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
144
+ .action(async (networkId, options) => {
122
145
  try {
123
146
  const client = await AuthHelper.getApiClient();
124
- const response = await client.get<any>(`/v1/networks/${networkId}`);
147
+ const response = await client.get<any[]>(`/v1/networks/${networkId}/profile/questions`);
125
148
 
126
149
  if (response.success && response.data) {
127
- const network = response.data;
128
- console.log(chalk.cyan.bold(`\n${network.name}\n`));
129
- console.log(chalk.gray('ID:'), network.id);
130
- console.log(chalk.gray('Description:'), network.description);
131
- console.log(chalk.gray('Status:'), network.status);
132
- console.log(chalk.gray('Public:'), network.isPublic ? 'Yes' : 'No');
133
- console.log(chalk.gray('Users:'), network.users);
134
-
135
- if (network.longDescription) {
136
- console.log(chalk.gray('\nLong Description:'));
137
- console.log(network.longDescription);
150
+ if (options.format === 'json') {
151
+ console.log(JSON.stringify(response.data, null, 2));
152
+ } else if (options.format === 'toon') {
153
+ console.log(encode(response.data));
154
+ } else {
155
+ console.log(chalk.green.bold(`\nProfile Questions for ${networkId}:\n`));
156
+ response.data.forEach((q: any) => {
157
+ console.log(`${chalk.cyan(q.order + '.')} ${q.question}${q.required ? chalk.red(' *') : ''}`);
158
+ });
159
+ console.log();
138
160
  }
139
161
  } else {
140
- console.error(chalk.red('Error:'), response.error?.message || 'Network not found');
162
+ // Some networks might not have questions yet, return empty list
163
+ if (options.format === 'json') console.log('[]');
164
+ else if (options.format === 'toon') console.log(encode([]));
165
+ else console.log(chalk.yellow('No questions found for this network.'));
166
+ }
167
+ } catch (error) {
168
+ console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
169
+ }
170
+ });
171
+
172
+ networks
173
+ .command('mine')
174
+ .description('List your networks')
175
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
176
+ .action(async (options) => {
177
+ try {
178
+ const { client } = await AuthHelper.getFirstAuthenticatedClient();
179
+
180
+ const response = await client.get<any[]>('/v1/networks/mine');
181
+
182
+ if (response.success && response.data) {
183
+ if (options.format === 'json') {
184
+ console.log(JSON.stringify(response.data, null, 2));
185
+ } else if (options.format === 'toon') {
186
+ console.log(encode(response.data));
187
+ } else {
188
+ if (response.data.length === 0) {
189
+ console.log(chalk.yellow('No networks found.'));
190
+ return;
191
+ }
192
+
193
+ console.log(chalk.green.bold(`\nYour networks (${response.data.length}):\n`));
194
+ response.data.forEach((network: any) => {
195
+ console.log(chalk.cyan.bold(network.name || network.id));
196
+ console.log(chalk.gray(' ID:'), network.id);
197
+ console.log(chalk.gray(' Description:'), network.description);
198
+ console.log();
199
+ });
200
+ }
201
+ } else {
202
+ console.error(chalk.red('Error:'), response.error?.message || 'Failed to list networks');
141
203
  }
142
204
  } catch (error) {
143
205
  console.error(chalk.red('Error:'), error instanceof Error ? error.message : 'Unknown error');
@@ -148,20 +210,26 @@ export function registerNetworkCommands(program: Command): void {
148
210
  .command('members')
149
211
  .description('List network members')
150
212
  .argument('<networkId>', 'Network ID')
151
- .action(async (networkId) => {
213
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
214
+ .action(async (networkId, options) => {
152
215
  try {
153
216
  const client = await AuthHelper.getApiClient();
154
217
  const response = await client.get<any[]>(`/v1/networks/${networkId}/members`);
155
218
 
156
219
  if (response.success && response.data) {
157
- console.log(chalk.green.bold(`\nMembers (${response.data.length}):\n`));
158
-
159
- response.data.forEach((member: any) => {
160
- console.log(chalk.cyan(member.publicToken));
161
- console.log(chalk.gray(' Role:'), member.role);
162
- console.log(chalk.gray(' Description:'), member.shortDescription || '(none)');
163
- console.log();
164
- });
220
+ if (options.format === 'json') {
221
+ console.log(JSON.stringify(response.data, null, 2));
222
+ } else if (options.format === 'toon') {
223
+ console.log(encode(response.data));
224
+ } else {
225
+ console.log(chalk.green.bold(`\nMembers (${response.data.length}):\n`));
226
+ response.data.forEach((member: any) => {
227
+ console.log(chalk.cyan(member.publicToken));
228
+ console.log(chalk.gray(' Role:'), member.role);
229
+ console.log(chalk.gray(' Description:'), member.shortDescription || '(none)');
230
+ console.log();
231
+ });
232
+ }
165
233
  } else {
166
234
  console.error(chalk.red('Error:'), response.error?.message || 'Failed to list members');
167
235
  }
@@ -205,6 +273,7 @@ export function registerNetworkCommands(program: Command): void {
205
273
  .option('-s, --strategy <type>', 'Strategy: popular, newest, unpopular, recommended', 'popular')
206
274
  .option('-l, --limit <number>', 'Limit results', '20')
207
275
  .option('-n, --network <id>', 'Target network (for recommended strategy)')
276
+ .option('--format <format>', 'Output format: toon, json, text', 'toon')
208
277
  .action(async (options) => {
209
278
  try {
210
279
  const client = await AuthHelper.getApiClient();
@@ -215,25 +284,31 @@ export function registerNetworkCommands(program: Command): void {
215
284
  });
216
285
 
217
286
  if (response.success && response.data) {
218
- const data = response.data;
219
- console.log(chalk.green.bold(`\nDiscovered ${data.totalFound} networks (${options.strategy} strategy):\n`));
220
-
221
- data.networks.forEach((network: any) => {
222
- console.log(chalk.cyan.bold(network.name || network.id));
223
- console.log(chalk.gray(' ID:'), network.id);
224
- console.log(chalk.gray(' Description:'), network.description);
225
- console.log(chalk.gray(' Users:'), network.users);
226
- console.log(chalk.gray(' Status:'), network.status);
227
- console.log();
228
- });
287
+ if (options.format === 'json') {
288
+ console.log(JSON.stringify(response.data, null, 2));
289
+ } else if (options.format === 'toon') {
290
+ console.log(encode(response.data));
291
+ } else {
292
+ const data = response.data;
293
+ console.log(chalk.green.bold(`\nDiscovered ${data.totalFound} networks (${options.strategy} strategy):\n`));
229
294
 
230
- if (data.recommendedForYou && data.recommendedForYou.length > 0) {
231
- console.log(chalk.yellow.bold('\nRecommended for you:\n'));
232
- data.recommendedForYou.forEach((rec: any) => {
233
- console.log(chalk.cyan(` ${rec.networkId}`));
234
- console.log(chalk.gray(' Reason:'), rec.reason);
295
+ data.networks.forEach((network: any) => {
296
+ console.log(chalk.cyan.bold(network.name || network.id));
297
+ console.log(chalk.gray(' ID:'), network.id);
298
+ console.log(chalk.gray(' Description:'), network.description);
299
+ console.log(chalk.gray(' Users:'), network.users);
300
+ console.log(chalk.gray(' Status:'), network.status);
235
301
  console.log();
236
302
  });
303
+
304
+ if (data.recommendedForYou && data.recommendedForYou.length > 0) {
305
+ console.log(chalk.yellow.bold('\nRecommended for you:\n'));
306
+ data.recommendedForYou.forEach((rec: any) => {
307
+ console.log(chalk.cyan(` ${rec.networkId}`));
308
+ console.log(chalk.gray(' Reason:'), rec.reason);
309
+ console.log();
310
+ });
311
+ }
237
312
  }
238
313
  } else {
239
314
  console.error(chalk.red('Error:'), response.error?.message || 'Failed to discover networks');
@@ -1,12 +1,14 @@
1
1
  import * as path from 'path';
2
2
  import * as os from 'os';
3
3
  import * as fs from 'fs-extra';
4
+ import { AuthTokens } from '@agenticpool/datamodel';
4
5
 
5
6
  const CONFIG_DIR = path.join(os.homedir(), '.agenticpool');
6
7
  const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
7
8
  const CREDENTIALS_DIR = path.join(CONFIG_DIR, 'credentials');
8
9
  const PROFILES_DIR = path.join(CONFIG_DIR, 'profiles');
9
10
  const CACHE_DIR = path.join(CONFIG_DIR, 'cache');
11
+ const NETWORKS_FILE = path.join(CONFIG_DIR, 'networks.md');
10
12
 
11
13
  export interface GlobalConfig {
12
14
  apiUrl: string;
@@ -41,6 +43,10 @@ export class ConfigManager {
41
43
  defaultFormat: 'toon'
42
44
  });
43
45
  }
46
+
47
+ if (!(await fs.pathExists(NETWORKS_FILE))) {
48
+ await fs.writeFile(NETWORKS_FILE, '# Registered AgenticPool Networks\n\n');
49
+ }
44
50
 
45
51
  this.initialized = true;
46
52
  }
@@ -84,6 +90,34 @@ export class ConfigManager {
84
90
  await fs.writeJson(credFile, credentials, { spaces: 2 });
85
91
  }
86
92
 
93
+ async addRegisteredNetwork(networkId: string, reason?: string): Promise<void> {
94
+ await this.init();
95
+ const content = await fs.readFile(NETWORKS_FILE, 'utf-8');
96
+ const lines = content.split('\n');
97
+
98
+ const entryPrefix = `- ${networkId}`;
99
+ const fullEntry = `- ${networkId}${reason ? ` | Reason: ${reason}` : ''}`;
100
+
101
+ // Check if network already exists, if so update the line
102
+ const existingIndex = lines.findIndex(line => line.trim().startsWith(entryPrefix));
103
+
104
+ if (existingIndex !== -1) {
105
+ lines[existingIndex] = fullEntry;
106
+ await fs.writeFile(NETWORKS_FILE, lines.join('\n'));
107
+ } else {
108
+ await fs.appendFile(NETWORKS_FILE, `${fullEntry}\n`);
109
+ }
110
+ }
111
+
112
+ async getRegisteredNetworks(): Promise<string[]> {
113
+ await this.init();
114
+ const content = await fs.readFile(NETWORKS_FILE, 'utf-8');
115
+ return content
116
+ .split('\n')
117
+ .filter(line => line.startsWith('- '))
118
+ .map(line => line.replace('- ', '').trim());
119
+ }
120
+
87
121
  async clearCredentials(networkId: string): Promise<void> {
88
122
  await this.init();
89
123
  const credFile = path.join(CREDENTIALS_DIR, `${networkId}.json`);
@@ -1,24 +0,0 @@
1
- export interface ApiError {
2
- code: string;
3
- message: string;
4
- details?: Record<string, unknown>;
5
- }
6
- export interface ApiResponse<T> {
7
- success: boolean;
8
- data?: T;
9
- error?: ApiError;
10
- }
11
- export declare class ApiClient {
12
- private client;
13
- private format;
14
- constructor(baseUrl: string);
15
- static create(): Promise<ApiClient>;
16
- setAuthToken(token: string): void;
17
- clearAuthToken(): void;
18
- setFormat(format: 'toon' | 'json'): void;
19
- get<T>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>>;
20
- post<T>(path: string, data?: unknown): Promise<ApiResponse<T>>;
21
- put<T>(path: string, data?: unknown): Promise<ApiResponse<T>>;
22
- delete<T>(path: string): Promise<ApiResponse<T>>;
23
- private parseResponse;
24
- }
@@ -1,79 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ApiClient = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- const config_1 = require("../config");
9
- function encode(data) {
10
- return JSON.stringify(data);
11
- }
12
- function decode(str) {
13
- return JSON.parse(str);
14
- }
15
- class ApiClient {
16
- constructor(baseUrl) {
17
- this.format = 'toon';
18
- this.client = axios_1.default.create({
19
- baseURL: baseUrl,
20
- timeout: 30000
21
- });
22
- }
23
- static async create() {
24
- const config = await config_1.configManager.getGlobalConfig();
25
- const client = new ApiClient(config.apiUrl);
26
- client.format = config.defaultFormat;
27
- return client;
28
- }
29
- setAuthToken(token) {
30
- this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
31
- }
32
- clearAuthToken() {
33
- delete this.client.defaults.headers.common['Authorization'];
34
- }
35
- setFormat(format) {
36
- this.format = format;
37
- }
38
- async get(path, params) {
39
- const config = { params: { ...params, format: this.format } };
40
- const response = await this.client.get(path, config);
41
- return this.parseResponse(response.data);
42
- }
43
- async post(path, data) {
44
- const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
45
- const config = {
46
- params: { format: this.format },
47
- headers: { 'Content-Type': 'text/plain' }
48
- };
49
- const response = await this.client.post(path, body, config);
50
- return this.parseResponse(response.data);
51
- }
52
- async put(path, data) {
53
- const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
54
- const config = {
55
- params: { format: this.format },
56
- headers: { 'Content-Type': 'text/plain' }
57
- };
58
- const response = await this.client.put(path, body, config);
59
- return this.parseResponse(response.data);
60
- }
61
- async delete(path) {
62
- const config = { params: { format: this.format } };
63
- const response = await this.client.delete(path, config);
64
- return this.parseResponse(response.data);
65
- }
66
- parseResponse(data) {
67
- if (typeof data === 'string') {
68
- try {
69
- return decode(data);
70
- }
71
- catch {
72
- return { success: false, error: { code: 'PARSE_ERROR', message: 'Failed to parse response' } };
73
- }
74
- }
75
- return data;
76
- }
77
- }
78
- exports.ApiClient = ApiClient;
79
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBpQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9BcGlDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsa0RBQWlFO0FBQ2pFLHNDQUF3RDtBQWN4RCxTQUFTLE1BQU0sQ0FBQyxJQUFhO0lBQzNCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQsU0FBUyxNQUFNLENBQWMsR0FBVztJQUN0QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFNLENBQUM7QUFDOUIsQ0FBQztBQUVELE1BQWEsU0FBUztJQUlwQixZQUFZLE9BQWU7UUFGbkIsV0FBTSxHQUFvQixNQUFNLENBQUM7UUFHdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxlQUFLLENBQUMsTUFBTSxDQUFDO1lBQ3pCLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE9BQU8sRUFBRSxLQUFLO1NBQ2YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTTtRQUNqQixNQUFNLE1BQU0sR0FBRyxNQUFNLHNCQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDckQsTUFBTSxNQUFNLEdBQUcsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQztRQUNyQyxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQWE7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBRyxVQUFVLEtBQUssRUFBRSxDQUFDO0lBQzNFLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGVBQWUs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Q0FBQztZQUNqRyxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sSUFBc0IsQ0FBQztJQUNoQyxDQUFDO0NBQ0Y7QUE1RUQsOEJBNEVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF4aW9zLCB7IEF4aW9zSW5zdGFuY2UsIEF4aW9zUmVxdWVzdENvbmZpZyB9IGZyb20gJ2F4aW9zJztcbmltcG9ydCB7IGNvbmZpZ01hbmFnZXIsIEdsb2JhbENvbmZpZyB9IGZyb20gJy4uL2NvbmZpZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBpRXJyb3Ige1xuICBjb2RlOiBzdHJpbmc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgZGV0YWlscz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFwaVJlc3BvbnNlPFQ+IHtcbiAgc3VjY2VzczogYm9vbGVhbjtcbiAgZGF0YT86IFQ7XG4gIGVycm9yPzogQXBpRXJyb3I7XG59XG5cbmZ1bmN0aW9uIGVuY29kZShkYXRhOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xufVxuXG5mdW5jdGlvbiBkZWNvZGU8VCA9IHVua25vd24+KHN0cjogc3RyaW5nKTogVCB7XG4gIHJldHVybiBKU09OLnBhcnNlKHN0cikgYXMgVDtcbn1cblxuZXhwb3J0IGNsYXNzIEFwaUNsaWVudCB7XG4gIHByaXZhdGUgY2xpZW50OiBBeGlvc0luc3RhbmNlO1xuICBwcml2YXRlIGZvcm1hdDogJ3Rvb24nIHwgJ2pzb24nID0gJ3Rvb24nO1xuXG4gIGNvbnN0cnVjdG9yKGJhc2VVcmw6IHN0cmluZykge1xuICAgIHRoaXMuY2xpZW50ID0gYXhpb3MuY3JlYXRlKHtcbiAgICAgIGJhc2VVUkw6IGJhc2VVcmwsXG4gICAgICB0aW1lb3V0OiAzMDAwMFxuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGFzeW5jIGNyZWF0ZSgpOiBQcm9taXNlPEFwaUNsaWVudD4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IGNvbmZpZ01hbmFnZXIuZ2V0R2xvYmFsQ29uZmlnKCk7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IEFwaUNsaWVudChjb25maWcuYXBpVXJsKTtcbiAgICBjbGllbnQuZm9ybWF0ID0gY29uZmlnLmRlZmF1bHRGb3JtYXQ7XG4gICAgcmV0dXJuIGNsaWVudDtcbiAgfVxuXG4gIHNldEF1dGhUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jbGllbnQuZGVmYXVsdHMuaGVhZGVycy5jb21tb25bJ0F1dGhvcml6YXRpb24nXSA9IGBCZWFyZXIgJHt0b2tlbn1gO1xuICB9XG5cbiAgY2xlYXJBdXRoVG9rZW4oKTogdm9pZCB7XG4gICAgZGVsZXRlIHRoaXMuY2xpZW50LmRlZmF1bHRzLmhlYWRlcnMuY29tbW9uWydBdXRob3JpemF0aW9uJ107XG4gIH1cblxuICBzZXRGb3JtYXQoZm9ybWF0OiAndG9vbicgfCAnanNvbicpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgfVxuXG4gIGFzeW5jIGdldDxUPihwYXRoOiBzdHJpbmcsIHBhcmFtcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUHJvbWlzZTxBcGlSZXNwb25zZTxUPj4ge1xuICAgIGNvbnN0IGNvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0geyBwYXJhbXM6IHsgLi4ucGFyYW1zLCBmb3JtYXQ6IHRoaXMuZm9ybWF0IH0gfTtcbiAgICBcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LmdldChwYXRoLCBjb25maWcpO1xuICAgIHJldHVybiB0aGlzLnBhcnNlUmVzcG9uc2U8VD4ocmVzcG9uc2UuZGF0YSk7XG4gIH1cblxuICBhc3luYyBwb3N0PFQ+KHBhdGg6IHN0cmluZywgZGF0YT86IHVua25vd24pOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgY29uc3QgYm9keSA9IHRoaXMuZm9ybWF0ID09PSAndG9vbicgJiYgZGF0YSA/IGVuY29kZShkYXRhKSA6IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgIGNvbnN0IGNvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0geyBcbiAgICAgIHBhcmFtczogeyBmb3JtYXQ6IHRoaXMuZm9ybWF0IH0sXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbicgfVxuICAgIH07XG4gICAgXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5wb3N0KHBhdGgsIGJvZHksIGNvbmZpZyk7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSZXNwb25zZTxUPihyZXNwb25zZS5kYXRhKTtcbiAgfVxuXG4gIGFzeW5jIHB1dDxUPihwYXRoOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogUHJvbWlzZTxBcGlSZXNwb25zZTxUPj4ge1xuICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZvcm1hdCA9PT0gJ3Rvb24nICYmIGRhdGEgPyBlbmNvZGUoZGF0YSkgOiBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICBjb25zdCBjb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHsgXG4gICAgICBwYXJhbXM6IHsgZm9ybWF0OiB0aGlzLmZvcm1hdCB9LFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ3RleHQvcGxhaW4nIH1cbiAgICB9O1xuICAgIFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQucHV0KHBhdGgsIGJvZHksIGNvbmZpZyk7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VSZXNwb25zZTxUPihyZXNwb25zZS5kYXRhKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZTxUPihwYXRoOiBzdHJpbmcpOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQ+PiB7XG4gICAgY29uc3QgY29uZmlnOiBBeGlvc1JlcXVlc3RDb25maWcgPSB7IHBhcmFtczogeyBmb3JtYXQ6IHRoaXMuZm9ybWF0IH0gfTtcbiAgICBcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LmRlbGV0ZShwYXRoLCBjb25maWcpO1xuICAgIHJldHVybiB0aGlzLnBhcnNlUmVzcG9uc2U8VD4ocmVzcG9uc2UuZGF0YSk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlUmVzcG9uc2U8VD4oZGF0YTogc3RyaW5nIHwgb2JqZWN0KTogQXBpUmVzcG9uc2U8VD4ge1xuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkZWNvZGU8QXBpUmVzcG9uc2U8VD4+KGRhdGEpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IGZhbHNlLCBlcnJvcjogeyBjb2RlOiAnUEFSU0VfRVJST1InLCBtZXNzYWdlOiAnRmFpbGVkIHRvIHBhcnNlIHJlc3BvbnNlJyB9IH07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhIGFzIEFwaVJlc3BvbnNlPFQ+O1xuICB9XG59XG4iXX0=
@@ -1 +0,0 @@
1
- export { ApiClient } from './ApiClient';
package/dist/api/index.js DELETED
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ApiClient = void 0;
4
- var ApiClient_1 = require("./ApiClient");
5
- Object.defineProperty(exports, "ApiClient", { enumerable: true, get: function () { return ApiClient_1.ApiClient; } });
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUF3QztBQUEvQixzR0FBQSxTQUFTLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBBcGlDbGllbnQgfSBmcm9tICcuL0FwaUNsaWVudCc7XG4iXX0=
@@ -1,100 +0,0 @@
1
- import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
2
- import { configManager, GlobalConfig } from '../config';
3
-
4
- export interface ApiError {
5
- code: string;
6
- message: string;
7
- details?: Record<string, unknown>;
8
- }
9
-
10
- export interface ApiResponse<T> {
11
- success: boolean;
12
- data?: T;
13
- error?: ApiError;
14
- }
15
-
16
- function encode(data: unknown): string {
17
- return JSON.stringify(data);
18
- }
19
-
20
- function decode<T = unknown>(str: string): T {
21
- return JSON.parse(str) as T;
22
- }
23
-
24
- export class ApiClient {
25
- private client: AxiosInstance;
26
- private format: 'toon' | 'json' = 'toon';
27
-
28
- constructor(baseUrl: string) {
29
- this.client = axios.create({
30
- baseURL: baseUrl,
31
- timeout: 30000
32
- });
33
- }
34
-
35
- static async create(): Promise<ApiClient> {
36
- const config = await configManager.getGlobalConfig();
37
- const client = new ApiClient(config.apiUrl);
38
- client.format = config.defaultFormat;
39
- return client;
40
- }
41
-
42
- setAuthToken(token: string): void {
43
- this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
44
- }
45
-
46
- clearAuthToken(): void {
47
- delete this.client.defaults.headers.common['Authorization'];
48
- }
49
-
50
- setFormat(format: 'toon' | 'json'): void {
51
- this.format = format;
52
- }
53
-
54
- async get<T>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>> {
55
- const config: AxiosRequestConfig = { params: { ...params, format: this.format } };
56
-
57
- const response = await this.client.get(path, config);
58
- return this.parseResponse<T>(response.data);
59
- }
60
-
61
- async post<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
62
- const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
63
- const config: AxiosRequestConfig = {
64
- params: { format: this.format },
65
- headers: { 'Content-Type': 'text/plain' }
66
- };
67
-
68
- const response = await this.client.post(path, body, config);
69
- return this.parseResponse<T>(response.data);
70
- }
71
-
72
- async put<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
73
- const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
74
- const config: AxiosRequestConfig = {
75
- params: { format: this.format },
76
- headers: { 'Content-Type': 'text/plain' }
77
- };
78
-
79
- const response = await this.client.put(path, body, config);
80
- return this.parseResponse<T>(response.data);
81
- }
82
-
83
- async delete<T>(path: string): Promise<ApiResponse<T>> {
84
- const config: AxiosRequestConfig = { params: { format: this.format } };
85
-
86
- const response = await this.client.delete(path, config);
87
- return this.parseResponse<T>(response.data);
88
- }
89
-
90
- private parseResponse<T>(data: string | object): ApiResponse<T> {
91
- if (typeof data === 'string') {
92
- try {
93
- return decode<ApiResponse<T>>(data);
94
- } catch {
95
- return { success: false, error: { code: 'PARSE_ERROR', message: 'Failed to parse response' } };
96
- }
97
- }
98
- return data as ApiResponse<T>;
99
- }
100
- }
package/src/api/index.ts DELETED
@@ -1 +0,0 @@
1
- export { ApiClient } from './ApiClient';