create-nextblock 0.14.1 → 0.14.4
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/docker-template/.dockerignore +23 -23
- package/docker-template/.env.docker.example +69 -69
- package/docker-template/docker/db/init/99-jwt.sql +6 -6
- package/docker-template/docker/db/init/99-roles.sql +25 -25
- package/docker-template/docker/kong/kong.yml +112 -112
- package/docker-template/scripts/docker-setup.mjs +310 -310
- package/libs/db/tsconfig.lib.json +3 -3
- package/libs/editor/tsconfig.lib.json +3 -3
- package/libs/ui/tsconfig.lib.json +3 -3
- package/libs/utils/tsconfig.json +3 -3
- package/package.json +1 -1
- package/project.json +19 -19
- package/templates/nextblock-template/.browserslistrc +11 -11
- package/templates/nextblock-template/.dockerignore +23 -23
- package/templates/nextblock-template/README.md +34 -34
- package/templates/nextblock-template/app/(auth-pages)/layout.tsx +9 -9
- package/templates/nextblock-template/app/(auth-pages)/post-sign-in/page.tsx +27 -27
- package/templates/nextblock-template/app/(auth-pages)/sign-up/page.tsx +46 -46
- package/templates/nextblock-template/app/(auth-pages)/two-factor/page.tsx +51 -51
- package/templates/nextblock-template/app/ToasterProvider.tsx +17 -17
- package/templates/nextblock-template/app/[slug]/pageClientActions.ts +7 -7
- package/templates/nextblock-template/app/actions/consent.ts +57 -57
- package/templates/nextblock-template/app/actions/postActions.ts +146 -146
- package/templates/nextblock-template/app/actions/twoFactorEmail.ts +22 -22
- package/templates/nextblock-template/app/api/ai/cortex/build-widget/route.ts +153 -153
- package/templates/nextblock-template/app/api/ai/generate-blocks/route.ts +96 -96
- package/templates/nextblock-template/app/api/brand/email-logo/route.ts +48 -48
- package/templates/nextblock-template/app/api/cms/check-updates/route.ts +44 -44
- package/templates/nextblock-template/app/api/cms/full-backup/export/route.ts +33 -33
- package/templates/nextblock-template/app/api/cms/full-backup/restore/route.ts +63 -63
- package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +3490 -3490
- package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +5881 -5623
- package/templates/nextblock-template/app/api/cron/sync-currencies/route.ts +39 -39
- package/templates/nextblock-template/app/api/custom-blocks/db-relations/route.ts +92 -92
- package/templates/nextblock-template/app/api/custom-blocks/editor-definitions/route.ts +43 -43
- package/templates/nextblock-template/app/api/media/library/route.ts +69 -69
- package/templates/nextblock-template/app/api/media/r2-presigned/route.ts +53 -53
- package/templates/nextblock-template/app/api/media/record/route.ts +160 -160
- package/templates/nextblock-template/app/api/search/route.ts +43 -43
- package/templates/nextblock-template/app/article/[slug]/PostClientContent.tsx +441 -441
- package/templates/nextblock-template/app/auth/callback/route.ts +31 -31
- package/templates/nextblock-template/app/cart/page.tsx +7 -7
- package/templates/nextblock-template/app/cms/CmsClientLayout.tsx +2 -2
- package/templates/nextblock-template/app/cms/blocks/components/ColumnEditor.tsx +17 -22
- package/templates/nextblock-template/app/cms/blocks/components/CustomBlockEditorPreview.tsx +160 -160
- package/templates/nextblock-template/app/cms/blocks/components/EditableBlock.tsx +13 -19
- package/templates/nextblock-template/app/cms/blocks/components/MediaLibraryModal.tsx +149 -149
- package/templates/nextblock-template/app/cms/blocks/editors/DynamicCustomBlockEditor.tsx +167 -167
- package/templates/nextblock-template/app/cms/blocks/editors/HeadingBlockEditor.tsx +45 -34
- package/templates/nextblock-template/app/cms/blocks/editors/ImageBlockEditor.tsx +4 -2
- package/templates/nextblock-template/app/cms/blocks/editors/TextBlockEditor.tsx +90 -90
- package/templates/nextblock-template/app/cms/components/ConnectGitHubButton.tsx +122 -122
- package/templates/nextblock-template/app/cms/components/CortexAiPageContext.tsx +58 -58
- package/templates/nextblock-template/app/cms/components/FeedbackModal.tsx +36 -36
- package/templates/nextblock-template/app/cms/components/SystemAlertsBanner.tsx +112 -112
- package/templates/nextblock-template/app/cms/components/TwoFactorReminderBanner.tsx +45 -45
- package/templates/nextblock-template/app/cms/components/github-connect-actions.ts +102 -102
- package/templates/nextblock-template/app/cms/components/system-alerts-actions.ts +31 -31
- package/templates/nextblock-template/app/cms/custom-blocks/[id]/edit/page.tsx +66 -66
- package/templates/nextblock-template/app/cms/custom-blocks/actions.ts +519 -519
- package/templates/nextblock-template/app/cms/custom-blocks/components/BlocksLibraryTransferControls.tsx +256 -256
- package/templates/nextblock-template/app/cms/custom-blocks/components/DBRelationSelect.tsx +384 -384
- package/templates/nextblock-template/app/cms/custom-blocks/components/ImageR2Picker.tsx +221 -221
- package/templates/nextblock-template/app/cms/custom-blocks/new/page.tsx +12 -12
- package/templates/nextblock-template/app/cms/custom-blocks/page.tsx +438 -438
- package/templates/nextblock-template/app/cms/dashboard/actions.ts +228 -228
- package/templates/nextblock-template/app/cms/dashboard/components/DashboardOnboarding.tsx +130 -130
- package/templates/nextblock-template/app/cms/import-export/actions.ts +226 -226
- package/templates/nextblock-template/app/cms/layout.tsx +73 -73
- package/templates/nextblock-template/app/cms/media/components/FolderNavigator.tsx +273 -273
- package/templates/nextblock-template/app/cms/media/components/FolderTree.tsx +122 -122
- package/templates/nextblock-template/app/cms/media/components/MediaEditForm.tsx +26 -26
- package/templates/nextblock-template/app/cms/media/components/MediaGridClient.tsx +69 -69
- package/templates/nextblock-template/app/cms/navigation/components/NavigationMenuDnd.tsx +3 -3
- package/templates/nextblock-template/app/cms/products/attributes/page.tsx +12 -12
- package/templates/nextblock-template/app/cms/products/categories/page.tsx +12 -12
- package/templates/nextblock-template/app/cms/products/inventory/page.tsx +13 -13
- package/templates/nextblock-template/app/cms/products/new/page.tsx +135 -135
- package/templates/nextblock-template/app/cms/products/productFormData.ts +133 -133
- package/templates/nextblock-template/app/cms/products/settings/page.tsx +5 -5
- package/templates/nextblock-template/app/cms/promotions/PromotionsWorkspace.tsx +456 -456
- package/templates/nextblock-template/app/cms/promotions/actions.ts +115 -115
- package/templates/nextblock-template/app/cms/promotions/page.tsx +31 -31
- package/templates/nextblock-template/app/cms/revisions/service.ts +19 -19
- package/templates/nextblock-template/app/cms/revisions/utils.ts +132 -132
- package/templates/nextblock-template/app/cms/settings/backup-restore/BackupRestoreWorkspace.tsx +1004 -1004
- package/templates/nextblock-template/app/cms/settings/backup-restore/page.tsx +29 -29
- package/templates/nextblock-template/app/cms/settings/bot-protection/page.tsx +24 -24
- package/templates/nextblock-template/app/cms/settings/cortex-ai/SandboxCortexAiSettingsClient.tsx +688 -688
- package/templates/nextblock-template/app/cms/settings/currencies/actions.ts +331 -331
- package/templates/nextblock-template/app/cms/settings/currencies/page.tsx +494 -494
- package/templates/nextblock-template/app/cms/settings/email/page.tsx +28 -28
- package/templates/nextblock-template/app/cms/settings/extra-translations/ExtraTranslationsWorkspace.tsx +767 -767
- package/templates/nextblock-template/app/cms/settings/extra-translations/page.tsx +93 -93
- package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeEditor.tsx +382 -0
- package/templates/nextblock-template/app/cms/settings/global-css/components/ThemeManager.tsx +267 -0
- package/templates/nextblock-template/app/cms/settings/global-css/page.tsx +40 -24
- package/templates/nextblock-template/app/cms/settings/global-css/theme-actions.ts +259 -0
- package/templates/nextblock-template/app/cms/settings/google-analytics/page.tsx +26 -26
- package/templates/nextblock-template/app/cms/settings/logos/[id]/edit/page.tsx +7 -7
- package/templates/nextblock-template/app/cms/settings/logos/components/BrandingSettingsForm.tsx +339 -339
- package/templates/nextblock-template/app/cms/settings/logos/components/DeleteLogoButton.tsx +21 -21
- package/templates/nextblock-template/app/cms/settings/logos/components/LogoForm.tsx +23 -21
- package/templates/nextblock-template/app/cms/settings/logos/components/SetActiveLogoButton.tsx +42 -42
- package/templates/nextblock-template/app/cms/settings/logos/components/SiteSeoSettingsForm.tsx +133 -133
- package/templates/nextblock-template/app/cms/settings/logos/new/page.tsx +8 -8
- package/templates/nextblock-template/app/cms/settings/packages/package-card.tsx +122 -122
- package/templates/nextblock-template/app/cms/settings/privacy/page.tsx +27 -27
- package/templates/nextblock-template/app/cms/settings/registration/page.tsx +27 -27
- package/templates/nextblock-template/app/cms/settings/security/components/SecurityPanel.tsx +9 -7
- package/templates/nextblock-template/app/cms/settings/security/page.tsx +33 -33
- package/templates/nextblock-template/app/cms/settings/taxes/page.tsx +21 -21
- package/templates/nextblock-template/app/cms/shipping/page.tsx +20 -20
- package/templates/nextblock-template/app/cms/users/components/DeleteUserButton.tsx +12 -12
- package/templates/nextblock-template/app/layout.tsx +49 -0
- package/templates/nextblock-template/app/lib/site-settings.ts +105 -105
- package/templates/nextblock-template/app/profile/ProfilePageHeader.tsx +16 -16
- package/templates/nextblock-template/app/profile/ProfilePageMissingState.tsx +9 -9
- package/templates/nextblock-template/app/profile/account-links.ts +22 -22
- package/templates/nextblock-template/app/profile/orders/CustomerOrdersPageClient.tsx +124 -124
- package/templates/nextblock-template/app/profile/orders/page.tsx +19 -19
- package/templates/nextblock-template/app/profile/password/PasswordSettingsPageClient.tsx +128 -128
- package/templates/nextblock-template/app/profile/password/actions.ts +59 -59
- package/templates/nextblock-template/app/profile/password/page.tsx +27 -27
- package/templates/nextblock-template/app/providers.tsx +16 -4
- package/templates/nextblock-template/app/setup/SetupWizard.tsx +678 -678
- package/templates/nextblock-template/app/setup/layout.tsx +13 -13
- package/templates/nextblock-template/app/setup/page.tsx +111 -111
- package/templates/nextblock-template/app/sitemap.ts +130 -130
- package/templates/nextblock-template/components/CartDrawerLoader.tsx +7 -7
- package/templates/nextblock-template/components/DeferredCartDrawer.tsx +23 -23
- package/templates/nextblock-template/components/DeferredGoogleAnalytics.tsx +70 -70
- package/templates/nextblock-template/components/DeferredGoogleTagManager.tsx +70 -70
- package/templates/nextblock-template/components/DeferredSpeedInsights.tsx +69 -69
- package/templates/nextblock-template/components/FeatureImageHero.tsx +47 -47
- package/templates/nextblock-template/components/FooterNavigation.tsx +32 -32
- package/templates/nextblock-template/components/HtmlScriptExecutor.tsx +47 -47
- package/templates/nextblock-template/components/LanguageSwitcher.tsx +2 -2
- package/templates/nextblock-template/components/PublicEnvBootstrap.tsx +30 -30
- package/templates/nextblock-template/components/ResponsiveNav.tsx +14 -14
- package/templates/nextblock-template/components/auth/AuthBotProtection.tsx +182 -182
- package/templates/nextblock-template/components/blocks/PostCardSkeleton.tsx +12 -12
- package/templates/nextblock-template/components/blocks/PostsGridBlock.tsx +12 -12
- package/templates/nextblock-template/components/blocks/ecommerceRendererLoaders.ts +23 -23
- package/templates/nextblock-template/components/blocks/renderers/FormBlockRenderer.tsx +249 -249
- package/templates/nextblock-template/components/blocks/renderers/HeadingBlockRenderer.tsx +7 -10
- package/templates/nextblock-template/components/blocks/types.ts +7 -7
- package/templates/nextblock-template/components/env-var-warning.tsx +3 -3
- package/templates/nextblock-template/components/form-message.tsx +32 -32
- package/templates/nextblock-template/components/media/YouTubeFacade.tsx +105 -105
- package/templates/nextblock-template/components/media/youtube-embed-replace.tsx +32 -32
- package/templates/nextblock-template/components/privacy/ConsentBanner.tsx +170 -170
- package/templates/nextblock-template/components/privacy/ConsentGatedAnalytics.tsx +70 -70
- package/templates/nextblock-template/components/renderers/CachedDynamicLayoutEngine.tsx +28 -28
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.test.tsx +166 -166
- package/templates/nextblock-template/components/renderers/DynamicLayoutEngine.tsx +471 -471
- package/templates/nextblock-template/components/submit-button.tsx +23 -23
- package/templates/nextblock-template/components/theme-icon.tsx +78 -0
- package/templates/nextblock-template/components/theme-switcher.tsx +77 -82
- package/templates/nextblock-template/components/visual-editing/DeferredVisualEditing.tsx +21 -21
- package/templates/nextblock-template/context/AuthContext.tsx +23 -23
- package/templates/nextblock-template/context/ThemeCatalogContext.tsx +44 -0
- package/templates/nextblock-template/context/language-rest-client.ts +32 -32
- package/templates/nextblock-template/docker/db/init/99-jwt.sql +6 -6
- package/templates/nextblock-template/docker/db/init/99-roles.sql +25 -25
- package/templates/nextblock-template/docker/kong/kong.yml +112 -112
- package/templates/nextblock-template/docs/01-PROJECT-OVERVIEW.md +94 -94
- package/templates/nextblock-template/docs/02-ECOMMERCE-CAPABILITIES.md +364 -364
- package/templates/nextblock-template/docs/03-CMS-AND-EDITOR.md +279 -202
- package/templates/nextblock-template/docs/04-DATABASE-AND-AUTH.md +246 -246
- package/templates/nextblock-template/docs/06-CLI-AND-SCAFFOLDING.md +176 -176
- package/templates/nextblock-template/docs/07-BLOCK-SDK-AND-EXTENSIBILITY.md +146 -146
- package/templates/nextblock-template/docs/10-CUSTOM-BLOCKS.md +222 -222
- package/templates/nextblock-template/docs/11-SELF-HOSTED-DOCKER.md +173 -173
- package/templates/nextblock-template/docs/12-VERCEL-DEPLOYMENT.md +170 -170
- package/templates/nextblock-template/docs/13-STAYING-UP-TO-DATE.md +151 -151
- package/templates/nextblock-template/docs/README.md +39 -39
- package/templates/nextblock-template/hooks/use-hotkeys.ts +21 -21
- package/templates/nextblock-template/hooks/useGlobalSearch.ts +101 -101
- package/templates/nextblock-template/index.d.ts +7 -7
- package/templates/nextblock-template/lib/app-secrets.ts +39 -39
- package/templates/nextblock-template/lib/auth/cookies.ts +47 -47
- package/templates/nextblock-template/lib/auth/crypto.ts +45 -45
- package/templates/nextblock-template/lib/auth/trustedDevices.ts +92 -92
- package/templates/nextblock-template/lib/auth-redirects.ts +46 -46
- package/templates/nextblock-template/lib/blocks/README.md +13 -13
- package/templates/nextblock-template/lib/blocks/blockColors.test.ts +114 -0
- package/templates/nextblock-template/lib/blocks/blockColors.ts +132 -0
- package/templates/nextblock-template/lib/blocks/blockRegistry.ts +17 -1
- package/templates/nextblock-template/lib/botProtection/verify.ts +134 -134
- package/templates/nextblock-template/lib/cms-transfer/server.ts +2243 -2243
- package/templates/nextblock-template/lib/cms-transfer/types.ts +145 -145
- package/templates/nextblock-template/lib/custom-block-definitions.ts +87 -87
- package/templates/nextblock-template/lib/custom-block-r2-upload-shared.ts +178 -178
- package/templates/nextblock-template/lib/custom-block-r2-upload.test.ts +140 -140
- package/templates/nextblock-template/lib/custom-block-r2-upload.ts +88 -88
- package/templates/nextblock-template/lib/custom-block-relations.test.ts +227 -227
- package/templates/nextblock-template/lib/custom-block-relations.ts +279 -279
- package/templates/nextblock-template/lib/custom-block-safelist.ts +14 -14
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.test.ts +172 -172
- package/templates/nextblock-template/lib/editor/dynamic-extension-core.ts +213 -213
- package/templates/nextblock-template/lib/editor/dynamic-extension-loader.ts +22 -22
- package/templates/nextblock-template/lib/editor/dynamic-extensions.tsx +193 -193
- package/templates/nextblock-template/lib/email/branding-format.test.ts +133 -133
- package/templates/nextblock-template/lib/email/branding-format.ts +123 -123
- package/templates/nextblock-template/lib/email/branding.ts +76 -76
- package/templates/nextblock-template/lib/full-backup/manifest.test.ts +121 -121
- package/templates/nextblock-template/lib/full-backup/manifest.ts +206 -206
- package/templates/nextblock-template/lib/full-backup/server.ts +743 -743
- package/templates/nextblock-template/lib/logos/active-logo.ts +53 -53
- package/templates/nextblock-template/lib/media/resolveMediaUrl.ts +54 -54
- package/templates/nextblock-template/lib/media/youtube.ts +99 -99
- package/templates/nextblock-template/lib/onboarding/actions.ts +31 -31
- package/templates/nextblock-template/lib/onboarding/status.ts +222 -222
- package/templates/nextblock-template/lib/posts/readTime.ts +60 -60
- package/templates/nextblock-template/lib/privacy/consent-client.ts +57 -57
- package/templates/nextblock-template/lib/privacy/contact-emails.ts +64 -64
- package/templates/nextblock-template/lib/privacy/settings.ts +115 -115
- package/templates/nextblock-template/lib/privacy/types.ts +69 -69
- package/templates/nextblock-template/lib/promotions/server.test.ts +74 -74
- package/templates/nextblock-template/lib/promotions/server.ts +741 -741
- package/templates/nextblock-template/lib/resolve-block-relations.test.ts +142 -142
- package/templates/nextblock-template/lib/resolve-block-relations.ts +255 -255
- package/templates/nextblock-template/lib/search/types.ts +27 -27
- package/templates/nextblock-template/lib/setup/actions.ts +460 -460
- package/templates/nextblock-template/lib/setup/env-status.ts +125 -125
- package/templates/nextblock-template/lib/setup/env-write.ts +111 -111
- package/templates/nextblock-template/lib/setup/migrations-bundle.ts +15 -10
- package/templates/nextblock-template/lib/setup/provisioning.ts +59 -59
- package/templates/nextblock-template/lib/setup/schema-apply.ts +408 -408
- package/templates/nextblock-template/lib/setup/system-config.ts +105 -105
- package/templates/nextblock-template/lib/setup/types.ts +18 -18
- package/templates/nextblock-template/lib/site-url.ts +48 -48
- package/templates/nextblock-template/lib/storage/provider.ts +66 -66
- package/templates/nextblock-template/lib/storage/supabase-storage.ts +103 -103
- package/templates/nextblock-template/lib/themes/buildThemeCss.test.ts +163 -0
- package/templates/nextblock-template/lib/themes/buildThemeCss.ts +124 -0
- package/templates/nextblock-template/lib/themes/tokenColor.ts +31 -0
- package/templates/nextblock-template/lib/themes/tokens.ts +143 -0
- package/templates/nextblock-template/lib/updates/check-upstream.ts +441 -441
- package/templates/nextblock-template/lib/updates/github-device.ts +206 -206
- package/templates/nextblock-template/lib/updates/repo-identity.ts +56 -56
- package/templates/nextblock-template/next-env.d.ts +2 -2
- package/templates/nextblock-template/package.json +1 -1
- package/templates/nextblock-template/postcss.config.js +6 -6
- package/templates/nextblock-template/scripts/backup.js +115 -115
- package/templates/nextblock-template/scripts/docker-setup.mjs +310 -310
- package/templates/nextblock-template/scripts/restore.js +385 -385
- package/templates/nextblock-template/scripts/verify-cortex-ai-build-widget.tsx +98 -98
- package/templates/nextblock-template/scripts/verify-cortex-ai-generate-blocks.ts +62 -62
- package/templates/nextblock-template/scripts/verify-cortex-ai-global-tools.ts +537 -537
- package/templates/nextblock-template/scripts/verify-cortex-ai-routing.ts +58 -58
- package/templates/nextblock-template/scripts/verify-custom-block-definitions.ts +188 -188
- package/templates/nextblock-template/scripts/verify-dynamic-custom-block-extensions.ts +123 -123
- package/templates/nextblock-template/scripts/verify-dynamic-layout-engine.tsx +133 -133
- package/templates/nextblock-template/scripts/verify-milestone-2-custom-blocks.ts +65 -65
- package/templates/nextblock-template/scripts/verify-site-themes.ts +63 -0
- package/templates/nextblock-template/tailwind.config.js +25 -25
- package/templates/nextblock-template/tools/build-migrate.mjs +209 -209
- package/templates/nextblock-template/tools/configure-supabase-auth.js +282 -282
- package/templates/nextblock-template/tsconfig.tsbuildinfo +1 -1
- package/templates/nextblock-template/types/jsdom.d.ts +6 -6
- package/tsconfig.base.json +3 -3
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { Button } from "@nextblock-cms/ui";
|
|
4
|
-
import { type ComponentProps } from "react";
|
|
5
|
-
import { useFormStatus } from "react-dom";
|
|
6
|
-
|
|
7
|
-
type Props = ComponentProps<typeof Button> & {
|
|
8
|
-
pendingText?: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export function SubmitButton({
|
|
12
|
-
children,
|
|
13
|
-
pendingText = "Submitting...",
|
|
14
|
-
...props
|
|
15
|
-
}: Props) {
|
|
16
|
-
const { pending } = useFormStatus();
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<Button type="submit" aria-disabled={pending} {...props}>
|
|
20
|
-
{pending ? pendingText : children}
|
|
21
|
-
</Button>
|
|
22
|
-
);
|
|
23
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@nextblock-cms/ui";
|
|
4
|
+
import { type ComponentProps } from "react";
|
|
5
|
+
import { useFormStatus } from "react-dom";
|
|
6
|
+
|
|
7
|
+
type Props = ComponentProps<typeof Button> & {
|
|
8
|
+
pendingText?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function SubmitButton({
|
|
12
|
+
children,
|
|
13
|
+
pendingText = "Submitting...",
|
|
14
|
+
...props
|
|
15
|
+
}: Props) {
|
|
16
|
+
const { pending } = useFormStatus();
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Button type="submit" aria-disabled={pending} {...props}>
|
|
20
|
+
{pending ? pendingText : children}
|
|
21
|
+
</Button>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Aperture,
|
|
5
|
+
Atom,
|
|
6
|
+
Blend,
|
|
7
|
+
Brush,
|
|
8
|
+
Cloud,
|
|
9
|
+
Contrast,
|
|
10
|
+
Droplet,
|
|
11
|
+
Feather,
|
|
12
|
+
Flame,
|
|
13
|
+
Gem,
|
|
14
|
+
Ghost,
|
|
15
|
+
Leaf,
|
|
16
|
+
Moon,
|
|
17
|
+
Mountain,
|
|
18
|
+
Palette,
|
|
19
|
+
Rocket,
|
|
20
|
+
Snowflake,
|
|
21
|
+
Sparkles,
|
|
22
|
+
Star,
|
|
23
|
+
Sun,
|
|
24
|
+
Sunrise,
|
|
25
|
+
Sunset,
|
|
26
|
+
Waves,
|
|
27
|
+
Zap,
|
|
28
|
+
type LucideIcon,
|
|
29
|
+
} from "lucide-react";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Curated icon set offered to themes.
|
|
33
|
+
*
|
|
34
|
+
* A fixed map rather than a dynamic lucide lookup: the icon name comes from the
|
|
35
|
+
* database, and importing lucide dynamically by string would either pull the
|
|
36
|
+
* whole icon set into the bundle or break tree-shaking.
|
|
37
|
+
*/
|
|
38
|
+
export const THEME_ICONS: Record<string, LucideIcon> = {
|
|
39
|
+
Sun,
|
|
40
|
+
Moon,
|
|
41
|
+
Zap,
|
|
42
|
+
Sparkles,
|
|
43
|
+
Palette,
|
|
44
|
+
Flame,
|
|
45
|
+
Droplet,
|
|
46
|
+
Leaf,
|
|
47
|
+
Star,
|
|
48
|
+
Cloud,
|
|
49
|
+
Snowflake,
|
|
50
|
+
Waves,
|
|
51
|
+
Mountain,
|
|
52
|
+
Sunrise,
|
|
53
|
+
Sunset,
|
|
54
|
+
Contrast,
|
|
55
|
+
Blend,
|
|
56
|
+
Brush,
|
|
57
|
+
Aperture,
|
|
58
|
+
Atom,
|
|
59
|
+
Feather,
|
|
60
|
+
Gem,
|
|
61
|
+
Ghost,
|
|
62
|
+
Rocket,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const THEME_ICON_NAMES = Object.keys(THEME_ICONS);
|
|
66
|
+
|
|
67
|
+
export function ThemeIcon({
|
|
68
|
+
name,
|
|
69
|
+
size = 16,
|
|
70
|
+
className,
|
|
71
|
+
}: {
|
|
72
|
+
name: string;
|
|
73
|
+
size?: number;
|
|
74
|
+
className?: string;
|
|
75
|
+
}) {
|
|
76
|
+
const Icon = THEME_ICONS[name] ?? Palette;
|
|
77
|
+
return <Icon size={size} className={className} />;
|
|
78
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
3
|
import { Button } from "@nextblock-cms/ui";
|
|
4
4
|
import {
|
|
5
5
|
DropdownMenu,
|
|
@@ -8,83 +8,78 @@ import {
|
|
|
8
8
|
DropdownMenuRadioItem,
|
|
9
9
|
DropdownMenuTrigger,
|
|
10
10
|
} from "@nextblock-cms/ui";
|
|
11
|
-
import { Laptop
|
|
12
|
-
import { useTheme } from "next-themes";
|
|
13
|
-
import { useEffect, useState } from "react";
|
|
14
|
-
import { useTranslations } from "@nextblock-cms/utils";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
</DropdownMenu>
|
|
87
|
-
);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export { ThemeSwitcher };
|
|
11
|
+
import { Laptop } from "lucide-react";
|
|
12
|
+
import { useTheme } from "next-themes";
|
|
13
|
+
import { useEffect, useState } from "react";
|
|
14
|
+
import { useTranslations } from "@nextblock-cms/utils";
|
|
15
|
+
import { useThemeCatalog } from "../context/ThemeCatalogContext";
|
|
16
|
+
import { ThemeIcon } from "./theme-icon";
|
|
17
|
+
|
|
18
|
+
const ICON_SIZE = 16;
|
|
19
|
+
|
|
20
|
+
const ThemeSwitcher = () => {
|
|
21
|
+
const [mounted, setMounted] = useState(false);
|
|
22
|
+
const { theme, setTheme } = useTheme();
|
|
23
|
+
const { t } = useTranslations();
|
|
24
|
+
const themes = useThemeCatalog();
|
|
25
|
+
|
|
26
|
+
// useEffect only runs on the client, so now we can safely show the UI
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setMounted(true);
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
if (!mounted) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const active = themes.find((entry) => entry.slug === theme);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Built-in slugs keep their existing translation keys so no copy is lost;
|
|
39
|
+
* admin-created themes fall back to the name stored on the row.
|
|
40
|
+
*/
|
|
41
|
+
const labelFor = (slug: string, name: string) => {
|
|
42
|
+
const builtin: Record<string, string> = {
|
|
43
|
+
light: "theme_light",
|
|
44
|
+
dark: "theme_dark",
|
|
45
|
+
vibrant: "theme_vibrant",
|
|
46
|
+
};
|
|
47
|
+
const key = builtin[slug];
|
|
48
|
+
if (!key) return name;
|
|
49
|
+
const translated = t(key);
|
|
50
|
+
return translated === key ? name : translated;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<DropdownMenu>
|
|
55
|
+
<DropdownMenuTrigger asChild>
|
|
56
|
+
<Button variant="ghost" size={"sm"} aria-label={t('theme_switcher')}>
|
|
57
|
+
{active ? (
|
|
58
|
+
<ThemeIcon name={active.icon} size={ICON_SIZE} className="text-muted-foreground" />
|
|
59
|
+
) : (
|
|
60
|
+
<Laptop size={ICON_SIZE} className="text-muted-foreground" />
|
|
61
|
+
)}
|
|
62
|
+
</Button>
|
|
63
|
+
</DropdownMenuTrigger>
|
|
64
|
+
<DropdownMenuContent className="w-content" align="start">
|
|
65
|
+
<DropdownMenuRadioGroup
|
|
66
|
+
value={theme}
|
|
67
|
+
onValueChange={(e) => setTheme(e)}
|
|
68
|
+
>
|
|
69
|
+
{themes.map((entry) => (
|
|
70
|
+
<DropdownMenuRadioItem key={entry.slug} className="flex gap-2" value={entry.slug}>
|
|
71
|
+
<ThemeIcon name={entry.icon} size={ICON_SIZE} className="text-muted-foreground" />{" "}
|
|
72
|
+
<span>{labelFor(entry.slug, entry.name)}</span>
|
|
73
|
+
</DropdownMenuRadioItem>
|
|
74
|
+
))}
|
|
75
|
+
<DropdownMenuRadioItem className="flex gap-2" value="system">
|
|
76
|
+
<Laptop size={ICON_SIZE} className="text-muted-foreground" />{" "}
|
|
77
|
+
<span>{t('theme_system')}</span>
|
|
78
|
+
</DropdownMenuRadioItem>
|
|
79
|
+
</DropdownMenuRadioGroup>
|
|
80
|
+
</DropdownMenuContent>
|
|
81
|
+
</DropdownMenu>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export { ThemeSwitcher };
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import dynamic from 'next/dynamic';
|
|
4
|
-
|
|
5
|
-
// Defer the visual-editing toolbar (and its heavy editor graph: BlockEditorModal,
|
|
6
|
-
// the per-block editors, and editor.css) out of the public bundle. The layout only
|
|
7
|
-
// renders this in draft/visual-editing mode, but a *static* import would still ship
|
|
8
|
-
// the entire editor graph to every public page. Loading it via next/dynamic with
|
|
9
|
-
// ssr:false keeps it out of the public homepage's render-blocking CSS and JS, and
|
|
10
|
-
// pulls it in client-side only when visual editing is actually active.
|
|
11
|
-
const NextblockVisualEditing = dynamic(
|
|
12
|
-
() =>
|
|
13
|
-
import('./NextblockVisualEditing').then(
|
|
14
|
-
(module) => module.NextblockVisualEditing
|
|
15
|
-
),
|
|
16
|
-
{ ssr: false }
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
export function DeferredVisualEditing() {
|
|
20
|
-
return <NextblockVisualEditing />;
|
|
21
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import dynamic from 'next/dynamic';
|
|
4
|
+
|
|
5
|
+
// Defer the visual-editing toolbar (and its heavy editor graph: BlockEditorModal,
|
|
6
|
+
// the per-block editors, and editor.css) out of the public bundle. The layout only
|
|
7
|
+
// renders this in draft/visual-editing mode, but a *static* import would still ship
|
|
8
|
+
// the entire editor graph to every public page. Loading it via next/dynamic with
|
|
9
|
+
// ssr:false keeps it out of the public homepage's render-blocking CSS and JS, and
|
|
10
|
+
// pulls it in client-side only when visual editing is actually active.
|
|
11
|
+
const NextblockVisualEditing = dynamic(
|
|
12
|
+
() =>
|
|
13
|
+
import('./NextblockVisualEditing').then(
|
|
14
|
+
(module) => module.NextblockVisualEditing
|
|
15
|
+
),
|
|
16
|
+
{ ssr: false }
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
export function DeferredVisualEditing() {
|
|
20
|
+
return <NextblockVisualEditing />;
|
|
21
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// context/AuthContext.tsx
|
|
2
|
-
'use client';
|
|
3
|
-
|
|
4
|
-
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
|
5
|
-
import type { ReactNode } from 'react';
|
|
6
|
-
import type { User, SupabaseClient } from '@supabase/supabase-js';
|
|
7
|
-
import type { Database } from '@nextblock-cms/db';
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
|
5
|
+
import type { ReactNode } from 'react';
|
|
6
|
+
import type { User, SupabaseClient } from '@supabase/supabase-js';
|
|
7
|
+
import type { Database } from '@nextblock-cms/db';
|
|
8
8
|
|
|
9
9
|
type Profile = Database['public']['Tables']['profiles']['Row'];
|
|
10
10
|
type UserRole = Database['public']['Enums']['user_role'];
|
|
@@ -28,17 +28,17 @@ interface AuthContextType {
|
|
|
28
28
|
|
|
29
29
|
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|
30
30
|
|
|
31
|
-
export const AuthProvider = ({ children, serverUser, serverProfile }: AuthProviderProps) => {
|
|
32
|
-
const [user, setUser] = useState<User | null>(serverUser);
|
|
33
|
-
const [profile, setProfile] = useState<Profile | null>(serverProfile);
|
|
34
|
-
const [role, setRole] = useState<UserRole | null>(serverProfile?.role ?? null);
|
|
35
|
-
const [isLoading] = useState(false);
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
setUser(serverUser);
|
|
39
|
-
setProfile(serverProfile);
|
|
40
|
-
setRole(serverProfile?.role ?? null);
|
|
41
|
-
}, [serverUser, serverProfile]);
|
|
31
|
+
export const AuthProvider = ({ children, serverUser, serverProfile }: AuthProviderProps) => {
|
|
32
|
+
const [user, setUser] = useState<User | null>(serverUser);
|
|
33
|
+
const [profile, setProfile] = useState<Profile | null>(serverProfile);
|
|
34
|
+
const [role, setRole] = useState<UserRole | null>(serverProfile?.role ?? null);
|
|
35
|
+
const [isLoading] = useState(false);
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
setUser(serverUser);
|
|
39
|
+
setProfile(serverProfile);
|
|
40
|
+
setRole(serverProfile?.role ?? null);
|
|
41
|
+
}, [serverUser, serverProfile]);
|
|
42
42
|
|
|
43
43
|
const isAdmin = role === 'ADMIN';
|
|
44
44
|
const isWriter = role === 'WRITER';
|
|
@@ -49,11 +49,11 @@ export const AuthProvider = ({ children, serverUser, serverProfile }: AuthProvid
|
|
|
49
49
|
profile,
|
|
50
50
|
role,
|
|
51
51
|
isLoading,
|
|
52
|
-
isAdmin,
|
|
53
|
-
isWriter,
|
|
54
|
-
isUserRole,
|
|
55
|
-
supabase: null,
|
|
56
|
-
}), [user, profile, role, isLoading, isAdmin, isWriter, isUserRole]);
|
|
52
|
+
isAdmin,
|
|
53
|
+
isWriter,
|
|
54
|
+
isUserRole,
|
|
55
|
+
supabase: null,
|
|
56
|
+
}), [user, profile, role, isLoading, isAdmin, isWriter, isUserRole]);
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
59
|
<AuthContext.Provider value={value}>
|
|
@@ -68,4 +68,4 @@ export const useAuth = () => {
|
|
|
68
68
|
throw new Error('useAuth must be used within an AuthProvider');
|
|
69
69
|
}
|
|
70
70
|
return context;
|
|
71
|
-
};
|
|
71
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
/** The switcher-facing shape of a row in `site_themes`. */
|
|
6
|
+
export interface ThemeCatalogEntry {
|
|
7
|
+
slug: string;
|
|
8
|
+
name: string;
|
|
9
|
+
/** lucide-react icon name. */
|
|
10
|
+
icon: string;
|
|
11
|
+
colorScheme: "light" | "dark";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Themes are read once on the server in app/layout.tsx and handed to the client
|
|
16
|
+
* through this context, so the switcher never fetches and never hardcodes a
|
|
17
|
+
* list. Falls back to the palette shipped in libs/ui/src/styles/theme.css when
|
|
18
|
+
* the table is empty or unreachable.
|
|
19
|
+
*/
|
|
20
|
+
export const FALLBACK_THEME_CATALOG: ThemeCatalogEntry[] = [
|
|
21
|
+
{ slug: "light", name: "Light", icon: "Sun", colorScheme: "light" },
|
|
22
|
+
{ slug: "dark", name: "Dark", icon: "Moon", colorScheme: "dark" },
|
|
23
|
+
{ slug: "vibrant", name: "Vibrant", icon: "Zap", colorScheme: "dark" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const ThemeCatalogContext = createContext<ThemeCatalogEntry[]>(FALLBACK_THEME_CATALOG);
|
|
27
|
+
|
|
28
|
+
export function ThemeCatalogProvider({
|
|
29
|
+
themes,
|
|
30
|
+
children,
|
|
31
|
+
}: {
|
|
32
|
+
themes?: ThemeCatalogEntry[];
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
}) {
|
|
35
|
+
const value = useMemo(
|
|
36
|
+
() => (Array.isArray(themes) && themes.length > 0 ? themes : FALLBACK_THEME_CATALOG),
|
|
37
|
+
[themes],
|
|
38
|
+
);
|
|
39
|
+
return <ThemeCatalogContext.Provider value={value}>{children}</ThemeCatalogContext.Provider>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function useThemeCatalog(): ThemeCatalogEntry[] {
|
|
43
|
+
return useContext(ThemeCatalogContext);
|
|
44
|
+
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import type { Database } from '@nextblock-cms/db';
|
|
2
|
-
import { resolveSupabaseAnonKey, resolveSupabaseUrl } from '../lib/setup/env-status';
|
|
3
|
-
|
|
4
|
-
type Language = Database['public']['Tables']['languages']['Row'];
|
|
5
|
-
|
|
6
|
-
export async function fetchActiveLanguagesFromRest(): Promise<Language[]> {
|
|
7
|
-
const supabaseUrl = resolveSupabaseUrl();
|
|
8
|
-
const supabaseAnonKey = resolveSupabaseAnonKey();
|
|
9
|
-
|
|
10
|
-
if (!supabaseUrl || !supabaseAnonKey) {
|
|
11
|
-
return [];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const url = new URL('/rest/v1/languages', supabaseUrl);
|
|
15
|
-
url.searchParams.set('select', 'id, code, name, is_default, is_active, created_at, updated_at');
|
|
16
|
-
url.searchParams.set('is_active', 'eq.true');
|
|
17
|
-
url.searchParams.set('order', 'name.asc');
|
|
18
|
-
|
|
19
|
-
const response = await fetch(url.toString(), {
|
|
20
|
-
headers: {
|
|
21
|
-
apikey: supabaseAnonKey,
|
|
22
|
-
Authorization: `Bearer ${supabaseAnonKey}`,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const data = await response.json();
|
|
31
|
-
return Array.isArray(data) ? data : [];
|
|
32
|
-
}
|
|
1
|
+
import type { Database } from '@nextblock-cms/db';
|
|
2
|
+
import { resolveSupabaseAnonKey, resolveSupabaseUrl } from '../lib/setup/env-status';
|
|
3
|
+
|
|
4
|
+
type Language = Database['public']['Tables']['languages']['Row'];
|
|
5
|
+
|
|
6
|
+
export async function fetchActiveLanguagesFromRest(): Promise<Language[]> {
|
|
7
|
+
const supabaseUrl = resolveSupabaseUrl();
|
|
8
|
+
const supabaseAnonKey = resolveSupabaseAnonKey();
|
|
9
|
+
|
|
10
|
+
if (!supabaseUrl || !supabaseAnonKey) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const url = new URL('/rest/v1/languages', supabaseUrl);
|
|
15
|
+
url.searchParams.set('select', 'id, code, name, is_default, is_active, created_at, updated_at');
|
|
16
|
+
url.searchParams.set('is_active', 'eq.true');
|
|
17
|
+
url.searchParams.set('order', 'name.asc');
|
|
18
|
+
|
|
19
|
+
const response = await fetch(url.toString(), {
|
|
20
|
+
headers: {
|
|
21
|
+
apikey: supabaseAnonKey,
|
|
22
|
+
Authorization: `Bearer ${supabaseAnonKey}`,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
return Array.isArray(data) ? data : [];
|
|
32
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
-- Expose the JWT secret to Postgres as a database GUC, matching Supabase's setup. Runs once.
|
|
2
|
-
\set jwt_secret `echo "$JWT_SECRET"`
|
|
3
|
-
\set jwt_exp `echo "$JWT_EXP"`
|
|
4
|
-
|
|
5
|
-
alter database postgres set "app.settings.jwt_secret" to :'jwt_secret';
|
|
6
|
-
alter database postgres set "app.settings.jwt_exp" to :'jwt_exp';
|
|
1
|
+
-- Expose the JWT secret to Postgres as a database GUC, matching Supabase's setup. Runs once.
|
|
2
|
+
\set jwt_secret `echo "$JWT_SECRET"`
|
|
3
|
+
\set jwt_exp `echo "$JWT_EXP"`
|
|
4
|
+
|
|
5
|
+
alter database postgres set "app.settings.jwt_secret" to :'jwt_secret';
|
|
6
|
+
alter database postgres set "app.settings.jwt_exp" to :'jwt_exp';
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
-- Self-hosted Supabase role passwords. The supabase/postgres image creates the platform roles;
|
|
2
|
-
-- GoTrue logs in as supabase_auth_admin and PostgREST as authenticator. Give the roles that exist
|
|
3
|
-
-- the generated POSTGRES_PASSWORD (the set varies by image tag, so each is guarded; the password
|
|
4
|
-
-- is passed via a session GUC because psql variables aren't interpolated inside a dollar block).
|
|
5
|
-
-- Runs once on first init.
|
|
6
|
-
\set pgpass `echo "$POSTGRES_PASSWORD"`
|
|
7
|
-
select set_config('nextblock.pgpass', :'pgpass', false);
|
|
8
|
-
|
|
9
|
-
do $$
|
|
10
|
-
declare
|
|
11
|
-
role_name text;
|
|
12
|
-
begin
|
|
13
|
-
foreach role_name in array array[
|
|
14
|
-
'authenticator',
|
|
15
|
-
'pgbouncer',
|
|
16
|
-
'supabase_auth_admin',
|
|
17
|
-
'supabase_storage_admin',
|
|
18
|
-
'supabase_functions_admin',
|
|
19
|
-
'supabase_read_only_user'
|
|
20
|
-
] loop
|
|
21
|
-
if exists (select 1 from pg_roles where rolname = role_name) then
|
|
22
|
-
execute format('alter role %I with password %L', role_name, current_setting('nextblock.pgpass'));
|
|
23
|
-
end if;
|
|
24
|
-
end loop;
|
|
25
|
-
end $$;
|
|
1
|
+
-- Self-hosted Supabase role passwords. The supabase/postgres image creates the platform roles;
|
|
2
|
+
-- GoTrue logs in as supabase_auth_admin and PostgREST as authenticator. Give the roles that exist
|
|
3
|
+
-- the generated POSTGRES_PASSWORD (the set varies by image tag, so each is guarded; the password
|
|
4
|
+
-- is passed via a session GUC because psql variables aren't interpolated inside a dollar block).
|
|
5
|
+
-- Runs once on first init.
|
|
6
|
+
\set pgpass `echo "$POSTGRES_PASSWORD"`
|
|
7
|
+
select set_config('nextblock.pgpass', :'pgpass', false);
|
|
8
|
+
|
|
9
|
+
do $$
|
|
10
|
+
declare
|
|
11
|
+
role_name text;
|
|
12
|
+
begin
|
|
13
|
+
foreach role_name in array array[
|
|
14
|
+
'authenticator',
|
|
15
|
+
'pgbouncer',
|
|
16
|
+
'supabase_auth_admin',
|
|
17
|
+
'supabase_storage_admin',
|
|
18
|
+
'supabase_functions_admin',
|
|
19
|
+
'supabase_read_only_user'
|
|
20
|
+
] loop
|
|
21
|
+
if exists (select 1 from pg_roles where rolname = role_name) then
|
|
22
|
+
execute format('alter role %I with password %L', role_name, current_setting('nextblock.pgpass'));
|
|
23
|
+
end if;
|
|
24
|
+
end loop;
|
|
25
|
+
end $$;
|