mongoose#SchemaType TypeScript Examples

The following examples show how to use mongoose#SchemaType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: built-in.ts    From pebula-node with MIT License 6 votes vote down vote up
@GtSchemaType({
  schemaType: Schema.Types.Array,
  isContainer: true,
  toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
    const arraySchemaTypeOpts: SchemaTypeOpts<any> = {
     type: [userType],
    };
    return arraySchemaTypeOpts;
  },
})
export class DocumentArray<T extends MongooseDocument> extends Types.DocumentArray<T> {

}
Example #2
Source File: schema-type.spec.ts    From pebula-node with MIT License 6 votes vote down vote up
describe('goosetyped', () => {
  describe('decorators', () => {

    it('should register a schema type definitions using GtSchemaType', () => {
      const metadata = {
        schemaType: Schema.Types.Array,
        isContainer: true,
        toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
          const arraySchemaTypeOpts: SchemaTypeOpts<any> = {
           type: [userType],
          };
          return arraySchemaTypeOpts;
        },
      };

      @GtSchemaType(metadata)
      class DocumentArray<T extends MongooseDocument> extends Types.DocumentArray<T> {}

      expect(getSchemaType(DocumentArray)).toBe(metadata);
    });

  });
});
Example #3
Source File: map.type.ts    From pebula-node with MIT License 6 votes vote down vote up
constructor(container: GtSchemaContainer, v: any, path: string, doc: any, schemaType: SchemaType) {
    super(v, path, doc, schemaType);
    if (container.localInfo.discriminator) {
      this.discriminatorKey = container.getSchemaOptions('discriminatorKey');
    }
    this[SCHEMA_CONTAINER] = container;
    const entries = [...this.entries()];
    this.clear();
    for (const [key, value] of entries) {
      this.set(key, value);
    }
  }
Example #4
Source File: schema-type-map.ts    From pebula-node with MIT License 6 votes vote down vote up
ArrayTypeMetadata: GtSchemaTypeMetadataArgs = {
  schemaType: Schema.Types.Array,
  isContainer: true,
  toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
    const arraySchemaTypeOpts: SchemaTypeOpts<any> = {
     type: [userType],
    };
    return arraySchemaTypeOpts;
  },
}
Example #5
Source File: schema-type-map.ts    From pebula-node with MIT License 6 votes vote down vote up
MapTypeMetadata: GtSchemaTypeMetadataArgs = {
  schemaType: Schema.Types.Map,
  isContainer: true,
  toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
    const mapSchemaTypeOpts: SchemaTypeOpts<any> = {
      type: reflectedType,
      of: userType,
    };
    return mapSchemaTypeOpts;
  },
}
Example #6
Source File: column-type-resolver.ts    From pebula-node with MIT License 6 votes vote down vote up
export function resolveColumnType(metadata: GtColumnMetadataArgs<any>, reflectedTsType: Ctor<any>): ResolvedColumnType {
  const { type } = metadata;
  const reflectedType = resolveType(reflectedTsType);
  let userType: ResolvedColumnType['userType'];

  if (type instanceof Schema ) {
    userType = { type };
  } else if (extendsClass(type, SchemaType)) {
    userType = {
      type: { schemaType: type },
    };
  } else {
    const runtimeType = type ? type() : undefined;
    if (runtimeType) {
      userType = resolveType(runtimeType);
    }
  }

  const isContainer = !!isContainerResolveType(reflectedType);
  const { underlyingType, schema } = createFinalColumnTypes(reflectedType, userType, metadata);
  return { schema, underlyingType, isContainer, reflectedType, userType };
}
Example #7
Source File: utils.spec.ts    From pebula-node with MIT License 6 votes vote down vote up
describe('goosetyped', () => {
  describe('Schema Builder', () => {
    describe('Column Type Logic', () => {

      it('should detect an instance of Schema', () => {
        expect(isSchemaInstance(new Schema())).toBe(true);
      });

      it('should detect if a resolved type is a container', () => {
        const nonContainerResolvedTypes = [
          { tsType: String },
          { tsType: String, type: new Schema() },
          { tsType: String, type: { schemaType: Schema.Types.String } },
        ];
        for (const c of nonContainerResolvedTypes) {
          expect(isContainerResolveType(c)).toBe(false);
        }

        const containerResolvedType = {
          tsType: Array,
          type: {
            schemaType: Schema.Types.Array,
            isContainer: true,
            toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
              return {
                type: [Schema.Types.String],
              };
            },
          },
        };
        expect(isContainerResolveType(containerResolvedType)).toBe(true);
      });

      it('should return the mongoose type from a ResolvedType', () => {
        expect(getMongoSchemaFromResolvedType({ tsType: String })).toBeFalsy();

        const schema = new Schema();
        expect(getMongoSchemaFromResolvedType({ tsType: String, type: schema })).toBe(schema);

        const schemaType = Schema.Types.String;
        expect(getMongoSchemaFromResolvedType({ tsType: String, type: { schemaType }})).toBe(schemaType);

        const containerResolvedType = {
          tsType: String,
          type: {
            schemaType: Schema.Types.Array,
            isContainer: true,
            toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
              return {
                type: [Schema.Types.String],
              };
            },
          },
        };
        expect(getMongoSchemaFromResolvedType(containerResolvedType)).toBe(Schema.Types.Array);
      });
    });
  });
});
Example #8
Source File: fields-picker.ts    From server with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Parse SchemType Objects to handle Custom Schema Options
 *
 * @param {Schema} schema - Mongoose Object Schema
 * @param {string} criteria - Custom Option in the Schema to Check
 * @returns {string[]} - Array of path names passing the criteria
 */
