alepha 0.15.3 → 0.15.5

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 (318) hide show
  1. package/README.md +26 -11
  2. package/dist/api/audits/index.d.ts +335 -335
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +11 -3
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +3 -3
  7. package/dist/api/files/index.js +4 -3
  8. package/dist/api/files/index.js.map +1 -1
  9. package/dist/api/jobs/index.d.ts +198 -155
  10. package/dist/api/jobs/index.d.ts.map +1 -1
  11. package/dist/api/jobs/index.js +103 -5
  12. package/dist/api/jobs/index.js.map +1 -1
  13. package/dist/api/keys/index.d.ts +198 -198
  14. package/dist/api/keys/index.d.ts.map +1 -1
  15. package/dist/api/keys/index.js +3 -3
  16. package/dist/api/keys/index.js.map +1 -1
  17. package/dist/api/notifications/index.browser.js +1 -0
  18. package/dist/api/notifications/index.browser.js.map +1 -1
  19. package/dist/api/notifications/index.d.ts +3 -3
  20. package/dist/api/notifications/index.js +4 -3
  21. package/dist/api/notifications/index.js.map +1 -1
  22. package/dist/api/parameters/index.d.ts +263 -263
  23. package/dist/api/parameters/index.d.ts.map +1 -1
  24. package/dist/api/parameters/index.js +41 -30
  25. package/dist/api/parameters/index.js.map +1 -1
  26. package/dist/api/users/index.d.ts +383 -77
  27. package/dist/api/users/index.d.ts.map +1 -1
  28. package/dist/api/users/index.js +284 -72
  29. package/dist/api/users/index.js.map +1 -1
  30. package/dist/api/verifications/index.d.ts +131 -131
  31. package/dist/api/verifications/index.d.ts.map +1 -1
  32. package/dist/api/verifications/index.js +3 -3
  33. package/dist/api/verifications/index.js.map +1 -1
  34. package/dist/batch/index.d.ts +3 -3
  35. package/dist/batch/index.js +3 -3
  36. package/dist/batch/index.js.map +1 -1
  37. package/dist/bucket/index.d.ts +3 -3
  38. package/dist/bucket/index.js +6 -6
  39. package/dist/bucket/index.js.map +1 -1
  40. package/dist/cache/core/index.d.ts +3 -3
  41. package/dist/cache/core/index.js +3 -3
  42. package/dist/cache/core/index.js.map +1 -1
  43. package/dist/cli/index.d.ts +5612 -20
  44. package/dist/cli/index.d.ts.map +1 -1
  45. package/dist/cli/index.js +122 -91
  46. package/dist/cli/index.js.map +1 -1
  47. package/dist/command/index.d.ts +11 -4
  48. package/dist/command/index.d.ts.map +1 -1
  49. package/dist/command/index.js +8 -6
  50. package/dist/command/index.js.map +1 -1
  51. package/dist/core/index.browser.js.map +1 -1
  52. package/dist/core/index.d.ts +4 -8
  53. package/dist/core/index.d.ts.map +1 -1
  54. package/dist/core/index.js +3 -3
  55. package/dist/core/index.js.map +1 -1
  56. package/dist/core/index.native.js.map +1 -1
  57. package/dist/datetime/index.d.ts +3 -3
  58. package/dist/datetime/index.js +3 -3
  59. package/dist/datetime/index.js.map +1 -1
  60. package/dist/email/index.d.ts +16 -16
  61. package/dist/email/index.d.ts.map +1 -1
  62. package/dist/email/index.js +10562 -10
  63. package/dist/email/index.js.map +1 -1
  64. package/dist/fake/index.d.ts +3 -3
  65. package/dist/fake/index.js +3 -3
  66. package/dist/fake/index.js.map +1 -1
  67. package/dist/lock/core/index.d.ts +9 -4
  68. package/dist/lock/core/index.d.ts.map +1 -1
  69. package/dist/lock/core/index.js +12 -4
  70. package/dist/lock/core/index.js.map +1 -1
  71. package/dist/logger/index.d.ts +3 -3
  72. package/dist/logger/index.js +6 -3
  73. package/dist/logger/index.js.map +1 -1
  74. package/dist/mcp/index.d.ts +3 -3
  75. package/dist/mcp/index.js +3 -3
  76. package/dist/mcp/index.js.map +1 -1
  77. package/dist/orm/index.d.ts +12 -12
  78. package/dist/orm/index.js +4 -4
  79. package/dist/orm/index.js.map +1 -1
  80. package/dist/queue/core/index.d.ts +3 -3
  81. package/dist/queue/core/index.js +3 -3
  82. package/dist/queue/core/index.js.map +1 -1
  83. package/dist/react/auth/index.browser.js +2 -1
  84. package/dist/react/auth/index.browser.js.map +1 -1
  85. package/dist/react/auth/index.d.ts +3 -3
  86. package/dist/react/auth/index.js +5 -4
  87. package/dist/react/auth/index.js.map +1 -1
  88. package/dist/react/core/index.d.ts +6 -6
  89. package/dist/react/core/index.js +3 -3
  90. package/dist/react/core/index.js.map +1 -1
  91. package/dist/react/form/index.d.ts +3 -3
  92. package/dist/react/form/index.js +3 -3
  93. package/dist/react/form/index.js.map +1 -1
  94. package/dist/react/head/index.d.ts +3 -3
  95. package/dist/react/head/index.js +3 -3
  96. package/dist/react/head/index.js.map +1 -1
  97. package/dist/react/i18n/index.d.ts +3 -3
  98. package/dist/react/i18n/index.js +3 -3
  99. package/dist/react/i18n/index.js.map +1 -1
  100. package/dist/react/intro/index.css +337 -0
  101. package/dist/react/intro/index.css.map +1 -0
  102. package/dist/react/intro/index.d.ts +10 -0
  103. package/dist/react/intro/index.d.ts.map +1 -0
  104. package/dist/react/intro/index.js +222 -0
  105. package/dist/react/intro/index.js.map +1 -0
  106. package/dist/react/router/index.browser.js +2 -2
  107. package/dist/react/router/index.browser.js.map +1 -1
  108. package/dist/react/router/index.d.ts +11 -1
  109. package/dist/react/router/index.d.ts.map +1 -1
  110. package/dist/react/router/index.js +21 -11
  111. package/dist/react/router/index.js.map +1 -1
  112. package/dist/redis/index.d.ts +22 -22
  113. package/dist/redis/index.js +3 -3
  114. package/dist/redis/index.js.map +1 -1
  115. package/dist/retry/index.d.ts +3 -3
  116. package/dist/retry/index.js +3 -3
  117. package/dist/retry/index.js.map +1 -1
  118. package/dist/scheduler/index.d.ts +16 -4
  119. package/dist/scheduler/index.d.ts.map +1 -1
  120. package/dist/scheduler/index.js +45 -7
  121. package/dist/scheduler/index.js.map +1 -1
  122. package/dist/security/index.d.ts +3 -3
  123. package/dist/security/index.js +5 -5
  124. package/dist/security/index.js.map +1 -1
  125. package/dist/server/auth/index.d.ts +3 -3
  126. package/dist/server/auth/index.js +3 -3
  127. package/dist/server/auth/index.js.map +1 -1
  128. package/dist/server/cache/index.d.ts +3 -3
  129. package/dist/server/cache/index.js +3 -3
  130. package/dist/server/cache/index.js.map +1 -1
  131. package/dist/server/compress/index.d.ts +3 -3
  132. package/dist/server/compress/index.d.ts.map +1 -1
  133. package/dist/server/compress/index.js +4 -3
  134. package/dist/server/compress/index.js.map +1 -1
  135. package/dist/server/cookies/index.d.ts +3 -3
  136. package/dist/server/cookies/index.js +3 -3
  137. package/dist/server/cookies/index.js.map +1 -1
  138. package/dist/server/core/index.d.ts +14 -25
  139. package/dist/server/core/index.d.ts.map +1 -1
  140. package/dist/server/core/index.js +13 -29
  141. package/dist/server/core/index.js.map +1 -1
  142. package/dist/server/cors/index.d.ts +3 -3
  143. package/dist/server/cors/index.js +3 -3
  144. package/dist/server/cors/index.js.map +1 -1
  145. package/dist/server/health/index.d.ts +20 -20
  146. package/dist/server/health/index.js +3 -3
  147. package/dist/server/health/index.js.map +1 -1
  148. package/dist/server/helmet/index.d.ts +3 -3
  149. package/dist/server/helmet/index.js +3 -3
  150. package/dist/server/helmet/index.js.map +1 -1
  151. package/dist/server/links/index.d.ts +42 -42
  152. package/dist/server/links/index.d.ts.map +1 -1
  153. package/dist/server/links/index.js +4 -4
  154. package/dist/server/links/index.js.map +1 -1
  155. package/dist/server/metrics/index.d.ts +3 -3
  156. package/dist/server/metrics/index.js +3 -3
  157. package/dist/server/metrics/index.js.map +1 -1
  158. package/dist/server/multipart/index.d.ts +3 -3
  159. package/dist/server/multipart/index.js +3 -3
  160. package/dist/server/multipart/index.js.map +1 -1
  161. package/dist/server/proxy/index.d.ts +3 -3
  162. package/dist/server/proxy/index.js +3 -3
  163. package/dist/server/proxy/index.js.map +1 -1
  164. package/dist/server/rate-limit/index.d.ts +3 -3
  165. package/dist/server/rate-limit/index.js +3 -3
  166. package/dist/server/rate-limit/index.js.map +1 -1
  167. package/dist/server/static/index.d.ts +3 -3
  168. package/dist/server/static/index.js +6 -6
  169. package/dist/server/static/index.js.map +1 -1
  170. package/dist/server/swagger/index.d.ts +3 -3
  171. package/dist/server/swagger/index.js +6 -6
  172. package/dist/server/swagger/index.js.map +1 -1
  173. package/dist/sms/index.d.ts +3 -3
  174. package/dist/sms/index.js +6 -6
  175. package/dist/sms/index.js.map +1 -1
  176. package/dist/system/index.d.ts +3 -3
  177. package/dist/system/index.js +3 -3
  178. package/dist/system/index.js.map +1 -1
  179. package/dist/thread/index.d.ts +3 -3
  180. package/dist/thread/index.js +3 -3
  181. package/dist/thread/index.js.map +1 -1
  182. package/dist/topic/core/index.d.ts +3 -3
  183. package/dist/topic/core/index.js +3 -3
  184. package/dist/topic/core/index.js.map +1 -1
  185. package/dist/vite/index.d.ts +6286 -4
  186. package/dist/vite/index.d.ts.map +1 -1
  187. package/dist/vite/index.js +28 -2
  188. package/dist/vite/index.js.map +1 -1
  189. package/dist/websocket/index.d.ts +37 -37
  190. package/dist/websocket/index.d.ts.map +1 -1
  191. package/dist/websocket/index.js +3 -3
  192. package/dist/websocket/index.js.map +1 -1
  193. package/package.json +12 -4
  194. package/src/api/audits/controllers/AdminAuditController.ts +8 -0
  195. package/src/api/audits/index.ts +3 -3
  196. package/src/api/files/controllers/AdminFileStatsController.ts +1 -0
  197. package/src/api/files/index.ts +3 -3
  198. package/src/api/jobs/controllers/AdminJobController.ts +18 -2
  199. package/src/api/jobs/index.ts +4 -3
  200. package/src/api/jobs/services/JobAudits.spec.ts +89 -0
  201. package/src/api/jobs/services/JobAudits.ts +101 -0
  202. package/src/api/keys/index.ts +3 -3
  203. package/src/api/notifications/controllers/AdminNotificationController.ts +1 -0
  204. package/src/api/notifications/index.ts +3 -3
  205. package/src/api/parameters/controllers/AdminConfigController.ts +10 -0
  206. package/src/api/parameters/index.ts +5 -3
  207. package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1 -1
  208. package/src/api/users/__tests__/ApiKeys.spec.ts +1 -1
  209. package/src/api/users/__tests__/EmailVerification.spec.ts +16 -1
  210. package/src/api/users/__tests__/PasswordReset.spec.ts +11 -0
  211. package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -0
  212. package/src/api/users/controllers/AdminIdentityController.ts +3 -0
  213. package/src/api/users/controllers/AdminSessionController.ts +3 -0
  214. package/src/api/users/controllers/AdminUserController.ts +5 -0
  215. package/src/api/users/index.ts +8 -9
  216. package/src/api/users/primitives/$realm.ts +117 -19
  217. package/src/api/users/providers/RealmProvider.ts +15 -7
  218. package/src/api/users/services/CredentialService.spec.ts +11 -0
  219. package/src/api/users/services/CredentialService.ts +47 -24
  220. package/src/api/users/services/IdentityService.ts +12 -4
  221. package/src/api/users/services/RegistrationService.spec.ts +11 -0
  222. package/src/api/users/services/RegistrationService.ts +33 -12
  223. package/src/api/users/services/SessionService.ts +83 -12
  224. package/src/api/users/services/UserAudits.ts +47 -0
  225. package/src/api/users/services/UserFiles.ts +19 -0
  226. package/src/api/users/services/UserJobs.spec.ts +107 -0
  227. package/src/api/users/services/UserJobs.ts +62 -0
  228. package/src/api/users/services/UserParameters.ts +23 -0
  229. package/src/api/users/services/UserService.ts +34 -17
  230. package/src/api/verifications/index.ts +3 -3
  231. package/src/batch/index.ts +3 -3
  232. package/src/bucket/index.ts +3 -3
  233. package/src/cache/core/index.ts +3 -3
  234. package/src/cli/commands/build.ts +1 -0
  235. package/src/cli/commands/db.ts +9 -0
  236. package/src/cli/commands/init.spec.ts +2 -17
  237. package/src/cli/commands/init.ts +37 -1
  238. package/src/cli/providers/ViteDevServerProvider.ts +36 -2
  239. package/src/cli/services/AlephaCliUtils.ts +17 -0
  240. package/src/cli/services/PackageManagerUtils.ts +15 -1
  241. package/src/cli/services/ProjectScaffolder.ts +8 -13
  242. package/src/cli/templates/agentMd.ts +2 -25
  243. package/src/cli/templates/apiAppSecurityTs.ts +37 -2
  244. package/src/cli/templates/mainCss.ts +2 -32
  245. package/src/cli/templates/webAppRouterTs.ts +5 -5
  246. package/src/cli/templates/webHomeComponentTsx.ts +10 -0
  247. package/src/command/helpers/Runner.ts +14 -1
  248. package/src/command/index.ts +3 -3
  249. package/src/core/helpers/primitive.ts +0 -5
  250. package/src/core/index.ts +3 -3
  251. package/src/datetime/index.ts +3 -3
  252. package/src/email/index.ts +3 -3
  253. package/src/email/index.workerd.ts +36 -0
  254. package/src/email/providers/LocalEmailProvider.ts +2 -2
  255. package/src/email/providers/WorkermailerEmailProvider.ts +221 -0
  256. package/src/fake/index.ts +3 -3
  257. package/src/lock/core/index.ts +3 -3
  258. package/src/lock/core/primitives/$lock.ts +13 -1
  259. package/src/logger/index.ts +3 -3
  260. package/src/logger/providers/PrettyFormatterProvider.ts +7 -0
  261. package/src/mcp/index.ts +3 -3
  262. package/src/orm/index.ts +3 -3
  263. package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
  264. package/src/queue/core/index.ts +3 -3
  265. package/src/react/auth/index.ts +3 -3
  266. package/src/react/auth/services/ReactAuth.ts +3 -1
  267. package/src/react/core/index.ts +3 -3
  268. package/src/react/form/index.ts +3 -3
  269. package/src/react/head/index.ts +3 -3
  270. package/src/react/i18n/index.ts +3 -3
  271. package/src/react/intro/components/GettingStarted.css +334 -0
  272. package/src/react/intro/components/GettingStarted.tsx +276 -0
  273. package/src/react/intro/index.ts +1 -0
  274. package/src/react/router/atoms/ssrManifestAtom.ts +7 -0
  275. package/src/react/router/index.browser.ts +2 -0
  276. package/src/react/router/index.ts +2 -0
  277. package/src/react/router/providers/ReactServerProvider.ts +14 -4
  278. package/src/react/router/providers/SSRManifestProvider.ts +7 -0
  279. package/src/redis/index.ts +3 -3
  280. package/src/retry/index.ts +3 -3
  281. package/src/router/index.ts +3 -3
  282. package/src/scheduler/index.ts +3 -3
  283. package/src/scheduler/index.workerd.ts +43 -0
  284. package/src/scheduler/providers/CronProvider.ts +53 -6
  285. package/src/scheduler/providers/WorkerdCronProvider.ts +102 -0
  286. package/src/security/index.ts +3 -3
  287. package/src/security/providers/JwtProvider.ts +2 -2
  288. package/src/server/auth/index.ts +3 -3
  289. package/src/server/cache/index.ts +3 -3
  290. package/src/server/compress/index.ts +3 -3
  291. package/src/server/compress/providers/ServerCompressProvider.ts +6 -0
  292. package/src/server/cookies/index.ts +3 -3
  293. package/src/server/core/index.ts +3 -3
  294. package/src/server/core/primitives/$action.spec.ts +3 -2
  295. package/src/server/core/primitives/$action.ts +6 -2
  296. package/src/server/core/providers/NodeHttpServerProvider.ts +2 -15
  297. package/src/server/core/providers/ServerProvider.ts +4 -2
  298. package/src/server/core/providers/ServerRouterProvider.ts +5 -27
  299. package/src/server/cors/index.ts +3 -3
  300. package/src/server/health/index.ts +3 -3
  301. package/src/server/helmet/index.ts +3 -3
  302. package/src/server/links/index.ts +3 -3
  303. package/src/server/links/providers/ServerLinksProvider.spec.ts +332 -0
  304. package/src/server/links/providers/ServerLinksProvider.ts +1 -1
  305. package/src/server/metrics/index.ts +3 -3
  306. package/src/server/multipart/index.ts +3 -3
  307. package/src/server/proxy/index.ts +3 -3
  308. package/src/server/rate-limit/index.ts +3 -3
  309. package/src/server/static/index.ts +3 -3
  310. package/src/server/swagger/index.ts +3 -3
  311. package/src/sms/index.ts +3 -3
  312. package/src/system/index.ts +3 -3
  313. package/src/thread/index.ts +3 -3
  314. package/src/topic/core/index.ts +3 -3
  315. package/src/vite/tasks/generateCloudflare.ts +38 -2
  316. package/src/websocket/index.ts +3 -3
  317. package/src/cli/templates/webHelloComponentTsx.ts +0 -30
  318. /package/src/api/users/{notifications → services}/UserNotifications.ts +0 -0
