@flakiness/sdk 0.98.0 → 0.99.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
  }
@@ -1646,6 +1646,17 @@ var LocalReportServer = class _LocalReportServer {
1646
1646
  this._authToken = _authToken;
1647
1647
  }
1648
1648
  static async create(options) {
1649
+ const report = JSON.parse(await fs8.promises.readFile(options.reportPath, "utf-8"));
1650
+ const attachmentsDir = options.attachmentsFolder;
1651
+ const { attachmentIdToPath, missingAttachments } = await resolveAttachmentPaths(report, attachmentsDir);
1652
+ if (missingAttachments.length) {
1653
+ const first = missingAttachments.slice(0, 3);
1654
+ for (let i = 0; i < 3 && i < missingAttachments.length; ++i)
1655
+ console.warn(`Missing attachment with id ${missingAttachments[i]}`);
1656
+ if (missingAttachments.length > 3)
1657
+ console.warn(`...and ${missingAttachments.length - 3} more missing attachments.`);
1658
+ }
1659
+ const commits = await listLocalCommits(process.cwd(), report.commitId, 100);
1649
1660
  const app = express();
1650
1661
  app.set("etag", false);
1651
1662
  const authToken = randomUUIDBase62();
@@ -1671,37 +1682,21 @@ var LocalReportServer = class _LocalReportServer {
1671
1682
  });
1672
1683
  app.use("/" + authToken, createTypedHttpExpressMiddleware({
1673
1684
  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
- }
1685
+ createRootContext: async ({ req, res, input }) => ({ report, commits, attachmentIdToPath })
1691
1686
  }));
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);
1687
+ app.use((err2, req, res, next) => {
1688
+ if (err2 instanceof TypedHTTP3.HttpError)
1689
+ return res.status(err2.status).send({ error: err2.message });
1690
+ logHTTPServer(err2);
1696
1691
  res.status(500).send({ error: "Internal Server Error" });
1697
1692
  });
1698
1693
  const server = http2.createServer(app);
1699
- server.on("error", (err) => {
1700
- if (err.code === "ECONNRESET") {
1694
+ server.on("error", (err2) => {
1695
+ if (err2.code === "ECONNRESET") {
1701
1696
  logHTTPServer("Client connection reset. Ignoring.");
1702
1697
  return;
1703
1698
  }
1704
- throw err;
1699
+ throw err2;
1705
1700
  });
1706
1701
  const port = await new Promise((resolve) => server.listen(options.port, () => {
1707
1702
  resolve(server.address().port);
@@ -1725,7 +1720,7 @@ async function cmdShowReport(reportFolder) {
1725
1720
  const session2 = await FlakinessSession.load();
1726
1721
  const config = await FlakinessConfig.load();
1727
1722
  const projectPublicId = config.projectPublicId();
1728
- const project = projectPublicId && session2 ? await session2.api.project.getProject.GET({ projectPublicId }) : void 0;
1723
+ const project = projectPublicId && session2 ? await session2.api.project.getProject.GET({ projectPublicId }).catch((e) => void 0) : void 0;
1729
1724
  const endpoint = session2?.endpoint() ?? "https://flakiness.io";
1730
1725
  const server = await LocalReportServer.create({
1731
1726
  endpoint,
@@ -2110,21 +2105,24 @@ async function cmdUploadPlaywrightJson(relativePath, options) {
2110
2105
  }
2111
2106
 
2112
2107
  // src/cli/cmd-upload.ts
2108
+ import chalk2 from "chalk";
2113
2109
  import fs11 from "fs/promises";
2114
2110
  import path9 from "path";
2111
+ var warn = (txt) => console.warn(chalk2.yellow(`[flakiness.io] WARN: ${txt}`));
2112
+ var err = (txt) => console.error(chalk2.red(`[flakiness.io] Error: ${txt}`));
2113
+ var log = (txt) => console.log(`[flakiness.io] ${txt}`);
2115
2114
  async function cmdUpload(relativePath, options) {
2116
2115
  const fullPath = path9.resolve(relativePath);
2117
2116
  if (!await fs11.access(fullPath, fs11.constants.F_OK).then(() => true).catch(() => false)) {
2118
- console.error(`Error: path ${fullPath} is not accessible`);
2117
+ err(`Path ${fullPath} is not accessible!`);
2119
2118
  process.exit(1);
2120
2119
  }
2121
2120
  const text = await fs11.readFile(fullPath, "utf-8");
2122
2121
  const report = JSON.parse(text);
2123
2122
  const attachmentsDir = options.attachmentsDir ?? path9.dirname(fullPath);
2124
2123
  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);
2124
+ if (missingAttachments.length) {
2125
+ warn(`Missing ${missingAttachments.length} attachments`);
2128
2126
  }
2129
2127
  const uploader = new ReportUploader({
2130
2128
  flakinessAccessToken: options.accessToken,
@@ -2133,9 +2131,9 @@ async function cmdUpload(relativePath, options) {
2133
2131
  const upload = uploader.createUpload(report, Array.from(attachmentIdToPath.values()));
2134
2132
  const uploadResult = await upload.upload();
2135
2133
  if (!uploadResult.success) {
2136
- console.log(`[flakiness.io] X Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
2134
+ err(`Failed to upload to ${options.endpoint}: ${uploadResult.message}`);
2137
2135
  } else {
2138
- console.log(`[flakiness.io] \u2713 Report uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
2136
+ log(`\u2713 Uploaded ${uploadResult.reportUrl ?? uploadResult.message ?? ""}`);
2139
2137
  }
2140
2138
  }
2141
2139
 
@@ -2156,7 +2154,6 @@ var session = await FlakinessSession.load();
2156
2154
  var optAccessToken = new Option("-t, --access-token <token>", "A read-write flakiness.io access token").env("FLAKINESS_ACCESS_TOKEN");
2157
2155
  var optEndpoint = new Option("-e, --endpoint <url>", "An endpoint where the service is deployed").default(session?.endpoint() ?? "https://flakiness.io").env("FLAKINESS_ENDPOINT");
2158
2156
  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
2157
  async function runCommand(callback) {
2161
2158
  try {
2162
2159
  await callback();
@@ -2260,7 +2257,7 @@ program.command("download").description("Download run").addOption(optSince).addO
2260
2257
  }
2261
2258
  await Promise.all(downloaders);
2262
2259
  }));
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) => {
2260
+ 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
2261
  await runCommand(async () => {
2265
2262
  await cmdUpload(relativePath, await ensureAccessToken(options));
2266
2263
  });
@@ -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.99.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.99.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.99.0",
57
+ "@flakiness/shared": "0.99.0",
58
58
  "@rgrove/parse-xml": "^4.2.0",
59
59
  "body-parser": "^1.20.3",
60
60
  "chalk": "^5.6.2",