@flakiness/sdk 0.98.0 → 0.100.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/lib/cli/cli.js CHANGED
@@ -773,8 +773,8 @@ function sha1File(filePath) {
773
773
  stream.on("end", () => {
774
774
  resolve(hash.digest("hex"));
775
775
  });
776
- stream.on("error", (err) => {
777
- reject(err);
776
+ stream.on("error", (err2) => {
777
+ reject(err2);
778
778
  });
779
779
  });
780
780
  }
@@ -1494,7 +1494,21 @@ var KNOWN_CLIENT_IDS = {
1494
1494
  // src/cli/cmd-login.ts
1495
1495
  import open from "open";
1496
1496
  import os3 from "os";
1497
+
1498
+ // src/cli/cmd-logout.ts
1499
+ async function cmdLogout() {
1500
+ const session2 = await FlakinessSession.load();
1501
+ if (!session2)
1502
+ return;
1503
+ const currentSession = await session2.api.user.currentSession.GET().catch((e) => void 0);
1504
+ if (currentSession)
1505
+ await session2.api.user.logoutSession.POST({ sessionId: currentSession.sessionPublicId });
1506
+ await FlakinessSession.remove();
1507
+ }
1508
+
1509
+ // src/cli/cmd-login.ts
1497
1510
  async function cmdLogin(endpoint) {
1511
+ await cmdLogout();
1498
1512
  const api = createServerAPI(endpoint);
1499
1513
  const data = await api.deviceauth.createRequest.POST({
1500
1514
  clientId: KNOWN_CLIENT_IDS.OFFICIAL_CLI,
@@ -1532,17 +1546,6 @@ async function cmdLogin(endpoint) {
1532
1546
  }
1533
1547
  }
1534
1548
 
1535
- // src/cli/cmd-logout.ts
1536
- async function cmdLogout() {
1537
- const session2 = await FlakinessSession.load();
1538
- if (!session2)
1539
- return;
1540
- const currentSession = await session2.api.user.currentSession.GET().catch((e) => void 0);
1541
- if (currentSession)
1542
- await session2.api.user.logoutSession.POST({ sessionId: currentSession.sessionPublicId });
1543
- await FlakinessSession.remove();
1544
- }
1545
-
1546
1549
  // src/cli/cmd-show-report.ts
1547
1550
  import chalk from "chalk";
1548
1551
  import open2 from "open";
@@ -1646,6 +1649,17 @@ var LocalReportServer = class _LocalReportServer {
1646
1649
  this._authToken = _authToken;
1647
1650
  }
1648
1651
  static async create(options) {
1652
+ const report = JSON.parse(await fs8.promises.readFile(options.reportPath, "utf-8"));
1653
+ const attachmentsDir = options.attachmentsFolder;
1654
+ const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
1655
+ if (missingAttachments.length) {
1656
+ const first = missingAttachments.slice(0, 3);
1657
+ for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
1658
+ console.warn(`Missing attachment with id ${missingAttachments[i]}`);
1659
+ if (missingAttachments.length > 3)
1660
+ console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
1661
+ }
1662
+ const commits = await listLocalCommits(process.cwd(), report.commitId, 100);
1649
1663
  const app = express();
1650
1664
  app.set("etag", false);
1651
1665
  const authToken = randomUUIDBase62();
@@ -1671,37 +1685,21 @@ var LocalReportServer = class _LocalReportServer {
1671
1685
  });
1672
1686
  app.use("/" + authToken, createTypedHttpExpressMiddleware({
1673
1687
  router: localReportRouter,
1674
- createRootContext: async ({ req, res, input }) => {
1675
- const report = JSON.parse(await fs8.promises.readFile(options.reportPath, "utf-8"));
1676
- const attachmentsDir = options.attachmentsFolder;
1677
- const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
1678
- if (missingAttachments.length) {
1679
- const first = missingAttachments.slice(0, 3);
1680
- for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
1681
- console.warn(`Missing attachment with id ${missingAttachments[i]}`);
1682
- if (missingAttachments.length > 3)
1683
- console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
1684
- }
1685
- return {
1686
- report,
1687
- commits: await listLocalCommits(process.cwd(), report.commitId, 100),
1688
- attachmentIdToPath
1689
- };
1690
- }
1688
+ createRootContext: async ({ req, res, input }) => ({ report, commits, attachmentIdToPath })
1691
1689
  }));
1692
- app.use((err, req, res, next) => {
1693
- if (err instanceof TypedHTTP3.HttpError)
1694
- return res.status(err.status).send({ error: err.message });
1695
- logHTTPServer(err);
1690
+ app.use((err2, req, res, next) => {
1691
+ if (err2 instanceof TypedHTTP3.HttpError)
1692
+ return res.status(err2.status).send({ error: err2.message });
1693
+ logHTTPServer(err2);
1696
1694
  res.status(500).send({ error: "Internal Server Error" });
1697
1695
  });
1698
1696
  const server = http2.createServer(app);
1699
- server.on("error", (err) => {
1700
- if (err.code === "ECONNRESET") {
1697
+ server.on("error", (err2) => {
1698
+ if (err2.code === "ECONNRESET") {
1701
1699
  logHTTPServer("Client connection reset. Ignoring.");
1702
1700
  return;
1703
1701
  }
1704
- throw err;
1702
+ throw err2;
1705
1703
  });
1706
1704
  const port = await new Promise((resolve) => server.listen(options.port, () => {
1707
1705
  resolve(server.address().port);
@@ -1725,7 +1723,7 @@ async function cmdShowReport(reportFolder) {
1725
1723
  const session2 = await FlakinessSession.load();
1726
1724
  const config = await FlakinessConfig.load();
1727
1725
  const projectPublicId = config.projectPublicId();
1728
- const project = projectPublicId && session2 ? await session2.api.project.getProject.GET({ projectPublicId }) : void 0;
1726
+ const project = projectPublicId && session2 ? await session2.api.project.getProject.GET({ projectPublicId }).catch((e) => void 0) : void 0;
1729
1727
  const endpoint = session2?.endpoint() ?? "https://flakiness.io";
1730
1728
  const server = await LocalReportServer.create({
1731
1729
  endpoint,
@@ -2110,21 +2108,24 @@ async function cmdUploadPlaywrightJson(relativePath, options) {
2110
2108
  }
2111
2109
 
2112
2110
  // src/cli/cmd-upload.ts
2111
+ import chalk2 from "chalk";
2113
2112
  import fs11 from "fs/promises";
2114
2113
  import path9 from "path";
2114
+ var warn = (txt) => console.warn(chalk2.yellow(`[flakiness.io] WARN: ${txt}`));
2115
+ var err = (txt) => console.error(chalk2.red(`[flakiness.io] Error: ${txt}`));
2116
+ var log = (txt) => console.log(`[flakiness.io] ${txt}`);
2115
2117
  async function cmdUpload(relativePath, options) {
2116
2118
  const fullPath = path9.resolve(relativePath);
2117
2119
  if (!await fs11.access(fullPath, fs11.constants.F_OK).then(() => true).catch(() => false)) {
2118
- console.error(`Error: path ${fullPath} is not accessible`);
2120
+ err(`Path ${fullPath} is not accessible!`);
2119
2121
  process.exit(1);
2120
2122
  }
2121
2123
  const text = await fs11.readFile(fullPath, "utf-8");
2122
2124
  const report = JSON.parse(text);
2123
2125
  const attachmentsDir = options.attachmentsDir ?? path9.dirname(fullPath);
2124
2126
  const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
2125
- if (missingAttachments.length && !options.ignoreMissingAttachments) {
2126
- console.log(`Missing ${missingAttachments.length} attachments - exiting. Use --ignore-missing-attachments to force upload.`);
2127
- process.exit(1);
2127
+ if (missingAttachments.length) {
2128
+ warn(`Missing ${missingAttachments.length} attachments`);
2128
2129
  }
2129
2130
  const uploader = new ReportUploader({
2130
2131
  flakinessAccessToken: options.accessToken,
@@ -2133,9 +2134,9 @@ async function cmdUpload(relativePath, options) {
2133
2134
  const upload = uploader.createUpload(report, Array.from(attachmentIdToPath.values()));
2134
2135
  const uploadResult = await upload.upload();
2135
2136
  if (!uploadResult.success) {
2136
- console.log(`[flakiness.io] X Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
2137
+ err(`Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
2137
2138
  } else {
2138
- console.log(`[flakiness.io] \u2713 Report uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
2139
+ log(`\u2713 Uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
2139
2140
  }
2140
2141
  }
2141
2142
 
@@ -2156,7 +2157,6 @@ var session = await FlakinessSession.load();
2156
2157
  var optAccessToken = new Option("-t, --access-token <token>", "A read-write flakiness.io access token").env("FLAKINESS_ACCESS_TOKEN");
2157
2158
  var optEndpoint = new Option("-e, --endpoint <url>", "An endpoint where the service is deployed").default(session?.endpoint() ?? "https://flakiness.io").env("FLAKINESS_ENDPOINT");
2158
2159
  var optAttachmentsDir = new Option("--attachments-dir <dir>", "Directory containing attachments to upload. Defaults to the report directory");
2159
- var optIgnoreMissingAttachments = new Option("--ignore-missing-attachments", "Upload report even if some attachments are missing.").default("", "Same directory as the report file");
2160
2160
  async function runCommand(callback) {
2161
2161
  try {
2162
2162
  await callback();
@@ -2260,7 +2260,7 @@ program.command("download").description("Download run").addOption(optSince).addO
2260
2260
  }
2261
2261
  await Promise.all(downloaders);
2262
2262
  }));
2263
- program.command("upload").description("Upload Flakiness report to the flakiness.io service").argument("<relative-path>", "Path to the Flakiness report file").addOption(optAccessToken).addOption(optEndpoint).addOption(optAttachmentsDir).addOption(optIgnoreMissingAttachments).action(async (relativePath, options) => {
2263
+ program.command("upload").description("Upload Flakiness report to the flakiness.io service").argument("<relative-path>", "Path to the Flakiness report file").addOption(optAccessToken).addOption(optEndpoint).addOption(optAttachmentsDir).action(async (relativePath, options) => {
2264
2264
  await runCommand(async () => {
2265
2265
  await cmdUpload(relativePath, await ensureAccessToken(options));
2266
2266
  });
@@ -164,8 +164,20 @@ var FlakinessSession = class _FlakinessSession {
164
164
  }
165
165
  };
166
166
 
167
+ // src/cli/cmd-logout.ts
168
+ async function cmdLogout() {
169
+ const session = await FlakinessSession.load();
170
+ if (!session)
171
+ return;
172
+ const currentSession = await session.api.user.currentSession.GET().catch((e) => void 0);
173
+ if (currentSession)
174
+ await session.api.user.logoutSession.POST({ sessionId: currentSession.sessionPublicId });
175
+ await FlakinessSession.remove();
176
+ }
177
+
167
178
  // src/cli/cmd-login.ts
168
179
  async function cmdLogin(endpoint) {
180
+ await cmdLogout();
169
181
  const api = createServerAPI(endpoint);
170
182
  const data = await api.deviceauth.createRequest.POST({
171
183
  clientId: KNOWN_CLIENT_IDS.OFFICIAL_CLI,
@@ -387,6 +387,17 @@ var LocalReportServer = class _LocalReportServer {
387
387
  this._authToken = _authToken;
388
388
  }
389
389
  static async create(options) {
390
+ const report = JSON.parse(await fs5.promises.readFile(options.reportPath, "utf-8"));
391
+ const attachmentsDir = options.attachmentsFolder;
392
+ const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
393
+ if (missingAttachments.length) {
394
+ const first = missingAttachments.slice(0, 3);
395
+ for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
396
+ console.warn(`Missing attachment with id ${missingAttachments[i]}`);
397
+ if (missingAttachments.length > 3)
398
+ console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
399
+ }
400
+ const commits = await listLocalCommits(process.cwd(), report.commitId, 100);
390
401
  const app = express();
391
402
  app.set("etag", false);
392
403
  const authToken = randomUUIDBase62();
@@ -412,23 +423,7 @@ var LocalReportServer = class _LocalReportServer {
412
423
  });
413
424
  app.use("/" + authToken, createTypedHttpExpressMiddleware({
414
425
  router: localReportRouter,
415
- createRootContext: async ({ req, res, input }) => {
416
- const report = JSON.parse(await fs5.promises.readFile(options.reportPath, "utf-8"));
417
- const attachmentsDir = options.attachmentsFolder;
418
- const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
419
- if (missingAttachments.length) {
420
- const first = missingAttachments.slice(0, 3);
421
- for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
422
- console.warn(`Missing attachment with id ${missingAttachments[i]}`);
423
- if (missingAttachments.length > 3)
424
- console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
425
- }
426
- return {
427
- report,
428
- commits: await listLocalCommits(process.cwd(), report.commitId, 100),
429
- attachmentIdToPath
430
- };
431
- }
426
+ createRootContext: async ({ req, res, input }) => ({ report, commits, attachmentIdToPath })
432
427
  }));
433
428
  app.use((err, req, res, next) => {
434
429
  if (err instanceof TypedHTTP3.HttpError)
@@ -466,7 +461,7 @@ async function cmdShowReport(reportFolder) {
466
461
  const session = await FlakinessSession.load();
467
462
  const config = await FlakinessConfig.load();
468
463
  const projectPublicId = config.projectPublicId();
469
- const project = projectPublicId && session ? await session.api.project.getProject.GET({ projectPublicId }) : void 0;
464
+ const project = projectPublicId && session ? await session.api.project.getProject.GET({ projectPublicId }).catch((e) => void 0) : void 0;
470
465
  const endpoint = session?.endpoint() ?? "https://flakiness.io";
471
466
  const server = await LocalReportServer.create({
472
467
  endpoint,
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/cmd-upload.ts
4
+ import chalk from "chalk";
4
5
  import fs3 from "fs/promises";
5
6
  import path2 from "path";
6
7
 
@@ -284,19 +285,21 @@ var ReportUpload = class {
284
285
  };
285
286
 
286
287
  // src/cli/cmd-upload.ts
288
+ var warn = (txt) => console.warn(chalk.yellow(`[flakiness.io] WARN: ${txt}`));
289
+ var err = (txt) => console.error(chalk.red(`[flakiness.io] Error: ${txt}`));
290
+ var log = (txt) => console.log(`[flakiness.io] ${txt}`);
287
291
  async function cmdUpload(relativePath, options) {
288
292
  const fullPath = path2.resolve(relativePath);
289
293
  if (!await fs3.access(fullPath, fs3.constants.F_OK).then(() => true).catch(() => false)) {
290
- console.error(`Error: path ${fullPath} is not accessible`);
294
+ err(`Path ${fullPath} is not accessible!`);
291
295
  process.exit(1);
292
296
  }
293
297
  const text = await fs3.readFile(fullPath, "utf-8");
294
298
  const report = JSON.parse(text);
295
299
  const attachmentsDir = options.attachmentsDir ?? path2.dirname(fullPath);
296
300
  const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
297
- if (missingAttachments.length && !options.ignoreMissingAttachments) {
298
- console.log(`Missing ${missingAttachments.length} attachments - exiting. Use --ignore-missing-attachments to force upload.`);
299
- process.exit(1);
301
+ if (missingAttachments.length) {
302
+ warn(`Missing ${missingAttachments.length} attachments`);
300
303
  }
301
304
  const uploader = new ReportUploader({
302
305
  flakinessAccessToken: options.accessToken,
@@ -305,9 +308,9 @@ async function cmdUpload(relativePath, options) {
305
308
  const upload = uploader.createUpload(report, Array.from(attachmentIdToPath.values()));
306
309
  const uploadResult = await upload.upload();
307
310
  if (!uploadResult.success) {
308
- console.log(`[flakiness.io] X Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
311
+ err(`Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
309
312
  } else {
310
- console.log(`[flakiness.io] \u2713 Report uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
313
+ log(`\u2713 Uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
311
314
  }
312
315
  }
313
316
  export {
@@ -222,6 +222,17 @@ var LocalReportServer = class _LocalReportServer {
222
222
  this._authToken = _authToken;
223
223
  }
224
224
  static async create(options) {
225
+ const report = JSON.parse(await fs3.promises.readFile(options.reportPath, "utf-8"));
226
+ const attachmentsDir = options.attachmentsFolder;
227
+ const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
228
+ if (missingAttachments.length) {
229
+ const first = missingAttachments.slice(0, 3);
230
+ for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
231
+ console.warn(`Missing attachment with id ${missingAttachments[i]}`);
232
+ if (missingAttachments.length > 3)
233
+ console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
234
+ }
235
+ const commits = await listLocalCommits(process.cwd(), report.commitId, 100);
225
236
  const app = express();
226
237
  app.set("etag", false);
227
238
  const authToken = randomUUIDBase62();
@@ -247,23 +258,7 @@ var LocalReportServer = class _LocalReportServer {
247
258
  });
248
259
  app.use("/" + authToken, createTypedHttpExpressMiddleware({
249
260
  router: localReportRouter,
250
- createRootContext: async ({ req, res, input }) => {
251
- const report = JSON.parse(await fs3.promises.readFile(options.reportPath, "utf-8"));
252
- const attachmentsDir = options.attachmentsFolder;
253
- const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
254
- if (missingAttachments.length) {
255
- const first = missingAttachments.slice(0, 3);
256
- for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
257
- console.warn(`Missing attachment with id ${missingAttachments[i]}`);
258
- if (missingAttachments.length > 3)
259
- console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
260
- }
261
- return {
262
- report,
263
- commits: await listLocalCommits(process.cwd(), report.commitId, 100),
264
- attachmentIdToPath
265
- };
266
- }
261
+ createRootContext: async ({ req, res, input }) => ({ report, commits, attachmentIdToPath })
267
262
  }));
268
263
  app.use((err, req, res, next) => {
269
264
  if (err instanceof TypedHTTP2.HttpError)
@@ -518,6 +518,17 @@ var LocalReportServer = class _LocalReportServer {
518
518
  this._authToken = _authToken;
519
519
  }
520
520
  static async create(options) {
521
+ const report = JSON.parse(await fs5.promises.readFile(options.reportPath, "utf-8"));
522
+ const attachmentsDir = options.attachmentsFolder;
523
+ const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
524
+ if (missingAttachments.length) {
525
+ const first = missingAttachments.slice(0, 3);
526
+ for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
527
+ console.warn(`Missing attachment with id ${missingAttachments[i]}`);
528
+ if (missingAttachments.length > 3)
529
+ console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
530
+ }
531
+ const commits = await listLocalCommits(process.cwd(), report.commitId, 100);
521
532
  const app = express();
522
533
  app.set("etag", false);
523
534
  const authToken = randomUUIDBase62();
@@ -543,23 +554,7 @@ var LocalReportServer = class _LocalReportServer {
543
554
  });
544
555
  app.use("/" + authToken, createTypedHttpExpressMiddleware({
545
556
  router: localReportRouter,
546
- createRootContext: async ({ req, res, input }) => {
547
- const report = JSON.parse(await fs5.promises.readFile(options.reportPath, "utf-8"));
548
- const attachmentsDir = options.attachmentsFolder;
549
- const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
550
- if (missingAttachments.length) {
551
- const first = missingAttachments.slice(0, 3);
552
- for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
553
- console.warn(`Missing attachment with id ${missingAttachments[i]}`);
554
- if (missingAttachments.length > 3)
555
- console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
556
- }
557
- return {
558
- report,
559
- commits: await listLocalCommits(process.cwd(), report.commitId, 100),
560
- attachmentIdToPath
561
- };
562
- }
557
+ createRootContext: async ({ req, res, input }) => ({ report, commits, attachmentIdToPath })
563
558
  }));
564
559
  app.use((err2, req, res, next) => {
565
560
  if (err2 instanceof TypedHTTP3.HttpError)
@@ -597,7 +592,7 @@ async function cmdShowReport(reportFolder) {
597
592
  const session = await FlakinessSession.load();
598
593
  const config = await FlakinessConfig.load();
599
594
  const projectPublicId = config.projectPublicId();
600
- const project = projectPublicId && session ? await session.api.project.getProject.GET({ projectPublicId }) : void 0;
595
+ const project = projectPublicId && session ? await session.api.project.getProject.GET({ projectPublicId }).catch((e) => void 0) : void 0;
601
596
  const endpoint = session?.endpoint() ?? "https://flakiness.io";
602
597
  const server = await LocalReportServer.create({
603
598
  endpoint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flakiness/sdk",
3
- "version": "0.98.0",
3
+ "version": "0.100.0",
4
4
  "private": false,
5
5
  "bin": {
6
6
  "flakiness": "./lib/cli/cli.js"
@@ -45,7 +45,7 @@
45
45
  "author": "Degu Labs, Inc",
46
46
  "license": "Fair Source 100",
47
47
  "devDependencies": {
48
- "@flakiness/server": "0.98.0",
48
+ "@flakiness/server": "0.100.0",
49
49
  "@playwright/test": "^1.54.0",
50
50
  "@types/babel__code-frame": "^7.0.6",
51
51
  "@types/compression": "^1.8.1",
@@ -53,8 +53,8 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@babel/code-frame": "^7.26.2",
56
- "@flakiness/report": "0.98.0",
57
- "@flakiness/shared": "0.98.0",
56
+ "@flakiness/report": "0.100.0",
57
+ "@flakiness/shared": "0.100.0",
58
58
  "@rgrove/parse-xml": "^4.2.0",
59
59
  "body-parser": "^1.20.3",
60
60
  "chalk": "^5.6.2",