Skip to content

Commit

Permalink
Merge pull request #271 from usu/feat/short-self-links
Browse files Browse the repository at this point in the history
Feat: short self links without apiRoot
  • Loading branch information
carlobeltrame committed Mar 19, 2022
2 parents 3472d3e + d518a84 commit c73f3e3
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 85 deletions.
11 changes: 7 additions & 4 deletions src/LoadingResource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import LoadingCollection from './LoadingCollection'
import ResourceInterface from './interfaces/ResourceInterface'
import CollectionInterface from './interfaces/CollectionInterface'
import { InternalConfig } from './interfaces/Config'

/**
* Creates a placeholder for an entity which has not yet finished loading from the API.
Expand All @@ -17,6 +18,7 @@ import CollectionInterface from './interfaces/CollectionInterface'
class LoadingResource implements ResourceInterface {
public _meta: {
self: string | null,
selfUrl: string | null,
load: Promise<ResourceInterface>
loading: boolean
}
Expand All @@ -26,12 +28,13 @@ class LoadingResource implements ResourceInterface {
/**
* @param entityLoaded a Promise that resolves to a Resource when the entity has finished
* loading from the API
* @param absoluteSelf optional fully qualified URI of the entity being loaded, if available. If passed, the
* @param self optional URI of the entity being loaded, if available. If passed, the
* returned LoadingResource will return it in calls to .self and ._meta.self
*/
constructor (loadResource: Promise<ResourceInterface>, absoluteSelf: string | null = null) {
constructor (loadResource: Promise<ResourceInterface>, self: string | null = null, config: InternalConfig | null = null) {
this._meta = {
self: absoluteSelf,
self: self,
selfUrl: self ? config?.apiRoot + self : null,
load: loadResource,
loading: true
}
Expand Down Expand Up @@ -64,7 +67,7 @@ class LoadingResource implements ResourceInterface {
try {
return property(templateParams)._meta.load
} catch (e) {
throw new Error(`Property '${prop.toString()}' on resource ${absoluteSelf} was used like a relation, but no relation with this name was returned by the API (actual return value: ${JSON.stringify(property)})`)
throw new Error(`Property '${prop.toString()}' on resource '${self}' was used like a relation, but no relation with this name was returned by the API (actual return value: ${JSON.stringify(property)})`)
}
}
))
Expand Down
4 changes: 3 additions & 1 deletion src/Resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { InternalConfig } from './interfaces/Config'
class Resource implements ResourceInterface {
public _meta: {
self: string,
selfUrl: string,
load: Promise<ResourceInterface>
loading: boolean
}
Expand Down Expand Up @@ -65,7 +66,8 @@ class Resource implements ResourceInterface {
this._meta = {
...storeData._meta,
load: loadResource,
self: this.config.apiRoot + storeData._meta.self
self: storeData._meta.self,
selfUrl: this.config.apiRoot + storeData._meta.self
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/ResourceCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ResourceCreator {
// Resource is loading --> return LoadingResource
if (meta.loading) {
const loadResource = (meta.load as Promise<StoreData>).then(storeData => this.wrapData(storeData))
return new LoadingResource(loadResource, this.config.apiRoot + meta.self)
return new LoadingResource(loadResource, meta.self, this.config)

// Resource is not loading --> wrap actual data
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ function HalJsonVuex (store: Store<Record<string, State>>, axios: AxiosInstance,
if (rel.templated) {
return urltemplate.parse(rel.href).expand(templateParams)
}
return axios.defaults.baseURL + rel.href
return rel.href
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/ResourceInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { StoreData, VirtualStoreData } from './StoreData'
interface ResourceInterface {
_meta: {
self: string | null
selfUrl: string | null
load: Promise<ResourceInterface>
loading: boolean
deleting?: boolean
Expand Down
34 changes: 17 additions & 17 deletions tests/apiOperations.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ id: 1, _meta: { self: 'http://localhost/camps' } })
expect(await load).toMatchObject({ id: 1, _meta: { self: '/camps' } })
done()
})

Expand All @@ -99,7 +99,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ id: 2, _meta: { self: 'http://localhost/camps' } })
expect(await load).toMatchObject({ id: 2, _meta: { self: '/camps' } })
done()
})