@@ -0,0 +1,337 @@
1
+ .alepha-blank {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ min-height: 100svh;
6
+ background: #fafafa;
7
+ font-family: system-ui, -apple-system, sans-serif;
8
+ color: #171717;
9
+ position: absolute;
10
+ left: 0;
11
+ right: 0;
12
+ bottom: 0;
13
+ top: 0;
14
+ width: 100%;
15
+ }
16
+
17
+ .alepha-blank-content {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ text-align: center;
22
+ max-width: 640px;
23
+ }
24
+
25
+ .alepha-blank-text-block {
26
+ min-height: 320px;
27
+ display: flex;
28
+ flex-direction: column;
29
+ align-items: center;
30
+ justify-content: center;
31
+ }
32
+
33
+ /* Message */
34
+
35
+ .alepha-blank-message {
36
+ font-size: clamp(2rem, 8vw, 3rem);
37
+ font-weight: 600;
38
+ letter-spacing: -0.02em;
39
+ margin: 0;
40
+ line-height: 1.1;
41
+ }
42
+
43
+ .alepha-blank-sub {
44
+ font-size: 1.0625rem;
45
+ color: #525252;
46
+ margin: 1rem 0 0;
47
+ font-weight: 400;
48
+ line-height: 1.5;
49
+ }
50
+
51
+ .alepha-blank-detail {
52
+ font-size: 0.875rem;
53
+ color: #a3a3a3;
54
+ margin: 0.5rem 0 0;
55
+ font-weight: 400;
56
+ line-height: 1.5;
57
+ }
58
+
59
+ /* Slide Animations */
60
+
61
+ .alepha-blank-slide-next {
62
+ animation: alepha-blank-slideNext 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
63
+ }
64
+
65
+ .alepha-blank-slide-prev {
66
+ animation: alepha-blank-slidePrev 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
67
+ }
68
+
69
+ @keyframes alepha-blank-slideNext {
70
+ from {
71
+ opacity: 0;
72
+ transform: translateX(20px);
73
+ }
74
+ to {
75
+ opacity: 1;
76
+ transform: translateX(0);
77
+ }
78
+ }
79
+
80
+ @keyframes alepha-blank-slidePrev {
81
+ from {
82
+ opacity: 0;
83
+ transform: translateX(-20px);
84
+ }
85
+ to {
86
+ opacity: 1;
87
+ transform: translateX(0);
88
+ }
89
+ }
90
+
91
+ /* Steps */
92
+
93
+ .alepha-blank-steps {
94
+ display: flex;
95
+ flex-direction: column;
96
+ gap: 0.25rem;
97
+ margin-top: 1.25rem;
98
+ text-align: left;
99
+ }
100
+
101
+ .alepha-blank-step {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 0.625rem;
105
+ padding: 0.25rem 0;
106
+ opacity: 0;
107
+ animation: alepha-blank-stepIn 0.4s cubic-bezier(0.22, 1, 0.36, 1) forwards;
108
+ }
109
+
110
+ .alepha-blank-step-num {
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ width: 20px;
115
+ height: 20px;
116
+ border-radius: 50%;
117
+ background: #171717;
118
+ color: #fff;
119
+ font-size: 0.6875rem;
120
+ font-weight: 600;
121
+ flex-shrink: 0;
122
+ }
123
+
124
+ .alepha-blank-step-text {
125
+ font-size: 0.8125rem;
126
+ color: #525252;
127
+ line-height: 1.5;
128
+ }
129
+
130
+ .alepha-blank-step-text code {
131
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
132
+ font-size: 0.75rem;
133
+ background: #f5f5f5;
134
+ color: #171717;
135
+ padding: 0.0625rem 0.375rem;
136
+ border-radius: 3px;
137
+ border: 1px solid #e5e5e5;
138
+ }
139
+
140
+ .alepha-blank-step-text a {
141
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
142
+ color: #525252;
143
+ text-decoration: underline;
144
+ text-underline-offset: 2px;
145
+ transition: color 0.15s ease;
146
+ }
147
+
148
+ .alepha-blank-step-text a:hover {
149
+ color: #171717;
150
+ }
151
+
152
+ @keyframes alepha-blank-stepIn {
153
+ from {
154
+ opacity: 0;
155
+ transform: translateY(10px);
156
+ }
157
+ to {
158
+ opacity: 1;
159
+ transform: translateY(0);
160
+ }
161
+ }
162
+
163
+ /* Links */
164
+
165
+ .alepha-blank-links {
166
+ display: flex;
167
+ gap: 1.5rem;
168
+ margin-top: 1.25rem;
169
+ }
170
+
171
+ .alepha-blank-links a {
172
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
173
+ font-size: 0.875rem;
174
+ color: #525252;
175
+ text-decoration: none;
176
+ position: relative;
177
+ opacity: 0;
178
+ animation: alepha-blank-fadeIn 0.3s ease-out forwards;
179
+ transition: color 0.2s ease;
180
+ }
181
+
182
+ .alepha-blank-links a::after {
183
+ content: "";
184
+ position: absolute;
185
+ left: 0;
186
+ right: 0;
187
+ bottom: -2px;
188
+ height: 1px;
189
+ background: #a3a3a3;
190
+ transform: scaleX(1);
191
+ transform-origin: left;
192
+ transition:
193
+ transform 0.25s cubic-bezier(0.22, 1, 0.36, 1),
194
+ background 0.2s ease;
195
+ }
196
+
197
+ .alepha-blank-links a:hover {
198
+ color: #171717;
199
+ }
200
+
201
+ .alepha-blank-links a:hover::after {
202
+ background: #171717;
203
+ transform: scaleX(1.05);
204
+ }
205
+
206
+ /* Slider */
207
+
208
+ .alepha-blank-slider {
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 1rem;
212
+ margin-top: 2.5rem;
213
+ }
214
+
215
+ .alepha-blank-dots {
216
+ display: flex;
217
+ align-items: center;
218
+ gap: 0.5rem;
219
+ }
220
+
221
+ .alepha-blank-dot {
222
+ width: 8px;
223
+ height: 8px;
224
+ border-radius: 50%;
225
+ background: transparent;
226
+ border: 1.5px solid #d4d4d4;
227
+ padding: 0;
228
+ cursor: pointer;
229
+ transition: all 0.25s cubic-bezier(0.22, 1, 0.36, 1);
230
+ }
231
+
232
+ .alepha-blank-dot:hover {
233
+ border-color: #a3a3a3;
234
+ transform: scale(1.2);
235
+ }
236
+
237
+ .alepha-blank-dot:focus-visible {
238
+ outline: 2px solid #737373;
239
+ outline-offset: 2px;
240
+ }
241
+
242
+ .alepha-blank-dot.active {
243
+ background: #737373;
244
+ border-color: #737373;
245
+ transform: scale(1.1);
246
+ }
247
+
248
+ /* Nav Buttons */
249
+
250
+ .alepha-blank-nav-btn {
251
+ width: 32px;
252
+ height: 32px;
253
+ display: flex;
254
+ align-items: center;
255
+ justify-content: center;
256
+ padding: 0;
257
+ font-family: inherit;
258
+ background: transparent;
259
+ color: #a3a3a3;
260
+ border: 1.5px solid transparent;
261
+ border-radius: 8px;
262
+ cursor: pointer;
263
+ transition: all 0.2s cubic-bezier(0.22, 1, 0.36, 1);
264
+ }
265
+
266
+ .alepha-blank-nav-btn:hover {
267
+ color: #525252;
268
+ background: #f0f0f0;
269
+ }
270
+
271
+ .alepha-blank-nav-btn:focus-visible {
272
+ outline: none;
273
+ border-color: #737373;
274
+ color: #525252;
275
+ }
276
+
277
+ .alepha-blank-nav-btn:active {
278
+ transform: scale(0.92);
279
+ background: #e5e5e5;
280
+ }
281
+
282
+ /* Hint */
283
+
284
+ .alepha-blank-hint {
285
+ margin-top: 2rem;
286
+ font-size: 0.75rem;
287
+ color: #a3a3a3;
288
+ display: flex;
289
+ align-items: center;
290
+ gap: 0.375rem;
291
+ opacity: 0;
292
+ animation: alepha-blank-fadeIn 0.5s ease-out 0.5s forwards;
293
+ }
294
+
295
+ .alepha-blank-hint kbd {
296
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
297
+ font-size: 0.6875rem;
298
+ background: #f0f0f0;
299
+ border: 1px solid #e5e5e5;
300
+ border-radius: 4px;
301
+ padding: 0.125rem 0.375rem;
302
+ box-shadow: 0 1px 0 #d4d4d4;
303
+ }
304
+
305
+ /* Fade In Animation */
306
+
307
+ @keyframes alepha-blank-fadeIn {
308
+ from {
309
+ opacity: 0;
310
+ }
311
+ to {
312
+ opacity: 1;
313
+ }
314
+ }
315
+
316
+ /* Respect reduced motion */
317
+
318
+ @media (prefers-reduced-motion: reduce) {
319
+ .alepha-blank-slide-next,
320
+ .alepha-blank-slide-prev,
321
+ .alepha-blank-links a,
322
+ .alepha-blank-hint,
323
+ .alepha-blank-step {
324
+ animation: none;
325
+ opacity: 1;
326
+ }
327
+
328
+ .alepha-blank-dot,
329
+ .alepha-blank-nav-btn,
330
+ .alepha-blank-links a,
331
+ .alepha-blank-links a::after {
332
+ transition: none;
333
+ }
334
+ }
335
+
336
+
337
+ /*# sourceMappingURL=index.css.map*/
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.css","names":[],"sources":["../../../../../src/react/intro/components/GettingStarted.css"],"sourcesContent":[".alepha-blank {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100svh;\n background: #fafafa;\n font-family: system-ui, -apple-system, sans-serif;\n color: #171717;\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n width: 100%;\n}\n\n.alepha-blank-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n max-width: 640px;\n}\n\n.alepha-blank-text-block {\n min-height: 320px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n/* Message */\n\n.alepha-blank-message {\n font-size: clamp(2rem, 8vw, 3rem);\n font-weight: 600;\n letter-spacing: -0.02em;\n margin: 0;\n line-height: 1.1;\n}\n\n.alepha-blank-sub {\n font-size: 1.0625rem;\n color: #525252;\n margin: 1rem 0 0;\n font-weight: 400;\n line-height: 1.5;\n}\n\n.alepha-blank-detail {\n font-size: 0.875rem;\n color: #a3a3a3;\n margin: 0.5rem 0 0;\n font-weight: 400;\n line-height: 1.5;\n}\n\n/* Slide Animations */\n\n.alepha-blank-slide-next {\n animation: alepha-blank-slideNext 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n.alepha-blank-slide-prev {\n animation: alepha-blank-slidePrev 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;\n}\n\n@keyframes alepha-blank-slideNext {\n from {\n opacity: 0;\n transform: translateX(20px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n@keyframes alepha-blank-slidePrev {\n from {\n opacity: 0;\n transform: translateX(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n/* Steps */\n\n.alepha-blank-steps {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n margin-top: 1.25rem;\n text-align: left;\n}\n\n.alepha-blank-step {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.25rem 0;\n opacity: 0;\n animation: alepha-blank-stepIn 0.4s cubic-bezier(0.22, 1, 0.36, 1) forwards;\n}\n\n.alepha-blank-step-num {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #171717;\n color: #fff;\n font-size: 0.6875rem;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.alepha-blank-step-text {\n font-size: 0.8125rem;\n color: #525252;\n line-height: 1.5;\n}\n\n.alepha-blank-step-text code {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.75rem;\n background: #f5f5f5;\n color: #171717;\n padding: 0.0625rem 0.375rem;\n border-radius: 3px;\n border: 1px solid #e5e5e5;\n}\n\n.alepha-blank-step-text a {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n color: #525252;\n text-decoration: underline;\n text-underline-offset: 2px;\n transition: color 0.15s ease;\n}\n\n.alepha-blank-step-text a:hover {\n color: #171717;\n}\n\n@keyframes alepha-blank-stepIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Links */\n\n.alepha-blank-links {\n display: flex;\n gap: 1.5rem;\n margin-top: 1.25rem;\n}\n\n.alepha-blank-links a {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.875rem;\n color: #525252;\n text-decoration: none;\n position: relative;\n opacity: 0;\n animation: alepha-blank-fadeIn 0.3s ease-out forwards;\n transition: color 0.2s ease;\n}\n\n.alepha-blank-links a::after {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n bottom: -2px;\n height: 1px;\n background: #a3a3a3;\n transform: scaleX(1);\n transform-origin: left;\n transition:\n transform 0.25s cubic-bezier(0.22, 1, 0.36, 1),\n background 0.2s ease;\n}\n\n.alepha-blank-links a:hover {\n color: #171717;\n}\n\n.alepha-blank-links a:hover::after {\n background: #171717;\n transform: scaleX(1.05);\n}\n\n/* Slider */\n\n.alepha-blank-slider {\n display: flex;\n align-items: center;\n gap: 1rem;\n margin-top: 2.5rem;\n}\n\n.alepha-blank-dots {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.alepha-blank-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: transparent;\n border: 1.5px solid #d4d4d4;\n padding: 0;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.22, 1, 0.36, 1);\n}\n\n.alepha-blank-dot:hover {\n border-color: #a3a3a3;\n transform: scale(1.2);\n}\n\n.alepha-blank-dot:focus-visible {\n outline: 2px solid #737373;\n outline-offset: 2px;\n}\n\n.alepha-blank-dot.active {\n background: #737373;\n border-color: #737373;\n transform: scale(1.1);\n}\n\n/* Nav Buttons */\n\n.alepha-blank-nav-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n font-family: inherit;\n background: transparent;\n color: #a3a3a3;\n border: 1.5px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.22, 1, 0.36, 1);\n}\n\n.alepha-blank-nav-btn:hover {\n color: #525252;\n background: #f0f0f0;\n}\n\n.alepha-blank-nav-btn:focus-visible {\n outline: none;\n border-color: #737373;\n color: #525252;\n}\n\n.alepha-blank-nav-btn:active {\n transform: scale(0.92);\n background: #e5e5e5;\n}\n\n/* Hint */\n\n.alepha-blank-hint {\n margin-top: 2rem;\n font-size: 0.75rem;\n color: #a3a3a3;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n opacity: 0;\n animation: alepha-blank-fadeIn 0.5s ease-out 0.5s forwards;\n}\n\n.alepha-blank-hint kbd {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.6875rem;\n background: #f0f0f0;\n border: 1px solid #e5e5e5;\n border-radius: 4px;\n padding: 0.125rem 0.375rem;\n box-shadow: 0 1px 0 #d4d4d4;\n}\n\n/* Fade In Animation */\n\n@keyframes alepha-blank-fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* Respect reduced motion */\n\n@media (prefers-reduced-motion: reduce) {\n .alepha-blank-slide-next,\n .alepha-blank-slide-prev,\n .alepha-blank-links a,\n .alepha-blank-hint,\n .alepha-blank-step {\n animation: none;\n opacity: 1;\n }\n\n .alepha-blank-dot,\n .alepha-blank-nav-btn,\n .alepha-blank-links a,\n .alepha-blank-links a::after {\n transition: none;\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA"}
@@ -0,0 +1,10 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region ../../src/react/intro/components/GettingStarted.d.ts
4
+ /**
5
+ * A welcome component displayed when creating a new Alepha application.
6
+ */
7
+ declare const GettingStarted: () => react_jsx_runtime0.JSX.Element;
8
+ //#endregion
9
+ export { GettingStarted };
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/react/intro/components/GettingStarted.tsx"],"mappings":";;;;;AAC8B;cAqCxB,cAAA,QAAc,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,222 @@
1
+ import { useCallback, useEffect, useMemo, useState } from "react";
2
+ import { useRouter } from "alepha/react/router";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region ../../src/react/intro/components/GettingStarted.tsx
6
+ const messages = [{
7
+ text: "Let's begin.",
8
+ sub: "Every story starts with a blank page.",
9
+ detail: "This one is yours."
10
+ }, {
11
+ text: "Need help?",
12
+ sub: "We've got you covered.",
13
+ detail: "Even our AI friends can read the docs.",
14
+ links: [{
15
+ label: "alepha.dev",
16
+ href: "https://alepha.dev"
17
+ }, {
18
+ label: "llms.txt",
19
+ href: "https://alepha.dev/llms.txt"
20
+ }]
21
+ }];
22
+ /**
23
+ * A welcome component displayed when creating a new Alepha application.
24
+ */
25
+ const GettingStarted = () => {
26
+ const [index, setIndex] = useState(0);
27
+ const [direction, setDirection] = useState("next");
28
+ const router = useRouter();
29
+ const hasAdmin = router.pages.find((it) => it.name === "adminLayout");
30
+ const hasAuth = router.pages.find((it) => it.name === "authLayout");
31
+ const adminAnchorProps = hasAdmin ? router.anchor(router.path("adminLayout")) : void 0;
32
+ const authAnchorProps = hasAuth ? router.anchor(router.path("login")) : void 0;
33
+ const filteredMessages = useMemo(() => {
34
+ const result = [];
35
+ for (const msg of messages) {
36
+ if (msg.text === "Need help?") break;
37
+ result.push(msg);
38
+ }
39
+ if (hasAuth && authAnchorProps) result.push({
40
+ text: "Who are you?",
41
+ sub: "Create your first account.",
42
+ steps: [{
43
+ num: "1",
44
+ text: /* @__PURE__ */ jsxs(Fragment, { children: ["Sign up at ", /* @__PURE__ */ jsx("a", {
45
+ ...authAnchorProps,
46
+ children: "/auth/login"
47
+ })] })
48
+ }, {
49
+ num: "2",
50
+ text: /* @__PURE__ */ jsxs(Fragment, { children: ["Customize in ", /* @__PURE__ */ jsx("code", { children: "src/api/AppSecurity.ts" })] })
51
+ }]
52
+ });
53
+ if (hasAdmin && adminAnchorProps) result.push({
54
+ text: "Take the wheel.",
55
+ sub: "Become admin in three steps.",
56
+ steps: [
57
+ {
58
+ num: "1",
59
+ text: /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ "Add your email to ",
61
+ /* @__PURE__ */ jsx("code", { children: "adminEmails" }),
62
+ " in",
63
+ " ",
64
+ /* @__PURE__ */ jsx("code", { children: "AppSecurity.ts" })
65
+ ] })
66
+ },
67
+ {
68
+ num: "2",
69
+ text: "Create a user account with that email"
70
+ },
71
+ {
72
+ num: "3",
73
+ text: /* @__PURE__ */ jsxs(Fragment, { children: ["Go to ", /* @__PURE__ */ jsx("a", {
74
+ ...adminAnchorProps,
75
+ children: "/admin"
76
+ })] })
77
+ }
78
+ ]
79
+ });
80
+ const helpMsg = messages.find((msg) => msg.text === "Need help?");
81
+ if (helpMsg) result.push(helpMsg);
82
+ return result;
83
+ }, [
84
+ hasAuth,
85
+ hasAdmin,
86
+ authAnchorProps,
87
+ adminAnchorProps
88
+ ]);
89
+ const current = filteredMessages[index];
90
+ const prev = useCallback(() => {
91
+ setDirection("prev");
92
+ setIndex((i) => (i - 1 + filteredMessages.length) % filteredMessages.length);
93
+ }, [filteredMessages.length]);
94
+ const next = useCallback(() => {
95
+ setDirection("next");
96
+ setIndex((i) => (i + 1) % filteredMessages.length);
97
+ }, [filteredMessages.length]);
98
+ const goTo = useCallback((i) => {
99
+ setDirection(i > index ? "next" : "prev");
100
+ setIndex(i);
101
+ }, [index]);
102
+ useEffect(() => {
103
+ const handleKeyDown = (e) => {
104
+ if (e.key === "ArrowLeft") prev();
105
+ else if (e.key === "ArrowRight") next();
106
+ };
107
+ window.addEventListener("keydown", handleKeyDown);
108
+ return () => window.removeEventListener("keydown", handleKeyDown);
109
+ }, [prev, next]);
110
+ return /* @__PURE__ */ jsx("main", {
111
+ className: "alepha-blank",
112
+ children: /* @__PURE__ */ jsxs("div", {
113
+ className: "alepha-blank-content",
114
+ children: [
115
+ /* @__PURE__ */ jsxs("div", {
116
+ className: "alepha-blank-text-block",
117
+ children: [
118
+ /* @__PURE__ */ jsx("h1", {
119
+ className: `alepha-blank-message alepha-blank-slide-${direction}`,
120
+ children: current.text
121
+ }, index),
122
+ /* @__PURE__ */ jsx("p", {
123
+ className: `alepha-blank-sub alepha-blank-slide-${direction}`,
124
+ children: current.sub
125
+ }, `sub-${index}`),
126
+ current.detail && /* @__PURE__ */ jsx("p", {
127
+ className: `alepha-blank-detail alepha-blank-slide-${direction}`,
128
+ children: current.detail
129
+ }, `detail-${index}`),
130
+ current.steps && /* @__PURE__ */ jsx("div", {
131
+ className: `alepha-blank-steps alepha-blank-slide-${direction}`,
132
+ children: current.steps.map((step, i) => /* @__PURE__ */ jsxs("div", {
133
+ className: "alepha-blank-step",
134
+ style: { animationDelay: `${.15 + i * .08}s` },
135
+ children: [/* @__PURE__ */ jsx("span", {
136
+ className: "alepha-blank-step-num",
137
+ children: step.num
138
+ }), /* @__PURE__ */ jsx("span", {
139
+ className: "alepha-blank-step-text",
140
+ children: step.text
141
+ })]
142
+ }, i))
143
+ }, `steps-${index}`),
144
+ current.links && /* @__PURE__ */ jsx("div", {
145
+ className: `alepha-blank-links alepha-blank-slide-${direction}`,
146
+ children: current.links.map((link, i) => /* @__PURE__ */ jsx("a", {
147
+ href: link.href,
148
+ target: link.href.startsWith("http") ? "_blank" : void 0,
149
+ rel: link.href.startsWith("http") ? "noopener noreferrer" : void 0,
150
+ style: { animationDelay: `${.1 + i * .05}s` },
151
+ children: link.label
152
+ }, link.href))
153
+ }, `links-${index}`)
154
+ ]
155
+ }),
156
+ /* @__PURE__ */ jsxs("div", {
157
+ className: "alepha-blank-slider",
158
+ children: [
159
+ /* @__PURE__ */ jsx("button", {
160
+ className: "alepha-blank-nav-btn",
161
+ onClick: prev,
162
+ "aria-label": "Previous",
163
+ children: /* @__PURE__ */ jsx("svg", {
164
+ width: "14",
165
+ height: "14",
166
+ viewBox: "0 0 14 14",
167
+ fill: "none",
168
+ children: /* @__PURE__ */ jsx("path", {
169
+ d: "M9 3L5 7L9 11",
170
+ stroke: "currentColor",
171
+ strokeWidth: "1.5",
172
+ strokeLinecap: "round",
173
+ strokeLinejoin: "round"
174
+ })
175
+ })
176
+ }),
177
+ /* @__PURE__ */ jsx("div", {
178
+ className: "alepha-blank-dots",
179
+ children: filteredMessages.map((_, i) => /* @__PURE__ */ jsx("button", {
180
+ className: `alepha-blank-dot ${i === index ? "active" : ""}`,
181
+ onClick: () => goTo(i),
182
+ "aria-label": `Go to message ${i + 1}`
183
+ }, i))
184
+ }),
185
+ /* @__PURE__ */ jsx("button", {
186
+ className: "alepha-blank-nav-btn",
187
+ onClick: next,
188
+ "aria-label": "Next",
189
+ children: /* @__PURE__ */ jsx("svg", {
190
+ width: "14",
191
+ height: "14",
192
+ viewBox: "0 0 14 14",
193
+ fill: "none",
194
+ children: /* @__PURE__ */ jsx("path", {
195
+ d: "M5 3L9 7L5 11",
196
+ stroke: "currentColor",
197
+ strokeWidth: "1.5",
198
+ strokeLinecap: "round",
199
+ strokeLinejoin: "round"
200
+ })
201
+ })
202
+ })
203
+ ]
204
+ }),
205
+ /* @__PURE__ */ jsxs("div", {
206
+ className: "alepha-blank-hint",
207
+ children: [
208
+ /* @__PURE__ */ jsx("kbd", { children: "←" }),
209
+ " ",
210
+ /* @__PURE__ */ jsx("kbd", { children: "→" }),
211
+ " to navigate"
212
+ ]
213
+ })
214
+ ]
215
+ })
216
+ });
217
+ };
218
+ var GettingStarted_default = GettingStarted;
219
+
220
+ //#endregion
221
+ export { GettingStarted_default as GettingStarted };
222
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/react/intro/components/GettingStarted.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport \"./GettingStarted.css\";\nimport { useRouter } from \"alepha/react/router\";\nimport type { ReactNode } from \"react\";\n\ntype Step = {\n num: string;\n text: ReactNode;\n};\n\ntype Message = {\n text: string;\n sub: string;\n detail?: string;\n steps?: Step[];\n links?: { label: string; href: string }[];\n};\n\nconst messages: Message[] = [\n {\n text: \"Let's begin.\",\n sub: \"Every story starts with a blank page.\",\n detail: \"This one is yours.\",\n },\n {\n text: \"Need help?\",\n sub: \"We've got you covered.\",\n detail: \"Even our AI friends can read the docs.\",\n links: [\n { label: \"alepha.dev\", href: \"https://alepha.dev\" },\n { label: \"llms.txt\", href: \"https://alepha.dev/llms.txt\" },\n ],\n },\n];\n\n/**\n * A welcome component displayed when creating a new Alepha application.\n */\nconst GettingStarted = () => {\n const [index, setIndex] = useState(0);\n const [direction, setDirection] = useState<\"next\" | \"prev\">(\"next\");\n\n const router = useRouter();\n const hasAdmin = router.pages.find((it) => it.name === \"adminLayout\");\n const hasAuth = router.pages.find((it) => it.name === \"authLayout\");\n\n const adminAnchorProps = hasAdmin\n ? router.anchor(router.path(\"adminLayout\"))\n : undefined;\n const authAnchorProps = hasAuth\n ? router.anchor(router.path(\"login\"))\n : undefined;\n\n const filteredMessages = useMemo(() => {\n const result: Message[] = [];\n\n // Add static messages up to \"What's next?\"\n for (const msg of messages) {\n if (msg.text === \"Need help?\") break;\n result.push(msg);\n }\n\n // Add auth message if available\n if (hasAuth && authAnchorProps) {\n result.push({\n text: \"Who are you?\",\n sub: \"Create your first account.\",\n steps: [\n {\n num: \"1\",\n text: (\n <>\n Sign up at <a {...authAnchorProps}>/auth/login</a>\n </>\n ),\n },\n {\n num: \"2\",\n text: (\n <>\n Customize in <code>src/api/AppSecurity.ts</code>\n </>\n ),\n },\n ],\n });\n }\n\n // Add admin message if available\n if (hasAdmin && adminAnchorProps) {\n result.push({\n text: \"Take the wheel.\",\n sub: \"Become admin in three steps.\",\n steps: [\n {\n num: \"1\",\n text: (\n <>\n Add your email to <code>adminEmails</code> in{\" \"}\n <code>AppSecurity.ts</code>\n </>\n ),\n },\n { num: \"2\", text: \"Create a user account with that email\" },\n {\n num: \"3\",\n text: (\n <>\n Go to <a {...adminAnchorProps}>/admin</a>\n </>\n ),\n },\n ],\n });\n }\n\n // Add \"Need help?\" message\n const helpMsg = messages.find((msg) => msg.text === \"Need help?\");\n if (helpMsg) {\n result.push(helpMsg);\n }\n\n return result;\n }, [hasAuth, hasAdmin, authAnchorProps, adminAnchorProps]);\n\n const current = filteredMessages[index];\n\n const prev = useCallback(() => {\n setDirection(\"prev\");\n setIndex(\n (i) => (i - 1 + filteredMessages.length) % filteredMessages.length,\n );\n }, [filteredMessages.length]);\n\n const next = useCallback(() => {\n setDirection(\"next\");\n setIndex((i) => (i + 1) % filteredMessages.length);\n }, [filteredMessages.length]);\n\n const goTo = useCallback(\n (i: number) => {\n setDirection(i > index ? \"next\" : \"prev\");\n setIndex(i);\n },\n [index],\n );\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"ArrowLeft\") {\n prev();\n } else if (e.key === \"ArrowRight\") {\n next();\n }\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [prev, next]);\n\n return (\n <main className=\"alepha-blank\">\n <div className=\"alepha-blank-content\">\n <div className=\"alepha-blank-text-block\">\n <h1\n className={`alepha-blank-message alepha-blank-slide-${direction}`}\n key={index}\n >\n {current.text}\n </h1>\n <p\n className={`alepha-blank-sub alepha-blank-slide-${direction}`}\n key={`sub-${index}`}\n >\n {current.sub}\n </p>\n {current.detail && (\n <p\n className={`alepha-blank-detail alepha-blank-slide-${direction}`}\n key={`detail-${index}`}\n >\n {current.detail}\n </p>\n )}\n {current.steps && (\n <div\n className={`alepha-blank-steps alepha-blank-slide-${direction}`}\n key={`steps-${index}`}\n >\n {current.steps.map((step, i) => (\n <div\n key={i}\n className=\"alepha-blank-step\"\n style={{ animationDelay: `${0.15 + i * 0.08}s` }}\n >\n <span className=\"alepha-blank-step-num\">{step.num}</span>\n <span className=\"alepha-blank-step-text\">{step.text}</span>\n </div>\n ))}\n </div>\n )}\n {current.links && (\n <div\n className={`alepha-blank-links alepha-blank-slide-${direction}`}\n key={`links-${index}`}\n >\n {current.links.map((link, i) => (\n <a\n key={link.href}\n href={link.href}\n target={link.href.startsWith(\"http\") ? \"_blank\" : undefined}\n rel={\n link.href.startsWith(\"http\")\n ? \"noopener noreferrer\"\n : undefined\n }\n style={{ animationDelay: `${0.1 + i * 0.05}s` }}\n >\n {link.label}\n </a>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"alepha-blank-slider\">\n <button\n className=\"alepha-blank-nav-btn\"\n onClick={prev}\n aria-label=\"Previous\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M9 3L5 7L9 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n <div className=\"alepha-blank-dots\">\n {filteredMessages.map((_, i) => (\n <button\n key={i}\n className={`alepha-blank-dot ${i === index ? \"active\" : \"\"}`}\n onClick={() => goTo(i)}\n aria-label={`Go to message ${i + 1}`}\n />\n ))}\n </div>\n <button\n className=\"alepha-blank-nav-btn\"\n onClick={next}\n aria-label=\"Next\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path\n d=\"M5 3L9 7L5 11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"alepha-blank-hint\">\n <kbd>←</kbd> <kbd>→</kbd> to navigate\n </div>\n </div>\n </main>\n );\n};\n\nexport default GettingStarted;\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { $atom, $env, $hook, $inject, $module, $use, Alepha, AlephaError, KIND, Primitive, createPrimitive, t } from "alepha";
2
2
  import { AlephaDateTime, DateTimeProvider } from "alepha/datetime";
