Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS v3: Native bigint support for select fields #72

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/generate_typescript.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ 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/algod_config.properties,$TEMPLATE_DIR/parameter_order_overrides.properties" \
-p "$TEMPLATE_DIR/algod_config.properties" \

java -jar target/generator-*-jar-with-dependencies.jar \
template \
Expand Down
51 changes: 51 additions & 0 deletions typescript_templates/algod_config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,54 @@
# changes.
use_object_params_if_greater_than=0
indexer=false
# Type override conventions:
# * All Algo and asset amounts should be bigint (including fees)
# * All round numbers should be bigint, including any quantities you would add
# to a round number (e.g. offset or duration)
# * All application and asset IDs should be bigint
# * All timestamps in nanoseconds should be bigint
# * If there is a quantity whose purpose is to be added to, subtracted from, or
# otherwise operated on with a bigint, it should be a bigint for ease of use
# * Other quantities outside of the above and which will never exceed the maximum
# safe javascript integer should be number
type_override_Account_amount=bigint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumb question, why should we leave this as configurable at all? While we are putting sane defaults here, what are the cases where we should support the client overriding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First I should explain what's happening in this file. It's really just a list of key-value definitions.

In the template code, specifically here:

#set( $d = "$" )
#set( $e = "!" )
#set( $type_override_variable = "${d}${e}propFile.type_override_${className}_#paramName(${param})" )
#set( $type_override = "#evaluate($type_override_variable)" )

we look at propFile.type_override_X_Y, where X is the generated class name and Y is the field in that class. If there's a value associated with that key from the prop file, we will use the type override that it declares.

So it's less about making each field configurable, and more about configuring the list of fields and their overrides.

I chose to put the overrides in this config file for a few reasons:

  1. Different fields needed to be overriden for algod and indexer
  2. It's much easier to encode this information in a file like this instead of placing a massive if/elseif/.../else statement in the template code

