@warp-drive/legacy 5.9.0-alpha.2 → 5.9.0-alpha.21

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 (162) hide show
  1. package/README.md +6 -0
  2. package/declarations/adapter/-private/build-url-mixin.d.ts +156 -0
  3. package/declarations/adapter/error.d.ts +385 -169
  4. package/declarations/adapter/json-api.d.ts +12 -1
  5. package/declarations/adapter/rest.d.ts +74 -0
  6. package/declarations/adapter.d.ts +6 -0
  7. package/declarations/compat/builders/find-all.d.ts +0 -1
  8. package/declarations/compat/extensions.d.ts +40 -0
  9. package/declarations/compat/legacy-network-handler/legacy-network-handler.d.ts +7 -0
  10. package/declarations/compat/legacy-network-handler/minimum-adapter-interface.d.ts +4 -0
  11. package/declarations/compat/legacy-network-handler/minimum-serializer-interface.d.ts +7 -0
  12. package/declarations/compat/utils.d.ts +11 -0
  13. package/declarations/compat.d.ts +32 -0
  14. package/declarations/index.d.ts +142 -0
  15. package/declarations/model/-private/attr.d.ts +21 -0
  16. package/declarations/model/-private/belongs-to.d.ts +21 -0
  17. package/declarations/model/-private/hooks.d.ts +26 -0
  18. package/declarations/model/-private/model.d.ts +55 -4
  19. package/declarations/model/-private/promise-many-array.d.ts +25 -1
  20. package/declarations/model/-private/schema-provider.d.ts +11 -1
  21. package/declarations/model/migration-support.d.ts +31 -5
  22. package/declarations/model-fragments/extensions/fragment-array.d.ts +38 -0
  23. package/declarations/model-fragments/extensions/fragment.d.ts +35 -0
  24. package/declarations/model-fragments/hooks/model-for.d.ts +7 -0
  25. package/declarations/model-fragments/index.d.ts +8 -0
  26. package/declarations/model-fragments/instance-initializers/fragment-extensions.d.ts +6 -0
  27. package/declarations/model-fragments/utilities/with-array-defaults.d.ts +30 -0
  28. package/declarations/model-fragments/utilities/with-fragment-array-defaults.d.ts +18 -0
  29. package/declarations/model-fragments/utilities/with-fragment-defaults.d.ts +15 -0
  30. package/declarations/model-fragments/utilities/with-legacy.d.ts +8 -0
  31. package/declarations/serializer/-private/transforms/boolean.d.ts +13 -0
  32. package/declarations/serializer/-private/transforms/date.d.ts +15 -1
  33. package/declarations/serializer/-private/transforms/number.d.ts +14 -1
  34. package/declarations/serializer/-private/transforms/string.d.ts +14 -1
  35. package/declarations/serializer/-private/utils.d.ts +24 -0
  36. package/declarations/serializer/json-api.d.ts +1 -1
  37. package/declarations/serializer.d.ts +4 -6
  38. package/declarations/store/-private.d.ts +2 -2
  39. package/declarations/store.d.ts +7 -0
  40. package/dist/adapter/error.js +386 -241
  41. package/dist/adapter/json-api.js +12 -0
  42. package/dist/adapter/rest.js +39 -3
  43. package/dist/adapter.js +23 -26
  44. package/dist/compat/builders.js +0 -1
  45. package/dist/compat/extensions.js +80 -3
  46. package/dist/compat/utils.js +14 -0
  47. package/dist/compat.js +17 -0
  48. package/dist/{errors-Cz5KrzBk.js → errors-DZKA206g.js} +24 -1
  49. package/dist/{hooks-D6diaM34.js → hooks-BvOqJBei.js} +33 -2
  50. package/dist/index.js +168 -13
  51. package/dist/{json-ChdEfB0X.js → json-DU8m1pGf.js} +83 -6
  52. package/dist/model/-private.js +1 -1
  53. package/dist/model/migration-support.js +15 -2
  54. package/dist/{unpkg/dev-deprecated/model-for-CqXsIKws.js → model-for-CXkJw59V.js} +77 -1
  55. package/dist/model-fragments.js +18 -2
  56. package/dist/model.js +12 -8
  57. package/dist/{schema-provider-DJCV_6AF.js → schema-provider-DtPOp0d7.js} +93 -6
  58. package/dist/serializer/json-api.js +8 -3
  59. package/dist/serializer/json.js +1 -1
  60. package/dist/serializer/rest.js +3 -4
  61. package/dist/serializer/transform.js +51 -3
  62. package/dist/serializer.js +4 -7
  63. package/dist/store.js +13 -7
  64. package/dist/unpkg/dev/adapter/error.js +386 -241
  65. package/dist/unpkg/dev/adapter/json-api.js +13 -1
  66. package/dist/unpkg/dev/adapter/rest.js +39 -3
  67. package/dist/unpkg/dev/adapter.js +23 -26
  68. package/dist/unpkg/dev/compat/builders.js +0 -1
  69. package/dist/unpkg/dev/compat/extensions.js +80 -3
  70. package/dist/unpkg/dev/compat/utils.js +14 -0
  71. package/dist/unpkg/dev/compat.js +34 -1
  72. package/dist/unpkg/dev/{errors-DmGGJr3T.js → errors-DngRU-If.js} +24 -1
  73. package/dist/unpkg/dev/{hooks-CkYiE6Ud.js → hooks-UuiLxWxS.js} +33 -2
  74. package/dist/unpkg/dev/index.js +171 -13
  75. package/dist/unpkg/dev/json-K2Y9z6MN.js +1333 -0
  76. package/dist/unpkg/dev/model/-private.js +1 -1
  77. package/dist/unpkg/dev/model/migration-support.js +16 -2
  78. package/dist/unpkg/{prod-deprecated/model-for-CqXsIKws.js → dev/model-for-CXkJw59V.js} +77 -1
  79. package/dist/unpkg/dev/model-fragments.js +18 -2
  80. package/dist/unpkg/dev/model.js +12 -8
  81. package/dist/unpkg/dev/{schema-provider-DDVYxmUV.js → schema-provider-0D7f-QOn.js} +92 -6
  82. package/dist/unpkg/dev/serializer/json-api.js +9 -4
  83. package/dist/unpkg/dev/serializer/json.js +1 -1
  84. package/dist/unpkg/dev/serializer/rest.js +3 -4
  85. package/dist/unpkg/dev/serializer/transform.js +51 -3
  86. package/dist/unpkg/dev/serializer.js +4 -7
  87. package/dist/unpkg/dev/store.js +21 -7
  88. package/dist/unpkg/dev-deprecated/adapter/error.js +386 -241
  89. package/dist/unpkg/dev-deprecated/adapter/json-api.js +13 -1
  90. package/dist/unpkg/dev-deprecated/adapter/rest.js +39 -3
  91. package/dist/unpkg/dev-deprecated/adapter.js +23 -26
  92. package/dist/unpkg/dev-deprecated/compat/builders.js +0 -1
  93. package/dist/unpkg/dev-deprecated/compat/extensions.js +80 -3
  94. package/dist/unpkg/dev-deprecated/compat/utils.js +14 -0
  95. package/dist/unpkg/dev-deprecated/compat.js +34 -1
  96. package/dist/unpkg/dev-deprecated/{errors-Spt6ubMd.js → errors-Bzidntpi.js} +24 -1
  97. package/dist/unpkg/dev-deprecated/{hooks-DOXegvhL.js → hooks-DVXhMW14.js} +33 -2
  98. package/dist/unpkg/dev-deprecated/index.js +171 -13
  99. package/dist/unpkg/{prod-deprecated/json-BWrZ5546.js → dev-deprecated/json-K2Y9z6MN.js} +96 -6
  100. package/dist/unpkg/dev-deprecated/model/-private.js +1 -1
  101. package/dist/unpkg/dev-deprecated/model/migration-support.js +16 -2
  102. package/dist/unpkg/{dev/model-for-CqXsIKws.js → dev-deprecated/model-for-CXkJw59V.js} +77 -1
  103. package/dist/unpkg/dev-deprecated/model-fragments.js +18 -2
  104. package/dist/unpkg/dev-deprecated/model.js +12 -8
  105. package/dist/unpkg/dev-deprecated/{schema-provider-BP6_8N-V.js → schema-provider-ZwO5_fZw.js} +84 -3
  106. package/dist/unpkg/dev-deprecated/serializer/json-api.js +9 -4
  107. package/dist/unpkg/dev-deprecated/serializer/json.js +1 -1
  108. package/dist/unpkg/dev-deprecated/serializer/rest.js +3 -4
  109. package/dist/unpkg/dev-deprecated/serializer/transform.js +51 -3
  110. package/dist/unpkg/dev-deprecated/serializer.js +4 -7
  111. package/dist/unpkg/dev-deprecated/store.js +21 -7
  112. package/dist/unpkg/prod/adapter/error.js +386 -241
  113. package/dist/unpkg/prod/adapter/json-api.js +13 -1
  114. package/dist/unpkg/prod/adapter/rest.js +39 -3
  115. package/dist/unpkg/prod/adapter.js +23 -26
  116. package/dist/unpkg/prod/compat/builders.js +0 -1
  117. package/dist/unpkg/prod/compat/extensions.js +70 -3
  118. package/dist/unpkg/prod/compat/utils.js +14 -0
  119. package/dist/unpkg/prod/compat.js +17 -0
  120. package/dist/unpkg/prod/{errors-BGVFCBmi.js → errors-B-PWeYlW.js} +24 -1
  121. package/dist/unpkg/prod/{hooks-BztVA_x0.js → hooks-Bx-zBziU.js} +32 -1
  122. package/dist/unpkg/prod/index.js +171 -5
  123. package/dist/unpkg/{dev/json-Cu1LNgmQ.js → prod/json-Qewu-UN9.js} +63 -19
  124. package/dist/unpkg/prod/model/-private.js +1 -1
  125. package/dist/unpkg/prod/model/migration-support.js +16 -2
  126. package/dist/unpkg/prod/model-for-CXkJw59V.js +297 -0
  127. package/dist/unpkg/prod/model-fragments.js +18 -2
  128. package/dist/unpkg/prod/model.js +12 -8
  129. package/dist/unpkg/prod/{schema-provider-DJtD_8jZ.js → schema-provider-BgRqk8i9.js} +96 -6
  130. package/dist/unpkg/prod/serializer/json-api.js +9 -4
  131. package/dist/unpkg/prod/serializer/json.js +1 -1
  132. package/dist/unpkg/prod/serializer/rest.js +3 -4
  133. package/dist/unpkg/prod/serializer/transform.js +51 -3
  134. package/dist/unpkg/prod/serializer.js +4 -7
  135. package/dist/unpkg/prod/store.js +21 -7
  136. package/dist/unpkg/prod-deprecated/adapter/error.js +386 -241
  137. package/dist/unpkg/prod-deprecated/adapter/json-api.js +13 -1
  138. package/dist/unpkg/prod-deprecated/adapter/rest.js +39 -3
  139. package/dist/unpkg/prod-deprecated/adapter.js +23 -26
  140. package/dist/unpkg/prod-deprecated/compat/builders.js +0 -1
  141. package/dist/unpkg/prod-deprecated/compat/extensions.js +70 -3
  142. package/dist/unpkg/prod-deprecated/compat/utils.js +14 -0
  143. package/dist/unpkg/prod-deprecated/compat.js +17 -0
  144. package/dist/unpkg/prod-deprecated/{errors-CdDaK81x.js → errors-Dl2J9d1D.js} +24 -1
  145. package/dist/unpkg/prod-deprecated/{hooks-yId87yyG.js → hooks-Cm60wWTf.js} +32 -1
  146. package/dist/unpkg/prod-deprecated/index.js +171 -5
  147. package/dist/unpkg/{dev-deprecated/json-Cu1LNgmQ.js → prod-deprecated/json-Qewu-UN9.js} +63 -19
  148. package/dist/unpkg/prod-deprecated/model/-private.js +1 -1
  149. package/dist/unpkg/prod-deprecated/model/migration-support.js +16 -2
  150. package/dist/{model-for-CqXsIKws.js → unpkg/prod-deprecated/model-for-CXkJw59V.js} +77 -1
  151. package/dist/unpkg/prod-deprecated/model-fragments.js +18 -2
  152. package/dist/unpkg/prod-deprecated/model.js +12 -8
  153. package/dist/unpkg/prod-deprecated/{schema-provider-CjX55uSY.js → schema-provider-Dh6tRqVI.js} +79 -3
  154. package/dist/unpkg/prod-deprecated/serializer/json-api.js +9 -4
  155. package/dist/unpkg/prod-deprecated/serializer/json.js +1 -1
  156. package/dist/unpkg/prod-deprecated/serializer/rest.js +3 -4
  157. package/dist/unpkg/prod-deprecated/serializer/transform.js +51 -3
  158. package/dist/unpkg/prod-deprecated/serializer.js +4 -7
  159. package/dist/unpkg/prod-deprecated/store.js +21 -7
  160. package/package.json +8 -8
  161. package/dist/unpkg/prod/json-BWrZ5546.js +0 -1243
  162. package/dist/unpkg/prod/model-for-CqXsIKws.js +0 -221
