remix 3.0.0-beta.0 → 3.0.0-beta.1

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/fetch-router.d.ts +7 -0
  2. package/dist/fetch-router.d.ts.map +1 -1
  3. package/dist/node-tsx/load-module.d.ts +2 -0
  4. package/dist/node-tsx/load-module.d.ts.map +1 -0
  5. package/dist/node-tsx/load-module.js +2 -0
  6. package/dist/node-tsx.d.ts +3 -0
  7. package/dist/node-tsx.d.ts.map +1 -0
  8. package/dist/node-tsx.js +3 -0
  9. package/dist/render-middleware.d.ts +2 -0
  10. package/dist/render-middleware.d.ts.map +1 -0
  11. package/dist/render-middleware.js +2 -0
  12. package/dist/route-pattern/href.d.ts +2 -0
  13. package/dist/route-pattern/href.d.ts.map +1 -0
  14. package/dist/route-pattern/href.js +2 -0
  15. package/dist/route-pattern/join.d.ts +2 -0
  16. package/dist/route-pattern/join.d.ts.map +1 -0
  17. package/dist/route-pattern/join.js +2 -0
  18. package/dist/route-pattern/match.d.ts +2 -0
  19. package/dist/route-pattern/match.d.ts.map +1 -0
  20. package/dist/route-pattern/match.js +2 -0
  21. package/package.json +153 -34
  22. package/src/assert/README.md +109 -0
  23. package/src/assets/README.md +539 -0
  24. package/src/async-context-middleware/README.md +100 -0
  25. package/src/auth/README.md +445 -0
  26. package/src/auth-middleware/README.md +246 -0
  27. package/src/cli/README.md +78 -0
  28. package/src/compression-middleware/README.md +176 -0
  29. package/src/cookie/README.md +106 -0
  30. package/src/cop-middleware/README.md +117 -0
  31. package/src/cors-middleware/README.md +174 -0
  32. package/src/csrf-middleware/README.md +99 -0
  33. package/src/data-schema/README.md +422 -0
  34. package/src/data-table/README.md +552 -0
  35. package/src/data-table-mysql/README.md +97 -0
  36. package/src/data-table-postgres/README.md +74 -0
  37. package/src/data-table-sqlite/README.md +84 -0
  38. package/src/fetch-proxy/README.md +46 -0
  39. package/src/fetch-router/README.md +902 -0
  40. package/src/fetch-router.ts +7 -0
  41. package/src/file-storage/README.md +51 -0
  42. package/src/file-storage-s3/README.md +47 -0
  43. package/src/form-data-middleware/README.md +109 -0
  44. package/src/form-data-parser/README.md +163 -0
  45. package/src/fs/README.md +60 -0
  46. package/src/headers/README.md +607 -0
  47. package/src/html-template/README.md +101 -0
  48. package/src/lazy-file/README.md +109 -0
  49. package/src/logger-middleware/README.md +132 -0
  50. package/src/method-override-middleware/README.md +71 -0
  51. package/src/mime/README.md +110 -0
  52. package/src/multipart-parser/README.md +241 -0
  53. package/src/node-fetch-server/README.md +356 -0
  54. package/src/node-serve/README.md +253 -0
  55. package/src/node-tsx/README.md +79 -0
  56. package/src/node-tsx/load-module.ts +2 -0
  57. package/src/node-tsx.ts +3 -0
  58. package/src/render-middleware/README.md +99 -0
  59. package/src/render-middleware.ts +2 -0
  60. package/src/route-pattern/README.md +291 -0
  61. package/src/route-pattern/href.ts +2 -0
  62. package/src/route-pattern/join.ts +2 -0
  63. package/src/route-pattern/match.ts +2 -0
  64. package/src/session/README.md +171 -0
  65. package/src/session-middleware/README.md +109 -0
  66. package/src/session-storage-memcache/README.md +37 -0
  67. package/src/session-storage-redis/README.md +37 -0
  68. package/src/static-middleware/README.md +89 -0
  69. package/src/tar-parser/README.md +74 -0
  70. package/src/terminal/README.md +92 -0
  71. package/src/test/README.md +430 -0
  72. package/src/ui/README.md +217 -0
  73. package/src/ui/accordion/README.md +166 -0
  74. package/src/ui/anchor/README.md +153 -0
  75. package/src/ui/animation/README.md +314 -0
  76. package/src/ui/breadcrumbs/README.md +55 -0
  77. package/src/ui/button/README.md +44 -0
  78. package/src/ui/combobox/README.md +145 -0
  79. package/src/ui/glyph/README.md +72 -0
  80. package/src/ui/listbox/README.md +115 -0
  81. package/src/ui/menu/README.md +96 -0
  82. package/src/ui/popover/README.md +122 -0
  83. package/src/ui/scroll-lock/README.md +33 -0
  84. package/src/ui/select/README.md +107 -0
  85. package/src/ui/server/README.md +88 -0
  86. package/src/ui/test/README.md +107 -0
  87. package/src/ui/theme/README.md +103 -0
