Skip to content

Commit

Permalink
fix: changeCase for relation names (#21)
Browse files Browse the repository at this point in the history
When deserializing with the `changeCase` option, we should change the
case of relation names so they are consistent with the other properties
  • Loading branch information
Delerme authored Jan 14, 2023
1 parent 70653e7 commit d8ca17f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 9 deletions.
11 changes: 8 additions & 3 deletions src/deserializer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AttributesObject, DocumentObject, ExistingResourceObject, Options, ResourceObject } from './types'
import { changeCase } from './utils'
import { caseTypes, changeCase } from './utils'

type IncludedCache = Record<string, Record<string, unknown>>

Expand Down Expand Up @@ -70,8 +70,13 @@ function parseJsonApiSimpleResourceData<TEntity, TExtraOptions>(
continue
}

let casedRelationName = relationName
if (options.changeCase) {
casedRelationName = caseTypes[options.changeCase](relationName)
}

if (Array.isArray(relationReference.data)) {
resource[relationName] = relationReference.data.map((relationData) => {
resource[casedRelationName] = relationReference.data.map((relationData) => {
return findJsonApiIncluded(included, includedCache, relationData.type, relationData.id, options)
})
} else if (relationReference && relationReference.data) {
Expand All @@ -87,7 +92,7 @@ function parseJsonApiSimpleResourceData<TEntity, TExtraOptions>(
relationResource.links = relationReference.links
}

resource[relationName] = relationResource
resource[casedRelationName] = relationResource
}
}
}
Expand Down
11 changes: 5 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { camelCase, snakeCase, paramCase } from 'change-case'
import { AttributesObject, CaseType, JsonObject } from './types'

type CaseFunction = (input: string) => string
export const caseTypes: Record<CaseType, CaseFunction> = {
[CaseType.camelCase]: camelCase,
[CaseType.snakeCase]: snakeCase,
[CaseType.kebabCase]: paramCase,
}

/**
* Used to change the case (e.g. captalization) of the keys of a object
Expand All @@ -11,12 +16,6 @@ type CaseFunction = (input: string) => string
* @param deep
*/
export function changeCase(originalAttributes: AttributesObject, caseType: CaseType, deep = false): AttributesObject {
const caseTypes: Record<CaseType, CaseFunction> = {
[CaseType.camelCase]: camelCase,
[CaseType.snakeCase]: snakeCase,
[CaseType.kebabCase]: paramCase,
}

const caseFunction = caseTypes[caseType]

if (!caseFunction) {
Expand Down
44 changes: 44 additions & 0 deletions tests/deserialize.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,48 @@ describe('deserialize', () => {
},
])
})

it('should change relationship name casing', () => {
const serialized: DocumentObject = {
data: [
{
type: 'users',
id: '1',
attributes: {
'first-name': 'Joe',
'last-name': 'Doe',
},
relationships: {
home_address: {
data: {
type: 'addr',
id: '1',
},
},
},
},
],
included: [
{
type: 'addr',
id: '1',
attributes: {
street: 'Street 1',
},
},
],
}

expect(deserialize(serialized, { changeCase: CaseType.camelCase })).toStrictEqual([
{
id: '1',
firstName: 'Joe',
lastName: 'Doe',
homeAddress: {
id: '1',
street: 'Street 1',
},
},
])
})
})

0 comments on commit d8ca17f

Please sign in to comment.