diff --git a/scripts/generate_typescript.sh b/scripts/generate_typescript.sh index 57b914a..d521bdb 100755 --- a/scripts/generate_typescript.sh +++ b/scripts/generate_typescript.sh @@ -82,4 +82,15 @@ java -jar target/generator-*-jar-with-dependencies.jar \ -s "$ALGOD_SPEC" \ -t "$TEMPLATE_DIR" \ -m "$SDK_DIR/src/client/v2/algod/models" \ - -p "$TEMPLATE_DIR/common_config.properties,$TEMPLATE_DIR/parameter_order_overrides.properties" \ + -p "$TEMPLATE_DIR/algod_config.properties,$TEMPLATE_DIR/parameter_order_overrides.properties" \ + +java -jar target/generator-*-jar-with-dependencies.jar \ + template \ + -s "$INDEXER_SPEC" \ + -t "$TEMPLATE_DIR" \ + -m "$SDK_DIR/src/client/v2/indexer/models" \ + -p "$TEMPLATE_DIR/indexer_config.properties" \ + +# Run prettier to fix formatting of generated code. +pushd $SDK_DIR +npm run format diff --git a/typescript_templates/algod_config.properties b/typescript_templates/algod_config.properties new file mode 100644 index 0000000..ff82adf --- /dev/null +++ b/typescript_templates/algod_config.properties @@ -0,0 +1,9 @@ +# In the future we should change this to 0 or remove entirely. It has two +# properties that are undesirable: +# 1. If new fields are added to a model that cause it to cross this threshold, +# we now have a breaking change. +# 2. Field order matters if we don't use object params, which means maintance +# and code generation changes are harder to do without introducing breaking +# changes. +use_object_params_if_greater_than=4 +indexer=false diff --git a/typescript_templates/common_config.properties b/typescript_templates/common_config.properties deleted file mode 100644 index 1f30559..0000000 --- a/typescript_templates/common_config.properties +++ /dev/null @@ -1 +0,0 @@ -use_object_params_if_greater_than = 4 diff --git a/typescript_templates/indexer_config.properties b/typescript_templates/indexer_config.properties new file mode 100644 index 0000000..2a0d48c --- /dev/null +++ b/typescript_templates/indexer_config.properties @@ -0,0 +1,2 @@ +use_object_params_if_greater_than=0 +indexer=true diff --git a/typescript_templates/model.vm b/typescript_templates/model.vm index 4b5ffeb..50e9f80 100644 --- a/typescript_templates/model.vm +++ b/typescript_templates/model.vm @@ -11,11 +11,11 @@ string## #elseif ( $param.algorandFormat == "BlockHeader" ) BlockHeader## #elseif ( $param.algorandFormat == "uint64" ) -number | bigint## +(number | bigint)## #elseif ( $param.type == "object" ) Record## #elseif ( $param.type == "integer" || $param.arrayType == "integer" ) -number | bigint## +(number | bigint)## #elseif ( $param.type == "boolean" ) boolean## #elseif( $param.type == "address" ) @@ -47,7 +47,37 @@ $unknown.type ## force a template failure with an unknown type #end #if ($param.arrayType && $param.arrayType != "")[]#end## Add array postfix to arrays... #end -## Converts a parameter type into the SDK specific type. +## Check if there's a class associated with this type +#macro ( isClassType $param ) +#if ( $param.algorandFormat == "SignedTransaction" ) +false## +#elseif ( $param.algorandFormat == "Address" ) +false## +#elseif ( $param.algorandFormat == "BlockHeader" ) +false## +#elseif ( $param.algorandFormat == "uint64" ) +false## +#elseif ( $param.type == "object" ) +false## +#elseif ( $param.type == "integer" || $param.arrayType == "integer" ) +false## +#elseif ( $param.type == "boolean" ) +false## +#elseif( $param.type == "address" ) +false## +#elseif( $param.type == "binary" ) +false## +#elseif($param.arrayType && $param.format == "byte") +false## +#elseif( $param.type == "string" && $param.format == "byte" ) +false## +#elseif( $param.type == "string" || $param.arrayType == "string" ) +false## +#else +true## +#end +#end +## Create an expression to assign a field in a constructor #macro ( constructorAssignType $prop ) #set( $argType = "#toSdkType($prop, true)" ) #set( $fieldType = "#toSdkType($prop, false)" ) @@ -65,6 +95,26 @@ UNHANDLED CONSTRUCTOR TYPE CONVERSION $unknown.type ## force a template failure with an unknown type #end #end +## Create an expression to assign a field in the from_obj_for_encoding function +#macro ( fromObjForEncodingAssignType $value $prop ) +#if ( "#isClassType($prop)" == "false" ) +$value## +#elseif ( $prop.arrayType ) +#set ( $assignment = "${value}.map(${prop.arrayType}.from_obj_for_encoding)" ) +#if ($prop.required) +$assignment## +#else +typeof $value !== 'undefined' ? $assignment : undefined## +#end +#else +#set ( $assignment = "${prop.refType}.from_obj_for_encoding($value)" ) +#if ($prop.required) +$assignment## +#else +typeof $value !== 'undefined' ? $assignment : undefined## +#end +#end +#end #macro ( questionMarkIfOptional $param ) #if ( ! $param.required ) ?## @@ -79,9 +129,11 @@ $unknown.type ## force a template failure with an unknown type */ /* eslint-disable no-use-before-define */ -import BaseModel from './base'; +import BaseModel from '../../basemodel'; +#if ( $propFile.indexer == "false" ) import { EncodedSignedTransaction } from '../../../../types/transactions/encoded'; import BlockHeader from '../../../../types/blockHeader'; +#end #foreach( $modelEntry in $models.entrySet() ) #set( $def = $modelEntry.key ) @@ -150,6 +202,37 @@ export class $def.name extends BaseModel { #end } } + + // eslint-disable-next-line camelcase + static from_obj_for_encoding(data: Record): $def.name { + /* eslint-disable dot-notation */ +#set ( $d = "$" )## Create a variable in order to insert a $ into the code +#foreach( $prop in $props ) +#if ($prop.required) +#if ($prop.arrayType) + if (!Array.isArray(data['$prop.propertyName'])) + throw new Error(`Response is missing required array field '${prop.propertyName}': ${d}{data}`); +#else + if (typeof data['$prop.propertyName'] === 'undefined') + throw new Error(`Response is missing required field '${prop.propertyName}': ${d}{data}`); +#end +#end +#end +#if ($use_object_params) + return new ${def.name}({ +#foreach( $prop in $props ) + #paramName($prop): #fromObjForEncodingAssignType("data['$prop.propertyName']", $prop), +#end + }); +#else + return new ${def.name}( +#foreach( $prop in $props ) + #fromObjForEncodingAssignType("data['$prop.propertyName']", $prop), +#end + ); +#end + /* eslint-enable dot-notation */ + } } #end