Skip to content

Commit 5c17fe5

Browse files
committed
add Collection Storage Driver use cases, refactor existing use cases to use shared StorageDriver model.
1 parent 9c7e9d8 commit 5c17fe5

25 files changed

Lines changed: 667 additions & 16 deletions

docs/useCases.md

Lines changed: 115 additions & 5 deletions
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)
@@ -172,6 +176,65 @@ The `collectionIdOrAlias` is a generic collection identifier, which can be eithe
172176

173177
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.
174178

179+
#### Get Collection Storage Driver
180+
181+
Returns a [StorageDriver](../src/core/domain/models/StorageDriver.ts) instance describing the collection's assigned storage driver.
182+
183+
##### Example call:
184+
185+
```typescript
186+
import { getCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
187+
188+
/* ... */
189+
190+
const collectionIdOrAlias = 'classicLiterature'
191+
192+
getCollectionStorageDriver.execute(collectionIdOrAlias).then((storageDriver: StorageDriver) => {
193+
/* ... */
194+
})
195+
196+
// Pass true to resolve the effective driver after inheritance/default fallback
197+
getCollectionStorageDriver
198+
.execute(collectionIdOrAlias, true)
199+
.then((storageDriver: StorageDriver) => {
200+
/* ... */
201+
})
202+
203+
/* ... */
204+
```
205+
206+
_See [use case](../src/collections/domain/useCases/GetCollectionStorageDriver.ts) implementation_.
207+
208+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
209+
210+
The optional `getEffective` parameter defaults to `false`. Set it to `true` to retrieve the effective storage driver after inheritance/default resolution.
211+
212+
#### Get Allowed Collection Storage Drivers
213+
214+
Returns an [AllowedStorageDrivers](../src/collections/domain/models/AllowedStorageDrivers.ts) object whose keys are driver labels and whose values are storage driver ids.
215+
216+
##### Example call:
217+
218+
```typescript
219+
import { getAllowedCollectionStorageDrivers } from '@iqss/dataverse-client-javascript'
220+
221+
/* ... */
222+
223+
const collectionIdOrAlias = 'classicLiterature'
224+
225+
getAllowedCollectionStorageDrivers
226+
.execute(collectionIdOrAlias)
227+
.then((storageDrivers: AllowedStorageDrivers) => {
228+
/* ... */
229+
})
230+
231+
/* ... */
232+
```
233+
234+
_See [use case](../src/collections/domain/useCases/GetAllowedCollectionStorageDrivers.ts) implementation_.
235+
236+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
237+
175238
#### Get Collection Facets
176239

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

443506
The use case returns a number, which is the identifier of the created collection.
444507

508+
#### Set Collection Storage Driver
509+
510+
Assigns a storage driver to a collection by driver label and returns the backend success message.
511+
512+
##### Example call:
513+
514+
```typescript
515+
import { setCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
516+
517+
/* ... */
518+
519+
const collectionIdOrAlias = 'classicLiterature'
520+
const driverLabel = 'Local Storage'
521+
522+
setCollectionStorageDriver.execute(collectionIdOrAlias, driverLabel).then((message: string) => {
523+
/* ... */
524+
})
525+
526+
/* ... */
527+
```
528+
529+
_See [use case](../src/collections/domain/useCases/SetCollectionStorageDriver.ts) implementation_.
530+
531+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
532+
533+
The `driverLabel` parameter must match the storage driver's label, not its id.
534+
535+
#### Delete Collection Storage Driver
536+
537+
Clears the directly assigned storage driver from a collection so it falls back to inherited/default storage, and returns the backend success message.
538+
539+
##### Example call:
540+
541+
```typescript
542+
import { deleteCollectionStorageDriver } from '@iqss/dataverse-client-javascript'
543+
544+
/* ... */
545+
546+
const collectionIdOrAlias = 'classicLiterature'
547+
548+
deleteCollectionStorageDriver.execute(collectionIdOrAlias).then((message: string) => {
549+
/* ... */
550+
})
551+
552+
/* ... */
553+
```
554+
555+
_See [use case](../src/collections/domain/useCases/DeleteCollectionStorageDriver.ts) implementation_.
556+
557+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
558+
445559
#### Update a Collection
446560

447561
Updates an existing collection, given a collection identifier and a [CollectionDTO](../src/collections/domain/dtos/CollectionDTO.ts) including the updated collection data.
@@ -1398,8 +1512,6 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetAvailableCategories.ts
13981512

