diff --git a/components/build-deploy-panel.tsx b/components/build-deploy-panel.tsx index e925809..065a98e 100644 --- a/components/build-deploy-panel.tsx +++ b/components/build-deploy-panel.tsx @@ -68,6 +68,15 @@ export function BuildDeployPanel() { > Deploy + ); } diff --git a/components/workspace/use-cli-commands.tsx b/components/workspace/use-cli-commands.tsx index 25b1279..c2092cb 100644 --- a/components/workspace/use-cli-commands.tsx +++ b/components/workspace/use-cli-commands.tsx @@ -9,6 +9,8 @@ import { TerminalContext } from "react-terminal"; import { useWorkspaceId } from "./use-workspace-id"; import { uploadContractCode, useAudit, useAuditReport } from "@/data/audit"; import clsx from "clsx"; +import { fileContentToZip } from "@/lib/file-content-to-zip"; +import { saveAs } from "file-saver"; export function useCliCommands() { const terminalContext = useContext(TerminalContext); @@ -28,6 +30,7 @@ export function useCliCommands() {
  • build - builds the current workspace
  • deploy - deploys the built smart contract
  • +
  • export - exports the current workspace
  • check txID - checks the result of transaction
  • @@ -187,6 +190,29 @@ export function useCliCommands() { ); }, + export: async () => { + if (typeof id !== "string") throw new Error("id is not string"); + const start = `${pathname}/`; + terminalContext.setBufferedContent( + <> +

    Loading files...

    + + ); + const files = ( + await db.files.filter((file) => file.path.startsWith(start)).toArray() + ).map((file) => ({ + path: decodeURIComponent(file.path.replace(start, "")), + contents: file.contents, + })); + + const zip = fileContentToZip(files); + const file = new File( + [zip], + `${pathname?.split("/")?.pop() || "export"}.zip`, + { type: "data:application/octet-stream;base64," } + ); + saveAs(file); + }, }; return commands; diff --git a/package-lock.json b/package-lock.json index 56ee8fe..d58f3c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "dexie": "^4.0.8", "dexie-react-hooks": "^1.1.7", "fflate": "^0.8.2", + "file-saver": "^2.0.5", "inversify": "^6.0.2", "inversify-react": "^1.1.1", "lucide-react": "^0.408.0", @@ -70,6 +71,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/file-saver": "^2.0.7", "@types/node": "^20", "@types/parse-github-url": "^1.0.3", "@types/react": "^18", @@ -2468,6 +2470,13 @@ "@types/estree": "*" } }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", @@ -5307,6 +5316,12 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", diff --git a/package.json b/package.json index 68bc909..ab9512a 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "dexie": "^4.0.8", "dexie-react-hooks": "^1.1.7", "fflate": "^0.8.2", + "file-saver": "^2.0.5", "inversify": "^6.0.2", "inversify-react": "^1.1.1", "lucide-react": "^0.408.0", @@ -71,6 +72,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/file-saver": "^2.0.7", "@types/node": "^20", "@types/parse-github-url": "^1.0.3", "@types/react": "^18",