switchroom 0.7.10 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-scheduler/index.js +1 -1
- package/dist/cli/switchroom.js +2971 -944
- package/dist/vault/approvals/kernel-server.js +18 -1
- package/dist/vault/broker/server.js +1991 -84
- package/package.json +4 -2
- package/telegram-plugin/dist/foreman/foreman.js +1552 -7
- package/telegram-plugin/dist/gateway/gateway.js +1560 -15
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
3
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
4
33
|
var __returnValue = (v) => v;
|
|
5
34
|
function __exportSetter(name, newValue) {
|
|
@@ -13,9 +42,1529 @@ var __export = (target, all) => {
|
|
|
13
42
|
configurable: true,
|
|
14
43
|
set: __exportSetter.bind(all, name)
|
|
15
44
|
});
|
|
16
|
-
};
|
|
17
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
45
|
+
};
|
|
46
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
48
|
+
|
|
49
|
+
// node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js
|
|
50
|
+
var require_polyfills = __commonJS((exports, module) => {
|
|
51
|
+
var constants = __require("constants");
|
|
52
|
+
var origCwd = process.cwd;
|
|
53
|
+
var cwd = null;
|
|
54
|
+
var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform;
|
|
55
|
+
process.cwd = function() {
|
|
56
|
+
if (!cwd)
|
|
57
|
+
cwd = origCwd.call(process);
|
|
58
|
+
return cwd;
|
|
59
|
+
};
|
|
60
|
+
try {
|
|
61
|
+
process.cwd();
|
|
62
|
+
} catch (er) {}
|
|
63
|
+
if (typeof process.chdir === "function") {
|
|
64
|
+
chdir = process.chdir;
|
|
65
|
+
process.chdir = function(d) {
|
|
66
|
+
cwd = null;
|
|
67
|
+
chdir.call(process, d);
|
|
68
|
+
};
|
|
69
|
+
if (Object.setPrototypeOf)
|
|
70
|
+
Object.setPrototypeOf(process.chdir, chdir);
|
|
71
|
+
}
|
|
72
|
+
var chdir;
|
|
73
|
+
module.exports = patch;
|
|
74
|
+
function patch(fs) {
|
|
75
|
+
if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
|
|
76
|
+
patchLchmod(fs);
|
|
77
|
+
}
|
|
78
|
+
if (!fs.lutimes) {
|
|
79
|
+
patchLutimes(fs);
|
|
80
|
+
}
|
|
81
|
+
fs.chown = chownFix(fs.chown);
|
|
82
|
+
fs.fchown = chownFix(fs.fchown);
|
|
83
|
+
fs.lchown = chownFix(fs.lchown);
|
|
84
|
+
fs.chmod = chmodFix(fs.chmod);
|
|
85
|
+
fs.fchmod = chmodFix(fs.fchmod);
|
|
86
|
+
fs.lchmod = chmodFix(fs.lchmod);
|
|
87
|
+
fs.chownSync = chownFixSync(fs.chownSync);
|
|
88
|
+
fs.fchownSync = chownFixSync(fs.fchownSync);
|
|
89
|
+
fs.lchownSync = chownFixSync(fs.lchownSync);
|
|
90
|
+
fs.chmodSync = chmodFixSync(fs.chmodSync);
|
|
91
|
+
fs.fchmodSync = chmodFixSync(fs.fchmodSync);
|
|
92
|
+
fs.lchmodSync = chmodFixSync(fs.lchmodSync);
|
|
93
|
+
fs.stat = statFix(fs.stat);
|
|
94
|
+
fs.fstat = statFix(fs.fstat);
|
|
95
|
+
fs.lstat = statFix(fs.lstat);
|
|
96
|
+
fs.statSync = statFixSync(fs.statSync);
|
|
97
|
+
fs.fstatSync = statFixSync(fs.fstatSync);
|
|
98
|
+
fs.lstatSync = statFixSync(fs.lstatSync);
|
|
99
|
+
if (fs.chmod && !fs.lchmod) {
|
|
100
|
+
fs.lchmod = function(path, mode, cb) {
|
|
101
|
+
if (cb)
|
|
102
|
+
process.nextTick(cb);
|
|
103
|
+
};
|
|
104
|
+
fs.lchmodSync = function() {};
|
|
105
|
+
}
|
|
106
|
+
if (fs.chown && !fs.lchown) {
|
|
107
|
+
fs.lchown = function(path, uid, gid, cb) {
|
|
108
|
+
if (cb)
|
|
109
|
+
process.nextTick(cb);
|
|
110
|
+
};
|
|
111
|
+
fs.lchownSync = function() {};
|
|
112
|
+
}
|
|
113
|
+
if (platform === "win32") {
|
|
114
|
+
fs.rename = typeof fs.rename !== "function" ? fs.rename : function(fs$rename) {
|
|
115
|
+
function rename(from, to, cb) {
|
|
116
|
+
var start = Date.now();
|
|
117
|
+
var backoff = 0;
|
|
118
|
+
fs$rename(from, to, function CB(er) {
|
|
119
|
+
if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 60000) {
|
|
120
|
+
setTimeout(function() {
|
|
121
|
+
fs.stat(to, function(stater, st) {
|
|
122
|
+
if (stater && stater.code === "ENOENT")
|
|
123
|
+
fs$rename(from, to, CB);
|
|
124
|
+
else
|
|
125
|
+
cb(er);
|
|
126
|
+
});
|
|
127
|
+
}, backoff);
|
|
128
|
+
if (backoff < 100)
|
|
129
|
+
backoff += 10;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (cb)
|
|
133
|
+
cb(er);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (Object.setPrototypeOf)
|
|
137
|
+
Object.setPrototypeOf(rename, fs$rename);
|
|
138
|
+
return rename;
|
|
139
|
+
}(fs.rename);
|
|
140
|
+
}
|
|
141
|
+
fs.read = typeof fs.read !== "function" ? fs.read : function(fs$read) {
|
|
142
|
+
function read(fd, buffer, offset, length, position, callback_) {
|
|
143
|
+
var callback;
|
|
144
|
+
if (callback_ && typeof callback_ === "function") {
|
|
145
|
+
var eagCounter = 0;
|
|
146
|
+
callback = function(er, _, __) {
|
|
147
|
+
if (er && er.code === "EAGAIN" && eagCounter < 10) {
|
|
148
|
+
eagCounter++;
|
|
149
|
+
return fs$read.call(fs, fd, buffer, offset, length, position, callback);
|
|
150
|
+
}
|
|
151
|
+
callback_.apply(this, arguments);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return fs$read.call(fs, fd, buffer, offset, length, position, callback);
|
|
155
|
+
}
|
|
156
|
+
if (Object.setPrototypeOf)
|
|
157
|
+
Object.setPrototypeOf(read, fs$read);
|
|
158
|
+
return read;
|
|
159
|
+
}(fs.read);
|
|
160
|
+
fs.readSync = typeof fs.readSync !== "function" ? fs.readSync : function(fs$readSync) {
|
|
161
|
+
return function(fd, buffer, offset, length, position) {
|
|
162
|
+
var eagCounter = 0;
|
|
163
|
+
while (true) {
|
|
164
|
+
try {
|
|
165
|
+
return fs$readSync.call(fs, fd, buffer, offset, length, position);
|
|
166
|
+
} catch (er) {
|
|
167
|
+
if (er.code === "EAGAIN" && eagCounter < 10) {
|
|
168
|
+
eagCounter++;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
throw er;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}(fs.readSync);
|
|
176
|
+
function patchLchmod(fs2) {
|
|
177
|
+
fs2.lchmod = function(path, mode, callback) {
|
|
178
|
+
fs2.open(path, constants.O_WRONLY | constants.O_SYMLINK, mode, function(err, fd) {
|
|
179
|
+
if (err) {
|
|
180
|
+
if (callback)
|
|
181
|
+
callback(err);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
fs2.fchmod(fd, mode, function(err2) {
|
|
185
|
+
fs2.close(fd, function(err22) {
|
|
186
|
+
if (callback)
|
|
187
|
+
callback(err2 || err22);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
fs2.lchmodSync = function(path, mode) {
|
|
193
|
+
var fd = fs2.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode);
|
|
194
|
+
var threw = true;
|
|
195
|
+
var ret;
|
|
196
|
+
try {
|
|
197
|
+
ret = fs2.fchmodSync(fd, mode);
|
|
198
|
+
threw = false;
|
|
199
|
+
} finally {
|
|
200
|
+
if (threw) {
|
|
201
|
+
try {
|
|
202
|
+
fs2.closeSync(fd);
|
|
203
|
+
} catch (er) {}
|
|
204
|
+
} else {
|
|
205
|
+
fs2.closeSync(fd);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return ret;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function patchLutimes(fs2) {
|
|
212
|
+
if (constants.hasOwnProperty("O_SYMLINK") && fs2.futimes) {
|
|
213
|
+
fs2.lutimes = function(path, at, mt, cb) {
|
|
214
|
+
fs2.open(path, constants.O_SYMLINK, function(er, fd) {
|
|
215
|
+
if (er) {
|
|
216
|
+
if (cb)
|
|
217
|
+
cb(er);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
fs2.futimes(fd, at, mt, function(er2) {
|
|
221
|
+
fs2.close(fd, function(er22) {
|
|
222
|
+
if (cb)
|
|
223
|
+
cb(er2 || er22);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
fs2.lutimesSync = function(path, at, mt) {
|
|
229
|
+
var fd = fs2.openSync(path, constants.O_SYMLINK);
|
|
230
|
+
var ret;
|
|
231
|
+
var threw = true;
|
|
232
|
+
try {
|
|
233
|
+
ret = fs2.futimesSync(fd, at, mt);
|
|
234
|
+
threw = false;
|
|
235
|
+
} finally {
|
|
236
|
+
if (threw) {
|
|
237
|
+
try {
|
|
238
|
+
fs2.closeSync(fd);
|
|
239
|
+
} catch (er) {}
|
|
240
|
+
} else {
|
|
241
|
+
fs2.closeSync(fd);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return ret;
|
|
245
|
+
};
|
|
246
|
+
} else if (fs2.futimes) {
|
|
247
|
+
fs2.lutimes = function(_a, _b, _c, cb) {
|
|
248
|
+
if (cb)
|
|
249
|
+
process.nextTick(cb);
|
|
250
|
+
};
|
|
251
|
+
fs2.lutimesSync = function() {};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function chmodFix(orig) {
|
|
255
|
+
if (!orig)
|
|
256
|
+
return orig;
|
|
257
|
+
return function(target, mode, cb) {
|
|
258
|
+
return orig.call(fs, target, mode, function(er) {
|
|
259
|
+
if (chownErOk(er))
|
|
260
|
+
er = null;
|
|
261
|
+
if (cb)
|
|
262
|
+
cb.apply(this, arguments);
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function chmodFixSync(orig) {
|
|
267
|
+
if (!orig)
|
|
268
|
+
return orig;
|
|
269
|
+
return function(target, mode) {
|
|
270
|
+
try {
|
|
271
|
+
return orig.call(fs, target, mode);
|
|
272
|
+
} catch (er) {
|
|
273
|
+
if (!chownErOk(er))
|
|
274
|
+
throw er;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function chownFix(orig) {
|
|
279
|
+
if (!orig)
|
|
280
|
+
return orig;
|
|
281
|
+
return function(target, uid, gid, cb) {
|
|
282
|
+
return orig.call(fs, target, uid, gid, function(er) {
|
|
283
|
+
if (chownErOk(er))
|
|
284
|
+
er = null;
|
|
285
|
+
if (cb)
|
|
286
|
+
cb.apply(this, arguments);
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function chownFixSync(orig) {
|
|
291
|
+
if (!orig)
|
|
292
|
+
return orig;
|
|
293
|
+
return function(target, uid, gid) {
|
|
294
|
+
try {
|
|
295
|
+
return orig.call(fs, target, uid, gid);
|
|
296
|
+
} catch (er) {
|
|
297
|
+
if (!chownErOk(er))
|
|
298
|
+
throw er;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function statFix(orig) {
|
|
303
|
+
if (!orig)
|
|
304
|
+
return orig;
|
|
305
|
+
return function(target, options, cb) {
|
|
306
|
+
if (typeof options === "function") {
|
|
307
|
+
cb = options;
|
|
308
|
+
options = null;
|
|
309
|
+
}
|
|
310
|
+
function callback(er, stats) {
|
|
311
|
+
if (stats) {
|
|
312
|
+
if (stats.uid < 0)
|
|
313
|
+
stats.uid += 4294967296;
|
|
314
|
+
if (stats.gid < 0)
|
|
315
|
+
stats.gid += 4294967296;
|
|
316
|
+
}
|
|
317
|
+
if (cb)
|
|
318
|
+
cb.apply(this, arguments);
|
|
319
|
+
}
|
|
320
|
+
return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function statFixSync(orig) {
|
|
324
|
+
if (!orig)
|
|
325
|
+
return orig;
|
|
326
|
+
return function(target, options) {
|
|
327
|
+
var stats = options ? orig.call(fs, target, options) : orig.call(fs, target);
|
|
328
|
+
if (stats) {
|
|
329
|
+
if (stats.uid < 0)
|
|
330
|
+
stats.uid += 4294967296;
|
|
331
|
+
if (stats.gid < 0)
|
|
332
|
+
stats.gid += 4294967296;
|
|
333
|
+
}
|
|
334
|
+
return stats;
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function chownErOk(er) {
|
|
338
|
+
if (!er)
|
|
339
|
+
return true;
|
|
340
|
+
if (er.code === "ENOSYS")
|
|
341
|
+
return true;
|
|
342
|
+
var nonroot = !process.getuid || process.getuid() !== 0;
|
|
343
|
+
if (nonroot) {
|
|
344
|
+
if (er.code === "EINVAL" || er.code === "EPERM")
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/legacy-streams.js
|
|
353
|
+
var require_legacy_streams = __commonJS((exports, module) => {
|
|
354
|
+
var Stream = __require("stream").Stream;
|
|
355
|
+
module.exports = legacy;
|
|
356
|
+
function legacy(fs) {
|
|
357
|
+
return {
|
|
358
|
+
ReadStream,
|
|
359
|
+
WriteStream
|
|
360
|
+
};
|
|
361
|
+
function ReadStream(path, options) {
|
|
362
|
+
if (!(this instanceof ReadStream))
|
|
363
|
+
return new ReadStream(path, options);
|
|
364
|
+
Stream.call(this);
|
|
365
|
+
var self = this;
|
|
366
|
+
this.path = path;
|
|
367
|
+
this.fd = null;
|
|
368
|
+
this.readable = true;
|
|
369
|
+
this.paused = false;
|
|
370
|
+
this.flags = "r";
|
|
371
|
+
this.mode = 438;
|
|
372
|
+
this.bufferSize = 64 * 1024;
|
|
373
|
+
options = options || {};
|
|
374
|
+
var keys = Object.keys(options);
|
|
375
|
+
for (var index = 0, length = keys.length;index < length; index++) {
|
|
376
|
+
var key = keys[index];
|
|
377
|
+
this[key] = options[key];
|
|
378
|
+
}
|
|
379
|
+
if (this.encoding)
|
|
380
|
+
this.setEncoding(this.encoding);
|
|
381
|
+
if (this.start !== undefined) {
|
|
382
|
+
if (typeof this.start !== "number") {
|
|
383
|
+
throw TypeError("start must be a Number");
|
|
384
|
+
}
|
|
385
|
+
if (this.end === undefined) {
|
|
386
|
+
this.end = Infinity;
|
|
387
|
+
} else if (typeof this.end !== "number") {
|
|
388
|
+
throw TypeError("end must be a Number");
|
|
389
|
+
}
|
|
390
|
+
if (this.start > this.end) {
|
|
391
|
+
throw new Error("start must be <= end");
|
|
392
|
+
}
|
|
393
|
+
this.pos = this.start;
|
|
394
|
+
}
|
|
395
|
+
if (this.fd !== null) {
|
|
396
|
+
process.nextTick(function() {
|
|
397
|
+
self._read();
|
|
398
|
+
});
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
fs.open(this.path, this.flags, this.mode, function(err, fd) {
|
|
402
|
+
if (err) {
|
|
403
|
+
self.emit("error", err);
|
|
404
|
+
self.readable = false;
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
self.fd = fd;
|
|
408
|
+
self.emit("open", fd);
|
|
409
|
+
self._read();
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
function WriteStream(path, options) {
|
|
413
|
+
if (!(this instanceof WriteStream))
|
|
414
|
+
return new WriteStream(path, options);
|
|
415
|
+
Stream.call(this);
|
|
416
|
+
this.path = path;
|
|
417
|
+
this.fd = null;
|
|
418
|
+
this.writable = true;
|
|
419
|
+
this.flags = "w";
|
|
420
|
+
this.encoding = "binary";
|
|
421
|
+
this.mode = 438;
|
|
422
|
+
this.bytesWritten = 0;
|
|
423
|
+
options = options || {};
|
|
424
|
+
var keys = Object.keys(options);
|
|
425
|
+
for (var index = 0, length = keys.length;index < length; index++) {
|
|
426
|
+
var key = keys[index];
|
|
427
|
+
this[key] = options[key];
|
|
428
|
+
}
|
|
429
|
+
if (this.start !== undefined) {
|
|
430
|
+
if (typeof this.start !== "number") {
|
|
431
|
+
throw TypeError("start must be a Number");
|
|
432
|
+
}
|
|
433
|
+
if (this.start < 0) {
|
|
434
|
+
throw new Error("start must be >= zero");
|
|
435
|
+
}
|
|
436
|
+
this.pos = this.start;
|
|
437
|
+
}
|
|
438
|
+
this.busy = false;
|
|
439
|
+
this._queue = [];
|
|
440
|
+
if (this.fd === null) {
|
|
441
|
+
this._open = fs.open;
|
|
442
|
+
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
|
|
443
|
+
this.flush();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/clone.js
|
|
450
|
+
var require_clone = __commonJS((exports, module) => {
|
|
451
|
+
module.exports = clone;
|
|
452
|
+
var getPrototypeOf = Object.getPrototypeOf || function(obj) {
|
|
453
|
+
return obj.__proto__;
|
|
454
|
+
};
|
|
455
|
+
function clone(obj) {
|
|
456
|
+
if (obj === null || typeof obj !== "object")
|
|
457
|
+
return obj;
|
|
458
|
+
if (obj instanceof Object)
|
|
459
|
+
var copy = { __proto__: getPrototypeOf(obj) };
|
|
460
|
+
else
|
|
461
|
+
var copy = Object.create(null);
|
|
462
|
+
Object.getOwnPropertyNames(obj).forEach(function(key) {
|
|
463
|
+
Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key));
|
|
464
|
+
});
|
|
465
|
+
return copy;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js
|
|
470
|
+
var require_graceful_fs = __commonJS((exports, module) => {
|
|
471
|
+
var fs = __require("fs");
|
|
472
|
+
var polyfills = require_polyfills();
|
|
473
|
+
var legacy = require_legacy_streams();
|
|
474
|
+
var clone = require_clone();
|
|
475
|
+
var util = __require("util");
|
|
476
|
+
var gracefulQueue;
|
|
477
|
+
var previousSymbol;
|
|
478
|
+
if (typeof Symbol === "function" && typeof Symbol.for === "function") {
|
|
479
|
+
gracefulQueue = Symbol.for("graceful-fs.queue");
|
|
480
|
+
previousSymbol = Symbol.for("graceful-fs.previous");
|
|
481
|
+
} else {
|
|
482
|
+
gracefulQueue = "___graceful-fs.queue";
|
|
483
|
+
previousSymbol = "___graceful-fs.previous";
|
|
484
|
+
}
|
|
485
|
+
function noop() {}
|
|
486
|
+
function publishQueue(context, queue2) {
|
|
487
|
+
Object.defineProperty(context, gracefulQueue, {
|
|
488
|
+
get: function() {
|
|
489
|
+
return queue2;
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
var debug = noop;
|
|
494
|
+
if (util.debuglog)
|
|
495
|
+
debug = util.debuglog("gfs4");
|
|
496
|
+
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ""))
|
|
497
|
+
debug = function() {
|
|
498
|
+
var m = util.format.apply(util, arguments);
|
|
499
|
+
m = "GFS4: " + m.split(/\n/).join(`
|
|
500
|
+
GFS4: `);
|
|
501
|
+
console.error(m);
|
|
502
|
+
};
|
|
503
|
+
if (!fs[gracefulQueue]) {
|
|
504
|
+
queue = global[gracefulQueue] || [];
|
|
505
|
+
publishQueue(fs, queue);
|
|
506
|
+
fs.close = function(fs$close) {
|
|
507
|
+
function close(fd, cb) {
|
|
508
|
+
return fs$close.call(fs, fd, function(err) {
|
|
509
|
+
if (!err) {
|
|
510
|
+
resetQueue();
|
|
511
|
+
}
|
|
512
|
+
if (typeof cb === "function")
|
|
513
|
+
cb.apply(this, arguments);
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
Object.defineProperty(close, previousSymbol, {
|
|
517
|
+
value: fs$close
|
|
518
|
+
});
|
|
519
|
+
return close;
|
|
520
|
+
}(fs.close);
|
|
521
|
+
fs.closeSync = function(fs$closeSync) {
|
|
522
|
+
function closeSync(fd) {
|
|
523
|
+
fs$closeSync.apply(fs, arguments);
|
|
524
|
+
resetQueue();
|
|
525
|
+
}
|
|
526
|
+
Object.defineProperty(closeSync, previousSymbol, {
|
|
527
|
+
value: fs$closeSync
|
|
528
|
+
});
|
|
529
|
+
return closeSync;
|
|
530
|
+
}(fs.closeSync);
|
|
531
|
+
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
|
|
532
|
+
process.on("exit", function() {
|
|
533
|
+
debug(fs[gracefulQueue]);
|
|
534
|
+
__require("assert").equal(fs[gracefulQueue].length, 0);
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
var queue;
|
|
539
|
+
if (!global[gracefulQueue]) {
|
|
540
|
+
publishQueue(global, fs[gracefulQueue]);
|
|
541
|
+
}
|
|
542
|
+
module.exports = patch(clone(fs));
|
|
543
|
+
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
|
|
544
|
+
module.exports = patch(fs);
|
|
545
|
+
fs.__patched = true;
|
|
546
|
+
}
|
|
547
|
+
function patch(fs2) {
|
|
548
|
+
polyfills(fs2);
|
|
549
|
+
fs2.gracefulify = patch;
|
|
550
|
+
fs2.createReadStream = createReadStream;
|
|
551
|
+
fs2.createWriteStream = createWriteStream;
|
|
552
|
+
var fs$readFile = fs2.readFile;
|
|
553
|
+
fs2.readFile = readFile;
|
|
554
|
+
function readFile(path, options, cb) {
|
|
555
|
+
if (typeof options === "function")
|
|
556
|
+
cb = options, options = null;
|
|
557
|
+
return go$readFile(path, options, cb);
|
|
558
|
+
function go$readFile(path2, options2, cb2, startTime) {
|
|
559
|
+
return fs$readFile(path2, options2, function(err) {
|
|
560
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
561
|
+
enqueue([go$readFile, [path2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
562
|
+
else {
|
|
563
|
+
if (typeof cb2 === "function")
|
|
564
|
+
cb2.apply(this, arguments);
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
var fs$writeFile = fs2.writeFile;
|
|
570
|
+
fs2.writeFile = writeFile;
|
|
571
|
+
function writeFile(path, data, options, cb) {
|
|
572
|
+
if (typeof options === "function")
|
|
573
|
+
cb = options, options = null;
|
|
574
|
+
return go$writeFile(path, data, options, cb);
|
|
575
|
+
function go$writeFile(path2, data2, options2, cb2, startTime) {
|
|
576
|
+
return fs$writeFile(path2, data2, options2, function(err) {
|
|
577
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
578
|
+
enqueue([go$writeFile, [path2, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
579
|
+
else {
|
|
580
|
+
if (typeof cb2 === "function")
|
|
581
|
+
cb2.apply(this, arguments);
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
var fs$appendFile = fs2.appendFile;
|
|
587
|
+
if (fs$appendFile)
|
|
588
|
+
fs2.appendFile = appendFile;
|
|
589
|
+
function appendFile(path, data, options, cb) {
|
|
590
|
+
if (typeof options === "function")
|
|
591
|
+
cb = options, options = null;
|
|
592
|
+
return go$appendFile(path, data, options, cb);
|
|
593
|
+
function go$appendFile(path2, data2, options2, cb2, startTime) {
|
|
594
|
+
return fs$appendFile(path2, data2, options2, function(err) {
|
|
595
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
596
|
+
enqueue([go$appendFile, [path2, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
597
|
+
else {
|
|
598
|
+
if (typeof cb2 === "function")
|
|
599
|
+
cb2.apply(this, arguments);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
var fs$copyFile = fs2.copyFile;
|
|
605
|
+
if (fs$copyFile)
|
|
606
|
+
fs2.copyFile = copyFile;
|
|
607
|
+
function copyFile(src, dest, flags, cb) {
|
|
608
|
+
if (typeof flags === "function") {
|
|
609
|
+
cb = flags;
|
|
610
|
+
flags = 0;
|
|
611
|
+
}
|
|
612
|
+
return go$copyFile(src, dest, flags, cb);
|
|
613
|
+
function go$copyFile(src2, dest2, flags2, cb2, startTime) {
|
|
614
|
+
return fs$copyFile(src2, dest2, flags2, function(err) {
|
|
615
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
616
|
+
enqueue([go$copyFile, [src2, dest2, flags2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
617
|
+
else {
|
|
618
|
+
if (typeof cb2 === "function")
|
|
619
|
+
cb2.apply(this, arguments);
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
var fs$readdir = fs2.readdir;
|
|
625
|
+
fs2.readdir = readdir;
|
|
626
|
+
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
627
|
+
function readdir(path, options, cb) {
|
|
628
|
+
if (typeof options === "function")
|
|
629
|
+
cb = options, options = null;
|
|
630
|
+
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path2, options2, cb2, startTime) {
|
|
631
|
+
return fs$readdir(path2, fs$readdirCallback(path2, options2, cb2, startTime));
|
|
632
|
+
} : function go$readdir2(path2, options2, cb2, startTime) {
|
|
633
|
+
return fs$readdir(path2, options2, fs$readdirCallback(path2, options2, cb2, startTime));
|
|
634
|
+
};
|
|
635
|
+
return go$readdir(path, options, cb);
|
|
636
|
+
function fs$readdirCallback(path2, options2, cb2, startTime) {
|
|
637
|
+
return function(err, files) {
|
|
638
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
639
|
+
enqueue([
|
|
640
|
+
go$readdir,
|
|
641
|
+
[path2, options2, cb2],
|
|
642
|
+
err,
|
|
643
|
+
startTime || Date.now(),
|
|
644
|
+
Date.now()
|
|
645
|
+
]);
|
|
646
|
+
else {
|
|
647
|
+
if (files && files.sort)
|
|
648
|
+
files.sort();
|
|
649
|
+
if (typeof cb2 === "function")
|
|
650
|
+
cb2.call(this, err, files);
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (process.version.substr(0, 4) === "v0.8") {
|
|
656
|
+
var legStreams = legacy(fs2);
|
|
657
|
+
ReadStream = legStreams.ReadStream;
|
|
658
|
+
WriteStream = legStreams.WriteStream;
|
|
659
|
+
}
|
|
660
|
+
var fs$ReadStream = fs2.ReadStream;
|
|
661
|
+
if (fs$ReadStream) {
|
|
662
|
+
ReadStream.prototype = Object.create(fs$ReadStream.prototype);
|
|
663
|
+
ReadStream.prototype.open = ReadStream$open;
|
|
664
|
+
}
|
|
665
|
+
var fs$WriteStream = fs2.WriteStream;
|
|
666
|
+
if (fs$WriteStream) {
|
|
667
|
+
WriteStream.prototype = Object.create(fs$WriteStream.prototype);
|
|
668
|
+
WriteStream.prototype.open = WriteStream$open;
|
|
669
|
+
}
|
|
670
|
+
Object.defineProperty(fs2, "ReadStream", {
|
|
671
|
+
get: function() {
|
|
672
|
+
return ReadStream;
|
|
673
|
+
},
|
|
674
|
+
set: function(val) {
|
|
675
|
+
ReadStream = val;
|
|
676
|
+
},
|
|
677
|
+
enumerable: true,
|
|
678
|
+
configurable: true
|
|
679
|
+
});
|
|
680
|
+
Object.defineProperty(fs2, "WriteStream", {
|
|
681
|
+
get: function() {
|
|
682
|
+
return WriteStream;
|
|
683
|
+
},
|
|
684
|
+
set: function(val) {
|
|
685
|
+
WriteStream = val;
|
|
686
|
+
},
|
|
687
|
+
enumerable: true,
|
|
688
|
+
configurable: true
|
|
689
|
+
});
|
|
690
|
+
var FileReadStream = ReadStream;
|
|
691
|
+
Object.defineProperty(fs2, "FileReadStream", {
|
|
692
|
+
get: function() {
|
|
693
|
+
return FileReadStream;
|
|
694
|
+
},
|
|
695
|
+
set: function(val) {
|
|
696
|
+
FileReadStream = val;
|
|
697
|
+
},
|
|
698
|
+
enumerable: true,
|
|
699
|
+
configurable: true
|
|
700
|
+
});
|
|
701
|
+
var FileWriteStream = WriteStream;
|
|
702
|
+
Object.defineProperty(fs2, "FileWriteStream", {
|
|
703
|
+
get: function() {
|
|
704
|
+
return FileWriteStream;
|
|
705
|
+
},
|
|
706
|
+
set: function(val) {
|
|
707
|
+
FileWriteStream = val;
|
|
708
|
+
},
|
|
709
|
+
enumerable: true,
|
|
710
|
+
configurable: true
|
|
711
|
+
});
|
|
712
|
+
function ReadStream(path, options) {
|
|
713
|
+
if (this instanceof ReadStream)
|
|
714
|
+
return fs$ReadStream.apply(this, arguments), this;
|
|
715
|
+
else
|
|
716
|
+
return ReadStream.apply(Object.create(ReadStream.prototype), arguments);
|
|
717
|
+
}
|
|
718
|
+
function ReadStream$open() {
|
|
719
|
+
var that = this;
|
|
720
|
+
open(that.path, that.flags, that.mode, function(err, fd) {
|
|
721
|
+
if (err) {
|
|
722
|
+
if (that.autoClose)
|
|
723
|
+
that.destroy();
|
|
724
|
+
that.emit("error", err);
|
|
725
|
+
} else {
|
|
726
|
+
that.fd = fd;
|
|
727
|
+
that.emit("open", fd);
|
|
728
|
+
that.read();
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
function WriteStream(path, options) {
|
|
733
|
+
if (this instanceof WriteStream)
|
|
734
|
+
return fs$WriteStream.apply(this, arguments), this;
|
|
735
|
+
else
|
|
736
|
+
return WriteStream.apply(Object.create(WriteStream.prototype), arguments);
|
|
737
|
+
}
|
|
738
|
+
function WriteStream$open() {
|
|
739
|
+
var that = this;
|
|
740
|
+
open(that.path, that.flags, that.mode, function(err, fd) {
|
|
741
|
+
if (err) {
|
|
742
|
+
that.destroy();
|
|
743
|
+
that.emit("error", err);
|
|
744
|
+
} else {
|
|
745
|
+
that.fd = fd;
|
|
746
|
+
that.emit("open", fd);
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
function createReadStream(path, options) {
|
|
751
|
+
return new fs2.ReadStream(path, options);
|
|
752
|
+
}
|
|
753
|
+
function createWriteStream(path, options) {
|
|
754
|
+
return new fs2.WriteStream(path, options);
|
|
755
|
+
}
|
|
756
|
+
var fs$open = fs2.open;
|
|
757
|
+
fs2.open = open;
|
|
758
|
+
function open(path, flags, mode, cb) {
|
|
759
|
+
if (typeof mode === "function")
|
|
760
|
+
cb = mode, mode = null;
|
|
761
|
+
return go$open(path, flags, mode, cb);
|
|
762
|
+
function go$open(path2, flags2, mode2, cb2, startTime) {
|
|
763
|
+
return fs$open(path2, flags2, mode2, function(err, fd) {
|
|
764
|
+
if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
|
|
765
|
+
enqueue([go$open, [path2, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
|
|
766
|
+
else {
|
|
767
|
+
if (typeof cb2 === "function")
|
|
768
|
+
cb2.apply(this, arguments);
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return fs2;
|
|
774
|
+
}
|
|
775
|
+
function enqueue(elem) {
|
|
776
|
+
debug("ENQUEUE", elem[0].name, elem[1]);
|
|
777
|
+
fs[gracefulQueue].push(elem);
|
|
778
|
+
retry();
|
|
779
|
+
}
|
|
780
|
+
var retryTimer;
|
|
781
|
+
function resetQueue() {
|
|
782
|
+
var now = Date.now();
|
|
783
|
+
for (var i = 0;i < fs[gracefulQueue].length; ++i) {
|
|
784
|
+
if (fs[gracefulQueue][i].length > 2) {
|
|
785
|
+
fs[gracefulQueue][i][3] = now;
|
|
786
|
+
fs[gracefulQueue][i][4] = now;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
retry();
|
|
790
|
+
}
|
|
791
|
+
function retry() {
|
|
792
|
+
clearTimeout(retryTimer);
|
|
793
|
+
retryTimer = undefined;
|
|
794
|
+
if (fs[gracefulQueue].length === 0)
|
|
795
|
+
return;
|
|
796
|
+
var elem = fs[gracefulQueue].shift();
|
|
797
|
+
var fn = elem[0];
|
|
798
|
+
var args = elem[1];
|
|
799
|
+
var err = elem[2];
|
|
800
|
+
var startTime = elem[3];
|
|
801
|
+
var lastTime = elem[4];
|
|
802
|
+
if (startTime === undefined) {
|
|
803
|
+
debug("RETRY", fn.name, args);
|
|
804
|
+
fn.apply(null, args);
|
|
805
|
+
} else if (Date.now() - startTime >= 60000) {
|
|
806
|
+
debug("TIMEOUT", fn.name, args);
|
|
807
|
+
var cb = args.pop();
|
|
808
|
+
if (typeof cb === "function")
|
|
809
|
+
cb.call(null, err);
|
|
810
|
+
} else {
|
|
811
|
+
var sinceAttempt = Date.now() - lastTime;
|
|
812
|
+
var sinceStart = Math.max(lastTime - startTime, 1);
|
|
813
|
+
var desiredDelay = Math.min(sinceStart * 1.2, 100);
|
|
814
|
+
if (sinceAttempt >= desiredDelay) {
|
|
815
|
+
debug("RETRY", fn.name, args);
|
|
816
|
+
fn.apply(null, args.concat([startTime]));
|
|
817
|
+
} else {
|
|
818
|
+
fs[gracefulQueue].push(elem);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
if (retryTimer === undefined) {
|
|
822
|
+
retryTimer = setTimeout(retry, 0);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
// node_modules/.bun/retry@0.12.0/node_modules/retry/lib/retry_operation.js
|
|
828
|
+
var require_retry_operation = __commonJS((exports, module) => {
|
|
829
|
+
function RetryOperation(timeouts, options) {
|
|
830
|
+
if (typeof options === "boolean") {
|
|
831
|
+
options = { forever: options };
|
|
832
|
+
}
|
|
833
|
+
this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
|
|
834
|
+
this._timeouts = timeouts;
|
|
835
|
+
this._options = options || {};
|
|
836
|
+
this._maxRetryTime = options && options.maxRetryTime || Infinity;
|
|
837
|
+
this._fn = null;
|
|
838
|
+
this._errors = [];
|
|
839
|
+
this._attempts = 1;
|
|
840
|
+
this._operationTimeout = null;
|
|
841
|
+
this._operationTimeoutCb = null;
|
|
842
|
+
this._timeout = null;
|
|
843
|
+
this._operationStart = null;
|
|
844
|
+
if (this._options.forever) {
|
|
845
|
+
this._cachedTimeouts = this._timeouts.slice(0);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
module.exports = RetryOperation;
|
|
849
|
+
RetryOperation.prototype.reset = function() {
|
|
850
|
+
this._attempts = 1;
|
|
851
|
+
this._timeouts = this._originalTimeouts;
|
|
852
|
+
};
|
|
853
|
+
RetryOperation.prototype.stop = function() {
|
|
854
|
+
if (this._timeout) {
|
|
855
|
+
clearTimeout(this._timeout);
|
|
856
|
+
}
|
|
857
|
+
this._timeouts = [];
|
|
858
|
+
this._cachedTimeouts = null;
|
|
859
|
+
};
|
|
860
|
+
RetryOperation.prototype.retry = function(err) {
|
|
861
|
+
if (this._timeout) {
|
|
862
|
+
clearTimeout(this._timeout);
|
|
863
|
+
}
|
|
864
|
+
if (!err) {
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
var currentTime = new Date().getTime();
|
|
868
|
+
if (err && currentTime - this._operationStart >= this._maxRetryTime) {
|
|
869
|
+
this._errors.unshift(new Error("RetryOperation timeout occurred"));
|
|
870
|
+
return false;
|
|
871
|
+
}
|
|
872
|
+
this._errors.push(err);
|
|
873
|
+
var timeout = this._timeouts.shift();
|
|
874
|
+
if (timeout === undefined) {
|
|
875
|
+
if (this._cachedTimeouts) {
|
|
876
|
+
this._errors.splice(this._errors.length - 1, this._errors.length);
|
|
877
|
+
this._timeouts = this._cachedTimeouts.slice(0);
|
|
878
|
+
timeout = this._timeouts.shift();
|
|
879
|
+
} else {
|
|
880
|
+
return false;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
var self = this;
|
|
884
|
+
var timer = setTimeout(function() {
|
|
885
|
+
self._attempts++;
|
|
886
|
+
if (self._operationTimeoutCb) {
|
|
887
|
+
self._timeout = setTimeout(function() {
|
|
888
|
+
self._operationTimeoutCb(self._attempts);
|
|
889
|
+
}, self._operationTimeout);
|
|
890
|
+
if (self._options.unref) {
|
|
891
|
+
self._timeout.unref();
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
self._fn(self._attempts);
|
|
895
|
+
}, timeout);
|
|
896
|
+
if (this._options.unref) {
|
|
897
|
+
timer.unref();
|
|
898
|
+
}
|
|
899
|
+
return true;
|
|
900
|
+
};
|
|
901
|
+
RetryOperation.prototype.attempt = function(fn, timeoutOps) {
|
|
902
|
+
this._fn = fn;
|
|
903
|
+
if (timeoutOps) {
|
|
904
|
+
if (timeoutOps.timeout) {
|
|
905
|
+
this._operationTimeout = timeoutOps.timeout;
|
|
906
|
+
}
|
|
907
|
+
if (timeoutOps.cb) {
|
|
908
|
+
this._operationTimeoutCb = timeoutOps.cb;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
var self = this;
|
|
912
|
+
if (this._operationTimeoutCb) {
|
|
913
|
+
this._timeout = setTimeout(function() {
|
|
914
|
+
self._operationTimeoutCb();
|
|
915
|
+
}, self._operationTimeout);
|
|
916
|
+
}
|
|
917
|
+
this._operationStart = new Date().getTime();
|
|
918
|
+
this._fn(this._attempts);
|
|
919
|
+
};
|
|
920
|
+
RetryOperation.prototype.try = function(fn) {
|
|
921
|
+
console.log("Using RetryOperation.try() is deprecated");
|
|
922
|
+
this.attempt(fn);
|
|
923
|
+
};
|
|
924
|
+
RetryOperation.prototype.start = function(fn) {
|
|
925
|
+
console.log("Using RetryOperation.start() is deprecated");
|
|
926
|
+
this.attempt(fn);
|
|
927
|
+
};
|
|
928
|
+
RetryOperation.prototype.start = RetryOperation.prototype.try;
|
|
929
|
+
RetryOperation.prototype.errors = function() {
|
|
930
|
+
return this._errors;
|
|
931
|
+
};
|
|
932
|
+
RetryOperation.prototype.attempts = function() {
|
|
933
|
+
return this._attempts;
|
|
934
|
+
};
|
|
935
|
+
RetryOperation.prototype.mainError = function() {
|
|
936
|
+
if (this._errors.length === 0) {
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
var counts = {};
|
|
940
|
+
var mainError = null;
|
|
941
|
+
var mainErrorCount = 0;
|
|
942
|
+
for (var i = 0;i < this._errors.length; i++) {
|
|
943
|
+
var error = this._errors[i];
|
|
944
|
+
var message = error.message;
|
|
945
|
+
var count = (counts[message] || 0) + 1;
|
|
946
|
+
counts[message] = count;
|
|
947
|
+
if (count >= mainErrorCount) {
|
|
948
|
+
mainError = error;
|
|
949
|
+
mainErrorCount = count;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return mainError;
|
|
953
|
+
};
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// node_modules/.bun/retry@0.12.0/node_modules/retry/lib/retry.js
|
|
957
|
+
var require_retry = __commonJS((exports) => {
|
|
958
|
+
var RetryOperation = require_retry_operation();
|
|
959
|
+
exports.operation = function(options) {
|
|
960
|
+
var timeouts = exports.timeouts(options);
|
|
961
|
+
return new RetryOperation(timeouts, {
|
|
962
|
+
forever: options && options.forever,
|
|
963
|
+
unref: options && options.unref,
|
|
964
|
+
maxRetryTime: options && options.maxRetryTime
|
|
965
|
+
});
|
|
966
|
+
};
|
|
967
|
+
exports.timeouts = function(options) {
|
|
968
|
+
if (options instanceof Array) {
|
|
969
|
+
return [].concat(options);
|
|
970
|
+
}
|
|
971
|
+
var opts = {
|
|
972
|
+
retries: 10,
|
|
973
|
+
factor: 2,
|
|
974
|
+
minTimeout: 1 * 1000,
|
|
975
|
+
maxTimeout: Infinity,
|
|
976
|
+
randomize: false
|
|
977
|
+
};
|
|
978
|
+
for (var key in options) {
|
|
979
|
+
opts[key] = options[key];
|
|
980
|
+
}
|
|
981
|
+
if (opts.minTimeout > opts.maxTimeout) {
|
|
982
|
+
throw new Error("minTimeout is greater than maxTimeout");
|
|
983
|
+
}
|
|
984
|
+
var timeouts = [];
|
|
985
|
+
for (var i = 0;i < opts.retries; i++) {
|
|
986
|
+
timeouts.push(this.createTimeout(i, opts));
|
|
987
|
+
}
|
|
988
|
+
if (options && options.forever && !timeouts.length) {
|
|
989
|
+
timeouts.push(this.createTimeout(i, opts));
|
|
990
|
+
}
|
|
991
|
+
timeouts.sort(function(a, b) {
|
|
992
|
+
return a - b;
|
|
993
|
+
});
|
|
994
|
+
return timeouts;
|
|
995
|
+
};
|
|
996
|
+
exports.createTimeout = function(attempt, opts) {
|
|
997
|
+
var random = opts.randomize ? Math.random() + 1 : 1;
|
|
998
|
+
var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
|
|
999
|
+
timeout = Math.min(timeout, opts.maxTimeout);
|
|
1000
|
+
return timeout;
|
|
1001
|
+
};
|
|
1002
|
+
exports.wrap = function(obj, options, methods) {
|
|
1003
|
+
if (options instanceof Array) {
|
|
1004
|
+
methods = options;
|
|
1005
|
+
options = null;
|
|
1006
|
+
}
|
|
1007
|
+
if (!methods) {
|
|
1008
|
+
methods = [];
|
|
1009
|
+
for (var key in obj) {
|
|
1010
|
+
if (typeof obj[key] === "function") {
|
|
1011
|
+
methods.push(key);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
for (var i = 0;i < methods.length; i++) {
|
|
1016
|
+
var method = methods[i];
|
|
1017
|
+
var original = obj[method];
|
|
1018
|
+
obj[method] = function retryWrapper(original2) {
|
|
1019
|
+
var op = exports.operation(options);
|
|
1020
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
1021
|
+
var callback = args.pop();
|
|
1022
|
+
args.push(function(err) {
|
|
1023
|
+
if (op.retry(err)) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (err) {
|
|
1027
|
+
arguments[0] = op.mainError();
|
|
1028
|
+
}
|
|
1029
|
+
callback.apply(this, arguments);
|
|
1030
|
+
});
|
|
1031
|
+
op.attempt(function() {
|
|
1032
|
+
original2.apply(obj, args);
|
|
1033
|
+
});
|
|
1034
|
+
}.bind(obj, original);
|
|
1035
|
+
obj[method].options = options;
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
// node_modules/.bun/signal-exit@3.0.7/node_modules/signal-exit/signals.js
|
|
1041
|
+
var require_signals = __commonJS((exports, module) => {
|
|
1042
|
+
module.exports = [
|
|
1043
|
+
"SIGABRT",
|
|
1044
|
+
"SIGALRM",
|
|
1045
|
+
"SIGHUP",
|
|
1046
|
+
"SIGINT",
|
|
1047
|
+
"SIGTERM"
|
|
1048
|
+
];
|
|
1049
|
+
if (process.platform !== "win32") {
|
|
1050
|
+
module.exports.push("SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
|
|
1051
|
+
}
|
|
1052
|
+
if (process.platform === "linux") {
|
|
1053
|
+
module.exports.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT", "SIGUNUSED");
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
// node_modules/.bun/signal-exit@3.0.7/node_modules/signal-exit/index.js
|
|
1058
|
+
var require_signal_exit = __commonJS((exports, module) => {
|
|
1059
|
+
var process2 = global.process;
|
|
1060
|
+
var processOk = function(process3) {
|
|
1061
|
+
return process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
|
|
1062
|
+
};
|
|
1063
|
+
if (!processOk(process2)) {
|
|
1064
|
+
module.exports = function() {
|
|
1065
|
+
return function() {};
|
|
1066
|
+
};
|
|
1067
|
+
} else {
|
|
1068
|
+
assert = __require("assert");
|
|
1069
|
+
signals = require_signals();
|
|
1070
|
+
isWin = /^win/i.test(process2.platform);
|
|
1071
|
+
EE = __require("events");
|
|
1072
|
+
if (typeof EE !== "function") {
|
|
1073
|
+
EE = EE.EventEmitter;
|
|
1074
|
+
}
|
|
1075
|
+
if (process2.__signal_exit_emitter__) {
|
|
1076
|
+
emitter = process2.__signal_exit_emitter__;
|
|
1077
|
+
} else {
|
|
1078
|
+
emitter = process2.__signal_exit_emitter__ = new EE;
|
|
1079
|
+
emitter.count = 0;
|
|
1080
|
+
emitter.emitted = {};
|
|
1081
|
+
}
|
|
1082
|
+
if (!emitter.infinite) {
|
|
1083
|
+
emitter.setMaxListeners(Infinity);
|
|
1084
|
+
emitter.infinite = true;
|
|
1085
|
+
}
|
|
1086
|
+
module.exports = function(cb, opts) {
|
|
1087
|
+
if (!processOk(global.process)) {
|
|
1088
|
+
return function() {};
|
|
1089
|
+
}
|
|
1090
|
+
assert.equal(typeof cb, "function", "a callback must be provided for exit handler");
|
|
1091
|
+
if (loaded === false) {
|
|
1092
|
+
load();
|
|
1093
|
+
}
|
|
1094
|
+
var ev = "exit";
|
|
1095
|
+
if (opts && opts.alwaysLast) {
|
|
1096
|
+
ev = "afterexit";
|
|
1097
|
+
}
|
|
1098
|
+
var remove = function() {
|
|
1099
|
+
emitter.removeListener(ev, cb);
|
|
1100
|
+
if (emitter.listeners("exit").length === 0 && emitter.listeners("afterexit").length === 0) {
|
|
1101
|
+
unload();
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
emitter.on(ev, cb);
|
|
1105
|
+
return remove;
|
|
1106
|
+
};
|
|
1107
|
+
unload = function unload2() {
|
|
1108
|
+
if (!loaded || !processOk(global.process)) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
loaded = false;
|
|
1112
|
+
signals.forEach(function(sig) {
|
|
1113
|
+
try {
|
|
1114
|
+
process2.removeListener(sig, sigListeners[sig]);
|
|
1115
|
+
} catch (er) {}
|
|
1116
|
+
});
|
|
1117
|
+
process2.emit = originalProcessEmit;
|
|
1118
|
+
process2.reallyExit = originalProcessReallyExit;
|
|
1119
|
+
emitter.count -= 1;
|
|
1120
|
+
};
|
|
1121
|
+
module.exports.unload = unload;
|
|
1122
|
+
emit = function emit2(event, code, signal) {
|
|
1123
|
+
if (emitter.emitted[event]) {
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
emitter.emitted[event] = true;
|
|
1127
|
+
emitter.emit(event, code, signal);
|
|
1128
|
+
};
|
|
1129
|
+
sigListeners = {};
|
|
1130
|
+
signals.forEach(function(sig) {
|
|
1131
|
+
sigListeners[sig] = function listener() {
|
|
1132
|
+
if (!processOk(global.process)) {
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
var listeners = process2.listeners(sig);
|
|
1136
|
+
if (listeners.length === emitter.count) {
|
|
1137
|
+
unload();
|
|
1138
|
+
emit("exit", null, sig);
|
|
1139
|
+
emit("afterexit", null, sig);
|
|
1140
|
+
if (isWin && sig === "SIGHUP") {
|
|
1141
|
+
sig = "SIGINT";
|
|
1142
|
+
}
|
|
1143
|
+
process2.kill(process2.pid, sig);
|
|
1144
|
+
}
|
|
1145
|
+
};
|
|
1146
|
+
});
|
|
1147
|
+
module.exports.signals = function() {
|
|
1148
|
+
return signals;
|
|
1149
|
+
};
|
|
1150
|
+
loaded = false;
|
|
1151
|
+
load = function load2() {
|
|
1152
|
+
if (loaded || !processOk(global.process)) {
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
loaded = true;
|
|
1156
|
+
emitter.count += 1;
|
|
1157
|
+
signals = signals.filter(function(sig) {
|
|
1158
|
+
try {
|
|
1159
|
+
process2.on(sig, sigListeners[sig]);
|
|
1160
|
+
return true;
|
|
1161
|
+
} catch (er) {
|
|
1162
|
+
return false;
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
process2.emit = processEmit;
|
|
1166
|
+
process2.reallyExit = processReallyExit;
|
|
1167
|
+
};
|
|
1168
|
+
module.exports.load = load;
|
|
1169
|
+
originalProcessReallyExit = process2.reallyExit;
|
|
1170
|
+
processReallyExit = function processReallyExit2(code) {
|
|
1171
|
+
if (!processOk(global.process)) {
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
process2.exitCode = code || 0;
|
|
1175
|
+
emit("exit", process2.exitCode, null);
|
|
1176
|
+
emit("afterexit", process2.exitCode, null);
|
|
1177
|
+
originalProcessReallyExit.call(process2, process2.exitCode);
|
|
1178
|
+
};
|
|
1179
|
+
originalProcessEmit = process2.emit;
|
|
1180
|
+
processEmit = function processEmit2(ev, arg) {
|
|
1181
|
+
if (ev === "exit" && processOk(global.process)) {
|
|
1182
|
+
if (arg !== undefined) {
|
|
1183
|
+
process2.exitCode = arg;
|
|
1184
|
+
}
|
|
1185
|
+
var ret = originalProcessEmit.apply(this, arguments);
|
|
1186
|
+
emit("exit", process2.exitCode, null);
|
|
1187
|
+
emit("afterexit", process2.exitCode, null);
|
|
1188
|
+
return ret;
|
|
1189
|
+
} else {
|
|
1190
|
+
return originalProcessEmit.apply(this, arguments);
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
var assert;
|
|
1195
|
+
var signals;
|
|
1196
|
+
var isWin;
|
|
1197
|
+
var EE;
|
|
1198
|
+
var emitter;
|
|
1199
|
+
var unload;
|
|
1200
|
+
var emit;
|
|
1201
|
+
var sigListeners;
|
|
1202
|
+
var loaded;
|
|
1203
|
+
var load;
|
|
1204
|
+
var originalProcessReallyExit;
|
|
1205
|
+
var processReallyExit;
|
|
1206
|
+
var originalProcessEmit;
|
|
1207
|
+
var processEmit;
|
|
1208
|
+
});
|
|
1209
|
+
|
|
1210
|
+
// node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/mtime-precision.js
|
|
1211
|
+
var require_mtime_precision = __commonJS((exports, module) => {
|
|
1212
|
+
var cacheSymbol = Symbol();
|
|
1213
|
+
function probe(file, fs, callback) {
|
|
1214
|
+
const cachedPrecision = fs[cacheSymbol];
|
|
1215
|
+
if (cachedPrecision) {
|
|
1216
|
+
return fs.stat(file, (err, stat) => {
|
|
1217
|
+
if (err) {
|
|
1218
|
+
return callback(err);
|
|
1219
|
+
}
|
|
1220
|
+
callback(null, stat.mtime, cachedPrecision);
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
const mtime = new Date(Math.ceil(Date.now() / 1000) * 1000 + 5);
|
|
1224
|
+
fs.utimes(file, mtime, mtime, (err) => {
|
|
1225
|
+
if (err) {
|
|
1226
|
+
return callback(err);
|
|
1227
|
+
}
|
|
1228
|
+
fs.stat(file, (err2, stat) => {
|
|
1229
|
+
if (err2) {
|
|
1230
|
+
return callback(err2);
|
|
1231
|
+
}
|
|
1232
|
+
const precision = stat.mtime.getTime() % 1000 === 0 ? "s" : "ms";
|
|
1233
|
+
Object.defineProperty(fs, cacheSymbol, { value: precision });
|
|
1234
|
+
callback(null, stat.mtime, precision);
|
|
1235
|
+
});
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
function getMtime(precision) {
|
|
1239
|
+
let now = Date.now();
|
|
1240
|
+
if (precision === "s") {
|
|
1241
|
+
now = Math.ceil(now / 1000) * 1000;
|
|
1242
|
+
}
|
|
1243
|
+
return new Date(now);
|
|
1244
|
+
}
|
|
1245
|
+
exports.probe = probe;
|
|
1246
|
+
exports.getMtime = getMtime;
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
// node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js
|
|
1250
|
+
var require_lockfile = __commonJS((exports, module) => {
|
|
1251
|
+
var path = __require("path");
|
|
1252
|
+
var fs = require_graceful_fs();
|
|
1253
|
+
var retry = require_retry();
|
|
1254
|
+
var onExit = require_signal_exit();
|
|
1255
|
+
var mtimePrecision = require_mtime_precision();
|
|
1256
|
+
var locks = {};
|
|
1257
|
+
function getLockFile(file, options) {
|
|
1258
|
+
return options.lockfilePath || `${file}.lock`;
|
|
1259
|
+
}
|
|
1260
|
+
function resolveCanonicalPath(file, options, callback) {
|
|
1261
|
+
if (!options.realpath) {
|
|
1262
|
+
return callback(null, path.resolve(file));
|
|
1263
|
+
}
|
|
1264
|
+
options.fs.realpath(file, callback);
|
|
1265
|
+
}
|
|
1266
|
+
function acquireLock(file, options, callback) {
|
|
1267
|
+
const lockfilePath = getLockFile(file, options);
|
|
1268
|
+
options.fs.mkdir(lockfilePath, (err) => {
|
|
1269
|
+
if (!err) {
|
|
1270
|
+
return mtimePrecision.probe(lockfilePath, options.fs, (err2, mtime, mtimePrecision2) => {
|
|
1271
|
+
if (err2) {
|
|
1272
|
+
options.fs.rmdir(lockfilePath, () => {});
|
|
1273
|
+
return callback(err2);
|
|
1274
|
+
}
|
|
1275
|
+
callback(null, mtime, mtimePrecision2);
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
if (err.code !== "EEXIST") {
|
|
1279
|
+
return callback(err);
|
|
1280
|
+
}
|
|
1281
|
+
if (options.stale <= 0) {
|
|
1282
|
+
return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file }));
|
|
1283
|
+
}
|
|
1284
|
+
options.fs.stat(lockfilePath, (err2, stat) => {
|
|
1285
|
+
if (err2) {
|
|
1286
|
+
if (err2.code === "ENOENT") {
|
|
1287
|
+
return acquireLock(file, { ...options, stale: 0 }, callback);
|
|
1288
|
+
}
|
|
1289
|
+
return callback(err2);
|
|
1290
|
+
}
|
|
1291
|
+
if (!isLockStale(stat, options)) {
|
|
1292
|
+
return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file }));
|
|
1293
|
+
}
|
|
1294
|
+
removeLock(file, options, (err3) => {
|
|
1295
|
+
if (err3) {
|
|
1296
|
+
return callback(err3);
|
|
1297
|
+
}
|
|
1298
|
+
acquireLock(file, { ...options, stale: 0 }, callback);
|
|
1299
|
+
});
|
|
1300
|
+
});
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
function isLockStale(stat, options) {
|
|
1304
|
+
return stat.mtime.getTime() < Date.now() - options.stale;
|
|
1305
|
+
}
|
|
1306
|
+
function removeLock(file, options, callback) {
|
|
1307
|
+
options.fs.rmdir(getLockFile(file, options), (err) => {
|
|
1308
|
+
if (err && err.code !== "ENOENT") {
|
|
1309
|
+
return callback(err);
|
|
1310
|
+
}
|
|
1311
|
+
callback();
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
function updateLock(file, options) {
|
|
1315
|
+
const lock2 = locks[file];
|
|
1316
|
+
if (lock2.updateTimeout) {
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
lock2.updateDelay = lock2.updateDelay || options.update;
|
|
1320
|
+
lock2.updateTimeout = setTimeout(() => {
|
|
1321
|
+
lock2.updateTimeout = null;
|
|
1322
|
+
options.fs.stat(lock2.lockfilePath, (err, stat) => {
|
|
1323
|
+
const isOverThreshold = lock2.lastUpdate + options.stale < Date.now();
|
|
1324
|
+
if (err) {
|
|
1325
|
+
if (err.code === "ENOENT" || isOverThreshold) {
|
|
1326
|
+
return setLockAsCompromised(file, lock2, Object.assign(err, { code: "ECOMPROMISED" }));
|
|
1327
|
+
}
|
|
1328
|
+
lock2.updateDelay = 1000;
|
|
1329
|
+
return updateLock(file, options);
|
|
1330
|
+
}
|
|
1331
|
+
const isMtimeOurs = lock2.mtime.getTime() === stat.mtime.getTime();
|
|
1332
|
+
if (!isMtimeOurs) {
|
|
1333
|
+
return setLockAsCompromised(file, lock2, Object.assign(new Error("Unable to update lock within the stale threshold"), { code: "ECOMPROMISED" }));
|
|
1334
|
+
}
|
|
1335
|
+
const mtime = mtimePrecision.getMtime(lock2.mtimePrecision);
|
|
1336
|
+
options.fs.utimes(lock2.lockfilePath, mtime, mtime, (err2) => {
|
|
1337
|
+
const isOverThreshold2 = lock2.lastUpdate + options.stale < Date.now();
|
|
1338
|
+
if (lock2.released) {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
if (err2) {
|
|
1342
|
+
if (err2.code === "ENOENT" || isOverThreshold2) {
|
|
1343
|
+
return setLockAsCompromised(file, lock2, Object.assign(err2, { code: "ECOMPROMISED" }));
|
|
1344
|
+
}
|
|
1345
|
+
lock2.updateDelay = 1000;
|
|
1346
|
+
return updateLock(file, options);
|
|
1347
|
+
}
|
|
1348
|
+
lock2.mtime = mtime;
|
|
1349
|
+
lock2.lastUpdate = Date.now();
|
|
1350
|
+
lock2.updateDelay = null;
|
|
1351
|
+
updateLock(file, options);
|
|
1352
|
+
});
|
|
1353
|
+
});
|
|
1354
|
+
}, lock2.updateDelay);
|
|
1355
|
+
if (lock2.updateTimeout.unref) {
|
|
1356
|
+
lock2.updateTimeout.unref();
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
function setLockAsCompromised(file, lock2, err) {
|
|
1360
|
+
lock2.released = true;
|
|
1361
|
+
if (lock2.updateTimeout) {
|
|
1362
|
+
clearTimeout(lock2.updateTimeout);
|
|
1363
|
+
}
|
|
1364
|
+
if (locks[file] === lock2) {
|
|
1365
|
+
delete locks[file];
|
|
1366
|
+
}
|
|
1367
|
+
lock2.options.onCompromised(err);
|
|
1368
|
+
}
|
|
1369
|
+
function lock(file, options, callback) {
|
|
1370
|
+
options = {
|
|
1371
|
+
stale: 1e4,
|
|
1372
|
+
update: null,
|
|
1373
|
+
realpath: true,
|
|
1374
|
+
retries: 0,
|
|
1375
|
+
fs,
|
|
1376
|
+
onCompromised: (err) => {
|
|
1377
|
+
throw err;
|
|
1378
|
+
},
|
|
1379
|
+
...options
|
|
1380
|
+
};
|
|
1381
|
+
options.retries = options.retries || 0;
|
|
1382
|
+
options.retries = typeof options.retries === "number" ? { retries: options.retries } : options.retries;
|
|
1383
|
+
options.stale = Math.max(options.stale || 0, 2000);
|
|
1384
|
+
options.update = options.update == null ? options.stale / 2 : options.update || 0;
|
|
1385
|
+
options.update = Math.max(Math.min(options.update, options.stale / 2), 1000);
|
|
1386
|
+
resolveCanonicalPath(file, options, (err, file2) => {
|
|
1387
|
+
if (err) {
|
|
1388
|
+
return callback(err);
|
|
1389
|
+
}
|
|
1390
|
+
const operation = retry.operation(options.retries);
|
|
1391
|
+
operation.attempt(() => {
|
|
1392
|
+
acquireLock(file2, options, (err2, mtime, mtimePrecision2) => {
|
|
1393
|
+
if (operation.retry(err2)) {
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
if (err2) {
|
|
1397
|
+
return callback(operation.mainError());
|
|
1398
|
+
}
|
|
1399
|
+
const lock2 = locks[file2] = {
|
|
1400
|
+
lockfilePath: getLockFile(file2, options),
|
|
1401
|
+
mtime,
|
|
1402
|
+
mtimePrecision: mtimePrecision2,
|
|
1403
|
+
options,
|
|
1404
|
+
lastUpdate: Date.now()
|
|
1405
|
+
};
|
|
1406
|
+
updateLock(file2, options);
|
|
1407
|
+
callback(null, (releasedCallback) => {
|
|
1408
|
+
if (lock2.released) {
|
|
1409
|
+
return releasedCallback && releasedCallback(Object.assign(new Error("Lock is already released"), { code: "ERELEASED" }));
|
|
1410
|
+
}
|
|
1411
|
+
unlock(file2, { ...options, realpath: false }, releasedCallback);
|
|
1412
|
+
});
|
|
1413
|
+
});
|
|
1414
|
+
});
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
function unlock(file, options, callback) {
|
|
1418
|
+
options = {
|
|
1419
|
+
fs,
|
|
1420
|
+
realpath: true,
|
|
1421
|
+
...options
|
|
1422
|
+
};
|
|
1423
|
+
resolveCanonicalPath(file, options, (err, file2) => {
|
|
1424
|
+
if (err) {
|
|
1425
|
+
return callback(err);
|
|
1426
|
+
}
|
|
1427
|
+
const lock2 = locks[file2];
|
|
1428
|
+
if (!lock2) {
|
|
1429
|
+
return callback(Object.assign(new Error("Lock is not acquired/owned by you"), { code: "ENOTACQUIRED" }));
|
|
1430
|
+
}
|
|
1431
|
+
lock2.updateTimeout && clearTimeout(lock2.updateTimeout);
|
|
1432
|
+
lock2.released = true;
|
|
1433
|
+
delete locks[file2];
|
|
1434
|
+
removeLock(file2, options, callback);
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
function check(file, options, callback) {
|
|
1438
|
+
options = {
|
|
1439
|
+
stale: 1e4,
|
|
1440
|
+
realpath: true,
|
|
1441
|
+
fs,
|
|
1442
|
+
...options
|
|
1443
|
+
};
|
|
1444
|
+
options.stale = Math.max(options.stale || 0, 2000);
|
|
1445
|
+
resolveCanonicalPath(file, options, (err, file2) => {
|
|
1446
|
+
if (err) {
|
|
1447
|
+
return callback(err);
|
|
1448
|
+
}
|
|
1449
|
+
options.fs.stat(getLockFile(file2, options), (err2, stat) => {
|
|
1450
|
+
if (err2) {
|
|
1451
|
+
return err2.code === "ENOENT" ? callback(null, false) : callback(err2);
|
|
1452
|
+
}
|
|
1453
|
+
return callback(null, !isLockStale(stat, options));
|
|
1454
|
+
});
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
function getLocks() {
|
|
1458
|
+
return locks;
|
|
1459
|
+
}
|
|
1460
|
+
onExit(() => {
|
|
1461
|
+
for (const file in locks) {
|
|
1462
|
+
const options = locks[file].options;
|
|
1463
|
+
try {
|
|
1464
|
+
options.fs.rmdirSync(getLockFile(file, options));
|
|
1465
|
+
} catch (e) {}
|
|
1466
|
+
}
|
|
1467
|
+
});
|
|
1468
|
+
exports.lock = lock;
|
|
1469
|
+
exports.unlock = unlock;
|
|
1470
|
+
exports.check = check;
|
|
1471
|
+
exports.getLocks = getLocks;
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
// node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/adapter.js
|
|
1475
|
+
var require_adapter = __commonJS((exports, module) => {
|
|
1476
|
+
var fs = require_graceful_fs();
|
|
1477
|
+
function createSyncFs(fs2) {
|
|
1478
|
+
const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
|
|
1479
|
+
const newFs = { ...fs2 };
|
|
1480
|
+
methods.forEach((method) => {
|
|
1481
|
+
newFs[method] = (...args) => {
|
|
1482
|
+
const callback = args.pop();
|
|
1483
|
+
let ret;
|
|
1484
|
+
try {
|
|
1485
|
+
ret = fs2[`${method}Sync`](...args);
|
|
1486
|
+
} catch (err) {
|
|
1487
|
+
return callback(err);
|
|
1488
|
+
}
|
|
1489
|
+
callback(null, ret);
|
|
1490
|
+
};
|
|
1491
|
+
});
|
|
1492
|
+
return newFs;
|
|
1493
|
+
}
|
|
1494
|
+
function toPromise(method) {
|
|
1495
|
+
return (...args) => new Promise((resolve, reject) => {
|
|
1496
|
+
args.push((err, result) => {
|
|
1497
|
+
if (err) {
|
|
1498
|
+
reject(err);
|
|
1499
|
+
} else {
|
|
1500
|
+
resolve(result);
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
method(...args);
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
function toSync(method) {
|
|
1507
|
+
return (...args) => {
|
|
1508
|
+
let err;
|
|
1509
|
+
let result;
|
|
1510
|
+
args.push((_err, _result) => {
|
|
1511
|
+
err = _err;
|
|
1512
|
+
result = _result;
|
|
1513
|
+
});
|
|
1514
|
+
method(...args);
|
|
1515
|
+
if (err) {
|
|
1516
|
+
throw err;
|
|
1517
|
+
}
|
|
1518
|
+
return result;
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
function toSyncOptions(options) {
|
|
1522
|
+
options = { ...options };
|
|
1523
|
+
options.fs = createSyncFs(options.fs || fs);
|
|
1524
|
+
if (typeof options.retries === "number" && options.retries > 0 || options.retries && typeof options.retries.retries === "number" && options.retries.retries > 0) {
|
|
1525
|
+
throw Object.assign(new Error("Cannot use retries with the sync api"), { code: "ESYNC" });
|
|
1526
|
+
}
|
|
1527
|
+
return options;
|
|
1528
|
+
}
|
|
1529
|
+
module.exports = {
|
|
1530
|
+
toPromise,
|
|
1531
|
+
toSync,
|
|
1532
|
+
toSyncOptions
|
|
1533
|
+
};
|
|
1534
|
+
});
|
|
1535
|
+
|
|
1536
|
+
// node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/index.js
|
|
1537
|
+
var require_proper_lockfile = __commonJS((exports, module) => {
|
|
1538
|
+
var lockfile = require_lockfile();
|
|
1539
|
+
var { toPromise, toSync, toSyncOptions } = require_adapter();
|
|
1540
|
+
async function lock(file, options) {
|
|
1541
|
+
const release = await toPromise(lockfile.lock)(file, options);
|
|
1542
|
+
return toPromise(release);
|
|
1543
|
+
}
|
|
1544
|
+
function lockSync(file, options) {
|
|
1545
|
+
const release = toSync(lockfile.lock)(file, toSyncOptions(options));
|
|
1546
|
+
return toSync(release);
|
|
1547
|
+
}
|
|
1548
|
+
function unlock(file, options) {
|
|
1549
|
+
return toPromise(lockfile.unlock)(file, options);
|
|
1550
|
+
}
|
|
1551
|
+
function unlockSync(file, options) {
|
|
1552
|
+
return toSync(lockfile.unlock)(file, toSyncOptions(options));
|
|
1553
|
+
}
|
|
1554
|
+
function check(file, options) {
|
|
1555
|
+
return toPromise(lockfile.check)(file, options);
|
|
1556
|
+
}
|
|
1557
|
+
function checkSync(file, options) {
|
|
1558
|
+
return toSync(lockfile.check)(file, toSyncOptions(options));
|
|
1559
|
+
}
|
|
1560
|
+
module.exports = lock;
|
|
1561
|
+
module.exports.lock = lock;
|
|
1562
|
+
module.exports.unlock = unlock;
|
|
1563
|
+
module.exports.lockSync = lockSync;
|
|
1564
|
+
module.exports.unlockSync = unlockSync;
|
|
1565
|
+
module.exports.check = check;
|
|
1566
|
+
module.exports.checkSync = checkSync;
|
|
1567
|
+
});
|
|
19
1568
|
|
|
20
1569
|
// node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
|
|
21
1570
|
var require_identity = __commonJS((exports) => {
|
|
@@ -11224,7 +12773,7 @@ var init_schema = __esm(() => {
|
|
|
11224
12773
|
}).optional()
|
|
11225
12774
|
});
|
|
11226
12775
|
VaultConfigSchema = exports_external.object({
|
|
11227
|
-
path: exports_external.string().default("~/.switchroom/vault.enc").describe("Path to encrypted vault file"),
|
|
12776
|
+
path: exports_external.string().default("~/.switchroom/vault/vault.enc").describe("Path to encrypted vault file. v0.7.12+ canonical default is " + "`~/.switchroom/vault/vault.enc` (parent-dir bind-mount enables " + "atomic-rename writes from the broker container). Older installs " + "with `~/.switchroom/vault.enc` are auto-migrated on `switchroom " + "apply`; the legacy path becomes a symlink for v0.7.10/.11 CLI " + "compatibility (sunset in v0.7.14)."),
|
|
11228
12777
|
broker: exports_external.object({
|
|
11229
12778
|
socket: exports_external.string().default("~/.switchroom/vault-broker.sock").describe("Unix domain socket path for the vault-broker daemon"),
|
|
11230
12779
|
enabled: exports_external.boolean().default(true).describe("Whether to start the vault-broker daemon on agent launch"),
|
|
@@ -11257,8 +12806,8 @@ var init_schema = __esm(() => {
|
|
|
11257
12806
|
});
|
|
11258
12807
|
|
|
11259
12808
|
// src/config/paths.ts
|
|
11260
|
-
import { existsSync as
|
|
11261
|
-
import { resolve } from "node:path";
|
|
12809
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
12810
|
+
import { resolve as resolve2 } from "node:path";
|
|
11262
12811
|
function home() {
|
|
11263
12812
|
return process.env.HOME ?? "/root";
|
|
11264
12813
|
}
|
|
@@ -11266,18 +12815,18 @@ function resolveDualPath(pathStr) {
|
|
|
11266
12815
|
const h = home();
|
|
11267
12816
|
if (pathStr.startsWith("~/")) {
|
|
11268
12817
|
const rest = pathStr.slice(2);
|
|
11269
|
-
const absolute =
|
|
12818
|
+
const absolute = resolve2(h, rest);
|
|
11270
12819
|
if (rest.startsWith(`${DEFAULT_STATE_DIR}/`)) {
|
|
11271
12820
|
const frag = rest.slice(DEFAULT_STATE_DIR.length + 1);
|
|
11272
|
-
if (!
|
|
11273
|
-
const legacy =
|
|
11274
|
-
if (
|
|
12821
|
+
if (!existsSync3(absolute)) {
|
|
12822
|
+
const legacy = resolve2(h, LEGACY_STATE_DIR, frag);
|
|
12823
|
+
if (existsSync3(legacy))
|
|
11275
12824
|
return legacy;
|
|
11276
12825
|
}
|
|
11277
12826
|
}
|
|
11278
12827
|
return absolute;
|
|
11279
12828
|
}
|
|
11280
|
-
return
|
|
12829
|
+
return resolve2(pathStr);
|
|
11281
12830
|
}
|
|
11282
12831
|
var DEFAULT_STATE_DIR = ".switchroom", LEGACY_STATE_DIR = ".clerk";
|
|
11283
12832
|
var init_paths = () => {};
|
|
@@ -11291,9 +12840,9 @@ __export(exports_loader, {
|
|
|
11291
12840
|
findConfigFile: () => findConfigFile,
|
|
11292
12841
|
ConfigError: () => ConfigError
|
|
11293
12842
|
});
|
|
11294
|
-
import { readFileSync as
|
|
12843
|
+
import { readFileSync as readFileSync3, existsSync as existsSync4 } from "node:fs";
|
|
11295
12844
|
import { homedir } from "node:os";
|
|
11296
|
-
import { resolve as
|
|
12845
|
+
import { resolve as resolve3 } from "node:path";
|
|
11297
12846
|
function formatZodErrors(error) {
|
|
11298
12847
|
return error.errors.map((e) => {
|
|
11299
12848
|
const path = e.path.join(".");
|
|
@@ -11303,24 +12852,24 @@ function formatZodErrors(error) {
|
|
|
11303
12852
|
function findConfigFile(startDir) {
|
|
11304
12853
|
const envPath = process.env.SWITCHROOM_CONFIG;
|
|
11305
12854
|
const home2 = homedir();
|
|
11306
|
-
const userDir =
|
|
12855
|
+
const userDir = resolve3(home2, ".switchroom");
|
|
11307
12856
|
const searchPaths = [
|
|
11308
|
-
envPath ?
|
|
11309
|
-
startDir ?
|
|
11310
|
-
startDir ?
|
|
11311
|
-
startDir ?
|
|
11312
|
-
startDir ?
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
12857
|
+
envPath ? resolve3(envPath) : null,
|
|
12858
|
+
startDir ? resolve3(startDir, "switchroom.yaml") : null,
|
|
12859
|
+
startDir ? resolve3(startDir, "switchroom.yml") : null,
|
|
12860
|
+
startDir ? resolve3(startDir, "clerk.yaml") : null,
|
|
12861
|
+
startDir ? resolve3(startDir, "clerk.yml") : null,
|
|
12862
|
+
resolve3(process.cwd(), "switchroom.yaml"),
|
|
12863
|
+
resolve3(process.cwd(), "switchroom.yml"),
|
|
12864
|
+
resolve3(process.cwd(), "clerk.yaml"),
|
|
12865
|
+
resolve3(process.cwd(), "clerk.yml"),
|
|
12866
|
+
resolve3(userDir, "switchroom.yaml"),
|
|
12867
|
+
resolve3(userDir, "switchroom.yml"),
|
|
12868
|
+
resolve3(userDir, "clerk.yaml"),
|
|
12869
|
+
resolve3(userDir, "clerk.yml")
|
|
11321
12870
|
].filter(Boolean);
|
|
11322
12871
|
for (const path of searchPaths) {
|
|
11323
|
-
if (
|
|
12872
|
+
if (existsSync4(path)) {
|
|
11324
12873
|
return path;
|
|
11325
12874
|
}
|
|
11326
12875
|
}
|
|
@@ -11328,12 +12877,12 @@ function findConfigFile(startDir) {
|
|
|
11328
12877
|
}
|
|
11329
12878
|
function loadConfig(configPath) {
|
|
11330
12879
|
const filePath = configPath ?? findConfigFile();
|
|
11331
|
-
if (!
|
|
12880
|
+
if (!existsSync4(filePath)) {
|
|
11332
12881
|
throw new ConfigError(`Config file not found: ${filePath}`);
|
|
11333
12882
|
}
|
|
11334
12883
|
let raw;
|
|
11335
12884
|
try {
|
|
11336
|
-
raw =
|
|
12885
|
+
raw = readFileSync3(filePath, "utf-8");
|
|
11337
12886
|
} catch (err) {
|
|
11338
12887
|
throw new ConfigError(`Failed to read config file: ${filePath}`, [
|
|
11339
12888
|
` ${err.message}`
|
|
@@ -11385,7 +12934,7 @@ var init_loader = __esm(() => {
|
|
|
11385
12934
|
|
|
11386
12935
|
// src/vault/broker/server.ts
|
|
11387
12936
|
import * as net from "node:net";
|
|
11388
|
-
import { mkdirSync as
|
|
12937
|
+
import { mkdirSync as mkdirSync5, chmodSync as chmodSync4, chownSync, existsSync as existsSync6, readFileSync as readFileSync6, readdirSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3, renameSync as renameSync3 } from "node:fs";
|
|
11389
12938
|
|
|
11390
12939
|
// src/agents/compose.ts
|
|
11391
12940
|
import { createHash } from "node:crypto";
|
|
@@ -11676,11 +13225,12 @@ function allocateAgentUid(name) {
|
|
|
11676
13225
|
}
|
|
11677
13226
|
|
|
11678
13227
|
// src/vault/broker/server.ts
|
|
11679
|
-
import { dirname as
|
|
13228
|
+
import { dirname as dirname4, resolve as resolve4, basename as basename3 } from "node:path";
|
|
11680
13229
|
import * as os3 from "node:os";
|
|
11681
13230
|
import * as path3 from "node:path";
|
|
11682
13231
|
|
|
11683
13232
|
// src/vault/vault.ts
|
|
13233
|
+
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
11684
13234
|
import { randomBytes, scryptSync, createCipheriv, createDecipheriv } from "node:crypto";
|
|
11685
13235
|
import {
|
|
11686
13236
|
readFileSync,
|
|
@@ -11690,10 +13240,34 @@ import {
|
|
|
11690
13240
|
mkdirSync,
|
|
11691
13241
|
unlinkSync
|
|
11692
13242
|
} from "node:fs";
|
|
13243
|
+
import { dirname, basename, resolve } from "node:path";
|
|
13244
|
+
var KNOWN_VAULT_ARTIFACT_NAMES = new Set([
|
|
13245
|
+
"vault.enc",
|
|
13246
|
+
"vault.enc.bak",
|
|
13247
|
+
"vault.enc.tmp",
|
|
13248
|
+
"vault.enc.lock",
|
|
13249
|
+
".vault.enc.symlink-tmp"
|
|
13250
|
+
]);
|
|
13251
|
+
var SAVE_VAULT_LOCK_RETRY_MS = 5000;
|
|
11693
13252
|
var SCRYPT_N = 32768;
|
|
11694
13253
|
var SCRYPT_R = 8;
|
|
11695
13254
|
var SCRYPT_P = 1;
|
|
11696
13255
|
var SCRYPT_MAXMEM = 128 * 1024 * 1024;
|
|
13256
|
+
function atomicWriteFileSync(path, data, mode) {
|
|
13257
|
+
const dir = dirname(resolve(path));
|
|
13258
|
+
const tmp = resolve(dir, `.${basename(path)}.${process.pid}.${Date.now()}.tmp`);
|
|
13259
|
+
try {
|
|
13260
|
+
writeFileSync(tmp, data, { encoding: "utf8", mode });
|
|
13261
|
+
renameSync(tmp, path);
|
|
13262
|
+
} catch (err) {
|
|
13263
|
+
try {
|
|
13264
|
+
if (existsSync(tmp))
|
|
13265
|
+
unlinkSync(tmp);
|
|
13266
|
+
} catch {}
|
|
13267
|
+
throw err;
|
|
13268
|
+
}
|
|
13269
|
+
}
|
|
13270
|
+
|
|
11697
13271
|
class VaultError extends Error {
|
|
11698
13272
|
constructor(message) {
|
|
11699
13273
|
super(message);
|
|
@@ -11709,6 +13283,17 @@ function deriveKey(passphrase, salt, params = { N: SCRYPT_N, r: SCRYPT_R, p: SCR
|
|
|
11709
13283
|
maxmem: SCRYPT_MAXMEM
|
|
11710
13284
|
});
|
|
11711
13285
|
}
|
|
13286
|
+
function encrypt(key, plaintext) {
|
|
13287
|
+
const iv = randomBytes(12);
|
|
13288
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
13289
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
13290
|
+
const tag = cipher.getAuthTag();
|
|
13291
|
+
return {
|
|
13292
|
+
iv: iv.toString("hex"),
|
|
13293
|
+
data: encrypted.toString("hex"),
|
|
13294
|
+
tag: tag.toString("hex")
|
|
13295
|
+
};
|
|
13296
|
+
}
|
|
11712
13297
|
function decrypt(key, iv, data, tag) {
|
|
11713
13298
|
const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
|
|
11714
13299
|
decipher.setAuthTag(Buffer.from(tag, "hex"));
|
|
@@ -11758,13 +13343,212 @@ function openVault(passphrase, vaultPath) {
|
|
|
11758
13343
|
}
|
|
11759
13344
|
return normalizeSecrets(vaultData.secrets ?? {});
|
|
11760
13345
|
}
|
|
13346
|
+
function saveVault(passphrase, vaultPath, secrets) {
|
|
13347
|
+
if (!existsSync(vaultPath)) {
|
|
13348
|
+
throw new VaultError(`Vault file not found: ${vaultPath}`);
|
|
13349
|
+
}
|
|
13350
|
+
let releaseLock = null;
|
|
13351
|
+
const lockStart = Date.now();
|
|
13352
|
+
let lastErr = null;
|
|
13353
|
+
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
13354
|
+
while (Date.now() - lockStart < SAVE_VAULT_LOCK_RETRY_MS) {
|
|
13355
|
+
try {
|
|
13356
|
+
releaseLock = import_proper_lockfile.default.lockSync(vaultPath, {
|
|
13357
|
+
stale: SAVE_VAULT_LOCK_RETRY_MS * 2,
|
|
13358
|
+
realpath: true
|
|
13359
|
+
});
|
|
13360
|
+
lastErr = null;
|
|
13361
|
+
break;
|
|
13362
|
+
} catch (err) {
|
|
13363
|
+
lastErr = err;
|
|
13364
|
+
const code = err?.code ?? "";
|
|
13365
|
+
if (code !== "ELOCKED")
|
|
13366
|
+
throw err;
|
|
13367
|
+
Atomics.wait(sleepBuf, 0, 0, 100);
|
|
13368
|
+
}
|
|
13369
|
+
}
|
|
13370
|
+
if (releaseLock === null) {
|
|
13371
|
+
if (lastErr) {
|
|
13372
|
+
throw new VaultError(`vault busy: another writer holds the lock at ${vaultPath} ` + `(retried for ${SAVE_VAULT_LOCK_RETRY_MS}ms). Try again in a moment.`);
|
|
13373
|
+
}
|
|
13374
|
+
}
|
|
13375
|
+
try {
|
|
13376
|
+
let vaultFile;
|
|
13377
|
+
try {
|
|
13378
|
+
vaultFile = JSON.parse(readFileSync(vaultPath, "utf8"));
|
|
13379
|
+
} catch {
|
|
13380
|
+
throw new VaultError(`Failed to read vault file: ${vaultPath}`);
|
|
13381
|
+
}
|
|
13382
|
+
const salt = Buffer.from(vaultFile.salt, "hex");
|
|
13383
|
+
const key = deriveKey(passphrase, salt, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P });
|
|
13384
|
+
vaultFile.kdf = { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P };
|
|
13385
|
+
const vaultData = { secrets };
|
|
13386
|
+
const { iv, data, tag } = encrypt(key, JSON.stringify(vaultData));
|
|
13387
|
+
vaultFile.iv = iv;
|
|
13388
|
+
vaultFile.data = data;
|
|
13389
|
+
vaultFile.tag = tag;
|
|
13390
|
+
atomicWriteFileSync(vaultPath, JSON.stringify(vaultFile, null, 2), 384);
|
|
13391
|
+
} finally {
|
|
13392
|
+
try {
|
|
13393
|
+
releaseLock();
|
|
13394
|
+
} catch {}
|
|
13395
|
+
}
|
|
13396
|
+
}
|
|
13397
|
+
function acquireVaultLock(vaultPath) {
|
|
13398
|
+
const start = Date.now();
|
|
13399
|
+
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
13400
|
+
while (Date.now() - start < SAVE_VAULT_LOCK_RETRY_MS) {
|
|
13401
|
+
try {
|
|
13402
|
+
return import_proper_lockfile.default.lockSync(vaultPath, {
|
|
13403
|
+
stale: SAVE_VAULT_LOCK_RETRY_MS * 2,
|
|
13404
|
+
realpath: true
|
|
13405
|
+
});
|
|
13406
|
+
} catch (err) {
|
|
13407
|
+
const code = err?.code ?? "";
|
|
13408
|
+
if (code !== "ELOCKED")
|
|
13409
|
+
throw err;
|
|
13410
|
+
Atomics.wait(sleepBuf, 0, 0, 100);
|
|
13411
|
+
}
|
|
13412
|
+
}
|
|
13413
|
+
throw new VaultError(`vault busy: another writer holds the lock at ${vaultPath} ` + `(retried for ${SAVE_VAULT_LOCK_RETRY_MS}ms).`);
|
|
13414
|
+
}
|
|
13415
|
+
|
|
13416
|
+
// src/vault/migrate-layout.ts
|
|
13417
|
+
import {
|
|
13418
|
+
copyFileSync,
|
|
13419
|
+
chmodSync,
|
|
13420
|
+
existsSync as existsSync2,
|
|
13421
|
+
fsyncSync as fsyncSync2,
|
|
13422
|
+
lstatSync,
|
|
13423
|
+
mkdirSync as mkdirSync2,
|
|
13424
|
+
openSync as openSync2,
|
|
13425
|
+
closeSync as closeSync2,
|
|
13426
|
+
readFileSync as readFileSync2,
|
|
13427
|
+
renameSync as renameSync2,
|
|
13428
|
+
statSync,
|
|
13429
|
+
symlinkSync,
|
|
13430
|
+
unlinkSync as unlinkSync2
|
|
13431
|
+
} from "node:fs";
|
|
13432
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
13433
|
+
import { basename as basename2, dirname as dirname2, join } from "node:path";
|
|
13434
|
+
function vaultLayoutPaths(home) {
|
|
13435
|
+
const switchroomRoot = join(home, ".switchroom");
|
|
13436
|
+
return {
|
|
13437
|
+
oldPath: join(switchroomRoot, "vault.enc"),
|
|
13438
|
+
newPath: join(switchroomRoot, "vault", "vault.enc"),
|
|
13439
|
+
parent: join(switchroomRoot, "vault"),
|
|
13440
|
+
switchroomRoot
|
|
13441
|
+
};
|
|
13442
|
+
}
|
|
13443
|
+
function inspectVaultLayout(home) {
|
|
13444
|
+
return runMigration(home, { dryRun: true });
|
|
13445
|
+
}
|
|
13446
|
+
function runMigration(home, opts) {
|
|
13447
|
+
const { oldPath, newPath, parent, switchroomRoot } = vaultLayoutPaths(home);
|
|
13448
|
+
const lockTarget = existsSync2(newPath) ? newPath : existsSync2(oldPath) ? oldPath : null;
|
|
13449
|
+
const release = !opts.dryRun && lockTarget !== null ? acquireVaultLock(lockTarget) : null;
|
|
13450
|
+
try {
|
|
13451
|
+
const oldStat = lstatSyncOrNull(oldPath);
|
|
13452
|
+
const newExists = existsSync2(newPath);
|
|
13453
|
+
if (oldStat === null && !newExists) {
|
|
13454
|
+
return { kind: "no-vault" };
|
|
13455
|
+
}
|
|
13456
|
+
if (oldStat?.isSymbolicLink() && newExists) {
|
|
13457
|
+
return { kind: "already-migrated" };
|
|
13458
|
+
}
|
|
13459
|
+
if (oldStat?.isFile() && newExists) {
|
|
13460
|
+
const oldHash = sha256File(oldPath);
|
|
13461
|
+
const newHash = sha256File(newPath);
|
|
13462
|
+
if (oldHash === newHash) {
|
|
13463
|
+
if (opts.dryRun)
|
|
13464
|
+
return { kind: "completed-partial" };
|
|
13465
|
+
atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
|
|
13466
|
+
fsyncDir(switchroomRoot);
|
|
13467
|
+
return { kind: "completed-partial" };
|
|
13468
|
+
}
|
|
13469
|
+
const oldRealStat = statSync(oldPath);
|
|
13470
|
+
const newRealStat = statSync(newPath);
|
|
13471
|
+
return {
|
|
13472
|
+
kind: "divergent",
|
|
13473
|
+
details: {
|
|
13474
|
+
oldPath,
|
|
13475
|
+
newPath,
|
|
13476
|
+
oldHash,
|
|
13477
|
+
newHash,
|
|
13478
|
+
oldSize: oldRealStat.size,
|
|
13479
|
+
newSize: newRealStat.size,
|
|
13480
|
+
oldMtime: oldRealStat.mtime.toISOString(),
|
|
13481
|
+
newMtime: newRealStat.mtime.toISOString()
|
|
13482
|
+
}
|
|
13483
|
+
};
|
|
13484
|
+
}
|
|
13485
|
+
if (oldStat?.isFile() && !newExists) {
|
|
13486
|
+
if (opts.dryRun)
|
|
13487
|
+
return { kind: "migrated" };
|
|
13488
|
+
mkdirSync2(parent, { recursive: true, mode: 448 });
|
|
13489
|
+
const tempNew = `${newPath}.tmp`;
|
|
13490
|
+
copyFileSync(oldPath, tempNew);
|
|
13491
|
+
chmodSync(tempNew, 384);
|
|
13492
|
+
fsyncFile(tempNew);
|
|
13493
|
+
renameSync2(tempNew, newPath);
|
|
13494
|
+
fsyncDir(parent);
|
|
13495
|
+
atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
|
|
13496
|
+
fsyncDir(switchroomRoot);
|
|
13497
|
+
return { kind: "migrated" };
|
|
13498
|
+
}
|
|
13499
|
+
return { kind: "no-vault" };
|
|
13500
|
+
} finally {
|
|
13501
|
+
if (release !== null) {
|
|
13502
|
+
try {
|
|
13503
|
+
release();
|
|
13504
|
+
} catch {}
|
|
13505
|
+
}
|
|
13506
|
+
}
|
|
13507
|
+
}
|
|
13508
|
+
function lstatSyncOrNull(path) {
|
|
13509
|
+
try {
|
|
13510
|
+
return lstatSync(path);
|
|
13511
|
+
} catch {
|
|
13512
|
+
return null;
|
|
13513
|
+
}
|
|
13514
|
+
}
|
|
13515
|
+
function sha256File(path) {
|
|
13516
|
+
const data = readFileSync2(path);
|
|
13517
|
+
return createHash2("sha256").update(data).digest("hex");
|
|
13518
|
+
}
|
|
13519
|
+
function atomicReplaceWithSymlink(target, linkTarget) {
|
|
13520
|
+
const tmp = join(dirname2(target), `.${basename2(target)}.symlink-tmp`);
|
|
13521
|
+
if (existsSync2(tmp)) {
|
|
13522
|
+
try {
|
|
13523
|
+
unlinkSync2(tmp);
|
|
13524
|
+
} catch {}
|
|
13525
|
+
}
|
|
13526
|
+
symlinkSync(linkTarget, tmp);
|
|
13527
|
+
renameSync2(tmp, target);
|
|
13528
|
+
}
|
|
13529
|
+
function fsyncFile(path) {
|
|
13530
|
+
const fd = openSync2(path, "r+");
|
|
13531
|
+
try {
|
|
13532
|
+
fsyncSync2(fd);
|
|
13533
|
+
} finally {
|
|
13534
|
+
closeSync2(fd);
|
|
13535
|
+
}
|
|
13536
|
+
}
|
|
13537
|
+
function fsyncDir(path) {
|
|
13538
|
+
const fd = openSync2(path, "r");
|
|
13539
|
+
try {
|
|
13540
|
+
fsyncSync2(fd);
|
|
13541
|
+
} finally {
|
|
13542
|
+
closeSync2(fd);
|
|
13543
|
+
}
|
|
13544
|
+
}
|
|
11761
13545
|
|
|
11762
13546
|
// src/vault/broker/server.ts
|
|
11763
13547
|
init_loader();
|
|
11764
13548
|
|
|
11765
13549
|
// src/vault/auto-unlock.ts
|
|
11766
13550
|
import { createHmac, randomBytes as randomBytes2, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2 } from "node:crypto";
|
|
11767
|
-
import { chmodSync, existsSync as
|
|
13551
|
+
import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11768
13552
|
var FORMAT_VERSION = 1;
|
|
11769
13553
|
var SALT_LEN = 16;
|
|
11770
13554
|
var NONCE_LEN = 12;
|
|
@@ -11792,7 +13576,7 @@ class AutoUnlockDecryptError extends Error {
|
|
|
11792
13576
|
function readMachineId() {
|
|
11793
13577
|
for (const path of [MACHINE_ID_PRIMARY, MACHINE_ID_FALLBACK]) {
|
|
11794
13578
|
try {
|
|
11795
|
-
const id =
|
|
13579
|
+
const id = readFileSync4(path, "utf8").trim();
|
|
11796
13580
|
if (id.length > 0)
|
|
11797
13581
|
return id;
|
|
11798
13582
|
} catch {}
|
|
@@ -11829,12 +13613,12 @@ function decryptAutoUnlock(blob, machineId) {
|
|
|
11829
13613
|
}
|
|
11830
13614
|
}
|
|
11831
13615
|
function readAutoUnlockFile(filePath) {
|
|
11832
|
-
if (!
|
|
13616
|
+
if (!existsSync5(filePath)) {
|
|
11833
13617
|
throw new AutoUnlockDecryptError("io");
|
|
11834
13618
|
}
|
|
11835
13619
|
let blob;
|
|
11836
13620
|
try {
|
|
11837
|
-
blob =
|
|
13621
|
+
blob = readFileSync4(filePath);
|
|
11838
13622
|
} catch {
|
|
11839
13623
|
throw new AutoUnlockDecryptError("io");
|
|
11840
13624
|
}
|
|
@@ -11844,7 +13628,7 @@ var DEFAULT_AUTO_UNLOCK_PATH = "~/.switchroom/vault-auto-unlock";
|
|
|
11844
13628
|
|
|
11845
13629
|
// src/vault/broker/peercred.ts
|
|
11846
13630
|
import { execFileSync } from "node:child_process";
|
|
11847
|
-
import { readFileSync as
|
|
13631
|
+
import { readFileSync as readFileSync5, readlinkSync, fstatSync } from "node:fs";
|
|
11848
13632
|
|
|
11849
13633
|
// src/vault/broker/peercred-ffi.ts
|
|
11850
13634
|
function getPeerCred(fd) {
|
|
@@ -11970,7 +13754,7 @@ function findClientPidByServerInode(rows, socketPath, serverInode) {
|
|
|
11970
13754
|
}
|
|
11971
13755
|
function readUid(pid) {
|
|
11972
13756
|
try {
|
|
11973
|
-
const status =
|
|
13757
|
+
const status = readFileSync5(`/proc/${pid}/status`, "utf8");
|
|
11974
13758
|
const m = status.match(/^Uid:\s+(\d+)/m);
|
|
11975
13759
|
if (!m)
|
|
11976
13760
|
return null;
|
|
@@ -11988,7 +13772,7 @@ function readExe(pid) {
|
|
|
11988
13772
|
}
|
|
11989
13773
|
function readSystemdUnit(pid) {
|
|
11990
13774
|
try {
|
|
11991
|
-
const content =
|
|
13775
|
+
const content = readFileSync5(`/proc/${pid}/cgroup`, "utf8");
|
|
11992
13776
|
const lines = content.split(`
|
|
11993
13777
|
`);
|
|
11994
13778
|
for (const line of lines) {
|
|
@@ -12243,6 +14027,16 @@ var GetRequestSchema = exports_external.object({
|
|
|
12243
14027
|
filename: exports_external.string().optional(),
|
|
12244
14028
|
token: exports_external.string().optional()
|
|
12245
14029
|
});
|
|
14030
|
+
var PutRequestSchema = exports_external.object({
|
|
14031
|
+
v: exports_external.literal(1),
|
|
14032
|
+
op: exports_external.literal("put"),
|
|
14033
|
+
key: exports_external.string().min(1),
|
|
14034
|
+
entry: exports_external.union([
|
|
14035
|
+
exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
|
|
14036
|
+
exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() })
|
|
14037
|
+
]),
|
|
14038
|
+
token: exports_external.string().optional()
|
|
14039
|
+
});
|
|
12246
14040
|
var ListRequestSchema = exports_external.object({
|
|
12247
14041
|
v: exports_external.literal(1),
|
|
12248
14042
|
op: exports_external.literal("list"),
|
|
@@ -12327,6 +14121,7 @@ var ApprovalRecordRequestSchema = exports_external.object({
|
|
|
12327
14121
|
});
|
|
12328
14122
|
var RequestSchema = exports_external.discriminatedUnion("op", [
|
|
12329
14123
|
GetRequestSchema,
|
|
14124
|
+
PutRequestSchema,
|
|
12330
14125
|
ListRequestSchema,
|
|
12331
14126
|
StatusRequestSchema,
|
|
12332
14127
|
LockRequestSchema,
|
|
@@ -12379,6 +14174,11 @@ var OkLockResponseSchema = exports_external.object({
|
|
|
12379
14174
|
ok: exports_external.literal(true),
|
|
12380
14175
|
locked: exports_external.literal(true)
|
|
12381
14176
|
});
|
|
14177
|
+
var OkPutResponseSchema = exports_external.object({
|
|
14178
|
+
ok: exports_external.literal(true),
|
|
14179
|
+
put: exports_external.literal(true),
|
|
14180
|
+
key: exports_external.string()
|
|
14181
|
+
});
|
|
12382
14182
|
var OkMintGrantResponseSchema = exports_external.object({
|
|
12383
14183
|
ok: exports_external.literal(true),
|
|
12384
14184
|
token: exports_external.string(),
|
|
@@ -12464,6 +14264,7 @@ var ResponseSchema = exports_external.union([
|
|
|
12464
14264
|
OkKeysResponseSchema,
|
|
12465
14265
|
OkStatusResponseSchema,
|
|
12466
14266
|
OkLockResponseSchema,
|
|
14267
|
+
OkPutResponseSchema,
|
|
12467
14268
|
OkMintGrantResponseSchema,
|
|
12468
14269
|
OkListGrantsResponseSchema,
|
|
12469
14270
|
OkRevokeGrantResponseSchema,
|
|
@@ -12613,13 +14414,13 @@ function genSalt(rounds, seed_length, callback) {
|
|
|
12613
14414
|
throw Error("Illegal callback: " + typeof callback);
|
|
12614
14415
|
_async(callback);
|
|
12615
14416
|
} else
|
|
12616
|
-
return new Promise(function(
|
|
14417
|
+
return new Promise(function(resolve4, reject) {
|
|
12617
14418
|
_async(function(err, res) {
|
|
12618
14419
|
if (err) {
|
|
12619
14420
|
reject(err);
|
|
12620
14421
|
return;
|
|
12621
14422
|
}
|
|
12622
|
-
|
|
14423
|
+
resolve4(res);
|
|
12623
14424
|
});
|
|
12624
14425
|
});
|
|
12625
14426
|
}
|
|
@@ -12639,13 +14440,13 @@ function hash(password, salt, callback, progressCallback) {
|
|
|
12639
14440
|
throw Error("Illegal callback: " + typeof callback);
|
|
12640
14441
|
_async(callback);
|
|
12641
14442
|
} else
|
|
12642
|
-
return new Promise(function(
|
|
14443
|
+
return new Promise(function(resolve4, reject) {
|
|
12643
14444
|
_async(function(err, res) {
|
|
12644
14445
|
if (err) {
|
|
12645
14446
|
reject(err);
|
|
12646
14447
|
return;
|
|
12647
14448
|
}
|
|
12648
|
-
|
|
14449
|
+
resolve4(res);
|
|
12649
14450
|
});
|
|
12650
14451
|
});
|
|
12651
14452
|
}
|
|
@@ -12678,13 +14479,13 @@ function compare(password, hashValue, callback, progressCallback) {
|
|
|
12678
14479
|
throw Error("Illegal callback: " + typeof callback);
|
|
12679
14480
|
_async(callback);
|
|
12680
14481
|
} else
|
|
12681
|
-
return new Promise(function(
|
|
14482
|
+
return new Promise(function(resolve4, reject) {
|
|
12682
14483
|
_async(function(err, res) {
|
|
12683
14484
|
if (err) {
|
|
12684
14485
|
reject(err);
|
|
12685
14486
|
return;
|
|
12686
14487
|
}
|
|
12687
|
-
|
|
14488
|
+
resolve4(res);
|
|
12688
14489
|
});
|
|
12689
14490
|
});
|
|
12690
14491
|
}
|
|
@@ -14478,12 +16279,12 @@ function countPendingNonces(db, now = Date.now()) {
|
|
|
14478
16279
|
WHERE consumed_at IS NULL AND expires_at > ?
|
|
14479
16280
|
GROUP BY agent_unit`).all(now);
|
|
14480
16281
|
const perAgent = new Map;
|
|
14481
|
-
let
|
|
16282
|
+
let global2 = 0;
|
|
14482
16283
|
for (const r of rows) {
|
|
14483
16284
|
perAgent.set(r.agent_unit, r.n);
|
|
14484
|
-
|
|
16285
|
+
global2 += r.n;
|
|
14485
16286
|
}
|
|
14486
|
-
return { perAgent, global };
|
|
16287
|
+
return { perAgent, global: global2 };
|
|
14487
16288
|
}
|
|
14488
16289
|
function computeRetryAfterMs(db, agent_unit, now = Date.now()) {
|
|
14489
16290
|
const row = agent_unit ? db.query(`SELECT MIN(expires_at) AS expires_at FROM approval_nonces
|
|
@@ -14709,6 +16510,7 @@ var PID_FILE_DEFAULT = "~/.switchroom/vault-broker.pid";
|
|
|
14709
16510
|
class VaultBroker {
|
|
14710
16511
|
testOpts;
|
|
14711
16512
|
secrets = null;
|
|
16513
|
+
passphrase = null;
|
|
14712
16514
|
config = null;
|
|
14713
16515
|
startedAt = Date.now();
|
|
14714
16516
|
server = null;
|
|
@@ -14721,9 +16523,12 @@ class VaultBroker {
|
|
|
14721
16523
|
grantsDb;
|
|
14722
16524
|
constructor(testOpts = {}) {
|
|
14723
16525
|
this.testOpts = testOpts;
|
|
14724
|
-
const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined;
|
|
16526
|
+
const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined || testOpts._testVaultPath !== undefined;
|
|
14725
16527
|
if (usingTestOpt && true) {
|
|
14726
|
-
throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
|
|
16528
|
+
throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb/_testVaultPath) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
|
|
16529
|
+
}
|
|
16530
|
+
if (testOpts._testVaultPath !== undefined) {
|
|
16531
|
+
this.vaultPath = testOpts._testVaultPath;
|
|
14727
16532
|
}
|
|
14728
16533
|
this.auditLogger = testOpts._testAuditLogger ?? createAuditLogger();
|
|
14729
16534
|
if (testOpts._testGrantsDb !== undefined) {
|
|
@@ -14736,7 +16541,7 @@ class VaultBroker {
|
|
|
14736
16541
|
if (process.platform !== "linux" && process.env.SWITCHROOM_BROKER_ALLOW_NON_LINUX !== "1") {
|
|
14737
16542
|
throw new Error(`vault-broker is Linux-only (running on ${process.platform}). ` + `The broker's ACL relies on cgroup-based systemd unit identification, ` + `which is not available on this platform. ` + `Use 'switchroom vault get --no-broker' for direct vault access. ` + `If you need to run the broker for development on this platform, ` + `set SWITCHROOM_BROKER_ALLOW_NON_LINUX=1 — but understand that the ` + `broker will accept any same-user caller without per-cron ACL enforcement.`);
|
|
14738
16543
|
}
|
|
14739
|
-
this.socketPath =
|
|
16544
|
+
this.socketPath = resolve4(socketPath);
|
|
14740
16545
|
this.unlockSocketPath = this.socketPath.replace(/\.sock$/, ".unlock.sock");
|
|
14741
16546
|
this.startedAt = Date.now();
|
|
14742
16547
|
if (this.testOpts._testConfig) {
|
|
@@ -14746,7 +16551,7 @@ class VaultBroker {
|
|
|
14746
16551
|
this.config = loadConfig2(configPath);
|
|
14747
16552
|
}
|
|
14748
16553
|
if (vaultPath) {
|
|
14749
|
-
this.vaultPath =
|
|
16554
|
+
this.vaultPath = resolve4(vaultPath);
|
|
14750
16555
|
} else {
|
|
14751
16556
|
this.vaultPath = resolvePath(this.config.vault?.path ?? "~/.switchroom/vault.enc");
|
|
14752
16557
|
}
|
|
@@ -14754,15 +16559,15 @@ class VaultBroker {
|
|
|
14754
16559
|
this.secrets = { ...this.testOpts._testSecrets };
|
|
14755
16560
|
}
|
|
14756
16561
|
process.umask(63);
|
|
14757
|
-
const parentDir =
|
|
14758
|
-
|
|
16562
|
+
const parentDir = dirname4(this.socketPath);
|
|
16563
|
+
mkdirSync5(parentDir, { recursive: true, mode: 448 });
|
|
14759
16564
|
try {
|
|
14760
|
-
|
|
16565
|
+
chmodSync4(parentDir, 448);
|
|
14761
16566
|
} catch {}
|
|
14762
16567
|
for (const p of [this.socketPath, this.unlockSocketPath]) {
|
|
14763
|
-
if (
|
|
16568
|
+
if (existsSync6(p)) {
|
|
14764
16569
|
try {
|
|
14765
|
-
|
|
16570
|
+
unlinkSync3(p);
|
|
14766
16571
|
} catch {}
|
|
14767
16572
|
}
|
|
14768
16573
|
}
|
|
@@ -14778,8 +16583,10 @@ class VaultBroker {
|
|
|
14778
16583
|
}
|
|
14779
16584
|
}
|
|
14780
16585
|
unlockFromPassphrase(passphrase) {
|
|
16586
|
+
detectVaultLayoutDrift(this.vaultPath);
|
|
14781
16587
|
const secrets = openVault(passphrase, this.vaultPath);
|
|
14782
16588
|
this.secrets = secrets;
|
|
16589
|
+
this.passphrase = passphrase;
|
|
14783
16590
|
}
|
|
14784
16591
|
lock() {
|
|
14785
16592
|
if (this.secrets !== null) {
|
|
@@ -14792,6 +16599,7 @@ class VaultBroker {
|
|
|
14792
16599
|
}
|
|
14793
16600
|
this.secrets = null;
|
|
14794
16601
|
}
|
|
16602
|
+
this.passphrase = null;
|
|
14795
16603
|
}
|
|
14796
16604
|
stop() {
|
|
14797
16605
|
this.lock();
|
|
@@ -14807,24 +16615,24 @@ class VaultBroker {
|
|
|
14807
16615
|
try {
|
|
14808
16616
|
entry.server.close();
|
|
14809
16617
|
} catch {}
|
|
14810
|
-
if (
|
|
16618
|
+
if (existsSync6(sockPath)) {
|
|
14811
16619
|
try {
|
|
14812
|
-
|
|
16620
|
+
unlinkSync3(sockPath);
|
|
14813
16621
|
} catch {}
|
|
14814
16622
|
}
|
|
14815
16623
|
}
|
|
14816
16624
|
this.agentServers.clear();
|
|
14817
16625
|
for (const p of [this.socketPath, this.unlockSocketPath]) {
|
|
14818
|
-
if (p &&
|
|
16626
|
+
if (p && existsSync6(p)) {
|
|
14819
16627
|
try {
|
|
14820
|
-
|
|
16628
|
+
unlinkSync3(p);
|
|
14821
16629
|
} catch {}
|
|
14822
16630
|
}
|
|
14823
16631
|
}
|
|
14824
16632
|
try {
|
|
14825
16633
|
const pidPath = resolvePath(PID_FILE_DEFAULT);
|
|
14826
|
-
if (
|
|
14827
|
-
|
|
16634
|
+
if (existsSync6(pidPath))
|
|
16635
|
+
unlinkSync3(pidPath);
|
|
14828
16636
|
} catch {}
|
|
14829
16637
|
}
|
|
14830
16638
|
getStatus() {
|
|
@@ -14838,7 +16646,7 @@ class VaultBroker {
|
|
|
14838
16646
|
return this.secrets;
|
|
14839
16647
|
}
|
|
14840
16648
|
bindAgentSocket(socketPath) {
|
|
14841
|
-
const abs =
|
|
16649
|
+
const abs = resolve4(socketPath);
|
|
14842
16650
|
const agentName = socketPathToAgent(abs);
|
|
14843
16651
|
if (agentName === null) {
|
|
14844
16652
|
return Promise.reject(new Error(`bindAgentSocket: socket path '${abs}' does not match the canonical ` + `/run/switchroom/broker/<agent>.sock shape — refusing to bind without ` + `a verifiable agent identity`));
|
|
@@ -14846,18 +16654,18 @@ class VaultBroker {
|
|
|
14846
16654
|
return new Promise((resolveP, rejectP) => {
|
|
14847
16655
|
if (abs.endsWith("/sock")) {
|
|
14848
16656
|
const dir = abs.slice(0, -"/sock".length);
|
|
14849
|
-
if (
|
|
16657
|
+
if (existsSync6(dir)) {
|
|
14850
16658
|
try {
|
|
14851
16659
|
chownSync(dir, 0, 0);
|
|
14852
16660
|
} catch {}
|
|
14853
16661
|
try {
|
|
14854
|
-
|
|
16662
|
+
chmodSync4(dir, 448);
|
|
14855
16663
|
} catch {}
|
|
14856
16664
|
}
|
|
14857
16665
|
}
|
|
14858
|
-
if (
|
|
16666
|
+
if (existsSync6(abs)) {
|
|
14859
16667
|
try {
|
|
14860
|
-
|
|
16668
|
+
unlinkSync3(abs);
|
|
14861
16669
|
} catch (err) {
|
|
14862
16670
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14863
16671
|
process.stderr.write(`[vault-broker] could not unlink stale socket agent=${agentName} sock=${abs}: ${msg}
|
|
@@ -14870,7 +16678,7 @@ class VaultBroker {
|
|
|
14870
16678
|
server.on("error", (err) => rejectP(err));
|
|
14871
16679
|
server.listen(abs, () => {
|
|
14872
16680
|
try {
|
|
14873
|
-
|
|
16681
|
+
chmodSync4(abs, 432);
|
|
14874
16682
|
} catch {}
|
|
14875
16683
|
try {
|
|
14876
16684
|
const uid = allocateAgentUid(agentName);
|
|
@@ -14890,7 +16698,7 @@ class VaultBroker {
|
|
|
14890
16698
|
});
|
|
14891
16699
|
}
|
|
14892
16700
|
_bindDataSocket() {
|
|
14893
|
-
return new Promise((
|
|
16701
|
+
return new Promise((resolve5, reject) => {
|
|
14894
16702
|
const server = net.createServer((socket) => {
|
|
14895
16703
|
this._handleDataConnection(socket);
|
|
14896
16704
|
});
|
|
@@ -14899,15 +16707,15 @@ class VaultBroker {
|
|
|
14899
16707
|
});
|
|
14900
16708
|
server.listen(this.socketPath, () => {
|
|
14901
16709
|
try {
|
|
14902
|
-
|
|
16710
|
+
chmodSync4(this.socketPath, 384);
|
|
14903
16711
|
} catch {}
|
|
14904
16712
|
this.server = server;
|
|
14905
|
-
|
|
16713
|
+
resolve5();
|
|
14906
16714
|
});
|
|
14907
16715
|
});
|
|
14908
16716
|
}
|
|
14909
16717
|
_bindUnlockSocket() {
|
|
14910
|
-
return new Promise((
|
|
16718
|
+
return new Promise((resolve5, reject) => {
|
|
14911
16719
|
const server = net.createServer((socket) => {
|
|
14912
16720
|
this._handleUnlockConnection(socket);
|
|
14913
16721
|
});
|
|
@@ -14916,10 +16724,10 @@ class VaultBroker {
|
|
|
14916
16724
|
});
|
|
14917
16725
|
server.listen(this.unlockSocketPath, () => {
|
|
14918
16726
|
try {
|
|
14919
|
-
|
|
16727
|
+
chmodSync4(this.unlockSocketPath, 384);
|
|
14920
16728
|
} catch {}
|
|
14921
16729
|
this.unlockServer = server;
|
|
14922
|
-
|
|
16730
|
+
resolve5();
|
|
14923
16731
|
});
|
|
14924
16732
|
});
|
|
14925
16733
|
}
|
|
@@ -15205,6 +17013,90 @@ class VaultBroker {
|
|
|
15205
17013
|
socket.write(encodeResponse(entryResponse(entry)));
|
|
15206
17014
|
return;
|
|
15207
17015
|
}
|
|
17016
|
+
if (req.op === "put") {
|
|
17017
|
+
if (this.secrets === null || this.passphrase === null) {
|
|
17018
|
+
socket.write(encodeResponse(errorResponse("LOCKED", "Vault is locked")));
|
|
17019
|
+
return;
|
|
17020
|
+
}
|
|
17021
|
+
if (agentName === null) {
|
|
17022
|
+
socket.write(encodeResponse(errorResponse("DENIED", "put requires path-as-identity (token-based grants are read-only)")));
|
|
17023
|
+
return;
|
|
17024
|
+
}
|
|
17025
|
+
if (this.config === null) {
|
|
17026
|
+
socket.write(encodeResponse(errorResponse("INTERNAL", "Broker config not loaded")));
|
|
17027
|
+
return;
|
|
17028
|
+
}
|
|
17029
|
+
const aclResult = checkAclByAgent(this.config, agentName, req.key);
|
|
17030
|
+
if (!aclResult.allow) {
|
|
17031
|
+
this.auditLogger.write({
|
|
17032
|
+
ts: new Date().toISOString(),
|
|
17033
|
+
op: "put",
|
|
17034
|
+
key: req.key,
|
|
17035
|
+
caller: auditCaller,
|
|
17036
|
+
pid: auditPid,
|
|
17037
|
+
cgroup: auditCgroup,
|
|
17038
|
+
result: `denied:${aclResult.reason}`
|
|
17039
|
+
});
|
|
17040
|
+
socket.write(encodeResponse(errorResponse("DENIED", aclResult.reason)));
|
|
17041
|
+
return;
|
|
17042
|
+
}
|
|
17043
|
+
const existing = this.secrets[req.key];
|
|
17044
|
+
if (existing === undefined) {
|
|
17045
|
+
this.auditLogger.write({
|
|
17046
|
+
ts: new Date().toISOString(),
|
|
17047
|
+
op: "put",
|
|
17048
|
+
key: req.key,
|
|
17049
|
+
caller: auditCaller,
|
|
17050
|
+
pid: auditPid,
|
|
17051
|
+
cgroup: auditCgroup,
|
|
17052
|
+
result: "denied:unknown_key"
|
|
17053
|
+
});
|
|
17054
|
+
socket.write(encodeResponse(errorResponse("UNKNOWN_KEY", `Key not found: ${req.key} (broker put cannot introduce new keys; ask operator to set it once via 'switchroom vault set' from the host)`)));
|
|
17055
|
+
return;
|
|
17056
|
+
}
|
|
17057
|
+
if (existing.kind !== req.entry.kind) {
|
|
17058
|
+
this.auditLogger.write({
|
|
17059
|
+
ts: new Date().toISOString(),
|
|
17060
|
+
op: "put",
|
|
17061
|
+
key: req.key,
|
|
17062
|
+
caller: auditCaller,
|
|
17063
|
+
pid: auditPid,
|
|
17064
|
+
cgroup: auditCgroup,
|
|
17065
|
+
result: `denied:kind_mismatch ${existing.kind}→${req.entry.kind}`
|
|
17066
|
+
});
|
|
17067
|
+
socket.write(encodeResponse(errorResponse("BAD_REQUEST", `kind mismatch: existing entry is '${existing.kind}', new entry is '${req.entry.kind}'`)));
|
|
17068
|
+
return;
|
|
17069
|
+
}
|
|
17070
|
+
const previousEntry = existing;
|
|
17071
|
+
this.secrets[req.key] = req.entry;
|
|
17072
|
+
try {
|
|
17073
|
+
saveVault(this.passphrase, this.vaultPath, this.secrets);
|
|
17074
|
+
} catch (err) {
|
|
17075
|
+
this.secrets[req.key] = previousEntry;
|
|
17076
|
+
this.auditLogger.write({
|
|
17077
|
+
ts: new Date().toISOString(),
|
|
17078
|
+
op: "put",
|
|
17079
|
+
key: req.key,
|
|
17080
|
+
caller: auditCaller,
|
|
17081
|
+
pid: auditPid,
|
|
17082
|
+
cgroup: auditCgroup,
|
|
17083
|
+
result: `error:${err?.message ?? "save failed"}`
|
|
17084
|
+
});
|
|
17085
|
+
socket.write(encodeResponse(errorResponse("INTERNAL", `Failed to persist: ${err?.message ?? "unknown"}`)));
|
|
17086
|
+
return;
|
|
17087
|
+
}
|
|
17088
|
+
this.auditLogger.write({
|
|
17089
|
+
ts: new Date().toISOString(),
|
|
17090
|
+
op: "put",
|
|
17091
|
+
key: req.key,
|
|
17092
|
+
caller: auditCaller,
|
|
17093
|
+
pid: auditPid,
|
|
17094
|
+
cgroup: auditCgroup,
|
|
17095
|
+
result: "allowed"
|
|
17096
|
+
});
|
|
17097
|
+
socket.write(encodeResponse({ ok: true, put: true, key: req.key }));
|
|
17098
|
+
return;
|
|
17099
|
+
}
|
|
15208
17100
|
if (req.op === "approval_request" || req.op === "approval_lookup" || req.op === "approval_consume" || req.op === "approval_revoke" || req.op === "approval_list" || req.op === "approval_record") {
|
|
15209
17101
|
await this._handleApprovalOp(socket, req);
|
|
15210
17102
|
return;
|
|
@@ -15272,11 +17164,11 @@ class VaultBroker {
|
|
|
15272
17164
|
}
|
|
15273
17165
|
try {
|
|
15274
17166
|
const tokenDir = path3.join(os3.homedir(), ".switchroom", "agents", agent);
|
|
15275
|
-
|
|
17167
|
+
mkdirSync5(tokenDir, { recursive: true });
|
|
15276
17168
|
const tokenPath = path3.join(tokenDir, ".vault-token");
|
|
15277
17169
|
const tmpPath = `${tokenPath}.tmp.${process.pid}`;
|
|
15278
17170
|
writeFileSync3(tmpPath, mintResult.token, { mode: 384 });
|
|
15279
|
-
|
|
17171
|
+
renameSync3(tmpPath, tokenPath);
|
|
15280
17172
|
} catch (err) {
|
|
15281
17173
|
process.stderr.write(`[vault-broker] mint_grant: failed to write token file for agent ${agent}: ${err.message}
|
|
15282
17174
|
`);
|
|
@@ -15327,9 +17219,9 @@ class VaultBroker {
|
|
|
15327
17219
|
const row = this.grantsDb.query("SELECT agent_slug FROM vault_grants WHERE id = ?").get(id);
|
|
15328
17220
|
if (row) {
|
|
15329
17221
|
const tokenPath = path3.join(os3.homedir(), ".switchroom", "agents", row.agent_slug, ".vault-token");
|
|
15330
|
-
if (
|
|
17222
|
+
if (existsSync6(tokenPath)) {
|
|
15331
17223
|
try {
|
|
15332
|
-
|
|
17224
|
+
unlinkSync3(tokenPath);
|
|
15333
17225
|
} catch {}
|
|
15334
17226
|
}
|
|
15335
17227
|
}
|
|
@@ -15570,7 +17462,7 @@ class VaultBroker {
|
|
|
15570
17462
|
const envPath = process.env.SWITCHROOM_VAULT_BROKER_AUTO_UNLOCK_PATH;
|
|
15571
17463
|
const configuredPath = (envPath && envPath.length > 0 ? envPath : undefined) ?? this.config?.vault?.broker?.autoUnlockCredentialPath ?? DEFAULT_AUTO_UNLOCK_PATH;
|
|
15572
17464
|
const filePath = resolvePath(configuredPath);
|
|
15573
|
-
if (!
|
|
17465
|
+
if (!existsSync6(filePath))
|
|
15574
17466
|
return false;
|
|
15575
17467
|
let passphrase;
|
|
15576
17468
|
try {
|
|
@@ -15607,7 +17499,7 @@ class VaultBroker {
|
|
|
15607
17499
|
const credPath = `${dir}/vault-passphrase`;
|
|
15608
17500
|
let passphrase;
|
|
15609
17501
|
try {
|
|
15610
|
-
passphrase =
|
|
17502
|
+
passphrase = readFileSync6(credPath, "utf8").replace(/\n+$/, "");
|
|
15611
17503
|
} catch (err) {
|
|
15612
17504
|
const code = err.code;
|
|
15613
17505
|
if (code === "ENOENT") {
|
|
@@ -15644,6 +17536,21 @@ class VaultBroker {
|
|
|
15644
17536
|
} catch {}
|
|
15645
17537
|
}
|
|
15646
17538
|
}
|
|
17539
|
+
function detectVaultLayoutDrift(vaultPath) {
|
|
17540
|
+
const dir = dirname4(vaultPath);
|
|
17541
|
+
if (basename3(dir) !== "vault")
|
|
17542
|
+
return;
|
|
17543
|
+
if (basename3(vaultPath) !== "vault.enc")
|
|
17544
|
+
return;
|
|
17545
|
+
const switchroomDir = dirname4(dir);
|
|
17546
|
+
if (basename3(switchroomDir) !== ".switchroom")
|
|
17547
|
+
return;
|
|
17548
|
+
const home2 = dirname4(switchroomDir);
|
|
17549
|
+
const result = inspectVaultLayout(home2);
|
|
17550
|
+
if (result.kind === "divergent") {
|
|
17551
|
+
throw new VaultError(`Vault layout divergence detected at boot: ${result.details.oldPath} and ${result.details.newPath} are both regular files with different content. An older switchroom CLI may have written to the legacy path after migration ran. Run \`switchroom apply\` from the host to surface the recovery recipe (state E refusal with literal \`mv\` commands). See docs/operators/state-e-recovery.md.`);
|
|
17552
|
+
}
|
|
17553
|
+
}
|
|
15647
17554
|
var _globalBroker = null;
|
|
15648
17555
|
function registerShutdownHandlers(broker) {
|
|
15649
17556
|
_globalBroker = broker;
|
|
@@ -15664,7 +17571,7 @@ async function main() {
|
|
|
15664
17571
|
const vaultPath = process.env.SWITCHROOM_VAULT_PATH;
|
|
15665
17572
|
let perAgentTargets = [];
|
|
15666
17573
|
try {
|
|
15667
|
-
if (
|
|
17574
|
+
if (existsSync6(perAgentDir)) {
|
|
15668
17575
|
const entries = readdirSync(perAgentDir, { withFileTypes: true });
|
|
15669
17576
|
const flat = [];
|
|
15670
17577
|
const subdirs = [];
|
|
@@ -15672,11 +17579,11 @@ async function main() {
|
|
|
15672
17579
|
if (e.name.startsWith("."))
|
|
15673
17580
|
continue;
|
|
15674
17581
|
if ((e.isFile() || e.isSocket()) && e.name.endsWith(".sock")) {
|
|
15675
|
-
flat.push(
|
|
17582
|
+
flat.push(resolve4(perAgentDir, e.name));
|
|
15676
17583
|
continue;
|
|
15677
17584
|
}
|
|
15678
17585
|
if (e.isDirectory()) {
|
|
15679
|
-
const candidate =
|
|
17586
|
+
const candidate = resolve4(perAgentDir, e.name, "sock");
|
|
15680
17587
|
if (socketPathToAgent(candidate) !== null) {
|
|
15681
17588
|
subdirs.push(candidate);
|
|
15682
17589
|
}
|