@magic-mustard/sqlsync
Version:
SQLSync simplifies database schema evolution by allowing a declarative approach to table management
141 lines (140 loc) • 5.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Flags = void 0;
const namespace_1 = require("./files/namespace");
var Flags;
(function (Flags) {
Flags.Declarer = 'sqlsync';
// FileType is the default file type if no other file type is specified
Flags.DefaultFileType = namespace_1.Files.FileType;
// export const StatementSplitters = {
// startStatement: 'startStatement',
// endStatement: 'endStatement'
// }
/**
* Builds a declarer statement with the comment and optional additional statements.
* Returns the formatted string that can be used in flags.
*/
function buildDeclarerStatement(...additionalStatements) {
let statement = `-- ${Flags.Declarer}`;
if (additionalStatements.length > 0) {
statement += `: ${additionalStatements.join(' ')}`;
}
return statement;
}
Flags.buildDeclarerStatement = buildDeclarerStatement;
/**
* Checks if a line is a comment and optionally if it contains the declarer.
* Returns true if the condition is met, false otherwise.
*/
function isCommentLine(line, checkDeclarer = false) {
const trimmedLine = line.trim();
if (!trimmedLine.startsWith('--')) {
return false;
}
return checkDeclarer ? trimmedLine.includes(Flags.Declarer) : true;
}
Flags.isCommentLine = isCommentLine;
function stripSqlSyncComments(content) {
return content.replace(/--.*$/gm, '');
}
Flags.stripSqlSyncComments = stripSqlSyncComments;
/**
* Validates the structure of flags in the content. Returns if the first non-empty line
* is not a sqlsync comment at the top of the file.
*/
function validateFlagStructure(content, filePath) {
const lines = content.split('\n');
let foundFirstContent = false;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.length === 0)
continue;
foundFirstContent = true;
if (!isCommentLine(line, true)) {
return;
}
break;
}
if (!foundFirstContent) {
return;
}
}
Flags.validateFlagStructure = validateFlagStructure;
/**
* Extracts the file type flag from the content. Returns 'DefaultFileType' if no specific flag is found or if the first line is not a sqlsync comment.
*/
function extractFileTypeFlag(content, filePath) {
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.length === 0)
continue;
if (isCommentLine(line, true)) {
const flagMatch = line.match(new RegExp(`--\\s*${Flags.Declarer}\\s*:\\s*(\\w+)`));
if (flagMatch) {
if (i > 0 && lines.slice(0, i).some(l => l.trim().length > 0 && !isCommentLine(l))) {
throw new Error(`Invalid placement of file type flag: Flag must be at the top of the file before any non-comment content. (file: ${filePath})`);
}
return flagMatch[1];
}
break;
}
else {
// Non-comment line encountered, stop searching for flags
break;
}
}
return Flags.DefaultFileType;
}
Flags.extractFileTypeFlag = extractFileTypeFlag;
/**
* Extracts content between start and end flags from the provided content.
* Returns an array of strings, each string being the content between a pair of start and end flags.
* Throws an error if a start flag exists without a corresponding end flag, or vice versa.
* Optionally enforces that at least one pair of flags must exist.
*/
function extractContentBetweenFlags(content, filePath, startFlag, endFlag, mustExist = false) {
const lines = content.split('\n');
const results = [];
let currentContent = '';
let insideFlags = false;
let startFlagFound = false;
let endFlagFound = false;
// Construct full flag strings using buildDeclarerStatement
const fullStartFlag = buildDeclarerStatement(startFlag);
const fullEndFlag = buildDeclarerStatement(endFlag);
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line.includes(fullStartFlag)) {
if (insideFlags) {
throw new Error(`Nested start flag detected before end flag: ${startFlag} (file: ${filePath}, line: ${i + 1})`);
}
insideFlags = true;
startFlagFound = true;
currentContent = '';
continue;
}
if (line.includes(fullEndFlag)) {
if (!insideFlags) {
throw new Error(`End flag found without a corresponding start flag: ${endFlag} (file: ${filePath}, line: ${i + 1})`);
}
insideFlags = false;
endFlagFound = true;
results.push(currentContent.trim());
continue;
}
if (insideFlags) {
currentContent += lines[i] + '\n';
}
}
if (insideFlags) {
throw new Error(`Missing end flag for the start flag: ${startFlag} (file: ${filePath})`);
}
if (mustExist && (!startFlagFound || !endFlagFound)) {
throw new Error(`Required flags are missing. At least one pair of start (${startFlag}) and end (${endFlag}) flags must exist. (file: ${filePath})`);
}
return results;
}
Flags.extractContentBetweenFlags = extractContentBetweenFlags;
})(Flags || (exports.Flags = Flags = {}));