koztv-blog-tools 1.0.0 → 1.0.2

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/dist/index.d.mts CHANGED
@@ -114,4 +114,32 @@ declare function trackLearnMore(service: string): void;
114
114
  */
115
115
  declare function trackServiceClick(service: string): void;
116
116
 
117
- export { type AnalyticsConfig, type GoalName, type GoalParams, type GroupedPost, type ParsePostOptions, type Post, categorizePost, cleanContent, configureAnalytics, deduplicatePosts, extractAttachments, extractExcerpt, extractTitle, generateSlug, groupPosts, parsePost, trackBookAppointment, trackGoal, trackLearnMore, trackServiceClick, trackTelegramClick };
117
+ /**
118
+ * Translation utilities using various AI APIs
119
+ */
120
+ interface TranslateOptions {
121
+ /** API key for the translation service */
122
+ apiKey: string;
123
+ /** Target language (default: 'en') */
124
+ targetLang?: string;
125
+ /** Source language (default: 'ru') */
126
+ sourceLang?: string;
127
+ /** API provider (default: 'glm') */
128
+ provider?: 'glm' | 'openai';
129
+ /** Model to use (default depends on provider) */
130
+ model?: string;
131
+ }
132
+ /**
133
+ * Translate text content
134
+ */
135
+ declare function translateContent(text: string, options: TranslateOptions): Promise<string>;
136
+ /**
137
+ * Translate post title
138
+ */
139
+ declare function translateTitle(title: string, options: TranslateOptions): Promise<string>;
140
+ /**
141
+ * Generate English slug from translated title
142
+ */
143
+ declare function generateEnglishSlug(title: string): string;
144
+
145
+ export { type AnalyticsConfig, type GoalName, type GoalParams, type GroupedPost, type ParsePostOptions, type Post, type TranslateOptions, categorizePost, cleanContent, configureAnalytics, deduplicatePosts, extractAttachments, extractExcerpt, extractTitle, generateEnglishSlug, generateSlug, groupPosts, parsePost, trackBookAppointment, trackGoal, trackLearnMore, trackServiceClick, trackTelegramClick, translateContent, translateTitle };
package/dist/index.d.ts CHANGED
@@ -114,4 +114,32 @@ declare function trackLearnMore(service: string): void;
114
114
  */
115
115
  declare function trackServiceClick(service: string): void;
116
116
 
117
- export { type AnalyticsConfig, type GoalName, type GoalParams, type GroupedPost, type ParsePostOptions, type Post, categorizePost, cleanContent, configureAnalytics, deduplicatePosts, extractAttachments, extractExcerpt, extractTitle, generateSlug, groupPosts, parsePost, trackBookAppointment, trackGoal, trackLearnMore, trackServiceClick, trackTelegramClick };
117
+ /**
118
+ * Translation utilities using various AI APIs
119
+ */
120
+ interface TranslateOptions {
121
+ /** API key for the translation service */
122
+ apiKey: string;
123
+ /** Target language (default: 'en') */
124
+ targetLang?: string;
125
+ /** Source language (default: 'ru') */
126
+ sourceLang?: string;
127
+ /** API provider (default: 'glm') */
128
+ provider?: 'glm' | 'openai';
129
+ /** Model to use (default depends on provider) */
130
+ model?: string;
131
+ }
132
+ /**
133
+ * Translate text content
134
+ */
135
+ declare function translateContent(text: string, options: TranslateOptions): Promise<string>;
136
+ /**
137
+ * Translate post title
138
+ */
139
+ declare function translateTitle(title: string, options: TranslateOptions): Promise<string>;
140
+ /**
141
+ * Generate English slug from translated title
142
+ */
143
+ declare function generateEnglishSlug(title: string): string;
144
+
145
+ export { type AnalyticsConfig, type GoalName, type GoalParams, type GroupedPost, type ParsePostOptions, type Post, type TranslateOptions, categorizePost, cleanContent, configureAnalytics, deduplicatePosts, extractAttachments, extractExcerpt, extractTitle, generateEnglishSlug, generateSlug, groupPosts, parsePost, trackBookAppointment, trackGoal, trackLearnMore, trackServiceClick, trackTelegramClick, translateContent, translateTitle };
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  extractAttachments: () => extractAttachments,
38
38
  extractExcerpt: () => extractExcerpt,
39
39
  extractTitle: () => extractTitle,
40
+ generateEnglishSlug: () => generateEnglishSlug,
40
41
  generateSlug: () => generateSlug,