Expand Down Expand Up @@ -161,14 +161,14 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ id: 1, _meta: { self: 'http://localhost/camps/1' } })
expect(vm.api.get('/camps/1')).toMatchObject({ id: 1, _meta: { self: 'http://localhost/camps/1' } })
expect(await load).toMatchObject({ id: 1, _meta: { self: '/camps/1' } })
expect(vm.api.get('/camps/1')).toMatchObject({ id: 1, _meta: { self: '/camps/1' } })
expect(vm.api.get('/campTypes/20')).toMatchObject({
id: 20,
name: 'camp',
js: true,
targetGroup: 'Kids',
_meta: { self: 'http://localhost/campTypes/20' }
_meta: { self: '/campTypes/20' }
})
done()
})
Expand Down Expand Up @@ -223,14 +223,14 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ id: 1, _meta: { self: 'http://localhost/camps/1' } })
expect(vm.api.get('/camps/1')).toMatchObject({ id: 1, _meta: { self: 'http://localhost/camps/1' } })
expect(await load).toMatchObject({ id: 1, _meta: { self: '/camps/1' } })
expect(vm.api.get('/camps/1')).toMatchObject({ id: 1, _meta: { self: '/camps/1' } })
expect(vm.api.get('/campTypes/20')).toMatchObject({
id: 20,
name: 'camp',
js: true,
targetGroup: 'Kids',
_meta: { self: 'http://localhost/campTypes/20' }
_meta: { self: '/campTypes/20' }
})
done()
})
Expand Down Expand Up @@ -268,7 +268,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ some: 'thing', _meta: { self: 'http://localhost/camps' } })
expect(await load).toMatchObject({ some: 'thing', _meta: { self: '/camps' } })
done()
})

Expand Down Expand Up @@ -303,7 +303,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(await load).toMatchObject({ some: 'thing', _meta: { self: 'http://localhost/camps' } })
expect(await load).toMatchObject({ some: 'thing', _meta: { self: '/camps' } })
done()
})

Expand Down Expand Up @@ -341,7 +341,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(hrefPromise).resolves.toEqual('http://localhost/camps/1/activities')
expect(hrefPromise).resolves.toEqual('/camps/1/activities')
done()
})

Expand All @@ -359,7 +359,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(hrefPromise).resolves.toEqual('http://localhost/camps/1/users/999')
expect(hrefPromise).resolves.toEqual('/camps/1/users/999')
done()
})

Expand All @@ -377,7 +377,7 @@ describe('Using dollar methods', () => {

// then
await letNetworkRequestFinish()
expect(hrefPromise).resolves.toEqual('http://localhost/books')
expect(hrefPromise).resolves.toEqual('/books')
done()
})

Expand Down Expand Up @@ -432,7 +432,7 @@ describe('Using dollar methods', () => {
await letNetworkRequestFinish()
const result = (await load).items
expect(result).toHaveLength(1)
expect(result[0]).toMatchObject({ id: 123, _meta: { self: 'http://localhost/items/123' } })
expect(result[0]).toMatchObject({ id: 123, _meta: { self: '/items/123' } })
done()
})

Expand Down Expand Up @@ -467,7 +467,7 @@ describe('Using dollar methods', () => {
await letNetworkRequestFinish()
const result = (await load).items
expect(result).toHaveLength(1)
expect(result[0]).toMatchObject({ id: 123, _meta: { self: 'http://localhost/items/123' } })
expect(result[0]).toMatchObject({ id: 123, _meta: { self: '/items/123' } })
done()
})

Expand Down Expand Up @@ -555,7 +555,7 @@ describe('Using dollar methods', () => {
id: 1028,
name: 'The first chapter',
_meta: {
self: 'http://localhost/chapters/1028'
self: '/chapters/1028'
}
})
done()
Expand Down Expand Up @@ -643,7 +643,7 @@ describe('Using dollar methods', () => {
id: 1028,
name: 'The first chapter',
_meta: {
self: 'http://localhost/chapters/1028'
self: '/chapters/1028'
}
})
done()
Expand Down
2 changes: 1 addition & 1 deletion tests/resources/root-with-link.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"href": "/"
},
"books": {
"href": "http://localhost/books{/id}",
"href": "/books{/id}",
"templated": true
}
}
Expand Down
8 changes: 4 additions & 4 deletions tests/resources/templated-link.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"href": "/camps/1"
},
"users": {
"href": "http://localhost/camps/1/users{/id}",
"href": "/camps/1/users{/id}",
"templated": true
}
}
Expand All @@ -24,7 +24,7 @@
"/camps/1": {
"id": 1,
"users": {
"href": "http://localhost/camps/1/users{/id}",
"href": "/camps/1/users{/id}",
"templated": true
},
"_meta": {
Expand All @@ -36,7 +36,7 @@
"/camps/1": {
"id": 1,
"users": {
"href": "http://localhost/camps/1/users{/id}",
"href": "/camps/1/users{/id}",
"templated": true
},
"_meta": {
Expand All @@ -51,4 +51,4 @@
}
}
}
}
}

0 comments on commit c73f3e3

Please sign in to comment.