remix 3.0.0-beta.1 → 3.0.0-beta.3

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 (87) hide show
  1. package/dist/headers/accept-encoding.d.ts +2 -0
  2. package/dist/headers/accept-encoding.d.ts.map +1 -0
  3. package/dist/headers/accept-encoding.js +2 -0
  4. package/dist/headers/accept-language.d.ts +2 -0
  5. package/dist/headers/accept-language.d.ts.map +1 -0
  6. package/dist/headers/accept-language.js +2 -0
  7. package/dist/headers/accept.d.ts +2 -0
  8. package/dist/headers/accept.d.ts.map +1 -0
  9. package/dist/headers/accept.js +2 -0
  10. package/dist/headers/cache-control.d.ts +2 -0
  11. package/dist/headers/cache-control.d.ts.map +1 -0
  12. package/dist/headers/cache-control.js +2 -0
  13. package/dist/headers/content-disposition.d.ts +2 -0
  14. package/dist/headers/content-disposition.d.ts.map +1 -0
  15. package/dist/headers/content-disposition.js +2 -0
  16. package/dist/headers/content-range.d.ts +2 -0
  17. package/dist/headers/content-range.d.ts.map +1 -0
  18. package/dist/headers/content-range.js +2 -0
  19. package/dist/headers/content-type.d.ts +2 -0
  20. package/dist/headers/content-type.d.ts.map +1 -0
  21. package/dist/headers/content-type.js +2 -0
  22. package/dist/headers/cookie.d.ts +2 -0
  23. package/dist/headers/cookie.d.ts.map +1 -0
  24. package/dist/headers/cookie.js +2 -0
  25. package/dist/headers/if-match.d.ts +2 -0
  26. package/dist/headers/if-match.d.ts.map +1 -0
  27. package/dist/headers/if-match.js +2 -0
  28. package/dist/headers/if-none-match.d.ts +2 -0
  29. package/dist/headers/if-none-match.d.ts.map +1 -0
  30. package/dist/headers/if-none-match.js +2 -0
  31. package/dist/headers/if-range.d.ts +2 -0
  32. package/dist/headers/if-range.d.ts.map +1 -0
  33. package/dist/headers/if-range.js +2 -0
  34. package/dist/headers/range.d.ts +2 -0
  35. package/dist/headers/range.d.ts.map +1 -0
  36. package/dist/headers/range.js +2 -0
  37. package/dist/headers/raw-headers.d.ts +2 -0
  38. package/dist/headers/raw-headers.d.ts.map +1 -0
  39. package/dist/headers/raw-headers.js +2 -0
  40. package/dist/headers/set-cookie.d.ts +2 -0
  41. package/dist/headers/set-cookie.d.ts.map +1 -0
  42. package/dist/headers/set-cookie.js +2 -0
  43. package/dist/headers/vary.d.ts +2 -0
  44. package/dist/headers/vary.d.ts.map +1 -0
  45. package/{src/node-serve.ts → dist/headers/vary.js} +1 -1
  46. package/package.json +102 -47
  47. package/src/csrf-middleware/README.md +5 -12
  48. package/src/data-schema/README.md +3 -9
  49. package/src/data-table/README.md +6 -14
  50. package/src/data-table-mysql/README.md +5 -11
  51. package/src/data-table-postgres/README.md +2 -4
  52. package/src/data-table-sqlite/README.md +2 -4
  53. package/src/fetch-proxy/README.md +1 -2
  54. package/src/file-storage/README.md +10 -4
  55. package/src/file-storage-s3/README.md +2 -3
  56. package/src/form-data-middleware/README.md +1 -2
  57. package/src/form-data-parser/README.md +7 -12
  58. package/src/headers/README.md +33 -1
  59. package/src/headers/accept-encoding.ts +2 -0
  60. package/src/headers/accept-language.ts +2 -0
  61. package/src/headers/accept.ts +2 -0
  62. package/src/headers/cache-control.ts +2 -0
  63. package/src/headers/content-disposition.ts +2 -0
  64. package/src/headers/content-range.ts +2 -0
  65. package/src/headers/content-type.ts +2 -0
  66. package/src/headers/cookie.ts +2 -0
  67. package/src/headers/if-match.ts +2 -0
  68. package/src/headers/if-none-match.ts +2 -0
  69. package/src/headers/if-range.ts +2 -0
  70. package/src/headers/range.ts +2 -0
  71. package/src/headers/raw-headers.ts +2 -0
  72. package/src/headers/set-cookie.ts +2 -0
  73. package/{dist/node-serve.js → src/headers/vary.ts} +1 -1
  74. package/src/node-fetch-server/README.md +1 -6
  75. package/src/node-tsx/README.md +3 -8
  76. package/src/route-pattern/README.md +18 -13
  77. package/src/session-storage-redis/README.md +1 -2
  78. package/src/test/README.md +2 -5
  79. package/src/ui/README.md +9 -7
  80. package/src/ui/anchor/README.md +11 -3
  81. package/src/ui/animation/README.md +7 -5
  82. package/src/ui/combobox/README.md +1 -1
  83. package/src/ui/menu/README.md +26 -2
  84. package/src/ui/server/README.md +4 -2
  85. package/dist/node-serve.d.ts +0 -2
  86. package/dist/node-serve.d.ts.map +0 -1
  87. package/src/node-serve/README.md +0 -253
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/accept-encoding';
2
+ //# sourceMappingURL=accept-encoding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept-encoding.d.ts","sourceRoot":"","sources":["../../src/headers/accept-encoding.ts"],"names":[],"mappings":"AACA,cAAc,oCAAoC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/accept-encoding';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/accept-language';
2
+ //# sourceMappingURL=accept-language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept-language.d.ts","sourceRoot":"","sources":["../../src/headers/accept-language.ts"],"names":[],"mappings":"AACA,cAAc,oCAAoC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/accept-language';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/accept';
2
+ //# sourceMappingURL=accept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept.d.ts","sourceRoot":"","sources":["../../src/headers/accept.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/accept';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/cache-control';
2
+ //# sourceMappingURL=cache-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-control.d.ts","sourceRoot":"","sources":["../../src/headers/cache-control.ts"],"names":[],"mappings":"AACA,cAAc,kCAAkC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/cache-control';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/content-disposition';
2
+ //# sourceMappingURL=content-disposition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-disposition.d.ts","sourceRoot":"","sources":["../../src/headers/content-disposition.ts"],"names":[],"mappings":"AACA,cAAc,wCAAwC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/content-disposition';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/content-range';
2
+ //# sourceMappingURL=content-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-range.d.ts","sourceRoot":"","sources":["../../src/headers/content-range.ts"],"names":[],"mappings":"AACA,cAAc,kCAAkC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/content-range';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/content-type';
2
+ //# sourceMappingURL=content-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-type.d.ts","sourceRoot":"","sources":["../../src/headers/content-type.ts"],"names":[],"mappings":"AACA,cAAc,iCAAiC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/content-type';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/cookie';
2
+ //# sourceMappingURL=cookie.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie.d.ts","sourceRoot":"","sources":["../../src/headers/cookie.ts"],"names":[],"mappings":"AACA,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/cookie';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/if-match';
2
+ //# sourceMappingURL=if-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"if-match.d.ts","sourceRoot":"","sources":["../../src/headers/if-match.ts"],"names":[],"mappings":"AACA,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/if-match';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/if-none-match';
2
+ //# sourceMappingURL=if-none-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"if-none-match.d.ts","sourceRoot":"","sources":["../../src/headers/if-none-match.ts"],"names":[],"mappings":"AACA,cAAc,kCAAkC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/if-none-match';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/if-range';
2
+ //# sourceMappingURL=if-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"if-range.d.ts","sourceRoot":"","sources":["../../src/headers/if-range.ts"],"names":[],"mappings":"AACA,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/if-range';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/range';
2
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/headers/range.ts"],"names":[],"mappings":"AACA,cAAc,0BAA0B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/range';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/raw-headers';
2
+ //# sourceMappingURL=raw-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raw-headers.d.ts","sourceRoot":"","sources":["../../src/headers/raw-headers.ts"],"names":[],"mappings":"AACA,cAAc,gCAAgC,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/raw-headers';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/set-cookie';
2
+ //# sourceMappingURL=set-cookie.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-cookie.d.ts","sourceRoot":"","sources":["../../src/headers/set-cookie.ts"],"names":[],"mappings":"AACA,cAAc,+BAA+B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/headers/set-cookie';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/headers/vary';
2
+ //# sourceMappingURL=vary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vary.d.ts","sourceRoot":"","sources":["../../src/headers/vary.ts"],"names":[],"mappings":"AACA,cAAc,yBAAyB,CAAA"}
@@ -1,2 +1,2 @@
1
1
  // IMPORTANT: This file is auto-generated, please do not edit manually.