@@ -1,2 +1,9 @@
1
1
  export * from '@remix-run/fetch-router';
2
+ export interface RouterTypes {
3
+ }
4
+ type RemixRouterTypes = RouterTypes;
5
+ declare module '@remix-run/fetch-router' {
6
+ interface RouterTypes extends RemixRouterTypes {
7
+ }
8
+ }
2
9
  //# sourceMappingURL=fetch-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-router.d.ts","sourceRoot":"","sources":["../src/fetch-router.ts"],"names":[],"mappings":"AACA,cAAc,yBAAyB,CAAA"}
1
+ {"version":3,"file":"fetch-router.d.ts","sourceRoot":"","sources":["../src/fetch-router.ts"],"names":[],"mappings":"AACA,cAAc,yBAAyB,CAAA;AAEvC,MAAM,WAAW,WAAW;CAAG;AAC/B,KAAK,gBAAgB,GAAG,WAAW,CAAA;AAEnC,OAAO,QAAQ,yBAAyB,CAAC;IACvC,UAAU,WAAY,SAAQ,gBAAgB;KAAG;CAClD"}
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/node-tsx/load-module';
2
+ //# sourceMappingURL=load-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-module.d.ts","sourceRoot":"","sources":["../../src/node-tsx/load-module.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/node-tsx/load-module';
@@ -0,0 +1,3 @@
1
+ import '@remix-run/node-tsx';
2
+ export {};
3
+ //# sourceMappingURL=node-tsx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-tsx.d.ts","sourceRoot":"","sources":["../src/node-tsx.ts"],"names":[],"mappings":"AACA,OAAO,qBAAqB,CAAA;AAC5B,OAAO,EAAE,CAAA"}
@@ -0,0 +1,3 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ import '@remix-run/node-tsx';
3
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/render-middleware';
2
+ //# sourceMappingURL=render-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-middleware.d.ts","sourceRoot":"","sources":["../src/render-middleware.ts"],"names":[],"mappings":"AACA,cAAc,8BAA8B,CAAA"}
@@ -0,0 +1,2 @@
1
+ // IMPORTANT: This file is auto-generated, please do not edit manually.
2
+ export * from '@remix-run/render-middleware';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/route-pattern/href';
2
+ //# sourceMappingURL=href.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"href.d.ts","sourceRoot":"","sources":["../../src/route-pattern/href.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/route-pattern/href';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/route-pattern/join';
2
+ //# sourceMappingURL=join.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../src/route-pattern/join.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/route-pattern/join';
@@ -0,0 +1,2 @@
1
+ export * from '@remix-run/route-pattern/match';
2
+ //# sourceMappingURL=match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/route-pattern/match.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/route-pattern/match';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remix",
3
- "version": "3.0.0-beta.0",
3
+ "version": "3.0.0-beta.1",
4
4
  "description": "The Remix web framework",
5
5
  "author": "Michael Jackson <mjijackson@gmail.com>",
6
6
  "license": "MIT",
@@ -109,14 +109,26 @@
109
109
  "types": "./dist/data-table/migrations/node.d.ts",
110
110
  "default": "./dist/data-table/migrations/node.js"
111
111
  },
