Skip to content

Commit 74bb1da

Browse files
committed
Add new flag injectOptionsFromRemoteContext
Hide the new "options" arguments behind a feature flag injectOptionsFromRemoteContext that is disabled by default for backwards compatibility. Fix construction of sharedCtor remoting metadata to prevent the situation when we are configuring remoting metadata after strong-remoting has already picked up data from our parent (base) model.
1 parent 693d52f commit 74bb1da

File tree

5 files changed

+162
-80
lines changed

5 files changed

+162
-80
lines changed

lib/model.js

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,9 @@ module.exports = function(registry) {
126126
var options = this.settings;
127127
var typeName = this.modelName;
128128

129-
var remotingOptions = {};
130-
extend(remotingOptions, options.remoting || {});
131-
132-
// create a sharedClass
133-
var sharedClass = ModelCtor.sharedClass = new SharedClass(
134-
ModelCtor.modelName,
135-
ModelCtor,
136-
remotingOptions
137-
);
138-
139-
// setup a remoting type converter for this model
140-
RemoteObjects.convert(typeName, function(val) {
141-
return val ? new ModelCtor(val) : val;
142-
});
143-
144129
// support remoting prototype methods
130+
// it's important to setup this function *before* calling `new SharedClass`
131+
// otherwise remoting metadata from our base model is picked up
145132
ModelCtor.sharedCtor = function(data, id, options, fn) {
146133
var ModelCtor = this;
147134

@@ -200,19 +187,34 @@ module.exports = function(registry) {
200187
};
201188

202189
var idDesc = ModelCtor.modelName + ' id';
203-
ModelCtor.sharedCtor.accepts = [
190+
ModelCtor.sharedCtor.accepts = this._removeOptionsArgIfDisabled([
204191
{arg: 'id', type: 'any', required: true, http: {source: 'path'},
205192
description: idDesc},
206193
// {arg: 'instance', type: 'object', http: {source: 'body'}}
207194
{arg: 'options', type: 'object', http: createOptionsViaModelMethod},
208-
];
195+
]);
209196

210197
ModelCtor.sharedCtor.http = [
211198
{path: '/:id'}
212199
];
213200

214201
ModelCtor.sharedCtor.returns = {root: true};
215202

203+
var remotingOptions = {};
204+
extend(remotingOptions, options.remoting || {});
205+
206+
// create a sharedClass
207+
var sharedClass = ModelCtor.sharedClass = new SharedClass(
208+
ModelCtor.modelName,
209+
ModelCtor,
210+
remotingOptions
211+
);
212+
213+
// setup a remoting type converter for this model
214+
RemoteObjects.convert(typeName, function(val) {
215+
return val ? new ModelCtor(val) : val;
216+
});
217+
216218
// before remote hook
217219
ModelCtor.beforeRemote = function(name, fn) {
218220
var className = this.modelName;
@@ -522,10 +524,10 @@ module.exports = function(registry) {
522524
define('__get__' + relationName, {
523525
isStatic: false,
524526
http: {verb: 'get', path: '/' + pathName},
525-
accepts: [
527+
accepts: this._removeOptionsArgIfDisabled([
526528
{arg: 'refresh', type: 'boolean', http: {source: 'query'}},
527529
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
528-
],
530+
]),
529531
accessType: 'READ',
530532
description: format('Fetches belongsTo relation %s.', relationName),
531533
returns: {arg: relationName, type: modelName, root: true},
@@ -550,10 +552,10 @@ module.exports = function(registry) {
550552
define('__get__' + relationName, {
551553
isStatic: false,
552554
http: {verb: 'get', path: '/' + pathName},
553-
accepts: [
555+
accepts: this._removeOptionsArgIfDisabled([
554556
{arg: 'refresh', type: 'boolean', http: {source: 'query'}},
555557
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
556-
],
558+
]),
557559
description: format('Fetches hasOne relation %s.', relationName),
558560
accessType: 'READ',
559561
returns: {arg: relationName, type: relation.modelTo.modelName, root: true},
@@ -563,13 +565,13 @@ module.exports = function(registry) {
563565
define('__create__' + relationName, {
564566
isStatic: false,
565567
http: {verb: 'post', path: '/' + pathName},
566-
accepts: [
568+
accepts: this._removeOptionsArgIfDisabled([
567569
{
568570
arg: 'data', type: 'object', model: toModelName,
569571
http: {source: 'body'},
570572
},
571573
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
572-
],
574+
]),
573575
description: format('Creates a new instance in %s of this model.', relationName),
574576
accessType: 'WRITE',
575577
returns: {arg: 'data', type: toModelName, root: true}
@@ -578,13 +580,13 @@ module.exports = function(registry) {
578580
define('__update__' + relationName, {
579581
isStatic: false,
580582
http: {verb: 'put', path: '/' + pathName},
581-
accepts: [
583+
accepts: this._removeOptionsArgIfDisabled([
582584
{
583585
arg: 'data', type: 'object', model: toModelName,
584586
http: {source: 'body'},
585587
},
586588
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
587-
],
589+
]),
588590
description: format('Update %s of this model.', relationName),
589591
accessType: 'WRITE',
590592
returns: {arg: 'data', type: toModelName, root: true}
@@ -593,9 +595,9 @@ module.exports = function(registry) {
593595
define('__destroy__' + relationName, {
594596
isStatic: false,
595597
http: {verb: 'delete', path: '/' + pathName},
596-
accepts: [
598+
accepts: this._removeOptionsArgIfDisabled([
597599
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
598-
],
600+
]),
599601
description: format('Deletes %s of this model.', relationName),
600602
accessType: 'WRITE',
601603
});
@@ -609,15 +611,15 @@ module.exports = function(registry) {
609611
define('__findById__' + relationName, {
610612
isStatic: false,
611613
http: {verb: 'get', path: '/' + pathName + '/:fk'},
612-
accepts: [
614+
accepts: this._removeOptionsArgIfDisabled([
613615
{
614616
arg: 'fk', type: 'any',
615617
description: format('Foreign key for %s', relationName),
616618
required: true,
617619
http: {source: 'path'},
618620
},
619621
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
620-
],
622+
]),
621623
description: format('Find a related item by id for %s.', relationName),
622624
accessType: 'READ',
623625
returns: {arg: 'result', type: toModelName, root: true},
@@ -628,15 +630,15 @@ module.exports = function(registry) {
628630
define('__destroyById__' + relationName, {
629631
isStatic: false,
630632
http: {verb: 'delete', path: '/' + pathName + '/:fk'},
631-
accepts: [
633+
accepts: this._removeOptionsArgIfDisabled([
632634
{
633635
arg: 'fk', type: 'any',
634636
description: format('Foreign key for %s', relationName),
635637
required: true,
636638
http: {source: 'path'},
637639
},
638640
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
639-
],
641+
]),
640642
description: format('Delete a related item by id for %s.', relationName),
641643
accessType: 'WRITE',
642644
returns: []
@@ -646,14 +648,14 @@ module.exports = function(registry) {
646648
define('__updateById__' + relationName, {
647649
isStatic: false,
648650
http: {verb: 'put', path: '/' + pathName + '/:fk'},
649-
accepts: [
651+
accepts: this._removeOptionsArgIfDisabled([
650652
{arg: 'fk', type: 'any',
651653
description: format('Foreign key for %s', relationName),
652654
required: true,
653655
http: { source: 'path' }},
654656
{arg: 'data', type: 'object', model: toModelName, http: {source: 'body'}},
655657
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
656-
],
658+
]),
657659
description: format('Update a related item by id for %s.', relationName),
658660
accessType: 'WRITE',
659661
returns: {arg: 'result', type: toModelName, root: true}
@@ -676,9 +678,9 @@ module.exports = function(registry) {
676678
description: format('Foreign key for %s', relationName),
677679
required: true,
678680
http: {source: 'path'}},
679-
].concat(accepts).concat([
681+
].concat(accepts).concat(this._removeOptionsArgIfDisabled([
680682
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
681-
]),
683+
])),
682684
description: format('Add a related item by id for %s.', relationName),
683685
accessType: 'WRITE',
684686
returns: {arg: relationName, type: modelThrough.modelName, root: true}
@@ -688,15 +690,15 @@ module.exports = function(registry) {
688690
define('__unlink__' + relationName, {
689691
isStatic: false,
690692
http: {verb: 'delete', path: '/' + pathName + '/rel/:fk'},
691-
accepts: [
693+
accepts: this._removeOptionsArgIfDisabled([
692694
{
693695
arg: 'fk', type: 'any',
694696
description: format('Foreign key for %s', relationName),
695697
required: true,
696698
http: {source: 'path'},
697699
},
698700
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
699-
],
701+
]),
700702
description: format('Remove the %s relation to an item by id.', relationName),
701703
accessType: 'WRITE',
702704
returns: []
@@ -708,15 +710,15 @@ module.exports = function(registry) {
708710
define('__exists__' + relationName, {
709711
isStatic: false,
710712
http: {verb: 'head', path: '/' + pathName + '/rel/:fk'},
711-
accepts: [
713+
accepts: this._removeOptionsArgIfDisabled([
712714
{
713715
arg: 'fk', type: 'any',
714716
description: format('Foreign key for %s', relationName),
715717
required: true,
716718
http: {source: 'path'},
717719
},
718720
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
719-
],
721+
]),
720722
description: format('Check the existence of %s relation to an item by id.', relationName),
721723
accessType: 'READ',
722724
returns: {arg: 'exists', type: 'boolean', root: true},
@@ -759,10 +761,10 @@ module.exports = function(registry) {
759761
define('__get__' + scopeName, {
760762
isStatic: isStatic,
761763
http: {verb: 'get', path: '/' + pathName},
762-
accepts: [
764+
accepts: this._removeOptionsArgIfDisabled([
763765
{arg: 'filter', type: 'object'},
764766
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
765-
],
767+
]),
766768
description: format('Queries %s of %s.', scopeName, this.modelName),
767769
accessType: 'READ',
768770
returns: {arg: scopeName, type: [toModelName], root: true}
@@ -771,15 +773,15 @@ module.exports = function(registry) {
771773
define('__create__' + scopeName, {
772774
isStatic: isStatic,
773775
http: {verb: 'post', path: '/' + pathName},
774-
accepts: [
776+
accepts: this._removeOptionsArgIfDisabled([
775777
{
776778
arg: 'data',
777779
type: 'object',
778780
model: toModelName,
779781
http: {source: 'body'},
780782
},
781783
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
782-
],
784+
]),
783785
description: format('Creates a new instance in %s of this model.', scopeName),
784786
accessType: 'WRITE',
785787
returns: {arg: 'data', type: toModelName, root: true}
@@ -788,7 +790,7 @@ module.exports = function(registry) {
788790
define('__delete__' + scopeName, {
789791
isStatic: isStatic,
790792
http: {verb: 'delete', path: '/' + pathName},
791-
accepts: [
793+
accepts: this._removeOptionsArgIfDisabled([
792794
{
793795
arg: 'where', type: 'object',
794796
// The "where" argument is not exposed in the REST API
@@ -797,28 +799,37 @@ module.exports = function(registry) {
797799
http: function(ctx) { return undefined; },
798800
},
799801
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
800-
],
802+
]),
801803
description: format('Deletes all %s of this model.', scopeName),
802804
accessType: 'WRITE',
803805
});
804806

805807
define('__count__' + scopeName, {
806808
isStatic: isStatic,
807809
http: {verb: 'get', path: '/' + pathName + '/count'},
808-
accepts: [
810+
accepts: this._removeOptionsArgIfDisabled([
809811
{
810812
arg: 'where', type: 'object',
811813
description: 'Criteria to match model instances',
812814
},
813815
{arg: 'options', type: 'object', http: 'optionsFromRequest'},
814-
],
816+
]),
815817
description: format('Counts %s of %s.', scopeName, this.modelName),
816818
accessType: 'READ',
817819
returns: {arg: 'count', type: 'number'}
818820
});
819821

820822
};
821823

824+
Model._removeOptionsArgIfDisabled = function(accepts) {
825+
if (this.settings.injectOptionsFromRemoteContext)
826+
return accepts;
827+
var lastArg = accepts[accepts.length - 1];
828+
var hasOptions = lastArg.arg === 'options' && lastArg.type === 'object';
829+
assert(hasOptions, 'last accepts argument is "options" arg');
830+
return accepts.slice(0, -1);
831+
};
832+
822833
/**
823834
* Enabled deeply-nested queries of related models via REST API.
824835
*

0 commit comments

Comments
 (0)