@calimero-network/mero-js 28.0.0 → 28.1.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/cloud-v2/approvals.d.ts +4 -0
- package/dist/cloud-v2/client.d.ts +245 -3
- package/dist/cloud-v2/client.js +163 -6
- package/dist/cloud-v2/index.d.ts +2 -2
- package/dist/cloud-v2/index.js +1 -1
- package/dist/index.browser.mjs +4 -4
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +148 -6
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +148 -6
- package/dist/index.mjs.map +2 -2
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -78,15 +78,18 @@ __export(index_exports, {
|
|
|
78
78
|
createQuoteVerifier: () => createQuoteVerifier,
|
|
79
79
|
createSealedFetch: () => createSealedFetch,
|
|
80
80
|
createSignedReleaseVerifier: () => createSignedReleaseVerifier,
|
|
81
|
+
deployerKey: () => deployerKey,
|
|
81
82
|
errorFrom: () => errorFrom,
|
|
82
83
|
fetchAttestedKey: () => fetchAttestedKey,
|
|
83
84
|
fetchGithubNodeRelease: () => fetchGithubNodeRelease,
|
|
84
85
|
fetchNodeRelease: () => fetchNodeRelease,
|
|
85
86
|
freshCollateral: () => freshCollateral,
|
|
86
87
|
fromB64url: () => fromB64url,
|
|
88
|
+
frontendManifest: () => frontendManifest,
|
|
87
89
|
generateOwnerKey: () => generateOwnerKey,
|
|
88
90
|
orgCapabilities: () => orgCapabilities,
|
|
89
91
|
ownerPublicKey: () => ownerPublicKey,
|
|
92
|
+
pageDeployment: () => pageDeployment,
|
|
90
93
|
pageQuery: () => pageQuery,
|
|
91
94
|
pendingApprovalsFrom: () => pendingApprovalsFrom,
|
|
92
95
|
provisionAgent: () => provisionAgent,
|
|
@@ -1759,6 +1762,26 @@ function upgradeConsent(app, toVersion, returnTo) {
|
|
|
1759
1762
|
}
|
|
1760
1763
|
|
|
1761
1764
|
// src/cloud-v2/client.ts
|
|
1765
|
+
function deployerKey(deployer) {
|
|
1766
|
+
return "account" in deployer ? `account:${deployer.account}` : `org:${deployer.org}`;
|
|
1767
|
+
}
|
|
1768
|
+
async function frontendManifest(origin, fetcher = fetch) {
|
|
1769
|
+
const base = origin ?? globalThis.location?.origin;
|
|
1770
|
+
if (!base) throw new Error("no page origin to read the frontend manifest from; pass `origin`");
|
|
1771
|
+
const response = await fetcher(new URL("/.well-known/calimero.json", base).toString());
|
|
1772
|
+
if (!response.ok) throw await refusal(response);
|
|
1773
|
+
const manifest = await response.json();
|
|
1774
|
+
return { ...manifest, deployments: manifest.deployments ?? [] };
|
|
1775
|
+
}
|
|
1776
|
+
function pageDeployment(href) {
|
|
1777
|
+
const at = href ?? globalThis.location?.href;
|
|
1778
|
+
if (!at) return null;
|
|
1779
|
+
try {
|
|
1780
|
+
return new URL(at).searchParams.get("deployment") || null;
|
|
1781
|
+
} catch {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1762
1785
|
function seg(value) {
|
|
1763
1786
|
return encodeURIComponent(value);
|
|
1764
1787
|
}
|
|
@@ -2217,14 +2240,41 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2217
2240
|
const { hash } = await this.json("POST", "bundles", void 0, wasm);
|
|
2218
2241
|
return hash;
|
|
2219
2242
|
}
|
|
2220
|
-
/**
|
|
2221
|
-
|
|
2222
|
-
|
|
2243
|
+
/**
|
|
2244
|
+
* Upload a blob for `app`: `blobId` is base58 (what apps print), `id` hex.
|
|
2245
|
+
* `contentType` (default `application/octet-stream`; printable ASCII, the
|
|
2246
|
+
* node refuses another with `400`) is sent as the upload's `Content-Type`:
|
|
2247
|
+
* a component app records it and serves downloads with it. A component
|
|
2248
|
+
* app holding as many blobs as it may answers `429 QUOTA_EXCEEDED`.
|
|
2249
|
+
*/
|
|
2250
|
+
uploadBlob(app, data, contentType = {}) {
|
|
2251
|
+
const mime = (typeof contentType === "string" ? contentType : contentType.contentType) ?? "application/octet-stream";
|
|
2252
|
+
return this.json("POST", `apps/${seg(app)}/blobs`, void 0, data, mime);
|
|
2223
2253
|
}
|
|
2224
2254
|
/** One of `app`'s blobs, by id (base58 or hex). */
|
|
2225
2255
|
async downloadBlob(app, id) {
|
|
2226
|
-
|
|
2227
|
-
|
|
2256
|
+
return (await this.blobContent(app, id)).data;
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Download a component app's blob with a grant one of its runs handed out
|
|
2260
|
+
* (`BlobRef::grant`, up to 24 h). No session needed: the grant is the
|
|
2261
|
+
* permission. A bad or expired grant answers `NotFound`, as a missing blob.
|
|
2262
|
+
*/
|
|
2263
|
+
async downloadBlobGranted(app, id, grant) {
|
|
2264
|
+
return (await this.blobContent(app, id, { grant })).data;
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* {@link downloadBlob} (or, with `grant`, {@link downloadBlobGranted}) with
|
|
2268
|
+
* the content type the node serves it as: the uploader's, for a component
|
|
2269
|
+
* app; `application/octet-stream` otherwise.
|
|
2270
|
+
*/
|
|
2271
|
+
async blobContent(app, id, options = {}) {
|
|
2272
|
+
const query = options.grant === void 0 ? "" : `?grant=${encodeURIComponent(options.grant)}`;
|
|
2273
|
+
const response = await this.send("GET", `apps/${seg(app)}/blobs/${seg(id)}${query}`);
|
|
2274
|
+
return {
|
|
2275
|
+
data: new Uint8Array(await response.arrayBuffer()),
|
|
2276
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream"
|
|
2277
|
+
};
|
|
2228
2278
|
}
|
|
2229
2279
|
/** `app`'s blobs. */
|
|
2230
2280
|
async listBlobs(app) {
|
|
@@ -2286,6 +2336,15 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2286
2336
|
async setAppMetadata(app, metadata) {
|
|
2287
2337
|
await this.post(`apps/${seg(app)}/metadata`, { metadata });
|
|
2288
2338
|
}
|
|
2339
|
+
/**
|
|
2340
|
+
* A component app's xcalls: how many messages wait in its outbox, and the
|
|
2341
|
+
* dead letters (never delivered), newest last. Its owner's or an org
|
|
2342
|
+
* admin's (`403` to anyone else); `409 NOT_SUPPORTED` for an app on the
|
|
2343
|
+
* wasmer runtime, whose xcalls are follow-ups.
|
|
2344
|
+
*/
|
|
2345
|
+
appXcalls(app) {
|
|
2346
|
+
return this.get(`apps/${seg(app)}/xcalls`);
|
|
2347
|
+
}
|
|
2289
2348
|
/** What the app's storage holds: `{ keys, bytes, blobs, blobBytes }`. */
|
|
2290
2349
|
appStorage(app) {
|
|
2291
2350
|
return this.get(`apps/${seg(app)}/storage`);
|
|
@@ -2353,7 +2412,13 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2353
2412
|
/**
|
|
2354
2413
|
* Create an app instance from a bundle hash, or from a package release
|
|
2355
2414
|
* (`{ package, version?, service? }`, installed from the registry first if
|
|
2356
|
-
* the cluster lacks it).
|
|
2415
|
+
* the cluster lacks it). With `deployment`, the instance runs the release
|
|
2416
|
+
* that deployment offers for `package` (`version`, if given, must be it)
|
|
2417
|
+
* and records the deployment; no install, no deployer grant. A package or
|
|
2418
|
+
* version it does not offer answers `400 NOT_OFFERED`, several offered
|
|
2419
|
+
* releases with no `version` `400 VERSION_REQUIRED`, and an unknown
|
|
2420
|
+
* `service` `400 NO_SUCH_SERVICE`. A page opened through `/d/{deployment}/`
|
|
2421
|
+
* finds its deployment with {@link pageDeployment}.
|
|
2357
2422
|
*/
|
|
2358
2423
|
async createApp(name, bundle, options = {}) {
|
|
2359
2424
|
const target = typeof bundle === "string" ? { bundle } : bundle;
|
|
@@ -2725,6 +2790,83 @@ var CalimeroClient = class _CalimeroClient {
|
|
|
2725
2790
|
redeemInvite(token) {
|
|
2726
2791
|
return this.post(`invites/${seg(token)}/redeem`);
|
|
2727
2792
|
}
|
|
2793
|
+
// ---------------------------------------------------------------- deployers
|
|
2794
|
+
/**
|
|
2795
|
+
* Let an account or organization install apps where the cluster's
|
|
2796
|
+
* deployments are `granted`, until `until` (RFC 3339 or a `Date`; absent,
|
|
2797
|
+
* the grant does not end). The cluster's owner grants it, approved with
|
|
2798
|
+
* `passkey`, where governance says `deployers: owner`; elsewhere the
|
|
2799
|
+
* operator grants with its key, and this is refused `403`.
|
|
2800
|
+
*/
|
|
2801
|
+
grantDeployer(deployer, passkey, options = {}) {
|
|
2802
|
+
const until = options.until instanceof Date ? options.until.toISOString() : options.until;
|
|
2803
|
+
return this.postConfirmed("deployers", { deployer, ...until === void 0 ? {} : { until } }, passkey);
|
|
2804
|
+
}
|
|
2805
|
+
/**
|
|
2806
|
+
* Who may install apps on the cluster: its deployments rule, who grants
|
|
2807
|
+
* deployers, its owner and every grant. For the cluster's owner, or the
|
|
2808
|
+
* operator (its token, `useApiKey`).
|
|
2809
|
+
*/
|
|
2810
|
+
deployers() {
|
|
2811
|
+
return this.get("deployers");
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* End a deployer's grant (`deployer`, or its key `account:{id}` /
|
|
2815
|
+
* `org:{id}`), as the cluster's owner, approved with `passkey`. Apps it
|
|
2816
|
+
* installed, and the apps running them, stay.
|
|
2817
|
+
*/
|
|
2818
|
+
async revokeDeployer(deployer, passkey) {
|
|
2819
|
+
const key = typeof deployer === "string" ? deployer : deployerKey(deployer);
|
|
2820
|
+
await this.deleteConfirmed(`deployers/${seg(key)}`, passkey);
|
|
2821
|
+
}
|
|
2822
|
+
// ---------------------------------------------------------------- deployments
|
|
2823
|
+
/**
|
|
2824
|
+
* Create a deployment: `owner`'s (the caller's own account, or an
|
|
2825
|
+
* organization where it holds `MANAGE_APPLICATION` org-wide) list of the
|
|
2826
|
+
* apps it offers, named `name` (1 to 64 characters, one line) for
|
|
2827
|
+
* customers. Approved with `passkey`; where deployments are `granted` the
|
|
2828
|
+
* caller needs a deployer grant. Answers the deployment's id.
|
|
2829
|
+
*/
|
|
2830
|
+
async createDeployment(name, owner, passkey) {
|
|
2831
|
+
const { id } = await this.postConfirmed("deployments", { name, owner }, passkey);
|
|
2832
|
+
return id;
|
|
2833
|
+
}
|
|
2834
|
+
/** The deployments the caller manages: its account's, and its organizations' where it holds `MANAGE_APPLICATION`. */
|
|
2835
|
+
async deployments() {
|
|
2836
|
+
const { deployments } = await this.get("deployments");
|
|
2837
|
+
return deployments;
|
|
2838
|
+
}
|
|
2839
|
+
/** A deployment as anyone may read it: its name, its owner's kind and name, and the apps it offers. Public. */
|
|
2840
|
+
deployment(id) {
|
|
2841
|
+
return this.get(`deployments/${seg(id)}`);
|
|
2842
|
+
}
|
|
2843
|
+
/** Delete a deployment that offers nothing and has no instances, approved with `passkey`. */
|
|
2844
|
+
async deleteDeployment(id, passkey) {
|
|
2845
|
+
await this.deleteConfirmed(`deployments/${seg(id)}`, passkey);
|
|
2846
|
+
}
|
|
2847
|
+
/**
|
|
2848
|
+
* Offer `package@version` (installed, and seen by the caller) as `app`
|
|
2849
|
+
* (1 to 64 letters, digits, `.`, `_`, `-`) in deployment `id`, or move an
|
|
2850
|
+
* offered app to another release of its package. Approved with `passkey`.
|
|
2851
|
+
*/
|
|
2852
|
+
offerApp(id, offer, passkey) {
|
|
2853
|
+
return this.postConfirmed(`deployments/${seg(id)}/apps`, { ...offer }, passkey);
|
|
2854
|
+
}
|
|
2855
|
+
/**
|
|
2856
|
+
* Withdraw `app` from deployment `id`, approved with `passkey`; refused
|
|
2857
|
+
* while an instance created from the deployment still runs it.
|
|
2858
|
+
*/
|
|
2859
|
+
async withdrawApp(id, app, passkey) {
|
|
2860
|
+
await this.deleteConfirmed(`deployments/${seg(id)}/apps/${seg(app)}`, passkey);
|
|
2861
|
+
}
|
|
2862
|
+
/**
|
|
2863
|
+
* The organizations with instances created from deployment `id`, for its
|
|
2864
|
+
* managers: each one's id, name, instance count, apps and releases, and
|
|
2865
|
+
* first instance. Never members, teams or app data.
|
|
2866
|
+
*/
|
|
2867
|
+
deploymentOrgs(id) {
|
|
2868
|
+
return this.get(`deployments/${seg(id)}/orgs`);
|
|
2869
|
+
}
|
|
2728
2870
|
};
|
|
2729
2871
|
|
|
2730
2872
|
// src/cloud-v2/capabilities.ts
|