@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,305 +1,264 @@
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
- // @ts-expect-error - unreachable code is reachable in production
147
- return format;
148
- }
108
+ switch (format) {
109
+ case "gzip":
110
+ case "deflate":
111
+ case "deflate-raw": return format;
112
+ default: return format;
113
+ }
149
114
  }
150
115
 
116
+ //#endregion
117
+ //#region src/-private/handlers/gated.ts
151
118
  /**
152
- * If CheckFn returns true, the wrapped handler will be used.
153
- * If CheckFn returns false, the wrapped handler will be skipped.
154
- */
155
-
119
+ * If CheckFn returns true, the wrapped handler will be used.
120
+ * If CheckFn returns false, the wrapped handler will be skipped.
121
+ */
156
122
  /**
157
- *
158
- * @group Handlers
159
- * @public
160
- */
161
- class Gate {
162
- constructor(handler, checkFn) {
163
- this.handler = handler;
164
- this.checkFn = checkFn;
165
- }
166
- request(context, next) {
167
- if (this.checkFn(context)) {
168
- return this.handler.request(context, next);
169
- }
170
- return next(context.request);
171
- }
172
- }
123
+ *
124
+ * @group Handlers
125
+ * @public
126
+ */
127
+ var Gate = class {
128
+ /**
129
+ * The wrapped handler to invoke when {@link Gate.checkFn | checkFn} returns `true`.
130
+ */
131
+ /**
132
+ * The predicate used to decide whether {@link Gate.handler | handler} should run for a given request.
133
+ */
134
+ constructor(handler, checkFn) {
135
+ this.handler = handler;
136
+ this.checkFn = checkFn;
137
+ }
138
+ request(context, next) {
139
+ if (this.checkFn(context)) return this.handler.request(context, next);
140
+ return next(context.request);
141
+ }
142
+ };
173
143
 
144
+ //#endregion
145
+ //#region src/-private/handlers/meta-doc.ts
174
146
  /**
175
- * MetaDocHandler processes requests that are marked as meta requests.
176
- *
177
- * It treats the response body as "entirely meta" transforming
178
- *
179
- * ```ts
180
- * {
181
- * some: "key",
182
- * another: "thing"
183
- * }
184
- * ```
185
- *
186
- * into
187
- *
188
- * ```ts
189
- * {
190
- * meta: {
191
- * some: "key",
192
- * another: "thing"
193
- * }
194
- * }
195
- * ```
196
- *
197
- * To activate this handler, a request should specify
198
- *
199
- * ```ts
200
- * options.isMetaRequest = true
201
- * ```
202
- *
203
- * For instance
204
- *
205
- * ```ts
206
- * store.request({
207
- * url: '/example',
208
- * options: {
209
- * isMetaRequest: true
210
- * }
211
- * });
212
- * ```
213
- *
214
- * Errors are not processed by this handler, so if the request fails and the error response
215
- * is not in {json:api} format additional processing may be needed.
216
- *
217
- * @group Handlers
218
- */
219
- const MetaDocHandler = {
220
- request(context, next) {
221
- if (!context.request.options?.isMetaRequest) {
222
- return next(context.request);
223
- }
224
- return next(context.request).then(response => {
225
- return processResponse(response);
226
- });
227
- }
228
- };
147
+ * MetaDocHandler processes requests that are marked as meta requests.
148
+ *
149
+ * It treats the response body as "entirely meta" transforming
150
+ *
151
+ * ```ts
152
+ * {
153
+ * some: "key",
154
+ * another: "thing"
155
+ * }
156
+ * ```
157
+ *
158
+ * into
159
+ *
160
+ * ```ts
161
+ * {
162
+ * meta: {
163
+ * some: "key",
164
+ * another: "thing"
165
+ * }
166
+ * }
167
+ * ```
168
+ *
169
+ * To activate this handler, a request should specify
170
+ *
171
+ * ```ts
172
+ * options.isMetaRequest = true
173
+ * ```
174
+ *
175
+ * For instance
176
+ *
177
+ * ```ts
178
+ * store.request({
179
+ * url: '/example',
180
+ * options: {
181
+ * isMetaRequest: true
182
+ * }
183
+ * });
184
+ * ```
185
+ *
186
+ * Errors are not processed by this handler, so if the request fails and the error response
187
+ * is not in {json:api} format additional processing may be needed.
188
+ *
189
+ * @group Handlers
190
+ */
191
+ const MetaDocHandler = { request(context, next) {
192
+ if (!context.request.options?.isMetaRequest) return next(context.request);
193
+ return next(context.request).then((response) => {
194
+ return processResponse(response);
195
+ });
196
+ } };
229
197
  function processResponse(response) {
230
- return {
231
- meta: response.content
232
- };
198
+ return { meta: response.content };
233
199
  }
