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