@@ -71,14 +71,23 @@ def generate_runtime(
71
71
"""Generate runtime files under the provided output directory."""
72
72
output_dir = Path (output_dir )
73
73
src_core = output_dir / "src" / "core"
74
+ base_name = ts_pascal_case (package_name )
75
+ base_core = base_name [:- 6 ] if base_name .lower ().endswith ("client" ) else base_name
76
+ client_class_name = f"{ base_core } Client"
77
+ service_class_name = f"{ base_core } Api"
78
+
74
79
context = {
75
80
"package_name" : package_name ,
76
81
"custom_description" : custom_description ,
82
+ "client_class_name" : client_class_name ,
83
+ "service_class_name" : service_class_name ,
77
84
}
78
85
79
86
files : dict [Path , str ] = {}
80
87
# Core runtime files
81
- files [src_core / "OpenAPI.ts" ] = self .template_engine .render_template ("base/src/core/OpenAPI.ts.j2" , context )
88
+ files [src_core / "ClientConfig.ts" ] = self .template_engine .render_template (
89
+ "base/src/core/ClientConfig.ts.j2" , context
90
+ )
82
91
files [src_core / "BaseHttpRequest.ts" ] = self .template_engine .render_template (
83
92
"base/src/core/BaseHttpRequest.ts.j2" , context
84
93
)
@@ -92,6 +101,7 @@ def generate_runtime(
92
101
)
93
102
files [src_core / "json.ts" ] = self .template_engine .render_template ("base/src/core/json.ts.j2" , context )
94
103
files [src_core / "msgpack.ts" ] = self .template_engine .render_template ("base/src/core/msgpack.ts.j2" , context )
104
+ files [src_core / "casing.ts" ] = self .template_engine .render_template ("base/src/core/casing.ts.j2" , context )
95
105
96
106
# Index barrel (runtime-only)
97
107
files [output_dir / "src" / "index.ts" ] = self .template_engine .render_template ("base/src/index.ts.j2" , context )
@@ -222,8 +232,8 @@ def collect_model_types(type_str: str) -> set[str]:
222
232
param = node
223
233
schema = param .get ("schema" , {}) or {}
224
234
t = ts_type (schema , schemas )
225
- # BigInt params accept number | bigint
226
- if schema . get ( "x-algokit-bigint" ) is True and t == "bigint" :
235
+ # When a parameter resolves to bigint, accept number | bigint for ergonomics
236
+ if t == "bigint" :
227
237
t_sig = "number | bigint"
228
238
stringify_bigint = True
229
239
else :
@@ -256,23 +266,44 @@ def collect_model_types(type_str: str) -> set[str]:
256
266
}
257
267
)
258
268
259
- # Request body (pick json if present, else msgpack/text)
269
+ # Request body handling
260
270
request_body_ctx : dict [str , Any ] | None = None
271
+ request_body_supports_msgpack = False
272
+ request_body_supports_json = False
261
273
rb = op .get ("requestBody" )
262
274
if isinstance (rb , dict ):
263
275
content = rb .get ("content" , {})
276
+
277
+ # Check what content types are supported
278
+ if "application/msgpack" in content :
279
+ request_body_supports_msgpack = True
280
+ if "application/json" in content :
281
+ request_body_supports_json = True
282
+
283
+ # Determine the type to use for TypeScript typing
284
+ # Prefer JSON schema for typing even when msgpack is used at runtime
264
285
if "application/json" in content :
265
286
sch = (content ["application/json" ] or {}).get ("schema" , {})
266
287
request_body_ctx = {
267
- "mediaType" : "application/json" ,
288
+ "mediaType" : (
289
+ "application/msgpack"
290
+ if request_body_supports_msgpack and not request_body_supports_json
291
+ else "application/json"
292
+ ),
268
293
"tsType" : ts_type (sch , schemas ),
269
294
"required" : rb .get ("required" , False ),
295
+ "supportsMsgpack" : request_body_supports_msgpack ,
296
+ "supportsJson" : request_body_supports_json ,
270
297
}
271
298
elif "application/msgpack" in content :
299
+ # msgpack-only endpoint - infer type from msgpack schema if available
300
+ sch = (content ["application/msgpack" ] or {}).get ("schema" , {})
272
301
request_body_ctx = {
273
302
"mediaType" : "application/msgpack" ,
274
- "tsType" : "Uint8Array " ,
303
+ "tsType" : ts_type ( sch , schemas ) if sch else "any " ,
275
304
"required" : rb .get ("required" , False ),
305
+ "supportsMsgpack" : True ,
306
+ "supportsJson" : False ,
276
307
}
277
308
elif "application/x-binary" in content or "application/octet-stream" in content :
278
309
# Raw binary transaction submission etc.
@@ -281,13 +312,17 @@ def collect_model_types(type_str: str) -> set[str]:
281
312
"mediaType" : mt ,
282
313
"tsType" : "Uint8Array" ,
283
314
"required" : rb .get ("required" , False ),
315
+ "supportsMsgpack" : False ,
316
+ "supportsJson" : False ,
284
317
}
285
318
elif "text/plain" in content :
286
319
sch = (content ["text/plain" ] or {}).get ("schema" , {})
287
320
request_body_ctx = {
288
321
"mediaType" : "text/plain" ,
289
322
"tsType" : ts_type (sch , schemas ),
290
323
"required" : rb .get ("required" , False ),
324
+ "supportsMsgpack" : False ,
325
+ "supportsJson" : False ,
291
326
}
292
327
293
328
# Responses
@@ -387,6 +422,8 @@ def collect_model_types(type_str: str) -> set[str]:
387
422
"acceptsMsgpack" : returns_msgpack ,
388
423
"returnsMsgpack" : returns_msgpack ,
389
424
"supportsJson" : supports_json ,
425
+ "requestBodySupportsMsgpack" : request_body_supports_msgpack ,
426
+ "requestBodySupportsJson" : request_body_supports_json ,
390
427
"hasFormatParam" : has_format_param ,
391
428
"formatVarName" : format_var_name ,
392
429
"signature" : ", " .join (sig_parts ),
@@ -465,21 +502,32 @@ def generate_full(
465
502
for t in op .get ("importTypes" , []):
466
503
import_types .add (t )
467
504
505
+ # Determine class names from package name (e.g., algod_client -> AlgodClient, AlgodApi)
506
+ base_name = ts_pascal_case (package_name )
507
+ base_core = base_name [:- 6 ] if base_name .lower ().endswith ("client" ) else base_name
508
+ client_class_name = f"{ base_core } Client"
509
+ service_class_name = f"{ base_core } Api"
510
+
468
511
svc_content = self .template_engine .render_template (
469
512
"apis/service.ts.j2" ,
470
- {"tag_name" : "api" , "operations" : all_ops , "import_types" : sorted (import_types )},
513
+ {
514
+ "tag_name" : "api" ,
515
+ "operations" : all_ops ,
516
+ "import_types" : sorted (import_types ),
517
+ "service_class_name" : service_class_name ,
518
+ },
471
519
)
472
520
files [apis_dir / "api.service.ts" ] = svc_content
473
521
474
522
files [apis_dir / "index.ts" ] = self .template_engine .render_template (
475
523
"apis/index.ts.j2" ,
476
- {},
524
+ {"service_class_name" : service_class_name },
477
525
)
478
526
479
527
# Client (single service)
480
528
files [Path (output_dir ) / "src" / "client.ts" ] = self .template_engine .render_template (
481
529
"client.ts.j2" ,
482
- {},
530
+ {"service_class_name" : service_class_name , "client_class_name" : client_class_name },
483
531
)
484
532
485
533
# Replace index with full barrel
@@ -488,12 +536,6 @@ def generate_full(
488
536
{},
489
537
)
490
538
491
- # Smoke tests (generated)
492
- files [Path (output_dir ) / "tests" / "generated" / "smoke.generated.spec.ts" ] = (
493
- self .template_engine .render_template (
494
- "full/tests/smoke.spec.ts.j2" ,
495
- {},
496
- )
497
- )
539
+ # Note: Generated smoke tests removed; prefer manual integration tests maintained by developers
498
540
499
541
return files
0 commit comments