112
+ "./data-table/mysql": {
113
+ "types": "./dist/data-table-mysql.d.ts",
114
+ "default": "./dist/data-table-mysql.js"
115
+ },
112
116
  "./data-table/operators": {
113
117
  "types": "./dist/data-table/operators.d.ts",
114
118
  "default": "./dist/data-table/operators.js"
115
119
  },
120
+ "./data-table/postgres": {
121
+ "types": "./dist/data-table-postgres.d.ts",
122
+ "default": "./dist/data-table-postgres.js"
123
+ },
116
124
  "./data-table/sql-helpers": {
117
125
  "types": "./dist/data-table/sql-helpers.d.ts",
118
126
  "default": "./dist/data-table/sql-helpers.js"
119
127
  },
128
+ "./data-table/sqlite": {
129
+ "types": "./dist/data-table-sqlite.d.ts",
130
+ "default": "./dist/data-table-sqlite.js"
131
+ },
120
132
  "./fetch-proxy": {
121
133
  "types": "./dist/fetch-proxy.d.ts",
122
134
  "default": "./dist/fetch-proxy.js"
@@ -145,6 +157,10 @@
145
157
  "types": "./dist/file-storage/memory.d.ts",
146
158
  "default": "./dist/file-storage/memory.js"
147
159
  },
160
+ "./file-storage/s3": {
161
+ "types": "./dist/file-storage-s3.d.ts",
162
+ "default": "./dist/file-storage-s3.js"
163
+ },
148
164
  "./form-data-middleware": {
149
165
  "types": "./dist/form-data-middleware.d.ts",
150
166
  "default": "./dist/form-data-middleware.js"
@@ -177,6 +193,54 @@
177
193
  "types": "./dist/method-override-middleware.d.ts",
178
194
  "default": "./dist/method-override-middleware.js"
179
195
  },
196
+ "./middleware/async-context": {
197
+ "types": "./dist/async-context-middleware.d.ts",
198
+ "default": "./dist/async-context-middleware.js"
199
+ },
200
+ "./middleware/auth": {
201
+ "types": "./dist/auth-middleware.d.ts",
202
+ "default": "./dist/auth-middleware.js"
203
+ },
204
+ "./middleware/compression": {
205
+ "types": "./dist/compression-middleware.d.ts",
206
+ "default": "./dist/compression-middleware.js"
207
+ },
208
+ "./middleware/cop": {
209
+ "types": "./dist/cop-middleware.d.ts",
210
+ "default": "./dist/cop-middleware.js"
211
+ },
212
+ "./middleware/cors": {
213
+ "types": "./dist/cors-middleware.d.ts",
214
+ "default": "./dist/cors-middleware.js"
215
+ },
216
+ "./middleware/csrf": {
217
+ "types": "./dist/csrf-middleware.d.ts",
218
+ "default": "./dist/csrf-middleware.js"
219
+ },
220
+ "./middleware/form-data": {
221
+ "types": "./dist/form-data-middleware.d.ts",
222
+ "default": "./dist/form-data-middleware.js"
223
+ },
224
+ "./middleware/logger": {
225
+ "types": "./dist/logger-middleware.d.ts",
226
+ "default": "./dist/logger-middleware.js"
227
+ },
228
+ "./middleware/method-override": {
229
+ "types": "./dist/method-override-middleware.d.ts",
230
+ "default": "./dist/method-override-middleware.js"
231
+ },
232
+ "./middleware/render": {
233
+ "types": "./dist/render-middleware.d.ts",
234
+ "default": "./dist/render-middleware.js"
235
+ },
236
+ "./middleware/session": {
237
+ "types": "./dist/session-middleware.d.ts",
238
+ "default": "./dist/session-middleware.js"
239
+ },
240
+ "./middleware/static": {
241
+ "types": "./dist/static-middleware.d.ts",
242
+ "default": "./dist/static-middleware.js"
243
+ },
180
244
  "./mime": {
181
245
  "types": "./dist/mime.d.ts",
182
246
  "default": "./dist/mime.js"
@@ -201,6 +265,18 @@
201
265
  "types": "./dist/node-serve.d.ts",
202
266
  "default": "./dist/node-serve.js"
203
267
  },
