@palmares/databases
Version:
Add support for working with databases with palmares framework
1,342 lines (1,332 loc) • 297 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/models/utils.ts
var utils_exports = {};
__export(utils_exports, {
factoryFunctionForModelTranslate: () => factoryFunctionForModelTranslate,
getDefaultModelOptions: () => getDefaultModelOptions,
indirectlyRelatedModels: () => indirectlyRelatedModels,
initializeModels: () => initializeModels,
parse: () => parse,
retrieveInputAndOutputParsersFromFieldAndCache: () => retrieveInputAndOutputParsersFromFieldAndCache
});
module.exports = __toCommonJS(utils_exports);
var import_core10 = require("@palmares/core");
// src/models/exceptions.ts
var ModelNoUniqueFieldsError = class _ModelNoUniqueFieldsError extends Error {
static {
__name(this, "ModelNoUniqueFieldsError");
}
constructor(modelName) {
super(`Model ${modelName} has no unique fields, it should have at least one unique field. If it's an abstract model, you need to set "abstract" to true in the model options.`);
this.name = _ModelNoUniqueFieldsError.name;
}
};
var ModelNoPrimaryKeyFieldError = class _ModelNoPrimaryKeyFieldError extends Error {
static {
__name(this, "ModelNoPrimaryKeyFieldError");
}
constructor(modelName) {
super(`Model ${modelName} has no primary key field, it should have at least one primary key. If it's an abstract model, you need to set "abstract" to true in the model options.`);
this.name = _ModelNoPrimaryKeyFieldError.name;
}
};
var ModelCircularAbstractError = class extends Error {
static {
__name(this, "ModelCircularAbstractError");
}
constructor(originalModelName, abstractModelName) {
super(`Model ${originalModelName} have a circular abstract dependency with ${abstractModelName}`);
}
};
var ManagerEngineInstanceNotFoundError = class _ManagerEngineInstanceNotFoundError extends Error {
static {
__name(this, "ManagerEngineInstanceNotFoundError");
}
constructor(engineName) {
super(`The engine ${engineName} is not found in the manager. Make sure that this model is available for that engine.`);
this.name = _ManagerEngineInstanceNotFoundError.name;
}
};
var ShouldAssignAllInstancesException = class _ShouldAssignAllInstancesException extends Error {
static {
__name(this, "ShouldAssignAllInstancesException");
}
constructor() {
super("You have translated the model before. And you have assigned `instance` to the model options. You should assign `instance` to all model options.");
this.name = _ShouldAssignAllInstancesException.name;
}
};
var EngineDoesNotSupportFieldTypeException = class _EngineDoesNotSupportFieldTypeException extends Error {
static {
__name(this, "EngineDoesNotSupportFieldTypeException");
}
constructor(engineName, fieldType) {
super(`The engine '${engineName}' does not support the field of type: '${fieldType}'. If you are using a custom field, make sure that you are using the 'TranslatableField' class.`);
this.name = _EngineDoesNotSupportFieldTypeException.name;
}
};
var RelatedModelFromForeignKeyIsNotFromEngineException = class _RelatedModelFromForeignKeyIsNotFromEngineException extends Error {
static {
__name(this, "RelatedModelFromForeignKeyIsNotFromEngineException");
}
constructor(engineName, modelName, foreignKeyFieldName, foreignKeyFieldModelName, fieldName) {
super(`The related model '${modelName}' from the foreign key field '${foreignKeyFieldName}' of the model '${foreignKeyFieldModelName}' is not from the engine '${engineName}' that is being used. This is not a problem, but you need to make sure that the field '${fieldName}' it is relating to exists on the model '${modelName}' it is related to.`);
this.name = _RelatedModelFromForeignKeyIsNotFromEngineException.name;
}
};
var ModelMissingException = class _ModelMissingException extends Error {
static {
__name(this, "ModelMissingException");
}
constructor(modelName) {
super(`The model ${modelName} was not found in the engine.`);
this.name = _ModelMissingException.name;
}
};
var FieldFromModelMissingException = class _FieldFromModelMissingException extends Error {
static {
__name(this, "FieldFromModelMissingException");
}
constructor(modelName, fieldName) {
super(`The field ${fieldName} was not found in the model ${modelName}.`);
this.name = _FieldFromModelMissingException.name;
}
};
// src/models/fields/field.ts
var import_core = require("@palmares/core");
// src/models/fields/utils.ts
async function defaultToStringCallback(engine, field, _, customParams = void 0) {
let customImports = [];
let stringifiedCustomAttributes = "{}";
if (engine.fields.fieldToString) {
const stringifiedField = engine.fields.fieldToString(field["__customAttributes"]);
customImports = stringifiedField.imports;
stringifiedCustomAttributes = stringifiedField.result;
}
const stringfieldDefaultValue = field["__defaultValue"] === void 0 ? void 0 : JSON.stringify(field["__defaultValue"]);
return {
stringfied: `models.fields.${field["__typeName"]}.new(${customParams?.constructorParams ? `${customParams.constructorParams}` : ""})${typeof field["__primaryKey"] === "boolean" ? `.primaryKey(${field["__primaryKey"]})` : ""}${stringfieldDefaultValue !== void 0 ? `.default(${typeof field["__defaultValue"] === "string" ? `"${stringfieldDefaultValue}"` : stringfieldDefaultValue})` : ""}${typeof field["__allowNull"] === "boolean" ? `.allowNull(${field["__allowNull"]})` : ""}${typeof field["__unique"] === "boolean" ? `.unique(${field["__unique"]})` : ""}${typeof field["__dbIndex"] === "boolean" ? `.dbIndex(${field["__dbIndex"]})` : ""}${typeof field["__databaseName"] === "string" ? `.databaseName("${field["__databaseName"]}")` : ""}${typeof field["__underscored"] === "boolean" ? `.underscored(${field["__underscored"]})` : ""}${typeof stringifiedCustomAttributes === "string" ? `.setCustomAttributes(${stringifiedCustomAttributes})` : ""}${customParams?.builderParams ? `${customParams.builderParams}` : ""}`,
customImports
};
}
__name(defaultToStringCallback, "defaultToStringCallback");
function defaultCompareCallback(engine, existingField, newField, _) {
let isCustomAttributesEqual = true;
if (engine.fields.compare) {
const areCustomAttributesEqual = engine.fields.compare(existingField["__customAttributes"], newField["__customAttributes"]);
isCustomAttributesEqual = areCustomAttributesEqual;
}
const isTypeNameEqual = existingField["__typeName"] === newField["__typeName"];
const isAllowNullEqual = existingField["__allowNull"] === newField["__allowNull"];
const isPrimaryKeyEqual = existingField["__primaryKey"] === newField["__primaryKey"];
const isDefaultValueEqual = existingField["__defaultValue"] === newField["__defaultValue"];
const isUniqueEqual = existingField["__unique"] === newField["__unique"];
const isDbIndexEqual = existingField["__dbIndex"] === newField["__dbIndex"];
const isDatabaseNameEqual = existingField["__databaseName"] === newField["__databaseName"];
const isUnderscoredEqual = existingField["__underscored"] === newField["__underscored"];
const changedAttributes = [
!isTypeNameEqual && "typeName",
!isAllowNullEqual && "allowNull",
!isCustomAttributesEqual && "customAttributes",
!isPrimaryKeyEqual && "primaryKey",
!isDefaultValueEqual && "defaultValue",
!isUniqueEqual && "unique",
!isDbIndexEqual && "dbIndex",
!isDatabaseNameEqual && "databaseName",
!isUnderscoredEqual && "underscored"
].filter((attr) => typeof attr === "string");
return [
changedAttributes.length === 0,
changedAttributes
];
}
__name(defaultCompareCallback, "defaultCompareCallback");
function defaultOptionsCallback(setFieldValue, oldField, _) {
setFieldValue("__allowNull", "allowNull", oldField["__allowNull"]);
setFieldValue("__customAttributes", "customAttributes", oldField["__customAttributes"]);
setFieldValue("__defaultValue", "defaultValue", oldField["__defaultValue"]);
setFieldValue("__dbIndex", "dbIndex", oldField["__dbIndex"]);
setFieldValue("__databaseName", "databaseName", oldField["__databaseName"]);
setFieldValue("__primaryKey", "primaryKey", oldField["__primaryKey"]);
setFieldValue("__underscored", "underscored", oldField["__underscored"]);
setFieldValue("__unique", "unique", oldField["__unique"]);
setFieldValue("__isAuto", "isAuto", oldField["__isAuto"]);
setFieldValue("__fieldName", "fieldName", oldField["__fieldName"]);
setFieldValue("__model", void 0, oldField["__model"]);
}
__name(defaultOptionsCallback, "defaultOptionsCallback");
function defaultNewInstanceArgumentsCallback(_field, _defaultNewInstanceArgumentsCallback) {
return [];
}
__name(defaultNewInstanceArgumentsCallback, "defaultNewInstanceArgumentsCallback");
function getRelatedToAsString(field) {
const relatedTo = field["__relatedTo"];
const relatedToAsString = field["__relatedToAsString"];
if (typeof relatedToAsString !== "string") {
if (typeof relatedTo === "function" && relatedTo["$$type"] !== "$PModel") field["__relatedToAsString"] = relatedTo()["__getName"]();
else if (typeof relatedTo === "string") field["__relatedToAsString"] = relatedTo;
else field["__relatedToAsString"] = relatedTo["__getName"]();
}
}
__name(getRelatedToAsString, "getRelatedToAsString");
function defaultGetArgumentsCallback(field, _) {
return {
$field: field,
$model: field["__model"],
typeName: field["__typeName"],
fieldName: field["__fieldName"],
modelName: field["__model"]?.["__getName"]?.() || "",
isAuto: field["__isAuto"],
primaryKey: field["__primaryKey"],
defaultValue: field["__defaultValue"],
allowNull: field["__allowNull"],
unique: field["__unique"],
dbIndex: field["__dbIndex"],
databaseName: field["__databaseName"],
underscored: field["__underscored"],
customAttributes: field["__customAttributes"]
};
}
__name(defaultGetArgumentsCallback, "defaultGetArgumentsCallback");
// src/models/fields/field.ts
var Field = class {
static {
__name(this, "Field");
}
$$type = "$PField";
__typeName = "Field";
__isAuto = false;
__hasDefaultValue = false;
__primaryKey = false;
__defaultValue = void 0;
__allowNull = false;
__unique = false;
__dbIndex = false;
__databaseName = void 0;
__underscored = true;
__customAttributes;
__allowedQueryOperations = /* @__PURE__ */ new Set([
"eq",
"is",
"greaterThan",
"lessThan",
"like",
"between",
"and",
"or"
]);
// eslint-disable-next-line ts/require-await
__toStringCallback = defaultToStringCallback;
// eslint-disable-next-line ts/require-await
__compareCallback = defaultCompareCallback;
__optionsCallback = defaultOptionsCallback;
__newInstanceCallback = defaultNewInstanceArgumentsCallback;
__customImports = [];
__getArgumentsCallback = defaultGetArgumentsCallback;
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
__model;
__fieldName;
constructor(..._args) {
}
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = TextField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = <TParams extends { name: string }>(params: TParams) => {
* const field = customBigInt.new(params);
* return field._setNewBuilderMethods({
* test: <TTest extends { age: number }>(param: TTest) =>
* // This will union the type `string` with what already exists in the field 'create' type
* field._setPartialAttributes<{ create: string }, { create: 'union' }>(param)
* });
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(this);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
if (typeof isUnique !== "boolean") isUnique = true;
this.__unique = isUnique;
return this;
}
allowNull(isNull) {
if (typeof isNull !== "boolean") isNull = true;
this.__allowNull = isNull;
return this;
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(dbIndex) {
if (typeof dbIndex !== "boolean") dbIndex = true;
this.__dbIndex = dbIndex;
return this;
}
underscored(isUnderscored) {
if (typeof isUnderscored !== "boolean") isUnderscored = true;
this.__underscored = isUnderscored;
return this;
}
primaryKey(isPrimaryKey) {
if (typeof isPrimaryKey !== "boolean") isPrimaryKey = true;
this.__primaryKey = isPrimaryKey;
return this;
}
auto(isAuto) {
if (typeof isAuto !== "boolean") isAuto = true;
this.__isAuto = isAuto;
return this;
}
default(defaultValue) {
this.__defaultValue = defaultValue;
return this;
}
databaseName(databaseName) {
this.__databaseName = databaseName;
return this;
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support the field type but the default type provided by palmares
* is not the one that the user want to use.
*
* @example
* ```ts
* const MyCustomDatabaseAutoField = AutoField.overrideType<{ input: string; output: string }>();
*
* // then the user can use as normal:
*
* const autoField = MyCustomDatabaseAutoField.new();
*
* // now the type inferred for the field will be a string instead of a number.
* ```
*
* ### Note
*
* Your library should provide documentation of the fields that are supported.
*/
static _overrideType(args) {
this.new = (params) => {
const newInstance = new this(params);
newInstance.__customImports = args.customImports || [];
newInstance.__toStringCallback = args.toStringCallback || defaultToStringCallback;
newInstance.__compareCallback = args.compareCallback || defaultCompareCallback;
newInstance.__optionsCallback = args.optionsCallback || defaultOptionsCallback;
newInstance.__newInstanceCallback = args.newInstanceCallback || defaultNewInstanceArgumentsCallback;
newInstance.__typeName = args.typeName;
newInstance.__allowedQueryOperations = /* @__PURE__ */ new Set([
"is",
"eq",
"greaterThan",
"lessThan",
"like",
"between"
]);
newInstance["__customAttributes"] = params;
return newInstance;
};
return this;
}
/**
* This method enables the framework to automatically import the files when generating the migrations.
*
* This is generally useful for custom field types.
*
* @return - Returns a list of packages that we want to import in the migration file.
*/
// eslint-disable-next-line ts/require-await
async __getCustomImports() {
return this["__customImports"];
}
__init(fieldName, model2) {
const isAlreadyInitialized = this.__model !== void 0 && typeof this.__fieldName === "string";
if (isAlreadyInitialized) return;
const isUnderscored = (this.__underscored || model2.__cachedOptions?.underscored) === true;
this.__fieldName = fieldName;
this.__model = model2;
if (this.__primaryKey) model2["__primaryKeys"].push(this.__fieldName);
if (isUnderscored) this.__databaseName = import_core.utils.camelCaseToHyphenOrSnakeCase(this.__fieldName);
else this.__databaseName = this.__fieldName;
}
/**
* Gets all of the arguments to pass to the field during migration, translation, etc.
*
* Everything in the field is protected, this way end users don't access the internal implementation.
*/
__getArguments() {
return this.__getArgumentsCallback(this, defaultGetArgumentsCallback);
}
// eslint-disable-next-line ts/require-await
async __toString(engine) {
return this.__toStringCallback(engine, this, defaultToStringCallback, void 0);
}
/**
* Used for comparing one field with the other so we are able to tell if they are different or not.
*
* This is obligatory to add if you create any custom fields.
*
* For custom fields you will call this super method before continuing, we first check if they are the same type.
*
* @param field - The field to compare to.
*
* @return - Returns true if the fields are equal and false otherwise
*/
// eslint-disable-next-line ts/require-await
__compare(engine, field) {
return this.__compareCallback(engine, this, field, defaultCompareCallback);
}
/**
* Used for cloning the field to a new field.
*
* @param oldField - The field to clone. If not provided it will use the current field.
*
* @returns - Returns the cloned field.
*/
__clone(oldField, args) {
const argumentsToPass = oldField.__newInstanceCallback(oldField, defaultNewInstanceArgumentsCallback);
const overridenArguments = args?.newInstanceOverrideCallback?.(argumentsToPass) || argumentsToPass;
const newInstanceOfField = oldField.constructor.new(...Array.isArray(overridenArguments) ? overridenArguments : []);
oldField.__optionsCallback((hiddenAttributeName, getAttributesAttributeName, value) => {
let actualValueToSet = value;
if (getAttributesAttributeName && args?.optionsOverrideCallback?.[getAttributesAttributeName] !== void 0) actualValueToSet = (args?.optionsOverrideCallback)[getAttributesAttributeName](value);
newInstanceOfField[hiddenAttributeName] = actualValueToSet;
}, oldField, defaultOptionsCallback);
return newInstanceOfField;
}
/**
* You should not use this method directly, it is used internally by the framework.
*
* This method is used to create a new instance of the field with the same options as the old field.
*/
static new(..._args) {
return new this(..._args);
}
};
// src/models/fields/date.ts
var DateField = class extends Field {
static {
__name(this, "DateField");
}
$$type = "$PDateField";
__typeName = "DateField";
__allowedQueryOperations = /* @__PURE__ */ new Set([
"eq",
"is",
"greaterThan",
"lessThan",
"between",
"and",
"or"
]);
__autoNow = false;
__autoNowAdd = false;
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
__compareCallback = /* @__PURE__ */ __name((engine, oldField, newField, defaultCompareCallback2) => {
const oldFieldAsTextField = oldField;
const newFieldAsTextField = newField;
const isAutoNowEqual = oldFieldAsTextField["__autoNow"] === newFieldAsTextField["__autoNow"];
const isAutoNowAddEqual = oldFieldAsTextField["__autoNowAdd"] === newFieldAsTextField["__autoNowAdd"];
const [isEqual, changedAttributes] = defaultCompareCallback2(engine, oldField, newField, defaultCompareCallback2);
if (!isAutoNowEqual) changedAttributes.push("autoNow");
if (!isAutoNowAddEqual) changedAttributes.push("autoNowAdd");
return [
isAutoNowAddEqual && isAutoNowEqual && isEqual,
changedAttributes
];
}, "__compareCallback");
__optionsCallback = /* @__PURE__ */ __name((setFieldValue, oldField, defaultOptionsCallback2) => {
const oldFieldAsTextField = oldField;
defaultOptionsCallback2(setFieldValue, oldField, defaultOptionsCallback2);
setFieldValue("__autoNow", "autoNow", oldFieldAsTextField["__autoNow"]);
setFieldValue("__autoNowAdd", "autoNowAdd", oldFieldAsTextField["__autoNowAdd"]);
}, "__optionsCallback");
__getArgumentsCallback = /* @__PURE__ */ __name((field, defaultCallback) => {
const fieldAsDateField = field;
const autoNow = fieldAsDateField["__autoNow"];
const autoNowAdd = fieldAsDateField["__autoNowAdd"];
return {
...defaultCallback(field, defaultCallback),
autoNow,
autoNowAdd
};
}, "__getArgumentsCallback");
/**
* This is used internally by the engine to convert the field to string.
* You can override this if you want to extend the ForeignKeyField class.
*/
__toStringCallback = /* @__PURE__ */ __name(async (engine, field, defaultToStringCallback2, _customParams = void 0) => {
const fieldAsDateField = field;
return await defaultToStringCallback2(engine, field, defaultToStringCallback2, {
builderParams: `${typeof fieldAsDateField["__autoNow"] === "boolean" ? `.autoNow(${fieldAsDateField["__autoNow"]})` : ""}${typeof fieldAsDateField["__autoNowAdd"] === "boolean" ? `.autoNowAdd(${fieldAsDateField["__autoNowAdd"]})` : ""}`
});
}, "__toStringCallback");
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = DateField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = <TParams extends { name: string }>(params: TParams) => {
* const field = customBigInt.new(params);
* return field._setNewBuilderMethods({
* test: <TTest extends { age: number }>(param: TTest) =>
* // This will union the type `string` with what already exists in the field 'create' type
* field._setPartialAttributes<{ create: string }, { create: 'union' }>(param)
* });
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(this);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
return super.unique(isUnique);
}
allowNull(isNull) {
return super.allowNull(isNull);
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(isDbIndex) {
return super.dbIndex(isDbIndex);
}
underscored(isUnderscored) {
return super.underscored(isUnderscored);
}
primaryKey(isPrimaryKey) {
return super.primaryKey(isPrimaryKey);
}
auto(isAuto) {
return super.auto(isAuto);
}
default(defaultValue) {
return super.default(defaultValue);
}
databaseName(databaseName) {
return super.databaseName(databaseName);
}
autoNow(isAutoNow) {
isAutoNow = typeof isAutoNow === "boolean" ? isAutoNow : true;
this.__autoNow = isAutoNow;
return this;
}
autoNowAdd(isAutoNowAdd) {
isAutoNowAdd = typeof isAutoNowAdd === "boolean" ? isAutoNowAdd : true;
this.__autoNowAdd = isAutoNowAdd;
return this;
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support a custom field type not supported by palmares.
*
* ### Note
* - Your library should provide documentation of the fields that are supported.
* - This should be used alongside the `_setPartialAttributes` method and `_setNewBuilderMethods`.
* Instead of making users type NameOfYourField.new(), you should create a function that calls .new and creates
* a new instance of the field for them.
* - TDefinitions exists on type-level only, in runtime, it's not a guarantee of nothing. If TDefinitions
* sets unique to true, it's up to you to do `NameOfYourField.new().unique()`, because otherwise it will be false
*/
static _overrideType(args) {
return super._overrideType(args);
}
static new(..._args) {
return new this(..._args);
}
};
// src/models/fields/decimal.ts
var DecimalField = class extends Field {
static {
__name(this, "DecimalField");
}
$$type = "$PDecimalField";
__typeName = "DecimalField";
__maxDigits;
__decimalPlaces;
__allowedQueryOperations = /* @__PURE__ */ new Set([
"lessThan",
"greaterThan",
"between",
"and",
"in",
"or",
"eq",
"is"
]);
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
__compareCallback = /* @__PURE__ */ __name((engine, oldField, newField, defaultCompareCallback2) => {
const oldFieldAsTextField = oldField;
const newFieldAsTextField = newField;
const isMaxDigitsEqual = oldFieldAsTextField["__maxDigits"] === newFieldAsTextField["__maxDigits"];
const isDecimalPlacesEqual = oldFieldAsTextField["__decimalPlaces"] === newFieldAsTextField["__decimalPlaces"];
const [isEqual, changedAttributes] = defaultCompareCallback2(engine, oldField, newField, defaultCompareCallback2);
if (!isMaxDigitsEqual) changedAttributes.push("maxDigits");
if (!isDecimalPlacesEqual) changedAttributes.push("decimalPlaces");
return [
isMaxDigitsEqual && isDecimalPlacesEqual && isEqual,
changedAttributes
];
}, "__compareCallback");
/**
* This is used internally by the engine to convert the field to string.
* You can override this if you want to extend the ForeignKeyField class.
*/
__toStringCallback = /* @__PURE__ */ __name(async (engine, field, defaultToStringCallback2, _customParams = void 0) => {
const fieldAsDecimalField = field;
return await defaultToStringCallback2(engine, field, defaultToStringCallback2, {
constructorParams: `{ maxDigits: ${fieldAsDecimalField["__maxDigits"]}, decimalPlaces: ${fieldAsDecimalField["__decimalPlaces"]} }`
});
}, "__toStringCallback");
/**
* This is used internally by the engine for cloning the field to a new instance.
* By doing that you are able to get the constructor options of the field when using Field.new(<instanceArguments>)
*/
__newInstanceCallback = /* @__PURE__ */ __name((oldField, defaultNewInstanceArgumentsCallback2) => {
const defaultData = defaultNewInstanceArgumentsCallback2(oldField, defaultNewInstanceArgumentsCallback2);
const position0 = defaultData[0] || {};
const otherPositions = defaultData.slice(1);
const asDecimalField = oldField;
return [
{
...position0,
maxDigits: asDecimalField["__maxDigits"],
decimalPlaces: asDecimalField["__decimalPlaces"]
},
...otherPositions
];
}, "__newInstanceCallback");
__getArgumentsCallback = /* @__PURE__ */ __name((field, defaultCallback) => {
const fieldAsDateField = field;
const maxDigits = fieldAsDateField["__maxDigits"];
const decimalPlaces = fieldAsDateField["__decimalPlaces"];
return {
...defaultCallback(field, defaultCallback),
decimalPlaces,
maxDigits
};
}, "__getArgumentsCallback");
constructor(params) {
super(params);
this.__maxDigits = params.maxDigits;
this.__decimalPlaces = params.decimalPlaces;
}
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = DecimalField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = <TParams extends { name: string }>(params: TParams) => {
* const field = customBigInt.new(params);
* return field._setNewBuilderMethods({
* test: <TTest extends { age: number }>(param: TTest) =>
* // This will union the type `string` with what already exists in the field 'create' type
* field._setPartialAttributes<{ create: string }, { create: 'union' }>(param)
* });
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(this);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
return super.unique(isUnique);
}
allowNull(isNull) {
return super.allowNull(isNull);
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(isDbIndex) {
return super.dbIndex(isDbIndex);
}
underscored(isUnderscored) {
return super.underscored(isUnderscored);
}
primaryKey(isPrimaryKey) {
return super.primaryKey(isPrimaryKey);
}
auto(isAuto) {
return super.auto(isAuto);
}
default(defaultValue) {
return super.default(defaultValue);
}
databaseName(databaseName) {
return super.databaseName(databaseName);
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support a custom field type not supported by palmares.
*
* ### Note
* - Your library should provide documentation of the fields that are supported.
* - This should be used alongside the `_setPartialAttributes` method and `_setNewBuilderMethods`.
* Instead of making users type NameOfYourField.new(), you should create a function that calls .new and creates
* a new instance of the field for them.
* - TDefinitions exists on type-level only, in runtime, it's not a guarantee of nothing. If TDefinitions
* sets unique to true, it's up to you to do `NameOfYourField.new().unique()`, because otherwise it will be false
*/
static _overrideType(args) {
return super._overrideType(args);
}
static new(params) {
return new this(params);
}
};
// src/models/fields/integer.ts
var IntegerField = class extends Field {
static {
__name(this, "IntegerField");
}
$$type = "$PIntegerField";
__typeName = "IntegerField";
__allowedQueryOperations = /* @__PURE__ */ new Set([
"lessThan",
"greaterThan",
"between",
"and",
"in",
"or",
"eq",
"is"
]);
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = TextField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = () => {
* const field = textField.new();
* class Builder {
* test<TTest extends { age: number }>(param: TTest) {
* return field
* ._setPartialAttributes<{ create: TTest }, { create: 'union' }>()(param)
* ._setNewBuilderMethods<Builder>();
* }
* value<const TValue extends string>(value: TValue) {
* return field
* ._setPartialAttributes<{ create: TValue }, { create: 'replace' }>()(value)
* ._setNewBuilderMethods<Builder>();
* }
* }
*
* const builder = new Builder();
* return field._setNewBuilderMethods(builder);
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(this);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
return super.unique(isUnique);
}
allowNull(isNull) {
return super.allowNull(isNull);
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(isDbIndex) {
return super.dbIndex(isDbIndex);
}
underscored(isUnderscored) {
return super.underscored(isUnderscored);
}
primaryKey(isPrimaryKey) {
return super.primaryKey(isPrimaryKey);
}
auto(isAuto) {
return super.auto(isAuto);
}
default(defaultValue) {
return super.default(defaultValue);
}
databaseName(databaseName) {
return super.databaseName(databaseName);
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support a custom field type not supported by palmares.
*
* ### Note
* Your library should provide documentation of the fields that are supported.
*/
static _overrideType(args) {
return super._overrideType(args);
}
static new(..._args) {
return new this(..._args);
}
};
// src/models/fields/big-integer.ts
var BigIntegerField = class extends Field {
static {
__name(this, "BigIntegerField");
}
$$type = "$PBigIntegerField";
__typeName = "BigIntegerField";
__allowedQueryOperations = /* @__PURE__ */ new Set([
"lessThan",
"greaterThan",
"and",
"in",
"or",
"eq",
"is",
"between"
]);
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = TextField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = () => {
* const field = textField.new();
* class Builder {
* test<TTest extends { age: number }>(param: TTest) {
* return field
* ._setPartialAttributes<{ create: TTest }, { create: 'union' }>()(param)
* ._setNewBuilderMethods<Builder>();
* }
* value<const TValue extends string>(value: TValue) {
* return field
* ._setPartialAttributes<{ create: TValue }, { create: 'replace' }>()(value)
* ._setNewBuilderMethods<Builder>();
* }
* }
*
* const builder = new Builder();
* return field._setNewBuilderMethods(builder);
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(this);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
return super.unique(isUnique);
}
allowNull(isNull) {
return super.allowNull(isNull);
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(isDbIndex) {
return super.dbIndex(isDbIndex);
}
underscored(isUnderscored) {
return super.underscored(isUnderscored);
}
primaryKey(isPrimaryKey) {
return super.primaryKey(isPrimaryKey);
}
auto(isAuto) {
return super.auto(isAuto);
}
default(defaultValue) {
return super.default(defaultValue);
}
databaseName(databaseName) {
return super.databaseName(databaseName);
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support a custom field type not supported by palmares.
*
* ### Note
* Your library should provide documentation of the fields that are supported.
*/
static _overrideType(args) {
return super._overrideType(args);
}
static new(..._args) {
return new this(..._args);
}
};
// src/models/fields/text.ts
var TextField = class extends Field {
static {
__name(this, "TextField");
}
$$type = "$PTextField";
__typeName = "TextField";
__allowedQueryOperations = /* @__PURE__ */ new Set([
"and",
"in",
"or",
"eq",
"is",
"like"
]);
__allowBlank = false;
__inputParsers = /* @__PURE__ */ new Map();
__outputParsers = /* @__PURE__ */ new Map();
__compareCallback = /* @__PURE__ */ __name((engine, oldField, newField, defaultCompareCallback2) => {
const oldFieldAsTextField = oldField;
const newFieldAsTextField = newField;
const isAllowBlankEqual = oldFieldAsTextField["__allowBlank"] === newFieldAsTextField["__allowBlank"];
const [isEqual, changedAttributes] = defaultCompareCallback2(engine, oldField, newField, defaultCompareCallback2);
if (!isAllowBlankEqual) changedAttributes.push("allowBlank");
return [
isAllowBlankEqual && isEqual,
changedAttributes
];
}, "__compareCallback");
__optionsCallback = /* @__PURE__ */ __name((setFieldValue, oldField, defaultOptionsCallback2) => {
const oldFieldAsTextField = oldField;
defaultOptionsCallback2(setFieldValue, oldField, defaultOptionsCallback2);
setFieldValue("__allowBlank", "allowBlank", oldFieldAsTextField["__allowBlank"]);
}, "__optionsCallback");
__getArgumentsCallback = /* @__PURE__ */ __name((field, defaultGetArgumentsCallback2) => {
const fieldAsTextField = field;
const defaultData = defaultGetArgumentsCallback2(field, defaultGetArgumentsCallback2);
return {
...defaultData,
allowBlank: fieldAsTextField["__allowBlank"]
};
}, "__getArgumentsCallback");
/**
* This is used internally by the engine to convert the field to string.
* You can override this if you want to extend the ForeignKeyField class.
*/
__toStringCallback = /* @__PURE__ */ __name(async (engine, field, defaultToStringCallback2, _customParams = void 0) => {
const fieldAsTextField = field;
return await defaultToStringCallback2(engine, field, defaultToStringCallback2, {
builderParams: `${typeof fieldAsTextField["__allowBlank"] === "boolean" ? `.allowBlank(${fieldAsTextField["__allowBlank"]})` : ""}`
});
}, "__toStringCallback");
/**
* Supposed to be used by library maintainers.
*
* When you custom create a field, you might want to take advantage of the builder pattern we already support.
* This let's you create functions that can be chained together to create a new field. It should be used
* alongside the `_setPartialAttributes` method like
*
* @example
* ```ts
* const customBigInt = TextField.overrideType<
* { create: bigint; read: bigint; update: bigint },
* {
* customAttributes: { name: string };
* unique: boolean;
* auto: boolean;
* allowNull: true;
* dbIndex: boolean;
* isPrimaryKey: boolean;
* defaultValue: any;
* typeName: string;
* engineInstance: DatabaseAdapter;
* }
* >({
* typeName: 'CustomBigInt'
* });
*
* const customBuilder = <TParams extends { name: string }>(params: TParams) => {
* const field = customBigInt.new(params);
* return field._setNewBuilderMethods({
* test: <TTest extends { age: number }>(param: TTest) =>
* // This will union the type `string` with what already exists in the field 'create' type
* field._setPartialAttributes<{ create: string }, { create: 'union' }>(param)
* });
* };
*
* // Then your user can use it like:
*
* const field = customBuilder({ name: 'test' }).test({ age: 2 });
* ```
*
* **Important**: `customBuilder` will be used by the end user and you are responsible for documenting it.
*/
_setNewBuilderMethods(functions) {
if (functions === void 0) return this;
const propertiesOfBase = Object.getOwnPropertyNames(Object.getPrototypeOf(functions));
for (const key of propertiesOfBase) {
if (key === "constructor") continue;
this[key] = functions[key].bind(functions);
}
return this;
}
/**
* FOR LIBRARY MAINTAINERS ONLY
*
* Focused for library maintainers that want to support a custom field type not supported by palmares.
* This let's them partially update the custom attributes of the field. By default setCustomAttributes
* will override the custom attributes entirely.
*/
_setPartialAttributes() {
return (partialCustomAttributes) => {
if (partialCustomAttributes !== void 0) {
if (this.__customAttributes === void 0) this.__customAttributes = {};
this.__customAttributes = {
...this.__customAttributes,
...partialCustomAttributes
};
}
return this;
};
}
setCustomAttributes(customAttributes) {
this.__customAttributes = customAttributes;
return this;
}
unique(isUnique) {
return super.unique(isUnique);
}
allowNull(isNull) {
return super.allowNull(isNull);
}
allowBlank(isBlank) {
if (isBlank === void 0) isBlank = true;
this.__allowBlank = isBlank;
return this;
}
/**
* This method is used to create an index on the database for this field.
*/
dbIndex(isDbIndex) {
return super.dbIndex(isDbIndex);
}
underscored(isUnderscored) {
return super.underscored(isUnderscored);
}
primaryKey(isPrimaryKey) {
return super.primaryKey(isPrimaryKey);
}
auto(isAuto) {
return super.auto(isAuto);
}
default(defaultValue) {
return super.default(defaultValue);
}
databaseName(databaseName) {
return super.databaseName(databaseName);
}
/**
* This method can be used to override the type of a field. This is useful for library
* maintainers that want to support a custom field type not supported by palmares.
*
* ### Note
* - Your library should provide documentation of the fields that are supported.
* - This should be used alongside the `_setPartialAttributes` method and `_setNewBuilderMethods`.
* Instead of making users type NameOfYourField.new(), you should create a function that calls .new and creates
* a new instance of the