@palmares/schemas
Version:
This defines a default schema definition for validation of data, it abstract popular schema validation libraries like zod, yup, valibot and others"
274 lines • 14.5 kB
TypeScript
import { SchemaAdapter } from './adapter';
import { schemasDomain as SchemaDomain } from './domain';
import { modelSchema } from './model';
import { ArraySchema, array } from './schema/array';
import { BooleanSchema, boolean } from './schema/boolean';
import { DatetimeSchema, datetime } from './schema/datetime';
import { NumberSchema, number } from './schema/number';
import { ObjectSchema, object } from './schema/object';
import { Schema, schema } from './schema/schema';
import { StringSchema, string } from './schema/string';
import { UnionSchema, union } from './schema/union';
import type { DefinitionsOfSchemaType, ExtractTypeFromObjectOfSchemas } from './schema/types';
import type { Narrow } from '@palmares/core';
import type { InferModel, Model, ModelFields } from '@palmares/databases';
export { FieldAdapter, fieldAdapter } from './adapter/fields';
export { NumberFieldAdapter, numberFieldAdapter } from './adapter/fields/number';
export { ObjectFieldAdapter, objectFieldAdapter } from './adapter/fields/object';
export { UnionFieldAdapter, unionFieldAdapter } from './adapter/fields/union';
export { StringFieldAdapter, stringFieldAdapter } from './adapter/fields/string';
export { ArrayFieldAdapter, arrayFieldAdapter } from './adapter/fields/array';
export { BooleanFieldAdapter, booleanFieldAdapter } from './adapter/fields/boolean';
export { DatetimeFieldAdapter, datetimeFieldAdapter } from './adapter/fields/datetime';
export type { Infer as infer } from './types';
export { setDefaultAdapter, getDefaultAdapter } from './conf';
export * from './adapter/types';
export * from './schema';
export { SchemaAdapter, NumberSchema, ObjectSchema, UnionSchema, StringSchema, ArraySchema, BooleanSchema, DatetimeSchema, Schema };
export { schema, number, object, union, string, array, datetime, boolean };
export { compile } from './compile';
export { schemaHandler } from './middleware';
export { modelSchema };
export { SchemaDomain };
export default SchemaDomain;
export declare function getSchemasWithDefaultAdapter<TAdapter extends SchemaAdapter>(): {
number: () => NumberSchema<{
input: number;
output: number;
internal: number;
representation: number;
validate: number;
}, {
schemaAdapter: TAdapter;
schemaType: "number";
hasSave: false;
context: any;
}>;
string: () => StringSchema<{
input: string;
output: string;
internal: string;
representation: string;
validate: string;
}, {
schemaAdapter: TAdapter;
schemaType: "string";
hasSave: false;
context: any;
}>;
array: <TSchemas extends readonly [Schema, ...Schema[]] | [[Schema]]>(...schemas: TSchemas) => TSchemas extends [[import("./schema/types").AllSchemaTypes]] ? ArraySchema<{
input: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "input", []>;
validate: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "validate", []>;
internal: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "internal", []>;
output: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "output", []>;
representation: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "representation", []>;
}, {
schemaAdapter: TAdapter;
schemaType: "array";
hasSave: false;
context: any;
}, TSchemas> : ArraySchema<{
input: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "input", []>;
validate: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "validate", []>;
internal: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "internal", []>;
output: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "output", []>;
representation: import("./schema/types").ExtractTypeFromArrayOfSchemas<TSchemas, "representation", []>;
}, {
schemaAdapter: TAdapter;
schemaType: "array";
hasSave: false;
context: any;
}, TSchemas> & {
maxLength: never;
minLength: never;
};
boolean: () => BooleanSchema<{
input: boolean;
validate: boolean;
internal: boolean;
output: boolean;
representation: boolean;
}, {
schemaAdapter: TAdapter;
schemaType: "boolean";
hasSave: false;
context: any;
}>;
object: <TData extends Record<any, Schema<any, any>>>(data: TData) => ObjectSchema<{
input: ExtractTypeFromObjectOfSchemas<TData, "input">;
validate: ExtractTypeFromObjectOfSchemas<TData, "validate">;
internal: ExtractTypeFromObjectOfSchemas<TData, "internal">;
representation: ExtractTypeFromObjectOfSchemas<TData, "representation">;
output: ExtractTypeFromObjectOfSchemas<TData, "output">;
}, {
schemaAdapter: TAdapter;
schemaType: "object";
hasSave: false;
context: any;
}, TData>;
union: <TSchemas extends readonly [Schema<any, any>, Schema<any, any>, ...Schema<any, any>[]]>(...schemas: Narrow<TSchemas>) => UnionSchema<{
input: import("./schema/types").ExtractTypeFromUnionOfSchemas<TSchemas, "input">;
internal: import("./schema/types").ExtractTypeFromUnionOfSchemas<TSchemas, "internal">;
output: import("./schema/types").ExtractTypeFromUnionOfSchemas<TSchemas, "output">;
representation: import("./schema/types").ExtractTypeFromUnionOfSchemas<TSchemas, "representation">;
validate: import("./schema/types").ExtractTypeFromUnionOfSchemas<TSchemas, "validate">;
}, {
schemaAdapter: TAdapter;
schemaType: "union";
hasSave: false;
context: any;
}, [Schema<any, any>, Schema<any, any>, ...Schema<any, any>[]]>;
datetime: () => DatetimeSchema<{
input: Date;
validate: Date;
internal: Date;
output: Date;
representation: Date;
}, {
schemaAdapter: TAdapter;
schemaType: "datetime";
hasSave: false;
context: any;
}>;
/**
* Different from other models, this function is a factory function that returns either an ObjectSchema or
* an ArraySchema.
* The idea is to build the schema of a model dynamically based on its fields.
*
* Another feature is that it can automatically add the foreign key relation to the schema,
* but for that you need to define the fields of the related model in the fields object.
*
* For example: A User model have a field `companyId` that is a ForeignKeyField to the Company model.
* The `relationName` is the direct relation from the User model to the Company model, and the `relatedName`
* is the reverse relation from the Company model to the User model. If you define the fieldName as either
* the relatedName or the relationName it will fetch the data automatically.
*
* **Important**: We build the schema dynamically but also lazily, if you don't try to parse or validate the
* schema, it won't be built. After the first time it's built, it's cached and never built again.
*
* **Important 2**: If you want to use the automatic relation feature, you need to define guarantee that the
* foreignKey field fieldName exists on `show` array, or that it doesn't exist on `omit` array.
*
* Like: `{ options: { show: ['id', 'name', 'companyId'] }}` or `{ options: { omit: ['id'] }}` it **will work**.
*
* If you do `{ options: { show: ['id', 'name'] }}` or `{ options: { omit: ['companyId']} }` it **won't work**.
*
* **Important 3**: If you want to return an array instead of an object, you need to pass the `many` option as true.
*
* @example
* ```typescript
* import { auto, choice, foreignKey, Model, define } from '@palmares/databases';
* import * as p from '@palmares/schemas';
*
* const Company = define('Company', {
* fields: {
* id: auto(),
* name: text(),
* },
* options: {
* tableName: 'company',
* }
* });
*
* class User extends Model<User>() {
* fields = {
* id: auto(),
* type: choice({ choices: ['user', 'admin'] }),
* companyId: foreignKey({
* relatedTo: Company,
* relationName: 'company',
* relatedName: 'usersOfCompany',
* toField: 'id',
* onDelete: 'CASCADE',
* }),
* }
*
* options = {
* tableName: 'user',
* }
* }
*
* const userSchema = p.modelSchema(User, {
* fields: {
* company: p.modelSchema(Company).optional({ outputOnly: true });
* },
* show: ['type', 'companyId']
* });
*
* const companySchema = p.modelSchema(Company, {
* fields: {
* usersOfCompany: p.modelSchema(User, { many: true }).optional({ outputOnly: true });
* },
* show: ['id', 'type']
* });
*```
* @param model - The model that you want to build the schema from.
* @param options - The options to build the schema.
* @param options.ignoreExtraneousFields - If you want to ignore extraneous fields set this to true.
* @param options.engineInstance - What engine instance you want to use to fetch the data.
* Defaults to the first one.
* @param options.fields - Extra fields that you want to add to the schema. If it has the same name as the
* model field, We will not create a schema for that field and use the one you have defined here.
* @param options.omit - Fields that you want to omit from the schema. If that is defined, we ignore `show` option.
* @param options.show - Fields that you want to show on the schema. If that is defined, we ignore `omit` option.
* @param options.many - If you want to return an array instead of an object, set this to true. With that we create
* an ArraySchema instead of an ObjectSchema.
*
* @returns - If you pass the `many` option as true, we return an ArraySchema, otherwise we return an ObjectSchema.
*/
modelSchema: <TModel extends ReturnType<typeof Model>, const TOmit extends readonly (keyof ModelFields<InstanceType<TModel>>)[] | undefined[] = undefined[], const TShow extends readonly (keyof ModelFields<InstanceType<TModel>>)[] | undefined[] = undefined[], TMany extends boolean = false, TFields extends Record<any, Schema<any, DefinitionsOfSchemaType>> | undefined = undefined, TAllModelFieldsRead = InferModel<InstanceType<TModel>, "read">, TAllModelFieldsCreate = InferModel<InstanceType<TModel>, "create">, TFieldsOnModelRead = TOmit extends undefined[] ? TShow extends undefined[] ? TAllModelFieldsRead : Pick<TAllModelFieldsRead, TShow[number] extends keyof TAllModelFieldsRead ? TShow[number] : never> : Omit<TAllModelFieldsRead, TOmit[number] extends keyof TAllModelFieldsRead ? TOmit[number] : never>, TFieldsOnModelCreateOrUpdate = TOmit extends undefined[] ? TShow extends undefined[] ? TAllModelFieldsCreate : Pick<TAllModelFieldsCreate, TShow[number] extends keyof TAllModelFieldsCreate ? TShow[number] : never> : Omit<TAllModelFieldsCreate, TOmit[number] extends keyof TAllModelFieldsCreate ? TOmit[number] : never>, TReturnType extends {
input: any;
output: any;
validate: any;
internal: any;
representation: any;
} = {
input: TFields extends undefined ? TFieldsOnModelCreateOrUpdate : Omit<TFieldsOnModelCreateOrUpdate, keyof ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "input">> & ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "input">;
output: TFields extends undefined ? TFieldsOnModelRead : Omit<TFieldsOnModelRead, keyof ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "output">> & ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "output">;
internal: TFields extends undefined ? TFieldsOnModelCreateOrUpdate : Omit<TFieldsOnModelCreateOrUpdate, keyof ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "internal">> & ExtractTypeFromObjectOfSchemas<TFields extends undefined ? {} : TFields, "internal">;
representation: TFields extends undefined ? TFieldsOnModelRead : Omit<TFieldsOnModelRead, keyof ExtractTypeFromObjectOfSchemas<TFields extends Record<any, Schema<any, DefinitionsOfSchemaType>> ? TFields : {}, "representation">> & ExtractTypeFromObjectOfSchemas<TFields extends Record<any, Schema<any, DefinitionsOfSchemaType>> ? TFields : {}, "representation">;
validate: TFields extends undefined ? TFieldsOnModelCreateOrUpdate : Omit<TFieldsOnModelCreateOrUpdate, keyof ExtractTypeFromObjectOfSchemas<TFields extends Record<any, Schema<any, DefinitionsOfSchemaType>> ? TFields : {}, "validate">> & ExtractTypeFromObjectOfSchemas<TFields extends Record<any, Schema<any, DefinitionsOfSchemaType>> ? TFields : {}, "validate">;
}>(model: TModel, options?: {
ignoreExtraneousFields?: boolean;
engineInstance?: string;
fields?: TFields;
omit?: TOmit;
omitRelation?: readonly (keyof TFields)[];
show?: TShow;
many?: TMany;
}) => TMany extends true ? ArraySchema<{
input: TReturnType["input"][];
output: TReturnType["output"][];
internal: TReturnType["internal"][];
representation: TReturnType["representation"][];
validate: TReturnType["validate"][];
}, {
schemaAdapter: TAdapter;
schemaType: "object";
context: any;
hasSave: false;
}, [ObjectSchema<{
input: TReturnType["input"];
output: TReturnType["output"];
internal: TReturnType["internal"];
representation: TReturnType["representation"];
validate: TReturnType["validate"];
}, {
schemaAdapter: TAdapter;
schemaType: "object";
context: any;
hasSave: false;
}, Record<any, any>>]> : ObjectSchema<{
input: TReturnType["input"];
output: TReturnType["output"];
internal: TReturnType["internal"];
representation: TReturnType["representation"];
validate: TReturnType["validate"];
}, {
schemaAdapter: TAdapter;
schemaType: "object";
context: any;
hasSave: false;
}, Record<any, any>>;
};
//# sourceMappingURL=index.d.ts.map