import {z} from 'zod' export type GetApiRestApiV1NotificationCategoriesOptions = {baseUrl?: string | undefined, ApiKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const notificationEventDTO = z.object({event: z.enum(["POSITION_OPENED", "POSITION_CLOSED", "POSITION_MODIFIED", "HISTORY_UPDATED", "TRADE_APPROVAL_REQUIRED", "TRADE_APPROVED", "UNMANAGED_POSITION_DETECTED", "COPY_SKIPPED", "ORDER_REJECTED", "INSUFFICIENT_MARGIN", "TRADE_FAILED_DISCONNECTED", "COPY_FAILED", "DUPLICATE_POSITION_DETECTED", "ACCOUNT_STARTED", "ACCOUNT_STOPPED", "ACCOUNT_CONNECTED", "ACCOUNT_DISCONNECTED", "ACCOUNT_LOGIN_FAILED", "ACCOUNT_TOKEN_EXPIRING", "ACCOUNT_RESTRICTED", "ACCOUNT_FALLBACK_MODE", "RISK_LIMIT_REACHED", "PROFIT_TARGET_REACHED", "LOSS_PROTECTED_EXIT", "GUARDRAIL_TRIGGERED", "COPIER_STOPPED_BY_RISK", "LIMIT_RESET", "BALANCE_ADJUSTMENT_DETECTED", "NEWS_EVENT_UPCOMING", "NEWS_EVENT_RELEASED", "NEWS_FILTER_ACTION_SCHEDULED", "NEWS_FILTER_ACTION_IMMINENT", "NEWS_FILTER_DAILY_AGENDA", "NEWS_FILTER_SKIPPED_COPY", "NEWS_FILTER_CLOSED_POSITION", "NEWS_FILTER_REOPENED", "NEWS_FILTER_REOPEN_SKIPPED", "NEWS_FILTER_HOLIDAY_MODE", "MARKET_NEWS_HIGH_IMPACT", "SIGNAL_RECEIVED", "SIGNAL_EXECUTED", "SIGNAL_REJECTED", "SIGNAL_AI_LIMIT_REACHED", "SIGNAL_SUBSCRIPTION_ENDED", "CONFIGURATION_ERROR", "CONFIGURATION_CHANGED", "MAINTENANCE_WINDOW", "PROXY_ISSUE", "EXPERT_ADVISOR_STARTED", "EXPERT_ADVISOR_STOPPED", "EXPERT_ADVISOR_WARNING", "LOG_RATE_LIMITED", "NOTIFICATION_CHANNEL_DISABLED", "GENERAL"]).optional(), i18nKey: z.string().optional(), ignoresLogLevel: z.boolean().optional()}); export const notificationCategoryDTO = z.object({category: z.enum(["TRADING", "COPY_SKIPPED", "EXECUTION_ERROR", "ACCOUNT_CONNECTION", "RISK", "NEWS", "SIGNALS", "SYSTEM", "OTHER"]).optional(), code: z.number().int().optional(), events: z.array(notificationEventDTO).optional(), i18nKey: z.string().optional(), toolFeatureTypeIds: z.array(z.number().int()).optional()}); export const getApiRestApiV1NotificationCategoriesResponse = z.array(notificationCategoryDTO); 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 }; /** * Notification categories and events * * GET /rest/api/v1/notificationCategories */ export const getApiRestApiV1NotificationCategories = async (options?: GetApiRestApiV1NotificationCategoriesOptions) => { const {baseUrl = "https://api.metacopier.io", fetch: fetchFn = fetch, ApiKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (ApiKeyAuth !== undefined) headers.set("X-API-KEY", ApiKeyAuth) const url = `${baseUrl.replace(/\/+$/, '')}/rest/api/v1/notificationCategories${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(getApiRestApiV1NotificationCategoriesResponse, await res.json()) };