elrh-cosca 0.3.2 → 0.3.4
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 +22 -14
- package/dist/elrh-cosca.mjs +44 -29
- package/dist/types/checks/get-package-manager.d.ts +6 -0
- package/dist/types/checks/path-exists.d.ts +8 -0
- package/dist/types/functions/delete-path.d.ts +4 -4
- package/dist/types/main.d.ts +3 -2
- package/package.json +4 -4
- package/dist/types/checks/file-exists.d.ts +0 -8
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# COSCA
|
|
2
|
-
Library of file-
|
|
2
|
+
Library of file-writing functions that help building CLI scripts for making changes in target projects - like adding default configuration files or new sections in `package.json`.
|
|
3
3
|
|
|
4
4
|
The first experimental "customers" are my [Nuxt Spec](https://github.com/AloisSeckar/nuxt-spec) and [Nuxt Ignis](https://github.com/AloisSeckar/nuxt-ignis) projects.
|
|
5
5
|
|
|
@@ -27,12 +27,12 @@ Path to `templateFile` must be prefixed with the package name to allow proper re
|
|
|
27
27
|
|
|
28
28
|
Path to `targetFile` is relative to `process.cwd()` which allows consumers to run `npx your-script` in their project roots during development. Several checks are in place to prevent accidental and malicious paths being passed in. Path traversal outside of CWD or providing absolute paths is disallowed. If the target directory does not exist, it will be automatically created.
|
|
29
29
|
|
|
30
|
-
By default the function asks for confirmation before attempting to create the file and if the file with the same name as `targetFile` is detected. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
30
|
+
By default the function asks for confirmation before attempting to create the file and if the file with the same name as `targetFile` is detected. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
31
31
|
|
|
32
32
|
#### `createFileFromWebTemplate`
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
|
-
async function
|
|
35
|
+
async function createFileFromWebTemplate(
|
|
36
36
|
url: string, targetFile: string, force: boolean = false, prompt: string = ''
|
|
37
37
|
): Promise<void>
|
|
38
38
|
```
|
|
@@ -43,7 +43,7 @@ Contents of `url` must be accessible via `node:https.get` function and will be f
|
|
|
43
43
|
|
|
44
44
|
Path to `targetFile` is relative to `process.cwd()` which allows consumers to run `npx your-script` in their project roots during development. Several checks are in place to prevent accidental and malicious paths being passed in. Path traversal outside of CWD or providing absolute paths is disallowed. If the target directory does not exist, it will be automatically created.
|
|
45
45
|
|
|
46
|
-
By default the function asks for confirmation before attempting to create the file and if the file with the same name as `targetFile` is detected. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
46
|
+
By default the function asks for confirmation before attempting to create the file and if the file with the same name as `targetFile` is detected. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
47
47
|
|
|
48
48
|
#### `updateConfigFile`
|
|
49
49
|
|
|
@@ -75,7 +75,7 @@ TypeError: 'set' on proxy: trap returned falsish for property '<YOUR_PROPERTY>'
|
|
|
75
75
|
If possible, you need to alter your logic, e.g. by creating a new object via the spread operator.
|
|
76
76
|
|
|
77
77
|
|
|
78
|
-
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
78
|
+
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
79
79
|
|
|
80
80
|
#### `updateJsonFile`
|
|
81
81
|
|
|
@@ -99,7 +99,7 @@ Path to `targetFile` is relative to `process.cwd()`. Several checks are in place
|
|
|
99
99
|
|
|
100
100
|
Currently it only allows adding new values under top-level keys. If the `jsonKey` exists, new values are merged into existing ones. Otherwise, new key is added. The function tracks if any real change was made and notifies the user if not.
|
|
101
101
|
|
|
102
|
-
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
102
|
+
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
103
103
|
|
|
104
104
|
#### `updateTextFile`
|
|
105
105
|
|
|
@@ -113,7 +113,7 @@ Takes a path to a plain text file and injects `rowsToAdd` at the end of the file
|
|
|
113
113
|
|
|
114
114
|
Path to `targetFile` is relative to `process.cwd()`. Several checks are in place to prevent accidental and malicious paths being passed in. Path traversal outside of CWD or providing absolute paths is disallowed.
|
|
115
115
|
|
|
116
|
-
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
116
|
+
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
117
117
|
|
|
118
118
|
#### `removeFromJsonFile`
|
|
119
119
|
|
|
@@ -129,7 +129,7 @@ Path to `targetFile` is relative to `process.cwd()`. Several checks are in place
|
|
|
129
129
|
|
|
130
130
|
Given `jsonKey` might point to a nested key using dot notation, e.g. `a.b.c`. If the key is not present, the function does nothing.
|
|
131
131
|
|
|
132
|
-
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
132
|
+
By default the function asks for confirmation before attempting to alter the `targetFile`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
133
133
|
|
|
134
134
|
#### `deletePath`
|
|
135
135
|
|
|
@@ -143,21 +143,21 @@ Deletes given `targetPath` from FS. Path is resolved relatively to `process.cwd(
|
|
|
143
143
|
|
|
144
144
|
If the `targetPath` does not exist, the function does nothing.
|
|
145
145
|
|
|
146
|
-
By default the function asks for confirmation before attempting to delete the `targetPath`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts.
|
|
146
|
+
By default the function asks for confirmation before attempting to delete the `targetPath`. Setting the last optional parameter `force` to `true` will suppress manual confirmation prompts. Passing a custom `prompt` allows tailoring your own question to the user.
|
|
147
147
|
|
|
148
148
|
### List of content checkers
|
|
149
149
|
|
|
150
|
-
#### `
|
|
150
|
+
#### `pathExists`
|
|
151
151
|
|
|
152
152
|
```ts
|
|
153
|
-
function
|
|
154
|
-
|
|
153
|
+
function pathExists(
|
|
154
|
+
targetPath: string
|
|
155
155
|
): boolean
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
Checks if the specified `
|
|
158
|
+
Checks if the specified `targetPath` exists on FS. Path is resolved relatively to `process.cwd()`. Several checks are in place to prevent accidental and malicious paths being passed in. Path traversal outside of CWD or providing absolute paths is disallowed.
|
|
159
159
|
|
|
160
|
-
If the
|
|
160
|
+
If the path exists , the function returns true, false otherwise.
|
|
161
161
|
|
|
162
162
|
#### `hasJsonKey`
|
|
163
163
|
|
|
@@ -183,6 +183,14 @@ Checks whether given `row` exists in text file located at `targetFile`. Path is
|
|
|
183
183
|
|
|
184
184
|
If the `row` is present, the function returns true, false otherwise. Row must be matched completely, but surrounding whitespaces are ignored.
|
|
185
185
|
|
|
186
|
+
#### `getPackageManager`
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
function getPackageManager(): 'npm' | 'yarn' | 'pnpm' | 'deno' | 'bun'
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Tries to detect the package manager used in the current environment by checking for specific global variables and user agent strings. Fallbacks to `npm` if common checks fail to detect otherwise.
|
|
193
|
+
|
|
186
194
|
### List of terminal helpers
|
|
187
195
|
|
|
188
196
|
#### `promptUser`
|
package/dist/elrh-cosca.mjs
CHANGED
|
@@ -3,8 +3,22 @@ import { existsSync as be, readFileSync as tt, access as Ia, constants as Na, mk
|
|
|
3
3
|
import Da from "node:readline";
|
|
4
4
|
import Ma from "node:https";
|
|
5
5
|
import "fs";
|
|
6
|
+
function Fl() {
|
|
7
|
+
if (globalThis?.Deno)
|
|
8
|
+
return "deno";
|
|
9
|
+
if (globalThis?.Bun)
|
|
10
|
+
return "bun";
|
|
11
|
+
const a = process?.env?.npm_config_user_agent;
|
|
12
|
+
if (a) {
|
|
13
|
+
if (a.includes("pnpm")) return "pnpm";
|
|
14
|
+
if (a.includes("yarn")) return "yarn";
|
|
15
|
+
if (a.includes("bun")) return "bun";
|
|
16
|
+
if (a.includes("npm")) return "npm";
|
|
17
|
+
}
|
|
18
|
+
return "npm";
|
|
19
|
+
}
|
|
6
20
|
function _e(a) {
|
|
7
|
-
if (
|
|
21
|
+
if (!a)
|
|
8
22
|
return { valid: !1, error: "Path cannot be empty" };
|
|
9
23
|
if (/^[A-Za-z]:/.test(a) || a.startsWith("/"))
|
|
10
24
|
return { valid: !1, error: `Path must be relative to CWD: '${a}'` };
|
|
@@ -18,13 +32,6 @@ function _e(a) {
|
|
|
18
32
|
const o = we(process.cwd(), a), u = we(process.cwd());
|
|
19
33
|
return !o.startsWith(u + Ca) && o !== u ? { valid: !1, error: `Path outside of CWD not allowed: '${a}'` } : { valid: !0 };
|
|
20
34
|
}
|
|
21
|
-
function Fl(a) {
|
|
22
|
-
const l = _e(a);
|
|
23
|
-
if (!l.valid)
|
|
24
|
-
throw new Error(l.error);
|
|
25
|
-
const r = we(process.cwd(), a);
|
|
26
|
-
return be(r);
|
|
27
|
-
}
|
|
28
35
|
function Bl(a, l) {
|
|
29
36
|
const r = _e(a);
|
|
30
37
|
if (!r.valid)
|
|
@@ -62,6 +69,13 @@ function _l(a, l) {
|
|
|
62
69
|
throw new Error(`No '${a}' found in project root — cannot check its contents.`);
|
|
63
70
|
return tt(i, "utf8").split(/\r?\n/).map((h) => h.trim()).includes(l.trim());
|
|
64
71
|
}
|
|
72
|
+
function jl(a) {
|
|
73
|
+
const l = _e(a);
|
|
74
|
+
if (!l.valid)
|
|
75
|
+
throw new Error(l.error);
|
|
76
|
+
const r = we(process.cwd(), a);
|
|
77
|
+
return be(r);
|
|
78
|
+
}
|
|
65
79
|
async function Ve(a, l) {
|
|
66
80
|
const r = Da.createInterface({
|
|
67
81
|
input: l?.input || process.stdin,
|
|
@@ -108,7 +122,7 @@ function Ba(a) {
|
|
|
108
122
|
}
|
|
109
123
|
throw new Error(`Cannot find package "${a}" from ${process.cwd()}. Make sure it's installed or linked in this project.`);
|
|
110
124
|
}
|
|
111
|
-
async function
|
|
125
|
+
async function Rl(a, l, r = !1, i = "") {
|
|
112
126
|
if (r || await Ve(
|
|
113
127
|
i || `This will create '${l}' file. Continue?`
|
|
114
128
|
)) {
|
|
@@ -144,7 +158,7 @@ async function _a(a) {
|
|
|
144
158
|
}).on("error", r);
|
|
145
159
|
});
|
|
146
160
|
}
|
|
147
|
-
async function
|
|
161
|
+
async function Ul(a, l, r = !1, i = "") {
|
|
148
162
|
if (r || await Ve(
|
|
149
163
|
i || `This will create '${l}' file. Continue?`
|
|
150
164
|
)) {
|
|
@@ -173,7 +187,7 @@ ${x}`);
|
|
|
173
187
|
} else
|
|
174
188
|
console.log(`Creation of '${l}' skipped.`);
|
|
175
189
|
}
|
|
176
|
-
async function
|
|
190
|
+
async function $l(a, l = !1, r = "") {
|
|
177
191
|
if (l || await Ve(
|
|
178
192
|
r || `This will delete '${a}'. Continue?`
|
|
179
193
|
)) {
|
|
@@ -191,7 +205,7 @@ async function Ul(a, l = !1, r = "") {
|
|
|
191
205
|
} else
|
|
192
206
|
console.log(`Removing '${a}' skipped.`);
|
|
193
207
|
}
|
|
194
|
-
async function
|
|
208
|
+
async function Vl(a, l, r = !1, i = "") {
|
|
195
209
|
if (r || await Ve(
|
|
196
210
|
i || `This will delete '${l}' from '${a}' file. Continue?`
|
|
197
211
|
)) {
|
|
@@ -16463,7 +16477,7 @@ function ln(a, l) {
|
|
|
16463
16477
|
i && !o ? ln(a[r], l[r]) : o ? a[r] = a[r] ? [.../* @__PURE__ */ new Set([...a[r], ...l[r]])] : l[r] : a[r] = l[r];
|
|
16464
16478
|
}
|
|
16465
16479
|
}
|
|
16466
|
-
async function
|
|
16480
|
+
async function Xl(a, l, r = !1, i = "") {
|
|
16467
16481
|
if (r || await Ve(
|
|
16468
16482
|
i || `This will update '${a}' file. Continue?`
|
|
16469
16483
|
)) {
|
|
@@ -16497,7 +16511,7 @@ async function Kl(a, l, r = !1, i = "") {
|
|
|
16497
16511
|
} else
|
|
16498
16512
|
console.log(`Updating '${a}' skipped.`);
|
|
16499
16513
|
}
|
|
16500
|
-
async function
|
|
16514
|
+
async function Gl(a, l, r, i = !1, o = "") {
|
|
16501
16515
|
if (i || await Ve(
|
|
16502
16516
|
o || `This will update '${a}' file. Continue?`
|
|
16503
16517
|
)) {
|
|
@@ -16527,7 +16541,7 @@ ${A}`);
|
|
|
16527
16541
|
} else
|
|
16528
16542
|
console.log(`Updating '${a}' skipped.`);
|
|
16529
16543
|
}
|
|
16530
|
-
async function
|
|
16544
|
+
async function Ql(a, l, r = !1, i = "") {
|
|
16531
16545
|
if (r || await Ve(
|
|
16532
16546
|
i || `This will update '${a}' file. Continue?`
|
|
16533
16547
|
)) {
|
|
@@ -16547,19 +16561,19 @@ async function Gl(a, l, r = !1, i = "") {
|
|
|
16547
16561
|
} else
|
|
16548
16562
|
console.log(`Updating '${a}' skipped.`);
|
|
16549
16563
|
}
|
|
16550
|
-
function
|
|
16564
|
+
function Yl(a, l = 1) {
|
|
16551
16565
|
process.stderr.write(a);
|
|
16552
16566
|
for (let r = 0; r < l; r++)
|
|
16553
16567
|
process.stderr.write(`
|
|
16554
16568
|
`);
|
|
16555
16569
|
}
|
|
16556
|
-
function
|
|
16570
|
+
function Zl(a, l = 1) {
|
|
16557
16571
|
process.stdout.write(a);
|
|
16558
16572
|
for (let r = 0; r < l; r++)
|
|
16559
16573
|
process.stdout.write(`
|
|
16560
16574
|
`);
|
|
16561
16575
|
}
|
|
16562
|
-
function
|
|
16576
|
+
function ec(a, l = we(process.cwd(), ".env")) {
|
|
16563
16577
|
if (!be(l))
|
|
16564
16578
|
return;
|
|
16565
16579
|
const r = tt(l, "utf-8");
|
|
@@ -16574,20 +16588,21 @@ function Zl(a, l = we(process.cwd(), ".env")) {
|
|
|
16574
16588
|
}
|
|
16575
16589
|
}
|
|
16576
16590
|
export {
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
|
|
16591
|
+
Rl as createFileFromTemplate,
|
|
16592
|
+
Ul as createFileFromWebTemplate,
|
|
16593
|
+
$l as deletePath,
|
|
16594
|
+
ec as getEnvValue,
|
|
16595
|
+
Fl as getPackageManager,
|
|
16582
16596
|
Bl as hasJsonKey,
|
|
16583
16597
|
_l as hasText,
|
|
16584
16598
|
Fa as parseQualifiedPath,
|
|
16599
|
+
jl as pathExists,
|
|
16585
16600
|
Ve as promptUser,
|
|
16586
|
-
|
|
16601
|
+
Vl as removeFromJsonFile,
|
|
16587
16602
|
Ba as resolvePackagePath,
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
|
|
16591
|
-
|
|
16592
|
-
|
|
16603
|
+
Yl as showError,
|
|
16604
|
+
Zl as showMessage,
|
|
16605
|
+
Xl as updateConfigFile,
|
|
16606
|
+
Gl as updateJsonFile,
|
|
16607
|
+
Ql as updateTextFile
|
|
16593
16608
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks what package manager was used to execute the current command.
|
|
3
|
+
*
|
|
4
|
+
* @returns {string} The name of the package manager used ('npm', 'yarn', 'pnpm', 'deno' or 'bun').
|
|
5
|
+
*/
|
|
6
|
+
export declare function getPackageManager(): 'npm' | 'yarn' | 'pnpm' | 'deno' | 'bun';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the specified path exists on FS.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} targetPath - The path on FS to be checked (relative to CWD).
|
|
5
|
+
* @returns {boolean} True if the path exists, false otherwise.
|
|
6
|
+
* @throws Will throw an error if the path is invalid (can't traverse past CWD).
|
|
7
|
+
*/
|
|
8
|
+
export declare function pathExists(targetPath: string): boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deletes given path from FS.
|
|
3
3
|
*
|
|
4
|
-
* @param {string} targetPath - The path to
|
|
5
|
-
* @param {boolean} force - Whether to force the
|
|
4
|
+
* @param {string} targetPath - The path to delete (relative to CWD).
|
|
5
|
+
* @param {boolean} force - Whether to force the deletion without prompting.
|
|
6
6
|
* @param {string} prompt - Custom prompt message displayed in terminal.
|
|
7
|
-
* @returns {Promise<void>} An empty promise that resolves when the
|
|
8
|
-
* @throws Will throw an error if the path is invalid
|
|
7
|
+
* @returns {Promise<void>} An empty promise that resolves when the path is deleted.
|
|
8
|
+
* @throws Will throw an error if the path is invalid.
|
|
9
9
|
*/
|
|
10
10
|
export declare function deletePath(targetPath: string, force?: boolean, prompt?: string): Promise<void>;
|
package/dist/types/main.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPackageManager } from './checks/get-package-manager';
|
|
2
2
|
import { hasJsonKey } from './checks/has-json-key';
|
|
3
3
|
import { hasText } from './checks/has-text';
|
|
4
|
+
import { pathExists } from './checks/path-exists';
|
|
4
5
|
import { createFileFromTemplate } from './functions/create-file-from-template';
|
|
5
6
|
import { createFileFromWebTemplate } from './functions/create-file-from-web-template';
|
|
6
7
|
import { deletePath } from './functions/delete-path';
|
|
@@ -14,4 +15,4 @@ import { showMessage } from './terminal/show-message';
|
|
|
14
15
|
import { getEnvValue } from './utils/get-env-value';
|
|
15
16
|
import { parseQualifiedPath } from './utils/parse-qualified-path';
|
|
16
17
|
import { resolvePackagePath } from './utils/resolve-package-path';
|
|
17
|
-
export {
|
|
18
|
+
export { getPackageManager, hasJsonKey, hasText, pathExists, createFileFromTemplate, createFileFromWebTemplate, deletePath, removeFromJsonFile, updateConfigFile, updateJsonFile, updateTextFile, promptUser, showError, showMessage, getEnvValue, parseQualifiedPath, resolvePackagePath, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elrh-cosca",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"module": "./dist/elrh-cosca.mjs",
|
|
19
19
|
"types": "./dist/types/index.d.ts",
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@types/node": "^24.
|
|
21
|
+
"@types/node": "^24.6.0",
|
|
22
22
|
"magicast": "^0.3.5",
|
|
23
|
-
"typescript": "^5.9.
|
|
24
|
-
"vite": "^7.1.
|
|
23
|
+
"typescript": "^5.9.3",
|
|
24
|
+
"vite": "^7.1.8",
|
|
25
25
|
"vite-plugin-dts": "^4.5.4",
|
|
26
26
|
"vitest": "^3.2.4"
|
|
27
27
|
},
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Checks if the specified file exists on FS.
|
|
3
|
-
*
|
|
4
|
-
* @param {string} targetFile - The path to the text file to be checked (relative to CWD).
|
|
5
|
-
* @returns {boolean} True if the file exists, false otherwise.
|
|
6
|
-
* @throws Will throw an error if the path is invalid (can't traverse past CWD).
|
|
7
|
-
*/
|
|
8
|
-
export declare function fileExists(targetFile: string): boolean;
|