Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds iso-date-time support from ajv-formats #254

Merged
merged 1 commit into from
Oct 4, 2024
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
11 changes: 10 additions & 1 deletion src/StringSchema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,22 @@ describe('StringSchema', () => {
}
)
})
it('valid FORMATS.ISO_DATE_TIME', () => {
assert.deepStrictEqual(
StringSchema().format(FORMATS.ISO_DATE_TIME).valueOf(),
{
type: 'string',
format: 'iso-date-time'
}
)
})
it('invalid', () => {
assert.throws(
() => StringSchema().format('invalid'),
(err) =>
err instanceof S.FluentSchemaError &&
err.message ===
"'format' must be one of relative-json-pointer, json-pointer, uuid, regex, ipv6, ipv4, hostname, email, url, uri-template, uri-reference, uri, time, date, date-time"
"'format' must be one of relative-json-pointer, json-pointer, uuid, regex, ipv6, ipv4, hostname, email, url, uri-template, uri-reference, uri, time, date, date-time, iso-time, iso-date-time"
)
})
})
Expand Down
39 changes: 21 additions & 18 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict'
const deepmerge = require('@fastify/deepmerge')
const isFluentSchema = obj => obj && obj.isFluentSchema
const isFluentSchema = (obj) => obj && obj.isFluentSchema

const hasCombiningKeywords = attributes =>
const hasCombiningKeywords = (attributes) =>
attributes.allOf || attributes.anyOf || attributes.oneOf || attributes.not

class FluentSchemaError extends Error {
Expand All @@ -12,15 +12,16 @@ class FluentSchemaError extends Error {
}
}

const last = array => {
const last = (array) => {
if (!array) return
const [prop] = [...array].reverse()
return prop
}

const isUniq = array => array.filter((v, i, a) => a.indexOf(v) === i).length === array.length
const isUniq = (array) =>
array.filter((v, i, a) => a.indexOf(v) === i).length === array.length

const isBoolean = value => typeof value === 'boolean'
const isBoolean = (value) => typeof value === 'boolean'

const omit = (obj, props) =>
Object.entries(obj).reduce((memo, [key, value]) => {
Expand All @@ -31,7 +32,7 @@ const omit = (obj, props) =>
}
}, {})

const flat = array =>
const flat = (array) =>
array.reduce((memo, prop) => {
const { name, ...rest } = prop
return {
Expand All @@ -41,21 +42,17 @@ const flat = array =>
}, {})

const combineArray = (options) => {
const {
clone,
isMergeableObject,
deepmerge
} = options
const { clone, isMergeableObject, deepmerge } = options

return (target, source) => {
const result = target.slice()

source.forEach((item, index) => {
const prop = target.find(attr => attr.name === item.name)
const prop = target.find((attr) => attr.name === item.name)
if (result[index] === undefined) {
result[index] = clone(item)
} else if (isMergeableObject(prop)) {
const propIndex = target.findIndex(prop => prop.name === item.name)
const propIndex = target.findIndex((prop) => prop.name === item.name)
result[propIndex] = deepmerge(prop, item)
} else if (target.indexOf(item) === -1) {
result.push(item)
Expand All @@ -66,7 +63,7 @@ const combineArray = (options) => {
}

const combineDeepmerge = deepmerge({ mergeArray: combineArray })
const toArray = obj =>
const toArray = (obj) =>
obj && Object.entries(obj).map(([key, value]) => ({ name: key, ...value }))

const REQUIRED = Symbol('required')
Expand All @@ -87,6 +84,8 @@ const URI = 'uri'
const TIME = 'time'
const DATE = 'date'
const DATE_TIME = 'date-time'
const ISO_TIME = 'iso-time'
const ISO_DATE_TIME = 'iso-date-time'

const FORMATS = {
RELATIVE_JSON_POINTER,
Expand All @@ -103,7 +102,9 @@ const FORMATS = {
URI,
TIME,
DATE,
DATE_TIME
DATE_TIME,
ISO_TIME,
ISO_DATE_TIME
}

const STRING = 'string'
Expand Down Expand Up @@ -168,7 +169,9 @@ const appendRequired = ({

const patchedRequired = [...schema.required, ...schemaRequired]
if (!isUniq(patchedRequired)) {
throw new FluentSchemaError("'required' has repeated keys, check your calls to .required()")
throw new FluentSchemaError(
"'required' has repeated keys, check your calls to .required()"
)
}

const schemaPatched = {
Expand Down Expand Up @@ -208,13 +211,13 @@ const setRaw = ({ schema, ...options }, raw) => {
}
// TODO LS maybe we can just use setAttribute and remove this one
const setComposeType = ({ prop, schemas, schema, options }) => {
if (!(Array.isArray(schemas) && schemas.every(v => isFluentSchema(v)))) {
if (!(Array.isArray(schemas) && schemas.every((v) => isFluentSchema(v)))) {
throw new FluentSchemaError(
`'${prop}' must be a an array of FluentSchema rather than a '${typeof schemas}'`
)
}

const values = schemas.map(schema => {
const values = schemas.map((schema) => {
const { $schema, ...props } = schema.valueOf({ isRoot: false })
return props
})
Expand Down