chore: simplifies index creation

This commit is contained in:
Dan Ribbens
2022-08-15 16:54:23 -04:00
parent 48f929f3ab
commit 2ca526bd22
3 changed files with 59 additions and 17 deletions

View File

@@ -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 = {

View File

@@ -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] },
};

View File

@@ -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;