type_override_Account_amountWithoutPendingRewards=bigint
type_override_Account_minBalance=bigint
type_override_Account_pendingRewards=bigint
type_override_Account_rewards=bigint
type_override_Account_round=bigint
type_override_Account_rewardBase=bigint
type_override_AccountApplicationResponse_round=bigint
type_override_AccountAssetResponse_round=bigint
type_override_AccountParticipation_voteFirstValid=bigint
type_override_AccountParticipation_voteKeyDilution=bigint
type_override_AccountParticipation_voteLastValid=bigint
type_override_Application_id=bigint
type_override_ApplicationLocalState_id=bigint
type_override_Asset_index=bigint
type_override_AssetHolding_assetId=bigint
type_override_Box_round=bigint
type_override_BoxReference_app=bigint
type_override_GetSyncRoundResponse_round=bigint
type_override_NodeStatusResponse_catchupTime=bigint
type_override_NodeStatusResponse_lastRound=bigint
type_override_NodeStatusResponse_nextVersionRound=bigint
type_override_NodeStatusResponse_timeSinceLastRound=bigint
type_override_NodeStatusResponse_upgradeDelay=bigint
type_override_NodeStatusResponse_upgradeNextProtocolVoteBefore=bigint
type_override_PendingTransactionResponse_applicationIndex=bigint
type_override_PendingTransactionResponse_assetClosingAmount=bigint
type_override_PendingTransactionResponse_assetIndex=bigint
type_override_PendingTransactionResponse_closeRewards=bigint
type_override_PendingTransactionResponse_closingAmount=bigint
type_override_PendingTransactionResponse_confirmedRound=bigint
type_override_PendingTransactionResponse_receiverRewards=bigint
type_override_PendingTransactionResponse_senderRewards=bigint
type_override_SimulateRequest_round=bigint
type_override_SimulateResponse_lastRound=bigint
type_override_SupplyResponse_currentRound=bigint
type_override_SupplyResponse_onlineMoney=bigint
type_override_SupplyResponse_totalMoney=bigint
type_override_TransactionParametersResponse_fee=bigint
type_override_TransactionParametersResponse_lastRound=bigint
type_override_TransactionParametersResponse_minFee=bigint
74 changes: 74 additions & 0 deletions typescript_templates/indexer_config.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,76 @@
use_object_params_if_greater_than=0
indexer=true
# Type override conventions:
# * All Algo and asset amounts should be bigint (including fees)
# * All round numbers should be bigint, including any quantities you would add
# to a round number (e.g. offset or duration)
# * All application and asset IDs should be bigint
# * All timestamps in nanoseconds should be bigint
# * If there is a quantity whose purpose is to be added to, subtracted from, or
# otherwise operated on with a bigint, it should be a bigint for ease of use
# * Other quantities outside of the above and which will never exceed the maximum
# safe javascript integer should be number
type_override_Account_amount=bigint
type_override_Account_amountWithoutPendingRewards=bigint
type_override_Account_pendingRewards=bigint
type_override_Account_rewards=bigint
type_override_Account_round=bigint
type_override_Account_rewardBase=bigint
type_override_AccountParticipation_voteFirstValid=bigint
type_override_AccountParticipation_voteKeyDilution=bigint
type_override_AccountParticipation_voteLastValid=bigint
type_override_AccountResponse_currentRound=bigint
type_override_AccountsResponse_currentRound=bigint
type_override_Application_id=bigint
type_override_ApplicationLocalState_id=bigint
type_override_ApplicationLocalStatesResponse_currentRound=bigint
type_override_ApplicationLogsResponse_applicationId=bigint
type_override_ApplicationLogsResponse_currentRound=bigint
type_override_ApplicationResponse_currentRound=bigint
type_override_ApplicationsResponse_currentRound=bigint
type_override_Asset_index=bigint
type_override_AssetBalancesResponse_currentRound=bigint
type_override_AssetHolding_assetId=bigint
type_override_AssetHoldingsResponse_currentRound=bigint
type_override_AssetResponse_currentRound=bigint
type_override_AssetsResponse_currentRound=bigint
type_override_Block_round=bigint
type_override_BlockRewards_rewardsCalculationRound=bigint
type_override_BlockRewards_rewardsLevel=bigint
type_override_BlockRewards_rewardsRate=bigint
type_override_BlockRewards_rewardsResidue=bigint
type_override_BlockUpgradeState_nextProtocolSwitchOn=bigint
type_override_BlockUpgradeState_nextProtocolVoteBefore=bigint
type_override_BlockUpgradeVote_upgradeDelay=bigint
type_override_Box_round=bigint
type_override_BoxesResponse_applicationId=bigint
type_override_HealthCheck_round=bigint
type_override_StateProofTracking_nextRound=bigint
type_override_StateProofTracking_onlineTotalWeight=bigint
type_override_StateProofTracking_type=number
type_override_StateSchema_numByteSlice=number
type_override_StateSchema_numUint=number
type_override_Transaction_fee=bigint
type_override_Transaction_firstValid=bigint
type_override_Transaction_lastValid=bigint
type_override_Transaction_closeRewards=bigint
type_override_Transaction_closingAmount=bigint
type_override_Transaction_confirmedRound=bigint
type_override_Transaction_createdApplicationIndex=bigint
type_override_Transaction_createdAssetIndex=bigint
type_override_Transaction_receiverRewards=bigint
type_override_Transaction_senderRewards=bigint
type_override_TransactionApplication_applicationId=bigint
type_override_TransactionApplication_foreignApps=bigint
type_override_TransactionApplication_foreignAssets=bigint
type_override_TransactionAssetConfig_assetId=bigint
type_override_TransactionAssetFreeze_assetId=bigint
type_override_TransactionAssetTransfer_assetId=bigint
type_override_TransactionKeyreg_voteFirstValid=bigint
type_override_TransactionKeyreg_voteKeyDilution=bigint
type_override_TransactionKeyreg_voteLastValid=bigint
type_override_TransactionPayment_amount=bigint
type_override_TransactionPayment_closeAmount=bigint
type_override_TransactionResponse_currentRound=bigint
type_override_TransactionStateProof_stateProofType=number
type_override_TransactionsResponse_currentRound=bigint
57 changes: 47 additions & 10 deletions typescript_templates/model.vm
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,31 @@
$str.kebabToCamel($param.propertyName.replaceAll("_", "-"))##
#end
## Converts a parameter type into the SDK specific type.
#macro ( toSdkType $param $isArgType )
#macro ( toSdkType $className $param $isArgType )
#set( $d = "$" )
#set( $e = "!" )
#set( $type_override_variable = "${d}${e}propFile.type_override_${className}_#paramName(${param})" )
#set( $type_override = "#evaluate($type_override_variable)" )
#if ( $param.algorandFormat == "SignedTransaction" )
EncodedSignedTransaction##
#elseif ( $param.algorandFormat == "Address" ) ## No special handling for Address in go SDK
string##
#elseif ( $param.algorandFormat == "BlockHeader" )
BlockHeader##
#elseif ( $param.algorandFormat == "uint64" )
#elseif ( $type_override == "bigint" || ( $param.algorandFormat == "uint64" && $type_override.length() == 0 ) )
#if ( $isArgType )
(number | bigint)##
#else
bigint##
#end
#elseif ( $param.type == "object" )
Record<string, any>##
#elseif ( $param.type == "integer" || $param.arrayType == "integer" )
#elseif ( $type_override == "number" || ( ( $param.type == "integer" || $param.arrayType == "integer" ) && $type_override.length() == 0 ) )
#if ( $isArgType )
(number | bigint)##
#else
number##
#end
#elseif ( $param.type == "boolean" )
boolean##
#elseif( $param.type == "address" )
Expand Down Expand Up @@ -78,14 +90,38 @@ 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)" )
#macro ( constructorAssignType $className $prop )
#set( $argType = "#toSdkType($className, $prop, true)" )
#set( $fieldType = "#toSdkType($className, $prop, false)" )
#set( $name = "#paramName($prop)" )
#if ( $argType == $fieldType )
$name##
#elseif ( $argType == "string | Uint8Array" && $fieldType == "Uint8Array" )
typeof $name === 'string' ? base64ToBytes($name) : $name##
#elseif ( $argType == "(number | bigint)" && $fieldType == "bigint" )
#if ( $prop.required )
ensureBigInt($name)##
#else
typeof $name === 'undefined' ? undefined : ensureBigInt($name)##
#end
#elseif ( $argType == "(number | bigint)[]" && $fieldType == "bigint[]" )
#if ( $prop.required )
${name}.map(ensureBigInt)##
#else
typeof ${name} === 'undefined' ? undefined : ${name}.map(ensureBigInt)##
#end
#elseif ( $argType == "(number | bigint)" && $fieldType == "number" )
#if ( $prop.required )
ensureSafeInteger($name)##
#else
typeof $name === 'undefined' ? undefined : ensureSafeInteger($name)##
#end
#elseif ( $argType == "(number | bigint)[]" && $fieldType == "number[]" )
#if ( $prop.required )
${name}.map(ensureSafeInteger)##
#else
typeof ${name} === 'undefined' ? undefined : ${name}.map(ensureSafeInteger)##
#end
#else
UNHANDLED CONSTRUCTOR TYPE CONVERSION
- property: $prop
Expand Down Expand Up @@ -129,6 +165,7 @@ typeof $value !== 'undefined' ? $assignment : undefined##
*/

