Skip to content

Commit 3af3878

Browse files
committed
Merge branch 'develop' into feat/get-collection-theme
# Conflicts: # test/unit/collections/CollectionsRepository.test.ts
2 parents 979772e + a16321b commit 3af3878

27 files changed

Lines changed: 793 additions & 15 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
4444
- Templates: Rename `CreateDatasetTemplateDTO` to `CreateTemplateDTO`.
4545
- Templates: Rename `createDatasetTemplate` repository method to `createTemplate`.
4646
- Templates: Rename `getDatasetTemplates` repository method to `getTemplatesByCollectionId`.
47+
- Collections: `updateCollection` now supports partial updates by accepting `Partial<CollectionDTO>`. Only explicitly provided fields are sent in update requests, aligning with Dataverse API semantics. Metadata blocks handling was adjusted to respect inheritance flags and avoid invalid field combinations.
4748

4849
### Fixed
4950

docs/useCases.md

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ The different use cases currently available in the package are classified below,
1111
- [Collections](#Collections)
1212
- [Collections read use cases](#collections-read-use-cases)
1313
- [Get a Collection](#get-a-collection)
14+
- [Get Collection Storage Driver](#get-collection-storage-driver)
15+
- [Get Allowed Collection Storage Drivers](#get-allowed-collection-storage-drivers)
1416
- [Get Collection Facets](#get-collection-facets)
1517
- [Get User Permissions on a Collection](#get-user-permissions-on-a-collection)
1618
- [List All Collection Items](#list-all-collection-items)
@@ -19,6 +21,8 @@ The different use cases currently available in the package are classified below,
1921
- [Get Collections for Linking](#get-collections-for-linking)
2022
- [Collections write use cases](#collections-write-use-cases)
2123
- [Create a Collection](#create-a-collection)
24+
- [Set Collection Storage Driver](#set-collection-storage-driver)
25+
- [Delete Collection Storage Driver](#delete-collection-storage-driver)
2226
- [Update a Collection](#update-a-collection)
2327
- [Publish a Collection](#publish-a-collection)
2428
- [Delete a Collection](#delete-a-collection)
@@ -190,6 +194,65 @@ The `collectionIdOrAlias` is a generic collection identifier, which can be eithe
190194

191195
If no collection identifier is specified, the default collection identifier; `:root` will be used. If you want to search for a different collection, you must add the collection identifier as a parameter in the use case call.
192196

197+
#### Get Collection Storage Driver
198+
199+
Returns a [StorageDriver](../src/core/domain/models/StorageDriver.ts) instance describing the collection's assigned storage driver.
200+
201+
##### Example call:
202+
203+
```typescript
204+
import { getCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
205+
206+
/* ... */
207+
208+
const collectionIdOrAlias = 'classicLiterature'
209+
210+
getCollectionStorageDriver.execute(collectionIdOrAlias).then((storageDriver: StorageDriver) => {
211+
/* ... */
212+
})
213+
214+
// Pass true to resolve the effective driver after inheritance/default fallback
215+
getCollectionStorageDriver
216+
.execute(collectionIdOrAlias, true)
217+
.then((storageDriver: StorageDriver) => {
218+
/* ... */
219+
})
220+
221+
/* ... */
222+
```
223+
224+
_See [use case](../src/collections/domain/useCases/GetCollectionStorageDriver.ts) implementation_.
225+
226+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
227+
228+
The optional `getEffective` parameter defaults to `false`. Set it to `true` to retrieve the effective storage driver after inheritance/default resolution.
229+
230+
#### Get Allowed Collection Storage Drivers
231+
232+
Returns an [AllowedStorageDrivers](../src/collections/domain/models/AllowedStorageDrivers.ts) object whose keys are driver labels and whose values are storage driver ids.
233+
234+
##### Example call:
235+
236+
```typescript
237+
import { getAllowedCollectionStorageDrivers } from '@iqss/dataverse-client-javascript'
238+
239+
/* ... */
240+
241+
const collectionIdOrAlias = 'classicLiterature'
242+
243+
getAllowedCollectionStorageDrivers
244+
.execute(collectionIdOrAlias)
245+
.then((storageDrivers: AllowedStorageDrivers) => {
246+
/* ... */
247+
})
248+
249+
/* ... */
250+
```
251+
252+
_See [use case](../src/collections/domain/useCases/GetAllowedCollectionStorageDrivers.ts) implementation_.
253+
254+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
255+
193256
#### Get Collection Facets
194257

195258
Returns a [CollectionFacet](../src/collections/domain/models/CollectionFacet.ts) array containing the facets of the requested collection, given the collection identifier or alias.
@@ -460,6 +523,57 @@ The above example creates the new collection in the root collection since no col
460523

461524
The use case returns a number, which is the identifier of the created collection.
462525

526+
#### Set Collection Storage Driver
527+
528+
Assigns a storage driver to a collection by driver label and returns the backend success message.
529+
530+
##### Example call:
531+
532+
```typescript
533+
import { setCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
534+
535+
/* ... */
536+
537+
const collectionIdOrAlias = 'classicLiterature'
538+
const driverLabel = 'Local Storage'
539+
540+
setCollectionStorageDriver.execute(collectionIdOrAlias, driverLabel).then((message: string) => {
541+
/* ... */
542+
})
543+
544+
/* ... */
545+
```
546+
547+
_See [use case](../src/collections/domain/useCases/SetCollectionStorageDriver.ts) implementation_.
548+
549+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
550+
551+
The `driverLabel` parameter must match the storage driver's label, not its id.
552+
553+
#### Delete Collection Storage Driver
554+
555+
Clears the directly assigned storage driver from a collection so it falls back to inherited/default storage, and returns the backend success message.
556+
557+
##### Example call:
558+
559+
```typescript
560+
import { deleteCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
561+
562+
/* ... */
563+
564+
const collectionIdOrAlias = 'classicLiterature'
565+
566+
deleteCollectionStorageDriver.execute(collectionIdOrAlias).then((message: string) => {
567+
/* ... */
568+
})
569+
570+
/* ... */
571+
```
572+
573+
_See [use case](../src/collections/domain/useCases/DeleteCollectionStorageDriver.ts) implementation_.
574+
575+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
576+
463577
#### Update a Collection
464578

465579
Updates an existing collection, given a collection identifier and a [CollectionDTO](../src/collections/domain/dtos/CollectionDTO.ts) including the updated collection data.
@@ -1491,7 +1605,7 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetTemplates.ts)_ definit
14911605

14921606
#### Get Dataset Storage Driver
14931607

1494-
Returns a [StorageDriver](../src/datasets/domain/models/StorageDriver.ts) instance with storage driver configuration for a dataset, including properties like name, type, label, and upload/download capabilities.
1608+
Returns a [StorageDriver](../src/core/domain/models/StorageDriver.ts) instance with storage driver configuration for a dataset, including properties like name, type, label, and upload/download capabilities.
14951609

14961610
##### Example call:
14971611

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type AllowedStorageDrivers = Record<string, string>

src/collections/domain/repositories/ICollectionsRepository.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,24 @@ import { PublicationStatus } from '../../../core/domain/models/PublicationStatus
1111
import { CollectionItemType } from '../../../collections/domain/models/CollectionItemType'
1212
import { CollectionLinks } from '../models/CollectionLinks'
1313
import { CollectionSummary } from '../models/CollectionSummary'
14+
import { AllowedStorageDrivers } from '../models/AllowedStorageDrivers'
15+
import { StorageDriver } from '../../../core/domain/models/StorageDriver'
1416
import { LinkingObjectType } from '../useCases/GetCollectionsForLinking'
1517

1618
export interface ICollectionsRepository {
1719
getCollection(collectionIdOrAlias: number | string): Promise<Collection>
20+
getCollectionStorageDriver(
21+
collectionIdOrAlias: number | string,
22+
getEffective?: boolean
23+
): Promise<StorageDriver>
24+
setCollectionStorageDriver(
25+
collectionIdOrAlias: number | string,
26+
driverLabel: string
27+
): Promise<string>
28+
deleteCollectionStorageDriver(collectionIdOrAlias: number | string): Promise<string>
29+
getAllowedCollectionStorageDrivers(
30+
collectionIdOrAlias: number | string
31+
): Promise<AllowedStorageDrivers>
1832
createCollection(
1933
collectionDTO: CollectionDTO,
2034
parentCollectionId: number | string
@@ -44,7 +58,7 @@ export interface ICollectionsRepository {
4458
): Promise<MyDataCollectionItemSubset>
4559
updateCollection(
4660
collectionIdOrAlias: number | string,
47-
updatedCollection: CollectionDTO
61+
updatedCollection: Partial<CollectionDTO>
4862
): Promise<void>
4963
getCollectionFeaturedItems(collectionIdOrAlias: number | string): Promise<FeaturedItem[]>
5064
updateCollectionFeaturedItems(
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
4+
export class DeleteCollectionStorageDriver implements UseCase<string> {
5+
private collectionsRepository: ICollectionsRepository
6+
7+
constructor(collectionsRepository: ICollectionsRepository) {
8+
this.collectionsRepository = collectionsRepository
9+
}
10+
11+
async execute(collectionIdOrAlias: number | string): Promise<string> {
12+
return this.collectionsRepository.deleteCollectionStorageDriver(collectionIdOrAlias)
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
import { AllowedStorageDrivers } from '../models/AllowedStorageDrivers'
4+
5+
export class GetAllowedCollectionStorageDrivers implements UseCase<AllowedStorageDrivers> {
6+
private collectionsRepository: ICollectionsRepository
7+
8+
constructor(collectionsRepository: ICollectionsRepository) {
9+
this.collectionsRepository = collectionsRepository
10+
}
11+
12+
async execute(collectionIdOrAlias: number | string): Promise<AllowedStorageDrivers> {
13+
return this.collectionsRepository.getAllowedCollectionStorageDrivers(collectionIdOrAlias)
14+
}
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { StorageDriver } from '../../../core/domain/models/StorageDriver'
3+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
4+
5+
export class GetCollectionStorageDriver implements UseCase<StorageDriver> {
6+
private collectionsRepository: ICollectionsRepository
7+
8+
constructor(collectionsRepository: ICollectionsRepository) {
9+
this.collectionsRepository = collectionsRepository
10+
}
11+
12+
async execute(
13+
collectionIdOrAlias: number | string,
14+
getEffective = false
15+
): Promise<StorageDriver> {
16+
return this.collectionsRepository.getCollectionStorageDriver(collectionIdOrAlias, getEffective)
17+
}
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
4+
export class SetCollectionStorageDriver implements UseCase<string> {
5+
private collectionsRepository: ICollectionsRepository
6+
7+
constructor(collectionsRepository: ICollectionsRepository) {
8+
this.collectionsRepository = collectionsRepository
9+
}
10+
11+
async execute(collectionIdOrAlias: number | string, driverLabel: string): Promise<string> {
12+
return this.collectionsRepository.setCollectionStorageDriver(collectionIdOrAlias, driverLabel)
13+
}
14+
}

src/collections/domain/useCases/UpdateCollection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class UpdateCollection implements UseCase<void> {
1919
*/
2020
async execute(
2121
collectionIdOrAlias: number | string,
22-
updatedCollection: CollectionDTO
22+
updatedCollection: Partial<CollectionDTO>
2323
): Promise<void> {
2424
return await this.collectionsRepository.updateCollection(collectionIdOrAlias, updatedCollection)
2525
}

src/collections/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { GetCollection } from './domain/useCases/GetCollection'
33
import { GetCollectionFacets } from './domain/useCases/GetCollectionFacets'
44
import { GetCollectionUserPermissions } from './domain/useCases/GetCollectionUserPermissions'
55
import { GetCollectionItems } from './domain/useCases/GetCollectionItems'
6+
import { GetCollectionStorageDriver } from './domain/useCases/GetCollectionStorageDriver'
67
import { PublishCollection } from './domain/useCases/PublishCollection'
78
import { UpdateCollection } from './domain/useCases/UpdateCollection'
89
import { GetCollectionFeaturedItems } from './domain/useCases/GetCollectionFeaturedItems'
@@ -16,10 +17,14 @@ import { LinkCollection } from './domain/useCases/LinkCollection'
1617
import { UnlinkCollection } from './domain/useCases/UnlinkCollection'
1718
import { GetCollectionLinks } from './domain/useCases/GetCollectionLinks'
1819
import { GetCollectionsForLinking } from './domain/useCases/GetCollectionsForLinking'
20+
import { SetCollectionStorageDriver } from './domain/useCases/SetCollectionStorageDriver'
21+
import { DeleteCollectionStorageDriver } from './domain/useCases/DeleteCollectionStorageDriver'
22+
import { GetAllowedCollectionStorageDrivers } from './domain/useCases/GetAllowedCollectionStorageDrivers'
1923

2024
const collectionsRepository = new CollectionsRepository()
2125

2226
const getCollection = new GetCollection(collectionsRepository)
27+
const getCollectionStorageDriver = new GetCollectionStorageDriver(collectionsRepository)
2328
const createCollection = new CreateCollection(collectionsRepository)
2429
const getCollectionFacets = new GetCollectionFacets(collectionsRepository)
2530
const getCollectionUserPermissions = new GetCollectionUserPermissions(collectionsRepository)
@@ -36,9 +41,15 @@ const linkCollection = new LinkCollection(collectionsRepository)
3641
const unlinkCollection = new UnlinkCollection(collectionsRepository)
3742
const getCollectionLinks = new GetCollectionLinks(collectionsRepository)
3843
const getCollectionsForLinking = new GetCollectionsForLinking(collectionsRepository)
44+
const setCollectionStorageDriver = new SetCollectionStorageDriver(collectionsRepository)
45+
const deleteCollectionStorageDriver = new DeleteCollectionStorageDriver(collectionsRepository)
46+
const getAllowedCollectionStorageDrivers = new GetAllowedCollectionStorageDrivers(
47+
collectionsRepository
48+
)
3949

4050
export {
4151
getCollection,
52+
getCollectionStorageDriver,
4253
createCollection,
4354
getCollectionFacets,
4455
getCollectionUserPermissions,
@@ -54,7 +65,10 @@ export {
5465
linkCollection,
5566
unlinkCollection,
5667
getCollectionLinks,
57-
getCollectionsForLinking
68+
getCollectionsForLinking,
69+
setCollectionStorageDriver,
70+
deleteCollectionStorageDriver,
71+
getAllowedCollectionStorageDrivers
5872
}
5973
export { Collection, CollectionInputLevel, CollectionTheme } from './domain/models/Collection'
6074
export { CollectionFacet } from './domain/models/CollectionFacet'
@@ -66,3 +80,4 @@ export { CollectionSearchCriteria } from './domain/models/CollectionSearchCriter
6680
export { FeaturedItem } from './domain/models/FeaturedItem'
6781
export { FeaturedItemsDTO } from './domain/dtos/FeaturedItemsDTO'
6882
export { CollectionSummary } from './domain/models/CollectionSummary'
83+
export { AllowedStorageDrivers } from './domain/models/AllowedStorageDrivers'

0 commit comments

Comments
 (0)