@warp-drive/utilities 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 (150) hide show
  1. package/cjs-dist/string.cjs +448 -0
  2. package/cjs-dist/string.cjs.map +1 -0
  3. package/declarations/-private.d.ts +12 -1
  4. package/declarations/-private.d.ts.map +1 -0
  5. package/declarations/active-record.d.ts +260 -3
  6. package/declarations/active-record.d.ts.map +1 -0
  7. package/declarations/derivations.d.ts +26 -23
  8. package/declarations/derivations.d.ts.map +1 -0
  9. package/declarations/handlers.d.ts +282 -9
  10. package/declarations/handlers.d.ts.map +1 -0
  11. package/declarations/index-BeMAuqgZ.d.ts +462 -0
  12. package/declarations/index-BeMAuqgZ.d.ts.map +1 -0
  13. package/declarations/index.d.ts +2 -208
  14. package/declarations/json-api.d.ts +496 -5
  15. package/declarations/json-api.d.ts.map +1 -0
  16. package/declarations/rest.d.ts +258 -3
  17. package/declarations/rest.d.ts.map +1 -0
  18. package/declarations/string.d.ts +164 -13
  19. package/declarations/string.d.ts.map +1 -0
  20. package/dist/-private.js +2 -6
  21. package/dist/active-record.js +254 -379
  22. package/dist/active-record.js.map +1 -0
  23. package/dist/builder-utils-BkXwUT0x.js +16 -0
  24. package/dist/builder-utils-BkXwUT0x.js.map +1 -0
  25. package/dist/derivations.js +26 -26
  26. package/dist/derivations.js.map +1 -0
  27. package/dist/handlers.js +240 -283
  28. package/dist/handlers.js.map +1 -0
  29. package/dist/index.js +357 -335
  30. package/dist/index.js.map +1 -0
  31. package/dist/inflections-DzBsjJqj.js +80 -0
  32. package/dist/inflections-DzBsjJqj.js.map +1 -0
  33. package/dist/json-api.js +470 -706
  34. package/dist/json-api.js.map +1 -0
  35. package/dist/rest.js +254 -377
  36. package/dist/rest.js.map +1 -0
  37. package/dist/string-CWmAluxh.js +290 -0
  38. package/dist/string-CWmAluxh.js.map +1 -0
  39. package/dist/string.js +2 -427
  40. package/dist/unpkg/dev/-private.js +2 -6
  41. package/dist/unpkg/dev/active-record.js +253 -378
  42. package/dist/unpkg/dev/active-record.js.map +1 -0
  43. package/dist/unpkg/dev/builder-utils-BkXwUT0x.js +16 -0
  44. package/dist/unpkg/dev/builder-utils-BkXwUT0x.js.map +1 -0
  45. package/dist/unpkg/dev/derivations.js +26 -26
  46. package/dist/unpkg/dev/derivations.js.map +1 -0
  47. package/dist/unpkg/dev/handlers.js +238 -282
  48. package/dist/unpkg/dev/handlers.js.map +1 -0
  49. package/dist/unpkg/dev/index.js +356 -336
  50. package/dist/unpkg/dev/index.js.map +1 -0
  51. package/dist/unpkg/dev/inflections-DzBsjJqj.js +80 -0
  52. package/dist/unpkg/dev/inflections-DzBsjJqj.js.map +1 -0
  53. package/dist/unpkg/dev/json-api.js +469 -706
  54. package/dist/unpkg/dev/json-api.js.map +1 -0
  55. package/dist/unpkg/dev/rest.js +253 -376
  56. package/dist/unpkg/dev/rest.js.map +1 -0
  57. package/dist/unpkg/dev/string-j4ur-TDs.js +289 -0
  58. package/dist/unpkg/dev/string-j4ur-TDs.js.map +1 -0
  59. package/dist/unpkg/dev/string.js +3 -1
  60. package/dist/unpkg/dev-deprecated/-private.js +2 -6
  61. package/dist/unpkg/dev-deprecated/active-record.js +253 -378
  62. package/dist/unpkg/dev-deprecated/active-record.js.map +1 -0
  63. package/dist/unpkg/dev-deprecated/builder-utils-BkXwUT0x.js +16 -0
  64. package/dist/unpkg/dev-deprecated/builder-utils-BkXwUT0x.js.map +1 -0
  65. package/dist/unpkg/dev-deprecated/derivations.js +26 -26
  66. package/dist/unpkg/dev-deprecated/derivations.js.map +1 -0
  67. package/dist/unpkg/dev-deprecated/handlers.js +238 -282
  68. package/dist/unpkg/dev-deprecated/handlers.js.map +1 -0
  69. package/dist/unpkg/dev-deprecated/index.js +356 -336
  70. package/dist/unpkg/dev-deprecated/index.js.map +1 -0
  71. package/dist/unpkg/dev-deprecated/inflections-DzBsjJqj.js +80 -0
  72. package/dist/unpkg/dev-deprecated/inflections-DzBsjJqj.js.map +1 -0
  73. package/dist/unpkg/dev-deprecated/json-api.js +469 -706
  74. package/dist/unpkg/dev-deprecated/json-api.js.map +1 -0
  75. package/dist/unpkg/dev-deprecated/rest.js +253 -376
  76. package/dist/unpkg/dev-deprecated/rest.js.map +1 -0
  77. package/dist/unpkg/dev-deprecated/string-j4ur-TDs.js +289 -0
  78. package/dist/unpkg/dev-deprecated/string-j4ur-TDs.js.map +1 -0
  79. package/dist/unpkg/dev-deprecated/string.js +3 -1
  80. package/dist/unpkg/prod/-private.js +2 -6
  81. package/dist/unpkg/prod/active-record.js +236 -351
  82. package/dist/unpkg/prod/active-record.js.map +1 -0
  83. package/dist/unpkg/prod/builder-utils-BkXwUT0x.js +16 -0
  84. package/dist/unpkg/prod/builder-utils-BkXwUT0x.js.map +1 -0
  85. package/dist/unpkg/prod/derivations.js +26 -26
  86. package/dist/unpkg/prod/derivations.js.map +1 -0
  87. package/dist/unpkg/prod/handlers.js +231 -272
  88. package/dist/unpkg/prod/handlers.js.map +1 -0
  89. package/dist/unpkg/prod/index.js +265 -215
  90. package/dist/unpkg/prod/index.js.map +1 -0
  91. package/dist/unpkg/prod/inflections-DzBsjJqj.js +80 -0
  92. package/dist/unpkg/prod/inflections-DzBsjJqj.js.map +1 -0
  93. package/dist/unpkg/prod/json-api.js +446 -669
  94. package/dist/unpkg/prod/json-api.js.map +1 -0
  95. package/dist/unpkg/prod/rest.js +236 -349
  96. package/dist/unpkg/prod/rest.js.map +1 -0
  97. package/dist/unpkg/prod/string-T1ahjLdj.js +283 -0
  98. package/dist/unpkg/prod/string-T1ahjLdj.js.map +1 -0
  99. package/dist/unpkg/prod/string.js +3 -1
  100. package/dist/unpkg/prod-deprecated/-private.js +2 -6
  101. package/dist/unpkg/prod-deprecated/active-record.js +236 -351
  102. package/dist/unpkg/prod-deprecated/active-record.js.map +1 -0
  103. package/dist/unpkg/prod-deprecated/builder-utils-BkXwUT0x.js +16 -0
  104. package/dist/unpkg/prod-deprecated/builder-utils-BkXwUT0x.js.map +1 -0
  105. package/dist/unpkg/prod-deprecated/derivations.js +26 -26
  106. package/dist/unpkg/prod-deprecated/derivations.js.map +1 -0
  107. package/dist/unpkg/prod-deprecated/handlers.js +231 -272
  108. package/dist/unpkg/prod-deprecated/handlers.js.map +1 -0
  109. package/dist/unpkg/prod-deprecated/index.js +265 -215
  110. package/dist/unpkg/prod-deprecated/index.js.map +1 -0
  111. package/dist/unpkg/prod-deprecated/inflections-DzBsjJqj.js +80 -0
  112. package/dist/unpkg/prod-deprecated/inflections-DzBsjJqj.js.map +1 -0
  113. package/dist/unpkg/prod-deprecated/json-api.js +446 -669
  114. package/dist/unpkg/prod-deprecated/json-api.js.map +1 -0
  115. package/dist/unpkg/prod-deprecated/rest.js +236 -349
  116. package/dist/unpkg/prod-deprecated/rest.js.map +1 -0
  117. package/dist/unpkg/prod-deprecated/string-T1ahjLdj.js +283 -0
  118. package/dist/unpkg/prod-deprecated/string-T1ahjLdj.js.map +1 -0
  119. package/dist/unpkg/prod-deprecated/string.js +3 -1
  120. package/package.json +11 -10
  121. package/declarations/-private/active-record/find-record.d.ts +0 -64
  122. package/declarations/-private/active-record/query.d.ts +0 -53
  123. package/declarations/-private/active-record/save-record.d.ts +0 -146
  124. package/declarations/-private/builder-utils.d.ts +0 -4
  125. package/declarations/-private/handlers/auto-compress.d.ts +0 -158
  126. package/declarations/-private/handlers/gated.d.ts +0 -19
  127. package/declarations/-private/handlers/meta-doc.d.ts +0 -47
  128. package/declarations/-private/handlers/utils.d.ts +0 -41
  129. package/declarations/-private/json-api/-utils.d.ts +0 -109
  130. package/declarations/-private/json-api/find-record.d.ts +0 -84
  131. package/declarations/-private/json-api/query.d.ts +0 -100
  132. package/declarations/-private/json-api/save-record.d.ts +0 -228
  133. package/declarations/-private/json-api/serialize.d.ts +0 -70
  134. package/declarations/-private/rest/find-record.d.ts +0 -62
  135. package/declarations/-private/rest/query.d.ts +0 -53
  136. package/declarations/-private/rest/save-record.d.ts +0 -146
  137. package/declarations/-private/string/inflect.d.ts +0 -82
  138. package/declarations/-private/string/inflections.d.ts +0 -9
  139. package/declarations/-private/string/transform.d.ts +0 -77
  140. package/dist/builder-utils-Donkk-BZ.js +0 -22
  141. package/dist/inflect-BSG696t-.js +0 -344
  142. package/dist/string.cjs +0 -430
  143. package/dist/unpkg/dev/builder-utils-Donkk-BZ.js +0 -22
  144. package/dist/unpkg/dev/inflect-BEv8WqY1.js +0 -343
  145. package/dist/unpkg/dev-deprecated/builder-utils-Donkk-BZ.js +0 -22
  146. package/dist/unpkg/dev-deprecated/inflect-BEv8WqY1.js +0 -343
  147. package/dist/unpkg/prod/builder-utils-Donkk-BZ.js +0 -22
  148. package/dist/unpkg/prod/inflect-Dh9dyEYx.js +0 -333
  149. package/dist/unpkg/prod-deprecated/builder-utils-Donkk-BZ.js +0 -22
  150. package/dist/unpkg/prod-deprecated/inflect-Dh9dyEYx.js +0 -333
