@zktx.io/sui-move-builder 0.1.2 → 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 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 fetching and dump outputs.
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
- ## Resolving dependencies from GitHub (optional)
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
- typeof resolution.files === "string"
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
- // If autoSystemDeps is enabled and std/Sui packages are missing,
78
- // the builder fetches them from GitHub using the Sui framework snapshot.
153
+ ### How it works
79
154
 
80
- // Enable ANSI-colored diagnostics (CLI-like output)
81
- const resultWithColor = await buildMovePackage({
82
- files: filesJson,
83
- dependencies: depsJson,
84
- ansiColor: true,
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 j=Object.create;var v=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,B=Object.prototype.hasOwnProperty;var A=(n,e)=>{for(var t in e)v(n,t,{get:e[t],enumerable:!0})},M=(n,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of L(e))!B.call(n,i)&&i!==t&&v(n,i,{get:()=>e[i],enumerable:!(s=W(e,i))||s.enumerable});return n};var O=(n,e,t)=>(t=n!=null?j(U(n)):{},M(e||!n||!n.__esModule?v(t,"default",{value:n,enumerable:!0}):t,n)),T=n=>M(v({},"__esModule",{value:!0}),n);var X={};A(X,{Fetcher:()=>g,GitHubFetcher:()=>p,Resolver:()=>y,buildMovePackage:()=>q,compileRaw:()=>Z,getSuiMoveVersion:()=>V,getSuiVersion:()=>K,getWasmBindings:()=>Q,initMoveCompiler:()=>J,parseToml:()=>h,resolve:()=>b});module.exports=T(X);var g=class{async fetch(e,t,s){throw new Error("Not implemented")}async fetchFile(e,t,s){throw new Error("Not implemented")}},p=class extends g{constructor(){super(),this.cache=new Map}async fetch(e,t,s){let{owner:i,repo:o}=this.parseGitUrl(e);if(!i||!o)throw new Error(`Invalid git URL: ${e}`);let c=`https://api.github.com/repos/${i}/${o}/git/trees/${t}?recursive=1`,l;try{let d=await fetch(c);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}`);l=await d.json()}catch{return{}}let r={},a=[];for(let d of l.tree){if(d.type!=="blob")continue;let u=d.path;if(s){if(!d.path.startsWith(s))continue;u=d.path.slice(s.length),u.startsWith("/")&&(u=u.slice(1))}if(!u.endsWith(".move")&&u!=="Move.toml")continue;let f=`https://raw.githubusercontent.com/${i}/${o}/${t}/${d.path}`,k=this.fetchContent(f).then(x=>{x&&(r[u]=x)});a.push(k)}return await Promise.all(a),r}async fetchFile(e,t,s){let{owner:i,repo:o}=this.parseGitUrl(e);if(!i||!o)throw new Error(`Invalid git URL: ${e}`);let c=`https://raw.githubusercontent.com/${i}/${o}/${t}/${s}`;return this.fetchContent(c)}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 s=await t.text();return this.cache.set(e,s),s}catch{return null}}parseGitUrl(e){try{let s=new URL(e).pathname.split("/").filter(i=>i);if(s.length>=2){let i=s[1];return i.endsWith(".git")&&(i=i.slice(0,-4)),{owner:s[0],repo:i}}}catch{}return{owner:null,repo:null}}};function N(n){let e=!1,t="";for(let s=0;s<n.length;s++){let i=n[s];if((i==='"'||i==="'")&&(!e||i===t)&&(e=!e,t=i),!e&&i==="#")return n.slice(0,s)}return n}function w(n){let e=n.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 E(n){let e={},t=n.trim().replace(/^\{/,"").replace(/\}$/,""),s="",i=!1,o="",c=[];for(let l=0;l<t.length;l++){let r=t[l];if((r==='"'||r==="'")&&(!i||r===o)&&(i=!i,o=r),!i&&r===","){c.push(s),s="";continue}s+=r}s.trim()&&c.push(s);for(let l of c){let r=l.indexOf("=");if(r===-1)continue;let a=l.slice(0,r).trim(),d=l.slice(r+1).trim();e[a]=w(d)}return e}function h(n){let e={package:{},dependencies:{},addresses:{}},t=null,s=n.split(/\r?\n/);for(let i of s){let o=N(i).trim();if(!o)continue;let c=o.match(/^\[([^\]]+)\]$/);if(c){t=c[1].trim();continue}let l=o.indexOf("=");if(l===-1||!t)continue;let r=o.slice(0,l).trim(),a=o.slice(l+1).trim();t==="package"?e.package[r.replace(/-/g,"_")]=w(a):t==="dependencies"?a.startsWith("{")?e.dependencies[r]=E(a):e.dependencies[r]=w(a):t==="addresses"&&(e.addresses[r]=w(a))}return e}var y=class{constructor(e){this.fetcher=e,this.globalAddresses={},this.visited=new Set,this.dependencyFiles={},this.systemDepsLoaded=new Set}async resolve(e,t){let s=h(e);s.addresses&&this.mergeAddresses(s.addresses),s.dependencies&&await this.resolveDeps(s.dependencies),await this.injectSystemDeps(s.dependencies);let i=this.reconstructMoveToml(s,this.globalAddresses),o={...t,"Move.toml":i};return{files:JSON.stringify(o),dependencies:JSON.stringify(this.dependencyFiles)}}mergeAddresses(e){for(let[t,s]of Object.entries(e))this.globalAddresses[t]=this.normalizeAddress(s)}normalizeAddress(e){if(!e)return e;let t=e;return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}async resolveDeps(e,t=null){for(let[s,i]of Object.entries(e)){let o,c,l;if(i.git)o=i.git,c=i.rev,l=i.subdir;else if(i.local){if(!t)continue;o=t.git,c=t.rev,l=this.resolvePath(t.subdir||"",i.local)}else continue;let r=`${o}|${c}|${l||""}`;if(this.visited.has(r))continue;this.visited.add(r);let a=await this.fetcher.fetch(o,c,l),d=null;for(let[u,f]of Object.entries(a))if(u.endsWith("Move.toml")){d=f;break}if(d){let u=h(d);u.addresses&&this.mergeAddresses(u.addresses),u.dependencies&&await this.resolveDeps(u.dependencies,{git:o,rev:c,subdir:l})}for(let[u,f]of Object.entries(a))if(u.endsWith(".move")||u.endsWith("Move.toml")){let k=`dependencies/${s}/${u}`;this.dependencyFiles[k]=f}}}resolvePath(e,t){let s=e.split("/").filter(o=>o&&o!=="."),i=t.split("/").filter(o=>o&&o!==".");for(let o of i)o===".."?s.pop():s.push(o);return s.join("/")}reconstructMoveToml(e,t){let s=`[package]
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
- `;if(e.package.edition&&(s+=`edition = "${e.package.edition}"
5
- `),s+=`
18
+ `,c=n||e.package.edition;if(c&&(a+=`edition = "${c}"
19
+ `),a+=`
6
20
  [dependencies]
7
- `,e.dependencies)for(let[i,o]of Object.entries(e.dependencies))s+=`${i} = { git = "${o.git}", rev = "${o.rev}" }
8
- `;s+=`
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[i,o]of Object.entries(t))s+=`${i} = "${o}"
11
- `;return s}async injectSystemDeps(e){if(e){for(let s of Object.values(e))if(!(!s||!s.git||!s.rev)&&this.isSuiRepo(s.git)){await this.addImplicitSystemDepsForRepo(s.git,s.rev);break}}this.dependencyFiles["dependencies/MoveStdlib/Move.toml"]||this.addFallbackSystemDeps()}async addImplicitSystemDepsForRepo(e,t){if(!this.isSuiRepo(e))return;let s=`${e}|${t}`;if(this.systemDepsLoaded.has(s))return;this.systemDepsLoaded.add(s);let i="crates/sui-framework-snapshot/manifest.json";if(!this.fetcher.fetchFile)return;let o=null;try{let c=await this.fetcher.fetchFile(e,t,i);if(c){let l=JSON.parse(c),r=Object.keys(l).map(u=>Number(u)).filter(u=>!Number.isNaN(u)).sort((u,f)=>u-f),a=r[r.length-1],d=l[String(a)];d&&d.packages&&(o=d.packages)}}catch{}o||(o=this.fallbackSystemPackages());for(let c of o)!c||!c.name||!c.id||c.name!=="DeepBook"&&this.addSystemDep(c.name,c.id)}addFallbackSystemDeps(){for(let e of this.fallbackSystemPackages())!e||!e.name||!e.id||e.name!=="DeepBook"&&this.addSystemDep(e.name,e.id)}addSystemDep(e,t){let s=`dependencies/${e}/Move.toml`;if(this.dependencyFiles[s])return;let i=["[package]",`name = "${e}"`,'version = "0.0.0"',`published-at = "${this.normalizeAddress(t)}"`,""].join(`
12
- `);this.dependencyFiles[s]=i}fallbackSystemPackages(){return[{name:"MoveStdlib",id:"0x1"},{name:"Sui",id:"0x2"},{name:"SuiSystem",id:"0x3"},{name:"Bridge",id:"0xb"}]}isSuiRepo(e){return e.includes("github.com/MystenLabs/sui")}};async function b(n,e,t){return new y(t).resolve(n,e)}var Y={},I=(()=>{try{return new URL("./sui_move_wasm_bg.wasm",Y.url)}catch{return"./sui_move_wasm_bg.wasm"}})(),R;async function m(n){return R||(R=import("./sui_move_wasm.js").then(async e=>(await e.default(n??I),e))),R}function S(n){return JSON.stringify(n??{})}function $(n){return{success:!1,error:n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}}function D(n){if(typeof n!="object"||n===null)throw new Error("Unexpected compile result shape from wasm");let e=n;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 C(n){let e=t=>t.map(s=>s.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(n);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let s=typeof t.digest=="string"?t.digest:e(t.digest);return{success:!0,modules:t.modules,dependencies:t.dependencies,digest:s}}catch(t){return $(t)}}function P(n){if(!n)return n;let e=n;return e.startsWith("0x")&&(e=e.slice(2)),/^[0-9a-fA-F]+$/.test(e)?"0x"+e.padStart(64,"0"):n}function z(n){let e={std:"0x1",sui:"0x2",sui_system:"0x3",bridge:"0xb"},t=n.split(/\r?\n/),s=/^\s*\[[^\]]+\]\s*$/,i=-1,o=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[addresses\]\s*$/.test(t[r])){i=r;for(let a=r+1;a<t.length;a++)if(s.test(t[a])){o=a;break}break}let c=new Set;if(i>=0)for(let r=i+1;r<o;r++){let a=t[r].trim();if(!a||a.startsWith("#"))continue;let d=a.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&c.add(d[1])}let l=Object.entries(e).filter(([r])=>!c.has(r)).map(([r,a])=>`${r} = "${P(a)}"`);return l.length===0?n:(i>=0?t.splice(o,0,...l):t.push("","[addresses]",...l),t.join(`
13
- `))}function H(n){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=n.split(/\r?\n/),s=/^\s*\[[^\]]+\]\s*$/,i=-1,o=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[dependencies\]\s*$/.test(t[r])){i=r;for(let a=r+1;a<t.length;a++)if(s.test(t[a])){o=a;break}break}let c=new Set;if(i>=0)for(let r=i+1;r<o;r++){let a=t[r].trim();if(!a||a.startsWith("#"))continue;let d=a.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&c.add(d[1])}let l=e.filter(r=>!c.has(r.name)).map(r=>`${r.name} = { git = "${r.git}", subdir = "${r.subdir}", rev = "${r.rev}" }`);return l.length===0?n:(i>=0?t.splice(o,0,...l):t.push("","[dependencies]",...l),t.join(`
14
- `))}function G(n){let e={...n??{}};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 s of t){let i=`dependencies/${s.name}/Move.toml`;e[i]||(e[i]=["[package]",`name = "${s.name}"`,'version = "0.0.0"',`published-at = "${P(s.id)}"`,""].join(`
15
- `))}return e}function F(n){return!!(n?.["dependencies/MoveStdlib/Move.toml"]&&n?.["dependencies/Sui/Move.toml"])}function _(n){return typeof n=="string"?JSON.parse(n):n}async function J(n){await m(n?.wasm)}async function q(n){try{let e=n.dependencies??{},t={...n.files},s=typeof t["Move.toml"]=="string";if(n.autoSystemDeps&&s){let a=z(t["Move.toml"]);F(e)||(a=H(a)),t["Move.toml"]=a}if(n.autoSystemDeps&&!F(e)&&s){let a=await b(t["Move.toml"],t,new p);t=_(a.files),e=_(a.dependencies)}else n.autoSystemDeps&&(e=G(e));let i=await m(n.wasm),o=n.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?C(r):$(r)}catch(e){return $(e)}}async function V(n){return(await m(n?.wasm)).sui_move_version()}async function K(n){return(await m(n?.wasm)).sui_version()}async function Q(n){return m(n?.wasm)}async function Z(n,e,t){let s=await m(t?.wasm),i=t?.ansiColor&&typeof s.compile_with_color=="function"?s.compile_with_color(n,e,!0):s.compile(n,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 globalAddresses;
30
+ private network;
23
31
  private visited;
24
- private dependencyFiles;
25
- private systemDepsLoaded;
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
- private mergeAddresses;
32
- private normalizeAddress;
33
- private resolveDeps;
34
- private resolvePath;
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
- private injectSystemDeps;
37
- private addImplicitSystemDepsForRepo;
38
- private addFallbackSystemDeps;
39
- private addSystemDep;
40
- private fallbackSystemPackages;
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
- declare function resolve(rootMoveTomlContent: string, rootSourceFiles: Record<string, string>, fetcher: Fetcher): Promise<{
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
- package: Record<string, any>;
50
- dependencies: Record<string, any>;
51
- addresses: Record<string, any>;
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 globalAddresses;
30
+ private network;
23
31
  private visited;
24
- private dependencyFiles;
25
- private systemDepsLoaded;
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
- private mergeAddresses;
32
- private normalizeAddress;
33
- private resolveDeps;
34
- private resolvePath;
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
- private injectSystemDeps;
37
- private addImplicitSystemDepsForRepo;
38
- private addFallbackSystemDeps;
39
- private addSystemDep;
40
- private fallbackSystemPackages;
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
- declare function resolve(rootMoveTomlContent: string, rootSourceFiles: Record<string, string>, fetcher: Fetcher): Promise<{
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
- package: Record<string, any>;
50
- dependencies: Record<string, any>;
51
- addresses: Record<string, any>;
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 g=class{async fetch(e,t,s){throw new Error("Not implemented")}async fetchFile(e,t,s){throw new Error("Not implemented")}},m=class extends g{constructor(){super(),this.cache=new Map}async fetch(e,t,s){let{owner:i,repo:o}=this.parseGitUrl(e);if(!i||!o)throw new Error(`Invalid git URL: ${e}`);let c=`https://api.github.com/repos/${i}/${o}/git/trees/${t}?recursive=1`,l;try{let d=await fetch(c);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}`);l=await d.json()}catch{return{}}let r={},a=[];for(let d of l.tree){if(d.type!=="blob")continue;let u=d.path;if(s){if(!d.path.startsWith(s))continue;u=d.path.slice(s.length),u.startsWith("/")&&(u=u.slice(1))}if(!u.endsWith(".move")&&u!=="Move.toml")continue;let f=`https://raw.githubusercontent.com/${i}/${o}/${t}/${d.path}`,b=this.fetchContent(f).then($=>{$&&(r[u]=$)});a.push(b)}return await Promise.all(a),r}async fetchFile(e,t,s){let{owner:i,repo:o}=this.parseGitUrl(e);if(!i||!o)throw new Error(`Invalid git URL: ${e}`);let c=`https://raw.githubusercontent.com/${i}/${o}/${t}/${s}`;return this.fetchContent(c)}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 s=await t.text();return this.cache.set(e,s),s}catch{return null}}parseGitUrl(e){try{let s=new URL(e).pathname.split("/").filter(i=>i);if(s.length>=2){let i=s[1];return i.endsWith(".git")&&(i=i.slice(0,-4)),{owner:s[0],repo:i}}}catch{}return{owner:null,repo:null}}};function D(n){let e=!1,t="";for(let s=0;s<n.length;s++){let i=n[s];if((i==='"'||i==="'")&&(!e||i===t)&&(e=!e,t=i),!e&&i==="#")return n.slice(0,s)}return n}function h(n){let e=n.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 P(n){let e={},t=n.trim().replace(/^\{/,"").replace(/\}$/,""),s="",i=!1,o="",c=[];for(let l=0;l<t.length;l++){let r=t[l];if((r==='"'||r==="'")&&(!i||r===o)&&(i=!i,o=r),!i&&r===","){c.push(s),s="";continue}s+=r}s.trim()&&c.push(s);for(let l of c){let r=l.indexOf("=");if(r===-1)continue;let a=l.slice(0,r).trim(),d=l.slice(r+1).trim();e[a]=h(d)}return e}function y(n){let e={package:{},dependencies:{},addresses:{}},t=null,s=n.split(/\r?\n/);for(let i of s){let o=D(i).trim();if(!o)continue;let c=o.match(/^\[([^\]]+)\]$/);if(c){t=c[1].trim();continue}let l=o.indexOf("=");if(l===-1||!t)continue;let r=o.slice(0,l).trim(),a=o.slice(l+1).trim();t==="package"?e.package[r.replace(/-/g,"_")]=h(a):t==="dependencies"?a.startsWith("{")?e.dependencies[r]=P(a):e.dependencies[r]=h(a):t==="addresses"&&(e.addresses[r]=h(a))}return e}var v=class{constructor(e){this.fetcher=e,this.globalAddresses={},this.visited=new Set,this.dependencyFiles={},this.systemDepsLoaded=new Set}async resolve(e,t){let s=y(e);s.addresses&&this.mergeAddresses(s.addresses),s.dependencies&&await this.resolveDeps(s.dependencies),await this.injectSystemDeps(s.dependencies);let i=this.reconstructMoveToml(s,this.globalAddresses),o={...t,"Move.toml":i};return{files:JSON.stringify(o),dependencies:JSON.stringify(this.dependencyFiles)}}mergeAddresses(e){for(let[t,s]of Object.entries(e))this.globalAddresses[t]=this.normalizeAddress(s)}normalizeAddress(e){if(!e)return e;let t=e;return t.startsWith("0x")&&(t=t.slice(2)),/^[0-9a-fA-F]+$/.test(t)?"0x"+t.padStart(64,"0"):e}async resolveDeps(e,t=null){for(let[s,i]of Object.entries(e)){let o,c,l;if(i.git)o=i.git,c=i.rev,l=i.subdir;else if(i.local){if(!t)continue;o=t.git,c=t.rev,l=this.resolvePath(t.subdir||"",i.local)}else continue;let r=`${o}|${c}|${l||""}`;if(this.visited.has(r))continue;this.visited.add(r);let a=await this.fetcher.fetch(o,c,l),d=null;for(let[u,f]of Object.entries(a))if(u.endsWith("Move.toml")){d=f;break}if(d){let u=y(d);u.addresses&&this.mergeAddresses(u.addresses),u.dependencies&&await this.resolveDeps(u.dependencies,{git:o,rev:c,subdir:l})}for(let[u,f]of Object.entries(a))if(u.endsWith(".move")||u.endsWith("Move.toml")){let b=`dependencies/${s}/${u}`;this.dependencyFiles[b]=f}}}resolvePath(e,t){let s=e.split("/").filter(o=>o&&o!=="."),i=t.split("/").filter(o=>o&&o!==".");for(let o of i)o===".."?s.pop():s.push(o);return s.join("/")}reconstructMoveToml(e,t){let s=`[package]
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
- `;if(e.package.edition&&(s+=`edition = "${e.package.edition}"
5
- `),s+=`
18
+ `,c=n||e.package.edition;if(c&&(a+=`edition = "${c}"
19
+ `),a+=`
6
20
  [dependencies]
7
- `,e.dependencies)for(let[i,o]of Object.entries(e.dependencies))s+=`${i} = { git = "${o.git}", rev = "${o.rev}" }
8
- `;s+=`
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[i,o]of Object.entries(t))s+=`${i} = "${o}"
11
- `;return s}async injectSystemDeps(e){if(e){for(let s of Object.values(e))if(!(!s||!s.git||!s.rev)&&this.isSuiRepo(s.git)){await this.addImplicitSystemDepsForRepo(s.git,s.rev);break}}this.dependencyFiles["dependencies/MoveStdlib/Move.toml"]||this.addFallbackSystemDeps()}async addImplicitSystemDepsForRepo(e,t){if(!this.isSuiRepo(e))return;let s=`${e}|${t}`;if(this.systemDepsLoaded.has(s))return;this.systemDepsLoaded.add(s);let i="crates/sui-framework-snapshot/manifest.json";if(!this.fetcher.fetchFile)return;let o=null;try{let c=await this.fetcher.fetchFile(e,t,i);if(c){let l=JSON.parse(c),r=Object.keys(l).map(u=>Number(u)).filter(u=>!Number.isNaN(u)).sort((u,f)=>u-f),a=r[r.length-1],d=l[String(a)];d&&d.packages&&(o=d.packages)}}catch{}o||(o=this.fallbackSystemPackages());for(let c of o)!c||!c.name||!c.id||c.name!=="DeepBook"&&this.addSystemDep(c.name,c.id)}addFallbackSystemDeps(){for(let e of this.fallbackSystemPackages())!e||!e.name||!e.id||e.name!=="DeepBook"&&this.addSystemDep(e.name,e.id)}addSystemDep(e,t){let s=`dependencies/${e}/Move.toml`;if(this.dependencyFiles[s])return;let i=["[package]",`name = "${e}"`,'version = "0.0.0"',`published-at = "${this.normalizeAddress(t)}"`,""].join(`
12
- `);this.dependencyFiles[s]=i}fallbackSystemPackages(){return[{name:"MoveStdlib",id:"0x1"},{name:"Sui",id:"0x2"},{name:"SuiSystem",id:"0x3"},{name:"Bridge",id:"0xb"}]}isSuiRepo(e){return e.includes("github.com/MystenLabs/sui")}};async function S(n,e,t){return new v(t).resolve(n,e)}var j=(()=>{try{return new URL("./sui_move_wasm_bg.wasm",import.meta.url)}catch{return"./sui_move_wasm_bg.wasm"}})(),k;async function p(n){return k||(k=import("./sui_move_wasm.js").then(async e=>(await e.default(n??j),e))),k}function w(n){return JSON.stringify(n??{})}function R(n){return{success:!1,error:n instanceof Error?n.message:typeof n=="string"?n:"Unknown error"}}function F(n){if(typeof n!="object"||n===null)throw new Error("Unexpected compile result shape from wasm");let e=n;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 W(n){let e=t=>t.map(s=>s.toString(16).padStart(2,"0")).join("");try{let t=JSON.parse(n);if(!t.modules||!t.dependencies||!t.digest)throw new Error("missing fields in compiler output");let s=typeof t.digest=="string"?t.digest:e(t.digest);return{success:!0,modules:t.modules,dependencies:t.dependencies,digest:s}}catch(t){return R(t)}}function _(n){if(!n)return n;let e=n;return e.startsWith("0x")&&(e=e.slice(2)),/^[0-9a-fA-F]+$/.test(e)?"0x"+e.padStart(64,"0"):n}function L(n){let e={std:"0x1",sui:"0x2",sui_system:"0x3",bridge:"0xb"},t=n.split(/\r?\n/),s=/^\s*\[[^\]]+\]\s*$/,i=-1,o=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[addresses\]\s*$/.test(t[r])){i=r;for(let a=r+1;a<t.length;a++)if(s.test(t[a])){o=a;break}break}let c=new Set;if(i>=0)for(let r=i+1;r<o;r++){let a=t[r].trim();if(!a||a.startsWith("#"))continue;let d=a.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&c.add(d[1])}let l=Object.entries(e).filter(([r])=>!c.has(r)).map(([r,a])=>`${r} = "${_(a)}"`);return l.length===0?n:(i>=0?t.splice(o,0,...l):t.push("","[addresses]",...l),t.join(`
13
- `))}function U(n){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=n.split(/\r?\n/),s=/^\s*\[[^\]]+\]\s*$/,i=-1,o=t.length;for(let r=0;r<t.length;r++)if(/^\s*\[dependencies\]\s*$/.test(t[r])){i=r;for(let a=r+1;a<t.length;a++)if(s.test(t[a])){o=a;break}break}let c=new Set;if(i>=0)for(let r=i+1;r<o;r++){let a=t[r].trim();if(!a||a.startsWith("#"))continue;let d=a.match(/^([A-Za-z0-9_.-]+)\s*=/);d&&c.add(d[1])}let l=e.filter(r=>!c.has(r.name)).map(r=>`${r.name} = { git = "${r.git}", subdir = "${r.subdir}", rev = "${r.rev}" }`);return l.length===0?n:(i>=0?t.splice(o,0,...l):t.push("","[dependencies]",...l),t.join(`
14
- `))}function B(n){let e={...n??{}};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 s of t){let i=`dependencies/${s.name}/Move.toml`;e[i]||(e[i]=["[package]",`name = "${s.name}"`,'version = "0.0.0"',`published-at = "${_(s.id)}"`,""].join(`
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=U(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=B(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?W(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
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@zktx.io/sui-move-builder",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Build Move packages in web or Node.js with dependency fetching and dump outputs.",
5
+ "keywords": [
6
+ "sui",
7
+ "move",
8
+ "compiler",
9
+ "builder",
10
+ "wasm"
11
+ ],
5
12
  "license": "MIT",
6
13
  "author": "",
7
14
  "repository": {