2
- export * from '@remix-run/node-serve'
2
+ export * from '@remix-run/headers/vary';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remix",
3
- "version": "3.0.0-beta.1",
3
+ "version": "3.0.0-beta.3",
4
4
  "description": "The Remix web framework",
5
5
  "author": "Michael Jackson <mjijackson@gmail.com>",
6
6
  "license": "MIT",
@@ -177,6 +177,66 @@
177
177
  "types": "./dist/headers.d.ts",
178
178
  "default": "./dist/headers.js"
179
179
  },
180
+ "./headers/accept": {
181
+ "types": "./dist/headers/accept.d.ts",
182
+ "default": "./dist/headers/accept.js"
183
+ },
184
+ "./headers/accept-encoding": {
185
+ "types": "./dist/headers/accept-encoding.d.ts",
186
+ "default": "./dist/headers/accept-encoding.js"
187
+ },
188
+ "./headers/accept-language": {
189
+ "types": "./dist/headers/accept-language.d.ts",
190
+ "default": "./dist/headers/accept-language.js"
191
+ },
192
+ "./headers/cache-control": {
193
+ "types": "./dist/headers/cache-control.d.ts",
194
+ "default": "./dist/headers/cache-control.js"
195
+ },
196
+ "./headers/content-disposition": {
197
+ "types": "./dist/headers/content-disposition.d.ts",
198
+ "default": "./dist/headers/content-disposition.js"
199
+ },
200
+ "./headers/content-range": {
201
+ "types": "./dist/headers/content-range.d.ts",
202
+ "default": "./dist/headers/content-range.js"
203
+ },
204
+ "./headers/content-type": {
205
+ "types": "./dist/headers/content-type.d.ts",
206
+ "default": "./dist/headers/content-type.js"
207
+ },
208
+ "./headers/cookie": {
209
+ "types": "./dist/headers/cookie.d.ts",
210
+ "default": "./dist/headers/cookie.js"
211
+ },
212
+ "./headers/if-match": {
213
+ "types": "./dist/headers/if-match.d.ts",
214
+ "default": "./dist/headers/if-match.js"
215
+ },
216
+ "./headers/if-none-match": {
217
+ "types": "./dist/headers/if-none-match.d.ts",
218
+ "default": "./dist/headers/if-none-match.js"
219
+ },
220
+ "./headers/if-range": {
221
+ "types": "./dist/headers/if-range.d.ts",
222
+ "default": "./dist/headers/if-range.js"
223
+ },
224
+ "./headers/range": {
225
+ "types": "./dist/headers/range.d.ts",
226
+ "default": "./dist/headers/range.js"
227
+ },
228
+ "./headers/raw-headers": {
229
+ "types": "./dist/headers/raw-headers.d.ts",
230
+ "default": "./dist/headers/raw-headers.js"
231
+ },
232
+ "./headers/set-cookie": {
233
+ "types": "./dist/headers/set-cookie.d.ts",
234
+ "default": "./dist/headers/set-cookie.js"
235
+ },
236
+ "./headers/vary": {
237
+ "types": "./dist/headers/vary.d.ts",
238
+ "default": "./dist/headers/vary.js"
239
+ },
180
240
  "./html-template": {
181
241
  "types": "./dist/html-template.d.ts",
182
242
  "default": "./dist/html-template.js"
@@ -261,10 +321,6 @@
261
321
  "types": "./dist/node-fetch-server/test.d.ts",
262
322
  "default": "./dist/node-fetch-server/test.js"
263
323
  },
