movehat 0.2.1 → 0.2.2

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.
Files changed (134) hide show
  1. package/dist/__tests__/deployContract.test.js +56 -47
  2. package/dist/__tests__/deployContract.test.js.map +1 -1
  3. package/dist/__tests__/exports.test.d.ts +2 -0
  4. package/dist/__tests__/exports.test.d.ts.map +1 -0
  5. package/dist/__tests__/exports.test.js +30 -0
  6. package/dist/__tests__/exports.test.js.map +1 -0
  7. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts +4 -3
  8. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts.map +1 -1
  9. package/dist/__tests__/fixtures/sigint-deploy-harness.js +8 -7
  10. package/dist/__tests__/fixtures/sigint-deploy-harness.js.map +1 -1
  11. package/dist/__tests__/fork/api.test.js +5 -0
  12. package/dist/__tests__/fork/api.test.js.map +1 -1
  13. package/dist/__tests__/fork/api.timeout.test.d.ts +2 -0
  14. package/dist/__tests__/fork/api.timeout.test.d.ts.map +1 -0
  15. package/dist/__tests__/fork/api.timeout.test.js +98 -0
  16. package/dist/__tests__/fork/api.timeout.test.js.map +1 -0
  17. package/dist/commands/__tests__/compile.toml-mutation.test.d.ts +2 -0
  18. package/dist/commands/__tests__/compile.toml-mutation.test.d.ts.map +1 -0
  19. package/dist/commands/__tests__/compile.toml-mutation.test.js +69 -0
  20. package/dist/commands/__tests__/compile.toml-mutation.test.js.map +1 -0
  21. package/dist/commands/__tests__/init.test.js +73 -11
  22. package/dist/commands/__tests__/init.test.js.map +1 -1
  23. package/dist/commands/init.d.ts +22 -0
  24. package/dist/commands/init.d.ts.map +1 -1
  25. package/dist/commands/init.js +55 -6
  26. package/dist/commands/init.js.map +1 -1
  27. package/dist/core/AccountManager.d.ts.map +1 -1
  28. package/dist/core/AccountManager.js +14 -2
  29. package/dist/core/AccountManager.js.map +1 -1
  30. package/dist/core/Publisher.d.ts.map +1 -1
  31. package/dist/core/Publisher.js +52 -68
  32. package/dist/core/Publisher.js.map +1 -1
  33. package/dist/core/__tests__/AccountManager.global-state.test.d.ts +2 -0
  34. package/dist/core/__tests__/AccountManager.global-state.test.d.ts.map +1 -0
  35. package/dist/core/__tests__/AccountManager.global-state.test.js +69 -0
  36. package/dist/core/__tests__/AccountManager.global-state.test.js.map +1 -0
  37. package/dist/core/__tests__/movementProfile.test.d.ts +2 -0
  38. package/dist/core/__tests__/movementProfile.test.d.ts.map +1 -0
  39. package/dist/core/__tests__/movementProfile.test.js +112 -0
  40. package/dist/core/__tests__/movementProfile.test.js.map +1 -0
  41. package/dist/core/config.js +6 -5
  42. package/dist/core/config.js.map +1 -1
  43. package/dist/core/movementProfile.d.ts +55 -22
  44. package/dist/core/movementProfile.d.ts.map +1 -1
  45. package/dist/core/movementProfile.js +77 -99
  46. package/dist/core/movementProfile.js.map +1 -1
  47. package/dist/fork/__tests__/server.cors.test.d.ts +2 -0
  48. package/dist/fork/__tests__/server.cors.test.d.ts.map +1 -0
  49. package/dist/fork/__tests__/server.cors.test.js +79 -0
  50. package/dist/fork/__tests__/server.cors.test.js.map +1 -0
  51. package/dist/fork/api.d.ts +9 -1
  52. package/dist/fork/api.d.ts.map +1 -1
  53. package/dist/fork/api.js +37 -7
  54. package/dist/fork/api.js.map +1 -1
  55. package/dist/fork/server.d.ts +20 -1
  56. package/dist/fork/server.d.ts.map +1 -1
  57. package/dist/fork/server.js +19 -9
  58. package/dist/fork/server.js.map +1 -1
  59. package/dist/harness/Harness.d.ts +6 -2
  60. package/dist/harness/Harness.d.ts.map +1 -1
  61. package/dist/harness/Harness.js +8 -2
  62. package/dist/harness/Harness.js.map +1 -1
  63. package/dist/harness/codeObject.d.ts.map +1 -1
  64. package/dist/harness/codeObject.js +30 -33
  65. package/dist/harness/codeObject.js.map +1 -1
  66. package/dist/harness/script.d.ts +3 -3
  67. package/dist/harness/script.d.ts.map +1 -1
  68. package/dist/harness/script.js +33 -29
  69. package/dist/harness/script.js.map +1 -1
  70. package/dist/helpers/__tests__/setupLocalTesting.fork-network.test.d.ts +2 -0
  71. package/dist/helpers/__tests__/setupLocalTesting.fork-network.test.d.ts.map +1 -0
  72. package/dist/helpers/__tests__/setupLocalTesting.fork-network.test.js +172 -0
  73. package/dist/helpers/__tests__/setupLocalTesting.fork-network.test.js.map +1 -0
  74. package/dist/helpers/setupLocalTesting.d.ts.map +1 -1
  75. package/dist/helpers/setupLocalTesting.js +28 -2
  76. package/dist/helpers/setupLocalTesting.js.map +1 -1
  77. package/dist/index.d.ts +1 -0
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/node/LocalNodeManager.d.ts +8 -0
  80. package/dist/node/LocalNodeManager.d.ts.map +1 -1
  81. package/dist/node/LocalNodeManager.js +10 -1
  82. package/dist/node/LocalNodeManager.js.map +1 -1
  83. package/dist/node/__tests__/LocalNodeManager.api-port.test.d.ts +2 -0
  84. package/dist/node/__tests__/LocalNodeManager.api-port.test.d.ts.map +1 -0
  85. package/dist/node/__tests__/LocalNodeManager.api-port.test.js +55 -0
  86. package/dist/node/__tests__/LocalNodeManager.api-port.test.js.map +1 -0
  87. package/dist/node/__tests__/LocalNodeManager.test.js +4 -3
  88. package/dist/node/__tests__/LocalNodeManager.test.js.map +1 -1
  89. package/dist/templates/move/Move.toml +1 -1
  90. package/dist/templates/move/sources/Counter.move +31 -4
  91. package/dist/templates/scripts/deploy-counter.ts +10 -0
  92. package/dist/types/config.d.ts +8 -1
  93. package/dist/types/config.d.ts.map +1 -1
  94. package/dist/utils/__tests__/childProcessAdapter.maxBuffer.test.d.ts +2 -0
  95. package/dist/utils/__tests__/childProcessAdapter.maxBuffer.test.d.ts.map +1 -0
  96. package/dist/utils/__tests__/childProcessAdapter.maxBuffer.test.js +43 -0
  97. package/dist/utils/__tests__/childProcessAdapter.maxBuffer.test.js.map +1 -0
  98. package/dist/utils/childProcessAdapter.d.ts +7 -0
  99. package/dist/utils/childProcessAdapter.d.ts.map +1 -1
  100. package/dist/utils/childProcessAdapter.js +20 -2
  101. package/dist/utils/childProcessAdapter.js.map +1 -1
  102. package/package.json +1 -1
  103. package/src/__tests__/deployContract.test.ts +59 -50
  104. package/src/__tests__/exports.test.ts +32 -0
  105. package/src/__tests__/fixtures/sigint-deploy-harness.ts +8 -7
  106. package/src/__tests__/fork/api.test.ts +5 -0
  107. package/src/__tests__/fork/api.timeout.test.ts +150 -0
  108. package/src/commands/__tests__/compile.toml-mutation.test.ts +77 -0
  109. package/src/commands/__tests__/init.test.ts +96 -11
  110. package/src/commands/init.ts +77 -6
  111. package/src/core/AccountManager.ts +18 -1
  112. package/src/core/Publisher.ts +58 -77
  113. package/src/core/__tests__/AccountManager.global-state.test.ts +83 -0
  114. package/src/core/__tests__/movementProfile.test.ts +131 -0
  115. package/src/core/config.ts +9 -5
  116. package/src/core/movementProfile.ts +75 -127
  117. package/src/fork/__tests__/server.cors.test.ts +101 -0
  118. package/src/fork/api.ts +69 -10
  119. package/src/fork/server.ts +38 -9
  120. package/src/harness/Harness.ts +11 -2
  121. package/src/harness/codeObject.ts +37 -43
  122. package/src/harness/script.ts +40 -39
  123. package/src/helpers/__tests__/setupLocalTesting.fork-network.test.ts +212 -0
  124. package/src/helpers/setupLocalTesting.ts +36 -2
  125. package/src/index.ts +9 -1
  126. package/src/node/LocalNodeManager.ts +24 -2
  127. package/src/node/__tests__/LocalNodeManager.api-port.test.ts +62 -0
  128. package/src/node/__tests__/LocalNodeManager.test.ts +4 -3
  129. package/src/templates/move/Move.toml +1 -1
  130. package/src/templates/move/sources/Counter.move +31 -4
  131. package/src/templates/scripts/deploy-counter.ts +10 -0
  132. package/src/types/config.ts +8 -1
  133. package/src/utils/__tests__/childProcessAdapter.maxBuffer.test.ts +51 -0
  134. package/src/utils/childProcessAdapter.ts +32 -2
