@crvy/rprtr 0.0.5 → 0.0.7

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
@@ -5554,280 +5554,6 @@ if (dev_fallback_default) {
5554
5554
  throw_rune_error("$bindable");
5555
5555
  }
5556
5556
 
5557
- // node_modules/svelte/src/version.js
5558
- var PUBLIC_VERSION = "5";
5559
-
5560
- // node_modules/svelte/src/internal/disclose-version.js
5561
- if (typeof window !== "undefined") {
5562
- ((window.__svelte ??= {}).v ??= /* @__PURE__ */ new Set()).add(PUBLIC_VERSION);
5563
- }
5564
-
5565
- // src/types.ts
5566
- function isDefined(value) {
5567
- return value !== null && value !== void 0;
5568
- }
5569
- function isTest(x) {
5570
- if (x === null || typeof x !== "object") return false;
5571
- const hasId = "id" in x;
5572
- const hasTitlePath = "titlePath" in x;
5573
- return hasId && hasTitlePath && typeof x.id === "string" && Array.isArray(x.titlePath);
5574
- }
5575
- function getChildrenArray(children) {
5576
- if (children === void 0) return [];
5577
- return Object.values(children).filter(isDefined);
5578
- }
5579
- function getChildrenEntries(children) {
5580
- if (children === void 0) return [];
5581
- return Object.entries(children).filter((entry) => isDefined(entry[1]));
5582
- }
5583
- function getChildrenKeys(children) {
5584
- if (children === void 0) return [];
5585
- return Object.keys(children);
5586
- }
5587
-
5588
- // src/client/helpers/status.ts
5589
- var testStatuses = ["unknown", "pending", "running", "failed", "approved", "success", "retrying"];
5590
- function isTestStatus(value) {
5591
- return testStatuses.some((s) => s === value);
5592
- }
5593
- var statusUpdatesMap = /* @__PURE__ */ new Map([
5594
- [void 0, /(unknown|success|approved|failed|pending|running)/],
5595
- ["unknown", /(success|approved|failed|pending|running)/],
5596
- ["success", /(approved|failed|pending|running)/],
5597
- ["approved", /(failed|pending|running)/],
5598
- ["failed", /(pending|running)/],
5599
- ["pending", /running/]
5600
- ]);
5601
- function calcStatus(oldStatus, newStatus) {
5602
- return newStatus !== void 0 && statusUpdatesMap.get(oldStatus)?.test(newStatus) === true ? newStatus : oldStatus;
5603
- }
5604
- function countTestsStatus(suite) {
5605
- let successCount = 0;
5606
- let failedCount = 0;
5607
- let approvedCount = 0;
5608
- let pendingCount = 0;
5609
- const cases = getChildrenArray(suite.children);
5610
- let suiteOrTest;
5611
- while (suiteOrTest = cases.pop()) {
5612
- if (isTest(suiteOrTest)) {
5613
- if (!hasScreenshots(suiteOrTest)) continue;
5614
- if (suiteOrTest.status === "approved") approvedCount++;
5615
- if (suiteOrTest.status === "success") successCount++;
5616
- if (suiteOrTest.status === "failed") failedCount++;
5617
- if (suiteOrTest.status === "pending") pendingCount++;
5618
- } else {
5619
- cases.push(...getChildrenArray(suiteOrTest.children));
5620
- }
5621
- }
5622
- return { approvedCount, successCount, failedCount, pendingCount };
5623
- }
5624
- function getFailedTests(suite) {
5625
- return getChildrenArray(suite.children).flatMap((suiteOrTest) => {
5626
- if (isTest(suiteOrTest)) return suiteOrTest.status === "failed" ? suiteOrTest : [];
5627
- return getFailedTests(suiteOrTest);
5628
- });
5629
- }
5630
- function hasScreenshots(item) {
5631
- if (isTest(item)) {
5632
- return item.results?.some((r2) => r2.images !== void 0 && Object.keys(r2.images).length > 0) ?? false;
5633
- }
5634
- return getChildrenArray(item.children).some((child2) => hasScreenshots(child2));
5635
- }
5636
-
5637
- // src/client/helpers/path.ts
5638
- function getTestPath(test) {
5639
- return [...test.titlePath, test.title, test.browser].filter(isDefined);
5640
- }
5641
- function getSuiteByPath(suite, path) {
5642
- return path.reduce(
5643
- (suiteOrTest, pathToken) => isTest(suiteOrTest) ? suiteOrTest : suiteOrTest?.children?.[pathToken],
5644
- suite
5645
- );
5646
- }
5647
- function getTestByPath(suite, path) {
5648
- const test = getSuiteByPath(suite, path) ?? suite;
5649
- return isTest(test) ? test : null;
5650
- }
5651
- function setSearchParams(testPath) {
5652
- const params = new URLSearchParams();
5653
- testPath.forEach((p, i) => {
5654
- params.set(`testPath[${i}]`, p);
5655
- });
5656
- window.history.pushState({ testPath }, "", `?${params.toString()}`);
5657
- }
5658
- function getTestPathFromSearch() {
5659
- const params = new URLSearchParams(window.location.search);
5660
- const path = [];
5661
- let i = 0;
5662
- while (params.has(`testPath[${i}]`)) {
5663
- path.push(params.get(`testPath[${i}]`));
5664
- i++;
5665
- }
5666
- return path;
5667
- }
5668
- function parseFilterString(value) {
5669
- let status = null;
5670
- const subStrings = [];
5671
- value.split(" ").filter((s) => s !== "").map((word) => word.toLowerCase()).forEach((word) => {
5672
- const match = /^status:(failed|success|pending|approved)$/i.exec(word);
5673
- if (match !== null) {
5674
- const matchedStatus = match[1];
5675
- if (matchedStatus !== void 0 && isTestStatus(matchedStatus)) {
5676
- status = matchedStatus;
5677
- return;
5678
- }
5679
- }
5680
- subStrings.push(word);
5681
- });
5682
- return { status, subStrings };
5683
- }
5684
- function treeifyTests(testsById) {
5685
- const rootSuite = {
5686
- path: [],
5687
- skip: false,
5688
- opened: true,
5689
- checked: true,
5690
- indeterminate: false,
5691
- children: {}
5692
- };
5693
- Object.values(testsById).forEach((test) => {
5694
- if (test === void 0) return;
5695
- const titlePath = test.titlePath ?? [];
5696
- const browser = test.browser ?? "";
5697
- const title = test.title;
5698
- const pathParts = [...titlePath, title, browser].filter((p) => p !== void 0 && p !== "");
5699
- const [browserName, ...testPathParts] = pathParts.reverse();
5700
- if (browserName === void 0) return;
5701
- const lastSuite = testPathParts.reverse().reduce((suite, token) => {
5702
- suite.children = suite.children ?? {};
5703
- suite.children[token] ??= {
5704
- path: [...suite.path, token],
5705
- skip: false,
5706
- opened: false,
5707
- checked: true,
5708
- indeterminate: false,
5709
- children: {}
5710
- };
5711
- const subSuite = suite.children[token];
5712
- if (subSuite === void 0 || isTest(subSuite)) return suite;
5713
- subSuite.status = calcStatus(subSuite.status, test.status);
5714
- suite.status = calcStatus(suite.status, subSuite.status);
5715
- if (test.skip === false) subSuite.skip = false;
5716
- return subSuite;
5717
- }, rootSuite);
5718
- lastSuite.children = lastSuite.children ?? {};
5719
- lastSuite.children[browserName] = {
5720
- ...test,
5721
- checked: true
5722
- };
5723
- });
5724
- return rootSuite;
5725
- }
5726
- function mergeTreeState(target, source2) {
5727
- target.opened = source2.opened;
5728
- target.checked = source2.checked;
5729
- target.indeterminate = source2.indeterminate;
5730
- for (const [key2, targetChild] of getChildrenEntries(target.children)) {
5731
- const sourceChild = source2.children?.[key2];
5732
- if (targetChild === void 0 || sourceChild === void 0) continue;
5733
- if (!isTest(targetChild) && !isTest(sourceChild)) {
5734
- mergeTreeState(targetChild, sourceChild);
5735
- } else if (isTest(targetChild) && isTest(sourceChild)) {
5736
- targetChild.checked = sourceChild.checked;
5737
- }
5738
- }
5739
- }
5740
-
5741
- // src/client/helpers/suite.ts
5742
- function checkTests(suiteOrTest, checked) {
5743
- suiteOrTest.checked = checked;
5744
- if (!isTest(suiteOrTest)) {
5745
- suiteOrTest.indeterminate = false;
5746
- getChildrenArray(suiteOrTest.children).forEach((child2) => {
5747
- checkTests(child2, checked);
5748
- });
5749
- }
5750
- }
5751
- function updateChecked(suite) {
5752
- const children = getChildrenArray(suite.children).filter((child2) => child2.skip === false);
5753
- const checkedEvery = children.every((test) => test.checked);
5754
- const checkedSome = children.some((test) => test.checked);
5755
- const indeterminate = children.some((test) => isTest(test) ? false : test.indeterminate) || !checkedEvery && checkedSome;
5756
- const checked = indeterminate || suite.checked === checkedEvery ? suite.checked : checkedEvery;
5757
- suite.checked = checked;
5758
- suite.indeterminate = indeterminate;
5759
- }
5760
- function checkSuite(suite, path, checked) {
5761
- const subSuite = getSuiteByPath(suite, path);
5762
- if (subSuite) checkTests(subSuite, checked);
5763
- path.slice(0, -1).map((_, index2, tokens) => tokens.slice(0, tokens.length - index2)).forEach((parentPath) => {
5764
- const parentSuite = getSuiteByPath(suite, parentPath);
5765
- if (isTest(parentSuite)) return;
5766
- if (parentSuite) updateChecked(parentSuite);
5767
- });
5768
- updateChecked(suite);
5769
- }
5770
- function openSuite(suite, path, opened) {
5771
- const subSuite = path.reduce(
5772
- (suiteOrTest, pathToken) => {
5773
- if (suiteOrTest && !isTest(suiteOrTest)) {
5774
- if (opened) suiteOrTest.opened = opened;
5775
- return suiteOrTest.children?.[pathToken];
5776
- }
5777
- },
5778
- suite
5779
- );
5780
- if (subSuite && !isTest(subSuite)) subSuite.opened = opened;
5781
- }
5782
- function filterTests(suite, filter) {
5783
- const { status, subStrings } = filter;
5784
- if (!status && !subStrings.length) return suite;
5785
- const filteredSuite = { ...suite, children: {} };
5786
- getChildrenEntries(suite.children).forEach(([title, suiteOrTest]) => {
5787
- if (suiteOrTest.skip === true) return;
5788
- if (!status && subStrings.some((sub) => title.toLowerCase().includes(sub))) {
5789
- filteredSuite.children = filteredSuite.children ?? {};
5790
- filteredSuite.children[title] = suiteOrTest;
5791
- } else if (isTest(suiteOrTest)) {
5792
- if (status && suiteOrTest.status && ["pending", "running", status].includes(suiteOrTest.status)) {
5793
- filteredSuite.children = filteredSuite.children ?? {};
5794
- filteredSuite.children[title] = suiteOrTest;
5795
- }
5796
- } else {
5797
- const filteredSubSuite = filterTests(suiteOrTest, filter);
5798
- if (getChildrenKeys(filteredSubSuite.children).length === 0) return;
5799
- filteredSuite.children = filteredSuite.children ?? {};
5800
- filteredSuite.children[title] = filteredSubSuite;
5801
- }
5802
- });
5803
- return filteredSuite;
5804
- }
5805
- function flattenSuite(suite) {
5806
- if (!suite.opened) return [];
5807
- return getChildrenEntries(suite.children).flatMap(([title, subSuite]) => [
5808
- { title, suite: subSuite },
5809
- ...isTest(subSuite) ? [] : flattenSuite(subSuite)
5810
- ]);
5811
- }
5812
- function recalcSuiteStatuses(root10, testPath) {
5813
- const ancestorPaths = testPath.slice(0, -1).map((_, index2, tokens) => tokens.slice(0, tokens.length - index2));
5814
- for (const parentPath of ancestorPaths) {
5815
- const parentSuite = getSuiteByPath(root10, parentPath);
5816
- if (parentSuite && !isTest(parentSuite)) {
5817
- parentSuite.status = getChildrenArray(parentSuite.children).map(({ status }) => status).reduce(calcStatus);
5818
- }
5819
- }
5820
- root10.status = getChildrenArray(root10.children).map(({ status }) => status).reduce(calcStatus);
5821
- }
5822
- function recalcAllSuiteStatuses(suite) {
5823
- for (const child2 of getChildrenArray(suite.children)) {
5824
- if (!isTest(child2)) {
5825
- recalcAllSuiteStatuses(child2);
5826
- }
5827
- }
5828
- suite.status = getChildrenArray(suite.children).map(({ status }) => status).reduce(calcStatus);
5829
- }
5830
-
5831
5557
  // node_modules/zod/v4/classic/external.js
