@ollang-dev/sdk 0.3.1 → 0.3.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/README.md +65 -0
- package/bin/{tms.js → start.js} +6 -6
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +7 -5
- package/dist/tms/server/index.js +15 -16
- package/dist/tms/ui-dist/index.html +2 -2
- package/package.json +4 -3
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @ollang-dev/sdk
|
|
2
|
+
|
|
3
|
+
Official TypeScript/Node.js SDK for the Ollang API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ollang-dev/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import Ollang from '@ollang-dev/sdk';
|
|
15
|
+
|
|
16
|
+
const ollang = new Ollang({
|
|
17
|
+
apiKey: 'your-api-key',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Create a project
|
|
21
|
+
const project = await ollang.projects.create({ name: 'My Project' });
|
|
22
|
+
|
|
23
|
+
// Upload a file
|
|
24
|
+
const upload = await ollang.uploads.upload(project.id, './video.mp4');
|
|
25
|
+
|
|
26
|
+
// Create an order
|
|
27
|
+
const order = await ollang.orders.create({
|
|
28
|
+
projectId: project.id,
|
|
29
|
+
sourceLanguage: 'en',
|
|
30
|
+
targetLanguages: ['fr', 'de', 'es'],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Check order status
|
|
34
|
+
const status = await ollang.orders.get(order.id);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Ollang Translation System
|
|
38
|
+
|
|
39
|
+
Launch the built-in Ollang dashboard to scan and manage translatable content in your project:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @ollang-dev/sdk start
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Resources
|
|
46
|
+
|
|
47
|
+
| Resource | Description |
|
|
48
|
+
| --------------------------- | -------------------------------------- |
|
|
49
|
+
| `ollang.projects` | Create and manage projects |
|
|
50
|
+
| `ollang.uploads` | Upload files (video, audio, documents) |
|
|
51
|
+
| `ollang.orders` | Create and track translation orders |
|
|
52
|
+
| `ollang.revisions` | Request revisions on completed orders |
|
|
53
|
+
| `ollang.customInstructions` | Set custom translation instructions |
|
|
54
|
+
| `ollang.scans` | Scan content for translatable text |
|
|
55
|
+
| `ollang.cms` | CMS integration |
|
|
56
|
+
|
|
57
|
+
## Documentation
|
|
58
|
+
|
|
59
|
+
For comprehensive API documentation, guides, and examples visit:
|
|
60
|
+
|
|
61
|
+
**[https://api-docs.ollang.com](https://api-docs.ollang.com/)**
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
MIT
|
package/bin/{tms.js → start.js}
RENAMED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Translation
|
|
4
|
+
* Ollang Translation System CLI
|
|
5
5
|
*
|
|
6
|
-
* Usage: npx @ollang/sdk
|
|
6
|
+
* Usage: npx @ollang-dev/sdk start
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const { spawn } = require('child_process');
|
|
10
10
|
const path = require('path');
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
|
|
13
|
-
console.log('🚀 Translation
|
|
13
|
+
console.log('🚀 Ollang Translation System starting...\n');
|
|
14
14
|
|
|
15
15
|
const serverPath = path.join(__dirname, '..', 'dist', 'tms', 'server', 'index.js');
|
|
16
16
|
|
|
@@ -29,19 +29,19 @@ const server = spawn('node', [serverPath], {
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
process.on('SIGINT', () => {
|
|
32
|
-
console.log('\n\n👋
|
|
32
|
+
console.log('\n\n👋 Ollang shutting down...');
|
|
33
33
|
server.kill('SIGINT');
|
|
34
34
|
process.exit(0);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
server.on('error', (error) => {
|
|
38
|
-
console.error('❌
|
|
38
|
+
console.error('❌ Failed to start server:', error.message);
|
|
39
39
|
process.exit(1);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
server.on('exit', (code) => {
|
|
43
43
|
if (code !== 0 && code !== null) {
|
|
44
|
-
console.error(`❌ Server
|
|
44
|
+
console.error(`❌ Server closed with error (code: ${code})`);
|
|
45
45
|
process.exit(code);
|
|
46
46
|
}
|
|
47
47
|
});
|
package/dist/browser/index.d.ts
CHANGED
package/dist/browser/index.js
CHANGED
|
@@ -1201,7 +1201,7 @@ class OllangBrowser {
|
|
|
1201
1201
|
</div>
|
|
1202
1202
|
<div id="ollang-strapi-schema-block" style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #e2e8f0;">
|
|
1203
1203
|
<span style="font-size: 11px; font-weight: 500; color: #64748b;">Strapi schema (optional)</span>
|
|
1204
|
-
<p style="margin: 4px 0 8px 0; font-size: 11px; color: #94a3b8;">Fetch schema here so Push uses Content-Type Builder fields. Use your Strapi API token (not the Ollang
|
|
1204
|
+
<p style="margin: 4px 0 8px 0; font-size: 11px; color: #94a3b8;">Fetch schema here so Push uses Content-Type Builder fields. Use your Strapi API token (not the Ollang API token).</p>
|
|
1205
1205
|
<div style="display: flex; flex-direction: column; gap: 6px;">
|
|
1206
1206
|
<input type="text" id="ollang-strapi-url" placeholder="Strapi URL (e.g. https://api.example.com)" style="width: 100%; padding: 6px 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; box-sizing: border-box;" />
|
|
1207
1207
|
<input type="password" id="ollang-strapi-jwt" placeholder="Strapi Admin JWT token" style="width: 100%; padding: 6px 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 12px; box-sizing: border-box;" />
|
|
@@ -1263,7 +1263,9 @@ class OllangBrowser {
|
|
|
1263
1263
|
this.getCmsContent().forEach((c) => this.selectedContentIds.add(c.id));
|
|
1264
1264
|
this.showContent(contentList);
|
|
1265
1265
|
});
|
|
1266
|
-
document
|
|
1266
|
+
document
|
|
1267
|
+
.getElementById('ollang-push-tms')
|
|
1268
|
+
?.addEventListener('click', () => this.pushToOllang());
|
|
1267
1269
|
document
|
|
1268
1270
|
.getElementById('ollang-fetch-schema')
|
|
1269
1271
|
?.addEventListener('click', () => this.fetchStrapiSchemaInPanel());
|
|
@@ -1929,7 +1931,7 @@ class OllangBrowser {
|
|
|
1929
1931
|
async fetchStrapiSchemaInPanel() {
|
|
1930
1932
|
const baseUrl = (this.config.baseUrl || '').replace(/\/$/, '');
|
|
1931
1933
|
if (!baseUrl) {
|
|
1932
|
-
this.showStatus('Missing
|
|
1934
|
+
this.showStatus('Missing Ollang baseUrl', 'error');
|
|
1933
1935
|
return;
|
|
1934
1936
|
}
|
|
1935
1937
|
const urlInput = document.getElementById('ollang-strapi-url');
|
|
@@ -1967,7 +1969,7 @@ class OllangBrowser {
|
|
|
1967
1969
|
btn.disabled = false;
|
|
1968
1970
|
}
|
|
1969
1971
|
}
|
|
1970
|
-
async
|
|
1972
|
+
async pushToOllang() {
|
|
1971
1973
|
if (this.selectedContentIds.size === 0) {
|
|
1972
1974
|
this.showStatus('Please select at least one item', 'error');
|
|
1973
1975
|
return;
|
|
@@ -1977,7 +1979,7 @@ class OllangBrowser {
|
|
|
1977
1979
|
return;
|
|
1978
1980
|
}
|
|
1979
1981
|
if (!this.config.apiKey) {
|
|
1980
|
-
this.showStatus('Please enter
|
|
1982
|
+
this.showStatus('Please enter Ollang API token first', 'error');
|
|
1981
1983
|
return;
|
|
1982
1984
|
}
|
|
1983
1985
|
const baseUrl = (this.config.baseUrl || '').replace(/\/$/, '');
|
package/dist/tms/server/index.js
CHANGED
|
@@ -53,11 +53,11 @@ app.use('/api', (req, res, next) => {
|
|
|
53
53
|
if (!configuredKey)
|
|
54
54
|
return next(); // first-time setup, no key configured yet
|
|
55
55
|
const providedKey = req.headers['x-api-key'] ||
|
|
56
|
-
(req.headers.authorization?.startsWith('Bearer ')
|
|
57
|
-
? req.headers.authorization.slice(7)
|
|
58
|
-
: '');
|
|
56
|
+
(req.headers.authorization?.startsWith('Bearer ') ? req.headers.authorization.slice(7) : '');
|
|
59
57
|
if (providedKey !== configuredKey) {
|
|
60
|
-
return res
|
|
58
|
+
return res
|
|
59
|
+
.status(401)
|
|
60
|
+
.json({ success: false, error: 'Unauthorized: invalid or missing API key' });
|
|
61
61
|
}
|
|
62
62
|
next();
|
|
63
63
|
});
|
|
@@ -88,7 +88,7 @@ async function updateCurrentScan(folderName) {
|
|
|
88
88
|
const state = getOrCreateFolderState(folderName);
|
|
89
89
|
const { currentScanId, texts, videos, images, audios } = state;
|
|
90
90
|
if (!tms) {
|
|
91
|
-
console.warn('⚠️ Cannot update scan:
|
|
91
|
+
console.warn('⚠️ Cannot update scan: Ollang not initialized');
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
try {
|
|
@@ -315,7 +315,7 @@ app.post('/api/config/apikey', async (req, res) => {
|
|
|
315
315
|
tms = await initTMS();
|
|
316
316
|
return res.status(401).json({
|
|
317
317
|
success: false,
|
|
318
|
-
error: 'Invalid
|
|
318
|
+
error: 'Invalid Ollang API key. Please check your token and try again.',
|
|
319
319
|
});
|
|
320
320
|
}
|
|
321
321
|
}
|
|
@@ -349,7 +349,10 @@ app.post('/api/config/update', async (req, res) => {
|
|
|
349
349
|
return res.status(400).json({ success: false, error: 'Invalid target language format' });
|
|
350
350
|
}
|
|
351
351
|
if (!VALID_VIDEO_TYPES.includes(videoTranslationType)) {
|
|
352
|
-
return res.status(400).json({
|
|
352
|
+
return res.status(400).json({
|
|
353
|
+
success: false,
|
|
354
|
+
error: 'Invalid video translation type. Must be aiDubbing or subtitle.',
|
|
355
|
+
});
|
|
353
356
|
}
|
|
354
357
|
process.env.TMS_SOURCE_LANGUAGE = sourceLanguage;
|
|
355
358
|
process.env.TMS_TARGET_LANGUAGES = targetLanguages.join(',');
|
|
@@ -584,7 +587,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
584
587
|
if (!tms) {
|
|
585
588
|
return res.status(400).json({
|
|
586
589
|
success: false,
|
|
587
|
-
error: '
|
|
590
|
+
error: 'Ollang not initialized. Please scan first.',
|
|
588
591
|
});
|
|
589
592
|
}
|
|
590
593
|
const { textIds, targetLanguage, targetLanguages, level, folderName } = req.body;
|
|
@@ -612,7 +615,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
612
615
|
if (sdk && folderName) {
|
|
613
616
|
try {
|
|
614
617
|
console.log(`📂 Loading latest scan for folder: ${folderName}`);
|
|
615
|
-
// Get folderId from
|
|
618
|
+
// Get folderId from Ollang server's /api/folders endpoint
|
|
616
619
|
try {
|
|
617
620
|
const axios = require('axios');
|
|
618
621
|
const foldersResponse = await axios.get('http://localhost:5972/api/folders');
|
|
@@ -909,7 +912,7 @@ app.post('/api/apply', async (req, res) => {
|
|
|
909
912
|
if (!tms) {
|
|
910
913
|
return res.status(400).json({
|
|
911
914
|
success: false,
|
|
912
|
-
error: '
|
|
915
|
+
error: 'Ollang not initialized.',
|
|
913
916
|
});
|
|
914
917
|
}
|
|
915
918
|
const { targetLanguage, textIds, folderName, strapiUrl: reqStrapiUrl, strapiToken: reqStrapiToken, } = req.body;
|
|
@@ -1121,11 +1124,7 @@ function getOllangBackendBase() {
|
|
|
1121
1124
|
backendBase = backendBase.replace(/\/$/, '');
|
|
1122
1125
|
try {
|
|
1123
1126
|
const parsed = new URL(backendBase);
|
|
1124
|
-
const allowedHosts = new Set([
|
|
1125
|
-
'localhost',
|
|
1126
|
-
'127.0.0.1',
|
|
1127
|
-
'api-integration.ollang.com',
|
|
1128
|
-
]);
|
|
1127
|
+
const allowedHosts = new Set(['localhost', '127.0.0.1', 'api-integration.ollang.com']);
|
|
1129
1128
|
const extraHosts = (process.env.OLLANG_ALLOWED_HOSTS || '').split(',').filter(Boolean);
|
|
1130
1129
|
extraHosts.forEach((h) => allowedHosts.add(h.trim()));
|
|
1131
1130
|
if (!allowedHosts.has(parsed.hostname)) {
|
|
@@ -1413,7 +1412,7 @@ app.post('/api/strapi-schema', async (req, res) => {
|
|
|
1413
1412
|
if (!strapiUrl || !strapiToken) {
|
|
1414
1413
|
return res.status(400).json({
|
|
1415
1414
|
success: false,
|
|
1416
|
-
error: 'strapiUrl and strapiToken (Strapi API token) are required. This is not the Ollang
|
|
1415
|
+
error: 'strapiUrl and strapiToken (Strapi API token) are required. This is not the Ollang API token.',
|
|
1417
1416
|
});
|
|
1418
1417
|
}
|
|
1419
1418
|
const base = String(strapiUrl).replace(/\/$/, '');
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>Ollang
|
|
7
|
+
<title>Ollang</title>
|
|
8
8
|
<script type="module" crossorigin src="/assets/index-HvrqZV5Z.js"></script>
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-5U1Hw3uo.css"
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-5U1Hw3uo.css" />
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ollang-dev/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Official TypeScript/Node.js SDK for Ollang API - Translation, Transcription, Dubbing, Closed Captioning, and Translation Management System",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
-
"ollang-
|
|
8
|
+
"ollang-start": "./bin/start.js"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "npm run build:node && npm run build:ui && npm run build:browser",
|
|
28
|
+
"build:ci": "npm run build:node && npm run build:ui:copy",
|
|
28
29
|
"build:node": "tsc",
|
|
29
30
|
"build:ui": "npm run build:ui:react && npm run build:ui:copy",
|
|
30
31
|
"build:ui:react": "cd src/tms/ui-react && npm install && npm run build && cd ../../..",
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
"dev:ui": "cd src/tms/ui-react && npm run dev",
|
|
37
38
|
"dev:browser": "npm run build:browser:watch & npm run watch:copy",
|
|
38
39
|
"watch:copy": "nodemon --watch dist/browser/ollang-browser.min.js --exec 'npm run copy:browser'",
|
|
39
|
-
"prepublishOnly": "npm run build",
|
|
40
|
+
"prepublishOnly": "npm run build:ci",
|
|
40
41
|
"test": "jest",
|
|
41
42
|
"test:tms:local": "npm run build:node && node dist/examples/test-tms-local.js",
|
|
42
43
|
"test:browser": "open examples/browser-cms-integration.html",
|