@draftlab/auth 0.15.0 → 0.16.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 (272) hide show
  1. package/dist/esm/allow.js +26 -0
  2. package/dist/esm/client.js +254 -0
  3. package/dist/esm/core.js +597 -0
  4. package/dist/esm/css.d.js +0 -0
  5. package/dist/esm/error.js +88 -0
  6. package/dist/esm/index.js +5 -0
  7. package/dist/esm/keys.js +126 -0
  8. package/dist/esm/mutex.js +53 -0
  9. package/dist/esm/pkce.js +87 -0
  10. package/dist/esm/provider/apple.js +15 -0
  11. package/dist/esm/provider/code.js +62 -0
  12. package/dist/esm/provider/discord.js +15 -0
  13. package/dist/esm/provider/facebook.js +15 -0
  14. package/dist/esm/provider/github.js +15 -0
  15. package/dist/esm/provider/gitlab.js +15 -0
  16. package/dist/esm/provider/google.js +16 -0
  17. package/dist/esm/provider/linkedin.js +15 -0
  18. package/dist/esm/provider/magiclink.js +83 -0
  19. package/dist/esm/provider/microsoft.js +15 -0
  20. package/dist/esm/provider/oauth2.js +130 -0
  21. package/dist/esm/provider/password.js +331 -0
  22. package/dist/esm/provider/provider.js +18 -0
  23. package/dist/esm/provider/reddit.js +15 -0
  24. package/dist/esm/provider/slack.js +15 -0
  25. package/dist/esm/provider/spotify.js +15 -0
  26. package/dist/esm/provider/twitch.js +15 -0
  27. package/dist/esm/provider/vercel.js +17 -0
  28. package/dist/esm/random.js +40 -0
  29. package/dist/esm/revocation.js +27 -0
  30. package/dist/esm/storage/memory.js +110 -0
  31. package/dist/esm/storage/storage.js +56 -0
  32. package/dist/esm/storage/turso.js +93 -0
  33. package/dist/esm/storage/unstorage.js +78 -0
  34. package/dist/esm/subject.js +7 -0
  35. package/dist/esm/themes/theme.js +115 -0
  36. package/dist/esm/toolkit/client.js +119 -0
  37. package/dist/esm/toolkit/index.js +25 -0
  38. package/dist/esm/toolkit/providers/facebook.js +11 -0
  39. package/dist/esm/toolkit/providers/github.js +11 -0
  40. package/dist/esm/toolkit/providers/google.js +11 -0
  41. package/dist/esm/toolkit/providers/strategy.js +0 -0
  42. package/dist/esm/toolkit/storage.js +81 -0
  43. package/dist/esm/toolkit/utils.js +18 -0
  44. package/dist/esm/types.js +0 -0
  45. package/dist/esm/ui/base.js +478 -0
  46. package/dist/esm/ui/code.js +186 -0
  47. package/dist/esm/ui/form.js +46 -0
  48. package/dist/esm/ui/icon.js +242 -0
  49. package/dist/esm/ui/magiclink.js +158 -0
  50. package/dist/esm/ui/password.js +435 -0
  51. package/dist/esm/ui/select.js +102 -0
  52. package/dist/esm/util.js +59 -0
  53. package/dist/{allow.d.mts → types/allow.d.ts} +9 -11
  54. package/dist/types/allow.d.ts.map +1 -0
  55. package/dist/types/client.d.ts +462 -0
  56. package/dist/types/client.d.ts.map +1 -0
  57. package/dist/types/core.d.ts +113 -0
  58. package/dist/types/core.d.ts.map +1 -0
  59. package/dist/{error.d.mts → types/error.d.ts} +95 -97
  60. package/dist/types/error.d.ts.map +1 -0
  61. package/dist/types/index.d.ts +2 -0
  62. package/dist/types/index.d.ts.map +1 -0
  63. package/dist/{keys.d.mts → types/keys.d.ts} +20 -24
  64. package/dist/types/keys.d.ts.map +1 -0
  65. package/dist/types/mutex.d.ts +42 -0
  66. package/dist/types/mutex.d.ts.map +1 -0
  67. package/dist/{pkce.d.mts → types/pkce.d.ts} +10 -11
  68. package/dist/types/pkce.d.ts.map +1 -0
  69. package/dist/types/provider/apple.d.ts +197 -0
  70. package/dist/types/provider/apple.d.ts.map +1 -0
  71. package/dist/types/provider/code.d.ts +288 -0
  72. package/dist/types/provider/code.d.ts.map +1 -0
  73. package/dist/types/provider/discord.d.ts +206 -0
  74. package/dist/types/provider/discord.d.ts.map +1 -0
  75. package/dist/types/provider/facebook.d.ts +200 -0
  76. package/dist/types/provider/facebook.d.ts.map +1 -0
  77. package/dist/types/provider/github.d.ts +220 -0
  78. package/dist/types/provider/github.d.ts.map +1 -0
  79. package/dist/types/provider/gitlab.d.ts +180 -0
  80. package/dist/types/provider/gitlab.d.ts.map +1 -0
  81. package/dist/types/provider/google.d.ts +158 -0
  82. package/dist/types/provider/google.d.ts.map +1 -0
  83. package/dist/types/provider/linkedin.d.ts +190 -0
  84. package/dist/types/provider/linkedin.d.ts.map +1 -0
  85. package/dist/types/provider/magiclink.d.ts +141 -0
  86. package/dist/types/provider/magiclink.d.ts.map +1 -0
  87. package/dist/types/provider/microsoft.d.ts +247 -0
  88. package/dist/types/provider/microsoft.d.ts.map +1 -0
  89. package/dist/types/provider/oauth2.d.ts +229 -0
  90. package/dist/types/provider/oauth2.d.ts.map +1 -0
  91. package/dist/types/provider/password.d.ts +408 -0
  92. package/dist/types/provider/password.d.ts.map +1 -0
  93. package/dist/types/provider/provider.d.ts +226 -0
  94. package/dist/types/provider/provider.d.ts.map +1 -0
  95. package/dist/types/provider/reddit.d.ts +159 -0
  96. package/dist/types/provider/reddit.d.ts.map +1 -0
  97. package/dist/types/provider/slack.d.ts +171 -0
  98. package/dist/types/provider/slack.d.ts.map +1 -0
  99. package/dist/types/provider/spotify.d.ts +168 -0
  100. package/dist/types/provider/spotify.d.ts.map +1 -0
  101. package/dist/types/provider/twitch.d.ts +163 -0
  102. package/dist/types/provider/twitch.d.ts.map +1 -0
  103. package/dist/types/provider/vercel.d.ts +294 -0
  104. package/dist/types/provider/vercel.d.ts.map +1 -0
  105. package/dist/{random.d.mts → types/random.d.ts} +4 -6
  106. package/dist/types/random.d.ts.map +1 -0
  107. package/dist/types/revocation.d.ts +76 -0
  108. package/dist/types/revocation.d.ts.map +1 -0
  109. package/dist/{storage/memory.d.mts → types/storage/memory.d.ts} +17 -21
  110. package/dist/types/storage/memory.d.ts.map +1 -0
  111. package/dist/types/storage/storage.d.ts +177 -0
  112. package/dist/types/storage/storage.d.ts.map +1 -0
  113. package/dist/{storage/turso.d.mts → types/storage/turso.d.ts} +4 -8
  114. package/dist/types/storage/turso.d.ts.map +1 -0
  115. package/dist/{storage/unstorage.d.mts → types/storage/unstorage.d.ts} +12 -11
  116. package/dist/types/storage/unstorage.d.ts.map +1 -0
  117. package/dist/types/subject.d.ts +115 -0
  118. package/dist/types/subject.d.ts.map +1 -0
  119. package/dist/types/themes/theme.d.ts +207 -0
  120. package/dist/types/themes/theme.d.ts.map +1 -0
  121. package/dist/types/toolkit/client.d.ts +235 -0
  122. package/dist/types/toolkit/client.d.ts.map +1 -0
  123. package/dist/types/toolkit/index.d.ts +45 -0
  124. package/dist/types/toolkit/index.d.ts.map +1 -0
  125. package/dist/types/toolkit/providers/facebook.d.ts +8 -0
  126. package/dist/types/toolkit/providers/facebook.d.ts.map +1 -0
  127. package/dist/types/toolkit/providers/github.d.ts +8 -0
  128. package/dist/types/toolkit/providers/github.d.ts.map +1 -0
  129. package/dist/types/toolkit/providers/google.d.ts +8 -0
  130. package/dist/types/toolkit/providers/google.d.ts.map +1 -0
  131. package/dist/types/toolkit/providers/strategy.d.ts +38 -0
  132. package/dist/types/toolkit/providers/strategy.d.ts.map +1 -0
  133. package/dist/{toolkit/storage.d.mts → types/toolkit/storage.d.ts} +37 -39
  134. package/dist/types/toolkit/storage.d.ts.map +1 -0
  135. package/dist/{toolkit/utils.d.mts → types/toolkit/utils.d.ts} +2 -4
  136. package/dist/types/toolkit/utils.d.ts.map +1 -0
  137. package/dist/types/types.d.ts +92 -0
  138. package/dist/types/types.d.ts.map +1 -0
  139. package/dist/types/ui/base.d.ts +18 -0
  140. package/dist/types/ui/base.d.ts.map +1 -0
  141. package/dist/types/ui/code.d.ts +43 -0
  142. package/dist/types/ui/code.d.ts.map +1 -0
  143. package/dist/types/ui/form.d.ts +24 -0
  144. package/dist/types/ui/form.d.ts.map +1 -0
  145. package/dist/types/ui/icon.d.ts +60 -0
  146. package/dist/types/ui/icon.d.ts.map +1 -0
  147. package/dist/types/ui/magiclink.d.ts +41 -0
  148. package/dist/types/ui/magiclink.d.ts.map +1 -0
  149. package/dist/types/ui/password.d.ts +43 -0
  150. package/dist/types/ui/password.d.ts.map +1 -0
  151. package/dist/types/ui/select.d.ts +33 -0
  152. package/dist/types/ui/select.d.ts.map +1 -0
  153. package/dist/{util.d.mts → types/util.d.ts} +11 -13
  154. package/dist/types/util.d.ts.map +1 -0
  155. package/package.json +10 -16
  156. package/dist/adapters/node.d.mts +0 -18
  157. package/dist/adapters/node.mjs +0 -69
  158. package/dist/allow.mjs +0 -63
  159. package/dist/client.d.mts +0 -456
  160. package/dist/client.mjs +0 -283
  161. package/dist/core.d.mts +0 -110
  162. package/dist/core.mjs +0 -595
  163. package/dist/error.mjs +0 -237
  164. package/dist/index.d.mts +0 -2
  165. package/dist/index.mjs +0 -3
  166. package/dist/keys.mjs +0 -146
  167. package/dist/mutex.d.mts +0 -44
  168. package/dist/mutex.mjs +0 -110
  169. package/dist/pkce.mjs +0 -157
  170. package/dist/provider/apple.d.mts +0 -111
  171. package/dist/provider/apple.mjs +0 -164
  172. package/dist/provider/code.d.mts +0 -228
  173. package/dist/provider/code.mjs +0 -246
  174. package/dist/provider/discord.d.mts +0 -146
  175. package/dist/provider/discord.mjs +0 -156
  176. package/dist/provider/facebook.d.mts +0 -142
  177. package/dist/provider/facebook.mjs +0 -150
  178. package/dist/provider/github.d.mts +0 -140
  179. package/dist/provider/github.mjs +0 -169
  180. package/dist/provider/gitlab.d.mts +0 -106
  181. package/dist/provider/gitlab.mjs +0 -147
  182. package/dist/provider/google.d.mts +0 -112
  183. package/dist/provider/google.mjs +0 -109
  184. package/dist/provider/linkedin.d.mts +0 -132
  185. package/dist/provider/linkedin.mjs +0 -142
  186. package/dist/provider/magiclink.d.mts +0 -89
  187. package/dist/provider/magiclink.mjs +0 -143
  188. package/dist/provider/microsoft.d.mts +0 -178
  189. package/dist/provider/microsoft.mjs +0 -177
  190. package/dist/provider/oauth2.d.mts +0 -176
  191. package/dist/provider/oauth2.mjs +0 -222
  192. package/dist/provider/passkey.d.mts +0 -104
  193. package/dist/provider/passkey.mjs +0 -320
  194. package/dist/provider/password.d.mts +0 -412
  195. package/dist/provider/password.mjs +0 -363
  196. package/dist/provider/provider.d.mts +0 -227
  197. package/dist/provider/provider.mjs +0 -44
  198. package/dist/provider/reddit.d.mts +0 -107
  199. package/dist/provider/reddit.mjs +0 -127
  200. package/dist/provider/slack.d.mts +0 -114
  201. package/dist/provider/slack.mjs +0 -138
  202. package/dist/provider/spotify.d.mts +0 -113
  203. package/dist/provider/spotify.mjs +0 -135
  204. package/dist/provider/totp.d.mts +0 -112
  205. package/dist/provider/totp.mjs +0 -191
  206. package/dist/provider/twitch.d.mts +0 -108
  207. package/dist/provider/twitch.mjs +0 -131
  208. package/dist/provider/vercel.d.mts +0 -177
  209. package/dist/provider/vercel.mjs +0 -230
  210. package/dist/random.mjs +0 -86
  211. package/dist/revocation.d.mts +0 -55
  212. package/dist/revocation.mjs +0 -63
  213. package/dist/router/context.d.mts +0 -21
  214. package/dist/router/context.mjs +0 -193
  215. package/dist/router/cookies.d.mts +0 -8
  216. package/dist/router/cookies.mjs +0 -13
  217. package/dist/router/index.d.mts +0 -21
  218. package/dist/router/index.mjs +0 -107
  219. package/dist/router/matcher.d.mts +0 -15
  220. package/dist/router/matcher.mjs +0 -76
  221. package/dist/router/middleware/cors.d.mts +0 -15
  222. package/dist/router/middleware/cors.mjs +0 -114
  223. package/dist/router/safe-request.d.mts +0 -52
  224. package/dist/router/safe-request.mjs +0 -160
  225. package/dist/router/types.d.mts +0 -67
  226. package/dist/router/types.mjs +0 -1
  227. package/dist/router/variables.d.mts +0 -12
  228. package/dist/router/variables.mjs +0 -20
  229. package/dist/storage/memory.mjs +0 -125
  230. package/dist/storage/storage.d.mts +0 -179
  231. package/dist/storage/storage.mjs +0 -104
  232. package/dist/storage/turso.mjs +0 -117
  233. package/dist/storage/unstorage.mjs +0 -103
  234. package/dist/subject.d.mts +0 -62
  235. package/dist/subject.mjs +0 -36
  236. package/dist/themes/theme.d.mts +0 -209
  237. package/dist/themes/theme.mjs +0 -120
  238. package/dist/toolkit/client.d.mts +0 -169
  239. package/dist/toolkit/client.mjs +0 -209
  240. package/dist/toolkit/index.d.mts +0 -9
  241. package/dist/toolkit/index.mjs +0 -9
  242. package/dist/toolkit/providers/facebook.d.mts +0 -12
  243. package/dist/toolkit/providers/facebook.mjs +0 -16
  244. package/dist/toolkit/providers/github.d.mts +0 -12
  245. package/dist/toolkit/providers/github.mjs +0 -16
  246. package/dist/toolkit/providers/google.d.mts +0 -12
  247. package/dist/toolkit/providers/google.mjs +0 -20
  248. package/dist/toolkit/providers/strategy.d.mts +0 -40
  249. package/dist/toolkit/providers/strategy.mjs +0 -1
  250. package/dist/toolkit/storage.mjs +0 -157
  251. package/dist/toolkit/utils.mjs +0 -30
  252. package/dist/types.d.mts +0 -94
  253. package/dist/types.mjs +0 -1
  254. package/dist/ui/base.d.mts +0 -30
  255. package/dist/ui/base.mjs +0 -407
  256. package/dist/ui/code.d.mts +0 -43
  257. package/dist/ui/code.mjs +0 -173
  258. package/dist/ui/form.d.mts +0 -32
  259. package/dist/ui/form.mjs +0 -49
  260. package/dist/ui/icon.d.mts +0 -58
  261. package/dist/ui/icon.mjs +0 -247
  262. package/dist/ui/magiclink.d.mts +0 -41
  263. package/dist/ui/magiclink.mjs +0 -152
  264. package/dist/ui/passkey.d.mts +0 -27
  265. package/dist/ui/passkey.mjs +0 -323
  266. package/dist/ui/password.d.mts +0 -42
  267. package/dist/ui/password.mjs +0 -402
  268. package/dist/ui/select.d.mts +0 -34
  269. package/dist/ui/select.mjs +0 -98
  270. package/dist/ui/totp.d.mts +0 -34
  271. package/dist/ui/totp.mjs +0 -270
  272. package/dist/util.mjs +0 -128
