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