Trace results can now be inset (negative) or outset (positive) by a pixel amount. Offset the outline and holes in opposite directions with clipper-lib's miter joins, then recombine with a boolean difference so holes grow on inset and shrink on outset. Collapsed shapes return an empty outline; a split outline keeps the largest ring. Document the parameter and the new dependency.
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
/** Validate a Workshop item ID (a non-empty run of digits). */
|
|
export const itemIdSchema = z
|
|
.string()
|
|
.regex(/^\d+$/, 'Item ID must be a number')
|
|
.min(1);
|
|
|
|
/** Query params for `GET /search`. */
|
|
export const searchQuerySchema = z.object({
|
|
q: z.string().trim().min(1, 'Search query is required'),
|
|
page: z.coerce.number().int().min(1).default(1),
|
|
});
|
|
|
|
export const assetKindSchema = z.enum([
|
|
'pdf',
|
|
'deckFace',
|
|
'deckBack',
|
|
'image',
|
|
'imageSecondary',
|
|
]);
|
|
|
|
export const assetRefSchema = z.object({
|
|
kind: assetKindSchema,
|
|
url: z.string().url(),
|
|
ownerGuid: z.string(),
|
|
});
|
|
|
|
export const extractedObjectSchema = z.object({
|
|
guid: z.string(),
|
|
name: z.string(),
|
|
type: z.string(),
|
|
parentGuid: z.string().optional(),
|
|
childrenGuids: z.array(z.string()),
|
|
refs: z.array(assetRefSchema),
|
|
});
|
|
|
|
export const workshopItemSchema = z.object({
|
|
id: z.string(),
|
|
title: z.string(),
|
|
author: z.string(),
|
|
previewImageUrl: z.string(),
|
|
fileUrl: z.string().optional(),
|
|
description: z.string().optional(),
|
|
tags: z.array(z.string()).optional(),
|
|
timeCreated: z.number().optional(),
|
|
timeUpdated: z.number().optional(),
|
|
});
|
|
|
|
export const searchResultSchema = z.object({
|
|
items: z.array(workshopItemSchema),
|
|
page: z.number(),
|
|
hasMore: z.boolean(),
|
|
});
|
|
|
|
export const traceModeSchema = z.enum(['alpha', 'bw', 'color']);
|
|
|
|
export const traceFormatSchema = z.enum(['svg', 'shape']);
|
|
|
|
/** Query params for `GET /trace`. */
|
|
export const traceRequestSchema = z.object({
|
|
url: z.string().url('url must be a valid URL'),
|
|
mode: traceModeSchema.default('alpha'),
|
|
threshold: z.coerce.number().int().min(0).max(255).default(128),
|
|
format: traceFormatSchema.default('shape'),
|
|
simplify: z.coerce.number().min(0).optional(),
|
|
maxColors: z.coerce.number().int().min(1).optional(),
|
|
/** Inset (negative) or outset (positive) the traced shape, in pixels. */
|
|
offset: z.coerce.number().optional(),
|
|
}); |