264
- "./node-serve": {
265
- "types": "./dist/node-serve.d.ts",
266
- "default": "./dist/node-serve.js"
267
- },
268
324
  "./node-tsx": {
269
325
  "types": "./dist/node-tsx.d.ts",
270
326
  "default": "./dist/node-tsx.js"
@@ -473,51 +529,50 @@
473
529
  "typescript": "^5.9.3"
474
530
  },
475
531
  "dependencies": {
476
- "@remix-run/async-context-middleware": "^0.3.0",
477
- "@remix-run/assets": "^0.4.0",
478
- "@remix-run/auth-middleware": "^0.2.0",
479
- "@remix-run/auth": "^0.2.2",
480
- "@remix-run/ui": "^0.1.2",
481
- "@remix-run/compression-middleware": "^0.1.8",
482
- "@remix-run/cors-middleware": "^0.1.3",
483
- "@remix-run/cop-middleware": "^0.1.3",
484
- "@remix-run/cookie": "^0.5.2",
532
+ "@remix-run/assets": "^0.4.2",
533
+ "@remix-run/auth": "^0.2.4",
534
+ "@remix-run/compression-middleware": "^0.1.10",
535
+ "@remix-run/cop-middleware": "^0.1.5",
536
+ "@remix-run/csrf-middleware": "^0.1.5",
537
+ "@remix-run/cors-middleware": "^0.1.5",
538
+ "@remix-run/ui": "^0.3.0",
539
+ "@remix-run/async-context-middleware": "^0.3.2",
540
+ "@remix-run/auth-middleware": "^0.2.2",
541
+ "@remix-run/cookie": "^0.5.4",
485
542
  "@remix-run/data-schema": "^0.3.0",
486
- "@remix-run/csrf-middleware": "^0.1.3",
487
- "@remix-run/data-table": "^0.3.0",
488
- "@remix-run/data-table-mysql": "^0.4.0",
489
543
  "@remix-run/data-table-postgres": "^0.4.0",
490
- "@remix-run/data-table-sqlite": "^0.5.0",
491
- "@remix-run/fetch-proxy": "^0.8.1",
492
- "@remix-run/file-storage": "^0.13.4",
493
- "@remix-run/file-storage-s3": "^0.1.1",
494
- "@remix-run/fetch-router": "^0.19.0",
495
- "@remix-run/form-data-parser": "^0.17.1",
496
- "@remix-run/fs": "^0.4.3",
497
- "@remix-run/form-data-middleware": "^0.3.0",
498
- "@remix-run/headers": "^0.20.0",
499
- "@remix-run/html-template": "^0.3.0",
500
- "@remix-run/lazy-file": "^5.0.3",
544
+ "@remix-run/data-table-sqlite": "^0.5.1",
545
+ "@remix-run/data-table-mysql": "^0.4.0",
546
+ "@remix-run/data-table": "^0.3.0",
547
+ "@remix-run/fetch-router": "^0.19.2",
548
+ "@remix-run/file-storage": "^0.13.6",
549
+ "@remix-run/fetch-proxy": "^0.8.3",
550
+ "@remix-run/file-storage-s3": "^0.1.3",
551
+ "@remix-run/form-data-middleware": "^0.3.2",
552
+ "@remix-run/form-data-parser": "^0.17.3",
553
+ "@remix-run/fs": "^0.4.5",
554
+ "@remix-run/headers": "^0.21.1",
555
+ "@remix-run/lazy-file": "^5.0.5",
556
+ "@remix-run/html-template": "^0.3.1",
557
+ "@remix-run/logger-middleware": "^0.3.2",
558
+ "@remix-run/method-override-middleware": "^0.1.10",
559
+ "@remix-run/multipart-parser": "^0.16.3",
501
560
  "@remix-run/mime": "^0.4.1",
502
- "@remix-run/multipart-parser": "^0.16.1",
503
- "@remix-run/method-override-middleware": "^0.1.8",
504
- "@remix-run/logger-middleware": "^0.3.0",
505
- "@remix-run/node-fetch-server": "^0.13.2",
506
- "@remix-run/node-tsx": "^0.1.0",
507
- "@remix-run/response": "^0.3.4",
508
- "@remix-run/session": "^0.4.1",
509
- "@remix-run/session-middleware": "^0.3.0",
510
- "@remix-run/route-pattern": "^0.21.0",
511
- "@remix-run/session-storage-redis": "^0.1.0",
512
- "@remix-run/static-middleware": "^0.4.9",
513
- "@remix-run/session-storage-memcache": "^0.1.0",
514
- "@remix-run/cli": "^0.3.0",
515
- "@remix-run/assert": "^0.2.0",
516
- "@remix-run/test": "^0.4.0",
561
+ "@remix-run/node-fetch-server": "^0.13.3",
562
+ "@remix-run/response": "^0.3.6",
563
+ "@remix-run/node-tsx": "^0.1.1",
564
+ "@remix-run/route-pattern": "^0.22.0",
565
+ "@remix-run/session": "^0.4.2",
566
+ "@remix-run/session-middleware": "^0.3.2",
567
+ "@remix-run/session-storage-memcache": "^0.1.2",
568
+ "@remix-run/static-middleware": "^0.4.11",
569
+ "@remix-run/session-storage-redis": "^0.1.1",
517
570
  "@remix-run/tar-parser": "^0.7.1",
518
- "@remix-run/terminal": "^0.1.0",
519
- "@remix-run/render-middleware": "^0.1.0",
520
- "@remix-run/node-serve": "^0.2.0"
571
+ "@remix-run/cli": "^0.3.2",
572
+ "@remix-run/assert": "^0.2.1",
573
+ "@remix-run/terminal": "^0.1.1",
574
+ "@remix-run/test": "^0.4.2",
575
+ "@remix-run/render-middleware": "^0.1.2"
521
576
  },
