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.
Files changed (161) hide show
  1. package/README.md +57 -13
  2. package/dist/bin.js +1 -24
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.d.ts +10 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +179 -106
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/backup.d.ts +2 -1
  9. package/dist/commands/backup.d.ts.map +1 -1
  10. package/dist/commands/backup.js +15 -19
  11. package/dist/commands/backup.js.map +1 -1
  12. package/dist/commands/claim.d.ts +2 -1
  13. package/dist/commands/claim.d.ts.map +1 -1
  14. package/dist/commands/claim.js +114 -80
  15. package/dist/commands/claim.js.map +1 -1
  16. package/dist/commands/context.d.ts +11 -0
  17. package/dist/commands/context.d.ts.map +1 -0
  18. package/dist/commands/context.js +53 -0
  19. package/dist/commands/context.js.map +1 -0
  20. package/dist/commands/export.d.ts +11 -0
  21. package/dist/commands/export.d.ts.map +1 -0
  22. package/dist/commands/export.js +67 -0
  23. package/dist/commands/export.js.map +1 -0
  24. package/dist/commands/guest.d.ts +9 -3
  25. package/dist/commands/guest.d.ts.map +1 -1
  26. package/dist/commands/guest.js +32 -28
  27. package/dist/commands/guest.js.map +1 -1
  28. package/dist/commands/import.d.ts +26 -0
  29. package/dist/commands/import.d.ts.map +1 -0
  30. package/dist/commands/import.js +168 -0
  31. package/dist/commands/import.js.map +1 -0
  32. package/dist/commands/lock.d.ts +5 -0
  33. package/dist/commands/lock.d.ts.map +1 -0
  34. package/dist/commands/lock.js +18 -0
  35. package/dist/commands/lock.js.map +1 -0
  36. package/dist/commands/ls.d.ts +6 -0
  37. package/dist/commands/ls.d.ts.map +1 -0
  38. package/dist/commands/ls.js +37 -0
  39. package/dist/commands/ls.js.map +1 -0
  40. package/dist/commands/restore.d.ts +7 -2
  41. package/dist/commands/restore.d.ts.map +1 -1
  42. package/dist/commands/restore.js +57 -49
  43. package/dist/commands/restore.js.map +1 -1
  44. package/dist/commands/run.d.ts +7 -5
  45. package/dist/commands/run.d.ts.map +1 -1
  46. package/dist/commands/run.js +98 -187
  47. package/dist/commands/run.js.map +1 -1
  48. package/dist/commands/set.d.ts +16 -0
  49. package/dist/commands/set.d.ts.map +1 -0
  50. package/dist/commands/set.js +111 -0
  51. package/dist/commands/set.js.map +1 -0
  52. package/dist/commands/start.d.ts +16 -0
  53. package/dist/commands/start.d.ts.map +1 -0
  54. package/dist/commands/start.js +118 -0
  55. package/dist/commands/start.js.map +1 -0
  56. package/dist/commands/status.d.ts +5 -0
  57. package/dist/commands/status.d.ts.map +1 -0
  58. package/dist/commands/status.js +40 -0
  59. package/dist/commands/status.js.map +1 -0
  60. package/dist/commands/unlink.d.ts +9 -0
  61. package/dist/commands/unlink.d.ts.map +1 -0
  62. package/dist/commands/unlink.js +70 -0
  63. package/dist/commands/unlink.js.map +1 -0
  64. package/dist/lib/api-url.d.ts +12 -0
  65. package/dist/lib/api-url.d.ts.map +1 -1
  66. package/dist/lib/api-url.js +32 -0
  67. package/dist/lib/api-url.js.map +1 -1
  68. package/dist/lib/api.d.ts +35 -23
  69. package/dist/lib/api.d.ts.map +1 -1
  70. package/dist/lib/api.js +23 -59
  71. package/dist/lib/api.js.map +1 -1
  72. package/dist/lib/authorize.d.ts +13 -6
  73. package/dist/lib/authorize.d.ts.map +1 -1
  74. package/dist/lib/authorize.js +68 -61
  75. package/dist/lib/authorize.js.map +1 -1
  76. package/dist/lib/bootstrap.d.ts +18 -15
  77. package/dist/lib/bootstrap.d.ts.map +1 -1
  78. package/dist/lib/bootstrap.js +59 -69
  79. package/dist/lib/bootstrap.js.map +1 -1
  80. package/dist/lib/confirm.js +4 -4
  81. package/dist/lib/confirm.js.map +1 -1
  82. package/dist/lib/context.d.ts +12 -0
  83. package/dist/lib/context.d.ts.map +1 -0
  84. package/dist/lib/context.js +43 -0
  85. package/dist/lib/context.js.map +1 -0
  86. package/dist/lib/credentials.d.ts +8 -13
  87. package/dist/lib/credentials.d.ts.map +1 -1
  88. package/dist/lib/credentials.js +2 -9
  89. package/dist/lib/credentials.js.map +1 -1
  90. package/dist/lib/fs.d.ts +26 -40
  91. package/dist/lib/fs.d.ts.map +1 -1
  92. package/dist/lib/fs.js +112 -326
  93. package/dist/lib/fs.js.map +1 -1
  94. package/dist/lib/guest-key.d.ts +2 -5
  95. package/dist/lib/guest-key.d.ts.map +1 -1
  96. package/dist/lib/guest-key.js +9 -2
  97. package/dist/lib/guest-key.js.map +1 -1
  98. package/dist/lib/identity.d.ts +9 -11
  99. package/dist/lib/identity.d.ts.map +1 -1
  100. package/dist/lib/identity.js +34 -24
  101. package/dist/lib/identity.js.map +1 -1
  102. package/dist/lib/keychain.d.ts +21 -0
  103. package/dist/lib/keychain.d.ts.map +1 -0
  104. package/dist/lib/keychain.js +124 -0
  105. package/dist/lib/keychain.js.map +1 -0
  106. package/dist/lib/pek.d.ts +15 -24
  107. package/dist/lib/pek.d.ts.map +1 -1
  108. package/dist/lib/pek.js +30 -54
  109. package/dist/lib/pek.js.map +1 -1
  110. package/dist/lib/run-env.d.ts +50 -0
  111. package/dist/lib/run-env.d.ts.map +1 -0
  112. package/dist/lib/run-env.js +114 -0
  113. package/dist/lib/run-env.js.map +1 -0
  114. package/dist/lib/unlock.d.ts +24 -0
  115. package/dist/lib/unlock.d.ts.map +1 -0
  116. package/dist/lib/unlock.js +87 -0
  117. package/dist/lib/unlock.js.map +1 -0
  118. package/dist/lib/update-check.d.ts +4 -2
  119. package/dist/lib/update-check.d.ts.map +1 -1
  120. package/dist/lib/update-check.js +54 -68
  121. package/dist/lib/update-check.js.map +1 -1
  122. package/dist/lib/upload.d.ts +21 -0
  123. package/dist/lib/upload.d.ts.map +1 -0
  124. package/dist/lib/upload.js +53 -0
  125. package/dist/lib/upload.js.map +1 -0
  126. package/package.json +5 -3
  127. package/dist/commands/delete.d.ts +0 -6
  128. package/dist/commands/delete.d.ts.map +0 -1
  129. package/dist/commands/delete.js +0 -55
  130. package/dist/commands/delete.js.map +0 -1
  131. package/dist/commands/link.d.ts +0 -16
  132. package/dist/commands/link.d.ts.map +0 -1
  133. package/dist/commands/link.js +0 -142
  134. package/dist/commands/link.js.map +0 -1
  135. package/dist/commands/pull.d.ts +0 -15
  136. package/dist/commands/pull.d.ts.map +0 -1
  137. package/dist/commands/pull.js +0 -155
  138. package/dist/commands/pull.js.map +0 -1
  139. package/dist/commands/push.d.ts +0 -15
  140. package/dist/commands/push.d.ts.map +0 -1
  141. package/dist/commands/push.js +0 -261
  142. package/dist/commands/push.js.map +0 -1
  143. package/dist/commands/remove.d.ts +0 -11
  144. package/dist/commands/remove.d.ts.map +0 -1
  145. package/dist/commands/remove.js +0 -39
  146. package/dist/commands/remove.js.map +0 -1
  147. package/dist/commands/token.d.ts +0 -14
  148. package/dist/commands/token.d.ts.map +0 -1
  149. package/dist/commands/token.js +0 -132
  150. package/dist/commands/token.js.map +0 -1
  151. package/dist/commands/whoami.d.ts +0 -6
  152. package/dist/commands/whoami.d.ts.map +0 -1
  153. package/dist/commands/whoami.js +0 -46
  154. package/dist/commands/whoami.js.map +0 -1
  155. package/dist/lib/env-name.d.ts +0 -3
  156. package/dist/lib/env-name.d.ts.map +0 -1
  157. package/dist/lib/env-name.js +0 -5
  158. package/dist/lib/env-name.js.map +0 -1
  159. package/dist/lib/guest-key.test.d.ts +0 -2
  160. package/dist/lib/guest-key.test.d.ts.map +0 -1
  161. package/dist/lib/guest-key.test.js.map +0 -1
