From 6c82c00393731668c195ded874891c25cd130015 Mon Sep 17 00:00:00 2001 From: ncomerci Date: Fri, 9 Jan 2026 12:36:33 -0300 Subject: [PATCH 1/6] CLI: Introduce lib-runner mapping --- packages/cli/lib-runner-mapping.yaml | 15 +++++++++++ packages/cli/package.json | 5 +++- packages/cli/src/lib/ManifestHandler.ts | 31 ++++++++++++++++++++-- packages/cli/src/types.ts | 3 ++- packages/cli/src/validators.ts | 12 +++++++-- packages/cli/tests/ManifestHandler.spec.ts | 20 +++++++------- yarn.lock | 5 ++++ 7 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 packages/cli/lib-runner-mapping.yaml diff --git a/packages/cli/lib-runner-mapping.yaml b/packages/cli/lib-runner-mapping.yaml new file mode 100644 index 00000000..ffca8faf --- /dev/null +++ b/packages/cli/lib-runner-mapping.yaml @@ -0,0 +1,15 @@ +# Mapping between @mimicprotocol/lib-ts versions and runner versions +# Only add new entries when there are breaking changes between lib-ts and runner +# +# Format: +# - libVersionRange: semver range (e.g., ">=0.0.1-rc.1 <0.1.0") +# runnerVersion: semver version (e.g., "1.0.0") +# +# Example with multiple entries: +# - libVersionRange: ">=0.0.1-rc.1 <0.1.0" +# runnerVersion: "1.0.0" +# - libVersionRange: ">=0.1.0" +# runnerVersion: "2.0.0" + +- libVersionRange: ">=0.0.1-rc.1" + runnerVersion: "1.0.0" diff --git a/packages/cli/package.json b/packages/cli/package.json index 61e71038..a56f8231 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -16,7 +16,8 @@ }, "files": [ "dist", - "bin" + "bin", + "lib-runner-mapping.yaml" ], "dependencies": { "@inquirer/prompts": "^7.2.4", @@ -28,6 +29,7 @@ "form-data": "^4.0.1", "js-yaml": "^4.1.0", "lodash": "^4.17.21", + "semver": "^7.6.3", "simple-git": "^3.30.0", "zod": "^3.24.1" }, @@ -40,6 +42,7 @@ "@types/lodash": "^4.17.15", "@types/mocha": "^10.0.1", "@types/node": "^22.10.5", + "@types/semver": "^7.5.8", "axios-mock-adapter": "^2.1.0", "chai": "^4.3.7", "eslint-config-mimic": "^0.0.3", diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index 8ebf4d93..12050948 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -2,11 +2,12 @@ import { Command } from '@oclif/core' import * as fs from 'fs' import { load } from 'js-yaml' import * as path from 'path' +import * as semver from 'semver' import { ZodError } from 'zod' import { DuplicateEntryError, EmptyManifestError, MoreThanOneEntryError } from '../errors' import { Manifest } from '../types' -import { ManifestValidator } from '../validators' +import { LibRunnerMappingValidator, ManifestValidator } from '../validators' export default { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -17,7 +18,7 @@ export default { ...manifest, inputs: mergeIfUnique(manifest.inputs), abis: mergeIfUnique(manifest.abis), - metadata: { libVersion: getLibVersion() }, + metadata: { runnerVersion: getRunnerVersion(getLibVersion()) }, } return ManifestValidator.parse(mergedManifest) }, @@ -94,3 +95,29 @@ function getLibVersion(): string { throw new Error(`Failed to read @mimicprotocol/lib-ts version: ${error}`) } } + +function getRunnerVersion(libVersion: string): string { + try { + let currentDir = process.cwd() + while (currentDir !== path.dirname(currentDir)) { + const mappingPath = path.join(currentDir, 'lib-runner-mapping.yaml') + if (fs.existsSync(mappingPath)) { + const mappingContent = fs.readFileSync(mappingPath, 'utf-8') + const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) + + for (const entry of mapping) { + if (semver.satisfies(libVersion, entry.libVersionRange)) { + return entry.runnerVersion + } + } + + throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) + } + currentDir = path.dirname(currentDir) + } + + throw new Error('Could not find lib-runner-mapping.yaml') + } catch (error) { + throw new Error(`Failed to read lib-runner-mapping.yaml: ${error}`) + } +} diff --git a/packages/cli/src/types.ts b/packages/cli/src/types.ts index e710ac0a..1447841d 100644 --- a/packages/cli/src/types.ts +++ b/packages/cli/src/types.ts @@ -1,9 +1,10 @@ import { z } from 'zod' -import { ManifestValidator } from './validators' +import { LibRunnerMappingValidator, ManifestValidator } from './validators' export type Manifest = z.infer export type ManifestInputs = z.infer +export type LibRunnerMapping = z.infer export type AbiParameter = { name?: string diff --git a/packages/cli/src/validators.ts b/packages/cli/src/validators.ts index bcf24259..23d0f257 100644 --- a/packages/cli/src/validators.ts +++ b/packages/cli/src/validators.ts @@ -9,6 +9,7 @@ export const SEM_VER_REGEX = const String = z.string().min(1) +const SemVer = String.regex(SEM_VER_REGEX, 'Must be a valid semver') const SolidityType = String.regex(SOLIDITY_TYPE_REGEX, 'Must be a valid solidity type') const TokenType = String.regex(TOKEN_TYPE_REGEX, 'Must be a valid token type') const InputType = z.union([SolidityType, TokenType]) @@ -16,12 +17,19 @@ const InputType = z.union([SolidityType, TokenType]) const InputValue = z.union([InputType, z.object({ type: InputType, description: String.optional() })]) export const ManifestValidator = z.object({ - version: String.regex(SEM_VER_REGEX, 'Must be a valid semver'), + version: SemVer, name: String, description: String, inputs: z.record(String, InputValue), abis: z.record(String, String), metadata: z.object({ - libVersion: String.regex(SEM_VER_REGEX, 'Must be a valid semver'), + runnerVersion: SemVer, }), }) + +export const LibRunnerMappingValidator = z.array( + z.object({ + libVersionRange: String, + runnerVersion: SemVer, + }) +) diff --git a/packages/cli/tests/ManifestHandler.spec.ts b/packages/cli/tests/ManifestHandler.spec.ts index 4847fbad..3aa2f324 100644 --- a/packages/cli/tests/ManifestHandler.spec.ts +++ b/packages/cli/tests/ManifestHandler.spec.ts @@ -71,22 +71,22 @@ describe('ManifestHandler', () => { }) }) - context('when dealing with lib version', () => { - context('when the lib version is not present', () => { - it('adds the lib version to the manifest', () => { + context('when dealing with runner version', () => { + context('when the runner version is not present', () => { + it('adds the runner version to the manifest', () => { const parsedManifest = ManifestHandler.validate(manifest) - expect(parsedManifest.metadata.libVersion).to.match(SEM_VER_REGEX) + expect(parsedManifest.metadata.runnerVersion).to.match(SEM_VER_REGEX) }) }) - context('when the lib version is present', () => { - it('overrides the lib version', () => { - const libVersion = '999.9.9' - const manifestWithLibVersion = { ...manifest, metadata: { libVersion } } - const parsedManifest = ManifestHandler.validate(manifestWithLibVersion) + context('when the runner version is present', () => { + it('overrides the runner version', () => { + const runnerVersion = '999.9.9' + const manifestWithRunnerVersion = { ...manifest, metadata: { runnerVersion } } + const parsedManifest = ManifestHandler.validate(manifestWithRunnerVersion) - expect(parsedManifest.metadata.libVersion).to.not.equal(libVersion) + expect(parsedManifest.metadata.runnerVersion).to.not.equal(runnerVersion) }) }) }) diff --git a/yarn.lock b/yarn.lock index a3c31e0c..b70ee462 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1055,6 +1055,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.0.tgz#64c441bdae033b378b6eef7d0c3d77c329b9378e" integrity sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA== +"@types/semver@^7.5.8": + version "7.7.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" + integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== + "@types/send@*": version "0.17.5" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.5.tgz#d991d4f2b16f2b1ef497131f00a9114290791e74" From c62c94f3ef1d001faa815601ee5d40f3807d5660 Mon Sep 17 00:00:00 2001 From: ncomerci Date: Fri, 9 Jan 2026 13:17:17 -0300 Subject: [PATCH 2/6] refactor: getRunnerVersion function for improved path handling --- packages/cli/package.json | 2 +- packages/cli/src/lib/ManifestHandler.ts | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index a56f8231..65581324 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -9,7 +9,7 @@ }, "scripts": { "prepare": "yarn build", - "build": "rm -rf dist && tsc", + "build": "rm -rf dist && tsc && cp lib-runner-mapping.yaml dist/lib-runner-mapping.yaml", "start": "yarn build && node ./bin/run.js", "test": "yarn build && ts-mocha ./tests --recursive --extension .spec.ts --exit --timeout 5000", "lint": "eslint ." diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index 12050948..7263b1eb 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -98,25 +98,18 @@ function getLibVersion(): string { function getRunnerVersion(libVersion: string): string { try { - let currentDir = process.cwd() - while (currentDir !== path.dirname(currentDir)) { - const mappingPath = path.join(currentDir, 'lib-runner-mapping.yaml') - if (fs.existsSync(mappingPath)) { - const mappingContent = fs.readFileSync(mappingPath, 'utf-8') - const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) + let mappingPath = path.join(__dirname, '..', 'lib-runner-mapping.yaml') - for (const entry of mapping) { - if (semver.satisfies(libVersion, entry.libVersionRange)) { - return entry.runnerVersion - } - } + const mappingContent = fs.readFileSync(mappingPath, 'utf-8') + const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) - throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) + for (const entry of mapping) { + if (semver.satisfies(libVersion, entry.libVersionRange)) { + return entry.runnerVersion } - currentDir = path.dirname(currentDir) } - throw new Error('Could not find lib-runner-mapping.yaml') + throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) } catch (error) { throw new Error(`Failed to read lib-runner-mapping.yaml: ${error}`) } From 253df76c593cf5ccbe43c7e33dabd54130875952 Mon Sep 17 00:00:00 2001 From: ncomerci Date: Fri, 9 Jan 2026 14:21:26 -0300 Subject: [PATCH 3/6] test: added test cases --- packages/cli/package.json | 5 +- .../cli/{ => src}/lib-runner-mapping.yaml | 0 packages/cli/src/lib/ManifestHandler.ts | 9 +- packages/cli/tests/ManifestHandler.spec.ts | 94 ++++++++++++++++++- .../lib-runner-mappings/invalid-mapping.yaml | 3 + .../lib-runner-mappings/multiple-ranges.yaml | 7 ++ .../lib-runner-mappings/single-range.yaml | 3 + 7 files changed, 114 insertions(+), 7 deletions(-) rename packages/cli/{ => src}/lib-runner-mapping.yaml (100%) create mode 100644 packages/cli/tests/fixtures/lib-runner-mappings/invalid-mapping.yaml create mode 100644 packages/cli/tests/fixtures/lib-runner-mappings/multiple-ranges.yaml create mode 100644 packages/cli/tests/fixtures/lib-runner-mappings/single-range.yaml diff --git a/packages/cli/package.json b/packages/cli/package.json index 65581324..fc6022b3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -9,15 +9,14 @@ }, "scripts": { "prepare": "yarn build", - "build": "rm -rf dist && tsc && cp lib-runner-mapping.yaml dist/lib-runner-mapping.yaml", + "build": "rm -rf dist && tsc && cp src/lib-runner-mapping.yaml dist/lib-runner-mapping.yaml", "start": "yarn build && node ./bin/run.js", "test": "yarn build && ts-mocha ./tests --recursive --extension .spec.ts --exit --timeout 5000", "lint": "eslint ." }, "files": [ "dist", - "bin", - "lib-runner-mapping.yaml" + "bin" ], "dependencies": { "@inquirer/prompts": "^7.2.4", diff --git a/packages/cli/lib-runner-mapping.yaml b/packages/cli/src/lib-runner-mapping.yaml similarity index 100% rename from packages/cli/lib-runner-mapping.yaml rename to packages/cli/src/lib-runner-mapping.yaml diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index 7263b1eb..c29ff4ae 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -96,11 +96,11 @@ function getLibVersion(): string { } } -function getRunnerVersion(libVersion: string): string { +export function getRunnerVersion(libVersion: string, mappingPath?: string): string { try { - let mappingPath = path.join(__dirname, '..', 'lib-runner-mapping.yaml') + const finalMappingPath = mappingPath || path.join(__dirname, '..', 'lib-runner-mapping.yaml') - const mappingContent = fs.readFileSync(mappingPath, 'utf-8') + const mappingContent = fs.readFileSync(finalMappingPath, 'utf-8') const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) for (const entry of mapping) { @@ -111,6 +111,9 @@ function getRunnerVersion(libVersion: string): string { throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) } catch (error) { + if (error instanceof Error && error.message.includes('No runner version mapping found')) { + throw error + } throw new Error(`Failed to read lib-runner-mapping.yaml: ${error}`) } } diff --git a/packages/cli/tests/ManifestHandler.spec.ts b/packages/cli/tests/ManifestHandler.spec.ts index 3aa2f324..aa2941ee 100644 --- a/packages/cli/tests/ManifestHandler.spec.ts +++ b/packages/cli/tests/ManifestHandler.spec.ts @@ -1,6 +1,7 @@ import { expect } from 'chai' +import * as path from 'path' -import ManifestHandler from '../src/lib/ManifestHandler' +import ManifestHandler, { getRunnerVersion } from '../src/lib/ManifestHandler' import { SEM_VER_REGEX } from '../src/validators' import invalidSemVers from './fixtures/sem-vers/invalid-sem-vers.json' @@ -151,4 +152,95 @@ describe('ManifestHandler', () => { }) }) }) + + describe('getRunnerVersion', () => { + const singleRangePath = path.join(__dirname, 'fixtures', 'lib-runner-mappings', 'single-range.yaml') + const multipleRangesPath = path.join(__dirname, 'fixtures', 'lib-runner-mappings', 'multiple-ranges.yaml') + const invalidMappingPath = path.join(__dirname, 'fixtures', 'lib-runner-mappings', 'invalid-mapping.yaml') + + context('when using a single range mapping', () => { + context('when version satisfies the range', () => { + context('when version is at exact boundary', () => { + it('returns the corresponding runner version', () => { + const result = getRunnerVersion('0.0.1-rc.1', singleRangePath) + + expect(result).to.equal('1.0.0') + }) + }) + + context('when version is above the boundary', () => { + it('returns the corresponding runner version', () => { + const versions = ['0.0.1-rc.5', '0.1.0', '1.0.0', '2.0.0'] + + for (const version of versions) { + const result = getRunnerVersion(version, singleRangePath) + expect(result).to.equal('1.0.0') + } + }) + }) + }) + + context('when version does not satisfy the range', () => { + context('when version is below the boundary', () => { + it('throws an error', () => { + const versions = ['0.0.0', '0.0.1-alpha.1', '0.0.1-beta.1', '0.0.1-rc.0'] + + for (const version of versions) { + expect(() => getRunnerVersion(version, singleRangePath)).to.throw( + `No runner version mapping found for lib-ts version ${version}` + ) + } + }) + }) + }) + }) + + context('when using multiple range mappings', () => { + context('when version satisfies multiple ranges', () => { + it('returns the runner version from the first matching range', () => { + const result = getRunnerVersion('0.0.5', multipleRangesPath) + + expect(result).to.equal('1.0.0') + }) + }) + + context('when version satisfies only one range', () => { + it('returns the corresponding runner version', () => { + const testCases = [ + { version: '0.0.1-rc.1', expected: '1.0.0' }, + { version: '0.0.9', expected: '1.0.0' }, + { version: '0.1.0', expected: '2.0.0' }, + { version: '0.5.0', expected: '2.0.0' }, + { version: '1.0.0', expected: '3.0.0' }, + { version: '2.0.0', expected: '3.0.0' }, + ] + + for (const { version, expected } of testCases) { + const result = getRunnerVersion(version, multipleRangesPath) + expect(result).to.equal(expected) + } + }) + }) + + context('when version does not satisfy any range', () => { + it('throws an error', () => { + const versions = ['0.0.0', '0.0.1-alpha.1', '0.0.1-beta.1'] + + for (const version of versions) { + expect(() => getRunnerVersion(version, multipleRangesPath)).to.throw( + `No runner version mapping found for lib-ts version ${version}` + ) + } + }) + }) + }) + + context('when mapping file is invalid', () => { + it('throws an error', () => { + expect(() => getRunnerVersion('0.0.1-rc.1', invalidMappingPath)).to.throw( + 'Failed to read lib-runner-mapping.yaml' + ) + }) + }) + }) }) diff --git a/packages/cli/tests/fixtures/lib-runner-mappings/invalid-mapping.yaml b/packages/cli/tests/fixtures/lib-runner-mappings/invalid-mapping.yaml new file mode 100644 index 00000000..36e3c90f --- /dev/null +++ b/packages/cli/tests/fixtures/lib-runner-mappings/invalid-mapping.yaml @@ -0,0 +1,3 @@ +# Invalid mapping fixture - missing required fields +- libVersionRange: ">=0.0.1-rc.1" + # runnerVersion is missing diff --git a/packages/cli/tests/fixtures/lib-runner-mappings/multiple-ranges.yaml b/packages/cli/tests/fixtures/lib-runner-mappings/multiple-ranges.yaml new file mode 100644 index 00000000..529b8cf2 --- /dev/null +++ b/packages/cli/tests/fixtures/lib-runner-mappings/multiple-ranges.yaml @@ -0,0 +1,7 @@ +# Multiple range mappings fixture for testing priority/order +- libVersionRange: ">=1.0.0" + runnerVersion: "3.0.0" +- libVersionRange: ">=0.1.0 <1.0.0" + runnerVersion: "2.0.0" +- libVersionRange: ">=0.0.1-rc.1 <0.1.0" + runnerVersion: "1.0.0" diff --git a/packages/cli/tests/fixtures/lib-runner-mappings/single-range.yaml b/packages/cli/tests/fixtures/lib-runner-mappings/single-range.yaml new file mode 100644 index 00000000..2b34e31b --- /dev/null +++ b/packages/cli/tests/fixtures/lib-runner-mappings/single-range.yaml @@ -0,0 +1,3 @@ +# Single range mapping fixture (simulates current state) +- libVersionRange: ">=0.0.1-rc.1" + runnerVersion: "1.0.0" From dd69d5a0ec09cdc2ef056d6b28194b8889c808a4 Mon Sep 17 00:00:00 2001 From: ncomerci Date: Fri, 9 Jan 2026 15:20:37 -0300 Subject: [PATCH 4/6] fix: enhance path resolution in getRunnerVersion function --- packages/cli/src/lib/ManifestHandler.ts | 28 +++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index c29ff4ae..c2f2bc85 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -98,7 +98,28 @@ function getLibVersion(): string { export function getRunnerVersion(libVersion: string, mappingPath?: string): string { try { - const finalMappingPath = mappingPath || path.join(__dirname, '..', 'lib-runner-mapping.yaml') + let finalMappingPath = mappingPath + + if (!finalMappingPath) { + let currentDir = process.cwd() + while (currentDir !== path.dirname(currentDir)) { + const distMappingPath = path.join( + currentDir, + 'node_modules', + '@mimicprotocol', + 'cli', + 'dist', + 'lib-runner-mapping.yaml' + ) + if (fs.existsSync(distMappingPath)) { + finalMappingPath = distMappingPath + break + } + currentDir = path.dirname(currentDir) + } + + if (!finalMappingPath) throw new Error('Could not find @mimicprotocol/cli package with lib-runner-mapping.yaml') + } const mappingContent = fs.readFileSync(finalMappingPath, 'utf-8') const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) @@ -114,6 +135,9 @@ export function getRunnerVersion(libVersion: string, mappingPath?: string): stri if (error instanceof Error && error.message.includes('No runner version mapping found')) { throw error } - throw new Error(`Failed to read lib-runner-mapping.yaml: ${error}`) + if (error instanceof Error && error.message.includes('Could not find @mimicprotocol/cli package')) { + throw error + } + throw new Error(`Failed to read lib-runner-mapping.yaml from @mimicprotocol/cli: ${error}`) } } From 73fe7fb12926b95e624f9a8f8489b633e93f591d Mon Sep 17 00:00:00 2001 From: ncomerci Date: Fri, 9 Jan 2026 15:29:59 -0300 Subject: [PATCH 5/6] fix: simplify error handling in getRunnerVersion function --- packages/cli/src/lib/ManifestHandler.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index c2f2bc85..f8de2ab9 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -132,12 +132,6 @@ export function getRunnerVersion(libVersion: string, mappingPath?: string): stri throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) } catch (error) { - if (error instanceof Error && error.message.includes('No runner version mapping found')) { - throw error - } - if (error instanceof Error && error.message.includes('Could not find @mimicprotocol/cli package')) { - throw error - } throw new Error(`Failed to read lib-runner-mapping.yaml from @mimicprotocol/cli: ${error}`) } } From fd7efac41e3f8b93ea8df9556d7b37e71835d817 Mon Sep 17 00:00:00 2001 From: ncomerci Date: Mon, 12 Jan 2026 13:19:55 -0300 Subject: [PATCH 6/6] refactor: extract file resolution logic --- packages/cli/src/lib/ManifestHandler.ts | 62 +++++++++++-------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/packages/cli/src/lib/ManifestHandler.ts b/packages/cli/src/lib/ManifestHandler.ts index f8de2ab9..2a5b16bd 100644 --- a/packages/cli/src/lib/ManifestHandler.ts +++ b/packages/cli/src/lib/ManifestHandler.ts @@ -81,57 +81,49 @@ function handleValidationError(command: Command, err: unknown): never { command.error(message, { code, suggestions }) } +function findFileInNodeModules(relativePath: string): string { + let currentDir = process.cwd() + + while (currentDir !== path.dirname(currentDir)) { + const filePath = path.join(currentDir, 'node_modules', ...relativePath.split('/')) + if (fs.existsSync(filePath)) return filePath + currentDir = path.dirname(currentDir) + } + + throw new Error(`Could not find ${relativePath} in node_modules`) +} + function getLibVersion(): string { try { - let currentDir = process.cwd() - while (currentDir !== path.dirname(currentDir)) { - const libPackagePath = path.join(currentDir, 'node_modules', '@mimicprotocol', 'lib-ts', 'package.json') - if (fs.existsSync(libPackagePath)) return JSON.parse(fs.readFileSync(libPackagePath, 'utf-8')).version - currentDir = path.dirname(currentDir) - } - - throw new Error('Could not find @mimicprotocol/lib-ts package') + const libPackagePath = findFileInNodeModules('@mimicprotocol/lib-ts/package.json') + const packageContent = fs.readFileSync(libPackagePath, 'utf-8') + return JSON.parse(packageContent).version } catch (error) { + if (error instanceof Error && error.message.includes('Could not find')) { + throw new Error('Could not find @mimicprotocol/lib-ts package') + } throw new Error(`Failed to read @mimicprotocol/lib-ts version: ${error}`) } } export function getRunnerVersion(libVersion: string, mappingPath?: string): string { try { - let finalMappingPath = mappingPath - - if (!finalMappingPath) { - let currentDir = process.cwd() - while (currentDir !== path.dirname(currentDir)) { - const distMappingPath = path.join( - currentDir, - 'node_modules', - '@mimicprotocol', - 'cli', - 'dist', - 'lib-runner-mapping.yaml' - ) - if (fs.existsSync(distMappingPath)) { - finalMappingPath = distMappingPath - break - } - currentDir = path.dirname(currentDir) - } - - if (!finalMappingPath) throw new Error('Could not find @mimicprotocol/cli package with lib-runner-mapping.yaml') - } + const resolvedMappingPath = mappingPath || findFileInNodeModules('@mimicprotocol/cli/dist/lib-runner-mapping.yaml') - const mappingContent = fs.readFileSync(finalMappingPath, 'utf-8') + const mappingContent = fs.readFileSync(resolvedMappingPath, 'utf-8') const mapping = LibRunnerMappingValidator.parse(load(mappingContent)) for (const entry of mapping) { - if (semver.satisfies(libVersion, entry.libVersionRange)) { - return entry.runnerVersion - } + if (semver.satisfies(libVersion, entry.libVersionRange)) return entry.runnerVersion } throw new Error(`No runner version mapping found for lib-ts version ${libVersion}`) } catch (error) { - throw new Error(`Failed to read lib-runner-mapping.yaml from @mimicprotocol/cli: ${error}`) + if (error instanceof ZodError) { + throw new Error( + `Failed to read lib-runner-mapping.yaml from @mimicprotocol/cli: Invalid format - ${error.message}` + ) + } + throw error } }