@levr-one/cli 0.10.21 → 0.11.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.
@@ -0,0 +1,405 @@
1
+ import { getApiUrl } from "./env-CdwyPHGV.js";
2
+
3
+ //#region ../sdk-public/dist/runtime/client.js
4
+ function createInterceptorManager() {
5
+ const _fns = [];
6
+ return {
7
+ _fns,
8
+ use(fn) {
9
+ _fns.push(fn);
10
+ },
11
+ eject(fn) {
12
+ const idx = _fns.indexOf(fn);
13
+ if (idx !== -1) _fns[idx] = void 0;
14
+ }
15
+ };
16
+ }
17
+ function buildPath(urlTemplate, pathParams) {
18
+ if (!pathParams) return urlTemplate;
19
+ return urlTemplate.replace(/\{(\w+)\}/g, (_, key) => {
20
+ const val = pathParams[key];
21
+ if (val === void 0) return `{${key}}`;
22
+ const str = typeof val === "object" && val !== null ? JSON.stringify(val) : String(val);
23
+ return encodeURIComponent(str);
24
+ });
25
+ }
26
+ function buildQuery(query) {
27
+ if (!query) return "";
28
+ const params = new URLSearchParams();
29
+ for (const [key, value] of Object.entries(query)) {
30
+ if (value === null || value === void 0) continue;
31
+ if (Array.isArray(value)) {
32
+ for (const item of value) if (item !== null && item !== void 0) params.append(key, String(item));
33
+ } else if (typeof value === "object") params.append(key, JSON.stringify(value));
34
+ else params.append(key, String(value));
35
+ }
36
+ const str = params.toString();
37
+ return str ? `?${str}` : "";
38
+ }
39
+ async function setAuthHeader(headers, config, security) {
40
+ if (!security?.length || !config.auth) return;
41
+ const scheme = security[0];
42
+ if (!scheme) return;
43
+ let token;
44
+ if (typeof config.auth === "function") token = await config.auth(scheme);
45
+ else token = config.auth;
46
+ if (token) {
47
+ const prefix = token.startsWith("Bearer ") ? "" : "Bearer ";
48
+ headers.set("Authorization", `${prefix}${token}`);
49
+ }
50
+ }
51
+ function createClient(initialConfig = {}) {
52
+ let _config = { ...initialConfig };
53
+ const interceptors = {
54
+ request: createInterceptorManager(),
55
+ response: createInterceptorManager(),
56
+ error: createInterceptorManager()
57
+ };
58
+ const getConfig = () => ({ ..._config });
59
+ const setConfig = (config) => {
60
+ _config = { ...config };
61
+ return getConfig();
62
+ };
63
+ const request = async (options) => {
64
+ const fetchFn = _config.fetch ?? globalThis.fetch;
65
+ const url = `${(typeof _config.baseUrl === "function" ? _config.baseUrl() : _config.baseUrl) ?? ""}${buildPath(options.url, options.path)}${buildQuery(options.query)}`;
66
+ const headers = new Headers();
67
+ if (_config.headers) for (const [k, v] of Object.entries(_config.headers)) headers.set(k, v);
68
+ if (options.headers) for (const [k, v] of Object.entries(options.headers)) headers.set(k, v);
69
+ if (_config.workspaceId) {
70
+ if (!headers.has("Workspace-Id")) headers.set("Workspace-Id", _config.workspaceId);
71
+ }
72
+ await setAuthHeader(headers, _config, options.security);
73
+ let body;
74
+ if (options.body !== void 0) if (options.bodySerializer) {
75
+ const serialized = options.bodySerializer(options.body);
76
+ if (serialized instanceof FormData) {
77
+ body = serialized;
78
+ headers.delete("Content-Type");
79
+ } else body = serialized;
80
+ } else if (options.body instanceof FormData) {
81
+ body = options.body;
82
+ headers.delete("Content-Type");
83
+ } else {
84
+ body = JSON.stringify(options.body);
85
+ if (!headers.has("Content-Type")) headers.set("Content-Type", "application/json");
86
+ }
87
+ else headers.delete("Content-Type");
88
+ if (options.requestValidator) await options.requestValidator(options);
89
+ let req = new Request(url, {
90
+ method: options.method ?? "GET",
91
+ headers,
92
+ body,
93
+ redirect: "follow",
94
+ credentials: "include"
95
+ });
96
+ for (const fn of interceptors.request._fns) if (fn) req = await fn(req, options);
97
+ let response = await fetchFn(req);
98
+ for (const fn of interceptors.response._fns) if (fn) response = await fn(response, req, options);
99
+ const result = {
100
+ request: req,
101
+ response
102
+ };
103
+ if (response.ok) {
104
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") return {
105
+ ok: true,
106
+ data: {},
107
+ error: void 0,
108
+ ...result
109
+ };
110
+ const parseAs = options.parseAs ?? "json";
111
+ let data;
112
+ if (parseAs === "stream") return {
113
+ ok: true,
114
+ data: response.body,
115
+ error: void 0,
116
+ ...result
117
+ };
118
+ if (parseAs === "auto" || parseAs === "json") if ((response.headers.get("Content-Type") ?? "").includes("json")) data = await response.json();
119
+ else data = await response.text();
120
+ else data = await response[parseAs]();
121
+ if (parseAs === "json" && options.responseTransformer) data = await options.responseTransformer(data);
122
+ return {
123
+ ok: true,
124
+ data,
125
+ error: void 0,
126
+ ...result
127
+ };
128
+ }
129
+ const textError = await response.text();
130
+ let jsonError;
131
+ try {
132
+ jsonError = JSON.parse(textError);
133
+ } catch {}
134
+ let error = jsonError ?? textError;
135
+ for (const fn of interceptors.error._fns) if (fn) error = await fn(error, response, req, options);
136
+ error = error || {};
137
+ if (options.throwOnError) throw error;
138
+ return {
139
+ ok: false,
140
+ data: void 0,
141
+ error,
142
+ ...result
143
+ };
144
+ };
145
+ return {
146
+ getConfig,
147
+ setConfig,
148
+ request,
149
+ get: (options) => request({
150
+ ...options,
151
+ method: "GET"
152
+ }),
153
+ post: (options) => request({
154
+ ...options,
155
+ method: "POST"
156
+ }),
157
+ put: (options) => request({
158
+ ...options,
159
+ method: "PUT"
160
+ }),
161
+ patch: (options) => request({
162
+ ...options,
163
+ method: "PATCH"
164
+ }),
165
+ delete: (options) => request({
166
+ ...options,
167
+ method: "DELETE"
168
+ }),
169
+ interceptors
170
+ };
171
+ }
172
+
173
+ //#endregion
174
+ //#region ../sdk-public/dist/runtime/index.js
175
+ const defaultConfig = { baseUrl: "https://api.levr.one" };
176
+ const client = createClient(defaultConfig);
177
+
178
+ //#endregion
179
+ //#region ../sdk-public/dist/gen/attachment-upload/functions.js
180
+ /** POST /v1/attachment/upload */
181
+ const attachmentUploadUploadV1 = (options) => {
182
+ return (options?.client ?? client).post({
183
+ security: [{
184
+ scheme: "bearer",
185
+ type: "http"
186
+ }],
187
+ url: "/v1/attachment/upload",
188
+ bodySerializer: (body) => {
189
+ const fd = new FormData();
190
+ if (body && typeof body === "object") for (const [k, v] of Object.entries(body)) {
191
+ if (v == null) continue;
192
+ fd.append(k, v instanceof Blob ? v : String(v));
193
+ }
194
+ return fd;
195
+ },
196
+ ...options
197
+ });
198
+ };
199
+
200
+ //#endregion
201
+ //#region ../sdk-public/dist/gen/auth/functions.js
202
+ /** GET /v1/auth/profile */
203
+ const authGetProfileV1 = (options) => {
204
+ return (options?.client ?? client).get({
205
+ security: [{
206
+ scheme: "bearer",
207
+ type: "http"
208
+ }],
209
+ url: "/v1/auth/profile",
210
+ ...options
211
+ });
212
+ };
213
+ /** GET /v1/auth/sites */
214
+ const authGetSitesV1 = (options) => {
215
+ return (options?.client ?? client).get({
216
+ security: [{
217
+ scheme: "bearer",
218
+ type: "http"
219
+ }],
220
+ url: "/v1/auth/sites",
221
+ ...options
222
+ });
223
+ };
224
+
225
+ //#endregion
226
+ //#region ../sdk-public/dist/gen/comment-issue/functions.js
227
+ /** POST /v1/comment-issue */
228
+ const commentIssueCreateV1 = (options) => {
229
+ return (options?.client ?? client).post({
230
+ security: [{
231
+ scheme: "bearer",
232
+ type: "http"
233
+ }],
234
+ url: "/v1/comment-issue",
235
+ ...options
236
+ });
237
+ };
238
+
239
+ //#endregion
240
+ //#region ../sdk-public/dist/gen/comment-run/functions.js
241
+ /** POST /v1/comment-run */
242
+ const commentRunCreateV1 = (options) => {
243
+ return (options?.client ?? client).post({
244
+ security: [{
245
+ scheme: "bearer",
246
+ type: "http"
247
+ }],
248
+ url: "/v1/comment-run",
249
+ ...options
250
+ });
251
+ };
252
+
253
+ //#endregion
254
+ //#region ../sdk-public/dist/gen/comment-test/functions.js
255
+ /** POST /v1/comment-test */
256
+ const commentTestCreateV1 = (options) => {
257
+ return (options?.client ?? client).post({
258
+ security: [{
259
+ scheme: "bearer",
260
+ type: "http"
261
+ }],
262
+ url: "/v1/comment-test",
263
+ ...options
264
+ });
265
+ };
266
+
267
+ //#endregion
268
+ //#region ../sdk-public/dist/gen/import/functions.js
269
+ /** POST /v1/imports */
270
+ const importCreateV1 = (options) => {
271
+ return (options?.client ?? client).post({
272
+ security: [{
273
+ scheme: "bearer",
274
+ type: "http"
275
+ }],
276
+ url: "/v1/imports",
277
+ bodySerializer: (body) => {
278
+ const fd = new FormData();
279
+ if (body && typeof body === "object") for (const [k, v] of Object.entries(body)) {
280
+ if (v == null) continue;
281
+ fd.append(k, v instanceof Blob ? v : String(v));
282
+ }
283
+ return fd;
284
+ },
285
+ ...options
286
+ });
287
+ };
288
+
289
+ //#endregion
290
+ //#region ../sdk-public/dist/gen/run-api/functions.js
291
+ /** PATCH /v1/run/run-result-variant/{runResultVariantId} */
292
+ const runApiUpdateRunResultVariantByIdV1 = (options) => {
293
+ return (options?.client ?? client).patch({
294
+ security: [{
295
+ scheme: "bearer",
296
+ type: "http"
297
+ }],
298
+ url: "/v1/run/run-result-variant/{runResultVariantId}",
299
+ ...options
300
+ });
301
+ };
302
+
303
+ //#endregion
304
+ //#region src/utils/sdk-client.ts
305
+ /**
306
+ * Configure the SDK client with the resolved auth token and API URL.
307
+ */
308
+ function configureClient(auth, workspaceId) {
309
+ client.setConfig({
310
+ baseUrl: getApiUrl(),
311
+ auth: () => auth.token,
312
+ workspaceId
313
+ });
314
+ }
315
+ /**
316
+ * Upload a test result file via the generated SDK function.
317
+ * importCreateV1 handles auth, FormData serialization, and Content-Type automatically.
318
+ *
319
+ * Note: requestValidator is disabled because the generated Zod schema types
320
+ * `file` as z.string() (from OpenAPI `format: binary`) but we pass a File object.
321
+ * The server validates the actual multipart payload.
322
+ */
323
+ async function uploadImport(options) {
324
+ const result = await importCreateV1({
325
+ body: {
326
+ file: options.file,
327
+ team_id: options.teamId,
328
+ format: options.format,
329
+ run_name: options.runName,
330
+ automation_source: options.automationSource,
331
+ automation_source_id: options.automationSourceId,
332
+ import_metadata: options.importMetadata ? JSON.stringify(options.importMetadata) : void 0,
333
+ include_results: options.includeResults ? true : void 0
334
+ },
335
+ requestValidator: void 0
336
+ });
337
+ if (result.error) {
338
+ const status = result.response?.status;
339
+ switch (status) {
340
+ case 401: throw new Error("Authentication failed. Check your token or run 'levr auth login'.");
341
+ case 403: throw new Error("Permission denied. Check your team access.");
342
+ case 404: throw new Error(tryReadMessage(result.error) ?? "Not found. Check --automation-source and --team-id.");
343
+ case 422: throw new Error("File could not be processed. Check the file format.");
344
+ case 429: throw new Error("Rate limited. Please try again later.");
345
+ default: throw new Error(`Import failed (${String(status ?? "unknown")}): ${JSON.stringify(result.error)}`);
346
+ }
347
+ }
348
+ return result.data;
349
+ }
350
+ function tryReadMessage(err) {
351
+ if (err && typeof err === "object" && "message" in err) {
352
+ const m = err.message;
353
+ return typeof m === "string" ? m : void 0;
354
+ }
355
+ }
356
+ async function uploadAttachment(body) {
357
+ const result = await attachmentUploadUploadV1({
358
+ body,
359
+ requestValidator: void 0
360
+ });
361
+ return {
362
+ status: result.response?.status ?? 0,
363
+ data: result.data,
364
+ error: result.error
365
+ };
366
+ }
367
+ /**
368
+ * Server-side append to an execution result's actual_result, addressed by
369
+ * the variant id alone (ENG-6161 PATCH /v1/run/run-result-variant/:id). Never
370
+ * a read-modify-write: the server appends.
371
+ */
372
+ async function appendActualResult(runResultVariantId, text) {
373
+ const result = await runApiUpdateRunResultVariantByIdV1({
374
+ path: { runResultVariantId },
375
+ body: { append_actual_result: text },
376
+ requestValidator: void 0
377
+ });
378
+ if (result.error) throw new Error(`Append failed (${String(result.response?.status ?? "unknown")}): ${tryReadMessage(result.error) ?? JSON.stringify(result.error)}`);
379
+ }
380
+ /** A NEW comment on an issue, test or run (append-only; ENG-6164 --embed). */
381
+ async function createComment(target, targetId, body) {
382
+ const result = target === "issue" ? await commentIssueCreateV1({
383
+ body: {
384
+ issue_id: targetId,
385
+ body
386
+ },
387
+ requestValidator: void 0
388
+ }) : target === "test" ? await commentTestCreateV1({
389
+ body: {
390
+ test_id: targetId,
391
+ body
392
+ },
393
+ requestValidator: void 0
394
+ }) : await commentRunCreateV1({
395
+ body: {
396
+ run_id: targetId,
397
+ body
398
+ },
399
+ requestValidator: void 0
400
+ });
401
+ if (result.error) throw new Error(`Comment failed (${String(result.response?.status ?? "unknown")}): ${tryReadMessage(result.error) ?? JSON.stringify(result.error)}`);
402
+ }
403
+
404
+ //#endregion
405
+ export { appendActualResult, authGetProfileV1, authGetSitesV1, client, configureClient, createComment, uploadAttachment, uploadImport };
@@ -1,4 +1,4 @@
1
- import { authGetSitesV1, configureClient } from "./sdk-client-B_urshDp.js";
1
+ import { authGetSitesV1, configureClient } from "./sdk-client-DYv-0CfA.js";
2
2
  import "./env-CdwyPHGV.js";
3
3
  import "./token-refresh-DeusLK8H.js";
4
4
  import { resolveToken } from "./resolve-token-7xb7kG7h.js";
@@ -1,4 +1,4 @@
1
- import { authGetProfileV1, configureClient } from "./sdk-client-B_urshDp.js";
1
+ import { authGetProfileV1, configureClient } from "./sdk-client-DYv-0CfA.js";
2
2
  import { getApiUrl, getPatToken, readCredentials } from "./env-CdwyPHGV.js";
3
3
  import { isTokenExpired } from "./token-refresh-DeusLK8H.js";
4
4
  import chalk from "chalk";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levr-one/cli",
3
- "version": "0.10.21",
3
+ "version": "0.11.0",
4
4
  "description": "The command-line interface for Levr",
5
5
  "type": "module",
6
6
  "license": "MIT",