@auto-engineer/generate-react-client 1.64.0 → 1.65.0

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 (144) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/starter/.storybook/main.ts +17 -22
  3. package/dist/starter/.storybook/manager-head.html +31 -31
  4. package/dist/starter/.storybook/manager.ts +133 -133
  5. package/dist/starter/.storybook/preview-head.html +12 -12
  6. package/dist/starter/.storybook/preview.tsx +79 -79
  7. package/dist/starter/biome.json +126 -0
  8. package/dist/starter/codegen.ts +11 -11
  9. package/dist/starter/components.json +27 -27
  10. package/dist/starter/package.json +86 -80
  11. package/dist/starter/public/mockServiceWorker.js +261 -261
  12. package/dist/starter/scripts/build-component-db.ts +17 -20
  13. package/dist/starter/src/App.tsx +15 -17
  14. package/dist/starter/src/components/ui/Accordion.stories.tsx +35 -35
  15. package/dist/starter/src/components/ui/Accordion.tsx +33 -33
  16. package/dist/starter/src/components/ui/Alert.stories.tsx +15 -15
  17. package/dist/starter/src/components/ui/Alert.tsx +32 -32
  18. package/dist/starter/src/components/ui/AlertDialog.stories.tsx +50 -50
  19. package/dist/starter/src/components/ui/AlertDialog.tsx +114 -115
  20. package/dist/starter/src/components/ui/AspectRatio.stories.tsx +20 -20
  21. package/dist/starter/src/components/ui/AspectRatio.tsx +1 -1
  22. package/dist/starter/src/components/ui/Avatar.stories.tsx +27 -27
  23. package/dist/starter/src/components/ui/Avatar.tsx +63 -63
  24. package/dist/starter/src/components/ui/Badge.stories.tsx +14 -14
  25. package/dist/starter/src/components/ui/Badge.tsx +27 -27
  26. package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +38 -38
  27. package/dist/starter/src/components/ui/Breadcrumb.tsx +63 -62
  28. package/dist/starter/src/components/ui/Button.stories.tsx +55 -55
  29. package/dist/starter/src/components/ui/Button.tsx +49 -49
  30. package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +17 -17
  31. package/dist/starter/src/components/ui/ButtonGroup.tsx +52 -53
  32. package/dist/starter/src/components/ui/Calendar.stories.tsx +20 -19
  33. package/dist/starter/src/components/ui/Calendar.tsx +142 -143
  34. package/dist/starter/src/components/ui/Card.stories.tsx +29 -29
  35. package/dist/starter/src/components/ui/Card.tsx +31 -31
  36. package/dist/starter/src/components/ui/Carousel.stories.tsx +41 -41
  37. package/dist/starter/src/components/ui/Carousel.tsx +171 -172
  38. package/dist/starter/src/components/ui/Chart.stories.tsx +21 -21
  39. package/dist/starter/src/components/ui/Chart.tsx +244 -247
  40. package/dist/starter/src/components/ui/Checkbox.stories.tsx +11 -11
  41. package/dist/starter/src/components/ui/Checkbox.tsx +18 -18
  42. package/dist/starter/src/components/ui/Collapsible.stories.tsx +40 -40
  43. package/dist/starter/src/components/ui/Collapsible.tsx +3 -3
  44. package/dist/starter/src/components/ui/Combobox.stories.tsx +48 -48
  45. package/dist/starter/src/components/ui/Combobox.tsx +204 -205
  46. package/dist/starter/src/components/ui/Command.stories.tsx +55 -55
  47. package/dist/starter/src/components/ui/Command.tsx +102 -103
  48. package/dist/starter/src/components/ui/ContextMenu.stories.tsx +52 -52
  49. package/dist/starter/src/components/ui/ContextMenu.tsx +151 -151
  50. package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +92 -92
  51. package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +139 -139
  52. package/dist/starter/src/components/ui/DesignSystem-Overview.stories.tsx +676 -657
  53. package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +59 -59
  54. package/dist/starter/src/components/ui/Dialog.stories.tsx +56 -56
  55. package/dist/starter/src/components/ui/Dialog.tsx +97 -98
  56. package/dist/starter/src/components/ui/Direction.stories.tsx +20 -20
  57. package/dist/starter/src/components/ui/Direction.tsx +7 -7
  58. package/dist/starter/src/components/ui/Drawer.stories.tsx +54 -54
  59. package/dist/starter/src/components/ui/Drawer.tsx +70 -70
  60. package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +58 -58
  61. package/dist/starter/src/components/ui/DropdownMenu.tsx +157 -157
  62. package/dist/starter/src/components/ui/Empty.stories.tsx +22 -22
  63. package/dist/starter/src/components/ui/Empty.tsx +58 -58
  64. package/dist/starter/src/components/ui/Field.stories.tsx +31 -31
  65. package/dist/starter/src/components/ui/Field.tsx +180 -181
  66. package/dist/starter/src/components/ui/Form.stories.tsx +29 -29
  67. package/dist/starter/src/components/ui/Form.tsx +93 -96
  68. package/dist/starter/src/components/ui/HoverCard.stories.tsx +34 -34
  69. package/dist/starter/src/components/ui/HoverCard.tsx +21 -21
  70. package/dist/starter/src/components/ui/Input.stories.tsx +18 -18
  71. package/dist/starter/src/components/ui/Input.tsx +14 -14
  72. package/dist/starter/src/components/ui/InputGroup.stories.tsx +34 -34
  73. package/dist/starter/src/components/ui/InputGroup.tsx +110 -111
  74. package/dist/starter/src/components/ui/InputOTP.stories.tsx +28 -28
  75. package/dist/starter/src/components/ui/InputOTP.tsx +43 -43
  76. package/dist/starter/src/components/ui/Item.stories.tsx +45 -45
  77. package/dist/starter/src/components/ui/Item.tsx +113 -114
  78. package/dist/starter/src/components/ui/Kbd.stories.tsx +31 -31
  79. package/dist/starter/src/components/ui/Kbd.tsx +11 -11
  80. package/dist/starter/src/components/ui/Label.stories.tsx +62 -62
  81. package/dist/starter/src/components/ui/Label.tsx +26 -25
  82. package/dist/starter/src/components/ui/Menubar.stories.tsx +62 -62
  83. package/dist/starter/src/components/ui/Menubar.tsx +173 -173
  84. package/dist/starter/src/components/ui/NativeSelect.stories.tsx +26 -26
  85. package/dist/starter/src/components/ui/NativeSelect.tsx +29 -29
  86. package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +64 -64
  87. package/dist/starter/src/components/ui/NavigationMenu.tsx +103 -103
  88. package/dist/starter/src/components/ui/Pagination.stories.tsx +61 -61
  89. package/dist/starter/src/components/ui/Pagination.tsx +69 -71
  90. package/dist/starter/src/components/ui/Popover.stories.tsx +38 -38
  91. package/dist/starter/src/components/ui/Popover.tsx +25 -25
  92. package/dist/starter/src/components/ui/Progress.stories.tsx +9 -9
  93. package/dist/starter/src/components/ui/Progress.tsx +14 -14
  94. package/dist/starter/src/components/ui/RadioGroup.stories.tsx +35 -35
  95. package/dist/starter/src/components/ui/RadioGroup.tsx +19 -19
  96. package/dist/starter/src/components/ui/Resizable.stories.tsx +54 -54
  97. package/dist/starter/src/components/ui/Resizable.tsx +29 -29
  98. package/dist/starter/src/components/ui/ScrollArea.stories.tsx +27 -27
  99. package/dist/starter/src/components/ui/ScrollArea.tsx +34 -34
  100. package/dist/starter/src/components/ui/Select.stories.tsx +43 -43
  101. package/dist/starter/src/components/ui/Select.tsx +120 -120
  102. package/dist/starter/src/components/ui/Separator.stories.tsx +27 -27
  103. package/dist/starter/src/components/ui/Separator.tsx +17 -17
  104. package/dist/starter/src/components/ui/Sheet.stories.tsx +53 -53
  105. package/dist/starter/src/components/ui/Sheet.tsx +69 -69
  106. package/dist/starter/src/components/ui/Sidebar.stories.tsx +77 -77
  107. package/dist/starter/src/components/ui/Sidebar.tsx +563 -564
  108. package/dist/starter/src/components/ui/Skeleton.stories.tsx +25 -25
  109. package/dist/starter/src/components/ui/Skeleton.tsx +1 -1
  110. package/dist/starter/src/components/ui/Slider.stories.tsx +5 -5
  111. package/dist/starter/src/components/ui/Slider.tsx +45 -44
  112. package/dist/starter/src/components/ui/Sonner.stories.tsx +32 -32
  113. package/dist/starter/src/components/ui/Sonner.tsx +23 -23
  114. package/dist/starter/src/components/ui/Spinner.stories.tsx +8 -8
  115. package/dist/starter/src/components/ui/Spinner.tsx +1 -1
  116. package/dist/starter/src/components/ui/Switch.stories.tsx +16 -17
  117. package/dist/starter/src/components/ui/Switch.tsx +24 -24
  118. package/dist/starter/src/components/ui/Table.stories.tsx +50 -50
  119. package/dist/starter/src/components/ui/Table.tsx +45 -45
  120. package/dist/starter/src/components/ui/Tabs.stories.tsx +39 -39
  121. package/dist/starter/src/components/ui/Tabs.tsx +47 -47
  122. package/dist/starter/src/components/ui/Textarea.stories.tsx +9 -9
  123. package/dist/starter/src/components/ui/Textarea.tsx +11 -11
  124. package/dist/starter/src/components/ui/Toast.stories.tsx +77 -77
  125. package/dist/starter/src/components/ui/Toast.tsx +75 -75
  126. package/dist/starter/src/components/ui/Toaster.tsx +17 -19
  127. package/dist/starter/src/components/ui/Toggle.stories.tsx +20 -20
  128. package/dist/starter/src/components/ui/Toggle.tsx +26 -26
  129. package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +41 -41
  130. package/dist/starter/src/components/ui/ToggleGroup.tsx +61 -62
  131. package/dist/starter/src/components/ui/Tooltip.stories.tsx +26 -26
  132. package/dist/starter/src/components/ui/Tooltip.tsx +24 -24
  133. package/dist/starter/src/gql/execute.ts +1 -1
  134. package/dist/starter/src/gql/fragment-masking.ts +1 -1
  135. package/dist/starter/src/gql/graphql.ts +3 -0
  136. package/dist/starter/src/hooks/use-mobile.ts +11 -11
  137. package/dist/starter/src/hooks/use-toast.ts +135 -135
  138. package/dist/starter/src/index.css +105 -105
  139. package/dist/starter/src/lib/utils.ts +1 -1
  140. package/dist/starter/src/main.tsx +4 -1
  141. package/dist/starter/tsconfig.app.json +24 -24
  142. package/dist/starter/tsconfig.json +8 -8
  143. package/dist/starter/vite.config.ts +38 -37
  144. package/package.json +3 -3
