UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

1,826 lines (1,812 loc) 47.1 kB
// node_modules/rado/dist/define/OrderBy.js var OrderDirection = /* @__PURE__ */ ((OrderDirection2) => { OrderDirection2["Asc"] = "Asc"; OrderDirection2["Desc"] = "Desc"; return OrderDirection2; })(OrderDirection || {}); // node_modules/rado/dist/define/Param.js var ParamType = /* @__PURE__ */ ((ParamType2) => { ParamType2["Value"] = "ParamData.Value"; ParamType2["Named"] = "ParamData.Named"; return ParamType2; })(ParamType || {}); var ParamData; ((ParamData2) => { class Value { constructor(value, inline = false) { this.value = value; this.inline = inline; } type = "ParamData.Value"; } ParamData2.Value = Value; class Named { constructor(name) { this.name = name; } type = "ParamData.Named"; } ParamData2.Named = Named; })(ParamData || (ParamData = {})); // node_modules/rado/dist/util/Alias.js function randomAlias() { return `__${Math.random().toString(36).slice(2, 9)}`; } // node_modules/rado/dist/define/Target.js var TargetType = /* @__PURE__ */ ((TargetType2) => { TargetType2["Expr"] = "Target.Expr"; TargetType2["CTE"] = "Target.CTE"; TargetType2["Query"] = "Target.Query"; TargetType2["Table"] = "Target.Table"; TargetType2["Join"] = "Target.Join"; return TargetType2; })(TargetType || {}); var Target; ((Target2) => { class Expr2 { constructor(expr, alias) { this.expr = expr; this.alias = alias; } type = "Target.Expr"; } Target2.Expr = Expr2; class CTE { constructor(name, union) { this.name = name; this.union = union; } type = "Target.CTE"; } Target2.CTE = CTE; class Query2 { constructor(query, alias) { this.query = query; this.alias = alias; } type = "Target.Query"; } Target2.Query = Query2; class Table2 { constructor(table2, indexedBy) { this.table = table2; this.indexedBy = indexedBy; } type = "Target.Table"; } Target2.Table = Table2; class Join { constructor(left, right, joinType, on) { this.left = left; this.right = right; this.joinType = joinType; this.on = on; } type = "Target.Join"; } Target2.Join = Join; function source(from) { switch (from.type) { case "Target.Table": return from.table; case "Target.Join": return source(from.left); default: return void 0; } } Target2.source = source; })(Target || (Target = {})); // node_modules/rado/dist/define/Expr.js var { fromEntries, entries } = Object; var UnOpType = /* @__PURE__ */ ((UnOpType2) => { UnOpType2["Not"] = "Not"; UnOpType2["IsNull"] = "IsNull"; return UnOpType2; })(UnOpType || {}); var BinOpType = /* @__PURE__ */ ((BinOpType2) => { BinOpType2["Add"] = "Add"; BinOpType2["Subt"] = "Subt"; BinOpType2["Mult"] = "Mult"; BinOpType2["Mod"] = "Mod"; BinOpType2["Div"] = "Div"; BinOpType2["Greater"] = "Greater"; BinOpType2["GreaterOrEqual"] = "GreaterOrEqual"; BinOpType2["Less"] = "Less"; BinOpType2["LessOrEqual"] = "LessOrEqual"; BinOpType2["Equals"] = "Equals"; BinOpType2["NotEquals"] = "NotEquals"; BinOpType2["And"] = "And"; BinOpType2["Or"] = "Or"; BinOpType2["Like"] = "Like"; BinOpType2["Glob"] = "Glob"; BinOpType2["Match"] = "Match"; BinOpType2["In"] = "In"; BinOpType2["NotIn"] = "NotIn"; BinOpType2["Concat"] = "Concat"; return BinOpType2; })(BinOpType || {}); var ExprType = /* @__PURE__ */ ((ExprType2) => { ExprType2["UnOp"] = "ExprData.UnOp"; ExprType2["BinOp"] = "ExprData.BinOp"; ExprType2["Field"] = "ExprData.Field"; ExprType2["Param"] = "ExprData.Param"; ExprType2["Call"] = "ExprData.Call"; ExprType2["Query"] = "ExprData.Query"; ExprType2["Record"] = "ExprData.Record"; ExprType2["Row"] = "ExprData.Row"; ExprType2["Map"] = "ExprData.Map"; ExprType2["Filter"] = "ExprData.Filter"; ExprType2["Merge"] = "ExprData.Merge"; return ExprType2; })(ExprType || {}); var ExprData; ((ExprData2) => { class UnOp { constructor(op, expr) { this.op = op; this.expr = expr; } type = "ExprData.UnOp"; } ExprData2.UnOp = UnOp; class BinOp { constructor(op, a, b) { this.op = op; this.a = a; this.b = b; } type = "ExprData.BinOp"; } ExprData2.BinOp = BinOp; class Field { constructor(expr, field) { this.expr = expr; this.field = field; } type = "ExprData.Field"; } ExprData2.Field = Field; class Param { constructor(param) { this.param = param; } type = "ExprData.Param"; } ExprData2.Param = Param; class Call { constructor(method, params) { this.method = method; this.params = params; } type = "ExprData.Call"; } ExprData2.Call = Call; class Query2 { constructor(query) { this.query = query; } type = "ExprData.Query"; } ExprData2.Query = Query2; class Record { constructor(fields) { this.fields = fields; } type = "ExprData.Record"; } ExprData2.Record = Record; class Merge { constructor(a, b) { this.a = a; this.b = b; } type = "ExprData.Merge"; } ExprData2.Merge = Merge; class Row { constructor(target) { this.target = target; } type = "ExprData.Row"; } ExprData2.Row = Row; class Map2 { constructor(target, result) { this.target = target; this.result = result; } type = "ExprData.Map"; } ExprData2.Map = Map2; class Filter { constructor(target, condition) { this.target = target; this.condition = condition; } type = "ExprData.Filter"; } ExprData2.Filter = Filter; function create2(input) { if (input === null || input === void 0) return new ExprData2.Param(new ParamData.Value(null)); if (Expr.hasExpr(input)) input = input[Expr.ToExpr](); if (Expr.isExpr(input)) return input[Expr.Data]; if (input && typeof input === "object" && !Array.isArray(input)) return new ExprData2.Record( fromEntries( entries(input).map(([key, value]) => [key, ExprData2.create(value)]) ) ); return new ExprData2.Param(new ParamData.Value(input)); } ExprData2.create = create2; function createAll(...inputs) { return inputs.map(create2); } ExprData2.createAll = createAll; })(ExprData || (ExprData = {})); var Expr = class _Expr { constructor(expr) { this[_Expr.Data] = expr; this[_Expr.IsExpr] = true; } asc() { return { expr: this[_Expr.Data], order: OrderDirection.Asc }; } desc() { return { expr: this[_Expr.Data], order: OrderDirection.Desc }; } not() { return new _Expr(new ExprData.UnOp("Not", this[_Expr.Data])); } or(that) { const a = this; const b = _Expr.create(that); if (b.isConstant(true) || a.isConstant(false)) return b; if (a.isConstant(true) || b.isConstant(false)) return this; return new _Expr( new ExprData.BinOp("Or", a[_Expr.Data], b[_Expr.Data]) ); } and(that) { const a = this; const b = _Expr.create(that); if (b.isConstant(true) || a.isConstant(false)) return this; if (a.isConstant(true) || b.isConstant(false)) return b; return new _Expr( new ExprData.BinOp("And", a[_Expr.Data], b[_Expr.Data]) ); } is(that) { if (that === null || _Expr.isExpr(that) && that.isConstant(null)) return this.isNull(); return new _Expr( new ExprData.BinOp( "Equals", this[_Expr.Data], ExprData.create(that) ) ); } isConstant(value) { const expr = this[_Expr.Data]; switch (expr.type) { case "ExprData.Param": const param = expr.param; switch (param.type) { case ParamType.Value: return param.value === value; default: return false; } default: return false; } } isNot(that) { if (that === null || _Expr.isExpr(that) && that.isConstant(null)) return this.isNotNull(); return new _Expr( new ExprData.BinOp( "NotEquals", this[_Expr.Data], ExprData.create(that) ) ); } isNull() { return new _Expr(new ExprData.UnOp("IsNull", this[_Expr.Data])); } isNotNull() { return this.isNull().not(); } isIn(that) { return new _Expr( new ExprData.BinOp("In", this[_Expr.Data], ExprData.create(that)) ); } isNotIn(that) { return new _Expr( new ExprData.BinOp( "NotIn", this[_Expr.Data], ExprData.create(that) ) ); } isGreater(that) { return new _Expr( new ExprData.BinOp( "Greater", this[_Expr.Data], ExprData.create(that) ) ); } isGreaterOrEqual(that) { return new _Expr( new ExprData.BinOp( "GreaterOrEqual", this[_Expr.Data], ExprData.create(that) ) ); } isLess(that) { return new _Expr( new ExprData.BinOp("Less", this[_Expr.Data], ExprData.create(that)) ); } isLessOrEqual(that) { return new _Expr( new ExprData.BinOp( "LessOrEqual", this[_Expr.Data], ExprData.create(that) ) ); } add(that, ...rest) { return new _Expr( ExprData.createAll(this, that, ...rest).reduce( (a, b) => new ExprData.BinOp("Add", a, b) ) ); } subtract(that, ...rest) { return new _Expr( ExprData.createAll(this, that, ...rest).reduce( (a, b) => new ExprData.BinOp("Subt", a, b) ) ); } multiply(that, ...rest) { return new _Expr( ExprData.createAll(this, that, ...rest).reduce( (a, b) => new ExprData.BinOp("Mult", a, b) ) ); } remainder(that) { return new _Expr( new ExprData.BinOp("Mod", this[_Expr.Data], ExprData.create(that)) ); } divide(that, ...rest) { return new _Expr( ExprData.createAll(this, that, ...rest).reduce( (a, b) => new ExprData.BinOp("Div", a, b) ) ); } concat(that, ...rest) { return new _Expr( ExprData.createAll(this, that, ...rest).reduce( (a, b) => new ExprData.BinOp("Concat", a, b) ) ); } like(that) { return new _Expr( new ExprData.BinOp("Like", this[_Expr.Data], ExprData.create(that)) ); } glob(that) { return new _Expr( new ExprData.BinOp("Glob", this[_Expr.Data], ExprData.create(that)) ); } match(that) { return new _Expr( new ExprData.BinOp( "Match", this[_Expr.Data], ExprData.create(that) ) ); } with(that) { return new _Expr( new ExprData.Merge(this[_Expr.Data], ExprData.create(that)) ); } /** * Dynamic expressions allow accessing runtime fields of JSON properties * through a Proxy. * * Expr.value({a: {b: 1}}).dynamic().a.b.is(1) // true **/ dynamic(...path) { return new Proxy( (...args) => { const method = path[path.length - 1]; const e = path.length > 1 ? this.get(path.slice(0, -1).join(".")) : this; return e[method]?.apply(e, args); }, { get: (_, key) => { const e = path.length > 0 ? this.get(path.join(".")) : this; if (typeof key !== "string") return e[key]; return this.dynamic(...path, key); } } ); } at(index) { return this.get(`[${Number(index)}]`); } includes(value) { return _Expr.create(value).isIn(this); } filter(fn) { const alias = randomAlias(); const target = new Target.Expr(this[_Expr.Data], alias); return new _Expr( new ExprData.Filter( target, ExprData.create(fn(new _Expr(new ExprData.Row(target)).dynamic())) ) ); } map(fn) { const alias = randomAlias(); const target = new Target.Expr(this[_Expr.Data], alias); return new _Expr( new ExprData.Map( target, ExprData.create(fn(new _Expr(new ExprData.Row(target)).dynamic())) ) ); } sure() { return this; } get(name) { switch (this[_Expr.Data].type) { case "ExprData.Record": if (name in this[_Expr.Data].fields) return new _Expr(this[_Expr.Data].fields[name]); default: return new _Expr(new ExprData.Field(this[_Expr.Data], name)); } } static [Symbol.hasInstance](instance) { return instance?.[_Expr.IsExpr]; } }; ((Expr2) => { Expr2.Data = Symbol("Expr.Data"); Expr2.IsExpr = Symbol("Expr.IsExpr"); Expr2.ToExpr = Symbol("Expr.ToExpr"); Expr2.NULL = create2(null); function value(value2, inline = false) { if (isExpr(value2)) return value2; return new Expr2(new ExprData.Param(new ParamData.Value(value2, inline))); } Expr2.value = value; function get2(expr, field) { return new Expr2(new ExprData.Field(expr[Expr2.Data], field)); } Expr2.get = get2; function create2(input) { if (isExpr(input)) return input; return new Expr2(ExprData.create(input)); } Expr2.create = create2; function and(...conditions) { return conditions.map(create2).reduce((condition, expr) => condition.and(expr), value(true)); } Expr2.and = and; function or(...conditions) { return conditions.map(create2).reduce((condition, expr) => condition.or(expr), value(false)); } Expr2.or = or; function hasExpr(input) { return input && (typeof input === "function" || typeof input === "object") && input[Expr2.ToExpr]; } Expr2.hasExpr = hasExpr; function isExpr(input) { return input instanceof Expr2; } Expr2.isExpr = isExpr; })(Expr || (Expr = {})); // node_modules/rado/dist/util/Callable.js var { setPrototypeOf } = Object; var Callable = class { constructor(fn) { return setPrototypeOf(fn, new.target.prototype); } }; // node_modules/rado/dist/define/Column.js var ColumnType = /* @__PURE__ */ ((ColumnType2) => { ColumnType2["String"] = "String"; ColumnType2["Integer"] = "Integer"; ColumnType2["Number"] = "Number"; ColumnType2["Boolean"] = "Boolean"; ColumnType2["Json"] = "Json"; return ColumnType2; })(ColumnType || {}); var Column; ((Column2) => { Column2.Data = Symbol("Column.Data"); Column2.Type = Symbol("Column.Type"); function isColumn(input) { return Boolean(input[Column2.Data]); } Column2.isColumn = isColumn; })(Column || (Column = {})); var ValueColumn = class _ValueColumn extends Callable { [Column.Data]; constructor(data) { super(() => this); this[Column.Data] = data; } get nullable() { return new _ValueColumn({ ...this[Column.Data], nullable: true }); } get unique() { return new _ValueColumn({ ...this[Column.Data], unique: true }); } get autoIncrement() { return new OptionalColumn({ ...this[Column.Data], autoIncrement: true }); } primaryKey(create2) { return new PrimaryColumn({ ...this[Column.Data], primaryKey: true, defaultValue: create2 ? () => ExprData.create(create2()) : this[Column.Data].defaultValue }); } references(column2) { return new ForeignKey({ ...this[Column.Data], references() { return ExprData.create(Expr.isExpr(column2) ? column2 : column2()); } }); } default(value) { return new OptionalColumn({ ...this[Column.Data], defaultValue: createDefaultValue(value) }); } }; function createDefaultValue(value) { return typeof value === "function" && !Expr.isExpr(value) ? () => ExprData.create(value()) : ExprData.create(value); } var Action = /* @__PURE__ */ ((Action2) => { Action2["NoAction"] = "no action"; Action2["Restrict"] = "restrict"; Action2["SetNull"] = "set null"; Action2["SetDefault"] = "set default"; Action2["Cascade"] = "cascade"; return Action2; })(Action || {}); var ForeignKey = class _ForeignKey extends ValueColumn { onUpdate(value) { return new _ForeignKey({ ...this[Column.Data], onUpdate: value }); } onDelete(value) { return new _ForeignKey({ ...this[Column.Data], onDelete: value }); } }; var OptionalColumn = class extends ValueColumn { [Column.IsOptional]; }; var PrimaryColumn = class extends ValueColumn { [Column.IsPrimary]; }; var ObjectColumn = class _ObjectColumn extends Callable { [Column.Data]; constructor(data) { super(() => this); this[Column.Data] = data; } get nullable() { return new _ObjectColumn({ ...this[Column.Data], nullable: true }); } get unique() { return new _ObjectColumn({ ...this[Column.Data], unique: true }); } defaultValue(value) { return new OptionalObjectColumn({ ...this[Column.Data], defaultValue: createDefaultValue(value) }); } }; var OptionalObjectColumn = class extends ObjectColumn { [Column.IsOptional]; }; var UnTyped = class _UnTyped extends Callable { [Column.Data]; constructor(data = {}) { super((name) => { return new ValueColumn({ ...data, name }); }); this[Column.Data] = data; } get nullable() { return new _UnTyped({ ...this[Column.Data], nullable: true }); } get unique() { return new _UnTyped({ ...this[Column.Data], unique: true }); } get string() { return new ValueColumn({ ...this[Column.Data], type: "String" /* String */ }); } get integer() { return new ValueColumn({ ...this[Column.Data], type: "Integer" /* Integer */ }); } get number() { return new ValueColumn({ ...this[Column.Data], type: "Number" /* Number */ }); } get boolean() { return new ValueColumn({ ...this[Column.Data], type: "Boolean" /* Boolean */ }); } get json() { return new ValueColumn({ ...this[Column.Data], type: "Json" /* Json */ }); } get object() { return new ObjectColumn({ ...this[Column.Data], type: "Json" /* Json */ }); } get array() { return new ValueColumn({ ...this[Column.Data], type: "Json" /* Json */ }); } }; var column = new UnTyped(); // node_modules/rado/dist/define/Functions.js function get(target, method) { if (method in target) return target[method]; return target[method] = (...args) => { return new Expr(new ExprData.Call(method, args.map(ExprData.create))); }; } var Functions = new Proxy(/* @__PURE__ */ Object.create(null), { get }); // node_modules/rado/dist/lib/Statement.js var SEPARATE = ", "; var WHITESPACE = " "; var NEWLINE = "\n"; var INSERT_PARAM = "?"; var Statement = class { constructor(sanitizer, options = {}) { this.sanitizer = sanitizer; this.options = options; } sql = ""; paramData = []; currentIndent = ""; /** * UNSAFE * Adds a string without applying escaping */ raw(query) { if (!query) return this; this.sql += query; return this; } /** * UNSAFE * Adds a space if the statement is not empty, and then adds the given string * without applying escaping */ add(addition) { if (!addition) return this; return this.space().raw(addition); } /** * UNSAFE * Adds a newline if the statement is not empty, and then adds the given * string without applying escaping */ addLine(addition) { if (!addition) return this; return this.newline().raw(addition); } /** * Adds a space if the statement is not empty */ space() { if (this.sql === "") return this; return this.raw(WHITESPACE); } /** * Increases the indentation level */ indent() { this.currentIndent = this.currentIndent + " "; return this; } /** * Decreases the indentation level */ dedent() { this.currentIndent = this.currentIndent.slice(0, -2); return this; } /** * Adds a newline */ newline(spaceRequired = true) { if (this.options.skipNewlines) if (spaceRequired) return this.space(); else return this; return this.raw(NEWLINE + this.currentIndent); } /** * Adds an identifier, applies escaping */ identifier(name) { return this.raw(this.sanitizer.escapeIdentifier(name)); } /** * Adds a space if the statement is not empty, and then adds an identifier */ addIdentifier(name) { return this.space().identifier(name); } /** * Adds a value, applies escaping */ value(value) { this.paramData.push(new ParamData.Value(value)); return this.raw(INSERT_PARAM); } /** * Adds a space if the statement is not empty, and then adds a value */ addValue(value) { return this.space().value(value); } /** * Adds a parameter */ param(data) { this.paramData.push(data); return this.raw(INSERT_PARAM); } /** * Adds a space if the statement is not empty, and then adds a parameter */ addParam(data) { return this.space().param(data); } /** * Opens a parenthesis and indents the next line */ openParenthesis() { return this.raw("(").indent().newline(false); } /** * Closes a parenthesis and dedents the next line */ closeParenthesis() { return this.dedent().newline(false).raw(")"); } /** * Adds parenthesis on start and end, and a seperator to the output on * each iteration */ *call(parts, separator = SEPARATE) { if (parts.length === 0) return this.raw("()"); this.openParenthesis(); yield* this.separate(parts, separator); this.closeParenthesis(); } /** * Adds seperator to the output on each iteration */ *separate(parts, separator = SEPARATE) { for (let i = 0; i < parts.length; i++) { if (i > 0) this.raw(separator).newline(false); yield parts[i]; } } /** * Returns true if the statement is empty */ isEmpty() { return this.sql === ""; } /** * Returns the parameter values in the order they appear in the query string */ params(input) { return this.paramData.map((param) => { if (param.type === ParamType.Named) { if (input && param.name in input) return this.sanitizer.formatParamValue(input[param.name]); throw new TypeError(`Missing parameter ${param.name}`); } return this.sanitizer.formatParamValue(param.value); }); } /** * For debug purposes this will apply parameter values to the query string, * and return the result */ inlineParams() { let index = 0; return this.sql.replace(/\?/g, () => { const param = this.paramData[index]; index++; switch (param.type) { case ParamType.Named: return `?${param.name}`; case ParamType.Value: return this.sanitizer.escapeValue(param.value); } }); } toString() { return this.sql; } }; // node_modules/rado/dist/define/Schema.js var Schema; ((Schema2) => { function create2(schema2) { const queries = []; queries.push(new QueryData.CreateTable({ table: schema2, ifNotExists: true })); const meta = schema2.meta(); if (meta.indexes) for (const index of Object.values(meta.indexes)) queries.push( new QueryData.CreateIndex({ table: schema2, index, ifNotExists: true }) ); return new QueryData.Batch({ queries }); } Schema2.create = create2; function removeLeadingWhitespace(str) { return str.replace(/\n\s+/g, "\n"); } function recreateTable(table2, addedColumns) { const queries = []; const tempTable = { ...table2, name: `$$new_${table2.name}` }; queries.push(new QueryData.CreateTable({ table: tempTable })); queries.push( new QueryData.Insert({ into: tempTable, select: new QueryData.Select({ from: new Target.Table(table2), selection: new ExprData.Record( Object.fromEntries( Object.entries(table2.columns).map(([key, column2]) => [ key, addedColumns.has(key) ? (typeof column2.defaultValue === "function" ? column2.defaultValue() : column2.defaultValue) || Expr.NULL[Expr.Data] : new ExprData.Field( new ExprData.Row(new Target.Table(table2)), key ) ]) ) ) }) }) ); queries.push(new QueryData.DropTable({ table: table2, ifExists: true })); queries.push( new QueryData.AlterTable({ table: table2, renameTable: { from: tempTable.name } }) ); for (const index of Object.values(table2.meta().indexes)) queries.push(new QueryData.CreateIndex({ table: table2, index })); return queries; } function upgrade(formatter, local, schema2, verbose = true) { const columnNames = /* @__PURE__ */ new Set([ ...Object.keys(local.columns), ...Object.keys(schema2.columns) ]); const res = []; let recreate = false; for (const columnName of columnNames) { const localInstruction = local.columns[columnName]; const schemaCol = schema2.columns[columnName]; if (!localInstruction) { res.push( new QueryData.AlterTable({ table: schema2, addColumn: schemaCol }) ); if (verbose) console.log(`Adding column ${columnName}`); } else if (!schemaCol) { res.push( new QueryData.AlterTable({ table: schema2, dropColumn: columnName }) ); if (verbose) console.log(`Removing column ${columnName}`); } else { const { sql: instruction } = formatter.formatColumn( { stmt: new Statement(formatter) }, { ...schemaCol, references: void 0 } ); if (removeLeadingWhitespace(localInstruction) !== removeLeadingWhitespace(instruction)) { if (verbose) console.log(`Recreating because ${columnName} differs`); recreate = true; } } } if (recreate) { const added = res.filter( (query) => query.type === QueryType.AlterTable && Boolean(query.addColumn) ).map((query) => query.addColumn.name); return recreateTable(schema2, new Set(added)); } const meta = schema2.meta(); const schemaIndexes = new Map( Object.values(meta.indexes).map((index) => [index.name, index]) ); const indexNames = /* @__PURE__ */ new Set([ ...Object.keys(local.indexes), ...schemaIndexes.keys() ]); for (const indexName of indexNames) { const localInstruction = local.indexes[indexName]; const schemaIndex = schemaIndexes.get(indexName); if (!localInstruction) { res.push( new QueryData.CreateIndex({ table: schema2, index: schemaIndex }) ); if (verbose) console.log(`Adding index ${indexName}`); } else if (!schemaIndex) { res.unshift(new QueryData.DropIndex({ table: schema2, name: indexName })); if (verbose) console.log(`Removing index ${indexName}`); } else { const { sql: instruction } = formatter.compile( new QueryData.CreateIndex({ table: schema2, index: schemaIndex }) ); if (removeLeadingWhitespace(localInstruction) !== removeLeadingWhitespace(instruction)) { if (verbose) console.log(`Recreating index ${indexName}`); res.unshift(new QueryData.DropIndex({ table: schema2, name: indexName })); res.push( new QueryData.CreateIndex({ table: schema2, index: schemaIndex }) ); } } } return res; } Schema2.upgrade = upgrade; })(Schema || (Schema = {})); // node_modules/rado/dist/define/VirtualTable.js var { create, entries: entries2 } = Object; var VirtualTable; ((VirtualTable2) => { VirtualTable2.Data = Symbol("VirtualTable.Data"); })(VirtualTable || (VirtualTable = {})); function createVirtualTable(data) { const cache = create(null); function call(...args) { const isConditionalRecord = args.length === 1 && !Expr.isExpr(args[0]); const conditions = isConditionalRecord ? entries2(args[0]).map(([key, value]) => { return new Expr( new ExprData.BinOp( BinOpType.Equals, new ExprData.Field(new ExprData.Row(data.target), key), ExprData.create(value) ) ); }) : args; return data.select(conditions); } return new Proxy(call, { get(_, column2) { if (column2 === VirtualTable.Data) return data; if (column2 === Expr.ToExpr) return new Expr(new ExprData.Row(data.target)); if (column2 in cache) return cache[column2]; return (cache[column2] = new Expr( new ExprData.Field(new ExprData.Row(data.target), column2) )).dynamic(); } }); } // node_modules/rado/dist/define/Query.js var { keys, assign, fromEntries: fromEntries2 } = Object; var QueryType = /* @__PURE__ */ ((QueryType2) => { QueryType2["Insert"] = "QueryData.Insert"; QueryType2["Select"] = "QueryData.Select"; QueryType2["Union"] = "QueryData.Union"; QueryType2["Update"] = "QueryData.Update"; QueryType2["Delete"] = "QueryData.Delete"; QueryType2["CreateTable"] = "QueryData.CreateTable"; QueryType2["AlterTable"] = "QueryData.AlterTable"; QueryType2["DropTable"] = "QueryData.DropTable"; QueryType2["CreateIndex"] = "QueryData.CreateIndex"; QueryType2["DropIndex"] = "QueryData.DropIndex"; QueryType2["Batch"] = "QueryData.Batch"; QueryType2["Transaction"] = "QueryData.Transaction"; QueryType2["Raw"] = "QueryData.Raw"; return QueryType2; })(QueryType || {}); var QueryData; ((QueryData2) => { class Data { constructor(data) { assign(this, data); } with(data) { return new this.constructor({ ...this, ...data }); } } let UnionOperation; ((UnionOperation2) => { UnionOperation2["Union"] = "Union"; UnionOperation2["UnionAll"] = "UnionAll"; UnionOperation2["Intersect"] = "Intersect"; UnionOperation2["Except"] = "Except"; })(UnionOperation = QueryData2.UnionOperation || (QueryData2.UnionOperation = {})); class Union2 extends Data { type = "QueryData.Union"; } QueryData2.Union = Union2; class Select2 extends Data { type = "QueryData.Select"; } QueryData2.Select = Select2; class Insert2 extends Data { type = "QueryData.Insert"; } QueryData2.Insert = Insert2; class Update2 extends Data { type = "QueryData.Update"; } QueryData2.Update = Update2; class Delete2 extends Data { type = "QueryData.Delete"; } QueryData2.Delete = Delete2; class CreateTable2 extends Data { type = "QueryData.CreateTable"; } QueryData2.CreateTable = CreateTable2; class AlterTable extends Data { type = "QueryData.AlterTable"; } QueryData2.AlterTable = AlterTable; class DropTable extends Data { type = "QueryData.DropTable"; } QueryData2.DropTable = DropTable; class CreateIndex extends Data { type = "QueryData.CreateIndex"; } QueryData2.CreateIndex = CreateIndex; class DropIndex extends Data { type = "QueryData.DropIndex"; } QueryData2.DropIndex = DropIndex; class Batch2 extends Data { type = "QueryData.Batch"; } QueryData2.Batch = Batch2; let TransactionOperation; ((TransactionOperation2) => { TransactionOperation2["Begin"] = "Begin"; TransactionOperation2["Commit"] = "Commit"; TransactionOperation2["Rollback"] = "Rollback"; })(TransactionOperation = QueryData2.TransactionOperation || (QueryData2.TransactionOperation = {})); class Transaction extends Data { type = "QueryData.Transaction"; } QueryData2.Transaction = Transaction; class Raw extends Data { type = "QueryData.Raw"; constructor(data) { if (data.strings.some((chunk) => chunk.includes("?"))) throw new TypeError("SQL injection hazard"); super(data); } } QueryData2.Raw = Raw; })(QueryData || (QueryData = {})); var Query = class _Query { constructor(query) { this[_Query.Data] = query; } next(cursor) { return new _Query( new QueryData.Batch( this[_Query.Data].with({ queries: [this[_Query.Data], cursor[_Query.Data]] }) ) ); } on(driver) { return driver.executeQuery(this[_Query.Data]); } toSql(driver, options = { forceInline: true }) { return driver.formatter.compile(this[_Query.Data], options).sql; } toJSON() { return this[_Query.Data]; } addWhere(where) { const query = this[_Query.Data]; const conditions = where.slice(); if (query.where) conditions.push(new Expr(query.where)); return query.with({ where: Expr.and(...conditions)[Expr.Data] }); } }; ((Query2) => { Query2.Data = Symbol("Query.Data"); function isQuery(input) { return input !== null && Boolean(Query2.Data in input); } Query2.isQuery = isQuery; })(Query || (Query = {})); var Batch = class extends Query { constructor(queries) { super(new QueryData.Batch({ queries })); this.queries = queries; } next(cursor) { return new Query( new QueryData.Batch({ queries: [...this[Query.Data].queries, cursor[Query.Data]] }) ); } }; var CreateTable = class extends Query { constructor(table2) { super(Schema.create(table2)); this.table = table2; } }; var Delete = class _Delete extends Query { constructor(query) { super(query); } where(...where) { return new _Delete(this.addWhere(where)); } orderBy(...orderBy) { return new _Delete(this[Query.Data].with({ orderBy })); } take(limit) { return new _Delete(this[Query.Data].with({ limit })); } skip(offset) { return new _Delete(this[Query.Data].with({ offset })); } }; var Insert = class _Insert extends Query { constructor(query) { super(query); } returning(selection) { return new _Insert( new QueryData.Insert({ ...this[Query.Data], selection: ExprData.create(selection) }) ); } }; var InsertOne = class extends Query { constructor(query) { super(query); } returning(selection) { return new Insert( new QueryData.Insert({ ...this[Query.Data], selection: ExprData.create(selection), singleResult: true }) ); } }; var InsertInto = class { constructor(into) { this.into = into; } selection(query) { return new Insert( new QueryData.Insert({ into: this.into, select: query[Query.Data] }) ); } values(...data) { return new Insert(new QueryData.Insert({ into: this.into, data })); } }; function joinTarget(joinType, query, to, on) { const toQuery = Query.isQuery(to) ? to[Query.Data] : void 0; const target = toQuery ? toQuery.from : new Target.Table(to[Table.Data]); if (!query.from || !target) throw new Error("No from clause"); const conditions = [...on]; if (toQuery) { const where = toQuery.where; if (where) conditions.push(new Expr(where)); } return new Target.Join( query.from, target, joinType, Expr.and(...conditions)[Expr.Data] ); } function columnsOf(expr) { switch (expr.type) { case ExprType.Record: return keys(expr.fields); case ExprType.Row: switch (expr.target.type) { case TargetType.Table: return keys(expr.target.table.columns); default: throw new Error("Could not retrieve CTE columns"); } default: throw new Error("Could not retrieve CTE columns"); } } function makeRecursiveUnion(initial, createUnion, operator) { const name = randomAlias(); const cols = columnsOf(initial.selection); const union = new QueryData.Union({ a: initial, operator, b: () => createUnion()[Query.Data] }); const target = new Target.CTE(name, union); const row = new ExprData.Row(target); const selection = new ExprData.Record( fromEntries2(cols.map((col) => [col, new ExprData.Field(row, col)])) ); const select = (conditions) => { const where = Expr.and(...conditions)[Expr.Data]; return new Select( new QueryData.Select({ selection, from: target, where }) ); }; const cte = createVirtualTable({ name, target, select }); return cte; } var RecursiveUnion = class { constructor(initialSelect) { this.initialSelect = initialSelect; } union(create2) { return makeRecursiveUnion( this.initialSelect, create2, "Union" /* Union */ ); } unionAll(create2) { return makeRecursiveUnion( this.initialSelect, create2, "UnionAll" /* UnionAll */ ); } }; var Union = class _Union extends Query { constructor(query) { super(query); } union(query) { return new _Union( new QueryData.Union({ a: this[Query.Data], operator: "Union", b: query[Query.Data] }) ); } unionAll(query) { return new _Union( new QueryData.Union({ a: this[Query.Data], operator: "UnionAll", b: query[Query.Data] }) ); } except(query) { return new _Union( new QueryData.Union({ a: this[Query.Data], operator: "Except", b: query[Query.Data] }) ); } intersect(query) { return new _Union( new QueryData.Union({ a: this[Query.Data], operator: "Intersect", b: query[Query.Data] }) ); } }; var Select = class _Select extends Union { constructor(query) { super(query); } from(table2) { const virtual = table2[VirtualTable.Data]; return new _Select( this[Query.Data].with({ from: virtual?.target || new Target.Table(table2) }) ); } indexedBy(index) { const from = this[Query.Data].from; switch (from?.type) { case TargetType.Table: return new _Select( this[Query.Data].with({ from: new Target.Table(from.table, index) }) ); default: throw new Error("Cannot index by without table target"); } } leftJoin(that, ...on) { const query = this[Query.Data]; return new _Select( this[Query.Data].with({ from: joinTarget("left", query, that, on) }) ); } innerJoin(that, ...on) { const query = this[Query.Data]; return new _Select( this[Query.Data].with({ from: joinTarget("inner", query, that, on) }) ); } select(selection) { return new _Select( this[Query.Data].with({ selection: ExprData.create(selection) }) ); } count() { return new SelectFirst( this[Query.Data].with({ selection: Functions.count()[Expr.Data], singleResult: true }) ); } orderBy(...orderBy) { return new _Select( this[Query.Data].with({ orderBy: orderBy.map((e) => { return Expr.isExpr(e) ? e.asc() : e; }) }) ); } groupBy(...groupBy) { return new _Select( this[Query.Data].with({ groupBy: groupBy.map(ExprData.create) }) ); } maybeFirst() { return new SelectFirst(this[Query.Data].with({ singleResult: true })); } first() { return new SelectFirst( this[Query.Data].with({ singleResult: true, validate: true }) ); } where(...where) { return new _Select(this.addWhere(where)); } take(limit) { return new _Select(this[Query.Data].with({ limit })); } skip(offset) { return new _Select(this[Query.Data].with({ offset })); } [Expr.ToExpr]() { return new Expr(new ExprData.Query(this[Query.Data])); } }; var SelectFirst = class _SelectFirst extends Query { constructor(query) { super(query); } from(table2) { return new Select(this[Query.Data].with({ from: new Target.Table(table2) })); } leftJoin(that, ...on) { const query = this[Query.Data]; return new _SelectFirst( this[Query.Data].with({ from: joinTarget("left", query, that, on) }) ); } innerJoin(that, ...on) { const query = this[Query.Data]; return new _SelectFirst( this[Query.Data].with({ from: joinTarget("inner", query, that, on) }) ); } select(selection) { return new _SelectFirst( this[Query.Data].with({ selection: ExprData.create(selection) }) ); } orderBy(...orderBy) { return new _SelectFirst( this[Query.Data].with({ orderBy }) ); } groupBy(...groupBy) { return new _SelectFirst( this[Query.Data].with({ groupBy: groupBy.map(ExprData.create) }) ); } where(...where) { return new _SelectFirst(this.addWhere(where)); } take(limit) { return new _SelectFirst(this[Query.Data].with({ limit })); } skip(offset) { return new _SelectFirst(this[Query.Data].with({ offset })); } all() { return new Select(this[Query.Data].with({ singleResult: false })); } [Expr.ToExpr]() { return new Expr(new ExprData.Query(this[Query.Data])); } }; var TableSelect = class extends Select { constructor(table2, conditions = []) { const target = new Target.Table(table2); super( new QueryData.Select({ from: target, selection: new ExprData.Row(target), where: Expr.and(...conditions)[Expr.Data] }) ); this.table = table2; } as(alias) { return createTable({ ...this.table, alias }); } create() { return new CreateTable(this.table); } insert(input) { if (input instanceof Select) { return this.insertSelect(input); } else if (Array.isArray(input)) { return this.insertAll(input); } else { return this.insertOne(input); } } insertSelect(query) { return new Insert( new QueryData.Insert({ into: this.table, select: query[Query.Data] }) ); } insertOne(record) { return new InsertOne( new QueryData.Insert({ into: this.table, data: [record], selection: new ExprData.Row(new Target.Table(this.table)), singleResult: true }) ); } insertAll(data) { return new InsertInto(this.table).values(...data); } set(data) { return new Update( new QueryData.Update({ table: this.table, where: this[Query.Data].where }) ).set(data); } delete() { return new Delete( new QueryData.Delete({ table: this.table, where: this[Query.Data].where }) ); } get(name) { return new Expr( new ExprData.Field(new ExprData.Row(new Target.Table(this.table)), name) ); } }; var Update = class _Update extends Query { set(set) { return new _Update(this[Query.Data].with({ set })); } where(...where) { return new _Update(this.addWhere(where)); } take(limit) { return new _Update(this[Query.Data].with({ limit })); } skip(offset) { return new _Update(this[Query.Data].with({ offset })); } }; // node_modules/rado/dist/define/Table.js var { assign: assign2, keys: keys2, entries: entries3, fromEntries: fromEntries3, getOwnPropertyDescriptors, getPrototypeOf, setPrototypeOf: setPrototypeOf2, defineProperty } = Object; var TableData = class { constructor(data) { assign2(this, data); } }; var Table; ((Table2) => { Table2.Data = Symbol("Table.Data"); Table2.Indexes = Symbol("Table.Indexes"); Table2.PrimaryKey = Symbol("Table.PrimaryKey"); })(Table || (Table = {})); function createTable(data) { const target = new Target.Table(data); const call = { [data.name]: function(...args) { const isConditionalRecord = args.length === 1 && !Expr.isExpr(args[0]); const conditions = isConditionalRecord ? entries3(args[0]).map(([key, value]) => { const column2 = data.columns[key]; if (!column2) throw new Error(`Column ${key} not found`); return new Expr( new ExprData.BinOp( BinOpType.Equals, new ExprData.Field(new ExprData.Row(target), key), ExprData.create(value) ) ); }) : args; return new TableSelect(data, conditions); } }[data.name]; const cols = keys2(data.columns); const row = new ExprData.Row(target); const expressions = fromEntries3( cols.map((name) => { let expr = new Expr(new ExprData.Field(row, name)); if (data.columns[name].type === ColumnType.Json) expr = expr.dynamic(); return [name, expr]; }) ); const toExpr = () => new Expr(row); delete call.name; delete call.length; for (const [key, value] of entries3(expressions)) defineProperty(call, key, { value, enumerable: true, configurable: true }); defineProperty(call, Table.Data, { value: data, enumerable: false }); let indexes; defineProperty(call, Table.Indexes, { get() { if (indexes) return indexes; return indexes = data.meta().indexes; }, enumerable: false }); defineProperty(call, Expr.ToExpr, { value: toExpr, enumerable: false }); setPrototypeOf2(call, getPrototypeOf(data.definition)); return call; } function table(define) { const names = keys2(define); if (names.length !== 1) throw new Error("Table must have a single name"); const name = names[0]; const target = define[name]; const definition = "prototype" in target ? new target() : target; const columns = definition; const res = createTable( new TableData({ name, definition, columns: fromEntries3( entries3(getOwnPropertyDescriptors(columns)).filter(([name2]) => { const column2 = columns[name2]; return Column.isColumn(column2); }).map(([name2, descriptor]) => { const column2 = columns[name2]; const data = column2[Column.Data]; if (!data.type) throw new Error(`Column ${name2} has no type`); return [ name2, { ...data, type: data.type, name: data.name || name2, enumerable: descriptor.enumerable } ]; }) ), meta() { const createIndexes = define[Table.Indexes]; const indexes = createIndexes ? createIndexes.apply(res) : {}; const createPrimaryKey = define[Table.PrimaryKey]; const primaryKey = createPrimaryKey ? createPrimaryKey.apply(res).map(ExprData.create) : void 0; return { primaryKey, indexes: fromEntries3( entries3(indexes || {}).map(([key, index]) => { const indexName = `${name}.${key}`; return [key, { name: indexName, ...index.data }]; }) ) }; } }) ); return res; } ((table2) => { table2.indexes = Table.Indexes; table2.primaryKey = Table.PrimaryKey; })(table || (table = {})); export { Callable, OrderDirection, ParamType, ParamData, TargetType, Target, UnOpType, BinOpType, ExprType, ExprData, Expr, ColumnType, Action, column, Functions, Statement, Schema, Table, createTable, table, QueryType, QueryData, Query, Batch, RecursiveUnion };