movehat 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -279
- package/dist/__tests__/deployContract.test.d.ts +2 -0
- package/dist/__tests__/deployContract.test.d.ts.map +1 -0
- package/dist/__tests__/deployContract.test.js +368 -0
- package/dist/__tests__/deployContract.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +46 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts +24 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts.map +1 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.js +82 -0
- package/dist/__tests__/fixtures/sigint-deploy-harness.js.map +1 -0
- package/dist/__tests__/fork/api.test.d.ts +2 -0
- package/dist/__tests__/fork/api.test.d.ts.map +1 -0
- package/dist/__tests__/fork/api.test.js +110 -0
- package/dist/__tests__/fork/api.test.js.map +1 -0
- package/dist/__tests__/harness/Harness.createLive.test.d.ts +2 -0
- package/dist/__tests__/harness/Harness.createLive.test.d.ts.map +1 -0
- package/dist/__tests__/harness/Harness.createLive.test.js +53 -0
- package/dist/__tests__/harness/Harness.createLive.test.js.map +1 -0
- package/dist/__tests__/harness/Harness.proxy.test.d.ts +2 -0
- package/dist/__tests__/harness/Harness.proxy.test.d.ts.map +1 -0
- package/dist/__tests__/harness/Harness.proxy.test.js +89 -0
- package/dist/__tests__/harness/Harness.proxy.test.js.map +1 -0
- package/dist/__tests__/harness/_fixture.d.ts +54 -0
- package/dist/__tests__/harness/_fixture.d.ts.map +1 -0
- package/dist/__tests__/harness/_fixture.js +69 -0
- package/dist/__tests__/harness/_fixture.js.map +1 -0
- package/dist/__tests__/harness/codeObject.deploy.test.d.ts +2 -0
- package/dist/__tests__/harness/codeObject.deploy.test.d.ts.map +1 -0
- package/dist/__tests__/harness/codeObject.deploy.test.js +288 -0
- package/dist/__tests__/harness/codeObject.deploy.test.js.map +1 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.d.ts +2 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.d.ts.map +1 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.js +138 -0
- package/dist/__tests__/harness/codeObject.upgrade.test.js.map +1 -0
- package/dist/__tests__/harness/script.test.d.ts +2 -0
- package/dist/__tests__/harness/script.test.d.ts.map +1 -0
- package/dist/__tests__/harness/script.test.js +219 -0
- package/dist/__tests__/harness/script.test.js.map +1 -0
- package/dist/__tests__/harness/view.test.d.ts +2 -0
- package/dist/__tests__/harness/view.test.d.ts.map +1 -0
- package/dist/__tests__/harness/view.test.js +92 -0
- package/dist/__tests__/harness/view.test.js.map +1 -0
- package/dist/__tests__/runtime.test.d.ts +2 -0
- package/dist/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/__tests__/runtime.test.js +141 -0
- package/dist/__tests__/runtime.test.js.map +1 -0
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/compile.test.d.ts +2 -0
- package/dist/commands/__tests__/compile.test.d.ts.map +1 -0
- package/dist/commands/__tests__/compile.test.js +351 -0
- package/dist/commands/__tests__/compile.test.js.map +1 -0
- package/dist/commands/__tests__/init.test.d.ts +2 -0
- package/dist/commands/__tests__/init.test.d.ts.map +1 -0
- package/dist/commands/__tests__/init.test.js +101 -0
- package/dist/commands/__tests__/init.test.js.map +1 -0
- package/dist/commands/__tests__/run.test.d.ts +2 -0
- package/dist/commands/__tests__/run.test.d.ts.map +1 -0
- package/dist/commands/__tests__/run.test.js +166 -0
- package/dist/commands/__tests__/run.test.js.map +1 -0
- package/dist/commands/__tests__/test-move.test.d.ts +2 -0
- package/dist/commands/__tests__/test-move.test.d.ts.map +1 -0
- package/dist/commands/__tests__/test-move.test.js +59 -0
- package/dist/commands/__tests__/test-move.test.js.map +1 -0
- package/dist/commands/__tests__/test.test.d.ts +2 -0
- package/dist/commands/__tests__/test.test.d.ts.map +1 -0
- package/dist/commands/__tests__/test.test.js +168 -0
- package/dist/commands/__tests__/test.test.js.map +1 -0
- package/dist/commands/__tests__/update.test.d.ts +2 -0
- package/dist/commands/__tests__/update.test.d.ts.map +1 -0
- package/dist/commands/__tests__/update.test.js +176 -0
- package/dist/commands/__tests__/update.test.js.map +1 -0
- package/dist/commands/compile.d.ts +7 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +150 -33
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/fork/__tests__/create.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/create.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/create.test.js +108 -0
- package/dist/commands/fork/__tests__/create.test.js.map +1 -0
- package/dist/commands/fork/__tests__/fund.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/fund.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/fund.test.js +72 -0
- package/dist/commands/fork/__tests__/fund.test.js.map +1 -0
- package/dist/commands/fork/__tests__/list.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/list.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/list.test.js +119 -0
- package/dist/commands/fork/__tests__/list.test.js.map +1 -0
- package/dist/commands/fork/__tests__/serve.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/serve.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/serve.test.js +97 -0
- package/dist/commands/fork/__tests__/serve.test.js.map +1 -0
- package/dist/commands/fork/__tests__/view-resource.test.d.ts +2 -0
- package/dist/commands/fork/__tests__/view-resource.test.d.ts.map +1 -0
- package/dist/commands/fork/__tests__/view-resource.test.js +77 -0
- package/dist/commands/fork/__tests__/view-resource.test.js.map +1 -0
- package/dist/commands/fork/create.d.ts +1 -1
- package/dist/commands/fork/create.d.ts.map +1 -1
- package/dist/commands/fork/create.js +3 -2
- package/dist/commands/fork/create.js.map +1 -1
- package/dist/commands/fork/fund.d.ts.map +1 -1
- package/dist/commands/fork/fund.js +15 -8
- package/dist/commands/fork/fund.js.map +1 -1
- package/dist/commands/fork/list.d.ts.map +1 -1
- package/dist/commands/fork/list.js +2 -1
- package/dist/commands/fork/list.js.map +1 -1
- package/dist/commands/fork/serve.d.ts +1 -0
- package/dist/commands/fork/serve.d.ts.map +1 -1
- package/dist/commands/fork/serve.js +4 -2
- package/dist/commands/fork/serve.js.map +1 -1
- package/dist/commands/fork/view-resource.d.ts.map +1 -1
- package/dist/commands/fork/view-resource.js +10 -5
- package/dist/commands/fork/view-resource.js.map +1 -1
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +50 -27
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/test-move.d.ts.map +1 -1
- package/dist/commands/test-move.js +3 -2
- package/dist/commands/test-move.js.map +1 -1
- package/dist/commands/test.js +52 -46
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +15 -13
- package/dist/commands/update.js.map +1 -1
- package/dist/core/AccountManager.d.ts +1 -4
- package/dist/core/AccountManager.d.ts.map +1 -1
- package/dist/core/AccountManager.js +20 -12
- package/dist/core/AccountManager.js.map +1 -1
- package/dist/core/Publisher.d.ts +26 -0
- package/dist/core/Publisher.d.ts.map +1 -0
- package/dist/core/Publisher.js +240 -0
- package/dist/core/Publisher.js.map +1 -0
- package/dist/core/__tests__/AccountManager.test.d.ts +2 -0
- package/dist/core/__tests__/AccountManager.test.d.ts.map +1 -0
- package/dist/core/__tests__/AccountManager.test.js +239 -0
- package/dist/core/__tests__/AccountManager.test.js.map +1 -0
- package/dist/core/__tests__/config.test.d.ts +2 -0
- package/dist/core/__tests__/config.test.d.ts.map +1 -0
- package/dist/core/__tests__/config.test.js +311 -0
- package/dist/core/__tests__/config.test.js.map +1 -0
- package/dist/core/__tests__/deployments.test.d.ts +2 -0
- package/dist/core/__tests__/deployments.test.d.ts.map +1 -0
- package/dist/core/__tests__/deployments.test.js +201 -0
- package/dist/core/__tests__/deployments.test.js.map +1 -0
- package/dist/core/__tests__/shell.test.d.ts +2 -0
- package/dist/core/__tests__/shell.test.d.ts.map +1 -0
- package/dist/core/__tests__/shell.test.js +107 -0
- package/dist/core/__tests__/shell.test.js.map +1 -0
- package/dist/core/config.d.ts +13 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +80 -11
- package/dist/core/config.js.map +1 -1
- package/dist/core/contract.d.ts +1 -4
- package/dist/core/contract.d.ts.map +1 -1
- package/dist/core/contract.js +15 -7
- package/dist/core/contract.js.map +1 -1
- package/dist/core/deployments.d.ts +2 -8
- package/dist/core/deployments.d.ts.map +1 -1
- package/dist/core/deployments.js +8 -18
- package/dist/core/deployments.js.map +1 -1
- package/dist/core/movementProfile.d.ts +34 -0
- package/dist/core/movementProfile.d.ts.map +1 -0
- package/dist/core/movementProfile.js +150 -0
- package/dist/core/movementProfile.js.map +1 -0
- package/dist/core/shell.d.ts +23 -7
- package/dist/core/shell.d.ts.map +1 -1
- package/dist/core/shell.js +32 -14
- package/dist/core/shell.js.map +1 -1
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +54 -0
- package/dist/errors.js.map +1 -1
- package/dist/fork/__tests__/manager.test.d.ts +2 -0
- package/dist/fork/__tests__/manager.test.d.ts.map +1 -0
- package/dist/fork/__tests__/manager.test.js +309 -0
- package/dist/fork/__tests__/manager.test.js.map +1 -0
- package/dist/fork/__tests__/server.test.d.ts +2 -0
- package/dist/fork/__tests__/server.test.d.ts.map +1 -0
- package/dist/fork/__tests__/server.test.js +54 -0
- package/dist/fork/__tests__/server.test.js.map +1 -0
- package/dist/fork/__tests__/storage.test.d.ts +2 -0
- package/dist/fork/__tests__/storage.test.d.ts.map +1 -0
- package/dist/fork/__tests__/storage.test.js +222 -0
- package/dist/fork/__tests__/storage.test.js.map +1 -0
- package/dist/fork/__tests__/test.test.d.ts +2 -0
- package/dist/fork/__tests__/test.test.d.ts.map +1 -0
- package/dist/fork/__tests__/test.test.js +81 -0
- package/dist/fork/__tests__/test.test.js.map +1 -0
- package/dist/fork/api.d.ts +14 -3
- package/dist/fork/api.d.ts.map +1 -1
- package/dist/fork/api.js +25 -14
- package/dist/fork/api.js.map +1 -1
- package/dist/fork/manager.d.ts +23 -29
- package/dist/fork/manager.d.ts.map +1 -1
- package/dist/fork/manager.js +79 -76
- package/dist/fork/manager.js.map +1 -1
- package/dist/fork/server.d.ts +11 -3
- package/dist/fork/server.d.ts.map +1 -1
- package/dist/fork/server.js +45 -13
- package/dist/fork/server.js.map +1 -1
- package/dist/fork/storage.d.ts +4 -4
- package/dist/fork/storage.d.ts.map +1 -1
- package/dist/fork/storage.js +7 -9
- package/dist/fork/storage.js.map +1 -1
- package/dist/fork/test.d.ts +12 -4
- package/dist/fork/test.d.ts.map +1 -1
- package/dist/fork/test.js +36 -27
- package/dist/fork/test.js.map +1 -1
- package/dist/harness/Harness.d.ts +118 -0
- package/dist/harness/Harness.d.ts.map +1 -0
- package/dist/harness/Harness.js +187 -0
- package/dist/harness/Harness.js.map +1 -0
- package/dist/harness/codeObject.d.ts +31 -0
- package/dist/harness/codeObject.d.ts.map +1 -0
- package/dist/harness/codeObject.js +267 -0
- package/dist/harness/codeObject.js.map +1 -0
- package/dist/harness/errors.d.ts +14 -0
- package/dist/harness/errors.d.ts.map +1 -0
- package/dist/harness/errors.js +22 -0
- package/dist/harness/errors.js.map +1 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +3 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/proxy.d.ts +7 -0
- package/dist/harness/proxy.d.ts.map +1 -0
- package/dist/harness/proxy.js +36 -0
- package/dist/harness/proxy.js.map +1 -0
- package/dist/harness/script.d.ts +21 -0
- package/dist/harness/script.d.ts.map +1 -0
- package/dist/harness/script.js +155 -0
- package/dist/harness/script.js.map +1 -0
- package/dist/harness/view.d.ts +22 -0
- package/dist/harness/view.d.ts.map +1 -0
- package/dist/harness/view.js +28 -0
- package/dist/harness/view.js.map +1 -0
- package/dist/helpers/__tests__/semver-utils.test.d.ts +2 -0
- package/dist/helpers/__tests__/semver-utils.test.d.ts.map +1 -0
- package/dist/helpers/__tests__/semver-utils.test.js +103 -0
- package/dist/helpers/__tests__/semver-utils.test.js.map +1 -0
- package/dist/helpers/index.d.ts +3 -2
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +2 -2
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/move-tests.d.ts +3 -3
- package/dist/helpers/move-tests.d.ts.map +1 -1
- package/dist/helpers/move-tests.js +21 -20
- package/dist/helpers/move-tests.js.map +1 -1
- package/dist/helpers/npm-registry.d.ts.map +1 -1
- package/dist/helpers/npm-registry.js +1 -3
- package/dist/helpers/npm-registry.js.map +1 -1
- package/dist/helpers/semver-utils.d.ts.map +1 -1
- package/dist/helpers/semver-utils.js +4 -3
- package/dist/helpers/semver-utils.js.map +1 -1
- package/dist/helpers/setup.d.ts.map +1 -1
- package/dist/helpers/setup.js +6 -4
- package/dist/helpers/setup.js.map +1 -1
- package/dist/helpers/setupLocalTesting.d.ts +31 -27
- package/dist/helpers/setupLocalTesting.d.ts.map +1 -1
- package/dist/helpers/setupLocalTesting.js +179 -180
- package/dist/helpers/setupLocalTesting.js.map +1 -1
- package/dist/helpers/testFixtures.d.ts +19 -53
- package/dist/helpers/testFixtures.d.ts.map +1 -1
- package/dist/helpers/testFixtures.js +89 -107
- package/dist/helpers/testFixtures.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/node/LocalNodeManager.d.ts +9 -1
- package/dist/node/LocalNodeManager.d.ts.map +1 -1
- package/dist/node/LocalNodeManager.js +75 -58
- package/dist/node/LocalNodeManager.js.map +1 -1
- package/dist/node/__tests__/LocalNodeManager.test.d.ts +2 -0
- package/dist/node/__tests__/LocalNodeManager.test.d.ts.map +1 -0
- package/dist/node/__tests__/LocalNodeManager.test.js +349 -0
- package/dist/node/__tests__/LocalNodeManager.test.js.map +1 -0
- package/dist/runtime.d.ts +12 -15
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +26 -239
- package/dist/runtime.js.map +1 -1
- package/dist/templates/README.md +1 -1
- package/dist/templates/movehat.config.ts +10 -0
- package/dist/templates/package.json +2 -1
- package/dist/templates/scripts/deploy-counter.ts +46 -38
- package/dist/templates/tests/Counter.test.ts +39 -51
- package/dist/templates/types/movehat.d.ts +6 -9
- package/dist/types/config.d.ts +8 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/fork.d.ts +7 -1
- package/dist/types/fork.d.ts.map +1 -1
- package/dist/types/harness.d.ts +166 -0
- package/dist/types/harness.d.ts.map +1 -0
- package/dist/types/harness.js +2 -0
- package/dist/types/harness.js.map +1 -0
- package/dist/types/runtime.d.ts +7 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/ui/__tests__/colors.test.d.ts +2 -0
- package/dist/ui/__tests__/colors.test.d.ts.map +1 -0
- package/dist/ui/__tests__/colors.test.js +127 -0
- package/dist/ui/__tests__/colors.test.js.map +1 -0
- package/dist/ui/colors.d.ts.map +1 -1
- package/dist/ui/colors.js +6 -2
- package/dist/ui/colors.js.map +1 -1
- package/dist/ui/logger.d.ts +17 -0
- package/dist/ui/logger.d.ts.map +1 -1
- package/dist/ui/logger.js +22 -0
- package/dist/ui/logger.js.map +1 -1
- package/dist/ui/symbols.d.ts +1 -0
- package/dist/ui/symbols.d.ts.map +1 -1
- package/dist/ui/symbols.js +7 -1
- package/dist/ui/symbols.js.map +1 -1
- package/dist/utils/__tests__/address.test.d.ts +2 -0
- package/dist/utils/__tests__/address.test.d.ts.map +1 -0
- package/dist/utils/__tests__/address.test.js +70 -0
- package/dist/utils/__tests__/address.test.js.map +1 -0
- package/dist/utils/__tests__/childProcessAdapter.test.d.ts +2 -0
- package/dist/utils/__tests__/childProcessAdapter.test.d.ts.map +1 -0
- package/dist/utils/__tests__/childProcessAdapter.test.js +217 -0
- package/dist/utils/__tests__/childProcessAdapter.test.js.map +1 -0
- package/dist/utils/__tests__/runCli.test.d.ts +2 -0
- package/dist/utils/__tests__/runCli.test.d.ts.map +1 -0
- package/dist/utils/__tests__/runCli.test.js +187 -0
- package/dist/utils/__tests__/runCli.test.js.map +1 -0
- package/dist/utils/address.d.ts +29 -0
- package/dist/utils/address.d.ts.map +1 -0
- package/dist/utils/address.js +48 -0
- package/dist/utils/address.js.map +1 -0
- package/dist/utils/childProcessAdapter.d.ts +93 -0
- package/dist/utils/childProcessAdapter.d.ts.map +1 -0
- package/dist/utils/childProcessAdapter.js +108 -0
- package/dist/utils/childProcessAdapter.js.map +1 -0
- package/dist/utils/parseCliOutput.d.ts +20 -0
- package/dist/utils/parseCliOutput.d.ts.map +1 -0
- package/dist/utils/parseCliOutput.js +26 -0
- package/dist/utils/parseCliOutput.js.map +1 -0
- package/dist/utils/redact.d.ts +15 -0
- package/dist/utils/redact.d.ts.map +1 -0
- package/dist/utils/redact.js +24 -0
- package/dist/utils/redact.js.map +1 -0
- package/dist/utils/runCli.d.ts +24 -0
- package/dist/utils/runCli.d.ts.map +1 -0
- package/dist/utils/runCli.js +37 -0
- package/dist/utils/runCli.js.map +1 -0
- package/package.json +15 -4
- package/src/__tests__/deployContract.test.ts +429 -0
- package/src/__tests__/errors.test.ts +84 -0
- package/src/__tests__/fixtures/sigint-deploy-harness.ts +95 -0
- package/src/__tests__/fork/api.test.ts +143 -0
- package/src/__tests__/harness/Harness.createLive.test.ts +57 -0
- package/src/__tests__/harness/Harness.proxy.test.ts +111 -0
- package/src/__tests__/harness/_fixture.ts +131 -0
- package/src/__tests__/harness/codeObject.deploy.test.ts +319 -0
- package/src/__tests__/harness/codeObject.upgrade.test.ts +156 -0
- package/src/__tests__/harness/script.test.ts +245 -0
- package/src/__tests__/harness/view.test.ts +104 -0
- package/src/__tests__/runtime.test.ts +182 -0
- package/src/cli.ts +2 -1
- package/src/commands/__tests__/compile.test.ts +407 -0
- package/src/commands/__tests__/init.test.ts +125 -0
- package/src/commands/__tests__/run.test.ts +192 -0
- package/src/commands/__tests__/test-move.test.ts +81 -0
- package/src/commands/__tests__/test.test.ts +204 -0
- package/src/commands/__tests__/update.test.ts +223 -0
- package/src/commands/compile.ts +168 -32
- package/src/commands/fork/__tests__/create.test.ts +132 -0
- package/src/commands/fork/__tests__/fund.test.ts +104 -0
- package/src/commands/fork/__tests__/list.test.ts +139 -0
- package/src/commands/fork/__tests__/serve.test.ts +121 -0
- package/src/commands/fork/__tests__/view-resource.test.ts +101 -0
- package/src/commands/fork/create.ts +4 -3
- package/src/commands/fork/fund.ts +16 -9
- package/src/commands/fork/list.ts +3 -2
- package/src/commands/fork/serve.ts +6 -3
- package/src/commands/fork/view-resource.ts +11 -6
- package/src/commands/run.ts +54 -28
- package/src/commands/test-move.ts +4 -3
- package/src/commands/test.ts +56 -44
- package/src/commands/update.ts +19 -16
- package/src/core/AccountManager.ts +23 -22
- package/src/core/Publisher.ts +314 -0
- package/src/core/__tests__/AccountManager.test.ts +290 -0
- package/src/core/__tests__/config.test.ts +377 -0
- package/src/core/__tests__/deployments.test.ts +247 -0
- package/src/core/__tests__/shell.test.ts +138 -0
- package/src/core/config.ts +96 -12
- package/src/core/contract.ts +13 -7
- package/src/core/deployments.ts +13 -23
- package/src/core/movementProfile.ts +179 -0
- package/src/core/shell.ts +34 -14
- package/src/errors.ts +60 -0
- package/src/fork/__tests__/manager.test.ts +385 -0
- package/src/fork/__tests__/server.test.ts +65 -0
- package/src/fork/__tests__/storage.test.ts +281 -0
- package/src/fork/__tests__/test.test.ts +97 -0
- package/src/fork/api.ts +28 -14
- package/src/fork/manager.ts +88 -83
- package/src/fork/server.ts +53 -19
- package/src/fork/storage.ts +12 -15
- package/src/fork/test.ts +57 -32
- package/src/harness/Harness.ts +222 -0
- package/src/harness/codeObject.ts +384 -0
- package/src/harness/errors.ts +22 -0
- package/src/harness/index.ts +3 -0
- package/src/harness/proxy.ts +40 -0
- package/src/harness/script.ts +196 -0
- package/src/harness/view.ts +34 -0
- package/src/helpers/__tests__/semver-utils.test.ts +121 -0
- package/src/helpers/index.ts +2 -8
- package/src/helpers/move-tests.ts +27 -23
- package/src/helpers/npm-registry.ts +4 -3
- package/src/helpers/semver-utils.ts +4 -3
- package/src/helpers/setup.ts +6 -4
- package/src/helpers/setupLocalTesting.ts +218 -200
- package/src/helpers/testFixtures.ts +106 -118
- package/src/index.ts +8 -3
- package/src/node/LocalNodeManager.ts +87 -62
- package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
- package/src/runtime.ts +28 -288
- package/src/templates/README.md +1 -1
- package/src/templates/movehat.config.ts +10 -0
- package/src/templates/package.json +2 -1
- package/src/templates/scripts/deploy-counter.ts +46 -38
- package/src/templates/tests/Counter.test.ts +39 -51
- package/src/templates/types/movehat.d.ts +6 -9
- package/src/types/config.ts +8 -0
- package/src/types/fork.ts +7 -1
- package/src/types/harness.ts +182 -0
- package/src/types/runtime.ts +11 -3
- package/src/ui/__tests__/colors.test.ts +156 -0
- package/src/ui/colors.ts +5 -2
- package/src/ui/logger.ts +22 -0
- package/src/ui/symbols.ts +7 -1
- package/src/utils/__tests__/address.test.ts +93 -0
- package/src/utils/__tests__/childProcessAdapter.test.ts +266 -0
- package/src/utils/__tests__/runCli.test.ts +240 -0
- package/src/utils/address.ts +52 -0
- package/src/utils/childProcessAdapter.ts +214 -0
- package/src/utils/parseCliOutput.ts +27 -0
- package/src/utils/redact.ts +24 -0
- package/src/utils/runCli.ts +64 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CliExecutionError } from '../errors.js';
|
|
2
|
+
import { defaultChildProcessAdapter, } from './childProcessAdapter.js';
|
|
3
|
+
import { redactSecrets } from './redact.js';
|
|
4
|
+
export { redactSecrets } from './redact.js';
|
|
5
|
+
const STDOUT_PREVIEW_CHARS = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* Spawns a CLI command through the injectable adapter, redacts well-known
|
|
8
|
+
* secret shapes from stdout and stderr before returning, and throws
|
|
9
|
+
* `CliExecutionError` (with already-redacted payloads) on non-zero exits.
|
|
10
|
+
*
|
|
11
|
+
* Callers that need to inspect raw output should set `throwOnNonZeroExit:false`
|
|
12
|
+
* and consume the returned `RunResult` directly — fields are still redacted.
|
|
13
|
+
*
|
|
14
|
+
* Pass `input.inheritStdio: true` for interactive commands (mocha, tsx,
|
|
15
|
+
* package managers) where the user expects to see live output. Under that
|
|
16
|
+
* flag, `stdout` and `stderr` in the returned `RunResult` are empty strings
|
|
17
|
+
* (and so is `stdoutPreview` on any `CliExecutionError`), since the child
|
|
18
|
+
* writes directly to the terminal rather than to a captured buffer.
|
|
19
|
+
*/
|
|
20
|
+
export async function runCli(input, options = {}) {
|
|
21
|
+
const adapter = options.adapter ?? defaultChildProcessAdapter;
|
|
22
|
+
const throwOnNonZeroExit = options.throwOnNonZeroExit ?? true;
|
|
23
|
+
const raw = await adapter.run(input);
|
|
24
|
+
const result = {
|
|
25
|
+
exitCode: raw.exitCode,
|
|
26
|
+
stdout: redactSecrets(raw.stdout),
|
|
27
|
+
stderr: redactSecrets(raw.stderr),
|
|
28
|
+
};
|
|
29
|
+
if (raw.signal) {
|
|
30
|
+
result.signal = raw.signal;
|
|
31
|
+
}
|
|
32
|
+
if (result.exitCode !== 0 && throwOnNonZeroExit) {
|
|
33
|
+
throw new CliExecutionError(`Command failed with exit code ${result.exitCode}: ${input.command}`, input.command, input.args, result.exitCode, result.stderr, result.stdout.slice(0, STDOUT_PREVIEW_CHARS));
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=runCli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCli.js","sourceRoot":"","sources":["../../src/utils/runCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,0BAA0B,GAI3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,oBAAoB,GAAG,IAAI,CAAC;AASlC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,KAAe,EACf,UAAyB,EAAE;IAE3B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,0BAA0B,CAAC;IAC9D,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,IAAI,CAAC;IAE9D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,MAAM,GAAc;QACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QACjC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;KAClC,CAAC;IACF,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,kBAAkB,EAAE,CAAC;QAChD,MAAM,IAAI,iBAAiB,CACzB,iCAAiC,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,EACpE,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,IAAI,EACV,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAC7C,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "movehat",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Hardhat-like development framework for Movement L1
|
|
5
|
+
"description": "Hardhat-like development framework for Movement L1 smart contracts",
|
|
6
6
|
"bin": {
|
|
7
7
|
"movehat": "./bin/movehat.js"
|
|
8
8
|
},
|
|
@@ -21,6 +21,13 @@
|
|
|
21
21
|
"copy-templates": "cp -r src/templates dist/",
|
|
22
22
|
"dev": "tsc --watch",
|
|
23
23
|
"clean": "rm -rf dist",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"test:coverage": "vitest run --coverage",
|
|
27
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
28
|
+
"docs:api": "typedoc && node scripts/postprocess-typedoc.mjs",
|
|
29
|
+
"bench": "cd ../../examples/counter-example && tsx ../../packages/movehat/bench/fork.bench.ts",
|
|
30
|
+
"prepack": "cp ../../README.md README.md",
|
|
24
31
|
"prepublishOnly": "npm run build"
|
|
25
32
|
},
|
|
26
33
|
"files": [
|
|
@@ -38,7 +45,6 @@
|
|
|
38
45
|
},
|
|
39
46
|
"keywords": [
|
|
40
47
|
"move",
|
|
41
|
-
"aptos",
|
|
42
48
|
"movement",
|
|
43
49
|
"blockchain",
|
|
44
50
|
"smart-contracts",
|
|
@@ -68,6 +74,11 @@
|
|
|
68
74
|
"@types/js-yaml": "^4.0.9",
|
|
69
75
|
"@types/node": "^24.10.1",
|
|
70
76
|
"@types/prompts": "^2.4.9",
|
|
71
|
-
"
|
|
77
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
78
|
+
"memfs": "^4.51.1",
|
|
79
|
+
"typedoc": "^0.28.19",
|
|
80
|
+
"typedoc-plugin-markdown": "^4.11.0",
|
|
81
|
+
"typescript": "^5.9.3",
|
|
82
|
+
"vitest": "^4.0.16"
|
|
72
83
|
}
|
|
73
84
|
}
|
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
existsSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
mkdtempSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
rmSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
} from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { spawn } from "node:child_process";
|
|
15
|
+
import * as yaml from "js-yaml";
|
|
16
|
+
import { CliExecutionError } from "../errors.js";
|
|
17
|
+
import { initRuntime } from "../runtime.js";
|
|
18
|
+
import { Publisher } from "../core/Publisher.js";
|
|
19
|
+
import type { ChildProcessAdapter, RunInput, RunResult } from "../utils/childProcessAdapter.js";
|
|
20
|
+
|
|
21
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Guards against the bug-#43 leak path: when `movement move publish`
|
|
26
|
+
* echoes `ed25519-priv-…` material in stdout/stderr, neither the
|
|
27
|
+
* thrown error nor anything reaching `console.error` may carry the
|
|
28
|
+
* raw key. The redaction is structurally guaranteed by runCli today
|
|
29
|
+
* — these tests make the guarantee *directly* asserted so a future
|
|
30
|
+
* PR adding a non-runCli code path can't silently re-leak.
|
|
31
|
+
*/
|
|
32
|
+
describe("runtime.deployContract — secret redaction", () => {
|
|
33
|
+
let tmpHome: string;
|
|
34
|
+
let tmpCwd: string;
|
|
35
|
+
let origHome: string | undefined;
|
|
36
|
+
let origCwd: string;
|
|
37
|
+
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
tmpHome = mkdtempSync(join(tmpdir(), "movehat-test-home-"));
|
|
40
|
+
tmpCwd = mkdtempSync(join(tmpdir(), "movehat-test-cwd-"));
|
|
41
|
+
|
|
42
|
+
// Minimal movehat.config.js — testnet with no `accounts` means the
|
|
43
|
+
// auto-generated deterministic test key is used (config.ts:147-155).
|
|
44
|
+
writeFileSync(
|
|
45
|
+
join(tmpCwd, "movehat.config.js"),
|
|
46
|
+
`export default {
|
|
47
|
+
defaultNetwork: "testnet",
|
|
48
|
+
networks: {
|
|
49
|
+
testnet: {
|
|
50
|
+
url: "https://testnet.movementnetwork.xyz/v1",
|
|
51
|
+
chainId: "testnet"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
`
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// Minimal Move package layout. `extractNamedAddresses` reads
|
|
59
|
+
// <moveDir>/sources/*.move; the empty file produces an empty Set.
|
|
60
|
+
const moveDir = join(tmpCwd, "move");
|
|
61
|
+
mkdirSync(join(moveDir, "sources"), { recursive: true });
|
|
62
|
+
writeFileSync(
|
|
63
|
+
join(moveDir, "Move.toml"),
|
|
64
|
+
`[package]
|
|
65
|
+
name = "dummy"
|
|
66
|
+
version = "0.0.1"
|
|
67
|
+
|
|
68
|
+
[addresses]
|
|
69
|
+
`
|
|
70
|
+
);
|
|
71
|
+
writeFileSync(join(moveDir, "sources", "dummy.move"), "// intentionally empty\n");
|
|
72
|
+
|
|
73
|
+
origHome = process.env.HOME;
|
|
74
|
+
process.env.HOME = tmpHome;
|
|
75
|
+
origCwd = process.cwd();
|
|
76
|
+
process.chdir(tmpCwd);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
try {
|
|
81
|
+
process.chdir(origCwd);
|
|
82
|
+
} finally {
|
|
83
|
+
if (origHome === undefined) delete process.env.HOME;
|
|
84
|
+
else process.env.HOME = origHome;
|
|
85
|
+
if (existsSync(tmpHome)) rmSync(tmpHome, { recursive: true, force: true });
|
|
86
|
+
if (existsSync(tmpCwd)) rmSync(tmpCwd, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
function makeAdapter(steps: { build: RunResult; publish: RunResult }): {
|
|
91
|
+
adapter: ChildProcessAdapter;
|
|
92
|
+
calls: RunInput[];
|
|
93
|
+
} {
|
|
94
|
+
const calls: RunInput[] = [];
|
|
95
|
+
const adapter: ChildProcessAdapter = {
|
|
96
|
+
async run(input) {
|
|
97
|
+
calls.push(input);
|
|
98
|
+
// The args layout is `["move", "build" | "publish", ...rest]`.
|
|
99
|
+
if (input.args[1] === "build") return steps.build;
|
|
100
|
+
if (input.args[1] === "publish") return steps.publish;
|
|
101
|
+
throw new Error(`unexpected movement subcommand: ${input.args[1]}`);
|
|
102
|
+
},
|
|
103
|
+
spawn() {
|
|
104
|
+
throw new Error("spawn not used in deployContract tests");
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
return { adapter, calls };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
it("leak path #2 — rethrown error has redacted stderr (no raw ed25519-priv-)", async () => {
|
|
111
|
+
const rawKey = "ed25519-priv-0x" + "a".repeat(64);
|
|
112
|
+
const { adapter, calls } = makeAdapter({
|
|
113
|
+
build: { exitCode: 0, stdout: "build ok", stderr: "" },
|
|
114
|
+
publish: { exitCode: 1, stdout: "", stderr: `Movement publish failed: ${rawKey}` },
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const runtime = await initRuntime();
|
|
118
|
+
|
|
119
|
+
let captured: unknown;
|
|
120
|
+
try {
|
|
121
|
+
await runtime.deployContract("mymodule", { adapter });
|
|
122
|
+
} catch (err) {
|
|
123
|
+
captured = err;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
expect(captured).toBeInstanceOf(CliExecutionError);
|
|
127
|
+
const err = captured as CliExecutionError;
|
|
128
|
+
expect(err.stderr).toContain("***REDACTED***");
|
|
129
|
+
expect(err.stderr).not.toContain("ed25519-priv-");
|
|
130
|
+
expect(err.stderr).not.toContain(rawKey);
|
|
131
|
+
|
|
132
|
+
// Pin the call shape: build then publish, args reach the adapter un-quoted.
|
|
133
|
+
// A previous regression (shell-escape mismatch fixed in 511fd95) survived
|
|
134
|
+
// unit tests because no assertion checked what landed in `args`.
|
|
135
|
+
expect(calls).toHaveLength(2);
|
|
136
|
+
const [build, publish] = calls;
|
|
137
|
+
if (!build || !publish) throw new Error("expected 2 captured calls");
|
|
138
|
+
expect(build.command).toBe("movement");
|
|
139
|
+
expect(build.args.slice(0, 2)).toEqual(["move", "build"]);
|
|
140
|
+
expect(publish.args.slice(0, 2)).toEqual(["move", "publish"]);
|
|
141
|
+
for (const arg of [...build.args, ...publish.args]) {
|
|
142
|
+
expect(arg.startsWith("'")).toBe(false);
|
|
143
|
+
expect(arg.endsWith("'")).toBe(false);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Bonus: deployContract's finally block must have restored / removed the
|
|
147
|
+
// movement config file. If a future refactor breaks the finally, this
|
|
148
|
+
// assertion fires before any real damage.
|
|
149
|
+
expect(existsSync(join(tmpHome, ".aptos", "config.yaml"))).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("two concurrent deploys do not corrupt ~/.aptos/config.yaml (#37)", async () => {
|
|
153
|
+
// Pre-fix #37: both deploys overwrote ~/.aptos/config.yaml with the
|
|
154
|
+
// SAME profile name ("default" by default), then both restored
|
|
155
|
+
// independently. The second deploy's restore would overwrite the
|
|
156
|
+
// first's profile mid-publish → potential cross-contamination of
|
|
157
|
+
// private keys / accounts. Post-fix: each deploy uses a unique
|
|
158
|
+
// movehat-deploy-<uuid> profile name and only deletes its own key
|
|
159
|
+
// on cleanup. The user's other profiles never get touched.
|
|
160
|
+
//
|
|
161
|
+
// The mutex is what makes this safe — without it, the
|
|
162
|
+
// read-modify-write cycles would race and silently drop a profile.
|
|
163
|
+
|
|
164
|
+
// Seed the yaml with an unrelated user profile that MUST survive.
|
|
165
|
+
const aptosDir = join(tmpHome, ".aptos");
|
|
166
|
+
mkdirSync(aptosDir, { recursive: true });
|
|
167
|
+
const preExisting = {
|
|
168
|
+
profiles: {
|
|
169
|
+
user_main: {
|
|
170
|
+
private_key: "0x" + "1".repeat(64),
|
|
171
|
+
public_key: "0x" + "2".repeat(64),
|
|
172
|
+
account: "0x" + "3".repeat(64),
|
|
173
|
+
rest_url: "https://example.invalid/v1",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
const configPath = join(aptosDir, "config.yaml");
|
|
178
|
+
writeFileSync(configPath, yaml.dump(preExisting), { mode: 0o600 });
|
|
179
|
+
|
|
180
|
+
// Set up two Publisher instances with fake adapters that record their
|
|
181
|
+
// own --profile argument and inject a small delay on publish so the
|
|
182
|
+
// critical sections overlap.
|
|
183
|
+
function makeDelayedAdapter(label: string): {
|
|
184
|
+
adapter: ChildProcessAdapter;
|
|
185
|
+
captured: { publishCall?: RunInput };
|
|
186
|
+
} {
|
|
187
|
+
const captured: { publishCall?: RunInput } = {};
|
|
188
|
+
const adapter: ChildProcessAdapter = {
|
|
189
|
+
async run(input) {
|
|
190
|
+
if (input.args[1] === "build") {
|
|
191
|
+
return { exitCode: 0, stdout: `built ${label}`, stderr: "" };
|
|
192
|
+
}
|
|
193
|
+
if (input.args[1] === "publish") {
|
|
194
|
+
captured.publishCall = input;
|
|
195
|
+
// Hold the lock-protected critical section open long enough
|
|
196
|
+
// for the other deploy's addProfile to compete.
|
|
197
|
+
await new Promise((r) => setTimeout(r, 30));
|
|
198
|
+
return {
|
|
199
|
+
exitCode: 0,
|
|
200
|
+
stdout: `Transaction hash: 0x${"d".repeat(64)}`,
|
|
201
|
+
stderr: "",
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
throw new Error(`unexpected: ${input.args[1]}`);
|
|
205
|
+
},
|
|
206
|
+
spawn() {
|
|
207
|
+
throw new Error("spawn not used");
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
return { adapter, captured };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const a = makeDelayedAdapter("A");
|
|
214
|
+
const b = makeDelayedAdapter("B");
|
|
215
|
+
|
|
216
|
+
// Build a minimal config + account once via initRuntime, then call
|
|
217
|
+
// Publisher directly (bypasses the loadDeployment cache that would
|
|
218
|
+
// throw on the second deploy if both used moduleName "test").
|
|
219
|
+
const runtime = await initRuntime();
|
|
220
|
+
const { config, account } = runtime;
|
|
221
|
+
|
|
222
|
+
await Promise.all([
|
|
223
|
+
new Publisher({ adapter: a.adapter }).deploy({
|
|
224
|
+
moduleName: "concurrent_a",
|
|
225
|
+
config,
|
|
226
|
+
account,
|
|
227
|
+
packageDir: join(tmpCwd, "move"),
|
|
228
|
+
}),
|
|
229
|
+
new Publisher({ adapter: b.adapter }).deploy({
|
|
230
|
+
moduleName: "concurrent_b",
|
|
231
|
+
config,
|
|
232
|
+
account,
|
|
233
|
+
packageDir: join(tmpCwd, "move"),
|
|
234
|
+
}),
|
|
235
|
+
]);
|
|
236
|
+
|
|
237
|
+
// Both publish calls captured distinct --profile args.
|
|
238
|
+
const argsA = a.captured.publishCall!.args;
|
|
239
|
+
const argsB = b.captured.publishCall!.args;
|
|
240
|
+
const profileArgA = argsA[argsA.indexOf("--profile") + 1];
|
|
241
|
+
const profileArgB = argsB[argsB.indexOf("--profile") + 1];
|
|
242
|
+
expect(profileArgA).toMatch(/^movehat-deploy-/);
|
|
243
|
+
expect(profileArgB).toMatch(/^movehat-deploy-/);
|
|
244
|
+
expect(profileArgA).not.toBe(profileArgB);
|
|
245
|
+
|
|
246
|
+
// After both deploys finish, ~/.aptos/config.yaml contains the
|
|
247
|
+
// user's original profile and zero movehat-deploy-* profiles.
|
|
248
|
+
const finalYaml: any = yaml.load(readFileSync(configPath, "utf8"));
|
|
249
|
+
expect(finalYaml.profiles).toBeDefined();
|
|
250
|
+
expect(Object.keys(finalYaml.profiles)).toEqual(["user_main"]);
|
|
251
|
+
expect(finalYaml.profiles.user_main.private_key).toBe(
|
|
252
|
+
preExisting.profiles.user_main.private_key
|
|
253
|
+
);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("SIGINT mid-deploy cleans the profile from ~/.aptos/config.yaml (#36)", async () => {
|
|
257
|
+
// Pre-fix #36: between the yaml write (private key persisted) and the
|
|
258
|
+
// finally block, a SIGINT would skip cleanup and leave the user's
|
|
259
|
+
// private key sitting in ~/.aptos/config.yaml at mode 0o600.
|
|
260
|
+
// Post-fix: a sync signal handler runs synchronously before exit,
|
|
261
|
+
// removing the deploy's unique profile from the yaml.
|
|
262
|
+
//
|
|
263
|
+
// This test spawns a child process running a harness that drives
|
|
264
|
+
// Publisher.deploy() with a 3-second-delayed publish, then sends
|
|
265
|
+
// SIGINT mid-flight. Vitest's own process is unaffected because
|
|
266
|
+
// the SIGINT goes to the child.
|
|
267
|
+
|
|
268
|
+
// Seed an unrelated user profile that MUST survive.
|
|
269
|
+
const aptosDir = join(tmpHome, ".aptos");
|
|
270
|
+
mkdirSync(aptosDir, { recursive: true });
|
|
271
|
+
const configPath = join(aptosDir, "config.yaml");
|
|
272
|
+
writeFileSync(
|
|
273
|
+
configPath,
|
|
274
|
+
yaml.dump({
|
|
275
|
+
profiles: {
|
|
276
|
+
user_main: {
|
|
277
|
+
private_key: "0x" + "a".repeat(64),
|
|
278
|
+
public_key: "0x" + "b".repeat(64),
|
|
279
|
+
account: "0x" + "c".repeat(64),
|
|
280
|
+
rest_url: "https://example.invalid/v1",
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
}),
|
|
284
|
+
{ mode: 0o600 }
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const harnessPath = join(__dirname, "fixtures", "sigint-deploy-harness.ts");
|
|
288
|
+
// Resolve tsx's CLI binary by absolute path — the test's tmp cwd has
|
|
289
|
+
// no node_modules, so a bare `tsx` import would fail to resolve.
|
|
290
|
+
// `require.resolve("tsx")` returns the package's main (dist/loader.mjs);
|
|
291
|
+
// the binary is two levels up from there, in `<root>/dist/cli.mjs`
|
|
292
|
+
// (same trick `commands/run.ts:49-53` uses).
|
|
293
|
+
const tsxMain = require.resolve("tsx");
|
|
294
|
+
const tsxCliPath = join(dirname(dirname(tsxMain)), "dist", "cli.mjs");
|
|
295
|
+
const child = spawn(
|
|
296
|
+
process.execPath,
|
|
297
|
+
[tsxCliPath, harnessPath],
|
|
298
|
+
{
|
|
299
|
+
env: { ...process.env, HOME: tmpHome },
|
|
300
|
+
cwd: tmpCwd,
|
|
301
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// Wait for the harness to announce its unique profile name via stdout
|
|
306
|
+
// (it writes a JSON line `{"profile":"movehat-deploy-XXXX"}` just
|
|
307
|
+
// before entering the slow publish step).
|
|
308
|
+
let announced: string | undefined;
|
|
309
|
+
let stdoutBuf = "";
|
|
310
|
+
let stderrBuf = "";
|
|
311
|
+
child.stdout?.on("data", (chunk: Buffer) => {
|
|
312
|
+
stdoutBuf += chunk.toString();
|
|
313
|
+
for (const line of stdoutBuf.split("\n")) {
|
|
314
|
+
const trimmed = line.trim();
|
|
315
|
+
if (!trimmed.startsWith("{")) continue;
|
|
316
|
+
try {
|
|
317
|
+
const parsed = JSON.parse(trimmed);
|
|
318
|
+
if (typeof parsed.profile === "string") announced = parsed.profile;
|
|
319
|
+
} catch {
|
|
320
|
+
/* not a JSON line we care about */
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
child.stderr?.on("data", (c: Buffer) => (stderrBuf += c.toString()));
|
|
325
|
+
|
|
326
|
+
// Poll until the harness has announced OR 8s timeout (the import +
|
|
327
|
+
// SDK initialization can take a few seconds in CI/cold-start).
|
|
328
|
+
const start = Date.now();
|
|
329
|
+
while (!announced && Date.now() - start < 8000) {
|
|
330
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!announced) {
|
|
334
|
+
child.kill("SIGKILL");
|
|
335
|
+
throw new Error(
|
|
336
|
+
`harness never announced profile in 8s.\n` +
|
|
337
|
+
`stdout so far:\n${stdoutBuf}\n---\nstderr so far:\n${stderrBuf}`
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
expect(announced).toMatch(/^movehat-deploy-/);
|
|
342
|
+
|
|
343
|
+
// Deliver SIGINT mid-publish and wait for the harness to exit.
|
|
344
|
+
child.kill("SIGINT");
|
|
345
|
+
const exitCode = await new Promise<number | null>((resolve) => {
|
|
346
|
+
child.on("exit", (code) => resolve(code));
|
|
347
|
+
});
|
|
348
|
+
expect(exitCode).toBe(130);
|
|
349
|
+
|
|
350
|
+
// The yaml on disk contains the user's original profile and NO
|
|
351
|
+
// movehat-deploy-* leftovers.
|
|
352
|
+
expect(existsSync(configPath)).toBe(true);
|
|
353
|
+
const finalYaml: any = yaml.load(readFileSync(configPath, "utf8"));
|
|
354
|
+
expect(finalYaml.profiles).toBeDefined();
|
|
355
|
+
expect(Object.keys(finalYaml.profiles).sort()).toEqual(["user_main"]);
|
|
356
|
+
expect(finalYaml.profiles.user_main.private_key).toBe("0x" + "a".repeat(64));
|
|
357
|
+
}, 15000);
|
|
358
|
+
|
|
359
|
+
it("does not mutate Move.toml during deploy (#38)", async () => {
|
|
360
|
+
// Pre-fix #38: deployContract overwrote every entry under [addresses]
|
|
361
|
+
// with the deployer address, then relied on `finally` to restore.
|
|
362
|
+
// Post-fix: Move.toml is never touched — `--named-addresses` carries
|
|
363
|
+
// the overrides on the CLI line for both build and publish.
|
|
364
|
+
const moveTomlPath = join(tmpCwd, "move", "Move.toml");
|
|
365
|
+
const moveTomlContent = `[package]
|
|
366
|
+
name = "dummy"
|
|
367
|
+
version = "0.0.1"
|
|
368
|
+
|
|
369
|
+
[addresses]
|
|
370
|
+
counter = "0x42"
|
|
371
|
+
greeting = "0xcafe"
|
|
372
|
+
`;
|
|
373
|
+
writeFileSync(moveTomlPath, moveTomlContent);
|
|
374
|
+
|
|
375
|
+
// Move source that references "counter" so extractNamedAddresses picks
|
|
376
|
+
// it up — otherwise the --named-addresses arg is empty and the test
|
|
377
|
+
// is uninteresting.
|
|
378
|
+
writeFileSync(
|
|
379
|
+
join(tmpCwd, "move", "sources", "dummy.move"),
|
|
380
|
+
"module counter::dummy { }\n"
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const { adapter } = makeAdapter({
|
|
384
|
+
build: { exitCode: 0, stdout: "build ok", stderr: "" },
|
|
385
|
+
publish: {
|
|
386
|
+
exitCode: 0,
|
|
387
|
+
stdout: "Transaction hash: 0x" + "c".repeat(64),
|
|
388
|
+
stderr: "",
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
const runtime = await initRuntime();
|
|
393
|
+
await runtime.deployContract("counter", { adapter });
|
|
394
|
+
|
|
395
|
+
const after = readFileSync(moveTomlPath, "utf8");
|
|
396
|
+
expect(after).toBe(moveTomlContent);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it("leak path #1 — console.error on a noisy-but-successful publish never sees raw key", async () => {
|
|
400
|
+
const rawKey = "ed25519-priv-0x" + "a".repeat(64);
|
|
401
|
+
const { adapter } = makeAdapter({
|
|
402
|
+
build: { exitCode: 0, stdout: "build ok", stderr: "" },
|
|
403
|
+
// Publish succeeds (exitCode 0) but emits a stderr line containing the key.
|
|
404
|
+
publish: {
|
|
405
|
+
exitCode: 0,
|
|
406
|
+
stdout: "Transaction hash: 0x" + "b".repeat(64),
|
|
407
|
+
stderr: `warning: ${rawKey}`,
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const errSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
412
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
413
|
+
|
|
414
|
+
try {
|
|
415
|
+
const runtime = await initRuntime();
|
|
416
|
+
await runtime.deployContract("mymodule", { adapter });
|
|
417
|
+
|
|
418
|
+
const allErr = errSpy.mock.calls.flat().join("\n");
|
|
419
|
+
const allLog = logSpy.mock.calls.flat().join("\n");
|
|
420
|
+
expect(allErr).not.toContain("ed25519-priv-");
|
|
421
|
+
expect(allErr).not.toContain(rawKey);
|
|
422
|
+
expect(allLog).not.toContain("ed25519-priv-");
|
|
423
|
+
expect(allLog).not.toContain(rawKey);
|
|
424
|
+
} finally {
|
|
425
|
+
errSpy.mockRestore();
|
|
426
|
+
logSpy.mockRestore();
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { ModuleAlreadyDeployedError } from '../errors.js';
|
|
3
|
+
|
|
4
|
+
describe('ModuleAlreadyDeployedError', () => {
|
|
5
|
+
it('should create error with all properties', () => {
|
|
6
|
+
const error = new ModuleAlreadyDeployedError(
|
|
7
|
+
'Module "counter" is already deployed',
|
|
8
|
+
'counter',
|
|
9
|
+
'testnet',
|
|
10
|
+
'0x1234',
|
|
11
|
+
1704985623564,
|
|
12
|
+
'0xabcd'
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(error).toBeInstanceOf(Error);
|
|
16
|
+
expect(error).toBeInstanceOf(ModuleAlreadyDeployedError);
|
|
17
|
+
expect(error.name).toBe('ModuleAlreadyDeployedError');
|
|
18
|
+
expect(error.message).toBe('Module "counter" is already deployed');
|
|
19
|
+
expect(error.moduleName).toBe('counter');
|
|
20
|
+
expect(error.network).toBe('testnet');
|
|
21
|
+
expect(error.address).toBe('0x1234');
|
|
22
|
+
expect(error.timestamp).toBe(1704985623564);
|
|
23
|
+
expect(error.txHash).toBe('0xabcd');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should work without optional txHash', () => {
|
|
27
|
+
const error = new ModuleAlreadyDeployedError(
|
|
28
|
+
'Module already deployed',
|
|
29
|
+
'token',
|
|
30
|
+
'mainnet',
|
|
31
|
+
'0x5678',
|
|
32
|
+
1704985623564
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(error.moduleName).toBe('token');
|
|
36
|
+
expect(error.network).toBe('mainnet');
|
|
37
|
+
expect(error.txHash).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should have proper stack trace', () => {
|
|
41
|
+
const error = new ModuleAlreadyDeployedError(
|
|
42
|
+
'Test error',
|
|
43
|
+
'test',
|
|
44
|
+
'local',
|
|
45
|
+
'0x0',
|
|
46
|
+
Date.now()
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(error.stack).toBeDefined();
|
|
50
|
+
expect(error.stack).toContain('ModuleAlreadyDeployedError');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should be catchable as Error', () => {
|
|
54
|
+
const throwError = () => {
|
|
55
|
+
throw new ModuleAlreadyDeployedError(
|
|
56
|
+
'Test',
|
|
57
|
+
'module',
|
|
58
|
+
'testnet',
|
|
59
|
+
'0x1',
|
|
60
|
+
Date.now()
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
expect(throwError).toThrow(Error);
|
|
65
|
+
expect(throwError).toThrow(ModuleAlreadyDeployedError);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should allow instanceof checks', () => {
|
|
69
|
+
try {
|
|
70
|
+
throw new ModuleAlreadyDeployedError(
|
|
71
|
+
'Test',
|
|
72
|
+
'module',
|
|
73
|
+
'testnet',
|
|
74
|
+
'0x1',
|
|
75
|
+
Date.now()
|
|
76
|
+
);
|
|
77
|
+
} catch (e) {
|
|
78
|
+
expect(e instanceof ModuleAlreadyDeployedError).toBe(true);
|
|
79
|
+
if (e instanceof ModuleAlreadyDeployedError) {
|
|
80
|
+
expect(e.moduleName).toBe('module');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|