@dizzlkheinz/ynab-mcpb 0.12.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +3 -0
- package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +3 -0
- package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +1 -0
- package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +5 -0
- package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +1569 -0
- package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +3 -0
- package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +2832 -0
- package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +2709 -0
- package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +2832 -0
- package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +2832 -0
- package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +2709 -0
- package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +1 -0
- package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +5217 -0
- package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +2594 -0
- package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +2594 -0
- package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +231 -0
- package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +2590 -0
- package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +5195 -0
- package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +286 -0
- package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +218 -0
- package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +180 -0
- package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +3 -0
- package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +1 -0
- package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +747 -0
- package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +1 -0
- package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +2594 -0
- package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +2594 -0
- package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +144 -0
- package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +416 -0
- package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +2590 -0
- package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +2590 -0
- package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +2590 -0
- package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +790 -0
- package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +766 -0
- package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +790 -0
- package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +2594 -0
- package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +1000 -0
- package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +3489 -0
- package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +766 -0
- package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +2594 -0
- package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +2456 -0
- package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +2594 -0
- package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +18 -0
- package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +48 -0
- package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +1 -0
- package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +1 -0
- package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +1 -0
- package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +1 -0
- package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +1271 -0
- package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +1570 -0
- package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +2590 -0
- package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +3 -0
- package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +3299 -0
- package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +3299 -0
- package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +1882 -0
- package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +2594 -0
- package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +1 -0
- package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +170 -0
- package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +1 -0
- package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +3 -0
- package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +1 -0
- package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +1 -0
- package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +3 -0
- package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +1 -0
- package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +1 -0
- package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +5 -0
- package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +1 -0
- package/.github/workflows/ci-tests.yml +6 -2
- package/.github/workflows/publish.yml +3 -3
- package/.github/workflows/release.yml +4 -0
- package/CHANGELOG.md +89 -1
- package/NUL +1 -1
- package/README.md +36 -10
- package/dist/bundle/index.cjs +65 -42
- package/dist/index.js +9 -20
- package/dist/server/YNABMCPServer.d.ts +2 -1
- package/dist/server/YNABMCPServer.js +61 -27
- package/dist/server/cacheKeys.d.ts +8 -0
- package/dist/server/cacheKeys.js +8 -0
- package/dist/server/config.d.ts +22 -3
- package/dist/server/config.js +16 -17
- package/dist/server/errorHandler.d.ts +2 -0
- package/dist/server/errorHandler.js +49 -5
- package/dist/server/securityMiddleware.js +3 -6
- package/dist/server/toolRegistry.js +8 -10
- package/dist/tools/accountTools.js +4 -3
- package/dist/tools/categoryTools.js +8 -7
- package/dist/tools/monthTools.js +2 -1
- package/dist/tools/payeeTools.js +2 -1
- package/dist/tools/reconcileAdapter.js +10 -5
- package/dist/tools/reconciliation/analyzer.d.ts +4 -2
- package/dist/tools/reconciliation/analyzer.js +120 -404
- package/dist/tools/reconciliation/csvParser.d.ts +51 -0
- package/dist/tools/reconciliation/csvParser.js +413 -0
- package/dist/tools/reconciliation/executor.d.ts +8 -0
- package/dist/tools/reconciliation/executor.js +277 -50
- package/dist/tools/reconciliation/index.d.ts +7 -7
- package/dist/tools/reconciliation/index.js +115 -39
- package/dist/tools/reconciliation/matcher.d.ts +24 -3
- package/dist/tools/reconciliation/matcher.js +175 -133
- package/dist/tools/reconciliation/recommendationEngine.js +22 -18
- package/dist/tools/reconciliation/reportFormatter.js +9 -8
- package/dist/tools/reconciliation/signDetector.d.ts +2 -0
- package/dist/tools/reconciliation/signDetector.js +54 -0
- package/dist/tools/reconciliation/types.d.ts +20 -34
- package/dist/tools/reconciliation/types.js +1 -7
- package/dist/tools/reconciliation/ynabAdapter.d.ts +4 -0
- package/dist/tools/reconciliation/ynabAdapter.js +15 -0
- package/dist/tools/transactionTools.d.ts +3 -17
- package/dist/tools/transactionTools.js +5 -17
- package/dist/types/reconciliation.d.ts +24 -0
- package/dist/types/reconciliation.js +1 -0
- package/dist/utils/baseError.d.ts +3 -0
- package/dist/utils/baseError.js +7 -0
- package/dist/utils/errors.d.ts +13 -0
- package/dist/utils/errors.js +15 -0
- package/dist/utils/validationError.d.ts +3 -0
- package/dist/utils/validationError.js +3 -0
- package/docs/guides/ARCHITECTURE.md +12 -129
- package/docs/plans/2025-11-20-reloadable-config-token-validation.md +93 -0
- package/docs/plans/2025-11-21-fix-transaction-cached-property.md +362 -0
- package/docs/plans/2025-11-21-reconciliation-error-handling.md +90 -0
- package/docs/plans/2025-11-21-v014-hardening.md +153 -0
- package/docs/plans/reconciliation-v2-redesign.md +1571 -0
- package/package.json +8 -2
- package/scripts/run-throttled-integration-tests.js +9 -3
- package/scripts/test-recommendations.ts +1 -1
- package/src/__tests__/performance.test.ts +12 -5
- package/src/__tests__/testUtils.ts +62 -5
- package/src/__tests__/tools/reconciliation/csvParser.integration.test.ts +129 -0
- package/src/__tests__/tools/reconciliation/real-world.integration.test.ts +53 -0
- package/src/__tests__/workflows.e2e.test.ts +33 -0
- package/src/index.ts +8 -31
- package/src/server/YNABMCPServer.ts +81 -42
- package/src/server/__tests__/YNABMCPServer.integration.test.ts +10 -12
- package/src/server/__tests__/YNABMCPServer.test.ts +27 -15
- package/src/server/__tests__/config.test.ts +76 -152
- package/src/server/__tests__/server-startup.integration.test.ts +42 -14
- package/src/server/__tests__/toolRegistry.test.ts +1 -1
- package/src/server/cacheKeys.ts +8 -0
- package/src/server/config.ts +20 -38
- package/src/server/errorHandler.ts +52 -5
- package/src/server/securityMiddleware.ts +3 -7
- package/src/server/toolRegistry.ts +14 -10
- package/src/tools/__tests__/categoryTools.test.ts +37 -19
- package/src/tools/__tests__/transactionTools.test.ts +58 -2
- package/src/tools/accountTools.ts +8 -3
- package/src/tools/categoryTools.ts +12 -7
- package/src/tools/monthTools.ts +7 -1
- package/src/tools/payeeTools.ts +7 -1
- package/src/tools/reconcileAdapter.ts +10 -5
- package/src/tools/reconciliation/__tests__/adapter.test.ts +28 -22
- package/src/tools/reconciliation/__tests__/analyzer.test.ts +114 -180
- package/src/tools/reconciliation/__tests__/csvParser.test.ts +87 -0
- package/src/tools/reconciliation/__tests__/executor.integration.test.ts +26 -6
- package/src/tools/reconciliation/__tests__/executor.test.ts +133 -60
- package/src/tools/reconciliation/__tests__/matcher.test.ts +68 -54
- package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +37 -30
- package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +6 -5
- package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +30 -11
- package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +50 -15
- package/src/tools/reconciliation/__tests__/signDetector.test.ts +211 -0
- package/src/tools/reconciliation/__tests__/ynabAdapter.test.ts +61 -0
- package/src/tools/reconciliation/analyzer.ts +174 -545
- package/src/tools/reconciliation/csvParser.ts +617 -0
- package/src/tools/reconciliation/executor.ts +344 -58
- package/src/tools/reconciliation/index.ts +141 -48
- package/src/tools/reconciliation/matcher.ts +234 -214
- package/src/tools/reconciliation/recommendationEngine.ts +23 -19
- package/src/tools/reconciliation/reportFormatter.ts +16 -11
- package/src/tools/reconciliation/signDetector.ts +117 -0
- package/src/tools/reconciliation/types.ts +39 -61
- package/src/tools/reconciliation/ynabAdapter.ts +33 -0
- package/src/tools/schemas/outputs/utilityOutputs.ts +1 -1
- package/src/tools/transactionTools.ts +7 -18
- package/src/types/reconciliation.ts +49 -0
- package/src/utils/baseError.ts +7 -0
- package/src/utils/errors.ts +21 -0
- package/src/utils/validationError.ts +3 -0
- package/temp-recon.ts +126 -0
- package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +3662 -0
- package/test_mcp_tools.mjs +75 -0
- package/.code/agents/0427d95e-edca-431f-a214-5e53264e29c4/error.txt +0 -8
- package/.code/agents/0d675174-d1e1-41c3-9975-4c2e275819a9/error.txt +0 -3
- package/.code/agents/0d8c5afd-4787-422b-abf8-2e5943fc7e67/error.txt +0 -3
- package/.code/agents/0ec34a70-ed5d-4b9e-bee4-bb0e4cccbc4b/error.txt +0 -1
- package/.code/agents/0ef51a21-1ab1-49d7-9561-0eaa43875ebc/error.txt +0 -12
- package/.code/agents/15db95d7-abad-4b4d-9c3b-8446089cb61d/error.txt +0 -1
- package/.code/agents/19ab9acb-f675-4ff0-902a-09a5476f8149/error.txt +0 -1
- package/.code/agents/1ef7e12d-f6ff-4897-8a9b-152d523d898e/error.txt +0 -5
- package/.code/agents/2465/exec-call_lroN9KKzJVWC7t5423DK1nT9.txt +0 -1453
- package/.code/agents/28edb6fe-95a9-41a0-ae69-aa0100d26c0c/error.txt +0 -8
- package/.code/agents/2ae40cf5-b4bf-42e2-92bf-7ea350a7755e/error.txt +0 -9
- package/.code/agents/2bfc4e1f-ac4b-45a5-b6df-bf89d4dbb54c/error.txt +0 -1
- package/.code/agents/2e2e1134-eff0-49be-ba25-8e2c3468a564/error.txt +0 -5
- package/.code/agents/3/exec-call_203OC4TNVkLxW7z2HCVEQ1cM.txt +0 -81
- package/.code/agents/3/exec-call_SS5T0XSiXB4LSNzUKTl75wkh.txt +0 -610
- package/.code/agents/3322c003-ce5e-48e3-a342-f5049c5bf9a2/error.txt +0 -1
- package/.code/agents/391e9b08-1ebc-468c-9bcd-6d0cc3193b37/error.txt +0 -1
- package/.code/agents/3ab0aa84-b7bb-4054-afa3-40b8fd7d3be0/error.txt +0 -1
- package/.code/agents/3bed368d-50fe-477e-aee3-a6707eaa1ab9/error.txt +0 -3
- package/.code/agents/3e40b925-db12-442f-8d7a-a25fc69a6672/error.txt +0 -8
- package/.code/agents/414d5776-cf58-41f3-9328-a6daed503a50/error.txt +0 -5
- package/.code/agents/42687751-4565-4610-b240-67835b17d861/error.txt +0 -1
- package/.code/agents/46b98876-1a39-43c9-9e2f-507ca6d47335/error.txt +0 -9
- package/.code/agents/4a7d9491-b26f-43dd-850d-2ecdc49b5d1b/error.txt +0 -1
- package/.code/agents/4e60f00a-1b3e-447f-87f3-7faf9deddec3/error.txt +0 -13
- package/.code/agents/5138fc1c-4d49-4b74-a7da-ccdb3a8e44e7/error.txt +0 -14
- package/.code/agents/521cff39-a7a3-42e5-a557-134f0f7daaa0/error.txt +0 -5
- package/.code/agents/53302dc5-3857-4413-9a47-9e0f64a51dc4/error.txt +0 -5
- package/.code/agents/567c7c2e-6a6f-4761-a08d-d36deeb2e0ac/error.txt +0 -5
- package/.code/agents/57b00845-80dc-47c9-953c-3028d16275d6/error.txt +0 -3
- package/.code/agents/593d9005-c2a5-48fd-8813-ece0d3f2de96/error.txt +0 -1
- package/.code/agents/5a112e66-0e1a-42f9-877c-53af56ea3551/error.txt +0 -1
- package/.code/agents/5b05e8ed-7788-4738-b7ee-9faa8180f992/error.txt +0 -5
- package/.code/agents/5f888d6f-d7ca-4ac8-be23-9ea1bf753951/error.txt +0 -5
- package/.code/agents/607db3ab-e4b0-435b-b497-93e9aa525549/error.txt +0 -8
- package/.code/agents/67dcb2a2-900f-4c78-b3fc-80b5213e0ddf/error.txt +0 -8
- package/.code/agents/69ad848c-4e98-49b3-b16c-0094ac2d1759/error.txt +0 -5
- package/.code/agents/6c9cfc5f-0d0b-445c-b121-9f60082c4f70/error.txt +0 -1
- package/.code/agents/6f6f8f77-4ab0-4f6e-9f30-40e8be0bd8f5/error.txt +0 -1
- package/.code/agents/72a7cde4-fa8a-4024-9038-27faa550539b/error.txt +0 -1
- package/.code/agents/7b48335c-8247-43aa-9949-5f820ba8e199/error.txt +0 -1
- package/.code/agents/80944249-bea9-4ac5-87de-a666c4df306e/error.txt +0 -1
- package/.code/agents/826099df-1b66-4186-a915-7eb59f9db19d/error.txt +0 -5
- package/.code/agents/8291d158-18a8-4a92-b799-4e9a4d9cce88/error.txt +0 -1
- package/.code/agents/82fb71a3-20fb-4341-804a-a2fc900f95bc/error.txt +0 -1
- package/.code/agents/855790ea-54ee-43e4-8209-a66994e37590/error.txt +0 -1
- package/.code/agents/88ce3a2e-04f2-42be-9062-bf97aa798da0/error.txt +0 -3
- package/.code/agents/9a17e398-b6ed-4218-bb55-bc64a8d38ce8/error.txt +0 -8
- package/.code/agents/9a4f4bfc-a2a6-4f40-a896-9335b41a7ed1/error.txt +0 -1
- package/.code/agents/9b633e55-ef84-47d6-94bb-fd3dd172ad97/error.txt +0 -1
- package/.code/agents/9b81f3ab-c72b-4a81-9a8f-28a49ddba84a/error.txt +0 -8
- package/.code/agents/a35daf29-b2d1-4aef-9b42-dad63a76bd47/error.txt +0 -3
- package/.code/agents/a81990cc-69ee-44d2-b907-17403c9bc5d7/error.txt +0 -5
- package/.code/agents/ab56260a-4a83-4ad4-9410-f88a23d6520a/error.txt +0 -1
- package/.code/agents/ad722c31-2d1d-45f7-bae2-3f02ca455b60/error.txt +0 -1
- package/.code/agents/b62e8690-3324-4b97-9309-731bee79416b/error.txt +0 -5
- package/.code/agents/baf60a3a-752b-4ad8-99d6-df32423ed2eb/error.txt +0 -1
- package/.code/agents/be049042-7dcb-4ac8-9beb-c8f1aea67742/error.txt +0 -14
- package/.code/agents/bed1dcb4-bfce-4a9f-8594-0f994962aafd/error.txt +0 -1
- package/.code/agents/c324a6cf-e935-4ede-9529-b3ebc18e8d6b/error.txt +0 -5
- package/.code/agents/c37c06ff-dfe3-43f2-9bbc-3ec73ec8f41d/error.txt +0 -5
- package/.code/agents/c8cd6671-433a-456b-9f88-e51cb2df6bfc/error.txt +0 -11
- package/.code/agents/ca2ccb67-2f24-428e-b27d-9365beadd140/error.txt +0 -1
- package/.code/agents/cf08c0c8-e7f0-423e-93ba-547e8e818340/error.txt +0 -8
- package/.code/agents/d579c74f-874b-40a4-9d56-ced1eb6a701d/error.txt +0 -1
- package/.code/agents/df412c98-7378-4deb-8e1e-76c416931181/error.txt +0 -3
- package/.code/agents/e5134eb3-2af4-45b0-8998-051cb4afdb45/error.txt +0 -3
- package/.code/agents/e6308471-aa45-4e9e-9496-2e9404164d97/error.txt +0 -8
- package/.code/agents/e7bd8bc7-23fb-4f46-98dc-b0dcf11b75a1/error.txt +0 -1
- package/.code/agents/e92bec35-378d-4fe1-8ac0-6e1bb3c86911/error.txt +0 -5
- package/.code/agents/ed918fbf-2dc4-4aa2-bfc5-04b65d9471ea/error.txt +0 -1
- package/.code/agents/ef1d756f-b272-48fc-8729-f05c494674f7/error.txt +0 -1
- package/.code/agents/ef359853-0249-4e41-a804-c0fc459fe456/error.txt +0 -1
- package/.code/agents/effc7b4a-4b90-40a0-8c86-a7a99d2d5fd2/error.txt +0 -1
- package/.code/agents/fa15f8d5-8359-4a8b-83a3-2f2056b3ff40/error.txt +0 -3
- package/.code/agents/fbef4193-eadf-4c8a-83ff-4878a6310f25/error.txt +0 -8
- package/.code/agents/fd0a4b4a-fda4-4964-a6d6-2b8a2da387c6/error.txt +0 -1
- package/.gemini/settings.json +0 -8
- package/ADOS-2-Module-1-Complete-Manual.md +0 -757
- package/WARP.md +0 -245
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
-
import { toMoneyValueFromDecimal, fromMilli
|
|
2
|
+
import { toMoneyValue, toMoneyValueFromDecimal, fromMilli } from '../../utils/money.js';
|
|
3
3
|
const RECOMMENDATION_VERSION = '1.0';
|
|
4
4
|
const CONFIDENCE = {
|
|
5
5
|
CREATE_EXACT_MATCH: 0.95,
|
|
@@ -33,15 +33,15 @@ function processInsight(insight, context) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
function createSuggestedMatchRecommendation(match, context) {
|
|
36
|
-
const bankTxn = match.
|
|
37
|
-
if (match.
|
|
36
|
+
const bankTxn = match.bankTransaction;
|
|
37
|
+
if (match.ynabTransaction && match.confidence !== 'none') {
|
|
38
38
|
return {
|
|
39
39
|
id: randomUUID(),
|
|
40
40
|
action_type: 'review_duplicate',
|
|
41
41
|
priority: 'high',
|
|
42
|
-
confidence: Math.max(0, Math.min(1, match.
|
|
42
|
+
confidence: Math.max(0, Math.min(1, match.confidenceScore / 100)),
|
|
43
43
|
message: `Review possible match: ${bankTxn.payee}`,
|
|
44
|
-
reason: match.
|
|
44
|
+
reason: match.matchReason,
|
|
45
45
|
estimated_impact: toMoneyValueFromDecimal(0, context.analysis.balance_info.current_cleared.currency),
|
|
46
46
|
account_id: context.account_id,
|
|
47
47
|
metadata: {
|
|
@@ -49,20 +49,20 @@ function createSuggestedMatchRecommendation(match, context) {
|
|
|
49
49
|
created_at: new Date().toISOString(),
|
|
50
50
|
},
|
|
51
51
|
parameters: {
|
|
52
|
-
candidate_ids: [match.
|
|
52
|
+
candidate_ids: [match.ynabTransaction.id],
|
|
53
53
|
bank_transaction: bankTxn,
|
|
54
|
-
suggested_match_id: match.
|
|
54
|
+
suggested_match_id: match.ynabTransaction.id,
|
|
55
55
|
},
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
const isCombinationMatch =
|
|
58
|
+
const isCombinationMatch = (match.candidates?.length ?? 0) > 1;
|
|
59
59
|
if (isCombinationMatch) {
|
|
60
60
|
return createCombinationReviewRecommendation(match, context);
|
|
61
61
|
}
|
|
62
62
|
const parameters = {
|
|
63
63
|
account_id: context.account_id,
|
|
64
64
|
date: bankTxn.date,
|
|
65
|
-
amount:
|
|
65
|
+
amount: bankTxn.amount,
|
|
66
66
|
payee_name: bankTxn.payee,
|
|
67
67
|
cleared: 'cleared',
|
|
68
68
|
approved: true,
|
|
@@ -77,7 +77,7 @@ function createSuggestedMatchRecommendation(match, context) {
|
|
|
77
77
|
confidence: CONFIDENCE.CREATE_EXACT_MATCH,
|
|
78
78
|
message: `Create transaction for ${bankTxn.payee}`,
|
|
79
79
|
reason: `This transaction exactly matches your discrepancy`,
|
|
80
|
-
estimated_impact:
|
|
80
|
+
estimated_impact: toMoneyValue(bankTxn.amount, context.analysis.balance_info.current_cleared.currency),
|
|
81
81
|
account_id: context.account_id,
|
|
82
82
|
metadata: {
|
|
83
83
|
version: RECOMMENDATION_VERSION,
|
|
@@ -87,7 +87,7 @@ function createSuggestedMatchRecommendation(match, context) {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
function createCombinationReviewRecommendation(match, context) {
|
|
90
|
-
const bankTxn = match.
|
|
90
|
+
const bankTxn = match.bankTransaction;
|
|
91
91
|
const candidateIds = match.candidates?.map((candidate) => candidate.ynab_transaction.id) ?? [];
|
|
92
92
|
const candidateTotalAmount = match.candidates?.reduce((sum, candidate) => {
|
|
93
93
|
const amount = candidate.ynab_transaction.amount;
|
|
@@ -110,7 +110,7 @@ function createCombinationReviewRecommendation(match, context) {
|
|
|
110
110
|
metadata: {
|
|
111
111
|
version: RECOMMENDATION_VERSION,
|
|
112
112
|
created_at: new Date().toISOString(),
|
|
113
|
-
bank_transaction_amount:
|
|
113
|
+
bank_transaction_amount: toMoneyValue(bankTxn.amount, context.analysis.balance_info.current_cleared.currency),
|
|
114
114
|
candidate_total_amount: toMoneyValueFromDecimal(candidateTotalAmount, context.analysis.balance_info.current_cleared.currency),
|
|
115
115
|
candidate_count: match.candidates?.length ?? 0,
|
|
116
116
|
},
|
|
@@ -125,8 +125,8 @@ function createCombinationReviewRecommendation(match, context) {
|
|
|
125
125
|
...candidateIds.map((id) => ({
|
|
126
126
|
source: 'ynab',
|
|
127
127
|
id,
|
|
128
|
-
description: match.candidates?.find((c) => c.ynab_transaction.id === id)?.ynab_transaction
|
|
129
|
-
|
|
128
|
+
description: match.candidates?.find((c) => c.ynab_transaction.id === id)?.ynab_transaction.payee ??
|
|
129
|
+
'Unknown',
|
|
130
130
|
})),
|
|
131
131
|
],
|
|
132
132
|
},
|
|
@@ -205,7 +205,11 @@ function processUnmatchedTransactions(context) {
|
|
|
205
205
|
for (const bankTxn of context.analysis.unmatched_bank) {
|
|
206
206
|
recommendations.push(createUnmatchedBankRecommendation(bankTxn, context));
|
|
207
207
|
}
|
|
208
|
-
|
|
208
|
+
const matchesForReview = [
|
|
209
|
+
...context.analysis.suggested_matches,
|
|
210
|
+
...context.analysis.auto_matches,
|
|
211
|
+
];
|
|
212
|
+
for (const match of matchesForReview) {
|
|
209
213
|
recommendations.push(createSuggestedMatchRecommendation(match, context));
|
|
210
214
|
}
|
|
211
215
|
for (const ynabTxn of context.analysis.unmatched_ynab) {
|
|
@@ -219,7 +223,7 @@ function createUnmatchedBankRecommendation(txn, context) {
|
|
|
219
223
|
const parameters = {
|
|
220
224
|
account_id: context.account_id,
|
|
221
225
|
date: txn.date,
|
|
222
|
-
amount:
|
|
226
|
+
amount: txn.amount,
|
|
223
227
|
payee_name: txn.payee,
|
|
224
228
|
cleared: 'cleared',
|
|
225
229
|
approved: true,
|
|
@@ -234,7 +238,7 @@ function createUnmatchedBankRecommendation(txn, context) {
|
|
|
234
238
|
confidence: CONFIDENCE.UNMATCHED_BANK,
|
|
235
239
|
message: `Create missing transaction: ${txn.payee}`,
|
|
236
240
|
reason: 'Transaction appears on bank statement but not in YNAB',
|
|
237
|
-
estimated_impact:
|
|
241
|
+
estimated_impact: toMoneyValue(txn.amount, context.analysis.balance_info.current_cleared.currency),
|
|
238
242
|
account_id: context.account_id,
|
|
239
243
|
metadata: {
|
|
240
244
|
version: RECOMMENDATION_VERSION,
|
|
@@ -249,7 +253,7 @@ function createUpdateClearedRecommendation(txn, context) {
|
|
|
249
253
|
action_type: 'update_cleared',
|
|
250
254
|
priority: 'low',
|
|
251
255
|
confidence: CONFIDENCE.UPDATE_CLEARED,
|
|
252
|
-
message: `Mark transaction as cleared: ${txn.
|
|
256
|
+
message: `Mark transaction as cleared: ${txn.payee || 'Unknown'}`,
|
|
253
257
|
reason: 'Transaction exists in YNAB but not yet cleared',
|
|
254
258
|
estimated_impact: toMoneyValueFromDecimal(0, context.analysis.balance_info.current_cleared.currency),
|
|
255
259
|
account_id: context.account_id,
|
|
@@ -81,12 +81,13 @@ function formatBankTransactionLine(txn) {
|
|
|
81
81
|
return ` ${txn.date} - ${txn.payee.substring(0, 40).padEnd(40)} ${amountStr}`;
|
|
82
82
|
}
|
|
83
83
|
function formatSuggestedMatchLine(match) {
|
|
84
|
-
const bankTxn = match.
|
|
84
|
+
const bankTxn = match.bankTransaction;
|
|
85
85
|
const amountStr = formatAmount(bankTxn.amount);
|
|
86
|
-
const confidenceStr = `${match.
|
|
86
|
+
const confidenceStr = `${match.confidenceScore}%`;
|
|
87
87
|
return ` ${bankTxn.date} - ${bankTxn.payee.substring(0, 35).padEnd(35)} ${amountStr} (${confidenceStr} confidence)`;
|
|
88
88
|
}
|
|
89
|
-
function formatAmount(
|
|
89
|
+
function formatAmount(amountMilli) {
|
|
90
|
+
const amount = amountMilli / 1000;
|
|
90
91
|
const sign = amount >= 0 ? '+' : '-';
|
|
91
92
|
const absAmount = Math.abs(amount);
|
|
92
93
|
return `${sign}$${absAmount.toFixed(2)}`.padStart(10);
|
|
@@ -198,13 +199,13 @@ export function formatTransactionList(transactions, maxItems = 10) {
|
|
|
198
199
|
const lines = [];
|
|
199
200
|
const toShow = transactions.slice(0, maxItems);
|
|
200
201
|
for (const txn of toShow) {
|
|
201
|
-
if ('
|
|
202
|
-
|
|
202
|
+
if ('cleared' in txn) {
|
|
203
|
+
const ynabTxn = txn;
|
|
204
|
+
const payee = ynabTxn.payee_name ?? ynabTxn.payee ?? 'Unknown';
|
|
205
|
+
lines.push(` ${ynabTxn.date} - ${payee.substring(0, 40).padEnd(40)} ${formatAmount(ynabTxn.amount)}`);
|
|
203
206
|
}
|
|
204
207
|
else {
|
|
205
|
-
|
|
206
|
-
const payee = txn.payee_name ?? 'Unknown';
|
|
207
|
-
lines.push(` ${txn.date} - ${payee.substring(0, 40).padEnd(40)} ${formatAmount(amount)}`);
|
|
208
|
+
lines.push(formatBankTransactionLine(txn));
|
|
208
209
|
}
|
|
209
210
|
}
|
|
210
211
|
if (transactions.length > maxItems) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export function detectSignInversion(bankTransactions, ynabTransactions) {
|
|
2
|
+
if (bankTransactions.length === 0 || ynabTransactions.length === 0) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
const sampleSize = Math.min(20, bankTransactions.length);
|
|
6
|
+
const sample = bankTransactions.slice(0, sampleSize);
|
|
7
|
+
const matches = [];
|
|
8
|
+
for (const bankTxn of sample) {
|
|
9
|
+
const match = findClosestMatch(bankTxn, ynabTransactions);
|
|
10
|
+
if (match) {
|
|
11
|
+
matches.push(match);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (matches.length === 0) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const oppositeSignCount = matches.filter((m) => m.oppositeSign).length;
|
|
18
|
+
const oppositeSignRatio = oppositeSignCount / matches.length;
|
|
19
|
+
return oppositeSignRatio > 0.5;
|
|
20
|
+
}
|
|
21
|
+
function findClosestMatch(bankTxn, ynabTransactions) {
|
|
22
|
+
const bankDate = new Date(bankTxn.date);
|
|
23
|
+
const bankAbsAmount = Math.abs(bankTxn.amount);
|
|
24
|
+
let bestMatch = null;
|
|
25
|
+
let bestScore = 0;
|
|
26
|
+
for (const ynabTxn of ynabTransactions) {
|
|
27
|
+
const ynabDate = new Date(ynabTxn.date);
|
|
28
|
+
const ynabAbsAmount = Math.abs(ynabTxn.amount);
|
|
29
|
+
const amountDiff = Math.abs(bankAbsAmount - ynabAbsAmount);
|
|
30
|
+
const amountTolerance = 100;
|
|
31
|
+
if (amountDiff > amountTolerance) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const daysDiff = Math.abs(bankDate.getTime() - ynabDate.getTime()) / (1000 * 60 * 60 * 24);
|
|
35
|
+
if (daysDiff > 7) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const amountScore = amountDiff === 0 ? 100 : Math.max(0, 100 - amountDiff / 10);
|
|
39
|
+
const dateScore = daysDiff === 0 ? 100 : Math.max(0, 100 - daysDiff * 10);
|
|
40
|
+
const score = amountScore * 0.7 + dateScore * 0.3;
|
|
41
|
+
if (score > bestScore) {
|
|
42
|
+
bestScore = score;
|
|
43
|
+
const bankSign = Math.sign(bankTxn.amount);
|
|
44
|
+
const ynabSign = Math.sign(ynabTxn.amount);
|
|
45
|
+
const oppositeSign = bankSign !== 0 && ynabSign !== 0 && bankSign !== ynabSign;
|
|
46
|
+
bestMatch = {
|
|
47
|
+
bankAmount: bankTxn.amount,
|
|
48
|
+
ynabAmount: ynabTxn.amount,
|
|
49
|
+
oppositeSign,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return bestMatch;
|
|
54
|
+
}
|
|
@@ -1,23 +1,8 @@
|
|
|
1
1
|
import type { MoneyValue } from '../../utils/money.js';
|
|
2
|
+
import type { BankTransaction as CanonicalBankTransaction, NormalizedYNABTransaction as CanonicalYNABTransaction } from '../../types/reconciliation.js';
|
|
3
|
+
export type BankTransaction = CanonicalBankTransaction;
|
|
4
|
+
export type YNABTransaction = CanonicalYNABTransaction;
|
|
2
5
|
export type MatchConfidence = 'high' | 'medium' | 'low' | 'none';
|
|
3
|
-
export interface BankTransaction {
|
|
4
|
-
id: string;
|
|
5
|
-
date: string;
|
|
6
|
-
amount: number;
|
|
7
|
-
payee: string;
|
|
8
|
-
memo?: string;
|
|
9
|
-
original_csv_row: number;
|
|
10
|
-
}
|
|
11
|
-
export interface YNABTransaction {
|
|
12
|
-
id: string;
|
|
13
|
-
date: string;
|
|
14
|
-
amount: number;
|
|
15
|
-
payee_name: string | null;
|
|
16
|
-
category_name: string | null;
|
|
17
|
-
cleared: 'cleared' | 'uncleared' | 'reconciled';
|
|
18
|
-
approved: boolean;
|
|
19
|
-
memo?: string | null;
|
|
20
|
-
}
|
|
21
6
|
export interface MatchCandidate {
|
|
22
7
|
ynab_transaction: YNABTransaction;
|
|
23
8
|
confidence: number;
|
|
@@ -25,14 +10,14 @@ export interface MatchCandidate {
|
|
|
25
10
|
explanation: string;
|
|
26
11
|
}
|
|
27
12
|
export interface TransactionMatch {
|
|
28
|
-
|
|
29
|
-
|
|
13
|
+
bankTransaction: BankTransaction;
|
|
14
|
+
ynabTransaction?: YNABTransaction;
|
|
30
15
|
candidates?: MatchCandidate[];
|
|
31
16
|
confidence: MatchConfidence;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
confidenceScore: number;
|
|
18
|
+
matchReason: string;
|
|
19
|
+
topConfidence?: number;
|
|
20
|
+
actionHint?: string;
|
|
36
21
|
recommendation?: string;
|
|
37
22
|
}
|
|
38
23
|
export interface BalanceInfo {
|
|
@@ -90,19 +75,20 @@ export interface ReconciliationAction {
|
|
|
90
75
|
metadata?: Record<string, unknown>;
|
|
91
76
|
}
|
|
92
77
|
export interface MatchingConfig {
|
|
78
|
+
weights: {
|
|
79
|
+
amount: number;
|
|
80
|
+
date: number;
|
|
81
|
+
payee: number;
|
|
82
|
+
};
|
|
83
|
+
amountToleranceMilliunits: number;
|
|
93
84
|
dateToleranceDays: number;
|
|
94
|
-
amountToleranceCents: number;
|
|
95
|
-
descriptionSimilarityThreshold: number;
|
|
96
85
|
autoMatchThreshold: number;
|
|
97
|
-
|
|
86
|
+
suggestedMatchThreshold: number;
|
|
87
|
+
minimumCandidateScore: number;
|
|
88
|
+
exactAmountBonus: number;
|
|
89
|
+
exactDateBonus: number;
|
|
90
|
+
exactPayeeBonus: number;
|
|
98
91
|
}
|
|
99
|
-
export declare const DEFAULT_MATCHING_CONFIG: {
|
|
100
|
-
dateToleranceDays: number;
|
|
101
|
-
amountToleranceCents: number;
|
|
102
|
-
descriptionSimilarityThreshold: number;
|
|
103
|
-
autoMatchThreshold: number;
|
|
104
|
-
suggestionThreshold: number;
|
|
105
|
-
};
|
|
106
92
|
export interface ParsedCSVData {
|
|
107
93
|
transactions: BankTransaction[];
|
|
108
94
|
format_detected: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type * as ynab from 'ynab';
|
|
2
|
+
import type { NormalizedYNABTransaction } from '../../types/reconciliation.js';
|
|
3
|
+
export declare function normalizeYNABTransaction(txn: ynab.TransactionDetail): NormalizedYNABTransaction;
|
|
4
|
+
export declare function normalizeYNABTransactions(txns: ynab.TransactionDetail[]): NormalizedYNABTransaction[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function normalizeYNABTransaction(txn) {
|
|
2
|
+
return {
|
|
3
|
+
id: txn.id,
|
|
4
|
+
date: txn.date,
|
|
5
|
+
amount: txn.amount,
|
|
6
|
+
payee: txn.payee_name ?? null,
|
|
7
|
+
memo: txn.memo ?? null,
|
|
8
|
+
categoryName: txn.category_name ?? null,
|
|
9
|
+
cleared: txn.cleared,
|
|
10
|
+
approved: txn.approved,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function normalizeYNABTransactions(txns) {
|
|
14
|
+
return txns.map(normalizeYNABTransaction);
|
|
15
|
+
}
|
|
@@ -58,13 +58,13 @@ export type CreateTransactionParams = z.infer<typeof CreateTransactionSchema>;
|
|
|
58
58
|
type BulkTransactionInput = Omit<CreateTransactionParams, 'budget_id' | 'dry_run' | 'subtransactions'>;
|
|
59
59
|
export declare const CreateTransactionsSchema: z.ZodObject<{
|
|
60
60
|
budget_id: z.ZodString;
|
|
61
|
-
transactions: z.ZodArray<z.
|
|
61
|
+
transactions: z.ZodArray<z.ZodObject<{
|
|
62
|
+
date: z.ZodString;
|
|
62
63
|
cleared: z.ZodOptional<z.ZodEnum<{
|
|
63
64
|
cleared: "cleared";
|
|
64
65
|
uncleared: "uncleared";
|
|
65
66
|
reconciled: "reconciled";
|
|
66
67
|
}>>;
|
|
67
|
-
date: z.ZodString;
|
|
68
68
|
amount: z.ZodNumber;
|
|
69
69
|
memo: z.ZodOptional<z.ZodString>;
|
|
70
70
|
approved: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -81,21 +81,7 @@ export declare const CreateTransactionsSchema: z.ZodObject<{
|
|
|
81
81
|
category_id: z.ZodOptional<z.ZodString>;
|
|
82
82
|
import_id: z.ZodOptional<z.ZodString>;
|
|
83
83
|
payee_name: z.ZodOptional<z.ZodString>;
|
|
84
|
-
|
|
85
|
-
}, z.core.$strict>, z.ZodTransform<BulkTransactionInput, {
|
|
86
|
-
date: string;
|
|
87
|
-
amount: number;
|
|
88
|
-
account_id: string;
|
|
89
|
-
cleared?: "cleared" | "uncleared" | "reconciled" | undefined;
|
|
90
|
-
memo?: string | undefined;
|
|
91
|
-
approved?: boolean | undefined;
|
|
92
|
-
flag_color?: "red" | "orange" | "yellow" | "green" | "blue" | "purple" | undefined;
|
|
93
|
-
payee_id?: string | undefined;
|
|
94
|
-
category_id?: string | undefined;
|
|
95
|
-
import_id?: string | undefined;
|
|
96
|
-
payee_name?: string | undefined;
|
|
97
|
-
subtransactions?: any;
|
|
98
|
-
}>>>;
|
|
84
|
+
}, z.core.$strict>>;
|
|
99
85
|
dry_run: z.ZodOptional<z.ZodBoolean>;
|
|
100
86
|
}, z.core.$strict>;
|
|
101
87
|
export type CreateTransactionsParams = z.infer<typeof CreateTransactionsSchema>;
|
|
@@ -161,23 +161,7 @@ const BulkTransactionInputSchemaBase = CreateTransactionSchema.pick({
|
|
|
161
161
|
flag_color: true,
|
|
162
162
|
import_id: true,
|
|
163
163
|
});
|
|
164
|
-
const BulkTransactionInputSchema = BulkTransactionInputSchemaBase.
|
|
165
|
-
subtransactions: z.any().optional(),
|
|
166
|
-
})
|
|
167
|
-
.strict()
|
|
168
|
-
.superRefine((data, ctx) => {
|
|
169
|
-
if (data.subtransactions !== undefined) {
|
|
170
|
-
ctx.addIssue({
|
|
171
|
-
code: z.ZodIssueCode.custom,
|
|
172
|
-
message: 'Subtransactions are not supported in bulk transaction creation',
|
|
173
|
-
path: ['subtransactions'],
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
.transform((data) => {
|
|
178
|
-
const { subtransactions, ...rest } = data;
|
|
179
|
-
return rest;
|
|
180
|
-
});
|
|
164
|
+
const BulkTransactionInputSchema = BulkTransactionInputSchemaBase.strict();
|
|
181
165
|
export const CreateTransactionsSchema = z
|
|
182
166
|
.object({
|
|
183
167
|
budget_id: z.string().min(1, 'Budget ID is required'),
|
|
@@ -541,6 +525,10 @@ export async function handleListTransactions(ynabAPI, deltaFetcherOrParams, mayb
|
|
|
541
525
|
showing: `First ${preview.length} transactions:`,
|
|
542
526
|
total_count: transactions.length,
|
|
543
527
|
estimated_size_kb: Math.round(estimatedSize / 1024),
|
|
528
|
+
cached: cacheHit,
|
|
529
|
+
cache_info: cacheHit
|
|
530
|
+
? `Data retrieved from cache for improved performance${usedDelta ? ' (delta merge applied)' : ''}`
|
|
531
|
+
: 'Fresh data retrieved from YNAB API',
|
|
544
532
|
preview_transactions: preview.map((transaction) => ({
|
|
545
533
|
id: transaction.id,
|
|
546
534
|
date: transaction.date,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface BankTransaction {
|
|
2
|
+
id: string;
|
|
3
|
+
date: string;
|
|
4
|
+
amount: number;
|
|
5
|
+
payee: string;
|
|
6
|
+
memo?: string;
|
|
7
|
+
sourceRow: number;
|
|
8
|
+
raw: {
|
|
9
|
+
date: string;
|
|
10
|
+
amount: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
warnings?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface NormalizedYNABTransaction {
|
|
16
|
+
id: string;
|
|
17
|
+
date: string;
|
|
18
|
+
amount: number;
|
|
19
|
+
payee: string | null;
|
|
20
|
+
memo: string | null;
|
|
21
|
+
categoryName: string | null;
|
|
22
|
+
cleared: 'cleared' | 'uncleared' | 'reconciled';
|
|
23
|
+
approved: boolean;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { BaseError } from './baseError.js';
|
|
2
|
+
export { ValidationError } from './validationError.js';
|
|
3
|
+
import { BaseError } from './baseError.js';
|
|
4
|
+
export declare class ConfigurationError extends BaseError {
|
|
5
|
+
}
|
|
6
|
+
export declare class AuthenticationError extends BaseError {
|
|
7
|
+
}
|
|
8
|
+
export declare class YNABRequestError extends BaseError {
|
|
9
|
+
status: number;
|
|
10
|
+
statusText: string;
|
|
11
|
+
ynabErrorId?: string | undefined;
|
|
12
|
+
constructor(status: number, statusText: string, ynabErrorId?: string | undefined);
|
|
13
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { BaseError } from './baseError.js';
|
|
2
|
+
export { ValidationError } from './validationError.js';
|
|
3
|
+
import { BaseError } from './baseError.js';
|
|
4
|
+
export class ConfigurationError extends BaseError {
|
|
5
|
+
}
|
|
6
|
+
export class AuthenticationError extends BaseError {
|
|
7
|
+
}
|
|
8
|
+
export class YNABRequestError extends BaseError {
|
|
9
|
+
constructor(status, statusText, ynabErrorId) {
|
|
10
|
+
super(`YNAB API request failed: ${status} ${statusText}${ynabErrorId ? ` (Error ID: ${ynabErrorId})` : ''}`);
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.statusText = statusText;
|
|
13
|
+
this.ynabErrorId = ynabErrorId;
|
|
14
|
+
}
|
|
15
|
+
}
|