Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
- Files: Added `getFileCitationByFormat` use case, repository method, and `FileCitationFormat` enum to support Dataverse file citation exports in `EndNote`, `RIS`, `BibTeX`, `CSL`, and `Internal` formats.
- Datasets: Added `getDatasetReviews` use case and repository method to support Dataverse endpoint `GET /datasets/{identifier}/reviews`, for retrieving review datasets associated with a dataset by persistent id or numeric id.
- Datasets: Added `exportDatasetMetadata` use case, repository method, and `ExportedDatasetMetadata` response type to support exporting dataset metadata by numeric id or persistent id through Dataverse endpoint `GET /datasets/export`.
- Datasets: Added `assignRoleOnDataset` and `unassignRoleOnDataset` use cases.
- Collections: Added `allowedDatasetTypes` field to the [Collection](./src/collections/domain/models/Collection.ts) model. This field is optional and only populated the feature is enabled on the installation and configured on the collection.
- Collections: Added theme information when retrieving a collection using `getCollection`.
- Collections: Added `assignRoleOnCollection` and `unassignRoleOnCollection` use cases.

### Changed

Expand Down
90 changes: 90 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ The different use cases currently available in the package are classified below,
- [Update Collection Featured Items](#update-collection-featured-items)
- [Delete Collection Featured Items](#delete-collection-featured-items)
- [Delete a Collection Featured Item](#delete-a-collection-featured-item)
- [Assign a Role on a Collection](#assign-a-role-on-a-collection)
- [Unassign a Role on a Collection](#unassign-a-role-on-a-collection)
- [Templates](#Templates)
- [Templates read use cases](#templates-read-use-cases)
- [Get a Template](#get-a-template)
Expand Down Expand Up @@ -75,6 +77,8 @@ The different use cases currently available in the package are classified below,
- [Link Dataset Type with Metadata Blocks](#link-dataset-type-with-metadata-blocks)
- [Set Available Licenses For Dataset Type](#set-available-licenses-for-dataset-type)
- [Delete a Dataset Type](#delete-a-dataset-type)
- [Assign a Role on a Dataset](#assign-a-role-on-a-dataset)
- [Unassign a Role on a Dataset](#unassign-a-role-on-a-dataset)
- [Files](#Files)
- [Files read use cases](#files-read-use-cases)
- [Get a File](#get-a-file)
Expand Down Expand Up @@ -732,6 +736,49 @@ deleteCollectionFeaturedItem.execute(featuredItemId)

_See [use case](../src/collections/domain/useCases/DeleteCollectionFeaturedItem.ts)_ definition.

#### Assign a Role on a Collection

Assigns a role on a collection, given a collection identifier, a role assignee and a role alias.

##### Example call:

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

/* ... */

const collectionIdOrAlias = 12345
const roleAssignee = "@myUser"
const roleAlias = "curator"

assignRoleOnCollection.execute(collectionIdOrAlias, roleAssignee, roleAlias)

/* ... */
```

_See [use case](../src/collections/domain/useCases/AssignRoleOnCollection.ts)_ definition.

#### Unassign a Role on a Collection

Unassigns a role on a collection, given a collection identifier and a role assignment identifier.

##### Example call:

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

/* ... */

const collectionIdOrAlias = 12345
const roleAssignmentId = 67890

unassignRoleOnCollection.execute(collectionIdOrAlias, roleAssignmentId)

/* ... */
```

_See [use case](../src/collections/domain/useCases/UnassignRoleOnCollection.ts)_ definition.

## Templates

### Templates Read Use Cases
Expand Down Expand Up @@ -1890,6 +1937,49 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetUploadLimits.ts) imple

If the backend does not define any quota limits for the dataset, the returned object can be empty (`{}`).

#### Assign a Role on a Dataset

Assigns a role on a dataset, given a dataset identifier, a role assignee and a role alias.

##### Example call:

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

/* ... */

const datasetId = 1
const roleAssignee = "@myUser"
const roleAlias = "curator"

assignRoleOnDataset.execute(datasetId, roleAssignee, roleAlias)

/* ... */
```

_See [use case](../src/datasets/domain/useCases/AssignRoleOnDataset.ts)_ definition.

#### Unassign a Role on a Dataset

Unassigns a role on a dataset, given a dataset identifier and a role assignment identifier.

##### Example call:

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

/* ... */

const datasetId = 1
const roleAssignmentId = 67890

unassignRoleOnDataset.execute(datasetId, roleAssignmentId)

/* ... */
```

_See [use case](../src/datasets/domain/useCases/UnassignRoleOnDataset.ts)_ definition.

## Files

### Files read use cases
Expand Down
9 changes: 9 additions & 0 deletions src/collections/domain/repositories/ICollectionsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export interface ICollectionsRepository {
getCollectionUserPermissions(
collectionIdOrAlias: number | string
): Promise<CollectionUserPermissions>
assignRoleOnCollection(
collectionIdOrAlias: number | string,
roleAssignee: string,
roleAlias: string
): Promise<void>
unassignRoleOnCollection(
collectionIdOrAlias: number | string,
roleAssignmentId: number
): Promise<void>
getCollectionItems(
collectionId?: string,
limit?: number,
Expand Down
28 changes: 28 additions & 0 deletions src/collections/domain/useCases/AssignRoleOnCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
import { ROOT_COLLECTION_ID } from '../models/Collection'

export class AssignRoleOnCollection implements UseCase<void> {
private collectionsRepository: ICollectionsRepository

constructor(collectionsRepository: ICollectionsRepository) {
this.collectionsRepository = collectionsRepository
}

/**
* Assigns a new role to someone on the given Dataverse collection.
*
* @param {number | string} [collectionIdOrAlias = ':root'] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId)
* If this parameter is not set, the default value is: ':root'
* @param {string} [roleAssignee] - To whom the role should be assigned
* @param {string} [roleAlias] - The alias of the role to be assigned
* @returns {Promise<void>}
*/
async execute(
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID,
roleAssignee: string,
roleAlias: string
): Promise<void> {
return await this.collectionsRepository.assignRoleOnCollection(collectionIdOrAlias, roleAssignee, roleAlias)
}
}
26 changes: 26 additions & 0 deletions src/collections/domain/useCases/UnassignRoleOnCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
import { ROOT_COLLECTION_ID } from '../models/Collection'

export class UnassignRoleOnCollection implements UseCase<void> {
private collectionsRepository: ICollectionsRepository

constructor(collectionsRepository: ICollectionsRepository) {
this.collectionsRepository = collectionsRepository
}

/**
* Deletes the given role assignment on the given Dataverse collection.
*
* @param {number | string} [collectionIdOrAlias = ':root'] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId)
* If this parameter is not set, the default value is: ':root'
* @param {number} [roleAssignmentId] - To numeric identifier of the role assignment
* @returns {Promise<void>}
*/
async execute(
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID,
roleAssignmentId: number
): Promise<void> {
return await this.collectionsRepository.unassignRoleOnCollection(collectionIdOrAlias, roleAssignmentId)
}
}
8 changes: 7 additions & 1 deletion src/collections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { GetCollectionsForLinking } from './domain/useCases/GetCollectionsForLin
import { SetCollectionStorageDriver } from './domain/useCases/SetCollectionStorageDriver'
import { DeleteCollectionStorageDriver } from './domain/useCases/DeleteCollectionStorageDriver'
import { GetAllowedCollectionStorageDrivers } from './domain/useCases/GetAllowedCollectionStorageDrivers'
import { AssignRoleOnCollection } from './domain/useCases/AssignRoleOnCollection'
import { UnassignRoleOnCollection } from './domain/useCases/UnassignRoleOnCollection'

const collectionsRepository = new CollectionsRepository()

Expand All @@ -46,6 +48,8 @@ const deleteCollectionStorageDriver = new DeleteCollectionStorageDriver(collecti
const getAllowedCollectionStorageDrivers = new GetAllowedCollectionStorageDrivers(
collectionsRepository
)
const assignRoleOnCollection = new AssignRoleOnCollection(collectionsRepository)
const unassignRoleOnCollection = new UnassignRoleOnCollection(collectionsRepository)

export {
getCollection,
Expand All @@ -68,7 +72,9 @@ export {
getCollectionsForLinking,
setCollectionStorageDriver,
deleteCollectionStorageDriver,
getAllowedCollectionStorageDrivers
getAllowedCollectionStorageDrivers,
assignRoleOnCollection,
unassignRoleOnCollection
}
export { Collection, CollectionInputLevel, CollectionTheme } from './domain/models/Collection'
export { CollectionFacet } from './domain/models/CollectionFacet'
Expand Down
26 changes: 26 additions & 0 deletions src/collections/infra/repositories/CollectionsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,32 @@ export class CollectionsRepository extends ApiRepository implements ICollections
})
}

public async assignRoleOnCollection(
collectionIdOrAlias: number | string,
roleAssignee: string,
roleAlias: string
): Promise<void> {
return this.doPost(`/${this.collectionsResourceName}/${collectionIdOrAlias}/assignments`, {
assignee: roleAssignee,
role: roleAlias
})
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async unassignRoleOnCollection(
collectionIdOrAlias: number | string,
roleAssignmentId: number
): Promise<void> {
return this.doDelete(`/${this.collectionsResourceName}/${collectionIdOrAlias}/assignments/${roleAssignmentId}`)
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async getCollectionItems(
collectionId?: string,
limit?: number,
Expand Down
9 changes: 9 additions & 0 deletions src/datasets/domain/repositories/IDatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,13 @@ export interface IDatasetsRepository {
getDatasetStorageDriver(datasetId: number | string): Promise<StorageDriver>
getDatasetUploadLimits(datasetId: number | string): Promise<DatasetUploadLimits>
getDatasetReviews(datasetId: number | string): Promise<DatasetReview[]>
assignRoleOnDataset(
datasetId: number | string,
roleAssignee: string,
roleAlias: string
): Promise<void>
unassignRoleOnDataset(
datasetId: number | string,
roleAssignmentId: number
): Promise<void>
}
26 changes: 26 additions & 0 deletions src/datasets/domain/useCases/AssignRoleOnDataset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'

export class AssignRoleOnDataset implements UseCase<void> {
private datasetsRepository: IDatasetsRepository

constructor(datasetsRepository: IDatasetsRepository) {
this.datasetsRepository = datasetsRepository
}

/**
* Assigns a new role to someone on the given dataset.
*
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {string} [roleAssignee] - To whom the role should be assigned
* @param {string} [roleAlias] - The alias of the role to be assigned
* @returns {Promise<void>}
*/
async execute(
datasetId: number | string,
roleAssignee: string,
roleAlias: string
): Promise<void> {
return await this.datasetsRepository.assignRoleOnDataset(datasetId, roleAssignee, roleAlias)
}
}
24 changes: 24 additions & 0 deletions src/datasets/domain/useCases/UnassignRoleOnDataset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'

export class UnassignRoleOnDataset implements UseCase<void> {
private datasetsRepository: IDatasetsRepository

constructor(datasetsRepository: IDatasetsRepository) {
this.datasetsRepository = datasetsRepository
}

/**
* Deletes the given role assignment on the given dataset.
*
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {number} [roleAssignmentId] - To numeric identifier of the role assignment
* @returns {Promise<void>}
*/
async execute(
datasetId: number | string,
roleAssignmentId: number
): Promise<void> {
return await this.datasetsRepository.unassignRoleOnDataset(datasetId, roleAssignmentId)
}
}
8 changes: 7 additions & 1 deletion src/datasets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import { GetDatasetStorageDriver } from './domain/useCases/GetDatasetStorageDriv
import { GetDatasetUploadLimits } from './domain/useCases/GetDatasetUploadLimits'
import { GetDatasetReviews } from './domain/useCases/GetDatasetReviews'
import { ExportDatasetMetadata } from './domain/useCases/ExportDatasetMetadata'
import { AssignRoleOnDataset } from './domain/useCases/AssignRoleOnDataset'
import { UnassignRoleOnDataset } from './domain/useCases/UnassignRoleOnDataset'

const datasetsRepository = new DatasetsRepository()

Expand Down Expand Up @@ -90,6 +92,8 @@ const getDatasetStorageDriver = new GetDatasetStorageDriver(datasetsRepository)
const getDatasetUploadLimits = new GetDatasetUploadLimits(datasetsRepository)
const getDatasetReviews = new GetDatasetReviews(datasetsRepository)
const exportDatasetMetadata = new ExportDatasetMetadata(datasetsRepository)
const assignRoleOnDataset = new AssignRoleOnDataset(datasetsRepository)
const unassignRoleOnDataset = new UnassignRoleOnDataset(datasetsRepository)

export {
getDataset,
Expand Down Expand Up @@ -124,7 +128,9 @@ export {
getDatasetStorageDriver,
getDatasetUploadLimits,
getDatasetReviews,
exportDatasetMetadata
exportDatasetMetadata,
assignRoleOnDataset,
unassignRoleOnDataset
}
export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion'
export { ExportedDatasetMetadata } from './domain/models/ExportedDatasetMetadata'
Expand Down
26 changes: 26 additions & 0 deletions src/datasets/infra/repositories/DatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,30 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi
throw error
})
}

public async assignRoleOnDataset(
datasetId: number | string,
roleAssignee: string,
roleAlias: string
): Promise<void> {
return this.doPost(this.buildApiEndpoint(this.datasetsResourceName, 'assignments', datasetId), {
assignee: roleAssignee,
role: roleAlias
})
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async unassignRoleOnDataset(
datasetId: number | string,
roleAssignmentId: number
): Promise<void> {
return this.doDelete(this.buildApiEndpoint(this.datasetsResourceName, `assignments/${roleAssignmentId}`, datasetId))
.then(() => undefined)
.catch((error) => {
throw error
})
}
}
Loading
Loading