-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #160 from subquery/add/proto-ts-codegen
Support for cosmos codegen
- Loading branch information
Showing
21 changed files
with
3,205 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ | |
packages/**/dist/** | ||
packages/**/lib/** | ||
.eslintrc.js | ||
*.proto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ | |
*.tgz | ||
*.cmd | ||
*.sh | ||
*.proto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
packages/common-cosmos/src/codegen/codegen-controller.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import path from 'path'; | ||
import {loadFromJsonOrYaml} from '@subql/common'; | ||
import {isProtoPath, prepareProtobufRenderProps, processProtoFilePath} from './codegen-controller'; | ||
import {validateCosmosManifest} from './util'; | ||
|
||
const PROJECT_PATH = path.join(__dirname, '../../test/protoTest1'); | ||
|
||
describe('Codegen cosmos, protobuf to ts', () => { | ||
it('process protobuf file paths', () => { | ||
const p = './proto/cosmos/osmosis/poolmanager/v1beta1/swap_route.proto'; | ||
expect(processProtoFilePath(p)).toBe('./proto-interfaces/cosmos/osmosis/poolmanager/v1beta1/swap_route'); | ||
}); | ||
it('should output correct protobuf render props', () => { | ||
const mockChainTypes = [ | ||
{ | ||
'osmosis.gamm.v1beta1': { | ||
file: './proto/osmosis/gamm/v1beta1/tx.proto', | ||
messages: ['MsgSwapExactAmountIn'], | ||
}, | ||
}, | ||
{ | ||
'osmosis.poolmanager.v1beta1': { | ||
file: './proto/osmosis/poolmanager/v1beta1/swap_route.proto', | ||
messages: ['SwapAmountInRoute'], | ||
}, | ||
}, | ||
]; | ||
expect(prepareProtobufRenderProps(mockChainTypes, PROJECT_PATH)).toStrictEqual([ | ||
{ | ||
messageNames: ['MsgSwapExactAmountIn'], | ||
path: './proto-interfaces/osmosis/gamm/v1beta1/tx', | ||
}, | ||
{ | ||
messageNames: ['SwapAmountInRoute'], | ||
path: './proto-interfaces/osmosis/poolmanager/v1beta1/swap_route', | ||
}, | ||
]); | ||
}); | ||
it('Should throw if path to protobuf does not exist', () => { | ||
const mockChainTypes = [ | ||
{ | ||
'osmosis.gamm.v1beta1': { | ||
file: './protato/osmosis/gamm/v1beta1/tx.proto', | ||
messages: ['MsgSwapExactAmountIn'], | ||
}, | ||
}, | ||
]; | ||
expect(() => prepareProtobufRenderProps(mockChainTypes, PROJECT_PATH)).toThrow( | ||
'Error: chainType osmosis.gamm.v1beta1, file ./protato/osmosis/gamm/v1beta1/tx.proto does not exist' | ||
); | ||
}); | ||
it('ensure correct regex for protoPath', () => { | ||
let p = './proto/cosmos/osmosis/gamm/v1beta1/tx.proto'; | ||
expect(isProtoPath(p, PROJECT_PATH)).toBe(true); | ||
p = 'proto/cosmos/osmosis/gamm/v1beta1/tx.proto'; | ||
expect(isProtoPath(p, PROJECT_PATH)).toBe(true); | ||
p = '../proto/cosmos/osmosis/gamm/v1beta1/tx.proto'; | ||
expect(isProtoPath(p, PROJECT_PATH)).toBe(false); | ||
p = './protos/cosmos/osmosis/gamm/v1beta1/tx.proto'; | ||
expect(isProtoPath(p, PROJECT_PATH)).toBe(false); | ||
}); | ||
it('Ensure correctness on Cosmos Manifest validate', () => { | ||
const cosmosManifest = loadFromJsonOrYaml(path.join(PROJECT_PATH, 'project.yaml')) as any; | ||
const ethManifest = loadFromJsonOrYaml(path.join(PROJECT_PATH, 'bad-cosmos-project.yaml')) as any; | ||
expect(validateCosmosManifest(cosmosManifest)).toBe(true); | ||
expect(validateCosmosManifest(ethManifest)).toBe(false); | ||
}); | ||
}); |
118 changes: 118 additions & 0 deletions
118
packages/common-cosmos/src/codegen/codegen-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import fs from 'fs'; | ||
import path from 'path'; | ||
import telescope from '@cosmology/telescope'; | ||
import {makeTempDir} from '@subql/common'; | ||
import {CustomModule} from '@subql/types-cosmos'; | ||
import {Data} from 'ejs'; | ||
import {copySync} from 'fs-extra'; | ||
import {TELESCOPE_OPTS} from './constants'; | ||
|
||
const PROTO_INTERFACES_ROOT_DIR = 'src/types/proto-interfaces'; | ||
const PROTO_INTERFACE_TEMPLATE_PATH = path.resolve(__dirname, './templates/proto-interface.ts.ejs'); | ||
const TYPE_ROOT_DIR = 'src/types'; | ||
|
||
interface ProtobufRenderProps { | ||
messageNames: string[]; // all messages | ||
path: string; // should process the file Path and concat with PROTO dir | ||
} | ||
type CosmosChainTypeDataType = Map<string, CustomModule> | Record<string, CustomModule>; | ||
|
||
export function processProtoFilePath(path: string): string { | ||
// removes `./proto` and `.proto` suffix, converts all `.` to `/` | ||
// should be able to accept more paths, not just from `proto directory` | ||
return `./proto-interfaces/${path.replace(/^\.\/proto\/|\.proto$/g, '').replace(/\./g, '/')}`; | ||
} | ||
|
||
export function isProtoPath(filePath: string, projectPath: string): boolean { | ||
// check if the protobuf files are under ./proto directory | ||
return !!path.join(projectPath, filePath).startsWith(path.join(projectPath, './proto/')); | ||
} | ||
|
||
export function prepareProtobufRenderProps( | ||
chainTypes: CosmosChainTypeDataType[], | ||
projectPath: string | ||
): ProtobufRenderProps[] { | ||
return chainTypes.flatMap((chainType) => { | ||
return Object.entries(chainType).map(([key, value]) => { | ||
const filePath = path.join(projectPath, value.file); | ||
if (!fs.existsSync(filePath)) { | ||
throw new Error(`Error: chainType ${key}, file ${value.file} does not exist`); | ||
} | ||
if (!isProtoPath(value.file, projectPath)) { | ||
console.error( | ||
`Codegen will not apply for this file: ${value.file} Please ensure it is under the ./proto directory if you want to run codegen on it` | ||
); | ||
} | ||
return { | ||
messageNames: value.messages, | ||
path: processProtoFilePath(value.file), | ||
}; | ||
}); | ||
}); | ||
} | ||
|
||
export async function tempProtoDir(projectPath: string): Promise<string> { | ||
const tmpDir = await makeTempDir(); | ||
const userProto = path.join(projectPath, './proto'); | ||
const commonProtoPaths = [ | ||
require('@protobufs/amino'), | ||
require('@protobufs/confio'), | ||
require('@protobufs/cosmos'), | ||
require('@protobufs/cosmos_proto'), | ||
require('@protobufs/gogoproto'), | ||
require('@protobufs/google'), | ||
require('@protobufs/ibc'), | ||
require('@protobufs/tendermint'), | ||
]; | ||
|
||
commonProtoPaths.forEach((p) => { | ||
// ensure output format is a dir | ||
copySync(p, path.join(tmpDir, `${p.replace(path.dirname(p), '')}`)); | ||
}); | ||
copySync(userProto, tmpDir, {overwrite: true}); | ||
return tmpDir; | ||
} | ||
|
||
export async function generateProto( | ||
chainTypes: CosmosChainTypeDataType[], | ||
projectPath: string, | ||
prepareDirPath: (path: string, recreate: boolean) => Promise<void>, | ||
renderTemplate: (templatePath: string, outputPath: string, templateData: Data) => Promise<void>, | ||
upperFirst: (string?: string) => string, | ||
mkdirProto: (projectPath: string) => Promise<string> | ||
): Promise<void> { | ||
let tmpPath: string; | ||
try { | ||
tmpPath = await mkdirProto(projectPath); | ||
const protobufRenderProps = prepareProtobufRenderProps(chainTypes, projectPath); | ||
const outputPath = path.join(projectPath, PROTO_INTERFACES_ROOT_DIR); | ||
await prepareDirPath(path.join(projectPath, PROTO_INTERFACES_ROOT_DIR), true); | ||
|
||
await telescope({ | ||
protoDirs: [tmpPath], | ||
outPath: outputPath, | ||
options: TELESCOPE_OPTS, | ||
}); | ||
console.log('* Protobuf types generated !'); | ||
|
||
await renderTemplate( | ||
PROTO_INTERFACE_TEMPLATE_PATH, | ||
path.join(projectPath, TYPE_ROOT_DIR, 'CosmosMessageTypes.ts'), | ||
{ | ||
props: {proto: protobufRenderProps}, | ||
helper: {upperFirst}, | ||
} | ||
); | ||
console.log('* Cosmos message wrappers generated !'); | ||
} catch (e: any) { | ||
const errorMessage = e.message.startsWith('Dependency') | ||
? `Please add the missing protobuf file to ./proto directory` | ||
: ''; | ||
throw new Error(`Failed to generate from protobufs. ${e.message}, ${errorMessage}`); | ||
} finally { | ||
fs.rmSync(tmpPath, {recursive: true, force: true}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import {TelescopeOptions} from '@cosmology/types/types/telescope'; | ||
|
||
export const TELESCOPE_OPTS: TelescopeOptions = { | ||
removeUnusedImports: true, | ||
tsDisable: { | ||
patterns: ['**/*amino.ts', '**/*registry.ts'], | ||
}, | ||
// experimentalGlobalProtoNamespace: true, // [ 'v1beta1' ] concentratedliquidity | ||
interfaces: { | ||
enabled: true, | ||
useUnionTypes: false, | ||
}, | ||
prototypes: { | ||
enabled: false, | ||
addTypeUrlToDecoders: true, | ||
addTypeUrlToObjects: true, | ||
excluded: { | ||
packages: [ | ||
'amino', | ||
'gogoproto', | ||
// 'google.api', | ||
// 'ibc.core.port.v1', | ||
// 'ibc.core.types.v1', | ||
], | ||
}, | ||
methods: { | ||
fromJSON: false, | ||
toJSON: false, | ||
|
||
encode: false, | ||
decode: false, | ||
fromPartial: false, | ||
|
||
toSDK: false, | ||
fromSDK: false, | ||
|
||
toAmino: false, | ||
fromAmino: false, | ||
fromProto: false, | ||
toProto: false, | ||
}, | ||
parser: { | ||
keepCase: false, | ||
}, | ||
typingsFormat: { | ||
duration: 'duration', | ||
timestamp: 'date', | ||
useExact: false, | ||
useDeepPartial: false, | ||
}, | ||
}, | ||
aminoEncoding: { | ||
enabled: false, | ||
exceptions: {}, | ||
useRecursiveV2encoding: true, | ||
}, | ||
lcdClients: { | ||
enabled: false, | ||
}, | ||
rpcClients: { | ||
// unsure if needed | ||
enabled: false, | ||
camelCase: true, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
export * from './codegen-controller'; | ||
export * from './util'; |
10 changes: 10 additions & 0 deletions
10
packages/common-cosmos/src/codegen/templates/proto-interface.ts.ejs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// Auto-generated , DO NOT EDIT | ||
import {CosmosMessage} from "@subql/types-cosmos"; | ||
<% props.proto.forEach(function(proto) { %> | ||
import {<% proto.messageNames.forEach(function(msg, index) { %><%= helper.upperFirst(msg) %><% if (index < proto.messageNames.length - 1) { %>,<% } %><% }); %>} from "<%= proto.path %>"; | ||
<% }); %> | ||
<% props.proto.forEach(function(proto) { %><% proto.messageNames.forEach(function(msg) { %> | ||
export type <%= helper.upperFirst(msg) %>Message = CosmosMessage<<%= helper.upperFirst(msg) %>>;<% }); %> | ||
<% }); %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import {parseCosmosProjectManifest} from '../project/load'; | ||
|
||
export function validateCosmosManifest(manifest: { | ||
network: {chainTypes?: Map<string, {file: string; messages: string[]}>}; | ||
}): boolean { | ||
try { | ||
return !!parseCosmosProjectManifest(manifest); | ||
} catch (e) { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
export * from './codegen'; | ||
export * from './project'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.