@intlpullhq/cli 0.1.8 → 0.1.10
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 +4 -0
- package/dist/api-77ZWU4IB.js +47 -0
- package/dist/chunk-BULIQM4U.js +73 -0
- package/dist/{chunk-GQADIM7O.js → chunk-IWYURZV2.js} +11 -2
- package/dist/chunk-KCZQUMQP.js +64 -0
- package/dist/chunk-KIDP7N6D.js +149 -0
- package/dist/chunk-WSY27J6N.js +116 -0
- package/dist/{chunk-2MCKJWPD.js → chunk-WVCVQFBI.js} +340 -305
- package/dist/{config-DX34FMWV.js → config-F3O3XWYX.js} +1 -1
- package/dist/index.js +3144 -195
- package/dist/keys-P3F5IKS2.js +8 -0
- package/dist/projects-AMQMORAR.js +8 -0
- package/dist/translations-7GWEFVRG.js +8 -0
- package/package.json +7 -2
- package/dist/api-K3AY4VAI.js +0 -29
package/README.md
CHANGED
|
@@ -193,6 +193,9 @@ npx @intlpullhq/cli download --format json --output ./messages
|
|
|
193
193
|
# Download specific languages
|
|
194
194
|
npx @intlpullhq/cli download --languages en,es,fr
|
|
195
195
|
|
|
196
|
+
# Download specific namespaces
|
|
197
|
+
npx @intlpullhq/cli download --namespace common,auth
|
|
198
|
+
|
|
196
199
|
# Quiet mode for CI
|
|
197
200
|
npx @intlpullhq/cli download --quiet
|
|
198
201
|
|
|
@@ -207,6 +210,7 @@ npx @intlpullhq/cli pull
|
|
|
207
210
|
| `--format <format>` | Output format: `json`, `yaml`, `ts` (default: `json`) |
|
|
208
211
|
| `--output <dir>` | Output directory (auto-detected from framework) |
|
|
209
212
|
| `--languages <langs>` | Languages to download (comma-separated) |
|
|
213
|
+
| `--namespace <namespaces>` | Namespaces to download (comma-separated, defaults to all) |
|
|
210
214
|
| `--branch <branch>` | Translation branch to download from |
|
|
211
215
|
| `--platform <platform>` | Platform variant: `default`, `ios`, `android`, `web` |
|
|
212
216
|
| `--no-parallel` | Disable parallel fetching |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ApiClient,
|
|
3
|
+
ApiKeysApi,
|
|
4
|
+
BillingApi,
|
|
5
|
+
ContributorsApi,
|
|
6
|
+
DocumentsApi,
|
|
7
|
+
EmailsApi,
|
|
8
|
+
ImportExportApi,
|
|
9
|
+
PLAN_LIMITS,
|
|
10
|
+
SnapshotsApi,
|
|
11
|
+
TMApi,
|
|
12
|
+
WebhooksApi,
|
|
13
|
+
WorkflowsApi,
|
|
14
|
+
createApiClient
|
|
15
|
+
} from "./chunk-WVCVQFBI.js";
|
|
16
|
+
import {
|
|
17
|
+
ProjectsApi
|
|
18
|
+
} from "./chunk-KCZQUMQP.js";
|
|
19
|
+
import {
|
|
20
|
+
TranslationsApi
|
|
21
|
+
} from "./chunk-WSY27J6N.js";
|
|
22
|
+
import {
|
|
23
|
+
KeysApi
|
|
24
|
+
} from "./chunk-BULIQM4U.js";
|
|
25
|
+
import {
|
|
26
|
+
BaseApiClient
|
|
27
|
+
} from "./chunk-KIDP7N6D.js";
|
|
28
|
+
import "./chunk-IWYURZV2.js";
|
|
29
|
+
export {
|
|
30
|
+
ApiClient,
|
|
31
|
+
ApiKeysApi,
|
|
32
|
+
BaseApiClient,
|
|
33
|
+
BillingApi,
|
|
34
|
+
ContributorsApi,
|
|
35
|
+
DocumentsApi,
|
|
36
|
+
EmailsApi,
|
|
37
|
+
ImportExportApi,
|
|
38
|
+
KeysApi,
|
|
39
|
+
PLAN_LIMITS,
|
|
40
|
+
ProjectsApi,
|
|
41
|
+
SnapshotsApi,
|
|
42
|
+
TMApi,
|
|
43
|
+
TranslationsApi,
|
|
44
|
+
WebhooksApi,
|
|
45
|
+
WorkflowsApi,
|
|
46
|
+
createApiClient
|
|
47
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseApiClient
|
|
3
|
+
} from "./chunk-KIDP7N6D.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/api/keys.ts
|
|
6
|
+
var KeysApi = class extends BaseApiClient {
|
|
7
|
+
/**
|
|
8
|
+
* List translation keys for a project
|
|
9
|
+
*/
|
|
10
|
+
async listKeys(projectId, options = {}) {
|
|
11
|
+
const params = new URLSearchParams();
|
|
12
|
+
if (options.namespace) {
|
|
13
|
+
params.append("namespace", options.namespace);
|
|
14
|
+
}
|
|
15
|
+
if (options.search) {
|
|
16
|
+
params.append("search", options.search);
|
|
17
|
+
}
|
|
18
|
+
if (options.tags && options.tags.length > 0) {
|
|
19
|
+
params.append("tags", options.tags.join(","));
|
|
20
|
+
}
|
|
21
|
+
if (options.limit) {
|
|
22
|
+
params.append("limit", options.limit.toString());
|
|
23
|
+
}
|
|
24
|
+
const query = params.toString();
|
|
25
|
+
const endpoint = `/api/v1/projects/${projectId}/keys${query ? `?${query}` : ""}`;
|
|
26
|
+
return this.request(endpoint);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get a specific translation key
|
|
30
|
+
*/
|
|
31
|
+
async getKey(projectId, keyId) {
|
|
32
|
+
return this.request(`/api/v1/projects/${projectId}/keys/${keyId}`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a new translation key
|
|
36
|
+
*/
|
|
37
|
+
async createKey(projectId, data) {
|
|
38
|
+
return this.request(`/api/v1/projects/${projectId}/keys`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
body: JSON.stringify(data)
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Update an existing translation key
|
|
45
|
+
*/
|
|
46
|
+
async updateKey(projectId, keyId, data) {
|
|
47
|
+
return this.request(`/api/v1/projects/${projectId}/keys/${keyId}`, {
|
|
48
|
+
method: "PATCH",
|
|
49
|
+
body: JSON.stringify(data)
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Delete a translation key
|
|
54
|
+
*/
|
|
55
|
+
async deleteKey(projectId, keyId) {
|
|
56
|
+
return this.request(`/api/v1/projects/${projectId}/keys/${keyId}`, {
|
|
57
|
+
method: "DELETE"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Bulk delete translation keys
|
|
62
|
+
*/
|
|
63
|
+
async bulkDeleteKeys(projectId, keyIds) {
|
|
64
|
+
return this.request(`/api/v1/projects/${projectId}/keys/bulk-delete`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
body: JSON.stringify({ key_ids: keyIds })
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
KeysApi
|
|
73
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/lib/config.ts
|
|
2
2
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, chmodSync, renameSync } from "fs";
|
|
3
3
|
import { homedir } from "os";
|
|
4
|
-
import { join, dirname } from "path";
|
|
4
|
+
import { join, dirname, resolve, relative } from "path";
|
|
5
5
|
function writeFileAtomic(filePath, content, options) {
|
|
6
6
|
const dir = dirname(filePath);
|
|
7
7
|
if (options?.createDir && !existsSync(dir)) {
|
|
@@ -331,7 +331,16 @@ function resolveOutputDir(outputDir, projectRoot) {
|
|
|
331
331
|
if (outputDir.startsWith("/") || outputDir.match(/^[A-Z]:\\/i)) {
|
|
332
332
|
return outputDir;
|
|
333
333
|
}
|
|
334
|
-
|
|
334
|
+
const resolvedPath = resolve(projectRoot, outputDir);
|
|
335
|
+
const relativePath = relative(projectRoot, resolvedPath);
|
|
336
|
+
if (relativePath.startsWith("..") || relativePath.includes("/../")) {
|
|
337
|
+
throw new Error(
|
|
338
|
+
`Invalid output directory: path traversal detected. Output directory must be within the project directory.
|
|
339
|
+
Project root: ${projectRoot}
|
|
340
|
+
Attempted path: ${outputDir}`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return resolvedPath;
|
|
335
344
|
}
|
|
336
345
|
function detectGitBranch(dir = process.cwd()) {
|
|
337
346
|
try {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseApiClient
|
|
3
|
+
} from "./chunk-KIDP7N6D.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/api/projects.ts
|
|
6
|
+
var ProjectsApi = class extends BaseApiClient {
|
|
7
|
+
async listProjects() {
|
|
8
|
+
return this.request("/api/v1/projects");
|
|
9
|
+
}
|
|
10
|
+
async getProject(projectId) {
|
|
11
|
+
return this.request(`/api/v1/projects/${projectId}`);
|
|
12
|
+
}
|
|
13
|
+
async createProject(data) {
|
|
14
|
+
return this.request("/api/v1/projects", {
|
|
15
|
+
method: "POST",
|
|
16
|
+
body: JSON.stringify(data)
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Find a project by name (searches through all projects)
|
|
21
|
+
*/
|
|
22
|
+
async findProjectByName(name) {
|
|
23
|
+
const { projects } = await this.listProjects();
|
|
24
|
+
const normalizedName = name.toLowerCase().trim();
|
|
25
|
+
return projects.find(
|
|
26
|
+
(p) => p.name.toLowerCase() === normalizedName || p.slug.toLowerCase() === normalizedName
|
|
27
|
+
) || null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get project languages/settings
|
|
31
|
+
*/
|
|
32
|
+
async getProjectLanguages(projectId) {
|
|
33
|
+
return this.request(`/api/v1/projects/${projectId}/language-settings`);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add multiple languages to a project with optional skip_translation flag
|
|
37
|
+
*/
|
|
38
|
+
async addLanguagesBulk(projectId, languages, skipTranslation = false) {
|
|
39
|
+
return this.request(`/api/v1/projects/${projectId}/language-settings/bulk`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
body: JSON.stringify({
|
|
42
|
+
languages,
|
|
43
|
+
skip_translation: skipTranslation
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Versions
|
|
48
|
+
async listVersions(projectId) {
|
|
49
|
+
return this.request(`/api/v1/projects/${projectId}/versions`);
|
|
50
|
+
}
|
|
51
|
+
async createVersion(projectId, data) {
|
|
52
|
+
return this.request(`/api/v1/projects/${projectId}/versions`, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
body: JSON.stringify(data)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async downloadVersion(projectId, version) {
|
|
58
|
+
return this.requestBlob(`/api/v1/projects/${projectId}/versions/${version}/download`);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
ProjectsApi
|
|
64
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAuthErrorMessage,
|
|
3
|
+
getGlobalConfig,
|
|
4
|
+
getResolvedApiKey
|
|
5
|
+
} from "./chunk-IWYURZV2.js";
|
|
6
|
+
|
|
7
|
+
// src/lib/api/base.ts
|
|
8
|
+
var DEFAULT_API_URL = process.env.INTLPULL_API_URL || "https://api.intlpull.com";
|
|
9
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
10
|
+
var BaseApiClient = class {
|
|
11
|
+
baseUrl;
|
|
12
|
+
apiKey;
|
|
13
|
+
timeout;
|
|
14
|
+
constructor() {
|
|
15
|
+
const globalConfig = getGlobalConfig();
|
|
16
|
+
this.baseUrl = globalConfig.apiUrl || DEFAULT_API_URL;
|
|
17
|
+
const resolved = getResolvedApiKey();
|
|
18
|
+
this.apiKey = resolved?.key || null;
|
|
19
|
+
this.timeout = DEFAULT_TIMEOUT_MS;
|
|
20
|
+
}
|
|
21
|
+
async request(endpoint, options = {}) {
|
|
22
|
+
if (!this.apiKey) {
|
|
23
|
+
throw new Error(getAuthErrorMessage());
|
|
24
|
+
}
|
|
25
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
26
|
+
const headers = {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
"X-API-Key": this.apiKey,
|
|
29
|
+
...options.headers || {}
|
|
30
|
+
};
|
|
31
|
+
const controller = new AbortController();
|
|
32
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
33
|
+
let response;
|
|
34
|
+
try {
|
|
35
|
+
response = await fetch(url, {
|
|
36
|
+
...options,
|
|
37
|
+
headers,
|
|
38
|
+
signal: controller.signal
|
|
39
|
+
});
|
|
40
|
+
} catch (err) {
|
|
41
|
+
clearTimeout(timeoutId);
|
|
42
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
43
|
+
throw new Error(`Request timeout: Server did not respond within ${this.timeout / 1e3}s`);
|
|
44
|
+
}
|
|
45
|
+
if (err instanceof TypeError) {
|
|
46
|
+
throw new Error(`Network error: Unable to connect to ${this.baseUrl}. Check your internet connection.`);
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Request failed: ${err instanceof Error ? err.message : "Unknown network error"}`);
|
|
49
|
+
} finally {
|
|
50
|
+
clearTimeout(timeoutId);
|
|
51
|
+
}
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const error = await response.json().catch(() => ({ error: `Request failed: ${response.status}` }));
|
|
54
|
+
throw new Error(error.error || `Request failed: ${response.status}`);
|
|
55
|
+
}
|
|
56
|
+
const text = await response.text();
|
|
57
|
+
if (!text) {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(text);
|
|
62
|
+
} catch {
|
|
63
|
+
throw new Error(`Invalid JSON response from API`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async requestBlob(endpoint) {
|
|
67
|
+
if (!this.apiKey) {
|
|
68
|
+
throw new Error(getAuthErrorMessage());
|
|
69
|
+
}
|
|
70
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
73
|
+
let response;
|
|
74
|
+
try {
|
|
75
|
+
response = await fetch(url, {
|
|
76
|
+
headers: {
|
|
77
|
+
"X-API-Key": this.apiKey
|
|
78
|
+
},
|
|
79
|
+
signal: controller.signal
|
|
80
|
+
});
|
|
81
|
+
} catch (err) {
|
|
82
|
+
clearTimeout(timeoutId);
|
|
83
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
84
|
+
throw new Error(`Request timeout: Server did not respond within ${this.timeout / 1e3}s`);
|
|
85
|
+
}
|
|
86
|
+
if (err instanceof TypeError) {
|
|
87
|
+
throw new Error(`Network error: Unable to connect to ${this.baseUrl}. Check your internet connection.`);
|
|
88
|
+
}
|
|
89
|
+
throw new Error(`Request failed: ${err instanceof Error ? err.message : "Unknown network error"}`);
|
|
90
|
+
} finally {
|
|
91
|
+
clearTimeout(timeoutId);
|
|
92
|
+
}
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
95
|
+
throw new Error(error.error || "Request failed");
|
|
96
|
+
}
|
|
97
|
+
return response.blob();
|
|
98
|
+
}
|
|
99
|
+
async requestBlobWithJsonFallback(endpoint) {
|
|
100
|
+
if (!this.apiKey) {
|
|
101
|
+
throw new Error(getAuthErrorMessage());
|
|
102
|
+
}
|
|
103
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
106
|
+
let response;
|
|
107
|
+
try {
|
|
108
|
+
response = await fetch(url, {
|
|
109
|
+
headers: {
|
|
110
|
+
"X-API-Key": this.apiKey
|
|
111
|
+
},
|
|
112
|
+
signal: controller.signal
|
|
113
|
+
});
|
|
114
|
+
} catch (err) {
|
|
115
|
+
clearTimeout(timeoutId);
|
|
116
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
117
|
+
throw new Error(`Request timeout: Server did not respond within ${this.timeout / 1e3}s`);
|
|
118
|
+
}
|
|
119
|
+
if (err instanceof TypeError) {
|
|
120
|
+
throw new Error(`Network error: Unable to connect to ${this.baseUrl}. Check your internet connection.`);
|
|
121
|
+
}
|
|
122
|
+
throw new Error(`Request failed: ${err instanceof Error ? err.message : "Unknown network error"}`);
|
|
123
|
+
} finally {
|
|
124
|
+
clearTimeout(timeoutId);
|
|
125
|
+
}
|
|
126
|
+
if (!response.ok) {
|
|
127
|
+
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
128
|
+
throw new Error(error.error || "Request failed");
|
|
129
|
+
}
|
|
130
|
+
const contentType = response.headers.get("content-type") || "";
|
|
131
|
+
if (contentType.includes("application/json")) {
|
|
132
|
+
const jsonData = await response.json();
|
|
133
|
+
if (jsonData.url && typeof jsonData.url === "string") {
|
|
134
|
+
const fileResponse = await fetch(jsonData.url);
|
|
135
|
+
if (!fileResponse.ok) {
|
|
136
|
+
throw new Error(`Failed to download file: ${fileResponse.status}`);
|
|
137
|
+
}
|
|
138
|
+
return fileResponse.blob();
|
|
139
|
+
}
|
|
140
|
+
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
141
|
+
return new Blob([jsonString], { type: "application/json" });
|
|
142
|
+
}
|
|
143
|
+
return response.blob();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
BaseApiClient
|
|
149
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseApiClient
|
|
3
|
+
} from "./chunk-KIDP7N6D.js";
|
|
4
|
+
import {
|
|
5
|
+
getProjectConfig
|
|
6
|
+
} from "./chunk-IWYURZV2.js";
|
|
7
|
+
|
|
8
|
+
// src/lib/api/translations.ts
|
|
9
|
+
var TranslationsApi = class extends BaseApiClient {
|
|
10
|
+
// Keys - uses import endpoint to create/update keys
|
|
11
|
+
async pushKeys(projectId, keys, language = "en", namespace, options) {
|
|
12
|
+
const content = {};
|
|
13
|
+
for (const k of keys) {
|
|
14
|
+
content[k.key] = k.value;
|
|
15
|
+
}
|
|
16
|
+
const fileName = namespace ? `${namespace}.json` : "push.json";
|
|
17
|
+
const result = await this.request(`/api/v1/projects/${projectId}/import`, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
body: JSON.stringify({
|
|
20
|
+
content: JSON.stringify(content),
|
|
21
|
+
file_name: fileName,
|
|
22
|
+
language,
|
|
23
|
+
options: {
|
|
24
|
+
namespace_name: namespace || "common",
|
|
25
|
+
update_existing: true,
|
|
26
|
+
branch_id: options?.branchId,
|
|
27
|
+
platforms: options?.platforms
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
keys_inserted: result.keys_inserted,
|
|
33
|
+
keys_updated: result.keys_updated,
|
|
34
|
+
keys_skipped: result.keys_skipped,
|
|
35
|
+
translations_inserted: result.translations_inserted,
|
|
36
|
+
translations_updated: result.translations_updated
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async getKeys(projectId, namespace) {
|
|
40
|
+
const params = namespace ? `?namespace=${namespace}` : "";
|
|
41
|
+
return this.request(`/api/v1/projects/${projectId}/keys${params}`);
|
|
42
|
+
}
|
|
43
|
+
// Translations - uses export/download endpoint
|
|
44
|
+
async pullTranslations(projectId, options) {
|
|
45
|
+
const params = new URLSearchParams();
|
|
46
|
+
params.set("format", "json");
|
|
47
|
+
if (options.languages?.length) {
|
|
48
|
+
options.languages.forEach((lang) => params.append("languages", lang));
|
|
49
|
+
}
|
|
50
|
+
if (options.branch) {
|
|
51
|
+
params.set("branch", options.branch);
|
|
52
|
+
}
|
|
53
|
+
if (options.platform) {
|
|
54
|
+
params.set("platform", options.platform);
|
|
55
|
+
}
|
|
56
|
+
return this.request(`/api/v1/projects/${projectId}/export/download?${params.toString()}`);
|
|
57
|
+
}
|
|
58
|
+
// Glossary
|
|
59
|
+
async searchGlossary(query, options) {
|
|
60
|
+
const params = new URLSearchParams();
|
|
61
|
+
params.set("q", query);
|
|
62
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
63
|
+
if (options?.language) params.set("language", options.language);
|
|
64
|
+
return this.request(`/api/v1/glossary/search?${params.toString()}`);
|
|
65
|
+
}
|
|
66
|
+
async addGlossaryTerm(data) {
|
|
67
|
+
const config = getProjectConfig();
|
|
68
|
+
if (!config?.projectId) {
|
|
69
|
+
throw new Error("No project configured. Run `npx @intlpullhq/cli init` first.");
|
|
70
|
+
}
|
|
71
|
+
return this.request(`/api/v1/projects/${config.projectId}/glossary`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
body: JSON.stringify(data)
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async exportGlossary(glossaryId) {
|
|
77
|
+
const config = getProjectConfig();
|
|
78
|
+
if (!config?.projectId) {
|
|
79
|
+
throw new Error("No project configured. Run `npx @intlpullhq/cli init` first.");
|
|
80
|
+
}
|
|
81
|
+
const params = glossaryId ? `?glossary_id=${glossaryId}` : "";
|
|
82
|
+
return this.request(`/api/v1/projects/${config.projectId}/glossary/export${params}`);
|
|
83
|
+
}
|
|
84
|
+
// Translation Memory
|
|
85
|
+
async searchTM(data) {
|
|
86
|
+
const config = getProjectConfig();
|
|
87
|
+
if (!config?.projectId) {
|
|
88
|
+
throw new Error("No project configured. Run `npx @intlpullhq/cli init` first.");
|
|
89
|
+
}
|
|
90
|
+
return this.request(`/api/v1/projects/${config.projectId}/memory/search`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
body: JSON.stringify(data)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async addTMEntry(data) {
|
|
96
|
+
const config = getProjectConfig();
|
|
97
|
+
if (!config?.projectId) {
|
|
98
|
+
throw new Error("No project configured. Run `npx @intlpullhq/cli init` first.");
|
|
99
|
+
}
|
|
100
|
+
return this.request(`/api/v1/projects/${config.projectId}/memory`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
body: JSON.stringify(data)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async getTMStats() {
|
|
106
|
+
const config = getProjectConfig();
|
|
107
|
+
if (!config?.projectId) {
|
|
108
|
+
throw new Error("No project configured. Run `npx @intlpullhq/cli init` first.");
|
|
109
|
+
}
|
|
110
|
+
return this.request(`/api/v1/projects/${config.projectId}/memory/stats`);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export {
|
|
115
|
+
TranslationsApi
|
|
116
|
+
};
|