Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576import { readdir, readFile } from 'node:fs/promises'import path from 'node:path'
const root = process.cwd()const src = path.join(root, 'src')
async function listSourceFiles(dir) { const entries = await readdir(dir, { withFileTypes: true }) const files = [] for (const entry of entries) { const full = path.join(dir, entry.name) if (entry.isDirectory()) files.push(...await listSourceFiles(full)) else if (/\.(ts|tsx)$/.test(entry.name)) files.push(full) } return files}
function relative(file) { return path.relative(root, file)}
const importPattern = /(?:import|export)\s+(?:type\s+)?(?:[^'";]+\s+from\s+)?['"]([^'"]+)['"]|import\s*\(\s*['"]([^'"]+)['"]\s*\)/g
function resolveSourceImport(rel, specifier) { if (!specifier.startsWith('.')) return null const resolved = path.normalize(path.join(path.dirname(rel), specifier)) for (const extension of ['.ts', '.tsx']) { const withExtension = `${resolved}${extension}` if (withExtension.startsWith('src/')) return withExtension } if (resolved.startsWith('src/')) return resolved return null}
function mayImportAtproto(rel) { return rel.startsWith('src/atproto/') || rel === 'src/editions/atproto.tsx' || rel === 'src/entries/atproto.tsx' || rel.startsWith('src/editions/__tests__/')}
function isTestSource(rel) { return rel.includes('/__tests__/') || /\.(?:test|spec)\.[^.]+$/.test(rel)}
const violations = []for (const file of await listSourceFiles(src)) { const rel = relative(file) const text = await readFile(file, 'utf8') for (const match of text.matchAll(importPattern)) { const specifier = match[1] ?? match[2] if (specifier === 'automerge-atproto' && !mayImportAtproto(rel)) { violations.push(`${rel} imports automerge-atproto`) } if (specifier === '@automerge/automerge-repo-react-hooks') { violations.push(`${rel} imports the retired repository React context`) } if (specifier === '@automerge/automerge-repo' && rel !== 'src/repo.ts' && !isTestSource(rel)) { violations.push(`${rel} imports the Classic repository outside its composition module`) } const resolved = resolveSourceImport(rel, specifier) if (resolved?.startsWith('src/atproto/') && !mayImportAtproto(rel)) { violations.push(`${rel} imports ATProto module ${resolved}`) } if (specifier === '#reams-edition' || specifier === '#reams-edition-account-ui') { violations.push(`${rel} imports removed edition alias ${specifier}`) } if ((specifier === './repo' || specifier === '../repo') && rel === 'src/App.tsx') { violations.push('src/App.tsx imports repo.ts instead of receiving an AppRuntime') } }}
if (violations.length) { throw new Error(`Edition source boundary violations:\n${violations.join('\n')}`)}
console.log('edition source boundary checks passed')