@@ -7,6 +7,10 @@ import { RESTAdapter } from './rest.js';
7
7
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
8
 
9
9
  class JSONAPIAdapter extends RESTAdapter {
10
+ /**
11
+ * The `Content-Type` header used when serializing request bodies
12
+ * that don't otherwise specify one.
13
+ */
10
14
  _defaultContentType = 'application/vnd.api+json';
11
15
 
12
16
  /**
@@ -88,6 +92,14 @@ class JSONAPIAdapter extends RESTAdapter {
88
92
  }
89
93
  });
90
94
  }
95
+
96
+ /**
97
+ * Determines the pathname for a given type.
98
+ *
99
+ * Unlike the base `BuildURLMixin` implementation, dasherizes (rather
100
+ * than camelizes) the type name before pluralizing it, per the
101
+ * {json:api} convention for member names.
102
+ */
91
103
  pathForType(modelName) {
92
104
  const dasherized = dasherize(modelName);
93
105
  return pluralize(dasherized);
@@ -236,13 +236,39 @@ const AdapterWithBuildURLMixin = Adapter.extend(BuildURLMixin);
236
236
  @public
237
237
  */
238
238
  class RESTAdapter extends AdapterWithBuildURLMixin {
239
+ /**
240
+ * @private
241
+ */
242
+
243
+ /**
244
+ * @private
245
+ */
246
+
247
+ /**
248
+ * See "Host customization" above.
249
+ */
250
+
251
+ /**
252
+ * See "Namespace customization" above.
253
+ */
254
+
239
255
  /**
240
256
  This property allows ajax to still be used instead when `false`.
241
257
  @default true
242
258
  @public
243
259
  */
244
260
  useFetch = true;
261
+
262
+ /**
263
+ * The `Content-Type` header used when serializing request bodies
264
+ * that don't otherwise specify one.
265
+ */
245
266
  _defaultContentType = 'application/json; charset=utf-8';
267
+
268
+ /**
269
+ * The FastBoot service instance, if running in a FastBoot environment.
270
+ * Lazily looked up on first access.
271
+ */
246
272
  get fastboot() {
247
273
  // Avoid computed property override deprecation in fastboot as suggested by:
248
274
  // https://deprecations.emberjs.com/v3.x/#toc_computed-property-override
@@ -252,6 +278,10 @@ class RESTAdapter extends AdapterWithBuildURLMixin {
252
278
  }
253
279
  return this._fastboot = getOwner(this).lookup('service:fastboot');
254
280
  }
281
+
282
+ /**
283
+ * Sets the FastBoot service instance to use.
284
+ */
255
285
  static {
256
286
  decorateMethodV2(this.prototype, "fastboot", [computed()]);
257
287
  }
@@ -648,7 +678,13 @@ class RESTAdapter extends AdapterWithBuildURLMixin {
648
678
  return expandedURL.join('/');
649
679
  }
650
680
 
651
- // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
681
+ /**
682
+ * The maximum URL length to allow when coalescing `findRecord` requests
683
+ * into a single `findMany` request via {@link RESTAdapter.groupRecordsForFindMany | groupRecordsForFindMany}.
684
+ * Requests that would exceed this length are split into multiple groups.
685
+ *
686
+ * See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
687
+ */
652
688
  maxURLLength = 2048;
653
689
 
654
690
  /**
@@ -709,8 +745,8 @@ class RESTAdapter extends AdapterWithBuildURLMixin {
709
745
  if (this.isSuccess(status, headers, payload)) {
710
746
  return payload;
711
747
  } else if (this.isInvalid(status, headers, payload)) {
712
- // @ts-expect-error needs cast to ApiError
713
- return new InvalidError(typeof payload === 'object' && 'errors' in payload ? payload.errors : undefined);
748
+ const errorPayload = payload ?? {};
749
+ return new InvalidError(typeof errorPayload === 'object' && 'errors' in errorPayload ? errorPayload.errors : undefined);
714
750
  }
715
751
  const errors = this.normalizeErrorResponse(status, headers, payload);
716
752
  const detailedMessage = this.generatedDetailedMessage(status, headers, payload, requestData);
package/dist/adapter.js CHANGED
@@ -5,6 +5,8 @@ import { a as decorateFieldV2, i as initializeDeferredDecorator } from "./runtim
5
5
  import Mixin from '@ember/object/mixin';
6
6
  import { camelize, pluralize } from '@warp-drive/utilities/string';
7
7
 
8
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
+
8
10
  /*
9
11
  The structure of this file is such because typing Mixins is hard. Here we've structured it in
10
12
  such a way as to maximize the type information that a consumer can utilize. There are simpler
@@ -15,37 +17,18 @@ import { camelize, pluralize } from '@warp-drive/utilities/string';
15
17
  // `interface BuildURLMixin { buildURL: typeof buildURL }`
16
18
  // then an extending class overwriting one of the methods will break because typescript
17
19
  // thinks it is a switch from an instance prop (that is a method) to an instance method.
20
+ /**
21
+ * The methods provided by the `BuildURLMixin` mixin (see the exported
22
+ * `BuildURLMixin` {@link Mixin} below).
23
+ *
24
+ * See also {@link MixtBuildURLMixin}, the interface used to type `this`
25
+ * within these methods.
26
+ */
18
27
 
19
28
  // prevents the final constructed object from needing to add
20
29
  // host and namespace which are provided by the final consuming
21
30
  // class to the prototype which can result in overwrite errors
22
31
 
23
- /**
24
- ## Using BuildURLMixin
25
-
26
- To use URL building, include the mixin when extending an adapter, and call `buildURL` where needed.
27
- The default behaviour is designed for RESTAdapter.
28
-
29
- ### Example
30
-
31
- ```javascript
32
- import Adapter, { BuildURLMixin } from '@ember-data/adapter';
33
-
34
- export default class ApplicationAdapter extends Adapter.extend(BuildURLMixin) {
35
- findRecord(store, type, id, snapshot) {
36
- var url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
37
- return this.ajax(url, 'GET');
38
- }
39
- }
40
- ```
41
-
42
- ### Attributes
43
-
44
- The `host` and `namespace` attributes will be used if defined, and are optional.
45
-
46
- @class BuildURLMixin
47
- @public
48
- */
49
32
  /**
50
33
  Builds a URL for a given type and optional ID.
51
34
 
@@ -491,6 +474,13 @@ const mixinProps = {
491
474
  urlPrefix,
492
475
  pathForType
493
476
  };
477
+
478
+ /**
479
+ * The `Mixin` implementation of {@link BuildURLMixin}, ready to be applied
480
+ * to an `EmberObject` subclass such as an `Adapter`.
481
+ *
482
+ * @public
483
+ */
494
484
  const BuildURLMixin = Mixin.create(mixinProps);
495
485
 
496
486
  /**
@@ -740,6 +730,13 @@ class Adapter extends EmberObject {
740
730
  decorateFieldV2(this.prototype, "store", [service]);
741
731
  }
742
732
  #store = (initializeDeferredDecorator(this, "store"), void 0);
733
+ /**
734
+ * The Store service instance that owns this Adapter.
735
+ */
736
+ /**
737
+ * @private
738
+ */
739
+
743
740
  /**
744
741
  The `findRecord()` method is invoked when the store is asked for a record that
745
742
  has not previously been loaded. In response to `findRecord()` being called, you
@@ -16,7 +16,6 @@ import { storeFor, recordIdentifierFor } from '@warp-drive/core';
16
16
  @deprecated
17
17
  @public
18
18
  @param type the name of the resource
19
- @param query a query to be used by the adapter
20
19
  @param options optional, may include `adapterOptions` hash which will be passed to adapter.findAll
21
20
  @return request config
22
21
  */
@@ -1,19 +1,75 @@
1
- import { get, set } from '@ember/object';
1
+ import { get, set, setProperties, notifyPropertyChange, getProperties } from '@ember/object';
2
+ import { removeObserver, addObserver } from '@ember/object/observers';
2
3
  import { compare } from '@ember/utils';
3
- import Ember from 'ember';
4
4
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
5
5
  const EmberObjectFeatures = {};
6
6
  const EmberObjectMethods = ['addObserver', 'cacheFor', 'decrementProperty', 'get', 'getProperties', 'incrementProperty', 'notifyPropertyChange', 'removeObserver', 'set', 'setProperties', 'toggleProperty'];
7
7
  EmberObjectMethods.forEach(method => {
8
8
  EmberObjectFeatures[method] = function delegatedMethod(...args) {
9
- return Ember[method](this, ...args);
9
+ switch (method) {
10
+ case 'addObserver':
11
+ return addObserver(this, ...args);
12
+ case 'cacheFor':
13
+ throw new Error('cacheFor has been removed and will not be replaced');
14
+ case 'decrementProperty':
15
+ {
16
+ const keyName = args[0];
17
+ const decrement = args[1] ?? 1;
18
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
19
+ if (!test) {
20
+ throw new Error('Must pass a numeric value to decrementProperty');
21
+ }
22
+ })((typeof decrement === 'number' || !isNaN(parseFloat(decrement))) && isFinite(decrement)) : {};
23
+ return set(this, keyName, (get(this, keyName) || 0) - decrement);
24
+ }
25
+ case 'get':
26
+ return get(this, ...args);
27
+ case 'getProperties':
28
+ return getProperties(this, ...args);
29
+ case 'incrementProperty':
30
+ {
31
+ const keyName = args[0];
32
+ const increment = args[1] ?? 1;
33
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
34
+ if (!test) {
35
+ throw new Error('Must pass a numeric value to incrementProperty');
36
+ }
37
+ })(!isNaN(parseFloat(String(increment))) && isFinite(increment)) : {};
38
+ return set(this, keyName, (parseFloat(get(this, keyName)) || 0) + increment);
39
+ }
40
+ case 'notifyPropertyChange':
41
+ return notifyPropertyChange(this, ...args);
42
+ case 'removeObserver':
43
+ return removeObserver(this, ...args);
44
+ case 'set':
45
+ return set(this, ...args);
46
+ case 'setProperties':
47
+ return setProperties(this, ...args);
48
+ case 'toggleProperty':
49
+ {
50
+ const key = args[0];
51
+ return set(this, key, !get(this, key));
52
+ }
53
+ }
10
54
  };
11
55
  });
