@stephendolan/ynab-cli 1.2.2 → 1.2.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.
package/dist/cli.js CHANGED
@@ -5,6 +5,95 @@ import { Command as Command11 } from "commander";
5
5
 
6
6
  // src/lib/utils.ts
7
7
  import { format, parseISO } from "date-fns";
8
+
9
+ // src/lib/errors.ts
10
+ var YnabCliError = class extends Error {
11
+ constructor(message, statusCode) {
12
+ super(message);
13
+ this.statusCode = statusCode;
14
+ this.name = "YnabCliError";
15
+ }
16
+ };
17
+ var ERROR_STATUS_CODES = {
18
+ bad_request: 400,
19
+ not_authorized: 401,
20
+ subscription_lapsed: 403,
21
+ trial_expired: 403,
22
+ unauthorized_scope: 403,
23
+ data_limit_reached: 403,
24
+ not_found: 404,
25
+ resource_not_found: 404,
26
+ conflict: 409,
27
+ too_many_requests: 429,
28
+ internal_server_error: 500,
29
+ service_unavailable: 503
30
+ };
31
+ function sanitizeErrorMessage(message) {
32
+ const sensitivePatterns = [
33
+ /Bearer\s+[\w\-._~+/]+=*/gi,
34
+ /token[=:]\s*[\w\-._~+/]+=*/gi,
35
+ /api[_-]?key[=:]\s*[\w\-._~+/]+=*/gi,
36
+ /authorization:\s*bearer\s+[\w\-._~+/]+=*/gi
37
+ ];
38
+ let sanitized = message;
39
+ for (const pattern of sensitivePatterns) {
40
+ sanitized = sanitized.replace(pattern, "[REDACTED]");
41
+ }
42
+ return sanitized.length > 500 ? sanitized.substring(0, 500) + "..." : sanitized;
43
+ }
44
+ function isErrorObject(value) {
45
+ return typeof value === "object" && value !== null;
46
+ }
47
+ function sanitizeApiError(error) {
48
+ if (!isErrorObject(error)) {
49
+ return {
50
+ name: "api_error",
51
+ detail: "An error occurred",
52
+ id: void 0
53
+ };
54
+ }
55
+ const apiError = error;
56
+ const detail = sanitizeErrorMessage(
57
+ String(apiError.detail || apiError.message || "An error occurred")
58
+ );
59
+ return {
60
+ name: apiError.name || "api_error",
61
+ detail,
62
+ id: apiError.id
63
+ };
64
+ }
65
+ function enhanceRateLimitMessage(detail) {
66
+ return `${detail}
67
+
68
+ YNAB API limit: 200 requests/hour (rolling window). Wait a few minutes and retry.`;
69
+ }
70
+ function formatErrorResponse(name, detail, statusCode) {
71
+ const enhancedDetail = name === "too_many_requests" ? enhanceRateLimitMessage(detail) : detail;
72
+ outputJson({ error: { name, detail: enhancedDetail, statusCode } });
73
+ process.exit(1);
74
+ }
75
+ function handleYnabError(error) {
76
+ if (!isErrorObject(error)) {
77
+ formatErrorResponse("unknown_error", "An unexpected error occurred", 1);
78
+ }
79
+ const errorObj = error;
80
+ if (errorObj.error) {
81
+ const ynabError = sanitizeApiError(errorObj.error);
82
+ formatErrorResponse(
83
+ ynabError.name,
84
+ ynabError.detail,
85
+ ERROR_STATUS_CODES[ynabError.name] || 500
86
+ );
87
+ }
88
+ if (error instanceof YnabCliError) {
89
+ const sanitized2 = sanitizeErrorMessage(error.message);
90
+ formatErrorResponse("cli_error", sanitized2, error.statusCode || 1);
91
+ }
92
+ const sanitized = sanitizeErrorMessage(errorObj.message || "An unexpected error occurred");
93
+ formatErrorResponse("unknown_error", sanitized, 1);
94
+ }
95
+
96
+ // src/lib/utils.ts
8
97
  function milliunitsToAmount(milliunits) {
9
98
  return milliunits / 1e3;
10
99
  }
@@ -64,7 +153,7 @@ function isDebtAmountMapField(fieldName) {
64
153
  function parseApprovedFilter(value) {
65
154
  const normalized = value.toLowerCase();
66
155
  if (normalized !== "true" && normalized !== "false") {
67
- throw new Error(`--approved must be 'true' or 'false', got '${value}'`);
156
+ throw new YnabCliError(`--approved must be 'true' or 'false', got '${value}'`, 400);
68
157
  }
69
158
  return normalized === "true";
70
159
  }
@@ -73,7 +162,7 @@ function parseStatusFilter(value) {
73
162
  const validStatuses = ["cleared", "uncleared", "reconciled"];
74
163
  for (const status of statuses) {
75
164
  if (!validStatuses.includes(status)) {
76
- throw new Error(`Invalid status '${status}'. Must be one of: ${validStatuses.join(", ")}`);
165
+ throw new YnabCliError(`Invalid status '${status}'. Must be one of: ${validStatuses.join(", ")}`, 400);
77
166
  }
78
167
  }
79
168
  return statuses;
@@ -222,7 +311,7 @@ async function promptForAccessToken() {
222
311
  validate: (input) => !!input.trim() || "Access token is required"
223
312
  }
224
313
  ]);
225
- return token;
314
+ return token.trim();
226
315
  }