@@ -1,18 +1,39 @@
1
- import { exec } from "node:child_process";
1
+ import { spawn } from "node:child_process";
2
2
  import pc from "picocolors";
3
3
  import { ensureGitignoreHasEnv, readLine, readProjectMeta, writeProjectMeta, } from "./fs.js";
4
- import { writeFolderToken, } from "./credentials.js";
5
- import { ApiClient, resolveApiUrl } from "./api.js";
6
- function openBrowser(url) {
7
- const platform = process.platform;
8
- const cmd = platform === "win32"
9
- ? `start "" "${url}"`
10
- : platform === "darwin"
11
- ? `open "${url}"`
12
- : `xdg-open "${url}"`;
13
- exec(cmd, () => undefined);
4
+ import { writeFolderToken } from "./credentials.js";
5
+ import { ApiClient, parseSafeUrl, resolveApiUrl } from "./api.js";
6
+ /** Command + argv to open a URL. No shell, so the URL is never parsed as a command. */
7
+ export function browserCommand(raw, platform = process.platform) {
8
+ const url = parseSafeUrl(raw);
9
+ if (!url)
10
+ return null;
11
+ const href = url.href;
12
+ if (platform === "win32") {
13
+ return { cmd: "rundll32.exe", args: ["url.dll,FileProtocolHandler", href] };
14
+ }
15
+ if (platform === "darwin")
16
+ return { cmd: "open", args: [href] };
17
+ return { cmd: "xdg-open", args: [href] };
18
+ }
19
+ export function openBrowser(url) {
20
+ const command = browserCommand(url);
21
+ if (!command)
22
+ return;
23
+ try {
24
+ const child = spawn(command.cmd, command.args, {
25
+ stdio: "ignore",
26
+ detached: true,
27
+ windowsHide: true,
28
+ });
29
+ child.on("error", () => undefined);
30
+ child.unref();
31
+ }
32
+ catch {
33
+ /* the URL is printed too; opening is best effort */
34
+ }
14
35
  }
15
- function sleep(ms) {
36
+ export function sleep(ms) {
16
37
  return new Promise((resolve) => setTimeout(resolve, ms));
17
38
  }
18
39
  /** Write token.json + project.json together. Authorize = link. */
@@ -26,31 +47,26 @@ async function saveVerifiedToken(token, apiUrl) {
26
47
  const msg = err instanceof Error ? err.message : String(err);
27
48
  throw new Error(`Could not verify token: ${msg}`);
28
49
  }
29
- const scope = who.cliScope === "production" ? "production" : "development";
30
- writeFolderToken({
31
- token,
32
- apiUrl,
33
- cliScope: scope,
34
- projectId: who.projectId,
35
- });
50
+ writeFolderToken({ token, apiUrl, projectId: who.project.id });
36
51
  const existing = readProjectMeta() ?? {};
52
+ const sameProject = existing.projectId === who.project.id;
37
53
  writeProjectMeta({
38
- ...existing,
39
- projectId: who.projectId,
40
- projectName: who.projectName,
41
- apiUrl,
54
+ ...(sameProject ? existing : {}),
55
+ projectId: who.project.id,
56
+ projectName: who.project.name,
42
57
  });
43
58
  ensureGitignoreHasEnv();
44
- console.log(`\n${pc.green("✓")} Authorized ${who.projectName} (${scope})\n`);
59
+ console.error(`\n${pc.green("✓")} Signed in. Project: ${pc.bold(who.project.name)}\n`);
60
+ return who;
45
61
  }
46
62
  async function authorizeViaPaste(apiUrl) {
47
63
  const cliPage = `${apiUrl.replace(/\/$/, "")}/cli`;
48
- console.log(pc.dim(`Create or copy a token: ${cliPage}\n`));
49
- const token = (await readLine("Paste per-project CLI token: ")).trim();
64
+ console.error(pc.dim(`Create or copy a folder token: ${cliPage}\n`));
65
+ const token = (await readLine("Paste CLI token: ")).trim();
50
66
  if (!token) {
51
67
  throw new Error("No token entered.");
52
68
  }
53
- await saveVerifiedToken(token, apiUrl);
69
+ return saveVerifiedToken(token, apiUrl);
54
70
  }
55
71
  async function authorizeViaBrowser(apiUrl) {
56
72
  const client = new ApiClient(apiUrl);
@@ -60,63 +76,54 @@ async function authorizeViaBrowser(apiUrl) {
60
76
  }
61
77
  catch (err) {
62
78
  const msg = err instanceof Error ? err.message : String(err);
63
- console.log(pc.yellow(`Browser sign-in unavailable (${msg}).`));
64
- console.log(pc.dim("Falling back to paste.\n"));
65
- await authorizeViaPaste(apiUrl);
66
- return;
67
- }
68
- console.log("Open this URL to authorize the CLI:\n");
69
- console.log(` ${start.verifyUrl}\n`);
70
- if (process.stdin.isTTY) {
71
- openBrowser(start.verifyUrl);
72
- console.log(pc.dim("Opened in your browser. Waiting...\n"));
73
- }
74
- else {
75
- console.log(pc.dim("Waiting for approval...\n"));
79
+ console.error(pc.yellow(`Browser sign-in unavailable (${msg}).`));
80
+ console.error(pc.dim("Falling back to paste.\n"));
81
+ return authorizeViaPaste(apiUrl);
76
82
  }
83
+ const linked = readProjectMeta()?.projectId;
84
+ const verifyUrl = linked
85
+ ? `${start.verifyUrl}${start.verifyUrl.includes("?") ? "&" : "?"}project=${encodeURIComponent(linked)}`
86
+ : start.verifyUrl;
87
+ console.error("Open this URL to sign in and pick a project:\n");
88
+ console.error(` ${verifyUrl}\n`);
89
+ console.error(`Check the page shows this code: ${pc.bold(start.userCode)}\n`);
90
+ openBrowser(verifyUrl);
91
+ console.error(pc.dim("Opened in your browser. Waiting...\n"));
77
92
  const deadline = new Date(start.expiresAt).getTime();
78
93
  while (Date.now() < deadline) {
79
94
  let poll;
80
95
  try {
81
- poll = await client.request("GET", `/api/cli-auth/poll?sessionId=${encodeURIComponent(start.sessionId)}`);
96
+ poll = await client.request("GET", `/api/cli-auth/poll?sessionId=${encodeURIComponent(start.sessionId)}`, undefined, { "X-Getmyenv-Poll-Secret": start.pollSecret });
82
97
  }
83
98
  catch (err) {
84
99
  const msg = err instanceof Error ? err.message : String(err);
85
- throw new Error(`Could not poll CLI auth: ${msg}`);
100
+ throw new Error(`Could not poll sign-in: ${msg}`);
86
101
  }
87
102
  if (poll.status === "approved" && poll.token) {
88
- process.stdout.write("\n");
89
- await saveVerifiedToken(poll.token, apiUrl);
90
- return;
103
+ process.stderr.write("\n");
104
+ return saveVerifiedToken(poll.token, apiUrl);
91
105
  }
92
106
  if (poll.status === "denied") {
93
- throw new Error("CLI authorization was denied in the browser.");
107
+ throw new Error("Sign-in was denied in the browser.");
94
108
  }
95
109
  if (poll.status === "expired") {
96
- throw new Error("CLI authorization expired. Re-run this command, or set GETMYENV_TOKEN for CI.");
110
+ throw new Error("Sign-in expired. Run the command again.");
97
111
  }
98
112
  const remaining = Math.max(0, Math.ceil((deadline - Date.now()) / 1000));
99
- process.stdout.write(`\r${pc.dim(`Waiting... ${String(remaining).padStart(2, "0")}s`)} `);
113
+ process.stderr.write(`\r${pc.dim(`Waiting... ${String(remaining).padStart(2, "0")}s`)} `);
100
114
  await sleep(2000);
101
115
  }
102
- process.stdout.write("\n");
103
- throw new Error("CLI authorization timed out. Re-run this command, or set GETMYENV_TOKEN for CI.");
116
+ process.stderr.write("\n");
117
+ throw new Error("Sign-in timed out. Run the command again.");
104
118
  }
105
119
  /**
106
- * Authorize this folder via browser (writes token.json + project.json).
107
- * Used by bootstrap when no folder token exists. CI uses GETMYENV_TOKEN.
120
+ * Sign in via the browser and link this folder (writes token.json + project.json).
121
+ * CI uses GETMYENV_TOKEN instead.
108
122
  */
109
123
  export async function authorizeFolder(opts = {}) {
110
124
  if (!process.stdin.isTTY) {
111
- throw new Error("No CLI token in this folder. Set GETMYENV_TOKEN for CI, or run in a TTY.");
112
- }
113
- const apiUrl = opts.apiUrl?.trim() ||
114
- process.env.GETMYENV_API_URL?.trim() ||
115
- resolveApiUrl(opts.apiUrl);
116
- const hasMeta = Boolean(readProjectMeta()?.projectId);
117
- if (!hasMeta) {
118
- console.log(pc.dim("No project in this folder yet. AI scaffolding without an account: npx getmyenv guest --name <project>\n"));
125
+ throw new Error("No CLI token in this folder. Set GETMYENV_TOKEN for CI, or run in a terminal.");
119
126
  }
120
- await authorizeViaBrowser(apiUrl);
127
+ return authorizeViaBrowser(resolveApiUrl(opts.apiUrl));
121
128
  }
122
129
  //# sourceMappingURL=authorize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/lib/authorize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/lib/authorize.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,22 @@
1
- import { type WhoamiResponse } from "./api.js";
2
- export type BootstrapOpts = {
3
- apiUrl?: string;
4
- /** Verb name (unused for prompts; kept for callers). */
5
- action: "push" | "pull" | "run" | "backup" | "restore";
6
- };
7
- /**
8
- * Ensure this folder is authorized and linked.
9
- * Token write also syncs project.json. If meta is missing or stale on name/env,
10
- * refresh silently from whoami. No "Link and run?" confirm.
11
- */
12
- export declare function ensureTokenAndLink(opts: BootstrapOpts): Promise<{
1
+ import { type ProjectMeta } from "./fs.js";
2
+ import { ApiClient, type WhoamiResponse } from "./api.js";
3
+ export type Linked = {
13
4
  who: WhoamiResponse;
14
5
  apiUrl: string;
15
6
  token: string;
16
- projectId: string;
17
- projectName: string;
18
- }>;
7
+ client: ApiClient;
8
+ meta: ProjectMeta | null;
9
+ };
10
+ export declare const NOT_LINKED_STEPS: string;
11
+ export declare function printGuestBanner(who: WhoamiResponse): void;
12
+ export declare function fetchWhoami(client: ApiClient): Promise<WhoamiResponse>;
13
+ /**
14
+ * Make sure this folder has a token, then load whoami.
15
+ * No token: a terminal runs guided setup; anything else gets next steps.
16
+ * project.json is refreshed from whoami (name, id) and keeps its context.
17
+ */
18
+ export declare function ensureTokenAndLink(opts?: {
19
+ apiUrl?: string;
20
+ quiet?: boolean;
21
+ }): Promise<Linked>;
19
22
  //# sourceMappingURL=bootstrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"AAOA,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAIlB,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;CACxD,CAAC;AAqBF;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;IACrE,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAgFD"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,SAAS,EAIT,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,MAAM,GAAG;IACnB,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAKjB,CAAC;AAEb,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,CAkB1D;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAgB5E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCzG"}
@@ -1,92 +1,82 @@
1
1
  import pc from "picocolors";
2
2
  import { ensureGitignoreHasEnv, readClaimFile, readProjectMeta, writeProjectMeta, } from "./fs.js";
3
- import { ApiClient, ApiError, ensureSessionToken, hasSessionToken, resolveApiUrl, } from "./api.js";
4
- import { authorizeFolder } from "./authorize.js";
5
- import { readFolderToken, writeFolderToken } from "./credentials.js";
6
- function printGuestBanner(who) {
3
+ import { ApiClient, ApiError, getSessionToken, resolveApiUrl, } from "./api.js";
4
+ export const NOT_LINKED_STEPS = [
5
+ "This folder is not linked to a getmyenv project.",
6
+ "Start in a terminal: npx getmyenv",
7
+ "Without an account: npx getmyenv guest",
8
+ "In CI: set GETMYENV_TOKEN",
9
+ ].join("\n");
10
+ export function printGuestBanner(who) {
7
11
  if (!who.isGuest)
8
12
  return;
9
- const expires = who.guestExpiresAt
10
- ? new Date(who.guestExpiresAt).getTime()
11
- : NaN;
12
- const daysLeft = Number.isFinite(expires)
13
- ? Math.max(0, Math.ceil((expires - Date.now()) / (24 * 60 * 60 * 1000)))
14
- : null;
15
- const claim = readClaimFile();
16
- const days = daysLeft == null ? "soon" : daysLeft === 1 ? "1 day" : `${daysLeft} days`;
17
- const needClaim = claim ? "" : " Need .getmyenv/claim.json.";
18
- console.log(pc.yellow(`Guest. Expires in ~${days}. Claim: npx getmyenv claim.${needClaim}\n`));
19
- }
20
- /**
21
- * Ensure this folder is authorized and linked.
22
- * Token write also syncs project.json. If meta is missing or stale on name/env,
23
- * refresh silently from whoami. No "Link and run?" confirm.
24
- */
25
- export async function ensureTokenAndLink(opts) {
26
- if (!hasSessionToken()) {
27
- if (!process.stdin.isTTY) {
28
- throw new Error("No CLI token in this folder. Set GETMYENV_TOKEN for CI, or run in a TTY.");
29
- }
30
- await authorizeFolder({ apiUrl: opts.apiUrl });
13
+ const DAY = 24 * 60 * 60 * 1000;
14
+ const expires = who.guestExpiresAt ? new Date(who.guestExpiresAt).getTime() : NaN;
15
+ const needClaim = readClaimFile() ? "" : " Needs .getmyenv/claim.json.";
16
+ const plural = (n) => (n === 1 ? "1 day" : `${n} days`);
17
+ if (Number.isFinite(expires) && expires <= Date.now()) {
18
+ const graceLeft = Math.max(0, Math.ceil((expires + 30 * DAY - Date.now()) / DAY));
19
+ console.error(pc.yellow(`Guest project expired. Read-only for ${plural(graceLeft)}. Export or claim it: npx getmyenv claim.${needClaim}\n`));
20
+ return;
31
21
  }
32
- let meta = readProjectMeta();
33
- let token = await ensureSessionToken();
34
- const apiUrl = resolveApiUrl(opts.apiUrl);
35
- const client = new ApiClient(apiUrl, token);
36
- let who;
22
+ const daysLeft = Number.isFinite(expires) ? Math.max(0, Math.ceil((expires - Date.now()) / DAY)) : null;
23
+ const days = daysLeft == null ? "soon" : plural(daysLeft);
24
+ console.error(pc.yellow(`Guest project. Expires in ${days}. Keep it: npx getmyenv claim.${needClaim}\n`));
25
+ }
26
+ export async function fetchWhoami(client) {
37
27
  try {
38
- who = await client.request("GET", "/api/cli/whoami");
28
+ return await client.request("GET", "/api/cli/whoami");
39
29
  }
40
30
  catch (err) {
41
31
  if (err instanceof ApiError && err.status === 410) {
42
- throw new Error(`${err.message}\nOpen: npx getmyenv claim`);
32
+ throw new Error(err.message);
33
+ }
34
+ if (err instanceof ApiError && err.status === 401) {
35
+ throw new Error(process.env.GETMYENV_TOKEN?.trim()
36
+ ? `${err.message}\nGETMYENV_TOKEN no longer works. Create a new token on the CLI page.`
37
+ : `${err.message}\nThis folder's token no longer works. Run: npx getmyenv unlink, then npx getmyenv`);
43
38
  }
44
39
  throw err;
45
40
  }
46
- printGuestBanner(who);
47
- if (meta?.projectId && String(meta.projectId) !== String(who.projectId)) {
41
+ }
42
+ /**
43
+ * Make sure this folder has a token, then load whoami.
44
+ * No token: a terminal runs guided setup; anything else gets next steps.
45
+ * project.json is refreshed from whoami (name, id) and keeps its context.
46
+ */
47
+ export async function ensureTokenAndLink(opts = {}) {
48
+ if (!getSessionToken()) {
49
+ if (!process.stdin.isTTY) {
50
+ throw new Error(NOT_LINKED_STEPS);
51
+ }
52
+ const { startSetup } = await import("../commands/start.js");
53
+ await startSetup({ apiUrl: opts.apiUrl, thenContinue: true });
54
+ }
55
+ const token = getSessionToken();
56
+ if (!token)
57
+ throw new Error(NOT_LINKED_STEPS);
58
+ const apiUrl = resolveApiUrl(opts.apiUrl);
59
+ const client = new ApiClient(apiUrl, token);
60
+ const who = await fetchWhoami(client);
61
+ if (!opts.quiet)
62
+ printGuestBanner(who);
63
+ let meta = readProjectMeta();
64
+ if (meta?.projectId && meta.projectId !== who.project.id) {
48
65
  throw new Error([
49
- `Linked project (${meta.projectName ?? meta.projectId}) does not match this folder's token (${who.projectName}).`,
50
- "Run: npx getmyenv delete (then re-run this command)",
66
+ `project.json points at ${meta.projectName ?? meta.projectId}, but the token is for ${who.project.name}.`,
67
+ "Run: npx getmyenv unlink (then run the command again)",
51
68
  ].join("\n"));
52
69
  }
53
- // Drop legacy token.json.projectName when present (name lives in project.json).
54
- const folder = readFolderToken();
55
- if (folder?.projectName) {
56
- writeFolderToken({
57
- token: folder.token,
58
- cliScope: folder.cliScope,
59
- projectId: folder.projectId,
60
- apiUrl: folder.apiUrl,
61
- addedAt: folder.addedAt,
62
- });
63
- }
64
- // Drop legacy project.json.environment when present (cliScope is source of truth).
65
- const needsSync = !meta?.projectId ||
66
- meta.projectName !== who.projectName ||
67
- meta.environment != null;
68
- if (needsSync) {
70
+ const usingEnvToken = Boolean(process.env.GETMYENV_TOKEN?.trim());
71
+ if (!usingEnvToken && (!meta?.projectId || meta.projectName !== who.project.name)) {
69
72
  writeProjectMeta({
70
73
  ...(meta ?? {}),
71
- projectId: who.projectId,
72
- projectName: who.projectName,
73
- apiUrl,
74
+ projectId: who.project.id,
75
+ projectName: who.project.name,
74
76
  });
75
77
  ensureGitignoreHasEnv();
76
78
  meta = readProjectMeta();
77
79
  }
78
- if (!meta?.projectId) {
79
- throw new Error([
80
- "No project is linked to this folder.",
81
- "Re-run this command to authorize, or set GETMYENV_TOKEN for CI.",
82
- ].join("\n"));
83
- }
84
- return {
85
- who,
86
- apiUrl,
87
- token,
88
- projectId: String(meta.projectId),
89
- projectName: meta.projectName ?? who.projectName,
90
- };
80
+ return { who, apiUrl, token, client, meta };
91
81
  }
92
82
  //# sourceMappingURL=bootstrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -8,14 +8,14 @@ export async function confirmDiff(opts) {
8
8
  const { conflicts, action, yes } = opts;
9
9
  if (conflicts.length === 0)
10
10
  return true;
11
- console.log(pc.yellow(`\n${conflicts.length} conflict(s):`));
11
+ console.error(pc.yellow(`\n${conflicts.length} conflict(s):`));
12
12
  for (const c of conflicts.slice(0, 20)) {
13
- console.log(` ${c.name}${c.detail ? pc.dim(` - ${c.detail}`) : ""}`);
13
+ console.error(` ${c.name}${c.detail ? pc.dim(` - ${c.detail}`) : ""}`);
14
14
  }
15
15
  if (conflicts.length > 20) {
16
- console.log(pc.dim(` …and ${conflicts.length - 20} more`));
16
+ console.error(pc.dim(` …and ${conflicts.length - 20} more`));
17
17
  }
18
- console.log("");
18
+ console.error("");
19
19
  if (yes)
20
20
  return true;
21
21
  if (!process.stdin.isTTY) {
@@ -1 +1 @@
1
- {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/lib/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAQxC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAMjC;IACC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC;IAC7D,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAErB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,wDAAwD,MAAM,CAAC,WAAW,EAAE,GAAG,CAChF,CAAC;IACJ,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/lib/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAQxC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAMjC;IACC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAElB,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAErB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,wDAAwD,MAAM,CAAC,WAAW,EAAE,GAAG,CAChF,CAAC;IACJ,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ContextInfo, WhoamiResponse } from "./api.js";
2
+ import type { ProjectMeta } from "./fs.js";
3
+ /**
4
+ * Default context for this folder:
5
+ * server token's bound context, then project.json `context`, then `development`.
6
+ */
7
+ export declare function defaultContextSlug(who: Pick<WhoamiResponse, "token" | "contexts">, meta: ProjectMeta | null): string;
8
+ /** Find a context by slug, or by name ("Customer Acme" finds customer-acme). */
9
+ export declare function findContext(contexts: ContextInfo[], input: string): ContextInfo | null;
10
+ /** The context a command acts on. Throws with the available slugs when unknown. */
11
+ export declare function resolveContext(who: Pick<WhoamiResponse, "token" | "contexts">, meta: ProjectMeta | null, explicit?: string): ContextInfo;
12
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC,EAC/C,IAAI,EAAE,WAAW,GAAG,IAAI,GACvB,MAAM,CAMR;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,GACZ,WAAW,GAAG,IAAI,CAUpB;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAC5B,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,CAAC,EAC/C,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,QAAQ,CAAC,EAAE,MAAM,GAChB,WAAW,CAab"}
@@ -0,0 +1,43 @@
1
+ import { DEFAULT_CONTEXT_SLUG, slugify } from "@getmyenv/shared";
2
+ /**
3
+ * Default context for this folder:
4
+ * server token's bound context, then project.json `context`, then `development`.
5
+ */
6
+ export function defaultContextSlug(who, meta) {
7
+ if (who.token.kind === "server" && who.token.context)
8
+ return who.token.context;
9
+ const slugs = new Set(who.contexts.map((c) => c.slug));
10
+ if (meta?.context && slugs.has(meta.context))
11
+ return meta.context;
12
+ if (slugs.has(DEFAULT_CONTEXT_SLUG))
13
+ return DEFAULT_CONTEXT_SLUG;
14
+ return who.contexts[0]?.slug ?? DEFAULT_CONTEXT_SLUG;
15
+ }
16
+ /** Find a context by slug, or by name ("Customer Acme" finds customer-acme). */
17
+ export function findContext(contexts, input) {
18
+ const raw = input.trim();
19
+ if (!raw)
20
+ return null;
21
+ const exact = contexts.find((c) => c.slug === raw);
22
+ if (exact)
23
+ return exact;
24
+ const lower = raw.toLowerCase();
25
+ const byName = contexts.find((c) => c.name.toLowerCase() === lower);
26
+ if (byName)
27
+ return byName;
28
+ const slug = slugify(raw);
29
+ return contexts.find((c) => c.slug === slug) ?? null;
30
+ }
31
+ /** The context a command acts on. Throws with the available slugs when unknown. */
32
+ export function resolveContext(who, meta, explicit) {
33
+ const wanted = explicit?.trim() || defaultContextSlug(who, meta);
34
+ const found = findContext(who.contexts, wanted);
35
+ if (found)
36
+ return found;
37
+ if (who.token.kind === "server") {
38
+ throw new Error(`This server token reads ${who.token.context ?? "one locked context"} only.`);
39
+ }
40
+ const available = who.contexts.map((c) => c.slug).join(", ") || "none";
41
+ throw new Error(`No context "${wanted}". Available: ${available}\nCreate one: npx getmyenv context create "${wanted}"`);
42
+ }
43
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/lib/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAIjE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAA+C,EAC/C,IAAwB;IAExB,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;IAC/E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI,EAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IAClE,IAAI,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACjE,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,oBAAoB,CAAC;AACvD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,QAAuB,EACvB,KAAa;IAEb,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IACnD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;IACpE,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;AACvD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAC5B,GAA+C,EAC/C,IAAwB,EACxB,QAAiB;IAEjB,MAAM,MAAM,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,oBAAoB,QAAQ,CAC7E,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;IACvE,MAAM,IAAI,KAAK,CACb,eAAe,MAAM,iBAAiB,SAAS,8CAA8C,MAAM,GAAG,CACvG,CAAC;AACJ,CAAC"}
@@ -1,27 +1,22 @@
1
- export type CliScope = "development" | "production";
2
1
  /**
3
- * Per-folder token stored in `.getmyenv/token.json`.
4
- * One folder = one project = one token. No machine-global store.
5
- * projectName is legacy on disk; display name lives in project.json.
2
+ * Per-folder token stored in `.getmyenv/token.json` (gitignored).
3
+ * One folder = one project = one token. What the token can reach is decided
4
+ * by the server (folder, guest or server token), not by this file.
6
5
  */
7
6
  export type FolderToken = {
8
- version: 1;
7
+ version: 2;
9
8
  token: string;
10
- cliScope: CliScope;
11
9
  apiUrl?: string;
12
10
  projectId: string;
13
- /** Legacy; tolerated on read, no longer written. */
14
- projectName?: string;
15
- /** Legacy field; no longer written. Tolerated on read. */
16
- label?: string;
17
11
  addedAt: string;
18
12
  };
19
13
  export declare function tokenFilePath(cwd?: string): string;
20
14
  export declare function readFolderToken(cwd?: string): FolderToken | null;
21
- export declare function writeFolderToken(entry: Omit<FolderToken, "version" | "addedAt" | "projectName" | "label"> & {
15
+ export declare function writeFolderToken(entry: {
16
+ token: string;
17
+ apiUrl?: string;
18
+ projectId: string;
22
19
  addedAt?: string;
23
- /** Ignored; project name lives in project.json. */
24
- projectName?: string;
25
20
  }, cwd?: string): string;
26
21
  export declare function clearFolderToken(cwd?: string): boolean;
27
22
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAEpD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,GAAG,SAAgB,GAAG,MAAM,CAEzD;AAED,wBAAgB,eAAe,CAAC,GAAG,SAAgB,GAAG,WAAW,GAAG,IAAI,CAmCvE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC,GAAG;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,GAAG,SAAgB,GAClB,MAAM,CAgBR;AAED,wBAAgB,gBAAgB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAK7D"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,GAAG,SAAgB,GAAG,MAAM,CAEzD;AAED,wBAAgB,eAAe,CAAC,GAAG,SAAgB,GAAG,WAAW,GAAG,IAAI,CA4BvE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAC9E,GAAG,SAAgB,GAClB,MAAM,CAeR;AAED,wBAAgB,gBAAgB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAK7D"}
@@ -24,19 +24,13 @@ export function readFolderToken(cwd = process.cwd()) {
24
24
  if (typeof d.projectId !== "string" && typeof d.projectId !== "number") {
25
25
  return null;
26
26
  }
27
- const scope = d.cliScope === "production" ? "production" : "development";
28
27
  return {
29
- version: 1,
28
+ version: 2,
30
29
  token: d.token.trim(),
31
- cliScope: scope,
32
30
  apiUrl: typeof d.apiUrl === "string" && d.apiUrl.trim()
33
31
  ? d.apiUrl.trim()
34
32
  : undefined,
35
33
  projectId: String(d.projectId),
36
- ...(typeof d.projectName === "string" && d.projectName.trim()
37
- ? { projectName: d.projectName.trim() }
38
- : {}),
39
- label: typeof d.label === "string" && d.label.trim() ? d.label.trim() : undefined,
40
34
  addedAt: typeof d.addedAt === "string" && d.addedAt
41
35
  ? d.addedAt
42
36
  : new Date().toISOString(),
@@ -47,9 +41,8 @@ export function writeFolderToken(entry, cwd = process.cwd()) {
47
41
  fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
48
42
  const diskApi = apiUrlForDisk(entry.apiUrl);
49
43
  const payload = {
50
- version: 1,
44
+ version: 2,
51
45
  token: entry.token.trim(),
52
- cliScope: entry.cliScope,
53
46
  projectId: String(entry.projectId),
54
47
  ...(diskApi ? { apiUrl: diskApi } : {}),
55
48
  addedAt: entry.addedAt ?? new Date().toISOString(),