Skip to content

Commit d78bd9f

Browse files
committed
fest: first blood, should just work
1 parent 2cbf4f0 commit d78bd9f

File tree

13 files changed

+376
-0
lines changed

13 files changed

+376
-0
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root=true
2+
3+
[*]
4+
indent_style=space
5+
indent_size=2
6+
tab_width=2
7+
end_of_line=lf
8+
charset=utf-8
9+
trim_trailing_whitespace=true
10+
insert_final_newline=true

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
- push
5+
- pull_request
6+
7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.ref }}
9+
cancel-in-progress: true
10+
11+
jobs:
12+
ci:
13+
name: ${{ matrix.os }}
14+
strategy:
15+
matrix:
16+
os:
17+
- macOS-latest
18+
- ubuntu-latest
19+
- windows-latest
20+
runs-on: ${{ matrix.os }}
21+
steps:
22+
- name: Checkout Repo
23+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
24+
25+
- name: Setup Deno
26+
uses: denoland/setup-deno@v2
27+
with:
28+
deno-version: v2.x
29+
30+
- name: Lint
31+
run: |
32+
deno fmt --check
33+
deno lint

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!.vscode/settings.json

.renovaterc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": [
3+
"github>1stG/configs"
4+
]
5+
}

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.defaultFormatter": "denoland.vscode-deno"
3+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# deeplx
2+
23
Running [deeplx](https://github.com/un-ts/deeplx) on Deno Deploy

deno.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"noUnusedLocals": true,
4+
"noUnusedParameters": true
5+
},
6+
"tasks": {
7+
"build": "deno run --allow-env --allow-read --allow-write --allow-net scripts/build.ts",
8+
"dev": "deno run --allow-ffi --allow-read --allow-net --watch main.ts",
9+
"start": "deno run --allow-ffi --allow-read --allow-net main.ts"
10+
},
11+
"fmt": {
12+
"semiColons": false,
13+
"singleQuote": true,
14+
"exclude": ["public/index.html"]
15+
}
16+
}

deno.lock

Lines changed: 90 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { translate } from './mod.ts'
2+
3+
Deno.serve(translate)

mod.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import {
2+
abbreviateLanguage,
3+
HTTP_STATUS_BAD_REQUEST,
4+
HTTP_STATUS_INTERNAL_ERROR,
5+
HTTP_STATUS_NOT_ALLOWED,
6+
HTTP_STATUS_NOT_FOUND,
7+
HTTP_STATUS_OK,
8+
type SourceLanguage,
9+
type TargetLanguage,
10+
translate as translate_,
11+
} from 'npm:@deeplx/core'
12+
13+
export interface RequestBody {
14+
text: string
15+
source_lang?: SourceLanguage
16+
target_lang: TargetLanguage
17+
}
18+
19+
async function extractBodyText(body: ReadableStream) {
20+
const reader = body.getReader()
21+
const decoder = new TextDecoder()
22+
23+
let text = ''
24+
25+
while (true) {
26+
const { done, value } = await reader.read()
27+
if (done) {
28+
return text
29+
}
30+
text += decoder.decode(value)
31+
}
32+
}
33+
34+
export const translate = async (
35+
req: Request,
36+
): Promise<Response> => {
37+
let url = new URL(req.url).pathname
38+
39+
if (!url || url === '/') {
40+
url = '/index.html'
41+
}
42+
43+
if (/\.[a-z]+[a-z\d]*$/.test(url)) {
44+
if (req.method !== 'GET') {
45+
return Response.json({
46+
code: HTTP_STATUS_NOT_ALLOWED,
47+
message: 'Not Allowed',
48+
}, { status: HTTP_STATUS_NOT_ALLOWED })
49+
}
50+
return new Response(await Deno.readFile(`./public${url}`))
51+
}
52+
53+
if (url !== '/translate') {
54+
return Response.json({
55+
code: HTTP_STATUS_NOT_FOUND,
56+
message: 'Not Found',
57+
}, {
58+
status: HTTP_STATUS_NOT_FOUND,
59+
})
60+
}
61+
62+
const body = req.body
63+
64+
if (!body || req.method !== 'POST') {
65+
return new Response(`DeepL Translate Api
66+
67+
POST {"text": "have a try", "source_lang": "auto", "target_lang": "ZH"} to /translate
68+
69+
https://github.com/devno-js/deeplx
70+
71+
powered by https://github.com/un-ts/deeplx`)
72+
}
73+
74+
const bodyText = await extractBodyText(body)
75+
76+
const { text, source_lang: sourceLang, target_lang: targetLang } = JSON.parse(
77+
bodyText,
78+
) as RequestBody
79+
80+
if (!text) {
81+
return Response.json({
82+
code: HTTP_STATUS_BAD_REQUEST,
83+
data: 'Text is required',
84+
}, {
85+
status: HTTP_STATUS_BAD_REQUEST,
86+
})
87+
}
88+
89+
if (!abbreviateLanguage(targetLang)) {
90+
return Response.json({
91+
code: HTTP_STATUS_BAD_REQUEST,
92+
data: 'Invalid target language',
93+
}, {
94+
status: HTTP_STATUS_BAD_REQUEST,
95+
})
96+
}
97+
98+
try {
99+
const translation = await translate_(text, targetLang, sourceLang)
100+
return Response.json({
101+
code: HTTP_STATUS_OK,
102+
data: translation,
103+
})
104+
} catch (err) {
105+
return Response.json({
106+
code: HTTP_STATUS_INTERNAL_ERROR,
107+
data: err instanceof Error ? err.message : String(err),
108+
}, {
109+
status: HTTP_STATUS_INTERNAL_ERROR,
110+
})
111+
}
112+
}

0 commit comments

Comments
 (0)