mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
* fix(deps): root and mobile resolve one zod, and CI fails if they drift
Mobile type-checks src/shared zod schemas. With mobile on zod 4.6.5 and the
root on 4.6.7, TypeScript treated them as unrelated packages, so wrapped
schemas inferred {} (tests/e2e/helpers/phone-feed-list.ts:154) whenever a
job installed mobile deps.
* fix(deps): guard every package mobile's tsconfig remaps, not only zod
* test(ci): pin the shared-dependency version check to the static phase
59 lines
2.1 KiB
JavaScript
59 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// Root and mobile are separate pnpm projects, so nothing else stops their lockfiles drifting apart.
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
import { join, resolve } from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
import { lockedVersion, lockfileRootImporter } from './pnpm-lockfile-root-importer.mjs'
|
|
|
|
// The packages src/shared imports that mobile/tsconfig.json remaps to mobile's copy. TypeScript
|
|
// merges two copies only at the same version; else zod-wrapped schemas infer `{}` (phone-feed-list.ts).
|
|
export const SHARED_DEPENDENCIES = ['zod', 'tweetnacl', '@noble/hashes', '@types/ws']
|
|
|
|
function importerVersion(importer, name) {
|
|
return lockedVersion(importer.dependencies?.[name] ?? importer.devDependencies?.[name])
|
|
}
|
|
|
|
export function findSharedDependencyVersionProblems({
|
|
rootImporter,
|
|
mobileImporter,
|
|
names = SHARED_DEPENDENCIES
|
|
}) {
|
|
const problems = []
|
|
for (const name of names) {
|
|
const root = importerVersion(rootImporter, name)
|
|
const mobile = importerVersion(mobileImporter, name)
|
|
if (!root || !mobile) {
|
|
problems.push(`${name} is not a direct dependency of ${root ? 'mobile' : 'the root'}`)
|
|
} else if (root !== mobile) {
|
|
problems.push(`${name}: the root locks ${root}, mobile locks ${mobile}`)
|
|
}
|
|
}
|
|
return problems
|
|
}
|
|
|
|
export function main(root = resolve(import.meta.dirname, '../..')) {
|
|
const readImporter = (lockfile) =>
|
|
lockfileRootImporter(readFileSync(join(root, lockfile), 'utf8'))
|
|
const problems = findSharedDependencyVersionProblems({
|
|
rootImporter: readImporter('pnpm-lock.yaml'),
|
|
mobileImporter: readImporter(join('mobile', 'pnpm-lock.yaml'))
|
|
})
|
|
if (problems.length > 0) {
|
|
console.error('Root and mobile must lock the same version of:')
|
|
for (const problem of problems) {
|
|
console.error(`- ${problem}`)
|
|
}
|
|
console.error(
|
|
'Set the same range in package.json and mobile/package.json, then pnpm install in both.'
|
|
)
|
|
return 1
|
|
}
|
|
console.log(`Root and mobile lock the same ${SHARED_DEPENDENCIES.join(', ')}.`)
|
|
return 0
|
|
}
|
|
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
process.exit(main())
|
|
}
|