@egdesk/next-api-plugin 1.1.0 → 1.2.2

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.
@@ -88,7 +88,8 @@ function generateApiWrapper(projectPath) {
88
88
  * Generated by @egdesk/next-api-plugin
89
89
  */
90
90
 
91
- const basePath = process.env.NEXT_PUBLIC_EGDESK_BASE_PATH || '';
91
+ const isDev = process.env.NODE_ENV === 'development';
92
+ const basePath = isDev ? '' : (process.env.NEXT_PUBLIC_EGDESK_BASE_PATH || '');
92
93
 
93
94
  /**
94
95
  * Fetch wrapper that handles basePath for tunneled environments
@@ -48,9 +48,9 @@ const os = __importStar(require("os"));
48
48
  function generateHelpers(projectPath) {
49
49
  const helperPath = path.join(projectPath, 'egdesk-helpers.ts');
50
50
  const helperContent = `/**
51
- * EGDesk User Data Helper Functions for Next.js
51
+ * EGDesk Helper Functions for Next.js
52
52
  *
53
- * Type-safe helpers for accessing EGDesk user data.
53
+ * Type-safe helpers for accessing EGDesk user data and FinanceHub.
54
54
  * Works in both client and server components.
55
55
  *
56
56
  * Generated by @egdesk/next-api-plugin
@@ -286,6 +286,159 @@ export async function renameTable(
286
286
  newDisplayName
287
287
  });
288
288
  }
289
+
290
+ // ==========================================
291
+ // FINANCEHUB HELPERS
292
+ // ==========================================
293
+
294
+ /**
295
+ * Call EGDesk FinanceHub MCP tool
296
+ */
297
+ export async function callFinanceHubTool(
298
+ toolName: string,
299
+ args: Record<string, any> = {}
300
+ ): Promise<any> {
301
+ const body = JSON.stringify({ tool: toolName, args });
302
+ const headers: Record<string, string> = {
303
+ 'Content-Type': 'application/json'
304
+ };
305
+
306
+ const isServer = typeof window === 'undefined';
307
+
308
+ let response: Response;
309
+ if (isServer) {
310
+ const apiUrl =
311
+ (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_EGDESK_API_URL) ||
312
+ EGDESK_CONFIG.apiUrl;
313
+ const apiKey =
314
+ (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_EGDESK_API_KEY) ||
315
+ EGDESK_CONFIG.apiKey;
316
+ if (apiKey) {
317
+ headers['X-Api-Key'] = apiKey;
318
+ }
319
+ response = await fetch(\`\${apiUrl}/financehub/tools/call\`, {
320
+ method: 'POST',
321
+ headers,
322
+ body
323
+ });
324
+ } else {
325
+ response = await fetch('/__financehub_proxy', {
326
+ method: 'POST',
327
+ headers,
328
+ body
329
+ });
330
+ }
331
+
332
+ if (!response.ok) {
333
+ throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
334
+ }
335
+
336
+ const result = await response.json();
337
+
338
+ if (!result.success) {
339
+ throw new Error(result.error || 'Tool call failed');
340
+ }
341
+
342
+ const content = result.result?.content?.[0]?.text;
343
+ return content ? JSON.parse(content) : null;
344
+ }
345
+
346
+ /**
347
+ * List all registered banks and card companies
348
+ */
349
+ export async function listBanks() {
350
+ return callFinanceHubTool('financehub_list_banks', {});
351
+ }
352
+
353
+ /**
354
+ * List bank accounts with balances
355
+ */
356
+ export async function listAccounts(options: {
357
+ bankId?: string;
358
+ isActive?: boolean;
359
+ } = {}) {
360
+ return callFinanceHubTool('financehub_list_accounts', options);
361
+ }
362
+
363
+ /**
364
+ * Query bank transactions
365
+ */
366
+ export async function queryBankTransactions(options: {
367
+ accountId?: string;
368
+ bankId?: string;
369
+ startDate?: string;
370
+ endDate?: string;
371
+ category?: string;
372
+ minAmount?: number;
373
+ maxAmount?: number;
374
+ searchText?: string;
375
+ limit?: number;
376
+ offset?: number;
377
+ orderBy?: 'date' | 'amount' | 'balance';
378
+ orderDir?: 'asc' | 'desc';
379
+ } = {}) {
380
+ return callFinanceHubTool('financehub_query_transactions', options);
381
+ }
382
+
383
+ /**
384
+ * Query card transactions (NEW)
385
+ */
386
+ export async function queryCardTransactions(options: {
387
+ accountId?: string;
388
+ cardCompanyId?: string;
389
+ cardNumber?: string;
390
+ merchantName?: string;
391
+ startDate?: string;
392
+ endDate?: string;
393
+ category?: string;
394
+ minAmount?: number;
395
+ maxAmount?: number;
396
+ includeCancelled?: boolean;
397
+ limit?: number;
398
+ offset?: number;
399
+ orderBy?: 'date' | 'amount';
400
+ orderDir?: 'asc' | 'desc';
401
+ } = {}) {
402
+ return callFinanceHubTool('financehub_query_card_transactions', options);
403
+ }
404
+
405
+ /**
406
+ * Get transaction statistics
407
+ */
408
+ export async function getTransactionStats(options: {
409
+ accountId?: string;
410
+ bankId?: string;
411
+ startDate?: string;
412
+ endDate?: string;
413
+ } = {}) {
414
+ return callFinanceHubTool('financehub_get_statistics', options);
415
+ }
416
+
417
+ /**
418
+ * Get monthly breakdown of deposits/withdrawals
419
+ */
420
+ export async function getMonthlySummary(options: {
421
+ accountId?: string;
422
+ bankId?: string;
423
+ year?: number;
424
+ months?: number;
425
+ } = {}) {
426
+ return callFinanceHubTool('financehub_get_monthly_summary', options);
427
+ }
428
+
429
+ /**
430
+ * Get overall stats (banks, accounts, transactions, balances)
431
+ */
432
+ export async function getOverallStats() {
433
+ return callFinanceHubTool('financehub_get_overall_stats', {});
434
+ }
435
+
436
+ /**
437
+ * Get sync operation history
438
+ */
439
+ export async function getSyncHistory(limit: number = 50) {
440
+ return callFinanceHubTool('financehub_get_sync_history', { limit });
441
+ }
289
442
  `;
290
443
  fs.writeFileSync(helperPath, helperContent.replace(/\r?\n/g, os.EOL), 'utf-8');
291
444
  console.log(`✅ Generated ${helperPath}`);
@@ -9,7 +9,8 @@ export interface UserDataTable {
9
9
  tableName: string;
10
10
  displayName: string;
11
11
  description?: string;
12
- rowCount: number;
12
+ /** May be unknown until the table is synced or counted */
13
+ rowCount?: number;
13
14
  columnCount: number;
14
15
  columns: string[];
15
16
  }
@@ -163,7 +163,7 @@ function updateEnvLocal(projectPath, config) {
163
163
  '',
164
164
  '# Available Tables',
165
165
  `# Total tables: ${config.tables.length}`,
166
- ...config.tables.map((table, index) => `# ${index + 1}. ${table.displayName} (${table.tableName}) - ${table.rowCount} rows, ${table.columnCount} columns`),
166
+ ...config.tables.map((table, index) => `# ${index + 1}. ${table.displayName} (${table.tableName}) - ${table.rowCount != null ? table.rowCount : '?'} rows, ${table.columnCount} columns`),
167
167
  ''
168
168
  ].join('\n');
169
169
  fs.writeFileSync(envPath, envContent.replace(/\r?\n/g, os.EOL), 'utf-8');
@@ -190,20 +190,26 @@ export interface TableDefinition {
190
190
  name: string;
191
191
  displayName: string;
192
192
  description?: string;
193
- rowCount: number;
193
+ /** Omitted or unknown until synced / counted */
194
+ rowCount?: number;
194
195
  columnCount: number;
195
196
  columns: string[];
196
197
  }
197
198
 
198
199
  export const TABLES = {
199
- ${config.tables.map((table, index) => ` table${index + 1}: {
200
- name: '${table.tableName}',
201
- displayName: '${table.displayName}',
202
- description: ${table.description ? `'${table.description}'` : 'undefined'},
203
- rowCount: ${table.rowCount},
204
- columnCount: ${table.columnCount},
205
- columns: [${table.columns.map(col => `'${col}'`).join(', ')}]
206
- } as TableDefinition`).join(',\n')}
200
+ ${config.tables.map((table, index) => {
201
+ const properties = [
202
+ `name: '${table.tableName}'`,
203
+ `displayName: '${table.displayName}'`,
204
+ table.description ? `description: '${table.description}'` : null,
205
+ table.rowCount != null ? `rowCount: ${table.rowCount}` : null,
206
+ `columnCount: ${table.columnCount}`,
207
+ `columns: [${table.columns.map(col => `'${col}'`).join(', ')}]`
208
+ ].filter(Boolean).join(',\n ');
209
+ return ` table${index + 1}: {
210
+ ${properties}
211
+ } as TableDefinition`;
212
+ }).join(',\n')}
207
213
  } as const;
208
214
 
209
215
  ${config.tables.length > 0 ? `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@egdesk/next-api-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.2.2",
4
4
  "description": "Next.js plugin for EGDesk database proxy integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -61,7 +61,8 @@ export function generateApiWrapper(projectPath: string): void {
61
61
  * Generated by @egdesk/next-api-plugin
62
62
  */
63
63
 
64
- const basePath = process.env.NEXT_PUBLIC_EGDESK_BASE_PATH || '';
64
+ const isDev = process.env.NODE_ENV === 'development';
65
+ const basePath = isDev ? '' : (process.env.NEXT_PUBLIC_EGDESK_BASE_PATH || '');
65
66
 
66
67
  /**
67
68
  * Fetch wrapper that handles basePath for tunneled environments
@@ -15,9 +15,9 @@ export function generateHelpers(projectPath: string): void {
15
15
  const helperPath = path.join(projectPath, 'egdesk-helpers.ts');
16
16
 
17
17
  const helperContent = `/**
18
- * EGDesk User Data Helper Functions for Next.js
18
+ * EGDesk Helper Functions for Next.js
19
19
  *
20
- * Type-safe helpers for accessing EGDesk user data.
20
+ * Type-safe helpers for accessing EGDesk user data and FinanceHub.
21
21
  * Works in both client and server components.
22
22
  *
23
23
  * Generated by @egdesk/next-api-plugin
@@ -253,6 +253,159 @@ export async function renameTable(
253
253
  newDisplayName
254
254
  });
255
255
  }
256
+
257
+ // ==========================================
258
+ // FINANCEHUB HELPERS
259
+ // ==========================================
260
+
261
+ /**
262
+ * Call EGDesk FinanceHub MCP tool
263
+ */
264
+ export async function callFinanceHubTool(
265
+ toolName: string,
266
+ args: Record<string, any> = {}
267
+ ): Promise<any> {
268
+ const body = JSON.stringify({ tool: toolName, args });
269
+ const headers: Record<string, string> = {
270
+ 'Content-Type': 'application/json'
271
+ };
272
+
273
+ const isServer = typeof window === 'undefined';
274
+
275
+ let response: Response;
276
+ if (isServer) {
277
+ const apiUrl =
278
+ (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_EGDESK_API_URL) ||
279
+ EGDESK_CONFIG.apiUrl;
280
+ const apiKey =
281
+ (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_EGDESK_API_KEY) ||
282
+ EGDESK_CONFIG.apiKey;
283
+ if (apiKey) {
284
+ headers['X-Api-Key'] = apiKey;
285
+ }
286
+ response = await fetch(\`\${apiUrl}/financehub/tools/call\`, {
287
+ method: 'POST',
288
+ headers,
289
+ body
290
+ });
291
+ } else {
292
+ response = await fetch('/__financehub_proxy', {
293
+ method: 'POST',
294
+ headers,
295
+ body
296
+ });
297
+ }
298
+
299
+ if (!response.ok) {
300
+ throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
301
+ }
302
+
303
+ const result = await response.json();
304
+
305
+ if (!result.success) {
306
+ throw new Error(result.error || 'Tool call failed');
307
+ }
308
+
309
+ const content = result.result?.content?.[0]?.text;
310
+ return content ? JSON.parse(content) : null;
311
+ }
312
+
313
+ /**
314
+ * List all registered banks and card companies
315
+ */
316
+ export async function listBanks() {
317
+ return callFinanceHubTool('financehub_list_banks', {});
318
+ }
319
+
320
+ /**
321
+ * List bank accounts with balances
322
+ */
323
+ export async function listAccounts(options: {
324
+ bankId?: string;
325
+ isActive?: boolean;
326
+ } = {}) {
327
+ return callFinanceHubTool('financehub_list_accounts', options);
328
+ }
329
+
330
+ /**
331
+ * Query bank transactions
332
+ */
333
+ export async function queryBankTransactions(options: {
334
+ accountId?: string;
335
+ bankId?: string;
336
+ startDate?: string;
337
+ endDate?: string;
338
+ category?: string;
339
+ minAmount?: number;
340
+ maxAmount?: number;
341
+ searchText?: string;
342
+ limit?: number;
343
+ offset?: number;
344
+ orderBy?: 'date' | 'amount' | 'balance';
345
+ orderDir?: 'asc' | 'desc';
346
+ } = {}) {
347
+ return callFinanceHubTool('financehub_query_transactions', options);
348
+ }
349
+
350
+ /**
351
+ * Query card transactions (NEW)
352
+ */
353
+ export async function queryCardTransactions(options: {
354
+ accountId?: string;
355
+ cardCompanyId?: string;
356
+ cardNumber?: string;
357
+ merchantName?: string;
358
+ startDate?: string;
359
+ endDate?: string;
360
+ category?: string;
361
+ minAmount?: number;
362
+ maxAmount?: number;
363
+ includeCancelled?: boolean;
364
+ limit?: number;
365
+ offset?: number;
366
+ orderBy?: 'date' | 'amount';
367
+ orderDir?: 'asc' | 'desc';
368
+ } = {}) {
369
+ return callFinanceHubTool('financehub_query_card_transactions', options);
370
+ }
371
+
372
+ /**
373
+ * Get transaction statistics
374
+ */
375
+ export async function getTransactionStats(options: {
376
+ accountId?: string;
377
+ bankId?: string;
378
+ startDate?: string;
379
+ endDate?: string;
380
+ } = {}) {
381
+ return callFinanceHubTool('financehub_get_statistics', options);
382
+ }
383
+
384
+ /**
385
+ * Get monthly breakdown of deposits/withdrawals
386
+ */
387
+ export async function getMonthlySummary(options: {
388
+ accountId?: string;
389
+ bankId?: string;
390
+ year?: number;
391
+ months?: number;
392
+ } = {}) {
393
+ return callFinanceHubTool('financehub_get_monthly_summary', options);
394
+ }
395
+
396
+ /**
397
+ * Get overall stats (banks, accounts, transactions, balances)
398
+ */
399
+ export async function getOverallStats() {
400
+ return callFinanceHubTool('financehub_get_overall_stats', {});
401
+ }
402
+
403
+ /**
404
+ * Get sync operation history
405
+ */
406
+ export async function getSyncHistory(limit: number = 50) {
407
+ return callFinanceHubTool('financehub_get_sync_history', { limit });
408
+ }
256
409
  `;
257
410
 
258
411
  fs.writeFileSync(helperPath, helperContent.replace(/\r?\n/g, os.EOL), 'utf-8');
@@ -14,7 +14,8 @@ export interface UserDataTable {
14
14
  tableName: string;
15
15
  displayName: string;
16
16
  description?: string;
17
- rowCount: number;
17
+ /** May be unknown until the table is synced or counted */
18
+ rowCount?: number;
18
19
  columnCount: number;
19
20
  columns: string[];
20
21
  }
@@ -168,7 +169,7 @@ export function updateEnvLocal(
168
169
  '# Available Tables',
169
170
  `# Total tables: ${config.tables.length}`,
170
171
  ...config.tables.map((table, index) =>
171
- `# ${index + 1}. ${table.displayName} (${table.tableName}) - ${table.rowCount} rows, ${table.columnCount} columns`
172
+ `# ${index + 1}. ${table.displayName} (${table.tableName}) - ${table.rowCount != null ? table.rowCount : '?'} rows, ${table.columnCount} columns`
172
173
  ),
173
174
  ''
174
175
  ].join('\n');
@@ -202,20 +203,27 @@ export interface TableDefinition {
202
203
  name: string;
203
204
  displayName: string;
204
205
  description?: string;
205
- rowCount: number;
206
+ /** Omitted or unknown until synced / counted */
207
+ rowCount?: number;
206
208
  columnCount: number;
207
209
  columns: string[];
208
210
  }
209
211
 
210
212
  export const TABLES = {
211
- ${config.tables.map((table, index) => ` table${index + 1}: {
212
- name: '${table.tableName}',
213
- displayName: '${table.displayName}',
214
- description: ${table.description ? `'${table.description}'` : 'undefined'},
215
- rowCount: ${table.rowCount},
216
- columnCount: ${table.columnCount},
217
- columns: [${table.columns.map(col => `'${col}'`).join(', ')}]
218
- } as TableDefinition`).join(',\n')}
213
+ ${config.tables.map((table, index) => {
214
+ const properties = [
215
+ `name: '${table.tableName}'`,
216
+ `displayName: '${table.displayName}'`,
217
+ table.description ? `description: '${table.description}'` : null,
218
+ table.rowCount != null ? `rowCount: ${table.rowCount}` : null,
219
+ `columnCount: ${table.columnCount}`,
220
+ `columns: [${table.columns.map(col => `'${col}'`).join(', ')}]`
221
+ ].filter(Boolean).join(',\n ');
222
+
223
+ return ` table${index + 1}: {
224
+ ${properties}
225
+ } as TableDefinition`;
226
+ }).join(',\n')}
219
227
  } as const;
220
228
 
221
229
  ${config.tables.length > 0 ? `