@umituz/web-localization 1.0.5 → 1.0.6

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.
Files changed (40) hide show
  1. package/dist/infrastructure/services/cli.service.js +3 -3
  2. package/dist/infrastructure/services/google-translate.service.d.ts +2 -2
  3. package/dist/infrastructure/services/google-translate.service.d.ts.map +1 -1
  4. package/dist/infrastructure/services/google-translate.service.js +3 -3
  5. package/dist/scripts/cli.js +1 -1
  6. package/package.json +1 -1
  7. package/src/infrastructure/services/cli.service.ts +8 -6
  8. package/src/infrastructure/services/google-translate.service.ts +5 -5
  9. package/src/infrastructure/utils/file.util.ts +0 -1
  10. package/src/scripts/cli.ts +1 -1
  11. package/src/domain/entities/translation.entity.d.ts +0 -30
  12. package/src/domain/entities/translation.entity.d.ts.map +0 -1
  13. package/src/domain/entities/translation.entity.js +0 -5
  14. package/src/domain/interfaces/translation-service.interface.d.ts +0 -21
  15. package/src/domain/interfaces/translation-service.interface.d.ts.map +0 -1
  16. package/src/domain/interfaces/translation-service.interface.js +0 -1
  17. package/src/index.d.ts +0 -11
  18. package/src/index.d.ts.map +0 -1
  19. package/src/index.js +0 -10
  20. package/src/infrastructure/constants/index.d.ts +0 -11
  21. package/src/infrastructure/constants/index.d.ts.map +0 -1
  22. package/src/infrastructure/constants/index.js +0 -10
  23. package/src/infrastructure/services/cli.service.d.ts +0 -11
  24. package/src/infrastructure/services/cli.service.d.ts.map +0 -1
  25. package/src/infrastructure/services/cli.service.js +0 -95
  26. package/src/infrastructure/services/google-translate.service.d.ts +0 -20
  27. package/src/infrastructure/services/google-translate.service.d.ts.map +0 -1
  28. package/src/infrastructure/services/google-translate.service.js +0 -202
  29. package/src/infrastructure/utils/file.util.d.ts +0 -10
  30. package/src/infrastructure/utils/file.util.d.ts.map +0 -1
  31. package/src/infrastructure/utils/file.util.js +0 -41
  32. package/src/infrastructure/utils/rate-limit.util.d.ts +0 -11
  33. package/src/infrastructure/utils/rate-limit.util.d.ts.map +0 -1
  34. package/src/infrastructure/utils/rate-limit.util.js +0 -20
  35. package/src/infrastructure/utils/text-validator.util.d.ts +0 -16
  36. package/src/infrastructure/utils/text-validator.util.d.ts.map +0 -1
  37. package/src/infrastructure/utils/text-validator.util.js +0 -34
  38. package/src/scripts/cli.d.ts +0 -6
  39. package/src/scripts/cli.d.ts.map +0 -1
  40. package/src/scripts/cli.js +0 -41
