@theholocron/cli 1.0.0 → 1.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/LICENSE +21 -674
- package/README.md +19 -8
- package/dist/capabilities/index.d.mts +2 -0
- package/dist/capabilities/index.mjs +2 -0
- package/dist/capabilities-QjjhVlDd.mjs +43 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +852 -0
- package/dist/config-DWlIfFZm.mjs +113 -0
- package/dist/index-CSxf0Yc7.d.mts +485 -0
- package/dist/index.d.mts +58 -0
- package/dist/index.mjs +3 -0
- package/package.json +46 -53
- package/.alexignore +0 -3
- package/.editorconfig +0 -24
- package/.editorconfig-checker.json +0 -20
- package/.env +0 -3
- package/.gitattributes +0 -12
- package/.github/CODEOWNERS +0 -1
- package/.github/dependabot.yml +0 -6
- package/.github/labeler.yml +0 -21
- package/.github/workflows/bookkeeping-pr.yml +0 -32
- package/.github/workflows/greetings.yml +0 -32
- package/.github/workflows/lint.yml +0 -96
- package/.github/workflows/publish.yml +0 -71
- package/.github/workflows/review.yml +0 -72
- package/.github/workflows/stale.yml +0 -25
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -13
- package/.husky/prepare-commit-msg +0 -18
- package/commitlint.config.js +0 -9
- package/eslint.config.js +0 -9
- package/media/README.md +0 -11
- package/media/error.mp3 +0 -0
- package/media/success.mp3 +0 -0
- package/media/warning.mp3 +0 -0
- package/prettier.config.js +0 -11
- package/src/cli.ts +0 -65
- package/src/commands/README.md +0 -13
- package/src/commands/bootstrap.ts +0 -102
- package/src/commands/conf/README.md +0 -45
- package/src/commands/conf/add.ts +0 -49
- package/src/commands/conf/edit.ts +0 -12
- package/src/commands/conf/view.ts +0 -40
- package/src/commands/conf.ts +0 -10
- package/src/commands/log.ts +0 -91
- package/src/const.ts +0 -19
- package/src/tasks/README.md +0 -33
- package/src/tasks/find/README.md +0 -49
- package/src/tasks/find/find-project.example.ts +0 -23
- package/src/tasks/find/find-project.ts +0 -76
- package/src/tasks/find/index.ts +0 -1
- package/src/tasks/index.ts +0 -2
- package/src/tasks/replace/README.md +0 -61
- package/src/tasks/replace/index.ts +0 -1
- package/src/tasks/replace/replace.example.ts +0 -31
- package/src/tasks/replace/replace.ts +0 -95
- package/src/ui/README.md +0 -8
- package/src/ui/index.ts +0 -2
- package/src/ui/open/README.md +0 -58
- package/src/ui/open/index.ts +0 -7
- package/src/ui/open/open-browser.ts +0 -25
- package/src/ui/open/open-editor.example.ts +0 -14
- package/src/ui/open/open-editor.ts +0 -30
- package/src/ui/prompts/README.md +0 -36
- package/src/ui/prompts/autocomplete.prompt.ts +0 -18
- package/src/ui/prompts/confirm.prompt.ts +0 -21
- package/src/ui/prompts/index.ts +0 -17
- package/src/ui/prompts/input.prompt.ts +0 -15
- package/src/ui/prompts/search.prompt.ts +0 -33
- package/src/ui/prompts/select.prompt.ts +0 -17
- package/src/ui/prompts/types.ts +0 -8
- package/src/ui/prompts/utils.ts +0 -11
- package/src/utils/$/README.md +0 -87
- package/src/utils/$/command.test.ts +0 -48
- package/src/utils/$/command.ts +0 -21
- package/src/utils/$/directory.ts +0 -108
- package/src/utils/$/file.ts +0 -98
- package/src/utils/$/index.example.ts +0 -37
- package/src/utils/$/index.ts +0 -22
- package/src/utils/$/path.ts +0 -13
- package/src/utils/$/remove.ts +0 -47
- package/src/utils/$/spawn.ts +0 -26
- package/src/utils/$/utils.ts +0 -21
- package/src/utils/README.md +0 -15
- package/src/utils/config/README.md +0 -41
- package/src/utils/config/config.ts +0 -26
- package/src/utils/config/index.ts +0 -1
- package/src/utils/config/preferences.conf.ts +0 -45
- package/src/utils/env/README.md +0 -52
- package/src/utils/env/env.example.ts +0 -21
- package/src/utils/env/env.ts +0 -57
- package/src/utils/env/index.ts +0 -1
- package/src/utils/index.ts +0 -5
- package/src/utils/log/README.md +0 -117
- package/src/utils/log/index.ts +0 -2
- package/src/utils/log/log.example.ts +0 -13
- package/src/utils/log/log.ts +0 -58
- package/src/utils/log/logger.ts +0 -28
- package/src/utils/log/sound.ts +0 -35
- package/src/utils/node/README.md +0 -23
- package/src/utils/node/index.ts +0 -5
- package/src/utils/node/package.ts +0 -12
- package/tsconfig.json +0 -15
- package/yamllint.config.yml +0 -20
package/src/utils/$/directory.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { promises as fs, Dirent } from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { HOME } from "@/const";
|
|
4
|
-
import { type Return } from "@/types";
|
|
5
|
-
import { expandTilde, isHidden, isIgnored } from "./utils";
|
|
6
|
-
|
|
7
|
-
export function getDirectoryByLevel(filepath: string, size: number = -3): string {
|
|
8
|
-
// Normalize the file path and split it into parts
|
|
9
|
-
const parts = path.normalize(filepath).split(path.sep);
|
|
10
|
-
|
|
11
|
-
// Remove the home directory path if present
|
|
12
|
-
if (filepath.startsWith(HOME)) {
|
|
13
|
-
parts.splice(0, HOME.split(path.sep).length);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Slice the last 3 directories, but if the third directory from the end is not the home directory, keep all three
|
|
17
|
-
const lastDirs = parts.slice(size);
|
|
18
|
-
|
|
19
|
-
// If three parts are kept, only return last two if the third last was home directory
|
|
20
|
-
return lastDirs.join(path.sep);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export async function isDirectory(pathname: string, options: object = {}): Promise<boolean> {
|
|
24
|
-
const resolvedPath = expandTilde(pathname);
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
const stat = await fs.stat(resolvedPath, options);
|
|
28
|
-
return stat.isDirectory();
|
|
29
|
-
} catch {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export async function readDirectory(
|
|
35
|
-
pathname: string,
|
|
36
|
-
maxDepth: number = Infinity,
|
|
37
|
-
currentDepth: number = 0,
|
|
38
|
-
options: object = {}
|
|
39
|
-
): Promise<string[]> {
|
|
40
|
-
const resolvedPath = expandTilde(pathname);
|
|
41
|
-
const files: string[] = [];
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const dirents: Dirent[] = await fs.readdir(resolvedPath, { withFileTypes: true, ...options });
|
|
45
|
-
|
|
46
|
-
for (const dirent of dirents) {
|
|
47
|
-
const fullPath = `${resolvedPath}/${dirent.name}`;
|
|
48
|
-
if (dirent.isDirectory()) {
|
|
49
|
-
if (!isHidden(dirent.name) && !isIgnored(dirent.name) && currentDepth < maxDepth) {
|
|
50
|
-
files.push(...(await readDirectory(fullPath, maxDepth, currentDepth + 1)));
|
|
51
|
-
}
|
|
52
|
-
} else {
|
|
53
|
-
files.push(fullPath);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return files;
|
|
58
|
-
} catch {
|
|
59
|
-
return [];
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export async function writeDirectory(pathname: string, options: object = {}): Promise<Return<string>> {
|
|
64
|
-
const resolvedPath = expandTilde(pathname);
|
|
65
|
-
|
|
66
|
-
if (await isDirectory(resolvedPath)) {
|
|
67
|
-
return [null, resolvedPath, 0];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
await fs.mkdir(resolvedPath, { recursive: true, ...options });
|
|
72
|
-
return [null, resolvedPath, 0];
|
|
73
|
-
} catch (error) {
|
|
74
|
-
return [error as Error, null, 0];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface Directory {
|
|
79
|
-
files: string[];
|
|
80
|
-
path: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function directory(pathname: string, maxDepth: number = Infinity): Promise<Return<Directory>> {
|
|
84
|
-
// if its a directory, return the resolved path and files
|
|
85
|
-
if (await isDirectory(pathname)) {
|
|
86
|
-
const files = await readDirectory(pathname, maxDepth);
|
|
87
|
-
return [
|
|
88
|
-
null,
|
|
89
|
-
{
|
|
90
|
-
files,
|
|
91
|
-
path: expandTilde(pathname),
|
|
92
|
-
},
|
|
93
|
-
0,
|
|
94
|
-
];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// if it doesn't exist, attempt to create it and return resolved path
|
|
98
|
-
// if it's a file or something other than a directory, it will throw an error
|
|
99
|
-
const [writeErr] = await writeDirectory(pathname);
|
|
100
|
-
return [
|
|
101
|
-
writeErr,
|
|
102
|
-
{
|
|
103
|
-
files: [],
|
|
104
|
-
path: expandTilde(pathname),
|
|
105
|
-
},
|
|
106
|
-
0,
|
|
107
|
-
];
|
|
108
|
-
}
|
package/src/utils/$/file.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import * as str from "@theholocron/utils-string";
|
|
3
|
-
import { type Return } from "@/types";
|
|
4
|
-
import { expandTilde } from "./utils";
|
|
5
|
-
|
|
6
|
-
const encoding = "utf-8";
|
|
7
|
-
|
|
8
|
-
export async function isFile(pathname: string, options: object = {}): Promise<boolean> {
|
|
9
|
-
const resolvedPath = expandTilde(pathname);
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
const stat = await fs.stat(resolvedPath, options);
|
|
13
|
-
return stat.isFile();
|
|
14
|
-
} catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface File {
|
|
20
|
-
path: string;
|
|
21
|
-
content: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function readFile(pathname: string | string[], options: object = {}): Promise<File[]> {
|
|
25
|
-
const files = str.toArray(pathname);
|
|
26
|
-
const results: File[] = [];
|
|
27
|
-
|
|
28
|
-
for (const file of files) {
|
|
29
|
-
const resolvedPath = expandTilde(file);
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const content = await fs.readFile(resolvedPath, { encoding, ...options });
|
|
33
|
-
results.push({
|
|
34
|
-
content,
|
|
35
|
-
path: resolvedPath,
|
|
36
|
-
});
|
|
37
|
-
} catch {
|
|
38
|
-
results.push({
|
|
39
|
-
content: "",
|
|
40
|
-
path: resolvedPath,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return results;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export async function writeFile(
|
|
49
|
-
pathname: string,
|
|
50
|
-
content?: string | Buffer,
|
|
51
|
-
overwrite: boolean = false,
|
|
52
|
-
options: object = {}
|
|
53
|
-
): Promise<Return<File>> {
|
|
54
|
-
const resolvedPath = expandTilde(pathname);
|
|
55
|
-
|
|
56
|
-
if (!content) {
|
|
57
|
-
const [data] = await readFile(resolvedPath);
|
|
58
|
-
return [null, data, 0];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
if (overwrite) {
|
|
63
|
-
await fs.writeFile(resolvedPath, content, { encoding, ...options });
|
|
64
|
-
} else {
|
|
65
|
-
await fs.appendFile(resolvedPath, content, { encoding, ...options });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const [data] = await readFile(resolvedPath);
|
|
69
|
-
return [null, data, 0];
|
|
70
|
-
} catch (error) {
|
|
71
|
-
return [error as Error, null, 0];
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// only handles single files
|
|
76
|
-
export async function file(
|
|
77
|
-
pathname: string,
|
|
78
|
-
content?: string | Buffer,
|
|
79
|
-
overwrite: boolean = false
|
|
80
|
-
): Promise<Return<File>> {
|
|
81
|
-
// if its a file and there's no content, return the resolved path and contents
|
|
82
|
-
if ((await isFile(pathname)) && !content) {
|
|
83
|
-
const [contents] = await readFile(pathname);
|
|
84
|
-
return [null, contents, 0];
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// if it doesn't exist, attempt to create it and return resolved path
|
|
88
|
-
// if it's a file or something other than a directory, it will throw an error
|
|
89
|
-
const [writeErr, write] = await writeFile(pathname, content, overwrite);
|
|
90
|
-
return [
|
|
91
|
-
writeErr,
|
|
92
|
-
{
|
|
93
|
-
content: write?.content ?? "",
|
|
94
|
-
path: write?.path ?? "",
|
|
95
|
-
},
|
|
96
|
-
0,
|
|
97
|
-
];
|
|
98
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { $ } from "./index";
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
const isFile = await $.file("./README.md");
|
|
5
|
-
const isNotAFile = await $.file("./");
|
|
6
|
-
const isResolvedFile = await $.file("~/Downloads/chevron-down.tsx");
|
|
7
|
-
console.log({
|
|
8
|
-
isFile,
|
|
9
|
-
isNotAFile,
|
|
10
|
-
isResolvedFile,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const isDirectory = await $.directory("./");
|
|
14
|
-
const isNotADirectory = await $.directory("./README.md");
|
|
15
|
-
const isResolvedDirectory = await $.directory("~/Downloads");
|
|
16
|
-
const isCreatedDirectory = await $.directory("./test");
|
|
17
|
-
console.log({
|
|
18
|
-
isDirectory,
|
|
19
|
-
isNotADirectory,
|
|
20
|
-
isResolvedDirectory,
|
|
21
|
-
isCreatedDirectory,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const [err, output, time] = await $("ls .");
|
|
25
|
-
if (err) {
|
|
26
|
-
console.error("Error executing command:", err);
|
|
27
|
-
} else {
|
|
28
|
-
console.log("Command output:", output);
|
|
29
|
-
console.log("Execution time:", time, "ms");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Checking if a command is installed
|
|
33
|
-
const isBrewInstalled = await $.command("brew");
|
|
34
|
-
console.log("Is brew installed?", isBrewInstalled);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
main();
|
package/src/utils/$/index.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type Return } from "@/types";
|
|
2
|
-
import { command, isInstalled } from "./command";
|
|
3
|
-
import { directory } from "./directory";
|
|
4
|
-
import { file } from "./file";
|
|
5
|
-
import { path } from "./path";
|
|
6
|
-
import { remove } from "./remove";
|
|
7
|
-
import { spwn } from "./spawn";
|
|
8
|
-
|
|
9
|
-
export { type Directory } from "./directory";
|
|
10
|
-
export { type File } from "./file";
|
|
11
|
-
export { getDirectoryByLevel } from "./directory";
|
|
12
|
-
|
|
13
|
-
export async function $(cmd: string, options: object = {}): Promise<Return<string>> {
|
|
14
|
-
return await command(cmd, options);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
$.command = isInstalled;
|
|
18
|
-
$.directory = directory;
|
|
19
|
-
$.file = file;
|
|
20
|
-
$.path = path;
|
|
21
|
-
$.remove = remove;
|
|
22
|
-
$.spawn = spwn;
|
package/src/utils/$/path.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import { expandTilde } from "./utils";
|
|
3
|
-
|
|
4
|
-
export async function path(pathname: string): Promise<boolean> {
|
|
5
|
-
const resolvedPath = expandTilde(pathname);
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
await fs.access(resolvedPath);
|
|
9
|
-
return true;
|
|
10
|
-
} catch {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
}
|
package/src/utils/$/remove.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import { type Return } from "@/types";
|
|
3
|
-
import { isDirectory } from "./directory";
|
|
4
|
-
import { isFile } from "./file";
|
|
5
|
-
import { expandTilde } from "./utils";
|
|
6
|
-
|
|
7
|
-
export async function removeFile(pathname: string, options: object = {}): Promise<boolean> {
|
|
8
|
-
const resolvedPath = expandTilde(pathname);
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
await fs.rm(resolvedPath, options);
|
|
12
|
-
return true;
|
|
13
|
-
} catch {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export async function removeDirectory(pathname: string, options: object = {}): Promise<boolean> {
|
|
19
|
-
const resolvedPath = expandTilde(pathname);
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
await fs.rmdir(resolvedPath, options);
|
|
23
|
-
return true;
|
|
24
|
-
} catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function remove(pathname: string, options: object = {}): Promise<Return<boolean>> {
|
|
30
|
-
const resolvedPath = expandTilde(pathname);
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
if (await isDirectory(resolvedPath)) {
|
|
34
|
-
await fs.rmdir(resolvedPath, { recursive: true, ...options });
|
|
35
|
-
return [null, true, 0];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (await isFile(resolvedPath)) {
|
|
39
|
-
await fs.rm(resolvedPath, options);
|
|
40
|
-
return [null, true, 0];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return [new Error(`Path does not exist: ${resolvedPath}`), null, 0];
|
|
44
|
-
} catch (error) {
|
|
45
|
-
return [error as Error, false, 0];
|
|
46
|
-
}
|
|
47
|
-
}
|
package/src/utils/$/spawn.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { type Return } from "@/types";
|
|
3
|
-
|
|
4
|
-
const asyncSpawn = (cmd: string, args: string[], options: object = {}): Promise<void> =>
|
|
5
|
-
new Promise((resolve, reject) => {
|
|
6
|
-
const process = spawn(cmd, args, options);
|
|
7
|
-
|
|
8
|
-
process.on("close", (code) => {
|
|
9
|
-
if (code !== 0) {
|
|
10
|
-
reject(new Error(`process exited with code ${code}`));
|
|
11
|
-
} else {
|
|
12
|
-
resolve();
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export async function spwn(cmd: string, args: string[], options: object = {}): Promise<Return<boolean>> {
|
|
18
|
-
const start = performance.now();
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
await asyncSpawn(cmd, args, options);
|
|
22
|
-
return [null, true, performance.now() - start];
|
|
23
|
-
} catch (error) {
|
|
24
|
-
return [error as Error, false, performance.now() - start];
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/utils/$/utils.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { HOME, SYSTEM_IGNORED_FOLDERS, type IgnoredFolders } from "@/const";
|
|
2
|
-
import { config } from "../config";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Expands the tilde (~) in a path to the user's home directory.
|
|
6
|
-
*/
|
|
7
|
-
export function expandTilde(pathname: string): string {
|
|
8
|
-
const tilde = "~";
|
|
9
|
-
|
|
10
|
-
if (pathname.startsWith(tilde)) {
|
|
11
|
-
return pathname.replace(tilde, HOME);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return pathname;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const isHidden = (pathname: string): boolean => pathname.startsWith(".");
|
|
18
|
-
|
|
19
|
-
export const isIgnored = (pathname: string): boolean =>
|
|
20
|
-
SYSTEM_IGNORED_FOLDERS.includes(pathname as IgnoredFolders) ||
|
|
21
|
-
config.get("preferences.ignoredFolders").includes(pathname);
|
package/src/utils/README.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Utilities
|
|
2
|
-
|
|
3
|
-
A set of functions designed to be littered everywhere.
|
|
4
|
-
|
|
5
|
-
## What's Available
|
|
6
|
-
|
|
7
|
-
- [$](./$/README.md) - run a bash command in Node
|
|
8
|
-
- [config](./config/README.md) - read and write to a configuration file
|
|
9
|
-
- [env](./env/README.md) - read and write to a `.env` for use with Environment variables
|
|
10
|
-
- [log](./log/README.md) - a logger
|
|
11
|
-
- [node](./node/README.md) - interact with node packages
|
|
12
|
-
|
|
13
|
-
## Rules
|
|
14
|
-
|
|
15
|
-
- There should be no logging; all Utilities should rely on what is returned, no thrown errors, only returns
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Configuration
|
|
2
|
-
|
|
3
|
-
A wrapper around [`conf`](https://github.com/sindresorhus/conf) that provides a configuration file for storing environment variables.
|
|
4
|
-
|
|
5
|
-
The configuration will pull from a `config.json` file within the operating systems [preferred configuration locations](https://github.com/sindresorhus/env-paths?tab=readme-ov-file#pathsdata).
|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
```javascript
|
|
10
|
-
import { config } from "@/utils";
|
|
11
|
-
|
|
12
|
-
const debugMode = "preferences.debug";
|
|
13
|
-
|
|
14
|
-
// get an item
|
|
15
|
-
const isDebugMode = config.get(debugMode);
|
|
16
|
-
|
|
17
|
-
// set an item
|
|
18
|
-
config.write(debugMode, true);
|
|
19
|
-
```
|
|
20
|
-
## API
|
|
21
|
-
|
|
22
|
-
The API is a wrapper, so look at the [docs](https://github.com/sindresorhus/conf) for a detailed list of functions. The following is the ones that are most commonly used.
|
|
23
|
-
|
|
24
|
-
### `.get(key, defaultValue?)`
|
|
25
|
-
|
|
26
|
-
Get an item or `defaultValue` if the item does not exist.
|
|
27
|
-
|
|
28
|
-
### `.set(key, value)`
|
|
29
|
-
|
|
30
|
-
Set an item.
|
|
31
|
-
|
|
32
|
-
The value must be JSON serializable. Trying to set the type `undefined`, `function`, or `symbol` will result in a `TypeError`.
|
|
33
|
-
|
|
34
|
-
### `.set(object)`
|
|
35
|
-
|
|
36
|
-
Set multiple items at once.
|
|
37
|
-
|
|
38
|
-
### `.edit()`
|
|
39
|
-
|
|
40
|
-
Open the configuration file in your preferred `$EDITOR`;
|
|
41
|
-
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import Conf, { type Schema } from "conf";
|
|
2
|
-
import pkg from "@/package";
|
|
3
|
-
|
|
4
|
-
import { preferences, type PreferencesSchema } from "./preferences.conf";
|
|
5
|
-
|
|
6
|
-
interface ConfigSchema {
|
|
7
|
-
name: string;
|
|
8
|
-
preferences: PreferencesSchema;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const schema: Schema<ConfigSchema> = {
|
|
12
|
-
name: {
|
|
13
|
-
default: "holocron",
|
|
14
|
-
type: "string",
|
|
15
|
-
},
|
|
16
|
-
preferences: {
|
|
17
|
-
type: "object",
|
|
18
|
-
properties: preferences,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const config = new Conf({
|
|
23
|
-
projectName: pkg.name,
|
|
24
|
-
projectVersion: pkg.version,
|
|
25
|
-
schema,
|
|
26
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./config";
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
|
-
import { HOME, OS } from "@/const";
|
|
3
|
-
|
|
4
|
-
export interface PreferencesSchema {
|
|
5
|
-
debug: boolean;
|
|
6
|
-
destination: string;
|
|
7
|
-
ignoredFolders: string[];
|
|
8
|
-
notifications: boolean;
|
|
9
|
-
sound: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const preferences = {
|
|
13
|
-
debug: {
|
|
14
|
-
type: "boolean",
|
|
15
|
-
default: false,
|
|
16
|
-
},
|
|
17
|
-
destination: {
|
|
18
|
-
type: "string",
|
|
19
|
-
default: `${OS}/Desktop`,
|
|
20
|
-
},
|
|
21
|
-
ignoredFolders: {
|
|
22
|
-
type: "array",
|
|
23
|
-
items: {
|
|
24
|
-
type: "string",
|
|
25
|
-
},
|
|
26
|
-
uniqueItems: true,
|
|
27
|
-
default: [".DS_Store", "holocron", "coverage", "dist", "node_modules"],
|
|
28
|
-
},
|
|
29
|
-
logs: {
|
|
30
|
-
type: "string",
|
|
31
|
-
default:
|
|
32
|
-
process.env.LOG_DIR ||
|
|
33
|
-
(OS === "win32"
|
|
34
|
-
? path.join(process.env.LOCALAPPDATA || path.join(HOME, "AppData", "Local"), "Holocron", "logs")
|
|
35
|
-
: path.join(HOME, ".holocron", "logs")),
|
|
36
|
-
},
|
|
37
|
-
notifications: {
|
|
38
|
-
type: "boolean",
|
|
39
|
-
default: false,
|
|
40
|
-
},
|
|
41
|
-
sound: {
|
|
42
|
-
type: "boolean",
|
|
43
|
-
default: false,
|
|
44
|
-
},
|
|
45
|
-
};
|
package/src/utils/env/README.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# Environment Variables
|
|
2
|
-
|
|
3
|
-
A wrapper around [`dotenv`](https://github.com/motdotla/dotenv) that provides a configuration file for storing environment variables.
|
|
4
|
-
|
|
5
|
-
The configuration will pull from a `.env` file within the repository and place all of that data onto the `process.env` for instant access.
|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
```javascript
|
|
10
|
-
import { env } from "@/utils";
|
|
11
|
-
|
|
12
|
-
// grab every value within the configuration file
|
|
13
|
-
const [readErr, readData] = env.read();
|
|
14
|
-
|
|
15
|
-
// grab a specific variable
|
|
16
|
-
const [readAllErr, readAllData] = env.read("SOME_ENV_VAR");
|
|
17
|
-
|
|
18
|
-
// set a specific variable
|
|
19
|
-
const [writeErr, writeData] = env.write({ mockKey: "mockValue" });
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### When to use `env` methods or `process.env`
|
|
23
|
-
|
|
24
|
-
#### Use `process.env` for accessing environment variables
|
|
25
|
-
|
|
26
|
-
The point of `dotenv` is to allow you to put environment variables within a file in order to have them show up on `process.env`. So if you need access to any environment variable, rather than running it on the command-line, you can add it to the `.env` and it will be present.
|
|
27
|
-
|
|
28
|
-
#### Use `env.read()` for interfacing with the configuration file
|
|
29
|
-
|
|
30
|
-
Whenever you want the application to read the configuration file or values on it, then use `env.read()`. Common use cases would be to read the configuration before changing it, or reading the values to use it for setting something else such as a file name.
|
|
31
|
-
|
|
32
|
-
#### Use `env.write()` for writing to or updating the configuration file
|
|
33
|
-
|
|
34
|
-
Whenever you want the application to change the configuration file or values on it, then use `env.write()`. This will set permanent changes to the configuration file.
|
|
35
|
-
|
|
36
|
-
## API
|
|
37
|
-
|
|
38
|
-
### `.read(key?: string)`
|
|
39
|
-
|
|
40
|
-
Returns the value of the key specified or the entire environment variables object if no key is present.
|
|
41
|
-
|
|
42
|
-
#### key
|
|
43
|
-
|
|
44
|
-
Type: `string`
|
|
45
|
-
|
|
46
|
-
### `.write(obj: Record<string, string>)`
|
|
47
|
-
|
|
48
|
-
Returns `true` if writing to the environment variables file was successful, or `false` if there was an error.
|
|
49
|
-
|
|
50
|
-
#### obj
|
|
51
|
-
|
|
52
|
-
Type: `Record<string, string>`
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { env } from "@/utils";
|
|
2
|
-
|
|
3
|
-
const [err, data] = env.read();
|
|
4
|
-
|
|
5
|
-
if (err) {
|
|
6
|
-
console.error(err);
|
|
7
|
-
process.exit(1);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
console.log("Complete env");
|
|
11
|
-
console.log(data);
|
|
12
|
-
|
|
13
|
-
const [singleErr, singleData] = env.read("VERBOSE");
|
|
14
|
-
|
|
15
|
-
if (singleErr) {
|
|
16
|
-
console.error(singleErr);
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
console.log("Single key env");
|
|
21
|
-
console.log(singleData);
|
package/src/utils/env/env.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import dotenv from "dotenv";
|
|
3
|
-
|
|
4
|
-
const ENV_CONF = `${process.cwd()}/.env`;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Reads environment variables from the .env file.
|
|
8
|
-
*/
|
|
9
|
-
type ReadEnvReturn<T> = [Error | null, T];
|
|
10
|
-
|
|
11
|
-
const readEnv = <T = Record<string, string>>(key?: string): ReadEnvReturn<T> => {
|
|
12
|
-
try {
|
|
13
|
-
const result = dotenv.config();
|
|
14
|
-
|
|
15
|
-
if (result.error) {
|
|
16
|
-
return [result.error, {} as T];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const parsedData = result.parsed || {};
|
|
20
|
-
|
|
21
|
-
if (key && parsedData.hasOwnProperty(key)) {
|
|
22
|
-
return [null, parsedData[key] as T];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return [null, parsedData as T];
|
|
26
|
-
} catch (error) {
|
|
27
|
-
return [error as Error, {} as T];
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Writes environment variables to the .env file.
|
|
33
|
-
*/
|
|
34
|
-
const writeEnv = (obj: Record<string, string>): [Error | null, boolean] => {
|
|
35
|
-
try {
|
|
36
|
-
const [_, conf] = readEnv();
|
|
37
|
-
|
|
38
|
-
const newConf = {
|
|
39
|
-
...conf,
|
|
40
|
-
...obj,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const content = Object.entries(newConf)
|
|
44
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
45
|
-
.join("\n");
|
|
46
|
-
|
|
47
|
-
fs.writeFileSync(ENV_CONF, content, { flag: "w+" });
|
|
48
|
-
return [null, true];
|
|
49
|
-
} catch (err) {
|
|
50
|
-
return [err as Error, false];
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const env = {
|
|
55
|
-
read: readEnv,
|
|
56
|
-
write: writeEnv,
|
|
57
|
-
};
|
package/src/utils/env/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./env";
|