@calimero-network/mero-js 2.3.0 → 2.4.1

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.cjs CHANGED
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  WsClient: () => WsClient,
35
35
  buildAuthLoginUrl: () => buildAuthLoginUrl,
36
36
  combineSignals: () => combineSignals,
37
+ compareSemver: () => compareSemver,
37
38
  createAdminApiClient: () => createAdminApiClient,
38
39
  createAdminApiClientFromHttpClient: () => createAdminApiClientFromHttpClient,
39
40
  createAuthApiClient: () => createAuthApiClient,
@@ -697,6 +698,24 @@ function createAuthApiClientFromHttpClient(httpClient, _config) {
697
698
  function unwrap(response) {
698
699
  return response.data;
699
700
  }
701
+ function compareSemver(a, b) {
702
+ const pa = a.split(".");
703
+ const pb = b.split(".");
704
+ const n = Math.max(pa.length, pb.length);
705
+ for (let i = 0; i < n; i++) {
706
+ const sa = pa[i] ?? "0";
707
+ const sb = pb[i] ?? "0";
708
+ const na = Number.parseInt(sa, 10);
709
+ const nb = Number.parseInt(sb, 10);
710
+ if (Number.isNaN(na) || Number.isNaN(nb)) {
711
+ const c = sa.localeCompare(sb);
712
+ if (c !== 0) return c;
713
+ } else if (na !== nb) {
714
+ return na - nb;
715
+ }
716
+ }
717
+ return 0;
718
+ }
700
719
  var AdminApiClient = class {
701
720
  constructor(httpClient) {
702
721
  this.httpClient = httpClient;
@@ -712,6 +731,57 @@ var AdminApiClient = class {
712
731
  async installApplication(request) {
713
732
  return unwrap(await this.httpClient.post("/admin-api/install-application", request));
714
733
  }
734
+ /**
735
+ * Resolve a `package@version` to its registry artifact URL and install it.
736
+ * Node install is URL-based (no node-side package+version resolution), so this
737
+ * fetches the bundle manifest from the registry, derives the `.mpk` artifact
738
+ * URL, then calls {@link installApplication}. `registryUrl` is the registry
739
+ * origin. This is the discrete "download" step an Updates flow pairs with a
740
+ * subsequent `upgradeGroup`.
741
+ */
742
+ async installFromRegistry(registryUrl, packageName, version) {
743
+ const base = new URL(registryUrl).origin;
744
+ const manifestUrl = new URL(
745
+ `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,
746
+ base
747
+ ).toString();
748
+ const resp = await fetch(manifestUrl);
749
+ if (!resp.ok) {
750
+ throw new Error(
751
+ `registry manifest fetch failed (${resp.status}) for ${packageName}@${version}`
752
+ );
753
+ }
754
+ const bundle = await resp.json();
755
+ const pkg = encodeURIComponent(bundle.package);
756
+ const ver = encodeURIComponent(bundle.appVersion);
757
+ const artifactUrl = `${base}/artifacts/${pkg}/${ver}/${pkg}-${ver}.mpk`;
758
+ return this.installApplication({
759
+ url: artifactUrl,
760
+ package: bundle.package,
761
+ version: bundle.appVersion,
762
+ metadata: []
763
+ });
764
+ }
765
+ /**
766
+ * List a package's published versions from the registry, newest-first by
767
+ * semver. Reads the registry's V2 bundle listing
768
+ * (`GET {registry}/api/v2/bundles?package={package}`), taking each bundle's
769
+ * `appVersion`. Registry-side data — distinct from the node's
770
+ * installed-version list — and the source an Updates view compares against
771
+ * the running `Context.applicationVersion` to detect "a new version exists".
772
+ */
773
+ async getRegistryVersions(registryUrl, packageName) {
774
+ const url = new URL("/api/v2/bundles", new URL(registryUrl).origin);
775
+ url.searchParams.set("package", packageName);
776
+ const resp = await fetch(url.toString());
777
+ if (!resp.ok) {
778
+ throw new Error(
779
+ `registry versions fetch failed (${resp.status}) for ${packageName}`
780
+ );
781
+ }
782
+ const bundles = await resp.json();
783
+ return (Array.isArray(bundles) ? bundles : []).map((b) => b.appVersion).filter((v) => typeof v === "string").sort((a, b) => compareSemver(b, a));
784
+ }
715
785
  async installDevApplication(request) {
716
786
  return unwrap(await this.httpClient.post("/admin-api/install-dev-application", request));
717
787
  }
@@ -1027,7 +1097,7 @@ var AdminApiClient = class {
1027
1097
  await this.httpClient.put(`/admin-api/groups/${groupId}/metadata`, request);
1028
1098
  }
1029
1099
  async getGroupMetadata(groupId) {
1030
- return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/metadata`)).data;
1100
+ return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/metadata`))?.data ?? null;
1031
1101
  }
1032
1102
  async setMemberMetadata(groupId, identity, request) {
1033
1103
  await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/metadata`, request);
@@ -1035,7 +1105,7 @@ var AdminApiClient = class {
1035
1105
  async getMemberMetadata(groupId, identity) {
1036
1106
  return unwrap(
1037
1107
  await this.httpClient.get(`/admin-api/groups/${groupId}/members/${identity}/metadata`)
1038
- ).data;
1108
+ )?.data ?? null;
1039
1109
  }
1040
1110
  async setContextMetadata(groupId, contextId, request) {
1041
1111
  await this.httpClient.put(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`, request);
@@ -1043,7 +1113,7 @@ var AdminApiClient = class {
1043
1113
  async getContextMetadata(groupId, contextId) {
1044
1114
  return unwrap(
1045
1115
  await this.httpClient.get(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`)
1046
- ).data;
1116
+ )?.data ?? null;
1047
1117
  }
1048
1118
  async syncGroup(groupId, request) {
1049
1119
  return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/sync`, request ?? {}));