56
+ /**
57
+ * A schema extension that adds the classic `EmberObject` API (`get`, `set`,
58
+ * `getProperties`, `setProperties`, `incrementProperty`, `decrementProperty`,
59
+ * `toggleProperty`, `notifyPropertyChange`, `addObserver`, `removeObserver`)
60
+ * to reactive array resources.
61
+ */
12
62
  const EmberObjectArrayExtension = {
13
63
  kind: 'array',
14
64
  name: 'ember-object',
15
65
  features: EmberObjectFeatures
16
66
  };
67
+ /**
68
+ * A schema extension that adds the classic `EmberObject` API (`get`, `set`,
69
+ * `getProperties`, `setProperties`, `incrementProperty`, `decrementProperty`,
70
+ * `toggleProperty`, `notifyPropertyChange`, `addObserver`, `removeObserver`)
71
+ * to reactive object resources.
72
+ */
17
73
  const EmberObjectExtension = {
18
74
  kind: 'object',
19
75
  name: 'ember-object',
@@ -235,9 +291,30 @@ const EmberArrayLikeFeatures = {
235
291
  return this.at(-1);
236
292
  }
237
293
  };
294
+
295
+ /**
296
+ * A schema extension that adds Ember's classic `MutableArray`/`Enumerable`
297
+ * style methods (`pushObject`, `removeObject`, `mapBy`, `filterBy`,
298
+ * `sortBy`, `firstObject`, `lastObject`, etc.) to reactive array resources.
299
+ */
238
300
  const EmberArrayLikeExtension = {
239
301
  kind: 'array',
240
302
  name: 'ember-array-like',
241
303
  features: EmberArrayLikeFeatures
242
304
  };