522
577
  "bin": {
523
578
  "remix": "./dist/cli-entry.js"
@@ -526,7 +581,7 @@
526
581
  "mysql2": "^3.15.3",
527
582
  "pg": "^8.16.3",
528
583
  "redis": "^5.10.0",
529
- "playwright": "^1.59.0"
584
+ "playwright": "^1.60.0"
530
585
  },
531
586
  "peerDependenciesMeta": {
532
587
  "mysql2": {
@@ -74,18 +74,11 @@ For unsafe methods (`POST`, `PUT`, `PATCH`, `DELETE`), the middleware validates
74
74
 
75
75
  ## Why This Exists
76
76
 
77
- Modern browsers now provide stronger cross-origin signals like `Sec-Fetch-Site`, and explicit
78
- `SameSite=Lax` cookies already block many CSRF attacks. We have considered the lighter,
79
- tokenless model used by Go's `CrossOriginProtection`, and we think it is a good fit when a
80
- deployment can make all of the guarantees that model depends on.
81
-
82
- Remix cannot assume those guarantees for every app. `csrf()` still exists as the conservative
83
- option for apps that want synchronizer tokens in addition to origin checks, especially for
84
- session-backed HTML form workflows and mixed deployment environments.
85
-
86
- If your deployment can guarantee the prerequisites for the tokenless model, this middleware is
87
- optional. In that case, [`cop-middleware`](https://github.com/remix-run/remix/tree/main/packages/cop-middleware)
88
- may be a better fit.
77
+ Modern browsers now provide stronger cross-origin signals like `Sec-Fetch-Site`, and explicit `SameSite=Lax` cookies already block many CSRF attacks. We have considered the lighter, tokenless model used by Go's `CrossOriginProtection`, and we think it is a good fit when a deployment can make all of the guarantees that model depends on.
78
+
79
+ Remix cannot assume those guarantees for every app. `csrf()` still exists as the conservative option for apps that want synchronizer tokens in addition to origin checks, especially for session-backed HTML form workflows and mixed deployment environments.
80
+
81
+ If your deployment can guarantee the prerequisites for the tokenless model, this middleware is optional. In that case, [`cop-middleware`](https://github.com/remix-run/remix/tree/main/packages/cop-middleware) may be a better fit.
89
82
 
90
83
  ## Related Packages
91
84
 
@@ -71,8 +71,7 @@ if (!result.success) {
71
71
 
72
72
  Both `parse` and `parseSafe` accept any [Standard Schema](https://standardschema.dev/) v1 schema, not just data-schema's own schemas. You can pass a Zod, Valibot, or ArkType schema and they'll work.
73
73
 
74
- For `FormData` and `URLSearchParams`, use the `remix/data-schema/form-data` helpers to build
75
- schemas that plug into the same `parse()` / `parseSafe()` flow:
74
+ For `FormData` and `URLSearchParams`, use the `remix/data-schema/form-data` helpers to build schemas that plug into the same `parse()` / `parseSafe()` flow:
76
75
 
77
76
  ```ts
78
77
  import * as s from 'remix/data-schema'
@@ -95,11 +94,7 @@ let filters = s.parse(
95
94
  )
96
95
  ```
97
96
 
98
- `f.object(...)` is the root schema for `FormData` and `URLSearchParams`.
99
- Use `f.field(...)` for one text value, `f.fields(...)` for repeated text values,
100
- `f.file(...)` for one uploaded file, and `f.files(...)` for repeated files.
101
- When you want a fallback value, prefer `s.defaulted(s.string(), '')`.
102
- File helpers are intended for `FormData`; `URLSearchParams` only supports text values.
97
+ `f.object(...)` is the root schema for `FormData` and `URLSearchParams`. Use `f.field(...)` for one text value, `f.fields(...)` for repeated text values, `f.file(...)` for one uploaded file, and `f.files(...)` for repeated files. When you want a fallback value, prefer `s.defaulted(s.string(), '')`. File helpers are intended for `FormData`; `URLSearchParams` only supports text values.
103
98
 
104
99
  You can also customize built-in validation messages with `errorMap`:
105
100
 
@@ -127,8 +122,7 @@ let result = parseSafe(User, input, {
127
122
  })
128
123
  ```
129
124
 
130
- `errorMap` receives `{ code, defaultMessage, path, values, input, locale }`.
131
- Return `undefined` to keep the default message.
125
+ `errorMap` receives `{ code, defaultMessage, path, values, input, locale }`. Return `undefined` to keep the default message.
132
126
 
133
127
  ## Primitives
134
128
 
@@ -249,8 +249,7 @@ Return behavior:
249
249
 
250
250
  ### Validation and Lifecycle
251
251
 
252
- Validation is optional and table-scoped. Define `validate(context)` to validate/coerce write
253
- payloads, and add lifecycle callbacks when you need custom read/write/delete behavior.
252
+ Validation is optional and table-scoped. Define `validate(context)` to validate/coerce write payloads, and add lifecycle callbacks when you need custom read/write/delete behavior.
254
253
 
255
254
  ```ts
256
255
  import { column as c, fail, table } from 'remix/data-table'
@@ -344,10 +343,7 @@ await db.transaction(async (tx) => {
344
343
 
345
344
  ## Migrations
346
345
 
347
- `data-table` ships a SQL-first migration system under `remix/data-table/migrations`. Each migration
348
- is a directory containing hand-written `up.sql` and (optionally) `down.sql`. The runner journals
349
- applied migrations, detects checksum drift, and wraps each migration in a transaction when the
350
- adapter supports transactional DDL.
346
+ `data-table` ships a SQL-first migration system under `remix/data-table/migrations`. Each migration is a directory containing hand-written `up.sql` and (optionally) `down.sql`. The runner journals applied migrations, detects checksum drift, and wraps each migration in a transaction when the adapter supports transactional DDL.
351
347
 
352
348
  ### Example Setup
353
349
 
@@ -392,8 +388,7 @@ drop table if exists users;
392
388
 
393
389
  ### Multi-Statement Driver Configuration
394
390
 
395
- The runner sends each migration to the adapter as a single multi-statement script. Make sure the
396
- underlying driver accepts multiple statements:
391
+ The runner sends each migration to the adapter as a single multi-statement script. Make sure the underlying driver accepts multiple statements:
397
392
 
398
393
  - `better-sqlite3`: works out of the box (`db.exec`).
399
394
  - `pg`: works out of the box when no parameter array is passed.
@@ -476,8 +471,7 @@ for (let script of plan.sql) {
476
471
 
477
472
  ### Transaction Modes
478
473
 
479
- By default each migration is wrapped in a transaction when the adapter supports transactional DDL.
480
- Override per migration with a directive on the first non-blank line of `up.sql`:
474
+ By default each migration is wrapped in a transaction when the adapter supports transactional DDL. Override per migration with a directive on the first non-blank line of `up.sql`:
481
475
 
482
476
  ```sql
483
477
  -- data-table/transaction: none
@@ -488,11 +482,9 @@ Supported modes:
488
482
 
489
483
  - `auto` (default): wrap when the adapter supports transactional DDL.
490
484
  - `required`: wrap; the runner throws if the adapter cannot support it.
491
- - `none`: never wrap. Use this for statements like postgres `CREATE INDEX CONCURRENTLY` that
492
- cannot run inside a transaction.
485
+ - `none`: never wrap. Use this for statements like postgres `CREATE INDEX CONCURRENTLY` that cannot run inside a transaction.
493
486
 
494
- You can also set `transaction` directly on a `MigrationDescriptor` when registering migrations
495
- programmatically.
487
+ You can also set `transaction` directly on a `MigrationDescriptor` when registering migrations programmatically.
496
488
 
497
489
  ### Programmatic Registration
498
490
 
@@ -1,7 +1,6 @@
1
1
  # data-table-mysql
2
2
 
3
- MySQL adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table).
4
- Use this package when you want `data-table` APIs backed by `mysql2`.
3
+ MySQL adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table). Use this package when you want `data-table` APIs backed by `mysql2`.
5
4
 
6
5
  ## Features
7
6
 
@@ -33,8 +32,7 @@ let pool = createPool(process.env.DATABASE_URL as string)
33
32
  let db = createDatabase(createMysqlDatabaseAdapter(pool))
34
33
  ```
35
34
 
36
- Use `db.query(...)`, relation loading, and transactions from `remix/data-table`.
37
- Import any driver-specific types you need directly from `mysql2/promise`.
35
+ Use `db.query(...)`, relation loading, and transactions from `remix/data-table`. Import any driver-specific types you need directly from `mysql2/promise`.
38
36
 
39
37
  ## Adapter Capabilities
40
38
 
@@ -50,9 +48,7 @@ Import any driver-specific types you need directly from `mysql2/promise`.
50
48
 
51
49
  ### Multi-Statement Migrations
52
50
 
53
- `remix/data-table/migrations` sends each migration to the adapter as a single multi-statement SQL
54
- script. mysql2 only accepts multi-statement scripts when the connection is created with
55
- `multipleStatements: true`:
51
+ `remix/data-table/migrations` sends each migration to the adapter as a single multi-statement SQL script. mysql2 only accepts multi-statement scripts when the connection is created with `multipleStatements: true`:
56
52
 
57
53
  ```ts
58
54
  import { createPool } from 'mysql2/promise'
@@ -65,11 +61,9 @@ let pool = createPool({
65
61
 
66
62
  ### `returning` On MySQL
67
63
 
68
- MySQL does not natively support SQL `RETURNING`. In this adapter, using `returning` on write
69
- operations throws `DataTableQueryError`.
64
+ MySQL does not natively support SQL `RETURNING`. In this adapter, using `returning` on write operations throws `DataTableQueryError`.
70
65
 
71
- Use write metadata (`affectedRows`, `insertId`) on MySQL, or switch adapters when returned rows
72
- are required.
66
+ Use write metadata (`affectedRows`, `insertId`) on MySQL, or switch adapters when returned rows are required.
73
67
 
74
68
  ```ts
75
69
  import { DataTableQueryError } from 'remix/data-table'
@@ -1,7 +1,6 @@
1
1
  # data-table-postgres
2
2
 
3
- PostgreSQL adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table).
4
- Use this package when you want `data-table` APIs backed by `pg`.
3
+ PostgreSQL adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table). Use this package when you want `data-table` APIs backed by `pg`.
5
4
 
6
5
  ## Features
7
6
 
@@ -36,8 +35,7 @@ let pool = new Pool({
36
35
  let db = createDatabase(createPostgresDatabaseAdapter(pool))
37
36
  ```
38
37
 
39
- Use `db.query(...)`, relation loading, and transactions from `remix/data-table`.
40
- Import any driver-specific types you need directly from `pg`.
38
+ Use `db.query(...)`, relation loading, and transactions from `remix/data-table`. Import any driver-specific types you need directly from `pg`.
41
39
 
42
40
  ## Adapter Capabilities
43
41
 
@@ -1,7 +1,6 @@
1
1
  # data-table-sqlite
2
2
 
3
- SQLite adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table).
4
- Use this package when you want `data-table` APIs backed by a synchronous SQLite client.
3
+ SQLite adapter for [`remix/data-table`](https://github.com/remix-run/remix/tree/main/packages/data-table). Use this package when you want `data-table` APIs backed by a synchronous SQLite client.
5
4
 
6
5
  ## Features
7
6
 
@@ -46,8 +45,7 @@ let sqlite = new Database('app.db')
46
45
  let db = createDatabase(createSqliteDatabaseAdapter(sqlite))
47
46
  ```
48
47
 
49
- This is a good fit for local development, embedded deployments, and single-node services.
50
- Import any driver-specific types you need directly from your runtime's SQLite module.
48
+ This is a good fit for local development, embedded deployments, and single-node services. Import any driver-specific types you need directly from your runtime's SQLite module.
51
49
 
52
50
  ## Adapter Capabilities
53
51
 
@@ -1,7 +1,6 @@
1
1
  # fetch-proxy
2
2
 
3
- HTTP proxy utilities built on the web [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
4
- Use `fetch-proxy` to create `fetch` handlers that forward requests to target servers while optionally rewriting headers and cookies.
3
+ HTTP proxy utilities built on the web [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). Use `fetch-proxy` to create `fetch` handlers that forward requests to target servers while optionally rewriting headers and cookies.
5
4
 
6
5
  ## Features
7
6
 
@@ -7,7 +7,7 @@ Key/value storage interfaces for server-side [`File` objects](https://developer.
7
7
  - **Simple API** - Intuitive key/value API (like [Web Storage](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API), but for `File`s instead of strings)
8
8
  - **Multiple Backends** - Built-in filesystem and memory backends
9
9
  - **Streaming Support** - Stream file content to and from storage
10
- - **Metadata Preservation** - Preserves all `File` metadata including `file.name`, `file.type`, and `file.lastModified`
10
+ - **Metadata Preservation** - Preserves all `File` metadata including `file.name`, `file.type`, `file.size`, and `file.lastModified`
11
11
 
12
12
  ## Installation
13
13
 
@@ -32,9 +32,15 @@ await storage.set(key, file)
32
32
 
33
33
  // Then, sometime later...
34
34
  let fileFromStorage = await storage.get(key)
35
- // All of the original file's metadata is intact
36
- fileFromStorage.name // 'hello.txt'
37
- fileFromStorage.type // 'text/plain'
35
+
36
+ if (fileFromStorage != null) {
37
+ // All of the original file's metadata is intact
38
+ fileFromStorage.name // 'hello.txt'
39
+ fileFromStorage.type // 'text/plain'
40
+
41
+ // The filesystem backend returns a LazyFile, so you can stream it directly.
42
+ let response = new Response(fileFromStorage.stream())
43
+ }
38
44
 
39
45
  // To remove from storage
40
46
  await storage.remove(key)