import {z} from 'zod' export type SyncConsumersStatus = 'all' | 'enabled' | 'not_enabled'; export type GetApiSyncsArgs = {consumers_status?: SyncConsumersStatus | undefined}; export type GetApiSyncsOptions = {baseUrl?: string | undefined, bearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const syncsConnectionItem = z.object({one_api: z.number().int().nullable().optional(), connection_type: z.number().int().nullable().optional(), display_order: z.number().int().optional(), display_hidden: z.boolean().optional()}); export const fieldItemType = z.enum(["fixed", "api"]); export const fieldItemValue = z.object({id: z.string(), label: z.string()}); export const fieldItem = z.object({name: z.string(), type: fieldItemType, display_condition: z.record(z.string(), z.unknown()).nullable().optional(), values: z.array(fieldItemValue).nullable().optional(), api_route: z.string().nullable().optional(), connection_type: z.number().int().nullable().optional()}); export const createSyncMappingToFieldItemOutput = z.object({name: z.string(), description: z.string().nullable().optional(), display_order: z.number().int().optional(), challenge_question: z.string().nullable().optional(), conditions: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), source_field: fieldItem, target_field: fieldItem, display_delete: z.boolean().optional(), logic: z.record(z.string(), z.unknown()).nullable().optional(), manual_mapping: z.boolean().optional()}); export const createSyncMappingItemOutput = z.object({name: z.string(), description: z.string().nullable().optional(), display_order: z.number().int().optional(), challenge_question: z.string().nullable().optional(), conditions: z.record(z.string(), z.record(z.string(), z.unknown())).nullable().optional(), sub_mappings: z.array(createSyncMappingToFieldItemOutput).optional()}); export const executionType = z.enum(["code", "module"]); export const flowExecutionChain = z.object({name: z.string()}); export const flowExecutionCode = z.object({code: z.string()}); export const flowExecution = z.object({type: executionType, data: z.union([flowExecutionChain, flowExecutionCode]).nullable()}); export const datastoreStatus = z.enum(["active", "inactive"]); export const datastoreColumn = z.object({name: z.string(), title: z.string(), type: z.string(), optional: z.boolean().nullable().optional()}); export const datastoreDef = z.object({columns: z.array(datastoreColumn), search_column: z.string().nullable().optional()}); export const flowDataStoreItemOutput = z.object({id: z.string().nullable().optional(), name: z.string(), status: datastoreStatus.nullable().optional(), definition: datastoreDef}); export const flowConfigOutput = z.object({definitionFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(), doorkeyFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(), customFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(), datastores: z.array(flowDataStoreItemOutput).nullable().optional()}); export const triggerType = z.enum(["timer", "event"]); export const triggerPriority = z.enum(["NORMAL", "MEDIUM", "HIGH"]); export const flowTrigger = z.object({id: z.string(), type: triggerType, cronschedules: z.array(z.string()).nullable().optional(), visible: z.boolean().nullable().optional(), definitionFields: z.array(z.record(z.string(), z.unknown())).nullable().optional(), options: z.record(z.string(), z.unknown()).nullable().optional(), priority: triggerPriority.optional()}); export const readFlowItem = z.object({name: z.string(), description: z.string().nullable().optional(), id: z.string(), execution: flowExecution.nullable().optional(), config: flowConfigOutput.nullable().optional(), triggers: z.array(flowTrigger).nullable().optional()}); export const objectKindItem = z.object({kind: z.string(), capability: z.string()}); export const readSyncItem = z.object({name: z.string().min(1), config: z.record(z.string(), z.unknown()).nullable().optional(), connections: z.array(syncsConnectionItem), mappings: z.array(createSyncMappingItemOutput).optional(), syncid: z.string(), consumers: z.array(z.string()), flows: z.array(readFlowItem), module: z.string().nullable().optional(), object_kinds: z.array(objectKindItem).nullable().optional()}); export const getApiSyncsResponse = z.array(readSyncItem); 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 }; /** * Get syncs * * GET /syncs */ export const getApiSyncs = async (args: GetApiSyncsArgs, options?: GetApiSyncsOptions) => { const {baseUrl = "https://api.chift.eu", fetch: fetchFn = fetch, bearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.consumers_status != null) query.append("consumers_status", String(args.consumers_status)) if (bearerAuth !== undefined) headers.set('authorization', `Bearer ${bearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/syncs${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(getApiSyncsResponse, await res.json()) };