import {z} from 'zod' export type GetApiApiV1ConditionTemplatesOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const dimensions = z.object({width_in: z.number().gte(0).nullable().optional(), thickness_in: z.number().gte(0).nullable().optional(), height_in: z.number().gte(0).nullable().optional(), slope: z.string().nullable().optional()}); export const tileModule = z.object({w_in: z.number().int().gte(0), h_in: z.number().int().gte(0), gap_in: z.number().int().gte(0)}); export const gridSpacing = z.object({x_in: z.number().int().gte(0), y_in: z.number().int().gte(0)}); export const rounding = z.object({enabled: z.boolean().optional(), increment: z.number().gt(0).optional()}); export const displayConfig = z.object({name: z.boolean().optional(), dimension: z.boolean().optional(), pattern_while_drawing: z.boolean().optional()}); export const conditionConfig = z.object({dimensions: dimensions.nullable().optional(), tile_module: tileModule.nullable().optional(), grid_spacing: gridSpacing.nullable().optional(), rounding: rounding.optional(), display: displayConfig.optional()}); export const attachmentConfig = z.object({deduct_from_parent: z.boolean().optional()}); export const derivation = z.object({id: z.string(), ordinal: z.number().int().gte(1), result_type: z.enum(["count", "total_height", "perimeter", "surface_area_top_or_bottom", "surface_area_top_and_bottom", "surface_area_all_sides", "surface_area_full", "volume", "length", "segment_count", "surface_area_single_side", "surface_area_both_sides", "surface_area_single_end", "surface_area_both_ends", "surface_area_all_side_duct", "area", "grid_length_visible", "grid_length_x_visible", "grid_length_y_visible", "grid_intersection_count", "tile_count_average", "tile_count_visible", "area_counts"]), uom: z.enum(["EA", "LF", "IN", "FT", "SF", "SY", "CF", "CY"]), respects_backouts: z.boolean().optional(), respects_attachments: z.boolean().optional()}); export const conditionTemplate = z.object({id: z.string(), org_id: z.string(), name: z.string().min(1).max(200), geometry_kind: z.enum(["count", "linear", "area"]), shape: z.enum(["circle", "square", "rectangle"]).nullable(), color: z.string(), config: conditionConfig, notes: z.string().nullable(), attachment_kind: z.enum(["area", "linear"]).nullable(), attachment_config: attachmentConfig.nullable(), extension_id: z.string().nullable(), phase_code_id: z.string().nullable(), folder_id: z.string().nullable(), sort_order: z.number(), external_id: z.string().nullable(), created_at: z.string(), updated_at: z.string(), row_version: z.number().int(), derivations: z.array(derivation).optional()}); export const conditionTemplateListResponse = z.object({items: z.array(conditionTemplate)}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * List Condition Templates * * GET /api/v1/condition-templates */ export const getApiApiV1ConditionTemplates = async (options: GetApiApiV1ConditionTemplatesOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/api/v1/condition-templates${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(conditionTemplateListResponse, await res.json()) };