-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement LocalRegistry and setup ESlint (#13)
- Create new LocalRegistry class - Add new export entry for local-related things - Refactor unit tests to cover both registry types - Setup ESLint 9
- Loading branch information
Showing
18 changed files
with
953 additions
and
102 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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@hyperlane-xyz/registry': patch | ||
--- | ||
|
||
Create LocalRegistry class |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"eslint.experimental.useFlatConfig": 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,38 @@ | ||
import eslint from '@eslint/js'; | ||
import tseslint from 'typescript-eslint'; | ||
import tsparser from '@typescript-eslint/parser'; | ||
|
||
export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommended, { | ||
files: ['src/**/*.ts'], | ||
languageOptions: { | ||
parser: tsparser, | ||
parserOptions: { | ||
ecmaVersion: 2022, | ||
sourceType: 'module', | ||
project: './tsconfig.json', | ||
}, | ||
}, | ||
rules: { | ||
'no-console': ['error'], | ||
'no-eval': ['error'], | ||
'no-extra-boolean-cast': ['error'], | ||
'no-ex-assign': ['error'], | ||
'no-constant-condition': ['off'], | ||
'guard-for-in': ['error'], | ||
'@typescript-eslint/ban-ts-comment': ['off'], | ||
'@typescript-eslint/explicit-module-boundary-types': ['off'], | ||
'@typescript-eslint/no-explicit-any': ['off'], | ||
'@typescript-eslint/no-floating-promises': ['error'], | ||
'@typescript-eslint/no-non-null-assertion': ['off'], | ||
'@typescript-eslint/no-require-imports': ['warn'], | ||
'@typescript-eslint/no-unused-vars': [ | ||
'error', | ||
{ | ||
argsIgnorePattern: '^_', | ||
varsIgnorePattern: '^_', | ||
caughtErrorsIgnorePattern: '^_', | ||
}, | ||
], | ||
}, | ||
ignores: ['node_modules', 'dist', 'tmp'], | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Exports for utilities that require fs access and are not suitable for browser use | ||
export { LocalRegistry } from './registry/LocalRegistry.js'; |
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
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
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,102 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import type { Logger } from 'pino'; | ||
import { parse as yamlParse } from 'yaml'; | ||
|
||
import { type ChainMap, type ChainMetadata, type ChainName } from '@hyperlane-xyz/sdk'; | ||
|
||
import { ChainAddresses, ChainAddressesSchema } from '../types.js'; | ||
import { BaseRegistry, CHAIN_FILE_REGEX } from './BaseRegistry.js'; | ||
import { | ||
RegistryType, | ||
type ChainFiles, | ||
type IRegistry, | ||
type RegistryContent, | ||
} from './IRegistry.js'; | ||
|
||
export interface LocalRegistryOptions { | ||
uri: string; | ||
logger?: Logger; | ||
} | ||
|
||
export class LocalRegistry extends BaseRegistry implements IRegistry { | ||
public readonly type = RegistryType.Local; | ||
public readonly uri: string; | ||
|
||
constructor(options: LocalRegistryOptions) { | ||
super({ logger: options.logger }); | ||
this.uri = options.uri; | ||
} | ||
|
||
listRegistryContent(): RegistryContent { | ||
if (this.listContentCache) return this.listContentCache; | ||
|
||
const chainFileList = this.listFiles(path.join(this.uri, this.getChainsPath())); | ||
const chains: ChainMap<ChainFiles> = {}; | ||
for (const chainFilePath of chainFileList) { | ||
const matches = chainFilePath.match(CHAIN_FILE_REGEX); | ||
if (!matches) continue; | ||
const [_, chainName, fileName] = matches; | ||
chains[chainName] ??= {}; | ||
// @ts-ignore allow dynamic key assignment | ||
chains[chainName][fileName] = chainFilePath; | ||
} | ||
|
||
// TODO add handling for deployment artifact files here too | ||
|
||
return (this.listContentCache = { chains, deployments: {} }); | ||
} | ||
|
||
getChains(): Array<ChainName> { | ||
return Object.keys(this.listRegistryContent().chains); | ||
} | ||
|
||
getMetadata(): ChainMap<ChainMetadata> { | ||
if (this.metadataCache) return this.metadataCache; | ||
const chainMetadata: ChainMap<ChainMetadata> = {}; | ||
const repoContents = this.listRegistryContent(); | ||
for (const [chainName, chainFiles] of Object.entries(repoContents.chains)) { | ||
if (!chainFiles.metadata) continue; | ||
const data = fs.readFileSync(chainFiles.metadata, 'utf8'); | ||
chainMetadata[chainName] = yamlParse(data); | ||
} | ||
return (this.metadataCache = chainMetadata); | ||
} | ||
|
||
getChainMetadata(chainName: ChainName): ChainMetadata { | ||
const metadata = this.getMetadata(); | ||
if (!metadata[chainName]) | ||
throw new Error(`Metadata not found in registry for chain: ${chainName}`); | ||
return metadata[chainName]; | ||
} | ||
|
||
getAddresses(): ChainMap<ChainAddresses> { | ||
if (this.addressCache) return this.addressCache; | ||
const chainAddresses: ChainMap<ChainAddresses> = {}; | ||
const repoContents = this.listRegistryContent(); | ||
for (const [chainName, chainFiles] of Object.entries(repoContents.chains)) { | ||
if (!chainFiles.addresses) continue; | ||
const data = fs.readFileSync(chainFiles.addresses, 'utf8'); | ||
chainAddresses[chainName] = ChainAddressesSchema.parse(yamlParse(data)); | ||
} | ||
return (this.addressCache = chainAddresses); | ||
} | ||
|
||
getChainAddresses(chainName: ChainName): ChainAddresses { | ||
const addresses = this.getAddresses(); | ||
if (!addresses[chainName]) | ||
throw new Error(`Addresses not found in registry for chain: ${chainName}`); | ||
return addresses[chainName]; | ||
} | ||
|
||
protected listFiles(dirPath: string): string[] { | ||
const entries = fs.readdirSync(dirPath, { withFileTypes: true }); | ||
|
||
const filePaths = entries.map((entry) => { | ||
const fullPath = path.join(dirPath, entry.name); | ||
return entry.isDirectory() ? this.listFiles(fullPath) : fullPath; | ||
}); | ||
|
||
return filePaths.flat(); | ||
} | ||
} |
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,7 @@ | ||
import { z } from 'zod'; | ||
|
||
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#the-awaited-type-and-promise-improvements | ||
export type MaybePromise<T> = T | Promise<T> | PromiseLike<T>; | ||
|
||
export const ChainAddressesSchema = z.record(z.string()); | ||
export type ChainAddresses = z.infer<typeof ChainAddressesSchema>; |
Oops, something went wrong.