import Crowdin from '@crowdin/crowdin-api-client';
import { Request } from 'express';
import { ContextContent } from './modules/context-menu/types';
import { CustomMTLogic } from './modules/custom-mt/types';
import { CustomSpellcheckerModule } from './modules/custom-spell-check/types';
import { EditorPanels } from './modules/editor-right-panel/types';
import { CustomFileFormatLogic, FilePostExportLogic, FilePostImportLogic, FilePreExportLogic, FilePreImportLogic, TranslationsAlignmentLogic } from './modules/file-processing/types';
import { IntegrationLogic } from './modules/integration/types';
import { Storage } from './storage';
import { MySQLStorageConfig } from './storage/mysql';
import { PostgreStorageConfig } from './storage/postgre';
import { D1StorageConfig } from './storage/d1';
import type { Fetcher } from '@cloudflare/workers-types';
import { ApiModule } from './modules/api/types';
import { LogErrorFunction, LogFunction } from './util/logger';
import { AiProviderModule } from './modules/ai-provider/types';
import { AiPromptProviderModule } from './modules/ai-prompt-provider/types';
import { AiTool, AiToolWidget } from './modules/ai-tools/types';
import { ExternalQaCheckModule } from './modules/external-qa-check/types';
import { Webhook } from './modules/webhooks/types';
import { WorkflowStepTypeModule } from './modules/workflow-step-type/types';
import { AiRequestProcessorModule, AiStreamProcessorModule } from './modules/ai-request-processors/types';
import { AutomationActionModule } from './modules/automation-action/types';
import { AuthGuardModule } from './modules/auth-guard/types';
import { Cron } from './util/cron';
export { Cron };
export interface ClientConfig extends ImagePath {
    /**
     * Authentication Crowdin App type: "authorization_code", "crowdin_app", "crowdin_agent". Default: "crowdin_app"
     */
    authenticationType?: AuthenticationType;
    /**
     * Crowdin Agent information: name, username, avatarUrl
     */
    agent?: Agent;
    /**
     * client id that we received when registering the app
     */
    clientId?: string;
    /**
     * client secret that we received when registering the app
     */
    clientSecret?: string;
    /**
     * Secret to encrypt/decrypt credentials (by default @clientSecret will be used)
     */
    cryptoSecret?: string;
    /**
     * Options to validate Crowdin JWT token
     */
    jwtValidationOptions?: VerifyOptions;
    /**
     * https url where an app is reachable from the internet (e.g. the one that ngrok generates for us)
     */
    baseUrl?: string;
    /**
     * define custom Crowdin urls (e.g. to work against local Crowdin server)
     */
    crowdinUrls?: CrowdinUrls;
    /**
     * define custom User Agent in requests to Crowdin
     */
    crowdinApiUserAgent?: string;
    /**
     * Set of scopes requested by this app (default 'project')
     */
    scopes?: Scope[];
    /**
     * app name
     */
    name: string;
    /**
     * app identifier
     */
    identifier: string;
    /**
     * app description
     */
    description: string;
    /**
     * link to the app's description/detail page
     */
    detailPage?: string;
    /**
     * Set default app permissions
     */
    defaultPermissions?: DefaultPermissions;
    /**
     * port where to start express application
     */
    port?: number;
    /**
     * folder where module will create sqlite db file to persist credentials (e.g. {@example __dirname})
     */
    dbFolder?: string;
    /**
     * migrate from SQLite to PostgreSQL
     */
    migrateToPostgreFromSQLite?: boolean;
    /**
     * config to configure PostgreSQL as a storage
     */
    postgreConfig?: PostgreStorageConfig;
    /**
     * config to configure MySQL as a storage
     */
    mysqlConfig?: MySQLStorageConfig;
    /**
     * config to configure Cloudflare D1 as a storage
     */
    d1Config?: D1StorageConfig;
    /**
     * Custom cron for scheduling background jobs.
     * If not provided, the default node-cron will be used.
     * Useful for external cron systems like Cloudflare Workers Scheduled Events.
     */
    cron?: Cron;
    /**
     * Cloudflare Workers Assets configuration
     */
    assetsConfig?: AssetsConfig;
    /**
     * integration module logic
     */
    projectIntegration?: IntegrationLogic & ImagePath & Environments;
    /**
     * custom file format module logic
     */
    customFileFormat?: OneOrMany<CustomFileFormatLogic>;
    /**
     * custom MT module logic
     */
    customMT?: OneOrMany<CustomMTLogic & ImagePath & Environments>;
    /**
     * resources module
     */
    profileResourcesMenu?: OneOrMany<UiModule & ImagePath & Environments>;
    /**
     * profile-settings-menu module
     */
    profileSettingsMenu?: OneOrMany<UiModule & ImagePath & Environments>;
    /**
     * organization-menu module
     */
    organizationMenu?: OneOrMany<UiModule & ImagePath>;
    /**
     * organization-settings-menu module
     */
    organizationSettingsMenu?: OneOrMany<UiModule & ImagePath>;
    /**
     * editor-right-panel module
     */
    editorRightPanel?: OneOrMany<EditorPanels & Environments>;
    /**
     * project menu module
     */
    projectMenu?: OneOrMany<UiModule & Environments>;
    /**
     * project menu crowdsource module
     */
    projectMenuCrowdsource?: OneOrMany<UiModule>;
    /**
     * tools module
     */
    projectTools?: OneOrMany<UiModule & ImagePath & Environments>;
    /**
     * reports module
     */
    projectReports?: OneOrMany<UiModule & ImagePath>;
    /**
     * API module
     */
    api?: ApiModule;
    /**
     * context menu module
     */
    contextMenu?: OneOrMany<ContextModule>;
    /**
     * modal module
     */
    modal?: OneOrMany<ModalModule>;
    /**
     * chat module
     */
    chat?: ChatModule[];
    /**
     * Install hook
     */
    onInstall?: (options: {
        organization: string;
        userId: number;
        client: Crowdin;
    }) => Promise<void>;
    /**
     * Uninstall hook for cleanup logic
     */
    onUninstall?: (options: {
        organization: string;
        allCredentials: {
            settings?: any;
            credentials: any;
        }[];
    }) => Promise<void>;
    /**
     * Error interceptor (can be used to log error in centralized place)
     */
    onError?: (options: {
        error: any;
        context?: CrowdinContextInfo;
    }) => void;
    /**
     * Disable global error handling of unhandledRejection and uncaughtException events
     */
    disableGlobalErrorHandling?: boolean;
    /**
     * Configuration to log everything that are happening in the app
     */
    logger?: Logger;
    /**
     * Enable status page with optional db and filesystem checks
     */
    enableStatusPage?: {
        database?: boolean;
        filesystem?: boolean;
        rateLimit?: number;
    };
    /**
     * Configuration of app pricing
     */
    pricing?: Pricing;
    filePreImport?: OneOrMany<FilePreImportLogic>;
    filePostImport?: OneOrMany<FilePostImportLogic>;
    filePreExport?: OneOrMany<FilePreExportLogic>;
    filePostExport?: OneOrMany<FilePostExportLogic>;
    fileTranslationsAlignmentExport?: OneOrMany<TranslationsAlignmentLogic>;
    /**
     * Disable formatting logs
     */
    disableLogsFormatter?: boolean;
    /**
     * AWS configuration for uploading big files to temporary bucket. Used with customFileFormat and file processors modules.
     *
     * Not necessary to configure if environment variables AWS_REGION and AWS_TMP_BUCKET_NAME are properly set.
     */
    awsConfig?: AWSConfig;
    customSpellchecker?: OneOrMany<CustomSpellcheckerModule>;
    /**
     * ai provider module
     */
    aiProvider?: OneOrMany<AiProviderModule & ImagePath>;
    /**
     * ai prompt provider module
     */
    aiPromptProvider?: OneOrMany<AiPromptProviderModule & ImagePath>;
    /**
     * ai request pre-compile processor module
     */
    aiRequestPreCompile?: OneOrMany<AiRequestProcessorModule>;
    /**
     * ai request post-compile processor module
     */
    aiRequestPostCompile?: OneOrMany<AiRequestProcessorModule>;
    /**
     * ai request pre-parse processor module
     */
    aiRequestPreParse?: OneOrMany<AiStreamProcessorModule>;
    /**
     * ai request post-parse processor module
     */
    aiRequestPostParse?: OneOrMany<AiRequestProcessorModule>;
    /**
     * AI tool_calls modules
     */
    aiTools?: OneOrMany<AiTool>;
    /**
     * AI tool_calls modules with UI widgets
     */
    aiToolsWidget?: OneOrMany<AiToolWidget>;
    /**
     * qa check module
     */
    externalQaCheck?: OneOrMany<ExternalQaCheckModule & ImagePath>;
    /**
     * webhook modules
     */
    webhooks?: OneOrMany<Webhook>;
    /**
     * workflow step modules
     */
    workflowStepType?: OneOrMany<WorkflowStepTypeModule>;
    /**
     * property that tells backend that AiProvider and AiPromptProvider modules can cooperate only with each one
     */
    restrictAiToSameApp?: boolean;
    /**
     * Flag to indicate if the app works with string-based projects
     */
    stringBasedAvailable?: boolean;
    /**
     * Automation action module
     */
    automationAction?: OneOrMany<AutomationActionModule>;
    /**
     * Auth guard module for custom authentication/authorization checks
     */
    authGuard?: OneOrMany<AuthGuardModule>;
    /**
     * custom file storage
     */
    fileStore?: FileStore;
    /**
     * path to assets files directory (default: 'static')
     */
    assetsPath?: string;
}
export interface AssetsConfig {
    /**
     * Cloudflare Workers Assets Fetcher
     */
    fetcher: Fetcher;
}
export interface Environments {
    environments?: OneOrMany<Environment>;
}
type Environment = 'crowdin' | 'crowdin-enterprise';
export type Config = ClientConfig & {
    baseUrl?: string;
    clientId: string;
    clientSecret: string;
    port: number;
    dbFolder: string;
    imagePath: string;
};
export type UnauthorizedConfig = Omit<Config, 'clientId' | 'clientSecret'> & {
    clientId?: string;
    clientSecret?: string;
};
export declare enum AuthenticationType {
    CODE = "authorization_code",
    APP = "crowdin_app",
    APP_WITH_CODE = "crowdin_app_with_code",
    AGENT = "crowdin_agent",
    NONE = "none"
}
export interface Agent {
    name?: string;
    username: string;
    avatarUrl?: string;
}
export interface CrowdinUrls {
    /** @deprecated use apiDomain instead */
    apiUrl?: string;
    apiDomain?: string;
    accountUrl?: string;
    subscriptionUrl?: string;
}
export declare enum Scope {
    ALL_SCOPES = "all",
    NOTIFICATIONS = "notification",
    TRANSLATION_MEMORIES = "tm",
    MACHINE_TRANSLATION_ENGINES = "mt",
    GLOSSARIES = "glossary",
    USERS = "user",
    TEAMS = "team",
    GROUPS = "group",
    PROJECTS = "project",
    TASKS = "project.task",
    REPORTS = "project.report",
    TRANSLATION_STATUS = "project.status",
    SOURCE_FILES_AND_STRINGS = "project.source",
    WEBHOOKS = "project.webhook",
    ORGANIZATION_WEBHOOKS = "webhook",
    TRANSLATIONS = "project.translation",
    SCREENSHOTS = "project.screenshot",
    SECURITY_LOGS = "security-log",
    VENDORS = "vendor",
    FIELDS = "field",
    AI = "ai",
    AI_PROVIDERS = "ai.provider",
    AI_PROMPTS = "ai.prompt",
    AI_PROXIES = "ai.proxy",
    APPLICATIONS = "application"
}
export interface CrowdinClientRequest extends Request {
    crowdinApiClient: Crowdin;
    crowdinContext: CrowdinContextInfo;
    subscriptionInfo?: SubscriptionInfo;
    logInfo: LogFunction;
    logError: LogErrorFunction;
    isApiCall?: boolean;
}
export interface CrowdinCredentials {
    id: string;
    appSecret: string;
    domain?: string;
    userId: number;
    agentId?: number;
    organizationId: number;
    baseUrl: string;
    accessToken: string;
    refreshToken: string;
    expire: string;
    type: AccountType;
}
export declare enum AccountType {
    NORMAL = "normal",
    ENTERPRISE = "enterprise"
}
export interface CrowdinContextInfo {
    jwtPayload: JwtPayload;
    crowdinId: string;
    clientId: string;
    appIdentifier: string;
}
export declare enum SubscriptionInfoType {
    TRIAL = "trial",
    SUBSCRIPTION = "subscription"
}
export interface SubscriptionInfo {
    expired: boolean;
    subscribeLink?: string;
    daysLeft?: number;
    type?: SubscriptionInfoType;
}
export declare enum EditorMode {
    ASSETS = "assets",
    REVIEW = "review",
    TRANSLATE = "TRANSLATE",
    PROOFREAD = "proofread",
    COMFORTABLE = "comfortable",
    SIDE_BY_SIDE = "side-by-side",
    MULTILINGUAL = "multilingual"
}
interface ModuleContent {
    /**
     * relative URL to the content page of the module
     */
    url?: string;
}
export interface CrowdinAppUtilities extends CrowdinMetadataStore {
    establishCrowdinConnection: (options: {
        authRequest?: CrowdinClientRequest;
        jwtToken?: string;
        moduleKey: string[] | string | undefined;
    }) => Promise<{
        context: CrowdinContextInfo;
        client?: Crowdin;
    }>;
    encryptCrowdinConnection: (options: {
        crowdinId: string;
        extra: Record<string, any>;
    }) => string;
    decryptCrowdinConnection: (options: {
        hash: string;
        autoRenew?: boolean;
    }) => Promise<{
        client: Crowdin;
        extra: Record<string, any>;
    }>;
    jwtMiddleware: (options: {
        moduleKey: string[] | string;
        optional?: boolean;
        checkSubscriptionExpiration?: boolean;
    }) => (req: any, res: any, next: any) => void;
    storage: Storage;
    cron: Cron;
}
export interface CrowdinMetadataStore {
    saveMetadata: (options: {
        id: string;
        metadata: any;
        crowdinId: string;
    }) => Promise<void>;
    getMetadata: (id: string) => Promise<any | undefined>;
    deleteMetadata: (id: string) => Promise<void>;
    /**
     * Settings that users manage in the integration module
     */
    getUserSettings: (clientId: string) => Promise<any | undefined>;
}
export interface UiModule extends ModuleKey {
    /**
     * Form schema for react-jsonschema-doc to be used as front-end
     * https://rjsf-team.github.io/react-jsonschema-form/docs
     */
    formSchema?: object;
    /**
     * URL to custom endpoint that can be used instead of default one to save form data.
     * Endpoint should accept POST requests.
     */
    formPostDataUrl?: string;
    /**
     * URL to custom endpoint that can be used instead of default one to retrieve form data.
     * Endpoint should accept GET requests.
     */
    formGetDataUrl?: string;
    /**
     * URL to custom endpoint for patching form data.
     * Endpoint should accept PATCH requests.
     */
    formPatchDataUrl?: string;
    /**
     * Additional attributes for react-jsonschema-doc
     */
    formUiSchema?: any;
    /**
     * path to ui folder (e.g. {@example join(__dirname, 'public')})
     */
    uiPath?: string;
    /**
     * page name (default index.html)
     */
    fileName?: string;
    /**
     * Module name
     */
    name?: string;
}
export interface ModuleKey {
    /**
     * key to identify module
     */
    key?: string;
}
export type OneOrMany<T> = T | T[];
export interface ImagePath {
    /**
     * path to app logo (e.g. {@example join(__dirname, 'logo.png')})
     */
    imagePath?: string;
    /**
     * URL to app logo that can be used instead of hosting it in the app (e.g. 'https://example.com/logo.png')
     */
    imageUrl?: string;
}
export interface Logger {
    enabled: boolean;
    log?: (options: {
        message: string;
        context?: CrowdinContextInfo;
    }) => void;
}
export interface Pricing {
    planType: 'free' | 'recurring';
    trial?: number;
    trialCrowdin?: number;
    trialEnterprise?: number;
    cachingSeconds?: number;
    infoDisplayDaysThreshold?: number;
}
export declare enum UserPermissions {
    OWNER = "owner",
    MANAGERS = "managers",
    ALL_MEMBERS = "all",
    GUESTS = "guests",
    RESTRICTED = "restricted"
}
export declare enum ProjectPermissions {
    OWN = "own",
    RESTRICTED = "restricted"
}
export interface DefaultPermissions {
    user?: UserPermissions;
    project?: ProjectPermissions;
}
export interface AWSConfig {
    /**
     * AWS bucket name for temporary files
     */
    tmpBucketName?: string;
    /**
     * AWS region
     */
    region?: string;
}
export interface SignaturePatterns {
    fileName?: string;
    fileContent?: string;
}
export declare enum storageFiles {
    SQLITE = "app.sqlite",
    SQLITE_BACKUP = "backup_app.sqlite",
    DUMP = "dump_table_%s.sql"
}
export interface ModalModule extends ModuleContent, UiModule, Environments {
}
export interface ChatModule extends ModuleContent, UiModule, Environments {
}
export interface ContextModule extends ContextContent, UiModule, Environments {
}
export interface FileStore {
    getFile: (fileRef: string) => Promise<Buffer>;
    storeFile: (content: Buffer) => Promise<string>;
    deleteFile: (fileRef: string) => Promise<void>;
}
export interface JwtPayload {
    aud: string;
    sub: string;
    domain?: string;
    module?: string;
    context: JwtPayloadContext;
    iat: number;
    exp: number;
    code?: string;
}
export interface JwtPayloadContext {
    project_id: number;
    project_identifier?: string;
    organization_id: number;
    organization_domain?: string;
    user_id: number;
    user_login?: string;
}
export interface VerifyOptions {
    ignoreExpiration: boolean;
}
export interface InstallEvent {
    appId: string;
    appSecret: string;
    clientId: string;
    userId: number;
    agentId?: number;
    organizationId: number;
    domain?: string;
    baseUrl: string;
    code?: string;
}
export interface UninstallEvent {
    appId: string;
    appSecret: string;
    clientId: string;
    organizationId: number;
    domain?: string;
    baseUrl: string;
}
export declare class PaymentRequiredError extends Error {
    subscribeLink: string;
    initializedAt: string;
    constructor(subscribeLink: string, initializedAt: string);
}
