@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
@@ -0,0 +1,478 @@
1
+ // src/themes/theme.ts
2
+ var THEME_DRAFTAUTH = {
3
+ title: "Draft Auth",
4
+ radius: "none",
5
+ background: {
6
+ dark: "black",
7
+ light: "white"
8
+ },
9
+ primary: {
10
+ dark: "white",
11
+ light: "black"
12
+ },
13
+ font: {
14
+ family: "IBM Plex Sans, sans-serif"
15
+ },
16
+ css: `
17
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@100;200;300;400;500;600;700&display=swap');
18
+ `
19
+ };
20
+ var getTheme = () => {
21
+ return globalThis.DRAFTAUTH_THEME || THEME_DRAFTAUTH;
22
+ };
23
+
24
+ // src/ui/ui.css
25
+ var ui_default = `@import url("https://unpkg.com/tailwindcss@3.4.15/src/css/preflight.css");
26
+
27
+ :root {
28
+ --color-background-dark: #0e0e11;
29
+ --color-background-light: #ffffff;
30
+ --color-primary-dark: #6772e5;
31
+ --color-primary-light: #6772e5;
32
+
33
+ --color-background-success-dark: oklch(0.3 0.04 172);
34
+ --color-background-success-light: oklch(
35
+ from var(--color-background-success-dark) 0.83 c h
36
+ );
37
+ --color-success-dark: oklch(
38
+ from var(--color-background-success-dark) 0.92 c h
39
+ );
40
+ --color-success-light: oklch(
41
+ from var(--color-background-success-dark) 0.25 c h
42
+ );
43
+
44
+ --color-background-error-dark: oklch(0.32 0.07 15);
45
+ --color-background-error-light: oklch(
46
+ from var(--color-background-error-dark) 0.92 c h
47
+ );
48
+ --color-error-dark: oklch(from var(--color-background-error-dark) 0.92 c h);
49
+ --color-error-light: oklch(from var(--color-background-error-dark) 0.25 c h);
50
+
51
+ --border-radius: 0;
52
+
53
+ --color-background: var(--color-background-dark);
54
+ --color-primary: var(--color-primary-dark);
55
+
56
+ --color-background-success: var(--color-background-success-dark);
57
+ --color-success: var(--color-success-dark);
58
+ --color-background-error: var(--color-background-error-dark);
59
+ --color-error: var(--color-error-dark);
60
+
61
+ @media (prefers-color-scheme: light) {
62
+ --color-background: var(--color-background-light);
63
+ --color-primary: var(--color-primary-light);
64
+
65
+ --color-background-success: var(--color-background-success-light);
66
+ --color-success: var(--color-success-light);
67
+ --color-background-error: var(--color-background-error-light);
68
+ --color-error: var(--color-error-light);
69
+ }
70
+
71
+ --color-high: oklch(
72
+ from var(--color-background) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
73
+ );
74
+ --color-low: oklch(
75
+ from var(--color-background) clamp(0, calc((l - 0.714) * 1000), 1) 0 0
76
+ );
77
+ --lightness-high: color-mix(
78
+ in oklch,
79
+ var(--color-high) 0%,
80
+ oklch(var(--color-high) 0 0)
81
+ );
82
+ --lightness-low: color-mix(
83
+ in oklch,
84
+ var(--color-low) 0%,
85
+ oklch(var(--color-low) 0 0)
86
+ );
87
+ --font-family:
88
+ ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
89
+ "Segoe UI Symbol", "Noto Color Emoji";
90
+ --font-scale: 1;
91
+
92
+ --font-size-xs: calc(0.75rem * var(--font-scale));
93
+ --font-size-sm: calc(0.875rem * var(--font-scale));
94
+ --font-size-md: calc(1rem * var(--font-scale));
95
+ --font-size-lg: calc(1.125rem * var(--font-scale));
96
+ --font-size-xl: calc(1.25rem * var(--font-scale));
97
+ --font-size-2xl: calc(1.5rem * var(--font-scale));
98
+ }
99
+
100
+ [data-component="root"] {
101
+ font-family: var(--font-family);
102
+ background-color: var(--color-background);
103
+ padding: 1rem;
104
+ color: white;
105
+ position: absolute;
106
+ inset: 0;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ flex-direction: column;
111
+ user-select: none;
112
+ color: var(--color-high);
113
+ }
114
+
115
+ [data-component="center"] {
116
+ width: 380px;
117
+ display: flex;
118
+ flex-direction: column;
119
+ gap: 1.5rem;
120
+
121
+ &[data-size="small"] {
122
+ width: 300px;
123
+ }
124
+ }
125
+
126
+ [data-component="link"] {
127
+ text-decoration: underline;
128
+ text-underline-offset: 0.125rem;
129
+ font-weight: 600;
130
+ }
131
+
132
+ [data-component="label"] {
133
+ display: flex;
134
+ gap: 0.75rem;
135
+ flex-direction: column;
136
+ font-size: var(--font-size-xs);
137
+ }
138
+
139
+ [data-component="logo"] {
140
+ margin: 0 auto;
141
+ height: 2.5rem;
142
+ width: auto;
143
+ display: none;
144
+
145
+ @media (prefers-color-scheme: light) {
146
+ &[data-mode="light"] {
147
+ display: block;
148
+ }
149
+ }
150
+
151
+ @media (prefers-color-scheme: dark) {
152
+ &[data-mode="dark"] {
153
+ display: block;
154
+ }
155
+ }
156
+ }
157
+
158
+ [data-component="logo-default"] {
159
+ margin: 0 auto;
160
+ height: 2.5rem;
161
+ width: auto;
162
+
163
+ @media (prefers-color-scheme: light) {
164
+ color: var(--color-high);
165
+ }
166
+
167
+ @media (prefers-color-scheme: dark) {
168
+ color: var(--color-high);
169
+ }
170
+ }
171
+
172
+ [data-component="input"] {
173
+ width: 100%;
174
+ height: 2.5rem;
175
+ padding: 0 1rem;
176
+ border: 1px solid transparent;
177
+ --background: oklch(
178
+ from var(--color-background)
179
+ calc(l + (-0.06 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.03)) c h
180
+ );
181
+ background: var(--background);
182
+ border-color: oklch(
183
+ from var(--color-background)
184
+ calc(
185
+ clamp(
186
+ 0.22,
187
+ l +
188
+ (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
189
+ 0.88
190
+ )
191
+ )
192
+ c h
193
+ );
194
+ border-radius: calc(var(--border-radius) * 0.25rem);
195
+ font-size: var(--font-size-sm);
196
+ outline: none;
197
+
198
+ &:focus {
199
+ border-color: oklch(
200
+ from var(--color-background)
201
+ calc(
202
+ clamp(
203
+ 0.3,
204
+ l +
205
+ (-0.2 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.1),
206
+ 0.7
207
+ )
208
+ )
209
+ c h
210
+ );
211
+ }
212
+
213
+ &:user-invalid:not(:focus) {
214
+ border-color: oklch(0.4 0.09 7.91);
215
+ }
216
+ }
217
+
218
+ [data-component="button"] {
219
+ height: 2.5rem;
220
+ cursor: pointer;
221
+ border: 0;
222
+ font-weight: 500;
223
+ font-size: var(--font-size-sm);
224
+ border-radius: calc(var(--border-radius) * 0.25rem);
225
+ display: flex;
226
+ gap: 0.75rem;
227
+ align-items: center;
228
+ justify-content: center;
229
+ background: var(--color-primary);
230
+ color: oklch(
231
+ from var(--color-primary) clamp(0, calc((l - 0.714) * -1000), 1) 0 0
232
+ );
233
+
234
+ &[data-color="ghost"] {
235
+ background: transparent;
236
+ color: var(--color-high);
237
+ border: 1px solid
238
+ oklch(
239
+ from var(--color-background)
240
+ calc(
241
+ clamp(
242
+ 0.22,
243
+ l +
244
+ (-0.12 * clamp(0, calc((l - 0.714) * 1000), 1) + 0.06),
245
+ 0.88
246
+ )
247
+ )
248
+ c h
249
+ );
250
+ }
251
+
252
+ [data-slot="icon"] {
253
+ width: 16px;
254
+ height: 16px;
255
+
256
+ svg {
257
+ width: 100%;
258
+ height: 100%;
259
+ }
260
+ }
261
+ }
262
+
263
+ [data-component="form"] {
264
+ max-width: 100%;
265
+ display: flex;
266
+ flex-direction: column;
267
+ gap: 1rem;
268
+ margin: 0;
269
+ }
270
+
271
+ [data-component="form-alert"] {
272
+ height: 2.5rem;
273
+ display: flex;
274
+ align-items: center;
275
+ padding: 0 1rem;
276
+ border-radius: calc(var(--border-radius) * 0.25rem);
277
+ background: var(--color-background-error);
278
+ color: var(--color-error);
279
+ text-align: left;
280
+ font-size: 0.75rem;
281
+ gap: 0.5rem;
282
+
283
+ &[data-color="success"] {
284
+ background: var(--color-background-success);
285
+ color: var(--color-success);
286
+
287
+ [data-slot="icon-success"] {
288
+ display: block;
289
+ }
290
+ [data-slot="icon-danger"] {
291
+ display: none;
292
+ }
293
+ }
294
+
295
+ &:has([data-slot="message"]:empty) {
296
+ display: none;
297
+ }
298
+
299
+ [data-slot="icon-success"],
300
+ [data-slot="icon-danger"] {
301
+ width: 1rem;
302
+ height: 1rem;
303
+ }
304
+ [data-slot="icon-success"] {
305
+ display: none;
306
+ }
307
+ }
308
+
309
+ [data-component="form-footer"] {
310
+ display: flex;
311
+ gap: 1rem;
312
+ font-size: 0.75rem;
313
+ align-items: center;
314
+ justify-content: center;
315
+
316
+ &:has(> :nth-child(2)) {
317
+ justify-content: space-between;
318
+ }
319
+ }
320
+
321
+ [data-component="title"] {
322
+ font-size: var(--font-size-2xl);
323
+ font-weight: 600;
324
+ margin: 0 0 0.5rem 0;
325
+ color: var(--color-high);
326
+ text-align: center;
327
+ }
328
+
329
+ [data-component="description"] {
330
+ font-size: var(--font-size-sm);
331
+ color: var(--color-high);
332
+ margin: 0 0 1.5rem 0;
333
+ text-align: center;
334
+ opacity: 0.8;
335
+ }
336
+ `;
337
+
338
+ // src/ui/base.tsx
339
+ import { jsxDEV, Fragment } from "hono/jsx/jsx-dev-runtime";
340
+ var ICON_DRAFTAUTH = /* @__PURE__ */ jsxDEV("svg", {
341
+ "aria-label": "Draft Auth Logo",
342
+ "data-component": "logo-default",
343
+ fill: "none",
344
+ height: "51",
345
+ viewBox: "0 0 51 51",
346
+ width: "51",
347
+ xmlns: "http://www.w3.org/2000/svg",
348
+ children: [
349
+ /* @__PURE__ */ jsxDEV("title", {
350
+ children: "Draft Auth Logo"
351
+ }, undefined, false, undefined, this),
352
+ /* @__PURE__ */ jsxDEV("path", {
353
+ 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",
354
+ fill: "currentColor"
355
+ }, undefined, false, undefined, this)
356
+ ]
357
+ }, undefined, true, undefined, this);
358
+ var Layout = (props) => {
359
+ const currentTheme = props.theme || getTheme();
360
+ const getThemeValue = (key, mode) => {
361
+ if (!currentTheme?.[key]) {
362
+ return;
363
+ }
364
+ if (typeof currentTheme[key] === "string") {
365
+ return currentTheme[key];
366
+ }
367
+ return currentTheme[key][mode];
368
+ };
369
+ const getBorderRadius = () => {
370
+ switch (currentTheme?.radius) {
371
+ case "none":
372
+ return "0";
373
+ case "sm":
374
+ return "1";
375
+ case "md":
376
+ return "1.25";
377
+ case "lg":
378
+ return "1.5";
379
+ case "full":
380
+ return "1000000000001";
381
+ default:
382
+ return "1";
383
+ }
384
+ };
385
+ const hasCustomLogo = Boolean(getThemeValue("logo", "light") && getThemeValue("logo", "dark"));
386
+ return /* @__PURE__ */ jsxDEV("html", {
387
+ lang: "en",
388
+ style: {
389
+ "--color-background-light": getThemeValue("background", "light"),
390
+ "--color-background-dark": getThemeValue("background", "dark"),
391
+ "--color-primary-light": getThemeValue("primary", "light"),
392
+ "--color-primary-dark": getThemeValue("primary", "dark"),
393
+ "--font-family": currentTheme?.font?.family,
394
+ "--font-scale": currentTheme?.font?.scale,
395
+ "--border-radius": getBorderRadius()
396
+ },
397
+ children: [
398
+ /* @__PURE__ */ jsxDEV("head", {
399
+ children: [
400
+ /* @__PURE__ */ jsxDEV("title", {
401
+ children: props.title || currentTheme?.title || "Draft Auth"
402
+ }, undefined, false, undefined, this),
403
+ /* @__PURE__ */ jsxDEV("meta", {
404
+ charset: "utf-8"
405
+ }, undefined, false, undefined, this),
406
+ /* @__PURE__ */ jsxDEV("meta", {
407
+ name: "viewport",
408
+ content: "width=device-width, initial-scale=1"
409
+ }, undefined, false, undefined, this),
410
+ currentTheme?.favicon ? /* @__PURE__ */ jsxDEV("link", {
411
+ rel: "icon",
412
+ href: currentTheme.favicon
413
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(Fragment, {
414
+ children: [
415
+ /* @__PURE__ */ jsxDEV("link", {
416
+ rel: "icon",
417
+ href: "https://openauth.js.org/favicon.ico",
418
+ sizes: "48x48"
419
+ }, undefined, false, undefined, this),
420
+ /* @__PURE__ */ jsxDEV("link", {
421
+ rel: "icon",
422
+ href: "https://openauth.js.org/favicon.svg",
423
+ media: "(prefers-color-scheme: light)"
424
+ }, undefined, false, undefined, this),
425
+ /* @__PURE__ */ jsxDEV("link", {
426
+ rel: "icon",
427
+ href: "https://openauth.js.org/favicon-dark.svg",
428
+ media: "(prefers-color-scheme: dark)"
429
+ }, undefined, false, undefined, this),
430
+ /* @__PURE__ */ jsxDEV("link", {
431
+ rel: "shortcut icon",
432
+ href: "https://openauth.js.org/favicon.svg",
433
+ type: "image/svg+xml"
434
+ }, undefined, false, undefined, this)
435
+ ]
436
+ }, undefined, true, undefined, this),
437
+ /* @__PURE__ */ jsxDEV("style", {
438
+ dangerouslySetInnerHTML: { __html: ui_default }
439
+ }, undefined, false, undefined, this),
440
+ currentTheme?.css && /* @__PURE__ */ jsxDEV("style", {
441
+ dangerouslySetInnerHTML: { __html: currentTheme.css }
442
+ }, undefined, false, undefined, this)
443
+ ]
444
+ }, undefined, true, undefined, this),
445
+ /* @__PURE__ */ jsxDEV("body", {
446
+ children: /* @__PURE__ */ jsxDEV("div", {
447
+ "data-component": "root",
448
+ children: /* @__PURE__ */ jsxDEV("div", {
449
+ "data-component": "center",
450
+ "data-size": props.size,
451
+ children: [
452
+ hasCustomLogo ? /* @__PURE__ */ jsxDEV(Fragment, {
453
+ children: [
454
+ /* @__PURE__ */ jsxDEV("img", {
455
+ "data-component": "logo",
456
+ src: getThemeValue("logo", "light"),
457
+ "data-mode": "light",
458
+ alt: "Logo Light"
459
+ }, undefined, false, undefined, this),
460
+ /* @__PURE__ */ jsxDEV("img", {
461
+ "data-component": "logo",
462
+ src: getThemeValue("logo", "dark"),
463
+ "data-mode": "dark",
464
+ alt: "Logo Dark"
465
+ }, undefined, false, undefined, this)
466
+ ]
467
+ }, undefined, true, undefined, this) : ICON_DRAFTAUTH,
468
+ props.children
469
+ ]
470
+ }, undefined, true, undefined, this)
471
+ }, undefined, false, undefined, this)
472
+ }, undefined, false, undefined, this)
473
+ ]
474
+ }, undefined, true, undefined, this);
475
+ };
476
+ export {
477
+ Layout
478
+ };
@@ -0,0 +1,186 @@
1
+ // src/ui/code.tsx
2
+ import { UnknownStateError } from "../error";
3
+ import { run } from "../util";
4
+ import { Layout } from "./base";
5
+ import { FormAlert } from "./form";
6
+ import { jsxDEV } from "hono/jsx/jsx-dev-runtime";
7
+ var DEFAULT_COPY = {
8
+ email_placeholder: "Email",
9
+ email_invalid: "Email address is not valid",
10
+ button_continue: "Continue",
11
+ code_info: "We'll send a pin code to your email.",
12
+ code_placeholder: "Code",
13
+ code_invalid: "Invalid code",
14
+ code_sent: "Code sent to ",
15
+ code_resent: "Code resent to ",
16
+ code_didnt_get: "Didn't get code?",
17
+ code_resend: "Resend"
18
+ };
19
+ var getErrorMessage = (error, copy) => {
20
+ if (!error?.type)
21
+ return;
22
+ switch (error.type) {
23
+ case "invalid_code":
24
+ return copy.code_invalid;
25
+ case "invalid_claim":
26
+ return copy.email_invalid;
27
+ }
28
+ };
29
+ var getSuccessMessage = (state, copy) => {
30
+ if (state.type === "start" || !state.claims)
31
+ return;
32
+ const contact = state.claims.email || state.claims.phone || "";
33
+ const prefix = state.resend ? copy.code_resent : copy.code_sent;
34
+ return {
35
+ message: `${prefix}${contact}`,
36
+ contact
37
+ };
38
+ };
39
+ var CodeUI = (options) => {
40
+ const copy = {
41
+ ...DEFAULT_COPY,
42
+ ...options.copy
43
+ };
44
+ const mode = options.mode || "email";
45
+ return {
46
+ sendCode: options.sendCode,
47
+ request: async (_req, state, form, error) => {
48
+ if (state.type === "start") {
49
+ const success = getSuccessMessage(state || { type: "start" }, copy);
50
+ const jsx = /* @__PURE__ */ jsxDEV(Layout, {
51
+ children: /* @__PURE__ */ jsxDEV("form", {
52
+ "data-component": "form",
53
+ method: "post",
54
+ children: [
55
+ run(() => {
56
+ if (success) {
57
+ return /* @__PURE__ */ jsxDEV(FormAlert, {
58
+ message: success.message,
59
+ color: "success"
60
+ }, undefined, false, undefined, this);
61
+ }
62
+ return /* @__PURE__ */ jsxDEV(FormAlert, {
63
+ message: getErrorMessage(error, copy)
64
+ }, undefined, false, undefined, this);
65
+ }),
66
+ /* @__PURE__ */ jsxDEV("input", {
67
+ "data-component": "input",
68
+ type: mode === "email" ? "email" : "tel",
69
+ name: mode,
70
+ placeholder: copy.email_placeholder,
71
+ value: form?.get(mode)?.toString() || "",
72
+ autoComplete: mode,
73
+ required: true
74
+ }, undefined, false, undefined, this),
75
+ /* @__PURE__ */ jsxDEV("input", {
76
+ type: "hidden",
77
+ name: "action",
78
+ value: "request"
79
+ }, undefined, false, undefined, this),
80
+ /* @__PURE__ */ jsxDEV("button", {
81
+ "data-component": "button",
82
+ type: "submit",
83
+ children: copy.button_continue
84
+ }, undefined, false, undefined, this),
85
+ /* @__PURE__ */ jsxDEV("p", {
86
+ "data-component": "description",
87
+ children: copy.code_info
88
+ }, undefined, false, undefined, this)
89
+ ]
90
+ }, undefined, true, undefined, this)
91
+ }, undefined, false, undefined, this);
92
+ return new Response(jsx.toString(), {
93
+ headers: {
94
+ "Content-Type": "text/html"
95
+ }
96
+ });
97
+ }
98
+ if (state.type === "code") {
99
+ const success = getSuccessMessage(state, copy);
100
+ const contact = state.type === "code" ? state.claims?.[mode] || "" : "";
101
+ const jsx = /* @__PURE__ */ jsxDEV(Layout, {
102
+ children: [
103
+ /* @__PURE__ */ jsxDEV("form", {
104
+ "data-component": "form",
105
+ method: "post",
106
+ children: [
107
+ run(() => {
108
+ if (success) {
109
+ return /* @__PURE__ */ jsxDEV(FormAlert, {
110
+ message: success.message,
111
+ color: "success"
112
+ }, undefined, false, undefined, this);
113
+ }
114
+ return /* @__PURE__ */ jsxDEV(FormAlert, {
115
+ message: getErrorMessage(error, copy)
116
+ }, undefined, false, undefined, this);
117
+ }),
118
+ /* @__PURE__ */ jsxDEV("input", {
119
+ name: "action",
120
+ type: "hidden",
121
+ value: "verify"
122
+ }, undefined, false, undefined, this),
123
+ /* @__PURE__ */ jsxDEV("input", {
124
+ "data-component": "input",
125
+ type: "text",
126
+ name: "code",
127
+ placeholder: copy.code_placeholder,
128
+ "aria-label": "6-digit verification code",
129
+ autoComplete: "one-time-code",
130
+ inputMode: "numeric",
131
+ maxLength: 6,
132
+ minLength: 6,
133
+ pattern: "[0-9]{6}",
134
+ required: true
135
+ }, undefined, false, undefined, this),
136
+ /* @__PURE__ */ jsxDEV("button", {
137
+ "data-component": "button",
138
+ type: "submit",
139
+ children: copy.button_continue
140
+ }, undefined, false, undefined, this)
141
+ ]
142
+ }, undefined, true, undefined, this),
143
+ /* @__PURE__ */ jsxDEV("form", {
144
+ method: "post",
145
+ children: [
146
+ /* @__PURE__ */ jsxDEV("input", {
147
+ name: "action",
148
+ type: "hidden",
149
+ value: "resend"
150
+ }, undefined, false, undefined, this),
151
+ /* @__PURE__ */ jsxDEV("input", {
152
+ name: mode,
153
+ type: "hidden",
154
+ value: contact
155
+ }, undefined, false, undefined, this),
156
+ /* @__PURE__ */ jsxDEV("div", {
157
+ "data-component": "form-footer",
158
+ children: /* @__PURE__ */ jsxDEV("span", {
159
+ children: [
160
+ copy.code_didnt_get,
161
+ " ",
162
+ /* @__PURE__ */ jsxDEV("button", {
163
+ type: "submit",
164
+ "data-component": "link",
165
+ children: copy.code_resend
166
+ }, undefined, false, undefined, this)
167
+ ]
168
+ }, undefined, true, undefined, this)
169
+ }, undefined, false, undefined, this)
170
+ ]
171
+ }, undefined, true, undefined, this)
172
+ ]
173
+ }, undefined, true, undefined, this);
174
+ return new Response(jsx.toString(), {
175
+ headers: {
176
+ "Content-Type": "text/html"
177
+ }
178
+ });
179
+ }
180
+ throw new UnknownStateError;
181
+ }
182
+ };
183
+ };
184
+ export {
185
+ CodeUI
186
+ };
@@ -0,0 +1,46 @@
1
+ // src/ui/form.tsx
2
+ import { jsxDEV } from "hono/jsx/jsx-dev-runtime";
3
+ function FormAlert(props) {
4
+ const { message, color = "danger" } = props;
5
+ return /* @__PURE__ */ jsxDEV("div", {
6
+ "data-component": "form-alert",
7
+ "data-color": color,
8
+ children: [
9
+ /* @__PURE__ */ jsxDEV("svg", {
10
+ "aria-hidden": "true",
11
+ "data-slot": "icon-success",
12
+ xmlns: "http://www.w3.org/2000/svg",
13
+ fill: "none",
14
+ viewBox: "0 0 24 24",
15
+ "stroke-width": "1.5",
16
+ stroke: "currentColor",
17
+ children: /* @__PURE__ */ jsxDEV("path", {
18
+ "stroke-linecap": "round",
19
+ "stroke-linejoin": "round",
20
+ d: "M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
21
+ }, undefined, false, undefined, this)
22
+ }, undefined, false, undefined, this),
23
+ /* @__PURE__ */ jsxDEV("svg", {
24
+ "aria-hidden": "true",
25
+ "data-slot": "icon-danger",
26
+ xmlns: "http://www.w3.org/2000/svg",
27
+ fill: "none",
28
+ viewBox: "0 0 24 24",
29
+ "stroke-width": "1.5",
30
+ stroke: "currentColor",
31
+ children: /* @__PURE__ */ jsxDEV("path", {
32
+ "stroke-linecap": "round",
33
+ "stroke-linejoin": "round",
34
+ d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
35
+ }, undefined, false, undefined, this)
36
+ }, undefined, false, undefined, this),
37
+ /* @__PURE__ */ jsxDEV("span", {
38
+ "data-slot": "message",
39
+ children: message
40
+ }, undefined, false, undefined, this)
41
+ ]
42
+ }, undefined, true, undefined, this);
43
+ }
44
+ export {
45
+ FormAlert
46
+ };