@@ -12,105 +12,105 @@ const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82';
12
12
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse');
13
13
  const activeClientIds = new Set();
14
14
 
15
- addEventListener('install', function () {
16
- self.skipWaiting();
15
+ addEventListener('install', () => {
16
+ self.skipWaiting();
17
17
  });
18
18
 
19
- addEventListener('activate', function (event) {
20
- event.waitUntil(self.clients.claim());
19
+ addEventListener('activate', (event) => {
20
+ event.waitUntil(self.clients.claim());
21
21
  });
22
22
 
23
- addEventListener('message', async function (event) {
24
- const clientId = Reflect.get(event.source || {}, 'id');
25
-
26
- if (!clientId || !self.clients) {
27
- return;
28
- }
29
-
30
- const client = await self.clients.get(clientId);
31
-
32
- if (!client) {
33
- return;
34
- }
35
-
36
- const allClients = await self.clients.matchAll({
37
- type: 'window',
38
- });
39
-
40
- switch (event.data) {
41
- case 'KEEPALIVE_REQUEST': {
42
- sendToClient(client, {
43
- type: 'KEEPALIVE_RESPONSE',
44
- });
45
- break;
46
- }
47
-
48
- case 'INTEGRITY_CHECK_REQUEST': {
49
- sendToClient(client, {
50
- type: 'INTEGRITY_CHECK_RESPONSE',
51
- payload: {
52
- packageVersion: PACKAGE_VERSION,
53
- checksum: INTEGRITY_CHECKSUM,
54
- },
55
- });
56
- break;
57
- }
58
-
59
- case 'MOCK_ACTIVATE': {
60
- activeClientIds.add(clientId);
61
-
62
- sendToClient(client, {
63
- type: 'MOCKING_ENABLED',
64
- payload: {
65
- client: {
66
- id: client.id,
67
- frameType: client.frameType,
68
- },
69
- },
70
- });
71
- break;
72
- }
73
-
74
- case 'CLIENT_CLOSED': {
75
- activeClientIds.delete(clientId);
76
-
77
- const remainingClients = allClients.filter((client) => {
78
- return client.id !== clientId;
79
- });
80
-
81
- // Unregister itself when there are no more clients
82
- if (remainingClients.length === 0) {
83
- self.registration.unregister();
84
- }
85
-
86
- break;
87
- }
88
- }
23
+ addEventListener('message', async (event) => {
24
+ const clientId = Reflect.get(event.source || {}, 'id');
25
+
26
+ if (!clientId || !self.clients) {
27
+ return;
28
+ }
29
+
30
+ const client = await self.clients.get(clientId);
31
+
32
+ if (!client) {
33
+ return;
34
+ }
35
+
36
+ const allClients = await self.clients.matchAll({
37
+ type: 'window',
38
+ });
39
+
40
+ switch (event.data) {
41
+ case 'KEEPALIVE_REQUEST': {
42
+ sendToClient(client, {
43
+ type: 'KEEPALIVE_RESPONSE',
44
+ });
45
+ break;
46
+ }
47
+
48
+ case 'INTEGRITY_CHECK_REQUEST': {
49
+ sendToClient(client, {
50
+ type: 'INTEGRITY_CHECK_RESPONSE',
51
+ payload: {
52
+ packageVersion: PACKAGE_VERSION,
53
+ checksum: INTEGRITY_CHECKSUM,
54
+ },
55
+ });
56
+ break;
57
+ }
58
+
59
+ case 'MOCK_ACTIVATE': {
60
+ activeClientIds.add(clientId);
61
+
62
+ sendToClient(client, {
63
+ type: 'MOCKING_ENABLED',
64
+ payload: {
65
+ client: {
66
+ id: client.id,
67
+ frameType: client.frameType,
68
+ },
69
+ },
70
+ });
71
+ break;
72
+ }
73
+
74
+ case 'CLIENT_CLOSED': {
75
+ activeClientIds.delete(clientId);
76
+
77
+ const remainingClients = allClients.filter((client) => {
78
+ return client.id !== clientId;
79
+ });
80
+
81
+ // Unregister itself when there are no more clients
82
+ if (remainingClients.length === 0) {
83
+ self.registration.unregister();
84
+ }
85
+
86
+ break;
87
+ }
88
+ }
89
89
  });
90
90
 
91
- addEventListener('fetch', function (event) {
92
- const requestInterceptedAt = Date.now();
93
-
94
- // Bypass navigation requests.
95
- if (event.request.mode === 'navigate') {
96
- return;
97
- }
98
-
99
- // Opening the DevTools triggers the "only-if-cached" request
100
- // that cannot be handled by the worker. Bypass such requests.
101
- if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') {
102
- return;
103
- }
104
-
105
- // Bypass all requests when there are no active clients.
106
- // Prevents the self-unregistered worked from handling requests
107
- // after it's been terminated (still remains active until the next reload).
108
- if (activeClientIds.size === 0) {
109
- return;
110
- }
111
-
112
- const requestId = crypto.randomUUID();
113
- event.respondWith(handleRequest(event, requestId, requestInterceptedAt));
91
+ addEventListener('fetch', (event) => {
92
+ const requestInterceptedAt = Date.now();
93
+
94
+ // Bypass navigation requests.
95
+ if (event.request.mode === 'navigate') {
96
+ return;
97
+ }
98
+
99
+ // Opening the DevTools triggers the "only-if-cached" request
100
+ // that cannot be handled by the worker. Bypass such requests.
101
+ if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') {
102
+ return;
103
+ }
104
+
105
+ // Bypass all requests when there are no active clients.
106
+ // Prevents the self-unregistered worked from handling requests
107
+ // after it's been terminated (still remains active until the next reload).
108
+ if (activeClientIds.size === 0) {
109
+ return;
110
+ }
111
+
112
+ const requestId = crypto.randomUUID();
113
+ event.respondWith(handleRequest(event, requestId, requestInterceptedAt));
114
114
  });
115
115
 
116
116
  /**
@@ -119,43 +119,43 @@ addEventListener('fetch', function (event) {
119
119
  * @param {number} requestInterceptedAt
120
120
  */
121
121
  async function handleRequest(event, requestId, requestInterceptedAt) {
122
- const client = await resolveMainClient(event);
123
- const requestCloneForEvents = event.request.clone();
124
- const response = await getResponse(event, client, requestId, requestInterceptedAt);
125
-
126
- // Send back the response clone for the "response:*" life-cycle events.
127
- // Ensure MSW is active and ready to handle the message, otherwise
128
- // this message will pend indefinitely.
129
- if (client && activeClientIds.has(client.id)) {
130
- const serializedRequest = await serializeRequest(requestCloneForEvents);
131
-
132
- // Clone the response so both the client and the library could consume it.
133
- const responseClone = response.clone();
134
-
135
- sendToClient(
136
- client,
137
- {
138
- type: 'RESPONSE',
139
- payload: {
140
- isMockedResponse: IS_MOCKED_RESPONSE in response,
141
- request: {
142
- id: requestId,
143
- ...serializedRequest,
144
- },
145
- response: {
146
- type: responseClone.type,
147
- status: responseClone.status,
148
- statusText: responseClone.statusText,
149
- headers: Object.fromEntries(responseClone.headers.entries()),
150
- body: responseClone.body,
151
- },
152
- },
153
- },
154
- responseClone.body ? [serializedRequest.body, responseClone.body] : [],
155
- );
156
- }
157
-
158
- return response;
122
+ const client = await resolveMainClient(event);
123
+ const requestCloneForEvents = event.request.clone();
124
+ const response = await getResponse(event, client, requestId, requestInterceptedAt);
125
+
126
+ // Send back the response clone for the "response:*" life-cycle events.
127
+ // Ensure MSW is active and ready to handle the message, otherwise
128
+ // this message will pend indefinitely.
129
+ if (client && activeClientIds.has(client.id)) {
130
+ const serializedRequest = await serializeRequest(requestCloneForEvents);
131
+
132
+ // Clone the response so both the client and the library could consume it.
133
+ const responseClone = response.clone();
134
+
135
+ sendToClient(
136
+ client,
137
+ {
138
+ type: 'RESPONSE',
139
+ payload: {
140
+ isMockedResponse: IS_MOCKED_RESPONSE in response,
141
+ request: {
142
+ id: requestId,
143
+ ...serializedRequest,
144
+ },
145
+ response: {
146
+ type: responseClone.type,
147
+ status: responseClone.status,
148
+ statusText: responseClone.statusText,
149
+ headers: Object.fromEntries(responseClone.headers.entries()),
150
+ body: responseClone.body,
151
+ },
152
+ },
153
+ },
154
+ responseClone.body ? [serializedRequest.body, responseClone.body] : [],
155
+ );
156
+ }
157
+
158
+ return response;
159
159
  }
160
160
 
161
161
  /**
@@ -167,30 +167,30 @@ async function handleRequest(event, requestId, requestInterceptedAt) {
167
167
  * @returns {Promise<Client | undefined>}
168
168
  */
169
169
  async function resolveMainClient(event) {
170
- const client = await self.clients.get(event.clientId);
171
-
172
- if (activeClientIds.has(event.clientId)) {
173
- return client;
174
- }
175
-
176
- if (client?.frameType === 'top-level') {
177
- return client;
178
- }
179
-
180
- const allClients = await self.clients.matchAll({
181
- type: 'window',
182
- });
183
-
184
- return allClients
185
- .filter((client) => {
186
- // Get only those clients that are currently visible.
187
- return client.visibilityState === 'visible';
188
- })
189
- .find((client) => {
190
- // Find the client ID that's recorded in the
191
- // set of clients that have registered the worker.
192
- return activeClientIds.has(client.id);
193
- });
170
+ const client = await self.clients.get(event.clientId);
171
+
172
+ if (activeClientIds.has(event.clientId)) {
173
+ return client;
174
+ }
175
+
176
+ if (client?.frameType === 'top-level') {
177
+ return client;
178
+ }
179
+
180
+ const allClients = await self.clients.matchAll({
181
+ type: 'window',
182
+ });
183
+
184
+ return allClients
185
+ .filter((client) => {
186
+ // Get only those clients that are currently visible.
187
+ return client.visibilityState === 'visible';
188
+ })
189
+ .find((client) => {
190
+ // Find the client ID that's recorded in the
191
+ // set of clients that have registered the worker.
192
+ return activeClientIds.has(client.id);
193
+ });
194
194
  }
195
195
 
196
196
  /**
@@ -201,72 +201,72 @@ async function resolveMainClient(event) {
201
201
  * @returns {Promise<Response>}
202
202
  */
203
203
  async function getResponse(event, client, requestId, requestInterceptedAt) {
204
- // Clone the request because it might've been already used
205
- // (i.e. its body has been read and sent to the client).
206
- const requestClone = event.request.clone();
207
-
208
- function passthrough() {
209
- // Cast the request headers to a new Headers instance
210
- // so the headers can be manipulated with.
211
- const headers = new Headers(requestClone.headers);
212
-
213
- // Remove the "accept" header value that marked this request as passthrough.
214
- // This prevents request alteration and also keeps it compliant with the
215
- // user-defined CORS policies.
216
- const acceptHeader = headers.get('accept');
217
- if (acceptHeader) {
218
- const values = acceptHeader.split(',').map((value) => value.trim());
219
- const filteredValues = values.filter((value) => value !== 'msw/passthrough');
220
-
221
- if (filteredValues.length > 0) {
222
- headers.set('accept', filteredValues.join(', '));
223
- } else {
224
- headers.delete('accept');
225
- }
226
- }
227
-
228
- return fetch(requestClone, { headers });
229
- }
230
-
231
- // Bypass mocking when the client is not active.
232
- if (!client) {
233
- return passthrough();
234
- }
235
-
236
- // Bypass initial page load requests (i.e. static assets).
237
- // The absence of the immediate/parent client in the map of the active clients
238
- // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
239
- // and is not ready to handle requests.
240
- if (!activeClientIds.has(client.id)) {
241
- return passthrough();
242
- }
243
-
244
- // Notify the client that a request has been intercepted.
245
- const serializedRequest = await serializeRequest(event.request);
246
- const clientMessage = await sendToClient(
247
- client,
248
- {
249
- type: 'REQUEST',
250
- payload: {
251
- id: requestId,
252
- interceptedAt: requestInterceptedAt,
253
- ...serializedRequest,
254
- },
255
- },
256
- [serializedRequest.body],
257
- );
258
-
259
- switch (clientMessage.type) {
260
- case 'MOCK_RESPONSE': {
261
- return respondWithMock(clientMessage.data);
262
- }
263
-
264
- case 'PASSTHROUGH': {
265
- return passthrough();
266
- }
267
- }
268
-
269
- return passthrough();
204
+ // Clone the request because it might've been already used
205
+ // (i.e. its body has been read and sent to the client).
206
+ const requestClone = event.request.clone();
207
+
208
+ function passthrough() {
209
+ // Cast the request headers to a new Headers instance
210
+ // so the headers can be manipulated with.
211
+ const headers = new Headers(requestClone.headers);
212
+
213
+ // Remove the "accept" header value that marked this request as passthrough.
214
+ // This prevents request alteration and also keeps it compliant with the
215
+ // user-defined CORS policies.
216
+ const acceptHeader = headers.get('accept');
217
+ if (acceptHeader) {
218
+ const values = acceptHeader.split(',').map((value) => value.trim());
219
+ const filteredValues = values.filter((value) => value !== 'msw/passthrough');
220
+
221
+ if (filteredValues.length > 0) {
222
+ headers.set('accept', filteredValues.join(', '));
223
+ } else {
224
+ headers.delete('accept');
225
+ }
226
+ }
227
+
228
+ return fetch(requestClone, { headers });
229
+ }
230
+
231
+ // Bypass mocking when the client is not active.
232
+ if (!client) {
233
+ return passthrough();
234
+ }
235
+
236
+ // Bypass initial page load requests (i.e. static assets).
237
+ // The absence of the immediate/parent client in the map of the active clients
238
+ // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
239
+ // and is not ready to handle requests.
240
+ if (!activeClientIds.has(client.id)) {
241
+ return passthrough();
242
+ }
243
+
244
+ // Notify the client that a request has been intercepted.
245
+ const serializedRequest = await serializeRequest(event.request);
246
+ const clientMessage = await sendToClient(
247
+ client,
248
+ {
249
+ type: 'REQUEST',
250
+ payload: {
251
+ id: requestId,
252
+ interceptedAt: requestInterceptedAt,
253
+ ...serializedRequest,
254
+ },
255
+ },
256
+ [serializedRequest.body],
257
+ );
258
+
259
+ switch (clientMessage.type) {
260
+ case 'MOCK_RESPONSE': {
261
+ return respondWithMock(clientMessage.data);
262
+ }
263
+
264
+ case 'PASSTHROUGH': {
265
+ return passthrough();
266
+ }
267
+ }
268
+
269
+ return passthrough();
270
270
  }
271
271
 
272
272
  /**
@@ -276,19 +276,19 @@ async function getResponse(event, client, requestId, requestInterceptedAt) {
276
276
  * @returns {Promise<any>}
277
277
  */
278
278
  function sendToClient(client, message, transferrables = []) {
279
- return new Promise((resolve, reject) => {
280
- const channel = new MessageChannel();
279
+ return new Promise((resolve, reject) => {
280
+ const channel = new MessageChannel();
281
281
 
282
- channel.port1.onmessage = (event) => {
283
- if (event.data && event.data.error) {
284
- return reject(event.data.error);
285
- }
282
+ channel.port1.onmessage = (event) => {
283
+ if (event.data?.error) {
284
+ return reject(event.data.error);
285
+ }
286
286
 
287
- resolve(event.data);
288
- };
287
+ resolve(event.data);
288
+ };
289
289
 
290
- client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]);
291
- });
290
+ client.postMessage(message, [channel.port2, ...transferrables.filter(Boolean)]);
291
+ });
292
292
  }
293
293
 
294
294
  /**
@@ -296,41 +296,41 @@ function sendToClient(client, message, transferrables = []) {
296
296
  * @returns {Response}
297
297
  */
298
298
  function respondWithMock(response) {
299
- // Setting response status code to 0 is a no-op.
300
- // However, when responding with a "Response.error()", the produced Response
301
- // instance will have status code set to 0. Since it's not possible to create
302
- // a Response instance with status code 0, handle that use-case separately.
303
- if (response.status === 0) {
304
- return Response.error();
305
- }
306
-
307
- const mockedResponse = new Response(response.body, response);
308
-
309
- Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
310
- value: true,
311
- enumerable: true,
312
- });
313
-
314
- return mockedResponse;
299
+ // Setting response status code to 0 is a no-op.
300
+ // However, when responding with a "Response.error()", the produced Response
301
+ // instance will have status code set to 0. Since it's not possible to create
302
+ // a Response instance with status code 0, handle that use-case separately.
303
+ if (response.status === 0) {
304
+ return Response.error();
305
+ }
306
+
307
+ const mockedResponse = new Response(response.body, response);
308
+
309
+ Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
310
+ value: true,
311
+ enumerable: true,
312
+ });
313
+
314
+ return mockedResponse;
315
315
  }
