UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

241 lines (196 loc) • 7.21 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { getDevExpressLCXKey } = require('./dx-get-lcx'); const { tryConvertLCXtoLCP, getLCPInfo } = require('./dx-lcx-2-lcp'); const { TEMPLATES } = require('./messages'); const EXPORT_NAME = 'licenseKey'; const TRIAL_VALUE = 'TRIAL'; const CLI_PREFIX = '[devextreme-license]'; function logStderr(...lines) { process.stderr.write(lines.join('\n') + '\n\n'); } function prefixed(msg) { return `${CLI_PREFIX} ${msg}`; } function fail(msg) { process.stderr.write(msg.endsWith('\n') ? msg : msg + '\n'); process.exit(0); } function printHelp() { process.stdout.write( [ 'Usage:', ' devextreme-license --out <path> [options]', '', 'Options:', ' --out <path> Output file path (optional)', ' --non-modular Generate a non-modular JS file (only with .js extension)', ' --no-gitignore Do not modify .gitignore', ' --force Overwrite existing output file', ' --cwd <path> Project root (default: process.cwd())', ' -h, --help Show help', '', 'Examples:', ' "prebuild": "devextreme-license --out src/.devextreme/license-key.ts"', ' "prebuild": "devextreme-license --non-modular --out src/.devextreme/license-key.js"', '', ].join('\n') ); } function parseArgs(argv) { const args = argv.slice(2); const out = { outPath: null, nonModular: false, gitignore: true, force: false, cwd: process.cwd(), help: false, }; for(let i = 0; i < args.length; i++) { const a = args[i]; if(a === '-h' || a === '--help') out.help = true; else if(a === '--out') { const next = args[i + 1]; if(!next || next.startsWith('-')) { logStderr(prefixed('Warning: --out requires a path argument but none was provided. Ignoring --out.')); } else { out.outPath = args[++i]; } } else if(a.startsWith('--out=')) { const val = a.slice('--out='.length); if(!val) { logStderr(prefixed('Warning: --out requires a path argument but none was provided. Ignoring --out.')); } else { out.outPath = val; } } else if(a === '--non-modular') out.nonModular = true; else if(a === '--no-gitignore') out.gitignore = false; else if(a === '--force') out.force = true; else if(a === '--cwd') out.cwd = args[++i] || process.cwd(); else if(a.startsWith('--cwd=')) out.cwd = a.slice('--cwd='.length); else fail(`Unknown argument: ${a}\nRun devextreme-license --help`); } return out; } function ensureDirExists(dirPath) { fs.mkdirSync(dirPath, { recursive: true }); } function readTextIfExists(filePath) { try { if(!fs.existsSync(filePath)) return null; return fs.readFileSync(filePath, 'utf8'); } catch{ return null; } } function writeFileAtomic(filePath, content) { const dir = path.dirname(filePath); const base = path.basename(filePath); const tmp = path.join(dir, `.${base}.${process.pid}.${Date.now()}.tmp`); fs.writeFileSync(tmp, content, 'utf8'); fs.renameSync(tmp, filePath); } function toPosixPath(p) { return p.split(path.sep).join('/'); } function addToGitignore(projectRoot, outAbsPath) { const gitignorePath = path.join(projectRoot, '.gitignore'); let rel = path.relative(projectRoot, outAbsPath); if(rel.startsWith('..')) return; rel = toPosixPath(rel).trim(); const existing = readTextIfExists(gitignorePath); if(existing == null) { writeFileAtomic(gitignorePath, rel + '\n'); return; } const lines = existing.split(/\r?\n/).map((l) => l.trim()); if(lines.includes(rel) || lines.includes('/' + rel)) return; const needsNewline = existing.length > 0 && !existing.endsWith('\n'); fs.appendFileSync(gitignorePath, (needsNewline ? '\n' : '') + rel + '\n', 'utf8'); } function renderFile(lcpKey) { return [ '// Auto-generated by devextreme-license.', '// Do not commit this file to source control.', '', `export const ${EXPORT_NAME} = ${JSON.stringify(lcpKey)};`, '', ].join('\n'); } function renderNonModularFile(lcpKey) { return [ '// Auto-generated by devextreme-license.', '// Do not commit this file to source control.', '', `DevExpress.config({ licenseKey: ${JSON.stringify(lcpKey)} });`, '', ].join('\n'); } function main() { const opts = parseArgs(process.argv); if(opts.help) { printHelp(); process.exit(0); } const { key: lcx, source, currentVersion } = getDevExpressLCXKey() || {}; let lcp = TRIAL_VALUE; let licenseId = null; if(lcx) { lcp = tryConvertLCXtoLCP(lcx) || TRIAL_VALUE; const { warning, licenseId: id } = getLCPInfo(lcp); licenseId = id; if(warning) { const lines = []; lines.push( prefixed(`${TEMPLATES.warningPrefix(1000)} ${TEMPLATES.purchaseLicense}`), ); if(licenseId) { lines.push(TEMPLATES.licenseId(licenseId)); } lines.push( TEMPLATES.keyWasFound(source.type, source.path), ); if(warning.type !== 'trial') { const code = TEMPLATES.warningCodeByType(warning.type); lines.push( TEMPLATES.keyVerificationFailed(warning.type, warning.keyVersion, warning.currentVersion), ); if(warning.type === 'trialExpired') { lines.push(prefixed(`${TEMPLATES.warningPrefix(code)} ${TEMPLATES.purchaseLicense}`)); } else { lines.push(prefixed(`${TEMPLATES.warningPrefix(code)} ${TEMPLATES.installationInstructions}`)); } } logStderr(...lines); } } else { logStderr( prefixed(`${TEMPLATES.warningPrefix(1000)} ${TEMPLATES.purchaseLicense}`), TEMPLATES.keyNotFound, prefixed(`${TEMPLATES.warningPrefix(1001)} ${TEMPLATES.installationInstructions}`), ); } if(!opts.outPath) { process.stdout.write(lcp + '\n'); process.exit(0); } const projectRoot = path.resolve(opts.cwd); const outAbs = path.resolve(projectRoot, opts.outPath); ensureDirExists(path.dirname(outAbs)); if(!opts.force && fs.existsSync(outAbs)) { fail(`Output file already exists: ${opts.outPath}\nUse --force to overwrite.`); } const useNonModular = opts.nonModular && outAbs.endsWith('.js'); writeFileAtomic(outAbs, useNonModular ? renderNonModularFile(lcp) : renderFile(lcp)); if(opts.gitignore) { try { addToGitignore(projectRoot, outAbs); } catch{} } process.exit(0); } main();