Skip to content

Commit efd78dc

Browse files
committed
feat: cli 1.20 and CS
1 parent 1afc7a8 commit efd78dc

20 files changed

+198
-169
lines changed

Makefile

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,15 @@ serve: website/.env ## Serve the application
7575

7676
.PHONY: build-cli
7777
build-cli: ## Build CLI
78-
@cd $(CLI_DIR) && bun build --bundle src/index.ts --outfile atw-cli.js --target=bun
79-
@cd $(CLI_DIR) && bun shim.ts
80-
@cd $(CLI_DIR) && bun build --compile --minify atw-cli.js --outfile atw-cli
81-
@cd $(CLI_DIR) && rm atw-cli.js
78+
@cd $(CLI_DIR) && bun build --compile --minify src/index --outfile atw-cli
79+
@cd $(CLI_DIR) && rm -f .*.bun-build
8280

8381
.PHONY: build-all-cli
8482
build-all-cli:
85-
@cd $(CLI_DIR) && bun build --bundle src/index.ts --outfile atw-cli.js --target=bun
86-
@cd $(CLI_DIR) && bun shim.ts
8783
@cd $(CLI_DIR) && for target in bun-linux-x64 bun-linux-arm64 bun-windows-x64 bun-darwin-x64 bun-darwin-arm64; do \
88-
bun build --compile --minify atw-cli.js --outfile atw-cli-$$target --target=$$target; \
84+
bun build --compile --minify src/index --outfile atw-cli-$$target --target=$$target; \
8985
done
90-
@cd $(CLI_DIR) && rm atw-cli.js
86+
@cd $(CLI_DIR) && rm -f .*.bun-build
9187

9288
.PHONY: deploy-sync-permissions
9389
deploy-sync-permissions:

