freee-demo-kit 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +35 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/auth.d.ts +3 -0
  8. package/dist/commands/auth.d.ts.map +1 -0
  9. package/dist/commands/auth.js +57 -0
  10. package/dist/commands/auth.js.map +1 -0
  11. package/dist/commands/corrupt.d.ts +3 -0
  12. package/dist/commands/corrupt.d.ts.map +1 -0
  13. package/dist/commands/corrupt.js +72 -0
  14. package/dist/commands/corrupt.js.map +1 -0
  15. package/dist/commands/dry-run.d.ts +3 -0
  16. package/dist/commands/dry-run.d.ts.map +1 -0
  17. package/dist/commands/dry-run.js +59 -0
  18. package/dist/commands/dry-run.js.map +1 -0
  19. package/dist/commands/list.d.ts +3 -0
  20. package/dist/commands/list.d.ts.map +1 -0
  21. package/dist/commands/list.js +58 -0
  22. package/dist/commands/list.js.map +1 -0
  23. package/dist/commands/load-all.d.ts +3 -0
  24. package/dist/commands/load-all.d.ts.map +1 -0
  25. package/dist/commands/load-all.js +69 -0
  26. package/dist/commands/load-all.js.map +1 -0
  27. package/dist/commands/load.d.ts +25 -0
  28. package/dist/commands/load.d.ts.map +1 -0
  29. package/dist/commands/load.js +197 -0
  30. package/dist/commands/load.js.map +1 -0
  31. package/dist/commands/reset.d.ts +3 -0
  32. package/dist/commands/reset.d.ts.map +1 -0
  33. package/dist/commands/reset.js +117 -0
  34. package/dist/commands/reset.js.map +1 -0
  35. package/dist/commands/setup.d.ts +4 -0
  36. package/dist/commands/setup.d.ts.map +1 -0
  37. package/dist/commands/setup.js +190 -0
  38. package/dist/commands/setup.js.map +1 -0
  39. package/dist/commands/status.d.ts +3 -0
  40. package/dist/commands/status.d.ts.map +1 -0
  41. package/dist/commands/status.js +25 -0
  42. package/dist/commands/status.js.map +1 -0
  43. package/dist/commands/validate.d.ts +5 -0
  44. package/dist/commands/validate.d.ts.map +1 -0
  45. package/dist/commands/validate.js +132 -0
  46. package/dist/commands/validate.js.map +1 -0
  47. package/dist/commands/verify.d.ts +3 -0
  48. package/dist/commands/verify.d.ts.map +1 -0
  49. package/dist/commands/verify.js +87 -0
  50. package/dist/commands/verify.js.map +1 -0
  51. package/dist/commands/whoami.d.ts +3 -0
  52. package/dist/commands/whoami.d.ts.map +1 -0
  53. package/dist/commands/whoami.js +31 -0
  54. package/dist/commands/whoami.js.map +1 -0
  55. package/dist/types/freee.d.ts +112 -0
  56. package/dist/types/freee.d.ts.map +1 -0
  57. package/dist/types/freee.js +3 -0
  58. package/dist/types/freee.js.map +1 -0
  59. package/dist/types/preset.d.ts +14 -0
  60. package/dist/types/preset.d.ts.map +1 -0
  61. package/dist/types/preset.js +2 -0
  62. package/dist/types/preset.js.map +1 -0
  63. package/dist/utils/accounting-validator.d.ts +13 -0
  64. package/dist/utils/accounting-validator.d.ts.map +1 -0
  65. package/dist/utils/accounting-validator.js +95 -0
  66. package/dist/utils/accounting-validator.js.map +1 -0
  67. package/dist/utils/auth-flow.d.ts +17 -0
  68. package/dist/utils/auth-flow.d.ts.map +1 -0
  69. package/dist/utils/auth-flow.js +137 -0
  70. package/dist/utils/auth-flow.js.map +1 -0
  71. package/dist/utils/config.d.ts +11 -0
  72. package/dist/utils/config.d.ts.map +1 -0
  73. package/dist/utils/config.js +13 -0
  74. package/dist/utils/config.js.map +1 -0
  75. package/dist/utils/confirm-company.d.ts +7 -0
  76. package/dist/utils/confirm-company.d.ts.map +1 -0
  77. package/dist/utils/confirm-company.js +20 -0
  78. package/dist/utils/confirm-company.js.map +1 -0
  79. package/dist/utils/corrupt-injector.d.ts +17 -0
  80. package/dist/utils/corrupt-injector.d.ts.map +1 -0
  81. package/dist/utils/corrupt-injector.js +123 -0
  82. package/dist/utils/corrupt-injector.js.map +1 -0
  83. package/dist/utils/env-loader.d.ts +9 -0
  84. package/dist/utils/env-loader.d.ts.map +1 -0
  85. package/dist/utils/env-loader.js +12 -0
  86. package/dist/utils/env-loader.js.map +1 -0
  87. package/dist/utils/env-writer.d.ts +10 -0
  88. package/dist/utils/env-writer.d.ts.map +1 -0
  89. package/dist/utils/env-writer.js +40 -0
  90. package/dist/utils/env-writer.js.map +1 -0
  91. package/dist/utils/freee-api.d.ts +24 -0
  92. package/dist/utils/freee-api.d.ts.map +1 -0
  93. package/dist/utils/freee-api.js +175 -0
  94. package/dist/utils/freee-api.js.map +1 -0
  95. package/dist/utils/logger.d.ts +6 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +22 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/pkce.d.ts +12 -0
  100. package/dist/utils/pkce.d.ts.map +1 -0
  101. package/dist/utils/pkce.js +18 -0
  102. package/dist/utils/pkce.js.map +1 -0
  103. package/dist/utils/preset-loader.d.ts +3 -0
  104. package/dist/utils/preset-loader.d.ts.map +1 -0
  105. package/dist/utils/preset-loader.js +47 -0
  106. package/dist/utils/preset-loader.js.map +1 -0
  107. package/dist/utils/preset-validator.d.ts +10 -0
  108. package/dist/utils/preset-validator.d.ts.map +1 -0
  109. package/dist/utils/preset-validator.js +23 -0
  110. package/dist/utils/preset-validator.js.map +1 -0
  111. package/dist/utils/state-store.d.ts +6 -0
  112. package/dist/utils/state-store.d.ts.map +1 -0
  113. package/dist/utils/state-store.js +37 -0
  114. package/dist/utils/state-store.js.map +1 -0
  115. package/dist/utils/token-store.d.ts +6 -0
  116. package/dist/utils/token-store.d.ts.map +1 -0
  117. package/dist/utils/token-store.js +30 -0
  118. package/dist/utils/token-store.js.map +1 -0
  119. package/package.json +58 -0
  120. package/presets/README.md +182 -0
  121. package/presets/accounting/README.md +3 -0
  122. package/presets/accounting/construction/preset.json +309 -0
  123. package/presets/accounting/freelance-invoice/preset.json +261 -0
  124. package/presets/accounting/full-year/preset.json +1534 -0
  125. package/presets/accounting/it-startup/preset.json +472 -0
  126. package/presets/accounting/manufacturing/preset.json +333 -0
  127. package/presets/accounting/medical/preset.json +453 -0
  128. package/presets/accounting/non-profit/preset.json +375 -0
  129. package/presets/accounting/npo-subsidy/preset.json +454 -0
  130. package/presets/accounting/payroll-agency/preset.json +286 -0
  131. package/presets/accounting/quickstart/preset.json +917 -0
  132. package/presets/accounting/real-estate/preset.json +453 -0
  133. package/presets/accounting/restaurant/preset.json +349 -0
  134. package/presets/accounting/retail/preset.json +536 -0
  135. package/presets/accounting/sole-proprietor/preset.json +408 -0
  136. package/presets/advanced/multi-company/README.md +3 -0
  137. package/presets/advanced/multi-company/preset.json +640 -0
  138. package/presets/advanced/multi-period/README.md +3 -0
  139. package/presets/advanced/multi-period/preset.json +633 -0
  140. package/presets/common/depreciation/preset.json +433 -0
  141. package/presets/errors/consumption-tax/preset.json +136 -0
  142. package/presets/errors/depreciation-method/preset.json +133 -0
  143. package/presets/errors/duplicate-journal/preset.json +181 -0
  144. package/presets/errors/entertainment/preset.json +108 -0
  145. package/presets/errors/mixed/preset.json +171 -0
  146. package/presets/errors/officer-pay/preset.json +100 -0
  147. package/presets/errors/overdue-receivable/preset.json +157 -0
  148. package/presets/errors/tax-code/preset.json +140 -0
  149. package/presets/errors/year-end-closing/preset.json +163 -0
  150. package/presets/expenses/README.md +3 -0
  151. package/presets/expenses/quickstart/preset.json +240 -0
  152. package/presets/hr/README.md +3 -0
  153. package/presets/hr/quickstart/preset.json +443 -0
  154. package/presets/invoices/README.md +3 -0
  155. package/presets/invoices/quickstart/preset.json +246 -0
  156. package/presets/invoices/subscription/preset.json +263 -0
  157. package/presets/unclassified/quickstart/preset.json +182 -0
