@walkeros/cli 4.7.1 → 4.7.2-next-1791147139360

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/dist/index.js CHANGED
@@ -86,6 +86,116 @@ import {
86
86
  import { randomBytes } from "crypto";
87
87
  import { join } from "path";
88
88
  import { homedir } from "os";
89
+
90
+ // src/core/api-error.ts
91
+ var EXIT_RETRYABLE = 75;
92
+ var ApiError = class extends Error {
93
+ code;
94
+ details;
95
+ status;
96
+ retryable;
97
+ retryAfterSeconds;
98
+ // Populated only for CLIENT_OUTDATED responses (HTTP 426).
99
+ minVersion;
100
+ clientVersion;
101
+ client;
102
+ upgrade;
103
+ docs;
104
+ constructor(message, options) {
105
+ super(message);
106
+ this.name = "ApiError";
107
+ this.code = options?.code;
108
+ this.details = options?.details;
109
+ this.status = options?.status;
110
+ this.retryable = options?.retryable;
111
+ this.retryAfterSeconds = options?.retryAfterSeconds;
112
+ this.minVersion = options?.minVersion;
113
+ this.clientVersion = options?.clientVersion;
114
+ this.client = options?.client;
115
+ this.upgrade = options?.upgrade;
116
+ this.docs = options?.docs;
117
+ }
118
+ };
119
+ function notAuthenticatedError() {
120
+ return new ApiError("Not authenticated. Run `walkeros auth login` first.", {
121
+ code: "UNAUTHORIZED"
122
+ });
123
+ }
124
+ function extractApiErrorOptions(error, fallbackMessage) {
125
+ if (!error || typeof error !== "object" || !("error" in error) || typeof error.error !== "object") {
126
+ return null;
127
+ }
128
+ const inner = error.error;
129
+ const message = inner.message || fallbackMessage;
130
+ const code = inner.code;
131
+ const details = inner.details?.errors;
132
+ const options = { code, details };
133
+ if (code === "CLIENT_OUTDATED") {
134
+ options.minVersion = inner.minVersion;
135
+ options.clientVersion = inner.clientVersion;
136
+ options.client = inner.client;
137
+ options.upgrade = inner.upgrade;
138
+ options.docs = inner.docs;
139
+ }
140
+ return { message, options };
141
+ }
142
+ function throwApiError(error, fallbackMessage) {
143
+ const extracted = extractApiErrorOptions(error, fallbackMessage);
144
+ if (extracted) throw new ApiError(extracted.message, extracted.options);
145
+ throw new ApiError(fallbackMessage);
146
+ }
147
+ function parseRetryAfter(value) {
148
+ if (!value) return void 0;
149
+ const trimmed = value.trim();
150
+ if (/^\d+$/.test(trimmed)) return parseInt(trimmed, 10);
151
+ const when = Date.parse(trimmed);
152
+ if (Number.isNaN(when)) return void 0;
153
+ return Math.max(0, Math.round((when - Date.now()) / 1e3));
154
+ }
155
+ function throwApiResponseError(response, body, fallbackMessage) {
156
+ const status = response.status;
157
+ const retryAfterSeconds = parseRetryAfter(
158
+ response.headers.get("retry-after")
159
+ );
160
+ const retryable = status === 429 || status === 503 && retryAfterSeconds !== void 0;
161
+ const extracted = extractApiErrorOptions(body, fallbackMessage);
162
+ const message = extracted?.message ?? fallbackMessage;
163
+ const options = {
164
+ ...extracted?.options ?? {},
165
+ status,
166
+ retryable,
167
+ retryAfterSeconds
168
+ };
169
+ throw new ApiError(message, options);
170
+ }
171
+ function machineReadableErrorLine(err) {
172
+ const code = err instanceof ApiError ? err.code ?? "UNKNOWN" : "UNKNOWN";
173
+ const retryable = err instanceof ApiError ? err.retryable === true : false;
174
+ const retryAfter = err instanceof ApiError && err.retryAfterSeconds !== void 0 ? ` retryAfter=${err.retryAfterSeconds}` : "";
175
+ const message = err instanceof Error ? err.message : String(err);
176
+ return `error: code=${code} retryable=${retryable}${retryAfter} message=${message}`;
177
+ }
178
+ function handleCliError(err) {
179
+ console.error(machineReadableErrorLine(err));
180
+ if (err instanceof ApiError && err.code === "CLIENT_OUTDATED") {
181
+ console.error(`
182
+ ${err.message}
183
+ `);
184
+ if (err.upgrade) console.error(` Upgrade: ${err.upgrade}`);
185
+ if (err.docs) console.error(` Docs: ${err.docs}
186
+ `);
187
+ process.exit(2);
188
+ }
189
+ if (err instanceof ApiError && err.retryable) {
190
+ const hint = err.retryAfterSeconds !== void 0 ? ` Retry after ${err.retryAfterSeconds}s.` : " This is temporary, retry shortly.";
191
+ console.error(`${err.message}${hint}`);
192
+ process.exit(EXIT_RETRYABLE);
193
+ }
194
+ console.error(err instanceof Error ? err.message : String(err));
195
+ process.exit(1);
196
+ }
197
+
198
+ // src/lib/config-file.ts
89
199
  function getConfigDir() {
90
200
  const xdgConfig = process.env.XDG_CONFIG_HOME;
91
201
  const base = xdgConfig || join(homedir(), ".config");
@@ -158,9 +268,7 @@ function getFeedbackPreference() {
158
268
  }
159
269
  function setDefaultProject(projectId) {
160
270
  const config = readConfig();
161
- if (!config) {
162
- throw new Error("Not authenticated. Run `walkeros auth login` first.");
163
- }
271
+ if (!config) throw notAuthenticatedError();
164
272
  writeConfig({ ...config, defaultProjectId: projectId });
165
273
  }
166
274
  function getDefaultProject() {
@@ -7256,7 +7364,7 @@ import {
7256
7364
  REF_STORE,
7257
7365
  SECRET_MARKER_PREFIX as SECRET_MARKER_PREFIX3
7258
7366
  } from "@walkeros/core";
7259
- var CLIENT_HEADER = "walkeros-cli/4.7.1";
7367
+ var CLIENT_HEADER = "walkeros-cli/4.7.2-next-1791147139360";
7260
7368
  function createSettingsContext(configDir) {
7261
7369
  return { configDir, cache: /* @__PURE__ */ new Map(), compiled: /* @__PURE__ */ new Map() };
7262
7370
  }
@@ -8924,8 +9032,7 @@ function createApiClient() {
8924
9032
  // here would go stale and never pick up a refresh.
8925
9033
  async onRequest({ request }) {
8926
9034
  const token = await resolveAccessToken();
8927
- if (!token)
8928
- throw new Error("Not authenticated. Run `walkeros auth login` first.");
9035
+ if (!token) throw notAuthenticatedError();
8929
9036
  requireSecureUrl(request.url);
8930
9037
  request.headers.set("Authorization", `Bearer ${token}`);
8931
9038
  return request;
@@ -8934,109 +9041,6 @@ function createApiClient() {
8934
9041
  return client;
8935
9042
  }
8936
9043
 
8937
- // src/core/api-error.ts
8938
- var EXIT_RETRYABLE = 75;
8939
- var ApiError = class extends Error {
8940
- code;
8941
- details;
8942
- status;
8943
- retryable;
8944
- retryAfterSeconds;
8945
- // Populated only for CLIENT_OUTDATED responses (HTTP 426).
8946
- minVersion;
8947
- clientVersion;
8948
- client;
8949
- upgrade;
8950
- docs;
8951
- constructor(message, options) {
8952
- super(message);
8953
- this.name = "ApiError";
8954
- this.code = options?.code;
8955
- this.details = options?.details;
8956
- this.status = options?.status;
8957
- this.retryable = options?.retryable;
8958
- this.retryAfterSeconds = options?.retryAfterSeconds;
8959
- this.minVersion = options?.minVersion;
8960
- this.clientVersion = options?.clientVersion;
8961
- this.client = options?.client;
8962
- this.upgrade = options?.upgrade;
8963
- this.docs = options?.docs;
8964
- }
8965
- };
8966
- function extractApiErrorOptions(error, fallbackMessage) {
8967
- if (!error || typeof error !== "object" || !("error" in error) || typeof error.error !== "object") {
8968
- return null;
8969
- }
8970
- const inner = error.error;
8971
- const message = inner.message || fallbackMessage;
8972
- const code = inner.code;
8973
- const details = inner.details?.errors;
8974
- const options = { code, details };
8975
- if (code === "CLIENT_OUTDATED") {
8976
- options.minVersion = inner.minVersion;
8977
- options.clientVersion = inner.clientVersion;
8978
- options.client = inner.client;
8979
- options.upgrade = inner.upgrade;
8980
- options.docs = inner.docs;
8981
- }
8982
- return { message, options };
8983
- }
8984
- function throwApiError(error, fallbackMessage) {
8985
- const extracted = extractApiErrorOptions(error, fallbackMessage);
8986
- if (extracted) throw new ApiError(extracted.message, extracted.options);
8987
- throw new ApiError(fallbackMessage);
8988
- }
8989
- function parseRetryAfter(value) {
8990
- if (!value) return void 0;
8991
- const trimmed = value.trim();
8992
- if (/^\d+$/.test(trimmed)) return parseInt(trimmed, 10);
8993
- const when = Date.parse(trimmed);
8994
- if (Number.isNaN(when)) return void 0;
8995
- return Math.max(0, Math.round((when - Date.now()) / 1e3));
8996
- }
8997
- function throwApiResponseError(response, body, fallbackMessage) {
8998
- const status = response.status;
8999
- const retryAfterSeconds = parseRetryAfter(
9000
- response.headers.get("retry-after")
9001
- );
9002
- const retryable = status === 429 || status === 503 && retryAfterSeconds !== void 0;
9003
- const extracted = extractApiErrorOptions(body, fallbackMessage);
9004
- const message = extracted?.message ?? fallbackMessage;
9005
- const options = {
9006
- ...extracted?.options ?? {},
9007
- status,
9008
- retryable,
9009
- retryAfterSeconds
9010
- };
9011
- throw new ApiError(message, options);
9012
- }
9013
- function machineReadableErrorLine(err) {
9014
- const code = err instanceof ApiError ? err.code ?? "UNKNOWN" : "UNKNOWN";
9015
- const retryable = err instanceof ApiError ? err.retryable === true : false;
9016
- const retryAfter = err instanceof ApiError && err.retryAfterSeconds !== void 0 ? ` retryAfter=${err.retryAfterSeconds}` : "";
9017
- const message = err instanceof Error ? err.message : String(err);
9018
- return `error: code=${code} retryable=${retryable}${retryAfter} message=${message}`;
9019
- }
9020
- function handleCliError(err) {
9021
- console.error(machineReadableErrorLine(err));
9022
- if (err instanceof ApiError && err.code === "CLIENT_OUTDATED") {
9023
- console.error(`
9024
- ${err.message}
9025
- `);
9026
- if (err.upgrade) console.error(` Upgrade: ${err.upgrade}`);
9027
- if (err.docs) console.error(` Docs: ${err.docs}
9028
- `);
9029
- process.exit(2);
9030
- }
9031
- if (err instanceof ApiError && err.retryable) {
9032
- const hint = err.retryAfterSeconds !== void 0 ? ` Retry after ${err.retryAfterSeconds}s.` : " This is temporary, retry shortly.";
9033
- console.error(`${err.message}${hint}`);
9034
- process.exit(EXIT_RETRYABLE);
9035
- }
9036
- console.error(err instanceof Error ? err.message : String(err));
9037
- process.exit(1);
9038
- }
9039
-
9040
9044
  // src/commands/auth/index.ts
9041
9045
  async function whoami() {
9042
9046
  const client = createApiClient();
@@ -9067,7 +9071,7 @@ async function listProjects(options = {}) {
9067
9071
  const { data, error } = await client.GET("/api/projects", {
9068
9072
  params: { query: { cursor: options.cursor, limit: options.limit } }
9069
9073
  });
9070
- if (error) throw new Error(error.error?.message || "Failed to list projects");
9074
+ if (error) throwApiError(error, "Failed to list projects");
9071
9075
  return data;
9072
9076
  }
9073
9077
  async function getProject(options = {}) {
@@ -9076,7 +9080,7 @@ async function getProject(options = {}) {
9076
9080
  const { data, error } = await client.GET("/api/projects/{projectId}", {
9077
9081
  params: { path: { projectId: id } }
9078
9082
  });
9079
- if (error) throw new Error(error.error?.message || "Failed to get project");
9083
+ if (error) throwApiError(error, "Failed to get project");
9080
9084
  return data;
9081
9085
  }
9082
9086
  async function createProject(options) {
@@ -9084,8 +9088,7 @@ async function createProject(options) {
9084
9088
  const { data, error } = await client.POST("/api/projects", {
9085
9089
  body: { name: options.name }
9086
9090
  });
9087
- if (error)
9088
- throw new Error(error.error?.message || "Failed to create project");
9091
+ if (error) throwApiError(error, "Failed to create project");
9089
9092
  return data;
9090
9093
  }
9091
9094
  async function updateProject(options) {
@@ -9095,8 +9098,7 @@ async function updateProject(options) {
9095
9098
  params: { path: { projectId: id } },
9096
9099
  body: { name: options.name }
9097
9100
  });
9098
- if (error)
9099
- throw new Error(error.error?.message || "Failed to update project");
9101
+ if (error) throwApiError(error, "Failed to update project");
9100
9102
  return data;
9101
9103
  }
9102
9104
  async function deleteProject(options = {}) {
@@ -9105,8 +9107,7 @@ async function deleteProject(options = {}) {
9105
9107
  const { data, error } = await client.DELETE("/api/projects/{projectId}", {
9106
9108
  params: { path: { projectId: id } }
9107
9109
  });
9108
- if (error)
9109
- throw new Error(error.error?.message || "Failed to delete project");
9110
+ if (error) throwApiError(error, "Failed to delete project");
9110
9111
  if (getDefaultProject() === id) clearDefaultProject();
9111
9112
  return data ?? { success: true };
9112
9113
  }