Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ The different use cases currently available in the package are classified below,
- [Mark As Read](#mark-as-read)
- [Search](#Search)
- [Get Search Services](#get-search-services)
- [External Vocabularies](#external-vocabularies)
- [External Vocabularies read use cases](#external-vocabularies-read-use-cases)
- [Get Configured External Vocabularies](#get-configured-external-vocabularies)
- [Get External Vocabulary Config](#get-external-vocabulary-config)
- [Search External Vocabulary Terms](#search-external-vocabulary-terms)
- [Resolve External Vocabulary Term](#resolve-external-vocabulary-term)
- [Validate External Vocabulary Value](#validate-external-vocabulary-value)
- [External Tools](#external-tools)
- [External Tools read use cases](#external-tools-read-use-cases)
- [Get External Tools](#get-external-tools)
Expand Down Expand Up @@ -3126,6 +3133,98 @@ getSearchServices.execute().then((searchServices: SearchService[]) => {

_See [use case](../src/search/domain/useCases/GetSearchServices.ts) implementation_.

## External Vocabularies

### External Vocabularies Read Use Cases

#### Get Configured External Vocabularies

Returns sanitized external vocabulary configurations derived from the Dataverse `:CVocConf` setting.

##### Example call:

```typescript
import { getConfiguredExternalVocabularies } from '@iqss/dataverse-client-javascript'

getConfiguredExternalVocabularies.execute().then((configs: ExternalVocabularyConfig[]) => {
/* ... */
})
```

_See [use case](../src/externalVocabularies/domain/useCases/GetConfiguredExternalVocabularies.ts) implementation_.

#### Get External Vocabulary Config

Returns the sanitized external vocabulary configuration for a field.

##### Example call:

```typescript
import { getExternalVocabularyConfig } from '@iqss/dataverse-client-javascript'

getExternalVocabularyConfig
.execute('authorAffiliation')
.then((config: ExternalVocabularyConfig) => {
/* ... */
})
```

_See [use case](../src/externalVocabularies/domain/useCases/GetExternalVocabularyConfig.ts) implementation_.

#### Search External Vocabulary Terms

Searches terms for a configured external vocabulary field.

##### Example call:

```typescript
import { searchExternalVocabularyTerms } from '@iqss/dataverse-client-javascript'

searchExternalVocabularyTerms
.execute('authorAffiliation', 'harvard', 'ror', 'en')
.then((terms: ExternalVocabularyTerm[]) => {
/* ... */
})
```

_See [use case](../src/externalVocabularies/domain/useCases/SearchExternalVocabularyTerms.ts) implementation_.

#### Resolve External Vocabulary Term

Resolves a stored external vocabulary URI to its label and mapped metadata.

##### Example call:

```typescript
import { resolveExternalVocabularyTerm } from '@iqss/dataverse-client-javascript'

resolveExternalVocabularyTerm
.execute('authorAffiliation', 'https://ror.org/03vek6s52', 'en')
.then((term: ExternalVocabularyTerm | null) => {
/* ... */
})
```

_See [use case](../src/externalVocabularies/domain/useCases/ResolveExternalVocabularyTerm.ts) implementation_.

#### Validate External Vocabulary Value

Validates a value against the configured vocabulary URI spaces and free-text rules for a field.

##### Example call:

```typescript
import { validateExternalVocabularyValue } from '@iqss/dataverse-client-javascript'

validateExternalVocabularyValue
.execute('authorAffiliation', 'https://ror.org/03vek6s52')
.then((valid: boolean) => {
/* ... */
})
```

_See [use case](../src/externalVocabularies/domain/useCases/ValidateExternalVocabularyValue.ts) implementation_.

## External Tools

### External Tools Read Use Cases
Expand Down
74 changes: 74 additions & 0 deletions src/externalVocabularies/domain/models/ExternalVocabularyConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export type ExternalVocabularyJsonValue =
| string
| number
| boolean
| null
| ExternalVocabularyJsonValue[]
| { [key: string]: ExternalVocabularyJsonValue }

export type ExternalVocabularyPathConfig = string | string[]

export interface ExternalVocabularyConfig {
fieldName: string
termUriField: string
protocol: string
allowFreeText: boolean
languages: string
termParentUri?: string
vocabs: Record<string, ExternalVocabularyVocabConfig>
managedFields: Record<string, string>
provider?: ExternalVocabularyProviderConfig
headers?: Record<string, string>
prefix?: string
'retrieval-uri'?: string
'retrieval-filtering'?: ExternalVocabularyRetrievalFilteringConfig
'search-uri'?: string
'search-url'?: string
'resolve-uri'?: string
'resolve-url'?: string
'results-path'?: string
'resolve-result-path'?: string
'uri-path'?: ExternalVocabularyPathConfig
'label-path'?: ExternalVocabularyPathConfig
'vocabulary-name'?: string
'vocabulary-name-path'?: ExternalVocabularyPathConfig
'vocabulary-uri'?: string
'vocabulary-uri-path'?: ExternalVocabularyPathConfig
limit?: number
}

export interface ExternalVocabularyVocabConfig {
uriSpace: string
vocabularyUri?: string
}

export interface ExternalVocabularyProviderConfig {
type?: 'http-json' | string
'search-uri'?: string
'search-url'?: string
'resolve-uri'?: string
'resolve-url'?: string
'results-path'?: string
'resolve-result-path'?: string
'uri-path'?: ExternalVocabularyPathConfig
'label-path'?: ExternalVocabularyPathConfig
'vocabulary-name'?: string
'vocabulary-name-path'?: ExternalVocabularyPathConfig
'vocabulary-uri'?: string
'vocabulary-uri-path'?: ExternalVocabularyPathConfig
limit?: number
[key: string]: ExternalVocabularyJsonValue | undefined
}

export interface ExternalVocabularyRetrievalFilteringConfig {
'@context'?: Record<string, ExternalVocabularyJsonValue>
[fieldName: string]:
| ExternalVocabularyRetrievalFilterConfig
| Record<string, ExternalVocabularyJsonValue>
| undefined
}

export interface ExternalVocabularyRetrievalFilterConfig {
pattern: string
params?: string[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export interface ExternalVocabularyTerm {
uri: string
label: string
vocabularyName?: string
vocabularyUri?: string
source?: string
mappedFields?: Record<string, unknown>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ExternalVocabularyConfig } from '../models/ExternalVocabularyConfig'
import { ExternalVocabularyTerm } from '../models/ExternalVocabularyTerm'

export interface IExternalVocabulariesRepository {
getConfiguredExternalVocabularies(): Promise<ExternalVocabularyConfig[]>
getExternalVocabularyConfig(fieldName: string): Promise<ExternalVocabularyConfig>
searchExternalVocabularyTerms(
fieldName: string,
query: string,
vocabulary?: string,
language?: string
): Promise<ExternalVocabularyTerm[]>
resolveExternalVocabularyTerm(
fieldName: string,
uri: string,
language?: string
): Promise<ExternalVocabularyTerm | null>
validateExternalVocabularyValue(fieldName: string, value: string): Promise<boolean>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ExternalVocabularyConfig } from '../models/ExternalVocabularyConfig'
import { IExternalVocabulariesRepository } from '../repositories/IExternalVocabulariesRepository'

export class GetConfiguredExternalVocabularies implements UseCase<ExternalVocabularyConfig[]> {
private externalVocabulariesRepository: IExternalVocabulariesRepository

constructor(externalVocabulariesRepository: IExternalVocabulariesRepository) {
this.externalVocabulariesRepository = externalVocabulariesRepository
}

async execute(): Promise<ExternalVocabularyConfig[]> {
return await this.externalVocabulariesRepository.getConfiguredExternalVocabularies()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ExternalVocabularyConfig } from '../models/ExternalVocabularyConfig'
import { IExternalVocabulariesRepository } from '../repositories/IExternalVocabulariesRepository'

export class GetExternalVocabularyConfig implements UseCase<ExternalVocabularyConfig> {
private externalVocabulariesRepository: IExternalVocabulariesRepository

constructor(externalVocabulariesRepository: IExternalVocabulariesRepository) {
this.externalVocabulariesRepository = externalVocabulariesRepository
}

async execute(fieldName: string): Promise<ExternalVocabularyConfig> {
return await this.externalVocabulariesRepository.getExternalVocabularyConfig(fieldName)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ExternalVocabularyTerm } from '../models/ExternalVocabularyTerm'
import { IExternalVocabulariesRepository } from '../repositories/IExternalVocabulariesRepository'

export class ResolveExternalVocabularyTerm implements UseCase<ExternalVocabularyTerm | null> {
private externalVocabulariesRepository: IExternalVocabulariesRepository

constructor(externalVocabulariesRepository: IExternalVocabulariesRepository) {
this.externalVocabulariesRepository = externalVocabulariesRepository
}

async execute(
fieldName: string,
uri: string,
language?: string
): Promise<ExternalVocabularyTerm | null> {
return await this.externalVocabulariesRepository.resolveExternalVocabularyTerm(
fieldName,
uri,
language
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ExternalVocabularyTerm } from '../models/ExternalVocabularyTerm'
import { IExternalVocabulariesRepository } from '../repositories/IExternalVocabulariesRepository'

export class SearchExternalVocabularyTerms implements UseCase<ExternalVocabularyTerm[]> {
private externalVocabulariesRepository: IExternalVocabulariesRepository

constructor(externalVocabulariesRepository: IExternalVocabulariesRepository) {
this.externalVocabulariesRepository = externalVocabulariesRepository
}

async execute(
fieldName: string,
query: string,
vocabulary?: string,
language?: string
): Promise<ExternalVocabularyTerm[]> {
return await this.externalVocabulariesRepository.searchExternalVocabularyTerms(
fieldName,
query,
vocabulary,
language
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { IExternalVocabulariesRepository } from '../repositories/IExternalVocabulariesRepository'

export class ValidateExternalVocabularyValue implements UseCase<boolean> {
private externalVocabulariesRepository: IExternalVocabulariesRepository

constructor(externalVocabulariesRepository: IExternalVocabulariesRepository) {
this.externalVocabulariesRepository = externalVocabulariesRepository
}

async execute(fieldName: string, value: string): Promise<boolean> {
return await this.externalVocabulariesRepository.validateExternalVocabularyValue(
fieldName,
value
)
}
}
33 changes: 33 additions & 0 deletions src/externalVocabularies/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GetConfiguredExternalVocabularies } from './domain/useCases/GetConfiguredExternalVocabularies'
import { GetExternalVocabularyConfig } from './domain/useCases/GetExternalVocabularyConfig'
import { ResolveExternalVocabularyTerm } from './domain/useCases/ResolveExternalVocabularyTerm'
import { SearchExternalVocabularyTerms } from './domain/useCases/SearchExternalVocabularyTerms'
import { ValidateExternalVocabularyValue } from './domain/useCases/ValidateExternalVocabularyValue'
import { ExternalVocabulariesRepository } from './infra/repositories/ExternalVocabulariesRepository'

const externalVocabulariesRepository = new ExternalVocabulariesRepository()

const getConfiguredExternalVocabularies = new GetConfiguredExternalVocabularies(
externalVocabulariesRepository
)
const getExternalVocabularyConfig = new GetExternalVocabularyConfig(externalVocabulariesRepository)
const searchExternalVocabularyTerms = new SearchExternalVocabularyTerms(
externalVocabulariesRepository
)
const resolveExternalVocabularyTerm = new ResolveExternalVocabularyTerm(
externalVocabulariesRepository
)
const validateExternalVocabularyValue = new ValidateExternalVocabularyValue(
externalVocabulariesRepository
)

export {
getConfiguredExternalVocabularies,
getExternalVocabularyConfig,
searchExternalVocabularyTerms,
resolveExternalVocabularyTerm,
validateExternalVocabularyValue
}

export { ExternalVocabularyConfig } from './domain/models/ExternalVocabularyConfig'
export { ExternalVocabularyTerm } from './domain/models/ExternalVocabularyTerm'
Loading
Loading