@guard-rail/core 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +253 -36
  2. package/dist/adapters/supabase/auth.js +1 -2
  3. package/dist/adapters/supabase/auth.js.map +1 -1
  4. package/dist/adapters/supabase/client.js +6 -1
  5. package/dist/adapters/supabase/client.js.map +1 -1
  6. package/dist/adapters/supabase/confirm.d.ts +11 -11
  7. package/dist/adapters/supabase/confirm.js +14 -18
  8. package/dist/adapters/supabase/confirm.js.map +1 -1
  9. package/dist/adapters/supabase/index.d.ts +3 -1
  10. package/dist/adapters/supabase/index.js +5 -0
  11. package/dist/adapters/supabase/index.js.map +1 -1
  12. package/dist/adapters/supabase/rateLimit.d.ts +24 -0
  13. package/dist/adapters/supabase/rateLimit.js +37 -0
  14. package/dist/adapters/supabase/rateLimit.js.map +1 -0
  15. package/dist/cli/doctor.d.ts +1 -0
  16. package/dist/cli/doctor.js +1046 -0
  17. package/dist/cli/doctor.js.map +1 -0
  18. package/dist/cli/init-db.js +23 -5
  19. package/dist/cli/init-db.js.map +1 -1
  20. package/dist/core/adapter-types.d.ts +71 -1
  21. package/dist/core/config.d.ts +12 -1
  22. package/dist/core/config.js +29 -1
  23. package/dist/core/config.js.map +1 -1
  24. package/dist/core/csp.d.ts +32 -0
  25. package/dist/core/csp.js +26 -0
  26. package/dist/core/csp.js.map +1 -0
  27. package/dist/core/validate.d.ts +47 -0
  28. package/dist/core/validate.js +118 -0
  29. package/dist/core/validate.js.map +1 -0
  30. package/dist/index.client.d.ts +2 -1
  31. package/dist/index.client.js +3 -0
  32. package/dist/index.client.js.map +1 -1
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.js +3 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/react/Admin.d.ts +5 -3
  37. package/dist/react/Admin.js +29 -41
  38. package/dist/react/Admin.js.map +1 -1
  39. package/dist/react/AuthDrawer.js +22 -34
  40. package/dist/react/AuthDrawer.js.map +1 -1
  41. package/dist/react/AuthRedirectSync.js +28 -22
  42. package/dist/react/AuthRedirectSync.js.map +1 -1
  43. package/dist/react/GRail/client.js +27 -47
  44. package/dist/react/GRail/client.js.map +1 -1
  45. package/dist/react/GRail/render.js +3 -2
  46. package/dist/react/GRail/render.js.map +1 -1
  47. package/dist/react/MediaPicker.js +12 -16
  48. package/dist/react/MediaPicker.js.map +1 -1
  49. package/dist/react/Repeater/client.js +12 -13
  50. package/dist/react/Repeater/client.js.map +1 -1
  51. package/dist/react/Team.d.ts +1 -7
  52. package/dist/react/Team.js +21 -46
  53. package/dist/react/Team.js.map +1 -1
  54. package/dist/react/guardrail.css +563 -0
  55. package/dist/server/actions.js +52 -31
  56. package/dist/server/actions.js.map +1 -1
  57. package/dist/server/loader.js +4 -4
  58. package/dist/server/loader.js.map +1 -1
  59. package/dist/server/rateLimit.d.ts +21 -0
  60. package/dist/server/rateLimit.js +94 -0
  61. package/dist/server/rateLimit.js.map +1 -0
  62. package/dist/server/repeaterActions.js +9 -1
  63. package/dist/server/repeaterActions.js.map +1 -1
  64. package/dist/server/wrapper.js +18 -1
  65. package/dist/server/wrapper.js.map +1 -1
  66. package/package.json +11 -9
  67. package/supabase/admin/check-grants.sql +41 -0
  68. package/supabase/migrations/20261028000000_require_confirmed_email.sql +53 -0
  69. package/supabase/migrations/20261028010000_rate_limits.sql +67 -0
  70. package/supabase/migrations/20261028020000_member_and_bucket_guards.sql +96 -0
  71. package/dist/react/styles.d.ts +0 -504
  72. package/dist/react/styles.js +0 -500
  73. package/dist/react/styles.js.map +0 -1
  74. package/scripts/postinstall.mjs +0 -48
