@palmares/databases
Version:
Add support for working with databases with palmares framework
322 lines • 14.5 kB
TypeScript
import type { AdapterFieldParser } from './field';
import type { AdapterFieldParserInputAndOutputArgs, AdapterFieldParserTranslateArgs } from '../..';
/**
* Functional approach to create a custom field parser.
*
* This will be used to parse the fields that are going to be used in the model in the database, we call this class just
* for the `BigAutoField`
*
* This class can have three methods:
* - `inputParser` - Used to parse the input value before it is sent to the database on your `AdapterQuery`
* implementation.
* - `outputParser` - Used to parse the output value before it is sent to the client on your `AdapterQuery`
* implementation.
* - `translate` - Used to translate the BigAutoField to something that the database can understand.
* translated directly with the `translate` method, all other field types should define a parser with the `translate`
* field, those will be injected in the `DatabaseAdapter` class constructor.
*/
export declare function adapterBigAutoFieldParser<TTranslateFunction extends AdapterBigAutoFieldParser['translate'], TInputParserFunction extends Required<AdapterBigAutoFieldParser>['inputParser'], TOutputParserFunction extends Required<AdapterBigAutoFieldParser>['outputParser']>(args: {
/**
* @description
* Used to translate the field to something that the database can understand. The `{@link AdapterFieldParser}`
* instance will be injected by default in the `translate` method.
* The core idea is that for every field type we will have a parser that will be used to translate the field
* to something that the database can understand. It's nice if all of the configuration options are supported
* by your ORM, but if that's not the case it's nice to notify the users through documentation.
*
* - _Note_: **If you return undefined, we will not consider that field on the object we build on
* `translateFields` under {@link AdapterModels} instance.**
* - _Note2_: **Use the `lazyEvaluate` function to evaluate something after the model was translated.**
*
* Imagine that you translating to sequelize field:
* @example
* ```ts
* async translate({
* engine,
* field,
* modelName,
* }: {
* engine: SequelizeEngine;
* field: Field;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* lazyEvaluate: (translatedField: any) => void;
* }): Promise<ModelAttributeColumnOptions> {
* const defaultOptions = {} as ModelAttributeColumnOptions;
* const isFieldAIndexOrIsFieldUnique = field.dbIndex === true || (field.unique as boolean) === true;
*
* if (isFieldAIndexOrIsFieldUnique) appendIndexes(engine.connectionName, modelName, field);
*
* const hasNotYetSetDefaultValueForField = defaultOptions.defaultValue === undefined;
* if (hasNotYetSetDefaultValueForField) defaultOptions.defaultValue = field.defaultValue;
*
* defaultOptions.autoIncrement = field.isAuto;
* defaultOptions.autoIncrementIdentity = field.isAuto;
* defaultOptions.primaryKey = field.primaryKey;
* defaultOptions.allowNull = field.allowNull;
* defaultOptions.unique = field.unique;
* defaultOptions.validate = {};
* defaultOptions.validate.notNull = !field.allowNull;
* defaultOptions.field = field.databaseName;
*
* const customAttributesOfFieldEntries = Object.entries(field.customAttributes);
* for (const [key, value] of customAttributesOfFieldEntries) {
* const keyAsTypeofModelColumnOption = key as keyof ModelAttributeColumnOptions;
* defaultOptions[keyAsTypeofModelColumnOption] = value as never;
* }
*
* const isFieldOfTypeText =
* field.typeName === TextField.name || field.typeName === CharField.name || field.typeName === UuidField.name;
*
* if (isFieldOfTypeText) this.textFieldValidations(field as TextField);
*
* return defaultOptions;
* }
* ```
*
* @description Or you can lazy evaluate (useful for ForeignKeys):
*
* @example
* ```ts
* async translate(args: {
* engine: SequelizeEngine;
* field: BigAutoField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* lazyEvaluate: (translatedField: TranslatedFieldToEvaluateAfterType) => void;
* }): Promise<undefined> {
* const defaultOptions = await args.fieldParser.translate(args);
*
* args.lazyEvaluate({
* fieldAttributes: defaultOptions,
* type: 'foreign-key',
* } as TranslatedFieldToEvaluateAfterType);
* }
* ```
*
* @description
* As we discussed before, the `lazyEvaluate` function is used to evaluate something after the model was translated.
* So what you pass to the `lazyEvaluate` function will be passed to `lazyEvaluateField` method on the
* `{@link AdapterFields}` instance under `fieldTranslated` argument
*
* @returns - The translated field.
*/
translate: TTranslateFunction;
/**
* @description
* This is used to parse the input value before you save it. For example, let's say that palmares by default accept
* `Date` objects for `DateField`. But your database does not support saving `Date` instances. What you can do is
* that you can implement this method on `DateFieldParser` and return a iSO string. With that, you can be 100% sure
* that the data on your `queryData` is something valid for your database.
*
* This parses the value for each data.
*
* @example
* ```ts
* async inputParser(args: {
* engine: SequelizeEngine;
* field: DateField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* value: Date | string;
* }): Promise<string> {
* if (args.value instanceof Date) return args.value.toISOString();
* return args.value;
* }
* ```
*
* @returns - The parsed value.
*/
inputParser?: TInputParserFunction;
/**
* @description
* This is used to parse the output value before you send it to the user. For example, if the user is fetching a
* `DateField` from the database, you can parse the value to a `Date` object.
* This can be useful so you can guarantee that the user will receive the data in the format that it's expected.
*
* This parses the value for each data that is retrieved.
*
* @example
* ```ts
* async outputParser(args: {
* engine: SequelizeEngine;
* field: DateField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* value: string;
* }): Promise<string> {
* if (typeof value === 'string') return new Date(value);
* return args.value;
* }
* ```
*
* @returns - The parsed value for the user for that specific field.
*/
outputParser?: TOutputParserFunction;
}): typeof AdapterBigAutoFieldParser & {
new (): AdapterFieldParser & {
translate: TTranslateFunction;
inputParser: TInputParserFunction;
outputParser: TOutputParserFunction;
};
};
/**
* This will be used to parse the fields that are going to be used in the model in the database, we call this
* class just for the `BigAutoField`
* This class can have three methods:
* - `inputParser` - Used to parse the input value before it is sent to the database on your `AdapterQuery`
* implementation.
* - `outputParser` - Used to parse the output value before it is sent to the client on your `AdapterQuery`
* implementation.
* - `translate` - Used to translate the BigAutoField to something that the database can understand.
* translated directly with the `translate` method, all other field types should define a parser with the
* `translate` field, those will be injected in the `DatabaseAdapter` class constructor.
*/
export declare class AdapterBigAutoFieldParser {
/**
* @description
* Used to translate the field to something that the database can understand. The `{@link AdapterFieldParser}`
* instance will be injected by default in the `translate` method.
* The core idea is that for every field type we will have a parser that will be used to translate the field
* to something that the database can understand. It's nice if all of the configuration options are supported
* by your ORM, but if that's not the case it's nice to notify the users through documentation.
*
* - _Note_: **If you return undefined, we will not consider that field on the object we build on `translateFields`
* under {@link AdapterModels} instance.**
* - _Note2_: **Use the `lazyEvaluate` function to evaluate something after the model was translated.**
*
* Imagine that you translating to sequelize field:
* @example
* ```ts
* async translate({
* engine,
* field,
* modelName,
* }: {
* engine: SequelizeEngine;
* field: Field;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* lazyEvaluate: (translatedField: any) => void;
* }): Promise<ModelAttributeColumnOptions> {
* const defaultOptions = {} as ModelAttributeColumnOptions;
* const isFieldAIndexOrIsFieldUnique = field.dbIndex === true || (field.unique as boolean) === true;
*
* if (isFieldAIndexOrIsFieldUnique) appendIndexes(engine.connectionName, modelName, field);
*
* const hasNotYetSetDefaultValueForField = defaultOptions.defaultValue === undefined;
* if (hasNotYetSetDefaultValueForField) defaultOptions.defaultValue = field.defaultValue;
*
* defaultOptions.autoIncrement = field.isAuto;
* defaultOptions.autoIncrementIdentity = field.isAuto;
* defaultOptions.primaryKey = field.primaryKey;
* defaultOptions.allowNull = field.allowNull;
* defaultOptions.unique = field.unique;
* defaultOptions.validate = {};
* defaultOptions.validate.notNull = !field.allowNull;
* defaultOptions.field = field.databaseName;
*
* const customAttributesOfFieldEntries = Object.entries(field.customAttributes);
* for (const [key, value] of customAttributesOfFieldEntries) {
* const keyAsTypeofModelColumnOption = key as keyof ModelAttributeColumnOptions;
* defaultOptions[keyAsTypeofModelColumnOption] = value as never;
* }
*
* const isFieldOfTypeText =
* field.typeName === TextField.name || field.typeName === CharField.name || field.typeName === UuidField.name;
*
* if (isFieldOfTypeText) this.textFieldValidations(field as TextField);
*
* return defaultOptions;
* }
* ```
*
* @description Or you can lazy evaluate (useful for ForeignKeys):
*
* @example
* ```ts
* async translate(args: {
* engine: SequelizeEngine;
* field: BigAutoField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* lazyEvaluate: (translatedField: TranslatedFieldToEvaluateAfterType) => void;
* }): Promise<undefined> {
* const defaultOptions = await args.fieldParser.translate(args);
*
* args.lazyEvaluate({
* fieldAttributes: defaultOptions,
* type: 'foreign-key',
* } as TranslatedFieldToEvaluateAfterType);
* }
* ```
*
* @description
* As we discussed before, the `lazyEvaluate` function is used to evaluate something after the model was translated.
* So what you pass to the `lazyEvaluate` function will be passed to `lazyEvaluateField` method on the
* `{@link AdapterFields}` instance under `fieldTranslated` argument
*
* @returns - The translated field.
*/
translate(args: AdapterFieldParserTranslateArgs<'big-auto'>): Promise<any>;
/**
* @description
* This is used to parse the input value before you save it. For example, let's say that palmares by default accept
* `Date` objects for `DateField`. But your database does not support saving `Date` instances. What you can do is
* that you can implement this method on `DateFieldParser` and return a iSO string. With that, you can be 100% sure
* that the data on your `queryData` is something valid for your database.
*
* This parses the value for each data.
*
* @example
* ```ts
* async inputParser(args: {
* engine: SequelizeEngine;
* field: DateField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* value: Date | string;
* }): Promise<string> {
* if (args.value instanceof Date) return args.value.toISOString();
* return args.value;
* }
* ```
*
* @returns - The parsed value.
*/
inputParser?(args: AdapterFieldParserInputAndOutputArgs<'big-auto'>): Promise<any>;
/**
* @description
* This is used to parse the output value before you send it to the user. For example, if the user is fetching a
* `DateField` from the database, you can parse the value to a `Date` object.
* This can be useful so you can guarantee that the user will receive the data in the format that it's expected.
*
* This parses the value for each data that is retrieved.
*
* @example
* ```ts
* async outputParser(args: {
* engine: SequelizeEngine;
* field: DateField;
* fieldParser: SequelizeEngineFieldParser;
* modelName: string;
* model: InstanceType<ReturnType<typeof Model>>;
* value: string;
* }): Promise<string> {
* if (typeof value === 'string') return new Date(value);
* return args.value;
* }
* ```
*
* @returns - The parsed value for the user for that specific field.
*/
outputParser?(args: AdapterFieldParserInputAndOutputArgs<'big-auto'>): Promise<any>;
}
//# sourceMappingURL=big-auto.d.ts.map