/* eslint-disable no-use-before-define */
import { ensureBigInt, ensureSafeInteger } from '../../../../utils/utils.js';
import { base64ToBytes } from '../../../../encoding/binarydata.js';
#if ( $propFile.indexer == "false" )
import BlockHeader from '../../../../types/blockHeader.js';
Expand Down Expand Up @@ -160,7 +197,7 @@ export class $def.name extends BaseModel {
* $str.formatDoc($prop.doc, " * ")
*/
#end
public #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, false);
public #paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, false);

#end
/**
Expand All @@ -178,13 +215,13 @@ export class $def.name extends BaseModel {
#if ($use_object_params)
#paramName($prop),
#else
#paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, true),
#paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, true),
#end
#end
#if ($use_object_params)
}: {
#foreach ( $prop in $props )
#paramName($prop)#questionMarkIfOptional($prop): #toSdkType($prop, true)
#paramName($prop)#questionMarkIfOptional($prop): #toSdkType($def.name, $prop, true)

#end
}) {
Expand All @@ -194,7 +231,7 @@ export class $def.name extends BaseModel {
super();
#foreach( $prop in $props )
#set( $var = "#paramName($prop)" )
this.$var = #constructorAssignType($prop);
this.$var = #constructorAssignType($def.name, $prop);
#end

this.attribute_map = {
Expand Down
10 changes: 0 additions & 10 deletions typescript_templates/parameter_order_overrides.properties

This file was deleted.

Loading