UNPKG

@threeify/shader-transpiler

Version:

A glsl to JS module transpiler.

158 lines 6.28 kB
#!/usr/bin/env -S node --experimental-modules import fs from 'node:fs'; import path from 'node:path'; import process, { exit } from 'node:process'; import { program } from 'commander'; import glob from 'glob'; import watch from 'watch'; import { Options } from './Options.js'; import { glslToJavaScriptTranspiler } from './transpiler.js'; function commaSeparatedList(value) { return value.split(','); } const packageJson = JSON.parse(fs.readFileSync('./package.json').toString()); program .name('@threeify/shader-transpiler') .version(packageJson.version) .option('-p, --projectDir <dirpath>', `the root of the project directory tree`) .option('-r, --rootDir <dirpath>', `the root of the source directory tree`) .option('-i', '--includeDirs <dirpaths>', 'a series of comma separated include directories') .option('-o, --outDir <dirpath>', `the root of the output directory tree`) .option('-w, --watch', `watch and incremental transpile any changed files`) .option('-j, --allowJSIncludes', `allow referencing javascript and typescript code via includes`) .option('-m, --minify', `reduce the size of the glsl code`) .option('-e, --extensions <items>', 'comma separated list of extensions to transpile', commaSeparatedList) .option('-v, --verboseLevel <level>', `higher numbers means more output`, Number.parseInt); program.parse(process.argv); const options = new Options(); let projectDir = process.cwd(); const programOptions = program.opts(); if (programOptions.projectDir) { projectDir = programOptions.projectDir; } const tsConfigFilePath = path.join(projectDir, 'tsconfig.json'); if (fs.existsSync(tsConfigFilePath)) { const tsConfig = JSON.parse(fs.readFileSync(tsConfigFilePath).toString()); if (tsConfig.compilerOptions) { if (options.verboseLevel >= 1) { console.log(` inferring setup from ${tsConfigFilePath}.`); } options.safeCopy({ rootDir: tsConfig.compilerOptions.rootDir, outDir: tsConfig.compilerOptions.outDir }); } } const threeifyFilePath = path.join(projectDir, 'threeify.json'); if (fs.existsSync(threeifyFilePath)) { const threeifyConfig = JSON.parse(fs.readFileSync(threeifyFilePath).toString()); if (options.verboseLevel >= 1) { console.log(` reading settings from ${threeifyFilePath}.`); } if (threeifyConfig.glsl) { options.safeCopy(threeifyConfig.glsl); } } if (options.verboseLevel >= 1) { console.log(` applying command line overrides.`); } options.safeCopy(program); if (options.verboseLevel >= 2) { console.log(options); } options.extensions = options.extensions.map((ext) => ext.toLowerCase()); if (!options.rootDir) { console.error(`no rootDir specified`); exit(0); } if (!options.outDir) { console.error(`no outDir specified`); exit(0); } options.rootDir = path.normalize(path.join(projectDir, options.rootDir)); if (!fs.existsSync(options.rootDir)) { console.error(`rootDir doesn't exist: ${options.rootDir}`); exit(0); } options.outDir = path.normalize(path.join(projectDir, options.outDir)); options.includeDirs = options.includeDirs.map((includeDir) => path.normalize(path.join(projectDir, includeDir))); if (options.verboseLevel >= 2) { console.log(options); } let numFiles = 0; let numErrors = 0; function inputFileNameToOutputFileName(inputFileName) { inputFileName = path.normalize(inputFileName); const outputFileName = inputFileName.replace(options.rootDir, options.outDir) + '.js'; return outputFileName; } function transpile(sourceFileName) { if (!fs.lstatSync(sourceFileName).isFile()) { return []; } sourceFileName = path.normalize(sourceFileName); const outputFileName = inputFileNameToOutputFileName(sourceFileName); const fileErrors = glslToJavaScriptTranspiler(sourceFileName, outputFileName, options); if (fileErrors.length > 0) { numErrors++; console.error(` ${sourceFileName} --> ${path.basename(outputFileName)}: ${fileErrors.length} Errors.`); fileErrors.forEach((error) => { console.error(` ${error}`); }); } else { if (options.verboseLevel >= 1) { console.log(` ${sourceFileName} --> ${path.basename(outputFileName)}`); } } return fileErrors; } function isFileSupported(fileName) { let ext = path.extname(fileName); if (ext.length > 1) { ext = ext.slice(1); } const result = options.extensions.includes(ext.toLowerCase()); return result; } const extGlob = options.extensions.join('|'); const globRegex = `${options.rootDir}/**/*.+(${extGlob})`; glob(globRegex, {}, function (er, sourceFileNames) { sourceFileNames.forEach((inputFileName) => { numFiles++; transpile(inputFileName); }); if (numErrors > 0) { console.error(`${numErrors} files failed to transpile.`); } console.log(`${numFiles - numErrors} files transpile successfully.`); if (programOptions.watch) { watch.createMonitor(options.rootDir, function (monitor) { monitor.on('created', function (sourceFileName, stat) { if (options.verboseLevel > 1) console.log(`created ${sourceFileName}`); if (isFileSupported(sourceFileName)) { transpile(sourceFileName); } }); monitor.on('changed', function (sourceFileName, curr, prev) { if (options.verboseLevel > 1) console.log(`changed ${sourceFileName}`); if (isFileSupported(sourceFileName)) { transpile(sourceFileName); } }); monitor.on('removed', function (sourceFileName, stat) { if (options.verboseLevel > 1) console.log(`removed ${sourceFileName}`); if (isFileSupported(sourceFileName)) { const outputFileName = inputFileNameToOutputFileName(sourceFileName); if (fs.existsSync(outputFileName)) { fs.unlinkSync(outputFileName); } } }); }); } }); //# sourceMappingURL=index.js.map