@@ -1,316 +1,272 @@
1
+ //#region src/-private/handlers/auto-compress.ts
1
2
  function isCompressibleMethod(method) {
2
- return method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE';
3
+ return method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE";
3
4
  }
4
-
5
5
  /**
6
- * Whether the browser supports `ReadableStream` as a request body
7
- * in a `POST` request.
8
- *
9
- * @group Constants
10
- */
6
+ * Whether the browser supports `ReadableStream` as a request body
7
+ * in a `POST` request.
8
+ *
9
+ * @group Constants
10
+ */
11
11
  const SupportsRequestStreams = (() => {
12
- let duplexAccessed = false;
13
- const hasContentType = new Request('', {
14
- body: new ReadableStream(),
15
- method: 'POST',
16
- // @ts-expect-error untyped
17
- get duplex() {
18
- duplexAccessed = true;
19
- return 'half';
20
- }
21
- }).headers.has('Content-Type');
22
- return duplexAccessed && !hasContentType;
12
+ let duplexAccessed = false;
13
+ const hasContentType = new Request("", {
14
+ body: new ReadableStream(),
15
+ method: "POST",
16
+ get duplex() {
17
+ duplexAccessed = true;
18
+ return "half";
19
+ }
20
+ }).headers.has("Content-Type");
21
+ return duplexAccessed && !hasContentType;
23
22
  })();
