@zktx.io/sui-move-builder 0.1.7 → 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 +62 -4
- package/dist/full/index.cjs +28 -0
- package/dist/{index.d.cts → full/index.d.cts} +19 -3
- package/dist/{index.d.ts → full/index.d.ts} +19 -3
- package/dist/full/index.js +28 -0
- package/dist/full/sui_move_wasm.d.ts +69 -0
- package/dist/full/sui_move_wasm.js +364 -0
- package/dist/full/sui_move_wasm_bg.wasm +0 -0
- package/dist/full/sui_move_wasm_bg.wasm.d.ts +18 -0
- package/dist/lite/index.cjs +28 -0
- package/dist/lite/index.d.cts +149 -0
- package/dist/lite/index.d.ts +149 -0
- package/dist/lite/index.js +28 -0
- package/dist/lite/sui_move_wasm.d.ts +54 -0
- package/dist/{sui_move_wasm.js → lite/sui_move_wasm.js} +149 -151
- package/dist/lite/sui_move_wasm_bg.wasm +0 -0
- package/dist/{sui_move_wasm_bg.wasm.d.ts → lite/sui_move_wasm_bg.wasm.d.ts} +5 -6
- package/package.json +14 -6
- package/dist/index.cjs +0 -28
- package/dist/index.js +0 -28
- package/dist/sui_move_wasm.d.ts +0 -57
- package/dist/sui_move_wasm_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @zktx.io/sui-move-builder
|
|
2
2
|
|
|
3
|
+
> **Upstream source:** [MystenLabs/sui](https://github.com/MystenLabs/sui) (tag: `testnet-v1.63.1`)
|
|
4
|
+
|
|
3
5
|
Build Move packages in web or Node.js with Sui CLI-compatible dependency resolution and compilation.
|
|
4
6
|
|
|
5
7
|
## Features
|
|
@@ -19,6 +21,32 @@ Build Move packages in web or Node.js with Sui CLI-compatible dependency resolut
|
|
|
19
21
|
npm install @zktx.io/sui-move-builder
|
|
20
22
|
```
|
|
21
23
|
|
|
24
|
+
## Lite vs Full Version
|
|
25
|
+
|
|
26
|
+
The package comes in two variants:
|
|
27
|
+
|
|
28
|
+
1. **Full Version (Default)**: ~12MB. Includes `move-unit-test`, `sui-move-natives`, and testing capabilities.
|
|
29
|
+
2. **Lite Version**: ~5.1MB. Build-only. **Recommended for frontend applications** where testing infrastructure is not needed.
|
|
30
|
+
|
|
31
|
+
### Using the Full Version (Default)
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import {
|
|
35
|
+
initMoveCompiler,
|
|
36
|
+
buildMovePackage,
|
|
37
|
+
testMovePackage,
|
|
38
|
+
} from "@zktx.io/sui-move-builder";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Using the Lite Version
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
initMoveCompiler,
|
|
46
|
+
buildMovePackage,
|
|
47
|
+
} from "@zktx.io/sui-move-builder/lite";
|
|
48
|
+
```
|
|
49
|
+
|
|
22
50
|
## Quick start (Node.js or browser)
|
|
23
51
|
|
|
24
52
|
```ts
|
|
@@ -49,6 +77,12 @@ const result = await buildMovePackage({
|
|
|
49
77
|
files,
|
|
50
78
|
// optional: bump GitHub API limits during dependency resolution
|
|
51
79
|
githubToken: process.env.GITHUB_TOKEN,
|
|
80
|
+
// optional: silence warnings from Move compiler
|
|
81
|
+
silenceWarnings: true,
|
|
82
|
+
// optional: enable test mode (include #[test_only] modules)
|
|
83
|
+
testMode: false,
|
|
84
|
+
// optional: set linting level (default: "all")
|
|
85
|
+
lintFlag: "all",
|
|
52
86
|
});
|
|
53
87
|
|
|
54
88
|
if (result.success) {
|
|
@@ -123,6 +157,19 @@ if (result.success) {
|
|
|
123
157
|
}
|
|
124
158
|
```
|
|
125
159
|
|
|
160
|
+
## Package Management Logic
|
|
161
|
+
|
|
162
|
+
This builder follows the official Sui CLI precedence rules for package management:
|
|
163
|
+
|
|
164
|
+
1. **CLI Overrides**: Explicit options (e.g., `network`) take highest precedence.
|
|
165
|
+
2. **Move.lock**: If present and valid, dependencies are resolved exactly as pinned in the lockfile. This ensures deterministic builds.
|
|
166
|
+
- The addresses of dependencies (e.g., `Sui`, `Std`) are determined by the lockfile's `[move.package.addresses]` section for the active environment (e.g., `devnet`, `mainnet`).
|
|
167
|
+
3. **Move.toml**: Used if no lockfile exists or if it is invalid. Defines direct dependencies and their sources.
|
|
168
|
+
4. **Published.toml**:
|
|
169
|
+
- Used to resolve the `published-at` address (original ID) for the root package if available.
|
|
170
|
+
- **Does not** override dependency resolution; it is primarily an output record of deployment.
|
|
171
|
+
- If a package is listed in `Published.toml` with a matching `id`, the builder uses that ID for linking, similar to how the Sui CLI handles upgrades.
|
|
172
|
+
|
|
126
173
|
## Dependency caching and reuse
|
|
127
174
|
|
|
128
175
|
For faster builds when compiling multiple times with the same dependencies, you can resolve dependencies once and reuse them:
|
|
@@ -174,13 +221,24 @@ const result2 = await buildMovePackage({
|
|
|
174
221
|
|
|
175
222
|
- Dependencies are always compiled from source. Bytecode-only deps (.mv fallback used by the Sui CLI when sources are missing) are not supported in the wasm path.
|
|
176
223
|
|
|
224
|
+
## Best Practices
|
|
225
|
+
|
|
226
|
+
### Input Sanitization
|
|
227
|
+
|
|
228
|
+
When preparing the `files` object for `buildMovePackage`, **exclude build artifacts** (e.g., the `build/` directory) and version control folders (`.git/`). Including these can cause:
|
|
229
|
+
|
|
230
|
+
- **Compilation Errors**: Duplicate modules or incorrect edition parsing (e.g., dependency files treated as root sources).
|
|
231
|
+
- **Performance Issues**: Unnecessary processing of large binary files.
|
|
232
|
+
|
|
233
|
+
Example filtering logic:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
if (entry.name === "build" || entry.name === ".git") continue;
|
|
237
|
+
```
|
|
238
|
+
|
|
177
239
|
## Local test page
|
|
178
240
|
|
|
179
241
|
```
|
|
180
242
|
npm run serve:test # serves ./test via python -m http.server
|
|
181
243
|
# open http://localhost:8000/test/index.html
|
|
182
244
|
```
|
|
183
|
-
|
|
184
|
-
## Source
|
|
185
|
-
|
|
186
|
-
> **Upstream source (Sui repository):** https://github.com/MystenLabs/sui
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";var E=Object.create;var R=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var H=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var J=(d,e)=>{for(var t in e)R(d,t,{get:e[t],enumerable:!0})},G=(d,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of V(e))!q.call(d,n)&&n!==t&&R(d,n,{get:()=>e[n],enumerable:!(s=z(e,n))||s.enumerable});return d};var K=(d,e,t)=>(t=d!=null?E(H(d)):{},G(e||!d||!d.__esModule?R(t,"default",{value:d,enumerable:!0}):t,d)),Q=d=>G(R({},"__esModule",{value:!0}),d);var ae={};J(ae,{buildMovePackage:()=>te,compileRaw:()=>oe,fetchPackageFromGitHub:()=>_,getSuiMoveVersion:()=>se,getSuiVersion:()=>ie,getWasmBindings:()=>re,initMoveCompiler:()=>ee,resolveDependencies:()=>L,testMovePackage:()=>ne});module.exports=Q(ae);var x=class{async fetch(e,t,s){throw new Error("Not implemented")}async fetchFile(e,t,s){throw new Error("Not implemented")}},S=class extends x{constructor(t){super();this.rateLimitRemaining=60;this.rateLimitReset=0;this.cache=new Map,this.treeCache=new Map,this.token=t}updateRateLimit(t){let s=t.headers.get("x-ratelimit-remaining"),n=t.headers.get("x-ratelimit-reset");s&&(this.rateLimitRemaining=parseInt(s,10)),n&&(this.rateLimitReset=parseInt(n,10)*1e3)}async fetch(t,s,n,i){let{owner:r,repo:c}=this.parseGitUrl(t);if(!r||!c)throw new Error(`Invalid git URL: ${t}`);let a=`${r}/${c}@${s}`,u=`https://api.github.com/repos/${r}/${c}/git/trees/${s}?recursive=1`,o;if(this.treeCache.has(a))o=this.treeCache.get(a);else{let p=null;for(let h=1;h<=3;h++)try{if(h>1){let k=Math.pow(2,h-1)*1e3;await new Promise(v=>setTimeout(v,k))}let y={};this.token&&(y.Authorization=`Bearer ${this.token}`);let m=await fetch(u,{headers:y});if(this.updateRateLimit(m),!m.ok){if(m.status===403||m.status===429){let k=new Date(this.rateLimitReset);throw new Error(`GitHub API rate limit exceeded. Resets at ${k.toLocaleTimeString()}`)}if(m.status>=500&&m.status<600&&h<3){p=new Error(`Failed to fetch tree: ${m.statusText}`);continue}throw new Error(`Failed to fetch tree: ${m.statusText}`)}o=await m.json(),this.treeCache.set(a,o);break}catch(y){if(p=y instanceof Error?y:new Error(String(y)),h===3)return{}}if(p)return{}}let g={},f=[];for(let l of o.tree){if(l.type!=="blob")continue;let p=l.path;if(n){if(!l.path.startsWith(n))continue;p=l.path.slice(n.length),p.startsWith("/")&&(p=p.slice(1))}if(!p.endsWith(".move")&&p!=="Move.toml"&&p!=="Move.lock"&&!p.match(/^Move\.(mainnet|testnet|devnet)\.toml$/))continue;let h=`https://raw.githubusercontent.com/${r}/${c}/${s}/${l.path}`,y=this.fetchContent(h).then(m=>{m&&(g[p]=m)});f.push(y)}if(await Promise.all(f),g["Move.toml"]){let l=g["Move.toml"].trim();if(l.match(/^Move\.(mainnet|testnet|devnet)\.toml$/)&&!l.includes("[")&&!l.includes("=")){let p=l,h=n?`${n}/${p}`.replace(/\/+/g,"/"):p,y=`https://raw.githubusercontent.com/${r}/${c}/${s}/${h}`,m=await this.fetchContent(y);m&&(g["Move.toml"]=m,g[p]=m)}}return g}async fetchFile(t,s,n){let{owner:i,repo:r}=this.parseGitUrl(t);if(!i||!r)throw new Error(`Invalid git URL: ${t}`);let c=`https://raw.githubusercontent.com/${i}/${r}/${s}/${n}`;return this.fetchContent(c)}async fetchContent(t){if(this.cache.has(t))return this.cache.get(t)??null;try{let s={},n=typeof window<"u",i=t.startsWith("https://api.github.com/");this.token&&(!n||i)&&(s.Authorization=`Bearer ${this.token}`);let r=await fetch(t,{headers:s});if(!r.ok)return null;let c=await r.text();return this.cache.set(t,c),c}catch{return null}}parseGitUrl(t){try{let n=new URL(t).pathname.split("/").filter(i=>i);if(n.length>=2){let i=n[1];return i.endsWith(".git")&&(i=i.slice(0,-4)),{owner:n[0],repo:i}}}catch{}return{owner:null,repo:null}}};function M(d){let e=!1,t="";for(let s=0;s<d.length;s++){let n=d[s];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return d.slice(0,s)}return d}function F(d){let e=d.trim();if(!e)return"";if(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))return e.slice(1,-1);if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return Number.isNaN(t)?e:t}function B(d){let e={},t=d.trim().replace(/^\{/,"").replace(/\}$/,""),s="",n=!1,i="",r=[];for(let c=0;c<t.length;c++){let a=t[c];if((a==='"'||a==="'")&&(!n||a===i)&&(n=!n,i=a),!n&&a===","){r.push(s),s="";continue}s+=a}s.trim()&&r.push(s);for(let c of r){let a=c.indexOf("=");if(a===-1)continue;let u=c.slice(0,a).trim(),o=c.slice(a+1).trim();e[u]=F(o)}return e}function X(d){let e=[],t=d.trim().replace(/^\[/,"").replace(/\]$/,""),s="",n=!1,i="",r=0;for(let c=0;c<t.length;c++){let a=t[c];if((a==='"'||a==="'")&&(!n||a===i)&&(n=!n,i=n?a:""),!n&&(a==="{"&&r++,a==="}"&&r--,a===","&&r===0)){s.trim()&&e.push(C(s.trim())),s="";continue}s+=a}return s.trim()&&e.push(C(s.trim())),e}function C(d){return d.startsWith("{")?B(d):F(d)}function w(d){let e={},t=null,s=!1,n=d.split(/\r?\n/),i=[],r=0;for(;r<n.length;){let a=M(n[r]);if(a.match(/=\s*\[\s*$/)||a.includes("=")&&a.includes("[")&&!a.includes("]")){let u=a;for(r++;r<n.length&&!u.includes("]");)u+=" "+M(n[r]).trim(),r++;r<n.length&&u.includes("[")&&!u.includes("]")&&(u+=" "+M(n[r]).trim(),r++),i.push(u)}else i.push(a),r++}function c(a,u){let o=a;for(let g of u){if(!(g in o))return;o=o[g]}return o}for(let a of i){let u=M(a).trim();if(!u)continue;let o=u.match(/^\[\[([^\]]+)\]\]$/);if(o){t=o[1].trim(),s=!0;let y=t.split("."),m=e;for(let v=0;v<y.length-1;v++){let b=y[v];b in m||(m[b]={}),m=m[b]}let k=y[y.length-1];Array.isArray(m[k])||(m[k]=[]),m[k].push({});continue}let g=u.match(/^\[([^\]]+)\]$/);if(g){t=g[1].trim(),s=!1;continue}let f=u.indexOf("=");if(f===-1||!t)continue;let l=u.slice(0,f).trim(),p=u.slice(f+1).trim(),h;if(p.startsWith("{")?h=B(p):p.startsWith("[")?h=X(p):h=F(p),s){let y=t.split("."),m=c(e,y);if(Array.isArray(m)&&m.length>0){let k=m[m.length-1];k[l]=h}}else{let y=t.split("."),m=e;for(let v of y)v in m||(m[v]={}),m=m[v];let k=t==="package"?l.replace(/-/g,"_"):l;m[k]=h}}return e}var D=class{constructor(e){this.packageTable=new Map;this.graph=new Map;this.alwaysDeps=new Set(["Sui","MoveStdlib","SuiSystem","Bridge"]);this.lockfileOrder=[];this.root=e}setLockfileOrder(e){this.lockfileOrder=e}addPackage(e){this.packageTable.set(e.id.name,e),this.graph.has(e.id.name)||this.graph.set(e.id.name,new Set)}addDependency(e,t,s){this.graph.has(e)||this.graph.set(e,new Set),this.graph.get(e).add(t)}getPackage(e){return this.packageTable.get(e)}getAllPackages(){return Array.from(this.packageTable.values())}getImmediateDependencies(e){return this.graph.get(e)||new Set}getTransitiveDependencies(e){let t=new Set,s=new Set,n=i=>{if(s.has(i))return;s.add(i),t.add(i);let r=this.graph.get(i);if(r)for(let c of r)n(c)};return n(e),t.delete(e),t}topologicalOrder(){if(!this.lockfileOrder.length)return this.topologicalOrderDFS().filter(r=>r!==this.root);let e=new Set,t=new Set,s=i=>{if(t.has(i))return;t.add(i),e.add(i);let r=this.graph.get(i);if(r)for(let c of r)s(c)};s(this.root);let n=[];for(let i of this.lockfileOrder)i!==this.root&&e.has(i)&&n.push(i);return n}topologicalOrderDFS(){let e=new Set,t=[],s=n=>{if(e.has(n))return;e.add(n);let i=this.graph.get(n);if(i)for(let r of Array.from(i))s(r);t.push(n)};s(this.root);for(let n of this.packageTable.keys())s(n);return t}detectCycle(){let e=new Set,t=new Set,s=new Map,n=i=>{e.add(i),t.add(i);let r=this.graph.get(i);if(r)for(let c of r)if(e.has(c)){if(t.has(c)){let a=[c],u=i;for(;u!==c;)a.unshift(u),u=s.get(u);return a.unshift(c),a}}else{s.set(c,i);let a=n(c);if(a)return a}return t.delete(i),null};for(let i of this.packageTable.keys())if(!e.has(i)){let r=n(i);if(r)return r}return null}getRootPackage(){return this.packageTable.get(this.root)}getRootName(){return this.root}isAlwaysDep(e){return this.alwaysDeps.has(e)}};var A=class{constructor(e,t={}){this.unifiedAddressTable=new Map;this.packageResolvedTables=new Map;this.graph=e,this.buildConfig=t}async resolve(){let t=[this.graph.getRootName(),...this.graph.topologicalOrder()];for(let s of t){let n=this.graph.getPackage(s);if(n)for(let[i,r]of Object.entries(n.manifest.addresses)){let c=this.normalizeAddress(r);this.unifiedAddressTable.has(i)&&this.unifiedAddressTable.get(i)!==c||this.unifiedAddressTable.set(i,c)}}for(let s of this.graph.getAllPackages()){let n={};for(let[i,r]of this.unifiedAddressTable.entries())n[i]=r;this.packageResolvedTables.set(s.id.name,n),s.resolvedTable=n}}normalizeAddress(e){if(!e)return e;let t=e.trim();return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}getUnifiedAddressTable(){let e={};for(let[t,s]of this.unifiedAddressTable.entries())e[t]=s;return e}getPackageResolvedTable(e){return this.packageResolvedTables.get(e)}getGraph(){return this.graph}topologicalOrder(){return this.graph.topologicalOrder()}getRootName(){return this.graph.getRootName()}getPackage(e){return this.graph.getPackage(e)}getImmediateDependencies(e){return this.graph.getImmediateDependencies(e)}};var $=class{constructor(e){this.dependencies=[];this.resolvedGraph=e,this.rootPackageName=e.getRootName()}async compute(e){if(!this.resolvedGraph.getPackage(this.rootPackageName))throw new Error(`Root package '${this.rootPackageName}' not found`);let s=this.resolvedGraph.getImmediateDependencies(this.rootPackageName),n=this.resolvedGraph.topologicalOrder(),i=new Set(["Bridge","SuiSystem"]);for(let r of n){if(r===this.rootPackageName)continue;let c=this.resolvedGraph.getPackage(r);if(!c||i.has(r))continue;let a=e.get(r)||{},u=this.extractSourcePaths(r,a),o=c.manifest.edition||"legacy",g=c.manifest.latestPublishedId||c.manifest.originalId||c.manifest.publishedAt||c.resolvedTable?.[r],f={name:r,isImmediate:s.has(r),sourcePaths:u,addressMapping:c.resolvedTable||{},compilerConfig:{edition:o,flavor:"sui"},moduleFormat:u.length>0?"Source":"Bytecode",edition:o,publishedIdForOutput:g};this.dependencies.push(f)}}extractSourcePaths(e,t){let s=Object.keys(t).filter(r=>r.endsWith("Move.toml")||r.endsWith("Move.lock")?!1:r.endsWith(".move")),n=new TextEncoder,i=(r,c)=>{let a=n.encode(`/vfs/deps/${e}/${r}`),u=n.encode(`/vfs/deps/${e}/${c}`),o=Math.min(a.length,u.length);for(let g=0;g<o;g++)if(a[g]!==u[g])return a[g]-u[g];return a.length-u.length};return s.sort(i),s}toPackageGroupedFormat(e){let t=[];for(let s of this.dependencies){let n=e.get(s.name)||{},i={};for(let[r,c]of Object.entries(n)){if(r.endsWith("Move.lock"))continue;let a=`dependencies/${s.name}/${r}`;r.endsWith("Move.toml")?i[a]=this.reconstructDependencyMoveToml(s.name,c,s.edition,s.addressMapping):i[a]=c}t.push({name:s.name,files:i,edition:s.edition,addressMapping:s.addressMapping,publishedIdForOutput:s.publishedIdForOutput})}return t}reconstructDependencyMoveToml(e,t,s,n){let i=(t||"").split(`
|
|
2
|
+
`),r=[],c=[],a=!1,u=!1;for(let l of i){let p=l.trim();if(p.startsWith("[package]")){a=!0,u=!1;continue}if(p.startsWith("[dependencies]")){a=!1,u=!0;continue}if(p.startsWith("[")){a=!1,u=!1;continue}a&&p&&r.push(l),u&&p&&c.push(l)}let o=`[package]
|
|
3
|
+
`,g=!1,f=!1;for(let l of r)if(l.includes("name ="))o+=l+`
|
|
4
|
+
`,g=!0;else if(l.includes("version ="))o+=l+`
|
|
5
|
+
`,f=!0;else{if(l.includes("edition ="))continue;o+=l+`
|
|
6
|
+
`}g||(o+=`name = "${e}"
|
|
7
|
+
`),f||(o+=`version = "0.0.0"
|
|
8
|
+
`),o+=`edition = "${s}"
|
|
9
|
+
`,o+=`
|
|
10
|
+
[dependencies]
|
|
11
|
+
`;for(let l of c)o+=l+`
|
|
12
|
+
`;o+=`
|
|
13
|
+
[addresses]
|
|
14
|
+
`;for(let[l,p]of Object.entries(n))o+=`${l} = "${p}"
|
|
15
|
+
`;return o}};var T=class{constructor(e,t="mainnet",s=null){this.visited=new Set;this.packageNameCache=new Map;this.packageFiles=new Map;this.fetcher=e,this.network=t,this.rootSource=s}async resolve(e,t){let s=w(e),n=s.package?.name||"RootPackage",i=s.package?.edition,r=new D(n),c=await this.buildPackage(n,this.rootSource,e,t);i&&(c.manifest.edition=i);let a=c.manifest.addresses[n];this.normalizeAddress(a||"")==="0x0000000000000000000000000000000000000000000000000000000000000000"&&c.manifest.originalId&&(c.manifest.addresses[n]=this.normalizeAddress(c.manifest.originalId)),r.addPackage(c),this.packageFiles.set(n,t);let o=await this.loadFromLockfile(r,c,t),g=Array.from(c.dependencies.keys()).filter(k=>!r.getPackage(k));(!o||g.length>0)&&await this.buildDependencyGraph(r,c);let f=r.detectCycle();if(f)throw new Error(`Dependency cycle detected: ${f.join(" \u2192 ")}`);let l=new A(r,{});await l.resolve();let p=new $(l);await p.compute(this.packageFiles);let h=this.reconstructMoveToml(s,l.getUnifiedAddressTable(),!0,i),y={...t};delete y["Move.lock"],y["Move.toml"]=h;let m=p.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(y),dependencies:JSON.stringify(m)}}async buildPackage(e,t,s,n){let i=w(s),r=n["Move.lock"],c=this.getChainIdForNetwork(this.network),a=this.resolvePublishedAt(s,r,c),u=a.latestId?this.normalizeAddress(a.latestId):void 0;i.package&&!i.package.edition?console.log(`[Resolver] Package ${e} has no edition in Move.toml. Parsed:`,JSON.stringify(i.package)):i.package&&console.log(`[Resolver] Package ${e} detected edition: ${i.package.edition}`);let o=n["Published.toml"],g,f;if(o)try{let b=w(o).published?.[this.network];b&&(b["published-at"]&&(g=this.normalizeAddress(b["published-at"])),b["original-id"]&&(f=this.normalizeAddress(b["original-id"])))}catch{}a.error;let l={name:i.package?.name||e,version:i.package?.version||"0.0.0",edition:i.package?.edition,publishedAt:g||a.publishedAt,originalId:f||a.originalId,latestPublishedId:u,addresses:i.addresses||{},dependencies:i.dependencies||{},devDependencies:i["dev-dependencies"]},p=l.publishedAt&&l.publishedAt!=="0x0"?this.normalizeAddress(l.publishedAt):void 0,h=l.addresses[l.name],y=h?this.normalizeAddress(h):void 0;p?l.addresses[l.name]=p:y?l.addresses[l.name]=y:l.addresses[l.name]="0x0";let m=new Map;if(l.dependencies)for(let[v,b]of Object.entries(l.dependencies)){let N=this.parseDependencyInfo(b);N&&m.set(v,N)}return{id:{name:l.name,version:l.version,source:t||{type:"local"}},manifest:l,dependencies:m,devDependencies:new Map}}parseDependencyInfo(e){if(!e)return null;let t={source:{type:"local"}};if(e.git&&e.rev)t.source={type:"git",git:e.git,rev:e.rev,subdir:e.subdir};else if(e.local)t.source={type:"local",local:e.local};else return null;if(e["addr-subst"]||e.addr_subst){let s=e["addr-subst"]||e.addr_subst,n={};for(let[i,r]of Object.entries(s))typeof r=="string"&&(r.startsWith("0x")||/^[0-9a-fA-F]+$/.test(r)?n[i]={type:"assign",address:r}:n[i]={type:"renameFrom",name:r});Object.keys(n).length>0&&(t.subst=n)}return t}async buildDependencyGraph(e,t){for(let[s,n]of t.dependencies.entries()){if(n.source.type==="local")if(t.id.source.type==="git"&&n.source.local){let g=t.id.source.subdir||"",f=n.source.local,l=this.resolveRelativePath(g,f);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:l}}else continue;if(n.source.type!=="git")continue;let i=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(i)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(i);let r=n.source.subdir;!r&&n.source.git&&this.isSuiRepo(n.source.git)&&(r=this.inferSuiFrameworkSubdir(s),r&&(n.source.subdir=r));let c=await this.fetcher.fetch(n.source.git,n.source.rev,r),a=null,u=`Move.${this.network}.toml`;for(let[g,f]of Object.entries(c))if(g.endsWith(u)){a=f;break}if(!a){for(let[g,f]of Object.entries(c))if(g.endsWith("Move.toml")){a=f;break}}if(!a)continue;let o=await this.buildPackage(s,n.source,a,c);if(!this.lockfileVersion||this.lockfileVersion<4){let g=this.packageNameCache.get(o.manifest.name);if(g){let f=l=>JSON.stringify(l);throw new Error([`Conflicting versions of package '${o.manifest.name}' found`,`Existing: ${f(g)}`,`New: ${f(n.source)}`,`When resolving dependencies for '${t.id.name}' -> '${s}'`].join(`
|
|
16
|
+
`))}this.packageNameCache.set(o.manifest.name,n.source)}o.manifest.publishedAt&&(o.manifest.addresses[o.manifest.name]=this.normalizeAddress(o.manifest.publishedAt)),o.manifest.edition||(o.manifest.edition="legacy"),e.addPackage(o),e.addDependency(t.id.name,o.id.name,n),this.packageFiles.set(o.id.name,c),await this.buildDependencyGraph(e,o)}}getChainIdForNetwork(e){return{mainnet:"35834a8a",testnet:"4c78adac",devnet:"2",localnet:"localnet"}[e]||e}resolvePublishedAt(e,t,s){let n=w(e),i=n.package?.published_at||n.package?.["published-at"],r=i&&i!=="0x0"?i:void 0,c=r?this.normalizeAddress(r):void 0,a=n.package?.["original-id"];if(!t||!s)return{publishedAt:c,originalId:a};let u=w(t),o,g,f;if(u.env)for(let[,l]of Object.entries(u.env)){let p=l["latest-published-id"],h=l["original-published-id"],y=l["chain-id"];if(y===s||!y){let m=p&&p!=="0x0"?this.normalizeAddress(p):void 0,k=h&&h!=="0x0"?this.normalizeAddress(h):void 0;g=m,f=k,o=m||k;break}}return!f&&o&&(f=o),o&&c&&o!==c?{error:`Conflicting 'published-at' addresses between Move.toml (${c}) and Move.lock (${o})`}:{publishedAt:f||c||o,originalId:f||a,latestId:g||o||c}}findPackageBySource(e,t){for(let s of e.getAllPackages()){let n=s.id.source;if(n.type===t.type&&n.git===t.git&&n.rev===t.rev&&n.subdir===t.subdir)return s}}resolveRelativePath(e,t){let s=e?e.split("/").filter(Boolean):[],n=t.split("/").filter(Boolean),i=[...s];for(let r of n)r===".."?i.length>0&&i.pop():r!=="."&&i.push(r);return i.join("/")}async computeManifestDigest(e){let s=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",s);return Array.from(new Uint8Array(n)).map(c=>c.toString(16).padStart(2,"0")).join("").toUpperCase()}async loadFromLockfile(e,t,s){let n=s["Move.lock"];if(!n)return!1;let i=w(n);this.lockfileVersion=i.move?.version;let r=i.move?.version;return r===3?await this.loadFromLockfileV3(e,i,t):r&&r>=4?i.pinned?await this.loadFromLockfileV4(e,i,s,t):!1:await this.loadFromLockfileV0(e,i,t)}async loadFromLockfileV0(e,t,s){let n=t.move?.package;if(!n||!Array.isArray(n))return!1;let i=Array.isArray(t.move?.dependencies)?t.move.dependencies.map(o=>o.name||o.id||o).filter(Boolean):[],r=n.map(o=>o.name||o.id).filter(Boolean),c=[...i,...r.filter(o=>!i.includes(o))],a=new Map,u=new Map;for(let o of n){let g=o.id||o.name,f=o.source;if(!g||!f)continue;let l=null;if(f.git&&f.rev)l={type:"git",git:f.git,rev:f.rev,subdir:f.subdir};else if(f.local&&this.rootSource?.type==="git"){let m=this.resolveRelativePath(this.rootSource.subdir||"",f.local);l={type:"git",git:this.rootSource.git,rev:this.rootSource.rev,subdir:m}}else continue;let p=await this.fetcher.fetch(l.git,l.rev,l.subdir);if(Object.keys(p).length===0)continue;let h=p["Move.toml"];if(!h)continue;let y=await this.buildPackage(g,l,h,p);a.set(g,y),u.set(y.manifest.name,y),this.packageFiles.set(y.manifest.name,p),e.addPackage(y)}c.length&&e.setLockfileOrder(c);for(let o of n){let g=o.id||o.name,f=a.get(g);if(!f)continue;let l=o.dependencies;if(l&&Array.isArray(l))for(let p of l){let h=p.id||p.name,y=a.get(h)||u.get(h);if(y){let m={source:y.id.source};e.addDependency(f.id.name,y.id.name,m)}}}for(let o of s.dependencies.keys()){let g=u.get(o);if(g){let f=s.dependencies.get(o);e.addDependency(s.id.name,g.id.name,f)}}return a.size>0}async loadFromLockfileV3(e,t,s){let n=t.move?.package;if(!n||!Array.isArray(n))return!1;let i=new Map,r=new Map,c=[];for(let a of n)a.id&&r.set(a.id,a);for(let a of n){let u=a.id,o=a.source;c.push(u);let g=null;if(o?.git&&o.rev)g={type:"git",git:o.git,rev:o.rev,subdir:o.subdir};else if(o?.local&&this.rootSource?.type==="git"){let h=this.resolveRelativePath(this.rootSource.subdir||"",o.local);g={type:"git",git:this.rootSource.git,rev:this.rootSource.rev,subdir:h}}else continue;let f=await this.fetcher.fetch(g.git,g.rev,g.subdir);if(Object.keys(f).length===0)continue;let l=f["Move.toml"];if(!l)continue;let p=await this.buildPackage(u,g,l,f);i.set(u,p),this.packageFiles.set(p.manifest.name,f),e.addPackage(p)}e.setLockfileOrder(c);for(let a of n){let u=a.id,o=i.get(u);if(!o)continue;let g=a.dependencies;if(!(!g||!Array.isArray(g)))for(let f of g){let l=f.id,p=i.get(l);if(!p){let h=r.get(l);if(h?.source?.local&&o.id.source.type==="git"){let y=this.resolveRelativePath(o.id.source.subdir||"",h.source.local),m={type:"git",git:o.id.source.git,rev:o.id.source.rev,subdir:y},k=await this.fetcher.fetch(m.git,m.rev,m.subdir),v=k["Move.toml"];if(v){let b=await this.buildPackage(l,m,v,k);i.set(l,b),this.packageFiles.set(b.manifest.name,k),e.addPackage(b),p=b}}}if(p){let h={source:p.id.source};e.addDependency(o.id.name,p.id.name,h)}}}for(let a of s.dependencies.keys()){let u=i.get(a);if(u){let o=s.dependencies.get(a);e.addDependency(s.id.name,u.id.name,o)}}return!0}async loadFromLockfileV4(e,t,s,n){let i=t.pinned?.[this.network];if(!i)return!1;let r=s["Move.toml"];if(r&&t.move?.manifest_digest&&await this.computeManifestDigest(r)!==t.move.manifest_digest)return!1;let c=new Map,a=new Map,u=[];for(let[o,g]of Object.entries(i)){u.push(o);let f=this.lockfileSourceToDependencySource(g.source);if(!f)continue;let l=await this.fetchFromSource(f);if(!l)return!1;let p=l["Move.toml"];if(!p||g["manifest-digest"]&&await this.computeManifestDigest(p)!==g["manifest-digest"])return!1;let h=await this.buildPackage(o,f,p,l);c.set(o,h),a.set(h.manifest.name,h),this.packageFiles.set(h.manifest.name,l),(f.type!=="local"||!("root"in g.source))&&e.addPackage(h)}u.length>0&&e.setLockfileOrder(u);for(let[o,g]of Object.entries(i)){let f=c.get(o);if(f&&g.deps)for(let[l,p]of Object.entries(g.deps)){let h=c.get(p);if(h){let y=f.dependencies.get(l);y&&e.addDependency(f.id.name,h.id.name,y)}}}for(let o of n.dependencies.keys()){let g=a.get(o)||c.get(o);if(g){let f=n.dependencies.get(o);e.addDependency(n.id.name,g.id.name,f)}}return!0}lockfileSourceToDependencySource(e){return"git"in e?{type:"git",git:e.git,rev:e.rev,subdir:e.subdir}:"local"in e?{type:"local",local:e.local}:"root"in e?{type:"local"}:null}async fetchFromSource(e){if(e.type==="git"&&e.git&&e.rev)try{return await this.fetcher.fetch(e.git,e.rev,e.subdir)}catch{return null}return null}reconstructMoveToml(e,t,s,n){let r=`[package]
|
|
17
|
+
name = "${e.package.name}"
|
|
18
|
+
version = "${e.package.version}"
|
|
19
|
+
`,c=n||e.package.edition;if(c&&(r+=`edition = "${c}"
|
|
20
|
+
`),r+=`
|
|
21
|
+
[dependencies]
|
|
22
|
+
`,e.dependencies)for(let[a,u]of Object.entries(e.dependencies)){let o=u;o.local?r+=`${a} = { local = "${o.local}" }
|
|
23
|
+
`:o.git&&o.rev&&(o.subdir?r+=`${a} = { git = "${o.git}", subdir = "${o.subdir}", rev = "${o.rev}" }
|
|
24
|
+
`:r+=`${a} = { git = "${o.git}", rev = "${o.rev}" }
|
|
25
|
+
`)}r+=`
|
|
26
|
+
[addresses]
|
|
27
|
+
`;for(let[a,u]of Object.entries(t))r+=`${a} = "${u}"
|
|
28
|
+
`;return r}normalizeAddress(e){if(!e)return e;let t=e.trim();return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}isSuiRepo(e){return e.includes("github.com/MystenLabs/sui")}inferSuiFrameworkSubdir(e){let t={Sui:"crates/sui-framework/packages/sui-framework",MoveStdlib:"crates/sui-framework/packages/move-stdlib",SuiSystem:"crates/sui-framework/packages/sui-system",Bridge:"crates/sui-framework/packages/bridge",DeepBook:"crates/sui-framework/packages/deepbook",SuiFramework:"crates/sui-framework/packages/sui-framework"};return t[e]||t[e.toLowerCase()]}};async function W(d,e,t,s="mainnet",n){return new T(t,s,n||null).resolve(d,e)}function Y(d){try{let e=new URL(d);if(e.hostname!=="github.com")return null;let t=e.pathname.split("/").filter(Boolean);if(t.length<2)return null;let s=t[0],n=t[1],i="main",r;return t.length>=4&&t[2]==="tree"&&(i=t[3],t.length>4&&(r=t.slice(4).join("/"))),{owner:s,repo:n,ref:i,subdir:r}}catch{return null}}async function _(d,e){let t=Y(d);if(!t)throw new Error(`Invalid GitHub URL: ${d}`);let s=e?.fetcher||new S(e?.githubToken),n=e?.includeLock!==!1,i=`https://github.com/${t.owner}/${t.repo}.git`,r=await s.fetch(i,t.ref,t.subdir,`root:${t.owner}/${t.repo}`);if(Object.defineProperty(r,"__rootGit",{value:{git:i,rev:t.ref,subdir:t.subdir},enumerable:!1}),!n&&r["Move.lock"]){let{"Move.lock":c,...a}=r;return a}return r}var O;async function P(d){return O||(O=import("./sui_move_wasm.js").then(async e=>(d?await e.default(d):await e.default(),e))),O}function I(d){return{error:d instanceof Error?d.message:typeof d=="string"?d:"Unknown error"}}function j(d){if(typeof d!="object"||d===null)throw new Error("Unexpected compile result shape from wasm");let e=d;if(typeof e.success=="function"&&typeof e.output=="function")return e;if(typeof e.success=="boolean"&&typeof e.output=="string")return{success:()=>e.success,output:()=>e.output};throw new Error("Unexpected compile result shape from wasm")}function Z(d){let e=t=>{let s=t.startsWith("0x")?t.slice(2):t,n=s.length%2===0?s:`0${s}`,i=[];for(let r=0;r<n.length;r+=2){let c=parseInt(n.slice(r,r+2),16);if(Number.isNaN(c))throw new Error("invalid hex digest");i.push(c)}return i};try{let t=JSON.parse(d);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let s=typeof t.digest=="string"?e(t.digest):Array.from(t.digest);return{modules:t.modules,dependencies:t.dependencies,digest:s}}catch(t){return I(t)}}function U(d){try{let e=JSON.parse(d);for(let t of e){let s=t.addressMapping?.[t.name]??(()=>{let n=Object.entries(t.files).find(([r])=>r.endsWith("Move.toml"));if(!n)return;let i=w(n[1]);return i.addresses&&i.addresses[t.name]||i.package?.published_at||i.package?.["published-at"]})()}}catch{}}async function ee(d){await P(d?.wasm)}async function L(d){let e=d.files["Move.toml"]||"",t=d.rootGit||d.files.__rootGit,s=await W(e,{...d.files,"Move.toml":e},new S(d.githubToken),d.network,t?{type:"git",git:t.git,rev:t.rev,subdir:t.subdir}:void 0);return{files:s.files,dependencies:s.dependencies}}async function te(d){try{if(d.files["Move.lock"]&&d.files["Move.toml"])try{let c=w(d.files["Move.lock"]),a=d.network||"mainnet",u=c.env?.[a]?.["original-published-id"];if(u){let g=w(d.files["Move.toml"]).package?.name;if(g){let f=new Set([g,g.toLowerCase()]),l=d.files["Move.toml"];for(let p of f){let h=new RegExp(`(^|[\\s])(${p}\\s*=\\s*)"0x0"`,"m");if(h.test(l)){l=l.replace(h,`$1$2"${u}"`);break}}d.files["Move.toml"]=l}}}catch{}let e=d.resolvedDependencies?d.resolvedDependencies:await L(d),t=await P(d.wasm);U(e.dependencies);let s=t.compile(e.files,e.dependencies,JSON.stringify({silenceWarnings:d.silenceWarnings,testMode:d.testMode,lintFlag:d.lintFlag,stripMetadata:d.stripMetadata})),n=j(s),i=n.success(),r=n.output();return i?Z(r):I(r)}catch(e){return I(e)}}async function ne(d){try{let e=d.resolvedDependencies?d.resolvedDependencies:await L(d),t=await P(d.wasm);U(e.dependencies);let s=d.ansiColor&&typeof t.test_with_color=="function"?t.test_with_color(e.files,e.dependencies,!0):t.test(e.files,e.dependencies);if(typeof s.passed=="boolean"&&typeof s.output=="string")return{passed:s.passed,output:s.output};let n=typeof s.passed=="function"?s.passed():s.passed,i=typeof s.output=="function"?s.output():s.output;return{passed:n,output:i}}catch(e){return I(e)}}async function se(d){return(await P(d?.wasm)).sui_move_version()}async function ie(d){return(await P(d?.wasm)).sui_version()}async function re(d){return P(d?.wasm)}async function oe(d,e,t){let s=await P(t?.wasm),n=t?.ansiColor&&typeof s.compile_with_color=="function"?s.compile_with_color(d,e,!0):s.compile(d,e,JSON.stringify({silenceWarnings:!1})),i=j(n);return{success:i.success(),output:i.output()}}0&&(module.exports={buildMovePackage,compileRaw,fetchPackageFromGitHub,getSuiMoveVersion,getSuiVersion,getWasmBindings,initMoveCompiler,resolveDependencies,testMovePackage});
|
|
@@ -69,7 +69,7 @@ interface BuildInput {
|
|
|
69
69
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
70
70
|
files: Record<string, string>;
|
|
71
71
|
/** Optional custom URL for the wasm binary. Defaults to bundled wasm next to this module. */
|
|
72
|
-
wasm?: string | URL;
|
|
72
|
+
wasm?: string | URL | BufferSource;
|
|
73
73
|
/** Optional hint for the root package git source (enables resolving local deps from Move.lock). */
|
|
74
74
|
rootGit?: {
|
|
75
75
|
git: string;
|
|
@@ -84,6 +84,14 @@ interface BuildInput {
|
|
|
84
84
|
network?: "mainnet" | "testnet" | "devnet";
|
|
85
85
|
/** Optional pre-resolved dependencies. If provided, dependency resolution will be skipped. */
|
|
86
86
|
resolvedDependencies?: ResolvedDependencies;
|
|
87
|
+
/** Use this option to silence warnings. */
|
|
88
|
+
silenceWarnings?: boolean;
|
|
89
|
+
/** Use this option to enable test mode (includes #[test_only] modules). */
|
|
90
|
+
testMode?: boolean;
|
|
91
|
+
/** Use this option to specify lint level (e.g. "all", "none"). */
|
|
92
|
+
lintFlag?: string;
|
|
93
|
+
/** Use this option to strip metadata from the output (e.g. for mainnet dep matching). */
|
|
94
|
+
stripMetadata?: boolean;
|
|
87
95
|
}
|
|
88
96
|
interface BuildSuccess {
|
|
89
97
|
/** Base64-encoded bytecode modules. */
|
|
@@ -99,7 +107,7 @@ interface BuildFailure {
|
|
|
99
107
|
type WasmModule = typeof __sui_move_wasm_js;
|
|
100
108
|
/** Initialize the wasm module (idempotent). Provide a custom wasm URL if hosting separately. */
|
|
101
109
|
declare function initMoveCompiler(options?: {
|
|
102
|
-
wasm?: string | URL;
|
|
110
|
+
wasm?: string | URL | BufferSource;
|
|
103
111
|
}): Promise<void>;
|
|
104
112
|
/**
|
|
105
113
|
* Resolve dependencies for a Move package without compiling.
|
|
@@ -108,6 +116,14 @@ declare function initMoveCompiler(options?: {
|
|
|
108
116
|
declare function resolveDependencies(input: Omit<BuildInput, "resolvedDependencies">): Promise<ResolvedDependencies>;
|
|
109
117
|
/** Compile a Move package in memory using the bundled Move compiler wasm. */
|
|
110
118
|
declare function buildMovePackage(input: BuildInput): Promise<BuildSuccess | BuildFailure>;
|
|
119
|
+
interface TestSuccess {
|
|
120
|
+
/** Whether all tests passed. */
|
|
121
|
+
passed: boolean;
|
|
122
|
+
/** Output from the test runner (stdout). */
|
|
123
|
+
output: string;
|
|
124
|
+
}
|
|
125
|
+
/** Compile and run tests for a Move package in memory. */
|
|
126
|
+
declare function testMovePackage(input: BuildInput): Promise<TestSuccess | BuildFailure>;
|
|
111
127
|
/** Sui Move version baked into the wasm (e.g. from Cargo.lock). */
|
|
112
128
|
declare function getSuiMoveVersion(options?: {
|
|
113
129
|
wasm?: string | URL;
|
|
@@ -130,4 +146,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
130
146
|
}>;
|
|
131
147
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
132
148
|
|
|
133
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies };
|
|
149
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, type TestSuccess, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies, testMovePackage };
|
|
@@ -69,7 +69,7 @@ interface BuildInput {
|
|
|
69
69
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
70
70
|
files: Record<string, string>;
|
|
71
71
|
/** Optional custom URL for the wasm binary. Defaults to bundled wasm next to this module. */
|
|
72
|
-
wasm?: string | URL;
|
|
72
|
+
wasm?: string | URL | BufferSource;
|
|
73
73
|
/** Optional hint for the root package git source (enables resolving local deps from Move.lock). */
|
|
74
74
|
rootGit?: {
|
|
75
75
|
git: string;
|
|
@@ -84,6 +84,14 @@ interface BuildInput {
|
|
|
84
84
|
network?: "mainnet" | "testnet" | "devnet";
|
|
85
85
|
/** Optional pre-resolved dependencies. If provided, dependency resolution will be skipped. */
|
|
86
86
|
resolvedDependencies?: ResolvedDependencies;
|
|
87
|
+
/** Use this option to silence warnings. */
|
|
88
|
+
silenceWarnings?: boolean;
|
|
89
|
+
/** Use this option to enable test mode (includes #[test_only] modules). */
|
|
90
|
+
testMode?: boolean;
|
|
91
|
+
/** Use this option to specify lint level (e.g. "all", "none"). */
|
|
92
|
+
lintFlag?: string;
|
|
93
|
+
/** Use this option to strip metadata from the output (e.g. for mainnet dep matching). */
|
|
94
|
+
stripMetadata?: boolean;
|
|
87
95
|
}
|
|
88
96
|
interface BuildSuccess {
|
|
89
97
|
/** Base64-encoded bytecode modules. */
|
|
@@ -99,7 +107,7 @@ interface BuildFailure {
|
|
|
99
107
|
type WasmModule = typeof __sui_move_wasm_js;
|
|
100
108
|
/** Initialize the wasm module (idempotent). Provide a custom wasm URL if hosting separately. */
|
|
101
109
|
declare function initMoveCompiler(options?: {
|
|
102
|
-
wasm?: string | URL;
|
|
110
|
+
wasm?: string | URL | BufferSource;
|
|
103
111
|
}): Promise<void>;
|
|
104
112
|
/**
|
|
105
113
|
* Resolve dependencies for a Move package without compiling.
|
|
@@ -108,6 +116,14 @@ declare function initMoveCompiler(options?: {
|
|
|
108
116
|
declare function resolveDependencies(input: Omit<BuildInput, "resolvedDependencies">): Promise<ResolvedDependencies>;
|
|
109
117
|
/** Compile a Move package in memory using the bundled Move compiler wasm. */
|
|
110
118
|
declare function buildMovePackage(input: BuildInput): Promise<BuildSuccess | BuildFailure>;
|
|
119
|
+
interface TestSuccess {
|
|
120
|
+
/** Whether all tests passed. */
|
|
121
|
+
passed: boolean;
|
|
122
|
+
/** Output from the test runner (stdout). */
|
|
123
|
+
output: string;
|
|
124
|
+
}
|
|
125
|
+
/** Compile and run tests for a Move package in memory. */
|
|
126
|
+
declare function testMovePackage(input: BuildInput): Promise<TestSuccess | BuildFailure>;
|
|
111
127
|
/** Sui Move version baked into the wasm (e.g. from Cargo.lock). */
|
|
112
128
|
declare function getSuiMoveVersion(options?: {
|
|
113
129
|
wasm?: string | URL;
|
|
@@ -130,4 +146,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
130
146
|
}>;
|
|
131
147
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
132
148
|
|
|
133
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies };
|
|
149
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, type TestSuccess, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies, testMovePackage };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
var I=class{async fetch(e,t,s){throw new Error("Not implemented")}async fetchFile(e,t,s){throw new Error("Not implemented")}},S=class extends I{constructor(t){super();this.rateLimitRemaining=60;this.rateLimitReset=0;this.cache=new Map,this.treeCache=new Map,this.token=t}updateRateLimit(t){let s=t.headers.get("x-ratelimit-remaining"),n=t.headers.get("x-ratelimit-reset");s&&(this.rateLimitRemaining=parseInt(s,10)),n&&(this.rateLimitReset=parseInt(n,10)*1e3)}async fetch(t,s,n,i){let{owner:r,repo:c}=this.parseGitUrl(t);if(!r||!c)throw new Error(`Invalid git URL: ${t}`);let a=`${r}/${c}@${s}`,u=`https://api.github.com/repos/${r}/${c}/git/trees/${s}?recursive=1`,o;if(this.treeCache.has(a))o=this.treeCache.get(a);else{let p=null;for(let h=1;h<=3;h++)try{if(h>1){let k=Math.pow(2,h-1)*1e3;await new Promise(v=>setTimeout(v,k))}let y={};this.token&&(y.Authorization=`Bearer ${this.token}`);let m=await fetch(u,{headers:y});if(this.updateRateLimit(m),!m.ok){if(m.status===403||m.status===429){let k=new Date(this.rateLimitReset);throw new Error(`GitHub API rate limit exceeded. Resets at ${k.toLocaleTimeString()}`)}if(m.status>=500&&m.status<600&&h<3){p=new Error(`Failed to fetch tree: ${m.statusText}`);continue}throw new Error(`Failed to fetch tree: ${m.statusText}`)}o=await m.json(),this.treeCache.set(a,o);break}catch(y){if(p=y instanceof Error?y:new Error(String(y)),h===3)return{}}if(p)return{}}let g={},f=[];for(let d of o.tree){if(d.type!=="blob")continue;let p=d.path;if(n){if(!d.path.startsWith(n))continue;p=d.path.slice(n.length),p.startsWith("/")&&(p=p.slice(1))}if(!p.endsWith(".move")&&p!=="Move.toml"&&p!=="Move.lock"&&!p.match(/^Move\.(mainnet|testnet|devnet)\.toml$/))continue;let h=`https://raw.githubusercontent.com/${r}/${c}/${s}/${d.path}`,y=this.fetchContent(h).then(m=>{m&&(g[p]=m)});f.push(y)}if(await Promise.all(f),g["Move.toml"]){let d=g["Move.toml"].trim();if(d.match(/^Move\.(mainnet|testnet|devnet)\.toml$/)&&!d.includes("[")&&!d.includes("=")){let p=d,h=n?`${n}/${p}`.replace(/\/+/g,"/"):p,y=`https://raw.githubusercontent.com/${r}/${c}/${s}/${h}`,m=await this.fetchContent(y);m&&(g["Move.toml"]=m,g[p]=m)}}return g}async fetchFile(t,s,n){let{owner:i,repo:r}=this.parseGitUrl(t);if(!i||!r)throw new Error(`Invalid git URL: ${t}`);let c=`https://raw.githubusercontent.com/${i}/${r}/${s}/${n}`;return this.fetchContent(c)}async fetchContent(t){if(this.cache.has(t))return this.cache.get(t)??null;try{let s={},n=typeof window<"u",i=t.startsWith("https://api.github.com/");this.token&&(!n||i)&&(s.Authorization=`Bearer ${this.token}`);let r=await fetch(t,{headers:s});if(!r.ok)return null;let c=await r.text();return this.cache.set(t,c),c}catch{return null}}parseGitUrl(t){try{let n=new URL(t).pathname.split("/").filter(i=>i);if(n.length>=2){let i=n[1];return i.endsWith(".git")&&(i=i.slice(0,-4)),{owner:n[0],repo:i}}}catch{}return{owner:null,repo:null}}};function R(l){let e=!1,t="";for(let s=0;s<l.length;s++){let n=l[s];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return l.slice(0,s)}return l}function x(l){let e=l.trim();if(!e)return"";if(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))return e.slice(1,-1);if(e==="true")return!0;if(e==="false")return!1;let t=Number(e);return Number.isNaN(t)?e:t}function N(l){let e={},t=l.trim().replace(/^\{/,"").replace(/\}$/,""),s="",n=!1,i="",r=[];for(let c=0;c<t.length;c++){let a=t[c];if((a==='"'||a==="'")&&(!n||a===i)&&(n=!n,i=a),!n&&a===","){r.push(s),s="";continue}s+=a}s.trim()&&r.push(s);for(let c of r){let a=c.indexOf("=");if(a===-1)continue;let u=c.slice(0,a).trim(),o=c.slice(a+1).trim();e[u]=x(o)}return e}function _(l){let e=[],t=l.trim().replace(/^\[/,"").replace(/\]$/,""),s="",n=!1,i="",r=0;for(let c=0;c<t.length;c++){let a=t[c];if((a==='"'||a==="'")&&(!n||a===i)&&(n=!n,i=n?a:""),!n&&(a==="{"&&r++,a==="}"&&r--,a===","&&r===0)){s.trim()&&e.push(L(s.trim())),s="";continue}s+=a}return s.trim()&&e.push(L(s.trim())),e}function L(l){return l.startsWith("{")?N(l):x(l)}function w(l){let e={},t=null,s=!1,n=l.split(/\r?\n/),i=[],r=0;for(;r<n.length;){let a=R(n[r]);if(a.match(/=\s*\[\s*$/)||a.includes("=")&&a.includes("[")&&!a.includes("]")){let u=a;for(r++;r<n.length&&!u.includes("]");)u+=" "+R(n[r]).trim(),r++;r<n.length&&u.includes("[")&&!u.includes("]")&&(u+=" "+R(n[r]).trim(),r++),i.push(u)}else i.push(a),r++}function c(a,u){let o=a;for(let g of u){if(!(g in o))return;o=o[g]}return o}for(let a of i){let u=R(a).trim();if(!u)continue;let o=u.match(/^\[\[([^\]]+)\]\]$/);if(o){t=o[1].trim(),s=!0;let y=t.split("."),m=e;for(let v=0;v<y.length-1;v++){let b=y[v];b in m||(m[b]={}),m=m[b]}let k=y[y.length-1];Array.isArray(m[k])||(m[k]=[]),m[k].push({});continue}let g=u.match(/^\[([^\]]+)\]$/);if(g){t=g[1].trim(),s=!1;continue}let f=u.indexOf("=");if(f===-1||!t)continue;let d=u.slice(0,f).trim(),p=u.slice(f+1).trim(),h;if(p.startsWith("{")?h=N(p):p.startsWith("[")?h=_(p):h=x(p),s){let y=t.split("."),m=c(e,y);if(Array.isArray(m)&&m.length>0){let k=m[m.length-1];k[d]=h}}else{let y=t.split("."),m=e;for(let v of y)v in m||(m[v]={}),m=m[v];let k=t==="package"?d.replace(/-/g,"_"):d;m[k]=h}}return e}var M=class{constructor(e){this.packageTable=new Map;this.graph=new Map;this.alwaysDeps=new Set(["Sui","MoveStdlib","SuiSystem","Bridge"]);this.lockfileOrder=[];this.root=e}setLockfileOrder(e){this.lockfileOrder=e}addPackage(e){this.packageTable.set(e.id.name,e),this.graph.has(e.id.name)||this.graph.set(e.id.name,new Set)}addDependency(e,t,s){this.graph.has(e)||this.graph.set(e,new Set),this.graph.get(e).add(t)}getPackage(e){return this.packageTable.get(e)}getAllPackages(){return Array.from(this.packageTable.values())}getImmediateDependencies(e){return this.graph.get(e)||new Set}getTransitiveDependencies(e){let t=new Set,s=new Set,n=i=>{if(s.has(i))return;s.add(i),t.add(i);let r=this.graph.get(i);if(r)for(let c of r)n(c)};return n(e),t.delete(e),t}topologicalOrder(){if(!this.lockfileOrder.length)return this.topologicalOrderDFS().filter(r=>r!==this.root);let e=new Set,t=new Set,s=i=>{if(t.has(i))return;t.add(i),e.add(i);let r=this.graph.get(i);if(r)for(let c of r)s(c)};s(this.root);let n=[];for(let i of this.lockfileOrder)i!==this.root&&e.has(i)&&n.push(i);return n}topologicalOrderDFS(){let e=new Set,t=[],s=n=>{if(e.has(n))return;e.add(n);let i=this.graph.get(n);if(i)for(let r of Array.from(i))s(r);t.push(n)};s(this.root);for(let n of this.packageTable.keys())s(n);return t}detectCycle(){let e=new Set,t=new Set,s=new Map,n=i=>{e.add(i),t.add(i);let r=this.graph.get(i);if(r)for(let c of r)if(e.has(c)){if(t.has(c)){let a=[c],u=i;for(;u!==c;)a.unshift(u),u=s.get(u);return a.unshift(c),a}}else{s.set(c,i);let a=n(c);if(a)return a}return t.delete(i),null};for(let i of this.packageTable.keys())if(!e.has(i)){let r=n(i);if(r)return r}return null}getRootPackage(){return this.packageTable.get(this.root)}getRootName(){return this.root}isAlwaysDep(e){return this.alwaysDeps.has(e)}};var D=class{constructor(e,t={}){this.unifiedAddressTable=new Map;this.packageResolvedTables=new Map;this.graph=e,this.buildConfig=t}async resolve(){let t=[this.graph.getRootName(),...this.graph.topologicalOrder()];for(let s of t){let n=this.graph.getPackage(s);if(n)for(let[i,r]of Object.entries(n.manifest.addresses)){let c=this.normalizeAddress(r);this.unifiedAddressTable.has(i)&&this.unifiedAddressTable.get(i)!==c||this.unifiedAddressTable.set(i,c)}}for(let s of this.graph.getAllPackages()){let n={};for(let[i,r]of this.unifiedAddressTable.entries())n[i]=r;this.packageResolvedTables.set(s.id.name,n),s.resolvedTable=n}}normalizeAddress(e){if(!e)return e;let t=e.trim();return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}getUnifiedAddressTable(){let e={};for(let[t,s]of this.unifiedAddressTable.entries())e[t]=s;return e}getPackageResolvedTable(e){return this.packageResolvedTables.get(e)}getGraph(){return this.graph}topologicalOrder(){return this.graph.topologicalOrder()}getRootName(){return this.graph.getRootName()}getPackage(e){return this.graph.getPackage(e)}getImmediateDependencies(e){return this.graph.getImmediateDependencies(e)}};var A=class{constructor(e){this.dependencies=[];this.resolvedGraph=e,this.rootPackageName=e.getRootName()}async compute(e){if(!this.resolvedGraph.getPackage(this.rootPackageName))throw new Error(`Root package '${this.rootPackageName}' not found`);let s=this.resolvedGraph.getImmediateDependencies(this.rootPackageName),n=this.resolvedGraph.topologicalOrder(),i=new Set(["Bridge","SuiSystem"]);for(let r of n){if(r===this.rootPackageName)continue;let c=this.resolvedGraph.getPackage(r);if(!c||i.has(r))continue;let a=e.get(r)||{},u=this.extractSourcePaths(r,a),o=c.manifest.edition||"legacy",g=c.manifest.latestPublishedId||c.manifest.originalId||c.manifest.publishedAt||c.resolvedTable?.[r],f={name:r,isImmediate:s.has(r),sourcePaths:u,addressMapping:c.resolvedTable||{},compilerConfig:{edition:o,flavor:"sui"},moduleFormat:u.length>0?"Source":"Bytecode",edition:o,publishedIdForOutput:g};this.dependencies.push(f)}}extractSourcePaths(e,t){let s=Object.keys(t).filter(r=>r.endsWith("Move.toml")||r.endsWith("Move.lock")?!1:r.endsWith(".move")),n=new TextEncoder,i=(r,c)=>{let a=n.encode(`/vfs/deps/${e}/${r}`),u=n.encode(`/vfs/deps/${e}/${c}`),o=Math.min(a.length,u.length);for(let g=0;g<o;g++)if(a[g]!==u[g])return a[g]-u[g];return a.length-u.length};return s.sort(i),s}toPackageGroupedFormat(e){let t=[];for(let s of this.dependencies){let n=e.get(s.name)||{},i={};for(let[r,c]of Object.entries(n)){if(r.endsWith("Move.lock"))continue;let a=`dependencies/${s.name}/${r}`;r.endsWith("Move.toml")?i[a]=this.reconstructDependencyMoveToml(s.name,c,s.edition,s.addressMapping):i[a]=c}t.push({name:s.name,files:i,edition:s.edition,addressMapping:s.addressMapping,publishedIdForOutput:s.publishedIdForOutput})}return t}reconstructDependencyMoveToml(e,t,s,n){let i=(t||"").split(`
|
|
2
|
+
`),r=[],c=[],a=!1,u=!1;for(let d of i){let p=d.trim();if(p.startsWith("[package]")){a=!0,u=!1;continue}if(p.startsWith("[dependencies]")){a=!1,u=!0;continue}if(p.startsWith("[")){a=!1,u=!1;continue}a&&p&&r.push(d),u&&p&&c.push(d)}let o=`[package]
|
|
3
|
+
`,g=!1,f=!1;for(let d of r)if(d.includes("name ="))o+=d+`
|
|
4
|
+
`,g=!0;else if(d.includes("version ="))o+=d+`
|
|
5
|
+
`,f=!0;else{if(d.includes("edition ="))continue;o+=d+`
|
|
6
|
+
`}g||(o+=`name = "${e}"
|
|
7
|
+
`),f||(o+=`version = "0.0.0"
|
|
8
|
+
`),o+=`edition = "${s}"
|
|
9
|
+
`,o+=`
|
|
10
|
+
[dependencies]
|
|
11
|
+
`;for(let d of c)o+=d+`
|
|
12
|
+
`;o+=`
|
|
13
|
+
[addresses]
|
|
14
|
+
`;for(let[d,p]of Object.entries(n))o+=`${d} = "${p}"
|
|
15
|
+
`;return o}};var F=class{constructor(e,t="mainnet",s=null){this.visited=new Set;this.packageNameCache=new Map;this.packageFiles=new Map;this.fetcher=e,this.network=t,this.rootSource=s}async resolve(e,t){let s=w(e),n=s.package?.name||"RootPackage",i=s.package?.edition,r=new M(n),c=await this.buildPackage(n,this.rootSource,e,t);i&&(c.manifest.edition=i);let a=c.manifest.addresses[n];this.normalizeAddress(a||"")==="0x0000000000000000000000000000000000000000000000000000000000000000"&&c.manifest.originalId&&(c.manifest.addresses[n]=this.normalizeAddress(c.manifest.originalId)),r.addPackage(c),this.packageFiles.set(n,t);let o=await this.loadFromLockfile(r,c,t),g=Array.from(c.dependencies.keys()).filter(k=>!r.getPackage(k));(!o||g.length>0)&&await this.buildDependencyGraph(r,c);let f=r.detectCycle();if(f)throw new Error(`Dependency cycle detected: ${f.join(" \u2192 ")}`);let d=new D(r,{});await d.resolve();let p=new A(d);await p.compute(this.packageFiles);let h=this.reconstructMoveToml(s,d.getUnifiedAddressTable(),!0,i),y={...t};delete y["Move.lock"],y["Move.toml"]=h;let m=p.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(y),dependencies:JSON.stringify(m)}}async buildPackage(e,t,s,n){let i=w(s),r=n["Move.lock"],c=this.getChainIdForNetwork(this.network),a=this.resolvePublishedAt(s,r,c),u=a.latestId?this.normalizeAddress(a.latestId):void 0;i.package&&!i.package.edition?console.log(`[Resolver] Package ${e} has no edition in Move.toml. Parsed:`,JSON.stringify(i.package)):i.package&&console.log(`[Resolver] Package ${e} detected edition: ${i.package.edition}`);let o=n["Published.toml"],g,f;if(o)try{let b=w(o).published?.[this.network];b&&(b["published-at"]&&(g=this.normalizeAddress(b["published-at"])),b["original-id"]&&(f=this.normalizeAddress(b["original-id"])))}catch{}a.error;let d={name:i.package?.name||e,version:i.package?.version||"0.0.0",edition:i.package?.edition,publishedAt:g||a.publishedAt,originalId:f||a.originalId,latestPublishedId:u,addresses:i.addresses||{},dependencies:i.dependencies||{},devDependencies:i["dev-dependencies"]},p=d.publishedAt&&d.publishedAt!=="0x0"?this.normalizeAddress(d.publishedAt):void 0,h=d.addresses[d.name],y=h?this.normalizeAddress(h):void 0;p?d.addresses[d.name]=p:y?d.addresses[d.name]=y:d.addresses[d.name]="0x0";let m=new Map;if(d.dependencies)for(let[v,b]of Object.entries(d.dependencies)){let O=this.parseDependencyInfo(b);O&&m.set(v,O)}return{id:{name:d.name,version:d.version,source:t||{type:"local"}},manifest:d,dependencies:m,devDependencies:new Map}}parseDependencyInfo(e){if(!e)return null;let t={source:{type:"local"}};if(e.git&&e.rev)t.source={type:"git",git:e.git,rev:e.rev,subdir:e.subdir};else if(e.local)t.source={type:"local",local:e.local};else return null;if(e["addr-subst"]||e.addr_subst){let s=e["addr-subst"]||e.addr_subst,n={};for(let[i,r]of Object.entries(s))typeof r=="string"&&(r.startsWith("0x")||/^[0-9a-fA-F]+$/.test(r)?n[i]={type:"assign",address:r}:n[i]={type:"renameFrom",name:r});Object.keys(n).length>0&&(t.subst=n)}return t}async buildDependencyGraph(e,t){for(let[s,n]of t.dependencies.entries()){if(n.source.type==="local")if(t.id.source.type==="git"&&n.source.local){let g=t.id.source.subdir||"",f=n.source.local,d=this.resolveRelativePath(g,f);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:d}}else continue;if(n.source.type!=="git")continue;let i=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(i)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(i);let r=n.source.subdir;!r&&n.source.git&&this.isSuiRepo(n.source.git)&&(r=this.inferSuiFrameworkSubdir(s),r&&(n.source.subdir=r));let c=await this.fetcher.fetch(n.source.git,n.source.rev,r),a=null,u=`Move.${this.network}.toml`;for(let[g,f]of Object.entries(c))if(g.endsWith(u)){a=f;break}if(!a){for(let[g,f]of Object.entries(c))if(g.endsWith("Move.toml")){a=f;break}}if(!a)continue;let o=await this.buildPackage(s,n.source,a,c);if(!this.lockfileVersion||this.lockfileVersion<4){let g=this.packageNameCache.get(o.manifest.name);if(g){let f=d=>JSON.stringify(d);throw new Error([`Conflicting versions of package '${o.manifest.name}' found`,`Existing: ${f(g)}`,`New: ${f(n.source)}`,`When resolving dependencies for '${t.id.name}' -> '${s}'`].join(`
|
|
16
|
+
`))}this.packageNameCache.set(o.manifest.name,n.source)}o.manifest.publishedAt&&(o.manifest.addresses[o.manifest.name]=this.normalizeAddress(o.manifest.publishedAt)),o.manifest.edition||(o.manifest.edition="legacy"),e.addPackage(o),e.addDependency(t.id.name,o.id.name,n),this.packageFiles.set(o.id.name,c),await this.buildDependencyGraph(e,o)}}getChainIdForNetwork(e){return{mainnet:"35834a8a",testnet:"4c78adac",devnet:"2",localnet:"localnet"}[e]||e}resolvePublishedAt(e,t,s){let n=w(e),i=n.package?.published_at||n.package?.["published-at"],r=i&&i!=="0x0"?i:void 0,c=r?this.normalizeAddress(r):void 0,a=n.package?.["original-id"];if(!t||!s)return{publishedAt:c,originalId:a};let u=w(t),o,g,f;if(u.env)for(let[,d]of Object.entries(u.env)){let p=d["latest-published-id"],h=d["original-published-id"],y=d["chain-id"];if(y===s||!y){let m=p&&p!=="0x0"?this.normalizeAddress(p):void 0,k=h&&h!=="0x0"?this.normalizeAddress(h):void 0;g=m,f=k,o=m||k;break}}return!f&&o&&(f=o),o&&c&&o!==c?{error:`Conflicting 'published-at' addresses between Move.toml (${c}) and Move.lock (${o})`}:{publishedAt:f||c||o,originalId:f||a,latestId:g||o||c}}findPackageBySource(e,t){for(let s of e.getAllPackages()){let n=s.id.source;if(n.type===t.type&&n.git===t.git&&n.rev===t.rev&&n.subdir===t.subdir)return s}}resolveRelativePath(e,t){let s=e?e.split("/").filter(Boolean):[],n=t.split("/").filter(Boolean),i=[...s];for(let r of n)r===".."?i.length>0&&i.pop():r!=="."&&i.push(r);return i.join("/")}async computeManifestDigest(e){let s=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",s);return Array.from(new Uint8Array(n)).map(c=>c.toString(16).padStart(2,"0")).join("").toUpperCase()}async loadFromLockfile(e,t,s){let n=s["Move.lock"];if(!n)return!1;let i=w(n);this.lockfileVersion=i.move?.version;let r=i.move?.version;return r===3?await this.loadFromLockfileV3(e,i,t):r&&r>=4?i.pinned?await this.loadFromLockfileV4(e,i,s,t):!1:await this.loadFromLockfileV0(e,i,t)}async loadFromLockfileV0(e,t,s){let n=t.move?.package;if(!n||!Array.isArray(n))return!1;let i=Array.isArray(t.move?.dependencies)?t.move.dependencies.map(o=>o.name||o.id||o).filter(Boolean):[],r=n.map(o=>o.name||o.id).filter(Boolean),c=[...i,...r.filter(o=>!i.includes(o))],a=new Map,u=new Map;for(let o of n){let g=o.id||o.name,f=o.source;if(!g||!f)continue;let d=null;if(f.git&&f.rev)d={type:"git",git:f.git,rev:f.rev,subdir:f.subdir};else if(f.local&&this.rootSource?.type==="git"){let m=this.resolveRelativePath(this.rootSource.subdir||"",f.local);d={type:"git",git:this.rootSource.git,rev:this.rootSource.rev,subdir:m}}else continue;let p=await this.fetcher.fetch(d.git,d.rev,d.subdir);if(Object.keys(p).length===0)continue;let h=p["Move.toml"];if(!h)continue;let y=await this.buildPackage(g,d,h,p);a.set(g,y),u.set(y.manifest.name,y),this.packageFiles.set(y.manifest.name,p),e.addPackage(y)}c.length&&e.setLockfileOrder(c);for(let o of n){let g=o.id||o.name,f=a.get(g);if(!f)continue;let d=o.dependencies;if(d&&Array.isArray(d))for(let p of d){let h=p.id||p.name,y=a.get(h)||u.get(h);if(y){let m={source:y.id.source};e.addDependency(f.id.name,y.id.name,m)}}}for(let o of s.dependencies.keys()){let g=u.get(o);if(g){let f=s.dependencies.get(o);e.addDependency(s.id.name,g.id.name,f)}}return a.size>0}async loadFromLockfileV3(e,t,s){let n=t.move?.package;if(!n||!Array.isArray(n))return!1;let i=new Map,r=new Map,c=[];for(let a of n)a.id&&r.set(a.id,a);for(let a of n){let u=a.id,o=a.source;c.push(u);let g=null;if(o?.git&&o.rev)g={type:"git",git:o.git,rev:o.rev,subdir:o.subdir};else if(o?.local&&this.rootSource?.type==="git"){let h=this.resolveRelativePath(this.rootSource.subdir||"",o.local);g={type:"git",git:this.rootSource.git,rev:this.rootSource.rev,subdir:h}}else continue;let f=await this.fetcher.fetch(g.git,g.rev,g.subdir);if(Object.keys(f).length===0)continue;let d=f["Move.toml"];if(!d)continue;let p=await this.buildPackage(u,g,d,f);i.set(u,p),this.packageFiles.set(p.manifest.name,f),e.addPackage(p)}e.setLockfileOrder(c);for(let a of n){let u=a.id,o=i.get(u);if(!o)continue;let g=a.dependencies;if(!(!g||!Array.isArray(g)))for(let f of g){let d=f.id,p=i.get(d);if(!p){let h=r.get(d);if(h?.source?.local&&o.id.source.type==="git"){let y=this.resolveRelativePath(o.id.source.subdir||"",h.source.local),m={type:"git",git:o.id.source.git,rev:o.id.source.rev,subdir:y},k=await this.fetcher.fetch(m.git,m.rev,m.subdir),v=k["Move.toml"];if(v){let b=await this.buildPackage(d,m,v,k);i.set(d,b),this.packageFiles.set(b.manifest.name,k),e.addPackage(b),p=b}}}if(p){let h={source:p.id.source};e.addDependency(o.id.name,p.id.name,h)}}}for(let a of s.dependencies.keys()){let u=i.get(a);if(u){let o=s.dependencies.get(a);e.addDependency(s.id.name,u.id.name,o)}}return!0}async loadFromLockfileV4(e,t,s,n){let i=t.pinned?.[this.network];if(!i)return!1;let r=s["Move.toml"];if(r&&t.move?.manifest_digest&&await this.computeManifestDigest(r)!==t.move.manifest_digest)return!1;let c=new Map,a=new Map,u=[];for(let[o,g]of Object.entries(i)){u.push(o);let f=this.lockfileSourceToDependencySource(g.source);if(!f)continue;let d=await this.fetchFromSource(f);if(!d)return!1;let p=d["Move.toml"];if(!p||g["manifest-digest"]&&await this.computeManifestDigest(p)!==g["manifest-digest"])return!1;let h=await this.buildPackage(o,f,p,d);c.set(o,h),a.set(h.manifest.name,h),this.packageFiles.set(h.manifest.name,d),(f.type!=="local"||!("root"in g.source))&&e.addPackage(h)}u.length>0&&e.setLockfileOrder(u);for(let[o,g]of Object.entries(i)){let f=c.get(o);if(f&&g.deps)for(let[d,p]of Object.entries(g.deps)){let h=c.get(p);if(h){let y=f.dependencies.get(d);y&&e.addDependency(f.id.name,h.id.name,y)}}}for(let o of n.dependencies.keys()){let g=a.get(o)||c.get(o);if(g){let f=n.dependencies.get(o);e.addDependency(n.id.name,g.id.name,f)}}return!0}lockfileSourceToDependencySource(e){return"git"in e?{type:"git",git:e.git,rev:e.rev,subdir:e.subdir}:"local"in e?{type:"local",local:e.local}:"root"in e?{type:"local"}:null}async fetchFromSource(e){if(e.type==="git"&&e.git&&e.rev)try{return await this.fetcher.fetch(e.git,e.rev,e.subdir)}catch{return null}return null}reconstructMoveToml(e,t,s,n){let r=`[package]
|
|
17
|
+
name = "${e.package.name}"
|
|
18
|
+
version = "${e.package.version}"
|
|
19
|
+
`,c=n||e.package.edition;if(c&&(r+=`edition = "${c}"
|
|
20
|
+
`),r+=`
|
|
21
|
+
[dependencies]
|
|
22
|
+
`,e.dependencies)for(let[a,u]of Object.entries(e.dependencies)){let o=u;o.local?r+=`${a} = { local = "${o.local}" }
|
|
23
|
+
`:o.git&&o.rev&&(o.subdir?r+=`${a} = { git = "${o.git}", subdir = "${o.subdir}", rev = "${o.rev}" }
|
|
24
|
+
`:r+=`${a} = { git = "${o.git}", rev = "${o.rev}" }
|
|
25
|
+
`)}r+=`
|
|
26
|
+
[addresses]
|
|
27
|
+
`;for(let[a,u]of Object.entries(t))r+=`${a} = "${u}"
|
|
28
|
+
`;return r}normalizeAddress(e){if(!e)return e;let t=e.trim();return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}isSuiRepo(e){return e.includes("github.com/MystenLabs/sui")}inferSuiFrameworkSubdir(e){let t={Sui:"crates/sui-framework/packages/sui-framework",MoveStdlib:"crates/sui-framework/packages/move-stdlib",SuiSystem:"crates/sui-framework/packages/sui-system",Bridge:"crates/sui-framework/packages/bridge",DeepBook:"crates/sui-framework/packages/deepbook",SuiFramework:"crates/sui-framework/packages/sui-framework"};return t[e]||t[e.toLowerCase()]}};async function G(l,e,t,s="mainnet",n){return new F(t,s,n||null).resolve(l,e)}function j(l){try{let e=new URL(l);if(e.hostname!=="github.com")return null;let t=e.pathname.split("/").filter(Boolean);if(t.length<2)return null;let s=t[0],n=t[1],i="main",r;return t.length>=4&&t[2]==="tree"&&(i=t[3],t.length>4&&(r=t.slice(4).join("/"))),{owner:s,repo:n,ref:i,subdir:r}}catch{return null}}async function U(l,e){let t=j(l);if(!t)throw new Error(`Invalid GitHub URL: ${l}`);let s=e?.fetcher||new S(e?.githubToken),n=e?.includeLock!==!1,i=`https://github.com/${t.owner}/${t.repo}.git`,r=await s.fetch(i,t.ref,t.subdir,`root:${t.owner}/${t.repo}`);if(Object.defineProperty(r,"__rootGit",{value:{git:i,rev:t.ref,subdir:t.subdir},enumerable:!1}),!n&&r["Move.lock"]){let{"Move.lock":c,...a}=r;return a}return r}var T;async function P(l){return T||(T=import("./sui_move_wasm.js").then(async e=>(l?await e.default(l):await e.default(),e))),T}function $(l){return{error:l instanceof Error?l.message:typeof l=="string"?l:"Unknown error"}}function C(l){if(typeof l!="object"||l===null)throw new Error("Unexpected compile result shape from wasm");let e=l;if(typeof e.success=="function"&&typeof e.output=="function")return e;if(typeof e.success=="boolean"&&typeof e.output=="string")return{success:()=>e.success,output:()=>e.output};throw new Error("Unexpected compile result shape from wasm")}function E(l){let e=t=>{let s=t.startsWith("0x")?t.slice(2):t,n=s.length%2===0?s:`0${s}`,i=[];for(let r=0;r<n.length;r+=2){let c=parseInt(n.slice(r,r+2),16);if(Number.isNaN(c))throw new Error("invalid hex digest");i.push(c)}return i};try{let t=JSON.parse(l);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let s=typeof t.digest=="string"?e(t.digest):Array.from(t.digest);return{modules:t.modules,dependencies:t.dependencies,digest:s}}catch(t){return $(t)}}function B(l){try{let e=JSON.parse(l);for(let t of e){let s=t.addressMapping?.[t.name]??(()=>{let n=Object.entries(t.files).find(([r])=>r.endsWith("Move.toml"));if(!n)return;let i=w(n[1]);return i.addresses&&i.addresses[t.name]||i.package?.published_at||i.package?.["published-at"]})()}}catch{}}async function ge(l){await P(l?.wasm)}async function W(l){let e=l.files["Move.toml"]||"",t=l.rootGit||l.files.__rootGit,s=await G(e,{...l.files,"Move.toml":e},new S(l.githubToken),l.network,t?{type:"git",git:t.git,rev:t.rev,subdir:t.subdir}:void 0);return{files:s.files,dependencies:s.dependencies}}async function ue(l){try{if(l.files["Move.lock"]&&l.files["Move.toml"])try{let c=w(l.files["Move.lock"]),a=l.network||"mainnet",u=c.env?.[a]?.["original-published-id"];if(u){let g=w(l.files["Move.toml"]).package?.name;if(g){let f=new Set([g,g.toLowerCase()]),d=l.files["Move.toml"];for(let p of f){let h=new RegExp(`(^|[\\s])(${p}\\s*=\\s*)"0x0"`,"m");if(h.test(d)){d=d.replace(h,`$1$2"${u}"`);break}}l.files["Move.toml"]=d}}}catch{}let e=l.resolvedDependencies?l.resolvedDependencies:await W(l),t=await P(l.wasm);B(e.dependencies);let s=t.compile(e.files,e.dependencies,JSON.stringify({silenceWarnings:l.silenceWarnings,testMode:l.testMode,lintFlag:l.lintFlag,stripMetadata:l.stripMetadata})),n=C(s),i=n.success(),r=n.output();return i?E(r):$(r)}catch(e){return $(e)}}async function pe(l){try{let e=l.resolvedDependencies?l.resolvedDependencies:await W(l),t=await P(l.wasm);B(e.dependencies);let s=l.ansiColor&&typeof t.test_with_color=="function"?t.test_with_color(e.files,e.dependencies,!0):t.test(e.files,e.dependencies);if(typeof s.passed=="boolean"&&typeof s.output=="string")return{passed:s.passed,output:s.output};let n=typeof s.passed=="function"?s.passed():s.passed,i=typeof s.output=="function"?s.output():s.output;return{passed:n,output:i}}catch(e){return $(e)}}async function fe(l){return(await P(l?.wasm)).sui_move_version()}async function me(l){return(await P(l?.wasm)).sui_version()}async function he(l){return P(l?.wasm)}async function ye(l,e,t){let s=await P(t?.wasm),n=t?.ansiColor&&typeof s.compile_with_color=="function"?s.compile_with_color(l,e,!0):s.compile(l,e,JSON.stringify({silenceWarnings:!1})),i=C(n);return{success:i.success(),output:i.output()}}export{ue as buildMovePackage,ye as compileRaw,U as fetchPackageFromGitHub,fe as getSuiMoveVersion,me as getSuiVersion,he as getWasmBindings,ge as initMoveCompiler,W as resolveDependencies,pe as testMovePackage};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
export class MoveCompilerResult {
|
|
5
|
+
private constructor();
|
|
6
|
+
free(): void;
|
|
7
|
+
[Symbol.dispose](): void;
|
|
8
|
+
readonly output: string;
|
|
9
|
+
readonly success: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class MoveTestResult {
|
|
13
|
+
private constructor();
|
|
14
|
+
free(): void;
|
|
15
|
+
[Symbol.dispose](): void;
|
|
16
|
+
readonly output: string;
|
|
17
|
+
readonly passed: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function compile(files_json: string, dependencies_json: string, options_json?: string | null): MoveCompilerResult;
|
|
21
|
+
|
|
22
|
+
export function sui_move_version(): string;
|
|
23
|
+
|
|
24
|
+
export function sui_version(): string;
|
|
25
|
+
|
|
26
|
+
export function test(files_json: string, dependencies_json: string): MoveTestResult;
|
|
27
|
+
|
|
28
|
+
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
29
|
+
|
|
30
|
+
export interface InitOutput {
|
|
31
|
+
readonly memory: WebAssembly.Memory;
|
|
32
|
+
readonly __wbg_movecompilerresult_free: (a: number, b: number) => void;
|
|
33
|
+
readonly compile: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
|
|
34
|
+
readonly movecompilerresult_output: (a: number) => [number, number];
|
|
35
|
+
readonly movecompilerresult_success: (a: number) => number;
|
|
36
|
+
readonly sui_move_version: () => [number, number];
|
|
37
|
+
readonly test: (a: number, b: number, c: number, d: number) => number;
|
|
38
|
+
readonly sui_version: () => [number, number];
|
|
39
|
+
readonly __wbg_movetestresult_free: (a: number, b: number) => void;
|
|
40
|
+
readonly movetestresult_output: (a: number) => [number, number];
|
|
41
|
+
readonly movetestresult_passed: (a: number) => number;
|
|
42
|
+
readonly __wbindgen_externrefs: WebAssembly.Table;
|
|
43
|
+
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
44
|
+
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
45
|
+
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
46
|
+
readonly __wbindgen_start: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Instantiates the given `module`, which can either be bytes or
|
|
53
|
+
* a precompiled `WebAssembly.Module`.
|
|
54
|
+
*
|
|
55
|
+
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
|
56
|
+
*
|
|
57
|
+
* @returns {InitOutput}
|
|
58
|
+
*/
|
|
59
|
+
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
|
63
|
+
* for everything else, calls `WebAssembly.instantiate` directly.
|
|
64
|
+
*
|
|
65
|
+
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
|
66
|
+
*
|
|
67
|
+
* @returns {Promise<InitOutput>}
|
|
68
|
+
*/
|
|
69
|
+
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|