Skip to content

Commit

Permalink
feat: Add getRegistry (#647)
Browse files Browse the repository at this point in the history
### Description
This PR re-adds getRegistry, but with it exported from index-fs.ts and
removed from index.ts. The reason is that we cannot export functions
that use `fs` considering that the frontend cannot access this package.
Instead we must rely on tree-shaking via index-fs.ts

### Backward compatibility
Yes

### Testing
Tested with `yarn link`

---------

Co-authored-by: Morteza Shojaei <[email protected]>
  • Loading branch information
ltyu and mshojaei-txfusion authored Mar 6, 2025
1 parent dedd673 commit 6031ff9
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-dancers-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperlane-xyz/registry': minor
---

Add getRegistry function
1 change: 1 addition & 0 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export const WARP_ROUTE_CONFIG_FILE_REGEX = /warp_routes\/([a-zA-Z0-9]+)\/([a-z0
export const WARP_ROUTE_DEPLOY_FILE_REGEX = /warp_routes\/([a-zA-Z0-9]+)\/([a-z0-9-]+)-deploy.yaml/;

export const ABACUS_WORKS_DEPLOYER_NAME = 'Abacus Works';
export const PROXY_DEPLOYED_URL = 'https://proxy.hyperlane.xyz';
1 change: 1 addition & 0 deletions src/index-fs.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
// Exports for utilities that require fs access and are not suitable for browser use
export { FileSystemRegistry } from './registry/FileSystemRegistry.js';
export { getRegistry } from './registry/registry-utils.js';
50 changes: 50 additions & 0 deletions src/registry/registry-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Logger } from 'pino';
import { GithubRegistry } from './GithubRegistry.js';
import { FileSystemRegistry } from './FileSystemRegistry.js';
import { IRegistry } from './IRegistry.js';
import { DEFAULT_GITHUB_REGISTRY, PROXY_DEPLOYED_URL } from '../consts.js';
import { MergedRegistry } from './MergedRegistry.js';

const isHttpsUrl = (value: string): boolean => {
try {
if (!value) return false;
const url = new URL(value);
return url.protocol === 'https:';
} catch {
return false;
}
};

const isCanonicalRepoUrl = (url: string): boolean => {
return url === DEFAULT_GITHUB_REGISTRY;
};

export function getRegistry(
registryUris: string[],
enableProxy: boolean,
logger?: Logger,
): IRegistry {
const registryLogger = logger?.child({ module: 'MergedRegistry' });
const registries = registryUris
.map((uri) => uri.trim())
.filter((uri) => !!uri)
.map((uri, index) => {
const childLogger = registryLogger?.child({ uri, index });
if (isHttpsUrl(uri)) {
return new GithubRegistry({
uri,
logger: childLogger,
proxyUrl: enableProxy && isCanonicalRepoUrl(uri) ? PROXY_DEPLOYED_URL : undefined,
});
} else {
return new FileSystemRegistry({
uri,
logger: childLogger,
});
}
});
return new MergedRegistry({
registries,
logger,
});
}
108 changes: 108 additions & 0 deletions test/unit/registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { expect } from 'chai';
import sinon from 'sinon';

import type { ChainMetadata } from '@hyperlane-xyz/sdk';
import type { Logger } from 'pino';
import fs from 'fs';
import { CHAIN_FILE_REGEX } from '../../src/consts.js';
import { FileSystemRegistry } from '../../src/registry/FileSystemRegistry.js';
Expand All @@ -11,6 +12,8 @@ import { RegistryType } from '../../src/registry/IRegistry.js';
import { MergedRegistry } from '../../src/registry/MergedRegistry.js';
import { PartialRegistry } from '../../src/registry/PartialRegistry.js';
import { ChainAddresses } from '../../src/types.js';
import { getRegistry } from '../../src/registry/registry-utils.js';
import { DEFAULT_GITHUB_REGISTRY, PROXY_DEPLOYED_URL } from '../../src/consts.js';

const GITHUB_REGISTRY_BRANCH = 'main';

Expand Down Expand Up @@ -262,3 +265,108 @@ describe('Warp routes file structure', () => {
expect(foundPath, foundPath ? `Found addresses.yaml at: ${foundPath}` : '').to.be.null;
});
});

describe('Registry Utils', () => {
// Mock logger
const logger: Logger = {
child: () => ({ info: () => {}, child: () => ({ info: () => {} }) }),
} as any;

const localPath = './';
const githubUrl = 'https://github.com/hyperlane-xyz/hyperlane-registry';

describe('getRegistry', () => {
type TestCase = {
name: string;
uris: string[];
useProxy: boolean;
expectedRegistries: {
type: any;
uri: string;
proxyUrl?: string;
}[];
};

const testCases: TestCase[] = [
{
name: 'FileSystemRegistry for local path',
uris: [localPath],
useProxy: false,
expectedRegistries: [{ type: FileSystemRegistry, uri: localPath }],
},
{
name: 'GithubRegistry for HTTPS URLs',
uris: [githubUrl],
useProxy: false,
expectedRegistries: [{ type: GithubRegistry, uri: githubUrl }],
},
{
name: 'proxied GithubRegistry for canonical repo',
uris: [DEFAULT_GITHUB_REGISTRY],
useProxy: true,
expectedRegistries: [
{ type: GithubRegistry, uri: DEFAULT_GITHUB_REGISTRY, proxyUrl: PROXY_DEPLOYED_URL },
],
},
{
name: 'non-proxied GithubRegistry for non-canonical repos',
uris: ['https://github.com/test'],
useProxy: true,
expectedRegistries: [{ type: GithubRegistry, uri: 'https://github.com/test' }],
},
{
name: 'FileSystemRegistry for non-HTTPS URLs',
uris: ['local/path'],
useProxy: false,
expectedRegistries: [{ type: FileSystemRegistry, uri: 'local/path' }],
},
{
name: 'multiple URIs with mixed types',
uris: [githubUrl, localPath],
useProxy: false,
expectedRegistries: [
{ type: GithubRegistry, uri: githubUrl },
{ type: FileSystemRegistry, uri: localPath },
],
},
{
name: 'mixed registry types with proxy settings',
uris: [DEFAULT_GITHUB_REGISTRY, localPath, 'https://github.com/test'],
useProxy: true,
expectedRegistries: [
{ type: GithubRegistry, uri: DEFAULT_GITHUB_REGISTRY, proxyUrl: PROXY_DEPLOYED_URL },
{ type: FileSystemRegistry, uri: localPath },
{ type: GithubRegistry, uri: 'https://github.com/test' },
],
},
];

testCases.forEach(({ name, uris, useProxy, expectedRegistries }) => {
it(name, () => {
const registry = getRegistry(uris, useProxy, logger) as MergedRegistry;
expect(registry).to.be.instanceOf(MergedRegistry);
expect(registry.registries.length).to.equal(expectedRegistries.length);

registry.registries.forEach((reg, idx) => {
const expected = expectedRegistries[idx];
expect(reg).to.be.instanceOf(expected.type);
expect(reg.uri).to.equal(expected.uri);
if (reg instanceof GithubRegistry) {
expect(reg.proxyUrl).to.equal(expected.proxyUrl);
}
expect(reg).to.have.property('logger');
});
});
});

it('throws error for empty URIs array', () => {
expect(() => getRegistry([], true, logger)).to.throw('At least one registry URI is required');
expect(() => getRegistry([''], true, logger)).to.throw(
'At least one registry URI is required',
);
expect(() => getRegistry([' '], true, logger)).to.throw(
'At least one registry URI is required',
);
});
});
});

0 comments on commit 6031ff9

Please sign in to comment.