@vltpkg/config 0.0.0-19
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/LICENSE +15 -0
- package/README.md +78 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +165 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Copyright (c) vlt technology, Inc.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
7
|
+
Subject to the terms and conditions of this license, each copyright holder and contributor hereby grants to those receiving rights under this license a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except for failure to satisfy the conditions of this license) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer this software, where such license applies only to those patent claims, already acquired or hereafter acquired, licensable by such copyright holder or contributor that are necessarily infringed by:
|
|
8
|
+
|
|
9
|
+
(a) their Contribution(s) (the licensed copyrights of copyright holders and non-copyrightable additions of contributors, in source or binary form) alone; or
|
|
10
|
+
(b) combination of their Contribution(s) with the work of authorship to which such Contribution(s) was added by such copyright holder or contributor, if, at the time the Contribution is added, such addition causes such combination to be necessarily infringed. The patent license shall not apply to any other combinations which include the Contribution.
|
|
11
|
+
Except as expressly stated above, no rights or licenses from any copyright holder or contributor is granted under this license, whether expressly, by implication, estoppel or otherwise.
|
|
12
|
+
|
|
13
|
+
DISCLAIMER
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# @vltpkg/config
|
|
2
|
+
|
|
3
|
+
Config utilities for the vlt client.
|
|
4
|
+
|
|
5
|
+
**[Usage](#usage)** · **[API](#api)**
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
These are config utilities used by the vlt cli.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { get, set, edit, list, del } from '@vltpkg/config'
|
|
15
|
+
|
|
16
|
+
// Assuming you have a LoadedConfig instance from @vltpkg/cli-sdk
|
|
17
|
+
// const conf = await loadConfig()
|
|
18
|
+
|
|
19
|
+
// Get a config value by key
|
|
20
|
+
const colorValue = await get(conf) // requires conf.positionals[1] to be the key name
|
|
21
|
+
// Supports dot notation for nested properties in record fields
|
|
22
|
+
// e.g., conf.positionals = ['get', 'registry.npmjs.org']
|
|
23
|
+
|
|
24
|
+
// Set config values using key=value pairs
|
|
25
|
+
// conf.positionals should contain pairs like ['set', 'color=auto', 'timeout=5000']
|
|
26
|
+
await set(conf)
|
|
27
|
+
// Creates config file if it doesn't exist when called with no pairs
|
|
28
|
+
// Supports dot notation for record fields: 'registry.npmjs.org=https://registry.npmjs.org/'
|
|
29
|
+
|
|
30
|
+
// Edit the config file with the configured editor
|
|
31
|
+
await edit(conf) // opens conf.get('config') file in conf.get('editor')
|
|
32
|
+
|
|
33
|
+
// List all current config values as key=value pairs
|
|
34
|
+
const allConfig = list(conf) // returns array of 'key=value' strings
|
|
35
|
+
|
|
36
|
+
// Delete config keys
|
|
37
|
+
// conf.positionals should contain keys to delete: ['del', 'color', 'timeout']
|
|
38
|
+
await del(conf) // removes specified keys from conf.get('config') file
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### API
|
|
42
|
+
|
|
43
|
+
#### `get(conf: LoadedConfig)`
|
|
44
|
+
|
|
45
|
+
- Retrieves a single config value by key
|
|
46
|
+
- Supports dot notation for accessing nested properties in record
|
|
47
|
+
fields
|
|
48
|
+
- Returns the value as
|
|
49
|
+
`string | number | boolean | string[] | Record<string, string> | undefined`
|
|
50
|
+
- Requires exactly one key in `conf.positionals[1]`
|
|
51
|
+
|
|
52
|
+
#### `set(conf: LoadedConfig)`
|
|
53
|
+
|
|
54
|
+
- Sets config values from key=value pairs in `conf.positionals`
|
|
55
|
+
- Creates an empty config file if no pairs are provided
|
|
56
|
+
- Supports dot notation for record fields (e.g.,
|
|
57
|
+
`registry.npmjs.org=value`)
|
|
58
|
+
- Writes to the config file specified by `conf.get('config')`
|
|
59
|
+
|
|
60
|
+
#### `edit(conf: LoadedConfig)`
|
|
61
|
+
|
|
62
|
+
- Opens the config file in the editor specified by
|
|
63
|
+
`conf.get('editor')`
|
|
64
|
+
- Uses `spawnSync` to launch the editor with the config file path
|
|
65
|
+
- Throws an error if the editor command fails
|
|
66
|
+
|
|
67
|
+
#### `list(conf: LoadedConfig)`
|
|
68
|
+
|
|
69
|
+
- Returns all current config options as an array of 'key=value'
|
|
70
|
+
strings
|
|
71
|
+
- Converts the internal config records to a flat list format
|
|
72
|
+
|
|
73
|
+
#### `del(conf: LoadedConfig)`
|
|
74
|
+
|
|
75
|
+
- Deletes specified config keys from the config file
|
|
76
|
+
- Requires at least one key in `conf.positionals` (after the command
|
|
77
|
+
name)
|
|
78
|
+
- Removes keys from the file specified by `conf.get('config')`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LoadedConfig } from '@vltpkg/cli-sdk/config';
|
|
2
|
+
export declare const list: (conf: LoadedConfig) => import("@vltpkg/cli-sdk/config").RecordPairs;
|
|
3
|
+
export declare const del: (conf: LoadedConfig) => Promise<void>;
|
|
4
|
+
export declare const get: (conf: LoadedConfig) => Promise<string | number | boolean | string[] | import("@vltpkg/cli-sdk/config").RecordString | undefined>;
|
|
5
|
+
export declare const edit: (conf: LoadedConfig) => Promise<void>;
|
|
6
|
+
export declare const set: (conf: LoadedConfig) => Promise<void>;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEV,YAAY,EACb,MAAM,wBAAwB,CAAA;AAE/B,eAAO,MAAM,IAAI,SAAU,YAAY,iDAEtC,CAAA;AAED,eAAO,MAAM,GAAG,SAAgB,YAAY,kBAS3C,CAAA;AAED,eAAO,MAAM,GAAG,SAAgB,YAAY,8GAqC3C,CAAA;AAED,eAAO,MAAM,IAAI,SAAgB,YAAY,kBAkB5C,CAAA;AAED,eAAO,MAAM,GAAG,SAAgB,YAAY,kBA8E3C,CAAA"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import * as dotProp from '@vltpkg/dot-prop';
|
|
3
|
+
import { error } from '@vltpkg/error-cause';
|
|
4
|
+
import { asRootError } from '@vltpkg/output/error';
|
|
5
|
+
import { isObject } from '@vltpkg/types';
|
|
6
|
+
import { getSortedKeys } from '@vltpkg/cli-sdk/definition';
|
|
7
|
+
import { isRecordField, pairsToRecords, recordsToPairs, } from '@vltpkg/cli-sdk/config';
|
|
8
|
+
export const list = (conf) => {
|
|
9
|
+
return recordsToPairs(conf.options);
|
|
10
|
+
};
|
|
11
|
+
export const del = async (conf) => {
|
|
12
|
+
const fields = conf.positionals.slice(1);
|
|
13
|
+
if (!fields.length) {
|
|
14
|
+
throw error('At least one key is required', {
|
|
15
|
+
code: 'EUSAGE',
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
await conf.deleteConfigKeys(conf.get('config'), fields);
|
|
19
|
+
};
|
|
20
|
+
export const get = async (conf) => {
|
|
21
|
+
const keys = conf.positionals.slice(1);
|
|
22
|
+
const k = keys[0];
|
|
23
|
+
if (!k || keys.length > 1) {
|
|
24
|
+
throw error('Exactly one key is required', {
|
|
25
|
+
code: 'EUSAGE',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// check if this is a dot-prop path into a record field, in which case
|
|
29
|
+
// we need to get the record first and then use dot-prop to get the value
|
|
30
|
+
if (k.includes('.')) {
|
|
31
|
+
const [field, ...rest] = k.split('.');
|
|
32
|
+
const subKey = rest.join('.');
|
|
33
|
+
if (!field || !subKey) {
|
|
34
|
+
throw error('Could not read property', {
|
|
35
|
+
found: k,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// we'd need a type assertion helper from jackspeak definition
|
|
39
|
+
// options in order to cast the field to a known name type
|
|
40
|
+
// @ts-expect-error @typescript-eslint/no-unsafe-argument
|
|
41
|
+
const record = conf.getRecord(field);
|
|
42
|
+
return dotProp.get(record, subKey);
|
|
43
|
+
}
|
|
44
|
+
// otherwise just get the value directly from the config getter
|
|
45
|
+
return isRecordField(k) ?
|
|
46
|
+
conf.getRecord(k)
|
|
47
|
+
: conf.get(k);
|
|
48
|
+
};
|
|
49
|
+
export const edit = async (conf) => {
|
|
50
|
+
const [command, ...args] = conf.get('editor').split(' ');
|
|
51
|
+
if (!command) {
|
|
52
|
+
throw error(`editor is empty`);
|
|
53
|
+
}
|
|
54
|
+
await conf.editConfigFile(conf.get('config'), file => {
|
|
55
|
+
args.push(file);
|
|
56
|
+
const res = spawnSync(command, args, {
|
|
57
|
+
stdio: 'inherit',
|
|
58
|
+
});
|
|
59
|
+
if (res.status !== 0) {
|
|
60
|
+
throw error(`${command} command failed`, {
|
|
61
|
+
...res,
|
|
62
|
+
command,
|
|
63
|
+
args,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
export const set = async (conf) => {
|
|
69
|
+
const pairs = conf.positionals.slice(1);
|
|
70
|
+
if (!pairs.length) {
|
|
71
|
+
// Create an empty config file
|
|
72
|
+
await conf.addConfigToFile(conf.get('config'), {});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const which = conf.get('config');
|
|
76
|
+
// separate dot-prop paths from simple keys for different handling
|
|
77
|
+
// any keys that include a dot (.) will be treated as dotPropPairs
|
|
78
|
+
// other keys/value pairs are handled as simplePairs
|
|
79
|
+
const dotPropPairs = [];
|
|
80
|
+
const simplePairs = [];
|
|
81
|
+
for (const pair of pairs) {
|
|
82
|
+
const eq = pair.indexOf('=');
|
|
83
|
+
if (eq === -1) {
|
|
84
|
+
throw error('Set arguments must contain `=`', {
|
|
85
|
+
code: 'EUSAGE',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const key = pair.substring(0, eq);
|
|
89
|
+
const value = pair.substring(eq + 1);
|
|
90
|
+
if (key.includes('.')) {
|
|
91
|
+
const [field, ...rest] = key.split('.');
|
|
92
|
+
const subKey = rest.join('.');
|
|
93
|
+
if (field && subKey) {
|
|
94
|
+
dotPropPairs.push({ key, field, subKey, value });
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw error('Could not read property', {
|
|
98
|
+
found: pair,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
simplePairs.push(pair);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Handle keys that consists of a single name (e.g., `--foo`)
|
|
107
|
+
// so that it doesn't need the dot-prop logic to handle values
|
|
108
|
+
if (simplePairs.length > 0) {
|
|
109
|
+
try {
|
|
110
|
+
const parsed = conf.jack.parseRaw(simplePairs.map(kv => `--${kv}`)).values;
|
|
111
|
+
await conf.addConfigToFile(which, pairsToRecords(parsed));
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
handleSetError(simplePairs, err);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Handle dot-prop paths for record fields
|
|
118
|
+
if (dotPropPairs.length > 0) {
|
|
119
|
+
for (const { field, subKey, value } of dotPropPairs) {
|
|
120
|
+
if (isRecordField(field)) {
|
|
121
|
+
// For record fields, we add entries in the format field=key=value
|
|
122
|
+
const recordPair = `${field}=${subKey}=${value}`;
|
|
123
|
+
try {
|
|
124
|
+
const parsed = conf.jack.parseRaw([
|
|
125
|
+
`--${recordPair}`,
|
|
126
|
+
]).values;
|
|
127
|
+
await conf.addConfigToFile(which, pairsToRecords(parsed));
|
|
128
|
+
/* c8 ignore start */
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
handleSetError([recordPair], err);
|
|
132
|
+
}
|
|
133
|
+
/* c8 ignore end */
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const handleSetError = (simplePairs, err) => {
|
|
139
|
+
const { name, found, validOptions } = asRootError(err).cause;
|
|
140
|
+
// when a boolean gets a value, it throw a parse error
|
|
141
|
+
if (isObject(found) &&
|
|
142
|
+
typeof found.name === 'string' &&
|
|
143
|
+
typeof found.value === 'string') {
|
|
144
|
+
const { name, value } = found;
|
|
145
|
+
throw error(`Boolean flag must be "${name}" or "no-${name}", not a value`, {
|
|
146
|
+
code: 'ECONFIG',
|
|
147
|
+
name,
|
|
148
|
+
found: `${name}=${value}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (Array.isArray(validOptions)) {
|
|
152
|
+
throw error(`Invalid value provided for ${name}`, {
|
|
153
|
+
code: 'ECONFIG',
|
|
154
|
+
found,
|
|
155
|
+
validOptions,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// an unknown property
|
|
159
|
+
throw error('Invalid config keys', {
|
|
160
|
+
code: 'ECONFIG',
|
|
161
|
+
found: simplePairs.map(kv => kv.split('=')[0]),
|
|
162
|
+
validOptions: getSortedKeys(),
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from 'node:child_process'\nimport * as dotProp from '@vltpkg/dot-prop'\nimport { error } from '@vltpkg/error-cause'\nimport { asRootError } from '@vltpkg/output/error'\nimport { isObject } from '@vltpkg/types'\nimport { getSortedKeys } from '@vltpkg/cli-sdk/definition'\nimport {\n isRecordField,\n pairsToRecords,\n recordsToPairs,\n} from '@vltpkg/cli-sdk/config'\n\nimport type {\n ConfigDefinitions,\n LoadedConfig,\n} from '@vltpkg/cli-sdk/config'\n\nexport const list = (conf: LoadedConfig) => {\n return recordsToPairs(conf.options)\n}\n\nexport const del = async (conf: LoadedConfig) => {\n const fields = conf.positionals.slice(1)\n if (!fields.length) {\n throw error('At least one key is required', {\n code: 'EUSAGE',\n })\n }\n\n await conf.deleteConfigKeys(conf.get('config'), fields)\n}\n\nexport const get = async (conf: LoadedConfig) => {\n const keys = conf.positionals.slice(1)\n const k = keys[0]\n if (!k || keys.length > 1) {\n throw error('Exactly one key is required', {\n code: 'EUSAGE',\n })\n }\n // check if this is a dot-prop path into a record field, in which case\n // we need to get the record first and then use dot-prop to get the value\n if (k.includes('.')) {\n const [field, ...rest] = k.split('.')\n const subKey = rest.join('.')\n\n if (!field || !subKey) {\n throw error('Could not read property', {\n found: k,\n })\n }\n\n // we'd need a type assertion helper from jackspeak definition\n // options in order to cast the field to a known name type\n // @ts-expect-error @typescript-eslint/no-unsafe-argument\n const record = conf.getRecord(field)\n\n return dotProp.get(record, subKey) as\n | string\n | number\n | boolean\n | string[]\n | undefined\n }\n\n // otherwise just get the value directly from the config getter\n return isRecordField(k) ?\n conf.getRecord(k)\n : conf.get(k as keyof ConfigDefinitions)\n}\n\nexport const edit = async (conf: LoadedConfig) => {\n const [command, ...args] = conf.get('editor').split(' ')\n if (!command) {\n throw error(`editor is empty`)\n }\n await conf.editConfigFile(conf.get('config'), file => {\n args.push(file)\n const res = spawnSync(command, args, {\n stdio: 'inherit',\n })\n if (res.status !== 0) {\n throw error(`${command} command failed`, {\n ...res,\n command,\n args,\n })\n }\n })\n}\n\nexport const set = async (conf: LoadedConfig) => {\n const pairs = conf.positionals.slice(1)\n if (!pairs.length) {\n // Create an empty config file\n await conf.addConfigToFile(conf.get('config'), {})\n return\n }\n\n const which = conf.get('config')\n\n // separate dot-prop paths from simple keys for different handling\n // any keys that include a dot (.) will be treated as dotPropPairs\n // other keys/value pairs are handled as simplePairs\n const dotPropPairs: {\n key: string\n field: string\n subKey: string\n value: string\n }[] = []\n const simplePairs: string[] = []\n\n for (const pair of pairs) {\n const eq = pair.indexOf('=')\n if (eq === -1) {\n throw error('Set arguments must contain `=`', {\n code: 'EUSAGE',\n })\n }\n\n const key = pair.substring(0, eq)\n const value = pair.substring(eq + 1)\n if (key.includes('.')) {\n const [field, ...rest] = key.split('.')\n const subKey = rest.join('.')\n if (field && subKey) {\n dotPropPairs.push({ key, field, subKey, value })\n } else {\n throw error('Could not read property', {\n found: pair,\n })\n }\n } else {\n simplePairs.push(pair)\n }\n }\n\n // Handle keys that consists of a single name (e.g., `--foo`)\n // so that it doesn't need the dot-prop logic to handle values\n if (simplePairs.length > 0) {\n try {\n const parsed = conf.jack.parseRaw(\n simplePairs.map(kv => `--${kv}`),\n ).values\n await conf.addConfigToFile(which, pairsToRecords(parsed))\n } catch (err) {\n handleSetError(simplePairs, err)\n }\n }\n\n // Handle dot-prop paths for record fields\n if (dotPropPairs.length > 0) {\n for (const { field, subKey, value } of dotPropPairs) {\n if (isRecordField(field)) {\n // For record fields, we add entries in the format field=key=value\n const recordPair = `${field}=${subKey}=${value}`\n try {\n const parsed = conf.jack.parseRaw([\n `--${recordPair}`,\n ]).values\n await conf.addConfigToFile(which, pairsToRecords(parsed))\n /* c8 ignore start */\n } catch (err) {\n handleSetError([recordPair], err)\n }\n /* c8 ignore end */\n }\n }\n }\n}\n\nconst handleSetError = (simplePairs: string[], err: unknown) => {\n const { name, found, validOptions } = asRootError(err).cause\n // when a boolean gets a value, it throw a parse error\n if (\n isObject(found) &&\n typeof found.name === 'string' &&\n typeof found.value === 'string'\n ) {\n const { name, value } = found\n throw error(\n `Boolean flag must be \"${name}\" or \"no-${name}\", not a value`,\n {\n code: 'ECONFIG',\n name,\n found: `${name}=${value}`,\n },\n )\n }\n if (Array.isArray(validOptions)) {\n throw error(`Invalid value provided for ${name}`, {\n code: 'ECONFIG',\n found,\n validOptions,\n })\n }\n // an unknown property\n throw error('Invalid config keys', {\n code: 'ECONFIG',\n found: simplePairs.map(kv => kv.split('=')[0]),\n validOptions: getSortedKeys(),\n })\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vltpkg/config",
|
|
3
|
+
"description": "Project config logic for vltpkg",
|
|
4
|
+
"version": "0.0.0-19",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
8
|
+
"directory": "src/config"
|
|
9
|
+
},
|
|
10
|
+
"tshy": {
|
|
11
|
+
"selfLink": false,
|
|
12
|
+
"liveDev": true,
|
|
13
|
+
"dialects": [
|
|
14
|
+
"esm"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
"./package.json": "./package.json",
|
|
18
|
+
".": "./src/index.ts"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"path-scurry": "^2.0.0",
|
|
23
|
+
"@vltpkg/cli-sdk": "0.0.0-19",
|
|
24
|
+
"@vltpkg/dot-prop": "0.0.0-19",
|
|
25
|
+
"@vltpkg/output": "0.0.0-19",
|
|
26
|
+
"@vltpkg/package-json": "0.0.0-19",
|
|
27
|
+
"@vltpkg/error-cause": "0.0.0-19",
|
|
28
|
+
"@vltpkg/types": "0.0.0-19"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/js": "^9.28.0",
|
|
32
|
+
"@types/node": "^22.15.29",
|
|
33
|
+
"eslint": "^9.28.0",
|
|
34
|
+
"prettier": "^3.6.0",
|
|
35
|
+
"tap": "^21.1.0",
|
|
36
|
+
"tshy": "^3.0.2",
|
|
37
|
+
"typedoc": "~0.27.9",
|
|
38
|
+
"typescript": "5.7.3",
|
|
39
|
+
"typescript-eslint": "^8.33.1"
|
|
40
|
+
},
|
|
41
|
+
"license": "BSD-2-Clause-Patent",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22"
|
|
44
|
+
},
|
|
45
|
+
"tap": {
|
|
46
|
+
"extends": "../../tap-config.yaml"
|
|
47
|
+
},
|
|
48
|
+
"prettier": "../../.prettierrc.js",
|
|
49
|
+
"module": "./dist/esm/index.js",
|
|
50
|
+
"type": "module",
|
|
51
|
+
"exports": {
|
|
52
|
+
"./package.json": "./package.json",
|
|
53
|
+
".": {
|
|
54
|
+
"import": {
|
|
55
|
+
"types": "./dist/esm/index.d.ts",
|
|
56
|
+
"default": "./dist/esm/index.js"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"dist"
|
|
62
|
+
],
|
|
63
|
+
"keywords": [
|
|
64
|
+
"vltpkg",
|
|
65
|
+
"config"
|
|
66
|
+
],
|
|
67
|
+
"scripts": {
|
|
68
|
+
"format": "prettier --write . --log-level warn --ignore-path ../../.prettierignore --cache",
|
|
69
|
+
"format:check": "prettier --check . --ignore-path ../../.prettierignore --cache",
|
|
70
|
+
"lint": "eslint . --fix",
|
|
71
|
+
"lint:check": "eslint .",
|
|
72
|
+
"snap": "tap",
|
|
73
|
+
"test": "tap",
|
|
74
|
+
"posttest": "tsc --noEmit",
|
|
75
|
+
"tshy": "tshy",
|
|
76
|
+
"typecheck": "tsc --noEmit"
|
|
77
|
+
}
|
|
78
|
+
}
|