316
316
 
317
317
  /**
318
318
  * @param {Request} request
319
319
  */
320
320
  async function serializeRequest(request) {
321
- return {
322
- url: request.url,
323
- mode: request.mode,
324
- method: request.method,
325
- headers: Object.fromEntries(request.headers.entries()),
326
- cache: request.cache,
327
- credentials: request.credentials,
328
- destination: request.destination,
329
- integrity: request.integrity,
330
- redirect: request.redirect,
331
- referrer: request.referrer,
332
- referrerPolicy: request.referrerPolicy,
333
- body: await request.arrayBuffer(),
334
- keepalive: request.keepalive,
335
- };
321
+ return {
322
+ url: request.url,
323
+ mode: request.mode,
324
+ method: request.method,
325
+ headers: Object.fromEntries(request.headers.entries()),
326
+ cache: request.cache,
327
+ credentials: request.credentials,
328
+ destination: request.destination,
329
+ integrity: request.integrity,
330
+ redirect: request.redirect,
331
+ referrer: request.referrer,
332
+ referrerPolicy: request.referrerPolicy,
333
+ body: await request.arrayBuffer(),
334
+ keepalive: request.keepalive,
335
+ };
336
336
  }
@@ -1,16 +1,16 @@
1
- import { writeFileSync, mkdirSync } from "node:fs";
2
- import { mkdir, writeFile } from "node:fs/promises";
3
- import { dirname, resolve } from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { parseArgs } from "node:util";
6
- import { uploadFile } from "@auto-engineer/file-upload";
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { parseArgs } from 'node:util';
6
+ import { uploadFile } from '@auto-engineer/file-upload';
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
- const OUTPUT_DIR = resolve(__dirname, "../../.context");
10
- const OUTPUT_FILE = resolve(OUTPUT_DIR, "components-db.json");
9
+ const OUTPUT_DIR = resolve(__dirname, '../../.context');
10
+ const OUTPUT_FILE = resolve(OUTPUT_DIR, 'components-db.json');
11
11
 
