alinea
Version:
[](https://npmjs.org/package/alinea) [](https://packagephobia.com/result?p=alinea)
1,826 lines (1,812 loc) • 47.1 kB
JavaScript
// 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
};