studiocms 0.2.0 → 0.4.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 (293) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/cli/add/index.d.ts +2 -2
  3. package/dist/cli/add/index.js +4 -3
  4. package/dist/cli/add/npm-utils.d.ts +6 -6
  5. package/dist/cli/add/tryToInstallPlugins.d.ts +1 -1
  6. package/dist/cli/add/tryToInstallPlugins.js +6 -5
  7. package/dist/cli/add/updateStudioCMSConfig.d.ts +1 -1
  8. package/dist/cli/add/updateStudioCMSConfig.js +3 -4
  9. package/dist/cli/add/validatePlugins.d.ts +1 -2
  10. package/dist/cli/add/validatePlugins.js +15 -9
  11. package/dist/cli/crypto/genJWT/index.d.ts +1 -1
  12. package/dist/cli/crypto/genJWT/index.js +8 -9
  13. package/dist/cli/crypto/index.d.ts +1 -1
  14. package/dist/cli/init/steps/env.js +14 -4
  15. package/dist/cli/init/steps/next.d.ts +1 -1
  16. package/dist/cli/init/steps/next.js +6 -5
  17. package/dist/cli/migrator/index.d.ts +1 -1
  18. package/dist/cli/migrator/index.js +2 -2
  19. package/dist/cli/users/index.d.ts +1 -1
  20. package/dist/cli/users/shared.js +2 -2
  21. package/dist/cli/users/steps/createUsers.js +7 -7
  22. package/dist/cli/users/steps/modifyUsers.js +2 -2
  23. package/dist/cli/users/steps/next.d.ts +1 -1
  24. package/dist/cli/utils/checkRequiredEnvVars.js +2 -2
  25. package/dist/cli/utils/context.d.ts +2 -4
  26. package/dist/cli/utils/context.js +1 -3
  27. package/dist/cli/utils/getCliDbClient.d.ts +1 -1
  28. package/dist/cli/utils/intro.d.ts +1 -1
  29. package/dist/cli/utils/loadConfig.d.ts +54 -49
  30. package/dist/cli/utils/loadConfig.js +5 -8
  31. package/dist/cli/utils/logger.js +3 -3
  32. package/dist/cli/utils/user-utils.d.ts +1 -1
  33. package/dist/cli/utils/user-utils.js +4 -3
  34. package/dist/client/apiClient.d.ts +4923 -0
  35. package/dist/client/apiClient.js +72 -0
  36. package/dist/config.d.ts +1734 -1
  37. package/dist/consts.d.ts +5 -5
  38. package/dist/consts.js +3 -2
  39. package/dist/db/plugins.d.ts +1 -1
  40. package/dist/db/plugins.js +5 -8
  41. package/dist/handlers/frontend/routes.d.ts +4 -18
  42. package/dist/handlers/frontend/routes.js +13 -152
  43. package/dist/handlers/frontend/types.d.ts +1 -1
  44. package/dist/handlers/frontend/utils.js +0 -18
  45. package/dist/handlers/pluginHandler.d.ts +34 -257
  46. package/dist/handlers/pluginHandler.js +92 -46
  47. package/dist/handlers/routeHandler.js +32 -11
  48. package/dist/handlers/setupDbStudio.d.ts +3 -1
  49. package/dist/handlers/setupDbStudio.js +19 -10
  50. package/dist/handlers/storage-manager/core/effectify-astro-context.d.ts +25 -0
  51. package/dist/handlers/storage-manager/core/effectify-astro-context.js +78 -0
  52. package/dist/handlers/storage-manager/no-op.d.ts +2 -2
  53. package/dist/handlers/storage-manager/no-op.js +2 -3
  54. package/dist/index.d.ts +0 -1
  55. package/dist/index.js +10 -20
  56. package/dist/integrations/robots/index.d.ts +2 -2
  57. package/dist/integrations/robots/index.js +1 -3
  58. package/dist/integrations/robots/schema.d.ts +102 -273
  59. package/dist/integrations/robots/schema.js +220 -209
  60. package/dist/plugins/analytics/assets/schemas.d.ts +14 -9
  61. package/dist/plugins/analytics/assets/schemas.js +25 -17
  62. package/dist/plugins/analytics/db-client.d.ts +1 -1
  63. package/dist/plugins/analytics/index.d.ts +823 -3
  64. package/dist/plugins/analytics/index.js +4 -5
  65. package/dist/plugins/analytics/schemas.d.ts +54 -62
  66. package/dist/plugins/analytics/schemas.js +64 -13
  67. package/dist/plugins/analytics/table.d.ts +1 -1
  68. package/dist/plugins.d.ts +0 -1
  69. package/dist/schemas/config/api.d.ts +17 -0
  70. package/dist/schemas/config/api.js +14 -0
  71. package/dist/schemas/config/auth.d.ts +55 -59
  72. package/dist/schemas/config/auth.js +34 -11
  73. package/dist/schemas/config/dashboard.d.ts +43 -79
  74. package/dist/schemas/config/dashboard.js +43 -12
  75. package/dist/schemas/config/db.d.ts +15 -17
  76. package/dist/schemas/config/db.js +13 -5
  77. package/dist/schemas/config/developer.d.ts +33 -45
  78. package/dist/schemas/config/developer.js +22 -5
  79. package/dist/schemas/config/index.d.ts +398 -521
  80. package/dist/schemas/config/index.js +115 -57
  81. package/dist/schemas/config/sdk.d.ts +50 -196
  82. package/dist/schemas/config/sdk.js +61 -73
  83. package/dist/schemas/custom.d.ts +40 -0
  84. package/dist/schemas/custom.js +41 -0
  85. package/dist/schemas/external-schemas.d.ts +171 -0
  86. package/dist/schemas/external-schemas.js +179 -0
  87. package/dist/schemas/index.d.ts +2 -0
  88. package/dist/schemas/index.js +2 -0
  89. package/dist/schemas/plugins/i18n.d.ts +59 -39
  90. package/dist/schemas/plugins/i18n.js +42 -5
  91. package/dist/schemas/plugins/index.d.ts +7126 -10296
  92. package/dist/schemas/plugins/index.js +260 -276
  93. package/dist/schemas/plugins/shared.d.ts +1293 -3718
  94. package/dist/schemas/plugins/shared.js +320 -329
  95. package/dist/test-utils.d.ts +15 -4
  96. package/dist/test-utils.js +27 -11
  97. package/dist/toolbar/db-viewer/db-shared-types.d.ts +6 -6
  98. package/dist/toolbar/db-viewer/studio/connection.d.ts +8 -4
  99. package/dist/toolbar/db-viewer/studio/connection.js +2 -28
  100. package/dist/toolbar/db-viewer/studio/env/libsql.d.ts +7 -0
  101. package/dist/toolbar/db-viewer/studio/env/libsql.js +17 -0
  102. package/dist/toolbar/db-viewer/studio/env/mysql.d.ts +7 -0
  103. package/dist/toolbar/db-viewer/studio/env/mysql.js +23 -0
  104. package/dist/toolbar/db-viewer/studio/env/postgres.d.ts +7 -0
  105. package/dist/toolbar/db-viewer/studio/env/postgres.js +23 -0
  106. package/dist/toolbar/db-viewer/studio/index.js +20 -56
  107. package/dist/toolbar/db-viewer/studio/type.d.ts +1 -2
  108. package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.d.ts +3 -0
  109. package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.js +24 -0
  110. package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.d.ts +3 -0
  111. package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.js +9 -0
  112. package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.d.ts +3 -0
  113. package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.js +9 -0
  114. package/dist/toolbar/db-viewer/viewer.js +20 -21
  115. package/dist/types.d.ts +30 -0
  116. package/dist/utils/effects/smtp.d.ts +1 -1
  117. package/dist/utils/lang-helper.d.ts +10 -2
  118. package/dist/virtual.d.ts +35 -28
  119. package/dist/virtuals/auth/core.d.ts +5 -5
  120. package/dist/virtuals/auth/verify-email.d.ts +6 -6
  121. package/dist/virtuals/components/Generator.astro +2 -2
  122. package/dist/virtuals/components/Renderer.astro +9 -1
  123. package/dist/virtuals/components/renderFn.d.ts +3 -1
  124. package/dist/virtuals/components/renderFn.js +18 -0
  125. package/dist/virtuals/lib/headDefaults.d.ts +4 -2
  126. package/dist/virtuals/lib/headDefaults.js +0 -2
  127. package/dist/virtuals/lib/routeMap.d.ts +0 -12
  128. package/dist/virtuals/lib/routeMap.js +2 -14
  129. package/dist/virtuals/mailer/index.d.ts +3 -3
  130. package/dist/virtuals/notifier/index.d.ts +5 -5
  131. package/dist/virtuals/plugins/dashboard-pages.d.ts +2 -64
  132. package/dist/virtuals/scripts/StorageFileBrowser.d.ts +1 -172
  133. package/dist/virtuals/scripts/StorageFileBrowser.js +216 -119
  134. package/dist/virtuals/template-engine/index.d.ts +4 -4
  135. package/frontend/components/dashboard/configuration/ConfigForm.astro +218 -110
  136. package/frontend/components/dashboard/content-mgmt/ContentSearch.astro +21 -22
  137. package/frontend/components/dashboard/content-mgmt/CreateFolder.astro +66 -54
  138. package/frontend/components/dashboard/content-mgmt/CreatePage.astro +58 -104
  139. package/frontend/components/dashboard/content-mgmt/EditFolder.astro +65 -67
  140. package/frontend/components/dashboard/content-mgmt/EditPage.astro +86 -134
  141. package/frontend/components/dashboard/content-mgmt/InnerSidebarElement.astro +0 -1
  142. package/frontend/components/dashboard/content-mgmt/PageHeader.astro +33 -52
  143. package/frontend/components/dashboard/content-mgmt/PageTypeHandler.astro +2 -2
  144. package/frontend/components/dashboard/profile/APITokens.astro +219 -158
  145. package/frontend/components/dashboard/profile/BasicInfo.astro +165 -106
  146. package/frontend/components/dashboard/profile/Notifications.astro +27 -18
  147. package/frontend/components/dashboard/profile/UpdatePassword.astro +134 -94
  148. package/frontend/components/dashboard/sidebar/VersionCheck.astro +31 -16
  149. package/frontend/components/dashboard/sidebar/VersionCheckChangelog.astro +18 -11
  150. package/frontend/components/dashboard/sidebar-modals/VersionModal.astro +2 -2
  151. package/frontend/components/dashboard/smtp-config/TemplateEditor.astro +14 -14
  152. package/frontend/components/dashboard/taxonomy/InnerSidebarElement.astro +0 -1
  153. package/frontend/components/dashboard/taxonomy/MetaContainer.astro +0 -2
  154. package/frontend/components/dashboard/taxonomy/PageHeader.astro +16 -24
  155. package/frontend/components/dashboard/taxonomy/TaxonomySearch.astro +23 -27
  156. package/frontend/components/dashboard/user-mgmt/InnerSidebarElement.astro +111 -104
  157. package/frontend/components/dashboard/user-mgmt/UserListItem.astro +9 -22
  158. package/frontend/components/dashboard/user-mgmt/UserListItems.astro +18 -0
  159. package/frontend/components/first-time-setup/snippets/{opt2-studiocms.config.diff → studiocms.config.diff} +1 -0
  160. package/frontend/components/shared/Code.astro +1 -4
  161. package/frontend/components/shared/DynamicSettingsRenderer.astro +1 -1
  162. package/frontend/components/shared/SSRUser.astro +2 -4
  163. package/frontend/components/shared/foldertree/FolderTreeNode.astro +0 -6
  164. package/frontend/components/shared/storage-manager/StorageCopyOutput.astro +0 -1
  165. package/frontend/components/shared/taxonomy/TaxonomyTreeNode.astro +0 -6
  166. package/frontend/layouts/DashboardLayout.astro +1 -10
  167. package/frontend/layouts/TaxonomyLayout.astro +0 -1
  168. package/frontend/middleware/index.ts +102 -61
  169. package/frontend/pages/404.astro +5 -9
  170. package/frontend/pages/[dashboard]/[...pluginPage].astro +10 -1
  171. package/frontend/pages/[dashboard]/configuration.astro +10 -1
  172. package/frontend/pages/[dashboard]/content-management/createfolder.astro +10 -1
  173. package/frontend/pages/[dashboard]/content-management/createpage.astro +10 -1
  174. package/frontend/pages/[dashboard]/content-management/diff.astro +39 -14
  175. package/frontend/pages/[dashboard]/content-management/editfolder.astro +10 -1
  176. package/frontend/pages/[dashboard]/content-management/editpage.astro +10 -1
  177. package/frontend/pages/[dashboard]/content-management/index.astro +10 -1
  178. package/frontend/pages/[dashboard]/index.astro +10 -1
  179. package/frontend/pages/[dashboard]/login.astro +86 -25
  180. package/frontend/pages/[dashboard]/password-reset.astro +22 -16
  181. package/frontend/pages/[dashboard]/plugins/[plugin].astro +10 -1
  182. package/frontend/pages/[dashboard]/profile.astro +10 -1
  183. package/frontend/pages/[dashboard]/signup.astro +153 -52
  184. package/frontend/pages/[dashboard]/smtp-configuration.astro +77 -75
  185. package/frontend/pages/[dashboard]/system-management.astro +10 -1
  186. package/frontend/pages/[dashboard]/taxonomy/categories.astro +30 -41
  187. package/frontend/pages/[dashboard]/taxonomy/index.astro +10 -0
  188. package/frontend/pages/[dashboard]/taxonomy/tags.astro +33 -43
  189. package/frontend/pages/[dashboard]/unverified-email.astro +29 -21
  190. package/frontend/pages/[dashboard]/user-management/edit.astro +170 -90
  191. package/frontend/pages/[dashboard]/user-management/index.astro +10 -1
  192. package/frontend/pages/studiocms_api/[...all].ts +106 -0
  193. package/frontend/pages/studiocms_api/_handlers/_utils/auth.ts +26 -0
  194. package/frontend/pages/studiocms_api/_handlers/_utils/changelog.ts +147 -0
  195. package/frontend/pages/studiocms_api/_handlers/_utils/db-studio-driver.ts +46 -0
  196. package/frontend/pages/studiocms_api/_handlers/_utils/parseLogLevel.ts +27 -0
  197. package/frontend/pages/studiocms_api/_handlers/auth/auth.ts +459 -0
  198. package/frontend/pages/studiocms_api/_handlers/auth/index.ts +17 -0
  199. package/frontend/pages/studiocms_api/_handlers/auth/oauth.ts +91 -0
  200. package/frontend/pages/studiocms_api/_handlers/dashboard/_shared.ts +57 -0
  201. package/frontend/pages/studiocms_api/_handlers/dashboard/apiTokens.ts +134 -0
  202. package/frontend/pages/studiocms_api/_handlers/dashboard/config.ts +64 -0
  203. package/frontend/pages/studiocms_api/_handlers/dashboard/content.ts +741 -0
  204. package/frontend/pages/studiocms_api/_handlers/dashboard/create.ts +480 -0
  205. package/frontend/pages/studiocms_api/_handlers/dashboard/emailNotifications.ts +49 -0
  206. package/frontend/pages/studiocms_api/_handlers/dashboard/index.ts +45 -0
  207. package/frontend/pages/studiocms_api/_handlers/dashboard/mailer.ts +136 -0
  208. package/frontend/pages/studiocms_api/_handlers/dashboard/plugins.ts +80 -0
  209. package/frontend/pages/studiocms_api/_handlers/dashboard/profile.ts +275 -0
  210. package/frontend/pages/studiocms_api/_handlers/dashboard/resetPassword.ts +140 -0
  211. package/frontend/pages/studiocms_api/_handlers/dashboard/search.ts +63 -0
  212. package/frontend/pages/studiocms_api/_handlers/dashboard/taxonomy.ts +285 -0
  213. package/frontend/pages/studiocms_api/_handlers/dashboard/templates.ts +75 -0
  214. package/frontend/pages/studiocms_api/_handlers/dashboard/users.ts +312 -0
  215. package/frontend/pages/studiocms_api/_handlers/dashboard/verifyEndpoints.ts +307 -0
  216. package/frontend/pages/studiocms_api/_handlers/integration/dbStudio.ts +98 -0
  217. package/frontend/pages/studiocms_api/_handlers/integration/index.ts +17 -0
  218. package/frontend/pages/studiocms_api/_handlers/integration/storageManager.ts +107 -0
  219. package/frontend/pages/studiocms_api/_handlers/rest-api/index.ts +8 -0
  220. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/_shared.ts +41 -0
  221. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/index.ts +17 -0
  222. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/public.ts +195 -0
  223. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/secure.ts +1726 -0
  224. package/frontend/pages/studiocms_api/_handlers/sdk.ts +129 -0
  225. package/frontend/pages/studiocms_api/_middleware/astroLocals.ts +36 -0
  226. package/frontend/pages/studiocms_api/_middleware/restApi.ts +56 -0
  227. package/frontend/pages/studiocms_api/integrations/[...all].ts +8 -0
  228. package/frontend/scripts/formdata.ts +219 -0
  229. package/frontend/setup-pages/3-done.astro +4 -20
  230. package/frontend/setup-pages/studiocms_api/dashboard/step-2.ts +3 -6
  231. package/frontend/styles/dashboard-base.css +0 -1
  232. package/frontend/web-vitals/endpoint.ts +2 -1
  233. package/package.json +35 -31
  234. package/dist/global.d.ts +0 -9
  235. package/frontend/components/dashboard/LoginChecker.astro +0 -68
  236. package/frontend/components/dashboard/user-mgmt/RankCheck.astro +0 -57
  237. package/frontend/components/first-time-setup/snippets/opt1-astro.config.diff +0 -14
  238. package/frontend/components/first-time-setup/snippets/opt2-astro.config.diff +0 -9
  239. package/frontend/middleware/_authmap.ts +0 -63
  240. package/frontend/pages/studiocms_api/auth/[path].ts +0 -390
  241. package/frontend/pages/studiocms_api/auth/[provider]/[...id].ts +0 -64
  242. package/frontend/pages/studiocms_api/auth/[provider]/_effects/index.ts +0 -101
  243. package/frontend/pages/studiocms_api/auth/_shared.ts +0 -52
  244. package/frontend/pages/studiocms_api/dashboard/api-tokens.ts +0 -115
  245. package/frontend/pages/studiocms_api/dashboard/config.ts +0 -74
  246. package/frontend/pages/studiocms_api/dashboard/content/diff.ts +0 -73
  247. package/frontend/pages/studiocms_api/dashboard/content/folder.ts +0 -220
  248. package/frontend/pages/studiocms_api/dashboard/content/page.ts +0 -359
  249. package/frontend/pages/studiocms_api/dashboard/create-reset-link.ts +0 -77
  250. package/frontend/pages/studiocms_api/dashboard/create-user-invite.ts +0 -231
  251. package/frontend/pages/studiocms_api/dashboard/create-user.ts +0 -186
  252. package/frontend/pages/studiocms_api/dashboard/email-notification-settings-site.ts +0 -74
  253. package/frontend/pages/studiocms_api/dashboard/mailer/check-email.ts +0 -75
  254. package/frontend/pages/studiocms_api/dashboard/mailer/config.ts +0 -136
  255. package/frontend/pages/studiocms_api/dashboard/plugins/[plugin].ts +0 -80
  256. package/frontend/pages/studiocms_api/dashboard/profile.ts +0 -245
  257. package/frontend/pages/studiocms_api/dashboard/resend-verify-email.ts +0 -77
  258. package/frontend/pages/studiocms_api/dashboard/reset-password.ts +0 -124
  259. package/frontend/pages/studiocms_api/dashboard/search-list.ts +0 -59
  260. package/frontend/pages/studiocms_api/dashboard/taxonomy-search.ts +0 -47
  261. package/frontend/pages/studiocms_api/dashboard/taxonomy.ts +0 -230
  262. package/frontend/pages/studiocms_api/dashboard/templates.ts +0 -74
  263. package/frontend/pages/studiocms_api/dashboard/update-user-notifications.ts +0 -86
  264. package/frontend/pages/studiocms_api/dashboard/users.ts +0 -236
  265. package/frontend/pages/studiocms_api/dashboard/verify-email.ts +0 -83
  266. package/frontend/pages/studiocms_api/dashboard/verify-session.ts +0 -187
  267. package/frontend/pages/studiocms_api/integrations/[type]/[...id].ts +0 -15
  268. package/frontend/pages/studiocms_api/integrations/[type]/_routes/db-studio.ts +0 -173
  269. package/frontend/pages/studiocms_api/integrations/[type]/_routes/storage.ts +0 -88
  270. package/frontend/pages/studiocms_api/partials/editor.astro +0 -74
  271. package/frontend/pages/studiocms_api/partials/render.astro +0 -39
  272. package/frontend/pages/studiocms_api/partials/user-list-items.astro +0 -43
  273. package/frontend/pages/studiocms_api/rest/utils/auth-token.ts +0 -59
  274. package/frontend/pages/studiocms_api/rest/v1/[type]/[...id].ts +0 -23
  275. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/categories.ts +0 -267
  276. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/folders.ts +0 -283
  277. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/pages.ts +0 -505
  278. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/settings.ts +0 -100
  279. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/tags.ts +0 -229
  280. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/users.ts +0 -553
  281. package/frontend/pages/studiocms_api/rest/v1/public/[type]/[...id].ts +0 -19
  282. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/categories.ts +0 -74
  283. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/folders.ts +0 -85
  284. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/pages.ts +0 -103
  285. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/tags.ts +0 -67
  286. package/frontend/pages/studiocms_api/sdk/[...path].ts +0 -97
  287. package/frontend/pages/studiocms_api/sdk/utils/changelog.ts +0 -119
  288. package/frontend/scripts/auth/formListener.ts +0 -81
  289. package/frontend/scripts/formdata-utils.ts +0 -116
  290. package/frontend/utils/build-partial-schema.ts +0 -46
  291. package/frontend/utils/errors.ts +0 -6
  292. package/frontend/utils/param-extractor.ts +0 -83
  293. package/frontend/utils/rest-router.ts +0 -444
