remix 3.0.0-beta.2 → 3.0.0-beta.4

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 (81) 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/dist/headers/vary.js +2 -0
  46. package/package.json +96 -35
  47. package/src/assert/README.md +11 -4
  48. package/src/csrf-middleware/README.md +5 -12
  49. package/src/data-schema/README.md +3 -9
  50. package/src/data-table/README.md +6 -14
  51. package/src/data-table-mysql/README.md +5 -11
  52. package/src/data-table-postgres/README.md +2 -4
  53. package/src/data-table-sqlite/README.md +2 -4
  54. package/src/fetch-proxy/README.md +1 -2
  55. package/src/fetch-router/README.md +115 -35
  56. package/src/file-storage-s3/README.md +1 -2
  57. package/src/form-data-middleware/README.md +1 -2
  58. package/src/form-data-parser/README.md +2 -4
  59. package/src/headers/README.md +10 -0
  60. package/src/headers/accept-encoding.ts +2 -0
  61. package/src/headers/accept-language.ts +2 -0
  62. package/src/headers/accept.ts +2 -0
  63. package/src/headers/cache-control.ts +2 -0
  64. package/src/headers/content-disposition.ts +2 -0
  65. package/src/headers/content-range.ts +2 -0
  66. package/src/headers/content-type.ts +2 -0
  67. package/src/headers/cookie.ts +2 -0
  68. package/src/headers/if-match.ts +2 -0
  69. package/src/headers/if-none-match.ts +2 -0
  70. package/src/headers/if-range.ts +2 -0
  71. package/src/headers/range.ts +2 -0
  72. package/src/headers/raw-headers.ts +2 -0
  73. package/src/headers/set-cookie.ts +2 -0
  74. package/src/headers/vary.ts +2 -0
  75. package/src/node-fetch-server/README.md +1 -2
  76. package/src/node-tsx/README.md +3 -8
  77. package/src/route-pattern/README.md +18 -13
  78. package/src/session-storage-redis/README.md +1 -2
  79. package/src/test/README.md +29 -5
  80. package/src/ui/anchor/README.md +11 -3
  81. package/src/ui/menu/README.md +26 -2
@@ -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"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
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.2",
3
+ "version": "3.0.0-beta.4",
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"
@@ -469,50 +529,50 @@
469
529
  "typescript": "^5.9.3"
470
530
  },
471
531
  "dependencies": {
472
- "@remix-run/assets": "^0.4.1",
473
- "@remix-run/async-context-middleware": "^0.3.1",
474
- "@remix-run/auth": "^0.2.3",
475
- "@remix-run/ui": "^0.2.0",
476
- "@remix-run/cop-middleware": "^0.1.4",
477
- "@remix-run/compression-middleware": "^0.1.9",
478
- "@remix-run/cookie": "^0.5.3",
479
- "@remix-run/auth-middleware": "^0.2.1",
480
- "@remix-run/cors-middleware": "^0.1.4",
481
- "@remix-run/csrf-middleware": "^0.1.4",
532
+ "@remix-run/assets": "^0.4.3",
533
+ "@remix-run/auth": "^0.2.5",
534
+ "@remix-run/async-context-middleware": "^0.3.3",
535
+ "@remix-run/ui": "^0.3.0",
536
+ "@remix-run/compression-middleware": "^0.1.11",
537
+ "@remix-run/auth-middleware": "^0.2.3",
538
+ "@remix-run/cop-middleware": "^0.1.6",
539
+ "@remix-run/csrf-middleware": "^0.1.6",
540
+ "@remix-run/cors-middleware": "^0.1.6",
482
541
  "@remix-run/data-schema": "^0.3.0",
483
542
  "@remix-run/data-table": "^0.3.0",
484
- "@remix-run/data-table-mysql": "^0.4.0",
543
+ "@remix-run/cookie": "^0.5.4",
485
544
  "@remix-run/data-table-postgres": "^0.4.0",
486
- "@remix-run/data-table-sqlite": "^0.5.0",
487
- "@remix-run/fetch-proxy": "^0.8.2",
488
- "@remix-run/fetch-router": "^0.19.1",
489
- "@remix-run/file-storage": "^0.13.5",
490
- "@remix-run/form-data-middleware": "^0.3.1",
491
- "@remix-run/form-data-parser": "^0.17.2",
492
- "@remix-run/file-storage-s3": "^0.1.2",
493
- "@remix-run/fs": "^0.4.4",
545
+ "@remix-run/data-table-mysql": "^0.4.0",
546
+ "@remix-run/data-table-sqlite": "^0.5.1",
547
+ "@remix-run/fetch-proxy": "^0.8.3",
548
+ "@remix-run/fetch-router": "^0.20.0",
549
+ "@remix-run/file-storage": "^0.13.6",
550
+ "@remix-run/form-data-middleware": "^0.3.3",
551
+ "@remix-run/file-storage-s3": "^0.1.3",
552
+ "@remix-run/headers": "^0.21.1",
553
+ "@remix-run/fs": "^0.4.5",
554
+ "@remix-run/form-data-parser": "^0.17.3",
494
555
  "@remix-run/html-template": "^0.3.1",
495
- "@remix-run/headers": "^0.21.0",
496
- "@remix-run/lazy-file": "^5.0.4",
497
- "@remix-run/logger-middleware": "^0.3.1",
556
+ "@remix-run/method-override-middleware": "^0.1.11",
557
+ "@remix-run/logger-middleware": "^0.3.3",
498
558
  "@remix-run/mime": "^0.4.1",
499
- "@remix-run/multipart-parser": "^0.16.2",
500
- "@remix-run/method-override-middleware": "^0.1.9",
559
+ "@remix-run/multipart-parser": "^0.16.3",
560
+ "@remix-run/lazy-file": "^5.0.5",
501
561
  "@remix-run/node-fetch-server": "^0.13.3",
502
562
  "@remix-run/node-tsx": "^0.1.1",
503
- "@remix-run/route-pattern": "^0.21.1",
563
+ "@remix-run/route-pattern": "^0.22.1",
564
+ "@remix-run/response": "^0.3.6",
504
565
  "@remix-run/session": "^0.4.2",
505
- "@remix-run/response": "^0.3.5",
506
- "@remix-run/session-middleware": "^0.3.1",
507
- "@remix-run/session-storage-memcache": "^0.1.1",
508
- "@remix-run/static-middleware": "^0.4.10",
509
566
  "@remix-run/session-storage-redis": "^0.1.1",
567
+ "@remix-run/session-middleware": "^0.3.3",
568
+ "@remix-run/session-storage-memcache": "^0.1.2",
569
+ "@remix-run/static-middleware": "^0.4.12",
570
+ "@remix-run/assert": "^0.3.0",
510
571
  "@remix-run/tar-parser": "^0.7.1",
511
- "@remix-run/assert": "^0.2.1",
512
- "@remix-run/cli": "^0.3.1",
513
- "@remix-run/render-middleware": "^0.1.1",
572
+ "@remix-run/cli": "^0.3.3",
573
+ "@remix-run/test": "^0.5.0",
514
574
  "@remix-run/terminal": "^0.1.1",
515
- "@remix-run/test": "^0.4.1"
575
+ "@remix-run/render-middleware": "^0.1.3"
516
576
  },
