@plutocms/supabase 0.0.1-alpha.9 → 0.1.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 +105 -0
- package/README.md +2 -4
- package/app/assets/css/tailwind.css +5 -0
- package/app/components/navbar/NavbarAdmin.vue +6 -5
- package/app/composables/auth.ts +124 -2
- package/app/middleware/auth.ts +9 -6
- package/app/middleware/setup-check.ts +25 -21
- package/app/pages/admin/(auth)/confirm.vue +38 -0
- package/app/pages/admin/(auth)/forgot-password.vue +88 -0
- package/app/pages/admin/(auth)/login.vue +5 -1
- package/app/pages/admin/(auth)/signup.vue +76 -16
- package/app/pages/admin/(auth)/update-password.vue +134 -0
- package/app/pages/admin/setup.vue +5 -142
- package/app/pages/admin.vue +2 -4
- package/modules/pluto-migrations.ts +121 -0
- package/nuxt.config.ts +14 -1
- package/package.json +40 -24
- package/public/schema.sql +46 -5
- package/scripts/supabase-typegen.ts +36 -21
- package/scripts/tsconfig.json +18 -0
- package/server/api/{signup.post.ts → auth/signup.post.ts} +7 -16
- package/server/api/setup/create.post.ts +39 -82
- package/server/plugins/migrations.ts +60 -0
- package/server/utils/migrations.ts +88 -0
- package/server/utils/sql.ts +81 -0
- package/server/utils/typegen.ts +68 -0
- package/shared/types/runtime-config.d.ts +16 -0
- package/shared/types/supabase.ts +138 -124
- package/.agents/skills/nuxt/GENERATION.md +0 -5
- package/.agents/skills/nuxt/SKILL.md +0 -55
- package/.agents/skills/nuxt/references/advanced-hooks.md +0 -289
- package/.agents/skills/nuxt/references/advanced-layers.md +0 -299
- package/.agents/skills/nuxt/references/advanced-module-authoring.md +0 -554
- package/.agents/skills/nuxt/references/best-practices-data-fetching.md +0 -357
- package/.agents/skills/nuxt/references/best-practices-ssr.md +0 -355
- package/.agents/skills/nuxt/references/core-cli.md +0 -263
- package/.agents/skills/nuxt/references/core-config.md +0 -162
- package/.agents/skills/nuxt/references/core-data-fetching.md +0 -236
- package/.agents/skills/nuxt/references/core-deployment.md +0 -224
- package/.agents/skills/nuxt/references/core-directory-structure.md +0 -269
- package/.agents/skills/nuxt/references/core-modules.md +0 -292
- package/.agents/skills/nuxt/references/core-routing.md +0 -226
- package/.agents/skills/nuxt/references/features-components-autoimport.md +0 -328
- package/.agents/skills/nuxt/references/features-components.md +0 -264
- package/.agents/skills/nuxt/references/features-composables.md +0 -276
- package/.agents/skills/nuxt/references/features-server.md +0 -265
- package/.agents/skills/nuxt/references/features-state.md +0 -194
- package/.agents/skills/nuxt/references/rendering-modes.md +0 -237
- package/.agents/skills/nuxt-ui/SKILL.md +0 -334
- package/.agents/skills/nuxt-ui/references/components.md +0 -377
- package/.agents/skills/nuxt-ui/references/composables.md +0 -127
- package/.agents/skills/nuxt-ui/references/layouts/chat.md +0 -195
- package/.agents/skills/nuxt-ui/references/layouts/dashboard.md +0 -220
- package/.agents/skills/nuxt-ui/references/layouts/docs.md +0 -141
- package/.agents/skills/nuxt-ui/references/layouts/editor.md +0 -167
- package/.agents/skills/nuxt-ui/references/layouts/page.md +0 -260
- package/.agents/skills/nuxt-ui/references/theming.md +0 -427
- package/.agents/skills/supabase-postgres-best-practices/AGENTS.md +0 -68
- package/.agents/skills/supabase-postgres-best-practices/CLAUDE.md +0 -1
- package/.agents/skills/supabase-postgres-best-practices/README.md +0 -116
- package/.agents/skills/supabase-postgres-best-practices/SKILL.md +0 -64
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +0 -55
- package/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +0 -49
- package/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +0 -46
- package/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +0 -44
- package/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +0 -41
- package/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +0 -46
- package/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +0 -54
- package/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +0 -53
- package/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +0 -50
- package/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +0 -50
- package/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +0 -56
- package/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +0 -68
- package/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +0 -50
- package/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +0 -54
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +0 -45
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +0 -55
- package/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +0 -55
- package/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +0 -44
- package/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +0 -40
- package/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +0 -48
- package/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +0 -43
- package/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +0 -45
- package/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +0 -80
- package/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +0 -46
- package/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +0 -59
- package/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +0 -55
- package/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +0 -55
- package/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +0 -61
- package/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +0 -54
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +0 -50
- package/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +0 -57
- package/.editorconfig +0 -12
- package/.eslintignore +0 -1
- package/.prettierrc +0 -9
- package/.vscode/extensions.json +0 -10
- package/.vscode/settings.json +0 -61
- package/bun.lock +0 -2837
- package/eslint.config.mjs +0 -88
- package/server/api/category/list.get.ts +0 -9
- package/server/api/category/new.post.ts +0 -31
- package/skills-lock.json +0 -20
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a SQL string into individual statements, correctly handling
|
|
3
|
+
* $$ dollar-quoted blocks, single-quoted strings, and -- comments.
|
|
4
|
+
*/
|
|
5
|
+
export function splitStatements(sql: string): string[] {
|
|
6
|
+
const statements: string[] = []
|
|
7
|
+
let current = ''
|
|
8
|
+
let i = 0
|
|
9
|
+
|
|
10
|
+
while (i < sql.length) {
|
|
11
|
+
// Check for dollar-quoting ($$)
|
|
12
|
+
if (sql[i] === '$' && sql[i + 1] === '$') {
|
|
13
|
+
current += '$$'
|
|
14
|
+
i += 2
|
|
15
|
+
// Read until closing $$
|
|
16
|
+
while (i < sql.length) {
|
|
17
|
+
if (sql[i] === '$' && sql[i + 1] === '$') {
|
|
18
|
+
current += '$$'
|
|
19
|
+
i += 2
|
|
20
|
+
break
|
|
21
|
+
}
|
|
22
|
+
current += sql[i]
|
|
23
|
+
i++
|
|
24
|
+
}
|
|
25
|
+
continue
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check for single-quoted strings (handle '' escapes)
|
|
29
|
+
if (sql[i] === `'`) {
|
|
30
|
+
current += sql[i]
|
|
31
|
+
i++
|
|
32
|
+
while (i < sql.length) {
|
|
33
|
+
if (sql[i] === `'` && sql[i + 1] === `'`) {
|
|
34
|
+
// Escaped quote
|
|
35
|
+
current += `''`
|
|
36
|
+
i += 2
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
if (sql[i] === `'`) {
|
|
40
|
+
current += sql[i]
|
|
41
|
+
i++
|
|
42
|
+
break
|
|
43
|
+
}
|
|
44
|
+
current += sql[i]
|
|
45
|
+
i++
|
|
46
|
+
}
|
|
47
|
+
continue
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check for single-line comments
|
|
51
|
+
if (sql[i] === '-' && sql[i + 1] === '-') {
|
|
52
|
+
while (i < sql.length && sql[i] !== '\n') {
|
|
53
|
+
current += sql[i]
|
|
54
|
+
i++
|
|
55
|
+
}
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Statement terminator
|
|
60
|
+
if (sql[i] === ';') {
|
|
61
|
+
current += ';'
|
|
62
|
+
const trimmed = current.trim()
|
|
63
|
+
if (trimmed && trimmed !== ';') {
|
|
64
|
+
statements.push(trimmed)
|
|
65
|
+
}
|
|
66
|
+
current = ''
|
|
67
|
+
i++
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
current += sql[i]
|
|
72
|
+
i++
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const trimmed = current.trim()
|
|
76
|
+
if (trimmed && trimmed !== ';') {
|
|
77
|
+
statements.push(trimmed)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return statements
|
|
81
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process'
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import { promisify } from 'node:util'
|
|
5
|
+
|
|
6
|
+
const execFileAsync = promisify(execFile)
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the local `supabase` CLI binary from node_modules/.bin so
|
|
10
|
+
* generation works from within the Nitro dev server without relying on
|
|
11
|
+
* `bunx`/`npx` (and without requiring `supabase login`, since we connect
|
|
12
|
+
* directly via --db-url).
|
|
13
|
+
*/
|
|
14
|
+
function resolveSupabaseBin(rootDir: string): string {
|
|
15
|
+
const binName = process.platform === 'win32' ? 'supabase.cmd' : 'supabase'
|
|
16
|
+
const localBin = join(rootDir, 'node_modules/.bin', binName)
|
|
17
|
+
return existsSync(localBin) ? localBin : 'supabase'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Regenerates the Supabase `Database` types from the live database schema
|
|
22
|
+
* and writes them to <rootDir>/shared/types/supabase.ts, only touching the
|
|
23
|
+
* file if the content actually changed (avoids needless dev-server reloads).
|
|
24
|
+
*
|
|
25
|
+
* Never throws — failures are logged and swallowed so this can safely run
|
|
26
|
+
* as a side effect of the migrations plugin without breaking server boot.
|
|
27
|
+
*/
|
|
28
|
+
export async function regenerateSupabaseTypes(
|
|
29
|
+
rootDir: string,
|
|
30
|
+
connectionString?: string
|
|
31
|
+
): Promise<void> {
|
|
32
|
+
const connStr = connectionString ?? process.env.DATABASE_URL
|
|
33
|
+
|
|
34
|
+
if (!connStr) {
|
|
35
|
+
console.warn(
|
|
36
|
+
'[typegen] Skipping Supabase type generation: no DATABASE_URL configured.'
|
|
37
|
+
)
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const targetPath = join(rootDir, 'shared/types/supabase.ts')
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const { stdout } = await execFileAsync(
|
|
45
|
+
resolveSupabaseBin(rootDir),
|
|
46
|
+
['gen', 'types', 'typescript', '--db-url', connStr, '--schema', 'public'],
|
|
47
|
+
{ maxBuffer: 1024 * 1024 * 16 }
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if (!stdout.trim()) {
|
|
51
|
+
console.warn('[typegen] Supabase CLI returned no output, skipping write.')
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const existing = existsSync(targetPath)
|
|
56
|
+
? readFileSync(targetPath, 'utf-8')
|
|
57
|
+
: null
|
|
58
|
+
|
|
59
|
+
if (existing === stdout) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
writeFileSync(targetPath, stdout, 'utf-8')
|
|
64
|
+
console.warn(`[typegen] Regenerated Supabase types at ${targetPath}`)
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.warn('[typegen] Failed to regenerate Supabase types:', error)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Nuxt infers runtimeConfig types from the actual merged value at build
|
|
2
|
+
// time, which narrows `plutoLayerSchemas` to whatever layer keys happen
|
|
3
|
+
// to be discovered in a given project (e.g. `{ "supabase-shop": string }`)
|
|
4
|
+
// instead of the general `Record<string, string>` declared in
|
|
5
|
+
// nuxt.config.ts. This augmentation pins the intended, stable shape.
|
|
6
|
+
// Lives under shared/ so it's picked up by the app, server, and shared
|
|
7
|
+
// TS projects alike (layer-root .d.ts files are only included by the
|
|
8
|
+
// shared project).
|
|
9
|
+
declare module '@nuxt/schema' {
|
|
10
|
+
interface RuntimeConfig {
|
|
11
|
+
plutoRootDir: string
|
|
12
|
+
plutoLayerSchemas: Record<string, string>
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {}
|
package/shared/types/supabase.ts
CHANGED
|
@@ -10,66 +10,24 @@ export type Database = {
|
|
|
10
10
|
// Allows to automatically instantiate createClient with right options
|
|
11
11
|
// instead of createClient<Database, { PostgrestVersion: 'XX' }>(URL, KEY)
|
|
12
12
|
__InternalSupabase: {
|
|
13
|
-
PostgrestVersion: "
|
|
13
|
+
PostgrestVersion: "14.5"
|
|
14
14
|
}
|
|
15
15
|
public: {
|
|
16
16
|
Tables: {
|
|
17
|
-
availability: {
|
|
18
|
-
Row: {
|
|
19
|
-
created_at: string
|
|
20
|
-
id: number
|
|
21
|
-
label: string | null
|
|
22
|
-
slug: string | null
|
|
23
|
-
}
|
|
24
|
-
Insert: {
|
|
25
|
-
created_at?: string
|
|
26
|
-
id?: number
|
|
27
|
-
label?: string | null
|
|
28
|
-
slug?: string | null
|
|
29
|
-
}
|
|
30
|
-
Update: {
|
|
31
|
-
created_at?: string
|
|
32
|
-
id?: number
|
|
33
|
-
label?: string | null
|
|
34
|
-
slug?: string | null
|
|
35
|
-
}
|
|
36
|
-
Relationships: []
|
|
37
|
-
}
|
|
38
|
-
categories: {
|
|
39
|
-
Row: {
|
|
40
|
-
description: string | null
|
|
41
|
-
id: number
|
|
42
|
-
label: string
|
|
43
|
-
slug: string
|
|
44
|
-
}
|
|
45
|
-
Insert: {
|
|
46
|
-
description?: string | null
|
|
47
|
-
id?: number
|
|
48
|
-
label: string
|
|
49
|
-
slug: string
|
|
50
|
-
}
|
|
51
|
-
Update: {
|
|
52
|
-
description?: string | null
|
|
53
|
-
id?: number
|
|
54
|
-
label?: string
|
|
55
|
-
slug?: string
|
|
56
|
-
}
|
|
57
|
-
Relationships: []
|
|
58
|
-
}
|
|
59
17
|
healthcheck: {
|
|
60
18
|
Row: {
|
|
61
|
-
config_name: Database["public"]["Enums"]["
|
|
62
|
-
config_value: string
|
|
19
|
+
config_name: Database["public"]["Enums"]["thealthcheck"]
|
|
20
|
+
config_value: string
|
|
63
21
|
id: number
|
|
64
22
|
}
|
|
65
23
|
Insert: {
|
|
66
|
-
config_name: Database["public"]["Enums"]["
|
|
67
|
-
config_value
|
|
24
|
+
config_name: Database["public"]["Enums"]["thealthcheck"]
|
|
25
|
+
config_value: string
|
|
68
26
|
id?: number
|
|
69
27
|
}
|
|
70
28
|
Update: {
|
|
71
|
-
config_name?: Database["public"]["Enums"]["
|
|
72
|
-
config_value?: string
|
|
29
|
+
config_name?: Database["public"]["Enums"]["thealthcheck"]
|
|
30
|
+
config_value?: string
|
|
73
31
|
id?: number
|
|
74
32
|
}
|
|
75
33
|
Relationships: []
|
|
@@ -79,22 +37,31 @@ export type Database = {
|
|
|
79
37
|
alt: string | null
|
|
80
38
|
created_at: string
|
|
81
39
|
id: number
|
|
40
|
+
mime_type: string | null
|
|
82
41
|
name: string | null
|
|
83
42
|
product_id: number | null
|
|
43
|
+
size: number | null
|
|
44
|
+
storage_path: string | null
|
|
84
45
|
}
|
|
85
46
|
Insert: {
|
|
86
47
|
alt?: string | null
|
|
87
48
|
created_at?: string
|
|
88
49
|
id?: number
|
|
50
|
+
mime_type?: string | null
|
|
89
51
|
name?: string | null
|
|
90
52
|
product_id?: number | null
|
|
53
|
+
size?: number | null
|
|
54
|
+
storage_path?: string | null
|
|
91
55
|
}
|
|
92
56
|
Update: {
|
|
93
57
|
alt?: string | null
|
|
94
58
|
created_at?: string
|
|
95
59
|
id?: number
|
|
60
|
+
mime_type?: string | null
|
|
96
61
|
name?: string | null
|
|
97
62
|
product_id?: number | null
|
|
63
|
+
size?: number | null
|
|
64
|
+
storage_path?: string | null
|
|
98
65
|
}
|
|
99
66
|
Relationships: [
|
|
100
67
|
{
|
|
@@ -106,52 +73,106 @@ export type Database = {
|
|
|
106
73
|
},
|
|
107
74
|
]
|
|
108
75
|
}
|
|
109
|
-
|
|
76
|
+
pluto_migrations: {
|
|
77
|
+
Row: {
|
|
78
|
+
applied_at: string
|
|
79
|
+
id: number
|
|
80
|
+
layer_name: string
|
|
81
|
+
}
|
|
82
|
+
Insert: {
|
|
83
|
+
applied_at?: string
|
|
84
|
+
id?: number
|
|
85
|
+
layer_name: string
|
|
86
|
+
}
|
|
87
|
+
Update: {
|
|
88
|
+
applied_at?: string
|
|
89
|
+
id?: number
|
|
90
|
+
layer_name?: string
|
|
91
|
+
}
|
|
92
|
+
Relationships: []
|
|
93
|
+
}
|
|
94
|
+
product_availability: {
|
|
110
95
|
Row: {
|
|
111
|
-
author_id: string
|
|
112
|
-
content: string | null
|
|
113
96
|
created_at: string
|
|
114
|
-
deleted_at: string | null
|
|
115
|
-
excerpt: string | null
|
|
116
97
|
id: number
|
|
117
|
-
|
|
118
|
-
published_at: string | null
|
|
98
|
+
label: string
|
|
119
99
|
slug: string
|
|
120
|
-
title: string | null
|
|
121
|
-
updated_at: string | null
|
|
122
100
|
}
|
|
123
101
|
Insert: {
|
|
124
|
-
author_id: string
|
|
125
|
-
content?: string | null
|
|
126
102
|
created_at?: string
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
id?: number
|
|
130
|
-
is_draft?: boolean | null
|
|
131
|
-
published_at?: string | null
|
|
103
|
+
id?: never
|
|
104
|
+
label: string
|
|
132
105
|
slug: string
|
|
133
|
-
title?: string | null
|
|
134
|
-
updated_at?: string | null
|
|
135
106
|
}
|
|
136
107
|
Update: {
|
|
137
|
-
author_id?: string
|
|
138
|
-
content?: string | null
|
|
139
108
|
created_at?: string
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
109
|
+
id?: never
|
|
110
|
+
label?: string
|
|
111
|
+
slug?: string
|
|
112
|
+
}
|
|
113
|
+
Relationships: []
|
|
114
|
+
}
|
|
115
|
+
product_category: {
|
|
116
|
+
Row: {
|
|
117
|
+
description: string | null
|
|
118
|
+
id: number
|
|
119
|
+
label: string
|
|
120
|
+
slug: string
|
|
121
|
+
}
|
|
122
|
+
Insert: {
|
|
123
|
+
description?: string | null
|
|
124
|
+
id?: never
|
|
125
|
+
label: string
|
|
126
|
+
slug: string
|
|
127
|
+
}
|
|
128
|
+
Update: {
|
|
129
|
+
description?: string | null
|
|
130
|
+
id?: never
|
|
131
|
+
label?: string
|
|
145
132
|
slug?: string
|
|
146
|
-
|
|
147
|
-
|
|
133
|
+
}
|
|
134
|
+
Relationships: []
|
|
135
|
+
}
|
|
136
|
+
product_media: {
|
|
137
|
+
Row: {
|
|
138
|
+
alt: string | null
|
|
139
|
+
created_at: string
|
|
140
|
+
id: number
|
|
141
|
+
mime_type: string | null
|
|
142
|
+
name: string
|
|
143
|
+
product_id: number | null
|
|
144
|
+
size: number | null
|
|
145
|
+
storage_path: string | null
|
|
146
|
+
url: string | null
|
|
147
|
+
}
|
|
148
|
+
Insert: {
|
|
149
|
+
alt?: string | null
|
|
150
|
+
created_at?: string
|
|
151
|
+
id?: never
|
|
152
|
+
mime_type?: string | null
|
|
153
|
+
name: string
|
|
154
|
+
product_id?: number | null
|
|
155
|
+
size?: number | null
|
|
156
|
+
storage_path?: string | null
|
|
157
|
+
url?: string | null
|
|
158
|
+
}
|
|
159
|
+
Update: {
|
|
160
|
+
alt?: string | null
|
|
161
|
+
created_at?: string
|
|
162
|
+
id?: never
|
|
163
|
+
mime_type?: string | null
|
|
164
|
+
name?: string
|
|
165
|
+
product_id?: number | null
|
|
166
|
+
size?: number | null
|
|
167
|
+
storage_path?: string | null
|
|
168
|
+
url?: string | null
|
|
148
169
|
}
|
|
149
170
|
Relationships: [
|
|
150
171
|
{
|
|
151
|
-
foreignKeyName: "
|
|
152
|
-
columns: ["
|
|
153
|
-
isOneToOne:
|
|
154
|
-
referencedRelation: "
|
|
172
|
+
foreignKeyName: "product_media_product_id_fkey"
|
|
173
|
+
columns: ["product_id"]
|
|
174
|
+
isOneToOne: false
|
|
175
|
+
referencedRelation: "products"
|
|
155
176
|
referencedColumns: ["id"]
|
|
156
177
|
},
|
|
157
178
|
]
|
|
@@ -172,9 +193,9 @@ export type Database = {
|
|
|
172
193
|
Insert: {
|
|
173
194
|
availability?: number | null
|
|
174
195
|
category?: number | null
|
|
175
|
-
created_at
|
|
196
|
+
created_at?: string
|
|
176
197
|
description?: string | null
|
|
177
|
-
id?:
|
|
198
|
+
id?: never
|
|
178
199
|
is_custom?: boolean
|
|
179
200
|
name: string
|
|
180
201
|
price: number
|
|
@@ -186,7 +207,7 @@ export type Database = {
|
|
|
186
207
|
category?: number | null
|
|
187
208
|
created_at?: string
|
|
188
209
|
description?: string | null
|
|
189
|
-
id?:
|
|
210
|
+
id?: never
|
|
190
211
|
is_custom?: boolean
|
|
191
212
|
name?: string
|
|
192
213
|
price?: number
|
|
@@ -198,53 +219,59 @@ export type Database = {
|
|
|
198
219
|
foreignKeyName: "products_availability_fkey"
|
|
199
220
|
columns: ["availability"]
|
|
200
221
|
isOneToOne: false
|
|
201
|
-
referencedRelation: "
|
|
222
|
+
referencedRelation: "product_availability"
|
|
202
223
|
referencedColumns: ["id"]
|
|
203
224
|
},
|
|
204
225
|
{
|
|
205
226
|
foreignKeyName: "products_category_fkey"
|
|
206
227
|
columns: ["category"]
|
|
207
228
|
isOneToOne: false
|
|
208
|
-
referencedRelation: "
|
|
229
|
+
referencedRelation: "product_category"
|
|
209
230
|
referencedColumns: ["id"]
|
|
210
231
|
},
|
|
211
232
|
]
|
|
212
233
|
}
|
|
213
234
|
profiles: {
|
|
214
235
|
Row: {
|
|
215
|
-
|
|
236
|
+
display_name: string | null
|
|
237
|
+
email: string | null
|
|
216
238
|
id: string
|
|
217
|
-
is_admin: boolean
|
|
218
|
-
|
|
239
|
+
is_admin: boolean
|
|
240
|
+
updated_at: string | null
|
|
241
|
+
username: string | null
|
|
219
242
|
}
|
|
220
243
|
Insert: {
|
|
221
|
-
|
|
244
|
+
display_name?: string | null
|
|
245
|
+
email?: string | null
|
|
222
246
|
id: string
|
|
223
|
-
is_admin?: boolean
|
|
224
|
-
|
|
247
|
+
is_admin?: boolean
|
|
248
|
+
updated_at?: string | null
|
|
249
|
+
username?: string | null
|
|
225
250
|
}
|
|
226
251
|
Update: {
|
|
227
|
-
|
|
252
|
+
display_name?: string | null
|
|
253
|
+
email?: string | null
|
|
228
254
|
id?: string
|
|
229
|
-
is_admin?: boolean
|
|
230
|
-
|
|
255
|
+
is_admin?: boolean
|
|
256
|
+
updated_at?: string | null
|
|
257
|
+
username?: string | null
|
|
231
258
|
}
|
|
232
259
|
Relationships: []
|
|
233
260
|
}
|
|
234
261
|
settings: {
|
|
235
262
|
Row: {
|
|
236
263
|
id: number
|
|
237
|
-
setting_name: Database["public"]["Enums"]["
|
|
264
|
+
setting_name: Database["public"]["Enums"]["tsettings"]
|
|
238
265
|
setting_value: string
|
|
239
266
|
}
|
|
240
267
|
Insert: {
|
|
241
268
|
id?: number
|
|
242
|
-
setting_name: Database["public"]["Enums"]["
|
|
269
|
+
setting_name: Database["public"]["Enums"]["tsettings"]
|
|
243
270
|
setting_value: string
|
|
244
271
|
}
|
|
245
272
|
Update: {
|
|
246
273
|
id?: number
|
|
247
|
-
setting_name?: Database["public"]["Enums"]["
|
|
274
|
+
setting_name?: Database["public"]["Enums"]["tsettings"]
|
|
248
275
|
setting_value?: string
|
|
249
276
|
}
|
|
250
277
|
Relationships: []
|
|
@@ -257,14 +284,8 @@ export type Database = {
|
|
|
257
284
|
[_ in never]: never
|
|
258
285
|
}
|
|
259
286
|
Enums: {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
Settings:
|
|
263
|
-
| "admin_email"
|
|
264
|
-
| "website_description"
|
|
265
|
-
| "website_title"
|
|
266
|
-
| "website_url"
|
|
267
|
-
| "users_can_register"
|
|
287
|
+
thealthcheck: "first_setup"
|
|
288
|
+
tsettings: "website_title" | "website_url" | "website_description"
|
|
268
289
|
}
|
|
269
290
|
CompositeTypes: {
|
|
270
291
|
[_ in never]: never
|
|
@@ -280,12 +301,12 @@ export type Tables<
|
|
|
280
301
|
DefaultSchemaTableNameOrOptions extends
|
|
281
302
|
| keyof (DefaultSchema["Tables"] & DefaultSchema["Views"])
|
|
282
303
|
| { schema: keyof DatabaseWithoutInternals },
|
|
283
|
-
TableName extends DefaultSchemaTableNameOrOptions extends {
|
|
304
|
+
TableName extends (DefaultSchemaTableNameOrOptions extends {
|
|
284
305
|
schema: keyof DatabaseWithoutInternals
|
|
285
306
|
}
|
|
286
307
|
? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] &
|
|
287
308
|
DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])
|
|
288
|
-
: never = never,
|
|
309
|
+
: never) = never,
|
|
289
310
|
> = DefaultSchemaTableNameOrOptions extends {
|
|
290
311
|
schema: keyof DatabaseWithoutInternals
|
|
291
312
|
}
|
|
@@ -309,11 +330,11 @@ export type TablesInsert<
|
|
|
309
330
|
DefaultSchemaTableNameOrOptions extends
|
|
310
331
|
| keyof DefaultSchema["Tables"]
|
|
311
332
|
| { schema: keyof DatabaseWithoutInternals },
|
|
312
|
-
TableName extends DefaultSchemaTableNameOrOptions extends {
|
|
333
|
+
TableName extends (DefaultSchemaTableNameOrOptions extends {
|
|
313
334
|
schema: keyof DatabaseWithoutInternals
|
|
314
335
|
}
|
|
315
336
|
? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"]
|
|
316
|
-
: never = never,
|
|
337
|
+
: never) = never,
|
|
317
338
|
> = DefaultSchemaTableNameOrOptions extends {
|
|
318
339
|
schema: keyof DatabaseWithoutInternals
|
|
319
340
|
}
|
|
@@ -334,11 +355,11 @@ export type TablesUpdate<
|
|
|
334
355
|
DefaultSchemaTableNameOrOptions extends
|
|
335
356
|
| keyof DefaultSchema["Tables"]
|
|
336
357
|
| { schema: keyof DatabaseWithoutInternals },
|
|
337
|
-
TableName extends DefaultSchemaTableNameOrOptions extends {
|
|
358
|
+
TableName extends (DefaultSchemaTableNameOrOptions extends {
|
|
338
359
|
schema: keyof DatabaseWithoutInternals
|
|
339
360
|
}
|
|
340
361
|
? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"]
|
|
341
|
-
: never = never,
|
|
362
|
+
: never) = never,
|
|
342
363
|
> = DefaultSchemaTableNameOrOptions extends {
|
|
343
364
|
schema: keyof DatabaseWithoutInternals
|
|
344
365
|
}
|
|
@@ -359,11 +380,11 @@ export type Enums<
|
|
|
359
380
|
DefaultSchemaEnumNameOrOptions extends
|
|
360
381
|
| keyof DefaultSchema["Enums"]
|
|
361
382
|
| { schema: keyof DatabaseWithoutInternals },
|
|
362
|
-
EnumName extends DefaultSchemaEnumNameOrOptions extends {
|
|
383
|
+
EnumName extends (DefaultSchemaEnumNameOrOptions extends {
|
|
363
384
|
schema: keyof DatabaseWithoutInternals
|
|
364
385
|
}
|
|
365
386
|
? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"]
|
|
366
|
-
: never = never,
|
|
387
|
+
: never) = never,
|
|
367
388
|
> = DefaultSchemaEnumNameOrOptions extends {
|
|
368
389
|
schema: keyof DatabaseWithoutInternals
|
|
369
390
|
}
|
|
@@ -376,11 +397,11 @@ export type CompositeTypes<
|
|
|
376
397
|
PublicCompositeTypeNameOrOptions extends
|
|
377
398
|
| keyof DefaultSchema["CompositeTypes"]
|
|
378
399
|
| { schema: keyof DatabaseWithoutInternals },
|
|
379
|
-
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
|
|
400
|
+
CompositeTypeName extends (PublicCompositeTypeNameOrOptions extends {
|
|
380
401
|
schema: keyof DatabaseWithoutInternals
|
|
381
402
|
}
|
|
382
403
|
? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"]
|
|
383
|
-
: never = never,
|
|
404
|
+
: never) = never,
|
|
384
405
|
> = PublicCompositeTypeNameOrOptions extends {
|
|
385
406
|
schema: keyof DatabaseWithoutInternals
|
|
386
407
|
}
|
|
@@ -392,15 +413,8 @@ export type CompositeTypes<
|
|
|
392
413
|
export const Constants = {
|
|
393
414
|
public: {
|
|
394
415
|
Enums: {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
Settings: [
|
|
398
|
-
"admin_email",
|
|
399
|
-
"website_description",
|
|
400
|
-
"website_title",
|
|
401
|
-
"website_url",
|
|
402
|
-
"users_can_register",
|
|
403
|
-
],
|
|
416
|
+
thealthcheck: ["first_setup"],
|
|
417
|
+
tsettings: ["website_title", "website_url", "website_description"],
|
|
404
418
|
},
|
|
405
419
|
},
|
|
406
420
|
} as const
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: nuxt
|
|
3
|
-
description: Nuxt full-stack Vue framework with SSR, auto-imports, and file-based routing. Use when working with Nuxt apps, server routes, useFetch, middleware, or hybrid rendering.
|
|
4
|
-
metadata:
|
|
5
|
-
author: Anthony Fu
|
|
6
|
-
version: "2026.1.28"
|
|
7
|
-
source: Generated from https://github.com/nuxt/nuxt, scripts located at https://github.com/antfu/skills
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
Nuxt is a full-stack Vue framework that provides server-side rendering, file-based routing, auto-imports, and a powerful module system. It uses Nitro as its server engine for universal deployment across Node.js, serverless, and edge platforms.
|
|
11
|
-
|
|
12
|
-
> The skill is based on Nuxt 3.x, generated at 2026-01-28.
|
|
13
|
-
|
|
14
|
-
## Core
|
|
15
|
-
|
|
16
|
-
| Topic | Description | Reference |
|
|
17
|
-
|-------|-------------|-----------|
|
|
18
|
-
| Directory Structure | Project folder structure, conventions, file organization | [core-directory-structure](references/core-directory-structure.md) |
|
|
19
|
-
| Configuration | nuxt.config.ts, app.config.ts, runtime config, environment variables | [core-config](references/core-config.md) |
|
|
20
|
-
| CLI Commands | Dev server, build, generate, preview, and utility commands | [core-cli](references/core-cli.md) |
|
|
21
|
-
| Routing | File-based routing, dynamic routes, navigation, middleware, layouts | [core-routing](references/core-routing.md) |
|
|
22
|
-
| Data Fetching | useFetch, useAsyncData, $fetch, caching, refresh | [core-data-fetching](references/core-data-fetching.md) |
|
|
23
|
-
| Modules | Creating and using Nuxt modules, Nuxt Kit utilities | [core-modules](references/core-modules.md) |
|
|
24
|
-
| Deployment | Platform-agnostic deployment with Nitro, Vercel, Netlify, Cloudflare | [core-deployment](references/core-deployment.md) |
|
|
25
|
-
|
|
26
|
-
## Features
|
|
27
|
-
|
|
28
|
-
| Topic | Description | Reference |
|
|
29
|
-
|-------|-------------|-----------|
|
|
30
|
-
| Composables Auto-imports | Vue APIs, Nuxt composables, custom composables, utilities | [features-composables](references/features-composables.md) |
|
|
31
|
-
| Components Auto-imports | Component naming, lazy loading, hydration strategies | [features-components-autoimport](references/features-components-autoimport.md) |
|
|
32
|
-
| Built-in Components | NuxtLink, NuxtPage, NuxtLayout, ClientOnly, and more | [features-components](references/features-components.md) |
|
|
33
|
-
| State Management | useState composable, SSR-friendly state, Pinia integration | [features-state](references/features-state.md) |
|
|
34
|
-
| Server Routes | API routes, server middleware, Nitro server engine | [features-server](references/features-server.md) |
|
|
35
|
-
|
|
36
|
-
## Rendering
|
|
37
|
-
|
|
38
|
-
| Topic | Description | Reference |
|
|
39
|
-
|-------|-------------|-----------|
|
|
40
|
-
| Rendering Modes | Universal (SSR), client-side (SPA), hybrid rendering, route rules | [rendering-modes](references/rendering-modes.md) |
|
|
41
|
-
|
|
42
|
-
## Best Practices
|
|
43
|
-
|
|
44
|
-
| Topic | Description | Reference |
|
|
45
|
-
|-------|-------------|-----------|
|
|
46
|
-
| Data Fetching Patterns | Efficient fetching, caching, parallel requests, error handling | [best-practices-data-fetching](references/best-practices-data-fetching.md) |
|
|
47
|
-
| SSR & Hydration | Avoiding context leaks, hydration mismatches, composable patterns | [best-practices-ssr](references/best-practices-ssr.md) |
|
|
48
|
-
|
|
49
|
-
## Advanced
|
|
50
|
-
|
|
51
|
-
| Topic | Description | Reference |
|
|
52
|
-
|-------|-------------|-----------|
|
|
53
|
-
| Layers | Extending applications with reusable layers | [advanced-layers](references/advanced-layers.md) |
|
|
54
|
-
| Lifecycle Hooks | Build-time, runtime, and server hooks | [advanced-hooks](references/advanced-hooks.md) |
|
|
55
|
-
| Module Authoring | Creating publishable Nuxt modules with Nuxt Kit | [advanced-module-authoring](references/advanced-module-authoring.md) |
|