fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 112 lines 2.8 kB view raw
1import fs from 'node:fs'; 2import path from 'node:path'; 3 4import type { AnyString } from '@hey-api/types'; 5import ts from 'typescript'; 6 7export function findPackageJson(initialDir: string): unknown | undefined { 8 let dir = initialDir; 9 while (dir !== path.dirname(dir)) { 10 const files = fs.readdirSync(dir); 11 const candidates = files.filter((file) => file === 'package.json'); 12 13 if (candidates[0]) { 14 const packageJsonPath = path.join(dir, candidates[0]); 15 return JSON.parse( 16 fs.readFileSync(packageJsonPath, { 17 encoding: 'utf8', 18 }), 19 ); 20 } 21 22 dir = path.dirname(dir); 23 } 24 25 return; 26} 27 28type PackageJson = { 29 bugs: { 30 url: string; 31 }; 32 name: string; 33 version: string; 34}; 35 36export function loadPackageJson(initialDir: string): PackageJson | undefined { 37 const packageJson = findPackageJson(initialDir); 38 39 const safePackage: PackageJson = { 40 bugs: { 41 url: '', 42 }, 43 name: '', 44 version: '', 45 }; 46 47 if (packageJson && typeof packageJson === 'object') { 48 if ('name' in packageJson && typeof packageJson.name === 'string') { 49 safePackage.name = packageJson.name; 50 } 51 52 if ('version' in packageJson && typeof packageJson.version === 'string') { 53 safePackage.version = packageJson.version; 54 } 55 56 if ('bugs' in packageJson && packageJson.bugs && typeof packageJson.bugs === 'object') { 57 if ('url' in packageJson.bugs && typeof packageJson.bugs.url === 'string') { 58 safePackage.bugs.url = packageJson.bugs.url; 59 if (safePackage.bugs.url && !safePackage.bugs.url.endsWith('/')) { 60 safePackage.bugs.url += '/'; 61 } 62 } 63 } 64 } 65 66 if (!safePackage.name) return; 67 68 return safePackage; 69} 70 71export function findTsConfigPath(baseDir: string, tsConfigPath?: AnyString | null): string | null { 72 if (tsConfigPath === null) { 73 return null; 74 } 75 76 if (tsConfigPath) { 77 const resolved = path.isAbsolute(tsConfigPath) 78 ? tsConfigPath 79 : path.resolve(baseDir, tsConfigPath); 80 return fs.existsSync(resolved) ? resolved : null; 81 } 82 83 let dir = baseDir; 84 while (dir !== path.dirname(dir)) { 85 const files = fs.readdirSync(dir); 86 const candidates = files 87 .filter((file) => file.startsWith('tsconfig') && file.endsWith('.json')) 88 .sort((file) => (file === 'tsconfig.json' ? -1 : 1)); 89 90 if (candidates[0]) { 91 return path.join(dir, candidates[0]); 92 } 93 94 dir = path.dirname(dir); 95 } 96 97 return null; 98} 99 100export function loadTsConfig(configPath: string | null): ts.ParsedCommandLine | null { 101 if (!configPath) { 102 return null; 103 } 104 105 const raw = ts.readConfigFile(configPath, ts.sys.readFile); 106 107 if (raw.error) { 108 throw new Error(`Couldn't read tsconfig from path: ${configPath}`); 109 } 110 111 return ts.parseJsonConfigFileContent(raw.config, ts.sys, path.dirname(configPath)); 112}