268
+ "./node-tsx": {
269
+ "types": "./dist/node-tsx.d.ts",
270
+ "default": "./dist/node-tsx.js"
271
+ },
272
+ "./node-tsx/load-module": {
273
+ "types": "./dist/node-tsx/load-module.d.ts",
274
+ "default": "./dist/node-tsx/load-module.js"
275
+ },
276
+ "./render-middleware": {
277
+ "types": "./dist/render-middleware.d.ts",
278
+ "default": "./dist/render-middleware.js"
279
+ },
204
280
  "./response/compress": {
205
281
  "types": "./dist/response/compress.d.ts",
206
282
  "default": "./dist/response/compress.js"
@@ -221,10 +297,30 @@
221
297
  "types": "./dist/route-pattern.d.ts",
222
298
  "default": "./dist/route-pattern.js"
223
299
  },
300
+ "./route-pattern/href": {
301
+ "types": "./dist/route-pattern/href.d.ts",
302
+ "default": "./dist/route-pattern/href.js"
303
+ },
304
+ "./route-pattern/join": {
305
+ "types": "./dist/route-pattern/join.d.ts",
306
+ "default": "./dist/route-pattern/join.js"
307
+ },
308
+ "./route-pattern/match": {
309
+ "types": "./dist/route-pattern/match.d.ts",
310
+ "default": "./dist/route-pattern/match.js"
311
+ },
224
312
  "./route-pattern/specificity": {
225
313
  "types": "./dist/route-pattern/specificity.d.ts",
226
314
  "default": "./dist/route-pattern/specificity.js"
227
315
  },
316
+ "./router": {
317
+ "types": "./dist/fetch-router.d.ts",
318
+ "default": "./dist/fetch-router.js"
319
+ },
320
+ "./routes": {
321
+ "types": "./dist/fetch-router/routes.d.ts",
322
+ "default": "./dist/fetch-router/routes.js"
323
+ },
228
324
  "./session": {
229
325
  "types": "./dist/session.d.ts",
230
326
  "default": "./dist/session.js"
@@ -241,6 +337,26 @@
241
337
  "types": "./dist/session-storage-redis.d.ts",
242
338
  "default": "./dist/session-storage-redis.js"
243
339
  },
340
+ "./session-storage/cookie": {
341
+ "types": "./dist/session/cookie-storage.d.ts",
342
+ "default": "./dist/session/cookie-storage.js"
343
+ },
344
+ "./session-storage/fs": {
345
+ "types": "./dist/session/fs-storage.d.ts",
346
+ "default": "./dist/session/fs-storage.js"
347
+ },
348
+ "./session-storage/memcache": {
349
+ "types": "./dist/session-storage-memcache.d.ts",
350
+ "default": "./dist/session-storage-memcache.js"
351
+ },
352
+ "./session-storage/memory": {
353
+ "types": "./dist/session/memory-storage.d.ts",
354
+ "default": "./dist/session/memory-storage.js"
355
+ },
356
+ "./session-storage/redis": {
357
+ "types": "./dist/session-storage-redis.d.ts",
358
+ "default": "./dist/session-storage-redis.js"
359
+ },
244
360
  "./session/cookie-storage": {
245
361
  "types": "./dist/session/cookie-storage.d.ts",
246
362
  "default": "./dist/session/cookie-storage.js"
@@ -357,49 +473,51 @@
357
473
  "typescript": "^5.9.3"
358
474
  },
