@clef-sh/core 0.1.16 → 0.1.18
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/compliance/generator.d.ts +19 -0
- package/dist/compliance/generator.d.ts.map +1 -0
- package/dist/compliance/run.d.ts +85 -0
- package/dist/compliance/run.d.ts.map +1 -0
- package/dist/compliance/types.d.ts +72 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/git/integration.d.ts +8 -5
- package/dist/git/integration.d.ts.map +1 -1
- package/dist/import/index.d.ts +7 -0
- package/dist/import/index.d.ts.map +1 -1
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +979 -318
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +913 -294
- package/dist/index.mjs.map +4 -4
- package/dist/lint/runner.d.ts +7 -0
- package/dist/lint/runner.d.ts.map +1 -1
- package/dist/merge/metadata-driver.d.ts +17 -0
- package/dist/merge/metadata-driver.d.ts.map +1 -0
- package/dist/pending/metadata.d.ts +40 -15
- package/dist/pending/metadata.d.ts.map +1 -1
- package/dist/policy/evaluator.d.ts +49 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/parser.d.ts +36 -0
- package/dist/policy/parser.d.ts.map +1 -0
- package/dist/policy/types.d.ts +101 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/scanner/index.d.ts +9 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/patterns.d.ts +12 -0
- package/dist/scanner/patterns.d.ts.map +1 -1
- package/dist/sops/client.d.ts.map +1 -1
- package/dist/types/index.d.ts +25 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -301,13 +301,13 @@ var require_lib = __commonJS({
|
|
|
301
301
|
"node_modules/write-file-atomic/lib/index.js"(exports, module) {
|
|
302
302
|
"use strict";
|
|
303
303
|
module.exports = writeFile;
|
|
304
|
-
module.exports.sync =
|
|
304
|
+
module.exports.sync = writeFileSync7;
|
|
305
305
|
module.exports._getTmpname = getTmpname;
|
|
306
306
|
module.exports._cleanupOnExit = cleanupOnExit;
|
|
307
|
-
var
|
|
307
|
+
var fs19 = __require("fs");
|
|
308
308
|
var crypto4 = __require("node:crypto");
|
|
309
309
|
var { onExit } = require_cjs();
|
|
310
|
-
var
|
|
310
|
+
var path26 = __require("path");
|
|
311
311
|
var { promisify } = __require("util");
|
|
312
312
|
var activeFiles = {};
|
|
313
313
|
var threadId = (function getId() {
|
|
@@ -325,7 +325,7 @@ var require_lib = __commonJS({
|
|
|
325
325
|
function cleanupOnExit(tmpfile) {
|
|
326
326
|
return () => {
|
|
327
327
|
try {
|
|
328
|
-
|
|
328
|
+
fs19.unlinkSync(typeof tmpfile === "function" ? tmpfile() : tmpfile);
|
|
329
329
|
} catch {
|
|
330
330
|
}
|
|
331
331
|
};
|
|
@@ -360,13 +360,13 @@ var require_lib = __commonJS({
|
|
|
360
360
|
let fd;
|
|
361
361
|
let tmpfile;
|
|
362
362
|
const removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile));
|
|
363
|
-
const absoluteName =
|
|
363
|
+
const absoluteName = path26.resolve(filename);
|
|
364
364
|
try {
|
|
365
365
|
await serializeActiveFile(absoluteName);
|
|
366
|
-
const truename = await promisify(
|
|
366
|
+
const truename = await promisify(fs19.realpath)(filename).catch(() => filename);
|
|
367
367
|
tmpfile = getTmpname(truename);
|
|
368
368
|
if (!options.mode || !options.chown) {
|
|
369
|
-
const stats = await promisify(
|
|
369
|
+
const stats = await promisify(fs19.stat)(truename).catch(() => {
|
|
370
370
|
});
|
|
371
371
|
if (stats) {
|
|
372
372
|
if (options.mode == null) {
|
|
@@ -377,45 +377,45 @@ var require_lib = __commonJS({
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
|
-
fd = await promisify(
|
|
380
|
+
fd = await promisify(fs19.open)(tmpfile, "w", options.mode);
|
|
381
381
|
if (options.tmpfileCreated) {
|
|
382
382
|
await options.tmpfileCreated(tmpfile);
|
|
383
383
|
}
|
|
384
384
|
if (ArrayBuffer.isView(data)) {
|
|
385
|
-
await promisify(
|
|
385
|
+
await promisify(fs19.write)(fd, data, 0, data.length, 0);
|
|
386
386
|
} else if (data != null) {
|
|
387
|
-
await promisify(
|
|
387
|
+
await promisify(fs19.write)(fd, String(data), 0, String(options.encoding || "utf8"));
|
|
388
388
|
}
|
|
389
389
|
if (options.fsync !== false) {
|
|
390
|
-
await promisify(
|
|
390
|
+
await promisify(fs19.fsync)(fd);
|
|
391
391
|
}
|
|
392
|
-
await promisify(
|
|
392
|
+
await promisify(fs19.close)(fd);
|
|
393
393
|
fd = null;
|
|
394
394
|
if (options.chown) {
|
|
395
|
-
await promisify(
|
|
395
|
+
await promisify(fs19.chown)(tmpfile, options.chown.uid, options.chown.gid).catch((err) => {
|
|
396
396
|
if (!isChownErrOk(err)) {
|
|
397
397
|
throw err;
|
|
398
398
|
}
|
|
399
399
|
});
|
|
400
400
|
}
|
|
401
401
|
if (options.mode) {
|
|
402
|
-
await promisify(
|
|
402
|
+
await promisify(fs19.chmod)(tmpfile, options.mode).catch((err) => {
|
|
403
403
|
if (!isChownErrOk(err)) {
|
|
404
404
|
throw err;
|
|
405
405
|
}
|
|
406
406
|
});
|
|
407
407
|
}
|
|
408
|
-
await promisify(
|
|
408
|
+
await promisify(fs19.rename)(tmpfile, truename);
|
|
409
409
|
} finally {
|
|
410
410
|
if (fd) {
|
|
411
|
-
await promisify(
|
|
411
|
+
await promisify(fs19.close)(fd).catch(
|
|
412
412
|
/* istanbul ignore next */
|
|
413
413
|
() => {
|
|
414
414
|
}
|
|
415
415
|
);
|
|
416
416
|
}
|
|
417
417
|
removeOnExitHandler();
|
|
418
|
-
await promisify(
|
|
418
|
+
await promisify(fs19.unlink)(tmpfile).catch(() => {
|
|
419
419
|
});
|
|
420
420
|
activeFiles[absoluteName].shift();
|
|
421
421
|
if (activeFiles[absoluteName].length > 0) {
|
|
@@ -441,20 +441,20 @@ var require_lib = __commonJS({
|
|
|
441
441
|
}
|
|
442
442
|
return promise;
|
|
443
443
|
}
|
|
444
|
-
function
|
|
444
|
+
function writeFileSync7(filename, data, options) {
|
|
445
445
|
if (typeof options === "string") {
|
|
446
446
|
options = { encoding: options };
|
|
447
447
|
} else if (!options) {
|
|
448
448
|
options = {};
|
|
449
449
|
}
|
|
450
450
|
try {
|
|
451
|
-
filename =
|
|
451
|
+
filename = fs19.realpathSync(filename);
|
|
452
452
|
} catch (ex) {
|
|
453
453
|
}
|
|
454
454
|
const tmpfile = getTmpname(filename);
|
|
455
455
|
if (!options.mode || !options.chown) {
|
|
456
456
|
try {
|
|
457
|
-
const stats =
|
|
457
|
+
const stats = fs19.statSync(filename);
|
|
458
458
|
options = Object.assign({}, options);
|
|
459
459
|
if (!options.mode) {
|
|
460
460
|
options.mode = stats.mode;
|
|
@@ -470,23 +470,23 @@ var require_lib = __commonJS({
|
|
|
470
470
|
const removeOnExitHandler = onExit(cleanup);
|
|
471
471
|
let threw = true;
|
|
472
472
|
try {
|
|
473
|
-
fd =
|
|
473
|
+
fd = fs19.openSync(tmpfile, "w", options.mode || 438);
|
|
474
474
|
if (options.tmpfileCreated) {
|
|
475
475
|
options.tmpfileCreated(tmpfile);
|
|
476
476
|
}
|
|
477
477
|
if (ArrayBuffer.isView(data)) {
|
|
478
|
-
|
|
478
|
+
fs19.writeSync(fd, data, 0, data.length, 0);
|
|
479
479
|
} else if (data != null) {
|
|
480
|
-
|
|
480
|
+
fs19.writeSync(fd, String(data), 0, String(options.encoding || "utf8"));
|
|
481
481
|
}
|
|
482
482
|
if (options.fsync !== false) {
|
|
483
|
-
|
|
483
|
+
fs19.fsyncSync(fd);
|
|
484
484
|
}
|
|
485
|
-
|
|
485
|
+
fs19.closeSync(fd);
|
|
486
486
|
fd = null;
|
|
487
487
|
if (options.chown) {
|
|
488
488
|
try {
|
|
489
|
-
|
|
489
|
+
fs19.chownSync(tmpfile, options.chown.uid, options.chown.gid);
|
|
490
490
|
} catch (err) {
|
|
491
491
|
if (!isChownErrOk(err)) {
|
|
492
492
|
throw err;
|
|
@@ -495,19 +495,19 @@ var require_lib = __commonJS({
|
|
|
495
495
|
}
|
|
496
496
|
if (options.mode) {
|
|
497
497
|
try {
|
|
498
|
-
|
|
498
|
+
fs19.chmodSync(tmpfile, options.mode);
|
|
499
499
|
} catch (err) {
|
|
500
500
|
if (!isChownErrOk(err)) {
|
|
501
501
|
throw err;
|
|
502
502
|
}
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
|
-
|
|
505
|
+
fs19.renameSync(tmpfile, filename);
|
|
506
506
|
threw = false;
|
|
507
507
|
} finally {
|
|
508
508
|
if (fd) {
|
|
509
509
|
try {
|
|
510
|
-
|
|
510
|
+
fs19.closeSync(fd);
|
|
511
511
|
} catch (ex) {
|
|
512
512
|
}
|
|
513
513
|
}
|
|
@@ -546,54 +546,54 @@ var require_polyfills = __commonJS({
|
|
|
546
546
|
}
|
|
547
547
|
var chdir;
|
|
548
548
|
module.exports = patch;
|
|
549
|
-
function patch(
|
|
549
|
+
function patch(fs19) {
|
|
550
550
|
if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
|
|
551
|
-
patchLchmod(
|
|
552
|
-
}
|
|
553
|
-
if (!
|
|
554
|
-
patchLutimes(
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (
|
|
575
|
-
|
|
551
|
+
patchLchmod(fs19);
|
|
552
|
+
}
|
|
553
|
+
if (!fs19.lutimes) {
|
|
554
|
+
patchLutimes(fs19);
|
|
555
|
+
}
|
|
556
|
+
fs19.chown = chownFix(fs19.chown);
|
|
557
|
+
fs19.fchown = chownFix(fs19.fchown);
|
|
558
|
+
fs19.lchown = chownFix(fs19.lchown);
|
|
559
|
+
fs19.chmod = chmodFix(fs19.chmod);
|
|
560
|
+
fs19.fchmod = chmodFix(fs19.fchmod);
|
|
561
|
+
fs19.lchmod = chmodFix(fs19.lchmod);
|
|
562
|
+
fs19.chownSync = chownFixSync(fs19.chownSync);
|
|
563
|
+
fs19.fchownSync = chownFixSync(fs19.fchownSync);
|
|
564
|
+
fs19.lchownSync = chownFixSync(fs19.lchownSync);
|
|
565
|
+
fs19.chmodSync = chmodFixSync(fs19.chmodSync);
|
|
566
|
+
fs19.fchmodSync = chmodFixSync(fs19.fchmodSync);
|
|
567
|
+
fs19.lchmodSync = chmodFixSync(fs19.lchmodSync);
|
|
568
|
+
fs19.stat = statFix(fs19.stat);
|
|
569
|
+
fs19.fstat = statFix(fs19.fstat);
|
|
570
|
+
fs19.lstat = statFix(fs19.lstat);
|
|
571
|
+
fs19.statSync = statFixSync(fs19.statSync);
|
|
572
|
+
fs19.fstatSync = statFixSync(fs19.fstatSync);
|
|
573
|
+
fs19.lstatSync = statFixSync(fs19.lstatSync);
|
|
574
|
+
if (fs19.chmod && !fs19.lchmod) {
|
|
575
|
+
fs19.lchmod = function(path26, mode, cb) {
|
|
576
576
|
if (cb) process.nextTick(cb);
|
|
577
577
|
};
|
|
578
|
-
|
|
578
|
+
fs19.lchmodSync = function() {
|
|
579
579
|
};
|
|
580
580
|
}
|
|
581
|
-
if (
|
|
582
|
-
|
|
581
|
+
if (fs19.chown && !fs19.lchown) {
|
|
582
|
+
fs19.lchown = function(path26, uid, gid, cb) {
|
|
583
583
|
if (cb) process.nextTick(cb);
|
|
584
584
|
};
|
|
585
|
-
|
|
585
|
+
fs19.lchownSync = function() {
|
|
586
586
|
};
|
|
587
587
|
}
|
|
588
588
|
if (platform === "win32") {
|
|
589
|
-
|
|
589
|
+
fs19.rename = typeof fs19.rename !== "function" ? fs19.rename : (function(fs$rename) {
|
|
590
590
|
function rename(from, to, cb) {
|
|
591
591
|
var start = Date.now();
|
|
592
592
|
var backoff = 0;
|
|
593
593
|
fs$rename(from, to, function CB(er) {
|
|
594
594
|
if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 6e4) {
|
|
595
595
|
setTimeout(function() {
|
|
596
|
-
|
|
596
|
+
fs19.stat(to, function(stater, st) {
|
|
597
597
|
if (stater && stater.code === "ENOENT")
|
|
598
598
|
fs$rename(from, to, CB);
|
|
599
599
|
else
|
|
@@ -609,9 +609,9 @@ var require_polyfills = __commonJS({
|
|
|
609
609
|
}
|
|
610
610
|
if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename);
|
|
611
611
|
return rename;
|
|
612
|
-
})(
|
|
612
|
+
})(fs19.rename);
|
|
613
613
|
}
|
|
614
|
-
|
|
614
|
+
fs19.read = typeof fs19.read !== "function" ? fs19.read : (function(fs$read) {
|
|
615
615
|
function read(fd, buffer, offset, length, position, callback_) {
|
|
616
616
|
var callback;
|
|
617
617
|
if (callback_ && typeof callback_ === "function") {
|
|
@@ -619,22 +619,22 @@ var require_polyfills = __commonJS({
|
|
|
619
619
|
callback = function(er, _, __) {
|
|
620
620
|
if (er && er.code === "EAGAIN" && eagCounter < 10) {
|
|
621
621
|
eagCounter++;
|
|
622
|
-
return fs$read.call(
|
|
622
|
+
return fs$read.call(fs19, fd, buffer, offset, length, position, callback);
|
|
623
623
|
}
|
|
624
624
|
callback_.apply(this, arguments);
|
|
625
625
|
};
|
|
626
626
|
}
|
|
627
|
-
return fs$read.call(
|
|
627
|
+
return fs$read.call(fs19, fd, buffer, offset, length, position, callback);
|
|
628
628
|
}
|
|
629
629
|
if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read);
|
|
630
630
|
return read;
|
|
631
|
-
})(
|
|
632
|
-
|
|
631
|
+
})(fs19.read);
|
|
632
|
+
fs19.readSync = typeof fs19.readSync !== "function" ? fs19.readSync : /* @__PURE__ */ (function(fs$readSync) {
|
|
633
633
|
return function(fd, buffer, offset, length, position) {
|
|
634
634
|
var eagCounter = 0;
|
|
635
635
|
while (true) {
|
|
636
636
|
try {
|
|
637
|
-
return fs$readSync.call(
|
|
637
|
+
return fs$readSync.call(fs19, fd, buffer, offset, length, position);
|
|
638
638
|
} catch (er) {
|
|
639
639
|
if (er.code === "EAGAIN" && eagCounter < 10) {
|
|
640
640
|
eagCounter++;
|
|
@@ -644,11 +644,11 @@ var require_polyfills = __commonJS({
|
|
|
644
644
|
}
|
|
645
645
|
}
|
|
646
646
|
};
|
|
647
|
-
})(
|
|
648
|
-
function patchLchmod(
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
647
|
+
})(fs19.readSync);
|
|
648
|
+
function patchLchmod(fs20) {
|
|
649
|
+
fs20.lchmod = function(path26, mode, callback) {
|
|
650
|
+
fs20.open(
|
|
651
|
+
path26,
|
|
652
652
|
constants.O_WRONLY | constants.O_SYMLINK,
|
|
653
653
|
mode,
|
|
654
654
|
function(err, fd) {
|
|
@@ -656,80 +656,80 @@ var require_polyfills = __commonJS({
|
|
|
656
656
|
if (callback) callback(err);
|
|
657
657
|
return;
|
|
658
658
|
}
|
|
659
|
-
|
|
660
|
-
|
|
659
|
+
fs20.fchmod(fd, mode, function(err2) {
|
|
660
|
+
fs20.close(fd, function(err22) {
|
|
661
661
|
if (callback) callback(err2 || err22);
|
|
662
662
|
});
|
|
663
663
|
});
|
|
664
664
|
}
|
|
665
665
|
);
|
|
666
666
|
};
|
|
667
|
-
|
|
668
|
-
var fd =
|
|
667
|
+
fs20.lchmodSync = function(path26, mode) {
|
|
668
|
+
var fd = fs20.openSync(path26, constants.O_WRONLY | constants.O_SYMLINK, mode);
|
|
669
669
|
var threw = true;
|
|
670
670
|
var ret;
|
|
671
671
|
try {
|
|
672
|
-
ret =
|
|
672
|
+
ret = fs20.fchmodSync(fd, mode);
|
|
673
673
|
threw = false;
|
|
674
674
|
} finally {
|
|
675
675
|
if (threw) {
|
|
676
676
|
try {
|
|
677
|
-
|
|
677
|
+
fs20.closeSync(fd);
|
|
678
678
|
} catch (er) {
|
|
679
679
|
}
|
|
680
680
|
} else {
|
|
681
|
-
|
|
681
|
+
fs20.closeSync(fd);
|
|
682
682
|
}
|
|
683
683
|
}
|
|
684
684
|
return ret;
|
|
685
685
|
};
|
|
686
686
|
}
|
|
687
|
-
function patchLutimes(
|
|
688
|
-
if (constants.hasOwnProperty("O_SYMLINK") &&
|
|
689
|
-
|
|
690
|
-
|
|
687
|
+
function patchLutimes(fs20) {
|
|
688
|
+
if (constants.hasOwnProperty("O_SYMLINK") && fs20.futimes) {
|
|
689
|
+
fs20.lutimes = function(path26, at, mt, cb) {
|
|
690
|
+
fs20.open(path26, constants.O_SYMLINK, function(er, fd) {
|
|
691
691
|
if (er) {
|
|
692
692
|
if (cb) cb(er);
|
|
693
693
|
return;
|
|
694
694
|
}
|
|
695
|
-
|
|
696
|
-
|
|
695
|
+
fs20.futimes(fd, at, mt, function(er2) {
|
|
696
|
+
fs20.close(fd, function(er22) {
|
|
697
697
|
if (cb) cb(er2 || er22);
|
|
698
698
|
});
|
|
699
699
|
});
|
|
700
700
|
});
|
|
701
701
|
};
|
|
702
|
-
|
|
703
|
-
var fd =
|
|
702
|
+
fs20.lutimesSync = function(path26, at, mt) {
|
|
703
|
+
var fd = fs20.openSync(path26, constants.O_SYMLINK);
|
|
704
704
|
var ret;
|
|
705
705
|
var threw = true;
|
|
706
706
|
try {
|
|
707
|
-
ret =
|
|
707
|
+
ret = fs20.futimesSync(fd, at, mt);
|
|
708
708
|
threw = false;
|
|
709
709
|
} finally {
|
|
710
710
|
if (threw) {
|
|
711
711
|
try {
|
|
712
|
-
|
|
712
|
+
fs20.closeSync(fd);
|
|
713
713
|
} catch (er) {
|
|
714
714
|
}
|
|
715
715
|
} else {
|
|
716
|
-
|
|
716
|
+
fs20.closeSync(fd);
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
return ret;
|
|
720
720
|
};
|
|
721
|
-
} else if (
|
|
722
|
-
|
|
721
|
+
} else if (fs20.futimes) {
|
|
722
|
+
fs20.lutimes = function(_a, _b, _c, cb) {
|
|
723
723
|
if (cb) process.nextTick(cb);
|
|
724
724
|
};
|
|
725
|
-
|
|
725
|
+
fs20.lutimesSync = function() {
|
|
726
726
|
};
|
|
727
727
|
}
|
|
728
728
|
}
|
|
729
729
|
function chmodFix(orig) {
|
|
730
730
|
if (!orig) return orig;
|
|
731
731
|
return function(target, mode, cb) {
|
|
732
|
-
return orig.call(
|
|
732
|
+
return orig.call(fs19, target, mode, function(er) {
|
|
733
733
|
if (chownErOk(er)) er = null;
|
|
734
734
|
if (cb) cb.apply(this, arguments);
|
|
735
735
|
});
|
|
@@ -739,7 +739,7 @@ var require_polyfills = __commonJS({
|
|
|
739
739
|
if (!orig) return orig;
|
|
740
740
|
return function(target, mode) {
|
|
741
741
|
try {
|
|
742
|
-
return orig.call(
|
|
742
|
+
return orig.call(fs19, target, mode);
|
|
743
743
|
} catch (er) {
|
|
744
744
|
if (!chownErOk(er)) throw er;
|
|
745
745
|
}
|
|
@@ -748,7 +748,7 @@ var require_polyfills = __commonJS({
|
|
|
748
748
|
function chownFix(orig) {
|
|
749
749
|
if (!orig) return orig;
|
|
750
750
|
return function(target, uid, gid, cb) {
|
|
751
|
-
return orig.call(
|
|
751
|
+
return orig.call(fs19, target, uid, gid, function(er) {
|
|
752
752
|
if (chownErOk(er)) er = null;
|
|
753
753
|
if (cb) cb.apply(this, arguments);
|
|
754
754
|
});
|
|
@@ -758,7 +758,7 @@ var require_polyfills = __commonJS({
|
|
|
758
758
|
if (!orig) return orig;
|
|
759
759
|
return function(target, uid, gid) {
|
|
760
760
|
try {
|
|
761
|
-
return orig.call(
|
|
761
|
+
return orig.call(fs19, target, uid, gid);
|
|
762
762
|
} catch (er) {
|
|
763
763
|
if (!chownErOk(er)) throw er;
|
|
764
764
|
}
|
|
@@ -778,13 +778,13 @@ var require_polyfills = __commonJS({
|
|
|
778
778
|
}
|
|
779
779
|
if (cb) cb.apply(this, arguments);
|
|
780
780
|
}
|
|
781
|
-
return options ? orig.call(
|
|
781
|
+
return options ? orig.call(fs19, target, options, callback) : orig.call(fs19, target, callback);
|
|
782
782
|
};
|
|
783
783
|
}
|
|
784
784
|
function statFixSync(orig) {
|
|
785
785
|
if (!orig) return orig;
|
|
786
786
|
return function(target, options) {
|
|
787
|
-
var stats = options ? orig.call(
|
|
787
|
+
var stats = options ? orig.call(fs19, target, options) : orig.call(fs19, target);
|
|
788
788
|
if (stats) {
|
|
789
789
|
if (stats.uid < 0) stats.uid += 4294967296;
|
|
790
790
|
if (stats.gid < 0) stats.gid += 4294967296;
|
|
@@ -813,16 +813,16 @@ var require_legacy_streams = __commonJS({
|
|
|
813
813
|
"../../node_modules/graceful-fs/legacy-streams.js"(exports, module) {
|
|
814
814
|
var Stream = __require("stream").Stream;
|
|
815
815
|
module.exports = legacy;
|
|
816
|
-
function legacy(
|
|
816
|
+
function legacy(fs19) {
|
|
817
817
|
return {
|
|
818
818
|
ReadStream,
|
|
819
819
|
WriteStream
|
|
820
820
|
};
|
|
821
|
-
function ReadStream(
|
|
822
|
-
if (!(this instanceof ReadStream)) return new ReadStream(
|
|
821
|
+
function ReadStream(path26, options) {
|
|
822
|
+
if (!(this instanceof ReadStream)) return new ReadStream(path26, options);
|
|
823
823
|
Stream.call(this);
|
|
824
824
|
var self = this;
|
|
825
|
-
this.path =
|
|
825
|
+
this.path = path26;
|
|
826
826
|
this.fd = null;
|
|
827
827
|
this.readable = true;
|
|
828
828
|
this.paused = false;
|
|
@@ -856,7 +856,7 @@ var require_legacy_streams = __commonJS({
|
|
|
856
856
|
});
|
|
857
857
|
return;
|
|
858
858
|
}
|
|
859
|
-
|
|
859
|
+
fs19.open(this.path, this.flags, this.mode, function(err, fd) {
|
|
860
860
|
if (err) {
|
|
861
861
|
self.emit("error", err);
|
|
862
862
|
self.readable = false;
|
|
@@ -867,10 +867,10 @@ var require_legacy_streams = __commonJS({
|
|
|
867
867
|
self._read();
|
|
868
868
|
});
|
|
869
869
|
}
|
|
870
|
-
function WriteStream(
|
|
871
|
-
if (!(this instanceof WriteStream)) return new WriteStream(
|
|
870
|
+
function WriteStream(path26, options) {
|
|
871
|
+
if (!(this instanceof WriteStream)) return new WriteStream(path26, options);
|
|
872
872
|
Stream.call(this);
|
|
873
|
-
this.path =
|
|
873
|
+
this.path = path26;
|
|
874
874
|
this.fd = null;
|
|
875
875
|
this.writable = true;
|
|
876
876
|
this.flags = "w";
|
|
@@ -895,7 +895,7 @@ var require_legacy_streams = __commonJS({
|
|
|
895
895
|
this.busy = false;
|
|
896
896
|
this._queue = [];
|
|
897
897
|
if (this.fd === null) {
|
|
898
|
-
this._open =
|
|
898
|
+
this._open = fs19.open;
|
|
899
899
|
this._queue.push([this._open, this.path, this.flags, this.mode, void 0]);
|
|
900
900
|
this.flush();
|
|
901
901
|
}
|
|
@@ -930,7 +930,7 @@ var require_clone = __commonJS({
|
|
|
930
930
|
// ../../node_modules/graceful-fs/graceful-fs.js
|
|
931
931
|
var require_graceful_fs = __commonJS({
|
|
932
932
|
"../../node_modules/graceful-fs/graceful-fs.js"(exports, module) {
|
|
933
|
-
var
|
|
933
|
+
var fs19 = __require("fs");
|
|
934
934
|
var polyfills = require_polyfills();
|
|
935
935
|
var legacy = require_legacy_streams();
|
|
936
936
|
var clone = require_clone();
|
|
@@ -962,12 +962,12 @@ var require_graceful_fs = __commonJS({
|
|
|
962
962
|
m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
|
|
963
963
|
console.error(m);
|
|
964
964
|
};
|
|
965
|
-
if (!
|
|
965
|
+
if (!fs19[gracefulQueue]) {
|
|
966
966
|
queue = global[gracefulQueue] || [];
|
|
967
|
-
publishQueue(
|
|
968
|
-
|
|
967
|
+
publishQueue(fs19, queue);
|
|
968
|
+
fs19.close = (function(fs$close) {
|
|
969
969
|
function close(fd, cb) {
|
|
970
|
-
return fs$close.call(
|
|
970
|
+
return fs$close.call(fs19, fd, function(err) {
|
|
971
971
|
if (!err) {
|
|
972
972
|
resetQueue();
|
|
973
973
|
}
|
|
@@ -979,48 +979,48 @@ var require_graceful_fs = __commonJS({
|
|
|
979
979
|
value: fs$close
|
|
980
980
|
});
|
|
981
981
|
return close;
|
|
982
|
-
})(
|
|
983
|
-
|
|
982
|
+
})(fs19.close);
|
|
983
|
+
fs19.closeSync = (function(fs$closeSync) {
|
|
984
984
|
function closeSync2(fd) {
|
|
985
|
-
fs$closeSync.apply(
|
|
985
|
+
fs$closeSync.apply(fs19, arguments);
|
|
986
986
|
resetQueue();
|
|
987
987
|
}
|
|
988
988
|
Object.defineProperty(closeSync2, previousSymbol, {
|
|
989
989
|
value: fs$closeSync
|
|
990
990
|
});
|
|
991
991
|
return closeSync2;
|
|
992
|
-
})(
|
|
992
|
+
})(fs19.closeSync);
|
|
993
993
|
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
|
|
994
994
|
process.on("exit", function() {
|
|
995
|
-
debug(
|
|
996
|
-
__require("assert").equal(
|
|
995
|
+
debug(fs19[gracefulQueue]);
|
|
996
|
+
__require("assert").equal(fs19[gracefulQueue].length, 0);
|
|
997
997
|
});
|
|
998
998
|
}
|
|
999
999
|
}
|
|
1000
1000
|
var queue;
|
|
1001
1001
|
if (!global[gracefulQueue]) {
|
|
1002
|
-
publishQueue(global,
|
|
1003
|
-
}
|
|
1004
|
-
module.exports = patch(clone(
|
|
1005
|
-
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !
|
|
1006
|
-
module.exports = patch(
|
|
1007
|
-
|
|
1008
|
-
}
|
|
1009
|
-
function patch(
|
|
1010
|
-
polyfills(
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
var fs$readFile =
|
|
1015
|
-
|
|
1016
|
-
function readFile(
|
|
1002
|
+
publishQueue(global, fs19[gracefulQueue]);
|
|
1003
|
+
}
|
|
1004
|
+
module.exports = patch(clone(fs19));
|
|
1005
|
+
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs19.__patched) {
|
|
1006
|
+
module.exports = patch(fs19);
|
|
1007
|
+
fs19.__patched = true;
|
|
1008
|
+
}
|
|
1009
|
+
function patch(fs20) {
|
|
1010
|
+
polyfills(fs20);
|
|
1011
|
+
fs20.gracefulify = patch;
|
|
1012
|
+
fs20.createReadStream = createReadStream;
|
|
1013
|
+
fs20.createWriteStream = createWriteStream;
|
|
1014
|
+
var fs$readFile = fs20.readFile;
|
|
1015
|
+
fs20.readFile = readFile;
|
|
1016
|
+
function readFile(path26, options, cb) {
|
|
1017
1017
|
if (typeof options === "function")
|
|
1018
1018
|
cb = options, options = null;
|
|
1019
|
-
return go$readFile(
|
|
1020
|
-
function go$readFile(
|
|
1021
|
-
return fs$readFile(
|
|
1019
|
+
return go$readFile(path26, options, cb);
|
|
1020
|
+
function go$readFile(path27, options2, cb2, startTime) {
|
|
1021
|
+
return fs$readFile(path27, options2, function(err) {
|
|
1022
1022
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1023
|
-
enqueue([go$readFile, [
|
|
1023
|
+
enqueue([go$readFile, [path27, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
1024
1024
|
else {
|
|
1025
1025
|
if (typeof cb2 === "function")
|
|
1026
1026
|
cb2.apply(this, arguments);
|
|
@@ -1028,16 +1028,16 @@ var require_graceful_fs = __commonJS({
|
|
|
1028
1028
|
});
|
|
1029
1029
|
}
|
|
1030
1030
|
}
|
|
1031
|
-
var fs$writeFile =
|
|
1032
|
-
|
|
1033
|
-
function writeFile(
|
|
1031
|
+
var fs$writeFile = fs20.writeFile;
|
|
1032
|
+
fs20.writeFile = writeFile;
|
|
1033
|
+
function writeFile(path26, data, options, cb) {
|
|
1034
1034
|
if (typeof options === "function")
|
|
1035
1035
|
cb = options, options = null;
|
|
1036
|
-
return go$writeFile(
|
|
1037
|
-
function go$writeFile(
|
|
1038
|
-
return fs$writeFile(
|
|
1036
|
+
return go$writeFile(path26, data, options, cb);
|
|
1037
|
+
function go$writeFile(path27, data2, options2, cb2, startTime) {
|
|
1038
|
+
return fs$writeFile(path27, data2, options2, function(err) {
|
|
1039
1039
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1040
|
-
enqueue([go$writeFile, [
|
|
1040
|
+
enqueue([go$writeFile, [path27, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
1041
1041
|
else {
|
|
1042
1042
|
if (typeof cb2 === "function")
|
|
1043
1043
|
cb2.apply(this, arguments);
|
|
@@ -1045,17 +1045,17 @@ var require_graceful_fs = __commonJS({
|
|
|
1045
1045
|
});
|
|
1046
1046
|
}
|
|
1047
1047
|
}
|
|
1048
|
-
var fs$appendFile =
|
|
1048
|
+
var fs$appendFile = fs20.appendFile;
|
|
1049
1049
|
if (fs$appendFile)
|
|
1050
|
-
|
|
1051
|
-
function appendFile(
|
|
1050
|
+
fs20.appendFile = appendFile;
|
|
1051
|
+
function appendFile(path26, data, options, cb) {
|
|
1052
1052
|
if (typeof options === "function")
|
|
1053
1053
|
cb = options, options = null;
|
|
1054
|
-
return go$appendFile(
|
|
1055
|
-
function go$appendFile(
|
|
1056
|
-
return fs$appendFile(
|
|
1054
|
+
return go$appendFile(path26, data, options, cb);
|
|
1055
|
+
function go$appendFile(path27, data2, options2, cb2, startTime) {
|
|
1056
|
+
return fs$appendFile(path27, data2, options2, function(err) {
|
|
1057
1057
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1058
|
-
enqueue([go$appendFile, [
|
|
1058
|
+
enqueue([go$appendFile, [path27, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
1059
1059
|
else {
|
|
1060
1060
|
if (typeof cb2 === "function")
|
|
1061
1061
|
cb2.apply(this, arguments);
|
|
@@ -1063,9 +1063,9 @@ var require_graceful_fs = __commonJS({
|
|
|
1063
1063
|
});
|
|
1064
1064
|
}
|
|
1065
1065
|
}
|
|
1066
|
-
var fs$copyFile =
|
|
1066
|
+
var fs$copyFile = fs20.copyFile;
|
|
1067
1067
|
if (fs$copyFile)
|
|
1068
|
-
|
|
1068
|
+
fs20.copyFile = copyFile;
|
|
1069
1069
|
function copyFile(src, dest, flags, cb) {
|
|
1070
1070
|
if (typeof flags === "function") {
|
|
1071
1071
|
cb = flags;
|
|
@@ -1083,34 +1083,34 @@ var require_graceful_fs = __commonJS({
|
|
|
1083
1083
|
});
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|
|
1086
|
-
var fs$readdir =
|
|
1087
|
-
|
|
1086
|
+
var fs$readdir = fs20.readdir;
|
|
1087
|
+
fs20.readdir = readdir;
|
|
1088
1088
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
1089
|
-
function readdir(
|
|
1089
|
+
function readdir(path26, options, cb) {
|
|
1090
1090
|
if (typeof options === "function")
|
|
1091
1091
|
cb = options, options = null;
|
|
1092
|
-
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(
|
|
1093
|
-
return fs$readdir(
|
|
1094
|
-
|
|
1092
|
+
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path27, options2, cb2, startTime) {
|
|
1093
|
+
return fs$readdir(path27, fs$readdirCallback(
|
|
1094
|
+
path27,
|
|
1095
1095
|
options2,
|
|
1096
1096
|
cb2,
|
|
1097
1097
|
startTime
|
|
1098
1098
|
));
|
|
1099
|
-
} : function go$readdir2(
|
|
1100
|
-
return fs$readdir(
|
|
1101
|
-
|
|
1099
|
+
} : function go$readdir2(path27, options2, cb2, startTime) {
|
|
1100
|
+
return fs$readdir(path27, options2, fs$readdirCallback(
|
|
1101
|
+
path27,
|
|
1102
1102
|
options2,
|
|
1103
1103
|
cb2,
|
|
1104
1104
|
startTime
|
|
1105
1105
|
));
|
|
1106
1106
|
};
|
|
1107
|
-
return go$readdir(
|
|
1108
|
-
function fs$readdirCallback(
|
|
1107
|
+
return go$readdir(path26, options, cb);
|
|
1108
|
+
function fs$readdirCallback(path27, options2, cb2, startTime) {
|
|
1109
1109
|
return function(err, files) {
|
|
1110
1110
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1111
1111
|
enqueue([
|
|
1112
1112
|
go$readdir,
|
|
1113
|
-
[
|
|
1113
|
+
[path27, options2, cb2],
|
|
1114
1114
|
err,
|
|
1115
1115
|
startTime || Date.now(),
|
|
1116
1116
|
Date.now()
|
|
@@ -1125,21 +1125,21 @@ var require_graceful_fs = __commonJS({
|
|
|
1125
1125
|
}
|
|
1126
1126
|
}
|
|
1127
1127
|
if (process.version.substr(0, 4) === "v0.8") {
|
|
1128
|
-
var legStreams = legacy(
|
|
1128
|
+
var legStreams = legacy(fs20);
|
|
1129
1129
|
ReadStream = legStreams.ReadStream;
|
|
1130
1130
|
WriteStream = legStreams.WriteStream;
|
|
1131
1131
|
}
|
|
1132
|
-
var fs$ReadStream =
|
|
1132
|
+
var fs$ReadStream = fs20.ReadStream;
|
|
1133
1133
|
if (fs$ReadStream) {
|
|
1134
1134
|
ReadStream.prototype = Object.create(fs$ReadStream.prototype);
|
|
1135
1135
|
ReadStream.prototype.open = ReadStream$open;
|
|
1136
1136
|
}
|
|
1137
|
-
var fs$WriteStream =
|
|
1137
|
+
var fs$WriteStream = fs20.WriteStream;
|
|
1138
1138
|
if (fs$WriteStream) {
|
|
1139
1139
|
WriteStream.prototype = Object.create(fs$WriteStream.prototype);
|
|
1140
1140
|
WriteStream.prototype.open = WriteStream$open;
|
|
1141
1141
|
}
|
|
1142
|
-
Object.defineProperty(
|
|
1142
|
+
Object.defineProperty(fs20, "ReadStream", {
|
|
1143
1143
|
get: function() {
|
|
1144
1144
|
return ReadStream;
|
|
1145
1145
|
},
|
|
@@ -1149,7 +1149,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1149
1149
|
enumerable: true,
|
|
1150
1150
|
configurable: true
|
|
1151
1151
|
});
|
|
1152
|
-
Object.defineProperty(
|
|
1152
|
+
Object.defineProperty(fs20, "WriteStream", {
|
|
1153
1153
|
get: function() {
|
|
1154
1154
|
return WriteStream;
|
|
1155
1155
|
},
|
|
@@ -1160,7 +1160,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1160
1160
|
configurable: true
|
|
1161
1161
|
});
|
|
1162
1162
|
var FileReadStream = ReadStream;
|
|
1163
|
-
Object.defineProperty(
|
|
1163
|
+
Object.defineProperty(fs20, "FileReadStream", {
|
|
1164
1164
|
get: function() {
|
|
1165
1165
|
return FileReadStream;
|
|
1166
1166
|
},
|
|
@@ -1171,7 +1171,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1171
1171
|
configurable: true
|
|
1172
1172
|
});
|
|
1173
1173
|
var FileWriteStream = WriteStream;
|
|
1174
|
-
Object.defineProperty(
|
|
1174
|
+
Object.defineProperty(fs20, "FileWriteStream", {
|
|
1175
1175
|
get: function() {
|
|
1176
1176
|
return FileWriteStream;
|
|
1177
1177
|
},
|
|
@@ -1181,7 +1181,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1181
1181
|
enumerable: true,
|
|
1182
1182
|
configurable: true
|
|
1183
1183
|
});
|
|
1184
|
-
function ReadStream(
|
|
1184
|
+
function ReadStream(path26, options) {
|
|
1185
1185
|
if (this instanceof ReadStream)
|
|
1186
1186
|
return fs$ReadStream.apply(this, arguments), this;
|
|
1187
1187
|
else
|
|
@@ -1201,7 +1201,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1201
1201
|
}
|
|
1202
1202
|
});
|
|
1203
1203
|
}
|
|
1204
|
-
function WriteStream(
|
|
1204
|
+
function WriteStream(path26, options) {
|
|
1205
1205
|
if (this instanceof WriteStream)
|
|
1206
1206
|
return fs$WriteStream.apply(this, arguments), this;
|
|
1207
1207
|
else
|
|
@@ -1219,22 +1219,22 @@ var require_graceful_fs = __commonJS({
|
|
|
1219
1219
|
}
|
|
1220
1220
|
});
|
|
1221
1221
|
}
|
|
1222
|
-
function createReadStream(
|
|
1223
|
-
return new
|
|
1222
|
+
function createReadStream(path26, options) {
|
|
1223
|
+
return new fs20.ReadStream(path26, options);
|
|
1224
1224
|
}
|
|
1225
|
-
function createWriteStream(
|
|
1226
|
-
return new
|
|
1225
|
+
function createWriteStream(path26, options) {
|
|
1226
|
+
return new fs20.WriteStream(path26, options);
|
|
1227
1227
|
}
|
|
1228
|
-
var fs$open =
|
|
1229
|
-
|
|
1230
|
-
function open(
|
|
1228
|
+
var fs$open = fs20.open;
|
|
1229
|
+
fs20.open = open;
|
|
1230
|
+
function open(path26, flags, mode, cb) {
|
|
1231
1231
|
if (typeof mode === "function")
|
|
1232
1232
|
cb = mode, mode = null;
|
|
1233
|
-
return go$open(
|
|
1234
|
-
function go$open(
|
|
1235
|
-
return fs$open(
|
|
1233
|
+
return go$open(path26, flags, mode, cb);
|
|
1234
|
+
function go$open(path27, flags2, mode2, cb2, startTime) {
|
|
1235
|
+
return fs$open(path27, flags2, mode2, function(err, fd) {
|
|
1236
1236
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1237
|
-
enqueue([go$open, [
|
|
1237
|
+
enqueue([go$open, [path27, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
1238
1238
|
else {
|
|
1239
1239
|
if (typeof cb2 === "function")
|
|
1240
1240
|
cb2.apply(this, arguments);
|
|
@@ -1242,20 +1242,20 @@ var require_graceful_fs = __commonJS({
|
|
|
1242
1242
|
});
|
|
1243
1243
|
}
|
|
1244
1244
|
}
|
|
1245
|
-
return
|
|
1245
|
+
return fs20;
|
|
1246
1246
|
}
|
|
1247
1247
|
function enqueue(elem) {
|
|
1248
1248
|
debug("ENQUEUE", elem[0].name, elem[1]);
|
|
1249
|
-
|
|
1249
|
+
fs19[gracefulQueue].push(elem);
|
|
1250
1250
|
retry();
|
|
1251
1251
|
}
|
|
1252
1252
|
var retryTimer;
|
|
1253
1253
|
function resetQueue() {
|
|
1254
1254
|
var now = Date.now();
|
|
1255
|
-
for (var i = 0; i <
|
|
1256
|
-
if (
|
|
1257
|
-
|
|
1258
|
-
|
|
1255
|
+
for (var i = 0; i < fs19[gracefulQueue].length; ++i) {
|
|
1256
|
+
if (fs19[gracefulQueue][i].length > 2) {
|
|
1257
|
+
fs19[gracefulQueue][i][3] = now;
|
|
1258
|
+
fs19[gracefulQueue][i][4] = now;
|
|
1259
1259
|
}
|
|
1260
1260
|
}
|
|
1261
1261
|
retry();
|
|
@@ -1263,9 +1263,9 @@ var require_graceful_fs = __commonJS({
|
|
|
1263
1263
|
function retry() {
|
|
1264
1264
|
clearTimeout(retryTimer);
|
|
1265
1265
|
retryTimer = void 0;
|
|
1266
|
-
if (
|
|
1266
|
+
if (fs19[gracefulQueue].length === 0)
|
|
1267
1267
|
return;
|
|
1268
|
-
var elem =
|
|
1268
|
+
var elem = fs19[gracefulQueue].shift();
|
|
1269
1269
|
var fn = elem[0];
|
|
1270
1270
|
var args = elem[1];
|
|
1271
1271
|
var err = elem[2];
|
|
@@ -1287,7 +1287,7 @@ var require_graceful_fs = __commonJS({
|
|
|
1287
1287
|
debug("RETRY", fn.name, args);
|
|
1288
1288
|
fn.apply(null, args.concat([startTime]));
|
|
1289
1289
|
} else {
|
|
1290
|
-
|
|
1290
|
+
fs19[gracefulQueue].push(elem);
|
|
1291
1291
|
}
|
|
1292
1292
|
}
|
|
1293
1293
|
if (retryTimer === void 0) {
|
|
@@ -1722,10 +1722,10 @@ var require_mtime_precision = __commonJS({
|
|
|
1722
1722
|
"../../node_modules/proper-lockfile/lib/mtime-precision.js"(exports, module) {
|
|
1723
1723
|
"use strict";
|
|
1724
1724
|
var cacheSymbol = /* @__PURE__ */ Symbol();
|
|
1725
|
-
function probe(file,
|
|
1726
|
-
const cachedPrecision =
|
|
1725
|
+
function probe(file, fs19, callback) {
|
|
1726
|
+
const cachedPrecision = fs19[cacheSymbol];
|
|
1727
1727
|
if (cachedPrecision) {
|
|
1728
|
-
return
|
|
1728
|
+
return fs19.stat(file, (err, stat) => {
|
|
1729
1729
|
if (err) {
|
|
1730
1730
|
return callback(err);
|
|
1731
1731
|
}
|
|
@@ -1733,16 +1733,16 @@ var require_mtime_precision = __commonJS({
|
|
|
1733
1733
|
});
|
|
1734
1734
|
}
|
|
1735
1735
|
const mtime = new Date(Math.ceil(Date.now() / 1e3) * 1e3 + 5);
|
|
1736
|
-
|
|
1736
|
+
fs19.utimes(file, mtime, mtime, (err) => {
|
|
1737
1737
|
if (err) {
|
|
1738
1738
|
return callback(err);
|
|
1739
1739
|
}
|
|
1740
|
-
|
|
1740
|
+
fs19.stat(file, (err2, stat) => {
|
|
1741
1741
|
if (err2) {
|
|
1742
1742
|
return callback(err2);
|
|
1743
1743
|
}
|
|
1744
1744
|
const precision = stat.mtime.getTime() % 1e3 === 0 ? "s" : "ms";
|
|
1745
|
-
Object.defineProperty(
|
|
1745
|
+
Object.defineProperty(fs19, cacheSymbol, { value: precision });
|
|
1746
1746
|
callback(null, stat.mtime, precision);
|
|
1747
1747
|
});
|
|
1748
1748
|
});
|
|
@@ -1763,8 +1763,8 @@ var require_mtime_precision = __commonJS({
|
|
|
1763
1763
|
var require_lockfile = __commonJS({
|
|
1764
1764
|
"../../node_modules/proper-lockfile/lib/lockfile.js"(exports, module) {
|
|
1765
1765
|
"use strict";
|
|
1766
|
-
var
|
|
1767
|
-
var
|
|
1766
|
+
var path26 = __require("path");
|
|
1767
|
+
var fs19 = require_graceful_fs();
|
|
1768
1768
|
var retry = require_retry2();
|
|
1769
1769
|
var onExit = require_signal_exit();
|
|
1770
1770
|
var mtimePrecision = require_mtime_precision();
|
|
@@ -1774,7 +1774,7 @@ var require_lockfile = __commonJS({
|
|
|
1774
1774
|
}
|
|
1775
1775
|
function resolveCanonicalPath(file, options, callback) {
|
|
1776
1776
|
if (!options.realpath) {
|
|
1777
|
-
return callback(null,
|
|
1777
|
+
return callback(null, path26.resolve(file));
|
|
1778
1778
|
}
|
|
1779
1779
|
options.fs.realpath(file, callback);
|
|
1780
1780
|
}
|
|
@@ -1895,7 +1895,7 @@ var require_lockfile = __commonJS({
|
|
|
1895
1895
|
update: null,
|
|
1896
1896
|
realpath: true,
|
|
1897
1897
|
retries: 0,
|
|
1898
|
-
fs:
|
|
1898
|
+
fs: fs19,
|
|
1899
1899
|
onCompromised: (err) => {
|
|
1900
1900
|
throw err;
|
|
1901
1901
|
},
|
|
@@ -1939,7 +1939,7 @@ var require_lockfile = __commonJS({
|
|
|
1939
1939
|
}
|
|
1940
1940
|
function unlock(file, options, callback) {
|
|
1941
1941
|
options = {
|
|
1942
|
-
fs:
|
|
1942
|
+
fs: fs19,
|
|
1943
1943
|
realpath: true,
|
|
1944
1944
|
...options
|
|
1945
1945
|
};
|
|
@@ -1961,7 +1961,7 @@ var require_lockfile = __commonJS({
|
|
|
1961
1961
|
options = {
|
|
1962
1962
|
stale: 1e4,
|
|
1963
1963
|
realpath: true,
|
|
1964
|
-
fs:
|
|
1964
|
+
fs: fs19,
|
|
1965
1965
|
...options
|
|
1966
1966
|
};
|
|
1967
1967
|
options.stale = Math.max(options.stale || 0, 2e3);
|
|
@@ -2000,16 +2000,16 @@ var require_lockfile = __commonJS({
|
|
|
2000
2000
|
var require_adapter = __commonJS({
|
|
2001
2001
|
"../../node_modules/proper-lockfile/lib/adapter.js"(exports, module) {
|
|
2002
2002
|
"use strict";
|
|
2003
|
-
var
|
|
2004
|
-
function createSyncFs(
|
|
2003
|
+
var fs19 = require_graceful_fs();
|
|
2004
|
+
function createSyncFs(fs20) {
|
|
2005
2005
|
const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
|
|
2006
|
-
const newFs = { ...
|
|
2006
|
+
const newFs = { ...fs20 };
|
|
2007
2007
|
methods.forEach((method) => {
|
|
2008
2008
|
newFs[method] = (...args) => {
|
|
2009
2009
|
const callback = args.pop();
|
|
2010
2010
|
let ret;
|
|
2011
2011
|
try {
|
|
2012
|
-
ret =
|
|
2012
|
+
ret = fs20[`${method}Sync`](...args);
|
|
2013
2013
|
} catch (err) {
|
|
2014
2014
|
return callback(err);
|
|
2015
2015
|
}
|
|
@@ -2047,7 +2047,7 @@ var require_adapter = __commonJS({
|
|
|
2047
2047
|
}
|
|
2048
2048
|
function toSyncOptions(options) {
|
|
2049
2049
|
options = { ...options };
|
|
2050
|
-
options.fs = createSyncFs(options.fs ||
|
|
2050
|
+
options.fs = createSyncFs(options.fs || fs19);
|
|
2051
2051
|
if (typeof options.retries === "number" && options.retries > 0 || options.retries && typeof options.retries.retries === "number" && options.retries.retries > 0) {
|
|
2052
2052
|
throw Object.assign(new Error("Cannot use retries with the sync api"), { code: "ESYNC" });
|
|
2053
2053
|
}
|
|
@@ -2161,6 +2161,13 @@ var GitOperationError = class extends ClefError {
|
|
|
2161
2161
|
this.name = "GitOperationError";
|
|
2162
2162
|
}
|
|
2163
2163
|
};
|
|
2164
|
+
var PolicyValidationError = class extends ClefError {
|
|
2165
|
+
constructor(message, field) {
|
|
2166
|
+
super(message, field ? `Check the '${field}' field in .clef/policy.yaml` : void 0);
|
|
2167
|
+
this.field = field;
|
|
2168
|
+
this.name = "PolicyValidationError";
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2164
2171
|
var SchemaLoadError = class extends ClefError {
|
|
2165
2172
|
constructor(message, filePath) {
|
|
2166
2173
|
super(
|
|
@@ -2835,6 +2842,20 @@ var PATTERNS = [
|
|
|
2835
2842
|
},
|
|
2836
2843
|
{ name: "Database URL", regex: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/ }
|
|
2837
2844
|
];
|
|
2845
|
+
var PUBLIC_PREFIX_PATTERNS = [
|
|
2846
|
+
// reCAPTCHA v2, v3, and Enterprise site keys are exactly 40 chars and
|
|
2847
|
+
// begin with 6L[c-f]. Site keys are designed to be embedded in HTML.
|
|
2848
|
+
// https://developers.google.com/recaptcha/docs/faq
|
|
2849
|
+
{ name: "reCAPTCHA site key", regex: /^6L[c-f][0-9A-Za-z_-]{37}$/ },
|
|
2850
|
+
// Stripe publishable keys (client-side, distinct from sk_live_/sk_test_).
|
|
2851
|
+
{ name: "Stripe publishable key", regex: /^pk_(?:live|test)_[0-9a-zA-Z]{24,}$/ }
|
|
2852
|
+
];
|
|
2853
|
+
function matchPublicPrefix(value) {
|
|
2854
|
+
for (const def of PUBLIC_PREFIX_PATTERNS) {
|
|
2855
|
+
if (def.regex.test(value)) return { name: def.name };
|
|
2856
|
+
}
|
|
2857
|
+
return null;
|
|
2858
|
+
}
|
|
2838
2859
|
function shannonEntropy(str) {
|
|
2839
2860
|
if (str.length === 0) return 0;
|
|
2840
2861
|
const freq = /* @__PURE__ */ new Map();
|
|
@@ -3023,7 +3044,8 @@ var ScanRunner = class {
|
|
|
3023
3044
|
}
|
|
3024
3045
|
}
|
|
3025
3046
|
if (options.severity !== "high") {
|
|
3026
|
-
const
|
|
3047
|
+
const allowPublic = options.publicAllowlist !== false;
|
|
3048
|
+
const entropyHit = this.detectEntropy(line, lineNum, relPath, allowPublic);
|
|
3027
3049
|
if (entropyHit && !shouldIgnoreMatch(entropyHit, ignoreRules)) {
|
|
3028
3050
|
matches.push(entropyHit);
|
|
3029
3051
|
}
|
|
@@ -3064,13 +3086,14 @@ var ScanRunner = class {
|
|
|
3064
3086
|
return false;
|
|
3065
3087
|
}
|
|
3066
3088
|
}
|
|
3067
|
-
detectEntropy(line, lineNum, filePath) {
|
|
3089
|
+
detectEntropy(line, lineNum, filePath, allowPublic) {
|
|
3068
3090
|
const valuePattern = /(?:=|:\s*)["']?([A-Za-z0-9+/=_-]{20,})["']?/;
|
|
3069
3091
|
const match = valuePattern.exec(line);
|
|
3070
3092
|
if (!match) return null;
|
|
3071
3093
|
const value = match[1];
|
|
3072
3094
|
const entropy = shannonEntropy(value);
|
|
3073
3095
|
if (!isHighEntropy(value)) return null;
|
|
3096
|
+
if (allowPublic && matchPublicPrefix(value)) return null;
|
|
3074
3097
|
const varMatch = /(\w+)\s*(?:=|:)/.exec(line);
|
|
3075
3098
|
const varName = varMatch ? varMatch[1] : "";
|
|
3076
3099
|
const preview = varName ? `${varName}=\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022` : redactValue(value);
|
|
@@ -3152,41 +3175,50 @@ function metadataPath(encryptedFilePath) {
|
|
|
3152
3175
|
return path4.join(dir, `${base}.clef-meta.yaml`);
|
|
3153
3176
|
}
|
|
3154
3177
|
var HEADER_COMMENT = "# Managed by Clef. Do not edit manually.\n";
|
|
3178
|
+
function emptyMetadata() {
|
|
3179
|
+
return { version: 1, pending: [], rotations: [] };
|
|
3180
|
+
}
|
|
3155
3181
|
async function loadMetadata(filePath) {
|
|
3156
3182
|
const metaPath = metadataPath(filePath);
|
|
3157
3183
|
try {
|
|
3158
|
-
if (!fs5.existsSync(metaPath))
|
|
3159
|
-
return { version: 1, pending: [] };
|
|
3160
|
-
}
|
|
3184
|
+
if (!fs5.existsSync(metaPath)) return emptyMetadata();
|
|
3161
3185
|
const content = fs5.readFileSync(metaPath, "utf-8");
|
|
3162
3186
|
const parsed = YAML3.parse(content);
|
|
3163
|
-
if (!parsed ||
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3187
|
+
if (!parsed || typeof parsed !== "object") return emptyMetadata();
|
|
3188
|
+
const pendingRaw = Array.isArray(parsed.pending) ? parsed.pending : [];
|
|
3189
|
+
const pending = pendingRaw.filter(
|
|
3190
|
+
(p) => !!p && typeof p === "object" && typeof p.key === "string" && typeof p.since === "string" && typeof p.setBy === "string"
|
|
3191
|
+
).map((p) => ({ key: p.key, since: new Date(p.since), setBy: p.setBy }));
|
|
3192
|
+
const rotationsRaw = Array.isArray(parsed.rotations) ? parsed.rotations : [];
|
|
3193
|
+
const rotations = rotationsRaw.filter(
|
|
3194
|
+
(r) => !!r && typeof r === "object" && typeof r.key === "string" && typeof r.last_rotated_at === "string" && typeof r.rotated_by === "string" && typeof r.rotation_count === "number"
|
|
3195
|
+
).map((r) => ({
|
|
3196
|
+
key: r.key,
|
|
3197
|
+
lastRotatedAt: new Date(r.last_rotated_at),
|
|
3198
|
+
rotatedBy: r.rotated_by,
|
|
3199
|
+
rotationCount: r.rotation_count
|
|
3200
|
+
}));
|
|
3201
|
+
return { version: 1, pending, rotations };
|
|
3174
3202
|
} catch {
|
|
3175
|
-
return
|
|
3203
|
+
return emptyMetadata();
|
|
3176
3204
|
}
|
|
3177
3205
|
}
|
|
3178
3206
|
async function saveMetadata(filePath, metadata) {
|
|
3179
3207
|
const metaPath = metadataPath(filePath);
|
|
3180
3208
|
const dir = path4.dirname(metaPath);
|
|
3181
|
-
if (!fs5.existsSync(dir)) {
|
|
3182
|
-
fs5.mkdirSync(dir, { recursive: true });
|
|
3183
|
-
}
|
|
3209
|
+
if (!fs5.existsSync(dir)) fs5.mkdirSync(dir, { recursive: true });
|
|
3184
3210
|
const data = {
|
|
3185
3211
|
version: metadata.version,
|
|
3186
3212
|
pending: metadata.pending.map((p) => ({
|
|
3187
3213
|
key: p.key,
|
|
3188
3214
|
since: p.since.toISOString(),
|
|
3189
3215
|
setBy: p.setBy
|
|
3216
|
+
})),
|
|
3217
|
+
rotations: metadata.rotations.map((r) => ({
|
|
3218
|
+
key: r.key,
|
|
3219
|
+
last_rotated_at: r.lastRotatedAt.toISOString(),
|
|
3220
|
+
rotated_by: r.rotatedBy,
|
|
3221
|
+
rotation_count: r.rotationCount
|
|
3190
3222
|
}))
|
|
3191
3223
|
};
|
|
3192
3224
|
fs5.writeFileSync(metaPath, HEADER_COMMENT + YAML3.stringify(data), "utf-8");
|
|
@@ -3217,6 +3249,38 @@ async function isPending(filePath, key) {
|
|
|
3217
3249
|
const metadata = await loadMetadata(filePath);
|
|
3218
3250
|
return metadata.pending.some((p) => p.key === key);
|
|
3219
3251
|
}
|
|
3252
|
+
async function recordRotation(filePath, keys, rotatedBy, now = /* @__PURE__ */ new Date()) {
|
|
3253
|
+
const metadata = await loadMetadata(filePath);
|
|
3254
|
+
for (const key of keys) {
|
|
3255
|
+
const existing = metadata.rotations.findIndex((r) => r.key === key);
|
|
3256
|
+
if (existing >= 0) {
|
|
3257
|
+
metadata.rotations[existing] = {
|
|
3258
|
+
key,
|
|
3259
|
+
lastRotatedAt: now,
|
|
3260
|
+
rotatedBy,
|
|
3261
|
+
rotationCount: metadata.rotations[existing].rotationCount + 1
|
|
3262
|
+
};
|
|
3263
|
+
} else {
|
|
3264
|
+
metadata.rotations.push({
|
|
3265
|
+
key,
|
|
3266
|
+
lastRotatedAt: now,
|
|
3267
|
+
rotatedBy,
|
|
3268
|
+
rotationCount: 1
|
|
3269
|
+
});
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
metadata.pending = metadata.pending.filter((p) => !keys.includes(p.key));
|
|
3273
|
+
await saveMetadata(filePath, metadata);
|
|
3274
|
+
}
|
|
3275
|
+
async function removeRotation(filePath, keys) {
|
|
3276
|
+
const metadata = await loadMetadata(filePath);
|
|
3277
|
+
metadata.rotations = metadata.rotations.filter((r) => !keys.includes(r.key));
|
|
3278
|
+
await saveMetadata(filePath, metadata);
|
|
3279
|
+
}
|
|
3280
|
+
async function getRotations(filePath) {
|
|
3281
|
+
const metadata = await loadMetadata(filePath);
|
|
3282
|
+
return metadata.rotations;
|
|
3283
|
+
}
|
|
3220
3284
|
function generateRandomValue() {
|
|
3221
3285
|
return crypto.randomBytes(32).toString("hex");
|
|
3222
3286
|
}
|
|
@@ -4018,61 +4082,83 @@ var GitIntegration = class {
|
|
|
4018
4082
|
* @throws {@link GitOperationError} On failure.
|
|
4019
4083
|
*/
|
|
4020
4084
|
async installMergeDriver(repoRoot) {
|
|
4021
|
-
const
|
|
4022
|
-
"
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
)
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4085
|
+
const drivers = [
|
|
4086
|
+
{ config: "merge.sops", friendly: "SOPS-aware merge driver" },
|
|
4087
|
+
{ config: "merge.clef-metadata", friendly: "Clef metadata merge driver" }
|
|
4088
|
+
];
|
|
4089
|
+
for (const driver of drivers) {
|
|
4090
|
+
const nameResult = await this.runner.run(
|
|
4091
|
+
"git",
|
|
4092
|
+
["config", `${driver.config}.name`, driver.friendly],
|
|
4093
|
+
{ cwd: repoRoot }
|
|
4030
4094
|
);
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4095
|
+
if (nameResult.exitCode !== 0) {
|
|
4096
|
+
throw new GitOperationError(
|
|
4097
|
+
`Failed to configure merge driver name: ${nameResult.stderr.trim()}`,
|
|
4098
|
+
"Ensure you are inside a git repository."
|
|
4099
|
+
);
|
|
4100
|
+
}
|
|
4101
|
+
const driverResult = await this.runner.run(
|
|
4102
|
+
"git",
|
|
4103
|
+
["config", `${driver.config}.driver`, "clef merge-driver %O %A %B"],
|
|
4104
|
+
{ cwd: repoRoot }
|
|
4041
4105
|
);
|
|
4106
|
+
if (driverResult.exitCode !== 0) {
|
|
4107
|
+
throw new GitOperationError(
|
|
4108
|
+
`Failed to configure merge driver command: ${driverResult.stderr.trim()}`,
|
|
4109
|
+
"Ensure you are inside a git repository."
|
|
4110
|
+
);
|
|
4111
|
+
}
|
|
4042
4112
|
}
|
|
4043
4113
|
await this.ensureGitattributes(repoRoot);
|
|
4044
4114
|
}
|
|
4045
4115
|
/**
|
|
4046
|
-
* Check whether
|
|
4047
|
-
*
|
|
4048
|
-
*
|
|
4049
|
-
*
|
|
4050
|
-
*
|
|
4116
|
+
* Check whether both Clef merge drivers are configured in `.git/config`
|
|
4117
|
+
* and `.gitattributes`. Reports separately on the SOPS driver
|
|
4118
|
+
* (`merge=sops` for `.enc.*`) and the metadata driver
|
|
4119
|
+
* (`merge=clef-metadata` for `.clef-meta.yaml`) so `clef doctor` can
|
|
4120
|
+
* prompt the user to run `clef hooks` when only the SOPS driver is
|
|
4121
|
+
* installed (older install, pre-metadata-merge).
|
|
4051
4122
|
*/
|
|
4052
4123
|
async checkMergeDriver(repoRoot) {
|
|
4053
|
-
const
|
|
4124
|
+
const sopsConfig = await this.runner.run("git", ["config", "--get", "merge.sops.driver"], {
|
|
4054
4125
|
cwd: repoRoot
|
|
4055
4126
|
});
|
|
4056
|
-
const gitConfig =
|
|
4127
|
+
const gitConfig = sopsConfig.exitCode === 0 && sopsConfig.stdout.trim().length > 0;
|
|
4128
|
+
const metaConfig = await this.runner.run(
|
|
4129
|
+
"git",
|
|
4130
|
+
["config", "--get", "merge.clef-metadata.driver"],
|
|
4131
|
+
{ cwd: repoRoot }
|
|
4132
|
+
);
|
|
4133
|
+
const metadataGitConfig = metaConfig.exitCode === 0 && metaConfig.stdout.trim().length > 0;
|
|
4057
4134
|
const attrFilePath = path8.join(repoRoot, ".gitattributes");
|
|
4058
4135
|
const attrContent = fs9.existsSync(attrFilePath) ? fs9.readFileSync(attrFilePath, "utf-8") : "";
|
|
4059
4136
|
const gitattributes = attrContent.includes("merge=sops");
|
|
4060
|
-
|
|
4137
|
+
const metadataGitattributes = attrContent.includes("merge=clef-metadata");
|
|
4138
|
+
return { gitConfig, gitattributes, metadataGitConfig, metadataGitattributes };
|
|
4061
4139
|
}
|
|
4062
4140
|
async ensureGitattributes(repoRoot) {
|
|
4063
4141
|
const attrPath = path8.join(repoRoot, ".gitattributes");
|
|
4064
|
-
const mergeRule = "*.enc.yaml merge=sops\n*.enc.json merge=sops";
|
|
4065
4142
|
const existing = fs9.existsSync(attrPath) ? fs9.readFileSync(attrPath, "utf-8") : "";
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4143
|
+
let newContent = existing;
|
|
4144
|
+
if (!existing.includes("merge=sops")) {
|
|
4145
|
+
const block = `# Clef: SOPS-aware merge driver for encrypted files
|
|
4146
|
+
*.enc.yaml merge=sops
|
|
4147
|
+
*.enc.json merge=sops
|
|
4148
|
+
`;
|
|
4149
|
+
newContent = newContent.trimEnd() ? `${newContent.trimEnd()}
|
|
4070
4150
|
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4151
|
+
${block}` : block;
|
|
4152
|
+
}
|
|
4153
|
+
if (!newContent.includes("merge=clef-metadata")) {
|
|
4154
|
+
const block = `# Clef: rotation-aware merge driver for metadata sidecars
|
|
4155
|
+
*.clef-meta.yaml merge=clef-metadata
|
|
4075
4156
|
`;
|
|
4157
|
+
newContent = newContent.trimEnd() ? `${newContent.trimEnd()}
|
|
4158
|
+
|
|
4159
|
+
${block}` : block;
|
|
4160
|
+
}
|
|
4161
|
+
if (newContent === existing) return;
|
|
4076
4162
|
try {
|
|
4077
4163
|
fs9.writeFileSync(attrPath, newContent, "utf-8");
|
|
4078
4164
|
} catch (err) {
|
|
@@ -4779,8 +4865,11 @@ var SopsClient = class {
|
|
|
4779
4865
|
}
|
|
4780
4866
|
const backend = this.detectBackend(sops);
|
|
4781
4867
|
const recipients = this.extractRecipients(sops, backend);
|
|
4782
|
-
const
|
|
4783
|
-
|
|
4868
|
+
const lastModifiedRaw = typeof sops.lastmodified === "string" ? sops.lastmodified : void 0;
|
|
4869
|
+
const lastModified = lastModifiedRaw ? new Date(lastModifiedRaw) : /* @__PURE__ */ new Date();
|
|
4870
|
+
const lastModifiedPresent = lastModifiedRaw !== void 0;
|
|
4871
|
+
const version = typeof sops.version === "string" ? sops.version : void 0;
|
|
4872
|
+
return { backend, recipients, lastModified, lastModifiedPresent, version };
|
|
4784
4873
|
}
|
|
4785
4874
|
detectBackend(sops) {
|
|
4786
4875
|
if (sops.age && Array.isArray(sops.age) && sops.age.length > 0) return "age";
|
|
@@ -5066,8 +5155,50 @@ var LintRunner = class {
|
|
|
5066
5155
|
);
|
|
5067
5156
|
issues.push(...siIssues);
|
|
5068
5157
|
}
|
|
5158
|
+
const metadataIssues = await this.lintMetadataConsistency(existingCells);
|
|
5159
|
+
issues.push(...metadataIssues);
|
|
5069
5160
|
return { issues, fileCount: fileCount + missingCells.length, pendingCount };
|
|
5070
5161
|
}
|
|
5162
|
+
/**
|
|
5163
|
+
* Cross-reference `.clef-meta.yaml` against the cipher's plaintext key
|
|
5164
|
+
* names for each existing cell. Reports orphan rotation records and
|
|
5165
|
+
* dual-state (pending + rotation) inconsistencies. Uses
|
|
5166
|
+
* {@link readSopsKeyNames} (plaintext YAML parse) — no decryption.
|
|
5167
|
+
*/
|
|
5168
|
+
async lintMetadataConsistency(cells) {
|
|
5169
|
+
const issues = [];
|
|
5170
|
+
for (const cell of cells) {
|
|
5171
|
+
const keysInCipher = readSopsKeyNames(cell.filePath);
|
|
5172
|
+
if (keysInCipher === null) continue;
|
|
5173
|
+
const cipherKeys = new Set(keysInCipher);
|
|
5174
|
+
const metadata = await loadMetadata(cell.filePath);
|
|
5175
|
+
for (const record of metadata.rotations) {
|
|
5176
|
+
if (!cipherKeys.has(record.key)) {
|
|
5177
|
+
issues.push({
|
|
5178
|
+
severity: "warning",
|
|
5179
|
+
category: "metadata",
|
|
5180
|
+
file: cell.filePath,
|
|
5181
|
+
key: record.key,
|
|
5182
|
+
message: `Rotation record exists for key '${record.key}' but the key is not in this cell. Remove the orphan entry from .clef-meta.yaml or re-add the key via clef set.`
|
|
5183
|
+
});
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
const pendingKeys = new Set(metadata.pending.map((p) => p.key));
|
|
5187
|
+
for (const record of metadata.rotations) {
|
|
5188
|
+
if (pendingKeys.has(record.key)) {
|
|
5189
|
+
issues.push({
|
|
5190
|
+
severity: "error",
|
|
5191
|
+
category: "metadata",
|
|
5192
|
+
file: cell.filePath,
|
|
5193
|
+
key: record.key,
|
|
5194
|
+
message: `Key '${record.key}' appears in both 'pending' and 'rotations' sections of .clef-meta.yaml. One of them is stale \u2014 likely a manual edit or a failed transaction. Re-run clef set to reconcile.`,
|
|
5195
|
+
fixCommand: `clef set ${cell.namespace}/${cell.environment} ${record.key}`
|
|
5196
|
+
});
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
return issues;
|
|
5201
|
+
}
|
|
5071
5202
|
/**
|
|
5072
5203
|
* Lint service identity configurations for drift issues.
|
|
5073
5204
|
*/
|
|
@@ -5420,22 +5551,33 @@ var ImportRunner = class {
|
|
|
5420
5551
|
}
|
|
5421
5552
|
const decrypted = await this.sopsClient.decrypt(filePath);
|
|
5422
5553
|
const newValues = { ...decrypted.values };
|
|
5554
|
+
const rotatedKeys = [];
|
|
5423
5555
|
for (const [key, value] of candidates) {
|
|
5424
|
-
|
|
5556
|
+
const existed = key in decrypted.values;
|
|
5557
|
+
if (existed && !options.overwrite) {
|
|
5425
5558
|
skipped.push(key);
|
|
5426
5559
|
continue;
|
|
5427
5560
|
}
|
|
5561
|
+
const valueChanged = !existed || decrypted.values[key] !== value;
|
|
5428
5562
|
newValues[key] = value;
|
|
5429
5563
|
imported.push(key);
|
|
5564
|
+
if (valueChanged) rotatedKeys.push(key);
|
|
5430
5565
|
}
|
|
5431
5566
|
if (imported.length === 0) {
|
|
5432
5567
|
return { imported, skipped, failed, warnings, dryRun: false };
|
|
5433
5568
|
}
|
|
5569
|
+
const relCellPath = path14.relative(repoRoot, filePath);
|
|
5570
|
+
const relMetaPath = relCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
5434
5571
|
await this.tx.run(repoRoot, {
|
|
5435
5572
|
description: `clef import ${target}: ${imported.length} key(s)`,
|
|
5436
|
-
|
|
5573
|
+
// Include the metadata path so rotation records created in the mutate
|
|
5574
|
+
// callback are staged and rolled back atomically with the ciphertext.
|
|
5575
|
+
paths: [relCellPath, relMetaPath],
|
|
5437
5576
|
mutate: async () => {
|
|
5438
5577
|
await this.sopsClient.encrypt(filePath, newValues, manifest, env);
|
|
5578
|
+
if (options.rotatedBy && rotatedKeys.length > 0) {
|
|
5579
|
+
await recordRotation(filePath, rotatedKeys, options.rotatedBy);
|
|
5580
|
+
}
|
|
5439
5581
|
}
|
|
5440
5582
|
});
|
|
5441
5583
|
return { imported, skipped, failed, warnings, dryRun: false };
|
|
@@ -6448,6 +6590,116 @@ var SopsMergeDriver = class {
|
|
|
6448
6590
|
}
|
|
6449
6591
|
};
|
|
6450
6592
|
|
|
6593
|
+
// src/merge/metadata-driver.ts
|
|
6594
|
+
import * as fs15 from "fs";
|
|
6595
|
+
import * as YAML10 from "yaml";
|
|
6596
|
+
var HEADER_COMMENT3 = "# Managed by Clef. Do not edit manually.\n";
|
|
6597
|
+
function parseMetadata(content) {
|
|
6598
|
+
try {
|
|
6599
|
+
const parsed = YAML10.parse(content);
|
|
6600
|
+
if (!parsed || typeof parsed !== "object") return emptyMetadata2();
|
|
6601
|
+
const pendingRaw = Array.isArray(parsed.pending) ? parsed.pending : [];
|
|
6602
|
+
const pending = pendingRaw.filter(
|
|
6603
|
+
(p) => !!p && typeof p === "object" && typeof p.key === "string" && typeof p.since === "string" && typeof p.setBy === "string"
|
|
6604
|
+
).map((p) => ({ key: p.key, since: new Date(p.since), setBy: p.setBy }));
|
|
6605
|
+
const rotationsRaw = Array.isArray(parsed.rotations) ? parsed.rotations : [];
|
|
6606
|
+
const rotations = rotationsRaw.filter(
|
|
6607
|
+
(r) => !!r && typeof r === "object" && typeof r.key === "string" && typeof r.last_rotated_at === "string" && typeof r.rotated_by === "string" && typeof r.rotation_count === "number"
|
|
6608
|
+
).map((r) => ({
|
|
6609
|
+
key: r.key,
|
|
6610
|
+
lastRotatedAt: new Date(r.last_rotated_at),
|
|
6611
|
+
rotatedBy: r.rotated_by,
|
|
6612
|
+
rotationCount: r.rotation_count
|
|
6613
|
+
}));
|
|
6614
|
+
return { version: 1, pending, rotations };
|
|
6615
|
+
} catch {
|
|
6616
|
+
return emptyMetadata2();
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6619
|
+
function emptyMetadata2() {
|
|
6620
|
+
return { version: 1, pending: [], rotations: [] };
|
|
6621
|
+
}
|
|
6622
|
+
function serializeMetadata(m) {
|
|
6623
|
+
const data = {
|
|
6624
|
+
version: m.version,
|
|
6625
|
+
pending: m.pending.map((p) => ({
|
|
6626
|
+
key: p.key,
|
|
6627
|
+
since: p.since.toISOString(),
|
|
6628
|
+
setBy: p.setBy
|
|
6629
|
+
})),
|
|
6630
|
+
rotations: m.rotations.map((r) => ({
|
|
6631
|
+
key: r.key,
|
|
6632
|
+
last_rotated_at: r.lastRotatedAt.toISOString(),
|
|
6633
|
+
rotated_by: r.rotatedBy,
|
|
6634
|
+
rotation_count: r.rotationCount
|
|
6635
|
+
}))
|
|
6636
|
+
};
|
|
6637
|
+
return HEADER_COMMENT3 + YAML10.stringify(data);
|
|
6638
|
+
}
|
|
6639
|
+
function mergeRotations(ours, theirs) {
|
|
6640
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
6641
|
+
const ourByKey = new Map(ours.map((r) => [r.key, r]));
|
|
6642
|
+
const theirByKey = new Map(theirs.map((r) => [r.key, r]));
|
|
6643
|
+
const allKeys = /* @__PURE__ */ new Set([...ourByKey.keys(), ...theirByKey.keys()]);
|
|
6644
|
+
for (const key of allKeys) {
|
|
6645
|
+
const o = ourByKey.get(key);
|
|
6646
|
+
const t = theirByKey.get(key);
|
|
6647
|
+
if (o && t) {
|
|
6648
|
+
const oTime = o.lastRotatedAt.getTime();
|
|
6649
|
+
const tTime = t.lastRotatedAt.getTime();
|
|
6650
|
+
const winner = tTime > oTime ? t : o;
|
|
6651
|
+
byKey.set(key, {
|
|
6652
|
+
key,
|
|
6653
|
+
lastRotatedAt: winner.lastRotatedAt,
|
|
6654
|
+
rotatedBy: winner.rotatedBy,
|
|
6655
|
+
rotationCount: Math.max(o.rotationCount, t.rotationCount) + 1
|
|
6656
|
+
});
|
|
6657
|
+
} else if (o) {
|
|
6658
|
+
byKey.set(key, o);
|
|
6659
|
+
} else if (t) {
|
|
6660
|
+
byKey.set(key, t);
|
|
6661
|
+
}
|
|
6662
|
+
}
|
|
6663
|
+
return Array.from(byKey.values());
|
|
6664
|
+
}
|
|
6665
|
+
function mergePending(oursPending, theirsPending, oursRotations, theirsRotations) {
|
|
6666
|
+
const ourByKey = new Map(oursPending.map((p) => [p.key, p]));
|
|
6667
|
+
const theirByKey = new Map(theirsPending.map((p) => [p.key, p]));
|
|
6668
|
+
const rotatedKeys = /* @__PURE__ */ new Set([
|
|
6669
|
+
...oursRotations.map((r) => r.key),
|
|
6670
|
+
...theirsRotations.map((r) => r.key)
|
|
6671
|
+
]);
|
|
6672
|
+
const allKeys = /* @__PURE__ */ new Set([...ourByKey.keys(), ...theirByKey.keys()]);
|
|
6673
|
+
const out = [];
|
|
6674
|
+
for (const key of allKeys) {
|
|
6675
|
+
if (rotatedKeys.has(key)) continue;
|
|
6676
|
+
const o = ourByKey.get(key);
|
|
6677
|
+
const t = theirByKey.get(key);
|
|
6678
|
+
if (o && t) {
|
|
6679
|
+
const winner = t.since.getTime() > o.since.getTime() ? t : o;
|
|
6680
|
+
out.push({ key, since: winner.since, setBy: winner.setBy });
|
|
6681
|
+
} else if (o) {
|
|
6682
|
+
out.push(o);
|
|
6683
|
+
} else if (t) {
|
|
6684
|
+
out.push(t);
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
return out;
|
|
6688
|
+
}
|
|
6689
|
+
function mergeMetadataContents(oursContent, theirsContent) {
|
|
6690
|
+
const ours = parseMetadata(oursContent);
|
|
6691
|
+
const theirs = parseMetadata(theirsContent);
|
|
6692
|
+
const rotations = mergeRotations(ours.rotations, theirs.rotations);
|
|
6693
|
+
const pending = mergePending(ours.pending, theirs.pending, ours.rotations, theirs.rotations);
|
|
6694
|
+
return serializeMetadata({ version: 1, pending, rotations });
|
|
6695
|
+
}
|
|
6696
|
+
function mergeMetadataFiles(_basePath, oursPath, theirsPath) {
|
|
6697
|
+
const oursContent = fs15.existsSync(oursPath) ? fs15.readFileSync(oursPath, "utf-8") : "";
|
|
6698
|
+
const theirsContent = fs15.existsSync(theirsPath) ? fs15.readFileSync(theirsPath, "utf-8") : "";
|
|
6699
|
+
const merged = mergeMetadataContents(oursContent, theirsContent);
|
|
6700
|
+
fs15.writeFileSync(oursPath, merged, "utf-8");
|
|
6701
|
+
}
|
|
6702
|
+
|
|
6451
6703
|
// src/service-identity/manager.ts
|
|
6452
6704
|
import * as path19 from "path";
|
|
6453
6705
|
var ServiceIdentityManager = class {
|
|
@@ -6983,7 +7235,7 @@ var ServiceIdentityManager = class {
|
|
|
6983
7235
|
};
|
|
6984
7236
|
|
|
6985
7237
|
// src/structure/manager.ts
|
|
6986
|
-
import * as
|
|
7238
|
+
import * as fs16 from "fs";
|
|
6987
7239
|
import * as path20 from "path";
|
|
6988
7240
|
var StructureManager = class {
|
|
6989
7241
|
constructor(matrixManager, encryption, tx) {
|
|
@@ -7011,7 +7263,7 @@ var StructureManager = class {
|
|
|
7011
7263
|
)
|
|
7012
7264
|
}));
|
|
7013
7265
|
for (const cell of newCellPaths) {
|
|
7014
|
-
if (
|
|
7266
|
+
if (fs16.existsSync(cell.filePath)) {
|
|
7015
7267
|
throw new Error(
|
|
7016
7268
|
`Cannot add namespace '${name}': file '${path20.relative(repoRoot, cell.filePath)}' already exists.`
|
|
7017
7269
|
);
|
|
@@ -7083,7 +7335,7 @@ var StructureManager = class {
|
|
|
7083
7335
|
)
|
|
7084
7336
|
}));
|
|
7085
7337
|
for (const cell of newCellPaths) {
|
|
7086
|
-
if (
|
|
7338
|
+
if (fs16.existsSync(cell.filePath)) {
|
|
7087
7339
|
throw new Error(
|
|
7088
7340
|
`Cannot add environment '${name}': file '${path20.relative(repoRoot, cell.filePath)}' already exists.`
|
|
7089
7341
|
);
|
|
@@ -7167,7 +7419,7 @@ var StructureManager = class {
|
|
|
7167
7419
|
paths: this.deletePaths(repoRoot, cellsToDelete),
|
|
7168
7420
|
mutate: async () => {
|
|
7169
7421
|
for (const cell of cellsToDelete) {
|
|
7170
|
-
|
|
7422
|
+
fs16.unlinkSync(cell.filePath);
|
|
7171
7423
|
this.unlinkMetaSibling(cell.filePath);
|
|
7172
7424
|
}
|
|
7173
7425
|
const doc = readManifestYaml(repoRoot);
|
|
@@ -7217,7 +7469,7 @@ var StructureManager = class {
|
|
|
7217
7469
|
paths: this.deletePaths(repoRoot, cellsToDelete),
|
|
7218
7470
|
mutate: async () => {
|
|
7219
7471
|
for (const cell of cellsToDelete) {
|
|
7220
|
-
|
|
7472
|
+
fs16.unlinkSync(cell.filePath);
|
|
7221
7473
|
this.unlinkMetaSibling(cell.filePath);
|
|
7222
7474
|
}
|
|
7223
7475
|
const doc = readManifestYaml(repoRoot);
|
|
@@ -7259,7 +7511,7 @@ var StructureManager = class {
|
|
|
7259
7511
|
const renamePairs = isRename ? this.collectRenamePairs(manifest, repoRoot, name, opts.rename, "namespace") : [];
|
|
7260
7512
|
if (isRename) {
|
|
7261
7513
|
for (const pair of renamePairs) {
|
|
7262
|
-
if (
|
|
7514
|
+
if (fs16.existsSync(pair.to)) {
|
|
7263
7515
|
throw new Error(
|
|
7264
7516
|
`Rename target '${path20.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
7265
7517
|
);
|
|
@@ -7302,7 +7554,7 @@ var StructureManager = class {
|
|
|
7302
7554
|
const renamePairs = isRename ? this.collectRenamePairs(manifest, repoRoot, name, opts.rename, "environment") : [];
|
|
7303
7555
|
if (isRename) {
|
|
7304
7556
|
for (const pair of renamePairs) {
|
|
7305
|
-
if (
|
|
7557
|
+
if (fs16.existsSync(pair.to)) {
|
|
7306
7558
|
throw new Error(
|
|
7307
7559
|
`Rename target '${path20.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
7308
7560
|
);
|
|
@@ -7339,7 +7591,7 @@ var StructureManager = class {
|
|
|
7339
7591
|
const newCellPath = this.swapAxisInCellPath(repoRoot, manifest, cell, axis, newName);
|
|
7340
7592
|
pairs.push({ from: cell.filePath, to: newCellPath });
|
|
7341
7593
|
const oldMeta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
7342
|
-
if (
|
|
7594
|
+
if (fs16.existsSync(oldMeta)) {
|
|
7343
7595
|
const newMeta = newCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
7344
7596
|
pairs.push({ from: oldMeta, to: newMeta });
|
|
7345
7597
|
}
|
|
@@ -7379,10 +7631,10 @@ var StructureManager = class {
|
|
|
7379
7631
|
applyRenames(pairs) {
|
|
7380
7632
|
for (const pair of pairs) {
|
|
7381
7633
|
const targetDir = path20.dirname(pair.to);
|
|
7382
|
-
if (!
|
|
7383
|
-
|
|
7634
|
+
if (!fs16.existsSync(targetDir)) {
|
|
7635
|
+
fs16.mkdirSync(targetDir, { recursive: true });
|
|
7384
7636
|
}
|
|
7385
|
-
|
|
7637
|
+
fs16.renameSync(pair.from, pair.to);
|
|
7386
7638
|
}
|
|
7387
7639
|
}
|
|
7388
7640
|
/**
|
|
@@ -7395,7 +7647,7 @@ var StructureManager = class {
|
|
|
7395
7647
|
for (const cell of cells) {
|
|
7396
7648
|
paths.add(path20.relative(repoRoot, cell.filePath));
|
|
7397
7649
|
const meta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
7398
|
-
if (
|
|
7650
|
+
if (fs16.existsSync(meta)) {
|
|
7399
7651
|
paths.add(path20.relative(repoRoot, meta));
|
|
7400
7652
|
}
|
|
7401
7653
|
}
|
|
@@ -7409,8 +7661,8 @@ var StructureManager = class {
|
|
|
7409
7661
|
*/
|
|
7410
7662
|
unlinkMetaSibling(cellPath) {
|
|
7411
7663
|
const meta = cellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
7412
|
-
if (
|
|
7413
|
-
|
|
7664
|
+
if (fs16.existsSync(meta)) {
|
|
7665
|
+
fs16.unlinkSync(meta);
|
|
7414
7666
|
}
|
|
7415
7667
|
}
|
|
7416
7668
|
/**
|
|
@@ -7555,7 +7807,7 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
|
|
|
7555
7807
|
import * as crypto3 from "crypto";
|
|
7556
7808
|
|
|
7557
7809
|
// src/artifact/output.ts
|
|
7558
|
-
import * as
|
|
7810
|
+
import * as fs17 from "fs";
|
|
7559
7811
|
import * as path21 from "path";
|
|
7560
7812
|
var FilePackOutput = class {
|
|
7561
7813
|
constructor(outputPath) {
|
|
@@ -7563,12 +7815,12 @@ var FilePackOutput = class {
|
|
|
7563
7815
|
}
|
|
7564
7816
|
async write(_artifact, json) {
|
|
7565
7817
|
const outputDir = path21.dirname(this.outputPath);
|
|
7566
|
-
if (!
|
|
7567
|
-
|
|
7818
|
+
if (!fs17.existsSync(outputDir)) {
|
|
7819
|
+
fs17.mkdirSync(outputDir, { recursive: true });
|
|
7568
7820
|
}
|
|
7569
7821
|
const tmpOutput = `${this.outputPath}.tmp.${process.pid}`;
|
|
7570
|
-
|
|
7571
|
-
|
|
7822
|
+
fs17.writeFileSync(tmpOutput, json, "utf-8");
|
|
7823
|
+
fs17.renameSync(tmpOutput, this.outputPath);
|
|
7572
7824
|
}
|
|
7573
7825
|
};
|
|
7574
7826
|
var MemoryPackOutput = class {
|
|
@@ -7790,7 +8042,7 @@ var VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
|
|
|
7790
8042
|
|
|
7791
8043
|
// src/migration/backend.ts
|
|
7792
8044
|
import * as path22 from "path";
|
|
7793
|
-
import * as
|
|
8045
|
+
import * as YAML11 from "yaml";
|
|
7794
8046
|
var BACKEND_KEY_FIELDS = {
|
|
7795
8047
|
age: void 0,
|
|
7796
8048
|
awskms: "aws_kms_arn",
|
|
@@ -7913,7 +8165,7 @@ var BackendMigrator = class {
|
|
|
7913
8165
|
const doc = readManifestYaml(repoRoot);
|
|
7914
8166
|
this.updateManifestDoc(doc, target, environment);
|
|
7915
8167
|
writeManifestYaml(repoRoot, doc);
|
|
7916
|
-
const updatedManifest =
|
|
8168
|
+
const updatedManifest = YAML11.parse(YAML11.stringify(doc));
|
|
7917
8169
|
for (const cell of toMigrate) {
|
|
7918
8170
|
onProgress?.({
|
|
7919
8171
|
type: "migrate",
|
|
@@ -8306,17 +8558,375 @@ var SyncManager = class {
|
|
|
8306
8558
|
};
|
|
8307
8559
|
}
|
|
8308
8560
|
};
|
|
8561
|
+
|
|
8562
|
+
// src/policy/parser.ts
|
|
8563
|
+
import * as fs18 from "fs";
|
|
8564
|
+
import * as YAML12 from "yaml";
|
|
8565
|
+
|
|
8566
|
+
// src/policy/types.ts
|
|
8567
|
+
var DEFAULT_POLICY = Object.freeze({
|
|
8568
|
+
version: 1,
|
|
8569
|
+
rotation: Object.freeze({ max_age_days: 90 })
|
|
8570
|
+
});
|
|
8571
|
+
|
|
8572
|
+
// src/policy/parser.ts
|
|
8573
|
+
var CLEF_POLICY_FILENAME = ".clef/policy.yaml";
|
|
8574
|
+
var SUPPORTED_VERSIONS = [1];
|
|
8575
|
+
var PolicyParser = class {
|
|
8576
|
+
/**
|
|
8577
|
+
* Read and validate a policy file from disk.
|
|
8578
|
+
*
|
|
8579
|
+
* @throws {@link PolicyValidationError} If the file cannot be read, contains
|
|
8580
|
+
* invalid YAML, or fails schema validation.
|
|
8581
|
+
*/
|
|
8582
|
+
parse(filePath) {
|
|
8583
|
+
let raw;
|
|
8584
|
+
try {
|
|
8585
|
+
raw = fs18.readFileSync(filePath, "utf-8");
|
|
8586
|
+
} catch {
|
|
8587
|
+
throw new PolicyValidationError(`Could not read policy file at '${filePath}'.`);
|
|
8588
|
+
}
|
|
8589
|
+
return this.parseContent(raw);
|
|
8590
|
+
}
|
|
8591
|
+
/**
|
|
8592
|
+
* Parse and validate a policy document from a YAML string.
|
|
8593
|
+
*
|
|
8594
|
+
* @throws {@link PolicyValidationError} If the content is malformed or
|
|
8595
|
+
* fails validation.
|
|
8596
|
+
*/
|
|
8597
|
+
parseContent(content) {
|
|
8598
|
+
let parsed;
|
|
8599
|
+
try {
|
|
8600
|
+
parsed = YAML12.parse(content);
|
|
8601
|
+
} catch {
|
|
8602
|
+
throw new PolicyValidationError(
|
|
8603
|
+
"Policy file contains invalid YAML. Check for syntax errors."
|
|
8604
|
+
);
|
|
8605
|
+
}
|
|
8606
|
+
return this.validate(parsed);
|
|
8607
|
+
}
|
|
8608
|
+
/**
|
|
8609
|
+
* Load policy from disk, returning {@link DEFAULT_POLICY} if the file does
|
|
8610
|
+
* not exist. Any other read or validation error throws.
|
|
8611
|
+
*/
|
|
8612
|
+
load(filePath) {
|
|
8613
|
+
if (!fs18.existsSync(filePath)) return DEFAULT_POLICY;
|
|
8614
|
+
return this.parse(filePath);
|
|
8615
|
+
}
|
|
8616
|
+
validate(raw) {
|
|
8617
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
8618
|
+
throw new PolicyValidationError("Policy file must be a YAML object.");
|
|
8619
|
+
}
|
|
8620
|
+
const doc = raw;
|
|
8621
|
+
if (!SUPPORTED_VERSIONS.includes(doc.version)) {
|
|
8622
|
+
throw new PolicyValidationError(
|
|
8623
|
+
`Policy file must declare 'version: 1', got: ${JSON.stringify(doc.version)}.`,
|
|
8624
|
+
"version"
|
|
8625
|
+
);
|
|
8626
|
+
}
|
|
8627
|
+
const rotation = doc.rotation === void 0 ? void 0 : this.validateRotation(doc.rotation);
|
|
8628
|
+
return { version: 1, ...rotation ? { rotation } : {} };
|
|
8629
|
+
}
|
|
8630
|
+
validateRotation(raw) {
|
|
8631
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
8632
|
+
throw new PolicyValidationError("Policy 'rotation' must be an object.", "rotation");
|
|
8633
|
+
}
|
|
8634
|
+
const rot = raw;
|
|
8635
|
+
const maxAge = rot.max_age_days;
|
|
8636
|
+
if (typeof maxAge !== "number" || !Number.isFinite(maxAge) || maxAge <= 0) {
|
|
8637
|
+
throw new PolicyValidationError(
|
|
8638
|
+
"Policy 'rotation.max_age_days' must be a positive number.",
|
|
8639
|
+
"rotation.max_age_days"
|
|
8640
|
+
);
|
|
8641
|
+
}
|
|
8642
|
+
const result = { max_age_days: maxAge };
|
|
8643
|
+
if (rot.environments !== void 0) {
|
|
8644
|
+
if (typeof rot.environments !== "object" || rot.environments === null || Array.isArray(rot.environments)) {
|
|
8645
|
+
throw new PolicyValidationError(
|
|
8646
|
+
"Policy 'rotation.environments' must be an object keyed by environment name.",
|
|
8647
|
+
"rotation.environments"
|
|
8648
|
+
);
|
|
8649
|
+
}
|
|
8650
|
+
const envs = {};
|
|
8651
|
+
for (const [envName, envVal] of Object.entries(rot.environments)) {
|
|
8652
|
+
if (typeof envVal !== "object" || envVal === null || Array.isArray(envVal)) {
|
|
8653
|
+
throw new PolicyValidationError(
|
|
8654
|
+
`Policy 'rotation.environments.${envName}' must be an object.`,
|
|
8655
|
+
`rotation.environments.${envName}`
|
|
8656
|
+
);
|
|
8657
|
+
}
|
|
8658
|
+
const envMaxAge = envVal.max_age_days;
|
|
8659
|
+
if (typeof envMaxAge !== "number" || !Number.isFinite(envMaxAge) || envMaxAge <= 0) {
|
|
8660
|
+
throw new PolicyValidationError(
|
|
8661
|
+
`Policy 'rotation.environments.${envName}.max_age_days' must be a positive number.`,
|
|
8662
|
+
`rotation.environments.${envName}.max_age_days`
|
|
8663
|
+
);
|
|
8664
|
+
}
|
|
8665
|
+
envs[envName] = { max_age_days: envMaxAge };
|
|
8666
|
+
}
|
|
8667
|
+
result.environments = envs;
|
|
8668
|
+
}
|
|
8669
|
+
return result;
|
|
8670
|
+
}
|
|
8671
|
+
};
|
|
8672
|
+
|
|
8673
|
+
// src/policy/evaluator.ts
|
|
8674
|
+
var MS_PER_DAY = 864e5;
|
|
8675
|
+
var DEFAULT_MAX_AGE_DAYS = 90;
|
|
8676
|
+
var PolicyEvaluator = class {
|
|
8677
|
+
constructor(policy) {
|
|
8678
|
+
this.policy = policy;
|
|
8679
|
+
}
|
|
8680
|
+
/**
|
|
8681
|
+
* Evaluate a single encrypted file's per-key rotation state.
|
|
8682
|
+
*
|
|
8683
|
+
* @param filePath Repo-relative or absolute path to the encrypted file.
|
|
8684
|
+
* @param environment Environment name; selects per-env overrides.
|
|
8685
|
+
* @param metadata SOPS metadata for the file (carries last_modified,
|
|
8686
|
+
* backend, recipients). The evaluator does not read
|
|
8687
|
+
* `last_modified` for the policy gate — it is echoed
|
|
8688
|
+
* into the output for audit consumers only.
|
|
8689
|
+
* @param keys Plaintext key names present in the cipher, enumerated
|
|
8690
|
+
* from the unencrypted YAML top-level keys (no decrypt
|
|
8691
|
+
* required since SOPS stores key names in plaintext).
|
|
8692
|
+
* @param rotations Rotation records from `.clef-meta.yaml`. Records for
|
|
8693
|
+
* keys not in `keys` are ignored (those are orphans;
|
|
8694
|
+
* lint surfaces them as a warning).
|
|
8695
|
+
* @param now Reference time. Inject for deterministic tests.
|
|
8696
|
+
*/
|
|
8697
|
+
evaluateFile(filePath, environment, metadata, keys, rotations, now = /* @__PURE__ */ new Date()) {
|
|
8698
|
+
const maxAgeDays = this.resolveMaxAgeDays(environment);
|
|
8699
|
+
const byKey = new Map(rotations.map((r) => [r.key, r]));
|
|
8700
|
+
const keyStatuses = keys.map(
|
|
8701
|
+
(key) => this.evaluateKey(key, byKey.get(key), maxAgeDays, now)
|
|
8702
|
+
);
|
|
8703
|
+
return {
|
|
8704
|
+
path: filePath,
|
|
8705
|
+
environment,
|
|
8706
|
+
backend: metadata.backend,
|
|
8707
|
+
recipients: metadata.recipients,
|
|
8708
|
+
last_modified: metadata.lastModified.toISOString(),
|
|
8709
|
+
last_modified_known: metadata.lastModifiedPresent !== false,
|
|
8710
|
+
keys: keyStatuses,
|
|
8711
|
+
// Cell-level compliance is the AND of per-key verdicts. An empty
|
|
8712
|
+
// `keys` array (cell with no secrets) is vacuously compliant.
|
|
8713
|
+
compliant: keyStatuses.every((k) => k.compliant)
|
|
8714
|
+
};
|
|
8715
|
+
}
|
|
8716
|
+
evaluateKey(key, record, maxAgeDays, now) {
|
|
8717
|
+
if (!record) {
|
|
8718
|
+
return {
|
|
8719
|
+
key,
|
|
8720
|
+
last_rotated_at: null,
|
|
8721
|
+
last_rotated_known: false,
|
|
8722
|
+
rotated_by: null,
|
|
8723
|
+
rotation_count: 0,
|
|
8724
|
+
rotation_due: null,
|
|
8725
|
+
rotation_overdue: false,
|
|
8726
|
+
days_overdue: 0,
|
|
8727
|
+
compliant: false
|
|
8728
|
+
};
|
|
8729
|
+
}
|
|
8730
|
+
const rotationDue = new Date(record.lastRotatedAt.getTime() + maxAgeDays * MS_PER_DAY);
|
|
8731
|
+
const rotationOverdue = now.getTime() > rotationDue.getTime();
|
|
8732
|
+
const daysOverdue = rotationOverdue ? Math.floor((now.getTime() - rotationDue.getTime()) / MS_PER_DAY) : 0;
|
|
8733
|
+
return {
|
|
8734
|
+
key,
|
|
8735
|
+
last_rotated_at: record.lastRotatedAt.toISOString(),
|
|
8736
|
+
last_rotated_known: true,
|
|
8737
|
+
rotated_by: record.rotatedBy,
|
|
8738
|
+
rotation_count: record.rotationCount,
|
|
8739
|
+
rotation_due: rotationDue.toISOString(),
|
|
8740
|
+
rotation_overdue: rotationOverdue,
|
|
8741
|
+
days_overdue: daysOverdue,
|
|
8742
|
+
compliant: !rotationOverdue
|
|
8743
|
+
};
|
|
8744
|
+
}
|
|
8745
|
+
resolveMaxAgeDays(environment) {
|
|
8746
|
+
const envOverride = this.policy.rotation?.environments?.[environment];
|
|
8747
|
+
if (envOverride !== void 0) return envOverride.max_age_days;
|
|
8748
|
+
return this.policy.rotation?.max_age_days ?? DEFAULT_MAX_AGE_DAYS;
|
|
8749
|
+
}
|
|
8750
|
+
};
|
|
8751
|
+
|
|
8752
|
+
// src/compliance/generator.ts
|
|
8753
|
+
import { createHash as createHash3 } from "crypto";
|
|
8754
|
+
var SCHEMA_VERSION = "1";
|
|
8755
|
+
function canonicalJson(value) {
|
|
8756
|
+
if (value === null || typeof value !== "object") {
|
|
8757
|
+
return JSON.stringify(value);
|
|
8758
|
+
}
|
|
8759
|
+
if (Array.isArray(value)) {
|
|
8760
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
8761
|
+
}
|
|
8762
|
+
const obj = value;
|
|
8763
|
+
const keys = Object.keys(obj).sort();
|
|
8764
|
+
const entries = keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(obj[k])}`);
|
|
8765
|
+
return `{${entries.join(",")}}`;
|
|
8766
|
+
}
|
|
8767
|
+
var ComplianceGenerator = class {
|
|
8768
|
+
generate(opts) {
|
|
8769
|
+
const { sha, repo, policy, scanResult, lintResult, files, now } = opts;
|
|
8770
|
+
const generated_at = (now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
8771
|
+
const policy_hash = `sha256:${createHash3("sha256").update(canonicalJson(policy)).digest("hex")}`;
|
|
8772
|
+
return {
|
|
8773
|
+
schema_version: SCHEMA_VERSION,
|
|
8774
|
+
generated_at,
|
|
8775
|
+
sha,
|
|
8776
|
+
repo,
|
|
8777
|
+
policy_hash,
|
|
8778
|
+
policy_snapshot: policy,
|
|
8779
|
+
summary: this.buildSummary(scanResult, lintResult, files),
|
|
8780
|
+
files,
|
|
8781
|
+
scan: scanResult,
|
|
8782
|
+
lint: lintResult
|
|
8783
|
+
};
|
|
8784
|
+
}
|
|
8785
|
+
/**
|
|
8786
|
+
* Compute a {@link ComplianceDocument.policy_hash}-format hash of any
|
|
8787
|
+
* {@link PolicyDocument} without generating a full document. Useful for
|
|
8788
|
+
* external consumers that want to compare policies across repos.
|
|
8789
|
+
*/
|
|
8790
|
+
static hashPolicy(policy) {
|
|
8791
|
+
return `sha256:${createHash3("sha256").update(canonicalJson(policy)).digest("hex")}`;
|
|
8792
|
+
}
|
|
8793
|
+
buildSummary(scan, lint, files) {
|
|
8794
|
+
const rotationOverdue = files.filter((f) => !f.compliant).length;
|
|
8795
|
+
return {
|
|
8796
|
+
total_files: files.length,
|
|
8797
|
+
compliant: files.filter((f) => f.compliant).length,
|
|
8798
|
+
rotation_overdue: rotationOverdue,
|
|
8799
|
+
scan_violations: scan.matches.length,
|
|
8800
|
+
lint_errors: lint.issues.filter((i) => i.severity === "error").length
|
|
8801
|
+
};
|
|
8802
|
+
}
|
|
8803
|
+
};
|
|
8804
|
+
|
|
8805
|
+
// src/compliance/run.ts
|
|
8806
|
+
import * as path25 from "path";
|
|
8807
|
+
var UNKNOWN = "unknown";
|
|
8808
|
+
async function runCompliance(opts) {
|
|
8809
|
+
const start = Date.now();
|
|
8810
|
+
const repoRoot = opts.repoRoot ?? process.cwd();
|
|
8811
|
+
const manifestPath = opts.manifestPath ?? path25.join(repoRoot, "clef.yaml");
|
|
8812
|
+
const policyPath = opts.policyPath ?? path25.join(repoRoot, CLEF_POLICY_FILENAME);
|
|
8813
|
+
const include = {
|
|
8814
|
+
scan: opts.include?.scan ?? true,
|
|
8815
|
+
lint: opts.include?.lint ?? true,
|
|
8816
|
+
rotation: opts.include?.rotation ?? true
|
|
8817
|
+
};
|
|
8818
|
+
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
8819
|
+
const manifest = new ManifestParser().parse(manifestPath);
|
|
8820
|
+
const policy = opts.policy ?? new PolicyParser().load(policyPath);
|
|
8821
|
+
const sopsClient = new SopsClient(opts.runner, opts.ageKeyFile, opts.ageKey, opts.sopsPath);
|
|
8822
|
+
const matrixManager = new MatrixManager();
|
|
8823
|
+
const schemaValidator = new SchemaValidator();
|
|
8824
|
+
const [sha, repo, files, scanResult, lintResult] = await Promise.all([
|
|
8825
|
+
opts.sha !== void 0 ? Promise.resolve(opts.sha) : detectSha(opts.runner, repoRoot),
|
|
8826
|
+
opts.repo !== void 0 ? Promise.resolve(opts.repo) : detectRepo(opts.runner, repoRoot),
|
|
8827
|
+
include.rotation ? evaluateMatrix({
|
|
8828
|
+
manifest,
|
|
8829
|
+
repoRoot,
|
|
8830
|
+
policy,
|
|
8831
|
+
matrixManager,
|
|
8832
|
+
sopsClient,
|
|
8833
|
+
filter: opts.filter,
|
|
8834
|
+
now
|
|
8835
|
+
}) : Promise.resolve([]),
|
|
8836
|
+
include.scan ? new ScanRunner(opts.runner).scan(repoRoot, manifest) : Promise.resolve(emptyScan()),
|
|
8837
|
+
include.lint ? new LintRunner(matrixManager, schemaValidator, sopsClient).run(manifest, repoRoot) : Promise.resolve(emptyLint())
|
|
8838
|
+
]);
|
|
8839
|
+
const adjustedLint = downgradeDecryptIssues(lintResult);
|
|
8840
|
+
const document = new ComplianceGenerator().generate({
|
|
8841
|
+
sha,
|
|
8842
|
+
repo,
|
|
8843
|
+
policy,
|
|
8844
|
+
scanResult,
|
|
8845
|
+
lintResult: adjustedLint,
|
|
8846
|
+
files,
|
|
8847
|
+
now
|
|
8848
|
+
});
|
|
8849
|
+
const passed = document.summary.rotation_overdue === 0 && document.summary.scan_violations === 0 && document.summary.lint_errors === 0;
|
|
8850
|
+
return { document, passed, durationMs: Date.now() - start };
|
|
8851
|
+
}
|
|
8852
|
+
async function evaluateMatrix(args) {
|
|
8853
|
+
const evaluator = new PolicyEvaluator(args.policy);
|
|
8854
|
+
const cells = args.matrixManager.resolveMatrix(args.manifest, args.repoRoot).filter((c) => applyFilter(c.namespace, c.environment, args.filter)).filter((c) => c.exists);
|
|
8855
|
+
return Promise.all(
|
|
8856
|
+
cells.map(async (cell) => {
|
|
8857
|
+
const metadata = await args.sopsClient.getMetadata(cell.filePath);
|
|
8858
|
+
const relPath = path25.relative(args.repoRoot, cell.filePath).replace(/\\/g, "/");
|
|
8859
|
+
const keys = readSopsKeyNames(cell.filePath) ?? [];
|
|
8860
|
+
const rotations = await getRotations(cell.filePath);
|
|
8861
|
+
return evaluator.evaluateFile(relPath, cell.environment, metadata, keys, rotations, args.now);
|
|
8862
|
+
})
|
|
8863
|
+
);
|
|
8864
|
+
}
|
|
8865
|
+
function applyFilter(namespace, environment, filter) {
|
|
8866
|
+
if (filter?.namespaces?.length && !filter.namespaces.includes(namespace)) return false;
|
|
8867
|
+
if (filter?.environments?.length && !filter.environments.includes(environment)) return false;
|
|
8868
|
+
return true;
|
|
8869
|
+
}
|
|
8870
|
+
function emptyScan() {
|
|
8871
|
+
return {
|
|
8872
|
+
matches: [],
|
|
8873
|
+
filesScanned: 0,
|
|
8874
|
+
filesSkipped: 0,
|
|
8875
|
+
unencryptedMatrixFiles: [],
|
|
8876
|
+
durationMs: 0
|
|
8877
|
+
};
|
|
8878
|
+
}
|
|
8879
|
+
function emptyLint() {
|
|
8880
|
+
return { issues: [], fileCount: 0, pendingCount: 0 };
|
|
8881
|
+
}
|
|
8882
|
+
function downgradeDecryptIssues(result) {
|
|
8883
|
+
return {
|
|
8884
|
+
...result,
|
|
8885
|
+
issues: result.issues.map((issue) => {
|
|
8886
|
+
if (issue.category === "sops" && issue.message.startsWith("Failed to decrypt")) {
|
|
8887
|
+
return {
|
|
8888
|
+
...issue,
|
|
8889
|
+
severity: "info",
|
|
8890
|
+
message: `File not decryptable in this environment (compliance runs without keys). Original check: ${issue.message}`
|
|
8891
|
+
};
|
|
8892
|
+
}
|
|
8893
|
+
return issue;
|
|
8894
|
+
})
|
|
8895
|
+
};
|
|
8896
|
+
}
|
|
8897
|
+
async function detectSha(runner, repoRoot) {
|
|
8898
|
+
const env = process.env;
|
|
8899
|
+
const fromEnv = env.GITHUB_SHA ?? env.CI_COMMIT_SHA ?? env.BITBUCKET_COMMIT ?? env.CIRCLE_SHA1 ?? env.BUILD_VCS_NUMBER;
|
|
8900
|
+
if (fromEnv) return fromEnv;
|
|
8901
|
+
const result = await runner.run("git", ["rev-parse", "HEAD"], { cwd: repoRoot });
|
|
8902
|
+
if (result.exitCode !== 0) return UNKNOWN;
|
|
8903
|
+
const trimmed = result.stdout.trim();
|
|
8904
|
+
return trimmed || UNKNOWN;
|
|
8905
|
+
}
|
|
8906
|
+
async function detectRepo(runner, repoRoot) {
|
|
8907
|
+
const env = process.env;
|
|
8908
|
+
const fromEnv = env.GITHUB_REPOSITORY ?? env.CI_PROJECT_PATH ?? env.BITBUCKET_REPO_FULL_NAME ?? (env.CIRCLE_PROJECT_USERNAME && env.CIRCLE_PROJECT_REPONAME ? `${env.CIRCLE_PROJECT_USERNAME}/${env.CIRCLE_PROJECT_REPONAME}` : void 0);
|
|
8909
|
+
if (fromEnv) return fromEnv;
|
|
8910
|
+
const result = await runner.run("git", ["remote", "get-url", "origin"], { cwd: repoRoot });
|
|
8911
|
+
if (result.exitCode !== 0) return UNKNOWN;
|
|
8912
|
+
const url = result.stdout.trim();
|
|
8913
|
+
const match = url.match(/[:/]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
8914
|
+
return match ? `${match[1]}/${match[2]}` : UNKNOWN;
|
|
8915
|
+
}
|
|
8309
8916
|
export {
|
|
8310
8917
|
ArtifactPacker,
|
|
8311
8918
|
BackendMigrator,
|
|
8312
8919
|
BulkOps,
|
|
8313
8920
|
CLEF_MANIFEST_FILENAME,
|
|
8921
|
+
CLEF_POLICY_FILENAME,
|
|
8314
8922
|
CLEF_REPORT_SCHEMA_VERSION,
|
|
8315
8923
|
CLEF_SUPPORTED_EXTENSIONS,
|
|
8316
8924
|
ClefError,
|
|
8317
8925
|
CloudApiError,
|
|
8318
8926
|
CloudClient,
|
|
8927
|
+
ComplianceGenerator,
|
|
8319
8928
|
ConsumptionClient,
|
|
8929
|
+
DEFAULT_POLICY,
|
|
8320
8930
|
DiffEngine,
|
|
8321
8931
|
DriftDetector,
|
|
8322
8932
|
FilePackOutput,
|
|
@@ -8328,6 +8938,9 @@ export {
|
|
|
8328
8938
|
ManifestValidationError,
|
|
8329
8939
|
MatrixManager,
|
|
8330
8940
|
MemoryPackOutput,
|
|
8941
|
+
PolicyEvaluator,
|
|
8942
|
+
PolicyParser,
|
|
8943
|
+
PolicyValidationError,
|
|
8331
8944
|
REQUESTS_FILENAME,
|
|
8332
8945
|
REQUIREMENTS,
|
|
8333
8946
|
RecipientManager,
|
|
@@ -8368,6 +8981,7 @@ export {
|
|
|
8368
8981
|
generateRandomValue,
|
|
8369
8982
|
generateSigningKeyPair,
|
|
8370
8983
|
getPendingKeys,
|
|
8984
|
+
getRotations,
|
|
8371
8985
|
isHighEntropy,
|
|
8372
8986
|
isKmsEnvelope,
|
|
8373
8987
|
isPending,
|
|
@@ -8379,6 +8993,8 @@ export {
|
|
|
8379
8993
|
markPendingWithRetry,
|
|
8380
8994
|
markResolved,
|
|
8381
8995
|
matchPatterns,
|
|
8996
|
+
mergeMetadataContents,
|
|
8997
|
+
mergeMetadataFiles,
|
|
8382
8998
|
metadataPath,
|
|
8383
8999
|
parse9 as parse,
|
|
8384
9000
|
parseDotenv,
|
|
@@ -8386,14 +9002,17 @@ export {
|
|
|
8386
9002
|
parseJson,
|
|
8387
9003
|
parseYaml,
|
|
8388
9004
|
readManifestYaml,
|
|
9005
|
+
recordRotation,
|
|
8389
9006
|
redactValue,
|
|
8390
9007
|
removeRequest as removeAccessRequest,
|
|
9008
|
+
removeRotation,
|
|
8391
9009
|
requestsFilePath,
|
|
8392
9010
|
resetSopsResolution,
|
|
8393
9011
|
resolveBackendConfig,
|
|
8394
9012
|
resolveIdentitySecrets,
|
|
8395
9013
|
resolveRecipientsForEnvironment,
|
|
8396
9014
|
resolveSopsPath,
|
|
9015
|
+
runCompliance,
|
|
8397
9016
|
saveMetadata,
|
|
8398
9017
|
saveRequests,
|
|
8399
9018
|
shannonEntropy,
|