gengo-ts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +316 -0
- package/dist/common-Bk4hl8fX.d.ts +53 -0
- package/dist/index.d.ts +703 -0
- package/dist/index.js +469 -0
- package/dist/index.js.map +1 -0
- package/dist/webhook/express.d.ts +50 -0
- package/dist/webhook/express.js +24 -0
- package/dist/webhook/express.js.map +1 -0
- package/dist/webhook/hono.d.ts +40 -0
- package/dist/webhook/hono.js +24 -0
- package/dist/webhook/hono.js.map +1 -0
- package/dist/webhook/index.d.ts +95 -0
- package/dist/webhook/index.js +100 -0
- package/dist/webhook/index.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/webhook/hono.ts
|
|
2
|
+
function honoAdapter(handler) {
|
|
3
|
+
return async (c) => {
|
|
4
|
+
if (c.req.method !== "POST") {
|
|
5
|
+
return c.text("Method not allowed", 405);
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
const body = await c.req.parseBody();
|
|
9
|
+
const result = await handler.handleFormData(body);
|
|
10
|
+
if (result.success) {
|
|
11
|
+
return c.text("OK", 200);
|
|
12
|
+
} else {
|
|
13
|
+
return c.text(result.error?.message ?? "Processing failed", 500);
|
|
14
|
+
}
|
|
15
|
+
} catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
17
|
+
return c.text(message, 500);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { honoAdapter };
|
|
23
|
+
//# sourceMappingURL=hono.js.map
|
|
24
|
+
//# sourceMappingURL=hono.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/webhook/hono.ts"],"names":[],"mappings":";AAsCO,SAAS,YAAY,OAAA,EAAsC;AAChE,EAAA,OAAO,OAAO,CAAA,KAAM;AAClB,IAAA,IAAI,CAAA,CAAE,GAAA,CAAI,MAAA,KAAW,MAAA,EAAQ;AAC3B,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,oBAAA,EAAsB,GAAG,CAAA;AAAA,IACzC;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,CAAA,CAAE,GAAA,CAAI,SAAA,EAAU;AACnC,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,cAAA,CAAe,IAA8B,CAAA;AAE1E,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,OAAO,CAAA,CAAE,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA;AAAA,MACzB,CAAA,MAAO;AACL,QAAA,OAAO,EAAE,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,OAAA,IAAW,qBAAqB,GAAG,CAAA;AAAA,MACjE;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAA,GAAU,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AACzD,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,OAAA,EAAS,GAAG,CAAA;AAAA,IAC5B;AAAA,EACF,CAAA;AACF","file":"hono.js","sourcesContent":["import type { WebhookHandler } from './index.js';\n\n/**\n * Hono-compatible context interface\n */\ninterface HonoContext {\n req: {\n method: string;\n parseBody(): Promise<Record<string, string>>;\n };\n text(body: string, status?: number): Response;\n}\n\n/**\n * Hono handler type\n */\ntype HonoHandler = (c: HonoContext) => Promise<Response>;\n\n/**\n * Creates a Hono handler adapter for the webhook handler\n *\n * @example\n * ```typescript\n * import { Hono } from 'hono';\n * import { createWebhookHandler } from 'gengo-ts/webhook';\n * import { honoAdapter } from 'gengo-ts/webhook/hono';\n *\n * const app = new Hono();\n *\n * const handler = createWebhookHandler({\n * onJobUpdate: (job) => {\n * console.log('Job updated:', job.job_id, job.status);\n * },\n * });\n *\n * app.post('/webhook', honoAdapter(handler));\n * ```\n */\nexport function honoAdapter(handler: WebhookHandler): HonoHandler {\n return async (c) => {\n if (c.req.method !== 'POST') {\n return c.text('Method not allowed', 405);\n }\n\n try {\n const body = await c.req.parseBody();\n const result = await handler.handleFormData(body as Record<string, string>);\n\n if (result.success) {\n return c.text('OK', 200);\n } else {\n return c.text(result.error?.message ?? 'Processing failed', 500);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return c.text(message, 500);\n }\n };\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { T as Tier, a as JobStatus, C as Currency } from '../common-Bk4hl8fX.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Job callback payload sent by Gengo
|
|
5
|
+
*/
|
|
6
|
+
interface JobCallback {
|
|
7
|
+
job_id: number;
|
|
8
|
+
order_id: number;
|
|
9
|
+
body_src: string;
|
|
10
|
+
body_tgt: string;
|
|
11
|
+
lc_src: string;
|
|
12
|
+
lc_tgt: string;
|
|
13
|
+
unit_count: number;
|
|
14
|
+
tier: Tier;
|
|
15
|
+
credits: number;
|
|
16
|
+
status: JobStatus;
|
|
17
|
+
eta: number;
|
|
18
|
+
ctime: number;
|
|
19
|
+
callback_url: string;
|
|
20
|
+
auto_approve: boolean;
|
|
21
|
+
custom_data: string;
|
|
22
|
+
slug: string;
|
|
23
|
+
currency: Currency;
|
|
24
|
+
file_url_src?: string;
|
|
25
|
+
file_url_tgt?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Comment callback payload sent by Gengo
|
|
29
|
+
*/
|
|
30
|
+
interface CommentCallback {
|
|
31
|
+
job_id: string;
|
|
32
|
+
body: string;
|
|
33
|
+
ctime: string;
|
|
34
|
+
custom_data?: string;
|
|
35
|
+
file_url_tgt?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Webhook handler callbacks
|
|
39
|
+
*/
|
|
40
|
+
interface WebhookHandlerCallbacks {
|
|
41
|
+
/** Called when a job status update is received */
|
|
42
|
+
onJobUpdate?: (job: JobCallback) => void | Promise<void>;
|
|
43
|
+
/** Called when a translator comment is received */
|
|
44
|
+
onComment?: (comment: CommentCallback) => void | Promise<void>;
|
|
45
|
+
/** Called when an error occurs during processing */
|
|
46
|
+
onError?: (error: Error) => void | Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parsed webhook payload
|
|
50
|
+
*/
|
|
51
|
+
type WebhookPayload = {
|
|
52
|
+
type: 'job';
|
|
53
|
+
data: JobCallback;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'comment';
|
|
56
|
+
data: CommentCallback;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Result of webhook processing
|
|
60
|
+
*/
|
|
61
|
+
interface WebhookResult {
|
|
62
|
+
success: boolean;
|
|
63
|
+
type?: 'job' | 'comment';
|
|
64
|
+
error?: Error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Webhook handler for processing Gengo callbacks
|
|
69
|
+
*/
|
|
70
|
+
declare class WebhookHandler {
|
|
71
|
+
private readonly callbacks;
|
|
72
|
+
constructor(callbacks: WebhookHandlerCallbacks);
|
|
73
|
+
/**
|
|
74
|
+
* Parses form data and returns the webhook payload
|
|
75
|
+
*/
|
|
76
|
+
parsePayload(formData: URLSearchParams | FormData | Record<string, string>): WebhookPayload | null;
|
|
77
|
+
/**
|
|
78
|
+
* Processes a webhook payload and calls the appropriate callback
|
|
79
|
+
*/
|
|
80
|
+
process(payload: WebhookPayload): Promise<WebhookResult>;
|
|
81
|
+
/**
|
|
82
|
+
* Parses and processes a webhook request body
|
|
83
|
+
*/
|
|
84
|
+
handleFormData(formData: URLSearchParams | FormData | Record<string, string>): Promise<WebhookResult>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a webhook handler with the specified callbacks
|
|
88
|
+
*/
|
|
89
|
+
declare function createWebhookHandler(callbacks: WebhookHandlerCallbacks): WebhookHandler;
|
|
90
|
+
/**
|
|
91
|
+
* Handles a raw Web Request (for Deno, Bun, Cloudflare Workers)
|
|
92
|
+
*/
|
|
93
|
+
declare function handleRequest(request: Request, handler: WebhookHandler): Promise<Response>;
|
|
94
|
+
|
|
95
|
+
export { type CommentCallback, type JobCallback, WebhookHandler, type WebhookHandlerCallbacks, type WebhookPayload, type WebhookResult, createWebhookHandler, handleRequest };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/webhook/index.ts
|
|
2
|
+
var WebhookHandler = class {
|
|
3
|
+
constructor(callbacks) {
|
|
4
|
+
this.callbacks = callbacks;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Parses form data and returns the webhook payload
|
|
8
|
+
*/
|
|
9
|
+
parsePayload(formData) {
|
|
10
|
+
let jobData = null;
|
|
11
|
+
let commentData = null;
|
|
12
|
+
if (formData instanceof URLSearchParams) {
|
|
13
|
+
jobData = formData.get("job");
|
|
14
|
+
commentData = formData.get("comment");
|
|
15
|
+
} else if (formData instanceof FormData) {
|
|
16
|
+
const jobValue = formData.get("job");
|
|
17
|
+
const commentValue = formData.get("comment");
|
|
18
|
+
jobData = typeof jobValue === "string" ? jobValue : null;
|
|
19
|
+
commentData = typeof commentValue === "string" ? commentValue : null;
|
|
20
|
+
} else {
|
|
21
|
+
jobData = formData["job"] ?? null;
|
|
22
|
+
commentData = formData["comment"] ?? null;
|
|
23
|
+
}
|
|
24
|
+
if (jobData) {
|
|
25
|
+
return { type: "job", data: JSON.parse(jobData) };
|
|
26
|
+
}
|
|
27
|
+
if (commentData) {
|
|
28
|
+
return { type: "comment", data: JSON.parse(commentData) };
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Processes a webhook payload and calls the appropriate callback
|
|
34
|
+
*/
|
|
35
|
+
async process(payload) {
|
|
36
|
+
try {
|
|
37
|
+
if (payload.type === "job" && this.callbacks.onJobUpdate) {
|
|
38
|
+
await this.callbacks.onJobUpdate(payload.data);
|
|
39
|
+
return { success: true, type: "job" };
|
|
40
|
+
}
|
|
41
|
+
if (payload.type === "comment" && this.callbacks.onComment) {
|
|
42
|
+
await this.callbacks.onComment(payload.data);
|
|
43
|
+
return { success: true, type: "comment" };
|
|
44
|
+
}
|
|
45
|
+
return { success: true, type: payload.type };
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
48
|
+
if (this.callbacks.onError) {
|
|
49
|
+
await this.callbacks.onError(err);
|
|
50
|
+
}
|
|
51
|
+
return { success: false, error: err };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parses and processes a webhook request body
|
|
56
|
+
*/
|
|
57
|
+
async handleFormData(formData) {
|
|
58
|
+
const payload = this.parsePayload(formData);
|
|
59
|
+
if (!payload) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: new Error("Invalid webhook payload: no job or comment data found")
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return this.process(payload);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function createWebhookHandler(callbacks) {
|
|
69
|
+
return new WebhookHandler(callbacks);
|
|
70
|
+
}
|
|
71
|
+
async function handleRequest(request, handler) {
|
|
72
|
+
if (request.method !== "POST") {
|
|
73
|
+
return new Response("Method not allowed", { status: 405 });
|
|
74
|
+
}
|
|
75
|
+
const contentType = request.headers.get("content-type") ?? "";
|
|
76
|
+
try {
|
|
77
|
+
let formData;
|
|
78
|
+
if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
79
|
+
const text = await request.text();
|
|
80
|
+
formData = new URLSearchParams(text);
|
|
81
|
+
} else if (contentType.includes("multipart/form-data")) {
|
|
82
|
+
formData = await request.formData();
|
|
83
|
+
} else {
|
|
84
|
+
return new Response("Unsupported content type", { status: 415 });
|
|
85
|
+
}
|
|
86
|
+
const result = await handler.handleFormData(formData);
|
|
87
|
+
if (result.success) {
|
|
88
|
+
return new Response("OK", { status: 200 });
|
|
89
|
+
} else {
|
|
90
|
+
return new Response(result.error?.message ?? "Processing failed", { status: 500 });
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
94
|
+
return new Response(message, { status: 500 });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { WebhookHandler, createWebhookHandler, handleRequest };
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
100
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/webhook/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n JobCallback,\n CommentCallback,\n WebhookHandlerCallbacks,\n WebhookPayload,\n WebhookResult,\n} from './types.js';\n\nexport type {\n JobCallback,\n CommentCallback,\n WebhookHandlerCallbacks,\n WebhookPayload,\n WebhookResult,\n};\n\n/**\n * Webhook handler for processing Gengo callbacks\n */\nexport class WebhookHandler {\n constructor(private readonly callbacks: WebhookHandlerCallbacks) {}\n\n /**\n * Parses form data and returns the webhook payload\n */\n parsePayload(formData: URLSearchParams | FormData | Record<string, string>): WebhookPayload | null {\n let jobData: string | null = null;\n let commentData: string | null = null;\n\n if (formData instanceof URLSearchParams) {\n jobData = formData.get('job');\n commentData = formData.get('comment');\n } else if (formData instanceof FormData) {\n const jobValue = formData.get('job');\n const commentValue = formData.get('comment');\n jobData = typeof jobValue === 'string' ? jobValue : null;\n commentData = typeof commentValue === 'string' ? commentValue : null;\n } else {\n jobData = formData['job'] ?? null;\n commentData = formData['comment'] ?? null;\n }\n\n if (jobData) {\n return { type: 'job', data: JSON.parse(jobData) as JobCallback };\n }\n\n if (commentData) {\n return { type: 'comment', data: JSON.parse(commentData) as CommentCallback };\n }\n\n return null;\n }\n\n /**\n * Processes a webhook payload and calls the appropriate callback\n */\n async process(payload: WebhookPayload): Promise<WebhookResult> {\n try {\n if (payload.type === 'job' && this.callbacks.onJobUpdate) {\n await this.callbacks.onJobUpdate(payload.data);\n return { success: true, type: 'job' };\n }\n\n if (payload.type === 'comment' && this.callbacks.onComment) {\n await this.callbacks.onComment(payload.data);\n return { success: true, type: 'comment' };\n }\n\n return { success: true, type: payload.type };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (this.callbacks.onError) {\n await this.callbacks.onError(err);\n }\n return { success: false, error: err };\n }\n }\n\n /**\n * Parses and processes a webhook request body\n */\n async handleFormData(\n formData: URLSearchParams | FormData | Record<string, string>\n ): Promise<WebhookResult> {\n const payload = this.parsePayload(formData);\n\n if (!payload) {\n return {\n success: false,\n error: new Error('Invalid webhook payload: no job or comment data found'),\n };\n }\n\n return this.process(payload);\n }\n}\n\n/**\n * Creates a webhook handler with the specified callbacks\n */\nexport function createWebhookHandler(\n callbacks: WebhookHandlerCallbacks\n): WebhookHandler {\n return new WebhookHandler(callbacks);\n}\n\n/**\n * Handles a raw Web Request (for Deno, Bun, Cloudflare Workers)\n */\nexport async function handleRequest(\n request: Request,\n handler: WebhookHandler\n): Promise<Response> {\n if (request.method !== 'POST') {\n return new Response('Method not allowed', { status: 405 });\n }\n\n const contentType = request.headers.get('content-type') ?? '';\n\n try {\n let formData: URLSearchParams | FormData;\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await request.text();\n formData = new URLSearchParams(text);\n } else if (contentType.includes('multipart/form-data')) {\n formData = await request.formData();\n } else {\n return new Response('Unsupported content type', { status: 415 });\n }\n\n const result = await handler.handleFormData(formData);\n\n if (result.success) {\n return new Response('OK', { status: 200 });\n } else {\n return new Response(result.error?.message ?? 'Processing failed', { status: 500 });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return new Response(message, { status: 500 });\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gengo-ts",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Modern TypeScript client for the Gengo Translation API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./webhook": {
|
|
15
|
+
"types": "./dist/webhook/index.d.ts",
|
|
16
|
+
"import": "./dist/webhook/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./webhook/express": {
|
|
19
|
+
"types": "./dist/webhook/express.d.ts",
|
|
20
|
+
"import": "./dist/webhook/express.js"
|
|
21
|
+
},
|
|
22
|
+
"./webhook/hono": {
|
|
23
|
+
"types": "./dist/webhook/hono.d.ts",
|
|
24
|
+
"import": "./dist/webhook/hono.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"dev": "tsup --watch",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"clean": "rm -rf dist"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"gengo",
|
|
39
|
+
"translation",
|
|
40
|
+
"api",
|
|
41
|
+
"typescript",
|
|
42
|
+
"i18n",
|
|
43
|
+
"localization"
|
|
44
|
+
],
|
|
45
|
+
"author": "",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.10.0",
|
|
52
|
+
"tsup": "^8.0.1",
|
|
53
|
+
"typescript": "^5.3.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"express": "^4.18.0 || ^5.0.0",
|
|
57
|
+
"hono": "^3.0.0 || ^4.0.0"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"express": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"hono": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|