@palmares/drizzle-engine
Version:
This is the engine that wraps the hole drizzle interface in a way palmares can understand and have full control of
988 lines (961 loc) • 39 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
// src/engine.ts
import { databaseAdapter } from "@palmares/databases";
// src/fields/index.ts
import { adapterFields } from "@palmares/databases";
// src/fields/big-integer.ts
import { adapterBigIntegerFieldParser } from "@palmares/databases";
// src/fields/utils.ts
function getBuilderArgs(builder, callback) {
const defaultOptions = callback([]);
return (customAttributesArgs, customAttributesOptions) => {
const customAttributesDefined = new Set(Object.keys(customAttributesOptions || {}));
const builderArgs = Object.entries(customAttributesOptions || {}).map(([method, args]) => {
return [
method,
args.map((arg) => typeof arg === "object" ? JSON.stringify(arg) : arg.toString()).join(", ")
];
});
for (const [method, args] of defaultOptions) if (!customAttributesDefined.has(method)) builderArgs.push([
method,
args
]);
const builderArguments = builderArgs.map(([method, args]) => {
return (args || []).length > 0 ? `.${method}(${args})` : `.${method}()`;
}).join("");
return `${builder.withoutD ? "" : "d."}${builder.type}('${builder.databaseName}'${customAttributesArgs !== void 0 || builder.args ? `, ${customAttributesArgs !== void 0 ? JSON.stringify(customAttributesArgs) : builder.args}` : ""})${builderArguments}`;
};
}
__name(getBuilderArgs, "getBuilderArgs");
// src/fields/big-integer.ts
var bigIntegerFieldParser = adapterBigIntegerFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
const builderArgsFormatted = getBuilderArgs({
type: mainType === "sqlite" ? "integer" : mainType !== "postgres" ? "bigint" : defaultOptions.autoincrement ? "bigserial" : "bigint",
databaseName: field.databaseName,
args: "{ mode: 'number' }"
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
mainType === "sqlite" ? "{ autoIncrement: true }" : ""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
defaultOptions.default
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
if (mainType === "mysql" && defaultOptions.autoincrement) defaultBuilderArgs.push([
"autoIncrement",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
return builderArgsFormatted;
}, "translate")
});
// src/fields/boolean.ts
import { adapterBooleanFieldParser } from "@palmares/databases";
var booleanFieldParser = adapterBooleanFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
const builderArgsFormatted = getBuilderArgs({
type: mainType === "sqlite" ? "integer" : "boolean",
databaseName: field.databaseName,
args: mainType === "sqlite" ? "{ mode: 'number' }" : void 0
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (typeof defaultOptions.default === "boolean") if (mainType === "sqlite") defaultBuilderArgs.push([
"default",
defaultOptions.default ? "1" : "0"
]);
else defaultBuilderArgs.push([
"default",
JSON.stringify(defaultOptions.default)
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
return builderArgsFormatted;
}, "translate")
});
// src/fields/char.ts
import { adapterCharFieldParser } from "@palmares/databases";
var charFieldParser = adapterCharFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
return getBuilderArgs({
type: mainType === "sqlite" ? "text" : "varchar",
databaseName: field.databaseName,
args: `{ length: ${args.field.maxLength} }`
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
`"${defaultOptions.default}"`
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/date.ts
import { adapterDateFieldParser } from "@palmares/databases";
var dateFieldParser = adapterDateFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
return getBuilderArgs({
type: mainType === "sqlite" ? "text" : mainType === "postgres" ? "timestamp" : "datetime",
databaseName: field.databaseName,
args: mainType === "postgres" ? "{ precision: 6, withTimezone: true, mode: 'date' }" : mainType === "sqlite" ? "" : "{ fsp: 6, mode: 'date' }"
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
defaultOptions.default
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
if (field.autoNowAdd) if (mainType === "sqlite") defaultBuilderArgs.push([
"default",
"drzl.sql`(current_timestamp)`"
]);
else defaultBuilderArgs.push([
"defaultNow",
""
]);
if (field.autoNow) if (mainType === "sqlite") defaultBuilderArgs.push([
"$onUpdate",
"() => drzl.sql`CURRENT_TIMESTAMP`"
]);
else defaultBuilderArgs.push([
"$onUpdate",
"() => drzl.sql`now()`"
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/decimal.ts
import { adapterDecimalFieldParser } from "@palmares/databases";
var decimalFieldParser = adapterDecimalFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
return getBuilderArgs({
type: mainType === "sqlite" ? "real" : mainType === "postgres" ? "numeric" : "decimal",
databaseName: field.databaseName,
args: mainType === "sqlite" ? "" : `{ precision: ${field.decimalPlaces}, scale: ${field.maxDigits} }`
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
defaultOptions.default
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/enum.ts
import { adapterEnumFieldParser } from "@palmares/databases";
var enumFieldParse = adapterEnumFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
const optionsAsString = args.field.choices.map((choice) => `"${choice}"`).join(", ");
const enumVariableName = `${field.fieldName}Enum`;
if (mainType === "postgres") {
args.lazyEvaluate({
type: "enum",
data: `export const ${enumVariableName} = d.pgEnum('${field.databaseName}', [${optionsAsString}]);`
});
}
return getBuilderArgs({
type: mainType === "sqlite" ? "text" : mainType === "postgres" ? enumVariableName : "mysqlEnum",
databaseName: field.databaseName,
args: mainType === "sqlite" ? `{ enum: [${optionsAsString}] }` : mainType === "mysql" ? `[${optionsAsString}]` : "",
withoutD: mainType === "postgres" ? true : false
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
`${typeof defaultOptions.default === "string" ? `'${defaultOptions.default}'` : defaultOptions.default}`
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/field.ts
import { adapterFieldParser } from "@palmares/databases";
var fieldParser = adapterFieldParser({
// eslint-disable-next-line ts/require-await
translate: /* @__PURE__ */ __name(async (args) => {
if (args.customAttributes.type) return getBuilderArgs({
type: args.customAttributes.type,
databaseName: args.field.databaseName,
args: args.customAttributes.args
}, (defaultBuilderArgs) => defaultBuilderArgs)(args.customAttributes.args, args.customAttributes.options);
if (args.field.dbIndex) {
args.lazyEvaluate({
type: "index",
indexAttributes: {
modelName: args.modelName,
fieldName: args.field.fieldName,
databaseName: args.field.databaseName,
unique: args.field.unique
}
});
}
const fieldData = {
fieldName: args.field.fieldName,
primaryKey: args.field.primaryKey,
unique: args.field.unique,
nullable: args.field.allowNull,
dbIndex: args.field.dbIndex,
default: args.field.defaultValue,
autoincrement: args.field.isAuto,
databaseName: args.field.databaseName,
custom: args.customAttributes
};
return fieldData;
}, "translate")
});
// src/fields/foreign-key.ts
import { adapterForeignKeyFieldParser } from "@palmares/databases";
var foreignKeyFieldParser = adapterForeignKeyFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
args.lazyEvaluate({
type: "foreign-key",
fieldAttributes: {
...defaultOptions,
foreignData: {
...args.field,
toField: args.field.toField,
relatedToModelName: args.field.relatedTo,
relatedName: args.field.relatedName,
relationName: args.field.relationName,
action: args.field.onDelete
}
}
});
}, "translate")
});
// src/fields/integer.ts
import { adapterIntegerFieldParser } from "@palmares/databases";
var integerFieldParser = adapterIntegerFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
const mainType = args.engine.instance.mainType;
const builderArgsFormatted = getBuilderArgs({
type: mainType === "sqlite" ? "integer" : mainType !== "postgres" ? "bigint" : defaultOptions.autoincrement ? "serial" : "integer",
databaseName: field.databaseName,
args: mainType === "sqlite" ? "{ mode: 'number' }" : ""
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
mainType === "sqlite" ? "{ autoIncrement: true }" : ""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
defaultOptions.default
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
if (mainType === "mysql" && defaultOptions.autoincrement) defaultBuilderArgs.push([
"autoIncrement",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
return builderArgsFormatted;
}, "translate")
});
// src/fields/text.ts
import { adapterTextFieldParser } from "@palmares/databases";
var textFieldParser = adapterTextFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate(args);
const field = args.field;
return getBuilderArgs({
type: "text",
databaseName: field.databaseName,
args: void 0
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
`"${defaultOptions.default}"`
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/uuid.ts
import { adapterUuidFieldParser } from "@palmares/databases";
var uuidFieldParser = adapterUuidFieldParser({
translate: /* @__PURE__ */ __name(async (args) => {
const defaultOptions = await args.fieldParser.translate({
...args,
field: {
...args.field,
isAuto: false
}
});
const field = args.field;
const mainType = args.engine.instance.mainType;
if (field.isAuto && mainType !== "postgres") {
args.lazyEvaluate({
type: "uuid",
data: `import * as pdb from '@palmares/databases;'`
});
}
return getBuilderArgs({
type: mainType === "sqlite" ? "text" : mainType === "postgres" ? "uuid" : "varchar",
databaseName: field.databaseName,
args: mainType === "sqlite" || mainType === "postgres" ? "" : `{ length: 36 }`
}, (defaultBuilderArgs) => {
if (defaultOptions.primaryKey) defaultBuilderArgs.push([
"primaryKey",
""
]);
if (defaultOptions.default) defaultBuilderArgs.push([
"default",
`"${defaultOptions.default}"`
]);
if (defaultOptions.nullable !== true) defaultBuilderArgs.push([
"notNull",
""
]);
if (defaultOptions.unique) defaultBuilderArgs.push([
"unique",
""
]);
if (field.isAuto) {
if (mainType === "postgres") defaultBuilderArgs.push([
"defaultRandom",
""
]);
else defaultBuilderArgs.push([
"$defaultFn",
"() => pdb.generateUUID()"
]);
}
return defaultBuilderArgs;
})(args.customAttributes.args, args.customAttributes.options);
}, "translate")
});
// src/fields/index.ts
function createOneToOneRelation(modelName, modelFieldName, relatedModelName, relatedFieldName) {
return `args.one(${relatedModelName}, {
fields: [${modelName}.${modelFieldName}],
references: [${relatedModelName}.${relatedFieldName}]
})`;
}
__name(createOneToOneRelation, "createOneToOneRelation");
async function formatForeignKeyField(engine, modelName, translatedModel, _field, fieldTranslated, parseAgain) {
const foreignData = fieldTranslated.fieldAttributes.foreignData;
const data = await parseAgain({
fieldName: foreignData.toField,
modelName: foreignData.relatedToModelName,
optionsOverrideCallback: {
isAuto: /* @__PURE__ */ __name(() => foreignData.isAuto, "isAuto"),
primaryKey: /* @__PURE__ */ __name(() => foreignData.isPrimaryKey, "primaryKey"),
unique: /* @__PURE__ */ __name(() => foreignData.isUnique, "unique"),
allowNull: /* @__PURE__ */ __name(() => foreignData.allowNull, "allowNull"),
defaultValue: /* @__PURE__ */ __name(() => foreignData.defaultValue, "defaultValue"),
customAttributes: /* @__PURE__ */ __name(() => foreignData.customAttributes, "customAttributes"),
databaseName: /* @__PURE__ */ __name(() => foreignData.databaseName, "databaseName"),
dbIndex: /* @__PURE__ */ __name(() => foreignData.dbIndex, "dbIndex"),
fieldName: /* @__PURE__ */ __name(() => foreignData.fieldName, "fieldName"),
underscored: /* @__PURE__ */ __name(() => foreignData.underscored, "underscored"),
autoNow: /* @__PURE__ */ __name(() => false, "autoNow"),
autoNowAdd: /* @__PURE__ */ __name(() => false, "autoNowAdd"),
allowBlank: /* @__PURE__ */ __name(() => false, "allowBlank"),
maxLength: /* @__PURE__ */ __name(() => false, "maxLength")
}
});
const columnType = engine.instance.mainType === "postgres" ? "d.AnyPgColumn" : engine.instance.mainType === "sqlite" ? "d.AnySQLiteColumn" : "d.AnyMySqlColumn";
translatedModel.fields[fieldTranslated.fieldAttributes.fieldName] = `${data}.references((): ${columnType} => ${foreignData.relatedToModelName}.${foreignData.toField})`;
translatedModel.options.relationships ??= {};
translatedModel.options.relationships[modelName] ??= {};
translatedModel.options.relationships[modelName][foreignData.relationName] = createOneToOneRelation(modelName, fieldTranslated.fieldAttributes.fieldName, foreignData.relatedToModelName, foreignData.toField);
const ifIndirectOneRelation = createOneToOneRelation(foreignData.relatedToModelName, foreignData.toField, modelName, fieldTranslated.fieldAttributes.fieldName);
const ifIndirectManyRelation = `args.many(${modelName})`;
translatedModel.options.relationships[foreignData.relatedToModelName] ??= {};
translatedModel.options.relationships[foreignData.relatedToModelName][foreignData.relatedName] = fieldTranslated.fieldAttributes.unique ? ifIndirectOneRelation : ifIndirectManyRelation;
}
__name(formatForeignKeyField, "formatForeignKeyField");
var fields = adapterFields({
fieldsParser: new fieldParser(),
bigIntegerFieldParser: new bigIntegerFieldParser(),
charFieldParser: new charFieldParser(),
dateFieldParser: new dateFieldParser(),
decimalFieldParser: new decimalFieldParser(),
foreignKeyFieldParser: new foreignKeyFieldParser(),
integerFieldParser: new integerFieldParser(),
textFieldParser: new textFieldParser(),
uuidFieldParser: new uuidFieldParser(),
enumFieldParser: new enumFieldParse(),
booleanFieldParser: new booleanFieldParser(),
lazyEvaluateField: /* @__PURE__ */ __name(async (engine, modelName, translatedModel, fieldAttributes, fieldTranslated, parseAgain) => {
switch (fieldTranslated.type) {
case "enum": {
translatedModel.options.enums ??= [];
translatedModel.options.enums.push(fieldTranslated.data);
return translatedModel;
}
case "uuid": {
translatedModel.options.imports ??= /* @__PURE__ */ new Set();
translatedModel.options.imports.add(`import * as pdb from '@palmares/databases';`);
return translatedModel;
}
case "foreign-key": {
await formatForeignKeyField(engine, modelName, translatedModel, fieldAttributes, fieldTranslated, parseAgain);
return translatedModel;
}
case "index": {
if (modelName === fieldTranslated.indexAttributes.modelName) {
translatedModel.options.drizzleIndexes ??= [];
translatedModel.options.drizzleIndexes.push(fieldTranslated.indexAttributes);
return translatedModel;
}
break;
}
}
return void 0;
}, "lazyEvaluateField")
});
// src/model.ts
import { std } from "@palmares/core";
import { adapterModels } from "@palmares/databases";
var models = adapterModels({
// eslint-disable-next-line ts/require-await
translateOptions: /* @__PURE__ */ __name(async (_engine, modelName, options) => {
const optionsWithConjunctiveIndexes = options;
if (options.indexes) optionsWithConjunctiveIndexes.conjunctiveIndexes = options.indexes.map((index) => {
const indexFields = index.fields.join("_");
const indexAsCamel = indexFields.toLowerCase().replace(/(^([a-z]+))|([-_][a-z])/g, (group) => {
const groupWithoutDash = group.replace(/[-_]/, "");
const firstLetterUpper = groupWithoutDash[0].toUpperCase();
return firstLetterUpper + groupWithoutDash.slice(1);
});
const indexFieldsForOnClause = index.fields.map((field) => `table.${field}`).join(", ");
return ` ${modelName.slice(0, 1).toLowerCase() + modelName.slice(1)}${indexAsCamel}: d.${index.unique ? "uniqueIndex" : "index"}('${options.tableName || modelName}_${indexFields}').on(${indexFieldsForOnClause})`;
});
return {
...options
};
}, "translateOptions"),
translate: /* @__PURE__ */ __name(async (_engine, _modelName, _model, _fieldEntriesOfModel, _modelOptions, _customModelOptions, defaultTranslateCallback, _, __) => {
const { options: translatedOptions, fields: translatedAttributes } = await defaultTranslateCallback();
return {
fields: translatedAttributes,
options: translatedOptions
};
}, "translate"),
afterModelsTranslation: /* @__PURE__ */ __name(async (engine, models2) => {
let fileContent = "";
const cwd = await std.os.cwd();
const directoryName = std.files.dirname(engine.instance.output);
const [folderName, locationToRequire] = await Promise.all([
std.files.join(cwd, directoryName),
std.files.join(cwd, engine.instance.output)
]);
const imports = /* @__PURE__ */ new Set([
`/** Automatically generated by @palmares/drizzle-engine on ${(/* @__PURE__ */ new Date()).toISOString()} */
`,
`import * as d from '@palmares/drizzle-engine/${engine.instance.mainType === "postgres" ? "pg" : engine.instance.mainType === "sqlite" ? "sqlite" : "mysql"}-core';`
]);
const relationships = /* @__PURE__ */ new Map();
const tableType = engine.instance.mainType === "postgres" ? "pgTable" : engine.instance.mainType === "sqlite" ? "sqliteTable" : "mysqlTable";
for (let i = 0; i < models2.length; i++) {
const [modelName, model] = models2[i];
for (const [relationModelName, relations] of Object.entries(model.options.relationships || {})) {
relationships.set(relationModelName, {
...relationships.get(relationModelName) || {},
...relations
});
}
const indexesOfModel = model.options.drizzleIndexes || [];
const entriesOfFields = Object.entries(model.fields);
const hasEnums = (model.options.enums || []).length > 0;
if (model.options.imports) Array.from(model.options.imports || []).forEach((importString) => imports.add(importString));
const modelContentStarter = hasEnums ? model.options.enums.map((enumColumn) => enumColumn).join("\n") + "\n\n" : "";
const modelContent = `${modelContentStarter}export const ${modelName} = d.${tableType}('${model.options.tableName}', {
${entriesOfFields.map(([fieldName, fieldString]) => ` ${fieldName}: ${fieldString}`).join(",\n")}
}${indexesOfModel.length > 0 ? `, (table) => ({
${indexesOfModel.map((index) => ` ${index.fieldName}Idx: d.${index.unique ? "uniqueIndex" : "index"}('${model.options.tableName}_${index.databaseName}_idx').on(table.${index.fieldName})`).concat(model.options.conjunctiveIndexes || []).join(",\n")}
})` : ""});
`;
fileContent += modelContent;
models2[i] = [
modelName,
async () => {
try {
return Promise.resolve(__require(std.files.getPathToFileURL(locationToRequire))[modelName]);
} catch (e) {
return (await import(std.files.getPathToFileURL(locationToRequire)))[modelName];
}
}
];
}
if (relationships.size > 0) imports.add(`import * as drzl from '@palmares/drizzle-engine/drizzle';`);
for (const [modelName, relations] of relationships.entries()) {
fileContent += `export const ${modelName}Relations = drzl.relations(${modelName}, (args) => ({
${Object.entries(relations).map(([relationName, relation]) => ` ${relationName}: ${relation}`).join(",\n")}
}));
`;
}
await std.files.makeDirectory(folderName);
await std.files.writeFile(locationToRequire, `${Array.from(imports).join("\n")}
${fileContent}`);
const modelsImported = await Promise.all(models2.map(async ([modelName, model]) => [
modelName,
await model()
]));
return modelsImported;
}, "afterModelsTranslation")
});
// src/query.ts
import { adapterGetQuery, adapterOrderingQuery, adapterQuery, adapterRemoveQuery, adapterSearchQuery, adapterSetQuery } from "@palmares/databases";
import { and, asc, between, desc, eq, gt, gte, ilike, inArray, isNotNull, isNull, like, lt, lte, not, notBetween, notIlike, notInArray, notLike, or } from "drizzle-orm";
var getQuery = adapterGetQuery({
// eslint-disable-next-line ts/require-await
queryData: /* @__PURE__ */ __name(async (engine, args) => {
const selectArgs = Array.isArray(args.fields) && args.fields.length > 0 ? [
args.fields.reduce((acc, field) => ({
...acc,
[field]: args.modelOfEngineInstance[field]
}), {})
] : [];
let query2 = engine.instance.instance.select(...selectArgs).from(args.modelOfEngineInstance);
if (args.search) {
const searchAsObjectValues = Object.values(args.search);
if (searchAsObjectValues.length > 0) query2 = query2.where(and(...searchAsObjectValues));
}
if (typeof args.limit === "number") query2 = query2.limit(args.limit);
if (typeof args.offset === "number") query2 = query2.offset(args.offset);
if ((args.ordering || []).length > 0) query2 = query2.orderBy(...args.ordering || []);
return query2;
}, "queryData")
});
var setQuery = adapterSetQuery({
queryData: /* @__PURE__ */ __name(async (engine, args) => {
const engineInstanceOrTransaction = args.transaction || engine.instance.instance;
if (args.search && Object.keys(args.search).length > 0) {
if (engine.instance.mainType === "sqlite" || engine.instance.mainType === "postgres") {
return (await engineInstanceOrTransaction.update(args.modelOfEngineInstance).set(args.data[0]).where(and(...Object.values(args.search))).returning() || []).map((data) => [
false,
data
]);
} else {
await engineInstanceOrTransaction.update(args.modelOfEngineInstance).set(args.data[0]).where(and(...Object.values(args.search)));
const search2 = await engineInstanceOrTransaction.select().from(args.modelOfEngineInstance).where(and(...Object.values(args.search)));
return search2.map((each) => [
false,
each
]);
}
}
const inserts = await Promise.all(args.data.map(async (eachData) => {
if (engine.instance.mainType === "sqlite" || engine.instance.mainType === "postgres") {
return [
true,
(await engineInstanceOrTransaction.insert(args.modelOfEngineInstance).values(eachData).returning())[0]
];
}
const results = await engineInstanceOrTransaction.insert(args.modelOfEngineInstance).values(eachData).$returningId();
const insertedData = results?.[0];
if (!insertedData) return void 0;
const primaryKey = Object.keys(insertedData)[0];
const primaryKeyValue = insertedData[primaryKey];
const searchForInsertedData = eq(args.modelOfEngineInstance[primaryKey], primaryKeyValue);
const searchResult = await engineInstanceOrTransaction.select().from(args.modelOfEngineInstance).where(searchForInsertedData);
if ((searchResult?.length || []) <= 0) return void 0;
return [
true,
searchResult[0]
];
}));
return inserts.filter((insert) => Array.isArray(insert));
}, "queryData")
});
var removeQuery = adapterRemoveQuery({
queryData: /* @__PURE__ */ __name(async (engine, args) => {
const engineInstanceOrTransaction = args.transaction || engine.instance.instance;
if (engine.instance.mainType === "sqlite" || engine.instance.mainType === "postgres") return engineInstanceOrTransaction.delete(args.modelOfEngineInstance).where(and(...Object.values(args.search))).returning();
const dataToBeDeleted = await engine.instance.instance.select().from(args.modelOfEngineInstance).where(and(...Object.values(args.search)));
await engineInstanceOrTransaction.delete(args.modelOfEngineInstance).where(and(...Object.values(args.search)));
return dataToBeDeleted;
}, "queryData")
});
var order = adapterOrderingQuery({
// eslint-disable-next-line ts/require-await
parseOrdering: /* @__PURE__ */ __name(async (model, ordering) => {
return ordering.map((order2) => {
const isDescending = order2.startsWith("-");
return isDescending ? desc(model[order2.slice(1)]) : asc(model[order2]);
});
}, "parseOrdering")
});
var search = adapterSearchQuery({
// eslint-disable-next-line ts/require-await
parseSearchFieldValue: /* @__PURE__ */ __name(async (operationType, key, model, value, result, options) => {
switch (operationType) {
case "like": {
if (options?.ignoreCase) result[key] = ilike(model[key], value);
else if (options?.isNot && options.ignoreCase) result[key] = notIlike(model[key], value);
else if (options?.isNot) result[key] = notLike(model[key], value);
else result[key] = like(model[key], value);
return;
}
case "is":
if (value === null && options?.isNot) {
result[key] = isNotNull(model[key]);
return;
} else if (value === null) {
result[key] = isNull(model[key]);
return;
} else if (options?.isNot) result[key] = not(eq(model[key], value));
else result[key] = eq(model[key], value);
return;
case "in":
if (options?.isNot) result[key] = notInArray(model[key], value);
else result[key] = inArray(model[key], value);
return;
case "between":
if (options?.isNot) result[key] = notBetween(model[key], value, value);
else result[key] = between(model[key], value, value);
return;
case "and":
result[key] = and(eq(model[key], value), eq(model[key], value));
return;
case "or":
result[key] = or(eq(model[key], value), eq(model[key], value));
return;
case "greaterThan":
if (options?.equals) result[key] = gte(model[key], value);
else result[key] = gt(model[key], value);
return;
case "lessThan":
if (options?.equals) result[key] = lte(model[key], value);
else result[key] = lt(model[key], value);
return;
default:
result[key] = eq(model[key], value);
}
}, "parseSearchFieldValue")
});
var query = adapterQuery({
search: new search(),
ordering: new order(),
get: new getQuery(),
set: new setQuery(),
remove: new removeQuery()
});
// src/engine.ts
var instancesByConnectionNames = /* @__PURE__ */ new Map();
var checkIfInstanceSavedOrSave = /* @__PURE__ */ __name((connectionName, type, mainType, drizzleInstance, closeCallback) => {
const instance = instancesByConnectionNames.get(connectionName);
if (instance !== void 0) return instance;
const toSave = {
instance: drizzleInstance,
type,
mainType,
closeCallback,
isConnected: void 0
};
instancesByConnectionNames.set(connectionName, toSave);
return toSave;
}, "checkIfInstanceSavedOrSave");
var drizzleDatabaseAdapter = databaseAdapter({
fields: new fields(),
models: new models(),
query: new query(),
new: /* @__PURE__ */ __name((args) => {
const engineInstance = new drizzleDatabaseAdapter();
engineInstance.instance = {
output: args.output,
type: args.type,
mainType: args.type.includes("sqlite") ? "sqlite" : "postgres",
instance: args.drizzle,
closeCallback: args.closeCallback
};
return [
args,
() => engineInstance
];
}, "new"),
// eslint-disable-next-line ts/require-await
isConnected: /* @__PURE__ */ __name(async () => {
return true;
}, "isConnected"),
transaction: /* @__PURE__ */ __name(async (databaseAdapter2, callback, ...args) => {
const instanceData = checkIfInstanceSavedOrSave(databaseAdapter2.connectionName, databaseAdapter2.instance.type, databaseAdapter2.instance.mainType, databaseAdapter2.instance.instance);
return new Promise((resolve, reject) => {
try {
instanceData.instance.transaction(async (transaction) => {
try {
resolve(await callback(transaction, ...args));
} catch (e) {
reject(e);
}
}).catch(reject);
} catch (e) {
reject(e);
}
});
}, "transaction"),
duplicate: /* @__PURE__ */ __name(async (getNewEngine) => {
return getNewEngine();
}, "duplicate"),
close: /* @__PURE__ */ __name(async (databaseAdapter2) => {
const instanceData = checkIfInstanceSavedOrSave(databaseAdapter2.connectionName, databaseAdapter2.instance.type, databaseAdapter2.instance.mainType, databaseAdapter2.instance.instance);
try {
await Promise.resolve(instanceData.closeCallback?.());
} catch (_) {
}
}, "close")
});
// src/fields/custom-fields/sqlite.ts
import { Field, TextField } from "@palmares/databases";
// src/fields/custom-fields/utils.ts
var DefaultBuilder = class _DefaultBuilder {
static {
__name(this, "DefaultBuilder");
}
_;
constructor(fieldInstance, type) {
this._ = {
field: fieldInstance,
type
};
}
$type() {
return this._.field._setPartialAttributes()(this._.field["__customAttributes"])._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
$default(cb) {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
$default: [
cb
]
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
$onUpdate(cb) {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
$onUpdate: [
cb
]
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
references(cb) {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
references: [
cb
]
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
primaryKey() {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
primaryKey: true
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
unique() {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
unique: true
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
notNull() {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
notNull: []
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
generatedAlwaysAs(cb) {
return this._.field._setPartialAttributes()({
type: this._.type,
args: this._.field["__customAttributes"]?.["args"],
options: {
...this._.field["__customAttributes"]?.["options"] || {},
generatedAlwaysAs: [
cb
]
}
})._setNewBuilderMethods(new _DefaultBuilder(this._.field, this._.type));
}
};
// src/fields/custom-fields/sqlite.ts
function real() {
const RealField = Field._overrideType({
typeName: "real"
});
const instance = RealField.new({}).allowNull(false);
return instance._setNewBuilderMethods();
}
__name(real, "real");
function integer(args) {
const IntegerField = Field._overrideType({
typeName: "integer"
});
const instance = IntegerField.new({}).allowNull(false);
instance["__customAttributes"] = {
args
};
return instance._setNewBuilderMethods();
}
__name(integer, "integer");
function text(args) {
const CustomTextField = TextField._overrideType({
typeName: "text"
});
const instance = CustomTextField.new({}).allowNull(false).allowBlank(true);
instance["__customAttributes"] = {
args
};
return instance._setNewBuilderMethods(new DefaultBuilder(instance, "text"));
}
__name(text, "text");
function blob(args) {
const CustomTextField = Field._overrideType({
typeName: "text"
});
const instance = CustomTextField.new({}).allowNull(false);
instance["__customAttributes"] = {
args
};
return instance._setNewBuilderMethods();
}
__name(blob, "blob");
// src/index.ts
var src_default = drizzleDatabaseAdapter;
export {
drizzleDatabaseAdapter as DrizzleDatabaseAdapter,
blob,
src_default as default,
integer,
real,
text
};