package/dist/ui/base.mjs DELETED
@@ -1,407 +0,0 @@
1
- import { getTheme } from "../themes/theme.mjs";
2
- import { render } from "preact-render-to-string";
3
- import { jsx, jsxs } from "preact/jsx-runtime";
4
-
5
- //#region src/ui/base.tsx
6
- const css = `@import url("https://unpkg.com/tailwindcss@3.4.15/src/css/preflight.css");
7
-
8
- :root {
9
- --color-background-dark: #0e0e11;
10
- --color-background-light: #ffffff;
11
- --color-primary-dark: #6772e5;
12
- --color-primary-light: #6772e5;
13
-
14
- --color-background-success-dark: oklch(0.3 0.04 172);
15
- --color-background-success-light: oklch(from var(--color-background-success-dark) 0.83 c h);
16
- --color-success-dark: oklch(from var(--color-background-success-dark) 0.92 c h);
17
- --color-success-light: oklch(from var(--color-background-success-dark) 0.25 c h);
18
-
19
- --color-background-error-dark: oklch(0.32 0.07 15);
20
- --color-background-error-light: oklch(from var(--color-background-error-dark) 0.92 c h);
21
- --color-error-dark: oklch(from var(--color-background-error-dark) 0.92 c h);
22
- --color-error-light: oklch(from var(--color-background-error-dark) 0.25 c h);
23
-
24
- --border-radius: 0;
25
-
26
- --color-background: var(--color-background-dark);
27
- --color-primary: var(--color-primary-dark);
28
-
29
- --color-background-success: var(--color-background-success-dark);
30
- --color-success: var(--color-success-dark);
31
- --color-background-error: var(--color-background-error-dark);
32
- --color-error: var(--color-error-dark);
33
-
34
- @media (prefers-color-scheme: light) {
35
- --color-background: var(--color-background-light);
36
- --color-primary: var(--color-primary-light);
37
-
38
- --color-background-success: var(--color-background-success-light);
39
- --color-success: var(--color-success-light);
40
- --color-background-error: var(--color-background-error-light);
41
- --color-error: var(--color-error-light);
42
- }
43
-
44
- --color-high: oklch(
45
- from var(--color-background) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
46
- );
47
- --color-low: oklch(from var(--color-background) clamp(0, calc((l - 0.714) * 1000), 1) 0 0);
48
- --lightness-high: color-mix(
49
- in oklch,
50
- var(--color-high) 0%,
51
- oklch(var(--color-high) 0 0)
52
- );
53
- --lightness-low: color-mix(
54
- in oklch,
55
- var(--color-low) 0%,
56
- oklch(var(--color-low) 0 0)
57
- );
58
- --font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
59
- "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
60
- --font-scale: 1;
61
-
62
- --font-size-xs: calc(0.75rem * var(--font-scale));
63
- --font-size-sm: calc(0.875rem * var(--font-scale));
64
- --font-size-md: calc(1rem * var(--font-scale));
65
- --font-size-lg: calc(1.125rem * var(--font-scale));
66
- --font-size-xl: calc(1.25rem * var(--font-scale));
67
- --font-size-2xl: calc(1.5rem * var(--font-scale));
68
- }
69
-
70
- [data-component="root"] {
71
- font-family: var(--font-family);
72
- background-color: var(--color-background);
73
- padding: 1rem;
74
- color: white;
75
- position: absolute;
76
- inset: 0;
77
- display: flex;
78
- align-items: center;
79
- justify-content: center;
80
- flex-direction: column;
81
- color: var(--color-high);
82
- }
83
-
84
- [data-component="center"] {
85
- width: 380px;
86
- display: flex;
87
- flex-direction: column;
88
- gap: 1.5rem;
89
- }
90
-
91
- [data-component="center"][data-size="small"] {
92
- width: 300px;
93
- }
94
-
95
- [data-component="link"] {
96
- text-decoration: underline;
97
- text-underline-offset: 0.125rem;
98
- font-weight: 600;
99
- }
100
-
101
- [data-component="label"] {
102
- display: flex;
103
- gap: 0.75rem;
104
- flex-direction: column;
105
- font-size: var(--font-size-xs);
106
- }
107
-
108
- [data-component="logo"] {
109
- margin: 0 auto;
110
- height: 2.5rem;
111
- width: auto;
112
- display: none;
113
- }
114
-
115
- [data-component="logo"][data-mode="light"] {
116
- display: none;
117
- }
118
-
119
- [data-component="logo"][data-mode="dark"] {
120
- display: block;
121
- }
122
-
123
- @media (prefers-color-scheme: light) {
124
- [data-component="logo"][data-mode="light"] {
125
- display: block;
126
- }
127
-
128
- [data-component="logo"][data-mode="dark"] {
129
- display: none;
130
- }
131
- }
132
-
133
- @media (prefers-color-scheme: dark) {
134
- [data-component="logo"][data-mode="dark"] {
135
- display: block;
136
- }
137
- }
138
-
139
- [data-component="logo-default"] {
140
- margin: 0 auto;
141
- height: 2.5rem;
142
- width: auto;
143
- }
144
-
145
- @media (prefers-color-scheme: light) {
146
- [data-component="logo-default"] {
147
- color: var(--color-high);
148
- }
149
- }
150
-
151
- @media (prefers-color-scheme: dark) {
152
- [data-component="logo-default"] {
153
- color: var(--color-high);
154
- }
155
- }
156
-
157
- [data-component="input"] {
158
- width: 100%;
159
- height: 2.5rem;
160
- padding: 0 1rem;
161
- border: 1px solid transparent;
162
- --background: oklch(
163
- from var(--color-background) calc(l + (-0.06 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.03)) c h
164
- );
165
- background: var(--background);
166
- border-color: oklch(
167
- from var(--color-background)
168
- calc(clamp(0.22, l + (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06), 0.88)) c h
169
- );
170
- border-radius: calc(var(--border-radius) * 0.25rem);
171
- font-size: var(--font-size-sm);
172
- outline: none;
173
- }
174
-
175
- [data-component="input"]:focus {
176
- border-color: oklch(
177
- from var(--color-background)
178
- calc(clamp(0.3, l + (-0.2 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.1), 0.7)) c h
179
- );
180
- }
181
-
182
- [data-component="input"]:user-invalid:not(:focus) {
183
- border-color: oklch(0.4 0.09 7.91);
184
- }
185
-
186
- [data-component="button"] {
187
- height: 2.5rem;
188
- cursor: pointer;
189
- border: 0;
190
- font-weight: 500;
191
- font-size: var(--font-size-sm);
192
- border-radius: calc(var(--border-radius) * 0.25rem);
193
- display: flex;
194
- gap: 0.75rem;
195
- align-items: center;
196
- justify-content: center;
197
- background: var(--color-primary);
198
- color: oklch(from var(--color-primary) clamp(0, calc((l - 0.714) * -1000), 1) 0 0);
199
- }
200
-
201
- [data-component="button"][data-color="ghost"] {
202
- background: transparent;
203
- color: var(--color-high);
204
- border: 1px solid
205
- oklch(
206
- from var(--color-background)
207
- calc(clamp(0.22, l + (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06), 0.88)) c h
208
- );
209
- }
210
-
211
- [data-component="button"] [data-slot="icon"] {
212
- width: 16px;
213
- height: 16px;
214
- }
215
-
216
- [data-component="button"] [data-slot="icon"] svg {
217
- width: 100%;
218
- height: 100%;
219
- }
220
-
221
- [data-component="form"] {
222
- max-width: 100%;
223
- display: flex;
224
- flex-direction: column;
225
- gap: 1rem;
226
- margin: 0;
227
- }
228
-
229
- [data-component="form-alert"] {
230
- height: 2.5rem;
231
- display: flex;
232
- align-items: center;
233
- padding: 0 1rem;
234
- border-radius: calc(var(--border-radius) * 0.25rem);
235
- background: var(--color-background-error);
236
- color: var(--color-error);
237
- text-align: left;
238
- font-size: 0.75rem;
239
- gap: 0.5rem;
240
- }
241
-
242
- [data-component="form-alert"][data-color="success"] {
243
- background: var(--color-background-success);
244
- color: var(--color-success);
245
- }
246
-
247
- [data-component="form-alert"][data-color="success"] [data-slot="icon-success"] {
248
- display: block;
249
- }
250
-
251
- [data-component="form-alert"][data-color="success"] [data-slot="icon-danger"] {
252
- display: none;
253
- }
254
-
255
- [data-component="form-alert"]:has([data-slot="message"]:empty) {
256
- display: none;
257
- }
258
-
259
- [data-component="form-alert"] [data-slot="icon-success"],
260
- [data-component="form-alert"] [data-slot="icon-danger"] {
261
- width: 1rem;
262
- height: 1rem;
263
- }
264
-
265
- [data-component="form-alert"] [data-slot="icon-success"] {
266
- display: none;
267
- }
268
-
269
- [data-component="form-footer"] {
270
- display: flex;
271
- gap: 1rem;
272
- font-size: 0.75rem;
273
- align-items: center;
274
- justify-content: center;
275
- }
276
-
277
- [data-component="form-footer"]:has(> :nth-child(2)) {
278
- justify-content: space-between;
279
- }
280
-
281
- [data-component="title"] {
282
- font-size: var(--font-size-2xl);
283
- font-weight: 600;
284
- margin: 0 0 0.5rem 0;
285
- color: var(--color-high);
286
- text-align: center;
287
- }
288
-
289
- [data-component="description"] {
290
- font-size: var(--font-size-sm);
291
- color: var(--color-high);
292
- margin: 0 0 1.5rem 0;
293
- text-align: center;
294
- opacity: 0.8;
295
- }
296
- `;
297
- /**
298
- * Base Layout component that provides the foundational structure for all auth UIs
299
- */
300
- const Layout = ({ children, theme, title, size }) => {
301
- const currentTheme = theme || getTheme();
302
- /**
303
- * Gets a theme value for a specific key and color mode.
304
- */
305
- const getThemeValue = (key, mode) => {
306
- if (!currentTheme?.[key]) return;
307
- if (typeof currentTheme[key] === "string") return currentTheme[key];
308
- return currentTheme[key][mode];
309
- };
310
- /**
311
- * Calculates border radius value based on theme configuration.
312
- */
313
- const getBorderRadius = () => {
314
- switch (currentTheme?.radius) {
315
- case "none": return "0";
316
- case "sm": return "1";
317
- case "md": return "1.25";
318
- case "lg": return "1.5";
319
- case "full": return "1000000000001";
320
- default: return "1";
321
- }
322
- };
323
- /**
324
- * Checks if both light and dark logo variants are available.
325
- */
326
- const hasCustomLogo = Boolean(getThemeValue("logo", "light") && getThemeValue("logo", "dark"));
327
- /**
328
- * CSS custom properties for theming.
329
- */
330
- const themeStyles = [
331
- `--color-background-light: ${getThemeValue("background", "light") || ""}`,
332
- `--color-background-dark: ${getThemeValue("background", "dark") || ""}`,
333
- `--color-primary-light: ${getThemeValue("primary", "light") || ""}`,
334
- `--color-primary-dark: ${getThemeValue("primary", "dark") || ""}`,
335
- `--font-family: ${currentTheme?.font?.family || ""}`,
336
- `--font-scale: ${currentTheme?.font?.scale || ""}`,
337
- `--border-radius: ${getBorderRadius()}`
338
- ].join("; ");
339
- const faviconHtml = currentTheme?.favicon ? `<link href="${currentTheme.favicon}" rel="icon" />` : `
340
- <link href="https://openauth.js.org/favicon.ico" rel="icon" sizes="48x48" />
341
- <link href="https://openauth.js.org/favicon.svg" media="(prefers-color-scheme: light)" rel="icon" />
342
- <link href="https://openauth.js.org/favicon-dark.svg" media="(prefers-color-scheme: dark)" rel="icon" />
343
- <link href="https://openauth.js.org/favicon.svg" rel="shortcut icon" type="image/svg+xml" />
344
- `;
345
- const logoHtml = hasCustomLogo ? `
346
- <img
347
- alt="Logo Light"
348
- data-component="logo"
349
- data-mode="light"
350
- src="${getThemeValue("logo", "light") || ""}"
351
- />
352
- <img
353
- alt="Logo Dark"
354
- data-component="logo"
355
- data-mode="dark"
356
- src="${getThemeValue("logo", "dark") || ""}"
357
- />
358
- ` : `
359
- <svg
360
- aria-label="Draft Auth Logo"
361
- data-component="logo-default"
362
- fill="none"
363
- height="51"
364
- viewBox="0 0 51 51"
365
- width="51"
366
- xmlns="http://www.w3.org/2000/svg"
367
- >
368
- <title>Draft Auth Logo</title>
369
- <path
370
- d="M0 50.2303V0.12854H50.1017V50.2303H0ZM3.08002 11.8326H11.7041V3.20856H3.08002V11.8326ZM14.8526 11.8326H23.4766V3.20856H14.8526V11.8326ZM26.5566 11.8326H35.1807V3.20856H26.5566V11.8326ZM38.3292 11.8326H47.0217V3.20856H38.3292V11.8326ZM3.08002 23.6052H11.7041V14.9811H3.08002V23.6052ZM14.8526 23.6052H23.4766V14.9811H14.8526V23.6052ZM26.5566 23.6052H35.1807V14.9811H26.5566V23.6052ZM38.3292 23.6052H47.0217V14.9811H38.3292V23.6052ZM3.08002 35.3092H11.7041V26.6852H3.08002V35.3092ZM14.8526 35.3092H23.4766V26.6852H14.8526V35.3092ZM26.5566 35.3092H35.1807V26.6852H26.5566V35.3092ZM38.3292 35.3092H47.0217V26.6852H38.3292V35.3092ZM3.08002 47.1502H11.7041V38.3893H3.08002V47.1502ZM14.8526 47.1502H23.4766V38.3893H14.8526V47.1502ZM26.5566 47.1502H35.1807V38.3893H26.5566V47.1502ZM38.3292 47.1502H47.0217V38.3893H38.3292V47.1502Z"
371
- fill="currentColor"
372
- />
373
- </svg>
374
- `;
375
- return /* @__PURE__ */ jsxs("html", {
376
- lang: "en",
377
- style: themeStyles,
378
- children: [/* @__PURE__ */ jsxs("head", { children: [
379
- /* @__PURE__ */ jsx("title", { children: title || currentTheme?.title || "Draft Auth" }),
380
- /* @__PURE__ */ jsx("meta", { charset: "utf-8" }),
381
- /* @__PURE__ */ jsx("meta", {
382
- content: "width=device-width, initial-scale=1",
383
- name: "viewport"
384
- }),
385
- /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: faviconHtml } }),
386
- /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: css } }),
387
- currentTheme?.css && /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: currentTheme.css } })
388
- ] }), /* @__PURE__ */ jsx("body", { children: /* @__PURE__ */ jsx("div", {
389
- "data-component": "root",
390
- children: /* @__PURE__ */ jsxs("div", {
391
- "data-component": "center",
392
- "data-size": size || "",
393
- children: [/* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: logoHtml } }), children]
394
- })
395
- }) })]
396
- });
397
- };
398
- /**
399
- * Helper function to render a Preact component to HTML string
400
- */
401
- const renderToHTML = (component) => {
402
- if (!component) return "";
403
- return render(component);
404
- };
405
-
406
- //#endregion
407
- export { Layout, renderToHTML };
@@ -1,43 +0,0 @@
1
- import { CodeProviderOptions } from "../provider/code.mjs";
2
-
3
- //#region src/ui/code.d.ts
4
-
5
- /**
6
- * Type for customizable UI copy text
7
- */
8
- interface CodeUICopy {
9
- readonly email_placeholder: string;
10
- readonly email_invalid: string;
11
- readonly button_continue: string;
12
- readonly code_info: string;
13
- readonly code_placeholder: string;
14
- readonly code_invalid: string;
15
- readonly code_sent: string;
16
- readonly code_resent: string;
17
- readonly code_didnt_get: string;
18
- readonly code_resend: string;
19
- }
20
- /**
21
- * Input mode for the contact field
22
- */
23
- type CodeUIMode = "email" | "phone";
24
- /**
25
- * Configuration options for the CodeUI component
26
- */
27
- interface CodeUIOptions extends Pick<CodeProviderOptions, "sendCode"> {
28
- /**
29
- * Input mode determining the type of contact information to collect
30
- * @default "email"
31
- */
32
- readonly mode?: CodeUIMode;
33
- /**
34
- * Custom text copy for UI labels, messages, and errors
35
- */
36
- readonly copy?: Partial<CodeUICopy>;
37
- }
38
- /**
39
- * Creates a complete UI configuration for PIN code authentication
40
- */
41
- declare const CodeUI: (options: CodeUIOptions) => CodeProviderOptions;
42
- //#endregion
43
- export { CodeUI, CodeUICopy, CodeUIMode, CodeUIOptions };
package/dist/ui/code.mjs DELETED
@@ -1,173 +0,0 @@
1
- import { run } from "../util.mjs";
2
- import { Layout, renderToHTML } from "./base.mjs";
3
- import { FormAlert } from "./form.mjs";
4
- import { jsx, jsxs } from "preact/jsx-runtime";
5
-
6
- //#region src/ui/code.tsx
7
- /**
8
- * Default text copy for the PIN code authentication UI
9
- */
10
- const DEFAULT_COPY = {
11
- email_placeholder: "Email",
12
- email_invalid: "Email address is not valid",
13
- button_continue: "Continue",
14
- code_info: "We'll send a pin code to your email.",
15
- code_placeholder: "Code",
16
- code_invalid: "Invalid code",
17
- code_sent: "Code sent to ",
18
- code_resent: "Code resent to ",
19
- code_didnt_get: "Didn't get code?",
20
- code_resend: "Resend"
21
- };
22
- /**
23
- * Gets the appropriate error message for display
24
- */
25
- const getErrorMessage = (error, copy) => {
26
- if (!error?.type) return void 0;
27
- switch (error.type) {
28
- case "invalid_code": return copy.code_invalid;
29
- case "invalid_claim": return copy.email_invalid;
30
- }
31
- };
32
- /**
33
- * Gets the appropriate success message for display
34
- */
35
- const getSuccessMessage = (state, copy) => {
36
- if (state.type === "start" || !state.claims) return void 0;
37
- const contact = state.claims.email || state.claims.phone || "";
38
- return {
39
- message: `${state.resend ? copy.code_resent : copy.code_sent}${contact}`,
40
- contact
41
- };
42
- };
43
- /**
44
- * Creates a complete UI configuration for PIN code authentication
45
- */
46
- const CodeUI = (options) => {
47
- const copy = {
48
- ...DEFAULT_COPY,
49
- ...options.copy
50
- };
51
- const mode = options.mode || "email";
52
- /**
53
- * Renders the start form for collecting contact information
54
- */
55
- const renderStart = (form, error, state) => {
56
- const success = getSuccessMessage(state || { type: "start" }, copy);
57
- return /* @__PURE__ */ jsx(Layout, { children: /* @__PURE__ */ jsxs("form", {
58
- "data-component": "form",
59
- method: "post",
60
- children: [
61
- run(() => {
62
- if (success) return /* @__PURE__ */ jsx(FormAlert, {
63
- message: success.message,
64
- color: "success"
65
- });
66
- return /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error, copy) });
67
- }),
68
- /* @__PURE__ */ jsx("input", {
69
- "data-component": "input",
70
- type: mode === "email" ? "email" : "tel",
71
- name: mode,
72
- placeholder: copy.email_placeholder,
73
- value: form?.get(mode)?.toString() || "",
74
- autoComplete: mode,
75
- required: true
76
- }),
77
- /* @__PURE__ */ jsx("input", {
78
- type: "hidden",
79
- name: "action",
80
- value: "request"
81
- }),
82
- /* @__PURE__ */ jsx("button", {
83
- "data-component": "button",
84
- type: "submit",
85
- children: copy.button_continue
86
- }),
87
- /* @__PURE__ */ jsx("p", {
88
- "data-component": "description",
89
- children: copy.code_info
90
- })
91
- ]
92
- }) });
93
- };
94
- /**
95
- * Renders the code verification form
96
- */
97
- const renderCode = (_form, error, state) => {
98
- const success = getSuccessMessage(state, copy);
99
- const contact = state.type === "code" ? state.claims?.[mode] || "" : "";
100
- return /* @__PURE__ */ jsxs(Layout, { children: [/* @__PURE__ */ jsxs("form", {
101
- "data-component": "form",
102
- method: "post",
103
- children: [
104
- run(() => {
105
- if (success) return /* @__PURE__ */ jsx(FormAlert, {
106
- message: success.message,
107
- color: "success"
108
- });
109
- return /* @__PURE__ */ jsx(FormAlert, { message: getErrorMessage(error, copy) });
110
- }),
111
- /* @__PURE__ */ jsx("input", {
112
- name: "action",
113
- type: "hidden",
114
- value: "verify"
115
- }),
116
- /* @__PURE__ */ jsx("input", {
117
- "data-component": "input",
118
- type: "text",
119
- name: "code",
120
- placeholder: copy.code_placeholder,
121
- "aria-label": "6-digit verification code",
122
- autoComplete: "one-time-code",
123
- inputMode: "numeric",
124
- maxLength: 6,
125
- minLength: 6,
126
- pattern: "[0-9]{6}",
127
- required: true
128
- }),
129
- /* @__PURE__ */ jsx("button", {
130
- "data-component": "button",
131
- type: "submit",
132
- children: copy.button_continue
133
- })
134
- ]
135
- }), /* @__PURE__ */ jsxs("form", {
136
- method: "post",
137
- children: [
138
- /* @__PURE__ */ jsx("input", {
139
- name: "action",
140
- type: "hidden",
141
- value: "resend"
142
- }),
143
- /* @__PURE__ */ jsx("input", {
144
- name: mode,
145
- type: "hidden",
146
- value: contact
147
- }),
148
- /* @__PURE__ */ jsx("div", {
149
- "data-component": "form-footer",
150
- children: /* @__PURE__ */ jsxs("span", { children: [
151
- copy.code_didnt_get,
152
- " ",
153
- /* @__PURE__ */ jsx("button", {
154
- type: "submit",
155
- "data-component": "link",
156
- children: copy.code_resend
157
- })
158
- ] })
159
- })
160
- ]
161
- })] });
162
- };
163
- return {
164
- sendCode: options.sendCode,
165
- request: async (_req, state, form, error) => {
166
- const html = renderToHTML(state.type === "start" ? renderStart(form, error, state) : renderCode(form, error, state));
167
- return new Response(html, { headers: { "Content-Type": "text/html" } });
168
- }
169
- };
170
- };
171
-
172
- //#endregion
173
- export { CodeUI };
@@ -1,32 +0,0 @@
1
- import { ComponentChildren } from "preact";
2
-
3
- //#region src/ui/form.d.ts
4
-
5
- /**
6
- * Alert color variant determining the visual style and icon.
7
- */
8
- type FormAlertColor = "danger" | "success";
9
- /**
10
- * Props for the FormAlert component.
11
- */
12
- interface FormAlertProps {
13
- /**
14
- * The message text to display in the alert.
15
- * If not provided, the alert will not render.
16
- */
17
- readonly message?: string;
18
- /**
19
- * Visual style variant for the alert.
20
- * @default "danger"
21
- */
22
- readonly color?: FormAlertColor;
23
- }
24
- /**
25
- * Form alert component that displays error or success messages.
26
- */
27
- declare const FormAlert: ({
28
- message,
29
- color
30
- }: FormAlertProps) => ComponentChildren;
31
- //#endregion
32
- export { FormAlert, FormAlertColor, FormAlertProps };
package/dist/ui/form.mjs DELETED
@@ -1,49 +0,0 @@
1
- import { jsx, jsxs } from "preact/jsx-runtime";
2
-
3
- //#region src/ui/form.tsx
4
- /**
5
- * Form alert component that displays error or success messages.
6
- */
7
- const FormAlert = ({ message, color = "danger" }) => {
8
- return /* @__PURE__ */ jsxs("div", {
9
- "data-component": "form-alert",
10
- "data-color": color,
11
- children: [
12
- /* @__PURE__ */ jsx("svg", {
13
- "aria-hidden": "true",
14
- "data-slot": "icon-success",
15
- xmlns: "http://www.w3.org/2000/svg",
16
- fill: "none",
17
- viewBox: "0 0 24 24",
18
- "stroke-width": "1.5",
19
- stroke: "currentColor",
20
- children: /* @__PURE__ */ jsx("path", {
21
- "stroke-linecap": "round",
22
- "stroke-linejoin": "round",
23
- d: "M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
24
- })
25
- }),
26
- /* @__PURE__ */ jsx("svg", {
27
- "aria-hidden": "true",
28
- "data-slot": "icon-danger",
29
- xmlns: "http://www.w3.org/2000/svg",
30
- fill: "none",
31
- viewBox: "0 0 24 24",
32
- "stroke-width": "1.5",
33
- stroke: "currentColor",
34
- children: /* @__PURE__ */ jsx("path", {
35
- "stroke-linecap": "round",
36
- "stroke-linejoin": "round",
37
- d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
38
- })
39
- }),
40
- /* @__PURE__ */ jsx("span", {
41
- "data-slot": "message",
42
- children: message
43
- })
44
- ]
45
- });
46
- };
47
-
48
- //#endregion
49
- export { FormAlert };