mirror of
https://github.com/onsonr/nebula.git
synced 2025-03-10 17:29:11 +00:00
172 lines
4.5 KiB
JavaScript
172 lines
4.5 KiB
JavaScript
// @ts-check
|
|
|
|
/**
|
|
* This script generates the src/protobufs directory from the proto files in the
|
|
* repos specified in `REPOS`. It uses `buf` to generate TS files from the proto
|
|
* files, and then generates an `index.ts` file to re-export the generated code.
|
|
*/
|
|
|
|
import { spawnSync } from "child_process";
|
|
import degit from "degit";
|
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
import { globSync } from "glob";
|
|
import { capitalize } from "lodash-es";
|
|
import { dirname, join } from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
/**
|
|
* @typedef Repo
|
|
* @type {object}
|
|
* @property {string} repo - Git repo and branch to clone
|
|
* @property {string[]} paths - Paths to proto files relative to the repo root
|
|
*/
|
|
|
|
/**
|
|
* TODO: Add more repos here when necessary.
|
|
* @type {Repo[]}
|
|
*/
|
|
const REPOS = [
|
|
{
|
|
repo: "cosmos/cosmos-sdk#v0.50.5",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "cosmos/ics23#master",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "cosmos/ibc-go#main",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "onsonr/sonr#main",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "CosmWasm/wasmd#main",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "osmosis-labs/osmosis#main",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "evmos/ethermint#main",
|
|
paths: ["proto"],
|
|
},
|
|
{
|
|
repo: "nomic-io/nomic#develop",
|
|
paths: ["src/babylon/proto"],
|
|
},
|
|
];
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const PROTOBUFS_DIR = join(__dirname, "..", "src", "protobufs");
|
|
const TMP_DIR = join(PROTOBUFS_DIR, ".tmp");
|
|
/** Generates a unique dirname from `repo` to use in `TMP_DIR`. */
|
|
const id = (/** @type {string} */ repo) => repo.replace(/[#/]/g, "-");
|
|
|
|
console.log("Initialising directories...");
|
|
{
|
|
rmSync(PROTOBUFS_DIR, { recursive: true, force: true });
|
|
rmSync(TMP_DIR, { recursive: true, force: true });
|
|
mkdirSync(PROTOBUFS_DIR);
|
|
mkdirSync(TMP_DIR);
|
|
}
|
|
|
|
console.log("Cloning required repos...");
|
|
{
|
|
await Promise.all(
|
|
REPOS.map(({ repo }) => degit(repo).clone(join(TMP_DIR, id(repo))))
|
|
);
|
|
}
|
|
|
|
console.log("Generating TS files from proto files...");
|
|
{
|
|
for (const { repo, paths } of REPOS) {
|
|
for (const path of paths) {
|
|
spawnSync(
|
|
"pnpm",
|
|
[
|
|
"buf",
|
|
"generate",
|
|
join(TMP_DIR, id(repo), path),
|
|
"--output",
|
|
join(
|
|
PROTOBUFS_DIR,
|
|
repo.startsWith("dymensionxyz") ? "dymension" : ""
|
|
),
|
|
],
|
|
{
|
|
cwd: process.cwd(),
|
|
stdio: "inherit",
|
|
}
|
|
);
|
|
}
|
|
console.log(`✔️ [${repo}]`);
|
|
}
|
|
}
|
|
|
|
console.log("Generating src/index.ts file and renaming exports...");
|
|
{
|
|
const LAST_SEGMENT_REGEX = /[^/]+$/;
|
|
const EXPORTED_NAME_REGEX = /^export \w+ (\w+) /gm;
|
|
let contents =
|
|
"/** This file is generated by gen-protobufs.mjs. Do not edit. */\n\n";
|
|
/**
|
|
* Builds the `src/proto/index.ts` file to re-export generated code.
|
|
* A prefix is added to the exported names to avoid name collisions.
|
|
* The prefix is the names of the directories in `proto` leading up
|
|
* to the directory of the exported code, concatenated in PascalCase.
|
|
* For example, if the exported code is in `proto/foo/bar/goo.ts`, the
|
|
* prefix will be `FooBar`.
|
|
* @param {string} dir
|
|
*/
|
|
function generateIndexExports(dir) {
|
|
const files = globSync(join(dir, "*"));
|
|
if (files.length === 0) {
|
|
return;
|
|
}
|
|
const prefixName = dir
|
|
.replace(PROTOBUFS_DIR + "/", "")
|
|
.split("/")
|
|
.map((name) =>
|
|
// convert all names to PascalCase
|
|
name.split(/[-_]/).map(capitalize).join("")
|
|
)
|
|
.join("");
|
|
for (const file of files) {
|
|
const fileName = file.match(LAST_SEGMENT_REGEX)?.[0];
|
|
if (!fileName) {
|
|
console.error("Could not find name for", file);
|
|
continue;
|
|
}
|
|
if (!fileName.endsWith(".ts")) {
|
|
continue;
|
|
}
|
|
const code = readFileSync(file, "utf8");
|
|
contents += `export {\n`;
|
|
for (const match of code.matchAll(EXPORTED_NAME_REGEX)) {
|
|
const exportedName = match[1];
|
|
contents += ` ${exportedName} as ${prefixName + exportedName},\n`;
|
|
}
|
|
const exportedFile = file
|
|
.replace(PROTOBUFS_DIR + "/", "")
|
|
.replace(".ts", ".js");
|
|
contents += `} from "./${exportedFile}";\n`;
|
|
}
|
|
for (const file of files) {
|
|
generateIndexExports(file);
|
|
}
|
|
}
|
|
generateIndexExports(PROTOBUFS_DIR);
|
|
writeFileSync(join(PROTOBUFS_DIR, "index.ts"), contents);
|
|
}
|
|
|
|
console.log("Cleaning up...");
|
|
{
|
|
rmSync(TMP_DIR, { recursive: true, force: true });
|
|
}
|
|
|
|
console.log("Proto generation completed successfully!");
|