export default function <T, U extends Document, V extends Model<U>>(
  schema: Schema<U, V, T>,
  criteria: string,
): string[] {
  const pickedFields: string[] = [];
  schema.eachPath((path: string, schemaType: SchemaType) => {
    const keys = Object.keys(schemaType);
    const props = Object.create(schemaType);
    if (keys && props) {
      const options = props['options'];
      if (dotProp.has(options, criteria)) {
        pickedFields.push(path);
      }
    }
  });
  return pickedFields;
}
Example #9
Source File: getSchemaTypeOptions.ts    From payload with MIT License 5 votes vote down vote up
getSchemaTypeOptions = (schemaType: SchemaType): SchemaTypeOptions<{ localized: boolean }> => {
  if (schemaType?.instance === 'Array') {
    return schemaType.options.type[0];
  }

  return schemaType?.options;
}
Example #10
Source File: factory.ts    From pebula-node with MIT License 5 votes vote down vote up
export function createEmbeddedContainerForType(knownContainer: GtSchemaContainer, column: GtColumnMetadata): SchemaType {
  const newSchema = column.resolvedColumnType.reflectedType.tsType === Map
    ? new GtMapPath(knownContainer, column.key, column.schema.of)
    : new GtDocumentArrayPath(knownContainer, column.key, column.schema.type[0], column.schema)
  ;

  return newSchema;
}
Example #11
Source File: schema-explorer.ts    From pebula-node with MIT License 5 votes vote down vote up
private readonly schemaType: SchemaType;
Example #12
Source File: sanitizeFormattedValue.ts    From payload with MIT License 4 votes vote down vote up
sanitizeQueryValue = (schemaType: SchemaType, path: string, operator: string, val: any): unknown => {
  let formattedValue = val;
  const schemaOptions = getSchemaTypeOptions(schemaType);

  // Disregard invalid _ids

  if (path === '_id' && typeof val === 'string' && val.split(',').length === 1) {
    if (schemaType?.instance === 'ObjectID') {
      const isValid = mongoose.Types.ObjectId.isValid(val);

      if (!isValid) {
        return undefined;
      }
    }

    if (schemaType?.instance === 'Number') {
      const parsedNumber = parseFloat(val);

      if (Number.isNaN(parsedNumber)) {
        return undefined;
      }
    }
  }

  // Cast incoming values as proper searchable types

  if (schemaType?.instance === 'Boolean' && typeof val === 'string') {
    if (val.toLowerCase() === 'true') formattedValue = true;
    if (val.toLowerCase() === 'false') formattedValue = false;
  }

  if (schemaType?.instance === 'Number' && typeof val === 'string') {
    formattedValue = Number(val);
  }

  if ((schemaOptions?.ref || schemaOptions?.refPath) && val === 'null') {
    formattedValue = null;
  }

  // Set up specific formatting necessary by operators

  if (operator === 'near') {
    let lng;
    let lat;
    let maxDistance;
    let minDistance;

    if (Array.isArray(formattedValue)) {
      [lng, lat, maxDistance, minDistance] = formattedValue;
    }

    if (typeof formattedValue === 'string') {
      [lng, lat, maxDistance, minDistance] = createArrayFromCommaDelineated(formattedValue);
    }

    if (!lng || !lat || (!maxDistance && !minDistance)) {
      formattedValue = undefined;
    } else {
      formattedValue = {
        $geometry: { type: 'Point', coordinates: [parseFloat(lng), parseFloat(lat)] },
      };

      if (maxDistance) formattedValue.$maxDistance = parseFloat(maxDistance);
      if (minDistance) formattedValue.$minDistance = parseFloat(minDistance);
    }
  }

  if (['all', 'not_in', 'in'].includes(operator) && typeof formattedValue === 'string') {
    formattedValue = createArrayFromCommaDelineated(formattedValue);
  }

  if (schemaOptions && (schemaOptions.ref || schemaOptions.refPath) && operator === 'in') {
    if (Array.isArray(formattedValue)) {
      formattedValue = formattedValue.reduce((formattedValues, inVal) => {
        const newValues = [inVal];
        if (mongoose.Types.ObjectId.isValid(inVal)) newValues.push(new mongoose.Types.ObjectId(inVal));

        const parsedNumber = parseFloat(inVal);
        if (!Number.isNaN(parsedNumber)) newValues.push(parsedNumber);

        return [
          ...formattedValues,
          ...newValues,
        ];
      }, []);
    }
  }

  if (path !== '_id') {
    if (operator === 'contains') {
      formattedValue = { $regex: formattedValue, $options: 'i' };
    }

    if (operator === 'like' && typeof formattedValue === 'string') {
      const words = formattedValue.split(' ');
      const regex = words.reduce((pattern, word, i) => {
        return `${pattern}(?=.*\\b${word}\\b)${i + 1 === words.length ? '.+' : ''}`;
      }, '');

      formattedValue = { $regex: new RegExp(regex), $options: 'i' };
    }
  }

  if (operator === 'exists') {
    formattedValue = (formattedValue === 'true' || formattedValue === true);
  }

  return formattedValue;
}
Example #13
Source File: mongo-type-resolver.spec.ts    From pebula-node with MIT License 4 votes vote down vote up
describe('goosetyped', () => {
  describe('Schema Builder', () => {
    describe('Column Type Logic', () => {

      it('should throw if there is no mongo type match', () => {
        expect(() => getMongoType({ tsType: String }, undefined))
          .toThrowError('Invalid type definition, could not find a valid type which maps to a Schema or SchemaType');
        expect(() => getMongoType({ tsType: String }, { tsType: String }))
          .toThrowError('Invalid type definition, could not find a valid type which maps to a Schema or SchemaType');
      });

      it('should resolve the main mongo type from a single-item reflected and user resolved types', () => {
        const schema = new Schema();
        const schema1 = new Schema();
        const resolvedSchemaTypeString = { tsType: String, type: { schemaType: Schema.Types.String } };
        expect(getMongoType({ tsType: String, type: schema }, { tsType: String, type: schema1 })).toBe(schema1);
        expect(getMongoType({ tsType: String, type: schema1 }, undefined)).toBe(schema1);
        expect(getMongoType(resolvedSchemaTypeString, { tsType: String, type: { schemaType: Schema.Types.Number } })).toBe(Schema.Types.Number);
        expect(getMongoType(resolvedSchemaTypeString, undefined)).toBe(Schema.Types.String);
      });

      it('should resolve the main mongo type from a collection reflected and user resolved types', () => {
        const containerResolvedType = {
          tsType: Array,
          type: {
            schemaType: Schema.Types.Array,
            isContainer: true,
            toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
              return {
                type: [userType],
              };
            },
          },
        };
        const userResolvedType = { tsType: String, type: { schemaType: Schema.Types.Number } };
        const spy = jest.spyOn(containerResolvedType.type, 'toSchema');
        getMongoType(containerResolvedType, userResolvedType)

        expect(spy).toBeCalledTimes(1);
        expect(spy).toBeCalledWith(containerResolvedType.type.schemaType, userResolvedType.type.schemaType);
        expect(spy).toReturnWith({ type: [Schema.Types.Number] });
      });

      it('should throw when the reflected type is a collection but there is no user type provided', () => {
        const containerResolvedType = {
          tsType: Array,
          type: {
            schemaType: Schema.Types.Array,
            isContainer: true,
            toSchema(reflectedType: typeof SchemaType | Schema, userType?: typeof SchemaType | Schema) {
              return {
                type: userType,
              };
            },
          },
        };
        expect(() => getMongoType(containerResolvedType, { tsType: String, type: undefined }))
          .toThrowError('Invalid type configuration, container type requires an explicity type definition');
      });

      it('should set the default option on the final schema', () => {
        const { schema } = createFinalColumnTypes({ tsType: String, type: new Schema() }, undefined, { default: '123' });
        expect(schema.default).toBe('123');
      });

      it('should set the required option on the final schema', () => {
        const { schema } = createFinalColumnTypes({ tsType: String, type: new Schema() }, undefined, { required: '123' });
        expect(schema.required).toBe('123');
      });

      it('should set the enum option on the final schema', () => {
        const enums = ['a', 'b', 'c'];
        let column = createFinalColumnTypes({ tsType: String, type: new Schema() }, undefined, { enum: enums });
        expect(column.schema.enum).toBe(enums);

        enum TestEnum {
          a = 3,
          b = 5,
          c = 9,
        }
        column = createFinalColumnTypes({ tsType: Number, type: new Schema() }, undefined, { enum: TestEnum });
        expect(column.schema.enum)
          .toEqual([3, 5, 9]);
      });

    });
  });
});