359
475
  "dependencies": {
360
- "@remix-run/assets": "^0.3.0",
361
- "@remix-run/auth": "^0.2.1",
362
- "@remix-run/async-context-middleware": "^0.2.2",
363
- "@remix-run/auth-middleware": "^0.1.2",
364
- "@remix-run/cop-middleware": "^0.1.2",
365
- "@remix-run/csrf-middleware": "^0.1.2",
366
- "@remix-run/ui": "^0.1.1",
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",
367
485
  "@remix-run/data-schema": "^0.3.0",
368
- "@remix-run/cors-middleware": "^0.1.2",
369
- "@remix-run/data-table": "^0.2.1",
370
- "@remix-run/compression-middleware": "^0.1.7",
371
- "@remix-run/data-table-mysql": "^0.3.1",
372
- "@remix-run/data-table-postgres": "^0.3.1",
373
- "@remix-run/fetch-proxy": "^0.8.0",
374
- "@remix-run/fetch-router": "^0.18.2",
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
+ "@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",
375
492
  "@remix-run/file-storage": "^0.13.4",
376
- "@remix-run/data-table-sqlite": "^0.4.1",
377
493
  "@remix-run/file-storage-s3": "^0.1.1",
378
- "@remix-run/cookie": "^0.5.1",
379
- "@remix-run/form-data-middleware": "^0.2.3",
380
- "@remix-run/form-data-parser": "^0.17.0",
494
+ "@remix-run/fetch-router": "^0.19.0",
495
+ "@remix-run/form-data-parser": "^0.17.1",
381
496
  "@remix-run/fs": "^0.4.3",
382
- "@remix-run/lazy-file": "^5.0.3",
497
+ "@remix-run/form-data-middleware": "^0.3.0",
498
+ "@remix-run/headers": "^0.20.0",
383
499
  "@remix-run/html-template": "^0.3.0",
384
- "@remix-run/headers": "^0.19.0",
385
- "@remix-run/logger-middleware": "^0.2.1",
500
+ "@remix-run/lazy-file": "^5.0.3",
386
501
  "@remix-run/mime": "^0.4.1",
387
- "@remix-run/method-override-middleware": "^0.1.7",
388
- "@remix-run/multipart-parser": "^0.16.0",
389
- "@remix-run/node-fetch-server": "^0.13.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",
390
508
  "@remix-run/session": "^0.4.1",
391
- "@remix-run/session-middleware": "^0.2.2",
392
- "@remix-run/response": "^0.3.3",
393
- "@remix-run/session-storage-memcache": "^0.1.0",
394
- "@remix-run/static-middleware": "^0.4.8",
509
+ "@remix-run/session-middleware": "^0.3.0",
510
+ "@remix-run/route-pattern": "^0.21.0",
395
511
  "@remix-run/session-storage-redis": "^0.1.0",
396
- "@remix-run/tar-parser": "^0.7.1",
397
- "@remix-run/route-pattern": "^0.20.1",
512
+ "@remix-run/static-middleware": "^0.4.9",
513
+ "@remix-run/session-storage-memcache": "^0.1.0",
514
+ "@remix-run/cli": "^0.3.0",
398
515
  "@remix-run/assert": "^0.2.0",
399
- "@remix-run/cli": "^0.2.0",
516
+ "@remix-run/test": "^0.4.0",
517
+ "@remix-run/tar-parser": "^0.7.1",
400
518
  "@remix-run/terminal": "^0.1.0",
401
- "@remix-run/node-serve": "^0.1.0",
402
- "@remix-run/test": "^0.3.0"
519
+ "@remix-run/render-middleware": "^0.1.0",
520
+ "@remix-run/node-serve": "^0.2.0"
403
521
  },
404
522
  "bin": {
405
523
  "remix": "./dist/cli-entry.js"
@@ -427,6 +545,7 @@
427
545
  "scripts": {
428
546
  "build": "tsc -p tsconfig.build.json",
429
547
  "clean": "git clean -fdX",
548
+ "test": "remix-test",
430
549
  "typecheck": "tsc --noEmit"
431
550
  }
432
551
  }