517
577
  "bin": {
518
578
  "remix": "./dist/cli-entry.js"
@@ -521,7 +581,7 @@
521
581
  "mysql2": "^3.15.3",
522
582
  "pg": "^8.16.3",
523
583
  "redis": "^5.10.0",
524
- "playwright": "^1.59.0"
584
+ "playwright": "^1.60.0"
525
585
  },
526
586
  "peerDependenciesMeta": {
527
587
  "mysql2": {
@@ -540,6 +600,7 @@
540
600
  "scripts": {
541
601
  "build": "tsc -p tsconfig.build.json",
542
602
  "clean": "git clean -fdX",
603
+ "sync-readmes": "node ../../scripts/sync-remix-readmes.ts",
543
604
  "test": "remix-test",
544
605
  "typecheck": "tsc --noEmit"
545
606
  }
@@ -2,14 +2,14 @@
2
2
 
3
3
  A compatible subset of `node:assert/strict` that works in any JavaScript environment, including browsers — plus a vitest-/jest-style `expect` API for tests that prefer chainable matchers.
4
4
 
5
- Uses strict equality (`===`) for all comparisons — no type coercion.
5
+ Uses strict equality (`Object.is`) for all comparisons — no type coercion.
6
6
 
7
7
  ## Features
8
8
 
9
9
  - `AssertionError` — compatible with `node:assert.AssertionError` (`actual`, `expected`, `operator`, `name`)
10
10
  - `assert.ok` — truthy check
11
- - `assert.equal` / `assert.notEqual` — strict equality (`===` / `!==`)
12
- - `assert.deepEqual` / `assert.notDeepEqual` — recursive strict deep equality
11
+ - `assert.equal` / `assert.notEqual` — strict equality (`Object.is` / `!Object.is`)
12
+ - `assert.deepEqual` / `assert.partialDeepEqual` / `assert.notDeepEqual` — recursive strict deep equality
13
13
  - `assert.match` — string matches a regexp
14
14
  - `assert.fail` — unconditional failure
15
15
  - `assert.throws` — synchronous throw assertion with optional error validation
@@ -24,17 +24,20 @@ npm i remix
24
24
 
25
25
  ## Usage
26
26
 
27
- Mirrors `node:assert/strict` — uses strict equality (`===`), so `1 !== '1'` and `null !== undefined`.
27
+ Mirrors `node:assert/strict` — uses strict equality (`Object.is`), so `1 !== '1'`, `null !== undefined`, `NaN` equals `NaN`, and `0` does not equal `-0`.
28
28
 
29
29
  ```ts
30
30
  import assert from 'remix/assert'
31
31
 
32
32
  assert.ok(true)
33
+ assert(true)
33
34
  assert.equal(1, 1)
34
35
  assert.equal(1, '1') // throws — different types
36
+ assert.equal(NaN, NaN)
35
37
  assert.notEqual('a', 'b')
36
38
  assert.deepEqual({ a: 1 }, { a: 1 })
37
39
  assert.deepEqual({ a: 1 }, { a: '1' }) // throws — different types
40
+ assert.partialDeepEqual({ a: 1, b: 2 }, { a: 1 })
38
41
  assert.match('hello world', /world/)
39
42
  assert.fail('should not reach here')
40
43
 
@@ -64,11 +67,15 @@ import {
64
67
  equal,
65
68
  notEqual,
66
69
  deepEqual,
70
+ partialDeepEqual,
67
71
  notDeepEqual,
68
72
  match,
73
+ doesNotMatch,
69
74
  fail,
70
75
  throws,
76
+ doesNotThrow,
71
77
  rejects,
78
+ doesNotReject,
72
79
  } from 'remix/assert'
73
80
  ```
74
81
 
@@ -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