41
42
  groupPosts: () => groupPosts,
42
43
  parsePost: () => parsePost,
@@ -44,7 +45,9 @@ __export(index_exports, {
44
45
  trackGoal: () => trackGoal,
45
46
  trackLearnMore: () => trackLearnMore,
46
47
  trackServiceClick: () => trackServiceClick,
47
- trackTelegramClick: () => trackTelegramClick
48
+ trackTelegramClick: () => trackTelegramClick,
49
+ translateContent: () => translateContent,
50
+ translateTitle: () => translateTitle
48
51
  });
49
52
  module.exports = __toCommonJS(index_exports);
50
53
 
@@ -304,6 +307,96 @@ function trackLearnMore(service) {
304
307
  function trackServiceClick(service) {
305
308
  trackGoal("click_service", { service });
306
309
  }
310
+
311
+ // src/translate.ts
312
+ async function translateWithGLM(text, options) {
313
+ const model = options.model || "glm-4";
314
+ const targetLang = options.targetLang || "en";
315
+ const sourceLang = options.sourceLang || "ru";
316
+ const messages = [
317
+ {
318
+ role: "system",
319
+ content: `You are a professional translator. Translate the following text from ${sourceLang} to ${targetLang}.
320
+ Keep the markdown formatting intact.
321
+ Only output the translated text, nothing else.
322
+ Do not add any explanations or notes.`
323
+ },
324
+ {
325
+ role: "user",
326
+ content: text
327
+ }
328
+ ];
329
+ const response = await fetch("https://open.bigmodel.cn/api/paas/v4/chat/completions", {
330
+ method: "POST",
331
+ headers: {
332
+ "Content-Type": "application/json",
333
+ "Authorization": `Bearer ${options.apiKey}`
334
+ },
335
+ body: JSON.stringify({
336
+ model,
337
+ messages,
338
+ temperature: 0.3
339
+ })
340
+ });
341
+ if (!response.ok) {
342
+ const error = await response.text();
343
+ throw new Error(`GLM API error: ${response.status} - ${error}`);
344
+ }
345
+ const data = await response.json();
346
+ return data.choices[0]?.message?.content || "";
347
+ }
348
+ async function translateWithOpenAI(text, options) {
349
+ const model = options.model || "gpt-4o-mini";
350
+ const targetLang = options.targetLang || "en";
351
+ const sourceLang = options.sourceLang || "ru";
352
+ const response = await fetch("https://api.openai.com/v1/chat/completions", {
353
+ method: "POST",
354
+ headers: {
355
+ "Content-Type": "application/json",
356
+ "Authorization": `Bearer ${options.apiKey}`
357
+ },
358
+ body: JSON.stringify({
359
+ model,
360
+ messages: [
361
+ {
362
+ role: "system",
363
+ content: `You are a professional translator. Translate the following text from ${sourceLang} to ${targetLang}.
364
+ Keep the markdown formatting intact.
365
+ Only output the translated text, nothing else.`
366
+ },
367
+ {
368
+ role: "user",
369
+ content: text
370
+ }
371
+ ],
372
+ temperature: 0.3
373
+ })
374
+ });
375
+ if (!response.ok) {
376
+ const error = await response.text();
377
+ throw new Error(`OpenAI API error: ${response.status} - ${error}`);
378
+ }
379
+ const data = await response.json();
380
+ return data.choices[0]?.message?.content || "";
381
+ }
382
+ async function translateContent(text, options) {
383
+ const provider = options.provider || "glm";
384
+ switch (provider) {
385
+ case "glm":
386
+ return translateWithGLM(text, options);
387
+ case "openai":
388
+ return translateWithOpenAI(text, options);
389
+ default:
390
+ throw new Error(`Unknown provider: ${provider}`);
391
+ }
392
+ }
393
+ async function translateTitle(title, options) {
394
+ const translated = await translateContent(title, options);
395
+ return translated.replace(/^["']|["']$/g, "").trim();
396
+ }
397
+ function generateEnglishSlug(title) {
398
+ return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").substring(0, 60);
399
+ }
307
400
  // Annotate the CommonJS export names for ESM import in node:
308
401
  0 && (module.exports = {
309
402
  categorizePost,
@@ -313,6 +406,7 @@ function trackServiceClick(service) {
313
406
  extractAttachments,
314
407
  extractExcerpt,
315
408
  extractTitle,
409
+ generateEnglishSlug,
316
410
  generateSlug,
317
411
  groupPosts,
318
412
  parsePost,
@@ -320,5 +414,7 @@ function trackServiceClick(service) {
320
414
  trackGoal,
321
415
  trackLearnMore,
322
416
  trackServiceClick,
323
- trackTelegramClick
417
+ trackTelegramClick,
418
+ translateContent,
419
+ translateTitle
324
420
  });
package/dist/index.mjs CHANGED
@@ -254,6 +254,96 @@ function trackLearnMore(service) {
254
254
  function trackServiceClick(service) {
255
255
  trackGoal("click_service", { service });
256
256
  }
257
+
258
+ // src/translate.ts
259
+ async function translateWithGLM(text, options) {
260
+ const model = options.model || "glm-4";
261
+ const targetLang = options.targetLang || "en";
262
+ const sourceLang = options.sourceLang || "ru";
263
+ const messages = [
264
+ {
265
+ role: "system",
266
+ content: `You are a professional translator. Translate the following text from ${sourceLang} to ${targetLang}.
267
+ Keep the markdown formatting intact.
268
+ Only output the translated text, nothing else.
269
+ Do not add any explanations or notes.`
270
+ },
271
+ {
272
+ role: "user",
273
+ content: text
274
+ }
275
+ ];
276
+ const response = await fetch("https://open.bigmodel.cn/api/paas/v4/chat/completions", {
277
+ method: "POST",
278
+ headers: {
279
+ "Content-Type": "application/json",
280
+ "Authorization": `Bearer ${options.apiKey}`
281
+ },
282
+ body: JSON.stringify({
283
+ model,
284
+ messages,
285
+ temperature: 0.3
286
+ })
287
+ });
288
+ if (!response.ok) {
289
+ const error = await response.text();
290
+ throw new Error(`GLM API error: ${response.status} - ${error}`);
291
+ }
292
+ const data = await response.json();
293
+ return data.choices[0]?.message?.content || "";
294
+ }
295
+ async function translateWithOpenAI(text, options) {
296
+ const model = options.model || "gpt-4o-mini";
297
+ const targetLang = options.targetLang || "en";
298
+ const sourceLang = options.sourceLang || "ru";
299
+ const response = await fetch("https://api.openai.com/v1/chat/completions", {
300
+ method: "POST",
301
+ headers: {
302
+ "Content-Type": "application/json",
303
+ "Authorization": `Bearer ${options.apiKey}`
304
+ },
305
+ body: JSON.stringify({
306
+ model,
307
+ messages: [
308
+ {
309
+ role: "system",
310
+ content: `You are a professional translator. Translate the following text from ${sourceLang} to ${targetLang}.
311
+ Keep the markdown formatting intact.
312
+ Only output the translated text, nothing else.`
313
+ },
314
+ {
315
+ role: "user",
316
+ content: text
317
+ }
318
+ ],
319
+ temperature: 0.3
320
+ })
321
+ });
322
+ if (!response.ok) {
323
+ const error = await response.text();
324
+ throw new Error(`OpenAI API error: ${response.status} - ${error}`);
325
+ }
326
+ const data = await response.json();
327
+ return data.choices[0]?.message?.content || "";
328
+ }
329
+ async function translateContent(text, options) {
330
+ const provider = options.provider || "glm";
331
+ switch (provider) {
332
+ case "glm":
333
+ return translateWithGLM(text, options);
334
+ case "openai":
335
+ return translateWithOpenAI(text, options);
336
+ default:
337
+ throw new Error(`Unknown provider: ${provider}`);
338
+ }
339
+ }
340
+ async function translateTitle(title, options) {
341
+ const translated = await translateContent(title, options);
342
+ return translated.replace(/^["']|["']$/g, "").trim();
343
+ }
344
+ function generateEnglishSlug(title) {
345
+ return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").substring(0, 60);
346
+ }
257
347
  export {
258
348
  categorizePost,
259
349
  cleanContent,
@@ -262,6 +352,7 @@ export {
262
352
  extractAttachments,
263
353
  extractExcerpt,
264
354
  extractTitle,
355
+ generateEnglishSlug,
265
356
  generateSlug,
266
357
  groupPosts,
267
358
  parsePost,
@@ -269,5 +360,7 @@ export {
269
360
  trackGoal,
270
361
  trackLearnMore,
271
362
  trackServiceClick,
272
- trackTelegramClick
363
+ trackTelegramClick,
364
+ translateContent,
365
+ translateTitle
273
366
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koztv-blog-tools",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Shared utilities for Telegram-based blog sites",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",