@@ -1,504 +0,0 @@
1
- /**
2
- * Guardrail's own chrome is styled with inline styles on purpose. Utility
3
- * classes would make the package depend on the consumer having Tailwind *and*
4
- * adding node_modules/guardrail to their content globs — it would render
5
- * unstyled on a clean install. Developer-authored content is never touched.
6
- *
7
- * Colors are CSS variables so the chrome can follow the visitor's OS light/dark
8
- * preference — inline styles can't express a media query, but they can read a
9
- * variable that one defines. THEME_CSS (rendered once by <GRailAdmin>) sets the
10
- * variables; every use below carries the light value as its fallback, so the
11
- * chrome still renders correctly if that stylesheet is ever absent.
12
- */
13
- declare const LIGHT: {
14
- readonly bg: "#ffffff";
15
- readonly "bg-glass": "rgba(255,255,255,0.97)";
16
- readonly fg: "#111827";
17
- readonly fg2: "#4b5563";
18
- readonly muted: "#6b7280";
19
- readonly subtle: "#9ca3af";
20
- readonly border: "#e5e7eb";
21
- readonly "border-strong": "#d1d5db";
22
- readonly "border-soft": "#f3f4f6";
23
- readonly "input-bg": "#ffffff";
24
- readonly soft: "#f3f4f6";
25
- readonly accent: "#2563eb";
26
- readonly "accent-soft": "#eff6ff";
27
- readonly "accent-text": "#1d4ed8";
28
- readonly "primary-bg": "#111827";
29
- readonly "primary-fg": "#ffffff";
30
- readonly danger: "#dc2626";
31
- readonly label: "#1e3a8a";
32
- readonly shadow: "rgba(0,0,0,0.25)";
33
- };
34
- /** A themed color: reads the variable, falls back to the light value. */
35
- declare const v: (name: keyof typeof LIGHT) => string;
36
- /**
37
- * Rendered once by <GRailAdmin>. Variables go on :root so portaled chrome
38
- * inherits them. `color-scheme` is deliberately scoped to Guardrail's own
39
- * elements, never :root — that would flip the host site's form controls and
40
- * scrollbars too. It's what makes native controls inside the chrome (the
41
- * team drawer's role <select>, its dropdown list) match the palette.
42
- */
43
- declare const THEME_CSS: string;
44
- declare const S: {
45
- banner: {
46
- position: "fixed";
47
- bottom: number;
48
- left: number;
49
- width: string;
50
- background: string;
51
- color: string;
52
- padding: string;
53
- zIndex: number;
54
- borderTop: string;
55
- fontFamily: "system-ui, -apple-system, sans-serif";
56
- };
57
- bannerForm: {
58
- display: "flex";
59
- gap: number;
60
- justifyContent: "center";
61
- alignItems: "center";
62
- flexWrap: "wrap";
63
- };
64
- brand: {
65
- fontWeight: number;
66
- letterSpacing: string;
67
- fontSize: number;
68
- textTransform: "uppercase";
69
- };
70
- /** Brand plus any status/error text under it, stacked instead of sharing
71
- * the form's row — otherwise a login error reads as if it's labeling the
72
- * next field over, not feedback about the brand's own sign-in attempt. */
73
- brandStack: {
74
- display: "flex";
75
- flexDirection: "column";
76
- alignItems: "flex-start";
77
- gap: number;
78
- };
79
- error: {
80
- color: string;
81
- fontSize: number;
82
- fontWeight: number;
83
- };
84
- input: {
85
- border: string;
86
- borderRadius: number;
87
- padding: string;
88
- fontSize: number;
89
- color: string;
90
- background: string;
91
- outline: string;
92
- };
93
- primaryBtn: {
94
- background: string;
95
- color: string;
96
- padding: string;
97
- borderRadius: number;
98
- fontSize: number;
99
- fontWeight: number;
100
- border: string;
101
- cursor: "pointer";
102
- };
103
- toolbar: {
104
- position: "fixed";
105
- bottom: number;
106
- left: string;
107
- transform: "translateX(-50%)";
108
- zIndex: number;
109
- background: string;
110
- backdropFilter: "blur(8px)";
111
- color: string;
112
- padding: string;
113
- borderRadius: number;
114
- boxShadow: `0 20px 40px ${string}`;
115
- display: "flex";
116
- alignItems: "center";
117
- gap: number;
118
- border: string;
119
- fontFamily: "system-ui, -apple-system, sans-serif";
120
- };
121
- dot: {
122
- display: "inline-block";
123
- width: number;
124
- height: number;
125
- borderRadius: string;
126
- background: string;
127
- };
128
- toolbarLabel: {
129
- fontSize: number;
130
- fontWeight: number;
131
- textTransform: "uppercase";
132
- letterSpacing: string;
133
- color: string;
134
- };
135
- divider: {
136
- width: number;
137
- height: number;
138
- background: string;
139
- };
140
- linkBtn: {
141
- fontSize: number;
142
- fontWeight: number;
143
- textTransform: "uppercase";
144
- letterSpacing: string;
145
- color: string;
146
- background: string;
147
- border: string;
148
- cursor: "pointer";
149
- };
150
- popover: {
151
- position: "fixed";
152
- bottom: number;
153
- left: string;
154
- transform: "translateX(-50%)";
155
- zIndex: number;
156
- background: string;
157
- color: string;
158
- padding: number;
159
- borderRadius: number;
160
- boxShadow: `0 20px 40px ${string}`;
161
- border: string;
162
- minWidth: number;
163
- cursor: "default";
164
- fontFamily: "system-ui, -apple-system, sans-serif";
165
- };
166
- label: {
167
- display: "block";
168
- fontSize: number;
169
- fontWeight: number;
170
- color: string;
171
- marginBottom: number;
172
- textTransform: "uppercase";
173
- };
174
- field: {
175
- border: string;
176
- borderRadius: number;
177
- padding: string;
178
- fontSize: number;
179
- color: string;
180
- background: string;
181
- width: string;
182
- marginBottom: number;
183
- boxSizing: "border-box";
184
- };
185
- row: {
186
- display: "flex";
187
- gap: number;
188
- marginTop: number;
189
- paddingTop: number;
190
- borderTop: string;
191
- };
192
- cancelBtn: {
193
- background: string;
194
- color: string;
195
- padding: string;
196
- borderRadius: number;
197
- fontSize: number;
198
- border: string;
199
- cursor: "pointer";
200
- };
201
- /** Anchored to the element's rect at runtime; top/left are set inline. */
202
- anchoredBar: {
203
- position: "fixed";
204
- zIndex: number;
205
- display: "flex";
206
- alignItems: "center";
207
- gap: number;
208
- background: string;
209
- color: string;
210
- backdropFilter: "blur(8px)";
211
- padding: number;
212
- borderRadius: number;
213
- boxShadow: `0 8px 24px ${string}`;
214
- border: string;
215
- fontFamily: "system-ui, -apple-system, sans-serif";
216
- };
217
- anchoredPanel: {
218
- position: "fixed";
219
- zIndex: number;
220
- maxHeight: string;
221
- overflowY: "auto";
222
- background: string;
223
- color: string;
224
- padding: number;
225
- borderRadius: number;
226
- boxShadow: `0 12px 32px ${string}`;
227
- border: string;
228
- minWidth: number;
229
- maxWidth: string;
230
- cursor: "default";
231
- fontFamily: "system-ui, -apple-system, sans-serif";
232
- };
233
- iconBtn: {
234
- display: "inline-flex";
235
- alignItems: "center";
236
- justifyContent: "center";
237
- width: number;
238
- height: number;
239
- borderRadius: number;
240
- border: string;
241
- background: string;
242
- color: string;
243
- cursor: "pointer";
244
- padding: number;
245
- };
246
- iconBtnPrimary: {
247
- display: "inline-flex";
248
- alignItems: "center";
249
- justifyContent: "center";
250
- width: number;
251
- height: number;
252
- borderRadius: number;
253
- border: string;
254
- background: string;
255
- color: "#fff";
256
- cursor: "pointer";
257
- padding: number;
258
- };
259
- scrim: {
260
- position: "fixed";
261
- inset: number;
262
- background: string;
263
- zIndex: number;
264
- };
265
- drawer: {
266
- position: "fixed";
267
- top: number;
268
- right: number;
269
- height: string;
270
- width: string;
271
- background: string;
272
- color: string;
273
- zIndex: number;
274
- boxShadow: `-12px 0 32px ${string}`;
275
- display: "flex";
276
- flexDirection: "column";
277
- fontFamily: "system-ui, -apple-system, sans-serif";
278
- };
279
- drawerHead: {
280
- display: "flex";
281
- alignItems: "center";
282
- justifyContent: "space-between";
283
- padding: string;
284
- borderBottom: string;
285
- };
286
- drawerTitle: {
287
- fontSize: number;
288
- fontWeight: number;
289
- margin: number;
290
- };
291
- drawerBody: {
292
- padding: number;
293
- overflowY: "auto";
294
- flex: number;
295
- };
296
- memberRow: {
297
- display: "flex";
298
- alignItems: "center";
299
- gap: number;
300
- padding: string;
301
- borderBottom: string;
302
- };
303
- memberEmail: {
304
- flex: number;
305
- fontSize: number;
306
- overflow: "hidden";
307
- textOverflow: "ellipsis";
308
- whiteSpace: "nowrap";
309
- };
310
- select: {
311
- border: string;
312
- borderRadius: number;
313
- padding: string;
314
- fontSize: number;
315
- background: string;
316
- color: string;
317
- };
318
- badge: {
319
- fontSize: number;
320
- fontWeight: number;
321
- textTransform: "uppercase";
322
- letterSpacing: string;
323
- padding: string;
324
- borderRadius: number;
325
- background: string;
326
- color: "#92400e";
327
- };
328
- sectionLabel: {
329
- fontSize: number;
330
- fontWeight: number;
331
- textTransform: "uppercase";
332
- letterSpacing: string;
333
- color: string;
334
- margin: string;
335
- };
336
- pickerScrim: {
337
- position: "fixed";
338
- inset: number;
339
- background: string;
340
- zIndex: number;
341
- };
342
- picker: {
343
- position: "fixed";
344
- top: string;
345
- left: string;
346
- transform: "translate(-50%, -50%)";
347
- width: string;
348
- maxHeight: string;
349
- background: string;
350
- color: string;
351
- borderRadius: number;
352
- zIndex: number;
353
- boxShadow: `0 24px 64px ${string}`;
354
- display: "flex";
355
- flexDirection: "column";
356
- overflow: "hidden";
357
- fontFamily: "system-ui, -apple-system, sans-serif";
358
- };
359
- pickerGrid: {
360
- display: "grid";
361
- gridTemplateColumns: string;
362
- gap: number;
363
- };
364
- pickerTile: {
365
- position: "relative";
366
- aspectRatio: "1";
367
- borderRadius: number;
368
- overflow: "hidden";
369
- border: string;
370
- background: string;
371
- cursor: "pointer";
372
- padding: number;
373
- };
374
- pickerTileActive: {
375
- borderColor: string;
376
- };
377
- pickerThumb: {
378
- width: string;
379
- height: string;
380
- objectFit: "cover";
381
- display: "block";
382
- };
383
- dropzone: {
384
- border: string;
385
- borderRadius: number;
386
- padding: number;
387
- textAlign: "center";
388
- fontSize: number;
389
- color: string;
390
- marginBottom: number;
391
- cursor: "pointer";
392
- };
393
- dropzoneActive: {
394
- borderColor: string;
395
- background: string;
396
- color: string;
397
- };
398
- previewThumb: {
399
- width: string;
400
- maxWidth: number;
401
- height: string;
402
- maxHeight: number;
403
- objectFit: "contain";
404
- background: string;
405
- borderRadius: number;
406
- display: "block";
407
- marginBottom: number;
408
- };
409
- secondaryBtn: {
410
- background: string;
411
- color: string;
412
- padding: string;
413
- borderRadius: number;
414
- fontSize: number;
415
- fontWeight: number;
416
- border: string;
417
- cursor: "pointer";
418
- width: string;
419
- marginBottom: number;
420
- };
421
- /**
422
- * Edit affordance for image fields, drawn as separate fixed elements instead
423
- * of styling the <img> itself. Backgrounds (next/image `fill` behind
424
- * overlaid content) can't take an in-place affordance: it either sits under
425
- * the content and can't be clicked, or gets lifted over it and hides it.
426
- * The outline ignores the pointer so overlaid content stays interactive;
427
- * the handle is the one clickable piece.
428
- */
429
- markerOutline: {
430
- position: "fixed";
431
- zIndex: number;
432
- pointerEvents: "none";
433
- boxSizing: "border-box";
434
- borderRadius: number;
435
- };
436
- markerHandle: {
437
- position: "fixed";
438
- zIndex: number;
439
- display: "inline-flex";
440
- alignItems: "center";
441
- gap: number;
442
- padding: string;
443
- borderRadius: number;
444
- border: string;
445
- background: string;
446
- color: "#fff";
447
- fontSize: number;
448
- fontWeight: number;
449
- fontFamily: "system-ui, -apple-system, sans-serif";
450
- cursor: "pointer";
451
- boxShadow: `0 4px 12px ${string}`;
452
- };
453
- repeaterItem: {
454
- position: "relative";
455
- outline: string;
456
- outlineOffset: number;
457
- };
458
- repeaterToolbar: {
459
- position: "absolute";
460
- top: number;
461
- right: number;
462
- zIndex: number;
463
- display: "flex";
464
- gap: number;
465
- background: string;
466
- color: string;
467
- backdropFilter: "blur(6px)";
468
- padding: number;
469
- borderRadius: number;
470
- boxShadow: `0 4px 12px ${string}`;
471
- border: string;
472
- };
473
- repeaterAddRow: {
474
- display: "flex";
475
- gap: number;
476
- alignItems: "center";
477
- marginTop: number;
478
- fontFamily: "system-ui, -apple-system, sans-serif";
479
- };
480
- repeaterAddBtn: {
481
- display: "inline-flex";
482
- alignItems: "center";
483
- gap: number;
484
- padding: string;
485
- borderRadius: number;
486
- border: string;
487
- background: string;
488
- color: string;
489
- fontSize: number;
490
- fontWeight: number;
491
- cursor: "pointer";
492
- };
493
- repeaterSlugInput: {
494
- border: string;
495
- borderRadius: number;
496
- padding: string;
497
- fontSize: number;
498
- color: string;
499
- background: string;
500
- minWidth: number;
501
- };
502
- };
503
-
504
- export { S, THEME_CSS, v };