@@ -1,187 +0,0 @@
1
- import { Session } from 'studiocms:auth/lib';
2
- import type { SessionValidationResult, UserSessionData } from 'studiocms:auth/lib/types';
3
- import { logger as _logger } from 'studiocms:logger';
4
- import { SDKCore } from 'studiocms:sdk';
5
- import {
6
- AllResponse,
7
- createEffectAPIRoutes,
8
- createJsonResponse,
9
- Effect,
10
- genLogger,
11
- OptionsResponse,
12
- parseAPIContextJson,
13
- Schema,
14
- } from '@withstudiocms/effect';
15
- import type { APIContext } from 'astro';
16
- import { AuthSessionCookieName } from '#consts';
17
-
18
- /**
19
- * Represents the JSON data structure for verifying a session in the dashboard API.
20
- *
21
- * @remarks
22
- * This class extends a schema definition for type-safe validation.
23
- *
24
- * @property originPathname - The original pathname as a string.
25
- */
26
- export class JsonData extends Schema.Class<JsonData>('JsonData')({
27
- originPathname: Schema.String,
28
- }) {}
29
-
30
- /**
31
- * Represents the response data for verifying a user session on the dashboard API.
32
- *
33
- * @property isLoggedIn - Indicates whether the user is currently logged in.
34
- * @property user - The authenticated user's information, or `null` if not logged in.
35
- * @property user.id - The unique identifier of the user.
36
- * @property user.name - The display name of the user.
37
- * @property user.email - The user's email address, or `null` if not available.
38
- * @property user.avatar - The URL to the user's avatar image, or `null` if not set.
39
- * @property user.username - The user's unique username.
40
- * @property permissionLevel - The user's permission level, as defined in `UserSessionData`.
41
- * @property routes - An object containing route paths relevant to the dashboard.
42
- * @property routes.logout - The route for logging out.
43
- * @property routes.userProfile - The route to the user's profile page.
44
- * @property routes.contentManagement - The route for content management.
45
- * @property routes.dashboardIndex - The route to the dashboard index page.
46
- */
47
- type ResponseData = {
48
- isLoggedIn: boolean;
49
- user: {
50
- id: string;
51
- name: string;
52
- email: string | null;
53
- avatar: string | null;
54
- username: string;
55
- } | null;
56
- permissionLevel: UserSessionData['permissionLevel'];
57
- routes: {
58
- logout: string;
59
- userProfile: string;
60
- contentManagement: string;
61
- dashboardIndex: string;
62
- };
63
- };
64
-
65
- /**
66
- * Builds a JSON HTTP response containing session verification data for the dashboard API.
67
- *
68
- * @param context - The API context containing local route mappings and other request-specific data.
69
- * @param isLoggedIn - Indicates whether the user is currently logged in.
70
- * @param user - The validated user object from the session, or `null` if not logged in.
71
- * @param permissionLevel - The user's permission level within the session.
72
- * @returns A `Response` object with a JSON body containing login status, user info, permission level, and relevant route URLs.
73
- */
74
- const responseBuilder = (
75
- context: APIContext,
76
- isLoggedIn: boolean,
77
- user: SessionValidationResult['user'],
78
- permissionLevel: UserSessionData['permissionLevel']
79
- ) => {
80
- const data: ResponseData = {
81
- isLoggedIn,
82
- user: user
83
- ? {
84
- id: user.id,
85
- name: user.name,
86
- email: user.email || null,
87
- avatar: user.avatar || null,
88
- username: user.username,
89
- }
90
- : null,
91
- permissionLevel: permissionLevel,
92
- routes: {
93
- logout: context.locals.StudioCMS.routeMap.authLinks.logoutAPI,
94
- userProfile: context.locals.StudioCMS.routeMap.mainLinks.userProfile,
95
- contentManagement: context.locals.StudioCMS.routeMap.mainLinks.contentManagement,
96
- dashboardIndex: context.locals.StudioCMS.routeMap.mainLinks.dashboardIndex,
97
- },
98
- };
99
-
100
- return createJsonResponse(data);
101
- };
102
-
103
- export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
104
- {
105
- POST: (ctx) =>
106
- genLogger('studiocms/routes/api/dashboard/verify-session.POST')(function* () {
107
- const [ses, sdk] = yield* Effect.all([Session, SDKCore]);
108
-
109
- const logger = _logger.fork('studiocms:runtime:api:verify-session');
110
-
111
- const { cookies } = ctx;
112
-
113
- const { originPathname } = yield* parseAPIContextJson(ctx, JsonData);
114
-
115
- const sessionToken = cookies.get(AuthSessionCookieName)?.value ?? null;
116
-
117
- if (!sessionToken) {
118
- logger.info(
119
- `No session token found in cookies, returning unknown session status. Origin: ${originPathname}`
120
- );
121
- return responseBuilder(ctx, false, null, 'unknown');
122
- }
123
-
124
- const { session, user } = yield* ses.validateSessionToken(sessionToken);
125
-
126
- if (session === null) {
127
- yield* ses.deleteSessionTokenCookie(ctx);
128
- logger.info(
129
- `Session token is invalid or expired, deleting cookie. Origin: ${originPathname}`
130
- );
131
- return responseBuilder(ctx, false, null, 'unknown');
132
- }
133
-
134
- if (!user || user === null) {
135
- logger.info(
136
- `No user found for session token, returning unknown session status. Origin: ${originPathname}`
137
- );
138
- return responseBuilder(ctx, false, null, 'unknown');
139
- }
140
-
141
- const result = yield* sdk.AUTH.permission.currentStatus(user.id);
142
-
143
- if (!result) {
144
- logger.error(
145
- `Failed to retrieve permission status for user ${user.id}, returning unknown session status. Origin: ${originPathname}`
146
- );
147
- return responseBuilder(ctx, true, user, 'unknown');
148
- }
149
-
150
- let permissionLevel: UserSessionData['permissionLevel'] = 'unknown';
151
-
152
- switch (result.rank) {
153
- case 'owner':
154
- permissionLevel = 'owner';
155
- break;
156
- case 'admin':
157
- permissionLevel = 'admin';
158
- break;
159
- case 'editor':
160
- permissionLevel = 'editor';
161
- break;
162
- case 'visitor':
163
- permissionLevel = 'visitor';
164
- break;
165
- default:
166
- permissionLevel = 'unknown';
167
- break;
168
- }
169
-
170
- return responseBuilder(ctx, true, user, permissionLevel);
171
- }),
172
- OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
173
- ALL: () => Effect.try(() => AllResponse()),
174
- },
175
- {
176
- cors: { methods: ['POST', 'OPTIONS'] },
177
- onError: (error) => {
178
- console.error('API Error:', error);
179
- return createJsonResponse(
180
- { error: 'Internal Server Error' },
181
- {
182
- status: 500,
183
- }
184
- );
185
- },
186
- }
187
- );
@@ -1,15 +0,0 @@
1
- import { Schema } from 'effect';
2
- import { createRestRouter, type RouteRegistry } from '#frontend/utils/rest-router.js';
3
- import { dbStudioRoute } from './_routes/db-studio.js';
4
- import { storageRoute } from './_routes/storage.js';
5
-
6
- const registry: RouteRegistry = {
7
- 'db-studio': dbStudioRoute,
8
- storage: storageRoute,
9
- };
10
-
11
- export const ALL = createRestRouter(
12
- 'studiocms:integrations',
13
- Schema.Literal('db-studio', 'storage'),
14
- registry
15
- );
@@ -1,173 +0,0 @@
1
- import config, { developerConfig } from 'studiocms:config';
2
- import {
3
- AllResponse,
4
- CMSLogger,
5
- createEffectAPIRoutes,
6
- createJsonResponse,
7
- genLogger,
8
- type LoggerLevel,
9
- OptionsResponse,
10
- } from '@withstudiocms/effect';
11
- import { Data, Effect } from 'effect';
12
- import { type EndpointRoute, pathRouter, type SubPathRouter } from '#frontend/utils/rest-router.js';
13
- import { type BaseDriver, type DbQueryRequest, getDriver } from '#toolbar/db-studio';
14
-
15
- export class DriverError extends Data.TaggedError('DriverError')<{ message: string }> {}
16
-
17
- let driver: BaseDriver | undefined;
18
-
19
- const useDriverErrorPromise = <T>(_try: () => Promise<T>) =>
20
- Effect.tryPromise({
21
- try: _try,
22
- catch: (error) =>
23
- new DriverError({ message: error instanceof Error ? error.message : String(error) }),
24
- });
25
-
26
- const getDriverInstance = Effect.fn('getDriverInstance')(function* () {
27
- // Return existing driver if already initialized
28
- if (driver) return driver;
29
-
30
- // Attempt to get and initialize the driver
31
- driver = yield* useDriverErrorPromise(() => getDriver()).pipe(
32
- Effect.tap((drv) => useDriverErrorPromise(() => drv.init()))
33
- );
34
-
35
- // If driver is still undefined, return an error
36
- if (!driver) {
37
- return yield* new DriverError({ message: 'Failed to get database driver' });
38
- }
39
-
40
- // Return the initialized driver
41
- return driver;
42
- });
43
-
44
- const parseLogLevel = (
45
- level: 'All' | 'Fatal' | 'Error' | 'Warning' | 'Info' | 'Debug' | 'Trace' | 'None'
46
- ): LoggerLevel => {
47
- switch (level) {
48
- case 'Info':
49
- return 'info';
50
- case 'Warning':
51
- return 'warn';
52
- case 'Error':
53
- return 'error';
54
- case 'All':
55
- case 'Fatal':
56
- case 'Debug':
57
- case 'Trace':
58
- return 'debug';
59
- case 'None':
60
- return 'silent';
61
- }
62
- };
63
-
64
- const jsonResponse = (data: unknown, status = 200): Response =>
65
- new Response(JSON.stringify(data), {
66
- headers: { 'Content-Type': 'application/json' },
67
- status,
68
- });
69
-
70
- const dbStudioSubRouter: SubPathRouter = {
71
- query: (_id: string) =>
72
- createEffectAPIRoutes(
73
- {
74
- POST: ({ request, locals }) =>
75
- genLogger('studiocms:integrations:db-studio:query:POST')(function* () {
76
- // Determine if we are in development mode
77
- const isDev = import.meta.env.DEV;
78
-
79
- const logLevel = parseLogLevel(config.logLevel);
80
-
81
- const log = new CMSLogger({ level: logLevel }, 'studiocms:database/studio');
82
-
83
- // Check if demo mode is enabled
84
- if (developerConfig.demoMode !== false) {
85
- return createJsonResponse(
86
- { error: 'Demo mode is enabled, this action is not allowed.' },
87
- { status: 403 }
88
- );
89
- }
90
-
91
- // Security check: only allow access in the following cases
92
- // 1. In development mode
93
- // 2. In production, only if the user is an owner
94
- if (!isDev && !locals.StudioCMS.security?.userPermissionLevel.isOwner) {
95
- return createJsonResponse({ error: 'Forbidden' }, { status: 403 });
96
- }
97
-
98
- // Parse the request body
99
- const body: DbQueryRequest = yield* Effect.tryPromise({
100
- try: () => request.json(),
101
- catch: (error) =>
102
- new DriverError({
103
- message: `Invalid JSON body: ${error instanceof Error ? error.message : String(error)}`,
104
- }),
105
- });
106
-
107
- // Get the database driver instance
108
- const driver = yield* getDriverInstance();
109
-
110
- log.debug(`Received ${body.type} request`);
111
-
112
- try {
113
- if (body.type === 'query') {
114
- const r = yield* useDriverErrorPromise(() => driver.query(body.statement));
115
- return jsonResponse({
116
- type: body.type,
117
- id: body.id,
118
- data: r,
119
- });
120
- }
121
-
122
- const r = yield* useDriverErrorPromise(() => driver.batch(body.statements));
123
-
124
- log.debug(`${body.type} executed with ${r.length} results`);
125
-
126
- return jsonResponse({
127
- type: body.type,
128
- id: body.id,
129
- data: r,
130
- });
131
- } catch (e) {
132
- log.error(
133
- `Error handling ${body.type} request with ID ${body.id}: ${(e as Error).message}`
134
- );
135
- return jsonResponse(
136
- {
137
- type: body.type,
138
- id: body.id,
139
- error: (e as Error).message,
140
- },
141
- 500
142
- );
143
- }
144
- }),
145
- OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST', 'OPTIONS'] })),
146
- ALL: () => Effect.try(() => AllResponse()),
147
- },
148
- {
149
- cors: { methods: ['POST', 'OPTIONS'] },
150
- onError: (error) => {
151
- console.error('API Error:', error);
152
- return createJsonResponse({ error: 'Something went wrong' }, { status: 500 });
153
- },
154
- }
155
- ),
156
- };
157
-
158
- export const dbStudioRoute: EndpointRoute = {
159
- __idType: 'string',
160
- __index: createEffectAPIRoutes(
161
- {
162
- ALL: () => Effect.try(() => AllResponse()),
163
- },
164
- {
165
- cors: {},
166
- onError: (error) => {
167
- console.error('API Error:', error);
168
- return createJsonResponse({ error: 'Something went wrong' }, { status: 500 });
169
- },
170
- }
171
- ),
172
- id: (id: string) => pathRouter(id, dbStudioSubRouter),
173
- };
@@ -1,88 +0,0 @@
1
- import APIServiceModule from 'studiocms:storage-manager/module';
2
- import {
3
- AllResponse,
4
- createEffectAPIRoutes,
5
- createJsonResponse,
6
- OptionsResponse,
7
- } from '@withstudiocms/effect';
8
- import type { APIContext } from 'astro';
9
- import { Effect } from 'effect';
10
- import { type EndpointRoute, pathRouter, type SubPathRouter } from '#frontend/utils/rest-router.js';
11
- import APICore from '#storage-manager/core/api-core';
12
- import AstroContextDriver from '#storage-manager/core/astro-context';
13
- import UrlMappingDatabase from '#storage-manager/core/database';
14
- import UrlMappingService from '#storage-manager/core/url-mapping';
15
-
16
- let apiCore: APICore<APIContext, Response>;
17
-
18
- /**
19
- * Retrieves the singleton instance of the APICore.
20
- *
21
- * This function initializes the APICore instance if it hasn't been created yet,
22
- * setting up the necessary context driver, URL mapping service, and API service module.
23
- *
24
- * @returns The singleton APICore instance.
25
- */
26
- function getAPICore() {
27
- if (apiCore) {
28
- return apiCore;
29
- }
30
-
31
- // Instantiate the Astro context driver
32
- const astroContextDriver = new AstroContextDriver();
33
-
34
- // Instantiate the database
35
- const database = new UrlMappingDatabase();
36
-
37
- // Instantiate the URL mapping service
38
- const urlMappingService = new UrlMappingService(database);
39
-
40
- // Instantiate the API service module
41
- const apiService = new APIServiceModule(astroContextDriver, urlMappingService);
42
-
43
- // Instantiate the API core
44
- apiCore = new APICore({
45
- driver: astroContextDriver,
46
- urlMappingService: urlMappingService,
47
- storageDriver: apiService,
48
- });
49
-
50
- return apiCore;
51
- }
52
-
53
- const storageSubRouter: SubPathRouter = {
54
- manager: (_id: string) =>
55
- createEffectAPIRoutes(
56
- {
57
- POST: (ctx) => Effect.tryPromise(async () => getAPICore().getPOST('locals')(ctx)),
58
- PUT: (ctx) => Effect.tryPromise(async () => getAPICore().getPUT('locals')(ctx)),
59
- OPTIONS: () =>
60
- Effect.try(() => OptionsResponse({ allowedMethods: ['POST', 'PUT', 'OPTIONS'] })),
61
- ALL: () => Effect.try(() => AllResponse()),
62
- },
63
- {
64
- cors: { methods: ['POST', 'PUT', 'OPTIONS'] },
65
- onError: (error) => {
66
- console.error('API Error:', error);
67
- return createJsonResponse({ error: 'Something went wrong' }, { status: 500 });
68
- },
69
- }
70
- ),
71
- };
72
-
73
- export const storageRoute: EndpointRoute = {
74
- __idType: 'string',
75
- __index: createEffectAPIRoutes(
76
- {
77
- ALL: () => Effect.try(() => AllResponse()),
78
- },
79
- {
80
- cors: {},
81
- onError: (error) => {
82
- console.error('API Error:', error);
83
- return createJsonResponse({ error: 'Something went wrong' }, { status: 500 });
84
- },
85
- }
86
- ),
87
- id: (id: string) => pathRouter(id, storageSubRouter),
88
- };
@@ -1,74 +0,0 @@
1
- ---
2
- export const partial = true;
3
-
4
- import pluginsList from 'studiocms:plugins';
5
- import { AstroError } from 'astro/errors';
6
-
7
- type RawJsonData = {
8
- content: string | undefined;
9
- editor: string;
10
- };
11
-
12
- type EditorComponent = (_props?: {
13
- content?: string | null | undefined;
14
- // biome-ignore lint/suspicious/noExplicitAny: This is a valid use case for explicit any.
15
- }) => any;
16
-
17
- type EditorComponentItem = {
18
- identifier: string;
19
- Component: EditorComponent;
20
- };
21
-
22
- async function load() {
23
- const jsonData: RawJsonData | undefined = await Astro.request.json();
24
-
25
- const pageTypeComponents: EditorComponentItem[] = [];
26
-
27
- for (const { pageTypes } of pluginsList) {
28
- if (!pageTypes) continue;
29
-
30
- for (const { identifier, pageContentComponent } of pageTypes) {
31
- if (!pageContentComponent) continue;
32
-
33
- pageTypeComponents.push({
34
- identifier,
35
- Component: (await import(/* @vite-ignore */ pageContentComponent)).default,
36
- });
37
- }
38
- }
39
-
40
- let Editor: EditorComponentItem | undefined;
41
-
42
- Editor = pageTypeComponents.find((ed) => ed.identifier === jsonData?.editor);
43
-
44
- if (!Editor) {
45
- const MarkdownEditor = pageTypeComponents.find(
46
- (editor) => editor.identifier === 'studiocms/markdown'
47
- );
48
- if (MarkdownEditor) {
49
- Editor = MarkdownEditor;
50
- } else {
51
- throw new AstroError(
52
- `No editor found for identifier: ${jsonData?.editor}`,
53
- 'StudioCMSDashboardPartialEditorError - No editor found'
54
- );
55
- }
56
- }
57
-
58
- if (jsonData?.content) {
59
- return {
60
- content: jsonData.content,
61
- ActiveEditor: Editor.Component,
62
- };
63
- }
64
-
65
- return {
66
- content: 'No content to display',
67
- ActiveEditor: Editor.Component,
68
- };
69
- }
70
-
71
- const { content, ActiveEditor } = await load();
72
- ---
73
-
74
- <ActiveEditor content={content} />
@@ -1,39 +0,0 @@
1
- ---
2
- export const partial = true;
3
-
4
- import { pipe } from '@withstudiocms/effect';
5
- import { parseMarkdown } from '#utils/tinyMDParser';
6
-
7
- type FullJsonData = { content: string | undefined };
8
-
9
- const html = pipe(
10
- {
11
- queryParam: Astro.url.searchParams.get('content'),
12
- preQuery: Astro.url.searchParams.get('preload-content'),
13
- astroJsonData: await (async () => {
14
- const ct = Astro.request.headers.get('content-type') ?? '';
15
- if (!ct.toLowerCase().includes('application/json')) return undefined;
16
- try {
17
- return (await Astro.request.json()) as FullJsonData;
18
- } catch {
19
- return undefined;
20
- }
21
- })(),
22
- },
23
- (data) => {
24
- const { queryParam, preQuery, astroJsonData } = data;
25
- if (astroJsonData && astroJsonData.content !== undefined) {
26
- return astroJsonData.content;
27
- }
28
- if (queryParam && queryParam !== 'null') {
29
- return queryParam;
30
- }
31
- if (preQuery && preQuery !== 'null') {
32
- return preQuery;
33
- }
34
- return 'No content to display';
35
- },
36
- (content) => parseMarkdown(content)
37
- );
38
- ---
39
- <Fragment set:html={html} />
@@ -1,43 +0,0 @@
1
- ---
2
- export const partial = true;
3
-
4
- import type { AvailablePermissionRanks } from '@withstudiocms/auth-kit/types';
5
- import UserListItem from '../../../components/dashboard/user-mgmt/UserListItem.astro';
6
-
7
- type PermissionsData = {
8
- user: string;
9
- rank: AvailablePermissionRanks;
10
- };
11
-
12
- type Users = {
13
- id: string;
14
- name: string;
15
- email: string | null;
16
- avatar: string | null;
17
- username: string;
18
- permissionsData: PermissionsData | undefined;
19
- };
20
-
21
- type FullJsonData = {
22
- users: Users[];
23
- searchQuery?: string;
24
- };
25
-
26
- async function setData() {
27
- const jsonData: FullJsonData | undefined = await Astro.request.json();
28
-
29
- if (jsonData) return jsonData;
30
-
31
- return 'No Users to display';
32
- }
33
-
34
- const usersData = await setData();
35
- ---
36
-
37
- {
38
- typeof usersData !== "string"
39
- ? usersData.users.map((user) => (
40
- <UserListItem user={user} searchQuery={usersData.searchQuery} />
41
- ))
42
- : usersData
43
- }
@@ -1,59 +0,0 @@
1
- import { apiResponseLogger } from 'studiocms:logger';
2
- import { SDKCore } from 'studiocms:sdk';
3
- import { Effect, genLogger } from '@withstudiocms/effect';
4
- import type { APIContext } from 'astro';
5
-
6
- /**
7
- * Extracts the Bearer authentication token from the `Authorization` header of the given API context's request.
8
- *
9
- * This function attempts to retrieve the `Authorization` header from the request, and if present,
10
- * parses it to extract the token part of a Bearer token. If the header is missing, malformed, or does not
11
- * use the Bearer scheme, the function returns `null`.
12
- *
13
- * @param context - The API context containing the request object with headers.
14
- * @returns The extracted Bearer token as a string, or `null` if not found or invalid.
15
- */
16
- const getAuthTokenFromHeader = (context: APIContext) =>
17
- genLogger('routes/rest/utils/auth-token/getAuthTokenFromHeader')(function* () {
18
- const authTokenData = yield* Effect.try(() => context.request.headers.get('Authorization'));
19
-
20
- if (!authTokenData) {
21
- return null;
22
- }
23
-
24
- const parts = authTokenData.split(' ');
25
-
26
- if (parts.length !== 2 || parts[0].toLowerCase() !== 'bearer') {
27
- return null;
28
- }
29
-
30
- return parts[1];
31
- });
32
-
33
- /**
34
- * Verifies the authentication token from the request header in the given API context.
35
- *
36
- * This generator function attempts to extract an authentication token from the request header,
37
- * verifies it using the SDK's REST API, and returns the associated user if verification succeeds.
38
- * If the token is missing or invalid, it returns a 401 Unauthorized API response.
39
- *
40
- * @param context - The API context containing the request information.
41
- * @returns The verified user object if authentication succeeds, or a 401 Unauthorized response if it fails.
42
- */
43
- export const verifyAuthTokenFromHeader = (context: APIContext) =>
44
- genLogger('routes/rest/utils/auth-token/verifyAuthTokenFromHeader')(function* () {
45
- const sdk = yield* SDKCore;
46
-
47
- const authToken = yield* getAuthTokenFromHeader(context);
48
-
49
- if (!authToken) {
50
- return apiResponseLogger(401, 'Unauthorized');
51
- }
52
-
53
- const user = yield* sdk.REST_API.tokens.verify(authToken);
54
-
55
- if (!user) {
56
- return apiResponseLogger(401, 'Unauthorized');
57
- }
58
- return user;
59
- });