workspace.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import camelCase from "camelcase";
  2. import { PublicKey } from "@solana/web3.js";
  3. import { Program } from "./program";
  4. let _populatedWorkspace = false;
  5. // Workspace program discovery only works for node environments.
  6. export default new Proxy({} as any, {
  7. get(workspaceCache: { [key: string]: Program }, programName: string) {
  8. const find = require("find");
  9. const fs = require("fs");
  10. const process = require("process");
  11. if (typeof window !== "undefined") {
  12. // Workspaces aren't available in the browser, yet.
  13. return undefined;
  14. }
  15. if (!_populatedWorkspace) {
  16. const path = require("path");
  17. let projectRoot = process.cwd();
  18. while (!fs.existsSync(path.join(projectRoot, "Anchor.toml"))) {
  19. const parentDir = path.dirname(projectRoot);
  20. if (parentDir === projectRoot) {
  21. projectRoot = undefined;
  22. }
  23. projectRoot = parentDir;
  24. }
  25. if (projectRoot === undefined) {
  26. throw new Error("Could not find workspace root.");
  27. }
  28. find
  29. .fileSync(/target\/idl\/.*\.json/, projectRoot)
  30. .reduce((programs: any, path: string) => {
  31. const idlStr = fs.readFileSync(path);
  32. const idl = JSON.parse(idlStr);
  33. const name = camelCase(idl.name, { pascalCase: true });
  34. programs[name] = new Program(
  35. idl,
  36. new PublicKey(idl.metadata.address)
  37. );
  38. return programs;
  39. }, workspaceCache);
  40. _populatedWorkspace = true;
  41. }
  42. return workspaceCache[programName];
  43. },
  44. });