@ember-data/request-utils 5.3.3 → 5.3.5
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 +10 -0
- package/addon-main.cjs +5 -0
- package/dist/deprecation-support.js +76 -0
- package/dist/deprecation-support.js.map +1 -0
- package/{addon → dist}/index.js +197 -45
- package/dist/index.js.map +1 -0
- package/dist/inflect-CuaHncAE.js +311 -0
- package/dist/inflect-CuaHncAE.js.map +1 -0
- package/dist/string.js +1 -0
- package/dist/string.js.map +1 -0
- package/package.json +53 -39
- package/unstable-preview-types/-private/string/inflect.d.ts +14 -0
- package/unstable-preview-types/-private/string/inflect.d.ts.map +1 -0
- package/unstable-preview-types/-private/string/inflections.d.ts +12 -0
- package/unstable-preview-types/-private/string/inflections.d.ts.map +1 -0
- package/unstable-preview-types/-private/string/transform.d.ts +81 -0
- package/unstable-preview-types/-private/string/transform.d.ts.map +1 -0
- package/unstable-preview-types/deprecation-support.d.ts +4 -0
- package/unstable-preview-types/deprecation-support.d.ts.map +1 -0
- package/unstable-preview-types/index.d.ts +490 -0
- package/unstable-preview-types/index.d.ts.map +1 -0
- package/unstable-preview-types/string.d.ts +5 -0
- package/unstable-preview-types/string.d.ts.map +1 -0
- package/addon/index.js.map +0 -1
- package/addon-main.js +0 -19
package/README.md
CHANGED
|
@@ -28,6 +28,16 @@ Install using your javascript package manager of choice. For instance with [pnpm
|
|
|
28
28
|
```no-highlight
|
|
29
29
|
pnpm add @ember-data/request-utils
|
|
30
30
|
```
|
|
31
|
+
|
|
32
|
+
**Tagged Releases**
|
|
33
|
+
|
|
34
|
+
- 
|
|
35
|
+
- 
|
|
36
|
+
- 
|
|
37
|
+
- 
|
|
38
|
+
- 
|
|
39
|
+
|
|
40
|
+
|
|
31
41
|
## Utils
|
|
32
42
|
|
|
33
43
|
- [buildBaseUrl]()
|
package/addon-main.cjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { deprecate } from '@ember/debug';
|
|
2
|
+
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
3
|
+
import { b as plural, a as singular, i as irregular, u as uncountable } from "./inflect-CuaHncAE.js";
|
|
4
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_EMBER_INFLECTOR)) {
|
|
5
|
+
if (macroCondition(dependencySatisfies('ember-inflector', '*'))) {
|
|
6
|
+
const Inflector = importSync('ember-inflector').default;
|
|
7
|
+
const {
|
|
8
|
+
inflector
|
|
9
|
+
} = Inflector;
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
12
|
+
const originalPlural = inflector.plural;
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
14
|
+
const originalSingular = inflector.singular;
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
16
|
+
const originalIrregular = inflector.irregular;
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
18
|
+
const originalUncountable = inflector.uncountable;
|
|
19
|
+
inflector.plural = function (...args) {
|
|
20
|
+
plural(...args);
|
|
21
|
+
deprecate(`WarpDrive/EmberData no longer uses ember-inflector for pluralization.\nPlease \`import { plural } from '@ember-data/request-utils/string';\` instead to register a custom pluralization rule for use with EmberData.`, false, {
|
|
22
|
+
id: 'warp-drive.ember-inflector',
|
|
23
|
+
until: '6.0.0',
|
|
24
|
+
for: 'warp-drive',
|
|
25
|
+
since: {
|
|
26
|
+
enabled: '5.3.4',
|
|
27
|
+
available: '5.3.4'
|
|
28
|
+
},
|
|
29
|
+
url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector'
|
|
30
|
+
});
|
|
31
|
+
return originalPlural.apply(inflector, args);
|
|
32
|
+
};
|
|
33
|
+
inflector.singular = function (...args) {
|
|
34
|
+
singular(...args);
|
|
35
|
+
deprecate(`WarpDrive/EmberData no longer uses ember-inflector for singularization.\nPlease \`import { singular } from '@ember-data/request-utils/string';\` instead to register a custom singularization rule for use with EmberData.`, false, {
|
|
36
|
+
id: 'warp-drive.ember-inflector',
|
|
37
|
+
until: '6.0.0',
|
|
38
|
+
for: 'warp-drive',
|
|
39
|
+
since: {
|
|
40
|
+
enabled: '5.3.4',
|
|
41
|
+
available: '5.3.4'
|
|
42
|
+
},
|
|
43
|
+
url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector'
|
|
44
|
+
});
|
|
45
|
+
return originalSingular.apply(inflector, args);
|
|
46
|
+
};
|
|
47
|
+
inflector.irregular = function (...args) {
|
|
48
|
+
irregular(...args);
|
|
49
|
+
deprecate(`WarpDrive/EmberData no longer uses ember-inflector for irregular rules.\nPlease \`import { irregular } from '@ember-data/request-utils/string';\` instead to register a custom irregular rule for use with EmberData.`, false, {
|
|
50
|
+
id: 'warp-drive.ember-inflector',
|
|
51
|
+
until: '6.0.0',
|
|
52
|
+
for: 'warp-drive',
|
|
53
|
+
since: {
|
|
54
|
+
enabled: '5.3.4',
|
|
55
|
+
available: '5.3.4'
|
|
56
|
+
},
|
|
57
|
+
url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector'
|
|
58
|
+
});
|
|
59
|
+
return originalIrregular.apply(inflector, args);
|
|
60
|
+
};
|
|
61
|
+
inflector.uncountable = function (...args) {
|
|
62
|
+
uncountable(...args);
|
|
63
|
+
deprecate(`WarpDrive/EmberData no longer uses ember-inflector for uncountable rules.\nPlease \`import { uncountable } from '@ember-data/request-utils/string';\` instead to register a custom uncountable rule for use with EmberData.`, false, {
|
|
64
|
+
id: 'warp-drive.ember-inflector',
|
|
65
|
+
until: '6.0.0',
|
|
66
|
+
for: 'warp-drive',
|
|
67
|
+
since: {
|
|
68
|
+
enabled: '5.3.4',
|
|
69
|
+
available: '5.3.4'
|
|
70
|
+
},
|
|
71
|
+
url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector'
|
|
72
|
+
});
|
|
73
|
+
return originalUncountable.apply(inflector, args);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecation-support.js","sources":["../src/deprecation-support.ts"],"sourcesContent":["import { deprecate } from '@ember/debug';\n\nimport { dependencySatisfies, importSync, macroCondition } from '@embroider/macros';\n\nimport { DEPRECATE_EMBER_INFLECTOR } from '@warp-drive/build-config/deprecations';\n\nimport { irregular, plural, singular, uncountable } from './string';\n\nif (DEPRECATE_EMBER_INFLECTOR) {\n if (macroCondition(dependencySatisfies('ember-inflector', '*'))) {\n const Inflector = (importSync('ember-inflector') as { default: typeof import('ember-inflector').default }).default;\n const { inflector } = Inflector;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalPlural = inflector.plural;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalSingular = inflector.singular;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalIrregular = inflector.irregular;\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalUncountable = inflector.uncountable;\n\n inflector.plural = function (...args: Parameters<typeof originalPlural>) {\n plural(...args);\n\n deprecate(\n `WarpDrive/EmberData no longer uses ember-inflector for pluralization.\\nPlease \\`import { plural } from '@ember-data/request-utils/string';\\` instead to register a custom pluralization rule for use with EmberData.`,\n false,\n {\n id: 'warp-drive.ember-inflector',\n until: '6.0.0',\n for: 'warp-drive',\n since: {\n enabled: '5.3.4',\n available: '5.3.4',\n },\n url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector',\n }\n );\n\n return originalPlural.apply(inflector, args);\n };\n\n inflector.singular = function (...args: Parameters<typeof originalSingular>) {\n singular(...args);\n\n deprecate(\n `WarpDrive/EmberData no longer uses ember-inflector for singularization.\\nPlease \\`import { singular } from '@ember-data/request-utils/string';\\` instead to register a custom singularization rule for use with EmberData.`,\n false,\n {\n id: 'warp-drive.ember-inflector',\n until: '6.0.0',\n for: 'warp-drive',\n since: {\n enabled: '5.3.4',\n available: '5.3.4',\n },\n url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector',\n }\n );\n\n return originalSingular.apply(inflector, args);\n };\n\n inflector.irregular = function (...args: Parameters<typeof originalIrregular>) {\n irregular(...args);\n\n deprecate(\n `WarpDrive/EmberData no longer uses ember-inflector for irregular rules.\\nPlease \\`import { irregular } from '@ember-data/request-utils/string';\\` instead to register a custom irregular rule for use with EmberData.`,\n false,\n {\n id: 'warp-drive.ember-inflector',\n until: '6.0.0',\n for: 'warp-drive',\n since: {\n enabled: '5.3.4',\n available: '5.3.4',\n },\n url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector',\n }\n );\n\n return originalIrregular.apply(inflector, args);\n };\n\n inflector.uncountable = function (...args: Parameters<typeof originalUncountable>) {\n uncountable(...args);\n\n deprecate(\n `WarpDrive/EmberData no longer uses ember-inflector for uncountable rules.\\nPlease \\`import { uncountable } from '@ember-data/request-utils/string';\\` instead to register a custom uncountable rule for use with EmberData.`,\n false,\n {\n id: 'warp-drive.ember-inflector',\n until: '6.0.0',\n for: 'warp-drive',\n since: {\n enabled: '5.3.4',\n available: '5.3.4',\n },\n url: 'https://deprecations.emberjs.com/id/warp-drive.ember-inflector',\n }\n );\n\n return originalUncountable.apply(inflector, args);\n };\n }\n}\n"],"names":["macroCondition","getGlobalConfig","WarpDrive","deprecations","DEPRECATE_EMBER_INFLECTOR","dependencySatisfies","Inflector","importSync","default","inflector","originalPlural","plural","originalSingular","singular","originalIrregular","irregular","originalUncountable","uncountable","args","deprecate","id","until","for","since","enabled","available","url","apply"],"mappings":"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"}
|
package/{addon → dist}/index.js
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deprecate } from '@ember/debug';
|
|
2
|
+
import { macroCondition, getGlobalConfig } from '@embroider/macros';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Simple utility function to assist in url building,
|
|
@@ -39,11 +40,9 @@ import { assert, deprecate } from '@ember/debug';
|
|
|
39
40
|
* @main @ember-data/request-utils
|
|
40
41
|
* @public
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
43
|
// prevents the final constructed object from needing to add
|
|
44
44
|
// host and namespace which are provided by the final consuming
|
|
45
45
|
// class to the prototype which can result in overwrite errors
|
|
46
|
-
|
|
47
46
|
const CONFIG = {
|
|
48
47
|
host: '',
|
|
49
48
|
namespace: ''
|
|
@@ -90,13 +89,33 @@ const CONFIG = {
|
|
|
90
89
|
* @return void
|
|
91
90
|
*/
|
|
92
91
|
function setBuildURLConfig(config) {
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
93
|
+
if (!test) {
|
|
94
|
+
throw new Error(`setBuildURLConfig: You must pass a config object`);
|
|
95
|
+
}
|
|
96
|
+
})(config) : {};
|
|
97
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
98
|
+
if (!test) {
|
|
99
|
+
throw new Error(`setBuildURLConfig: You must pass a config object with a 'host' or 'namespace' property`);
|
|
100
|
+
}
|
|
101
|
+
})('host' in config || 'namespace' in config) : {};
|
|
95
102
|
CONFIG.host = config.host || '';
|
|
96
103
|
CONFIG.namespace = config.namespace || '';
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
105
|
+
if (!test) {
|
|
106
|
+
throw new Error(`buildBaseURL: host must NOT end with '/', received '${CONFIG.host}'`);
|
|
107
|
+
}
|
|
108
|
+
})(CONFIG.host === '/' || !CONFIG.host.endsWith('/')) : {};
|
|
109
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
110
|
+
if (!test) {
|
|
111
|
+
throw new Error(`buildBaseURL: namespace must NOT start with '/', received '${CONFIG.namespace}'`);
|
|
112
|
+
}
|
|
113
|
+
})(!CONFIG.namespace.startsWith('/')) : {};
|
|
114
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
115
|
+
if (!test) {
|
|
116
|
+
throw new Error(`buildBaseURL: namespace must NOT end with '/', received '${CONFIG.namespace}'`);
|
|
117
|
+
}
|
|
118
|
+
})(!CONFIG.namespace.endsWith('/')) : {};
|
|
100
119
|
}
|
|
101
120
|
const OPERATIONS_WITH_PRIMARY_RECORDS = new Set(['findRecord', 'findRelatedRecord', 'findRelatedCollection', 'updateRecord', 'deleteRecord']);
|
|
102
121
|
function isOperationWithPrimaryRecord(options) {
|
|
@@ -106,7 +125,11 @@ function hasResourcePath(options) {
|
|
|
106
125
|
return 'resourcePath' in options && typeof options.resourcePath === 'string' && options.resourcePath.length > 0;
|
|
107
126
|
}
|
|
108
127
|
function resourcePathForType(options) {
|
|
109
|
-
|
|
128
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
129
|
+
if (!test) {
|
|
130
|
+
throw new Error(`resourcePathForType: You must pass a valid op as part of options`);
|
|
131
|
+
}
|
|
132
|
+
})('op' in options && typeof options.op === 'string') : {};
|
|
110
133
|
return options.op === 'findMany' ? options.identifiers[0].type : options.identifier.type;
|
|
111
134
|
}
|
|
112
135
|
|
|
@@ -156,13 +179,41 @@ function buildBaseURL(urlOptions) {
|
|
|
156
179
|
host: CONFIG.host,
|
|
157
180
|
namespace: CONFIG.namespace
|
|
158
181
|
}, urlOptions);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
182
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
183
|
+
if (!test) {
|
|
184
|
+
throw new Error(`buildBaseURL: You must pass \`op\` as part of options`);
|
|
185
|
+
}
|
|
186
|
+
})(hasResourcePath(options) || typeof options.op === 'string' && options.op.length > 0) : {};
|
|
187
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
188
|
+
if (!test) {
|
|
189
|
+
throw new Error(`buildBaseURL: You must pass \`identifier\` as part of options`);
|
|
190
|
+
}
|
|
191
|
+
})(hasResourcePath(options) || options.op === 'findMany' || options.identifier && typeof options.identifier === 'object') : {};
|
|
192
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
193
|
+
if (!test) {
|
|
194
|
+
throw new Error(`buildBaseURL: You must pass \`identifiers\` as part of options`);
|
|
195
|
+
}
|
|
196
|
+
})(hasResourcePath(options) || options.op !== 'findMany' || options.identifiers && Array.isArray(options.identifiers) && options.identifiers.length > 0 && options.identifiers.every(i => i && typeof i === 'object')) : {};
|
|
197
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
198
|
+
if (!test) {
|
|
199
|
+
throw new Error(`buildBaseURL: You must pass valid \`identifier\` as part of options, expected 'id'`);
|
|
200
|
+
}
|
|
201
|
+
})(hasResourcePath(options) || !isOperationWithPrimaryRecord(options) || typeof options.identifier.id === 'string' && options.identifier.id.length > 0) : {};
|
|
202
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
203
|
+
if (!test) {
|
|
204
|
+
throw new Error(`buildBaseURL: You must pass \`identifiers\` as part of options`);
|
|
205
|
+
}
|
|
206
|
+
})(hasResourcePath(options) || options.op !== 'findMany' || options.identifiers.every(i => typeof i.id === 'string' && i.id.length > 0)) : {};
|
|
207
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
208
|
+
if (!test) {
|
|
209
|
+
throw new Error(`buildBaseURL: You must pass valid \`identifier\` as part of options, expected 'type'`);
|
|
210
|
+
}
|
|
211
|
+
})(hasResourcePath(options) || options.op === 'findMany' || typeof options.identifier.type === 'string' && options.identifier.type.length > 0) : {};
|
|
212
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
213
|
+
if (!test) {
|
|
214
|
+
throw new Error(`buildBaseURL: You must pass valid \`identifiers\` as part of options, expected 'type'`);
|
|
215
|
+
}
|
|
216
|
+
})(hasResourcePath(options) || options.op !== 'findMany' || typeof options.identifiers[0].type === 'string' && options.identifiers[0].type.length > 0) : {};
|
|
166
217
|
|
|
167
218
|
// prettier-ignore
|
|
168
219
|
const idPath = isOperationWithPrimaryRecord(options) ? encodeURIComponent(options.identifier.id) : '';
|
|
@@ -172,16 +223,56 @@ function buildBaseURL(urlOptions) {
|
|
|
172
223
|
namespace
|
|
173
224
|
} = options;
|
|
174
225
|
const fieldPath = 'fieldPath' in options ? options.fieldPath : '';
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
226
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
227
|
+
if (!test) {
|
|
228
|
+
throw new Error(`buildBaseURL: You tried to build a url for a ${String('op' in options ? options.op + ' ' : '')}request to ${resourcePath} but resourcePath must be set or op must be one of "${['findRecord', 'findRelatedRecord', 'findRelatedCollection', 'updateRecord', 'deleteRecord', 'createRecord', 'query', 'findMany'].join('","')}".`);
|
|
229
|
+
}
|
|
230
|
+
})(hasResourcePath(options) || ['findRecord', 'query', 'findMany', 'findRelatedCollection', 'findRelatedRecord', 'createRecord', 'updateRecord', 'deleteRecord'].includes(options.op)) : {};
|
|
231
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
232
|
+
if (!test) {
|
|
233
|
+
throw new Error(`buildBaseURL: host must NOT end with '/', received '${host}'`);
|
|
234
|
+
}
|
|
235
|
+
})(host === '/' || !host.endsWith('/')) : {};
|
|
236
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
237
|
+
if (!test) {
|
|
238
|
+
throw new Error(`buildBaseURL: namespace must NOT start with '/', received '${namespace}'`);
|
|
239
|
+
}
|
|
240
|
+
})(!namespace.startsWith('/')) : {};
|
|
241
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
242
|
+
if (!test) {
|
|
243
|
+
throw new Error(`buildBaseURL: namespace must NOT end with '/', received '${namespace}'`);
|
|
244
|
+
}
|
|
245
|
+
})(!namespace.endsWith('/')) : {};
|
|
246
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
247
|
+
if (!test) {
|
|
248
|
+
throw new Error(`buildBaseURL: resourcePath must NOT start with '/', received '${resourcePath}'`);
|
|
249
|
+
}
|
|
250
|
+
})(!resourcePath.startsWith('/')) : {};
|
|
251
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
252
|
+
if (!test) {
|
|
253
|
+
throw new Error(`buildBaseURL: resourcePath must NOT end with '/', received '${resourcePath}'`);
|
|
254
|
+
}
|
|
255
|
+
})(!resourcePath.endsWith('/')) : {};
|
|
256
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
257
|
+
if (!test) {
|
|
258
|
+
throw new Error(`buildBaseURL: fieldPath must NOT start with '/', received '${fieldPath}'`);
|
|
259
|
+
}
|
|
260
|
+
})(!fieldPath.startsWith('/')) : {};
|
|
261
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
262
|
+
if (!test) {
|
|
263
|
+
throw new Error(`buildBaseURL: fieldPath must NOT end with '/', received '${fieldPath}'`);
|
|
264
|
+
}
|
|
265
|
+
})(!fieldPath.endsWith('/')) : {};
|
|
266
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
267
|
+
if (!test) {
|
|
268
|
+
throw new Error(`buildBaseURL: idPath must NOT start with '/', received '${idPath}'`);
|
|
269
|
+
}
|
|
270
|
+
})(!idPath.startsWith('/')) : {};
|
|
271
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
272
|
+
if (!test) {
|
|
273
|
+
throw new Error(`buildBaseURL: idPath must NOT end with '/', received '${idPath}'`);
|
|
274
|
+
}
|
|
275
|
+
})(!idPath.endsWith('/')) : {};
|
|
185
276
|
const hasHost = host !== '' && host !== '/';
|
|
186
277
|
const url = [hasHost ? host : '', namespace, resourcePath, idPath, fieldPath].filter(Boolean).join('/');
|
|
187
278
|
return hasHost ? url : `/${url}`;
|
|
@@ -190,7 +281,11 @@ const DEFAULT_QUERY_PARAMS_SERIALIZATION_OPTIONS = {
|
|
|
190
281
|
arrayFormat: 'comma'
|
|
191
282
|
};
|
|
192
283
|
function handleInclude(include) {
|
|
193
|
-
|
|
284
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
285
|
+
if (!test) {
|
|
286
|
+
throw new Error(`Expected include to be a string or array, got ${typeof include}`);
|
|
287
|
+
}
|
|
288
|
+
})(typeof include === 'string' || Array.isArray(include)) : {};
|
|
194
289
|
return typeof include === 'string' ? include.split(',') : include;
|
|
195
290
|
}
|
|
196
291
|
|
|
@@ -358,14 +453,26 @@ function parseCacheControl(header) {
|
|
|
358
453
|
const cacheControlValue = {};
|
|
359
454
|
function parseCacheControlValue(stringToParse) {
|
|
360
455
|
const parsedValue = Number.parseInt(stringToParse);
|
|
361
|
-
|
|
456
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
457
|
+
if (!test) {
|
|
458
|
+
throw new Error(`Invalid Cache-Control value, expected a number but got - ${stringToParse}`);
|
|
459
|
+
}
|
|
460
|
+
})(!Number.isNaN(parsedValue)) : {};
|
|
362
461
|
return parsedValue;
|
|
363
462
|
}
|
|
364
463
|
for (let i = 0; i < header.length; i++) {
|
|
365
464
|
const char = header.charAt(i);
|
|
366
465
|
if (char === ',') {
|
|
367
|
-
|
|
368
|
-
|
|
466
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
467
|
+
if (!test) {
|
|
468
|
+
throw new Error(`Invalid Cache-Control value, expected a value`);
|
|
469
|
+
}
|
|
470
|
+
})(!isParsingKey || !NUMERIC_KEYS.has(key)) : {};
|
|
471
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
472
|
+
if (!test) {
|
|
473
|
+
throw new Error(`Invalid Cache-Control value, expected a value after "=" but got ","`);
|
|
474
|
+
}
|
|
475
|
+
})(i === 0 || header.charAt(i - 1) !== '=') : {};
|
|
369
476
|
isParsingKey = true;
|
|
370
477
|
// @ts-expect-error TS incorrectly thinks that optional keys must have a type that includes undefined
|
|
371
478
|
cacheControlValue[key] = NUMERIC_KEYS.has(key) ? parseCacheControlValue(value) : true;
|
|
@@ -373,7 +480,11 @@ function parseCacheControl(header) {
|
|
|
373
480
|
value = '';
|
|
374
481
|
continue;
|
|
375
482
|
} else if (char === '=') {
|
|
376
|
-
|
|
483
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
484
|
+
if (!test) {
|
|
485
|
+
throw new Error(`Invalid Cache-Control value, expected a value after "="`);
|
|
486
|
+
}
|
|
487
|
+
})(i + 1 !== header.length) : {};
|
|
377
488
|
isParsingKey = false;
|
|
378
489
|
} else if (char === ' ' || char === `\t` || char === `\n`) {
|
|
379
490
|
continue;
|
|
@@ -405,7 +516,7 @@ function isStale(headers, expirationTime) {
|
|
|
405
516
|
return result;
|
|
406
517
|
}
|
|
407
518
|
/**
|
|
408
|
-
* A basic
|
|
519
|
+
* A basic CachePolicy that can be added to the Store service.
|
|
409
520
|
*
|
|
410
521
|
* Determines staleness based on time since the request was last received from the API
|
|
411
522
|
* using the `date` header.
|
|
@@ -413,19 +524,30 @@ function isStale(headers, expirationTime) {
|
|
|
413
524
|
* Invalidates any request for which `cacheOptions.types` was provided when a createRecord
|
|
414
525
|
* request for that type is successful.
|
|
415
526
|
*
|
|
527
|
+
* For this to work, the `createRecord` request must include the `cacheOptions.types` array
|
|
528
|
+
* with the types that should be invalidated, or its request should specify the identifiers
|
|
529
|
+
* of the records that are being created via `records`. Providing both is valid.
|
|
530
|
+
*
|
|
531
|
+
* > [!NOTE]
|
|
532
|
+
* > only requests that had specified `cacheOptions.types` and occurred prior to the
|
|
533
|
+
* > createRecord request will be invalidated. This means that a given request should always
|
|
534
|
+
* > specify the types that would invalidate it to opt into this behavior. Abstracting this
|
|
535
|
+
* > behavior via builders is recommended to ensure consistency.
|
|
536
|
+
*
|
|
416
537
|
* This allows the Store's CacheHandler to determine if a request is expired and
|
|
417
538
|
* should be refetched upon next request.
|
|
418
539
|
*
|
|
419
540
|
* The `Fetch` handler provided by `@ember-data/request/fetch` will automatically
|
|
420
541
|
* add the `date` header to responses if it is not present.
|
|
421
542
|
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
543
|
+
* > [!NOTE]
|
|
544
|
+
* > Date headers do not have millisecond precision, so expiration times should
|
|
545
|
+
* > generally be larger than 1000ms.
|
|
424
546
|
*
|
|
425
547
|
* Usage:
|
|
426
548
|
*
|
|
427
549
|
* ```ts
|
|
428
|
-
* import {
|
|
550
|
+
* import { CachePolicy } from '@ember-data/request-utils';
|
|
429
551
|
* import DataStore from '@ember-data/store';
|
|
430
552
|
*
|
|
431
553
|
* // ...
|
|
@@ -433,16 +555,16 @@ function isStale(headers, expirationTime) {
|
|
|
433
555
|
* export class Store extends DataStore {
|
|
434
556
|
* constructor(args) {
|
|
435
557
|
* super(args);
|
|
436
|
-
* this.lifetimes = new
|
|
558
|
+
* this.lifetimes = new CachePolicy({ apiCacheSoftExpires: 30_000, apiCacheHardExpires: 60_000 });
|
|
437
559
|
* }
|
|
438
560
|
* }
|
|
439
561
|
* ```
|
|
440
562
|
*
|
|
441
|
-
* @class
|
|
563
|
+
* @class CachePolicy
|
|
442
564
|
* @public
|
|
443
565
|
* @module @ember-data/request-utils
|
|
444
566
|
*/
|
|
445
|
-
class
|
|
567
|
+
class CachePolicy {
|
|
446
568
|
_getStore(store) {
|
|
447
569
|
let set = this._stores.get(store);
|
|
448
570
|
if (!set) {
|
|
@@ -457,7 +579,7 @@ class LifetimesService {
|
|
|
457
579
|
constructor(config) {
|
|
458
580
|
this._stores = new WeakMap();
|
|
459
581
|
const _config = arguments.length === 1 ? config : arguments[1];
|
|
460
|
-
deprecate(`Passing a Store to the
|
|
582
|
+
deprecate(`Passing a Store to the CachePolicy is deprecated, please pass only a config instead.`, arguments.length === 1, {
|
|
461
583
|
id: 'ember-data:request-utils:lifetimes-service-store-arg',
|
|
462
584
|
since: {
|
|
463
585
|
enabled: '5.4',
|
|
@@ -466,16 +588,28 @@ class LifetimesService {
|
|
|
466
588
|
for: '@ember-data/request-utils',
|
|
467
589
|
until: '6.0'
|
|
468
590
|
});
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
591
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
592
|
+
if (!test) {
|
|
593
|
+
throw new Error(`You must pass a config to the CachePolicy`);
|
|
594
|
+
}
|
|
595
|
+
})(_config) : {};
|
|
596
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
597
|
+
if (!test) {
|
|
598
|
+
throw new Error(`You must pass a apiCacheSoftExpires to the CachePolicy`);
|
|
599
|
+
}
|
|
600
|
+
})(typeof _config.apiCacheSoftExpires === 'number') : {};
|
|
601
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
602
|
+
if (!test) {
|
|
603
|
+
throw new Error(`You must pass a apiCacheHardExpires to the CachePolicy`);
|
|
604
|
+
}
|
|
605
|
+
})(typeof _config.apiCacheHardExpires === 'number') : {};
|
|
472
606
|
this.config = _config;
|
|
473
607
|
}
|
|
474
608
|
|
|
475
609
|
/**
|
|
476
610
|
* Invalidate a request by its identifier for a given store instance.
|
|
477
611
|
*
|
|
478
|
-
* While the store argument may seem redundant, the
|
|
612
|
+
* While the store argument may seem redundant, the CachePolicy
|
|
479
613
|
* is designed to be shared across multiple stores / forks
|
|
480
614
|
* of the store.
|
|
481
615
|
*
|
|
@@ -496,7 +630,7 @@ class LifetimesService {
|
|
|
496
630
|
* Invalidate all requests associated to a specific type
|
|
497
631
|
* for a given store instance.
|
|
498
632
|
*
|
|
499
|
-
* While the store argument may seem redundant, the
|
|
633
|
+
* While the store argument may seem redundant, the CachePolicy
|
|
500
634
|
* is designed to be shared across multiple stores / forks
|
|
501
635
|
* of the store.
|
|
502
636
|
*
|
|
@@ -546,6 +680,10 @@ class LifetimesService {
|
|
|
546
680
|
const statusNumber = response?.status ?? 0;
|
|
547
681
|
if (statusNumber >= 200 && statusNumber < 400) {
|
|
548
682
|
const types = new Set(request.records?.map(r => r.type));
|
|
683
|
+
const additionalTypes = request.cacheOptions?.types;
|
|
684
|
+
additionalTypes?.forEach(type => {
|
|
685
|
+
types.add(type);
|
|
686
|
+
});
|
|
549
687
|
types.forEach(type => {
|
|
550
688
|
this.invalidateRequestsForType(type, store);
|
|
551
689
|
});
|
|
@@ -617,4 +755,18 @@ class LifetimesService {
|
|
|
617
755
|
return !cached || !cached.response || isStale(cached.response.headers, this.config.apiCacheSoftExpires);
|
|
618
756
|
}
|
|
619
757
|
}
|
|
620
|
-
|
|
758
|
+
class LifetimesService extends CachePolicy {
|
|
759
|
+
constructor(config) {
|
|
760
|
+
deprecate(`\`import { LifetimesService } from '@ember-data/request-utils';\` is deprecated, please use \`import { CachePolicy } from '@ember-data/request-utils';\` instead.`, false, {
|
|
761
|
+
id: 'ember-data:deprecate-lifetimes-service-import',
|
|
762
|
+
since: {
|
|
763
|
+
enabled: '5.4',
|
|
764
|
+
available: '5.4'
|
|
765
|
+
},
|
|
766
|
+
for: 'ember-data',
|
|
767
|
+
until: '6.0'
|
|
768
|
+
});
|
|
769
|
+
super(config);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
export { CachePolicy, LifetimesService, buildBaseURL, buildQueryParams, filterEmpty, parseCacheControl, setBuildURLConfig, sortQueryParams };
|