getmyenv 0.5.3 → 0.6.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/README.md +57 -13
- package/dist/bin.js +1 -24
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +179 -106
- package/dist/cli.js.map +1 -1
- package/dist/commands/backup.d.ts +2 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +15 -19
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/claim.d.ts +2 -1
- package/dist/commands/claim.d.ts.map +1 -1
- package/dist/commands/claim.js +114 -80
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/context.d.ts +11 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +53 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +67 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/guest.d.ts +9 -3
- package/dist/commands/guest.d.ts.map +1 -1
- package/dist/commands/guest.js +32 -28
- package/dist/commands/guest.js.map +1 -1
- package/dist/commands/import.d.ts +26 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +168 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/lock.d.ts +5 -0
- package/dist/commands/lock.d.ts.map +1 -0
- package/dist/commands/lock.js +18 -0
- package/dist/commands/lock.js.map +1 -0
- package/dist/commands/ls.d.ts +6 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +37 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/restore.d.ts +7 -2
- package/dist/commands/restore.d.ts.map +1 -1
- package/dist/commands/restore.js +57 -49
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/run.d.ts +7 -5
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +98 -187
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/set.d.ts +16 -0
- package/dist/commands/set.d.ts.map +1 -0
- package/dist/commands/set.js +111 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/start.d.ts +16 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +118 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +40 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/unlink.d.ts +9 -0
- package/dist/commands/unlink.d.ts.map +1 -0
- package/dist/commands/unlink.js +70 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/lib/api-url.d.ts +12 -0
- package/dist/lib/api-url.d.ts.map +1 -1
- package/dist/lib/api-url.js +32 -0
- package/dist/lib/api-url.js.map +1 -1
- package/dist/lib/api.d.ts +35 -23
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +23 -59
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/authorize.d.ts +13 -6
- package/dist/lib/authorize.d.ts.map +1 -1
- package/dist/lib/authorize.js +68 -61
- package/dist/lib/authorize.js.map +1 -1
- package/dist/lib/bootstrap.d.ts +18 -15
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +59 -69
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/confirm.js +4 -4
- package/dist/lib/confirm.js.map +1 -1
- package/dist/lib/context.d.ts +12 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/context.js +43 -0
- package/dist/lib/context.js.map +1 -0
- package/dist/lib/credentials.d.ts +8 -13
- package/dist/lib/credentials.d.ts.map +1 -1
- package/dist/lib/credentials.js +2 -9
- package/dist/lib/credentials.js.map +1 -1
- package/dist/lib/fs.d.ts +26 -40
- package/dist/lib/fs.d.ts.map +1 -1
- package/dist/lib/fs.js +112 -326
- package/dist/lib/fs.js.map +1 -1
- package/dist/lib/guest-key.d.ts +2 -5
- package/dist/lib/guest-key.d.ts.map +1 -1
- package/dist/lib/guest-key.js +9 -2
- package/dist/lib/guest-key.js.map +1 -1
- package/dist/lib/identity.d.ts +9 -11
- package/dist/lib/identity.d.ts.map +1 -1
- package/dist/lib/identity.js +34 -24
- package/dist/lib/identity.js.map +1 -1
- package/dist/lib/keychain.d.ts +21 -0
- package/dist/lib/keychain.d.ts.map +1 -0
- package/dist/lib/keychain.js +124 -0
- package/dist/lib/keychain.js.map +1 -0
- package/dist/lib/pek.d.ts +15 -24
- package/dist/lib/pek.d.ts.map +1 -1
- package/dist/lib/pek.js +30 -54
- package/dist/lib/pek.js.map +1 -1
- package/dist/lib/run-env.d.ts +50 -0
- package/dist/lib/run-env.d.ts.map +1 -0
- package/dist/lib/run-env.js +114 -0
- package/dist/lib/run-env.js.map +1 -0
- package/dist/lib/unlock.d.ts +24 -0
- package/dist/lib/unlock.d.ts.map +1 -0
- package/dist/lib/unlock.js +87 -0
- package/dist/lib/unlock.js.map +1 -0
- package/dist/lib/update-check.d.ts +4 -2
- package/dist/lib/update-check.d.ts.map +1 -1
- package/dist/lib/update-check.js +54 -68
- package/dist/lib/update-check.js.map +1 -1
- package/dist/lib/upload.d.ts +21 -0
- package/dist/lib/upload.d.ts.map +1 -0
- package/dist/lib/upload.js +53 -0
- package/dist/lib/upload.js.map +1 -0
- package/package.json +5 -3
- package/dist/commands/delete.d.ts +0 -6
- package/dist/commands/delete.d.ts.map +0 -1
- package/dist/commands/delete.js +0 -55
- package/dist/commands/delete.js.map +0 -1
- package/dist/commands/link.d.ts +0 -16
- package/dist/commands/link.d.ts.map +0 -1
- package/dist/commands/link.js +0 -142
- package/dist/commands/link.js.map +0 -1
- package/dist/commands/pull.d.ts +0 -15
- package/dist/commands/pull.d.ts.map +0 -1
- package/dist/commands/pull.js +0 -155
- package/dist/commands/pull.js.map +0 -1
- package/dist/commands/push.d.ts +0 -15
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -261
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/remove.d.ts +0 -11
- package/dist/commands/remove.d.ts.map +0 -1
- package/dist/commands/remove.js +0 -39
- package/dist/commands/remove.js.map +0 -1
- package/dist/commands/token.d.ts +0 -14
- package/dist/commands/token.d.ts.map +0 -1
- package/dist/commands/token.js +0 -132
- package/dist/commands/token.js.map +0 -1
- package/dist/commands/whoami.d.ts +0 -6
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js +0 -46
- package/dist/commands/whoami.js.map +0 -1
- package/dist/lib/env-name.d.ts +0 -3
- package/dist/lib/env-name.d.ts.map +0 -1
- package/dist/lib/env-name.js +0 -5
- package/dist/lib/env-name.js.map +0 -1
- package/dist/lib/guest-key.test.d.ts +0 -2
- package/dist/lib/guest-key.test.d.ts.map +0 -1
- package/dist/lib/guest-key.test.js.map +0 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { DEFAULT_CONTEXT_SLUG } from "@getmyenv/shared";
|
|
5
|
+
import { promptChoice, promptConfirm, readClaimFile, readLine, readProjectMeta, rootEnvFiles, writeProjectMeta, } from "../lib/fs.js";
|
|
6
|
+
import { ApiClient, getSessionToken, resolveApiUrl } from "../lib/api.js";
|
|
7
|
+
import { authorizeFolder } from "../lib/authorize.js";
|
|
8
|
+
import { NOT_LINKED_STEPS } from "../lib/bootstrap.js";
|
|
9
|
+
import { createGuestProject, folderNameHint } from "./guest.js";
|
|
10
|
+
import { statusCommand } from "./status.js";
|
|
11
|
+
/** Best guess at the app's start command, for the printed `run` line. */
|
|
12
|
+
export function suggestedStartCommand(cwd = process.cwd()) {
|
|
13
|
+
const pkgFile = path.join(cwd, "package.json");
|
|
14
|
+
if (fs.existsSync(pkgFile)) {
|
|
15
|
+
try {
|
|
16
|
+
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf8"));
|
|
17
|
+
if (pkg.scripts?.dev)
|
|
18
|
+
return "npm run dev";
|
|
19
|
+
if (pkg.scripts?.start)
|
|
20
|
+
return "npm start";
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
/* ignore */
|
|
24
|
+
}
|
|
25
|
+
return "node index.js";
|
|
26
|
+
}
|
|
27
|
+
if (fs.existsSync(path.join(cwd, "manage.py")))
|
|
28
|
+
return "python manage.py runserver";
|
|
29
|
+
if (fs.existsSync(path.join(cwd, "go.mod")))
|
|
30
|
+
return "go run .";
|
|
31
|
+
if (fs.existsSync(path.join(cwd, "Cargo.toml")))
|
|
32
|
+
return "cargo run";
|
|
33
|
+
return "<your start command>";
|
|
34
|
+
}
|
|
35
|
+
export function runLine(context, cwd = process.cwd()) {
|
|
36
|
+
const ctx = context && context !== DEFAULT_CONTEXT_SLUG ? ` ${context}` : "";
|
|
37
|
+
return `npx getmyenv run${ctx} -- ${suggestedStartCommand(cwd)}`;
|
|
38
|
+
}
|
|
39
|
+
async function nameFirstContext(apiUrl) {
|
|
40
|
+
const answer = (await readLine(`Name your first context ${pc.dim("[Development]")}: `)).trim();
|
|
41
|
+
if (!answer || answer.toLowerCase() === "development")
|
|
42
|
+
return DEFAULT_CONTEXT_SLUG;
|
|
43
|
+
const token = getSessionToken();
|
|
44
|
+
const created = await new ApiClient(apiUrl, token).request("POST", "/api/cli/contexts", { name: answer });
|
|
45
|
+
console.error(`${pc.green("✓")} Context ${pc.bold(created.name)} (${created.slug})`);
|
|
46
|
+
return created.slug;
|
|
47
|
+
}
|
|
48
|
+
/** A project that already has keys or its own contexts is set up. Do not ask for a first context. */
|
|
49
|
+
function isFreshProject(who) {
|
|
50
|
+
if (who.keys.length > 0)
|
|
51
|
+
return false;
|
|
52
|
+
return who.contexts.every((c) => c.slug === DEFAULT_CONTEXT_SLUG || c.protection === "locked");
|
|
53
|
+
}
|
|
54
|
+
function defaultContextFor(who) {
|
|
55
|
+
const open = who.contexts.filter((c) => c.protection === "open");
|
|
56
|
+
return (open.find((c) => c.slug === DEFAULT_CONTEXT_SLUG) ?? open[0])?.slug ?? DEFAULT_CONTEXT_SLUG;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Guided setup for an unlinked folder, in a terminal.
|
|
60
|
+
* Start without an account, or sign in. Then offer to import a detected .env.
|
|
61
|
+
*/
|
|
62
|
+
export async function startSetup(opts) {
|
|
63
|
+
console.error(pc.bold("\ngetmyenv"));
|
|
64
|
+
console.error(pc.dim("Keep using environment variables. Stop managing them as files.\n"));
|
|
65
|
+
const apiUrl = resolveApiUrl(opts.apiUrl);
|
|
66
|
+
const existing = readProjectMeta();
|
|
67
|
+
if (readClaimFile()) {
|
|
68
|
+
throw new Error("This folder has a guest project (claim.json) but no token on this machine. Claim it: npx getmyenv claim");
|
|
69
|
+
}
|
|
70
|
+
if (existing?.projectId) {
|
|
71
|
+
console.error(`This folder uses ${pc.bold(existing.projectName ?? existing.projectId)}. Sign in to get a token.\n`);
|
|
72
|
+
await authorizeFolder({ apiUrl });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const choice = await promptChoice("How do you want to start?", ["Start without an account (guest project, claim within 60 days)", "Sign in"], 0);
|
|
76
|
+
console.error("");
|
|
77
|
+
let context = DEFAULT_CONTEXT_SLUG;
|
|
78
|
+
if (choice === 0) {
|
|
79
|
+
const name = (await readLine(`Project name ${pc.dim(`[${folderNameHint()}]`)}: `)).trim() ||
|
|
80
|
+
folderNameHint();
|
|
81
|
+
await createGuestProject({ name, apiUrl });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const who = await authorizeFolder({ apiUrl });
|
|
85
|
+
context = isFreshProject(who) ? await nameFirstContext(apiUrl) : defaultContextFor(who);
|
|
86
|
+
const meta = readProjectMeta();
|
|
87
|
+
if (meta)
|
|
88
|
+
writeProjectMeta({ ...meta, context });
|
|
89
|
+
}
|
|
90
|
+
const files = rootEnvFiles();
|
|
91
|
+
if (files.length > 0) {
|
|
92
|
+
const rel = files.map((f) => path.basename(f)).join(", ");
|
|
93
|
+
const ok = await promptConfirm(`Import ${rel}? Values are encrypted before upload.`, {
|
|
94
|
+
defaultYes: true,
|
|
95
|
+
});
|
|
96
|
+
if (ok) {
|
|
97
|
+
const { importCommand } = await import("./import.js");
|
|
98
|
+
await importCommand(undefined, { apiUrl, yes: true });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!opts.thenContinue) {
|
|
102
|
+
console.error("Start your app with:\n");
|
|
103
|
+
console.error(pc.cyan(` ${runLine(context)}\n`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Bare `getmyenv`: setup when unlinked (terminal only), status when linked. */
|
|
107
|
+
export async function startCommand(opts) {
|
|
108
|
+
if (getSessionToken()) {
|
|
109
|
+
await statusCommand(opts);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!process.stdin.isTTY) {
|
|
113
|
+
console.log(NOT_LINKED_STEPS);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
await startSetup({ apiUrl: opts.apiUrl });
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAYA,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BjF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { isDefaultApiUrl } from "../lib/api.js";
|
|
3
|
+
import { ensureTokenAndLink } from "../lib/bootstrap.js";
|
|
4
|
+
import { defaultContextSlug } from "../lib/context.js";
|
|
5
|
+
import { runLine } from "./start.js";
|
|
6
|
+
const TOKEN_KIND = {
|
|
7
|
+
folder: "folder (open contexts, read and write)",
|
|
8
|
+
guest: "guest (Development, read and write)",
|
|
9
|
+
server: "server (one locked context, read-only)",
|
|
10
|
+
};
|
|
11
|
+
/** Project, token, contexts with value counts, and the run command. Names only. */
|
|
12
|
+
export async function statusCommand(opts = {}) {
|
|
13
|
+
const { who, apiUrl, meta } = await ensureTokenAndLink({ apiUrl: opts.apiUrl });
|
|
14
|
+
const current = defaultContextSlug(who, meta);
|
|
15
|
+
console.log(`${pc.bold(who.project.name)}${who.user ? pc.dim(` ${who.user.email}`) : ""}`);
|
|
16
|
+
console.log(pc.dim(`Token: ${TOKEN_KIND[who.token.kind] ?? who.token.kind}`));
|
|
17
|
+
if (process.env.GETMYENV_TOKEN?.trim())
|
|
18
|
+
console.log(pc.dim("Source: GETMYENV_TOKEN"));
|
|
19
|
+
if (!isDefaultApiUrl(apiUrl))
|
|
20
|
+
console.log(pc.dim(`API: ${apiUrl}`));
|
|
21
|
+
console.log("");
|
|
22
|
+
const total = who.keys.length;
|
|
23
|
+
const width = Math.max(...who.contexts.map((c) => c.slug.length), 4);
|
|
24
|
+
console.log(`Contexts (${total} variable${total === 1 ? "" : "s"}):`);
|
|
25
|
+
for (const c of who.contexts) {
|
|
26
|
+
const set = who.keys.filter((k) => {
|
|
27
|
+
const s = k.status[c.slug];
|
|
28
|
+
return s === "set" || s === "expiring_soon";
|
|
29
|
+
}).length;
|
|
30
|
+
const marker = c.slug === current ? pc.green("*") : " ";
|
|
31
|
+
const lock = c.protection === "locked" ? pc.yellow(" locked") : "";
|
|
32
|
+
const name = c.name.toLowerCase() === c.slug ? "" : pc.dim(` ${c.name}`);
|
|
33
|
+
console.log(` ${marker} ${c.slug.padEnd(width)} ${set}/${total} set${lock}${name}`);
|
|
34
|
+
}
|
|
35
|
+
console.log("");
|
|
36
|
+
console.log("Run your app:");
|
|
37
|
+
console.log(pc.cyan(` ${runLine(current)}`));
|
|
38
|
+
console.log("");
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,UAAU,GAA2B;IACzC,MAAM,EAAE,wCAAwC;IAChD,KAAK,EAAE,qCAAqC;IAC5C,MAAM,EAAE,wCAAwC;CACjD,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA4B,EAAE;IAChE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAE9C,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE;QAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,eAAe,CAAC;QAC9C,CAAC,CAAC,CAAC,MAAM,CAAC;QACV,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACxD,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,OAAO,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unlink this folder: revoke its token and remove local getmyenv files.
|
|
3
|
+
* The project, its contexts and values stay.
|
|
4
|
+
*/
|
|
5
|
+
export declare function unlinkCommand(opts: {
|
|
6
|
+
apiUrl?: string;
|
|
7
|
+
yes?: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=unlink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlink.d.ts","sourceRoot":"","sources":["../../src/commands/unlink.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D3F"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { getGetenvDir, promptConfirm, readClaimFile, readProjectMeta } from "../lib/fs.js";
|
|
5
|
+
import { clearFolderToken, readFolderToken } from "../lib/credentials.js";
|
|
6
|
+
import { clearCachedKey } from "../lib/pek.js";
|
|
7
|
+
import { clearCachedPek, keychainAccount } from "../lib/keychain.js";
|
|
8
|
+
import { ApiClient, ApiError, resolveApiUrl } from "../lib/api.js";
|
|
9
|
+
/**
|
|
10
|
+
* Unlink this folder: revoke its token and remove local getmyenv files.
|
|
11
|
+
* The project, its contexts and values stay.
|
|
12
|
+
*/
|
|
13
|
+
export async function unlinkCommand(opts) {
|
|
14
|
+
const meta = readProjectMeta();
|
|
15
|
+
const folder = readFolderToken();
|
|
16
|
+
const projectFile = path.join(getGetenvDir(), "project.json");
|
|
17
|
+
if (!folder && !meta?.projectId && !fs.existsSync(projectFile)) {
|
|
18
|
+
console.log(pc.dim("This folder is not linked."));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!opts.yes && !process.stdin.isTTY) {
|
|
22
|
+
throw new Error("Unlink revokes this folder's token. Without a terminal, pass --yes.");
|
|
23
|
+
}
|
|
24
|
+
if (!opts.yes) {
|
|
25
|
+
const label = meta?.projectName ?? meta?.projectId ?? "this folder";
|
|
26
|
+
const ok = await promptConfirm(`Unlink ${label}? Revokes this folder's token and removes .getmyenv files. The project and its values stay.`, { defaultYes: false });
|
|
27
|
+
if (!ok) {
|
|
28
|
+
console.log(pc.dim("Kept."));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (folder) {
|
|
33
|
+
try {
|
|
34
|
+
await new ApiClient(resolveApiUrl(opts.apiUrl), folder.token).request("DELETE", "/api/cli/token");
|
|
35
|
+
console.log(`${pc.green("✓")} Token revoked`);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
// 401/404: the token is already gone on the server. Anything else keeps
|
|
39
|
+
// token.json, so a still-valid token is never left without a local copy.
|
|
40
|
+
if (!(err instanceof ApiError && (err.status === 401 || err.status === 404))) {
|
|
41
|
+
throw new Error("Could not revoke the token on the server. Nothing was removed. Try again, or revoke it on the CLI page first.");
|
|
42
|
+
}
|
|
43
|
+
console.log(pc.dim("Token was already revoked."));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const projectId = meta?.projectId ?? folder?.projectId;
|
|
47
|
+
if (projectId && (await clearCachedPek(keychainAccount(resolveApiUrl(opts.apiUrl), projectId)))) {
|
|
48
|
+
console.log(`${pc.green("✓")} Removed the unlocked key from the OS keychain`);
|
|
49
|
+
}
|
|
50
|
+
if (clearFolderToken())
|
|
51
|
+
console.log(`${pc.green("✓")} Removed token.json`);
|
|
52
|
+
if (clearCachedKey())
|
|
53
|
+
console.log(`${pc.green("✓")} Removed key.json`);
|
|
54
|
+
if (fs.existsSync(projectFile)) {
|
|
55
|
+
fs.unlinkSync(projectFile);
|
|
56
|
+
console.log(`${pc.green("✓")} Removed project.json`);
|
|
57
|
+
}
|
|
58
|
+
if (readClaimFile()) {
|
|
59
|
+
console.log(pc.yellow("Kept claim.json. It is the only way to claim this guest project. Delete it if you do not need the project."));
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const dir = getGetenvDir();
|
|
63
|
+
if (fs.readdirSync(dir).length === 0)
|
|
64
|
+
fs.rmdirSync(dir);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* ignore */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=unlink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlink.js","sourceRoot":"","sources":["../../src/commands/unlink.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/api-url.d.ts
CHANGED
|
@@ -5,4 +5,16 @@ export declare function normalizeApiBase(url: string): string;
|
|
|
5
5
|
export declare function isDefaultApiUrl(url: string | undefined | null): boolean;
|
|
6
6
|
/** Persist only when different from production. */
|
|
7
7
|
export declare function apiUrlForDisk(url: string | undefined | null): string | undefined;
|
|
8
|
+
export declare function isLocalHost(hostname: string): boolean;
|
|
9
|
+
/** https anywhere, http only for localhost. Returns the parsed URL or null. */
|
|
10
|
+
export declare function parseSafeUrl(raw: string): URL | null;
|
|
11
|
+
/**
|
|
12
|
+
* Pick the API base: --api-url, then GETMYENV_API_URL, then the gitignored
|
|
13
|
+
* token.json, then production. project.json is committed, so it is never read.
|
|
14
|
+
*/
|
|
15
|
+
export declare function pickApiUrl(sources: {
|
|
16
|
+
override?: string;
|
|
17
|
+
env?: string;
|
|
18
|
+
tokenFile?: string;
|
|
19
|
+
}): string;
|
|
8
20
|
//# sourceMappingURL=api-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-url.d.ts","sourceRoot":"","sources":["../../src/lib/api-url.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAGvE;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAC7B,MAAM,GAAG,SAAS,CAGpB"}
|
|
1
|
+
{"version":3,"file":"api-url.d.ts","sourceRoot":"","sources":["../../src/lib/api-url.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,eAAO,MAAM,cAAc,yBAAyB,CAAC;AAErD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAGvE;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAC7B,MAAM,GAAG,SAAS,CAGpB;AAID,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAWpD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAOT"}
|
package/dist/lib/api-url.js
CHANGED
|
@@ -15,4 +15,36 @@ export function apiUrlForDisk(url) {
|
|
|
15
15
|
return undefined;
|
|
16
16
|
return normalizeApiBase(url);
|
|
17
17
|
}
|
|
18
|
+
const LOCAL_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
19
|
+
export function isLocalHost(hostname) {
|
|
20
|
+
return LOCAL_HOSTS.has(hostname.toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
/** https anywhere, http only for localhost. Returns the parsed URL or null. */
|
|
23
|
+
export function parseSafeUrl(raw) {
|
|
24
|
+
let url;
|
|
25
|
+
try {
|
|
26
|
+
url = new URL(raw.trim());
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
if (url.username || url.password)
|
|
32
|
+
return null;
|
|
33
|
+
if (url.protocol === "https:")
|
|
34
|
+
return url;
|
|
35
|
+
if (url.protocol === "http:" && isLocalHost(url.hostname))
|
|
36
|
+
return url;
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Pick the API base: --api-url, then GETMYENV_API_URL, then the gitignored
|
|
41
|
+
* token.json, then production. project.json is committed, so it is never read.
|
|
42
|
+
*/
|
|
43
|
+
export function pickApiUrl(sources) {
|
|
44
|
+
const raw = sources.override?.trim() || sources.env?.trim() || sources.tokenFile?.trim() || PRODUCTION_API;
|
|
45
|
+
if (!parseSafeUrl(raw)) {
|
|
46
|
+
throw new Error(`Refusing API URL ${raw}. Use https, or http://localhost for local development.`);
|
|
47
|
+
}
|
|
48
|
+
return normalizeApiBase(raw);
|
|
49
|
+
}
|
|
18
50
|
//# sourceMappingURL=api-url.js.map
|
package/dist/lib/api-url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-url.js","sourceRoot":"","sources":["../../src/lib/api-url.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAErD,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,GAA8B;IAC5D,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,cAAc,CAAC;AAClD,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,aAAa,CAC3B,GAA8B;IAE9B,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"api-url.js","sourceRoot":"","sources":["../../src/lib/api-url.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAErD,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAAC,GAA8B;IAC5D,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,cAAc,CAAC;AAClD,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,aAAa,CAC3B,GAA8B;IAE9B,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAEjE,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAC1C,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,GAAG,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAI1B;IACC,MAAM,GAAG,GACP,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC;IACjG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,yDAAyD,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC"}
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -1,26 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI API client. Never
|
|
3
|
-
* beyond what is needed; never prints secret plaintext.
|
|
2
|
+
* CLI API client. Never prints plaintext values.
|
|
4
3
|
*/
|
|
5
|
-
import { type CliScope } from "./credentials.js";
|
|
6
4
|
/** Keep in sync with packages/cli/package.json version. */
|
|
7
|
-
export declare const CLI_VERSION = "0.
|
|
8
|
-
export { PRODUCTION_API, isDefaultApiUrl, apiUrlForDisk, normalizeApiBase } from "./api-url.js";
|
|
5
|
+
export declare const CLI_VERSION = "0.6.0";
|
|
6
|
+
export { PRODUCTION_API, isDefaultApiUrl, apiUrlForDisk, normalizeApiBase, parseSafeUrl, } from "./api-url.js";
|
|
7
|
+
export type Protection = "open" | "locked";
|
|
8
|
+
export type ValueStatus = "set" | "expiring_soon" | "expired" | "missing";
|
|
9
|
+
export type ContextInfo = {
|
|
10
|
+
id: number;
|
|
11
|
+
slug: string;
|
|
12
|
+
name: string;
|
|
13
|
+
protection: Protection;
|
|
14
|
+
};
|
|
9
15
|
export type WhoamiResponse = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
project: {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
hasKey: boolean;
|
|
20
|
+
};
|
|
21
|
+
token: {
|
|
22
|
+
kind: "folder" | "guest" | "server";
|
|
23
|
+
label: string | null;
|
|
24
|
+
/** Server tokens: the one locked context they read. */
|
|
25
|
+
context: string | null;
|
|
26
|
+
allowedCidrs: string[];
|
|
27
|
+
};
|
|
28
|
+
user: {
|
|
29
|
+
email: string;
|
|
30
|
+
} | null;
|
|
31
|
+
isGuest: boolean;
|
|
32
|
+
guestExpiresAt: string | null;
|
|
33
|
+
contexts: ContextInfo[];
|
|
34
|
+
keys: Array<{
|
|
35
|
+
name: string;
|
|
36
|
+
status: Record<string, ValueStatus>;
|
|
37
|
+
}>;
|
|
17
38
|
};
|
|
18
39
|
export declare class ApiError extends Error {
|
|
19
40
|
status: number;
|
|
20
41
|
constructor(message: string, status: number);
|
|
21
42
|
}
|
|
22
|
-
|
|
23
|
-
export declare function resolveApiUrl(cliOverride?: string, _hint?: unknown): string;
|
|
43
|
+
export declare function resolveApiUrl(cliOverride?: string): string;
|
|
24
44
|
export declare class ApiClient {
|
|
25
45
|
private baseUrl;
|
|
26
46
|
private token?;
|
|
@@ -28,14 +48,6 @@ export declare class ApiClient {
|
|
|
28
48
|
private headers;
|
|
29
49
|
request<T>(method: string, path: string, body?: unknown, extraHeaders?: Record<string, string>): Promise<T>;
|
|
30
50
|
}
|
|
31
|
-
/** Env / folder token only
|
|
51
|
+
/** Env / folder token only, no prompt. */
|
|
32
52
|
export declare function getSessionToken(): string | undefined;
|
|
33
|
-
/** True when the folder is already authorized (env or .getmyenv/token.json). */
|
|
34
|
-
export declare function hasSessionToken(): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Env → folder token. When missing, TTY runs the browser auth flow
|
|
37
|
-
* and writes `.getmyenv/token.json`. Non-TTY throws (use GETMYENV_TOKEN).
|
|
38
|
-
*/
|
|
39
|
-
export declare function ensureSessionToken(_hint?: unknown): Promise<string>;
|
|
40
|
-
export { readFolderToken, writeFolderToken, tokenFilePath, } from "./credentials.js";
|
|
41
53
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/lib/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,2DAA2D;AAC3D,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,eAAe,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IACvD,KAAK,EAAE;QACL,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;QACpC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,uDAAuD;QACvD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAEF,qBAAa,QAAS,SAAQ,KAAK;IACjC,MAAM,EAAE,MAAM,CAAC;gBACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED,wBAAgB,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,qBAAa,SAAS;IAElB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK,CAAC;gBADN,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,YAAA;IAGxB,OAAO,CAAC,OAAO;IAWT,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,CAAC,CAAC;CAwBd;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAIpD"}
|
package/dist/lib/api.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI API client. Never
|
|
3
|
-
* beyond what is needed; never prints secret plaintext.
|
|
2
|
+
* CLI API client. Never prints plaintext values.
|
|
4
3
|
*/
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { readFolderToken, } from "./credentials.js";
|
|
8
|
-
import { PRODUCTION_API } from "./api-url.js";
|
|
4
|
+
import { readFolderToken } from "./credentials.js";
|
|
5
|
+
import { pickApiUrl } from "./api-url.js";
|
|
9
6
|
/** Keep in sync with packages/cli/package.json version. */
|
|
10
|
-
export const CLI_VERSION = "0.
|
|
11
|
-
export { PRODUCTION_API, isDefaultApiUrl, apiUrlForDisk, normalizeApiBase } from "./api-url.js";
|
|
7
|
+
export const CLI_VERSION = "0.6.0";
|
|
8
|
+
export { PRODUCTION_API, isDefaultApiUrl, apiUrlForDisk, normalizeApiBase, parseSafeUrl, } from "./api-url.js";
|
|
12
9
|
export class ApiError extends Error {
|
|
13
10
|
status;
|
|
14
11
|
constructor(message, status) {
|
|
@@ -17,20 +14,12 @@ export class ApiError extends Error {
|
|
|
17
14
|
this.status = status;
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
const token = readFolderToken();
|
|
28
|
-
if (token?.apiUrl)
|
|
29
|
-
return token.apiUrl;
|
|
30
|
-
const meta = readProjectMeta();
|
|
31
|
-
if (meta?.apiUrl)
|
|
32
|
-
return meta.apiUrl;
|
|
33
|
-
return PRODUCTION_API;
|
|
17
|
+
export function resolveApiUrl(cliOverride) {
|
|
18
|
+
return pickApiUrl({
|
|
19
|
+
override: cliOverride,
|
|
20
|
+
env: process.env.GETMYENV_API_URL,
|
|
21
|
+
tokenFile: readFolderToken()?.apiUrl,
|
|
22
|
+
});
|
|
34
23
|
}
|
|
35
24
|
export class ApiClient {
|
|
36
25
|
baseUrl;
|
|
@@ -51,11 +40,17 @@ export class ApiClient {
|
|
|
51
40
|
return h;
|
|
52
41
|
}
|
|
53
42
|
async request(method, path, body, extraHeaders) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
let res;
|
|
44
|
+
try {
|
|
45
|
+
res = await fetch(`${this.baseUrl.replace(/\/$/, "")}${path}`, {
|
|
46
|
+
method,
|
|
47
|
+
headers: this.headers(extraHeaders),
|
|
48
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
throw new ApiError(`Could not reach ${this.baseUrl}`, 0);
|
|
53
|
+
}
|
|
59
54
|
if (!res.ok) {
|
|
60
55
|
let message = `HTTP ${res.status}`;
|
|
61
56
|
try {
|
|
@@ -73,42 +68,11 @@ export class ApiClient {
|
|
|
73
68
|
return (await res.json());
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
|
-
/** Env / folder token only
|
|
71
|
+
/** Env / folder token only, no prompt. */
|
|
77
72
|
export function getSessionToken() {
|
|
78
73
|
const env = process.env.GETMYENV_TOKEN?.trim();
|
|
79
74
|
if (env)
|
|
80
75
|
return env;
|
|
81
76
|
return readFolderToken()?.token;
|
|
82
77
|
}
|
|
83
|
-
/** True when the folder is already authorized (env or .getmyenv/token.json). */
|
|
84
|
-
export function hasSessionToken() {
|
|
85
|
-
return !!getSessionToken();
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Env → folder token. When missing, TTY runs the browser auth flow
|
|
89
|
-
* and writes `.getmyenv/token.json`. Non-TTY throws (use GETMYENV_TOKEN).
|
|
90
|
-
*/
|
|
91
|
-
export async function ensureSessionToken(_hint) {
|
|
92
|
-
const env = process.env.GETMYENV_TOKEN?.trim();
|
|
93
|
-
if (env)
|
|
94
|
-
return env;
|
|
95
|
-
const existing = readFolderToken();
|
|
96
|
-
if (existing)
|
|
97
|
-
return existing.token;
|
|
98
|
-
if (!process.stdin.isTTY) {
|
|
99
|
-
throw new Error("No CLI token in this folder. Set GETMYENV_TOKEN for CI, or run in a TTY.");
|
|
100
|
-
}
|
|
101
|
-
// Lazy import to avoid a cycle (authorize ↔ api).
|
|
102
|
-
const { authorizeFolder } = await import("./authorize.js");
|
|
103
|
-
await authorizeFolder();
|
|
104
|
-
const after = readFolderToken();
|
|
105
|
-
if (!after) {
|
|
106
|
-
throw new Error("Authorization did not complete. Re-run this command, or set GETMYENV_TOKEN for CI.");
|
|
107
|
-
}
|
|
108
|
-
return after.token;
|
|
109
|
-
}
|
|
110
|
-
export { readFolderToken, writeFolderToken, tokenFilePath, } from "./credentials.js";
|
|
111
|
-
// picocolors is referenced by callers; re-export nothing here.
|
|
112
|
-
void pc;
|
|
113
|
-
void {};
|
|
114
78
|
//# sourceMappingURL=api.js.map
|
package/dist/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/authorize.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { type WhoamiResponse } from "./api.js";
|
|
2
|
+
/** Command + argv to open a URL. No shell, so the URL is never parsed as a command. */
|
|
3
|
+
export declare function browserCommand(raw: string, platform?: NodeJS.Platform): {
|
|
4
|
+
cmd: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
} | null;
|
|
7
|
+
export declare function openBrowser(url: string): void;
|
|
8
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
10
|
+
* Sign in via the browser and link this folder (writes token.json + project.json).
|
|
11
|
+
* CI uses GETMYENV_TOKEN instead.
|
|
7
12
|
*/
|
|
8
|
-
export declare function authorizeFolder(opts?:
|
|
13
|
+
export declare function authorizeFolder(opts?: {
|
|
14
|
+
apiUrl?: string;
|
|
15
|
+
}): Promise<WhoamiResponse>;
|
|
9
16
|
//# sourceMappingURL=authorize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/lib/authorize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/lib/authorize.ts"],"names":[],"mappings":"AASA,OAAO,EAA0C,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvF,uFAAuF;AACvF,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CASxC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAc7C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AA6GD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,OAAO,CAAC,cAAc,CAAC,CAOzB"}
|