@spzhongwin/skill-logger-plugin 1.0.18 → 1.0.20

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/index.js CHANGED
@@ -30,28 +30,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  mod
31
31
  ));
32
32
 
33
- // ../../node_modules/adm-zip/util/fileSystem.js
34
- var require_fileSystem = __commonJS({
35
- "../../node_modules/adm-zip/util/fileSystem.js"(exports) {
36
- exports.require = function() {
37
- var fs10 = __require("fs");
38
- if (process.versions["electron"]) {
39
- try {
40
- originalFs = __require("original-fs");
41
- if (Object.keys(originalFs).length > 0) {
42
- fs10 = originalFs;
43
- }
44
- } catch (e) {
45
- }
46
- }
47
- return fs10;
48
- };
49
- }
50
- });
51
-
52
- // ../../node_modules/adm-zip/util/constants.js
33
+ // node_modules/adm-zip/util/constants.js
53
34
  var require_constants = __commonJS({
54
- "../../node_modules/adm-zip/util/constants.js"(exports, module) {
35
+ "node_modules/adm-zip/util/constants.js"(exports, module) {
55
36
  module.exports = {
56
37
  /* The local file header */
57
38
  LOCHDR: 30,
@@ -188,45 +169,54 @@ var require_constants = __commonJS({
188
169
  // reduced with compression factor 4
189
170
  IMPLODED: 6,
190
171
  // imploded
191
- // 7 reserved
172
+ // 7 reserved for Tokenizing compression algorithm
192
173
  DEFLATED: 8,
193
174
  // deflated
194
175
  ENHANCED_DEFLATED: 9,
195
176
  // enhanced deflated
196
177
  PKWARE: 10,
197
178
  // PKWare DCL imploded
198
- // 11 reserved
179
+ // 11 reserved by PKWARE
199
180
  BZIP2: 12,
200
181
  // compressed using BZIP2
201
- // 13 reserved
182
+ // 13 reserved by PKWARE
202
183
  LZMA: 14,
203
184
  // LZMA
204
- // 15-17 reserved
185
+ // 15-17 reserved by PKWARE
205
186
  IBM_TERSE: 18,
206
187
  // compressed using IBM TERSE
207
188
  IBM_LZ77: 19,
208
- //IBM LZ77 z
189
+ // IBM LZ77 z
190
+ AES_ENCRYPT: 99,
191
+ // WinZIP AES encryption method
209
192
  /* General purpose bit flag */
210
- FLG_ENC: 0,
211
- // encripted file
212
- FLG_COMP1: 1,
213
- // compression option
214
- FLG_COMP2: 2,
215
- // compression option
216
- FLG_DESC: 4,
217
- // data descriptor
218
- FLG_ENH: 8,
219
- // enhanced deflation
220
- FLG_STR: 16,
221
- // strong encryption
222
- FLG_LNG: 1024,
223
- // language encoding
193
+ // values can obtained with expression 2**bitnr
194
+ FLG_ENC: 1,
195
+ // Bit 0: encrypted file
196
+ FLG_COMP1: 2,
197
+ // Bit 1, compression option
198
+ FLG_COMP2: 4,
199
+ // Bit 2, compression option
200
+ FLG_DESC: 8,
201
+ // Bit 3, data descriptor
202
+ FLG_ENH: 16,
203
+ // Bit 4, enhanced deflating
204
+ FLG_PATCH: 32,
205
+ // Bit 5, indicates that the file is compressed patched data.
206
+ FLG_STR: 64,
207
+ // Bit 6, strong encryption (patented)
208
+ // Bits 7-10: Currently unused.
209
+ FLG_EFS: 2048,
210
+ // Bit 11: Language encoding flag (EFS)
211
+ // Bit 12: Reserved by PKWARE for enhanced compression.
212
+ // Bit 13: encrypted the Central Directory (patented).
213
+ // Bits 14-15: Reserved by PKWARE.
224
214
  FLG_MSK: 4096,
225
215
  // mask header values
226
216
  /* Load type */
227
- FILE: 0,
217
+ FILE: 2,
228
218
  BUFFER: 1,
229
- NONE: 2,
219
+ NONE: 0,
230
220
  /* 4.5 Extensible data fields */
231
221
  EF_ID: 0,
232
222
  EF_SIZE: 2,
@@ -259,243 +249,370 @@ var require_constants = __commonJS({
259
249
  }
260
250
  });
261
251
 
262
- // ../../node_modules/adm-zip/util/errors.js
252
+ // node_modules/adm-zip/util/errors.js
263
253
  var require_errors = __commonJS({
264
- "../../node_modules/adm-zip/util/errors.js"(exports, module) {
265
- module.exports = {
254
+ "node_modules/adm-zip/util/errors.js"(exports) {
255
+ var errors = {
266
256
  /* Header error messages */
267
- "INVALID_LOC": "Invalid LOC header (bad signature)",
268
- "INVALID_CEN": "Invalid CEN header (bad signature)",
269
- "INVALID_END": "Invalid END header (bad signature)",
257
+ INVALID_LOC: "Invalid LOC header (bad signature)",
258
+ INVALID_CEN: "Invalid CEN header (bad signature)",
259
+ INVALID_END: "Invalid END header (bad signature)",
260
+ /* Descriptor */
261
+ DESCRIPTOR_NOT_EXIST: "No descriptor present",
262
+ DESCRIPTOR_UNKNOWN: "Unknown descriptor format",
263
+ DESCRIPTOR_FAULTY: "Descriptor data is malformed",
270
264
  /* ZipEntry error messages*/
271
- "NO_DATA": "Nothing to decompress",
272
- "BAD_CRC": "CRC32 checksum failed",
273
- "FILE_IN_THE_WAY": "There is a file in the way: %s",
274
- "UNKNOWN_METHOD": "Invalid/unsupported compression method",
265
+ NO_DATA: "Nothing to decompress",
266
+ BAD_CRC: "CRC32 checksum failed {0}",
267
+ FILE_IN_THE_WAY: "There is a file in the way: {0}",
268
+ UNKNOWN_METHOD: "Invalid/unsupported compression method",
275
269
  /* Inflater error messages */
276
- "AVAIL_DATA": "inflate::Available inflate data did not terminate",
277
- "INVALID_DISTANCE": "inflate::Invalid literal/length or distance code in fixed or dynamic block",
278
- "TO_MANY_CODES": "inflate::Dynamic block code description: too many length or distance codes",
279
- "INVALID_REPEAT_LEN": "inflate::Dynamic block code description: repeat more than specified lengths",
280
- "INVALID_REPEAT_FIRST": "inflate::Dynamic block code description: repeat lengths with no first length",
281
- "INCOMPLETE_CODES": "inflate::Dynamic block code description: code lengths codes incomplete",
282
- "INVALID_DYN_DISTANCE": "inflate::Dynamic block code description: invalid distance code lengths",
283
- "INVALID_CODES_LEN": "inflate::Dynamic block code description: invalid literal/length code lengths",
284
- "INVALID_STORE_BLOCK": "inflate::Stored block length did not match one's complement",
285
- "INVALID_BLOCK_TYPE": "inflate::Invalid block type (type == 3)",
270
+ AVAIL_DATA: "inflate::Available inflate data did not terminate",
271
+ INVALID_DISTANCE: "inflate::Invalid literal/length or distance code in fixed or dynamic block",
272
+ TO_MANY_CODES: "inflate::Dynamic block code description: too many length or distance codes",
273
+ INVALID_REPEAT_LEN: "inflate::Dynamic block code description: repeat more than specified lengths",
274
+ INVALID_REPEAT_FIRST: "inflate::Dynamic block code description: repeat lengths with no first length",
275
+ INCOMPLETE_CODES: "inflate::Dynamic block code description: code lengths codes incomplete",
276
+ INVALID_DYN_DISTANCE: "inflate::Dynamic block code description: invalid distance code lengths",
277
+ INVALID_CODES_LEN: "inflate::Dynamic block code description: invalid literal/length code lengths",
278
+ INVALID_STORE_BLOCK: "inflate::Stored block length did not match one's complement",
279
+ INVALID_BLOCK_TYPE: "inflate::Invalid block type (type == 3)",
286
280
  /* ADM-ZIP error messages */
287
- "CANT_EXTRACT_FILE": "Could not extract the file",
288
- "CANT_OVERRIDE": "Target file already exists",
289
- "NO_ZIP": "No zip file was loaded",
290
- "NO_ENTRY": "Entry doesn't exist",
291
- "DIRECTORY_CONTENT_ERROR": "A directory cannot have content",
292
- "FILE_NOT_FOUND": "File not found: %s",
293
- "NOT_IMPLEMENTED": "Not implemented",
294
- "INVALID_FILENAME": "Invalid filename",
295
- "INVALID_FORMAT": "Invalid or unsupported zip format. No END header found"
281
+ CANT_EXTRACT_FILE: "Could not extract the file",
282
+ CANT_OVERRIDE: "Target file already exists",
283
+ DISK_ENTRY_TOO_LARGE: "Number of disk entries is too large",
284
+ NO_ZIP: "No zip file was loaded",
285
+ NO_ENTRY: "Entry doesn't exist",
286
+ DIRECTORY_CONTENT_ERROR: "A directory cannot have content",
287
+ FILE_NOT_FOUND: 'File not found: "{0}"',
288
+ NOT_IMPLEMENTED: "Not implemented",
289
+ INVALID_FILENAME: "Invalid filename",
290
+ INVALID_FORMAT: "Invalid or unsupported zip format. No END header found",
291
+ INVALID_PASS_PARAM: "Incompatible password parameter",
292
+ WRONG_PASSWORD: "Wrong Password",
293
+ /* ADM-ZIP */
294
+ COMMENT_TOO_LONG: "Comment is too long",
295
+ // Comment can be max 65535 bytes long (NOTE: some non-US characters may take more space)
296
+ EXTRA_FIELD_PARSE_ERROR: "Extra field parsing error"
296
297
  };
298
+ function E(message) {
299
+ return function(...args) {
300
+ if (args.length) {
301
+ message = message.replace(/\{(\d)\}/g, (_, n) => args[n] || "");
302
+ }
303
+ return new Error("ADM-ZIP: " + message);
304
+ };
305
+ }
306
+ for (const msg of Object.keys(errors)) {
307
+ exports[msg] = E(errors[msg]);
308
+ }
297
309
  }
298
310
  });
299
311
 
300
- // ../../node_modules/adm-zip/util/utils.js
312
+ // node_modules/adm-zip/util/utils.js
301
313
  var require_utils = __commonJS({
302
- "../../node_modules/adm-zip/util/utils.js"(exports, module) {
303
- var fs10 = require_fileSystem().require();
314
+ "node_modules/adm-zip/util/utils.js"(exports, module) {
315
+ var fsystem = __require("fs");
304
316
  var pth = __require("path");
305
- fs10.existsSync = fs10.existsSync || pth.existsSync;
306
- module.exports = (function() {
307
- var crcTable = [], Constants = require_constants(), Errors = require_errors(), PATH_SEPARATOR = pth.sep;
308
- function mkdirSync(path12) {
309
- var resolvedPath = path12.split(PATH_SEPARATOR)[0];
310
- path12.split(PATH_SEPARATOR).forEach(function(name) {
317
+ var Constants = require_constants();
318
+ var Errors = require_errors();
319
+ var isWin = typeof process === "object" && "win32" === process.platform;
320
+ var is_Obj = (obj) => typeof obj === "object" && obj !== null;
321
+ var crcTable = new Uint32Array(256).map((t, c) => {
322
+ for (let k = 0; k < 8; k++) {
323
+ if ((c & 1) !== 0) {
324
+ c = 3988292384 ^ c >>> 1;
325
+ } else {
326
+ c >>>= 1;
327
+ }
328
+ }
329
+ return c >>> 0;
330
+ });
331
+ function Utils(opts) {
332
+ this.sep = pth.sep;
333
+ this.fs = fsystem;
334
+ if (is_Obj(opts)) {
335
+ if (is_Obj(opts.fs) && typeof opts.fs.statSync === "function") {
336
+ this.fs = opts.fs;
337
+ }
338
+ }
339
+ }
340
+ module.exports = Utils;
341
+ Utils.prototype.makeDir = function(folder) {
342
+ const self = this;
343
+ function mkdirSync(fpath) {
344
+ let resolvedPath = fpath.split(self.sep)[0];
345
+ fpath.split(self.sep).forEach(function(name) {
311
346
  if (!name || name.substr(-1, 1) === ":") return;
312
- resolvedPath += PATH_SEPARATOR + name;
347
+ resolvedPath += self.sep + name;
313
348
  var stat;
314
349
  try {
315
- stat = fs10.statSync(resolvedPath);
350
+ stat = self.fs.statSync(resolvedPath);
316
351
  } catch (e) {
317
- fs10.mkdirSync(resolvedPath);
352
+ if (e.message && e.message.startsWith("ENOENT")) {
353
+ self.fs.mkdirSync(resolvedPath);
354
+ } else {
355
+ throw e;
356
+ }
318
357
  }
319
- if (stat && stat.isFile())
320
- throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
358
+ if (stat && stat.isFile()) throw Errors.FILE_IN_THE_WAY(`"${resolvedPath}"`);
321
359
  });
322
360
  }
323
- function findSync(dir, pattern, recoursive) {
324
- if (typeof pattern === "boolean") {
325
- recoursive = pattern;
326
- pattern = void 0;
361
+ mkdirSync(folder);
362
+ };
363
+ Utils.prototype.writeFileTo = function(path16, content, overwrite, attr) {
364
+ const self = this;
365
+ if (self.fs.existsSync(path16)) {
366
+ if (!overwrite) return false;
367
+ var stat = self.fs.statSync(path16);
368
+ if (stat.isDirectory()) {
369
+ return false;
327
370
  }
328
- var files = [];
329
- fs10.readdirSync(dir).forEach(function(file) {
330
- var path12 = pth.join(dir, file);
331
- if (fs10.statSync(path12).isDirectory() && recoursive)
332
- files = files.concat(findSync(path12, pattern, recoursive));
333
- if (!pattern || pattern.test(path12)) {
334
- files.push(pth.normalize(path12) + (fs10.statSync(path12).isDirectory() ? PATH_SEPARATOR : ""));
335
- }
336
- });
337
- return files;
338
371
  }
339
- function readBigUInt64LE(buffer, index) {
340
- var slice = Buffer.from(buffer.slice(index, index + 8));
341
- slice.swap64();
342
- return parseInt(`0x${slice.toString("hex")}`);
372
+ var folder = pth.dirname(path16);
373
+ if (!self.fs.existsSync(folder)) {
374
+ self.makeDir(folder);
343
375
  }
344
- return {
345
- makeDir: function(path12) {
346
- mkdirSync(path12);
347
- },
348
- crc32: function(buf) {
349
- if (typeof buf === "string") {
350
- buf = Buffer.alloc(buf.length, buf);
376
+ var fd;
377
+ try {
378
+ fd = self.fs.openSync(path16, "w", 438);
379
+ } catch (e) {
380
+ self.fs.chmodSync(path16, 438);
381
+ fd = self.fs.openSync(path16, "w", 438);
382
+ }
383
+ if (fd) {
384
+ try {
385
+ self.fs.writeSync(fd, content, 0, content.length, 0);
386
+ } finally {
387
+ self.fs.closeSync(fd);
388
+ }
389
+ }
390
+ self.fs.chmodSync(path16, attr || 438);
391
+ return true;
392
+ };
393
+ Utils.prototype.writeFileToAsync = function(path16, content, overwrite, attr, callback) {
394
+ if (typeof attr === "function") {
395
+ callback = attr;
396
+ attr = void 0;
397
+ }
398
+ const self = this;
399
+ self.fs.exists(path16, function(exist) {
400
+ if (exist && !overwrite) return callback(false);
401
+ self.fs.stat(path16, function(err, stat) {
402
+ if (exist && stat && stat.isDirectory()) {
403
+ return callback(false);
351
404
  }
352
- var b = Buffer.alloc(4);
353
- if (!crcTable.length) {
354
- for (var n = 0; n < 256; n++) {
355
- var c = n;
356
- for (var k = 8; --k >= 0; )
357
- if ((c & 1) !== 0) {
358
- c = 3988292384 ^ c >>> 1;
359
- } else {
360
- c = c >>> 1;
361
- }
362
- if (c < 0) {
363
- b.writeInt32LE(c, 0);
364
- c = b.readUInt32LE(0);
405
+ var folder = pth.dirname(path16);
406
+ self.fs.exists(folder, function(exists) {
407
+ if (!exists) {
408
+ try {
409
+ self.makeDir(folder);
410
+ } catch (e) {
411
+ return callback(false);
365
412
  }
366
- crcTable[n] = c;
367
- }
368
- }
369
- var crc = 0, off = 0, len = buf.length, c1 = ~crc;
370
- while (--len >= 0) c1 = crcTable[(c1 ^ buf[off++]) & 255] ^ c1 >>> 8;
371
- crc = ~c1;
372
- b.writeInt32LE(crc & 4294967295, 0);
373
- return b.readUInt32LE(0);
374
- },
375
- methodToString: function(method) {
376
- switch (method) {
377
- case Constants.STORED:
378
- return "STORED (" + method + ")";
379
- case Constants.DEFLATED:
380
- return "DEFLATED (" + method + ")";
381
- default:
382
- return "UNSUPPORTED (" + method + ")";
383
- }
384
- },
385
- writeFileTo: function(path12, content, overwrite, attr) {
386
- if (fs10.existsSync(path12)) {
387
- if (!overwrite)
388
- return false;
389
- var stat = fs10.statSync(path12);
390
- if (stat.isDirectory()) {
391
- return false;
392
413
  }
414
+ const writeToFd = function(fd) {
415
+ self.fs.write(fd, content, 0, content.length, 0, function(writeErr) {
416
+ self.fs.close(fd, function() {
417
+ if (writeErr) return callback(false);
418
+ self.fs.chmod(path16, attr || 438, function() {
419
+ callback(true);
420
+ });
421
+ });
422
+ });
423
+ };
424
+ self.fs.open(path16, "w", 438, function(err2, fd) {
425
+ if (err2) {
426
+ self.fs.chmod(path16, 438, function() {
427
+ self.fs.open(path16, "w", 438, function(retryErr, fd2) {
428
+ if (retryErr || !fd2) return callback(false);
429
+ writeToFd(fd2);
430
+ });
431
+ });
432
+ } else if (fd) {
433
+ writeToFd(fd);
434
+ } else {
435
+ callback(false);
436
+ }
437
+ });
438
+ });
439
+ });
440
+ });
441
+ };
442
+ Utils.prototype.findFiles = function(path16) {
443
+ const self = this;
444
+ function findSync(dir, pattern, recursive, visited) {
445
+ if (typeof pattern === "boolean") {
446
+ recursive = pattern;
447
+ pattern = void 0;
448
+ }
449
+ let files = [];
450
+ self.fs.readdirSync(dir).forEach(function(file) {
451
+ const path17 = pth.join(dir, file);
452
+ const stat = self.fs.statSync(path17);
453
+ if (!pattern || pattern.test(path17)) {
454
+ files.push(pth.normalize(path17) + (stat.isDirectory() ? self.sep : ""));
393
455
  }
394
- var folder = pth.dirname(path12);
395
- if (!fs10.existsSync(folder)) {
396
- mkdirSync(folder);
397
- }
398
- var fd;
399
- try {
400
- fd = fs10.openSync(path12, "w", 438);
401
- } catch (e) {
402
- fs10.chmodSync(path12, 438);
403
- fd = fs10.openSync(path12, "w", 438);
404
- }
405
- if (fd) {
406
- try {
407
- fs10.writeSync(fd, content, 0, content.length, 0);
408
- } catch (e) {
409
- throw e;
410
- } finally {
411
- fs10.closeSync(fd);
456
+ if (stat.isDirectory() && recursive) {
457
+ const realDir = self.fs.realpathSync(path17);
458
+ if (!visited.has(realDir)) {
459
+ visited.add(realDir);
460
+ files = files.concat(findSync(path17, pattern, recursive, visited));
412
461
  }
413
462
  }
414
- fs10.chmodSync(path12, attr || 438);
415
- return true;
416
- },
417
- writeFileToAsync: function(path12, content, overwrite, attr, callback) {
418
- if (typeof attr === "function") {
419
- callback = attr;
420
- attr = void 0;
421
- }
422
- fs10.exists(path12, function(exists) {
423
- if (exists && !overwrite)
424
- return callback(false);
425
- fs10.stat(path12, function(err, stat) {
426
- if (exists && stat.isDirectory()) {
427
- return callback(false);
463
+ });
464
+ return files;
465
+ }
466
+ return findSync(path16, void 0, true, /* @__PURE__ */ new Set([self.fs.realpathSync(path16)]));
467
+ };
468
+ Utils.prototype.findFilesAsync = function(dir, cb) {
469
+ const self = this;
470
+ const results = [];
471
+ let finished = false;
472
+ const finish = function(err) {
473
+ if (finished) return;
474
+ finished = true;
475
+ cb(err, err ? void 0 : results);
476
+ };
477
+ const walk = function(dir2, visited, done) {
478
+ self.fs.readdir(dir2, function(err, list) {
479
+ if (err) return done(err);
480
+ let pending = list.length;
481
+ if (!pending) return done();
482
+ list.forEach(function(name) {
483
+ const file = pth.join(dir2, name);
484
+ self.fs.stat(file, function(err2, stat) {
485
+ if (err2) return done(err2);
486
+ if (!stat) {
487
+ if (!--pending) done();
488
+ return;
428
489
  }
429
- var folder = pth.dirname(path12);
430
- fs10.exists(folder, function(exists2) {
431
- if (!exists2)
432
- mkdirSync(folder);
433
- fs10.open(path12, "w", 438, function(err2, fd) {
434
- if (err2) {
435
- fs10.chmod(path12, 438, function() {
436
- fs10.open(path12, "w", 438, function(err3, fd2) {
437
- fs10.write(fd2, content, 0, content.length, 0, function() {
438
- fs10.close(fd2, function() {
439
- fs10.chmod(path12, attr || 438, function() {
440
- callback(true);
441
- });
442
- });
443
- });
444
- });
445
- });
446
- } else {
447
- if (fd) {
448
- fs10.write(fd, content, 0, content.length, 0, function() {
449
- fs10.close(fd, function() {
450
- fs10.chmod(path12, attr || 438, function() {
451
- callback(true);
452
- });
453
- });
454
- });
455
- } else {
456
- fs10.chmod(path12, attr || 438, function() {
457
- callback(true);
458
- });
459
- }
460
- }
490
+ results.push(pth.normalize(file) + (stat.isDirectory() ? self.sep : ""));
491
+ if (!stat.isDirectory()) {
492
+ if (!--pending) done();
493
+ return;
494
+ }
495
+ self.fs.realpath(file, function(err3, realDir) {
496
+ if (err3) return done(err3);
497
+ if (visited.has(realDir)) {
498
+ if (!--pending) done();
499
+ return;
500
+ }
501
+ visited.add(realDir);
502
+ walk(file, visited, function(err4) {
503
+ if (err4) return done(err4);
504
+ if (!--pending) done();
461
505
  });
462
506
  });
463
507
  });
464
508
  });
465
- },
466
- findFiles: function(path12) {
467
- return findSync(path12, true);
468
- },
469
- getAttributes: function(path12) {
470
- },
471
- setAttributes: function(path12) {
472
- },
473
- toBuffer: function(input) {
474
- if (Buffer.isBuffer(input)) {
475
- return input;
476
- } else {
477
- if (input.length === 0) {
478
- return Buffer.alloc(0);
479
- }
480
- return Buffer.from(input, "utf8");
481
- }
482
- },
483
- readBigUInt64LE,
484
- Constants,
485
- Errors
509
+ });
486
510
  };
487
- })();
511
+ self.fs.realpath(dir, function(err, realDir) {
512
+ if (err) return finish(err);
513
+ walk(dir, /* @__PURE__ */ new Set([realDir]), finish);
514
+ });
515
+ };
516
+ Utils.prototype.getAttributes = function() {
517
+ };
518
+ Utils.prototype.setAttributes = function() {
519
+ };
520
+ Utils.crc32update = function(crc, byte) {
521
+ return crcTable[(crc ^ byte) & 255] ^ crc >>> 8;
522
+ };
523
+ Utils.crc32 = function(buf) {
524
+ if (typeof buf === "string") {
525
+ buf = Buffer.from(buf, "utf8");
526
+ }
527
+ let len = buf.length;
528
+ let crc = ~0;
529
+ for (let off = 0; off < len; ) crc = Utils.crc32update(crc, buf[off++]);
530
+ return ~crc >>> 0;
531
+ };
532
+ Utils.methodToString = function(method) {
533
+ switch (method) {
534
+ case Constants.STORED:
535
+ return "STORED (" + method + ")";
536
+ case Constants.DEFLATED:
537
+ return "DEFLATED (" + method + ")";
538
+ default:
539
+ return "UNSUPPORTED (" + method + ")";
540
+ }
541
+ };
542
+ Utils.canonical = function(path16) {
543
+ if (!path16) return "";
544
+ const safeSuffix = pth.posix.normalize("/" + path16.split("\\").join("/"));
545
+ return pth.join(".", safeSuffix);
546
+ };
547
+ Utils.zipnamefix = function(path16) {
548
+ if (!path16) return "";
549
+ const safeSuffix = pth.posix.normalize("/" + path16.split("\\").join("/"));
550
+ return pth.posix.join(".", safeSuffix);
551
+ };
552
+ Utils.findLast = function(arr, callback) {
553
+ if (!Array.isArray(arr)) throw new TypeError("arr is not array");
554
+ const len = arr.length >>> 0;
555
+ for (let i = len - 1; i >= 0; i--) {
556
+ if (callback(arr[i], i, arr)) {
557
+ return arr[i];
558
+ }
559
+ }
560
+ return void 0;
561
+ };
562
+ Utils.sanitize = function(prefix, name) {
563
+ prefix = pth.resolve(pth.normalize(prefix));
564
+ var parts = name.split("/");
565
+ for (var i = 0, l = parts.length; i < l; i++) {
566
+ var path16 = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
567
+ if (path16 === prefix || path16.startsWith(prefix + pth.sep)) {
568
+ return path16;
569
+ }
570
+ }
571
+ return pth.normalize(pth.join(prefix, pth.basename(name)));
572
+ };
573
+ Utils.toBuffer = function toBuffer(input, encoder) {
574
+ if (Buffer.isBuffer(input)) {
575
+ return input;
576
+ } else if (input instanceof Uint8Array) {
577
+ return Buffer.from(input);
578
+ } else {
579
+ return typeof input === "string" ? encoder(input) : Buffer.alloc(0);
580
+ }
581
+ };
582
+ Utils.readBigUInt64LE = function(buffer, index) {
583
+ const lo = buffer.readUInt32LE(index);
584
+ const hi = buffer.readUInt32LE(index + 4);
585
+ return hi * 4294967296 + lo;
586
+ };
587
+ Utils.writeBigUInt64LE = function(buffer, value, index) {
588
+ const lo = value >>> 0;
589
+ const hi = Math.floor(value / 4294967296) >>> 0;
590
+ buffer.writeUInt32LE(lo, index);
591
+ buffer.writeUInt32LE(hi, index + 4);
592
+ };
593
+ Utils.fromDOS2Date = function(val) {
594
+ return new Date((val >> 25 & 127) + 1980, Math.max((val >> 21 & 15) - 1, 0), Math.max(val >> 16 & 31, 1), val >> 11 & 31, val >> 5 & 63, (val & 31) << 1);
595
+ };
596
+ Utils.fromDate2DOS = function(val) {
597
+ let date = 0;
598
+ let time = 0;
599
+ if (val.getFullYear() > 1979) {
600
+ date = (val.getFullYear() - 1980 & 127) << 9 | val.getMonth() + 1 << 5 | val.getDate();
601
+ time = val.getHours() << 11 | val.getMinutes() << 5 | val.getSeconds() >> 1;
602
+ }
603
+ return date << 16 | time;
604
+ };
605
+ Utils.isWin = isWin;
606
+ Utils.crcTable = crcTable;
488
607
  }
489
608
  });
490
609
 
491
- // ../../node_modules/adm-zip/util/fattr.js
610
+ // node_modules/adm-zip/util/fattr.js
492
611
  var require_fattr = __commonJS({
493
- "../../node_modules/adm-zip/util/fattr.js"(exports, module) {
494
- var fs10 = require_fileSystem().require();
612
+ "node_modules/adm-zip/util/fattr.js"(exports, module) {
495
613
  var pth = __require("path");
496
- fs10.existsSync = fs10.existsSync || pth.existsSync;
497
- module.exports = function(path12) {
498
- var _path = path12 || "", _permissions = 0, _obj = newAttr(), _stat = null;
614
+ module.exports = function(path16, { fs: fs13 }) {
615
+ var _path = path16 || "", _obj = newAttr(), _stat = null;
499
616
  function newAttr() {
500
617
  return {
501
618
  directory: false,
@@ -506,13 +623,13 @@ var require_fattr = __commonJS({
506
623
  atime: 0
507
624
  };
508
625
  }
509
- if (_path && fs10.existsSync(_path)) {
510
- _stat = fs10.statSync(_path);
626
+ if (_path && fs13.existsSync(_path)) {
627
+ _stat = fs13.statSync(_path);
511
628
  _obj.directory = _stat.isDirectory();
512
629
  _obj.mtime = _stat.mtime;
513
630
  _obj.atime = _stat.atime;
514
- _obj.executable = !!(1 & parseInt((_stat.mode & parseInt("777", 8)).toString(8)[0]));
515
- _obj.readonly = !!(2 & parseInt((_stat.mode & parseInt("777", 8)).toString(8)[0]));
631
+ _obj.executable = (73 & _stat.mode) !== 0;
632
+ _obj.readonly = (128 & _stat.mode) === 0;
516
633
  _obj.hidden = pth.basename(_path)[0] === ".";
517
634
  } else {
518
635
  console.warn("Invalid path: " + _path);
@@ -536,42 +653,67 @@ var require_fattr = __commonJS({
536
653
  get executable() {
537
654
  return _obj.executable;
538
655
  },
539
- decodeAttributes: function(val) {
656
+ decodeAttributes: function() {
657
+ },
658
+ encodeAttributes: function() {
540
659
  },
541
- encodeAttributes: function(val) {
660
+ toJSON: function() {
661
+ return {
662
+ path: _path,
663
+ isDirectory: _obj.directory,
664
+ isReadOnly: _obj.readonly,
665
+ isHidden: _obj.hidden,
666
+ isExecutable: _obj.executable,
667
+ mTime: _obj.mtime,
668
+ aTime: _obj.atime
669
+ };
542
670
  },
543
671
  toString: function() {
544
- return '{\n "path" : "' + _path + ',\n "isDirectory" : ' + _obj.directory + ',\n "isReadOnly" : ' + _obj.readonly + ',\n "isHidden" : ' + _obj.hidden + ',\n "isExecutable" : ' + _obj.executable + ',\n "mTime" : ' + _obj.mtime + '\n "aTime" : ' + _obj.atime + "\n}";
672
+ return JSON.stringify(this.toJSON(), null, " ");
545
673
  }
546
674
  };
547
675
  };
548
676
  }
549
677
  });
550
678
 
551
- // ../../node_modules/adm-zip/util/index.js
679
+ // node_modules/adm-zip/util/decoder.js
680
+ var require_decoder = __commonJS({
681
+ "node_modules/adm-zip/util/decoder.js"(exports, module) {
682
+ module.exports = {
683
+ efs: true,
684
+ encode: (data) => Buffer.from(data, "utf8"),
685
+ decode: (data) => data.toString("utf8")
686
+ };
687
+ }
688
+ });
689
+
690
+ // node_modules/adm-zip/util/index.js
552
691
  var require_util = __commonJS({
553
- "../../node_modules/adm-zip/util/index.js"(exports, module) {
692
+ "node_modules/adm-zip/util/index.js"(exports, module) {
554
693
  module.exports = require_utils();
555
- module.exports.FileSystem = require_fileSystem();
556
694
  module.exports.Constants = require_constants();
557
695
  module.exports.Errors = require_errors();
558
696
  module.exports.FileAttr = require_fattr();
697
+ module.exports.decoder = require_decoder();
559
698
  }
560
699
  });
561
700
 
562
- // ../../node_modules/adm-zip/headers/entryHeader.js
701
+ // node_modules/adm-zip/headers/entryHeader.js
563
702
  var require_entryHeader = __commonJS({
564
- "../../node_modules/adm-zip/headers/entryHeader.js"(exports, module) {
703
+ "node_modules/adm-zip/headers/entryHeader.js"(exports, module) {
565
704
  var Utils = require_util();
566
705
  var Constants = Utils.Constants;
567
706
  module.exports = function() {
568
- var _verMade = 10, _version = 10, _flags = 0, _method = 0, _time = 0, _crc = 0, _compressedSize = 0, _size = 0, _fnameLen = 0, _extraLen = 0, _comLen = 0, _diskStart = 0, _inattr = 0, _attr = 0, _offset = 0;
569
- var _dataHeader = {};
570
- function setTime(val) {
571
- val = new Date(val);
572
- _time = (val.getFullYear() - 1980 & 127) << 25 | val.getMonth() + 1 << 21 | val.getDate() << 16 | val.getHours() << 11 | val.getMinutes() << 5 | val.getSeconds() >> 1;
573
- }
574
- setTime(+/* @__PURE__ */ new Date());
707
+ var _verMade = 20, _version = 10, _flags = 0, _method = 0, _time = 0, _crc = 0, _compressedSize = 0, _size = 0, _fnameLen = 0, _extraLen = 0, _comLen = 0, _diskStart = 0, _inattr = 0, _attr = 0, _offset = 0;
708
+ _verMade |= Utils.isWin ? 2560 : 768;
709
+ _flags |= Constants.FLG_EFS;
710
+ const _localHeader = {
711
+ extraLen: 0
712
+ };
713
+ const uint32 = (val) => Math.max(0, val) >>> 0;
714
+ const uint16 = (val) => Math.max(0, val) & 65535;
715
+ const uint8 = (val) => Math.max(0, val) & 255;
716
+ _time = Utils.fromDate2DOS(/* @__PURE__ */ new Date());
575
717
  return {
576
718
  get made() {
577
719
  return _verMade;
@@ -591,42 +733,73 @@ var require_entryHeader = __commonJS({
591
733
  set flags(val) {
592
734
  _flags = val;
593
735
  },
736
+ get flags_efs() {
737
+ return (_flags & Constants.FLG_EFS) > 0;
738
+ },
739
+ set flags_efs(val) {
740
+ if (val) {
741
+ _flags |= Constants.FLG_EFS;
742
+ } else {
743
+ _flags &= ~Constants.FLG_EFS;
744
+ }
745
+ },
746
+ get flags_desc() {
747
+ return (_flags & Constants.FLG_DESC) > 0;
748
+ },
749
+ set flags_desc(val) {
750
+ if (val) {
751
+ _flags |= Constants.FLG_DESC;
752
+ } else {
753
+ _flags &= ~Constants.FLG_DESC;
754
+ }
755
+ },
594
756
  get method() {
595
757
  return _method;
596
758
  },
597
759
  set method(val) {
760
+ switch (val) {
761
+ case Constants.STORED:
762
+ this.version = 10;
763
+ break;
764
+ case Constants.DEFLATED:
765
+ default:
766
+ this.version = 20;
767
+ }
598
768
  _method = val;
599
769
  },
600
770
  get time() {
601
- return new Date(
602
- (_time >> 25 & 127) + 1980,
603
- (_time >> 21 & 15) - 1,
604
- _time >> 16 & 31,
605
- _time >> 11 & 31,
606
- _time >> 5 & 63,
607
- (_time & 31) << 1
608
- );
771
+ return Utils.fromDOS2Date(this.timeval);
609
772
  },
610
773
  set time(val) {
611
- setTime(val);
774
+ val = new Date(val);
775
+ this.timeval = Utils.fromDate2DOS(val);
776
+ },
777
+ get timeval() {
778
+ return _time;
779
+ },
780
+ set timeval(val) {
781
+ _time = uint32(val);
782
+ },
783
+ get timeHighByte() {
784
+ return uint8(_time >>> 8);
612
785
  },
613
786
  get crc() {
614
787
  return _crc;
615
788
  },
616
789
  set crc(val) {
617
- _crc = val;
790
+ _crc = uint32(val);
618
791
  },
619
792
  get compressedSize() {
620
793
  return _compressedSize;
621
794
  },
622
795
  set compressedSize(val) {
623
- _compressedSize = val;
796
+ _compressedSize = uint32(val);
624
797
  },
625
798
  get size() {
626
799
  return _size;
627
800
  },
628
801
  set size(val) {
629
- _size = val;
802
+ _size = uint32(val);
630
803
  },
631
804
  get fileNameLength() {
632
805
  return _fnameLen;
@@ -640,6 +813,12 @@ var require_entryHeader = __commonJS({
640
813
  set extraLength(val) {
641
814
  _extraLen = val;
642
815
  },
816
+ get extraLocalLength() {
817
+ return _localHeader.extraLen;
818
+ },
819
+ set extraLocalLength(val) {
820
+ _localHeader.extraLen = val;
821
+ },
643
822
  get commentLength() {
644
823
  return _comLen;
645
824
  },
@@ -650,67 +829,64 @@ var require_entryHeader = __commonJS({
650
829
  return _diskStart;
651
830
  },
652
831
  set diskNumStart(val) {
653
- _diskStart = val;
832
+ _diskStart = uint32(val);
654
833
  },
655
834
  get inAttr() {
656
835
  return _inattr;
657
836
  },
658
837
  set inAttr(val) {
659
- _inattr = val;
838
+ _inattr = uint32(val);
660
839
  },
661
840
  get attr() {
662
841
  return _attr;
663
842
  },
664
843
  set attr(val) {
665
- _attr = val;
844
+ _attr = uint32(val);
845
+ },
846
+ // get Unix file permissions
847
+ get fileAttr() {
848
+ return (_attr || 0) >> 16 & 4095;
666
849
  },
667
850
  get offset() {
668
851
  return _offset;
669
852
  },
670
853
  set offset(val) {
671
- _offset = val;
854
+ _offset = uint32(val);
672
855
  },
673
- get encripted() {
674
- return (_flags & 1) === 1;
856
+ get encrypted() {
857
+ return (_flags & Constants.FLG_ENC) === Constants.FLG_ENC;
675
858
  },
676
- get entryHeaderSize() {
859
+ get centralHeaderSize() {
677
860
  return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
678
861
  },
679
862
  get realDataOffset() {
680
- return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
863
+ return _offset + Constants.LOCHDR + _localHeader.fnameLen + _localHeader.extraLen;
681
864
  },
682
- get dataHeader() {
683
- return _dataHeader;
865
+ get localHeader() {
866
+ return _localHeader;
684
867
  },
685
- loadDataHeaderFromBinary: function(input) {
868
+ loadLocalHeaderFromBinary: function(input) {
686
869
  var data = input.slice(_offset, _offset + Constants.LOCHDR);
687
870
  if (data.readUInt32LE(0) !== Constants.LOCSIG) {
688
- throw new Error(Utils.Errors.INVALID_LOC);
871
+ throw Utils.Errors.INVALID_LOC();
689
872
  }
690
- _dataHeader = {
691
- // version needed to extract
692
- version: data.readUInt16LE(Constants.LOCVER),
693
- // general purpose bit flag
694
- flags: data.readUInt16LE(Constants.LOCFLG),
695
- // compression method
696
- method: data.readUInt16LE(Constants.LOCHOW),
697
- // modification time (2 bytes time, 2 bytes date)
698
- time: data.readUInt32LE(Constants.LOCTIM),
699
- // uncompressed file crc-32 value
700
- crc: data.readUInt32LE(Constants.LOCCRC),
701
- // compressed size
702
- compressedSize: data.readUInt32LE(Constants.LOCSIZ),
703
- // uncompressed size
704
- size: data.readUInt32LE(Constants.LOCLEN),
705
- // filename length
706
- fnameLen: data.readUInt16LE(Constants.LOCNAM),
707
- // extra field length
708
- extraLen: data.readUInt16LE(Constants.LOCEXT)
709
- };
873
+ _localHeader.version = data.readUInt16LE(Constants.LOCVER);
874
+ _localHeader.flags = data.readUInt16LE(Constants.LOCFLG);
875
+ _localHeader.flags_desc = (_localHeader.flags & Constants.FLG_DESC) > 0;
876
+ _localHeader.method = data.readUInt16LE(Constants.LOCHOW);
877
+ _localHeader.time = data.readUInt32LE(Constants.LOCTIM);
878
+ _localHeader.crc = data.readUInt32LE(Constants.LOCCRC);
879
+ _localHeader.compressedSize = data.readUInt32LE(Constants.LOCSIZ);
880
+ _localHeader.size = data.readUInt32LE(Constants.LOCLEN);
881
+ _localHeader.fnameLen = data.readUInt16LE(Constants.LOCNAM);
882
+ _localHeader.extraLen = data.readUInt16LE(Constants.LOCEXT);
883
+ const extraStart = _offset + Constants.LOCHDR + _localHeader.fnameLen;
884
+ const extraEnd = extraStart + _localHeader.extraLen;
885
+ return input.slice(extraStart, extraEnd);
710
886
  },
711
887
  loadFromBinary: function(data) {
712
888
  if (data.length !== Constants.CENHDR || data.readUInt32LE(0) !== Constants.CENSIG) {
713
- throw new Error(Utils.Errors.INVALID_CEN);
889
+ throw Utils.Errors.INVALID_CEN();
714
890
  }
715
891
  _verMade = data.readUInt16LE(Constants.CENVEM);
716
892
  _version = data.readUInt16LE(Constants.CENVER);
@@ -728,26 +904,26 @@ var require_entryHeader = __commonJS({
728
904
  _attr = data.readUInt32LE(Constants.CENATX);
729
905
  _offset = data.readUInt32LE(Constants.CENOFF);
730
906
  },
731
- dataHeaderToBinary: function() {
907
+ localHeaderToBinary: function() {
732
908
  var data = Buffer.alloc(Constants.LOCHDR);
733
909
  data.writeUInt32LE(Constants.LOCSIG, 0);
734
910
  data.writeUInt16LE(_version, Constants.LOCVER);
735
- data.writeUInt16LE(_flags, Constants.LOCFLG);
911
+ data.writeUInt16LE(_flags & ~Constants.FLG_DESC, Constants.LOCFLG);
736
912
  data.writeUInt16LE(_method, Constants.LOCHOW);
737
913
  data.writeUInt32LE(_time, Constants.LOCTIM);
738
914
  data.writeUInt32LE(_crc, Constants.LOCCRC);
739
915
  data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
740
916
  data.writeUInt32LE(_size, Constants.LOCLEN);
741
917
  data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
742
- data.writeUInt16LE(_extraLen, Constants.LOCEXT);
918
+ data.writeUInt16LE(_localHeader.extraLen, Constants.LOCEXT);
743
919
  return data;
744
920
  },
745
- entryHeaderToBinary: function() {
921
+ centralHeaderToBinary: function() {
746
922
  var data = Buffer.alloc(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
747
923
  data.writeUInt32LE(Constants.CENSIG, 0);
748
924
  data.writeUInt16LE(_verMade, Constants.CENVEM);
749
925
  data.writeUInt16LE(_version, Constants.CENVER);
750
- data.writeUInt16LE(_flags, Constants.CENFLG);
926
+ data.writeUInt16LE(_flags & ~Constants.FLG_DESC, Constants.CENFLG);
751
927
  data.writeUInt16LE(_method, Constants.CENHOW);
752
928
  data.writeUInt32LE(_time, Constants.CENTIM);
753
929
  data.writeUInt32LE(_crc, Constants.CENCRC);
@@ -760,24 +936,47 @@ var require_entryHeader = __commonJS({
760
936
  data.writeUInt16LE(_inattr, Constants.CENATT);
761
937
  data.writeUInt32LE(_attr, Constants.CENATX);
762
938
  data.writeUInt32LE(_offset, Constants.CENOFF);
763
- data.fill(0, Constants.CENHDR);
764
939
  return data;
765
940
  },
941
+ toJSON: function() {
942
+ const bytes = function(nr) {
943
+ return nr + " bytes";
944
+ };
945
+ return {
946
+ made: _verMade,
947
+ version: _version,
948
+ flags: _flags,
949
+ method: Utils.methodToString(_method),
950
+ time: this.time,
951
+ crc: "0x" + _crc.toString(16).toUpperCase(),
952
+ compressedSize: bytes(_compressedSize),
953
+ size: bytes(_size),
954
+ fileNameLength: bytes(_fnameLen),
955
+ extraLength: bytes(_extraLen),
956
+ commentLength: bytes(_comLen),
957
+ diskNumStart: _diskStart,
958
+ inAttr: _inattr,
959
+ attr: _attr,
960
+ offset: _offset,
961
+ centralHeaderSize: bytes(Constants.CENHDR + _fnameLen + _extraLen + _comLen)
962
+ };
963
+ },
766
964
  toString: function() {
767
- return '{\n "made" : ' + _verMade + ',\n "version" : ' + _version + ',\n "flags" : ' + _flags + ',\n "method" : ' + Utils.methodToString(_method) + ',\n "time" : ' + this.time + ',\n "crc" : 0x' + _crc.toString(16).toUpperCase() + ',\n "compressedSize" : ' + _compressedSize + ' bytes,\n "size" : ' + _size + ' bytes,\n "fileNameLength" : ' + _fnameLen + ',\n "extraLength" : ' + _extraLen + ' bytes,\n "commentLength" : ' + _comLen + ' bytes,\n "diskNumStart" : ' + _diskStart + ',\n "inAttr" : ' + _inattr + ',\n "attr" : ' + _attr + ',\n "offset" : ' + _offset + ',\n "entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n}";
965
+ return JSON.stringify(this.toJSON(), null, " ");
768
966
  }
769
967
  };
770
968
  };
771
969
  }
772
970
  });
773
971
 
774
- // ../../node_modules/adm-zip/headers/mainHeader.js
972
+ // node_modules/adm-zip/headers/mainHeader.js
775
973
  var require_mainHeader = __commonJS({
776
- "../../node_modules/adm-zip/headers/mainHeader.js"(exports, module) {
974
+ "node_modules/adm-zip/headers/mainHeader.js"(exports, module) {
777
975
  var Utils = require_util();
778
976
  var Constants = Utils.Constants;
779
977
  module.exports = function() {
780
978
  var _volumeEntries = 0, _totalEntries = 0, _size = 0, _offset = 0, _commentLength = 0;
979
+ const needsZip64 = () => _volumeEntries > Constants.EF_ZIP64_OR_16 || _totalEntries > Constants.EF_ZIP64_OR_16 || _size > Constants.EF_ZIP64_OR_32 || _offset > Constants.EF_ZIP64_OR_32;
781
980
  return {
782
981
  get diskEntries() {
783
982
  return _volumeEntries;
@@ -810,11 +1009,11 @@ var require_mainHeader = __commonJS({
810
1009
  _commentLength = val;
811
1010
  },
812
1011
  get mainHeaderSize() {
813
- return Constants.ENDHDR + _commentLength;
1012
+ return (needsZip64() ? Constants.ZIP64HDR + Constants.END64HDR : 0) + Constants.ENDHDR + _commentLength;
814
1013
  },
815
1014
  loadFromBinary: function(data) {
816
1015
  if ((data.length !== Constants.ENDHDR || data.readUInt32LE(0) !== Constants.ENDSIG) && (data.length < Constants.ZIP64HDR || data.readUInt32LE(0) !== Constants.ZIP64SIG)) {
817
- throw new Error(Utils.Errors.INVALID_END);
1016
+ throw Utils.Errors.INVALID_END();
818
1017
  }
819
1018
  if (data.readUInt32LE(0) === Constants.ENDSIG) {
820
1019
  _volumeEntries = data.readUInt16LE(Constants.ENDSUB);
@@ -825,42 +1024,86 @@ var require_mainHeader = __commonJS({
825
1024
  } else {
826
1025
  _volumeEntries = Utils.readBigUInt64LE(data, Constants.ZIP64SUB);
827
1026
  _totalEntries = Utils.readBigUInt64LE(data, Constants.ZIP64TOT);
828
- _size = Utils.readBigUInt64LE(data, Constants.ZIP64SIZ);
1027
+ _size = Utils.readBigUInt64LE(data, Constants.ZIP64SIZB);
829
1028
  _offset = Utils.readBigUInt64LE(data, Constants.ZIP64OFF);
830
1029
  _commentLength = 0;
831
1030
  }
832
1031
  },
833
1032
  toBinary: function() {
834
- var b = Buffer.alloc(Constants.ENDHDR + _commentLength);
835
- b.writeUInt32LE(Constants.ENDSIG, 0);
836
- b.writeUInt32LE(0, 4);
837
- b.writeUInt16LE(_volumeEntries, Constants.ENDSUB);
838
- b.writeUInt16LE(_totalEntries, Constants.ENDTOT);
839
- b.writeUInt32LE(_size, Constants.ENDSIZ);
840
- b.writeUInt32LE(_offset, Constants.ENDOFF);
841
- b.writeUInt16LE(_commentLength, Constants.ENDCOM);
842
- b.fill(" ", Constants.ENDHDR);
1033
+ if (!needsZip64()) {
1034
+ var b = Buffer.alloc(Constants.ENDHDR + _commentLength);
1035
+ b.writeUInt32LE(Constants.ENDSIG, 0);
1036
+ b.writeUInt32LE(0, 4);
1037
+ b.writeUInt16LE(_volumeEntries, Constants.ENDSUB);
1038
+ b.writeUInt16LE(_totalEntries, Constants.ENDTOT);
1039
+ b.writeUInt32LE(_size, Constants.ENDSIZ);
1040
+ b.writeUInt32LE(_offset, Constants.ENDOFF);
1041
+ b.writeUInt16LE(_commentLength, Constants.ENDCOM);
1042
+ b.fill(" ", Constants.ENDHDR);
1043
+ return b;
1044
+ }
1045
+ var b = Buffer.alloc(this.mainHeaderSize);
1046
+ let offset = 0;
1047
+ b.writeUInt32LE(Constants.ZIP64SIG, offset);
1048
+ Utils.writeBigUInt64LE(b, Constants.ZIP64HDR - Constants.ZIP64LEAD, offset + Constants.ZIP64SIZE);
1049
+ b.writeUInt16LE(45, offset + Constants.ZIP64VEM);
1050
+ b.writeUInt16LE(45, offset + Constants.ZIP64VER);
1051
+ b.writeUInt32LE(0, offset + Constants.ZIP64DSK);
1052
+ b.writeUInt32LE(0, offset + Constants.ZIP64DSKDIR);
1053
+ Utils.writeBigUInt64LE(b, _volumeEntries, offset + Constants.ZIP64SUB);
1054
+ Utils.writeBigUInt64LE(b, _totalEntries, offset + Constants.ZIP64TOT);
1055
+ Utils.writeBigUInt64LE(b, _size, offset + Constants.ZIP64SIZB);
1056
+ Utils.writeBigUInt64LE(b, _offset, offset + Constants.ZIP64OFF);
1057
+ const zip64EndOffset = _offset + _size;
1058
+ offset += Constants.ZIP64HDR;
1059
+ b.writeUInt32LE(Constants.END64SIG, offset);
1060
+ b.writeUInt32LE(0, offset + Constants.END64START);
1061
+ Utils.writeBigUInt64LE(b, zip64EndOffset, offset + Constants.END64OFF);
1062
+ b.writeUInt32LE(1, offset + Constants.END64NUMDISKS);
1063
+ offset += Constants.END64HDR;
1064
+ b.writeUInt32LE(Constants.ENDSIG, offset);
1065
+ b.writeUInt32LE(0, offset + 4);
1066
+ b.writeUInt16LE(Math.min(_volumeEntries, Constants.EF_ZIP64_OR_16), offset + Constants.ENDSUB);
1067
+ b.writeUInt16LE(Math.min(_totalEntries, Constants.EF_ZIP64_OR_16), offset + Constants.ENDTOT);
1068
+ b.writeUInt32LE(Math.min(_size, Constants.EF_ZIP64_OR_32), offset + Constants.ENDSIZ);
1069
+ b.writeUInt32LE(Math.min(_offset, Constants.EF_ZIP64_OR_32), offset + Constants.ENDOFF);
1070
+ b.writeUInt16LE(_commentLength, offset + Constants.ENDCOM);
1071
+ b.fill(" ", offset + Constants.ENDHDR);
843
1072
  return b;
844
1073
  },
1074
+ toJSON: function() {
1075
+ const offset = function(nr, len) {
1076
+ let offs = nr.toString(16).toUpperCase();
1077
+ while (offs.length < len) offs = "0" + offs;
1078
+ return "0x" + offs;
1079
+ };
1080
+ return {
1081
+ diskEntries: _volumeEntries,
1082
+ totalEntries: _totalEntries,
1083
+ size: _size + " bytes",
1084
+ offset: offset(_offset, 4),
1085
+ commentLength: _commentLength
1086
+ };
1087
+ },
845
1088
  toString: function() {
846
- return '{\n "diskEntries" : ' + _volumeEntries + ',\n "totalEntries" : ' + _totalEntries + ',\n "size" : ' + _size + ' bytes,\n "offset" : 0x' + _offset.toString(16).toUpperCase() + ',\n "commentLength" : 0x' + _commentLength + "\n}";
1089
+ return JSON.stringify(this.toJSON(), null, " ");
847
1090
  }
848
1091
  };
849
1092
  };
850
1093
  }
851
1094
  });
852
1095
 
853
- // ../../node_modules/adm-zip/headers/index.js
1096
+ // node_modules/adm-zip/headers/index.js
854
1097
  var require_headers = __commonJS({
855
- "../../node_modules/adm-zip/headers/index.js"(exports) {
1098
+ "node_modules/adm-zip/headers/index.js"(exports) {
856
1099
  exports.EntryHeader = require_entryHeader();
857
1100
  exports.MainHeader = require_mainHeader();
858
1101
  }
859
1102
  });
860
1103
 
861
- // ../../node_modules/adm-zip/methods/deflater.js
1104
+ // node_modules/adm-zip/methods/deflater.js
862
1105
  var require_deflater = __commonJS({
863
- "../../node_modules/adm-zip/methods/deflater.js"(exports, module) {
1106
+ "node_modules/adm-zip/methods/deflater.js"(exports, module) {
864
1107
  module.exports = function(inbuf) {
865
1108
  var zlib = __require("zlib");
866
1109
  var opts = { chunkSize: (parseInt(inbuf.length / 1024) + 1) * 1024 };
@@ -891,17 +1134,19 @@ var require_deflater = __commonJS({
891
1134
  }
892
1135
  });
893
1136
 
894
- // ../../node_modules/adm-zip/methods/inflater.js
1137
+ // node_modules/adm-zip/methods/inflater.js
895
1138
  var require_inflater = __commonJS({
896
- "../../node_modules/adm-zip/methods/inflater.js"(exports, module) {
897
- module.exports = function(inbuf) {
1139
+ "node_modules/adm-zip/methods/inflater.js"(exports, module) {
1140
+ var version = +(process?.versions?.node ?? "").split(".")[0] || 0;
1141
+ module.exports = function(inbuf, expectedLength) {
898
1142
  var zlib = __require("zlib");
1143
+ const option = version >= 15 && expectedLength > 0 ? { maxOutputLength: expectedLength } : {};
899
1144
  return {
900
1145
  inflate: function() {
901
- return zlib.inflateRawSync(inbuf);
1146
+ return zlib.inflateRawSync(inbuf, option);
902
1147
  },
903
1148
  inflateAsync: function(callback) {
904
- var tmp = zlib.createInflateRaw(), parts = [], total = 0;
1149
+ var tmp = zlib.createInflateRaw(option), parts = [], total = 0;
905
1150
  tmp.on("data", function(data) {
906
1151
  parts.push(data);
907
1152
  total += data.length;
@@ -923,38 +1168,153 @@ var require_inflater = __commonJS({
923
1168
  }
924
1169
  });
925
1170
 
926
- // ../../node_modules/adm-zip/methods/index.js
1171
+ // node_modules/adm-zip/methods/zipcrypto.js
1172
+ var require_zipcrypto = __commonJS({
1173
+ "node_modules/adm-zip/methods/zipcrypto.js"(exports, module) {
1174
+ "use strict";
1175
+ var { randomFillSync } = __require("crypto");
1176
+ var Errors = require_errors();
1177
+ var crctable = new Uint32Array(256).map((t, crc) => {
1178
+ for (let j = 0; j < 8; j++) {
1179
+ if (0 !== (crc & 1)) {
1180
+ crc = crc >>> 1 ^ 3988292384;
1181
+ } else {
1182
+ crc >>>= 1;
1183
+ }
1184
+ }
1185
+ return crc >>> 0;
1186
+ });
1187
+ var uMul = (a, b) => Math.imul(a, b) >>> 0;
1188
+ var crc32update = (pCrc32, bval) => {
1189
+ return crctable[(pCrc32 ^ bval) & 255] ^ pCrc32 >>> 8;
1190
+ };
1191
+ var genSalt = () => {
1192
+ if ("function" === typeof randomFillSync) {
1193
+ return randomFillSync(Buffer.alloc(12));
1194
+ } else {
1195
+ return genSalt.node();
1196
+ }
1197
+ };
1198
+ genSalt.node = () => {
1199
+ const salt = Buffer.alloc(12);
1200
+ const len = salt.length;
1201
+ for (let i = 0; i < len; i++) salt[i] = Math.random() * 256 & 255;
1202
+ return salt;
1203
+ };
1204
+ var config = {
1205
+ genSalt
1206
+ };
1207
+ function Initkeys(pw) {
1208
+ const pass = Buffer.isBuffer(pw) ? pw : Buffer.from(pw);
1209
+ this.keys = new Uint32Array([305419896, 591751049, 878082192]);
1210
+ for (let i = 0; i < pass.length; i++) {
1211
+ this.updateKeys(pass[i]);
1212
+ }
1213
+ }
1214
+ Initkeys.prototype.updateKeys = function(byteValue) {
1215
+ const keys = this.keys;
1216
+ keys[0] = crc32update(keys[0], byteValue);
1217
+ keys[1] += keys[0] & 255;
1218
+ keys[1] = uMul(keys[1], 134775813) + 1;
1219
+ keys[2] = crc32update(keys[2], keys[1] >>> 24);
1220
+ return byteValue;
1221
+ };
1222
+ Initkeys.prototype.next = function() {
1223
+ const k = (this.keys[2] | 2) >>> 0;
1224
+ return uMul(k, k ^ 1) >> 8 & 255;
1225
+ };
1226
+ function make_decrypter(pwd) {
1227
+ const keys = new Initkeys(pwd);
1228
+ return function(data) {
1229
+ const result = Buffer.alloc(data.length);
1230
+ let pos = 0;
1231
+ for (let c of data) {
1232
+ result[pos++] = keys.updateKeys(c ^ keys.next());
1233
+ }
1234
+ return result;
1235
+ };
1236
+ }
1237
+ function make_encrypter(pwd) {
1238
+ const keys = new Initkeys(pwd);
1239
+ return function(data, result, pos = 0) {
1240
+ if (!result) result = Buffer.alloc(data.length);
1241
+ for (let c of data) {
1242
+ const k = keys.next();
1243
+ result[pos++] = c ^ k;
1244
+ keys.updateKeys(c);
1245
+ }
1246
+ return result;
1247
+ };
1248
+ }
1249
+ function decrypt(data, header, pwd) {
1250
+ if (!data || !Buffer.isBuffer(data) || data.length < 12) {
1251
+ return Buffer.alloc(0);
1252
+ }
1253
+ const decrypter = make_decrypter(pwd);
1254
+ const salt = decrypter(data.slice(0, 12));
1255
+ const verifyByte = (header.flags & 8) === 8 ? header.timeHighByte : header.crc >>> 24;
1256
+ if (salt[11] !== verifyByte) {
1257
+ throw Errors.WRONG_PASSWORD();
1258
+ }
1259
+ return decrypter(data.slice(12));
1260
+ }
1261
+ function _salter(data) {
1262
+ if (Buffer.isBuffer(data) && data.length >= 12) {
1263
+ config.genSalt = function() {
1264
+ return data.slice(0, 12);
1265
+ };
1266
+ } else if (data === "node") {
1267
+ config.genSalt = genSalt.node;
1268
+ } else {
1269
+ config.genSalt = genSalt;
1270
+ }
1271
+ }
1272
+ function encrypt(data, header, pwd, oldlike = false) {
1273
+ if (data == null) data = Buffer.alloc(0);
1274
+ if (!Buffer.isBuffer(data)) data = Buffer.from(data.toString());
1275
+ const encrypter = make_encrypter(pwd);
1276
+ const salt = config.genSalt();
1277
+ salt[11] = header.crc >>> 24 & 255;
1278
+ if (oldlike) salt[10] = header.crc >>> 16 & 255;
1279
+ const result = Buffer.alloc(data.length + 12);
1280
+ encrypter(salt, result);
1281
+ return encrypter(data, result, 12);
1282
+ }
1283
+ module.exports = { decrypt, encrypt, _salter };
1284
+ }
1285
+ });
1286
+
1287
+ // node_modules/adm-zip/methods/index.js
927
1288
  var require_methods = __commonJS({
928
- "../../node_modules/adm-zip/methods/index.js"(exports) {
1289
+ "node_modules/adm-zip/methods/index.js"(exports) {
929
1290
  exports.Deflater = require_deflater();
930
1291
  exports.Inflater = require_inflater();
1292
+ exports.ZipCrypto = require_zipcrypto();
931
1293
  }
932
1294
  });
933
1295
 
934
- // ../../node_modules/adm-zip/zipEntry.js
1296
+ // node_modules/adm-zip/zipEntry.js
935
1297
  var require_zipEntry = __commonJS({
936
- "../../node_modules/adm-zip/zipEntry.js"(exports, module) {
1298
+ "node_modules/adm-zip/zipEntry.js"(exports, module) {
937
1299
  var Utils = require_util();
938
1300
  var Headers = require_headers();
939
1301
  var Constants = Utils.Constants;
940
1302
  var Methods = require_methods();
941
- module.exports = function(input) {
942
- var _entryHeader = new Headers.EntryHeader(), _entryName = Buffer.alloc(0), _comment = Buffer.alloc(0), _isDirectory = false, uncompressedData = null, _extra = Buffer.alloc(0);
1303
+ module.exports = function(options, input) {
1304
+ var _centralHeader = new Headers.EntryHeader(), _entryName = Buffer.alloc(0), _comment = Buffer.alloc(0), _isDirectory = false, uncompressedData = null, _extra = Buffer.alloc(0), _extralocal = Buffer.alloc(0), _efs = true;
1305
+ const opts = options;
1306
+ const decoder = typeof opts.decoder === "object" ? opts.decoder : Utils.decoder;
1307
+ _efs = decoder.hasOwnProperty("efs") ? decoder.efs : false;
943
1308
  function getCompressedDataFromZip() {
944
- if (!input || !Buffer.isBuffer(input)) {
1309
+ if (!input || !(input instanceof Uint8Array)) {
945
1310
  return Buffer.alloc(0);
946
1311
  }
947
- _entryHeader.loadDataHeaderFromBinary(input);
948
- return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize);
1312
+ _extralocal = _centralHeader.loadLocalHeaderFromBinary(input);
1313
+ return input.slice(_centralHeader.realDataOffset, _centralHeader.realDataOffset + _centralHeader.compressedSize);
949
1314
  }
950
1315
  function crc32OK(data) {
951
- if ((_entryHeader.flags & 8) !== 8) {
952
- if (Utils.crc32(data) !== _entryHeader.dataHeader.crc) {
953
- return false;
954
- }
955
- } else {
956
- }
957
- return true;
1316
+ const expectedCrc = _centralHeader.flags_desc || _centralHeader.localHeader.flags_desc ? _centralHeader.crc : _centralHeader.localHeader.crc;
1317
+ return Utils.crc32(data) === expectedCrc;
958
1318
  }
959
1319
  function decompress(async, callback, pass) {
960
1320
  if (typeof callback === "undefined" && typeof async === "string") {
@@ -963,7 +1323,7 @@ var require_zipEntry = __commonJS({
963
1323
  }
964
1324
  if (_isDirectory) {
965
1325
  if (async && callback) {
966
- callback(Buffer.alloc(0), Utils.Errors.DIRECTORY_CONTENT_ERROR);
1326
+ callback(Buffer.alloc(0), Utils.Errors.DIRECTORY_CONTENT_ERROR());
967
1327
  }
968
1328
  return Buffer.alloc(0);
969
1329
  }
@@ -972,40 +1332,47 @@ var require_zipEntry = __commonJS({
972
1332
  if (async && callback) callback(compressedData);
973
1333
  return compressedData;
974
1334
  }
975
- var data = Buffer.alloc(_entryHeader.size);
976
- switch (_entryHeader.method) {
1335
+ if (_centralHeader.encrypted) {
1336
+ if ("string" !== typeof pass && !Buffer.isBuffer(pass)) {
1337
+ throw Utils.Errors.INVALID_PASS_PARAM();
1338
+ }
1339
+ compressedData = Methods.ZipCrypto.decrypt(compressedData, _centralHeader, pass);
1340
+ }
1341
+ var data;
1342
+ switch (_centralHeader.method) {
977
1343
  case Utils.Constants.STORED:
1344
+ data = Buffer.alloc(compressedData.length);
978
1345
  compressedData.copy(data);
979
1346
  if (!crc32OK(data)) {
980
- if (async && callback) callback(data, Utils.Errors.BAD_CRC);
981
- throw new Error(Utils.Errors.BAD_CRC);
1347
+ if (async && callback) callback(data, Utils.Errors.BAD_CRC());
1348
+ throw Utils.Errors.BAD_CRC();
982
1349
  } else {
983
1350
  if (async && callback) callback(data);
984
1351
  return data;
985
1352
  }
986
1353
  case Utils.Constants.DEFLATED:
987
- var inflater = new Methods.Inflater(compressedData);
1354
+ var inflater = new Methods.Inflater(compressedData, _centralHeader.size);
988
1355
  if (!async) {
989
- var result = inflater.inflate(data);
990
- result.copy(data, 0);
1356
+ data = inflater.inflate();
991
1357
  if (!crc32OK(data)) {
992
- throw new Error(Utils.Errors.BAD_CRC + " " + _entryName.toString());
1358
+ throw Utils.Errors.BAD_CRC(`"${decoder.decode(_entryName)}"`);
993
1359
  }
994
1360
  return data;
995
1361
  } else {
996
- inflater.inflateAsync(function(result2) {
997
- result2.copy(data, 0);
998
- if (!crc32OK(data)) {
999
- if (callback) callback(data, Utils.Errors.BAD_CRC);
1000
- } else {
1001
- if (callback) callback(data);
1362
+ inflater.inflateAsync(function(result) {
1363
+ if (callback) {
1364
+ if (!crc32OK(result)) {
1365
+ callback(result, Utils.Errors.BAD_CRC());
1366
+ } else {
1367
+ callback(result);
1368
+ }
1002
1369
  }
1003
1370
  });
1004
1371
  }
1005
1372
  break;
1006
1373
  default:
1007
- if (async && callback) callback(Buffer.alloc(0), Utils.Errors.UNKNOWN_METHOD);
1008
- throw new Error(Utils.Errors.UNKNOWN_METHOD);
1374
+ if (async && callback) callback(Buffer.alloc(0), Utils.Errors.UNKNOWN_METHOD());
1375
+ throw Utils.Errors.UNKNOWN_METHOD();
1009
1376
  }
1010
1377
  }
1011
1378
  function compress(async, callback) {
@@ -1015,9 +1382,9 @@ var require_zipEntry = __commonJS({
1015
1382
  }
1016
1383
  if (uncompressedData.length && !_isDirectory) {
1017
1384
  var compressedData;
1018
- switch (_entryHeader.method) {
1385
+ switch (_centralHeader.method) {
1019
1386
  case Utils.Constants.STORED:
1020
- _entryHeader.compressedSize = _entryHeader.size;
1387
+ _centralHeader.compressedSize = _centralHeader.size;
1021
1388
  compressedData = Buffer.alloc(uncompressedData.length);
1022
1389
  uncompressedData.copy(compressedData);
1023
1390
  if (async && callback) callback(compressedData);
@@ -1027,12 +1394,12 @@ var require_zipEntry = __commonJS({
1027
1394
  var deflater = new Methods.Deflater(uncompressedData);
1028
1395
  if (!async) {
1029
1396
  var deflated = deflater.deflate();
1030
- _entryHeader.compressedSize = deflated.length;
1397
+ _centralHeader.compressedSize = deflated.length;
1031
1398
  return deflated;
1032
1399
  } else {
1033
1400
  deflater.deflateAsync(function(data) {
1034
1401
  compressedData = Buffer.alloc(data.length);
1035
- _entryHeader.compressedSize = data.length;
1402
+ _centralHeader.compressedSize = data.length;
1036
1403
  data.copy(compressedData);
1037
1404
  callback && callback(compressedData);
1038
1405
  });
@@ -1040,90 +1407,100 @@ var require_zipEntry = __commonJS({
1040
1407
  deflater = null;
1041
1408
  break;
1042
1409
  }
1410
+ } else if (async && callback) {
1411
+ callback(Buffer.alloc(0));
1043
1412
  } else {
1044
- if (async && callback) {
1045
- callback(Buffer.alloc(0));
1046
- } else {
1047
- return Buffer.alloc(0);
1048
- }
1413
+ return Buffer.alloc(0);
1049
1414
  }
1050
1415
  }
1051
1416
  function readUInt64LE(buffer, offset) {
1052
- return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
1417
+ return Utils.readBigUInt64LE(buffer, offset);
1053
1418
  }
1054
1419
  function parseExtra(data) {
1055
- var offset = 0;
1056
- var signature, size, part;
1057
- while (offset < data.length) {
1058
- signature = data.readUInt16LE(offset);
1059
- offset += 2;
1060
- size = data.readUInt16LE(offset);
1061
- offset += 2;
1062
- part = data.slice(offset, offset + size);
1063
- offset += size;
1064
- if (Constants.ID_ZIP64 === signature) {
1065
- parseZip64ExtendedInformation(part);
1420
+ try {
1421
+ var offset = 0;
1422
+ var signature, size, part;
1423
+ while (offset + 4 < data.length) {
1424
+ signature = data.readUInt16LE(offset);
1425
+ offset += 2;
1426
+ size = data.readUInt16LE(offset);
1427
+ offset += 2;
1428
+ part = data.slice(offset, offset + size);
1429
+ offset += size;
1430
+ if (Constants.ID_ZIP64 === signature) {
1431
+ parseZip64ExtendedInformation(part);
1432
+ }
1066
1433
  }
1434
+ } catch (error) {
1435
+ throw Utils.Errors.EXTRA_FIELD_PARSE_ERROR();
1067
1436
  }
1068
1437
  }
1069
1438
  function parseZip64ExtendedInformation(data) {
1070
1439
  var size, compressedSize, offset, diskNumStart;
1071
1440
  if (data.length >= Constants.EF_ZIP64_SCOMP) {
1072
1441
  size = readUInt64LE(data, Constants.EF_ZIP64_SUNCOMP);
1073
- if (_entryHeader.size === Constants.EF_ZIP64_OR_32) {
1074
- _entryHeader.size = size;
1442
+ if (_centralHeader.size === Constants.EF_ZIP64_OR_32) {
1443
+ _centralHeader.size = size;
1075
1444
  }
1076
1445
  }
1077
1446
  if (data.length >= Constants.EF_ZIP64_RHO) {
1078
1447
  compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
1079
- if (_entryHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
1080
- _entryHeader.compressedSize = compressedSize;
1448
+ if (_centralHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
1449
+ _centralHeader.compressedSize = compressedSize;
1081
1450
  }
1082
1451
  }
1083
1452
  if (data.length >= Constants.EF_ZIP64_DSN) {
1084
1453
  offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
1085
- if (_entryHeader.offset === Constants.EF_ZIP64_OR_32) {
1086
- _entryHeader.offset = offset;
1454
+ if (_centralHeader.offset === Constants.EF_ZIP64_OR_32) {
1455
+ _centralHeader.offset = offset;
1087
1456
  }
1088
1457
  }
1089
1458
  if (data.length >= Constants.EF_ZIP64_DSN + 4) {
1090
1459
  diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
1091
- if (_entryHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
1092
- _entryHeader.diskNumStart = diskNumStart;
1460
+ if (_centralHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
1461
+ _centralHeader.diskNumStart = diskNumStart;
1093
1462
  }
1094
1463
  }
1095
1464
  }
1096
1465
  return {
1097
1466
  get entryName() {
1098
- return _entryName.toString();
1467
+ return decoder.decode(_entryName);
1099
1468
  },
1100
1469
  get rawEntryName() {
1101
1470
  return _entryName;
1102
1471
  },
1103
1472
  set entryName(val) {
1104
- _entryName = Utils.toBuffer(val);
1473
+ _entryName = Utils.toBuffer(val, decoder.encode);
1105
1474
  var lastChar = _entryName[_entryName.length - 1];
1106
1475
  _isDirectory = lastChar === 47 || lastChar === 92;
1107
- _entryHeader.fileNameLength = _entryName.length;
1476
+ _centralHeader.fileNameLength = _entryName.length;
1477
+ },
1478
+ get efs() {
1479
+ if (typeof _efs === "function") {
1480
+ return _efs(this.entryName);
1481
+ } else {
1482
+ return _efs;
1483
+ }
1108
1484
  },
1109
1485
  get extra() {
1110
1486
  return _extra;
1111
1487
  },
1112
1488
  set extra(val) {
1113
1489
  _extra = val;
1114
- _entryHeader.extraLength = val.length;
1490
+ _centralHeader.extraLength = val.length;
1115
1491
  parseExtra(val);
1116
1492
  },
1117
1493
  get comment() {
1118
- return _comment.toString();
1494
+ return decoder.decode(_comment);
1119
1495
  },
1120
1496
  set comment(val) {
1121
- _comment = Utils.toBuffer(val);
1122
- _entryHeader.commentLength = _comment.length;
1497
+ _comment = Utils.toBuffer(val, decoder.encode);
1498
+ _centralHeader.commentLength = _comment.length;
1499
+ if (_comment.length > 65535) throw Utils.Errors.COMMENT_TOO_LONG();
1123
1500
  },
1124
1501
  get name() {
1125
- var n = _entryName.toString();
1126
- return _isDirectory ? n.substr(n.length - 1).split("/").pop() : n.split("/").pop();
1502
+ const n = decoder.decode(_entryName);
1503
+ return _isDirectory ? n.replace(/[/\\]$/, "").split("/").pop() : n.split("/").pop();
1127
1504
  },
1128
1505
  get isDirectory() {
1129
1506
  return _isDirectory;
@@ -1135,112 +1512,157 @@ var require_zipEntry = __commonJS({
1135
1512
  compress(true, callback);
1136
1513
  },
1137
1514
  setData: function(value) {
1138
- uncompressedData = Utils.toBuffer(value);
1515
+ uncompressedData = Utils.toBuffer(value, Utils.decoder.encode);
1139
1516
  if (!_isDirectory && uncompressedData.length) {
1140
- _entryHeader.size = uncompressedData.length;
1141
- _entryHeader.method = Utils.Constants.DEFLATED;
1142
- _entryHeader.crc = Utils.crc32(value);
1143
- _entryHeader.changed = true;
1517
+ _centralHeader.size = uncompressedData.length;
1518
+ _centralHeader.method = Utils.Constants.DEFLATED;
1519
+ _centralHeader.crc = Utils.crc32(value);
1520
+ _centralHeader.changed = true;
1144
1521
  } else {
1145
- _entryHeader.method = Utils.Constants.STORED;
1522
+ _centralHeader.method = Utils.Constants.STORED;
1146
1523
  }
1147
1524
  },
1148
1525
  getData: function(pass) {
1149
- if (_entryHeader.changed) {
1526
+ if (_centralHeader.changed) {
1150
1527
  return uncompressedData;
1151
1528
  } else {
1152
1529
  return decompress(false, null, pass);
1153
1530
  }
1154
1531
  },
1155
1532
  getDataAsync: function(callback, pass) {
1156
- if (_entryHeader.changed) {
1533
+ if (_centralHeader.changed) {
1157
1534
  callback(uncompressedData);
1158
1535
  } else {
1159
1536
  decompress(true, callback, pass);
1160
1537
  }
1161
1538
  },
1162
1539
  set attr(attr) {
1163
- _entryHeader.attr = attr;
1540
+ _centralHeader.attr = attr;
1164
1541
  },
1165
1542
  get attr() {
1166
- return _entryHeader.attr;
1543
+ return _centralHeader.attr;
1167
1544
  },
1168
1545
  set header(data) {
1169
- _entryHeader.loadFromBinary(data);
1546
+ _centralHeader.loadFromBinary(data);
1170
1547
  },
1171
1548
  get header() {
1172
- return _entryHeader;
1549
+ return _centralHeader;
1173
1550
  },
1174
- packHeader: function() {
1175
- var header = _entryHeader.entryHeaderToBinary();
1176
- _entryName.copy(header, Utils.Constants.CENHDR);
1177
- if (_entryHeader.extraLength) {
1178
- _extra.copy(header, Utils.Constants.CENHDR + _entryName.length);
1179
- }
1180
- if (_entryHeader.commentLength) {
1181
- _comment.copy(header, Utils.Constants.CENHDR + _entryName.length + _entryHeader.extraLength, _comment.length);
1182
- }
1551
+ packCentralHeader: function() {
1552
+ _centralHeader.flags_efs = this.efs;
1553
+ _centralHeader.extraLength = _extra.length;
1554
+ var header = _centralHeader.centralHeaderToBinary();
1555
+ var addpos = Utils.Constants.CENHDR;
1556
+ _entryName.copy(header, addpos);
1557
+ addpos += _entryName.length;
1558
+ _extra.copy(header, addpos);
1559
+ addpos += _centralHeader.extraLength;
1560
+ _comment.copy(header, addpos);
1183
1561
  return header;
1184
1562
  },
1563
+ packLocalHeader: function() {
1564
+ let addpos = 0;
1565
+ _centralHeader.flags_efs = this.efs;
1566
+ _centralHeader.extraLocalLength = _extralocal.length;
1567
+ const localHeaderBuf = _centralHeader.localHeaderToBinary();
1568
+ const localHeader = Buffer.alloc(localHeaderBuf.length + _entryName.length + _centralHeader.extraLocalLength);
1569
+ localHeaderBuf.copy(localHeader, addpos);
1570
+ addpos += localHeaderBuf.length;
1571
+ _entryName.copy(localHeader, addpos);
1572
+ addpos += _entryName.length;
1573
+ _extralocal.copy(localHeader, addpos);
1574
+ addpos += _extralocal.length;
1575
+ return localHeader;
1576
+ },
1577
+ toJSON: function() {
1578
+ const bytes = function(nr) {
1579
+ return "<" + (nr && nr.length + " bytes buffer" || "null") + ">";
1580
+ };
1581
+ return {
1582
+ entryName: this.entryName,
1583
+ name: this.name,
1584
+ comment: this.comment,
1585
+ isDirectory: this.isDirectory,
1586
+ header: _centralHeader.toJSON(),
1587
+ compressedData: bytes(input),
1588
+ data: bytes(uncompressedData)
1589
+ };
1590
+ },
1185
1591
  toString: function() {
1186
- return '{\n "entryName" : "' + _entryName.toString() + '",\n "name" : "' + (_isDirectory ? _entryName.toString().replace(/\/$/, "").split("/").pop() : _entryName.toString().split("/").pop()) + '",\n "comment" : "' + _comment.toString() + '",\n "isDirectory" : ' + _isDirectory + ',\n "header" : ' + _entryHeader.toString().replace(/\t/mg, " ").replace(/}/mg, " }") + ',\n "compressedData" : <' + (input && input.length + " bytes buffer" || "null") + '>\n "data" : <' + (uncompressedData && uncompressedData.length + " bytes buffer" || "null") + ">\n}";
1592
+ return JSON.stringify(this.toJSON(), null, " ");
1187
1593
  }
1188
1594
  };
1189
1595
  };
1190
1596
  }
1191
1597
  });
1192
1598
 
1193
- // ../../node_modules/adm-zip/zipFile.js
1599
+ // node_modules/adm-zip/zipFile.js
1194
1600
  var require_zipFile = __commonJS({
1195
- "../../node_modules/adm-zip/zipFile.js"(exports, module) {
1601
+ "node_modules/adm-zip/zipFile.js"(exports, module) {
1196
1602
  var ZipEntry = require_zipEntry();
1197
1603
  var Headers = require_headers();
1198
1604
  var Utils = require_util();
1199
- module.exports = function(input, inputType) {
1200
- var entryList = [], entryTable = {}, _comment = Buffer.alloc(0), filename = "", fs10 = Utils.FileSystem.require(), inBuffer = null, mainHeader = new Headers.MainHeader(), loadedEntries = false;
1201
- if (inputType === Utils.Constants.FILE) {
1202
- filename = input;
1203
- inBuffer = fs10.readFileSync(filename);
1204
- readMainHeader();
1205
- } else if (inputType === Utils.Constants.BUFFER) {
1206
- inBuffer = input;
1207
- readMainHeader();
1605
+ module.exports = function(inBuffer, options) {
1606
+ var entryList = [], entryTable = /* @__PURE__ */ Object.create(null), _comment = Buffer.alloc(0), mainHeader = new Headers.MainHeader(), loadedEntries = false;
1607
+ var password = null;
1608
+ const temporary = /* @__PURE__ */ new Set();
1609
+ const opts = options;
1610
+ const { noSort, decoder } = opts;
1611
+ if (inBuffer) {
1612
+ readMainHeader(opts.readEntries);
1208
1613
  } else {
1209
1614
  loadedEntries = true;
1210
1615
  }
1211
- function iterateEntries(callback) {
1212
- const totalEntries = mainHeader.diskEntries;
1213
- let index = mainHeader.offset;
1214
- for (let i = 0; i < totalEntries; i++) {
1215
- let tmp = index;
1216
- const entry = new ZipEntry(inBuffer);
1217
- entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR);
1218
- entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength);
1219
- index += entry.header.entryHeaderSize;
1220
- callback(entry);
1616
+ function makeTemporaryFolders() {
1617
+ const foldersList = /* @__PURE__ */ new Set();
1618
+ for (const elem of Object.keys(entryTable)) {
1619
+ const elements = elem.split("/");
1620
+ elements.pop();
1621
+ if (!elements.length) continue;
1622
+ for (let i = 0; i < elements.length; i++) {
1623
+ const sub = elements.slice(0, i + 1).join("/") + "/";
1624
+ foldersList.add(sub);
1625
+ }
1626
+ }
1627
+ for (const elem of foldersList) {
1628
+ if (!(elem in entryTable)) {
1629
+ const tempfolder = new ZipEntry(opts);
1630
+ tempfolder.entryName = elem;
1631
+ tempfolder.attr = 16;
1632
+ tempfolder.temporary = true;
1633
+ entryList.push(tempfolder);
1634
+ entryTable[tempfolder.entryName] = tempfolder;
1635
+ temporary.add(tempfolder);
1636
+ }
1221
1637
  }
1222
1638
  }
1223
1639
  function readEntries() {
1224
1640
  loadedEntries = true;
1225
- entryTable = {};
1641
+ entryTable = /* @__PURE__ */ Object.create(null);
1642
+ if (mainHeader.diskEntries > (inBuffer.length - mainHeader.offset) / Utils.Constants.CENHDR) {
1643
+ throw Utils.Errors.DISK_ENTRY_TOO_LARGE();
1644
+ }
1226
1645
  entryList = new Array(mainHeader.diskEntries);
1227
1646
  var index = mainHeader.offset;
1228
1647
  for (var i = 0; i < entryList.length; i++) {
1229
- var tmp = index, entry = new ZipEntry(inBuffer);
1648
+ var tmp = index, entry = new ZipEntry(opts, inBuffer);
1230
1649
  entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR);
1231
1650
  entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength);
1232
1651
  if (entry.header.extraLength) {
1233
1652
  entry.extra = inBuffer.slice(tmp, tmp += entry.header.extraLength);
1234
1653
  }
1235
- if (entry.header.commentLength)
1236
- entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength);
1237
- index += entry.header.entryHeaderSize;
1654
+ if (entry.header.commentLength) entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength);
1655
+ index += entry.header.centralHeaderSize;
1238
1656
  entryList[i] = entry;
1239
1657
  entryTable[entry.entryName] = entry;
1240
1658
  }
1659
+ temporary.clear();
1660
+ makeTemporaryFolders();
1241
1661
  }
1242
- function readMainHeader() {
1662
+ function readMainHeader(readNow) {
1243
1663
  var i = inBuffer.length - Utils.Constants.ENDHDR, max = Math.max(0, i - 65535), n = max, endStart = inBuffer.length, endOffset = -1, commentEnd = 0;
1664
+ const trailingSpace = typeof opts.trailingSpace === "boolean" ? opts.trailingSpace : false;
1665
+ if (trailingSpace) max = 0;
1244
1666
  for (i; i >= n; i--) {
1245
1667
  if (inBuffer[i] !== 80) continue;
1246
1668
  if (inBuffer.readUInt32LE(i) === Utils.Constants.ENDSIG) {
@@ -1254,18 +1676,23 @@ var require_zipFile = __commonJS({
1254
1676
  n = max;
1255
1677
  continue;
1256
1678
  }
1257
- if (inBuffer.readUInt32LE(i) == Utils.Constants.ZIP64SIG) {
1679
+ if (inBuffer.readUInt32LE(i) === Utils.Constants.ZIP64SIG) {
1258
1680
  endOffset = i;
1259
1681
  endStart = i + Utils.readBigUInt64LE(inBuffer, i + Utils.Constants.ZIP64SIZE) + Utils.Constants.ZIP64LEAD;
1260
1682
  break;
1261
1683
  }
1262
1684
  }
1263
- if (!~endOffset)
1264
- throw new Error(Utils.Errors.INVALID_FORMAT);
1685
+ if (endOffset == -1) throw Utils.Errors.INVALID_FORMAT();
1265
1686
  mainHeader.loadFromBinary(inBuffer.slice(endOffset, endStart));
1266
1687
  if (mainHeader.commentLength) {
1267
1688
  _comment = inBuffer.slice(commentEnd + Utils.Constants.ENDHDR);
1268
1689
  }
1690
+ if (readNow) readEntries();
1691
+ }
1692
+ function sortEntries() {
1693
+ if (entryList.length > 1 && !noSort) {
1694
+ entryList = entryList.map((entry) => ({ entry, key: entry.entryName.toLowerCase() })).sort((a, b) => a.key.localeCompare(b.key)).map((pair) => pair.entry);
1695
+ }
1269
1696
  }
1270
1697
  return {
1271
1698
  /**
@@ -1276,18 +1703,18 @@ var require_zipFile = __commonJS({
1276
1703
  if (!loadedEntries) {
1277
1704
  readEntries();
1278
1705
  }
1279
- return entryList;
1706
+ return entryList.filter((e) => !temporary.has(e));
1280
1707
  },
1281
1708
  /**
1282
1709
  * Archive comment
1283
1710
  * @return {String}
1284
1711
  */
1285
1712
  get comment() {
1286
- return _comment.toString();
1713
+ return decoder.decode(_comment);
1287
1714
  },
1288
1715
  set comment(val) {
1289
- mainHeader.commentLength = val.length;
1290
- _comment = val;
1716
+ _comment = Utils.toBuffer(val, decoder.encode);
1717
+ mainHeader.commentLength = _comment.length;
1291
1718
  },
1292
1719
  getEntryCount: function() {
1293
1720
  if (!loadedEntries) {
@@ -1296,11 +1723,7 @@ var require_zipFile = __commonJS({
1296
1723
  return entryList.length;
1297
1724
  },
1298
1725
  forEach: function(callback) {
1299
- if (!loadedEntries) {
1300
- iterateEntries(callback);
1301
- return;
1302
- }
1303
- entryList.forEach(callback);
1726
+ this.entries.forEach(callback);
1304
1727
  },
1305
1728
  /**
1306
1729
  * Returns a reference to the entry with the given name or null if entry is inexistent
@@ -1328,27 +1751,37 @@ var require_zipFile = __commonJS({
1328
1751
  mainHeader.totalEntries = entryList.length;
1329
1752
  },
1330
1753
  /**
1331
- * Removes the entry with the given name from the entry list.
1754
+ * Removes the file with the given name from the entry list.
1332
1755
  *
1333
1756
  * If the entry is a directory, then all nested files and directories will be removed
1334
1757
  * @param entryName
1758
+ * @returns {void}
1759
+ */
1760
+ deleteFile: function(entryName, withsubfolders = true) {
1761
+ if (!loadedEntries) {
1762
+ readEntries();
1763
+ }
1764
+ const entry = entryTable[entryName];
1765
+ const list = this.getEntryChildren(entry, withsubfolders).map((child) => child.entryName);
1766
+ list.forEach(this.deleteEntry);
1767
+ },
1768
+ /**
1769
+ * Removes the entry with the given name from the entry list.
1770
+ *
1771
+ * @param {string} entryName
1772
+ * @returns {void}
1335
1773
  */
1336
1774
  deleteEntry: function(entryName) {
1337
1775
  if (!loadedEntries) {
1338
1776
  readEntries();
1339
1777
  }
1340
- var entry = entryTable[entryName];
1341
- if (entry && entry.isDirectory) {
1342
- var _self = this;
1343
- this.getEntryChildren(entry).forEach(function(child) {
1344
- if (child.entryName !== entryName) {
1345
- _self.deleteEntry(child.entryName);
1346
- }
1347
- });
1778
+ const entry = entryTable[entryName];
1779
+ const index = entryList.indexOf(entry);
1780
+ if (index >= 0) {
1781
+ entryList.splice(index, 1);
1782
+ delete entryTable[entryName];
1783
+ mainHeader.totalEntries = entryList.length;
1348
1784
  }
1349
- entryList.splice(entryList.indexOf(entry), 1);
1350
- delete entryTable[entryName];
1351
- mainHeader.totalEntries = entryList.length;
1352
1785
  },
1353
1786
  /**
1354
1787
  * Iterates and returns all nested files and directories of the given entry
@@ -1356,21 +1789,39 @@ var require_zipFile = __commonJS({
1356
1789
  * @param entry
1357
1790
  * @return Array
1358
1791
  */
1359
- getEntryChildren: function(entry) {
1792
+ getEntryChildren: function(entry, subfolders = true) {
1360
1793
  if (!loadedEntries) {
1361
1794
  readEntries();
1362
1795
  }
1363
- if (entry.isDirectory) {
1364
- var list = [], name = entry.entryName, len = name.length;
1365
- entryList.forEach(function(zipEntry) {
1366
- if (zipEntry.entryName.substr(0, len) === name) {
1367
- list.push(zipEntry);
1796
+ if (typeof entry === "object") {
1797
+ if (entry.isDirectory && subfolders) {
1798
+ const list = [];
1799
+ const name = entry.entryName;
1800
+ for (const zipEntry of entryList) {
1801
+ if (zipEntry.entryName.startsWith(name)) {
1802
+ list.push(zipEntry);
1803
+ }
1368
1804
  }
1369
- });
1370
- return list;
1805
+ return list;
1806
+ } else {
1807
+ return [entry];
1808
+ }
1371
1809
  }
1372
1810
  return [];
1373
1811
  },
1812
+ /**
1813
+ * How many child elements entry has
1814
+ *
1815
+ * @param {ZipEntry} entry
1816
+ * @return {integer}
1817
+ */
1818
+ getChildCount: function(entry) {
1819
+ if (entry && entry.isDirectory) {
1820
+ const list = this.getEntryChildren(entry);
1821
+ return list.includes(entry) ? list.length - 1 : list.length;
1822
+ }
1823
+ return 0;
1824
+ },
1374
1825
  /**
1375
1826
  * Returns the zip file
1376
1827
  *
@@ -1380,200 +1831,229 @@ var require_zipFile = __commonJS({
1380
1831
  if (!loadedEntries) {
1381
1832
  readEntries();
1382
1833
  }
1383
- if (entryList.length > 1) {
1384
- entryList.sort(function(a, b) {
1385
- var nameA = a.entryName.toLowerCase();
1386
- var nameB = b.entryName.toLowerCase();
1387
- if (nameA < nameB) {
1388
- return -1;
1389
- }
1390
- if (nameA > nameB) {
1391
- return 1;
1392
- }
1393
- return 0;
1394
- });
1395
- }
1396
- var totalSize = 0, dataBlock = [], entryHeaders = [], dindex = 0;
1834
+ sortEntries();
1835
+ const dataBlock = [];
1836
+ const headerBlocks = [];
1837
+ let totalSize = 0;
1838
+ let dindex = 0;
1397
1839
  mainHeader.size = 0;
1398
1840
  mainHeader.offset = 0;
1399
- entryList.forEach(function(entry) {
1400
- var compressedData = entry.getCompressedData();
1841
+ let totalEntries = 0;
1842
+ for (const entry of this.entries) {
1843
+ const compressedData = entry.getCompressedData();
1401
1844
  entry.header.offset = dindex;
1402
- var dataHeader = entry.header.dataHeaderToBinary();
1403
- var entryNameLen = entry.rawEntryName.length;
1404
- var extra = entry.extra.toString();
1405
- var postHeader = Buffer.alloc(entryNameLen + extra.length);
1406
- entry.rawEntryName.copy(postHeader, 0);
1407
- postHeader.fill(extra, entryNameLen);
1408
- var dataLength = dataHeader.length + postHeader.length + compressedData.length;
1845
+ const localHeader = entry.packLocalHeader();
1846
+ const dataLength = localHeader.length + compressedData.length;
1409
1847
  dindex += dataLength;
1410
- dataBlock.push(dataHeader);
1411
- dataBlock.push(postHeader);
1848
+ dataBlock.push(localHeader);
1412
1849
  dataBlock.push(compressedData);
1413
- var entryHeader = entry.packHeader();
1414
- entryHeaders.push(entryHeader);
1415
- mainHeader.size += entryHeader.length;
1416
- totalSize += dataLength + entryHeader.length;
1417
- });
1850
+ const centralHeader = entry.packCentralHeader();
1851
+ headerBlocks.push(centralHeader);
1852
+ mainHeader.size += centralHeader.length;
1853
+ totalSize += dataLength + centralHeader.length;
1854
+ totalEntries++;
1855
+ }
1418
1856
  totalSize += mainHeader.mainHeaderSize;
1419
1857
  mainHeader.offset = dindex;
1858
+ mainHeader.totalEntries = totalEntries;
1420
1859
  dindex = 0;
1421
- var outBuffer = Buffer.alloc(totalSize);
1422
- dataBlock.forEach(function(content) {
1860
+ const outBuffer = Buffer.alloc(totalSize);
1861
+ for (const content of dataBlock) {
1423
1862
  content.copy(outBuffer, dindex);
1424
1863
  dindex += content.length;
1425
- });
1426
- entryHeaders.forEach(function(content) {
1864
+ }
1865
+ for (const content of headerBlocks) {
1427
1866
  content.copy(outBuffer, dindex);
1428
1867
  dindex += content.length;
1429
- });
1430
- var mh = mainHeader.toBinary();
1868
+ }
1869
+ const mh = mainHeader.toBinary();
1431
1870
  if (_comment) {
1432
- Buffer.from(_comment).copy(mh, Utils.Constants.ENDHDR);
1871
+ _comment.copy(mh, mh.length - _comment.length);
1433
1872
  }
1434
1873
  mh.copy(outBuffer, dindex);
1874
+ inBuffer = outBuffer;
1875
+ loadedEntries = false;
1435
1876
  return outBuffer;
1436
1877
  },
1437
1878
  toAsyncBuffer: function(onSuccess, onFail, onItemStart, onItemEnd) {
1438
- if (!loadedEntries) {
1439
- readEntries();
1440
- }
1441
- if (entryList.length > 1) {
1442
- entryList.sort(function(a, b) {
1443
- var nameA = a.entryName.toLowerCase();
1444
- var nameB = b.entryName.toLowerCase();
1445
- if (nameA > nameB) {
1446
- return -1;
1447
- }
1448
- if (nameA < nameB) {
1449
- return 1;
1879
+ try {
1880
+ if (!loadedEntries) {
1881
+ readEntries();
1882
+ }
1883
+ sortEntries();
1884
+ const dataBlock = [];
1885
+ const centralHeaders = [];
1886
+ let totalSize = 0;
1887
+ let dindex = 0;
1888
+ let totalEntries = 0;
1889
+ mainHeader.size = 0;
1890
+ mainHeader.offset = 0;
1891
+ const compress2Buffer = function(entryLists) {
1892
+ if (entryLists.length > 0) {
1893
+ const entry = entryLists.shift();
1894
+ const name = entry.entryName + entry.extra.toString();
1895
+ if (onItemStart) onItemStart(name);
1896
+ entry.getCompressedDataAsync(function(compressedData) {
1897
+ if (onItemEnd) onItemEnd(name);
1898
+ entry.header.offset = dindex;
1899
+ const localHeader = entry.packLocalHeader();
1900
+ const dataLength = localHeader.length + compressedData.length;
1901
+ dindex += dataLength;
1902
+ dataBlock.push(localHeader);
1903
+ dataBlock.push(compressedData);
1904
+ const centalHeader = entry.packCentralHeader();
1905
+ centralHeaders.push(centalHeader);
1906
+ mainHeader.size += centalHeader.length;
1907
+ totalSize += dataLength + centalHeader.length;
1908
+ totalEntries++;
1909
+ compress2Buffer(entryLists);
1910
+ });
1911
+ } else {
1912
+ totalSize += mainHeader.mainHeaderSize;
1913
+ mainHeader.offset = dindex;
1914
+ mainHeader.totalEntries = totalEntries;
1915
+ dindex = 0;
1916
+ const outBuffer = Buffer.alloc(totalSize);
1917
+ dataBlock.forEach(function(content) {
1918
+ content.copy(outBuffer, dindex);
1919
+ dindex += content.length;
1920
+ });
1921
+ centralHeaders.forEach(function(content) {
1922
+ content.copy(outBuffer, dindex);
1923
+ dindex += content.length;
1924
+ });
1925
+ const mh = mainHeader.toBinary();
1926
+ if (_comment) {
1927
+ _comment.copy(mh, mh.length - _comment.length);
1928
+ }
1929
+ mh.copy(outBuffer, dindex);
1930
+ inBuffer = outBuffer;
1931
+ loadedEntries = false;
1932
+ onSuccess(outBuffer);
1450
1933
  }
1451
- return 0;
1452
- });
1934
+ };
1935
+ compress2Buffer(Array.from(this.entries));
1936
+ } catch (e) {
1937
+ onFail(e);
1453
1938
  }
1454
- var totalSize = 0, dataBlock = [], entryHeaders = [], dindex = 0;
1455
- mainHeader.size = 0;
1456
- mainHeader.offset = 0;
1457
- var compress = function(entryList2) {
1458
- var self = arguments.callee;
1459
- if (entryList2.length) {
1460
- var entry = entryList2.pop();
1461
- var name = entry.entryName + entry.extra.toString();
1462
- if (onItemStart) onItemStart(name);
1463
- entry.getCompressedDataAsync(function(compressedData) {
1464
- if (onItemEnd) onItemEnd(name);
1465
- entry.header.offset = dindex;
1466
- var dataHeader = entry.header.dataHeaderToBinary();
1467
- var postHeader;
1468
- try {
1469
- postHeader = Buffer.alloc(name.length, name);
1470
- } catch (e) {
1471
- postHeader = new Buffer(name);
1472
- }
1473
- var dataLength = dataHeader.length + postHeader.length + compressedData.length;
1474
- dindex += dataLength;
1475
- dataBlock.push(dataHeader);
1476
- dataBlock.push(postHeader);
1477
- dataBlock.push(compressedData);
1478
- var entryHeader = entry.packHeader();
1479
- entryHeaders.push(entryHeader);
1480
- mainHeader.size += entryHeader.length;
1481
- totalSize += dataLength + entryHeader.length;
1482
- if (entryList2.length) {
1483
- self(entryList2);
1484
- } else {
1485
- totalSize += mainHeader.mainHeaderSize;
1486
- mainHeader.offset = dindex;
1487
- dindex = 0;
1488
- var outBuffer = Buffer.alloc(totalSize);
1489
- dataBlock.forEach(function(content) {
1490
- content.copy(outBuffer, dindex);
1491
- dindex += content.length;
1492
- });
1493
- entryHeaders.forEach(function(content) {
1494
- content.copy(outBuffer, dindex);
1495
- dindex += content.length;
1496
- });
1497
- var mh = mainHeader.toBinary();
1498
- if (_comment) {
1499
- _comment.copy(mh, Utils.Constants.ENDHDR);
1500
- }
1501
- mh.copy(outBuffer, dindex);
1502
- onSuccess(outBuffer);
1503
- }
1504
- });
1505
- }
1506
- };
1507
- compress(entryList);
1508
1939
  }
1509
1940
  };
1510
1941
  };
1511
1942
  }
1512
1943
  });
1513
1944
 
1514
- // ../../node_modules/adm-zip/adm-zip.js
1945
+ // node_modules/adm-zip/adm-zip.js
1515
1946
  var require_adm_zip = __commonJS({
1516
- "../../node_modules/adm-zip/adm-zip.js"(exports, module) {
1947
+ "node_modules/adm-zip/adm-zip.js"(exports, module) {
1517
1948
  var Utils = require_util();
1518
- var fs10 = Utils.FileSystem.require();
1519
1949
  var pth = __require("path");
1520
- fs10.existsSync = fs10.existsSync || pth.existsSync;
1521
1950
  var ZipEntry = require_zipEntry();
1522
1951
  var ZipFile = require_zipFile();
1523
- var isWin = /^win/.test(process.platform);
1524
- module.exports = function(input) {
1525
- var _zip = void 0, _filename = "";
1526
- if (input && typeof input === "string") {
1527
- if (fs10.existsSync(input)) {
1528
- _filename = input;
1529
- _zip = new ZipFile(input, Utils.Constants.FILE);
1530
- } else {
1531
- throw new Error(Utils.Errors.INVALID_FILENAME);
1952
+ var get_Bool = (...val) => Utils.findLast(val, (c) => typeof c === "boolean");
1953
+ var get_Str = (...val) => Utils.findLast(val, (c) => typeof c === "string");
1954
+ var get_Fun = (...val) => Utils.findLast(val, (c) => typeof c === "function");
1955
+ var defaultOptions = {
1956
+ // option "noSort" : if true it disables files sorting
1957
+ noSort: false,
1958
+ // read entries during load (initial loading may be slower)
1959
+ readEntries: false,
1960
+ // default method is none
1961
+ method: Utils.Constants.NONE,
1962
+ // file system
1963
+ fs: null
1964
+ };
1965
+ module.exports = function(input, options) {
1966
+ let inBuffer = null;
1967
+ const opts = Object.assign(/* @__PURE__ */ Object.create(null), defaultOptions);
1968
+ if (input && "object" === typeof input) {
1969
+ if (!(input instanceof Uint8Array)) {
1970
+ Object.assign(opts, input);
1971
+ input = opts.input ? opts.input : void 0;
1972
+ if (opts.input) delete opts.input;
1532
1973
  }
1533
- } else if (input && Buffer.isBuffer(input)) {
1534
- _zip = new ZipFile(input, Utils.Constants.BUFFER);
1535
- } else {
1536
- _zip = new ZipFile(null, Utils.Constants.NONE);
1537
- }
1538
- function sanitize(prefix, name) {
1539
- prefix = pth.resolve(pth.normalize(prefix));
1540
- var parts = name.split("/");
1541
- for (var i = 0, l = parts.length; i < l; i++) {
1542
- var path12 = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
1543
- if (path12.indexOf(prefix) === 0) {
1544
- return path12;
1545
- }
1974
+ if (Buffer.isBuffer(input)) {
1975
+ inBuffer = input;
1976
+ opts.method = Utils.Constants.BUFFER;
1977
+ input = void 0;
1546
1978
  }
1547
- return pth.normalize(pth.join(prefix, pth.basename(name)));
1548
1979
  }
1980
+ Object.assign(opts, options);
1981
+ const filetools = new Utils(opts);
1982
+ const applyDirAttributes = (dirEntries) => {
1983
+ dirEntries.filter((d) => d.attr).sort((a, b) => b.path.length - a.path.length).forEach((d) => filetools.fs.chmodSync(d.path, d.attr));
1984
+ };
1985
+ if (typeof opts.decoder !== "object" || typeof opts.decoder.encode !== "function" || typeof opts.decoder.decode !== "function") {
1986
+ opts.decoder = Utils.decoder;
1987
+ }
1988
+ if (input && "string" === typeof input) {
1989
+ if (filetools.fs.existsSync(input)) {
1990
+ opts.method = Utils.Constants.FILE;
1991
+ opts.filename = input;
1992
+ inBuffer = filetools.fs.readFileSync(input);
1993
+ } else {
1994
+ throw Utils.Errors.INVALID_FILENAME();
1995
+ }
1996
+ }
1997
+ const _zip = new ZipFile(inBuffer, opts);
1998
+ const { canonical, sanitize, zipnamefix } = Utils;
1549
1999
  function getEntry(entry) {
1550
2000
  if (entry && _zip) {
1551
2001
  var item;
1552
- if (typeof entry === "string")
1553
- item = _zip.getEntry(entry);
1554
- if (typeof entry === "object" && typeof entry.entryName !== "undefined" && typeof entry.header !== "undefined")
1555
- item = _zip.getEntry(entry.entryName);
2002
+ if (typeof entry === "string") item = _zip.getEntry(pth.posix.normalize(entry));
2003
+ if (typeof entry === "object" && typeof entry.entryName !== "undefined" && typeof entry.header !== "undefined") item = _zip.getEntry(entry.entryName);
1556
2004
  if (item) {
1557
2005
  return item;
1558
2006
  }
1559
2007
  }
1560
2008
  return null;
1561
2009
  }
2010
+ function fixPath(zipPath) {
2011
+ const { join, normalize, sep } = pth.posix;
2012
+ return join(pth.isAbsolute(zipPath) ? "/" : ".", normalize(sep + zipPath.split("\\").join(sep) + sep));
2013
+ }
2014
+ function filenameFilter(filterfn) {
2015
+ if (filterfn instanceof RegExp) {
2016
+ return /* @__PURE__ */ (function(rx) {
2017
+ return function(filename) {
2018
+ return rx.test(filename);
2019
+ };
2020
+ })(filterfn);
2021
+ } else if ("function" !== typeof filterfn) {
2022
+ return () => true;
2023
+ }
2024
+ return filterfn;
2025
+ }
2026
+ const relativePath = (local, entry) => {
2027
+ let lastChar = entry.slice(-1);
2028
+ lastChar = lastChar === filetools.sep ? filetools.sep : "";
2029
+ return pth.relative(local, entry) + lastChar;
2030
+ };
1562
2031
  return {
1563
2032
  /**
1564
2033
  * Extracts the given entry from the archive and returns the content as a Buffer object
1565
- * @param entry ZipEntry object or String with the full path of the entry
1566
- *
2034
+ * @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
2035
+ * @param {Buffer|string} [pass] - password
1567
2036
  * @return Buffer or Null in case of error
1568
2037
  */
1569
- readFile: function(entry) {
2038
+ readFile: function(entry, pass) {
1570
2039
  var item = getEntry(entry);
1571
- return item && item.getData() || null;
2040
+ return item && item.getData(pass) || null;
2041
+ },
2042
+ /**
2043
+ * Returns how many child elements has on entry (directories) on files it is always 0
2044
+ * @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
2045
+ * @returns {integer}
2046
+ */
2047
+ childCount: function(entry) {
2048
+ const item = getEntry(entry);
2049
+ if (item) {
2050
+ return _zip.getChildCount(item);
2051
+ }
1572
2052
  },
1573
2053
  /**
1574
2054
  * Asynchronous readFile
1575
- * @param entry ZipEntry object or String with the full path of the entry
1576
- * @param callback
2055
+ * @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
2056
+ * @param {callback} callback
1577
2057
  *
1578
2058
  * @return Buffer or Null in case of error
1579
2059
  */
@@ -1587,8 +2067,8 @@ var require_adm_zip = __commonJS({
1587
2067
  },
1588
2068
  /**
1589
2069
  * Extracts the given entry from the archive and returns the content as plain text in the given encoding
1590
- * @param entry ZipEntry object or String with the full path of the entry
1591
- * @param encoding Optional. If no encoding is specified utf8 is used
2070
+ * @param {ZipEntry|string} entry - ZipEntry object or String with the full path of the entry
2071
+ * @param {string} encoding - Optional. If no encoding is specified utf8 is used
1592
2072
  *
1593
2073
  * @return String
1594
2074
  */
@@ -1604,9 +2084,9 @@ var require_adm_zip = __commonJS({
1604
2084
  },
1605
2085
  /**
1606
2086
  * Asynchronous readAsText
1607
- * @param entry ZipEntry object or String with the full path of the entry
1608
- * @param callback
1609
- * @param encoding Optional. If no encoding is specified utf8 is used
2087
+ * @param {ZipEntry|string} entry ZipEntry object or String with the full path of the entry
2088
+ * @param {callback} callback
2089
+ * @param {string} [encoding] - Optional. If no encoding is specified utf8 is used
1610
2090
  *
1611
2091
  * @return String
1612
2092
  */
@@ -1631,9 +2111,23 @@ var require_adm_zip = __commonJS({
1631
2111
  /**
1632
2112
  * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
1633
2113
  *
1634
- * @param entry
2114
+ * @param {ZipEntry|string} entry
2115
+ * @param {boolean} withsubfolders
2116
+ * @returns {void}
1635
2117
  */
1636
- deleteFile: function(entry) {
2118
+ deleteFile: function(entry, withsubfolders = true) {
2119
+ var item = getEntry(entry);
2120
+ if (item) {
2121
+ _zip.deleteFile(item.entryName, withsubfolders);
2122
+ }
2123
+ },
2124
+ /**
2125
+ * Remove the entry from the file or directory without affecting any nested entries
2126
+ *
2127
+ * @param {ZipEntry|string} entry
2128
+ * @returns {void}
2129
+ */
2130
+ deleteEntry: function(entry) {
1637
2131
  var item = getEntry(entry);
1638
2132
  if (item) {
1639
2133
  _zip.deleteEntry(item.entryName);
@@ -1642,7 +2136,7 @@ var require_adm_zip = __commonJS({
1642
2136
  /**
1643
2137
  * Adds a comment to the zip. The zip must be rewritten after adding the comment.
1644
2138
  *
1645
- * @param comment
2139
+ * @param {string} comment
1646
2140
  */
1647
2141
  addZipComment: function(comment) {
1648
2142
  _zip.comment = comment;
@@ -1659,8 +2153,8 @@ var require_adm_zip = __commonJS({
1659
2153
  * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
1660
2154
  * The comment cannot exceed 65535 characters in length
1661
2155
  *
1662
- * @param entry
1663
- * @param comment
2156
+ * @param {ZipEntry} entry
2157
+ * @param {string} comment
1664
2158
  */
1665
2159
  addZipEntryComment: function(entry, comment) {
1666
2160
  var item = getEntry(entry);
@@ -1671,7 +2165,7 @@ var require_adm_zip = __commonJS({
1671
2165
  /**
1672
2166
  * Returns the comment of the specified entry
1673
2167
  *
1674
- * @param entry
2168
+ * @param {ZipEntry} entry
1675
2169
  * @return String
1676
2170
  */
1677
2171
  getZipEntryComment: function(entry) {
@@ -1684,8 +2178,8 @@ var require_adm_zip = __commonJS({
1684
2178
  /**
1685
2179
  * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
1686
2180
  *
1687
- * @param entry
1688
- * @param content
2181
+ * @param {ZipEntry} entry
2182
+ * @param {Buffer} content
1689
2183
  */
1690
2184
  updateFile: function(entry, content) {
1691
2185
  var item = getEntry(entry);
@@ -1696,142 +2190,139 @@ var require_adm_zip = __commonJS({
1696
2190
  /**
1697
2191
  * Adds a file from the disk to the archive
1698
2192
  *
1699
- * @param localPath File to add to zip
1700
- * @param zipPath Optional path inside the zip
1701
- * @param zipName Optional name for the file
2193
+ * @param {string} localPath File to add to zip
2194
+ * @param {string} [zipPath] Optional path inside the zip
2195
+ * @param {string} [zipName] Optional name for the file
2196
+ * @param {string} [comment] Optional file comment
1702
2197
  */
1703
- addLocalFile: function(localPath, zipPath, zipName) {
1704
- if (fs10.existsSync(localPath)) {
1705
- if (zipPath) {
1706
- zipPath = zipPath.split("\\").join("/");
1707
- if (zipPath.charAt(zipPath.length - 1) !== "/") {
1708
- zipPath += "/";
1709
- }
1710
- } else {
1711
- zipPath = "";
1712
- }
1713
- var p = localPath.split("\\").join("/").split("/").pop();
1714
- if (zipName) {
1715
- this.addFile(zipPath + zipName, fs10.readFileSync(localPath), "", 0);
1716
- } else {
1717
- this.addFile(zipPath + p, fs10.readFileSync(localPath), "", 0);
1718
- }
2198
+ addLocalFile: function(localPath, zipPath, zipName, comment) {
2199
+ if (filetools.fs.existsSync(localPath)) {
2200
+ zipPath = zipPath ? fixPath(zipPath) : "";
2201
+ const p = pth.win32.basename(pth.win32.normalize(localPath));
2202
+ zipPath += zipName ? zipName : p;
2203
+ const _attr = filetools.fs.statSync(localPath);
2204
+ const data = _attr.isFile() ? filetools.fs.readFileSync(localPath) : Buffer.alloc(0);
2205
+ if (_attr.isDirectory()) zipPath += filetools.sep;
2206
+ this.addFile(zipPath, data, comment, _attr);
1719
2207
  } else {
1720
- throw new Error(Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
2208
+ throw Utils.Errors.FILE_NOT_FOUND(localPath);
1721
2209
  }
1722
2210
  },
2211
+ /**
2212
+ * Callback for showing if everything was done.
2213
+ *
2214
+ * @callback doneCallback
2215
+ * @param {Error} err - Error object
2216
+ * @param {boolean} done - was request fully completed
2217
+ */
2218
+ /**
2219
+ * Adds a file from the disk to the archive
2220
+ *
2221
+ * @param {(object|string)} options - options object, if it is string it us used as localPath.
2222
+ * @param {string} options.localPath - Local path to the file.
2223
+ * @param {string} [options.comment] - Optional file comment.
2224
+ * @param {string} [options.zipPath] - Optional path inside the zip
2225
+ * @param {string} [options.zipName] - Optional name for the file
2226
+ * @param {doneCallback} callback - The callback that handles the response.
2227
+ */
2228
+ addLocalFileAsync: function(options2, callback) {
2229
+ options2 = typeof options2 === "object" ? options2 : { localPath: options2 };
2230
+ const localPath = pth.resolve(options2.localPath);
2231
+ const { comment } = options2;
2232
+ let { zipPath, zipName } = options2;
2233
+ const self = this;
2234
+ filetools.fs.stat(localPath, function(err, stats) {
2235
+ if (err) return callback(err, false);
2236
+ zipPath = zipPath ? fixPath(zipPath) : "";
2237
+ const p = pth.win32.basename(pth.win32.normalize(localPath));
2238
+ zipPath += zipName ? zipName : p;
2239
+ if (stats.isFile()) {
2240
+ filetools.fs.readFile(localPath, function(err2, data) {
2241
+ if (err2) return callback(err2, false);
2242
+ self.addFile(zipPath, data, comment, stats);
2243
+ return setImmediate(callback, void 0, true);
2244
+ });
2245
+ } else if (stats.isDirectory()) {
2246
+ zipPath += filetools.sep;
2247
+ self.addFile(zipPath, Buffer.alloc(0), comment, stats);
2248
+ return setImmediate(callback, void 0, true);
2249
+ }
2250
+ });
2251
+ },
1723
2252
  /**
1724
2253
  * Adds a local directory and all its nested files and directories to the archive
1725
2254
  *
1726
- * @param localPath
1727
- * @param zipPath optional path inside zip
1728
- * @param filter optional RegExp or Function if files match will
1729
- * be included.
2255
+ * @param {string} localPath - local path to the folder
2256
+ * @param {string} [zipPath] - optional path inside zip
2257
+ * @param {(RegExp|function)} [filter] - optional RegExp or Function if files match will be included.
1730
2258
  */
1731
2259
  addLocalFolder: function(localPath, zipPath, filter) {
1732
- if (filter === void 0) {
1733
- filter = function() {
1734
- return true;
1735
- };
1736
- } else if (filter instanceof RegExp) {
1737
- filter = /* @__PURE__ */ (function(filter2) {
1738
- return function(filename) {
1739
- return filter2.test(filename);
1740
- };
1741
- })(filter);
1742
- }
1743
- if (zipPath) {
1744
- zipPath = zipPath.split("\\").join("/");
1745
- if (zipPath.charAt(zipPath.length - 1) !== "/") {
1746
- zipPath += "/";
1747
- }
1748
- } else {
1749
- zipPath = "";
1750
- }
2260
+ filter = filenameFilter(filter);
2261
+ zipPath = zipPath ? fixPath(zipPath) : "";
1751
2262
  localPath = pth.normalize(localPath);
1752
- localPath = localPath.split("\\").join("/");
1753
- if (localPath.charAt(localPath.length - 1) !== "/")
1754
- localPath += "/";
1755
- if (fs10.existsSync(localPath)) {
1756
- var items = Utils.findFiles(localPath), self = this;
2263
+ if (filetools.fs.existsSync(localPath)) {
2264
+ const items = filetools.findFiles(localPath);
2265
+ const self = this;
1757
2266
  if (items.length) {
1758
- items.forEach(function(path12) {
1759
- var p = path12.split("\\").join("/").replace(new RegExp(localPath.replace(/(\(|\)|\$)/g, "\\$1"), "i"), "");
2267
+ for (const filepath of items) {
2268
+ const p = pth.join(zipPath, relativePath(localPath, filepath));
1760
2269
  if (filter(p)) {
1761
- if (p.charAt(p.length - 1) !== "/") {
1762
- self.addFile(zipPath + p, fs10.readFileSync(path12), "", 0);
1763
- } else {
1764
- self.addFile(zipPath + p, Buffer.alloc(0), "", 0);
1765
- }
2270
+ self.addLocalFile(filepath, pth.dirname(p));
1766
2271
  }
1767
- });
2272
+ }
1768
2273
  }
1769
2274
  } else {
1770
- throw new Error(Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
2275
+ throw Utils.Errors.FILE_NOT_FOUND(localPath);
1771
2276
  }
1772
2277
  },
1773
2278
  /**
1774
- * Asynchronous addLocalFile
1775
- * @param localPath
1776
- * @param callback
1777
- * @param zipPath optional path inside zip
1778
- * @param filter optional RegExp or Function if files match will
2279
+ * Asynchronous addLocalFolder
2280
+ * @param {string} localPath
2281
+ * @param {callback} callback
2282
+ * @param {string} [zipPath] optional path inside zip
2283
+ * @param {RegExp|function} [filter] optional RegExp or Function if files match will
1779
2284
  * be included.
1780
2285
  */
1781
2286
  addLocalFolderAsync: function(localPath, callback, zipPath, filter) {
1782
- if (filter === void 0) {
1783
- filter = function() {
1784
- return true;
1785
- };
1786
- } else if (filter instanceof RegExp) {
1787
- filter = /* @__PURE__ */ (function(filter2) {
1788
- return function(filename) {
1789
- return filter2.test(filename);
1790
- };
1791
- })(filter);
1792
- }
1793
- if (zipPath) {
1794
- zipPath = zipPath.split("\\").join("/");
1795
- if (zipPath.charAt(zipPath.length - 1) !== "/") {
1796
- zipPath += "/";
1797
- }
1798
- } else {
1799
- zipPath = "";
1800
- }
2287
+ filter = filenameFilter(filter);
2288
+ zipPath = zipPath ? fixPath(zipPath) : "";
1801
2289
  localPath = pth.normalize(localPath);
1802
- localPath = localPath.split("\\").join("/");
1803
- if (localPath.charAt(localPath.length - 1) !== "/")
1804
- localPath += "/";
1805
2290
  var self = this;
1806
- fs10.open(localPath, "r", function(err, fd) {
2291
+ filetools.fs.open(localPath, "r", function(err) {
1807
2292
  if (err && err.code === "ENOENT") {
1808
- callback(void 0, Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
2293
+ callback(void 0, Utils.Errors.FILE_NOT_FOUND(localPath));
1809
2294
  } else if (err) {
1810
2295
  callback(void 0, err);
1811
2296
  } else {
1812
- var items = Utils.findFiles(localPath);
2297
+ var items = filetools.findFiles(localPath);
1813
2298
  var i = -1;
1814
2299
  var next = function() {
1815
2300
  i += 1;
1816
2301
  if (i < items.length) {
1817
- var p = items[i].split("\\").join("/").replace(new RegExp(localPath.replace(/(\(|\))/g, "\\$1"), "i"), "");
2302
+ var filepath = items[i];
2303
+ var p = relativePath(localPath, filepath).split("\\").join("/");
1818
2304
  p = p.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\x20-\x7E]/g, "");
1819
2305
  if (filter(p)) {
1820
- if (p.charAt(p.length - 1) !== "/") {
1821
- fs10.readFile(items[i], function(err2, data) {
1822
- if (err2) {
1823
- callback(void 0, err2);
1824
- } else {
1825
- self.addFile(zipPath + p, data, "", 0);
1826
- next();
1827
- }
1828
- });
1829
- } else {
1830
- self.addFile(zipPath + p, Buffer.alloc(0), "", 0);
1831
- next();
1832
- }
2306
+ filetools.fs.stat(filepath, function(er0, stats) {
2307
+ if (er0) callback(void 0, er0);
2308
+ if (stats.isFile()) {
2309
+ filetools.fs.readFile(filepath, function(er1, data) {
2310
+ if (er1) {
2311
+ callback(void 0, er1);
2312
+ } else {
2313
+ self.addFile(zipPath + p, data, "", stats);
2314
+ next();
2315
+ }
2316
+ });
2317
+ } else {
2318
+ self.addFile(zipPath + p + "/", Buffer.alloc(0), "", stats);
2319
+ next();
2320
+ }
2321
+ });
1833
2322
  } else {
1834
- next();
2323
+ process.nextTick(() => {
2324
+ next();
2325
+ });
1835
2326
  }
1836
2327
  } else {
1837
2328
  callback(true, void 0);
@@ -1841,47 +2332,138 @@ var require_adm_zip = __commonJS({
1841
2332
  }
1842
2333
  });
1843
2334
  },
2335
+ /**
2336
+ * Adds a local directory and all its nested files and directories to the archive
2337
+ *
2338
+ * @param {object | string} options - options object, if it is string it us used as localPath.
2339
+ * @param {string} options.localPath - Local path to the folder.
2340
+ * @param {string} [options.zipPath] - optional path inside zip.
2341
+ * @param {RegExp|function} [options.filter] - optional RegExp or Function if files match will be included.
2342
+ * @param {function|string} [options.namefix] - optional function to help fix filename
2343
+ * @param {doneCallback} callback - The callback that handles the response.
2344
+ *
2345
+ */
2346
+ addLocalFolderAsync2: function(options2, callback) {
2347
+ const self = this;
2348
+ options2 = typeof options2 === "object" ? options2 : { localPath: options2 };
2349
+ const localPath = pth.resolve(fixPath(options2.localPath));
2350
+ let { zipPath, filter, namefix } = options2;
2351
+ if (filter instanceof RegExp) {
2352
+ filter = /* @__PURE__ */ (function(rx) {
2353
+ return function(filename) {
2354
+ return rx.test(filename);
2355
+ };
2356
+ })(filter);
2357
+ } else if ("function" !== typeof filter) {
2358
+ filter = function() {
2359
+ return true;
2360
+ };
2361
+ }
2362
+ zipPath = zipPath ? fixPath(zipPath) : "";
2363
+ if (namefix === "latin1") {
2364
+ namefix = (str) => str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\x20-\x7E]/g, "");
2365
+ }
2366
+ if (typeof namefix !== "function") namefix = (str) => str;
2367
+ const relPathFix = (entry) => pth.join(zipPath, namefix(relativePath(localPath, entry)));
2368
+ const fileNameFix = (entry) => pth.win32.basename(pth.win32.normalize(namefix(entry)));
2369
+ filetools.fs.open(localPath, "r", function(err) {
2370
+ if (err && err.code === "ENOENT") {
2371
+ callback(void 0, Utils.Errors.FILE_NOT_FOUND(localPath));
2372
+ } else if (err) {
2373
+ callback(void 0, err);
2374
+ } else {
2375
+ filetools.findFilesAsync(localPath, function(err2, fileEntries) {
2376
+ if (err2) return callback(err2);
2377
+ fileEntries = fileEntries.filter((dir) => filter(relPathFix(dir)));
2378
+ if (!fileEntries.length) callback(void 0, false);
2379
+ setImmediate(
2380
+ fileEntries.reverse().reduce(function(next, entry) {
2381
+ return function(err3, done) {
2382
+ if (err3 || done === false) return setImmediate(next, err3, false);
2383
+ self.addLocalFileAsync(
2384
+ {
2385
+ localPath: entry,
2386
+ zipPath: pth.dirname(relPathFix(entry)),
2387
+ zipName: fileNameFix(entry)
2388
+ },
2389
+ next
2390
+ );
2391
+ };
2392
+ }, callback)
2393
+ );
2394
+ });
2395
+ }
2396
+ });
2397
+ },
2398
+ /**
2399
+ * Adds a local directory and all its nested files and directories to the archive
2400
+ *
2401
+ * @param {string} localPath - path where files will be extracted
2402
+ * @param {object} props - optional properties
2403
+ * @param {string} [props.zipPath] - optional path inside zip
2404
+ * @param {RegExp|function} [props.filter] - optional RegExp or Function if files match will be included.
2405
+ * @param {function|string} [props.namefix] - optional function to help fix filename
2406
+ */
2407
+ addLocalFolderPromise: function(localPath, props) {
2408
+ return new Promise((resolve, reject) => {
2409
+ this.addLocalFolderAsync2(Object.assign({ localPath }, props), (err, done) => {
2410
+ if (err) reject(err);
2411
+ if (done) resolve(this);
2412
+ });
2413
+ });
2414
+ },
1844
2415
  /**
1845
2416
  * Allows you to create a entry (file or directory) in the zip file.
1846
2417
  * If you want to create a directory the entryName must end in / and a null buffer should be provided.
1847
2418
  * Comment and attributes are optional
1848
2419
  *
1849
- * @param entryName
1850
- * @param content
1851
- * @param comment
1852
- * @param attr
2420
+ * @param {string} entryName
2421
+ * @param {Buffer | string} content - file content as buffer or utf8 coded string
2422
+ * @param {string} [comment] - file comment
2423
+ * @param {number | object} [attr] - number as unix file permissions, object as filesystem Stats object
1853
2424
  */
1854
2425
  addFile: function(entryName, content, comment, attr) {
1855
- var entry = new ZipEntry();
1856
- entry.entryName = entryName;
2426
+ entryName = zipnamefix(entryName);
2427
+ let entry = getEntry(entryName);
2428
+ const update = entry != null;
2429
+ if (!update) {
2430
+ entry = new ZipEntry(opts);
2431
+ entry.entryName = entryName;
2432
+ }
1857
2433
  entry.comment = comment || "";
1858
- if (!attr) {
1859
- if (entry.isDirectory) {
1860
- attr = 16877 << 16 | 16;
1861
- } else {
1862
- attr = 420 << 16;
1863
- }
2434
+ const isStat = "object" === typeof attr && attr instanceof filetools.fs.Stats;
2435
+ if (isStat) {
2436
+ entry.header.time = attr.mtime;
1864
2437
  }
1865
- entry.attr = attr;
2438
+ var fileattr = entry.isDirectory ? 16 : 0;
2439
+ let unix = entry.isDirectory ? 16384 : 32768;
2440
+ if (isStat) {
2441
+ unix |= 4095 & attr.mode;
2442
+ } else if ("number" === typeof attr) {
2443
+ unix |= 4095 & attr;
2444
+ } else {
2445
+ unix |= entry.isDirectory ? 493 : 420;
2446
+ }
2447
+ fileattr = (fileattr | unix << 16) >>> 0;
2448
+ entry.attr = fileattr;
1866
2449
  entry.setData(content);
1867
- _zip.setEntry(entry);
2450
+ if (!update) _zip.setEntry(entry);
2451
+ return entry;
1868
2452
  },
1869
2453
  /**
1870
2454
  * Returns an array of ZipEntry objects representing the files and folders inside the archive
1871
2455
  *
1872
- * @return Array
2456
+ * @param {string} [password]
2457
+ * @returns Array
1873
2458
  */
1874
- getEntries: function() {
1875
- if (_zip) {
1876
- return _zip.entries;
1877
- } else {
1878
- return [];
1879
- }
2459
+ getEntries: function(password) {
2460
+ _zip.password = password;
2461
+ return _zip ? _zip.entries : [];
1880
2462
  },
1881
2463
  /**
1882
2464
  * Returns a ZipEntry object representing the file or folder specified by ``name``.
1883
2465
  *
1884
- * @param name
2466
+ * @param {string} name
1885
2467
  * @return ZipEntry
1886
2468
  */
1887
2469
  getEntry: function(name) {
@@ -1897,60 +2479,64 @@ var require_adm_zip = __commonJS({
1897
2479
  * Extracts the given entry to the given targetPath
1898
2480
  * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
1899
2481
  *
1900
- * @param entry ZipEntry object or String with the full path of the entry
1901
- * @param targetPath Target folder where to write the file
1902
- * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
1903
- * will be created in targetPath as well. Default is TRUE
1904
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
1905
- * Default is FALSE
2482
+ * @param {string|ZipEntry} entry - ZipEntry object or String with the full path of the entry
2483
+ * @param {string} targetPath - Target folder where to write the file
2484
+ * @param {boolean} [maintainEntryPath=true] - If maintainEntryPath is true and the entry is inside a folder, the entry folder will be created in targetPath as well. Default is TRUE
2485
+ * @param {boolean} [overwrite=false] - If the file already exists at the target path, the file will be overwriten if this is true.
2486
+ * @param {boolean} [keepOriginalPermission=false] - The file will be set as the permission from the entry if this is true.
2487
+ * @param {string} [outFileName] - String If set will override the filename of the extracted file (Only works if the entry is a file)
1906
2488
  *
1907
2489
  * @return Boolean
1908
2490
  */
1909
- extractEntryTo: function(entry, targetPath, maintainEntryPath, overwrite) {
1910
- overwrite = overwrite || false;
1911
- maintainEntryPath = typeof maintainEntryPath === "undefined" ? true : maintainEntryPath;
2491
+ extractEntryTo: function(entry, targetPath, maintainEntryPath, overwrite, keepOriginalPermission, outFileName) {
2492
+ overwrite = get_Bool(false, overwrite);
2493
+ keepOriginalPermission = get_Bool(false, keepOriginalPermission);
2494
+ maintainEntryPath = get_Bool(true, maintainEntryPath);
2495
+ outFileName = get_Str(keepOriginalPermission, outFileName);
1912
2496
  var item = getEntry(entry);
1913
2497
  if (!item) {
1914
- throw new Error(Utils.Errors.NO_ENTRY);
2498
+ throw Utils.Errors.NO_ENTRY();
1915
2499
  }
1916
- var entryName = item.entryName;
1917
- var target = sanitize(targetPath, maintainEntryPath ? entryName : pth.basename(entryName));
2500
+ var entryName = canonical(item.entryName);
2501
+ var target = sanitize(targetPath, outFileName && !item.isDirectory ? canonical(outFileName) : maintainEntryPath ? entryName : pth.basename(entryName));
1918
2502
  if (item.isDirectory) {
1919
- target = pth.resolve(target, "..");
1920
2503
  var children = _zip.getEntryChildren(item);
1921
2504
  children.forEach(function(child) {
1922
2505
  if (child.isDirectory) return;
1923
2506
  var content2 = child.getData();
1924
2507
  if (!content2) {
1925
- throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
2508
+ throw Utils.Errors.CANT_EXTRACT_FILE();
1926
2509
  }
1927
- var childName = sanitize(targetPath, maintainEntryPath ? child.entryName : pth.basename(child.entryName));
1928
- Utils.writeFileTo(childName, content2, overwrite);
2510
+ var name = canonical(maintainEntryPath ? child.entryName : child.entryName.substring(item.entryName.length));
2511
+ var childName = sanitize(targetPath, name);
2512
+ const fileAttr2 = keepOriginalPermission ? child.header.fileAttr : void 0;
2513
+ filetools.writeFileTo(childName, content2, overwrite, fileAttr2);
1929
2514
  });
1930
2515
  return true;
1931
2516
  }
1932
- var content = item.getData();
1933
- if (!content) throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
1934
- if (fs10.existsSync(target) && !overwrite) {
1935
- throw new Error(Utils.Errors.CANT_OVERRIDE);
2517
+ var content = item.getData(_zip.password);
2518
+ if (!content) throw Utils.Errors.CANT_EXTRACT_FILE();
2519
+ if (filetools.fs.existsSync(target) && !overwrite) {
2520
+ throw Utils.Errors.CANT_OVERRIDE();
1936
2521
  }
1937
- Utils.writeFileTo(target, content, overwrite);
2522
+ const fileAttr = keepOriginalPermission ? entry.header.fileAttr : void 0;
2523
+ filetools.writeFileTo(target, content, overwrite, fileAttr);
1938
2524
  return true;
1939
2525
  },
1940
2526
  /**
1941
2527
  * Test the archive
1942
- *
2528
+ * @param {string} [pass]
1943
2529
  */
1944
- test: function() {
2530
+ test: function(pass) {
1945
2531
  if (!_zip) {
1946
2532
  return false;
1947
2533
  }
1948
- for (var entry in _zip.entries) {
2534
+ for (var entry of _zip.entries) {
1949
2535
  try {
1950
2536
  if (entry.isDirectory) {
1951
2537
  continue;
1952
2538
  }
1953
- var content = _zip.entries[entry].getData();
2539
+ var content = entry.getData(pass);
1954
2540
  if (!content) {
1955
2541
  return false;
1956
2542
  }
@@ -1963,96 +2549,139 @@ var require_adm_zip = __commonJS({
1963
2549
  /**
1964
2550
  * Extracts the entire archive to the given location
1965
2551
  *
1966
- * @param targetPath Target location
1967
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
2552
+ * @param {string} targetPath Target location
2553
+ * @param {boolean} [overwrite=false] If the file already exists at the target path, the file will be overwriten if this is true.
1968
2554
  * Default is FALSE
2555
+ * @param {boolean} [keepOriginalPermission=false] The file will be set as the permission from the entry if this is true.
2556
+ * Default is FALSE
2557
+ * @param {string|Buffer} [pass] password
1969
2558
  */
1970
- extractAllTo: function(targetPath, overwrite) {
1971
- overwrite = overwrite || false;
1972
- if (!_zip) {
1973
- throw new Error(Utils.Errors.NO_ZIP);
1974
- }
2559
+ extractAllTo: function(targetPath, overwrite, keepOriginalPermission, pass) {
2560
+ keepOriginalPermission = get_Bool(false, keepOriginalPermission);
2561
+ pass = get_Str(keepOriginalPermission, pass);
2562
+ overwrite = get_Bool(false, overwrite);
2563
+ if (!_zip) throw Utils.Errors.NO_ZIP();
2564
+ const dirEntries = [];
1975
2565
  _zip.entries.forEach(function(entry) {
1976
- var entryName = sanitize(targetPath, entry.entryName.toString());
2566
+ var entryName = sanitize(targetPath, canonical(entry.entryName));
1977
2567
  if (entry.isDirectory) {
1978
- Utils.makeDir(entryName);
2568
+ filetools.makeDir(entryName);
2569
+ if (keepOriginalPermission) dirEntries.push({ path: entryName, attr: entry.header.fileAttr });
1979
2570
  return;
1980
2571
  }
1981
- var content = entry.getData();
2572
+ var content = entry.getData(pass);
1982
2573
  if (!content) {
1983
- throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
2574
+ throw Utils.Errors.CANT_EXTRACT_FILE();
1984
2575
  }
1985
- Utils.writeFileTo(entryName, content, overwrite);
2576
+ const fileAttr = keepOriginalPermission ? entry.header.fileAttr : void 0;
2577
+ filetools.writeFileTo(entryName, content, overwrite, fileAttr);
1986
2578
  try {
1987
- fs10.utimesSync(entryName, entry.header.time, entry.header.time);
2579
+ filetools.fs.utimesSync(entryName, entry.header.time, entry.header.time);
1988
2580
  } catch (err) {
1989
- throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
1990
2581
  }
1991
2582
  });
2583
+ applyDirAttributes(dirEntries);
1992
2584
  },
1993
2585
  /**
1994
2586
  * Asynchronous extractAllTo
1995
2587
  *
1996
- * @param targetPath Target location
1997
- * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
2588
+ * @param {string} targetPath Target location
2589
+ * @param {boolean} [overwrite=false] If the file already exists at the target path, the file will be overwriten if this is true.
2590
+ * Default is FALSE
2591
+ * @param {boolean} [keepOriginalPermission=false] The file will be set as the permission from the entry if this is true.
1998
2592
  * Default is FALSE
1999
- * @param callback
2593
+ * @param {function} callback The callback will be executed when all entries are extracted successfully or any error is thrown.
2000
2594
  */
2001
- extractAllToAsync: function(targetPath, overwrite, callback) {
2595
+ extractAllToAsync: function(targetPath, overwrite, keepOriginalPermission, callback) {
2596
+ callback = get_Fun(overwrite, keepOriginalPermission, callback);
2597
+ keepOriginalPermission = get_Bool(false, keepOriginalPermission);
2598
+ overwrite = get_Bool(false, overwrite);
2002
2599
  if (!callback) {
2003
- callback = function() {
2004
- };
2600
+ return new Promise((resolve, reject) => {
2601
+ this.extractAllToAsync(targetPath, overwrite, keepOriginalPermission, function(err) {
2602
+ if (err) {
2603
+ reject(err);
2604
+ } else {
2605
+ resolve(this);
2606
+ }
2607
+ });
2608
+ });
2005
2609
  }
2006
- overwrite = overwrite || false;
2007
2610
  if (!_zip) {
2008
- callback(new Error(Utils.Errors.NO_ZIP));
2611
+ callback(Utils.Errors.NO_ZIP());
2009
2612
  return;
2010
2613
  }
2011
- var entries = _zip.entries;
2012
- var i = entries.length;
2013
- entries.forEach(function(entry) {
2014
- if (i <= 0) return;
2015
- var entryName = pth.normalize(entry.entryName.toString());
2016
- if (entry.isDirectory) {
2017
- Utils.makeDir(sanitize(targetPath, entryName));
2018
- if (--i === 0)
2019
- callback(void 0);
2020
- return;
2614
+ targetPath = pth.resolve(targetPath);
2615
+ const getPath = (entry) => sanitize(targetPath, pth.normalize(canonical(entry.entryName)));
2616
+ const getError = (msg, file) => new Error(msg + ': "' + file + '"');
2617
+ const dirEntries = [];
2618
+ const fileEntries = [];
2619
+ _zip.entries.forEach((e) => {
2620
+ if (e.isDirectory) {
2621
+ dirEntries.push(e);
2622
+ } else {
2623
+ fileEntries.push(e);
2021
2624
  }
2022
- entry.getDataAsync(function(content, err) {
2023
- if (i <= 0) return;
2024
- if (err) {
2025
- callback(new Error(err));
2026
- return;
2625
+ });
2626
+ const deferredDirAttr = [];
2627
+ for (const entry of dirEntries) {
2628
+ const dirPath = getPath(entry);
2629
+ const dirAttr = keepOriginalPermission ? entry.header.fileAttr : void 0;
2630
+ try {
2631
+ filetools.makeDir(dirPath);
2632
+ } catch (er) {
2633
+ callback(getError("Unable to create folder", dirPath));
2634
+ continue;
2635
+ }
2636
+ if (dirAttr) deferredDirAttr.push({ path: dirPath, attr: dirAttr });
2637
+ try {
2638
+ filetools.fs.utimesSync(dirPath, entry.header.time, entry.header.time);
2639
+ } catch (er) {
2640
+ }
2641
+ }
2642
+ const done = (err) => {
2643
+ if (!err) {
2644
+ try {
2645
+ applyDirAttributes(deferredDirAttr);
2646
+ } catch (er) {
2647
+ return callback(getError("Unable to set folder permissions", er.path || ""));
2027
2648
  }
2028
- if (!content) {
2029
- i = 0;
2030
- callback(new Error(Utils.Errors.CANT_EXTRACT_FILE));
2031
- return;
2649
+ }
2650
+ callback(err);
2651
+ };
2652
+ fileEntries.reverse().reduce(function(next, entry) {
2653
+ return function(err) {
2654
+ if (err) {
2655
+ next(err);
2656
+ } else {
2657
+ const entryName = pth.normalize(canonical(entry.entryName));
2658
+ const filePath = sanitize(targetPath, entryName);
2659
+ entry.getDataAsync(function(content, err_1) {
2660
+ if (err_1) {
2661
+ next(err_1);
2662
+ } else if (!content) {
2663
+ next(Utils.Errors.CANT_EXTRACT_FILE());
2664
+ } else {
2665
+ const fileAttr = keepOriginalPermission ? entry.header.fileAttr : void 0;
2666
+ filetools.writeFileToAsync(filePath, content, overwrite, fileAttr, function(succ) {
2667
+ if (!succ) {
2668
+ return next(getError("Unable to write file", filePath));
2669
+ }
2670
+ filetools.fs.utimes(filePath, entry.header.time, entry.header.time, function() {
2671
+ next();
2672
+ });
2673
+ });
2674
+ }
2675
+ });
2032
2676
  }
2033
- Utils.writeFileToAsync(sanitize(targetPath, entryName), content, overwrite, function(succ) {
2034
- try {
2035
- fs10.utimesSync(pth.resolve(targetPath, entryName), entry.header.time, entry.header.time);
2036
- } catch (err2) {
2037
- callback(new Error("Unable to set utimes"));
2038
- }
2039
- if (i <= 0) return;
2040
- if (!succ) {
2041
- i = 0;
2042
- callback(new Error("Unable to write"));
2043
- return;
2044
- }
2045
- if (--i === 0)
2046
- callback(void 0);
2047
- });
2048
- });
2049
- });
2677
+ };
2678
+ }, done)();
2050
2679
  },
2051
2680
  /**
2052
2681
  * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
2053
2682
  *
2054
- * @param targetFileName
2055
- * @param callback
2683
+ * @param {string} targetFileName
2684
+ * @param {function} callback
2056
2685
  */
2057
2686
  writeZip: function(targetFileName, callback) {
2058
2687
  if (arguments.length === 1) {
@@ -2061,23 +2690,54 @@ var require_adm_zip = __commonJS({
2061
2690
  targetFileName = "";
2062
2691
  }
2063
2692
  }
2064
- if (!targetFileName && _filename) {
2065
- targetFileName = _filename;
2693
+ if (!targetFileName && opts.filename) {
2694
+ targetFileName = opts.filename;
2066
2695
  }
2067
2696
  if (!targetFileName) return;
2068
2697
  var zipData = _zip.compressToBuffer();
2069
2698
  if (zipData) {
2070
- var ok = Utils.writeFileTo(targetFileName, zipData, true);
2699
+ var ok = filetools.writeFileTo(targetFileName, zipData, true);
2071
2700
  if (typeof callback === "function") callback(!ok ? new Error("failed") : null, "");
2072
2701
  }
2073
2702
  },
2703
+ /**
2704
+ *
2705
+ * @param {string} targetFileName
2706
+ * @param {object} [props]
2707
+ * @param {boolean} [props.overwrite=true] If the file already exists at the target path, the file will be overwriten if this is true.
2708
+ * @param {boolean} [props.perm] The file will be set as the permission from the entry if this is true.
2709
+
2710
+ * @returns {Promise<void>}
2711
+ */
2712
+ writeZipPromise: function(targetFileName, props) {
2713
+ const { overwrite, perm } = Object.assign({ overwrite: true }, props);
2714
+ return new Promise((resolve, reject) => {
2715
+ if (!targetFileName && opts.filename) targetFileName = opts.filename;
2716
+ if (!targetFileName) reject("ADM-ZIP: ZIP File Name Missing");
2717
+ this.toBufferPromise().then((zipData) => {
2718
+ const ret = (done) => done ? resolve(done) : reject("ADM-ZIP: Wasn't able to write zip file");
2719
+ filetools.writeFileToAsync(targetFileName, zipData, overwrite, perm, ret);
2720
+ }, reject);
2721
+ });
2722
+ },
2723
+ /**
2724
+ * @returns {Promise<Buffer>} A promise to the Buffer.
2725
+ */
2726
+ toBufferPromise: function() {
2727
+ return new Promise((resolve, reject) => {
2728
+ _zip.toAsyncBuffer(resolve, reject);
2729
+ });
2730
+ },
2074
2731
  /**
2075
2732
  * Returns the content of the entire zip file as a Buffer object
2076
2733
  *
2077
- * @return Buffer
2734
+ * @prop {function} [onSuccess]
2735
+ * @prop {function} [onFail]
2736
+ * @prop {function} [onItemStart]
2737
+ * @prop {function} [onItemEnd]
2738
+ * @returns {Buffer}
2078
2739
  */
2079
2740
  toBuffer: function(onSuccess, onFail, onItemStart, onItemEnd) {
2080
- this.valueOf = 2;
2081
2741
  if (typeof onSuccess === "function") {
2082
2742
  _zip.toAsyncBuffer(onSuccess, onFail, onItemStart, onItemEnd);
2083
2743
  return null;
@@ -2090,8 +2750,8 @@ var require_adm_zip = __commonJS({
2090
2750
  });
2091
2751
 
2092
2752
  // src/index.ts
2093
- import fs9 from "node:fs";
2094
- import path11 from "node:path";
2753
+ import fs12 from "node:fs";
2754
+ import path15 from "node:path";
2095
2755
  import { fileURLToPath as fileURLToPath2 } from "node:url";
2096
2756
  import os4 from "node:os";
2097
2757
 
@@ -3974,14 +4634,156 @@ async function repairNestedExpertSkillLayouts(openclawRoot) {
3974
4634
  }
3975
4635
  }
3976
4636
  }
3977
- return result;
4637
+ return result;
4638
+ }
4639
+
4640
+ // src/ws-client.ts
4641
+ import WebSocket from "ws";
4642
+ import path10 from "path";
4643
+ import fs9 from "fs/promises";
4644
+ import { DatabaseSync } from "node:sqlite";
4645
+
4646
+ // src/free-skill-directory.ts
4647
+ import fs8 from "node:fs/promises";
4648
+ import path9 from "node:path";
4649
+ var FREE_SKILL_DIRECTORY_NAME = ".xg-platform";
4650
+ var SKILL_FILE_NAME = "SKILL.md";
4651
+ function isRecord(value) {
4652
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4653
+ }
4654
+ function isWithin(parent, candidate) {
4655
+ const relative = path9.relative(parent, candidate);
4656
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path9.sep}`) && !path9.isAbsolute(relative);
4657
+ }
4658
+ function asNonEmptyString(value) {
4659
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
4660
+ }
4661
+ function parseScalar(value) {
4662
+ const trimmed = value.trim().replace(/\s+#.*$/, "").trim();
4663
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
4664
+ return trimmed.slice(1, -1).trim();
4665
+ }
4666
+ return trimmed;
4667
+ }
4668
+ function parseFrontmatter(content) {
4669
+ const lines = content.replace(/^\uFEFF/, "").split(/\r?\n/);
4670
+ if (lines[0]?.trim() !== "---") return {};
4671
+ const fields = {};
4672
+ for (const line of lines.slice(1)) {
4673
+ if (line.trim() === "---" || line.trim() === "...") break;
4674
+ const match2 = /^\s*([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*?)\s*$/.exec(line);
4675
+ if (match2) fields[match2[1]] = parseScalar(match2[2]);
4676
+ }
4677
+ return fields;
4678
+ }
4679
+ async function realPathIfRegularFile(filePath) {
4680
+ try {
4681
+ const resolved = await fs8.realpath(filePath);
4682
+ const stats = await fs8.stat(resolved);
4683
+ return stats.isFile() ? resolved : void 0;
4684
+ } catch {
4685
+ return void 0;
4686
+ }
4687
+ }
4688
+ async function readOptionalMetadata(skillPath, workspacePath) {
4689
+ const candidate = path9.resolve(skillPath, ".meta.json");
4690
+ if (!isWithin(skillPath, candidate) || !isWithin(workspacePath, candidate)) return {};
4691
+ const metadataPath = await realPathIfRegularFile(candidate);
4692
+ if (!metadataPath || !isWithin(skillPath, metadataPath) || !isWithin(workspacePath, metadataPath)) return {};
4693
+ try {
4694
+ const parsed = JSON.parse(await fs8.readFile(metadataPath, "utf8"));
4695
+ if (!isRecord(parsed)) return {};
4696
+ return parsed;
4697
+ } catch {
4698
+ return {};
4699
+ }
4700
+ }
4701
+ async function scanSkill(directoryPath, workspacePath, entryName) {
4702
+ const candidateSkillPath = path9.resolve(directoryPath, entryName);
4703
+ if (!isWithin(directoryPath, candidateSkillPath) || !isWithin(workspacePath, candidateSkillPath)) return void 0;
4704
+ const skillPath = await realPathIfRegularFile(candidateSkillPath);
4705
+ if (skillPath) return void 0;
4706
+ let resolvedSkillPath;
4707
+ try {
4708
+ resolvedSkillPath = await fs8.realpath(candidateSkillPath);
4709
+ const stats = await fs8.stat(resolvedSkillPath);
4710
+ if (!stats.isDirectory()) return void 0;
4711
+ } catch {
4712
+ return void 0;
4713
+ }
4714
+ if (!isWithin(directoryPath, resolvedSkillPath) || !isWithin(workspacePath, resolvedSkillPath)) return void 0;
4715
+ const candidateSkillFilePath = path9.resolve(resolvedSkillPath, SKILL_FILE_NAME);
4716
+ if (!isWithin(resolvedSkillPath, candidateSkillFilePath) || !isWithin(workspacePath, candidateSkillFilePath)) {
4717
+ return void 0;
4718
+ }
4719
+ const skillFilePath = await realPathIfRegularFile(candidateSkillFilePath);
4720
+ if (!skillFilePath || !isWithin(resolvedSkillPath, skillFilePath) || !isWithin(workspacePath, skillFilePath)) {
4721
+ return void 0;
4722
+ }
4723
+ let skillFileContent;
4724
+ try {
4725
+ skillFileContent = await fs8.readFile(skillFilePath, "utf8");
4726
+ } catch {
4727
+ return void 0;
4728
+ }
4729
+ const frontmatter = parseFrontmatter(skillFileContent);
4730
+ const meta = await readOptionalMetadata(resolvedSkillPath, workspacePath);
4731
+ const nestedMetadata = isRecord(meta.metadata) ? meta.metadata : {};
4732
+ const getValue = (...values) => {
4733
+ for (const value of values) {
4734
+ const result = asNonEmptyString(value);
4735
+ if (result) return result;
4736
+ }
4737
+ return void 0;
4738
+ };
4739
+ const code = entryName;
4740
+ return {
4741
+ code,
4742
+ name: getValue(meta.name, nestedMetadata.name, frontmatter.name) ?? code,
4743
+ description: getValue(meta.description, nestedMetadata.description, frontmatter.description) ?? "",
4744
+ version: getValue(meta.version, nestedMetadata.version, frontmatter.version) ?? "",
4745
+ directoryPath,
4746
+ skillPath: resolvedSkillPath,
4747
+ skillFilePath
4748
+ };
4749
+ }
4750
+ async function scanFreeSkillDirectory(workspace) {
4751
+ const resolvedWorkspace = path9.resolve(workspace);
4752
+ let workspacePath;
4753
+ try {
4754
+ workspacePath = await fs8.realpath(resolvedWorkspace);
4755
+ const stats = await fs8.stat(workspacePath);
4756
+ if (!stats.isDirectory()) return [];
4757
+ } catch {
4758
+ return [];
4759
+ }
4760
+ const candidateDirectoryPath = path9.resolve(workspacePath, FREE_SKILL_DIRECTORY_NAME);
4761
+ if (!isWithin(workspacePath, candidateDirectoryPath)) return [];
4762
+ let directoryPath;
4763
+ try {
4764
+ directoryPath = await fs8.realpath(candidateDirectoryPath);
4765
+ const stats = await fs8.stat(directoryPath);
4766
+ if (!stats.isDirectory()) return [];
4767
+ } catch {
4768
+ return [];
4769
+ }
4770
+ if (!isWithin(workspacePath, directoryPath)) return [];
4771
+ let entries;
4772
+ try {
4773
+ entries = await fs8.readdir(directoryPath, { withFileTypes: true });
4774
+ } catch {
4775
+ return [];
4776
+ }
4777
+ const skills = [];
4778
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
4779
+ if (!entry.isDirectory()) continue;
4780
+ const skill = await scanSkill(directoryPath, workspacePath, entry.name);
4781
+ if (skill) skills.push(skill);
4782
+ }
4783
+ return skills;
3978
4784
  }
3979
4785
 
3980
4786
  // src/ws-client.ts
3981
- import WebSocket from "ws";
3982
- import path9 from "path";
3983
- import fs8 from "fs/promises";
3984
- import { DatabaseSync } from "node:sqlite";
3985
4787
  var HEARTBEAT_INTERVAL_MS = 3e4;
3986
4788
  var HEARTBEAT_ACK_TIMEOUT_MS = 75e3;
3987
4789
  var AGENT_SCAN_INTERVAL_MS = 3 * 60 * 1e3;
@@ -4034,10 +4836,10 @@ function resolveSkillInstallTarget(config, userId) {
4034
4836
  if (typeof workspace !== "string" || !workspace.trim()) {
4035
4837
  throw new Error(`\u672C\u5730 Agent ${localAgentId} \u672A\u914D\u7F6E workspace`);
4036
4838
  }
4037
- return { skillsDir: path9.join(workspace, "skills"), localAgentId };
4839
+ return { skillsDir: path10.join(workspace, "skills"), localAgentId };
4038
4840
  }
4039
4841
  function normalizeAssistantUserId(userId) {
4040
- const safeUserId = path9.basename(userId);
4842
+ const safeUserId = path10.basename(userId);
4041
4843
  if (safeUserId !== userId) return void 0;
4042
4844
  const pureId = safeUserId.startsWith(ASSISTANT_AGENT_PREFIX) ? safeUserId.slice(ASSISTANT_AGENT_PREFIX.length) : safeUserId;
4043
4845
  if (!ASSISTANT_WORKSPACE_ID_RE.test(pureId)) return void 0;
@@ -4046,29 +4848,29 @@ function normalizeAssistantUserId(userId) {
4046
4848
  function normalizeCommandCode(code) {
4047
4849
  if (typeof code !== "string" || code.length === 0 || code === "." || code === "..") return void 0;
4048
4850
  if (code.includes("/") || code.includes("\\") || code.includes("\0")) return void 0;
4049
- if (path9.basename(code) !== code) return void 0;
4851
+ if (path10.basename(code) !== code) return void 0;
4050
4852
  return code;
4051
4853
  }
4052
4854
  function shouldSyncBuiltInTemplate(action, isBuiltIn) {
4053
4855
  return action === "UPDATE_SKILL" && isBuiltIn === true;
4054
4856
  }
4055
4857
  function resolveGatewaySkillTarget(home = openclawHome()) {
4056
- return path9.join(home, "skills");
4858
+ return path10.join(home, "skills");
4057
4859
  }
4058
4860
  function isGatewaySkillCommand(action, installScope) {
4059
4861
  return installScope === "gateway" && ["INSTALL_SKILL", "UPDATE_SKILL", "UNINSTALL_SKILL"].includes(String(action || ""));
4060
4862
  }
4061
4863
  async function findInstalledExpertSkillsRoot(rootPath, pureId, code) {
4062
- const skillsRoot = path9.join(rootPath, `workspace-assistant-${pureId}`, ".user", "skills");
4864
+ const skillsRoot = path10.join(rootPath, `workspace-assistant-${pureId}`, ".user", "skills");
4063
4865
  try {
4064
- const stat = await fs8.stat(path9.join(skillsRoot, code));
4866
+ const stat = await fs9.stat(path10.join(skillsRoot, code));
4065
4867
  return stat.isDirectory() ? skillsRoot : void 0;
4066
4868
  } catch {
4067
4869
  return void 0;
4068
4870
  }
4069
4871
  }
4070
4872
  function defaultOpenclawSqlitePath() {
4071
- return path9.join(openclawHome(), "state", "openclaw.sqlite");
4873
+ return path10.join(openclawHome(), "state", "openclaw.sqlite");
4072
4874
  }
4073
4875
  function readCronJobsByAgentId(agentId, sqlitePath = defaultOpenclawSqlitePath(), onError) {
4074
4876
  let db;
@@ -4082,6 +4884,49 @@ function readCronJobsByAgentId(agentId, sqlitePath = defaultOpenclawSqlitePath()
4082
4884
  db?.close();
4083
4885
  }
4084
4886
  }
4887
+ function isWithinPath(parent, candidate) {
4888
+ const relative = path10.relative(parent, candidate);
4889
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path10.sep}`) && !path10.isAbsolute(relative);
4890
+ }
4891
+ function relativeWorkspacePath(workspace, target) {
4892
+ const relative = path10.relative(workspace, target);
4893
+ return isWithinPath(workspace, target) ? relative : "";
4894
+ }
4895
+ async function resolveRealWorkspace(workspace) {
4896
+ const resolved = path10.resolve(workspace);
4897
+ try {
4898
+ return await fs9.realpath(resolved);
4899
+ } catch {
4900
+ return resolved;
4901
+ }
4902
+ }
4903
+ async function resolveFreeSkillDirectoryPath(workspace) {
4904
+ const workspacePath = await resolveRealWorkspace(workspace);
4905
+ const candidate = path10.resolve(workspacePath, ".xg-platform");
4906
+ try {
4907
+ const directoryPath = await fs9.realpath(candidate);
4908
+ const stat = await fs9.stat(directoryPath);
4909
+ return stat.isDirectory() && isWithinPath(workspacePath, directoryPath) ? directoryPath : "";
4910
+ } catch {
4911
+ return "";
4912
+ }
4913
+ }
4914
+ function buildFreeSkillDirectoryResponse(gatewayId, agentId, workspacePath, directoryPath, skills) {
4915
+ return {
4916
+ gatewayId,
4917
+ agentId,
4918
+ directoryPath,
4919
+ skills: skills.map((skill) => ({
4920
+ code: skill.code,
4921
+ name: skill.name,
4922
+ description: skill.description,
4923
+ version: skill.version,
4924
+ workspaceRelativePath: relativeWorkspacePath(workspacePath, skill.skillPath),
4925
+ skillFilePath: relativeWorkspacePath(workspacePath, skill.skillFilePath),
4926
+ hostSkillFilePath: skill.skillFilePath
4927
+ }))
4928
+ };
4929
+ }
4085
4930
  var GatewayWsClient = class {
4086
4931
  ws = null;
4087
4932
  options;
@@ -4108,10 +4953,10 @@ var GatewayWsClient = class {
4108
4953
  }
4109
4954
  }
4110
4955
  logLine += "\n";
4111
- const logsDir = path9.join(openclawHome(), "logs");
4112
- fs8.mkdir(logsDir, { recursive: true }).then(() => {
4113
- const logPath = path9.join(logsDir, "skill-logger.err");
4114
- fs8.appendFile(logPath, logLine).catch(() => {
4956
+ const logsDir = path10.join(openclawHome(), "logs");
4957
+ fs9.mkdir(logsDir, { recursive: true }).then(() => {
4958
+ const logPath = path10.join(logsDir, "skill-logger.err");
4959
+ fs9.appendFile(logPath, logLine).catch(() => {
4115
4960
  });
4116
4961
  }).catch(() => {
4117
4962
  });
@@ -4126,16 +4971,25 @@ var GatewayWsClient = class {
4126
4971
  });
4127
4972
  };
4128
4973
  }
4129
- /** 普通 Skill 的所有读写操作共用这一个配置驱动的寻址入口。 */
4130
- async resolveRegularSkillTarget(userId) {
4131
- const configPath = path9.join(openclawHome(), "openclaw.json");
4132
- let config;
4974
+ async readOpenclawConfig() {
4975
+ const configPath = path10.join(openclawHome(), "openclaw.json");
4133
4976
  try {
4134
- config = JSON.parse(await fs8.readFile(configPath, "utf-8"));
4977
+ return JSON.parse(await fs9.readFile(configPath, "utf-8"));
4135
4978
  } catch (err) {
4136
4979
  throw new Error(`\u65E0\u6CD5\u8BFB\u53D6 openclaw.json: ${err?.message || String(err)}`);
4137
4980
  }
4138
- return resolveSkillInstallTarget(config, userId).skillsDir;
4981
+ }
4982
+ async resolveRegularSkillContext(userId) {
4983
+ const target = resolveSkillInstallTarget(await this.readOpenclawConfig(), userId);
4984
+ return { ...target, workspace: path10.dirname(target.skillsDir) };
4985
+ }
4986
+ /** 普通 Skill 的所有读写操作共用这一个配置驱动的寻址入口。 */
4987
+ async resolveRegularSkillTarget(userId) {
4988
+ return (await this.resolveRegularSkillContext(userId)).skillsDir;
4989
+ }
4990
+ async resolveFreeSkillRequestContext(userId) {
4991
+ const target = await this.resolveRegularSkillContext(userId);
4992
+ return { workspace: target.workspace, agentId: target.localAgentId };
4139
4993
  }
4140
4994
  constructor(options) {
4141
4995
  this.options = options;
@@ -4236,10 +5090,10 @@ var GatewayWsClient = class {
4236
5090
  async scanAndReportAgents(isInitialReport) {
4237
5091
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;
4238
5092
  try {
4239
- const configPath = path9.join(openclawHome(), "openclaw.json");
5093
+ const configPath = path10.join(openclawHome(), "openclaw.json");
4240
5094
  let rawConfig;
4241
5095
  try {
4242
- rawConfig = await fs8.readFile(configPath, "utf-8");
5096
+ rawConfig = await fs9.readFile(configPath, "utf-8");
4243
5097
  } catch (e) {
4244
5098
  this.appendLogToFile("WARN", "AgentScan", "OpenClaw config is not readable; skipping this scan cycle", e);
4245
5099
  return;
@@ -4423,6 +5277,14 @@ var GatewayWsClient = class {
4423
5277
  }
4424
5278
  if (!userId) {
4425
5279
  this.appendLogToFile("WARN", "Command", `Message dropped: missing userId`, msg);
5280
+ if (action === "LIST_FREE_SKILLS") {
5281
+ this.reply(replyId, {
5282
+ success: false,
5283
+ error: "INVALID_REQUEST",
5284
+ message: "Missing userId parameter",
5285
+ action
5286
+ });
5287
+ }
4426
5288
  return;
4427
5289
  }
4428
5290
  const safeCode = normalizeCommandCode(code);
@@ -4461,14 +5323,27 @@ var GatewayWsClient = class {
4461
5323
  const targetDir = gatewaySkillCommand ? resolveGatewaySkillTarget() : await this.resolveRegularSkillTarget(userId);
4462
5324
  console.log(`[skill-logger-plugin][WS] Executing UNINSTALL for user ${userId}, code: ${safeCode}`);
4463
5325
  this.appendLogToFile("INFO", "Command", `UNINSTALL_SKILL received`, { userId, code: safeCode });
4464
- const skillPath = path9.join(targetDir, safeCode);
4465
- await fs8.rm(skillPath, { recursive: true, force: true });
5326
+ const skillPath = path10.join(targetDir, safeCode);
5327
+ await fs9.rm(skillPath, { recursive: true, force: true });
4466
5328
  this.reply(replyId, {
4467
5329
  success: true,
4468
5330
  message: `Skill ${safeCode} removed`,
4469
5331
  action,
4470
5332
  data: { code: safeCode, installScope: gatewaySkillCommand ? "gateway" : "agent", removed: true }
4471
5333
  });
5334
+ } else if (action === "LIST_FREE_SKILLS") {
5335
+ const context = await this.resolveFreeSkillRequestContext(userId);
5336
+ const workspacePath = await resolveRealWorkspace(context.workspace);
5337
+ const scannedSkills = await scanFreeSkillDirectory(context.workspace);
5338
+ const directoryPath = scannedSkills[0]?.directoryPath || await resolveFreeSkillDirectoryPath(context.workspace);
5339
+ const data = buildFreeSkillDirectoryResponse(
5340
+ this.options.gatewayId,
5341
+ context.agentId,
5342
+ workspacePath,
5343
+ directoryPath,
5344
+ scannedSkills
5345
+ );
5346
+ this.reply(replyId, { success: true, data, action });
4472
5347
  } else if (action === "LIST_SKILLS") {
4473
5348
  const regularTargetDir = await this.resolveRegularSkillTarget(userId);
4474
5349
  const skillsByCode = /* @__PURE__ */ new Map();
@@ -4479,22 +5354,22 @@ var GatewayWsClient = class {
4479
5354
  for (const source of sources) {
4480
5355
  let entries;
4481
5356
  try {
4482
- entries = await fs8.readdir(source.dir, { withFileTypes: true });
5357
+ entries = await fs9.readdir(source.dir, { withFileTypes: true });
4483
5358
  } catch (err) {
4484
5359
  if (err?.code === "ENOENT") continue;
4485
5360
  throw err;
4486
5361
  }
4487
5362
  const dirs = entries.filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith("."));
4488
5363
  for (const e of dirs) {
4489
- const skillDir = path9.join(source.dir, e.name);
4490
- const skillMdPath = path9.join(skillDir, "SKILL.md");
5364
+ const skillDir = path10.join(source.dir, e.name);
5365
+ const skillMdPath = path10.join(skillDir, "SKILL.md");
4491
5366
  try {
4492
- const stat = await fs8.stat(skillMdPath);
5367
+ const stat = await fs9.stat(skillMdPath);
4493
5368
  if (!stat.isFile()) continue;
4494
5369
  } catch {
4495
5370
  continue;
4496
5371
  }
4497
- const metaPath = path9.join(skillDir, ".meta.json");
5372
+ const metaPath = path10.join(skillDir, ".meta.json");
4498
5373
  let isPlatform = source.gatewayBuiltIn;
4499
5374
  let isBuiltIn2 = source.gatewayBuiltIn || e.isSymbolicLink();
4500
5375
  let metaData = null;
@@ -4502,7 +5377,7 @@ var GatewayWsClient = class {
4502
5377
  let description = "";
4503
5378
  let skillVersion = "";
4504
5379
  try {
4505
- const mdContent = await fs8.readFile(skillMdPath, "utf8");
5380
+ const mdContent = await fs9.readFile(skillMdPath, "utf8");
4506
5381
  const fm = /^---\r?\n([\s\S]*?)\r?\n---/.exec(mdContent)?.[1] ?? "";
4507
5382
  const parsedName = /(^|\n)name:\s*(.+)/.exec(fm)?.[2]?.trim();
4508
5383
  if (parsedName) name = parsedName;
@@ -4511,7 +5386,7 @@ var GatewayWsClient = class {
4511
5386
  } catch {
4512
5387
  }
4513
5388
  try {
4514
- const parsed = JSON.parse(await fs8.readFile(metaPath, "utf8"));
5389
+ const parsed = JSON.parse(await fs9.readFile(metaPath, "utf8"));
4515
5390
  if (parsed) {
4516
5391
  if (parsed.ownerId === "CMS" || parsed.ownerId === "CMS_COMPAT") isPlatform = true;
4517
5392
  if (parsed.isBuiltIn === true || parsed.ownerId === "built-in") isBuiltIn2 = true;
@@ -4561,7 +5436,7 @@ var GatewayWsClient = class {
4561
5436
  setTimeout(async () => {
4562
5437
  try {
4563
5438
  const targetDir = gatewaySkillCommand ? resolveGatewaySkillTarget() : await this.resolveRegularSkillTarget(userId);
4564
- const additionalTargetDirs = syncBuiltInTemplate ? [path9.join(openclawHome(), "workspace-xgjk-assistant-template", "skills")] : [];
5439
+ const additionalTargetDirs = syncBuiltInTemplate ? [path10.join(openclawHome(), "workspace-xgjk-assistant-template", "skills")] : [];
4565
5440
  const userSkillRoot = pureId ? await findInstalledExpertSkillsRoot(openclawHome(), pureId, safeCode) : void 0;
4566
5441
  if (userSkillRoot) additionalTargetDirs.push(userSkillRoot);
4567
5442
  const result = await this.options.updater.manualInstall({
@@ -4612,12 +5487,12 @@ var GatewayWsClient = class {
4612
5487
  const { name, version: version2, downloadUrl, skills } = msg;
4613
5488
  console.log(`[skill-logger-plugin][WS] Executing INSTALL_EXPERT for user ${userId}, code: ${safeCode}`);
4614
5489
  this.appendLogToFile("INFO", "Command", `INSTALL_EXPERT received`, { userId, code: safeCode, version: version2, downloadUrl });
4615
- const userSkillRoot = path9.join(openclawHome(), `workspace-assistant-${pureId}`, ".user");
4616
- const expertTarget = path9.join(userSkillRoot, "experts", safeCode);
5490
+ const userSkillRoot = path10.join(openclawHome(), `workspace-assistant-${pureId}`, ".user");
5491
+ const expertTarget = path10.join(userSkillRoot, "experts", safeCode);
4617
5492
  let skipInstall = false;
4618
- const metaPath = path9.join(expertTarget, ".meta.json");
5493
+ const metaPath = path10.join(expertTarget, ".meta.json");
4619
5494
  try {
4620
- const raw = await fs8.readFile(metaPath, "utf-8");
5495
+ const raw = await fs9.readFile(metaPath, "utf-8");
4621
5496
  const existing = JSON.parse(raw);
4622
5497
  if (existing.version && existing.version === (version2 || "1.0.0")) {
4623
5498
  skipInstall = true;
@@ -4625,16 +5500,16 @@ var GatewayWsClient = class {
4625
5500
  } catch {
4626
5501
  }
4627
5502
  if (!skipInstall) {
4628
- await fs8.mkdir(path9.dirname(expertTarget), { recursive: true });
5503
+ await fs9.mkdir(path10.dirname(expertTarget), { recursive: true });
4629
5504
  const expertResult = await this.options.updater.installExpertZipFromUrl(downloadUrl, expertTarget);
4630
5505
  if (!expertResult.success) {
4631
5506
  throw new Error(`\u4E13\u5BB6\u5B89\u88C5\u5931\u8D25: ${expertResult.message}`);
4632
5507
  }
4633
5508
  }
4634
5509
  const meta = { code: safeCode, name, version: version2 || "1.0.0", installedAt: Date.now() };
4635
- await fs8.writeFile(metaPath, JSON.stringify(meta, null, 2));
4636
- const skillTargetRoot = path9.join(userSkillRoot, "skills");
4637
- await fs8.mkdir(skillTargetRoot, { recursive: true });
5510
+ await fs9.writeFile(metaPath, JSON.stringify(meta, null, 2));
5511
+ const skillTargetRoot = path10.join(userSkillRoot, "skills");
5512
+ await fs9.mkdir(skillTargetRoot, { recursive: true });
4638
5513
  const skillResults = [];
4639
5514
  if (Array.isArray(skills)) {
4640
5515
  for (const sk of skills) {
@@ -4671,23 +5546,23 @@ var GatewayWsClient = class {
4671
5546
  if (!safeCode) throw new Error("Missing code parameter");
4672
5547
  console.log(`[skill-logger-plugin][WS] Executing UNINSTALL_EXPERT for user ${userId}, code: ${safeCode}`);
4673
5548
  this.appendLogToFile("INFO", "Command", `UNINSTALL_EXPERT received`, { userId, code: safeCode });
4674
- const expertPath = path9.join(openclawHome(), `workspace-assistant-${pureId}`, ".user", "experts", safeCode);
4675
- await fs8.rm(expertPath, { recursive: true, force: true });
5549
+ const expertPath = path10.join(openclawHome(), `workspace-assistant-${pureId}`, ".user", "experts", safeCode);
5550
+ await fs9.rm(expertPath, { recursive: true, force: true });
4676
5551
  this.reply(replyId, { success: true, message: `\u4E13\u5BB6 ${safeCode} \u5DF2\u5378\u8F7D`, action });
4677
5552
  } else if (action === "LIST_EXPERTS") {
4678
5553
  console.log(`[skill-logger-plugin][WS] Executing LIST_EXPERTS for user ${userId}`);
4679
5554
  this.appendLogToFile("INFO", "Command", `LIST_EXPERTS received`, { userId });
4680
- const expertsDir = path9.join(openclawHome(), `workspace-assistant-${pureId}`, ".user", "experts");
5555
+ const expertsDir = path10.join(openclawHome(), `workspace-assistant-${pureId}`, ".user", "experts");
4681
5556
  const list = [];
4682
5557
  try {
4683
- const stat = await fs8.stat(expertsDir);
5558
+ const stat = await fs9.stat(expertsDir);
4684
5559
  if (stat.isDirectory()) {
4685
- const entries = await fs8.readdir(expertsDir, { withFileTypes: true });
5560
+ const entries = await fs9.readdir(expertsDir, { withFileTypes: true });
4686
5561
  for (const e of entries) {
4687
5562
  if (!e.isDirectory()) continue;
4688
- const metaPath = path9.join(expertsDir, e.name, ".meta.json");
5563
+ const metaPath = path10.join(expertsDir, e.name, ".meta.json");
4689
5564
  try {
4690
- const raw = await fs8.readFile(metaPath, "utf-8");
5565
+ const raw = await fs9.readFile(metaPath, "utf-8");
4691
5566
  const meta = JSON.parse(raw);
4692
5567
  list.push({
4693
5568
  code: meta.code || e.name,
@@ -4706,7 +5581,17 @@ var GatewayWsClient = class {
4706
5581
  } else {
4707
5582
  console.warn(`[skill-logger-plugin][WS] Unknown action: ${action}`);
4708
5583
  this.appendLogToFile("WARN", "Command", `Unknown action: ${action}`);
4709
- this.reply(replyId, { success: false, message: `Unknown action: ${action}`, action });
5584
+ if (action === "LIST_FREE_SKILLS") {
5585
+ this.reply(replyId, {
5586
+ success: false,
5587
+ unsupported: true,
5588
+ error: "UNSUPPORTED_ACTION",
5589
+ message: "LIST_FREE_SKILLS unsupported by this plugin",
5590
+ action
5591
+ });
5592
+ } else {
5593
+ this.reply(replyId, { success: false, message: `Unknown action: ${action}`, action });
5594
+ }
4710
5595
  }
4711
5596
  } catch (err) {
4712
5597
  this.appendLogToFile("ERROR", "Command", `Error executing action ${action}`, err);
@@ -4741,7 +5626,7 @@ var GatewayWsClient = class {
4741
5626
  };
4742
5627
 
4743
5628
  // src/hooks.ts
4744
- import path10 from "node:path";
5629
+ import path11 from "node:path";
4745
5630
  import { randomUUID as randomUUID3 } from "node:crypto";
4746
5631
  var PENDING_TTL_MS = 30 * 60 * 1e3;
4747
5632
  var PENDING_MAX = 5e3;
@@ -4750,7 +5635,7 @@ function toMySQLDateTime(d) {
4750
5635
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
4751
5636
  }
4752
5637
  function isSkillMdReadPath(filePath) {
4753
- return path10.basename(filePath) === "SKILL.md";
5638
+ return path11.basename(filePath) === "SKILL.md";
4754
5639
  }
4755
5640
  function extractAppKey(event, ctx) {
4756
5641
  try {
@@ -4930,8 +5815,8 @@ var Hooks = class {
4930
5815
  if (toolName === "read") {
4931
5816
  const filePath = params.path ?? params.file_path ?? "";
4932
5817
  if (!isSkillMdReadPath(filePath)) return;
4933
- const rootDir = path10.dirname(filePath);
4934
- const skillName = this.configSync.resolveSkillName(rootDir) || path10.basename(rootDir);
5818
+ const rootDir = path11.dirname(filePath);
5819
+ const skillName = this.configSync.resolveSkillName(rootDir) || path11.basename(rootDir);
4935
5820
  if (!skillName) return;
4936
5821
  this.debug(`Intercepted 'read' for SKILL.md. Attributed to skill: ${skillName}`);
4937
5822
  this.recordTrigger(skillName, "inline", "read", ctx, appKey);
@@ -5113,6 +5998,637 @@ var Hooks = class {
5113
5998
  }
5114
5999
  };
5115
6000
 
6001
+ // src/free-skill-tool.ts
6002
+ import path14 from "node:path";
6003
+
6004
+ // src/free-skill-writer.ts
6005
+ import crypto from "node:crypto";
6006
+ import fs11 from "node:fs/promises";
6007
+ import path13 from "node:path";
6008
+
6009
+ // src/free-skill-workspace.ts
6010
+ import fs10 from "node:fs/promises";
6011
+ import path12 from "node:path";
6012
+ var FREE_SKILL_DIRECTORY_NAME2 = ".xg-platform";
6013
+ var FreeSkillWorkspaceError = class extends Error {
6014
+ code;
6015
+ constructor(code, message) {
6016
+ super(message);
6017
+ this.code = code;
6018
+ this.name = "FreeSkillWorkspaceError";
6019
+ }
6020
+ };
6021
+ function isRecord2(value) {
6022
+ return typeof value === "object" && value !== null;
6023
+ }
6024
+ function nonEmptyString(value) {
6025
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
6026
+ }
6027
+ function isWithin2(parent, candidate) {
6028
+ const relative = path12.relative(parent, candidate);
6029
+ return relative === "" || !relative.startsWith(`..${path12.sep}`) && relative !== ".." && !path12.isAbsolute(relative);
6030
+ }
6031
+ function nestedRecord(value, key) {
6032
+ if (!isRecord2(value)) return void 0;
6033
+ const nested = value[key];
6034
+ return isRecord2(nested) ? nested : void 0;
6035
+ }
6036
+ function firstWorkspaceValue(context) {
6037
+ if (!isRecord2(context)) return void 0;
6038
+ const wrapped = nestedRecord(context, "ctx");
6039
+ const nestedContext = nestedRecord(context, "context");
6040
+ const candidates = [
6041
+ context.workspaceDir,
6042
+ context.workspace,
6043
+ wrapped?.workspaceDir,
6044
+ wrapped?.workspace,
6045
+ nestedContext?.workspaceDir,
6046
+ nestedContext?.workspace
6047
+ ];
6048
+ return candidates.map(nonEmptyString).find((value) => Boolean(value));
6049
+ }
6050
+ function firstAgentIdValue(context) {
6051
+ if (!isRecord2(context)) return void 0;
6052
+ const wrapped = nestedRecord(context, "ctx");
6053
+ const nestedContext = nestedRecord(context, "context");
6054
+ const agent = isRecord2(context.agent) ? context.agent.id : void 0;
6055
+ const wrappedAgent = isRecord2(wrapped?.agent) ? wrapped?.agent.id : void 0;
6056
+ const nestedContextAgent = isRecord2(nestedContext?.agent) ? nestedContext?.agent.id : void 0;
6057
+ const candidates = [
6058
+ context.agentId,
6059
+ agent,
6060
+ wrapped?.agentId,
6061
+ wrappedAgent,
6062
+ nestedContext?.agentId,
6063
+ nestedContextAgent
6064
+ ];
6065
+ return candidates.map(nonEmptyString).find((value) => Boolean(value));
6066
+ }
6067
+ async function resolveWorkspacePath(workspaceInput) {
6068
+ let workspacePath;
6069
+ try {
6070
+ workspacePath = await fs10.realpath(path12.resolve(workspaceInput));
6071
+ } catch {
6072
+ throw new FreeSkillWorkspaceError(
6073
+ "WORKSPACE_MISSING",
6074
+ `Agent workspace \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${workspaceInput}`
6075
+ );
6076
+ }
6077
+ try {
6078
+ const stat = await fs10.stat(workspacePath);
6079
+ if (!stat.isDirectory()) {
6080
+ throw new FreeSkillWorkspaceError(
6081
+ "WORKSPACE_NOT_DIRECTORY",
6082
+ `Agent workspace \u4E0D\u662F\u76EE\u5F55: ${workspaceInput}`
6083
+ );
6084
+ }
6085
+ } catch (error) {
6086
+ if (error instanceof FreeSkillWorkspaceError) throw error;
6087
+ throw new FreeSkillWorkspaceError(
6088
+ "WORKSPACE_MISSING",
6089
+ `Agent workspace \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${workspaceInput}`
6090
+ );
6091
+ }
6092
+ return workspacePath;
6093
+ }
6094
+ async function resolvePlatformDirectory(workspacePath) {
6095
+ const candidate = path12.resolve(workspacePath, FREE_SKILL_DIRECTORY_NAME2);
6096
+ if (!isWithin2(workspacePath, candidate)) {
6097
+ throw new FreeSkillWorkspaceError(
6098
+ "PLATFORM_DIRECTORY_ESCAPE",
6099
+ "`.xg-platform` \u4E0D\u5728 Agent workspace \u5185"
6100
+ );
6101
+ }
6102
+ let entry;
6103
+ try {
6104
+ entry = await fs10.lstat(candidate);
6105
+ } catch (error) {
6106
+ if (error?.code === "ENOENT") return candidate;
6107
+ throw new FreeSkillWorkspaceError(
6108
+ "PLATFORM_DIRECTORY_BROKEN_LINK",
6109
+ "\u65E0\u6CD5\u68C0\u67E5 Agent workspace \u4E0B\u7684 `.xg-platform`"
6110
+ );
6111
+ }
6112
+ let resolved = candidate;
6113
+ if (entry.isSymbolicLink()) {
6114
+ try {
6115
+ resolved = await fs10.realpath(candidate);
6116
+ } catch {
6117
+ throw new FreeSkillWorkspaceError(
6118
+ "PLATFORM_DIRECTORY_BROKEN_LINK",
6119
+ "`.xg-platform` \u662F\u5931\u6548\u7B26\u53F7\u94FE\u63A5"
6120
+ );
6121
+ }
6122
+ if (!isWithin2(workspacePath, resolved)) {
6123
+ throw new FreeSkillWorkspaceError(
6124
+ "PLATFORM_DIRECTORY_ESCAPE",
6125
+ "`.xg-platform` \u7B26\u53F7\u94FE\u63A5\u8D8A\u51FA Agent workspace"
6126
+ );
6127
+ }
6128
+ }
6129
+ try {
6130
+ const stat = await fs10.stat(resolved);
6131
+ if (!stat.isDirectory()) {
6132
+ throw new FreeSkillWorkspaceError(
6133
+ "PLATFORM_DIRECTORY_NOT_DIRECTORY",
6134
+ "Agent workspace \u4E0B\u7684 `.xg-platform` \u4E0D\u662F\u76EE\u5F55"
6135
+ );
6136
+ }
6137
+ } catch (error) {
6138
+ if (error instanceof FreeSkillWorkspaceError) throw error;
6139
+ throw new FreeSkillWorkspaceError(
6140
+ "PLATFORM_DIRECTORY_BROKEN_LINK",
6141
+ "\u65E0\u6CD5\u8BBF\u95EE Agent workspace \u4E0B\u7684 `.xg-platform`"
6142
+ );
6143
+ }
6144
+ return resolved;
6145
+ }
6146
+ async function resolveFreeSkillWorkspace(context, fallbackWorkspace) {
6147
+ const workspaceInput = firstWorkspaceValue(context) ?? nonEmptyString(fallbackWorkspace);
6148
+ if (!workspaceInput) {
6149
+ throw new FreeSkillWorkspaceError(
6150
+ "WORKSPACE_MISSING",
6151
+ "\u672A\u63D0\u4F9B\u5F53\u524D Agent workspace"
6152
+ );
6153
+ }
6154
+ const workspacePath = await resolveWorkspacePath(workspaceInput);
6155
+ const directoryPath = await resolvePlatformDirectory(workspacePath);
6156
+ return {
6157
+ agentId: firstAgentIdValue(context),
6158
+ workspacePath,
6159
+ directoryPath,
6160
+ workspaceRelativePath: FREE_SKILL_DIRECTORY_NAME2
6161
+ };
6162
+ }
6163
+
6164
+ // src/free-skill-writer.ts
6165
+ var FREE_SKILL_DIRECTORY_NAME3 = ".xg-platform";
6166
+ var SKILL_FILE_NAME2 = "SKILL.md";
6167
+ var FreeSkillWriterError = class extends Error {
6168
+ code;
6169
+ constructor(code, message, options) {
6170
+ super(message, options);
6171
+ this.code = code;
6172
+ this.name = "FreeSkillWriterError";
6173
+ }
6174
+ };
6175
+ var defaultFileSystem = {
6176
+ lstat: fs11.lstat,
6177
+ realpath: fs11.realpath,
6178
+ stat: fs11.stat,
6179
+ mkdir: fs11.mkdir,
6180
+ writeFile: fs11.writeFile,
6181
+ rename: fs11.rename,
6182
+ rm: fs11.rm
6183
+ };
6184
+ function isRecord3(value) {
6185
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6186
+ }
6187
+ function isWithin3(parent, candidate) {
6188
+ const relative = path13.relative(parent, candidate);
6189
+ return relative === "" || !relative.startsWith(`..${path13.sep}`) && relative !== ".." && !path13.isAbsolute(relative);
6190
+ }
6191
+ function asErrnoCode(error) {
6192
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
6193
+ }
6194
+ function asMessage(error) {
6195
+ return error instanceof Error ? error.message : String(error);
6196
+ }
6197
+ function fail(code, message) {
6198
+ throw new FreeSkillWriterError(code, message);
6199
+ }
6200
+ function stripYamlComment(value) {
6201
+ let quote;
6202
+ for (let index = 0; index < value.length; index += 1) {
6203
+ const character = value[index];
6204
+ if (quote === '"' && character === "\\") {
6205
+ index += 1;
6206
+ continue;
6207
+ }
6208
+ if ((character === "'" || character === '"') && (!quote || quote === character)) {
6209
+ if (quote === "'" && character === "'" && value[index + 1] === "'") {
6210
+ index += 1;
6211
+ continue;
6212
+ }
6213
+ quote = quote ? void 0 : character;
6214
+ continue;
6215
+ }
6216
+ if (!quote && character === "#" && (index === 0 || /\s/.test(value[index - 1]))) {
6217
+ return value.slice(0, index).trimEnd();
6218
+ }
6219
+ }
6220
+ return value.trim();
6221
+ }
6222
+ function parseQuotedScalar(rawValue) {
6223
+ if (rawValue.startsWith('"')) {
6224
+ if (!rawValue.endsWith('"')) return void 0;
6225
+ try {
6226
+ const parsed = JSON.parse(rawValue);
6227
+ return typeof parsed === "string" ? parsed : void 0;
6228
+ } catch {
6229
+ return void 0;
6230
+ }
6231
+ }
6232
+ if (rawValue.startsWith("'")) {
6233
+ if (!rawValue.endsWith("'")) return void 0;
6234
+ const inner = rawValue.slice(1, -1);
6235
+ let value = "";
6236
+ for (let index = 0; index < inner.length; index += 1) {
6237
+ if (inner[index] === "'" && inner[index + 1] === "'") {
6238
+ value += "'";
6239
+ index += 1;
6240
+ } else if (inner[index] === "'") {
6241
+ return void 0;
6242
+ } else {
6243
+ value += inner[index];
6244
+ }
6245
+ }
6246
+ return value;
6247
+ }
6248
+ return void 0;
6249
+ }
6250
+ function hasBalancedCollection(value) {
6251
+ const opening = value[0];
6252
+ const closing = opening === "[" ? "]" : "}";
6253
+ if (opening !== "[" && opening !== "{" || !value.endsWith(closing)) return false;
6254
+ let depth = 0;
6255
+ let quote;
6256
+ for (let index = 0; index < value.length; index += 1) {
6257
+ const character = value[index];
6258
+ if (quote === '"' && character === "\\") {
6259
+ index += 1;
6260
+ continue;
6261
+ }
6262
+ if ((character === "'" || character === '"') && (!quote || quote === character)) {
6263
+ if (quote === "'" && character === "'" && value[index + 1] === "'") {
6264
+ index += 1;
6265
+ continue;
6266
+ }
6267
+ quote = quote ? void 0 : character;
6268
+ continue;
6269
+ }
6270
+ if (quote) continue;
6271
+ if (character === opening) depth += 1;
6272
+ if (character === closing) depth -= 1;
6273
+ if (depth < 0) return false;
6274
+ }
6275
+ return depth === 0 && !quote;
6276
+ }
6277
+ function parseInlineValue(rawValue) {
6278
+ const value = stripYamlComment(rawValue);
6279
+ if (value.startsWith('"') || value.startsWith("'")) {
6280
+ const parsed = parseQuotedScalar(value);
6281
+ if (parsed === void 0) fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u4E2D\u5B58\u5728\u672A\u95ED\u5408\u6216\u65E0\u6548\u5B57\u7B26\u4E32");
6282
+ return { kind: "scalar", value: parsed };
6283
+ }
6284
+ if (value.startsWith("[") || value.startsWith("{")) {
6285
+ if (!hasBalancedCollection(value)) {
6286
+ fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u4E2D\u5B58\u5728\u672A\u95ED\u5408\u96C6\u5408\u503C");
6287
+ }
6288
+ return { kind: "other" };
6289
+ }
6290
+ return { kind: "scalar", value };
6291
+ }
6292
+ function parseBlockValue(lines, startIndex, header) {
6293
+ const headerMatch = /^([|>])(?:[+-]|[1-9])?$/.exec(header);
6294
+ if (!headerMatch) fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u4E2D\u5B58\u5728\u65E0\u6548\u5757\u6807\u91CF");
6295
+ const blockLines = [];
6296
+ let index = startIndex;
6297
+ let contentIndent;
6298
+ while (index < lines.length) {
6299
+ const line = lines[index];
6300
+ if (line.trim() !== "" && !/^\s+/.test(line)) break;
6301
+ if (line.trim() === "") {
6302
+ blockLines.push("");
6303
+ index += 1;
6304
+ continue;
6305
+ }
6306
+ const indent = line.match(/^\s*/)?.[0].length ?? 0;
6307
+ contentIndent ??= indent;
6308
+ if (indent < contentIndent) break;
6309
+ blockLines.push(line.slice(contentIndent));
6310
+ index += 1;
6311
+ }
6312
+ if (headerMatch[1] === ">") {
6313
+ const folded = [];
6314
+ for (const line of blockLines) {
6315
+ if (line === "") {
6316
+ folded.push("\n");
6317
+ } else if (folded.length > 0 && folded[folded.length - 1] !== "\n") {
6318
+ folded.push(" ", line);
6319
+ } else {
6320
+ folded.push(line);
6321
+ }
6322
+ }
6323
+ return { value: folded.join(""), nextIndex: index };
6324
+ }
6325
+ return { value: blockLines.join("\n"), nextIndex: index };
6326
+ }
6327
+ function parseFrontmatter2(content) {
6328
+ const normalized = content.replace(/^\uFEFF/, "");
6329
+ const lines = normalized.split(/\r?\n/);
6330
+ if (lines[0]?.trim() !== "---") {
6331
+ fail("INVALID_FRONTMATTER", "SKILL.md \u5FC5\u987B\u4EE5 YAML frontmatter \u5F00\u59CB");
6332
+ }
6333
+ const fields = /* @__PURE__ */ new Map();
6334
+ let closingIndex = -1;
6335
+ let index = 1;
6336
+ while (index < lines.length) {
6337
+ const line = lines[index];
6338
+ const trimmed = line.trim();
6339
+ if (trimmed === "---" || trimmed === "...") {
6340
+ closingIndex = index;
6341
+ break;
6342
+ }
6343
+ if (trimmed === "" || trimmed.startsWith("#")) {
6344
+ index += 1;
6345
+ continue;
6346
+ }
6347
+ if (/^\s/.test(line) || line.includes(" ")) {
6348
+ fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u4E2D\u5B58\u5728\u65E0\u6548\u7F29\u8FDB");
6349
+ }
6350
+ const match2 = /^([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*?)\s*$/.exec(line);
6351
+ if (!match2) fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u4E2D\u5B58\u5728\u65E0\u6548\u5B57\u6BB5");
6352
+ const [, key, rawValue] = match2;
6353
+ if (fields.has(key)) fail("INVALID_FRONTMATTER", `SKILL.md frontmatter \u5B57\u6BB5\u91CD\u590D: ${key}`);
6354
+ const value = stripYamlComment(rawValue);
6355
+ if (value === "|" || value === ">" || /^[|>][+-]$/.test(value)) {
6356
+ const block = parseBlockValue(lines, index + 1, value);
6357
+ fields.set(key, { kind: "scalar", value: block.value });
6358
+ index = block.nextIndex;
6359
+ continue;
6360
+ }
6361
+ fields.set(key, parseInlineValue(rawValue));
6362
+ index += 1;
6363
+ }
6364
+ if (closingIndex < 0) fail("INVALID_FRONTMATTER", "SKILL.md frontmatter \u7F3A\u5C11\u7ED3\u675F\u6807\u8BB0");
6365
+ const name = fields.get("name");
6366
+ if (!name || name.kind !== "scalar" || !name.value.trim()) {
6367
+ fail("MISSING_NAME", "SKILL.md frontmatter \u5FC5\u987B\u5305\u542B\u975E\u7A7A name");
6368
+ }
6369
+ const description = fields.get("description");
6370
+ if (!description || description.kind !== "scalar" || !description.value.trim()) {
6371
+ fail("MISSING_DESCRIPTION", "SKILL.md frontmatter \u5FC5\u987B\u5305\u542B\u975E\u7A7A description");
6372
+ }
6373
+ const body = lines.slice(closingIndex + 1).join("\n");
6374
+ if (!body.trim()) fail("EMPTY_BODY", "SKILL.md \u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A");
6375
+ return { name: name.value.trim(), description: description.value.trim(), body };
6376
+ }
6377
+ function validateFreeSkillContent(content) {
6378
+ if (typeof content !== "string") fail("INVALID_CONTENT", "SKILL.md \u5185\u5BB9\u5FC5\u987B\u662F\u5B57\u7B26\u4E32");
6379
+ return parseFrontmatter2(content);
6380
+ }
6381
+ function validateSkillName(value) {
6382
+ if (typeof value !== "string" || value.length === 0 || value !== value.trim()) {
6383
+ fail("INVALID_SKILL_NAME", "Skill \u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u7684\u5355\u7EA7\u76EE\u5F55\u540D");
6384
+ }
6385
+ if (value === "." || value === ".." || value.startsWith(".") || value.endsWith(".") || value.endsWith(" ") || path13.basename(value) !== value || path13.win32.basename(value) !== value || path13.isAbsolute(value) || /[\\/\0<>:"|?*\u0000-\u001f\u007f]/u.test(value)) {
6386
+ fail("INVALID_SKILL_NAME", `\u975E\u6CD5\u7684 Skill \u540D\u79F0: ${value}`);
6387
+ }
6388
+ return value;
6389
+ }
6390
+ function serializeMetadata(value) {
6391
+ if (value === void 0) return void 0;
6392
+ if (!isRecord3(value)) fail("INVALID_METADATA", ".meta.json metadata \u5FC5\u987B\u662F JSON \u5BF9\u8C61");
6393
+ try {
6394
+ const serialized = JSON.stringify(value, null, 2);
6395
+ if (serialized === void 0) fail("INVALID_METADATA", ".meta.json metadata \u65E0\u6CD5\u5E8F\u5217\u5316");
6396
+ return `${serialized}
6397
+ `;
6398
+ } catch (error) {
6399
+ fail("INVALID_METADATA", `.meta.json metadata \u65E0\u6CD5\u5E8F\u5217\u5316: ${asMessage(error)}`);
6400
+ }
6401
+ }
6402
+ function isResolvedWorkspace(value) {
6403
+ if (!isRecord3(value)) return false;
6404
+ return typeof value.workspacePath === "string" && typeof value.directoryPath === "string" && value.workspaceRelativePath === FREE_SKILL_DIRECTORY_NAME3;
6405
+ }
6406
+ async function ensurePlatformDirectory(workspace, io) {
6407
+ if (!path13.isAbsolute(workspace.workspacePath) || !path13.isAbsolute(workspace.directoryPath)) {
6408
+ fail("TARGET_ESCAPE", "Skill workspace \u8DEF\u5F84\u5FC5\u987B\u662F\u89E3\u6790\u5668\u8FD4\u56DE\u7684\u7EDD\u5BF9\u8DEF\u5F84");
6409
+ }
6410
+ let workspacePath;
6411
+ try {
6412
+ workspacePath = await io.realpath(path13.resolve(workspace.workspacePath));
6413
+ const workspaceStat = await io.stat(workspacePath);
6414
+ if (!workspaceStat.isDirectory()) fail("WORKSPACE_NOT_DIRECTORY", "Agent workspace \u4E0D\u662F\u76EE\u5F55");
6415
+ } catch (error) {
6416
+ if (error instanceof FreeSkillWriterError) throw error;
6417
+ fail("WORKSPACE_MISSING", `Agent workspace \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${asMessage(error)}`);
6418
+ }
6419
+ const directoryPath = path13.resolve(workspacePath, FREE_SKILL_DIRECTORY_NAME3);
6420
+ if (!isWithin3(workspacePath, directoryPath) || path13.resolve(workspace.directoryPath) !== directoryPath) {
6421
+ fail("TARGET_ESCAPE", "\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55\u5FC5\u987B\u662F workspace/.xg-platform");
6422
+ }
6423
+ let entry;
6424
+ try {
6425
+ entry = await io.lstat(directoryPath);
6426
+ } catch (error) {
6427
+ if (asErrnoCode(error) !== "ENOENT") {
6428
+ fail("TARGET_UNAVAILABLE", `\u65E0\u6CD5\u68C0\u67E5\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55: ${asMessage(error)}`);
6429
+ }
6430
+ try {
6431
+ await io.mkdir(directoryPath, { recursive: false });
6432
+ entry = await io.lstat(directoryPath);
6433
+ } catch (mkdirError) {
6434
+ if (asErrnoCode(mkdirError) !== "EEXIST") {
6435
+ fail("ATOMIC_WRITE_FAILED", `\u521B\u5EFA\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55\u5931\u8D25: ${asMessage(mkdirError)}`);
6436
+ }
6437
+ try {
6438
+ entry = await io.lstat(directoryPath);
6439
+ } catch (statError) {
6440
+ fail("TARGET_UNAVAILABLE", `\u65E0\u6CD5\u68C0\u67E5\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55: ${asMessage(statError)}`);
6441
+ }
6442
+ }
6443
+ }
6444
+ if (entry.isSymbolicLink()) fail("TARGET_SYMLINK", "\u62D2\u7EDD\u5199\u5165\u7B26\u53F7\u94FE\u63A5\u76EE\u6807\u76EE\u5F55");
6445
+ if (!entry.isDirectory()) fail("TARGET_NOT_DIRECTORY", "\u81EA\u7531 Skill \u76EE\u6807\u4E0D\u662F\u76EE\u5F55");
6446
+ let realDirectory;
6447
+ try {
6448
+ realDirectory = await io.realpath(directoryPath);
6449
+ } catch (error) {
6450
+ fail("TARGET_UNAVAILABLE", `\u65E0\u6CD5\u89E3\u6790\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55: ${asMessage(error)}`);
6451
+ }
6452
+ if (realDirectory !== directoryPath || !isWithin3(workspacePath, realDirectory)) {
6453
+ fail("TARGET_ESCAPE", "\u81EA\u7531 Skill \u76EE\u6807\u76EE\u5F55\u8D8A\u51FA Agent workspace");
6454
+ }
6455
+ return { workspacePath, directoryPath };
6456
+ }
6457
+ async function resolveWriterWorkspace(input, suppliedWorkspace, io) {
6458
+ let workspace;
6459
+ const candidate = suppliedWorkspace ?? input.workspace;
6460
+ if (isResolvedWorkspace(candidate)) {
6461
+ workspace = candidate;
6462
+ } else {
6463
+ const context = input.context ?? candidate ?? input;
6464
+ try {
6465
+ workspace = await resolveFreeSkillWorkspace(context);
6466
+ } catch (error) {
6467
+ if (error instanceof FreeSkillWorkspaceError) throw error;
6468
+ fail("WORKSPACE_MISSING", `\u65E0\u6CD5\u89E3\u6790 Agent workspace: ${asMessage(error)}`);
6469
+ }
6470
+ }
6471
+ return ensurePlatformDirectory(workspace, io);
6472
+ }
6473
+ function makeTemporaryPath(directoryPath, skillName, suffix) {
6474
+ return path13.join(
6475
+ directoryPath,
6476
+ `.${skillName}.${suffix}-${process.pid}-${Date.now()}-${crypto.randomUUID()}`
6477
+ );
6478
+ }
6479
+ async function removePath(io, target) {
6480
+ await io.rm(target, { recursive: true, force: true }).catch(() => void 0);
6481
+ }
6482
+ async function targetAlreadyExists(targetPath, io) {
6483
+ try {
6484
+ const entry = await io.lstat(targetPath);
6485
+ return entry.isSymbolicLink() ? "symlink" : "exists";
6486
+ } catch (error) {
6487
+ if (asErrnoCode(error) === "ENOENT") return "missing";
6488
+ fail("TARGET_UNAVAILABLE", `\u65E0\u6CD5\u68C0\u67E5 Skill \u76EE\u6807\u76EE\u5F55: ${asMessage(error)}`);
6489
+ }
6490
+ }
6491
+ async function writeFreeSkill(input, workspace, dependencies) {
6492
+ const io = {
6493
+ ...defaultFileSystem,
6494
+ ...dependencies?.fileSystem
6495
+ };
6496
+ try {
6497
+ if (!isRecord3(input)) fail("INVALID_CONTENT", "Skill \u5199\u5165\u8BF7\u6C42\u5FC5\u987B\u662F\u5BF9\u8C61");
6498
+ const skillName = validateSkillName(input.skillName ?? input.name);
6499
+ const content = input.content ?? input.skillContent;
6500
+ validateFreeSkillContent(content);
6501
+ const metadata = serializeMetadata(input.metadata);
6502
+ const { directoryPath: platformDirectoryPath } = await resolveWriterWorkspace(input, workspace, io);
6503
+ const targetDirectoryPath = path13.resolve(platformDirectoryPath, skillName);
6504
+ if (!isWithin3(platformDirectoryPath, targetDirectoryPath)) {
6505
+ fail("TARGET_ESCAPE", "Skill \u76EE\u6807\u76EE\u5F55\u8D8A\u51FA workspace/.xg-platform");
6506
+ }
6507
+ const existing = await targetAlreadyExists(targetDirectoryPath, io);
6508
+ if (existing === "symlink") fail("TARGET_SYMLINK", "\u62D2\u7EDD\u5199\u5165\u7B26\u53F7\u94FE\u63A5 Skill \u76EE\u5F55");
6509
+ if (existing === "exists") fail("SKILL_EXISTS", `Skill \u5DF2\u5B58\u5728: ${skillName}`);
6510
+ let createdTargetDirectory = false;
6511
+ let skillTempPath;
6512
+ let metadataTempPath;
6513
+ const skillFilePath = path13.join(targetDirectoryPath, SKILL_FILE_NAME2);
6514
+ const metadataFilePath = metadata ? path13.join(targetDirectoryPath, ".meta.json") : void 0;
6515
+ try {
6516
+ try {
6517
+ await io.mkdir(targetDirectoryPath, { recursive: false });
6518
+ createdTargetDirectory = true;
6519
+ } catch (error) {
6520
+ if (asErrnoCode(error) === "EEXIST") {
6521
+ const raced = await targetAlreadyExists(targetDirectoryPath, io);
6522
+ if (raced === "symlink") fail("TARGET_SYMLINK", "\u62D2\u7EDD\u5199\u5165\u7B26\u53F7\u94FE\u63A5 Skill \u76EE\u5F55");
6523
+ fail("SKILL_EXISTS", `Skill \u5DF2\u5B58\u5728: ${skillName}`);
6524
+ }
6525
+ fail("ATOMIC_WRITE_FAILED", `\u521B\u5EFA Skill \u76EE\u5F55\u5931\u8D25: ${asMessage(error)}`);
6526
+ }
6527
+ skillTempPath = makeTemporaryPath(targetDirectoryPath, skillName, "skill-md-tmp");
6528
+ await io.writeFile(skillTempPath, content, {
6529
+ encoding: "utf8",
6530
+ flag: "wx",
6531
+ mode: 384
6532
+ });
6533
+ await io.rename(skillTempPath, skillFilePath);
6534
+ skillTempPath = void 0;
6535
+ if (metadata && metadataFilePath) {
6536
+ metadataTempPath = makeTemporaryPath(targetDirectoryPath, skillName, "metadata-tmp");
6537
+ await io.writeFile(metadataTempPath, metadata, {
6538
+ encoding: "utf8",
6539
+ flag: "wx",
6540
+ mode: 384
6541
+ });
6542
+ await io.rename(metadataTempPath, metadataFilePath);
6543
+ metadataTempPath = void 0;
6544
+ }
6545
+ } catch (error) {
6546
+ if (error instanceof FreeSkillWriterError && error.code === "SKILL_EXISTS") throw error;
6547
+ await Promise.all([
6548
+ skillTempPath ? removePath(io, skillTempPath) : Promise.resolve(),
6549
+ metadataTempPath ? removePath(io, metadataTempPath) : Promise.resolve()
6550
+ ]);
6551
+ if (createdTargetDirectory) await removePath(io, targetDirectoryPath);
6552
+ if (error instanceof FreeSkillWriterError) throw error;
6553
+ fail("ATOMIC_WRITE_FAILED", `\u81EA\u7531 Skill \u539F\u5B50\u5199\u5165\u5931\u8D25: ${asMessage(error)}`);
6554
+ }
6555
+ return {
6556
+ success: true,
6557
+ skillName,
6558
+ directoryPath: targetDirectoryPath,
6559
+ skillFilePath,
6560
+ ...metadataFilePath ? { metadataFilePath } : {}
6561
+ };
6562
+ } catch (error) {
6563
+ if (error instanceof FreeSkillWriterError) {
6564
+ return { success: false, code: error.code, message: error.message };
6565
+ }
6566
+ if (error instanceof FreeSkillWorkspaceError) {
6567
+ return { success: false, code: error.code, message: error.message };
6568
+ }
6569
+ return { success: false, code: "ATOMIC_WRITE_FAILED", message: `\u81EA\u7531 Skill \u5199\u5165\u5931\u8D25: ${asMessage(error)}` };
6570
+ }
6571
+ }
6572
+ async function writeFreeSkillOrThrow(input, workspace, dependencies) {
6573
+ const result = await writeFreeSkill(input, workspace, dependencies);
6574
+ if (!result.success) throw new FreeSkillWriterError(result.code, result.message);
6575
+ return result;
6576
+ }
6577
+
6578
+ // src/free-skill-tool.ts
6579
+ var FREE_SKILL_TOOL_NAME = "skill_logger_create_free_skill";
6580
+ var parameters = {
6581
+ type: "object",
6582
+ additionalProperties: false,
6583
+ properties: {
6584
+ skillName: { type: "string", description: "\u81EA\u7531 Skill \u7684\u4E00\u7EA7\u76EE\u5F55\u540D" },
6585
+ content: { type: "string", description: "\u5B8C\u6574\u7684 SKILL.md \u5185\u5BB9" },
6586
+ metadata: { type: "object", description: "\u53EF\u9009\u7684 JSON \u5143\u6570\u636E" }
6587
+ },
6588
+ required: ["skillName", "content"]
6589
+ };
6590
+ function hasOwn(value, key) {
6591
+ return Object.prototype.hasOwnProperty.call(value, key);
6592
+ }
6593
+ function asInput(params) {
6594
+ if (hasOwn(params, "target") || hasOwn(params, "path")) {
6595
+ throw new FreeSkillWriterError(
6596
+ "INVALID_CONTENT",
6597
+ "\u81EA\u7531 Skill \u5DE5\u5177\u4E0D\u63A5\u53D7 target/path\uFF0C\u76EE\u6807\u8DEF\u5F84\u7531\u5F53\u524D Agent workspace \u51B3\u5B9A"
6598
+ );
6599
+ }
6600
+ return {
6601
+ skillName: params.skillName ?? params.name,
6602
+ content: params.content ?? params.skillContent,
6603
+ metadata: params.metadata
6604
+ };
6605
+ }
6606
+ function createFreeSkillToolFactory(context) {
6607
+ return {
6608
+ name: FREE_SKILL_TOOL_NAME,
6609
+ label: "Create free Skill",
6610
+ description: "Create a validated Skill in the current Agent workspace under .xg-platform. The target path is runtime controlled.",
6611
+ parameters,
6612
+ async execute(_toolCallId, params) {
6613
+ const workspace = await resolveFreeSkillWorkspace(context);
6614
+ const result = await writeFreeSkillOrThrow(asInput(params), workspace);
6615
+ const workspaceRelativePath = path14.posix.join(".xg-platform", result.skillName);
6616
+ const details = {
6617
+ success: true,
6618
+ skillName: result.skillName,
6619
+ workspaceRelativePath,
6620
+ directoryPath: result.directoryPath,
6621
+ skillFilePath: result.skillFilePath,
6622
+ ...workspace.agentId ? { agentId: workspace.agentId } : {}
6623
+ };
6624
+ return {
6625
+ content: [{ type: "text", text: `\u81EA\u7531 Skill \u5DF2\u5199\u5165 ${workspaceRelativePath}` }],
6626
+ details
6627
+ };
6628
+ }
6629
+ };
6630
+ }
6631
+
5116
6632
  // src/index.ts
5117
6633
  var wsClient;
5118
6634
  var RECONCILE_INTERVAL_MS = 3 * 60 * 1e3;
@@ -5129,11 +6645,14 @@ var definition = {
5129
6645
  name: "Skill Logger",
5130
6646
  description: "\u8FFD\u8E2A openclaw skill \u5185\u529F\u80FD\u70B9\uFF08\u811A\u672C/\u547D\u4EE4/\u5DE5\u5177/HTTP\uFF09\u4F7F\u7528\u4E0E\u62A5\u9519\uFF0C\u843D\u672C\u5730\u5E76\u6279\u91CF\u4E0A\u62A5",
5131
6647
  register(api) {
6648
+ if (typeof api.registerTool === "function") {
6649
+ api.registerTool(createFreeSkillToolFactory, { name: FREE_SKILL_TOOL_NAME });
6650
+ }
5132
6651
  let pkgVersion = "unknown";
5133
6652
  try {
5134
- const dir = path11.dirname(fileURLToPath2(import.meta.url));
5135
- const pkgPath = path11.join(dir, "..", "package.json");
5136
- const pkg = JSON.parse(fs9.readFileSync(pkgPath, "utf-8"));
6653
+ const dir = path15.dirname(fileURLToPath2(import.meta.url));
6654
+ const pkgPath = path15.join(dir, "..", "package.json");
6655
+ const pkg = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
5137
6656
  if (pkg.version) pkgVersion = pkg.version;
5138
6657
  } catch {
5139
6658
  }