Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript strict config #238

Merged
merged 11 commits into from
Jan 27, 2025
8 changes: 4 additions & 4 deletions src/collections/infra/repositories/CollectionsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export interface NewCollectionContactRequestPayload {
}

export interface NewCollectionMetadataBlocksRequestPayload {
metadataBlockNames: string[]
facetIds: string[]
inputLevels: NewCollectionInputLevelRequestPayload[]
metadataBlockNames?: string[]
facetIds?: string[]
inputLevels?: NewCollectionInputLevelRequestPayload[]
}

export interface NewCollectionInputLevelRequestPayload {
Expand Down Expand Up @@ -179,7 +179,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections
})
)

const inputLevelsRequestBody: NewCollectionInputLevelRequestPayload[] =
const inputLevelsRequestBody: NewCollectionInputLevelRequestPayload[] | undefined =
collectionDTO.inputLevels?.map((inputLevel) => ({
datasetFieldTypeName: inputLevel.datasetFieldName,
include: inputLevel.include,
Expand Down
2 changes: 1 addition & 1 deletion src/core/infra/repositories/ApiRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export abstract class ApiRepository {
protected buildApiEndpoint(
resourceName: string,
operation: string,
resourceId: number | string = undefined
resourceId: number | string | undefined = undefined
) {
return typeof resourceId === 'number'
? `/${resourceName}/${resourceId}/${operation}`
Expand Down
2 changes: 1 addition & 1 deletion src/core/infra/repositories/apiConfigBuilders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const buildRequestConfig = (
contentType: string = ApiConstants.CONTENT_TYPE_APPLICATION_JSON,
abortSignal?: AbortSignal
): AxiosRequestConfig => {
const requestConfig: AxiosRequestConfig = {
const requestConfig: AxiosRequestConfig & { headers: Record<string, unknown> } = {
params: queryParams,
headers: {
'Content-Type': contentType
Expand Down
2 changes: 1 addition & 1 deletion src/datasets/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type DatasetMetadataFieldValue =
| DatasetMetadataSubField[]
| AnonymizedField

export type DatasetMetadataSubField = Record<string, string>
export type DatasetMetadataSubField = Record<string, string | undefined>

export interface CitationMetadataBlock extends DatasetMetadataBlock {
name: 'citation'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ export class DatasetResourceValidator implements ResourceValidator {
metadataBlocks: MetadataBlock[]
) {
const metadataBlockName = metadataBlockValues.name
const metadataBlock: MetadataBlock = metadataBlocks.find(
const metadataBlock = metadataBlocks.find(
(metadataBlock) => metadataBlock.name === metadataBlockName
)
) as MetadataBlock

for (const metadataFieldKey of Object.keys(metadataBlock.metadataFields)) {
this.metadataFieldValidator.validate({
metadataFieldInfo: metadataBlock.metadataFields[metadataFieldKey],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MetadataFieldValidator } from './MetadataFieldValidator'
import { DatasetMetadataChildFieldValueDTO } from '../../dtos/DatasetDTO'
import { MultipleMetadataFieldValidator } from './MultipleMetadataFieldValidator'
import {
MetadataFieldInfo,
MetadataFieldType,
MetadataFieldWatermark
} from '../../../../metadataBlocks/domain/models/MetadataBlock'
Expand Down Expand Up @@ -62,7 +63,7 @@ export class SingleMetadataFieldValidator extends BaseMetadataFieldValidator {
datasetMetadataFieldAndValueInfo: DatasetMetadataFieldAndValueInfo
) {
if (
!datasetMetadataFieldAndValueInfo.metadataFieldInfo.controlledVocabularyValues.includes(
!datasetMetadataFieldAndValueInfo.metadataFieldInfo.controlledVocabularyValues?.includes(
datasetMetadataFieldAndValueInfo.metadataFieldValue as string
)
) {
Expand Down Expand Up @@ -120,13 +121,21 @@ export class SingleMetadataFieldValidator extends BaseMetadataFieldValidator {
datasetMetadataFieldAndValueInfo: DatasetMetadataFieldAndValueInfo
) {
const metadataFieldInfo = datasetMetadataFieldAndValueInfo.metadataFieldInfo
const childMetadataFieldKeys = Object.keys(metadataFieldInfo.childMetadataFields)

const childMetadataFieldKeys = Object.keys(
metadataFieldInfo.childMetadataFields as Record<string, MetadataFieldInfo>
)

const metadataFieldValidator = new MetadataFieldValidator(
this,
new MultipleMetadataFieldValidator(this)
)

for (const childMetadataFieldKey of childMetadataFieldKeys) {
const childMetadataFieldInfo = metadataFieldInfo.childMetadataFields[childMetadataFieldKey]
const childMetadataFieldInfo = (
metadataFieldInfo.childMetadataFields as Record<string, MetadataFieldInfo>
)[childMetadataFieldKey]

metadataFieldValidator.validate({
metadataFieldInfo: childMetadataFieldInfo,
metadataFieldKey: childMetadataFieldKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ export const transformDatasetModelToUpdateDatasetRequestPayload = (
datasetMetadataBlocksValues.forEach(function (
newDatasetMetadataBlockValues: DatasetMetadataBlockValuesDTO
) {
const metadataBlock: MetadataBlock = metadataBlocks.find(
const metadataBlock = metadataBlocks.find(
(metadataBlock) => metadataBlock.name == newDatasetMetadataBlockValues.name
)
) as MetadataBlock
const metadataBlockFieldsPayload: MetadataFieldRequestPayload[] = []
const metadataBlockFields = metadataBlock.metadataFields
const datasetMetadataFields = newDatasetMetadataBlockValues.fields
Expand Down Expand Up @@ -119,7 +119,7 @@ export const transformMetadataBlockModelsToRequestPayload = (
) {
const metadataBlock: MetadataBlock = metadataBlocks.find(
(metadataBlock) => metadataBlock.name == newDatasetMetadataBlockValues.name
)
) as MetadataBlock
metadataBlocksRequestPayload[newDatasetMetadataBlockValues.name] = {
fields: transformMetadataFieldModelsToRequestPayload(
newDatasetMetadataBlockValues.fields,
Expand Down Expand Up @@ -195,8 +195,9 @@ export const transformMetadataChildFieldValueToRequestPayload = (
): Record<string, MetadataFieldRequestPayload> => {
const metadataChildFieldRequestPayload: Record<string, MetadataFieldRequestPayload> = {}
for (const metadataChildFieldKey of Object.keys(datasetMetadataChildFieldValue)) {
const childMetadataFieldInfo: MetadataFieldInfo =
metadataBlockFieldInfo.childMetadataFields[metadataChildFieldKey]
const childMetadataFieldInfo: MetadataFieldInfo = (
metadataBlockFieldInfo.childMetadataFields as Record<string, MetadataFieldInfo>
)[metadataChildFieldKey]
const value: string = datasetMetadataChildFieldValue[metadataChildFieldKey] as unknown as string
metadataChildFieldRequestPayload[metadataChildFieldKey] = {
value: value,
Expand Down Expand Up @@ -242,7 +243,9 @@ export const transformVersionPayloadToDataset = (
})
}
if ('license' in versionPayload) {
datasetModel.license = transformPayloadToDatasetLicense(versionPayload.license)
datasetModel.license = transformPayloadToDatasetLicense(
versionPayload.license as LicensePayload
)
}
if ('alternativePersistentId' in versionPayload) {
datasetModel.alternativePersistentId = versionPayload.alternativePersistentId
Expand Down
17 changes: 11 additions & 6 deletions src/files/infra/clients/DirectUploadClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ export class DirectUploadClient implements IDirectUploadClient {
if (axios.isCancel(error)) {
throw new FileUploadCancelError(file.name, datasetId)
}
throw new FileUploadError(file.name, datasetId, error.message)
const errorMessage = error instanceof Error ? error.message : 'Upload singlepart file failed'
throw new FileUploadError(file.name, datasetId, errorMessage)
}
}

Expand Down Expand Up @@ -114,16 +115,20 @@ export class DirectUploadClient implements IDirectUploadClient {
eTags[`${index + 1}`] = eTag
} catch (error) {
if (axios.isCancel(error)) {
await this.abortMultipartUpload(file.name, datasetId, destination.abortEndpoint)
await this.abortMultipartUpload(file.name, datasetId, destination.abortEndpoint as string)
throw new FileUploadCancelError(file.name, datasetId)
}
if (retries < maxRetries) {
const backoffDelay = Math.pow(2, retries) * 1000
await new Promise((resolve) => setTimeout(resolve, backoffDelay))
await uploadPart(destinationUrl, index, retries + 1)
} else {
await this.abortMultipartUpload(file.name, datasetId, destination.abortEndpoint)
throw new FilePartUploadError(file.name, datasetId, error.message, index + 1)
await this.abortMultipartUpload(file.name, datasetId, destination.abortEndpoint as string)

const errorMessage =
error instanceof Error ? error.message : 'Upload part of multipart file failed'

throw new FilePartUploadError(file.name, datasetId, errorMessage, index + 1)
}
}
}
Expand Down Expand Up @@ -165,7 +170,7 @@ export class DirectUploadClient implements IDirectUploadClient {
): Promise<void> {
return await axios
.put(
buildRequestUrl(destination.completeEndpoint),
buildRequestUrl(destination.completeEndpoint as string),
eTags,
buildRequestConfig(
true,
Expand All @@ -177,7 +182,7 @@ export class DirectUploadClient implements IDirectUploadClient {
.then(() => undefined)
.catch(async (error) => {
if (axios.isCancel(error)) {
await this.abortMultipartUpload(fileName, datasetId, destination.abortEndpoint)
await this.abortMultipartUpload(fileName, datasetId, destination.abortEndpoint as string)
throw new FileUploadCancelError(fileName, datasetId)
}
throw new MultipartCompletionError(fileName, datasetId, error.message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,19 @@ const transformMetadataBlockPayloadToMetadataBlock = (

const getChildFieldKeys = (metadataBlockFieldsPayload: Record<string, unknown>): Set<string> => {
const childFieldKeys = new Set<string>()
Object.values(metadataBlockFieldsPayload).forEach(
(fieldInfo: { childFields?: Record<string, unknown> }) => {
if (fieldInfo.childFields) {
Object.keys(fieldInfo.childFields).forEach((childKey) => {
childFieldKeys.add(childKey)
})
}
Object.values(metadataBlockFieldsPayload).forEach((fieldInfo) => {
if (
fieldInfo &&
typeof fieldInfo === 'object' &&
'childFields' in fieldInfo &&
typeof fieldInfo.childFields === 'object' &&
(fieldInfo?.childFields as Record<string, unknown>)
) {
Object.keys(fieldInfo.childFields as Record<string, unknown>).forEach((childKey) => {
childFieldKeys.add(childKey)
})
}
)
})
return childFieldKeys
}

Expand Down
6 changes: 3 additions & 3 deletions test/functional/collections/CreateCollection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ describe('execute', () => {
test('should throw an error when the parent collection does not exist', async () => {
const testNewCollection = createCollectionDTO()
expect.assertions(2)
let writeError: WriteError
let writeError: WriteError | undefined = undefined
try {
await createCollection.execute(testNewCollection, TestConstants.TEST_DUMMY_COLLECTION_ID)
throw new Error('Use case should throw an error')
} catch (error) {
writeError = error
writeError = error as WriteError
} finally {
expect(writeError).toBeInstanceOf(WriteError)
expect(writeError.message).toEqual(
expect(writeError?.message).toEqual(
`There was an error when writing the resource. Reason was: [404] Can't find dataverse with identifier='${TestConstants.TEST_DUMMY_COLLECTION_ID}'`
)
}
Expand Down
6 changes: 3 additions & 3 deletions test/functional/collections/GetCollectionFacets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ describe('execute', () => {

test('should throw an error when collection does not exist', async () => {
expect.assertions(2)
let readError: ReadError
let readError: ReadError | undefined = undefined
try {
await getCollectionFacets.execute(TestConstants.TEST_DUMMY_COLLECTION_ID)
throw new Error('Use case should throw an error')
} catch (error) {
readError = error
readError = error as ReadError
} finally {
expect(readError).toBeInstanceOf(ReadError)
expect(readError.message).toEqual(
expect(readError?.message).toEqual(
`There was an error when reading the resource. Reason was: [404] Can't find dataverse with identifier='${TestConstants.TEST_DUMMY_COLLECTION_ID}'`
)
}
Expand Down
16 changes: 7 additions & 9 deletions test/functional/collections/GetCollectionItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
} from '../../testHelpers/collections/collectionHelper'
import { uploadFileViaApi } from '../../testHelpers/files/filesHelper'
import { deleteUnpublishedDatasetViaApi } from '../../testHelpers/datasets/datasetHelper'
import { CollectionItemSubset } from '../../../src/collections/domain/models/CollectionItemSubset'

describe('execute', () => {
const testCollectionAlias = 'collectionsRepositoryFunctionalTestCollection'
Expand Down Expand Up @@ -59,33 +58,32 @@ describe('execute', () => {
// Give enough time to Solr for indexing
await new Promise((resolve) => setTimeout(resolve, 5000))

let actual: CollectionItemSubset
try {
actual = await getCollectionItems.execute(testCollectionAlias)
} catch (error) {
throw new Error('Item subset should be retrieved')
} finally {
const actual = await getCollectionItems.execute(testCollectionAlias)

const actualFilePreview = actual.items[0] as FilePreview
const actualDatasetPreview = actual.items[1] as DatasetPreview

expect(actualFilePreview.name).toBe('test-file-1.txt')
expect(actualDatasetPreview.title).toBe('Dataset created using the createDataset use case')

expect(actual.totalItemCount).toBe(2)
} catch (error) {
throw new Error('Item subset should be retrieved')
}
})

test('should throw an error when collection does not exist', async () => {
expect.assertions(2)
let readError: ReadError
let readError: ReadError | undefined = undefined
try {
await getCollectionItems.execute(TestConstants.TEST_DUMMY_COLLECTION_ALIAS)
throw new Error('Use case should throw an error')
} catch (error) {
readError = error
readError = error as ReadError
} finally {
expect(readError).toBeInstanceOf(ReadError)
expect(readError.message).toEqual(
expect(readError?.message).toEqual(
`There was an error when reading the resource. Reason was: [400] Could not find dataverse with alias ${TestConstants.TEST_DUMMY_COLLECTION_ALIAS}`
)
}
Expand Down
51 changes: 22 additions & 29 deletions test/functional/collections/GetCollectionUserPermissions.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
ApiConfig,
CollectionUserPermissions,
ReadError,
getCollectionUserPermissions
} from '../../../src'
import { ApiConfig, ReadError, getCollectionUserPermissions } from '../../../src'
import { TestConstants } from '../../testHelpers/TestConstants'
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'

Expand All @@ -19,49 +14,47 @@ describe('execute', () => {
})

test('should return user permissions for the default collection', async () => {
let actual: CollectionUserPermissions
try {
actual = await getCollectionUserPermissions.execute()
const permissions = await getCollectionUserPermissions.execute()

expect(permissions.canAddDataset).toBe(true)
expect(permissions.canAddCollection).toBe(true)
expect(permissions.canDeleteCollection).toBe(true)
expect(permissions.canEditCollection).toBe(true)
expect(permissions.canManageCollectionPermissions).toBe(true)
expect(permissions.canPublishCollection).toBe(true)
expect(permissions.canViewUnpublishedCollection).toBe(true)
} catch (error) {
throw new Error('Permissions should be retrieved')
} finally {
expect(actual.canAddDataset).toBe(true)
expect(actual.canAddCollection).toBe(true)
expect(actual.canDeleteCollection).toBe(true)
expect(actual.canEditCollection).toBe(true)
expect(actual.canManageCollectionPermissions).toBe(true)
expect(actual.canPublishCollection).toBe(true)
expect(actual.canViewUnpublishedCollection).toBe(true)
}
})
test('should return user permissions when a valid collection alias is provided', async () => {
let actual: CollectionUserPermissions
try {
actual = await getCollectionUserPermissions.execute(ROOT_COLLECTION_ALIAS)
const permissions = await getCollectionUserPermissions.execute(ROOT_COLLECTION_ALIAS)

expect(permissions.canAddDataset).toBe(true)
expect(permissions.canAddCollection).toBe(true)
expect(permissions.canDeleteCollection).toBe(true)
expect(permissions.canEditCollection).toBe(true)
expect(permissions.canManageCollectionPermissions).toBe(true)
expect(permissions.canPublishCollection).toBe(true)
expect(permissions.canViewUnpublishedCollection).toBe(true)
} catch (error) {
throw new Error('Permissions should be retrieved')
} finally {
expect(actual.canAddDataset).toBe(true)
expect(actual.canAddCollection).toBe(true)
expect(actual.canDeleteCollection).toBe(true)
expect(actual.canEditCollection).toBe(true)
expect(actual.canManageCollectionPermissions).toBe(true)
expect(actual.canPublishCollection).toBe(true)
expect(actual.canViewUnpublishedCollection).toBe(true)
}
})

test('should throw an error when collection does not exist', async () => {
expect.assertions(2)
let readError: ReadError
let readError: ReadError | undefined = undefined
try {
await getCollectionUserPermissions.execute(TestConstants.TEST_DUMMY_COLLECTION_ID)
throw new Error('Use case should throw an error')
} catch (error) {
readError = error
readError = error as ReadError
} finally {
expect(readError).toBeInstanceOf(ReadError)
expect(readError.message).toEqual(
expect(readError?.message).toEqual(
`There was an error when reading the resource. Reason was: [404] Can't find dataverse with identifier='${TestConstants.TEST_DUMMY_COLLECTION_ID}'`
)
}
Expand Down
Loading
Loading