@langapi/mcp-server 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 +551 -0
- package/bin/langapi-mcp.js +11 -0
- package/dist/api/client.d.ts +24 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +145 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +6 -0
- package/dist/api/types.js.map +1 -0
- package/dist/config/env.d.ts +18 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +29 -0
- package/dist/config/env.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/locale-detection/index.d.ts +41 -0
- package/dist/locale-detection/index.d.ts.map +1 -0
- package/dist/locale-detection/index.js +188 -0
- package/dist/locale-detection/index.js.map +1 -0
- package/dist/locale-detection/patterns.d.ts +21 -0
- package/dist/locale-detection/patterns.d.ts.map +1 -0
- package/dist/locale-detection/patterns.js +135 -0
- package/dist/locale-detection/patterns.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +24 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get-diff.d.ts +23 -0
- package/dist/tools/get-diff.d.ts.map +1 -0
- package/dist/tools/get-diff.js +88 -0
- package/dist/tools/get-diff.js.map +1 -0
- package/dist/tools/get-translation-status.d.ts +47 -0
- package/dist/tools/get-translation-status.d.ts.map +1 -0
- package/dist/tools/get-translation-status.js +176 -0
- package/dist/tools/get-translation-status.js.map +1 -0
- package/dist/tools/list-local-locales.d.ts +39 -0
- package/dist/tools/list-local-locales.d.ts.map +1 -0
- package/dist/tools/list-local-locales.js +52 -0
- package/dist/tools/list-local-locales.js.map +1 -0
- package/dist/tools/sync-translations.d.ts +35 -0
- package/dist/tools/sync-translations.d.ts.map +1 -0
- package/dist/tools/sync-translations.js +629 -0
- package/dist/tools/sync-translations.js.map +1 -0
- package/dist/utils/format-preserve.d.ts +25 -0
- package/dist/utils/format-preserve.d.ts.map +1 -0
- package/dist/utils/format-preserve.js +56 -0
- package/dist/utils/format-preserve.js.map +1 -0
- package/dist/utils/json-parser.d.ts +33 -0
- package/dist/utils/json-parser.d.ts.map +1 -0
- package/dist/utils/json-parser.js +92 -0
- package/dist/utils/json-parser.js.map +1 -0
- package/dist/utils/sync-cache.d.ts +40 -0
- package/dist/utils/sync-cache.d.ts.map +1 -0
- package/dist/utils/sync-cache.js +153 -0
- package/dist/utils/sync-cache.js.map +1 -0
- package/dist/utils/sync-cache.test.d.ts +2 -0
- package/dist/utils/sync-cache.test.d.ts.map +1 -0
- package/dist/utils/sync-cache.test.js +205 -0
- package/dist/utils/sync-cache.test.js.map +1 -0
- package/dist/utils/validation.d.ts +37 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +67 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangAPI client for making API requests
|
|
3
|
+
*/
|
|
4
|
+
import { API_BASE_URL, getApiKey } from "../config/env.js";
|
|
5
|
+
/** Default request timeout in milliseconds (30 seconds) */
|
|
6
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
7
|
+
/**
|
|
8
|
+
* Type guard for SyncDryRunResponse
|
|
9
|
+
*/
|
|
10
|
+
function isSyncDryRunResponse(data) {
|
|
11
|
+
if (typeof data !== "object" || data === null)
|
|
12
|
+
return false;
|
|
13
|
+
const obj = data;
|
|
14
|
+
return (obj.success === true &&
|
|
15
|
+
typeof obj.delta === "object" &&
|
|
16
|
+
obj.delta !== null &&
|
|
17
|
+
typeof obj.cost === "object" &&
|
|
18
|
+
obj.cost !== null &&
|
|
19
|
+
"wordsToTranslate" in obj.cost);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Type guard for SyncExecuteResponse
|
|
23
|
+
*/
|
|
24
|
+
function isSyncExecuteResponse(data) {
|
|
25
|
+
if (typeof data !== "object" || data === null)
|
|
26
|
+
return false;
|
|
27
|
+
const obj = data;
|
|
28
|
+
return (obj.success === true &&
|
|
29
|
+
Array.isArray(obj.results) &&
|
|
30
|
+
typeof obj.cost === "object" &&
|
|
31
|
+
obj.cost !== null &&
|
|
32
|
+
"creditsUsed" in obj.cost);
|
|
33
|
+
}
|
|
34
|
+
export class LangAPIClient {
|
|
35
|
+
apiKey;
|
|
36
|
+
baseUrl;
|
|
37
|
+
timeoutMs;
|
|
38
|
+
constructor(apiKey, baseUrl = API_BASE_URL, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
39
|
+
this.apiKey = apiKey;
|
|
40
|
+
this.baseUrl = baseUrl;
|
|
41
|
+
this.timeoutMs = timeoutMs;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a client instance using the configured API key
|
|
45
|
+
* @throws Error if no API key is configured
|
|
46
|
+
*/
|
|
47
|
+
static create() {
|
|
48
|
+
const apiKey = getApiKey();
|
|
49
|
+
if (!apiKey) {
|
|
50
|
+
throw new Error("No API key configured. Set the LANGAPI_API_KEY environment variable.");
|
|
51
|
+
}
|
|
52
|
+
return new LangAPIClient(apiKey);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if client can be created (API key is configured)
|
|
56
|
+
*/
|
|
57
|
+
static canCreate() {
|
|
58
|
+
return !!getApiKey();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Sync translations with the LangAPI service
|
|
62
|
+
*/
|
|
63
|
+
async sync(request) {
|
|
64
|
+
// Create abort controller for timeout
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
67
|
+
try {
|
|
68
|
+
const response = await fetch(`${this.baseUrl}/api/v1/sync`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify(request),
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
const data = await response.json();
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
// Parse error response safely
|
|
80
|
+
const errorObj = typeof data === "object" && data !== null
|
|
81
|
+
? data
|
|
82
|
+
: {};
|
|
83
|
+
const errorData = typeof errorObj.error === "object" && errorObj.error !== null
|
|
84
|
+
? errorObj.error
|
|
85
|
+
: {};
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: {
|
|
89
|
+
code: typeof errorData.code === "string" ? errorData.code : "API_ERROR",
|
|
90
|
+
message: typeof errorData.message === "string"
|
|
91
|
+
? errorData.message
|
|
92
|
+
: `HTTP ${response.status}`,
|
|
93
|
+
currentBalance: typeof errorData.currentBalance === "number"
|
|
94
|
+
? errorData.currentBalance
|
|
95
|
+
: undefined,
|
|
96
|
+
requiredCredits: typeof errorData.requiredCredits === "number"
|
|
97
|
+
? errorData.requiredCredits
|
|
98
|
+
: undefined,
|
|
99
|
+
topUpUrl: typeof errorData.topUpUrl === "string"
|
|
100
|
+
? errorData.topUpUrl
|
|
101
|
+
: undefined,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Validate successful response using type guards
|
|
106
|
+
if (isSyncDryRunResponse(data)) {
|
|
107
|
+
return data;
|
|
108
|
+
}
|
|
109
|
+
if (isSyncExecuteResponse(data)) {
|
|
110
|
+
return data;
|
|
111
|
+
}
|
|
112
|
+
// Unknown response format
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
error: {
|
|
116
|
+
code: "INVALID_RESPONSE",
|
|
117
|
+
message: "API returned an unexpected response format",
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
// Handle timeout and network errors
|
|
123
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
124
|
+
return {
|
|
125
|
+
success: false,
|
|
126
|
+
error: {
|
|
127
|
+
code: "TIMEOUT",
|
|
128
|
+
message: `Request timed out after ${this.timeoutMs}ms`,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: {
|
|
135
|
+
code: "NETWORK_ERROR",
|
|
136
|
+
message: error instanceof Error ? error.message : "Unknown network error",
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
clearTimeout(timeoutId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API request/response types for LangAPI
|
|
3
|
+
* These types match the langapi-api sync endpoint
|
|
4
|
+
*/
|
|
5
|
+
export interface KeyValue {
|
|
6
|
+
key: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SyncRequest {
|
|
10
|
+
source_lang: string;
|
|
11
|
+
target_langs: string[];
|
|
12
|
+
content: KeyValue[];
|
|
13
|
+
dry_run: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface SyncDelta {
|
|
16
|
+
newKeys: string[];
|
|
17
|
+
changedKeys: string[];
|
|
18
|
+
unchangedKeys: string[];
|
|
19
|
+
totalKeysToSync: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SyncCostEstimate {
|
|
22
|
+
wordsToTranslate: number;
|
|
23
|
+
creditsRequired: number;
|
|
24
|
+
currentBalance: number;
|
|
25
|
+
balanceAfterSync: number;
|
|
26
|
+
}
|
|
27
|
+
export interface SyncDryRunResponse {
|
|
28
|
+
success: true;
|
|
29
|
+
delta: SyncDelta;
|
|
30
|
+
cost: SyncCostEstimate;
|
|
31
|
+
}
|
|
32
|
+
export interface SyncLanguageResult {
|
|
33
|
+
language: string;
|
|
34
|
+
translatedCount: number;
|
|
35
|
+
translations: KeyValue[];
|
|
36
|
+
}
|
|
37
|
+
export interface SyncExecuteResponse {
|
|
38
|
+
success: true;
|
|
39
|
+
results: SyncLanguageResult[];
|
|
40
|
+
cost: {
|
|
41
|
+
creditsUsed: number;
|
|
42
|
+
balanceAfterSync: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface SyncErrorResponse {
|
|
46
|
+
success: false;
|
|
47
|
+
error: {
|
|
48
|
+
code: string;
|
|
49
|
+
message: string;
|
|
50
|
+
currentBalance?: number;
|
|
51
|
+
requiredCredits?: number;
|
|
52
|
+
topUpUrl?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export type SyncResponse = SyncDryRunResponse | SyncExecuteResponse | SyncErrorResponse;
|
|
56
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAGD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAGD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,QAAQ,EAAE,CAAC;CAC1B;AAGD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAGD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAGD,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment variable configuration for LangAPI MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export declare const API_BASE_URL: string;
|
|
5
|
+
/**
|
|
6
|
+
* Get the API key from environment variable
|
|
7
|
+
* @returns The API key or null if not configured
|
|
8
|
+
*/
|
|
9
|
+
export declare function getApiKey(): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Check if the API key is configured
|
|
12
|
+
*/
|
|
13
|
+
export declare function isApiKeyConfigured(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get masked API key for display (shows first 10 and last 4 chars)
|
|
16
|
+
*/
|
|
17
|
+
export declare function getMaskedApiKey(): string | null;
|
|
18
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,YAAY,QACgC,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAK/C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment variable configuration for LangAPI MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export const API_BASE_URL = process.env.LANGAPI_API_URL || "https://api.langapi.io";
|
|
5
|
+
/**
|
|
6
|
+
* Get the API key from environment variable
|
|
7
|
+
* @returns The API key or null if not configured
|
|
8
|
+
*/
|
|
9
|
+
export function getApiKey() {
|
|
10
|
+
return process.env.LANGAPI_API_KEY || null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if the API key is configured
|
|
14
|
+
*/
|
|
15
|
+
export function isApiKeyConfigured() {
|
|
16
|
+
return !!getApiKey();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get masked API key for display (shows first 10 and last 4 chars)
|
|
20
|
+
*/
|
|
21
|
+
export function getMaskedApiKey() {
|
|
22
|
+
const key = getApiKey();
|
|
23
|
+
if (!key)
|
|
24
|
+
return null;
|
|
25
|
+
if (key.length <= 14)
|
|
26
|
+
return "***";
|
|
27
|
+
return `${key.slice(0, 10)}...${key.slice(-4)}`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,YAAY,GACvB,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAClD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* LangAPI MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This MCP server enables AI assistants to manage i18n translations
|
|
6
|
+
* in developer projects via the LangAPI service.
|
|
7
|
+
*
|
|
8
|
+
* Tools available:
|
|
9
|
+
* - list_local_locales: Scan project for locale files
|
|
10
|
+
* - get_translation_status: Compare source vs target locales
|
|
11
|
+
* - sync_translations: Sync translations via LangAPI API
|
|
12
|
+
* - get_diff: Compare source against sync cache for delta detection
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* LangAPI MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This MCP server enables AI assistants to manage i18n translations
|
|
6
|
+
* in developer projects via the LangAPI service.
|
|
7
|
+
*
|
|
8
|
+
* Tools available:
|
|
9
|
+
* - list_local_locales: Scan project for locale files
|
|
10
|
+
* - get_translation_status: Compare source vs target locales
|
|
11
|
+
* - sync_translations: Sync translations via LangAPI API
|
|
12
|
+
* - get_diff: Compare source against sync cache for delta detection
|
|
13
|
+
*/
|
|
14
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
15
|
+
import { createServer } from "./server.js";
|
|
16
|
+
async function main() {
|
|
17
|
+
const server = createServer();
|
|
18
|
+
const transport = new StdioServerTransport();
|
|
19
|
+
await server.connect(transport);
|
|
20
|
+
}
|
|
21
|
+
main().catch((error) => {
|
|
22
|
+
console.error("Failed to start LangAPI MCP server:", error);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locale detection orchestrator
|
|
3
|
+
* Detects i18n framework and locale files in a project
|
|
4
|
+
*/
|
|
5
|
+
export interface LocaleFile {
|
|
6
|
+
/** Absolute path to the file */
|
|
7
|
+
path: string;
|
|
8
|
+
/** Relative path from project root */
|
|
9
|
+
relativePath: string;
|
|
10
|
+
/** Namespace if applicable (from directory name) */
|
|
11
|
+
namespace: string | null;
|
|
12
|
+
/** Number of translation keys */
|
|
13
|
+
keyCount: number;
|
|
14
|
+
}
|
|
15
|
+
export interface DetectedLocale {
|
|
16
|
+
/** Language code */
|
|
17
|
+
lang: string;
|
|
18
|
+
/** Files for this language */
|
|
19
|
+
files: LocaleFile[];
|
|
20
|
+
/** Total key count across all files */
|
|
21
|
+
totalKeys: number;
|
|
22
|
+
}
|
|
23
|
+
export interface LocaleDetectionResult {
|
|
24
|
+
/** Detected framework */
|
|
25
|
+
framework: string;
|
|
26
|
+
/** Confidence level */
|
|
27
|
+
confidence: "high" | "medium" | "low";
|
|
28
|
+
/** Path to locales directory (relative) */
|
|
29
|
+
localesPath: string | null;
|
|
30
|
+
/** Detected source language */
|
|
31
|
+
sourceLang: string | null;
|
|
32
|
+
/** All detected locales */
|
|
33
|
+
locales: DetectedLocale[];
|
|
34
|
+
/** Path to i18n config file if found */
|
|
35
|
+
configFile: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Detect i18n framework and locale files in a project
|
|
39
|
+
*/
|
|
40
|
+
export declare function detectLocales(projectPath: string, includeKeyCount?: boolean): Promise<LocaleDetectionResult>;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locale-detection/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,2CAA2C;IAC3C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+BAA+B;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,2BAA2B;IAC3B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,wCAAwC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,eAAe,UAAO,GACrB,OAAO,CAAC,qBAAqB,CAAC,CAgChC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locale detection orchestrator
|
|
3
|
+
* Detects i18n framework and locale files in a project
|
|
4
|
+
*/
|
|
5
|
+
import { glob } from "glob";
|
|
6
|
+
import { readFile } from "fs/promises";
|
|
7
|
+
import { join, basename, dirname, relative } from "path";
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
|
+
import { FRAMEWORK_PATTERNS, isLikelyLanguageCode, } from "./patterns.js";
|
|
10
|
+
import { countKeys, parseJsonSafe } from "../utils/json-parser.js";
|
|
11
|
+
/**
|
|
12
|
+
* Detect i18n framework and locale files in a project
|
|
13
|
+
*/
|
|
14
|
+
export async function detectLocales(projectPath, includeKeyCount = true) {
|
|
15
|
+
// Try to detect framework from config files
|
|
16
|
+
const { framework, configFile, confidence } = await detectFramework(projectPath);
|
|
17
|
+
// Get the pattern for this framework
|
|
18
|
+
const pattern = FRAMEWORK_PATTERNS[framework] || FRAMEWORK_PATTERNS.generic;
|
|
19
|
+
// Find locale files
|
|
20
|
+
const localeFiles = await findLocaleFiles(projectPath, pattern);
|
|
21
|
+
// Group by language
|
|
22
|
+
const locales = await groupByLanguage(projectPath, localeFiles, includeKeyCount);
|
|
23
|
+
// Determine locales path
|
|
24
|
+
const localesPath = determineLocalesPath(localeFiles, projectPath);
|
|
25
|
+
// Try to detect source language (usually 'en' if present, or first one)
|
|
26
|
+
const sourceLang = locales.find((l) => l.lang === "en")?.lang || locales[0]?.lang || null;
|
|
27
|
+
return {
|
|
28
|
+
framework,
|
|
29
|
+
confidence,
|
|
30
|
+
localesPath,
|
|
31
|
+
sourceLang,
|
|
32
|
+
locales,
|
|
33
|
+
configFile,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Detect the i18n framework from config files
|
|
38
|
+
*/
|
|
39
|
+
async function detectFramework(projectPath) {
|
|
40
|
+
// Check frameworks in order of specificity
|
|
41
|
+
for (const [frameworkName, pattern] of Object.entries(FRAMEWORK_PATTERNS)) {
|
|
42
|
+
if (frameworkName === "generic")
|
|
43
|
+
continue;
|
|
44
|
+
for (const configFile of pattern.configFiles) {
|
|
45
|
+
const fullPath = join(projectPath, configFile);
|
|
46
|
+
if (existsSync(fullPath)) {
|
|
47
|
+
// Read file and check content pattern
|
|
48
|
+
if (pattern.configPattern) {
|
|
49
|
+
try {
|
|
50
|
+
const content = await readFile(fullPath, "utf-8");
|
|
51
|
+
if (pattern.configPattern.test(content)) {
|
|
52
|
+
return {
|
|
53
|
+
framework: frameworkName,
|
|
54
|
+
configFile: configFile,
|
|
55
|
+
confidence: "high",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Ignore read errors
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return {
|
|
65
|
+
framework: frameworkName,
|
|
66
|
+
configFile: configFile,
|
|
67
|
+
confidence: "medium",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Fall back to generic
|
|
74
|
+
return { framework: "generic", configFile: null, confidence: "low" };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Find locale files matching the framework patterns
|
|
78
|
+
*/
|
|
79
|
+
async function findLocaleFiles(projectPath, pattern) {
|
|
80
|
+
const allFiles = [];
|
|
81
|
+
for (const globPattern of pattern.localeGlobs) {
|
|
82
|
+
try {
|
|
83
|
+
const files = await glob(globPattern, {
|
|
84
|
+
cwd: projectPath,
|
|
85
|
+
absolute: true,
|
|
86
|
+
nodir: true,
|
|
87
|
+
});
|
|
88
|
+
allFiles.push(...files);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Ignore glob errors
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Deduplicate
|
|
95
|
+
return [...new Set(allFiles)];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Group locale files by language
|
|
99
|
+
*/
|
|
100
|
+
async function groupByLanguage(projectPath, files, includeKeyCount) {
|
|
101
|
+
const languageMap = new Map();
|
|
102
|
+
for (const filePath of files) {
|
|
103
|
+
const lang = extractLanguageFromPath(filePath);
|
|
104
|
+
if (!lang)
|
|
105
|
+
continue;
|
|
106
|
+
let keyCount = 0;
|
|
107
|
+
if (includeKeyCount) {
|
|
108
|
+
try {
|
|
109
|
+
const content = await readFile(filePath, "utf-8");
|
|
110
|
+
const parsed = parseJsonSafe(content);
|
|
111
|
+
if (parsed) {
|
|
112
|
+
keyCount = countKeys(parsed);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Ignore read errors
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const relativePath = relative(projectPath, filePath);
|
|
120
|
+
const dirName = basename(dirname(filePath));
|
|
121
|
+
const namespace = dirName !== lang && !isLikelyLanguageCode(dirName) ? dirName : null;
|
|
122
|
+
const localeFile = {
|
|
123
|
+
path: filePath,
|
|
124
|
+
relativePath,
|
|
125
|
+
namespace,
|
|
126
|
+
keyCount,
|
|
127
|
+
};
|
|
128
|
+
if (!languageMap.has(lang)) {
|
|
129
|
+
languageMap.set(lang, []);
|
|
130
|
+
}
|
|
131
|
+
languageMap.get(lang).push(localeFile);
|
|
132
|
+
}
|
|
133
|
+
// Convert to array and calculate totals
|
|
134
|
+
return Array.from(languageMap.entries()).map(([lang, files]) => ({
|
|
135
|
+
lang,
|
|
136
|
+
files,
|
|
137
|
+
totalKeys: files.reduce((sum, f) => sum + f.keyCount, 0),
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extract language code from file path
|
|
142
|
+
* Supports patterns like: /locales/en.json, /messages/en/common.json, /public/locales/en/translation.json
|
|
143
|
+
*/
|
|
144
|
+
function extractLanguageFromPath(filePath) {
|
|
145
|
+
const parts = filePath.split("/");
|
|
146
|
+
const fileName = basename(filePath, ".json");
|
|
147
|
+
// Check if filename is a language code (e.g., en.json)
|
|
148
|
+
if (isLikelyLanguageCode(fileName)) {
|
|
149
|
+
return fileName;
|
|
150
|
+
}
|
|
151
|
+
// Check parent directories for language code
|
|
152
|
+
for (let i = parts.length - 2; i >= 0; i--) {
|
|
153
|
+
if (isLikelyLanguageCode(parts[i])) {
|
|
154
|
+
return parts[i];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Determine the common locales directory path
|
|
161
|
+
*/
|
|
162
|
+
function determineLocalesPath(files, projectPath) {
|
|
163
|
+
if (files.length === 0)
|
|
164
|
+
return null;
|
|
165
|
+
// Find common parent directory
|
|
166
|
+
const relativePaths = files.map((f) => relative(projectPath, f));
|
|
167
|
+
if (relativePaths.length === 0)
|
|
168
|
+
return null;
|
|
169
|
+
// Get the first path's directory parts
|
|
170
|
+
const firstDir = dirname(relativePaths[0]).split("/");
|
|
171
|
+
// Find common prefix
|
|
172
|
+
let commonParts = [...firstDir];
|
|
173
|
+
for (const relPath of relativePaths) {
|
|
174
|
+
const parts = dirname(relPath).split("/");
|
|
175
|
+
const newCommon = [];
|
|
176
|
+
for (let i = 0; i < Math.min(commonParts.length, parts.length); i++) {
|
|
177
|
+
if (commonParts[i] === parts[i]) {
|
|
178
|
+
newCommon.push(commonParts[i]);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
commonParts = newCommon;
|
|
185
|
+
}
|
|
186
|
+
return commonParts.length > 0 ? commonParts.join("/") : null;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/locale-detection/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-specific patterns for detecting i18n locale files
|
|
3
|
+
*/
|
|
4
|
+
export interface FrameworkPattern {
|
|
5
|
+
/** Config files that identify this framework */
|
|
6
|
+
configFiles: string[];
|
|
7
|
+
/** Glob patterns for locale files */
|
|
8
|
+
localeGlobs: string[];
|
|
9
|
+
/** Regex pattern to identify framework in config content */
|
|
10
|
+
configPattern?: RegExp;
|
|
11
|
+
}
|
|
12
|
+
export declare const FRAMEWORK_PATTERNS: Record<string, FrameworkPattern>;
|
|
13
|
+
/**
|
|
14
|
+
* Common language codes
|
|
15
|
+
*/
|
|
16
|
+
export declare const COMMON_LANGUAGE_CODES: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Check if a string looks like a language code
|
|
19
|
+
*/
|
|
20
|
+
export declare function isLikelyLanguageCode(str: string): boolean;
|
|
21
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/locale-detection/patterns.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,qCAAqC;IACrC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA+D/D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,UAoDjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOzD"}
|