// ipfs add artifacts/ --recursive --cid-version=1 --hidden --max-directory-links=1000 --chunker=size-1048576 import * as Fs from "@std/fs"; import * as Path from "@std/path"; import { cpSync } from "node:fs"; import { load } from "@std/dotenv"; import { MemoryBlockstore } from "blockstore-core/memory"; import { importer } from "ipfs-unixfs-importer"; import { CID } from "multiformats/cid"; import * as DagPB from "@ipld/dag-pb"; import artifactsJson from "../../artifacts/artifacts.json" with { type: "json", }; import type { Artifact } from "../../common/types.d.ts"; import { execSync, writeCar } from "../../common/index.ts"; const artifacts: Record = artifactsJson as any; //////////////////////////////////////////// // ADD CARS //////////////////////////////////////////// Fs.ensureDirSync("cars"); Object.values(artifacts).forEach((artifact) => { const carPath = Path.join("cars", artifact.cid + ".car"); const exists = Fs.existsSync(carPath); if (!exists) { const inputPath = Path.join("artifacts", artifact.cid); const tmpDir = Deno.makeTempDirSync(); cpSync(inputPath, tmpDir, { dereference: true, preserveTimestamps: true, recursive: true, }); writeCar(tmpDir, artifact.cid); Deno.removeSync(tmpDir, { recursive: true }); } execSync( "ipfs", "dag", "import", carPath, ); }); //////////////////////////////////////////// // GENERATE ROOT DAG //////////////////////////////////////////// const blockstore = new MemoryBlockstore(); const source = [ "artifacts/_redirects", "artifacts/artifacts.json", "artifacts/versions.json", ].map( (path) => { return { path: path, content: Deno.readFileSync(path), }; }, ); const it = Fs.walkSync("dist"); for (const entry of it) { if (!entry.isFile) continue; source.push({ path: entry.path.split("/").slice(1).join("/"), content: Deno.readFileSync(entry.path), }); } const links = []; for await (const entry of importer(source, blockstore)) { links.push( DagPB.createLink(entry.path ?? "", Number(entry.size), entry.cid), ); } Object.values(artifacts).forEach((artifact) => { links.push( DagPB.createLink(artifact.cid, 0, CID.parse(artifact.cid)), ); }); const bytes = DagPB.encode({ Data: new Uint8Array([8, 1]), Links: links.toSorted((a, b) => { const aName = a.Name ?? ""; const bName = b.Name ?? ""; if (aName < bName) return -1; if (aName > bName) return 1; return 0; }), }); //////////////////////////////////////////// // ADD ROOT DAG TO IPFS //////////////////////////////////////////// const cmd = new Deno.Command("ipfs", { args: ["dag", "put", "--store-codec", "dag-pb", "--input-codec", "dag-pb"], stdin: "piped", stdout: "piped", }); const process = cmd.spawn(); const writer = process.stdin.getWriter(); await writer.write(bytes); await writer.close(); const cid = (await process.stdout.text()).trim(); console.log("✅️ Added artifacts DAG to IPFS with CID: " + cid); //////////////////////////////////////////// // SET DNSLINK //////////////////////////////////////////// const env = await load(); const deleteCmd = new Deno.Command("lexicon", { args: [ "dnsimple", "delete", "diffuse.sh", "TXT", "--name", "_dnslink.elements.diffuse.sh", ], env, }); await deleteCmd.spawn().output(); const createCmd = new Deno.Command("lexicon", { args: [ "dnsimple", "create", "diffuse.sh", "TXT", "--name", "_dnslink.elements.diffuse.sh", "--content", `"dnslink=/ipfs/${cid}"`, ], env, }); await createCmd.spawn().output(); console.log("✅️ DNSLink set");