@intrig/plugin-react 0.0.1 → 0.0.2-2

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 (58) hide show
  1. package/dist/index.cjs +4260 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +4235 -0
  4. package/package.json +6 -3
  5. package/.swcrc +0 -29
  6. package/README.md +0 -7
  7. package/eslint.config.mjs +0 -19
  8. package/project.json +0 -29
  9. package/rollup.config.cjs +0 -54
  10. package/rollup.config.mjs +0 -33
  11. package/src/index.ts +0 -2
  12. package/src/lib/code-generator.ts +0 -79
  13. package/src/lib/get-endpoint-documentation.ts +0 -35
  14. package/src/lib/get-schema-documentation.ts +0 -11
  15. package/src/lib/internal-types.ts +0 -15
  16. package/src/lib/plugin-react.ts +0 -22
  17. package/src/lib/templates/context.template.ts +0 -74
  18. package/src/lib/templates/docs/__snapshots__/async-hook.spec.ts.snap +0 -889
  19. package/src/lib/templates/docs/__snapshots__/download-hook.spec.ts.snap +0 -1445
  20. package/src/lib/templates/docs/__snapshots__/react-hook.spec.ts.snap +0 -1371
  21. package/src/lib/templates/docs/__snapshots__/sse-hook.spec.ts.snap +0 -2008
  22. package/src/lib/templates/docs/async-hook.spec.ts +0 -92
  23. package/src/lib/templates/docs/async-hook.ts +0 -226
  24. package/src/lib/templates/docs/download-hook.spec.ts +0 -182
  25. package/src/lib/templates/docs/download-hook.ts +0 -170
  26. package/src/lib/templates/docs/react-hook.spec.ts +0 -97
  27. package/src/lib/templates/docs/react-hook.ts +0 -323
  28. package/src/lib/templates/docs/schema.ts +0 -105
  29. package/src/lib/templates/docs/sse-hook.spec.ts +0 -207
  30. package/src/lib/templates/docs/sse-hook.ts +0 -221
  31. package/src/lib/templates/extra.template.ts +0 -198
  32. package/src/lib/templates/index.template.ts +0 -14
  33. package/src/lib/templates/intrigMiddleware.template.ts +0 -21
  34. package/src/lib/templates/logger.template.ts +0 -67
  35. package/src/lib/templates/media-type-utils.template.ts +0 -191
  36. package/src/lib/templates/network-state.template.ts +0 -702
  37. package/src/lib/templates/packageJson.template.ts +0 -63
  38. package/src/lib/templates/provider/__tests__/provider-templates.spec.ts +0 -209
  39. package/src/lib/templates/provider/axios-config.template.ts +0 -49
  40. package/src/lib/templates/provider/hooks.template.ts +0 -240
  41. package/src/lib/templates/provider/interfaces.template.ts +0 -72
  42. package/src/lib/templates/provider/intrig-provider-stub.template.ts +0 -73
  43. package/src/lib/templates/provider/intrig-provider.template.ts +0 -185
  44. package/src/lib/templates/provider/main.template.ts +0 -48
  45. package/src/lib/templates/provider/reducer.template.ts +0 -50
  46. package/src/lib/templates/provider/status-trap.template.ts +0 -80
  47. package/src/lib/templates/provider.template.ts +0 -698
  48. package/src/lib/templates/source/controller/method/asyncFunctionHook.template.ts +0 -196
  49. package/src/lib/templates/source/controller/method/clientIndex.template.ts +0 -38
  50. package/src/lib/templates/source/controller/method/download.template.ts +0 -256
  51. package/src/lib/templates/source/controller/method/params.template.ts +0 -31
  52. package/src/lib/templates/source/controller/method/requestHook.template.ts +0 -220
  53. package/src/lib/templates/source/type/typeTemplate.ts +0 -257
  54. package/src/lib/templates/swcrc.template.ts +0 -25
  55. package/src/lib/templates/tsconfig.template.ts +0 -37
  56. package/src/lib/templates/type-utils.template.ts +0 -28
  57. package/tsconfig.json +0 -13
  58. package/tsconfig.lib.json +0 -20
