From 3451dcfbb8bfced1be268ed8850fd3c1fa1a66d0 Mon Sep 17 00:00:00 2001 From: Benjamin DeMann Date: Wed, 4 Oct 2023 10:33:52 -0600 Subject: [PATCH] rename paramIdls to paramCandidTypes etc --- src/lib/candid/index.ts | 22 ++- src/lib/candid/recursive.ts | 10 +- src/lib/candid/types/reference/func.ts | 8 +- src/lib/candid/types/reference/service.ts | 187 +++++++------------- src/lib/canister_methods/heartbeat.ts | 6 +- src/lib/canister_methods/index.ts | 8 +- src/lib/canister_methods/init.ts | 10 +- src/lib/canister_methods/inspect_message.ts | 6 +- src/lib/canister_methods/post_upgrade.ts | 10 +- src/lib/canister_methods/pre_upgrade.ts | 6 +- src/lib/canister_methods/query.ts | 14 +- src/lib/canister_methods/update.ts | 8 +- 12 files changed, 119 insertions(+), 176 deletions(-) diff --git a/src/lib/candid/index.ts b/src/lib/candid/index.ts index 3229b5b2c6..3013d0aa1b 100644 --- a/src/lib/candid/index.ts +++ b/src/lib/candid/index.ts @@ -115,20 +115,26 @@ export type Parent = { name: string; }; -export function toIDLType(idl: CandidType, parents: Parent[]): IDL.Type { - if ('_azleName' in idl) { - const parent = parents.find((parent) => parent.name === idl._azleName); - // If we the parent isn't undefined (ie we found one with the same name) - // this is a recursive type and we should return the parent rec idl instead of calling getIDL +export function toIDLType( + candidType: CandidType, + parents: Parent[] +): IDL.Type { + if ('_azleName' in candidType) { + const parent = parents.find( + (parent) => parent.name === candidType._azleName + ); + // If the parent isn't undefined (ie we found one with the same name) + // this is a recursive type and we should return the parent rec idl + // instead of calling getIDL if (parent !== undefined) { return parent.idl; } } - if ('_azleIsCanister' in idl && idl._azleIsCanister) { - return toIDLType((idl as any)(), parents); + if ('_azleIsCanister' in candidType && candidType._azleIsCanister) { + return toIDLType((candidType as any)(), parents); } // All CandidTypes ought to have a getIDL function defined for them - return (idl as any).getIDL(parents); + return (candidType as any).getIDL(parents); } export function toParamIDLTypes( diff --git a/src/lib/candid/recursive.ts b/src/lib/candid/recursive.ts index e55838bad3..77dc55abbb 100644 --- a/src/lib/candid/recursive.ts +++ b/src/lib/candid/recursive.ts @@ -2,7 +2,7 @@ import { v4 } from 'uuid'; import { IDL } from '@dfinity/candid'; import { CandidType, Parent } from './index'; -type _AzleRecursiveFunction = { +export type _AzleRecursiveFunction = { (...args: any[]): CandidType; _azleName?: string; _azleIsRecursive?: boolean; @@ -13,11 +13,11 @@ export function Recursive(candidTypeCallback: any): any { const name = v4(); let result: _AzleRecursiveFunction = (...args: any[]) => { - const idl = candidTypeCallback(); - if (idl._azleIsCanister) { - return idl(...args); + const candidType = candidTypeCallback(); + if (candidType._azleIsCanister) { + return candidType(...args); } - return idl; + return candidType; }; result._azleName = name; diff --git a/src/lib/candid/types/reference/func.ts b/src/lib/candid/types/reference/func.ts index 46011247f0..aa3483a826 100644 --- a/src/lib/candid/types/reference/func.ts +++ b/src/lib/candid/types/reference/func.ts @@ -12,15 +12,15 @@ const modeToCandid = { }; export function Func( - paramsIdls: CandidType[], - returnIdl: CandidType, + paramCandidTypes: CandidType[], + returnCandidTypes: CandidType, mode: Mode ): [Principal, string] & { _azleCandidType?: '_azleCandidType' } { return { getIDL(parents: Parent[]) { return IDL.Func( - toParamIDLTypes(paramsIdls, parents), - toReturnIDLType(returnIdl, parents), + toParamIDLTypes(paramCandidTypes, parents), + toReturnIDLType(returnCandidTypes, parents), modeToCandid[mode] ); } diff --git a/src/lib/candid/types/reference/service.ts b/src/lib/candid/types/reference/service.ts index 8f8633bef7..e56c794982 100644 --- a/src/lib/candid/types/reference/service.ts +++ b/src/lib/candid/types/reference/service.ts @@ -5,6 +5,7 @@ import { toReturnIDLType, CandidType } from '../../index'; +import { _AzleRecursiveFunction } from '../../recursive'; import { ic } from '../../../ic'; import { Principal } from './principal'; import { IDL } from '@dfinity/candid'; @@ -16,7 +17,9 @@ type CanisterOptions = { }; type _AzleCanisterOptions = { - [key: string]: (parent: Parent | undefined) => CanisterMethodInfo; + [key: string]: ( + parentOrUndefined: _AzleRecursiveFunction | undefined + ) => CanisterMethodInfo; }; type _AzleFunctionReturnType = { @@ -33,6 +36,11 @@ type _AzleFunctionReturnType = { getIDL?: (parents: Parent[]) => IDL.Type; }; +type _AzleCanisterReturnType = { + (parentOrPrincipal: _AzleRecursiveFunction | Principal): void; + _azleIsCanister?: boolean; +}; + type CanisterReturn = { [EndpointName in keyof T]: T[EndpointName] extends CanisterMethodInfo< infer Params, @@ -53,7 +61,7 @@ export function Canister( ): CallableObject & { _azleCandidType?: '_azleCandidType' } { const _azleCanisterOptions = serviceOptions as unknown as _AzleCanisterOptions; - let result = (parentOrPrincipal: any) => { + let result: _AzleCanisterReturnType = (parentOrPrincipal: any) => { const originalPrincipal = parentOrPrincipal; const parentOrUndefined = parentOrPrincipal !== undefined && parentOrPrincipal._isPrincipal @@ -64,19 +72,6 @@ export function Canister( const key = entry[0]; const value = entry[1](parentOrUndefined); - // if (principal === undefined) { - // return { - // ...acc, - // [key]: (...args: any[]) => { - // return serviceCall( - // principal as any, - // key, - // value.paramsIdls, - // value.returnIdl - // )(...args); - // } - // }; - // } else { return { ...acc, [key]: { @@ -85,8 +80,8 @@ export function Canister( return serviceCall( this.principal as any, key, - value.paramsIdls, - value.returnIdl + value.paramCandidTypes, + value.returnCandidType )(...args); } } @@ -189,19 +184,6 @@ export function Canister( const key = entry[0]; const value = entry[1](parentOrUndefined); - // if (principal === undefined) { - // return { - // ...acc, - // [key]: (...args: any[]) => { - // return serviceCall( - // principal as any, - // key, - // value.paramsIdls, - // value.returnIdl - // )(...args); - // } - // }; - // } else { return { ...acc, [key]: { @@ -210,8 +192,8 @@ export function Canister( return serviceCall( principal as any, key, - value.paramsIdls, - value.returnIdl + value.paramCandidTypes, + value.returnCandidType )(...args); } } @@ -235,11 +217,11 @@ export function Canister( returnFunction.queries = queries; returnFunction.updates = updates; returnFunction.callbacks = callbacks; - (returnFunction.getSystemFunctionIDLs = ( + returnFunction.getSystemFunctionIDLs = ( parents: Parent[] ): IDL.FuncClass[] => { - const serviceFunctionInfo: ServiceFunctionInfo = - _azleCanisterOptions; + const serviceFunctionInfo = + _azleCanisterOptions as unknown as ServiceFunctionInfo; return Object.entries(serviceFunctionInfo).reduce( (accumulator, [_methodName, functionInfo]) => { @@ -250,11 +232,11 @@ export function Canister( } const paramRealIdls = toParamIDLTypes( - functionInfo(parentOrUndefined).paramsIdls, + functionInfo(parentOrUndefined).paramCandidTypes, parents ); const returnRealIdl = toReturnIDLType( - functionInfo(parentOrUndefined).returnIdl, + functionInfo(parentOrUndefined).returnCandidType, parents ); return [ @@ -264,101 +246,56 @@ export function Canister( }, [] as IDL.FuncClass[] ); - }), - (returnFunction.getIDL = (parents: Parent[]): IDL.ServiceClass => { - const serviceFunctionInfo: ServiceFunctionInfo = - _azleCanisterOptions; - - const record = Object.entries(serviceFunctionInfo).reduce( - (accumulator, [methodName, functionInfo]) => { - const paramRealIdls = toParamIDLTypes( - functionInfo(parentOrUndefined).paramsIdls, - parents - ); - const returnRealIdl = toReturnIDLType( - functionInfo(parentOrUndefined).returnIdl, - parents - ); - - const mode = functionInfo(parentOrUndefined).mode; - let annotations: string[] = []; - if (mode === 'update') { - // do nothing - } else if (mode === 'query') { - annotations = ['query']; - } else { - // We don't want init, post upgrade, etc showing up in the idl - return accumulator; - } + }; + returnFunction.getIDL = (parents: Parent[]): IDL.ServiceClass => { + const serviceFunctionInfo = + _azleCanisterOptions as unknown as ServiceFunctionInfo; - return { - ...accumulator, - [methodName]: IDL.Func( - paramRealIdls, - returnRealIdl, - annotations - ) - }; - }, - {} as Record - ); + const record = Object.entries(serviceFunctionInfo).reduce( + (accumulator, [methodName, functionInfo]) => { + const paramRealIdls = toParamIDLTypes( + functionInfo(parentOrUndefined).paramCandidTypes, + parents + ); + const returnRealIdl = toReturnIDLType( + functionInfo(parentOrUndefined).returnCandidType, + parents + ); - return IDL.Service(record); - }); + const mode = functionInfo(parentOrUndefined).mode; + let annotations: string[] = []; + if (mode === 'update') { + // do nothing + } else if (mode === 'query') { + annotations = ['query']; + } else { + // We don't want init, post upgrade, etc showing up in the idl + return accumulator; + } + + return { + ...accumulator, + [methodName]: IDL.Func( + paramRealIdls, + returnRealIdl, + annotations + ) + }; + }, + {} as Record + ); + + return IDL.Service(record); + }; if (originalPrincipal !== undefined && originalPrincipal._isPrincipal) { return returnFunction(originalPrincipal); } return returnFunction; - - // TODO loop through each key and simply grab the candid off - // TODO grab the init/post_upgrade candid as well - // return { - // candid: `${ - // candidTypes.length === 0 ? '' : candidTypes.join('\n') + '\n' - // }service: () -> { - // ${Object.entries(serviceOptions) - // .map((entry) => { - // return `${entry[0]}: ${entry[1].candid}`; - // }) - // .join('\n ')} - // } - // `, - // queries, - // updates, - // callbacks, - // principal, - // ...callbacks, // TODO then we can't use any names that could collide in this object - // getIDL(parents: Parent[]): IDL.ServiceClass { - // const serviceFunctionInfo: ServiceFunctionInfo = serviceOptions; - - // const record = Object.entries(serviceFunctionInfo).reduce( - // (accumulator, [methodName, functionInfo]) => { - // const paramRealIdls = toParamIDLTypes(functionInfo.paramsIdls); - // const returnRealIdl = toReturnIDLType(functionInfo.returnIdl); - - // const annotations = - // functionInfo.mode === 'update' ? [] : ['query']; - - // return { - // ...accumulator, - // [methodName]: IDL.Func( - // paramRealIdls, - // returnRealIdl, - // annotations - // ) - // }; - // }, - // {} as Record - // ); - - // return IDL.Service(record); - // } - // } as any; }; result._azleIsCanister = true; - return result; + return result as any; } type CallRawFunction = typeof ic.callRaw | typeof ic.callRaw128; @@ -422,10 +359,10 @@ function createGlobalGuard( type FunctionInfo = { mode: 'query' | 'update'; - paramIdls: any[]; - returnIdl: any; + paramCandidTypes: CandidType[]; + returnCandidType: CandidType; }; interface ServiceFunctionInfo { - [key: string]: FunctionInfo; + [key: string]: (parent: _AzleRecursiveFunction | undefined) => FunctionInfo; } diff --git a/src/lib/canister_methods/heartbeat.ts b/src/lib/canister_methods/heartbeat.ts index 3c91e9ae42..ae5ec61dda 100644 --- a/src/lib/canister_methods/heartbeat.ts +++ b/src/lib/canister_methods/heartbeat.ts @@ -12,10 +12,10 @@ export function heartbeat( return { mode: 'heartbeat', callback: finalCallback, - paramsIdls: [], - returnIdl: Void, + paramCandidTypes: [], + returnCandidType: Void, async: isAsync(callback), guard: undefined - }; + } as CanisterMethodInfo<[], Void>; }) as any; } diff --git a/src/lib/canister_methods/index.ts b/src/lib/canister_methods/index.ts index 31fba439c2..35ed2b7a55 100644 --- a/src/lib/canister_methods/index.ts +++ b/src/lib/canister_methods/index.ts @@ -28,8 +28,8 @@ export type CanisterMethodInfo, K> = { | 'preUpgrade'; async: boolean; callback?: (...args: any) => any; - paramsIdls: any[]; - returnIdl: any; + paramCandidTypes: any[]; + returnCandidType: any; guard: (() => any) | undefined; }; @@ -70,7 +70,7 @@ export function executeMethod( return; } - const decodedArgs = decodeMultiple(paramCandidTypes, args[0]); + const decodedArgs = decodeMultiple(paramCandidTypes, args[0], parents); const result = callback(...decodedArgs); @@ -94,7 +94,7 @@ export function executeMethod( console.log(`final instructions: ${ic.instructionCounter()}`); if (!manual) { - ic.replyRaw(encode(returnCandidType, result)); + ic.replyRaw(encode(returnCandidType, result, parents)); } }) .catch((error: any) => { diff --git a/src/lib/canister_methods/init.ts b/src/lib/canister_methods/init.ts index 22e5ca8b3c..90a4a47da0 100644 --- a/src/lib/canister_methods/init.ts +++ b/src/lib/canister_methods/init.ts @@ -6,7 +6,7 @@ export function init< const Params extends ReadonlyArray, GenericCallback extends Callback >( - paramsIdls: Params, + paramCandidTypes: Params, callback?: Awaited> extends TypeMapping ? GenericCallback : never @@ -20,7 +20,7 @@ export function init< 'init', args, callback, - paramsIdls as any, + paramCandidTypes as unknown as CandidType[], Void, false, createParents(parent) @@ -30,10 +30,10 @@ export function init< return { mode: 'init', callback: finalCallback, - paramsIdls: paramsIdls as any, - returnIdl: Void, + paramCandidTypes: paramCandidTypes as any, + returnCandidType: Void, async: false, guard: undefined - }; + } as CanisterMethodInfo; }) as any; } diff --git a/src/lib/canister_methods/inspect_message.ts b/src/lib/canister_methods/inspect_message.ts index 2e7f658eda..a90833e79f 100644 --- a/src/lib/canister_methods/inspect_message.ts +++ b/src/lib/canister_methods/inspect_message.ts @@ -20,10 +20,10 @@ export function inspectMessage( return { mode: 'inspectMessage', callback: finalCallback, - paramsIdls: [], - returnIdl: Void, + paramCandidTypes: [], + returnCandidType: Void, async: false, guard: undefined - }; + } as CanisterMethodInfo<[], Void>; }) as any; } diff --git a/src/lib/canister_methods/post_upgrade.ts b/src/lib/canister_methods/post_upgrade.ts index e9857ed2fa..4b34b622e2 100644 --- a/src/lib/canister_methods/post_upgrade.ts +++ b/src/lib/canister_methods/post_upgrade.ts @@ -6,7 +6,7 @@ export function postUpgrade< const Params extends ReadonlyArray, GenericCallback extends Callback >( - paramsIdls: Params, + paramCandidTypes: Params, callback?: Awaited> extends TypeMapping ? GenericCallback : never @@ -20,7 +20,7 @@ export function postUpgrade< 'postUpgrade', args, callback, - paramsIdls as any, + paramCandidTypes as unknown as CandidType[], Void, false, createParents(parent) @@ -30,10 +30,10 @@ export function postUpgrade< return { mode: 'postUpgrade', callback: finalCallback, - paramsIdls: paramsIdls as any, - returnIdl: Void, + paramCandidTypes: paramCandidTypes as unknown as CandidType[], + returnCandidType: Void, async: false, guard: undefined - }; + } as CanisterMethodInfo; }) as any; } diff --git a/src/lib/canister_methods/pre_upgrade.ts b/src/lib/canister_methods/pre_upgrade.ts index 89b5ecda22..6ffa18fe95 100644 --- a/src/lib/canister_methods/pre_upgrade.ts +++ b/src/lib/canister_methods/pre_upgrade.ts @@ -12,10 +12,10 @@ export function preUpgrade( return { mode: 'preUpgrade', callback: finalCallback, - paramsIdls: [], - returnIdl: Void, + paramCandidTypes: [], + returnCandidType: Void, async: isAsync(callback), guard: undefined - }; + } as CanisterMethodInfo<[], Void>; }) as any; } diff --git a/src/lib/canister_methods/query.ts b/src/lib/canister_methods/query.ts index 7461732590..d9a7947aac 100644 --- a/src/lib/canister_methods/query.ts +++ b/src/lib/canister_methods/query.ts @@ -13,8 +13,8 @@ export function query< Return extends CandidType, GenericCallback extends Callback >( - paramsIdls: Params, - returnIdl: Return, + paramCandidTypes: Params, + returnCandidType: Return, callback?: Awaited> extends TypeMapping ? GenericCallback : never, @@ -30,8 +30,8 @@ export function query< 'query', args, callback, - paramsIdls as any, - returnIdl, + paramCandidTypes as unknown as CandidType[], + returnCandidType, methodArgs?.manual ?? false, createParents(parent) ); @@ -40,10 +40,10 @@ export function query< return { mode: 'query', callback: finalCallback, - paramsIdls: paramsIdls as any, - returnIdl, + paramCandidTypes: paramCandidTypes as unknown as CandidType[], + returnCandidType, async: callback === undefined ? false : isAsync(callback), guard: methodArgs?.guard - }; + } as CanisterMethodInfo; }) as any; } diff --git a/src/lib/canister_methods/update.ts b/src/lib/canister_methods/update.ts index be352bda63..d02d74729b 100644 --- a/src/lib/canister_methods/update.ts +++ b/src/lib/canister_methods/update.ts @@ -29,7 +29,7 @@ export function update< 'update', args, callback, - paramCandidTypes as any, + paramCandidTypes as unknown as CandidType[], returnCandidType, methodArgs?.manual ?? false, createParents(parent) @@ -39,10 +39,10 @@ export function update< return { mode: 'update', callback: finalCallback, - paramsIdls: paramCandidTypes as any, - returnIdl: returnCandidType, + paramCandidTypes: paramCandidTypes as unknown as CandidType[], + returnCandidType, async: callback === undefined ? false : isAsync(callback), guard: methodArgs?.guard - }; + } as CanisterMethodInfo; }) as any; }