stat-tracker/module/utils/databases/model.mjs
2025-05-31 23:15:42 -06:00

113 lines
2.1 KiB
JavaScript

import * as Joi from "joi";
import { PrivacyMode } from "../privacy.mjs";
// MARK: Buckets
export const numberBucketSchema = Joi.object({
type: Joi.string().valid(`number`).required(),
min: Joi
.number()
.integer()
.when(`step`, {
is: Joi.exist(),
then: Joi.required(),
}),
max: Joi
.number()
.integer()
.when(`min`, {
is: Joi.exist(),
then: Joi.number().greater(Joi.ref(`min`)),
}),
step: Joi
.number()
.integer()
.min(1),
});
export const stringBucketSchema = Joi.object({
type: Joi.string().valid(`string`).required(),
choices: Joi
.array()
.items(
Joi.string().trim().invalid(``),
)
.min(1)
.optional(),
});
// MARK: Graphs
export const barGraphSchema = Joi.object({
type: Joi.string().valid(`bar`).required(),
stacked: Joi.boolean().optional().default(true),
showEmptyBuckets: Joi.boolean().optional().default(false),
});
// MARK: Table
export const tableSchema = Joi.object({
name: Joi
.string()
.trim()
.invalid(``)
.required()
.pattern(/^[0-9a-z \-_]+(\/[0-9a-z \-_]+)?$/i),
buckets: Joi
.alternatives()
.conditional(
`/buckets.type`,
{
switch: [
{
is: `number`,
then: numberBucketSchema,
},
{
is: `string`,
then: stringBucketSchema,
},
],
otherwise: Joi.forbidden(),
},
)
.required(),
graph: Joi
.alternatives()
.conditional(
`/graph.type`,
{
switch: [
{ is: `bar`, then: barGraphSchema },
],
otherwise: Joi.forbidden(),
},
)
.required(),
});
// MARK: Row
/**
* The schema for the row objects, this does not validate that the
* value of the row conforms to the bucket configurations, however
* it does validate that the value is at least one of the accepted
* types. For validation of the value itself check "validateValue"
* in `utils/buckets.mjs`
*/
export const rowSchema = Joi.object({
_id: Joi
.string()
.alphanum()
.required(),
timestamp: Joi
.string()
.isoDate()
.required(),
value: Joi
.alternatives([
Joi.string().trim().invalid(``),
Joi.number(),
])
.required(),
privacy: Joi
.string()
.valid(...Object.values(PrivacyMode))
.required(),
});