Skip to content

Commit

Permalink
feat(path): add method to transform a usual "route" into a path for t…
Browse files Browse the repository at this point in the history
…he db

With this feature you can easily transform `/user/123` into a path to get the data in node-json-db.
  • Loading branch information
Belphemur authored Oct 16, 2023
2 parents 847821f + 889d55e commit c389c7c
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/JsonDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,4 +432,43 @@ export class JsonDB {
throw new DatabaseError("Can't save the database", 2, err)
}
}


/**
* Convert a router style path to a normal path
* By default propertyName to search is "id"
* @param path router based path to a correct base path
* @param propertyName name of the property to look for searchValue
*/
public async fromPath(path: string, propertyName:string = 'id' ): Promise<string> {

const [,...pathToQuery] = path.split("/")

const pathObject = pathToQuery.reduce((prev, curr, indexPath) => {
const isKey = indexPath % 2 === 0
if (isKey) {
prev[`${curr}`] = ''
} else {
const keys = Object.keys(prev)
prev[`${keys[keys.length - 1]}`] = `${curr}`
}
return prev
}, {} as {[key: string]:string})

let normalPath: string[] = []

for await (const pathKey of Object.keys(pathObject)) {
normalPath.push(`/${pathKey}`)

const pathValue = pathObject[pathKey]
try {
const pathIndex = await this.getIndex(normalPath.join(""), pathValue, propertyName)
normalPath.push(`[${pathIndex}]`)
} catch (error) {
throw new DataError(`DataPath: ${normalPath.join("")}/${pathValue} not found.`, 13, error)
}
}

return normalPath.join("")
}
}
82 changes: 82 additions & 0 deletions test/04-array-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,88 @@ describe('Array Utils', () => {
expect(nestedArrayIndicies[1]).toEqual('2')
})
})
describe('To router path style to normal path', () => {
test('should convert a router style path to a normal path', async () => {
const recipe_1 = {
id: '78687873783',
name: 'Gratin',
category: 'Dish',
}
const recipe_2 = {
id: '65464646155',
name: 'Cheesecake',
category: 'Dessert',
nested: [
{
id: '458445',
name: 'test-1',
},
{
id: '88488',
name: 'test-2',
},
{
id: '458455',
name: 'test-3',
},
],
}
const recipe_3 = {
id: '12335373873',
name: 'Soupe',
category: 'Starter',
}
await db.push('/recipes[0]', recipe_1, true)
await db.push('/recipes[1]', recipe_2, true)
await db.push('/recipes[2]', recipe_3, true)

const routerPathStyle = '/recipes/65464646155/nested/88488'

const normalPath = await db.fromPath(routerPathStyle)

expect(normalPath).toEqual('/recipes[1]/nested[1]')
})
test('should convert a router style path to a normal path using other propertyName', async () => {
const recipe_1 = {
_id: '78687873783',
name: 'Gratin',
category: 'Dish',
}
const recipe_2 = {
_id: '65464646155',
name: 'Cheesecake',
category: 'Dessert',
nested: [
{
_id: '458445',
name: 'test-1',
},
{
_id: '88488',
name: 'test-2',
},
{
_id: '458455',
name: 'test-3',
},
],
}
const recipe_3 = {
_id: '12335373873',
name: 'Soupe',
category: 'Starter',
}
await db.push('/recipes[0]', recipe_1, true)
await db.push('/recipes[1]', recipe_2, true)
await db.push('/recipes[2]', recipe_3, true)

const routerPathStyle = '/recipes/65464646155/nested/88488'

const normalPath = await db.fromPath(routerPathStyle, '_id')

expect(normalPath).toEqual('/recipes[1]/nested[1]')
})
})
describe('Cleanup', () => {
test('should remove the test files', async () => {
fs.unlinkSync('test/recipe.json')
Expand Down
33 changes: 33 additions & 0 deletions test/JsonDB.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,39 @@ describe('JsonDB', () => {
})
})

describe('fromPath()', () => {
test('should throw path error when not found item',() => {
db.getData = jest.fn(async () => ({
a: [
{
id: '1'
}
]
}))

expect(async () => {
await db.fromPath('/a/1')
}).rejects.toThrow(
'DataPath: /a/1 not found.'
)
})
test('should throw path error when not found item and using a wrong propertyName',() => {
db.getData = jest.fn(async () => ({
a: [
{
id: '1'
}
]
}))

expect(async () => {
await db.fromPath('/a/1', '_id')
}).rejects.toThrow(
'DataPath: /a/1 not found.'
)
})
})

// Test was made for code coverage for getParentData, but this cannot return null or undefined.
// Commented out the test and the checks in JsonDB.ts.
// describe('push()', () => {
Expand Down

0 comments on commit c389c7c

Please sign in to comment.