zen-fs-config 0.5.21 → 0.5.24

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.mjs CHANGED
@@ -54,9 +54,11 @@ function createSerializerChain(custom) {
54
54
  };
55
55
  }
56
56
  function configKeyToFilePath(configPath) {
57
- const ext = getExtension(configPath);
58
- if (ext !== "") return configPath;
59
- return configPath.endsWith("/") ? configPath : `${configPath}.json`;
57
+ let p = configPath;
58
+ if (!p.startsWith("/")) p = "/" + p;
59
+ const ext = getExtension(p);
60
+ if (ext !== "") return p;
61
+ return p.endsWith("/") ? p : `${p}.json`;
60
62
  }
61
63
  function getExtension(path) {
62
64
  const lastSlash = path.lastIndexOf("/");
@@ -172,6 +174,20 @@ async function ensureParentDir(absolutePath) {
172
174
  }
173
175
 
174
176
  // src/adapters.ts
177
+ function toUint8Array(data) {
178
+ if (data instanceof Uint8Array) return data;
179
+ if (data instanceof ArrayBuffer) return new Uint8Array(data);
180
+ if (typeof data === "string") return new TextEncoder().encode(data);
181
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
182
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
183
+ }
184
+ return new Uint8Array(data);
185
+ }
186
+ function toString(data, encoding) {
187
+ if (typeof data === "string") return data;
188
+ const bytes = toUint8Array(data);
189
+ return new TextDecoder().decode(bytes);
190
+ }
175
191
  function backendToSyncableFS(backend, name) {
176
192
  const syncable = {
177
193
  async readdir(path) {
@@ -180,15 +196,9 @@ function backendToSyncableFS(backend, name) {
180
196
  async readFile(path, encoding) {
181
197
  const result = await backend.readFile(path, encoding);
182
198
  if (encoding) {
183
- if (typeof result === "string") return result;
184
- if (result instanceof Uint8Array) return new TextDecoder().decode(result);
185
- if (Buffer.isBuffer(result)) return result.toString(encoding);
186
- return String(result);
199
+ return toString(result, encoding);
187
200
  }
188
- if (typeof result === "string") return Buffer.from(result);
189
- if (result instanceof Uint8Array) return Buffer.from(result);
190
- if (Buffer.isBuffer(result)) return result;
191
- return Buffer.from(String(result));
201
+ return toUint8Array(result);
192
202
  },
193
203
  async writeFile(path, data) {
194
204
  return backend.writeFile(path, data);
@@ -409,20 +419,150 @@ function versionPathFor(configFilePath) {
409
419
  const versionFileName = fileName.startsWith(".") ? `${fileName}.version` : `.${fileName}.version`;
410
420
  return dir ? `${dir}/${versionFileName}` : versionFileName;
411
421
  }
422
+ function sha256PureJS(data) {
423
+ const K = new Uint32Array([
424
+ 1116352408,
425
+ 1899447441,
426
+ 3049323471,
427
+ 3921009573,
428
+ 961987163,
429
+ 1508970993,
430
+ 2453635748,
431
+ 2870763221,
432
+ 3624381080,
433
+ 310598401,
434
+ 607225278,
435
+ 1426881987,
436
+ 1925078388,
437
+ 2162078206,
438
+ 2614888103,
439
+ 3248222580,
440
+ 3835390401,
441
+ 4022224774,
442
+ 264347078,
443
+ 604807628,
444
+ 770255983,
445
+ 1249150122,
446
+ 1555081692,
447
+ 1996064986,
448
+ 2554220882,
449
+ 2821834349,
450
+ 2952996808,
451
+ 3210313671,
452
+ 3336571891,
453
+ 3584528711,
454
+ 113926993,
455
+ 338241895,
456
+ 666307205,
457
+ 773529912,
458
+ 1294757372,
459
+ 1396182291,
460
+ 1695183700,
461
+ 1986661051,
462
+ 2177026350,
463
+ 2456956037,
464
+ 2730485921,
465
+ 2820302411,
466
+ 3259730800,
467
+ 3345764771,
468
+ 3516065817,
469
+ 3600352804,
470
+ 4094571909,
471
+ 275423344,
472
+ 430227734,
473
+ 506948616,
474
+ 659060556,
475
+ 883997877,
476
+ 958139571,
477
+ 1322822218,
478
+ 1537002063,
479
+ 1747873779,
480
+ 1955562222,
481
+ 2024104815,
482
+ 2227730452,
483
+ 2361852424,
484
+ 2428436474,
485
+ 2756734187,
486
+ 3204031479,
487
+ 3329325298
488
+ ]);
489
+ const H = new Uint32Array([
490
+ 1779033703,
491
+ 3144134277,
492
+ 1013904242,
493
+ 2773480762,
494
+ 1359893119,
495
+ 2600822924,
496
+ 528734635,
497
+ 1541459225
498
+ ]);
499
+ const len = data.length;
500
+ const bitLen = len * 8;
501
+ const padLen = (len + 8 >> 6 << 6) + 64;
502
+ const buf = new Uint8Array(padLen);
503
+ buf.set(data);
504
+ buf[len] = 128;
505
+ const dv = new DataView(buf.buffer);
506
+ dv.setUint32(padLen - 4, bitLen >>> 0, false);
507
+ dv.setUint32(padLen - 8, Math.floor(bitLen / 4294967296) >>> 0, false);
508
+ const W = new Uint32Array(64);
509
+ for (let i = 0; i < padLen; i += 64) {
510
+ for (let t = 0; t < 16; t++) {
511
+ W[t] = dv.getUint32(i + t * 4, false);
512
+ }
513
+ for (let t = 16; t < 64; t++) {
514
+ const s0 = (W[t - 15] >>> 7 | W[t - 15] << 25) ^ (W[t - 15] >>> 18 | W[t - 15] << 14) ^ W[t - 15] >>> 3;
515
+ const s1 = (W[t - 2] >>> 17 | W[t - 2] << 15) ^ (W[t - 2] >>> 19 | W[t - 2] << 13) ^ W[t - 2] >>> 10;
516
+ W[t] = W[t - 16] + s0 + W[t - 7] + s1 >>> 0;
517
+ }
518
+ let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
519
+ for (let t = 0; t < 64; t++) {
520
+ const S1 = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);
521
+ const ch = e & f ^ ~e & g;
522
+ const temp1 = h + S1 + ch + K[t] + W[t] >>> 0;
523
+ const S0 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);
524
+ const maj = a & b ^ a & c ^ b & c;
525
+ const temp2 = S0 + maj >>> 0;
526
+ h = g;
527
+ g = f;
528
+ f = e;
529
+ e = d + temp1 >>> 0;
530
+ d = c;
531
+ c = b;
532
+ b = a;
533
+ a = temp1 + temp2 >>> 0;
534
+ }
535
+ H[0] = H[0] + a >>> 0;
536
+ H[1] = H[1] + b >>> 0;
537
+ H[2] = H[2] + c >>> 0;
538
+ H[3] = H[3] + d >>> 0;
539
+ H[4] = H[4] + e >>> 0;
540
+ H[5] = H[5] + f >>> 0;
541
+ H[6] = H[6] + g >>> 0;
542
+ H[7] = H[7] + h >>> 0;
543
+ }
544
+ const out = new Uint8Array(32);
545
+ const outDv = new DataView(out.buffer);
546
+ for (let i = 0; i < 8; i++) outDv.setUint32(i * 4, H[i], false);
547
+ return out;
548
+ }
412
549
  async function sha256(data) {
413
550
  const buffer = data.byteLength === data.buffer.byteLength ? data.buffer : data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
414
- if (typeof crypto !== "undefined" && typeof crypto.subtle?.digest === "function") {
415
- const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
551
+ const webCrypto = globalThis.crypto;
552
+ if (webCrypto && typeof webCrypto.subtle?.digest === "function") {
553
+ const hashBuffer = await webCrypto.subtle.digest("SHA-256", buffer);
416
554
  const hashArray = Array.from(new Uint8Array(hashBuffer));
417
- const hex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
418
- return `sha256:${hex}`;
555
+ const hex2 = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
556
+ return `sha256:${hex2}`;
419
557
  }
420
558
  if (typeof globalThis.window === "undefined") {
421
559
  const nodeCrypto = await new Function("return import('node:crypto')")();
422
560
  const hash = nodeCrypto.createHash("sha256").update(Buffer.from(buffer)).digest("hex");
423
561
  return `sha256:${hash}`;
424
562
  }
425
- throw new Error("SHA-256 not available: neither Web Crypto nor Node.js crypto module found");
563
+ const digest = sha256PureJS(data);
564
+ const hex = Array.from(digest).map((b) => b.toString(16).padStart(2, "0")).join("");
565
+ return `sha256:${hex}`;
426
566
  }
427
567
  async function readVersion(fs, versionFilePath) {
428
568
  try {
@@ -463,7 +603,7 @@ async function verifyOrRepairVersion(fs, configFilePath, author) {
463
603
  data = new TextEncoder().encode(content);
464
604
  } else if (content instanceof Uint8Array) {
465
605
  data = content;
466
- } else if (Buffer.isBuffer(content)) {
606
+ } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(content)) {
467
607
  data = new Uint8Array(content.buffer, content.byteOffset, content.byteLength);
468
608
  } else {
469
609
  data = new Uint8Array(content);
@@ -614,7 +754,7 @@ var ConfigRepo = class {
614
754
  const fullPath = `${NODES_DIR}/${nodeId}${filePath}`;
615
755
  try {
616
756
  const raw = await this.cachedFS.readFile(fullPath);
617
- return this.serializer.deserialize(toUint8Array(raw), fullPath);
757
+ return this.serializer.deserialize(toUint8Array2(raw), fullPath);
618
758
  } catch {
619
759
  throw new Error(`Node config not found: ${nodeId}${path}`);
620
760
  }
@@ -691,7 +831,7 @@ var ConfigRepo = class {
691
831
  const fullPath = `${NODES_DIR}/${nodeId}${filePath}`;
692
832
  try {
693
833
  const raw = await this.cachedFS.readFile(fullPath);
694
- return this.serializer.deserialize(toUint8Array(raw), fullPath);
834
+ return this.serializer.deserialize(toUint8Array2(raw), fullPath);
695
835
  } catch {
696
836
  throw new Error(`Node config not found: ${nodeId}${path}`);
697
837
  }
@@ -785,7 +925,7 @@ var ConfigRepo = class {
785
925
  if (!entry.endsWith(".json")) continue;
786
926
  try {
787
927
  const raw = await this.cachedFS.readFile(`${DELETIONS_DIR}/${entry}`);
788
- const data = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
928
+ const data = JSON.parse(new TextDecoder().decode(toUint8Array2(raw)));
789
929
  tombstones.push(data);
790
930
  } catch {
791
931
  }
@@ -1028,7 +1168,7 @@ var ConfigRepo = class {
1028
1168
  try {
1029
1169
  const raw = await this.cachedFS.readFile(metaPath);
1030
1170
  const archive = JSON.parse(
1031
- new TextDecoder().decode(toUint8Array(raw))
1171
+ new TextDecoder().decode(toUint8Array2(raw))
1032
1172
  );
1033
1173
  const configPath = archive.conflictPath;
1034
1174
  const bytes = this.serializer.serialize(mergedContent, configPath);
@@ -1064,7 +1204,7 @@ var ConfigRepo = class {
1064
1204
  try {
1065
1205
  const raw = await this.cachedFS.readFile(metaPath);
1066
1206
  const archive = JSON.parse(
1067
- new TextDecoder().decode(toUint8Array(raw))
1207
+ new TextDecoder().decode(toUint8Array2(raw))
1068
1208
  );
1069
1209
  archives.push(archive);
1070
1210
  } catch {
@@ -1079,7 +1219,7 @@ var ConfigRepo = class {
1079
1219
  const conflictDir = `${CONFLICTS_DIR}/${conflictId}`.replace(/\/meta\.json$/, "");
1080
1220
  const filePath = `${conflictDir}/${fileType}`;
1081
1221
  const raw = await this.cachedFS.readFile(filePath);
1082
- return new TextDecoder().decode(toUint8Array(raw));
1222
+ return new TextDecoder().decode(toUint8Array2(raw));
1083
1223
  }
1084
1224
  // -----------------------------------------------------------------------
1085
1225
  // IConfigRepo — Lifecycle
@@ -1210,7 +1350,7 @@ var ConfigRepo = class {
1210
1350
  files.map(async (filePath) => {
1211
1351
  try {
1212
1352
  const raw = await this.cachedFS.readFile(filePath);
1213
- const data = this.serializer.deserialize(toUint8Array(raw), filePath);
1353
+ const data = this.serializer.deserialize(toUint8Array2(raw), filePath);
1214
1354
  return { filePath, data };
1215
1355
  } catch {
1216
1356
  return null;
@@ -1340,7 +1480,7 @@ var ConfigRepo = class {
1340
1480
  async readMetaFile(path) {
1341
1481
  try {
1342
1482
  const raw = await this.cachedFS.readFile(path);
1343
- return JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
1483
+ return JSON.parse(new TextDecoder().decode(toUint8Array2(raw)));
1344
1484
  } catch {
1345
1485
  return null;
1346
1486
  }
@@ -1368,7 +1508,7 @@ var ConfigRepo = class {
1368
1508
  const filePath = `${BACKENDS_DIR}/${entry}`;
1369
1509
  try {
1370
1510
  const raw = await this.cachedFS.readFile(filePath);
1371
- const desc = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
1511
+ const desc = JSON.parse(new TextDecoder().decode(toUint8Array2(raw)));
1372
1512
  if (desc.id && desc.type) {
1373
1513
  let mtime = 0;
1374
1514
  try {
@@ -1703,7 +1843,7 @@ var ConfigRepo = class {
1703
1843
  const descPath = this.appDataGroupFilePath(id);
1704
1844
  try {
1705
1845
  const raw = await this.cachedFS.readFile(descPath);
1706
- const descriptor = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
1846
+ const descriptor = JSON.parse(new TextDecoder().decode(toUint8Array2(raw)));
1707
1847
  const group = new AppDataGroupImpl(
1708
1848
  id,
1709
1849
  this.appId,
@@ -1727,7 +1867,7 @@ var ConfigRepo = class {
1727
1867
  if (!entry.endsWith(".json")) continue;
1728
1868
  try {
1729
1869
  const raw = await this.cachedFS.readFile(`${dir}/${entry}`);
1730
- const desc = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
1870
+ const desc = JSON.parse(new TextDecoder().decode(toUint8Array2(raw)));
1731
1871
  if (desc.id && desc.groupType === "data-sync") {
1732
1872
  descriptors.push(desc);
1733
1873
  }
@@ -1893,11 +2033,13 @@ var AppDataGroupImpl = class {
1893
2033
  this.dataBackends.clear();
1894
2034
  }
1895
2035
  };
1896
- function toUint8Array(raw) {
2036
+ function toUint8Array2(raw) {
1897
2037
  if (raw instanceof ArrayBuffer) return new Uint8Array(raw);
1898
2038
  if (raw instanceof Uint8Array) return raw;
1899
2039
  if (typeof raw === "string") return new TextEncoder().encode(raw);
1900
- if (Buffer.isBuffer(raw)) return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
2040
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(raw)) {
2041
+ return new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
2042
+ }
1901
2043
  return new Uint8Array(raw);
1902
2044
  }
1903
2045
  async function createConfigRepo(appId, options = {}) {