-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: local file metadata provider (#56)
# 🤖 Linear Closes ZKS-221 ## Description - Add `LocalFileMetadataProvider` - Add `Cache` to `GithubMetadataProvider`
- Loading branch information
Showing
11 changed files
with
467 additions
and
43 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 @@ | ||
export class FileNotFound extends Error { | ||
constructor(path: string) { | ||
super(`File not found at path: ${path}`); | ||
} | ||
} |
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,2 +1,3 @@ | ||
export * from "./invalidSchema.exception.js"; | ||
export * from "./fetchError.exception.js"; | ||
export * from "./fileNotFound.exception.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
export type { IMetadataProvider } from "./internal.js"; | ||
|
||
export { InvalidSchema, FetchError } from "./internal.js"; | ||
export { InvalidSchema, FetchError, FileNotFound } from "./internal.js"; | ||
|
||
export { StaticMetadataProvider, GithubMetadataProvider } from "./internal.js"; | ||
export { | ||
StaticMetadataProvider, | ||
GithubMetadataProvider, | ||
LocalFileMetadataProvider, | ||
} from "./internal.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,30 @@ | ||
import { Token, TokenType, ZKChainMetadata } from "@zkchainhub/shared"; | ||
|
||
/** | ||
* Represents a metadata provider that retrieves chains and tokens metadata. | ||
*/ | ||
export interface IMetadataProvider { | ||
/** | ||
* Retrieves the metadata for ZK chains of the ecosystem | ||
* | ||
* @returns A promise that resolves to the metadata of ZK chains. | ||
* | ||
* @throws {FetchError} | ||
* If there is an issue with the network request. | ||
* | ||
* | ||
* @throws {InvalidSchema} | ||
* If the response data is invalid or cannot be parsed. | ||
*/ | ||
getChainsMetadata(): Promise<ZKChainMetadata>; | ||
|
||
/** | ||
* Retrieves metadata for tokens of the ecosystem | ||
* | ||
* @returns A promise that resolves to an array of token metadata. | ||
* | ||
* @throws {FetchError} If there is an issue with the network request. | ||
* @throws {InvalidSchema} If the response data is invalid or cannot be parsed. | ||
*/ | ||
getTokensMetadata(): Promise<Token<TokenType>[]>; | ||
} |
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 |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./githubMetadata.provider.js"; | ||
export * from "./staticMetadata.provider.js"; | ||
export * from "./localFileMetadata.provider.js"; |
91 changes: 91 additions & 0 deletions
91
packages/metadata/src/providers/localFileMetadata.provider.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,91 @@ | ||
import { existsSync, readFileSync } from "fs"; | ||
import { z } from "zod"; | ||
|
||
import { | ||
ILogger, | ||
Token, | ||
TokenType, | ||
ZKChainMetadata, | ||
ZKChainMetadataItem, | ||
} from "@zkchainhub/shared"; | ||
|
||
import { FileNotFound, IMetadataProvider, InvalidSchema } from "../internal.js"; | ||
import { ChainSchema, TokenSchema } from "../schemas/index.js"; | ||
|
||
export const LOCALFILE_METADATA_PREFIX = "local-metadata"; | ||
|
||
/** | ||
* Represents a provider that retrieves metadata from local files. | ||
* Note: Files are read only once and saved to instance variables. | ||
*/ | ||
export class LocalFileMetadataProvider implements IMetadataProvider { | ||
private readonly chainMetadata: ZKChainMetadata; | ||
private readonly tokenMetadata: Token<TokenType>[]; | ||
|
||
/** | ||
* Constructs a new instance of the LocalFileMetadataProvider class. | ||
* @param tokenJsonPath The path to the token JSON file. | ||
* @param chainJsonPath The path to the chain JSON file. | ||
* @param logger The logger instance. | ||
* @throws {FileNotFound} if any of the files is not found. | ||
*/ | ||
constructor( | ||
private readonly tokenJsonPath: string, | ||
private readonly chainJsonPath: string, | ||
private readonly logger: ILogger, | ||
) { | ||
if (!existsSync(tokenJsonPath)) { | ||
throw new FileNotFound(tokenJsonPath); | ||
} | ||
|
||
if (!existsSync(chainJsonPath)) { | ||
throw new FileNotFound(chainJsonPath); | ||
} | ||
|
||
this.tokenMetadata = this.readAndParseTokenMetadata(); | ||
this.chainMetadata = this.readAndParseChainMetadata(); | ||
} | ||
|
||
/** @inheritdoc */ | ||
async getChainsMetadata(): Promise<ZKChainMetadata> { | ||
return Promise.resolve(this.chainMetadata); | ||
} | ||
|
||
readAndParseChainMetadata() { | ||
const jsonData = readFileSync(this.chainJsonPath, "utf-8"); | ||
const parsed = JSON.parse(jsonData); | ||
|
||
const validatedData = z.array(ChainSchema).safeParse(parsed); | ||
|
||
if (!validatedData.success) { | ||
this.logger.error(`Invalid ZKChains metadata: ${validatedData.error.errors}`); | ||
throw new InvalidSchema("Invalid ZKChains metadata"); | ||
} | ||
|
||
return validatedData.data.reduce((acc, chain) => { | ||
const { chainId, ...rest } = chain; | ||
const chainIdBn = BigInt(chainId); | ||
acc.set(chainIdBn, { ...rest, chainId: chainIdBn }); | ||
return acc; | ||
}, new Map<bigint, ZKChainMetadataItem>()); | ||
} | ||
|
||
/** @inheritdoc */ | ||
async getTokensMetadata(): Promise<Token<TokenType>[]> { | ||
return Promise.resolve(this.tokenMetadata); | ||
} | ||
|
||
readAndParseTokenMetadata() { | ||
const jsonData = readFileSync(this.tokenJsonPath, "utf-8"); | ||
const parsed = JSON.parse(jsonData); | ||
|
||
const validatedData = z.array(TokenSchema).safeParse(parsed); | ||
|
||
if (!validatedData.success) { | ||
this.logger.error(`Invalid Tokens metadata: ${validatedData.error.errors}`); | ||
throw new InvalidSchema("Invalid Tokens metadata"); | ||
} | ||
|
||
return validatedData.data; | ||
} | ||
} |
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
Oops, something went wrong.