Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "functional-models",
"version": "3.0.12",
"version": "3.0.16",
"description": "Functional models is ooey gooey framework for building and using awesome models EVERYWHERE.",
"main": "index.js",
"types": "index.d.ts",
Expand Down
12 changes: 6 additions & 6 deletions src/orm/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const _builderV2 = (data: OrmSearch): InnerBuilderV2 => {
const thisDatesBefore = (
key: string,
jsDate: Date | string,
{ valueType = DatastoreValueType.string, equalToAndBefore = true } = {}
{ valueType = DatastoreValueType.date, equalToAndBefore = true } = {}
) => {
const p = datesBefore(key, jsDate, { valueType, equalToAndBefore })
return _link(merge(data, { query: data.query.concat(p) }))
Expand All @@ -103,7 +103,7 @@ const _builderV2 = (data: OrmSearch): InnerBuilderV2 => {
const thisDatesAfter = (
key: string,
jsDate: Date | string,
{ valueType = DatastoreValueType.string, equalToAndAfter = true } = {}
{ valueType = DatastoreValueType.date, equalToAndAfter = true } = {}
) => {
const p = datesAfter(key, jsDate, { valueType, equalToAndAfter })
return _link(merge(data, { query: data.query.concat(p) }))
Expand Down Expand Up @@ -235,11 +235,11 @@ const datesAfter = (
key: string,
jsDate: Date | string,
options: { valueType: DatastoreValueType; equalToAndAfter: boolean } = {
valueType: DatastoreValueType.string,
valueType: DatastoreValueType.date,
equalToAndAfter: true,
}
): DatesAfterQuery => {
const { valueType = DatastoreValueType.string, equalToAndAfter = true } =
const { valueType = DatastoreValueType.date, equalToAndAfter = true } =
options
return {
type: 'datesAfter',
Expand Down Expand Up @@ -271,11 +271,11 @@ const datesBefore = (
key: string,
jsDate: Date | string,
options: { valueType: DatastoreValueType; equalToAndBefore: boolean } = {
valueType: DatastoreValueType.string,
valueType: DatastoreValueType.date,
equalToAndBefore: true,
}
): DatesBeforeQuery => {
const { valueType = DatastoreValueType.string, equalToAndBefore = true } =
const { valueType = DatastoreValueType.date, equalToAndBefore = true } =
options
return {
type: 'datesBefore',
Expand Down
2 changes: 2 additions & 0 deletions src/orm/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ type InnerBuilderV2 = {
complex: (subBuilderFunc: SubBuilderFunction) => BuilderV2Link
/**
* Searches for elements that are after the given date.
* NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using.
* @param key - The property name/key to use.
* @param jsDate - The date to search.
* @param options - Additional options.
Expand All @@ -756,6 +757,7 @@ type InnerBuilderV2 = {
) => BuilderV2Link
/**
* Searches for elements that are before the given date.
* NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using.
* @param key - The property name/key to use.
* @param jsDate - The date to search.
* @param options - Additional options.
Expand Down
2 changes: 1 addition & 1 deletion src/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ type DatePropertyConfig<T extends Arrayable<DataValue>> = {
formatFunction?: (date: Date, format?: string) => string
/**
* The format the date should be in. This is a framework agnostic format, and should be based on your format function.
* NOTE: If a formatFunction is not provided, this is completely ignored. For dates YYYY/MM/DD is the default and for Datetimes it is ISOString()
* NOTE: If a formatFunction is not provided, this is completely ignored. For dates YYYY-MM-DD is the default and for Datetimes it is ISOString()
*/
format?: string
} & PropertyConfig<T>
Expand Down
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type Arrayable<T> = T | readonly T[]
* A JSON compliant object.
*/
type JsonObj = Readonly<{
[s: string]: JsonAble | null
[s: string]: JsonAble | null | undefined
}>

/**
Expand All @@ -42,6 +42,7 @@ type JsonAble =
| string
| boolean
| null
| undefined

/**
* This is a fully Json compliant version of a DataDescription
Expand Down
47 changes: 30 additions & 17 deletions src/validation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import isEmpty from 'lodash/isEmpty'
import merge from 'lodash/merge'
import flatMap from 'lodash/flatMap'
import get from 'lodash/get'
import {
DataDescription,
ModelInstance,
Expand Down Expand Up @@ -417,8 +418,17 @@ const referenceTypeMatch = (
any
> => {
return (value?: ModelInstance<any, any, any>) => {
if (!value) {
return 'Must include a value'
const theType = typeof value
switch (theType) {
case 'string':
case 'number':
case 'undefined':
return undefined
default:
break
}
if (value === null) {
return undefined
}
// This needs to stay here, as it delays the creation long enough for
// self referencing types.
Expand All @@ -436,16 +446,22 @@ const referenceTypeMatch = (
}
}

/**
* A validator that can validate an entire object.
*
* @param required - If this object is required.
* @param keyToValidators - An object that has a dotted path key to the property to validate, and one or more validators for it.
*/
const objectValidator = <T extends object>({
required,
keyToValidators,
}: {
required?: boolean
keyToValidators: {
[s: string]:
| ValuePropertyValidatorComponent<any>
| ValuePropertyValidatorComponent<any>[]
}
keyToValidators: Record<
string,
| ValuePropertyValidatorComponent<any>
| ValuePropertyValidatorComponent<any>[]
>
}): ValuePropertyValidatorComponent<T> => {
return (obj: T) => {
if (!obj) {
Expand All @@ -459,16 +475,13 @@ const objectValidator = <T extends object>({
return isNotObj
}
return (
Object.entries(obj)
.reduce((acc, [key, value]) => {
const validators = keyToValidators[key]
if (!validators) {
return acc
}
const validator = Array.isArray(validators)
? multiValidator(validators)
: validators
const error = validator(value)
Object.entries(keyToValidators)
.reduce((acc, [key, validator]) => {
const theValidator = Array.isArray(validator)
? multiValidator(validator)
: (validator as ValuePropertyValidatorComponent<any>)
const value = get(obj, key)
const error = theValidator(value)
if (error) {
return acc.concat(`${key}: ${error}`)
}
Expand Down
8 changes: 4 additions & 4 deletions test/src/orm/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ describe('/src/orm/query.ts', () => {
type: 'datesBefore',
key: 'my-key',
date: '2025-01-01T00:00:00.000Z',
valueType: DatastoreValueType.string,
valueType: DatastoreValueType.date,
options: {
equalToAndBefore: true,
},
Expand Down Expand Up @@ -497,7 +497,7 @@ describe('/src/orm/query.ts', () => {
type: 'datesAfter',
key: 'my-key',
date: '2025-01-01T00:00:00.000Z',
valueType: DatastoreValueType.string,
valueType: DatastoreValueType.date,
options: {
equalToAndAfter: true,
},
Expand Down Expand Up @@ -725,7 +725,7 @@ describe('/src/orm/query.ts', () => {
type: 'datesBefore',
key: 'my-key',
date: '2020-01-01',
valueType: 'string',
valueType: 'date',
options: {
equalToAndBefore: true,
},
Expand All @@ -746,7 +746,7 @@ describe('/src/orm/query.ts', () => {
type: 'datesAfter',
key: 'my-key',
date: '2020-01-01',
valueType: 'string',
valueType: 'date',
options: {
equalToAndAfter: true,
},
Expand Down
8 changes: 4 additions & 4 deletions test/src/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ describe('/src/validation.ts', () => {
})
})
describe('#referenceTypeMatch()', () => {
it('should return an error if undefined is passed as a value', () => {
it('should return undefined if undefined is passed as a value', () => {
const myModel = TestModel1.create({})
const actual = referenceTypeMatch(TestModel1)(
// @ts-ignore
Expand All @@ -778,9 +778,9 @@ describe('/src/validation.ts', () => {
{},
{}
)
assert.isOk(actual)
assert.isUndefined(actual)
})
it('should return an error if null is passed as a value', () => {
it('should return undefined if null is passed as a value', () => {
const myModel = TestModel1.create({})
const actual = referenceTypeMatch(TestModel1)(
// @ts-ignore
Expand All @@ -789,7 +789,7 @@ describe('/src/validation.ts', () => {
{},
{}
)
assert.isOk(actual)
assert.isUndefined(actual)
})
it('should allow a function for a model', async () => {
const myModel = EMPTY_MODEL.create({})
Expand Down