@codeguide/core 0.0.5 → 0.0.7

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/README.md ADDED
@@ -0,0 +1,503 @@
1
+ # @codeguide/core
2
+
3
+ The core package for CodeGuide with programmatic API access. This package provides TypeScript interfaces and services for integrating CodeGuide functionality into your applications.
4
+
5
+ ## Features
6
+
7
+ - 🔑 **API Key Management**: Full CRUD operations for API keys
8
+ - 📝 **Project Management**: Create and manage projects programmatically
9
+ - 🎯 **Task Management**: Organize and track development tasks
10
+ - 📊 **Usage Analytics**: Monitor API usage and credits
11
+ - 🔍 **Repository Analysis**: Analyze code repositories
12
+ - 🎨 **Code Generation**: Generate code with AI assistance
13
+ - 🔐 **Multiple Authentication**: Support for various auth methods
14
+ - 🛡️ **TypeScript Support**: Full type safety and IntelliSense
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @codeguide/core
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### Basic Usage
25
+
26
+ ```typescript
27
+ import { CodeGuide } from '@codeguide/core'
28
+
29
+ const codeguide = new CodeGuide({
30
+ baseUrl: 'https://api.codeguide.ai',
31
+ databaseApiKey: 'sk_your_database_api_key'
32
+ })
33
+
34
+ // Get all API keys
35
+ const keysResponse = await codeguide.apiKeyEnhanced.getAllApiKeys()
36
+ console.log(`Found ${keysResponse.data.length} API keys`)
37
+
38
+ // Create a new API key
39
+ const newKey = await codeguide.apiKeyEnhanced.createApiKey({
40
+ name: 'My Application'
41
+ })
42
+ console.log(`Created key: ${newKey.data.api_key}`)
43
+ ```
44
+
45
+ ### API Key Management
46
+
47
+ ```typescript
48
+ import {
49
+ CodeGuide,
50
+ ApiKeyListResponse,
51
+ CreateApiKeyRequest
52
+ } from '@codeguide/core'
53
+
54
+ const codeguide = new CodeGuide({
55
+ baseUrl: 'https://api.codeguide.ai',
56
+ databaseApiKey: 'sk_your_database_api_key'
57
+ })
58
+
59
+ // List all API keys
60
+ const keysResponse: ApiKeyListResponse = await codeguide.apiKeyEnhanced.getAllApiKeys()
61
+
62
+ // Check if you can create new keys
63
+ const permission = await codeguide.apiKeyEnhanced.checkApiKeyPermission()
64
+ if (permission.data.can_create) {
65
+ console.log('You can create new API keys')
66
+ }
67
+
68
+ // Create a new key
69
+ const createRequest: CreateApiKeyRequest = {
70
+ name: 'Production Application'
71
+ }
72
+ const newKey = await codeguide.apiKeyEnhanced.createApiKey(createRequest)
73
+
74
+ // Revoke a key
75
+ await codeguide.apiKeyEnhanced.revokeApiKey('key-id-123')
76
+ ```
77
+
78
+ ### Project Management
79
+
80
+ ```typescript
81
+ import { CodeGuide } from '@codeguide/core'
82
+
83
+ const codeguide = new CodeGuide({
84
+ baseUrl: 'https://api.codeguide.ai',
85
+ databaseApiKey: 'sk_your_database_api_key'
86
+ })
87
+
88
+ // Create a new project
89
+ const project = await codeguide.projects.createProject({
90
+ title: 'My Web Application',
91
+ description: 'A modern web app built with React'
92
+ })
93
+
94
+ // Get project details
95
+ const projectDetails = await codeguide.projects.getProject(project.id)
96
+
97
+ // List all projects
98
+ const projects = await codeguide.projects.getAllProjects()
99
+ ```
100
+
101
+ ### Task Management
102
+
103
+ ```typescript
104
+ import { CodeGuide } from '@codeguide/core'
105
+
106
+ const codeguide = new CodeGuide({
107
+ baseUrl: 'https://api.codeguide.ai',
108
+ databaseApiKey: 'sk_your_database_api_key'
109
+ })
110
+
111
+ // Generate tasks for a project
112
+ const tasks = await codeguide.tasks.generateTasks({
113
+ project_id: 'project-id-123',
114
+ context: 'Building a React application with TypeScript'
115
+ })
116
+
117
+ // Get all tasks for a project
118
+ const projectTasks = await codeguide.tasks.getProjectTasks('project-id-123')
119
+
120
+ // Update task status
121
+ await codeguide.tasks.updateTask('task-id-123', {
122
+ status: 'in_progress',
123
+ notes: 'Started working on authentication module'
124
+ })
125
+ ```
126
+
127
+ ## Authentication
128
+
129
+ The CodeGuide client supports multiple authentication methods with automatic priority handling:
130
+
131
+ ### 1. Database API Key (Highest Priority)
132
+
133
+ ```typescript
134
+ const codeguide = new CodeGuide({
135
+ baseUrl: 'https://api.codeguide.ai',
136
+ databaseApiKey: 'sk_your_database_api_key'
137
+ })
138
+ ```
139
+
140
+ ### 2. Legacy API Key + User ID
141
+
142
+ ```typescript
143
+ const codeguide = new CodeGuide({
144
+ baseUrl: 'https://api.codeguide.ai',
145
+ apiKey: 'your_api_key',
146
+ userId: 'your_user_id'
147
+ })
148
+ ```
149
+
150
+ ### 3. Clerk JWT Token
151
+
152
+ ```typescript
153
+ const codeguide = new CodeGuide({
154
+ baseUrl: 'https://api.codeguide.ai',
155
+ jwtToken: 'your_jwt_token'
156
+ })
157
+ ```
158
+
159
+ ### Automatic Fallback
160
+
161
+ The client automatically falls back through authentication methods:
162
+
163
+ ```typescript
164
+ const codeguide = new CodeGuide({
165
+ baseUrl: 'https://api.codeguide.ai',
166
+ databaseApiKey: 'sk_key', // Will try this first
167
+ apiKey: 'legacy_key', // Fallback if database key fails
168
+ userId: 'user_id', // Required for legacy auth
169
+ jwtToken: 'jwt_token' // Final fallback
170
+ })
171
+ ```
172
+
173
+ ## API Reference
174
+
175
+ ### ApiKeyEnhancedService
176
+
177
+ #### getAllApiKeys()
178
+ ```typescript
179
+ async getAllApiKeys(): Promise<ApiKeyListResponse>
180
+ ```
181
+ Get all API keys for the authenticated user.
182
+
183
+ **Returns:** `Promise<ApiKeyListResponse>`
184
+
185
+ **Example:**
186
+ ```typescript
187
+ const response = await codeguide.apiKeyEnhanced.getAllApiKeys()
188
+ console.log(response.data) // Array of ApiKey objects
189
+ ```
190
+
191
+ #### createApiKey(request)
192
+ ```typescript
193
+ async createApiKey(request: CreateApiKeyRequest): Promise<CreateApiKeyResponse>
194
+ ```
195
+ Create a new API key.
196
+
197
+ **Parameters:**
198
+ - `request.name` (string): Name for the new API key
199
+
200
+ **Returns:** `Promise<CreateApiKeyResponse>`
201
+
202
+ **Example:**
203
+ ```typescript
204
+ const response = await codeguide.apiKeyEnhanced.createApiKey({
205
+ name: 'My Application'
206
+ })
207
+ console.log(response.data.api_key) // The new API key
208
+ ```
209
+
210
+ #### revokeApiKey(apiKeyId)
211
+ ```typescript
212
+ async revokeApiKey(apiKeyId: string): Promise<RevokeApiKeyResponse>
213
+ ```
214
+ Revoke an API key by ID.
215
+
216
+ **Parameters:**
217
+ - `apiKeyId` (string): ID of the API key to revoke
218
+
219
+ **Returns:** `Promise<RevokeApiKeyResponse>`
220
+
221
+ #### checkApiKeyPermission()
222
+ ```typescript
223
+ async checkApiKeyPermission(): Promise<ApiKeyPermissionResponse>
224
+ ```
225
+ Check if the user can create new API keys.
226
+
227
+ **Returns:** `Promise<ApiKeyPermissionResponse>`
228
+
229
+ ### ProjectService
230
+
231
+ #### createProject(request)
232
+ ```typescript
233
+ async createProject(request: CreateProjectRequest): Promise<ProjectResponse>
234
+ ```
235
+ Create a new project.
236
+
237
+ #### getProject(projectId)
238
+ ```typescript
239
+ async getProject(projectId: string): Promise<ProjectResponse>
240
+ ```
241
+ Get project details by ID.
242
+
243
+ #### getAllProjects()
244
+ ```typescript
245
+ async getAllProjects(): Promise<ProjectsListResponse>
246
+ ```
247
+ Get all projects for the authenticated user.
248
+
249
+ ### TaskService
250
+
251
+ #### generateTasks(request)
252
+ ```typescript
253
+ async generateTasks(request: GenerateTasksRequest): Promise<TasksResponse>
254
+ ```
255
+ Generate tasks for a project.
256
+
257
+ #### getProjectTasks(projectId)
258
+ ```typescript
259
+ async getProjectTasks(projectId: string): Promise<TasksResponse>
260
+ ```
261
+ Get all tasks for a project.
262
+
263
+ #### updateTask(taskId, update)
264
+ ```typescript
265
+ async updateTask(taskId: string, update: UpdateTaskRequest): Promise<TaskResponse>
266
+ ```
267
+ Update task status and notes.
268
+
269
+ ## Types
270
+
271
+ ### ApiKey
272
+ ```typescript
273
+ interface ApiKey {
274
+ id: string
275
+ key: string // Full API key string
276
+ user_id: string
277
+ name: string
278
+ created_at: string
279
+ expires_at?: string
280
+ is_active: boolean
281
+ metadata?: Record<string, any>
282
+ }
283
+ ```
284
+
285
+ ### ApiKeyListResponse
286
+ ```typescript
287
+ interface ApiKeyListResponse {
288
+ status: string
289
+ data: ApiKey[]
290
+ }
291
+ ```
292
+
293
+ ### CreateApiKeyRequest
294
+ ```typescript
295
+ interface CreateApiKeyRequest {
296
+ name: string
297
+ }
298
+ ```
299
+
300
+ ### CreateApiKeyResponse
301
+ ```typescript
302
+ interface CreateApiKeyResponse {
303
+ status: string
304
+ data: {
305
+ api_key: string
306
+ id: string
307
+ name: string
308
+ created_at: string
309
+ expires_at?: string
310
+ is_active: boolean
311
+ metadata?: Record<string, any>
312
+ }
313
+ message?: string
314
+ }
315
+ ```
316
+
317
+ ### APIServiceConfig
318
+ ```typescript
319
+ interface APIServiceConfig {
320
+ baseUrl: string
321
+ databaseApiKey?: string // Highest priority
322
+ apiKey?: string // Legacy API key
323
+ userId?: string // Required for legacy auth
324
+ jwtToken?: string // Clerk JWT token
325
+ timeout?: number // Default: 3600000 (1 hour)
326
+ }
327
+ ```
328
+
329
+ ## Error Handling
330
+
331
+ The client provides detailed error information:
332
+
333
+ ```typescript
334
+ try {
335
+ const keys = await codeguide.apiKeyEnhanced.getAllApiKeys()
336
+ } catch (error) {
337
+ if (error.message.includes('401')) {
338
+ console.error('Authentication failed:', error.message)
339
+ } else if (error.message.includes('403')) {
340
+ console.error('Permission denied:', error.message)
341
+ } else if (error.message.includes('429')) {
342
+ console.error('Rate limited:', error.message)
343
+ } else {
344
+ console.error('API error:', error.message)
345
+ }
346
+ }
347
+ ```
348
+
349
+ ## Configuration
350
+
351
+ ### Timeout Configuration
352
+
353
+ ```typescript
354
+ const codeguide = new CodeGuide({
355
+ baseUrl: 'https://api.codeguide.ai',
356
+ databaseApiKey: 'sk_your_key',
357
+ timeout: 1800000 // 30 minutes
358
+ })
359
+ ```
360
+
361
+ ### Verbose Logging
362
+
363
+ ```typescript
364
+ const codeguide = new CodeGuide({
365
+ baseUrl: 'https://api.codeguide.ai',
366
+ databaseApiKey: 'sk_your_key'
367
+ }, {
368
+ verbose: true // Enable detailed logging
369
+ })
370
+ ```
371
+
372
+ ## Advanced Usage
373
+
374
+ ### Custom Headers
375
+
376
+ The BaseService allows you to intercept and modify requests:
377
+
378
+ ```typescript
379
+ // Access the underlying axios instance
380
+ const client = codeguide.apiKeyEnhanced.client
381
+
382
+ // Add custom headers
383
+ client.interceptors.request.use(config => {
384
+ config.headers['X-Custom-Header'] = 'value'
385
+ return config
386
+ })
387
+ ```
388
+
389
+ ### Response Interceptors
390
+
391
+ ```typescript
392
+ // Add custom response handling
393
+ client.interceptors.response.use(
394
+ response => response,
395
+ error => {
396
+ // Custom error handling
397
+ console.error('API Error:', error.response?.data)
398
+ return Promise.reject(error)
399
+ }
400
+ )
401
+ ```
402
+
403
+ ## Examples
404
+
405
+ ### Complete API Key Management Flow
406
+
407
+ ```typescript
408
+ import { CodeGuide } from '@codeguide/core'
409
+
410
+ async function manageApiKeys() {
411
+ const codeguide = new CodeGuide({
412
+ baseUrl: 'https://api.codeguide.ai',
413
+ databaseApiKey: 'sk_your_key'
414
+ })
415
+
416
+ try {
417
+ // Check permissions
418
+ const permission = await codeguide.apiKeyEnhanced.checkApiKeyPermission()
419
+ if (!permission.data.can_create) {
420
+ console.log('Cannot create new keys:', permission.data.reason)
421
+ return
422
+ }
423
+
424
+ // List current keys
425
+ const currentKeys = await codeguide.apiKeyEnhanced.getAllApiKeys()
426
+ console.log(`Current keys: ${currentKeys.data.length}`)
427
+
428
+ // Create new key
429
+ const newKey = await codeguide.apiKeyEnhanced.createApiKey({
430
+ name: 'Production Application'
431
+ })
432
+ console.log('Created key:', newKey.data.api_key)
433
+
434
+ // Revoke old key if needed
435
+ if (currentKeys.data.length > 5) {
436
+ await codeguide.apiKeyEnhanced.revokeApiKey(currentKeys.data[0].id)
437
+ console.log('Revoked oldest key')
438
+ }
439
+
440
+ } catch (error) {
441
+ console.error('API key management failed:', error.message)
442
+ }
443
+ }
444
+ ```
445
+
446
+ ### Project Setup with Tasks
447
+
448
+ ```typescript
449
+ import { CodeGuide } from '@codeguide/core'
450
+
451
+ async function setupProject() {
452
+ const codeguide = new CodeGuide({
453
+ baseUrl: 'https://api.codeguide.ai',
454
+ databaseApiKey: 'sk_your_key'
455
+ })
456
+
457
+ try {
458
+ // Create project
459
+ const project = await codeguide.projects.createProject({
460
+ title: 'E-commerce Platform',
461
+ description: 'Modern e-commerce solution with React and Node.js'
462
+ })
463
+
464
+ // Generate tasks
465
+ const tasks = await codeguide.tasks.generateTasks({
466
+ project_id: project.id,
467
+ context: 'Building a full-stack e-commerce platform'
468
+ })
469
+
470
+ console.log(`Created project with ${tasks.data.length} tasks`)
471
+
472
+ // Start first task
473
+ if (tasks.data.length > 0) {
474
+ await codeguide.tasks.updateTask(tasks.data[0].id, {
475
+ status: 'in_progress',
476
+ notes: 'Starting project setup'
477
+ })
478
+ }
479
+
480
+ } catch (error) {
481
+ console.error('Project setup failed:', error.message)
482
+ }
483
+ }
484
+ ```
485
+
486
+ ## Contributing
487
+
488
+ 1. Fork the repository
489
+ 2. Create a feature branch
490
+ 3. Make your changes
491
+ 4. Add tests
492
+ 5. Submit a pull request
493
+
494
+ ## Support
495
+
496
+ - **Documentation**: [Main README](../../README.md)
497
+ - **CLI Package**: [@codeguide/cli](../cli/README.md)
498
+ - **Issues**: [GitHub Issues](https://github.com/CodeGuide-dev/codeguide/issues)
499
+ - **Discussions**: [GitHub Discussions](https://github.com/CodeGuide-dev/codeguide/discussions)
500
+
501
+ ## License
502
+
503
+ MIT License - see [LICENSE](../../LICENSE) file for details.
package/codeguide.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  RepositoryAnalysisService,
14
14
  TaskService,
15
15
  ApiKeyEnhancedService,
16
+ SubscriptionService,
16
17
  } from './services'
17
18
  import { APIServiceConfig, CodeGuideOptions } from './types'
18
19
 
@@ -23,6 +24,7 @@ export class CodeGuide {
23
24
  public repositoryAnalysis: RepositoryAnalysisService
24
25
  public tasks: TaskService
25
26
  public apiKeyEnhanced: ApiKeyEnhancedService
27
+ public subscription: SubscriptionService
26
28
  private options: CodeGuideOptions
27
29
 
28
30
  constructor(config: APIServiceConfig, options: CodeGuideOptions = {}) {
@@ -35,6 +37,7 @@ export class CodeGuide {
35
37
  this.repositoryAnalysis = new RepositoryAnalysisService(config)
36
38
  this.tasks = new TaskService(config)
37
39
  this.apiKeyEnhanced = new ApiKeyEnhancedService(config)
40
+ this.subscription = new SubscriptionService(config)
38
41
  }
39
42
 
40
43
  // Convenience method for backward compatibility
@@ -1,4 +1,4 @@
1
- import { GenerationService, ProjectService, UsageService, RepositoryAnalysisService, TaskService, ApiKeyEnhancedService } from './services';
1
+ import { GenerationService, ProjectService, UsageService, RepositoryAnalysisService, TaskService, ApiKeyEnhancedService, SubscriptionService } from './services';
2
2
  import { APIServiceConfig, CodeGuideOptions } from './types';
3
3
  export declare class CodeGuide {
4
4
  generation: GenerationService;
@@ -7,6 +7,7 @@ export declare class CodeGuide {
7
7
  repositoryAnalysis: RepositoryAnalysisService;
8
8
  tasks: TaskService;
9
9
  apiKeyEnhanced: ApiKeyEnhancedService;
10
+ subscription: SubscriptionService;
10
11
  private options;
11
12
  constructor(config: APIServiceConfig, options?: CodeGuideOptions);
12
13
  getGuidance(prompt: string): Promise<any>;
package/dist/codeguide.js CHANGED
@@ -22,6 +22,7 @@ class CodeGuide {
22
22
  this.repositoryAnalysis = new services_1.RepositoryAnalysisService(config);
23
23
  this.tasks = new services_1.TaskService(config);
24
24
  this.apiKeyEnhanced = new services_1.ApiKeyEnhancedService(config);
25
+ this.subscription = new services_1.SubscriptionService(config);
25
26
  }
26
27
  // Convenience method for backward compatibility
27
28
  async getGuidance(prompt) {
@@ -1,12 +1,12 @@
1
1
  import { BaseService } from '../base/base-service';
2
- import { ApiKey, CreateApiKeyRequest, CreateApiKeyResponse, ApiKeyPermission, RevokeApiKeyResponse } from '../../types';
2
+ import { CreateApiKeyRequest, CreateApiKeyResponse, ApiKeyPermissionResponse, RevokeApiKeyResponse, ApiKeyListResponse, ApiKeyResponse } from '../../types';
3
3
  export declare class ApiKeyEnhancedService extends BaseService {
4
4
  constructor(config: any);
5
5
  /**
6
6
  * Get all API keys for the authenticated user
7
7
  * GET /api-key-enhanced/
8
8
  */
9
- getAllApiKeys(): Promise<ApiKey[]>;
9
+ getAllApiKeys(): Promise<ApiKeyListResponse>;
10
10
  /**
11
11
  * Create a new API key
12
12
  * POST /api-key-enhanced/
@@ -21,32 +21,35 @@ export declare class ApiKeyEnhancedService extends BaseService {
21
21
  * Check if user can create API keys
22
22
  * GET /api-key-enhanced/check-permission
23
23
  */
24
- checkApiKeyPermission(): Promise<ApiKeyPermission>;
24
+ checkApiKeyPermission(): Promise<ApiKeyPermissionResponse>;
25
25
  /**
26
26
  * Get API key details by ID
27
27
  * GET /api-key-enhanced/{api_key_id}
28
28
  */
29
- getApiKeyById(apiKeyId: string): Promise<ApiKey>;
29
+ getApiKeyById(apiKeyId: string): Promise<ApiKeyResponse>;
30
30
  /**
31
31
  * Update API key name (if supported by API)
32
32
  * PUT /api-key-enhanced/{api_key_id}
33
33
  */
34
- updateApiKeyName(apiKeyId: string, name: string): Promise<ApiKey>;
34
+ updateApiKeyName(apiKeyId: string, name: string): Promise<ApiKeyResponse>;
35
35
  /**
36
36
  * Toggle API key active status (if supported by API)
37
37
  * PATCH /api-key-enhanced/{api_key_id}/toggle
38
38
  */
39
- toggleApiKeyStatus(apiKeyId: string): Promise<ApiKey>;
39
+ toggleApiKeyStatus(apiKeyId: string): Promise<ApiKeyResponse>;
40
40
  /**
41
41
  * Get API key usage statistics (if supported by API)
42
42
  * GET /api-key-enhanced/{api_key_id}/usage
43
43
  */
44
44
  getApiKeyUsage(apiKeyId: string): Promise<{
45
- usage_count: number;
46
- last_used?: string;
47
- daily_usage?: Array<{
48
- date: string;
49
- count: number;
50
- }>;
45
+ status: string;
46
+ data: {
47
+ usage_count: number;
48
+ last_used?: string;
49
+ daily_usage?: Array<{
50
+ date: string;
51
+ count: number;
52
+ }>;
53
+ };
51
54
  }>;
52
55
  }
@@ -5,9 +5,11 @@ export { UsageService } from './usage';
5
5
  export { RepositoryAnalysisService } from './repository-analysis';
6
6
  export { TaskService } from './tasks';
7
7
  export { ApiKeyEnhancedService } from './api-key-enhanced';
8
+ export { SubscriptionService } from './subscriptions';
8
9
  export * from './generation';
9
10
  export * from './projects';
10
11
  export * from './usage';
11
12
  export * from './repository-analysis';
12
13
  export * from './tasks';
13
14
  export * from './api-key-enhanced';
15
+ export * from './subscriptions';
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.ApiKeyEnhancedService = exports.TaskService = exports.RepositoryAnalysisService = exports.UsageService = exports.ProjectService = exports.GenerationService = exports.BaseService = void 0;
20
+ exports.SubscriptionService = exports.ApiKeyEnhancedService = exports.TaskService = exports.RepositoryAnalysisService = exports.UsageService = exports.ProjectService = exports.GenerationService = exports.BaseService = void 0;
21
21
  const dotenv_1 = __importDefault(require("dotenv"));
22
22
  const path_1 = __importDefault(require("path"));
23
23
  // Load environment variables from project root
@@ -39,6 +39,8 @@ var tasks_1 = require("./tasks");
39
39
  Object.defineProperty(exports, "TaskService", { enumerable: true, get: function () { return tasks_1.TaskService; } });
40
40
  var api_key_enhanced_1 = require("./api-key-enhanced");
41
41
  Object.defineProperty(exports, "ApiKeyEnhancedService", { enumerable: true, get: function () { return api_key_enhanced_1.ApiKeyEnhancedService; } });
42
+ var subscriptions_1 = require("./subscriptions");
43
+ Object.defineProperty(exports, "SubscriptionService", { enumerable: true, get: function () { return subscriptions_1.SubscriptionService; } });
42
44
  // Re-export all types for convenience
43
45
  __exportStar(require("./generation"), exports);
44
46
  __exportStar(require("./projects"), exports);
@@ -46,3 +48,4 @@ __exportStar(require("./usage"), exports);
46
48
  __exportStar(require("./repository-analysis"), exports);
47
49
  __exportStar(require("./tasks"), exports);
48
50
  __exportStar(require("./api-key-enhanced"), exports);
51
+ __exportStar(require("./subscriptions"), exports);
@@ -0,0 +1 @@
1
+ export { SubscriptionService } from './subscription-service';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionService = void 0;
4
+ var subscription_service_1 = require("./subscription-service");
5
+ Object.defineProperty(exports, "SubscriptionService", { enumerable: true, get: function () { return subscription_service_1.SubscriptionService; } });
@@ -0,0 +1,103 @@
1
+ import { BaseService } from '../base/base-service';
2
+ import { CurrentSubscriptionResponse, UserSubscriptionsResponse, CancelSubscriptionRequest, CancelSubscriptionResponse } from '../../types';
3
+ export declare class SubscriptionService extends BaseService {
4
+ constructor(config: any);
5
+ /**
6
+ * Get the currently active subscription for the authenticated user
7
+ * GET /subscriptions/current
8
+ */
9
+ getCurrentSubscription(): Promise<CurrentSubscriptionResponse>;
10
+ /**
11
+ * Get all subscriptions (active and historical) for the authenticated user
12
+ * GET /subscriptions/
13
+ */
14
+ getAllSubscriptions(): Promise<UserSubscriptionsResponse>;
15
+ /**
16
+ * Cancel subscription but keep it active until the end of the current billing period
17
+ * POST /subscriptions/{subscription_id}/cancel
18
+ */
19
+ cancelSubscription(subscriptionId: string, request: CancelSubscriptionRequest): Promise<CancelSubscriptionResponse>;
20
+ /**
21
+ * Get subscription details by ID
22
+ * GET /subscriptions/{subscription_id}
23
+ */
24
+ getSubscriptionById(subscriptionId: string): Promise<{
25
+ status: string;
26
+ data: {
27
+ subscription: any;
28
+ product: any;
29
+ price: any;
30
+ };
31
+ }>;
32
+ /**
33
+ * Reactivate a canceled subscription (if supported by API)
34
+ * POST /subscriptions/{subscription_id}/reactivate
35
+ */
36
+ reactivateSubscription(subscriptionId: string): Promise<{
37
+ status: string;
38
+ message: string;
39
+ data: any;
40
+ }>;
41
+ /**
42
+ * Update subscription quantity or other parameters
43
+ * PUT /subscriptions/{subscription_id}
44
+ */
45
+ updateSubscription(subscriptionId: string, updates: {
46
+ quantity?: number;
47
+ metadata?: Record<string, any>;
48
+ }): Promise<{
49
+ status: string;
50
+ data: any;
51
+ }>;
52
+ /**
53
+ * Get subscription usage statistics (if supported by API)
54
+ * GET /subscriptions/{subscription_id}/usage
55
+ */
56
+ getSubscriptionUsage(subscriptionId: string): Promise<{
57
+ status: string;
58
+ data: {
59
+ current_usage: number;
60
+ limit: number;
61
+ period_start: string;
62
+ period_end: string;
63
+ usage_breakdown?: Array<{
64
+ feature: string;
65
+ used: number;
66
+ limit: number;
67
+ }>;
68
+ };
69
+ }>;
70
+ /**
71
+ * Get upcoming invoice for subscription
72
+ * GET /subscriptions/{subscription_id}/upcoming-invoice
73
+ */
74
+ getUpcomingInvoice(subscriptionId: string): Promise<{
75
+ status: string;
76
+ data: {
77
+ amount: number;
78
+ currency: string;
79
+ date: string;
80
+ line_items: Array<{
81
+ description: string;
82
+ amount: number;
83
+ currency: string;
84
+ }>;
85
+ };
86
+ }>;
87
+ /**
88
+ * Get subscription history and payments
89
+ * GET /subscriptions/{subscription_id}/history
90
+ */
91
+ getSubscriptionHistory(subscriptionId: string): Promise<{
92
+ status: string;
93
+ data: Array<{
94
+ id: string;
95
+ type: 'payment' | 'invoice' | 'refund';
96
+ amount: number;
97
+ currency: string;
98
+ status: string;
99
+ created: string;
100
+ description?: string;
101
+ }>;
102
+ }>;
103
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionService = void 0;
4
+ const base_service_1 = require("../base/base-service");
5
+ class SubscriptionService extends base_service_1.BaseService {
6
+ constructor(config) {
7
+ super(config);
8
+ }
9
+ /**
10
+ * Get the currently active subscription for the authenticated user
11
+ * GET /subscriptions/current
12
+ */
13
+ async getCurrentSubscription() {
14
+ return this.get('/subscriptions/current');
15
+ }
16
+ /**
17
+ * Get all subscriptions (active and historical) for the authenticated user
18
+ * GET /subscriptions/
19
+ */
20
+ async getAllSubscriptions() {
21
+ return this.get('/subscriptions/');
22
+ }
23
+ /**
24
+ * Cancel subscription but keep it active until the end of the current billing period
25
+ * POST /subscriptions/{subscription_id}/cancel
26
+ */
27
+ async cancelSubscription(subscriptionId, request) {
28
+ return this.post(`/subscriptions/${subscriptionId}/cancel`, request);
29
+ }
30
+ /**
31
+ * Get subscription details by ID
32
+ * GET /subscriptions/{subscription_id}
33
+ */
34
+ async getSubscriptionById(subscriptionId) {
35
+ return this.get(`/subscriptions/${subscriptionId}`);
36
+ }
37
+ /**
38
+ * Reactivate a canceled subscription (if supported by API)
39
+ * POST /subscriptions/{subscription_id}/reactivate
40
+ */
41
+ async reactivateSubscription(subscriptionId) {
42
+ return this.post(`/subscriptions/${subscriptionId}/reactivate`, {});
43
+ }
44
+ /**
45
+ * Update subscription quantity or other parameters
46
+ * PUT /subscriptions/{subscription_id}
47
+ */
48
+ async updateSubscription(subscriptionId, updates) {
49
+ return this.put(`/subscriptions/${subscriptionId}`, updates);
50
+ }
51
+ /**
52
+ * Get subscription usage statistics (if supported by API)
53
+ * GET /subscriptions/{subscription_id}/usage
54
+ */
55
+ async getSubscriptionUsage(subscriptionId) {
56
+ return this.get(`/subscriptions/${subscriptionId}/usage`);
57
+ }
58
+ /**
59
+ * Get upcoming invoice for subscription
60
+ * GET /subscriptions/{subscription_id}/upcoming-invoice
61
+ */
62
+ async getUpcomingInvoice(subscriptionId) {
63
+ return this.get(`/subscriptions/${subscriptionId}/upcoming-invoice`);
64
+ }
65
+ /**
66
+ * Get subscription history and payments
67
+ * GET /subscriptions/{subscription_id}/history
68
+ */
69
+ async getSubscriptionHistory(subscriptionId) {
70
+ return this.get(`/subscriptions/${subscriptionId}/history`);
71
+ }
72
+ }
73
+ exports.SubscriptionService = SubscriptionService;
package/dist/types.d.ts CHANGED
@@ -42,31 +42,111 @@ export interface CodeGuideOptions {
42
42
  }
43
43
  export interface ApiKey {
44
44
  id: string;
45
+ key: string;
46
+ user_id: string;
45
47
  name: string;
46
- prefix: string;
47
48
  created_at: string;
48
- last_used?: string;
49
+ expires_at?: string;
49
50
  is_active: boolean;
50
- usage_count?: number;
51
+ metadata?: Record<string, any>;
52
+ }
53
+ export interface ApiKeyListResponse {
54
+ status: string;
55
+ data: ApiKey[];
51
56
  }
52
57
  export interface CreateApiKeyRequest {
53
58
  name: string;
54
59
  }
55
60
  export interface CreateApiKeyResponse {
56
- api_key: string;
61
+ status: string;
62
+ data: {
63
+ api_key: string;
64
+ id: string;
65
+ name: string;
66
+ created_at: string;
67
+ expires_at?: string;
68
+ is_active: boolean;
69
+ metadata?: Record<string, any>;
70
+ };
71
+ message?: string;
72
+ }
73
+ export interface ApiKeyPermissionResponse {
74
+ status: string;
75
+ data: {
76
+ can_create: boolean;
77
+ reason?: string;
78
+ current_keys_count?: number;
79
+ max_keys_allowed?: number;
80
+ };
81
+ }
82
+ export interface ApiKeyResponse {
83
+ status: string;
84
+ data: ApiKey;
85
+ }
86
+ export interface RevokeApiKeyResponse {
87
+ status: string;
88
+ message: string;
89
+ revoked_key_id?: string;
90
+ }
91
+ export interface Subscription {
57
92
  id: string;
93
+ user_id: string;
94
+ status: 'active' | 'canceled' | 'past_due' | 'unpaid' | 'trialing' | 'incomplete' | 'incomplete_expired';
95
+ metadata: Record<string, any>;
96
+ price_id: string;
97
+ quantity: number;
98
+ cancel_at_period_end: boolean;
99
+ created: string;
100
+ current_period_start: string;
101
+ current_period_end: string;
102
+ ended_at?: string | null;
103
+ cancel_at?: string | null;
104
+ canceled_at?: string | null;
105
+ trial_start?: string | null;
106
+ trial_end?: string | null;
107
+ org_id?: string | null;
108
+ }
109
+ export interface Product {
110
+ id: string;
111
+ active: boolean;
58
112
  name: string;
59
- prefix: string;
60
- created_at: string;
61
- message: string;
113
+ description: string;
114
+ image: string;
115
+ metadata: Record<string, any>;
116
+ marketing_features: string[];
117
+ live_mode: boolean;
118
+ is_team_plan: boolean;
119
+ }
120
+ export interface Price {
121
+ id: string;
122
+ product_id: string;
123
+ active: boolean;
124
+ description: string;
125
+ unit_amount: number;
126
+ currency: string;
127
+ type: 'recurring' | 'one_time';
128
+ interval: 'day' | 'week' | 'month' | 'year';
129
+ interval_count: number;
130
+ trial_period_days?: number | null;
131
+ metadata?: Record<string, any> | null;
62
132
  }
63
- export interface ApiKeyPermission {
64
- can_create: boolean;
65
- reason?: string;
66
- current_keys_count?: number;
67
- max_keys_allowed?: number;
133
+ export interface CurrentSubscriptionResponse {
134
+ status: string;
135
+ data: {
136
+ subscription: Subscription;
137
+ product: Product;
138
+ price: Price;
139
+ };
68
140
  }
69
- export interface RevokeApiKeyResponse {
141
+ export interface UserSubscriptionsResponse {
142
+ status: string;
143
+ data: Subscription[];
144
+ }
145
+ export interface CancelSubscriptionRequest {
146
+ cancel_at_period_end: boolean;
147
+ }
148
+ export interface CancelSubscriptionResponse {
149
+ status: string;
70
150
  message: string;
71
- revoked_key_id: string;
151
+ data: Subscription;
72
152
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeguide/core",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Core package for code guidance with programmatic API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,8 +3,10 @@ import {
3
3
  ApiKey,
4
4
  CreateApiKeyRequest,
5
5
  CreateApiKeyResponse,
6
- ApiKeyPermission,
6
+ ApiKeyPermissionResponse,
7
7
  RevokeApiKeyResponse,
8
+ ApiKeyListResponse,
9
+ ApiKeyResponse,
8
10
  } from '../../types'
9
11
 
10
12
  export class ApiKeyEnhancedService extends BaseService {
@@ -16,8 +18,8 @@ export class ApiKeyEnhancedService extends BaseService {
16
18
  * Get all API keys for the authenticated user
17
19
  * GET /api-key-enhanced/
18
20
  */
19
- async getAllApiKeys(): Promise<ApiKey[]> {
20
- return this.get<ApiKey[]>('/api-key-enhanced/')
21
+ async getAllApiKeys(): Promise<ApiKeyListResponse> {
22
+ return this.get<ApiKeyListResponse>('/api-key-enhanced/')
21
23
  }
22
24
 
23
25
  /**
@@ -40,32 +42,32 @@ export class ApiKeyEnhancedService extends BaseService {
40
42
  * Check if user can create API keys
41
43
  * GET /api-key-enhanced/check-permission
42
44
  */
43
- async checkApiKeyPermission(): Promise<ApiKeyPermission> {
44
- return this.get<ApiKeyPermission>('/api-key-enhanced/check-permission')
45
+ async checkApiKeyPermission(): Promise<ApiKeyPermissionResponse> {
46
+ return this.get<ApiKeyPermissionResponse>('/api-key-enhanced/check-permission')
45
47
  }
46
48
 
47
49
  /**
48
50
  * Get API key details by ID
49
51
  * GET /api-key-enhanced/{api_key_id}
50
52
  */
51
- async getApiKeyById(apiKeyId: string): Promise<ApiKey> {
52
- return this.get<ApiKey>(`/api-key-enhanced/${apiKeyId}`)
53
+ async getApiKeyById(apiKeyId: string): Promise<ApiKeyResponse> {
54
+ return this.get<ApiKeyResponse>(`/api-key-enhanced/${apiKeyId}`)
53
55
  }
54
56
 
55
57
  /**
56
58
  * Update API key name (if supported by API)
57
59
  * PUT /api-key-enhanced/{api_key_id}
58
60
  */
59
- async updateApiKeyName(apiKeyId: string, name: string): Promise<ApiKey> {
60
- return this.put<ApiKey>(`/api-key-enhanced/${apiKeyId}`, { name })
61
+ async updateApiKeyName(apiKeyId: string, name: string): Promise<ApiKeyResponse> {
62
+ return this.put<ApiKeyResponse>(`/api-key-enhanced/${apiKeyId}`, { name })
61
63
  }
62
64
 
63
65
  /**
64
66
  * Toggle API key active status (if supported by API)
65
67
  * PATCH /api-key-enhanced/{api_key_id}/toggle
66
68
  */
67
- async toggleApiKeyStatus(apiKeyId: string): Promise<ApiKey> {
68
- return this.post<ApiKey>(`/api-key-enhanced/${apiKeyId}/toggle`, {})
69
+ async toggleApiKeyStatus(apiKeyId: string): Promise<ApiKeyResponse> {
70
+ return this.post<ApiKeyResponse>(`/api-key-enhanced/${apiKeyId}/toggle`, {})
69
71
  }
70
72
 
71
73
  /**
@@ -73,9 +75,12 @@ export class ApiKeyEnhancedService extends BaseService {
73
75
  * GET /api-key-enhanced/{api_key_id}/usage
74
76
  */
75
77
  async getApiKeyUsage(apiKeyId: string): Promise<{
76
- usage_count: number
77
- last_used?: string
78
- daily_usage?: Array<{ date: string; count: number }>
78
+ status: string
79
+ data: {
80
+ usage_count: number
81
+ last_used?: string
82
+ daily_usage?: Array<{ date: string; count: number }>
83
+ }
79
84
  }> {
80
85
  return this.get(`/api-key-enhanced/${apiKeyId}/usage`)
81
86
  }
package/services/index.ts CHANGED
@@ -14,6 +14,7 @@ export { UsageService } from './usage'
14
14
  export { RepositoryAnalysisService } from './repository-analysis'
15
15
  export { TaskService } from './tasks'
16
16
  export { ApiKeyEnhancedService } from './api-key-enhanced'
17
+ export { SubscriptionService } from './subscriptions'
17
18
 
18
19
  // Re-export all types for convenience
19
20
  export * from './generation'
@@ -22,3 +23,4 @@ export * from './usage'
22
23
  export * from './repository-analysis'
23
24
  export * from './tasks'
24
25
  export * from './api-key-enhanced'
26
+ export * from './subscriptions'
@@ -0,0 +1 @@
1
+ export { SubscriptionService } from './subscription-service'
@@ -0,0 +1,147 @@
1
+ import { BaseService } from '../base/base-service'
2
+ import {
3
+ CurrentSubscriptionResponse,
4
+ UserSubscriptionsResponse,
5
+ CancelSubscriptionRequest,
6
+ CancelSubscriptionResponse,
7
+ } from '../../types'
8
+
9
+ export class SubscriptionService extends BaseService {
10
+ constructor(config: any) {
11
+ super(config)
12
+ }
13
+
14
+ /**
15
+ * Get the currently active subscription for the authenticated user
16
+ * GET /subscriptions/current
17
+ */
18
+ async getCurrentSubscription(): Promise<CurrentSubscriptionResponse> {
19
+ return this.get<CurrentSubscriptionResponse>('/subscriptions/current')
20
+ }
21
+
22
+ /**
23
+ * Get all subscriptions (active and historical) for the authenticated user
24
+ * GET /subscriptions/
25
+ */
26
+ async getAllSubscriptions(): Promise<UserSubscriptionsResponse> {
27
+ return this.get<UserSubscriptionsResponse>('/subscriptions/')
28
+ }
29
+
30
+ /**
31
+ * Cancel subscription but keep it active until the end of the current billing period
32
+ * POST /subscriptions/{subscription_id}/cancel
33
+ */
34
+ async cancelSubscription(
35
+ subscriptionId: string,
36
+ request: CancelSubscriptionRequest
37
+ ): Promise<CancelSubscriptionResponse> {
38
+ return this.post<CancelSubscriptionResponse>(
39
+ `/subscriptions/${subscriptionId}/cancel`,
40
+ request
41
+ )
42
+ }
43
+
44
+ /**
45
+ * Get subscription details by ID
46
+ * GET /subscriptions/{subscription_id}
47
+ */
48
+ async getSubscriptionById(subscriptionId: string): Promise<{
49
+ status: string
50
+ data: {
51
+ subscription: any
52
+ product: any
53
+ price: any
54
+ }
55
+ }> {
56
+ return this.get(`/subscriptions/${subscriptionId}`)
57
+ }
58
+
59
+ /**
60
+ * Reactivate a canceled subscription (if supported by API)
61
+ * POST /subscriptions/{subscription_id}/reactivate
62
+ */
63
+ async reactivateSubscription(subscriptionId: string): Promise<{
64
+ status: string
65
+ message: string
66
+ data: any
67
+ }> {
68
+ return this.post(`/subscriptions/${subscriptionId}/reactivate`, {})
69
+ }
70
+
71
+ /**
72
+ * Update subscription quantity or other parameters
73
+ * PUT /subscriptions/{subscription_id}
74
+ */
75
+ async updateSubscription(
76
+ subscriptionId: string,
77
+ updates: {
78
+ quantity?: number
79
+ metadata?: Record<string, any>
80
+ }
81
+ ): Promise<{
82
+ status: string
83
+ data: any
84
+ }> {
85
+ return this.put(`/subscriptions/${subscriptionId}`, updates)
86
+ }
87
+
88
+ /**
89
+ * Get subscription usage statistics (if supported by API)
90
+ * GET /subscriptions/{subscription_id}/usage
91
+ */
92
+ async getSubscriptionUsage(subscriptionId: string): Promise<{
93
+ status: string
94
+ data: {
95
+ current_usage: number
96
+ limit: number
97
+ period_start: string
98
+ period_end: string
99
+ usage_breakdown?: Array<{
100
+ feature: string
101
+ used: number
102
+ limit: number
103
+ }>
104
+ }
105
+ }> {
106
+ return this.get(`/subscriptions/${subscriptionId}/usage`)
107
+ }
108
+
109
+ /**
110
+ * Get upcoming invoice for subscription
111
+ * GET /subscriptions/{subscription_id}/upcoming-invoice
112
+ */
113
+ async getUpcomingInvoice(subscriptionId: string): Promise<{
114
+ status: string
115
+ data: {
116
+ amount: number
117
+ currency: string
118
+ date: string
119
+ line_items: Array<{
120
+ description: string
121
+ amount: number
122
+ currency: string
123
+ }>
124
+ }
125
+ }> {
126
+ return this.get(`/subscriptions/${subscriptionId}/upcoming-invoice`)
127
+ }
128
+
129
+ /**
130
+ * Get subscription history and payments
131
+ * GET /subscriptions/{subscription_id}/history
132
+ */
133
+ async getSubscriptionHistory(subscriptionId: string): Promise<{
134
+ status: string
135
+ data: Array<{
136
+ id: string
137
+ type: 'payment' | 'invoice' | 'refund'
138
+ amount: number
139
+ currency: string
140
+ status: string
141
+ created: string
142
+ description?: string
143
+ }>
144
+ }> {
145
+ return this.get(`/subscriptions/${subscriptionId}/history`)
146
+ }
147
+ }
package/types.ts CHANGED
@@ -53,12 +53,19 @@ export interface CodeGuideOptions {
53
53
  // API Key Enhanced Types
54
54
  export interface ApiKey {
55
55
  id: string
56
+ key: string
57
+ user_id: string
56
58
  name: string
57
- prefix: string
58
59
  created_at: string
59
- last_used?: string
60
+ expires_at?: string
60
61
  is_active: boolean
61
- usage_count?: number
62
+ metadata?: Record<string, any>
63
+ }
64
+
65
+ // API Response wrapper
66
+ export interface ApiKeyListResponse {
67
+ status: string
68
+ data: ApiKey[]
62
69
  }
63
70
 
64
71
  export interface CreateApiKeyRequest {
@@ -66,22 +73,106 @@ export interface CreateApiKeyRequest {
66
73
  }
67
74
 
68
75
  export interface CreateApiKeyResponse {
69
- api_key: string
76
+ status: string
77
+ data: {
78
+ api_key: string
79
+ id: string
80
+ name: string
81
+ created_at: string
82
+ expires_at?: string
83
+ is_active: boolean
84
+ metadata?: Record<string, any>
85
+ }
86
+ message?: string
87
+ }
88
+
89
+ export interface ApiKeyPermissionResponse {
90
+ status: string
91
+ data: {
92
+ can_create: boolean
93
+ reason?: string
94
+ current_keys_count?: number
95
+ max_keys_allowed?: number
96
+ }
97
+ }
98
+
99
+ export interface ApiKeyResponse {
100
+ status: string
101
+ data: ApiKey
102
+ }
103
+
104
+ export interface RevokeApiKeyResponse {
105
+ status: string
106
+ message: string
107
+ revoked_key_id?: string
108
+ }
109
+
110
+ // Subscription Types
111
+ export interface Subscription {
70
112
  id: string
113
+ user_id: string
114
+ status: 'active' | 'canceled' | 'past_due' | 'unpaid' | 'trialing' | 'incomplete' | 'incomplete_expired'
115
+ metadata: Record<string, any>
116
+ price_id: string
117
+ quantity: number
118
+ cancel_at_period_end: boolean
119
+ created: string
120
+ current_period_start: string
121
+ current_period_end: string
122
+ ended_at?: string | null
123
+ cancel_at?: string | null
124
+ canceled_at?: string | null
125
+ trial_start?: string | null
126
+ trial_end?: string | null
127
+ org_id?: string | null
128
+ }
129
+
130
+ export interface Product {
131
+ id: string
132
+ active: boolean
71
133
  name: string
72
- prefix: string
73
- created_at: string
74
- message: string
134
+ description: string
135
+ image: string
136
+ metadata: Record<string, any>
137
+ marketing_features: string[]
138
+ live_mode: boolean
139
+ is_team_plan: boolean
75
140
  }
76
141
 
77
- export interface ApiKeyPermission {
78
- can_create: boolean
79
- reason?: string
80
- current_keys_count?: number
81
- max_keys_allowed?: number
142
+ export interface Price {
143
+ id: string
144
+ product_id: string
145
+ active: boolean
146
+ description: string
147
+ unit_amount: number
148
+ currency: string
149
+ type: 'recurring' | 'one_time'
150
+ interval: 'day' | 'week' | 'month' | 'year'
151
+ interval_count: number
152
+ trial_period_days?: number | null
153
+ metadata?: Record<string, any> | null
82
154
  }
83
155
 
84
- export interface RevokeApiKeyResponse {
156
+ export interface CurrentSubscriptionResponse {
157
+ status: string
158
+ data: {
159
+ subscription: Subscription
160
+ product: Product
161
+ price: Price
162
+ }
163
+ }
164
+
165
+ export interface UserSubscriptionsResponse {
166
+ status: string
167
+ data: Subscription[]
168
+ }
169
+
170
+ export interface CancelSubscriptionRequest {
171
+ cancel_at_period_end: boolean
172
+ }
173
+
174
+ export interface CancelSubscriptionResponse {
175
+ status: string
85
176
  message: string
86
- revoked_key_id: string
177
+ data: Subscription
87
178
  }