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,58 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const PRESETS_DIR = path.resolve(__dirname, '../../presets');
7
+ async function scanPresets(dir, prefix = '') {
8
+ const entries = [];
9
+ let items;
10
+ try {
11
+ items = await fs.readdir(dir);
12
+ }
13
+ catch {
14
+ return entries;
15
+ }
16
+ for (const item of items) {
17
+ const fullPath = path.join(dir, item);
18
+ const stat = await fs.stat(fullPath);
19
+ if (stat.isDirectory()) {
20
+ // Check if this directory has a preset.json
21
+ const presetJson = path.join(fullPath, 'preset.json');
22
+ try {
23
+ await fs.access(presetJson);
24
+ const id = prefix ? `${prefix}/${item}` : item;
25
+ entries.push({ id, path: fullPath });
26
+ }
27
+ catch {
28
+ // No preset.json — recurse into subdirectory
29
+ const id = prefix ? `${prefix}/${item}` : item;
30
+ const nested = await scanPresets(fullPath, id);
31
+ entries.push(...nested);
32
+ }
33
+ }
34
+ }
35
+ return entries;
36
+ }
37
+ export const listCommand = new Command('list')
38
+ .description('List available presets')
39
+ .action(async () => {
40
+ const presets = await scanPresets(PRESETS_DIR);
41
+ if (presets.length === 0) {
42
+ console.log('利用可能なプリセット:');
43
+ console.log(' (なし — Phase 2 で実装予定)');
44
+ console.log('');
45
+ console.log('予定プリセット:');
46
+ console.log(' accounting/quickstart 基本的な会計データ(中小企業向け) [Phase 2 予定]');
47
+ console.log(' expenses 経費精算デモデータ [Phase 2 予定]');
48
+ console.log(' invoices 請求書・売掛金デモデータ [Phase 2 予定]');
49
+ console.log(' hr 給与・人事デモデータ [Phase 2 予定]');
50
+ }
51
+ else {
52
+ console.log('利用可能なプリセット:');
53
+ for (const preset of presets) {
54
+ console.log(` ${preset.id}`);
55
+ }
56
+ }
57
+ });
58
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const loadAllCommand: Command;
3
+ //# sourceMappingURL=load-all.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-all.d.ts","sourceRoot":"","sources":["../../src/commands/load-all.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,eAAO,MAAM,cAAc,SA0CvB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { Command } from 'commander';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { PRESETS_DIR } from '../utils/preset-validator.js';
5
+ import { info, error as logError } from '../utils/logger.js';
6
+ async function findPresetIds(dir, prefix = '') {
7
+ const results = [];
8
+ let items;
9
+ try {
10
+ items = await fs.readdir(dir);
11
+ }
12
+ catch {
13
+ return results;
14
+ }
15
+ for (const item of items) {
16
+ const fullPath = path.join(dir, item);
17
+ const stat = await fs.stat(fullPath).catch(() => null);
18
+ if (!stat?.isDirectory())
19
+ continue;
20
+ const id = prefix ? `${prefix}/${item}` : item;
21
+ const presetJson = path.join(fullPath, 'preset.json');
22
+ try {
23
+ await fs.access(presetJson);
24
+ results.push(id);
25
+ }
26
+ catch {
27
+ results.push(...(await findPresetIds(fullPath, id)));
28
+ }
29
+ }
30
+ return results;
31
+ }
32
+ export const loadAllCommand = new Command('load-all')
33
+ .description('Load all available presets into the freee sandbox company')
34
+ .option('--dry-run', 'Show what would be loaded without actually loading')
35
+ .option('--delay <ms>', 'Extra delay between presets in milliseconds', '500')
36
+ .action(async (options) => {
37
+ const presetIds = await findPresetIds(PRESETS_DIR);
38
+ if (presetIds.length === 0) {
39
+ console.log('利用可能なプリセットが見つかりません。');
40
+ return;
41
+ }
42
+ console.log(`\n📦 全プリセットを投入します (${presetIds.length}件):`);
43
+ for (const id of presetIds) {
44
+ console.log(` - ${id}`);
45
+ }
46
+ if (options.dryRun) {
47
+ console.log('\n(--dry-run: 実際の投入はスキップされました)');
48
+ console.log('実際に投入するには: fdk load-all');
49
+ return;
50
+ }
51
+ const delayMs = parseInt(options.delay ?? '500', 10);
52
+ const { loadCommand } = await import('./load.js');
53
+ for (const presetId of presetIds) {
54
+ console.log(`\n▶ ${presetId} を投入中...`);
55
+ try {
56
+ // Invoke load command programmatically
57
+ await loadCommand.parseAsync([presetId], { from: 'user' });
58
+ info(` ✓ ${presetId} 完了`);
59
+ }
60
+ catch (err) {
61
+ logError(` ✗ ${presetId} 失敗: ${String(err)}`);
62
+ }
63
+ if (delayMs > 0) {
64
+ await new Promise(resolve => setTimeout(resolve, delayMs));
65
+ }
66
+ }
67
+ console.log('\n✅ 全プリセットの投入が完了しました');
68
+ });
69
+ //# sourceMappingURL=load-all.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-all.js","sourceRoot":"","sources":["../../src/commands/load-all.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE7D,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,MAAM,GAAG,EAAE;IACnD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE;YAAE,SAAS;QACnC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KAClD,WAAW,CAAC,2DAA2D,CAAC;KACxE,MAAM,CAAC,WAAW,EAAE,oDAAoD,CAAC;KACzE,MAAM,CAAC,cAAc,EAAE,6CAA6C,EAAE,KAAK,CAAC;KAC5E,MAAM,CAAC,KAAK,EAAE,OAA6C,EAAE,EAAE;IAC9D,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;IAEnD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;IACzD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IAElD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC;YACH,uCAAuC;YACvC,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,OAAO,QAAQ,QAAQ,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { Command } from 'commander';
2
+ export interface LoadOptions {
3
+ dryRun?: boolean;
4
+ force?: boolean;
5
+ yes?: boolean;
6
+ }
7
+ export interface LoadProgress {
8
+ stage: 'walletables' | 'deals' | 'journals';
9
+ current: number;
10
+ total: number;
11
+ }
12
+ export interface LoadResult {
13
+ walletableIds: number[];
14
+ dealIds: number[];
15
+ manualJournalIds: number[];
16
+ presetName: string;
17
+ companyName: string;
18
+ }
19
+ /**
20
+ * プリセットを freee サンドボックスに投入する。
21
+ * setup コマンドからも呼び出せる純粋関数。
22
+ */
23
+ export declare function runLoad(preset: string, options: LoadOptions, onProgress?: (progress: LoadProgress) => void): Promise<LoadResult>;
24
+ export declare const loadCommand: Command;
25
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/commands/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,GAC5C,OAAO,CAAC,UAAU,CAAC,CA4JrB;AAED,eAAO,MAAM,WAAW,SA6BpB,CAAC"}
@@ -0,0 +1,197 @@
1
+ import { Command } from 'commander';
2
+ import { validatePresetName } from '../utils/preset-validator.js';
3
+ import { loadPreset } from '../utils/preset-loader.js';
4
+ import { FreeeApiClient } from '../utils/freee-api.js';
5
+ import { loadTokens, saveTokens } from '../utils/token-store.js';
6
+ import { saveState, loadState } from '../utils/state-store.js';
7
+ import { info, warn, error as logError } from '../utils/logger.js';
8
+ import { confirmCompany } from '../utils/confirm-company.js';
9
+ const DELAY_MS = 200;
10
+ function sleep(ms) {
11
+ return new Promise(resolve => setTimeout(resolve, ms));
12
+ }
13
+ /**
14
+ * プリセットを freee サンドボックスに投入する。
15
+ * setup コマンドからも呼び出せる純粋関数。
16
+ */
17
+ export async function runLoad(preset, options, onProgress) {
18
+ validatePresetName(preset);
19
+ const definition = await loadPreset(preset);
20
+ const { data, expected, name: presetName } = definition;
21
+ if (options.dryRun) {
22
+ console.log(`\n🔍 ドライラン: ${presetName}`);
23
+ console.log(`\n口座 (${data.walletables.length}件):`);
24
+ for (const w of data.walletables) {
25
+ console.log(` [${w.type}] ${w.name}`);
26
+ }
27
+ console.log(`\n取引 (${data.deals.length}件):`);
28
+ for (const d of data.deals) {
29
+ const total = d.details.reduce((s, x) => s + x.amount, 0);
30
+ console.log(` ${d.issue_date} [${d.type}] ${d.partner_name ?? ''} ¥${total.toLocaleString()}`);
31
+ }
32
+ console.log(`\n手動仕訳 (${data.manualJournals.length}件):`);
33
+ for (const mj of data.manualJournals) {
34
+ console.log(` ${mj.issue_date} (${mj.details.length}明細)`);
35
+ }
36
+ console.log(`\n期待値: 口座${expected.walletables}件, 取引${expected.deals}件, 仕訳${expected.manualJournals}件`);
37
+ return { walletableIds: [], dealIds: [], manualJournalIds: [], presetName, companyName: '' };
38
+ }
39
+ if (!options.force) {
40
+ const existing = await loadState(preset);
41
+ if (existing) {
42
+ throw new Error(`"${preset}" は既にロード済みです (${existing.loadedAt})。上書きするには --force を使用してください。`);
43
+ }
44
+ }
45
+ const tokens = await loadTokens();
46
+ if (!tokens)
47
+ throw new Error('Not authenticated. Run `fdk auth` first.');
48
+ let companyId = tokens.company_id;
49
+ const client = new FreeeApiClient();
50
+ let companyName = `ID: ${companyId}`;
51
+ if (!companyId) {
52
+ const companies = await client.getCompanies();
53
+ if (companies.length === 0)
54
+ throw new Error('No companies found in your freee account.');
55
+ companyId = companies[0].id;
56
+ companyName = companies[0].display_name || companies[0].name;
57
+ warn(`Company ID not set. Using first company: [${companyId}] ${companyName}`);
58
+ await saveTokens({ ...tokens, company_id: companyId });
59
+ }
60
+ else {
61
+ const company = await client.getCompany(companyId);
62
+ companyName = company.display_name || company.name;
63
+ }
64
+ const ok = await confirmCompany(companyName, companyId, options.yes ?? false);
65
+ if (!ok)
66
+ throw new Error('CANCELLED');
67
+ let itemMap = new Map();
68
+ function resolveDeals(deals) {
69
+ return deals.map(deal => ({
70
+ ...deal,
71
+ details: deal.details.map(d => {
72
+ if (d.account_item_name && !d.account_item_id) {
73
+ const id = itemMap.get(d.account_item_name);
74
+ if (!id)
75
+ warn(`勘定科目が見つかりません: "${d.account_item_name}"`);
76
+ return { ...d, account_item_id: id };
77
+ }
78
+ return d;
79
+ }),
80
+ }));
81
+ }
82
+ function resolveJournals(journals) {
83
+ return journals.map(mj => ({
84
+ ...mj,
85
+ details: mj.details.map(d => {
86
+ if (d.account_item_name && !d.account_item_id) {
87
+ const id = itemMap.get(d.account_item_name);
88
+ if (!id)
89
+ warn(`勘定科目が見つかりません: "${d.account_item_name}"`);
90
+ return { ...d, account_item_id: id };
91
+ }
92
+ return d;
93
+ }),
94
+ }));
95
+ }
96
+ const walletableIds = [];
97
+ const dealIds = [];
98
+ const manualJournalIds = [];
99
+ // 口座を作成
100
+ const existingWalletables = await client.getWalletables(companyId);
101
+ const existingWalletableMap = new Map(existingWalletables.map(w => [w.name, w.id]));
102
+ for (let i = 0; i < data.walletables.length; i++) {
103
+ const w = data.walletables[i];
104
+ onProgress?.({ stage: 'walletables', current: i + 1, total: data.walletables.length });
105
+ const existingId = existingWalletableMap.get(w.name);
106
+ if (existingId !== undefined) {
107
+ info(` ✓ ${w.name} (既存 id: ${existingId}) — スキップ`);
108
+ continue;
109
+ }
110
+ try {
111
+ const created = await client.createWalletable(companyId, w);
112
+ walletableIds.push(created.id);
113
+ info(` ✓ ${w.name} (id: ${created.id})`);
114
+ await sleep(DELAY_MS);
115
+ }
116
+ catch (err) {
117
+ logError(`口座作成失敗: ${w.name} — ${String(err)}`);
118
+ }
119
+ }
120
+ // 勘定科目マップを構築
121
+ info('勘定科目を取得中...');
122
+ const accountItems = await client.getAccountItems(companyId);
123
+ itemMap = new Map(accountItems.map(a => [a.name, a.id]));
124
+ // 取引を作成
125
+ const resolvedDeals = resolveDeals(data.deals);
126
+ for (let i = 0; i < resolvedDeals.length; i++) {
127
+ const deal = resolvedDeals[i];
128
+ onProgress?.({ stage: 'deals', current: i + 1, total: resolvedDeals.length });
129
+ try {
130
+ const created = await client.createDeal(companyId, deal);
131
+ dealIds.push(created.id);
132
+ await sleep(DELAY_MS);
133
+ }
134
+ catch (err) {
135
+ logError(`取引作成失敗: ${deal.issue_date} — ${String(err)}`);
136
+ }
137
+ }
138
+ info(` ✓ ${dealIds.length}件 作成完了`);
139
+ // 手動仕訳を作成
140
+ if (data.manualJournals.length > 0) {
141
+ const resolvedJournals = resolveJournals(data.manualJournals);
142
+ for (let i = 0; i < resolvedJournals.length; i++) {
143
+ const mj = resolvedJournals[i];
144
+ onProgress?.({ stage: 'journals', current: i + 1, total: resolvedJournals.length });
145
+ try {
146
+ const created = await client.createManualJournal(companyId, mj);
147
+ manualJournalIds.push(created.id);
148
+ info(` ✓ ${mj.issue_date} (id: ${created.id})`);
149
+ await sleep(DELAY_MS);
150
+ }
151
+ catch (err) {
152
+ logError(`手動仕訳作成失敗: ${mj.issue_date} — ${String(err)}`);
153
+ }
154
+ }
155
+ }
156
+ // 状態を保存
157
+ await saveState({
158
+ preset,
159
+ loadedAt: new Date().toISOString(),
160
+ walletableIds,
161
+ dealIds,
162
+ manualJournalIds,
163
+ });
164
+ return { walletableIds, dealIds, manualJournalIds, presetName, companyName };
165
+ }
166
+ export const loadCommand = new Command('load')
167
+ .description('Load a specific preset into the freee sandbox company')
168
+ .argument('<preset>', 'Preset name (e.g. accounting/quickstart)')
169
+ .option('--dry-run', 'Preview without making API calls')
170
+ .option('--force', 'Load even if state.json already exists for this preset')
171
+ .option('--yes', 'Skip confirmation prompt')
172
+ .action(async (preset, options) => {
173
+ try {
174
+ validatePresetName(preset);
175
+ }
176
+ catch (err) {
177
+ logError(String(err));
178
+ process.exit(1);
179
+ }
180
+ try {
181
+ const result = await runLoad(preset, options);
182
+ if (!options.dryRun) {
183
+ console.log(`\n✅ 投入完了: 口座${result.walletableIds.length}件, 取引${result.dealIds.length}件, 仕訳${result.manualJournalIds.length}件`);
184
+ console.log('確認するには: fdk verify ' + preset);
185
+ }
186
+ }
187
+ catch (err) {
188
+ const msg = String(err);
189
+ if (msg.includes('CANCELLED')) {
190
+ console.log('キャンセルしました。');
191
+ process.exit(0);
192
+ }
193
+ logError(msg);
194
+ process.exit(1);
195
+ }
196
+ });
197
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/commands/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const resetCommand: Command;
3
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyEpC,eAAO,MAAM,YAAY,SAsDrB,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { Command } from 'commander';
2
+ import { FreeeApiClient } from '../utils/freee-api.js';
3
+ import { loadTokens } from '../utils/token-store.js';
4
+ import { loadState, clearState } from '../utils/state-store.js';
5
+ import { warn, error as logError } from '../utils/logger.js';
6
+ import { confirmCompany } from '../utils/confirm-company.js';
7
+ const DELAY_MS = 200;
8
+ function sleep(ms) {
9
+ return new Promise(resolve => setTimeout(resolve, ms));
10
+ }
11
+ async function resetPreset(preset, companyId, client) {
12
+ const state = await loadState(preset);
13
+ if (!state) {
14
+ console.log(`⚠️ "${preset}" の投入データが見つかりません。`);
15
+ return;
16
+ }
17
+ console.log(`\n🗑️ "${preset}" を削除中...`);
18
+ console.log(` 仕訳: ${state.manualJournalIds.length}件, 取引: ${state.dealIds.length}件, 口座: ${state.walletableIds.length}件`);
19
+ // Delete in reverse order: journals → deals → walletables
20
+ let errors = 0;
21
+ for (const id of state.manualJournalIds) {
22
+ try {
23
+ await client.deleteManualJournal(companyId, id);
24
+ await sleep(DELAY_MS);
25
+ }
26
+ catch {
27
+ warn(`手動仕訳の削除失敗 (id: ${id})`);
28
+ errors++;
29
+ }
30
+ }
31
+ for (const id of state.dealIds) {
32
+ try {
33
+ await client.deleteDeal(companyId, id);
34
+ await sleep(DELAY_MS);
35
+ }
36
+ catch {
37
+ warn(`取引の削除失敗 (id: ${id})`);
38
+ errors++;
39
+ }
40
+ }
41
+ const existingWalletables = await client.getWalletables(companyId);
42
+ const walletableTypeMap = new Map(existingWalletables.map(w => [w.id, w.type]));
43
+ for (const id of state.walletableIds) {
44
+ const type = walletableTypeMap.get(id);
45
+ if (!type) {
46
+ warn(`口座が見つかりません (id: ${id}) — スキップ`);
47
+ continue;
48
+ }
49
+ try {
50
+ await client.deleteWalletable(companyId, id, type);
51
+ await sleep(DELAY_MS);
52
+ }
53
+ catch {
54
+ warn(`口座の削除失敗 (id: ${id})`);
55
+ errors++;
56
+ }
57
+ }
58
+ await clearState(preset);
59
+ if (errors > 0) {
60
+ console.log(`⚠️ 削除完了(${errors}件のエラーあり)`);
61
+ }
62
+ else {
63
+ console.log(`✅ リセット完了: "${preset}"`);
64
+ }
65
+ }
66
+ export const resetCommand = new Command('reset')
67
+ .description('Delete all demo data from the freee sandbox company')
68
+ .argument('[preset]', 'Reset only a specific preset (omit to reset all)')
69
+ .option('--dry-run', 'Show what would be deleted without actually deleting')
70
+ .option('--yes', 'Skip confirmation prompt')
71
+ .action(async (preset, options) => {
72
+ const tokens = await loadTokens();
73
+ if (!tokens) {
74
+ logError('Not authenticated. Run `fdk auth` first.');
75
+ process.exit(1);
76
+ }
77
+ const companyId = tokens.company_id;
78
+ if (!companyId) {
79
+ logError('Company not set. Run `fdk auth` first.');
80
+ process.exit(1);
81
+ }
82
+ const client = new FreeeApiClient();
83
+ const company = await client.getCompany(companyId);
84
+ const companyName = company.display_name || company.name;
85
+ if (options.dryRun) {
86
+ const targets = preset ? [preset] : ['all presets in state.json'];
87
+ console.log(`🔍 ドライラン — 削除対象: ${targets.join(', ')}`);
88
+ if (preset) {
89
+ const state = await loadState(preset);
90
+ if (state) {
91
+ console.log(` 仕訳: ${state.manualJournalIds.length}件`);
92
+ console.log(` 取引: ${state.dealIds.length}件`);
93
+ console.log(` 口座: ${state.walletableIds.length}件`);
94
+ }
95
+ else {
96
+ console.log(' 投入データなし');
97
+ }
98
+ }
99
+ return;
100
+ }
101
+ const ok = await confirmCompany(companyName, companyId, options.yes ?? false);
102
+ if (!ok) {
103
+ console.log('キャンセルしました。');
104
+ process.exit(0);
105
+ }
106
+ if (preset) {
107
+ await resetPreset(preset, companyId, client);
108
+ }
109
+ else {
110
+ // Reset all — read state file for all preset keys
111
+ const { loadState: ls } = await import('../utils/state-store.js');
112
+ // We don't have a listStates function yet; just warn
113
+ console.log('⚠️ 全プリセットリセットはプリセット名指定が必要です。');
114
+ console.log('例: fdk reset accounting/quickstart');
115
+ }
116
+ });
117
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ export declare function runSetup(): Promise<void>;
3
+ export declare const setupCommand: Command;
4
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsFpC,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAwJ9C;AAED,eAAO,MAAM,YAAY,SASrB,CAAC"}