@zktx.io/sui-move-builder 0.1.3 → 0.1.4
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 +105 -20
- package/dist/index.cjs +26 -11
- package/dist/index.d.cts +156 -20
- package/dist/index.d.ts +156 -20
- package/dist/index.js +26 -11
- package/dist/sui_move_wasm_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# @zktx.io/sui-move-builder
|
|
2
2
|
|
|
3
|
-
Build Move packages in web or Node.js with dependency
|
|
3
|
+
Build Move packages in web or Node.js with Sui CLI-compatible dependency resolution and compilation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Sui CLI Compatible**: Identical dependency resolution algorithm as Sui CLI
|
|
8
|
+
- ✅ **Lockfile Support**: Reads `Move.lock` for faster, deterministic builds
|
|
9
|
+
- ✅ **Per-Package Editions**: Each package can use its own Move edition (legacy, 2024.alpha, 2024.beta)
|
|
10
|
+
- ✅ **Monorepo Support**: Handles local dependencies in monorepo structures
|
|
11
|
+
- ✅ **Version Conflict Resolution**: Automatically resolves dependency version conflicts
|
|
12
|
+
- ✅ **Browser & Node.js**: Works in both environments with WASM-based compilation
|
|
13
|
+
- ✅ **GitHub Integration**: Fetches dependencies directly from git repositories
|
|
4
14
|
|
|
5
15
|
## Install
|
|
6
16
|
|
|
@@ -48,42 +58,117 @@ if (result.success) {
|
|
|
48
58
|
}
|
|
49
59
|
```
|
|
50
60
|
|
|
51
|
-
##
|
|
61
|
+
## Fetching packages from GitHub
|
|
62
|
+
|
|
63
|
+
Use the utility functions to fetch Move packages directly from GitHub URLs:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import {
|
|
67
|
+
fetchPackageFromGitHub,
|
|
68
|
+
buildMovePackage,
|
|
69
|
+
initMoveCompiler,
|
|
70
|
+
} from "@zktx.io/sui-move-builder";
|
|
71
|
+
|
|
72
|
+
await initMoveCompiler();
|
|
73
|
+
|
|
74
|
+
// Fetch a package from GitHub URL
|
|
75
|
+
const files = await fetchPackageFromGitHub(
|
|
76
|
+
"https://github.com/MystenLabs/sui/tree/framework/mainnet/crates/sui-framework/packages/sui-framework"
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// files = {
|
|
80
|
+
// 'Move.toml': '...',
|
|
81
|
+
// 'Move.lock': '...',
|
|
82
|
+
// 'sources/object.move': '...',
|
|
83
|
+
// ...
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
// Compile directly
|
|
87
|
+
const result = await buildMovePackage({ files });
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Fetch multiple packages
|
|
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
|
|
111
|
+
|
|
112
|
+
The dependency resolver works exactly like Sui CLI:
|
|
113
|
+
|
|
114
|
+
1. **Tries Move.lock first**: If a valid `Move.lock` exists, dependencies are loaded from it (faster, deterministic)
|
|
115
|
+
2. **Falls back to manifests**: If lockfile is missing/invalid, resolves dependencies from `Move.toml` files
|
|
116
|
+
3. **Validates digests**: Checks manifest digests to detect changes
|
|
117
|
+
4. **Handles monorepos**: Converts local dependencies to git dependencies automatically
|
|
52
118
|
|
|
53
119
|
```ts
|
|
54
120
|
import { resolve, GitHubFetcher } from "@zktx.io/sui-move-builder";
|
|
55
121
|
|
|
122
|
+
const files = {
|
|
123
|
+
"Move.toml": `
|
|
124
|
+
[package]
|
|
125
|
+
name = "my_package"
|
|
126
|
+
edition = "2024.beta"
|
|
127
|
+
|
|
128
|
+
[dependencies]
|
|
129
|
+
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/mainnet" }
|
|
130
|
+
deepbook = { git = "https://github.com/MystenLabs/deepbookv3.git", subdir = "packages/deepbook", rev = "main" }
|
|
131
|
+
`,
|
|
132
|
+
"Move.lock": "...", // Optional: will be used if valid
|
|
133
|
+
"sources/main.move": "...",
|
|
134
|
+
};
|
|
135
|
+
|
|
56
136
|
const resolution = await resolve(
|
|
57
137
|
files["Move.toml"],
|
|
58
138
|
files,
|
|
59
|
-
new GitHubFetcher()
|
|
139
|
+
new GitHubFetcher(),
|
|
140
|
+
"mainnet" // network: 'mainnet' | 'testnet' | 'devnet'
|
|
60
141
|
);
|
|
61
142
|
|
|
62
|
-
const filesJson =
|
|
63
|
-
|
|
64
|
-
? JSON.parse(resolution.files)
|
|
65
|
-
: resolution.files;
|
|
66
|
-
const depsJson =
|
|
67
|
-
typeof resolution.dependencies === "string"
|
|
68
|
-
? JSON.parse(resolution.dependencies)
|
|
69
|
-
: resolution.dependencies;
|
|
143
|
+
const filesJson = JSON.parse(resolution.files);
|
|
144
|
+
const depsJson = JSON.parse(resolution.dependencies);
|
|
70
145
|
|
|
71
146
|
const result = await buildMovePackage({
|
|
72
147
|
files: filesJson,
|
|
73
148
|
dependencies: depsJson,
|
|
74
149
|
autoSystemDeps: true,
|
|
75
150
|
});
|
|
151
|
+
```
|
|
76
152
|
|
|
77
|
-
|
|
78
|
-
// the builder fetches them from GitHub using the Sui framework snapshot.
|
|
153
|
+
### How it works
|
|
79
154
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
155
|
+
The resolver implements Sui CLI's 3-layer architecture:
|
|
156
|
+
|
|
157
|
+
1. **Layer 1: Dependency Graph**
|
|
158
|
+
- Builds a DAG of all packages
|
|
159
|
+
- Resolves transitive dependencies recursively
|
|
160
|
+
- Handles version conflicts (first version wins)
|
|
161
|
+
- Converts local dependencies to git dependencies for monorepos
|
|
162
|
+
|
|
163
|
+
2. **Layer 2: Address Resolution**
|
|
164
|
+
- Creates unified address table
|
|
165
|
+
- Resolves all named addresses across packages
|
|
166
|
+
- Uses `Move.lock` addresses when available
|
|
167
|
+
|
|
168
|
+
3. **Layer 3: Compilation Format**
|
|
169
|
+
- Groups dependencies by package
|
|
170
|
+
- Each package compiles with its own edition
|
|
171
|
+
- Prepares format for WASM compiler
|
|
87
172
|
|
|
88
173
|
`buildMovePackage` returns:
|
|
89
174
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var H=Object.create;var S=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var K=(s,e)=>{for(var t in e)S(s,t,{get:e[t],enumerable:!0})},_=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of V(e))!J.call(s,n)&&n!==t&&S(s,n,{get:()=>e[n],enumerable:!(i=z(e,n))||i.enumerable});return s};var Q=(s,e,t)=>(t=s!=null?H(q(s)):{},_(e||!s||!s.__esModule?S(t,"default",{value:s,enumerable:!0}):t,s)),Z=s=>_(S({},"__esModule",{value:!0}),s);var le={};K(le,{Fetcher:()=>w,GitHubFetcher:()=>k,Resolver:()=>P,buildMovePackage:()=>re,compileRaw:()=>de,fetchPackageFromGitHub:()=>L,fetchPackagesFromGitHub:()=>I,getSuiMoveVersion:()=>oe,getSuiVersion:()=>ae,getWasmBindings:()=>ce,githubUrl:()=>U,initMoveCompiler:()=>se,parseGitHubUrl:()=>F,parseToml:()=>v,resolve:()=>x});module.exports=Z(le);var w=class{async fetch(e,t,i){throw new Error("Not implemented")}async fetchFile(e,t,i){throw new Error("Not implemented")}},k=class extends w{constructor(){super(),this.cache=new Map}async fetch(e,t,i){let{owner:n,repo:o}=this.parseGitUrl(e);if(!n||!o)throw new Error(`Invalid git URL: ${e}`);let a=`https://api.github.com/repos/${n}/${o}/git/trees/${t}?recursive=1`,c;try{let d=await fetch(a);if(!d.ok)throw d.status===403||d.status===429?new Error("GitHub API rate limit exceeded."):new Error(`Failed to fetch tree: ${d.statusText}`);c=await d.json()}catch{return{}}let r={},l=[];for(let d of c.tree){if(d.type!=="blob")continue;let f=d.path;if(i){if(!d.path.startsWith(i))continue;f=d.path.slice(i.length),f.startsWith("/")&&(f=f.slice(1))}if(!f.endsWith(".move")&&f!=="Move.toml"&&f!=="Move.lock"&&!f.match(/^Move\.(mainnet|testnet|devnet)\.toml$/))continue;let m=`https://raw.githubusercontent.com/${n}/${o}/${t}/${d.path}`,g=this.fetchContent(m).then(u=>{u&&(r[f]=u)});l.push(g)}return await Promise.all(l),r}async fetchFile(e,t,i){let{owner:n,repo:o}=this.parseGitUrl(e);if(!n||!o)throw new Error(`Invalid git URL: ${e}`);let a=`https://raw.githubusercontent.com/${n}/${o}/${t}/${i}`;return this.fetchContent(a)}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 X(s){let e=!1,t="";for(let i=0;i<s.length;i++){let n=s[i];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return s.slice(0,i)}return s}function T(s){let e=s.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 C(s){let e={},t=s.trim().replace(/^\{/,"").replace(/\}$/,""),i="",n=!1,o="",a=[];for(let c=0;c<t.length;c++){let r=t[c];if((r==='"'||r==="'")&&(!n||r===o)&&(n=!n,o=r),!n&&r===","){a.push(i),i="";continue}i+=r}i.trim()&&a.push(i);for(let c of a){let r=c.indexOf("=");if(r===-1)continue;let l=c.slice(0,r).trim(),d=c.slice(r+1).trim();e[l]=T(d)}return e}function Y(s){let e=[],t=s.trim().replace(/^\[/,"").replace(/\]$/,""),i="",n=!1,o="",a=0;for(let c=0;c<t.length;c++){let r=t[c];if((r==='"'||r==="'")&&(!n||r===o)&&(n=!n,o=n?r:""),!n&&(r==="{"&&a++,r==="}"&&a--,r===","&&a===0)){i.trim()&&e.push(j(i.trim())),i="";continue}i+=r}return i.trim()&&e.push(j(i.trim())),e}function j(s){return s.startsWith("{")?C(s):T(s)}function v(s){let e={},t=null,i=!1,n=s.split(/\r?\n/);function o(a,c){let r=a;for(let l of c){if(!(l in r))return;r=r[l]}return r}for(let a of n){let c=X(a).trim();if(!c)continue;let r=c.match(/^\[\[([^\]]+)\]\]$/);if(r){t=r[1].trim(),i=!0;let u=t.split("."),p=e;for(let y=0;y<u.length-1;y++){let A=u[y];A in p||(p[A]={}),p=p[A]}let h=u[u.length-1];Array.isArray(p[h])||(p[h]=[]),p[h].push({});continue}let l=c.match(/^\[([^\]]+)\]$/);if(l){t=l[1].trim(),i=!1;continue}let d=c.indexOf("=");if(d===-1||!t)continue;let f=c.slice(0,d).trim(),m=c.slice(d+1).trim(),g;if(m.startsWith("{")?g=C(m):m.startsWith("[")?g=Y(m):g=T(m),i){let u=t.split("."),p=o(e,u);if(Array.isArray(p)&&p.length>0){let h=p[p.length-1];h[f]=g}}else{let u=t.split("."),p=e;for(let y of u)y in p||(p[y]={}),p=p[y];let h=t==="package"?f.replace(/-/g,"_"):f;p[h]=g}}return e}var M=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=o=>{if(i.has(o))return;i.add(o),t.add(o);let a=this.graph.get(o);if(a)for(let c of a)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 o=this.graph.get(n);if(o)for(let a of o)i(a);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=o=>{e.add(o),t.add(o);let a=this.graph.get(o);if(a)for(let c of a)if(e.has(c)){if(t.has(c)){let r=[c],l=o;for(;l!==c;)r.unshift(l),l=i.get(l);return r.unshift(c),r}}else{i.set(c,o);let r=n(c);if(r)return r}return t.delete(o),null};for(let o of this.packageTable.keys())if(!e.has(o)){let a=n(o);if(a)return a}return null}getRootPackage(){return this.packageTable.get(this.root)}getRootName(){return this.root}isAlwaysDep(e){return this.alwaysDeps.has(e)}};var R=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,o]of Object.entries(i.manifest.addresses)){let a=this.normalizeAddress(o);this.unifiedAddressTable.has(n)&&this.unifiedAddressTable.get(n)!==a||this.unifiedAddressTable.set(n,a)}}for(let t of this.graph.getAllPackages()){let i={};for(let[n,o]of this.unifiedAddressTable.entries())i[n]=o;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 D=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 o of n){if(o===this.rootPackageName)continue;let a=this.resolvedGraph.getPackage(o);if(!a)continue;let c=e.get(o)||{},r=this.extractSourcePaths(o,c),l=a.manifest.edition||"legacy",d={name:o,isImmediate:i.has(o),sourcePaths:r,addressMapping:a.resolvedTable||{},compilerConfig:{edition:l,flavor:"sui"},moduleFormat:r.length>0?"Source":"Bytecode",edition:l};this.dependencies.push(d)}}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)||{},o={};for(let[a,c]of Object.entries(n)){if(a.endsWith("Move.lock"))continue;let r=`dependencies/${i.name}/${a}`;if(a.endsWith("Move.toml")){let l=this.reconstructDependencyMoveToml(i.name,c,i.edition,i.addressMapping);o[r]=l}else o[r]=c}t.push({name:i.name,files:o,edition:i.edition})}return t}reconstructDependencyMoveToml(e,t,i,n){let o=t.split(`
|
|
2
|
+
`),a=[],c=[],r=!1,l=!1;for(let g of o){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&&a.push(g),l&&u&&c.push(g)}let d=`[package]
|
|
3
|
+
`,f=!1,m=!1;for(let g of a)if(g.includes("name ="))d+=g+`
|
|
4
|
+
`,f=!0;else if(g.includes("version ="))d+=g+`
|
|
5
|
+
`,m=!0;else{if(g.includes("edition ="))continue;d+=g+`
|
|
6
|
+
`}f||(d+=`name = "${e}"
|
|
7
|
+
`),m||(d+=`version = "0.0.0"
|
|
8
|
+
`),d+=`edition = "${i}"
|
|
9
|
+
`,d+=`
|
|
10
|
+
[dependencies]
|
|
11
|
+
`;for(let g of c)d+=g+`
|
|
12
|
+
`;d+=`
|
|
13
|
+
[addresses]
|
|
14
|
+
`;for(let[g,u]of Object.entries(n))d+=`${g} = "${u}"
|
|
15
|
+
`;return d}getUnifiedAddressTable(){return this.resolvedGraph.getUnifiedAddressTable()}};var P=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=v(e),n=i.package?.name||"RootPackage",o=i.package?.edition;if(t["Move.lock"]){let h=v(t["Move.lock"]);h.move?.["toolchain-version"]?.edition&&(o=h.move["toolchain-version"].edition)}let a=o||"2024.beta",c=new M(n),r=await this.buildPackage(n,null,e,t);o&&(r.manifest.edition=o),c.addPackage(r),this.packageFiles.set(n,t),await this.loadFromLockfile(c,r,t)||await this.buildDependencyGraph(c,r);let d=c.detectCycle();if(d)throw new Error(`Dependency cycle detected: ${d.join(" \u2192 ")}`);let f=new R(c,{});await f.resolve();let m=new D(f);await m.compute(this.packageFiles);let g=this.reconstructMoveToml(i,f.getUnifiedAddressTable(),!0,a),u={...t};delete u["Move.lock"],u["Move.toml"]=g;let p=m.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(u),dependencies:JSON.stringify(p)}}async buildPackage(e,t,i,n){let o=v(i),a={name:o.package?.name||e,version:o.package?.version||"0.0.0",edition:o.package?.edition,publishedAt:o.package?.published_at,addresses:o.addresses||{},dependencies:o.dependencies||{},devDependencies:o["dev-dependencies"]},c=new Map;if(a.dependencies)for(let[l,d]of Object.entries(a.dependencies)){let f=this.parseDependencyInfo(d);f&&c.set(l,f)}return{id:{name:a.name,version:a.version,source:t||{type:"local"}},manifest:a,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,p=this.resolveRelativePath(g,u);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:p}}else continue;if(n.source.type!=="git")continue;let o=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(o)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(o);let a=n.source.subdir;!a&&n.source.git&&this.isSuiRepo(n.source.git)&&(a=this.inferSuiFrameworkSubdir(i),a&&(n.source.subdir=a));let c=await this.fetcher.fetch(n.source.git,n.source.rev,a),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 d=await this.buildPackage(i,n.source,r,c),f=this.packageNameCache.get(d.manifest.name);if(f){let g=this.findPackageBySource(e,f);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.packageNameCache.set(d.manifest.name,n.source);let m=c["Move.lock"];if(m){let g=v(m);if(g.env?.[this.network]){let u=g.env[this.network]["latest-published-id"]||g.env[this.network]["original-published-id"];u&&(d.manifest.publishedAt=u,d.manifest.addresses[d.manifest.name]=this.normalizeAddress(u))}d.manifest.edition||(d.manifest.edition="legacy")}if(!d.manifest.publishedAt){let g={Sui:"0x2",MoveStdlib:"0x1",SuiSystem:"0x3",Bridge:"0xb"};g[i]&&(d.manifest.publishedAt=g[i])}e.addPackage(d),e.addDependency(t.id.name,d.id.name,n),this.packageFiles.set(d.id.name,c),await this.buildDependencyGraph(e,d)}}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),o=[...i];for(let a of n)a===".."?o.length>0&&o.pop():a!=="."&&o.push(a);return o.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 o=v(n),a=o.pinned?.[this.network];if(!a)return!1;let c=i["Move.toml"];if(c&&o.move?.manifest_digest&&await this.computeManifestDigest(c)!==o.move.manifest_digest)return!1;let r=new Map;for(let[l,d]of Object.entries(a)){let f=this.lockfileSourceToDependencySource(d.source);if(!f)continue;let m=await this.fetchFromSource(f);if(!m)return!1;let g=m["Move.toml"];if(!g||d["manifest-digest"]&&await this.computeManifestDigest(g)!==d["manifest-digest"])return!1;let u=await this.buildPackage(l,f,g,m);r.set(l,u),this.packageFiles.set(u.manifest.name,m),(f.type!=="local"||!("root"in d.source))&&e.addPackage(u)}for(let[l,d]of Object.entries(a)){let f=r.get(l);if(f&&d.deps)for(let[m,g]of Object.entries(d.deps)){let u=r.get(g);if(u){let p=f.dependencies.get(m);p&&e.addDependency(f.id.name,u.id.name,p)}}}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 a=`[package]
|
|
2
16
|
name = "${e.package.name}"
|
|
3
17
|
version = "${e.package.version}"
|
|
4
|
-
|
|
5
|
-
`),
|
|
18
|
+
`,c=n||e.package.edition;if(c&&(a+=`edition = "${c}"
|
|
19
|
+
`),a+=`
|
|
6
20
|
[dependencies]
|
|
7
|
-
`,e.dependencies)for(let[
|
|
8
|
-
|
|
21
|
+
`,e.dependencies)for(let[r,l]of Object.entries(e.dependencies)){let d=l;d.local?a+=`${r} = { local = "${d.local}" }
|
|
22
|
+
`:d.git&&d.rev&&(d.subdir?a+=`${r} = { git = "${d.git}", subdir = "${d.subdir}", rev = "${d.rev}" }
|
|
23
|
+
`:a+=`${r} = { git = "${d.git}", rev = "${d.rev}" }
|
|
24
|
+
`)}a+=`
|
|
9
25
|
[addresses]
|
|
10
|
-
`;for(let[
|
|
11
|
-
`;return
|
|
12
|
-
`)
|
|
13
|
-
`))}function
|
|
14
|
-
`))}function
|
|
15
|
-
`))}return e}function F(s){return!!(s?.["dependencies/MoveStdlib/Move.toml"]&&s?.["dependencies/Sui/Move.toml"])}function _(s){return typeof s=="string"?JSON.parse(s):s}async function G(s){await m(s?.wasm)}async function J(s){try{let e=s.dependencies??{},t={...s.files},n=typeof t["Move.toml"]=="string";if(s.autoSystemDeps&&n){let a=C(t["Move.toml"]);F(e)||(a=z(a)),t["Move.toml"]=a}if(s.autoSystemDeps&&!F(e)&&n){let a=await b(t["Move.toml"],t,new p);t=_(a.files),e=_(a.dependencies)}else s.autoSystemDeps&&(e=H(e));let i=await m(s.wasm),o=s.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(S(t),S(e),!0):i.compile(S(t),S(e)),c=D(o),l=c.success(),r=c.output();return l?I(r):$(r)}catch(e){return $(e)}}async function q(s){return(await m(s?.wasm)).sui_move_version()}async function V(s){return(await m(s?.wasm)).sui_version()}async function K(s){return m(s?.wasm)}async function Q(s,e,t){let n=await m(t?.wasm),i=t?.ansiColor&&typeof n.compile_with_color=="function"?n.compile_with_color(s,e,!0):n.compile(s,e),o=D(i);return{success:o.success(),output:o.output()}}0&&(module.exports={Fetcher,GitHubFetcher,Resolver,buildMovePackage,compileRaw,getSuiMoveVersion,getSuiVersion,getWasmBindings,initMoveCompiler,parseToml,resolve});
|
|
26
|
+
`;for(let[r,l]of Object.entries(t))a+=`${r} = "${l}"
|
|
27
|
+
`;return a}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 x(s,e,t,i="mainnet"){return new P(t,i).resolve(s,e)}function F(s){try{let e=new URL(s);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],o="main",a;return t.length>=4&&t[2]==="tree"&&(o=t[3],t.length>4&&(a=t.slice(4).join("/"))),{owner:i,repo:n,ref:o,subdir:a}}catch{return null}}async function L(s,e){let t=F(s);if(!t)throw new Error(`Invalid GitHub URL: ${s}`);let i=e?.fetcher||new k,n=e?.includeLock!==!1,o=`https://github.com/${t.owner}/${t.repo}.git`,a=await i.fetch(o,t.ref,t.subdir);if(!n&&a["Move.lock"]){let{"Move.lock":c,...r}=a;return r}return a}async function I(s,e){let t=Array.isArray(s)?Object.fromEntries(s.map((n,o)=>[`package_${o}`,n])):s,i={};for(let[n,o]of Object.entries(t))i[n]=await L(o,e);return i}function U(s,e="main",t){let i=`https://github.com/${s}`;return(e||t)&&(i+=`/tree/${e}`),t&&(i+=`/${t}`),i}var G;async function b(s){return G||(G=import("./sui_move_wasm.js").then(async e=>(s?await e.default({module_or_path:s}):await e.default(),e))),G}function $(s){return JSON.stringify(s??{})}function N(s){return{success:!1,error:s instanceof Error?s.message:typeof s=="string"?s:"Unknown error"}}function W(s){if(typeof s!="object"||s===null)throw new Error("Unexpected compile result shape from wasm");let e=s;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 ee(s){let e=t=>t.map(i=>i.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(s);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 N(t)}}function E(s){if(!s)return s;let e=s;return e.startsWith("0x")&&(e=e.slice(2)),/^[0-9a-fA-F]+$/.test(e)?"0x"+e.padStart(64,"0"):s}function te(s){let e={std:"0x1",sui:"0x2",sui_system:"0x3",bridge:"0xb"},t=s.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,o=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[addresses\]\s*$/.test(t[r])){n=r;for(let l=r+1;l<t.length;l++)if(i.test(t[l])){o=l;break}break}let a=new Set;if(n>=0)for(let r=n+1;r<o;r++){let l=t[r].trim();if(!l||l.startsWith("#"))continue;let d=l.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&a.add(d[1])}let c=Object.entries(e).filter(([r])=>!a.has(r)).map(([r,l])=>`${r} = "${E(l)}"`);return c.length===0?s:(n>=0?t.splice(o,0,...c):t.push("","[addresses]",...c),t.join(`
|
|
28
|
+
`))}function ne(s){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=s.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,o=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])){o=l;break}break}let a=new Set;if(n>=0)for(let r=n+1;r<o;r++){let l=t[r].trim();if(!l||l.startsWith("#"))continue;let d=l.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&a.add(d[1])}let c=e.filter(r=>!a.has(r.name)).map(r=>`${r.name} = { git = "${r.git}", subdir = "${r.subdir}", rev = "${r.rev}" }`);return c.length===0?s:(n>=0?t.splice(o,0,...c):t.push("","[dependencies]",...c),t.join(`
|
|
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});
|
package/dist/index.d.cts
CHANGED
|
@@ -17,39 +17,173 @@ 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
|
+
|
|
20
28
|
declare class Resolver {
|
|
21
29
|
private fetcher;
|
|
22
|
-
private
|
|
30
|
+
private network;
|
|
23
31
|
private visited;
|
|
24
|
-
private
|
|
25
|
-
private
|
|
26
|
-
constructor(fetcher: Fetcher);
|
|
32
|
+
private packageNameCache;
|
|
33
|
+
private packageFiles;
|
|
34
|
+
constructor(fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet");
|
|
35
|
+
/**
|
|
36
|
+
* Main resolve function using 3-layer architecture
|
|
37
|
+
*/
|
|
27
38
|
resolve(rootMoveToml: string, rootFiles: Record<string, string>): Promise<{
|
|
28
39
|
files: string;
|
|
29
40
|
dependencies: string;
|
|
30
41
|
}>;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
private
|
|
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
|
+
*/
|
|
35
83
|
private reconstructMoveToml;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Normalize address to 0x-prefixed 64-char hex
|
|
86
|
+
*/
|
|
87
|
+
private normalizeAddress;
|
|
88
|
+
/**
|
|
89
|
+
* Check if git URL is Sui repository
|
|
90
|
+
*/
|
|
41
91
|
private isSuiRepo;
|
|
92
|
+
/**
|
|
93
|
+
* Infer subdir for Sui framework packages
|
|
94
|
+
*/
|
|
95
|
+
private inferSuiFrameworkSubdir;
|
|
42
96
|
}
|
|
43
|
-
|
|
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<{
|
|
44
101
|
files: string;
|
|
45
102
|
dependencies: string;
|
|
46
103
|
}>;
|
|
47
104
|
|
|
48
|
-
declare function parseToml(content: string):
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
105
|
+
declare function parseToml(content: string): any;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Utility functions for fetching Move packages from GitHub
|
|
109
|
+
*/
|
|
110
|
+
|
|
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
|
+
/**
|
|
127
|
+
* Fetch a Move package from GitHub URL
|
|
128
|
+
*
|
|
129
|
+
* @param url - GitHub repository URL (e.g., "https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework")
|
|
130
|
+
* @param options - Optional configuration
|
|
131
|
+
* @returns Object with Move.toml and source files
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const files = await fetchPackageFromGitHub(
|
|
136
|
+
* 'https://github.com/MystenLabs/deepbookv3/tree/main/packages/deepbook'
|
|
137
|
+
* );
|
|
138
|
+
*
|
|
139
|
+
* // files = {
|
|
140
|
+
* // 'Move.toml': '...',
|
|
141
|
+
* // 'Move.lock': '...',
|
|
142
|
+
* // 'sources/pool.move': '...',
|
|
143
|
+
* // ...
|
|
144
|
+
* // }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function fetchPackageFromGitHub(url: string, options?: {
|
|
148
|
+
/** Custom fetcher instance (default: GitHubFetcher) */
|
|
149
|
+
fetcher?: GitHubFetcher;
|
|
150
|
+
/** Include Move.lock file (default: true) */
|
|
151
|
+
includeLock?: boolean;
|
|
152
|
+
}): 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;
|
|
53
187
|
|
|
54
188
|
interface BuildInput {
|
|
55
189
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
@@ -62,6 +196,8 @@ interface BuildInput {
|
|
|
62
196
|
ansiColor?: boolean;
|
|
63
197
|
/** Inject standard Sui system packages when missing (CLI-like behavior). */
|
|
64
198
|
autoSystemDeps?: boolean;
|
|
199
|
+
/** Network environment (mainnet, testnet, devnet). Defaults to mainnet. */
|
|
200
|
+
network?: "mainnet" | "testnet" | "devnet";
|
|
65
201
|
}
|
|
66
202
|
interface BuildSuccess {
|
|
67
203
|
success: true;
|
|
@@ -105,4 +241,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
105
241
|
}>;
|
|
106
242
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
107
243
|
|
|
108
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, Fetcher, GitHubFetcher, Resolver, buildMovePackage, compileRaw, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, parseToml, resolve };
|
|
244
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, Fetcher, GitHubFetcher, Resolver, buildMovePackage, compileRaw, fetchPackageFromGitHub, fetchPackagesFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, githubUrl, initMoveCompiler, parseGitHubUrl, parseToml, resolve };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,39 +17,173 @@ 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
|
+
|
|
20
28
|
declare class Resolver {
|
|
21
29
|
private fetcher;
|
|
22
|
-
private
|
|
30
|
+
private network;
|
|
23
31
|
private visited;
|
|
24
|
-
private
|
|
25
|
-
private
|
|
26
|
-
constructor(fetcher: Fetcher);
|
|
32
|
+
private packageNameCache;
|
|
33
|
+
private packageFiles;
|
|
34
|
+
constructor(fetcher: Fetcher, network?: "mainnet" | "testnet" | "devnet");
|
|
35
|
+
/**
|
|
36
|
+
* Main resolve function using 3-layer architecture
|
|
37
|
+
*/
|
|
27
38
|
resolve(rootMoveToml: string, rootFiles: Record<string, string>): Promise<{
|
|
28
39
|
files: string;
|
|
29
40
|
dependencies: string;
|
|
30
41
|
}>;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
private
|
|
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
|
+
*/
|
|
35
83
|
private reconstructMoveToml;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Normalize address to 0x-prefixed 64-char hex
|
|
86
|
+
*/
|
|
87
|
+
private normalizeAddress;
|
|
88
|
+
/**
|
|
89
|
+
* Check if git URL is Sui repository
|
|
90
|
+
*/
|
|
41
91
|
private isSuiRepo;
|
|
92
|
+
/**
|
|
93
|
+
* Infer subdir for Sui framework packages
|
|
94
|
+
*/
|
|
95
|
+
private inferSuiFrameworkSubdir;
|
|
42
96
|
}
|
|
43
|
-
|
|
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<{
|
|
44
101
|
files: string;
|
|
45
102
|
dependencies: string;
|
|
46
103
|
}>;
|
|
47
104
|
|
|
48
|
-
declare function parseToml(content: string):
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
105
|
+
declare function parseToml(content: string): any;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Utility functions for fetching Move packages from GitHub
|
|
109
|
+
*/
|
|
110
|
+
|
|
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
|
+
/**
|
|
127
|
+
* Fetch a Move package from GitHub URL
|
|
128
|
+
*
|
|
129
|
+
* @param url - GitHub repository URL (e.g., "https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework")
|
|
130
|
+
* @param options - Optional configuration
|
|
131
|
+
* @returns Object with Move.toml and source files
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* const files = await fetchPackageFromGitHub(
|
|
136
|
+
* 'https://github.com/MystenLabs/deepbookv3/tree/main/packages/deepbook'
|
|
137
|
+
* );
|
|
138
|
+
*
|
|
139
|
+
* // files = {
|
|
140
|
+
* // 'Move.toml': '...',
|
|
141
|
+
* // 'Move.lock': '...',
|
|
142
|
+
* // 'sources/pool.move': '...',
|
|
143
|
+
* // ...
|
|
144
|
+
* // }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function fetchPackageFromGitHub(url: string, options?: {
|
|
148
|
+
/** Custom fetcher instance (default: GitHubFetcher) */
|
|
149
|
+
fetcher?: GitHubFetcher;
|
|
150
|
+
/** Include Move.lock file (default: true) */
|
|
151
|
+
includeLock?: boolean;
|
|
152
|
+
}): 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;
|
|
53
187
|
|
|
54
188
|
interface BuildInput {
|
|
55
189
|
/** Virtual file system contents. Keys are paths (e.g. "Move.toml", "sources/Module.move"). */
|
|
@@ -62,6 +196,8 @@ interface BuildInput {
|
|
|
62
196
|
ansiColor?: boolean;
|
|
63
197
|
/** Inject standard Sui system packages when missing (CLI-like behavior). */
|
|
64
198
|
autoSystemDeps?: boolean;
|
|
199
|
+
/** Network environment (mainnet, testnet, devnet). Defaults to mainnet. */
|
|
200
|
+
network?: "mainnet" | "testnet" | "devnet";
|
|
65
201
|
}
|
|
66
202
|
interface BuildSuccess {
|
|
67
203
|
success: true;
|
|
@@ -105,4 +241,4 @@ declare function compileRaw(filesJson: string, depsJson: string, options?: {
|
|
|
105
241
|
}>;
|
|
106
242
|
type BuildResult = BuildSuccess | BuildFailure;
|
|
107
243
|
|
|
108
|
-
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, Fetcher, GitHubFetcher, Resolver, buildMovePackage, compileRaw, getSuiMoveVersion, getSuiVersion, getWasmBindings, initMoveCompiler, parseToml, resolve };
|
|
244
|
+
export { type BuildFailure, type BuildInput, type BuildResult, type BuildSuccess, Fetcher, GitHubFetcher, Resolver, buildMovePackage, compileRaw, fetchPackageFromGitHub, fetchPackagesFromGitHub, getSuiMoveVersion, getSuiVersion, getWasmBindings, githubUrl, initMoveCompiler, parseGitHubUrl, parseToml, resolve };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
var
|
|
1
|
+
var w=class{async fetch(e,t,i){throw new Error("Not implemented")}async fetchFile(e,t,i){throw new Error("Not implemented")}},v=class extends w{constructor(){super(),this.cache=new Map}async fetch(e,t,i){let{owner:n,repo:r}=this.parseGitUrl(e);if(!n||!r)throw new Error(`Invalid git URL: ${e}`);let a=`https://api.github.com/repos/${n}/${r}/git/trees/${t}?recursive=1`,c;try{let d=await fetch(a);if(!d.ok)throw d.status===403||d.status===429?new Error("GitHub API rate limit exceeded."):new Error(`Failed to fetch tree: ${d.statusText}`);c=await d.json()}catch{return{}}let s={},l=[];for(let d of c.tree){if(d.type!=="blob")continue;let f=d.path;if(i){if(!d.path.startsWith(i))continue;f=d.path.slice(i.length),f.startsWith("/")&&(f=f.slice(1))}if(!f.endsWith(".move")&&f!=="Move.toml"&&f!=="Move.lock"&&!f.match(/^Move\.(mainnet|testnet|devnet)\.toml$/))continue;let m=`https://raw.githubusercontent.com/${n}/${r}/${t}/${d.path}`,g=this.fetchContent(m).then(u=>{u&&(s[f]=u)});l.push(g)}return await Promise.all(l),s}async fetchFile(e,t,i){let{owner:n,repo:r}=this.parseGitUrl(e);if(!n||!r)throw new Error(`Invalid git URL: ${e}`);let a=`https://raw.githubusercontent.com/${n}/${r}/${t}/${i}`;return this.fetchContent(a)}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 O(o){let e=!1,t="";for(let i=0;i<o.length;i++){let n=o[i];if((n==='"'||n==="'")&&(!e||n===t)&&(e=!e,t=n),!e&&n==="#")return o.slice(0,i)}return o}function $(o){let e=o.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(o){let e={},t=o.trim().replace(/^\{/,"").replace(/\}$/,""),i="",n=!1,r="",a=[];for(let c=0;c<t.length;c++){let s=t[c];if((s==='"'||s==="'")&&(!n||s===r)&&(n=!n,r=s),!n&&s===","){a.push(i),i="";continue}i+=s}i.trim()&&a.push(i);for(let c of a){let s=c.indexOf("=");if(s===-1)continue;let l=c.slice(0,s).trim(),d=c.slice(s+1).trim();e[l]=$(d)}return e}function B(o){let e=[],t=o.trim().replace(/^\[/,"").replace(/\]$/,""),i="",n=!1,r="",a=0;for(let c=0;c<t.length;c++){let s=t[c];if((s==='"'||s==="'")&&(!n||s===r)&&(n=!n,r=n?s:""),!n&&(s==="{"&&a++,s==="}"&&a--,s===","&&a===0)){i.trim()&&e.push(L(i.trim())),i="";continue}i+=s}return i.trim()&&e.push(L(i.trim())),e}function L(o){return o.startsWith("{")?G(o):$(o)}function y(o){let e={},t=null,i=!1,n=o.split(/\r?\n/);function r(a,c){let s=a;for(let l of c){if(!(l in s))return;s=s[l]}return s}for(let a of n){let c=O(a).trim();if(!c)continue;let s=c.match(/^\[\[([^\]]+)\]\]$/);if(s){t=s[1].trim(),i=!0;let u=t.split("."),p=e;for(let k=0;k<u.length-1;k++){let x=u[k];x in p||(p[x]={}),p=p[x]}let h=u[u.length-1];Array.isArray(p[h])||(p[h]=[]),p[h].push({});continue}let l=c.match(/^\[([^\]]+)\]$/);if(l){t=l[1].trim(),i=!1;continue}let d=c.indexOf("=");if(d===-1||!t)continue;let f=c.slice(0,d).trim(),m=c.slice(d+1).trim(),g;if(m.startsWith("{")?g=G(m):m.startsWith("[")?g=B(m):g=$(m),i){let u=t.split("."),p=r(e,u);if(Array.isArray(p)&&p.length>0){let h=p[p.length-1];h[f]=g}}else{let u=t.split("."),p=e;for(let k of u)k in p||(p[k]={}),p=p[k];let h=t==="package"?f.replace(/-/g,"_"):f;p[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=r=>{if(i.has(r))return;i.add(r),t.add(r);let a=this.graph.get(r);if(a)for(let c of a)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 r=this.graph.get(n);if(r)for(let a of r)i(a);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=r=>{e.add(r),t.add(r);let a=this.graph.get(r);if(a)for(let c of a)if(e.has(c)){if(t.has(c)){let s=[c],l=r;for(;l!==c;)s.unshift(l),l=i.get(l);return s.unshift(c),s}}else{i.set(c,r);let s=n(c);if(s)return s}return t.delete(r),null};for(let r of this.packageTable.keys())if(!e.has(r)){let a=n(r);if(a)return a}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,r]of Object.entries(i.manifest.addresses)){let a=this.normalizeAddress(r);this.unifiedAddressTable.has(n)&&this.unifiedAddressTable.get(n)!==a||this.unifiedAddressTable.set(n,a)}}for(let t of this.graph.getAllPackages()){let i={};for(let[n,r]of this.unifiedAddressTable.entries())i[n]=r;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 M=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 r of n){if(r===this.rootPackageName)continue;let a=this.resolvedGraph.getPackage(r);if(!a)continue;let c=e.get(r)||{},s=this.extractSourcePaths(r,c),l=a.manifest.edition||"legacy",d={name:r,isImmediate:i.has(r),sourcePaths:s,addressMapping:a.resolvedTable||{},compilerConfig:{edition:l,flavor:"sui"},moduleFormat:s.length>0?"Source":"Bytecode",edition:l};this.dependencies.push(d)}}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)||{},r={};for(let[a,c]of Object.entries(n)){if(a.endsWith("Move.lock"))continue;let s=`dependencies/${i.name}/${a}`;if(a.endsWith("Move.toml")){let l=this.reconstructDependencyMoveToml(i.name,c,i.edition,i.addressMapping);r[s]=l}else r[s]=c}t.push({name:i.name,files:r,edition:i.edition})}return t}reconstructDependencyMoveToml(e,t,i,n){let r=t.split(`
|
|
2
|
+
`),a=[],c=[],s=!1,l=!1;for(let g of r){let u=g.trim();if(u.startsWith("[package]")){s=!0,l=!1;continue}if(u.startsWith("[dependencies]")){s=!1,l=!0;continue}if(u.startsWith("[")){s=!1,l=!1;continue}s&&u&&a.push(g),l&&u&&c.push(g)}let d=`[package]
|
|
3
|
+
`,f=!1,m=!1;for(let g of a)if(g.includes("name ="))d+=g+`
|
|
4
|
+
`,f=!0;else if(g.includes("version ="))d+=g+`
|
|
5
|
+
`,m=!0;else{if(g.includes("edition ="))continue;d+=g+`
|
|
6
|
+
`}f||(d+=`name = "${e}"
|
|
7
|
+
`),m||(d+=`version = "0.0.0"
|
|
8
|
+
`),d+=`edition = "${i}"
|
|
9
|
+
`,d+=`
|
|
10
|
+
[dependencies]
|
|
11
|
+
`;for(let g of c)d+=g+`
|
|
12
|
+
`;d+=`
|
|
13
|
+
[addresses]
|
|
14
|
+
`;for(let[g,u]of Object.entries(n))d+=`${g} = "${u}"
|
|
15
|
+
`;return d}getUnifiedAddressTable(){return this.resolvedGraph.getUnifiedAddressTable()}};var R=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",r=i.package?.edition;if(t["Move.lock"]){let h=y(t["Move.lock"]);h.move?.["toolchain-version"]?.edition&&(r=h.move["toolchain-version"].edition)}let a=r||"2024.beta",c=new P(n),s=await this.buildPackage(n,null,e,t);r&&(s.manifest.edition=r),c.addPackage(s),this.packageFiles.set(n,t),await this.loadFromLockfile(c,s,t)||await this.buildDependencyGraph(c,s);let d=c.detectCycle();if(d)throw new Error(`Dependency cycle detected: ${d.join(" \u2192 ")}`);let f=new S(c,{});await f.resolve();let m=new M(f);await m.compute(this.packageFiles);let g=this.reconstructMoveToml(i,f.getUnifiedAddressTable(),!0,a),u={...t};delete u["Move.lock"],u["Move.toml"]=g;let p=m.toPackageGroupedFormat(this.packageFiles);return{files:JSON.stringify(u),dependencies:JSON.stringify(p)}}async buildPackage(e,t,i,n){let r=y(i),a={name:r.package?.name||e,version:r.package?.version||"0.0.0",edition:r.package?.edition,publishedAt:r.package?.published_at,addresses:r.addresses||{},dependencies:r.dependencies||{},devDependencies:r["dev-dependencies"]},c=new Map;if(a.dependencies)for(let[l,d]of Object.entries(a.dependencies)){let f=this.parseDependencyInfo(d);f&&c.set(l,f)}return{id:{name:a.name,version:a.version,source:t||{type:"local"}},manifest:a,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,p=this.resolveRelativePath(g,u);n.source={type:"git",git:t.id.source.git,rev:t.id.source.rev,subdir:p}}else continue;if(n.source.type!=="git")continue;let r=`${n.source.git}|${n.source.rev}|${n.source.subdir||""}`;if(this.visited.has(r)){let g=this.findPackageBySource(e,n.source);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.visited.add(r);let a=n.source.subdir;!a&&n.source.git&&this.isSuiRepo(n.source.git)&&(a=this.inferSuiFrameworkSubdir(i),a&&(n.source.subdir=a));let c=await this.fetcher.fetch(n.source.git,n.source.rev,a),s=null,l=`Move.${this.network}.toml`;for(let[g,u]of Object.entries(c))if(g.endsWith(l)){s=u;break}if(!s){for(let[g,u]of Object.entries(c))if(g.endsWith("Move.toml")){s=u;break}}if(!s)continue;let d=await this.buildPackage(i,n.source,s,c),f=this.packageNameCache.get(d.manifest.name);if(f){let g=this.findPackageBySource(e,f);g&&e.addDependency(t.id.name,g.id.name,n);continue}this.packageNameCache.set(d.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&&(d.manifest.publishedAt=u,d.manifest.addresses[d.manifest.name]=this.normalizeAddress(u))}d.manifest.edition||(d.manifest.edition="legacy")}if(!d.manifest.publishedAt){let g={Sui:"0x2",MoveStdlib:"0x1",SuiSystem:"0x3",Bridge:"0xb"};g[i]&&(d.manifest.publishedAt=g[i])}e.addPackage(d),e.addDependency(t.id.name,d.id.name,n),this.packageFiles.set(d.id.name,c),await this.buildDependencyGraph(e,d)}}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),r=[...i];for(let a of n)a===".."?r.length>0&&r.pop():a!=="."&&r.push(a);return r.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 r=y(n),a=r.pinned?.[this.network];if(!a)return!1;let c=i["Move.toml"];if(c&&r.move?.manifest_digest&&await this.computeManifestDigest(c)!==r.move.manifest_digest)return!1;let s=new Map;for(let[l,d]of Object.entries(a)){let f=this.lockfileSourceToDependencySource(d.source);if(!f)continue;let m=await this.fetchFromSource(f);if(!m)return!1;let g=m["Move.toml"];if(!g||d["manifest-digest"]&&await this.computeManifestDigest(g)!==d["manifest-digest"])return!1;let u=await this.buildPackage(l,f,g,m);s.set(l,u),this.packageFiles.set(u.manifest.name,m),(f.type!=="local"||!("root"in d.source))&&e.addPackage(u)}for(let[l,d]of Object.entries(a)){let f=s.get(l);if(f&&d.deps)for(let[m,g]of Object.entries(d.deps)){let u=s.get(g);if(u){let p=f.dependencies.get(m);p&&e.addDependency(f.id.name,u.id.name,p)}}}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 a=`[package]
|
|
2
16
|
name = "${e.package.name}"
|
|
3
17
|
version = "${e.package.version}"
|
|
4
|
-
|
|
5
|
-
`),
|
|
18
|
+
`,c=n||e.package.edition;if(c&&(a+=`edition = "${c}"
|
|
19
|
+
`),a+=`
|
|
6
20
|
[dependencies]
|
|
7
|
-
`,e.dependencies)for(let[
|
|
8
|
-
|
|
21
|
+
`,e.dependencies)for(let[s,l]of Object.entries(e.dependencies)){let d=l;d.local?a+=`${s} = { local = "${d.local}" }
|
|
22
|
+
`:d.git&&d.rev&&(d.subdir?a+=`${s} = { git = "${d.git}", subdir = "${d.subdir}", rev = "${d.rev}" }
|
|
23
|
+
`:a+=`${s} = { git = "${d.git}", rev = "${d.rev}" }
|
|
24
|
+
`)}a+=`
|
|
9
25
|
[addresses]
|
|
10
|
-
`;for(let[
|
|
11
|
-
`;return
|
|
12
|
-
`)
|
|
13
|
-
`))}function
|
|
14
|
-
`))}function
|
|
15
|
-
`))}return e}function x(n){return!!(n?.["dependencies/MoveStdlib/Move.toml"]&&n?.["dependencies/Sui/Move.toml"])}function M(n){return typeof n=="string"?JSON.parse(n):n}async function C(n){await p(n?.wasm)}async function z(n){try{let e=n.dependencies??{},t={...n.files},s=typeof t["Move.toml"]=="string";if(n.autoSystemDeps&&s){let a=L(t["Move.toml"]);x(e)||(a=W(a)),t["Move.toml"]=a}if(n.autoSystemDeps&&!x(e)&&s){let a=await S(t["Move.toml"],t,new m);t=M(a.files),e=M(a.dependencies)}else n.autoSystemDeps&&(e=U(e));let i=await p(n.wasm),o=n.ansiColor&&typeof i.compile_with_color=="function"?i.compile_with_color(w(t),w(e),!0):i.compile(w(t),w(e)),c=F(o),l=c.success(),r=c.output();return l?j(r):R(r)}catch(e){return R(e)}}async function H(n){return(await p(n?.wasm)).sui_move_version()}async function G(n){return(await p(n?.wasm)).sui_version()}async function J(n){return p(n?.wasm)}async function q(n,e,t){let s=await p(t?.wasm),i=t?.ansiColor&&typeof s.compile_with_color=="function"?s.compile_with_color(n,e,!0):s.compile(n,e),o=F(i);return{success:o.success(),output:o.output()}}export{g as Fetcher,m as GitHubFetcher,v as Resolver,z as buildMovePackage,q as compileRaw,H as getSuiMoveVersion,G as getSuiVersion,J as getWasmBindings,C as initMoveCompiler,y as parseToml,S as resolve};
|
|
26
|
+
`;for(let[s,l]of Object.entries(t))a+=`${s} = "${l}"
|
|
27
|
+
`;return a}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 A(o,e,t,i="mainnet"){return new R(t,i).resolve(o,e)}function N(o){try{let e=new URL(o);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],r="main",a;return t.length>=4&&t[2]==="tree"&&(r=t[3],t.length>4&&(a=t.slice(4).join("/"))),{owner:i,repo:n,ref:r,subdir:a}}catch{return null}}async function _(o,e){let t=N(o);if(!t)throw new Error(`Invalid GitHub URL: ${o}`);let i=e?.fetcher||new v,n=e?.includeLock!==!1,r=`https://github.com/${t.owner}/${t.repo}.git`,a=await i.fetch(r,t.ref,t.subdir);if(!n&&a["Move.lock"]){let{"Move.lock":c,...s}=a;return s}return a}async function W(o,e){let t=Array.isArray(o)?Object.fromEntries(o.map((n,r)=>[`package_${r}`,n])):o,i={};for(let[n,r]of Object.entries(t))i[n]=await _(r,e);return i}function E(o,e="main",t){let i=`https://github.com/${o}`;return(e||t)&&(i+=`/tree/${e}`),t&&(i+=`/${t}`),i}var T;async function b(o){return T||(T=import("./sui_move_wasm.js").then(async e=>(o?await e.default({module_or_path:o}):await e.default(),e))),T}function D(o){return JSON.stringify(o??{})}function F(o){return{success:!1,error:o instanceof Error?o.message:typeof o=="string"?o:"Unknown error"}}function I(o){if(typeof o!="object"||o===null)throw new Error("Unexpected compile result shape from wasm");let e=o;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 H(o){let e=t=>t.map(i=>i.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(o);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 F(t)}}function U(o){if(!o)return o;let e=o;return e.startsWith("0x")&&(e=e.slice(2)),/^[0-9a-fA-F]+$/.test(e)?"0x"+e.padStart(64,"0"):o}function z(o){let e={std:"0x1",sui:"0x2",sui_system:"0x3",bridge:"0xb"},t=o.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,r=t.length;for(let s=0;s<t.length;s++)if(/^\s*\[addresses\]\s*$/.test(t[s])){n=s;for(let l=s+1;l<t.length;l++)if(i.test(t[l])){r=l;break}break}let a=new Set;if(n>=0)for(let s=n+1;s<r;s++){let l=t[s].trim();if(!l||l.startsWith("#"))continue;let d=l.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&a.add(d[1])}let c=Object.entries(e).filter(([s])=>!a.has(s)).map(([s,l])=>`${s} = "${U(l)}"`);return c.length===0?o:(n>=0?t.splice(r,0,...c):t.push("","[addresses]",...c),t.join(`
|
|
28
|
+
`))}function V(o){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=o.split(/\r?\n/),i=/^\s*\[[^\]]+\]\s*$/,n=-1,r=t.length;for(let s=0;s<t.length;s++)if(/^\s*\[dependencies\]\s*$/.test(t[s])){n=s;for(let l=s+1;l<t.length;l++)if(i.test(t[l])){r=l;break}break}let a=new Set;if(n>=0)for(let s=n+1;s<r;s++){let l=t[s].trim();if(!l||l.startsWith("#"))continue;let d=l.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&a.add(d[1])}let c=e.filter(s=>!a.has(s.name)).map(s=>`${s.name} = { git = "${s.git}", subdir = "${s.subdir}", rev = "${s.rev}" }`);return c.length===0?o:(n>=0?t.splice(r,0,...c):t.push("","[dependencies]",...c),t.join(`
|
|
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};
|
|
Binary file
|