bitfab 0.30.0 → 0.30.2
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/{chunk-FHCRK2P6.js → chunk-CPEQSNVE.js} +4 -4
- package/dist/{chunk-FHCRK2P6.js.map → chunk-CPEQSNVE.js.map} +1 -1
- package/dist/{chunk-2EFKQLJ7.js → chunk-FLVQ7Q3I.js} +204 -4
- package/dist/chunk-FLVQ7Q3I.js.map +1 -0
- package/dist/index.cjs +211 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/node.cjs +211 -4
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +2 -2
- package/dist/{replay-MSOW7LGF.js → replay-YJI2SUSN.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-2EFKQLJ7.js.map +0 -1
- /package/dist/{replay-MSOW7LGF.js.map → replay-YJI2SUSN.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1808,7 +1808,7 @@ declare class BitfabFunction {
|
|
|
1808
1808
|
/**
|
|
1809
1809
|
* SDK version from package.json (injected at build time)
|
|
1810
1810
|
*/
|
|
1811
|
-
declare const __version__ = "0.30.
|
|
1811
|
+
declare const __version__ = "0.30.2";
|
|
1812
1812
|
|
|
1813
1813
|
/**
|
|
1814
1814
|
* Constants for the Bitfab SDK.
|
package/dist/index.d.ts
CHANGED
|
@@ -1808,7 +1808,7 @@ declare class BitfabFunction {
|
|
|
1808
1808
|
/**
|
|
1809
1809
|
* SDK version from package.json (injected at build time)
|
|
1810
1810
|
*/
|
|
1811
|
-
declare const __version__ = "0.30.
|
|
1811
|
+
declare const __version__ = "0.30.2";
|
|
1812
1812
|
|
|
1813
1813
|
/**
|
|
1814
1814
|
* Constants for the Bitfab SDK.
|
package/dist/index.js
CHANGED
|
@@ -23,12 +23,12 @@ import {
|
|
|
23
23
|
flushTraces,
|
|
24
24
|
getCurrentSpan,
|
|
25
25
|
getCurrentTrace
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-CPEQSNVE.js";
|
|
27
27
|
import {
|
|
28
28
|
BITFAB_PROGRESS_PREFIX,
|
|
29
29
|
BitfabError,
|
|
30
30
|
reportReplayProgress
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-FLVQ7Q3I.js";
|
|
32
32
|
export {
|
|
33
33
|
BITFAB_PROGRESS_PREFIX,
|
|
34
34
|
Bitfab,
|
package/dist/node.cjs
CHANGED
|
@@ -336,6 +336,203 @@ var init_replayContext = __esm({
|
|
|
336
336
|
}
|
|
337
337
|
});
|
|
338
338
|
|
|
339
|
+
// src/codeChange.ts
|
|
340
|
+
async function resolveAutoCodeChange(label) {
|
|
341
|
+
if (typeof process === "undefined") {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
if (process.env?.BITFAB_DISABLE_CODE_CHANGE_CAPTURE) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const fromEnv = await readCodeChangeFile();
|
|
348
|
+
if (fromEnv) {
|
|
349
|
+
return fromEnv;
|
|
350
|
+
}
|
|
351
|
+
return captureCodeChangeFromGit(process.cwd?.() ?? ".", label);
|
|
352
|
+
}
|
|
353
|
+
async function readCodeChangeFile() {
|
|
354
|
+
const path = process.env?.BITFAB_CODE_CHANGE_PATH;
|
|
355
|
+
if (!path) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
const { readFile } = await import("fs/promises");
|
|
360
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
361
|
+
const files = Array.isArray(parsed?.files) && parsed.files.every(
|
|
362
|
+
(f) => typeof f === "object" && f !== null && !Array.isArray(f)
|
|
363
|
+
) ? parsed.files : void 0;
|
|
364
|
+
const description = typeof parsed?.description === "string" ? parsed.description : void 0;
|
|
365
|
+
if (!files && description === void 0) {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
return { description, files };
|
|
369
|
+
} catch {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
async function captureCodeChangeFromGit(cwd, label) {
|
|
374
|
+
let execFile;
|
|
375
|
+
let readFile;
|
|
376
|
+
try {
|
|
377
|
+
;
|
|
378
|
+
({ execFile } = await import("child_process"));
|
|
379
|
+
({ readFile } = await import("fs/promises"));
|
|
380
|
+
} catch {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
const git = (dir, args) => new Promise((resolve) => {
|
|
384
|
+
execFile(
|
|
385
|
+
"git",
|
|
386
|
+
args,
|
|
387
|
+
// 30s timeout so a hung git (e.g. a network-touching ref op) can't
|
|
388
|
+
// block the whole replay indefinitely.
|
|
389
|
+
{ cwd: dir, maxBuffer: 64 * 1024 * 1024, timeout: 3e4 },
|
|
390
|
+
(err, stdout) => resolve(err ? null : stdout)
|
|
391
|
+
);
|
|
392
|
+
});
|
|
393
|
+
try {
|
|
394
|
+
const root = (await git(cwd, ["rev-parse", "--show-toplevel"]))?.trim();
|
|
395
|
+
if (!root) {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
const resolved = await resolveBase(git, root);
|
|
399
|
+
if (!resolved) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
const { base, fromTrunk } = resolved;
|
|
403
|
+
const blobBytes = async (ref, path) => {
|
|
404
|
+
const out = await git(root, ["cat-file", "-s", `${ref}:${path}`]);
|
|
405
|
+
const n = out ? Number.parseInt(out.trim(), 10) : Number.NaN;
|
|
406
|
+
return Number.isFinite(n) ? n : 0;
|
|
407
|
+
};
|
|
408
|
+
const workingBytes = async (path) => {
|
|
409
|
+
try {
|
|
410
|
+
const { stat } = await import("fs/promises");
|
|
411
|
+
const { join } = await import("path");
|
|
412
|
+
return (await stat(join(root, path))).size;
|
|
413
|
+
} catch {
|
|
414
|
+
return 0;
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
const tracked = await git(root, [
|
|
418
|
+
"diff",
|
|
419
|
+
"--name-status",
|
|
420
|
+
"--no-renames",
|
|
421
|
+
"-z",
|
|
422
|
+
base,
|
|
423
|
+
"--",
|
|
424
|
+
":!.bitfab"
|
|
425
|
+
]);
|
|
426
|
+
const untracked = await git(root, [
|
|
427
|
+
"ls-files",
|
|
428
|
+
"--others",
|
|
429
|
+
"--exclude-standard",
|
|
430
|
+
"-z",
|
|
431
|
+
"--",
|
|
432
|
+
":!.bitfab"
|
|
433
|
+
]);
|
|
434
|
+
const entries = [
|
|
435
|
+
...parseNameStatusZ(tracked ?? ""),
|
|
436
|
+
...(untracked ?? "").split(NUL).filter((p) => p.length > 0).map((path) => ({ status: "A", path }))
|
|
437
|
+
];
|
|
438
|
+
if (entries.length === 0) {
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
const files = [];
|
|
442
|
+
let totalBytes = 0;
|
|
443
|
+
for (const { status, path } of entries) {
|
|
444
|
+
if (files.length >= MAX_FILES) {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
const beforeBytes = status === "A" ? 0 : await blobBytes(base, path);
|
|
448
|
+
const afterBytes = status === "D" ? 0 : await workingBytes(path);
|
|
449
|
+
if (beforeBytes > MAX_FILE_BYTES || afterBytes > MAX_FILE_BYTES) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
const before = (status === "A" ? "" : await git(root, ["show", `${base}:${path}`]) ?? "").replace(/\r\n/g, "\n");
|
|
453
|
+
const after = (status === "D" ? "" : await readWorkingFile(readFile, root, path)).replace(/\r\n/g, "\n");
|
|
454
|
+
if (before === after) {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
const size = Buffer.byteLength(before, "utf8") + Buffer.byteLength(after, "utf8");
|
|
458
|
+
if (totalBytes + size > MAX_TOTAL_BYTES || looksBinary(before) || looksBinary(after)) {
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
totalBytes += size;
|
|
462
|
+
files.push({ path, before, after });
|
|
463
|
+
}
|
|
464
|
+
if (files.length === 0) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
const subject = (await git(root, ["log", "-1", "--format=%s", "HEAD"]))?.trim();
|
|
468
|
+
const fileWord = files.length === 1 ? "file" : "files";
|
|
469
|
+
const head = label?.trim() || subject || "Working-tree change";
|
|
470
|
+
const against = fromTrunk ? "vs trunk" : "uncommitted (vs HEAD)";
|
|
471
|
+
return {
|
|
472
|
+
description: `${head} (${files.length} ${fileWord} changed ${against})`,
|
|
473
|
+
files
|
|
474
|
+
};
|
|
475
|
+
} catch {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
async function resolveBase(git, root) {
|
|
480
|
+
const forced = process.env?.BITFAB_CODE_CHANGE_BASE;
|
|
481
|
+
if (forced && await refExists(git, root, forced)) {
|
|
482
|
+
const base = (await git(root, ["merge-base", "HEAD", forced]))?.trim() || (await git(root, ["rev-parse", "--verify", forced]))?.trim() || null;
|
|
483
|
+
return base ? { base, fromTrunk: true } : null;
|
|
484
|
+
}
|
|
485
|
+
for (const candidate of TRUNK_CANDIDATES) {
|
|
486
|
+
if (!await refExists(git, root, candidate)) {
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
const mb = (await git(root, ["merge-base", "HEAD", candidate]))?.trim();
|
|
490
|
+
if (mb) {
|
|
491
|
+
return { base: mb, fromTrunk: true };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
return await refExists(git, root, "HEAD") ? { base: "HEAD", fromTrunk: false } : null;
|
|
495
|
+
}
|
|
496
|
+
async function refExists(git, root, ref) {
|
|
497
|
+
return await git(root, ["rev-parse", "--verify", `${ref}^{object}`]) !== null;
|
|
498
|
+
}
|
|
499
|
+
async function readWorkingFile(readFile, root, path) {
|
|
500
|
+
try {
|
|
501
|
+
const { join } = await import("path");
|
|
502
|
+
return await readFile(join(root, path), "utf8");
|
|
503
|
+
} catch {
|
|
504
|
+
return "";
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function parseNameStatusZ(raw) {
|
|
508
|
+
const parts = raw.split(NUL).filter((p) => p.length > 0);
|
|
509
|
+
const out = [];
|
|
510
|
+
for (let i = 0; i + 1 < parts.length; i += 2) {
|
|
511
|
+
out.push({ status: parts[i].charAt(0), path: parts[i + 1] });
|
|
512
|
+
}
|
|
513
|
+
return out;
|
|
514
|
+
}
|
|
515
|
+
function looksBinary(s) {
|
|
516
|
+
return s.slice(0, 8e3).includes(NUL);
|
|
517
|
+
}
|
|
518
|
+
var MAX_FILES, MAX_FILE_BYTES, MAX_TOTAL_BYTES, TRUNK_CANDIDATES, NUL;
|
|
519
|
+
var init_codeChange = __esm({
|
|
520
|
+
"src/codeChange.ts"() {
|
|
521
|
+
"use strict";
|
|
522
|
+
MAX_FILES = 60;
|
|
523
|
+
MAX_FILE_BYTES = 5e5;
|
|
524
|
+
MAX_TOTAL_BYTES = 2e6;
|
|
525
|
+
TRUNK_CANDIDATES = [
|
|
526
|
+
"origin/HEAD",
|
|
527
|
+
"origin/main",
|
|
528
|
+
"origin/master",
|
|
529
|
+
"main",
|
|
530
|
+
"master"
|
|
531
|
+
];
|
|
532
|
+
NUL = String.fromCharCode(0);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
|
|
339
536
|
// src/replay.ts
|
|
340
537
|
var replay_exports = {};
|
|
341
538
|
__export(replay_exports, {
|
|
@@ -560,6 +757,15 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
560
757
|
}
|
|
561
758
|
}
|
|
562
759
|
await replayContextReady;
|
|
760
|
+
let codeChangeDescription = options?.codeChangeDescription;
|
|
761
|
+
let codeChangeFiles = options?.codeChangeFiles;
|
|
762
|
+
if (codeChangeDescription === void 0 && codeChangeFiles === void 0) {
|
|
763
|
+
const captured = await resolveAutoCodeChange(options?.name);
|
|
764
|
+
if (captured) {
|
|
765
|
+
codeChangeDescription = captured.description;
|
|
766
|
+
codeChangeFiles = captured.files;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
563
769
|
const {
|
|
564
770
|
testRunId,
|
|
565
771
|
testRunUrl,
|
|
@@ -571,8 +777,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
571
777
|
options?.traceIds ? void 0 : options?.limit ?? 5,
|
|
572
778
|
options?.traceIds,
|
|
573
779
|
options?.name,
|
|
574
|
-
|
|
575
|
-
|
|
780
|
+
codeChangeDescription,
|
|
781
|
+
codeChangeFiles,
|
|
576
782
|
options?.environment !== void 0,
|
|
577
783
|
// includeDbBranchLease
|
|
578
784
|
options?.experimentGroupId,
|
|
@@ -606,7 +812,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
606
812
|
const resultItems = await mapWithConcurrency(
|
|
607
813
|
tasks,
|
|
608
814
|
maxConcurrency,
|
|
609
|
-
options?.onProgress ? (item
|
|
815
|
+
options?.onProgress ? (item) => {
|
|
610
816
|
completed += 1;
|
|
611
817
|
if (item.error === null) {
|
|
612
818
|
succeeded += 1;
|
|
@@ -728,6 +934,7 @@ var BITFAB_PROGRESS_PREFIX;
|
|
|
728
934
|
var init_replay = __esm({
|
|
729
935
|
"src/replay.ts"() {
|
|
730
936
|
"use strict";
|
|
937
|
+
init_codeChange();
|
|
731
938
|
init_errors();
|
|
732
939
|
init_mockOverride();
|
|
733
940
|
init_randomUuid();
|
|
@@ -770,7 +977,7 @@ registerAsyncLocalStorageClass(
|
|
|
770
977
|
);
|
|
771
978
|
|
|
772
979
|
// src/version.generated.ts
|
|
773
|
-
var __version__ = "0.30.
|
|
980
|
+
var __version__ = "0.30.2";
|
|
774
981
|
|
|
775
982
|
// src/constants.ts
|
|
776
983
|
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|