@jaskrowo/xtb2sure 0.0.0-stage → 0.1.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/.editorconfig +30 -0
- package/.github/actions/setup/action.yml +15 -0
- package/.github/actions/validate-pr-title/action.yml +18 -0
- package/.github/pull_request_template.md +3 -0
- package/.github/workflows/main.yml +51 -0
- package/.github/workflows/npm-audit.yml +23 -0
- package/.github/workflows/pr.yml +20 -0
- package/.github/workflows/validate.yml +60 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +1 -0
- package/.release-it.cjs +41 -0
- package/CODE_OF_CONDUCT.md +23 -0
- package/CONTRIBUTING.md +26 -0
- package/LICENSE +21 -0
- package/README.md +64 -2
- package/SECURITY.md +11 -0
- package/biome.json +20 -0
- package/commitlint.config.cjs +12 -0
- package/config/default.mjs +11 -0
- package/docs/PRD.md +141 -0
- package/knip.config.js +5 -0
- package/package.json +54 -5
- package/renovate.json +10 -0
- package/src/cli.ts +103 -0
- package/src/convert.ts +110 -0
- package/src/csv.ts +5 -0
- package/src/date.ts +22 -0
- package/src/excel.ts +105 -0
- package/src/index.ts +93 -0
- package/src/operations.ts +113 -0
- package/src/output.ts +24 -0
- package/src/types.ts +42 -0
- package/test/cli.test.ts +148 -0
- package/test/date.test.ts +8 -0
- package/test/fixtures/IKE/input.xlsx +0 -0
- package/test/fixtures/IKE/output_investments.csv +3 -0
- package/test/fixtures/IKE/output_transactions.csv +3 -0
- package/test/fixtures/PLN/input.xlsx +0 -0
- package/test/fixtures/PLN/output_investments.csv +5 -0
- package/test/fixtures/PLN/output_transactions.csv +6 -0
- package/test/integration.test.ts +171 -0
- package/test/operations.test.ts +23 -0
- package/tsconfig.json +24 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs.
|
|
2
|
+
# Requires EditorConfig JetBrains Plugin - http://github.com/editorconfig/editorconfig-jetbrains
|
|
3
|
+
|
|
4
|
+
# Set this file as the topmost .editorconfig
|
|
5
|
+
# (multiple files can be used, and are applied starting from current document location)
|
|
6
|
+
root = true
|
|
7
|
+
|
|
8
|
+
# Use bracketed regexp to target specific file types or file locations
|
|
9
|
+
[*.{ts,js,tsx,json,yml,yaml}]
|
|
10
|
+
|
|
11
|
+
# Use hard or soft tabs ["tab", "space"]
|
|
12
|
+
indent_style = space
|
|
13
|
+
|
|
14
|
+
# Size of a single indent [an integer, "tab"]
|
|
15
|
+
indent_size = tab
|
|
16
|
+
|
|
17
|
+
# Number of columns representing a tab character [an integer]
|
|
18
|
+
tab_width = 4
|
|
19
|
+
|
|
20
|
+
# Line breaks representation ["lf", "cr", "crlf"]
|
|
21
|
+
end_of_line = lf
|
|
22
|
+
|
|
23
|
+
# ["latin1", "utf-8", "utf-16be", "utf-16le"]
|
|
24
|
+
charset = utf-8
|
|
25
|
+
|
|
26
|
+
# Remove any whitespace characters preceding newline characters ["true", "false"]
|
|
27
|
+
trim_trailing_whitespace = false
|
|
28
|
+
|
|
29
|
+
# Ensure file ends with a newline when saving ["true", "false"]
|
|
30
|
+
insert_final_newline = true
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: Runtime & application setup
|
|
2
|
+
description: Sets right node version, installs dependencies
|
|
3
|
+
|
|
4
|
+
runs:
|
|
5
|
+
using: 'composite'
|
|
6
|
+
steps:
|
|
7
|
+
- name: Set correct node version
|
|
8
|
+
uses: actions/setup-node@v7
|
|
9
|
+
with:
|
|
10
|
+
node-version-file: package.json
|
|
11
|
+
cache: 'npm'
|
|
12
|
+
registry-url: 'https://registry.npmjs.org'
|
|
13
|
+
- name: Install dependencies
|
|
14
|
+
run: npm ci --quiet --no-audit --no-fund --ignore-scripts
|
|
15
|
+
shell: bash
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Validate PR title
|
|
2
|
+
description: Runs commitlint on the PR title
|
|
3
|
+
|
|
4
|
+
runs:
|
|
5
|
+
using: composite
|
|
6
|
+
steps:
|
|
7
|
+
- name: Set correct node version
|
|
8
|
+
uses: actions/setup-node@v7
|
|
9
|
+
with:
|
|
10
|
+
node-version: 24.x
|
|
11
|
+
- name: Install commitlint
|
|
12
|
+
run: npm install -g @commitlint/cli @commitlint/config-conventional
|
|
13
|
+
shell: bash
|
|
14
|
+
- name: Validate PR title
|
|
15
|
+
env:
|
|
16
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
17
|
+
run: echo "$PR_TITLE" | npx commitlint
|
|
18
|
+
shell: bash
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Main branch
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
merge_group:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
TZ: ${{ vars.TZ }}
|
|
16
|
+
FORCE_COLOR: 1
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
validate:
|
|
20
|
+
name: Validate
|
|
21
|
+
uses: ./.github/workflows/validate.yml
|
|
22
|
+
secrets: inherit
|
|
23
|
+
|
|
24
|
+
npm:
|
|
25
|
+
name: NPM audit
|
|
26
|
+
uses: ./.github/workflows/npm-audit.yml
|
|
27
|
+
secrets: inherit
|
|
28
|
+
|
|
29
|
+
release:
|
|
30
|
+
name: Release
|
|
31
|
+
needs: [validate]
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
concurrency: ${{ github.workflow }}-release
|
|
34
|
+
permissions:
|
|
35
|
+
contents: write
|
|
36
|
+
id-token: write
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v7
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
token: ${{ secrets.RELEASE_TOKEN }}
|
|
42
|
+
- name: Select correct node version, install deps
|
|
43
|
+
uses: ./.github/actions/setup
|
|
44
|
+
- name: Configure git
|
|
45
|
+
run: |
|
|
46
|
+
git config user.name "domeq"
|
|
47
|
+
git config user.email "iskra.wojtek@gmail.com"
|
|
48
|
+
- name: Create a release
|
|
49
|
+
env:
|
|
50
|
+
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
51
|
+
run: npm run release -- --ci
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
|
|
6
|
+
env:
|
|
7
|
+
TZ: Europe/Oslo
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
audit:
|
|
11
|
+
name: Audit
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 15
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
- name: Set correct node version
|
|
17
|
+
uses: actions/setup-node@v7
|
|
18
|
+
with:
|
|
19
|
+
node-version-file: package.json
|
|
20
|
+
cache: npm
|
|
21
|
+
registry-url: 'https://registry.npmjs.org'
|
|
22
|
+
- name: NPM Audit
|
|
23
|
+
run: npm audit --omit=dev --audit-level=high
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: PR
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
contents: read
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
env:
|
|
13
|
+
TZ: ${{ vars.TZ }}
|
|
14
|
+
FORCE_COLOR: 1
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
validate:
|
|
18
|
+
name: Validate
|
|
19
|
+
uses: ./.github/workflows/validate.yml
|
|
20
|
+
secrets: inherit
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Validate
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
id-token: write
|
|
5
|
+
contents: read
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
env:
|
|
11
|
+
TZ: ${{ vars.TZ }}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
validate_pr_title:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
name: Validate PR title
|
|
17
|
+
if: github.event.pull_request != null
|
|
18
|
+
timeout-minutes: 5
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v7
|
|
21
|
+
- name: Validate PR title
|
|
22
|
+
uses: ./.github/actions/validate-pr-title
|
|
23
|
+
linters:
|
|
24
|
+
name: Linters
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 15
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v7
|
|
29
|
+
- uses: ./.github/actions/setup
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: npm run lint
|
|
32
|
+
typecheck:
|
|
33
|
+
name: Typecheck
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
timeout-minutes: 15
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v7
|
|
38
|
+
- uses: ./.github/actions/setup
|
|
39
|
+
- name: Typecheck
|
|
40
|
+
run: npm run typecheck
|
|
41
|
+
knip:
|
|
42
|
+
name: Knip
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
timeout-minutes: 15
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v7
|
|
47
|
+
- uses: ./.github/actions/setup
|
|
48
|
+
- name: Knip
|
|
49
|
+
run: npm run knip
|
|
50
|
+
- name: Knip (production mode)
|
|
51
|
+
run: npm run knip -- --production
|
|
52
|
+
tests:
|
|
53
|
+
name: Tests
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
timeout-minutes: 15
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v7
|
|
58
|
+
- uses: ./.github/actions/setup
|
|
59
|
+
- name: Test
|
|
60
|
+
run: npm test
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no -- commitlint --edit ${1}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx lint-staged
|
package/.release-it.cjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
git: {
|
|
3
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: release-it placeholders
|
|
4
|
+
commitMessage: "chore: release ${version} \n\n${changelog}",
|
|
5
|
+
requireBranch: "main",
|
|
6
|
+
requireCleanWorkingDir: true,
|
|
7
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: release-it placeholders
|
|
8
|
+
tagName: "v${version}",
|
|
9
|
+
},
|
|
10
|
+
github: {
|
|
11
|
+
release: true,
|
|
12
|
+
tokenRef: "GITHUB_TOKEN",
|
|
13
|
+
},
|
|
14
|
+
npm: {
|
|
15
|
+
publish: true,
|
|
16
|
+
skipChecks: true,
|
|
17
|
+
},
|
|
18
|
+
plugins: {
|
|
19
|
+
"@release-it/conventional-changelog": {
|
|
20
|
+
infile: "CHANGELOG.md",
|
|
21
|
+
preset: {
|
|
22
|
+
name: "conventionalcommits",
|
|
23
|
+
types: [
|
|
24
|
+
{ section: "Features", type: "feat" },
|
|
25
|
+
{ section: "Features", type: "feature" },
|
|
26
|
+
{ section: "Bug Fixes", type: "fix" },
|
|
27
|
+
{ section: "Performance Improvements", type: "perf" },
|
|
28
|
+
{ section: "Reverts", type: "revert" },
|
|
29
|
+
{ section: "Documentation", type: "docs" },
|
|
30
|
+
{ section: "Styles", type: "style" },
|
|
31
|
+
{ section: "Miscellaneous Chores", type: "chore" },
|
|
32
|
+
{ section: "Code Refactoring", type: "refactor" },
|
|
33
|
+
{ section: "Tests", type: "test" },
|
|
34
|
+
{ section: "Build System", type: "build" },
|
|
35
|
+
{ section: "Continuous Integration", type: "ci" },
|
|
36
|
+
{ section: "Configuration changes", type: "config" },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We are committed to providing a friendly, safe, and welcoming environment for everyone.
|
|
6
|
+
|
|
7
|
+
## Our Standards
|
|
8
|
+
|
|
9
|
+
Examples of positive behavior:
|
|
10
|
+
|
|
11
|
+
- Being respectful and constructive
|
|
12
|
+
- Accepting and giving feedback gracefully
|
|
13
|
+
- Prioritizing collaboration and empathy
|
|
14
|
+
|
|
15
|
+
Examples of unacceptable behavior:
|
|
16
|
+
|
|
17
|
+
- Harassment, discrimination, or abusive language
|
|
18
|
+
- Personal attacks or trolling
|
|
19
|
+
- Publishing private information without consent
|
|
20
|
+
|
|
21
|
+
## Enforcement
|
|
22
|
+
|
|
23
|
+
Project maintainers are responsible for clarifying and enforcing this code of conduct.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing to `xtb2sure`.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Install Node.js 22+.
|
|
8
|
+
2. Install dependencies:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Validate changes
|
|
15
|
+
|
|
16
|
+
Run the test suite before opening a pull request:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm test
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Guidelines
|
|
23
|
+
|
|
24
|
+
- Keep behavior deterministic and fixture-driven.
|
|
25
|
+
- Add tests for every functional change.
|
|
26
|
+
- Prefer small, focused pull requests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xtb2sure contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# xtb2sure
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Convert XTB `.xlsx` exports into Sure-compatible CSV files.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Reads the `Cash Operations` sheet from an XTB export workbook.
|
|
8
|
+
- Produces two CSV files:
|
|
9
|
+
- transactions CSV (`date,amount,name,account,notes`)
|
|
10
|
+
- investments CSV (`date,ticker,currency,qty,price,account,name`)
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Node.js 24
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node --experimental-transform-types ./src/cli.ts convert <input.xlsx> --currency <CODE> --account "<ACCOUNT_NAME>"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
|
|
30
|
+
- `--out-dir <dir>`
|
|
31
|
+
- `--transactions-out <file>`
|
|
32
|
+
- `--investments-out <file>`
|
|
33
|
+
- `--strict`
|
|
34
|
+
- `--dry-run`
|
|
35
|
+
- `--report <file>`
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
node --experimental-transform-types ./src/cli.ts convert sample_data/IKE/input.xlsx --currency USD --account "XTB IKE"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
node --experimental-transform-types ./src/cli.ts convert sample_data/PLN/input.xlsx --currency PLN --account "XTB PLN" --out-dir ./out
|
|
45
|
+
|
|
46
|
+
Or via npm script:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run convert -- sample_data/PLN/input.xlsx --currency PLN --account "XTB PLN"
|
|
50
|
+
```
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Exit codes
|
|
54
|
+
|
|
55
|
+
- `0` success
|
|
56
|
+
- `1` conversion or validation failure
|
|
57
|
+
- `2` usage or config error
|
|
58
|
+
|
|
59
|
+
## Development
|
|
60
|
+
|
|
61
|
+
Run tests (Node.js test runner):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm test
|
|
65
|
+
```
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
If you discover a security issue, please report it privately to the maintainers.
|
|
4
|
+
|
|
5
|
+
Please include:
|
|
6
|
+
|
|
7
|
+
- A clear description of the issue
|
|
8
|
+
- Steps to reproduce
|
|
9
|
+
- Potential impact
|
|
10
|
+
|
|
11
|
+
Do not open public issues for security vulnerabilities.
|
package/biome.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.2.6/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"formatter": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"indentStyle": "space",
|
|
11
|
+
"indentWidth": 4,
|
|
12
|
+
"lineWidth": 120
|
|
13
|
+
},
|
|
14
|
+
"linter": {
|
|
15
|
+
"enabled": true,
|
|
16
|
+
"rules": {
|
|
17
|
+
"recommended": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
extends: ["@commitlint/config-conventional"],
|
|
3
|
+
rules: {
|
|
4
|
+
"body-max-line-length": [2, "always", Infinity],
|
|
5
|
+
"footer-max-line-length": [2, "always", Infinity],
|
|
6
|
+
"type-enum": [
|
|
7
|
+
2,
|
|
8
|
+
"always",
|
|
9
|
+
["build", "chore", "ci", "config", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test"],
|
|
10
|
+
],
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const NAME = process.env.DD_SERVICE || "xtb2sure";
|
|
2
|
+
const ENVIRONMENT = process.env.NODE_ENV || "development";
|
|
3
|
+
const VERSION = process.env.npm_package_version || "dev";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
application: {
|
|
7
|
+
env: ENVIRONMENT,
|
|
8
|
+
name: NAME,
|
|
9
|
+
version: VERSION,
|
|
10
|
+
},
|
|
11
|
+
};
|
package/docs/PRD.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# xtb2sure PRD
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Build an open-source TypeScript CLI that converts XTB `.xlsx` exports into two Sure-compatible CSV files:
|
|
6
|
+
|
|
7
|
+
1. transactions CSV (for Sure Transactions import)
|
|
8
|
+
2. investments CSV (for Sure Trades import)
|
|
9
|
+
|
|
10
|
+
Target runtime is current Node LTS, executed directly via Node strip-types.
|
|
11
|
+
|
|
12
|
+
## Confirmed Decisions
|
|
13
|
+
|
|
14
|
+
- Input format: `.xlsx`
|
|
15
|
+
- Source data: only `Cash Operations` sheet
|
|
16
|
+
- Output: two CSVs per input file
|
|
17
|
+
- Date output format: `YYYY-MM-DD`
|
|
18
|
+
- Currency: required CLI parameter
|
|
19
|
+
- Account: account-level label provided by CLI (e.g. `XTB PLN`, `XTB IKE`)
|
|
20
|
+
- Include tax rows (`Free funds interest tax`, `Withholding tax`)
|
|
21
|
+
- Ignore summary `Total` row
|
|
22
|
+
- Trade ticker uses XTB input as-is (e.g. `EIMI.UK`, `IUSQ.DE`)
|
|
23
|
+
|
|
24
|
+
## Input Schema (XTB Cash Operations)
|
|
25
|
+
|
|
26
|
+
Relevant columns:
|
|
27
|
+
- `Type`
|
|
28
|
+
- `Instrument`
|
|
29
|
+
- `Ticker`
|
|
30
|
+
- `Time`
|
|
31
|
+
- `Amount`
|
|
32
|
+
- `ID`
|
|
33
|
+
- `Comment`
|
|
34
|
+
- `Product`
|
|
35
|
+
- `Position ID`
|
|
36
|
+
|
|
37
|
+
## Output A: Transactions CSV
|
|
38
|
+
|
|
39
|
+
Header:
|
|
40
|
+
- `date,amount,name,account,notes`
|
|
41
|
+
|
|
42
|
+
Includes operation types:
|
|
43
|
+
- `Deposit`
|
|
44
|
+
- `IKE deposit`
|
|
45
|
+
- `IKZE deposit`
|
|
46
|
+
- `Free funds interest`
|
|
47
|
+
- `Free funds interest tax`
|
|
48
|
+
- `Withholding tax`
|
|
49
|
+
|
|
50
|
+
Mapping:
|
|
51
|
+
- `date` from `Time` (Excel serial UTC) -> `YYYY-MM-DD`
|
|
52
|
+
- `amount` from `Amount` (signed as-is)
|
|
53
|
+
- `name` from `Type` (or normalized label if fixture requires)
|
|
54
|
+
- `account` from CLI account label
|
|
55
|
+
- `notes` as traceable text including `XTB <ID>` and source comment
|
|
56
|
+
|
|
57
|
+
## Output B: Investments CSV
|
|
58
|
+
|
|
59
|
+
Header:
|
|
60
|
+
- `date,ticker,currency,qty,price,account,name`
|
|
61
|
+
|
|
62
|
+
Includes operation types:
|
|
63
|
+
- `Stock purchase`
|
|
64
|
+
- `Stock sell`
|
|
65
|
+
|
|
66
|
+
Mapping:
|
|
67
|
+
- `date` from `Time` -> `YYYY-MM-DD`
|
|
68
|
+
- `ticker` from XTB `Ticker` as-is (e.g. `IPOL.UK`, `SXRV.DE`)
|
|
69
|
+
- `currency` from CLI currency argument
|
|
70
|
+
- `qty` parsed from `Comment` (sell rows negative where reflected in fixture)
|
|
71
|
+
- `price` parsed from `Comment` (`@ <price>`)
|
|
72
|
+
- `account` from CLI account label
|
|
73
|
+
- `name` fixture-compatible human-readable label including `XTB <ID>`
|
|
74
|
+
|
|
75
|
+
## CLI (v1)
|
|
76
|
+
|
|
77
|
+
Command:
|
|
78
|
+
- `xtb2sure convert <input.xlsx> --currency <CODE> --account "<ACCOUNT_NAME>"`
|
|
79
|
+
|
|
80
|
+
Options:
|
|
81
|
+
- `--out-dir <dir>`
|
|
82
|
+
- `--transactions-out <file>`
|
|
83
|
+
- `--investments-out <file>`
|
|
84
|
+
- `--strict`
|
|
85
|
+
- `--dry-run`
|
|
86
|
+
- `--report <file>`
|
|
87
|
+
|
|
88
|
+
Exit codes:
|
|
89
|
+
- `0` success
|
|
90
|
+
- `1` conversion/validation failure
|
|
91
|
+
- `2` usage/config error
|
|
92
|
+
|
|
93
|
+
## TDD Plan
|
|
94
|
+
|
|
95
|
+
### Unit tests
|
|
96
|
+
- Excel serial date conversion
|
|
97
|
+
- operation classification (transaction/investment/ignored)
|
|
98
|
+
- qty/price parser from comment text
|
|
99
|
+
- per-row mapping by type
|
|
100
|
+
|
|
101
|
+
### Integration tests (fixture exact)
|
|
102
|
+
- `sample_data/IKE/input.xlsx` -> exact match:
|
|
103
|
+
- `sample_data/IKE/output_transactions.csv`
|
|
104
|
+
- `sample_data/IKE/output_investments.csv`
|
|
105
|
+
- `sample_data/PLN/input.xlsx` -> exact match:
|
|
106
|
+
- `sample_data/PLN/output_transactions.csv`
|
|
107
|
+
- `sample_data/PLN/output_investments.csv`
|
|
108
|
+
- investments schema regression checks:
|
|
109
|
+
- `ticker` equals source `Cash Operations.Ticker` value for the matching XTB operation ID
|
|
110
|
+
|
|
111
|
+
### CLI tests
|
|
112
|
+
- required args validation (`--currency`, `--account`)
|
|
113
|
+
- output file generation
|
|
114
|
+
- `--dry-run` behavior
|
|
115
|
+
- strict-mode failure behavior
|
|
116
|
+
- summary counters and exit codes
|
|
117
|
+
|
|
118
|
+
## Open Source Baseline
|
|
119
|
+
|
|
120
|
+
Include in repo from the beginning:
|
|
121
|
+
- `README.md`
|
|
122
|
+
- `LICENSE` (permissive and inclusive; MIT recommended unless you choose otherwise)
|
|
123
|
+
- `CONTRIBUTING.md`
|
|
124
|
+
- `CODE_OF_CONDUCT.md`
|
|
125
|
+
- optional but recommended: `SECURITY.md`, CI workflow, issue templates
|
|
126
|
+
|
|
127
|
+
## Non-goals (v1)
|
|
128
|
+
|
|
129
|
+
- `Closed Positions` / `Open Positions` parsing
|
|
130
|
+
- Sure API upload automation
|
|
131
|
+
- FX conversion logic
|
|
132
|
+
- Data enrichment beyond deterministic mapping
|
|
133
|
+
|
|
134
|
+
## Fixture Status
|
|
135
|
+
|
|
136
|
+
Current fixtures are aligned and usable for TDD:
|
|
137
|
+
- `sample_data/IKE`
|
|
138
|
+
- `sample_data/PLN`
|
|
139
|
+
|
|
140
|
+
Investments outputs now use:
|
|
141
|
+
- ticker from input as-is
|
package/knip.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@jaskrowo/xtb2sure",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Convert XTB .xlsx exports into Sure-compatible CSV files",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": "24"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"xtb2sure": "./src/cli.ts"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "node --experimental-transform-types --watch src/index.ts",
|
|
19
|
+
"convert": "node --experimental-transform-types ./src/cli.ts convert",
|
|
20
|
+
"format": "biome format --write .",
|
|
21
|
+
"knip": "knip",
|
|
22
|
+
"lint-fix": "biome check --write .",
|
|
23
|
+
"lint": "biome check .",
|
|
24
|
+
"prepare": "husky",
|
|
25
|
+
"release": "release-it",
|
|
26
|
+
"start": "node --experimental-transform-types src/index.ts",
|
|
27
|
+
"test": "node --experimental-transform-types --test",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"lint-staged": {
|
|
31
|
+
"*": [
|
|
32
|
+
"biome check --write --no-errors-on-unmatched"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"imports": {
|
|
36
|
+
"#*": "./src/*"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@biomejs/biome": "2.5.15",
|
|
40
|
+
"@commitlint/cli": "21.2.3",
|
|
41
|
+
"@commitlint/config-conventional": "21.2.3",
|
|
42
|
+
"@release-it/conventional-changelog": "12.0.2",
|
|
43
|
+
"@types/node": "24.19.1",
|
|
44
|
+
"husky": "9.1.7",
|
|
45
|
+
"knip": "6.41.0",
|
|
46
|
+
"lint-staged": "17.6.0",
|
|
47
|
+
"release-it": "21.1.1",
|
|
48
|
+
"typescript": "5.9.3"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"commander": "15.0.0",
|
|
52
|
+
"csv-stringify": "6.9.0",
|
|
53
|
+
"xlsx": "0.18.5"
|
|
54
|
+
}
|
|
55
|
+
}
|