getmyenv 0.1.1
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 -0
- package/README.md +13 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +105 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +8 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +64 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/backup.d.ts +7 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +35 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/export.d.ts +9 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +48 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +58 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +35 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +13 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/migrate.d.ts +13 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +127 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/restore.d.ts +8 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +61 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/run.d.ts +8 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +164 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +76 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/lib/api.d.ts +27 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +97 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/credentials.d.ts +9 -0
- package/dist/lib/credentials.d.ts.map +1 -0
- package/dist/lib/credentials.js +46 -0
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/env-name.d.ts +3 -0
- package/dist/lib/env-name.d.ts.map +1 -0
- package/dist/lib/env-name.js +5 -0
- package/dist/lib/env-name.js.map +1 -0
- package/dist/lib/fs.d.ts +56 -0
- package/dist/lib/fs.d.ts.map +1 -0
- package/dist/lib/fs.js +501 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/lib/identity.d.ts +12 -0
- package/dist/lib/identity.d.ts.map +1 -0
- package/dist/lib/identity.js +38 -0
- package/dist/lib/identity.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 getenv.dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# getmyenv
|
|
2
|
+
|
|
3
|
+
CLI for [getmyenv](https://getmyenv.com) - encrypted environment variables for any language.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx getmyenv login
|
|
7
|
+
npx getmyenv migrate
|
|
8
|
+
npx getmyenv run -- npm start
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Create a token at https://getmyenv.com/cli, then `login` (or paste when a command asks). Login may offer to run `migrate`. Migrate searches this folder tree for `.env*` files (including `.env.example` / `.env.sample`) and lists candidates. Use `--file` to pick a path. Defaults to `https://getmyenv.com`. Use `login --api-url` or `--api-url` for another origin.
|
|
12
|
+
|
|
13
|
+
See https://getmyenv.com/docs
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from "./cli.js";
|
|
3
|
+
runCli(process.argv).catch((err) => {
|
|
4
|
+
const message = err instanceof Error ? err.message : "Unexpected error";
|
|
5
|
+
// Never print secret values - sanitize to message only
|
|
6
|
+
console.error(`getmyenv: ${message}`);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACxE,uDAAuD;IACvD,OAAO,CAAC,KAAK,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA0BA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmI1D"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { initCommand } from "./commands/init.js";
|
|
3
|
+
import { migrateCommand } from "./commands/migrate.js";
|
|
4
|
+
import { addCommand } from "./commands/add.js";
|
|
5
|
+
import { statusCommand } from "./commands/status.js";
|
|
6
|
+
import { exportCommand } from "./commands/export.js";
|
|
7
|
+
import { backupCommand } from "./commands/backup.js";
|
|
8
|
+
import { restoreCommand } from "./commands/restore.js";
|
|
9
|
+
import { runCommand } from "./commands/run.js";
|
|
10
|
+
import { loginCommand } from "./commands/login.js";
|
|
11
|
+
import { logoutCommand } from "./commands/logout.js";
|
|
12
|
+
import { normalizeEnvName } from "./lib/env-name.js";
|
|
13
|
+
import { resolveApiUrl } from "./lib/api.js";
|
|
14
|
+
const ENV_OPTION = [
|
|
15
|
+
"-e, --env <name>",
|
|
16
|
+
"Environment (lowercase, e.g. development or production)",
|
|
17
|
+
"development",
|
|
18
|
+
];
|
|
19
|
+
function withNormalizedEnv(fn) {
|
|
20
|
+
return (opts) => fn({ ...opts, env: normalizeEnvName(opts.env) });
|
|
21
|
+
}
|
|
22
|
+
export async function runCli(argv) {
|
|
23
|
+
const apiDefault = resolveApiUrl();
|
|
24
|
+
const program = new Command();
|
|
25
|
+
program
|
|
26
|
+
.name("getmyenv")
|
|
27
|
+
.description("Keep using environment variables. Stop managing them as files.")
|
|
28
|
+
.version("0.1.1");
|
|
29
|
+
program
|
|
30
|
+
.command("login")
|
|
31
|
+
.description("Save a dashboard CLI token (paste once; no shell env needed)")
|
|
32
|
+
.option("--api-url <url>", "API base URL to remember (default production)")
|
|
33
|
+
.action(loginCommand);
|
|
34
|
+
program
|
|
35
|
+
.command("logout")
|
|
36
|
+
.description("Clear the saved CLI token")
|
|
37
|
+
.action(logoutCommand);
|
|
38
|
+
program
|
|
39
|
+
.command("init")
|
|
40
|
+
.description("Detect expected environment variable names across languages (never collects values)")
|
|
41
|
+
.action(initCommand);
|
|
42
|
+
program
|
|
43
|
+
.command("migrate")
|
|
44
|
+
.description("Encrypt an .env* file locally and upload (searches this folder tree)")
|
|
45
|
+
.option(...ENV_OPTION)
|
|
46
|
+
.option("-f, --file <path>", "Path to .env file to migrate")
|
|
47
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
48
|
+
.option("--vault-password-stdin", "Read vault password from stdin (non-interactive)")
|
|
49
|
+
.action((opts) => migrateCommand({
|
|
50
|
+
...opts,
|
|
51
|
+
env: normalizeEnvName(opts.env),
|
|
52
|
+
envWasDefault: !process.argv.includes("-e") && !process.argv.includes("--env"),
|
|
53
|
+
}));
|
|
54
|
+
program
|
|
55
|
+
.command("add <name>")
|
|
56
|
+
.description("Add a secret via secure interactive input (never pass values on the CLI)")
|
|
57
|
+
.option(...ENV_OPTION)
|
|
58
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
59
|
+
.option("--vault-password-stdin", "Read vault password from stdin (non-interactive)")
|
|
60
|
+
.action((name, opts) => addCommand(name, { ...opts, env: normalizeEnvName(opts.env) }));
|
|
61
|
+
program
|
|
62
|
+
.command("status")
|
|
63
|
+
.description("Show secret status for the current project")
|
|
64
|
+
.option(...ENV_OPTION)
|
|
65
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
66
|
+
.action(withNormalizedEnv(statusCommand));
|
|
67
|
+
program
|
|
68
|
+
.command("export")
|
|
69
|
+
.description("Export secrets to a plaintext .env file")
|
|
70
|
+
.option(...ENV_OPTION)
|
|
71
|
+
.option("-o, --output <file>", "Output file", ".env")
|
|
72
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
73
|
+
.option("--vault-password-stdin", "Read vault password from stdin (non-interactive)")
|
|
74
|
+
.action(withNormalizedEnv(exportCommand));
|
|
75
|
+
program
|
|
76
|
+
.command("backup")
|
|
77
|
+
.description("Create a portable encrypted .getmyenv backup")
|
|
78
|
+
.option("-o, --output <file>", "Output file")
|
|
79
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
80
|
+
.action(backupCommand);
|
|
81
|
+
program
|
|
82
|
+
.command("restore <file>")
|
|
83
|
+
.description("Restore from an encrypted .getmyenv backup (creates a new project by default)")
|
|
84
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
85
|
+
.option("--into-linked", "Overwrite the project linked in the current directory")
|
|
86
|
+
.option("--vault-password-stdin", "Read vault password from stdin (non-interactive)")
|
|
87
|
+
.action(restoreCommand);
|
|
88
|
+
program
|
|
89
|
+
.command("run")
|
|
90
|
+
.description("Decrypt authorized secrets and run a command with the secrets available as environment variables")
|
|
91
|
+
.option(...ENV_OPTION)
|
|
92
|
+
.option("--api-url <url>", "API base URL", apiDefault)
|
|
93
|
+
.option("--vault-password-stdin", "Read vault password from stdin (non-interactive)")
|
|
94
|
+
.allowUnknownOption(true)
|
|
95
|
+
.allowExcessArguments(true)
|
|
96
|
+
.action(async (opts, cmd) => {
|
|
97
|
+
const args = cmd.args;
|
|
98
|
+
// Support: getmyenv run -- npm start
|
|
99
|
+
const dashIdx = process.argv.indexOf("--");
|
|
100
|
+
const childArgs = dashIdx >= 0 ? process.argv.slice(dashIdx + 1) : args;
|
|
101
|
+
await runCommand({ ...opts, env: normalizeEnvName(opts.env) }, childArgs);
|
|
102
|
+
});
|
|
103
|
+
await program.parseAsync(argv);
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAeA,KAAK,OAAO,GAAG;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE3E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { createWrappedProjectKey, encryptSecret, serializePayload, serializeWrappedKey, unwrapProjectKey, parseWrappedKey, } from "@getmyenv/crypto";
|
|
3
|
+
import { secretNameSchema } from "@getmyenv/shared";
|
|
4
|
+
import { promptHidden, readProjectMeta, writeProjectMeta } from "../lib/fs.js";
|
|
5
|
+
import { ApiClient, ensureSessionToken } from "../lib/api.js";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
export async function addCommand(name, opts) {
|
|
9
|
+
const parsed = secretNameSchema.safeParse(name);
|
|
10
|
+
if (!parsed.success) {
|
|
11
|
+
throw new Error("Invalid secret name. Use a valid environment variable name.");
|
|
12
|
+
}
|
|
13
|
+
// Reject accidental value-in-argv patterns
|
|
14
|
+
if (name.includes("=")) {
|
|
15
|
+
throw new Error('Do not pass secret values on the command line. Use: npx getmyenv add NAME');
|
|
16
|
+
}
|
|
17
|
+
console.log(pc.bold("\ngetmyenv add\n"));
|
|
18
|
+
console.log(`Secret: ${name}`);
|
|
19
|
+
console.log(`Environment: ${opts.env}\n`);
|
|
20
|
+
const value = await promptHidden("Secret value: ");
|
|
21
|
+
if (!value)
|
|
22
|
+
throw new Error("Value required");
|
|
23
|
+
const password = await promptHidden("Vault password: ", {
|
|
24
|
+
allowStdin: opts.vaultPasswordStdin,
|
|
25
|
+
});
|
|
26
|
+
const meta = readProjectMeta() ?? {};
|
|
27
|
+
const pendingPath = path.join(process.cwd(), ".getmyenv", "wrapped-key.json");
|
|
28
|
+
let pek;
|
|
29
|
+
let wrappedRaw;
|
|
30
|
+
if (fs.existsSync(pendingPath)) {
|
|
31
|
+
const wrapped = parseWrappedKey(fs.readFileSync(pendingPath, "utf8"));
|
|
32
|
+
pek = await unwrapProjectKey(password, wrapped);
|
|
33
|
+
wrappedRaw = serializeWrappedKey(wrapped);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const created = await createWrappedProjectKey(password);
|
|
37
|
+
pek = created.pek;
|
|
38
|
+
wrappedRaw = serializeWrappedKey(created.wrapped);
|
|
39
|
+
fs.mkdirSync(path.dirname(pendingPath), { recursive: true });
|
|
40
|
+
fs.writeFileSync(pendingPath, wrappedRaw, { mode: 0o600 });
|
|
41
|
+
}
|
|
42
|
+
const ciphertext = serializePayload(encryptSecret(pek, value));
|
|
43
|
+
const token = await ensureSessionToken();
|
|
44
|
+
const client = new ApiClient(opts.apiUrl, token);
|
|
45
|
+
if (!meta.projectId) {
|
|
46
|
+
const queue = path.join(process.cwd(), ".getmyenv", "pending-secrets.json");
|
|
47
|
+
const existing = fs.existsSync(queue)
|
|
48
|
+
? JSON.parse(fs.readFileSync(queue, "utf8"))
|
|
49
|
+
: [];
|
|
50
|
+
existing.push({ name, environment: opts.env, ciphertext });
|
|
51
|
+
fs.writeFileSync(queue, JSON.stringify(existing, null, 2), { mode: 0o600 });
|
|
52
|
+
writeProjectMeta({ ...meta, protectionMode: "advanced", apiUrl: opts.apiUrl });
|
|
53
|
+
console.log(`${pc.green("✓")} Encrypted locally and queued (link a project with migrate to sync)\n`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await client.request("POST", `/api/cli/projects/${meta.projectId}/secrets`, {
|
|
57
|
+
name,
|
|
58
|
+
environment: opts.env,
|
|
59
|
+
ciphertext,
|
|
60
|
+
wrappedProjectKey: JSON.parse(wrappedRaw),
|
|
61
|
+
});
|
|
62
|
+
console.log(`${pc.green("✓")} Added ${name}\n`);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"AAYA,KAAK,UAAU,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CnE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { createBackupEnvelope, parsePayload, parseWrappedKey, serializeBackup, } from "@getmyenv/crypto";
|
|
5
|
+
import { readProjectMeta } from "../lib/fs.js";
|
|
6
|
+
import { ApiClient, ensureSessionToken } from "../lib/api.js";
|
|
7
|
+
export async function backupCommand(opts) {
|
|
8
|
+
console.log(pc.bold("\ngetmyenv backup\n"));
|
|
9
|
+
const meta = readProjectMeta();
|
|
10
|
+
if (!meta?.projectId) {
|
|
11
|
+
throw new Error("Linked project required for backup. Run migrate first, then npx getmyenv login if needed.");
|
|
12
|
+
}
|
|
13
|
+
const token = await ensureSessionToken();
|
|
14
|
+
const client = new ApiClient(opts.apiUrl, token);
|
|
15
|
+
const data = await client.request("GET", `/api/cli/projects/${meta.projectId}/backup`);
|
|
16
|
+
const envelope = createBackupEnvelope({
|
|
17
|
+
projectName: data.projectName,
|
|
18
|
+
wrappedProjectKey: parseWrappedKey(JSON.stringify(data.wrappedProjectKey)),
|
|
19
|
+
secrets: data.secrets.map((s) => ({
|
|
20
|
+
name: s.name,
|
|
21
|
+
environment: s.environment,
|
|
22
|
+
status: s.status,
|
|
23
|
+
expiresAt: s.expiresAt,
|
|
24
|
+
payload: s.ciphertext != null && s.status !== "placeholder"
|
|
25
|
+
? parsePayload(s.ciphertext)
|
|
26
|
+
: null,
|
|
27
|
+
})),
|
|
28
|
+
});
|
|
29
|
+
const out = opts.output ??
|
|
30
|
+
path.join(process.cwd(), `${data.projectName.replace(/\s+/g, "-").toLowerCase()}.getmyenv`);
|
|
31
|
+
fs.writeFileSync(out, serializeBackup(envelope), { mode: 0o600 });
|
|
32
|
+
console.log(`${pc.green("✓")} Wrote encrypted backup: ${out}`);
|
|
33
|
+
console.log(pc.dim("Portable. No plaintext. Usable offline with your vault password.\n"));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAI9D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAgB;IAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAEzC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAU9B,KAAK,EAAE,qBAAqB,IAAI,CAAC,SAAS,SAAS,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,oBAAoB,CAAC;QACpC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,iBAAiB,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1E,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EACL,CAAC,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa;gBAChD,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC5B,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;KACJ,CAAC,CAAC;IAEH,MAAM,GAAG,GACP,IAAI,CAAC,MAAM;QACX,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC9F,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC,CAAC;AAC5F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAYA,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiEnE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { decryptSecret, parsePayload, parseWrappedKey, unwrapProjectKey, } from "@getmyenv/crypto";
|
|
4
|
+
import { EXPORT_WARNING } from "@getmyenv/shared";
|
|
5
|
+
import { promptHidden, readProjectMeta } from "../lib/fs.js";
|
|
6
|
+
import { ApiClient, ensureSessionToken } from "../lib/api.js";
|
|
7
|
+
export async function exportCommand(opts) {
|
|
8
|
+
console.log(pc.bold("\ngetmyenv export\n"));
|
|
9
|
+
console.log(pc.yellow(EXPORT_WARNING));
|
|
10
|
+
console.log("");
|
|
11
|
+
const meta = readProjectMeta();
|
|
12
|
+
if (!meta?.projectId) {
|
|
13
|
+
throw new Error("Linked project required for export. Run migrate first, then npx getmyenv login if needed.");
|
|
14
|
+
}
|
|
15
|
+
const token = await ensureSessionToken();
|
|
16
|
+
const password = await promptHidden("Vault password: ", {
|
|
17
|
+
allowStdin: opts.vaultPasswordStdin,
|
|
18
|
+
});
|
|
19
|
+
const client = new ApiClient(opts.apiUrl, token);
|
|
20
|
+
const data = await client.request("GET", `/api/cli/projects/${meta.projectId}/export?environment=${encodeURIComponent(opts.env)}`);
|
|
21
|
+
const pek = await unwrapProjectKey(password, parseWrappedKey(typeof data.wrappedProjectKey === "string"
|
|
22
|
+
? data.wrappedProjectKey
|
|
23
|
+
: JSON.stringify(data.wrappedProjectKey)));
|
|
24
|
+
const lines = [
|
|
25
|
+
"# Exported by getmyenv - PLAINTEXT SECRETS",
|
|
26
|
+
`# Environment: ${opts.env}`,
|
|
27
|
+
"# Do not commit this file.",
|
|
28
|
+
"",
|
|
29
|
+
];
|
|
30
|
+
for (const secret of data.secrets) {
|
|
31
|
+
if (secret.status === "revoked") {
|
|
32
|
+
lines.push("# revoked - getmyenv is not providing this");
|
|
33
|
+
}
|
|
34
|
+
if (secret.status === "placeholder" ||
|
|
35
|
+
secret.ciphertext == null ||
|
|
36
|
+
secret.ciphertext === "") {
|
|
37
|
+
lines.push(`# placeholder - no value yet`);
|
|
38
|
+
lines.push(`${secret.name}=`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const value = decryptSecret(pek, parsePayload(secret.ciphertext));
|
|
42
|
+
lines.push(`${secret.name}=${value}`);
|
|
43
|
+
}
|
|
44
|
+
fs.writeFileSync(opts.output, lines.join("\n") + "\n", { mode: 0o600 });
|
|
45
|
+
console.log(`${pc.green("✓")} Wrote ${opts.output}`);
|
|
46
|
+
console.log(pc.dim("Your secrets are yours. Protect this file.\n"));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAUA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyEjD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { detectEnvNames, detectLanguages, writeProjectMeta, writeRequirements, readProjectMeta, } from "../lib/fs.js";
|
|
3
|
+
import { ApiClient, ensureSessionToken, resolveApiUrl } from "../lib/api.js";
|
|
4
|
+
export async function initCommand() {
|
|
5
|
+
console.log(pc.bold("\ngetmyenv\n"));
|
|
6
|
+
const languages = detectLanguages();
|
|
7
|
+
const names = detectEnvNames();
|
|
8
|
+
const meta = readProjectMeta();
|
|
9
|
+
if (languages.length > 0) {
|
|
10
|
+
console.log(pc.green("✓") +
|
|
11
|
+
" Project detected: " +
|
|
12
|
+
languages.map((l) => l.label).join(", "));
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
console.log(pc.green("✓") + " Project detected");
|
|
16
|
+
}
|
|
17
|
+
console.log(pc.green("✓") + " Environment files scanned");
|
|
18
|
+
console.log("");
|
|
19
|
+
console.log(`Detected ${names.length} environment variables:\n`);
|
|
20
|
+
for (const name of names) {
|
|
21
|
+
console.log(` ${pc.green("✓")} ${name}`);
|
|
22
|
+
}
|
|
23
|
+
console.log("");
|
|
24
|
+
writeRequirements(names);
|
|
25
|
+
if (!meta) {
|
|
26
|
+
writeProjectMeta({
|
|
27
|
+
projectName: process.cwd().split(/[/\\]/).pop() ?? "project",
|
|
28
|
+
protectionMode: "advanced",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
console.log(pc.dim("Wrote .getmyenv/requirements.json (names only - no values collected)."));
|
|
32
|
+
const projectId = meta?.projectId ?? readProjectMeta()?.projectId;
|
|
33
|
+
if (projectId && names.length > 0) {
|
|
34
|
+
try {
|
|
35
|
+
const token = await ensureSessionToken();
|
|
36
|
+
const client = new ApiClient(resolveApiUrl(), token);
|
|
37
|
+
const result = await client.request("POST", `/api/cli/projects/${projectId}/secrets`, {
|
|
38
|
+
names,
|
|
39
|
+
environment: "development",
|
|
40
|
+
placeholder: true,
|
|
41
|
+
});
|
|
42
|
+
console.log(pc.green("✓") +
|
|
43
|
+
` Dashboard placeholders: ${result.created} new name(s) (both environments synced).`);
|
|
44
|
+
console.log(pc.dim("Fill values in the dashboard or with: npx getmyenv add NAME"));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.log(pc.yellow("!") +
|
|
48
|
+
" Could not push placeholders to the dashboard: " +
|
|
49
|
+
(err instanceof Error ? err.message : String(err)));
|
|
50
|
+
console.log(pc.dim("Local requirements were still saved."));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (names.length > 0) {
|
|
54
|
+
console.log(pc.dim("Link a project (migrate), then re-run init to create dashboard placeholders."));
|
|
55
|
+
}
|
|
56
|
+
console.log(pc.dim("Next: npx getmyenv migrate (or fill placeholders)\n"));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAcA,KAAK,SAAS,GAAG;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCjE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { listEnvFiles, promptConfirm, promptHidden, } from "../lib/fs.js";
|
|
3
|
+
import { credentialsFilePath, readCredentials, writeCredentials, } from "../lib/credentials.js";
|
|
4
|
+
import { resolveApiUrl } from "../lib/api.js";
|
|
5
|
+
import { runMigrateFromLogin } from "./migrate.js";
|
|
6
|
+
export async function loginCommand(opts) {
|
|
7
|
+
console.log(pc.bold("\ngetmyenv login\n"));
|
|
8
|
+
console.log(pc.dim("Create a token in the dashboard CLI page, then paste it here (hidden)."));
|
|
9
|
+
console.log("");
|
|
10
|
+
const token = (await promptHidden("Paste CLI token: ")).trim();
|
|
11
|
+
if (!token) {
|
|
12
|
+
throw new Error("No token entered.");
|
|
13
|
+
}
|
|
14
|
+
const apiUrl = opts.apiUrl?.trim() ||
|
|
15
|
+
process.env.GETMYENV_API_URL?.trim() ||
|
|
16
|
+
readCredentials()?.apiUrl;
|
|
17
|
+
const file = writeCredentials({
|
|
18
|
+
token,
|
|
19
|
+
apiUrl: apiUrl || undefined,
|
|
20
|
+
});
|
|
21
|
+
const effectiveApi = resolveApiUrl(opts.apiUrl);
|
|
22
|
+
console.log(`\n${pc.green("✓")} Saved to ${file}`);
|
|
23
|
+
console.log(pc.dim(`API: ${effectiveApi}`));
|
|
24
|
+
console.log(pc.dim(`File: ${credentialsFilePath()}\n`));
|
|
25
|
+
const candidates = listEnvFiles();
|
|
26
|
+
if (process.stdin.isTTY && candidates.length > 0) {
|
|
27
|
+
const run = await promptConfirm("Run migrate now?", { defaultYes: true });
|
|
28
|
+
if (run) {
|
|
29
|
+
await runMigrateFromLogin(opts.apiUrl);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
console.log("Next: npx getmyenv migrate or npx getmyenv run -- <cmd>\n");
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAMnD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAe;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CACJ,wEAAwE,CACzE,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,KAAK,GAAG,CAAC,MAAM,YAAY,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE;QACpC,eAAe,EAAE,EAAE,MAAM,CAAC;IAE5B,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC5B,KAAK;QACL,MAAM,EAAE,MAAM,IAAI,SAAS;KAC5B,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,YAAY,EAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,mBAAmB,EAAE,IAAI,CAAC,CAAC,CAAC;IAExD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;IAClC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAQnD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { clearCredentials, credentialsFilePath } from "../lib/credentials.js";
|
|
3
|
+
export async function logoutCommand() {
|
|
4
|
+
console.log(pc.bold("\ngetmyenv logout\n"));
|
|
5
|
+
const path = credentialsFilePath();
|
|
6
|
+
if (clearCredentials()) {
|
|
7
|
+
console.log(`${pc.green("✓")} Cleared credentials at ${path}\n`);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
console.log(pc.dim(`No credentials file at ${path}\n`));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACnC,IAAI,gBAAgB,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,IAAI,IAAI,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0BAA0B,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type MigrateOpts = {
|
|
2
|
+
env: string;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
file?: string;
|
|
5
|
+
vaultPasswordStdin?: boolean;
|
|
6
|
+
/** When true, caller already defaulted env to development (allow basename infer). */
|
|
7
|
+
envWasDefault?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function migrateCommand(opts: MigrateOpts): Promise<void>;
|
|
10
|
+
/** Shared entry for login → migrate offer. */
|
|
11
|
+
export declare function runMigrateFromLogin(apiUrl?: string): Promise<void>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAyBA,KAAK,WAAW,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAqCF,wBAAsB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmHrE;AAED,8CAA8C;AAC9C,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxE"}
|