24
-
25
23
  /**
26
- * Options for configuring the AutoCompress handler.
27
- *
28
- */
29
-
24
+ * Options for configuring the AutoCompress handler.
25
+ *
26
+ */
30
27
  const DEFAULT_CONSTRAINTS = {
31
- Blob: 1000,
32
- ArrayBuffer: 1000,
33
- TypedArray: 1000,
34
- DataView: 1000,
35
- String: 1000
28
+ Blob: 1e3,
29
+ ArrayBuffer: 1e3,
30
+ TypedArray: 1e3,
31
+ DataView: 1e3,
32
+ String: 1e3
36
33
  };
37
34
  const TypedArray = Object.getPrototypeOf(Uint8Array);
38
-
39
35
  /**
40
- * A request handler that automatically compresses the request body
41
- * if the request body is a string, array buffer, blob, or form data.
42
- *
43
- * This uses the [CompressionStream API](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream)
44
- *
45
- * The compression format as well as the kinds of data to compress can be
46
- * configured using the `format` and `constraints` options.
47
- *
48
- * ```diff
49
- * +import { AutoCompress } from '@ember-data/request-utils/handlers';
50
- * import Fetch from '@ember-data/request/fetch';
51
- * import RequestManager from '@ember-data/request';
52
- * import Store from '@ember-data/store';
53
- *
54
- * class AppStore extends Store {
55
- * requestManager = new RequestManager()
56
- * .use([
57
- * + new AutoCompress(),
58
- * Fetch
59
- * ]);
60
- * }
61
- * ```
62
- *
63
- * @group Handlers
64
- * @public
65
- * @since 5.5.0
66
- */
67
- class AutoCompress {
68
- constructor(options = {}) {
69
- const opts = {
70
- format: options.format ?? 'gzip',
71
- constraints: Object.assign({}, DEFAULT_CONSTRAINTS, options.constraints),
72
- allowStreaming: options.allowStreaming ?? false,
73
- forceStreaming: options.forceStreaming ?? false
74
- };
75
- this.options = opts;
76
- }
77
- request({
78
- request
79
- }, next) {
80
- const {
81
- constraints
82
- } = this.options;
83
- const {
84
- body
85
- } = request;
86
- const shouldCompress = !!body && isCompressibleMethod(request.method) && request.options?.compress !== false && (
87
- // prettier-ignore
88
- request.options?.compress ? true : typeof body === 'string' || body instanceof String ? canCompress('String', constraints, body.length) : body instanceof Blob ? canCompress('Blob', constraints, body.size) : body instanceof ArrayBuffer ? canCompress('ArrayBuffer', constraints, body.byteLength) : body instanceof DataView ? canCompress('DataView', constraints, body.byteLength) : body instanceof TypedArray ? canCompress('TypedArray', constraints, body.byteLength) : false);
89
- if (!shouldCompress) return next(request);
90
-
91
- // A convenient way to convert all of the supported body types to a readable
92
- // stream is to use a `Response` object body
93
- const response = new Response(request.body);
94
- const stream = response.body?.pipeThrough(new CompressionStream(this.options.format));
95
- const headers = new Headers(request.headers);
96
- headers.set('Content-Encoding', encodingForFormat(this.options.format));
97
-
98
- //
99
- // For browsers that support it, `fetch` can receive a `ReadableStream` as
100
- // the body, so all we need to do is to create a new `ReadableStream` and
101
- // compress it on the fly
102
- //
103
- const forceStreaming = request.options?.forceStreaming ?? this.options.forceStreaming;
104
- const allowStreaming = request.options?.allowStreaming ?? this.options.allowStreaming;
105
- if (forceStreaming || SupportsRequestStreams && allowStreaming) {
106
- const req = Object.assign({}, request, {
107
- body: stream,
108
- headers
109
- });
110
- if (SupportsRequestStreams) {
111
- // @ts-expect-error untyped
112
- req.duplex = 'half';
113
- }
114
- return next(req);
115
-
116
- //
117
- // For non-chromium browsers, we have to "pull" the stream to get the final
118
- // bytes and supply the final byte array as the new request body.
119
- //
120
- }
121
-
122
- // we need to pull the stream to get the final bytes
123
- const resp = new Response(stream);
124
- return resp.blob().then(blob => {
125
- const req = Object.assign({}, request, {
126
- body: blob,
127
- headers
128
- });
129
- return next(req);
130
- });
131
- }
132
- }
36
+ * A request handler that automatically compresses the request body
37
+ * if the request body is a string, array buffer, blob, or form data.
38
+ *
39
+ * This uses the [CompressionStream API](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream)
40
+ *
41
+ * The compression format as well as the kinds of data to compress can be
42
+ * configured using the `format` and `constraints` options.
43
+ *
44
+ * ```diff
45
+ * +import { AutoCompress } from '@ember-data/request-utils/handlers';
46
+ * import Fetch from '@ember-data/request/fetch';
47
+ * import RequestManager from '@ember-data/request';
48
+ * import Store from '@ember-data/store';
49
+ *
50
+ * class AppStore extends Store {
51
+ * requestManager = new RequestManager()
52
+ * .use([
53
+ * + new AutoCompress(),
54
+ * Fetch
55
+ * ]);
56
+ * }
57
+ * ```
58
+ *
59
+ * @group Handlers
60
+ * @public
61
+ * @since 5.5.0
62
+ */
63
+ var AutoCompress = class {
64
+ /**
65
+ * The resolved options this handler was configured with, with all
66
+ * defaults (including `constraints` defaults) applied.
67
+ */
68
+ constructor(options = {}) {
69
+ const opts = {
70
+ format: options.format ?? "gzip",
71
+ constraints: Object.assign({}, DEFAULT_CONSTRAINTS, options.constraints),
72
+ allowStreaming: options.allowStreaming ?? false,
73
+ forceStreaming: options.forceStreaming ?? false
74
+ };
75
+ this.options = opts;
76
+ }
77
+ request({ request }, next) {
78
+ const { constraints } = this.options;
79
+ const { body } = request;
80
+ if (!(!!body && isCompressibleMethod(request.method) && request.options?.compress !== false && (request.options?.compress ? true : typeof body === "string" || body instanceof String ? canCompress("String", constraints, body.length) : body instanceof Blob ? canCompress("Blob", constraints, body.size) : body instanceof ArrayBuffer ? canCompress("ArrayBuffer", constraints, body.byteLength) : body instanceof DataView ? canCompress("DataView", constraints, body.byteLength) : body instanceof TypedArray ? canCompress("TypedArray", constraints, body.byteLength) : false))) return next(request);
81
+ const stream = new Response(request.body).body?.pipeThrough(new CompressionStream(this.options.format));
82
+ const headers = new Headers(request.headers);
83
+ headers.set("Content-Encoding", encodingForFormat(this.options.format));
84
+ const forceStreaming = request.options?.forceStreaming ?? this.options.forceStreaming;
85
+ const allowStreaming = request.options?.allowStreaming ?? this.options.allowStreaming;
86
+ if (forceStreaming || SupportsRequestStreams && allowStreaming) {
87
+ const req = Object.assign({}, request, {
88
+ body: stream,
89
+ headers
90
+ });
91
+ if (SupportsRequestStreams) req.duplex = "half";
92
+ return next(req);
93
+ }
94
+ return new Response(stream).blob().then((blob) => {
95
+ return next(Object.assign({}, request, {
96
+ body: blob,
97
+ headers
98
+ }));
99
+ });
100
+ }
101
+ };
133
102
  function canCompress(type, constraints, size) {
134
- // if we have a value of 0, we can compress anything
135
- if (constraints[type] === 0) return true;
136
- if (constraints[type] === -1) return false;
137
- return size >= constraints[type];
103
+ if (constraints[type] === 0) return true;
104
+ if (constraints[type] === -1) return false;
105
+ return size >= constraints[type];
138
106
  }