@@ -0,0 +1,109 @@
1
+ # assert
2
+
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
+
5
+ Uses strict equality (`===`) for all comparisons — no type coercion.
6
+
7
+ ## Features
8
+
9
+ - `AssertionError` — compatible with `node:assert.AssertionError` (`actual`, `expected`, `operator`, `name`)
10
+ - `assert.ok` — truthy check
11
+ - `assert.equal` / `assert.notEqual` — strict equality (`===` / `!==`)
12
+ - `assert.deepEqual` / `assert.notDeepEqual` — recursive strict deep equality
13
+ - `assert.match` — string matches a regexp
14
+ - `assert.fail` — unconditional failure
15
+ - `assert.throws` — synchronous throw assertion with optional error validation
16
+ - `assert.rejects` — async rejection assertion with optional error validation
17
+ - `expect(value)` — chainable matchers with `.not`, `.rejects`, `.resolves`, plus `expect.objectContaining(...)` for partial matches
18
+
19
+ ## Installation
20
+
21
+ ```sh
22
+ npm i remix
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Mirrors `node:assert/strict` — uses strict equality (`===`), so `1 !== '1'` and `null !== undefined`.
28
+
29
+ ```ts
30
+ import assert from 'remix/assert'
31
+
32
+ assert.ok(true)
33
+ assert.equal(1, 1)
34
+ assert.equal(1, '1') // throws — different types
35
+ assert.notEqual('a', 'b')
36
+ assert.deepEqual({ a: 1 }, { a: 1 })
37
+ assert.deepEqual({ a: 1 }, { a: '1' }) // throws — different types
38
+ assert.match('hello world', /world/)
39
+ assert.fail('should not reach here')
40
+
41
+ await assert.rejects(() => Promise.reject(new Error('oops')))
42
+ assert.throws(() => {
43
+ throw new TypeError('bad')
44
+ }, TypeError)
45
+
46
+ assert.throws(
47
+ () => {
48
+ let error = new Error('Invalid value') as Error & { code: string }
49
+ error.code = 'ERR_INVALID_ARG_VALUE'
50
+ throw error
51
+ },
52
+ { code: 'ERR_INVALID_ARG_VALUE', message: /Invalid value/ },
53
+ )
54
+ ```
55
+
56
+ ### Named exports
57
+
58
+ Each assertion is also exported as a named function:
59
+
60
+ ```ts
61
+ import {
62
+ ok,
63
+ assert, // alias of ok()
64
+ equal,
65
+ notEqual,
66
+ deepEqual,
67
+ notDeepEqual,
68
+ match,
69
+ fail,
70
+ throws,
71
+ rejects,
72
+ } from 'remix/assert'
73
+ ```
74
+
75
+ ### `expect`
76
+
77
+ A vitest-/jest-style chainable matcher API on top of the same `AssertionError`. Use `.not` to negate, `.rejects` / `.resolves` to assert on a promise. Mock-aware matchers work with `mock.fn()` / `mock.method()` from `remix/test`.
78
+
79
+ ```ts
80
+ import { expect } from 'remix/assert'
81
+
82
+ expect(value).toBe(42)
83
+ expect({ a: 1, b: 2 }).toEqual({ a: 1, b: 2 })
84
+ expect({ a: 1, b: 2 }).toEqual(expect.objectContaining({ a: 1 }))
85
+ expect({ a: { b: 1, c: 2 } }).toMatchObject({ a: { b: 1 } })
86
+ expect(value).not.toBeNull()
87
+ expect(arr).toHaveLength(3)
88
+ expect(spy).toHaveBeenCalledWith('hello', 1)
89
+
90
+ await expect(fetch('/missing')).rejects.toThrow('Not found')
91
+ await expect(loadModule()).resolves.toBeUndefined()
92
+ ```
93
+
94
+ Available matchers:
95
+
96
+ | Group | Matchers |
97
+ | --------------- | ------------------------------------------------------------------------------------------------------------------------ |
98
+ | Equality | `toBe`, `toEqual`, `toBeNull`, `toBeUndefined`, `toBeDefined`, `toBeTruthy`, `toBeInstanceOf` |
99
+ | Numbers | `toBeGreaterThan`, `toBeGreaterThanOrEqual`, `toBeLessThan`, `toBeLessThanOrEqual`, `toBeCloseTo` |
100
+ | String/iterable | `toContain`, `toMatch`, `toHaveLength` |
101
+ | Object shape | `toHaveProperty(path, value?)`, `toMatchObject(partial)` |
102
+ | Throwing | `toThrow(expected?)` |
103
+ | Mock-aware | `toHaveBeenCalled`, `toHaveBeenCalledTimes(n)`, `toHaveBeenCalledWith(...args)`, `toHaveBeenNthCalledWith(nth, ...args)` |
104
+
105
+ `expect.objectContaining(partial)` is an asymmetric matcher recognized by `toEqual` (and any matcher that uses deep equality under the hood). It passes when the actual value has at least the keys in `partial` with matching values — extra keys are allowed.
106
+
107
+ ## License
108
+
109
+ See [LICENSE](https://github.com/remix-run/remix/blob/main/LICENSE)