3
3
  import { AlephaContext, AlephaReact, ClientOnly, ErrorBoundary, useAlepha, useEvents, useInject, useStore } from "alepha/react";
4
+ import { AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
4
5
  import { AlephaServer } from "alepha/server";
5
6
  import { AlephaServerLinks, LinkProvider } from "alepha/server/links";
6
7
  import { $logger } from "alepha/logger";
7
- import { BrowserHeadProvider } from "alepha/react/head";
8
8
  import { RouterProvider } from "alepha/router";
9
9
  import { StrictMode, createContext, createElement, memo, use, useEffect, useRef, useState } from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -1966,7 +1966,7 @@ const AlephaReactRouter = $module({
1966
1966
  ReactBrowserRendererProvider,
1967
1967
  ReactPageService
1968
1968
  ],
1969
- register: (alepha) => alepha.with(AlephaReact).with(AlephaDateTime).with(AlephaServer).with(AlephaServerLinks).with(ReactPageProvider).with(ReactBrowserProvider).with(ReactBrowserRouterProvider).with(ReactBrowserRendererProvider).with(ReactRouter)
1969
+ register: (alepha) => alepha.with(AlephaReact).with(AlephaReactHead).with(AlephaDateTime).with(AlephaServer).with(AlephaServerLinks).with(ReactPageProvider).with(ReactBrowserProvider).with(ReactBrowserRouterProvider).with(ReactBrowserRendererProvider).with(ReactRouter)
1970
1970
  });
1971
1971
 
1972
1972
  //#endregion