@@ -118,16 +118,6 @@ pub trait CanisterBuilder {
118118 )
119119 } ) ?;
120120 }
121- std:: fs:: create_dir_all ( & generate_output_dir) . with_context ( || {
122- format ! (
123- "Failed to create dir: {}" ,
124- generate_output_dir. to_string_lossy( )
125- )
126- } ) ?;
127-
128- let generated_idl_path = self . generate_idl ( pool, info, config) ?;
129-
130- let ( env, ty) = check_candid_file ( generated_idl_path. as_path ( ) ) ?;
131121
132122 let bindings = info
133123 . get_declarations_config ( )
@@ -145,6 +135,17 @@ pub trait CanisterBuilder {
145135 ) ;
146136 }
147137
138+ std:: fs:: create_dir_all ( & generate_output_dir) . with_context ( || {
139+ format ! (
140+ "Failed to create dir: {}" ,
141+ generate_output_dir. to_string_lossy( )
142+ )
143+ } ) ?;
144+
145+ let generated_idl_path = self . generate_idl ( pool, info, config) ?;
146+
147+ let ( env, ty) = check_candid_file ( generated_idl_path. as_path ( ) ) ?;
148+
148149 // Typescript
149150 if bindings. contains ( & "ts" . to_string ( ) ) {
150151 let output_did_ts_path = generate_output_dir
@@ -158,6 +159,8 @@ pub trait CanisterBuilder {
158159 )
159160 } ) ?;
160161 eprintln ! ( " {}" , & output_did_ts_path. display( ) ) ;
162+
163+ compile_handlebars_files ( "ts" , info, generate_output_dir) ?;
161164 }
162165
163166 // Javascript
@@ -174,78 +177,8 @@ pub trait CanisterBuilder {
174177 )
175178 } ) ?;
176179 eprintln ! ( " {}" , & output_did_js_path. display( ) ) ;
177- // index.js
178- let mut language_bindings = crate :: util:: assets:: language_bindings ( )
179- . context ( "Failed to get language bindings archive." ) ?;
180- for f in language_bindings
181- . entries ( )
182- . context ( "Failed to read language bindings archive entries." ) ?
183- {
184- let mut file = f. context ( "Failed to read language bindings archive entry." ) ?;
185-
186- let pathname: PathBuf = file
187- . path ( )
188- . context ( "Failed to read language bindings entry path name." ) ?
189- . to_path_buf ( ) ;
190- let extension = pathname. extension ( ) ;
191- let is_template = matches ! ( extension, Some ( ext ) if ext == OsStr :: new( "hbs" ) ) ;
192-
193- if is_template {
194- let mut file_contents = String :: new ( ) ;
195- file. read_to_string ( & mut file_contents)
196- . context ( "Failed to read language bindings archive file content." ) ?;
197-
198- // create the handlebars registry
199- let handlebars = Handlebars :: new ( ) ;
200-
201- let mut data: BTreeMap < String , & String > = BTreeMap :: new ( ) ;
202-
203- let canister_name = & info. get_name ( ) . to_string ( ) ;
204-
205- let node_compatibility = info. get_declarations_config ( ) . node_compatibility ;
206-
207- // Insert only if node outputs are specified
208- let actor_export = if node_compatibility {
209- // leave empty for nodejs
210- "" . to_string ( )
211- } else {
212- format ! (
213- r#"
214180
215- /**
216- * A ready-to-use agent for the {0} canister
217- * @type {{import("@dfinity/agent").ActorSubclass<import("./{0}.did.js")._SERVICE>}}
218- */
219- export const {0} = createActor(canisterId);"# ,
220- canister_name
221- )
222- . to_string ( )
223- } ;
224-
225- data. insert ( "canister_name" . to_string ( ) , canister_name) ;
226- data. insert ( "actor_export" . to_string ( ) , & actor_export) ;
227-
228- let process_string: String = match & info. get_declarations_config ( ) . env_override
229- {
230- Some ( s) => format ! ( r#""{}""# , s. clone( ) ) ,
231- None => {
232- format ! (
233- "process.env.{}{}" ,
234- & canister_name. to_ascii_uppercase( ) ,
235- "_CANISTER_ID"
236- )
237- }
238- } ;
239-
240- data. insert ( "canister_name_process_env" . to_string ( ) , & process_string) ;
241-
242- let new_file_contents =
243- handlebars. render_template ( & file_contents, & data) . unwrap ( ) ;
244- let new_path = generate_output_dir. join ( pathname. with_extension ( "" ) ) ;
245- std:: fs:: write ( & new_path, new_file_contents)
246- . with_context ( || format ! ( "Failed to write to {}." , new_path. display( ) ) ) ?;
247- }
248- }
181+ compile_handlebars_files ( "js" , info, generate_output_dir) ?;
249182 }
250183
251184 // Motoko
@@ -268,6 +201,7 @@ export const {0} = createActor(canisterId);"#,
268201 } else {
269202 eprintln ! ( " {}" , & generated_idl_path. display( ) ) ;
270203 }
204+
271205 Ok ( ( ) )
272206 }
273207
@@ -281,6 +215,87 @@ export const {0} = createActor(canisterId);"#,
281215 }
282216}
283217
218+ fn compile_handlebars_files (
219+ lang : & str ,
220+ info : & CanisterInfo ,
221+ generate_output_dir : & Path ,
222+ ) -> DfxResult {
223+ // index.js
224+ let mut language_bindings = crate :: util:: assets:: language_bindings ( )
225+ . context ( "Failed to get language bindings archive." ) ?;
226+ for f in language_bindings
227+ . entries ( )
228+ . context ( "Failed to read language bindings archive entries." ) ?
229+ {
230+ let mut file = f. context ( "Failed to read language bindings archive entry." ) ?;
231+
232+ let pathname: PathBuf = file
233+ . path ( )
234+ . context ( "Failed to read language bindings entry path name." ) ?
235+ . to_path_buf ( ) ;
236+ let file_extension = format ! ( "{}.hbs" , lang) ;
237+ let is_template = pathname
238+ . to_str ( )
239+ . map_or ( false , |name| name. ends_with ( & file_extension) ) ;
240+
241+ if is_template {
242+ let mut file_contents = String :: new ( ) ;
243+ file. read_to_string ( & mut file_contents)
244+ . context ( "Failed to read language bindings archive file content." ) ?;
245+
246+ // create the handlebars registry
247+ let handlebars = Handlebars :: new ( ) ;
248+
249+ let mut data: BTreeMap < String , & String > = BTreeMap :: new ( ) ;
250+
251+ let canister_name = & info. get_name ( ) . to_string ( ) ;
252+
253+ let node_compatibility = info. get_declarations_config ( ) . node_compatibility ;
254+
255+ // Insert only if node outputs are specified
256+ let actor_export = if node_compatibility {
257+ // leave empty for nodejs
258+ "" . to_string ( )
259+ } else {
260+ format ! (
261+ r#"
262+
263+ /**
264+ * A ready-to-use agent for the {0} canister
265+ * @type {{import("@dfinity/agent").ActorSubclass<import("./{0}.did.js")._SERVICE>}}
266+ */
267+ export const {0} = createActor(canisterId);"# ,
268+ canister_name
269+ )
270+ . to_string ( )
271+ } ;
272+
273+ data. insert ( "canister_name" . to_string ( ) , canister_name) ;
274+ data. insert ( "actor_export" . to_string ( ) , & actor_export) ;
275+
276+ let process_string: String = match & info. get_declarations_config ( ) . env_override {
277+ Some ( s) => format ! ( r#""{}""# , s. clone( ) ) ,
278+ None => {
279+ format ! (
280+ "process.env.{}{}" ,
281+ & canister_name. to_ascii_uppercase( ) ,
282+ "_CANISTER_ID"
283+ )
284+ }
285+ } ;
286+
287+ data. insert ( "canister_name_process_env" . to_string ( ) , & process_string) ;
288+
289+ let new_file_contents = handlebars. render_template ( & file_contents, & data) . unwrap ( ) ;
290+ let new_path = generate_output_dir. join ( pathname. with_extension ( "" ) ) ;
291+ std:: fs:: write ( & new_path, new_file_contents)
292+ . with_context ( || format ! ( "Failed to write to {}." , new_path. display( ) ) ) ?;
293+ }
294+ }
295+
296+ Ok ( ( ) )
297+ }
298+
284299// TODO: this function was copied from src/lib/models/canister.rs
285300fn ensure_trailing_newline ( s : String ) -> String {
286301 if s. ends_with ( '\n' ) {
0 commit comments