139
107
  function encodingForFormat(format) {
140
- switch (format) {
141
- case 'gzip':
142
- case 'deflate':
143
- case 'deflate-raw':
144
- return format;
145
- default:
146
- (test => {
147
- {
148
- throw new Error(`Unsupported compression format: ${format}`);
149
- }
150
- })();
151
- // @ts-expect-error - unreachable code is reachable in production
152
- return format;
153
- }
108
+ switch (format) {
109
+ case "gzip":
110
+ case "deflate":
111
+ case "deflate-raw": return format;
112
+ default:
113
+ ((test) => {
114
+ if (!test) throw new Error(`Unsupported compression format: ${format}`);
115
+ })(false);
116
+ return format;
117
+ }
154
118
  }
155
119
 
120
+ //#endregion
121
+ //#region src/-private/handlers/gated.ts
156
122
  /**
157
- * If CheckFn returns true, the wrapped handler will be used.
158
- * If CheckFn returns false, the wrapped handler will be skipped.
159
- */
160
-
123
+ * If CheckFn returns true, the wrapped handler will be used.
124
+ * If CheckFn returns false, the wrapped handler will be skipped.
125
+ */
161
126
  /**
162
- *
163
- * @group Handlers
164
- * @public
165
- */
166
- class Gate {
167
- constructor(handler, checkFn) {
168
- this.handler = handler;
169
- this.checkFn = checkFn;
170
- }
171
- request(context, next) {
172
- if (this.checkFn(context)) {
173
- return this.handler.request(context, next);
174
- }
175
- return next(context.request);
176
- }
177
- }
127
+ *
128
+ * @group Handlers
129
+ * @public
130
+ */
131
+ var Gate = class {
132
+ /**
133
+ * The wrapped handler to invoke when {@link Gate.checkFn | checkFn} returns `true`.
134
+ */
135
+ /**
136
+ * The predicate used to decide whether {@link Gate.handler | handler} should run for a given request.
137
+ */
138
+ constructor(handler, checkFn) {
139
+ this.handler = handler;
140
+ this.checkFn = checkFn;
141
+ }
142
+ request(context, next) {
143
+ if (this.checkFn(context)) return this.handler.request(context, next);
144
+ return next(context.request);
145
+ }
146
+ };
178
147
 
