added format command and added trailing commas to reduce conflicts

This commit is contained in:
dswbx
2025-02-26 20:06:03 +01:00
parent 88b5359f1c
commit 7743f71a11
414 changed files with 3622 additions and 3610 deletions

View File

@@ -10,7 +10,7 @@ export class MemoryCache<Data = any> implements ICachePool<Data> {
supports = () => ({
metadata: true,
clear: true
clear: true,
});
async get(key: string): Promise<MemoryCacheItem<Data>> {
@@ -61,7 +61,7 @@ export class MemoryCache<Data = any> implements ICachePool<Data> {
async put(
key: string,
value: Data,
options: { expiresAt?: Date; ttl?: number; metadata?: Record<string, string> } = {}
options: { expiresAt?: Date; ttl?: number; metadata?: Record<string, string> } = {},
): Promise<boolean> {
const item = await this.get(key);
item.set(value, options.metadata || {});

View File

@@ -17,9 +17,9 @@ export const config = {
server: {
default_port: 1337,
// resetted to root for now, bc bundling with vite
assets_path: "/"
assets_path: "/",
},
data: {
default_primary_field: "id"
}
default_primary_field: "id",
},
} as const;

View File

@@ -26,7 +26,7 @@ const originalConsoles = {
warn: console.warn,
info: console.info,
log: console.log,
debug: console.debug
debug: console.debug,
} as typeof console;
function __tty(type: any, args: any[]) {
@@ -34,25 +34,25 @@ function __tty(type: any, args: any[]) {
const styles = {
error: {
prefix: colors.red,
args: colors.red
args: colors.red,
},
warn: {
prefix: colors.yellow,
args: colors.yellow
args: colors.yellow,
},
info: {
prefix: colors.cyan
prefix: colors.cyan,
},
log: {
prefix: colors.dim
prefix: colors.dim,
},
debug: {
prefix: colors.yellow
}
prefix: colors.yellow,
},
} as const;
const prefix = styles[type].prefix(`[${type.toUpperCase()}]`);
const _args = args.map((a) =>
"args" in styles[type] && has && typeof a === "string" ? styles[type].args(a) : a
"args" in styles[type] && has && typeof a === "string" ? styles[type].args(a) : a,
);
return originalConsoles[type](prefix, colors.gray(datetimeStringLocal()), ..._args);
}
@@ -78,13 +78,13 @@ export const $console = new Proxy(
return (...args: any[]) => __tty(prop, args);
}
return () => null;
}
}
},
},
) as typeof console;
export async function withDisabledConsole<R>(
fn: () => Promise<R>,
sev?: TConsoleSeverity[]
sev?: TConsoleSeverity[],
): Promise<R> {
disableConsole(sev);
try {

View File

@@ -19,7 +19,7 @@ export class Exception extends Error {
return {
error: this.message,
type: this.name,
context: this._context
context: this._context,
};
}
}
@@ -28,7 +28,7 @@ export class BkndError extends Error {
constructor(
message: string,
public details?: Record<string, any>,
public type?: string
public type?: string,
) {
super(message);
}
@@ -41,7 +41,7 @@ export class BkndError extends Error {
return {
type: this.type ?? "unknown",
message: this.message,
details: this.details
details: this.details,
};
}
}

View File

@@ -20,7 +20,7 @@ export abstract class Event<Params = any, Returning = void> {
protected clone<This extends Event<Params, Returning> = Event<Params, Returning>>(
this: This,
params: Params
params: Params,
): This {
const cloned = new (this.constructor as any)(params);
cloned.returned = true;
@@ -50,7 +50,7 @@ export class InvalidEventReturn extends Error {
export class EventReturnedWithoutValidation extends Error {
constructor(
event: EventClass,
public data: any
public data: any,
) {
// @ts-expect-error slug is static
super(`Event "${event.constructor.slug}" returned without validation`);

View File

@@ -6,7 +6,7 @@ export type ListenerMode = (typeof ListenerModes)[number];
export type ListenerHandler<E extends Event<any, any>> = (
event: E,
slug: string
slug: string,
) => E extends Event<any, infer R> ? R | Promise<R | void> : never;
export class EventListener<E extends Event = Event> {
@@ -20,7 +20,7 @@ export class EventListener<E extends Event = Event> {
event: EventClass,
handler: ListenerHandler<E>,
mode: ListenerMode = "async",
id?: string
id?: string,
) {
this.event = event;
this.handler = handler;

View File

@@ -17,7 +17,7 @@ export interface EmitsEvents {
export type { EventClass };
export class EventManager<
RegisteredEvents extends Record<string, EventClass> = Record<string, EventClass>
RegisteredEvents extends Record<string, EventClass> = Record<string, EventClass>,
> {
protected events: EventClass[] = [];
protected listeners: EventListener[] = [];
@@ -30,7 +30,7 @@ export class EventManager<
onError?: (event: Event, e: unknown) => void;
onInvalidReturn?: (event: Event, e: InvalidEventReturn) => void;
asyncExecutor?: typeof Promise.all;
}
},
) {
if (events) {
this.registerEvents(events);
@@ -69,7 +69,7 @@ export class EventManager<
return new Proxy(this, {
get: (_, prop: string) => {
return this.events.find((e) => e.slug === prop);
}
},
}) as any;
}
@@ -141,7 +141,7 @@ export class EventManager<
protected createEventListener(
_event: EventClass | string,
handler: ListenerHandler<any>,
_config: RegisterListenerConfig = "async"
_config: RegisterListenerConfig = "async",
) {
const event =
typeof _event === "string" ? this.events.find((e) => e.slug === _event)! : _event;
@@ -159,7 +159,7 @@ export class EventManager<
onEvent<ActualEvent extends EventClass, Instance extends InstanceType<ActualEvent>>(
event: ActualEvent,
handler: ListenerHandler<Instance>,
config?: RegisterListenerConfig
config?: RegisterListenerConfig,
) {
this.createEventListener(event, handler, config);
}
@@ -167,7 +167,7 @@ export class EventManager<
on<Params = any>(
slug: string,
handler: ListenerHandler<Event<Params>>,
config?: RegisterListenerConfig
config?: RegisterListenerConfig,
) {
this.createEventListener(slug, handler, config);
}
@@ -225,7 +225,7 @@ export class EventManager<
if (!newEvent.returned) {
throw new Error(
// @ts-expect-error slug is static
`Returned event ${newEvent.constructor.slug} must be marked as returned.`
`Returned event ${newEvent.constructor.slug} must be marked as returned.`,
);
}
_event = newEvent as Actual;

View File

@@ -3,6 +3,6 @@ export {
EventListener,
ListenerModes,
type ListenerMode,
type ListenerHandler
type ListenerHandler,
} from "./EventListener";
export { EventManager, type EmitsEvents, type EventClass } from "./EventManager";

View File

@@ -9,7 +9,7 @@ export {
SimpleRenderer,
type TemplateObject,
type TemplateTypes,
type SimpleRendererOptions
type SimpleRendererOptions,
} from "./template/SimpleRenderer";
export { SchemaObject } from "./object/SchemaObject";
export { DebugLogger } from "./utils/DebugLogger";
@@ -22,7 +22,7 @@ export {
isPrimitive,
type TExpression,
type BooleanLike,
isBooleanLike
isBooleanLike,
} from "./object/query/query";
export { Registry, type Constructor } from "./registry/Registry";

View File

@@ -6,14 +6,14 @@ import {
getFullPathKeys,
mergeObjectWith,
parse,
stripMark
stripMark,
} from "../utils";
export type SchemaObjectOptions<Schema extends TObject> = {
onUpdate?: (config: Static<Schema>) => void | Promise<void>;
onBeforeUpdate?: (
from: Static<Schema>,
to: Static<Schema>
to: Static<Schema>,
) => Static<Schema> | Promise<Static<Schema>>;
restrictPaths?: string[];
overwritePaths?: (RegExp | string)[];
@@ -29,13 +29,13 @@ export class SchemaObject<Schema extends TObject> {
constructor(
private _schema: Schema,
initial?: Partial<Static<Schema>>,
private options?: SchemaObjectOptions<Schema>
private options?: SchemaObjectOptions<Schema>,
) {
this._default = Default(_schema, {} as any) as any;
this._value = initial
? parse(_schema, structuredClone(initial as any), {
forceParse: this.isForceParse(),
skipMark: this.isForceParse()
skipMark: this.isForceParse(),
})
: this._default;
this._config = Object.freeze(this._value);
@@ -71,7 +71,7 @@ export class SchemaObject<Schema extends TObject> {
async set(config: Static<Schema>, noEmit?: boolean): Promise<Static<Schema>> {
const valid = parse(this._schema, structuredClone(config) as any, {
forceParse: true,
skipMark: this.isForceParse()
skipMark: this.isForceParse(),
});
// regardless of "noEmit" this should always be triggered
const updatedConfig = await this.onBeforeUpdate(this._config, valid);
@@ -159,7 +159,7 @@ export class SchemaObject<Schema extends TObject> {
overwritePaths.some((k2) => {
//console.log("keep?", { k, k2 }, k2 !== k && k2.startsWith(k));
return k2 !== k && k2.startsWith(k);
})
}),
)
: overwritePaths;
//console.log("specific", specific);

View File

@@ -1,7 +1,7 @@
enum Change {
Add = "a",
Remove = "r",
Edit = "e"
Edit = "e",
}
type Object = object;
@@ -50,7 +50,7 @@ function diff(oldObj: Object, newObj: Object): DiffEntry[] {
t: Change.Edit,
p: path,
o: oldValue,
n: newValue
n: newValue,
});
} else if (Array.isArray(oldValue) && Array.isArray(newValue)) {
const maxLength = Math.max(oldValue.length, newValue.length);
@@ -60,14 +60,14 @@ function diff(oldObj: Object, newObj: Object): DiffEntry[] {
t: Change.Add,
p: [...path, i],
o: undefined,
n: newValue[i]
n: newValue[i],
});
} else if (i >= newValue.length) {
diffs.push({
t: Change.Remove,
p: [...path, i],
o: oldValue[i],
n: undefined
n: undefined,
});
} else {
recurse(oldValue[i], newValue[i], [...path, i]);
@@ -83,14 +83,14 @@ function diff(oldObj: Object, newObj: Object): DiffEntry[] {
t: Change.Add,
p: [...path, key],
o: undefined,
n: newValue[key]
n: newValue[key],
});
} else if (!(key in newValue)) {
diffs.push({
t: Change.Remove,
p: [...path, key],
o: oldValue[key],
n: undefined
n: undefined,
});
} else {
recurse(oldValue[key], newValue[key], [...path, key]);
@@ -101,7 +101,7 @@ function diff(oldObj: Object, newObj: Object): DiffEntry[] {
t: Change.Edit,
p: path,
o: oldValue,
n: newValue
n: newValue,
});
}
}

View File

@@ -4,12 +4,12 @@ const expressions = [
exp(
"$eq",
(v: Primitive) => isPrimitive(v),
(e, a) => e === a
(e, a) => e === a,
),
exp(
"$ne",
(v: Primitive) => isPrimitive(v),
(e, a) => e !== a
(e, a) => e !== a,
),
exp(
"$like",
@@ -25,7 +25,7 @@ const expressions = [
default:
return false;
}
}
},
),
exp(
"$regex",
@@ -39,54 +39,54 @@ const expressions = [
return regex.test(a);
}
return false;
}
},
),
exp(
"$isnull",
(v: boolean | 1 | 0) => true,
(e, a) => (e ? a === null : a !== null)
(e, a) => (e ? a === null : a !== null),
),
exp(
"$notnull",
(v: boolean | 1 | 0) => true,
(e, a) => (e ? a !== null : a === null)
(e, a) => (e ? a !== null : a === null),
),
exp(
"$in",
(v: (string | number)[]) => Array.isArray(v),
(e: any, a: any) => e.includes(a)
(e: any, a: any) => e.includes(a),
),
exp(
"$notin",
(v: (string | number)[]) => Array.isArray(v),
(e: any, a: any) => !e.includes(a)
(e: any, a: any) => !e.includes(a),
),
exp(
"$gt",
(v: number) => typeof v === "number",
(e: any, a: any) => a > e
(e: any, a: any) => a > e,
),
exp(
"$gte",
(v: number) => typeof v === "number",
(e: any, a: any) => a >= e
(e: any, a: any) => a >= e,
),
exp(
"$lt",
(v: number) => typeof v === "number",
(e: any, a: any) => a < e
(e: any, a: any) => a < e,
),
exp(
"$lte",
(v: number) => typeof v === "number",
(e: any, a: any) => a <= e
(e: any, a: any) => a <= e,
),
exp(
"$between",
(v: [number, number]) =>
Array.isArray(v) && v.length === 2 && v.every((n) => typeof n === "number"),
(e: any, a: any) => e[0] <= a && a <= e[1]
)
(e: any, a: any) => e[0] <= a && a <= e[1],
),
];
export type ObjectQuery = FilterQuery<typeof expressions>;

