11import { service } from '@ember-decorators/service' ;
2+ import { assert } from '@ember/debug' ;
23import { underscore } from '@ember/string' ;
34import DS from 'ember-data' ;
45import config from 'ember-get-config' ;
@@ -39,9 +40,29 @@ enum RequestType {
3940 * @extends DS.JSONAPIAdapter
4041 * @uses GenericDataAdapterMixin
4142 */
42- export default class OsfAdapter extends JSONAPIAdapter . extend ( {
43- host,
44- namespace,
43+ export default class OsfAdapter extends JSONAPIAdapter {
44+ @service session ! : Session ;
45+ @service currentUser ! : CurrentUser ;
46+
47+ host = host ;
48+ namespace = namespace ;
49+
50+ /**
51+ * When an object lives "under" another in the API, set `parentRelationship` to the name of
52+ * the belongsTo that points to the parent object. Requests for creating new children will
53+ * go to the nested route for that relationship.
54+ *
55+ * e.g. If the contributor adapter has `parentRelationship = 'node'`, creating a new contributor
56+ * for node xyz will POST to /v2/nodes/xyz/contributors/
57+ *
58+ * TODO: `OsfAdapter<M extends OsfModel>`, `parentRelationship: RelationshipsFor<M> | null`
59+ */
60+ parentRelationship : string | null = null ;
61+
62+ get headers ( ) {
63+ // Not a computed; evaluate every time in case something changes
64+ return this . currentUser . ajaxHeaders ( ) ;
65+ }
4566
4667 /**
4768 * Overrides buildQuery method - Allows users to embed resources with findRecord
@@ -51,11 +72,11 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
5172 *
5273 * @method buildQuery
5374 */
54- buildQuery ( this : OsfAdapter , snapshot : DS . Snapshot ) : object {
75+ buildQuery ( snapshot : DS . Snapshot ) : object {
5576 const { query : adapterOptionsQuery = { } } = ( snapshot . adapterOptions || { } ) as AdapterOptions ;
5677
5778 const query : { include ?: any , embed ?: any } = {
58- ...this . _super ( snapshot ) ,
79+ ...super . buildQuery ( snapshot ) ,
5980 ...adapterOptionsQuery ,
6081 } ;
6182
@@ -64,32 +85,21 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
6485 embed : query . include ,
6586 include : undefined ,
6687 } ;
67- } ,
88+ }
6889
6990 buildURL (
70- this : OsfAdapter ,
71- modelName : string ,
91+ modelName : string | undefined ,
7292 id : string | null ,
7393 snapshot : DS . Snapshot | null ,
7494 requestType : string ,
95+ query ?: { } ,
7596 ) : string {
76- let url : string = this . _super ( modelName , id , snapshot , requestType ) ;
97+ let url : string = super . buildURL ( modelName , id , snapshot , requestType , query ) ;
7798
7899 if ( snapshot ) {
79- const { record, adapterOptions } = snapshot ;
80- const opts : AdapterOptions = adapterOptions || { } ;
81- if ( requestType === 'deleteRecord' ) {
82- if ( record && record . get ( 'links.delete' ) ) {
83- url = record . get ( 'links.delete' ) ;
84- } else if ( record && record . get ( 'links.self' ) ) {
85- url = record . get ( 'links.self' ) ;
86- }
87- } else if ( requestType === 'updateRecord' || requestType === 'findRecord' ) {
88- if ( record && record . get ( 'links.self' ) ) {
89- url = record . get ( 'links.self' ) ;
90- }
91- } else if ( opts . url ) {
92- url = opts . url ; // eslint-disable-line prefer-destructuring
100+ const { adapterOptions } : { adapterOptions ?: { url ?: string } } = snapshot ;
101+ if ( adapterOptions && adapterOptions . url ) {
102+ url = adapterOptions . url ; // eslint-disable-line prefer-destructuring
93103 }
94104 }
95105
@@ -98,11 +108,51 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
98108 if ( url . lastIndexOf ( '/' ) !== url . length - 1 ) {
99109 url += '/' ;
100110 }
111+
101112 return url ;
102- } ,
113+ }
114+
115+ urlForFindRecord ( id : string , modelName : string , snapshot : DS . Snapshot ) : string {
116+ if ( snapshot && snapshot . record && snapshot . record . links && snapshot . record . links . self ) {
117+ return snapshot . record . links . self ;
118+ }
119+ return super . urlForFindRecord ( id , modelName , snapshot ) ;
120+ }
121+
122+ urlForCreateRecord ( modelName : string , snapshot : DS . Snapshot ) : string {
123+ const { parentRelationship } = this ;
124+ if ( ! parentRelationship ) {
125+ return super . urlForCreateRecord ( modelName , snapshot ) ;
126+ }
103127
104- ajaxOptions ( this : OsfAdapter , url : string , type : RequestType , options ?: { isBulk ?: boolean } ) : object {
105- const hash = this . _super ( url , type , options ) ;
128+ const parentObj = snapshot . record . belongsTo ( parentRelationship ) . value ( ) ;
129+ const inverseRelation : string = snapshot . record . inverseFor ( parentRelationship ) . name ;
130+
131+ assert ( 'To create a nested object, the parent must already be loaded.' , parentObj ) ;
132+
133+ const url = parentObj . get ( `links.relationships.${ inverseRelation } .links.related.href` ) ;
134+
135+ assert ( `Couldn't find create link for nested ${ modelName } ` , url ) ;
136+
137+ return url ;
138+ }
139+
140+ urlForUpdateRecord ( id : string , modelName : string , snapshot : DS . Snapshot ) : string {
141+ const { links } = snapshot . record ;
142+ if ( links && links . self ) {
143+ return links . self ;
144+ }
145+ return super . urlForUpdateRecord ( id , modelName , snapshot ) ;
146+ }
147+
148+ urlForDeleteRecord ( id : string , modelName : string , snapshot : DS . Snapshot ) : string {
149+ const { links } = snapshot . record ;
150+ const url = links . delete || links . self ;
151+ return url || super . urlForDeleteRecord ( id , modelName , snapshot ) ;
152+ }
153+
154+ ajaxOptions ( url : string , type : RequestType , options ?: { isBulk ?: boolean } ) : object {
155+ const hash : any = super . ajaxOptions ( url , type , options ) ;
106156
107157 hash . xhrFields = {
108158 withCredentials : true ,
@@ -113,7 +163,7 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
113163 }
114164
115165 return hash ;
116- } ,
166+ }
117167
118168 buildRelationshipURL ( snapshot : DS . Snapshot , relationship : string ) : string {
119169 const links = ! ! relationship && snapshot . record . get ( `relationshipLinks.${ underscore ( relationship ) } .links` ) ;
@@ -123,19 +173,11 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
123173 }
124174
125175 return '' ;
126- } ,
176+ }
127177
128178 pathForType ( modelName : string ) : string {
129179 const underscored : string = underscore ( modelName ) ;
130180 return pluralize ( underscored ) ;
131- } ,
132- } ) {
133- @service session ! : Session ;
134- @service currentUser ! : CurrentUser ;
135-
136- get headers ( ) {
137- // Not a computed; evaluate every time in case something changes
138- return this . currentUser . ajaxHeaders ( ) ;
139181 }
140182
141183 handleResponse (
0 commit comments