|
@@ -1,4 +1,5 @@
|
|
import * as toml from "toml";
|
|
import * as toml from "toml";
|
|
|
|
+import camelcase from "camelcase";
|
|
import { snakeCase } from "snake-case";
|
|
import { snakeCase } from "snake-case";
|
|
import { Program } from "./program/index.js";
|
|
import { Program } from "./program/index.js";
|
|
import { isBrowser } from "./utils/common.js";
|
|
import { isBrowser } from "./utils/common.js";
|
|
@@ -19,27 +20,10 @@ const workspace = new Proxy(
|
|
throw new Error("Workspaces aren't available in the browser");
|
|
throw new Error("Workspaces aren't available in the browser");
|
|
}
|
|
}
|
|
|
|
|
|
- // Converting `programName` to snake_case enables the ability to use any
|
|
|
|
|
|
+ // Converting `programName` to camelCase enables the ability to use any
|
|
// of the following to access the workspace program:
|
|
// of the following to access the workspace program:
|
|
// `workspace.myProgram`, `workspace.MyProgram`, `workspace["my-program"]`...
|
|
// `workspace.myProgram`, `workspace.MyProgram`, `workspace["my-program"]`...
|
|
- programName = snakeCase(programName);
|
|
|
|
-
|
|
|
|
- // Check whether the program name contains any digits
|
|
|
|
- if (/\d/.test(programName)) {
|
|
|
|
- // Numbers cannot be properly converted from camelCase to snake_case,
|
|
|
|
- // e.g. if the `programName` is `myProgram2`, the actual program name could
|
|
|
|
- // be `my_program2` or `my_program_2`. This implementation assumes the
|
|
|
|
- // latter as the default and always converts to `_numbers`.
|
|
|
|
- //
|
|
|
|
- // A solution to the conversion of program names with numbers in them
|
|
|
|
- // would be to always convert the `programName` to camelCase instead of
|
|
|
|
- // snake_case. The problem with this approach is that it would require
|
|
|
|
- // converting everything else e.g. program names in Anchor.toml and IDL
|
|
|
|
- // file names which are both snake_case.
|
|
|
|
- programName = programName
|
|
|
|
- .replace(/\d+/g, (match) => "_" + match)
|
|
|
|
- .replace("__", "_");
|
|
|
|
- }
|
|
|
|
|
|
+ programName = camelcase(programName);
|
|
|
|
|
|
// Return early if the program is in cache
|
|
// Return early if the program is in cache
|
|
if (workspaceCache[programName]) return workspaceCache[programName];
|
|
if (workspaceCache[programName]) return workspaceCache[programName];
|
|
@@ -50,7 +34,13 @@ const workspace = new Proxy(
|
|
// Override the workspace programs if the user put them in the config.
|
|
// Override the workspace programs if the user put them in the config.
|
|
const anchorToml = toml.parse(fs.readFileSync("Anchor.toml"));
|
|
const anchorToml = toml.parse(fs.readFileSync("Anchor.toml"));
|
|
const clusterId = anchorToml.provider.cluster;
|
|
const clusterId = anchorToml.provider.cluster;
|
|
- const programEntry = anchorToml.programs?.[clusterId]?.[programName];
|
|
|
|
|
|
+ const programs = anchorToml.programs?.[clusterId];
|
|
|
|
+ let programEntry;
|
|
|
|
+ if (programs) {
|
|
|
|
+ programEntry = Object.entries(programs).find(
|
|
|
|
+ ([key]) => camelcase(key) === programName
|
|
|
|
+ )?.[1];
|
|
|
|
+ }
|
|
|
|
|
|
let idlPath: string;
|
|
let idlPath: string;
|
|
let programId;
|
|
let programId;
|
|
@@ -58,7 +48,22 @@ const workspace = new Proxy(
|
|
idlPath = programEntry.idl;
|
|
idlPath = programEntry.idl;
|
|
programId = programEntry.address;
|
|
programId = programEntry.address;
|
|
} else {
|
|
} else {
|
|
- idlPath = path.join("target", "idl", `${programName}.json`);
|
|
|
|
|
|
+ // Assuming the IDL file's name to be the snake_case name of the
|
|
|
|
+ // `programName` with `.json` extension results in problems when
|
|
|
|
+ // numbers are involved due to the nature of case conversion from
|
|
|
|
+ // camelCase to snake_case being lossy.
|
|
|
|
+ //
|
|
|
|
+ // To avoid the above problem with numbers, read the `idl` directory and
|
|
|
|
+ // compare the camelCased version of both file names and `programName`.
|
|
|
|
+ const idlDirPath = path.join("target", "idl");
|
|
|
|
+ const fileName = fs
|
|
|
|
+ .readdirSync(idlDirPath)
|
|
|
|
+ .find((name) => camelcase(path.parse(name).name) === programName);
|
|
|
|
+ if (!fileName) {
|
|
|
|
+ throw new Error(`Failed to find IDL of program \`${programName}\``);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ idlPath = path.join(idlDirPath, fileName);
|
|
}
|
|
}
|
|
|
|
|
|
if (!fs.existsSync(idlPath)) {
|
|
if (!fs.existsSync(idlPath)) {
|