View File

@@ -13,7 +13,7 @@ export class Expression<Key, Expect = unknown, CTX = any> {
constructor(
public key: Key,
public valid: (v: Expect) => boolean,
public validate: (e: any, a: any, ctx: CTX) => any
public validate: (e: any, a: any, ctx: CTX) => any,
) {}
}
export type TExpression<Key, Expect = unknown, CTX = any> = Expression<Key, Expect, CTX>;
@@ -21,7 +21,7 @@ export type TExpression<Key, Expect = unknown, CTX = any> = Expression<Key, Expe
export function exp<const Key, const Expect, CTX = any>(
key: Key,
valid: (v: Expect) => boolean,
validate: (e: Expect, a: unknown, ctx: CTX) => any
validate: (e: Expect, a: unknown, ctx: CTX) => any,
): Expression<Key, Expect, CTX> {
return new Expression(key, valid, validate);
}
@@ -38,7 +38,7 @@ type ExpressionCondition<Exps extends Expressions> = {
function getExpression<Exps extends Expressions>(
expressions: Exps,
key: string
key: string,
): Expression<any, any> {
const exp = expressions.find((e) => e.key === key);
if (!exp) throw new Error(`Expression does not exist: "${key}"`);
@@ -61,7 +61,7 @@ export type FilterQuery<Exps extends Expressions> =
function _convert<Exps extends Expressions>(
$query: FilterQuery<Exps>,
expressions: Exps,
path: string[] = []
path: string[] = [],
): FilterQuery<Exps> {
//console.log("-----------------");
const ExpressionConditionKeys = expressions.map((e) => e.key);
@@ -98,7 +98,7 @@ function _convert<Exps extends Expressions>(
} else if (typeof value === "object") {
// when object is given, check if all keys are expressions
const invalid = Object.keys(value).filter(
(f) => !ExpressionConditionKeys.includes(f as any)
(f) => !ExpressionConditionKeys.includes(f as any),
);
if (invalid.length === 0) {
newQuery[key] = {};
@@ -109,7 +109,7 @@ function _convert<Exps extends Expressions>(
}
} else {
throw new Error(
`Invalid key(s) at "${key}": ${invalid.join(", ")}. Expected expressions.`
`Invalid key(s) at "${key}": ${invalid.join(", ")}. Expected expressions.`,
);
}
}
@@ -128,7 +128,7 @@ type BuildOptions = {
function _build<Exps extends Expressions>(
_query: FilterQuery<Exps>,
expressions: Exps,
options: BuildOptions
options: BuildOptions,
): ValidationResults {
const $query = options.convert ? _convert<Exps>(_query, expressions) : _query;
@@ -137,7 +137,7 @@ function _build<Exps extends Expressions>(
const result: ValidationResults = {
$and: [],
$or: [],
keys: new Set<string>()
keys: new Set<string>(),
};
const { $or, ...$and } = $query;
@@ -187,7 +187,7 @@ function _build<Exps extends Expressions>(
function _validate(results: ValidationResults): boolean {
const matches: { $and?: boolean; $or?: boolean } = {
$and: undefined,
$or: undefined
$or: undefined,
};
matches.$and = results.$and.every((r) => Boolean(r));
@@ -204,6 +204,6 @@ export function makeValidator<Exps extends Expressions>(expressions: Exps) {
validate: (query: FilterQuery<Exps>, options: BuildOptions) => {
const fns = _build(query, expressions, options);
return _validate(fns);
}
},
};
}

View File

@@ -5,7 +5,7 @@ export type RegisterFn<Item> = (unknown: any) => Item;
export class Registry<
Item,
Items extends Record<string, Item> = Record<string, Item>,
Fn extends RegisterFn<Item> = RegisterFn<Item>
Fn extends RegisterFn<Item> = RegisterFn<Item>,
> {
private is_set: boolean = false;
private items: Items = {} as Items;

View File

@@ -5,7 +5,7 @@ export class Permission<Name extends string = string> {
toJSON() {
return {
name: this.name
name: this.name,
};
}
}

View File

@@ -7,7 +7,7 @@ export type FlashMessageType = "error" | "warning" | "success" | "info";
export function addFlashMessage(c: Context, message: string, type: FlashMessageType = "info") {
if (c.req.header("Accept")?.includes("text/html")) {
setCookie(c, flash_key, JSON.stringify({ type, message }), {
path: "/"
path: "/",
});
}
}
@@ -28,7 +28,7 @@ function getCookieValue(name) {
}
export function getFlashMessage(
clear = true
clear = true,
): { type: FlashMessageType; message: string } | undefined {
const flash = getCookieValue(flash_key);
if (flash && clear) {

View File

@@ -5,7 +5,7 @@ import { validator } from "hono/validator";
type Hook<T, E extends Env, P extends string> = (
result: { success: true; data: T } | { success: false; errors: ValueError[] },
c: Context<E, P>
c: Context<E, P>,
) => Response | Promise<Response> | void;
export function tbValidator<
@@ -13,7 +13,7 @@ export function tbValidator<
Target extends keyof ValidationTargets,
E extends Env,
P extends string,
V extends { in: { [K in Target]: StaticDecode<T> }; out: { [K in Target]: StaticDecode<T> } }
V extends { in: { [K in Target]: StaticDecode<T> }; out: { [K in Target]: StaticDecode<T> } },
>(target: Target, schema: T, hook?: Hook<StaticDecode<T>, E, P>): MiddlewareHandler<E, P, V> {
// Compile the provided schema once rather than per validation. This could be optimized further using a shared schema
// compilation pool similar to the Fastify implementation.

View File

@@ -14,7 +14,7 @@ export class SimpleRenderer {
constructor(
private variables: Record<string, any> = {},
private options: SimpleRendererOptions = {}
private options: SimpleRendererOptions = {},
) {}
another() {
@@ -48,7 +48,7 @@ export class SimpleRenderer {
return (await this.renderString(template)) as unknown as Given;
} else if (Array.isArray(template)) {
return (await Promise.all(
template.map((item) => this.render(item))
template.map((item) => this.render(item)),
)) as unknown as Given;
} else if (typeof template === "object") {
return (await this.renderObject(template)) as unknown as Given;
@@ -61,8 +61,8 @@ export class SimpleRenderer {
kind: e.token.kind,
input: e.token.input,
begin: e.token.begin,
end: e.token.end
}
end: e.token.end,
},
};
throw new BkndError(e.message, details, "liquid");

View File

@@ -1,4 +1,4 @@
export interface Serializable<Class, Json extends object = object> {
toJSON(): Json;
fromJSON(json: Json): Class;
}
}

View File

@@ -20,7 +20,7 @@ export const hash = {
sha256: async (input: string, salt?: string, pepper?: string) =>
digest("SHA-256", input, salt, pepper),
sha1: async (input: string, salt?: string, pepper?: string) =>
digest("SHA-1", input, salt, pepper)
digest("SHA-1", input, salt, pepper),
};
export async function checksum(s: any) {

View File

@@ -14,7 +14,7 @@ export function isObject(value: unknown): value is Record<string, unknown> {
export function omitKeys<T extends object, K extends keyof T>(
obj: T,
keys_: readonly K[]
keys_: readonly K[],
): Omit<T, Extract<K, keyof T>> {
const keys = new Set(keys_);
const result = {} as Omit<T, Extract<K, keyof T>>;
@@ -47,7 +47,7 @@ export function keepChanged<T extends object>(origin: T, updated: T): Partial<T>
}
return acc;
},
{} as Partial<T>
{} as Partial<T>,
);
}
@@ -66,13 +66,13 @@ export function objectKeysPascalToKebab(obj: any, ignoreKeys: string[] = []): an
acc[kebabKey] = objectKeysPascalToKebab(obj[key], ignoreKeys);
return acc;
},
{} as Record<string, any>
{} as Record<string, any>,
);
}
export function filterKeys<Object extends { [key: string]: any }>(
obj: Object,
keysToFilter: string[]
keysToFilter: string[],
): Object {
const result = {} as Object;
@@ -92,7 +92,7 @@ export function filterKeys<Object extends { [key: string]: any }>(
export function transformObject<T extends Record<string, any>, U>(
object: T,
transform: (value: T[keyof T], key: keyof T) => U | undefined
transform: (value: T[keyof T], key: keyof T) => U | undefined,
): { [K in keyof T]: U } {
return Object.entries(object).reduce(
(acc, [key, value]) => {
@@ -102,20 +102,20 @@ export function transformObject<T extends Record<string, any>, U>(
}
return acc;
},
{} as { [K in keyof T]: U }
{} as { [K in keyof T]: U },
);
}
export const objectTransform = transformObject;
export function objectEach<T extends Record<string, any>, U>(
object: T,
each: (value: T[keyof T], key: keyof T) => U
each: (value: T[keyof T], key: keyof T) => U,
): void {
Object.entries(object).forEach(
([key, value]) => {
each(value, key);
},
{} as { [K in keyof T]: U }
{} as { [K in keyof T]: U },
);
}
@@ -291,7 +291,7 @@ export function isEqual(value1: any, value2: any): boolean {
return "plainObject";
if (value instanceof Function) return "function";
throw new Error(
`deeply comparing an instance of type ${value1.constructor?.name} is not supported.`
`deeply comparing an instance of type ${value1.constructor?.name} is not supported.`,
);
};
@@ -336,7 +336,7 @@ export function isEqual(value1: any, value2: any): boolean {
export function getPath(
object: object,
_path: string | (string | number)[],
defaultValue = undefined
defaultValue = undefined,
): any {
const path = typeof _path === "string" ? _path.split(/[.\[\]\"]+/).filter((x) => x) : _path;

View File

@@ -161,11 +161,11 @@ const FILE_SIGNATURES: Record<string, string> = {
FFF9: "audio/aac",
"52494646????41564920": "audio/wav",
"52494646????57415645": "audio/wave",
"52494646????415550": "audio/aiff"
"52494646????415550": "audio/aiff",
};
async function detectMimeType(
input: ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob | File | null
input: ReadableStream | ArrayBuffer | ArrayBufferView | string | Blob | File | null,
): Promise<string | undefined> {
if (!input) return;
@@ -202,7 +202,7 @@ async function detectMimeType(
export async function blobToFile(
blob: Blob | File | unknown,
overrides: FilePropertyBag & { name?: string } = {}
overrides: FilePropertyBag & { name?: string } = {},
): Promise<File> {
if (isFile(blob)) return blob;
if (!isBlob(blob)) throw new Error("Not a Blob");
@@ -215,7 +215,7 @@ export async function blobToFile(
return new File([blob], name, {
type: type || guess(name),
lastModified: Date.now()
lastModified: Date.now(),
});
}
@@ -340,5 +340,5 @@ export const enum HttpStatus {
INSUFFICIENT_STORAGE = 507,
LOOP_DETECTED = 508,
NOT_EXTENDED = 510,
NETWORK_AUTHENTICATION_REQUIRED = 511
NETWORK_AUTHENTICATION_REQUIRED = 511,
}

View File

@@ -28,7 +28,7 @@ export function getRuntimeKey(): string {
const features = {
// supports the redirect of not full qualified addresses
// not supported in nextjs
redirects_non_fq: true
redirects_non_fq: true,
};
export function runtimeSupports(feature: keyof typeof features) {

View File

@@ -2,17 +2,17 @@ type ConsoleSeverity = "log" | "warn" | "error";
const _oldConsoles = {
log: console.log,
warn: console.warn,
error: console.error
error: console.error,
};
export async function withDisabledConsole<R>(
fn: () => Promise<R>,
severities: ConsoleSeverity[] = ["log", "warn", "error"]
severities: ConsoleSeverity[] = ["log", "warn", "error"],
): Promise<R> {
const _oldConsoles = {
log: console.log,
warn: console.warn,
error: console.error
error: console.error,
};
disableConsoleLog(severities);
const enable = () => {
@@ -57,6 +57,6 @@ export function formatMemoryUsage() {
rss: usage.rss / 1024 / 1024,
heapUsed: usage.heapUsed / 1024 / 1024,
external: usage.external / 1024 / 1024,
arrayBuffers: usage.arrayBuffers / 1024 / 1024
arrayBuffers: usage.arrayBuffers / 1024 / 1024,
};
}

View File

@@ -56,6 +56,7 @@ const IsSArray = (value: unknown): value is SArray =>
!Type.ValueGuard.IsArray(value.items) &&
Type.ValueGuard.IsObject(value.items);
const IsSConst = (value: unknown): value is SConst =>
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsObject(value["const"]);
const IsSString = (value: unknown): value is SString =>
Type.ValueGuard.IsObject(value) && IsExact(value.type, "string");
@@ -68,7 +69,7 @@ const IsSBoolean = (value: unknown): value is SBoolean =>
const IsSNull = (value: unknown): value is SBoolean =>
Type.ValueGuard.IsObject(value) && IsExact(value.type, "null");
const IsSProperties = (value: unknown): value is SProperties => Type.ValueGuard.IsObject(value);
// prettier-ignore
// biome-ignore format: keep
const IsSObject = (value: unknown): value is SObject => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'object') && IsSProperties(value.properties) && (value.required === undefined || Type.ValueGuard.IsArray(value.required) && value.required.every((value: unknown) => Type.ValueGuard.IsString(value)))
type SValue = string | number | boolean;
type SEnum = Readonly<{ enum: readonly SValue[] }>;
@@ -88,8 +89,9 @@ type SNull = Readonly<{ type: "null" }>;
// ------------------------------------------------------------------
// FromRest
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromRest<T extends readonly unknown[], Acc extends Type.TSchema[] = []> = (
// biome-ignore lint/complexity/noUselessTypeConstraint: <explanation>
T extends readonly [infer L extends unknown, ...infer R extends unknown[]]
? TFromSchema<L> extends infer S extends Type.TSchema
? TFromRest<R, [...Acc, S]>
@@ -102,7 +104,7 @@ function FromRest<T extends readonly unknown[]>(T: T): TFromRest<T> {
// ------------------------------------------------------------------
// FromEnumRest
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromEnumRest<T extends readonly SValue[], Acc extends Type.TSchema[] = []> = (
T extends readonly [infer L extends SValue, ...infer R extends SValue[]]
? TFromEnumRest<R, [...Acc, Type.TLiteral<L>]>
@@ -114,7 +116,7 @@ function FromEnumRest<T extends readonly SValue[]>(T: T): TFromEnumRest<T> {
// ------------------------------------------------------------------
// AllOf
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromAllOf<T extends SAllOf> = (
TFromRest<T['allOf']> extends infer Rest extends Type.TSchema[]
? Type.TIntersectEvaluated<Rest>
@@ -126,7 +128,7 @@ function FromAllOf<T extends SAllOf>(T: T): TFromAllOf<T> {
// ------------------------------------------------------------------
// AnyOf
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromAnyOf<T extends SAnyOf> = (
TFromRest<T['anyOf']> extends infer Rest extends Type.TSchema[]
? Type.TUnionEvaluated<Rest>
@@ -138,7 +140,7 @@ function FromAnyOf<T extends SAnyOf>(T: T): TFromAnyOf<T> {
// ------------------------------------------------------------------
// OneOf
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromOneOf<T extends SOneOf> = (
TFromRest<T['oneOf']> extends infer Rest extends Type.TSchema[]
? Type.TUnionEvaluated<Rest>
@@ -150,7 +152,7 @@ function FromOneOf<T extends SOneOf>(T: T): TFromOneOf<T> {
// ------------------------------------------------------------------
// Enum
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromEnum<T extends SEnum> = (
TFromEnumRest<T['enum']> extends infer Elements extends Type.TSchema[]
? Type.TUnionEvaluated<Elements>
@@ -162,33 +164,33 @@ function FromEnum<T extends SEnum>(T: T): TFromEnum<T> {
// ------------------------------------------------------------------
// Tuple
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromTuple<T extends STuple> = (
TFromRest<T['items']> extends infer Elements extends Type.TSchema[]
? Type.TTuple<Elements>
: Type.TTuple<[]>
)
// prettier-ignore
// biome-ignore format: keep
function FromTuple<T extends STuple>(T: T): TFromTuple<T> {
return Type.Tuple(FromRest(T.items), T) as never
}
// ------------------------------------------------------------------
// Array
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromArray<T extends SArray> = (
TFromSchema<T['items']> extends infer Items extends Type.TSchema
? Type.TArray<Items>
: Type.TArray<Type.TUnknown>
)
// prettier-ignore
// biome-ignore format: keep
function FromArray<T extends SArray>(T: T): TFromArray<T> {
return Type.Array(FromSchema(T.items), T) as never
}
// ------------------------------------------------------------------
// Const
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
type TFromConst<T extends SConst> = (
Type.Ensure<Type.TLiteral<T['const']>>
)
@@ -202,13 +204,13 @@ type TFromPropertiesIsOptional<
K extends PropertyKey,
R extends string | unknown,
> = unknown extends R ? true : K extends R ? false : true;
// prettier-ignore
// biome-ignore format: keep
type TFromProperties<T extends SProperties, R extends string | unknown> = Type.Evaluate<{
-readonly [K in keyof T]: TFromPropertiesIsOptional<K, R> extends true
? Type.TOptional<TFromSchema<T[K]>>
: TFromSchema<T[K]>
}>
// prettier-ignore
// biome-ignore format: keep
type TFromObject<T extends SObject> = (
TFromProperties<T['properties'], Exclude<T['required'], undefined>[number]> extends infer Properties extends Type.TProperties
? Type.TObject<Properties>
@@ -217,11 +219,11 @@ type TFromObject<T extends SObject> = (
function FromObject<T extends SObject>(T: T): TFromObject<T> {
const properties = globalThis.Object.getOwnPropertyNames(T.properties).reduce((Acc, K) => {
return {
// biome-ignore lint/performance/noAccumulatingSpread: <explanation>
...Acc,
[K]:
T.required && T.required.includes(K)
? FromSchema(T.properties[K])
: Type.Optional(FromSchema(T.properties[K])),
[K]: T.required?.includes(K)
? FromSchema(T.properties[K])
: Type.Optional(FromSchema(T.properties[K])),
};
}, {} as Type.TProperties);
return Type.Object(properties, T) as never;
@@ -229,7 +231,7 @@ function FromObject<T extends SObject>(T: T): TFromObject<T> {
// ------------------------------------------------------------------
// FromSchema
// ------------------------------------------------------------------
// prettier-ignore
// biome-ignore format: keep
export type TFromSchema<T> = (
T extends SAllOf ? TFromAllOf<T> :
T extends SAnyOf ? TFromAnyOf<T> :
@@ -248,7 +250,7 @@ export type TFromSchema<T> = (
)
/** Parses a TypeBox type from raw JsonSchema */
export function FromSchema<T>(T: T): TFromSchema<T> {
// prettier-ignore
// biome-ignore format: keep
return (
IsSAllOf(T) ? FromAllOf(T) :
IsSAnyOf(T) ? FromAnyOf(T) :

View File

@@ -12,13 +12,13 @@ import {
type TSchema,
type TString,
Type,
TypeRegistry
TypeRegistry,
} from "@sinclair/typebox";
import {
DefaultErrorFunction,
Errors,
SetErrorFunction,
type ValueErrorIterator
type ValueErrorIterator,
} from "@sinclair/typebox/errors";
import { Check, Default, Value, type ValueError } from "@sinclair/typebox/value";
@@ -45,7 +45,7 @@ export class TypeInvalidError extends Error {
constructor(
public schema: TSchema,
public data: unknown,
message?: string
message?: string,
) {
//console.warn("errored schema", JSON.stringify(schema, null, 2));
super(message ?? `Invalid: ${JSON.stringify(data)}`);
@@ -66,7 +66,7 @@ export class TypeInvalidError extends Error {
message: this.message,
schema: this.schema,
data: this.data,
errors: this.errors
errors: this.errors,
};
}
}
@@ -95,7 +95,7 @@ export function mark(obj: any, validated = true) {
export function parse<Schema extends TSchema = TSchema>(
schema: Schema,
data: RecursivePartial<Static<Schema>>,
options?: ParseOptions
options?: ParseOptions,
): Static<Schema> {
if (!options?.forceParse && typeof data === "object" && validationSymbol in data) {
if (options?.useDefaults === false) {
@@ -124,7 +124,7 @@ export function parse<Schema extends TSchema = TSchema>(
export function parseDecode<Schema extends TSchema = TSchema>(
schema: Schema,
data: RecursivePartial<StaticDecode<Schema>>
data: RecursivePartial<StaticDecode<Schema>>,
): StaticDecode<Schema> {
//console.log("parseDecode", schema, data);
const parsed = Default(schema, data);
@@ -140,7 +140,7 @@ export function parseDecode<Schema extends TSchema = TSchema>(
export function strictParse<Schema extends TSchema = TSchema>(
schema: Schema,
data: Static<Schema>,
options?: ParseOptions
options?: ParseOptions,
): Static<Schema> {
return parse(schema, data as any, options);
}
@@ -157,7 +157,7 @@ export const StringEnum = <const T extends readonly string[]>(values: T, options
[Kind]: "StringEnum",
type: "string",
enum: values,
...options
...options,
});
// key value record compatible with RJSF and typebox inference
@@ -175,7 +175,7 @@ export const Const = <T extends TLiteralValue = TLiteralValue>(value: T, options
export const StringIdentifier = Type.String({
pattern: "^[a-zA-Z_][a-zA-Z0-9_]*$",
minLength: 2,
maxLength: 150
maxLength: 150,
});
SetErrorFunction((error) => {
@@ -202,5 +202,5 @@ export {
Value,
Default,
Errors,
Check
Check,
};