@@ -1,1445 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`reactDownloadHookDocs > handles case-insensitive path parameter detection 1`] = `
4
- "# Intrig Download Hooks — Quick Guide
5
-
6
- ## Copy-paste starter (fast lane)
7
-
8
- ### Auto-download (most common)
9
-
10
- \`\`\`ts
11
- import { useDownloadInvoiceDownload } from "@intrig/react/invoices/{invoiceId}/client";
12
- \`\`\`
13
-
14
- \`\`\`ts
15
- import { isPending, isError } from "@intrig/react";
16
- \`\`\`
17
-
18
- \`\`\`tsx
19
- const [downloadInvoiceResp, downloadInvoice] = useDownloadInvoiceDownload({
20
- clearOnUnmount: true,
21
- });
22
- // e.g., in a click handler:
23
- downloadInvoice(downloadInvoiceParams);
24
- \`\`\`
25
-
26
- ### Manual/stateful (you handle the blob/UI)
27
-
28
- \`\`\`ts
29
- import { useDownloadInvoice } from "@intrig/react/invoices/{invoiceId}/client";
30
- \`\`\`
31
-
32
- \`\`\`ts
33
- import { isSuccess, isPending, isError } from "@intrig/react";
34
- \`\`\`
35
-
36
- \`\`\`tsx
37
- const [downloadInvoiceResp, downloadInvoice] = useDownloadInvoice({
38
- clearOnUnmount: true,
39
- });
40
- // later:
41
- downloadInvoice(downloadInvoiceParams);
42
- \`\`\`
43
-
44
- ---
45
-
46
- ## TL;DR (auto-download)
47
-
48
- \`\`\`tsx
49
- import { useDownloadInvoiceDownload } from "@intrig/react/invoices/{invoiceId}/client";
50
- import { isPending, isError } from "@intrig/react";
51
-
52
- export default function Example() {
53
- const [downloadInvoiceResp, downloadInvoice] = useDownloadInvoiceDownload({
54
- clearOnUnmount: true,
55
- });
56
-
57
- return (
58
- <button
59
- onClick={() => downloadInvoice(downloadInvoiceParams)}
60
- disabled={isPending(downloadInvoiceResp)}
61
- >
62
- {isPending(downloadInvoiceResp) ? "Downloading…" : "Download"}
63
- </button>
64
- );
65
- }
66
- \`\`\`
67
-
68
- ### Optional types (if generated by your build)
69
-
70
- \`\`\`ts
71
- import type { DownloadInvoiceParams } from "@intrig/react/invoices/{invoiceId}/DownloadInvoice.params";
72
- import type { DownloadInvoiceResponseBody } from "@intrig/react/invoices/{invoiceId}/DownloadInvoice.response";
73
- \`\`\`
74
-
75
- ---
76
-
77
- ## Hook APIs
78
-
79
- ### \`useDownloadInvoiceDownload\` (auto-download)
80
-
81
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
82
- - **Signature:** \`[state, download, clear]\`
83
- - \`download(params: DownloadInvoiceParams) => void\`
84
-
85
- ### \`useDownloadInvoice\` (manual/stateful)
86
-
87
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
88
- - **Signature:** \`[state, fetchFile, clear]\`
89
- - \`fetchFile(params: DownloadInvoiceParams) => void\`
90
-
91
- ---
92
-
93
- ## Usage Patterns
94
-
95
- ### 1) Auto-download on click (recommended)
96
-
97
- \`\`\`tsx
98
- const [downloadInvoiceResp, downloadInvoice] = useDownloadInvoiceDownload({
99
- clearOnUnmount: true,
100
- });
101
-
102
- <button
103
- onClick={() => downloadInvoice(downloadInvoiceParams)}
104
- disabled={isPending(downloadInvoiceResp)}
105
- >
106
- {isPending(downloadInvoiceResp) ? "Downloading…" : "Download file"}
107
- </button>;
108
- {
109
- isError(downloadInvoiceResp) ? (
110
- <p className="text-red-500">Failed to download.</p>
111
- ) : null;
112
- }
113
- \`\`\`
114
-
115
- <details><summary>Description</summary>
116
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
117
- </details>
118
-
119
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
120
-
121
- \`\`\`tsx
122
- useEffect(() => {
123
- downloadInvoice(downloadInvoiceParams);
124
- }, [downloadInvoice]);
125
- \`\`\`
126
-
127
- <details><summary>Description</summary>
128
- <p>Good for post-processing routes that immediately start a download.</p>
129
- </details>
130
-
131
- ### 3) Manual handling (preview or custom filename)
132
-
133
- \`\`\`tsx
134
- const [downloadInvoiceResp, downloadInvoice] = useDownloadInvoice({
135
- clearOnUnmount: true,
136
- });
137
-
138
- useEffect(() => {
139
- if (isSuccess(downloadInvoiceResp)) {
140
- const ct =
141
- downloadInvoiceResp.headers?.["content-type"] ??
142
- "application/octet-stream";
143
- const parts = Array.isArray(downloadInvoiceResp.data)
144
- ? downloadInvoiceResp.data
145
- : [downloadInvoiceResp.data];
146
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
147
- // preview/save with your own UI...
148
- return () => URL.revokeObjectURL(url);
149
- }
150
- }, [downloadInvoiceResp]);
151
- \`\`\`
152
-
153
- <details><summary>Description</summary>
154
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
155
- </details>
156
-
157
- ---
158
-
159
- ## Behavior notes (what the auto-download variant does)
160
-
161
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
162
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
163
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
164
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
165
-
166
- ---
167
-
168
- ## Gotchas & Tips
169
-
170
- - **Expose headers in CORS:** server should send
171
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
172
- - **Disable double clicks:** guard with \`isPending(state)\`.
173
- - **Revoke URLs** when you create them manually in the stateful variant.
174
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
175
-
176
- ---
177
-
178
- ## Troubleshooting
179
-
180
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
181
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
182
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
183
-
184
- ---
185
- "
186
- `;
187
-
188
- exports[`reactDownloadHookDocs > handles empty variables array 1`] = `
189
- "# Intrig Download Hooks — Quick Guide
190
-
191
- ## Copy-paste starter (fast lane)
192
-
193
- ### Auto-download (most common)
194
-
195
- \`\`\`ts
196
- import { useDownloadBackupDownload } from "@intrig/react/backup/client";
197
- \`\`\`
198
-
199
- \`\`\`ts
200
- import { isPending, isError } from "@intrig/react";
201
- \`\`\`
202
-
203
- \`\`\`tsx
204
- const [downloadBackupResp, downloadBackup] = useDownloadBackupDownload({
205
- clearOnUnmount: true,
206
- });
207
- // e.g., in a click handler:
208
- downloadBackup({});
209
- \`\`\`
210
-
211
- ### Manual/stateful (you handle the blob/UI)
212
-
213
- \`\`\`ts
214
- import { useDownloadBackup } from "@intrig/react/backup/client";
215
- \`\`\`
216
-
217
- \`\`\`ts
218
- import { isSuccess, isPending, isError } from "@intrig/react";
219
- \`\`\`
220
-
221
- \`\`\`tsx
222
- const [downloadBackupResp, downloadBackup] = useDownloadBackup({
223
- clearOnUnmount: true,
224
- });
225
- // later:
226
- downloadBackup({});
227
- \`\`\`
228
-
229
- ---
230
-
231
- ## TL;DR (auto-download)
232
-
233
- \`\`\`tsx
234
- import { useDownloadBackupDownload } from "@intrig/react/backup/client";
235
- import { isPending, isError } from "@intrig/react";
236
-
237
- export default function Example() {
238
- const [downloadBackupResp, downloadBackup] = useDownloadBackupDownload({
239
- clearOnUnmount: true,
240
- });
241
-
242
- return (
243
- <button
244
- onClick={() => downloadBackup({})}
245
- disabled={isPending(downloadBackupResp)}
246
- >
247
- {isPending(downloadBackupResp) ? "Downloading…" : "Download"}
248
- </button>
249
- );
250
- }
251
- \`\`\`
252
-
253
- ---
254
-
255
- ## Hook APIs
256
-
257
- ### \`useDownloadBackupDownload\` (auto-download)
258
-
259
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
260
- - **Signature:** \`[state, download, clear]\`
261
- - \`download(params: Record<string, unknown>) => void\`
262
-
263
- ### \`useDownloadBackup\` (manual/stateful)
264
-
265
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
266
- - **Signature:** \`[state, fetchFile, clear]\`
267
- - \`fetchFile(params: Record<string, unknown>) => void\`
268
-
269
- ---
270
-
271
- ## Usage Patterns
272
-
273
- ### 1) Auto-download on click (recommended)
274
-
275
- \`\`\`tsx
276
- const [downloadBackupResp, downloadBackup] = useDownloadBackupDownload({
277
- clearOnUnmount: true,
278
- });
279
-
280
- <button
281
- onClick={() => downloadBackup({})}
282
- disabled={isPending(downloadBackupResp)}
283
- >
284
- {isPending(downloadBackupResp) ? "Downloading…" : "Download file"}
285
- </button>;
286
- {
287
- isError(downloadBackupResp) ? (
288
- <p className="text-red-500">Failed to download.</p>
289
- ) : null;
290
- }
291
- \`\`\`
292
-
293
- <details><summary>Description</summary>
294
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
295
- </details>
296
-
297
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
298
-
299
- \`\`\`tsx
300
- useEffect(() => {
301
- downloadBackup({});
302
- }, [downloadBackup]);
303
- \`\`\`
304
-
305
- <details><summary>Description</summary>
306
- <p>Good for post-processing routes that immediately start a download.</p>
307
- </details>
308
-
309
- ### 3) Manual handling (preview or custom filename)
310
-
311
- \`\`\`tsx
312
- const [downloadBackupResp, downloadBackup] = useDownloadBackup({
313
- clearOnUnmount: true,
314
- });
315
-
316
- useEffect(() => {
317
- if (isSuccess(downloadBackupResp)) {
318
- const ct =
319
- downloadBackupResp.headers?.["content-type"] ??
320
- "application/octet-stream";
321
- const parts = Array.isArray(downloadBackupResp.data)
322
- ? downloadBackupResp.data
323
- : [downloadBackupResp.data];
324
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
325
- // preview/save with your own UI...
326
- return () => URL.revokeObjectURL(url);
327
- }
328
- }, [downloadBackupResp]);
329
- \`\`\`
330
-
331
- <details><summary>Description</summary>
332
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
333
- </details>
334
-
335
- ---
336
-
337
- ## Behavior notes (what the auto-download variant does)
338
-
339
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
340
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
341
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
342
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
343
-
344
- ---
345
-
346
- ## Gotchas & Tips
347
-
348
- - **Expose headers in CORS:** server should send
349
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
350
- - **Disable double clicks:** guard with \`isPending(state)\`.
351
- - **Revoke URLs** when you create them manually in the stateful variant.
352
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
353
-
354
- ---
355
-
356
- ## Troubleshooting
357
-
358
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
359
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
360
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
361
-
362
- ---
363
- "
364
- `;
365
-
366
- exports[`reactDownloadHookDocs > handles multiple path params 1`] = `
367
- "# Intrig Download Hooks — Quick Guide
368
-
369
- ## Copy-paste starter (fast lane)
370
-
371
- ### Auto-download (most common)
372
-
373
- \`\`\`ts
374
- import { useDownloadProjectAssetDownload } from "@intrig/react/projects/{projectId}/assets/{assetId}/client";
375
- \`\`\`
376
-
377
- \`\`\`ts
378
- import { isPending, isError } from "@intrig/react";
379
- \`\`\`
380
-
381
- \`\`\`tsx
382
- const [downloadProjectAssetResp, downloadProjectAsset] =
383
- useDownloadProjectAssetDownload({ clearOnUnmount: true });
384
- // e.g., in a click handler:
385
- downloadProjectAsset(downloadProjectAssetParams);
386
- \`\`\`
387
-
388
- ### Manual/stateful (you handle the blob/UI)
389
-
390
- \`\`\`ts
391
- import { useDownloadProjectAsset } from "@intrig/react/projects/{projectId}/assets/{assetId}/client";
392
- \`\`\`
393
-
394
- \`\`\`ts
395
- import { isSuccess, isPending, isError } from "@intrig/react";
396
- \`\`\`
397
-
398
- \`\`\`tsx
399
- const [downloadProjectAssetResp, downloadProjectAsset] =
400
- useDownloadProjectAsset({ clearOnUnmount: true });
401
- // later:
402
- downloadProjectAsset(downloadProjectAssetParams);
403
- \`\`\`
404
-
405
- ---
406
-
407
- ## TL;DR (auto-download)
408
-
409
- \`\`\`tsx
410
- import { useDownloadProjectAssetDownload } from "@intrig/react/projects/{projectId}/assets/{assetId}/client";
411
- import { isPending, isError } from "@intrig/react";
412
-
413
- export default function Example() {
414
- const [downloadProjectAssetResp, downloadProjectAsset] =
415
- useDownloadProjectAssetDownload({ clearOnUnmount: true });
416
-
417
- return (
418
- <button
419
- onClick={() => downloadProjectAsset(downloadProjectAssetParams)}
420
- disabled={isPending(downloadProjectAssetResp)}
421
- >
422
- {isPending(downloadProjectAssetResp) ? "Downloading…" : "Download"}
423
- </button>
424
- );
425
- }
426
- \`\`\`
427
-
428
- ### Optional types (if generated by your build)
429
-
430
- \`\`\`ts
431
- import type { DownloadProjectAssetParams } from "@intrig/react/projects/{projectId}/assets/{assetId}/DownloadProjectAsset.params";
432
- import type { DownloadProjectAssetResponseBody } from "@intrig/react/projects/{projectId}/assets/{assetId}/DownloadProjectAsset.response";
433
- \`\`\`
434
-
435
- ---
436
-
437
- ## Hook APIs
438
-
439
- ### \`useDownloadProjectAssetDownload\` (auto-download)
440
-
441
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
442
- - **Signature:** \`[state, download, clear]\`
443
- - \`download(params: DownloadProjectAssetParams) => void\`
444
-
445
- ### \`useDownloadProjectAsset\` (manual/stateful)
446
-
447
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
448
- - **Signature:** \`[state, fetchFile, clear]\`
449
- - \`fetchFile(params: DownloadProjectAssetParams) => void\`
450
-
451
- ---
452
-
453
- ## Usage Patterns
454
-
455
- ### 1) Auto-download on click (recommended)
456
-
457
- \`\`\`tsx
458
- const [downloadProjectAssetResp, downloadProjectAsset] =
459
- useDownloadProjectAssetDownload({ clearOnUnmount: true });
460
-
461
- <button
462
- onClick={() => downloadProjectAsset(downloadProjectAssetParams)}
463
- disabled={isPending(downloadProjectAssetResp)}
464
- >
465
- {isPending(downloadProjectAssetResp) ? "Downloading…" : "Download file"}
466
- </button>;
467
- {
468
- isError(downloadProjectAssetResp) ? (
469
- <p className="text-red-500">Failed to download.</p>
470
- ) : null;
471
- }
472
- \`\`\`
473
-
474
- <details><summary>Description</summary>
475
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
476
- </details>
477
-
478
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
479
-
480
- \`\`\`tsx
481
- useEffect(() => {
482
- downloadProjectAsset(downloadProjectAssetParams);
483
- }, [downloadProjectAsset]);
484
- \`\`\`
485
-
486
- <details><summary>Description</summary>
487
- <p>Good for post-processing routes that immediately start a download.</p>
488
- </details>
489
-
490
- ### 3) Manual handling (preview or custom filename)
491
-
492
- \`\`\`tsx
493
- const [downloadProjectAssetResp, downloadProjectAsset] =
494
- useDownloadProjectAsset({ clearOnUnmount: true });
495
-
496
- useEffect(() => {
497
- if (isSuccess(downloadProjectAssetResp)) {
498
- const ct =
499
- downloadProjectAssetResp.headers?.["content-type"] ??
500
- "application/octet-stream";
501
- const parts = Array.isArray(downloadProjectAssetResp.data)
502
- ? downloadProjectAssetResp.data
503
- : [downloadProjectAssetResp.data];
504
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
505
- // preview/save with your own UI...
506
- return () => URL.revokeObjectURL(url);
507
- }
508
- }, [downloadProjectAssetResp]);
509
- \`\`\`
510
-
511
- <details><summary>Description</summary>
512
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
513
- </details>
514
-
515
- ---
516
-
517
- ## Behavior notes (what the auto-download variant does)
518
-
519
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
520
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
521
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
522
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
523
-
524
- ---
525
-
526
- ## Gotchas & Tips
527
-
528
- - **Expose headers in CORS:** server should send
529
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
530
- - **Disable double clicks:** guard with \`isPending(state)\`.
531
- - **Revoke URLs** when you create them manually in the stateful variant.
532
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
533
-
534
- ---
535
-
536
- ## Troubleshooting
537
-
538
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
539
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
540
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
541
-
542
- ---
543
- "
544
- `;
545
-
546
- exports[`reactDownloadHookDocs > handles query params mixed with path params 1`] = `
547
- "# Intrig Download Hooks — Quick Guide
548
-
549
- ## Copy-paste starter (fast lane)
550
-
551
- ### Auto-download (most common)
552
-
553
- \`\`\`ts
554
- import { useDownloadTaskFileDownload } from "@intrig/react/tasks/{taskId}/files/client";
555
- \`\`\`
556
-
557
- \`\`\`ts
558
- import { isPending, isError } from "@intrig/react";
559
- \`\`\`
560
-
561
- \`\`\`tsx
562
- const [downloadTaskFileResp, downloadTaskFile] = useDownloadTaskFileDownload({
563
- clearOnUnmount: true,
564
- });
565
- // e.g., in a click handler:
566
- downloadTaskFile(downloadTaskFileParams);
567
- \`\`\`
568
-
569
- ### Manual/stateful (you handle the blob/UI)
570
-
571
- \`\`\`ts
572
- import { useDownloadTaskFile } from "@intrig/react/tasks/{taskId}/files/client";
573
- \`\`\`
574
-
575
- \`\`\`ts
576
- import { isSuccess, isPending, isError } from "@intrig/react";
577
- \`\`\`
578
-
579
- \`\`\`tsx
580
- const [downloadTaskFileResp, downloadTaskFile] = useDownloadTaskFile({
581
- clearOnUnmount: true,
582
- });
583
- // later:
584
- downloadTaskFile(downloadTaskFileParams);
585
- \`\`\`
586
-
587
- ---
588
-
589
- ## TL;DR (auto-download)
590
-
591
- \`\`\`tsx
592
- import { useDownloadTaskFileDownload } from "@intrig/react/tasks/{taskId}/files/client";
593
- import { isPending, isError } from "@intrig/react";
594
-
595
- export default function Example() {
596
- const [downloadTaskFileResp, downloadTaskFile] = useDownloadTaskFileDownload({
597
- clearOnUnmount: true,
598
- });
599
-
600
- return (
601
- <button
602
- onClick={() => downloadTaskFile(downloadTaskFileParams)}
603
- disabled={isPending(downloadTaskFileResp)}
604
- >
605
- {isPending(downloadTaskFileResp) ? "Downloading…" : "Download"}
606
- </button>
607
- );
608
- }
609
- \`\`\`
610
-
611
- ### Optional types (if generated by your build)
612
-
613
- \`\`\`ts
614
- import type { DownloadTaskFileParams } from "@intrig/react/tasks/{taskId}/files/DownloadTaskFile.params";
615
- import type { DownloadTaskFileResponseBody } from "@intrig/react/tasks/{taskId}/files/DownloadTaskFile.response";
616
- \`\`\`
617
-
618
- ---
619
-
620
- ## Hook APIs
621
-
622
- ### \`useDownloadTaskFileDownload\` (auto-download)
623
-
624
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
625
- - **Signature:** \`[state, download, clear]\`
626
- - \`download(params: DownloadTaskFileParams) => void\`
627
-
628
- ### \`useDownloadTaskFile\` (manual/stateful)
629
-
630
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
631
- - **Signature:** \`[state, fetchFile, clear]\`
632
- - \`fetchFile(params: DownloadTaskFileParams) => void\`
633
-
634
- ---
635
-
636
- ## Usage Patterns
637
-
638
- ### 1) Auto-download on click (recommended)
639
-
640
- \`\`\`tsx
641
- const [downloadTaskFileResp, downloadTaskFile] = useDownloadTaskFileDownload({
642
- clearOnUnmount: true,
643
- });
644
-
645
- <button
646
- onClick={() => downloadTaskFile(downloadTaskFileParams)}
647
- disabled={isPending(downloadTaskFileResp)}
648
- >
649
- {isPending(downloadTaskFileResp) ? "Downloading…" : "Download file"}
650
- </button>;
651
- {
652
- isError(downloadTaskFileResp) ? (
653
- <p className="text-red-500">Failed to download.</p>
654
- ) : null;
655
- }
656
- \`\`\`
657
-
658
- <details><summary>Description</summary>
659
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
660
- </details>
661
-
662
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
663
-
664
- \`\`\`tsx
665
- useEffect(() => {
666
- downloadTaskFile(downloadTaskFileParams);
667
- }, [downloadTaskFile]);
668
- \`\`\`
669
-
670
- <details><summary>Description</summary>
671
- <p>Good for post-processing routes that immediately start a download.</p>
672
- </details>
673
-
674
- ### 3) Manual handling (preview or custom filename)
675
-
676
- \`\`\`tsx
677
- const [downloadTaskFileResp, downloadTaskFile] = useDownloadTaskFile({
678
- clearOnUnmount: true,
679
- });
680
-
681
- useEffect(() => {
682
- if (isSuccess(downloadTaskFileResp)) {
683
- const ct =
684
- downloadTaskFileResp.headers?.["content-type"] ??
685
- "application/octet-stream";
686
- const parts = Array.isArray(downloadTaskFileResp.data)
687
- ? downloadTaskFileResp.data
688
- : [downloadTaskFileResp.data];
689
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
690
- // preview/save with your own UI...
691
- return () => URL.revokeObjectURL(url);
692
- }
693
- }, [downloadTaskFileResp]);
694
- \`\`\`
695
-
696
- <details><summary>Description</summary>
697
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
698
- </details>
699
-
700
- ---
701
-
702
- ## Behavior notes (what the auto-download variant does)
703
-
704
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
705
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
706
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
707
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
708
-
709
- ---
710
-
711
- ## Gotchas & Tips
712
-
713
- - **Expose headers in CORS:** server should send
714
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
715
- - **Disable double clicks:** guard with \`isPending(state)\`.
716
- - **Revoke URLs** when you create them manually in the stateful variant.
717
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
718
-
719
- ---
720
-
721
- ## Troubleshooting
722
-
723
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
724
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
725
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
726
-
727
- ---
728
- "
729
- `;
730
-
731
- exports[`reactDownloadHookDocs > snapshot — path params only (no request body) 1`] = `
732
- "# Intrig Download Hooks — Quick Guide
733
-
734
- ## Copy-paste starter (fast lane)
735
-
736
- ### Auto-download (most common)
737
-
738
- \`\`\`ts
739
- import { useDownloadFileByIdDownload } from "@intrig/react/files/{id}/client";
740
- \`\`\`
741
-
742
- \`\`\`ts
743
- import { isPending, isError } from "@intrig/react";
744
- \`\`\`
745
-
746
- \`\`\`tsx
747
- const [downloadFileByIdResp, downloadFileById] = useDownloadFileByIdDownload({
748
- clearOnUnmount: true,
749
- });
750
- // e.g., in a click handler:
751
- downloadFileById(downloadFileByIdParams);
752
- \`\`\`
753
-
754
- ### Manual/stateful (you handle the blob/UI)
755
-
756
- \`\`\`ts
757
- import { useDownloadFileById } from "@intrig/react/files/{id}/client";
758
- \`\`\`
759
-
760
- \`\`\`ts
761
- import { isSuccess, isPending, isError } from "@intrig/react";
762
- \`\`\`
763
-
764
- \`\`\`tsx
765
- const [downloadFileByIdResp, downloadFileById] = useDownloadFileById({
766
- clearOnUnmount: true,
767
- });
768
- // later:
769
- downloadFileById(downloadFileByIdParams);
770
- \`\`\`
771
-
772
- ---
773
-
774
- ## TL;DR (auto-download)
775
-
776
- \`\`\`tsx
777
- import { useDownloadFileByIdDownload } from "@intrig/react/files/{id}/client";
778
- import { isPending, isError } from "@intrig/react";
779
-
780
- export default function Example() {
781
- const [downloadFileByIdResp, downloadFileById] = useDownloadFileByIdDownload({
782
- clearOnUnmount: true,
783
- });
784
-
785
- return (
786
- <button
787
- onClick={() => downloadFileById(downloadFileByIdParams)}
788
- disabled={isPending(downloadFileByIdResp)}
789
- >
790
- {isPending(downloadFileByIdResp) ? "Downloading…" : "Download"}
791
- </button>
792
- );
793
- }
794
- \`\`\`
795
-
796
- ### Optional types (if generated by your build)
797
-
798
- \`\`\`ts
799
- import type { DownloadFileByIdParams } from "@intrig/react/files/{id}/DownloadFileById.params";
800
- import type { DownloadFileByIdResponseBody } from "@intrig/react/files/{id}/DownloadFileById.response";
801
- \`\`\`
802
-
803
- ---
804
-
805
- ## Hook APIs
806
-
807
- ### \`useDownloadFileByIdDownload\` (auto-download)
808
-
809
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
810
- - **Signature:** \`[state, download, clear]\`
811
- - \`download(params: DownloadFileByIdParams) => void\`
812
-
813
- ### \`useDownloadFileById\` (manual/stateful)
814
-
815
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
816
- - **Signature:** \`[state, fetchFile, clear]\`
817
- - \`fetchFile(params: DownloadFileByIdParams) => void\`
818
-
819
- ---
820
-
821
- ## Usage Patterns
822
-
823
- ### 1) Auto-download on click (recommended)
824
-
825
- \`\`\`tsx
826
- const [downloadFileByIdResp, downloadFileById] = useDownloadFileByIdDownload({
827
- clearOnUnmount: true,
828
- });
829
-
830
- <button
831
- onClick={() => downloadFileById(downloadFileByIdParams)}
832
- disabled={isPending(downloadFileByIdResp)}
833
- >
834
- {isPending(downloadFileByIdResp) ? "Downloading…" : "Download file"}
835
- </button>;
836
- {
837
- isError(downloadFileByIdResp) ? (
838
- <p className="text-red-500">Failed to download.</p>
839
- ) : null;
840
- }
841
- \`\`\`
842
-
843
- <details><summary>Description</summary>
844
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
845
- </details>
846
-
847
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
848
-
849
- \`\`\`tsx
850
- useEffect(() => {
851
- downloadFileById(downloadFileByIdParams);
852
- }, [downloadFileById]);
853
- \`\`\`
854
-
855
- <details><summary>Description</summary>
856
- <p>Good for post-processing routes that immediately start a download.</p>
857
- </details>
858
-
859
- ### 3) Manual handling (preview or custom filename)
860
-
861
- \`\`\`tsx
862
- const [downloadFileByIdResp, downloadFileById] = useDownloadFileById({
863
- clearOnUnmount: true,
864
- });
865
-
866
- useEffect(() => {
867
- if (isSuccess(downloadFileByIdResp)) {
868
- const ct =
869
- downloadFileByIdResp.headers?.["content-type"] ??
870
- "application/octet-stream";
871
- const parts = Array.isArray(downloadFileByIdResp.data)
872
- ? downloadFileByIdResp.data
873
- : [downloadFileByIdResp.data];
874
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
875
- // preview/save with your own UI...
876
- return () => URL.revokeObjectURL(url);
877
- }
878
- }, [downloadFileByIdResp]);
879
- \`\`\`
880
-
881
- <details><summary>Description</summary>
882
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
883
- </details>
884
-
885
- ---
886
-
887
- ## Behavior notes (what the auto-download variant does)
888
-
889
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
890
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
891
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
892
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
893
-
894
- ---
895
-
896
- ## Gotchas & Tips
897
-
898
- - **Expose headers in CORS:** server should send
899
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
900
- - **Disable double clicks:** guard with \`isPending(state)\`.
901
- - **Revoke URLs** when you create them manually in the stateful variant.
902
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
903
-
904
- ---
905
-
906
- ## Troubleshooting
907
-
908
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
909
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
910
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
911
-
912
- ---
913
- "
914
- `;
915
-
916
- exports[`reactDownloadHookDocs > snapshot — request body and path params 1`] = `
917
- "# Intrig Download Hooks — Quick Guide
918
-
919
- ## Copy-paste starter (fast lane)
920
-
921
- ### Auto-download (most common)
922
-
923
- \`\`\`ts
924
- import { useDownloadUserDocumentDownload } from "@intrig/react/users/{userId}/documents/client";
925
- \`\`\`
926
-
927
- \`\`\`ts
928
- import { isPending, isError } from "@intrig/react";
929
- \`\`\`
930
-
931
- \`\`\`tsx
932
- const [downloadUserDocumentResp, downloadUserDocument] =
933
- useDownloadUserDocumentDownload({ clearOnUnmount: true });
934
- // e.g., in a click handler:
935
- downloadUserDocument(downloadUserDocumentParams);
936
- \`\`\`
937
-
938
- ### Manual/stateful (you handle the blob/UI)
939
-
940
- \`\`\`ts
941
- import { useDownloadUserDocument } from "@intrig/react/users/{userId}/documents/client";
942
- \`\`\`
943
-
944
- \`\`\`ts
945
- import { isSuccess, isPending, isError } from "@intrig/react";
946
- \`\`\`
947
-
948
- \`\`\`tsx
949
- const [downloadUserDocumentResp, downloadUserDocument] =
950
- useDownloadUserDocument({ clearOnUnmount: true });
951
- // later:
952
- downloadUserDocument(downloadUserDocumentParams);
953
- \`\`\`
954
-
955
- ---
956
-
957
- ## TL;DR (auto-download)
958
-
959
- \`\`\`tsx
960
- import { useDownloadUserDocumentDownload } from "@intrig/react/users/{userId}/documents/client";
961
- import { isPending, isError } from "@intrig/react";
962
-
963
- export default function Example() {
964
- const [downloadUserDocumentResp, downloadUserDocument] =
965
- useDownloadUserDocumentDownload({ clearOnUnmount: true });
966
-
967
- return (
968
- <button
969
- onClick={() => downloadUserDocument(downloadUserDocumentParams)}
970
- disabled={isPending(downloadUserDocumentResp)}
971
- >
972
- {isPending(downloadUserDocumentResp) ? "Downloading…" : "Download"}
973
- </button>
974
- );
975
- }
976
- \`\`\`
977
-
978
- ### Optional types (if generated by your build)
979
-
980
- \`\`\`ts
981
- import type { DownloadUserDocumentParams } from "@intrig/react/users/{userId}/documents/DownloadUserDocument.params";
982
- import type { DownloadUserDocumentResponseBody } from "@intrig/react/users/{userId}/documents/DownloadUserDocument.response";
983
- \`\`\`
984
-
985
- ---
986
-
987
- ## Hook APIs
988
-
989
- ### \`useDownloadUserDocumentDownload\` (auto-download)
990
-
991
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
992
- - **Signature:** \`[state, download, clear]\`
993
- - \`download(params: DownloadUserDocumentParams) => void\`
994
-
995
- ### \`useDownloadUserDocument\` (manual/stateful)
996
-
997
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
998
- - **Signature:** \`[state, fetchFile, clear]\`
999
- - \`fetchFile(params: DownloadUserDocumentParams) => void\`
1000
-
1001
- ---
1002
-
1003
- ## Usage Patterns
1004
-
1005
- ### 1) Auto-download on click (recommended)
1006
-
1007
- \`\`\`tsx
1008
- const [downloadUserDocumentResp, downloadUserDocument] =
1009
- useDownloadUserDocumentDownload({ clearOnUnmount: true });
1010
-
1011
- <button
1012
- onClick={() => downloadUserDocument(downloadUserDocumentParams)}
1013
- disabled={isPending(downloadUserDocumentResp)}
1014
- >
1015
- {isPending(downloadUserDocumentResp) ? "Downloading…" : "Download file"}
1016
- </button>;
1017
- {
1018
- isError(downloadUserDocumentResp) ? (
1019
- <p className="text-red-500">Failed to download.</p>
1020
- ) : null;
1021
- }
1022
- \`\`\`
1023
-
1024
- <details><summary>Description</summary>
1025
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
1026
- </details>
1027
-
1028
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
1029
-
1030
- \`\`\`tsx
1031
- useEffect(() => {
1032
- downloadUserDocument(downloadUserDocumentParams);
1033
- }, [downloadUserDocument]);
1034
- \`\`\`
1035
-
1036
- <details><summary>Description</summary>
1037
- <p>Good for post-processing routes that immediately start a download.</p>
1038
- </details>
1039
-
1040
- ### 3) Manual handling (preview or custom filename)
1041
-
1042
- \`\`\`tsx
1043
- const [downloadUserDocumentResp, downloadUserDocument] =
1044
- useDownloadUserDocument({ clearOnUnmount: true });
1045
-
1046
- useEffect(() => {
1047
- if (isSuccess(downloadUserDocumentResp)) {
1048
- const ct =
1049
- downloadUserDocumentResp.headers?.["content-type"] ??
1050
- "application/octet-stream";
1051
- const parts = Array.isArray(downloadUserDocumentResp.data)
1052
- ? downloadUserDocumentResp.data
1053
- : [downloadUserDocumentResp.data];
1054
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
1055
- // preview/save with your own UI...
1056
- return () => URL.revokeObjectURL(url);
1057
- }
1058
- }, [downloadUserDocumentResp]);
1059
- \`\`\`
1060
-
1061
- <details><summary>Description</summary>
1062
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
1063
- </details>
1064
-
1065
- ---
1066
-
1067
- ## Behavior notes (what the auto-download variant does)
1068
-
1069
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
1070
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
1071
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
1072
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
1073
-
1074
- ---
1075
-
1076
- ## Gotchas & Tips
1077
-
1078
- - **Expose headers in CORS:** server should send
1079
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
1080
- - **Disable double clicks:** guard with \`isPending(state)\`.
1081
- - **Revoke URLs** when you create them manually in the stateful variant.
1082
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
1083
-
1084
- ---
1085
-
1086
- ## Troubleshooting
1087
-
1088
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
1089
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
1090
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
1091
-
1092
- ---
1093
- "
1094
- `;
1095
-
1096
- exports[`reactDownloadHookDocs > snapshot — request body only (no path params) 1`] = `
1097
- "# Intrig Download Hooks — Quick Guide
1098
-
1099
- ## Copy-paste starter (fast lane)
1100
-
1101
- ### Auto-download (most common)
1102
-
1103
- \`\`\`ts
1104
- import { useDownloadCustomReportDownload } from "@intrig/react/reports/client";
1105
- \`\`\`
1106
-
1107
- \`\`\`ts
1108
- import { isPending, isError } from "@intrig/react";
1109
- \`\`\`
1110
-
1111
- \`\`\`tsx
1112
- const [downloadCustomReportResp, downloadCustomReport] =
1113
- useDownloadCustomReportDownload({ clearOnUnmount: true });
1114
- // e.g., in a click handler:
1115
- downloadCustomReport({});
1116
- \`\`\`
1117
-
1118
- ### Manual/stateful (you handle the blob/UI)
1119
-
1120
- \`\`\`ts
1121
- import { useDownloadCustomReport } from "@intrig/react/reports/client";
1122
- \`\`\`
1123
-
1124
- \`\`\`ts
1125
- import { isSuccess, isPending, isError } from "@intrig/react";
1126
- \`\`\`
1127
-
1128
- \`\`\`tsx
1129
- const [downloadCustomReportResp, downloadCustomReport] =
1130
- useDownloadCustomReport({ clearOnUnmount: true });
1131
- // later:
1132
- downloadCustomReport({});
1133
- \`\`\`
1134
-
1135
- ---
1136
-
1137
- ## TL;DR (auto-download)
1138
-
1139
- \`\`\`tsx
1140
- import { useDownloadCustomReportDownload } from "@intrig/react/reports/client";
1141
- import { isPending, isError } from "@intrig/react";
1142
-
1143
- export default function Example() {
1144
- const [downloadCustomReportResp, downloadCustomReport] =
1145
- useDownloadCustomReportDownload({ clearOnUnmount: true });
1146
-
1147
- return (
1148
- <button
1149
- onClick={() => downloadCustomReport({})}
1150
- disabled={isPending(downloadCustomReportResp)}
1151
- >
1152
- {isPending(downloadCustomReportResp) ? "Downloading…" : "Download"}
1153
- </button>
1154
- );
1155
- }
1156
- \`\`\`
1157
-
1158
- ---
1159
-
1160
- ## Hook APIs
1161
-
1162
- ### \`useDownloadCustomReportDownload\` (auto-download)
1163
-
1164
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
1165
- - **Signature:** \`[state, download, clear]\`
1166
- - \`download(params: Record<string, unknown>) => void\`
1167
-
1168
- ### \`useDownloadCustomReport\` (manual/stateful)
1169
-
1170
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
1171
- - **Signature:** \`[state, fetchFile, clear]\`
1172
- - \`fetchFile(params: Record<string, unknown>) => void\`
1173
-
1174
- ---
1175
-
1176
- ## Usage Patterns
1177
-
1178
- ### 1) Auto-download on click (recommended)
1179
-
1180
- \`\`\`tsx
1181
- const [downloadCustomReportResp, downloadCustomReport] =
1182
- useDownloadCustomReportDownload({ clearOnUnmount: true });
1183
-
1184
- <button
1185
- onClick={() => downloadCustomReport({})}
1186
- disabled={isPending(downloadCustomReportResp)}
1187
- >
1188
- {isPending(downloadCustomReportResp) ? "Downloading…" : "Download file"}
1189
- </button>;
1190
- {
1191
- isError(downloadCustomReportResp) ? (
1192
- <p className="text-red-500">Failed to download.</p>
1193
- ) : null;
1194
- }
1195
- \`\`\`
1196
-
1197
- <details><summary>Description</summary>
1198
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
1199
- </details>
1200
-
1201
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
1202
-
1203
- \`\`\`tsx
1204
- useEffect(() => {
1205
- downloadCustomReport({});
1206
- }, [downloadCustomReport]);
1207
- \`\`\`
1208
-
1209
- <details><summary>Description</summary>
1210
- <p>Good for post-processing routes that immediately start a download.</p>
1211
- </details>
1212
-
1213
- ### 3) Manual handling (preview or custom filename)
1214
-
1215
- \`\`\`tsx
1216
- const [downloadCustomReportResp, downloadCustomReport] =
1217
- useDownloadCustomReport({ clearOnUnmount: true });
1218
-
1219
- useEffect(() => {
1220
- if (isSuccess(downloadCustomReportResp)) {
1221
- const ct =
1222
- downloadCustomReportResp.headers?.["content-type"] ??
1223
- "application/octet-stream";
1224
- const parts = Array.isArray(downloadCustomReportResp.data)
1225
- ? downloadCustomReportResp.data
1226
- : [downloadCustomReportResp.data];
1227
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
1228
- // preview/save with your own UI...
1229
- return () => URL.revokeObjectURL(url);
1230
- }
1231
- }, [downloadCustomReportResp]);
1232
- \`\`\`
1233
-
1234
- <details><summary>Description</summary>
1235
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
1236
- </details>
1237
-
1238
- ---
1239
-
1240
- ## Behavior notes (what the auto-download variant does)
1241
-
1242
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
1243
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
1244
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
1245
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
1246
-
1247
- ---
1248
-
1249
- ## Gotchas & Tips
1250
-
1251
- - **Expose headers in CORS:** server should send
1252
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
1253
- - **Disable double clicks:** guard with \`isPending(state)\`.
1254
- - **Revoke URLs** when you create them manually in the stateful variant.
1255
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
1256
-
1257
- ---
1258
-
1259
- ## Troubleshooting
1260
-
1261
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
1262
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
1263
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
1264
-
1265
- ---
1266
- "
1267
- `;
1268
-
1269
- exports[`reactDownloadHookDocs > snapshot — simple REST descriptor (no body, no path params) 1`] = `
1270
- "# Intrig Download Hooks — Quick Guide
1271
-
1272
- ## Copy-paste starter (fast lane)
1273
-
1274
- ### Auto-download (most common)
1275
-
1276
- \`\`\`ts
1277
- import { useDownloadReportDownload } from "@intrig/react/reports/client";
1278
- \`\`\`
1279
-
1280
- \`\`\`ts
1281
- import { isPending, isError } from "@intrig/react";
1282
- \`\`\`
1283
-
1284
- \`\`\`tsx
1285
- const [downloadReportResp, downloadReport] = useDownloadReportDownload({
1286
- clearOnUnmount: true,
1287
- });
1288
- // e.g., in a click handler:
1289
- downloadReport({});
1290
- \`\`\`
1291
-
1292
- ### Manual/stateful (you handle the blob/UI)
1293
-
1294
- \`\`\`ts
1295
- import { useDownloadReport } from "@intrig/react/reports/client";
1296
- \`\`\`
1297
-
1298
- \`\`\`ts
1299
- import { isSuccess, isPending, isError } from "@intrig/react";
1300
- \`\`\`
1301
-
1302
- \`\`\`tsx
1303
- const [downloadReportResp, downloadReport] = useDownloadReport({
1304
- clearOnUnmount: true,
1305
- });
1306
- // later:
1307
- downloadReport({});
1308
- \`\`\`
1309
-
1310
- ---
1311
-
1312
- ## TL;DR (auto-download)
1313
-
1314
- \`\`\`tsx
1315
- import { useDownloadReportDownload } from "@intrig/react/reports/client";
1316
- import { isPending, isError } from "@intrig/react";
1317
-
1318
- export default function Example() {
1319
- const [downloadReportResp, downloadReport] = useDownloadReportDownload({
1320
- clearOnUnmount: true,
1321
- });
1322
-
1323
- return (
1324
- <button
1325
- onClick={() => downloadReport({})}
1326
- disabled={isPending(downloadReportResp)}
1327
- >
1328
- {isPending(downloadReportResp) ? "Downloading…" : "Download"}
1329
- </button>
1330
- );
1331
- }
1332
- \`\`\`
1333
-
1334
- ---
1335
-
1336
- ## Hook APIs
1337
-
1338
- ### \`useDownloadReportDownload\` (auto-download)
1339
-
1340
- - **What it does:** requests the file with \`responseType: 'blob'\` + \`adapter: 'fetch'\`, derives filename from \`Content-Disposition\` if present, creates a temporary object URL, clicks a hidden \`<a>\`, **downloads**, then resets state to \`init\`.
1341
- - **Signature:** \`[state, download, clear]\`
1342
- - \`download(params: Record<string, unknown>) => void\`
1343
-
1344
- ### \`useDownloadReport\` (manual/stateful)
1345
-
1346
- - **What it does:** same request but **does not** auto-save. You control preview/saving using \`state.data\` + \`state.headers\`.
1347
- - **Signature:** \`[state, fetchFile, clear]\`
1348
- - \`fetchFile(params: Record<string, unknown>) => void\`
1349
-
1350
- ---
1351
-
1352
- ## Usage Patterns
1353
-
1354
- ### 1) Auto-download on click (recommended)
1355
-
1356
- \`\`\`tsx
1357
- const [downloadReportResp, downloadReport] = useDownloadReportDownload({
1358
- clearOnUnmount: true,
1359
- });
1360
-
1361
- <button
1362
- onClick={() => downloadReport({})}
1363
- disabled={isPending(downloadReportResp)}
1364
- >
1365
- {isPending(downloadReportResp) ? "Downloading…" : "Download file"}
1366
- </button>;
1367
- {
1368
- isError(downloadReportResp) ? (
1369
- <p className="text-red-500">Failed to download.</p>
1370
- ) : null;
1371
- }
1372
- \`\`\`
1373
-
1374
- <details><summary>Description</summary>
1375
- <p>Most users just need a button that saves the file. This variant handles object URL creation, filename extraction, click, and state reset.</p>
1376
- </details>
1377
-
1378
- ### 2) Auto-download on mount (e.g., “Your file is ready” page)
1379
-
1380
- \`\`\`tsx
1381
- useEffect(() => {
1382
- downloadReport({});
1383
- }, [downloadReport]);
1384
- \`\`\`
1385
-
1386
- <details><summary>Description</summary>
1387
- <p>Good for post-processing routes that immediately start a download.</p>
1388
- </details>
1389
-
1390
- ### 3) Manual handling (preview or custom filename)
1391
-
1392
- \`\`\`tsx
1393
- const [downloadReportResp, downloadReport] = useDownloadReport({
1394
- clearOnUnmount: true,
1395
- });
1396
-
1397
- useEffect(() => {
1398
- if (isSuccess(downloadReportResp)) {
1399
- const ct =
1400
- downloadReportResp.headers?.["content-type"] ??
1401
- "application/octet-stream";
1402
- const parts = Array.isArray(downloadReportResp.data)
1403
- ? downloadReportResp.data
1404
- : [downloadReportResp.data];
1405
- const url = URL.createObjectURL(new Blob(parts, { type: ct }));
1406
- // preview/save with your own UI...
1407
- return () => URL.revokeObjectURL(url);
1408
- }
1409
- }, [downloadReportResp]);
1410
- \`\`\`
1411
-
1412
- <details><summary>Description</summary>
1413
- <p>Use when you need to inspect headers, show a preview, or control the filename/UI flow.</p>
1414
- </details>
1415
-
1416
- ---
1417
-
1418
- ## Behavior notes (what the auto-download variant does)
1419
-
1420
- - Forces \`responseType: 'blob'\` and \`adapter: 'fetch'\`.
1421
- - If \`content-type\` is JSON, stringifies payload so the saved file is human-readable.
1422
- - Parses \`Content-Disposition\` to derive a filename; falls back to a default.
1423
- - Creates and clicks a temporary link, then **resets state to \`init\`**.
1424
-
1425
- ---
1426
-
1427
- ## Gotchas & Tips
1428
-
1429
- - **Expose headers in CORS:** server should send
1430
- \`Access-Control-Expose-Headers: Content-Disposition, Content-Type\`
1431
- - **Disable double clicks:** guard with \`isPending(state)\`.
1432
- - **Revoke URLs** when you create them manually in the stateful variant.
1433
- - **iOS Safari:** blob downloads may open a new tab—consider server-side direct-download URLs for a smoother UX.
1434
-
1435
- ---
1436
-
1437
- ## Troubleshooting
1438
-
1439
- - **No filename shown:** your server didn’t include \`Content-Disposition\`. Add it.
1440
- - **Got JSON instead of a file:** server returned \`application/json\` (maybe an error). The auto hook saves it as text; surface the error in UI.
1441
- - **Nothing happens on click:** ensure you’re using the **Download** variant and the request succeeds (check Network tab); verify CORS headers.
1442
-
1443
- ---
1444
- "
1445
- `;