234
- if (typeof FastBoot === 'undefined') {
235
- globalThis.addEventListener('beforeunload', function () {
236
- sessionStorage.setItem('tab-closed', 'true');
237
- });
238
- }
239
- function getTabId() {
240
- if (typeof sessionStorage === 'undefined') {
241
- return crypto.randomUUID();
242
- }
243
- const tabId = sessionStorage.getItem('tab-id');
244
- if (tabId) {
245
- const tabClosed = sessionStorage.getItem('tab-closed');
246
- if (tabClosed === 'true') {
247
- return tabId;
248
- }
249
200
 
250
- // fall through to generate a new tab id
251
- }
252
- const newTabId = crypto.randomUUID();
253
- sessionStorage.setItem('tab-id', newTabId);
254
- return newTabId;
201
+ //#endregion
202
+ //#region src/-private/handlers/utils.ts
203
+ if (typeof FastBoot === "undefined") globalThis.addEventListener("beforeunload", function() {
204
+ sessionStorage.setItem("tab-closed", "true");
205
+ });
206
+ function getTabId() {
207
+ if (typeof sessionStorage === "undefined") return crypto.randomUUID();
208
+ const tabId = sessionStorage.getItem("tab-id");
209
+ if (tabId) {
210
+ if (sessionStorage.getItem("tab-closed") === "true") return tabId;
211
+ }
212
+ const newTabId = crypto.randomUUID();
213
+ sessionStorage.setItem("tab-id", newTabId);
214
+ return newTabId;
255
215
  }
256
-
257
216
  /**
258
- * A unique identifier for the current browser tab
259
- * useful for observability/tracing and deduping
260
- * across multiple tabs.
261
- *
262
- * @group Constants
263
- */
217
+ * A unique identifier for the current browser tab
218
+ * useful for observability/tracing and deduping
219
+ * across multiple tabs.
220
+ *
221
+ * @group Constants
222
+ */
264
223
  const TAB_ID = getTabId();
265
224
  /**
266
- * The epoch seconds at which the tab id was generated
267
- *
268
- * @group Constants
269
- */
270
- const TAB_ASSIGNED = Math.floor(Date.now() / 1000);
271
-
225
+ * The epoch seconds at which the tab id was generated
226
+ *
227
+ * @group Constants
228
+ */
229
+ const TAB_ASSIGNED = Math.floor(Date.now() / 1e3);
272
230
  /**
273
- * Adds the `X-Amzn-Trace-Id` header to support observability
274
- * tooling around request routing.
275
- *
276
- * This makes use of the {@link TAB_ID} and {@link TAB_ASSIGNED}
277
- * to enable tracking the browser tab of origin across multiple requests.
278
- *
279
- * Follows the template: `Root=1-${now}-${uuidv4};TabId=1-${epochSeconds}-${tab-uuid}`
280
- *
281
- * @group Utility Functions
282
- */
231
+ * Adds the `X-Amzn-Trace-Id` header to support observability
232
+ * tooling around request routing.
233
+ *
234
+ * This makes use of the {@link TAB_ID} and {@link TAB_ASSIGNED}
235
+ * to enable tracking the browser tab of origin across multiple requests.
236
+ *
237
+ * Follows the template: `Root=1-${now}-${uuidv4};TabId=1-${epochSeconds}-${tab-uuid}`
238
+ *
239
+ * @group Utility Functions
240
+ */
283
241
  function addTraceHeader(headers) {
284
- const now = Math.floor(Date.now() / 1000);
285
- headers.set('X-Amzn-Trace-Id', `Root=1-${now}-${crypto.randomUUID()};TabId=1-${TAB_ASSIGNED}-${TAB_ID}`);
286
- return headers;
242
+ const now = Math.floor(Date.now() / 1e3);
243
+ headers.set("X-Amzn-Trace-Id", `Root=1-${now}-${crypto.randomUUID()};TabId=1-${TAB_ASSIGNED}-${TAB_ID}`);
244
+ return headers;
287
245
  }
288
-
289
246
  /**
290
- * Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html
291
- * As of 2024-12-05 the maximum URL length is 8192 bytes.
292
- *
293
- * @group Constants
294
- */
247
+ * Source: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html
248
+ * As of 2024-12-05 the maximum URL length is 8192 bytes.
249
+ *
250
+ * @group Constants
251
+ */
295
252
  const MAX_URL_LENGTH = 8192;
296
-
297
253
  /**
298
- * This assertion takes a URL and throws an error if the URL is longer than the maximum URL length.
299
- *
300
- * See also {@link MAX_URL_LENGTH}
301
- *
302
- * @group Utility Functions
303
- */
254
+ * This assertion takes a URL and throws an error if the URL is longer than the maximum URL length.
255
+ *
256
+ * See also {@link MAX_URL_LENGTH}
257
+ *
258
+ * @group Utility Functions
259
+ */
304
260
  function assertInvalidUrlLength(url) {}
305
- export { AutoCompress, Gate, MAX_URL_LENGTH, MetaDocHandler, SupportsRequestStreams, TAB_ASSIGNED, TAB_ID, addTraceHeader, assertInvalidUrlLength };
261
+
262
+ //#endregion
263
+ export { AutoCompress, Gate, MAX_URL_LENGTH, MetaDocHandler, SupportsRequestStreams, TAB_ASSIGNED, TAB_ID, addTraceHeader, assertInvalidUrlLength };
264
+ //# 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","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"],"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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"}