ember-source 4.3.0-alpha.3 → 4.4.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +6 -2
  2. package/blueprints/acceptance-test/mocha-files/tests/acceptance/__name__-test.js +4 -4
  3. package/blueprints/acceptance-test/mocha-rfc-232-files/tests/acceptance/__name__-test.js +2 -2
  4. package/blueprints/acceptance-test/qunit-files/tests/acceptance/__name__-test.js +2 -2
  5. package/blueprints/acceptance-test/qunit-rfc-232-files/tests/acceptance/__name__-test.js +2 -2
  6. package/blueprints/component/index.js +2 -2
  7. package/blueprints/component-class/index.js +2 -2
  8. package/blueprints/component-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +4 -4
  9. package/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.js +7 -5
  10. package/blueprints/component-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +4 -4
  11. package/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.js +4 -4
  12. package/blueprints/component-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +4 -4
  13. package/blueprints/controller/files/__root__/__path__/__name__.js +1 -2
  14. package/blueprints/controller-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  15. package/blueprints/controller-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  16. package/blueprints/controller-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  17. package/blueprints/controller-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  18. package/blueprints/controller-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  19. package/blueprints/helper/files/__root__/__collection__/__name__.js +1 -1
  20. package/blueprints/helper/mu-files/__root__/__collection__/__name__.js +1 -1
  21. package/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +3 -3
  22. package/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +6 -4
  23. package/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +2 -2
  24. package/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +2 -2
  25. package/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +2 -2
  26. package/blueprints/initializer/files/__root__/initializers/__name__.js +2 -3
  27. package/blueprints/initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +6 -7
  28. package/blueprints/initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  29. package/blueprints/initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +3 -4
  30. package/blueprints/instance-initializer/files/__root__/instance-initializers/__name__.js +2 -3
  31. package/blueprints/instance-initializer-test/mocha-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  32. package/blueprints/instance-initializer-test/mocha-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +5 -5
  33. package/blueprints/instance-initializer-test/qunit-files/__root__/__testType__/__path__/__name__-test.js +2 -2
  34. package/blueprints/mixin/files/__root__/mixins/__name__.js +1 -2
  35. package/blueprints/mixin-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
  36. package/blueprints/mixin-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
  37. package/blueprints/mixin-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
  38. package/blueprints/mixin-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +1 -1
  39. package/blueprints/route/files/__root__/__path__/__name__.js +2 -2
  40. package/blueprints/route-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  41. package/blueprints/route-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  42. package/blueprints/route-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  43. package/blueprints/route-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  44. package/blueprints/route-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  45. package/blueprints/service/files/__root__/__path__/__name__.js +1 -2
  46. package/blueprints/service-test/mocha-0.12-files/__root__/__testType__/__path__/__test__.js +2 -2
  47. package/blueprints/service-test/mocha-files/__root__/__testType__/__path__/__test__.js +5 -3
  48. package/blueprints/service-test/mocha-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  49. package/blueprints/service-test/qunit-files/__root__/__testType__/__path__/__test__.js +1 -1
  50. package/blueprints/service-test/qunit-rfc-232-files/__root__/__testType__/__path__/__test__.js +2 -2
  51. package/blueprints/util-test/mocha-files/__root__/__testType__/__name__-test.js +2 -2
  52. package/blueprints/util-test/mocha-rfc-232-files/__root__/__testType__/__name__-test.js +2 -2
  53. package/blueprints/util-test/qunit-files/__root__/__testType__/__name__-test.js +1 -1
  54. package/blueprints/util-test/qunit-rfc-232-files/__root__/__testType__/__name__-test.js +2 -3
  55. package/build-metadata.json +3 -3
  56. package/dist/dependencies/router_js.js +67 -32
  57. package/dist/ember-template-compiler.js +1168 -908
  58. package/dist/ember-template-compiler.map +1 -1
  59. package/dist/ember-testing.js +76 -43
  60. package/dist/ember-testing.map +1 -1
  61. package/dist/ember.debug.js +3206 -2734
  62. package/dist/ember.debug.map +1 -1
  63. package/dist/header/license.js +1 -1
  64. package/dist/packages/@ember/-internals/container/index.js +18 -13
  65. package/dist/packages/@ember/-internals/glimmer/index.js +128 -67
  66. package/dist/packages/@ember/-internals/meta/lib/meta.js +8 -9
  67. package/dist/packages/@ember/-internals/metal/index.js +58 -61
  68. package/dist/packages/@ember/-internals/routing/lib/ext/controller.js +10 -8
  69. package/dist/packages/@ember/-internals/routing/lib/services/router.js +155 -191
  70. package/dist/packages/@ember/-internals/routing/lib/services/routing.js +2 -0
  71. package/dist/packages/@ember/-internals/routing/lib/system/generate_controller.js +3 -1
  72. package/dist/packages/@ember/-internals/routing/lib/system/route-info.js +2 -2
  73. package/dist/packages/@ember/-internals/routing/lib/system/route.js +108 -380
  74. package/dist/packages/@ember/-internals/routing/lib/system/router.js +65 -46
  75. package/dist/packages/@ember/-internals/routing/lib/utils.js +33 -21
  76. package/dist/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +32 -32
  77. package/dist/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +29 -29
  78. package/dist/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +51 -50
  79. package/dist/packages/@ember/-internals/utils/index.js +3 -1
  80. package/dist/packages/@ember/-internals/views/lib/system/utils.js +1 -0
  81. package/dist/packages/@ember/application/instance.js +3 -3
  82. package/dist/packages/@ember/canary-features/index.js +0 -10
  83. package/dist/packages/@ember/controller/index.js +3 -54
  84. package/dist/packages/@ember/debug/lib/capture-render-tree.js +2 -0
  85. package/dist/packages/@ember/instrumentation/index.js +9 -13
  86. package/dist/packages/@ember/routing/router-service.js +1 -0
  87. package/dist/packages/@ember/service/index.js +6 -73
  88. package/dist/packages/ember/index.js +3 -14
  89. package/dist/packages/ember/version.js +1 -1
  90. package/docs/data.json +556 -504
  91. package/package.json +13 -13
