11import { basename , resolve } from 'node:path' ;
22import { prepareBinding } from './bindings.ts' ;
33import { ensureDir , writeFileSafe } from './fs.ts' ;
4+ import type { DidFile } from './rs/dist/icp-js-bindgen' ;
45import { type WasmGenerateResult , wasmGenerate , wasmInit } from './rs.ts' ;
56
67const DID_FILE_EXTENSION = '.did' ;
@@ -59,7 +60,11 @@ export type GenerateOptions = {
5960 /**
6061 * The path to the `.did` file.
6162 */
62- didFile : string ;
63+ didFile ?: string ;
64+ /**
65+ *
66+ */
67+ didRemoteUrl ?: string ;
6368 /**
6469 * The path to the directory where the bindings will be generated.
6570 */
@@ -93,6 +98,7 @@ export async function generate(options: GenerateOptions) {
9398
9499 const {
95100 didFile,
101+ didRemoteUrl,
96102 outDir,
97103 output = {
98104 force : false ,
@@ -108,15 +114,56 @@ export async function generate(options: GenerateOptions) {
108114 const force = Boolean ( output . force ) ; // ensure force is a boolean
109115 const declarationsRootExports = Boolean ( output . declarations ?. rootExports ?? false ) ; // ensure rootExports is a boolean
110116
111- const didFilePath = resolve ( didFile ) ;
112- const outputFileName = basename ( didFile , DID_FILE_EXTENSION ) ;
117+ if ( didFile && didRemoteUrl ) {
118+ throw new Error ( 'Only one of didFile or didRemoteUrl should be provided.' ) ;
119+ }
120+
121+ function fromDidFile ( didFile : string ) : {
122+ did_file : DidFile ;
123+ service_name : string ;
124+ } {
125+ return {
126+ did_file : { LocalPath : resolve ( didFile ) } ,
127+ service_name : basename ( didFile , DID_FILE_EXTENSION ) ,
128+ } ;
129+ }
130+
131+ async function fromDidRemoteUrl ( didRemoteUrl : string ) : Promise < {
132+ did_file : DidFile ;
133+ service_name : string ;
134+ } > {
135+ const u = new URL ( didRemoteUrl ) ;
136+ const fileName = u . pathname . split ( '/' ) . pop ( ) ;
137+ const r = await fetch ( didRemoteUrl ) ;
138+ if ( ! r . ok ) {
139+ throw new Error (
140+ `Failed to fetch .did file from URL: ${ didRemoteUrl } . Status: ${ r . status } ${ r . statusText } ` ,
141+ ) ;
142+ }
143+ const didFile = await r . text ( ) ;
144+ return {
145+ did_file : { InlineString : didFile } ,
146+ service_name : fileName || 'service' ,
147+ } ;
148+ }
149+
150+ let did_file : DidFile ;
151+ let service_name : string ;
152+
153+ if ( didFile ) {
154+ ( { did_file, service_name } = fromDidFile ( didFile ) ) ;
155+ } else if ( didRemoteUrl ) {
156+ ( { did_file, service_name } = await fromDidRemoteUrl ( didRemoteUrl ) ) ;
157+ } else {
158+ throw new Error ( 'Either didFile or didRemoteUrl must be provided.' ) ;
159+ }
113160
114161 await ensureDir ( outDir ) ;
115162 await ensureDir ( resolve ( outDir , 'declarations' ) ) ;
116163
117164 const result = wasmGenerate ( {
118- did_file : { LocalPath : didFilePath } ,
119- service_name : outputFileName ,
165+ did_file,
166+ service_name,
120167 declarations : {
121168 root_exports : declarationsRootExports ,
122169 } ,
@@ -125,7 +172,7 @@ export async function generate(options: GenerateOptions) {
125172 await writeBindings ( {
126173 bindings : result ,
127174 outDir,
128- outputFileName,
175+ outputFileName : service_name ,
129176 output,
130177 force,
131178 } ) ;
0 commit comments