UNPKG

cloudscript-server

Version:

A local environment for cloudscript development

129 lines (104 loc) 4.39 kB
const fs = require('fs'); const { spawnSync } = require('child_process'); const path = require('path'); const crypto = require('crypto'); const compilerUtils = require('./src/compilers/compilerUtils'); function clearCache() { if (!fs.existsSync(path.join(__dirname, 'typings-cache'))) return; fs.rmSync(path.join(__dirname, 'typings-cache'), { recursive: true }); fs.mkdirSync(path.join(__dirname, 'typings-cache'), { recursive: true }); } function hashDirectory(directory) { return crypto.createHash('md5').update(directory).digest('hex'); } function loadCache(directory) { const hash = hashDirectory(directory); const mapsDir = path.join(__dirname, 'typings-cache'); fs.mkdirSync(mapsDir, { recursive: true }); const cachePath = path.join(mapsDir, `${hash}.typings.json`); if (!fs.existsSync(cachePath)) { return { cache: {}, path: cachePath }; } const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8')); return { cache, path: cachePath }; } function saveCache(cache, cachePath) { fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2)); } function generateTypings(directory) { console.log('🔠 Generating typings...'.blue); const startTime = Date.now(); let files = compilerUtils.getFiles(directory, `\nnode_modules\ntypings\n`, '.dtsignore'); files = files.filter(file => file.includes('.js')); const { cache, path: cachePath } = loadCache(directory); const filesToProcess = []; for (let file of files) { const relativePath = path.relative(directory, file).replace(/\\/g, '/'); const stats = fs.statSync(file); const mtime = stats.mtimeMs; if (!cache[relativePath] || cache[relativePath] !== mtime) { filesToProcess.push(file); cache[relativePath] = mtime; } } if (filesToProcess.length === 0) { console.log('All typings up to date'.blue); } else { console.log(`Generating typings for ${filesToProcess.length} changed files...`.yellow); generateTypingsBatch(filesToProcess, directory); } saveCache(cache, cachePath); // Now update the index.d.ts file (still always generated) try { let addedTypings = files.map(file => { let absolutePath = path.relative(directory, file); let ext = path.extname(absolutePath); absolutePath = absolutePath.substring(0, absolutePath.length - ext.length); let typingPath = path.join('scripts', absolutePath + '.d.ts'); typingPath = typingPath.replace(/\\/g, '/'); return `/// <reference path="${typingPath}" />`; }); fs.writeFileSync(path.join(directory, 'typings/autogenerated/index.d.ts'), addedTypings.join('\n')); } catch (e) { console.error(e); } console.log(`✔️ Typings generated in ${Date.now() - startTime}ms`.blue); } function generateTypingsBatch(files, mainDir) { try { if (files.length === 0) { console.log('No files to generate typings'); return; } const typingsDir = path.join(mainDir, 'typings', 'autogenerated', 'scripts'); fs.mkdirSync(typingsDir, { recursive: true }); const tempTsconfigPath = path.join(__dirname, 'tsconfig.typings.json'); const tsconfig = { compilerOptions: { declaration: true, emitDeclarationOnly: true, allowJs: true, noResolve: true, outDir: typingsDir, target: "ESNext", module: "ESNext", strict: false }, files: files }; fs.writeFileSync(tempTsconfigPath, JSON.stringify(tsconfig, null, 2)); console.log('Running tsc...'.dim); const result = spawnSync(process.execPath, [ path.join(__dirname, 'node_modules/typescript/lib/tsc.js'), '-p', tempTsconfigPath ], { encoding: 'utf-8' }); // console.log(result.stdout); // console.error(result.stderr); fs.unlinkSync(tempTsconfigPath); } catch (e) { console.error(e); } } module.exports = { generateTypings, clearCache };