227
316
  async function promptForConfirmation(message) {
228
317
  const { confirmed } = await inquirer.prompt([
@@ -270,100 +359,15 @@ async function promptForTransaction() {
270
359
 
271
360
  // src/lib/api-client.ts
272
361
  import * as ynab from "ynab";
273
-
274
- // src/lib/errors.ts
275
- var YnabCliError = class extends Error {
276
- constructor(message, statusCode) {
277
- super(message);
278
- this.statusCode = statusCode;
279
- this.name = "YnabCliError";
280
- }
281
- };
282
- var ERROR_STATUS_CODES = {
283
- bad_request: 400,
284
- not_authorized: 401,
285
- subscription_lapsed: 403,
286
- trial_expired: 403,
287
- unauthorized_scope: 403,
288
- data_limit_reached: 403,
289
- not_found: 404,
290
- resource_not_found: 404,
291
- conflict: 409,
292
- too_many_requests: 429,
293
- internal_server_error: 500,
294
- service_unavailable: 503
295
- };
296
- function sanitizeErrorMessage(message) {
297
- const sensitivePatterns = [
298
- /Bearer\s+[\w\-._~+/]+=*/gi,
299
- /token[=:]\s*[\w\-._~+/]+=*/gi,
300
- /api[_-]?key[=:]\s*[\w\-._~+/]+=*/gi,
301
- /authorization:\s*bearer\s+[\w\-._~+/]+=*/gi
302
- ];
303
- let sanitized = message;
304
- for (const pattern of sensitivePatterns) {
305
- sanitized = sanitized.replace(pattern, "[REDACTED]");
306
- }
307
- return sanitized.length > 500 ? sanitized.substring(0, 500) + "..." : sanitized;
308
- }
309
- function isErrorObject(value) {
310
- return typeof value === "object" && value !== null;
311
- }
312
- function sanitizeApiError(error) {
313
- if (!isErrorObject(error)) {
314
- return {
315
- name: "api_error",
316
- detail: "An error occurred",
317
- id: void 0
318
- };
319
- }
320
- const apiError = error;
321
- const detail = sanitizeErrorMessage(
322
- String(apiError.detail || apiError.message || "An error occurred")
323
- );
324
- return {
325
- name: apiError.name || "api_error",
326
- detail,
327
- id: apiError.id
328
- };
329
- }
330
- function enhanceRateLimitMessage(detail) {
331
- return `${detail}
332
-
333
- YNAB API limit: 200 requests/hour (rolling window). Wait a few minutes and retry.`;
334
- }
335
- function formatErrorResponse(name, detail, statusCode) {
336
- const enhancedDetail = name === "too_many_requests" ? enhanceRateLimitMessage(detail) : detail;
337
- outputJson({ error: { name, detail: enhancedDetail, statusCode } });
338
- process.exit(1);
339
- }
340
- function handleYnabError(error) {
341
- if (!isErrorObject(error)) {
342
- formatErrorResponse("unknown_error", "An unexpected error occurred", 1);
343
- }
344
- const errorObj = error;
345
- if (errorObj.error) {
346
- const ynabError = sanitizeApiError(errorObj.error);
347
- formatErrorResponse(
348
- ynabError.name,
349
- ynabError.detail,
350
- ERROR_STATUS_CODES[ynabError.name] || 500
351
- );
352
- }
353
- if (error instanceof YnabCliError) {
354
- const sanitized2 = sanitizeErrorMessage(error.message);
355
- formatErrorResponse("cli_error", sanitized2, error.statusCode || 1);
356
- }
357
- const sanitized = sanitizeErrorMessage(errorObj.message || "An unexpected error occurred");
358
- formatErrorResponse("unknown_error", sanitized, 1);
359
- }
360
-
361
- // src/lib/api-client.ts
362
362
  import dotenv from "dotenv";
363
363
  dotenv.config();
364
364
  var YnabClient = class {
365
365
  api = null;
366
366
  envVarWarningShown = false;
367
+ clearApi() {
368
+ this.api = null;
369
+ this.envVarWarningShown = false;
370
+ }
367
371
  async getApi() {
368
372
  if (this.api) {
369
373
  return this.api;
@@ -830,6 +834,7 @@ function createAuthCommand() {
830
834
  cmd.command("login").description("Configure access token").action(withErrorHandling(async () => {
831
835
  const token = await promptForAccessToken();
832
836
  await auth.setAccessToken(token);
837
+ client.clearApi();
833
838
  try {
834
839
  const user = await client.getUser();
835
840
  outputJson({
@@ -838,6 +843,7 @@ function createAuthCommand() {
838
843
  });
839
844
  } catch (error) {
840
845
  await auth.deleteAccessToken();
846
+ client.clearApi();
841
847
  throw error;
842
848
  }
843
849
  }));
@@ -856,6 +862,7 @@ function createAuthCommand() {
856
862
  }));
857
863
  cmd.command("logout").description("Remove stored credentials").action(withErrorHandling(async () => {
858
864
  await auth.logout();
865
+ client.clearApi();
859
866
  outputJson({ message: "Successfully logged out" });
860
867
  }));
861
868
  return cmd;
@@ -1034,8 +1041,11 @@ function createTransactionsCommand() {
1034
1041
  outputJson(transaction);
1035
1042
  }));
1036
1043
  cmd.command("create").description("Create transaction").option("-b, --budget <id>", "Budget ID").option("--account <id>", "Account ID").option("--date <date>", "Date (YYYY-MM-DD)").option("--amount <amount>", "Amount in currency units (e.g., 10.50)", parseFloat).option("--payee-name <name>", "Payee name").option("--payee-id <id>", "Payee ID").option("--category-id <id>", "Category ID").option("--memo <memo>", "Memo").option("--cleared <status>", "Cleared status (cleared, uncleared, reconciled)").option("--approved", "Mark as approved").action(withErrorHandling(async (options) => {
1037
- const shouldPrompt = isInteractive() && !options.account && !options.amount;
1038
- const transactionData = shouldPrompt ? await promptForTransaction() : buildTransactionData(options);
1044
+ const shouldPrompt = isInteractive() && !options.amount;
1045
+ if (shouldPrompt && !options.account) {
1046
+ throw new YnabCliError("--account is required. Interactive mode cannot auto-select an account.", 400);
1047
+ }
1048
+ const transactionData = shouldPrompt ? { ...await promptForTransaction(), account_id: options.account } : buildTransactionData(options);
1039
1049
  const transaction = await client.createTransaction(
1040
1050
  { transaction: transactionData },
1041
1051
  options.budget
@@ -1275,7 +1285,7 @@ function createApiCommand() {
1275
1285
 
1276
1286
  // src/cli.ts
1277
1287
  var program = new Command11();
1278
- program.name("ynab").description("A command-line interface for You Need a Budget (YNAB)").version("1.2.2").option("-c, --compact", "Minified JSON output (single line)").hook("preAction", (thisCommand) => {
1288
+ program.name("ynab").description("A command-line interface for You Need a Budget (YNAB)").version("1.2.3").option("-c, --compact", "Minified JSON output (single line)").hook("preAction", (thisCommand) => {
1279
1289
  const options = thisCommand.opts();
1280
1290
  setOutputOptions({
1281
1291
  compact: options.compact
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/lib/utils.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/lib/prompts.ts","../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/command-utils.ts","../src/commands/user.ts","../src/commands/budgets.ts","../src/commands/accounts.ts","../src/commands/categories.ts","../src/commands/transactions.ts","../src/lib/schemas.ts","../src/commands/scheduled.ts","../src/commands/payees.ts","../src/commands/months.ts","../src/commands/api.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createAuthCommand } from './commands/auth.js';\nimport { createUserCommand } from './commands/user.js';\nimport { createBudgetsCommand } from './commands/budgets.js';\nimport { createAccountsCommand } from './commands/accounts.js';\nimport { createCategoriesCommand } from './commands/categories.js';\nimport { createTransactionsCommand } from './commands/transactions.js';\nimport { createScheduledCommand } from './commands/scheduled.js';\nimport { createPayeesCommand } from './commands/payees.js';\nimport { createMonthsCommand } from './commands/months.js';\nimport { createApiCommand } from './commands/api.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('ynab')\n .description('A command-line interface for You Need a Budget (YNAB)')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createAuthCommand());\nprogram.addCommand(createUserCommand());\nprogram.addCommand(createBudgetsCommand());\nprogram.addCommand(createAccountsCommand());\nprogram.addCommand(createCategoriesCommand());\nprogram.addCommand(createTransactionsCommand());\nprogram.addCommand(createScheduledCommand());\nprogram.addCommand(createPayeesCommand());\nprogram.addCommand(createMonthsCommand());\nprogram.addCommand(createApiCommand());\n\nprogram.parse();\n","import { format, parseISO } from 'date-fns';\n\nexport function milliunitsToAmount(milliunits: number): number {\n return milliunits / 1000;\n}\n\nexport function amountToMilliunits(amount: number): number {\n return Math.round(amount * 1000);\n}\n\nexport function formatCurrency(milliunits: number, currencySymbol = '$'): string {\n const amount = milliunitsToAmount(milliunits);\n return `${currencySymbol}${amount.toFixed(2)}`;\n}\n\nexport function formatDate(isoDate: string, formatString = 'yyyy-MM-dd'): string {\n return format(parseISO(isoDate), formatString);\n}\n\nexport function parseDate(dateString: string): string {\n const date = parseISO(dateString);\n return format(date, 'yyyy-MM-dd');\n}\n\nexport function isInteractive(): boolean {\n return process.stdin.isTTY === true;\n}\n\nexport function convertMilliunitsToAmounts(data: unknown): unknown {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) return data.map(convertMilliunitsToAmounts);\n if (typeof data !== 'object') return data;\n\n const converted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isAmountField(key) && typeof value === 'number') {\n converted[key] = milliunitsToAmount(value);\n } else if (isDebtAmountMapField(key) && typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const convertedMap: Record<string, unknown> = {};\n for (const [dateKey, amountValue] of Object.entries(value)) {\n convertedMap[dateKey] = typeof amountValue === 'number' ? milliunitsToAmount(amountValue) : amountValue;\n }\n converted[key] = convertedMap;\n } else {\n converted[key] = convertMilliunitsToAmounts(value);\n }\n }\n return converted;\n}\n\nfunction isAmountField(fieldName: string): boolean {\n const amountFields = [\n 'amount',\n 'balance',\n 'cleared_balance',\n 'uncleared_balance',\n 'budgeted',\n 'activity',\n 'available',\n 'goal_target',\n 'goal_under_funded',\n 'goal_overall_funded',\n 'goal_overall_left',\n 'income',\n 'to_be_budgeted',\n 'debt_original_balance',\n ];\n\n return amountFields.includes(fieldName) || fieldName.endsWith('_amount');\n}\n\nfunction isDebtAmountMapField(fieldName: string): boolean {\n const debtAmountMapFields = [\n 'debt_minimum_payments',\n 'debt_escrow_amounts',\n 'debt_interest_rates',\n ];\n\n return debtAmountMapFields.includes(fieldName);\n}\n\nexport function parseApprovedFilter(value: string): boolean {\n const normalized = value.toLowerCase();\n if (normalized !== 'true' && normalized !== 'false') {\n throw new Error(`--approved must be 'true' or 'false', got '${value}'`);\n }\n return normalized === 'true';\n}\n\nexport function parseStatusFilter(value: string): string[] {\n const statuses = value.split(',').map(s => s.trim().toLowerCase());\n const validStatuses = ['cleared', 'uncleared', 'reconciled'];\n\n for (const status of statuses) {\n if (!validStatuses.includes(status)) {\n throw new Error(`Invalid status '${status}'. Must be one of: ${validStatuses.join(', ')}`);\n }\n }\n\n return statuses;\n}\n\nexport type TransactionLike = {\n date: string;\n amount: number;\n approved: boolean;\n cleared: string;\n};\n\nexport function applyTransactionFilters<T extends TransactionLike>(transactions: T[], filters: {\n until?: string;\n approved?: string;\n status?: string;\n minAmount?: number;\n maxAmount?: number;\n}): T[] {\n let filtered = transactions;\n\n if (filters.until) {\n filtered = filtered.filter(t => t.date <= filters.until!);\n }\n\n if (filters.approved !== undefined) {\n const approvedValue = parseApprovedFilter(filters.approved);\n filtered = filtered.filter(t => t.approved === approvedValue);\n }\n\n if (filters.status) {\n const statuses = parseStatusFilter(filters.status);\n filtered = filtered.filter(t => statuses.includes(t.cleared.toLowerCase()));\n }\n\n if (filters.minAmount !== undefined) {\n const minMilliunits = amountToMilliunits(filters.minAmount);\n filtered = filtered.filter(t => t.amount >= minMilliunits);\n }\n\n if (filters.maxAmount !== undefined) {\n const maxMilliunits = amountToMilliunits(filters.maxAmount);\n filtered = filtered.filter(t => t.amount <= maxMilliunits);\n }\n\n return filtered;\n}\n\nexport function applyFieldSelection<T>(items: T[], fields?: string): Partial<T>[] {\n if (!fields) return items;\n\n const fieldList = fields.split(',').map(f => f.trim());\n return items.map(item => {\n const filtered: Partial<T> = {};\n const itemRecord = item as Record<string, unknown>;\n fieldList.forEach(field => {\n if (field in itemRecord) {\n (filtered as Record<string, unknown>)[field] = itemRecord[field];\n }\n });\n return filtered;\n });\n}\n","import type { OutputOptions } from '../types/index.js';\nimport { convertMilliunitsToAmounts } from './utils.js';\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const convertedData = convertMilliunitsToAmounts(data);\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact\n ? JSON.stringify(convertedData)\n : JSON.stringify(convertedData, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { auth } from '../lib/auth.js';\nimport { promptForAccessToken } from '../lib/prompts.js';\nimport { outputJson } from '../lib/output.js';\nimport { client } from '../lib/api-client.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createAuthCommand(): Command {\n const cmd = new Command('auth').description('Authentication management');\n\n cmd\n .command('login')\n .description('Configure access token')\n .action(withErrorHandling(async () => {\n const token = await promptForAccessToken();\n await auth.setAccessToken(token);\n\n try {\n const user = await client.getUser();\n outputJson({\n message: 'Successfully authenticated',\n user: { id: user?.id },\n });\n } catch (error) {\n await auth.deleteAccessToken();\n throw error;\n }\n }));\n\n cmd\n .command('status')\n .description('Check authentication status')\n .action(withErrorHandling(async () => {\n const isAuthenticated = await auth.isAuthenticated();\n\n if (!isAuthenticated) {\n outputJson({ authenticated: false, message: 'Not authenticated' });\n return;\n }\n\n try {\n const user = await client.getUser();\n outputJson({ authenticated: true, user: { id: user?.id } });\n } catch (error) {\n outputJson({ authenticated: false, message: 'Token exists but is invalid' });\n }\n }));\n\n cmd\n .command('logout')\n .description('Remove stored credentials')\n .action(withErrorHandling(async () => {\n await auth.logout();\n outputJson({ message: 'Successfully logged out' });\n }));\n\n return cmd;\n}\n","import { Entry } from '@napi-rs/keyring';\nimport { config } from './config.js';\n\nconst SERVICE_NAME = 'ynab-cli';\nconst ACCOUNT_NAME = 'access-token';\n\nconst KEYRING_UNAVAILABLE_ERROR =\n 'Keychain storage unavailable. Cannot store credentials securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'Then reinstall: npm install -g @stephendolan/ynab-cli\\n' +\n 'Alternatively, use the YNAB_API_KEY environment variable.';\n\nlet keyring: Entry | undefined;\n\ntry {\n keyring = new Entry(SERVICE_NAME, ACCOUNT_NAME);\n} catch (error) {\n if (process.env.NODE_ENV !== 'test') {\n console.error(\n 'Warning: Keychain storage unavailable. Credentials will not be stored securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'On macOS, ensure you have access to the system Keychain.\\n' +\n 'Falling back to environment variable only (YNAB_API_KEY).\\n'\n );\n }\n}\n\nexport class AuthManager {\n async getAccessToken(): Promise<string | null> {\n if (keyring) {\n try {\n return keyring.getPassword();\n } catch (error) {\n return null;\n }\n }\n return null;\n }\n\n async setAccessToken(token: string): Promise<void> {\n if (keyring) {\n keyring.setPassword(token);\n } else {\n throw new Error(KEYRING_UNAVAILABLE_ERROR);\n }\n }\n\n async deleteAccessToken(): Promise<boolean> {\n if (keyring) {\n return keyring.deletePassword();\n }\n return false;\n }\n\n async isAuthenticated(): Promise<boolean> {\n return (await this.getAccessToken()) !== null;\n }\n\n async logout(): Promise<void> {\n await this.deleteAccessToken();\n config.clearDefaultBudget();\n }\n}\n\nexport const auth = new AuthManager();\n","import Conf from 'conf';\nimport type { Config } from '../types/index.js';\n\nclass ConfigManager {\n private conf: Conf<Config>;\n\n constructor() {\n this.conf = new Conf<Config>({\n projectName: 'ynab-cli',\n schema: {\n defaultBudget: { type: 'string' },\n version: { type: 'string', default: '1.0.0' },\n },\n defaults: { version: '1.0.0' },\n });\n }\n\n getDefaultBudget(): string | undefined {\n return this.conf.get('defaultBudget');\n }\n\n setDefaultBudget(budgetId: string): void {\n this.conf.set('defaultBudget', budgetId);\n }\n\n clearDefaultBudget(): void {\n this.conf.delete('defaultBudget');\n }\n\n clear(): void {\n this.conf.clear();\n }\n}\n\nexport const config = new ConfigManager();\n","import inquirer from 'inquirer';\nimport { amountToMilliunits } from './utils.js';\n\nexport async function promptForAccessToken(): Promise<string> {\n const { token } = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: 'Enter your YNAB Personal Access Token:',\n validate: (input: string) => !!input.trim() || 'Access token is required',\n },\n ]);\n return token;\n}\n\nexport async function promptForBudget(\n budgets: Array<{ id: string; name: string }>,\n): Promise<string> {\n const { budgetId } = await inquirer.prompt([\n {\n type: 'list',\n name: 'budgetId',\n message: 'Select a budget:',\n choices: budgets.map((b) => ({ name: b.name, value: b.id })),\n },\n ]);\n return budgetId;\n}\n\nexport async function promptForConfirmation(message: string): Promise<boolean> {\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message,\n default: false,\n },\n ]);\n return confirmed;\n}\n\nexport async function promptForTransaction(): Promise<Record<string, unknown>> {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'date',\n message: 'Date (YYYY-MM-DD):',\n default: new Date().toISOString().split('T')[0],\n },\n {\n type: 'input',\n name: 'amount',\n message: 'Amount (in currency units, e.g., 10.50):',\n validate: (input: string) => !isNaN(parseFloat(input)) || 'Amount must be a valid number',\n },\n {\n type: 'input',\n name: 'payee_name',\n message: 'Payee name (optional):',\n },\n {\n type: 'input',\n name: 'memo',\n message: 'Memo (optional):',\n },\n ]);\n\n return {\n date: answers.date,\n amount: amountToMilliunits(parseFloat(answers.amount)),\n payee_name: answers.payee_name || undefined,\n memo: answers.memo || undefined,\n };\n}\n","import * as ynab from 'ynab';\nimport { config } from './config.js';\nimport { YnabCliError, handleYnabError, sanitizeApiError } from './errors.js';\nimport { auth } from './auth.js';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\ntype TransactionTypeFilter = 'uncategorized' | 'unapproved' | undefined;\n\nexport class YnabClient {\n private api: ynab.API | null = null;\n private envVarWarningShown = false;\n\n async getApi(): Promise<ynab.API> {\n if (this.api) {\n return this.api;\n }\n\n const keychainToken = await auth.getAccessToken();\n const accessToken = keychainToken || process.env.YNAB_API_KEY || null;\n\n if (!accessToken) {\n throw new YnabCliError(\n 'Not authenticated. Please run: ynab auth login or set YNAB_API_KEY environment variable',\n 401,\n );\n }\n\n if (!keychainToken && process.env.YNAB_API_KEY && !this.envVarWarningShown) {\n console.warn(\n '\\x1b[33m⚠️ WARNING: Using YNAB_API_KEY environment variable.\\n' +\n 'Environment variables may be visible to other processes.\\n' +\n 'For better security, use: ynab auth login\\x1b[0m\\n'\n );\n this.envVarWarningShown = true;\n }\n\n this.api = new ynab.API(accessToken);\n return this.api;\n }\n\n async getBudgetId(budgetIdOrDefault?: string): Promise<string> {\n const budgetId =\n budgetIdOrDefault || config.getDefaultBudget() || process.env.YNAB_BUDGET_ID;\n\n if (!budgetId) {\n throw new YnabCliError(\n 'No budget specified. Use --budget flag, set default with \"ynab budgets set-default\", or set YNAB_BUDGET_ID environment variable',\n 400,\n );\n }\n\n return budgetId;\n }\n\n private async withErrorHandling<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n handleYnabError(error);\n }\n }\n\n async getUser() {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const response = await api.user.getUser();\n return response.data.user;\n });\n }\n\n async getBudgets(includeAccounts = false) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const response = await api.budgets.getBudgets(includeAccounts);\n return {\n budgets: response.data.budgets,\n server_knowledge: 0,\n };\n });\n }\n\n async getBudget(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.budgets.getBudgetById(id, lastKnowledgeOfServer);\n return {\n budget: response.data.budget,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getBudgetSettings(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.budgets.getBudgetSettingsById(id);\n return response.data.settings;\n });\n }\n\n async getAccounts(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.getAccounts(id, lastKnowledgeOfServer);\n return {\n accounts: response.data.accounts,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getAccount(accountId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.getAccountById(id, accountId);\n return response.data.account;\n });\n }\n\n async createAccount(accountData: ynab.PostAccountWrapper, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.createAccount(id, accountData);\n return response.data.account;\n });\n }\n\n async getCategories(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getCategories(id, lastKnowledgeOfServer);\n return {\n category_groups: response.data.category_groups,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getCategory(categoryId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getCategoryById(id, categoryId);\n return response.data.category;\n });\n }\n\n async updateCategory(\n categoryId: string,\n data: ynab.PatchCategoryWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.updateCategory(id, categoryId, data);\n return response.data.category;\n });\n }\n\n async getMonthCategory(month: string, categoryId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getMonthCategoryById(id, month, categoryId);\n return response.data.category;\n });\n }\n\n async updateMonthCategory(\n month: string,\n categoryId: string,\n data: ynab.PatchMonthCategoryWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.updateMonthCategory(id, month, categoryId, data);\n return response.data.category;\n });\n }\n\n async getPayees(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.getPayees(id, lastKnowledgeOfServer);\n return {\n payees: response.data.payees,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getPayee(payeeId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.getPayeeById(id, payeeId);\n return response.data.payee;\n });\n }\n\n async updatePayee(payeeId: string, data: ynab.PatchPayeeWrapper, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.updatePayee(id, payeeId, data);\n return response.data.payee;\n });\n }\n\n async getPayeeLocations(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocations(id);\n return response.data.payee_locations;\n });\n }\n\n async getPayeeLocation(payeeLocationId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocationById(id, payeeLocationId);\n return response.data.payee_location;\n });\n }\n\n async getPayeeLocationsByPayee(payeeId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocationsByPayee(id, payeeId);\n return response.data.payee_locations;\n });\n }\n\n async getBudgetMonths(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.months.getBudgetMonths(id, lastKnowledgeOfServer);\n return {\n months: response.data.months,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getBudgetMonth(month: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.months.getBudgetMonth(id, month);\n return response.data.month;\n });\n }\n\n async getTransactions(params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactions(\n id,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByAccount(accountId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByAccount(\n id,\n accountId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByCategory(categoryId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByCategory(\n id,\n categoryId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByPayee(payeeId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByPayee(\n id,\n payeeId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransaction(transactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.getTransactionById(id, transactionId);\n return response.data.transaction;\n });\n }\n\n async createTransaction(\n transactionData: ynab.PostTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.createTransaction(id, transactionData);\n return response.data.transaction;\n });\n }\n\n async createTransactions(\n transactionsData: ynab.PostTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.createTransactions(id, transactionsData);\n return response.data;\n });\n }\n\n async updateTransaction(\n transactionId: string,\n transactionData: ynab.PutTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.updateTransaction(\n id,\n transactionId,\n transactionData,\n );\n return response.data.transaction;\n });\n }\n\n async updateTransactions(\n transactionsData: ynab.PatchTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.updateTransactions(id, transactionsData);\n return response.data;\n });\n }\n\n async deleteTransaction(transactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.deleteTransaction(id, transactionId);\n return response.data.transaction;\n });\n }\n\n async importTransactions(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.importTransactions(id);\n return response.data.transaction_ids;\n });\n }\n\n async getScheduledTransactions(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.getScheduledTransactions(\n id,\n lastKnowledgeOfServer,\n );\n return {\n scheduled_transactions: response.data.scheduled_transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getScheduledTransaction(scheduledTransactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.getScheduledTransactionById(\n id,\n scheduledTransactionId,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async createScheduledTransaction(\n data: ynab.PostScheduledTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.createScheduledTransaction(id, data);\n return response.data.scheduled_transaction;\n });\n }\n\n async updateScheduledTransaction(\n scheduledTransactionId: string,\n data: ynab.PutScheduledTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.updateScheduledTransaction(\n id,\n scheduledTransactionId,\n data,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async deleteScheduledTransaction(scheduledTransactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.deleteScheduledTransaction(\n id,\n scheduledTransactionId,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async rawApiCall(method: string, path: string, data?: unknown, budgetId?: string) {\n return this.withErrorHandling(async () => {\n await this.getApi();\n\n const fullPath = path.includes('{budget_id}')\n ? path.replace('{budget_id}', await this.getBudgetId(budgetId))\n : path;\n\n const url = `https://api.ynab.com/v1${fullPath}`;\n const headers = {\n Authorization: `Bearer ${await auth.getAccessToken()}`,\n 'Content-Type': 'application/json',\n };\n\n const httpMethod = method.toUpperCase();\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(httpMethod);\n\n if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(httpMethod)) {\n throw new YnabCliError(`Unsupported HTTP method: ${method}`, 400);\n }\n\n const response = await fetch(url, {\n method: httpMethod,\n headers,\n ...(hasBody && { body: JSON.stringify(data) }),\n });\n\n if (!response.ok) {\n const errorData = await response.json() as Record<string, unknown>;\n throw { error: sanitizeApiError(errorData.error || errorData) };\n }\n\n return await response.json();\n });\n }\n}\n\nexport const client = new YnabClient();\n","import type { YnabError } from '../types/index.js';\nimport { outputJson } from './output.js';\n\nexport class YnabCliError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = 'YnabCliError';\n }\n}\n\nconst ERROR_STATUS_CODES: Record<string, number> = {\n bad_request: 400,\n not_authorized: 401,\n subscription_lapsed: 403,\n trial_expired: 403,\n unauthorized_scope: 403,\n data_limit_reached: 403,\n not_found: 404,\n resource_not_found: 404,\n conflict: 409,\n too_many_requests: 429,\n internal_server_error: 500,\n service_unavailable: 503,\n};\n\nexport function sanitizeErrorMessage(message: string): string {\n const sensitivePatterns = [\n /Bearer\\s+[\\w\\-._~+/]+=*/gi,\n /token[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /api[_-]?key[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /authorization:\\s*bearer\\s+[\\w\\-._~+/]+=*/gi,\n ];\n\n let sanitized = message;\n for (const pattern of sensitivePatterns) {\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n\n return sanitized.length > 500 ? sanitized.substring(0, 500) + '...' : sanitized;\n}\n\ninterface YnabApiError {\n name?: string;\n detail?: string;\n message?: string;\n id?: string;\n}\n\nfunction isErrorObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sanitizeApiError(error: unknown): YnabError {\n if (!isErrorObject(error)) {\n return {\n name: 'api_error',\n detail: 'An error occurred',\n id: undefined,\n };\n }\n\n const apiError = error as YnabApiError;\n const detail = sanitizeErrorMessage(\n String(apiError.detail || apiError.message || 'An error occurred')\n );\n\n return {\n name: apiError.name || 'api_error',\n detail,\n id: apiError.id,\n };\n}\n\nfunction enhanceRateLimitMessage(detail: string): string {\n return `${detail}\\n\\nYNAB API limit: 200 requests/hour (rolling window). Wait a few minutes and retry.`;\n}\n\nfunction formatErrorResponse(name: string, detail: string, statusCode: number): never {\n const enhancedDetail = name === 'too_many_requests'\n ? enhanceRateLimitMessage(detail)\n : detail;\n\n outputJson({ error: { name, detail: enhancedDetail, statusCode } });\n process.exit(1);\n}\n\nexport function handleYnabError(error: unknown): never {\n if (!isErrorObject(error)) {\n formatErrorResponse('unknown_error', 'An unexpected error occurred', 1);\n }\n\n const errorObj = error as { error?: unknown; message?: string };\n\n if (errorObj.error) {\n const ynabError: YnabError = sanitizeApiError(errorObj.error);\n formatErrorResponse(\n ynabError.name,\n ynabError.detail,\n ERROR_STATUS_CODES[ynabError.name] || 500,\n );\n }\n\n if (error instanceof YnabCliError) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('cli_error', sanitized, error.statusCode || 1);\n }\n\n const sanitized = sanitizeErrorMessage(errorObj.message || 'An unexpected error occurred');\n formatErrorResponse('unknown_error', sanitized, 1);\n}\n","import { handleYnabError } from './errors.js';\nimport { promptForConfirmation } from './prompts.js';\nimport { isInteractive } from './utils.js';\nimport { outputJson } from './output.js';\n\nexport function withErrorHandling<TArgs extends unknown[], R>(\n fn: (...args: TArgs) => Promise<R>,\n): (...args: TArgs) => Promise<void> {\n return async (...args: TArgs) => {\n try {\n await fn(...args);\n } catch (error) {\n handleYnabError(error);\n }\n };\n}\n\nexport async function confirmDelete(\n itemType: string,\n skipConfirmation: boolean = false,\n): Promise<boolean> {\n if (skipConfirmation || !isInteractive()) {\n return true;\n }\n\n const confirmed = await promptForConfirmation(\n `Are you sure you want to delete this ${itemType}?`,\n );\n\n if (!confirmed) {\n outputJson({ message: 'Operation cancelled' });\n return false;\n }\n\n return true;\n}\n\nexport function buildUpdateObject<T>(\n options: T,\n mapping: Record<string, string>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const optionsRecord = options as Record<string, unknown>;\n\n for (const [optionKey, targetKey] of Object.entries(mapping)) {\n if (optionsRecord[optionKey] !== undefined) {\n result[targetKey] = optionsRecord[optionKey];\n }\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createUserCommand(): Command {\n const cmd = new Command('user').description('User information');\n\n cmd\n .command('info')\n .description('Get authenticated user information')\n .action(withErrorHandling(async () => {\n const user = await client.getUser();\n outputJson(user);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { config } from '../lib/config.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createBudgetsCommand(): Command {\n const cmd = new Command('budgets').description('Budget operations');\n\n cmd\n .command('list')\n .description('List all budgets')\n .option('--include-accounts', 'Include accounts in response')\n .action(withErrorHandling(async (options: { includeAccounts?: boolean }) => {\n const result = await client.getBudgets(options.includeAccounts);\n outputJson(result?.budgets);\n }));\n\n cmd\n .command('view')\n .description('View budget details (uses default if no id provided)')\n .argument('[id]', 'Budget ID')\n .action(withErrorHandling(async (id: string | undefined) => {\n const result = await client.getBudget(id);\n outputJson(result?.budget);\n }));\n\n cmd\n .command('settings')\n .description('View budget settings')\n .argument('[id]', 'Budget ID')\n .action(withErrorHandling(async (id: string | undefined) => {\n const settings = await client.getBudgetSettings(id);\n outputJson(settings);\n }));\n\n cmd\n .command('set-default')\n .description('Set default budget for commands')\n .argument('<id>', 'Budget ID')\n .action(withErrorHandling(async (id: string) => {\n const result = await client.getBudgets();\n const budget = result?.budgets.find((b) => b.id === id);\n\n if (!budget) {\n throw new YnabCliError(`Budget with ID ${id} not found`, 404);\n }\n\n config.setDefaultBudget(id);\n outputJson({\n message: 'Default budget set',\n budget: { id: budget.id, name: budget.name },\n });\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createAccountsCommand(): Command {\n const cmd = new Command('accounts').description('Account operations');\n\n cmd\n .command('list')\n .description('List all accounts')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (options: CommandOptions) => {\n const result = await client.getAccounts(options.budget);\n outputJson(result?.accounts);\n }));\n\n cmd\n .command('view')\n .description('View account details')\n .argument('<id>', 'Account ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const account = await client.getAccount(id, options.budget);\n outputJson(account);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for account')\n .argument('<id>', 'Account ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByAccount(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { amountToMilliunits } from '../lib/utils.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createCategoriesCommand(): Command {\n const cmd = new Command('categories').description('Category operations');\n\n cmd\n .command('list')\n .description('List all categories')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getCategories(options.budget, options.lastKnowledge);\n outputJson(result?.category_groups);\n }));\n\n cmd\n .command('view')\n .description('View category details')\n .argument('<id>', 'Category ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const category = await client.getCategory(id, options.budget);\n outputJson(category);\n }));\n\n cmd\n .command('budget')\n .description('Set category budgeted amount for a month (overrides existing amount)')\n .argument('<id>', 'Category ID')\n .requiredOption('--month <month>', 'Month in YYYY-MM-DD format (e.g., 2025-07-01)')\n .requiredOption('--amount <amount>', 'Total budgeted amount to set (e.g., 100.50)', parseFloat)\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (\n id: string,\n options: {\n month: string;\n amount: number;\n budget?: string;\n } & CommandOptions,\n ) => {\n if (isNaN(options.amount)) {\n throw new YnabCliError('Amount must be a valid number', 400);\n }\n\n const milliunits = amountToMilliunits(options.amount);\n const category = await client.updateMonthCategory(\n options.month,\n id,\n { category: { budgeted: milliunits } },\n options.budget,\n );\n outputJson(category);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for category')\n .argument('<id>', 'Category ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n lastKnowledge?: number;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByCategory(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n lastKnowledgeOfServer: options.lastKnowledge,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { promptForTransaction } from '../lib/prompts.js';\nimport { isInteractive, amountToMilliunits, applyTransactionFilters, applyFieldSelection, type TransactionLike } from '../lib/utils.js';\nimport { withErrorHandling, confirmDelete, buildUpdateObject } from '../lib/command-utils.js';\nimport { validateJson, TransactionSplitSchema } from '../lib/schemas.js';\nimport type { CommandOptions } from '../types/index.js';\n\ninterface TransactionOptions {\n account?: string;\n date?: string;\n amount?: number;\n payeeName?: string;\n payeeId?: string;\n categoryId?: string;\n memo?: string;\n cleared?: string;\n approved?: boolean;\n}\n\nfunction buildTransactionData(options: TransactionOptions): Record<string, unknown> {\n if (!options.account) {\n throw new YnabCliError('--account is required in non-interactive mode', 400);\n }\n if (options.amount === undefined) {\n throw new YnabCliError('--amount is required in non-interactive mode', 400);\n }\n\n return {\n account_id: options.account,\n date: options.date || new Date().toISOString().split('T')[0],\n amount: amountToMilliunits(options.amount),\n payee_name: options.payeeName,\n payee_id: options.payeeId,\n category_id: options.categoryId,\n memo: options.memo,\n cleared: options.cleared,\n approved: options.approved,\n };\n}\n\nexport function createTransactionsCommand(): Command {\n const cmd = new Command('transactions').description('Transaction operations');\n\n cmd\n .command('list')\n .description('List transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Filter by account ID')\n .option('--category <id>', 'Filter by category ID')\n .option('--payee <id>', 'Filter by payee ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--until <date>', 'Filter transactions until date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--approved <value>', 'Filter by approval status: true or false')\n .option('--status <statuses>', 'Filter by cleared status: cleared, uncleared, reconciled (comma-separated for multiple)')\n .option('--min-amount <amount>', 'Minimum amount in currency units (e.g., 10.50)', parseFloat)\n .option('--max-amount <amount>', 'Maximum amount in currency units (e.g., 100.00)', parseFloat)\n .option('--fields <fields>', 'Comma-separated list of fields to include (e.g., id,date,amount,memo)')\n .action(withErrorHandling(async (options: {\n budget?: string;\n account?: string;\n category?: string;\n payee?: string;\n since?: string;\n until?: string;\n type?: string;\n approved?: string;\n status?: string;\n minAmount?: number;\n maxAmount?: number;\n fields?: string;\n } & CommandOptions) => {\n const params = {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n };\n\n const result = options.account\n ? await client.getTransactionsByAccount(options.account, params)\n : options.category\n ? await client.getTransactionsByCategory(options.category, params)\n : options.payee\n ? await client.getTransactionsByPayee(options.payee, params)\n : await client.getTransactions(params);\n\n const transactions = result?.transactions || [];\n\n const filtered = applyTransactionFilters(transactions as TransactionLike[], {\n until: options.until,\n approved: options.approved,\n status: options.status,\n minAmount: options.minAmount,\n maxAmount: options.maxAmount,\n });\n\n const selected = applyFieldSelection(filtered, options.fields);\n\n outputJson(selected);\n }));\n\n cmd\n .command('view')\n .description('View single transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const transaction = await client.getTransaction(id, options.budget);\n outputJson(transaction);\n }));\n\n cmd\n .command('create')\n .description('Create transaction')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Account ID')\n .option('--date <date>', 'Date (YYYY-MM-DD)')\n .option('--amount <amount>', 'Amount in currency units (e.g., 10.50)', parseFloat)\n .option('--payee-name <name>', 'Payee name')\n .option('--payee-id <id>', 'Payee ID')\n .option('--category-id <id>', 'Category ID')\n .option('--memo <memo>', 'Memo')\n .option('--cleared <status>', 'Cleared status (cleared, uncleared, reconciled)')\n .option('--approved', 'Mark as approved')\n .action(withErrorHandling(async (options: {\n budget?: string;\n account?: string;\n date?: string;\n amount?: number;\n payeeName?: string;\n payeeId?: string;\n categoryId?: string;\n memo?: string;\n cleared?: string;\n approved?: boolean;\n } & CommandOptions) => {\n const shouldPrompt = isInteractive() && !options.account && !options.amount;\n const transactionData = shouldPrompt\n ? await promptForTransaction()\n : buildTransactionData(options);\n\n const transaction = await client.createTransaction(\n { transaction: transactionData },\n options.budget,\n );\n outputJson(transaction);\n }));\n\n cmd\n .command('update')\n .description('Update transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Account ID')\n .option('--date <date>', 'Date (YYYY-MM-DD)')\n .option('--amount <amount>', 'Amount in currency units', parseFloat)\n .option('--payee-name <name>', 'Payee name')\n .option('--payee-id <id>', 'Payee ID')\n .option('--category-id <id>', 'Category ID')\n .option('--memo <memo>', 'Memo')\n .option('--cleared <status>', 'Cleared status')\n .option('--approved', 'Mark as approved')\n .action(withErrorHandling(async (\n id: string,\n options: TransactionOptions & { budget?: string } & CommandOptions,\n ) => {\n const transactionData = buildUpdateObject(options, {\n account: 'account_id',\n date: 'date',\n payeeName: 'payee_name',\n payeeId: 'payee_id',\n categoryId: 'category_id',\n memo: 'memo',\n cleared: 'cleared',\n approved: 'approved',\n });\n\n if (options.amount !== undefined) {\n transactionData.amount = amountToMilliunits(options.amount);\n }\n\n const transaction = await client.updateTransaction(\n id,\n { transaction: transactionData },\n options.budget,\n );\n outputJson(transaction);\n }));\n\n cmd\n .command('delete')\n .description('Delete transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(withErrorHandling(async (id: string, options: { budget?: string; yes?: boolean } & CommandOptions) => {\n if (!await confirmDelete('transaction', options.yes)) {\n return;\n }\n\n const transaction = await client.deleteTransaction(id, options.budget);\n outputJson({ message: 'Transaction deleted', transaction });\n }));\n\n cmd\n .command('import')\n .description('Import transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (options: CommandOptions) => {\n const transactionIds = await client.importTransactions(options.budget);\n outputJson({ transaction_ids: transactionIds });\n }));\n\n cmd\n .command('split')\n .description('Split transaction into multiple categories. Amounts should be in dollars (e.g., 10.50).')\n .argument('<id>', 'Transaction ID')\n .requiredOption('--splits <json>', 'JSON array of splits with dollar amounts: [{\"amount\": -21.40, \"category_id\": \"xxx\", \"memo\": \"...\"}]')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-f, --force', 'Force update of already-split transactions by deleting and recreating')\n .action(withErrorHandling(async (\n id: string,\n options: { splits: string; budget?: string; force?: boolean } & CommandOptions,\n ) => {\n let parsedSplits;\n try {\n parsedSplits = JSON.parse(options.splits);\n } catch (error) {\n throw new YnabCliError('Invalid JSON in --splits parameter', 400);\n }\n\n const splits = validateJson(parsedSplits, TransactionSplitSchema, 'transaction splits');\n\n const splitsInMilliunits = splits.map(split => ({\n ...split,\n amount: amountToMilliunits(split.amount),\n }));\n\n const existingTransaction = await client.getTransaction(id, options.budget);\n const isAlreadySplit = existingTransaction.subtransactions && existingTransaction.subtransactions.length > 0;\n\n if (isAlreadySplit && !options.force) {\n throw new YnabCliError(\n 'Transaction is already split. YNAB API does not support updating split transactions. ' +\n 'Use --force to delete and recreate the transaction with new splits.',\n 400\n );\n }\n\n if (isAlreadySplit) {\n await client.deleteTransaction(id, options.budget);\n\n const recreatedTransaction = await client.createTransaction(\n {\n transaction: {\n account_id: existingTransaction.account_id,\n date: existingTransaction.date,\n amount: existingTransaction.amount,\n payee_id: existingTransaction.payee_id,\n payee_name: existingTransaction.payee_name,\n category_id: null,\n memo: existingTransaction.memo,\n cleared: existingTransaction.cleared,\n approved: existingTransaction.approved,\n flag_color: existingTransaction.flag_color,\n subtransactions: splitsInMilliunits,\n },\n },\n options.budget,\n );\n outputJson(recreatedTransaction);\n } else {\n const transaction = await client.updateTransaction(\n id,\n {\n transaction: {\n category_id: null,\n subtransactions: splitsInMilliunits,\n },\n },\n options.budget,\n );\n outputJson(transaction);\n }\n }));\n\n cmd\n .command('search')\n .description('Search transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--memo <text>', 'Search in memo field')\n .option('--payee-name <name>', 'Search in payee name')\n .option('--amount <amount>', 'Search for exact amount in currency units', parseFloat)\n .option('--since <date>', 'Search transactions since date (YYYY-MM-DD)')\n .option('--until <date>', 'Search transactions until date (YYYY-MM-DD)')\n .option('--approved <value>', 'Filter by approval status: true or false')\n .option('--status <statuses>', 'Filter by cleared status: cleared, uncleared, reconciled (comma-separated)')\n .option('--fields <fields>', 'Comma-separated list of fields to include')\n .action(withErrorHandling(async (options: {\n budget?: string;\n memo?: string;\n payeeName?: string;\n amount?: number;\n since?: string;\n until?: string;\n approved?: string;\n status?: string;\n fields?: string;\n } & CommandOptions) => {\n if (!options.memo && !options.payeeName && options.amount === undefined) {\n throw new YnabCliError('At least one search criteria required: --memo, --payee-name, or --amount', 400);\n }\n\n const params = {\n budgetId: options.budget,\n sinceDate: options.since,\n };\n\n const result = await client.getTransactions(params);\n let transactions = result?.transactions || [];\n\n if (options.memo) {\n const searchTerm = options.memo.toLowerCase();\n transactions = transactions.filter(t =>\n t.memo?.toLowerCase().includes(searchTerm)\n );\n }\n\n if (options.payeeName) {\n const searchTerm = options.payeeName.toLowerCase();\n transactions = transactions.filter(t =>\n t.payee_name?.toLowerCase().includes(searchTerm)\n );\n }\n\n if (options.amount !== undefined) {\n const amountMilliunits = amountToMilliunits(options.amount);\n transactions = transactions.filter(t => t.amount === amountMilliunits);\n }\n\n transactions = applyTransactionFilters(transactions, {\n until: options.until,\n approved: options.approved,\n status: options.status,\n });\n\n const filteredTransactions = applyFieldSelection(transactions, options.fields);\n\n outputJson(filteredTransactions);\n }));\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { YnabCliError } from './errors.js';\n\nexport const TransactionSplitSchema = z.array(\n z.object({\n amount: z.number(),\n category_id: z.string().nullable().optional(),\n memo: z.string().optional(),\n payee_id: z.string().optional(),\n })\n);\n\nexport const ApiDataSchema = z.record(z.any());\n\nexport function validateJson<T>(\n data: unknown,\n schema: z.ZodSchema<T>,\n fieldName: string\n): T {\n try {\n return schema.parse(data);\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues\n .map(i => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new YnabCliError(`Invalid ${fieldName}: ${issues}`, 400);\n }\n throw error;\n }\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, confirmDelete } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createScheduledCommand(): Command {\n const cmd = new Command('scheduled').description('Scheduled transaction operations');\n\n cmd\n .command('list')\n .description('List all scheduled transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getScheduledTransactions(options.budget, options.lastKnowledge);\n outputJson(result?.scheduled_transactions);\n }));\n\n cmd\n .command('view')\n .description('View scheduled transaction')\n .argument('<id>', 'Scheduled transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const scheduledTransaction = await client.getScheduledTransaction(id, options.budget);\n outputJson(scheduledTransaction);\n }));\n\n cmd\n .command('delete')\n .description('Delete scheduled transaction')\n .argument('<id>', 'Scheduled transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(withErrorHandling(async (id: string, options: { budget?: string; yes?: boolean } & CommandOptions) => {\n if (!await confirmDelete('scheduled transaction', options.yes)) {\n return;\n }\n\n const scheduledTransaction = await client.deleteScheduledTransaction(id, options.budget);\n outputJson({\n message: 'Scheduled transaction deleted',\n scheduled_transaction: scheduledTransaction,\n });\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createPayeesCommand(): Command {\n const cmd = new Command('payees').description('Payee operations');\n\n cmd\n .command('list')\n .description('List all payees')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getPayees(options.budget, options.lastKnowledge);\n outputJson(result?.payees);\n }));\n\n cmd\n .command('view')\n .description('View payee details')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const payee = await client.getPayee(id, options.budget);\n outputJson(payee);\n }));\n\n cmd\n .command('update')\n .description('Rename payee')\n .argument('<id>', 'Payee ID')\n .requiredOption('--name <name>', 'New payee name')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: { name: string; budget?: string } & CommandOptions) => {\n if (!options.name?.trim()) {\n throw new YnabCliError('Name cannot be empty', 400);\n }\n\n const payee = await client.updatePayee(\n id,\n { payee: { name: options.name } },\n options.budget,\n );\n outputJson(payee);\n }));\n\n cmd\n .command('locations')\n .description('List locations for payee')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const locations = await client.getPayeeLocationsByPayee(id, options.budget);\n outputJson(locations);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for payee')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n lastKnowledge?: number;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByPayee(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n lastKnowledgeOfServer: options.lastKnowledge,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createMonthsCommand(): Command {\n const cmd = new Command('months').description('Monthly budget operations');\n\n cmd\n .command('list')\n .description('List all budget months')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getBudgetMonths(options.budget, options.lastKnowledge);\n outputJson(result?.months);\n }));\n\n cmd\n .command('view')\n .description('View specific month details')\n .argument('<month>', 'Month in YYYY-MM-DD format (e.g., 2025-07-01)')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (month: string, options: CommandOptions) => {\n const monthData = await client.getBudgetMonth(month, options.budget);\n outputJson(monthData);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { validateJson, ApiDataSchema } from '../lib/schemas.js';\nimport type { CommandOptions } from '../types/index.js';\n\nconst VALID_HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\n\nexport function createApiCommand(): Command {\n const cmd = new Command('api').description('Raw API access');\n\n cmd\n .argument('<method>', 'HTTP method (GET, POST, PUT, PATCH, DELETE)')\n .argument('<path>', 'API path (e.g., /budgets or /budgets/{budget_id}/transactions)')\n .option('-b, --budget <id>', 'Budget ID (used to replace {budget_id} in path)')\n .option('--data <json>', 'JSON data for POST/PUT/PATCH requests')\n .description('Make raw API calls to YNAB')\n .action(withErrorHandling(async (\n method: string,\n path: string,\n options: { budget?: string; data?: string } & CommandOptions,\n ) => {\n const upperMethod = method.toUpperCase();\n\n if (!VALID_HTTP_METHODS.includes(upperMethod)) {\n throw new YnabCliError(\n `Invalid HTTP method: ${method}. Must be one of: ${VALID_HTTP_METHODS.join(', ')}`,\n 400,\n );\n }\n\n let data: Record<string, unknown> | undefined;\n if (options.data) {\n try {\n const parsedData = JSON.parse(options.data);\n data = validateJson(parsedData, ApiDataSchema, 'API data');\n } catch (error) {\n throw new YnabCliError('Invalid JSON in --data parameter', 400);\n }\n }\n\n const result = await client.rawApiCall(upperMethod, path, data, options.budget);\n outputJson(result);\n }));\n\n return cmd;\n}\n"],"mappings":";;;AAEA,SAAS,WAAAA,iBAAe;;;ACFxB,SAAS,QAAQ,gBAAgB;AAE1B,SAAS,mBAAmB,YAA4B;AAC7D,SAAO,aAAa;AACtB;AAEO,SAAS,mBAAmB,QAAwB;AACzD,SAAO,KAAK,MAAM,SAAS,GAAI;AACjC;AAgBO,SAAS,gBAAyB;AACvC,SAAO,QAAQ,MAAM,UAAU;AACjC;AAEO,SAAS,2BAA2B,MAAwB;AACjE,MAAI,SAAS,QAAQ,SAAS,OAAW,QAAO;AAChD,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,KAAK,IAAI,0BAA0B;AACnE,MAAI,OAAO,SAAS,SAAU,QAAO;AAErC,QAAM,YAAqC,CAAC;AAC5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,cAAc,GAAG,KAAK,OAAO,UAAU,UAAU;AACnD,gBAAU,GAAG,IAAI,mBAAmB,KAAK;AAAA,IAC3C,WAAW,qBAAqB,GAAG,KAAK,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC5G,YAAM,eAAwC,CAAC;AAC/C,iBAAW,CAAC,SAAS,WAAW,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1D,qBAAa,OAAO,IAAI,OAAO,gBAAgB,WAAW,mBAAmB,WAAW,IAAI;AAAA,MAC9F;AACA,gBAAU,GAAG,IAAI;AAAA,IACnB,OAAO;AACL,gBAAU,GAAG,IAAI,2BAA2B,KAAK;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,WAA4B;AACjD,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,aAAa,SAAS,SAAS,KAAK,UAAU,SAAS,SAAS;AACzE;AAEA,SAAS,qBAAqB,WAA4B;AACxD,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,oBAAoB,SAAS,SAAS;AAC/C;AAEO,SAAS,oBAAoB,OAAwB;AAC1D,QAAM,aAAa,MAAM,YAAY;AACrC,MAAI,eAAe,UAAU,eAAe,SAAS;AACnD,UAAM,IAAI,MAAM,8CAA8C,KAAK,GAAG;AAAA,EACxE;AACA,SAAO,eAAe;AACxB;AAEO,SAAS,kBAAkB,OAAyB;AACzD,QAAM,WAAW,MAAM,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,EAAE,YAAY,CAAC;AACjE,QAAM,gBAAgB,CAAC,WAAW,aAAa,YAAY;AAE3D,aAAW,UAAU,UAAU;AAC7B,QAAI,CAAC,cAAc,SAAS,MAAM,GAAG;AACnC,YAAM,IAAI,MAAM,mBAAmB,MAAM,sBAAsB,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,wBAAmD,cAAmB,SAM9E;AACN,MAAI,WAAW;AAEf,MAAI,QAAQ,OAAO;AACjB,eAAW,SAAS,OAAO,OAAK,EAAE,QAAQ,QAAQ,KAAM;AAAA,EAC1D;AAEA,MAAI,QAAQ,aAAa,QAAW;AAClC,UAAM,gBAAgB,oBAAoB,QAAQ,QAAQ;AAC1D,eAAW,SAAS,OAAO,OAAK,EAAE,aAAa,aAAa;AAAA,EAC9D;AAEA,MAAI,QAAQ,QAAQ;AAClB,UAAM,WAAW,kBAAkB,QAAQ,MAAM;AACjD,eAAW,SAAS,OAAO,OAAK,SAAS,SAAS,EAAE,QAAQ,YAAY,CAAC,CAAC;AAAA,EAC5E;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,UAAM,gBAAgB,mBAAmB,QAAQ,SAAS;AAC1D,eAAW,SAAS,OAAO,OAAK,EAAE,UAAU,aAAa;AAAA,EAC3D;AAEA,MAAI,QAAQ,cAAc,QAAW;AACnC,UAAM,gBAAgB,mBAAmB,QAAQ,SAAS;AAC1D,eAAW,SAAS,OAAO,OAAK,EAAE,UAAU,aAAa;AAAA,EAC3D;AAEA,SAAO;AACT;AAEO,SAAS,oBAAuB,OAAY,QAA+B;AAChF,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,YAAY,OAAO,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AACrD,SAAO,MAAM,IAAI,UAAQ;AACvB,UAAM,WAAuB,CAAC;AAC9B,UAAM,aAAa;AACnB,cAAU,QAAQ,WAAS;AACzB,UAAI,SAAS,YAAY;AACvB,QAAC,SAAqC,KAAK,IAAI,WAAW,KAAK;AAAA,MACjE;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,CAAC;AACH;;;AC5JA,IAAI,sBAAqC,CAAC;AAEnC,SAAS,iBAAiB,SAA8B;AAC7D,wBAAsB;AACxB;AAEO,SAAS,WAAW,MAAe,UAAyB,CAAC,GAAS;AAC3E,QAAM,gBAAgB,2BAA2B,IAAI;AACrD,QAAM,gBAAgB,EAAE,GAAG,qBAAqB,GAAG,QAAQ;AAC3D,QAAM,aAAa,cAAc,UAC7B,KAAK,UAAU,aAAa,IAC5B,KAAK,UAAU,eAAe,MAAM,CAAC;AAEzC,UAAQ,IAAI,UAAU;AACxB;;;ACjBA,SAAS,eAAe;;;ACAxB,SAAS,aAAa;;;ACAtB,OAAO,UAAU;AAGjB,IAAM,gBAAN,MAAoB;AAAA,EACV;AAAA,EAER,cAAc;AACZ,SAAK,OAAO,IAAI,KAAa;AAAA,MAC3B,aAAa;AAAA,MACb,QAAQ;AAAA,QACN,eAAe,EAAE,MAAM,SAAS;AAAA,QAChC,SAAS,EAAE,MAAM,UAAU,SAAS,QAAQ;AAAA,MAC9C;AAAA,MACA,UAAU,EAAE,SAAS,QAAQ;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,mBAAuC;AACrC,WAAO,KAAK,KAAK,IAAI,eAAe;AAAA,EACtC;AAAA,EAEA,iBAAiB,UAAwB;AACvC,SAAK,KAAK,IAAI,iBAAiB,QAAQ;AAAA,EACzC;AAAA,EAEA,qBAA2B;AACzB,SAAK,KAAK,OAAO,eAAe;AAAA,EAClC;AAAA,EAEA,QAAc;AACZ,SAAK,KAAK,MAAM;AAAA,EAClB;AACF;AAEO,IAAM,SAAS,IAAI,cAAc;;;AD/BxC,IAAM,eAAe;AACrB,IAAM,eAAe;AAErB,IAAM,4BACJ;AAKF,IAAI;AAEJ,IAAI;AACF,YAAU,IAAI,MAAM,cAAc,YAAY;AAChD,SAAS,OAAO;AACd,MAAI,QAAQ,IAAI,aAAa,QAAQ;AACnC,YAAQ;AAAA,MACN;AAAA,IAIF;AAAA,EACF;AACF;AAEO,IAAM,cAAN,MAAkB;AAAA,EACvB,MAAM,iBAAyC;AAC7C,QAAI,SAAS;AACX,UAAI;AACF,eAAO,QAAQ,YAAY;AAAA,MAC7B,SAAS,OAAO;AACd,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,OAA8B;AACjD,QAAI,SAAS;AACX,cAAQ,YAAY,KAAK;AAAA,IAC3B,OAAO;AACL,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,oBAAsC;AAC1C,QAAI,SAAS;AACX,aAAO,QAAQ,eAAe;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAoC;AACxC,WAAQ,MAAM,KAAK,eAAe,MAAO;AAAA,EAC3C;AAAA,EAEA,MAAM,SAAwB;AAC5B,UAAM,KAAK,kBAAkB;AAC7B,WAAO,mBAAmB;AAAA,EAC5B;AACF;AAEO,IAAM,OAAO,IAAI,YAAY;;;AEhEpC,OAAO,cAAc;AAGrB,eAAsB,uBAAwC;AAC5D,QAAM,EAAE,MAAM,IAAI,MAAM,SAAS,OAAO;AAAA,IACtC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,UAAkB,CAAC,CAAC,MAAM,KAAK,KAAK;AAAA,IACjD;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAgBA,eAAsB,sBAAsB,SAAmC;AAC7E,QAAM,EAAE,UAAU,IAAI,MAAM,SAAS,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,eAAsB,uBAAyD;AAC7E,QAAM,UAAU,MAAM,SAAS,OAAO;AAAA,IACpC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAS,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IAChD;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,UAAkB,CAAC,MAAM,WAAW,KAAK,CAAC,KAAK;AAAA,IAC5D;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,QAAQ,mBAAmB,WAAW,QAAQ,MAAM,CAAC;AAAA,IACrD,YAAY,QAAQ,cAAc;AAAA,IAClC,MAAM,QAAQ,QAAQ;AAAA,EACxB;AACF;;;ACzEA,YAAY,UAAU;;;ACGf,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YACE,SACO,YACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEA,IAAM,qBAA6C;AAAA,EACjD,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACX,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,qBAAqB;AACvB;AAEO,SAAS,qBAAqB,SAAyB;AAC5D,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AAChB,aAAW,WAAW,mBAAmB;AACvC,gBAAY,UAAU,QAAQ,SAAS,YAAY;AAAA,EACrD;AAEA,SAAO,UAAU,SAAS,MAAM,UAAU,UAAU,GAAG,GAAG,IAAI,QAAQ;AACxE;AASA,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEO,SAAS,iBAAiB,OAA2B;AAC1D,MAAI,CAAC,cAAc,KAAK,GAAG;AACzB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,IAAI;AAAA,IACN;AAAA,EACF;AAEA,QAAM,WAAW;AACjB,QAAM,SAAS;AAAA,IACb,OAAO,SAAS,UAAU,SAAS,WAAW,mBAAmB;AAAA,EACnE;AAEA,SAAO;AAAA,IACL,MAAM,SAAS,QAAQ;AAAA,IACvB;AAAA,IACA,IAAI,SAAS;AAAA,EACf;AACF;AAEA,SAAS,wBAAwB,QAAwB;AACvD,SAAO,GAAG,MAAM;AAAA;AAAA;AAClB;AAEA,SAAS,oBAAoB,MAAc,QAAgB,YAA2B;AACpF,QAAM,iBAAiB,SAAS,sBAC5B,wBAAwB,MAAM,IAC9B;AAEJ,aAAW,EAAE,OAAO,EAAE,MAAM,QAAQ,gBAAgB,WAAW,EAAE,CAAC;AAClE,UAAQ,KAAK,CAAC;AAChB;AAEO,SAAS,gBAAgB,OAAuB;AACrD,MAAI,CAAC,cAAc,KAAK,GAAG;AACzB,wBAAoB,iBAAiB,gCAAgC,CAAC;AAAA,EACxE;AAEA,QAAM,WAAW;AAEjB,MAAI,SAAS,OAAO;AAClB,UAAM,YAAuB,iBAAiB,SAAS,KAAK;AAC5D;AAAA,MACE,UAAU;AAAA,MACV,UAAU;AAAA,MACV,mBAAmB,UAAU,IAAI,KAAK;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,iBAAiB,cAAc;AACjC,UAAMC,aAAY,qBAAqB,MAAM,OAAO;AACpD,wBAAoB,aAAaA,YAAW,MAAM,cAAc,CAAC;AAAA,EACnE;AAEA,QAAM,YAAY,qBAAqB,SAAS,WAAW,8BAA8B;AACzF,sBAAoB,iBAAiB,WAAW,CAAC;AACnD;;;AD5GA,OAAO,YAAY;AAEnB,OAAO,OAAO;AAIP,IAAM,aAAN,MAAiB;AAAA,EACd,MAAuB;AAAA,EACvB,qBAAqB;AAAA,EAE7B,MAAM,SAA4B;AAChC,QAAI,KAAK,KAAK;AACZ,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,gBAAgB,MAAM,KAAK,eAAe;AAChD,UAAM,cAAc,iBAAiB,QAAQ,IAAI,gBAAgB;AAEjE,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,iBAAiB,QAAQ,IAAI,gBAAgB,CAAC,KAAK,oBAAoB;AAC1E,cAAQ;AAAA,QACN;AAAA,MAGF;AACA,WAAK,qBAAqB;AAAA,IAC5B;AAEA,SAAK,MAAM,IAAS,SAAI,WAAW;AACnC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,YAAY,mBAA6C;AAC7D,UAAM,WACJ,qBAAqB,OAAO,iBAAiB,KAAK,QAAQ,IAAI;AAEhE,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kBAAqB,IAAkC;AACnE,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,OAAO;AACd,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,UAAU;AACd,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,WAAW,MAAM,IAAI,KAAK,QAAQ;AACxC,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,kBAAkB,OAAO;AACxC,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,WAAW,MAAM,IAAI,QAAQ,WAAW,eAAe;AAC7D,aAAO;AAAA,QACL,SAAS,SAAS,KAAK;AAAA,QACvB,kBAAkB;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,UAAmB,uBAAgC;AACjE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,QAAQ,cAAc,IAAI,qBAAqB;AAC1E,aAAO;AAAA,QACL,QAAQ,SAAS,KAAK;AAAA,QACtB,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAkB,UAAmB;AACzC,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,QAAQ,sBAAsB,EAAE;AAC3D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,UAAmB,uBAAgC;AACnE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,SAAS,YAAY,IAAI,qBAAqB;AACzE,aAAO;AAAA,QACL,UAAU,SAAS,KAAK;AAAA,QACxB,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,WAAmB,UAAmB;AACrD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,SAAS,eAAe,IAAI,SAAS;AAChE,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,aAAsC,UAAmB;AAC3E,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,SAAS,cAAc,IAAI,WAAW;AACjE,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,UAAmB,uBAAgC;AACrE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,WAAW,cAAc,IAAI,qBAAqB;AAC7E,aAAO;AAAA,QACL,iBAAiB,SAAS,KAAK;AAAA,QAC/B,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,YAAoB,UAAmB;AACvD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,WAAW,gBAAgB,IAAI,UAAU;AACpE,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eACJ,YACA,MACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,WAAW,eAAe,IAAI,YAAY,IAAI;AACzE,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,OAAe,YAAoB,UAAmB;AAC3E,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,WAAW,qBAAqB,IAAI,OAAO,UAAU;AAChF,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,oBACJ,OACA,YACA,MACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,WAAW,oBAAoB,IAAI,OAAO,YAAY,IAAI;AACrF,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU,UAAmB,uBAAgC;AACjE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,OAAO,UAAU,IAAI,qBAAqB;AACrE,aAAO;AAAA,QACL,QAAQ,SAAS,KAAK;AAAA,QACtB,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS,SAAiB,UAAmB;AACjD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,OAAO,aAAa,IAAI,OAAO;AAC1D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY,SAAiB,MAA8B,UAAmB;AAClF,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,OAAO,YAAY,IAAI,SAAS,IAAI;AAC/D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAkB,UAAmB;AACzC,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,eAAe,kBAAkB,EAAE;AAC9D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBAAiB,iBAAyB,UAAmB;AACjE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,eAAe,qBAAqB,IAAI,eAAe;AAClF,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,yBAAyB,SAAiB,UAAmB;AACjE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,eAAe,yBAAyB,IAAI,OAAO;AAC9E,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,gBAAgB,UAAmB,uBAAgC;AACvE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,OAAO,gBAAgB,IAAI,qBAAqB;AAC3E,aAAO;AAAA,QACL,QAAQ,SAAS,KAAK;AAAA,QACtB,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,OAAe,UAAmB;AACrD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,OAAO,eAAe,IAAI,KAAK;AAC1D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,gBAAgB,QAKnB;AACD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,OAAO,QAAQ;AACjD,YAAM,WAAW,MAAM,IAAI,aAAa;AAAA,QACtC;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,cAAc,SAAS,KAAK;AAAA,QAC5B,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,yBAAyB,WAAmB,QAK/C;AACD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,OAAO,QAAQ;AACjD,YAAM,WAAW,MAAM,IAAI,aAAa;AAAA,QACtC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,cAAc,SAAS,KAAK;AAAA,QAC5B,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,0BAA0B,YAAoB,QAKjD;AACD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,OAAO,QAAQ;AACjD,YAAM,WAAW,MAAM,IAAI,aAAa;AAAA,QACtC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,cAAc,SAAS,KAAK;AAAA,QAC5B,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,uBAAuB,SAAiB,QAK3C;AACD,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,OAAO,QAAQ;AACjD,YAAM,WAAW,MAAM,IAAI,aAAa;AAAA,QACtC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,cAAc,SAAS,KAAK;AAAA,QAC5B,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,eAAuB,UAAmB;AAC7D,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,mBAAmB,IAAI,aAAa;AAC5E,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBACJ,iBACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,kBAAkB,IAAI,eAAe;AAC7E,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBACJ,kBACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,mBAAmB,IAAI,gBAAgB;AAC/E,aAAO,SAAS;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBACJ,eACA,iBACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa;AAAA,QACtC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBACJ,kBACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,mBAAmB,IAAI,gBAAgB;AAC/E,aAAO,SAAS;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,kBAAkB,eAAuB,UAAmB;AAChE,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,kBAAkB,IAAI,aAAa;AAC3E,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,UAAmB;AAC1C,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,aAAa,mBAAmB,EAAE;AAC7D,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,yBAAyB,UAAmB,uBAAgC;AAChF,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,sBAAsB;AAAA,QAC/C;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,QACL,wBAAwB,SAAS,KAAK;AAAA,QACtC,kBAAkB,SAAS,KAAK;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,wBAAwB,wBAAgC,UAAmB;AAC/E,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,sBAAsB;AAAA,QAC/C;AAAA,QACA;AAAA,MACF;AACA,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,2BACJ,MACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,sBAAsB,2BAA2B,IAAI,IAAI;AACpF,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,2BACJ,wBACA,MACA,UACA;AACA,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,sBAAsB;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,2BAA2B,wBAAgC,UAAmB;AAClF,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,YAAM,KAAK,MAAM,KAAK,YAAY,QAAQ;AAC1C,YAAM,WAAW,MAAM,IAAI,sBAAsB;AAAA,QAC/C;AAAA,QACA;AAAA,MACF;AACA,aAAO,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,QAAgB,MAAc,MAAgB,UAAmB;AAChF,WAAO,KAAK,kBAAkB,YAAY;AACxC,YAAM,KAAK,OAAO;AAElB,YAAM,WAAW,KAAK,SAAS,aAAa,IACxC,KAAK,QAAQ,eAAe,MAAM,KAAK,YAAY,QAAQ,CAAC,IAC5D;AAEJ,YAAM,MAAM,0BAA0B,QAAQ;AAC9C,YAAM,UAAU;AAAA,QACd,eAAe,UAAU,MAAM,KAAK,eAAe,CAAC;AAAA,QACpD,gBAAgB;AAAA,MAClB;AAEA,YAAM,aAAa,OAAO,YAAY;AACtC,YAAM,UAAU,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,UAAU;AAE5D,UAAI,CAAC,CAAC,OAAO,QAAQ,OAAO,SAAS,QAAQ,EAAE,SAAS,UAAU,GAAG;AACnE,cAAM,IAAI,aAAa,4BAA4B,MAAM,IAAI,GAAG;AAAA,MAClE;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR;AAAA,QACA,GAAI,WAAW,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9C,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,cAAM,EAAE,OAAO,iBAAiB,UAAU,SAAS,SAAS,EAAE;AAAA,MAChE;AAEA,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;AAEO,IAAM,SAAS,IAAI,WAAW;;;AE5hB9B,SAAS,kBACd,IACmC;AACnC,SAAO,UAAU,SAAgB;AAC/B,QAAI;AACF,YAAM,GAAG,GAAG,IAAI;AAAA,IAClB,SAAS,OAAO;AACd,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AACF;AAEA,eAAsB,cACpB,UACA,mBAA4B,OACV;AAClB,MAAI,oBAAoB,CAAC,cAAc,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB,wCAAwC,QAAQ;AAAA,EAClD;AAEA,MAAI,CAAC,WAAW;AACd,eAAW,EAAE,SAAS,sBAAsB,CAAC;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,kBACd,SACA,SACyB;AACzB,QAAM,SAAkC,CAAC;AACzC,QAAM,gBAAgB;AAEtB,aAAW,CAAC,WAAW,SAAS,KAAK,OAAO,QAAQ,OAAO,GAAG;AAC5D,QAAI,cAAc,SAAS,MAAM,QAAW;AAC1C,aAAO,SAAS,IAAI,cAAc,SAAS;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;;;AN5CO,SAAS,oBAA6B;AAC3C,QAAM,MAAM,IAAI,QAAQ,MAAM,EAAE,YAAY,2BAA2B;AAEvE,MACG,QAAQ,OAAO,EACf,YAAY,wBAAwB,EACpC,OAAO,kBAAkB,YAAY;AACpC,UAAM,QAAQ,MAAM,qBAAqB;AACzC,UAAM,KAAK,eAAe,KAAK;AAE/B,QAAI;AACF,YAAM,OAAO,MAAM,OAAO,QAAQ;AAClC,iBAAW;AAAA,QACT,SAAS;AAAA,QACT,MAAM,EAAE,IAAI,MAAM,GAAG;AAAA,MACvB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,KAAK,kBAAkB;AAC7B,YAAM;AAAA,IACR;AAAA,EACF,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,OAAO,kBAAkB,YAAY;AACpC,UAAM,kBAAkB,MAAM,KAAK,gBAAgB;AAEnD,QAAI,CAAC,iBAAiB;AACpB,iBAAW,EAAE,eAAe,OAAO,SAAS,oBAAoB,CAAC;AACjE;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,OAAO,QAAQ;AAClC,iBAAW,EAAE,eAAe,MAAM,MAAM,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC;AAAA,IAC5D,SAAS,OAAO;AACd,iBAAW,EAAE,eAAe,OAAO,SAAS,8BAA8B,CAAC;AAAA,IAC7E;AAAA,EACF,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,OAAO,kBAAkB,YAAY;AACpC,UAAM,KAAK,OAAO;AAClB,eAAW,EAAE,SAAS,0BAA0B,CAAC;AAAA,EACnD,CAAC,CAAC;AAEJ,SAAO;AACT;;;AOzDA,SAAS,WAAAC,gBAAe;AAKjB,SAAS,oBAA6B;AAC3C,QAAM,MAAM,IAAIC,SAAQ,MAAM,EAAE,YAAY,kBAAkB;AAE9D,MACG,QAAQ,MAAM,EACd,YAAY,oCAAoC,EAChD,OAAO,kBAAkB,YAAY;AACpC,UAAM,OAAO,MAAM,OAAO,QAAQ;AAClC,eAAW,IAAI;AAAA,EACjB,CAAC,CAAC;AAEJ,SAAO;AACT;;;ACjBA,SAAS,WAAAC,gBAAe;AAOjB,SAAS,uBAAgC;AAC9C,QAAM,MAAM,IAAIC,SAAQ,SAAS,EAAE,YAAY,mBAAmB;AAElE,MACG,QAAQ,MAAM,EACd,YAAY,kBAAkB,EAC9B,OAAO,sBAAsB,8BAA8B,EAC3D,OAAO,kBAAkB,OAAO,YAA2C;AAC1E,UAAM,SAAS,MAAM,OAAO,WAAW,QAAQ,eAAe;AAC9D,eAAW,QAAQ,OAAO;AAAA,EAC5B,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,sDAAsD,EAClE,SAAS,QAAQ,WAAW,EAC5B,OAAO,kBAAkB,OAAO,OAA2B;AAC1D,UAAM,SAAS,MAAM,OAAO,UAAU,EAAE;AACxC,eAAW,QAAQ,MAAM;AAAA,EAC3B,CAAC,CAAC;AAEJ,MACG,QAAQ,UAAU,EAClB,YAAY,sBAAsB,EAClC,SAAS,QAAQ,WAAW,EAC5B,OAAO,kBAAkB,OAAO,OAA2B;AAC1D,UAAM,WAAW,MAAM,OAAO,kBAAkB,EAAE;AAClD,eAAW,QAAQ;AAAA,EACrB,CAAC,CAAC;AAEJ,MACG,QAAQ,aAAa,EACrB,YAAY,iCAAiC,EAC7C,SAAS,QAAQ,WAAW,EAC5B,OAAO,kBAAkB,OAAO,OAAe;AAC9C,UAAM,SAAS,MAAM,OAAO,WAAW;AACvC,UAAM,SAAS,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAEtD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,aAAa,kBAAkB,EAAE,cAAc,GAAG;AAAA,IAC9D;AAEA,WAAO,iBAAiB,EAAE;AAC1B,eAAW;AAAA,MACT,SAAS;AAAA,MACT,QAAQ,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,KAAK;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC,CAAC;AAEJ,SAAO;AACT;;;ACzDA,SAAS,WAAAC,gBAAe;AAMjB,SAAS,wBAAiC;AAC/C,QAAM,MAAM,IAAIC,SAAQ,UAAU,EAAE,YAAY,oBAAoB;AAEpE,MACG,QAAQ,MAAM,EACd,YAAY,mBAAmB,EAC/B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,YAA4B;AAC3D,UAAM,SAAS,MAAM,OAAO,YAAY,QAAQ,MAAM;AACtD,eAAW,QAAQ,QAAQ;AAAA,EAC7B,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,sBAAsB,EAClC,SAAS,QAAQ,YAAY,EAC7B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,UAAU,MAAM,OAAO,WAAW,IAAI,QAAQ,MAAM;AAC1D,eAAW,OAAO;AAAA,EACpB,CAAC,CAAC;AAEJ,MACG,QAAQ,cAAc,EACtB,YAAY,+BAA+B,EAC3C,SAAS,QAAQ,YAAY,EAC7B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,kBAAkB,OACxB,IACA,YAKG;AACH,UAAM,SAAS,MAAM,OAAO,yBAAyB,IAAI;AAAA,MACvD,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,IAChB,CAAC;AACD,eAAW,QAAQ,YAAY;AAAA,EACjC,CAAC,CAAC;AAEJ,SAAO;AACT;;;ACpDA,SAAS,WAAAC,gBAAe;AAQjB,SAAS,0BAAmC;AACjD,QAAM,MAAM,IAAIC,SAAQ,YAAY,EAAE,YAAY,qBAAqB;AAEvE,MACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OAAO,YAA0E;AACzG,UAAM,SAAS,MAAM,OAAO,cAAc,QAAQ,QAAQ,QAAQ,aAAa;AAC/E,eAAW,QAAQ,eAAe;AAAA,EACpC,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,uBAAuB,EACnC,SAAS,QAAQ,aAAa,EAC9B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,WAAW,MAAM,OAAO,YAAY,IAAI,QAAQ,MAAM;AAC5D,eAAW,QAAQ;AAAA,EACrB,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,sEAAsE,EAClF,SAAS,QAAQ,aAAa,EAC9B,eAAe,mBAAmB,+CAA+C,EACjF,eAAe,qBAAqB,+CAA+C,UAAU,EAC7F,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OACxB,IACA,YAKG;AACH,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAM,IAAI,aAAa,iCAAiC,GAAG;AAAA,IAC7D;AAEA,UAAM,aAAa,mBAAmB,QAAQ,MAAM;AACpD,UAAM,WAAW,MAAM,OAAO;AAAA,MAC5B,QAAQ;AAAA,MACR;AAAA,MACA,EAAE,UAAU,EAAE,UAAU,WAAW,EAAE;AAAA,MACrC,QAAQ;AAAA,IACV;AACA,eAAW,QAAQ;AAAA,EACrB,CAAC,CAAC;AAEJ,MACG,QAAQ,cAAc,EACtB,YAAY,gCAAgC,EAC5C,SAAS,QAAQ,aAAa,EAC9B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OACxB,IACA,YAMG;AACH,UAAM,SAAS,MAAM,OAAO,0BAA0B,IAAI;AAAA,MACxD,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,uBAAuB,QAAQ;AAAA,IACjC,CAAC;AACD,eAAW,QAAQ,YAAY;AAAA,EACjC,CAAC,CAAC;AAEJ,SAAO;AACT;;;ACvFA,SAAS,WAAAC,gBAAe;;;ACAxB,SAAS,SAAS;AAGX,IAAM,yBAAyB,EAAE;AAAA,EACtC,EAAE,OAAO;AAAA,IACP,QAAQ,EAAE,OAAO;AAAA,IACjB,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,IAC5C,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,CAAC;AACH;AAEO,IAAM,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC;AAEtC,SAAS,aACd,MACA,QACA,WACG;AACH,MAAI;AACF,WAAO,OAAO,MAAM,IAAI;AAAA,EAC1B,SAAS,OAAO;AACd,QAAI,iBAAiB,EAAE,UAAU;AAC/B,YAAM,SAAS,MAAM,OAClB,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAC5C,KAAK,IAAI;AACZ,YAAM,IAAI,aAAa,WAAW,SAAS,KAAK,MAAM,IAAI,GAAG;AAAA,IAC/D;AACA,UAAM;AAAA,EACR;AACF;;;ADRA,SAAS,qBAAqB,SAAsD;AAClF,MAAI,CAAC,QAAQ,SAAS;AACpB,UAAM,IAAI,aAAa,iDAAiD,GAAG;AAAA,EAC7E;AACA,MAAI,QAAQ,WAAW,QAAW;AAChC,UAAM,IAAI,aAAa,gDAAgD,GAAG;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL,YAAY,QAAQ;AAAA,IACpB,MAAM,QAAQ,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IAC3D,QAAQ,mBAAmB,QAAQ,MAAM;AAAA,IACzC,YAAY,QAAQ;AAAA,IACpB,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,IACrB,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,UAAU,QAAQ;AAAA,EACpB;AACF;AAEO,SAAS,4BAAqC;AACnD,QAAM,MAAM,IAAIC,SAAQ,cAAc,EAAE,YAAY,wBAAwB;AAE5E,MACG,QAAQ,MAAM,EACd,YAAY,mBAAmB,EAC/B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,sBAAsB,EAC/C,OAAO,mBAAmB,uBAAuB,EACjD,OAAO,gBAAgB,oBAAoB,EAC3C,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,sBAAsB,0CAA0C,EACvE,OAAO,uBAAuB,yFAAyF,EACvH,OAAO,yBAAyB,kDAAkD,UAAU,EAC5F,OAAO,yBAAyB,mDAAmD,UAAU,EAC7F,OAAO,qBAAqB,uEAAuE,EACnG,OAAO,kBAAkB,OAAO,YAaV;AACrB,UAAM,SAAS;AAAA,MACb,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,IAChB;AAEA,UAAM,SAAS,QAAQ,UACnB,MAAM,OAAO,yBAAyB,QAAQ,SAAS,MAAM,IAC7D,QAAQ,WACR,MAAM,OAAO,0BAA0B,QAAQ,UAAU,MAAM,IAC/D,QAAQ,QACR,MAAM,OAAO,uBAAuB,QAAQ,OAAO,MAAM,IACzD,MAAM,OAAO,gBAAgB,MAAM;AAEvC,UAAM,eAAe,QAAQ,gBAAgB,CAAC;AAE9C,UAAM,WAAW,wBAAwB,cAAmC;AAAA,MAC1E,OAAO,QAAQ;AAAA,MACf,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,IACrB,CAAC;AAED,UAAM,WAAW,oBAAoB,UAAU,QAAQ,MAAM;AAE7D,eAAW,QAAQ;AAAA,EACrB,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,yBAAyB,EACrC,SAAS,QAAQ,gBAAgB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,cAAc,MAAM,OAAO,eAAe,IAAI,QAAQ,MAAM;AAClE,eAAW,WAAW;AAAA,EACxB,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,YAAY,EACrC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,qBAAqB,0CAA0C,UAAU,EAChF,OAAO,uBAAuB,YAAY,EAC1C,OAAO,mBAAmB,UAAU,EACpC,OAAO,sBAAsB,aAAa,EAC1C,OAAO,iBAAiB,MAAM,EAC9B,OAAO,sBAAsB,iDAAiD,EAC9E,OAAO,cAAc,kBAAkB,EACvC,OAAO,kBAAkB,OAAO,YAWV;AACrB,UAAM,eAAe,cAAc,KAAK,CAAC,QAAQ,WAAW,CAAC,QAAQ;AACrE,UAAM,kBAAkB,eACpB,MAAM,qBAAqB,IAC3B,qBAAqB,OAAO;AAEhC,UAAM,cAAc,MAAM,OAAO;AAAA,MAC/B,EAAE,aAAa,gBAAgB;AAAA,MAC/B,QAAQ;AAAA,IACV;AACA,eAAW,WAAW;AAAA,EACxB,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,SAAS,QAAQ,gBAAgB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,YAAY,EACrC,OAAO,iBAAiB,mBAAmB,EAC3C,OAAO,qBAAqB,4BAA4B,UAAU,EAClE,OAAO,uBAAuB,YAAY,EAC1C,OAAO,mBAAmB,UAAU,EACpC,OAAO,sBAAsB,aAAa,EAC1C,OAAO,iBAAiB,MAAM,EAC9B,OAAO,sBAAsB,gBAAgB,EAC7C,OAAO,cAAc,kBAAkB,EACvC,OAAO,kBAAkB,OACxB,IACA,YACG;AACH,UAAM,kBAAkB,kBAAkB,SAAS;AAAA,MACjD,SAAS;AAAA,MACT,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,IACZ,CAAC;AAED,QAAI,QAAQ,WAAW,QAAW;AAChC,sBAAgB,SAAS,mBAAmB,QAAQ,MAAM;AAAA,IAC5D;AAEA,UAAM,cAAc,MAAM,OAAO;AAAA,MAC/B;AAAA,MACA,EAAE,aAAa,gBAAgB;AAAA,MAC/B,QAAQ;AAAA,IACV;AACA,eAAW,WAAW;AAAA,EACxB,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,oBAAoB,EAChC,SAAS,QAAQ,gBAAgB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,aAAa,mBAAmB,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAAiE;AAC5G,QAAI,CAAC,MAAM,cAAc,eAAe,QAAQ,GAAG,GAAG;AACpD;AAAA,IACF;AAEA,UAAM,cAAc,MAAM,OAAO,kBAAkB,IAAI,QAAQ,MAAM;AACrE,eAAW,EAAE,SAAS,uBAAuB,YAAY,CAAC;AAAA,EAC5D,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,YAA4B;AAC3D,UAAM,iBAAiB,MAAM,OAAO,mBAAmB,QAAQ,MAAM;AACrE,eAAW,EAAE,iBAAiB,eAAe,CAAC;AAAA,EAChD,CAAC,CAAC;AAEJ,MACG,QAAQ,OAAO,EACf,YAAY,yFAAyF,EACrG,SAAS,QAAQ,gBAAgB,EACjC,eAAe,mBAAmB,qGAAqG,EACvI,OAAO,qBAAqB,WAAW,EACvC,OAAO,eAAe,uEAAuE,EAC7F,OAAO,kBAAkB,OACxB,IACA,YACG;AACH,QAAI;AACJ,QAAI;AACF,qBAAe,KAAK,MAAM,QAAQ,MAAM;AAAA,IAC1C,SAAS,OAAO;AACd,YAAM,IAAI,aAAa,sCAAsC,GAAG;AAAA,IAClE;AAEA,UAAM,SAAS,aAAa,cAAc,wBAAwB,oBAAoB;AAEtF,UAAM,qBAAqB,OAAO,IAAI,YAAU;AAAA,MAC9C,GAAG;AAAA,MACH,QAAQ,mBAAmB,MAAM,MAAM;AAAA,IACzC,EAAE;AAEF,UAAM,sBAAsB,MAAM,OAAO,eAAe,IAAI,QAAQ,MAAM;AAC1E,UAAM,iBAAiB,oBAAoB,mBAAmB,oBAAoB,gBAAgB,SAAS;AAE3G,QAAI,kBAAkB,CAAC,QAAQ,OAAO;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,QAEA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB;AAClB,YAAM,OAAO,kBAAkB,IAAI,QAAQ,MAAM;AAEjD,YAAM,uBAAuB,MAAM,OAAO;AAAA,QACxC;AAAA,UACE,aAAa;AAAA,YACX,YAAY,oBAAoB;AAAA,YAChC,MAAM,oBAAoB;AAAA,YAC1B,QAAQ,oBAAoB;AAAA,YAC5B,UAAU,oBAAoB;AAAA,YAC9B,YAAY,oBAAoB;AAAA,YAChC,aAAa;AAAA,YACb,MAAM,oBAAoB;AAAA,YAC1B,SAAS,oBAAoB;AAAA,YAC7B,UAAU,oBAAoB;AAAA,YAC9B,YAAY,oBAAoB;AAAA,YAChC,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,MACV;AACA,iBAAW,oBAAoB;AAAA,IACjC,OAAO;AACL,YAAM,cAAc,MAAM,OAAO;AAAA,QAC/B;AAAA,QACA;AAAA,UACE,aAAa;AAAA,YACX,aAAa;AAAA,YACb,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,MACV;AACA,iBAAW,WAAW;AAAA,IACxB;AAAA,EACF,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,qBAAqB,WAAW,EACvC,OAAO,iBAAiB,sBAAsB,EAC9C,OAAO,uBAAuB,sBAAsB,EACpD,OAAO,qBAAqB,6CAA6C,UAAU,EACnF,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,sBAAsB,0CAA0C,EACvE,OAAO,uBAAuB,4EAA4E,EAC1G,OAAO,qBAAqB,2CAA2C,EACvE,OAAO,kBAAkB,OAAO,YAUV;AACrB,QAAI,CAAC,QAAQ,QAAQ,CAAC,QAAQ,aAAa,QAAQ,WAAW,QAAW;AACvE,YAAM,IAAI,aAAa,4EAA4E,GAAG;AAAA,IACxG;AAEA,UAAM,SAAS;AAAA,MACb,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,IACrB;AAEA,UAAM,SAAS,MAAM,OAAO,gBAAgB,MAAM;AAClD,QAAI,eAAe,QAAQ,gBAAgB,CAAC;AAE5C,QAAI,QAAQ,MAAM;AAChB,YAAM,aAAa,QAAQ,KAAK,YAAY;AAC5C,qBAAe,aAAa;AAAA,QAAO,OACjC,EAAE,MAAM,YAAY,EAAE,SAAS,UAAU;AAAA,MAC3C;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW;AACrB,YAAM,aAAa,QAAQ,UAAU,YAAY;AACjD,qBAAe,aAAa;AAAA,QAAO,OACjC,EAAE,YAAY,YAAY,EAAE,SAAS,UAAU;AAAA,MACjD;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,QAAW;AAChC,YAAM,mBAAmB,mBAAmB,QAAQ,MAAM;AAC1D,qBAAe,aAAa,OAAO,OAAK,EAAE,WAAW,gBAAgB;AAAA,IACvE;AAEA,mBAAe,wBAAwB,cAAc;AAAA,MACnD,OAAO,QAAQ;AAAA,MACf,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,UAAM,uBAAuB,oBAAoB,cAAc,QAAQ,MAAM;AAE7E,eAAW,oBAAoB;AAAA,EACjC,CAAC,CAAC;AAEJ,SAAO;AACT;;;AEnWA,SAAS,WAAAC,gBAAe;AAMjB,SAAS,yBAAkC;AAChD,QAAM,MAAM,IAAIC,SAAQ,WAAW,EAAE,YAAY,kCAAkC;AAEnF,MACG,QAAQ,MAAM,EACd,YAAY,iCAAiC,EAC7C,OAAO,qBAAqB,WAAW,EACvC,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OAAO,YAA0E;AACzG,UAAM,SAAS,MAAM,OAAO,yBAAyB,QAAQ,QAAQ,QAAQ,aAAa;AAC1F,eAAW,QAAQ,sBAAsB;AAAA,EAC3C,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,SAAS,QAAQ,0BAA0B,EAC3C,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,uBAAuB,MAAM,OAAO,wBAAwB,IAAI,QAAQ,MAAM;AACpF,eAAW,oBAAoB;AAAA,EACjC,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,8BAA8B,EAC1C,SAAS,QAAQ,0BAA0B,EAC3C,OAAO,qBAAqB,WAAW,EACvC,OAAO,aAAa,mBAAmB,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAAiE;AAC5G,QAAI,CAAC,MAAM,cAAc,yBAAyB,QAAQ,GAAG,GAAG;AAC9D;AAAA,IACF;AAEA,UAAM,uBAAuB,MAAM,OAAO,2BAA2B,IAAI,QAAQ,MAAM;AACvF,eAAW;AAAA,MACT,SAAS;AAAA,MACT,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH,CAAC,CAAC;AAEJ,SAAO;AACT;;;AChDA,SAAS,WAAAC,gBAAe;AAOjB,SAAS,sBAA+B;AAC7C,QAAM,MAAM,IAAIC,SAAQ,QAAQ,EAAE,YAAY,kBAAkB;AAEhE,MACG,QAAQ,MAAM,EACd,YAAY,iBAAiB,EAC7B,OAAO,qBAAqB,WAAW,EACvC,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OAAO,YAA0E;AACzG,UAAM,SAAS,MAAM,OAAO,UAAU,QAAQ,QAAQ,QAAQ,aAAa;AAC3E,eAAW,QAAQ,MAAM;AAAA,EAC3B,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,oBAAoB,EAChC,SAAS,QAAQ,UAAU,EAC3B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,QAAQ,MAAM,OAAO,SAAS,IAAI,QAAQ,MAAM;AACtD,eAAW,KAAK;AAAA,EAClB,CAAC,CAAC;AAEJ,MACG,QAAQ,QAAQ,EAChB,YAAY,cAAc,EAC1B,SAAS,QAAQ,UAAU,EAC3B,eAAe,iBAAiB,gBAAgB,EAChD,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAAgE;AAC3G,QAAI,CAAC,QAAQ,MAAM,KAAK,GAAG;AACzB,YAAM,IAAI,aAAa,wBAAwB,GAAG;AAAA,IACpD;AAEA,UAAM,QAAQ,MAAM,OAAO;AAAA,MACzB;AAAA,MACA,EAAE,OAAO,EAAE,MAAM,QAAQ,KAAK,EAAE;AAAA,MAChC,QAAQ;AAAA,IACV;AACA,eAAW,KAAK;AAAA,EAClB,CAAC,CAAC;AAEJ,MACG,QAAQ,WAAW,EACnB,YAAY,0BAA0B,EACtC,SAAS,QAAQ,UAAU,EAC3B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,IAAY,YAA4B;AACvE,UAAM,YAAY,MAAM,OAAO,yBAAyB,IAAI,QAAQ,MAAM;AAC1E,eAAW,SAAS;AAAA,EACtB,CAAC,CAAC;AAEJ,MACG,QAAQ,cAAc,EACtB,YAAY,6BAA6B,EACzC,SAAS,QAAQ,UAAU,EAC3B,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,6CAA6C,EACtE,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OACxB,IACA,YAMG;AACH,UAAM,SAAS,MAAM,OAAO,uBAAuB,IAAI;AAAA,MACrD,UAAU,QAAQ;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,uBAAuB,QAAQ;AAAA,IACjC,CAAC;AACD,eAAW,QAAQ,YAAY;AAAA,EACjC,CAAC,CAAC;AAEJ,SAAO;AACT;;;ACtFA,SAAS,WAAAC,gBAAe;AAMjB,SAAS,sBAA+B;AAC7C,QAAM,MAAM,IAAIC,SAAQ,QAAQ,EAAE,YAAY,2BAA2B;AAEzE,MACG,QAAQ,MAAM,EACd,YAAY,wBAAwB,EACpC,OAAO,qBAAqB,WAAW,EACvC,OAAO,6BAA6B,4BAA4B,QAAQ,EACxE,OAAO,kBAAkB,OAAO,YAA0E;AACzG,UAAM,SAAS,MAAM,OAAO,gBAAgB,QAAQ,QAAQ,QAAQ,aAAa;AACjF,eAAW,QAAQ,MAAM;AAAA,EAC3B,CAAC,CAAC;AAEJ,MACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,SAAS,WAAW,+CAA+C,EACnE,OAAO,qBAAqB,WAAW,EACvC,OAAO,kBAAkB,OAAO,OAAe,YAA4B;AAC1E,UAAM,YAAY,MAAM,OAAO,eAAe,OAAO,QAAQ,MAAM;AACnE,eAAW,SAAS;AAAA,EACtB,CAAC,CAAC;AAEJ,SAAO;AACT;;;AC9BA,SAAS,WAAAC,iBAAe;AAQxB,IAAM,qBAAqB,CAAC,OAAO,QAAQ,OAAO,SAAS,QAAQ;AAE5D,SAAS,mBAA4B;AAC1C,QAAM,MAAM,IAAIC,UAAQ,KAAK,EAAE,YAAY,gBAAgB;AAE3D,MACG,SAAS,YAAY,6CAA6C,EAClE,SAAS,UAAU,gEAAgE,EACnF,OAAO,qBAAqB,iDAAiD,EAC7E,OAAO,iBAAiB,uCAAuC,EAC/D,YAAY,4BAA4B,EACxC,OAAO,kBAAkB,OACxB,QACA,MACA,YACG;AACH,UAAM,cAAc,OAAO,YAAY;AAEvC,QAAI,CAAC,mBAAmB,SAAS,WAAW,GAAG;AAC7C,YAAM,IAAI;AAAA,QACR,wBAAwB,MAAM,qBAAqB,mBAAmB,KAAK,IAAI,CAAC;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACJ,QAAI,QAAQ,MAAM;AAChB,UAAI;AACF,cAAM,aAAa,KAAK,MAAM,QAAQ,IAAI;AAC1C,eAAO,aAAa,YAAY,eAAe,UAAU;AAAA,MAC3D,SAAS,OAAO;AACd,cAAM,IAAI,aAAa,oCAAoC,GAAG;AAAA,MAChE;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,OAAO,WAAW,aAAa,MAAM,MAAM,QAAQ,MAAM;AAC9E,eAAW,MAAM;AAAA,EACnB,CAAC,CAAC;AAEJ,SAAO;AACT;;;AnB/BA,IAAM,UAAU,IAAIC,UAAQ;AAE5B,QACG,KAAK,MAAM,EACX,YAAY,uDAAuD,EACnE,QAAQ,OAAW,EACnB,OAAO,iBAAiB,oCAAoC,EAC5D,KAAK,aAAa,CAAC,gBAAgB;AAClC,QAAM,UAAU,YAAY,KAAK;AACjC,mBAAiB;AAAA,IACf,SAAS,QAAQ;AAAA,EACnB,CAAC;AACH,CAAC;AAEH,QAAQ,WAAW,kBAAkB,CAAC;AACtC,QAAQ,WAAW,kBAAkB,CAAC;AACtC,QAAQ,WAAW,qBAAqB,CAAC;AACzC,QAAQ,WAAW,sBAAsB,CAAC;AAC1C,QAAQ,WAAW,wBAAwB,CAAC;AAC5C,QAAQ,WAAW,0BAA0B,CAAC;AAC9C,QAAQ,WAAW,uBAAuB,CAAC;AAC3C,QAAQ,WAAW,oBAAoB,CAAC;AACxC,QAAQ,WAAW,oBAAoB,CAAC;AACxC,QAAQ,WAAW,iBAAiB,CAAC;AAErC,QAAQ,MAAM;","names":["Command","sanitized","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/lib/utils.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/auth.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/lib/prompts.ts","../src/lib/api-client.ts","../src/lib/command-utils.ts","../src/commands/user.ts","../src/commands/budgets.ts","../src/commands/accounts.ts","../src/commands/categories.ts","../src/commands/transactions.ts","../src/lib/schemas.ts","../src/commands/scheduled.ts","../src/commands/payees.ts","../src/commands/months.ts","../src/commands/api.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createAuthCommand } from './commands/auth.js';\nimport { createUserCommand } from './commands/user.js';\nimport { createBudgetsCommand } from './commands/budgets.js';\nimport { createAccountsCommand } from './commands/accounts.js';\nimport { createCategoriesCommand } from './commands/categories.js';\nimport { createTransactionsCommand } from './commands/transactions.js';\nimport { createScheduledCommand } from './commands/scheduled.js';\nimport { createPayeesCommand } from './commands/payees.js';\nimport { createMonthsCommand } from './commands/months.js';\nimport { createApiCommand } from './commands/api.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('ynab')\n .description('A command-line interface for You Need a Budget (YNAB)')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createAuthCommand());\nprogram.addCommand(createUserCommand());\nprogram.addCommand(createBudgetsCommand());\nprogram.addCommand(createAccountsCommand());\nprogram.addCommand(createCategoriesCommand());\nprogram.addCommand(createTransactionsCommand());\nprogram.addCommand(createScheduledCommand());\nprogram.addCommand(createPayeesCommand());\nprogram.addCommand(createMonthsCommand());\nprogram.addCommand(createApiCommand());\n\nprogram.parse();\n","import { format, parseISO } from 'date-fns';\nimport { YnabCliError } from './errors.js';\n\nexport function milliunitsToAmount(milliunits: number): number {\n return milliunits / 1000;\n}\n\nexport function amountToMilliunits(amount: number): number {\n return Math.round(amount * 1000);\n}\n\nexport function formatCurrency(milliunits: number, currencySymbol = '$'): string {\n const amount = milliunitsToAmount(milliunits);\n return `${currencySymbol}${amount.toFixed(2)}`;\n}\n\nexport function formatDate(isoDate: string, formatString = 'yyyy-MM-dd'): string {\n return format(parseISO(isoDate), formatString);\n}\n\nexport function parseDate(dateString: string): string {\n const date = parseISO(dateString);\n return format(date, 'yyyy-MM-dd');\n}\n\nexport function isInteractive(): boolean {\n return process.stdin.isTTY === true;\n}\n\nexport function convertMilliunitsToAmounts(data: unknown): unknown {\n if (data === null || data === undefined) return data;\n if (Array.isArray(data)) return data.map(convertMilliunitsToAmounts);\n if (typeof data !== 'object') return data;\n\n const converted: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (isAmountField(key) && typeof value === 'number') {\n converted[key] = milliunitsToAmount(value);\n } else if (isDebtAmountMapField(key) && typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const convertedMap: Record<string, unknown> = {};\n for (const [dateKey, amountValue] of Object.entries(value)) {\n convertedMap[dateKey] = typeof amountValue === 'number' ? milliunitsToAmount(amountValue) : amountValue;\n }\n converted[key] = convertedMap;\n } else {\n converted[key] = convertMilliunitsToAmounts(value);\n }\n }\n return converted;\n}\n\nfunction isAmountField(fieldName: string): boolean {\n const amountFields = [\n 'amount',\n 'balance',\n 'cleared_balance',\n 'uncleared_balance',\n 'budgeted',\n 'activity',\n 'available',\n 'goal_target',\n 'goal_under_funded',\n 'goal_overall_funded',\n 'goal_overall_left',\n 'income',\n 'to_be_budgeted',\n 'debt_original_balance',\n ];\n\n return amountFields.includes(fieldName) || fieldName.endsWith('_amount');\n}\n\nfunction isDebtAmountMapField(fieldName: string): boolean {\n const debtAmountMapFields = [\n 'debt_minimum_payments',\n 'debt_escrow_amounts',\n 'debt_interest_rates',\n ];\n\n return debtAmountMapFields.includes(fieldName);\n}\n\nexport function parseApprovedFilter(value: string): boolean {\n const normalized = value.toLowerCase();\n if (normalized !== 'true' && normalized !== 'false') {\n throw new YnabCliError(`--approved must be 'true' or 'false', got '${value}'`, 400);\n }\n return normalized === 'true';\n}\n\nexport function parseStatusFilter(value: string): string[] {\n const statuses = value.split(',').map(s => s.trim().toLowerCase());\n const validStatuses = ['cleared', 'uncleared', 'reconciled'];\n\n for (const status of statuses) {\n if (!validStatuses.includes(status)) {\n throw new YnabCliError(`Invalid status '${status}'. Must be one of: ${validStatuses.join(', ')}`, 400);\n }\n }\n\n return statuses;\n}\n\nexport type TransactionLike = {\n date: string;\n amount: number;\n approved: boolean;\n cleared: string;\n};\n\nexport function applyTransactionFilters<T extends TransactionLike>(transactions: T[], filters: {\n until?: string;\n approved?: string;\n status?: string;\n minAmount?: number;\n maxAmount?: number;\n}): T[] {\n let filtered = transactions;\n\n if (filters.until) {\n filtered = filtered.filter(t => t.date <= filters.until!);\n }\n\n if (filters.approved !== undefined) {\n const approvedValue = parseApprovedFilter(filters.approved);\n filtered = filtered.filter(t => t.approved === approvedValue);\n }\n\n if (filters.status) {\n const statuses = parseStatusFilter(filters.status);\n filtered = filtered.filter(t => statuses.includes(t.cleared.toLowerCase()));\n }\n\n if (filters.minAmount !== undefined) {\n const minMilliunits = amountToMilliunits(filters.minAmount);\n filtered = filtered.filter(t => t.amount >= minMilliunits);\n }\n\n if (filters.maxAmount !== undefined) {\n const maxMilliunits = amountToMilliunits(filters.maxAmount);\n filtered = filtered.filter(t => t.amount <= maxMilliunits);\n }\n\n return filtered;\n}\n\nexport function applyFieldSelection<T>(items: T[], fields?: string): Partial<T>[] {\n if (!fields) return items;\n\n const fieldList = fields.split(',').map(f => f.trim());\n return items.map(item => {\n const filtered: Partial<T> = {};\n const itemRecord = item as Record<string, unknown>;\n fieldList.forEach(field => {\n if (field in itemRecord) {\n (filtered as Record<string, unknown>)[field] = itemRecord[field];\n }\n });\n return filtered;\n });\n}\n","import type { YnabError } from '../types/index.js';\nimport { outputJson } from './output.js';\n\nexport class YnabCliError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message);\n this.name = 'YnabCliError';\n }\n}\n\nconst ERROR_STATUS_CODES: Record<string, number> = {\n bad_request: 400,\n not_authorized: 401,\n subscription_lapsed: 403,\n trial_expired: 403,\n unauthorized_scope: 403,\n data_limit_reached: 403,\n not_found: 404,\n resource_not_found: 404,\n conflict: 409,\n too_many_requests: 429,\n internal_server_error: 500,\n service_unavailable: 503,\n};\n\nexport function sanitizeErrorMessage(message: string): string {\n const sensitivePatterns = [\n /Bearer\\s+[\\w\\-._~+/]+=*/gi,\n /token[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /api[_-]?key[=:]\\s*[\\w\\-._~+/]+=*/gi,\n /authorization:\\s*bearer\\s+[\\w\\-._~+/]+=*/gi,\n ];\n\n let sanitized = message;\n for (const pattern of sensitivePatterns) {\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n\n return sanitized.length > 500 ? sanitized.substring(0, 500) + '...' : sanitized;\n}\n\ninterface YnabApiError {\n name?: string;\n detail?: string;\n message?: string;\n id?: string;\n}\n\nfunction isErrorObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sanitizeApiError(error: unknown): YnabError {\n if (!isErrorObject(error)) {\n return {\n name: 'api_error',\n detail: 'An error occurred',\n id: undefined,\n };\n }\n\n const apiError = error as YnabApiError;\n const detail = sanitizeErrorMessage(\n String(apiError.detail || apiError.message || 'An error occurred')\n );\n\n return {\n name: apiError.name || 'api_error',\n detail,\n id: apiError.id,\n };\n}\n\nfunction enhanceRateLimitMessage(detail: string): string {\n return `${detail}\\n\\nYNAB API limit: 200 requests/hour (rolling window). Wait a few minutes and retry.`;\n}\n\nfunction formatErrorResponse(name: string, detail: string, statusCode: number): never {\n const enhancedDetail = name === 'too_many_requests'\n ? enhanceRateLimitMessage(detail)\n : detail;\n\n outputJson({ error: { name, detail: enhancedDetail, statusCode } });\n process.exit(1);\n}\n\nexport function handleYnabError(error: unknown): never {\n if (!isErrorObject(error)) {\n formatErrorResponse('unknown_error', 'An unexpected error occurred', 1);\n }\n\n const errorObj = error as { error?: unknown; message?: string };\n\n if (errorObj.error) {\n const ynabError: YnabError = sanitizeApiError(errorObj.error);\n formatErrorResponse(\n ynabError.name,\n ynabError.detail,\n ERROR_STATUS_CODES[ynabError.name] || 500,\n );\n }\n\n if (error instanceof YnabCliError) {\n const sanitized = sanitizeErrorMessage(error.message);\n formatErrorResponse('cli_error', sanitized, error.statusCode || 1);\n }\n\n const sanitized = sanitizeErrorMessage(errorObj.message || 'An unexpected error occurred');\n formatErrorResponse('unknown_error', sanitized, 1);\n}\n","import type { OutputOptions } from '../types/index.js';\nimport { convertMilliunitsToAmounts } from './utils.js';\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const convertedData = convertMilliunitsToAmounts(data);\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact\n ? JSON.stringify(convertedData)\n : JSON.stringify(convertedData, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { auth } from '../lib/auth.js';\nimport { promptForAccessToken } from '../lib/prompts.js';\nimport { outputJson } from '../lib/output.js';\nimport { client } from '../lib/api-client.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createAuthCommand(): Command {\n const cmd = new Command('auth').description('Authentication management');\n\n cmd\n .command('login')\n .description('Configure access token')\n .action(withErrorHandling(async () => {\n const token = await promptForAccessToken();\n await auth.setAccessToken(token);\n client.clearApi();\n\n try {\n const user = await client.getUser();\n outputJson({\n message: 'Successfully authenticated',\n user: { id: user?.id },\n });\n } catch (error) {\n await auth.deleteAccessToken();\n client.clearApi();\n throw error;\n }\n }));\n\n cmd\n .command('status')\n .description('Check authentication status')\n .action(withErrorHandling(async () => {\n const isAuthenticated = await auth.isAuthenticated();\n\n if (!isAuthenticated) {\n outputJson({ authenticated: false, message: 'Not authenticated' });\n return;\n }\n\n try {\n const user = await client.getUser();\n outputJson({ authenticated: true, user: { id: user?.id } });\n } catch (error) {\n outputJson({ authenticated: false, message: 'Token exists but is invalid' });\n }\n }));\n\n cmd\n .command('logout')\n .description('Remove stored credentials')\n .action(withErrorHandling(async () => {\n await auth.logout();\n client.clearApi();\n outputJson({ message: 'Successfully logged out' });\n }));\n\n return cmd;\n}\n","import { Entry } from '@napi-rs/keyring';\nimport { config } from './config.js';\n\nconst SERVICE_NAME = 'ynab-cli';\nconst ACCOUNT_NAME = 'access-token';\n\nconst KEYRING_UNAVAILABLE_ERROR =\n 'Keychain storage unavailable. Cannot store credentials securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'Then reinstall: npm install -g @stephendolan/ynab-cli\\n' +\n 'Alternatively, use the YNAB_API_KEY environment variable.';\n\nlet keyring: Entry | undefined;\n\ntry {\n keyring = new Entry(SERVICE_NAME, ACCOUNT_NAME);\n} catch (error) {\n if (process.env.NODE_ENV !== 'test') {\n console.error(\n 'Warning: Keychain storage unavailable. Credentials will not be stored securely.\\n' +\n 'On Linux, install libsecret: sudo apt-get install libsecret-1-dev\\n' +\n 'On macOS, ensure you have access to the system Keychain.\\n' +\n 'Falling back to environment variable only (YNAB_API_KEY).\\n'\n );\n }\n}\n\nexport class AuthManager {\n async getAccessToken(): Promise<string | null> {\n if (keyring) {\n try {\n return keyring.getPassword();\n } catch (error) {\n return null;\n }\n }\n return null;\n }\n\n async setAccessToken(token: string): Promise<void> {\n if (keyring) {\n keyring.setPassword(token);\n } else {\n throw new Error(KEYRING_UNAVAILABLE_ERROR);\n }\n }\n\n async deleteAccessToken(): Promise<boolean> {\n if (keyring) {\n return keyring.deletePassword();\n }\n return false;\n }\n\n async isAuthenticated(): Promise<boolean> {\n return (await this.getAccessToken()) !== null;\n }\n\n async logout(): Promise<void> {\n await this.deleteAccessToken();\n config.clearDefaultBudget();\n }\n}\n\nexport const auth = new AuthManager();\n","import Conf from 'conf';\nimport type { Config } from '../types/index.js';\n\nclass ConfigManager {\n private conf: Conf<Config>;\n\n constructor() {\n this.conf = new Conf<Config>({\n projectName: 'ynab-cli',\n schema: {\n defaultBudget: { type: 'string' },\n version: { type: 'string', default: '1.0.0' },\n },\n defaults: { version: '1.0.0' },\n });\n }\n\n getDefaultBudget(): string | undefined {\n return this.conf.get('defaultBudget');\n }\n\n setDefaultBudget(budgetId: string): void {\n this.conf.set('defaultBudget', budgetId);\n }\n\n clearDefaultBudget(): void {\n this.conf.delete('defaultBudget');\n }\n\n clear(): void {\n this.conf.clear();\n }\n}\n\nexport const config = new ConfigManager();\n","import inquirer from 'inquirer';\nimport { amountToMilliunits } from './utils.js';\n\nexport async function promptForAccessToken(): Promise<string> {\n const { token } = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: 'Enter your YNAB Personal Access Token:',\n validate: (input: string) => !!input.trim() || 'Access token is required',\n },\n ]);\n return token.trim();\n}\n\nexport async function promptForBudget(\n budgets: Array<{ id: string; name: string }>,\n): Promise<string> {\n const { budgetId } = await inquirer.prompt([\n {\n type: 'list',\n name: 'budgetId',\n message: 'Select a budget:',\n choices: budgets.map((b) => ({ name: b.name, value: b.id })),\n },\n ]);\n return budgetId;\n}\n\nexport async function promptForConfirmation(message: string): Promise<boolean> {\n const { confirmed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message,\n default: false,\n },\n ]);\n return confirmed;\n}\n\nexport async function promptForTransaction(): Promise<Record<string, unknown>> {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'date',\n message: 'Date (YYYY-MM-DD):',\n default: new Date().toISOString().split('T')[0],\n },\n {\n type: 'input',\n name: 'amount',\n message: 'Amount (in currency units, e.g., 10.50):',\n validate: (input: string) => !isNaN(parseFloat(input)) || 'Amount must be a valid number',\n },\n {\n type: 'input',\n name: 'payee_name',\n message: 'Payee name (optional):',\n },\n {\n type: 'input',\n name: 'memo',\n message: 'Memo (optional):',\n },\n ]);\n\n return {\n date: answers.date,\n amount: amountToMilliunits(parseFloat(answers.amount)),\n payee_name: answers.payee_name || undefined,\n memo: answers.memo || undefined,\n };\n}\n","import * as ynab from 'ynab';\nimport { config } from './config.js';\nimport { YnabCliError, handleYnabError, sanitizeApiError } from './errors.js';\nimport { auth } from './auth.js';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\ntype TransactionTypeFilter = 'uncategorized' | 'unapproved' | undefined;\n\nexport class YnabClient {\n private api: ynab.API | null = null;\n private envVarWarningShown = false;\n\n clearApi(): void {\n this.api = null;\n this.envVarWarningShown = false;\n }\n\n async getApi(): Promise<ynab.API> {\n if (this.api) {\n return this.api;\n }\n\n const keychainToken = await auth.getAccessToken();\n const accessToken = keychainToken || process.env.YNAB_API_KEY || null;\n\n if (!accessToken) {\n throw new YnabCliError(\n 'Not authenticated. Please run: ynab auth login or set YNAB_API_KEY environment variable',\n 401,\n );\n }\n\n if (!keychainToken && process.env.YNAB_API_KEY && !this.envVarWarningShown) {\n console.warn(\n '\\x1b[33m⚠️ WARNING: Using YNAB_API_KEY environment variable.\\n' +\n 'Environment variables may be visible to other processes.\\n' +\n 'For better security, use: ynab auth login\\x1b[0m\\n'\n );\n this.envVarWarningShown = true;\n }\n\n this.api = new ynab.API(accessToken);\n return this.api;\n }\n\n async getBudgetId(budgetIdOrDefault?: string): Promise<string> {\n const budgetId =\n budgetIdOrDefault || config.getDefaultBudget() || process.env.YNAB_BUDGET_ID;\n\n if (!budgetId) {\n throw new YnabCliError(\n 'No budget specified. Use --budget flag, set default with \"ynab budgets set-default\", or set YNAB_BUDGET_ID environment variable',\n 400,\n );\n }\n\n return budgetId;\n }\n\n private async withErrorHandling<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n handleYnabError(error);\n }\n }\n\n async getUser() {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const response = await api.user.getUser();\n return response.data.user;\n });\n }\n\n async getBudgets(includeAccounts = false) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const response = await api.budgets.getBudgets(includeAccounts);\n return {\n budgets: response.data.budgets,\n server_knowledge: 0,\n };\n });\n }\n\n async getBudget(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.budgets.getBudgetById(id, lastKnowledgeOfServer);\n return {\n budget: response.data.budget,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getBudgetSettings(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.budgets.getBudgetSettingsById(id);\n return response.data.settings;\n });\n }\n\n async getAccounts(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.getAccounts(id, lastKnowledgeOfServer);\n return {\n accounts: response.data.accounts,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getAccount(accountId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.getAccountById(id, accountId);\n return response.data.account;\n });\n }\n\n async createAccount(accountData: ynab.PostAccountWrapper, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.accounts.createAccount(id, accountData);\n return response.data.account;\n });\n }\n\n async getCategories(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getCategories(id, lastKnowledgeOfServer);\n return {\n category_groups: response.data.category_groups,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getCategory(categoryId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getCategoryById(id, categoryId);\n return response.data.category;\n });\n }\n\n async updateCategory(\n categoryId: string,\n data: ynab.PatchCategoryWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.updateCategory(id, categoryId, data);\n return response.data.category;\n });\n }\n\n async getMonthCategory(month: string, categoryId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.getMonthCategoryById(id, month, categoryId);\n return response.data.category;\n });\n }\n\n async updateMonthCategory(\n month: string,\n categoryId: string,\n data: ynab.PatchMonthCategoryWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.categories.updateMonthCategory(id, month, categoryId, data);\n return response.data.category;\n });\n }\n\n async getPayees(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.getPayees(id, lastKnowledgeOfServer);\n return {\n payees: response.data.payees,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getPayee(payeeId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.getPayeeById(id, payeeId);\n return response.data.payee;\n });\n }\n\n async updatePayee(payeeId: string, data: ynab.PatchPayeeWrapper, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payees.updatePayee(id, payeeId, data);\n return response.data.payee;\n });\n }\n\n async getPayeeLocations(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocations(id);\n return response.data.payee_locations;\n });\n }\n\n async getPayeeLocation(payeeLocationId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocationById(id, payeeLocationId);\n return response.data.payee_location;\n });\n }\n\n async getPayeeLocationsByPayee(payeeId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.payeeLocations.getPayeeLocationsByPayee(id, payeeId);\n return response.data.payee_locations;\n });\n }\n\n async getBudgetMonths(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.months.getBudgetMonths(id, lastKnowledgeOfServer);\n return {\n months: response.data.months,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getBudgetMonth(month: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.months.getBudgetMonth(id, month);\n return response.data.month;\n });\n }\n\n async getTransactions(params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactions(\n id,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByAccount(accountId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByAccount(\n id,\n accountId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByCategory(categoryId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByCategory(\n id,\n categoryId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransactionsByPayee(payeeId: string, params: {\n budgetId?: string;\n sinceDate?: string;\n type?: string;\n lastKnowledgeOfServer?: number;\n }) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(params.budgetId);\n const response = await api.transactions.getTransactionsByPayee(\n id,\n payeeId,\n params.sinceDate,\n params.type as TransactionTypeFilter,\n params.lastKnowledgeOfServer,\n );\n return {\n transactions: response.data.transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getTransaction(transactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.getTransactionById(id, transactionId);\n return response.data.transaction;\n });\n }\n\n async createTransaction(\n transactionData: ynab.PostTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.createTransaction(id, transactionData);\n return response.data.transaction;\n });\n }\n\n async createTransactions(\n transactionsData: ynab.PostTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.createTransactions(id, transactionsData);\n return response.data;\n });\n }\n\n async updateTransaction(\n transactionId: string,\n transactionData: ynab.PutTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.updateTransaction(\n id,\n transactionId,\n transactionData,\n );\n return response.data.transaction;\n });\n }\n\n async updateTransactions(\n transactionsData: ynab.PatchTransactionsWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.updateTransactions(id, transactionsData);\n return response.data;\n });\n }\n\n async deleteTransaction(transactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.deleteTransaction(id, transactionId);\n return response.data.transaction;\n });\n }\n\n async importTransactions(budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.transactions.importTransactions(id);\n return response.data.transaction_ids;\n });\n }\n\n async getScheduledTransactions(budgetId?: string, lastKnowledgeOfServer?: number) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.getScheduledTransactions(\n id,\n lastKnowledgeOfServer,\n );\n return {\n scheduled_transactions: response.data.scheduled_transactions,\n server_knowledge: response.data.server_knowledge,\n };\n });\n }\n\n async getScheduledTransaction(scheduledTransactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.getScheduledTransactionById(\n id,\n scheduledTransactionId,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async createScheduledTransaction(\n data: ynab.PostScheduledTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.createScheduledTransaction(id, data);\n return response.data.scheduled_transaction;\n });\n }\n\n async updateScheduledTransaction(\n scheduledTransactionId: string,\n data: ynab.PutScheduledTransactionWrapper,\n budgetId?: string,\n ) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.updateScheduledTransaction(\n id,\n scheduledTransactionId,\n data,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async deleteScheduledTransaction(scheduledTransactionId: string, budgetId?: string) {\n return this.withErrorHandling(async () => {\n const api = await this.getApi();\n const id = await this.getBudgetId(budgetId);\n const response = await api.scheduledTransactions.deleteScheduledTransaction(\n id,\n scheduledTransactionId,\n );\n return response.data.scheduled_transaction;\n });\n }\n\n async rawApiCall(method: string, path: string, data?: unknown, budgetId?: string) {\n return this.withErrorHandling(async () => {\n await this.getApi();\n\n const fullPath = path.includes('{budget_id}')\n ? path.replace('{budget_id}', await this.getBudgetId(budgetId))\n : path;\n\n const url = `https://api.ynab.com/v1${fullPath}`;\n const headers = {\n Authorization: `Bearer ${await auth.getAccessToken()}`,\n 'Content-Type': 'application/json',\n };\n\n const httpMethod = method.toUpperCase();\n const hasBody = ['POST', 'PUT', 'PATCH'].includes(httpMethod);\n\n if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(httpMethod)) {\n throw new YnabCliError(`Unsupported HTTP method: ${method}`, 400);\n }\n\n const response = await fetch(url, {\n method: httpMethod,\n headers,\n ...(hasBody && { body: JSON.stringify(data) }),\n });\n\n if (!response.ok) {\n const errorData = await response.json() as Record<string, unknown>;\n throw { error: sanitizeApiError(errorData.error || errorData) };\n }\n\n return await response.json();\n });\n }\n}\n\nexport const client = new YnabClient();\n","import { handleYnabError } from './errors.js';\nimport { promptForConfirmation } from './prompts.js';\nimport { isInteractive } from './utils.js';\nimport { outputJson } from './output.js';\n\nexport function withErrorHandling<TArgs extends unknown[], R>(\n fn: (...args: TArgs) => Promise<R>,\n): (...args: TArgs) => Promise<void> {\n return async (...args: TArgs) => {\n try {\n await fn(...args);\n } catch (error) {\n handleYnabError(error);\n }\n };\n}\n\nexport async function confirmDelete(\n itemType: string,\n skipConfirmation: boolean = false,\n): Promise<boolean> {\n if (skipConfirmation || !isInteractive()) {\n return true;\n }\n\n const confirmed = await promptForConfirmation(\n `Are you sure you want to delete this ${itemType}?`,\n );\n\n if (!confirmed) {\n outputJson({ message: 'Operation cancelled' });\n return false;\n }\n\n return true;\n}\n\nexport function buildUpdateObject<T>(\n options: T,\n mapping: Record<string, string>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const optionsRecord = options as Record<string, unknown>;\n\n for (const [optionKey, targetKey] of Object.entries(mapping)) {\n if (optionsRecord[optionKey] !== undefined) {\n result[targetKey] = optionsRecord[optionKey];\n }\n }\n\n return result;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createUserCommand(): Command {\n const cmd = new Command('user').description('User information');\n\n cmd\n .command('info')\n .description('Get authenticated user information')\n .action(withErrorHandling(async () => {\n const user = await client.getUser();\n outputJson(user);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { config } from '../lib/config.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\n\nexport function createBudgetsCommand(): Command {\n const cmd = new Command('budgets').description('Budget operations');\n\n cmd\n .command('list')\n .description('List all budgets')\n .option('--include-accounts', 'Include accounts in response')\n .action(withErrorHandling(async (options: { includeAccounts?: boolean }) => {\n const result = await client.getBudgets(options.includeAccounts);\n outputJson(result?.budgets);\n }));\n\n cmd\n .command('view')\n .description('View budget details (uses default if no id provided)')\n .argument('[id]', 'Budget ID')\n .action(withErrorHandling(async (id: string | undefined) => {\n const result = await client.getBudget(id);\n outputJson(result?.budget);\n }));\n\n cmd\n .command('settings')\n .description('View budget settings')\n .argument('[id]', 'Budget ID')\n .action(withErrorHandling(async (id: string | undefined) => {\n const settings = await client.getBudgetSettings(id);\n outputJson(settings);\n }));\n\n cmd\n .command('set-default')\n .description('Set default budget for commands')\n .argument('<id>', 'Budget ID')\n .action(withErrorHandling(async (id: string) => {\n const result = await client.getBudgets();\n const budget = result?.budgets.find((b) => b.id === id);\n\n if (!budget) {\n throw new YnabCliError(`Budget with ID ${id} not found`, 404);\n }\n\n config.setDefaultBudget(id);\n outputJson({\n message: 'Default budget set',\n budget: { id: budget.id, name: budget.name },\n });\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createAccountsCommand(): Command {\n const cmd = new Command('accounts').description('Account operations');\n\n cmd\n .command('list')\n .description('List all accounts')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (options: CommandOptions) => {\n const result = await client.getAccounts(options.budget);\n outputJson(result?.accounts);\n }));\n\n cmd\n .command('view')\n .description('View account details')\n .argument('<id>', 'Account ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const account = await client.getAccount(id, options.budget);\n outputJson(account);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for account')\n .argument('<id>', 'Account ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByAccount(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { amountToMilliunits } from '../lib/utils.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createCategoriesCommand(): Command {\n const cmd = new Command('categories').description('Category operations');\n\n cmd\n .command('list')\n .description('List all categories')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getCategories(options.budget, options.lastKnowledge);\n outputJson(result?.category_groups);\n }));\n\n cmd\n .command('view')\n .description('View category details')\n .argument('<id>', 'Category ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const category = await client.getCategory(id, options.budget);\n outputJson(category);\n }));\n\n cmd\n .command('budget')\n .description('Set category budgeted amount for a month (overrides existing amount)')\n .argument('<id>', 'Category ID')\n .requiredOption('--month <month>', 'Month in YYYY-MM-DD format (e.g., 2025-07-01)')\n .requiredOption('--amount <amount>', 'Total budgeted amount to set (e.g., 100.50)', parseFloat)\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (\n id: string,\n options: {\n month: string;\n amount: number;\n budget?: string;\n } & CommandOptions,\n ) => {\n if (isNaN(options.amount)) {\n throw new YnabCliError('Amount must be a valid number', 400);\n }\n\n const milliunits = amountToMilliunits(options.amount);\n const category = await client.updateMonthCategory(\n options.month,\n id,\n { category: { budgeted: milliunits } },\n options.budget,\n );\n outputJson(category);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for category')\n .argument('<id>', 'Category ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n lastKnowledge?: number;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByCategory(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n lastKnowledgeOfServer: options.lastKnowledge,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { promptForTransaction } from '../lib/prompts.js';\nimport { isInteractive, amountToMilliunits, applyTransactionFilters, applyFieldSelection, type TransactionLike } from '../lib/utils.js';\nimport { withErrorHandling, confirmDelete, buildUpdateObject } from '../lib/command-utils.js';\nimport { validateJson, TransactionSplitSchema } from '../lib/schemas.js';\nimport type { CommandOptions } from '../types/index.js';\n\ninterface TransactionOptions {\n account?: string;\n date?: string;\n amount?: number;\n payeeName?: string;\n payeeId?: string;\n categoryId?: string;\n memo?: string;\n cleared?: string;\n approved?: boolean;\n}\n\nfunction buildTransactionData(options: TransactionOptions): Record<string, unknown> {\n if (!options.account) {\n throw new YnabCliError('--account is required in non-interactive mode', 400);\n }\n if (options.amount === undefined) {\n throw new YnabCliError('--amount is required in non-interactive mode', 400);\n }\n\n return {\n account_id: options.account,\n date: options.date || new Date().toISOString().split('T')[0],\n amount: amountToMilliunits(options.amount),\n payee_name: options.payeeName,\n payee_id: options.payeeId,\n category_id: options.categoryId,\n memo: options.memo,\n cleared: options.cleared,\n approved: options.approved,\n };\n}\n\nexport function createTransactionsCommand(): Command {\n const cmd = new Command('transactions').description('Transaction operations');\n\n cmd\n .command('list')\n .description('List transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Filter by account ID')\n .option('--category <id>', 'Filter by category ID')\n .option('--payee <id>', 'Filter by payee ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--until <date>', 'Filter transactions until date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--approved <value>', 'Filter by approval status: true or false')\n .option('--status <statuses>', 'Filter by cleared status: cleared, uncleared, reconciled (comma-separated for multiple)')\n .option('--min-amount <amount>', 'Minimum amount in currency units (e.g., 10.50)', parseFloat)\n .option('--max-amount <amount>', 'Maximum amount in currency units (e.g., 100.00)', parseFloat)\n .option('--fields <fields>', 'Comma-separated list of fields to include (e.g., id,date,amount,memo)')\n .action(withErrorHandling(async (options: {\n budget?: string;\n account?: string;\n category?: string;\n payee?: string;\n since?: string;\n until?: string;\n type?: string;\n approved?: string;\n status?: string;\n minAmount?: number;\n maxAmount?: number;\n fields?: string;\n } & CommandOptions) => {\n const params = {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n };\n\n const result = options.account\n ? await client.getTransactionsByAccount(options.account, params)\n : options.category\n ? await client.getTransactionsByCategory(options.category, params)\n : options.payee\n ? await client.getTransactionsByPayee(options.payee, params)\n : await client.getTransactions(params);\n\n const transactions = result?.transactions || [];\n\n const filtered = applyTransactionFilters(transactions as TransactionLike[], {\n until: options.until,\n approved: options.approved,\n status: options.status,\n minAmount: options.minAmount,\n maxAmount: options.maxAmount,\n });\n\n const selected = applyFieldSelection(filtered, options.fields);\n\n outputJson(selected);\n }));\n\n cmd\n .command('view')\n .description('View single transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const transaction = await client.getTransaction(id, options.budget);\n outputJson(transaction);\n }));\n\n cmd\n .command('create')\n .description('Create transaction')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Account ID')\n .option('--date <date>', 'Date (YYYY-MM-DD)')\n .option('--amount <amount>', 'Amount in currency units (e.g., 10.50)', parseFloat)\n .option('--payee-name <name>', 'Payee name')\n .option('--payee-id <id>', 'Payee ID')\n .option('--category-id <id>', 'Category ID')\n .option('--memo <memo>', 'Memo')\n .option('--cleared <status>', 'Cleared status (cleared, uncleared, reconciled)')\n .option('--approved', 'Mark as approved')\n .action(withErrorHandling(async (options: {\n budget?: string;\n account?: string;\n date?: string;\n amount?: number;\n payeeName?: string;\n payeeId?: string;\n categoryId?: string;\n memo?: string;\n cleared?: string;\n approved?: boolean;\n } & CommandOptions) => {\n const shouldPrompt = isInteractive() && !options.amount;\n if (shouldPrompt && !options.account) {\n throw new YnabCliError('--account is required. Interactive mode cannot auto-select an account.', 400);\n }\n const transactionData = shouldPrompt\n ? { ...(await promptForTransaction()), account_id: options.account }\n : buildTransactionData(options);\n\n const transaction = await client.createTransaction(\n { transaction: transactionData },\n options.budget,\n );\n outputJson(transaction);\n }));\n\n cmd\n .command('update')\n .description('Update transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--account <id>', 'Account ID')\n .option('--date <date>', 'Date (YYYY-MM-DD)')\n .option('--amount <amount>', 'Amount in currency units', parseFloat)\n .option('--payee-name <name>', 'Payee name')\n .option('--payee-id <id>', 'Payee ID')\n .option('--category-id <id>', 'Category ID')\n .option('--memo <memo>', 'Memo')\n .option('--cleared <status>', 'Cleared status')\n .option('--approved', 'Mark as approved')\n .action(withErrorHandling(async (\n id: string,\n options: TransactionOptions & { budget?: string } & CommandOptions,\n ) => {\n const transactionData = buildUpdateObject(options, {\n account: 'account_id',\n date: 'date',\n payeeName: 'payee_name',\n payeeId: 'payee_id',\n categoryId: 'category_id',\n memo: 'memo',\n cleared: 'cleared',\n approved: 'approved',\n });\n\n if (options.amount !== undefined) {\n transactionData.amount = amountToMilliunits(options.amount);\n }\n\n const transaction = await client.updateTransaction(\n id,\n { transaction: transactionData },\n options.budget,\n );\n outputJson(transaction);\n }));\n\n cmd\n .command('delete')\n .description('Delete transaction')\n .argument('<id>', 'Transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(withErrorHandling(async (id: string, options: { budget?: string; yes?: boolean } & CommandOptions) => {\n if (!await confirmDelete('transaction', options.yes)) {\n return;\n }\n\n const transaction = await client.deleteTransaction(id, options.budget);\n outputJson({ message: 'Transaction deleted', transaction });\n }));\n\n cmd\n .command('import')\n .description('Import transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (options: CommandOptions) => {\n const transactionIds = await client.importTransactions(options.budget);\n outputJson({ transaction_ids: transactionIds });\n }));\n\n cmd\n .command('split')\n .description('Split transaction into multiple categories. Amounts should be in dollars (e.g., 10.50).')\n .argument('<id>', 'Transaction ID')\n .requiredOption('--splits <json>', 'JSON array of splits with dollar amounts: [{\"amount\": -21.40, \"category_id\": \"xxx\", \"memo\": \"...\"}]')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-f, --force', 'Force update of already-split transactions by deleting and recreating')\n .action(withErrorHandling(async (\n id: string,\n options: { splits: string; budget?: string; force?: boolean } & CommandOptions,\n ) => {\n let parsedSplits;\n try {\n parsedSplits = JSON.parse(options.splits);\n } catch (error) {\n throw new YnabCliError('Invalid JSON in --splits parameter', 400);\n }\n\n const splits = validateJson(parsedSplits, TransactionSplitSchema, 'transaction splits');\n\n const splitsInMilliunits = splits.map(split => ({\n ...split,\n amount: amountToMilliunits(split.amount),\n }));\n\n const existingTransaction = await client.getTransaction(id, options.budget);\n const isAlreadySplit = existingTransaction.subtransactions && existingTransaction.subtransactions.length > 0;\n\n if (isAlreadySplit && !options.force) {\n throw new YnabCliError(\n 'Transaction is already split. YNAB API does not support updating split transactions. ' +\n 'Use --force to delete and recreate the transaction with new splits.',\n 400\n );\n }\n\n if (isAlreadySplit) {\n await client.deleteTransaction(id, options.budget);\n\n const recreatedTransaction = await client.createTransaction(\n {\n transaction: {\n account_id: existingTransaction.account_id,\n date: existingTransaction.date,\n amount: existingTransaction.amount,\n payee_id: existingTransaction.payee_id,\n payee_name: existingTransaction.payee_name,\n category_id: null,\n memo: existingTransaction.memo,\n cleared: existingTransaction.cleared,\n approved: existingTransaction.approved,\n flag_color: existingTransaction.flag_color,\n subtransactions: splitsInMilliunits,\n },\n },\n options.budget,\n );\n outputJson(recreatedTransaction);\n } else {\n const transaction = await client.updateTransaction(\n id,\n {\n transaction: {\n category_id: null,\n subtransactions: splitsInMilliunits,\n },\n },\n options.budget,\n );\n outputJson(transaction);\n }\n }));\n\n cmd\n .command('search')\n .description('Search transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--memo <text>', 'Search in memo field')\n .option('--payee-name <name>', 'Search in payee name')\n .option('--amount <amount>', 'Search for exact amount in currency units', parseFloat)\n .option('--since <date>', 'Search transactions since date (YYYY-MM-DD)')\n .option('--until <date>', 'Search transactions until date (YYYY-MM-DD)')\n .option('--approved <value>', 'Filter by approval status: true or false')\n .option('--status <statuses>', 'Filter by cleared status: cleared, uncleared, reconciled (comma-separated)')\n .option('--fields <fields>', 'Comma-separated list of fields to include')\n .action(withErrorHandling(async (options: {\n budget?: string;\n memo?: string;\n payeeName?: string;\n amount?: number;\n since?: string;\n until?: string;\n approved?: string;\n status?: string;\n fields?: string;\n } & CommandOptions) => {\n if (!options.memo && !options.payeeName && options.amount === undefined) {\n throw new YnabCliError('At least one search criteria required: --memo, --payee-name, or --amount', 400);\n }\n\n const params = {\n budgetId: options.budget,\n sinceDate: options.since,\n };\n\n const result = await client.getTransactions(params);\n let transactions = result?.transactions || [];\n\n if (options.memo) {\n const searchTerm = options.memo.toLowerCase();\n transactions = transactions.filter(t =>\n t.memo?.toLowerCase().includes(searchTerm)\n );\n }\n\n if (options.payeeName) {\n const searchTerm = options.payeeName.toLowerCase();\n transactions = transactions.filter(t =>\n t.payee_name?.toLowerCase().includes(searchTerm)\n );\n }\n\n if (options.amount !== undefined) {\n const amountMilliunits = amountToMilliunits(options.amount);\n transactions = transactions.filter(t => t.amount === amountMilliunits);\n }\n\n transactions = applyTransactionFilters(transactions, {\n until: options.until,\n approved: options.approved,\n status: options.status,\n });\n\n const filteredTransactions = applyFieldSelection(transactions, options.fields);\n\n outputJson(filteredTransactions);\n }));\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { YnabCliError } from './errors.js';\n\nexport const TransactionSplitSchema = z.array(\n z.object({\n amount: z.number(),\n category_id: z.string().nullable().optional(),\n memo: z.string().optional(),\n payee_id: z.string().optional(),\n })\n);\n\nexport const ApiDataSchema = z.record(z.any());\n\nexport function validateJson<T>(\n data: unknown,\n schema: z.ZodSchema<T>,\n fieldName: string\n): T {\n try {\n return schema.parse(data);\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues\n .map(i => `${i.path.join('.')}: ${i.message}`)\n .join(', ');\n throw new YnabCliError(`Invalid ${fieldName}: ${issues}`, 400);\n }\n throw error;\n }\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling, confirmDelete } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createScheduledCommand(): Command {\n const cmd = new Command('scheduled').description('Scheduled transaction operations');\n\n cmd\n .command('list')\n .description('List all scheduled transactions')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getScheduledTransactions(options.budget, options.lastKnowledge);\n outputJson(result?.scheduled_transactions);\n }));\n\n cmd\n .command('view')\n .description('View scheduled transaction')\n .argument('<id>', 'Scheduled transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const scheduledTransaction = await client.getScheduledTransaction(id, options.budget);\n outputJson(scheduledTransaction);\n }));\n\n cmd\n .command('delete')\n .description('Delete scheduled transaction')\n .argument('<id>', 'Scheduled transaction ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('-y, --yes', 'Skip confirmation')\n .action(withErrorHandling(async (id: string, options: { budget?: string; yes?: boolean } & CommandOptions) => {\n if (!await confirmDelete('scheduled transaction', options.yes)) {\n return;\n }\n\n const scheduledTransaction = await client.deleteScheduledTransaction(id, options.budget);\n outputJson({\n message: 'Scheduled transaction deleted',\n scheduled_transaction: scheduledTransaction,\n });\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createPayeesCommand(): Command {\n const cmd = new Command('payees').description('Payee operations');\n\n cmd\n .command('list')\n .description('List all payees')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getPayees(options.budget, options.lastKnowledge);\n outputJson(result?.payees);\n }));\n\n cmd\n .command('view')\n .description('View payee details')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const payee = await client.getPayee(id, options.budget);\n outputJson(payee);\n }));\n\n cmd\n .command('update')\n .description('Rename payee')\n .argument('<id>', 'Payee ID')\n .requiredOption('--name <name>', 'New payee name')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: { name: string; budget?: string } & CommandOptions) => {\n if (!options.name?.trim()) {\n throw new YnabCliError('Name cannot be empty', 400);\n }\n\n const payee = await client.updatePayee(\n id,\n { payee: { name: options.name } },\n options.budget,\n );\n outputJson(payee);\n }));\n\n cmd\n .command('locations')\n .description('List locations for payee')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (id: string, options: CommandOptions) => {\n const locations = await client.getPayeeLocationsByPayee(id, options.budget);\n outputJson(locations);\n }));\n\n cmd\n .command('transactions')\n .description('List transactions for payee')\n .argument('<id>', 'Payee ID')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--since <date>', 'Filter transactions since date (YYYY-MM-DD)')\n .option('--type <type>', 'Filter by transaction type')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (\n id: string,\n options: {\n budget?: string;\n since?: string;\n type?: string;\n lastKnowledge?: number;\n } & CommandOptions,\n ) => {\n const result = await client.getTransactionsByPayee(id, {\n budgetId: options.budget,\n sinceDate: options.since,\n type: options.type,\n lastKnowledgeOfServer: options.lastKnowledge,\n });\n outputJson(result?.transactions);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport type { CommandOptions } from '../types/index.js';\n\nexport function createMonthsCommand(): Command {\n const cmd = new Command('months').description('Monthly budget operations');\n\n cmd\n .command('list')\n .description('List all budget months')\n .option('-b, --budget <id>', 'Budget ID')\n .option('--last-knowledge <number>', 'Last knowledge of server', parseInt)\n .action(withErrorHandling(async (options: { budget?: string; lastKnowledge?: number } & CommandOptions) => {\n const result = await client.getBudgetMonths(options.budget, options.lastKnowledge);\n outputJson(result?.months);\n }));\n\n cmd\n .command('view')\n .description('View specific month details')\n .argument('<month>', 'Month in YYYY-MM-DD format (e.g., 2025-07-01)')\n .option('-b, --budget <id>', 'Budget ID')\n .action(withErrorHandling(async (month: string, options: CommandOptions) => {\n const monthData = await client.getBudgetMonth(month, options.budget);\n outputJson(monthData);\n }));\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { client } from '../lib/api-client.js';\nimport { outputJson } from '../lib/output.js';\nimport { YnabCliError } from '../lib/errors.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { validateJson, ApiDataSchema } from '../lib/schemas.js';\nimport type { CommandOptions } from '../types/index.js';\n\nconst VALID_HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];\n\nexport function createApiCommand(): Command {\n const cmd = new Command('api').description('Raw API access');\n\n cmd\n .argument('<method>', 'HTTP method (GET, POST, PUT, PATCH, DELETE)')\n .argument('<path>', 'API path (e.g., /budgets or /budgets/{budget_id}/transactions)')\n .option('-b, --budget <id>', 'Budget ID (used to replace {budget_id} in path)')\n .option('--data <json>', 'JSON data for POST/PUT/PATCH requests')\n .description('Make raw API calls to YNAB')\n .action(withErrorHandling(async (\n method: string,\n path: string,\n options: { budget?: string; data?: string } & CommandOptions,\n ) => {\n const upperMethod = method.toUpperCase();\n\n if (!VALID_HTTP_METHODS.includes(upperMethod)) {\n throw new YnabCliError(\n `Invalid HTTP method: ${method}. Must be one of: ${VALID_HTTP_METHODS.join(', ')}`,\n 400,\n );\n }\n\n let data: Record<string, unknown> | undefined;\n if (options.data) {\n try {\n const parsedData = JSON.parse(options.data);\n data = validateJson(parsedData, ApiDataSchema, 'API data');\n } catch (error) {\n throw new YnabCliError('Invalid JSON in --data parameter', 400);\n }\n }\n\n const result = await client.rawApiCall(upperMethod, path, data, options.budget);\n outputJson(result);\n }));\n\n return cmd;\n}\n"],"mappings":"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","names":["Command","sanitized","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stephendolan/ynab-cli",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A command-line interface for You Need a Budget (YNAB)",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",