@cakemail-org/cakemail-cli 1.3.0 → 1.5.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.
Files changed (80) hide show
  1. package/dist/cli.js +40 -6
  2. package/dist/cli.js.map +1 -1
  3. package/dist/client.js +0 -2
  4. package/dist/client.js.map +1 -1
  5. package/dist/commands/account.d.ts +5 -0
  6. package/dist/commands/account.d.ts.map +1 -0
  7. package/dist/commands/account.js +231 -0
  8. package/dist/commands/account.js.map +1 -0
  9. package/dist/commands/attributes.d.ts.map +1 -1
  10. package/dist/commands/attributes.js +43 -15
  11. package/dist/commands/attributes.js.map +1 -1
  12. package/dist/commands/campaigns.d.ts.map +1 -1
  13. package/dist/commands/campaigns.js +153 -19
  14. package/dist/commands/campaigns.js.map +1 -1
  15. package/dist/commands/config.d.ts +8 -0
  16. package/dist/commands/config.d.ts.map +1 -0
  17. package/dist/commands/config.js +235 -0
  18. package/dist/commands/config.js.map +1 -0
  19. package/dist/commands/contacts.d.ts.map +1 -1
  20. package/dist/commands/contacts.js +233 -38
  21. package/dist/commands/contacts.js.map +1 -1
  22. package/dist/commands/lists.d.ts.map +1 -1
  23. package/dist/commands/lists.js +160 -23
  24. package/dist/commands/lists.js.map +1 -1
  25. package/dist/commands/reports.d.ts.map +1 -1
  26. package/dist/commands/reports.js +90 -13
  27. package/dist/commands/reports.js.map +1 -1
  28. package/dist/commands/segments.d.ts.map +1 -1
  29. package/dist/commands/segments.js +59 -21
  30. package/dist/commands/segments.js.map +1 -1
  31. package/dist/commands/senders.d.ts.map +1 -1
  32. package/dist/commands/senders.js +36 -5
  33. package/dist/commands/senders.js.map +1 -1
  34. package/dist/commands/suppressed.d.ts.map +1 -1
  35. package/dist/commands/suppressed.js +20 -6
  36. package/dist/commands/suppressed.js.map +1 -1
  37. package/dist/commands/templates.d.ts.map +1 -1
  38. package/dist/commands/templates.js +11 -3
  39. package/dist/commands/templates.js.map +1 -1
  40. package/dist/types/profile.d.ts +92 -0
  41. package/dist/types/profile.d.ts.map +1 -0
  42. package/dist/types/profile.js +119 -0
  43. package/dist/types/profile.js.map +1 -0
  44. package/dist/utils/auth.d.ts +26 -0
  45. package/dist/utils/auth.d.ts.map +1 -0
  46. package/dist/utils/auth.js +198 -0
  47. package/dist/utils/auth.js.map +1 -0
  48. package/dist/utils/config-file.d.ts +92 -0
  49. package/dist/utils/config-file.d.ts.map +1 -0
  50. package/dist/utils/config-file.js +244 -0
  51. package/dist/utils/config-file.js.map +1 -0
  52. package/dist/utils/config.d.ts +11 -2
  53. package/dist/utils/config.d.ts.map +1 -1
  54. package/dist/utils/config.js +74 -8
  55. package/dist/utils/config.js.map +1 -1
  56. package/dist/utils/confirm.d.ts +38 -0
  57. package/dist/utils/confirm.d.ts.map +1 -0
  58. package/dist/utils/confirm.js +124 -0
  59. package/dist/utils/confirm.js.map +1 -0
  60. package/dist/utils/defaults.d.ts +39 -0
  61. package/dist/utils/defaults.d.ts.map +1 -0
  62. package/dist/utils/defaults.js +195 -0
  63. package/dist/utils/defaults.js.map +1 -0
  64. package/dist/utils/errors.d.ts +67 -0
  65. package/dist/utils/errors.d.ts.map +1 -0
  66. package/dist/utils/errors.js +395 -0
  67. package/dist/utils/errors.js.map +1 -0
  68. package/dist/utils/interactive.d.ts +97 -0
  69. package/dist/utils/interactive.d.ts.map +1 -0
  70. package/dist/utils/interactive.js +265 -0
  71. package/dist/utils/interactive.js.map +1 -0
  72. package/dist/utils/output.d.ts +72 -2
  73. package/dist/utils/output.d.ts.map +1 -1
  74. package/dist/utils/output.js +383 -37
  75. package/dist/utils/output.js.map +1 -1
  76. package/dist/utils/progress.d.ts +139 -0
  77. package/dist/utils/progress.d.ts.map +1 -0
  78. package/dist/utils/progress.js +216 -0
  79. package/dist/utils/progress.js.map +1 -0
  80. package/package.json +3 -1
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Profile System Types
3
+ *
4
+ * Defines the profile-based UX system that adapts CLI behavior
5
+ * based on user type (developer vs marketer vs balanced)
6
+ */
7
+ /**
8
+ * Developer profile: JSON output, minimal interactivity, scriptable
9
+ */
10
+ export const DEVELOPER_PROFILE = {
11
+ output: {
12
+ format: 'json',
13
+ colors: 'minimal',
14
+ pretty_print: false,
15
+ show_tips: false,
16
+ },
17
+ behavior: {
18
+ interactive_prompts: false,
19
+ confirm_destructive: false,
20
+ auto_open_browser: false,
21
+ show_progress: false,
22
+ },
23
+ display: {
24
+ date_format: 'iso8601',
25
+ show_ids: true,
26
+ show_api_details: true,
27
+ verbose_errors: true,
28
+ },
29
+ };
30
+ /**
31
+ * Marketer profile: Compact output, rich interactivity, guided workflows
32
+ */
33
+ export const MARKETER_PROFILE = {
34
+ output: {
35
+ format: 'compact',
36
+ colors: 'rich',
37
+ pretty_print: true,
38
+ show_tips: true,
39
+ },
40
+ behavior: {
41
+ interactive_prompts: true,
42
+ confirm_destructive: true,
43
+ auto_open_browser: true,
44
+ show_progress: true,
45
+ },
46
+ display: {
47
+ date_format: 'relative',
48
+ show_ids: false,
49
+ show_api_details: false,
50
+ verbose_errors: false,
51
+ },
52
+ };
53
+ /**
54
+ * Balanced profile: Mix of both workflows, context-dependent
55
+ */
56
+ export const BALANCED_PROFILE = {
57
+ output: {
58
+ format: 'table',
59
+ colors: 'moderate',
60
+ pretty_print: true,
61
+ show_tips: true,
62
+ },
63
+ behavior: {
64
+ interactive_prompts: 'auto',
65
+ confirm_destructive: true,
66
+ auto_open_browser: false,
67
+ show_progress: true,
68
+ },
69
+ display: {
70
+ date_format: 'friendly',
71
+ show_ids: true,
72
+ show_api_details: false,
73
+ verbose_errors: false,
74
+ },
75
+ };
76
+ /**
77
+ * Get default profile configuration by type
78
+ */
79
+ export function getDefaultProfile(type) {
80
+ switch (type) {
81
+ case 'developer':
82
+ return DEVELOPER_PROFILE;
83
+ case 'marketer':
84
+ return MARKETER_PROFILE;
85
+ case 'balanced':
86
+ return BALANCED_PROFILE;
87
+ default:
88
+ return BALANCED_PROFILE;
89
+ }
90
+ }
91
+ /**
92
+ * Profile descriptions for display in prompts
93
+ */
94
+ export const PROFILE_DESCRIPTIONS = {
95
+ developer: {
96
+ name: '👨‍💻 Developer/Technical user',
97
+ description: [
98
+ 'Scripting and automation',
99
+ 'JSON output and piping',
100
+ 'Minimal interactivity',
101
+ ],
102
+ },
103
+ marketer: {
104
+ name: '📊 Marketer/Business user',
105
+ description: [
106
+ 'Campaign management',
107
+ 'Visual formatting and guides',
108
+ 'Interactive workflows',
109
+ ],
110
+ },
111
+ balanced: {
112
+ name: '🔄 Both/Balanced',
113
+ description: [
114
+ 'Mix of technical and business tasks',
115
+ 'Flexible workflow',
116
+ ],
117
+ },
118
+ };
119
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/types/profile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwEH;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,MAAM,EAAE;QACN,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,KAAK;KACjB;IACD,QAAQ,EAAE;QACR,mBAAmB,EAAE,KAAK;QAC1B,mBAAmB,EAAE,KAAK;QAC1B,iBAAiB,EAAE,KAAK;QACxB,aAAa,EAAE,KAAK;KACrB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,IAAI;QACd,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C,MAAM,EAAE;QACN,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,IAAI;KAChB;IACD,QAAQ,EAAE;QACR,mBAAmB,EAAE,IAAI;QACzB,mBAAmB,EAAE,IAAI;QACzB,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,IAAI;KACpB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,UAAU;QACvB,QAAQ,EAAE,KAAK;QACf,gBAAgB,EAAE,KAAK;QACvB,cAAc,EAAE,KAAK;KACtB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C,MAAM,EAAE;QACN,MAAM,EAAE,OAAO;QACf,MAAM,EAAE,UAAU;QAClB,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,IAAI;KAChB;IACD,QAAQ,EAAE;QACR,mBAAmB,EAAE,MAAM;QAC3B,mBAAmB,EAAE,IAAI;QACzB,iBAAiB,EAAE,KAAK;QACxB,aAAa,EAAE,IAAI;KACpB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,UAAU;QACvB,QAAQ,EAAE,IAAI;QACd,gBAAgB,EAAE,KAAK;QACvB,cAAc,EAAE,KAAK;KACtB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW;YACd,OAAO,iBAAiB,CAAC;QAC3B,KAAK,UAAU;YACb,OAAO,gBAAgB,CAAC;QAC1B,KAAK,UAAU;YACb,OAAO,gBAAgB,CAAC;QAC1B;YACE,OAAO,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,SAAS,EAAE;QACT,IAAI,EAAE,gCAAgC;QACtC,WAAW,EAAE;YACX,0BAA0B;YAC1B,wBAAwB;YACxB,uBAAuB;SACxB;KACF;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE;YACX,qBAAqB;YACrB,8BAA8B;YAC9B,uBAAuB;SACxB;KACF;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE;YACX,qCAAqC;YACrC,mBAAmB;SACpB;KACF;CACF,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { ProfileType } from '../types/profile.js';
2
+ export interface Credentials {
3
+ email: string;
4
+ password: string;
5
+ }
6
+ /**
7
+ * Prompts the user to select their profile type
8
+ */
9
+ export declare function promptForProfile(): Promise<ProfileType>;
10
+ /**
11
+ * Prompts the user for their Cakemail credentials
12
+ */
13
+ export declare function promptForCredentials(): Promise<Credentials>;
14
+ /**
15
+ * Tests credentials by attempting to authenticate with the API
16
+ */
17
+ export declare function testCredentials(email: string, password: string): Promise<boolean>;
18
+ /**
19
+ * Saves credentials to .env file in current working directory
20
+ */
21
+ export declare function saveCredentials(email: string, password: string, accountId?: string): void;
22
+ /**
23
+ * Interactive authentication flow - prompts for credentials and saves them
24
+ */
25
+ export declare function authenticateInteractively(): Promise<Credentials>;
26
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAwB,MAAM,qBAAqB,CAAC;AAGxE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,CAAC,CA2B7D;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,WAAW,CAAC,CAkCjE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcvF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAkCzF;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,WAAW,CAAC,CAwFtE"}
@@ -0,0 +1,198 @@
1
+ import inquirer from 'inquirer';
2
+ import { writeFileSync, readFileSync, existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { CakemailClient as SDK } from '@cakemail-org/cakemail-sdk';
5
+ import chalk from 'chalk';
6
+ import { PROFILE_DESCRIPTIONS } from '../types/profile.js';
7
+ import { updateConfigFile, configFileExists } from './config-file.js';
8
+ /**
9
+ * Prompts the user to select their profile type
10
+ */
11
+ export async function promptForProfile() {
12
+ console.log(chalk.cyan('\n✨ One more thing - let\'s personalize your experience!\n'));
13
+ console.log(chalk.white('What best describes how you\'ll use Cakemail CLI?\n'));
14
+ // Build choices from profile descriptions
15
+ const choices = Object.entries(PROFILE_DESCRIPTIONS).map(([key, info], index) => {
16
+ const description = info.description.map(d => ` ${chalk.gray('•')} ${d}`).join('\n');
17
+ return {
18
+ name: `${index + 1}. ${info.name}\n${description}\n`,
19
+ value: key,
20
+ short: info.name
21
+ };
22
+ });
23
+ const answer = await inquirer.prompt([
24
+ {
25
+ type: 'list',
26
+ name: 'profile',
27
+ message: 'Choose your profile:',
28
+ choices,
29
+ pageSize: 10
30
+ }
31
+ ]);
32
+ console.log(chalk.gray(`\n💡 You can change this anytime with: ${chalk.cyan('cakemail config profile <type>')}\n`));
33
+ return answer.profile;
34
+ }
35
+ /**
36
+ * Prompts the user for their Cakemail credentials
37
+ */
38
+ export async function promptForCredentials() {
39
+ console.log(chalk.yellow('⚠ Not authenticated'));
40
+ console.log(chalk.gray('Please enter your Cakemail credentials:\n'));
41
+ const answers = await inquirer.prompt([
42
+ {
43
+ type: 'input',
44
+ name: 'email',
45
+ message: 'Email:',
46
+ validate: (input) => {
47
+ if (!input || !input.includes('@')) {
48
+ return 'Please enter a valid email address';
49
+ }
50
+ return true;
51
+ }
52
+ },
53
+ {
54
+ type: 'password',
55
+ name: 'password',
56
+ message: 'Password:',
57
+ mask: '*',
58
+ validate: (input) => {
59
+ if (!input || input.length < 1) {
60
+ return 'Please enter your password';
61
+ }
62
+ return true;
63
+ }
64
+ }
65
+ ]);
66
+ return {
67
+ email: answers.email,
68
+ password: answers.password
69
+ };
70
+ }
71
+ /**
72
+ * Tests credentials by attempting to authenticate with the API
73
+ */
74
+ export async function testCredentials(email, password) {
75
+ try {
76
+ const sdk = new SDK({
77
+ email,
78
+ password,
79
+ baseURL: process.env.CAKEMAIL_API_BASE || 'https://api.cakemail.dev'
80
+ });
81
+ // Test credentials by fetching account info
82
+ await sdk.accountService.getSelfAccount();
83
+ return true;
84
+ }
85
+ catch (error) {
86
+ return false;
87
+ }
88
+ }
89
+ /**
90
+ * Saves credentials to .env file in current working directory
91
+ */
92
+ export function saveCredentials(email, password, accountId) {
93
+ const envPath = join(process.cwd(), '.env');
94
+ let envContent = '';
95
+ // Read existing .env if it exists
96
+ if (existsSync(envPath)) {
97
+ envContent = readFileSync(envPath, 'utf-8');
98
+ }
99
+ // Parse existing env variables
100
+ const envLines = envContent.split('\n');
101
+ const envVars = {};
102
+ envLines.forEach(line => {
103
+ const match = line.match(/^([^=]+)=(.*)$/);
104
+ if (match) {
105
+ envVars[match[1].trim()] = match[2].trim();
106
+ }
107
+ });
108
+ // Update credentials
109
+ envVars['CAKEMAIL_EMAIL'] = email;
110
+ envVars['CAKEMAIL_PASSWORD'] = password;
111
+ if (accountId !== undefined) {
112
+ envVars['CAKEMAIL_CURRENT_ACCOUNT_ID'] = accountId;
113
+ }
114
+ // Rebuild .env content
115
+ const newEnvContent = Object.entries(envVars)
116
+ .map(([key, value]) => `${key}=${value}`)
117
+ .join('\n') + '\n';
118
+ writeFileSync(envPath, newEnvContent, 'utf-8');
119
+ }
120
+ /**
121
+ * Interactive authentication flow - prompts for credentials and saves them
122
+ */
123
+ export async function authenticateInteractively() {
124
+ const credentials = await promptForCredentials();
125
+ console.log(chalk.gray('\nValidating credentials...'));
126
+ const isValid = await testCredentials(credentials.email, credentials.password);
127
+ if (!isValid) {
128
+ console.log(chalk.red('✗ Invalid credentials. Please try again.\n'));
129
+ // Retry
130
+ return authenticateInteractively();
131
+ }
132
+ console.log(chalk.green('✓ Authenticated'));
133
+ // Fetch account info to show welcome message
134
+ let accountId;
135
+ try {
136
+ const sdk = new SDK({
137
+ email: credentials.email,
138
+ password: credentials.password,
139
+ baseURL: process.env.CAKEMAIL_API_BASE || 'https://api.cakemail.dev'
140
+ });
141
+ const accountResponse = await sdk.accountService.getSelfAccount();
142
+ const account = accountResponse.data;
143
+ accountId = account.id;
144
+ // List all accessible accounts with count
145
+ const accountsResponse = await sdk.subAccountService.listAccounts({
146
+ partnerAccountId: parseInt(account.id),
147
+ recursive: true,
148
+ withCount: true
149
+ });
150
+ // Use actual count from pagination if available, otherwise show "X+" for first page
151
+ const subAccountCount = accountsResponse.pagination?.count ?? accountsResponse.data?.length ?? 0;
152
+ const totalAccounts = 1 + subAccountCount;
153
+ const hasMorePages = accountsResponse.pagination?.count === null && (accountsResponse.data?.length || 0) >= 50;
154
+ const accountMessage = hasMorePages
155
+ ? `Welcome! You have access to ${totalAccounts}+ accounts.`
156
+ : `Welcome! You have access to ${totalAccounts} account${totalAccounts > 1 ? 's' : ''}.`;
157
+ console.log(chalk.cyan(`\n${accountMessage}`));
158
+ if (totalAccounts > 1) {
159
+ console.log(chalk.gray(`Use 'cakemail account list' to see all accounts.`));
160
+ console.log(chalk.gray(`Use 'cakemail account use <id>' to switch accounts.`));
161
+ }
162
+ }
163
+ catch (error) {
164
+ // If we can't fetch account info, just show basic welcome
165
+ console.log(chalk.cyan('\nWelcome!\n'));
166
+ }
167
+ // Check if this is first-time setup (no config file exists yet)
168
+ const isFirstTimeSetup = !configFileExists();
169
+ // Prompt for profile selection on first-time setup
170
+ let selectedProfile;
171
+ if (isFirstTimeSetup) {
172
+ selectedProfile = await promptForProfile();
173
+ console.log(chalk.green(`✓ Profile set to: ${PROFILE_DESCRIPTIONS[selectedProfile].name}`));
174
+ }
175
+ // Save to config file (preferred) or fallback to .env
176
+ if (isFirstTimeSetup || configFileExists()) {
177
+ // Save to config file
178
+ updateConfigFile({
179
+ version: '1.0',
180
+ profile: selectedProfile || 'balanced',
181
+ auth: {
182
+ method: 'password',
183
+ email: credentials.email,
184
+ base_url: process.env.CAKEMAIL_API_BASE || 'https://api.cakemail.dev'
185
+ },
186
+ defaults: accountId ? { account_id: accountId } : undefined
187
+ });
188
+ console.log(chalk.green('✓ Configuration saved to ~/.cakemail/config.json'));
189
+ }
190
+ else {
191
+ // Fallback to .env for backward compatibility
192
+ saveCredentials(credentials.email, credentials.password, accountId);
193
+ console.log(chalk.green('✓ Credentials saved to .env'));
194
+ }
195
+ console.log(chalk.gray('\n' + '─'.repeat(50) + '\n'));
196
+ return credentials;
197
+ }
198
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Configuration File Management
3
+ *
4
+ * Handles reading/writing ~/.cakemail/config.json
5
+ * Supports migration from .env to config file
6
+ */
7
+ import { ProfileType, ProfileConfig } from '../types/profile.js';
8
+ /**
9
+ * Complete configuration file schema
10
+ */
11
+ export interface ConfigFile {
12
+ version: string;
13
+ profile?: ProfileType;
14
+ auth?: {
15
+ method?: 'password' | 'token';
16
+ email?: string;
17
+ token?: string;
18
+ base_url?: string;
19
+ };
20
+ profiles?: {
21
+ developer?: Partial<ProfileConfig>;
22
+ marketer?: Partial<ProfileConfig>;
23
+ balanced?: Partial<ProfileConfig>;
24
+ custom?: Partial<ProfileConfig>;
25
+ };
26
+ defaults?: {
27
+ list_id?: number;
28
+ sender_id?: number;
29
+ account_id?: string;
30
+ };
31
+ }
32
+ /**
33
+ * Ensure config directory exists
34
+ */
35
+ export declare function ensureConfigDir(): void;
36
+ /**
37
+ * Check if config file exists
38
+ */
39
+ export declare function configFileExists(): boolean;
40
+ /**
41
+ * Load config file
42
+ * Returns undefined if file doesn't exist
43
+ */
44
+ export declare function loadConfigFile(): ConfigFile | undefined;
45
+ /**
46
+ * Save config file
47
+ */
48
+ export declare function saveConfigFile(config: ConfigFile): void;
49
+ /**
50
+ * Update config file (merge with existing)
51
+ */
52
+ export declare function updateConfigFile(updates: Partial<ConfigFile>): void;
53
+ /**
54
+ * Get current profile from config file
55
+ */
56
+ export declare function getCurrentProfile(): ProfileType;
57
+ /**
58
+ * Set current profile in config file
59
+ */
60
+ export declare function setCurrentProfile(profile: ProfileType): void;
61
+ /**
62
+ * Get profile configuration
63
+ * Merges default profile with custom overrides
64
+ */
65
+ export declare function getProfileConfig(profileType?: ProfileType): ProfileConfig;
66
+ /**
67
+ * Set a custom profile config value
68
+ * Example: setProfileConfigValue('output.format', 'table')
69
+ */
70
+ export declare function setProfileConfigValue(key: string, value: any): void;
71
+ /**
72
+ * Reset custom profile config
73
+ */
74
+ export declare function resetProfileConfig(): void;
75
+ /**
76
+ * Migrate .env to config file
77
+ * This runs once when user first upgrades to profile system
78
+ */
79
+ export declare function migrateFromEnv(): ConfigFile | undefined;
80
+ /**
81
+ * Get defaults (list_id, sender_id, account_id)
82
+ */
83
+ export declare function getDefaults(): {
84
+ list_id?: number;
85
+ sender_id?: number;
86
+ account_id?: string;
87
+ };
88
+ /**
89
+ * Set a default value
90
+ */
91
+ export declare function setDefault(key: 'list_id' | 'sender_id' | 'account_id', value: number | string): void;
92
+ //# sourceMappingURL=config-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file.d.ts","sourceRoot":"","sources":["../../src/utils/config-file.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAqB,MAAM,qBAAqB,CAAC;AAKpF;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QACnC,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAClC,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;KACjC,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,GAAG,SAAS,CAYvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CASvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAInE;AAeD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAG/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAE5D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,aAAa,CAmBzE;AAsBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CA0BnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CASzC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,UAAU,GAAG,SAAS,CAsDvD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAO3F;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,WAAW,GAAG,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcpG"}