codexdb-sdk 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/PUBLISH.md +21 -0
- package/README.md +34 -0
- package/example_app.js +26 -0
- package/index.js +79 -0
- package/package.json +11 -0
- package/test-db.db.lock +0 -0
- package/test.js +34 -0
package/PUBLISH.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Publishing to npm
|
|
2
|
+
|
|
3
|
+
To publish the CodexDB Node.js SDK to npm:
|
|
4
|
+
|
|
5
|
+
1. Make sure you have an npm account: https://www.npmjs.com/signup
|
|
6
|
+
2. Login to npm in your terminal:
|
|
7
|
+
```sh
|
|
8
|
+
npm login
|
|
9
|
+
```
|
|
10
|
+
3. In the sdk/nodejs directory, publish the package:
|
|
11
|
+
```sh
|
|
12
|
+
npm publish
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If you get a name conflict error, choose a unique package name in package.json (e.g., codexdb-sdk-everton) and try again.
|
|
16
|
+
|
|
17
|
+
## Versioning
|
|
18
|
+
- Update the version field in package.json before publishing a new release.
|
|
19
|
+
|
|
20
|
+
## Automated Publishing (optional)
|
|
21
|
+
You can automate npm publishing using GitHub Actions or another CI/CD tool. Let me know if you want a workflow example!
|
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# CodexDB Node.js SDK
|
|
2
|
+
|
|
3
|
+
Node.js SDK for CodexDB. Simple wrapper for `codex-cli` as an external process.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install via npm (from local directory):
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install ./
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or, for development:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install -g ./
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage Example
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
const { CodexClient } = require('codexdb-sdk');
|
|
23
|
+
|
|
24
|
+
const client = new CodexClient({ file: 'test.db' });
|
|
25
|
+
client.set('user:1', { name: 'Alice', age: 30 });
|
|
26
|
+
console.log(client.get('user:1'));
|
|
27
|
+
console.log(client.keys());
|
|
28
|
+
client.delete('user:1');
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- Node.js 14+
|
|
34
|
+
- `codex-cli` binary available in your PATH
|
package/example_app.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const CodexClient = require('./index');
|
|
3
|
+
|
|
4
|
+
const dbPath = path.resolve(__dirname, 'example-db.db');
|
|
5
|
+
const client = new CodexClient({ file: dbPath });
|
|
6
|
+
|
|
7
|
+
(async () => {
|
|
8
|
+
// Set a value
|
|
9
|
+
await client.set('greeting', { msg: 'Hello from Node.js!' });
|
|
10
|
+
|
|
11
|
+
// Get the value
|
|
12
|
+
const value = await client.get('greeting');
|
|
13
|
+
console.log('Greeting:', value.msg);
|
|
14
|
+
|
|
15
|
+
// List all keys
|
|
16
|
+
const keys = await client.keys();
|
|
17
|
+
console.log('All keys:', keys);
|
|
18
|
+
|
|
19
|
+
// Delete the key
|
|
20
|
+
const deleted = await client.delete('greeting');
|
|
21
|
+
console.log('Deleted:', deleted);
|
|
22
|
+
|
|
23
|
+
// Cleanup
|
|
24
|
+
const fs = require('fs');
|
|
25
|
+
try { fs.unlinkSync(dbPath); } catch (e) {}
|
|
26
|
+
})();
|
package/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const { execFile } = require('child_process');
|
|
2
|
+
|
|
3
|
+
function execCodexCli(cliPath, args, env = {}) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
execFile(cliPath, args, { env: { ...process.env, ...env } }, (error, stdout, stderr) => {
|
|
6
|
+
if (error) {
|
|
7
|
+
const message = stderr.trim() || stdout.trim() || error.message;
|
|
8
|
+
return reject(new Error(message));
|
|
9
|
+
}
|
|
10
|
+
resolve(stdout.trim());
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class CodexClient {
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
if (!options.file) {
|
|
18
|
+
throw new Error('options.file is required (path to database file)');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.cliPath = options.cliPath || 'codex-cli';
|
|
22
|
+
this.file = options.file;
|
|
23
|
+
this.ledger = options.ledger ? '--ledger' : null;
|
|
24
|
+
this.env = {};
|
|
25
|
+
|
|
26
|
+
if (options.encryptionKey) {
|
|
27
|
+
this.env.CODEX_KEY = options.encryptionKey;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_baseArgs() {
|
|
32
|
+
const args = ['--file', this.file];
|
|
33
|
+
if (this.ledger) args.push(this.ledger);
|
|
34
|
+
return args;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async set(key, value) {
|
|
38
|
+
const payload = JSON.stringify(value);
|
|
39
|
+
const args = [...this._baseArgs(), 'set', key, payload];
|
|
40
|
+
await execCodexCli(this.cliPath, args, this.env);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async get(key) {
|
|
45
|
+
const args = [...this._baseArgs(), 'get', key];
|
|
46
|
+
const raw = await execCodexCli(this.cliPath, args, this.env);
|
|
47
|
+
if (!raw) return null;
|
|
48
|
+
return JSON.parse(raw);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async delete(key) {
|
|
52
|
+
const args = [...this._baseArgs(), 'delete', key];
|
|
53
|
+
await execCodexCli(this.cliPath, args, this.env);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async keys() {
|
|
58
|
+
const args = [...this._baseArgs(), 'keys'];
|
|
59
|
+
const raw = await execCodexCli(this.cliPath, args, this.env);
|
|
60
|
+
if (!raw) return [];
|
|
61
|
+
return raw.split('\n').filter((k) => k);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async has(key) {
|
|
65
|
+
const args = [...this._baseArgs(), 'has', key];
|
|
66
|
+
const raw = await execCodexCli(this.cliPath, args, this.env);
|
|
67
|
+
return raw.trim() === 'true';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async clear() {
|
|
71
|
+
const args = [...this._baseArgs(), 'clear'];
|
|
72
|
+
await execCodexCli(this.cliPath, args, this.env);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
CodexClient
|
|
79
|
+
};
|
package/package.json
ADDED
package/test-db.db.lock
ADDED
|
File without changes
|
package/test.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const CodexClient = require('./index');
|
|
4
|
+
|
|
5
|
+
(async () => {
|
|
6
|
+
const dbPath = path.resolve(__dirname, 'test-db.db');
|
|
7
|
+
|
|
8
|
+
// cleanup before test
|
|
9
|
+
try { fs.unlinkSync(dbPath); } catch (e) {}
|
|
10
|
+
|
|
11
|
+
const client = new CodexClient({ file: dbPath });
|
|
12
|
+
|
|
13
|
+
await client.set('test-key', { hello: 'world' });
|
|
14
|
+
const value = await client.get('test-key');
|
|
15
|
+
|
|
16
|
+
if (value.hello !== 'world') throw new Error('value mismatch');
|
|
17
|
+
|
|
18
|
+
const hasKey = await client.has('test-key');
|
|
19
|
+
if (!hasKey) throw new Error('expected key to exist');
|
|
20
|
+
|
|
21
|
+
const keys = await client.keys();
|
|
22
|
+
if (!keys.includes('test-key')) throw new Error('expected keys to include test-key');
|
|
23
|
+
|
|
24
|
+
await client.delete('test-key');
|
|
25
|
+
const hasAfterDelete = await client.has('test-key');
|
|
26
|
+
if (hasAfterDelete) throw new Error('expected key to be deleted');
|
|
27
|
+
|
|
28
|
+
await client.clear();
|
|
29
|
+
|
|
30
|
+
// cleanup after test
|
|
31
|
+
try { fs.unlinkSync(dbPath); } catch (e) {}
|
|
32
|
+
|
|
33
|
+
console.log('Node.js SDK smoke test passed');
|
|
34
|
+
})();
|