atw-cli/bun.lock

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77
"@inkjs/ui": "^2.0.0",
88
"@rocicorp/zero": "^0.16.2025022602",
99
"commander": "^13.1.0",
10-
"ink": "^5.1.1",
10+
"ink": "^5.2.0",
1111
"ink-link": "^4.1.0",
1212
"picocolors": "^1.1.1",
13+
"qrcode-terminal": "^0.12.0",
1314
"react": "^18",
1415
"react-devtools-core": "^6.1.1",
1516
},
1617
"devDependencies": {
1718
"@types/bun": "latest",
19+
"@types/qrcode-terminal": "^0.12.2",
1820
"@types/react": "^19.0.10",
1921
},
2022
"peerDependencies": {
@@ -187,15 +189,17 @@
187189

188190
"@rocicorp/resolver": ["@rocicorp/resolver@1.0.2", "", {}, "sha512-TfjMTQp9cNNqNtHFfa+XHEGdA7NnmDRu+ZJH4YF3dso0Xk/b9DMhg/sl+b6CR4ThFZArXXDsG1j8Mwl34wcOZQ=="],
189191

190-
"@rocicorp/zero": ["@rocicorp/zero@0.16.2025022800", "", { "dependencies": { "@badrap/valita": "0.3.11", "@databases/escape-identifier": "^1.0.3", "@databases/sql": "^3.3.0", "@drdgvhbh/postgres-error-codes": "^0.0.6", "@fastify/cors": "^10.0.0", "@fastify/websocket": "^11.0.0", "@google-cloud/precise-date": "^4.0.0", "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-trace-otlp-http": "^0.56.0", "@opentelemetry/sdk-node": "^0.56.0", "@opentelemetry/sdk-trace-node": "^1.29.0", "@postgresql-typed/oids": "^0.2.0", "@rocicorp/lock": "^1.0.4", "@rocicorp/logger": "^5.3.0", "@rocicorp/resolver": "^1.0.2", "@rocicorp/zero-sqlite3": "^1.0.4", "chalk": "^5.3.0", "chalk-template": "^1.1.0", "chokidar": "^4.0.1", "command-line-args": "^6.0.1", "command-line-usage": "^7.0.3", "compare-utf8": "^0.1.1", "defu": "^6.1.4", "dotenv": "^16.4.5", "eventemitter3": "^5.0.1", "fastify": "^5.0.0", "jose": "^5.9.3", "js-xxhash": "^4.0.0", "json-custom-numbers": "^3.1.1", "kasi": "^1.1.0", "nanoid": "^5.0.8", "pg": "^8.11.3", "pg-format": "npm:pg-format-fix@^1.0.5", "pg-logical-replication": "^2.0.7", "pg-protocol": "^1.7.0", "postgres": "^3.4.4", "postgres-array": "^3.0.2", "semver": "^7.5.4", "tsx": "^4.19.1", "url-pattern": "^1.0.3", "ws": "^8.18.0" }, "bin": { "zero-cache": "out/zero/src/cli.js", "zero-cache-dev": "out/zero/src/zero-cache-dev.js", "zero-build-schema": "out/zero/src/build-schema.js", "zero-deploy-permissions": "out/zero/src/deploy-permissions.js" } }, "sha512-+8Zgh8hbzTh0nB3C47M/zR8iAT6M49T4fJzSjJ3qXS6a2j7AvgljijWMFhMPBXG/jBtIsZbIkGk1O2Wf0PwDeg=="],
192+
"@rocicorp/zero": ["@rocicorp/zero@0.16.2025031000", "", { "dependencies": { "@badrap/valita": "0.3.11", "@databases/escape-identifier": "^1.0.3", "@databases/sql": "^3.3.0", "@drdgvhbh/postgres-error-codes": "^0.0.6", "@fastify/cors": "^10.0.0", "@fastify/websocket": "^11.0.0", "@google-cloud/precise-date": "^4.0.0", "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-trace-otlp-http": "^0.56.0", "@opentelemetry/sdk-node": "^0.56.0", "@opentelemetry/sdk-trace-node": "^1.29.0", "@postgresql-typed/oids": "^0.2.0", "@rocicorp/lock": "^1.0.4", "@rocicorp/logger": "^5.3.0", "@rocicorp/resolver": "^1.0.2", "@rocicorp/zero-sqlite3": "^1.0.4", "chalk": "^5.3.0", "chalk-template": "^1.1.0", "chokidar": "^4.0.1", "command-line-args": "^6.0.1", "command-line-usage": "^7.0.3", "compare-utf8": "^0.1.1", "defu": "^6.1.4", "dotenv": "^16.4.5", "eventemitter3": "^5.0.1", "fastify": "^5.0.0", "jose": "^5.9.3", "js-xxhash": "^4.0.0", "json-custom-numbers": "^3.1.1", "kasi": "^1.1.0", "nanoid": "^5.0.8", "pg": "^8.11.3", "pg-format": "npm:pg-format-fix@^1.0.5", "pg-logical-replication": "^2.0.7", "pg-protocol": "^1.7.0", "postgres": "^3.4.4", "postgres-array": "^3.0.2", "semver": "^7.5.4", "tsx": "^4.19.1", "url-pattern": "^1.0.3", "ws": "^8.18.0" }, "bin": { "zero-cache": "out/zero/src/cli.js", "zero-cache-dev": "out/zero/src/zero-cache-dev.js", "zero-build-schema": "out/zero/src/build-schema.js", "zero-deploy-permissions": "out/zero/src/deploy-permissions.js" } }, "sha512-+23jiWm0tvZA9hE1naGI9UDvMTVBa93UitestsyBCoOyNmHgMXIi78yJWbgSoIsOgQs1UXXxbbivEt1vleuPPg=="],
191193

192194
"@rocicorp/zero-sqlite3": ["@rocicorp/zero-sqlite3@1.0.4", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" }, "bin": { "zero-sqlite3": "shell.ps1" } }, "sha512-bm+VUdF4CnKVjUj/dSCmVu0hjcyXaF/nKkw2rNhZUjGeBOMRy/hh8z/32h311es4dxCVvcZ3+QHQHMxF2YG5Kw=="],
193195

194-
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
196+
"@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="],
195197

196198
"@types/node": ["@types/node@22.13.10", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw=="],
197199

198-
"@types/react": ["@types/react@19.0.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g=="],
200+
"@types/qrcode-terminal": ["@types/qrcode-terminal@0.12.2", "", {}, "sha512-v+RcIEJ+Uhd6ygSQ0u5YYY7ZM+la7GgPbs0V/7l/kFs2uO4S8BcIUEMoP7za4DNIqNnUD5npf0A/7kBhrCKG5Q=="],
201+
202+
"@types/react": ["@types/react@19.0.11", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-vrdxRZfo9ALXth6yPfV16PYTLZwsUWhVjjC+DkfE5t1suNSbBrWC9YqSuuxJZ8Ps6z1o2ycRpIqzZJIgklq4Tw=="],
199203

200204
"@types/shimmer": ["@types/shimmer@1.2.0", "", {}, "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg=="],
201205

@@ -233,7 +237,7 @@
233237

234238
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
235239

236-
"bun-types": ["bun-types@1.2.4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
240+
"bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="],
237241

238242
"chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
239243

@@ -485,6 +489,8 @@
485489

486490
"pump": ["pump@3.0.2", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw=="],
487491

492+
"qrcode-terminal": ["qrcode-terminal@0.12.0", "", { "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="],
493+
488494
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
489495

490496
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],

atw-cli/package.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22
"name": "atw-cli",
33
"module": "index.ts",
44
"type": "module",
5-
"version": "1.1.0",
5+
"version": "1.2.0",
66
"private": true,
77
"devDependencies": {
88
"@types/bun": "latest",
9-
"@types/react": "^19.0.10"
9+
"@types/qrcode-terminal": "^0.12.2",
10+
"@types/react": "^19.0.11"
1011
},
1112
"peerDependencies": {
12-
"typescript": "^5"
13+
"typescript": "^5.8.2"
1314
},
1415
"dependencies": {
1516
"@inkjs/ui": "^2.0.0",
17+
"@rocicorp/zero": "^0.16.2025031000",
1618
"commander": "^13.1.0",
17-
"ink": "^5.1.1",
19+
"ink": "^5.2.0",
1820
"ink-link": "^4.1.0",
19-
"@rocicorp/zero": "^0.16.2025022602",
2021
"picocolors": "^1.1.1",
21-
"react": "^18",
22+
"qrcode-terminal": "^0.12.0",
23+
"react": "^18.3.1",
2224
"react-devtools-core": "^6.1.1"
2325
}
2426
}

atw-cli/shim.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

atw-cli/src/actions/register.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export type Event = {
55
slug: string
66
name: string
77
startDate: number
8+
tagline: string
89
shortLocation: string|null
910
}
1011

atw-cli/src/commands/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { createJarvis } from "../core/create-jarvis";
12
import { createRegisterCommand } from "./register";
23

4+
const jarvis = createJarvis("Plopix");
35
export const commands = [
4-
createRegisterCommand()
6+
createRegisterCommand({ tBot:jarvis }),
57
]
68

atw-cli/src/commands/register.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ import { RegisterJourney } from "../ui/journeys/register";
44
import pc from "picocolors";
55
import { logo } from "..";
66
import { AppLayout } from "../ui/app-layout";
7+
import type { TalkativeBot } from "../contracts/talkative-bot-interface";
78

8-
export const createRegisterCommand = (): Command => {
9+
type Deps = {
10+
tBot: TalkativeBot
11+
}
12+
export const createRegisterCommand = (deps:Deps): Command => {
913
const command = new Command("register")
1014
.description("Register to an event.")
1115
.action(async () => {
1216
console.log(pc.dim(logo));
17+
deps.tBot.say("We can't wait to see you soon! Select one of the events below to register.");
1318
const { waitUntilExit, unmount } = render(
1419
<AppLayout title="Register to an event!">
15-
<RegisterJourney unmount={() => unmount()} />
20+
<RegisterJourney unmount={() => unmount()} deps={deps} />
1621
</AppLayout>,
1722
{
1823
exitOnCtrlC: true,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type TalkativeBot = {
2+
say: (text: string) => Promise<void>;
3+
shutup: () => Promise<void>;
4+
isSpeaking: () => boolean;
5+
}

atw-cli/src/core/create-jarvis.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { TalkativeBot } from "../contracts/talkative-bot-interface";
2+
3+
export const createJarvis = (voice: string): TalkativeBot => {
4+
let currentOuput: ReturnType<typeof Bun.spawn> | null = null;
5+
6+
const shutup = async () => {
7+
if (currentOuput) {
8+
currentOuput.kill('SIGKILL');
9+
await currentOuput.exited;
10+
}
11+
currentOuput = null;
12+
}
13+
return {
14+
say: async (text: string) => {
15+
try {
16+
await shutup();
17+
currentOuput = Bun.spawn(['say', '-v', voice, text]);
18+
await currentOuput.exited;
19+
} catch (e) {
20+
currentOuput = null;
21+
}
22+
},
23+
shutup,
24+
isSpeaking: () => {
25+
return currentOuput !== null;
26+
}
27+
}
28+
29+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import qrcode from 'qrcode-terminal';
2+
3+
export const generateQrCode = async (input: string, small = true) => new Promise<string>((resolve, reject) => {
4+
qrcode.generate(input, { small }, (qrcode) => {
5+
if (qrcode) {
6+
resolve(qrcode);
7+
} else {
8+
reject(new Error("Failed to generate QR code"));
9+
}
10+
});
11+
});

atw-cli/src/ui/journeys/register/core.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export const reducer = (state: State, action: Action): State => {
4646
email: action.email
4747
}
4848
case 'HANDLE_API_RESULTS':
49-
console.log({action})
5049
return {
5150
...state,
5251
isSubmitting: false,

atw-cli/src/ui/journeys/register/index.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Box, Text } from "ink"
2-
import { useReducer } from "react"
1+
import { Box, Newline, Text } from "ink"
2+
import { useEffect, useReducer, useState } from "react"
33
import { Select } from "../../components/select"
44
import { Badge, EmailInput, Spinner } from '@inkjs/ui';
55

@@ -10,17 +10,29 @@ import { schema } from "@lib/zero-sync/schema";
1010
import { colors } from "../../theme";
1111
import { initialState, reducer, toDate } from "./core";
1212
import { ATW_BASEURL } from "../../../config";
13+
import { generateQrCode } from "../../../helpers/generate-qr-code";
14+
import type { TalkativeBot } from "../../../contracts/talkative-bot-interface";
15+
1316

1417
type RegisterJourneyProps = {
1518
unmount: () => void
19+
deps: {
20+
tBot: TalkativeBot
21+
}
1622
}
1723

18-
export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => {
24+
export const RegisterJourney = ({ unmount, deps: { tBot } }: RegisterJourneyProps) => {
1925
const z = useZero<typeof schema>();
2026
const [events] = useQuery(z.query.events.where('startDate', '>', (new Date()).getTime()).orderBy('startDate', 'desc').limit(10))
2127
const [state, dispatch] = useReducer(reducer, initialState);
2228
const { event, hasSucceeded, isSubmitting, error } = state
2329
const isLoading = events.length <= 0
30+
const [qr, setQr] = useState<string | null>(null)
31+
useEffect(() => {
32+
if (!event) return
33+
generateQrCode(`${ATW_BASEURL}/${event.slug}`).then(setQr).catch();
34+
}, [event])
35+
2436
return <Box flexDirection="column" padding={1}>
2537
{isLoading && <Spinner type='aesthetic' label="Loading events..." />}
2638
{!event && !isLoading && <Text>Here is the list of the upcomping events:</Text>}
@@ -39,8 +51,11 @@ export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => {
3951
</Box>
4052
</Box>
4153
}
42-
})} onSelect={(event) => {
54+
})} onSelect={async (event) => {
4355
dispatch({ type: 'SELECT_EVENT', event })
56+
await tBot.say(`You selected ${event.name}. It's happening on ${toDate(event.startDate)} at ${event.shortLocation}.`);
57+
await tBot.say(event.tagline.split(/\.|\!/).slice(1).join('.'));
58+
await tBot.say(`Please enter your email now.`);
4459
}} />}
4560

4661
{event && <Box flexDirection="column" padding={1} gap={1}>
@@ -50,6 +65,10 @@ export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => {
5065
<Link url={`${ATW_BASEURL}/${event.slug}`}>
5166
<Text color={colors.mainBlue}>{`${ATW_BASEURL}/${event.slug}`}</Text>
5267
</Link>
68+
<Newline />
69+
<Text>{event.tagline}</Text>
70+
<Newline />
71+
<Text color={colors.mainPurple}>{qr}</Text>
5372
</Box>
5473

5574
{hasSucceeded === null && !isSubmitting && <>
@@ -61,6 +80,12 @@ export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => {
6180
dispatch({ type: 'SET_EMAIL', email })
6281
const results = await registerAction(email, event.id)
6382
dispatch({ type: 'HANDLE_API_RESULTS', results })
83+
if (results.success === true) {
84+
await tBot.say(`Yeah! You are all set! See you there!`);
85+
}
86+
if (results.success === false) {
87+
await tBot.say(`Oh no! Something went wrong! ${error}`);
88+
}
6489
setTimeout(() => {
6590
unmount()
6691
}, 2000)
@@ -72,8 +97,10 @@ export const RegisterJourney = ({ unmount }: RegisterJourneyProps) => {
7297
<Badge color="yellow">Registrating...</Badge><Text dimColor>{state.email}</Text><Spinner type='bouncingBall' label="Hang tight!" />
7398
</Box>}
7499
{hasSucceeded === true && <Box flexDirection="row" gap={2} padding={2}>
75-
<Badge color="green">Registration Successful!</Badge><Spinner type='fingerDance' label="See you there" /><Text color={colors.mainOrange}>{state.email}</Text>
100+
<Badge color="green">Registration Successful!</Badge>
101+
<Spinner type='fingerDance' label="See you there" />
76102
</Box>}
103+
77104
{hasSucceeded === false && <Box flexDirection="row" gap={2} padding={2}>
78105
<Badge color="red">Registration Failed!</Badge><Spinner type='monkey' label={error || 'Something went wrong!'} />
79106
</Box>}

lib/db/schema.server.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,20 +151,24 @@ export const eventTalksTable = pgTable("event_talks", {
151151
updatedAt,
152152
});
153153

154-
export const eventImagesTable = pgTable("event_images", {
155-
eventId: uuid("event_id")
156-
.notNull()
157-
.references(() => eventsTable.id, { onDelete: "cascade" }),
158-
imageId: uuid("image_id")
159-
.notNull()
160-
.references(() => imagesTable.id, { onDelete: "cascade" }),
161-
createdAt,
162-
updatedAt,
163-
}, (table) => {
164-
return {
165-
pk: primaryKey({ columns: [table.eventId, table.imageId] }),
166-
};
167-
});
154+
export const eventImagesTable = pgTable(
155+
"event_images",
156+
{
157+
eventId: uuid("event_id")
158+
.notNull()
159+
.references(() => eventsTable.id, { onDelete: "cascade" }),
160+
imageId: uuid("image_id")
161+
.notNull()
162+
.references(() => imagesTable.id, { onDelete: "cascade" }),
163+
createdAt,
164+
updatedAt,
165+
},
166+
(table) => {
167+
return {
168+
pk: primaryKey({ columns: [table.eventId, table.imageId] }),
169+
};
170+
},
171+
);
168172

169173
export type InsertEvent = typeof eventsTable.$inferInsert;
170174
export type SelectEvent = typeof eventsTable.$inferSelect;

lib/s3/client.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ type Deps = {
99
region: string;
1010
url: string;
1111
bucket: string;
12-
}
13-
}
12+
};
13+
};
1414
};
1515

1616
export type S3Client = ReturnType<typeof createS3Client>;

website/app/modules/db/queries.server.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { eq, and, gte, lt, aliasedTable, desc, inArray, sql } from "drizzle-orm";
1+
import {
2+
eq,
3+
and,
4+
gte,
5+
lt,
6+
aliasedTable,
7+
desc,
8+
inArray,
9+
sql,
10+
} from "drizzle-orm";
211
import { Speaker, Sponsor, Talk } from "../allthingsweb/events";
312
import { Event } from "../allthingsweb/events";
413
import { getSocialUrls } from "../allthingsweb/socials";
@@ -355,7 +364,7 @@ export const createDbQueryClient = ({ db, mainConfig }: Deps) => {
355364
SELECT DISTINCT ${talkSpeakersTable.speakerId}
356365
FROM ${talkSpeakersTable}
357366
JOIN ${eventTalksTable} ON ${talkSpeakersTable.talkId} = ${eventTalksTable.talkId}
358-
)`
367+
)`,
359368
)
360369
.leftJoin(imagesTable, eq(profilesTable.image, imagesTable.id));
361370
}

0 commit comments

Comments
 (0)