bs3m
Version:
TS/JS migrations framework for sqlite3 databases
103 lines • 3.5 kB
JavaScript
;
/** Utility functions for migration ID parsing and validation. */
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseIdParts = parseIdParts;
const types_js_1 = require("./types.js");
const errors_js_1 = require("./errors.js");
/**
* Parses a migration string ID into its components. Expected format:
* yymmdd_hhmm_name__flags (flags are optional)
*
* @param stringId - The migration string ID to parse
* @returns Parsed migration ID components
* @throws {@link MigrationIdParseError} If the format is invalid
*/
function parseIdParts(stringId) {
// Split by double underscore to separate flags
const [mainPart, flagsPart] = stringId.split('__');
if (!mainPart) {
throw new errors_js_1.MigrationIdParseError(stringId, 'empty main part');
}
// Parse main part: yymmdd_hhmm_name
const parts = mainPart.split('_');
if (parts.length < 3) {
throw new errors_js_1.MigrationIdParseError(stringId, 'must have at least date, time, and name');
}
const [date, time, ...nameParts] = parts;
// Validate date part
if (!date || !containsNDigits(date, 6)) {
throw new errors_js_1.MigrationIdParseError(stringId, 'date must be 6 digits (yymmdd)');
}
// Validate time part
if (!time || !containsNDigits(time, 4)) {
throw new errors_js_1.MigrationIdParseError(stringId, 'time must be 4 digits (hhmm)');
}
// Validate and join name parts
const name = nameParts.join('_');
if (!name || !isValidMigrationName(name)) {
throw new errors_js_1.MigrationIdParseError(stringId, 'name must be alphanumeric with underscores (max 1 consecutive)');
}
// Parse numeric ID
const id = parseInt(`${date}${time}`, 10);
// Parse flags
let flags = types_js_1.MigrationFlag.NONE;
if (flagsPart !== undefined) {
if (!flagsPart || !isValidHexString(flagsPart)) {
throw new errors_js_1.MigrationIdParseError(stringId, 'flags must be a valid hex string');
}
flags = parseInt(flagsPart, 16);
}
return {
stringId: stringId,
id,
flags,
name,
};
}
/** Validates that a string contains only digits and has the specified length. */
function containsNDigits(str, len) {
if (str.length !== len) {
return false;
}
for (const c of str) {
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
/** Validates that a string is a valid lowercase hex string. */
function isValidHexString(str) {
if (str.length === 0) {
return false;
}
for (const c of str) {
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))) {
return false;
}
}
return true;
}
/**
* Validates migration name format. Must be lowercase alphanumeric with
* underscores, max 1 consecutive underscore.
*/
function isValidMigrationName(name) {
if (!name || name.length === 0) {
return false;
}
let prevWasUnderscore = false;
for (const c of name) {
const isAlphaNumeric = (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
const isUnderscore = c === '_';
if (!isAlphaNumeric && !isUnderscore) {
return false;
}
if (isUnderscore && prevWasUnderscore) {
return false; // No consecutive underscores
}
prevWasUnderscore = isUnderscore;
}
return true;
}
//# sourceMappingURL=migrations_id_parser.js.map