UNPKG

inkplugin

Version:

INK cli tools for plugin developers.

161 lines (145 loc) 4.73 kB
const {Command, flags} = require('@oclif/command') const fs = require('fs') const path = require('path') const JSZip = require('jszip') let packageJSONfile = null const filesBlackList = [ '.exe', '.dll', '.bin', '.bat', '.com', '.sh', '.vb', '.dye', ] const requiredFiles = ['package.json'] const inkLatestVer = '^2.0.0' function dirRecursiveFileSearch(dir, done) { // console.log(dir) const lastDir = dir.split(path.sep).pop() if ((lastDir[0] === '.' && lastDir !== './') || lastDir === 'node_modules') { done(null, []) } var results = [] fs.readdir(dir, function (err, list) { if (err) return done(err) var pending = list.length if (!pending) return done(null, results) list.forEach(function (file) { file = path.resolve(dir, file) fs.stat(file, function (_err, stat) { if (stat && stat.isDirectory()) { dirRecursiveFileSearch(file, function (_err, res) { results = results.concat(res) if (!--pending) done(null, results) }) } else { results.push(file) if (!--pending) done(null, results) } }) }) }) } function validate(fileNames, location) { let flag = true // validating it contains all the required files for (let i = 0; i < requiredFiles.length; i++) { flag = flag && fileNames.includes(path.join(location, requiredFiles[i])) if (!flag) return false } // check if package.json `main` field points towards entry js file const rawData = fs.readFileSync(path.join(location, 'package.json')) packageJSONfile = JSON.parse(rawData) flag = flag && packageJSONfile && packageJSONfile['ink-plugin'] && fs.existsSync(path.join(location, packageJSONfile.main)) return flag } class PackageCommand extends Command { async run() { const {args, flags} = this.parse(PackageCommand) const location = args.path const output = flags.output || location this.log( '\n******************** INK Cli Packager ********************\n' ) this.log(`Packaging directory: ${location}\n`) dirRecursiveFileSearch(location, (err, files) => { // handling error if (err) { return this.log('Unable to scan directory: ' + err) } // listing all files using forEach files = files .map(f => f.replace(process.cwd() + path.sep, '')) .filter( f => !filesBlackList.includes(path.extname(f)) && f !== 'inkapi.js' ) // if its a blacklisted file, remove it if (validate(files, location)) { this.log('- ' + files.join('\n- ')) const {name, engines} = packageJSONfile const zip = new JSZip() // creating main zip const extension = zip.folder('extension') // creating extension directory inside our zip files.forEach(file => { extension.file( file.replace(location + path.sep, ''), fs.readFileSync(file) ) }) zip.file( 'manifest.json', JSON.stringify({ name: name, ink: engines ? engines.ink : inkLatestVer, }) ) // creating empty manifest.json file // write the generated zip file to disk zip .generateNodeStream({ type: 'nodebuffer', streamFiles: true, compression: 'DEFLATE', }) .pipe(fs.createWriteStream(path.join(output, `${name}.dye`))) .on('finish', () => { this.log( '\n****************** Packaged Successfully ******************' ) this.log( '\nOutput Packaged File: ', path.join(output, `${name}.dye \n\n`) ) }) } else { this.log('Required files are missing in the directory.\n') this.log('1. It must contain a package.json file.') this.log( '2. package.json `main` field should point toward the entry js file\n' ) } }) } } PackageCommand.description = `package INK plugin project into a DYE file. It will package your INK plugin project into a DYE file, which can be used to install your plugin in INK editor. ` PackageCommand.flags = { output: flags.string({ char: 'o', description: 'destination path for DYE file', // help description for flag required: false, // make flag required (this is not common and you should probably use an argument instead) }), } PackageCommand.args = [ { name: 'path', // name of arg to show in help and reference with args[name] description: 'Path to plugin project.', // help description hidden: false, // hide this arg from help default: './', }, ] module.exports = PackageCommand