Skip to content

Commit 53a5623

Browse files
authored
Merge pull request #141 from IQSS/135-collections-get-metadata-blocks
Get collection metadata blocks
2 parents c4971c2 + 153a56a commit 53a5623

File tree

20 files changed

+441
-117
lines changed

20 files changed

+441
-117
lines changed

docs/useCases.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ The different use cases currently available in the package are classified below,
3838
- [Metadata Blocks](#metadata-blocks)
3939
- [Metadata Blocks read use cases](#metadata-blocks-read-use-cases)
4040
- [Get Metadata Block By Name](#get-metadata-block-by-name)
41+
- [Get Collection Metadata Blocks](#get-collection-metadata-blocks)
4142
- [Users](#Users)
4243
- [Users read use cases](#users-read-use-cases)
4344
- [Get Current Authenticated User](#get-current-authenticated-user)
@@ -765,6 +766,32 @@ getMetadataBlockByName.execute(name).then((metadataBlock: MetadataBlock) => {
765766

766767
_See [use case](../src/metadataBlocks/domain/useCases/GetMetadataBlockByName.ts) implementation_.
767768

769+
#### Get Collection Metadata Blocks
770+
771+
Returns a [MetadataBlock](../src/metadataBlocks/domain/models/MetadataBlock.ts) array containing the metadata blocks from the requested collection.
772+
773+
##### Example call:
774+
775+
```typescript
776+
import { getCollectionMetadataBlocks } from '@iqss/dataverse-client-javascript'
777+
778+
/* ... */
779+
780+
const collectionIdOrAlias = 'citation'
781+
782+
getCollectionMetadataBlocks.execute(collectionAlias).then((metadataBlocks: MetadataBlock[]) => {
783+
/* ... */
784+
})
785+
786+
/* ... */
787+
```
788+
789+
_See [use case](../src/metadataBlocks/domain/useCases/GetCollectionMetadataBlocks.ts) implementation_.
790+
791+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
792+
793+
There is a second optional parameter called `onlyDisplayedOnCreate` which indicates whether or not to return only the metadata blocks that are displayed on dataset creation. The default value is false.
794+
768795
## Users
769796

770797
### Users read use cases
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Collection } from '../models/Collection'
2+
23
export interface ICollectionsRepository {
34
getCollection(collectionIdOrAlias: number | string): Promise<Collection>
45
}

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,16 @@ import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'
22
import { ICollectionsRepository } from '../../domain/repositories/ICollectionsRepository'
33
import { transformCollectionResponseToCollection } from './transformers/collectionTransformers'
44
import { Collection, ROOT_COLLECTION_ALIAS } from '../../domain/models/Collection'
5+
56
export class CollectionsRepository extends ApiRepository implements ICollectionsRepository {
67
private readonly collectionsResourceName: string = 'dataverses'
7-
private readonly collectionsDefaultOperationType: string = 'get'
88

99
public async getCollection(
1010
collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS
1111
): Promise<Collection> {
12-
return this.doGet(
13-
this.buildApiEndpoint(
14-
this.collectionsResourceName,
15-
this.collectionsDefaultOperationType,
16-
collectionIdOrAlias
17-
),
18-
true,
19-
{ returnOwners: true }
20-
)
12+
return this.doGet(`/${this.collectionsResourceName}/${collectionIdOrAlias}`, true, {
13+
returnOwners: true
14+
})
2115
.then((response) => transformCollectionResponseToCollection(response))
2216
.catch((error) => {
2317
throw error

src/core/infra/repositories/ApiRepository.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ export abstract class ApiRepository {
3939
operation: string,
4040
resourceId: number | string = undefined
4141
) {
42-
if (resourceName === 'dataverses') {
43-
return `/${resourceName}/${resourceId}`
44-
}
45-
4642
return typeof resourceId === 'number'
4743
? `/${resourceName}/${resourceId}/${operation}`
4844
: typeof resourceId === 'string'

src/datasets/domain/useCases/validators/MultipleMetadataFieldValidator.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
} from './BaseMetadataFieldValidator'
55
import { NewDatasetMetadataFieldValueDTO } from '../../dtos/NewDatasetDTO'
66
import { SingleMetadataFieldValidator } from './SingleMetadataFieldValidator'
7+
import { MetadataFieldType } from '../../../../metadataBlocks/domain/models/MetadataBlock'
78

89
export class MultipleMetadataFieldValidator extends BaseMetadataFieldValidator {
910
constructor(private singleMetadataFieldValidator: SingleMetadataFieldValidator) {
@@ -19,14 +20,17 @@ export class MultipleMetadataFieldValidator extends BaseMetadataFieldValidator {
1920
'Expecting an array of values.'
2021
)
2122
}
22-
if (this.isValidArrayType(metadataFieldValue, 'string') && metadataFieldInfo.type === 'NONE') {
23+
if (
24+
this.isValidArrayType(metadataFieldValue, 'string') &&
25+
metadataFieldInfo.type === MetadataFieldType.None
26+
) {
2327
throw this.createGeneralValidationError(
2428
newDatasetMetadataFieldAndValueInfo,
2529
'Expecting an array of child fields, not strings.'
2630
)
2731
} else if (
2832
this.isValidArrayType(metadataFieldValue, 'object') &&
29-
metadataFieldInfo.type !== 'NONE'
33+
metadataFieldInfo.type !== MetadataFieldType.None
3034
) {
3135
throw this.createGeneralValidationError(
3236
newDatasetMetadataFieldAndValueInfo,

src/datasets/domain/useCases/validators/SingleMetadataFieldValidator.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { DateFormatFieldError } from './errors/DateFormatFieldError'
77
import { MetadataFieldValidator } from './MetadataFieldValidator'
88
import { NewDatasetMetadataChildFieldValueDTO } from '../../dtos/NewDatasetDTO'
99
import { MultipleMetadataFieldValidator } from './MultipleMetadataFieldValidator'
10+
import { MetadataFieldType } from '../../../../metadataBlocks/domain/models/MetadataBlock'
1011

1112
export class SingleMetadataFieldValidator extends BaseMetadataFieldValidator {
1213
validate(newDatasetMetadataFieldAndValueInfo: NewDatasetMetadataFieldAndValueInfo): void {
@@ -18,13 +19,19 @@ export class SingleMetadataFieldValidator extends BaseMetadataFieldValidator {
1819
'Expecting a single field, not an array.'
1920
)
2021
}
21-
if (typeof metadataFieldValue === 'object' && metadataFieldInfo.type !== 'NONE') {
22+
if (
23+
typeof metadataFieldValue === 'object' &&
24+
metadataFieldInfo.type !== MetadataFieldType.None
25+
) {
2226
throw this.createGeneralValidationError(
2327
newDatasetMetadataFieldAndValueInfo,
2428
'Expecting a string, not child fields.'
2529
)
2630
}
27-
if (typeof metadataFieldValue === 'string' && metadataFieldInfo.type === 'NONE') {
31+
if (
32+
typeof metadataFieldValue === 'string' &&
33+
metadataFieldInfo.type === MetadataFieldType.None
34+
) {
2835
throw this.createGeneralValidationError(
2936
newDatasetMetadataFieldAndValueInfo,
3037
'Expecting child fields, not a string.'
@@ -41,7 +48,7 @@ export class SingleMetadataFieldValidator extends BaseMetadataFieldValidator {
4148
this.validateControlledVocabularyFieldValue(newDatasetMetadataFieldAndValueInfo)
4249
}
4350

44-
if (metadataFieldInfo.type == 'DATE') {
51+
if (metadataFieldInfo.type == MetadataFieldType.Date) {
4552
this.validateDateFieldValue(newDatasetMetadataFieldAndValueInfo)
4653
}
4754

src/metadataBlocks/domain/models/MetadataBlock.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ export interface MetadataBlock {
33
name: string
44
displayName: string
55
metadataFields: Record<string, MetadataFieldInfo>
6+
displayOnCreate: boolean
67
}
78

89
export interface MetadataFieldInfo {
910
name: string
1011
displayName: string
1112
title: string
12-
type: string
13-
typeClass: string
14-
watermark: string
13+
type: MetadataFieldType
14+
typeClass: MetadataFieldTypeClass
15+
watermark: MetadataFieldWatermark
1516
description: string
1617
multiple: boolean
1718
isControlledVocabulary: boolean
@@ -20,4 +21,37 @@ export interface MetadataFieldInfo {
2021
childMetadataFields?: Record<string, MetadataFieldInfo>
2122
isRequired: boolean
2223
displayOrder: number
24+
displayOnCreate: boolean
25+
}
26+
27+
export enum MetadataFieldType {
28+
Date = 'DATE',
29+
Email = 'EMAIL',
30+
Float = 'FLOAT',
31+
Int = 'INT',
32+
None = 'NONE',
33+
Text = 'TEXT',
34+
Textbox = 'TEXTBOX',
35+
URL = 'URL'
36+
}
37+
38+
export enum MetadataFieldTypeClass {
39+
Compound = 'compound',
40+
ControlledVocabulary = 'controlledVocabulary',
41+
Primitive = 'primitive'
42+
}
43+
44+
export enum MetadataFieldWatermark {
45+
Empty = '',
46+
EnterAFloatingPointNumber = 'Enter a floating-point number.',
47+
EnterAnInteger = 'Enter an integer.',
48+
FamilyNameGivenNameOrOrganization = 'FamilyName, GivenName or Organization',
49+
HTTPS = 'https://',
50+
NameEmailXyz = '[email protected]',
51+
OrganizationXYZ = 'Organization XYZ',
52+
The1FamilyNameGivenNameOr2Organization = '1) FamilyName, GivenName or 2) Organization',
53+
The1FamilyNameGivenNameOr2OrganizationXYZ = '1) Family Name, Given Name or 2) Organization XYZ',
54+
WatermarkEnterAnInteger = 'Enter an integer...',
55+
YYYYOrYYYYMMOrYYYYMMDD = 'YYYY or YYYY-MM or YYYY-MM-DD',
56+
YyyyMmDD = 'YYYY-MM-DD'
2357
}

src/metadataBlocks/domain/repositories/IMetadataBlocksRepository.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ import { MetadataBlock } from '../models/MetadataBlock'
22

33
export interface IMetadataBlocksRepository {
44
getMetadataBlockByName(metadataBlockName: string): Promise<MetadataBlock>
5+
6+
getCollectionMetadataBlocks(
7+
collectionIdOrAlias: number | string,
8+
onlyDisplayedOnCreate: boolean
9+
): Promise<MetadataBlock[]>
510
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { MetadataBlock } from '../..'
3+
import { ROOT_COLLECTION_ALIAS } from '../../../collections/domain/models/Collection'
4+
import { IMetadataBlocksRepository } from '../repositories/IMetadataBlocksRepository'
5+
6+
export class GetCollectionMetadataBlocks implements UseCase<MetadataBlock[]> {
7+
private metadataBlocksRepository: IMetadataBlocksRepository
8+
9+
constructor(metadataBlocksRepository: IMetadataBlocksRepository) {
10+
this.metadataBlocksRepository = metadataBlocksRepository
11+
}
12+
13+
/**
14+
* Returns a MetadataBlock array containing the metadata blocks from the requested collection.
15+
*
16+
* @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)
17+
* If this parameter is not set, the default value is: 'root'
18+
* @param {boolean} [onlyDisplayedOnCreate=false] - Indicates whether or not to return only the metadata blocks that are displayed on dataset creation. The default value is false.
19+
* @returns {Promise<MetadataBlock[]>}
20+
*/
21+
async execute(
22+
collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS,
23+
onlyDisplayedOnCreate = false
24+
): Promise<MetadataBlock[]> {
25+
return await this.metadataBlocksRepository.getCollectionMetadataBlocks(
26+
collectionIdOrAlias,
27+
onlyDisplayedOnCreate
28+
)
29+
}
30+
}

src/metadataBlocks/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import { GetMetadataBlockByName } from './domain/useCases/GetMetadataBlockByName'
22
import { MetadataBlocksRepository } from './infra/repositories/MetadataBlocksRepository'
3+
import { GetCollectionMetadataBlocks } from './domain/useCases/GetCollectionMetadataBlocks'
34

45
const metadataBlocksRepository = new MetadataBlocksRepository()
56

67
const getMetadataBlockByName = new GetMetadataBlockByName(metadataBlocksRepository)
8+
const getCollectionMetadataBlocks = new GetCollectionMetadataBlocks(metadataBlocksRepository)
79

8-
export { getMetadataBlockByName }
9-
export { MetadataBlock, MetadataFieldInfo } from './domain/models/MetadataBlock'
10+
export { getMetadataBlockByName, getCollectionMetadataBlocks }
11+
export {
12+
MetadataBlock,
13+
MetadataFieldInfo,
14+
MetadataFieldType,
15+
MetadataFieldTypeClass
16+
} from './domain/models/MetadataBlock'

0 commit comments

Comments
 (0)