UNPKG

@oddjs/odd

Version:
195 lines (164 loc) 4.84 kB
import type { CID } from "multiformats/cid" import * as Crypto from "../components/crypto/implementation.js" import * as DID from "../did/index.js" import * as Fission from "../common/fission.js" import * as Reference from "../components/reference/implementation.js" import * as Ucan from "../ucan/index.js" import { Maybe } from "../common/types.js" import { isString } from "../common/type-checks.js" export type AppMetadata = { domains: string[] insertedAt: string modifiedAt: string } type AppIndexResponseJson = { [ k: number ]: { insertedAt: string modifiedAt: string urls: string[] } } export type Dependencies = { crypto: Crypto.Implementation reference: Reference.Implementation } /** * Get A list of all of your apps and their associated domain names */ export async function index( endpoints: Fission.Endpoints, dependencies: Dependencies ): Promise<Array<AppMetadata>> { const localUcan = await dependencies.reference.repositories.ucans.lookupAppUcan("*") if (localUcan === null) { throw "Could not find your local UCAN" } const jwt = Ucan.encode(await Ucan.build({ dependencies: dependencies, audience: await Fission.did(endpoints), issuer: await DID.ucan(dependencies.crypto), proof: localUcan, potency: null })) const response = await fetch(Fission.apiUrl(endpoints, "/app"), { method: "GET", headers: { "authorization": `Bearer ${jwt}` } }) const data: AppIndexResponseJson = await response.json() return Object .values(data) .filter(v => v.urls.length > 0) .map(({ urls, insertedAt, modifiedAt }) => ({ domains: urls, insertedAt, modifiedAt })) } /** * Creates a new app, assigns an initial subdomain, and sets an asset placeholder * * @param subdomain Subdomain to create the fission app with */ export async function create( endpoints: Fission.Endpoints, dependencies: Dependencies, subdomain: Maybe<string> ): Promise<AppMetadata> { const localUcan = await dependencies.reference.repositories.ucans.lookupAppUcan("*") if (localUcan === null) { throw "Could not find your local UCAN" } const jwt = Ucan.encode(await Ucan.build({ dependencies, audience: await Fission.did(endpoints), issuer: await DID.ucan(dependencies.crypto), proof: localUcan, potency: null })) const url = isString(subdomain) ? Fission.apiUrl(endpoints, `/app?subdomain=${encodeURIComponent(subdomain)}`) : Fission.apiUrl(endpoints, `/app`) const response = await fetch(url, { method: "POST", headers: { "authorization": `Bearer ${jwt}` } }) const data = await response.json() const nowIso = (new Date()).toISOString() return { domains: [ data ], insertedAt: nowIso, modifiedAt: nowIso } } /** * Destroy app by any associated domain * * @param domain The domain associated with the app we want to delete */ export async function deleteByDomain( endpoints: Fission.Endpoints, dependencies: Dependencies, domain: string ): Promise<void> { const localUcan = await dependencies.reference.repositories.ucans.lookupAppUcan(domain) if (localUcan === null) { throw new Error("Could not find your local UCAN") } const jwt = Ucan.encode(await Ucan.build({ dependencies, audience: await Fission.did(endpoints), issuer: await DID.ucan(dependencies.crypto), proof: localUcan, potency: null })) const appIndexResponse = await fetch(Fission.apiUrl(endpoints, "/app"), { method: "GET", headers: { "authorization": `Bearer ${jwt}` } }) const index: AppIndexResponseJson = await appIndexResponse.json() const appToDelete = Object.entries(index).find(([ _, app ]) => app.urls.includes(domain)) if (appToDelete == null) { throw new Error(`Couldn't find an app with domain ${domain}`) } await fetch( Fission.apiUrl(endpoints, `/app/${encodeURIComponent(appToDelete[ 0 ])}`), { method: "DELETE", headers: { "authorization": `Bearer ${jwt}` } } ) } /** * Updates an app by CID * * @param subdomain Subdomain to create the fission app with */ export async function publish( endpoints: Fission.Endpoints, dependencies: Dependencies, domain: string, cid: CID, ): Promise<void> { const localUcan = await dependencies.reference.repositories.ucans.lookupAppUcan(domain) if (localUcan === null) { throw "Could not find your local UCAN" } const jwt = Ucan.encode(await Ucan.build({ dependencies, audience: await Fission.did(endpoints), issuer: await DID.ucan(dependencies.crypto), proof: localUcan, potency: null })) const url = Fission.apiUrl(endpoints, `/app/${domain}/${cid}`) await fetch(url, { method: "PUT", headers: { "authorization": `Bearer ${jwt}` } }) }