@@ -1,9 +1,9 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import chalk from "chalk";
4
- import { googleTranslateService } from "./google-translate.service";
5
- import { parseTypeScriptFile, generateTypeScriptContent } from "../utils/file.util";
6
- import { DEFAULT_LOCALES_DIR, DEFAULT_BASE_LANGUAGE } from "../constants";
4
+ import { googleTranslateService } from "./google-translate.service.js";
5
+ import { parseTypeScriptFile, generateTypeScriptContent } from "../utils/file.util.js";
6
+ import { DEFAULT_LOCALES_DIR, DEFAULT_BASE_LANGUAGE } from "../constants/index.js";
7
7
  export class CLIService {
8
8
  async sync(options = {}) {
9
9
  const localesDir = path.resolve(process.cwd(), options.localesDir || DEFAULT_LOCALES_DIR);
@@ -2,8 +2,8 @@
2
2
  * Google Translate Service
3
3
  * @description Main translation service using Google Translate API
4
4
  */
5
- import type { TranslationRequest, TranslationResponse, TranslationStats } from "../../domain/entities/translation.entity";
6
- import type { ITranslationService, TranslationServiceConfig } from "../../domain/interfaces/translation-service.interface";
5
+ import type { TranslationRequest, TranslationResponse, TranslationStats } from "../../domain/entities/translation.entity.js";
6
+ import type { ITranslationService, TranslationServiceConfig } from "../../domain/interfaces/translation-service.interface.js";
7
7
  declare class GoogleTranslateService implements ITranslationService {
8
8
  private config;
9
9
  private rateLimiter;
@@ -1 +1 @@
1
- {"version":3,"file":"google-translate.service.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/services/google-translate.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAa/D,cAAM,sBAAuB,YAAW,mBAAmB;IACzD,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,WAAW,CAA4B;IAE/C,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI;IASlD,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAQnB,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsDpE,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyDzE,eAAe,CACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,cAAc,EAAE,MAAM,EACtB,IAAI,SAAK,EACT,KAAK,GAAE,gBAMN,EACD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,GAC5D,OAAO,CAAC,IAAI,CAAC;YA6DF,gBAAgB;CAuC/B;AAED,eAAO,MAAM,sBAAsB,wBAA+B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"google-translate.service.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/services/google-translate.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,0DAA0D,CAAC;AAalE,cAAM,sBAAuB,YAAW,mBAAmB;IACzD,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,WAAW,CAA4B;IAE/C,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI;IASlD,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAQnB,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsDpE,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyDzE,eAAe,CACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,cAAc,EAAE,MAAM,EACtB,IAAI,SAAK,EACT,KAAK,GAAE,gBAMN,EACD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,GAC5D,OAAO,CAAC,IAAI,CAAC;YA6DF,gBAAgB;CAuC/B;AAED,eAAO,MAAM,sBAAsB,wBAA+B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -2,9 +2,9 @@
2
2
  * Google Translate Service
3
3
  * @description Main translation service using Google Translate API
4
4
  */
5
- import { RateLimiter } from "../utils/rate-limit.util";
6
- import { shouldSkipWord, needsTranslation, isValidText, } from "../utils/text-validator.util";
7
- import { GOOGLE_TRANSLATE_API_URL, DEFAULT_MIN_DELAY, DEFAULT_TIMEOUT, } from "../constants";
5
+ import { RateLimiter } from "../utils/rate-limit.util.js";
6
+ import { shouldSkipWord, needsTranslation, isValidText, } from "../utils/text-validator.util.js";
7
+ import { GOOGLE_TRANSLATE_API_URL, DEFAULT_MIN_DELAY, DEFAULT_TIMEOUT, } from "../constants/index.js";
8
8
  class GoogleTranslateService {
9
9
  config = null;
10
10
  rateLimiter = null;
@@ -3,7 +3,7 @@
3
3
  * CLI Tool for @umituz/web-localization
4
4
  */
5
5
  import { Command } from "commander";
6
- import { cliService } from "../infrastructure/services/cli.service";
6
+ import { cliService } from "../infrastructure/services/cli.service.js";
7
7
  import chalk from "chalk";
8
8
  const program = new Command();
9
9
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/web-localization",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Google Translate integrated localization package for web applications",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -1,13 +1,12 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import chalk from "chalk";
4
- import { googleTranslateService } from "./google-translate.service";
5
- import { parseTypeScriptFile, generateTypeScriptContent } from "../utils/file.util";
4
+ import { googleTranslateService } from "./google-translate.service.js";
5
+ import { parseTypeScriptFile, generateTypeScriptContent } from "../utils/file.util.js";
6
6
  import {
7
7
  DEFAULT_LOCALES_DIR,
8
- DEFAULT_SOURCE_DIR,
9
8
  DEFAULT_BASE_LANGUAGE
10
- } from "../constants";
9
+ } from "../constants/index.js";
11
10
 
12
11
  export interface SyncOptions {
13
12
  localesDir?: string;
@@ -44,11 +43,14 @@ export class CLIService {
44
43
  const langCode = file.replace(".ts", "");
45
44
 
46
45
  // Deep merge with base data structure
47
- const syncObject = (source: any, target: any) => {
46
+ const syncObject = (source: Record<string, unknown>, target: Record<string, unknown>): Record<string, unknown> => {
48
47
  const result = { ...target };
49
48
  for (const key in source) {
50
49
  if (typeof source[key] === "object" && source[key] !== null) {
51
- result[key] = syncObject(source[key], target[key] || {});
50
+ result[key] = syncObject(
51
+ source[key] as Record<string, unknown>,
52
+ (target[key] as Record<string, unknown>) || {}
53
+ );
52
54
  } else if (target[key] === undefined) {
53
55
  result[key] = source[key];
54
56
  }
@@ -7,22 +7,22 @@ import type {
7
7
  TranslationRequest,
8
8
  TranslationResponse,
9
9
  TranslationStats,
10
- } from "../../domain/entities/translation.entity";
10
+ } from "../../domain/entities/translation.entity.js";
11
11
  import type {
12
12
  ITranslationService,
13
13
  TranslationServiceConfig,
14
- } from "../../domain/interfaces/translation-service.interface";
15
- import { RateLimiter } from "../utils/rate-limit.util";
14
+ } from "../../domain/interfaces/translation-service.interface.js";
15
+ import { RateLimiter } from "../utils/rate-limit.util.js";
16
16
  import {
17
17
  shouldSkipWord,
18
18
  needsTranslation,
19
19
  isValidText,
20
- } from "../utils/text-validator.util";
20
+ } from "../utils/text-validator.util.js";
21
21
  import {
22
22
  GOOGLE_TRANSLATE_API_URL,
23
23
  DEFAULT_MIN_DELAY,
24
24
  DEFAULT_TIMEOUT,
25
- } from "../constants";
25
+ } from "../constants/index.js";
26
26
 
27
27
  class GoogleTranslateService implements ITranslationService {
28
28
  private config: TranslationServiceConfig | null = null;
@@ -1,5 +1,4 @@
1
1
  import fs from "fs";
2
- import path from "path";
3
2
 
4
3
  /**
5
4
  * Parses a TypeScript file containing an object export
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { Command } from "commander";
8
- import { cliService } from "../infrastructure/services/cli.service";
8
+ import { cliService } from "../infrastructure/services/cli.service.js";
9
9
  import chalk from "chalk";
10
10
 
11
11
  const program = new Command();
@@ -1,30 +0,0 @@
1
- /**
2
- * Translation Entity
3
- * @description Data structures for translation requests and responses
4
- */
5
- export interface TranslationRequest {
6
- readonly text: string;
7
- readonly targetLanguage: string;
8
- readonly sourceLanguage?: string;
9
- }
10
- export interface TranslationResponse {
11
- readonly originalText: string;
12
- readonly translatedText: string;
13
- readonly sourceLanguage: string;
14
- readonly targetLanguage: string;
15
- readonly success: boolean;
16
- readonly error?: string;
17
- }
18
- export interface TranslationItem {
19
- readonly key: string;
20
- readonly from: string;
21
- readonly to: string;
22
- }
23
- export interface TranslationStats {
24
- totalCount: number;
25
- successCount: number;
26
- failureCount: number;
27
- skippedCount: number;
28
- translatedKeys: TranslationItem[];
29
- }
30
- //# sourceMappingURL=translation.entity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translation.entity.d.ts","sourceRoot":"","sources":["translation.entity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,eAAe,EAAE,CAAC;CACnC"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Translation Entity
3
- * @description Data structures for translation requests and responses
4
- */
5
- export {};
@@ -1,21 +0,0 @@
1
- import type { TranslationRequest, TranslationResponse, TranslationStats } from "../entities/translation.entity";
2
- /**
3
- * Translation Service Config
4
- */
5
- export interface TranslationServiceConfig {
6
- minDelay?: number;
7
- maxRetries?: number;
8
- timeout?: number;
9
- apiKey?: string;
10
- }
11
- /**
12
- * Translation Service Interface
13
- */
14
- export interface ITranslationService {
15
- initialize(config: TranslationServiceConfig): void;
16
- isInitialized(): boolean;
17
- translate(request: TranslationRequest): Promise<TranslationResponse>;
18
- translateBatch(requests: TranslationRequest[]): Promise<TranslationStats>;
19
- translateObject(sourceObject: Record<string, unknown>, targetObject: Record<string, unknown>, targetLanguage: string, path?: string, stats?: TranslationStats, onTranslate?: (key: string, from: string, to: string) => void): Promise<void>;
20
- }
21
- //# sourceMappingURL=translation-service.interface.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"translation-service.interface.d.ts","sourceRoot":"","sources":["translation-service.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACnD,aAAa,IAAI,OAAO,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrE,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1E,eAAe,CACb,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,gBAAgB,EACxB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,GAC5D,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
package/src/index.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * @umituz/web-localization
3
- * Google Translate integrated localization package for web applications
4
- */
5
- export * from "./domain/entities/translation.entity";
6
- export * from "./domain/interfaces/translation-service.interface";
7
- export * from "./infrastructure/services/google-translate.service";
8
- export * from "./infrastructure/constants";
9
- export * from "./infrastructure/utils/text-validator.util";
10
- export * from "./infrastructure/utils/rate-limit.util";
11
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,sCAAsC,CAAC;AACrD,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wCAAwC,CAAC"}
package/src/index.js DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * @umituz/web-localization
3
- * Google Translate integrated localization package for web applications
4
- */
5
- export * from "./domain/entities/translation.entity";
6
- export * from "./domain/interfaces/translation-service.interface";
7
- export * from "./infrastructure/services/google-translate.service";
8
- export * from "./infrastructure/constants";
9
- export * from "./infrastructure/utils/text-validator.util";
10
- export * from "./infrastructure/utils/rate-limit.util";
@@ -1,11 +0,0 @@
1
- /**
2
- * Localization Constants
3
- */
4
- export declare const GOOGLE_TRANSLATE_API_URL = "https://translate.googleapis.com/translate_a/single";
5
- export declare const DEFAULT_MIN_DELAY = 100;
6
- export declare const DEFAULT_MAX_RETRIES = 3;
7
- export declare const DEFAULT_TIMEOUT = 10000;
8
- export declare const DEFAULT_LOCALES_DIR = "src/locales";
9
- export declare const DEFAULT_SOURCE_DIR = "src";
10
- export declare const DEFAULT_BASE_LANGUAGE = "en-US";
11
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,wBAAwB,wDAAwD,CAAC;AAE9F,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AACjD,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,qBAAqB,UAAU,CAAC"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Localization Constants
3
- */
4
- export const GOOGLE_TRANSLATE_API_URL = "https://translate.googleapis.com/translate_a/single";
5
- export const DEFAULT_MIN_DELAY = 100;
6
- export const DEFAULT_MAX_RETRIES = 3;
7
- export const DEFAULT_TIMEOUT = 10000;
8
- export const DEFAULT_LOCALES_DIR = "src/locales";
9
- export const DEFAULT_SOURCE_DIR = "src";
10
- export const DEFAULT_BASE_LANGUAGE = "en-US";
@@ -1,11 +0,0 @@
1
- export interface SyncOptions {
2
- localesDir?: string;
3
- sourceDir?: string;
4
- baseLang?: string;
5
- }
6
- export declare class CLIService {
7
- sync(options?: SyncOptions): Promise<void>;
8
- translate(options?: SyncOptions): Promise<void>;
9
- }
10
- export declare const cliService: CLIService;
11
- //# sourceMappingURL=cli.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.service.d.ts","sourceRoot":"","sources":["cli.service.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACf,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsD9C,SAAS,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAsD1D;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC"}
@@ -1,95 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import chalk from "chalk";
4
- import { googleTranslateService } from "./google-translate.service";
5
- import { parseTypeScriptFile, generateTypeScriptContent } from "../utils/file.util";
6
- import { DEFAULT_LOCALES_DIR, DEFAULT_BASE_LANGUAGE } from "../constants";
7
- export class CLIService {
8
- async sync(options = {}) {
9
- const localesDir = path.resolve(process.cwd(), options.localesDir || DEFAULT_LOCALES_DIR);
10
- const baseLang = options.baseLang || DEFAULT_BASE_LANGUAGE;
11
- const baseLangPath = path.join(localesDir, `${baseLang}.ts`);
12
- if (!fs.existsSync(localesDir)) {
13
- console.error(chalk.red(`❌ Locales directory not found: ${localesDir}`));
14
- return;
15
- }
16
- if (!fs.existsSync(baseLangPath)) {
17
- console.error(chalk.red(`❌ Base language file not found: ${baseLangPath}`));
18
- return;
19
- }
20
- const baseData = parseTypeScriptFile(baseLangPath);
21
- const files = fs.readdirSync(localesDir)
22
- .filter(f => f.match(/^[a-z]{2}-[A-Z]{2}\.ts$/) && f !== `${baseLang}.ts`)
23
- .sort();
24
- console.log(chalk.blue(`📊 Found ${files.length} languages to sync with ${baseLang}.\n`));
25
- for (const file of files) {
26
- const targetPath = path.join(localesDir, file);
27
- const targetData = parseTypeScriptFile(targetPath);
28
- const langCode = file.replace(".ts", "");
29
- // Deep merge with base data structure
30
- const syncObject = (source, target) => {
31
- const result = { ...target };
32
- for (const key in source) {
33
- if (typeof source[key] === "object" && source[key] !== null) {
34
- result[key] = syncObject(source[key], target[key] || {});
35
- }
36
- else if (target[key] === undefined) {
37
- result[key] = source[key];
38
- }
39
- }
40
- // Remove extra keys
41
- for (const key in target) {
42
- if (source[key] === undefined) {
43
- delete result[key];
44
- }
45
- }
46
- return result;
47
- };
48
- const syncedData = syncObject(baseData, targetData);
49
- fs.writeFileSync(targetPath, generateTypeScriptContent(syncedData, langCode));
50
- console.log(chalk.green(` 🌍 ${langCode}: Synced structure.`));
51
- }
52
- console.log(chalk.bold.green("\n✅ Synchronization completed!"));
53
- }
54
- async translate(options = {}) {
55
- const localesDir = path.resolve(process.cwd(), options.localesDir || DEFAULT_LOCALES_DIR);
56
- const baseLang = options.baseLang || DEFAULT_BASE_LANGUAGE;
57
- const baseLangPath = path.join(localesDir, `${baseLang}.ts`);
58
- if (!fs.existsSync(baseLangPath)) {
59
- console.error(chalk.red(`❌ Base language file not found: ${baseLangPath}`));
60
- return;
61
- }
62
- googleTranslateService.initialize({});
63
- const baseData = parseTypeScriptFile(baseLangPath);
64
- const files = fs.readdirSync(localesDir)
65
- .filter(f => f.match(/^[a-z]{2}-[A-Z]{2}\.ts$/) && f !== `${baseLang}.ts`)
66
- .sort();
67
- console.log(chalk.blue.bold(`🚀 Starting automatic translation for ${files.length} languages...\n`));
68
- for (const file of files) {
69
- const targetPath = path.join(localesDir, file);
70
- const targetData = parseTypeScriptFile(targetPath);
71
- const langCode = file.replace(".ts", "");
72
- const stats = {
73
- totalCount: 0,
74
- successCount: 0,
75
- failureCount: 0,
76
- skippedCount: 0,
77
- translatedKeys: []
78
- };
79
- console.log(chalk.yellow(`🌍 Translating ${langCode}...`));
80
- await googleTranslateService.translateObject(baseData, targetData, langCode.split("-")[0], // ISO 639-1
81
- "", stats, (key, from, to) => {
82
- process.stdout.write(chalk.gray(` • ${key}: ${from.substring(0, 15)}... → ${to.substring(0, 15)}...\r`));
83
- });
84
- if (stats.successCount > 0) {
85
- fs.writeFileSync(targetPath, generateTypeScriptContent(targetData, langCode));
86
- console.log(chalk.green(` ✅ Successfully translated ${stats.successCount} keys.`));
87
- }
88
- else {
89
- console.log(chalk.gray(" ✨ Already up to date."));
90
- }
91
- }
92
- console.log(chalk.bold.green("\n✅ All translations completed!"));
93
- }
94
- }
95
- export const cliService = new CLIService();
@@ -1,20 +0,0 @@
1
- /**
2
- * Google Translate Service
3
- * @description Main translation service using Google Translate API
4
- */
5
- import type { TranslationRequest, TranslationResponse, TranslationStats } from "../../domain/entities/translation.entity";
6
- import type { ITranslationService, TranslationServiceConfig } from "../../domain/interfaces/translation-service.interface";
7
- declare class GoogleTranslateService implements ITranslationService {
8
- private config;
9
- private rateLimiter;
10
- initialize(config: TranslationServiceConfig): void;
11
- isInitialized(): boolean;
12
- private ensureInitialized;
13
- translate(request: TranslationRequest): Promise<TranslationResponse>;
14
- translateBatch(requests: TranslationRequest[]): Promise<TranslationStats>;
15
- translateObject(sourceObject: Record<string, unknown>, targetObject: Record<string, unknown>, targetLanguage: string, path?: string, stats?: TranslationStats, onTranslate?: (key: string, from: string, to: string) => void): Promise<void>;
16
- private callTranslateAPI;
17
- }
18
- export declare const googleTranslateService: GoogleTranslateService;
19
- export { GoogleTranslateService };
20
- //# sourceMappingURL=google-translate.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"google-translate.service.d.ts","sourceRoot":"","sources":["google-translate.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,uDAAuD,CAAC;AAa/D,cAAM,sBAAuB,YAAW,mBAAmB;IACzD,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,WAAW,CAA4B;IAE/C,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI;IASlD,aAAa,IAAI,OAAO;IAIxB,OAAO,CAAC,iBAAiB;IAQnB,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsDpE,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyDzE,eAAe,CACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,cAAc,EAAE,MAAM,EACtB,IAAI,SAAK,EACT,KAAK,GAAE,gBAMN,EACD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,GAC5D,OAAO,CAAC,IAAI,CAAC;YA6DF,gBAAgB;CAuC/B;AAED,eAAO,MAAM,sBAAsB,wBAA+B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -1,202 +0,0 @@
1
- /**
2
- * Google Translate Service
3
- * @description Main translation service using Google Translate API
4
- */
5
- import { RateLimiter } from "../utils/rate-limit.util";
6
- import { shouldSkipWord, needsTranslation, isValidText, } from "../utils/text-validator.util";
7
- import { GOOGLE_TRANSLATE_API_URL, DEFAULT_MIN_DELAY, DEFAULT_TIMEOUT, } from "../constants";
8
- class GoogleTranslateService {
9
- config = null;
10
- rateLimiter = null;
11
- initialize(config) {
12
- this.config = {
13
- minDelay: DEFAULT_MIN_DELAY,
14
- timeout: DEFAULT_TIMEOUT,
15
- ...config,
16
- };
17
- this.rateLimiter = new RateLimiter(this.config.minDelay);
18
- }
19
- isInitialized() {
20
- return this.config !== null && this.rateLimiter !== null;
21
- }
22
- ensureInitialized() {
23
- if (!this.isInitialized()) {
24
- throw new Error("GoogleTranslateService is not initialized. Call initialize() first.");
25
- }
26
- }
27
- async translate(request) {
28
- this.ensureInitialized();
29
- const { text, targetLanguage, sourceLanguage = "en" } = request;
30
- if (!isValidText(text) || shouldSkipWord(text)) {
31
- return {
32
- originalText: text,
33
- translatedText: text,
34
- sourceLanguage,
35
- targetLanguage,
36
- success: true,
37
- };
38
- }
39
- if (!targetLanguage || targetLanguage.trim().length === 0) {
40
- return {
41
- originalText: text,
42
- translatedText: text,
43
- sourceLanguage,
44
- targetLanguage,
45
- success: false,
46
- error: "Invalid target language",
47
- };
48
- }
49
- await this.rateLimiter.waitForSlot();
50
- try {
51
- const translatedText = await this.callTranslateAPI(text, targetLanguage, sourceLanguage);
52
- return {
53
- originalText: text,
54
- translatedText,
55
- sourceLanguage,
56
- targetLanguage,
57
- success: true,
58
- };
59
- }
60
- catch (error) {
61
- return {
62
- originalText: text,
63
- translatedText: text,
64
- sourceLanguage,
65
- targetLanguage,
66
- success: false,
67
- error: error instanceof Error ? error.message : "Unknown error",
68
- };
69
- }
70
- }
71
- async translateBatch(requests) {
72
- this.ensureInitialized();
73
- const stats = {
74
- totalCount: requests.length,
75
- successCount: 0,
76
- failureCount: 0,
77
- skippedCount: 0,
78
- translatedKeys: [],
79
- };
80
- if (!Array.isArray(requests) || requests.length === 0) {
81
- return stats;
82
- }
83
- // Process requests concurrently with controlled parallelism
84
- const concurrencyLimit = 10;
85
- const chunks = [];
86
- for (let i = 0; i < requests.length; i += concurrencyLimit) {
87
- chunks.push(requests.slice(i, i + concurrencyLimit));
88
- }
89
- for (const chunk of chunks) {
90
- const results = await Promise.all(chunk.map(async (request) => {
91
- await this.rateLimiter.waitForSlot();
92
- return this.callTranslateAPI(request.text, request.targetLanguage, request.sourceLanguage || "en");
93
- }));
94
- for (let i = 0; i < chunk.length; i++) {
95
- const request = chunk[i];
96
- const translatedText = results[i];
97
- if (translatedText && translatedText !== request.text) {
98
- stats.successCount++;
99
- stats.translatedKeys.push({
100
- key: request.text,
101
- from: request.text,
102
- to: translatedText,
103
- });
104
- }
105
- else if (!translatedText) {
106
- stats.failureCount++;
107
- }
108
- else {
109
- stats.skippedCount++;
110
- }
111
- }
112
- }
113
- return stats;
114
- }
115
- async translateObject(sourceObject, targetObject, targetLanguage, path = "", stats = {
116
- totalCount: 0,
117
- successCount: 0,
118
- failureCount: 0,
119
- skippedCount: 0,
120
- translatedKeys: [],
121
- }, onTranslate) {
122
- if (!sourceObject || typeof sourceObject !== "object")
123
- return;
124
- if (!targetObject || typeof targetObject !== "object")
125
- return;
126
- if (!targetLanguage || targetLanguage.trim().length === 0)
127
- return;
128
- const keys = Object.keys(sourceObject);
129
- const textsToTranslate = [];
130
- for (const key of keys) {
131
- const enValue = sourceObject[key];
132
- const targetValue = targetObject[key];
133
- const currentPath = path ? `${path}.${key}` : key;
134
- if (typeof enValue === "object" && enValue !== null) {
135
- if (!targetObject[key] || typeof targetObject[key] !== "object") {
136
- targetObject[key] = {};
137
- }
138
- await this.translateObject(enValue, targetObject[key], targetLanguage, currentPath, stats, onTranslate);
139
- }
140
- else if (typeof enValue === "string") {
141
- stats.totalCount++;
142
- if (needsTranslation(targetValue, enValue)) {
143
- textsToTranslate.push({ key, enValue, currentPath });
144
- }
145
- else {
146
- stats.skippedCount++;
147
- }
148
- }
149
- }
150
- if (textsToTranslate.length > 0) {
151
- const batchSize = 50;
152
- for (let i = 0; i < textsToTranslate.length; i += batchSize) {
153
- const batch = textsToTranslate.slice(i, i + batchSize);
154
- const results = await this.translateBatch(batch.map(item => ({
155
- text: item.enValue,
156
- targetLanguage,
157
- })));
158
- let resultIndex = 0;
159
- for (let j = 0; j < batch.length; j++) {
160
- const { key, enValue, currentPath } = batch[j];
161
- const translatedItem = results.translatedKeys[resultIndex];
162
- if (translatedItem && translatedItem.from === enValue && translatedItem.to !== enValue) {
163
- targetObject[key] = translatedItem.to;
164
- if (onTranslate)
165
- onTranslate(currentPath, enValue, translatedItem.to);
166
- resultIndex++;
167
- }
168
- }
169
- }
170
- }
171
- }
172
- async callTranslateAPI(text, targetLanguage, sourceLanguage) {
173
- const timeout = this.config?.timeout || DEFAULT_TIMEOUT;
174
- const encodedText = encodeURIComponent(text);
175
- const url = `${GOOGLE_TRANSLATE_API_URL}?client=gtx&sl=${sourceLanguage}&tl=${targetLanguage}&dt=t&q=${encodedText}`;
176
- const controller = new AbortController();
177
- const timeoutId = setTimeout(() => controller.abort(), timeout);
178
- try {
179
- const response = await fetch(url, {
180
- signal: controller.signal,
181
- });
182
- if (!response.ok) {
183
- throw new Error(`API request failed: ${response.status}`);
184
- }
185
- const data = await response.json();
186
- if (Array.isArray(data) &&
187
- data.length > 0 &&
188
- Array.isArray(data[0]) &&
189
- data[0].length > 0 &&
190
- Array.isArray(data[0][0]) &&
191
- typeof data[0][0][0] === "string") {
192
- return data[0][0][0];
193
- }
194
- return text;
195
- }
196
- finally {
197
- clearTimeout(timeoutId);
198
- }
199
- }
200
- }
201
- export const googleTranslateService = new GoogleTranslateService();
202
- export { GoogleTranslateService };
@@ -1,10 +0,0 @@
1
- /**
2
- * Parses a TypeScript file containing an object export
3
- * @description Simplistic parser for 'export default { ... }' or 'export const data = { ... }'
4
- */
5
- export declare function parseTypeScriptFile(filePath: string): Record<string, unknown>;
6
- /**
7
- * Generates a TypeScript file content from an object
8
- */
9
- export declare function generateTypeScriptContent(obj: Record<string, unknown>, langCode?: string): string;
10
- //# sourceMappingURL=file.util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file.util.d.ts","sourceRoot":"","sources":["file.util.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoB7E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAajG"}
@@ -1,41 +0,0 @@
1
- import fs from "fs";
2
- /**
3
- * Parses a TypeScript file containing an object export
4
- * @description Simplistic parser for 'export default { ... }' or 'export const data = { ... }'
5
- */
6
- export function parseTypeScriptFile(filePath) {
7
- if (!fs.existsSync(filePath))
8
- return {};
9
- const content = fs.readFileSync(filePath, "utf-8");
10
- // Extract the object part
11
- // This is a naive implementation, but matches the pattern used in the project
12
- const match = content.match(/export (default|const [^=]+ =) (\{[\s\S]*\});?\s*$/);
13
- if (!match)
14
- return {};
15
- try {
16
- // Evaluate the object string to a real JS object
17
- // Using Function instead of eval for slightly better safety
18
- const objStr = match[2];
19
- const obj = new Function(`return ${objStr}`)();
20
- return obj;
21
- }
22
- catch (err) {
23
- console.error(`Error parsing ${filePath}:`, err);
24
- return {};
25
- }
26
- }
27
- /**
28
- * Generates a TypeScript file content from an object
29
- */
30
- export function generateTypeScriptContent(obj, langCode) {
31
- const jsonStr = JSON.stringify(obj, null, 2);
32
- // Clean up keys (remove quotes if possible, though JSON.stringify adds them)
33
- // For simplicity, we'll keep them as valid JS objects
34
- return `/**
35
- * Localization: ${langCode || "unknown"}
36
- * Generated by @umituz/web-localization
37
- */
38
-
39
- export default ${jsonStr};
40
- `;
41
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Simple Rate Limiter
3
- * @description Controls the frequency of API requests
4
- */
5
- export declare class RateLimiter {
6
- private lastRequestTime;
7
- private minDelay;
8
- constructor(minDelay?: number);
9
- waitForSlot(): Promise<void>;
10
- }
11
- //# sourceMappingURL=rate-limit.util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rate-limit.util.d.ts","sourceRoot":"","sources":["rate-limit.util.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,WAAW;IACtB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,SAAM;IAIpB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAWnC"}
@@ -1,20 +0,0 @@
1
- /**
2
- * Simple Rate Limiter
3
- * @description Controls the frequency of API requests
4
- */
5
- export class RateLimiter {
6
- lastRequestTime = 0;
7
- minDelay;
8
- constructor(minDelay = 100) {
9
- this.minDelay = minDelay;
10
- }
11
- async waitForSlot() {
12
- const now = Date.now();
13
- const elapsedTime = now - this.lastRequestTime;
14
- if (elapsedTime < this.minDelay) {
15
- const waitTime = this.minDelay - elapsedTime;
16
- await new Promise(resolve => setTimeout(resolve, waitTime));
17
- }
18
- this.lastRequestTime = Date.now();
19
- }
20
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Text Validation Utilities
3
- */
4
- /**
5
- * Validates if the text is suitable for translation
6
- */
7
- export declare function isValidText(text: unknown): text is string;
8
- /**
9
- * Checks if a word should be skipped (e.g., proper nouns, symbols)
10
- */
11
- export declare function shouldSkipWord(text: string): boolean;
12
- /**
13
- * Determines if a key needs translation
14
- */
15
- export declare function needsTranslation(targetValue: unknown, sourceValue: string): boolean;
16
- //# sourceMappingURL=text-validator.util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"text-validator.util.d.ts","sourceRoot":"","sources":["text-validator.util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAKzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAKnF"}
@@ -1,34 +0,0 @@
1
- /**
2
- * Text Validation Utilities
3
- */
4
- /**
5
- * Validates if the text is suitable for translation
6
- */
7
- export function isValidText(text) {
8
- if (typeof text !== "string")
9
- return false;
10
- if (text.trim().length === 0)
11
- return false;
12
- if (/^\d+$/.test(text))
13
- return false; // Don't translate pure numbers
14
- return true;
15
- }
16
- /**
17
- * Checks if a word should be skipped (e.g., proper nouns, symbols)
18
- */
19
- export function shouldSkipWord(text) {
20
- const skiplist = ["@umituz"];
21
- return skiplist.some(word => text.includes(word));
22
- }
23
- /**
24
- * Determines if a key needs translation
25
- */
26
- export function needsTranslation(targetValue, sourceValue) {
27
- if (typeof targetValue !== "string")
28
- return true;
29
- if (targetValue.trim().length === 0)
30
- return true;
31
- if (targetValue === sourceValue && !/^\d+$/.test(sourceValue))
32
- return true;
33
- return false;
34
- }
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * CLI Tool for @umituz/web-localization
4
- */
5
- export {};
6
- //# sourceMappingURL=cli.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
@@ -1,41 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * CLI Tool for @umituz/web-localization
4
- */
5
- import { Command } from "commander";
6
- import { cliService } from "../infrastructure/services/cli.service";
7
- import chalk from "chalk";
8
- const program = new Command();
9
- program
10
- .name("web-loc")
11
- .description("Localization CLI tool for web applications")
12
- .version("1.0.0");
13
- program
14
- .command("sync")
15
- .description("Synchronize missing keys from base language to other languages")
16
- .option("-d, --locales-dir <dir>", "Directory containing locale files", "src/locales")
17
- .option("-b, --base-lang <lang>", "Base language code", "en-US")
18
- .action(async (options) => {
19
- try {
20
- await cliService.sync(options);
21
- }
22
- catch (error) {
23
- console.error(chalk.red("❌ Sync failed:"), error instanceof Error ? error.message : error);
24
- process.exit(1);
25
- }
26
- });
27
- program
28
- .command("translate")
29
- .description("Automatically translate missing strings using Google Translate")
30
- .option("-d, --locales-dir <dir>", "Directory containing locale files", "src/locales")
31
- .option("-b, --base-lang <lang>", "Base language code", "en-US")
32
- .action(async (options) => {
33
- try {
34
- await cliService.translate(options);
35
- }
36
- catch (error) {
37
- console.error(chalk.red("❌ Translation failed:"), error instanceof Error ? error.message : error);
38
- process.exit(1);
39
- }
40
- });
41
- program.parse();