@newpeak/barista-cli 0.2.197 → 0.2.199
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/liberica/courier/status.d.ts.map +1 -1
- package/dist/commands/liberica/courier/status.js.map +1 -1
- package/dist/commands/liberica/courier/uninstall.d.ts.map +1 -1
- package/dist/commands/liberica/courier/uninstall.js.map +1 -1
- package/dist/commands/liberica/files/upload.d.ts.map +1 -1
- package/dist/commands/liberica/files/upload.js +29 -6
- package/dist/commands/liberica/files/upload.js.map +1 -1
- package/dist/commands/skills/index.js +1 -1
- package/dist/commands/skills/index.js.map +1 -1
- package/dist/core/api/client.d.ts +28 -1
- package/dist/core/api/client.d.ts.map +1 -1
- package/dist/core/api/client.js +201 -31
- package/dist/core/api/client.js.map +1 -1
- package/dist/types/file.d.ts +30 -0
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +1 -0
- package/dist/types/file.js.map +1 -1
- package/package.json +1 -1
- package/skills/barista-cli/data/commands.json +1 -1
- package/skills/barista-cli/data/commands.yaml +1 -1
package/dist/core/api/client.js
CHANGED
|
@@ -11505,7 +11505,12 @@ export const apiClient = {
|
|
|
11505
11505
|
return extractApiError(error);
|
|
11506
11506
|
}
|
|
11507
11507
|
},
|
|
11508
|
-
|
|
11508
|
+
/// ========== ChunkedFileController — single file upload ==========
|
|
11509
|
+
/**
|
|
11510
|
+
* Upload a file via ChunkedFileController (/enterprise/files/upload).
|
|
11511
|
+
* X-TENANT-ID is injected by nginx — no client header needed.
|
|
11512
|
+
*/
|
|
11513
|
+
async uploadFileToStorage(environment, tenant, filePath, timeout) {
|
|
11509
11514
|
try {
|
|
11510
11515
|
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11511
11516
|
if (!token)
|
|
@@ -11517,23 +11522,13 @@ export const apiClient = {
|
|
|
11517
11522
|
const FormData = (await import('form-data')).default;
|
|
11518
11523
|
const formData = new FormData();
|
|
11519
11524
|
formData.append('file', createReadStream(filePath), basename(filePath));
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
if (businessData)
|
|
11523
|
-
formData.append('businessData', businessData);
|
|
11524
|
-
if (remark)
|
|
11525
|
-
formData.append('remark', remark);
|
|
11526
|
-
const axiosConfig = {
|
|
11527
|
-
headers: formData.getHeaders(),
|
|
11528
|
-
};
|
|
11529
|
-
if (timeout !== undefined) {
|
|
11525
|
+
const axiosConfig = { headers: formData.getHeaders() };
|
|
11526
|
+
if (timeout !== undefined)
|
|
11530
11527
|
axiosConfig.timeout = timeout;
|
|
11531
|
-
|
|
11532
|
-
const response = await client.getClient().post('/api/enterprise/document/upload', formData, axiosConfig);
|
|
11528
|
+
const response = await client.getClient().post('/api/enterprise/files/upload', formData, axiosConfig);
|
|
11533
11529
|
const body = response.data;
|
|
11534
|
-
if (body && body.code === '00000')
|
|
11530
|
+
if (body && body.code === '00000')
|
|
11535
11531
|
return { success: true, data: body.data };
|
|
11536
|
-
}
|
|
11537
11532
|
return {
|
|
11538
11533
|
success: false,
|
|
11539
11534
|
error: { code: body?.code || 'UNKNOWN', message: JSON.stringify(body?.data) || 'Upload failed' },
|
|
@@ -11543,40 +11538,215 @@ export const apiClient = {
|
|
|
11543
11538
|
return extractApiError(error);
|
|
11544
11539
|
}
|
|
11545
11540
|
},
|
|
11546
|
-
|
|
11541
|
+
/// ========== DocumentController — save document metadata ==========
|
|
11542
|
+
/**
|
|
11543
|
+
* Save a document record associating an uploaded file with a category.
|
|
11544
|
+
* POST /api/enterprise/document/save
|
|
11545
|
+
*/
|
|
11546
|
+
async saveDocument(environment, tenant, params, timeout) {
|
|
11547
11547
|
try {
|
|
11548
11548
|
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11549
11549
|
if (!token)
|
|
11550
11550
|
return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
|
|
11551
11551
|
const client = createAPIClient('liberica', environment, tenant);
|
|
11552
11552
|
client.setAuthToken(token);
|
|
11553
|
-
const
|
|
11554
|
-
|
|
11555
|
-
const FormData = (await import('form-data')).default;
|
|
11556
|
-
const formData = new FormData();
|
|
11557
|
-
formData.append('file', createReadStream(filePath), basename(filePath));
|
|
11558
|
-
formData.append('secretFlag', secretFlag);
|
|
11559
|
-
const axiosConfig = {
|
|
11560
|
-
headers: formData.getHeaders(),
|
|
11553
|
+
const payload = {
|
|
11554
|
+
fileId: params.fileId, fileName: params.fileName, fileSize: params.fileSize,
|
|
11561
11555
|
};
|
|
11562
|
-
if (
|
|
11556
|
+
if (params.fileType)
|
|
11557
|
+
payload.fileType = params.fileType;
|
|
11558
|
+
if (params.categoryCode)
|
|
11559
|
+
payload.categoryCode = params.categoryCode;
|
|
11560
|
+
if (params.businessData)
|
|
11561
|
+
payload.businessData = params.businessData;
|
|
11562
|
+
if (params.remark)
|
|
11563
|
+
payload.remark = params.remark;
|
|
11564
|
+
const axiosConfig = { headers: { 'Content-Type': 'application/json' } };
|
|
11565
|
+
if (timeout !== undefined)
|
|
11563
11566
|
axiosConfig.timeout = timeout;
|
|
11564
|
-
|
|
11565
|
-
const response = await client.getClient().post('/api/sysFileInfo/upload', formData, axiosConfig);
|
|
11567
|
+
const response = await client.getClient().post('/api/enterprise/document/save', payload, axiosConfig);
|
|
11566
11568
|
const body = response.data;
|
|
11567
|
-
|
|
11568
|
-
if (body && body.code === '00000') {
|
|
11569
|
+
if (body && body.code === '00000')
|
|
11569
11570
|
return { success: true, data: body.data };
|
|
11570
|
-
}
|
|
11571
11571
|
return {
|
|
11572
11572
|
success: false,
|
|
11573
|
-
error: { code: body?.code || 'UNKNOWN', message: JSON.stringify(body?.data) || '
|
|
11573
|
+
error: { code: body?.code || 'UNKNOWN', message: JSON.stringify(body?.data) || 'Save document failed' },
|
|
11574
11574
|
};
|
|
11575
11575
|
}
|
|
11576
11576
|
catch (error) {
|
|
11577
11577
|
return extractApiError(error);
|
|
11578
11578
|
}
|
|
11579
11579
|
},
|
|
11580
|
+
/// ========== Two-step document upload (upload file + save document metadata) ==========
|
|
11581
|
+
async uploadDocument(environment, tenant, filePath, categoryCode, businessData, remark, timeout) {
|
|
11582
|
+
const uploadResult = await this.uploadFileToStorage(environment, tenant, filePath, timeout);
|
|
11583
|
+
if (!uploadResult.success)
|
|
11584
|
+
return uploadResult;
|
|
11585
|
+
const { fileId, fileName, fileSize } = uploadResult.data;
|
|
11586
|
+
const fileSuffix = fileName.includes('.') ? fileName.split('.').pop() : undefined;
|
|
11587
|
+
return this.saveDocument(environment, tenant, {
|
|
11588
|
+
fileId, fileName, fileSize, fileType: fileSuffix,
|
|
11589
|
+
categoryCode, businessData, remark,
|
|
11590
|
+
}, timeout);
|
|
11591
|
+
},
|
|
11592
|
+
/// ========== Simple file upload (via ChunkedFileController, backward compat) ==========
|
|
11593
|
+
async uploadSysFile(environment, tenant, filePath, _secretFlag = 'N', timeout) {
|
|
11594
|
+
return this.uploadFileToStorage(environment, tenant, filePath, timeout);
|
|
11595
|
+
},
|
|
11596
|
+
/// ========== Chunked upload ==========
|
|
11597
|
+
async initChunkUpload(environment, tenant, fileName, fileSize, chunkSize) {
|
|
11598
|
+
try {
|
|
11599
|
+
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11600
|
+
if (!token)
|
|
11601
|
+
return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
|
|
11602
|
+
const client = createAPIClient('liberica', environment, tenant);
|
|
11603
|
+
client.setAuthToken(token);
|
|
11604
|
+
const params = new URLSearchParams({ fileName, fileSize: String(fileSize) });
|
|
11605
|
+
if (chunkSize)
|
|
11606
|
+
params.append('chunkSize', String(chunkSize));
|
|
11607
|
+
const response = await client.getClient().post(`/api/enterprise/files/chunk/init?${params.toString()}`, null);
|
|
11608
|
+
const body = response.data;
|
|
11609
|
+
if (body && body.code === '00000')
|
|
11610
|
+
return { success: true, data: body.data };
|
|
11611
|
+
return { success: false, error: { code: body?.code || 'UNKNOWN', message: 'Init chunk upload failed' } };
|
|
11612
|
+
}
|
|
11613
|
+
catch (error) {
|
|
11614
|
+
return extractApiError(error);
|
|
11615
|
+
}
|
|
11616
|
+
},
|
|
11617
|
+
async uploadChunk(environment, tenant, uploadId, index, chunkFilePath, timeout) {
|
|
11618
|
+
try {
|
|
11619
|
+
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11620
|
+
if (!token)
|
|
11621
|
+
return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
|
|
11622
|
+
const client = createAPIClient('liberica', environment, tenant);
|
|
11623
|
+
client.setAuthToken(token);
|
|
11624
|
+
const { createReadStream } = await import('node:fs');
|
|
11625
|
+
const FormData = (await import('form-data')).default;
|
|
11626
|
+
const formData = new FormData();
|
|
11627
|
+
formData.append('uploadId', uploadId);
|
|
11628
|
+
formData.append('index', String(index));
|
|
11629
|
+
formData.append('file', createReadStream(chunkFilePath), `chunk-${index}`);
|
|
11630
|
+
const axiosConfig = { headers: formData.getHeaders() };
|
|
11631
|
+
if (timeout !== undefined)
|
|
11632
|
+
axiosConfig.timeout = timeout;
|
|
11633
|
+
const response = await client.getClient().post('/api/enterprise/files/chunk/upload', formData, axiosConfig);
|
|
11634
|
+
const body = response.data;
|
|
11635
|
+
if (body && body.code === '00000')
|
|
11636
|
+
return { success: true, data: body.data };
|
|
11637
|
+
return { success: false, error: { code: body?.code || 'UNKNOWN', message: 'Chunk upload failed' } };
|
|
11638
|
+
}
|
|
11639
|
+
catch (error) {
|
|
11640
|
+
return extractApiError(error);
|
|
11641
|
+
}
|
|
11642
|
+
},
|
|
11643
|
+
async completeChunkUpload(environment, tenant, uploadId) {
|
|
11644
|
+
try {
|
|
11645
|
+
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11646
|
+
if (!token)
|
|
11647
|
+
return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
|
|
11648
|
+
const client = createAPIClient('liberica', environment, tenant);
|
|
11649
|
+
client.setAuthToken(token);
|
|
11650
|
+
const response = await client.getClient().post(`/api/enterprise/files/chunk/complete?uploadId=${uploadId}`, null);
|
|
11651
|
+
const body = response.data;
|
|
11652
|
+
if (body && body.code === '00000')
|
|
11653
|
+
return { success: true, data: body.data };
|
|
11654
|
+
return { success: false, error: { code: body?.code || 'UNKNOWN', message: 'Complete chunk upload failed' } };
|
|
11655
|
+
}
|
|
11656
|
+
catch (error) {
|
|
11657
|
+
return extractApiError(error);
|
|
11658
|
+
}
|
|
11659
|
+
},
|
|
11660
|
+
async getChunkUploadStatus(environment, tenant, uploadId) {
|
|
11661
|
+
try {
|
|
11662
|
+
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|
|
11663
|
+
if (!token)
|
|
11664
|
+
return { success: false, error: { code: 'NO_TOKEN', message: 'Not logged in' } };
|
|
11665
|
+
const client = createAPIClient('liberica', environment, tenant);
|
|
11666
|
+
client.setAuthToken(token);
|
|
11667
|
+
const response = await client.getClient().get(`/api/enterprise/files/chunk/complete/status?uploadId=${uploadId}`);
|
|
11668
|
+
const body = response.data;
|
|
11669
|
+
if (body && body.code === '00000')
|
|
11670
|
+
return { success: true, data: body.data };
|
|
11671
|
+
return { success: false, error: { code: body?.code || 'UNKNOWN', message: 'Get chunk status failed' } };
|
|
11672
|
+
}
|
|
11673
|
+
catch (error) {
|
|
11674
|
+
return extractApiError(error);
|
|
11675
|
+
}
|
|
11676
|
+
},
|
|
11677
|
+
/**
|
|
11678
|
+
* Complete chunked upload flow: init → upload all chunks → complete → poll until COMPLETED.
|
|
11679
|
+
* Max poll time: 10 minutes (600s).
|
|
11680
|
+
*/
|
|
11681
|
+
async uploadFileChunked(environment, tenant, filePath, timeout) {
|
|
11682
|
+
const { statSync, openSync, readSync, writeFileSync, closeSync, rmSync, mkdtempSync } = await import('node:fs');
|
|
11683
|
+
const { basename, join } = await import('node:path');
|
|
11684
|
+
const { tmpdir } = await import('node:os');
|
|
11685
|
+
const stats = statSync(filePath);
|
|
11686
|
+
const fileName = basename(filePath);
|
|
11687
|
+
const fileSize = stats.size;
|
|
11688
|
+
const chunkSize = 5 * 1024 * 1024;
|
|
11689
|
+
const initResult = await this.initChunkUpload(environment, tenant, fileName, fileSize, chunkSize);
|
|
11690
|
+
if (!initResult.success)
|
|
11691
|
+
return initResult;
|
|
11692
|
+
const { uploadId, chunkCount } = initResult.data;
|
|
11693
|
+
const chunkDir = mkdtempSync(join(tmpdir(), 'barista-chunk-'));
|
|
11694
|
+
try {
|
|
11695
|
+
const fd = openSync(filePath, 'r');
|
|
11696
|
+
const buffer = Buffer.alloc(chunkSize);
|
|
11697
|
+
// Pre-write all chunks to temp files
|
|
11698
|
+
const chunkFiles = [];
|
|
11699
|
+
for (let i = 0; i < chunkCount; i++) {
|
|
11700
|
+
const bytesRead = readSync(fd, buffer, 0, chunkSize, i * chunkSize);
|
|
11701
|
+
const chunkFile = join(chunkDir, `chunk-${i}`);
|
|
11702
|
+
writeFileSync(chunkFile, buffer.subarray(0, bytesRead));
|
|
11703
|
+
chunkFiles.push(chunkFile);
|
|
11704
|
+
}
|
|
11705
|
+
closeSync(fd);
|
|
11706
|
+
// Upload chunks in batches of 3 (like Android OTG_CHUNK_CONCURRENCY)
|
|
11707
|
+
const CONCURRENCY = 3;
|
|
11708
|
+
let chunkError = null;
|
|
11709
|
+
for (let start = 0; start < chunkCount && !chunkError; start += CONCURRENCY) {
|
|
11710
|
+
const end = Math.min(start + CONCURRENCY, chunkCount);
|
|
11711
|
+
const promises = [];
|
|
11712
|
+
for (let i = start; i < end; i++) {
|
|
11713
|
+
const idx = i;
|
|
11714
|
+
promises.push(this.uploadChunk(environment, tenant, uploadId, idx, chunkFiles[idx], timeout)
|
|
11715
|
+
.then((r) => {
|
|
11716
|
+
if (!r.success && !chunkError) {
|
|
11717
|
+
chunkError = `Chunk ${idx + 1}/${chunkCount} upload failed: ${r.error?.message || 'unknown'}`;
|
|
11718
|
+
}
|
|
11719
|
+
}));
|
|
11720
|
+
}
|
|
11721
|
+
await Promise.all(promises);
|
|
11722
|
+
}
|
|
11723
|
+
if (chunkError) {
|
|
11724
|
+
return { success: false, error: { code: 'CHUNK_UPLOAD_FAILED', message: chunkError } };
|
|
11725
|
+
}
|
|
11726
|
+
const completeResult = await this.completeChunkUpload(environment, tenant, uploadId);
|
|
11727
|
+
if (!completeResult.success)
|
|
11728
|
+
return completeResult;
|
|
11729
|
+
const maxAttempts = 60;
|
|
11730
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
11731
|
+
await new Promise(r => setTimeout(r, 10000));
|
|
11732
|
+
const statusResult = await this.getChunkUploadStatus(environment, tenant, uploadId);
|
|
11733
|
+
if (!statusResult.success)
|
|
11734
|
+
continue;
|
|
11735
|
+
const s = statusResult.data;
|
|
11736
|
+
if (s.status === 'COMPLETED')
|
|
11737
|
+
return { success: true, data: { fileId: s.fileId, fileName: s.fileName || fileName, fileSize: s.fileSize || fileSize } };
|
|
11738
|
+
if (s.status === 'FAILED')
|
|
11739
|
+
return { success: false, error: { code: 'CHUNK_UPLOAD_FAILED', message: s.errorMessage || 'Chunk upload failed' } };
|
|
11740
|
+
}
|
|
11741
|
+
return { success: false, error: { code: 'CHUNK_UPLOAD_TIMEOUT', message: 'Chunk upload timed out after 10 minutes' } };
|
|
11742
|
+
}
|
|
11743
|
+
finally {
|
|
11744
|
+
try {
|
|
11745
|
+
rmSync(chunkDir, { recursive: true, force: true });
|
|
11746
|
+
}
|
|
11747
|
+
catch { /* cleanup best-effort */ }
|
|
11748
|
+
}
|
|
11749
|
+
},
|
|
11580
11750
|
async getHrsSkillDefinitions(environment, tenant) {
|
|
11581
11751
|
try {
|
|
11582
11752
|
const token = await tokenManager.getToken({ service: 'liberica', environment, tenant });
|