@james-pre/config 1.1.0 → 1.2.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/README.md +12 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.js +79 -0
- package/package.json +20 -36
package/README.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
# @james-pre/config
|
|
2
2
|
|
|
3
3
|
A small library for managing configuration files.
|
|
4
|
+
|
|
5
|
+
## CLI
|
|
6
|
+
|
|
7
|
+
`@james-pre/config/cli` adds a `config` command to a [Commander](https://github.com/tj/commander.js) program, with `dump`, `get`, `set`, `list`, and `schema`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { configCommand } from '@james-pre/config/cli';
|
|
11
|
+
|
|
12
|
+
configCommand(program, configManager);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Commander is an optional peer dependency, needed only for the CLI.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import type { FileType, Manager } from './manager.js';
|
|
4
|
+
export interface ConfigCommandOptions {
|
|
5
|
+
/** @default 'config' */
|
|
6
|
+
name?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Keys whose values `--redact` hides, wherever they are.
|
|
9
|
+
* @default ['password', 'secret']
|
|
10
|
+
*/
|
|
11
|
+
sensitive?: readonly string[];
|
|
12
|
+
/** The kind of file `set` writes to without `--type`, otherwise the most recently loaded one. */
|
|
13
|
+
defaultType?: FileType;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Add a command for reading and changing a manager's configuration to `parent`.
|
|
17
|
+
* @returns the new command, for adding more subcommands
|
|
18
|
+
*/
|
|
19
|
+
export declare function configCommand<C extends Command>(parent: C, manager: Manager<z.ZodObject>, options?: ConfigCommandOptions): Command;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { getByString, setByString } from 'utilium';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
const fileTypes = ['system', 'user', 'local'];
|
|
4
|
+
function redact(value, keys) {
|
|
5
|
+
if (Array.isArray(value))
|
|
6
|
+
return value.map(item => redact(item, keys));
|
|
7
|
+
if (typeof value != 'object' || value === null)
|
|
8
|
+
return value;
|
|
9
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, keys.includes(key) ? '[redacted]' : redact(child, keys)]));
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Add a command for reading and changing a manager's configuration to `parent`.
|
|
13
|
+
* @returns the new command, for adding more subcommands
|
|
14
|
+
*/
|
|
15
|
+
export function configCommand(parent, manager, options = {}) {
|
|
16
|
+
const { sensitive = ['password', 'secret'] } = options;
|
|
17
|
+
const command = parent
|
|
18
|
+
.command(options.name ?? 'config')
|
|
19
|
+
.description('Manage the configuration')
|
|
20
|
+
.option('-j, --json', 'read and write values as JSON', false)
|
|
21
|
+
.option('-r, --redact', 'hide sensitive values', false);
|
|
22
|
+
function output(value) {
|
|
23
|
+
const { json, redact: hide } = command.opts();
|
|
24
|
+
if (hide)
|
|
25
|
+
value = redact(value, sensitive);
|
|
26
|
+
console.log(json ? JSON.stringify(value, null, 4) : value);
|
|
27
|
+
}
|
|
28
|
+
command
|
|
29
|
+
.command('dump')
|
|
30
|
+
.description('Output the entire current configuration')
|
|
31
|
+
.action(() => output(manager.data));
|
|
32
|
+
command
|
|
33
|
+
.command('get')
|
|
34
|
+
.description('Get a config value')
|
|
35
|
+
.argument('<key>', 'the key to get')
|
|
36
|
+
.action(key => output(getByString(manager.data, key)));
|
|
37
|
+
command
|
|
38
|
+
.command('set')
|
|
39
|
+
.description('Set a config value, which must be JSON for anything but a string')
|
|
40
|
+
.argument('<key>', 'the key to set')
|
|
41
|
+
.argument('<value>', 'the value')
|
|
42
|
+
.addOption(command.createOption('-t, --type <type>', 'the kind of file to write to').choices(fileTypes))
|
|
43
|
+
.addOption(command.createOption('-g, --global', 'write to the system file, like --type system').conflicts('type'))
|
|
44
|
+
.action(function (key, value, opts) {
|
|
45
|
+
let parsed = value;
|
|
46
|
+
if (command.opts().json) {
|
|
47
|
+
try {
|
|
48
|
+
parsed = JSON.parse(value);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
this.error('error: value is not valid JSON');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const update = {};
|
|
55
|
+
setByString(update, key, parsed);
|
|
56
|
+
try {
|
|
57
|
+
manager.update(update, opts.global ? 'system' : (opts.type ?? options.defaultType));
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (!(error instanceof z.ZodError))
|
|
61
|
+
throw error;
|
|
62
|
+
this.error('error: invalid value\n' + z.prettifyError(error));
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
command
|
|
66
|
+
.command('list')
|
|
67
|
+
.alias('ls')
|
|
68
|
+
.alias('files')
|
|
69
|
+
.description('List loaded config files')
|
|
70
|
+
.action(() => {
|
|
71
|
+
for (const path of manager.filePaths)
|
|
72
|
+
console.log(path);
|
|
73
|
+
});
|
|
74
|
+
command
|
|
75
|
+
.command('schema')
|
|
76
|
+
.description('Get the JSON schema for config files')
|
|
77
|
+
.action(() => output(z.toJSONSchema(manager.fileSchema, { io: 'input' })));
|
|
78
|
+
return command;
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@james-pre/config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Manage configuration files",
|
|
5
|
+
"author": "James Prevett <jp@jamespre.dev> (https://jamespre.dev)",
|
|
6
|
+
"license": "LGPL-3.0-or-later",
|
|
5
7
|
"funding": {
|
|
6
8
|
"type": "individual",
|
|
7
9
|
"url": "https://github.com/sponsors/james-pre"
|
|
8
10
|
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/james-pre/common.git",
|
|
14
|
+
"directory": "packages/config"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/james-pre/common/tree/main/packages/config#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/james-pre/common/issues"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
9
21
|
"main": "dist/index.js",
|
|
10
22
|
"types": "dist/index.d.ts",
|
|
11
|
-
"type": "module",
|
|
12
23
|
"exports": {
|
|
13
24
|
".": "./dist/index.js",
|
|
14
25
|
"./*": "./dist/*.js"
|
|
@@ -18,51 +29,24 @@
|
|
|
18
29
|
"README.md"
|
|
19
30
|
],
|
|
20
31
|
"scripts": {
|
|
21
|
-
"
|
|
22
|
-
"format": "prettier --write .",
|
|
23
|
-
"build": "tsc -b",
|
|
24
|
-
"lint": "tsc -b --noEmit && eslint src",
|
|
25
|
-
"prepublishOnly": "npx tsc"
|
|
32
|
+
"build": "tsc"
|
|
26
33
|
},
|
|
27
|
-
"repository": {
|
|
28
|
-
"type": "git",
|
|
29
|
-
"url": "git+https://github.com/james-pre/config"
|
|
30
|
-
},
|
|
31
|
-
"author": "James Prevett <jp@jamespre.dev> (https://jamespre.dev)",
|
|
32
|
-
"license": "LGPL-3.0-or-later",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/james-pre/config/issues"
|
|
35
|
-
},
|
|
36
|
-
"homepage": "https://github.com/james-pre/config#readme",
|
|
37
34
|
"engines": {
|
|
38
35
|
"node": ">=22.0.0"
|
|
39
36
|
},
|
|
40
37
|
"peerDependencies": {
|
|
38
|
+
"commander": "^15.0.0",
|
|
41
39
|
"utilium": "^3.7.0",
|
|
42
40
|
"zod": "^4.5.0"
|
|
43
41
|
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"commander": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
44
47
|
"publishConfig": {
|
|
45
48
|
"provenance": true,
|
|
46
49
|
"access": "public"
|
|
47
50
|
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@eslint/js": "^10.0.1",
|
|
50
|
-
"@types/node": "^24.7.0",
|
|
51
|
-
"eslint": "^10.1.0",
|
|
52
|
-
"globals": "^17.4.0",
|
|
53
|
-
"prettier": "^3.2.5",
|
|
54
|
-
"typedoc": "^0.28.18",
|
|
55
|
-
"typescript": "^6.0.2",
|
|
56
|
-
"typescript-eslint": "^8.58.0"
|
|
57
|
-
},
|
|
58
|
-
"prettier": {
|
|
59
|
-
"singleQuote": true,
|
|
60
|
-
"useTabs": true,
|
|
61
|
-
"trailingComma": "es5",
|
|
62
|
-
"tabWidth": 4,
|
|
63
|
-
"printWidth": 120,
|
|
64
|
-
"arrowParens": "avoid",
|
|
65
|
-
"experimentalOperatorPosition": "start"
|
|
66
|
-
},
|
|
67
51
|
"sideEffects": false
|
|
68
52
|
}
|