local-kv-cli 1.0.0 → 2.0.1
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/CHANGELOG.md +32 -0
- package/README.md +118 -10
- package/dist/args.d.ts +7 -0
- package/dist/args.js +71 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +306 -56
- package/dist/clipboard.d.ts +2 -0
- package/dist/clipboard.js +24 -0
- package/dist/env.d.ts +13 -0
- package/dist/env.js +59 -0
- package/dist/format.d.ts +34 -0
- package/dist/format.js +86 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +9 -2
- package/dist/locate.d.ts +19 -0
- package/dist/locate.js +75 -0
- package/dist/store.d.ts +66 -14
- package/dist/store.js +262 -58
- package/dist/values.d.ts +14 -0
- package/dist/values.js +73 -0
- package/package.json +20 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
- Added links to the GitHub repository, homepage and issue tracker on the npm page
|
|
6
|
+
|
|
7
|
+
## 2.0.0
|
|
8
|
+
|
|
9
|
+
### Breaking changes
|
|
10
|
+
|
|
11
|
+
- **New data file format.** Each value now stores its type, created/updated times and history, and values are grouped into namespaces. 1.x files are upgraded automatically on first use, and the old file is kept as `store.json.v1-backup`. 1.x can't read the new format.
|
|
12
|
+
- **Values are typed.** `lkv set n 42` now stores the number `42`, and `true`, `false` and JSON objects/arrays are stored as their type. Values like `007` or `1e5` stay text. Use `--type string` to keep text. Values from 1.x stay text.
|
|
13
|
+
- **Library API.** `Store` values are typed (`Value`) instead of always strings. `set(key, value, force)` is now `set(key, value, { force })`. `getStorePath()` was replaced by `locateStore()` / `globalStorePath()`.
|
|
14
|
+
- **Project stores.** Inside a folder with a `.lkv.json` (created by `lkv init`), `lkv` uses that file instead of the global store. Use `--global` to get the global store.
|
|
15
|
+
- The `LKV_STORE_PATH` environment variable still overrides everything.
|
|
16
|
+
|
|
17
|
+
### New
|
|
18
|
+
|
|
19
|
+
- `incr` / `decr` counters
|
|
20
|
+
- `history` of previous values (last 20 per key); `list --long` shows type and update time
|
|
21
|
+
- Namespaces: `-n <name>`, `LKV_NAMESPACE`, `lkv namespaces`
|
|
22
|
+
- `lkv init` for per-project stores
|
|
23
|
+
- `search`, `list --filter`
|
|
24
|
+
- `rename`
|
|
25
|
+
- `export` / `import` (handles UTF-16 files from Windows PowerShell's `>`)
|
|
26
|
+
- `env` (sh, PowerShell, cmd) and `run <command>`
|
|
27
|
+
- `get --copy` to copy a value to the clipboard, `get --json`
|
|
28
|
+
- `--version`
|
|
29
|
+
|
|
30
|
+
## 1.0.0
|
|
31
|
+
|
|
32
|
+
- First release: `set`, `get`, `update`, `delete`, `list`, `clear`, `path`
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# local-kv-cli
|
|
2
2
|
|
|
3
|
-
A tiny, zero-dependency CLI to store key-value pairs locally on your machine.
|
|
3
|
+
A tiny, zero-dependency CLI to store key-value pairs locally on your machine, with typed values, counters, history, namespaces, per-project stores and environment variable export.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,32 +8,140 @@ A tiny, zero-dependency CLI to store key-value pairs locally on your machine.
|
|
|
8
8
|
npm install -g local-kv-cli
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Basics
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
lkv set api_url https://example.com # create a pair
|
|
15
15
|
lkv get api_url # print a value
|
|
16
16
|
lkv update api_url https://new.com # change an existing value
|
|
17
|
-
lkv
|
|
18
|
-
lkv delete
|
|
19
|
-
lkv
|
|
20
|
-
lkv
|
|
17
|
+
lkv rename api_url base_url # rename a key
|
|
18
|
+
lkv delete base_url # remove a pair
|
|
19
|
+
lkv list # show all pairs
|
|
20
|
+
lkv clear # remove everything in the namespace
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
`set` won't overwrite an existing key; use `update`, or `set <key> <value> --force`.
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
## Typed values
|
|
26
|
+
|
|
27
|
+
Numbers, `true`/`false` and JSON are stored with their type:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
lkv set retries 3 # number
|
|
31
|
+
lkv set debug true # boolean
|
|
32
|
+
lkv set config '{"port":8080}' # JSON
|
|
33
|
+
lkv set zip 02134 # stays text (leading zero)
|
|
34
|
+
lkv set -t string code 42 # force a type: string, number, boolean or json
|
|
35
|
+
lkv get config --json # print as JSON
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Counters
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
lkv incr build_count # 1 (missing keys start at 0)
|
|
42
|
+
lkv incr build_count 10 # 11
|
|
43
|
+
lkv decr build_count # 10
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## History and details
|
|
47
|
+
|
|
48
|
+
Every change keeps the previous value (the last 20 per key).
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
lkv history retries # current value first, then older ones
|
|
52
|
+
lkv list --long # type and last update time for each key
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Search
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
lkv search example # key or value contains "example"
|
|
59
|
+
lkv list --filter api # key contains "api"
|
|
60
|
+
lkv list --json # everything as JSON
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Namespaces
|
|
64
|
+
|
|
65
|
+
Keep separate groups of values:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
lkv -n work set token abc123
|
|
69
|
+
lkv -n work list
|
|
70
|
+
lkv namespaces # list namespaces and how many keys each has
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
You can also set the `LKV_NAMESPACE` environment variable.
|
|
74
|
+
|
|
75
|
+
## Per-project stores
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cd my-project
|
|
79
|
+
lkv init # creates .lkv.json here
|
|
80
|
+
lkv set port 3000
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Inside that folder (and its subfolders) `lkv` uses the project's `.lkv.json`. Add `--global` (`-g`) to use your global store instead. Add `.lkv.json` to `.gitignore` if it holds private values.
|
|
84
|
+
|
|
85
|
+
`lkv path` shows which file is in use.
|
|
86
|
+
|
|
87
|
+
## Environment variables
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
eval "$(lkv env)" # bash / zsh
|
|
91
|
+
lkv env | Invoke-Expression # PowerShell
|
|
92
|
+
lkv env --shell cmd # cmd.exe syntax
|
|
93
|
+
lkv env --upper # API_URL instead of api_url
|
|
94
|
+
|
|
95
|
+
lkv run npm start # run a command with your values as env variables
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Keys that aren't valid variable names (like `my-key`) are skipped with a warning.
|
|
99
|
+
|
|
100
|
+
## Backup and restore
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
lkv export backup.json # current namespace
|
|
104
|
+
lkv export backup.json --all # every namespace
|
|
105
|
+
lkv import backup.json # skips keys that already exist
|
|
106
|
+
lkv import backup.json --force # overwrite them
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`import` also accepts a plain `{ "key": "value" }` JSON object.
|
|
110
|
+
|
|
111
|
+
## Clipboard
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
lkv get api_url --copy
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
On Linux this needs `wl-clipboard`, `xclip` or `xsel`.
|
|
118
|
+
|
|
119
|
+
## Where data is stored
|
|
120
|
+
|
|
121
|
+
1. The file in the `LKV_STORE_PATH` environment variable, if set
|
|
122
|
+
2. Otherwise a `.lkv.json` in the current folder or a parent folder
|
|
123
|
+
3. Otherwise `~/.local-kv/store.json`
|
|
26
124
|
|
|
27
125
|
## Use from code
|
|
28
126
|
|
|
29
127
|
```ts
|
|
30
128
|
import { Store } from "local-kv-cli";
|
|
31
129
|
|
|
32
|
-
const store = new Store();
|
|
33
|
-
|
|
34
|
-
|
|
130
|
+
const store = new Store(); // same lookup as the CLI
|
|
131
|
+
const work = new Store({ namespace: "work" });
|
|
132
|
+
const custom = new Store({ path: "./data.json" });
|
|
133
|
+
|
|
134
|
+
store.set("visits", 0);
|
|
135
|
+
store.incr("visits"); // 1
|
|
136
|
+
store.get("visits"); // 1
|
|
137
|
+
store.history("visits"); // [{ value: 0, type: "number", updated: "..." }]
|
|
138
|
+
store.entry("visits"); // value, type, created, updated, history
|
|
35
139
|
```
|
|
36
140
|
|
|
141
|
+
## Upgrading from 1.x
|
|
142
|
+
|
|
143
|
+
Your data is upgraded automatically the first time 2.x runs, and a copy of the old file is saved next to it as `store.json.v1-backup`. See [CHANGELOG.md](CHANGELOG.md) for breaking changes.
|
|
144
|
+
|
|
37
145
|
## License
|
|
38
146
|
|
|
39
147
|
MIT
|
package/dist/args.d.ts
ADDED
package/dist/args.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseArgs = parseArgs;
|
|
4
|
+
/** Flags that take a value, with their short aliases. */
|
|
5
|
+
const VALUE_FLAGS = {
|
|
6
|
+
"--namespace": "namespace",
|
|
7
|
+
"-n": "namespace",
|
|
8
|
+
"--type": "type",
|
|
9
|
+
"-t": "type",
|
|
10
|
+
"--filter": "filter",
|
|
11
|
+
"--shell": "shell",
|
|
12
|
+
};
|
|
13
|
+
/** On/off flags, with their short aliases. */
|
|
14
|
+
const BOOL_FLAGS = {
|
|
15
|
+
"--force": "force",
|
|
16
|
+
"-f": "force",
|
|
17
|
+
"--json": "json",
|
|
18
|
+
"--long": "long",
|
|
19
|
+
"-l": "long",
|
|
20
|
+
"--copy": "copy",
|
|
21
|
+
"-c": "copy",
|
|
22
|
+
"--all": "all",
|
|
23
|
+
"--global": "global",
|
|
24
|
+
"-g": "global",
|
|
25
|
+
"--upper": "upper",
|
|
26
|
+
"--help": "help",
|
|
27
|
+
"-h": "help",
|
|
28
|
+
"--version": "version",
|
|
29
|
+
"-v": "version",
|
|
30
|
+
};
|
|
31
|
+
/** Negative numbers ("-5") are values, not flags. */
|
|
32
|
+
function isFlag(token) {
|
|
33
|
+
return token.startsWith("-") && token !== "-" && !/^-\d/.test(token);
|
|
34
|
+
}
|
|
35
|
+
function parseArgs(argv) {
|
|
36
|
+
const parsed = { args: [], options: {}, flags: new Set() };
|
|
37
|
+
for (let i = 0; i < argv.length; i++) {
|
|
38
|
+
const token = argv[i];
|
|
39
|
+
if (token === "--") {
|
|
40
|
+
parsed.args.push(...argv.slice(i + 1));
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
// Everything after `run`'s first word belongs to the command being run.
|
|
44
|
+
if (parsed.command === "run" && parsed.args.length > 0) {
|
|
45
|
+
parsed.args.push(...argv.slice(i));
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
if (!isFlag(token)) {
|
|
49
|
+
if (parsed.command === undefined)
|
|
50
|
+
parsed.command = token;
|
|
51
|
+
else
|
|
52
|
+
parsed.args.push(token);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const eq = token.indexOf("=");
|
|
56
|
+
const name = eq === -1 ? token : token.slice(0, eq);
|
|
57
|
+
if (name in VALUE_FLAGS) {
|
|
58
|
+
const value = eq === -1 ? argv[++i] : token.slice(eq + 1);
|
|
59
|
+
if (value === undefined)
|
|
60
|
+
throw new Error(`${name} needs a value`);
|
|
61
|
+
parsed.options[VALUE_FLAGS[name]] = value;
|
|
62
|
+
}
|
|
63
|
+
else if (name in BOOL_FLAGS && eq === -1) {
|
|
64
|
+
parsed.flags.add(BOOL_FLAGS[name]);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error(`Unknown option "${token}". Run "lkv help".`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
2
|
+
/** Runs the CLI and returns the exit code. */
|
|
3
|
+
export declare function main(argv: string[]): number;
|