@@ -0,0 +1,123 @@
1
+ const OFFICER_KEYWORDS = ['取締役', '役員', '監査役'];
2
+ // 各科目で注入するエラー税区分(正しい値と逆を設定)
3
+ const TAX_CODE_INJECT = {
4
+ '役員報酬': 34, // 正: 0 → 誤: 34
5
+ '給料手当': 34, // 正: 0 → 誤: 34
6
+ '外注費': 0, // 正: 34 → 誤: 0
7
+ '売上高': 0, // 正: 21 → 誤: 0
8
+ };
9
+ /** ディープクローン */
10
+ function deepClone(obj) {
11
+ return JSON.parse(JSON.stringify(obj));
12
+ }
13
+ /** OFFICER-PAY-001: 役員報酬 → 給料手当 に置換 */
14
+ export function injectOfficerPay(preset) {
15
+ const cloned = deepClone(preset);
16
+ const manifest = [];
17
+ for (const deal of cloned.data.deals) {
18
+ const partnerName = deal.partner_name ?? '';
19
+ const isOfficer = OFFICER_KEYWORDS.some(kw => partnerName.includes(kw));
20
+ if (!isOfficer)
21
+ continue;
22
+ for (const detail of deal.details) {
23
+ if (detail.account_item_name === '役員報酬') {
24
+ detail.account_item_name = '給料手当';
25
+ manifest.push({
26
+ rule: 'OFFICER-PAY-001',
27
+ location: `${deal.issue_date} ${partnerName}`,
28
+ description: '役員報酬を「給料手当」に誤計上',
29
+ expected_fix: '「役員報酬」科目に変更してください',
30
+ });
31
+ }
32
+ }
33
+ }
34
+ return { preset: cloned, manifest };
35
+ }
36
+ /** TAX-CODE-001: 対象科目の税区分を誤った値に置換 */
37
+ export function injectTaxCode(preset) {
38
+ const cloned = deepClone(preset);
39
+ const manifest = [];
40
+ for (const deal of cloned.data.deals) {
41
+ for (const detail of deal.details) {
42
+ const name = detail.account_item_name;
43
+ if (!name || !(name in TAX_CODE_INJECT))
44
+ continue;
45
+ const wrongCode = TAX_CODE_INJECT[name];
46
+ if (detail.tax_code !== wrongCode) {
47
+ detail.tax_code = wrongCode;
48
+ manifest.push({
49
+ rule: 'TAX-CODE-001',
50
+ location: `${deal.issue_date} 勘定科目「${name}」`,
51
+ description: `tax_code を ${wrongCode} に誤設定`,
52
+ expected_fix: '正しい税区分に変更してください',
53
+ });
54
+ }
55
+ }
56
+ }
57
+ return { preset: cloned, manifest };
58
+ }
59
+ const ENTERTAINMENT_LIMIT = 667000;
60
+ const ENTERTAINMENT_TARGET = 750000; // 注入後の目標月合計
61
+ /** ENTERTAINMENT-001: 交際費の月合計が 667,000 超になるよう増幅 */
62
+ export function injectEntertainment(preset) {
63
+ const cloned = deepClone(preset);
64
+ const manifest = [];
65
+ // 月ごとに交際費 deal を収集
66
+ const byMonth = new Map();
67
+ for (const deal of cloned.data.deals) {
68
+ const [year, month] = deal.issue_date.split('-');
69
+ const key = `${year}-${month}`;
70
+ const hasEntertainment = deal.details.some(d => d.account_item_name === '交際費');
71
+ if (!hasEntertainment)
72
+ continue;
73
+ if (!byMonth.has(key))
74
+ byMonth.set(key, []);
75
+ byMonth.get(key).push(deal);
76
+ }
77
+ for (const [monthKey, deals] of byMonth) {
78
+ const currentTotal = deals
79
+ .flatMap(d => d.details)
80
+ .filter(d => d.account_item_name === '交際費')
81
+ .reduce((sum, d) => sum + d.amount, 0);
82
+ if (currentTotal >= ENTERTAINMENT_LIMIT)
83
+ continue; // すでに超過していれば注入不要
84
+ // 最後の交際費 detail の amount を増加させて目標値に到達させる
85
+ const multiplier = Math.ceil(ENTERTAINMENT_TARGET / currentTotal);
86
+ for (const deal of deals) {
87
+ for (const detail of deal.details) {
88
+ if (detail.account_item_name === '交際費') {
89
+ detail.amount = detail.amount * multiplier;
90
+ }
91
+ }
92
+ }
93
+ const [year, month] = monthKey.split('-');
94
+ manifest.push({
95
+ rule: 'ENTERTAINMENT-001',
96
+ location: `${year}年${month}月 交際費`,
97
+ description: `交際費月合計を ¥667,000 超になるよう増幅(${multiplier}倍)`,
98
+ expected_fix: '交際費を分散するか月次上限内に収めてください',
99
+ });
100
+ }
101
+ return { preset: cloned, manifest };
102
+ }
103
+ /** 複数ルールを順次適用して CorruptResult を返す */
104
+ export function runCorrupt(preset, options) {
105
+ let current = deepClone(preset);
106
+ const allManifest = [];
107
+ for (const rule of options.rules) {
108
+ let result;
109
+ if (rule === 'officer-pay') {
110
+ result = injectOfficerPay(current);
111
+ }
112
+ else if (rule === 'tax-code') {
113
+ result = injectTaxCode(current);
114
+ }
115
+ else {
116
+ result = injectEntertainment(current);
117
+ }
118
+ current = result.preset;
119
+ allManifest.push(...result.manifest);
120
+ }
121
+ return { preset: current, manifest: allManifest };
122
+ }
123
+ //# sourceMappingURL=corrupt-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corrupt-injector.js","sourceRoot":"","sources":["../../src/utils/corrupt-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * .env ファイルを読み込み、process.env に設定する。
3
+ * ファイルが存在しない場合はエラーにならず、何もしない。
4
+ * 既に設定済みの環境変数は上書きしない(dotenv デフォルト動作)。
5
+ *
6
+ * @param path - 読み込む .env ファイルのパス(省略時はカレントディレクトリの .env)
7
+ */
8
+ export declare function loadEnv(path?: string): void;
9
+ //# sourceMappingURL=env-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-loader.d.ts","sourceRoot":"","sources":["../../src/utils/env-loader.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAE3C"}
@@ -0,0 +1,12 @@
1
+ import { config } from 'dotenv';
2
+ /**
3
+ * .env ファイルを読み込み、process.env に設定する。
4
+ * ファイルが存在しない場合はエラーにならず、何もしない。
5
+ * 既に設定済みの環境変数は上書きしない(dotenv デフォルト動作)。
6
+ *
7
+ * @param path - 読み込む .env ファイルのパス(省略時はカレントディレクトリの .env)
8
+ */
9
+ export function loadEnv(path) {
10
+ config({ path, override: false, quiet: true });
11
+ }
12
+ //# sourceMappingURL=env-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-loader.js","sourceRoot":"","sources":["../../src/utils/env-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,IAAa;IACnC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * .env に FREEE_CLIENT_ID と FREEE_CLIENT_SECRET が両方設定されているか確認する
3
+ */
4
+ export declare function hasCredentials(envPath?: string): Promise<boolean>;
5
+ /**
6
+ * FREEE_CLIENT_ID と FREEE_CLIENT_SECRET を .env に書き込む
7
+ * 既存ファイルがある場合は末尾に追記する
8
+ */
9
+ export declare function writeCredentials(clientId: string, clientSecret: string, envPath?: string): Promise<void>;
10
+ //# sourceMappingURL=env-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-writer.d.ts","sourceRoot":"","sources":["../../src/utils/env-writer.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE,MAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,CASzF;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,MAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -0,0 +1,40 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const DEFAULT_ENV_PATH = path.resolve(process.cwd(), '.env');
4
+ /**
5
+ * .env に FREEE_CLIENT_ID と FREEE_CLIENT_SECRET が両方設定されているか確認する
6
+ */
7
+ export async function hasCredentials(envPath = DEFAULT_ENV_PATH) {
8
+ try {
9
+ const content = await fs.readFile(envPath, 'utf-8');
10
+ const hasId = /^FREEE_CLIENT_ID=.+$/m.test(content);
11
+ const hasSecret = /^FREEE_CLIENT_SECRET=.+$/m.test(content);
12
+ return hasId && hasSecret;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ /**
19
+ * FREEE_CLIENT_ID と FREEE_CLIENT_SECRET を .env に書き込む
20
+ * 既存ファイルがある場合は末尾に追記する
21
+ */
22
+ export async function writeCredentials(clientId, clientSecret, envPath = DEFAULT_ENV_PATH) {
23
+ let existing = '';
24
+ try {
25
+ existing = await fs.readFile(envPath, 'utf-8');
26
+ }
27
+ catch {
28
+ // ファイルが存在しない場合は新規作成
29
+ }
30
+ const lines = [];
31
+ if (existing)
32
+ lines.push(existing.trimEnd());
33
+ lines.push(`FREEE_CLIENT_ID=${clientId}`);
34
+ lines.push(`FREEE_CLIENT_SECRET=${clientSecret}`);
35
+ await fs.writeFile(envPath, lines.join('\n') + '\n', {
36
+ encoding: 'utf-8',
37
+ mode: 0o600,
38
+ });
39
+ }
40
+ //# sourceMappingURL=env-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-writer.js","sourceRoot":"","sources":["../../src/utils/env-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB,gBAAgB;IACrE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5D,OAAO,KAAK,IAAI,SAAS,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,YAAoB,EACpB,UAAkB,gBAAgB;IAElC,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,oBAAoB;IACtB,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IAElD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE;QACnD,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { FreeeUser, FreeeCompany, FreeeWalletable, WalletableData, WalletableType, FreeeDeal, DealData, FreeeManualJournal, ManualJournalData, FreeeAccountItem, FreeeTax } from '../types/freee.js';
2
+ export declare class FreeeApiClient {
3
+ private getValidTokens;
4
+ private refreshTokens;
5
+ private request;
6
+ private requestPost;
7
+ private requestDelete;
8
+ getMe(): Promise<FreeeUser>;
9
+ getCompanies(): Promise<FreeeCompany[]>;
10
+ getCompany(companyId: number): Promise<FreeeCompany>;
11
+ getWalletables(companyId: number): Promise<FreeeWalletable[]>;
12
+ getDeals(companyId: number, params?: Record<string, string>): Promise<FreeeDeal[]>;
13
+ getAccountItems(companyId: number): Promise<FreeeAccountItem[]>;
14
+ getTaxes(companyId: number): Promise<FreeeTax[]>;
15
+ getTrialPl(companyId: number, params: Record<string, string>): Promise<unknown>;
16
+ getTrialBs(companyId: number, params: Record<string, string>): Promise<unknown>;
17
+ createWalletable(companyId: number, data: WalletableData): Promise<FreeeWalletable>;
18
+ deleteWalletable(companyId: number, id: number, type: WalletableType): Promise<void>;
19
+ createDeal(companyId: number, data: DealData): Promise<FreeeDeal>;
20
+ deleteDeal(companyId: number, id: number): Promise<void>;
21
+ createManualJournal(companyId: number, data: ManualJournalData): Promise<FreeeManualJournal>;
22
+ deleteManualJournal(companyId: number, id: number): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=freee-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freee-api.d.ts","sourceRoot":"","sources":["../../src/utils/freee-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,SAAS,EACT,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,EACT,MAAM,mBAAmB,CAAC;AAqB3B,qBAAa,cAAc;YACX,cAAc;YAad,aAAa;YAiDb,OAAO;YAkBP,WAAW;YAsBX,aAAa;IAkBrB,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC;IAK3B,YAAY,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAKvC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAKpD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAO7D,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMlF,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAO/D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOhD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAQnF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAQjE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAQ5F,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxE"}
@@ -0,0 +1,175 @@
1
+ import { loadTokens, saveTokens, isTokenExpired } from './token-store.js';
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ const BASE_URL = 'https://api.freee.co.jp';
6
+ const TOKEN_URL = 'https://accounts.secure.freee.co.jp/public_api/token';
7
+ function getVersion() {
8
+ try {
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const pkgPath = path.resolve(__dirname, '../../package.json');
11
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
12
+ return pkg.version;
13
+ }
14
+ catch {
15
+ return '0.0.0';
16
+ }
17
+ }
18
+ const USER_AGENT = `freee-demo-kit/${getVersion()}`;
19
+ export class FreeeApiClient {
20
+ async getValidTokens() {
21
+ const tokens = await loadTokens();
22
+ if (!tokens) {
23
+ throw new Error('Not authenticated. Run `fdk auth` to authenticate with freee.');
24
+ }
25
+ if (isTokenExpired(tokens)) {
26
+ return this.refreshTokens(tokens);
27
+ }
28
+ return tokens;
29
+ }
30
+ async refreshTokens(tokens) {
31
+ const clientId = process.env['FREEE_CLIENT_ID'];
32
+ const clientSecret = process.env['FREEE_CLIENT_SECRET'];
33
+ if (!clientId || !clientSecret) {
34
+ throw new Error('Authentication expired. Run `fdk auth` to re-authenticate with freee.');
35
+ }
36
+ const body = new URLSearchParams({
37
+ grant_type: 'refresh_token',
38
+ client_id: clientId,
39
+ client_secret: clientSecret,
40
+ refresh_token: tokens.refresh_token,
41
+ });
42
+ const res = await fetch(TOKEN_URL, {
43
+ method: 'POST',
44
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
45
+ body: body.toString(),
46
+ });
47
+ if (!res.ok) {
48
+ throw new Error('Token refresh failed. Run `fdk auth` to re-authenticate with freee.');
49
+ }
50
+ const data = (await res.json());
51
+ const newTokens = {
52
+ access_token: data.access_token,
53
+ refresh_token: data.refresh_token,
54
+ token_type: data.token_type,
55
+ expires_at: (data.created_at + data.expires_in) * 1000,
56
+ company_id: tokens.company_id,
57
+ };
58
+ await saveTokens(newTokens);
59
+ return newTokens;
60
+ }
61
+ async request(apiPath) {
62
+ const tokens = await this.getValidTokens();
63
+ const res = await fetch(`${BASE_URL}${apiPath}`, {
64
+ headers: {
65
+ Authorization: `Bearer ${tokens.access_token}`,
66
+ 'User-Agent': USER_AGENT,
67
+ Accept: 'application/json',
68
+ },
69
+ });
70
+ if (!res.ok) {
71
+ throw new Error(`freee API error: ${res.status} ${apiPath}`);
72
+ }
73
+ return res.json();
74
+ }
75
+ async requestPost(apiPath, body) {
76
+ const tokens = await this.getValidTokens();
77
+ const res = await fetch(`${BASE_URL}${apiPath}`, {
78
+ method: 'POST',
79
+ headers: {
80
+ Authorization: `Bearer ${tokens.access_token}`,
81
+ 'User-Agent': USER_AGENT,
82
+ Accept: 'application/json',
83
+ 'Content-Type': 'application/json',
84
+ },
85
+ body: JSON.stringify(body),
86
+ });
87
+ if (!res.ok) {
88
+ const text = await res.text().catch(() => '');
89
+ throw new Error(`freee API error: ${res.status} POST ${apiPath} — ${text}`);
90
+ }
91
+ return res.json();
92
+ }
93
+ async requestDelete(apiPath) {
94
+ const tokens = await this.getValidTokens();
95
+ const res = await fetch(`${BASE_URL}${apiPath}`, {
96
+ method: 'DELETE',
97
+ headers: {
98
+ Authorization: `Bearer ${tokens.access_token}`,
99
+ 'User-Agent': USER_AGENT,
100
+ },
101
+ });
102
+ if (!res.ok && res.status !== 204) {
103
+ throw new Error(`freee API error: ${res.status} DELETE ${apiPath}`);
104
+ }
105
+ }
106
+ // ── GET endpoints ───────────────────────────────────────────────────────
107
+ async getMe() {
108
+ const data = await this.request('/api/1/users/me');
109
+ return data.user;
110
+ }
111
+ async getCompanies() {
112
+ const data = await this.request('/api/1/companies');
113
+ return data.companies;
114
+ }
115
+ async getCompany(companyId) {
116
+ const data = await this.request(`/api/1/companies/${companyId}`);
117
+ return data.company;
118
+ }
119
+ async getWalletables(companyId) {
120
+ const data = await this.request(`/api/1/walletables?company_id=${companyId}`);
121
+ return data.walletables;
122
+ }
123
+ async getDeals(companyId, params) {
124
+ const query = new URLSearchParams({ company_id: String(companyId), ...params }).toString();
125
+ const data = await this.request(`/api/1/deals?${query}`);
126
+ return data.deals;
127
+ }
128
+ async getAccountItems(companyId) {
129
+ const data = await this.request(`/api/1/account_items?company_id=${companyId}`);
130
+ return data.account_items;
131
+ }
132
+ async getTaxes(companyId) {
133
+ const data = await this.request(`/api/1/taxes/companies/${companyId}`);
134
+ return data.taxes;
135
+ }
136
+ async getTrialPl(companyId, params) {
137
+ const query = new URLSearchParams({ company_id: String(companyId), ...params }).toString();
138
+ return this.request(`/api/1/trial_pl?${query}`);
139
+ }
140
+ async getTrialBs(companyId, params) {
141
+ const query = new URLSearchParams({ company_id: String(companyId), ...params }).toString();
142
+ return this.request(`/api/1/trial_bs?${query}`);
143
+ }
144
+ // ── Walletable write ────────────────────────────────────────────────────
145
+ async createWalletable(companyId, data) {
146
+ const res = await this.requestPost('/api/1/walletables', {
147
+ company_id: companyId,
148
+ ...data,
149
+ });
150
+ return res.walletable;
151
+ }
152
+ async deleteWalletable(companyId, id, type) {
153
+ await this.requestDelete(`/api/1/walletables/${type}/${id}?company_id=${companyId}`);
154
+ }
155
+ // ── Deal write ──────────────────────────────────────────────────────────
156
+ async createDeal(companyId, data) {
157
+ const res = await this.requestPost('/api/1/deals', {
158
+ company_id: companyId,
159
+ ...data,
160
+ });
161
+ return res.deal;
162
+ }
163
+ async deleteDeal(companyId, id) {
164
+ await this.requestDelete(`/api/1/deals/${id}?company_id=${companyId}`);
165
+ }
166
+ // ── ManualJournal write ─────────────────────────────────────────────────
167
+ async createManualJournal(companyId, data) {
168
+ const res = await this.requestPost('/api/1/manual_journals', { company_id: companyId, ...data });
169
+ return res.manual_journal;
170
+ }
171
+ async deleteManualJournal(companyId, id) {
172
+ await this.requestDelete(`/api/1/manual_journals/${id}?company_id=${companyId}`);
173
+ }
174
+ }
175
+ //# sourceMappingURL=freee-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freee-api.js","sourceRoot":"","sources":["../../src/utils/freee-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type LogLevel = 'info' | 'warn' | 'error' | 'debug';
2
+ export declare function log(level: LogLevel, message: string): void;
3
+ export declare function info(message: string): void;
4
+ export declare function warn(message: string): void;
5
+ export declare function error(message: string): void;
6
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE3D,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAS1D;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3C"}
@@ -0,0 +1,22 @@
1
+ export function log(level, message) {
2
+ const prefix = `[fdk:${level}]`;
3
+ if (level === 'error') {
4
+ console.error(`${prefix} ${message}`);
5
+ }
6
+ else if (level === 'warn') {
7
+ console.warn(`${prefix} ${message}`);
8
+ }
9
+ else {
10
+ console.log(`${prefix} ${message}`);
11
+ }
12
+ }
13
+ export function info(message) {
14
+ log('info', message);
15
+ }
16
+ export function warn(message) {
17
+ log('warn', message);
18
+ }
19
+ export function error(message) {
20
+ log('error', message);
21
+ }
22
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,OAAe;IAClD,MAAM,MAAM,GAAG,QAAQ,KAAK,GAAG,CAAC;IAChC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generates a PKCE code_verifier.
3
+ * Returns a URL-safe base64 string of 96 bytes (128 chars).
4
+ * Per RFC 7636: must be 43-128 chars from [A-Z a-z 0-9 - . _ ~]
5
+ */
6
+ export declare function generateCodeVerifier(): string;
7
+ /**
8
+ * Generates a PKCE code_challenge from a verifier.
9
+ * S256 method: BASE64URL(SHA256(code_verifier))
10
+ */
11
+ export declare function generateCodeChallenge(verifier: string): Promise<string>;
12
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/utils/pkce.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7E"}
@@ -0,0 +1,18 @@
1
+ import crypto from 'node:crypto';
2
+ /**
3
+ * Generates a PKCE code_verifier.
4
+ * Returns a URL-safe base64 string of 96 bytes (128 chars).
5
+ * Per RFC 7636: must be 43-128 chars from [A-Z a-z 0-9 - . _ ~]
6
+ */
7
+ export function generateCodeVerifier() {
8
+ return crypto.randomBytes(72).toString('base64url');
9
+ }
10
+ /**
11
+ * Generates a PKCE code_challenge from a verifier.
12
+ * S256 method: BASE64URL(SHA256(code_verifier))
13
+ */
14
+ export async function generateCodeChallenge(verifier) {
15
+ const hash = crypto.createHash('sha256').update(verifier).digest();
16
+ return hash.toString('base64url');
17
+ }
18
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/utils/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;IACnE,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PresetDefinition } from '../types/freee.js';
2
+ export declare function loadPreset(presetName: string): Promise<PresetDefinition>;
3
+ //# sourceMappingURL=preset-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset-loader.d.ts","sourceRoot":"","sources":["../../src/utils/preset-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAmB1D,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+B9E"}
@@ -0,0 +1,47 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { PRESETS_DIR } from './preset-validator.js';
4
+ function isValidPreset(obj) {
5
+ if (!obj || typeof obj !== 'object')
6
+ return false;
7
+ const p = obj;
8
+ return (typeof p['name'] === 'string' &&
9
+ typeof p['description'] === 'string' &&
10
+ typeof p['version'] === 'string' &&
11
+ typeof p['expected'] === 'object' &&
12
+ p['expected'] !== null &&
13
+ typeof p['data'] === 'object' &&
14
+ p['data'] !== null &&
15
+ Array.isArray(p['data']['walletables']) &&
16
+ Array.isArray(p['data']['deals']) &&
17
+ Array.isArray(p['data']['manualJournals']));
18
+ }
19
+ export async function loadPreset(presetName) {
20
+ const presetDir = path.resolve(PRESETS_DIR, presetName);
21
+ const presetFile = path.join(presetDir, 'preset.json');
22
+ try {
23
+ await fs.access(presetDir);
24
+ }
25
+ catch {
26
+ throw new Error(`Preset not found: "${presetName}". Run \`fdk list\` to see available presets.`);
27
+ }
28
+ let raw;
29
+ try {
30
+ raw = await fs.readFile(presetFile, 'utf-8');
31
+ }
32
+ catch {
33
+ throw new Error(`Preset not found: "${presetName}" has no preset.json.`);
34
+ }
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(raw);
38
+ }
39
+ catch (e) {
40
+ throw new Error(`Invalid preset JSON in "${presetName}": ${String(e)}`);
41
+ }
42
+ if (!isValidPreset(parsed)) {
43
+ throw new Error(`Invalid preset "${presetName}": missing required fields (name, description, version, expected, data.walletables, data.deals, data.manualJournals)`);
44
+ }
45
+ return parsed;
46
+ }
47
+ //# sourceMappingURL=preset-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset-loader.js","sourceRoot":"","sources":["../../src/utils/preset-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,SAAS,aAAa,CAAC,GAAY;IACjC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,CAAC,GAAG,GAA8B,CAAC;IACzC,OAAO,CACL,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ;QAC7B,OAAO,CAAC,CAAC,aAAa,CAAC,KAAK,QAAQ;QACpC,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ;QAChC,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ;QACjC,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI;QACtB,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ;QAC7B,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI;QAClB,KAAK,CAAC,OAAO,CAAE,CAAC,CAAC,MAAM,CAA6B,CAAC,aAAa,CAAC,CAAC;QACpE,KAAK,CAAC,OAAO,CAAE,CAAC,CAAC,MAAM,CAA6B,CAAC,OAAO,CAAC,CAAC;QAC9D,KAAK,CAAC,OAAO,CAAE,CAAC,CAAC,MAAM,CAA6B,CAAC,gBAAgB,CAAC,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,sBAAsB,UAAU,+CAA+C,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,sBAAsB,UAAU,uBAAuB,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2BAA2B,UAAU,MAAM,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,mBAAmB,UAAU,sHAAsH,CACpJ,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ declare const PRESETS_DIR: string;
2
+ /**
3
+ * Validates a preset name for security:
4
+ * - Only alphanumeric characters, /, -, _ are allowed
5
+ * - Path traversal (../) is rejected
6
+ * - Leading slash is rejected
7
+ */
8
+ export declare function validatePresetName(preset: string): void;
9
+ export { PRESETS_DIR };
10
+ //# sourceMappingURL=preset-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset-validator.d.ts","sourceRoot":"","sources":["../../src/utils/preset-validator.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,WAAW,QAA2C,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAcvD;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
4
+ // Presets directory is at project root: <repo>/presets/
5
+ const PRESETS_DIR = path.resolve(__dirname, '../../presets');
6
+ /**
7
+ * Validates a preset name for security:
8
+ * - Only alphanumeric characters, /, -, _ are allowed
9
+ * - Path traversal (../) is rejected
10
+ * - Leading slash is rejected
11
+ */
12
+ export function validatePresetName(preset) {
13
+ if (!preset || !/^[a-zA-Z0-9/_-]+$/.test(preset)) {
14
+ throw new Error(`Invalid preset name: "${preset}". Use only alphanumeric characters, /, -, _`);
15
+ }
16
+ // Prevent path traversal by resolving and checking prefix
17
+ const resolved = path.resolve(PRESETS_DIR, preset);
18
+ if (!resolved.startsWith(PRESETS_DIR + path.sep) && resolved !== PRESETS_DIR) {
19
+ throw new Error(`Invalid preset name: "${preset}" — path traversal detected`);
20
+ }
21
+ }
22
+ export { PRESETS_DIR };
23
+ //# sourceMappingURL=preset-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset-validator.js","sourceRoot":"","sources":["../../src/utils/preset-validator.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,wDAAwD;AACxD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,IAAI,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,8CAA8C,CAC9E,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,6BAA6B,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { PresetState } from '../types/freee.js';
2
+ export declare function saveState(state: PresetState): Promise<void>;
3
+ export declare function loadState(preset: string): Promise<PresetState | null>;
4
+ export declare function clearState(preset: string): Promise<void>;
5
+ export declare function listAllStates(): Promise<PresetState[]>;
6
+ //# sourceMappingURL=state-store.d.ts.map