@@ -9,74 +9,99 @@ var __decorate = this && this.__decorate || function (decorators, target, key, d
9
9
  import { privatize as P } from '@ember/-internals/container';
10
10
  import { addObserver, computed, defineProperty, descriptorForProperty, flushAsyncObservers, get, getProperties, isEmpty, set, setProperties } from '@ember/-internals/metal';
11
11
  import { getOwner } from '@ember/-internals/owner';
12
+ import { BucketCache } from '@ember/-internals/routing';
12
13
  import { A as emberA, ActionHandler, Evented, Object as EmberObject, typeOf } from '@ember/-internals/runtime';
13
14
  import { isProxy, lookupDescriptor, symbol } from '@ember/-internals/utils';
15
+ import Controller from '@ember/controller';
14
16
  import { assert, info, isTesting } from '@ember/debug';
17
+ import EngineInstance from '@ember/engine/instance';
15
18
  import { dependentKeyCompat } from '@ember/object/compat';
16
19
  import { once } from '@ember/runloop';
17
20
  import { DEBUG } from '@glimmer/env';
18
21
  import { PARAMS_SYMBOL, STATE_SYMBOL } from 'router_js';
19
22
  import { calculateCacheKey, deprecateTransitionMethods, normalizeControllerQueryParams, prefixRouteNameArg, stashParamNames } from '../utils';
20
23
  import generateController from './generate_controller';
24
+ import EmberRouter from './router';
21
25
  export const ROUTE_CONNECTIONS = new WeakMap();
22
26
  const RENDER = symbol('render');
23
- export function defaultSerialize(model, params) {
24
- if (params.length < 1 || !model) {
25
- return;
26
- }
27
-
28
- let object = {};
29
-
30
- if (params.length === 1) {
31
- let [name] = params;
32
-
33
- if (name in model) {
34
- object[name] = get(model, name);
35
- } else if (/_id$/.test(name)) {
36
- object[name] = get(model, 'id');
37
- } else if (isProxy(model)) {
38
- object[name] = get(model, name);
39
- }
40
- } else {
41
- object = getProperties(model, params);
42
- }
43
-
44
- return object;
45
- }
46
- export function hasDefaultSerialize(route) {
47
- return route.serialize === defaultSerialize;
48
- }
49
- /**
50
- @module @ember/routing
51
- */
52
-
53
- /**
54
- The `Route` class is used to define individual routes. Refer to
55
- the [routing guide](https://guides.emberjs.com/release/routing/) for documentation.
56
-
57
- @class Route
58
- @extends EmberObject
59
- @uses ActionHandler
60
- @uses Evented
61
- @since 1.0.0
62
- @public
63
- */
64
27
 
65
28
  class Route extends EmberObject.extend(ActionHandler, Evented) {
66
29
  constructor(owner) {
67
- super(...arguments);
30
+ super(owner);
68
31
  this.context = {};
69
32
 
70
33
  if (owner) {
71
34
  let router = owner.lookup('router:main');
72
35
  let bucketCache = owner.lookup(P`-bucket-cache:main`);
73
- assert('ROUTER BUG: Expected route injections to be defined on the route. This is an internal bug, please open an issue on Github if you see this message!', router && bucketCache);
36
+ assert('ROUTER BUG: Expected route injections to be defined on the route. This is an internal bug, please open an issue on Github if you see this message!', router instanceof EmberRouter && bucketCache instanceof BucketCache);
74
37
  this._router = router;
75
38
  this._bucketCache = bucketCache;
76
39
  this._topLevelViewTemplate = owner.lookup('template:-outlet');
77
40
  this._environment = owner.lookup('-environment:main');
78
41
  }
79
42
  }
43
+ /**
44
+ A hook you can implement to convert the route's model into parameters
45
+ for the URL.
46
+ ```app/router.js
47
+ // ...
48
+ Router.map(function() {
49
+ this.route('post', { path: '/posts/:post_id' });
50
+ });
51
+ ```
52
+ ```app/routes/post.js
53
+ import Route from '@ember/routing/route';
54
+ export default class PostRoute extends Route {
55
+ model({ post_id }) {
56
+ // the server returns `{ id: 12 }`
57
+ return fetch(`/posts/${post_id}`;
58
+ }
59
+ serialize(model) {
60
+ // this will make the URL `/posts/12`
61
+ return { post_id: model.id };
62
+ }
63
+ }
64
+ ```
65
+ The default `serialize` method will insert the model's `id` into the
66
+ route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'.
67
+ If the route has multiple dynamic segments or does not contain '_id', `serialize`
68
+ will return `getProperties(model, params)`
69
+ This method is called when `transitionTo` is called with a context
70
+ in order to populate the URL.
71
+ @method serialize
72
+ @param {Object} model the routes model
73
+ @param {Array} params an Array of parameter names for the current
74
+ route (in the example, `['post_id']`.
75
+ @return {Object} the serialized parameters
76
+ @since 1.0.0
77
+ @public
78
+ */
79
+
80
+
81
+ serialize(model, params) {
82
+ if (params.length < 1 || !model) {
83
+ return;
84
+ }
85
+
86
+ let object = {};
87
+
88
+ if (params.length === 1) {
89
+ let [name] = params;
90
+ assert('has name', name);
91
+
92
+ if (name in model) {
93
+ object[name] = get(model, name);
94
+ } else if (/_id$/.test(name)) {
95
+ object[name] = get(model, 'id');
96
+ } else if (isProxy(model)) {
97
+ object[name] = get(model, name);
98
+ }
99
+ } else {
100
+ object = getProperties(model, params);
101
+ }
102
+
103
+ return object;
104
+ }
80
105
  /**
81
106
  Sets the name for this route, including a fully resolved name for routes
82
107
  inside engines.
@@ -89,7 +114,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
89
114
  _setRouteName(name) {
90
115
  this.routeName = name;
91
116
  let owner = getOwner(this);
92
- assert('Route is unexpectedly missing an owner', owner);
117
+ assert('Expected route to have EngineInstance as owner', owner instanceof EngineInstance);
93
118
  this.fullRouteName = getEngineRouteName(owner, name);
94
119
  }
95
120
  /**
@@ -118,9 +143,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
118
143
  namePaths[a] = `${routeInfo.name}.${names[a]}`;
119
144
  }
120
145
 
121
- for (let i = 0; i < qps.length; ++i) {
122
- let qp = qps[i];
123
-
146
+ for (let qp of qps) {
124
147
  if (qp.scope === 'model') {
125
148
  qp.parts = namePaths;
126
149
  }
@@ -203,9 +226,9 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
203
226
  let fullName = route.fullRouteName;
204
227
  let params = Object.assign({}, state.params[fullName]);
205
228
  let queryParams = getQueryParamsFor(route, state);
206
- return Object.keys(queryParams).reduce((params, key) => {
229
+ return Object.entries(queryParams).reduce((params, [key, value]) => {
207
230
  assert(`The route '${this.routeName}' has both a dynamic segment and query param with name '${key}'. Please rename one to avoid collisions.`, !params[key]);
208
- params[key] = queryParams[key];
231
+ params[key] = value;
209
232
  return params;
210
233
  }, params);
211
234
  }
@@ -322,148 +345,6 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
322
345
  this.activate(transition);
323
346
  this.trigger('activate', transition);
324
347
  }
325
- /**
326
- The `willTransition` action is fired at the beginning of any
327
- attempted transition with a `Transition` object as the sole
328
- argument. This action can be used for aborting, redirecting,
329
- or decorating the transition from the currently active routes.
330
- A good example is preventing navigation when a form is
331
- half-filled out:
332
- ```app/routes/contact-form.js
333
- import Route from '@ember/routing/route';
334
- import { action } from '@ember/object';
335
- export default class ContactFormRoute extends Route {
336
- @action
337
- willTransition(transition) {
338
- if (this.controller.get('userHasEnteredData')) {
339
- this.controller.displayNavigationConfirm();
340
- transition.abort();
341
- }
342
- }
343
- }
344
- ```
345
- You can also redirect elsewhere by calling
346
- `this.transitionTo('elsewhere')` from within `willTransition`.
347
- Note that `willTransition` will not be fired for the
348
- redirecting `transitionTo`, since `willTransition` doesn't
349
- fire when there is already a transition underway. If you want
350
- subsequent `willTransition` actions to fire for the redirecting
351
- transition, you must first explicitly call
352
- `transition.abort()`.
353
- To allow the `willTransition` event to continue bubbling to the parent
354
- route, use `return true;`. When the `willTransition` method has a
355
- return value of `true` then the parent route's `willTransition` method
356
- will be fired, enabling "bubbling" behavior for the event.
357
- @event willTransition
358
- @param {Transition} transition
359
- @since 1.0.0
360
- @public
361
- */
362
-
363
- /**
364
- The `didTransition` action is fired after a transition has
365
- successfully been completed. This occurs after the normal model
366
- hooks (`beforeModel`, `model`, `afterModel`, `setupController`)
367
- have resolved. The `didTransition` action has no arguments,
368
- however, it can be useful for tracking page views or resetting
369
- state on the controller.
370
- ```app/routes/login.js
371
- import Route from '@ember/routing/route';
372
- import { action } from '@ember/object';
373
- export default class LoginRoute extends Route {
374
- @action
375
- didTransition() {
376
- this.controller.get('errors.base').clear();
377
- return true; // Bubble the didTransition event
378
- }
379
- }
380
- ```
381
- @event didTransition
382
- @since 1.2.0
383
- @public
384
- */
385
-
386
- /**
387
- The `loading` action is fired on the route when a route's `model`
388
- hook returns a promise that is not already resolved. The current
389
- `Transition` object is the first parameter and the route that
390
- triggered the loading event is the second parameter.
391
- ```app/routes/application.js
392
- import Route from '@ember/routing/route';
393
- import { action } from '@ember/object';
394
- export default class ApplicationRoute extends Route {
395
- @action
396
- loading(transition, route) {
397
- let controller = this.controllerFor('foo');
398
- // The controller may not be instantiated when initially loading
399
- if (controller) {
400
- controller.currentlyLoading = true;
401
- transition.finally(function() {
402
- controller.currentlyLoading = false;
403
- });
404
- }
405
- }
406
- }
407
- ```
408
- @event loading
409
- @param {Transition} transition
410
- @param {Route} route The route that triggered the loading event
411
- @since 1.2.0
412
- @public
413
- */
414
-
415
- /**
416
- When attempting to transition into a route, any of the hooks
417
- may return a promise that rejects, at which point an `error`
418
- action will be fired on the partially-entered routes, allowing
419
- for per-route error handling logic, or shared error handling
420
- logic defined on a parent route.
421
- Here is an example of an error handler that will be invoked
422
- for rejected promises from the various hooks on the route,
423
- as well as any unhandled errors from child routes:
424
- ```app/routes/admin.js
425
- import { reject } from 'rsvp';
426
- import Route from '@ember/routing/route';
427
- import { action } from '@ember/object';
428
- export default class AdminRoute extends Route {
429
- beforeModel() {
430
- return reject('bad things!');
431
- }
432
- @action
433
- error(error, transition) {
434
- // Assuming we got here due to the error in `beforeModel`,
435
- // we can expect that error === "bad things!",
436
- // but a promise model rejecting would also
437
- // call this hook, as would any errors encountered
438
- // in `afterModel`.
439
- // The `error` hook is also provided the failed
440
- // `transition`, which can be stored and later
441
- // `.retry()`d if desired.
442
- this.transitionTo('login');
443
- }
444
- }
445
- ```
446
- `error` actions that bubble up all the way to `ApplicationRoute`
447
- will fire a default error handler that logs the error. You can
448
- specify your own global default error handler by overriding the
449
- `error` handler on `ApplicationRoute`:
450
- ```app/routes/application.js
451
- import Route from '@ember/routing/route';
452
- import { action } from '@ember/object';
453
- export default class ApplicationRoute extends Route {
454
- @action
455
- error(error, transition) {
456
- this.controllerFor('banner').displayError(error.message);
457
- }
458
- }
459
- ```
460
- @event error
461
- @param {Error} error
462
- @param {Transition} transition
463
- @since 1.0.0
464
- @public
465
- */
466
-
467
348
  /**
468
349
  This event is triggered when the router enters the route. It is
469
350
  not executed when the model for the route changes.
@@ -774,14 +655,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
774
655
  setup(context, transition) {
775
656
  let controllerName = this.controllerName || this.routeName;
776
657
  let definedController = this.controllerFor(controllerName, true);
777
- let controller;
778
-
779
- if (definedController) {
780
- controller = definedController;
781
- } else {
782
- controller = this.generateController(controllerName);
783
- } // SAFETY: Since `_qp` is protected we can't infer the type
784
-
658
+ let controller = definedController !== null && definedController !== void 0 ? definedController : this.generateController(controllerName); // SAFETY: Since `_qp` is protected we can't infer the type
785
659
 
786
660
  let queryParams = get(this, '_qp'); // Assign the route's controller so that it can more easily be
787
661
  // referenced in action handlers. Side effects. Side effects everywhere.
@@ -803,6 +677,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
803
677
  let allParams = queryParams.propertyNames;
804
678
  allParams.forEach(prop => {
805
679
  let aQp = queryParams.map[prop];
680
+ assert('expected aQp', aQp);
806
681
  aQp.values = params;
807
682
  let cacheKey = calculateCacheKey(aQp.route.fullRouteName, aQp.parts, aQp.values);
808
683
  let value = cache.lookup(cacheKey, prop, aQp.undecoratedDefaultValue);
@@ -839,71 +714,10 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
839
714
  let cacheKey = calculateCacheKey(qp.route.fullRouteName, qp.parts, qp.values);
840
715
  cache.stash(cacheKey, prop, value);
841
716
  }
842
- /**
843
- This hook is the first of the route entry validation hooks
844
- called when an attempt is made to transition into a route
845
- or one of its children. It is called before `model` and
846
- `afterModel`, and is appropriate for cases when:
847
- 1) A decision can be made to redirect elsewhere without
848
- needing to resolve the model first.
849
- 2) Any async operations need to occur first before the
850
- model is attempted to be resolved.
851
- This hook is provided the current `transition` attempt
852
- as a parameter, which can be used to `.abort()` the transition,
853
- save it for a later `.retry()`, or retrieve values set
854
- on it from a previous hook. You can also just call
855
- `this.transitionTo` to another route to implicitly
856
- abort the `transition`.
857
- You can return a promise from this hook to pause the
858
- transition until the promise resolves (or rejects). This could
859
- be useful, for instance, for retrieving async code from
860
- the server that is required to enter a route.
861
- @method beforeModel
862
- @param {Transition} transition
863
- @return {any | Promise<any>} if the value returned from this hook is
864
- a promise, the transition will pause until the transition
865
- resolves. Otherwise, non-promise return values are not
866
- utilized in any way.
867
- @since 1.0.0
868
- @public
869
- */
870
-
871
-
872
- beforeModel() {}
873
- /**
874
- This hook is called after this route's model has resolved.
875
- It follows identical async/promise semantics to `beforeModel`
876
- but is provided the route's resolved model in addition to
877
- the `transition`, and is therefore suited to performing
878
- logic that can only take place after the model has already
879
- resolved.
880
- ```app/routes/posts.js
881
- import Route from '@ember/routing/route';
882
- export default class PostsRoute extends Route {
883
- afterModel(posts, transition) {
884
- if (posts.get('length') === 1) {
885
- this.transitionTo('post.show', posts.get('firstObject'));
886
- }
887
- }
888
- }
889
- ```
890
- Refer to documentation for `beforeModel` for a description
891
- of transition-pausing semantics when a promise is returned
892
- from this hook.
893
- @method afterModel
894
- @param {Object} resolvedModel the value returned from `model`,
895
- or its resolved value if it was a promise
896
- @param {Transition} transition
897
- @return {any | Promise<any>} if the value returned from this hook is
898
- a promise, the transition will pause until the transition
899
- resolves. Otherwise, non-promise return values are not
900
- utilized in any way.
901
- @since 1.0.0
902
- @public
903
- */
904
717
 
718
+ beforeModel(_transition) {}
905
719
 
906
- afterModel() {}
720
+ afterModel(_resolvedModel, _transition) {}
907
721
  /**
908
722
  A hook you can implement to optionally redirect to another route.
909
723
  Calling `this.transitionTo` from inside of the `redirect` hook will
@@ -926,7 +740,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
926
740
  */
927
741
 
928
742
 
929
- redirect() {}
743
+ redirect(_model, _transition) {}
930
744
  /**
931
745
  Called when the context is changed by router.js.
932
746
  @private
@@ -1021,11 +835,13 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1021
835
 
1022
836
  if (!name) {
1023
837
  if (sawParams) {
838
+ // SAFETY: This should be equivalent
1024
839
  return Object.assign({}, params);
1025
840
  } else {
1026
841
  if (transition.resolveIndex < 1) {
1027
842
  return;
1028
- }
843
+ } // SAFETY: This should be correct, but TS is unable to infer this.
844
+
1029
845
 
1030
846
  return transition[STATE_SYMBOL].routeInfos[transition.resolveIndex - 1].context;
1031
847
  }
@@ -1116,29 +932,8 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1116
932
  set(controller, 'model', context);
1117
933
  }
1118
934
  }
1119
- /**
1120
- Returns the controller of the current route, or a parent (or any ancestor)
1121
- route in a route hierarchy.
1122
- The controller instance must already have been created, either through entering the
1123
- associated route or using `generateController`.
1124
- ```app/routes/post.js
1125
- import Route from '@ember/routing/route';
1126
- export default class PostRoute extends Route {
1127
- setupController(controller, post) {
1128
- super.setupController(controller, post);
1129
- this.controllerFor('posts').set('currentPost', post);
1130
- }
1131
- }
1132
- ```
1133
- @method controllerFor
1134
- @param {String} name the name of the route or controller
1135
- @return {Controller}
1136
- @since 1.0.0
1137
- @public
1138
- */
1139
-
1140
935
 
1141
- controllerFor(name, _skipAssert) {
936
+ controllerFor(name, _skipAssert = false) {
1142
937
  let owner = getOwner(this);
1143
938
  assert('Route is unexpectedly missing an owner', owner);
1144
939
  let route = owner.lookup(`route:${name}`);
@@ -1152,6 +947,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1152
947
  // passed a model to skip the assertion.
1153
948
 
1154
949
  assert(`The controller named '${name}' could not be found. Make sure that this route exists and has already been entered at least once. If you are accessing a controller not associated with a route, make sure the controller class is explicitly defined.`, controller !== undefined || _skipAssert === true);
950
+ assert(`Expected controller:${name} to be an instance of Controller`, controller === undefined || controller instanceof Controller);
1155
951
  return controller;
1156
952
  }
1157
953
  /**
@@ -1216,7 +1012,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1216
1012
  modelFor(_name) {
1217
1013
  let name;
1218
1014
  let owner = getOwner(this);
1219
- assert('Route is unexpectedly missing an owner', owner);
1015
+ assert('Expected router owner to be an EngineInstance', owner instanceof EngineInstance);
1220
1016
  let transition = this._router && this._router._routerMicrolib ? this._router._routerMicrolib.activeTransition : undefined; // Only change the route name when there is an active transition.
1221
1017
  // Otherwise, use the passed in route name.
1222
1018
 
@@ -1237,7 +1033,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1237
1033
  }
1238
1034
  }
1239
1035
 
1240
- return route && route.currentModel;
1036
+ return route === null || route === void 0 ? void 0 : route.currentModel;
1241
1037
  }
1242
1038
  /**
1243
1039
  `this[RENDER]` is used to render a template into a region of another template
@@ -1280,39 +1076,6 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1280
1076
  once(this._router, '_setOutlets');
1281
1077
  }
1282
1078
  }
1283
- /**
1284
- Allows you to produce custom metadata for the route.
1285
- The return value of this method will be attached to
1286
- its corresponding RouteInfoWithAttributes object.
1287
- Example
1288
- ```app/routes/posts/index.js
1289
- import Route from '@ember/routing/route';
1290
- export default class PostsIndexRoute extends Route {
1291
- buildRouteInfoMetadata() {
1292
- return { title: 'Posts Page' }
1293
- }
1294
- }
1295
- ```
1296
- ```app/routes/application.js
1297
- import Route from '@ember/routing/route';
1298
- import { service } from '@ember/service';
1299
- export default class ApplicationRoute extends Route {
1300
- @service router
1301
- constructor() {
1302
- super(...arguments);
1303
- this.router.on('routeDidChange', transition => {
1304
- document.title = transition.to.metadata.title;
1305
- // would update document's title to "Posts Page"
1306
- });
1307
- }
1308
- }
1309
- ```
1310
- @method buildRouteInfoMetadata
1311
- @return any
1312
- @since 3.10.0
1313
- @public
1314
- */
1315
-
1316
1079
 
1317
1080
  buildRouteInfoMetadata() {}
1318
1081
 
@@ -1377,11 +1140,12 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1377
1140
  let hasRouterDefinedQueryParams = Object.keys(queryParameterConfiguraton).length > 0;
1378
1141
 
1379
1142
  if (controller) {
1380
- // the developer has authored a controller class in their application for
1143
+ assert('Expected an instance of controller', controller instanceof Controller); // the developer has authored a controller class in their application for
1381
1144
  // this route find its query params and normalize their object shape them
1382
1145
  // merge in the query params for the route. As a mergedProperty,
1383
1146
  // Route#queryParams is always at least `{}`
1384
- let controllerDefinedQueryParameterConfiguration = get(controller, 'queryParams') || {};
1147
+
1148
+ let controllerDefinedQueryParameterConfiguration = get(controller, 'queryParams') || [];
1385
1149
  let normalizedControllerQueryParameterConfiguration = normalizeControllerQueryParams(controllerDefinedQueryParameterConfiguration);
1386
1150
  combinedQueryParameterConfiguration = mergeEachQueryParams(normalizedControllerQueryParameterConfiguration, queryParameterConfiguraton);
1387
1151
  } else if (hasRouterDefinedQueryParams) {
@@ -1453,6 +1217,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1453
1217
  */
1454
1218
  inactive: (prop, value) => {
1455
1219
  let qp = map[prop];
1220
+ assert('expected inactive callback to only be called for registered qps', qp);
1456
1221
 
1457
1222
  this._qpChanged(prop, value, qp);
1458
1223
  },
@@ -1464,6 +1229,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1464
1229
  */
1465
1230
  active: (prop, value) => {
1466
1231
  let qp = map[prop];
1232
+ assert('expected active callback to only be called for registered qps', qp);
1467
1233
 
1468
1234
  this._qpChanged(prop, value, qp);
1469
1235
 
@@ -1476,6 +1242,7 @@ class Route extends EmberObject.extend(ActionHandler, Evented) {
1476
1242
  */
1477
1243
  allowOverrides: (prop, value) => {
1478
1244
  let qp = map[prop];
1245
+ assert('expected allowOverrides callback to only be called for registered qps', qp);
1479
1246
 
1480
1247
  this._qpChanged(prop, value, qp);
1481
1248
 
@@ -1506,7 +1273,9 @@ function routeInfoFor(route, routeInfos, offset = 0) {
1506
1273
  let current;
1507
1274
 
1508
1275
  for (let i = 0; i < routeInfos.length; i++) {
1509
- current = routeInfos[i].route;
1276
+ let routeInfo = routeInfos[i];
1277
+ assert('has current routeInfo', routeInfo);
1278
+ current = routeInfo.route;
1510
1279
 
1511
1280
  if (current === route) {
1512
1281
  return routeInfos[i + offset];
@@ -1535,7 +1304,7 @@ function buildRenderOptions(route, nameOrOptions, options) {
1535
1304
  let owner = getOwner(route);
1536
1305
  assert('Route is unexpectedly missing an owner', owner);
1537
1306
  let name, templateName, into, outlet, model;
1538
- let controller = undefined;
1307
+ let controller;
1539
1308
 
1540
1309
  if (options) {
1541
1310
  into = options.into && options.into.replace(/\//g, '.');
@@ -1568,6 +1337,8 @@ function buildRenderOptions(route, nameOrOptions, options) {
1568
1337
  assert(`You passed \`controller: '${controllerName}'\` into the \`render\` method, but no such controller could be found.`, isDefaultRender || controller !== undefined);
1569
1338
  }
1570
1339
 
1340
+ assert('Expected an instance of controller', controller instanceof Controller);
1341
+
1571
1342
  if (model === undefined) {
1572
1343
  model = route.currentModel;
1573
1344
  } else {
@@ -1628,9 +1399,10 @@ export function getFullQueryParams(router, state) {
1628
1399
  function getQueryParamsFor(route, state) {
1629
1400
  state.queryParamsFor = state.queryParamsFor || {};
1630
1401
  let name = route.fullRouteName;
1402
+ let existing = state.queryParamsFor[name];
1631
1403
 
1632
- if (state.queryParamsFor[name]) {
1633
- return state.queryParamsFor[name];
1404
+ if (existing) {
1405
+ return existing;
1634
1406
  }
1635
1407
 
1636
1408
  let fullQueryParams = getFullQueryParams(route._router, state);
@@ -1639,9 +1411,8 @@ function getQueryParamsFor(route, state) {
1639
1411
 
1640
1412
  let qps = get(route, '_qp').qps;
1641
1413
 
1642
- for (let i = 0; i < qps.length; ++i) {
1414
+ for (let qp of qps) {
1643
1415
  // Put deserialized qp on params hash.
1644
- let qp = qps[i];
1645
1416
  let qpValueWasPassedIn = (qp.prop in fullQueryParams);
1646
1417
  params[qp.prop] = qpValueWasPassedIn ? fullQueryParams[qp.prop] : copyDefaultValue(qp.defaultValue);
1647
1418
  }
@@ -1732,54 +1503,12 @@ function getEngineRouteName(engine, routeName) {
1732
1503
 
1733
1504
  return routeName;
1734
1505
  }
1735
- /**
1736
- A hook you can implement to convert the route's model into parameters
1737
- for the URL.
1738
-
1739
- ```app/router.js
1740
- // ...
1741
-
1742
- Router.map(function() {
1743
- this.route('post', { path: '/posts/:post_id' });
1744
- });
1745
1506
 
1746
- ```
1747
-
1748
- ```app/routes/post.js
1749
- import Route from '@ember/routing/route';
1750
-
1751
- export default class PostRoute extends Route {
1752
- model({ post_id }) {
1753
- // the server returns `{ id: 12 }`
1754
- return fetch(`/posts/${post_id}`;
1755
- }
1756
-
1757
- serialize(model) {
1758
- // this will make the URL `/posts/12`
1759
- return { post_id: model.id };
1760
- }
1761
- }
1762
- ```
1763
-
1764
- The default `serialize` method will insert the model's `id` into the
1765
- route's dynamic segment (in this case, `:post_id`) if the segment contains '_id'.
1766
- If the route has multiple dynamic segments or does not contain '_id', `serialize`
1767
- will return `getProperties(model, params)`
1768
-
1769
- This method is called when `transitionTo` is called with a context
1770
- in order to populate the URL.
1771
-
1772
- @method serialize
1773
- @param {Object} model the routes model
1774
- @param {Array} params an Array of parameter names for the current
1775
- route (in the example, `['post_id']`.
1776
- @return {Object} the serialized parameters
1777
- @since 1.0.0
1778
- @public
1779
- */
1780
-
1781
-
1782
- Route.prototype.serialize = defaultSerialize; // Set these here so they can be overridden with extend
1507
+ const defaultSerialize = Route.prototype.serialize;
1508
+ export { defaultSerialize };
1509
+ export function hasDefaultSerialize(route) {
1510
+ return route.serialize === defaultSerialize;
1511
+ } // Set these here so they can be overridden with extend
1783
1512
 
1784
1513
  Route.reopen({
1785
1514
  mergedProperties: ['queryParams'],
@@ -1842,8 +1571,8 @@ Route.reopen({
1842
1571
  let qpMap = get(this, '_qp').map;
1843
1572
  let totalChanged = Object.keys(changed).concat(Object.keys(removed));
1844
1573
 
1845
- for (let i = 0; i < totalChanged.length; ++i) {
1846
- let qp = qpMap[totalChanged[i]];
1574
+ for (let change of totalChanged) {
1575
+ let qp = qpMap[change];
1847
1576
 
1848
1577
  if (qp) {
1849
1578
  let options = this._optionsForQueryParam(qp);
@@ -1880,8 +1609,7 @@ Route.reopen({
1880
1609
  let replaceUrl;
1881
1610
  stashParamNames(router, routeInfos);
1882
1611
 
1883
- for (let i = 0; i < qpMeta.qps.length; ++i) {
1884
- let qp = qpMeta.qps[i];
1612
+ for (let qp of qpMeta.qps) {
1885
1613
  let route = qp.route;
1886
1614
  let controller = route.controller;
1887
1615
  let presentKey = qp.urlKey in params && qp.urlKey; // Do a reverse lookup to see if the changed query