@benshawmean/envedit 1.3.1 → 1.3.2-2
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/.gitlab-ci.yml +9 -2
- package/{cmd → cli/cmd}/environmentCmd/add.ts +29 -26
- package/{cmd → cli/cmd}/environmentCmd/edit.ts +13 -21
- package/{cmd → cli/cmd}/environmentCmd/list.ts +2 -4
- package/{cmd → cli/cmd}/environmentCmd/remove.ts +11 -12
- package/{cmd → cli/cmd}/index.ts +2 -1
- package/{cmd/setup.ts → cli/cmd/init.ts} +17 -17
- package/cli/cmd/setup.ts +46 -0
- package/{cmd → cli/cmd}/use.ts +14 -10
- package/{cmd → cli/cmd}/variableCmd/add.ts +10 -8
- package/{cmd → cli/cmd}/variableCmd/edit.ts +38 -41
- package/{cmd → cli/cmd}/variableCmd/list.ts +4 -4
- package/{cmd → cli/cmd}/variableCmd/remove.ts +9 -12
- package/{index.ts → cli/index.ts} +1 -1
- package/lib/config.ts +26 -96
- package/package.json +3 -5
- /package/{cmd → cli/cmd}/environment.ts +0 -0
- /package/{cmd → cli/cmd}/environmentCmd/index.ts +0 -0
- /package/{cmd → cli/cmd}/variable.ts +0 -0
- /package/{cmd → cli/cmd}/variableCmd/index.ts +0 -0
package/.gitlab-ci.yml
CHANGED
|
@@ -65,6 +65,8 @@ publish:
|
|
|
65
65
|
export PACKAGE_NAME=$(jq -r '.name' package.json)
|
|
66
66
|
export CURR_VER=$(jq -r '.version' package.json)
|
|
67
67
|
export LIVE_VER=$(bun info $PACKAGE_NAME version)
|
|
68
|
+
export IS_PRE_RELEASE=$(echo $CURR_VER | grep -E '[-+]')
|
|
69
|
+
export PUBLISH_FLAGS=( "--silent" )
|
|
68
70
|
|
|
69
71
|
- | # Check if the current version is already published
|
|
70
72
|
if [ "$LIVE_VER" == "$CURR_VER" ]; then
|
|
@@ -73,9 +75,14 @@ publish:
|
|
|
73
75
|
fi
|
|
74
76
|
|
|
75
77
|
- bun pm pack --filename package.tgz
|
|
76
|
-
-
|
|
78
|
+
- |
|
|
79
|
+
if [ $IS_PRE_RELEASE ]; then
|
|
80
|
+
echo "Pre-release version detected. Publishing with 'next' tag."
|
|
81
|
+
PUBLISH_FLAGS+=( "--tag=next" )
|
|
82
|
+
fi
|
|
83
|
+
- bunx npm publish ${PUBLISH_FLAGS[*]} package.tgz
|
|
77
84
|
- sh ci/npm.sh
|
|
78
|
-
- bun publish
|
|
85
|
+
- bun publish ${PUBLISH_FLAGS[*]} package.tgz
|
|
79
86
|
- rm package.tgz .npmrc
|
|
80
87
|
|
|
81
88
|
allow_failure:
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
existsSync as exists,
|
|
3
|
+
unlinkSync as unlink,
|
|
4
|
+
symlinkSync as symlink,
|
|
5
|
+
} from "node:fs";
|
|
2
6
|
|
|
3
7
|
import { confirm, input, password, select } from "@inquirer/prompts";
|
|
4
8
|
|
|
@@ -11,7 +15,7 @@ export default {
|
|
|
11
15
|
describe: 'Add a new environment',
|
|
12
16
|
builder: (yargs) => yargs,
|
|
13
17
|
handler: async (argv) => {
|
|
14
|
-
const config = new Configuration()
|
|
18
|
+
const config = new Configuration();
|
|
15
19
|
const logger = new Logger(argv.level);
|
|
16
20
|
|
|
17
21
|
const name = await input({
|
|
@@ -20,7 +24,7 @@ export default {
|
|
|
20
24
|
if (!input) {
|
|
21
25
|
return "Environment name cannot be empty";
|
|
22
26
|
}
|
|
23
|
-
if (config.
|
|
27
|
+
if (config.envs.has(input)) {
|
|
24
28
|
return "Environment name already exists";
|
|
25
29
|
}
|
|
26
30
|
return true;
|
|
@@ -38,18 +42,17 @@ export default {
|
|
|
38
42
|
|
|
39
43
|
const isActive = await confirm({
|
|
40
44
|
message: "Is this environment active?",
|
|
45
|
+
default: !config.active,
|
|
41
46
|
});
|
|
42
47
|
|
|
43
|
-
logger
|
|
44
|
-
.debug(`Adding new environment "${name}" with prefix "${prefix}" and file: "${file}"`);
|
|
48
|
+
logger.debug(`Adding new environment "${name}" with prefix "${prefix}" and file: "${file}"`);
|
|
45
49
|
|
|
46
|
-
config
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
config.envs.set(name, { name, prefix, file, isActive });
|
|
51
|
+
config.save();
|
|
52
|
+
|
|
53
|
+
const envFile = new EnvironmentFile(file);
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (!fs.existsSync(file)) {
|
|
55
|
+
if (!exists(file)) {
|
|
53
56
|
logger.debug(`Environment file not found: ${file}`);
|
|
54
57
|
|
|
55
58
|
const shouldClone = await confirm({
|
|
@@ -61,13 +64,10 @@ export default {
|
|
|
61
64
|
|
|
62
65
|
const clonedEnv = await select({
|
|
63
66
|
message: "Select the environment to clone from:",
|
|
64
|
-
choices: config.
|
|
65
|
-
name: env.name,
|
|
66
|
-
value: env.name,
|
|
67
|
-
})),
|
|
67
|
+
choices: Array.from(config.envs.keys()),
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
const selectedEnv = config.
|
|
70
|
+
const selectedEnv = config.envs.get(clonedEnv);
|
|
71
71
|
|
|
72
72
|
if (!selectedEnv) {
|
|
73
73
|
throw new NotFoundError(`Environment not found: ${clonedEnv}`);
|
|
@@ -75,11 +75,11 @@ export default {
|
|
|
75
75
|
|
|
76
76
|
const envSpecificFile = new EnvironmentFile(selectedEnv.file);
|
|
77
77
|
|
|
78
|
-
for (const [key, value] of Object.entries(envSpecificFile.
|
|
79
|
-
|
|
78
|
+
for (const [key, value] of Object.entries(envSpecificFile.vars)) {
|
|
79
|
+
envFile.vars.set(key, value);
|
|
80
80
|
}
|
|
81
81
|
} else {
|
|
82
|
-
for (const variable of config.
|
|
82
|
+
for (const [_, variable] of config.vars) {
|
|
83
83
|
const request = {
|
|
84
84
|
message: `Enter the value for ${variable.name} in environment ${name}:`,
|
|
85
85
|
mask: variable.type === VariableType.Private ? "*" : undefined,
|
|
@@ -92,19 +92,22 @@ export default {
|
|
|
92
92
|
logger
|
|
93
93
|
.debug(`Setting variable "${variable.name}" with value "${value}" in environment "${name}"`);
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
envFile.vars.set(variable.name, value);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
envFile.save();
|
|
100
|
+
}
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
.debug(`Setting variable "${key}" with value "${value}" in environment file: ${file}`);
|
|
102
|
+
if (isActive) {
|
|
103
|
+
config.active = name;
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
if (exists('.env')) {
|
|
106
|
+
unlink('.env');
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
const properEnv = config.envs.get(name)!;
|
|
110
|
+
symlink(properEnv.file, '.env', 'file');
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
} satisfies CommandModule;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
renameSync as rename,
|
|
3
|
+
existsSync as exists,
|
|
4
|
+
} from "node:fs";
|
|
2
5
|
|
|
3
|
-
import {
|
|
6
|
+
import { input, select, checkbox } from "@inquirer/prompts";
|
|
4
7
|
|
|
5
8
|
import { Configuration } from "#lib/config";
|
|
6
9
|
import { NotFoundError } from "#lib/error";
|
|
@@ -11,18 +14,15 @@ export default {
|
|
|
11
14
|
describe: 'Edit an environment',
|
|
12
15
|
builder: (yargs) => yargs,
|
|
13
16
|
handler: async (argv) => {
|
|
14
|
-
const config = new Configuration()
|
|
17
|
+
const config = new Configuration();
|
|
15
18
|
const logger = new Logger(argv.level);
|
|
16
19
|
|
|
17
20
|
const name = await select({
|
|
18
21
|
message: "Select the environment to edit:",
|
|
19
|
-
choices: config.
|
|
20
|
-
name: env.name,
|
|
21
|
-
value: env.name,
|
|
22
|
-
})),
|
|
22
|
+
choices: Array.from(config.envs.keys()),
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
const selectedEnv = config.
|
|
25
|
+
const selectedEnv = config.envs.get(name);
|
|
26
26
|
|
|
27
27
|
if (!selectedEnv) {
|
|
28
28
|
throw new NotFoundError(`Environment not found: ${name}`);
|
|
@@ -63,20 +63,12 @@ export default {
|
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
config
|
|
67
|
-
|
|
68
|
-
.save();
|
|
66
|
+
config.envs.set(name, updatedEnv);
|
|
67
|
+
config.save();
|
|
69
68
|
|
|
70
|
-
if (itemsToEdit.includes("file") &&
|
|
71
|
-
logger.debug(`
|
|
72
|
-
|
|
73
|
-
message: `Old environment file found: ${selectedEnv.file}. Do you want to rename it to the new file path: ${updatedEnv.file}?`
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (toRename) {
|
|
77
|
-
logger.debug(`Renaming environment file from "${selectedEnv.file}" to "${updatedEnv.file}"`);
|
|
78
|
-
fs.renameSync(selectedEnv.file, updatedEnv.file);
|
|
79
|
-
}
|
|
69
|
+
if (itemsToEdit.includes("file") && exists(selectedEnv.file)) {
|
|
70
|
+
logger.debug(`Renaming environment file from "${selectedEnv.file}" to "${updatedEnv.file}"`);
|
|
71
|
+
rename(selectedEnv.file, updatedEnv.file);
|
|
80
72
|
}
|
|
81
73
|
}
|
|
82
74
|
} satisfies CommandModule;
|
|
@@ -6,13 +6,11 @@ export default {
|
|
|
6
6
|
describe: 'List all environments',
|
|
7
7
|
builder: (yargs) => yargs,
|
|
8
8
|
handler: async (argv) => {
|
|
9
|
-
const config = new Configuration()
|
|
9
|
+
const config = new Configuration();
|
|
10
10
|
const logger = new Logger(argv.level);
|
|
11
11
|
|
|
12
12
|
logger.debug(`Listing all environments`);
|
|
13
13
|
|
|
14
|
-
console.log(
|
|
15
|
-
JSON.stringify(config.configuration.environments, null, 2)
|
|
16
|
-
)
|
|
14
|
+
console.log(JSON.stringify(Array.from(config.envs.values()), null, 2));
|
|
17
15
|
}
|
|
18
16
|
} satisfies CommandModule;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
existsSync as exists,
|
|
3
|
+
unlinkSync as unlink,
|
|
4
|
+
} from "node:fs";
|
|
2
5
|
|
|
3
6
|
import { confirm, select } from "@inquirer/prompts";
|
|
4
7
|
|
|
@@ -11,18 +14,15 @@ export default {
|
|
|
11
14
|
describe: 'Remove an environment',
|
|
12
15
|
builder: (yargs) => yargs,
|
|
13
16
|
handler: async (argv) => {
|
|
14
|
-
const config = new Configuration()
|
|
17
|
+
const config = new Configuration();
|
|
15
18
|
const logger = new Logger(argv.level);
|
|
16
19
|
|
|
17
20
|
const name = await select({
|
|
18
21
|
message: "Select the environment to remove:",
|
|
19
|
-
choices: config.
|
|
20
|
-
name: env.name,
|
|
21
|
-
value: env.name,
|
|
22
|
-
})),
|
|
22
|
+
choices: Array.from(config.envs.keys()),
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
const selectedEnv = config.
|
|
25
|
+
const selectedEnv = config.envs.get(name);
|
|
26
26
|
|
|
27
27
|
if (!selectedEnv) {
|
|
28
28
|
throw new NotFoundError(`Environment not found: ${name}`);
|
|
@@ -30,18 +30,17 @@ export default {
|
|
|
30
30
|
|
|
31
31
|
logger.debug(`Removing environment "${name}" with file: "${selectedEnv.file}"`);
|
|
32
32
|
|
|
33
|
-
config
|
|
34
|
-
|
|
35
|
-
.save();
|
|
33
|
+
config.envs.delete(name);
|
|
34
|
+
config.save();
|
|
36
35
|
|
|
37
|
-
if (
|
|
36
|
+
if (exists(selectedEnv.file)) {
|
|
38
37
|
const toDelete = await confirm({
|
|
39
38
|
message: `Environment file found: ${selectedEnv.file}. Do you want to delete it?`
|
|
40
39
|
});
|
|
41
40
|
|
|
42
41
|
if (toDelete) {
|
|
43
42
|
logger.debug(`Deleting environment file: ${selectedEnv.file}`);
|
|
44
|
-
|
|
43
|
+
unlink(selectedEnv.file);
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
}
|
package/{cmd → cli/cmd}/index.ts
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Environment from './environment';
|
|
2
2
|
import Variable from './variable';
|
|
3
3
|
import Use from './use';
|
|
4
|
+
import Init from './init';
|
|
4
5
|
import Setup from './setup';
|
|
5
6
|
|
|
6
|
-
export default [Environment, Variable, Use, Setup];
|
|
7
|
+
export default [Environment, Variable, Use, Init, Setup];
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
existsSync as exists,
|
|
3
|
+
readFileSync as read,
|
|
4
|
+
writeFileSync as write,
|
|
5
|
+
appendFileSync as append,
|
|
6
|
+
} from "node:fs";
|
|
2
7
|
|
|
3
8
|
import { confirm } from "@inquirer/prompts";
|
|
4
9
|
|
|
@@ -6,33 +11,28 @@ import { Configuration } from "#lib/config";
|
|
|
6
11
|
import { Logger } from "#lib/logger";
|
|
7
12
|
|
|
8
13
|
export default {
|
|
9
|
-
command: '
|
|
10
|
-
describe: '
|
|
14
|
+
command: 'init',
|
|
15
|
+
describe: 'Initialize the project for use with envedit',
|
|
11
16
|
builder: (yargs) => yargs
|
|
12
|
-
.usage('Usage: envedit
|
|
17
|
+
.usage('Usage: envedit init')
|
|
18
|
+
.epilogue("Note that this command is meant to be used when the project is FIRST setup, not to setup based on a pre-existing configuration. for that, please run the 'setup' command"),
|
|
13
19
|
handler: async (argv) => {
|
|
14
20
|
const logger = new Logger(argv.level);
|
|
21
|
+
new Configuration();
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (fs.existsSync('.git')) {
|
|
23
|
+
if (exists('.git')) {
|
|
19
24
|
logger.debug(`Git repository found. Checking for git ignore file.`);
|
|
20
25
|
|
|
21
26
|
const gitignorePath = '.gitignore';
|
|
22
27
|
|
|
23
|
-
if (!
|
|
24
|
-
logger.debug(`Git ignore file not found: ${gitignorePath}`);
|
|
25
|
-
|
|
28
|
+
if (!exists('.gitignore')) {
|
|
26
29
|
const toCreate = await confirm({
|
|
27
|
-
message: `Git Repository without a git ignore file not found
|
|
30
|
+
message: `Git Repository without a git ignore file not found. Do you want to create it?`
|
|
28
31
|
});
|
|
29
32
|
|
|
30
33
|
if (toCreate) {
|
|
31
|
-
|
|
32
|
-
process.exit(1);
|
|
34
|
+
write('.gitignore', "");
|
|
33
35
|
}
|
|
34
|
-
|
|
35
|
-
fs.writeFileSync(gitignorePath, "");
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const expectedItems = ['.env', '.env.*'];
|
|
@@ -40,7 +40,7 @@ export default {
|
|
|
40
40
|
logger.debug(`Checking for expected items in git ignore file: ${expectedItems.join(", ")}`);
|
|
41
41
|
|
|
42
42
|
for (const item of expectedItems) {
|
|
43
|
-
if (
|
|
43
|
+
if (read(gitignorePath, "utf-8").includes(item)) {
|
|
44
44
|
logger.debug(`Item not found in git ignore file: ${item}`);
|
|
45
45
|
|
|
46
46
|
const toAdd = await confirm({
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
process.exit(1);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
append(gitignorePath, `\n${item}`);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
package/cli/cmd/setup.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lstatSync as lstat,
|
|
3
|
+
existsSync as exists,
|
|
4
|
+
copyFileSync as copy,
|
|
5
|
+
unlinkSync as unlink,
|
|
6
|
+
symlinkSync as symlink,
|
|
7
|
+
} from 'node:fs';
|
|
8
|
+
|
|
9
|
+
import { Configuration, EnvironmentFile } from "#lib/config";
|
|
10
|
+
import { NotFoundError } from "#lib/error";
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
command: 'setup',
|
|
14
|
+
describe: 'Setup the project for use with envedit',
|
|
15
|
+
builder: (yargs) => yargs
|
|
16
|
+
.usage('Usage: envedit setup')
|
|
17
|
+
.epilogue("Note that this command is meant to be used after the project has been setup. To make a clean start, please run the 'init' command instead."),
|
|
18
|
+
handler: async (_argv) => {
|
|
19
|
+
if (!exists('env.config.yaml')) {
|
|
20
|
+
throw new NotFoundError("Could not find configuration file. Did you run the init command?")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const config = new Configuration();
|
|
24
|
+
|
|
25
|
+
for (const environment of config.envs.values()) {
|
|
26
|
+
const envFile = new EnvironmentFile(environment.file);
|
|
27
|
+
|
|
28
|
+
if (environment.isActive) {
|
|
29
|
+
if (exists('.env') && !lstat('.env').isSymbolicLink()) {
|
|
30
|
+
copy('.env', environment.file);
|
|
31
|
+
unlink('.env');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
symlink(environment.file, '.env', 'file');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const variable of config.vars.values()) {
|
|
38
|
+
if (!envFile.vars.has(variable.name)) {
|
|
39
|
+
envFile.vars.set(variable.name, '');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
envFile.save();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} as CommandModule;
|
package/{cmd → cli/cmd}/use.ts
RENAMED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
lstatSync as lstat,
|
|
3
|
+
existsSync as exists,
|
|
4
|
+
unlinkSync as unlink,
|
|
5
|
+
symlinkSync as symlink,
|
|
6
|
+
} from 'node:fs';
|
|
2
7
|
|
|
3
8
|
import { select } from "@inquirer/prompts";
|
|
4
9
|
|
|
@@ -13,19 +18,18 @@ export default {
|
|
|
13
18
|
.usage('Usage: envedit use'),
|
|
14
19
|
handler: async (argv) => {
|
|
15
20
|
const logger = new Logger(argv.level);
|
|
16
|
-
|
|
17
|
-
const config = new Configuration().load();
|
|
21
|
+
const config = new Configuration();
|
|
18
22
|
|
|
19
23
|
const name = await select({
|
|
20
24
|
message: "Select the environment to use",
|
|
21
|
-
choices: config.
|
|
22
|
-
name: env
|
|
23
|
-
value: env
|
|
25
|
+
choices: Array.from(config.envs.keys()).map(env => ({
|
|
26
|
+
name: env + (config.envs.get(env)?.isActive ? " (active)" : ""),
|
|
27
|
+
value: env,
|
|
24
28
|
})),
|
|
25
29
|
default: config.active,
|
|
26
30
|
});
|
|
27
31
|
|
|
28
|
-
const selectedEnv = config.
|
|
32
|
+
const selectedEnv = config.envs.get(name);
|
|
29
33
|
|
|
30
34
|
if (!selectedEnv) {
|
|
31
35
|
throw new NotFoundError(`Environment not found: ${name}`);
|
|
@@ -45,12 +49,12 @@ export default {
|
|
|
45
49
|
|
|
46
50
|
const envFilePath = selectedEnv.file;
|
|
47
51
|
|
|
48
|
-
if (
|
|
52
|
+
if (exists('.env')) {
|
|
49
53
|
logger.debug(`Removing existing symlink or file: .env`);
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
unlink('.env');
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
symlink(envFilePath, '.env', 'file');
|
|
55
59
|
}
|
|
56
60
|
} as CommandModule;
|
|
@@ -9,7 +9,7 @@ export default {
|
|
|
9
9
|
describe: 'Add a new environment variable',
|
|
10
10
|
builder: (yargs) => yargs,
|
|
11
11
|
handler: async (argv) => {
|
|
12
|
-
const config = new Configuration()
|
|
12
|
+
const config = new Configuration();
|
|
13
13
|
const logger = new Logger(argv.level);
|
|
14
14
|
|
|
15
15
|
const name = await input({
|
|
@@ -18,7 +18,7 @@ export default {
|
|
|
18
18
|
if (!input) {
|
|
19
19
|
return "Variable name cannot be empty";
|
|
20
20
|
}
|
|
21
|
-
if (config.
|
|
21
|
+
if (config.vars.has(input)) {
|
|
22
22
|
return "Variable name already exists";
|
|
23
23
|
}
|
|
24
24
|
return true;
|
|
@@ -35,15 +35,14 @@ export default {
|
|
|
35
35
|
|
|
36
36
|
logger.debug(`Adding new variable "${name}" with type "${type}"`);
|
|
37
37
|
|
|
38
|
-
config
|
|
39
|
-
|
|
40
|
-
.save();
|
|
38
|
+
config.vars.set(name, { name, type });
|
|
39
|
+
config.save();
|
|
41
40
|
|
|
42
41
|
const shouldGloballySet = await confirm({
|
|
43
42
|
message: "Do you want to set this variable with a global value for all environments?",
|
|
44
43
|
});
|
|
45
44
|
|
|
46
|
-
const valuesToSet = config.
|
|
45
|
+
const valuesToSet = Array.from(config.envs.values()).map(env => ({
|
|
47
46
|
envName: env.name,
|
|
48
47
|
value: '',
|
|
49
48
|
}));
|
|
@@ -77,14 +76,17 @@ export default {
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
for (const envValue of valuesToSet) {
|
|
80
|
-
const env = config.
|
|
79
|
+
const env = config.envs.get(envValue.envName);
|
|
81
80
|
logger.debug(`Retrieving environment: ${envValue.envName}`);
|
|
82
81
|
|
|
83
82
|
if (!env) {
|
|
84
83
|
throw new NotFoundError(`Environment not found: ${envValue.envName}`);
|
|
85
84
|
}
|
|
86
85
|
|
|
87
|
-
EnvironmentFile
|
|
86
|
+
const envFile = new EnvironmentFile(env.file);
|
|
87
|
+
|
|
88
|
+
envFile.vars.set(name, envValue.value);
|
|
89
|
+
envFile.save();
|
|
88
90
|
}
|
|
89
91
|
}
|
|
90
92
|
} satisfies CommandModule;
|
|
@@ -9,18 +9,15 @@ export default {
|
|
|
9
9
|
describe: 'Edit an environment variable',
|
|
10
10
|
builder: (yargs) => yargs,
|
|
11
11
|
handler: async (argv) => {
|
|
12
|
-
const config = new Configuration()
|
|
12
|
+
const config = new Configuration();
|
|
13
13
|
const logger = new Logger(argv.level);
|
|
14
14
|
|
|
15
15
|
const name = await select({
|
|
16
16
|
message: "Select the variable to edit:",
|
|
17
|
-
choices: config.
|
|
18
|
-
name: variable.name,
|
|
19
|
-
value: variable.name,
|
|
20
|
-
})),
|
|
17
|
+
choices: Array.from(config.vars.keys()),
|
|
21
18
|
});
|
|
22
19
|
|
|
23
|
-
const variableConfiguration = config.
|
|
20
|
+
const variableConfiguration = config.vars.get(name);
|
|
24
21
|
|
|
25
22
|
if (!variableConfiguration) {
|
|
26
23
|
throw new NotFoundError(`Variable not found: ${name}`);
|
|
@@ -53,17 +50,22 @@ export default {
|
|
|
53
50
|
default: variableConfiguration.name,
|
|
54
51
|
});
|
|
55
52
|
|
|
56
|
-
for (const env of config.
|
|
53
|
+
for (const [_, env] of config.envs) {
|
|
57
54
|
const envFile = new EnvironmentFile(env.file);
|
|
58
55
|
|
|
59
56
|
logger.debug(`Editing variable "${name}" in environment file: ${env.file}`);
|
|
60
57
|
|
|
61
|
-
if (envFile.
|
|
62
|
-
envFile
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
if (envFile.vars.has(name)) {
|
|
59
|
+
const value = envFile.vars.get(name) || '';
|
|
60
|
+
|
|
61
|
+
envFile.vars.delete(name);
|
|
62
|
+
envFile.vars.set(updatedVariable.name, value);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
envFile.save();
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
config.vars.delete(name);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
if (itemsToEdit.includes("type")) {
|
|
@@ -79,13 +81,12 @@ export default {
|
|
|
79
81
|
logger.debug(`Editing variable type for "${name}" to "${updatedVariable.type}"`);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
config
|
|
83
|
-
|
|
84
|
-
.save();
|
|
84
|
+
config.vars.set(updatedVariable.name, updatedVariable);
|
|
85
|
+
config.save();
|
|
85
86
|
} else {
|
|
86
|
-
logger.debug(`Adding
|
|
87
|
+
logger.debug(`Adding edited variable value for: ${name}`);
|
|
87
88
|
|
|
88
|
-
let valuesToSet = config.
|
|
89
|
+
let valuesToSet = Array.from(config.envs.values()).map(env => ({
|
|
89
90
|
envName: env.name,
|
|
90
91
|
value: '',
|
|
91
92
|
}));
|
|
@@ -106,47 +107,43 @@ export default {
|
|
|
106
107
|
|
|
107
108
|
logger.debug(`Setting variable "${variableConfiguration.name}" with global value "${globalValue}" for all environments`);
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
for (const [_, env] of config.envs) {
|
|
111
|
+
const envFile = new EnvironmentFile(env.file);
|
|
112
|
+
|
|
113
|
+
logger.debug(`Setting variable "${variableConfiguration.name}" with value "${globalValue}" in environment file: ${env.file}`);
|
|
114
|
+
|
|
115
|
+
envFile.vars.set(variableConfiguration.name, globalValue);
|
|
116
|
+
envFile.save();
|
|
117
|
+
}
|
|
110
118
|
} else {
|
|
111
119
|
const envsToEdit = await checkbox({
|
|
112
120
|
message: "Select the environments to edit the variable value for:",
|
|
113
|
-
choices: config.
|
|
114
|
-
name: env.name,
|
|
115
|
-
value: env.name,
|
|
116
|
-
})),
|
|
121
|
+
choices: Array.from(config.envs.keys()),
|
|
117
122
|
});
|
|
118
123
|
|
|
119
124
|
logger.debug(`Selected environments for editing: ${envsToEdit.join(", ")}`);
|
|
120
125
|
|
|
121
|
-
|
|
126
|
+
for (const selectedEnv of envsToEdit) {
|
|
127
|
+
const env = config.envs.get(selectedEnv);
|
|
122
128
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
129
|
+
if (!env) {
|
|
130
|
+
throw new NotFoundError(`Environment not found: ${selectedEnv}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const envFile = new EnvironmentFile(env.file);
|
|
127
134
|
|
|
128
|
-
for (const envValue of valuesToSet) {
|
|
129
135
|
const request = {
|
|
130
|
-
message: `Enter the value for ${variableConfiguration.name} in environment ${
|
|
136
|
+
message: `Enter the value for ${variableConfiguration.name} in environment ${selectedEnv}:`,
|
|
131
137
|
mask: variableConfiguration.type === VariableType.Private ? "*" : undefined,
|
|
132
138
|
};
|
|
133
139
|
|
|
134
|
-
|
|
140
|
+
const newValue = variableConfiguration.type === VariableType.Private
|
|
135
141
|
? await password(request)
|
|
136
142
|
: await input(request);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
for (const envValue of valuesToSet) {
|
|
141
|
-
const env = config.getEnvironment(envValue.envName);
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
envFile.vars.set(variableConfiguration.name, newValue);
|
|
145
|
+
envFile.save();
|
|
145
146
|
}
|
|
146
|
-
|
|
147
|
-
logger.debug(`Setting variable "${variableConfiguration.name}" with value "${envValue.value}" in environment file: ${env.file}`);
|
|
148
|
-
|
|
149
|
-
EnvironmentFile.quickUpdate(env.file, variableConfiguration.name, envValue.value);
|
|
150
147
|
}
|
|
151
148
|
}
|
|
152
149
|
}
|
|
@@ -7,10 +7,10 @@ export default {
|
|
|
7
7
|
describe: 'List all environment variables',
|
|
8
8
|
builder: (yargs) => yargs,
|
|
9
9
|
handler: async (argv) => {
|
|
10
|
-
const config = new Configuration()
|
|
10
|
+
const config = new Configuration();
|
|
11
11
|
const logger = new Logger(argv.level);
|
|
12
12
|
|
|
13
|
-
const activeEnv = config.active ? config.
|
|
13
|
+
const activeEnv = config.active ? config.envs.get(config.active)! : undefined;
|
|
14
14
|
|
|
15
15
|
if (!activeEnv) {
|
|
16
16
|
throw new NotFoundError(`No active environment found. Please set an active environment using the "use" command.`);
|
|
@@ -18,8 +18,8 @@ export default {
|
|
|
18
18
|
|
|
19
19
|
const envFile = new EnvironmentFile(activeEnv.file);
|
|
20
20
|
|
|
21
|
-
for (const [key, value] of
|
|
22
|
-
const variableConfiguration = config.
|
|
21
|
+
for (const [key, value] of envFile.vars) {
|
|
22
|
+
const variableConfiguration = config.vars.get(key);
|
|
23
23
|
if (variableConfiguration) {
|
|
24
24
|
const type = Configuration.getTypeDetails(variableConfiguration.type);
|
|
25
25
|
|
|
@@ -9,33 +9,30 @@ export default {
|
|
|
9
9
|
describe: 'Remove an environment variable',
|
|
10
10
|
builder: (yargs) => yargs,
|
|
11
11
|
handler: async (argv) => {
|
|
12
|
-
const config = new Configuration()
|
|
12
|
+
const config = new Configuration();
|
|
13
13
|
const logger = new Logger(argv.level);
|
|
14
14
|
|
|
15
15
|
const name = await select({
|
|
16
16
|
message: "Select the variable to remove:",
|
|
17
|
-
choices: config.
|
|
18
|
-
name: variable.name,
|
|
19
|
-
value: variable.name,
|
|
20
|
-
})),
|
|
17
|
+
choices: Array.from(config.vars.keys()),
|
|
21
18
|
});
|
|
22
19
|
|
|
23
|
-
if (!config.
|
|
20
|
+
if (!config.vars.has(name)) {
|
|
24
21
|
throw new NotFoundError(`Variable not found: ${name}`);
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
logger.debug(`Removing variable "${name}" from configuration and all environment files`);
|
|
28
25
|
|
|
29
|
-
config
|
|
30
|
-
|
|
31
|
-
.save();
|
|
26
|
+
config.vars.delete(name);
|
|
27
|
+
config.save();
|
|
32
28
|
|
|
33
|
-
for (const env of config.
|
|
29
|
+
for (const [_, env] of config.envs) {
|
|
34
30
|
const envFile = new EnvironmentFile(env.file);
|
|
35
31
|
|
|
36
|
-
if (envFile.
|
|
32
|
+
if (envFile.vars.has(name)) {
|
|
37
33
|
logger.debug(`Removing variable "${name}" from environment file: ${env.file}`);
|
|
38
|
-
envFile.
|
|
34
|
+
envFile.vars.delete(name);
|
|
35
|
+
envFile.save();
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
38
|
}
|
|
@@ -9,13 +9,13 @@ await yargs(hideBin(process.argv))
|
|
|
9
9
|
alias: "l",
|
|
10
10
|
type: "string",
|
|
11
11
|
description: "Set the log level",
|
|
12
|
-
choices: ['debug', 'info', 'warn', 'error', 'fatal'],
|
|
13
12
|
default: process.env.LOG_LEVEL || "info",
|
|
14
13
|
})
|
|
15
14
|
.env('ENVEDIT')
|
|
16
15
|
.scriptName("envedit")
|
|
17
16
|
.usage("Usage: $0 <command>")
|
|
18
17
|
.command(Commands)
|
|
18
|
+
.showHelpOnFail(false)
|
|
19
19
|
.demandCommand()
|
|
20
20
|
.strict()
|
|
21
21
|
.parseAsync();
|
package/lib/config.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
existsSync as exists,
|
|
3
|
+
readFileSync as read,
|
|
4
|
+
writeFileSync as write,
|
|
5
|
+
appendFileSync as append,
|
|
6
|
+
} from 'fs';
|
|
2
7
|
|
|
3
8
|
import { parse } from 'dotenv';
|
|
4
9
|
|
|
@@ -33,15 +38,7 @@ export class Configuration {
|
|
|
33
38
|
public readonly version: number = 1;
|
|
34
39
|
private readonly configFilePath: string = 'env.config.yaml';
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
version: this.version,
|
|
39
|
-
environments: Array.from(this.envs.values()) || [],
|
|
40
|
-
variables: Array.from(this.vars.values()) || [],
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public load() {
|
|
41
|
+
constructor() {
|
|
45
42
|
if (!exists(this.configFilePath)) {
|
|
46
43
|
this
|
|
47
44
|
.importFromEnv(exists('.env') ? read('.env', "utf-8") : '')
|
|
@@ -57,13 +54,16 @@ export class Configuration {
|
|
|
57
54
|
configContent.environments.forEach(setWrapper(this.envs))
|
|
58
55
|
configContent.variables.forEach(setWrapper(this.vars))
|
|
59
56
|
|
|
60
|
-
return this;
|
|
61
57
|
}
|
|
62
58
|
|
|
63
59
|
public save() {
|
|
64
60
|
write(
|
|
65
61
|
this.configFilePath,
|
|
66
|
-
Bun.YAML.stringify(
|
|
62
|
+
Bun.YAML.stringify({
|
|
63
|
+
version: this.version,
|
|
64
|
+
environments: Array.from(this.envs.values()),
|
|
65
|
+
variables: Array.from(this.vars.values()),
|
|
66
|
+
}, null, 2),
|
|
67
67
|
{ mode: 0o600 },
|
|
68
68
|
);
|
|
69
69
|
|
|
@@ -88,64 +88,9 @@ export class Configuration {
|
|
|
88
88
|
this.save();
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
public addEnvironment(env: EnviornmentConfiguration) {
|
|
92
|
-
this.envs.set(env.name, env);
|
|
93
|
-
|
|
94
|
-
return this;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public editEnvironment(name: string, env: Partial<EnviornmentConfiguration>) {
|
|
98
|
-
if (!this.envs.has(name)) {
|
|
99
|
-
throw new NotFoundError(`Environment not found: ${name}`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
this.envs.set(name, { ...this.envs.get(name)!, ...env });
|
|
103
|
-
|
|
104
|
-
return this;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
public removeEnvironment(name: string) {
|
|
108
|
-
this.envs.delete(name);
|
|
109
|
-
|
|
110
|
-
return this;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public getEnvironment(name: string): EnviornmentConfiguration | undefined {
|
|
114
|
-
return this.envs.get(name);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public addVariable(variable: VariableConfiguration) {
|
|
118
|
-
this.vars.set(variable.name, variable);
|
|
119
|
-
|
|
120
|
-
return this;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
public editVariable(name: string, variable: Partial<VariableConfiguration>) {
|
|
124
|
-
if (!this.vars.has(name)) {
|
|
125
|
-
throw new NotFoundError(`Variable not found: ${name}`);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
this.vars.set(name, { ...this.vars.get(name)!, ...variable });
|
|
129
|
-
|
|
130
|
-
return this;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public removeVariable(name: string) {
|
|
134
|
-
this.vars.delete(name);
|
|
135
|
-
|
|
136
|
-
return this;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public getVariable(name: string): VariableConfiguration | undefined {
|
|
140
|
-
return this.vars.get(name);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
91
|
public importFromEnv(content: string): Configuration {
|
|
144
92
|
for (const [key, _] of Object.entries(parse(content))) {
|
|
145
|
-
this.
|
|
146
|
-
name: key,
|
|
147
|
-
type: key.includes('PRIVATE') ? VariableType.Private : VariableType.Public,
|
|
148
|
-
});
|
|
93
|
+
this.vars.set(key, { name: key, type: VariableType.Private });
|
|
149
94
|
}
|
|
150
95
|
|
|
151
96
|
return this;
|
|
@@ -167,37 +112,22 @@ export class Configuration {
|
|
|
167
112
|
}
|
|
168
113
|
|
|
169
114
|
export class EnvironmentFile {
|
|
170
|
-
|
|
171
|
-
public
|
|
172
|
-
if (
|
|
173
|
-
|
|
115
|
+
public readonly vars: Map<string, string> = new Map();
|
|
116
|
+
constructor(public readonly path: string) {
|
|
117
|
+
if (exists(path)) {
|
|
118
|
+
const content = read(path, "utf-8");
|
|
119
|
+
const parsed = parse(content);
|
|
120
|
+
|
|
121
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
122
|
+
this.vars.set(key, value);
|
|
123
|
+
}
|
|
174
124
|
}
|
|
175
|
-
return parse(fs.readFileSync(this.path, "utf-8"));
|
|
176
125
|
}
|
|
177
126
|
|
|
178
|
-
public
|
|
179
|
-
|
|
180
|
-
for (const [key, value] of
|
|
181
|
-
|
|
127
|
+
public save() {
|
|
128
|
+
write(this.path, '')
|
|
129
|
+
for (const [key, value] of this.vars.entries()) {
|
|
130
|
+
append(this.path, `${key}='${value}'\n`);
|
|
182
131
|
}
|
|
183
|
-
fs.writeFileSync(this.path, lines.join('\n'));
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
public setVariable(name: string, value: string) {
|
|
187
|
-
this.data = { ...this.data, [name]: value };
|
|
188
|
-
return this;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
public removeVariable(name: string) {
|
|
192
|
-
const tmpData = Object.assign({}, this.data);
|
|
193
|
-
delete tmpData[name];
|
|
194
|
-
this.data = tmpData;
|
|
195
|
-
return this;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
public static quickUpdate(path: string, name: string, value: string) {
|
|
199
|
-
const envFile = new EnvironmentFile(path);
|
|
200
|
-
envFile.setVariable(name, value);
|
|
201
|
-
return envFile;
|
|
202
132
|
}
|
|
203
133
|
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benshawmean/envedit",
|
|
3
|
-
"module": "index.ts",
|
|
4
3
|
"type": "module",
|
|
5
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.2-2",
|
|
6
5
|
"license": "GPL-3.0-only",
|
|
7
6
|
"bin": {
|
|
8
|
-
"envedit": "index.ts"
|
|
7
|
+
"envedit": "cli/index.ts"
|
|
9
8
|
},
|
|
10
9
|
"repository": {
|
|
11
10
|
"url": "https://gitlab.com/benshawmean/envedit.git"
|
|
12
11
|
},
|
|
13
12
|
"publishConfig": {
|
|
14
13
|
"access": "public",
|
|
15
|
-
"provenance": true
|
|
16
|
-
"tag": "latest"
|
|
14
|
+
"provenance": true
|
|
17
15
|
},
|
|
18
16
|
"devDependencies": {
|
|
19
17
|
"@types/bun": "^1.3.14",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|