[MNT-25629] Add batch document-runtime endpoint support (#12121)

* [MNT-25629] Add batch document-runtime endpoint support

* [MNT-25629] cr fixes

* [MNT-25629] cr fixes

* [MNT-25629] add tests for api method
This commit is contained in:
Mykyta Maliarchuk
2026-08-07 10:37:57 +02:00
committed by GitHub
parent 33cf47342d
commit 1ab385a3c9
10 changed files with 253 additions and 1 deletions
@@ -27,6 +27,11 @@ import { throwIfNotDefined } from '../../../assert';
* Content service.
*/
export class ContentApi extends BaseApi {
/**
* Maximum number of source document ids accepted by the batch document-runtime endpoint in a single request.
*/
static readonly DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT = 500;
/**
* Attach existing content to a process instance
*
@@ -318,4 +323,34 @@ export class ContentApi extends BaseApi {
}
});
}
/**
* Batch variant of getProcessesAndTasksOnContent. Accepts multiple source document ids
* in one request (up to 500) and returns the related processes and tasks for all of them.
*
* @param sourceIds - ids of the documents to query process participation for (up to 500)
* @param source - source of the documents that workflows or tasks have been started with
* @param size - size of the entries to get
* @param page - page number
* @return Promise<ResultListDataRepresentationRelatedProcessTask>
* @throws {Error} if sourceIds exceeds DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT
*/
getProcessesAndTasksOnContentBatch(
sourceIds: string[],
source: string,
size?: number,
page?: number
): Promise<ResultListDataRepresentationRelatedProcessTask> {
throwIfNotDefined(sourceIds, 'sourceIds');
throwIfNotDefined(source, 'source');
if (sourceIds.length > ContentApi.DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT) {
throw new Error(`sourceIds length exceeds the maximum batch size of ${ContentApi.DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT}`);
}
return this.post({
path: '/api/enterprise/document-runtime',
bodyParam: { sourceIds, source, size, page }
});
}
}
@@ -17,6 +17,7 @@ Method | HTTP request | Description
[**getRelatedContentForProcessInstance**](ContentApi.md#getRelatedContentForProcessInstance) | **GET** /enterprise/process-instances/{processInstanceId}/content | List content attached to a process instance
[**getRelatedContentForTask**](ContentApi.md#getRelatedContentForTask) | **GET** /enterprise/tasks/{taskId}/content | List content attached to a task
[**getProcessesAndTasksOnContent**](ContentApi.md#getProcessesAndTasksOnContent) | **GET** enterprise/content/document-runtime | Lists processes and tasks on workflow started with provided document
[**getProcessesAndTasksOnContentBatch**](ContentApi.md#getProcessesAndTasksOnContentBatch) | **POST** /enterprise/document-runtime | Batch lookup of processes and tasks for multiple source documents
<a name="createRelatedContentOnProcessInstance"></a>
# **createRelatedContentOnProcessInstance**
@@ -530,5 +531,42 @@ contentApi.getProcessesAndTasksOnContent('sourceId', 'source').then((data) => {
[**ResultListDataRepresentationRelatedProcessTask**](ResultListDataRepresentationRelatedProcessTask.md)
<a name="getProcessesAndTasksOnContentBatch"></a>
# **getProcessesAndTasksOnContentBatch**
> ResultListDataRepresentationRelatedProcessTask getProcessesAndTasksOnContentBatch(sourceIds, source, size, page)
Batch variant of getProcessesAndTasksOnContent. Accepts up to 500 source document ids in one request and returns the related processes and tasks for all of them.
### Example
```javascript
import ContentApi from 'ContentApi';
import { AlfrescoApi } from '@alfresco/js-api';
const alfrescoApi = new AlfrescoApi();
alfrescoApi.setConfig({
hostEcm: 'http://127.0.0.1:8080'
});
const contentApi = new ContentApi(alfrescoApi);
contentApi.getProcessesAndTasksOnContentBatch(['id1', 'id2'], 'source').then((data) => {
console.log('API called successfully. Returned data: ' + data);
}, function(error) {
console.error(error);
});
```
### Parameters
| Name | Type | Description | Notes |
|---------------|--------------|-----------------------------------------|----------|
| **sourceIds** | **string[]** | List of source document ids (up to 500) | |
| **source** | **string** | Source repository identifier | |
| **size** | **number** | Page size | optional |
| **page** | **number** | Page number (zero-based) | optional |
### Return type
[**ResultListDataRepresentationRelatedProcessTask**](ResultListDataRepresentationRelatedProcessTask.md)
@@ -5,3 +5,4 @@
| ------------ | ------------- | ------------- | ------------- |
| **processId** | **string** | | [optional] [default to undefined] |
| **taskId** | **string** | | [optional] [default to undefined] |
| **sourceId** | **string** | | [optional] [default to undefined] |
@@ -18,4 +18,5 @@
export interface RelatedProcessTask {
processId?: string;
taskId?: string;
sourceId?: string;
}
+1
View File
@@ -39,6 +39,7 @@ export * from './goverance-services/security-groups.mock';
export * from './goverance-services/security-marks.mock';
export * from './process-services/bpm-auth.mock';
export * from './process-services/content.mock';
export * from './process-services/process.mock';
export * from './process-services/process-instance-variables.mock';
export * from './process-services/models.mock';
@@ -0,0 +1,42 @@
/*!
* @license
* Copyright © 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { BaseMock } from '../base.mock';
export class ContentMock extends BaseMock {
getProcessesAndTasksOnContentBatch200(): void {
this.mock()
.post('/activiti-app/api/enterprise/document-runtime')
.reply(200, {
size: 2,
total: 2,
start: 0,
data: [
{
sourceId: 'node-1;1.0@site1',
processId: '42',
taskId: null
},
{
sourceId: 'node-2;1.0@site1',
processId: null,
taskId: '7'
}
]
});
}
}
@@ -0,0 +1,79 @@
/*!
* @license
* Copyright © 2005-2026 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import assert from 'assert';
import { resetGlobalMockAgent } from '../mockObjects/base.mock';
import { BpmAuthMock, ContentMock } from '../mockObjects';
import { AlfrescoApi, ActivitiContentApi } from '../../src';
import { describe, it, beforeEach, afterEach } from 'node:test';
describe('Activiti Content Api', () => {
let authResponseBpmMock: BpmAuthMock;
let contentMock: ContentMock;
let alfrescoJsApi: AlfrescoApi;
let contentApi: ActivitiContentApi;
const hostBpm = 'https://127.0.0.1:9999';
beforeEach(async () => {
authResponseBpmMock = new BpmAuthMock(hostBpm);
contentMock = new ContentMock(hostBpm);
authResponseBpmMock.get200Response();
alfrescoJsApi = new AlfrescoApi({
hostBpm,
provider: 'BPM'
});
contentApi = new ActivitiContentApi(alfrescoJsApi);
await alfrescoJsApi.login('admin', 'admin');
});
afterEach(() => {
resetGlobalMockAgent();
});
describe('getProcessesAndTasksOnContentBatch', () => {
it('should return related processes and tasks for the given source ids', async () => {
contentMock.getProcessesAndTasksOnContentBatch200();
const result = await contentApi.getProcessesAndTasksOnContentBatch(['node-1;1.0@site1', 'node-2;1.0@site1'], 'alfresco-1-repoAlfresco');
assert.equal(result.size, 2);
assert.equal(result.data[0].sourceId, 'node-1;1.0@site1');
assert.equal(result.data[0].processId, '42');
assert.equal(result.data[1].sourceId, 'node-2;1.0@site1');
});
it('should throw when sourceIds exceeds DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT', () => {
const oversizedIds = Array.from({ length: ActivitiContentApi.DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT + 1 }, (_, i) => `node-${i}`);
assert.throws(
() => contentApi.getProcessesAndTasksOnContentBatch(oversizedIds, 'alfresco-1-repoAlfresco'),
(err: Error) => {
assert.equal(
err.message,
`sourceIds length exceeds the maximum batch size of ${ActivitiContentApi.DOCUMENT_RUNTIME_BATCH_SIZE_LIMIT}`
);
return true;
}
);
});
});
});