12
12
  const { values } = parseArgs({
13
- options: { port: { type: "string", default: "6006" } },
13
+ options: { port: { type: 'string', default: '6006' } },
14
14
  });
15
15
  const PORT = Number(values.port);
16
16
 
@@ -58,8 +58,7 @@ async function checkStorybookRunning(port: number): Promise<void> {
58
58
  for (let attempt = 0; attempt <= delays.length; attempt++) {
59
59
  try {
60
60
  const response = await fetch(`http://localhost:${port}`);
61
- if (!response.ok)
62
- throw new Error("Storybook responded with non-OK status");
61
+ if (!response.ok) throw new Error('Storybook responded with non-OK status');
63
62
  return;
64
63
  } catch {
65
64
  if (attempt === delays.length) {
@@ -79,15 +78,14 @@ async function fetchWithRetry<T>(url: string, maxAttempts = 3): Promise<T> {
79
78
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
80
79
  try {
81
80
  const res = await fetch(url);
82
- if (!res.ok)
83
- throw new Error(`${url} responded with status ${res.status}`);
81
+ if (!res.ok) throw new Error(`${url} responded with status ${res.status}`);
84
82
  return await res.json();
85
83
  } catch (err) {
86
84
  if (attempt === maxAttempts) throw err;
87
85
  await new Promise((r) => setTimeout(r, 1000));
88
86
  }
89
87
  }
90
- throw new Error("unreachable");
88
+ throw new Error('unreachable');
91
89
  }
92
90
 
93
91
  function merge(componentsJson: ComponentsManifest, indexJson: IndexJson) {
@@ -97,13 +95,12 @@ function merge(componentsJson: ComponentsManifest, indexJson: IndexJson) {
97
95
  const docsByComponent = new Map<string, IndexEntry>();
98
96
 
99
97
  for (const entry of Object.values(entries)) {
100
- const componentId = entry.id.replace(/--.*$/, "");
98
+ const componentId = entry.id.replace(/--.*$/, '');
101
99
 
102
- if (entry.type === "docs") {
100
+ if (entry.type === 'docs') {
103
101
  docsByComponent.set(componentId, entry);
104
102
  } else {
105
- if (!storysByComponent.has(componentId))
106
- storysByComponent.set(componentId, []);
103
+ if (!storysByComponent.has(componentId)) storysByComponent.set(componentId, []);
107
104
  storysByComponent.get(componentId)!.push(entry);
108
105
  }
109
106
  }
@@ -153,14 +150,14 @@ const [componentsJson, indexJson] = await Promise.all([
153
150
 
154
151
  const merged = merge(componentsJson, indexJson);
155
152
 
156
- const json = JSON.stringify(merged, null, 2) + "\n";
153
+ const json = `${JSON.stringify(merged, null, 2)}\n`;
157
154
 
158
155
  mkdirSync(OUTPUT_DIR, { recursive: true });
159
156
  writeFileSync(OUTPUT_FILE, json);
160
157
 
161
158
  console.log(`Wrote ${merged.length} components to ${OUTPUT_FILE}`);
162
159
 
163
- await uploadFile(".context/components-db.json", new TextEncoder().encode(json), {
160
+ await uploadFile('.context/components-db.json', new TextEncoder().encode(json), {
164
161
  uploadUrl: process.env.FILE_UPLOAD_URL,
165
162
  prefix: process.env.FILE_UPLOAD_PREFIX,
166
163
  signerUrl: process.env.UPLOAD_SIGNER_URL,