148
+ //#endregion
149
+ //#region src/-private/handlers/meta-doc.ts
179
150
  /**
180
- * MetaDocHandler processes requests that are marked as meta requests.
181
- *
182
- * It treats the response body as "entirely meta" transforming
183
- *
184
- * ```ts
185
- * {
186
- * some: "key",
187
- * another: "thing"
188
- * }
189
- * ```
190
- *
191
- * into
192
- *
193
- * ```ts
194
- * {
195
- * meta: {
196
- * some: "key",
197
- * another: "thing"
198
- * }
199
- * }
200
- * ```
201
- *
202
- * To activate this handler, a request should specify
203
- *
204
- * ```ts
205
- * options.isMetaRequest = true
206
- * ```
207
- *
208
- * For instance
209
- *
210
- * ```ts
211
- * store.request({
212
- * url: '/example',
213
- * options: {
214
- * isMetaRequest: true
215
- * }
216
- * });
217
- * ```
218
- *
219
- * Errors are not processed by this handler, so if the request fails and the error response
220
- * is not in {json:api} format additional processing may be needed.
221
- *
222
- * @group Handlers
223
- */
224
- const MetaDocHandler = {
225
- request(context, next) {
226
- if (!context.request.options?.isMetaRequest) {
227
- return next(context.request);
228
- }
229
- return next(context.request).then(response => {
230
- return processResponse(response);
231
- });
232
- }
233
- };
151
+ * MetaDocHandler processes requests that are marked as meta requests.
152
+ *
153
+ * It treats the response body as "entirely meta" transforming
154
+ *
155
+ * ```ts
156
+ * {
157
+ * some: "key",
158
+ * another: "thing"
159
+ * }
160
+ * ```
161
+ *
162
+ * into
163
+ *
164
+ * ```ts
165
+ * {
166
+ * meta: {
167
+ * some: "key",
168
+ * another: "thing"
169
+ * }
170
+ * }
171
+ * ```
172
+ *
173
+ * To activate this handler, a request should specify
174
+ *
175
+ * ```ts
176
+ * options.isMetaRequest = true
177
+ * ```
178
+ *
179
+ * For instance
180
+ *
181
+ * ```ts
182
+ * store.request({
183
+ * url: '/example',
184
+ * options: {
185
+ * isMetaRequest: true
186
+ * }
187
+ * });
188
+ * ```
189
+ *
190
+ * Errors are not processed by this handler, so if the request fails and the error response
191
+ * is not in {json:api} format additional processing may be needed.
192
+ *
193
+ * @group Handlers
194
+ */
195
+ const MetaDocHandler = { request(context, next) {
196
+ if (!context.request.options?.isMetaRequest) return next(context.request);
197
+ return next(context.request).then((response) => {
198
+ return processResponse(response);
199
+ });
200
+ } };
234
201
  function processResponse(response) {
235
- return {
236
- meta: response.content
237
- };
202
+ return { meta: response.content };
238
203
  }
