@plutocms/supabase 0.20.0 → 0.22.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 CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.0](https://github.com/plutocms/supabase/compare/v0.21.0...v0.22.0) (2026-11-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * the admin navbar shows the Supabase backend, with the project and a dashboard link ([#190](https://github.com/plutocms/supabase/issues/190)) ([2b8de9f](https://github.com/plutocms/supabase/commit/2b8de9f500a71a2afeb65fe97d66be41dac2eed2))
9
+
10
+ ## [0.21.0](https://github.com/plutocms/supabase/compare/v0.20.0...v0.21.0) (2026-10-31)
11
+
12
+
13
+ ### Features
14
+
15
+ * the supabase repo holds the Supabase integration (supabase, supabase-shop, supabase-blog) ([0da28ef](https://github.com/plutocms/supabase/commit/0da28ef93d4882076a3750822f011de9714156d7))
16
+ * the supabase repo holds the Supabase integration (supabase, supabase-shop, supabase-blog) ([ab50f47](https://github.com/plutocms/supabase/commit/ab50f4779a8fb77f61a43f4db9efcd4314ae59ec))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * apps that extend the layer no longer get the ESLint module or an install script ([#151](https://github.com/plutocms/supabase/issues/151)) ([818bf93](https://github.com/plutocms/supabase/commit/818bf93a44cea01e6a1b237ace33a325f45de590))
22
+ * **deps:** ensure @plutocms/pluto ^0.10.0 range is published ([#67](https://github.com/plutocms/supabase/issues/67)) ([ed45ad3](https://github.com/plutocms/supabase/commit/ed45ad3a5b1ed4c4990a2272c48571c5e8eb5a92))
23
+
3
24
  ## [0.20.0](https://github.com/plutocms/supabase/compare/v0.19.0...v0.20.0) (2026-10-31)
4
25
 
5
26
 
package/FEATURES.md CHANGED
@@ -19,7 +19,8 @@ policies shared by every project here.
19
19
  filters, puts the timestamps on items, and reads the public API of core with an anonymous client.
20
20
  @.claude/skills/content-adapter/SKILL.md
21
21
  - Auth driver: plugs Supabase sign-in into the admin shell that pluto core owns (navbar, sign-in
22
- page, route guard), and keeps the setup guard in the driver.
22
+ page, route guard), keeps the setup guard in the driver, and registers the backend badge
23
+ ("Database · Supabase", with the project and a dashboard link).
23
24
  @.claude/skills/auth-driver/SKILL.md
24
25
  - Profile language: stores each user's admin language in `profiles.locale`, written through a
25
26
  security-definer function, and plugs it into pluto's i18n as a locale driver.
package/README.md CHANGED
@@ -26,7 +26,7 @@ npm i @plutocms/supabase
26
26
  ```ts
27
27
  // nuxt.config.ts
28
28
  export default defineNuxtConfig({
29
- extends: [['@plutocms/supabase', { install: true }]],
29
+ extends: ['@plutocms/supabase'],
30
30
  })
31
31
  ```
32
32
 
@@ -116,7 +116,7 @@ a page of another site cannot call them. A failure is an HTTP error with a trans
116
116
 
117
117
  The public content of the Supabase layers is read through the public API of core,
118
118
  `GET /api/pluto/v1/content/<type>` (and `/<id or slug>`). See
119
- [the public API](https://pluto.vulmix.dev/docs/core/public-api). The routes are anonymous. This layer
119
+ [the public API](https://pluto.vulmix.dev/docs/build/public-api). The routes are anonymous. This layer
120
120
  reads for them with an anon client that has no user session, so Row Level Security applies as for
121
121
  an anonymous visitor, and the answer is the same for everyone. A CDN can cache it. The adapter
122
122
  never uses the service role key for a read. The adapter also supports the `filters` of a public
@@ -141,3 +141,7 @@ sort by date.
141
141
  ### Types
142
142
 
143
143
  - `Database`: Auto-imported type definitions for Supabase database interactions.
144
+
145
+ ## Development
146
+
147
+ This package lives in the [`plutocms/supabase`](https://github.com/plutocms/supabase) monorepo, in `packages/supabase`. Run `bun install` at the root of the repo, then the scripts of the package (`bun run --cwd packages/supabase dev`). This package is the base of the other two. Its changes reach `supabase-shop` and `supabase-blog` through the workspace link. Each package reads its own `.env` file.
@@ -0,0 +1,52 @@
1
+ <script setup lang="ts">
2
+ // The popover body of the backend badge of core (`backend.details`): the
3
+ // Supabase project that holds the content, with a link to its dashboard. A
4
+ // local Supabase (or a custom domain) has no project ref, so the host shows.
5
+ import {
6
+ supabaseDashboardLinks,
7
+ supabaseProjectRef,
8
+ } from '../../utils/supabase-project'
9
+
10
+ const { t } = usePlutoI18n()
11
+ const url = String(
12
+ (useRuntimeConfig().public.supabase as { url?: string } | undefined)?.url ??
13
+ ''
14
+ )
15
+ const projectRef = supabaseProjectRef(url)
16
+ const dashboard = projectRef ? supabaseDashboardLinks(projectRef).project : ''
17
+ const host = (() => {
18
+ try {
19
+ return new URL(url).host
20
+ } catch {
21
+ return ''
22
+ }
23
+ })()
24
+ </script>
25
+
26
+ <template>
27
+ <div class="space-y-3">
28
+ <p class="text-muted">{{ t('supabase.backend.description') }}</p>
29
+ <dl class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1">
30
+ <dt class="text-muted">
31
+ {{
32
+ projectRef
33
+ ? t('supabase.backend.project')
34
+ : t('supabase.backend.host')
35
+ }}
36
+ </dt>
37
+ <dd class="text-highlighted truncate font-mono text-xs/5">
38
+ {{ projectRef || host }}
39
+ </dd>
40
+ </dl>
41
+ <UButton
42
+ v-if="dashboard"
43
+ :label="t('supabase.backend.openDashboard')"
44
+ :to="dashboard"
45
+ color="neutral"
46
+ icon="i-lucide-external-link"
47
+ size="xs"
48
+ target="_blank"
49
+ variant="outline"
50
+ />
51
+ </div>
52
+ </template>
@@ -11,6 +11,10 @@ const MigrationsBanner = defineAsyncComponent(
11
11
  const SettingsGeneralPanel = defineAsyncComponent(
12
12
  () => import('../components/settings/SettingsGeneralPanel.vue')
13
13
  )
14
+ // The popover of the backend badge of the navbar.
15
+ const SupabaseBackendDetails = defineAsyncComponent(
16
+ () => import('../components/backend/SupabaseBackendDetails.vue')
17
+ )
14
18
  // The guide for the Supabase sign-in emails, a section of the Email tab.
15
19
  const AuthEmailsPanel = defineAsyncComponent(
16
20
  () => import('../components/mail/AuthEmailsPanel.vue')
@@ -152,6 +156,14 @@ export default defineNuxtPlugin(() => {
152
156
  // In development, "View site" opens this dev server, like the old navbar.
153
157
  url: () => (import.meta.dev ? null : siteSettings.value.website_url),
154
158
  },
159
+ // The backend badge of the navbar: the content is in a Supabase database.
160
+ backend: {
161
+ id: 'supabase',
162
+ kind: 'database',
163
+ label: 'Supabase',
164
+ icon: 'i-lucide-database',
165
+ details: SupabaseBackendDetails,
166
+ },
155
167
  // The pending-migrations notice, shown at the top of the admin pages.
156
168
  adminBanners: [{ id: 'migrations', component: MigrationsBanner }],
157
169
  settingsPanels: [
@@ -386,6 +386,12 @@
386
386
  "noProject": "Pluto could not read the project ref from your Supabase URL. Open the Supabase dashboard by hand.",
387
387
  "rateLimitHint": "After you set custom SMTP, open Authentication, then Rate Limits, and raise the number of emails each hour. The default is low."
388
388
  }
389
+ },
390
+ "backend": {
391
+ "description": "Each save writes to the Postgres database of this Supabase project.",
392
+ "project": "Project",
393
+ "host": "Server",
394
+ "openDashboard": "Open the Supabase dashboard"
389
395
  }
390
396
  }
391
397
  }
@@ -386,6 +386,12 @@
386
386
  "noProject": "O Pluto não conseguiu ler a referência do projeto na sua URL do Supabase. Abra o painel do Supabase manualmente.",
387
387
  "rateLimitHint": "Depois de configurar o SMTP próprio, abra Authentication, depois Rate Limits, e aumente o número de e-mails por hora. O padrão é baixo."
388
388
  }
389
+ },
390
+ "backend": {
391
+ "description": "Cada salvamento grava no banco Postgres deste projeto do Supabase.",
392
+ "project": "Projeto",
393
+ "host": "Servidor",
394
+ "openDashboard": "Abrir o painel do Supabase"
389
395
  }
390
396
  }
391
397
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@plutocms/supabase",
3
3
  "type": "module",
4
- "version": "0.20.0",
4
+ "version": "0.22.0",
5
5
  "description": "Supabase backend layer for Pluto",
6
6
  "author": "Victor Ribeiro",
7
- "homepage": "https://github.com/plutocms/supabase#readme",
7
+ "homepage": "https://github.com/plutocms/supabase/tree/main/packages/supabase#readme",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/plutocms/supabase.git"
10
+ "url": "git+https://github.com/plutocms/supabase.git",
11
+ "directory": "packages/supabase"
11
12
  },
12
13
  "bugs": {
13
14
  "url": "https://github.com/plutocms/supabase/issues"
@@ -18,7 +19,7 @@
18
19
  "dev": "nuxt dev",
19
20
  "generate": "nuxt generate",
20
21
  "preview": "nuxt preview",
21
- "prepare": "nuxt prepare",
22
+ "dev:prepare": "nuxt prepare",
22
23
  "prettier": "prettier --write .",
23
24
  "lint": "eslint .",
24
25
  "lint:fix": "eslint . --fix",
@@ -29,31 +30,22 @@
29
30
  "dependencies": {
30
31
  "@nuxt/ui": "^4.12.0",
31
32
  "@nuxtjs/supabase": "^2.1.0",
32
- "@plutocms/core": ">=0.41.0 <1.0.0",
33
+ "@plutocms/core": ">=0.48.0 <1.0.0",
33
34
  "@supabase/supabase-js": "^2.117.3",
34
35
  "postgres": "^3.4.9",
35
36
  "supabase": "^2.121.0",
36
37
  "zod": "^4.6.7"
37
38
  },
38
39
  "devDependencies": {
39
- "@antfu/eslint-config": "^9.5.1",
40
- "@nuxt/eslint-config": "^1.17.0",
41
40
  "@types/bun": "^1.4.3",
42
41
  "@vueuse/nuxt": "^14.4.0",
43
- "eslint": "^10.13.0",
44
- "eslint-config-prettier": "^10.1.8",
45
- "eslint-plugin-better-tailwindcss": "^4.10.0",
46
42
  "nuxt": "^4.6.2",
47
- "prettier": "^3.9.10",
48
43
  "tailwindcss": "^4.3.3",
49
44
  "vitest": "^5.0.5",
50
45
  "vue": "^3.5.44",
51
46
  "vue-router": "^5.4.0",
52
47
  "vue-tsc": "^3.3.13"
53
48
  },
54
- "overrides": {
55
- "typescript": "^5.9.3"
56
- },
57
49
  "publishConfig": {
58
50
  "access": "public"
59
51
  }
@@ -9,9 +9,9 @@ import { requireCapability } from './capability-guard'
9
9
  *
10
10
  * A content type's table name (`type.source`) is a plain runtime string —
11
11
  * it is not known until a layer declares a content type, in a different
12
- * repo, at that repo's build time. `serverSupabaseClient` defaults to
12
+ * package, at that package's build time. `serverSupabaseClient` defaults to
13
13
  * this app's own `Database` type (see `shared/types/supabase.ts`), whose
14
- * `.from()` only accepts this repo's own table names as literals. Casting
14
+ * `.from()` only accepts this package's own table names as literals. Casting
15
15
  * to the bare `SupabaseClient` type (whose own generic defaults to `any`)
16
16
  * is the one, deliberate place this file loses compile-time table/column
17
17
  * safety. See `.claude/skills/content-adapter/SKILL.md` for the full
@@ -19,7 +19,7 @@ import { requireCapability } from './capability-guard'
19
19
  *
20
20
  * Goes through `unknown` first: `serverSupabaseClient`'s inferred
21
21
  * `Database` type is whichever layer's own generated types are in scope
22
- * at the *call site* — this repo's own `shared/types/supabase.ts` when
22
+ * at the *call site* — this package's own `shared/types/supabase.ts` when
23
23
  * typechecked standalone, but a different consumer's own generated types
24
24
  * when this file is typechecked as part of a deeper extends chain (a
25
25
  * layer that extends this one, extending it in turn). A direct `as