13991513
The `datasetId` parameter is a number for numeric identifiers or string for persistent identifiers.
14001514

1401-
# <<<<<<< HEAD
1402-
14031515
#### Get Dataset Templates
14041516

14051517
Returns a [DatasetTemplate](../src/datasets/domain/models/DatasetTemplate.ts) array containing the dataset templates of the requested collection, given the collection identifier or alias.
@@ -1420,7 +1532,7 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetTemplates.ts)_ definit
14201532

14211533
#### Get Dataset Storage Driver
14221534

1423-
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.
1535+
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.
14241536

14251537
##### Example call:
14261538

@@ -1442,8 +1554,6 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetStorageDriver.ts) impl
14421554

14431555
The `datasetId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers.
14441556

1445-
> > > > > > > develop
1446-
14471557
#### Add a Dataset Type
14481558

14491559
Adds a dataset types that can be used at dataset creation.
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: 14 additions & 0 deletions
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
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/index.ts

Lines changed: 17 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 } from './domain/models/Collection'
6074
export { CollectionFacet } from './domain/models/CollectionFacet'
@@ -66,3 +80,5 @@ 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'
84+
export { StorageDriver } from '../core/domain/models/StorageDriver'

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import { PublicationStatus } from '../../../core/domain/models/PublicationStatus
3939
import { ReadError } from '../../../core/domain/repositories/ReadError'
4040
import { CollectionLinks } from '../../domain/models/CollectionLinks'
4141
import { CollectionSummary } from '../../domain/models/CollectionSummary'
42+
import { AllowedStorageDrivers } from '../../domain/models/AllowedStorageDrivers'
43+
import { StorageDriver } from '../../../core/domain/models/StorageDriver'
4244
import { LinkingObjectType } from '../../domain/useCases/GetCollectionsForLinking'
4345

4446
export interface NewCollectionRequestPayload {
@@ -108,6 +110,62 @@ export class CollectionsRepository extends ApiRepository implements ICollections
108110
})
109111
}
110112

113+
public async getCollectionStorageDriver(
114+
collectionIdOrAlias: number | string,
115+
getEffective = false
116+
): Promise<StorageDriver> {
117+
return this.doGet(
118+
`/${this.collectionsResourceName}/${collectionIdOrAlias}/storageDriver`,
119+
true,
120+
{
121+
getEffective
122+
}
123+
)
124+
.then((response) => response.data.data as StorageDriver)
125+
.catch((error) => {
126+
throw error
127+
})
128+
}
129+
130+
public async setCollectionStorageDriver(
131+
collectionIdOrAlias: number | string,
132+
driverLabel: string
133+
): Promise<string> {
134+
return this.doPut(
135+
`/${this.collectionsResourceName}/${collectionIdOrAlias}/storageDriver`,
136+
driverLabel,
137+
undefined,
138+
ApiConstants.CONTENT_TYPE_TEXT_PLAIN
139+
)
140+
.then((response) => response.data.data.message)
141+
.catch((error) => {
142+
throw error
143+
})
144+
}
145+
146+
public async deleteCollectionStorageDriver(
147+
collectionIdOrAlias: number | string
148+
): Promise<string> {
149+
return this.doDelete(`/${this.collectionsResourceName}/${collectionIdOrAlias}/storageDriver`)
150+
.then((response) => response.data.data.message)
151+
.catch((error) => {
152+
throw error
153+
})
154+
}
155+
156+
public async getAllowedCollectionStorageDrivers(
157+
collectionIdOrAlias: number | string
158+
): Promise<AllowedStorageDrivers> {
159+
return this.doGet(
160+
`/${this.collectionsResourceName}/${collectionIdOrAlias}/allowedStorageDrivers`,
161+
true
162+
)
163+
.then((response) => response.data.data as AllowedStorageDrivers)
164+
.catch((error) => {
165+
throw error
166+
})
167+
}
168+
111169
public async createCollection(
112170
collectionDTO: CollectionDTO,
113171
parentCollectionId: number | string = ROOT_COLLECTION_ID

src/datasets/domain/models/StorageDriver.ts renamed to src/core/domain/models/StorageDriver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export interface StorageDriver {
22
name: string
3-
type: string
4-
label: string
3+
type?: string
4+
label?: string
55
directUpload: boolean
66
directDownload: boolean
77
uploadOutOfBand: boolean

0 commit comments

Comments
 (0)