239
- if (typeof FastBoot === 'undefined') {
240
- globalThis.addEventListener('beforeunload', function () {
241
- sessionStorage.setItem('tab-closed', 'true');
242
- });
243
- }
244
- function getTabId() {
245
- if (typeof sessionStorage === 'undefined') {
246
- return crypto.randomUUID();
247
- }
248
- const tabId = sessionStorage.getItem('tab-id');
249
- if (tabId) {
250
- const tabClosed = sessionStorage.getItem('tab-closed');
251
- if (tabClosed === 'true') {
252
- return tabId;
253
- }
254
204
 
255
- // fall through to generate a new tab id
256
- }
257
- const newTabId = crypto.randomUUID();
258
- sessionStorage.setItem('tab-id', newTabId);
259
- return newTabId;
205
+ //#endregion
206
+ //#region src/-private/handlers/utils.ts
207
+ if (typeof FastBoot === "undefined") globalThis.addEventListener("beforeunload", function() {
208
+ sessionStorage.setItem("tab-closed", "true");
209
+ });
210
+ function getTabId() {
211
+ if (typeof sessionStorage === "undefined") return crypto.randomUUID();
212
+ const tabId = sessionStorage.getItem("tab-id");
213
+ if (tabId) {
214
+ if (sessionStorage.getItem("tab-closed") === "true") return tabId;
215
+ }
216
+ const newTabId = crypto.randomUUID();
217
+ sessionStorage.setItem("tab-id", newTabId);
218
+ return newTabId;
260
219
  }
261
-
262
220
  /**
263
- * A unique identifier for the current browser tab
264
- * useful for observability/tracing and deduping
265
- * across multiple tabs.
266
- *
267
- * @group Constants
268
- */
221
+ * A unique identifier for the current browser tab
222
+ * useful for observability/tracing and deduping
223
+ * across multiple tabs.
224
+ *
225
+ * @group Constants
226
+ */
269
227
  const TAB_ID = getTabId();
270
228
  /**
271
- * The epoch seconds at which the tab id was generated
272
- *
273
- * @group Constants
274
- */
275
- const TAB_ASSIGNED = Math.floor(Date.now() / 1000);
276
-
229
+ * The epoch seconds at which the tab id was generated
230
+ *
231
+ * @group Constants
232
+ */
233
+ const TAB_ASSIGNED = Math.floor(Date.now() / 1e3);
277
234
  /**
278
- * Adds the `X-Amzn-Trace-Id` header to support observability
279
- * tooling around request routing.
280
- *
281
- * This makes use of the {@link TAB_ID} and {@link TAB_ASSIGNED}
282
- * to enable tracking the browser tab of origin across multiple requests.
283
- *
284
- * Follows the template: `Root=1-${now}-${uuidv4};TabId=1-${epochSeconds}-${tab-uuid}`
285
- *
286
- * @group Utility Functions
287
- */
235
+ * Adds the `X-Amzn-Trace-Id` header to support observability
236
+ * tooling around request routing.
237
+ *
238
+ * This makes use of the {@link TAB_ID} and {@link TAB_ASSIGNED}
239
+ * to enable tracking the browser tab of origin across multiple requests.
240
+ *
241
+ * Follows the template: `Root=1-${now}-${uuidv4};TabId=1-${epochSeconds}-${tab-uuid}`
242
+ *
243
+ * @group Utility Functions
244
+ */
288
245
  function addTraceHeader(headers) {
289
- const now = Math.floor(Date.now() / 1000);
290
- headers.set('X-Amzn-Trace-Id', `Root=1-${now}-${crypto.randomUUID()};TabId=1-${TAB_ASSIGNED}-${TAB_ID}`);
291
- return headers;
246
+ const now = Math.floor(Date.now() / 1e3);
247
+ headers.set("X-Amzn-Trace-Id", `Root=1-${now}-${crypto.randomUUID()};TabId=1-${TAB_ASSIGNED}-${TAB_ID}`);
248
+ return headers;
292
249
  }
293
-
294
250
  /**
295
- * Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html
296
- * As of 2024-12-05 the maximum URL length is 8192 bytes.
297
- *
298
- * @group Constants
299
- */
251
+ * Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html
252
+ * As of 2024-12-05 the maximum URL length is 8192 bytes.
253
+ *
254
+ * @group Constants
255
+ */
300
256
  const MAX_URL_LENGTH = 8192;
301
-
302
257
  /**
303
- * This assertion takes a URL and throws an error if the URL is longer than the maximum URL length.
304
- *
305
- * See also {@link MAX_URL_LENGTH}
306
- *
307
- * @group Utility Functions
308
- */
258
+ * This assertion takes a URL and throws an error if the URL is longer than the maximum URL length.
259
+ *
260
+ * See also {@link MAX_URL_LENGTH}
261
+ *
262
+ * @group Utility Functions
263
+ */
309
264
  function assertInvalidUrlLength(url) {
310
- (test => {
311
- if (!test) {
312
- throw new Error(`URL length ${url?.length} exceeds the maximum URL length of ${MAX_URL_LENGTH} bytes.\n\nConsider converting this request query a \`/query\` endpoint instead of a GET, or upgrade the current endpoint to be able to receive a POST request directly (ideally specifying the header HTTP-Method-Override: QUERY)\n\nThe Invalid URL is:\n\n${url}`);
313
- }
314
- })(!url || url.length <= MAX_URL_LENGTH);
265
+ ((test) => {
266
+ if (!test) throw new Error(`URL length ${url?.length} exceeds the maximum URL length of ${MAX_URL_LENGTH} bytes.\n\nConsider converting this request query a \`/query\` endpoint instead of a GET, or upgrade the current endpoint to be able to receive a POST request directly (ideally specifying the header HTTP-Method-Override: QUERY)\n\nThe Invalid URL is:\n\n${url}`);
267
+ })(!url || url.length <= 8192);
315
268
  }
316
- export { AutoCompress, Gate, MAX_URL_LENGTH, MetaDocHandler, SupportsRequestStreams, TAB_ASSIGNED, TAB_ID, addTraceHeader, assertInvalidUrlLength };
269
+
270
+ //#endregion
271
+ export { AutoCompress, Gate, MAX_URL_LENGTH, MetaDocHandler, SupportsRequestStreams, TAB_ASSIGNED, TAB_ID, addTraceHeader, assertInvalidUrlLength };
272
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","names":["isCompressibleMethod","method","SupportsRequestStreams","duplexAccessed","hasContentType","Request","body","ReadableStream","duplex","headers","has","DEFAULT_CONSTRAINTS","Blob","ArrayBuffer","TypedArray","DataView","String","Object","getPrototypeOf","Uint8Array","AutoCompress","constructor","options","opts","format","constraints","assign","allowStreaming","forceStreaming","request","next","shouldCompress","compress","canCompress","length","size","byteLength","response","Response","stream","pipeThrough","CompressionStream","Headers","set","encodingForFormat","req","resp","blob","then","type","test","Error","Gate","constructor","handler","checkFn","request","context","next","FastBoot","globalThis","addEventListener","sessionStorage","setItem","getTabId","crypto","randomUUID","tabId","getItem","tabClosed","newTabId","TAB_ID","TAB_ASSIGNED","Math","floor","Date","now","addTraceHeader","headers","set","MAX_URL_LENGTH","assertInvalidUrlLength","url","test","Error","length"],"sources":["../../../src/-private/handlers/auto-compress.ts","../../../src/-private/handlers/gated.ts","../../../src/-private/handlers/meta-doc.ts","../../../src/-private/handlers/utils.ts"],"sourcesContent":["import { assert } from '@warp-drive/core/build-config/macros';\nimport type { Future, Handler, NextFn } from '@warp-drive/core/request';\nimport type { HTTPMethod, RequestContext } from '@warp-drive/core/types/request';\n\nfunction isCompressibleMethod(method?: HTTPMethod): boolean {\n return method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE';\n}\n\n/**\n * Whether the browser supports `ReadableStream` as a request body\n * in a `POST` request.\n *\n * @group Constants\n */\nexport const SupportsRequestStreams: boolean = (() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request('', {\n body: new ReadableStream(),\n method: 'POST',\n // @ts-expect-error untyped\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n})();\n\ninterface Constraints {\n /**\n * The minimum size at which to compress blobs\n *\n * @default 1000\n */\n Blob?: number;\n /**\n * The minimum size at which to compress array buffers\n *\n * @default 1000\n */\n ArrayBuffer?: number;\n /**\n * The minimum size at which to compress typed arrays\n *\n * @default 1000\n */\n TypedArray?: number;\n /**\n * The minimum size at which to compress data views\n *\n * @default 1000\n */\n DataView?: number;\n /**\n * The minimum size at which to compress strings\n *\n * @default 1000\n */\n String?: number;\n}\n\n/**\n * Options for configuring the AutoCompress handler.\n *\n */\ninterface CompressionOptions {\n /**\n * The compression format to use. Must be a valid\n * compression format supported by [CompressionStream](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream)\n *\n * The default is `gzip`.\n *\n */\n format?: CompressionFormat;\n\n /**\n * Some browsers support `ReadableStream` as a request body. This option\n * enables passing the compression stream as the request body instead of\n * the final compressed body when the browser supports doing so.\n *\n * This comes with several caveats:\n *\n * - the request will be put into `duplex: 'half'` mode. This should be\n * transparent to you, but it is worth noting.\n * - the request mode cannot be `no-cors` as requests with a `ReadableStream`\n * have no content length and thus are a new form of request that triggers\n * cors requirements and a preflight request.\n * - http/1.x is not supported.\n *\n * For additional reading about the restrictions of using `ReadableStream`\n * as a request body, see the [Chromium Documentation](https://developer.chrome.com/docs/capabilities/web-apis/fetch-streaming-requests#restrictions)\n *\n * Streaming can be enabled per-request in browsers which support it by\n * setting `request.options.allowStreaming` to `true`.\n *\n * Streaming can be forced even when the browser does not support it by setting\n * `request.options.forceStreaming` to `true`. This is useful if later handlers\n * in the chain can handle the request body as a stream.\n *\n * @default false\n */\n allowStreaming?: boolean;\n\n /**\n * If `true`, the request will be forced into streaming mode even\n * if the browser does not support it. This is useful if later handlers\n * in the chain can handle the request body as a stream.\n *\n * @default false\n */\n forceStreaming?: boolean;\n\n /**\n * The constraints for the request body. This is used to determine\n * whether to compress the request body or not.\n *\n * The defaults are:\n *\n * ```ts\n * {\n * Blob: 1000, // blob.size\n * ArrayBuffer: 1000, // buffer.byteLength\n * TypedArray: 1000, // array.byteLength\n * DataView: 1000, // view.byteLength\n * String: 1000, // string.length\n * }\n * ```\n *\n * The following body types are never compressed unless explicitly\n * configured by the request:\n * - `FormData`\n * - `URLSearchParams`\n * - `ReadableStream`\n *\n * A request.options.compress value of `false` will disable\n * compression for a request body of any type. While a value of\n * `true` will enable compression for the request.\n *\n * An undefined value will use the default, a value of `0` will\n * enable compression for all values, and a value of `-1` will\n * disable compression.\n *\n */\n constraints?: Constraints;\n}\n\nconst DEFAULT_CONSTRAINTS = {\n Blob: 1000,\n ArrayBuffer: 1000,\n TypedArray: 1000,\n DataView: 1000,\n String: 1000,\n};\nconst TypedArray = Object.getPrototypeOf(Uint8Array) as typeof Uint8Array;\n\n/**\n * A request handler that automatically compresses the request body\n * if the request body is a string, array buffer, blob, or form data.\n *\n * This uses the [CompressionStream API](https://developer.mozilla.org/en-US/docs/Web/API/CompressionStream)\n *\n * The compression format as well as the kinds of data to compress can be\n * configured using the `format` and `constraints` options.\n *\n * ```diff\n * +import { AutoCompress } from '@ember-data/request-utils/handlers';\n * import Fetch from '@ember-data/request/fetch';\n * import RequestManager from '@ember-data/request';\n * import Store from '@ember-data/store';\n *\n * class AppStore extends Store {\n * requestManager = new RequestManager()\n * .use([\n * + new AutoCompress(),\n * Fetch\n * ]);\n * }\n * ```\n *\n * @group Handlers\n * @public\n * @since 5.5.0\n */\nexport class AutoCompress implements Handler {\n /**\n * The resolved options this handler was configured with, with all\n * defaults (including `constraints` defaults) applied.\n */\n declare options: Required<CompressionOptions> & {\n /**\n * The resolved size constraints used to decide whether to compress a given request body.\n */\n constraints: Required<Constraints>;\n };\n\n constructor(options: CompressionOptions = {}) {\n const opts = {\n format: options.format ?? 'gzip',\n constraints: Object.assign({}, DEFAULT_CONSTRAINTS, options.constraints),\n allowStreaming: options.allowStreaming ?? false,\n forceStreaming: options.forceStreaming ?? false,\n };\n this.options = opts;\n }\n\n request<T>({ request }: RequestContext, next: NextFn<T>): Promise<T> | Future<T> {\n const { constraints } = this.options;\n const { body } = request;\n\n const shouldCompress =\n !!body &&\n isCompressibleMethod(request.method) &&\n request.options?.compress !== false &&\n // prettier-ignore\n (request.options?.compress ? true\n : typeof body === 'string' || body instanceof String ? canCompress('String', constraints, body.length)\n : body instanceof Blob ? canCompress('Blob', constraints, body.size)\n : body instanceof ArrayBuffer ? canCompress('ArrayBuffer', constraints, body.byteLength)\n : body instanceof DataView ? canCompress('DataView', constraints, body.byteLength)\n : body instanceof TypedArray ? canCompress('TypedArray', constraints, body.byteLength)\n : false);\n\n if (!shouldCompress) return next(request);\n\n // A convenient way to convert all of the supported body types to a readable\n // stream is to use a `Response` object body\n const response = new Response(request.body);\n const stream = response.body?.pipeThrough(new CompressionStream(this.options.format));\n const headers = new Headers(request.headers);\n headers.set('Content-Encoding', encodingForFormat(this.options.format));\n\n //\n // For browsers that support it, `fetch` can receive a `ReadableStream` as\n // the body, so all we need to do is to create a new `ReadableStream` and\n // compress it on the fly\n //\n const forceStreaming = request.options?.forceStreaming ?? this.options.forceStreaming;\n const allowStreaming = request.options?.allowStreaming ?? this.options.allowStreaming;\n if (forceStreaming || (SupportsRequestStreams && allowStreaming)) {\n const req = Object.assign({}, request, {\n body: stream,\n headers,\n });\n if (SupportsRequestStreams) {\n // @ts-expect-error untyped\n req.duplex = 'half';\n }\n\n return next(req);\n\n //\n // For non-chromium browsers, we have to \"pull\" the stream to get the final\n // bytes and supply the final byte array as the new request body.\n //\n }\n\n // we need to pull the stream to get the final bytes\n const resp = new Response(stream);\n return resp.blob().then((blob) => {\n const req = Object.assign({}, request, {\n body: blob,\n headers,\n });\n return next(req);\n }) as Promise<T>;\n }\n}\n\nfunction canCompress(type: keyof Constraints, constraints: Required<Constraints>, size: number): boolean {\n // if we have a value of 0, we can compress anything\n if (constraints[type] === 0) return true;\n if (constraints[type] === -1) return false;\n return size >= constraints[type];\n}\n\nfunction encodingForFormat(format: CompressionFormat): string {\n switch (format) {\n case 'gzip':\n case 'deflate':\n case 'deflate-raw':\n return format;\n default:\n assert(`Unsupported compression format: ${format as unknown as string}`);\n // @ts-expect-error - unreachable code is reachable in production\n return format;\n }\n}\n","import type { Future, Handler, NextFn } from '@warp-drive/core/request';\nimport type { RequestContext, StructuredDataDocument } from '@warp-drive/core/types/request';\n\n/**\n * If CheckFn returns true, the wrapped handler will be used.\n * If CheckFn returns false, the wrapped handler will be skipped.\n */\ntype CheckFn = (context: RequestContext) => boolean;\n\n/**\n *\n * @group Handlers\n * @public\n */\nexport class Gate implements Handler {\n /**\n * The wrapped handler to invoke when {@link Gate.checkFn | checkFn} returns `true`.\n */\n declare handler: Handler;\n /**\n * The predicate used to decide whether {@link Gate.handler | handler} should run for a given request.\n */\n declare checkFn: CheckFn;\n\n constructor(handler: Handler, checkFn: CheckFn) {\n this.handler = handler;\n this.checkFn = checkFn;\n }\n\n request<T = unknown>(context: RequestContext, next: NextFn<T>): Promise<T | StructuredDataDocument<T>> | Future<T> {\n if (this.checkFn(context)) {\n return this.handler.request(context, next);\n }\n return next(context.request);\n }\n}\n","import type { StoreRequestContext } from '@warp-drive/core';\nimport type { Handler, NextFn } from '@warp-drive/core/request';\nimport type { StructuredDataDocument } from '@warp-drive/core/types/request';\n\n/**\n * MetaDocHandler processes requests that are marked as meta requests.\n *\n * It treats the response body as \"entirely meta\" transforming\n *\n * ```ts\n * {\n * some: \"key\",\n * another: \"thing\"\n * }\n * ```\n *\n * into\n *\n * ```ts\n * {\n * \t meta: {\n * some: \"key\",\n * another: \"thing\"\n * }\n * }\n * ```\n *\n * To activate this handler, a request should specify\n *\n * ```ts\n * options.isMetaRequest = true\n * ```\n *\n * For instance\n *\n * ```ts\n * store.request({\n * url: '/example',\n * options: {\n * isMetaRequest: true\n * }\n * });\n * ```\n *\n * Errors are not processed by this handler, so if the request fails and the error response\n * is not in {json:api} format additional processing may be needed.\n *\n * @group Handlers\n */\nexport const MetaDocHandler: Handler = {\n request<T>(context: StoreRequestContext, next: NextFn<T>): Promise<T | StructuredDataDocument<T> | Awaited<T>> {\n if (!context.request.options?.isMetaRequest) {\n return next(context.request);\n }\n\n return next(context.request).then((response) => {\n return processResponse<T>(response);\n });\n },\n};\n\nfunction processResponse<T>(response: StructuredDataDocument<T>): T {\n return {\n meta: response.content,\n } as T;\n}\n","import { assert } from '@warp-drive/core/build-config/macros';\n\nif (typeof FastBoot === 'undefined') {\n globalThis.addEventListener('beforeunload', function () {\n sessionStorage.setItem('tab-closed', 'true');\n });\n}\n\nfunction getTabId() {\n if (typeof sessionStorage === 'undefined') {\n return crypto.randomUUID();\n }\n\n const tabId = sessionStorage.getItem('tab-id');\n if (tabId) {\n const tabClosed = sessionStorage.getItem('tab-closed');\n if (tabClosed === 'true') {\n return tabId;\n }\n\n // fall through to generate a new tab id\n }\n\n const newTabId = crypto.randomUUID();\n sessionStorage.setItem('tab-id', newTabId);\n return newTabId;\n}\n\n/**\n * A unique identifier for the current browser tab\n * useful for observability/tracing and deduping\n * across multiple tabs.\n *\n * @group Constants\n */\nexport const TAB_ID: string = getTabId();\n/**\n * The epoch seconds at which the tab id was generated\n *\n * @group Constants\n */\nexport const TAB_ASSIGNED: number = Math.floor(Date.now() / 1000);\n\n/**\n * Adds the `X-Amzn-Trace-Id` header to support observability\n * tooling around request routing.\n *\n * This makes use of the {@link TAB_ID} and {@link TAB_ASSIGNED}\n * to enable tracking the browser tab of origin across multiple requests.\n *\n * Follows the template: `Root=1-${now}-${uuidv4};TabId=1-${epochSeconds}-${tab-uuid}`\n *\n * @group Utility Functions\n */\nexport function addTraceHeader(headers: Headers): Headers {\n const now = Math.floor(Date.now() / 1000);\n headers.set('X-Amzn-Trace-Id', `Root=1-${now}-${crypto.randomUUID()};TabId=1-${TAB_ASSIGNED}-${TAB_ID}`);\n\n return headers;\n}\n\n/**\n * Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html\n * As of 2024-12-05 the maximum URL length is 8192 bytes.\n *\n * @group Constants\n */\nexport const MAX_URL_LENGTH = 8192;\n\n/**\n * This assertion takes a URL and throws an error if the URL is longer than the maximum URL length.\n *\n * See also {@link MAX_URL_LENGTH}\n *\n * @group Utility Functions\n */\nexport function assertInvalidUrlLength(url: string | undefined): void {\n assert(\n `URL length ${url?.length} exceeds the maximum URL length of ${MAX_URL_LENGTH} bytes.\\n\\nConsider converting this request query a \\`/query\\` endpoint instead of a GET, or upgrade the current endpoint to be able to receive a POST request directly (ideally specifying the header HTTP-Method-Override: QUERY)\\n\\nThe Invalid URL is:\\n\\n${url}`,\n !url || url.length <= MAX_URL_LENGTH\n );\n}\n"],"mappings":"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"}