@clef-sh/core 0.1.28 → 0.3.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 +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1080 -832
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +1049 -791
- 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,29 +11498,24 @@ __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
11503
|
isHighEntropy: () => isHighEntropy,
|
|
11506
11504
|
isKmsEnvelope: () => isKmsEnvelope,
|
|
11505
|
+
isLintable: () => isLintable,
|
|
11506
|
+
isMergeAware: () => isMergeAware,
|
|
11507
|
+
isMigratable: () => isMigratable,
|
|
11507
11508
|
isPackedArtifact: () => isPackedArtifact,
|
|
11508
|
-
|
|
11509
|
+
isRecipientManaged: () => isRecipientManaged,
|
|
11510
|
+
isRotatable: () => isRotatable,
|
|
11511
|
+
isStructural: () => isStructural,
|
|
11509
11512
|
keyPreview: () => keyPreview,
|
|
11510
|
-
loadIgnoreRules: () => loadIgnoreRules,
|
|
11511
|
-
loadMetadata: () => loadMetadata,
|
|
11512
11513
|
loadRequests: () => loadRequests,
|
|
11513
11514
|
markPending: () => markPending,
|
|
11514
|
-
markPendingWithRetry: () => markPendingWithRetry,
|
|
11515
11515
|
markResolved: () => markResolved,
|
|
11516
11516
|
matchPatterns: () => matchPatterns,
|
|
11517
|
-
mergeMetadataContents: () => mergeMetadataContents,
|
|
11518
11517
|
mergeMetadataFiles: () => mergeMetadataFiles,
|
|
11519
|
-
metadataPath: () => metadataPath,
|
|
11520
11518
|
parse: () => parse9,
|
|
11521
|
-
parseDotenv: () => parseDotenv,
|
|
11522
|
-
parseIgnoreContent: () => parseIgnoreContent,
|
|
11523
|
-
parseJson: () => parseJson,
|
|
11524
11519
|
parseSignerKey: () => parseSignerKey,
|
|
11525
11520
|
parseYaml: () => parseYaml,
|
|
11526
11521
|
pkcs11UriToSyntheticArn: () => pkcs11UriToSyntheticArn,
|
|
@@ -11538,14 +11533,8 @@ __export(index_exports, {
|
|
|
11538
11533
|
resolveRecipientsForEnvironment: () => resolveRecipientsForEnvironment,
|
|
11539
11534
|
resolveSopsPath: () => resolveSopsPath,
|
|
11540
11535
|
runCompliance: () => runCompliance,
|
|
11541
|
-
saveMetadata: () => saveMetadata,
|
|
11542
11536
|
saveRequests: () => saveRequests,
|
|
11543
|
-
|
|
11544
|
-
shannonEntropy: () => shannonEntropy,
|
|
11545
|
-
shouldIgnoreFile: () => shouldIgnoreFile,
|
|
11546
|
-
shouldIgnoreMatch: () => shouldIgnoreMatch,
|
|
11547
|
-
signEd25519: () => signEd25519,
|
|
11548
|
-
signKms: () => signKms,
|
|
11537
|
+
shouldUseLinuxStdinFifo: () => shouldUseLinuxStdinFifo,
|
|
11549
11538
|
spawnKeyservice: () => spawnKeyservice,
|
|
11550
11539
|
syntheticArnToPkcs11Uri: () => syntheticArnToPkcs11Uri,
|
|
11551
11540
|
tryBundledKeyservice: () => tryBundledKeyservice,
|
|
@@ -11555,6 +11544,7 @@ __export(index_exports, {
|
|
|
11555
11544
|
validatePackedArtifact: () => validatePackedArtifact,
|
|
11556
11545
|
validateResetScope: () => validateResetScope,
|
|
11557
11546
|
verifySignature: () => verifySignature,
|
|
11547
|
+
wrapWithLinuxStdinFifo: () => wrapWithLinuxStdinFifo,
|
|
11558
11548
|
writeManifestYaml: () => writeManifestYaml,
|
|
11559
11549
|
writeManifestYamlRaw: () => writeManifestYamlRaw,
|
|
11560
11550
|
writeSchema: () => writeSchema,
|
|
@@ -12907,10 +12897,6 @@ async function getPendingKeys(filePath) {
|
|
|
12907
12897
|
const metadata = await loadMetadata(filePath);
|
|
12908
12898
|
return metadata.pending.map((p) => p.key);
|
|
12909
12899
|
}
|
|
12910
|
-
async function isPending(filePath, key) {
|
|
12911
|
-
const metadata = await loadMetadata(filePath);
|
|
12912
|
-
return metadata.pending.some((p) => p.key === key);
|
|
12913
|
-
}
|
|
12914
12900
|
async function recordRotation(filePath, keys, rotatedBy, now = /* @__PURE__ */ new Date()) {
|
|
12915
12901
|
const metadata = await loadMetadata(filePath);
|
|
12916
12902
|
for (const key of keys) {
|
|
@@ -12946,14 +12932,6 @@ async function getRotations(filePath) {
|
|
|
12946
12932
|
function generateRandomValue() {
|
|
12947
12933
|
return crypto2.randomBytes(32).toString("hex");
|
|
12948
12934
|
}
|
|
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
12935
|
|
|
12958
12936
|
// src/sops/keys.ts
|
|
12959
12937
|
var fs6 = __toESM(require("fs"));
|
|
@@ -13003,34 +12981,17 @@ var MatrixManager = class {
|
|
|
13003
12981
|
detectMissingCells(manifest, repoRoot) {
|
|
13004
12982
|
return this.resolveMatrix(manifest, repoRoot).filter((cell) => !cell.exists);
|
|
13005
12983
|
}
|
|
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
12984
|
/**
|
|
13021
12985
|
* Read each cell and return key counts, pending counts, and cross-environment issues.
|
|
13022
12986
|
*
|
|
13023
|
-
*
|
|
13024
|
-
*
|
|
13025
|
-
*
|
|
13026
|
-
* decrypt-based implementation later (e.g. for backends that don't expose
|
|
13027
|
-
* key names without decryption).
|
|
12987
|
+
* Keys are read from the plaintext YAML structure directly — no
|
|
12988
|
+
* decryption needed. A future backend that doesn't expose key names
|
|
12989
|
+
* without decryption would need its own implementation.
|
|
13028
12990
|
*
|
|
13029
12991
|
* @param manifest - Parsed manifest.
|
|
13030
12992
|
* @param repoRoot - Absolute path to the repository root.
|
|
13031
|
-
* @param _sopsClient - Reserved for future use; pass any `EncryptionBackend`.
|
|
13032
12993
|
*/
|
|
13033
|
-
async getMatrixStatus(manifest, repoRoot
|
|
12994
|
+
async getMatrixStatus(manifest, repoRoot) {
|
|
13034
12995
|
const cells = this.resolveMatrix(manifest, repoRoot);
|
|
13035
12996
|
const statuses = [];
|
|
13036
12997
|
const cellKeys = /* @__PURE__ */ new Map();
|
|
@@ -13346,7 +13307,6 @@ function orderedKeys(keys) {
|
|
|
13346
13307
|
}
|
|
13347
13308
|
|
|
13348
13309
|
// src/diff/engine.ts
|
|
13349
|
-
var path7 = __toESM(require("path"));
|
|
13350
13310
|
var DiffEngine = class {
|
|
13351
13311
|
/**
|
|
13352
13312
|
* Compare two in-memory value maps and produce a sorted diff result.
|
|
@@ -13397,131 +13357,21 @@ var DiffEngine = class {
|
|
|
13397
13357
|
* @param namespace - Namespace containing both cells.
|
|
13398
13358
|
* @param envA - Name of environment A.
|
|
13399
13359
|
* @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.
|
|
13360
|
+
* @param source - SecretSource that resolves both cells (substrate-agnostic).
|
|
13361
|
+
* @throws {@link SopsDecryptionError} If either cell cannot be decrypted.
|
|
13404
13362
|
*/
|
|
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
|
-
);
|
|
13363
|
+
async diffCells(namespace, envA, envB, source) {
|
|
13414
13364
|
const [decryptedA, decryptedB] = await Promise.all([
|
|
13415
|
-
|
|
13416
|
-
|
|
13365
|
+
source.readCell({ namespace, environment: envA }),
|
|
13366
|
+
source.readCell({ namespace, environment: envB })
|
|
13417
13367
|
]);
|
|
13418
13368
|
return this.diff(decryptedA.values, decryptedB.values, envA, envB, namespace);
|
|
13419
13369
|
}
|
|
13420
13370
|
};
|
|
13421
13371
|
|
|
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
13372
|
// src/git/integration.ts
|
|
13523
13373
|
var fs10 = __toESM(require("fs"));
|
|
13524
|
-
var
|
|
13374
|
+
var path7 = __toESM(require("path"));
|
|
13525
13375
|
var PRE_COMMIT_HOOK = `#!/bin/sh
|
|
13526
13376
|
# Clef pre-commit hook \u2014 blocks commits of files missing SOPS encryption metadata
|
|
13527
13377
|
# and scans staged files for plaintext secrets.
|
|
@@ -13697,17 +13547,17 @@ var GitIntegration = class {
|
|
|
13697
13547
|
* @returns The kind of operation in progress, or null if none.
|
|
13698
13548
|
*/
|
|
13699
13549
|
async isMidOperation(repoRoot) {
|
|
13700
|
-
const gitDir =
|
|
13701
|
-
if (fs10.existsSync(
|
|
13550
|
+
const gitDir = path7.join(repoRoot, ".git");
|
|
13551
|
+
if (fs10.existsSync(path7.join(gitDir, "MERGE_HEAD"))) {
|
|
13702
13552
|
return { midOp: true, kind: "merge" };
|
|
13703
13553
|
}
|
|
13704
|
-
if (fs10.existsSync(
|
|
13554
|
+
if (fs10.existsSync(path7.join(gitDir, "rebase-merge")) || fs10.existsSync(path7.join(gitDir, "rebase-apply"))) {
|
|
13705
13555
|
return { midOp: true, kind: "rebase" };
|
|
13706
13556
|
}
|
|
13707
|
-
if (fs10.existsSync(
|
|
13557
|
+
if (fs10.existsSync(path7.join(gitDir, "CHERRY_PICK_HEAD"))) {
|
|
13708
13558
|
return { midOp: true, kind: "cherry-pick" };
|
|
13709
13559
|
}
|
|
13710
|
-
if (fs10.existsSync(
|
|
13560
|
+
if (fs10.existsSync(path7.join(gitDir, "REVERT_HEAD"))) {
|
|
13711
13561
|
return { midOp: true, kind: "revert" };
|
|
13712
13562
|
}
|
|
13713
13563
|
return { midOp: false };
|
|
@@ -13919,14 +13769,14 @@ var GitIntegration = class {
|
|
|
13919
13769
|
{ cwd: repoRoot }
|
|
13920
13770
|
);
|
|
13921
13771
|
const metadataGitConfig = metaConfig.exitCode === 0 && metaConfig.stdout.trim().length > 0;
|
|
13922
|
-
const attrFilePath =
|
|
13772
|
+
const attrFilePath = path7.join(repoRoot, ".gitattributes");
|
|
13923
13773
|
const attrContent = fs10.existsSync(attrFilePath) ? fs10.readFileSync(attrFilePath, "utf-8") : "";
|
|
13924
13774
|
const gitattributes = attrContent.includes("merge=sops");
|
|
13925
13775
|
const metadataGitattributes = attrContent.includes("merge=clef-metadata");
|
|
13926
13776
|
return { gitConfig, gitattributes, metadataGitConfig, metadataGitattributes };
|
|
13927
13777
|
}
|
|
13928
13778
|
async ensureGitattributes(repoRoot) {
|
|
13929
|
-
const attrPath =
|
|
13779
|
+
const attrPath = path7.join(repoRoot, ".gitattributes");
|
|
13930
13780
|
const existing = fs10.existsSync(attrPath) ? fs10.readFileSync(attrPath, "utf-8") : "";
|
|
13931
13781
|
let newContent = existing;
|
|
13932
13782
|
if (!existing.includes("merge=sops")) {
|
|
@@ -13961,9 +13811,9 @@ ${block}` : block;
|
|
|
13961
13811
|
* @throws {@link GitOperationError} On failure.
|
|
13962
13812
|
*/
|
|
13963
13813
|
async installPreCommitHook(repoRoot) {
|
|
13964
|
-
const hookPath =
|
|
13814
|
+
const hookPath = path7.join(repoRoot, ".git", "hooks", "pre-commit");
|
|
13965
13815
|
try {
|
|
13966
|
-
const hooksDir =
|
|
13816
|
+
const hooksDir = path7.dirname(hookPath);
|
|
13967
13817
|
if (!fs10.existsSync(hooksDir)) {
|
|
13968
13818
|
fs10.mkdirSync(hooksDir, { recursive: true });
|
|
13969
13819
|
}
|
|
@@ -13979,7 +13829,7 @@ ${block}` : block;
|
|
|
13979
13829
|
|
|
13980
13830
|
// src/tx/transaction-manager.ts
|
|
13981
13831
|
var fs11 = __toESM(require("fs"));
|
|
13982
|
-
var
|
|
13832
|
+
var path8 = __toESM(require("path"));
|
|
13983
13833
|
var lockfile = __toESM(require_proper_lockfile());
|
|
13984
13834
|
|
|
13985
13835
|
// src/tx/errors.ts
|
|
@@ -14028,15 +13878,15 @@ var TransactionManager = class {
|
|
|
14028
13878
|
async run(repoRoot, opts) {
|
|
14029
13879
|
const shouldCommit = opts.commit !== false;
|
|
14030
13880
|
const allowDirty = opts.allowDirty === true;
|
|
14031
|
-
const clefDir =
|
|
13881
|
+
const clefDir = path8.join(repoRoot, CLEF_DIR);
|
|
14032
13882
|
if (!fs11.existsSync(clefDir)) {
|
|
14033
13883
|
fs11.mkdirSync(clefDir, { recursive: true });
|
|
14034
13884
|
}
|
|
14035
|
-
const clefGitignore =
|
|
13885
|
+
const clefGitignore = path8.join(clefDir, ".gitignore");
|
|
14036
13886
|
if (!fs11.existsSync(clefGitignore)) {
|
|
14037
13887
|
fs11.writeFileSync(clefGitignore, "*\n");
|
|
14038
13888
|
}
|
|
14039
|
-
const lockPath =
|
|
13889
|
+
const lockPath = path8.join(clefDir, LOCK_FILE);
|
|
14040
13890
|
if (!fs11.existsSync(lockPath)) {
|
|
14041
13891
|
fs11.writeFileSync(lockPath, "");
|
|
14042
13892
|
}
|
|
@@ -14177,16 +14027,15 @@ var TransactionManager = class {
|
|
|
14177
14027
|
var fs14 = __toESM(require("fs"));
|
|
14178
14028
|
var net = __toESM(require("net"));
|
|
14179
14029
|
var import_crypto = require("crypto");
|
|
14180
|
-
var import_write_file_atomic3 = __toESM(require_lib());
|
|
14181
14030
|
var YAML8 = __toESM(require("yaml"));
|
|
14182
14031
|
|
|
14183
14032
|
// src/sops/resolver.ts
|
|
14184
14033
|
var fs13 = __toESM(require("fs"));
|
|
14185
|
-
var
|
|
14034
|
+
var path10 = __toESM(require("path"));
|
|
14186
14035
|
|
|
14187
14036
|
// src/sops/bundled.ts
|
|
14188
14037
|
var fs12 = __toESM(require("fs"));
|
|
14189
|
-
var
|
|
14038
|
+
var path9 = __toESM(require("path"));
|
|
14190
14039
|
function tryBundled() {
|
|
14191
14040
|
const platform = process.platform;
|
|
14192
14041
|
const arch = process.arch;
|
|
@@ -14198,8 +14047,8 @@ function tryBundled() {
|
|
|
14198
14047
|
const binName = platform === "win32" ? "sops.exe" : "sops";
|
|
14199
14048
|
try {
|
|
14200
14049
|
const packageMain = require.resolve(`${packageName}/package.json`);
|
|
14201
|
-
const packageDir =
|
|
14202
|
-
const binPath =
|
|
14050
|
+
const packageDir = path9.dirname(packageMain);
|
|
14051
|
+
const binPath = path9.join(packageDir, "bin", binName);
|
|
14203
14052
|
return fs12.existsSync(binPath) ? binPath : null;
|
|
14204
14053
|
} catch {
|
|
14205
14054
|
return null;
|
|
@@ -14208,7 +14057,7 @@ function tryBundled() {
|
|
|
14208
14057
|
|
|
14209
14058
|
// src/sops/resolver.ts
|
|
14210
14059
|
function validateSopsPath(candidate) {
|
|
14211
|
-
if (!
|
|
14060
|
+
if (!path10.isAbsolute(candidate)) {
|
|
14212
14061
|
throw new Error(`CLEF_SOPS_PATH must be an absolute path, got '${candidate}'.`);
|
|
14213
14062
|
}
|
|
14214
14063
|
const segments = candidate.split(/[/\\]/);
|
|
@@ -14387,6 +14236,17 @@ function isClefHsmArn(arn) {
|
|
|
14387
14236
|
function formatFromPath(filePath) {
|
|
14388
14237
|
return filePath.endsWith(".json") ? "json" : "yaml";
|
|
14389
14238
|
}
|
|
14239
|
+
async function openInputPipe(content) {
|
|
14240
|
+
if (process.platform === "win32") {
|
|
14241
|
+
const pipe = await openWindowsInputPipe(content);
|
|
14242
|
+
return { inputArg: pipe.inputArg, cleanup: pipe.cleanup };
|
|
14243
|
+
}
|
|
14244
|
+
return { inputArg: "/dev/stdin", cleanup: () => {
|
|
14245
|
+
}, runnerStdin: content };
|
|
14246
|
+
}
|
|
14247
|
+
function nullConfigPath() {
|
|
14248
|
+
return process.platform === "win32" ? "NUL" : "/dev/null";
|
|
14249
|
+
}
|
|
14390
14250
|
function openWindowsInputPipe(content) {
|
|
14391
14251
|
const pipeName = `\\\\.\\pipe\\clef-sops-${(0, import_crypto.randomBytes)(8).toString("hex")}`;
|
|
14392
14252
|
return new Promise((resolve2, reject) => {
|
|
@@ -14434,6 +14294,10 @@ var SopsClient = class {
|
|
|
14434
14294
|
runner;
|
|
14435
14295
|
ageKeyFile;
|
|
14436
14296
|
ageKey;
|
|
14297
|
+
/** {@link EncryptionBackend} identifier. */
|
|
14298
|
+
id = "sops";
|
|
14299
|
+
/** {@link EncryptionBackend} short description (used by `clef doctor`). */
|
|
14300
|
+
description = "SOPS-based encryption via the bundled `sops` binary";
|
|
14437
14301
|
sopsCommand;
|
|
14438
14302
|
keyserviceArgs;
|
|
14439
14303
|
buildSopsEnv() {
|
|
@@ -14447,14 +14311,18 @@ var SopsClient = class {
|
|
|
14447
14311
|
return Object.keys(env).length > 0 ? env : void 0;
|
|
14448
14312
|
}
|
|
14449
14313
|
/**
|
|
14450
|
-
* Decrypt a SOPS-encrypted file
|
|
14314
|
+
* Decrypt a SOPS-encrypted file by path. The only remaining file-path
|
|
14315
|
+
* entry point on this class — kept for the merge driver, which
|
|
14316
|
+
* receives temp filesystem paths from git that don't map onto a
|
|
14317
|
+
* `CellRef`. Production `SecretSource` consumers should call
|
|
14318
|
+
* `source.readCell` instead.
|
|
14451
14319
|
*
|
|
14452
14320
|
* @param filePath - Path to the `.enc.yaml` or `.enc.json` file.
|
|
14453
14321
|
* @returns {@link DecryptedFile} with plaintext values in memory only.
|
|
14454
14322
|
* @throws {@link SopsKeyNotFoundError} If no matching decryption key is available.
|
|
14455
14323
|
* @throws {@link SopsDecryptionError} On any other decryption failure.
|
|
14456
14324
|
*/
|
|
14457
|
-
async
|
|
14325
|
+
async decryptFile(filePath) {
|
|
14458
14326
|
await assertSops(this.runner, this.sopsCommand);
|
|
14459
14327
|
const fmt = formatFromPath(filePath);
|
|
14460
14328
|
const env = this.buildSopsEnv();
|
|
@@ -14490,170 +14358,9 @@ var SopsClient = class {
|
|
|
14490
14358
|
for (const [key, value] of Object.entries(parsed)) {
|
|
14491
14359
|
values[key] = String(value);
|
|
14492
14360
|
}
|
|
14493
|
-
const metadata =
|
|
14361
|
+
const metadata = this.parseMetadataFromFile(filePath);
|
|
14494
14362
|
return { values, metadata };
|
|
14495
14363
|
}
|
|
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
14364
|
/**
|
|
14658
14365
|
* Determine whether a decrypt failure is caused by a missing/mismatched key (vs. some other
|
|
14659
14366
|
* SOPS error) without relying on stderr message text.
|
|
@@ -14697,20 +14404,30 @@ var SopsClient = class {
|
|
|
14697
14404
|
filePath
|
|
14698
14405
|
);
|
|
14699
14406
|
}
|
|
14407
|
+
return this.parseMetadataFromContent(content, filePath);
|
|
14408
|
+
}
|
|
14409
|
+
/**
|
|
14410
|
+
* Parse SOPS metadata from a string (no IO). Used by both
|
|
14411
|
+
* `parseMetadataFromFile` (after reading from disk) and the blob-shaped
|
|
14412
|
+
* `getMetadataFromBlob` (which receives ciphertext directly from a
|
|
14413
|
+
* BlobStore). The `label` is woven into error messages so callers can
|
|
14414
|
+
* include the file path or cell ref the content came from.
|
|
14415
|
+
*/
|
|
14416
|
+
parseMetadataFromContent(content, label) {
|
|
14700
14417
|
let parsed;
|
|
14701
14418
|
try {
|
|
14702
14419
|
parsed = YAML8.parse(content);
|
|
14703
14420
|
} catch {
|
|
14704
14421
|
throw new SopsDecryptionError(
|
|
14705
|
-
|
|
14706
|
-
|
|
14422
|
+
`${label} is not valid YAML. Cannot extract SOPS metadata.`,
|
|
14423
|
+
label
|
|
14707
14424
|
);
|
|
14708
14425
|
}
|
|
14709
14426
|
const sops = parsed?.sops;
|
|
14710
14427
|
if (!sops) {
|
|
14711
14428
|
throw new SopsDecryptionError(
|
|
14712
|
-
|
|
14713
|
-
|
|
14429
|
+
`${label} does not contain SOPS metadata. It may not be encrypted.`,
|
|
14430
|
+
label
|
|
14714
14431
|
);
|
|
14715
14432
|
}
|
|
14716
14433
|
const backend = this.detectBackend(sops);
|
|
@@ -14773,7 +14490,7 @@ var SopsClient = class {
|
|
|
14773
14490
|
}
|
|
14774
14491
|
}
|
|
14775
14492
|
}
|
|
14776
|
-
buildEncryptArgs(
|
|
14493
|
+
buildEncryptArgs(manifest, environment) {
|
|
14777
14494
|
const args = [];
|
|
14778
14495
|
const config = environment ? resolveBackendConfig(manifest, environment) : {
|
|
14779
14496
|
backend: manifest.sops.default_backend,
|
|
@@ -14821,11 +14538,255 @@ var SopsClient = class {
|
|
|
14821
14538
|
}
|
|
14822
14539
|
return args;
|
|
14823
14540
|
}
|
|
14541
|
+
// ── Blob-shaped methods ─────────────────────────────────────────────────
|
|
14542
|
+
//
|
|
14543
|
+
// These mirror the file-path methods above but operate on opaque
|
|
14544
|
+
// ciphertext bytes via SOPS' stdin/stdout. They are the substrate-
|
|
14545
|
+
// agnostic primitives used by the `composeSecretSource` factory to
|
|
14546
|
+
// wrap any `BlobStore` (filesystem, postgres, etc.) into a full
|
|
14547
|
+
// `SecretSource`. Plaintext never leaves the SOPS subprocess.
|
|
14548
|
+
/**
|
|
14549
|
+
* {@link EncryptionBackend.decrypt} — decrypt SOPS-encrypted bytes (e.g.
|
|
14550
|
+
* read from a `StorageBackend`) and return plaintext values + metadata.
|
|
14551
|
+
* Plaintext lives only in memory.
|
|
14552
|
+
*/
|
|
14553
|
+
async decrypt(blob, ctx) {
|
|
14554
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14555
|
+
const env = this.buildSopsEnv();
|
|
14556
|
+
const pipe = await openInputPipe(blob);
|
|
14557
|
+
let result;
|
|
14558
|
+
try {
|
|
14559
|
+
result = await this.runner.run(
|
|
14560
|
+
this.sopsCommand,
|
|
14561
|
+
[
|
|
14562
|
+
"decrypt",
|
|
14563
|
+
...this.keyserviceArgs,
|
|
14564
|
+
"--input-type",
|
|
14565
|
+
ctx.format,
|
|
14566
|
+
"--output-type",
|
|
14567
|
+
ctx.format,
|
|
14568
|
+
pipe.inputArg
|
|
14569
|
+
],
|
|
14570
|
+
{
|
|
14571
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14572
|
+
...env ? { env } : {}
|
|
14573
|
+
}
|
|
14574
|
+
);
|
|
14575
|
+
} finally {
|
|
14576
|
+
pipe.cleanup();
|
|
14577
|
+
}
|
|
14578
|
+
if (result.exitCode !== 0) {
|
|
14579
|
+
const errorType = await this.classifyDecryptErrorFromContent(blob);
|
|
14580
|
+
if (errorType === "key-not-found") {
|
|
14581
|
+
throw new SopsKeyNotFoundError(`No decryption key found for cell. ${result.stderr.trim()}`);
|
|
14582
|
+
}
|
|
14583
|
+
throw new SopsDecryptionError(`Failed to decrypt cell: ${result.stderr.trim()}`);
|
|
14584
|
+
}
|
|
14585
|
+
let parsed;
|
|
14586
|
+
try {
|
|
14587
|
+
parsed = YAML8.parse(result.stdout) ?? {};
|
|
14588
|
+
} catch {
|
|
14589
|
+
throw new SopsDecryptionError("Decrypted content is not valid YAML.");
|
|
14590
|
+
}
|
|
14591
|
+
const values = {};
|
|
14592
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
14593
|
+
values[key] = String(value);
|
|
14594
|
+
}
|
|
14595
|
+
const metadata = this.parseMetadataFromContent(blob, "<cell>");
|
|
14596
|
+
return { values, metadata };
|
|
14597
|
+
}
|
|
14598
|
+
/**
|
|
14599
|
+
* {@link EncryptionBackend.encrypt} — encrypt plaintext values into a
|
|
14600
|
+
* SOPS-formatted ciphertext blob. Returns the bytes as a string;
|
|
14601
|
+
* caller (typically a `StorageBackend`) decides where to put them.
|
|
14602
|
+
* Plaintext is piped via stdin only.
|
|
14603
|
+
*/
|
|
14604
|
+
async encrypt(values, ctx) {
|
|
14605
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14606
|
+
const content = ctx.format === "json" ? JSON.stringify(values, null, 2) : YAML8.stringify(values);
|
|
14607
|
+
const args = this.buildEncryptArgs(ctx.manifest, ctx.environment);
|
|
14608
|
+
const env = this.buildSopsEnv();
|
|
14609
|
+
const pipe = await openInputPipe(content);
|
|
14610
|
+
let result;
|
|
14611
|
+
try {
|
|
14612
|
+
result = await this.runner.run(
|
|
14613
|
+
this.sopsCommand,
|
|
14614
|
+
[
|
|
14615
|
+
"--config",
|
|
14616
|
+
nullConfigPath(),
|
|
14617
|
+
"encrypt",
|
|
14618
|
+
...this.keyserviceArgs,
|
|
14619
|
+
...args,
|
|
14620
|
+
"--input-type",
|
|
14621
|
+
ctx.format,
|
|
14622
|
+
"--output-type",
|
|
14623
|
+
ctx.format,
|
|
14624
|
+
pipe.inputArg
|
|
14625
|
+
],
|
|
14626
|
+
{
|
|
14627
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14628
|
+
...env ? { env } : {}
|
|
14629
|
+
}
|
|
14630
|
+
);
|
|
14631
|
+
} finally {
|
|
14632
|
+
pipe.cleanup();
|
|
14633
|
+
}
|
|
14634
|
+
if (result.exitCode !== 0) {
|
|
14635
|
+
throw new SopsEncryptionError(`Failed to encrypt cell: ${result.stderr.trim()}`);
|
|
14636
|
+
}
|
|
14637
|
+
return result.stdout;
|
|
14638
|
+
}
|
|
14639
|
+
/**
|
|
14640
|
+
* {@link EncryptionBackend.rotate} — add or remove recipients from an
|
|
14641
|
+
* encrypted SOPS blob via stdin/stdout. Drops the in-place `-i` flag
|
|
14642
|
+
* the deleted file-path-shaped methods used, so SOPS writes the
|
|
14643
|
+
* rotated ciphertext to stdout instead of back to a file. Plaintext
|
|
14644
|
+
* stays inside the SOPS subprocess; no plaintext window exists in
|
|
14645
|
+
* this Node process.
|
|
14646
|
+
*
|
|
14647
|
+
* Single SOPS invocation can both add and remove recipients
|
|
14648
|
+
* simultaneously (matches the CLI flag set).
|
|
14649
|
+
*/
|
|
14650
|
+
async rotate(blob, opts, ctx) {
|
|
14651
|
+
await assertSops(this.runner, this.sopsCommand);
|
|
14652
|
+
const env = this.buildSopsEnv();
|
|
14653
|
+
const pipe = await openInputPipe(blob);
|
|
14654
|
+
const flagArgs = [];
|
|
14655
|
+
if (opts.addAge) flagArgs.push("--add-age", opts.addAge);
|
|
14656
|
+
if (opts.rmAge) flagArgs.push("--rm-age", opts.rmAge);
|
|
14657
|
+
if (opts.addKms) flagArgs.push("--add-kms", opts.addKms);
|
|
14658
|
+
if (opts.rmKms) flagArgs.push("--rm-kms", opts.rmKms);
|
|
14659
|
+
if (opts.addGcpKms) flagArgs.push("--add-gcp-kms", opts.addGcpKms);
|
|
14660
|
+
if (opts.rmGcpKms) flagArgs.push("--rm-gcp-kms", opts.rmGcpKms);
|
|
14661
|
+
if (opts.addAzureKv) flagArgs.push("--add-azure-kv", opts.addAzureKv);
|
|
14662
|
+
if (opts.rmAzureKv) flagArgs.push("--rm-azure-kv", opts.rmAzureKv);
|
|
14663
|
+
if (opts.addPgp) flagArgs.push("--add-pgp", opts.addPgp);
|
|
14664
|
+
if (opts.rmPgp) flagArgs.push("--rm-pgp", opts.rmPgp);
|
|
14665
|
+
let result;
|
|
14666
|
+
try {
|
|
14667
|
+
result = await this.runner.run(
|
|
14668
|
+
this.sopsCommand,
|
|
14669
|
+
[
|
|
14670
|
+
"--config",
|
|
14671
|
+
nullConfigPath(),
|
|
14672
|
+
"rotate",
|
|
14673
|
+
...this.keyserviceArgs,
|
|
14674
|
+
...flagArgs,
|
|
14675
|
+
"--input-type",
|
|
14676
|
+
ctx.format,
|
|
14677
|
+
"--output-type",
|
|
14678
|
+
ctx.format,
|
|
14679
|
+
pipe.inputArg
|
|
14680
|
+
],
|
|
14681
|
+
{
|
|
14682
|
+
...pipe.runnerStdin !== void 0 ? { stdin: pipe.runnerStdin } : {},
|
|
14683
|
+
...env ? { env } : {}
|
|
14684
|
+
}
|
|
14685
|
+
);
|
|
14686
|
+
} finally {
|
|
14687
|
+
pipe.cleanup();
|
|
14688
|
+
}
|
|
14689
|
+
if (result.exitCode !== 0) {
|
|
14690
|
+
throw new SopsEncryptionError(`Failed to rotate cell: ${result.stderr.trim()}`);
|
|
14691
|
+
}
|
|
14692
|
+
return result.stdout;
|
|
14693
|
+
}
|
|
14694
|
+
/**
|
|
14695
|
+
* {@link EncryptionBackend.getMetadata} — extract SOPS metadata from a
|
|
14696
|
+
* ciphertext blob without decrypting. Pure parser, no IO, no
|
|
14697
|
+
* subprocess.
|
|
14698
|
+
*/
|
|
14699
|
+
getMetadata(content) {
|
|
14700
|
+
return this.parseMetadataFromContent(content, "<cell>");
|
|
14701
|
+
}
|
|
14702
|
+
/**
|
|
14703
|
+
* {@link EncryptionBackend.validateEncryption} — whether `content` is a
|
|
14704
|
+
* valid SOPS-encrypted blob (parses + has the `sops:` metadata
|
|
14705
|
+
* block). Never throws.
|
|
14706
|
+
*/
|
|
14707
|
+
validateEncryption(content) {
|
|
14708
|
+
try {
|
|
14709
|
+
this.parseMetadataFromContent(content, "<cell>");
|
|
14710
|
+
return true;
|
|
14711
|
+
} catch {
|
|
14712
|
+
return false;
|
|
14713
|
+
}
|
|
14714
|
+
}
|
|
14715
|
+
/**
|
|
14716
|
+
* Blob-shaped variant of `classifyDecryptError`. Same logic as the
|
|
14717
|
+
* file-path version but reads metadata from the in-memory ciphertext
|
|
14718
|
+
* instead of disk.
|
|
14719
|
+
*/
|
|
14720
|
+
async classifyDecryptErrorFromContent(content) {
|
|
14721
|
+
let metadata;
|
|
14722
|
+
try {
|
|
14723
|
+
metadata = this.parseMetadataFromContent(content, "<cell>");
|
|
14724
|
+
} catch {
|
|
14725
|
+
return "other";
|
|
14726
|
+
}
|
|
14727
|
+
if (metadata.backend !== "age") return "other";
|
|
14728
|
+
if (!this.ageKey && !this.ageKeyFile) return "key-not-found";
|
|
14729
|
+
let keyContent;
|
|
14730
|
+
try {
|
|
14731
|
+
keyContent = this.ageKey ?? fs14.readFileSync(this.ageKeyFile, "utf-8");
|
|
14732
|
+
} catch {
|
|
14733
|
+
return "key-not-found";
|
|
14734
|
+
}
|
|
14735
|
+
const privateKeys = keyContent.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("AGE-SECRET-KEY-"));
|
|
14736
|
+
if (privateKeys.length === 0) return "key-not-found";
|
|
14737
|
+
try {
|
|
14738
|
+
const publicKeys = await Promise.all(privateKeys.map((k) => deriveAgePublicKey(k)));
|
|
14739
|
+
const recipients = new Set(metadata.recipients);
|
|
14740
|
+
return publicKeys.some((pk) => recipients.has(pk)) ? "other" : "key-not-found";
|
|
14741
|
+
} catch {
|
|
14742
|
+
return "other";
|
|
14743
|
+
}
|
|
14744
|
+
}
|
|
14824
14745
|
};
|
|
14825
14746
|
|
|
14747
|
+
// src/sops/linux-stdin-fifo.ts
|
|
14748
|
+
var os = __toESM(require("os"));
|
|
14749
|
+
var path11 = __toESM(require("path"));
|
|
14750
|
+
var import_child_process = require("child_process");
|
|
14751
|
+
function shouldUseLinuxStdinFifo() {
|
|
14752
|
+
return process.platform === "linux" && !process.env.JEST_WORKER_ID;
|
|
14753
|
+
}
|
|
14754
|
+
function wrapWithLinuxStdinFifo(runner) {
|
|
14755
|
+
if (!shouldUseLinuxStdinFifo()) return runner;
|
|
14756
|
+
return {
|
|
14757
|
+
run: (cmd, args, opts) => {
|
|
14758
|
+
const stdinIdx = args.indexOf("/dev/stdin");
|
|
14759
|
+
if (stdinIdx < 0 || opts?.stdin === void 0) {
|
|
14760
|
+
return runner.run(cmd, args, opts);
|
|
14761
|
+
}
|
|
14762
|
+
const fifoDir = (0, import_child_process.execFileSync)("mktemp", ["-d", path11.join(os.tmpdir(), "clef-fifo-XXXXXX")]).toString().trim();
|
|
14763
|
+
const fifoPath = path11.join(fifoDir, "input");
|
|
14764
|
+
(0, import_child_process.execFileSync)("mkfifo", [fifoPath]);
|
|
14765
|
+
const writer = (0, import_child_process.spawn)("dd", [`of=${fifoPath}`, "status=none"], {
|
|
14766
|
+
stdio: ["pipe", "ignore", "ignore"]
|
|
14767
|
+
});
|
|
14768
|
+
writer.stdin.write(opts.stdin);
|
|
14769
|
+
writer.stdin.end();
|
|
14770
|
+
const patchedArgs = [...args];
|
|
14771
|
+
patchedArgs[stdinIdx] = fifoPath;
|
|
14772
|
+
const { stdin: _stdin, ...restOpts } = opts;
|
|
14773
|
+
return runner.run(cmd, patchedArgs, restOpts).finally(() => {
|
|
14774
|
+
try {
|
|
14775
|
+
writer.kill();
|
|
14776
|
+
} catch {
|
|
14777
|
+
}
|
|
14778
|
+
try {
|
|
14779
|
+
(0, import_child_process.execFileSync)("rm", ["-rf", fifoDir]);
|
|
14780
|
+
} catch {
|
|
14781
|
+
}
|
|
14782
|
+
});
|
|
14783
|
+
}
|
|
14784
|
+
};
|
|
14785
|
+
}
|
|
14786
|
+
|
|
14826
14787
|
// src/hsm/bundled.ts
|
|
14827
14788
|
var fs15 = __toESM(require("fs"));
|
|
14828
|
-
var
|
|
14789
|
+
var path12 = __toESM(require("path"));
|
|
14829
14790
|
function tryBundledKeyservice() {
|
|
14830
14791
|
const platform = process.platform;
|
|
14831
14792
|
const arch = process.arch;
|
|
@@ -14837,8 +14798,8 @@ function tryBundledKeyservice() {
|
|
|
14837
14798
|
const binName = "clef-keyservice";
|
|
14838
14799
|
try {
|
|
14839
14800
|
const packageMain = require.resolve(`${packageName}/package.json`);
|
|
14840
|
-
const packageDir =
|
|
14841
|
-
const binPath =
|
|
14801
|
+
const packageDir = path12.dirname(packageMain);
|
|
14802
|
+
const binPath = path12.join(packageDir, "bin", binName);
|
|
14842
14803
|
return fs15.existsSync(binPath) ? binPath : null;
|
|
14843
14804
|
} catch {
|
|
14844
14805
|
return null;
|
|
@@ -14847,9 +14808,9 @@ function tryBundledKeyservice() {
|
|
|
14847
14808
|
|
|
14848
14809
|
// src/hsm/resolver.ts
|
|
14849
14810
|
var fs16 = __toESM(require("fs"));
|
|
14850
|
-
var
|
|
14811
|
+
var path13 = __toESM(require("path"));
|
|
14851
14812
|
function validateKeyservicePath(candidate) {
|
|
14852
|
-
if (!
|
|
14813
|
+
if (!path13.isAbsolute(candidate)) {
|
|
14853
14814
|
throw new Error(`CLEF_KEYSERVICE_PATH must be an absolute path, got '${candidate}'.`);
|
|
14854
14815
|
}
|
|
14855
14816
|
const segments = candidate.split(/[/\\]/);
|
|
@@ -14884,7 +14845,7 @@ function resetKeyserviceResolution() {
|
|
|
14884
14845
|
}
|
|
14885
14846
|
|
|
14886
14847
|
// src/hsm/keyservice.ts
|
|
14887
|
-
var
|
|
14848
|
+
var import_child_process2 = require("child_process");
|
|
14888
14849
|
var readline = __toESM(require("readline"));
|
|
14889
14850
|
var PORT_REGEX = /^PORT=(\d+)$/;
|
|
14890
14851
|
var STARTUP_TIMEOUT_MS = 5e3;
|
|
@@ -14902,7 +14863,7 @@ async function spawnKeyservice(options) {
|
|
|
14902
14863
|
...options.pin ? { CLEF_PKCS11_PIN: options.pin } : {},
|
|
14903
14864
|
...options.pinFile ? { CLEF_PKCS11_PIN_FILE: options.pinFile } : {}
|
|
14904
14865
|
};
|
|
14905
|
-
const child = (0,
|
|
14866
|
+
const child = (0, import_child_process2.spawn)(options.binaryPath, args, {
|
|
14906
14867
|
stdio: ["ignore", "pipe", "pipe"],
|
|
14907
14868
|
env: childEnv
|
|
14908
14869
|
});
|
|
@@ -14978,16 +14939,16 @@ function killGracefully(child) {
|
|
|
14978
14939
|
}
|
|
14979
14940
|
|
|
14980
14941
|
// src/lint/runner.ts
|
|
14981
|
-
var
|
|
14942
|
+
var path14 = __toESM(require("path"));
|
|
14982
14943
|
var LintRunner = class {
|
|
14983
|
-
constructor(matrixManager, schemaValidator,
|
|
14944
|
+
constructor(matrixManager, schemaValidator, source) {
|
|
14984
14945
|
this.matrixManager = matrixManager;
|
|
14985
14946
|
this.schemaValidator = schemaValidator;
|
|
14986
|
-
this.
|
|
14947
|
+
this.source = source;
|
|
14987
14948
|
}
|
|
14988
14949
|
matrixManager;
|
|
14989
14950
|
schemaValidator;
|
|
14990
|
-
|
|
14951
|
+
source;
|
|
14991
14952
|
/**
|
|
14992
14953
|
* Lint the entire matrix: check missing files, schema errors, SOPS integrity,
|
|
14993
14954
|
* single-recipient warnings, and cross-environment key drift.
|
|
@@ -15014,8 +14975,9 @@ var LintRunner = class {
|
|
|
15014
14975
|
fileCount = existingCells.length;
|
|
15015
14976
|
const namespaceKeys = {};
|
|
15016
14977
|
for (const cell of existingCells) {
|
|
14978
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15017
14979
|
try {
|
|
15018
|
-
const isValid = await this.
|
|
14980
|
+
const isValid = await this.source.validateEncryption(ref);
|
|
15019
14981
|
if (!isValid) {
|
|
15020
14982
|
issues.push({
|
|
15021
14983
|
severity: "error",
|
|
@@ -15036,7 +14998,7 @@ var LintRunner = class {
|
|
|
15036
14998
|
continue;
|
|
15037
14999
|
}
|
|
15038
15000
|
try {
|
|
15039
|
-
const decrypted = await this.
|
|
15001
|
+
const decrypted = await this.source.readCell(ref);
|
|
15040
15002
|
const keys = Object.keys(decrypted.values);
|
|
15041
15003
|
if (!namespaceKeys[cell.namespace]) {
|
|
15042
15004
|
namespaceKeys[cell.namespace] = {};
|
|
@@ -15081,7 +15043,7 @@ var LintRunner = class {
|
|
|
15081
15043
|
}
|
|
15082
15044
|
const ns = manifest.namespaces.find((n) => n.name === cell.namespace);
|
|
15083
15045
|
if (ns?.schema) {
|
|
15084
|
-
const schemaPath =
|
|
15046
|
+
const schemaPath = path14.join(repoRoot, ns.schema);
|
|
15085
15047
|
try {
|
|
15086
15048
|
const schema = this.schemaValidator.loadSchema(schemaPath);
|
|
15087
15049
|
const result = this.schemaValidator.validate(decrypted.values, schema);
|
|
@@ -15124,7 +15086,8 @@ var LintRunner = class {
|
|
|
15124
15086
|
}
|
|
15125
15087
|
}
|
|
15126
15088
|
try {
|
|
15127
|
-
const
|
|
15089
|
+
const meta = await this.source.getPendingMetadata(ref);
|
|
15090
|
+
const pendingKeys = meta.pending.map((p) => p.key);
|
|
15128
15091
|
pendingCount += pendingKeys.length;
|
|
15129
15092
|
for (const pendingKey of pendingKeys) {
|
|
15130
15093
|
issues.push({
|
|
@@ -15177,7 +15140,6 @@ var LintRunner = class {
|
|
|
15177
15140
|
const siIssues = await this.lintServiceIdentities(
|
|
15178
15141
|
manifest.service_identities,
|
|
15179
15142
|
manifest,
|
|
15180
|
-
repoRoot,
|
|
15181
15143
|
existingCells
|
|
15182
15144
|
);
|
|
15183
15145
|
issues.push(...siIssues);
|
|
@@ -15187,18 +15149,27 @@ var LintRunner = class {
|
|
|
15187
15149
|
return { issues, fileCount: fileCount + missingCells.length, pendingCount };
|
|
15188
15150
|
}
|
|
15189
15151
|
/**
|
|
15190
|
-
* Cross-reference
|
|
15152
|
+
* Cross-reference cell metadata against the cipher's plaintext key
|
|
15191
15153
|
* names for each existing cell. Reports orphan rotation records and
|
|
15192
|
-
* dual-state (pending + rotation) inconsistencies. Uses
|
|
15193
|
-
*
|
|
15154
|
+
* dual-state (pending + rotation) inconsistencies. Uses the source's
|
|
15155
|
+
* `listKeys` (no decryption).
|
|
15194
15156
|
*/
|
|
15195
15157
|
async lintMetadataConsistency(cells) {
|
|
15196
15158
|
const issues = [];
|
|
15197
15159
|
for (const cell of cells) {
|
|
15198
|
-
const
|
|
15199
|
-
|
|
15200
|
-
|
|
15201
|
-
|
|
15160
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15161
|
+
let cipherKeys;
|
|
15162
|
+
try {
|
|
15163
|
+
cipherKeys = new Set(await this.source.listKeys(ref));
|
|
15164
|
+
} catch {
|
|
15165
|
+
continue;
|
|
15166
|
+
}
|
|
15167
|
+
let metadata;
|
|
15168
|
+
try {
|
|
15169
|
+
metadata = await this.source.getPendingMetadata(ref);
|
|
15170
|
+
} catch {
|
|
15171
|
+
continue;
|
|
15172
|
+
}
|
|
15202
15173
|
for (const record of metadata.rotations) {
|
|
15203
15174
|
if (!cipherKeys.has(record.key)) {
|
|
15204
15175
|
issues.push({
|
|
@@ -15229,7 +15200,7 @@ var LintRunner = class {
|
|
|
15229
15200
|
/**
|
|
15230
15201
|
* Lint service identity configurations for drift issues.
|
|
15231
15202
|
*/
|
|
15232
|
-
async lintServiceIdentities(identities, manifest,
|
|
15203
|
+
async lintServiceIdentities(identities, manifest, existingCells) {
|
|
15233
15204
|
const issues = [];
|
|
15234
15205
|
const declaredEnvNames = new Set(manifest.environments.map((e) => e.name));
|
|
15235
15206
|
const declaredNsNames = new Set(manifest.namespaces.map((ns) => ns.name));
|
|
@@ -15270,9 +15241,10 @@ var LintRunner = class {
|
|
|
15270
15241
|
const envConfig = si.environments[cell.environment];
|
|
15271
15242
|
if (!envConfig) continue;
|
|
15272
15243
|
if (!envConfig.recipient) continue;
|
|
15244
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15273
15245
|
if (si.namespaces.includes(cell.namespace)) {
|
|
15274
15246
|
try {
|
|
15275
|
-
const metadata = await this.
|
|
15247
|
+
const metadata = await this.source.getCellMetadata(ref);
|
|
15276
15248
|
if (!metadata.recipients.includes(envConfig.recipient)) {
|
|
15277
15249
|
issues.push({
|
|
15278
15250
|
severity: "warning",
|
|
@@ -15286,7 +15258,7 @@ var LintRunner = class {
|
|
|
15286
15258
|
}
|
|
15287
15259
|
} else {
|
|
15288
15260
|
try {
|
|
15289
|
-
const metadata = await this.
|
|
15261
|
+
const metadata = await this.source.getCellMetadata(ref);
|
|
15290
15262
|
if (metadata.recipients.includes(envConfig.recipient)) {
|
|
15291
15263
|
issues.push({
|
|
15292
15264
|
severity: "warning",
|
|
@@ -15312,7 +15284,10 @@ var LintRunner = class {
|
|
|
15312
15284
|
async fix(manifest, repoRoot) {
|
|
15313
15285
|
const missingCells = this.matrixManager.detectMissingCells(manifest, repoRoot);
|
|
15314
15286
|
for (const cell of missingCells) {
|
|
15315
|
-
await this.
|
|
15287
|
+
await this.source.scaffoldCell(
|
|
15288
|
+
{ namespace: cell.namespace, environment: cell.environment },
|
|
15289
|
+
manifest
|
|
15290
|
+
);
|
|
15316
15291
|
}
|
|
15317
15292
|
return this.run(manifest, repoRoot);
|
|
15318
15293
|
}
|
|
@@ -15367,15 +15342,12 @@ Use 'clef exec' to inject secrets directly into a process, or 'clef export --for
|
|
|
15367
15342
|
}
|
|
15368
15343
|
};
|
|
15369
15344
|
|
|
15370
|
-
// src/import/index.ts
|
|
15371
|
-
var path17 = __toESM(require("path"));
|
|
15372
|
-
|
|
15373
15345
|
// src/import/parsers.ts
|
|
15374
|
-
var
|
|
15346
|
+
var path15 = __toESM(require("path"));
|
|
15375
15347
|
var YAML9 = __toESM(require("yaml"));
|
|
15376
15348
|
function detectFormat(filePath, content) {
|
|
15377
|
-
const base =
|
|
15378
|
-
const ext =
|
|
15349
|
+
const base = path15.basename(filePath);
|
|
15350
|
+
const ext = path15.extname(filePath).toLowerCase();
|
|
15379
15351
|
if (base === ".env" || base.startsWith(".env.")) {
|
|
15380
15352
|
return "dotenv";
|
|
15381
15353
|
}
|
|
@@ -15525,11 +15497,11 @@ function parse9(content, format, filePath) {
|
|
|
15525
15497
|
|
|
15526
15498
|
// src/import/index.ts
|
|
15527
15499
|
var ImportRunner = class {
|
|
15528
|
-
constructor(
|
|
15529
|
-
this.
|
|
15500
|
+
constructor(source, tx) {
|
|
15501
|
+
this.source = source;
|
|
15530
15502
|
this.tx = tx;
|
|
15531
15503
|
}
|
|
15532
|
-
|
|
15504
|
+
source;
|
|
15533
15505
|
tx;
|
|
15534
15506
|
/**
|
|
15535
15507
|
* Parse a source file and import its key/value pairs into a target `namespace/environment` cell.
|
|
@@ -15543,10 +15515,8 @@ var ImportRunner = class {
|
|
|
15543
15515
|
*/
|
|
15544
15516
|
async import(target, sourcePath, content, manifest, repoRoot, options) {
|
|
15545
15517
|
const [ns, env] = target.split("/");
|
|
15546
|
-
const
|
|
15547
|
-
|
|
15548
|
-
manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
|
|
15549
|
-
);
|
|
15518
|
+
const ref = { namespace: ns, environment: env };
|
|
15519
|
+
const relCellPath = manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env);
|
|
15550
15520
|
const parsed = parse9(content, options.format ?? "auto", sourcePath ?? "");
|
|
15551
15521
|
let candidates = Object.entries(parsed.pairs);
|
|
15552
15522
|
if (options.prefix) {
|
|
@@ -15564,7 +15534,7 @@ var ImportRunner = class {
|
|
|
15564
15534
|
if (options.dryRun) {
|
|
15565
15535
|
let existingKeys;
|
|
15566
15536
|
try {
|
|
15567
|
-
const decrypted2 = await this.
|
|
15537
|
+
const decrypted2 = await this.source.readCell(ref);
|
|
15568
15538
|
existingKeys = new Set(Object.keys(decrypted2.values));
|
|
15569
15539
|
} catch {
|
|
15570
15540
|
existingKeys = /* @__PURE__ */ new Set();
|
|
@@ -15578,7 +15548,7 @@ var ImportRunner = class {
|
|
|
15578
15548
|
}
|
|
15579
15549
|
return { imported, skipped, failed, warnings, dryRun: true };
|
|
15580
15550
|
}
|
|
15581
|
-
const decrypted = await this.
|
|
15551
|
+
const decrypted = await this.source.readCell(ref);
|
|
15582
15552
|
const newValues = { ...decrypted.values };
|
|
15583
15553
|
const rotatedKeys = [];
|
|
15584
15554
|
for (const [key, value] of candidates) {
|
|
@@ -15595,7 +15565,6 @@ var ImportRunner = class {
|
|
|
15595
15565
|
if (imported.length === 0) {
|
|
15596
15566
|
return { imported, skipped, failed, warnings, dryRun: false };
|
|
15597
15567
|
}
|
|
15598
|
-
const relCellPath = path17.relative(repoRoot, filePath);
|
|
15599
15568
|
const relMetaPath = relCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
15600
15569
|
await this.tx.run(repoRoot, {
|
|
15601
15570
|
description: `clef import ${target}: ${imported.length} key(s)`,
|
|
@@ -15603,9 +15572,9 @@ var ImportRunner = class {
|
|
|
15603
15572
|
// callback are staged and rolled back atomically with the ciphertext.
|
|
15604
15573
|
paths: [relCellPath, relMetaPath],
|
|
15605
15574
|
mutate: async () => {
|
|
15606
|
-
await this.
|
|
15575
|
+
await this.source.writeCell(ref, newValues);
|
|
15607
15576
|
if (options.rotatedBy && rotatedKeys.length > 0) {
|
|
15608
|
-
await recordRotation(
|
|
15577
|
+
await this.source.recordRotation(ref, rotatedKeys, options.rotatedBy);
|
|
15609
15578
|
}
|
|
15610
15579
|
}
|
|
15611
15580
|
});
|
|
@@ -15614,7 +15583,7 @@ var ImportRunner = class {
|
|
|
15614
15583
|
};
|
|
15615
15584
|
|
|
15616
15585
|
// src/recipients/index.ts
|
|
15617
|
-
var
|
|
15586
|
+
var path16 = __toESM(require("path"));
|
|
15618
15587
|
function parseRecipientEntry(entry) {
|
|
15619
15588
|
if (typeof entry === "string") {
|
|
15620
15589
|
return { key: entry };
|
|
@@ -15682,12 +15651,12 @@ function ensureEnvironmentRecipientsArray(doc, envName) {
|
|
|
15682
15651
|
return env.recipients;
|
|
15683
15652
|
}
|
|
15684
15653
|
var RecipientManager = class {
|
|
15685
|
-
constructor(
|
|
15686
|
-
this.
|
|
15654
|
+
constructor(source, matrixManager, tx) {
|
|
15655
|
+
this.source = source;
|
|
15687
15656
|
this.matrixManager = matrixManager;
|
|
15688
15657
|
this.tx = tx;
|
|
15689
15658
|
}
|
|
15690
|
-
|
|
15659
|
+
source;
|
|
15691
15660
|
matrixManager;
|
|
15692
15661
|
tx;
|
|
15693
15662
|
/**
|
|
@@ -15742,7 +15711,7 @@ var RecipientManager = class {
|
|
|
15742
15711
|
const reEncryptedFiles = [];
|
|
15743
15712
|
await this.tx.run(repoRoot, {
|
|
15744
15713
|
description: environment ? `clef recipients add ${keyPreview(normalizedKey)} -e ${environment}` : `clef recipients add ${keyPreview(normalizedKey)}`,
|
|
15745
|
-
paths: [...cells.map((c) =>
|
|
15714
|
+
paths: [...cells.map((c) => path16.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
|
|
15746
15715
|
mutate: async () => {
|
|
15747
15716
|
const doc = readManifestYaml(repoRoot);
|
|
15748
15717
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
@@ -15753,7 +15722,8 @@ var RecipientManager = class {
|
|
|
15753
15722
|
}
|
|
15754
15723
|
writeManifestYaml(repoRoot, doc);
|
|
15755
15724
|
for (const cell of cells) {
|
|
15756
|
-
|
|
15725
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15726
|
+
await this.source.rotate(ref, { addAge: normalizedKey });
|
|
15757
15727
|
reEncryptedFiles.push(cell.filePath);
|
|
15758
15728
|
}
|
|
15759
15729
|
}
|
|
@@ -15801,7 +15771,7 @@ var RecipientManager = class {
|
|
|
15801
15771
|
const reEncryptedFiles = [];
|
|
15802
15772
|
await this.tx.run(repoRoot, {
|
|
15803
15773
|
description: environment ? `clef recipients remove ${keyPreview(trimmedKey)} -e ${environment}` : `clef recipients remove ${keyPreview(trimmedKey)}`,
|
|
15804
|
-
paths: [...cells.map((c) =>
|
|
15774
|
+
paths: [...cells.map((c) => path16.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
|
|
15805
15775
|
mutate: async () => {
|
|
15806
15776
|
const doc = readManifestYaml(repoRoot);
|
|
15807
15777
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
@@ -15809,7 +15779,8 @@ var RecipientManager = class {
|
|
|
15809
15779
|
recipients.splice(idx, 1);
|
|
15810
15780
|
writeManifestYaml(repoRoot, doc);
|
|
15811
15781
|
for (const cell of cells) {
|
|
15812
|
-
|
|
15782
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
15783
|
+
await this.source.rotate(ref, { rmAge: trimmedKey });
|
|
15813
15784
|
reEncryptedFiles.push(cell.filePath);
|
|
15814
15785
|
}
|
|
15815
15786
|
}
|
|
@@ -15831,12 +15802,12 @@ var RecipientManager = class {
|
|
|
15831
15802
|
|
|
15832
15803
|
// src/recipients/requests.ts
|
|
15833
15804
|
var fs17 = __toESM(require("fs"));
|
|
15834
|
-
var
|
|
15805
|
+
var path17 = __toESM(require("path"));
|
|
15835
15806
|
var YAML10 = __toESM(require("yaml"));
|
|
15836
15807
|
var REQUESTS_FILENAME = ".clef-requests.yaml";
|
|
15837
15808
|
var HEADER_COMMENT2 = "# Pending recipient access requests. Approve with: clef recipients approve <label>\n";
|
|
15838
15809
|
function requestsFilePath(repoRoot) {
|
|
15839
|
-
return
|
|
15810
|
+
return path17.join(repoRoot, REQUESTS_FILENAME);
|
|
15840
15811
|
}
|
|
15841
15812
|
function loadRequests(repoRoot) {
|
|
15842
15813
|
const filePath = requestsFilePath(repoRoot);
|
|
@@ -15911,7 +15882,7 @@ function findInList(requests, identifier) {
|
|
|
15911
15882
|
}
|
|
15912
15883
|
|
|
15913
15884
|
// src/drift/detector.ts
|
|
15914
|
-
var
|
|
15885
|
+
var path18 = __toESM(require("path"));
|
|
15915
15886
|
var DriftDetector = class {
|
|
15916
15887
|
parser = new ManifestParser();
|
|
15917
15888
|
matrix = new MatrixManager();
|
|
@@ -15924,8 +15895,8 @@ var DriftDetector = class {
|
|
|
15924
15895
|
* @returns Drift result with any issues found.
|
|
15925
15896
|
*/
|
|
15926
15897
|
detect(localRoot, remoteRoot, namespaceFilter) {
|
|
15927
|
-
const localManifest = this.parser.parse(
|
|
15928
|
-
const remoteManifest = this.parser.parse(
|
|
15898
|
+
const localManifest = this.parser.parse(path18.join(localRoot, CLEF_MANIFEST_FILENAME));
|
|
15899
|
+
const remoteManifest = this.parser.parse(path18.join(remoteRoot, CLEF_MANIFEST_FILENAME));
|
|
15929
15900
|
const localCells = this.matrix.resolveMatrix(localManifest, localRoot);
|
|
15930
15901
|
const remoteCells = this.matrix.resolveMatrix(remoteManifest, remoteRoot);
|
|
15931
15902
|
const localEnvNames = localManifest.environments.map((e) => e.name);
|
|
@@ -15989,7 +15960,7 @@ var DriftDetector = class {
|
|
|
15989
15960
|
};
|
|
15990
15961
|
|
|
15991
15962
|
// src/report/generator.ts
|
|
15992
|
-
var
|
|
15963
|
+
var path19 = __toESM(require("path"));
|
|
15993
15964
|
|
|
15994
15965
|
// src/report/sanitizer.ts
|
|
15995
15966
|
var ReportSanitizer = class {
|
|
@@ -16126,14 +16097,14 @@ var ReportSanitizer = class {
|
|
|
16126
16097
|
|
|
16127
16098
|
// src/report/generator.ts
|
|
16128
16099
|
var ReportGenerator = class {
|
|
16129
|
-
constructor(runner,
|
|
16100
|
+
constructor(runner, source, matrixManager, schemaValidator) {
|
|
16130
16101
|
this.runner = runner;
|
|
16131
|
-
this.
|
|
16102
|
+
this.source = source;
|
|
16132
16103
|
this.matrixManager = matrixManager;
|
|
16133
16104
|
this.schemaValidator = schemaValidator;
|
|
16134
16105
|
}
|
|
16135
16106
|
runner;
|
|
16136
|
-
|
|
16107
|
+
source;
|
|
16137
16108
|
matrixManager;
|
|
16138
16109
|
schemaValidator;
|
|
16139
16110
|
/**
|
|
@@ -16149,7 +16120,7 @@ var ReportGenerator = class {
|
|
|
16149
16120
|
let manifest = null;
|
|
16150
16121
|
try {
|
|
16151
16122
|
const parser = new ManifestParser();
|
|
16152
|
-
manifest = parser.parse(
|
|
16123
|
+
manifest = parser.parse(path19.join(repoRoot, "clef.yaml"));
|
|
16153
16124
|
} catch {
|
|
16154
16125
|
const emptyManifest = {
|
|
16155
16126
|
manifestVersion: 0,
|
|
@@ -16270,16 +16241,17 @@ var ReportGenerator = class {
|
|
|
16270
16241
|
metadata: null
|
|
16271
16242
|
};
|
|
16272
16243
|
}
|
|
16244
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
16273
16245
|
const keyCount = this.readKeyCount(cell.filePath);
|
|
16274
16246
|
let pendingCount = 0;
|
|
16275
16247
|
try {
|
|
16276
|
-
const
|
|
16277
|
-
pendingCount = pending.length;
|
|
16248
|
+
const meta = await this.source.getPendingMetadata(ref);
|
|
16249
|
+
pendingCount = meta.pending.length;
|
|
16278
16250
|
} catch {
|
|
16279
16251
|
}
|
|
16280
16252
|
let metadata = null;
|
|
16281
16253
|
try {
|
|
16282
|
-
const sopsMetadata = await this.
|
|
16254
|
+
const sopsMetadata = await this.source.getCellMetadata(ref);
|
|
16283
16255
|
metadata = {
|
|
16284
16256
|
backend: sopsMetadata.backend,
|
|
16285
16257
|
recipients: sopsMetadata.recipients,
|
|
@@ -16302,7 +16274,7 @@ var ReportGenerator = class {
|
|
|
16302
16274
|
}
|
|
16303
16275
|
async buildPolicy(manifest, repoRoot) {
|
|
16304
16276
|
try {
|
|
16305
|
-
const lintRunner = new LintRunner(this.matrixManager, this.schemaValidator, this.
|
|
16277
|
+
const lintRunner = new LintRunner(this.matrixManager, this.schemaValidator, this.source);
|
|
16306
16278
|
const lintResult = await lintRunner.run(manifest, repoRoot);
|
|
16307
16279
|
return new ReportSanitizer().sanitize(lintResult.issues);
|
|
16308
16280
|
} catch {
|
|
@@ -16619,9 +16591,9 @@ var SopsMergeDriver = class {
|
|
|
16619
16591
|
*/
|
|
16620
16592
|
async mergeFiles(basePath, oursPath, theirsPath) {
|
|
16621
16593
|
const [baseDecrypted, oursDecrypted, theirsDecrypted] = await Promise.all([
|
|
16622
|
-
this.sopsClient.
|
|
16623
|
-
this.sopsClient.
|
|
16624
|
-
this.sopsClient.
|
|
16594
|
+
this.sopsClient.decryptFile(basePath),
|
|
16595
|
+
this.sopsClient.decryptFile(oursPath),
|
|
16596
|
+
this.sopsClient.decryptFile(theirsPath)
|
|
16625
16597
|
]);
|
|
16626
16598
|
return this.merge(baseDecrypted.values, oursDecrypted.values, theirsDecrypted.values);
|
|
16627
16599
|
}
|
|
@@ -16738,22 +16710,26 @@ function mergeMetadataFiles(_basePath, oursPath, theirsPath) {
|
|
|
16738
16710
|
}
|
|
16739
16711
|
|
|
16740
16712
|
// src/service-identity/manager.ts
|
|
16741
|
-
var
|
|
16713
|
+
var path20 = __toESM(require("path"));
|
|
16742
16714
|
var ServiceIdentityManager = class {
|
|
16743
|
-
constructor(
|
|
16744
|
-
this.
|
|
16715
|
+
constructor(source, matrixManager, tx) {
|
|
16716
|
+
this.source = source;
|
|
16745
16717
|
this.matrixManager = matrixManager;
|
|
16746
16718
|
this.tx = tx;
|
|
16747
16719
|
}
|
|
16748
|
-
|
|
16720
|
+
source;
|
|
16749
16721
|
matrixManager;
|
|
16750
16722
|
tx;
|
|
16723
|
+
/** Helper: cell → ref for the source seam. */
|
|
16724
|
+
ref(cell) {
|
|
16725
|
+
return { namespace: cell.namespace, environment: cell.environment };
|
|
16726
|
+
}
|
|
16751
16727
|
/**
|
|
16752
16728
|
* Compute repo-relative paths for a set of cells plus the manifest. Used
|
|
16753
16729
|
* to seed TransactionManager.run's `paths` argument.
|
|
16754
16730
|
*/
|
|
16755
16731
|
txPaths(repoRoot, cells) {
|
|
16756
|
-
return [...cells.map((c) =>
|
|
16732
|
+
return [...cells.map((c) => path20.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME];
|
|
16757
16733
|
}
|
|
16758
16734
|
/**
|
|
16759
16735
|
* Create a new service identity with per-environment age key pairs or KMS envelope config.
|
|
@@ -16845,7 +16821,7 @@ var ServiceIdentityManager = class {
|
|
|
16845
16821
|
if (!envConfig?.recipient) continue;
|
|
16846
16822
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16847
16823
|
try {
|
|
16848
|
-
await this.
|
|
16824
|
+
await this.source.rotate(this.ref(cell), { rmAge: envConfig.recipient });
|
|
16849
16825
|
} catch {
|
|
16850
16826
|
}
|
|
16851
16827
|
}
|
|
@@ -16895,7 +16871,7 @@ var ServiceIdentityManager = class {
|
|
|
16895
16871
|
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
16896
16872
|
for (const cell of scopedCells) {
|
|
16897
16873
|
try {
|
|
16898
|
-
await this.
|
|
16874
|
+
await this.source.rotate(this.ref(cell), { rmAge: oldConfig.recipient });
|
|
16899
16875
|
} catch {
|
|
16900
16876
|
}
|
|
16901
16877
|
}
|
|
@@ -16922,7 +16898,7 @@ var ServiceIdentityManager = class {
|
|
|
16922
16898
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16923
16899
|
if (!envConfig.recipient) continue;
|
|
16924
16900
|
try {
|
|
16925
|
-
await this.
|
|
16901
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
16926
16902
|
} catch (err) {
|
|
16927
16903
|
const message = err instanceof Error ? err.message : String(err);
|
|
16928
16904
|
if (!message.includes("already")) {
|
|
@@ -16970,7 +16946,7 @@ var ServiceIdentityManager = class {
|
|
|
16970
16946
|
if (isKmsEnvelope(envConfig)) continue;
|
|
16971
16947
|
if (!envConfig.recipient) continue;
|
|
16972
16948
|
try {
|
|
16973
|
-
await this.
|
|
16949
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
16974
16950
|
affectedFiles.push(cell.filePath);
|
|
16975
16951
|
} catch (err) {
|
|
16976
16952
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -17031,7 +17007,7 @@ var ServiceIdentityManager = class {
|
|
|
17031
17007
|
if (isKmsEnvelope(envConfig)) continue;
|
|
17032
17008
|
if (!envConfig.recipient) continue;
|
|
17033
17009
|
try {
|
|
17034
|
-
await this.
|
|
17010
|
+
await this.source.rotate(this.ref(cell), { rmAge: envConfig.recipient });
|
|
17035
17011
|
affectedFiles.push(cell.filePath);
|
|
17036
17012
|
} catch {
|
|
17037
17013
|
}
|
|
@@ -17100,7 +17076,7 @@ var ServiceIdentityManager = class {
|
|
|
17100
17076
|
if (!identity.pack_only && !isKmsEnvelope(envConfig) && envConfig.recipient) {
|
|
17101
17077
|
for (const cell of cells) {
|
|
17102
17078
|
try {
|
|
17103
|
-
await this.
|
|
17079
|
+
await this.source.rotate(this.ref(cell), { addAge: envConfig.recipient });
|
|
17104
17080
|
} catch (err) {
|
|
17105
17081
|
const message = err instanceof Error ? err.message : String(err);
|
|
17106
17082
|
if (!message.includes("already")) {
|
|
@@ -17177,10 +17153,10 @@ var ServiceIdentityManager = class {
|
|
|
17177
17153
|
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
17178
17154
|
for (const cell of scopedCells) {
|
|
17179
17155
|
try {
|
|
17180
|
-
await this.
|
|
17156
|
+
await this.source.rotate(this.ref(cell), { rmAge: oldRecipient });
|
|
17181
17157
|
} catch {
|
|
17182
17158
|
}
|
|
17183
|
-
await this.
|
|
17159
|
+
await this.source.rotate(this.ref(cell), { addAge: newPublicKey });
|
|
17184
17160
|
}
|
|
17185
17161
|
}
|
|
17186
17162
|
}
|
|
@@ -17239,7 +17215,7 @@ var ServiceIdentityManager = class {
|
|
|
17239
17215
|
if (!envConfig.recipient) continue;
|
|
17240
17216
|
if (si.namespaces.includes(cell.namespace)) {
|
|
17241
17217
|
try {
|
|
17242
|
-
const metadata = await this.
|
|
17218
|
+
const metadata = await this.source.getCellMetadata(this.ref(cell));
|
|
17243
17219
|
if (!metadata.recipients.includes(envConfig.recipient)) {
|
|
17244
17220
|
issues.push({
|
|
17245
17221
|
identity: si.name,
|
|
@@ -17254,7 +17230,7 @@ var ServiceIdentityManager = class {
|
|
|
17254
17230
|
}
|
|
17255
17231
|
} else {
|
|
17256
17232
|
try {
|
|
17257
|
-
const metadata = await this.
|
|
17233
|
+
const metadata = await this.source.getCellMetadata(this.ref(cell));
|
|
17258
17234
|
if (metadata.recipients.includes(envConfig.recipient)) {
|
|
17259
17235
|
issues.push({
|
|
17260
17236
|
identity: si.name,
|
|
@@ -17276,15 +17252,15 @@ var ServiceIdentityManager = class {
|
|
|
17276
17252
|
|
|
17277
17253
|
// src/structure/manager.ts
|
|
17278
17254
|
var fs19 = __toESM(require("fs"));
|
|
17279
|
-
var
|
|
17255
|
+
var path21 = __toESM(require("path"));
|
|
17280
17256
|
var StructureManager = class {
|
|
17281
|
-
constructor(matrixManager,
|
|
17257
|
+
constructor(matrixManager, buildSource, tx) {
|
|
17282
17258
|
this.matrixManager = matrixManager;
|
|
17283
|
-
this.
|
|
17259
|
+
this.buildSource = buildSource;
|
|
17284
17260
|
this.tx = tx;
|
|
17285
17261
|
}
|
|
17286
17262
|
matrixManager;
|
|
17287
|
-
|
|
17263
|
+
buildSource;
|
|
17288
17264
|
tx;
|
|
17289
17265
|
// ── add ──────────────────────────────────────────────────────────────────
|
|
17290
17266
|
/**
|
|
@@ -17300,7 +17276,7 @@ var StructureManager = class {
|
|
|
17300
17276
|
this.assertValidIdentifier("namespace", name);
|
|
17301
17277
|
const newCellPaths = manifest.environments.map((env) => ({
|
|
17302
17278
|
environment: env.name,
|
|
17303
|
-
filePath:
|
|
17279
|
+
filePath: path21.join(
|
|
17304
17280
|
repoRoot,
|
|
17305
17281
|
manifest.file_pattern.replace("{namespace}", name).replace("{environment}", env.name)
|
|
17306
17282
|
)
|
|
@@ -17308,7 +17284,7 @@ var StructureManager = class {
|
|
|
17308
17284
|
for (const cell of newCellPaths) {
|
|
17309
17285
|
if (fs19.existsSync(cell.filePath)) {
|
|
17310
17286
|
throw new Error(
|
|
17311
|
-
`Cannot add namespace '${name}': file '${
|
|
17287
|
+
`Cannot add namespace '${name}': file '${path21.relative(repoRoot, cell.filePath)}' already exists.`
|
|
17312
17288
|
);
|
|
17313
17289
|
}
|
|
17314
17290
|
}
|
|
@@ -17327,21 +17303,14 @@ var StructureManager = class {
|
|
|
17327
17303
|
await this.tx.run(repoRoot, {
|
|
17328
17304
|
description: `clef namespace add ${name}`,
|
|
17329
17305
|
paths: [
|
|
17330
|
-
...newCellPaths.map((c) =>
|
|
17306
|
+
...newCellPaths.map((c) => path21.relative(repoRoot, c.filePath)),
|
|
17331
17307
|
CLEF_MANIFEST_FILENAME
|
|
17332
17308
|
],
|
|
17333
17309
|
mutate: async () => {
|
|
17310
|
+
const source = this.buildSource(updatedManifest);
|
|
17334
17311
|
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
|
-
);
|
|
17312
|
+
const ref = { namespace: name, environment: cell.environment };
|
|
17313
|
+
await source.scaffoldCell(ref, updatedManifest);
|
|
17345
17314
|
}
|
|
17346
17315
|
const doc = readManifestYaml(repoRoot);
|
|
17347
17316
|
const namespaces = doc.namespaces;
|
|
@@ -17372,7 +17341,7 @@ var StructureManager = class {
|
|
|
17372
17341
|
this.assertValidIdentifier("environment", name);
|
|
17373
17342
|
const newCellPaths = manifest.namespaces.map((ns) => ({
|
|
17374
17343
|
namespace: ns.name,
|
|
17375
|
-
filePath:
|
|
17344
|
+
filePath: path21.join(
|
|
17376
17345
|
repoRoot,
|
|
17377
17346
|
manifest.file_pattern.replace("{namespace}", ns.name).replace("{environment}", name)
|
|
17378
17347
|
)
|
|
@@ -17380,7 +17349,7 @@ var StructureManager = class {
|
|
|
17380
17349
|
for (const cell of newCellPaths) {
|
|
17381
17350
|
if (fs19.existsSync(cell.filePath)) {
|
|
17382
17351
|
throw new Error(
|
|
17383
|
-
`Cannot add environment '${name}': file '${
|
|
17352
|
+
`Cannot add environment '${name}': file '${path21.relative(repoRoot, cell.filePath)}' already exists.`
|
|
17384
17353
|
);
|
|
17385
17354
|
}
|
|
17386
17355
|
}
|
|
@@ -17399,21 +17368,14 @@ var StructureManager = class {
|
|
|
17399
17368
|
await this.tx.run(repoRoot, {
|
|
17400
17369
|
description: `clef env add ${name}`,
|
|
17401
17370
|
paths: [
|
|
17402
|
-
...newCellPaths.map((c) =>
|
|
17371
|
+
...newCellPaths.map((c) => path21.relative(repoRoot, c.filePath)),
|
|
17403
17372
|
CLEF_MANIFEST_FILENAME
|
|
17404
17373
|
],
|
|
17405
17374
|
mutate: async () => {
|
|
17375
|
+
const source = this.buildSource(updatedManifest);
|
|
17406
17376
|
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
|
-
);
|
|
17377
|
+
const ref = { namespace: cell.namespace, environment: name };
|
|
17378
|
+
await source.scaffoldCell(ref, updatedManifest);
|
|
17417
17379
|
}
|
|
17418
17380
|
const doc = readManifestYaml(repoRoot);
|
|
17419
17381
|
const environments = doc.environments;
|
|
@@ -17556,7 +17518,7 @@ var StructureManager = class {
|
|
|
17556
17518
|
for (const pair of renamePairs) {
|
|
17557
17519
|
if (fs19.existsSync(pair.to)) {
|
|
17558
17520
|
throw new Error(
|
|
17559
|
-
`Rename target '${
|
|
17521
|
+
`Rename target '${path21.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
17560
17522
|
);
|
|
17561
17523
|
}
|
|
17562
17524
|
}
|
|
@@ -17599,7 +17561,7 @@ var StructureManager = class {
|
|
|
17599
17561
|
for (const pair of renamePairs) {
|
|
17600
17562
|
if (fs19.existsSync(pair.to)) {
|
|
17601
17563
|
throw new Error(
|
|
17602
|
-
`Rename target '${
|
|
17564
|
+
`Rename target '${path21.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
|
|
17603
17565
|
);
|
|
17604
17566
|
}
|
|
17605
17567
|
}
|
|
@@ -17649,7 +17611,7 @@ var StructureManager = class {
|
|
|
17649
17611
|
swapAxisInCellPath(repoRoot, manifest, cell, axis, newName) {
|
|
17650
17612
|
const ns = axis === "namespace" ? newName : cell.namespace;
|
|
17651
17613
|
const env = axis === "environment" ? newName : cell.environment;
|
|
17652
|
-
return
|
|
17614
|
+
return path21.join(
|
|
17653
17615
|
repoRoot,
|
|
17654
17616
|
manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
|
|
17655
17617
|
);
|
|
@@ -17661,8 +17623,8 @@ var StructureManager = class {
|
|
|
17661
17623
|
txPaths(repoRoot, renamePairs) {
|
|
17662
17624
|
const paths = /* @__PURE__ */ new Set();
|
|
17663
17625
|
for (const pair of renamePairs) {
|
|
17664
|
-
paths.add(
|
|
17665
|
-
paths.add(
|
|
17626
|
+
paths.add(path21.relative(repoRoot, pair.from));
|
|
17627
|
+
paths.add(path21.relative(repoRoot, pair.to));
|
|
17666
17628
|
}
|
|
17667
17629
|
paths.add(CLEF_MANIFEST_FILENAME);
|
|
17668
17630
|
return [...paths];
|
|
@@ -17673,7 +17635,7 @@ var StructureManager = class {
|
|
|
17673
17635
|
*/
|
|
17674
17636
|
applyRenames(pairs) {
|
|
17675
17637
|
for (const pair of pairs) {
|
|
17676
|
-
const targetDir =
|
|
17638
|
+
const targetDir = path21.dirname(pair.to);
|
|
17677
17639
|
if (!fs19.existsSync(targetDir)) {
|
|
17678
17640
|
fs19.mkdirSync(targetDir, { recursive: true });
|
|
17679
17641
|
}
|
|
@@ -17688,10 +17650,10 @@ var StructureManager = class {
|
|
|
17688
17650
|
deletePaths(repoRoot, cells) {
|
|
17689
17651
|
const paths = /* @__PURE__ */ new Set();
|
|
17690
17652
|
for (const cell of cells) {
|
|
17691
|
-
paths.add(
|
|
17653
|
+
paths.add(path21.relative(repoRoot, cell.filePath));
|
|
17692
17654
|
const meta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
|
|
17693
17655
|
if (fs19.existsSync(meta)) {
|
|
17694
|
-
paths.add(
|
|
17656
|
+
paths.add(path21.relative(repoRoot, meta));
|
|
17695
17657
|
}
|
|
17696
17658
|
}
|
|
17697
17659
|
paths.add(CLEF_MANIFEST_FILENAME);
|
|
@@ -17806,7 +17768,7 @@ function renameKeyPreservingOrder(obj, oldKey, newKey) {
|
|
|
17806
17768
|
}
|
|
17807
17769
|
|
|
17808
17770
|
// src/artifact/resolve.ts
|
|
17809
|
-
async function resolveIdentitySecrets(identityName, environment, manifest, repoRoot,
|
|
17771
|
+
async function resolveIdentitySecrets(identityName, environment, manifest, repoRoot, source, matrixManager) {
|
|
17810
17772
|
const identity = manifest.service_identities?.find((si) => si.name === identityName);
|
|
17811
17773
|
if (!identity) {
|
|
17812
17774
|
throw new Error(`Service identity '${identityName}' not found in manifest.`);
|
|
@@ -17822,7 +17784,10 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
|
|
|
17822
17784
|
(c) => c.exists && identity.namespaces.includes(c.namespace) && c.environment === environment
|
|
17823
17785
|
);
|
|
17824
17786
|
for (const cell of cells) {
|
|
17825
|
-
const decrypted = await
|
|
17787
|
+
const decrypted = await source.readCell({
|
|
17788
|
+
namespace: cell.namespace,
|
|
17789
|
+
environment: cell.environment
|
|
17790
|
+
});
|
|
17826
17791
|
const bucket = allValues[cell.namespace] ??= {};
|
|
17827
17792
|
for (const [key, value] of Object.entries(decrypted.values)) {
|
|
17828
17793
|
if (key in bucket && bucket[key] !== value) {
|
|
@@ -17846,14 +17811,14 @@ var crypto5 = __toESM(require("crypto"));
|
|
|
17846
17811
|
|
|
17847
17812
|
// src/artifact/output.ts
|
|
17848
17813
|
var fs20 = __toESM(require("fs"));
|
|
17849
|
-
var
|
|
17814
|
+
var path22 = __toESM(require("path"));
|
|
17850
17815
|
var FilePackOutput = class {
|
|
17851
17816
|
constructor(outputPath) {
|
|
17852
17817
|
this.outputPath = outputPath;
|
|
17853
17818
|
}
|
|
17854
17819
|
outputPath;
|
|
17855
17820
|
async write(_artifact, json) {
|
|
17856
|
-
const outputDir =
|
|
17821
|
+
const outputDir = path22.dirname(this.outputPath);
|
|
17857
17822
|
if (!fs20.existsSync(outputDir)) {
|
|
17858
17823
|
fs20.mkdirSync(outputDir, { recursive: true });
|
|
17859
17824
|
}
|
|
@@ -17900,17 +17865,6 @@ function buildSigningPayload(artifact) {
|
|
|
17900
17865
|
];
|
|
17901
17866
|
return Buffer.from(fields.join("\n"), "utf-8");
|
|
17902
17867
|
}
|
|
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
17868
|
function signEd25519(payload, privateKeyBase64) {
|
|
17915
17869
|
const keyObj = crypto3.createPrivateKey({
|
|
17916
17870
|
key: Buffer.from(privateKeyBase64, "base64"),
|
|
@@ -17946,17 +17900,6 @@ function verifySignature(payload, signatureBase64, publicKeyBase64) {
|
|
|
17946
17900
|
}
|
|
17947
17901
|
throw new Error(`Unsupported key type for signature verification: ${keyType}`);
|
|
17948
17902
|
}
|
|
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
17903
|
|
|
17961
17904
|
// src/artifact/hash.ts
|
|
17962
17905
|
var crypto4 = __toESM(require("crypto"));
|
|
@@ -17966,12 +17909,12 @@ function computeCiphertextHash(ciphertext) {
|
|
|
17966
17909
|
|
|
17967
17910
|
// src/artifact/packer.ts
|
|
17968
17911
|
var ArtifactPacker = class {
|
|
17969
|
-
constructor(
|
|
17970
|
-
this.
|
|
17912
|
+
constructor(source, matrixManager, kms) {
|
|
17913
|
+
this.source = source;
|
|
17971
17914
|
this.matrixManager = matrixManager;
|
|
17972
17915
|
this.kms = kms;
|
|
17973
17916
|
}
|
|
17974
|
-
|
|
17917
|
+
source;
|
|
17975
17918
|
matrixManager;
|
|
17976
17919
|
kms;
|
|
17977
17920
|
/**
|
|
@@ -17989,7 +17932,7 @@ var ArtifactPacker = class {
|
|
|
17989
17932
|
config.environment,
|
|
17990
17933
|
manifest,
|
|
17991
17934
|
repoRoot,
|
|
17992
|
-
this.
|
|
17935
|
+
this.source,
|
|
17993
17936
|
this.matrixManager
|
|
17994
17937
|
);
|
|
17995
17938
|
const plaintext = JSON.stringify(resolved.values);
|
|
@@ -18374,11 +18317,7 @@ var JsonEnvelopeBackend = class {
|
|
|
18374
18317
|
}
|
|
18375
18318
|
async pack(req) {
|
|
18376
18319
|
const opts = req.backendOptions;
|
|
18377
|
-
const packer = new ArtifactPacker(
|
|
18378
|
-
req.services.encryption,
|
|
18379
|
-
new MatrixManager(),
|
|
18380
|
-
req.services.kms
|
|
18381
|
-
);
|
|
18320
|
+
const packer = new ArtifactPacker(req.services.source, new MatrixManager(), req.services.kms);
|
|
18382
18321
|
const output = opts.output ?? (opts.outputPath ? new FilePackOutput(opts.outputPath) : void 0);
|
|
18383
18322
|
const result = await packer.pack(
|
|
18384
18323
|
{
|
|
@@ -18407,7 +18346,7 @@ var JsonEnvelopeBackend = class {
|
|
|
18407
18346
|
var VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
|
|
18408
18347
|
|
|
18409
18348
|
// src/migration/backend.ts
|
|
18410
|
-
var
|
|
18349
|
+
var path23 = __toESM(require("path"));
|
|
18411
18350
|
var YAML12 = __toESM(require("yaml"));
|
|
18412
18351
|
var BACKEND_KEY_FIELDS = {
|
|
18413
18352
|
age: void 0,
|
|
@@ -18435,23 +18374,24 @@ function metadataMatchesTarget(meta, target) {
|
|
|
18435
18374
|
}
|
|
18436
18375
|
var BackendMigrator = class {
|
|
18437
18376
|
/**
|
|
18438
|
-
* @param
|
|
18377
|
+
* @param buildSource - Factory that builds a `SecretSource` bound to a
|
|
18378
|
+
* given manifest. Called twice during a real migration: once with the
|
|
18379
|
+
* pre-migration manifest (for classification + decrypt) and once with
|
|
18380
|
+
* the post-mutation manifest (for re-encrypt + verify). The factory
|
|
18381
|
+
* pattern is required because the encryption layer of a composed
|
|
18382
|
+
* source is bound to a manifest at construction.
|
|
18439
18383
|
* @param matrixManager - Matrix resolver.
|
|
18440
18384
|
* @param tx - Transaction manager that wraps the migration in a single git commit
|
|
18441
18385
|
* 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
18386
|
*/
|
|
18445
|
-
constructor(
|
|
18387
|
+
constructor(buildSource, matrixManager, tx) {
|
|
18388
|
+
this.buildSource = buildSource;
|
|
18446
18389
|
this.matrixManager = matrixManager;
|
|
18447
18390
|
this.tx = tx;
|
|
18448
|
-
this.decryptBackend = encryption;
|
|
18449
|
-
this.encryptBackend = targetEncryption ?? encryption;
|
|
18450
18391
|
}
|
|
18392
|
+
buildSource;
|
|
18451
18393
|
matrixManager;
|
|
18452
18394
|
tx;
|
|
18453
|
-
decryptBackend;
|
|
18454
|
-
encryptBackend;
|
|
18455
18395
|
async migrate(manifest, repoRoot, options, onProgress) {
|
|
18456
18396
|
const { target, environment, dryRun, skipVerify } = options;
|
|
18457
18397
|
if (environment) {
|
|
@@ -18471,10 +18411,12 @@ var BackendMigrator = class {
|
|
|
18471
18411
|
warnings: ["No encrypted files found to migrate."]
|
|
18472
18412
|
};
|
|
18473
18413
|
}
|
|
18414
|
+
const sourceBefore = this.buildSource(manifest);
|
|
18474
18415
|
const toMigrate = [];
|
|
18475
18416
|
const skippedFiles = [];
|
|
18476
18417
|
for (const cell of targetCells) {
|
|
18477
|
-
const
|
|
18418
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18419
|
+
const meta = await sourceBefore.getCellMetadata(ref);
|
|
18478
18420
|
if (metadataMatchesTarget(meta, target)) {
|
|
18479
18421
|
skippedFiles.push(cell.filePath);
|
|
18480
18422
|
onProgress?.({
|
|
@@ -18525,11 +18467,12 @@ var BackendMigrator = class {
|
|
|
18525
18467
|
const migratedFiles = [];
|
|
18526
18468
|
let migrationFailed = false;
|
|
18527
18469
|
let migrationError;
|
|
18470
|
+
let sourceAfter;
|
|
18528
18471
|
try {
|
|
18529
18472
|
await this.tx.run(repoRoot, {
|
|
18530
18473
|
description: environment ? `clef migrate-backend ${target.backend}: ${environment}` : `clef migrate-backend ${target.backend}`,
|
|
18531
18474
|
paths: [
|
|
18532
|
-
...toMigrate.map((c) =>
|
|
18475
|
+
...toMigrate.map((c) => path23.relative(repoRoot, c.filePath)),
|
|
18533
18476
|
CLEF_MANIFEST_FILENAME
|
|
18534
18477
|
],
|
|
18535
18478
|
mutate: async () => {
|
|
@@ -18537,19 +18480,16 @@ var BackendMigrator = class {
|
|
|
18537
18480
|
this.updateManifestDoc(doc, target, environment);
|
|
18538
18481
|
writeManifestYaml(repoRoot, doc);
|
|
18539
18482
|
const updatedManifest = YAML12.parse(YAML12.stringify(doc));
|
|
18483
|
+
sourceAfter = this.buildSource(updatedManifest);
|
|
18540
18484
|
for (const cell of toMigrate) {
|
|
18541
18485
|
onProgress?.({
|
|
18542
18486
|
type: "migrate",
|
|
18543
18487
|
file: cell.filePath,
|
|
18544
18488
|
message: `Migrating ${cell.namespace}/${cell.environment}...`
|
|
18545
18489
|
});
|
|
18546
|
-
const
|
|
18547
|
-
await
|
|
18548
|
-
|
|
18549
|
-
decrypted.values,
|
|
18550
|
-
updatedManifest,
|
|
18551
|
-
cell.environment
|
|
18552
|
-
);
|
|
18490
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18491
|
+
const decrypted = await sourceBefore.readCell(ref);
|
|
18492
|
+
await sourceAfter.writeCell(ref, decrypted.values);
|
|
18553
18493
|
migratedFiles.push(cell.filePath);
|
|
18554
18494
|
}
|
|
18555
18495
|
}
|
|
@@ -18579,7 +18519,7 @@ var BackendMigrator = class {
|
|
|
18579
18519
|
}
|
|
18580
18520
|
const verifiedFiles = [];
|
|
18581
18521
|
const warnings = [];
|
|
18582
|
-
if (!skipVerify) {
|
|
18522
|
+
if (!skipVerify && sourceAfter) {
|
|
18583
18523
|
for (const cell of toMigrate) {
|
|
18584
18524
|
try {
|
|
18585
18525
|
onProgress?.({
|
|
@@ -18587,7 +18527,8 @@ var BackendMigrator = class {
|
|
|
18587
18527
|
file: cell.filePath,
|
|
18588
18528
|
message: `Verifying ${cell.namespace}/${cell.environment}...`
|
|
18589
18529
|
});
|
|
18590
|
-
|
|
18530
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18531
|
+
await sourceAfter.readCell(ref);
|
|
18591
18532
|
verifiedFiles.push(cell.filePath);
|
|
18592
18533
|
} catch (err) {
|
|
18593
18534
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -18632,16 +18573,16 @@ var BackendMigrator = class {
|
|
|
18632
18573
|
};
|
|
18633
18574
|
|
|
18634
18575
|
// src/reset/manager.ts
|
|
18635
|
-
var
|
|
18576
|
+
var path24 = __toESM(require("path"));
|
|
18636
18577
|
var ResetManager = class {
|
|
18637
|
-
constructor(matrixManager,
|
|
18578
|
+
constructor(matrixManager, buildSource, schemaValidator, tx) {
|
|
18638
18579
|
this.matrixManager = matrixManager;
|
|
18639
|
-
this.
|
|
18580
|
+
this.buildSource = buildSource;
|
|
18640
18581
|
this.schemaValidator = schemaValidator;
|
|
18641
18582
|
this.tx = tx;
|
|
18642
18583
|
}
|
|
18643
18584
|
matrixManager;
|
|
18644
|
-
|
|
18585
|
+
buildSource;
|
|
18645
18586
|
schemaValidator;
|
|
18646
18587
|
tx;
|
|
18647
18588
|
async reset(opts, manifest, repoRoot) {
|
|
@@ -18661,11 +18602,11 @@ var ResetManager = class {
|
|
|
18661
18602
|
txPaths.push(CLEF_MANIFEST_FILENAME);
|
|
18662
18603
|
}
|
|
18663
18604
|
for (const cell of targetCells) {
|
|
18664
|
-
txPaths.push(
|
|
18605
|
+
txPaths.push(path24.relative(repoRoot, cell.filePath));
|
|
18665
18606
|
const cellKeys = keyPlan.get(cell.namespace) ?? [];
|
|
18666
18607
|
if (cellKeys.length > 0) {
|
|
18667
18608
|
txPaths.push(
|
|
18668
|
-
|
|
18609
|
+
path24.relative(repoRoot, cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"))
|
|
18669
18610
|
);
|
|
18670
18611
|
}
|
|
18671
18612
|
}
|
|
@@ -18682,17 +18623,14 @@ var ResetManager = class {
|
|
|
18682
18623
|
writeManifestYaml(repoRoot, doc);
|
|
18683
18624
|
effectiveManifest = withBackendOverride(manifest, affectedEnvs, opts.backend, opts.key);
|
|
18684
18625
|
}
|
|
18626
|
+
const source = this.buildSource(effectiveManifest);
|
|
18685
18627
|
for (const cell of targetCells) {
|
|
18686
18628
|
const keys = keyPlan.get(cell.namespace) ?? [];
|
|
18687
18629
|
const placeholders = this.buildPlaceholders(keys);
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
placeholders,
|
|
18691
|
-
effectiveManifest,
|
|
18692
|
-
cell.environment
|
|
18693
|
-
);
|
|
18630
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18631
|
+
await source.writeCell(ref, placeholders);
|
|
18694
18632
|
if (keys.length > 0) {
|
|
18695
|
-
await
|
|
18633
|
+
await source.markPending(ref, keys, "clef reset");
|
|
18696
18634
|
pendingKeysByCell[cell.filePath] = keys;
|
|
18697
18635
|
}
|
|
18698
18636
|
scaffoldedCells.push(cell.filePath);
|
|
@@ -18753,7 +18691,7 @@ var ResetManager = class {
|
|
|
18753
18691
|
for (const namespace of namespaces) {
|
|
18754
18692
|
const nsDef = manifest.namespaces.find((n) => n.name === namespace);
|
|
18755
18693
|
if (nsDef?.schema) {
|
|
18756
|
-
const schema = this.schemaValidator.loadSchema(
|
|
18694
|
+
const schema = this.schemaValidator.loadSchema(path24.join(repoRoot, nsDef.schema));
|
|
18757
18695
|
plan.set(namespace, Object.keys(schema.keys));
|
|
18758
18696
|
continue;
|
|
18759
18697
|
}
|
|
@@ -18832,15 +18770,15 @@ function withBackendOverride(manifest, envNames, backend, key) {
|
|
|
18832
18770
|
}
|
|
18833
18771
|
|
|
18834
18772
|
// src/sync/manager.ts
|
|
18835
|
-
var
|
|
18773
|
+
var path25 = __toESM(require("path"));
|
|
18836
18774
|
var SyncManager = class {
|
|
18837
|
-
constructor(matrixManager,
|
|
18775
|
+
constructor(matrixManager, source, tx) {
|
|
18838
18776
|
this.matrixManager = matrixManager;
|
|
18839
|
-
this.
|
|
18777
|
+
this.source = source;
|
|
18840
18778
|
this.tx = tx;
|
|
18841
18779
|
}
|
|
18842
18780
|
matrixManager;
|
|
18843
|
-
|
|
18781
|
+
source;
|
|
18844
18782
|
tx;
|
|
18845
18783
|
/**
|
|
18846
18784
|
* Compute what sync would do without mutating anything.
|
|
@@ -18857,8 +18795,13 @@ var SyncManager = class {
|
|
|
18857
18795
|
const targetCells = opts.namespace ? existingCells.filter((c) => c.namespace === opts.namespace) : existingCells;
|
|
18858
18796
|
const keysByNsEnv = {};
|
|
18859
18797
|
for (const cell of targetCells) {
|
|
18860
|
-
const
|
|
18861
|
-
|
|
18798
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18799
|
+
let keys;
|
|
18800
|
+
try {
|
|
18801
|
+
keys = await this.source.listKeys(ref);
|
|
18802
|
+
} catch {
|
|
18803
|
+
continue;
|
|
18804
|
+
}
|
|
18862
18805
|
if (!keysByNsEnv[cell.namespace]) keysByNsEnv[cell.namespace] = {};
|
|
18863
18806
|
keysByNsEnv[cell.namespace][cell.environment] = new Set(keys);
|
|
18864
18807
|
}
|
|
@@ -18904,7 +18847,7 @@ var SyncManager = class {
|
|
|
18904
18847
|
}
|
|
18905
18848
|
const txPaths = [];
|
|
18906
18849
|
for (const cell of syncPlan.cells) {
|
|
18907
|
-
const rel =
|
|
18850
|
+
const rel = path25.relative(repoRoot, cell.filePath);
|
|
18908
18851
|
txPaths.push(rel);
|
|
18909
18852
|
txPaths.push(rel.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"));
|
|
18910
18853
|
}
|
|
@@ -18917,17 +18860,13 @@ var SyncManager = class {
|
|
|
18917
18860
|
paths: txPaths,
|
|
18918
18861
|
mutate: async () => {
|
|
18919
18862
|
for (const cell of syncPlan.cells) {
|
|
18920
|
-
const
|
|
18863
|
+
const ref = { namespace: cell.namespace, environment: cell.environment };
|
|
18864
|
+
const decrypted = await this.source.readCell(ref);
|
|
18921
18865
|
for (const key of cell.missingKeys) {
|
|
18922
18866
|
decrypted.values[key] = generateRandomValue();
|
|
18923
18867
|
}
|
|
18924
|
-
await this.
|
|
18925
|
-
|
|
18926
|
-
decrypted.values,
|
|
18927
|
-
manifest,
|
|
18928
|
-
cell.environment
|
|
18929
|
-
);
|
|
18930
|
-
await markPendingWithRetry(cell.filePath, cell.missingKeys, "clef sync");
|
|
18868
|
+
await this.source.writeCell(ref, decrypted.values);
|
|
18869
|
+
await this.source.markPending(ref, cell.missingKeys, "clef sync");
|
|
18931
18870
|
const cellLabel = `${cell.namespace}/${cell.environment}`;
|
|
18932
18871
|
modifiedCells.push(cellLabel);
|
|
18933
18872
|
scaffoldedKeys[cellLabel] = cell.missingKeys;
|
|
@@ -19187,13 +19126,272 @@ var ComplianceGenerator = class {
|
|
|
19187
19126
|
};
|
|
19188
19127
|
|
|
19189
19128
|
// src/compliance/run.ts
|
|
19190
|
-
var
|
|
19129
|
+
var path27 = __toESM(require("path"));
|
|
19130
|
+
|
|
19131
|
+
// src/source/compose.ts
|
|
19132
|
+
var YAML14 = __toESM(require("yaml"));
|
|
19133
|
+
|
|
19134
|
+
// src/source/default-bulk.ts
|
|
19135
|
+
function defaultBulk(source) {
|
|
19136
|
+
return {
|
|
19137
|
+
async bulkSet(namespace, key, valuesByEnv, _manifest) {
|
|
19138
|
+
for (const [environment, value] of Object.entries(valuesByEnv)) {
|
|
19139
|
+
const cell = { namespace, environment };
|
|
19140
|
+
const existing = await source.cellExists(cell) ? (await source.readCell(cell)).values : {};
|
|
19141
|
+
await source.writeCell(cell, { ...existing, [key]: value });
|
|
19142
|
+
}
|
|
19143
|
+
},
|
|
19144
|
+
async bulkDelete(namespace, key, manifest) {
|
|
19145
|
+
for (const env of manifest.environments) {
|
|
19146
|
+
const cell = { namespace, environment: env.name };
|
|
19147
|
+
if (!await source.cellExists(cell)) continue;
|
|
19148
|
+
const data = await source.readCell(cell);
|
|
19149
|
+
if (!(key in data.values)) continue;
|
|
19150
|
+
const next = { ...data.values };
|
|
19151
|
+
delete next[key];
|
|
19152
|
+
await source.writeCell(cell, next);
|
|
19153
|
+
}
|
|
19154
|
+
},
|
|
19155
|
+
async copyValue(key, from, to, _manifest) {
|
|
19156
|
+
const src = await source.readCell(from);
|
|
19157
|
+
if (!(key in src.values)) {
|
|
19158
|
+
throw new Error(
|
|
19159
|
+
`Cannot copy: key '${key}' not present in ${from.namespace}/${from.environment}`
|
|
19160
|
+
);
|
|
19161
|
+
}
|
|
19162
|
+
const dst = await source.cellExists(to) ? (await source.readCell(to)).values : {};
|
|
19163
|
+
await source.writeCell(to, { ...dst, [key]: src.values[key] });
|
|
19164
|
+
}
|
|
19165
|
+
};
|
|
19166
|
+
}
|
|
19167
|
+
|
|
19168
|
+
// src/source/compose.ts
|
|
19169
|
+
function composeSecretSource(storage, encryption, manifest) {
|
|
19170
|
+
return new ComposedSecretSource(storage, encryption, manifest);
|
|
19171
|
+
}
|
|
19172
|
+
var ComposedSecretSource = class {
|
|
19173
|
+
constructor(storage, encryption, manifest) {
|
|
19174
|
+
this.storage = storage;
|
|
19175
|
+
this.encryption = encryption;
|
|
19176
|
+
this.manifest = manifest;
|
|
19177
|
+
this.id = `${storage.id}+${encryption.id}`;
|
|
19178
|
+
this.description = `${storage.description} / ${encryption.description}`;
|
|
19179
|
+
}
|
|
19180
|
+
storage;
|
|
19181
|
+
encryption;
|
|
19182
|
+
manifest;
|
|
19183
|
+
id;
|
|
19184
|
+
description;
|
|
19185
|
+
context(cell) {
|
|
19186
|
+
return {
|
|
19187
|
+
manifest: this.manifest,
|
|
19188
|
+
environment: cell.environment,
|
|
19189
|
+
format: this.storage.blobFormat(cell)
|
|
19190
|
+
};
|
|
19191
|
+
}
|
|
19192
|
+
// ── Core SecretSource ──────────────────────────────────────────────────
|
|
19193
|
+
async readCell(cell) {
|
|
19194
|
+
const blob = await this.storage.readBlob(cell);
|
|
19195
|
+
return this.encryption.decrypt(blob, this.context(cell));
|
|
19196
|
+
}
|
|
19197
|
+
async writeCell(cell, values) {
|
|
19198
|
+
const blob = await this.encryption.encrypt(values, this.context(cell));
|
|
19199
|
+
await this.storage.writeBlob(cell, blob);
|
|
19200
|
+
}
|
|
19201
|
+
async deleteCell(cell) {
|
|
19202
|
+
await this.storage.deleteBlob(cell);
|
|
19203
|
+
}
|
|
19204
|
+
async cellExists(cell) {
|
|
19205
|
+
return this.storage.blobExists(cell);
|
|
19206
|
+
}
|
|
19207
|
+
/**
|
|
19208
|
+
* List cell keys WITHOUT decrypting. SOPS files store key names in
|
|
19209
|
+
* plaintext at the top level of the YAML/JSON document — we read the
|
|
19210
|
+
* blob and return everything except the `sops:` metadata block.
|
|
19211
|
+
*
|
|
19212
|
+
* NOTE: this is currently SOPS-shaped. A future non-SOPS
|
|
19213
|
+
* `EncryptionBackend` whose ciphertext doesn't expose key names in
|
|
19214
|
+
* the clear would need its own listing strategy — likely a
|
|
19215
|
+
* `listKeys(blob)` method on `EncryptionBackend`. Deferred until a
|
|
19216
|
+
* second backend exists.
|
|
19217
|
+
*/
|
|
19218
|
+
async listKeys(cell) {
|
|
19219
|
+
if (!await this.storage.blobExists(cell)) return [];
|
|
19220
|
+
const blob = await this.storage.readBlob(cell);
|
|
19221
|
+
const parsed = YAML14.parse(blob);
|
|
19222
|
+
if (!parsed || typeof parsed !== "object") return [];
|
|
19223
|
+
return Object.keys(parsed).filter((k) => k !== "sops");
|
|
19224
|
+
}
|
|
19225
|
+
async getCellMetadata(cell) {
|
|
19226
|
+
const blob = await this.storage.readBlob(cell);
|
|
19227
|
+
return this.encryption.getMetadata(blob);
|
|
19228
|
+
}
|
|
19229
|
+
async scaffoldCell(cell, manifest) {
|
|
19230
|
+
if (await this.storage.blobExists(cell)) return;
|
|
19231
|
+
const blob = await this.encryption.encrypt(
|
|
19232
|
+
{},
|
|
19233
|
+
{
|
|
19234
|
+
manifest,
|
|
19235
|
+
environment: cell.environment,
|
|
19236
|
+
format: this.storage.blobFormat(cell)
|
|
19237
|
+
}
|
|
19238
|
+
);
|
|
19239
|
+
await this.storage.writeBlob(cell, blob);
|
|
19240
|
+
}
|
|
19241
|
+
// ── Pending / rotation metadata ────────────────────────────────────────
|
|
19242
|
+
async getPendingMetadata(cell) {
|
|
19243
|
+
return this.storage.readPendingMetadata(cell);
|
|
19244
|
+
}
|
|
19245
|
+
async markPending(cell, keys, setBy) {
|
|
19246
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19247
|
+
const now = /* @__PURE__ */ new Date();
|
|
19248
|
+
for (const key of keys) {
|
|
19249
|
+
if (!meta.pending.find((p) => p.key === key)) {
|
|
19250
|
+
meta.pending.push({ key, since: now, setBy });
|
|
19251
|
+
}
|
|
19252
|
+
}
|
|
19253
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19254
|
+
}
|
|
19255
|
+
async markResolved(cell, keys) {
|
|
19256
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19257
|
+
meta.pending = meta.pending.filter((p) => !keys.includes(p.key));
|
|
19258
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19259
|
+
}
|
|
19260
|
+
async recordRotation(cell, keys, rotatedBy) {
|
|
19261
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19262
|
+
const now = /* @__PURE__ */ new Date();
|
|
19263
|
+
for (const key of keys) {
|
|
19264
|
+
const existing = meta.rotations.find((r) => r.key === key);
|
|
19265
|
+
if (existing) {
|
|
19266
|
+
existing.lastRotatedAt = now;
|
|
19267
|
+
existing.rotatedBy = rotatedBy;
|
|
19268
|
+
existing.rotationCount += 1;
|
|
19269
|
+
} else {
|
|
19270
|
+
meta.rotations.push({ key, lastRotatedAt: now, rotatedBy, rotationCount: 1 });
|
|
19271
|
+
}
|
|
19272
|
+
}
|
|
19273
|
+
meta.pending = meta.pending.filter((p) => !keys.includes(p.key));
|
|
19274
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19275
|
+
}
|
|
19276
|
+
async removeRotation(cell, keys) {
|
|
19277
|
+
const meta = await this.storage.readPendingMetadata(cell);
|
|
19278
|
+
meta.rotations = meta.rotations.filter((r) => !keys.includes(r.key));
|
|
19279
|
+
await this.storage.writePendingMetadata(cell, meta);
|
|
19280
|
+
}
|
|
19281
|
+
// ── Lintable ───────────────────────────────────────────────────────────
|
|
19282
|
+
async validateEncryption(cell) {
|
|
19283
|
+
if (!await this.storage.blobExists(cell)) return false;
|
|
19284
|
+
const blob = await this.storage.readBlob(cell);
|
|
19285
|
+
return this.encryption.validateEncryption(blob);
|
|
19286
|
+
}
|
|
19287
|
+
async checkRecipientDrift(cell, expected) {
|
|
19288
|
+
const blob = await this.storage.readBlob(cell);
|
|
19289
|
+
const meta = this.encryption.getMetadata(blob);
|
|
19290
|
+
const actual = new Set(meta.recipients);
|
|
19291
|
+
const expectedSet = new Set(expected);
|
|
19292
|
+
return {
|
|
19293
|
+
missing: expected.filter((r) => !actual.has(r)),
|
|
19294
|
+
unexpected: meta.recipients.filter((r) => !expectedSet.has(r))
|
|
19295
|
+
};
|
|
19296
|
+
}
|
|
19297
|
+
// ── Rotatable ──────────────────────────────────────────────────────────
|
|
19298
|
+
async rotate(cell, opts) {
|
|
19299
|
+
const blob = await this.storage.readBlob(cell);
|
|
19300
|
+
const rotated = await this.encryption.rotate(blob, opts, this.context(cell));
|
|
19301
|
+
await this.storage.writeBlob(cell, rotated);
|
|
19302
|
+
}
|
|
19303
|
+
// ── Bulk ───────────────────────────────────────────────────────────────
|
|
19304
|
+
//
|
|
19305
|
+
// Default looped implementation. A future StorageBackend that supports
|
|
19306
|
+
// batch operations (e.g. PostgresStorageBackend with row-level UPDATE
|
|
19307
|
+
// batching) can override these by wrapping `composeSecretSource`'s
|
|
19308
|
+
// output and replacing just the bulk methods.
|
|
19309
|
+
bulkSet = (namespace, key, valuesByEnv, manifest) => defaultBulk(this).bulkSet(namespace, key, valuesByEnv, manifest);
|
|
19310
|
+
bulkDelete = (namespace, key, manifest) => defaultBulk(this).bulkDelete(namespace, key, manifest);
|
|
19311
|
+
copyValue = (key, from, to, manifest) => defaultBulk(this).copyValue(key, from, to, manifest);
|
|
19312
|
+
};
|
|
19313
|
+
|
|
19314
|
+
// src/source/filesystem-storage-backend.ts
|
|
19315
|
+
var fs22 = __toESM(require("fs"));
|
|
19316
|
+
var path26 = __toESM(require("path"));
|
|
19317
|
+
var import_crypto3 = require("crypto");
|
|
19318
|
+
var FilesystemStorageBackend = class {
|
|
19319
|
+
constructor(manifest, repoRoot) {
|
|
19320
|
+
this.manifest = manifest;
|
|
19321
|
+
this.repoRoot = repoRoot;
|
|
19322
|
+
}
|
|
19323
|
+
manifest;
|
|
19324
|
+
repoRoot;
|
|
19325
|
+
id = "filesystem";
|
|
19326
|
+
description = "Filesystem-backed cell storage (default substrate)";
|
|
19327
|
+
/**
|
|
19328
|
+
* Resolve a cell reference to its absolute filesystem path. Public —
|
|
19329
|
+
* used by substrate-specific trait implementations.
|
|
19330
|
+
*/
|
|
19331
|
+
cellPath(cell) {
|
|
19332
|
+
const relativePath = this.manifest.file_pattern.replace("{namespace}", cell.namespace).replace("{environment}", cell.environment);
|
|
19333
|
+
return path26.join(this.repoRoot, relativePath);
|
|
19334
|
+
}
|
|
19335
|
+
/** The repo root, exposed for filesystem-shaped trait implementations. */
|
|
19336
|
+
getRepoRoot() {
|
|
19337
|
+
return this.repoRoot;
|
|
19338
|
+
}
|
|
19339
|
+
blobFormat(cell) {
|
|
19340
|
+
return this.cellPath(cell).endsWith(".json") ? "json" : "yaml";
|
|
19341
|
+
}
|
|
19342
|
+
async readBlob(cell) {
|
|
19343
|
+
const filePath = this.cellPath(cell);
|
|
19344
|
+
return fs22.readFileSync(filePath, "utf-8");
|
|
19345
|
+
}
|
|
19346
|
+
async writeBlob(cell, blob) {
|
|
19347
|
+
const filePath = this.cellPath(cell);
|
|
19348
|
+
const dir = path26.dirname(filePath);
|
|
19349
|
+
if (!fs22.existsSync(dir)) {
|
|
19350
|
+
fs22.mkdirSync(dir, { recursive: true });
|
|
19351
|
+
}
|
|
19352
|
+
const tmpPath = `${filePath}.${Date.now()}.${(0, import_crypto3.randomBytes)(4).toString("hex")}.tmp`;
|
|
19353
|
+
const handle = fs22.openSync(tmpPath, "w");
|
|
19354
|
+
try {
|
|
19355
|
+
fs22.writeFileSync(handle, blob);
|
|
19356
|
+
fs22.fsyncSync(handle);
|
|
19357
|
+
} finally {
|
|
19358
|
+
fs22.closeSync(handle);
|
|
19359
|
+
}
|
|
19360
|
+
fs22.renameSync(tmpPath, filePath);
|
|
19361
|
+
}
|
|
19362
|
+
async deleteBlob(cell) {
|
|
19363
|
+
const filePath = this.cellPath(cell);
|
|
19364
|
+
if (fs22.existsSync(filePath)) {
|
|
19365
|
+
fs22.unlinkSync(filePath);
|
|
19366
|
+
}
|
|
19367
|
+
const sidecar = this.sidecarPath(filePath);
|
|
19368
|
+
if (fs22.existsSync(sidecar)) {
|
|
19369
|
+
fs22.unlinkSync(sidecar);
|
|
19370
|
+
}
|
|
19371
|
+
}
|
|
19372
|
+
async blobExists(cell) {
|
|
19373
|
+
return fs22.existsSync(this.cellPath(cell));
|
|
19374
|
+
}
|
|
19375
|
+
async readPendingMetadata(cell) {
|
|
19376
|
+
return loadMetadata(this.cellPath(cell));
|
|
19377
|
+
}
|
|
19378
|
+
async writePendingMetadata(cell, meta) {
|
|
19379
|
+
await saveMetadata(this.cellPath(cell), meta);
|
|
19380
|
+
}
|
|
19381
|
+
sidecarPath(filePath) {
|
|
19382
|
+
const dir = path26.dirname(filePath);
|
|
19383
|
+
const base = path26.basename(filePath).replace(/\.enc\.(yaml|json)$/, "");
|
|
19384
|
+
return path26.join(dir, `${base}.clef-meta.yaml`);
|
|
19385
|
+
}
|
|
19386
|
+
};
|
|
19387
|
+
|
|
19388
|
+
// src/compliance/run.ts
|
|
19191
19389
|
var UNKNOWN = "unknown";
|
|
19192
19390
|
async function runCompliance(opts) {
|
|
19193
19391
|
const start = Date.now();
|
|
19194
19392
|
const repoRoot = opts.repoRoot ?? process.cwd();
|
|
19195
|
-
const manifestPath = opts.manifestPath ??
|
|
19196
|
-
const policyPath = opts.policyPath ??
|
|
19393
|
+
const manifestPath = opts.manifestPath ?? path27.join(repoRoot, "clef.yaml");
|
|
19394
|
+
const policyPath = opts.policyPath ?? path27.join(repoRoot, CLEF_POLICY_FILENAME);
|
|
19197
19395
|
const include = {
|
|
19198
19396
|
scan: opts.include?.scan ?? true,
|
|
19199
19397
|
lint: opts.include?.lint ?? true,
|
|
@@ -19205,6 +19403,11 @@ async function runCompliance(opts) {
|
|
|
19205
19403
|
const sopsClient = new SopsClient(opts.runner, opts.ageKeyFile, opts.ageKey, opts.sopsPath);
|
|
19206
19404
|
const matrixManager = new MatrixManager();
|
|
19207
19405
|
const schemaValidator = new SchemaValidator();
|
|
19406
|
+
const lintSource = composeSecretSource(
|
|
19407
|
+
new FilesystemStorageBackend(manifest, repoRoot),
|
|
19408
|
+
sopsClient,
|
|
19409
|
+
manifest
|
|
19410
|
+
);
|
|
19208
19411
|
const [sha, repo, files, scanResult, lintResult] = await Promise.all([
|
|
19209
19412
|
opts.sha !== void 0 ? Promise.resolve(opts.sha) : detectSha(opts.runner, repoRoot),
|
|
19210
19413
|
opts.repo !== void 0 ? Promise.resolve(opts.repo) : detectRepo(opts.runner, repoRoot),
|
|
@@ -19213,12 +19416,12 @@ async function runCompliance(opts) {
|
|
|
19213
19416
|
repoRoot,
|
|
19214
19417
|
policy,
|
|
19215
19418
|
matrixManager,
|
|
19216
|
-
|
|
19419
|
+
source: lintSource,
|
|
19217
19420
|
filter: opts.filter,
|
|
19218
19421
|
now
|
|
19219
19422
|
}) : Promise.resolve([]),
|
|
19220
19423
|
include.scan ? new ScanRunner(opts.runner).scan(repoRoot, manifest) : Promise.resolve(emptyScan()),
|
|
19221
|
-
include.lint ? new LintRunner(matrixManager, schemaValidator,
|
|
19424
|
+
include.lint ? new LintRunner(matrixManager, schemaValidator, lintSource).run(manifest, repoRoot) : Promise.resolve(emptyLint())
|
|
19222
19425
|
]);
|
|
19223
19426
|
const adjustedLint = downgradeDecryptIssues(lintResult);
|
|
19224
19427
|
const document = new ComplianceGenerator().generate({
|
|
@@ -19238,8 +19441,11 @@ async function evaluateMatrix(args) {
|
|
|
19238
19441
|
const cells = args.matrixManager.resolveMatrix(args.manifest, args.repoRoot).filter((c) => applyFilter(c.namespace, c.environment, args.filter)).filter((c) => c.exists);
|
|
19239
19442
|
return Promise.all(
|
|
19240
19443
|
cells.map(async (cell) => {
|
|
19241
|
-
const metadata = await args.
|
|
19242
|
-
|
|
19444
|
+
const metadata = await args.source.getCellMetadata({
|
|
19445
|
+
namespace: cell.namespace,
|
|
19446
|
+
environment: cell.environment
|
|
19447
|
+
});
|
|
19448
|
+
const relPath = path27.relative(args.repoRoot, cell.filePath).replace(/\\/g, "/");
|
|
19243
19449
|
const keys = readSopsKeyNames(cell.filePath) ?? [];
|
|
19244
19450
|
const rotations = await getRotations(cell.filePath);
|
|
19245
19451
|
return evaluator.evaluateFile(relPath, cell.environment, metadata, keys, rotations, args.now);
|
|
@@ -19297,11 +19503,62 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19297
19503
|
const match = url.match(/[:/]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
19298
19504
|
return match ? `${match[1]}/${match[2]}` : UNKNOWN;
|
|
19299
19505
|
}
|
|
19506
|
+
|
|
19507
|
+
// src/source/guards.ts
|
|
19508
|
+
function isFn(o, name) {
|
|
19509
|
+
return typeof o === "object" && o !== null && typeof o[name] === "function";
|
|
19510
|
+
}
|
|
19511
|
+
function isLintable(s) {
|
|
19512
|
+
return isFn(s, "validateEncryption") && isFn(s, "checkRecipientDrift");
|
|
19513
|
+
}
|
|
19514
|
+
function isRotatable(s) {
|
|
19515
|
+
return isFn(s, "rotate");
|
|
19516
|
+
}
|
|
19517
|
+
function isRecipientManaged(s) {
|
|
19518
|
+
return isFn(s, "listRecipients") && isFn(s, "addRecipient") && isFn(s, "removeRecipient");
|
|
19519
|
+
}
|
|
19520
|
+
function isMergeAware(s) {
|
|
19521
|
+
return isFn(s, "mergeCells") && isFn(s, "installMergeDriver");
|
|
19522
|
+
}
|
|
19523
|
+
function isMigratable(s) {
|
|
19524
|
+
return isFn(s, "migrateBackend");
|
|
19525
|
+
}
|
|
19526
|
+
function isBulk(s) {
|
|
19527
|
+
return isFn(s, "bulkSet") && isFn(s, "bulkDelete") && isFn(s, "copyValue");
|
|
19528
|
+
}
|
|
19529
|
+
function isStructural(s) {
|
|
19530
|
+
return isFn(s, "addNamespace") && isFn(s, "addEnvironment") && isFn(s, "renameNamespace") && isFn(s, "renameEnvironment");
|
|
19531
|
+
}
|
|
19532
|
+
function describeCapabilities(s) {
|
|
19533
|
+
return {
|
|
19534
|
+
lint: isLintable(s),
|
|
19535
|
+
rotate: isRotatable(s),
|
|
19536
|
+
recipients: isRecipientManaged(s),
|
|
19537
|
+
merge: isMergeAware(s),
|
|
19538
|
+
migrate: isMigratable(s),
|
|
19539
|
+
bulk: isBulk(s),
|
|
19540
|
+
structural: isStructural(s)
|
|
19541
|
+
};
|
|
19542
|
+
}
|
|
19543
|
+
|
|
19544
|
+
// src/source/errors.ts
|
|
19545
|
+
var SourceCapabilityUnsupportedError = class extends ClefError {
|
|
19546
|
+
constructor(capability, sourceId) {
|
|
19547
|
+
super(
|
|
19548
|
+
`'${capability}' is not supported by the '${sourceId}' source.`,
|
|
19549
|
+
`Switch to a source that implements ${capability}, or use a different command.`
|
|
19550
|
+
);
|
|
19551
|
+
this.capability = capability;
|
|
19552
|
+
this.sourceId = sourceId;
|
|
19553
|
+
this.name = "SourceCapabilityUnsupportedError";
|
|
19554
|
+
}
|
|
19555
|
+
capability;
|
|
19556
|
+
sourceId;
|
|
19557
|
+
};
|
|
19300
19558
|
// Annotate the CommonJS export names for ESM import in node:
|
|
19301
19559
|
0 && (module.exports = {
|
|
19302
19560
|
ArtifactPacker,
|
|
19303
19561
|
BackendMigrator,
|
|
19304
|
-
BulkOps,
|
|
19305
19562
|
CLEF_MANIFEST_FILENAME,
|
|
19306
19563
|
CLEF_POLICY_FILENAME,
|
|
19307
19564
|
CLEF_REPORT_SCHEMA_VERSION,
|
|
@@ -19315,6 +19572,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19315
19572
|
DiffEngine,
|
|
19316
19573
|
DriftDetector,
|
|
19317
19574
|
FilePackOutput,
|
|
19575
|
+
FilesystemStorageBackend,
|
|
19318
19576
|
GitIntegration,
|
|
19319
19577
|
GitOperationError,
|
|
19320
19578
|
ImportRunner,
|
|
@@ -19331,7 +19589,6 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19331
19589
|
PolicyValidationError,
|
|
19332
19590
|
REQUESTS_FILENAME,
|
|
19333
19591
|
REQUIREMENTS,
|
|
19334
|
-
REVEAL_WARNING,
|
|
19335
19592
|
RecipientManager,
|
|
19336
19593
|
ReportGenerator,
|
|
19337
19594
|
ReportSanitizer,
|
|
@@ -19348,6 +19605,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19348
19605
|
SopsMergeDriver,
|
|
19349
19606
|
SopsMissingError,
|
|
19350
19607
|
SopsVersionError,
|
|
19608
|
+
SourceCapabilityUnsupportedError,
|
|
19351
19609
|
StructureManager,
|
|
19352
19610
|
SyncManager,
|
|
19353
19611
|
TransactionLockError,
|
|
@@ -19367,11 +19625,11 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19367
19625
|
checkAll,
|
|
19368
19626
|
checkDependency,
|
|
19369
19627
|
collectCIContext,
|
|
19628
|
+
composeSecretSource,
|
|
19370
19629
|
computeCiphertextHash,
|
|
19371
19630
|
deriveAgePublicKey,
|
|
19631
|
+
describeCapabilities,
|
|
19372
19632
|
describeScope,
|
|
19373
|
-
detectAlgorithm,
|
|
19374
|
-
detectFormat,
|
|
19375
19633
|
emptyTemplate,
|
|
19376
19634
|
exampleTemplate,
|
|
19377
19635
|
findRequest,
|
|
@@ -19379,29 +19637,24 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19379
19637
|
formatRevealWarning,
|
|
19380
19638
|
generateAgeIdentity,
|
|
19381
19639
|
generateRandomValue,
|
|
19382
|
-
|
|
19383
|
-
getPendingKeys,
|
|
19384
|
-
getRotations,
|
|
19640
|
+
isBulk,
|
|
19385
19641
|
isClefHsmArn,
|
|
19386
19642
|
isHighEntropy,
|
|
19387
19643
|
isKmsEnvelope,
|
|
19644
|
+
isLintable,
|
|
19645
|
+
isMergeAware,
|
|
19646
|
+
isMigratable,
|
|
19388
19647
|
isPackedArtifact,
|
|
19389
|
-
|
|
19648
|
+
isRecipientManaged,
|
|
19649
|
+
isRotatable,
|
|
19650
|
+
isStructural,
|
|
19390
19651
|
keyPreview,
|
|
19391
|
-
loadIgnoreRules,
|
|
19392
|
-
loadMetadata,
|
|
19393
19652
|
loadRequests,
|
|
19394
19653
|
markPending,
|
|
19395
|
-
markPendingWithRetry,
|
|
19396
19654
|
markResolved,
|
|
19397
19655
|
matchPatterns,
|
|
19398
|
-
mergeMetadataContents,
|
|
19399
19656
|
mergeMetadataFiles,
|
|
19400
|
-
metadataPath,
|
|
19401
19657
|
parse,
|
|
19402
|
-
parseDotenv,
|
|
19403
|
-
parseIgnoreContent,
|
|
19404
|
-
parseJson,
|
|
19405
19658
|
parseSignerKey,
|
|
19406
19659
|
parseYaml,
|
|
19407
19660
|
pkcs11UriToSyntheticArn,
|
|
@@ -19419,14 +19672,8 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19419
19672
|
resolveRecipientsForEnvironment,
|
|
19420
19673
|
resolveSopsPath,
|
|
19421
19674
|
runCompliance,
|
|
19422
|
-
saveMetadata,
|
|
19423
19675
|
saveRequests,
|
|
19424
|
-
|
|
19425
|
-
shannonEntropy,
|
|
19426
|
-
shouldIgnoreFile,
|
|
19427
|
-
shouldIgnoreMatch,
|
|
19428
|
-
signEd25519,
|
|
19429
|
-
signKms,
|
|
19676
|
+
shouldUseLinuxStdinFifo,
|
|
19430
19677
|
spawnKeyservice,
|
|
19431
19678
|
syntheticArnToPkcs11Uri,
|
|
19432
19679
|
tryBundledKeyservice,
|
|
@@ -19436,6 +19683,7 @@ async function detectRepo(runner, repoRoot) {
|
|
|
19436
19683
|
validatePackedArtifact,
|
|
19437
19684
|
validateResetScope,
|
|
19438
19685
|
verifySignature,
|
|
19686
|
+
wrapWithLinuxStdinFifo,
|
|
19439
19687
|
writeManifestYaml,
|
|
19440
19688
|
writeManifestYamlRaw,
|
|
19441
19689
|
writeSchema,
|