UNPKG

@launchql/core

Version:

LaunchQL Package and Migration Tools

103 lines (102 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.writePackage = exports.packageModule = exports.cleanTree = void 0; const logger_1 = require("@launchql/logger"); const fs_1 = require("fs"); const path_1 = require("path"); const pgsql_deparser_1 = require("pgsql-deparser"); const pgsql_parser_1 = require("pgsql-parser"); const files_1 = require("../files"); const resolve_1 = require("../resolution/resolve"); const transform_1 = require("./transform"); const log = new logger_1.Logger('package'); const noop = () => undefined; const cleanTree = (tree) => { return (0, transform_1.transformProps)(tree, { stmt_len: noop, stmt_location: noop, location: noop, }); }; exports.cleanTree = cleanTree; const filterStatements = (stmts, extension) => { if (!extension) return stmts; return stmts.filter(node => { const stmt = node.stmt; return !stmt.hasOwnProperty('TransactionStmt') && !stmt.hasOwnProperty('CreateExtensionStmt'); }); }; const packageModule = async (packageDir, { usePlan = true, extension = true, pretty = true, functionDelimiter = '$EOFCODE$' } = {}) => { const resolveFn = usePlan ? resolve_1.resolveWithPlan : resolve_1.resolve; const sql = resolveFn(packageDir); if (!sql?.trim()) { log.warn(`⚠️ No SQL generated for module at ${packageDir}. Skipping.`); return { sql: '' }; } const extname = (0, files_1.getExtensionName)(packageDir); try { const parsed = await (0, pgsql_parser_1.parse)(sql); parsed.stmts = filterStatements(parsed.stmts, extension); const topLine = extension ? `\\echo Use "CREATE EXTENSION ${extname}" to load this file. \\quit\n` : ''; const finalSql = await (0, pgsql_deparser_1.deparse)(parsed, { pretty, functionDelimiter }); const tree1 = parsed.stmts; const tree2 = await (0, pgsql_parser_1.parse)(finalSql); const results = { sql: `${topLine}${finalSql}`, }; const diff = JSON.stringify((0, exports.cleanTree)(tree1)) !== JSON.stringify((0, exports.cleanTree)(tree2)); if (diff) { results.diff = true; results.tree1 = JSON.stringify((0, exports.cleanTree)(tree1), null, 2); results.tree2 = JSON.stringify((0, exports.cleanTree)(tree2), null, 2); } return results; } catch (e) { log.error(`❌ Failed to parse SQL for ${packageDir}`); console.error(e); throw e; } }; exports.packageModule = packageModule; const writePackage = async ({ version, extension = true, usePlan = true, packageDir, }) => { const pkgPath = `${packageDir}/package.json`; const pkg = require(pkgPath); const extname = await (0, files_1.getExtensionName)(packageDir); const makePath = `${packageDir}/Makefile`; const controlPath = `${packageDir}/${extname}.control`; const sqlFileName = `${extname}--${version}.sql`; const Makefile = (0, fs_1.readFileSync)(makePath, 'utf-8'); const control = (0, fs_1.readFileSync)(controlPath, 'utf-8'); const { sql, diff, tree1, tree2 } = await (0, exports.packageModule)(packageDir, { extension, usePlan, }); const outPath = extension ? `${packageDir}/sql` : `${packageDir}/out`; (0, fs_1.rmSync)(outPath, { recursive: true, force: true }); (0, fs_1.mkdirSync)(outPath, { recursive: true }); if (extension) { (0, fs_1.writeFileSync)(controlPath, control.replace(/default_version = '[0-9\.]+'/, `default_version = '${version}'`)); pkg.version = version; (0, fs_1.writeFileSync)(pkgPath, JSON.stringify(pkg, null, 2)); const regex = new RegExp(`${extname}--[0-9.]+.sql`); (0, fs_1.writeFileSync)(makePath, Makefile.replace(regex, sqlFileName)); } if (diff) { log.warn(`⚠️ SQL diff exists! Review the ${(0, path_1.relative)(packageDir, outPath)}/ folder.`); // Uncomment if needed: // writeFileSync(`${outPath}/orig.${sqlFileName}.tree.json`, tree1); // writeFileSync(`${outPath}/parsed.${sqlFileName}.tree.json`, tree2); } const writePath = `${outPath}/${sqlFileName}`; (0, fs_1.writeFileSync)(writePath, sql); log.success(`${(0, path_1.relative)(packageDir, writePath)} written`); }; exports.writePackage = writePackage;