@weft-js/create 0.1.1 → 0.1.3
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/README.md +393 -19
- package/bin/create-weft.mjs +62 -14
- package/package.json +26 -16
- package/scripts/tarballs.mjs +56 -6
- package/src/data.mjs +90 -18
- package/src/index.mjs +210 -51
- package/src/stack/pages.mjs +151 -0
- package/src/stack/schema.mjs +195 -0
- package/src/stack.mjs +102 -313
- package/src/templates.mjs +174 -0
- package/src/wizard.mjs +65 -16
- package/templates/admin/files/drizzle/.schema-hash +1 -0
- package/templates/admin/files/drizzle/0000_admin.sql +136 -0
- package/templates/admin/files/drizzle/meta/0000_snapshot.json +771 -0
- package/templates/admin/files/drizzle/meta/_journal.json +13 -0
- package/templates/admin/files/public/favicon.svg +1 -0
- package/templates/admin/files/src/auth.server.ts +24 -0
- package/templates/admin/files/src/components/AuthPage.tsx +33 -0
- package/templates/admin/files/src/components/Failed.tsx +19 -0
- package/templates/admin/files/src/components/Logo.tsx +16 -0
- package/templates/admin/files/src/components/OrderDetail.tsx +93 -0
- package/templates/admin/files/src/components/OrdersFilters.tsx +44 -0
- package/templates/admin/files/src/components/OrdersTable.tsx +144 -0
- package/templates/admin/files/src/components/Overview.tsx +113 -0
- package/templates/admin/files/src/components/StatusBadge.tsx +12 -0
- package/templates/admin/files/src/db/schema.ts +68 -0
- package/templates/admin/files/src/lib/orders.ts +60 -0
- package/templates/admin/files/src/routes/404.tsx +20 -0
- package/templates/admin/files/src/routes/_error.tsx +20 -0
- package/templates/admin/files/src/routes/_layout.tsx +6 -0
- package/templates/admin/files/src/routes/admin/_layout.tsx +89 -0
- package/templates/admin/files/src/routes/admin/index.tsx +45 -0
- package/templates/admin/files/src/routes/admin/nested/_layout.tsx +35 -0
- package/templates/admin/files/src/routes/admin/nested/index.tsx +77 -0
- package/templates/admin/files/src/routes/admin/orders/[id].tsx +24 -0
- package/templates/admin/files/src/routes/admin/orders/index.tsx +28 -0
- package/templates/admin/files/src/routes/admin/per-row.tsx +81 -0
- package/templates/admin/files/src/routes/admin/slow.tsx +74 -0
- package/templates/admin/files/src/routes/index.tsx +13 -0
- package/templates/admin/files/src/routes/login.tsx +53 -0
- package/templates/admin/files/src/routes/signup.tsx +60 -0
- package/templates/admin/files/src/server/orders.ts +193 -0
- package/templates/admin/files/src/server/reports.ts +92 -0
- package/templates/admin/files/src/server/session.ts +42 -0
- package/templates/admin/files/src/theme.css +43 -0
- package/templates/admin/files/weft.config.ts +31 -0
- package/templates/admin/template.json +22 -0
- package/templates/catalog/files/drizzle/.schema-hash +1 -0
- package/templates/catalog/files/drizzle/0000_catalog.sql +47 -0
- package/templates/catalog/files/drizzle/meta/0000_snapshot.json +263 -0
- package/templates/catalog/files/drizzle/meta/_journal.json +13 -0
- package/templates/catalog/files/public/favicon.svg +1 -0
- package/templates/catalog/files/seed.sql +13 -0
- package/templates/catalog/files/src/components/AddToCart.tsx +22 -0
- package/templates/catalog/files/src/components/Aisles.tsx +31 -0
- package/templates/catalog/files/src/components/CartLines.tsx +96 -0
- package/templates/catalog/files/src/components/CartLink.tsx +29 -0
- package/templates/catalog/files/src/components/Failed.tsx +19 -0
- package/templates/catalog/files/src/components/Featured.tsx +19 -0
- package/templates/catalog/files/src/components/Filters.tsx +40 -0
- package/templates/catalog/files/src/components/Logo.tsx +16 -0
- package/templates/catalog/files/src/components/ProductArt.tsx +42 -0
- package/templates/catalog/files/src/components/ProductCard.tsx +42 -0
- package/templates/catalog/files/src/components/ProductList.tsx +65 -0
- package/templates/catalog/files/src/components/Related.tsx +19 -0
- package/templates/catalog/files/src/components/SiteFooter.tsx +9 -0
- package/templates/catalog/files/src/components/SiteHeader.tsx +16 -0
- package/templates/catalog/files/src/db/schema.ts +53 -0
- package/templates/catalog/files/src/lib/catalog.ts +35 -0
- package/templates/catalog/files/src/routes/404.tsx +18 -0
- package/templates/catalog/files/src/routes/_error.tsx +18 -0
- package/templates/catalog/files/src/routes/_layout.tsx +14 -0
- package/templates/catalog/files/src/routes/c/[slug].tsx +53 -0
- package/templates/catalog/files/src/routes/cart.tsx +29 -0
- package/templates/catalog/files/src/routes/index.tsx +84 -0
- package/templates/catalog/files/src/routes/p/[slug].tsx +67 -0
- package/templates/catalog/files/src/server/cart.ts +125 -0
- package/templates/catalog/files/src/server/catalog.ts +107 -0
- package/templates/catalog/files/src/theme.css +159 -0
- package/templates/catalog/files/weft.config.ts +30 -0
- package/templates/catalog/template.json +20 -0
- package/templates/landing/files/.weft/plugins.lock.json +42 -0
- package/templates/landing/files/assets/fonts/LICENSE-figtree.txt +93 -0
- package/templates/landing/files/assets/fonts/figtree.woff2 +0 -0
- package/templates/landing/files/assets/hero.webp +0 -0
- package/templates/landing/files/drizzle/.schema-hash +1 -0
- package/templates/landing/files/drizzle/0000_landing.sql +6 -0
- package/templates/landing/files/drizzle/meta/0000_snapshot.json +60 -0
- package/templates/landing/files/drizzle/meta/_journal.json +13 -0
- package/templates/landing/files/public/favicon.svg +1 -0
- package/templates/landing/files/src/components/SiteFooter.tsx +24 -0
- package/templates/landing/files/src/components/SiteHeader.tsx +23 -0
- package/templates/landing/files/src/components/WaitlistForm.tsx +36 -0
- package/templates/landing/files/src/db/schema.ts +7 -0
- package/templates/landing/files/src/routes/404.tsx +24 -0
- package/templates/landing/files/src/routes/_error.tsx +24 -0
- package/templates/landing/files/src/routes/_layout.tsx +14 -0
- package/templates/landing/files/src/routes/index.tsx +130 -0
- package/templates/landing/files/src/routes/joined.tsx +30 -0
- package/templates/landing/files/src/routes/pricing.tsx +131 -0
- package/templates/landing/files/src/routes/privacy.tsx +56 -0
- package/templates/landing/files/src/server/waitlist.ts +13 -0
- package/templates/landing/files/src/theme.css +108 -0
- package/templates/landing/files/weft.config.ts +44 -0
- package/templates/landing/template.json +17 -0
- package/templates/todo/files/drizzle/.schema-hash +1 -0
- package/templates/todo/files/drizzle/0000_todo.sql +82 -0
- package/templates/todo/files/drizzle/meta/0000_snapshot.json +462 -0
- package/templates/todo/files/drizzle/meta/_journal.json +13 -0
- package/templates/todo/files/public/favicon.svg +1 -0
- package/templates/todo/files/src/components/AuthPage.tsx +33 -0
- package/templates/todo/files/src/components/Logo.tsx +14 -0
- package/templates/todo/files/src/components/NewTodo.tsx +27 -0
- package/templates/todo/files/src/components/TodoList.tsx +101 -0
- package/templates/todo/files/src/db/schema.ts +18 -0
- package/templates/todo/files/src/lib/views.ts +13 -0
- package/templates/todo/files/src/routes/404.tsx +20 -0
- package/templates/todo/files/src/routes/_error.tsx +20 -0
- package/templates/todo/files/src/routes/_layout.tsx +6 -0
- package/templates/todo/files/src/routes/index.tsx +13 -0
- package/templates/todo/files/src/routes/login.tsx +53 -0
- package/templates/todo/files/src/routes/signup.tsx +57 -0
- package/templates/todo/files/src/routes/todos.tsx +87 -0
- package/templates/todo/files/src/server/todos.ts +98 -0
- package/templates/todo/files/src/theme.css +71 -0
- package/templates/todo/files/weft.config.ts +30 -0
- package/templates/todo/template.json +18 -0
package/src/wizard.mjs
CHANGED
|
@@ -1,47 +1,93 @@
|
|
|
1
|
-
// The create-weft wizard
|
|
1
|
+
// The create-weft wizard: each choice is a list with the default selected. A flag answers its question,
|
|
2
2
|
// and with no terminal or with --yes every unanswered question takes its default, so agents and CI never see a prompt.
|
|
3
3
|
import { emitKeypressEvents } from 'node:readline'
|
|
4
4
|
import { CONFIGS, DB, LAYERS, RUNTIMES, UI } from './index.mjs'
|
|
5
5
|
|
|
6
6
|
const PMS = ['npm', 'pnpm', 'bun', 'deno', 'yarn']
|
|
7
7
|
const LABELS = {
|
|
8
|
-
warp: 'warp',
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
warp: 'warp',
|
|
9
|
+
headless: 'Headless (warp behaviour, your markup)',
|
|
10
|
+
tailwind: 'Tailwind',
|
|
11
|
+
none: 'None',
|
|
12
|
+
sqlite: 'SQLite',
|
|
13
|
+
postgres: 'Postgres',
|
|
14
|
+
mysql: 'MySQL',
|
|
15
|
+
drizzle: 'Drizzle',
|
|
16
|
+
prisma: 'Prisma',
|
|
17
|
+
native: 'Native (no ORM)',
|
|
18
|
+
node: 'Node',
|
|
19
|
+
bun: 'Bun',
|
|
20
|
+
deno: 'Deno',
|
|
21
|
+
npm: 'npm',
|
|
22
|
+
pnpm: 'pnpm',
|
|
23
|
+
yarn: 'Yarn',
|
|
24
|
+
ts: 'TypeScript',
|
|
25
|
+
json: 'JSON',
|
|
26
|
+
yaml: 'YAML',
|
|
11
27
|
}
|
|
12
|
-
const list = values => values.map(value => ({ value, label: LABELS[value] ?? value }))
|
|
13
|
-
const yesNo = [
|
|
28
|
+
const list = (values) => values.map((value) => ({ value, label: LABELS[value] ?? value }))
|
|
29
|
+
const yesNo = [
|
|
30
|
+
{ value: true, label: 'Yes' },
|
|
31
|
+
{ value: false, label: 'No' },
|
|
32
|
+
]
|
|
14
33
|
/** Whichever of Node, Bun and Deno is running this: a machine may have only that one. */
|
|
15
34
|
const host = process.versions.deno ? 'deno' : process.versions.bun ? 'bun' : 'node'
|
|
16
|
-
const packageManager =
|
|
35
|
+
const packageManager = (env) =>
|
|
36
|
+
host === 'node' ? (PMS.find((pm) => env.npm_config_user_agent?.startsWith(pm)) ?? 'npm') : host
|
|
17
37
|
|
|
18
38
|
/** In order. `when` skips a question that doesn't apply. `sideEffect` questions default to off with no terminal. */
|
|
19
|
-
export const questions = env => [
|
|
39
|
+
export const questions = (env) => [
|
|
20
40
|
{ key: 'ui', label: 'UI', default: 'warp', options: list(UI) },
|
|
21
41
|
{ key: 'db', label: 'Database', default: 'sqlite', options: list(DB) },
|
|
22
|
-
{
|
|
23
|
-
|
|
42
|
+
{
|
|
43
|
+
key: 'layer',
|
|
44
|
+
label: 'Data layer',
|
|
45
|
+
default: 'drizzle',
|
|
46
|
+
skip: 'drizzle',
|
|
47
|
+
options: list(LAYERS),
|
|
48
|
+
when: (a) => a.db !== 'none',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: 'auth',
|
|
52
|
+
label: 'Sign-in',
|
|
53
|
+
default: true,
|
|
54
|
+
options: [
|
|
55
|
+
{ value: true, label: 'Better Auth' },
|
|
56
|
+
{ value: 'custom', label: 'Bring your own' },
|
|
57
|
+
{ value: false, label: 'None' },
|
|
58
|
+
],
|
|
59
|
+
when: (a) => a.db !== 'none',
|
|
60
|
+
},
|
|
24
61
|
{ key: 'runtime', label: 'Runtime', default: host, options: list(RUNTIMES) },
|
|
25
62
|
{ key: 'config', label: 'Config file', default: 'ts', options: list(CONFIGS) },
|
|
26
63
|
{ key: 'pm', label: 'Package manager', default: packageManager(env), options: list(PMS) },
|
|
27
64
|
{ key: 'git', label: 'Start a git repository', default: true, options: yesNo, sideEffect: true },
|
|
28
|
-
{
|
|
65
|
+
{
|
|
66
|
+
key: 'install',
|
|
67
|
+
label: 'Install dependencies',
|
|
68
|
+
default: true,
|
|
69
|
+
options: yesNo,
|
|
70
|
+
sideEffect: true,
|
|
71
|
+
},
|
|
29
72
|
]
|
|
30
73
|
|
|
31
74
|
/** One list on a terminal: arrows move, Enter picks. Resolves with the option's value. */
|
|
32
75
|
export function select({ label, options, default: initial }, { input, output }) {
|
|
33
|
-
let at = Math.max(
|
|
34
|
-
|
|
76
|
+
let at = Math.max(
|
|
77
|
+
0,
|
|
78
|
+
options.findIndex((o) => o.value === initial),
|
|
79
|
+
)
|
|
80
|
+
const draw = (first) => {
|
|
35
81
|
if (!first) output.write(`\x1b[${options.length}A`)
|
|
36
82
|
options.forEach((o, i) => output.write(`\x1b[2K${i === at ? '› ' : ' '}${o.label}\n`))
|
|
37
83
|
}
|
|
38
|
-
return new Promise(ok => {
|
|
84
|
+
return new Promise((ok) => {
|
|
39
85
|
output.write(`${label}\n`)
|
|
40
86
|
draw(true)
|
|
41
87
|
emitKeypressEvents(input)
|
|
42
88
|
input.setRawMode?.(true)
|
|
43
89
|
input.resume()
|
|
44
|
-
const done = value => {
|
|
90
|
+
const done = (value) => {
|
|
45
91
|
input.off('keypress', onKey)
|
|
46
92
|
input.setRawMode?.(false)
|
|
47
93
|
input.pause()
|
|
@@ -63,7 +109,10 @@ export function select({ label, options, default: initial }, { input, output })
|
|
|
63
109
|
}
|
|
64
110
|
|
|
65
111
|
/** Every choice, from flags, then the terminal if there is one, then the defaults. */
|
|
66
|
-
export async function resolveChoices(
|
|
112
|
+
export async function resolveChoices(
|
|
113
|
+
given,
|
|
114
|
+
{ interactive, yes = false, env = process.env, io } = {},
|
|
115
|
+
) {
|
|
67
116
|
const choices = { ...given }
|
|
68
117
|
for (const q of questions(env)) {
|
|
69
118
|
if (q.when && !q.when(choices)) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4fc125bb55cd53a8
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "categories" (
|
|
2
|
+
"id" serial PRIMARY KEY NOT NULL,
|
|
3
|
+
"slug" text NOT NULL,
|
|
4
|
+
"name" text NOT NULL,
|
|
5
|
+
CONSTRAINT "categories_slug_unique" UNIQUE("slug")
|
|
6
|
+
);
|
|
7
|
+
--> statement-breakpoint
|
|
8
|
+
CREATE TABLE IF NOT EXISTS "customers" (
|
|
9
|
+
"id" serial PRIMARY KEY NOT NULL,
|
|
10
|
+
"name" text NOT NULL,
|
|
11
|
+
"email" text NOT NULL,
|
|
12
|
+
"city" text NOT NULL,
|
|
13
|
+
CONSTRAINT "customers_email_unique" UNIQUE("email")
|
|
14
|
+
);
|
|
15
|
+
--> statement-breakpoint
|
|
16
|
+
CREATE TABLE IF NOT EXISTS "order_items" (
|
|
17
|
+
"id" serial PRIMARY KEY NOT NULL,
|
|
18
|
+
"order_id" integer NOT NULL,
|
|
19
|
+
"product_id" integer NOT NULL,
|
|
20
|
+
"quantity" integer NOT NULL,
|
|
21
|
+
"price_cents" integer NOT NULL
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
CREATE TABLE IF NOT EXISTS "orders" (
|
|
25
|
+
"id" serial PRIMARY KEY NOT NULL,
|
|
26
|
+
"customer_id" integer NOT NULL,
|
|
27
|
+
"status" text NOT NULL,
|
|
28
|
+
"total_cents" integer NOT NULL,
|
|
29
|
+
"created_at" timestamp with time zone NOT NULL
|
|
30
|
+
);
|
|
31
|
+
--> statement-breakpoint
|
|
32
|
+
CREATE TABLE IF NOT EXISTS "products" (
|
|
33
|
+
"id" serial PRIMARY KEY NOT NULL,
|
|
34
|
+
"slug" text NOT NULL,
|
|
35
|
+
"name" text NOT NULL,
|
|
36
|
+
"description" text NOT NULL,
|
|
37
|
+
"category_id" integer NOT NULL,
|
|
38
|
+
"price_cents" integer NOT NULL,
|
|
39
|
+
"stock" integer NOT NULL,
|
|
40
|
+
"featured" boolean DEFAULT false NOT NULL,
|
|
41
|
+
CONSTRAINT "products_slug_unique" UNIQUE("slug")
|
|
42
|
+
);
|
|
43
|
+
--> statement-breakpoint
|
|
44
|
+
CREATE TABLE IF NOT EXISTS "account" (
|
|
45
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
46
|
+
"accountId" text NOT NULL,
|
|
47
|
+
"providerId" text NOT NULL,
|
|
48
|
+
"userId" text NOT NULL,
|
|
49
|
+
"accessToken" text,
|
|
50
|
+
"refreshToken" text,
|
|
51
|
+
"idToken" text,
|
|
52
|
+
"accessTokenExpiresAt" timestamp with time zone,
|
|
53
|
+
"refreshTokenExpiresAt" timestamp with time zone,
|
|
54
|
+
"scope" text,
|
|
55
|
+
"password" text,
|
|
56
|
+
"createdAt" timestamp with time zone NOT NULL,
|
|
57
|
+
"updatedAt" timestamp with time zone NOT NULL
|
|
58
|
+
);
|
|
59
|
+
--> statement-breakpoint
|
|
60
|
+
CREATE TABLE IF NOT EXISTS "jwks" (
|
|
61
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
62
|
+
"publicKey" text NOT NULL,
|
|
63
|
+
"privateKey" text NOT NULL,
|
|
64
|
+
"createdAt" timestamp with time zone NOT NULL,
|
|
65
|
+
"expiresAt" timestamp with time zone,
|
|
66
|
+
"alg" text,
|
|
67
|
+
"crv" text
|
|
68
|
+
);
|
|
69
|
+
--> statement-breakpoint
|
|
70
|
+
CREATE TABLE IF NOT EXISTS "session" (
|
|
71
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
72
|
+
"expiresAt" timestamp with time zone NOT NULL,
|
|
73
|
+
"token" text NOT NULL,
|
|
74
|
+
"createdAt" timestamp with time zone NOT NULL,
|
|
75
|
+
"updatedAt" timestamp with time zone NOT NULL,
|
|
76
|
+
"ipAddress" text,
|
|
77
|
+
"userAgent" text,
|
|
78
|
+
"userId" text NOT NULL,
|
|
79
|
+
CONSTRAINT "session_token_unique" UNIQUE("token")
|
|
80
|
+
);
|
|
81
|
+
--> statement-breakpoint
|
|
82
|
+
CREATE TABLE IF NOT EXISTS "user" (
|
|
83
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
84
|
+
"name" text NOT NULL,
|
|
85
|
+
"email" text NOT NULL,
|
|
86
|
+
"emailVerified" boolean NOT NULL,
|
|
87
|
+
"image" text,
|
|
88
|
+
"createdAt" timestamp with time zone NOT NULL,
|
|
89
|
+
"updatedAt" timestamp with time zone NOT NULL,
|
|
90
|
+
CONSTRAINT "user_email_unique" UNIQUE("email")
|
|
91
|
+
);
|
|
92
|
+
--> statement-breakpoint
|
|
93
|
+
CREATE TABLE IF NOT EXISTS "verification" (
|
|
94
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
95
|
+
"identifier" text NOT NULL,
|
|
96
|
+
"value" text NOT NULL,
|
|
97
|
+
"expiresAt" timestamp with time zone NOT NULL,
|
|
98
|
+
"createdAt" timestamp with time zone,
|
|
99
|
+
"updatedAt" timestamp with time zone
|
|
100
|
+
);
|
|
101
|
+
--> statement-breakpoint
|
|
102
|
+
DO $$ BEGIN
|
|
103
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"order_items"'::regclass AND c.contype = 'f' AND a.attname = 'order_id') THEN
|
|
104
|
+
ALTER TABLE "order_items" ADD CONSTRAINT "order_items_order_id_orders_id_fk" FOREIGN KEY ("order_id") REFERENCES "public"."orders"("id") ON DELETE cascade ON UPDATE no action;
|
|
105
|
+
END IF;
|
|
106
|
+
END $$;--> statement-breakpoint
|
|
107
|
+
DO $$ BEGIN
|
|
108
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"order_items"'::regclass AND c.contype = 'f' AND a.attname = 'product_id') THEN
|
|
109
|
+
ALTER TABLE "order_items" ADD CONSTRAINT "order_items_product_id_products_id_fk" FOREIGN KEY ("product_id") REFERENCES "public"."products"("id") ON DELETE no action ON UPDATE no action;
|
|
110
|
+
END IF;
|
|
111
|
+
END $$;--> statement-breakpoint
|
|
112
|
+
DO $$ BEGIN
|
|
113
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"orders"'::regclass AND c.contype = 'f' AND a.attname = 'customer_id') THEN
|
|
114
|
+
ALTER TABLE "orders" ADD CONSTRAINT "orders_customer_id_customers_id_fk" FOREIGN KEY ("customer_id") REFERENCES "public"."customers"("id") ON DELETE no action ON UPDATE no action;
|
|
115
|
+
END IF;
|
|
116
|
+
END $$;--> statement-breakpoint
|
|
117
|
+
DO $$ BEGIN
|
|
118
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"products"'::regclass AND c.contype = 'f' AND a.attname = 'category_id') THEN
|
|
119
|
+
ALTER TABLE "products" ADD CONSTRAINT "products_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE no action ON UPDATE no action;
|
|
120
|
+
END IF;
|
|
121
|
+
END $$;--> statement-breakpoint
|
|
122
|
+
DO $$ BEGIN
|
|
123
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"account"'::regclass AND c.contype = 'f' AND a.attname = 'userId') THEN
|
|
124
|
+
ALTER TABLE "account" ADD CONSTRAINT "account_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
|
125
|
+
END IF;
|
|
126
|
+
END $$;--> statement-breakpoint
|
|
127
|
+
DO $$ BEGIN
|
|
128
|
+
IF NOT EXISTS (SELECT 1 FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = c.conkey[1] WHERE c.conrelid = '"session"'::regclass AND c.contype = 'f' AND a.attname = 'userId') THEN
|
|
129
|
+
ALTER TABLE "session" ADD CONSTRAINT "session_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
|
|
130
|
+
END IF;
|
|
131
|
+
END $$;--> statement-breakpoint
|
|
132
|
+
CREATE INDEX IF NOT EXISTS "order_items_order" ON "order_items" USING btree ("order_id");--> statement-breakpoint
|
|
133
|
+
CREATE INDEX IF NOT EXISTS "orders_created" ON "orders" USING btree ("created_at" desc,"id" desc);--> statement-breakpoint
|
|
134
|
+
CREATE INDEX IF NOT EXISTS "orders_status" ON "orders" USING btree ("status","created_at" desc);--> statement-breakpoint
|
|
135
|
+
CREATE INDEX IF NOT EXISTS "orders_customer" ON "orders" USING btree ("customer_id");--> statement-breakpoint
|
|
136
|
+
CREATE INDEX IF NOT EXISTS "products_category" ON "products" USING btree ("category_id","price_cents","id");
|