chore: simplifies index creation
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
/* eslint-disable class-methods-use-this */
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
/* eslint-disable no-use-before-define */
|
||||
import { IndexOptions, Schema, SchemaOptions } from 'mongoose';
|
||||
import { IndexOptions, Schema, SchemaOptions, SchemaTypeOptions } from 'mongoose';
|
||||
import { SanitizedConfig } from '../config/types';
|
||||
import { ArrayField, Block, BlockField, CheckboxField, CodeField, CollapsibleField, DateField, EmailField, Field, fieldAffectsData, fieldIsPresentationalOnly, GroupField, NonPresentationalField, NumberField, PointField, RadioField, RelationshipField, RichTextField, RowField, SelectField, TabsField, TextareaField, TextField, UploadField } from '../fields/config/types';
|
||||
|
||||
@@ -15,12 +15,17 @@ export type BuildSchemaOptions = {
|
||||
|
||||
type FieldSchemaGenerator = (field: Field, schema: Schema, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions) => void;
|
||||
|
||||
const formatBaseSchema = (field: NonPresentationalField, buildSchemaOptions: BuildSchemaOptions) => ({
|
||||
sparse: field.unique && field.localized,
|
||||
unique: (!buildSchemaOptions.disableUnique && field.unique) || false,
|
||||
required: false,
|
||||
index: field.index || field.unique || false,
|
||||
});
|
||||
const formatBaseSchema = (field: NonPresentationalField, buildSchemaOptions: BuildSchemaOptions) => {
|
||||
const schema: SchemaTypeOptions<unknown> = {
|
||||
unique: (!buildSchemaOptions.disableUnique && field.unique) || false,
|
||||
required: false,
|
||||
index: field.index || field.unique || false,
|
||||
};
|
||||
if (field.unique && field.localized) {
|
||||
schema.sparse = true;
|
||||
}
|
||||
return schema;
|
||||
};
|
||||
|
||||
const localizeSchema = (field: NonPresentationalField, schema, localization) => {
|
||||
if (field.localized && localization && Array.isArray(localization.locales)) {
|
||||
@@ -112,27 +117,39 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
|
||||
});
|
||||
},
|
||||
point: (field: PointField, schema: Schema, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions): void => {
|
||||
const baseSchema = {
|
||||
const baseSchema: SchemaTypeOptions<unknown> = {
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point'],
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number],
|
||||
sparse: (buildSchemaOptions.disableUnique && field.unique) && field.localized,
|
||||
unique: (buildSchemaOptions.disableUnique && field.unique) || false,
|
||||
required: false,
|
||||
default: field.defaultValue || undefined,
|
||||
},
|
||||
};
|
||||
if (buildSchemaOptions.disableUnique && field.unique && field.localized) {
|
||||
baseSchema.coordinates.sparse = true;
|
||||
}
|
||||
|
||||
schema.add({
|
||||
[field.name]: localizeSchema(field, baseSchema, config.localization),
|
||||
});
|
||||
|
||||
// if (field.index === true || field.index === undefined) {
|
||||
// baseSchema.index = '2dsphere';
|
||||
// }
|
||||
if (field.index === true || field.index === undefined) {
|
||||
const indexOptions: IndexOptions = {};
|
||||
if (!buildSchemaOptions.disableUnique && field.unique) {
|
||||
indexOptions.sparse = true;
|
||||
indexOptions.unique = true;
|
||||
}
|
||||
if (field.localized && config.localization) {
|
||||
config.localization.locales.forEach((locale) => {
|
||||
schema.index({ [`${field.name}.${locale}`]: '2dsphere' }, indexOptions);
|
||||
});
|
||||
} else {
|
||||
schema.index({ [field.name]: '2dsphere' }, indexOptions);
|
||||
}
|
||||
}
|
||||
},
|
||||
radio: (field: RadioField, schema: Schema, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions): void => {
|
||||
const baseSchema = {
|
||||
|
||||
@@ -19,6 +19,7 @@ const PointFields: CollectionConfig = {
|
||||
name: 'localized',
|
||||
type: 'point',
|
||||
label: 'Localized Point',
|
||||
unique: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
@@ -36,7 +37,7 @@ const PointFields: CollectionConfig = {
|
||||
|
||||
export const pointDoc = {
|
||||
point: [7, -7],
|
||||
localized: [5, -2],
|
||||
localized: [15, -12],
|
||||
group: { point: [1, 9] },
|
||||
};
|
||||
|
||||
|
||||
@@ -160,6 +160,9 @@ describe('Fields', () => {
|
||||
|
||||
describe('point', () => {
|
||||
let doc;
|
||||
const point = [7, -7];
|
||||
const localized = [5, -2];
|
||||
const group = { point: [1, 9] };
|
||||
|
||||
beforeAll(async () => {
|
||||
const findDoc = await payload.find({
|
||||
@@ -183,9 +186,6 @@ describe('Fields', () => {
|
||||
});
|
||||
|
||||
it('should create', async () => {
|
||||
const point = [7, -7];
|
||||
const localized = [5, -2];
|
||||
const group = { point: [1, 9] };
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
@@ -199,6 +199,30 @@ describe('Fields', () => {
|
||||
expect(doc.localized).toEqual(localized);
|
||||
expect(doc.group).toMatchObject(group);
|
||||
});
|
||||
|
||||
it('should not create duplicate point when unique', async () => {
|
||||
await expect(() => payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
point,
|
||||
localized,
|
||||
group,
|
||||
},
|
||||
}))
|
||||
.rejects
|
||||
.toThrow(Error);
|
||||
|
||||
await expect(async () => payload.create({
|
||||
collection: 'number-fields',
|
||||
data: {
|
||||
min: 5,
|
||||
},
|
||||
})).rejects.toThrow('The following field is invalid: min');
|
||||
|
||||
expect(doc.point).toEqual(point);
|
||||
expect(doc.localized).toEqual(localized);
|
||||
expect(doc.group).toMatchObject(group);
|
||||
});
|
||||
});
|
||||
describe('array', () => {
|
||||
let doc;
|
||||
|
||||
Reference in New Issue
Block a user