305
+
306
+ /**
307
+ * Extracts the element type of an array type, or `never` if `T` is not an array.
308
+ */
309
+
310
+ /**
311
+ * Adds the classic `EmberObject` API (as registered by {@link EmberObjectExtension}/
312
+ * {@link EmberObjectArrayExtension}) to the type of a reactive resource.
313
+ */
314
+
315
+ /**
316
+ * Adds Ember's classic array-like API (as registered by {@link EmberArrayLikeExtension})
317
+ * to the type of a reactive array resource.
318
+ */
319
+
243
320
  export { EmberArrayLikeExtension, EmberObjectArrayExtension, EmberObjectExtension };
@@ -146,6 +146,20 @@ function formattedId(id) {
146
146
  }
147
147
  return id === null ? null : String(id);
148
148
  }
149
+
150
+ /**
151
+ * Like {@link formattedId}, but asserts that `id` is not `null` rather
152
+ * than allowing and passing through `null`.
153
+ *
154
+ * @public
155
+ */
156
+
157
+ /**
158
+ * Throws, since `id` is `null`.
159
+ *
160
+ * @public
161
+ */
162
+
149
163
  function expectId(id) {
150
164
  AssertFn('expectId: id must not be null', id !== null);
151
165
  return formattedId(id);
package/dist/compat.js CHANGED
@@ -283,6 +283,14 @@ function validateRelationshipEntry({
283
283
  return !!id && id.toString() === parentModelID;
284
284
  }
285
285
  const PotentialLegacyOperations = new Set(['findRecord', 'findAll', 'query', 'queryRecord', 'findBelongsTo', 'findHasMany', 'updateRecord', 'createRecord', 'deleteRecord']);
286
+
287
+ /**
288
+ * A {@link Handler} that fulfills legacy `findRecord`/`findAll`/`query`/
289
+ * `queryRecord`/`findBelongsTo`/`findHasMany`/`createRecord`/`updateRecord`/
290
+ * `deleteRecord` requests using the store's configured {@link MinimumAdapterInterface | adapter}
291
+ * and {@link MinimumSerializerInterface | serializer}, passing any other
292
+ * request through to the next handler unchanged.
293
+ */
286
294
  const LegacyNetworkHandler = {
287
295
  request(context, next) {
288
296
  // if we are not a legacy request, move on
@@ -995,6 +1003,10 @@ function pushPayload(modelName, inputPayload) {
995
1003
  serializer.pushPayload(this, payload);
996
1004
  }
997
1005
 
1006
+ /**
1007
+ * Serializes a record using the store's legacy network layer, as with
1008
+ * {@link LegacyStoreCompat.serializeRecord | store.serializeRecord}.
1009
+ */
998
1010
  // TODO @runspired @deprecate records should implement their own serialization if desired
999
1011
  function serializeRecord(record, options) {
1000
1012
  // TODO we used to check if the record was destroyed here
@@ -1003,6 +1015,11 @@ function serializeRecord(record, options) {
1003
1015
  }
1004
1016
  return this._fetchManager.createSnapshot(recordIdentifierFor(record)).serialize(options);
1005
1017
  }
1018
+
1019
+ /**
1020
+ * Destroys any adapters/serializers the legacy network layer has created
1021
+ * for this store, invoked when the store itself is destroyed.
1022
+ */
1006
1023
  function cleanup() {
1007
1024
  // enqueue destruction of any adapters/serializers we have created
1008
1025
  for (const adapterName in this._adapterCache) {
@@ -77,7 +77,7 @@ PromiseBelongsTo.prototype[LegacyPromiseProxy] = true;
77
77
 
78
78
  /**
79
79
  This class is returned as the result of accessing an async hasMany relationship
80
- on an instance of a Model extending from `@ember-data/model`.
80
+ on an instance of a Model extending from `@warp-drive/legacy/model`.
81
81
 
82
82
  A PromiseManyArray is an iterable proxy that allows templates to consume related
83
83
  ManyArrays and update once their contents are no longer pending.
@@ -91,6 +91,20 @@ PromiseBelongsTo.prototype[LegacyPromiseProxy] = true;
91
91
  @public
92
92
  */
93
93
  class PromiseManyArray {
94
+ /**
95
+ * The promise for the relationship's content, or `null` once
96
+ * {@link PromiseManyArray.destroy | destroy} has been called.
97
+ */
98
+
99
+ /**
100
+ * Whether {@link PromiseManyArray.destroy | destroy} has been called.
101
+ */
102
+
103
+ /**
104
+ * The resolved `ManyArray` for the relationship, if the promise has
105
+ * resolved, else `null`.
106
+ */
107
+
94
108
  constructor(promise, content) {
95
109
  this._update(promise, content);
96
110
  this.isDestroyed = false;
@@ -111,6 +125,9 @@ class PromiseManyArray {
111
125
  return this.content ? this.content.length : 0;
112
126
  }
113
127
 
128
+ /**
129
+ * @private
130
+ */
114
131
  // this will error if someone tries to call
115
132
  // A(identifierArray) since it is not configurable
116
133
  // which is preferrable to the `meta` override we used
@@ -212,6 +229,12 @@ class PromiseManyArray {
212
229
 
213
230
  //---- Methods on EmberObject that we should keep
214
231
 
232
+ /**
233
+ * Tears down this proxy, releasing its {@link PromiseManyArray.content | content} and
234
+ * {@link PromiseManyArray.promise | promise} and marking it as {@link PromiseManyArray.isDestroyed | destroyed}.
235
+ *
236
+ * @public
237
+ */
215
238
  destroy() {
216
239
  this.isDestroyed = true;
217
240
  this.content = null;
@@ -1,8 +1,16 @@
1
1
  import { setOwner, getOwner } from '@ember/application';
2
2
  import { assertPrivateStore, setRecordIdentifier, StoreMap } from '@warp-drive/core/store/-private';
3
- import { g as getModelFactory } from "./schema-provider-DJCV_6AF.js";
3
+ import { g as getModelFactory } from "./schema-provider-DtPOp0d7.js";
4
4
  import { n as normalizeModelName } from "./util-Dul6TZts.js";
5
5
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
6
+
7
+ /**
8
+ * The `instantiateRecord` hook implementation for use with `Model`. Pass
9
+ * this to your store's `instantiateRecord` method when configuring the
10
+ * store to use `Model` for schema/record instantiation.
11
+ *
12
+ * @public
13
+ */
6
14
  function instantiateRecord(identifier, createRecordArgs) {
7
15
  const type = identifier.type;
8
16
 
@@ -27,14 +35,37 @@ function instantiateRecord(identifier, createRecordArgs) {
27
35
  })(factory) : {};
28
36
  return factory.class.create(createOptions);
29
37
  }
38
+
39
+ /**
40
+ * The `teardownRecord` hook implementation for use with `Model`. Pass this
41
+ * to your store's `teardownRecord` method when configuring the store to
42
+ * use `Model` for schema/record instantiation.
43
+ *
44
+ * @public
45
+ */
30
46
  function teardownRecord(record) {
31
47
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
32
48
  if (!test) {
33
- throw new Error(`expected to receive an instance of Model from @ember-data/model. If using a custom model make sure you implement teardownRecord`);
49
+ throw new Error(`expected to receive an instance of Model from @warp-drive/legacy/model. If using a custom model make sure you implement teardownRecord`);
34
50
  }
35
51
  })('destroy' in record) : {};
36
52
  record.destroy();
37
53
  }
54
+
55
+ /**
56
+ * The `modelFor` implementation for use with `Model`, exposed on the store
57
+ * as `store.modelFor(type)` when the store is configured to use `Model`.
58
+ * Returns the `Model` subclass registered for the given type, if any.
59
+ *
60
+ * @public
61
+ */
62
+
63
+ /**
64
+ * Overload accepting a raw type string instead of a typed record instance.
65
+ *
66
+ * @public
67
+ */
68
+
38
69
  function modelFor(modelName) {
39
70
  assertPrivateStore(this);
40
71
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
package/dist/index.js CHANGED
@@ -9,11 +9,11 @@ import '@ember/debug';
9
9
  import '@warp-drive/utilities/string';
10
10
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
11
11
  import '@warp-drive/core/store/-private';
12
- import "./errors-Cz5KrzBk.js";
13
- import "./schema-provider-DJCV_6AF.js";
14
- import { i as instantiateRecord, t as teardownRecord, m as modelFor } from "./hooks-D6diaM34.js";
12
+ import "./errors-DZKA206g.js";
13
+ import "./schema-provider-DtPOp0d7.js";
14
+ import { i as instantiateRecord, t as teardownRecord, m as modelFor } from "./hooks-BvOqJBei.js";
15
15
  import { registerDerivations as registerDerivations$1, DelegatingSchemaService } from './model/migration-support.js';
16
- import { F as FragmentExtension, a as FragmentArrayExtension, f as fragmentsModelFor } from "./model-for-CqXsIKws.js";
16
+ import { F as FragmentExtension, a as FragmentArrayExtension, f as fragmentsModelFor } from "./model-for-CXkJw59V.js";
17
17
  import { restoreDeprecatedStoreBehaviors } from './store.js';
18
18
 
19
19
  /**
@@ -21,8 +21,148 @@ import { restoreDeprecatedStoreBehaviors } from './store.js';
21
21
  * @mergeModuleWith <project>
22
22
  */
23
23
 
24
+ /**
25
+ * Setup options for a legacy store configured to use `Model` with `linksMode`
26
+ * enabled, meaning no legacy adapter/serializer request infrastructure is required.
27
+ *
28
+ * @public
29
+ */
30
+ /**
31
+ * Setup options for a legacy store configured to use `Model` along with the
32
+ * legacy adapter/serializer network layer, but without the deprecated
33
+ * `store.findRecord`/`findAll`/`query`/etc. request methods.
34
+ *
35
+ * @public
36
+ */
37
+ /**
38
+ * Setup options for a legacy store configured to use `Model` along with the
39
+ * legacy adapter/serializer network layer and the deprecated
40
+ * `store.findRecord`/`findAll`/`query`/etc. request methods.
41
+ *
42
+ * @public
43
+ */
44
+ //export type ConfiguredStore<T = unknown> = typeof Store;
45
+ /**
46
+ * The available options when setting up the legacy store,
47
+ * one of:
48
+ *
49
+ * - {@link LegacyModelStoreSetupOptions}
50
+ * - {@link LegacyModelAndNetworkStoreSetupOptions}
51
+ * - {@link LegacyModelAndNetworkAndRequestStoreSetupOptions}
52
+ */
24
53
  /**
25
54
  * Use the legacy store with the given options.
55
+ *
56
+ * See {@link LegacyStoreSetupOptions} for details on the available options.
57
+ *
58
+ * ```ts
59
+ * import { useLegacyStore } from '@warp-drive/legacy';
60
+ * import { JSONAPICache } from '@warp-drive/json-api';
61
+ *
62
+ * export default useLegacyStore({
63
+ * linksMode: false,
64
+ * legacyRequests: true,
65
+ * cache: JSONAPICache,
66
+ * schemas: [],
67
+ * });
68
+ * ```
69
+ *
70
+ * ### Adding Stateful Handlers
71
+ *
72
+ * A request {@link Handler} is sometimes more than a plain object or class
73
+ * with a `request` method — it may need access to a stateful dependency such
74
+ * as an Ember service (an auth token, a feature-flags service, an i18n
75
+ * helper, etc.).
76
+ *
77
+ * A plain class handler that only relies on Ember's `@service` decorator will
78
+ * not work here on its own: the handler is never instantiated *through*
79
+ * Ember's container (it's just `new`'d up), so it has no owner and its
80
+ * `@service` injections would fail to resolve.
81
+ *
82
+ * Instead, give `handlers` a function. It receives the {@link Store} instance
83
+ * being configured, which by the time the function runs already has an owner
84
+ * assigned. Use `getOwner`/`setOwner` from `@ember/owner` to transfer that
85
+ * owner onto your handler instance before returning it, exactly as you would
86
+ * when constructing any other DI-aware object outside of the container:
87
+ *
88
+ * ```ts
89
+ * import { getOwner, setOwner } from '@ember/owner';
90
+ * import { service } from '@ember/service';
91
+ * import { useLegacyStore } from '@warp-drive/legacy';
92
+ * import type { NextFn } from '@warp-drive/core/request';
93
+ * import type { RequestContext } from '@warp-drive/core/types/request';
94
+ * import { JSONAPICache } from '@warp-drive/json-api';
95
+ *
96
+ * class AuthHandler {
97
+ * @service session;
98
+ *
99
+ * request<T>(context: RequestContext, next: NextFn<T>) {
100
+ * const headers = new Headers(context.request.headers);
101
+ * headers.append('Authorization', `Bearer ${this.session.accessToken}`);
102
+ * return next(Object.assign({}, context.request, { headers }));
103
+ * }
104
+ * }
105
+ *
106
+ * export default useLegacyStore({
107
+ * linksMode: false,
108
+ * legacyRequests: true,
109
+ * cache: JSONAPICache,
110
+ * handlers: (store) => {
111
+ * const authHandler = new AuthHandler();
112
+ * setOwner(authHandler, getOwner(store)!);
113
+ * return [authHandler];
114
+ * },
115
+ * });
116
+ * ```
117
+ *
118
+ * The `handlers` function is invoked lazily and only once per store instance,
119
+ * the first time `store.requestManager` is accessed, so it is safe to do
120
+ * owner-dependent setup like this inside of it.
121
+ *
122
+ * ### Accessing the Store from a Handler's Context
123
+ *
124
+ * If a handler only needs to read something *off of the store itself*
125
+ * (its cache, or a property/service you've attached to a custom store
126
+ * subclass) rather than an unrelated Ember service, there is a second,
127
+ * simpler option that requires no DI/`setOwner` wiring at all.
128
+ *
129
+ * Every request issued via {@link Store.request | store.request(...)}
130
+ * automatically carries the originating store along as
131
+ * {@link RequestInfo.store | context.request.store}. Any handler — a plain
132
+ * object, a function-built handler, or a class — can read it directly,
133
+ * without needing the `handlers` callback form shown above:
134
+ *
135
+ * ```ts
136
+ * import { useLegacyStore } from '@warp-drive/legacy';
137
+ * import type { NextFn } from '@warp-drive/core/request';
138
+ * import type { RequestContext } from '@warp-drive/core/types/request';
139
+ * import { JSONAPICache } from '@warp-drive/json-api';
140
+ *
141
+ * const LoggingHandler = {
142
+ * request<T>(context: RequestContext, next: NextFn<T>) {
143
+ * // only present when the request was made via `store.request(...)`
144
+ * const store = context.request.store;
145
+ * if (store) {
146
+ * console.log(`[${store.constructor.name}] ${context.request.url ?? ''}`);
147
+ * }
148
+ * return next(context.request);
149
+ * },
150
+ * };
151
+ *
152
+ * export default useLegacyStore({
153
+ * linksMode: false,
154
+ * legacyRequests: true,
155
+ * cache: JSONAPICache,
156
+ * handlers: [LoggingHandler],
157
+ * });
158
+ * ```
159
+ *
160
+ * The trade-off versus the `getOwner`/`setOwner` pattern above is that
161
+ * `context.request.store` is only populated for requests issued via
162
+ * `store.request(...)`; a request made directly against a
163
+ * {@link RequestManager} won't have it set unless the caller supplies it
164
+ * explicitly, so a handler relying on it should treat it as optional (as
165
+ * `LoggingHandler` does above).
26
166
  */
27
167
  function useLegacyStore(options, StoreKlass = Store) {
28
168
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
@@ -33,7 +173,30 @@ function useLegacyStore(options, StoreKlass = Store) {
33
173
  // we extend the store to ensure we don't leak our prototype overrides to other stores below.
34
174
  class BaseKlass extends StoreKlass {}
35
175
  class LegacyConfiguredStore extends BaseKlass {
36
- requestManager = new RequestManager().use([options.linksMode ? null : LegacyNetworkHandler, ...(options.handlers ?? []), Fetch].filter(Boolean)).useCache(CacheHandler);
176
+ constructor(createArgs) {
177
+ super(createArgs);
178
+ // installed via defineProperty (rather than a class field/accessor) so that
179
+ // this lazy override of the inherited `requestManager` field does not
180
+ // conflict with the documented pattern of assigning it directly on
181
+ // consumer-authored Store subclasses. The setter preserves the ability
182
+ // to replace `requestManager` outright after construction.
183
+ let requestManager;
184
+ Object.defineProperty(this, 'requestManager', {
185
+ configurable: true,
186
+ enumerable: true,
187
+ get: () => {
188
+ if (!requestManager) {
189
+ const handlersOption = options.handlers;
190
+ const handlers = typeof handlersOption === 'function' ? handlersOption(this) : handlersOption ?? [];
191
+ requestManager = new RequestManager().use([options.linksMode ? null : LegacyNetworkHandler, ...handlers, Fetch].filter(Boolean)).useCache(CacheHandler);
192
+ }
193
+ return requestManager;
194
+ },
195
+ set: value => {
196
+ requestManager = value;
197
+ }
198
+ });
199
+ }
37
200
  lifetimes = options.policy ?? new DefaultCachePolicy({
38
201
  apiCacheHardExpires: 15 * 60 * 1000,
39
202
  // 15 minutes
@@ -113,14 +276,6 @@ function useLegacyStore(options, StoreKlass = Store) {
113
276
  }
114
277
  modelFor(type) {
115
278
  assertType(this.schema, type);
116
- // TODO I'm not sure this is right
117
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
118
- if (!test) {
119
- throw new Error(`modelFor should only be used to lookup legacy models when in linksMode: false`);
120
- }
121
- })(!options.linksMode || !this.schema.isDelegated({
122
- type
123
- })) : {};
124
279
  const klass =
125
280
  // prefer real models if present
126
281
  modelFor.call(this, type) || (