Skip to content

Commit d576136

Browse files
committed
feat: external tool use cases
1 parent bfb640a commit d576136

14 files changed

+380
-0
lines changed

docs/useCases.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ The different use cases currently available in the package are classified below,
9393
- [Send Feedback to Object Contacts](#send-feedback-to-object-contacts)
9494
- [Search](#Search)
9595
- [Get Search Services](#get-search-services)
96+
- [External Tools](#external-tools)
97+
- [External Tools read use cases](#external-tools-read-use-cases)
98+
- [Get External Tools](#get-external-tools)
99+
- [Get Dataset External Tool Url](#get-dataset-external-tool-url)
100+
- [Get File External Tool Url](#get-file-external-tool-url)
96101

97102
## Collections
98103

@@ -2142,3 +2147,81 @@ getSearchServices.execute().then((searchServices: SearchService[]) => {
21422147
```
21432148

21442149
_See [use case](../src/search/domain/useCases/GetSearchServices.ts) implementation_.
2150+
2151+
## External Tools
2152+
2153+
### External Tools Read Use Cases
2154+
2155+
#### Get External Tools
2156+
2157+
Returns an array of [ExternalTool](../src/externalTools/domain/models/ExternalTool.ts) objects, which represent the external tools available in the installation.
2158+
2159+
##### Example call:
2160+
2161+
```typescript
2162+
import { getExternalTools } from '@iqss/dataverse-client-javascript'
2163+
2164+
/* ... */
2165+
2166+
getExternalTools.execute().then((externalTools: ExternalTool[]) => {
2167+
/* ... */
2168+
})
2169+
2170+
/* ... */
2171+
```
2172+
2173+
_See [use case](../src/externalTools/domain/useCases/GetExternalTools.ts) implementation_.
2174+
2175+
#### Get Dataset External Tool Url
2176+
2177+
Returns an instance of [DatasetExternalToolUrl](../src/externalTools/domain/models/ExternalTool.ts), which contains the resolved URL for accessing an external tool that operates at the dataset level.
2178+
2179+
##### Example call:
2180+
2181+
```typescript
2182+
import { getDatasetExternalToolUrl } from '@iqss/dataverse-client-javascript'
2183+
2184+
/* ... */
2185+
const toolId = 1
2186+
const datasetId = 2
2187+
const getExternalToolDTO: GetExternalToolDTO = {
2188+
preview: true,
2189+
locale: 'en'
2190+
}
2191+
2192+
getDatasetExternalToolUrl
2193+
.execute(toolId, datasetId, getExternalToolDTO)
2194+
.then((datasetExternalToolUrl: DatasetExternalToolUrl) => {
2195+
/* ... */
2196+
})
2197+
/* ... */
2198+
```
2199+
2200+
_See [use case](../src/externalTools/domain/useCases/GetDatasetExternalToolUrl.ts) implementation_.
2201+
2202+
#### Get File External Tool Url
2203+
2204+
Returns an instance of [FileExternalToolUrl](../src/externalTools/domain/models/ExternalTool.ts), which contains the resolved URL for accessing an external tool that operates at the file level.
2205+
2206+
##### Example call:
2207+
2208+
```typescript
2209+
import { getFileExternalToolUrl } from '@iqss/dataverse-client-javascript'
2210+
2211+
/* ... */
2212+
const toolId = 1
2213+
const fileId = 2
2214+
const getExternalToolDTO: GetExternalToolDTO = {
2215+
preview: true,
2216+
locale: 'en'
2217+
}
2218+
2219+
getFileExternalToolUrl
2220+
.execute(toolId, fileId, getExternalToolDTO)
2221+
.then((fileExternalToolUrl: FileExternalToolUrl) => {
2222+
/* ... */
2223+
})
2224+
/* ... */
2225+
```
2226+
2227+
_See [use case](../src/externalTools/domain/useCases/GetfileExternalToolUrl.ts) implementation_.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @property {boolean} preview - boolean flag to indicate if the request is for previewing the tool or not.
3+
* @property {string} locale - string specifying the locale for internationalization
4+
*/
5+
6+
export interface GetExternalToolDTO {
7+
preview: boolean
8+
locale: string
9+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export interface ExternalTool {
2+
id: number
3+
displayName: string
4+
description: string
5+
types: ToolType[]
6+
scope: ToolScope
7+
}
8+
9+
export enum ToolType {
10+
Explore = 'explore',
11+
Configure = 'configure',
12+
Preview = 'preview',
13+
Query = 'query'
14+
}
15+
16+
export enum ToolScope {
17+
Dataset = 'dataset',
18+
File = 'file'
19+
}
20+
21+
export interface DatasetExternalToolUrl {
22+
toolUrlResolved: string
23+
displayName: string
24+
datasetId: number
25+
preview: boolean
26+
}
27+
28+
export interface FileExternalToolUrl {
29+
toolUrlResolved: string
30+
displayName: string
31+
fileId: number
32+
preview: boolean
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { GetExternalToolDTO } from '../dtos/GetExternalToolDTO'
2+
import { DatasetExternalToolUrl, ExternalTool, FileExternalToolUrl } from '../models/ExternalTool'
3+
4+
export interface IExternalToolsRepository {
5+
getExternalTools(): Promise<ExternalTool[]>
6+
getDatasetExternalToolUrl(
7+
datasetId: number | string,
8+
toolId: number,
9+
getExternalToolDTO: GetExternalToolDTO
10+
): Promise<DatasetExternalToolUrl>
11+
getFileExternalToolUrl(
12+
fileId: number | string,
13+
toolId: number,
14+
getExternalToolDTO: GetExternalToolDTO
15+
): Promise<FileExternalToolUrl>
16+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { GetExternalToolDTO } from '../dtos/GetExternalToolDTO'
3+
import { DatasetExternalToolUrl } from '../models/ExternalTool'
4+
import { IExternalToolsRepository } from '../repositories/IExternalToolsRepository'
5+
6+
export class GetDatasetExternalToolUrl implements UseCase<DatasetExternalToolUrl> {
7+
private externalToolsRepository: IExternalToolsRepository
8+
9+
constructor(externalToolsRepository: IExternalToolsRepository) {
10+
this.externalToolsRepository = externalToolsRepository
11+
}
12+
13+
/**
14+
* Returns a DatasetExternalToolUrl object containing the resolved URL for accessing an external tool that operates at the dataset level.
15+
* The URL includes necessary authentication tokens and parameters based on the user's permissions and the tool's configuration.
16+
* Authentication is required for draft or deaccessioned datasets and the user must have ViewUnpublishedDataset permission.
17+
*
18+
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
19+
* @param {number} toolId - The identifier of the external tool.
20+
* @param {GetExternalToolDTO} getExternalToolDTO - The GetExternalToolDTO object containing additional parameters for the request.
21+
* @returns {Promise<DatasetExternalToolUrl>}
22+
*/
23+
async execute(
24+
datasetId: number | string,
25+
toolId: number,
26+
getExternalToolDTO: GetExternalToolDTO
27+
): Promise<DatasetExternalToolUrl> {
28+
return await this.externalToolsRepository.getDatasetExternalToolUrl(
29+
datasetId,
30+
toolId,
31+
getExternalToolDTO
32+
)
33+
}
34+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ExternalTool } from '../models/ExternalTool'
3+
import { IExternalToolsRepository } from '../repositories/IExternalToolsRepository'
4+
5+
export class GetExternalTools implements UseCase<ExternalTool[]> {
6+
private externalToolsRepository: IExternalToolsRepository
7+
8+
constructor(externalToolsRepository: IExternalToolsRepository) {
9+
this.externalToolsRepository = externalToolsRepository
10+
}
11+
12+
/**
13+
* Returns a list containing all the external tools available in the installation.
14+
*
15+
* @returns {Promise<ExternalTool[]>}
16+
*/
17+
async execute(): Promise<ExternalTool[]> {
18+
return await this.externalToolsRepository.getExternalTools()
19+
}
20+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { GetExternalToolDTO } from '../dtos/GetExternalToolDTO'
3+
import { FileExternalToolUrl } from '../models/ExternalTool'
4+
import { IExternalToolsRepository } from '../repositories/IExternalToolsRepository'
5+
6+
export class GetFileExternalToolUrl implements UseCase<FileExternalToolUrl> {
7+
private externalToolsRepository: IExternalToolsRepository
8+
9+
constructor(externalToolsRepository: IExternalToolsRepository) {
10+
this.externalToolsRepository = externalToolsRepository
11+
}
12+
13+
/**
14+
* Returns a FileExternalToolUrl object containing the resolved URL for accessing an external tool that operates at the file level.
15+
* The URL includes necessary authentication tokens and parameters based on the user's permissions and the tool's configuration.
16+
* Authentication is required for draft, restricted, embargoed, or expired (retention period) files, the user must have appropriate permissions.
17+
*
18+
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
19+
* @param {number} toolId - The identifier of the external tool.
20+
* @param {GetExternalToolDTO} getExternalToolDTO - The GetExternalToolDTO object containing additional parameters for the request.
21+
* @returns {Promise<FileExternalToolUrl>}
22+
*/
23+
async execute(
24+
fileId: number | string,
25+
toolId: number,
26+
getExternalToolDTO: GetExternalToolDTO
27+
): Promise<FileExternalToolUrl> {
28+
return await this.externalToolsRepository.getFileExternalToolUrl(
29+
fileId,
30+
toolId,
31+
getExternalToolDTO
32+
)
33+
}
34+
}

src/externalTools/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { GetDatasetExternalToolUrl } from './domain/useCases/GetDatasetExternalToolUrl'
2+
import { GetExternalTools } from './domain/useCases/GetExternalTools'
3+
import { GetFileExternalToolUrl } from './domain/useCases/GetFileExternalToolUrl'
4+
import { ExternalToolsRepository } from './infra/ExternalToolsRepository'
5+
6+
const externalToolsRepository = new ExternalToolsRepository()
7+
8+
const getExternalTools = new GetExternalTools(externalToolsRepository)
9+
const getDatasetExternalToolUrl = new GetDatasetExternalToolUrl(externalToolsRepository)
10+
const getFileExternalToolUrl = new GetFileExternalToolUrl(externalToolsRepository)
11+
12+
export {
13+
getExternalTools,
14+
getDatasetExternalToolUrl,
15+
getFileExternalToolUrl,
16+
externalToolsRepository
17+
}
18+
19+
export {
20+
ExternalTool,
21+
ToolScope,
22+
ToolType,
23+
DatasetExternalToolUrl,
24+
FileExternalToolUrl
25+
} from './domain/models/ExternalTool'
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { IExternalToolsRepository } from '../domain/repositories/IExternalToolsRepository'
2+
import { ApiRepository } from '../../core/infra/repositories/ApiRepository'
3+
import {
4+
DatasetExternalToolUrl,
5+
ExternalTool,
6+
FileExternalToolUrl
7+
} from '../domain/models/ExternalTool'
8+
import { GetExternalToolDTO } from '../domain/dtos/GetExternalToolDTO'
9+
import { datasetExternalToolTransformer } from './transformers/datasetExternalToolTransformer'
10+
import { fileExternalToolTransformer } from './transformers/fileExternalToolTransformer'
11+
import { externalToolsTransformer } from './transformers/externalToolsTransformer'
12+
13+
export class ExternalToolsRepository extends ApiRepository implements IExternalToolsRepository {
14+
private readonly externalToolsResourceName: string = 'externalTools'
15+
16+
public async getExternalTools(): Promise<ExternalTool[]> {
17+
return this.doGet(this.buildApiEndpoint(this.externalToolsResourceName))
18+
.then((response) => externalToolsTransformer(response))
19+
.catch((error) => {
20+
throw error
21+
})
22+
}
23+
24+
public async getDatasetExternalToolUrl(
25+
datasetId: number | string,
26+
toolId: number,
27+
getExternalToolDTO: GetExternalToolDTO
28+
): Promise<DatasetExternalToolUrl> {
29+
return this.doPost(
30+
this.buildApiEndpoint('datasets', `externalTool/${toolId}/toolUrl`, datasetId),
31+
getExternalToolDTO
32+
)
33+
.then((response) => datasetExternalToolTransformer(response))
34+
.catch((error) => {
35+
throw error
36+
})
37+
}
38+
39+
public async getFileExternalToolUrl(
40+
fileId: number | string,
41+
toolId: number,
42+
getExternalToolDTO: GetExternalToolDTO
43+
): Promise<FileExternalToolUrl> {
44+
return this.doPost(
45+
this.buildApiEndpoint('files', `externalTool/${toolId}/toolUrl`, fileId),
46+
getExternalToolDTO
47+
)
48+
.then((response) => fileExternalToolTransformer(response))
49+
.catch((error) => {
50+
throw error
51+
})
52+
}
53+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export interface ExternalToolPayload {
2+
id: number
3+
displayName: string
4+
description: string
5+
types: ToolTypePayload[]
6+
scope: ToolScopePayload
7+
}
8+
9+
enum ToolTypePayload {
10+
Explore = 'explore',
11+
Configure = 'configure',
12+
Preview = 'preview',
13+
Query = 'query'
14+
}
15+
16+
enum ToolScopePayload {
17+
Dataset = 'dataset',
18+
File = 'file'
19+
}

0 commit comments

Comments
 (0)