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.
- package/CHANGELOG.md +122 -0
- package/dist/cli/add/index.d.ts +2 -2
- package/dist/cli/add/index.js +4 -3
- package/dist/cli/add/npm-utils.d.ts +6 -6
- package/dist/cli/add/tryToInstallPlugins.d.ts +1 -1
- package/dist/cli/add/tryToInstallPlugins.js +6 -5
- package/dist/cli/add/updateStudioCMSConfig.d.ts +1 -1
- package/dist/cli/add/updateStudioCMSConfig.js +3 -4
- package/dist/cli/add/validatePlugins.d.ts +1 -2
- package/dist/cli/add/validatePlugins.js +15 -9
- package/dist/cli/crypto/genJWT/index.d.ts +1 -1
- package/dist/cli/crypto/genJWT/index.js +8 -9
- package/dist/cli/crypto/index.d.ts +1 -1
- package/dist/cli/init/steps/env.js +14 -4
- package/dist/cli/init/steps/next.d.ts +1 -1
- package/dist/cli/init/steps/next.js +6 -5
- package/dist/cli/migrator/index.d.ts +1 -1
- package/dist/cli/migrator/index.js +2 -2
- package/dist/cli/users/index.d.ts +1 -1
- package/dist/cli/users/shared.js +2 -2
- package/dist/cli/users/steps/createUsers.js +7 -7
- package/dist/cli/users/steps/modifyUsers.js +2 -2
- package/dist/cli/users/steps/next.d.ts +1 -1
- package/dist/cli/utils/checkRequiredEnvVars.js +2 -2
- package/dist/cli/utils/context.d.ts +2 -4
- package/dist/cli/utils/context.js +1 -3
- package/dist/cli/utils/getCliDbClient.d.ts +1 -1
- package/dist/cli/utils/intro.d.ts +1 -1
- package/dist/cli/utils/loadConfig.d.ts +54 -49
- package/dist/cli/utils/loadConfig.js +5 -8
- package/dist/cli/utils/logger.js +3 -3
- package/dist/cli/utils/user-utils.d.ts +1 -1
- package/dist/cli/utils/user-utils.js +4 -3
- package/dist/client/apiClient.d.ts +4923 -0
- package/dist/client/apiClient.js +72 -0
- package/dist/config.d.ts +1734 -1
- package/dist/consts.d.ts +5 -5
- package/dist/consts.js +3 -2
- package/dist/db/plugins.d.ts +1 -1
- package/dist/db/plugins.js +5 -8
- package/dist/handlers/frontend/routes.d.ts +4 -18
- package/dist/handlers/frontend/routes.js +13 -152
- package/dist/handlers/frontend/types.d.ts +1 -1
- package/dist/handlers/frontend/utils.js +0 -18
- package/dist/handlers/pluginHandler.d.ts +34 -257
- package/dist/handlers/pluginHandler.js +92 -46
- package/dist/handlers/routeHandler.js +32 -11
- package/dist/handlers/setupDbStudio.d.ts +3 -1
- package/dist/handlers/setupDbStudio.js +19 -10
- package/dist/handlers/storage-manager/core/effectify-astro-context.d.ts +25 -0
- package/dist/handlers/storage-manager/core/effectify-astro-context.js +78 -0
- package/dist/handlers/storage-manager/no-op.d.ts +2 -2
- package/dist/handlers/storage-manager/no-op.js +2 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.js +10 -20
- package/dist/integrations/robots/index.d.ts +2 -2
- package/dist/integrations/robots/index.js +1 -3
- package/dist/integrations/robots/schema.d.ts +102 -273
- package/dist/integrations/robots/schema.js +220 -209
- package/dist/plugins/analytics/assets/schemas.d.ts +14 -9
- package/dist/plugins/analytics/assets/schemas.js +25 -17
- package/dist/plugins/analytics/db-client.d.ts +1 -1
- package/dist/plugins/analytics/index.d.ts +823 -3
- package/dist/plugins/analytics/index.js +4 -5
- package/dist/plugins/analytics/schemas.d.ts +54 -62
- package/dist/plugins/analytics/schemas.js +64 -13
- package/dist/plugins/analytics/table.d.ts +1 -1
- package/dist/plugins.d.ts +0 -1
- package/dist/schemas/config/api.d.ts +17 -0
- package/dist/schemas/config/api.js +14 -0
- package/dist/schemas/config/auth.d.ts +55 -59
- package/dist/schemas/config/auth.js +34 -11
- package/dist/schemas/config/dashboard.d.ts +43 -79
- package/dist/schemas/config/dashboard.js +43 -12
- package/dist/schemas/config/db.d.ts +15 -17
- package/dist/schemas/config/db.js +13 -5
- package/dist/schemas/config/developer.d.ts +33 -45
- package/dist/schemas/config/developer.js +22 -5
- package/dist/schemas/config/index.d.ts +398 -521
- package/dist/schemas/config/index.js +115 -57
- package/dist/schemas/config/sdk.d.ts +50 -196
- package/dist/schemas/config/sdk.js +61 -73
- package/dist/schemas/custom.d.ts +40 -0
- package/dist/schemas/custom.js +41 -0
- package/dist/schemas/external-schemas.d.ts +171 -0
- package/dist/schemas/external-schemas.js +179 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/plugins/i18n.d.ts +59 -39
- package/dist/schemas/plugins/i18n.js +42 -5
- package/dist/schemas/plugins/index.d.ts +7126 -10296
- package/dist/schemas/plugins/index.js +260 -276
- package/dist/schemas/plugins/shared.d.ts +1293 -3718
- package/dist/schemas/plugins/shared.js +320 -329
- package/dist/test-utils.d.ts +15 -4
- package/dist/test-utils.js +27 -11
- package/dist/toolbar/db-viewer/db-shared-types.d.ts +6 -6
- package/dist/toolbar/db-viewer/studio/connection.d.ts +8 -4
- package/dist/toolbar/db-viewer/studio/connection.js +2 -28
- package/dist/toolbar/db-viewer/studio/env/libsql.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/libsql.js +17 -0
- package/dist/toolbar/db-viewer/studio/env/mysql.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/mysql.js +23 -0
- package/dist/toolbar/db-viewer/studio/env/postgres.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/postgres.js +23 -0
- package/dist/toolbar/db-viewer/studio/index.js +20 -56
- package/dist/toolbar/db-viewer/studio/type.d.ts +1 -2
- package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.js +24 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.js +9 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.js +9 -0
- package/dist/toolbar/db-viewer/viewer.js +20 -21
- package/dist/types.d.ts +30 -0
- package/dist/utils/effects/smtp.d.ts +1 -1
- package/dist/utils/lang-helper.d.ts +10 -2
- package/dist/virtual.d.ts +35 -28
- package/dist/virtuals/auth/core.d.ts +5 -5
- package/dist/virtuals/auth/verify-email.d.ts +6 -6
- package/dist/virtuals/components/Generator.astro +2 -2
- package/dist/virtuals/components/Renderer.astro +9 -1
- package/dist/virtuals/components/renderFn.d.ts +3 -1
- package/dist/virtuals/components/renderFn.js +18 -0
- package/dist/virtuals/lib/headDefaults.d.ts +4 -2
- package/dist/virtuals/lib/headDefaults.js +0 -2
- package/dist/virtuals/lib/routeMap.d.ts +0 -12
- package/dist/virtuals/lib/routeMap.js +2 -14
- package/dist/virtuals/mailer/index.d.ts +3 -3
- package/dist/virtuals/notifier/index.d.ts +5 -5
- package/dist/virtuals/plugins/dashboard-pages.d.ts +2 -64
- package/dist/virtuals/scripts/StorageFileBrowser.d.ts +1 -172
- package/dist/virtuals/scripts/StorageFileBrowser.js +216 -119
- package/dist/virtuals/template-engine/index.d.ts +4 -4
- package/frontend/components/dashboard/configuration/ConfigForm.astro +218 -110
- package/frontend/components/dashboard/content-mgmt/ContentSearch.astro +21 -22
- package/frontend/components/dashboard/content-mgmt/CreateFolder.astro +66 -54
- package/frontend/components/dashboard/content-mgmt/CreatePage.astro +58 -104
- package/frontend/components/dashboard/content-mgmt/EditFolder.astro +65 -67
- package/frontend/components/dashboard/content-mgmt/EditPage.astro +86 -134
- package/frontend/components/dashboard/content-mgmt/InnerSidebarElement.astro +0 -1
- package/frontend/components/dashboard/content-mgmt/PageHeader.astro +33 -52
- package/frontend/components/dashboard/content-mgmt/PageTypeHandler.astro +2 -2
- package/frontend/components/dashboard/profile/APITokens.astro +219 -158
- package/frontend/components/dashboard/profile/BasicInfo.astro +165 -106
- package/frontend/components/dashboard/profile/Notifications.astro +27 -18
- package/frontend/components/dashboard/profile/UpdatePassword.astro +134 -94
- package/frontend/components/dashboard/sidebar/VersionCheck.astro +31 -16
- package/frontend/components/dashboard/sidebar/VersionCheckChangelog.astro +18 -11
- package/frontend/components/dashboard/sidebar-modals/VersionModal.astro +2 -2
- package/frontend/components/dashboard/smtp-config/TemplateEditor.astro +14 -14
- package/frontend/components/dashboard/taxonomy/InnerSidebarElement.astro +0 -1
- package/frontend/components/dashboard/taxonomy/MetaContainer.astro +0 -2
- package/frontend/components/dashboard/taxonomy/PageHeader.astro +16 -24
- package/frontend/components/dashboard/taxonomy/TaxonomySearch.astro +23 -27
- package/frontend/components/dashboard/user-mgmt/InnerSidebarElement.astro +111 -104
- package/frontend/components/dashboard/user-mgmt/UserListItem.astro +9 -22
- package/frontend/components/dashboard/user-mgmt/UserListItems.astro +18 -0
- package/frontend/components/first-time-setup/snippets/{opt2-studiocms.config.diff → studiocms.config.diff} +1 -0
- package/frontend/components/shared/Code.astro +1 -4
- package/frontend/components/shared/DynamicSettingsRenderer.astro +1 -1
- package/frontend/components/shared/SSRUser.astro +2 -4
- package/frontend/components/shared/foldertree/FolderTreeNode.astro +0 -6
- package/frontend/components/shared/storage-manager/StorageCopyOutput.astro +0 -1
- package/frontend/components/shared/taxonomy/TaxonomyTreeNode.astro +0 -6
- package/frontend/layouts/DashboardLayout.astro +1 -10
- package/frontend/layouts/TaxonomyLayout.astro +0 -1
- package/frontend/middleware/index.ts +102 -61
- package/frontend/pages/404.astro +5 -9
- package/frontend/pages/[dashboard]/[...pluginPage].astro +10 -1
- package/frontend/pages/[dashboard]/configuration.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/createfolder.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/createpage.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/diff.astro +39 -14
- package/frontend/pages/[dashboard]/content-management/editfolder.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/editpage.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/index.astro +10 -1
- package/frontend/pages/[dashboard]/index.astro +10 -1
- package/frontend/pages/[dashboard]/login.astro +86 -25
- package/frontend/pages/[dashboard]/password-reset.astro +22 -16
- package/frontend/pages/[dashboard]/plugins/[plugin].astro +10 -1
- package/frontend/pages/[dashboard]/profile.astro +10 -1
- package/frontend/pages/[dashboard]/signup.astro +153 -52
- package/frontend/pages/[dashboard]/smtp-configuration.astro +77 -75
- package/frontend/pages/[dashboard]/system-management.astro +10 -1
- package/frontend/pages/[dashboard]/taxonomy/categories.astro +30 -41
- package/frontend/pages/[dashboard]/taxonomy/index.astro +10 -0
- package/frontend/pages/[dashboard]/taxonomy/tags.astro +33 -43
- package/frontend/pages/[dashboard]/unverified-email.astro +29 -21
- package/frontend/pages/[dashboard]/user-management/edit.astro +170 -90
- package/frontend/pages/[dashboard]/user-management/index.astro +10 -1
- package/frontend/pages/studiocms_api/[...all].ts +106 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/auth.ts +26 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/changelog.ts +147 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/db-studio-driver.ts +46 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/parseLogLevel.ts +27 -0
- package/frontend/pages/studiocms_api/_handlers/auth/auth.ts +459 -0
- package/frontend/pages/studiocms_api/_handlers/auth/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/auth/oauth.ts +91 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/_shared.ts +57 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/apiTokens.ts +134 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/config.ts +64 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/content.ts +741 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/create.ts +480 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/emailNotifications.ts +49 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/index.ts +45 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/mailer.ts +136 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/plugins.ts +80 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/profile.ts +275 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/resetPassword.ts +140 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/search.ts +63 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/taxonomy.ts +285 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/templates.ts +75 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/users.ts +312 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/verifyEndpoints.ts +307 -0
- package/frontend/pages/studiocms_api/_handlers/integration/dbStudio.ts +98 -0
- package/frontend/pages/studiocms_api/_handlers/integration/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/integration/storageManager.ts +107 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/index.ts +8 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/_shared.ts +41 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/public.ts +195 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/secure.ts +1726 -0
- package/frontend/pages/studiocms_api/_handlers/sdk.ts +129 -0
- package/frontend/pages/studiocms_api/_middleware/astroLocals.ts +36 -0
- package/frontend/pages/studiocms_api/_middleware/restApi.ts +56 -0
- package/frontend/pages/studiocms_api/integrations/[...all].ts +8 -0
- package/frontend/scripts/formdata.ts +219 -0
- package/frontend/setup-pages/3-done.astro +4 -20
- package/frontend/setup-pages/studiocms_api/dashboard/step-2.ts +3 -6
- package/frontend/styles/dashboard-base.css +0 -1
- package/frontend/web-vitals/endpoint.ts +2 -1
- package/package.json +35 -31
- package/dist/global.d.ts +0 -9
- package/frontend/components/dashboard/LoginChecker.astro +0 -68
- package/frontend/components/dashboard/user-mgmt/RankCheck.astro +0 -57
- package/frontend/components/first-time-setup/snippets/opt1-astro.config.diff +0 -14
- package/frontend/components/first-time-setup/snippets/opt2-astro.config.diff +0 -9
- package/frontend/middleware/_authmap.ts +0 -63
- package/frontend/pages/studiocms_api/auth/[path].ts +0 -390
- package/frontend/pages/studiocms_api/auth/[provider]/[...id].ts +0 -64
- package/frontend/pages/studiocms_api/auth/[provider]/_effects/index.ts +0 -101
- package/frontend/pages/studiocms_api/auth/_shared.ts +0 -52
- package/frontend/pages/studiocms_api/dashboard/api-tokens.ts +0 -115
- package/frontend/pages/studiocms_api/dashboard/config.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/content/diff.ts +0 -73
- package/frontend/pages/studiocms_api/dashboard/content/folder.ts +0 -220
- package/frontend/pages/studiocms_api/dashboard/content/page.ts +0 -359
- package/frontend/pages/studiocms_api/dashboard/create-reset-link.ts +0 -77
- package/frontend/pages/studiocms_api/dashboard/create-user-invite.ts +0 -231
- package/frontend/pages/studiocms_api/dashboard/create-user.ts +0 -186
- package/frontend/pages/studiocms_api/dashboard/email-notification-settings-site.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/mailer/check-email.ts +0 -75
- package/frontend/pages/studiocms_api/dashboard/mailer/config.ts +0 -136
- package/frontend/pages/studiocms_api/dashboard/plugins/[plugin].ts +0 -80
- package/frontend/pages/studiocms_api/dashboard/profile.ts +0 -245
- package/frontend/pages/studiocms_api/dashboard/resend-verify-email.ts +0 -77
- package/frontend/pages/studiocms_api/dashboard/reset-password.ts +0 -124
- package/frontend/pages/studiocms_api/dashboard/search-list.ts +0 -59
- package/frontend/pages/studiocms_api/dashboard/taxonomy-search.ts +0 -47
- package/frontend/pages/studiocms_api/dashboard/taxonomy.ts +0 -230
- package/frontend/pages/studiocms_api/dashboard/templates.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/update-user-notifications.ts +0 -86
- package/frontend/pages/studiocms_api/dashboard/users.ts +0 -236
- package/frontend/pages/studiocms_api/dashboard/verify-email.ts +0 -83
- package/frontend/pages/studiocms_api/dashboard/verify-session.ts +0 -187
- package/frontend/pages/studiocms_api/integrations/[type]/[...id].ts +0 -15
- package/frontend/pages/studiocms_api/integrations/[type]/_routes/db-studio.ts +0 -173
- package/frontend/pages/studiocms_api/integrations/[type]/_routes/storage.ts +0 -88
- package/frontend/pages/studiocms_api/partials/editor.astro +0 -74
- package/frontend/pages/studiocms_api/partials/render.astro +0 -39
- package/frontend/pages/studiocms_api/partials/user-list-items.astro +0 -43
- package/frontend/pages/studiocms_api/rest/utils/auth-token.ts +0 -59
- package/frontend/pages/studiocms_api/rest/v1/[type]/[...id].ts +0 -23
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/categories.ts +0 -267
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/folders.ts +0 -283
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/pages.ts +0 -505
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/settings.ts +0 -100
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/tags.ts +0 -229
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/users.ts +0 -553
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/[...id].ts +0 -19
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/categories.ts +0 -74
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/folders.ts +0 -85
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/pages.ts +0 -103
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/tags.ts +0 -67
- package/frontend/pages/studiocms_api/sdk/[...path].ts +0 -97
- package/frontend/pages/studiocms_api/sdk/utils/changelog.ts +0 -119
- package/frontend/scripts/auth/formListener.ts +0 -81
- package/frontend/scripts/formdata-utils.ts +0 -116
- package/frontend/utils/build-partial-schema.ts +0 -46
- package/frontend/utils/errors.ts +0 -6
- package/frontend/utils/param-extractor.ts +0 -83
- package/frontend/utils/rest-router.ts +0 -444
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { SDKCore } from 'studiocms:sdk';
|
|
2
|
+
import { HttpApiBuilder } from '@effect/platform';
|
|
3
|
+
import { StudioCMSSDKApiSpec } from '@withstudiocms/api-spec';
|
|
4
|
+
import { SDKAPIError } from '@withstudiocms/api-spec/sdk';
|
|
5
|
+
import { experimental_AstroContainer as AstroContainer } from 'astro/container';
|
|
6
|
+
import { Effect, Layer } from 'effect';
|
|
7
|
+
import { parseMarkdown } from '#utils/tinyMDParser';
|
|
8
|
+
// biome-ignore lint/suspicious/noTsIgnore: Typechecker override for Astro component imports
|
|
9
|
+
// @ts-ignore - This is an Astro component, so we ignore TypeScript errors for this import
|
|
10
|
+
import UserListItems from '../../../components/dashboard/user-mgmt/UserListItems.astro';
|
|
11
|
+
import { ProcessChangelog } from './_utils/changelog.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Utility function to catch errors in the Effect chain and convert them into SDKAPIError instances with a provided message.
|
|
15
|
+
*/
|
|
16
|
+
const catchError = (message: string) =>
|
|
17
|
+
Effect.catchAll((error: Error) => new SDKAPIError({ error: error.message || message }));
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Utility function to create a response object for the changelog endpoint.
|
|
21
|
+
*/
|
|
22
|
+
const makeChangelogResponse = (changelog: string) => ({ success: true, changelog });
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Utility function to create a response object for the latest version cache update endpoint.
|
|
26
|
+
*/
|
|
27
|
+
const makeVersionResponse = (latestVersion: { version: string; lastCacheUpdate: Date }) => ({
|
|
28
|
+
success: true,
|
|
29
|
+
latestVersion,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* SDK API Handler - Handles all API routes related to the StudioCMS SDK, including changelog generation and page listing.
|
|
34
|
+
*
|
|
35
|
+
* Endpoints:
|
|
36
|
+
* - POST /sdk/full-changelog.json: Generates and returns the full changelog in markdown format.
|
|
37
|
+
* - GET /sdk/list-pages: Retrieves a list of all SDK documentation pages with their last updated timestamp.
|
|
38
|
+
* - POST /sdk/update-latest-version-cache: Updates the cache for the latest SDK version and returns the new version information.
|
|
39
|
+
*
|
|
40
|
+
* Each endpoint is implemented as an Effect that interacts with the SDKCore and other utilities to perform the necessary operations.
|
|
41
|
+
*/
|
|
42
|
+
export const SDKAPIHandler = HttpApiBuilder.group(StudioCMSSDKApiSpec, 'sdk', (handlers) =>
|
|
43
|
+
handlers
|
|
44
|
+
.handle('fullChangelog', () =>
|
|
45
|
+
ProcessChangelog.pipe(
|
|
46
|
+
Effect.flatMap(({ runPipeline }) => runPipeline()),
|
|
47
|
+
Effect.map(makeChangelogResponse),
|
|
48
|
+
ProcessChangelog.Provide,
|
|
49
|
+
catchError('Failed to generate changelog')
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
.handle('updateLatestVersionCache', () =>
|
|
53
|
+
SDKCore.pipe(
|
|
54
|
+
Effect.flatMap((sdk) => sdk.UPDATE.latestVersion()),
|
|
55
|
+
Effect.map(makeVersionResponse),
|
|
56
|
+
catchError('Failed to update latest version cache')
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* SDK Utilities Handler - Handles utility API routes related to the StudioCMS SDK, such as rendering markdown content.
|
|
63
|
+
*/
|
|
64
|
+
export const SDKUtilsHandler = HttpApiBuilder.group(StudioCMSSDKApiSpec, 'utils', (handlers) =>
|
|
65
|
+
handlers
|
|
66
|
+
.handle(
|
|
67
|
+
'renderMarkdown',
|
|
68
|
+
Effect.fn(
|
|
69
|
+
({
|
|
70
|
+
urlParams: { content: queryParamContent, 'preload-content': preloadContent },
|
|
71
|
+
payload: { content: payloadContent },
|
|
72
|
+
}) =>
|
|
73
|
+
Effect.try({
|
|
74
|
+
try: () => {
|
|
75
|
+
let markdownContent: string | undefined;
|
|
76
|
+
|
|
77
|
+
if (payloadContent) {
|
|
78
|
+
markdownContent = payloadContent;
|
|
79
|
+
} else if (queryParamContent && queryParamContent !== 'null') {
|
|
80
|
+
markdownContent = queryParamContent;
|
|
81
|
+
} else if (preloadContent && preloadContent !== 'null') {
|
|
82
|
+
markdownContent = preloadContent;
|
|
83
|
+
} else {
|
|
84
|
+
markdownContent = 'No content provided';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const html = parseMarkdown(markdownContent);
|
|
88
|
+
|
|
89
|
+
return { html };
|
|
90
|
+
},
|
|
91
|
+
catch: () => new SDKAPIError({ error: 'Failed to render markdown' }),
|
|
92
|
+
})
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
.handle(
|
|
96
|
+
'userListItems',
|
|
97
|
+
Effect.fn(({ payload }) =>
|
|
98
|
+
Effect.tryPromise({
|
|
99
|
+
try: async () => {
|
|
100
|
+
const container = await AstroContainer.create();
|
|
101
|
+
|
|
102
|
+
let html = 'fail';
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
html = await container.renderToString(UserListItems, {
|
|
106
|
+
props: payload,
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error('Error rendering UserListItems:', error);
|
|
110
|
+
throw new SDKAPIError({ error: 'Failed to render user list items' });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
html,
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
catch: () => new SDKAPIError({ error: 'Failed to render user list items' }),
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Live SDK API Handler Layer - Provides the SDKAPIHandler with all necessary dependencies for live operation.
|
|
125
|
+
*/
|
|
126
|
+
export const SDKAPILive = HttpApiBuilder.api(StudioCMSSDKApiSpec).pipe(
|
|
127
|
+
Layer.provide(SDKAPIHandler),
|
|
128
|
+
Layer.provide(SDKUtilsHandler)
|
|
129
|
+
);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AstroLocalsMiddleware,
|
|
3
|
+
AstroLocalsMissing,
|
|
4
|
+
CurrentUser,
|
|
5
|
+
} from '@withstudiocms/api-spec/astro-context';
|
|
6
|
+
import { Effect, Layer } from 'effect';
|
|
7
|
+
import { AstroAPIContext } from 'effectify/astro/context';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Live implementation of the Astro locals authorization middleware.
|
|
11
|
+
*/
|
|
12
|
+
export const AstroLocalsAuthLive = Layer.effect(
|
|
13
|
+
AstroLocalsMiddleware,
|
|
14
|
+
Effect.gen(function* () {
|
|
15
|
+
return {
|
|
16
|
+
localUser: (_) =>
|
|
17
|
+
Effect.gen(function* () {
|
|
18
|
+
const { locals } = yield* AstroAPIContext;
|
|
19
|
+
const user = locals.StudioCMS?.security?.userSessionData;
|
|
20
|
+
const userPermissionLevel = locals.StudioCMS?.security?.userPermissionLevel || {
|
|
21
|
+
isVisitor: false,
|
|
22
|
+
isEditor: false,
|
|
23
|
+
isAdmin: false,
|
|
24
|
+
isOwner: false,
|
|
25
|
+
};
|
|
26
|
+
if (user) {
|
|
27
|
+
return CurrentUser.of({
|
|
28
|
+
...user,
|
|
29
|
+
userPermissionLevel,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return yield* new AstroLocalsMissing();
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
})
|
|
36
|
+
);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { SDKCore } from 'studiocms:sdk';
|
|
2
|
+
import {
|
|
3
|
+
RestAPIAuthorization,
|
|
4
|
+
RestAPIError,
|
|
5
|
+
type RestAPIUser,
|
|
6
|
+
Unauthorized,
|
|
7
|
+
} from '@withstudiocms/api-spec/rest-api';
|
|
8
|
+
import { Effect, Layer, Redacted } from 'effect';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Utility function to check if the provided user object is a valid RestAPIUser.
|
|
12
|
+
*
|
|
13
|
+
* This function takes a user object that may be `false` or a valid `RestAPIUser`.
|
|
14
|
+
* If the user is valid, it returns an Effect that succeeds with the user.
|
|
15
|
+
* If the user is `false`, it returns an Effect that fails with an `Unauthorized` error.
|
|
16
|
+
*
|
|
17
|
+
* @param user - The user object to validate, which can be `false` or a `RestAPIUser`.
|
|
18
|
+
* @returns An Effect that either succeeds with the valid RestAPIUser or fails with an Unauthorized error.
|
|
19
|
+
*/
|
|
20
|
+
const isUser = (
|
|
21
|
+
user: false | typeof RestAPIUser.Type
|
|
22
|
+
): Effect.Effect<RestAPIUser, Unauthorized, never> =>
|
|
23
|
+
user ? Effect.succeed(user) : Effect.fail(new Unauthorized());
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Live implementation of the RestAPIAuthorization middleware.
|
|
27
|
+
*/
|
|
28
|
+
export const RestAPIAuthorizationLive = Layer.effect(
|
|
29
|
+
RestAPIAuthorization,
|
|
30
|
+
Effect.gen(function* () {
|
|
31
|
+
return {
|
|
32
|
+
restApiToken: Effect.fn(
|
|
33
|
+
(token: Redacted.Redacted<string>) =>
|
|
34
|
+
SDKCore.pipe(
|
|
35
|
+
Effect.flatMap(({ REST_API }) => REST_API.tokens.verify(Redacted.value(token))),
|
|
36
|
+
Effect.flatMap(isUser)
|
|
37
|
+
),
|
|
38
|
+
Effect.catchTags({
|
|
39
|
+
DBClientInitializationError: () =>
|
|
40
|
+
new RestAPIError({
|
|
41
|
+
error: 'Database client initialization failed during token verification',
|
|
42
|
+
}),
|
|
43
|
+
DBCallbackFailure: () =>
|
|
44
|
+
new RestAPIError({ error: 'Database error during token verification' }),
|
|
45
|
+
SDKInitializationError: () =>
|
|
46
|
+
new RestAPIError({ error: 'SDK initialization error during token verification' }),
|
|
47
|
+
NotFoundError: () => new RestAPIError({ error: 'Token error during verification' }),
|
|
48
|
+
QueryError: () =>
|
|
49
|
+
new RestAPIError({ error: 'Database query error during token verification' }),
|
|
50
|
+
QueryParseError: () =>
|
|
51
|
+
new RestAPIError({ error: 'Database query parse error during token verification' }),
|
|
52
|
+
})
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
})
|
|
56
|
+
);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { APIRoute } from 'astro';
|
|
2
|
+
import { HttpApiToAstroRoute } from 'effectify/astro/HttpApi';
|
|
3
|
+
import { IntegrationsAPILive } from '../_handlers/integration/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Integrations API Route - Combines all Integrations API handlers into a single Astro route for serving the integrations-related API endpoints.
|
|
7
|
+
*/
|
|
8
|
+
export const ALL: APIRoute = HttpApiToAstroRoute(IntegrationsAPILive);
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { ParseResult } from 'effect';
|
|
2
|
+
import * as Schema from 'effect/Schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Convenience function to create a Schema from a property of a Schema. This is useful for creating Schemas for objects that are derived from FormData, where the keys are not known at compile time. It allows us to define the shape of the object we want to create from the FormData, while still being able to validate the individual properties using the original Schema.
|
|
6
|
+
*
|
|
7
|
+
* @param self - The original Schema that contains the property we want to extract.
|
|
8
|
+
* @param key - The key of the property we want to extract from the original Schema.
|
|
9
|
+
* @returns A new Schema that validates the value of the specified property from the original Schema.
|
|
10
|
+
*/
|
|
11
|
+
const FromKeyProperty = <Self extends Schema.Schema.All, Key extends PropertyKey>(
|
|
12
|
+
self: Self,
|
|
13
|
+
key: Key
|
|
14
|
+
) => Schema.propertySignature(self).pipe(Schema.fromKey(key));
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Similar to FromKeyProperty, but makes the property optional and allows for a default value. This is useful for handling optional fields in the FormData, where the absence of a key should not cause validation to fail, and we want to provide a default value instead.
|
|
18
|
+
*
|
|
19
|
+
* @param self - The original Schema that contains the property we want to extract.
|
|
20
|
+
* @param key - The key of the property we want to extract from the original Schema.
|
|
21
|
+
* @returns A new Schema that validates the value of the specified property from the original Schema, but allows it to be optional and provides a default value if it is not present.
|
|
22
|
+
*/
|
|
23
|
+
const OptionalFromKeyProperty = <Self extends Schema.Schema.All, Key extends PropertyKey>(
|
|
24
|
+
self: Self,
|
|
25
|
+
key: Key
|
|
26
|
+
) => Schema.optional(self).pipe(Schema.fromKey(key));
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Schema for validating that an input is an instance of FormData. This is used as a base for creating more complex Schemas that transform FormData into other shapes, such as objects with specific properties. It ensures that the input we are working with is indeed a FormData instance before we attempt to extract data from it.
|
|
30
|
+
*
|
|
31
|
+
* @remarks
|
|
32
|
+
* This Schema is used in conjunction with the ObjectFromFormData Schema, which transforms a FormData instance into a Record<string, string> object. By validating that the input is a FormData instance first, we can safely perform the transformation and handle any errors that may arise from invalid input.
|
|
33
|
+
*/
|
|
34
|
+
export const FormDataSchema = Schema.declare(
|
|
35
|
+
(input: unknown): input is FormData => input instanceof FormData,
|
|
36
|
+
{
|
|
37
|
+
title: 'FormData',
|
|
38
|
+
description: 'Schema for validating FormData instances',
|
|
39
|
+
identifier: 'FormData',
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Schema for transforming a FormData instance into a Record<string, string> object. This is useful for handling form submissions, where we want to convert the FormData into a more usable format for processing. It validates that the input is a FormData instance, and then iterates over its entries to create a plain object with string keys and values.
|
|
45
|
+
*
|
|
46
|
+
* @remarks
|
|
47
|
+
* This Schema is used in the CreatePage and EditPage components to handle form submissions. By transforming the FormData into a Record<string, string>, we can easily access the form values using standard object property access, and we can also perform additional validation on the individual properties using other Schemas.
|
|
48
|
+
*/
|
|
49
|
+
export const ObjectFromFormData = Schema.transformOrFail(
|
|
50
|
+
FormDataSchema,
|
|
51
|
+
Schema.mutable(
|
|
52
|
+
Schema.Record({
|
|
53
|
+
key: Schema.String,
|
|
54
|
+
value: Schema.String,
|
|
55
|
+
})
|
|
56
|
+
),
|
|
57
|
+
{
|
|
58
|
+
strict: true,
|
|
59
|
+
decode: (input, _options, ast) => {
|
|
60
|
+
if (!(input instanceof FormData)) {
|
|
61
|
+
return ParseResult.fail(
|
|
62
|
+
new ParseResult.Type(ast, input, 'Input is not an instance of FormData')
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const record: Record<string, string> = {};
|
|
66
|
+
for (const [key, value] of input.entries()) {
|
|
67
|
+
if (typeof key !== 'string' || typeof value !== 'string') {
|
|
68
|
+
return ParseResult.fail(
|
|
69
|
+
new ParseResult.Type(ast, input, 'FormData keys and values must be strings')
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
record[key] = value;
|
|
73
|
+
}
|
|
74
|
+
return ParseResult.succeed(record);
|
|
75
|
+
},
|
|
76
|
+
encode: (input) => {
|
|
77
|
+
const formData = new FormData();
|
|
78
|
+
for (const key in input) {
|
|
79
|
+
formData.append(key, input[key]);
|
|
80
|
+
}
|
|
81
|
+
return ParseResult.succeed(formData);
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Schema for validating that a string is a valid slug. A slug is a URL-friendly string that typically consists of lowercase letters, numbers, hyphens, and slashes. This Schema ensures that the input string adheres to these rules, which is important for generating clean URLs for pages in the CMS. It checks that the string is lowercase, does not contain spaces or special characters (other than hyphens and slashes), and does not have leading or trailing hyphens or slashes.
|
|
88
|
+
*
|
|
89
|
+
* @remarks
|
|
90
|
+
* This Schema is used for validating the slug field when creating or editing pages. By enforcing a specific format for slugs, we can ensure that the generated URLs are consistent and SEO-friendly. If the input does not match the expected slug format, the Schema will fail with a descriptive error message.
|
|
91
|
+
*/
|
|
92
|
+
export const SlugSchema = Schema.transformOrFail(Schema.String, Schema.String, {
|
|
93
|
+
strict: true,
|
|
94
|
+
decode: (input, _options, ast) => {
|
|
95
|
+
if (typeof input !== 'string') {
|
|
96
|
+
return ParseResult.fail(new ParseResult.Type(ast, input, 'Input is not a string'));
|
|
97
|
+
}
|
|
98
|
+
const slugRegex = /^[a-z0-9]+(?:[-/][a-z0-9]+)*$/;
|
|
99
|
+
if (!slugRegex.test(input)) {
|
|
100
|
+
return ParseResult.fail(
|
|
101
|
+
new ParseResult.Type(
|
|
102
|
+
ast,
|
|
103
|
+
input,
|
|
104
|
+
'Slug must be lowercase and can only contain letters, numbers, hyphens, and slashes (no leading/trailing hyphens or slashes)'
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return ParseResult.succeed(input);
|
|
109
|
+
},
|
|
110
|
+
encode: (input) => ParseResult.succeed(input),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Schema for validating the parent folder field, which can be either a string or null. This is used for handling the parent folder selection when creating or editing pages. The field can be a string representing the ID of the parent folder, or it can be null if the page does not have a parent folder. This Schema ensures that the input is either a valid string or null, and it also handles the case where the string "null" is passed, treating it as null.
|
|
115
|
+
*/
|
|
116
|
+
export const ParentFolderSchema = Schema.transformOrFail(
|
|
117
|
+
Schema.Union(Schema.String, Schema.Null),
|
|
118
|
+
Schema.Union(Schema.String, Schema.Null),
|
|
119
|
+
{
|
|
120
|
+
strict: true,
|
|
121
|
+
decode: (input, _options, ast) => {
|
|
122
|
+
if (typeof input === 'string') {
|
|
123
|
+
if (input === 'null') {
|
|
124
|
+
return ParseResult.succeed(null);
|
|
125
|
+
}
|
|
126
|
+
return ParseResult.succeed(input);
|
|
127
|
+
}
|
|
128
|
+
if (input === null) {
|
|
129
|
+
return ParseResult.succeed(null);
|
|
130
|
+
}
|
|
131
|
+
return ParseResult.fail(new ParseResult.Type(ast, input, 'Input must be a string or null'));
|
|
132
|
+
},
|
|
133
|
+
encode: (input) => ParseResult.succeed(input),
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Schema for validating that an input is either a string or an array of strings, and transforming it into an array of strings. This is useful for handling form fields that can accept either a single value or multiple values, such as categories or tags. The Schema checks if the input is a string, and if so, it wraps it in an array. If the input is already an array of strings, it validates that all elements are strings and returns it as is. If the input does not match either of these formats, the Schema fails with an error message.
|
|
139
|
+
*
|
|
140
|
+
* @remarks
|
|
141
|
+
* This Schema is used for the categories and tags fields in the CreatePage and EditPage components. By allowing both a single string and an array of strings, we can provide flexibility in how users input data, while still ensuring that the final output is always an array of strings for consistent processing.
|
|
142
|
+
*/
|
|
143
|
+
export const StringOrStringArrayToStringArraySchema = Schema.transformOrFail(
|
|
144
|
+
Schema.Union(Schema.String, Schema.Array(Schema.String)),
|
|
145
|
+
Schema.Array(Schema.String),
|
|
146
|
+
{
|
|
147
|
+
strict: true,
|
|
148
|
+
decode: (input, _options, ast) => {
|
|
149
|
+
if (typeof input === 'string') {
|
|
150
|
+
const isStringifiedArray = /^\s*\[\s*("[^"]*"\s*,\s*)*("[^"]*"\s*)?\]\s*$/.test(input);
|
|
151
|
+
if (isStringifiedArray) {
|
|
152
|
+
try {
|
|
153
|
+
const parsed = JSON.parse(input);
|
|
154
|
+
if (Array.isArray(parsed) && parsed.every((item) => typeof item === 'string')) {
|
|
155
|
+
return ParseResult.succeed(parsed);
|
|
156
|
+
}
|
|
157
|
+
} catch {}
|
|
158
|
+
}
|
|
159
|
+
if (Array.isArray(input)) {
|
|
160
|
+
return ParseResult.succeed(input);
|
|
161
|
+
}
|
|
162
|
+
return ParseResult.succeed([input]);
|
|
163
|
+
}
|
|
164
|
+
if (Array.isArray(input) && input.every((item) => typeof item === 'string')) {
|
|
165
|
+
return ParseResult.succeed(input);
|
|
166
|
+
}
|
|
167
|
+
return ParseResult.fail(
|
|
168
|
+
new ParseResult.Type(ast, input, 'Input must be a string or an array of strings')
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
encode: (input) => ParseResult.succeed(input),
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Schema for validating and transforming the data from the CreatePage form. This Schema defines the expected structure of the data that is submitted when creating a new page, including fields such as title, slug, description, package, showOnNav, heroImage, parentFolder, draft status, showAuthor, showContributors, categories, tags, and augments. It uses the previously defined Schemas for specific fields like SlugSchema and ParentFolderSchema to ensure that the data adheres to the expected formats.
|
|
177
|
+
*/
|
|
178
|
+
export const CreatePageDataFromFormDataObjectSchema = Schema.Struct({
|
|
179
|
+
title: FromKeyProperty(Schema.String, 'page-title'),
|
|
180
|
+
slug: FromKeyProperty(SlugSchema, 'page-slug'),
|
|
181
|
+
description: OptionalFromKeyProperty(Schema.String, 'page-description'),
|
|
182
|
+
package: FromKeyProperty(Schema.String, 'page-type'),
|
|
183
|
+
showOnNav: OptionalFromKeyProperty(Schema.BooleanFromString, 'show-in-nav'),
|
|
184
|
+
heroImage: OptionalFromKeyProperty(Schema.String, 'page-hero-image'),
|
|
185
|
+
parentFolder: Schema.optionalWith(ParentFolderSchema, {
|
|
186
|
+
default: () => null,
|
|
187
|
+
}).pipe(Schema.fromKey('parent-folder')),
|
|
188
|
+
draft: Schema.optional(Schema.BooleanFromString),
|
|
189
|
+
showAuthor: OptionalFromKeyProperty(Schema.BooleanFromString, 'show-author'),
|
|
190
|
+
showContributors: OptionalFromKeyProperty(Schema.BooleanFromString, 'show-contributors'),
|
|
191
|
+
categories: Schema.optionalWith(StringOrStringArrayToStringArraySchema, {
|
|
192
|
+
default: () => [],
|
|
193
|
+
}),
|
|
194
|
+
tags: Schema.optionalWith(StringOrStringArrayToStringArraySchema, {
|
|
195
|
+
default: () => [],
|
|
196
|
+
}),
|
|
197
|
+
augments: Schema.optional(Schema.Array(Schema.String)),
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Schema for validating and transforming the data from the EditPage form. This Schema extends the CreatePageDataFromFormDataObjectSchema by adding additional fields that are relevant for editing an existing page, such as the page ID, content, content ID, and plugin fields. It ensures that all the necessary data for editing a page is present and correctly formatted, while still allowing for optional fields and providing default values where appropriate.
|
|
202
|
+
*/
|
|
203
|
+
export const EditPageDataFromFormDataObjectSchema = Schema.mutable(
|
|
204
|
+
Schema.Struct({
|
|
205
|
+
...CreatePageDataFromFormDataObjectSchema.fields,
|
|
206
|
+
id: FromKeyProperty(Schema.String, 'page-id'),
|
|
207
|
+
content: FromKeyProperty(Schema.String, 'page-content'),
|
|
208
|
+
contentId: FromKeyProperty(Schema.String, 'page-content-id'),
|
|
209
|
+
pluginFields: Schema.optionalWith(
|
|
210
|
+
Schema.Record({
|
|
211
|
+
key: Schema.String,
|
|
212
|
+
value: Schema.NullOr(Schema.String),
|
|
213
|
+
}),
|
|
214
|
+
{
|
|
215
|
+
default: () => ({}),
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
})
|
|
219
|
+
);
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { Accordion, AccordionItem } from 'studiocms:ui/components/accordion';
|
|
3
2
|
import { Card } from 'studiocms:ui/components/card';
|
|
4
3
|
import PageHeader from '../components/first-time-setup/PageHeader.astro';
|
|
5
|
-
import
|
|
6
|
-
import codeSnippet2 from '../components/first-time-setup/snippets/opt2-astro.config.diff?raw';
|
|
7
|
-
import codeSnippet3 from '../components/first-time-setup/snippets/opt2-studiocms.config.diff?raw';
|
|
4
|
+
import codeSnippet_studiocms from '../components/first-time-setup/snippets/studiocms.config.diff?raw';
|
|
8
5
|
import Code from '../components/shared/Code.astro';
|
|
9
6
|
import Layout from '../layouts/FirstTimeSetupLayout.astro';
|
|
10
7
|
import { sharedProps } from './shared.js';
|
|
@@ -20,25 +17,12 @@ import { sharedProps } from './shared.js';
|
|
|
20
17
|
</div>
|
|
21
18
|
|
|
22
19
|
<div>
|
|
23
|
-
You're almost done! You can now start using StudioCMS after changing the following config option. If you have any questions, please reach out to us on our <a href="https://chat.studiocms.dev" target="_blank">Discord</a> server.
|
|
20
|
+
You're almost done! You can now start using StudioCMS after changing the following config option in your <code>studiocms.config.mjs</code> file. If you have any questions, please reach out to us on our <a href="https://chat.studiocms.dev" target="_blank">Discord</a> server.
|
|
24
21
|
</div>
|
|
25
22
|
<br />
|
|
26
23
|
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
<div slot="summary">Using StudioCMS with just the <code>astro.config.mjs</code></div>
|
|
30
|
-
<Code code={codeSnippet1} ins='11' />
|
|
31
|
-
</AccordionItem>
|
|
32
|
-
<AccordionItem>
|
|
33
|
-
<div slot="summary">Using StudioCMS with the <code>studiocms.config.mjs</code></div>
|
|
34
|
-
|
|
35
|
-
<span>astro.config.mjs</span>
|
|
36
|
-
<Code code={codeSnippet2} />
|
|
37
|
-
|
|
38
|
-
<span>studiocms.config.mjs</span>
|
|
39
|
-
<Code ins="4" code={codeSnippet3} />
|
|
40
|
-
</AccordionItem>
|
|
41
|
-
</Accordion>
|
|
24
|
+
<span>studiocms.config.mjs</span>
|
|
25
|
+
<Code ins="5" code={codeSnippet_studiocms} />
|
|
42
26
|
|
|
43
27
|
</Card>
|
|
44
28
|
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
OptionsResponse,
|
|
10
10
|
readAPIContextJson,
|
|
11
11
|
} from '@withstudiocms/effect';
|
|
12
|
-
import {
|
|
12
|
+
import { isValidEmail } from '#schemas/external-schemas';
|
|
13
13
|
|
|
14
14
|
export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
15
15
|
{
|
|
@@ -85,15 +85,12 @@ export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// If the email is invalid, return an error
|
|
88
|
-
const checkEmail =
|
|
89
|
-
.string()
|
|
90
|
-
.email({ message: 'Email address is invalid' })
|
|
91
|
-
.safeParse(email);
|
|
88
|
+
const checkEmail = isValidEmail(email);
|
|
92
89
|
|
|
93
90
|
if (!checkEmail.success) {
|
|
94
91
|
return createJsonResponse(
|
|
95
92
|
{
|
|
96
|
-
error: checkEmail.error.
|
|
93
|
+
error: checkEmail.error.message,
|
|
97
94
|
},
|
|
98
95
|
{
|
|
99
96
|
status: 400,
|
|
@@ -11,7 +11,8 @@ export const prerender = false;
|
|
|
11
11
|
export const ALL: APIRoute = async ({ request }) => {
|
|
12
12
|
try {
|
|
13
13
|
const rawBody = await request.json();
|
|
14
|
-
const
|
|
14
|
+
const parser = Schema.decodeUnknownSync(Schema.Array(ServerMetricSchema));
|
|
15
|
+
const body = parser(rawBody);
|
|
15
16
|
const db = await runEffect(getAnalyticsDbClient(config.db.dialect));
|
|
16
17
|
|
|
17
18
|
const insert = db.withEncoder({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "studiocms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A Community-Driven Astro native CMS. Built from the ground up by the Astro community.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "withstudiocms",
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"studiocms": "./studiocms-cli.mjs"
|
|
57
57
|
},
|
|
58
58
|
"imports": {
|
|
59
|
+
"#client/*": {
|
|
60
|
+
"types": "./dist/client/*.d.ts",
|
|
61
|
+
"default": "./dist/client/*.js"
|
|
62
|
+
},
|
|
59
63
|
"#consts": {
|
|
60
64
|
"types": "./dist/consts.d.ts",
|
|
61
65
|
"default": "./dist/consts.js"
|
|
@@ -127,6 +131,10 @@
|
|
|
127
131
|
"types": "./dist/index.d.ts",
|
|
128
132
|
"default": "./dist/index.js"
|
|
129
133
|
},
|
|
134
|
+
"./client/*": {
|
|
135
|
+
"types": "./dist/client/*.d.ts",
|
|
136
|
+
"default": "./dist/client/*.js"
|
|
137
|
+
},
|
|
130
138
|
"./config": {
|
|
131
139
|
"types": "./dist/config.d.ts",
|
|
132
140
|
"default": "./dist/config.js"
|
|
@@ -163,10 +171,6 @@
|
|
|
163
171
|
"types": "./dist/schemas/index.d.ts",
|
|
164
172
|
"default": "./dist/schemas/index.js"
|
|
165
173
|
},
|
|
166
|
-
"./schemas/renderer": {
|
|
167
|
-
"types": "./dist/schemas/config/rendererConfig.d.ts",
|
|
168
|
-
"default": "./dist/schemas/config/rendererConfig.js"
|
|
169
|
-
},
|
|
170
174
|
"./runtime": {
|
|
171
175
|
"types": "./dist/runtime/index.d.ts",
|
|
172
176
|
"default": "./dist/runtime/index.js"
|
|
@@ -222,61 +226,61 @@
|
|
|
222
226
|
"type": "module",
|
|
223
227
|
"dependencies": {
|
|
224
228
|
"@iconify-json/flat-color-icons": "^1.2.3",
|
|
225
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
229
|
+
"@iconify-json/simple-icons": "^1.2.72",
|
|
226
230
|
"@iconify-json/circle-flags": "^1.2.10",
|
|
227
|
-
"@inox-tools/runtime-logger": "^0.
|
|
231
|
+
"@inox-tools/runtime-logger": "^0.8.1",
|
|
228
232
|
"@nanostores/i18n": "^1.2.2",
|
|
229
|
-
"@nanostores/persistent": "^1.
|
|
233
|
+
"@nanostores/persistent": "^1.3.3",
|
|
230
234
|
"@outerbase/sdk-transform": "^1.0.8",
|
|
231
|
-
"@studiocms/ui": "^1.
|
|
232
|
-
"ace-builds": "^1.43.
|
|
235
|
+
"@studiocms/ui": "^1.1.2",
|
|
236
|
+
"ace-builds": "^1.43.6",
|
|
233
237
|
"astro-integration-kit": "^0.19.1",
|
|
234
238
|
"boxen": "^8.0.1",
|
|
235
|
-
"chalk": "^5.6.2",
|
|
236
239
|
"diff": "^8.0.3",
|
|
237
|
-
"dompurify": "^3.3.
|
|
238
|
-
"dotenv": "^17.
|
|
240
|
+
"dompurify": "^3.3.2",
|
|
241
|
+
"dotenv": "^17.3.1",
|
|
239
242
|
"fuse.js": "^7.1.0",
|
|
240
|
-
"jose": "^6.
|
|
243
|
+
"jose": "^6.2.0",
|
|
241
244
|
"micromark": "^4.0.2",
|
|
242
245
|
"micromark-extension-gfm": "^3.0.0",
|
|
243
|
-
"
|
|
244
|
-
"magicast": "^0.5.1",
|
|
246
|
+
"magicast": "^0.5.2",
|
|
245
247
|
"mdast-util-to-markdown": "^2.1.2",
|
|
246
248
|
"mrmime": "^2.0.1",
|
|
247
|
-
"nanostores": "^1.1.
|
|
249
|
+
"nanostores": "^1.1.1",
|
|
248
250
|
"package-manager-detector": "^1.6.0",
|
|
249
|
-
"semver": "^7.7.
|
|
251
|
+
"semver": "^7.7.4",
|
|
250
252
|
"three": "0.170.0",
|
|
251
253
|
"tinyglobby": "^0.2.15",
|
|
252
254
|
"ultrahtml": "^1.6.0",
|
|
253
255
|
"web-vitals": "^5.1.0",
|
|
254
|
-
"@withstudiocms/
|
|
255
|
-
"@withstudiocms/
|
|
256
|
-
"@withstudiocms/
|
|
257
|
-
"@withstudiocms/
|
|
258
|
-
"@withstudiocms/
|
|
259
|
-
"@withstudiocms/
|
|
260
|
-
"@withstudiocms/
|
|
256
|
+
"@withstudiocms/api-spec": "^0.3.0",
|
|
257
|
+
"@withstudiocms/internal_helpers": "^0.2.0",
|
|
258
|
+
"@withstudiocms/auth-kit": "^0.1.4",
|
|
259
|
+
"@withstudiocms/cli-kit": "^0.2.1",
|
|
260
|
+
"@withstudiocms/component-registry": "^0.1.4",
|
|
261
|
+
"@withstudiocms/config-utils": "^0.2.0",
|
|
262
|
+
"@withstudiocms/effect": "^0.4.0",
|
|
261
263
|
"@withstudiocms/template-lang": "^0.1.0",
|
|
262
|
-
"@withstudiocms/
|
|
264
|
+
"@withstudiocms/kysely": "^0.2.1",
|
|
265
|
+
"@withstudiocms/sdk": "^0.3.0",
|
|
266
|
+
"effectify": "^0.1.0"
|
|
263
267
|
},
|
|
264
268
|
"devDependencies": {
|
|
265
269
|
"@types/mdast": "^4.0.4",
|
|
266
|
-
"@types/micromatch": "^4.0.10",
|
|
267
270
|
"@types/node": "^22.0.0",
|
|
268
271
|
"@types/semver": "^7.7.1",
|
|
269
272
|
"@types/three": "0.169.0",
|
|
270
|
-
"@types/pg": "^8.
|
|
273
|
+
"@types/pg": "^8.18.0",
|
|
271
274
|
"typescript": "^5.9.3",
|
|
272
275
|
"vite": "^6.3.4"
|
|
273
276
|
},
|
|
274
277
|
"peerDependencies": {
|
|
278
|
+
"@effect/platform": "^0.94.5",
|
|
275
279
|
"@libsql/client": "^0.15.15",
|
|
276
280
|
"astro": "^5.12.9",
|
|
277
|
-
"effect": "^3.19.
|
|
278
|
-
"pg": "^8.
|
|
279
|
-
"mysql2": "^3.
|
|
281
|
+
"effect": "^3.19.19",
|
|
282
|
+
"pg": "^8.20.0",
|
|
283
|
+
"mysql2": "^3.18.0"
|
|
280
284
|
},
|
|
281
285
|
"peerDependenciesMeta": {
|
|
282
286
|
"@libsql/client": {
|