fix: default bridge and tests to project venv Python
Use .venv/bin/python3 by default, with PYTHON_PATH as an override, and update the setup script and docs to match the new virtualenv-based workflow.
This commit is contained in:
+20
-58
@@ -1,58 +1,20 @@
|
|||||||
# kdbx-lib
|
{
|
||||||
|
"name": "kdbx-lib",
|
||||||
TypeScript wrapper around `pykeepass` for read-only access to KeePass `.kdbx` files.
|
"packageManager": "bun@1.0.0",
|
||||||
|
"version": "0.1.0",
|
||||||
## Architecture
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
- Public API: TypeScript
|
"scripts": {
|
||||||
- Runtime backend: Python 3
|
"example": "bun run src/example.ts",
|
||||||
- Bridge: `src/python/bridge.py`
|
"validate": "bun run test",
|
||||||
- Transport: JSON over stdin/stdout
|
"test": "bun test",
|
||||||
- Backend library: `pykeepass`
|
"test:unit": "bun test",
|
||||||
|
"test:integration": "bun run src/test-integration.ts",
|
||||||
## Requirements
|
"setup:python": "python3 -m venv .venv && .venv/bin/pip install pykeepass"
|
||||||
|
},
|
||||||
- Node.js or Bun
|
"dependencies": {},
|
||||||
- Python 3
|
"devDependencies": {
|
||||||
- `pykeepass` installed in the Python environment used by the bridge
|
"typescript": "^5.5.0",
|
||||||
- A project-local `.venv` works well
|
"bun-types": "^1.1.0"
|
||||||
|
}
|
||||||
## Python setup
|
}
|
||||||
|
|
||||||
Install dependencies with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bun run setup:python
|
|
||||||
```
|
|
||||||
|
|
||||||
Manual alternative:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python3 -m pip install pykeepass
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core behavior
|
|
||||||
|
|
||||||
- Read-only library; it does not modify databases.
|
|
||||||
- `openKeePassDatabase(path, options)` opens a database through the Python bridge.
|
|
||||||
- `listEntries()` returns all entry fields exposed by the bridge: `title`, `username`, `password`, `url`, `notes`, `groupPath`, and `otp` when present.
|
|
||||||
- `findEntries(query)` performs partial matching and returns full entries.
|
|
||||||
- `listGroups()` returns group names and paths.
|
|
||||||
- `close()` is currently a no-op.
|
|
||||||
|
|
||||||
## Fixture facts
|
|
||||||
|
|
||||||
- Bundled fixtures: `tests/fixtures/data.kdbx` and `tests/fixtures/empty.kdbx`
|
|
||||||
- Fixture passwords and expected content live in companion JSON files
|
|
||||||
- `data.kdbx` contains four entries: `root`, `otp1`, `f1-item1`, `f2-item1`
|
|
||||||
- The fixture tree is `Racine/ -> root, otp1, Folder1/ -> f1-item1, Folder2/ -> f2-item1`
|
|
||||||
- Integration tests cover entries, groups, and the `otp1` OTP/TOTP value
|
|
||||||
- Canonical OTP value is the full `otpauth://...` URI returned by `pykeepass`
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- The bridge currently launches a Python process per call; simple but expensive.
|
|
||||||
- Errors from the bridge are propagated to TypeScript, including exit code when available.
|
|
||||||
- The API is still flatter than the real KeePass model.
|
|
||||||
- More failure-path tests are needed.
|
|
||||||
- Future improvement: a persistent Python process if performance becomes important.
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ The TypeScript layer launches a Python bridge and exchanges JSON through stdin/s
|
|||||||
- Node.js or Bun
|
- Node.js or Bun
|
||||||
- Python 3
|
- Python 3
|
||||||
- `pykeepass` installed in the Python environment used by the bridge (the project provides `bun run setup:python`)
|
- `pykeepass` installed in the Python environment used by the bridge (the project provides `bun run setup:python`)
|
||||||
|
- The bridge defaults to `.venv/bin/python3` when available, or you can override with `PYTHON_PATH`
|
||||||
|
|
||||||
## Python setup
|
## Python setup
|
||||||
|
|
||||||
@@ -28,10 +29,10 @@ bun run setup:python
|
|||||||
If you prefer manual installation:
|
If you prefer manual installation:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m pip install pykeepass
|
python3 -m venv .venv && .venv/bin/pip install pykeepass
|
||||||
```
|
```
|
||||||
|
|
||||||
The bridge also works with a project-local virtual environment such as `.venv` if you want to pin Python dependencies.
|
The bridge also works with a project-local virtual environment such as `.venv` and the tests will use it when present.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
"test": "bun test",
|
"test": "bun test",
|
||||||
"test:unit": "bun test",
|
"test:unit": "bun test",
|
||||||
"test:integration": "bun run src/test-integration.ts",
|
"test:integration": "bun run src/test-integration.ts",
|
||||||
"setup:python": "python3 -m pip install pykeepass"
|
"setup:python": "test -x .venv/bin/python3 || python3 -m venv .venv && .venv/bin/pip install pykeepass"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ export class KeePassDatabase {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly path: string,
|
private readonly path: string,
|
||||||
private readonly options: KeePassOpenOptions,
|
private readonly options: KeePassOpenOptions,
|
||||||
private readonly pythonPath = "python3",
|
private readonly pythonPath = process.env.PYTHON_PATH ?? ".venv/bin/python3",
|
||||||
private readonly bridgePath = new URL("./python/bridge.py", import.meta.url)
|
private readonly bridgePath = new URL("./python/bridge.py", import.meta.url)
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ const FIXTURE_PATH = "tests/fixtures/data.kdbx";
|
|||||||
const FIXTURE_DATA_PATH = "tests/fixtures/data.kdbx.json";
|
const FIXTURE_DATA_PATH = "tests/fixtures/data.kdbx.json";
|
||||||
|
|
||||||
async function ensurePyKeePass(): Promise<boolean> {
|
async function ensurePyKeePass(): Promise<boolean> {
|
||||||
const child = Bun.spawn(["python3", "-c", "import pykeepass; print('ok')"], {
|
const python = process.env.PYTHON_PATH ?? ".venv/bin/python3";
|
||||||
|
const child = Bun.spawn([python, "-c", "import pykeepass; print('ok')"], {
|
||||||
stdout: "pipe",
|
stdout: "pipe",
|
||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
});
|
});
|
||||||
@@ -95,7 +96,7 @@ test("lists the groups from the bundled data fixture", async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const db = openKeePassDatabase(FIXTURE_PATH, { password });
|
const db = openKeePassDatabase(FIXTURE_PATH, { password });
|
||||||
const groups = await db.listGroups();
|
const groups = await db.listGroups();
|
||||||
expect(groups).toEqual([
|
expect(groups).toEqual([
|
||||||
{ name: "Racine", path: "" },
|
{ name: "Racine", path: "" },
|
||||||
{ name: "Folder1", path: "Folder1" },
|
{ name: "Folder1", path: "Folder1" },
|
||||||
@@ -145,4 +146,3 @@ test("uses the JSON fixture content as the source of truth for expectations", as
|
|||||||
"\t\t- f2-item1",
|
"\t\t- f2-item1",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user