@clef-sh/core 0.1.28 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/artifact/packer.d.ts +4 -3
- package/dist/artifact/packer.d.ts.map +1 -1
- package/dist/artifact/resolve.d.ts +3 -2
- package/dist/artifact/resolve.d.ts.map +1 -1
- package/dist/compliance/run.d.ts.map +1 -1
- package/dist/diff/engine.d.ts +18 -8
- package/dist/diff/engine.d.ts.map +1 -1
- package/dist/import/index.d.ts +5 -5
- package/dist/import/index.d.ts.map +1 -1
- package/dist/index.d.mts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1080 -838
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +1049 -794
- package/dist/index.mjs.map +4 -4
- package/dist/lint/runner.d.ts +7 -7
- package/dist/lint/runner.d.ts.map +1 -1
- package/dist/matrix/manager.d.ts +4 -16
- package/dist/matrix/manager.d.ts.map +1 -1
- package/dist/merge/driver.d.ts +2 -2
- package/dist/merge/driver.d.ts.map +1 -1
- package/dist/merge/metadata-driver.d.ts +5 -4
- package/dist/merge/metadata-driver.d.ts.map +1 -1
- package/dist/migration/backend.d.ts +10 -7
- package/dist/migration/backend.d.ts.map +1 -1
- package/dist/pack/backends/json-envelope.d.ts.map +1 -1
- package/dist/pack/types.d.ts +9 -3
- package/dist/pack/types.d.ts.map +1 -1
- package/dist/pending/metadata.d.ts +1 -3
- package/dist/pending/metadata.d.ts.map +1 -1
- package/dist/recipients/index.d.ts +4 -3
- package/dist/recipients/index.d.ts.map +1 -1
- package/dist/report/generator.d.ts +4 -3
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/reset/manager.d.ts +21 -3
- package/dist/reset/manager.d.ts.map +1 -1
- package/dist/service-identity/manager.d.ts +6 -3
- package/dist/service-identity/manager.d.ts.map +1 -1
- package/dist/sops/client.d.ts +80 -55
- package/dist/sops/client.d.ts.map +1 -1
- package/dist/sops/linux-stdin-fifo.d.ts +31 -0
- package/dist/sops/linux-stdin-fifo.d.ts.map +1 -0
- package/dist/source/compose.d.ts +10 -0
- package/dist/source/compose.d.ts.map +1 -0
- package/dist/source/default-bulk.d.ts +12 -0
- package/dist/source/default-bulk.d.ts.map +1 -0
- package/dist/source/encryption-backend.d.ts +85 -0
- package/dist/source/encryption-backend.d.ts.map +1 -0
- package/dist/source/errors.d.ts +19 -0
- package/dist/source/errors.d.ts.map +1 -0
- package/dist/source/filesystem-storage-backend.d.ts +26 -0
- package/dist/source/filesystem-storage-backend.d.ts.map +1 -0
- package/dist/source/guards.d.ts +14 -0
- package/dist/source/guards.d.ts.map +1 -0
- package/dist/source/index.d.ts +10 -0
- package/dist/source/index.d.ts.map +1 -0
- package/dist/source/mock-source.d.ts +89 -0
- package/dist/source/mock-source.d.ts.map +1 -0
- package/dist/source/storage-backend.d.ts +61 -0
- package/dist/source/storage-backend.d.ts.map +1 -0
- package/dist/source/types.d.ts +212 -0
- package/dist/source/types.d.ts.map +1 -0
- package/dist/structure/manager.d.ts +17 -3
- package/dist/structure/manager.d.ts.map +1 -1
- package/dist/sync/manager.d.ts +7 -6
- package/dist/sync/manager.d.ts.map +1 -1
- package/dist/types/index.d.ts +10 -23
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/bulk/ops.d.ts +0 -57
- package/dist/bulk/ops.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -301,13 +301,13 @@ var require_lib = __commonJS({
|
|
|
301
301
|
"../../node_modules/write-file-atomic/lib/index.js"(exports2, module2) {
|
|
302
302
|
"use strict";
|
|
303
303
|
module2.exports = writeFile;
|
|
304
|
-
module2.exports.sync =
|
|
304
|
+
module2.exports.sync = writeFileSync8;
|
|
305
305
|
module2.exports._getTmpname = getTmpname;
|
|
306
306
|
module2.exports._cleanupOnExit = cleanupOnExit;
|
|
307
|
-
var
|
|
307
|
+
var fs23 = require("fs");
|
|
308
308
|
var crypto7 = require("node:crypto");
|
|
309
309
|
var { onExit } = require_cjs();
|
|
310
|
-
var
|
|
310
|
+
var path28 = 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
|
+
fs23.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 = path28.resolve(filename);
|
|
364
364
|
try {
|
|
365
365
|
await serializeActiveFile(absoluteName);
|
|
366
|
-
const truename = await promisify(
|
|
366
|
+
const truename = await promisify(fs23.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(fs23.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(fs23.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(fs23.write)(fd, data, 0, data.length, 0);
|
|
386
386
|
} else if (data != null) {
|
|
387
|
-
await promisify(
|
|
387
|
+
await promisify(fs23.write)(fd, String(data), 0, String(options.encoding || "utf8"));
|
|
388
388
|
}
|
|
389
389
|
if (options.fsync !== false) {
|
|
390
|
-
await promisify(
|
|
390
|
+
await promisify(fs23.fsync)(fd);
|
|
391
391
|
}
|
|
392
|
-
await promisify(
|
|
392
|
+
await promisify(fs23.close)(fd);
|
|
393
393
|
fd = null;
|
|
394
394
|
if (options.chown) {
|
|
395
|
-
await promisify(
|
|
395
|
+
await promisify(fs23.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(fs23.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(fs23.rename)(tmpfile, truename);
|
|
409
409
|
} finally {
|
|
410
410
|
if (fd) {
|
|
411
|
-
await promisify(
|
|
411
|
+
await promisify(fs23.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(fs23.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 writeFileSync8(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 = fs23.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 = fs23.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 = fs23.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
|
+
fs23.writeSync(fd, data, 0, data.length, 0);
|
|
479
479
|
} else if (data != null) {
|
|
480
|
-
|
|
480
|
+
fs23.writeSync(fd, String(data), 0, String(options.encoding || "utf8"));
|
|
481
481
|
}
|
|
482
482
|
if (options.fsync !== false) {
|
|
483
|
-
|
|
483
|
+
fs23.fsyncSync(fd);
|
|
484
484
|
}
|
|
485
|
-
|
|
485
|
+
fs23.closeSync(fd);
|
|
486
486
|
fd = null;
|
|
487
487
|
if (options.chown) {
|
|
488
488
|
try {
|
|
489
|
-
|
|
489
|
+
fs23.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
|
+
fs23.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
|
+
fs23.renameSync(tmpfile, filename);
|
|
506
506
|
threw = false;
|
|
507
507
|
} finally {
|
|
508
508
|
if (fd) {
|
|
509
509
|
try {
|
|
510
|
-
|
|
510
|
+
fs23.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
|
module2.exports = patch;
|
|
549
|
-
function patch(
|
|
549
|
+
function patch(fs23) {
|
|
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(fs23);
|
|
552
|
+
}
|
|
553
|
+
if (!fs23.lutimes) {
|
|
554
|
+
patchLutimes(fs23);
|
|
555
|
+
}
|
|
556
|
+
fs23.chown = chownFix(fs23.chown);
|
|
557
|
+
fs23.fchown = chownFix(fs23.fchown);
|
|
558
|
+
fs23.lchown = chownFix(fs23.lchown);
|
|
559
|
+
fs23.chmod = chmodFix(fs23.chmod);
|
|
560
|
+
fs23.fchmod = chmodFix(fs23.fchmod);
|
|
561
|
+
fs23.lchmod = chmodFix(fs23.lchmod);
|
|
562
|
+
fs23.chownSync = chownFixSync(fs23.chownSync);
|
|
563
|
+
fs23.fchownSync = chownFixSync(fs23.fchownSync);
|
|
564
|
+
fs23.lchownSync = chownFixSync(fs23.lchownSync);
|
|
565
|
+
fs23.chmodSync = chmodFixSync(fs23.chmodSync);
|
|
566
|
+
fs23.fchmodSync = chmodFixSync(fs23.fchmodSync);
|
|
567
|
+
fs23.lchmodSync = chmodFixSync(fs23.lchmodSync);
|
|
568
|
+
fs23.stat = statFix(fs23.stat);
|
|
569
|
+
fs23.fstat = statFix(fs23.fstat);
|
|
570
|
+
fs23.lstat = statFix(fs23.lstat);
|
|
571
|
+
fs23.statSync = statFixSync(fs23.statSync);
|
|
572
|
+
fs23.fstatSync = statFixSync(fs23.fstatSync);
|
|
573
|
+
fs23.lstatSync = statFixSync(fs23.lstatSync);
|
|
574
|
+
if (fs23.chmod && !fs23.lchmod) {
|
|
575
|
+
fs23.lchmod = function(path28, mode, cb) {
|
|
576
576
|
if (cb) process.nextTick(cb);
|
|
577
577
|
};
|
|
578
|
-
|
|
578
|
+
fs23.lchmodSync = function() {
|
|
579
579
|
};
|
|
580
580
|
}
|
|
581
|
-
if (
|
|
582
|
-
|
|
581
|
+
if (fs23.chown && !fs23.lchown) {
|
|
582
|
+
fs23.lchown = function(path28, uid, gid, cb) {
|
|
583
583
|
if (cb) process.nextTick(cb);
|
|
584
584
|
};
|
|
585
|
-
|
|
585
|
+
fs23.lchownSync = function() {
|
|
586
586
|
};
|
|
587
587
|
}
|
|
588
588
|
if (platform === "win32") {
|
|
589
|
-
|
|
589
|
+
fs23.rename = typeof fs23.rename !== "function" ? fs23.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
|
+
fs23.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
|
+
})(fs23.rename);
|
|
613
613
|
}
|
|
614
|
-
|
|
614
|
+
fs23.read = typeof fs23.read !== "function" ? fs23.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(fs23, 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(fs23, 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
|
+
})(fs23.read);
|
|
632
|
+
fs23.readSync = typeof fs23.readSync !== "function" ? fs23.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(fs23, 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
|
+
})(fs23.readSync);
|
|
648
|
+
function patchLchmod(fs24) {
|
|
649
|
+
fs24.lchmod = function(path28, mode, callback) {
|
|
650
|
+
fs24.open(
|
|
651
|
+
path28,
|
|
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
|
+
fs24.fchmod(fd, mode, function(err2) {
|
|
660
|
+
fs24.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
|
+
fs24.lchmodSync = function(path28, mode) {
|
|
668
|
+
var fd = fs24.openSync(path28, constants.O_WRONLY | constants.O_SYMLINK, mode);
|
|
669
669
|
var threw = true;
|
|
670
670
|
var ret;
|
|
671
671
|
try {
|
|
672
|
-
ret =
|
|
672
|
+
ret = fs24.fchmodSync(fd, mode);
|
|
673
673
|
threw = false;
|
|
674
674
|
} finally {
|
|
675
675
|
if (threw) {
|
|
676
676
|
try {
|
|
677
|
-
|
|
677
|
+
fs24.closeSync(fd);
|
|
678
678
|
} catch (er) {
|
|
679
679
|
}
|
|
680
680
|
} else {
|
|
681
|
-
|
|
681
|
+
fs24.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(fs24) {
|
|
688
|
+
if (constants.hasOwnProperty("O_SYMLINK") && fs24.futimes) {
|
|
689
|
+
fs24.lutimes = function(path28, at, mt, cb) {
|
|
690
|
+
fs24.open(path28, constants.O_SYMLINK, function(er, fd) {
|
|
691
691
|
if (er) {
|
|
692
692
|
if (cb) cb(er);
|
|
693
693
|
return;
|
|
694
694
|
}
|
|
695
|
-
|
|
696
|
-
|
|
695
|
+
fs24.futimes(fd, at, mt, function(er2) {
|
|
696
|
+
fs24.close(fd, function(er22) {
|
|
697
697
|
if (cb) cb(er2 || er22);
|
|
698
698
|
});
|
|
699
699
|
});
|
|
700
700
|
});
|
|
701
701
|
};
|
|
702
|
-
|
|
703
|
-
var fd =
|
|
702
|
+
fs24.lutimesSync = function(path28, at, mt) {
|
|
703
|
+
var fd = fs24.openSync(path28, constants.O_SYMLINK);
|
|
704
704
|
var ret;
|
|
705
705
|
var threw = true;
|
|
706
706
|
try {
|
|
707
|
-
ret =
|
|
707
|
+
ret = fs24.futimesSync(fd, at, mt);
|
|
708
708
|
threw = false;
|
|
709
709
|
} finally {
|
|
710
710
|
if (threw) {
|
|
711
711
|
try {
|
|
712
|
-
|
|
712
|
+
fs24.closeSync(fd);
|
|
713
713
|
} catch (er) {
|
|
714
714
|
}
|
|
715
715
|
} else {
|
|
716
|
-
|
|
716
|
+
fs24.closeSync(fd);
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
return ret;
|
|
720
720
|
};
|
|
721
|
-
} else if (
|
|
722
|
-
|
|
721
|
+
} else if (fs24.futimes) {
|
|
722
|
+
fs24.lutimes = function(_a, _b, _c, cb) {
|
|
723
723
|
if (cb) process.nextTick(cb);
|
|
724
724
|
};
|
|
725
|
-
|
|
725
|
+
fs24.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(fs23, 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(fs23, 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(fs23, 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(fs23, 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(fs23, target, options, callback) : orig.call(fs23, 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(fs23, target, options) : orig.call(fs23, 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"(exports2, module2) {
|
|
814
814
|
var Stream = require("stream").Stream;
|
|
815
815
|
module2.exports = legacy;
|
|
816
|
-
function legacy(
|
|
816
|
+
function legacy(fs23) {
|
|
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(path28, options) {
|
|
822
|
+
if (!(this instanceof ReadStream)) return new ReadStream(path28, options);
|
|
823
823
|
Stream.call(this);
|
|
824
824
|
var self = this;
|
|
825
|
-
this.path =
|
|
825
|
+
this.path = path28;
|
|
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
|
+
fs23.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(path28, options) {
|
|
871
|
+
if (!(this instanceof WriteStream)) return new WriteStream(path28, options);
|
|
872
872
|
Stream.call(this);
|
|
873
|
-
this.path =
|
|
873
|
+
this.path = path28;
|
|
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 = fs23.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"(exports2, module2) {
|
|
933
|
-
var
|
|
933
|
+
var fs23 = 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 (!fs23[gracefulQueue]) {
|
|
966
966
|
queue = global[gracefulQueue] || [];
|
|
967
|
-
publishQueue(
|
|
968
|
-
|
|
967
|
+
publishQueue(fs23, queue);
|
|
968
|
+
fs23.close = (function(fs$close) {
|
|
969
969
|
function close(fd, cb) {
|
|
970
|
-
return fs$close.call(
|
|
970
|
+
return fs$close.call(fs23, 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
|
-
|
|
984
|
-
function
|
|
985
|
-
fs$closeSync.apply(
|
|
982
|
+
})(fs23.close);
|
|
983
|
+
fs23.closeSync = (function(fs$closeSync) {
|
|
984
|
+
function closeSync3(fd) {
|
|
985
|
+
fs$closeSync.apply(fs23, arguments);
|
|
986
986
|
resetQueue();
|
|
987
987
|
}
|
|
988
|
-
Object.defineProperty(
|
|
988
|
+
Object.defineProperty(closeSync3, previousSymbol, {
|
|
989
989
|
value: fs$closeSync
|
|
990
990
|
});
|
|
991
|
-
return
|
|
992
|
-
})(
|
|
991
|
+
return closeSync3;
|
|
992
|
+
})(fs23.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(fs23[gracefulQueue]);
|
|
996
|
+
require("assert").equal(fs23[gracefulQueue].length, 0);
|
|
997
997
|
});
|
|
998
998
|
}
|
|
999
999
|
}
|
|
1000
1000
|
var queue;
|
|
1001
1001
|
if (!global[gracefulQueue]) {
|
|
1002
|
-
publishQueue(global,
|
|
1003
|
-
}
|
|
1004
|
-
module2.exports = patch(clone(
|
|
1005
|
-
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !
|
|
1006
|
-
module2.exports = patch(
|
|
1007
|
-
|
|
1008
|
-
}
|
|
1009
|
-
function patch(
|
|
1010
|
-
polyfills(
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
var fs$readFile =
|
|
1015
|
-
|
|
1016
|
-
function readFile(
|
|
1002
|
+
publishQueue(global, fs23[gracefulQueue]);
|
|
1003
|
+
}
|
|
1004
|
+
module2.exports = patch(clone(fs23));
|
|
1005
|
+
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs23.__patched) {
|
|
1006
|
+
module2.exports = patch(fs23);
|
|
1007
|
+
fs23.__patched = true;
|
|
1008
|
+
}
|
|
1009
|
+
function patch(fs24) {
|
|
1010
|
+
polyfills(fs24);
|
|
1011
|
+
fs24.gracefulify = patch;
|
|
1012
|
+
fs24.createReadStream = createReadStream;
|
|
1013
|
+
fs24.createWriteStream = createWriteStream;
|
|
1014
|
+
var fs$readFile = fs24.readFile;
|
|
1015
|
+
fs24.readFile = readFile;
|
|
1016
|
+
function readFile(path28, 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(path28, options, cb);
|
|
1020
|
+
function go$readFile(path29, options2, cb2, startTime) {
|
|
1021
|
+
return fs$readFile(path29, options2, function(err) {
|
|
1022
1022
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1023
|
-
enqueue([go$readFile, [
|
|
1023
|
+
enqueue([go$readFile, [path29, 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 = fs24.writeFile;
|
|
1032
|
+
fs24.writeFile = writeFile;
|
|
1033
|
+
function writeFile(path28, 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(path28, data, options, cb);
|
|
1037
|
+
function go$writeFile(path29, data2, options2, cb2, startTime) {
|
|
1038
|
+
return fs$writeFile(path29, data2, options2, function(err) {
|
|
1039
1039
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1040
|
-
enqueue([go$writeFile, [
|
|
1040
|
+
enqueue([go$writeFile, [path29, 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 = fs24.appendFile;
|
|
1049
1049
|
if (fs$appendFile)
|
|
1050
|
-
|
|
1051
|
-
function appendFile(
|
|
1050
|
+
fs24.appendFile = appendFile;
|
|
1051
|
+
function appendFile(path28, 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(path28, data, options, cb);
|
|
1055
|
+
function go$appendFile(path29, data2, options2, cb2, startTime) {
|
|
1056
|
+
return fs$appendFile(path29, data2, options2, function(err) {
|
|
1057
1057
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1058
|
-
enqueue([go$appendFile, [
|
|
1058
|
+
enqueue([go$appendFile, [path29, 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 = fs24.copyFile;
|
|
1067
1067
|
if (fs$copyFile)
|
|
1068
|
-
|
|
1068
|
+
fs24.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 = fs24.readdir;
|
|
1087
|
+
fs24.readdir = readdir;
|
|
1088
1088
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
1089
|
-
function readdir(
|
|
1089
|
+
function readdir(path28, 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(path29, options2, cb2, startTime) {
|
|
1093
|
+
return fs$readdir(path29, fs$readdirCallback(
|
|
1094
|
+
path29,
|
|
1095
1095
|
options2,
|
|
1096
1096
|
cb2,
|
|
1097
1097
|
startTime
|
|
1098
1098
|
));
|
|
1099
|
-
} : function go$readdir2(
|
|
1100
|
-
return fs$readdir(
|
|
1101
|
-
|
|
1099
|
+
} : function go$readdir2(path29, options2, cb2, startTime) {
|
|
1100
|
+
return fs$readdir(path29, options2, fs$readdirCallback(
|
|
1101
|
+
path29,
|
|
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(path28, options, cb);
|
|
1108
|
+
function fs$readdirCallback(path29, 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
|
+
[path29, 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(fs24);
|
|
1129
1129
|
ReadStream = legStreams.ReadStream;
|
|
1130
1130
|
WriteStream = legStreams.WriteStream;
|
|
1131
1131
|
}
|
|
1132
|
-
var fs$ReadStream =
|
|
1132
|
+
var fs$ReadStream = fs24.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 = fs24.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(fs24, "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(fs24, "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(fs24, "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(fs24, "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(path28, 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(path28, 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(path28, options) {
|
|
1223
|
+
return new fs24.ReadStream(path28, options);
|
|
1224
1224
|
}
|
|
1225
|
-
function createWriteStream(
|
|
1226
|
-
return new
|
|
1225
|
+
function createWriteStream(path28, options) {
|
|
1226
|
+
return new fs24.WriteStream(path28, options);
|
|
1227
1227
|
}
|
|
1228
|
-
var fs$open =
|
|
1229
|
-
|
|
1230
|
-
function open(
|
|
1228
|
+
var fs$open = fs24.open;
|
|
1229
|
+
fs24.open = open;
|
|
1230
|
+
function open(path28, 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(path28, flags, mode, cb);
|
|
1234
|
+
function go$open(path29, flags2, mode2, cb2, startTime) {
|
|
1235
|
+
return fs$open(path29, flags2, mode2, function(err, fd) {
|
|
1236
1236
|
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
1237
|
-
enqueue([go$open, [
|
|
1237
|
+
enqueue([go$open, [path29, 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 fs24;
|
|
1246
1246
|
}
|
|
1247
1247
|
function enqueue(elem) {
|
|
1248
1248
|
debug("ENQUEUE", elem[0].name, elem[1]);
|
|
1249
|
-
|
|
1249
|
+
fs23[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 < fs23[gracefulQueue].length; ++i) {
|
|
1256
|
+
if (fs23[gracefulQueue][i].length > 2) {
|
|
1257
|
+
fs23[gracefulQueue][i][3] = now;
|
|
1258
|
+
fs23[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 (fs23[gracefulQueue].length === 0)
|
|
1267
1267
|
return;
|
|
1268
|
-
var elem =
|
|
1268
|
+
var elem = fs23[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
|
+
fs23[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"(exports2, module2) {
|
|
1723
1723
|
"use strict";
|
|
1724
1724
|
var cacheSymbol = /* @__PURE__ */ Symbol();
|
|
1725
|
-
function probe(file,
|
|
1726
|
-
const cachedPrecision =
|
|
1725
|
+
function probe(file, fs23, callback) {
|
|
1726
|
+
const cachedPrecision = fs23[cacheSymbol];
|
|
1727
1727
|
if (cachedPrecision) {
|
|
1728
|
-
return
|
|
1728
|
+
return fs23.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
|
+
fs23.utimes(file, mtime, mtime, (err) => {
|
|
1737
1737
|
if (err) {
|
|
1738
1738
|
return callback(err);
|
|
1739
1739
|
}
|
|
1740
|
-
|
|
1740
|
+
fs23.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(fs23, 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"(exports2, module2) {
|
|
1765
1765
|
"use strict";
|
|
1766
|
-
var
|
|
1767
|
-
var
|
|
1766
|
+
var path28 = require("path");
|
|
1767
|
+
var fs23 = 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, path28.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: fs23,
|
|
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: fs23,
|
|
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: fs23,
|
|
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"(exports2, module2) {
|
|
2002
2002
|
"use strict";
|
|
2003
|
-
var
|
|
2004
|
-
function createSyncFs(
|
|
2003
|
+
var fs23 = require_graceful_fs();
|
|
2004
|
+
function createSyncFs(fs24) {
|
|
2005
2005
|
const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
|
|
2006
|
-
const newFs = { ...
|
|
2006
|
+
const newFs = { ...fs24 };
|
|
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 = fs24[`${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 || fs23);
|
|
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
|
}
|
|
@@ -2303,7 +2303,7 @@ var require_age_encryption = __commonJS({
|
|
|
2303
2303
|
Object.assign(hashC, info);
|
|
2304
2304
|
return Object.freeze(hashC);
|
|
2305
2305
|
}
|
|
2306
|
-
function
|
|
2306
|
+
function randomBytes5(bytesLength = 32) {
|
|
2307
2307
|
anumber(bytesLength, "bytesLength");
|
|
2308
2308
|
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
2309
2309
|
if (typeof cr?.getRandomValues !== "function")
|
|
@@ -3030,7 +3030,7 @@ var require_age_encryption = __commonJS({
|
|
|
3030
3030
|
};
|
|
3031
3031
|
}
|
|
3032
3032
|
// @__NO_SIDE_EFFECTS__
|
|
3033
|
-
function
|
|
3033
|
+
function join20(separator = "") {
|
|
3034
3034
|
astr("join", separator);
|
|
3035
3035
|
return {
|
|
3036
3036
|
encode: (from) => {
|
|
@@ -3160,9 +3160,9 @@ var require_age_encryption = __commonJS({
|
|
|
3160
3160
|
decode(s) {
|
|
3161
3161
|
return decodeBase64Builtin(s, false);
|
|
3162
3162
|
}
|
|
3163
|
-
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */
|
|
3164
|
-
var base64nopad = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */
|
|
3165
|
-
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */
|
|
3163
|
+
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join20("")));
|
|
3164
|
+
var base64nopad = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ join20("")));
|
|
3165
|
+
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join20(""));
|
|
3166
3166
|
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
3167
3167
|
function bech32Polymod(pre) {
|
|
3168
3168
|
const b = pre >> 25;
|
|
@@ -7655,7 +7655,7 @@ var require_age_encryption = __commonJS({
|
|
|
7655
7655
|
var concatBytes4 = (...arrays) => concatBytes(...arrays);
|
|
7656
7656
|
var hexToBytes3 = (hex) => hexToBytes(hex);
|
|
7657
7657
|
var isBytes5 = isBytes;
|
|
7658
|
-
var
|
|
7658
|
+
var randomBytes52 = (bytesLength) => randomBytes5(bytesLength);
|
|
7659
7659
|
var _0n7 = /* @__PURE__ */ BigInt(0);
|
|
7660
7660
|
var _1n8 = /* @__PURE__ */ BigInt(1);
|
|
7661
7661
|
function abool3(value, title = "") {
|
|
@@ -9127,7 +9127,7 @@ var require_age_encryption = __commonJS({
|
|
|
9127
9127
|
}
|
|
9128
9128
|
function ecdh2(Point, ecdhOpts = {}) {
|
|
9129
9129
|
const { Fn: Fn2 } = Point;
|
|
9130
|
-
const randomBytes_ = ecdhOpts.randomBytes === void 0 ?
|
|
9130
|
+
const randomBytes_ = ecdhOpts.randomBytes === void 0 ? randomBytes52 : ecdhOpts.randomBytes;
|
|
9131
9131
|
const lengths = Object.assign(getWLengths2(Point.Fp, Fn2), {
|
|
9132
9132
|
seed: Math.max(getMinHashLength2(Fn2.ORDER), 16)
|
|
9133
9133
|
});
|
|
@@ -9201,7 +9201,7 @@ var require_age_encryption = __commonJS({
|
|
|
9201
9201
|
bits2int_modN: "function"
|
|
9202
9202
|
});
|
|
9203
9203
|
ecdsaOpts = Object.assign({}, ecdsaOpts);
|
|
9204
|
-
const randomBytes6 = ecdsaOpts.randomBytes === void 0 ?
|
|
9204
|
+
const randomBytes6 = ecdsaOpts.randomBytes === void 0 ? randomBytes52 : ecdsaOpts.randomBytes;
|
|
9205
9205
|
const hmac3 = ecdsaOpts.hmac === void 0 ? (key, msg) => hmac(hash_, key, msg) : ecdsaOpts.hmac;
|
|
9206
9206
|
const { Fp: Fp2, Fn: Fn2 } = Point;
|
|
9207
9207
|
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn2;
|
|
@@ -9815,7 +9815,7 @@ var require_age_encryption = __commonJS({
|
|
|
9815
9815
|
const is25519 = type === "x25519";
|
|
9816
9816
|
if (!is25519 && type !== "x448")
|
|
9817
9817
|
throw new Error("invalid type");
|
|
9818
|
-
const randomBytes_ = rand === void 0 ?
|
|
9818
|
+
const randomBytes_ = rand === void 0 ? randomBytes52 : rand;
|
|
9819
9819
|
const montgomeryBits = is25519 ? 255 : 448;
|
|
9820
9820
|
const fieldLen = is25519 ? 32 : 56;
|
|
9821
9821
|
const Gu = is25519 ? BigInt(9) : BigInt(5);
|
|
@@ -10449,12 +10449,12 @@ var require_age_encryption = __commonJS({
|
|
|
10449
10449
|
return generateX25519Identity();
|
|
10450
10450
|
}
|
|
10451
10451
|
function generateX25519Identity() {
|
|
10452
|
-
const scalar =
|
|
10452
|
+
const scalar = randomBytes5(32);
|
|
10453
10453
|
const identity = bech32.encodeFromBytes("AGE-SECRET-KEY-", scalar).toUpperCase();
|
|
10454
10454
|
return Promise.resolve(identity);
|
|
10455
10455
|
}
|
|
10456
10456
|
function generateHybridIdentity() {
|
|
10457
|
-
const scalar =
|
|
10457
|
+
const scalar = randomBytes5(32);
|
|
10458
10458
|
const identity = bech32.encodeFromBytes("AGE-SECRET-KEY-PQ-", scalar).toUpperCase();
|
|
10459
10459
|
return Promise.resolve(identity);
|
|
10460
10460
|
}
|
|
@@ -10662,7 +10662,7 @@ var require_age_encryption = __commonJS({
|
|
|
10662
10662
|
this.recipient = res.bytes;
|
|
10663
10663
|
}
|
|
10664
10664
|
async wrapFileKey(fileKey) {
|
|
10665
|
-
const ephemeral =
|
|
10665
|
+
const ephemeral = randomBytes5(32);
|
|
10666
10666
|
const share = await scalarMultBase(ephemeral);
|
|
10667
10667
|
const secret = await scalarMult(ephemeral, this.recipient);
|
|
10668
10668
|
const salt = new Uint8Array(share.length + this.recipient.length);
|
|
@@ -10723,7 +10723,7 @@ var require_age_encryption = __commonJS({
|
|
|
10723
10723
|
this.logN = logN;
|
|
10724
10724
|
}
|
|
10725
10725
|
wrapFileKey(fileKey) {
|
|
10726
|
-
const salt =
|
|
10726
|
+
const salt = randomBytes5(16);
|
|
10727
10727
|
const label2 = "age-encryption.org/v1/scrypt";
|
|
10728
10728
|
const labelAndSalt = new Uint8Array(label2.length + 16);
|
|
10729
10729
|
labelAndSalt.set(new TextEncoder().encode(label2));
|
|
@@ -11058,7 +11058,7 @@ var require_age_encryption = __commonJS({
|
|
|
11058
11058
|
rp: { name: "", id: options.rpId },
|
|
11059
11059
|
user: {
|
|
11060
11060
|
name: options.keyName,
|
|
11061
|
-
id: domBuffer2(
|
|
11061
|
+
id: domBuffer2(randomBytes5(8)),
|
|
11062
11062
|
// avoid overwriting existing keys
|
|
11063
11063
|
displayName: ""
|
|
11064
11064
|
},
|
|
@@ -11128,7 +11128,7 @@ var require_age_encryption = __commonJS({
|
|
|
11128
11128
|
transports: this.transports,
|
|
11129
11129
|
type: "public-key"
|
|
11130
11130
|
}] : [],
|
|
11131
|
-
challenge: domBuffer2(
|
|
11131
|
+
challenge: domBuffer2(randomBytes5(16)),
|
|
11132
11132
|
extensions: { prf: { eval: prfInputs(nonce) } },
|
|
11133
11133
|
userVerification: "required",
|
|
11134
11134
|
// prf requires UV
|
|
@@ -11147,7 +11147,7 @@ var require_age_encryption = __commonJS({
|
|
|
11147
11147
|
* Implements {@link Recipient.wrapFileKey}.
|
|
11148
11148
|
*/
|
|
11149
11149
|
async wrapFileKey(fileKey) {
|
|
11150
|
-
const nonce =
|
|
11150
|
+
const nonce = randomBytes5(16);
|
|
11151
11151
|
const results = await this.getCredential(nonce);
|
|
11152
11152
|
const key = deriveKey(results);
|
|
11153
11153
|
return [new Stanza([label, base64nopad.encode(nonce)], encryptFileKey(fileKey, key))];
|
|
@@ -11270,7 +11270,7 @@ var require_age_encryption = __commonJS({
|
|
|
11270
11270
|
}
|
|
11271
11271
|
}
|
|
11272
11272
|
async encrypt(file) {
|
|
11273
|
-
const fileKey =
|
|
11273
|
+
const fileKey = randomBytes5(16);
|
|
11274
11274
|
const stanzas = [];
|
|
11275
11275
|
let recipients = this.recipients;
|
|
11276
11276
|
if (this.passphrase !== null) {
|
|
@@ -11283,7 +11283,7 @@ var require_age_encryption = __commonJS({
|
|
|
11283
11283
|
const hmacKey = hkdf(sha256, fileKey, void 0, labelHeader, 32);
|
|
11284
11284
|
const mac = hmac(sha256, hmacKey, encodeHeaderNoMAC(stanzas));
|
|
11285
11285
|
const header = encodeHeader(stanzas, mac);
|
|
11286
|
-
const nonce =
|
|
11286
|
+
const nonce = randomBytes5(16);
|
|
11287
11287
|
const labelPayload = new TextEncoder().encode("payload");
|
|
11288
11288
|
const streamKey = hkdf(sha256, fileKey, nonce, labelPayload, 32);
|
|
11289
11289
|
const encrypter = encryptSTREAM(streamKey);
|
|
@@ -11420,7 +11420,6 @@ var index_exports = {};
|
|
|
11420
11420
|
__export(index_exports, {
|
|
11421
11421
|
ArtifactPacker: () => ArtifactPacker,
|
|
11422
11422
|
BackendMigrator: () => BackendMigrator,
|
|
11423
|
-
BulkOps: () => BulkOps,
|
|
11424
11423
|
CLEF_MANIFEST_FILENAME: () => CLEF_MANIFEST_FILENAME,
|
|
11425
11424
|
CLEF_POLICY_FILENAME: () => CLEF_POLICY_FILENAME,
|
|
11426
11425
|
CLEF_REPORT_SCHEMA_VERSION: () => CLEF_REPORT_SCHEMA_VERSION,
|
|
@@ -11434,6 +11433,7 @@ __export(index_exports, {
|
|
|
11434
11433
|
DiffEngine: () => DiffEngine,
|
|
11435
11434
|
DriftDetector: () => DriftDetector,
|
|
11436
11435
|
FilePackOutput: () => FilePackOutput,
|
|
11436
|
+
FilesystemStorageBackend: () => FilesystemStorageBackend,
|
|
11437
11437
|
GitIntegration: () => GitIntegration,
|
|
11438
11438
|
GitOperationError: () => GitOperationError,
|
|
11439
11439
|
ImportRunner: () => ImportRunner,
|
|
@@ -11450,7 +11450,6 @@ __export(index_exports, {
|
|
|
11450
11450
|
PolicyValidationError: () => PolicyValidationError,
|
|
11451
11451
|
REQUESTS_FILENAME: () => REQUESTS_FILENAME,
|
|
11452
11452
|
REQUIREMENTS: () => REQUIREMENTS,
|
|
11453
|
-
REVEAL_WARNING: () => REVEAL_WARNING,
|
|
11454
11453
|
RecipientManager: () => RecipientManager,
|
|
11455
11454
|
ReportGenerator: () => ReportGenerator,
|
|
11456
11455
|
ReportSanitizer: () => ReportSanitizer,
|
|
@@ -11467,6 +11466,7 @@ __export(index_exports, {
|
|
|
11467
11466
|
SopsMergeDriver: () => SopsMergeDriver,
|
|
11468
11467
|
SopsMissingError: () => SopsMissingError,
|
|
11469
11468
|
SopsVersionError: () => SopsVersionError,
|
|
11469
|
+
SourceCapabilityUnsupportedError: () => SourceCapabilityUnsupportedError,
|
|
11470
11470
|
StructureManager: () => StructureManager,
|
|
11471
11471
|
SyncManager: () => SyncManager,
|
|
11472
11472
|
TransactionLockError: () => TransactionLockError,
|
|
@@ -11486,11 +11486,11 @@ __export(index_exports, {
|
|
|
11486
11486
|
checkAll: () => checkAll,
|
|
11487
11487
|
checkDependency: () => checkDependency,
|
|
11488
11488
|
collectCIContext: () => collectCIContext,
|
|
11489
|
+
composeSecretSource: () => composeSecretSource,
|
|
11489
11490
|
computeCiphertextHash: () => computeCiphertextHash,
|
|
11490
11491
|
deriveAgePublicKey: () => deriveAgePublicKey,
|
|
11492
|
+
describeCapabilities: () => describeCapabilities,
|
|
11491
11493
|
describeScope: () => describeScope,
|
|
11492
|
-
detectAlgorithm: () => detectAlgorithm,
|
|
11493
|
-
detectFormat: () => detectFormat,
|
|
11494
11494
|
emptyTemplate: () => emptyTemplate,
|
|
11495
11495
|
exampleTemplate: () => exampleTemplate,
|
|
11496
11496
|
findRequest: () => findRequest,
|
|
@@ -11498,35 +11498,27 @@ __export(index_exports, {
|
|
|
11498
11498
|
formatRevealWarning: () => formatRevealWarning,
|
|
11499
11499
|
generateAgeIdentity: () => generateAgeIdentity,
|
|
11500
11500
|
generateRandomValue: () => generateRandomValue,
|
|
11501
|
-
|
|
11502
|
-
getPendingKeys: () => getPendingKeys,
|
|
11503
|
-
getRotations: () => getRotations,
|
|
11501
|
+
isBulk: () => isBulk,
|
|
11504
11502
|
isClefHsmArn: () => isClefHsmArn,
|
|
11505
|
-
isHighEntropy: () => isHighEntropy,
|
|
11506
11503
|
isKmsEnvelope: () => isKmsEnvelope,
|
|
11504
|
+
isLintable: () => isLintable,
|
|
11505
|
+
isMergeAware: () => isMergeAware,
|
|
11506
|
+
isMigratable: () => isMigratable,
|
|
11507
11507
|
isPackedArtifact: () => isPackedArtifact,
|
|
11508
|
-
|
|
11508
|
+
isRecipientManaged: () => isRecipientManaged,
|
|
11509
|
+
isRotatable: () => isRotatable,
|
|
11510
|
+
isStructural: () => isStructural,
|
|
11509
11511
|
keyPreview: () => keyPreview,
|
|
11510
|
-
loadIgnoreRules: () => loadIgnoreRules,
|
|
11511
|
-
loadMetadata: () => loadMetadata,
|
|
11512
11512
|
loadRequests: () => loadRequests,
|
|
11513
11513
|
markPending: () => markPending,
|
|
11514
|
-
markPendingWithRetry: () => markPendingWithRetry,
|
|
11515
11514
|
markResolved: () => markResolved,
|
|
11516
|
-
matchPatterns: () => matchPatterns,
|
|
11517
|
-
mergeMetadataContents: () => mergeMetadataContents,
|
|
11518
11515
|
mergeMetadataFiles: () => mergeMetadataFiles,
|
|
11519
|
-
metadataPath: () => metadataPath,
|
|
11520
11516
|
parse: () => parse9,
|
|
11521
|
-
parseDotenv: () => parseDotenv,
|
|
11522
|
-
parseIgnoreContent: () => parseIgnoreContent,
|
|
11523
|
-
parseJson: () => parseJson,
|
|
11524
11517
|
parseSignerKey: () => parseSignerKey,
|
|
11525
11518
|
parseYaml: () => parseYaml,
|
|
11526
11519
|
pkcs11UriToSyntheticArn: () => pkcs11UriToSyntheticArn,
|
|
11527
11520
|
readManifestYaml: () => readManifestYaml,
|
|
11528
11521
|
recordRotation: () => recordRotation,
|
|
11529
|
-
redactValue: () => redactValue,
|
|
11530
11522
|
removeAccessRequest: () => removeRequest,
|
|
11531
11523
|
removeRotation: () => removeRotation,
|
|
11532
11524
|
requestsFilePath: () => requestsFilePath,
|
|
@@ -11538,14 +11530,8 @@ __export(index_exports, {
|
|
|
11538
11530
|
resolveRecipientsForEnvironment: () => resolveRecipientsForEnvironment,
|
|
11539
11531
|
resolveSopsPath: () => resolveSopsPath,
|
|
11540
11532
|
runCompliance: () => runCompliance,
|
|
11541
|
-
saveMetadata: () => saveMetadata,
|
|
11542
11533
|
saveRequests: () => saveRequests,
|
|
11543
|
-
|
|
11544
|
-
shannonEntropy: () => shannonEntropy,
|
|
11545
|
-
shouldIgnoreFile: () => shouldIgnoreFile,
|
|
11546
|
-
shouldIgnoreMatch: () => shouldIgnoreMatch,
|
|
11547
|
-
signEd25519: () => signEd25519,
|
|
11548
|
-
signKms: () => signKms,
|
|
11534
|
+
shouldUseLinuxStdinFifo: () => shouldUseLinuxStdinFifo,
|
|
11549
11535
|
spawnKeyservice: () => spawnKeyservice,
|
|
11550
11536
|
syntheticArnToPkcs11Uri: () => syntheticArnToPkcs11Uri,
|
|
11551
11537
|
tryBundledKeyservice: () => tryBundledKeyservice,
|
|
@@ -11555,6 +11541,7 @@ __export(index_exports, {
|
|
|
11555
11541
|
validatePackedArtifact: () => validatePackedArtifact,
|
|
11556
11542
|
validateResetScope: () => validateResetScope,
|
|
11557
11543
|
verifySignature: () => verifySignature,
|
|
11544
|
+
wrapWithLinuxStdinFifo: () => wrapWithLinuxStdinFifo,
|
|
11558
11545
|
writeManifestYaml: () => writeManifestYaml,
|
|
11559
11546
|
writeManifestYamlRaw: () => writeManifestYamlRaw,
|
|
11560
11547
|
writeSchema: () => writeSchema,
|
|
@@ -12907,10 +12894,6 @@ async function getPendingKeys(filePath) {
|
|
|
12907
12894
|
const metadata = await loadMetadata(filePath);
|
|
12908
12895
|
return metadata.pending.map((p) => p.key);
|
|
12909
12896
|
}
|
|
12910
|
-
async function isPending(filePath, key) {
|
|
12911
|
-
const metadata = await loadMetadata(filePath);
|
|
12912
|
-
return metadata.pending.some((p) => p.key === key);
|
|
12913
|
-
}
|
|
12914
12897
|
async function recordRotation(filePath, keys, rotatedBy, now = /* @__PURE__ */ new Date()) {
|
|
12915
12898
|
const metadata = await loadMetadata(filePath);
|
|
12916
12899
|
for (const key of keys) {
|
|
@@ -12946,14 +12929,6 @@ async function getRotations(filePath) {
|
|
|
12946
12929
|
function generateRandomValue() {
|
|
12947
12930
|
return crypto2.randomBytes(32).toString("hex");
|
|
12948
12931
|
}
|
|
12949
|
-
async function markPendingWithRetry(filePath, keys, setBy, retryDelayMs = 200) {
|
|
12950
|
-
try {
|
|
12951
|
-
await markPending(filePath, keys, setBy);
|
|
12952
|
-
} catch {
|
|
12953
|
-
await new Promise((r) => setTimeout(r, retryDelayMs));
|
|
12954
|
-
await markPending(filePath, keys, setBy);
|
|
12955
|
-
}
|
|
12956
|
-
}
|
|
12957
12932
|
|
|
12958
12933
|
// src/sops/keys.ts
|
|
12959
12934
|
var fs6 = __toESM(require("fs"));
|
|
@@ -13003,34 +12978,17 @@ var MatrixManager = class {
|
|
|
13003
12978
|
detectMissingCells(manifest, repoRoot) {
|
|
13004
12979
|
return this.resolveMatrix(manifest, repoRoot).filter((cell) => !cell.exists);
|
|
13005
12980
|
}
|
|
13006
|
-
/**
|
|
13007
|
-
* Create an empty encrypted SOPS file for a missing matrix cell.
|
|
13008
|
-
*
|
|
13009
|
-
* @param cell - The cell to scaffold (must not already exist).
|
|
13010
|
-
* @param sopsClient - SOPS client used to write the initial encrypted file.
|
|
13011
|
-
* @param manifest - Parsed manifest used to determine the encryption backend.
|
|
13012
|
-
*/
|
|
13013
|
-
async scaffoldCell(cell, sopsClient, manifest) {
|
|
13014
|
-
const dir = path5.dirname(cell.filePath);
|
|
13015
|
-
if (!fs7.existsSync(dir)) {
|
|
13016
|
-
fs7.mkdirSync(dir, { recursive: true });
|
|
13017
|
-
}
|
|
13018
|
-
await sopsClient.encrypt(cell.filePath, {}, manifest, cell.environment);
|
|
13019
|
-
}
|
|
13020
12981
|
/**
|
|
13021
12982
|
* Read each cell and return key counts, pending counts, and cross-environment issues.
|
|
13022
12983
|
*
|
|
13023
|
-
*
|
|
13024
|
-
*
|
|
13025
|
-
*
|
|
13026
|
-
* decrypt-based implementation later (e.g. for backends that don't expose
|
|
13027
|
-
* key names without decryption).
|
|
12984
|
+
* Keys are read from the plaintext YAML structure directly — no
|
|
12985
|
+
* decryption needed. A future backend that doesn't expose key names
|
|
12986
|
+
* without decryption would need its own implementation.
|
|
13028
12987
|
*
|
|
13029
12988
|
* @param manifest - Parsed manifest.
|
|
13030
12989
|
* @param repoRoot - Absolute path to the repository root.
|
|
13031
|
-
* @param _sopsClient - Reserved for future use; pass any `EncryptionBackend`.
|
|
13032
12990
|
*/
|
|
13033
|
-
async getMatrixStatus(manifest, repoRoot
|
|
12991
|
+
async getMatrixStatus(manifest, repoRoot) {
|
|
13034
12992
|
const cells = this.resolveMatrix(manifest, repoRoot);
|
|
13035
12993
|
const statuses = [];
|
|
13036
12994
|
const cellKeys = /* @__PURE__ */ new Map();
|
|
@@ -13346,7 +13304,6 @@ function orderedKeys(keys) {
|
|
|
13346
13304
|
}
|
|
13347
13305
|
|
|
13348
13306
|
// src/diff/engine.ts
|
|
13349
|
-
var path7 = __toESM(require("path"));
|
|
13350
13307
|
var DiffEngine = class {
|
|
13351
13308
|
/**
|
|
13352
13309
|
* Compare two in-memory value maps and produce a sorted diff result.
|
|
@@ -13397,131 +13354,21 @@ var DiffEngine = class {
|
|
|
13397
13354
|
* @param namespace - Namespace containing both cells.
|
|
13398
13355
|
* @param envA - Name of environment A.
|
|
13399
13356
|
* @param envB - Name of environment B.
|
|
13400
|
-
* @param
|
|
13401
|
-
* @
|
|
13402
|
-
* @param repoRoot - Absolute path to the repository root.
|
|
13403
|
-
* @throws {@link SopsDecryptionError} If either file cannot be decrypted.
|
|
13357
|
+
* @param source - SecretSource that resolves both cells (substrate-agnostic).
|
|
13358
|
+
* @throws {@link SopsDecryptionError} If either cell cannot be decrypted.
|
|
13404
13359
|
*/
|
|
13405
|
-
async
|
|
13406
|
-
const fileA = path7.join(
|
|
13407
|
-
repoRoot,
|
|
13408
|
-
manifest.file_pattern.replace("{namespace}", namespace).replace("{environment}", envA)
|
|
13409
|
-
);
|
|
13410
|
-
const fileB = path7.join(
|
|
13411
|
-
repoRoot,
|
|
13412
|
-
manifest.file_pattern.replace("{namespace}", namespace).replace("{environment}", envB)
|
|
13413
|
-
);
|
|
13360
|
+
async diffCells(namespace, envA, envB, source) {
|
|
13414
13361
|
const [decryptedA, decryptedB] = await Promise.all([
|
|
13415
|
-
|
|
13416
|
-
|
|
13362
|
+
source.readCell({ namespace, environment: envA }),
|
|
13363
|
+
source.readCell({ namespace, environment: envB })
|
|
13417
13364
|
]);
|
|
13418
13365
|
return this.diff(decryptedA.values, decryptedB.values, envA, envB, namespace);
|
|
13419
13366
|
}
|
|
13420
13367
|
};
|
|
13421
13368
|
|
|
13422
|
-
// src/bulk/ops.ts
|
|
13423
|
-
var path8 = __toESM(require("path"));
|
|
13424
|
-
var BulkOps = class {
|
|
13425
|
-
constructor(tx) {
|
|
13426
|
-
this.tx = tx;
|
|
13427
|
-
}
|
|
13428
|
-
tx;
|
|
13429
|
-
/**
|
|
13430
|
-
* Set a key to different values in multiple environments at once.
|
|
13431
|
-
*
|
|
13432
|
-
* @param namespace - Target namespace.
|
|
13433
|
-
* @param key - Secret key name to set.
|
|
13434
|
-
* @param values - Map of `{ environment: value }` pairs.
|
|
13435
|
-
* @param manifest - Parsed manifest.
|
|
13436
|
-
* @param sopsClient - SOPS client used to decrypt and re-encrypt each file.
|
|
13437
|
-
* @param repoRoot - Absolute path to the repository root.
|
|
13438
|
-
* @throws Whatever the underlying encrypt throws — the transaction rolls back.
|
|
13439
|
-
*/
|
|
13440
|
-
async setAcrossEnvironments(namespace, key, values, manifest, sopsClient, repoRoot) {
|
|
13441
|
-
const targets = manifest.environments.filter((env) => env.name in values).map((env) => ({
|
|
13442
|
-
env: env.name,
|
|
13443
|
-
filePath: path8.join(
|
|
13444
|
-
repoRoot,
|
|
13445
|
-
manifest.file_pattern.replace("{namespace}", namespace).replace("{environment}", env.name)
|
|
13446
|
-
)
|
|
13447
|
-
}));
|
|
13448
|
-
if (targets.length === 0) return;
|
|
13449
|
-
await this.tx.run(repoRoot, {
|
|
13450
|
-
description: `clef set: ${namespace}/${key} across ${targets.length} env(s)`,
|
|
13451
|
-
paths: targets.map((t) => path8.relative(repoRoot, t.filePath)),
|
|
13452
|
-
mutate: async () => {
|
|
13453
|
-
for (const target of targets) {
|
|
13454
|
-
const decrypted = await sopsClient.decrypt(target.filePath);
|
|
13455
|
-
decrypted.values[key] = values[target.env];
|
|
13456
|
-
await sopsClient.encrypt(target.filePath, decrypted.values, manifest, target.env);
|
|
13457
|
-
}
|
|
13458
|
-
}
|
|
13459
|
-
});
|
|
13460
|
-
}
|
|
13461
|
-
/**
|
|
13462
|
-
* Delete a key from every environment in a namespace.
|
|
13463
|
-
*
|
|
13464
|
-
* @param namespace - Target namespace.
|
|
13465
|
-
* @param key - Secret key name to delete.
|
|
13466
|
-
* @param manifest - Parsed manifest.
|
|
13467
|
-
* @param sopsClient - SOPS client.
|
|
13468
|
-
* @param repoRoot - Absolute path to the repository root.
|
|
13469
|
-
*/
|
|
13470
|
-
async deleteAcrossEnvironments(namespace, key, manifest, sopsClient, repoRoot) {
|
|
13471
|
-
const targets = manifest.environments.map((env) => ({
|
|
13472
|
-
env: env.name,
|
|
13473
|
-
filePath: path8.join(
|
|
13474
|
-
repoRoot,
|
|
13475
|
-
manifest.file_pattern.replace("{namespace}", namespace).replace("{environment}", env.name)
|
|
13476
|
-
)
|
|
13477
|
-
}));
|
|
13478
|
-
await this.tx.run(repoRoot, {
|
|
13479
|
-
description: `clef delete: ${namespace}/${key} from ${targets.length} env(s)`,
|
|
13480
|
-
paths: targets.map((t) => path8.relative(repoRoot, t.filePath)),
|
|
13481
|
-
mutate: async () => {
|
|
13482
|
-
for (const target of targets) {
|
|
13483
|
-
const decrypted = await sopsClient.decrypt(target.filePath);
|
|
13484
|
-
if (key in decrypted.values) {
|
|
13485
|
-
delete decrypted.values[key];
|
|
13486
|
-
await sopsClient.encrypt(target.filePath, decrypted.values, manifest, target.env);
|
|
13487
|
-
}
|
|
13488
|
-
}
|
|
13489
|
-
}
|
|
13490
|
-
});
|
|
13491
|
-
}
|
|
13492
|
-
/**
|
|
13493
|
-
* Copy a single key's value from one matrix cell to another.
|
|
13494
|
-
*
|
|
13495
|
-
* @param key - Secret key name to copy.
|
|
13496
|
-
* @param fromCell - Source matrix cell.
|
|
13497
|
-
* @param toCell - Destination matrix cell.
|
|
13498
|
-
* @param sopsClient - SOPS client.
|
|
13499
|
-
* @param manifest - Parsed manifest.
|
|
13500
|
-
* @param repoRoot - Absolute path to the repository root.
|
|
13501
|
-
* @throws `Error` if the key does not exist in the source cell.
|
|
13502
|
-
*/
|
|
13503
|
-
async copyValue(key, fromCell, toCell, sopsClient, manifest, repoRoot) {
|
|
13504
|
-
const source = await sopsClient.decrypt(fromCell.filePath);
|
|
13505
|
-
if (!(key in source.values)) {
|
|
13506
|
-
throw new Error(
|
|
13507
|
-
`Key '${key}' does not exist in ${fromCell.namespace}/${fromCell.environment}.`
|
|
13508
|
-
);
|
|
13509
|
-
}
|
|
13510
|
-
await this.tx.run(repoRoot, {
|
|
13511
|
-
description: `clef copy: ${key} from ${fromCell.namespace}/${fromCell.environment} to ${toCell.namespace}/${toCell.environment}`,
|
|
13512
|
-
paths: [path8.relative(repoRoot, toCell.filePath)],
|
|
13513
|
-
mutate: async () => {
|
|
13514
|
-
const dest = await sopsClient.decrypt(toCell.filePath);
|
|
13515
|
-
dest.values[key] = source.values[key];
|
|
13516
|
-
await sopsClient.encrypt(toCell.filePath, dest.values, manifest, toCell.environment);
|
|
13517
|
-
}
|
|
13518
|
-
});
|
|
13519
|
-
}
|
|
13520
|
-
};
|
|
13521
|
-
|
|
13522
13369
|
// src/git/integration.ts
|
|
13523
13370
|
var fs10 = __toESM(require("fs"));
|
|
13524
|
-
var
|
|
13371
|
+
var path7 = __toESM(require("path"));
|
|
13525
13372
|
var PRE_COMMIT_HOOK = `#!/bin/sh
|
|
13526
13373
|
# Clef pre-commit hook \u2014 blocks commits of files missing SOPS encryption metadata
|
|
13527
13374
|
# and scans staged files for plaintext secrets.
|
|
@@ -13697,17 +13544,17 @@ var GitIntegration = class {
|
|
|
13697
13544
|
* @returns The kind of operation in progress, or null if none.
|
|
13698
13545
|
*/
|
|
13699
13546
|
async isMidOperation(repoRoot) {
|
|
13700
|
-
const gitDir =
|
|
13701
|
-
if (fs10.existsSync(
|
|
13547
|
+
const gitDir = path7.join(repoRoot, ".git");
|
|
13548
|
+
if (fs10.existsSync(path7.join(gitDir, "MERGE_HEAD"))) {
|
|
13702
13549
|
return { midOp: true, kind: "merge" };
|
|
13703
13550
|
}
|
|
13704
|
-
if (fs10.existsSync(
|
|
13551
|
+
if (fs10.existsSync(path7.join(gitDir, "rebase-merge")) || fs10.existsSync(path7.join(gitDir, "rebase-apply"))) {
|
|
13705
13552
|
return { midOp: true, kind: "rebase" };
|
|
13706
13553
|
}
|
|
13707
|
-
if (fs10.existsSync(
|
|
13554
|
+
if (fs10.existsSync(path7.join(gitDir, "CHERRY_PICK_HEAD"))) {
|
|
13708
13555
|
return { midOp: true, kind: "cherry-pick" };
|
|
13709
13556
|
}
|
|
13710
|
-
if (fs10.existsSync(
|
|
13557
|
+
if (fs10.existsSync(path7.join(gitDir, "REVERT_HEAD"))) {
|
|
13711
13558
|
return { midOp: true, kind: "revert" };
|
|
13712
13559
|
}
|
|
13713
13560
|
return { midOp: false };
|
|
@@ -13919,14 +13766,14 @@ var GitIntegration = class {
|
|
|
13919
13766
|
{ cwd: repoRoot }
|
|
13920
13767
|
);
|
|
13921
13768
|
const metadataGitConfig = metaConfig.exitCode === 0 && metaConfig.stdout.trim().length > 0;
|
|
13922
|
-
const attrFilePath =
|
|
13769
|
+
const attrFilePath = path7.join(repoRoot, ".gitattributes");
|
|
13923
13770
|
const attrContent = fs10.existsSync(attrFilePath) ? fs10.readFileSync(attrFilePath, "utf-8") : "";
|
|
13924
13771
|
const gitattributes = attrContent.includes("merge=sops");
|
|
13925
13772
|
const metadataGitattributes = attrContent.includes("merge=clef-metadata");
|
|
13926
13773
|
return { gitConfig, gitattributes, metadataGitConfig, metadataGitattributes };
|
|
13927
13774
|
}
|
|
13928
13775
|
async ensureGitattributes(repoRoot) {
|
|
13929
|
-
const attrPath =
|
|
13776
|
+
const attrPath = path7.join(repoRoot, ".gitattributes");
|
|
13930
13777
|
const existing = fs10.existsSync(attrPath) ? fs10.readFileSync(attrPath, "utf-8") : "";
|
|
13931
13778
|
let newContent = existing;
|
|
13932
13779
|
if (!existing.includes("merge=sops")) {
|
|
@@ -13961,9 +13808,9 @@ ${block}` : block;
|
|
|
13961
13808
|
* @throws {@link GitOperationError} On failure.
|
|
13962
13809
|
*/
|
|
13963
13810
|
async installPreCommitHook(repoRoot) {
|
|
13964
|
-
const hookPath =
|
|
13811
|
+
const hookPath = path7.join(repoRoot, ".git", "hooks", "pre-commit");
|
|
13965
13812
|
try {
|
|
13966
|
-
const hooksDir =
|
|
13813
|
+
const hooksDir = path7.dirname(hookPath);
|
|
13967
13814
|
if (!fs10.existsSync(hooksDir)) {
|
|
13968
13815
|
fs10.mkdirSync(hooksDir, { recursive: true });
|
|
13969
13816
|
}
|
|
@@ -13979,7 +13826,7 @@ ${block}` : block;
|
|
|
13979
13826
|
|
|
13980
13827
|
// src/tx/transaction-manager.ts
|
|
13981
13828
|
var fs11 = __toESM(require("fs"));
|
|
13982
|
-
var
|
|
13829
|
+
var path8 = __toESM(require("path"));
|
|
13983
13830
|
var lockfile = __toESM(require_proper_lockfile());
|
|
13984
13831
|
|
|
13985
13832
|
// src/tx/errors.ts
|
|
@@ -14028,15 +13875,15 @@ var TransactionManager = class {
|
|
|
14028
13875
|
async run(repoRoot, opts) {
|
|
14029
13876
|
const shouldCommit = opts.commit !== false;
|
|
14030
13877
|
const allowDirty = opts.allowDirty === true;
|
|
14031
|
-
const clefDir =
|
|
13878
|
+
const clefDir = path8.join(repoRoot, CLEF_DIR);
|
|
14032
13879
|
if (!fs11.existsSync(clefDir)) {
|
|
14033
13880
|
fs11.mkdirSync(clefDir, { recursive: true });
|
|
14034
13881
|
}
|
|
14035
|
-
const clefGitignore =
|
|
13882
|
+
const clefGitignore = path8.join(clefDir, ".gitignore");
|
|
14036
13883
|
if (!fs11.existsSync(clefGitignore)) {
|
|
14037
13884
|
fs11.writeFileSync(clefGitignore, "*\n");
|
|
14038
13885
|
}
|
|
14039
|
-
const lockPath =
|
|
13886
|
+
const lockPath = path8.join(clefDir, LOCK_FILE);
|
|
14040
13887
|
if (!fs11.existsSync(lockPath)) {
|
|
14041
13888
|
fs11.writeFileSync(lockPath, "");
|
|
14042
13889
|
}
|
|
@@ -14177,16 +14024,15 @@ var TransactionManager = class {
|
|
|
14177
14024
|
var fs14 = __toESM(require("fs"));
|
|
14178
14025
|
var net = __toESM(require("net"));
|
|
14179
14026
|
var import_crypto = require("crypto");
|
|
14180
|
-
var import_write_file_atomic3 = __toESM(require_lib());
|
|
14181
14027
|
var YAML8 = __toESM(require("yaml"));
|
|
14182
14028
|
|
|
14183
14029
|
// src/sops/resolver.ts
|
|
14184
14030
|
var fs13 = __toESM(require("fs"));
|
|
14185
|
-
var
|
|
14031
|
+
var path10 = __toESM(require("path"));
|
|
14186
14032
|
|
|
14187
14033
|
// src/sops/bundled.ts
|
|
14188
14034
|
var fs12 = __toESM(require("fs"));
|
|
14189
|
-
var
|
|
14035
|
+
var path9 = __toESM(require("path"));
|
|
14190
14036
|
function tryBundled() {
|
|
14191
14037
|
const platform = process.platform;
|
|
14192
14038
|
const arch = process.arch;
|
|
@@ -14198,8 +14044,8 @@ function tryBundled() {
|
|
|
14198
14044
|
const binName = platform === "win32" ? "sops.exe" : "sops";
|
|
14199
14045
|
try {
|
|
14200
14046
|
const packageMain = require.resolve(`${packageName}/package.json`);
|
|
14201
|
-
const packageDir =
|
|
14202
|
-
const binPath =
|
|
14047
|
+
const packageDir = path9.dirname(packageMain);
|
|
14048
|
+
const binPath = path9.join(packageDir, "bin", binName);
|
|
14203
14049
|
return fs12.existsSync(binPath) ? binPath : null;
|
|
14204
14050
|
} catch {
|
|
14205
14051
|
return null;
|
|
@@ -14208,7 +14054,7 @@ function tryBundled() {
|
|
|
14208
14054
|
|
|
14209
14055
|
// src/sops/resolver.ts
|
|
14210
14056
|
function validateSopsPath(candidate) {
|
|
14211
|
-
if (!
|
|
14057
|
+
if (!path10.isAbsolute(candidate)) {
|
|
14212
14058
|
throw new Error(`CLEF_SOPS_PATH must be an absolute path, got '${candidate}'.`);
|
|
14213
14059
|
}
|
|
14214
14060
|
const segments = candidate.split(/[/\\]/);
|
|
@@ -14387,6 +14233,17 @@ function isClefHsmArn(arn) {
|
|
|
14387
14233
|
function formatFromPath(filePath) {
|
|
14388
14234
|
return filePath.endsWith(".json") ? "json" : "yaml";
|
|
14389
14235
|
}
|
|
14236
|
+
async function openInputPipe(content) {
|
|
14237
|
+
if (process.platform === "win32") {
|
|
14238
|
+
const pipe = await openWindowsInputPipe(content);
|
|
14239
|
+
return { inputArg: pipe.inputArg, cleanup: pipe.cleanup };
|
|
14240
|
+
}
|
|
14241
|
+
return { inputArg: "/dev/stdin", cleanup: () => {
|
|
14242
|
+
}, runnerStdin: content };
|
|
14243
|
+
}
|
|
14244
|
+
function nullConfigPath() {
|
|
14245
|
+
return process.platform === "win32" ? "NUL" : "/dev/null";
|
|
14246
|
+
}
|
|
14390
14247
|
function openWindowsInputPipe(content) {
|
|
14391
14248
|
const pipeName = `\\\\.\\pipe\\clef-sops-${(0, import_crypto.randomBytes)(8).toString("hex")}`;
|
|
14392
14249
|
return new Promise((resolve2, reject) => {
|
|
@@ -14434,6 +14291,10 @@ var SopsClient = class {
|
|
|
14434
14291
|
runner;
|
|
14435
14292
|
ageKeyFile;
|
|
14436
14293
|
ageKey;
|
|
14294
|
+
/** {@link EncryptionBackend} identifier. */
|
|
14295
|
+
id = "sops";
|
|
14296
|
+
/** {@link EncryptionBackend} short description (used by `clef doctor`). */
|
|
14297
|
+
description = "SOPS-based encryption via the bundled `sops` binary";
|
|
14437
14298
|
sopsCommand;
|
|
14438
14299
|
keyserviceArgs;
|
|
14439
14300
|
buildSopsEnv() {
|
|
@@ -14447,14 +14308,18 @@ var SopsClient = class {
|
|
|
14447
14308
|
return Object.keys(env).length > 0 ? env : void 0;
|
|
14448
14309
|
}
|
|
14449
14310
|
/**
|
|
14450
|
-
* Decrypt a SOPS-encrypted file
|
|
14311
|
+
* Decrypt a SOPS-encrypted file by path. The only remaining file-path
|
|
14312
|
+
* entry point on this class — kept for the merge driver, which
|
|
14313
|
+
* receives temp filesystem paths from git that don't map onto a
|
|
14314
|
+
* `CellRef`. Production `SecretSource` consumers should call
|
|
14315
|
+
* `source.readCell` instead.
|
|
14451
14316
|
*
|
|
14452
14317
|
* @param filePath - Path to the `.enc.yaml` or `.enc.json` file.
|
|
14453
14318
|
* @returns {@link DecryptedFile} with plaintext values in memory only.
|
|
14454
14319
|
* @throws {@link SopsKeyNotFoundError} If no matching decryption key is available.
|
|
14455
14320
|
* @throws {@link SopsDecryptionError} On any other decryption failure.
|
|
14456
14321
|
*/
|
|
14457
|
-
async
|
|
14322
|
+
async decryptFile(filePath) {
|
|
14458
14323
|
await assertSops(this.runner, this.sopsCommand);
|
|
14459
14324
|
const fmt = formatFromPath(filePath);
|
|
14460
14325
|
const env = this.buildSopsEnv();
|
|
@@ -14490,170 +14355,9 @@ var SopsClient = class {
|
|
|
14490
14355
|
for (const [key, value] of Object.entries(parsed)) {
|
|
14491
14356
|
values[key] = String(value);
|
|
14492
14357
|
}
|
|
14493
|
-
const metadata =
|
|
14358
|
+
const metadata = this.parseMetadataFromFile(filePath);
|
|
14494
14359
|
return { values, metadata };
|
|
14495
14360
|
}
|
|
14496
|
-
/**
|
|
14497
|
-
* Encrypt a key/value map and write it to an encrypted SOPS file.
|
|
14498
|
-
*
|
|
14499
|
-
* @param filePath - Destination path for the encrypted file.
|
|
14500
|
-
* @param values - Flat key/value map to encrypt.
|
|
14501
|
-
* @param manifest - Manifest used to determine the encryption backend and key configuration.
|
|
14502
|
-
* @param environment - Optional environment name. When provided, per-env backend overrides
|
|
14503
|
-
* are resolved from the manifest. When omitted, the global `sops.default_backend` is used.
|
|
14504
|
-
* @throws {@link SopsEncryptionError} On encryption or write failure.
|
|
14505
|
-
*/
|
|
14506
|
-
async encrypt(filePath, values, manifest, environment) {
|
|
14507
|
-
await assertSops(this.runner, this.sopsCommand);
|
|
14508
|
-
const fmt = formatFromPath(filePath);
|
|
14509
|
-
const content = fmt === "json" ? JSON.stringify(values, null, 2) : YAML8.stringify(values);
|
|
14510
|
-
const args = this.buildEncryptArgs(filePath, manifest, environment);
|
|
14511
|
-
const env = this.buildSopsEnv();
|
|
14512
|
-
let inputArg;
|
|
14513
|
-
let pipeCleanup;
|
|
14514
|
-
if (process.platform === "win32") {
|
|
14515
|
-
const pipe = await openWindowsInputPipe(content);
|
|
14516
|
-
inputArg = pipe.inputArg;
|
|
14517
|
-
pipeCleanup = pipe.cleanup;
|
|
14518
|
-
} else {
|
|
14519
|
-
inputArg = "/dev/stdin";
|
|
14520
|
-
}
|
|
14521
|
-
let result;
|
|
14522
|
-
try {
|
|
14523
|
-
const configPath = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
14524
|
-
result = await this.runner.run(
|
|
14525
|
-
this.sopsCommand,
|
|
14526
|
-
[
|
|
14527
|
-
"--config",
|
|
14528
|
-
configPath,
|
|
14529
|
-
"encrypt",
|
|
14530
|
-
...this.keyserviceArgs,
|
|
14531
|
-
...args,
|
|
14532
|
-
"--input-type",
|
|
14533
|
-
fmt,
|
|
14534
|
-
"--output-type",
|
|
14535
|
-
fmt,
|
|
14536
|
-
"--filename-override",
|
|
14537
|
-
filePath,
|
|
14538
|
-
inputArg
|
|
14539
|
-
],
|
|
14540
|
-
{
|
|
14541
|
-
// stdin is still piped on Unix (/dev/stdin reads from it);
|
|
14542
|
-
// on Windows the named pipe server feeds content directly.
|
|
14543
|
-
...process.platform !== "win32" ? { stdin: content } : {},
|
|
14544
|
-
...env ? { env } : {}
|
|
14545
|
-
}
|
|
14546
|
-
);
|
|
14547
|
-
} finally {
|
|
14548
|
-
pipeCleanup?.();
|
|
14549
|
-
}
|
|
14550
|
-
if (result.exitCode !== 0) {
|
|
14551
|
-
throw new SopsEncryptionError(
|
|
14552
|
-
`Failed to encrypt '${filePath}': ${result.stderr.trim()}`,
|
|
14553
|
-
filePath
|
|
14554
|
-
);
|
|
14555
|
-
}
|
|
14556
|
-
try {
|
|
14557
|
-
await (0, import_write_file_atomic3.default)(filePath, result.stdout);
|
|
14558
|
-
} catch (err) {
|
|
14559
|
-
throw new SopsEncryptionError(
|
|
14560
|
-
`Failed to write encrypted data to '${filePath}': ${err.message}`,
|
|
14561
|
-
filePath
|
|
14562
|
-
);
|
|
14563
|
-
}
|
|
14564
|
-
}
|
|
14565
|
-
/**
|
|
14566
|
-
* Rotate encryption by adding a new age recipient key to an existing SOPS file.
|
|
14567
|
-
*
|
|
14568
|
-
* @param filePath - Path to the encrypted file to re-encrypt.
|
|
14569
|
-
* @param newKey - New age public key to add as a recipient.
|
|
14570
|
-
* @throws {@link SopsEncryptionError} On failure.
|
|
14571
|
-
*/
|
|
14572
|
-
async reEncrypt(filePath, newKey) {
|
|
14573
|
-
await this.addRecipient(filePath, newKey);
|
|
14574
|
-
}
|
|
14575
|
-
/**
|
|
14576
|
-
* Add an age recipient to an existing SOPS file.
|
|
14577
|
-
*
|
|
14578
|
-
* @param filePath - Path to the encrypted file.
|
|
14579
|
-
* @param key - age public key to add as a recipient.
|
|
14580
|
-
* @throws {@link SopsEncryptionError} On failure.
|
|
14581
|
-
*/
|
|
14582
|
-
async addRecipient(filePath, key) {
|
|
14583
|
-
await assertSops(this.runner, this.sopsCommand);
|
|
14584
|
-
const env = this.buildSopsEnv();
|
|
14585
|
-
const result = await this.runner.run(
|
|
14586
|
-
this.sopsCommand,
|
|
14587
|
-
["rotate", ...this.keyserviceArgs, "-i", "--add-age", key, filePath],
|
|
14588
|
-
{
|
|
14589
|
-
...env ? { env } : {}
|
|
14590
|
-
}
|
|
14591
|
-
);
|
|
14592
|
-
if (result.exitCode !== 0) {
|
|
14593
|
-
throw new SopsEncryptionError(
|
|
14594
|
-
`Failed to add recipient to '${filePath}': ${result.stderr.trim()}`,
|
|
14595
|
-
filePath
|
|
14596
|
-
);
|
|
14597
|
-
}
|
|
14598
|
-
}
|
|
14599
|
-
/**
|
|
14600
|
-
* Remove an age recipient from an existing SOPS file.
|
|
14601
|
-
*
|
|
14602
|
-
* @param filePath - Path to the encrypted file.
|
|
14603
|
-
* @param key - age public key to remove.
|
|
14604
|
-
* @throws {@link SopsEncryptionError} On failure.
|
|
14605
|
-
*/
|
|
14606
|
-
async removeRecipient(filePath, key) {
|
|
14607
|
-
await assertSops(this.runner, this.sopsCommand);
|
|
14608
|
-
const env = this.buildSopsEnv();
|
|
14609
|
-
const result = await this.runner.run(
|
|
14610
|
-
this.sopsCommand,
|
|
14611
|
-
["rotate", ...this.keyserviceArgs, "-i", "--rm-age", key, filePath],
|
|
14612
|
-
{
|
|
14613
|
-
...env ? { env } : {}
|
|
14614
|
-
}
|
|
14615
|
-
);
|
|
14616
|
-
if (result.exitCode !== 0) {
|
|
14617
|
-
throw new SopsEncryptionError(
|
|
14618
|
-
`Failed to remove recipient from '${filePath}': ${result.stderr.trim()}`,
|
|
14619
|
-
filePath
|
|
14620
|
-
);
|
|
14621
|
-
}
|
|
14622
|
-
}
|
|
14623
|
-
/**
|
|
14624
|
-
* Check whether a file contains valid SOPS encryption metadata.
|
|
14625
|
-
*
|
|
14626
|
-
* @param filePath - Path to the file to check.
|
|
14627
|
-
* @returns `true` if valid SOPS metadata is present; `false` otherwise. Never throws.
|
|
14628
|
-
*/
|
|
14629
|
-
async validateEncryption(filePath) {
|
|
14630
|
-
await assertSops(this.runner, this.sopsCommand);
|
|
14631
|
-
try {
|
|
14632
|
-
await this.getMetadata(filePath);
|
|
14633
|
-
return true;
|
|
14634
|
-
} catch {
|
|
14635
|
-
return false;
|
|
14636
|
-
}
|
|
14637
|
-
}
|
|
14638
|
-
/**
|
|
14639
|
-
* Extract SOPS metadata (backend, recipients, last-modified timestamp) from an encrypted file
|
|
14640
|
-
* without decrypting its values.
|
|
14641
|
-
*
|
|
14642
|
-
* @param filePath - Path to the encrypted file.
|
|
14643
|
-
* @returns {@link SopsMetadata} parsed from the file's `sops:` block.
|
|
14644
|
-
* @throws {@link SopsDecryptionError} If the file cannot be read or parsed.
|
|
14645
|
-
*/
|
|
14646
|
-
async getMetadata(filePath) {
|
|
14647
|
-
await assertSops(this.runner, this.sopsCommand);
|
|
14648
|
-
const env = this.buildSopsEnv();
|
|
14649
|
-
const result = await this.runner.run(this.sopsCommand, ["filestatus", filePath], {
|
|
14650
|
-
...env ? { env } : {}
|
|
14651
|
-
});
|
|
14652
|
-
if (result.exitCode !== 0) {
|
|
14653
|
-
return this.parseMetadataFromFile(filePath);
|
|
14654
|
-
}
|
|
14655
|
-
return this.parseMetadataFromFile(filePath);
|
|
14656
|
-
}
|
|
14657
14361
|
/**
|
|
14658
14362
|
* Determine whether a decrypt failure is caused by a missing/mismatched key (vs. some other
|
|
14659
14363
|
* SOPS error) without relying on stderr message text.
|
|
@@ -14697,20 +14401,30 @@ var SopsClient = class {
|
|
|
14697
14401
|
filePath
|
|
14698
14402
|
);
|
|
14699
14403
|
}
|
|
14404
|
+
return this.parseMetadataFromContent(content, filePath);
|
|
14405
|
+
}
|
|
14406
|
+
/**
|
|
14407
|
+
* Parse SOPS metadata from a string (no IO). Used by both
|
|
14408
|
+
* `parseMetadataFromFile` (after reading from disk) and the blob-shaped
|
|
14409
|
+
* `getMetadataFromBlob` (which receives ciphertext directly from a
|
|
14410
|
+
* BlobStore). The `label` is woven into error messages so callers can
|
|
14411
|
+
* include the file path or cell ref the content came from.
|
|
14412
|
+
*/
|
|
14413
|
+
parseMetadataFromContent(content, label) {
|
|
14700
14414
|
let parsed;
|
|
14701
14415
|
try {
|
|
14702
14416
|
parsed = YAML8.parse(content);
|
|
14703
14417
|
} catch {
|
|
14704
14418
|
throw new SopsDecryptionError(
|
|
14705
|
-
|
|
14706
|
-
|
|
14419
|
+
`${label} is not valid YAML. Cannot extract SOPS metadata.`,
|
|
14420
|
+
label
|
|
14707
14421
|
);
|
|
14708
14422
|
}
|
|
14709
14423
|
const sops = parsed?.sops;
|
|
14710
14424
|
if (!sops) {
|
|
14711
14425
|
throw new SopsDecryptionError(
|
|
14712
|
-
|
|
14713
|
-
|
|
14426
|
+
`${label} does not contain SOPS metadata. It may not be encrypted.`,
|
|
14427
|
+
label
|
|
14714
14428
|
);
|
|
14715
14429
|
}
|
|
14716
14430
|
const backend = this.detectBackend(sops);
|
|
@@ -14773,7 +14487,7 @@ var SopsClient = class {
|
|
|
14773
14487
|
}
|
|
14774
14488
|
}
|
|
14775
14489
|
}
|
|
14776
|
-
buildEncryptArgs(
|
|
14490
|
+
buildEncryptArgs(manifest, environment) {
|
|
14777
14491
|
const args = [];
|
|
14778
14492
|
const config = environment ? resolveBackendConfig(manifest, environment) : {
|
|
14779
14493
|
backend: manifest.sops.default_backend,
|
|
@@ -14821,11 +14535,255 @@ var SopsClient = class {
|
|
|
14821
14535
|
}
|
|
14822
14536
|
return args;
|
|
14823
14537
|
}
|
|
14538
|
+
// ── Blob-shaped methods ─────────────────────────────────────────────────
|
|
14539
|
+
//
|
|
14540
|
+
// These mirror the file-path methods above but operate on opaque
|
|
14541
|
+
// ciphertext bytes via SOPS' stdin/stdout. They are the substrate-
|
|
14542
|
+
// agnostic primitives used by the `composeSecretSource` factory to
|
|
14543
|
+
// wrap any `BlobStore` (filesystem, postgres, etc.) into a full
|
|
14544
|
+
// `SecretSource`. Plaintext never leaves the SOPS subprocess.
|
|
14545
|
+
/**
|
|
14546
|
+
* {@link EncryptionBackend.decrypt} — decrypt SOPS-encrypted bytes (e.g.
|
|
14547
|
+
* read from a `StorageBackend`) and return plaintext values + metadata.
|
|
14548
|
+
* Plaintext lives only in memory.
|
|
14549
|
+
*/
|
|
14550
|
+
async decrypt(blob, ctx) {
|
|
14551
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14552
|
+
const env = this.buildSopsEnv();
|
|
14553
|
+
const pipe = await openInputPipe(blob);
|
|
14554
|
+
let result;
|
|
14555
|
+
try {
|
|
14556
|
+
result = await this.runner.run(
|
|
14557
|
+
this.sopsCommand,
|
|
14558
|
+
[
|
|
14559
|
+
"decrypt",
|
|
14560
|
+
...this.keyserviceArgs,
|
|
14561
|
+
"--input-type",
|
|
14562
|
+
ctx.format,
|
|
14563
|
+
"--output-type",
|
|
14564
|
+
ctx.format,
|
|
14565
|
+
pipe.inputArg
|
|
14566
|
+
],
|
|
14567
|
+
{
|
|
14568
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14569
|
+
...env ? { env } : {}
|
|
14570
|
+
}
|
|
14571
|
+
);
|
|
14572
|
+
} finally {
|
|
14573
|
+
pipe.cleanup();
|
|
14574
|
+
}
|
|
14575
|
+
if (result.exitCode !== 0) {
|
|
14576
|
+
const errorType = await this.classifyDecryptErrorFromContent(blob);
|
|
14577
|
+
if (errorType === "key-not-found") {
|
|
14578
|
+
throw new SopsKeyNotFoundError(`No decryption key found for cell. ${result.stderr.trim()}`);
|
|
14579
|
+
}
|
|
14580
|
+
throw new SopsDecryptionError(`Failed to decrypt cell: ${result.stderr.trim()}`);
|
|
14581
|
+
}
|
|
14582
|
+
let parsed;
|
|
14583
|
+
try {
|
|
14584
|
+
parsed = YAML8.parse(result.stdout) ?? {};
|
|
14585
|
+
} catch {
|
|
14586
|
+
throw new SopsDecryptionError("Decrypted content is not valid YAML.");
|
|
14587
|
+
}
|
|
14588
|
+
const values = {};
|
|
14589
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
14590
|
+
values[key] = String(value);
|
|
14591
|
+
}
|
|
14592
|
+
const metadata = this.parseMetadataFromContent(blob, "<cell>");
|
|
14593
|
+
return { values, metadata };
|
|
14594
|
+
}
|
|
14595
|
+
/**
|
|
14596
|
+
* {@link EncryptionBackend.encrypt} — encrypt plaintext values into a
|
|
14597
|
+
* SOPS-formatted ciphertext blob. Returns the bytes as a string;
|
|
14598
|
+
* caller (typically a `StorageBackend`) decides where to put them.
|
|
14599
|
+
* Plaintext is piped via stdin only.
|
|
14600
|
+
*/
|
|
14601
|
+
async encrypt(values, ctx) {
|
|
14602
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14603
|
+
const content = ctx.format === "json" ? JSON.stringify(values, null, 2) : YAML8.stringify(values);
|
|
14604
|
+
const args = this.buildEncryptArgs(ctx.manifest, ctx.environment);
|
|
14605
|
+
const env = this.buildSopsEnv();
|
|
14606
|
+
const pipe = await openInputPipe(content);
|
|
14607
|
+
let result;
|
|
14608
|
+
try {
|
|
14609
|
+
result = await this.runner.run(
|
|
14610
|
+
this.sopsCommand,
|
|
14611
|
+
[
|
|
14612
|
+
"--config",
|
|
14613
|
+
nullConfigPath(),
|
|
14614
|
+
"encrypt",
|
|
14615
|
+
...this.keyserviceArgs,
|
|
14616
|
+
...args,
|
|
14617
|
+
"--input-type",
|
|
14618
|
+
ctx.format,
|
|
14619
|
+
"--output-type",
|
|
14620
|
+
ctx.format,
|
|
14621
|
+
pipe.inputArg
|
|
14622
|
+
],
|
|
14623
|
+
{
|
|
14624
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14625
|
+
...env ? { env } : {}
|
|
14626
|
+
}
|
|
14627
|
+
);
|
|
14628
|
+
} finally {
|
|
14629
|
+
pipe.cleanup();
|
|
14630
|
+
}
|
|
14631
|
+
if (result.exitCode !== 0) {
|
|
14632
|
+
throw new SopsEncryptionError(`Failed to encrypt cell: ${result.stderr.trim()}`);
|
|
14633
|
+
}
|
|
14634
|
+
return result.stdout;
|
|
14635
|
+
}
|
|
14636
|
+
/**
|
|
14637
|
+
* {@link EncryptionBackend.rotate} — add or remove recipients from an
|
|
14638
|
+
* encrypted SOPS blob via stdin/stdout. Drops the in-place `-i` flag
|
|
14639
|
+
* the deleted file-path-shaped methods used, so SOPS writes the
|
|
14640
|
+
* rotated ciphertext to stdout instead of back to a file. Plaintext
|
|
14641
|
+
* stays inside the SOPS subprocess; no plaintext window exists in
|
|
14642
|
+
* this Node process.
|
|
14643
|
+
*
|
|
14644
|
+
* Single SOPS invocation can both add and remove recipients
|
|
14645
|
+
* simultaneously (matches the CLI flag set).
|
|
14646
|
+
*/
|
|
14647
|
+
async rotate(blob, opts, ctx) {
|
|
14648
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14649
|
+
const env = this.buildSopsEnv();
|
|
14650
|
+
const pipe = await openInputPipe(blob);
|
|
14651
|
+
const flagArgs = [];
|
|
14652
|
+
if (opts.addAge) flagArgs.push("--add-age", opts.addAge);
|
|
14653
|
+
if (opts.rmAge) flagArgs.push("--rm-age", opts.rmAge);
|
|
14654
|
+
if (opts.addKms) flagArgs.push("--add-kms", opts.addKms);
|
|
14655
|
+
if (opts.rmKms) flagArgs.push("--rm-kms", opts.rmKms);
|
|
14656
|
+
if (opts.addGcpKms) flagArgs.push("--add-gcp-kms", opts.addGcpKms);
|
|
14657
|
+
if (opts.rmGcpKms) flagArgs.push("--rm-gcp-kms", opts.rmGcpKms);
|
|
14658
|
+
if (opts.addAzureKv) flagArgs.push("--add-azure-kv", opts.addAzureKv);
|
|
14659
|
+
if (opts.rmAzureKv) flagArgs.push("--rm-azure-kv", opts.rmAzureKv);
|
|
14660
|
+
if (opts.addPgp) flagArgs.push("--add-pgp", opts.addPgp);
|
|
14661
|
+
if (opts.rmPgp) flagArgs.push("--rm-pgp", opts.rmPgp);
|
|
14662
|
+
let result;
|
|
14663
|
+
try {
|
|
14664
|
+
result = await this.runner.run(
|
|
14665
|
+
this.sopsCommand,
|
|
14666
|
+
[
|
|
14667
|
+
"--config",
|
|
14668
|
+
nullConfigPath(),
|
|
14669
|
+
"rotate",
|
|
14670
|
+
...this.keyserviceArgs,
|
|
14671
|
+
...flagArgs,
|
|
14672
|
+
"--input-type",
|
|
14673
|
+
ctx.format,
|
|
14674
|
+
"--output-type",
|
|
14675
|
+
ctx.format,
|
|
14676
|
+
pipe.inputArg
|
|
14677
|
+
],
|
|
14678
|
+
{
|
|
14679
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14680
|
+
...env ? { env } : {}
|
|
14681
|
+
}
|
|
14682
|
+
);
|
|
14683
|
+
} finally {
|
|
14684
|
+
pipe.cleanup();
|
|
14685
|
+
}
|
|
14686
|
+
if (result.exitCode !== 0) {
|
|
14687
|
+
throw new SopsEncryptionError(`Failed to rotate cell: ${result.stderr.trim()}`);
|
|
14688
|
+
}
|
|
14689
|
+
return result.stdout;
|
|
14690
|
+
}
|
|
14691
|
+
/**
|
|
14692
|
+
* {@link EncryptionBackend.getMetadata} — extract SOPS metadata from a
|
|
14693
|
+
* ciphertext blob without decrypting. Pure parser, no IO, no
|
|
14694
|
+
* subprocess.
|
|
14695
|
+
*/
|
|
14696
|
+
getMetadata(content) {
|
|
14697
|
+
return this.parseMetadataFromContent(content, "<cell>");
|
|
14698
|
+
}
|
|
14699
|
+
/**
|
|
14700
|
+
* {@link EncryptionBackend.validateEncryption} — whether `content` is a
|
|
14701
|
+
* valid SOPS-encrypted blob (parses + has the `sops:` metadata
|
|
14702
|
+
* block). Never throws.
|
|
14703
|
+
*/
|
|
14704
|
+
validateEncryption(content) {
|
|
14705
|
+
try {
|
|
14706
|
+
this.parseMetadataFromContent(content, "<cell>");
|
|
14707
|
+
return true;
|
|
14708
|
+
} catch {
|
|
14709
|
+
return false;
|
|
14710
|
+
}
|
|
14711
|
+
}
|
|
14712
|
+
/**
|
|
14713
|
+
* Blob-shaped variant of `classifyDecryptError`. Same logic as the
|
|
14714
|
+
* file-path version but reads metadata from the in-memory ciphertext
|
|
14715
|
+
* instead of disk.
|
|
14716
|
+
*/
|
|
14717
|
+
async classifyDecryptErrorFromContent(content) {
|
|
14718
|
+
let metadata;
|
|
14719
|
+
try {
|
|
14720
|
+
metadata = this.parseMetadataFromContent(content, "<cell>");
|
|
14721
|
+
} catch {
|
|
14722
|
+
return "other";
|
|
14723
|
+
}
|
|
14724
|
+
if (metadata.backend !== "age") return "other";
|
|
14725
|
+
if (!this.ageKey && !this.ageKeyFile) return "key-not-found";
|
|
14726
|
+
let keyContent;
|
|
14727
|
+
try {
|
|
14728
|
+
keyContent = this.ageKey ?? fs14.readFileSync(this.ageKeyFile, "utf-8");
|
|
14729
|
+
} catch {
|
|
14730
|
+
return "key-not-found";
|
|
14731
|
+
}
|
|
14732
|
+
const privateKeys = keyContent.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("AGE-SECRET-KEY-"));
|
|
14733
|
+
if (privateKeys.length === 0) return "key-not-found";
|
|
14734
|
+
try {
|
|
14735
|
+
const publicKeys = await Promise.all(privateKeys.map((k) => deriveAgePublicKey(k)));
|
|
14736
|
+
const recipients = new Set(metadata.recipients);
|
|
14737
|
+
return publicKeys.some((pk) => recipients.has(pk)) ? "other" : "key-not-found";
|
|
14738
|
+
} catch {
|
|
14739
|
+
return "other";
|
|
14740
|
+
}
|
|
14741
|
+
}
|
|
14824
14742
|
};
|
|
14825
14743
|
|
|
14744
|
+
// src/sops/linux-stdin-fifo.ts
|
|
14745
|
+
var os = __toESM(require("os"));
|
|
14746
|
+
var path11 = __toESM(require("path"));
|
|
14747
|
+
var import_child_process = require("child_process");
|
|
14748
|
+
function shouldUseLinuxStdinFifo() {
|
|
14749
|
+
return process.platform === "linux" && !process.env.JEST_WORKER_ID;
|
|
14750
|
+
}
|
|
14751
|
+
function wrapWithLinuxStdinFifo(runner) {
|
|
14752
|
+
if (!shouldUseLinuxStdinFifo()) return runner;
|
|
14753
|
+
return {
|
|
14754
|
+
run: (cmd, args, opts) => {
|
|
14755
|
+
const stdinIdx = args.indexOf("/dev/stdin");
|
|
14756
|
+
if (stdinIdx < 0 || opts?.stdin === void 0) {
|
|
14757
|
+
return runner.run(cmd, args, opts);
|
|
14758
|
+
}
|
|
14759
|
+
const fifoDir = (0, import_child_process.execFileSync)("mktemp", ["-d", path11.join(os.tmpdir(), "clef-fifo-XXXXXX")]).toString().trim();
|
|
14760
|
+
const fifoPath = path11.join(fifoDir, "input");
|
|
14761
|
+
(0, import_child_process.execFileSync)("mkfifo", [fifoPath]);
|
|
14762
|
+
const writer = (0, import_child_process.spawn)("dd", [`of=${fifoPath}`, "status=none"], {
|
|
14763
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
14764
|
+
});
|
|
14765
|
+
writer.stdin.write(opts.stdin);
|
|
14766
|
+
writer.stdin.end();
|
|
14767
|
+
const patchedArgs = [...args];
|
|
14768
|
+
patchedArgs[stdinIdx] = fifoPath;
|
|
14769
|
+
const { stdin: _stdin, ...restOpts } = opts;
|
|
14770
|
+
return runner.run(cmd, patchedArgs, restOpts).finally(() => {
|
|
14771
|
+
try {
|
|
14772
|
+
writer.kill();
|
|
14773
|
+
} catch {
|
|
14774
|
+
}
|
|
14775
|
+
try {
|
|
14776
|
+
(0, import_child_process.execFileSync)("rm", ["-rf", fifoDir]);
|
|
14777
|
+
} catch {
|
|
14778
|
+
}
|
|
14779
|
+
});
|
|
14780
|
+
}
|
|
14781
|
+
};
|
|
14782
|
+
}
|
|
14783
|
+
|
|
14826
14784
|
// src/hsm/bundled.ts
|
|
14827
14785
|
var fs15 = __toESM(require("fs"));
|
|
14828
|
-
var
|
|
14786
|
+
var path12 = __toESM(require("path"));
|
|
14829
14787
|
function tryBundledKeyservice() {
|
|
14830
14788
|
const platform = process.platform;
|
|
14831
14789
|
const arch = process.arch;
|
|
@@ -14837,8 +14795,8 @@ function tryBundledKeyservice() {
|
|
|
14837
14795
|
const binName = "clef-keyservice";
|
|
14838
14796
|
try {
|
|
14839
14797
|
const packageMain = require.resolve(`${packageName}/package.json`);
|
|
14840
|
-
const packageDir =
|
|
14841
|
-
const binPath =
|
|
14798
|
+
const packageDir = path12.dirname(packageMain);
|
|
14799
|
+
const binPath = path12.join(packageDir, "bin", binName);
|
|
14842
14800
|
return fs15.existsSync(binPath) ? binPath : null;
|
|
14843
14801
|
} catch {
|
|
14844
14802
|
return null;
|
|
@@ -14847,9 +14805,9 @@ function tryBundledKeyservice() {
|
|
|
14847
14805
|
|
|
14848
14806
|
// src/hsm/resolver.ts
|
|
14849
14807
|
var fs16 = __toESM(require("fs"));
|
|
14850
|
-
var
|
|
14808
|
+
var path13 = __toESM(require("path"));
|
|
14851
14809
|
function validateKeyservicePath(candidate) {
|
|
14852
|
-
if (!
|
|
14810
|
+
if (!path13.isAbsolute(candidate)) {
|
|
14853
14811
|
throw new Error(`CLEF_KEYSERVICE_PATH must be an absolute path, got '${candidate}'.`);
|
|
14854
14812
|
}
|
|
14855
14813
|
const segments = candidate.split(/[/\\]/);
|
|
@@ -14884,7 +14842,7 @@ function resetKeyserviceResolution() {
|
|
|
14884
14842
|
}
|
|
14885
14843
|
|
|
14886
14844
|
// src/hsm/keyservice.ts
|
|
14887
|
-
var
|
|
14845
|
+
var import_child_process2 = require("child_process");
|
|
14888
14846
|
var readline = __toESM(require("readline"));
|
|
14889
14847
|
var PORT_REGEX = /^PORT=(\d+)$/;
|
|
14890
14848
|
var STARTUP_TIMEOUT_MS = 5e3;
|
|
@@ -14902,7 +14860,7 @@ async function spawnKeyservice(options) {
|
|
|
14902
14860
|
...options.pin ? { CLEF_PKCS11_PIN: options.pin } : {},
|
|
14903
14861
|
...options.pinFile ? { CLEF_PKCS11_PIN_FILE: options.pinFile } : {}
|
|
14904
14862
|
};
|
|
14905
|
-
const child = (0,
|
|
14863
|
+
const child = (0, import_child_process2.spawn)(options.binaryPath, args, {
|
|
14906
14864
|
stdio: ["ignore", "pipe", "pipe"],
|
|
14907
14865
|
env: childEnv
|
|
14908
14866
|
});
|
|
@@ -14978,16 +14936,16 @@ function killGracefully(child) {
|
|
|
14978
14936
|
}
|
|
14979
14937
|
|
|
14980
14938
|
// src/lint/runner.ts
|
|
14981
|
-
var
|
|
14939
|
+
var path14 = __toESM(require("path"));
|
|
14982
14940
|
var LintRunner = class {
|
|
14983
|
-
constructor(matrixManager, schemaValidator,
|
|
14941
|
+
constructor(matrixManager, schemaValidator, source) {
|
|
14984
14942
|
this.matrixManager = matrixManager;
|
|
14985
14943
|
this.schemaValidator = schemaValidator;
|
|
14986
|
-
this.
|
|
14944
|
+
this.source = source;
|
|
14987
14945
|
}
|
|
14988
14946
|
matrixManager;
|
|
14989
14947
|
schemaValidator;
|
|
14990
|
-
|
|
14948
|
+
source;
|
|
14991
14949
|
/**
|
|
14992
14950
|
* Lint the entire matrix: check missing files, schema errors, SOPS integrity,
|
|
14993
14951
|
* single-recipient warnings, and cross-environment key drift.
|
|
@@ -15014,8 +14972,9 @@ var LintRunner = class {
|
|
|
15014
14972
|
fileCount = existingCells.length;
|
|
15015
14973
|
const namespaceKeys = {};
|
|
15016
14974
|
for (const cell of existingCells) {
|
|
14975
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15017
14976
|
try {
|
|
15018
|
-
const isValid = await this.
|
|
14977
|
+
const isValid = await this.source.validateEncryption(ref);
|
|
15019
14978
|
if (!isValid) {
|
|
15020
14979
|
issues.push({
|
|
15021
14980
|
severity: "error",
|
|
@@ -15036,7 +14995,7 @@ var LintRunner = class {
|
|
|
15036
14995
|
continue;
|
|
15037
14996
|
}
|
|
15038
14997
|
try {
|
|
15039
|
-
const decrypted = await this.
|
|
14998
|
+
const decrypted = await this.source.readCell(ref);
|
|
15040
14999
|
const keys = Object.keys(decrypted.values);
|
|
15041
15000
|
if (!namespaceKeys[cell.namespace]) {
|
|
15042
15001
|
namespaceKeys[cell.namespace] = {};
|
|
@@ -15081,7 +15040,7 @@ var LintRunner = class {
|
|
|
15081
15040
|
}
|
|
15082
15041
|
const ns = manifest.namespaces.find((n) => n.name === cell.namespace);
|
|
15083
15042
|
if (ns?.schema) {
|
|
15084
|
-
const schemaPath =
|
|
15043
|
+
const schemaPath = path14.join(repoRoot, ns.schema);
|
|
15085
15044
|
try {
|
|
15086
15045
|
const schema = this.schemaValidator.loadSchema(schemaPath);
|
|
15087
15046
|
const result = this.schemaValidator.validate(decrypted.values, schema);
|
|
@@ -15124,7 +15083,8 @@ var LintRunner = class {
|
|
|
15124
15083
|
}
|
|
15125
15084
|
}
|
|
15126
15085
|
try {
|
|
15127
|
-
const
|
|
15086
|
+
const meta = await this.source.getPendingMetadata(ref);
|
|
15087
|
+
const pendingKeys = meta.pending.map((p) => p.key);
|
|
15128
15088
|
pendingCount += pendingKeys.length;
|
|
15129
15089
|
for (const pendingKey of pendingKeys) {
|
|
15130
15090
|
issues.push({
|
|
@@ -15177,7 +15137,6 @@ var LintRunner = class {
|
|
|
15177
15137
|
const siIssues = await this.lintServiceIdentities(
|
|
15178
15138
|
manifest.service_identities,
|
|
15179
15139
|
manifest,
|
|
15180
|
-
repoRoot,
|
|
15181
15140
|
existingCells
|
|
15182
15141
|
);
|
|
15183
15142
|
issues.push(...siIssues);
|
|
@@ -15187,18 +15146,27 @@ var LintRunner = class {
|
|
|
15187
15146
|
return { issues, fileCount: fileCount + missingCells.length, pendingCount };
|
|
15188
15147
|
}
|
|
15189
15148
|
/**
|
|
15190
|
-
* Cross-reference
|
|
15149
|
+
* Cross-reference cell metadata against the cipher's plaintext key
|
|
15191
15150
|
* names for each existing cell. Reports orphan rotation records and
|
|
15192
|
-
* dual-state (pending + rotation) inconsistencies. Uses
|
|
15193
|
-
*
|
|
15151
|
+
* dual-state (pending + rotation) inconsistencies. Uses the source's
|
|
15152
|
+
* `listKeys` (no decryption).
|
|
15194
15153
|
*/
|
|
15195
15154
|
async lintMetadataConsistency(cells) {
|
|
15196
15155
|
const issues = [];
|
|
15197
15156
|
for (const cell of cells) {
|
|
15198
|
-
const
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15157
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15158
|
+
let cipherKeys;
|
|
15159
|
+
try {
|
|
15160
|
+
cipherKeys = new Set(await this.source.listKeys(ref));
|
|
15161
|
+
} catch {
|
|
15162
|
+
continue;
|
|
15163
|
+
}
|
|
15164
|
+
let metadata;
|
|
15165
|
+
try {
|
|
15166
|
+
metadata = await this.source.getPendingMetadata(ref);
|
|
15167
|
+
} catch {
|
|
15168
|
+
continue;
|
|
15169
|
+
}
|
|
15202
15170
|
for (const record of metadata.rotations) {
|
|
15203
15171
|
if (!cipherKeys.has(record.key)) {
|
|
15204
15172
|
issues.push({
|
|
@@ -15229,7 +15197,7 @@ var LintRunner = class {
|
|
|
15229
15197
|
/**
|
|
15230
15198
|
* Lint service identity configurations for drift issues.
|
|
15231
15199
|
*/
|
|
15232
|
-
async lintServiceIdentities(identities, manifest,
|
|
15200
|
+
async lintServiceIdentities(identities, manifest, existingCells) {
|
|
15233
15201
|
const issues = [];
|
|
15234
15202
|
const declaredEnvNames = new Set(manifest.environments.map((e) => e.name));
|
|
15235
15203
|
const declaredNsNames = new Set(manifest.namespaces.map((ns) => ns.name));
|
|
@@ -15270,9 +15238,10 @@ var LintRunner = class {
|
|
|
15270
15238
|
const envConfig = si.environments[cell.environment];
|
|
15271
15239
|
if (!envConfig) continue;
|
|
15272
15240
|
if (!envConfig.recipient) continue;
|
|
15241
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15273
15242
|
if (si.namespaces.includes(cell.namespace)) {
|
|
15274
15243
|
try {
|
|
15275
|
-
const metadata = await this.
|
|
15244
|
+
const metadata = await this.source.getCellMetadata(ref);
|
|
15276
15245
|
if (!metadata.recipients.includes(envConfig.recipient)) {
|
|
15277
15246
|
issues.push({
|
|
15278
15247
|
severity: "warning",
|
|
@@ -15286,7 +15255,7 @@ var LintRunner = class {
|
|
|
15286
15255
|
}
|
|
15287
15256
|
} else {
|
|
15288
15257
|
try {
|
|
15289
|
-
const metadata = await this.
|
|
15258
|
+
const metadata = await this.source.getCellMetadata(ref);
|
|
15290
15259
|
if (metadata.recipients.includes(envConfig.recipient)) {
|
|
15291
15260
|
issues.push({
|
|
15292
15261
|
severity: "warning",
|
|
@@ -15312,7 +15281,10 @@ var LintRunner = class {
|
|
|
15312
15281
|
async fix(manifest, repoRoot) {
|
|
15313
15282
|
const missingCells = this.matrixManager.detectMissingCells(manifest, repoRoot);
|
|
15314
15283
|
for (const cell of missingCells) {
|
|
15315
|
-
await this.
|
|
15284
|
+
await this.source.scaffoldCell(
|
|
15285
|
+
{ namespace: cell.namespace, environment: cell.environment },
|
|
15286
|
+
manifest
|
|
15287
|
+
);
|
|
15316
15288
|
}
|
|
15317
15289
|
return this.run(manifest, repoRoot);
|
|
15318
15290
|
}
|
|
@@ -15367,15 +15339,12 @@ Use 'clef exec' to inject secrets directly into a process, or 'clef export --for
|
|
|
15367
15339
|
}
|
|
15368
15340
|
};
|
|
15369
15341
|
|
|
15370
|
-
// src/import/index.ts
|
|
15371
|
-
var path17 = __toESM(require("path"));
|
|
15372
|
-
|
|
15373
15342
|
// src/import/parsers.ts
|
|
15374
|
-
var
|
|
15343
|
+
var path15 = __toESM(require("path"));
|
|
15375
15344
|
var YAML9 = __toESM(require("yaml"));
|
|
15376
15345
|
function detectFormat(filePath, content) {
|
|
15377
|
-
const base =
|
|
15378
|
-
const ext =
|
|
15346
|
+
const base = path15.basename(filePath);
|
|
15347
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
15379
15348
|
if (base === ".env" || base.startsWith(".env.")) {
|
|
15380
15349
|
return "dotenv";
|
|
15381
15350
|
}
|
|
@@ -15525,11 +15494,11 @@ function parse9(content, format, filePath) {
|
|
|
15525
15494
|
|
|
15526
15495
|
// src/import/index.ts
|
|
15527
15496
|
var ImportRunner = class {
|
|
15528
|
-
constructor(
|
|
15529
|
-
this.
|
|
15497
|
+
constructor(source, tx) {
|
|
15498
|
+
this.source = source;
|
|
15530
15499
|
this.tx = tx;
|
|
15531
15500
|
}
|
|
15532
|
-
|
|
15501
|
+
source;
|
|
15533
15502
|
tx;
|
|
15534
15503
|
/**
|
|
15535
15504
|
* Parse a source file and import its key/value pairs into a target `namespace/environment` cell.
|
|
@@ -15543,10 +15512,8 @@ var ImportRunner = class {
|
|
|
15543
15512
|
*/
|
|
15544
15513
|
async import(target, sourcePath, content, manifest, repoRoot, options) {
|
|
15545
15514
|
const [ns, env] = target.split("/");
|
|
15546
|
-
const
|
|
15547
|
-
|
|
15548
|
-
manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
|
|
15549
|
-
);
|
|
15515
|
+
const ref = { namespace: ns, environment: env };
|
|
15516
|
+
const relCellPath = manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env);
|
|
15550
15517
|
const parsed = parse9(content, options.format ?? "auto", sourcePath ?? "");
|
|
15551
15518
|
let candidates = Object.entries(parsed.pairs);
|
|
15552
15519
|
if (options.prefix) {
|
|
@@ -15564,7 +15531,7 @@ var ImportRunner = class {
|
|
|
15564
15531
|
if (options.dryRun) {
|
|
15565
15532
|
let existingKeys;
|
|
15566
15533
|
try {
|
|
15567
|
-
const decrypted2 = await this.
|
|
15534
|
+
const decrypted2 = await this.source.readCell(ref);
|
|
15568
15535
|
existingKeys = new Set(Object.keys(decrypted2.values));
|
|
15569
15536
|
} catch {
|
|
15570
15537
|
existingKeys = /* @__PURE__ */ new Set();
|
|
@@ -15578,7 +15545,7 @@ var ImportRunner = class {
|
|
|
15578
15545
|
}
|
|
15579
15546
|
return { imported, skipped, failed, warnings, dryRun: true };
|
|
15580
15547
|
}
|
|
15581
|
-
const decrypted = await this.
|
|
15548
|
+
const decrypted = await this.source.readCell(ref);
|
|
15582
15549
|
const newValues = { ...decrypted.values };
|
|
15583
15550
|
const rotatedKeys = [];
|
|
15584
15551
|
for (const [key, value] of candidates) {
|
|
@@ -15595,7 +15562,6 @@ var ImportRunner = class {
|
|
|
15595
15562
|
if (imported.length === 0) {
|
|
15596
15563
|
return { imported, skipped, failed, warnings, dryRun: false };
|
|
15597
15564
|
}
|
|
15598
|
-
const relCellPath = path17.relative(repoRoot, filePath);
|
|
15599
15565
|
const relMetaPath = relCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
15600
15566
|
await this.tx.run(repoRoot, {
|
|
15601
15567
|
description: `clef import ${target}: ${imported.length} key(s)`,
|
|
@@ -15603,9 +15569,9 @@ var ImportRunner = class {
|
|
|
15603
15569
|
// callback are staged and rolled back atomically with the ciphertext.
|
|
15604
15570
|
paths: [relCellPath, relMetaPath],
|
|
15605
15571
|
mutate: async () => {
|
|
15606
|
-
await this.
|
|
15572
|
+
await this.source.writeCell(ref, newValues);
|
|
15607
15573
|
if (options.rotatedBy && rotatedKeys.length > 0) {
|
|
15608
|
-
await recordRotation(
|
|
15574
|
+
await this.source.recordRotation(ref, rotatedKeys, options.rotatedBy);
|
|
15609
15575
|
}
|
|
15610
15576
|
}
|
|
15611
15577
|
});
|
|
@@ -15614,7 +15580,7 @@ var ImportRunner = class {
|
|
|
15614
15580
|
};
|
|
15615
15581
|
|
|
15616
15582
|
// src/recipients/index.ts
|
|
15617
|
-
var
|
|
15583
|
+
var path16 = __toESM(require("path"));
|
|
15618
15584
|
function parseRecipientEntry(entry) {
|
|
15619
15585
|
if (typeof entry === "string") {
|
|
15620
15586
|
return { key: entry };
|
|
@@ -15682,12 +15648,12 @@ function ensureEnvironmentRecipientsArray(doc, envName) {
|
|
|
15682
15648
|
return env.recipients;
|
|
15683
15649
|
}
|
|
15684
15650
|
var RecipientManager = class {
|
|
15685
|
-
constructor(
|
|
15686
|
-
this.
|
|
15651
|
+
constructor(source, matrixManager, tx) {
|
|
15652
|
+
this.source = source;
|
|
15687
15653
|
this.matrixManager = matrixManager;
|
|
15688
15654
|
this.tx = tx;
|
|
15689
15655
|
}
|
|
15690
|
-
|
|
15656
|
+
source;
|
|
15691
15657
|
matrixManager;
|
|
15692
15658
|
tx;
|
|
15693
15659
|
/**
|
|
@@ -15742,7 +15708,7 @@ var RecipientManager = class {
|
|
|
15742
15708
|
const reEncryptedFiles = [];
|
|
15743
15709
|
await this.tx.run(repoRoot, {
|
|
15744
15710
|
description: environment ? `clef recipients add ${keyPreview(normalizedKey)} -e ${environment}` : `clef recipients add ${keyPreview(normalizedKey)}`,
|
|
15745
|
-
paths: [...cells.map((c) =>
|
|
15711
|
+
paths: [...cells.map((c) => path16.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
|
|
15746
15712
|
mutate: async () => {
|
|
15747
15713
|
const doc = readManifestYaml(repoRoot);
|
|
15748
15714
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
@@ -15753,7 +15719,8 @@ var RecipientManager = class {
|
|
|
15753
15719
|
}
|
|
15754
15720
|
writeManifestYaml(repoRoot, doc);
|
|
15755
15721
|
for (const cell of cells) {
|
|
15756
|
-
|
|
15722
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15723
|
+
await this.source.rotate(ref, { addAge: normalizedKey });
|
|
15757
15724
|
reEncryptedFiles.push(cell.filePath);
|
|
15758
15725
|
}
|
|
15759
15726
|
}
|
|
@@ -15801,7 +15768,7 @@ var RecipientManager = class {
|
|
|
15801
15768
|
const reEncryptedFiles = [];
|
|
15802
15769
|
await this.tx.run(repoRoot, {
|
|
15803
15770
|
description: environment ? `clef recipients remove ${keyPreview(trimmedKey)} -e ${environment}` : `clef recipients remove ${keyPreview(trimmedKey)}`,
|
|
15804
|
-
paths: [...cells.map((c) =>
|
|
15771
|
+
paths: [...cells.map((c) => path16.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
|
|
15805
15772
|
mutate: async () => {
|
|
15806
15773
|
const doc = readManifestYaml(repoRoot);
|
|
15807
15774
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
@@ -15809,7 +15776,8 @@ var RecipientManager = class {
|
|
|
15809
15776
|
recipients.splice(idx, 1);
|
|
15810
15777
|
writeManifestYaml(repoRoot, doc);
|
|
15811
15778
|
for (const cell of cells) {
|
|
15812
|
-
|
|
15779
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15780
|
+
await this.source.rotate(ref, { rmAge: trimmedKey });
|
|
15813
15781
|
reEncryptedFiles.push(cell.filePath);
|
|
15814
15782
|
}
|
|
15815
15783
|
}
|
|
@@ -15831,12 +15799,12 @@ var RecipientManager = class {
|
|
|
15831
15799
|
|
|
15832
15800
|
// src/recipients/requests.ts
|
|
15833
15801
|
var fs17 = __toESM(require("fs"));
|
|
15834
|
-
var
|
|
15802
|
+
var path17 = __toESM(require("path"));
|
|
15835
15803
|
var YAML10 = __toESM(require("yaml"));
|
|
15836
15804
|
var REQUESTS_FILENAME = ".clef-requests.yaml";
|
|
15837
15805
|
var HEADER_COMMENT2 = "# Pending recipient access requests. Approve with: clef recipients approve <label>\n";
|
|
15838
15806
|
function requestsFilePath(repoRoot) {
|
|
15839
|
-
return
|
|
15807
|
+
return path17.join(repoRoot, REQUESTS_FILENAME);
|
|
15840
15808
|
}
|
|
15841
15809
|
function loadRequests(repoRoot) {
|
|
15842
15810
|
const filePath = requestsFilePath(repoRoot);
|
|
@@ -15911,7 +15879,7 @@ function findInList(requests, identifier) {
|
|
|
15911
15879
|
}
|
|
15912
15880
|
|
|
15913
15881
|
// src/drift/detector.ts
|
|
15914
|
-
var
|
|
15882
|
+
var path18 = __toESM(require("path"));
|
|
15915
15883
|
var DriftDetector = class {
|
|
15916
15884
|
parser = new ManifestParser();
|
|
15917
15885
|
matrix = new MatrixManager();
|
|
@@ -15924,8 +15892,8 @@ var DriftDetector = class {
|
|
|
15924
15892
|
* @returns Drift result with any issues found.
|
|
15925
15893
|
*/
|
|
15926
15894
|
detect(localRoot, remoteRoot, namespaceFilter) {
|
|
15927
|
-
const localManifest = this.parser.parse(
|
|
15928
|
-
const remoteManifest = this.parser.parse(
|
|
15895
|
+
const localManifest = this.parser.parse(path18.join(localRoot, CLEF_MANIFEST_FILENAME));
|
|
15896
|
+
const remoteManifest = this.parser.parse(path18.join(remoteRoot, CLEF_MANIFEST_FILENAME));
|
|
15929
15897
|
const localCells = this.matrix.resolveMatrix(localManifest, localRoot);
|
|
15930
15898
|
const remoteCells = this.matrix.resolveMatrix(remoteManifest, remoteRoot);
|
|
15931
15899
|
const localEnvNames = localManifest.environments.map((e) => e.name);
|
|
@@ -15989,7 +15957,7 @@ var DriftDetector = class {
|
|
|
15989
15957
|
};
|
|
15990
15958
|
|
|
15991
15959
|
// src/report/generator.ts
|
|
15992
|
-
var
|
|
15960
|
+
var path19 = __toESM(require("path"));
|
|
15993
15961
|
|
|
15994
15962
|
// src/report/sanitizer.ts
|
|
15995
15963
|
var ReportSanitizer = class {
|
|
@@ -16126,14 +16094,14 @@ var ReportSanitizer = class {
|
|
|
16126
16094
|
|
|
16127
16095
|
// src/report/generator.ts
|
|
16128
16096
|
var ReportGenerator = class {
|
|
16129
|
-
constructor(runner,
|
|
16097
|
+
constructor(runner, source, matrixManager, schemaValidator) {
|
|
16130
16098
|
this.runner = runner;
|
|
16131
|
-
this.
|
|
16099
|
+
this.source = source;
|
|
16132
16100
|
this.matrixManager = matrixManager;
|
|
16133
16101
|
this.schemaValidator = schemaValidator;
|
|
16134
16102
|
}
|
|
16135
16103
|
runner;
|
|
16136
|
-
|
|
16104
|
+
source;
|
|
16137
16105
|
matrixManager;
|
|
16138
16106
|
schemaValidator;
|
|
16139
16107
|
/**
|
|
@@ -16149,7 +16117,7 @@ var ReportGenerator = class {
|
|
|
16149
16117
|
let manifest = null;
|
|
16150
16118
|
try {
|
|
16151
16119
|
const parser = new ManifestParser();
|
|
16152
|
-
manifest = parser.parse(
|
|
16120
|
+
manifest = parser.parse(path19.join(repoRoot, "clef.yaml"));
|
|
16153
16121
|
} catch {
|
|
16154
16122
|
const emptyManifest = {
|
|
16155
16123
|
manifestVersion: 0,
|
|
@@ -16270,16 +16238,17 @@ var ReportGenerator = class {
|
|
|
16270
16238
|
metadata: null
|
|
16271
16239
|
};
|
|
16272
16240
|
}
|
|
16241
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
16273
16242
|
const keyCount = this.readKeyCount(cell.filePath);
|
|
16274
16243
|
let pendingCount = 0;
|
|
16275
16244
|
try {
|
|
16276
|
-
const
|
|
16277
|
-
pendingCount = pending.length;
|
|
16245
|
+
const meta = await this.source.getPendingMetadata(ref);
|
|
16246
|
+
pendingCount = meta.pending.length;
|
|
16278
16247
|
} catch {
|
|
16279
16248
|
}
|
|
16280
16249
|
let metadata = null;
|
|
16281
16250
|
try {
|
|
16282
|
-
const sopsMetadata = await this.
|
|
16251
|
+
const sopsMetadata = await this.source.getCellMetadata(ref);
|
|
16283
16252
|
metadata = {
|
|
16284
16253
|
backend: sopsMetadata.backend,
|
|
16285
16254
|
recipients: sopsMetadata.recipients,
|
|
@@ -16302,7 +16271,7 @@ var ReportGenerator = class {
|
|
|
16302
16271
|
}
|
|
16303
16272
|
async buildPolicy(manifest, repoRoot) {
|
|
16304
16273
|
try {
|
|
16305
|
-
const lintRunner = new LintRunner(this.matrixManager, this.schemaValidator, this.
|
|
16274
|
+
const lintRunner = new LintRunner(this.matrixManager, this.schemaValidator, this.source);
|
|
16306
16275
|
const lintResult = await lintRunner.run(manifest, repoRoot);
|
|
16307
16276
|
return new ReportSanitizer().sanitize(lintResult.issues);
|
|
16308
16277
|
} catch {
|
|
@@ -16619,9 +16588,9 @@ var SopsMergeDriver = class {
|
|
|
16619
16588
|
*/
|
|
16620
16589
|
async mergeFiles(basePath, oursPath, theirsPath) {
|
|
16621
16590
|
const [baseDecrypted, oursDecrypted, theirsDecrypted] = await Promise.all([
|
|
16622
|
-
this.sopsClient.
|
|
16623
|
-
this.sopsClient.
|
|
16624
|
-
this.sopsClient.
|
|
16591
|
+
this.sopsClient.decryptFile(basePath),
|
|
16592
|
+
this.sopsClient.decryptFile(oursPath),
|
|
16593
|
+
this.sopsClient.decryptFile(theirsPath)
|
|
16625
16594
|
]);
|
|
16626
16595
|
return this.merge(baseDecrypted.values, oursDecrypted.values, theirsDecrypted.values);
|
|
16627
16596
|
}
|
|
@@ -16738,22 +16707,26 @@ function mergeMetadataFiles(_basePath, oursPath, theirsPath) {
|
|
|
16738
16707
|
}
|
|
16739
16708
|
|
|
16740
16709
|
// src/service-identity/manager.ts
|
|
16741
|
-
var
|
|
16710
|
+
var path20 = __toESM(require("path"));
|
|
16742
16711
|
var ServiceIdentityManager = class {
|
|
16743
|
-
constructor(
|
|
16744
|
-
this.
|
|
16712
|
+
constructor(source, matrixManager, tx) {
|
|
16713
|
+
this.source = source;
|
|
16745
16714
|
this.matrixManager = matrixManager;
|
|
16746
16715
|
this.tx = tx;
|
|
16747
16716
|
}
|
|
16748
|
-
|
|
16717
|
+
source;
|
|
16749
16718
|
matrixManager;
|
|
16750
16719
|
tx;
|
|
16720
|
+
/** Helper: cell → ref for the source seam. */
|
|
16721
|
+
ref(cell) {
|
|
16722
|
+
return { namespace: cell.namespace, environment: cell.environment };
|
|
16723
|
+
}
|
|
16751
16724
|
/**
|
|
16752
16725
|
* Compute repo-relative paths for a set of cells plus the manifest. Used
|
|
16753
16726
|
* to seed TransactionManager.run's `paths` argument.
|
|
16754
16727
|
*/
|
|
16755
16728
|
txPaths(repoRoot, cells) {
|
|
16756
|
-
return [...cells.map((c) =>
|
|
16729
|
+
return [...cells.map((c) => path20.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME];
|
|
16757
16730
|
}
|
|
16758
16731
|
/**
|
|
16759
16732
|
* Create a new service identity with per-environment age key pairs or KMS envelope config.
|
|
@@ -16845,7 +16818,7 @@ var ServiceIdentityManager = class {
|
|
|
16845
16818
|
if (!envConfig?.recipient) continue;
|
|
16846
16819
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16847
16820
|
try {
|
|
16848
|
-
await this.
|
|
16821
|
+
await this.source.rotate(this.ref(cell), { rmAge: envConfig.recipient });
|
|
16849
16822
|
} catch {
|
|
16850
16823
|
}
|
|
16851
16824
|
}
|
|
@@ -16895,7 +16868,7 @@ var ServiceIdentityManager = class {
|
|
|
16895
16868
|
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
16896
16869
|
for (const cell of scopedCells) {
|
|
16897
16870
|
try {
|
|
16898
|
-
await this.
|
|
16871
|
+
await this.source.rotate(this.ref(cell), { rmAge: oldConfig.recipient });
|
|
16899
16872
|
} catch {
|
|
16900
16873
|
}
|
|
16901
16874
|
}
|
|
@@ -16922,7 +16895,7 @@ var ServiceIdentityManager = class {
|
|
|
16922
16895
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16923
16896
|
if (!envConfig.recipient) continue;
|
|
16924
16897
|
try {
|
|
16925
|
-
await this.
|
|
16898
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
16926
16899
|
} catch (err) {
|
|
16927
16900
|
const message = err instanceof Error ? err.message : String(err);
|
|
16928
16901
|
if (!message.includes("already")) {
|
|
@@ -16970,7 +16943,7 @@ var ServiceIdentityManager = class {
|
|
|
16970
16943
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16971
16944
|
if (!envConfig.recipient) continue;
|
|
16972
16945
|
try {
|
|
16973
|
-
await this.
|
|
16946
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
16974
16947
|
affectedFiles.push(cell.filePath);
|
|
16975
16948
|
} catch (err) {
|
|
16976
16949
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -17031,7 +17004,7 @@ var ServiceIdentityManager = class {
|
|
|
17031
17004
|
if (isKmsEnvelope(envConfig)) continue;
|
|
17032
17005
|
if (!envConfig.recipient) continue;
|
|
17033
17006
|
try {
|
|
17034
|
-
await this.
|
|
17007
|
+
await this.source.rotate(this.ref(cell), { rmAge: envConfig.recipient });
|
|
17035
17008
|
affectedFiles.push(cell.filePath);
|
|
17036
17009
|
} catch {
|
|
17037
17010
|
}
|
|
@@ -17100,7 +17073,7 @@ var ServiceIdentityManager = class {
|
|
|
17100
17073
|
if (!identity.pack_only && !isKmsEnvelope(envConfig) && envConfig.recipient) {
|
|
17101
17074
|
for (const cell of cells) {
|
|
17102
17075
|
try {
|
|
17103
|
-
await this.
|
|
17076
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
17104
17077
|
} catch (err) {
|
|
17105
17078
|
const message = err instanceof Error ? err.message : String(err);
|
|
17106
17079
|
if (!message.includes("already")) {
|
|
@@ -17177,10 +17150,10 @@ var ServiceIdentityManager = class {
|
|
|
17177
17150
|
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
17178
17151
|
for (const cell of scopedCells) {
|
|
17179
17152
|
try {
|
|
17180
|
-
await this.
|
|
17153
|
+
await this.source.rotate(this.ref(cell), { rmAge: oldRecipient });
|
|
17181
17154
|
} catch {
|
|
17182
17155
|
}
|
|
17183
|
-
await this.
|
|
17156
|
+
await this.source.rotate(this.ref(cell), { addAge: newPublicKey });
|
|
17184
17157
|
}
|
|
17185
17158
|
}
|
|
17186
17159
|
}
|
|
@@ -17239,7 +17212,7 @@ var ServiceIdentityManager = class {
|
|
|
17239
17212
|
if (!envConfig.recipient) continue;
|
|
17240
17213
|
if (si.namespaces.includes(cell.namespace)) {
|
|
17241
17214
|
try {
|
|
17242
|
-
const metadata = await this.
|
|
17215
|
+
const metadata = await this.source.getCellMetadata(this.ref(cell));
|
|
17243
17216
|
if (!metadata.recipients.includes(envConfig.recipient)) {
|
|
17244
17217
|
issues.push({
|
|
17245
17218
|
identity: si.name,
|
|
@@ -17254,7 +17227,7 @@ var ServiceIdentityManager = class {
|
|
|
17254
17227
|
}
|
|
17255
17228
|
} else {
|
|
17256
17229
|
try {
|
|
17257
|
-
const metadata = await this.
|
|
17230
|
+
const metadata = await this.source.getCellMetadata(this.ref(cell));
|
|
17258
17231
|
if (metadata.recipients.includes(envConfig.recipient)) {
|
|
17259
17232
|
issues.push({
|
|
17260
17233
|
identity: si.name,
|
|
@@ -17276,15 +17249,15 @@ var ServiceIdentityManager = class {
|
|
|
17276
17249
|
|
|
17277
17250
|
// src/structure/manager.ts
|
|
17278
17251
|
var fs19 = __toESM(require("fs"));
|
|
17279
|
-
var
|
|
17252
|
+
var path21 = __toESM(require("path"));
|
|
17280
17253
|
var StructureManager = class {
|
|
17281
|
-
constructor(matrixManager,
|
|
17254
|
+
constructor(matrixManager, buildSource, tx) {
|
|
17282
17255
|
this.matrixManager = matrixManager;
|
|
17283
|
-
this.
|
|
17256
|
+
this.buildSource = buildSource;
|
|
17284
17257
|
this.tx = tx;
|
|
17285
17258
|
}
|
|
17286
17259
|
matrixManager;
|
|
17287
|
-
|
|
17260
|
+
buildSource;
|
|
17288
17261
|
tx;
|
|
17289
17262
|
// ── add ──────────────────────────────────────────────────────────────────
|
|
17290
17263
|
/**
|
|
@@ -17300,7 +17273,7 @@ var StructureManager = class {
|
|
|
17300
17273
|
this.assertValidIdentifier("namespace", name);
|
|
17301
17274
|
const newCellPaths = manifest.environments.map((env) => ({
|
|
17302
17275
|
environment: env.name,
|
|
17303
|
-
filePath:
|
|
17276
|
+
filePath: path21.join(
|
|
17304
17277
|
repoRoot,
|
|
17305
17278
|
manifest.file_pattern.replace("{namespace}", name).replace("{environment}", env.name)
|
|
17306
17279
|
)
|
|
@@ -17308,7 +17281,7 @@ var StructureManager = class {
|
|
|
17308
17281
|
for (const cell of newCellPaths) {
|
|
17309
17282
|
if (fs19.existsSync(cell.filePath)) {
|
|
17310
17283
|
throw new Error(
|
|
17311
|
-
`Cannot add namespace '${name}': file '${
|
|
17284
|
+
`Cannot add namespace '${name}': file '${path21.relative(repoRoot, cell.filePath)}' already exists.`
|
|
17312
17285
|
);
|
|
17313
17286
|
}
|
|
17314
17287
|
}
|
|
@@ -17327,21 +17300,14 @@ var StructureManager = class {
|
|
|
17327
17300
|
await this.tx.run(repoRoot, {
|
|
17328
17301
|
description: `clef namespace add ${name}`,
|
|
17329
17302
|
paths: [
|
|
17330
|
-
...newCellPaths.map((c) =>
|
|
17303
|
+
...newCellPaths.map((c) => path21.relative(repoRoot, c.filePath)),
|
|
17331
17304
|
CLEF_MANIFEST_FILENAME
|
|
17332
17305
|
],
|
|
17333
17306
|
mutate: async () => {
|
|
17307
|
+
const source = this.buildSource(updatedManifest);
|
|
17334
17308
|
for (const cell of newCellPaths) {
|
|
17335
|
-
|
|
17336
|
-
|
|
17337
|
-
namespace: name,
|
|
17338
|
-
environment: cell.environment,
|
|
17339
|
-
filePath: cell.filePath,
|
|
17340
|
-
exists: false
|
|
17341
|
-
},
|
|
17342
|
-
this.encryption,
|
|
17343
|
-
updatedManifest
|
|
17344
|
-
);
|
|
17309
|
+
const ref = { namespace: name, environment: cell.environment };
|
|
17310
|
+
await source.scaffoldCell(ref, updatedManifest);
|
|
17345
17311
|
}
|
|
17346
17312
|
const doc = readManifestYaml(repoRoot);
|
|
17347
17313
|
const namespaces = doc.namespaces;
|
|
@@ -17372,7 +17338,7 @@ var StructureManager = class {
|
|
|
17372
17338
|
this.assertValidIdentifier("environment", name);
|
|
17373
17339
|
const newCellPaths = manifest.namespaces.map((ns) => ({
|
|
17374
17340
|
namespace: ns.name,
|
|
17375
|
-
filePath:
|
|
17341
|
+
filePath: path21.join(
|
|
17376
17342
|
repoRoot,
|
|
17377
17343
|
manifest.file_pattern.replace("{namespace}", ns.name).replace("{environment}", name)
|
|
17378
17344
|
)
|
|
@@ -17380,7 +17346,7 @@ var StructureManager = class {
|
|
|
17380
17346
|
for (const cell of newCellPaths) {
|
|
17381
17347
|
if (fs19.existsSync(cell.filePath)) {
|
|
17382
17348
|
throw new Error(
|
|
17383
|
-
`Cannot add environment '${name}': file '${
|
|
17349
|
+
`Cannot add environment '${name}': file '${path21.relative(repoRoot, cell.filePath)}' already exists.`
|
|
17384
17350
|
);
|
|
17385
17351
|
}
|
|
17386
17352
|
}
|
|
@@ -17399,21 +17365,14 @@ var StructureManager = class {
|
|
|
17399
17365
|
await this.tx.run(repoRoot, {
|
|
17400
17366
|
description: `clef env add ${name}`,
|
|
17401
17367
|
paths: [
|
|
17402
|
-
...newCellPaths.map((c) =>
|
|
17368
|
+
...newCellPaths.map((c) => path21.relative(repoRoot, c.filePath)),
|
|
17403
17369
|
CLEF_MANIFEST_FILENAME
|
|
17404
17370
|
],
|
|
17405
17371
|
mutate: async () => {
|
|
17372
|
+
const source = this.buildSource(updatedManifest);
|
|
17406
17373
|
for (const cell of newCellPaths) {
|
|
17407
|
-
|
|
17408
|
-
|
|
17409
|
-
namespace: cell.namespace,
|
|
17410
|
-
environment: name,
|
|
17411
|
-
filePath: cell.filePath,
|
|
17412
|
-
exists: false
|
|
17413
|
-
},
|
|
17414
|
-
this.encryption,
|
|
17415
|
-
updatedManifest
|
|
17416
|
-
);
|
|
17374
|
+
const ref = { namespace: cell.namespace, environment: name };
|
|
17375
|
+
await source.scaffoldCell(ref, updatedManifest);
|
|
17417
17376
|
}
|
|
17418
17377
|
const doc = readManifestYaml(repoRoot);
|
|
17419
17378
|
const environments = doc.environments;
|
|
@@ -17556,7 +17515,7 @@ var StructureManager = class {
|
|
|
17556
17515
|
for (const pair of renamePairs) {
|
|
17557
17516
|
if (fs19.existsSync(pair.to)) {
|
|
17558
17517
|
throw new Error(
|
|
17559
|
-
`Rename target '${
|
|
17518
|
+
`Rename target '${path21.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
17560
17519
|
);
|
|
17561
17520
|
}
|
|
17562
17521
|
}
|
|
@@ -17599,7 +17558,7 @@ var StructureManager = class {
|
|
|
17599
17558
|
for (const pair of renamePairs) {
|
|
17600
17559
|
if (fs19.existsSync(pair.to)) {
|
|
17601
17560
|
throw new Error(
|
|
17602
|
-
`Rename target '${
|
|
17561
|
+
`Rename target '${path21.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
17603
17562
|
);
|
|
17604
17563
|
}
|
|
17605
17564
|
}
|
|
@@ -17649,7 +17608,7 @@ var StructureManager = class {
|
|
|
17649
17608
|
swapAxisInCellPath(repoRoot, manifest, cell, axis, newName) {
|
|
17650
17609
|
const ns = axis === "namespace" ? newName : cell.namespace;
|
|
17651
17610
|
const env = axis === "environment" ? newName : cell.environment;
|
|
17652
|
-
return
|
|
17611
|
+
return path21.join(
|
|
17653
17612
|
repoRoot,
|
|
17654
17613
|
manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
|
|
17655
17614
|
);
|
|
@@ -17661,8 +17620,8 @@ var StructureManager = class {
|
|
|
17661
17620
|
txPaths(repoRoot, renamePairs) {
|
|
17662
17621
|
const paths = /* @__PURE__ */ new Set();
|
|
17663
17622
|
for (const pair of renamePairs) {
|
|
17664
|
-
paths.add(
|
|
17665
|
-
paths.add(
|
|
17623
|
+
paths.add(path21.relative(repoRoot, pair.from));
|
|
17624
|
+
paths.add(path21.relative(repoRoot, pair.to));
|
|
17666
17625
|
}
|
|
17667
17626
|
paths.add(CLEF_MANIFEST_FILENAME);
|
|
17668
17627
|
return [...paths];
|
|
@@ -17673,7 +17632,7 @@ var StructureManager = class {
|
|
|
17673
17632
|
*/
|
|
17674
17633
|
applyRenames(pairs) {
|
|
17675
17634
|
for (const pair of pairs) {
|
|
17676
|
-
const targetDir =
|
|
17635
|
+
const targetDir = path21.dirname(pair.to);
|
|
17677
17636
|
if (!fs19.existsSync(targetDir)) {
|
|
17678
17637
|
fs19.mkdirSync(targetDir, { recursive: true });
|
|
17679
17638
|
}
|
|
@@ -17688,10 +17647,10 @@ var StructureManager = class {
|
|
|
17688
17647
|
deletePaths(repoRoot, cells) {
|
|
17689
17648
|
const paths = /* @__PURE__ */ new Set();
|
|
17690
17649
|
for (const cell of cells) {
|
|
17691
|
-
paths.add(
|
|
17650
|
+
paths.add(path21.relative(repoRoot, cell.filePath));
|
|
17692
17651
|
const meta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
17693
17652
|
if (fs19.existsSync(meta)) {
|
|
17694
|
-
paths.add(
|
|
17653
|
+
paths.add(path21.relative(repoRoot, meta));
|
|
17695
17654
|
}
|
|
17696
17655
|
}
|
|
17697
17656
|
paths.add(CLEF_MANIFEST_FILENAME);
|
|
@@ -17806,7 +17765,7 @@ function renameKeyPreservingOrder(obj, oldKey, newKey) {
|
|
|
17806
17765
|
}
|
|
17807
17766
|
|
|
17808
17767
|
// src/artifact/resolve.ts
|
|
17809
|
-
async function resolveIdentitySecrets(identityName, environment, manifest, repoRoot,
|
|
17768
|
+
async function resolveIdentitySecrets(identityName, environment, manifest, repoRoot, source, matrixManager) {
|
|
17810
17769
|
const identity = manifest.service_identities?.find((si) => si.name === identityName);
|
|
17811
17770
|
if (!identity) {
|
|
17812
17771
|
throw new Error(`Service identity '${identityName}' not found in manifest.`);
|
|
@@ -17822,7 +17781,10 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
|
|
|
17822
17781
|
(c) => c.exists && identity.namespaces.includes(c.namespace) && c.environment === environment
|
|
17823
17782
|
);
|
|
17824
17783
|
for (const cell of cells) {
|
|
17825
|
-
const decrypted = await
|
|
17784
|
+
const decrypted = await source.readCell({
|
|
17785
|
+
namespace: cell.namespace,
|
|
17786
|
+
environment: cell.environment
|
|
17787
|
+
});
|
|
17826
17788
|
const bucket = allValues[cell.namespace] ??= {};
|
|
17827
17789
|
for (const [key, value] of Object.entries(decrypted.values)) {
|
|
17828
17790
|
if (key in bucket && bucket[key] !== value) {
|
|
@@ -17846,14 +17808,14 @@ var crypto5 = __toESM(require("crypto"));
|
|
|
17846
17808
|
|
|
17847
17809
|
// src/artifact/output.ts
|
|
17848
17810
|
var fs20 = __toESM(require("fs"));
|
|
17849
|
-
var
|
|
17811
|
+
var path22 = __toESM(require("path"));
|
|
17850
17812
|
var FilePackOutput = class {
|
|
17851
17813
|
constructor(outputPath) {
|
|
17852
17814
|
this.outputPath = outputPath;
|
|
17853
17815
|
}
|
|
17854
17816
|
outputPath;
|
|
17855
17817
|
async write(_artifact, json) {
|
|
17856
|
-
const outputDir =
|
|
17818
|
+
const outputDir = path22.dirname(this.outputPath);
|
|
17857
17819
|
if (!fs20.existsSync(outputDir)) {
|
|
17858
17820
|
fs20.mkdirSync(outputDir, { recursive: true });
|
|
17859
17821
|
}
|
|
@@ -17900,17 +17862,6 @@ function buildSigningPayload(artifact) {
|
|
|
17900
17862
|
];
|
|
17901
17863
|
return Buffer.from(fields.join("\n"), "utf-8");
|
|
17902
17864
|
}
|
|
17903
|
-
function generateSigningKeyPair() {
|
|
17904
|
-
const pair = crypto3.generateKeyPairSync("ed25519");
|
|
17905
|
-
return {
|
|
17906
|
-
publicKey: pair.publicKey.export({ type: "spki", format: "der" }).toString(
|
|
17907
|
-
"base64"
|
|
17908
|
-
),
|
|
17909
|
-
privateKey: pair.privateKey.export({ type: "pkcs8", format: "der" }).toString(
|
|
17910
|
-
"base64"
|
|
17911
|
-
)
|
|
17912
|
-
};
|
|
17913
|
-
}
|
|
17914
17865
|
function signEd25519(payload, privateKeyBase64) {
|
|
17915
17866
|
const keyObj = crypto3.createPrivateKey({
|
|
17916
17867
|
key: Buffer.from(privateKeyBase64, "base64"),
|
|
@@ -17946,17 +17897,6 @@ function verifySignature(payload, signatureBase64, publicKeyBase64) {
|
|
|
17946
17897
|
}
|
|
17947
17898
|
throw new Error(`Unsupported key type for signature verification: ${keyType}`);
|
|
17948
17899
|
}
|
|
17949
|
-
function detectAlgorithm(publicKeyBase64) {
|
|
17950
|
-
const keyObj = crypto3.createPublicKey({
|
|
17951
|
-
key: Buffer.from(publicKeyBase64, "base64"),
|
|
17952
|
-
format: "der",
|
|
17953
|
-
type: "spki"
|
|
17954
|
-
});
|
|
17955
|
-
const keyType = keyObj.asymmetricKeyType;
|
|
17956
|
-
if (keyType === "ed25519") return "Ed25519";
|
|
17957
|
-
if (keyType === "ec") return "ECDSA_SHA256";
|
|
17958
|
-
throw new Error(`Unsupported key type: ${keyType}`);
|
|
17959
|
-
}
|
|
17960
17900
|
|
|
17961
17901
|
// src/artifact/hash.ts
|
|
17962
17902
|
var crypto4 = __toESM(require("crypto"));
|
|
@@ -17966,12 +17906,12 @@ function computeCiphertextHash(ciphertext) {
|
|
|
17966
17906
|
|
|
17967
17907
|
// src/artifact/packer.ts
|
|
17968
17908
|
var ArtifactPacker = class {
|
|
17969
|
-
constructor(
|
|
17970
|
-
this.
|
|
17909
|
+
constructor(source, matrixManager, kms) {
|
|
17910
|
+
this.source = source;
|
|
17971
17911
|
this.matrixManager = matrixManager;
|
|
17972
17912
|
this.kms = kms;
|
|
17973
17913
|
}
|
|
17974
|
-
|
|
17914
|
+
source;
|
|
17975
17915
|
matrixManager;
|
|
17976
17916
|
kms;
|
|
17977
17917
|
/**
|
|
@@ -17989,7 +17929,7 @@ var ArtifactPacker = class {
|
|
|
17989
17929
|
config.environment,
|
|
17990
17930
|
manifest,
|
|
17991
17931
|
repoRoot,
|
|
17992
|
-
this.
|
|
17932
|
+
this.source,
|
|
17993
17933
|
this.matrixManager
|
|
17994
17934
|
);
|
|
17995
17935
|
const plaintext = JSON.stringify(resolved.values);
|
|
@@ -18374,11 +18314,7 @@ var JsonEnvelopeBackend = class {
|
|
|
18374
18314
|
}
|
|
18375
18315
|
async pack(req) {
|
|
18376
18316
|
const opts = req.backendOptions;
|
|
18377
|
-
const packer = new ArtifactPacker(
|
|
18378
|
-
req.services.encryption,
|
|
18379
|
-
new MatrixManager(),
|
|
18380
|
-
req.services.kms
|
|
18381
|
-
);
|
|
18317
|
+
const packer = new ArtifactPacker(req.services.source, new MatrixManager(), req.services.kms);
|
|
18382
18318
|
const output = opts.output ?? (opts.outputPath ? new FilePackOutput(opts.outputPath) : void 0);
|
|
18383
18319
|
const result = await packer.pack(
|
|
18384
18320
|
{
|
|
@@ -18407,7 +18343,7 @@ var JsonEnvelopeBackend = class {
|
|
|
18407
18343
|
var VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
|
|
18408
18344
|
|
|
18409
18345
|
// src/migration/backend.ts
|
|
18410
|
-
var
|
|
18346
|
+
var path23 = __toESM(require("path"));
|
|
18411
18347
|
var YAML12 = __toESM(require("yaml"));
|
|
18412
18348
|
var BACKEND_KEY_FIELDS = {
|
|
18413
18349
|
age: void 0,
|
|
@@ -18435,23 +18371,24 @@ function metadataMatchesTarget(meta, target) {
|
|
|
18435
18371
|
}
|
|
18436
18372
|
var BackendMigrator = class {
|
|
18437
18373
|
/**
|
|
18438
|
-
* @param
|
|
18374
|
+
* @param buildSource - Factory that builds a `SecretSource` bound to a
|
|
18375
|
+
* given manifest. Called twice during a real migration: once with the
|
|
18376
|
+
* pre-migration manifest (for classification + decrypt) and once with
|
|
18377
|
+
* the post-mutation manifest (for re-encrypt + verify). The factory
|
|
18378
|
+
* pattern is required because the encryption layer of a composed
|
|
18379
|
+
* source is bound to a manifest at construction.
|
|
18439
18380
|
* @param matrixManager - Matrix resolver.
|
|
18440
18381
|
* @param tx - Transaction manager that wraps the migration in a single git commit
|
|
18441
18382
|
* so a partial failure rolls back ALL files + the manifest via `git reset --hard`.
|
|
18442
|
-
* @param targetEncryption - Optional separate backend for encrypt. Use when migrating
|
|
18443
|
-
* from cloud (decrypt via keyservice) to another backend (encrypt via local credentials).
|
|
18444
18383
|
*/
|
|
18445
|
-
constructor(
|
|
18384
|
+
constructor(buildSource, matrixManager, tx) {
|
|
18385
|
+
this.buildSource = buildSource;
|
|
18446
18386
|
this.matrixManager = matrixManager;
|
|
18447
18387
|
this.tx = tx;
|
|
18448
|
-
this.decryptBackend = encryption;
|
|
18449
|
-
this.encryptBackend = targetEncryption ?? encryption;
|
|
18450
18388
|
}
|
|
18389
|
+
buildSource;
|
|
18451
18390
|
matrixManager;
|
|
18452
18391
|
tx;
|
|
18453
|
-
decryptBackend;
|
|
18454
|
-
encryptBackend;
|
|
18455
18392
|
async migrate(manifest, repoRoot, options, onProgress) {
|
|
18456
18393
|
const { target, environment, dryRun, skipVerify } = options;
|
|
18457
18394
|
if (environment) {
|
|
@@ -18471,10 +18408,12 @@ var BackendMigrator = class {
|
|
|
18471
18408
|
warnings: ["No encrypted files found to migrate."]
|
|
18472
18409
|
};
|
|
18473
18410
|
}
|
|
18411
|
+
const sourceBefore = this.buildSource(manifest);
|
|
18474
18412
|
const toMigrate = [];
|
|
18475
18413
|
const skippedFiles = [];
|
|
18476
18414
|
for (const cell of targetCells) {
|
|
18477
|
-
const
|
|
18415
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18416
|
+
const meta = await sourceBefore.getCellMetadata(ref);
|
|
18478
18417
|
if (metadataMatchesTarget(meta, target)) {
|
|
18479
18418
|
skippedFiles.push(cell.filePath);
|
|
18480
18419
|
onProgress?.({
|
|
@@ -18525,11 +18464,12 @@ var BackendMigrator = class {
|
|
|
18525
18464
|
const migratedFiles = [];
|
|
18526
18465
|
let migrationFailed = false;
|
|
18527
18466
|
let migrationError;
|
|
18467
|
+
let sourceAfter;
|
|
18528
18468
|
try {
|
|
18529
18469
|
await this.tx.run(repoRoot, {
|
|
18530
18470
|
description: environment ? `clef migrate-backend ${target.backend}: ${environment}` : `clef migrate-backend ${target.backend}`,
|
|
18531
18471
|
paths: [
|
|
18532
|
-
...toMigrate.map((c) =>
|
|
18472
|
+
...toMigrate.map((c) => path23.relative(repoRoot, c.filePath)),
|
|
18533
18473
|
CLEF_MANIFEST_FILENAME
|
|
18534
18474
|
],
|
|
18535
18475
|
mutate: async () => {
|
|
@@ -18537,19 +18477,16 @@ var BackendMigrator = class {
|
|
|
18537
18477
|
this.updateManifestDoc(doc, target, environment);
|
|
18538
18478
|
writeManifestYaml(repoRoot, doc);
|
|
18539
18479
|
const updatedManifest = YAML12.parse(YAML12.stringify(doc));
|
|
18480
|
+
sourceAfter = this.buildSource(updatedManifest);
|
|
18540
18481
|
for (const cell of toMigrate) {
|
|
18541
18482
|
onProgress?.({
|
|
18542
18483
|
type: "migrate",
|
|
18543
18484
|
file: cell.filePath,
|
|
18544
18485
|
message: `Migrating ${cell.namespace}/${cell.environment}...`
|
|
18545
18486
|
});
|
|
18546
|
-
const
|
|
18547
|
-
await
|
|
18548
|
-
|
|
18549
|
-
decrypted.values,
|
|
18550
|
-
updatedManifest,
|
|
18551
|
-
cell.environment
|
|
18552
|
-
);
|
|
18487
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18488
|
+
const decrypted = await sourceBefore.readCell(ref);
|
|
18489
|
+
await sourceAfter.writeCell(ref, decrypted.values);
|
|
18553
18490
|
migratedFiles.push(cell.filePath);
|
|
18554
18491
|
}
|
|
18555
18492
|
}
|
|
@@ -18579,7 +18516,7 @@ var BackendMigrator = class {
|
|
|
18579
18516
|
}
|
|
18580
18517
|
const verifiedFiles = [];
|
|
18581
18518
|
const warnings = [];
|
|
18582
|
-
if (!skipVerify) {
|
|
18519
|
+
if (!skipVerify && sourceAfter) {
|
|
18583
18520
|
for (const cell of toMigrate) {
|
|
18584
18521
|
try {
|
|
18585
18522
|
onProgress?.({
|
|
@@ -18587,7 +18524,8 @@ var BackendMigrator = class {
|
|
|
18587
18524
|
file: cell.filePath,
|
|
18588
18525
|
message: `Verifying ${cell.namespace}/${cell.environment}...`
|
|
18589
18526
|
});
|
|
18590
|
-
|
|
18527
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18528
|
+
await sourceAfter.readCell(ref);
|
|
18591
18529
|
verifiedFiles.push(cell.filePath);
|
|
18592
18530
|
} catch (err) {
|
|
18593
18531
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -18632,16 +18570,16 @@ var BackendMigrator = class {
|
|
|
18632
18570
|
};
|
|
18633
18571
|
|
|
18634
18572
|
// src/reset/manager.ts
|
|
18635
|
-
var
|
|
18573
|
+
var path24 = __toESM(require("path"));
|
|
18636
18574
|
var ResetManager = class {
|
|
18637
|
-
constructor(matrixManager,
|
|
18575
|
+
constructor(matrixManager, buildSource, schemaValidator, tx) {
|
|
18638
18576
|
this.matrixManager = matrixManager;
|
|
18639
|
-
this.
|
|
18577
|
+
this.buildSource = buildSource;
|
|
18640
18578
|
this.schemaValidator = schemaValidator;
|
|
18641
18579
|
this.tx = tx;
|
|
18642
18580
|
}
|
|
18643
18581
|
matrixManager;
|
|
18644
|
-
|
|
18582
|
+
buildSource;
|
|
18645
18583
|
schemaValidator;
|
|
18646
18584
|
tx;
|
|
18647
18585
|
async reset(opts, manifest, repoRoot) {
|
|
@@ -18661,11 +18599,11 @@ var ResetManager = class {
|
|
|
18661
18599
|
txPaths.push(CLEF_MANIFEST_FILENAME);
|
|
18662
18600
|
}
|
|
18663
18601
|
for (const cell of targetCells) {
|
|
18664
|
-
txPaths.push(
|
|
18602
|
+
txPaths.push(path24.relative(repoRoot, cell.filePath));
|
|
18665
18603
|
const cellKeys = keyPlan.get(cell.namespace) ?? [];
|
|
18666
18604
|
if (cellKeys.length > 0) {
|
|
18667
18605
|
txPaths.push(
|
|
18668
|
-
|
|
18606
|
+
path24.relative(repoRoot, cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"))
|
|
18669
18607
|
);
|
|
18670
18608
|
}
|
|
18671
18609
|
}
|
|
@@ -18682,17 +18620,14 @@ var ResetManager = class {
|
|
|
18682
18620
|
writeManifestYaml(repoRoot, doc);
|
|
18683
18621
|
effectiveManifest = withBackendOverride(manifest, affectedEnvs, opts.backend, opts.key);
|
|
18684
18622
|
}
|
|
18623
|
+
const source = this.buildSource(effectiveManifest);
|
|
18685
18624
|
for (const cell of targetCells) {
|
|
18686
18625
|
const keys = keyPlan.get(cell.namespace) ?? [];
|
|
18687
18626
|
const placeholders = this.buildPlaceholders(keys);
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
placeholders,
|
|
18691
|
-
effectiveManifest,
|
|
18692
|
-
cell.environment
|
|
18693
|
-
);
|
|
18627
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18628
|
+
await source.writeCell(ref, placeholders);
|
|
18694
18629
|
if (keys.length > 0) {
|
|
18695
|
-
await
|
|
18630
|
+
await source.markPending(ref, keys, "clef reset");
|
|
18696
18631
|
pendingKeysByCell[cell.filePath] = keys;
|
|
18697
18632
|
}
|
|
18698
18633
|
scaffoldedCells.push(cell.filePath);
|
|
@@ -18753,7 +18688,7 @@ var ResetManager = class {
|
|
|
18753
18688
|
for (const namespace of namespaces) {
|
|
18754
18689
|
const nsDef = manifest.namespaces.find((n) => n.name === namespace);
|
|
18755
18690
|
if (nsDef?.schema) {
|
|
18756
|
-
const schema = this.schemaValidator.loadSchema(
|
|
18691
|
+
const schema = this.schemaValidator.loadSchema(path24.join(repoRoot, nsDef.schema));
|
|
18757
18692
|
plan.set(namespace, Object.keys(schema.keys));
|
|
18758
18693
|
continue;
|
|
18759
18694
|
}
|
|
@@ -18832,15 +18767,15 @@ function withBackendOverride(manifest, envNames, backend, key) {
|
|
|
18832
18767
|
}
|
|
18833
18768
|
|
|
18834
18769
|
// src/sync/manager.ts
|
|
18835
|
-
var
|
|
18770
|
+
var path25 = __toESM(require("path"));
|
|
18836
18771
|
var SyncManager = class {
|
|
18837
|
-
constructor(matrixManager,
|
|
18772
|
+
constructor(matrixManager, source, tx) {
|
|
18838
18773
|
this.matrixManager = matrixManager;
|
|
18839
|
-
this.
|
|
18774
|
+
this.source = source;
|
|
18840
18775
|
this.tx = tx;
|
|
18841
18776
|
}
|
|
18842
18777
|
matrixManager;
|
|
18843
|
-
|
|
18778
|
+
source;
|
|
18844
18779
|
tx;
|
|
18845
18780
|
/**
|
|
18846
18781
|
* Compute what sync would do without mutating anything.
|
|
@@ -18857,8 +18792,13 @@ var SyncManager = class {
|
|
|
18857
18792
|
const targetCells = opts.namespace ? existingCells.filter((c) => c.namespace === opts.namespace) : existingCells;
|
|
18858
18793
|
const keysByNsEnv = {};
|
|
18859
18794
|
for (const cell of targetCells) {
|
|
18860
|
-
const
|
|
18861
|
-
|
|
18795
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18796
|
+
let keys;
|
|
18797
|
+
try {
|
|
18798
|
+
keys = await this.source.listKeys(ref);
|
|
18799
|
+
} catch {
|
|
18800
|
+
continue;
|
|
18801
|
+
}
|
|
18862
18802
|
if (!keysByNsEnv[cell.namespace]) keysByNsEnv[cell.namespace] = {};
|
|
18863
18803
|
keysByNsEnv[cell.namespace][cell.environment] = new Set(keys);
|
|
18864
18804
|
}
|
|
@@ -18904,7 +18844,7 @@ var SyncManager = class {
|
|
|
18904
18844
|
}
|
|
18905
18845
|
const txPaths = [];
|
|
18906
18846
|
for (const cell of syncPlan.cells) {
|
|
18907
|
-
const rel =
|
|
18847
|
+
const rel = path25.relative(repoRoot, cell.filePath);
|
|
18908
18848
|
txPaths.push(rel);
|
|
18909
18849
|
txPaths.push(rel.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"));
|
|
18910
18850
|
}
|
|
@@ -18917,17 +18857,13 @@ var SyncManager = class {
|
|
|
18917
18857
|
paths: txPaths,
|
|
18918
18858
|
mutate: async () => {
|
|
18919
18859
|
for (const cell of syncPlan.cells) {
|
|
18920
|
-
const
|
|
18860
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18861
|
+
const decrypted = await this.source.readCell(ref);
|
|
18921
18862
|
for (const key of cell.missingKeys) {
|
|
18922
18863
|
decrypted.values[key] = generateRandomValue();
|
|
18923
18864
|
}
|
|
18924
|
-
await this.
|
|
18925
|
-
|
|
18926
|
-
decrypted.values,
|
|
18927
|
-
manifest,
|
|
18928
|
-
cell.environment
|
|
18929
|
-
);
|
|
18930
|
-
await markPendingWithRetry(cell.filePath, cell.missingKeys, "clef sync");
|
|
18865
|
+
await this.source.writeCell(ref, decrypted.values);
|
|
18866
|
+
await this.source.markPending(ref, cell.missingKeys, "clef sync");
|
|
18931
18867
|
const cellLabel = `${cell.namespace}/${cell.environment}`;
|
|
18932
18868
|
modifiedCells.push(cellLabel);
|
|
18933
18869
|
scaffoldedKeys[cellLabel] = cell.missingKeys;
|
|
@@ -19187,13 +19123,272 @@ var ComplianceGenerator = class {
|
|
|
19187
19123
|
};
|
|
19188
19124
|
|
|
19189
19125
|
// src/compliance/run.ts
|
|
19190
|
-
var
|
|
19126
|
+
var path27 = __toESM(require("path"));
|
|
19127
|
+
|
|
19128
|
+
// src/source/compose.ts
|
|
19129
|
+
var YAML14 = __toESM(require("yaml"));
|
|
19130
|
+
|
|
19131
|
+
// src/source/default-bulk.ts
|
|
19132
|
+
function defaultBulk(source) {
|
|
19133
|
+
return {
|
|
19134
|
+
async bulkSet(namespace, key, valuesByEnv, _manifest) {
|
|
19135
|
+
for (const [environment, value] of Object.entries(valuesByEnv)) {
|
|
19136
|
+
const cell = { namespace, environment };
|
|
19137
|
+
const existing = await source.cellExists(cell) ? (await source.readCell(cell)).values : {};
|
|
19138
|
+
await source.writeCell(cell, { ...existing, [key]: value });
|
|
19139
|
+
}
|
|
19140
|
+
},
|
|
19141
|
+
async bulkDelete(namespace, key, manifest) {
|
|
19142
|
+
for (const env of manifest.environments) {
|
|
19143
|
+
const cell = { namespace, environment: env.name };
|
|
19144
|
+
if (!await source.cellExists(cell)) continue;
|
|
19145
|
+
const data = await source.readCell(cell);
|
|
19146
|
+
if (!(key in data.values)) continue;
|
|
19147
|
+
const next = { ...data.values };
|
|
19148
|
+
delete next[key];
|
|
19149
|
+
await source.writeCell(cell, next);
|
|
19150
|
+
}
|
|
19151
|
+
},
|
|
19152
|
+
async copyValue(key, from, to, _manifest) {
|
|
19153
|
+
const src = await source.readCell(from);
|
|
19154
|
+
if (!(key in src.values)) {
|
|
19155
|
+
throw new Error(
|
|
19156
|
+
`Cannot copy: key '${key}' not present in ${from.namespace}/${from.environment}`
|
|
19157
|
+
);
|
|
19158
|
+
}
|
|
19159
|
+
const dst = await source.cellExists(to) ? (await source.readCell(to)).values : {};
|
|
19160
|
+
await source.writeCell(to, { ...dst, [key]: src.values[key] });
|
|
19161
|
+
}
|
|
19162
|
+
};
|
|
19163
|
+
}
|
|
19164
|
+
|
|
19165
|
+
// src/source/compose.ts
|
|
19166
|
+
function composeSecretSource(storage, encryption, manifest) {
|
|
19167
|
+
return new ComposedSecretSource(storage, encryption, manifest);
|
|
19168
|
+
}
|
|
19169
|
+
var ComposedSecretSource = class {
|
|
19170
|
+
constructor(storage, encryption, manifest) {
|
|
19171
|
+
this.storage = storage;
|
|
19172
|
+
this.encryption = encryption;
|
|
19173
|
+
this.manifest = manifest;
|
|
19174
|
+
this.id = `${storage.id}+${encryption.id}`;
|
|
19175
|
+
this.description = `${storage.description} / ${encryption.description}`;
|
|
19176
|
+
}
|
|
19177
|
+
storage;
|
|
19178
|
+
encryption;
|
|
19179
|
+
manifest;
|
|
19180
|
+
id;
|
|
19181
|
+
description;
|
|
19182
|
+
context(cell) {
|
|
19183
|
+
return {
|
|
19184
|
+
manifest: this.manifest,
|
|
19185
|
+
environment: cell.environment,
|
|
19186
|
+
format: this.storage.blobFormat(cell)
|
|
19187
|
+
};
|
|
19188
|
+
}
|
|
19189
|
+
// ── Core SecretSource ──────────────────────────────────────────────────
|
|
19190
|
+
async readCell(cell) {
|
|
19191
|
+
const blob = await this.storage.readBlob(cell);
|
|
19192
|
+
return this.encryption.decrypt(blob, this.context(cell));
|
|
19193
|
+
}
|
|
19194
|
+
async writeCell(cell, values) {
|
|
19195
|
+
const blob = await this.encryption.encrypt(values, this.context(cell));
|
|
19196
|
+
await this.storage.writeBlob(cell, blob);
|
|
19197
|
+
}
|
|
19198
|
+
async deleteCell(cell) {
|
|
19199
|
+
await this.storage.deleteBlob(cell);
|
|
19200
|
+
}
|
|
19201
|
+
async cellExists(cell) {
|
|
19202
|
+
return this.storage.blobExists(cell);
|
|
19203
|
+
}
|
|
19204
|
+
/**
|
|
19205
|
+
* List cell keys WITHOUT decrypting. SOPS files store key names in
|
|
19206
|
+
* plaintext at the top level of the YAML/JSON document — we read the
|
|
19207
|
+
* blob and return everything except the `sops:` metadata block.
|
|
19208
|
+
*
|
|
19209
|
+
* NOTE: this is currently SOPS-shaped. A future non-SOPS
|
|
19210
|
+
* `EncryptionBackend` whose ciphertext doesn't expose key names in
|
|
19211
|
+
* the clear would need its own listing strategy — likely a
|
|
19212
|
+
* `listKeys(blob)` method on `EncryptionBackend`. Deferred until a
|
|
19213
|
+
* second backend exists.
|
|
19214
|
+
*/
|
|
19215
|
+
async listKeys(cell) {
|
|
19216
|
+
if (!await this.storage.blobExists(cell)) return [];
|
|
19217
|
+
const blob = await this.storage.readBlob(cell);
|
|
19218
|
+
const parsed = YAML14.parse(blob);
|
|
19219
|
+
if (!parsed || typeof parsed !== "object") return [];
|
|
19220
|
+
return Object.keys(parsed).filter((k) => k !== "sops");
|
|
19221
|
+
}
|
|
19222
|
+
async getCellMetadata(cell) {
|
|
19223
|
+
const blob = await this.storage.readBlob(cell);
|
|
19224
|
+
return this.encryption.getMetadata(blob);
|
|
19225
|
+
}
|
|
19226
|
+
async scaffoldCell(cell, manifest) {
|
|
19227
|
+
if (await this.storage.blobExists(cell)) return;
|
|
19228
|
+
const blob = await this.encryption.encrypt(
|
|
19229
|
+
{},
|
|
19230
|
+
{
|
|
19231
|
+
manifest,
|
|
19232
|
+
environment: cell.environment,
|
|
19233
|
+
format: this.storage.blobFormat(cell)
|
|
19234
|
+
}
|
|
19235
|
+
);
|
|
19236
|
+
await this.storage.writeBlob(cell, blob);
|
|
19237
|
+
}
|
|
19238
|
+
// ── Pending / rotation metadata ────────────────────────────────────────
|
|
19239
|
+
async getPendingMetadata(cell) {
|
|
19240
|
+
return this.storage.readPendingMetadata(cell);
|
|
19241
|
+
}
|
|
19242
|
+
async markPending(cell, keys, setBy) {
|
|
19243
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19244
|
+
const now = /* @__PURE__ */ new Date();
|
|
19245
|
+
for (const key of keys) {
|
|
19246
|
+
if (!meta.pending.find((p) => p.key === key)) {
|
|
19247
|
+
meta.pending.push({ key, since: now, setBy });
|
|
19248
|
+
}
|
|
19249
|
+
}
|
|
19250
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19251
|
+
}
|
|
19252
|
+
async markResolved(cell, keys) {
|
|
19253
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19254
|
+
meta.pending = meta.pending.filter((p) => !keys.includes(p.key));
|
|
19255
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19256
|
+
}
|
|
19257
|
+
async recordRotation(cell, keys, rotatedBy) {
|
|
19258
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19259
|
+
const now = /* @__PURE__ */ new Date();
|
|
19260
|
+
for (const key of keys) {
|
|
19261
|
+
const existing = meta.rotations.find((r) => r.key === key);
|
|
19262
|
+
if (existing) {
|
|
19263
|
+
existing.lastRotatedAt = now;
|
|
19264
|
+
existing.rotatedBy = rotatedBy;
|
|
19265
|
+
existing.rotationCount += 1;
|
|
19266
|
+
} else {
|
|
19267
|
+
meta.rotations.push({ key, lastRotatedAt: now, rotatedBy, rotationCount: 1 });
|
|
19268
|
+
}
|
|
19269
|
+
}
|
|
19270
|
+
meta.pending = meta.pending.filter((p) => !keys.includes(p.key));
|
|
19271
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19272
|
+
}
|
|
19273
|
+
async removeRotation(cell, keys) {
|
|
19274
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19275
|
+
meta.rotations = meta.rotations.filter((r) => !keys.includes(r.key));
|
|
19276
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19277
|
+
}
|
|
19278
|
+
// ── Lintable ───────────────────────────────────────────────────────────
|
|
19279
|
+
async validateEncryption(cell) {
|
|
19280
|
+
if (!await this.storage.blobExists(cell)) return false;
|
|
19281
|
+
const blob = await this.storage.readBlob(cell);
|
|
19282
|
+
return this.encryption.validateEncryption(blob);
|
|
19283
|
+
}
|
|
19284
|
+
async checkRecipientDrift(cell, expected) {
|
|
19285
|
+
const blob = await this.storage.readBlob(cell);
|
|
19286
|
+
const meta = this.encryption.getMetadata(blob);
|
|
19287
|
+
const actual = new Set(meta.recipients);
|
|
19288
|
+
const expectedSet = new Set(expected);
|
|
19289
|
+
return {
|
|
19290
|
+
missing: expected.filter((r) => !actual.has(r)),
|
|
19291
|
+
unexpected: meta.recipients.filter((r) => !expectedSet.has(r))
|
|
19292
|
+
};
|
|
19293
|
+
}
|
|
19294
|
+
// ── Rotatable ──────────────────────────────────────────────────────────
|
|
19295
|
+
async rotate(cell, opts) {
|
|
19296
|
+
const blob = await this.storage.readBlob(cell);
|
|
19297
|
+
const rotated = await this.encryption.rotate(blob, opts, this.context(cell));
|
|
19298
|
+
await this.storage.writeBlob(cell, rotated);
|
|
19299
|
+
}
|
|
19300
|
+
// ── Bulk ───────────────────────────────────────────────────────────────
|
|
19301
|
+
//
|
|
19302
|
+
// Default looped implementation. A future StorageBackend that supports
|
|
19303
|
+
// batch operations (e.g. PostgresStorageBackend with row-level UPDATE
|
|
19304
|
+
// batching) can override these by wrapping `composeSecretSource`'s
|
|
19305
|
+
// output and replacing just the bulk methods.
|
|
19306
|
+
bulkSet = (namespace, key, valuesByEnv, manifest) => defaultBulk(this).bulkSet(namespace, key, valuesByEnv, manifest);
|
|
19307
|
+
bulkDelete = (namespace, key, manifest) => defaultBulk(this).bulkDelete(namespace, key, manifest);
|
|
19308
|
+
copyValue = (key, from, to, manifest) => defaultBulk(this).copyValue(key, from, to, manifest);
|
|
19309
|
+
};
|
|
19310
|
+
|
|
19311
|
+
// src/source/filesystem-storage-backend.ts
|
|
19312
|
+
var fs22 = __toESM(require("fs"));
|
|
19313
|
+
var path26 = __toESM(require("path"));
|
|
19314
|
+
var import_crypto3 = require("crypto");
|
|
19315
|
+
var FilesystemStorageBackend = class {
|
|
19316
|
+
constructor(manifest, repoRoot) {
|
|
19317
|
+
this.manifest = manifest;
|
|
19318
|
+
this.repoRoot = repoRoot;
|
|
19319
|
+
}
|
|
19320
|
+
manifest;
|
|
19321
|
+
repoRoot;
|
|
19322
|
+
id = "filesystem";
|
|
19323
|
+
description = "Filesystem-backed cell storage (default substrate)";
|
|
19324
|
+
/**
|
|
19325
|
+
* Resolve a cell reference to its absolute filesystem path. Public —
|
|
19326
|
+
* used by substrate-specific trait implementations.
|
|
19327
|
+
*/
|
|
19328
|
+
cellPath(cell) {
|
|
19329
|
+
const relativePath = this.manifest.file_pattern.replace("{namespace}", cell.namespace).replace("{environment}", cell.environment);
|
|
19330
|
+
return path26.join(this.repoRoot, relativePath);
|
|
19331
|
+
}
|
|
19332
|
+
/** The repo root, exposed for filesystem-shaped trait implementations. */
|
|
19333
|
+
getRepoRoot() {
|
|
19334
|
+
return this.repoRoot;
|
|
19335
|
+
}
|
|
19336
|
+
blobFormat(cell) {
|
|
19337
|
+
return this.cellPath(cell).endsWith(".json") ? "json" : "yaml";
|
|
19338
|
+
}
|
|
19339
|
+
async readBlob(cell) {
|
|
19340
|
+
const filePath = this.cellPath(cell);
|
|
19341
|
+
return fs22.readFileSync(filePath, "utf-8");
|
|
19342
|
+
}
|
|
19343
|
+
async writeBlob(cell, blob) {
|
|
19344
|
+
const filePath = this.cellPath(cell);
|
|
19345
|
+
const dir = path26.dirname(filePath);
|
|
19346
|
+
if (!fs22.existsSync(dir)) {
|
|
19347
|
+
fs22.mkdirSync(dir, { recursive: true });
|
|
19348
|
+
}
|
|
19349
|
+
const tmpPath = `${filePath}.${Date.now()}.${(0, import_crypto3.randomBytes)(4).toString("hex")}.tmp`;
|
|
19350
|
+
const handle = fs22.openSync(tmpPath, "w");
|
|
19351
|
+
try {
|
|
19352
|
+
fs22.writeFileSync(handle, blob);
|
|
19353
|
+
fs22.fsyncSync(handle);
|
|
19354
|
+
} finally {
|
|
19355
|
+
fs22.closeSync(handle);
|
|
19356
|
+
}
|
|
19357
|
+
fs22.renameSync(tmpPath, filePath);
|
|
19358
|
+
}
|
|
19359
|
+
async deleteBlob(cell) {
|
|
19360
|
+
const filePath = this.cellPath(cell);
|
|
19361
|
+
if (fs22.existsSync(filePath)) {
|
|
19362
|
+
fs22.unlinkSync(filePath);
|
|
19363
|
+
}
|
|
19364
|
+
const sidecar = this.sidecarPath(filePath);
|
|
19365
|
+
if (fs22.existsSync(sidecar)) {
|
|
19366
|
+
fs22.unlinkSync(sidecar);
|
|
19367
|
+
}
|
|
19368
|
+
}
|
|
19369
|
+
async blobExists(cell) {
|
|
19370
|
+
return fs22.existsSync(this.cellPath(cell));
|
|
19371
|
+
}
|
|
19372
|
+
async readPendingMetadata(cell) {
|
|
19373
|
+
return loadMetadata(this.cellPath(cell));
|
|
19374
|
+
}
|
|
19375
|
+
async writePendingMetadata(cell, meta) {
|
|
19376
|
+
await saveMetadata(this.cellPath(cell), meta);
|
|
19377
|
+
}
|
|
19378
|
+
sidecarPath(filePath) {
|
|
19379
|
+
const dir = path26.dirname(filePath);
|
|
19380
|
+
const base = path26.basename(filePath).replace(/\.enc\.(yaml|json)$/, "");
|
|
19381
|
+
return path26.join(dir, `${base}.clef-meta.yaml`);
|
|
19382
|
+
}
|
|
19383
|
+
};
|
|
19384
|
+
|
|
19385
|
+
// src/compliance/run.ts
|
|
19191
19386
|
var UNKNOWN = "unknown";
|
|
19192
19387
|
async function runCompliance(opts) {
|
|
19193
19388
|
const start = Date.now();
|
|
19194
19389
|
const repoRoot = opts.repoRoot ?? process.cwd();
|
|
19195
|
-
const manifestPath = opts.manifestPath ??
|
|
19196
|
-
const policyPath = opts.policyPath ??
|
|
19390
|
+
const manifestPath = opts.manifestPath ?? path27.join(repoRoot, "clef.yaml");
|
|
19391
|
+
const policyPath = opts.policyPath ?? path27.join(repoRoot, CLEF_POLICY_FILENAME);
|
|
19197
19392
|
const include = {
|
|
19198
19393
|
scan: opts.include?.scan ?? true,
|
|
19199
19394
|
lint: opts.include?.lint ?? true,
|
|
@@ -19205,6 +19400,11 @@ async function runCompliance(opts) {
|
|
|
19205
19400
|
const sopsClient = new SopsClient(opts.runner, opts.ageKeyFile, opts.ageKey, opts.sopsPath);
|
|
19206
19401
|
const matrixManager = new MatrixManager();
|
|
19207
19402
|
const schemaValidator = new SchemaValidator();
|
|
19403
|
+
const lintSource = composeSecretSource(
|
|
19404
|
+
new FilesystemStorageBackend(manifest, repoRoot),
|
|
19405
|
+
sopsClient,
|
|
19406
|
+
manifest
|
|
19407
|
+
);
|
|
19208
19408
|
const [sha, repo, files, scanResult, lintResult] = await Promise.all([
|
|
19209
19409
|
opts.sha !== void 0 ? Promise.resolve(opts.sha) : detectSha(opts.runner, repoRoot),
|
|
19210
19410
|
opts.repo !== void 0 ? Promise.resolve(opts.repo) : detectRepo(opts.runner, repoRoot),
|
|
@@ -19213,12 +19413,12 @@ async function runCompliance(opts) {
|
|
|
19213
19413
|
repoRoot,
|
|
19214
19414
|
policy,
|
|
19215
19415
|
matrixManager,
|
|
19216
|
-
|
|
19416
|
+
source: lintSource,
|
|
19217
19417
|
filter: opts.filter,
|
|
19218
19418
|
now
|
|
19219
19419
|
}) : Promise.resolve([]),
|
|
19220
19420
|
include.scan ? new ScanRunner(opts.runner).scan(repoRoot, manifest) : Promise.resolve(emptyScan()),
|
|
19221
|
-
include.lint ? new LintRunner(matrixManager, schemaValidator,
|
|
19421
|
+
include.lint ? new LintRunner(matrixManager, schemaValidator, lintSource).run(manifest, repoRoot) : Promise.resolve(emptyLint())
|
|
19222
19422
|
]);
|
|
19223
19423
|
const adjustedLint = downgradeDecryptIssues(lintResult);
|
|
19224
19424
|
const document = new ComplianceGenerator().generate({
|
|
@@ -19238,8 +19438,11 @@ async function evaluateMatrix(args) {
|
|
|
19238
19438
|
const cells = args.matrixManager.resolveMatrix(args.manifest, args.repoRoot).filter((c) => applyFilter(c.namespace, c.environment, args.filter)).filter((c) => c.exists);
|
|
19239
19439
|
return Promise.all(
|
|
19240
19440
|
cells.map(async (cell) => {
|
|
19241
|
-
const metadata = await args.
|
|
19242
|
-
|
|
19441
|
+
const metadata = await args.source.getCellMetadata({
|
|
19442
|
+
namespace: cell.namespace,
|
|
19443
|
+
environment: cell.environment
|
|
19444
|
+
});
|
|
19445
|
+
const relPath = path27.relative(args.repoRoot, cell.filePath).replace(/\\/g, "/");
|
|
19243
19446
|
const keys = readSopsKeyNames(cell.filePath) ?? [];
|
|
19244
19447
|
const rotations = await getRotations(cell.filePath);
|
|
19245
19448
|
return evaluator.evaluateFile(relPath, cell.environment, metadata, keys, rotations, args.now);
|
|
@@ -19297,11 +19500,62 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19297
19500
|
const match = url.match(/[:/]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
19298
19501
|
return match ? `${match[1]}/${match[2]}` : UNKNOWN;
|
|
19299
19502
|
}
|
|
19503
|
+
|
|
19504
|
+
// src/source/guards.ts
|
|
19505
|
+
function isFn(o, name) {
|
|
19506
|
+
return typeof o === "object" && o !== null && typeof o[name] === "function";
|
|
19507
|
+
}
|
|
19508
|
+
function isLintable(s) {
|
|
19509
|
+
return isFn(s, "validateEncryption") && isFn(s, "checkRecipientDrift");
|
|
19510
|
+
}
|
|
19511
|
+
function isRotatable(s) {
|
|
19512
|
+
return isFn(s, "rotate");
|
|
19513
|
+
}
|
|
19514
|
+
function isRecipientManaged(s) {
|
|
19515
|
+
return isFn(s, "listRecipients") && isFn(s, "addRecipient") && isFn(s, "removeRecipient");
|
|
19516
|
+
}
|
|
19517
|
+
function isMergeAware(s) {
|
|
19518
|
+
return isFn(s, "mergeCells") && isFn(s, "installMergeDriver");
|
|
19519
|
+
}
|
|
19520
|
+
function isMigratable(s) {
|
|
19521
|
+
return isFn(s, "migrateBackend");
|
|
19522
|
+
}
|
|
19523
|
+
function isBulk(s) {
|
|
19524
|
+
return isFn(s, "bulkSet") && isFn(s, "bulkDelete") && isFn(s, "copyValue");
|
|
19525
|
+
}
|
|
19526
|
+
function isStructural(s) {
|
|
19527
|
+
return isFn(s, "addNamespace") && isFn(s, "addEnvironment") && isFn(s, "renameNamespace") && isFn(s, "renameEnvironment");
|
|
19528
|
+
}
|
|
19529
|
+
function describeCapabilities(s) {
|
|
19530
|
+
return {
|
|
19531
|
+
lint: isLintable(s),
|
|
19532
|
+
rotate: isRotatable(s),
|
|
19533
|
+
recipients: isRecipientManaged(s),
|
|
19534
|
+
merge: isMergeAware(s),
|
|
19535
|
+
migrate: isMigratable(s),
|
|
19536
|
+
bulk: isBulk(s),
|
|
19537
|
+
structural: isStructural(s)
|
|
19538
|
+
};
|
|
19539
|
+
}
|
|
19540
|
+
|
|
19541
|
+
// src/source/errors.ts
|
|
19542
|
+
var SourceCapabilityUnsupportedError = class extends ClefError {
|
|
19543
|
+
constructor(capability, sourceId) {
|
|
19544
|
+
super(
|
|
19545
|
+
`'${capability}' is not supported by the '${sourceId}' source.`,
|
|
19546
|
+
`Switch to a source that implements ${capability}, or use a different command.`
|
|
19547
|
+
);
|
|
19548
|
+
this.capability = capability;
|
|
19549
|
+
this.sourceId = sourceId;
|
|
19550
|
+
this.name = "SourceCapabilityUnsupportedError";
|
|
19551
|
+
}
|
|
19552
|
+
capability;
|
|
19553
|
+
sourceId;
|
|
19554
|
+
};
|
|
19300
19555
|
// Annotate the CommonJS export names for ESM import in node:
|
|
19301
19556
|
0 && (module.exports = {
|
|
19302
19557
|
ArtifactPacker,
|
|
19303
19558
|
BackendMigrator,
|
|
19304
|
-
BulkOps,
|
|
19305
19559
|
CLEF_MANIFEST_FILENAME,
|
|
19306
19560
|
CLEF_POLICY_FILENAME,
|
|
19307
19561
|
CLEF_REPORT_SCHEMA_VERSION,
|
|
@@ -19315,6 +19569,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19315
19569
|
DiffEngine,
|
|
19316
19570
|
DriftDetector,
|
|
19317
19571
|
FilePackOutput,
|
|
19572
|
+
FilesystemStorageBackend,
|
|
19318
19573
|
GitIntegration,
|
|
19319
19574
|
GitOperationError,
|
|
19320
19575
|
ImportRunner,
|
|
@@ -19331,7 +19586,6 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19331
19586
|
PolicyValidationError,
|
|
19332
19587
|
REQUESTS_FILENAME,
|
|
19333
19588
|
REQUIREMENTS,
|
|
19334
|
-
REVEAL_WARNING,
|
|
19335
19589
|
RecipientManager,
|
|
19336
19590
|
ReportGenerator,
|
|
19337
19591
|
ReportSanitizer,
|
|
@@ -19348,6 +19602,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19348
19602
|
SopsMergeDriver,
|
|
19349
19603
|
SopsMissingError,
|
|
19350
19604
|
SopsVersionError,
|
|
19605
|
+
SourceCapabilityUnsupportedError,
|
|
19351
19606
|
StructureManager,
|
|
19352
19607
|
SyncManager,
|
|
19353
19608
|
TransactionLockError,
|
|
@@ -19367,11 +19622,11 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19367
19622
|
checkAll,
|
|
19368
19623
|
checkDependency,
|
|
19369
19624
|
collectCIContext,
|
|
19625
|
+
composeSecretSource,
|
|
19370
19626
|
computeCiphertextHash,
|
|
19371
19627
|
deriveAgePublicKey,
|
|
19628
|
+
describeCapabilities,
|
|
19372
19629
|
describeScope,
|
|
19373
|
-
detectAlgorithm,
|
|
19374
|
-
detectFormat,
|
|
19375
19630
|
emptyTemplate,
|
|
19376
19631
|
exampleTemplate,
|
|
19377
19632
|
findRequest,
|
|
@@ -19379,35 +19634,27 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19379
19634
|
formatRevealWarning,
|
|
19380
19635
|
generateAgeIdentity,
|
|
19381
19636
|
generateRandomValue,
|
|
19382
|
-
|
|
19383
|
-
getPendingKeys,
|
|
19384
|
-
getRotations,
|
|
19637
|
+
isBulk,
|
|
19385
19638
|
isClefHsmArn,
|
|
19386
|
-
isHighEntropy,
|
|
19387
19639
|
isKmsEnvelope,
|
|
19640
|
+
isLintable,
|
|
19641
|
+
isMergeAware,
|
|
19642
|
+
isMigratable,
|
|
19388
19643
|
isPackedArtifact,
|
|
19389
|
-
|
|
19644
|
+
isRecipientManaged,
|
|
19645
|
+
isRotatable,
|
|
19646
|
+
isStructural,
|
|
19390
19647
|
keyPreview,
|
|
19391
|
-
loadIgnoreRules,
|
|
19392
|
-
loadMetadata,
|
|
19393
19648
|
loadRequests,
|
|
19394
19649
|
markPending,
|
|
19395
|
-
markPendingWithRetry,
|
|
19396
19650
|
markResolved,
|
|
19397
|
-
matchPatterns,
|
|
19398
|
-
mergeMetadataContents,
|
|
19399
19651
|
mergeMetadataFiles,
|
|
19400
|
-
metadataPath,
|
|
19401
19652
|
parse,
|
|
19402
|
-
parseDotenv,
|
|
19403
|
-
parseIgnoreContent,
|
|
19404
|
-
parseJson,
|
|
19405
19653
|
parseSignerKey,
|
|
19406
19654
|
parseYaml,
|
|
19407
19655
|
pkcs11UriToSyntheticArn,
|
|
19408
19656
|
readManifestYaml,
|
|
19409
19657
|
recordRotation,
|
|
19410
|
-
redactValue,
|
|
19411
19658
|
removeAccessRequest,
|
|
19412
19659
|
removeRotation,
|
|
19413
19660
|
requestsFilePath,
|
|
@@ -19419,14 +19666,8 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19419
19666
|
resolveRecipientsForEnvironment,
|
|
19420
19667
|
resolveSopsPath,
|
|
19421
19668
|
runCompliance,
|
|
19422
|
-
saveMetadata,
|
|
19423
19669
|
saveRequests,
|
|
19424
|
-
|
|
19425
|
-
shannonEntropy,
|
|
19426
|
-
shouldIgnoreFile,
|
|
19427
|
-
shouldIgnoreMatch,
|
|
19428
|
-
signEd25519,
|
|
19429
|
-
signKms,
|
|
19670
|
+
shouldUseLinuxStdinFifo,
|
|
19430
19671
|
spawnKeyservice,
|
|
19431
19672
|
syntheticArnToPkcs11Uri,
|
|
19432
19673
|
tryBundledKeyservice,
|
|
@@ -19436,6 +19677,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19436
19677
|
validatePackedArtifact,
|
|
19437
19678
|
validateResetScope,
|
|
19438
19679
|
verifySignature,
|
|
19680
|
+
wrapWithLinuxStdinFifo,
|
|
19439
19681
|
writeManifestYaml,
|
|
19440
19682
|
writeManifestYamlRaw,
|
|
19441
19683
|
writeSchema,
|