5832
5558
  var external_exports = {};
5833
5559
  __export(external_exports, {
@@ -19492,230 +19218,568 @@ function convertBaseSchema(schema, ctx) {
19492
19218
  if (schema.default !== void 0) {
19493
19219
  zodSchema = zodSchema.default(schema.default);
19494
19220
  }
19495
- return zodSchema;
19221
+ return zodSchema;
19222
+ }
19223
+ function convertSchema(schema, ctx) {
19224
+ if (typeof schema === "boolean") {
19225
+ return schema ? z.any() : z.never();
19226
+ }
19227
+ let baseSchema = convertBaseSchema(schema, ctx);
19228
+ const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
19229
+ if (schema.anyOf && Array.isArray(schema.anyOf)) {
19230
+ const options = schema.anyOf.map((s) => convertSchema(s, ctx));
19231
+ const anyOfUnion = z.union(options);
19232
+ baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
19233
+ }
19234
+ if (schema.oneOf && Array.isArray(schema.oneOf)) {
19235
+ const options = schema.oneOf.map((s) => convertSchema(s, ctx));
19236
+ const oneOfUnion = z.xor(options);
19237
+ baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
19238
+ }
19239
+ if (schema.allOf && Array.isArray(schema.allOf)) {
19240
+ if (schema.allOf.length === 0) {
19241
+ baseSchema = hasExplicitType ? baseSchema : z.any();
19242
+ } else {
19243
+ let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
19244
+ const startIdx = hasExplicitType ? 0 : 1;
19245
+ for (let i = startIdx; i < schema.allOf.length; i++) {
19246
+ result = z.intersection(result, convertSchema(schema.allOf[i], ctx));
19247
+ }
19248
+ baseSchema = result;
19249
+ }
19250
+ }
19251
+ if (schema.nullable === true && ctx.version === "openapi-3.0") {
19252
+ baseSchema = z.nullable(baseSchema);
19253
+ }
19254
+ if (schema.readOnly === true) {
19255
+ baseSchema = z.readonly(baseSchema);
19256
+ }
19257
+ const extraMeta = {};
19258
+ const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
19259
+ for (const key2 of coreMetadataKeys) {
19260
+ if (key2 in schema) {
19261
+ extraMeta[key2] = schema[key2];
19262
+ }
19263
+ }
19264
+ const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
19265
+ for (const key2 of contentMetadataKeys) {
19266
+ if (key2 in schema) {
19267
+ extraMeta[key2] = schema[key2];
19268
+ }
19269
+ }
19270
+ for (const key2 of Object.keys(schema)) {
19271
+ if (!RECOGNIZED_KEYS.has(key2)) {
19272
+ extraMeta[key2] = schema[key2];
19273
+ }
19274
+ }
19275
+ if (Object.keys(extraMeta).length > 0) {
19276
+ ctx.registry.add(baseSchema, extraMeta);
19277
+ }
19278
+ return baseSchema;
19279
+ }
19280
+ function fromJSONSchema(schema, params) {
19281
+ if (typeof schema === "boolean") {
19282
+ return schema ? z.any() : z.never();
19283
+ }
19284
+ const version2 = detectVersion(schema, params?.defaultTarget);
19285
+ const defs = schema.$defs || schema.definitions || {};
19286
+ const ctx = {
19287
+ version: version2,
19288
+ defs,
19289
+ refs: /* @__PURE__ */ new Map(),
19290
+ processing: /* @__PURE__ */ new Set(),
19291
+ rootSchema: schema,
19292
+ registry: params?.registry ?? globalRegistry
19293
+ };
19294
+ return convertSchema(schema, ctx);
19295
+ }
19296
+
19297
+ // node_modules/zod/v4/classic/coerce.js
19298
+ var coerce_exports = {};
19299
+ __export(coerce_exports, {
19300
+ bigint: () => bigint3,
19301
+ boolean: () => boolean3,
19302
+ date: () => date4,
19303
+ number: () => number3,
19304
+ string: () => string3
19305
+ });
19306
+ function string3(params) {
19307
+ return _coercedString(ZodString, params);
19308
+ }
19309
+ function number3(params) {
19310
+ return _coercedNumber(ZodNumber, params);
19311
+ }
19312
+ function boolean3(params) {
19313
+ return _coercedBoolean(ZodBoolean, params);
19314
+ }
19315
+ function bigint3(params) {
19316
+ return _coercedBigint(ZodBigInt, params);
19317
+ }
19318
+ function date4(params) {
19319
+ return _coercedDate(ZodDate, params);
19320
+ }
19321
+
19322
+ // node_modules/zod/v4/classic/external.js
19323
+ config(en_default());
19324
+
19325
+ // src/schemas.ts
19326
+ var LocationSchema = external_exports.object({
19327
+ file: external_exports.string(),
19328
+ line: external_exports.number()
19329
+ });
19330
+ var VisualSourceSchema = external_exports.enum(["comparison", "baseline-only", "declared-only"]);
19331
+ var ImagesSchema = external_exports.object({
19332
+ actual: external_exports.string().optional(),
19333
+ expect: external_exports.string().optional(),
19334
+ diff: external_exports.string().optional(),
19335
+ error: external_exports.string().optional(),
19336
+ source: VisualSourceSchema.optional()
19337
+ });
19338
+ var ScreenshotDeclarationSchema = external_exports.discriminatedUnion("kind", [
19339
+ external_exports.object({
19340
+ visualName: external_exports.string(),
19341
+ kind: external_exports.literal("named"),
19342
+ declaredName: external_exports.string(),
19343
+ snapshotBaseName: external_exports.string(),
19344
+ occurrenceIndex: external_exports.number()
19345
+ }),
19346
+ external_exports.object({
19347
+ visualName: external_exports.string(),
19348
+ kind: external_exports.literal("unnamed"),
19349
+ occurrenceIndex: external_exports.number()
19350
+ })
19351
+ ]);
19352
+ var AttachmentSchema = external_exports.object({
19353
+ name: external_exports.string(),
19354
+ path: external_exports.string(),
19355
+ contentType: external_exports.string()
19356
+ });
19357
+ var TestStatusSchema = external_exports.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
19358
+ var TestResultStatusSchema = external_exports.enum(["failed", "success", "pending"]);
19359
+ var TestResultSchema = external_exports.object({
19360
+ status: TestResultStatusSchema,
19361
+ retries: external_exports.number(),
19362
+ images: external_exports.record(external_exports.string(), ImagesSchema).optional(),
19363
+ visualDeclarations: external_exports.array(ScreenshotDeclarationSchema).optional(),
19364
+ error: external_exports.string().optional(),
19365
+ duration: external_exports.number().optional()
19366
+ });
19367
+ var TestDataSchema = external_exports.object({
19368
+ id: external_exports.string(),
19369
+ titlePath: external_exports.array(external_exports.string()),
19370
+ browser: external_exports.string(),
19371
+ title: external_exports.string(),
19372
+ skip: external_exports.union([external_exports.boolean(), external_exports.string()]).optional(),
19373
+ retries: external_exports.number().optional(),
19374
+ status: TestStatusSchema.optional(),
19375
+ results: external_exports.array(TestResultSchema).optional(),
19376
+ approved: external_exports.record(external_exports.string(), external_exports.number()).nullable().optional(),
19377
+ attachments: external_exports.array(AttachmentSchema).optional(),
19378
+ location: LocationSchema.optional()
19379
+ });
19380
+ var CrvyRprtrTestSchema = TestDataSchema.extend({
19381
+ checked: external_exports.boolean()
19382
+ });
19383
+ var CrvyRprtrSuiteSchema = external_exports.lazy(
19384
+ () => external_exports.object({
19385
+ path: external_exports.array(external_exports.string()),
19386
+ skip: external_exports.boolean(),
19387
+ status: TestStatusSchema.optional(),
19388
+ opened: external_exports.boolean(),
19389
+ checked: external_exports.boolean(),
19390
+ indeterminate: external_exports.boolean(),
19391
+ children: external_exports.record(external_exports.string(), external_exports.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
19392
+ })
19393
+ );
19394
+ var WebSocketMessageSchema = external_exports.object({
19395
+ type: external_exports.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
19396
+ data: external_exports.unknown()
19397
+ });
19398
+ var TestBeginDataSchema = external_exports.object({
19399
+ id: external_exports.string(),
19400
+ title: external_exports.string(),
19401
+ titlePath: external_exports.array(external_exports.string()),
19402
+ browser: external_exports.string(),
19403
+ location: LocationSchema
19404
+ });
19405
+ var TestEndDataSchema = external_exports.object({
19406
+ id: external_exports.string(),
19407
+ status: external_exports.enum(["passed", "failed", "skipped"]),
19408
+ attachments: external_exports.array(AttachmentSchema),
19409
+ visualNames: external_exports.array(external_exports.string()).default([]),
19410
+ visualDeclarations: external_exports.preprocess(
19411
+ (value) => value === null ? void 0 : value,
19412
+ external_exports.array(ScreenshotDeclarationSchema).optional()
19413
+ ),
19414
+ error: external_exports.string().optional(),
19415
+ duration: external_exports.number().optional()
19416
+ });
19417
+ var ReportDataSchema = external_exports.object({
19418
+ isRunning: external_exports.boolean(),
19419
+ tests: external_exports.record(external_exports.string(), TestDataSchema),
19420
+ browsers: external_exports.array(external_exports.string()),
19421
+ isUpdateMode: external_exports.boolean(),
19422
+ screenshotDir: external_exports.string()
19423
+ });
19424
+ var LoadedReportDataSchema = external_exports.object({
19425
+ tests: external_exports.record(external_exports.string(), TestDataSchema).optional(),
19426
+ isUpdateMode: external_exports.boolean().optional()
19427
+ });
19428
+ var OfflineEventSchema = external_exports.object({
19429
+ type: external_exports.enum(["test-begin", "test-end", "run-end"]),
19430
+ data: external_exports.unknown(),
19431
+ timestamp: external_exports.number(),
19432
+ workerIndex: external_exports.number()
19433
+ });
19434
+ var OfflineReportSchema = external_exports.object({
19435
+ version: external_exports.number(),
19436
+ generatedAt: external_exports.string(),
19437
+ workers: external_exports.number(),
19438
+ events: external_exports.array(OfflineEventSchema)
19439
+ });
19440
+ var ApproveRequestBodySchema = external_exports.object({
19441
+ id: external_exports.string(),
19442
+ retry: external_exports.number(),
19443
+ image: external_exports.string()
19444
+ });
19445
+ var ReportApiResponseSchema = external_exports.object({
19446
+ tests: external_exports.record(external_exports.string(), TestDataSchema),
19447
+ isUpdateMode: external_exports.boolean().optional()
19448
+ });
19449
+ var ClientBootstrapDataSchema = external_exports.object({
19450
+ report: ReportApiResponseSchema.extend({
19451
+ isUpdateMode: external_exports.boolean()
19452
+ }),
19453
+ liveUpdates: external_exports.boolean(),
19454
+ approvalEnabled: external_exports.boolean(),
19455
+ approvalMessage: external_exports.string().optional()
19456
+ });
19457
+ var ImagesViewModeSchema = external_exports.enum(["side-by-side", "swap", "slide", "blend"]);
19458
+ function safeParse3(schema, data) {
19459
+ const result = schema.safeParse(data);
19460
+ if (result.success) {
19461
+ return result.data;
19462
+ }
19463
+ return null;
19496
19464
  }
19497
- function convertSchema(schema, ctx) {
19498
- if (typeof schema === "boolean") {
19499
- return schema ? z.any() : z.never();
19500
- }
19501
- let baseSchema = convertBaseSchema(schema, ctx);
19502
- const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
19503
- if (schema.anyOf && Array.isArray(schema.anyOf)) {
19504
- const options = schema.anyOf.map((s) => convertSchema(s, ctx));
19505
- const anyOfUnion = z.union(options);
19506
- baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
19465
+
19466
+ // src/approval-api.ts
19467
+ var ApprovalResponseBodySchema = external_exports.object({
19468
+ success: external_exports.boolean(),
19469
+ error: external_exports.string().optional()
19470
+ });
19471
+ var BulkApprovalResponseBodySchema = external_exports.object({
19472
+ success: external_exports.boolean(),
19473
+ approved: external_exports.number(),
19474
+ unresolved: external_exports.number(),
19475
+ failed: external_exports.number()
19476
+ });
19477
+ var failedApprovalResult = { success: false };
19478
+ var failedBulkApprovalResult = {
19479
+ success: false,
19480
+ approved: 0,
19481
+ unresolved: 0,
19482
+ failed: 0
19483
+ };
19484
+ async function readJsonBody(response) {
19485
+ try {
19486
+ return await response.json();
19487
+ } catch {
19488
+ return null;
19507
19489
  }
19508
- if (schema.oneOf && Array.isArray(schema.oneOf)) {
19509
- const options = schema.oneOf.map((s) => convertSchema(s, ctx));
19510
- const oneOfUnion = z.xor(options);
19511
- baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
19490
+ }
19491
+ async function readApproveResult(response) {
19492
+ const body = safeParse3(ApprovalResponseBodySchema, await readJsonBody(response));
19493
+ return body !== null && response.ok && body.success ? body : failedApprovalResult;
19494
+ }
19495
+ async function readApproveAllResult(response) {
19496
+ const body = safeParse3(BulkApprovalResponseBodySchema, await readJsonBody(response));
19497
+ if (body === null) {
19498
+ return failedBulkApprovalResult;
19512
19499
  }
19513
- if (schema.allOf && Array.isArray(schema.allOf)) {
19514
- if (schema.allOf.length === 0) {
19515
- baseSchema = hasExplicitType ? baseSchema : z.any();
19500
+ return {
19501
+ success: response.ok && body.success,
19502
+ approved: body.approved,
19503
+ unresolved: body.unresolved,
19504
+ failed: body.failed
19505
+ };
19506
+ }
19507
+ function isBulkApprovalOptimisticSafe(result) {
19508
+ return result.success && result.unresolved === 0 && result.failed === 0;
19509
+ }
19510
+
19511
+ // node_modules/svelte/src/version.js
19512
+ var PUBLIC_VERSION = "5";
19513
+
19514
+ // node_modules/svelte/src/internal/disclose-version.js
19515
+ if (typeof window !== "undefined") {
19516
+ ((window.__svelte ??= {}).v ??= /* @__PURE__ */ new Set()).add(PUBLIC_VERSION);
19517
+ }
19518
+
19519
+ // src/types.ts
19520
+ function isDefined(value) {
19521
+ return value !== null && value !== void 0;
19522
+ }
19523
+ function isTest(x) {
19524
+ if (x === null || typeof x !== "object") return false;
19525
+ const hasId = "id" in x;
19526
+ const hasTitlePath = "titlePath" in x;
19527
+ return hasId && hasTitlePath && typeof x.id === "string" && Array.isArray(x.titlePath);
19528
+ }
19529
+ function getChildrenArray(children) {
19530
+ if (children === void 0) return [];
19531
+ return Object.values(children).filter(isDefined);
19532
+ }
19533
+ function getChildrenEntries(children) {
19534
+ if (children === void 0) return [];
19535
+ return Object.entries(children).filter((entry) => isDefined(entry[1]));
19536
+ }
19537
+ function getChildrenKeys(children) {
19538
+ if (children === void 0) return [];
19539
+ return Object.keys(children);
19540
+ }
19541
+
19542
+ // src/client/helpers/status.ts
19543
+ var testStatuses = ["unknown", "pending", "running", "failed", "approved", "success", "retrying"];
19544
+ function isTestStatus(value) {
19545
+ return testStatuses.some((s) => s === value);
19546
+ }
19547
+ var statusUpdatesMap = /* @__PURE__ */ new Map([
19548
+ [void 0, /(unknown|success|approved|failed|pending|running)/],
19549
+ ["unknown", /(success|approved|failed|pending|running)/],
19550
+ ["success", /(approved|failed|pending|running)/],
19551
+ ["approved", /(failed|pending|running)/],
19552
+ ["failed", /(pending|running)/],
19553
+ ["pending", /running/]
19554
+ ]);
19555
+ function calcStatus(oldStatus, newStatus) {
19556
+ return newStatus !== void 0 && statusUpdatesMap.get(oldStatus)?.test(newStatus) === true ? newStatus : oldStatus;
19557
+ }
19558
+ function countTestsStatus(suite) {
19559
+ let successCount = 0;
19560
+ let failedCount = 0;
19561
+ let approvedCount = 0;
19562
+ let pendingCount = 0;
19563
+ const cases = getChildrenArray(suite.children);
19564
+ let suiteOrTest;
19565
+ while (suiteOrTest = cases.pop()) {
19566
+ if (isTest(suiteOrTest)) {
19567
+ if (!hasScreenshots(suiteOrTest)) continue;
19568
+ if (suiteOrTest.status === "approved") approvedCount++;
19569
+ if (suiteOrTest.status === "success") successCount++;
19570
+ if (suiteOrTest.status === "failed") failedCount++;
19571
+ if (suiteOrTest.status === "pending") pendingCount++;
19516
19572
  } else {
19517
- let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
19518
- const startIdx = hasExplicitType ? 0 : 1;
19519
- for (let i = startIdx; i < schema.allOf.length; i++) {
19520
- result = z.intersection(result, convertSchema(schema.allOf[i], ctx));
19521
- }
19522
- baseSchema = result;
19573
+ cases.push(...getChildrenArray(suiteOrTest.children));
19523
19574
  }
19524
19575
  }
19525
- if (schema.nullable === true && ctx.version === "openapi-3.0") {
19526
- baseSchema = z.nullable(baseSchema);
19527
- }
19528
- if (schema.readOnly === true) {
19529
- baseSchema = z.readonly(baseSchema);
19576
+ return { approvedCount, successCount, failedCount, pendingCount };
19577
+ }
19578
+ function getFailedTests(suite) {
19579
+ return getChildrenArray(suite.children).flatMap((suiteOrTest) => {
19580
+ if (isTest(suiteOrTest)) return suiteOrTest.status === "failed" ? suiteOrTest : [];
19581
+ return getFailedTests(suiteOrTest);
19582
+ });
19583
+ }
19584
+ function hasScreenshots(item) {
19585
+ if (isTest(item)) {
19586
+ return item.results?.some((r2) => r2.images !== void 0 && Object.keys(r2.images).length > 0) ?? false;
19530
19587
  }
19531
- const extraMeta = {};
19532
- const coreMetadataKeys = ["$id", "id", "$comment", "$anchor", "$vocabulary", "$dynamicRef", "$dynamicAnchor"];
19533
- for (const key2 of coreMetadataKeys) {
19534
- if (key2 in schema) {
19535
- extraMeta[key2] = schema[key2];
19536
- }
19588
+ return getChildrenArray(item.children).some((child2) => hasScreenshots(child2));
19589
+ }
19590
+
19591
+ // src/client/helpers/path.ts
19592
+ function getTestPath(test) {
19593
+ return [...test.titlePath, test.title, test.browser].filter(isDefined);
19594
+ }
19595
+ function getSuiteByPath(suite, path) {
19596
+ return path.reduce(
19597
+ (suiteOrTest, pathToken) => isTest(suiteOrTest) ? suiteOrTest : suiteOrTest?.children?.[pathToken],
19598
+ suite
19599
+ );
19600
+ }
19601
+ function getTestByPath(suite, path) {
19602
+ const test = getSuiteByPath(suite, path) ?? suite;
19603
+ return isTest(test) ? test : null;
19604
+ }
19605
+ function setSearchParams(testPath) {
19606
+ const params = new URLSearchParams();
19607
+ testPath.forEach((p, i) => {
19608
+ params.set(`testPath[${i}]`, p);
19609
+ });
19610
+ window.history.pushState({ testPath }, "", `?${params.toString()}`);
19611
+ }
19612
+ function getTestPathFromSearch() {
19613
+ const params = new URLSearchParams(window.location.search);
19614
+ const path = [];
19615
+ let i = 0;
19616
+ while (params.has(`testPath[${i}]`)) {
19617
+ path.push(params.get(`testPath[${i}]`));
19618
+ i++;
19537
19619
  }
19538
- const contentMetadataKeys = ["contentEncoding", "contentMediaType", "contentSchema"];
19539
- for (const key2 of contentMetadataKeys) {
19540
- if (key2 in schema) {
19541
- extraMeta[key2] = schema[key2];
19620
+ return path;
19621
+ }
19622
+ function parseFilterString(value) {
19623
+ let status = null;
19624
+ const subStrings = [];
19625
+ value.split(" ").filter((s) => s !== "").map((word) => word.toLowerCase()).forEach((word) => {
19626
+ const match = /^status:(failed|success|pending|approved)$/i.exec(word);
19627
+ if (match !== null) {
19628
+ const matchedStatus = match[1];
19629
+ if (matchedStatus !== void 0 && isTestStatus(matchedStatus)) {
19630
+ status = matchedStatus;
19631
+ return;
19632
+ }
19542
19633
  }
19543
- }
19544
- for (const key2 of Object.keys(schema)) {
19545
- if (!RECOGNIZED_KEYS.has(key2)) {
19546
- extraMeta[key2] = schema[key2];
19634
+ subStrings.push(word);
19635
+ });
19636
+ return { status, subStrings };
19637
+ }
19638
+ function treeifyTests(testsById) {
19639
+ const rootSuite = {
19640
+ path: [],
19641
+ skip: false,
19642
+ opened: true,
19643
+ checked: true,
19644
+ indeterminate: false,
19645
+ children: {}
19646
+ };
19647
+ Object.values(testsById).forEach((test) => {
19648
+ if (test === void 0) return;
19649
+ const titlePath = test.titlePath ?? [];
19650
+ const browser = test.browser ?? "";
19651
+ const title = test.title;
19652
+ const pathParts = [...titlePath, title, browser].filter((p) => p !== void 0 && p !== "");
19653
+ const [browserName, ...testPathParts] = pathParts.reverse();
19654
+ if (browserName === void 0) return;
19655
+ const lastSuite = testPathParts.reverse().reduce((suite, token) => {
19656
+ suite.children = suite.children ?? {};
19657
+ suite.children[token] ??= {
19658
+ path: [...suite.path, token],
19659
+ skip: false,
19660
+ opened: false,
19661
+ checked: true,
19662
+ indeterminate: false,
19663
+ children: {}
19664
+ };
19665
+ const subSuite = suite.children[token];
19666
+ if (subSuite === void 0 || isTest(subSuite)) return suite;
19667
+ subSuite.status = calcStatus(subSuite.status, test.status);
19668
+ suite.status = calcStatus(suite.status, subSuite.status);
19669
+ if (test.skip === false) subSuite.skip = false;
19670
+ return subSuite;
19671
+ }, rootSuite);
19672
+ lastSuite.children = lastSuite.children ?? {};
19673
+ lastSuite.children[browserName] = {
19674
+ ...test,
19675
+ checked: true
19676
+ };
19677
+ });
19678
+ return rootSuite;
19679
+ }
19680
+ function mergeTreeState(target, source2) {
19681
+ target.opened = source2.opened;
19682
+ target.checked = source2.checked;
19683
+ target.indeterminate = source2.indeterminate;
19684
+ for (const [key2, targetChild] of getChildrenEntries(target.children)) {
19685
+ const sourceChild = source2.children?.[key2];
19686
+ if (targetChild === void 0 || sourceChild === void 0) continue;
19687
+ if (!isTest(targetChild) && !isTest(sourceChild)) {
19688
+ mergeTreeState(targetChild, sourceChild);
19689
+ } else if (isTest(targetChild) && isTest(sourceChild)) {
19690
+ targetChild.checked = sourceChild.checked;
19547
19691
  }
19548
19692
  }
19549
- if (Object.keys(extraMeta).length > 0) {
19550
- ctx.registry.add(baseSchema, extraMeta);
19551
- }
19552
- return baseSchema;
19553
19693
  }
19554
- function fromJSONSchema(schema, params) {
19555
- if (typeof schema === "boolean") {
19556
- return schema ? z.any() : z.never();
19694
+
19695
+ // src/client/helpers/suite.ts
19696
+ function checkTests(suiteOrTest, checked) {
19697
+ suiteOrTest.checked = checked;
19698
+ if (!isTest(suiteOrTest)) {
19699
+ suiteOrTest.indeterminate = false;
19700
+ getChildrenArray(suiteOrTest.children).forEach((child2) => {
19701
+ checkTests(child2, checked);
19702
+ });
19557
19703
  }
19558
- const version2 = detectVersion(schema, params?.defaultTarget);
19559
- const defs = schema.$defs || schema.definitions || {};
19560
- const ctx = {
19561
- version: version2,
19562
- defs,
19563
- refs: /* @__PURE__ */ new Map(),
19564
- processing: /* @__PURE__ */ new Set(),
19565
- rootSchema: schema,
19566
- registry: params?.registry ?? globalRegistry
19567
- };
19568
- return convertSchema(schema, ctx);
19569
19704
  }
19570
-
19571
- // node_modules/zod/v4/classic/coerce.js
19572
- var coerce_exports = {};
19573
- __export(coerce_exports, {
19574
- bigint: () => bigint3,
19575
- boolean: () => boolean3,
19576
- date: () => date4,
19577
- number: () => number3,
19578
- string: () => string3
19579
- });
19580
- function string3(params) {
19581
- return _coercedString(ZodString, params);
19705
+ function updateChecked(suite) {
19706
+ const children = getChildrenArray(suite.children).filter((child2) => child2.skip === false);
19707
+ const checkedEvery = children.every((test) => test.checked);
19708
+ const checkedSome = children.some((test) => test.checked);
19709
+ const indeterminate = children.some((test) => isTest(test) ? false : test.indeterminate) || !checkedEvery && checkedSome;
19710
+ const checked = indeterminate || suite.checked === checkedEvery ? suite.checked : checkedEvery;
19711
+ suite.checked = checked;
19712
+ suite.indeterminate = indeterminate;
19582
19713
  }
19583
- function number3(params) {
19584
- return _coercedNumber(ZodNumber, params);
19714
+ function checkSuite(suite, path, checked) {
19715
+ const subSuite = getSuiteByPath(suite, path);
19716
+ if (subSuite) checkTests(subSuite, checked);
19717
+ path.slice(0, -1).map((_, index2, tokens) => tokens.slice(0, tokens.length - index2)).forEach((parentPath) => {
19718
+ const parentSuite = getSuiteByPath(suite, parentPath);
19719
+ if (isTest(parentSuite)) return;
19720
+ if (parentSuite) updateChecked(parentSuite);
19721
+ });
19722
+ updateChecked(suite);
19585
19723
  }
19586
- function boolean3(params) {
19587
- return _coercedBoolean(ZodBoolean, params);
19724
+ function openSuite(suite, path, opened) {
19725
+ const subSuite = path.reduce(
19726
+ (suiteOrTest, pathToken) => {
19727
+ if (suiteOrTest && !isTest(suiteOrTest)) {
19728
+ if (opened) suiteOrTest.opened = opened;
19729
+ return suiteOrTest.children?.[pathToken];
19730
+ }
19731
+ },
19732
+ suite
19733
+ );
19734
+ if (subSuite && !isTest(subSuite)) subSuite.opened = opened;
19588
19735
  }
19589
- function bigint3(params) {
19590
- return _coercedBigint(ZodBigInt, params);
19736
+ function filterTests(suite, filter) {
19737
+ const { status, subStrings } = filter;
19738
+ if (!status && !subStrings.length) return suite;
19739
+ const filteredSuite = { ...suite, children: {} };
19740
+ getChildrenEntries(suite.children).forEach(([title, suiteOrTest]) => {
19741
+ if (suiteOrTest.skip === true) return;
19742
+ if (!status && subStrings.some((sub) => title.toLowerCase().includes(sub))) {
19743
+ filteredSuite.children = filteredSuite.children ?? {};
19744
+ filteredSuite.children[title] = suiteOrTest;
19745
+ } else if (isTest(suiteOrTest)) {
19746
+ if (status && suiteOrTest.status && ["pending", "running", status].includes(suiteOrTest.status)) {
19747
+ filteredSuite.children = filteredSuite.children ?? {};
19748
+ filteredSuite.children[title] = suiteOrTest;
19749
+ }
19750
+ } else {
19751
+ const filteredSubSuite = filterTests(suiteOrTest, filter);
19752
+ if (getChildrenKeys(filteredSubSuite.children).length === 0) return;
19753
+ filteredSuite.children = filteredSuite.children ?? {};
19754
+ filteredSuite.children[title] = filteredSubSuite;
19755
+ }
19756
+ });
19757
+ return filteredSuite;
19591
19758
  }
19592
- function date4(params) {
19593
- return _coercedDate(ZodDate, params);
19759
+ function flattenSuite(suite) {
19760
+ if (!suite.opened) return [];
19761
+ return getChildrenEntries(suite.children).flatMap(([title, subSuite]) => [
19762
+ { title, suite: subSuite },
19763
+ ...isTest(subSuite) ? [] : flattenSuite(subSuite)
19764
+ ]);
19594
19765
  }
19595
-
19596
- // node_modules/zod/v4/classic/external.js
19597
- config(en_default());
19598
-
19599
- // src/schemas.ts
19600
- var LocationSchema = external_exports.object({
19601
- file: external_exports.string(),
19602
- line: external_exports.number()
19603
- });
19604
- var VisualSourceSchema = external_exports.enum(["comparison", "baseline-only", "declared-only"]);
19605
- var ImagesSchema = external_exports.object({
19606
- actual: external_exports.string().optional(),
19607
- expect: external_exports.string().optional(),
19608
- diff: external_exports.string().optional(),
19609
- error: external_exports.string().optional(),
19610
- source: VisualSourceSchema.optional()
19611
- });
19612
- var AttachmentSchema = external_exports.object({
19613
- name: external_exports.string(),
19614
- path: external_exports.string(),
19615
- contentType: external_exports.string()
19616
- });
19617
- var TestStatusSchema = external_exports.enum(["unknown", "pending", "running", "failed", "approved", "success", "retrying"]);
19618
- var TestResultStatusSchema = external_exports.enum(["failed", "success", "pending"]);
19619
- var TestResultSchema = external_exports.object({
19620
- status: TestResultStatusSchema,
19621
- retries: external_exports.number(),
19622
- images: external_exports.record(external_exports.string(), ImagesSchema).optional(),
19623
- error: external_exports.string().optional(),
19624
- duration: external_exports.number().optional()
19625
- });
19626
- var TestDataSchema = external_exports.object({
19627
- id: external_exports.string(),
19628
- titlePath: external_exports.array(external_exports.string()),
19629
- browser: external_exports.string(),
19630
- title: external_exports.string(),
19631
- skip: external_exports.union([external_exports.boolean(), external_exports.string()]).optional(),
19632
- retries: external_exports.number().optional(),
19633
- status: TestStatusSchema.optional(),
19634
- results: external_exports.array(TestResultSchema).optional(),
19635
- approved: external_exports.record(external_exports.string(), external_exports.number()).nullable().optional(),
19636
- attachments: external_exports.array(AttachmentSchema).optional(),
19637
- location: LocationSchema.optional()
19638
- });
19639
- var CrvyRprtrTestSchema = TestDataSchema.extend({
19640
- checked: external_exports.boolean()
19641
- });
19642
- var CrvyRprtrSuiteSchema = external_exports.lazy(
19643
- () => external_exports.object({
19644
- path: external_exports.array(external_exports.string()),
19645
- skip: external_exports.boolean(),
19646
- status: TestStatusSchema.optional(),
19647
- opened: external_exports.boolean(),
19648
- checked: external_exports.boolean(),
19649
- indeterminate: external_exports.boolean(),
19650
- children: external_exports.record(external_exports.string(), external_exports.union([CrvyRprtrSuiteSchema, CrvyRprtrTestSchema])).optional()
19651
- })
19652
- );
19653
- var WebSocketMessageSchema = external_exports.object({
19654
- type: external_exports.enum(["test-begin", "test-end", "run-end", "approve", "sync"]),
19655
- data: external_exports.unknown()
19656
- });
19657
- var TestBeginDataSchema = external_exports.object({
19658
- id: external_exports.string(),
19659
- title: external_exports.string(),
19660
- titlePath: external_exports.array(external_exports.string()),
19661
- browser: external_exports.string(),
19662
- location: LocationSchema
19663
- });
19664
- var TestEndDataSchema = external_exports.object({
19665
- id: external_exports.string(),
19666
- status: external_exports.enum(["passed", "failed", "skipped"]),
19667
- attachments: external_exports.array(AttachmentSchema),
19668
- visualNames: external_exports.array(external_exports.string()).default([]),
19669
- error: external_exports.string().optional(),
19670
- duration: external_exports.number().optional()
19671
- });
19672
- var ReportDataSchema = external_exports.object({
19673
- isRunning: external_exports.boolean(),
19674
- tests: external_exports.record(external_exports.string(), TestDataSchema),
19675
- browsers: external_exports.array(external_exports.string()),
19676
- isUpdateMode: external_exports.boolean(),
19677
- screenshotDir: external_exports.string()
19678
- });
19679
- var LoadedReportDataSchema = external_exports.object({
19680
- tests: external_exports.record(external_exports.string(), TestDataSchema).optional(),
19681
- isUpdateMode: external_exports.boolean().optional()
19682
- });
19683
- var OfflineEventSchema = external_exports.object({
19684
- type: external_exports.enum(["test-begin", "test-end", "run-end"]),
19685
- data: external_exports.unknown(),
19686
- timestamp: external_exports.number(),
19687
- workerIndex: external_exports.number()
19688
- });
19689
- var OfflineReportSchema = external_exports.object({
19690
- version: external_exports.number(),
19691
- generatedAt: external_exports.string(),
19692
- workers: external_exports.number(),
19693
- events: external_exports.array(OfflineEventSchema)
19694
- });
19695
- var ApproveRequestBodySchema = external_exports.object({
19696
- id: external_exports.string(),
19697
- retry: external_exports.number(),
19698
- image: external_exports.string()
19699
- });
19700
- var ReportApiResponseSchema = external_exports.object({
19701
- tests: external_exports.record(external_exports.string(), TestDataSchema),
19702
- isUpdateMode: external_exports.boolean().optional()
19703
- });
19704
- var ClientBootstrapDataSchema = external_exports.object({
19705
- report: ReportApiResponseSchema.extend({
19706
- isUpdateMode: external_exports.boolean()
19707
- }),
19708
- liveUpdates: external_exports.boolean(),
19709
- approvalEnabled: external_exports.boolean(),
19710
- approvalMessage: external_exports.string().optional()
19711
- });
19712
- var ImagesViewModeSchema = external_exports.enum(["side-by-side", "swap", "slide", "blend"]);
19713
- function safeParse3(schema, data) {
19714
- const result = schema.safeParse(data);
19715
- if (result.success) {
19716
- return result.data;
19766
+ function recalcSuiteStatuses(root10, testPath) {
19767
+ const ancestorPaths = testPath.slice(0, -1).map((_, index2, tokens) => tokens.slice(0, tokens.length - index2));
19768
+ for (const parentPath of ancestorPaths) {
19769
+ const parentSuite = getSuiteByPath(root10, parentPath);
19770
+ if (parentSuite && !isTest(parentSuite)) {
19771
+ parentSuite.status = getChildrenArray(parentSuite.children).map(({ status }) => status).reduce(calcStatus);
19772
+ }
19717
19773
  }
19718
- return null;
19774
+ root10.status = getChildrenArray(root10.children).map(({ status }) => status).reduce(calcStatus);
19775
+ }
19776
+ function recalcAllSuiteStatuses(suite) {
19777
+ for (const child2 of getChildrenArray(suite.children)) {
19778
+ if (!isTest(child2)) {
19779
+ recalcAllSuiteStatuses(child2);
19780
+ }
19781
+ }
19782
+ suite.status = getChildrenArray(suite.children).map(({ status }) => status).reduce(calcStatus);
19719
19783
  }
19720
19784
 
19721
19785
  // src/client/viewMode.ts
@@ -20935,8 +20999,9 @@ function App($$anchor, $$props) {
20935
20999
  }
20936
21000
  }
20937
21001
  async function handleImageApprove() {
20938
- if (!get2(openedTest)?.id || !get2(canApprove)) return;
20939
- await $$props.onApprove(get2(openedTest).id, get2(retry) - 1, get2(imageName));
21002
+ if (!get2(openedTest)?.id || !get2(canApprove)) return false;
21003
+ const approvalResult = await $$props.onApprove(get2(openedTest).id, get2(retry) - 1, get2(imageName));
21004
+ if (!approvalResult.success) return false;
20940
21005
  if (!get2(openedTest).approved) get2(openedTest).approved = {};
20941
21006
  get2(openedTest).approved[get2(imageName)] = get2(retry) - 1;
20942
21007
  const result = get2(openedTest).results?.[get2(retry) - 1];
@@ -20947,16 +21012,19 @@ function App($$anchor, $$props) {
20947
21012
  recalcSuiteStatuses(get2(tests), getTestPath(get2(openedTest)));
20948
21013
  }
20949
21014
  }
21015
+ return true;
20950
21016
  }
20951
21017
  async function handleApproveAndGoNext() {
20952
- await handleImageApprove();
20953
- handleGoToNextFailed();
21018
+ if (await handleImageApprove()) {
21019
+ handleGoToNextFailed();
21020
+ }
20954
21021
  }
20955
21022
  function getAllTests(suite) {
20956
21023
  return Object.values(suite.children).filter(isDefined).flatMap((child2) => isTest(child2) ? [child2] : getAllTests(child2));
20957
21024
  }
20958
21025
  async function handleApproveAllTests() {
20959
- await $$props.onApproveAll();
21026
+ const approvalResult = await $$props.onApproveAll();
21027
+ if (!isBulkApprovalOptimisticSafe(approvalResult)) return;
20960
21028
  getAllTests(get2(tests)).forEach((test) => {
20961
21029
  if (!test.results?.length) return;
20962
21030
  const lastIdx = test.results.length - 1;
@@ -21149,14 +21217,16 @@ async function loadReportData() {
21149
21217
  };
21150
21218
  }
21151
21219
  var handleApprove = async (id, retry, image) => {
21152
- await fetch("/api/approve", {
21220
+ const response = await fetch("/api/approve", {
21153
21221
  method: "POST",
21154
21222
  headers: { "Content-Type": "application/json" },
21155
21223
  body: JSON.stringify({ id, retry, image })
21156
21224
  });
21225
+ return readApproveResult(response);
21157
21226
  };
21158
21227
  var handleApproveAll = async () => {
21159
- await fetch("/api/approve-all", { method: "POST" });
21228
+ const response = await fetch("/api/approve-all", { method: "POST" });
21229
+ return readApproveAllResult(response);
21160
21230
  };
21161
21231
  var root9 = document.getElementById("root");
21162
21232
  root9.innerHTML = `<div style="display:flex;align-items:center;justify-content:center;height:100vh;color:#808080;font-size:14px">Loading\u2026</div>`;