@zktx.io/sui-move-builder 0.1.4 → 0.1.5
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 +55 -75
- package/dist/index.cjs +22 -24
- package/dist/index.d.cts +14 -141
- package/dist/index.d.ts +14 -141
- package/dist/index.js +22 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,24 +44,18 @@ module hello_world::hello_world {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
// 3) Compile
|
|
47
|
-
const result = await buildMovePackage({
|
|
48
|
-
files,
|
|
49
|
-
dependencies: {},
|
|
50
|
-
autoSystemDeps: true, // Sui CLI-like defaults for std/Sui packages
|
|
51
|
-
});
|
|
47
|
+
const result = await buildMovePackage({ files });
|
|
52
48
|
|
|
53
49
|
if (result.success) {
|
|
54
|
-
console.log(result.digest);
|
|
55
|
-
console.log(result.modules); // Base64-encoded
|
|
50
|
+
console.log("Digest:", result.digest);
|
|
51
|
+
console.log("Modules:", result.modules); // Base64-encoded bytecode
|
|
56
52
|
} else {
|
|
57
|
-
console.error(result.error);
|
|
53
|
+
console.error("Build failed:", result.error);
|
|
58
54
|
}
|
|
59
55
|
```
|
|
60
56
|
|
|
61
57
|
## Fetching packages from GitHub
|
|
62
58
|
|
|
63
|
-
Use the utility functions to fetch Move packages directly from GitHub URLs:
|
|
64
|
-
|
|
65
59
|
```ts
|
|
66
60
|
import {
|
|
67
61
|
fetchPackageFromGitHub,
|
|
@@ -76,48 +70,24 @@ const files = await fetchPackageFromGitHub(
|
|
|
76
70
|
"https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework"
|
|
77
71
|
);
|
|
78
72
|
|
|
79
|
-
// files = {
|
|
80
|
-
// 'Move.toml': '...',
|
|
81
|
-
// 'Move.lock': '...',
|
|
82
|
-
// 'sources/object.move': '...',
|
|
83
|
-
// ...
|
|
84
|
-
// }
|
|
85
|
-
|
|
86
73
|
// Compile directly
|
|
87
74
|
const result = await buildMovePackage({ files });
|
|
88
75
|
```
|
|
89
76
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
import { fetchPackagesFromGitHub, githubUrl } from "@zktx.io/sui-move-builder";
|
|
94
|
-
|
|
95
|
-
const packages = await fetchPackagesFromGitHub({
|
|
96
|
-
Sui: githubUrl(
|
|
97
|
-
"MystenLabs/sui",
|
|
98
|
-
"framework/mainnet",
|
|
99
|
-
"crates/sui-framework/packages/sui-framework"
|
|
100
|
-
),
|
|
101
|
-
deepbook: githubUrl("MystenLabs/deepbookv3", "main", "packages/deepbook"),
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// packages = {
|
|
105
|
-
// 'Sui': { 'Move.toml': '...', ... },
|
|
106
|
-
// 'deepbook': { 'Move.toml': '...', ... }
|
|
107
|
-
// }
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Resolving dependencies from GitHub
|
|
77
|
+
## How it works
|
|
111
78
|
|
|
112
|
-
|
|
79
|
+
Dependencies are automatically resolved from `Move.toml`:
|
|
113
80
|
|
|
114
81
|
1. **Tries Move.lock first**: If a valid `Move.lock` exists, dependencies are loaded from it (faster, deterministic)
|
|
115
82
|
2. **Falls back to manifests**: If lockfile is missing/invalid, resolves dependencies from `Move.toml` files
|
|
116
83
|
3. **Validates digests**: Checks manifest digests to detect changes
|
|
117
84
|
4. **Handles monorepos**: Converts local dependencies to git dependencies automatically
|
|
85
|
+
5. **Injects system packages**: Automatically adds Sui, MoveStdlib, SuiSystem, and Bridge packages if missing
|
|
118
86
|
|
|
119
87
|
```ts
|
|
120
|
-
import {
|
|
88
|
+
import { initMoveCompiler, buildMovePackage } from "@zktx.io/sui-move-builder";
|
|
89
|
+
|
|
90
|
+
await initMoveCompiler();
|
|
121
91
|
|
|
122
92
|
const files = {
|
|
123
93
|
"Move.toml": `
|
|
@@ -126,55 +96,65 @@ name = "my_package"
|
|
|
126
96
|
edition = "2024.beta"
|
|
127
97
|
|
|
128
98
|
[dependencies]
|
|
129
|
-
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/mainnet" }
|
|
130
99
|
deepbook = { git = "https://github.com/MystenLabs/deepbookv3.git", subdir = "packages/deepbook", rev = "main" }
|
|
131
100
|
`,
|
|
132
|
-
"Move.lock": "...", // Optional: will be used if valid
|
|
133
101
|
"sources/main.move": "...",
|
|
134
102
|
};
|
|
135
103
|
|
|
136
|
-
const
|
|
137
|
-
files["Move.toml"],
|
|
138
|
-
files,
|
|
139
|
-
new GitHubFetcher(),
|
|
140
|
-
"mainnet" // network: 'mainnet' | 'testnet' | 'devnet'
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
const filesJson = JSON.parse(resolution.files);
|
|
144
|
-
const depsJson = JSON.parse(resolution.dependencies);
|
|
104
|
+
const result = await buildMovePackage({ files });
|
|
145
105
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
106
|
+
if (result.success) {
|
|
107
|
+
console.log("Modules:", result.modules); // Base64-encoded bytecode
|
|
108
|
+
console.log("Dependencies:", result.dependencies); // Hex-encoded IDs
|
|
109
|
+
console.log("Digest:", result.digest); // Package digest
|
|
110
|
+
} else {
|
|
111
|
+
console.error("Build failed:", result.error);
|
|
112
|
+
}
|
|
151
113
|
```
|
|
152
114
|
|
|
153
|
-
|
|
115
|
+
## Dependency caching and reuse
|
|
116
|
+
|
|
117
|
+
For faster builds when compiling multiple times with the same dependencies, you can resolve dependencies once and reuse them:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import {
|
|
121
|
+
initMoveCompiler,
|
|
122
|
+
resolveDependencies,
|
|
123
|
+
buildMovePackage
|
|
124
|
+
} from "@zktx.io/sui-move-builder";
|
|
125
|
+
|
|
126
|
+
await initMoveCompiler();
|
|
154
127
|
|
|
155
|
-
|
|
128
|
+
const files = {
|
|
129
|
+
"Move.toml": `...`,
|
|
130
|
+
"sources/main.move": "...",
|
|
131
|
+
};
|
|
156
132
|
|
|
157
|
-
1.
|
|
158
|
-
|
|
159
|
-
- Resolves transitive dependencies recursively
|
|
160
|
-
- Handles version conflicts (first version wins)
|
|
161
|
-
- Converts local dependencies to git dependencies for monorepos
|
|
133
|
+
// 1. Resolve dependencies once
|
|
134
|
+
const deps = await resolveDependencies({ files, network: "mainnet" });
|
|
162
135
|
|
|
163
|
-
2.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
136
|
+
// 2. Build multiple times without re-resolving dependencies
|
|
137
|
+
const result1 = await buildMovePackage({
|
|
138
|
+
files,
|
|
139
|
+
network: "mainnet",
|
|
140
|
+
resolvedDependencies: deps, // Skip dependency resolution
|
|
141
|
+
});
|
|
167
142
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
- Each package compiles with its own edition
|
|
171
|
-
- Prepares format for WASM compiler
|
|
143
|
+
// Modify source code
|
|
144
|
+
files["sources/main.move"] = "// updated code...";
|
|
172
145
|
|
|
173
|
-
|
|
146
|
+
// 3. Build again with cached dependencies (much faster!)
|
|
147
|
+
const result2 = await buildMovePackage({
|
|
148
|
+
files,
|
|
149
|
+
network: "mainnet",
|
|
150
|
+
resolvedDependencies: deps, // Reuse same dependencies
|
|
151
|
+
});
|
|
152
|
+
```
|
|
174
153
|
|
|
175
|
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
154
|
+
**Benefits:**
|
|
155
|
+
- ⚡ Faster builds when dependencies haven't changed
|
|
156
|
+
- 🔄 Useful for watch mode or iterative development
|
|
157
|
+
- 💾 Reduce network requests by caching dependency resolution
|
|
178
158
|
|
|
179
159
|
## Local test page
|
|
180
160
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`),
|
|
3
|
-
`,
|
|
4
|
-
`,
|
|
5
|
-
`,m=!0;else{if(g.includes("edition ="))continue;
|
|
6
|
-
`}
|
|
7
|
-
`),m||(
|
|
8
|
-
`),
|
|
9
|
-
`,
|
|
1
|
+
"use strict";var U=Object.create;var b=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var E=(a,e)=>{for(var t in e)b(a,t,{get:e[t],enumerable:!0})},L=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of O(e))!j.call(a,n)&&n!==t&&b(a,n,{get:()=>e[n],enumerable:!(i=B(e,n))||i.enumerable});return a};var H=(a,e,t)=>(t=a!=null?U(W(a)):{},L(e||!a||!a.__esModule?b(t,"default",{value:a,enumerable:!0}):t,a)),V=a=>L(b({},"__esModule",{value:!0}),a);var ie={};E(ie,{buildMovePackage:()=>X,compileRaw:()=>ne,fetchPackageFromGitHub:()=>C,getSuiMoveVersion:()=>Y,getSuiVersion:()=>ee,getWasmBindings:()=>te,initMoveCompiler:()=>Z,resolveDependencies:()=>_});module.exports=V(ie);var M=class{async fetch(e,t,i){throw new Error("Not implemented")}async fetchFile(e,t,i){throw new Error("Not implemented")}},k=class extends M{constructor(){super(),this.cache=new Map}async fetch(e,t,i){let{owner:n,repo:s}=this.parseGitUrl(e);if(!n||!s)throw new Error(`Invalid git URL: ${e}`);let o=`https://api.github.com/repos/${n}/${s}/git/trees/${t}?recursive=1`,d;try{let c=await fetch(o);if(!c.ok)throw c.status===403||c.status===429?new Error("GitHub API rate limit exceeded."):new Error(`Failed to fetch tree: ${c.statusText}`);d=await c.json()}catch{return{}}let r={},l=[];for(let c of d.tree){if(c.type!=="blob")continue;let p=c.path;if(i){if(!c.path.startsWith(i))continue;p=c.path.slice(i.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 m=`https://raw.githubusercontent.com/${n}/${s}/${t}/${c.path}`,g=this.fetchContent(m).then(u=>{u&&(r[p]=u)});l.push(g)}return await Promise.all(l),r}async fetchFile(e,t,i){let{owner:n,repo:s}=this.parseGitUrl(e);if(!n||!s)throw new Error(`Invalid git URL: ${e}`);let o=`https://raw.githubusercontent.com/${n}/${s}/${t}/${i}`;return this.fetchContent(o)}async fetchContent(e){if(this.cache.has(e))return this.cache.get(e)??null;try{let t=await fetch(e);if(!t.ok)return null;let i=await t.text();return this.cache.set(e,i),i}catch{return null}}parseGitUrl(e){try{let i=new URL(e).pathname.split("/").filter(n=>n);if(i.length>=2){let n=i[1];return n.endsWith(".git")&&(n=n.slice(0,-4)),{owner:i[0],repo:n}}}catch{}return{owner:null,repo:null}}};function z(a){let e=!1,t="";for(let i=0;i<a.length;i++){let n=a[i];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return a.slice(0,i)}return a}function x(a){let e=a.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 G(a){let e={},t=a.trim().replace(/^\{/,"").replace(/\}$/,""),i="",n=!1,s="",o=[];for(let d=0;d<t.length;d++){let r=t[d];if((r==='"'||r==="'")&&(!n||r===s)&&(n=!n,s=r),!n&&r===","){o.push(i),i="";continue}i+=r}i.trim()&&o.push(i);for(let d of o){let r=d.indexOf("=");if(r===-1)continue;let l=d.slice(0,r).trim(),c=d.slice(r+1).trim();e[l]=x(c)}return e}function q(a){let e=[],t=a.trim().replace(/^\[/,"").replace(/\]$/,""),i="",n=!1,s="",o=0;for(let d=0;d<t.length;d++){let r=t[d];if((r==='"'||r==="'")&&(!n||r===s)&&(n=!n,s=n?r:""),!n&&(r==="{"&&o++,r==="}"&&o--,r===","&&o===0)){i.trim()&&e.push(F(i.trim())),i="";continue}i+=r}return i.trim()&&e.push(F(i.trim())),e}function F(a){return a.startsWith("{")?G(a):x(a)}function y(a){let e={},t=null,i=!1,n=a.split(/\r?\n/);function s(o,d){let r=o;for(let l of d){if(!(l in r))return;r=r[l]}return r}for(let o of n){let d=z(o).trim();if(!d)continue;let r=d.match(/^\[\[([^\]]+)\]\]$/);if(r){t=r[1].trim(),i=!0;let u=t.split("."),f=e;for(let v=0;v<u.length-1;v++){let D=u[v];D in f||(f[D]={}),f=f[D]}let h=u[u.length-1];Array.isArray(f[h])||(f[h]=[]),f[h].push({});continue}let l=d.match(/^\[([^\]]+)\]$/);if(l){t=l[1].trim(),i=!1;continue}let c=d.indexOf("=");if(c===-1||!t)continue;let p=d.slice(0,c).trim(),m=d.slice(c+1).trim(),g;if(m.startsWith("{")?g=G(m):m.startsWith("[")?g=q(m):g=x(m),i){let u=t.split("."),f=s(e,u);if(Array.isArray(f)&&f.length>0){let h=f[f.length-1];h[p]=g}}else{let u=t.split("."),f=e;for(let v of u)v in f||(f[v]={}),f=f[v];let h=t==="package"?p.replace(/-/g,"_"):p;f[h]=g}}return e}var P=class{constructor(e){this.packageTable=new Map;this.graph=new Map;this.alwaysDeps=new Set(["Sui","MoveStdlib"]);this.root=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,i){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,i=new Set,n=s=>{if(i.has(s))return;i.add(s),t.add(s);let o=this.graph.get(s);if(o)for(let d of o)n(d)};return n(e),t.delete(e),t}topologicalOrder(){let e=new Set,t=[],i=n=>{if(e.has(n))return;e.add(n);let s=this.graph.get(n);if(s)for(let o of s)i(o);t.push(n)};i(this.root);for(let n of this.packageTable.keys())i(n);return t}detectCycle(){let e=new Set,t=new Set,i=new Map,n=s=>{e.add(s),t.add(s);let o=this.graph.get(s);if(o)for(let d of o)if(e.has(d)){if(t.has(d)){let r=[d],l=s;for(;l!==d;)r.unshift(l),l=i.get(l);return r.unshift(d),r}}else{i.set(d,s);let r=n(d);if(r)return r}return t.delete(s),null};for(let s of this.packageTable.keys())if(!e.has(s)){let o=n(s);if(o)return o}return null}getRootPackage(){return this.packageTable.get(this.root)}getRootName(){return this.root}isAlwaysDep(e){return this.alwaysDeps.has(e)}};var S=class{constructor(e,t={}){this.unifiedAddressTable=new Map;this.packageResolvedTables=new Map;this.graph=e,this.buildConfig=t}async resolve(){let e=this.graph.topologicalOrder();for(let t of e){let i=this.graph.getPackage(t);if(i)for(let[n,s]of Object.entries(i.manifest.addresses)){let o=this.normalizeAddress(s);this.unifiedAddressTable.has(n)&&this.unifiedAddressTable.get(n)!==o||this.unifiedAddressTable.set(n,o)}}for(let t of this.graph.getAllPackages()){let i={};for(let[n,s]of this.unifiedAddressTable.entries())i[n]=s;this.packageResolvedTables.set(t.id.name,i),t.resolvedTable=i}}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,i]of this.unifiedAddressTable.entries())e[t]=i;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 R=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 i=this.resolvedGraph.getImmediateDependencies(this.rootPackageName),n=this.resolvedGraph.topologicalOrder();for(let s of n){if(s===this.rootPackageName)continue;let o=this.resolvedGraph.getPackage(s);if(!o)continue;let d=e.get(s)||{},r=this.extractSourcePaths(s,d),l=o.manifest.edition||"legacy",c={name:s,isImmediate:i.has(s),sourcePaths:r,addressMapping:o.resolvedTable||{},compilerConfig:{edition:l,flavor:"sui"},moduleFormat:r.length>0?"Source":"Bytecode",edition:l};this.dependencies.push(c)}}extractSourcePaths(e,t){let i=[];for(let n of Object.keys(t))n.endsWith("Move.toml")||n.endsWith("Move.lock")||n.endsWith(".move")&&i.push(n);return i}toPackageGroupedFormat(e){let t=[];for(let i of this.dependencies){let n=e.get(i.name)||{},s={};for(let[o,d]of Object.entries(n)){if(o.endsWith("Move.lock"))continue;let r=`dependencies/${i.name}/${o}`;if(o.endsWith("Move.toml")){let l=this.reconstructDependencyMoveToml(i.name,d,i.edition,i.addressMapping);s[r]=l}else s[r]=d}t.push({name:i.name,files:s,edition:i.edition})}return t}reconstructDependencyMoveToml(e,t,i,n){let s=t.split(`
|
|
2
|
+
`),o=[],d=[],r=!1,l=!1;for(let g of s){let u=g.trim();if(u.startsWith("[package]")){r=!0,l=!1;continue}if(u.startsWith("[dependencies]")){r=!1,l=!0;continue}if(u.startsWith("[")){r=!1,l=!1;continue}r&&u&&o.push(g),l&&u&&d.push(g)}let c=`[package]
|
|
3
|
+
`,p=!1,m=!1;for(let g of o)if(g.includes("name ="))c+=g+`
|
|
4
|
+
`,p=!0;else if(g.includes("version ="))c+=g+`
|
|
5
|
+
`,m=!0;else{if(g.includes("edition ="))continue;c+=g+`
|
|
6
|
+
`}p||(c+=`name = "${e}"
|
|
7
|
+
`),m||(c+=`version = "0.0.0"
|
|
8
|
+
`),c+=`edition = "${i}"
|
|
9
|
+
`,c+=`
|
|
10
10
|
[dependencies]
|
|
11
|
-
`;for(let g of c
|
|
12
|
-
`;
|
|
11
|
+
`;for(let g of d)c+=g+`
|
|
12
|
+
`;c+=`
|
|
13
13
|
[addresses]
|
|
14
|
-
`;for(let[g,u]of Object.entries(n))
|
|
15
|
-
`;return
|
|
14
|
+
`;for(let[g,u]of Object.entries(n))c+=`${g} = "${u}"
|
|
15
|
+
`;return c}getUnifiedAddressTable(){return this.resolvedGraph.getUnifiedAddressTable()}};var $=class{constructor(e,t="mainnet"){this.visited=new Set;this.packageNameCache=new Map;this.packageFiles=new Map;this.fetcher=e,this.network=t}async resolve(e,t){let i=y(e),n=i.package?.name||"RootPackage",s=i.package?.edition;if(t["Move.lock"]){let h=y(t["Move.lock"]);h.move?.["toolchain-version"]?.edition&&(s=h.move["toolchain-version"].edition)}let o=s||"2024.beta",d=new P(n),r=await this.buildPackage(n,null,e,t);s&&(r.manifest.edition=s),d.addPackage(r),this.packageFiles.set(n,t),await this.loadFromLockfile(d,r,t)||await this.buildDependencyGraph(d,r);let c=d.detectCycle();if(c)throw new Error(`Dependency cycle detected: ${c.join(" \u2192 ")}`);let p=new S(d,{});await p.resolve();let m=new R(p);await m.compute(this.packageFiles);let g=this.reconstructMoveToml(i,p.getUnifiedAddressTable(),!0,o),u={...t};delete u["Move.lock"],u["Move.toml"]=g;let f=m.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(u),dependencies:JSON.stringify(f)}}async buildPackage(e,t,i,n){let s=y(i),o={name:s.package?.name||e,version:s.package?.version||"0.0.0",edition:s.package?.edition,publishedAt:s.package?.published_at,addresses:s.addresses||{},dependencies:s.dependencies||{},devDependencies:s["dev-dependencies"]},d=new Map;if(o.dependencies)for(let[l,c]of Object.entries(o.dependencies)){let p=this.parseDependencyInfo(c);p&&d.set(l,p)}return{id:{name:o.name,version:o.version,source:t||{type:"local"}},manifest:o,dependencies:d,devDependencies:new Map}}parseDependencyInfo(e){return e?e.git&&e.rev?{source:{type:"git",git:e.git,rev:e.rev,subdir:e.subdir}}:e.local?{source:{type:"local",local:e.local}}:null:null}async buildDependencyGraph(e,t){for(let[i,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||"",u=n.source.local,f=this.resolveRelativePath(g,u);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:f}}else continue;if(n.source.type!=="git")continue;let s=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(s)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(s);let o=n.source.subdir;!o&&n.source.git&&this.isSuiRepo(n.source.git)&&(o=this.inferSuiFrameworkSubdir(i),o&&(n.source.subdir=o));let d=await this.fetcher.fetch(n.source.git,n.source.rev,o),r=null,l=`Move.${this.network}.toml`;for(let[g,u]of Object.entries(d))if(g.endsWith(l)){r=u;break}if(!r){for(let[g,u]of Object.entries(d))if(g.endsWith("Move.toml")){r=u;break}}if(!r)continue;let c=await this.buildPackage(i,n.source,r,d),p=this.packageNameCache.get(c.manifest.name);if(p){let g=this.findPackageBySource(e,p);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.packageNameCache.set(c.manifest.name,n.source);let m=d["Move.lock"];if(m){let g=y(m);if(g.env?.[this.network]){let u=g.env[this.network]["latest-published-id"]||g.env[this.network]["original-published-id"];u&&(c.manifest.publishedAt=u,c.manifest.addresses[c.manifest.name]=this.normalizeAddress(u))}c.manifest.edition||(c.manifest.edition="legacy")}if(!c.manifest.publishedAt){let g={Sui:"0x2",MoveStdlib:"0x1",SuiSystem:"0x3",Bridge:"0xb"};g[i]&&(c.manifest.publishedAt=g[i])}e.addPackage(c),e.addDependency(t.id.name,c.id.name,n),this.packageFiles.set(c.id.name,d),await this.buildDependencyGraph(e,c)}}findPackageBySource(e,t){for(let i of e.getAllPackages()){let n=i.id.source;if(n.type===t.type&&n.git===t.git&&n.rev===t.rev&&n.subdir===t.subdir)return i}}resolveRelativePath(e,t){let i=e?e.split("/").filter(Boolean):[],n=t.split("/").filter(Boolean),s=[...i];for(let o of n)o===".."?s.length>0&&s.pop():o!=="."&&s.push(o);return s.join("/")}async computeManifestDigest(e){let i=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",i);return Array.from(new Uint8Array(n)).map(d=>d.toString(16).padStart(2,"0")).join("").toUpperCase()}async loadFromLockfile(e,t,i){let n=i["Move.lock"];if(!n)return!1;let s=y(n),o=s.pinned?.[this.network];if(!o)return!1;let d=i["Move.toml"];if(d&&s.move?.manifest_digest&&await this.computeManifestDigest(d)!==s.move.manifest_digest)return!1;let r=new Map;for(let[l,c]of Object.entries(o)){let p=this.lockfileSourceToDependencySource(c.source);if(!p)continue;let m=await this.fetchFromSource(p);if(!m)return!1;let g=m["Move.toml"];if(!g||c["manifest-digest"]&&await this.computeManifestDigest(g)!==c["manifest-digest"])return!1;let u=await this.buildPackage(l,p,g,m);r.set(l,u),this.packageFiles.set(u.manifest.name,m),(p.type!=="local"||!("root"in c.source))&&e.addPackage(u)}for(let[l,c]of Object.entries(o)){let p=r.get(l);if(p&&c.deps)for(let[m,g]of Object.entries(c.deps)){let u=r.get(g);if(u){let f=p.dependencies.get(m);f&&e.addDependency(p.id.name,u.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,i,n){let o=`[package]
|
|
16
16
|
name = "${e.package.name}"
|
|
17
17
|
version = "${e.package.version}"
|
|
18
|
-
`,
|
|
19
|
-
`),
|
|
18
|
+
`,d=n||e.package.edition;if(d&&(o+=`edition = "${d}"
|
|
19
|
+
`),o+=`
|
|
20
20
|
[dependencies]
|
|
21
|
-
`,e.dependencies)for(let[r,l]of Object.entries(e.dependencies)){let
|
|
22
|
-
`:
|
|
23
|
-
`:
|
|
24
|
-
`)}
|
|
21
|
+
`,e.dependencies)for(let[r,l]of Object.entries(e.dependencies)){let c=l;c.local?o+=`${r} = { local = "${c.local}" }
|
|
22
|
+
`:c.git&&c.rev&&(c.subdir?o+=`${r} = { git = "${c.git}", subdir = "${c.subdir}", rev = "${c.rev}" }
|
|
23
|
+
`:o+=`${r} = { git = "${c.git}", rev = "${c.rev}" }
|
|
24
|
+
`)}o+=`
|
|
25
25
|
[addresses]
|
|
26
|
-
`;for(let[r,l]of Object.entries(t))
|
|
27
|
-
`;return
|
|
28
|
-
`))}function
|
|
29
|
-
`))}function ie(s){let e={...s??{}};if(e["dependencies/MoveStdlib/Move.toml"])return e;let t=[{name:"MoveStdlib",id:"0x1"},{name:"Sui",id:"0x2"},{name:"SuiSystem",id:"0x3"},{name:"Bridge",id:"0xb"}];for(let i of t){let n=`dependencies/${i.name}/Move.toml`;e[n]||(e[n]=["[package]",`name = "${i.name}"`,'version = "0.0.0"',`published-at = "${E(i.id)}"`,""].join(`
|
|
30
|
-
`))}return e}function O(s){return!!(s?.["dependencies/MoveStdlib/Move.toml"]&&s?.["dependencies/Sui/Move.toml"])}function B(s){return typeof s=="string"?JSON.parse(s):s}async function se(s){await b(s?.wasm)}async function re(s){try{let e=s.dependencies??{},t={...s.files},i=typeof t["Move.toml"]=="string";if(s.autoSystemDeps&&i){let l=te(t["Move.toml"]);O(e)||(l=ne(l)),t["Move.toml"]=l}if(s.autoSystemDeps&&!O(e)&&i){let l=await x(t["Move.toml"],t,new k,s.network);t=B(l.files),e=B(l.dependencies)}else s.autoSystemDeps&&(e=ie(e));let n=await b(s.wasm),o=s.ansiColor&&typeof n.compile_with_color=="function"?n.compile_with_color($(t),$(e),!0):n.compile($(t),$(e)),a=W(o),c=a.success(),r=a.output();return c?ee(r):N(r)}catch(e){return N(e)}}async function oe(s){return(await b(s?.wasm)).sui_move_version()}async function ae(s){return(await b(s?.wasm)).sui_version()}async function ce(s){return b(s?.wasm)}async function de(s,e,t){let i=await b(t?.wasm),n=t?.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(s,e,!0):i.compile(s,e),o=W(n);return{success:o.success(),output:o.output()}}0&&(module.exports={Fetcher,GitHubFetcher,Resolver,buildMovePackage,compileRaw,fetchPackageFromGitHub,fetchPackagesFromGitHub,getSuiMoveVersion,getSuiVersion,getWasmBindings,githubUrl,initMoveCompiler,parseGitHubUrl,parseToml,resolve});
|
|
26
|
+
`;for(let[r,l]of Object.entries(t))o+=`${r} = "${l}"
|
|
27
|
+
`;return o}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 I(a,e,t,i="mainnet"){return new $(t,i).resolve(a,e)}function K(a){try{let e=new URL(a);if(e.hostname!=="github.com")return null;let t=e.pathname.split("/").filter(Boolean);if(t.length<2)return null;let i=t[0],n=t[1],s="main",o;return t.length>=4&&t[2]==="tree"&&(s=t[3],t.length>4&&(o=t.slice(4).join("/"))),{owner:i,repo:n,ref:s,subdir:o}}catch{return null}}async function C(a,e){let t=K(a);if(!t)throw new Error(`Invalid GitHub URL: ${a}`);let i=e?.fetcher||new k,n=e?.includeLock!==!1,s=`https://github.com/${t.owner}/${t.repo}.git`,o=await i.fetch(s,t.ref,t.subdir);if(!n&&o["Move.lock"]){let{"Move.lock":d,...r}=o;return r}return o}var A;async function w(a){return A||(A=import("./sui_move_wasm.js").then(async e=>(a?await e.default({module_or_path:a}):await e.default(),e))),A}function T(a){return{success:!1,error:a instanceof Error?a.message:typeof a=="string"?a:"Unknown error"}}function N(a){if(typeof a!="object"||a===null)throw new Error("Unexpected compile result shape from wasm");let e=a;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 Q(a){let e=t=>t.map(i=>i.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(a);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let i=typeof t.digest=="string"?t.digest:e(t.digest);return{success:!0,modules:t.modules,dependencies:t.dependencies,digest:i}}catch(t){return T(t)}}function J(a){let e=[{name:"Sui",git:"https://github.com/MystenLabs/sui.git",subdir:"crates/sui-framework/packages/sui-framework",rev:"framework/mainnet"},{name:"MoveStdlib",git:"https://github.com/MystenLabs/sui.git",subdir:"crates/sui-framework/packages/move-stdlib",rev:"framework/mainnet"}],t=a.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,s=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[dependencies\]\s*$/.test(t[r])){n=r;for(let l=r+1;l<t.length;l++)if(i.test(t[l])){s=l;break}break}let o=new Set;if(n>=0)for(let r=n+1;r<s;r++){let l=t[r].trim();if(!l||l.startsWith("#"))continue;let c=l.match(/^([A-Za-z0-9_.-]+)\s*=/);c&&o.add(c[1])}let d=e.filter(r=>!o.has(r.name)).map(r=>`${r.name} = { git = "${r.git}", subdir = "${r.subdir}", rev = "${r.rev}" }`);return d.length===0?a:(n>=0?t.splice(s,0,...d):t.push("","[dependencies]",...d),t.join(`
|
|
28
|
+
`))}async function Z(a){await w(a?.wasm)}async function _(a){let e=a.files["Move.toml"]||"";e&&(e=J(e));let t=await I(e,{...a.files,"Move.toml":e},new k,a.network);return{files:t.files,dependencies:t.dependencies}}async function X(a){try{let e=a.resolvedDependencies?a.resolvedDependencies:await _(a),t=await w(a.wasm),i=a.ansiColor&&typeof t.compile_with_color=="function"?t.compile_with_color(e.files,e.dependencies,!0):t.compile(e.files,e.dependencies),n=N(i),s=n.success(),o=n.output();return s?Q(o):T(o)}catch(e){return T(e)}}async function Y(a){return(await w(a?.wasm)).sui_move_version()}async function ee(a){return(await w(a?.wasm)).sui_version()}async function te(a){return w(a?.wasm)}async function ne(a,e,t){let i=await w(t?.wasm),n=t?.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(a,e,!0):i.compile(a,e),s=N(n);return{success:s.success(),output:s.output()}}0&&(module.exports={buildMovePackage,compileRaw,fetchPackageFromGitHub,getSuiMoveVersion,getSuiVersion,getWasmBindings,initMoveCompiler,resolveDependencies});
|
package/dist/index.d.cts
CHANGED
|
@@ -17,112 +17,10 @@ declare class GitHubFetcher extends Fetcher {
|
|
|
17
17
|
private parseGitUrl;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* New Resolver using 3-layer architecture matching Sui CLI
|
|
22
|
-
*
|
|
23
|
-
* Layer 1: DependencyGraph - Build DAG of packages
|
|
24
|
-
* Layer 2: ResolvedGraph - Unified address resolution
|
|
25
|
-
* Layer 3: CompilationDependencies - Compiler-ready format
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
declare class Resolver {
|
|
29
|
-
private fetcher;
|
|
30
|
-
private network;
|
|
31
|
-
private visited;
|
|
32
|
-
private packageNameCache;
|
|
33
|
-
private packageFiles;
|
|
34
|
-
constructor(fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet");
|
|
35
|
-
/**
|
|
36
|
-
* Main resolve function using 3-layer architecture
|
|
37
|
-
*/
|
|
38
|
-
resolve(rootMoveToml: string, rootFiles: Record<string, string>): Promise<{
|
|
39
|
-
files: string;
|
|
40
|
-
dependencies: string;
|
|
41
|
-
}>;
|
|
42
|
-
/**
|
|
43
|
-
* Build a Package object from Move.toml and files
|
|
44
|
-
*/
|
|
45
|
-
private buildPackage;
|
|
46
|
-
/**
|
|
47
|
-
* Parse dependency info from Move.toml
|
|
48
|
-
*/
|
|
49
|
-
private parseDependencyInfo;
|
|
50
|
-
/**
|
|
51
|
-
* Recursively build the dependency graph
|
|
52
|
-
*/
|
|
53
|
-
private buildDependencyGraph;
|
|
54
|
-
/**
|
|
55
|
-
* Find a package in the graph by its source
|
|
56
|
-
*/
|
|
57
|
-
private findPackageBySource;
|
|
58
|
-
/**
|
|
59
|
-
* Resolve relative path for local dependencies
|
|
60
|
-
* Example: parentSubdir="packages/deepbook", localPath="../token" -> "packages/token"
|
|
61
|
-
*/
|
|
62
|
-
private resolveRelativePath;
|
|
63
|
-
/**
|
|
64
|
-
* Compute manifest digest for lockfile validation (Sui CLI compatible)
|
|
65
|
-
*/
|
|
66
|
-
private computeManifestDigest;
|
|
67
|
-
/**
|
|
68
|
-
* Load dependency graph from lockfile (Sui CLI: load_from_lockfile)
|
|
69
|
-
* Returns null if lockfile is missing or invalid
|
|
70
|
-
*/
|
|
71
|
-
private loadFromLockfile;
|
|
72
|
-
/**
|
|
73
|
-
* Convert lockfile dependency source to our DependencySource format
|
|
74
|
-
*/
|
|
75
|
-
private lockfileSourceToDependencySource;
|
|
76
|
-
/**
|
|
77
|
-
* Fetch files from a dependency source
|
|
78
|
-
*/
|
|
79
|
-
private fetchFromSource;
|
|
80
|
-
/**
|
|
81
|
-
* Reconstruct Move.toml with unified addresses
|
|
82
|
-
*/
|
|
83
|
-
private reconstructMoveToml;
|
|
84
|
-
/**
|
|
85
|
-
* Normalize address to 0x-prefixed 64-char hex
|
|
86
|
-
*/
|
|
87
|
-
private normalizeAddress;
|
|
88
|
-
/**
|
|
89
|
-
* Check if git URL is Sui repository
|
|
90
|
-
*/
|
|
91
|
-
private isSuiRepo;
|
|
92
|
-
/**
|
|
93
|
-
* Infer subdir for Sui framework packages
|
|
94
|
-
*/
|
|
95
|
-
private inferSuiFrameworkSubdir;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Main resolve function (backward compatible)
|
|
99
|
-
*/
|
|
100
|
-
declare function resolve(rootMoveTomlContent: string, rootSourceFiles: Record<string, string>, fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet"): Promise<{
|
|
101
|
-
files: string;
|
|
102
|
-
dependencies: string;
|
|
103
|
-
}>;
|
|
104
|
-
|
|
105
|
-
declare function parseToml(content: string): any;
|
|
106
|
-
|
|
107
20
|
/**
|
|
108
21
|
* Utility functions for fetching Move packages from GitHub
|
|
109
22
|
*/
|
|
110
23
|
|
|
111
|
-
/**
|
|
112
|
-
* Parse GitHub URL to extract owner, repo, branch/tag, and subdir
|
|
113
|
-
*
|
|
114
|
-
* Supported formats:
|
|
115
|
-
* - https://github.com/owner/repo
|
|
116
|
-
* - https://github.com/owner/repo/tree/branch
|
|
117
|
-
* - https://github.com/owner/repo/tree/branch/path/to/package
|
|
118
|
-
* - https://github.com/owner/repo/tree/tag/path/to/package
|
|
119
|
-
*/
|
|
120
|
-
declare function parseGitHubUrl(url: string): {
|
|
121
|
-
owner: string;
|
|
122
|
-
repo: string;
|
|
123
|
-
ref: string;
|
|
124
|
-
subdir?: string;
|
|
125
|
-
} | null;
|
|
126
24
|
/**
|
|
127
25
|
* Fetch a Move package from GitHub URL
|
|
128
26
|
*
|
|
@@ -150,54 +48,24 @@ declare function fetchPackageFromGitHub(url: string, options?: {
|
|
|
150
48
|
/** Include Move.lock file (default: true) */
|
|
151
49
|
includeLock?: boolean;
|
|
152
50
|
}): Promise<Record<string, string>>;
|
|
153
|
-
/**
|
|
154
|
-
* Fetch multiple packages from GitHub URLs
|
|
155
|
-
*
|
|
156
|
-
* @param urls - Array of GitHub URLs or URL-to-alias mappings
|
|
157
|
-
* @returns Object mapping package names to their files
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```ts
|
|
161
|
-
* const packages = await fetchPackagesFromGitHub([
|
|
162
|
-
* 'https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework',
|
|
163
|
-
* 'https://github.com/MystenLabs/deepbookv3/tree/main/packages/deepbook'
|
|
164
|
-
* ]);
|
|
165
|
-
*
|
|
166
|
-
* // packages = {
|
|
167
|
-
* // 'Sui': { 'Move.toml': '...', ... },
|
|
168
|
-
* // 'deepbook': { 'Move.toml': '...', ... }
|
|
169
|
-
* // }
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
declare function fetchPackagesFromGitHub(urls: string[] | Record<string, string>, options?: {
|
|
173
|
-
fetcher?: GitHubFetcher;
|
|
174
|
-
includeLock?: boolean;
|
|
175
|
-
}): Promise<Record<string, Record<string, string>>>;
|
|
176
|
-
/**
|
|
177
|
-
* Create a shorthand GitHub URL for common repositories
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* ```ts
|
|
181
|
-
* githubUrl('MystenLabs/sui', 'framework/mainnet', 'crates/sui-framework/packages/sui-framework')
|
|
182
|
-
* // Returns: https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
declare function githubUrl(repo: string, // 'owner/repo'
|
|
186
|
-
ref?: string, subdir?: string): string;
|
|
187
51
|
|
|
52
|
+
interface ResolvedDependencies {
|
|
53
|
+
/** JSON string of resolved files for the root package */
|
|
54
|
+
files: string;
|
|
55
|
+
/** JSON string of resolved dependencies */
|
|
56
|
+
dependencies: string;
|
|
57
|
+
}
|
|
188
58
|
interface BuildInput {
|
|
189
59
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
190
60
|
files: Record<string, string>;
|
|
191
|
-
/** Optional dependency files keyed by path. */
|
|
192
|
-
dependencies?: Record<string, string>;
|
|
193
61
|
/** Optional custom URL for the wasm binary. Defaults to bundled wasm next to this module. */
|
|
194
62
|
wasm?: string | URL;
|
|
195
63
|
/** Emit ANSI color codes in diagnostics when available. */
|
|
196
64
|
ansiColor?: boolean;
|
|
197
|
-
/** Inject standard Sui system packages when missing (CLI-like behavior). */
|
|
198
|
-
autoSystemDeps?: boolean;
|
|
199
65
|
/** Network environment (mainnet, testnet, devnet). Defaults to mainnet. */
|
|
200
66
|
network?: "mainnet" | "testnet" | "devnet";
|
|
67
|
+
/** Optional pre-resolved dependencies. If provided, dependency resolution will be skipped. */
|
|
68
|
+
resolvedDependencies?: ResolvedDependencies;
|
|
201
69
|
}
|
|
202
70
|
interface BuildSuccess {
|
|
203
71
|
success: true;
|
|
@@ -217,6 +85,11 @@ type WasmModule = typeof __sui_move_wasm_js;
|
|
|
217
85
|
declare function initMoveCompiler(options?: {
|
|
218
86
|
wasm?: string | URL;
|
|
219
87
|
}): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve dependencies for a Move package without compiling.
|
|
90
|
+
* This function can be used to resolve dependencies once and reuse them across multiple builds.
|
|
91
|
+
*/
|
|
92
|
+
declare function resolveDependencies(input: Omit<BuildInput, "resolvedDependencies">): Promise<ResolvedDependencies>;
|
|
220
93
|
/** Compile a Move package in memory using the bundled Move compiler wasm. */
|
|
221
94
|
declare function buildMovePackage(input: BuildInput): Promise<BuildSuccess | BuildFailure>;
|
|
222
95
|
/** Sui Move version baked into the wasm (e.g. from Cargo.lock). */
|
|
@@ -241,4 +114,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
241
114
|
}>;
|
|
242
115
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
243
116
|
|
|
244
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess,
|
|
117
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,112 +17,10 @@ declare class GitHubFetcher extends Fetcher {
|
|
|
17
17
|
private parseGitUrl;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* New Resolver using 3-layer architecture matching Sui CLI
|
|
22
|
-
*
|
|
23
|
-
* Layer 1: DependencyGraph - Build DAG of packages
|
|
24
|
-
* Layer 2: ResolvedGraph - Unified address resolution
|
|
25
|
-
* Layer 3: CompilationDependencies - Compiler-ready format
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
declare class Resolver {
|
|
29
|
-
private fetcher;
|
|
30
|
-
private network;
|
|
31
|
-
private visited;
|
|
32
|
-
private packageNameCache;
|
|
33
|
-
private packageFiles;
|
|
34
|
-
constructor(fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet");
|
|
35
|
-
/**
|
|
36
|
-
* Main resolve function using 3-layer architecture
|
|
37
|
-
*/
|
|
38
|
-
resolve(rootMoveToml: string, rootFiles: Record<string, string>): Promise<{
|
|
39
|
-
files: string;
|
|
40
|
-
dependencies: string;
|
|
41
|
-
}>;
|
|
42
|
-
/**
|
|
43
|
-
* Build a Package object from Move.toml and files
|
|
44
|
-
*/
|
|
45
|
-
private buildPackage;
|
|
46
|
-
/**
|
|
47
|
-
* Parse dependency info from Move.toml
|
|
48
|
-
*/
|
|
49
|
-
private parseDependencyInfo;
|
|
50
|
-
/**
|
|
51
|
-
* Recursively build the dependency graph
|
|
52
|
-
*/
|
|
53
|
-
private buildDependencyGraph;
|
|
54
|
-
/**
|
|
55
|
-
* Find a package in the graph by its source
|
|
56
|
-
*/
|
|
57
|
-
private findPackageBySource;
|
|
58
|
-
/**
|
|
59
|
-
* Resolve relative path for local dependencies
|
|
60
|
-
* Example: parentSubdir="packages/deepbook", localPath="../token" -> "packages/token"
|
|
61
|
-
*/
|
|
62
|
-
private resolveRelativePath;
|
|
63
|
-
/**
|
|
64
|
-
* Compute manifest digest for lockfile validation (Sui CLI compatible)
|
|
65
|
-
*/
|
|
66
|
-
private computeManifestDigest;
|
|
67
|
-
/**
|
|
68
|
-
* Load dependency graph from lockfile (Sui CLI: load_from_lockfile)
|
|
69
|
-
* Returns null if lockfile is missing or invalid
|
|
70
|
-
*/
|
|
71
|
-
private loadFromLockfile;
|
|
72
|
-
/**
|
|
73
|
-
* Convert lockfile dependency source to our DependencySource format
|
|
74
|
-
*/
|
|
75
|
-
private lockfileSourceToDependencySource;
|
|
76
|
-
/**
|
|
77
|
-
* Fetch files from a dependency source
|
|
78
|
-
*/
|
|
79
|
-
private fetchFromSource;
|
|
80
|
-
/**
|
|
81
|
-
* Reconstruct Move.toml with unified addresses
|
|
82
|
-
*/
|
|
83
|
-
private reconstructMoveToml;
|
|
84
|
-
/**
|
|
85
|
-
* Normalize address to 0x-prefixed 64-char hex
|
|
86
|
-
*/
|
|
87
|
-
private normalizeAddress;
|
|
88
|
-
/**
|
|
89
|
-
* Check if git URL is Sui repository
|
|
90
|
-
*/
|
|
91
|
-
private isSuiRepo;
|
|
92
|
-
/**
|
|
93
|
-
* Infer subdir for Sui framework packages
|
|
94
|
-
*/
|
|
95
|
-
private inferSuiFrameworkSubdir;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Main resolve function (backward compatible)
|
|
99
|
-
*/
|
|
100
|
-
declare function resolve(rootMoveTomlContent: string, rootSourceFiles: Record<string, string>, fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet"): Promise<{
|
|
101
|
-
files: string;
|
|
102
|
-
dependencies: string;
|
|
103
|
-
}>;
|
|
104
|
-
|
|
105
|
-
declare function parseToml(content: string): any;
|
|
106
|
-
|
|
107
20
|
/**
|
|
108
21
|
* Utility functions for fetching Move packages from GitHub
|
|
109
22
|
*/
|
|
110
23
|
|
|
111
|
-
/**
|
|
112
|
-
* Parse GitHub URL to extract owner, repo, branch/tag, and subdir
|
|
113
|
-
*
|
|
114
|
-
* Supported formats:
|
|
115
|
-
* - https://github.com/owner/repo
|
|
116
|
-
* - https://github.com/owner/repo/tree/branch
|
|
117
|
-
* - https://github.com/owner/repo/tree/branch/path/to/package
|
|
118
|
-
* - https://github.com/owner/repo/tree/tag/path/to/package
|
|
119
|
-
*/
|
|
120
|
-
declare function parseGitHubUrl(url: string): {
|
|
121
|
-
owner: string;
|
|
122
|
-
repo: string;
|
|
123
|
-
ref: string;
|
|
124
|
-
subdir?: string;
|
|
125
|
-
} | null;
|
|
126
24
|
/**
|
|
127
25
|
* Fetch a Move package from GitHub URL
|
|
128
26
|
*
|
|
@@ -150,54 +48,24 @@ declare function fetchPackageFromGitHub(url: string, options?: {
|
|
|
150
48
|
/** Include Move.lock file (default: true) */
|
|
151
49
|
includeLock?: boolean;
|
|
152
50
|
}): Promise<Record<string, string>>;
|
|
153
|
-
/**
|
|
154
|
-
* Fetch multiple packages from GitHub URLs
|
|
155
|
-
*
|
|
156
|
-
* @param urls - Array of GitHub URLs or URL-to-alias mappings
|
|
157
|
-
* @returns Object mapping package names to their files
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```ts
|
|
161
|
-
* const packages = await fetchPackagesFromGitHub([
|
|
162
|
-
* 'https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework',
|
|
163
|
-
* 'https://github.com/MystenLabs/deepbookv3/tree/main/packages/deepbook'
|
|
164
|
-
* ]);
|
|
165
|
-
*
|
|
166
|
-
* // packages = {
|
|
167
|
-
* // 'Sui': { 'Move.toml': '...', ... },
|
|
168
|
-
* // 'deepbook': { 'Move.toml': '...', ... }
|
|
169
|
-
* // }
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
declare function fetchPackagesFromGitHub(urls: string[] | Record<string, string>, options?: {
|
|
173
|
-
fetcher?: GitHubFetcher;
|
|
174
|
-
includeLock?: boolean;
|
|
175
|
-
}): Promise<Record<string, Record<string, string>>>;
|
|
176
|
-
/**
|
|
177
|
-
* Create a shorthand GitHub URL for common repositories
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* ```ts
|
|
181
|
-
* githubUrl('MystenLabs/sui', 'framework/mainnet', 'crates/sui-framework/packages/sui-framework')
|
|
182
|
-
* // Returns: https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
declare function githubUrl(repo: string, // 'owner/repo'
|
|
186
|
-
ref?: string, subdir?: string): string;
|
|
187
51
|
|
|
52
|
+
interface ResolvedDependencies {
|
|
53
|
+
/** JSON string of resolved files for the root package */
|
|
54
|
+
files: string;
|
|
55
|
+
/** JSON string of resolved dependencies */
|
|
56
|
+
dependencies: string;
|
|
57
|
+
}
|
|
188
58
|
interface BuildInput {
|
|
189
59
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
190
60
|
files: Record<string, string>;
|
|
191
|
-
/** Optional dependency files keyed by path. */
|
|
192
|
-
dependencies?: Record<string, string>;
|
|
193
61
|
/** Optional custom URL for the wasm binary. Defaults to bundled wasm next to this module. */
|
|
194
62
|
wasm?: string | URL;
|
|
195
63
|
/** Emit ANSI color codes in diagnostics when available. */
|
|
196
64
|
ansiColor?: boolean;
|
|
197
|
-
/** Inject standard Sui system packages when missing (CLI-like behavior). */
|
|
198
|
-
autoSystemDeps?: boolean;
|
|
199
65
|
/** Network environment (mainnet, testnet, devnet). Defaults to mainnet. */
|
|
200
66
|
network?: "mainnet" | "testnet" | "devnet";
|
|
67
|
+
/** Optional pre-resolved dependencies. If provided, dependency resolution will be skipped. */
|
|
68
|
+
resolvedDependencies?: ResolvedDependencies;
|
|
201
69
|
}
|
|
202
70
|
interface BuildSuccess {
|
|
203
71
|
success: true;
|
|
@@ -217,6 +85,11 @@ type WasmModule = typeof __sui_move_wasm_js;
|
|
|
217
85
|
declare function initMoveCompiler(options?: {
|
|
218
86
|
wasm?: string | URL;
|
|
219
87
|
}): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve dependencies for a Move package without compiling.
|
|
90
|
+
* This function can be used to resolve dependencies once and reuse them across multiple builds.
|
|
91
|
+
*/
|
|
92
|
+
declare function resolveDependencies(input: Omit<BuildInput, "resolvedDependencies">): Promise<ResolvedDependencies>;
|
|
220
93
|
/** Compile a Move package in memory using the bundled Move compiler wasm. */
|
|
221
94
|
declare function buildMovePackage(input: BuildInput): Promise<BuildSuccess | BuildFailure>;
|
|
222
95
|
/** Sui Move version baked into the wasm (e.g. from Cargo.lock). */
|
|
@@ -241,4 +114,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
241
114
|
}>;
|
|
242
115
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
243
116
|
|
|
244
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess,
|
|
117
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, type ResolvedDependencies, buildMovePackage, compileRaw, fetchPackageFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, resolveDependencies };
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
var
|
|
2
|
-
`),
|
|
3
|
-
`,
|
|
4
|
-
`,
|
|
5
|
-
`,m=!0;else{if(g.includes("edition ="))continue;
|
|
6
|
-
`}
|
|
7
|
-
`),m||(
|
|
8
|
-
`),
|
|
9
|
-
`,
|
|
1
|
+
var D=class{async fetch(e,t,i){throw new Error("Not implemented")}async fetchFile(e,t,i){throw new Error("Not implemented")}},k=class extends D{constructor(){super(),this.cache=new Map}async fetch(e,t,i){let{owner:n,repo:s}=this.parseGitUrl(e);if(!n||!s)throw new Error(`Invalid git URL: ${e}`);let o=`https://api.github.com/repos/${n}/${s}/git/trees/${t}?recursive=1`,c;try{let a=await fetch(o);if(!a.ok)throw a.status===403||a.status===429?new Error("GitHub API rate limit exceeded."):new Error(`Failed to fetch tree: ${a.statusText}`);c=await a.json()}catch{return{}}let r={},l=[];for(let a of c.tree){if(a.type!=="blob")continue;let p=a.path;if(i){if(!a.path.startsWith(i))continue;p=a.path.slice(i.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 m=`https://raw.githubusercontent.com/${n}/${s}/${t}/${a.path}`,g=this.fetchContent(m).then(u=>{u&&(r[p]=u)});l.push(g)}return await Promise.all(l),r}async fetchFile(e,t,i){let{owner:n,repo:s}=this.parseGitUrl(e);if(!n||!s)throw new Error(`Invalid git URL: ${e}`);let o=`https://raw.githubusercontent.com/${n}/${s}/${t}/${i}`;return this.fetchContent(o)}async fetchContent(e){if(this.cache.has(e))return this.cache.get(e)??null;try{let t=await fetch(e);if(!t.ok)return null;let i=await t.text();return this.cache.set(e,i),i}catch{return null}}parseGitUrl(e){try{let i=new URL(e).pathname.split("/").filter(n=>n);if(i.length>=2){let n=i[1];return n.endsWith(".git")&&(n=n.slice(0,-4)),{owner:i[0],repo:n}}}catch{}return{owner:null,repo:null}}};function I(d){let e=!1,t="";for(let i=0;i<d.length;i++){let n=d[i];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return d.slice(0,i)}return d}function M(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 L(d){let e={},t=d.trim().replace(/^\{/,"").replace(/\}$/,""),i="",n=!1,s="",o=[];for(let c=0;c<t.length;c++){let r=t[c];if((r==='"'||r==="'")&&(!n||r===s)&&(n=!n,s=r),!n&&r===","){o.push(i),i="";continue}i+=r}i.trim()&&o.push(i);for(let c of o){let r=c.indexOf("=");if(r===-1)continue;let l=c.slice(0,r).trim(),a=c.slice(r+1).trim();e[l]=M(a)}return e}function C(d){let e=[],t=d.trim().replace(/^\[/,"").replace(/\]$/,""),i="",n=!1,s="",o=0;for(let c=0;c<t.length;c++){let r=t[c];if((r==='"'||r==="'")&&(!n||r===s)&&(n=!n,s=n?r:""),!n&&(r==="{"&&o++,r==="}"&&o--,r===","&&o===0)){i.trim()&&e.push(T(i.trim())),i="";continue}i+=r}return i.trim()&&e.push(T(i.trim())),e}function T(d){return d.startsWith("{")?L(d):M(d)}function y(d){let e={},t=null,i=!1,n=d.split(/\r?\n/);function s(o,c){let r=o;for(let l of c){if(!(l in r))return;r=r[l]}return r}for(let o of n){let c=I(o).trim();if(!c)continue;let r=c.match(/^\[\[([^\]]+)\]\]$/);if(r){t=r[1].trim(),i=!0;let u=t.split("."),f=e;for(let v=0;v<u.length-1;v++){let R=u[v];R in f||(f[R]={}),f=f[R]}let h=u[u.length-1];Array.isArray(f[h])||(f[h]=[]),f[h].push({});continue}let l=c.match(/^\[([^\]]+)\]$/);if(l){t=l[1].trim(),i=!1;continue}let a=c.indexOf("=");if(a===-1||!t)continue;let p=c.slice(0,a).trim(),m=c.slice(a+1).trim(),g;if(m.startsWith("{")?g=L(m):m.startsWith("[")?g=C(m):g=M(m),i){let u=t.split("."),f=s(e,u);if(Array.isArray(f)&&f.length>0){let h=f[f.length-1];h[p]=g}}else{let u=t.split("."),f=e;for(let v of u)v in f||(f[v]={}),f=f[v];let h=t==="package"?p.replace(/-/g,"_"):p;f[h]=g}}return e}var b=class{constructor(e){this.packageTable=new Map;this.graph=new Map;this.alwaysDeps=new Set(["Sui","MoveStdlib"]);this.root=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,i){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,i=new Set,n=s=>{if(i.has(s))return;i.add(s),t.add(s);let o=this.graph.get(s);if(o)for(let c of o)n(c)};return n(e),t.delete(e),t}topologicalOrder(){let e=new Set,t=[],i=n=>{if(e.has(n))return;e.add(n);let s=this.graph.get(n);if(s)for(let o of s)i(o);t.push(n)};i(this.root);for(let n of this.packageTable.keys())i(n);return t}detectCycle(){let e=new Set,t=new Set,i=new Map,n=s=>{e.add(s),t.add(s);let o=this.graph.get(s);if(o)for(let c of o)if(e.has(c)){if(t.has(c)){let r=[c],l=s;for(;l!==c;)r.unshift(l),l=i.get(l);return r.unshift(c),r}}else{i.set(c,s);let r=n(c);if(r)return r}return t.delete(s),null};for(let s of this.packageTable.keys())if(!e.has(s)){let o=n(s);if(o)return o}return null}getRootPackage(){return this.packageTable.get(this.root)}getRootName(){return this.root}isAlwaysDep(e){return this.alwaysDeps.has(e)}};var P=class{constructor(e,t={}){this.unifiedAddressTable=new Map;this.packageResolvedTables=new Map;this.graph=e,this.buildConfig=t}async resolve(){let e=this.graph.topologicalOrder();for(let t of e){let i=this.graph.getPackage(t);if(i)for(let[n,s]of Object.entries(i.manifest.addresses)){let o=this.normalizeAddress(s);this.unifiedAddressTable.has(n)&&this.unifiedAddressTable.get(n)!==o||this.unifiedAddressTable.set(n,o)}}for(let t of this.graph.getAllPackages()){let i={};for(let[n,s]of this.unifiedAddressTable.entries())i[n]=s;this.packageResolvedTables.set(t.id.name,i),t.resolvedTable=i}}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,i]of this.unifiedAddressTable.entries())e[t]=i;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 S=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 i=this.resolvedGraph.getImmediateDependencies(this.rootPackageName),n=this.resolvedGraph.topologicalOrder();for(let s of n){if(s===this.rootPackageName)continue;let o=this.resolvedGraph.getPackage(s);if(!o)continue;let c=e.get(s)||{},r=this.extractSourcePaths(s,c),l=o.manifest.edition||"legacy",a={name:s,isImmediate:i.has(s),sourcePaths:r,addressMapping:o.resolvedTable||{},compilerConfig:{edition:l,flavor:"sui"},moduleFormat:r.length>0?"Source":"Bytecode",edition:l};this.dependencies.push(a)}}extractSourcePaths(e,t){let i=[];for(let n of Object.keys(t))n.endsWith("Move.toml")||n.endsWith("Move.lock")||n.endsWith(".move")&&i.push(n);return i}toPackageGroupedFormat(e){let t=[];for(let i of this.dependencies){let n=e.get(i.name)||{},s={};for(let[o,c]of Object.entries(n)){if(o.endsWith("Move.lock"))continue;let r=`dependencies/${i.name}/${o}`;if(o.endsWith("Move.toml")){let l=this.reconstructDependencyMoveToml(i.name,c,i.edition,i.addressMapping);s[r]=l}else s[r]=c}t.push({name:i.name,files:s,edition:i.edition})}return t}reconstructDependencyMoveToml(e,t,i,n){let s=t.split(`
|
|
2
|
+
`),o=[],c=[],r=!1,l=!1;for(let g of s){let u=g.trim();if(u.startsWith("[package]")){r=!0,l=!1;continue}if(u.startsWith("[dependencies]")){r=!1,l=!0;continue}if(u.startsWith("[")){r=!1,l=!1;continue}r&&u&&o.push(g),l&&u&&c.push(g)}let a=`[package]
|
|
3
|
+
`,p=!1,m=!1;for(let g of o)if(g.includes("name ="))a+=g+`
|
|
4
|
+
`,p=!0;else if(g.includes("version ="))a+=g+`
|
|
5
|
+
`,m=!0;else{if(g.includes("edition ="))continue;a+=g+`
|
|
6
|
+
`}p||(a+=`name = "${e}"
|
|
7
|
+
`),m||(a+=`version = "0.0.0"
|
|
8
|
+
`),a+=`edition = "${i}"
|
|
9
|
+
`,a+=`
|
|
10
10
|
[dependencies]
|
|
11
|
-
`;for(let g of c)
|
|
12
|
-
`;
|
|
11
|
+
`;for(let g of c)a+=g+`
|
|
12
|
+
`;a+=`
|
|
13
13
|
[addresses]
|
|
14
|
-
`;for(let[g,u]of Object.entries(n))
|
|
15
|
-
`;return
|
|
14
|
+
`;for(let[g,u]of Object.entries(n))a+=`${g} = "${u}"
|
|
15
|
+
`;return a}getUnifiedAddressTable(){return this.resolvedGraph.getUnifiedAddressTable()}};var x=class{constructor(e,t="mainnet"){this.visited=new Set;this.packageNameCache=new Map;this.packageFiles=new Map;this.fetcher=e,this.network=t}async resolve(e,t){let i=y(e),n=i.package?.name||"RootPackage",s=i.package?.edition;if(t["Move.lock"]){let h=y(t["Move.lock"]);h.move?.["toolchain-version"]?.edition&&(s=h.move["toolchain-version"].edition)}let o=s||"2024.beta",c=new b(n),r=await this.buildPackage(n,null,e,t);s&&(r.manifest.edition=s),c.addPackage(r),this.packageFiles.set(n,t),await this.loadFromLockfile(c,r,t)||await this.buildDependencyGraph(c,r);let a=c.detectCycle();if(a)throw new Error(`Dependency cycle detected: ${a.join(" \u2192 ")}`);let p=new P(c,{});await p.resolve();let m=new S(p);await m.compute(this.packageFiles);let g=this.reconstructMoveToml(i,p.getUnifiedAddressTable(),!0,o),u={...t};delete u["Move.lock"],u["Move.toml"]=g;let f=m.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(u),dependencies:JSON.stringify(f)}}async buildPackage(e,t,i,n){let s=y(i),o={name:s.package?.name||e,version:s.package?.version||"0.0.0",edition:s.package?.edition,publishedAt:s.package?.published_at,addresses:s.addresses||{},dependencies:s.dependencies||{},devDependencies:s["dev-dependencies"]},c=new Map;if(o.dependencies)for(let[l,a]of Object.entries(o.dependencies)){let p=this.parseDependencyInfo(a);p&&c.set(l,p)}return{id:{name:o.name,version:o.version,source:t||{type:"local"}},manifest:o,dependencies:c,devDependencies:new Map}}parseDependencyInfo(e){return e?e.git&&e.rev?{source:{type:"git",git:e.git,rev:e.rev,subdir:e.subdir}}:e.local?{source:{type:"local",local:e.local}}:null:null}async buildDependencyGraph(e,t){for(let[i,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||"",u=n.source.local,f=this.resolveRelativePath(g,u);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:f}}else continue;if(n.source.type!=="git")continue;let s=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(s)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(s);let o=n.source.subdir;!o&&n.source.git&&this.isSuiRepo(n.source.git)&&(o=this.inferSuiFrameworkSubdir(i),o&&(n.source.subdir=o));let c=await this.fetcher.fetch(n.source.git,n.source.rev,o),r=null,l=`Move.${this.network}.toml`;for(let[g,u]of Object.entries(c))if(g.endsWith(l)){r=u;break}if(!r){for(let[g,u]of Object.entries(c))if(g.endsWith("Move.toml")){r=u;break}}if(!r)continue;let a=await this.buildPackage(i,n.source,r,c),p=this.packageNameCache.get(a.manifest.name);if(p){let g=this.findPackageBySource(e,p);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.packageNameCache.set(a.manifest.name,n.source);let m=c["Move.lock"];if(m){let g=y(m);if(g.env?.[this.network]){let u=g.env[this.network]["latest-published-id"]||g.env[this.network]["original-published-id"];u&&(a.manifest.publishedAt=u,a.manifest.addresses[a.manifest.name]=this.normalizeAddress(u))}a.manifest.edition||(a.manifest.edition="legacy")}if(!a.manifest.publishedAt){let g={Sui:"0x2",MoveStdlib:"0x1",SuiSystem:"0x3",Bridge:"0xb"};g[i]&&(a.manifest.publishedAt=g[i])}e.addPackage(a),e.addDependency(t.id.name,a.id.name,n),this.packageFiles.set(a.id.name,c),await this.buildDependencyGraph(e,a)}}findPackageBySource(e,t){for(let i of e.getAllPackages()){let n=i.id.source;if(n.type===t.type&&n.git===t.git&&n.rev===t.rev&&n.subdir===t.subdir)return i}}resolveRelativePath(e,t){let i=e?e.split("/").filter(Boolean):[],n=t.split("/").filter(Boolean),s=[...i];for(let o of n)o===".."?s.length>0&&s.pop():o!=="."&&s.push(o);return s.join("/")}async computeManifestDigest(e){let i=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",i);return Array.from(new Uint8Array(n)).map(c=>c.toString(16).padStart(2,"0")).join("").toUpperCase()}async loadFromLockfile(e,t,i){let n=i["Move.lock"];if(!n)return!1;let s=y(n),o=s.pinned?.[this.network];if(!o)return!1;let c=i["Move.toml"];if(c&&s.move?.manifest_digest&&await this.computeManifestDigest(c)!==s.move.manifest_digest)return!1;let r=new Map;for(let[l,a]of Object.entries(o)){let p=this.lockfileSourceToDependencySource(a.source);if(!p)continue;let m=await this.fetchFromSource(p);if(!m)return!1;let g=m["Move.toml"];if(!g||a["manifest-digest"]&&await this.computeManifestDigest(g)!==a["manifest-digest"])return!1;let u=await this.buildPackage(l,p,g,m);r.set(l,u),this.packageFiles.set(u.manifest.name,m),(p.type!=="local"||!("root"in a.source))&&e.addPackage(u)}for(let[l,a]of Object.entries(o)){let p=r.get(l);if(p&&a.deps)for(let[m,g]of Object.entries(a.deps)){let u=r.get(g);if(u){let f=p.dependencies.get(m);f&&e.addDependency(p.id.name,u.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,i,n){let o=`[package]
|
|
16
16
|
name = "${e.package.name}"
|
|
17
17
|
version = "${e.package.version}"
|
|
18
|
-
`,c=n||e.package.edition;if(c&&(
|
|
19
|
-
`),
|
|
18
|
+
`,c=n||e.package.edition;if(c&&(o+=`edition = "${c}"
|
|
19
|
+
`),o+=`
|
|
20
20
|
[dependencies]
|
|
21
|
-
`,e.dependencies)for(let[
|
|
22
|
-
`:
|
|
23
|
-
`:
|
|
24
|
-
`)}
|
|
21
|
+
`,e.dependencies)for(let[r,l]of Object.entries(e.dependencies)){let a=l;a.local?o+=`${r} = { local = "${a.local}" }
|
|
22
|
+
`:a.git&&a.rev&&(a.subdir?o+=`${r} = { git = "${a.git}", subdir = "${a.subdir}", rev = "${a.rev}" }
|
|
23
|
+
`:o+=`${r} = { git = "${a.git}", rev = "${a.rev}" }
|
|
24
|
+
`)}o+=`
|
|
25
25
|
[addresses]
|
|
26
|
-
`;for(let[
|
|
27
|
-
`;return
|
|
28
|
-
`))}function
|
|
29
|
-
`))}function q(o){let e={...o??{}};if(e["dependencies/MoveStdlib/Move.toml"])return e;let t=[{name:"MoveStdlib",id:"0x1"},{name:"Sui",id:"0x2"},{name:"SuiSystem",id:"0x3"},{name:"Bridge",id:"0xb"}];for(let i of t){let n=`dependencies/${i.name}/Move.toml`;e[n]||(e[n]=["[package]",`name = "${i.name}"`,'version = "0.0.0"',`published-at = "${U(i.id)}"`,""].join(`
|
|
30
|
-
`))}return e}function j(o){return!!(o?.["dependencies/MoveStdlib/Move.toml"]&&o?.["dependencies/Sui/Move.toml"])}function C(o){return typeof o=="string"?JSON.parse(o):o}async function me(o){await b(o?.wasm)}async function he(o){try{let e=o.dependencies??{},t={...o.files},i=typeof t["Move.toml"]=="string";if(o.autoSystemDeps&&i){let l=z(t["Move.toml"]);j(e)||(l=V(l)),t["Move.toml"]=l}if(o.autoSystemDeps&&!j(e)&&i){let l=await A(t["Move.toml"],t,new v,o.network);t=C(l.files),e=C(l.dependencies)}else o.autoSystemDeps&&(e=q(e));let n=await b(o.wasm),r=o.ansiColor&&typeof n.compile_with_color=="function"?n.compile_with_color(D(t),D(e),!0):n.compile(D(t),D(e)),a=I(r),c=a.success(),s=a.output();return c?H(s):F(s)}catch(e){return F(e)}}async function ke(o){return(await b(o?.wasm)).sui_move_version()}async function ve(o){return(await b(o?.wasm)).sui_version()}async function ye(o){return b(o?.wasm)}async function be(o,e,t){let i=await b(t?.wasm),n=t?.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(o,e,!0):i.compile(o,e),r=I(n);return{success:r.success(),output:r.output()}}export{w as Fetcher,v as GitHubFetcher,R as Resolver,he as buildMovePackage,be as compileRaw,_ as fetchPackageFromGitHub,W as fetchPackagesFromGitHub,ke as getSuiMoveVersion,ve as getSuiVersion,ye as getWasmBindings,E as githubUrl,me as initMoveCompiler,N as parseGitHubUrl,y as parseToml,A as resolve};
|
|
26
|
+
`;for(let[r,l]of Object.entries(t))o+=`${r} = "${l}"
|
|
27
|
+
`;return o}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 F(d,e,t,i="mainnet"){return new x(t,i).resolve(d,e)}function N(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 i=t[0],n=t[1],s="main",o;return t.length>=4&&t[2]==="tree"&&(s=t[3],t.length>4&&(o=t.slice(4).join("/"))),{owner:i,repo:n,ref:s,subdir:o}}catch{return null}}async function _(d,e){let t=N(d);if(!t)throw new Error(`Invalid GitHub URL: ${d}`);let i=e?.fetcher||new k,n=e?.includeLock!==!1,s=`https://github.com/${t.owner}/${t.repo}.git`,o=await i.fetch(s,t.ref,t.subdir);if(!n&&o["Move.lock"]){let{"Move.lock":c,...r}=o;return r}return o}var $;async function w(d){return $||($=import("./sui_move_wasm.js").then(async e=>(d?await e.default({module_or_path:d}):await e.default(),e))),$}function A(d){return{success:!1,error:d instanceof Error?d.message:typeof d=="string"?d:"Unknown error"}}function G(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 U(d){let e=t=>t.map(i=>i.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(d);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let i=typeof t.digest=="string"?t.digest:e(t.digest);return{success:!0,modules:t.modules,dependencies:t.dependencies,digest:i}}catch(t){return A(t)}}function B(d){let e=[{name:"Sui",git:"https://github.com/MystenLabs/sui.git",subdir:"crates/sui-framework/packages/sui-framework",rev:"framework/mainnet"},{name:"MoveStdlib",git:"https://github.com/MystenLabs/sui.git",subdir:"crates/sui-framework/packages/move-stdlib",rev:"framework/mainnet"}],t=d.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,s=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[dependencies\]\s*$/.test(t[r])){n=r;for(let l=r+1;l<t.length;l++)if(i.test(t[l])){s=l;break}break}let o=new Set;if(n>=0)for(let r=n+1;r<s;r++){let l=t[r].trim();if(!l||l.startsWith("#"))continue;let a=l.match(/^([A-Za-z0-9_.-]+)\s*=/);a&&o.add(a[1])}let c=e.filter(r=>!o.has(r.name)).map(r=>`${r.name} = { git = "${r.git}", subdir = "${r.subdir}", rev = "${r.rev}" }`);return c.length===0?d:(n>=0?t.splice(s,0,...c):t.push("","[dependencies]",...c),t.join(`
|
|
28
|
+
`))}async function ce(d){await w(d?.wasm)}async function O(d){let e=d.files["Move.toml"]||"";e&&(e=B(e));let t=await F(e,{...d.files,"Move.toml":e},new k,d.network);return{files:t.files,dependencies:t.dependencies}}async function de(d){try{let e=d.resolvedDependencies?d.resolvedDependencies:await O(d),t=await w(d.wasm),i=d.ansiColor&&typeof t.compile_with_color=="function"?t.compile_with_color(e.files,e.dependencies,!0):t.compile(e.files,e.dependencies),n=G(i),s=n.success(),o=n.output();return s?U(o):A(o)}catch(e){return A(e)}}async function le(d){return(await w(d?.wasm)).sui_move_version()}async function ge(d){return(await w(d?.wasm)).sui_version()}async function ue(d){return w(d?.wasm)}async function pe(d,e,t){let i=await w(t?.wasm),n=t?.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(d,e,!0):i.compile(d,e),s=G(n);return{success:s.success(),output:s.output()}}export{de as buildMovePackage,pe as compileRaw,_ as fetchPackageFromGitHub,le as getSuiMoveVersion,ge as getSuiVersion,ue as getWasmBindings,ce as initMoveCompiler,O as resolveDependencies};
|