{"version":3,"sources":["../src/index.ts","../src/locales/index.ts","../src/locales/en.ts","../src/locales/zh.ts","../src/utils.ts"],"sourcesContent":["import Translator from \"@koishijs/translator\";\nimport { FastText } from \"fasttext.wasm\";\nimport { Context, Logger, Schema, SessionError } from \"koishi\";\nimport type { Response } from \"./types\";\nimport { defineLocales, generateRequestBody } from \"./utils\";\n\nconst logger = new Logger(\"translator-deepl\");\n\nclass DeeplTranslator extends Translator<DeeplTranslator.Config> {\n  private id = Math.random() * 2 ** 32;\n  private fastText?: FastText;\n\n  public constructor(ctx: Context, config: DeeplTranslator.Config) {\n    super(ctx, config);\n    defineLocales(ctx);\n  }\n\n  public async translate(options: Translator.Result): Promise<string> {\n    if (!this.fastText) {\n      this.fastText = await FastText.create();\n      await this.fastText.loadModel();\n    }\n    const {\n      input,\n      source,\n      target = this.fastText.detect(input).toUpperCase() ===\n      this.config.defaultTargetLang[0]!\n        ? this.config.defaultTargetLang[1]!\n        : this.config.defaultTargetLang[0]!,\n    } = options;\n    const { data, status } = await this.ctx.http.axios<Response>(\"/jsonrpc\", {\n      method: \"post\",\n      baseURL: \"https://www2.deepl.com\",\n      data: generateRequestBody(\n        this.id++,\n        input,\n        target.toUpperCase(),\n        source?.toUpperCase(),\n      ),\n      headers: {\n        Accept: \"*/*\",\n        \"Accept-Language\": \"en-US,en;q=0.9\",\n        Connection: \"keep-alive\",\n        \"Content-Type\": \"application/json\",\n        \"User-Agent\": \"DeepL-iOS/2.9.0 iOS 16.5.0 (iPad13,1)\",\n        \"x-app-os-name\": \"iPadOS\",\n        \"x-app-os-version\": \"16.5.0\",\n        \"x-app-device\": \"iPad13,1\",\n        \"x-app-build\": \"490306\",\n        \"x-app-version\": \"2.9\",\n      },\n      validateStatus: (status) =>\n        (status >= 200 && status < 300) || status === 400 || status === 429,\n    });\n    switch (status) {\n      case 400: {\n        switch (data.error?.code) {\n          case -32600: {\n            logger.error(`Unsupport target language: ${target.toUpperCase()}`);\n\n            throw new SessionError(\".deepl.unsupportTarget\", { lang: target });\n          }\n          default:\n            logger.error(\n              `An unknown error has occurred${\n                data.error\n                  ? `: ${data.error?.message}(${data.error?.code})`\n                  : \"\"\n              }`,\n            );\n            throw new SessionError(\".deepl.unknownError\");\n        }\n      }\n      case 429:\n        logger.error(\"Too many requests\");\n        throw new SessionError(\".deepl.tooManyRequests\");\n      default:\n        return data.result.texts[0].text;\n    }\n  }\n}\n\nnamespace DeeplTranslator {\n  export interface Config {\n    defaultTargetLang: string[];\n  }\n\n  export const Config: Schema<Config> = Schema.object({\n    defaultTargetLang: Schema.tuple([String, String])\n      .description(\"默认的目标语言, 当输入语言为第一个时使用第二个\")\n      .default([\"ZH\", \"EN\"]),\n  });\n}\n\nexport default DeeplTranslator;\n","export * from \"./en\";\nexport * from \"./zh\";\n","import type { DeeplTranslatorLocale } from \"../types\";\n\nexport const en: DeeplTranslatorLocale = {\n  commands: {\n    translate: {\n      messages: {\n        deepl: {\n          tooManyRequests: \"Too many requests\",\n          unknownError: \"An unknown error has occurred\",\n          unsupportTarget: \"Unsupport target language: {target}\",\n        },\n      },\n    },\n  },\n};\n","import type { DeeplTranslatorLocale } from \"../types\";\n\nexport const zh: DeeplTranslatorLocale = {\n  commands: {\n    translate: {\n      messages: {\n        deepl: {\n          tooManyRequests: \"太多的请求\",\n          unknownError: \"发生未知错误\",\n          unsupportTarget: \"不支持的目标语言: {target}\",\n        },\n      },\n    },\n  },\n};\n","import type { Context, I18n } from \"koishi\";\nimport * as locales from \"./locales\";\nimport type { Request } from \"./types\";\n\nconst getTimestamp = (str: string) => {\n  const timestamp = new Date().getUTCMilliseconds();\n  const iCount = [...str].filter((c) => c === \"i\").length;\n\n  if (iCount !== 0) return timestamp - (timestamp % (iCount + 1)) + iCount + 1;\n  else return timestamp;\n};\n\nconst stringifyRequest = (req: Request) => {\n  const json = JSON.stringify(req, undefined, 4);\n  return (req.id + 5) % 29 === 0 || (req.id + 3) % 13 === 0\n    ? json.replace(/\"method\":\"/g, '\"method\" : \"')\n    : json;\n};\n\nexport const defineLocales = (ctx: Context) =>\n  Object.entries(locales).forEach(([lang, locale]) =>\n    ctx.i18n.define(lang, locale as unknown as I18n.Store),\n  );\n\nexport const generateRequestBody = (\n  id: number,\n  text: string,\n  targetLang: string,\n  sourceLang?: string,\n): string =>\n  stringifyRequest({\n    jsonrpc: \"2.0\",\n    method: \"LMT_handle_texts\",\n    id,\n    params: {\n      texts: [\n        {\n          text,\n          requestAlternatives: 0,\n        },\n      ],\n      splitting: \"newlines\",\n      lang: {\n        target_lang: targetLang,\n        ...(sourceLang ? { source_lang_user_selected: sourceLang } : {}),\n      },\n      timestamp: getTimestamp(text),\n      commonJobParams: {\n        transcribe_as: \"\",\n        wasSpoken: false,\n      },\n    },\n  });\n"],"mappings":"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","names":["status","DeeplTranslator"]}