resourcexjs 2.5.0 → 2.5.2

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
@@ -43,15 +43,16 @@ function define(input) {
43
43
  if (!obj.type || typeof obj.type !== "string") {
44
44
  throw new DefinitionError("type is required");
45
45
  }
46
- if (!obj.version || typeof obj.version !== "string") {
47
- throw new DefinitionError("version is required");
46
+ const tagValue = obj.tag ?? obj.version;
47
+ if (tagValue !== undefined && typeof tagValue !== "string") {
48
+ throw new DefinitionError("tag must be a string");
48
49
  }
49
50
  const rxd = {
50
51
  ...obj,
51
52
  name: obj.name,
52
53
  type: obj.type,
53
- version: obj.version,
54
- domain: typeof obj.domain === "string" ? obj.domain : "localhost",
54
+ tag: typeof tagValue === "string" ? tagValue : undefined,
55
+ registry: typeof obj.registry === "string" ? obj.registry : undefined,
55
56
  path: typeof obj.path === "string" ? obj.path : undefined,
56
57
  description: typeof obj.description === "string" ? obj.description : undefined,
57
58
  author: typeof obj.author === "string" ? obj.author : undefined,
@@ -63,11 +64,11 @@ function define(input) {
63
64
  }
64
65
  function manifest(rxd) {
65
66
  return {
66
- domain: rxd.domain,
67
+ registry: rxd.registry,
67
68
  path: rxd.path,
68
69
  name: rxd.name,
69
70
  type: rxd.type,
70
- version: rxd.version
71
+ tag: rxd.tag ?? "latest"
71
72
  };
72
73
  }
73
74
  function writeString(view, offset, size, value) {
@@ -987,11 +988,10 @@ async function archive(files2) {
987
988
  }
988
989
  function locate(rxm) {
989
990
  return {
990
- domain: rxm.domain,
991
+ registry: rxm.registry,
991
992
  path: rxm.path,
992
993
  name: rxm.name,
993
- type: rxm.type,
994
- version: rxm.version
994
+ tag: rxm.tag
995
995
  };
996
996
  }
997
997
  function resource(rxm, rxa) {
@@ -1015,56 +1015,85 @@ async function extract(rxa) {
1015
1015
  return files2;
1016
1016
  }
1017
1017
  function format(rxl) {
1018
- let result = rxl.domain + "/";
1018
+ let result = "";
1019
+ if (rxl.registry) {
1020
+ result += rxl.registry + "/";
1021
+ }
1019
1022
  if (rxl.path) {
1020
1023
  result += rxl.path + "/";
1021
1024
  }
1022
1025
  result += rxl.name;
1023
- result += "." + rxl.type;
1024
- result += "@" + rxl.version;
1026
+ if (rxl.tag && rxl.tag !== "latest") {
1027
+ result += ":" + rxl.tag;
1028
+ }
1025
1029
  return result;
1026
1030
  }
1031
+ function looksLikeRegistry(str) {
1032
+ if (str.includes(":") && !str.includes("/")) {
1033
+ return true;
1034
+ }
1035
+ if (str.includes(".")) {
1036
+ return true;
1037
+ }
1038
+ if (str === "localhost") {
1039
+ return true;
1040
+ }
1041
+ return false;
1042
+ }
1027
1043
  function parse(locator) {
1028
1044
  if (!locator || typeof locator !== "string") {
1029
- throw new LocatorError("locator must be a non-empty string", locator);
1045
+ throw new LocatorError("Locator must be a non-empty string", locator);
1030
1046
  }
1031
- const atIndex = locator.lastIndexOf("@");
1032
- if (atIndex === -1) {
1033
- throw new LocatorError("locator must contain version (@)", locator);
1047
+ if (locator.includes("@")) {
1048
+ throw new LocatorError("Invalid locator format. Use name:tag instead of name@version", locator);
1034
1049
  }
1035
- const version = locator.slice(atIndex + 1);
1036
- const beforeVersion = locator.slice(0, atIndex);
1037
- if (!version) {
1038
- throw new LocatorError("version is required", locator);
1050
+ const lastSlashIndex = locator.lastIndexOf("/");
1051
+ let beforeSlash = "";
1052
+ let afterSlash = locator;
1053
+ if (lastSlashIndex !== -1) {
1054
+ beforeSlash = locator.substring(0, lastSlashIndex);
1055
+ afterSlash = locator.substring(lastSlashIndex + 1);
1039
1056
  }
1040
- const dotIndex = beforeVersion.lastIndexOf(".");
1041
- if (dotIndex === -1) {
1042
- throw new LocatorError("locator must contain type (.)", locator);
1057
+ const colonIndex = afterSlash.lastIndexOf(":");
1058
+ let name;
1059
+ let tag;
1060
+ if (colonIndex === -1) {
1061
+ name = afterSlash;
1062
+ tag = "latest";
1063
+ } else {
1064
+ name = afterSlash.substring(0, colonIndex);
1065
+ tag = afterSlash.substring(colonIndex + 1);
1043
1066
  }
1044
- const type = beforeVersion.slice(dotIndex + 1);
1045
- const beforeType = beforeVersion.slice(0, dotIndex);
1046
- if (!type) {
1047
- throw new LocatorError("type is required", locator);
1067
+ if (!name) {
1068
+ throw new LocatorError("Name is required", locator);
1048
1069
  }
1049
- const parts = beforeType.split("/");
1050
- if (parts.length < 2) {
1051
- throw new LocatorError("locator must contain domain", locator);
1070
+ if (!tag) {
1071
+ throw new LocatorError("Tag cannot be empty. Use name:tag format or omit tag for :latest", locator);
1052
1072
  }
1053
- const domain = parts[0];
1054
- const name = parts[parts.length - 1];
1055
- const path = parts.length > 2 ? parts.slice(1, -1).join("/") : undefined;
1056
- if (!domain) {
1057
- throw new LocatorError("domain is required", locator);
1073
+ if (lastSlashIndex === -1) {
1074
+ return {
1075
+ registry: undefined,
1076
+ path: undefined,
1077
+ name,
1078
+ tag
1079
+ };
1058
1080
  }
1059
- if (!name) {
1060
- throw new LocatorError("name is required", locator);
1081
+ const parts = beforeSlash.split("/");
1082
+ if (looksLikeRegistry(parts[0])) {
1083
+ const registry = parts[0];
1084
+ const path = parts.length > 1 ? parts.slice(1).join("/") : undefined;
1085
+ return {
1086
+ registry,
1087
+ path,
1088
+ name,
1089
+ tag
1090
+ };
1061
1091
  }
1062
1092
  return {
1063
- domain,
1064
- path,
1093
+ registry: undefined,
1094
+ path: beforeSlash,
1065
1095
  name,
1066
- type,
1067
- version
1096
+ tag
1068
1097
  };
1069
1098
  }
1070
1099
 
@@ -16971,11 +17000,10 @@ var EOF_BUFFER3 = new Uint8Array(BLOCK_SIZE3 * 2);
16971
17000
  var gzipAsync3 = promisify5(gzip3);
16972
17001
  function locate2(rxm) {
16973
17002
  return {
16974
- domain: rxm.domain,
17003
+ registry: rxm.registry,
16975
17004
  path: rxm.path,
16976
17005
  name: rxm.name,
16977
- type: rxm.type,
16978
- version: rxm.version
17006
+ tag: rxm.tag
16979
17007
  };
16980
17008
  }
16981
17009
  function resource2(rxm, rxa) {
@@ -16988,56 +17016,85 @@ function resource2(rxm, rxa) {
16988
17016
  }
16989
17017
  var gunzipAsync3 = promisify23(gunzip3);
16990
17018
  function format2(rxl) {
16991
- let result = rxl.domain + "/";
17019
+ let result = "";
17020
+ if (rxl.registry) {
17021
+ result += rxl.registry + "/";
17022
+ }
16992
17023
  if (rxl.path) {
16993
17024
  result += rxl.path + "/";
16994
17025
  }
16995
17026
  result += rxl.name;
16996
- result += "." + rxl.type;
16997
- result += "@" + rxl.version;
17027
+ if (rxl.tag && rxl.tag !== "latest") {
17028
+ result += ":" + rxl.tag;
17029
+ }
16998
17030
  return result;
16999
17031
  }
17032
+ function looksLikeRegistry2(str) {
17033
+ if (str.includes(":") && !str.includes("/")) {
17034
+ return true;
17035
+ }
17036
+ if (str.includes(".")) {
17037
+ return true;
17038
+ }
17039
+ if (str === "localhost") {
17040
+ return true;
17041
+ }
17042
+ return false;
17043
+ }
17000
17044
  function parse2(locator) {
17001
17045
  if (!locator || typeof locator !== "string") {
17002
- throw new LocatorError2("locator must be a non-empty string", locator);
17046
+ throw new LocatorError2("Locator must be a non-empty string", locator);
17003
17047
  }
17004
- const atIndex = locator.lastIndexOf("@");
17005
- if (atIndex === -1) {
17006
- throw new LocatorError2("locator must contain version (@)", locator);
17048
+ if (locator.includes("@")) {
17049
+ throw new LocatorError2("Invalid locator format. Use name:tag instead of name@version", locator);
17007
17050
  }
17008
- const version = locator.slice(atIndex + 1);
17009
- const beforeVersion = locator.slice(0, atIndex);
17010
- if (!version) {
17011
- throw new LocatorError2("version is required", locator);
17051
+ const lastSlashIndex = locator.lastIndexOf("/");
17052
+ let beforeSlash = "";
17053
+ let afterSlash = locator;
17054
+ if (lastSlashIndex !== -1) {
17055
+ beforeSlash = locator.substring(0, lastSlashIndex);
17056
+ afterSlash = locator.substring(lastSlashIndex + 1);
17012
17057
  }
17013
- const dotIndex = beforeVersion.lastIndexOf(".");
17014
- if (dotIndex === -1) {
17015
- throw new LocatorError2("locator must contain type (.)", locator);
17058
+ const colonIndex = afterSlash.lastIndexOf(":");
17059
+ let name;
17060
+ let tag;
17061
+ if (colonIndex === -1) {
17062
+ name = afterSlash;
17063
+ tag = "latest";
17064
+ } else {
17065
+ name = afterSlash.substring(0, colonIndex);
17066
+ tag = afterSlash.substring(colonIndex + 1);
17016
17067
  }
17017
- const type = beforeVersion.slice(dotIndex + 1);
17018
- const beforeType = beforeVersion.slice(0, dotIndex);
17019
- if (!type) {
17020
- throw new LocatorError2("type is required", locator);
17068
+ if (!name) {
17069
+ throw new LocatorError2("Name is required", locator);
17021
17070
  }
17022
- const parts = beforeType.split("/");
17023
- if (parts.length < 2) {
17024
- throw new LocatorError2("locator must contain domain", locator);
17071
+ if (!tag) {
17072
+ throw new LocatorError2("Tag cannot be empty. Use name:tag format or omit tag for :latest", locator);
17025
17073
  }
17026
- const domain = parts[0];
17027
- const name = parts[parts.length - 1];
17028
- const path = parts.length > 2 ? parts.slice(1, -1).join("/") : undefined;
17029
- if (!domain) {
17030
- throw new LocatorError2("domain is required", locator);
17074
+ if (lastSlashIndex === -1) {
17075
+ return {
17076
+ registry: undefined,
17077
+ path: undefined,
17078
+ name,
17079
+ tag
17080
+ };
17031
17081
  }
17032
- if (!name) {
17033
- throw new LocatorError2("name is required", locator);
17082
+ const parts = beforeSlash.split("/");
17083
+ if (looksLikeRegistry2(parts[0])) {
17084
+ const registry = parts[0];
17085
+ const path = parts.length > 1 ? parts.slice(1).join("/") : undefined;
17086
+ return {
17087
+ registry,
17088
+ path,
17089
+ name,
17090
+ tag
17091
+ };
17034
17092
  }
17035
17093
  return {
17036
- domain,
17037
- path,
17094
+ registry: undefined,
17095
+ path: beforeSlash,
17038
17096
  name,
17039
- type,
17040
- version
17097
+ tag
17041
17098
  };
17042
17099
  }
17043
17100
 
@@ -17070,20 +17127,18 @@ class RegistryError extends ResourceXError3 {
17070
17127
  }
17071
17128
  }
17072
17129
 
17073
- class HostedRegistry {
17130
+ class LocalRegistry {
17074
17131
  storage;
17075
17132
  constructor(storage) {
17076
17133
  this.storage = storage;
17077
17134
  }
17078
17135
  buildKeyPrefix(rxl) {
17079
- const domain = rxl.domain ?? "localhost";
17080
- const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
17081
- const version = rxl.version ?? "latest";
17082
- let key = domain;
17136
+ const tag = rxl.tag ?? "latest";
17137
+ let key = rxl.name;
17083
17138
  if (rxl.path) {
17084
- key += `/${rxl.path}`;
17139
+ key = `${rxl.path}/${key}`;
17085
17140
  }
17086
- key += `/${resourceName}/${version}`;
17141
+ key += `/${tag}`;
17087
17142
  return key;
17088
17143
  }
17089
17144
  async get(rxl) {
@@ -17098,11 +17153,11 @@ class HostedRegistry {
17098
17153
  }
17099
17154
  const manifestJson = JSON.parse(manifestData.toString("utf-8"));
17100
17155
  const rxm = {
17101
- domain: manifestJson.domain,
17156
+ registry: manifestJson.registry,
17102
17157
  path: manifestJson.path,
17103
17158
  name: manifestJson.name,
17104
17159
  type: manifestJson.type,
17105
- version: manifestJson.version,
17160
+ tag: manifestJson.tag,
17106
17161
  files: manifestJson.files
17107
17162
  };
17108
17163
  const archiveData = await this.storage.get(archiveKey);
@@ -17114,11 +17169,11 @@ class HostedRegistry {
17114
17169
  const manifestKey = `${prefix}/manifest.json`;
17115
17170
  const archiveKey = `${prefix}/archive.tar.gz`;
17116
17171
  const manifestJson = {
17117
- domain: rxr2.manifest.domain,
17172
+ registry: rxr2.manifest.registry,
17118
17173
  path: rxr2.manifest.path,
17119
17174
  name: rxr2.manifest.name,
17120
17175
  type: rxr2.manifest.type,
17121
- version: rxr2.manifest.version,
17176
+ tag: rxr2.manifest.tag,
17122
17177
  files: rxr2.manifest.files
17123
17178
  };
17124
17179
  const manifestData = Buffer.from(JSON.stringify(manifestJson, null, 2), "utf-8");
@@ -17151,7 +17206,7 @@ class HostedRegistry {
17151
17206
  if (query) {
17152
17207
  const lowerQuery = query.toLowerCase();
17153
17208
  filtered = locators.filter((rxl) => {
17154
- const searchText = `${rxl.domain ?? ""} ${rxl.path ?? ""} ${rxl.name} ${rxl.type ?? ""}`.toLowerCase();
17209
+ const searchText = `${rxl.path ?? ""} ${rxl.name}`.toLowerCase();
17155
17210
  return searchText.includes(lowerQuery);
17156
17211
  });
17157
17212
  }
@@ -17164,30 +17219,18 @@ class HostedRegistry {
17164
17219
  parseKeyToRXL(key) {
17165
17220
  const dirPath = key.replace(/\/manifest\.json$/, "");
17166
17221
  const parts = dirPath.split("/");
17167
- if (parts.length < 3) {
17222
+ if (parts.length < 2) {
17168
17223
  return null;
17169
17224
  }
17170
- const version = parts.pop();
17171
- const nameTypePart = parts.pop();
17172
- const domain = parts.shift();
17225
+ const tag = parts.pop();
17226
+ const name = parts.pop();
17173
17227
  const path = parts.length > 0 ? parts.join("/") : undefined;
17174
- const dotIndex = nameTypePart.lastIndexOf(".");
17175
- let name;
17176
- let type;
17177
- if (dotIndex !== -1) {
17178
- name = nameTypePart.substring(0, dotIndex);
17179
- type = nameTypePart.substring(dotIndex + 1);
17180
- } else {
17181
- name = nameTypePart;
17182
- type = undefined;
17183
- }
17184
- let locatorStr = domain;
17228
+ let locatorStr = "";
17185
17229
  if (path)
17186
- locatorStr += `/${path}`;
17187
- locatorStr += `/${name}`;
17188
- if (type)
17189
- locatorStr += `.${type}`;
17190
- locatorStr += `@${version}`;
17230
+ locatorStr += `${path}/`;
17231
+ locatorStr += name;
17232
+ if (tag !== "latest")
17233
+ locatorStr += `:${tag}`;
17191
17234
  try {
17192
17235
  return parse2(locatorStr);
17193
17236
  } catch {
@@ -17202,14 +17245,13 @@ class MirrorRegistry {
17202
17245
  this.storage = storage;
17203
17246
  }
17204
17247
  buildKeyPrefix(rxl) {
17205
- const domain = rxl.domain ?? "localhost";
17206
- const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
17207
- const version = rxl.version ?? "latest";
17208
- let key = domain;
17248
+ const registry = rxl.registry ?? "localhost";
17249
+ const tag = rxl.tag ?? "latest";
17250
+ let key = registry;
17209
17251
  if (rxl.path) {
17210
17252
  key += `/${rxl.path}`;
17211
17253
  }
17212
- key += `/${resourceName}/${version}`;
17254
+ key += `/${rxl.name}/${tag}`;
17213
17255
  return key;
17214
17256
  }
17215
17257
  async get(rxl) {
@@ -17224,11 +17266,11 @@ class MirrorRegistry {
17224
17266
  }
17225
17267
  const manifestJson = JSON.parse(manifestData.toString("utf-8"));
17226
17268
  const rxm = {
17227
- domain: manifestJson.domain,
17269
+ registry: manifestJson.registry,
17228
17270
  path: manifestJson.path,
17229
17271
  name: manifestJson.name,
17230
17272
  type: manifestJson.type,
17231
- version: manifestJson.version,
17273
+ tag: manifestJson.tag,
17232
17274
  files: manifestJson.files
17233
17275
  };
17234
17276
  const archiveData = await this.storage.get(archiveKey);
@@ -17240,11 +17282,11 @@ class MirrorRegistry {
17240
17282
  const manifestKey = `${prefix}/manifest.json`;
17241
17283
  const archiveKey = `${prefix}/archive.tar.gz`;
17242
17284
  const manifestJson = {
17243
- domain: rxr2.manifest.domain,
17285
+ registry: rxr2.manifest.registry,
17244
17286
  path: rxr2.manifest.path,
17245
17287
  name: rxr2.manifest.name,
17246
17288
  type: rxr2.manifest.type,
17247
- version: rxr2.manifest.version,
17289
+ tag: rxr2.manifest.tag,
17248
17290
  files: rxr2.manifest.files
17249
17291
  };
17250
17292
  const manifestData = Buffer.from(JSON.stringify(manifestJson, null, 2), "utf-8");
@@ -17277,7 +17319,7 @@ class MirrorRegistry {
17277
17319
  if (query) {
17278
17320
  const lowerQuery = query.toLowerCase();
17279
17321
  filtered = locators.filter((rxl) => {
17280
- const searchText = `${rxl.domain ?? ""} ${rxl.path ?? ""} ${rxl.name} ${rxl.type ?? ""}`.toLowerCase();
17322
+ const searchText = `${rxl.registry ?? ""} ${rxl.path ?? ""} ${rxl.name}`.toLowerCase();
17281
17323
  return searchText.includes(lowerQuery);
17282
17324
  });
17283
17325
  }
@@ -17287,22 +17329,22 @@ class MirrorRegistry {
17287
17329
  }
17288
17330
  return result;
17289
17331
  }
17290
- async clear(domain) {
17291
- if (domain) {
17292
- await this.storage.delete(domain);
17332
+ async clear(registry) {
17333
+ if (registry) {
17334
+ await this.storage.delete(registry);
17293
17335
  } else {
17294
17336
  const allKeys = await this.storage.list();
17295
- const domains = new Set;
17337
+ const registries = new Set;
17296
17338
  for (const key of allKeys) {
17297
17339
  const firstSlash = key.indexOf("/");
17298
17340
  if (firstSlash !== -1) {
17299
- domains.add(key.substring(0, firstSlash));
17341
+ registries.add(key.substring(0, firstSlash));
17300
17342
  } else {
17301
- domains.add(key);
17343
+ registries.add(key);
17302
17344
  }
17303
17345
  }
17304
- for (const d of domains) {
17305
- await this.storage.delete(d);
17346
+ for (const r of registries) {
17347
+ await this.storage.delete(r);
17306
17348
  }
17307
17349
  }
17308
17350
  }
@@ -17312,27 +17354,16 @@ class MirrorRegistry {
17312
17354
  if (parts.length < 3) {
17313
17355
  return null;
17314
17356
  }
17315
- const version = parts.pop();
17316
- const nameTypePart = parts.pop();
17317
- const domain = parts.shift();
17357
+ const tag = parts.pop();
17358
+ const name = parts.pop();
17359
+ const registry = parts.shift();
17318
17360
  const path = parts.length > 0 ? parts.join("/") : undefined;
17319
- const dotIndex = nameTypePart.lastIndexOf(".");
17320
- let name;
17321
- let type;
17322
- if (dotIndex !== -1) {
17323
- name = nameTypePart.substring(0, dotIndex);
17324
- type = nameTypePart.substring(dotIndex + 1);
17325
- } else {
17326
- name = nameTypePart;
17327
- type = undefined;
17328
- }
17329
- let locatorStr = domain;
17361
+ let locatorStr = registry;
17330
17362
  if (path)
17331
17363
  locatorStr += `/${path}`;
17332
17364
  locatorStr += `/${name}`;
17333
- if (type)
17334
- locatorStr += `.${type}`;
17335
- locatorStr += `@${version}`;
17365
+ if (tag !== "latest")
17366
+ locatorStr += `:${tag}`;
17336
17367
  try {
17337
17368
  return parse2(locatorStr);
17338
17369
  } catch {
@@ -17365,15 +17396,16 @@ function define2(input) {
17365
17396
  if (!obj.type || typeof obj.type !== "string") {
17366
17397
  throw new DefinitionError2("type is required");
17367
17398
  }
17368
- if (!obj.version || typeof obj.version !== "string") {
17369
- throw new DefinitionError2("version is required");
17399
+ const tagValue = obj.tag ?? obj.version;
17400
+ if (tagValue !== undefined && typeof tagValue !== "string") {
17401
+ throw new DefinitionError2("tag must be a string");
17370
17402
  }
17371
17403
  const rxd = {
17372
17404
  ...obj,
17373
17405
  name: obj.name,
17374
17406
  type: obj.type,
17375
- version: obj.version,
17376
- domain: typeof obj.domain === "string" ? obj.domain : "localhost",
17407
+ tag: typeof tagValue === "string" ? tagValue : undefined,
17408
+ registry: typeof obj.registry === "string" ? obj.registry : undefined,
17377
17409
  path: typeof obj.path === "string" ? obj.path : undefined,
17378
17410
  description: typeof obj.description === "string" ? obj.description : undefined,
17379
17411
  author: typeof obj.author === "string" ? obj.author : undefined,
@@ -17385,11 +17417,11 @@ function define2(input) {
17385
17417
  }
17386
17418
  function manifest2(rxd) {
17387
17419
  return {
17388
- domain: rxd.domain,
17420
+ registry: rxd.registry,
17389
17421
  path: rxd.path,
17390
17422
  name: rxd.name,
17391
17423
  type: rxd.type,
17392
- version: rxd.version
17424
+ tag: rxd.tag ?? "latest"
17393
17425
  };
17394
17426
  }
17395
17427
  var BLOCK_SIZE22 = 512;
@@ -17818,11 +17850,10 @@ async function archive2(files2) {
17818
17850
  }
17819
17851
  function locate22(rxm) {
17820
17852
  return {
17821
- domain: rxm.domain,
17853
+ registry: rxm.registry,
17822
17854
  path: rxm.path,
17823
17855
  name: rxm.name,
17824
- type: rxm.type,
17825
- version: rxm.version
17856
+ tag: rxm.tag
17826
17857
  };
17827
17858
  }
17828
17859
  function resource22(rxm, rxa) {
@@ -17906,14 +17937,13 @@ class LinkedRegistry {
17906
17937
  this.basePath = basePath;
17907
17938
  }
17908
17939
  buildLinkPath(rxl) {
17909
- const domain = rxl.domain ?? "localhost";
17910
- const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
17911
- const version = rxl.version ?? "latest";
17912
- let linkPath = join2(this.basePath, domain);
17940
+ const registry = rxl.registry ?? "localhost";
17941
+ const tag = rxl.tag ?? "latest";
17942
+ let linkPath = join2(this.basePath, registry);
17913
17943
  if (rxl.path) {
17914
17944
  linkPath = join2(linkPath, rxl.path);
17915
17945
  }
17916
- return join2(linkPath, resourceName, version);
17946
+ return join2(linkPath, rxl.name, tag);
17917
17947
  }
17918
17948
  async isSymlink(path) {
17919
17949
  try {
@@ -17956,7 +17986,7 @@ class LinkedRegistry {
17956
17986
  if (query) {
17957
17987
  const lowerQuery = query.toLowerCase();
17958
17988
  filtered = locators.filter((rxl) => {
17959
- const searchText = `${rxl.domain ?? ""} ${rxl.path ?? ""} ${rxl.name} ${rxl.type ?? ""}`.toLowerCase();
17989
+ const searchText = `${rxl.registry ?? ""} ${rxl.path ?? ""} ${rxl.name}`.toLowerCase();
17960
17990
  return searchText.includes(lowerQuery);
17961
17991
  });
17962
17992
  }
@@ -18012,27 +18042,16 @@ class LinkedRegistry {
18012
18042
  if (parts.length < 3) {
18013
18043
  return null;
18014
18044
  }
18015
- const version = parts.pop();
18016
- const nameTypePart = parts.pop();
18017
- const domain = parts.shift();
18045
+ const tag = parts.pop();
18046
+ const name = parts.pop();
18047
+ const registry = parts.shift();
18018
18048
  const path = parts.length > 0 ? parts.join("/") : undefined;
18019
- const dotIndex = nameTypePart.lastIndexOf(".");
18020
- let name;
18021
- let type;
18022
- if (dotIndex !== -1) {
18023
- name = nameTypePart.substring(0, dotIndex);
18024
- type = nameTypePart.substring(dotIndex + 1);
18025
- } else {
18026
- name = nameTypePart;
18027
- type = undefined;
18028
- }
18029
- let locatorStr = domain;
18049
+ let locatorStr = registry;
18030
18050
  if (path)
18031
18051
  locatorStr += `/${path}`;
18032
18052
  locatorStr += `/${name}`;
18033
- if (type)
18034
- locatorStr += `.${type}`;
18035
- locatorStr += `@${version}`;
18053
+ if (tag !== "latest")
18054
+ locatorStr += `:${tag}`;
18036
18055
  try {
18037
18056
  return parse2(locatorStr);
18038
18057
  } catch {
@@ -18041,6 +18060,116 @@ class LinkedRegistry {
18041
18060
  }
18042
18061
  }
18043
18062
 
18063
+ class RegistryAccessChain {
18064
+ accessors;
18065
+ memCache = new Map;
18066
+ useMemCache;
18067
+ constructor(accessors, options) {
18068
+ this.accessors = accessors;
18069
+ this.useMemCache = options?.memCache ?? false;
18070
+ }
18071
+ async get(rxl) {
18072
+ const key = format2(rxl);
18073
+ if (this.useMemCache && this.memCache.has(key)) {
18074
+ return this.memCache.get(key);
18075
+ }
18076
+ for (const accessor of this.accessors) {
18077
+ if (await accessor.canHandle(rxl)) {
18078
+ const rxr2 = await accessor.get(rxl);
18079
+ if (this.useMemCache && accessor.name !== "linked") {
18080
+ this.memCache.set(key, rxr2);
18081
+ }
18082
+ return rxr2;
18083
+ }
18084
+ }
18085
+ throw new RegistryError(`Resource not found: ${key}`);
18086
+ }
18087
+ async has(rxl) {
18088
+ const key = format2(rxl);
18089
+ if (this.useMemCache && this.memCache.has(key)) {
18090
+ return true;
18091
+ }
18092
+ for (const accessor of this.accessors) {
18093
+ if (await accessor.canHandle(rxl)) {
18094
+ return true;
18095
+ }
18096
+ }
18097
+ return false;
18098
+ }
18099
+ clearCache() {
18100
+ this.memCache.clear();
18101
+ }
18102
+ invalidate(rxl) {
18103
+ this.memCache.delete(format2(rxl));
18104
+ }
18105
+ }
18106
+
18107
+ class LinkedAccessor {
18108
+ registry;
18109
+ name = "linked";
18110
+ constructor(registry) {
18111
+ this.registry = registry;
18112
+ }
18113
+ async canHandle(rxl) {
18114
+ return this.registry.has(rxl);
18115
+ }
18116
+ async get(rxl) {
18117
+ return this.registry.get(rxl);
18118
+ }
18119
+ }
18120
+
18121
+ class LocalAccessor {
18122
+ registry;
18123
+ name = "local";
18124
+ constructor(registry) {
18125
+ this.registry = registry;
18126
+ }
18127
+ async canHandle(rxl) {
18128
+ if (rxl.registry) {
18129
+ return false;
18130
+ }
18131
+ return this.registry.has(rxl);
18132
+ }
18133
+ async get(rxl) {
18134
+ return this.registry.get(rxl);
18135
+ }
18136
+ }
18137
+
18138
+ class CacheAccessor {
18139
+ registry;
18140
+ name = "cache";
18141
+ constructor(registry) {
18142
+ this.registry = registry;
18143
+ }
18144
+ async canHandle(rxl) {
18145
+ if (!rxl.registry) {
18146
+ return false;
18147
+ }
18148
+ return this.registry.has(rxl);
18149
+ }
18150
+ async get(rxl) {
18151
+ return this.registry.get(rxl);
18152
+ }
18153
+ }
18154
+
18155
+ class RemoteAccessor {
18156
+ fetcher;
18157
+ cache;
18158
+ name = "remote";
18159
+ constructor(fetcher, cache) {
18160
+ this.fetcher = fetcher;
18161
+ this.cache = cache;
18162
+ }
18163
+ async canHandle(rxl) {
18164
+ return !!rxl.registry;
18165
+ }
18166
+ async get(rxl) {
18167
+ const rxr2 = await this.fetcher.fetch(rxl);
18168
+ await this.cache.put(rxr2);
18169
+ return rxr2;
18170
+ }
18171
+ }
18172
+
18044
18173
  // ../loader/dist/index.js
18045
18174
  import { join as join5, relative as relative2 } from "node:path";
18046
18175
  import { stat as stat2, readFile as readFile4, readdir as readdir5 } from "node:fs/promises";
@@ -18073,15 +18202,16 @@ function define3(input) {
18073
18202
  if (!obj.type || typeof obj.type !== "string") {
18074
18203
  throw new DefinitionError3("type is required");
18075
18204
  }
18076
- if (!obj.version || typeof obj.version !== "string") {
18077
- throw new DefinitionError3("version is required");
18205
+ const tagValue = obj.tag ?? obj.version;
18206
+ if (tagValue !== undefined && typeof tagValue !== "string") {
18207
+ throw new DefinitionError3("tag must be a string");
18078
18208
  }
18079
18209
  const rxd = {
18080
18210
  ...obj,
18081
18211
  name: obj.name,
18082
18212
  type: obj.type,
18083
- version: obj.version,
18084
- domain: typeof obj.domain === "string" ? obj.domain : "localhost",
18213
+ tag: typeof tagValue === "string" ? tagValue : undefined,
18214
+ registry: typeof obj.registry === "string" ? obj.registry : undefined,
18085
18215
  path: typeof obj.path === "string" ? obj.path : undefined,
18086
18216
  description: typeof obj.description === "string" ? obj.description : undefined,
18087
18217
  author: typeof obj.author === "string" ? obj.author : undefined,
@@ -18093,11 +18223,11 @@ function define3(input) {
18093
18223
  }
18094
18224
  function manifest3(rxd) {
18095
18225
  return {
18096
- domain: rxd.domain,
18226
+ registry: rxd.registry,
18097
18227
  path: rxd.path,
18098
18228
  name: rxd.name,
18099
18229
  type: rxd.type,
18100
- version: rxd.version
18230
+ tag: rxd.tag ?? "latest"
18101
18231
  };
18102
18232
  }
18103
18233
  var BLOCK_SIZE4 = 512;
@@ -18526,11 +18656,10 @@ async function archive3(files2) {
18526
18656
  }
18527
18657
  function locate3(rxm) {
18528
18658
  return {
18529
- domain: rxm.domain,
18659
+ registry: rxm.registry,
18530
18660
  path: rxm.path,
18531
18661
  name: rxm.name,
18532
- type: rxm.type,
18533
- version: rxm.version
18662
+ tag: rxm.tag
18534
18663
  };
18535
18664
  }
18536
18665
  function resource3(rxm, rxa) {
@@ -18610,21 +18739,34 @@ async function loadResource2(source, config) {
18610
18739
 
18611
18740
  // src/ResourceX.ts
18612
18741
  var DEFAULT_BASE_PATH = `${homedir4()}/.resourcex`;
18613
- var DEFAULT_DOMAIN = "localhost";
18742
+ function normalizeRegistryUrl(url) {
18743
+ try {
18744
+ const parsed = new URL(url);
18745
+ const host = parsed.hostname;
18746
+ const port = parsed.port;
18747
+ const protocol = parsed.protocol;
18748
+ const isDefaultPort = protocol === "http:" && (port === "" || port === "80") || protocol === "https:" && (port === "" || port === "443");
18749
+ if (isDefaultPort || !port) {
18750
+ return host;
18751
+ }
18752
+ return `${host}:${port}`;
18753
+ } catch {
18754
+ return url;
18755
+ }
18756
+ }
18614
18757
 
18615
18758
  class DefaultResourceX {
18616
18759
  basePath;
18617
- domain;
18618
- registry;
18760
+ registryUrl;
18619
18761
  typeHandler;
18620
18762
  isolator;
18621
- hosted;
18763
+ local;
18622
18764
  cache;
18623
18765
  linked;
18766
+ chain;
18624
18767
  constructor(config2) {
18625
18768
  this.basePath = config2?.path ?? DEFAULT_BASE_PATH;
18626
- this.domain = config2?.domain ?? DEFAULT_DOMAIN;
18627
- this.registry = config2?.registry;
18769
+ this.registryUrl = config2?.registry;
18628
18770
  this.isolator = config2?.isolator ?? "none";
18629
18771
  this.typeHandler = TypeHandlerChain.create();
18630
18772
  if (config2?.types) {
@@ -18632,61 +18774,125 @@ class DefaultResourceX {
18632
18774
  this.typeHandler.register(type);
18633
18775
  }
18634
18776
  }
18635
- const hostedStorage = new FileSystemStorage(join9(this.basePath, "hosted"));
18777
+ const localStorage = new FileSystemStorage(join9(this.basePath, "local"));
18636
18778
  const cacheStorage = new FileSystemStorage(join9(this.basePath, "cache"));
18637
- this.hosted = new HostedRegistry(hostedStorage);
18779
+ this.local = new LocalRegistry(localStorage);
18638
18780
  this.cache = new MirrorRegistry(cacheStorage);
18639
18781
  this.linked = new LinkedRegistry(join9(this.basePath, "linked"));
18640
- }
18641
- normalizeLocator(locator) {
18642
- const atIndex = locator.indexOf("@");
18643
- const slashIndex = locator.indexOf("/");
18644
- if (slashIndex !== -1 && (atIndex === -1 || slashIndex < atIndex)) {
18645
- return locator;
18782
+ const accessors = [
18783
+ new LinkedAccessor(this.linked),
18784
+ new LocalAccessor(this.local),
18785
+ new CacheAccessor(this.cache)
18786
+ ];
18787
+ if (this.registryUrl) {
18788
+ const fetcher = this.createRemoteFetcher();
18789
+ accessors.push(new RemoteAccessor(fetcher, this.cache));
18646
18790
  }
18647
- return `${this.domain}/${locator}`;
18791
+ this.chain = new RegistryAccessChain(accessors);
18792
+ }
18793
+ createRemoteFetcher() {
18794
+ const registryUrl = this.registryUrl;
18795
+ const normalizedRegistry = normalizeRegistryUrl(registryUrl);
18796
+ return {
18797
+ fetch: async (rxl) => this.fetchFromRegistry(format(rxl), registryUrl, normalizedRegistry)
18798
+ };
18799
+ }
18800
+ toResource(rxr2) {
18801
+ return {
18802
+ locator: format(rxr2.locator),
18803
+ registry: rxr2.manifest.registry,
18804
+ path: rxr2.manifest.path,
18805
+ name: rxr2.manifest.name,
18806
+ type: rxr2.manifest.type,
18807
+ tag: rxr2.manifest.tag,
18808
+ files: rxr2.manifest.files
18809
+ };
18648
18810
  }
18649
18811
  async add(path11) {
18650
18812
  const rxr2 = await loadResource2(path11);
18651
- if (!rxr2.manifest.domain || rxr2.manifest.domain === "localhost") {
18813
+ if (rxr2.manifest.registry) {
18652
18814
  const { manifest: createManifest, resource: createResource } = await Promise.resolve().then(() => (init_dist(), exports_dist));
18653
18815
  const newManifest = createManifest({
18654
- domain: this.domain,
18816
+ registry: undefined,
18655
18817
  path: rxr2.manifest.path,
18656
18818
  name: rxr2.manifest.name,
18657
18819
  type: rxr2.manifest.type,
18658
- version: rxr2.manifest.version
18820
+ version: rxr2.manifest.tag
18659
18821
  });
18660
18822
  const newRxr = createResource(newManifest, rxr2.archive);
18661
- await this.hosted.put(newRxr);
18662
- } else {
18663
- await this.hosted.put(rxr2);
18823
+ await this.local.put(newRxr);
18824
+ return this.toResource(newRxr);
18664
18825
  }
18826
+ await this.local.put(rxr2);
18827
+ return this.toResource(rxr2);
18665
18828
  }
18666
18829
  async link(path11) {
18667
18830
  await this.linked.link(path11);
18668
18831
  }
18832
+ async unlink(locator) {
18833
+ const rxl = parse(locator);
18834
+ await this.linked.unlink(rxl);
18835
+ this.chain.invalidate(rxl);
18836
+ }
18669
18837
  async has(locator) {
18670
- const normalizedLocator = this.normalizeLocator(locator);
18671
- const rxl = parse(normalizedLocator);
18672
- return await this.linked.has(rxl) || await this.hosted.has(rxl) || await this.cache.has(rxl);
18838
+ const rxl = parse(locator);
18839
+ return this.chain.has(rxl);
18840
+ }
18841
+ async info(locator) {
18842
+ const rxl = parse(locator);
18843
+ const rxr2 = await this.chain.get(rxl);
18844
+ const filesRecord2 = await extract(rxr2.archive);
18845
+ const files2 = Object.keys(filesRecord2);
18846
+ return {
18847
+ locator: format(rxr2.locator),
18848
+ registry: rxr2.manifest.registry,
18849
+ path: rxr2.manifest.path,
18850
+ name: rxr2.manifest.name,
18851
+ type: rxr2.manifest.type,
18852
+ tag: rxr2.manifest.tag,
18853
+ files: files2
18854
+ };
18673
18855
  }
18674
18856
  async remove(locator) {
18675
- const normalizedLocator = this.normalizeLocator(locator);
18676
- const rxl = parse(normalizedLocator);
18857
+ const rxl = parse(locator);
18677
18858
  if (await this.linked.has(rxl)) {
18678
18859
  await this.linked.remove(rxl);
18679
18860
  }
18680
- if (await this.hosted.has(rxl)) {
18681
- await this.hosted.remove(rxl);
18861
+ if (!rxl.registry && await this.local.has(rxl)) {
18862
+ await this.local.remove(rxl);
18682
18863
  }
18683
- if (await this.cache.has(rxl)) {
18864
+ if (rxl.registry && await this.cache.has(rxl)) {
18684
18865
  await this.cache.remove(rxl);
18685
18866
  }
18867
+ this.chain.invalidate(rxl);
18686
18868
  }
18687
- async resolve(locator) {
18688
- const normalizedLocator = this.normalizeLocator(locator);
18689
- const rxr2 = await this.getRxr(normalizedLocator);
18869
+ async use(locator) {
18870
+ const rxl = parse(locator);
18871
+ let rxr2;
18872
+ try {
18873
+ rxr2 = await this.chain.get(rxl);
18874
+ } catch (error) {
18875
+ if (!rxl.registry && this.registryUrl) {
18876
+ const normalizedRegistry = normalizeRegistryUrl(this.registryUrl);
18877
+ try {
18878
+ rxr2 = await this.fetchFromRegistry(format(rxl), this.registryUrl, normalizedRegistry);
18879
+ await this.cache.put(rxr2);
18880
+ } catch {
18881
+ throw error;
18882
+ }
18883
+ } else if (rxl.registry) {
18884
+ const registryUrl = `http://${rxl.registry}`;
18885
+ const locatorWithoutRegistry = format({ ...rxl, registry: undefined });
18886
+ try {
18887
+ rxr2 = await this.fetchFromRegistry(locatorWithoutRegistry, registryUrl, rxl.registry);
18888
+ await this.cache.put(rxr2);
18889
+ } catch {
18890
+ throw error;
18891
+ }
18892
+ } else {
18893
+ throw error;
18894
+ }
18895
+ }
18690
18896
  const handler = this.typeHandler.getHandler(rxr2.manifest.type);
18691
18897
  return {
18692
18898
  schema: handler.schema,
@@ -18697,14 +18903,14 @@ class DefaultResourceX {
18697
18903
  }
18698
18904
  async search(query) {
18699
18905
  const options = query ? { query } : undefined;
18700
- const [linkedResults, hostedResults, cacheResults] = await Promise.all([
18906
+ const [linkedResults, localResults, cacheResults] = await Promise.all([
18701
18907
  this.linked.list(options),
18702
- this.hosted.list(options),
18908
+ this.local.list(options),
18703
18909
  this.cache.list(options)
18704
18910
  ]);
18705
18911
  const seen = new Set;
18706
18912
  const results = [];
18707
- for (const rxl of [...linkedResults, ...hostedResults, ...cacheResults]) {
18913
+ for (const rxl of [...linkedResults, ...localResults, ...cacheResults]) {
18708
18914
  const key = format(rxl);
18709
18915
  if (!seen.has(key)) {
18710
18916
  seen.add(key);
@@ -18713,63 +18919,40 @@ class DefaultResourceX {
18713
18919
  }
18714
18920
  return results;
18715
18921
  }
18716
- async push(path11) {
18717
- if (!this.registry) {
18922
+ async push(locator) {
18923
+ if (!this.registryUrl) {
18718
18924
  throw new RegistryError("Registry URL not configured. Set 'registry' in config.");
18719
18925
  }
18720
- const rxr2 = await loadResource2(path11);
18721
- const { manifest: createManifest, resource: createResource } = await Promise.resolve().then(() => (init_dist(), exports_dist));
18722
- const newManifest = createManifest({
18723
- domain: this.domain,
18724
- path: rxr2.manifest.path,
18725
- name: rxr2.manifest.name,
18726
- type: rxr2.manifest.type,
18727
- version: rxr2.manifest.version
18728
- });
18729
- const newRxr = createResource(newManifest, rxr2.archive);
18730
- await this.publishToRegistry(newRxr);
18926
+ const rxl = parse(locator);
18927
+ const rxr2 = await this.chain.get(rxl);
18928
+ await this.publishToRegistry(rxr2);
18731
18929
  }
18732
18930
  async pull(locator) {
18733
- if (!this.registry) {
18931
+ if (!this.registryUrl) {
18734
18932
  throw new RegistryError("Registry URL not configured. Set 'registry' in config.");
18735
18933
  }
18736
- const normalizedLocator = this.normalizeLocator(locator);
18737
- const rxr2 = await this.fetchFromRegistry(normalizedLocator);
18934
+ const normalizedRegistry = normalizeRegistryUrl(this.registryUrl);
18935
+ const rxr2 = await this.fetchFromRegistry(locator, this.registryUrl, normalizedRegistry);
18738
18936
  await this.cache.put(rxr2);
18739
18937
  }
18938
+ async clearCache(registry) {
18939
+ await this.cache.clear(registry);
18940
+ }
18740
18941
  supportType(type) {
18741
18942
  this.typeHandler.register(type);
18742
18943
  }
18743
- async getRxr(locator) {
18744
- const rxl = parse(locator);
18745
- if (await this.linked.has(rxl)) {
18746
- return this.linked.get(rxl);
18747
- }
18748
- if (await this.hosted.has(rxl)) {
18749
- return this.hosted.get(rxl);
18750
- }
18751
- if (await this.cache.has(rxl)) {
18752
- return this.cache.get(rxl);
18753
- }
18754
- if (this.registry) {
18755
- const rxr2 = await this.fetchFromRegistry(locator);
18756
- await this.cache.put(rxr2);
18757
- return rxr2;
18758
- }
18759
- throw new RegistryError(`Resource not found: ${locator}`);
18760
- }
18761
18944
  async publishToRegistry(rxr2) {
18762
- const baseUrl = this.registry.replace(/\/$/, "");
18763
- const publishUrl = `${baseUrl}/publish`;
18945
+ const baseUrl = this.registryUrl.replace(/\/$/, "");
18946
+ const publishUrl = `${baseUrl}/api/v1/publish`;
18764
18947
  const formData = new FormData;
18765
18948
  formData.append("locator", format(rxr2.locator));
18766
18949
  formData.append("manifest", new Blob([
18767
18950
  JSON.stringify({
18768
- domain: rxr2.manifest.domain,
18951
+ registry: rxr2.manifest.registry,
18769
18952
  path: rxr2.manifest.path,
18770
18953
  name: rxr2.manifest.name,
18771
18954
  type: rxr2.manifest.type,
18772
- version: rxr2.manifest.version
18955
+ version: rxr2.manifest.tag
18773
18956
  })
18774
18957
  ], { type: "application/json" }));
18775
18958
  const archiveBuffer = await rxr2.archive.buffer();
@@ -18782,9 +18965,10 @@ class DefaultResourceX {
18782
18965
  throw new RegistryError(`Failed to publish: ${response.statusText}`);
18783
18966
  }
18784
18967
  }
18785
- async fetchFromRegistry(locator) {
18786
- const baseUrl = this.registry.replace(/\/$/, "");
18787
- const manifestUrl = `${baseUrl}/resource/${encodeURIComponent(locator)}`;
18968
+ async fetchFromRegistry(locator, registryUrl, normalizedRegistry) {
18969
+ const baseUrl = registryUrl.replace(/\/$/, "");
18970
+ const registry = normalizedRegistry ?? normalizeRegistryUrl(registryUrl);
18971
+ const manifestUrl = `${baseUrl}/api/v1/resource/${encodeURIComponent(locator)}`;
18788
18972
  const manifestResponse = await fetch(manifestUrl);
18789
18973
  if (!manifestResponse.ok) {
18790
18974
  if (manifestResponse.status === 404) {
@@ -18799,13 +18983,13 @@ class DefaultResourceX {
18799
18983
  resource: createResource
18800
18984
  } = await Promise.resolve().then(() => (init_dist(), exports_dist));
18801
18985
  const rxm = createManifest({
18802
- domain: manifestData.domain,
18986
+ registry,
18803
18987
  path: manifestData.path,
18804
18988
  name: manifestData.name,
18805
18989
  type: manifestData.type,
18806
- version: manifestData.version
18990
+ tag: manifestData.tag
18807
18991
  });
18808
- const contentUrl = `${baseUrl}/content/${encodeURIComponent(locator)}`;
18992
+ const contentUrl = `${baseUrl}/api/v1/content/${encodeURIComponent(locator)}`;
18809
18993
  const contentResponse = await fetch(contentUrl);
18810
18994
  if (!contentResponse.ok) {
18811
18995
  throw new RegistryError(`Failed to fetch content: ${contentResponse.statusText}`);
@@ -18822,11 +19006,11 @@ class DefaultResourceX {
18822
19006
  }
18823
19007
  const context = {
18824
19008
  manifest: {
18825
- domain: rxr.manifest.domain,
19009
+ registry: rxr.manifest.registry,
18826
19010
  path: rxr.manifest.path,
18827
19011
  name: rxr.manifest.name,
18828
19012
  type: rxr.manifest.type,
18829
- version: rxr.manifest.version
19013
+ version: rxr.manifest.tag
18830
19014
  },
18831
19015
  files
18832
19016
  };
@@ -18872,13 +19056,21 @@ function createResourceX2(config2) {
18872
19056
  }
18873
19057
 
18874
19058
  // src/index.ts
18875
- var VERSION = "2.5.0";
19059
+ init_dist();
19060
+ var VERSION = "2.5.2";
18876
19061
  export {
19062
+ wrap,
19063
+ resource,
19064
+ parse,
19065
+ manifest,
19066
+ format,
19067
+ extract,
18877
19068
  createResourceX2 as createResourceX,
18878
19069
  bundleResourceType,
19070
+ archive,
18879
19071
  VERSION,
18880
19072
  ResourceTypeError,
18881
19073
  RegistryError
18882
19074
  };
18883
19075
 
18884
- //# debugId=2AD1F4EBBAD17C8564756E2164756E21
19076
+ //# debugId=D7A402F2FA14E9CA64756E2164756E21