as-services/libs/utils/schema/options.js
devthejo d5febb45c8
Some checks failed
/ build (map[dockerfile:./services/tasks/Dockerfile name:tasks]) (push) Failing after 1m25s
/ deploy (push) Has been skipped
/ build (map[dockerfile:./services/files/Dockerfile name:files]) (push) Failing after 1m34s
/ build (map[dockerfile:./services/app/Dockerfile name:app]) (push) Successful in 2m9s
/ build (map[dockerfile:./services/api/Dockerfile name:api]) (push) Failing after 1m42s
/ build (map[dockerfile:./services/web/Dockerfile name:web]) (push) Failing after 1m18s
/ build (map[dockerfile:./services/watchers/Dockerfile name:watchers]) (push) Failing after 1m22s
/ build (map[dockerfile:./services/hasura/Dockerfile name:hasura]) (push) Successful in 2m3s
chore(init): available sources
2025-04-13 10:34:01 +02:00

111 lines
2.6 KiB
JavaScript

const util = require("util")
const get = require("lodash.get")
const set = require("lodash.set")
const defaultsDeep = require("lodash.defaultsdeep")
const yup = require("yup")
const optionsSchema = yup.object({
async: yup.bool(),
cast: yup.bool(),
errorFull: yup.bool(),
errorDepth: yup.number().positive().integer(),
defaults: yup.object(),
validate: yup.object(),
properties: yup.object().shape({
required: yup.bool(),
validate: yup.object(),
}),
required: yup.array().of(yup.string()),
})
const defaultOptions = {
async: false,
cast: false,
errorFull: false,
errorDepth: 2,
defaults: {},
validate: {},
required: [],
properties: {},
}
function mergeSchemas(...schemas) {
const [first, ...rest] = schemas.filter((schema) => !!schema)
const merged = rest.reduce(
(mergedSchemas, schema) => mergedSchemas.concat(schema),
first
)
return merged
}
module.exports = function createOptions(options = {}, funcName) {
defaultsDeep(options, defaultOptions)
optionsSchema.validateSync(options)
const { validate } = options
const { properties } = options
const { required } = options
for (const [k, prop] of Object.entries(properties)) {
const key = k.split(".").join(".fields.")
const validator = get(validate, key)
const { validate: validateProp, required: requiredProp } = prop
if (requiredProp) {
required.push(k)
}
set(validate, key, mergeSchemas(validator, validateProp))
}
for (const k of required) {
const key = k.split(".").join(".fields.")
const validator = get(validate, key)
if (validator) {
set(validate, key, validator.required())
} else {
set(validate, key, yup.mixed().required())
}
}
const { cast, errorFull, errorDepth } = options
const validator = yup.object(validate)
if (options.async) {
return async (opts) => {
defaultsDeep(opts, options.defaults)
try {
await validator.validate(opts)
} catch (e) {
if (funcName) {
e.message += ` calling function "${funcName}"`
}
if (!errorFull) {
e.value = util.inspect(e.value, { depth: errorDepth })
}
throw e
}
if (cast) {
Object.assign(opts, validator.cast(opts))
}
}
}
return (opts) => {
defaultsDeep(opts, options.defaults)
try {
validator.validateSync(opts)
} catch (e) {
if (funcName) {
e.message += ` calling function "${funcName}"`
}
if (!errorFull) {
e.value = util.inspect(e.value, { depth: errorDepth })
}
throw e
}
if (cast) {
Object.assign(opts, validator.cast(opts))
}
}
}