@@ -126,17 +126,18 @@ describe("LocalNodeManager — start / stop / lifecycle", () => {
126
126
  expect(info.testDir).toBe(tmpDir);
127
127
  });
128
128
 
129
- it("honors custom ports from constructor options", () => {
129
+ it("honors custom faucet/ready ports; apiPort is pinned to 8080 (see F9)", () => {
130
130
  const { adapter } = buildFakeAdapter();
131
131
  const mgr = new LocalNodeManager({
132
132
  adapter,
133
133
  testDir: tmpDir,
134
- apiPort: 9000,
135
134
  faucetPort: 9001,
136
135
  readyPort: 9002,
137
136
  });
138
137
  const info = mgr.getNodeInfo();
139
- expect(info.rpcUrl).toContain(":9000");
138
+ // Movement CLI does not accept a flag for the REST API port; see
139
+ // LocalNodeManager.api-port.test.ts for the F9 contract.
140
+ expect(info.rpcUrl).toBe("http://127.0.0.1:8080");
140
141
  expect(info.faucetUrl).toContain(":9001");
141
142
  expect(info.readyUrl).toContain(":9002");
142
143
  });
@@ -1,5 +1,5 @@
1
1
  [package]
2
- name = "{{projectName}}"
2
+ name = "{{movePackageName}}"
3
3
  version = "1.0.0"
4
4
  authors = []
5
5
 
@@ -33,7 +33,16 @@ module counter::counter {
33
33
 
34
34
  public entry fun increment(account: &signer) acquires Counter {
35
35
  let account_addr = signer::address_of(account);
36
- assert!(exists<Counter>(account_addr), E_NOT_INITIALIZED);
36
+
37
+ // Auto-init: create Counter if it doesn't exist yet. Defense in
38
+ // depth so the module stays usable even if a caller skips the
39
+ // dedicated `init` entry function.
40
+ if (!exists<Counter>(account_addr)) {
41
+ move_to(account, Counter {
42
+ value: 0,
43
+ increment_events: account::new_event_handle<IncrementEvent>(account),
44
+ });
45
+ };
37
46
 
38
47
  let counter = borrow_global_mut<Counter>(account_addr);
39
48
  let old_value = counter.value;
@@ -56,14 +65,32 @@ module counter::counter {
56
65
  public fun test_increment(account: &signer) acquires Counter {
57
66
  let addr = signer::address_of(account);
58
67
  aptos_framework::account::create_account_for_test(addr);
59
-
68
+
60
69
  init(account);
61
70
  assert!(get(addr) == 0, 0);
62
-
71
+
63
72
  increment(account);
64
73
  assert!(get(addr) == 1, 1);
65
-
74
+
66
75
  increment(account);
67
76
  assert!(get(addr) == 2, 2);
68
77
  }
78
+
79
+ // Regression guard: increment must auto-create the Counter resource
80
+ // when called against a never-initialized account. Locks the
81
+ // defense-in-depth behavior so a future refactor can't accidentally
82
+ // remove it.
83
+ #[test(account = @0x2)]
84
+ public fun test_increment_auto_inits(account: &signer) acquires Counter {
85
+ let addr = signer::address_of(account);
86
+ aptos_framework::account::create_account_for_test(addr);
87
+
88
+ // Skip init entirely — increment must create the resource.
89
+ increment(account);
90
+ assert!(get(addr) == 1, 0);
91
+
92
+ // Idempotent: a second increment uses the now-existing resource.
93
+ increment(account);
94
+ assert!(get(addr) == 2, 1);
95
+ }
69
96
  }
@@ -31,6 +31,16 @@ async function main() {
31
31
  // Interact with the freshly deployed module via the runtime helper.
32
32
  const counter = harness.runtime.getContract(deployment.address, "counter");
33
33
 
34
+ // Counter is a Move resource — it must be created explicitly per
35
+ // account before any method that reads or mutates it. The dedicated
36
+ // `init` entry function does this once per signer. (The module also
37
+ // auto-inits inside `increment` as defense in depth, so this call is
38
+ // technically optional today, but kept for pedagogy: real-world Move
39
+ // modules usually require an explicit init step.)
40
+ console.log("\nšŸ”§ Initializing counter resource for this account...");
41
+ const initTx = await counter.call(harness.runtime.account, "init", []);
42
+ console.log(` Init tx: ${initTx.hash}`);
43
+
34
44
  console.log("\nšŸ“ Incrementing counter...");
35
45
  const txResult = await counter.call(harness.runtime.account, "increment", []);
36
46
  console.log(`āœ… Transaction hash: ${txResult.hash}`);
@@ -55,7 +55,14 @@ export interface LocalTestOptions {
55
55
  nodeSilent?: boolean; // Suppress node output (default: false)
56
56
 
57
57
  // Fork options (when mode='fork')
58
- forkNetwork?: 'testnet' | string; // Network to fork from (default: 'testnet')
58
+ forkNetwork?: 'testnet' | 'mainnet' | string; // Network to fork from (default: 'testnet')
59
+ /**
60
+ * RPC URL override used when forking a non-built-in network.
61
+ * Required when `forkNetwork` is not one of the built-in names
62
+ * (`'testnet'`, `'mainnet'`). Ignored when a fork already exists
63
+ * on disk (the saved metadata's nodeUrl is reused).
64
+ */
65
+ forkRpcUrl?: string;
59
66
  forkName?: string; // Name for the fork (default: 'test-local')
60
67
  forkPort?: number; // Fork server port (default: 8080)
61
68
  forkResetState?: boolean; // Clear fork state before tests (default: true)
@@ -0,0 +1,51 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { defaultChildProcessAdapter } from "../childProcessAdapter.js";
3
+
4
+ /**
5
+ * F4 — `run()` must reject when child output exceeds `maxBuffer`.
6
+ *
7
+ * Without this cap, the stdout/stderr Buffer arrays in
8
+ * DefaultChildProcessAdapter grow without limit. A buggy or hostile
9
+ * subprocess can OOM the parent process. F4 adds an opt-in byte cap
10
+ * with kill-on-overflow semantics.
11
+ */
12
+
13
+ const NODE = process.execPath;
14
+
15
+ describe("F4 — ChildProcessAdapter.run maxBuffer", () => {
16
+ it("rejects with a maxBuffer error when stdout exceeds the cap", async () => {
17
+ // 8KiB of output, cap at 1KiB → must abort.
18
+ const script = `process.stdout.write('x'.repeat(8 * 1024)); setTimeout(() => {}, 30000);`;
19
+ await expect(
20
+ defaultChildProcessAdapter.run({
21
+ command: NODE,
22
+ args: ["-e", script],
23
+ maxBuffer: 1024,
24
+ timeoutMs: 10_000,
25
+ })
26
+ ).rejects.toThrow(/maxBuffer|exceeded/i);
27
+ });
28
+
29
+ it("rejects with a maxBuffer error when stderr exceeds the cap", async () => {
30
+ const script = `process.stderr.write('y'.repeat(8 * 1024)); setTimeout(() => {}, 30000);`;
31
+ await expect(
32
+ defaultChildProcessAdapter.run({
33
+ command: NODE,
34
+ args: ["-e", script],
35
+ maxBuffer: 1024,
36
+ timeoutMs: 10_000,
37
+ })
38
+ ).rejects.toThrow(/maxBuffer|exceeded/i);
39
+ });
40
+
41
+ it("does NOT throw when output stays under the cap", async () => {
42
+ const script = `process.stdout.write('ok'); process.exit(0);`;
43
+ const result = await defaultChildProcessAdapter.run({
44
+ command: NODE,
45
+ args: ["-e", script],
46
+ maxBuffer: 1024,
47
+ });
48
+ expect(result.exitCode).toBe(0);
49
+ expect(result.stdout).toBe("ok");
50
+ });
51
+ });
@@ -38,8 +38,17 @@ export interface RunInput {
38
38
  * Default: `false`.
39
39
  */
40
40
  inheritStdio?: boolean;
41
+ /**
42
+ * Maximum combined bytes (stdout + stderr) the captured Buffers may
43
+ * grow to before the child is killed and the promise rejects. Defaults
44
+ * to 64 MiB. Set to `Infinity` to disable. Ignored when
45
+ * `inheritStdio` is `true` (no buffering happens).
46
+ */
47
+ maxBuffer?: number;
41
48
  }
42
49
 
50
+ const DEFAULT_MAX_BUFFER = 64 * 1024 * 1024;
51
+
43
52
  export interface RunResult {
44
53
  /**
45
54
  * Numeric exit code from the child. `-1` when the child was terminated by
@@ -114,10 +123,31 @@ class DefaultChildProcessAdapter implements ChildProcessAdapter {
114
123
 
115
124
  const stdoutChunks: Buffer[] = [];
116
125
  const stderrChunks: Buffer[] = [];
126
+ let totalBytes = 0;
127
+ let overflowed = false;
128
+ const maxBuffer = input.maxBuffer ?? DEFAULT_MAX_BUFFER;
129
+
130
+ const onChunk = (chunks: Buffer[]) => (chunk: Buffer) => {
131
+ if (overflowed) return;
132
+ totalBytes += chunk.length;
133
+ if (totalBytes > maxBuffer) {
134
+ overflowed = true;
135
+ clearTimer();
136
+ input.signal?.removeEventListener('abort', onAbort);
137
+ child.kill('SIGTERM');
138
+ reject(
139
+ new Error(
140
+ `Command output exceeded maxBuffer (${maxBuffer} bytes): ${input.command}`
141
+ )
142
+ );
143
+ return;
144
+ }
145
+ chunks.push(chunk);
146
+ };
117
147
 
118
148
  // Streams are null when stdio is 'inherit'; the `?.` covers that.
119
- child.stdout?.on('data', (chunk: Buffer) => stdoutChunks.push(chunk));
120
- child.stderr?.on('data', (chunk: Buffer) => stderrChunks.push(chunk));
149
+ child.stdout?.on('data', onChunk(stdoutChunks));
150
+ child.stderr?.on('data', onChunk(stderrChunks));
121
151
 
122
152
  let timeoutHandle: NodeJS.Timeout | undefined;
123
153
  const clearTimer = () => {