@plutocms/supabase 0.11.0 → 0.11.1
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 +13 -0
- package/app/plugins/pluto-extension.ts +35 -8
- package/package.json +2 -2
- package/server/utils/typegen.ts +67 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.1](https://github.com/plutocms/supabase/compare/v0.11.0...v0.11.1) (2026-10-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **deps:** use @plutocms/pluto 0.17 ([#91](https://github.com/plutocms/supabase/issues/91)) ([7deeac5](https://github.com/plutocms/supabase/commit/7deeac5379ddaac0317fa457897190c0850e8ffc))
|
|
9
|
+
* **typegen:** keep the PostgREST version block and the app's format ([#90](https://github.com/plutocms/supabase/issues/90)) ([2518c33](https://github.com/plutocms/supabase/commit/2518c33f69fe188e69d93695819d7d3ca19932d7))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Performance Improvements
|
|
13
|
+
|
|
14
|
+
* **admin:** load the admin components on demand and start the setup check early ([#89](https://github.com/plutocms/supabase/issues/89)) ([f0d36bc](https://github.com/plutocms/supabase/commit/f0d36bc7d46f911522990653cd93ebb523c5a774))
|
|
15
|
+
|
|
3
16
|
## [0.11.0](https://github.com/plutocms/supabase/compare/v0.10.0...v0.11.0) (2026-10-20)
|
|
4
17
|
|
|
5
18
|
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { defineAsyncComponent } from 'vue'
|
|
2
|
+
|
|
3
|
+
// The three components load on demand. They stay out of the entry chunk. Core
|
|
4
|
+
// shows a skeleton while each chunk loads.
|
|
5
|
+
const AuthSignIn = defineAsyncComponent(
|
|
6
|
+
() => import('../components/auth/AuthSignIn.vue')
|
|
7
|
+
)
|
|
8
|
+
const MigrationsBanner = defineAsyncComponent(
|
|
9
|
+
() => import('../components/migrations/MigrationsBanner.vue')
|
|
10
|
+
)
|
|
11
|
+
const SettingsGeneralPanel = defineAsyncComponent(
|
|
12
|
+
() => import('../components/settings/SettingsGeneralPanel.vue')
|
|
13
|
+
)
|
|
4
14
|
|
|
5
15
|
export default defineNuxtPlugin(() => {
|
|
6
16
|
// Read at setup, while the Nuxt context exists. The driver below calls it
|
|
@@ -35,11 +45,7 @@ export default defineNuxtPlugin(() => {
|
|
|
35
45
|
// again each time.
|
|
36
46
|
const setupDone = useState<boolean>('supabase-setup-done', () => false)
|
|
37
47
|
|
|
38
|
-
async function
|
|
39
|
-
if (setupDone.value) {
|
|
40
|
-
return 'done'
|
|
41
|
-
}
|
|
42
|
-
|
|
48
|
+
async function fetchSetupState(): Promise<SetupState> {
|
|
43
49
|
let state: SetupState = 'unknown'
|
|
44
50
|
try {
|
|
45
51
|
state = setupStateFromResponse(
|
|
@@ -56,6 +62,27 @@ export default defineNuxtPlugin(() => {
|
|
|
56
62
|
return state
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
// On a cold load of an admin path, the request starts here, at plugin setup.
|
|
66
|
+
// The guard then awaits a request that is already in flight. The guard takes
|
|
67
|
+
// this promise once, so a later navigation reads the state again.
|
|
68
|
+
let earlyState: Promise<SetupState> | null =
|
|
69
|
+
import.meta.client &&
|
|
70
|
+
!setupDone.value &&
|
|
71
|
+
/^\/admin(?:\/|$)/.test(window.location.pathname)
|
|
72
|
+
? fetchSetupState()
|
|
73
|
+
: null
|
|
74
|
+
|
|
75
|
+
async function readSetupState(): Promise<SetupState> {
|
|
76
|
+
if (setupDone.value) {
|
|
77
|
+
return 'done'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const early = earlyState
|
|
81
|
+
earlyState = null
|
|
82
|
+
|
|
83
|
+
return early ?? fetchSetupState()
|
|
84
|
+
}
|
|
85
|
+
|
|
59
86
|
if (import.meta.client) {
|
|
60
87
|
watch(
|
|
61
88
|
[() => Boolean(session.value), hasSettingsModified],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plutocms/supabase",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.1",
|
|
5
5
|
"trustedDependencies": [
|
|
6
6
|
"@parcel/watcher",
|
|
7
7
|
"@plutocms/pluto",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@nuxt/eslint": "^1.17.0",
|
|
40
40
|
"@nuxt/ui": "^4.12.0",
|
|
41
41
|
"@nuxtjs/supabase": "^2.1.0",
|
|
42
|
-
"@plutocms/pluto": "^0.
|
|
42
|
+
"@plutocms/pluto": "^0.17.0",
|
|
43
43
|
"@plutocms/utils": "^0.2.1",
|
|
44
44
|
"postgres": "^3.4.9",
|
|
45
45
|
"supabase": "^2.121.0",
|
package/server/utils/typegen.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { execFile } from 'node:child_process'
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { createRequire } from 'node:module'
|
|
3
4
|
import { join } from 'node:path'
|
|
5
|
+
import { pathToFileURL } from 'node:url'
|
|
4
6
|
import { promisify } from 'node:util'
|
|
5
7
|
|
|
6
8
|
const execFileAsync = promisify(execFile)
|
|
@@ -17,6 +19,63 @@ function resolveSupabaseBin(rootDir: string): string {
|
|
|
17
19
|
return existsSync(localBin) ? localBin : 'supabase'
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
// The block, with its leading comment lines. The block has no nested braces.
|
|
23
|
+
const INTERNAL_BLOCK = /(?:^[ \t]*\/\/[^\n]*\n)*^[ \t]*__InternalSupabase:\s*\{[^{}]*\}[ \t]*\n/m
|
|
24
|
+
const DATABASE_OPEN = /^export type Database = \{[ \t]*\n/m
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Keeps the `__InternalSupabase` block of the existing types file.
|
|
28
|
+
*
|
|
29
|
+
* The `--db-url` mode of the Supabase CLI does not write this block. It
|
|
30
|
+
* holds the PostgREST version that supabase-js reads for its typings. When
|
|
31
|
+
* the new output has no block and the existing file has one, this function
|
|
32
|
+
* copies the existing block into the new output. In every other case it
|
|
33
|
+
* returns the new output as it is.
|
|
34
|
+
*/
|
|
35
|
+
export function keepInternalSupabase(
|
|
36
|
+
next: string,
|
|
37
|
+
existing: string | null
|
|
38
|
+
): string {
|
|
39
|
+
if (!existing || next.includes('__InternalSupabase')) {
|
|
40
|
+
return next
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const block = existing.match(INTERNAL_BLOCK)?.[0]
|
|
44
|
+
const open = next.match(DATABASE_OPEN)
|
|
45
|
+
|
|
46
|
+
if (!block || !open || open.index === undefined) {
|
|
47
|
+
return next
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const at = open.index + open[0].length
|
|
51
|
+
|
|
52
|
+
return next.slice(0, at) + block + next.slice(at)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Formats the text with the Prettier of the app. It resolves Prettier from
|
|
57
|
+
* `rootDir`. It returns the text unchanged when the app has no Prettier or
|
|
58
|
+
* when the format fails.
|
|
59
|
+
*/
|
|
60
|
+
async function formatWithAppPrettier(
|
|
61
|
+
rootDir: string,
|
|
62
|
+
filePath: string,
|
|
63
|
+
text: string
|
|
64
|
+
): Promise<string> {
|
|
65
|
+
try {
|
|
66
|
+
const entry = createRequire(join(rootDir, 'package.json')).resolve(
|
|
67
|
+
'prettier'
|
|
68
|
+
)
|
|
69
|
+
const prettier = await import(pathToFileURL(entry).href)
|
|
70
|
+
const api = prettier.default ?? prettier
|
|
71
|
+
const options = (await api.resolveConfig(filePath)) ?? {}
|
|
72
|
+
|
|
73
|
+
return await api.format(text, { ...options, filepath: filePath })
|
|
74
|
+
} catch {
|
|
75
|
+
return text
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
20
79
|
/**
|
|
21
80
|
* Regenerates the Supabase `Database` types from the live database schema
|
|
22
81
|
* and writes them to <rootDir>/shared/types/supabase.ts, only touching the
|
|
@@ -56,11 +115,17 @@ export async function regenerateSupabaseTypes(
|
|
|
56
115
|
? readFileSync(targetPath, 'utf-8')
|
|
57
116
|
: null
|
|
58
117
|
|
|
59
|
-
|
|
118
|
+
const processed = await formatWithAppPrettier(
|
|
119
|
+
rootDir,
|
|
120
|
+
targetPath,
|
|
121
|
+
keepInternalSupabase(stdout, existing)
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if (existing === processed) {
|
|
60
125
|
return
|
|
61
126
|
}
|
|
62
127
|
|
|
63
|
-
writeFileSync(targetPath,
|
|
128
|
+
writeFileSync(targetPath, processed, 'utf-8')
|
|
64
129
|
console.warn(`[typegen] Regenerated Supabase types at ${targetPath}`)
|
|
65
130
|
} catch (error) {
|
|
66
131
|
console.warn('[typegen] Failed to regenerate Supabase types:', error)
|