@upstart.gg/sdk
Version:
You can test the CLI without recompiling by running:
94 lines (92 loc) • 3.96 kB
JavaScript
import "./string-enum.js";
import { FormatRegistry } from "@sinclair/typebox";
import { defaultsDeep } from "lodash-es";
import { Validator } from "@cfworker/json-schema";
//#region src/shared/utils/schema.ts
const urlValidator = (value) => {
try {
const url = new URL(value);
return url.protocol === "http:" || url.protocol === "https:";
} catch {
return false;
}
};
const noCheck = (value) => true;
FormatRegistry.Set("uuid", (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value));
FormatRegistry.Set("nanoid", (value) => /^[A-Za-z0-9_-]{7,32}$/.test(value));
FormatRegistry.Set("slug", (value) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value));
FormatRegistry.Set("richtext", noCheck);
FormatRegistry.Set("markdown", noCheck);
FormatRegistry.Set("multiline", noCheck);
FormatRegistry.Set("password", noCheck);
FormatRegistry.Set("image", urlValidator);
FormatRegistry.Set("file", urlValidator);
function normalizeSchemaEnum(schema) {
if (!("enum" in schema)) return schema.anyOf ?? schema.oneOf;
const { enum: enumValues, enumNames, "ui:icons": icons } = schema;
return enumValues.map((value, index) => ({
const: value,
title: enumNames ? enumNames[index] : value,
"ui:icon": icons ? icons[index] : void 0
}));
}
function getSchemaDefaults(schema, mode) {
if (schema.type === "object" && "properties" in schema) {
const objectSchema = schema;
const propertiesWithDefaults = {};
for (const [key, propertySchema] of Object.entries(objectSchema.properties)) {
const defaultValue = getNestedDefaults(propertySchema, mode);
if (defaultValue !== void 0) propertiesWithDefaults[key] = defaultValue;
}
return propertiesWithDefaults;
}
if (schema.type === "array" && "items" in schema) {
const arraySchema = schema;
if (mode && typeof arraySchema[`default:${mode}`] !== "undefined") return arraySchema[`default:${mode}`];
if (arraySchema.default) return arraySchema.default;
return [];
}
throw new Error("Schema must be either TObject or TArray");
}
function getNestedDefaults(schema, mode) {
if (mode && typeof schema[`default:${mode}`] !== "undefined") return schema[`default:${mode}`];
if ("default" in schema && schema.default !== void 0) return schema.default;
if (schema.type === "object" && "properties" in schema) {
const objectSchema = schema;
const required = objectSchema.required || [];
const propertiesWithDefaults = {};
for (const [key, propertySchema] of Object.entries(objectSchema.properties)) {
const defaultValue = getNestedDefaults(propertySchema, mode);
if (defaultValue !== void 0) propertiesWithDefaults[key] = defaultValue;
}
for (const requiredProp of required) if (!(requiredProp in propertiesWithDefaults)) return;
return Object.keys(propertiesWithDefaults).length > 0 ? propertiesWithDefaults : void 0;
}
if (schema.type === "array" && "items" in schema) return;
}
function filterSchemaProperties(schema, filter) {
function extractProperties(schema$1) {
const props = {};
for (const [key, prop] of Object.entries(schema$1.properties)) if (filter(prop)) props[key] = prop;
else if (prop.type === "object" && prop.properties) {
const nestedContentProps = extractProperties(prop);
if (Object.keys(nestedContentProps).length > 0) Object.assign(props, nestedContentProps);
}
return props;
}
return extractProperties(schema);
}
function validate(schema, data) {
const result = new Validator(schema, "7", false).validate(data);
if (!result.valid) {
const errors = [];
for (const error of result.errors) errors.push(`${error.error} (at ${error.keywordLocation})`);
const formatedError = `- ${errors.join("\n- ")}`;
throw new Error(formatedError);
}
const defaults = getSchemaDefaults(schema);
return Array.isArray(data) ? data : defaultsDeep({}, data, defaults);
}
//#endregion
export { filterSchemaProperties, getSchemaDefaults, normalizeSchemaEnum, validate };
//# sourceMappingURL=schema.js.map