misc: initial move to pants

This commit is contained in:
Roman Godmaire 2024-02-09 22:43:36 -05:00
parent 9fb666bc85
commit 7371819ed7
49 changed files with 269 additions and 129 deletions

13
.gitignore vendored
View file

@ -1,12 +1 @@
.DS_Store .pants.d/
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
*.db

14
pants.toml Normal file
View file

@ -0,0 +1,14 @@
[GLOBAL]
pants_version = "2.19.0"
backend_packages = [
"pants.backend.docker",
"pants.backend.shell",
"pants.backend.experimental.adhoc",
"pants.backend.experimental.javascript",
"pants.backend.experimental.javascript.lint.prettier",
"pants.backend.experimental.rust",
]
[system-binaries]
system_binary_paths = ["<PATH>"]

12
plice/.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
*.db

0
plice/.projectile Normal file
View file

54
plice/BUILD Normal file
View file

@ -0,0 +1,54 @@
docker_image(name="docker")
files(
name="sources",
sources=[
"prisma/**",
"src/**/*.ts",
]
)
files(
name="package-config",
sources=[
"package.json",
"pnpm-lock.yaml",
],
)
system_binary(
name="pnpm",
binary_name="pnpm",
fingerprint=r"8\.\d+\.\d+",
fingerprint_args=["--version"],
fingerprint_dependencies=[":node"],
)
system_binary(
name="node",
binary_name="node",
fingerprint=r"v21\.\d+\.\d+",
fingerprint_args=["--version"],
)
system_binary(
name="sh",
binary_name="sh",
)
adhoc_tool(
name="node-modules",
runnable=":pnpm",
runnable_dependencies=[":node", ":sh"],
args=["install", "--reporter", "ndjson"],
output_dependencies=[":package-config"],
execution_dependencies=[":package-config"],
output_directories=["node_modules"],
)
experimental_test_shell_command(
name="test",
tools=["pnpm", "node", "sh", "sed", "dirname", "uname"],
command="pnpm vitest run",
execution_dependencies=[":sources", ":package-config", ":node-modules"],
)

View file

@ -1,5 +1,5 @@
{ {
"name": "larsen", "name": "larsen-plice",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {

View file

@ -43,7 +43,6 @@ model Key {
model Track { model Track {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
title String title String
objectKey String
producer User @relation(fields: [producerId], references: [id], onDelete: Cascade) producer User @relation(fields: [producerId], references: [id], onDelete: Cascade)
producerId String producerId String
@ -57,7 +56,7 @@ model Track {
} }
model TrackVersion { model TrackVersion {
id Int @id @default(autoincrement()) id String @id @default(uuid())
track Track @relation(fields: [trackId], references: [id], onDelete: Cascade) track Track @relation(fields: [trackId], references: [id], onDelete: Cascade)
trackId Int trackId Int
@ -77,7 +76,7 @@ model Comment {
authorId String authorId String
trackVersion TrackVersion @relation(fields: [trackVersionId], references: [id], onDelete: Cascade) trackVersion TrackVersion @relation(fields: [trackVersionId], references: [id], onDelete: Cascade)
trackVersionId Int trackVersionId String
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt

View file

View file

@ -1,12 +1,10 @@
import type { Handle } from '@sveltejs/kit'; import type { Handle } from '@sveltejs/kit';
import { S3_ENDPOINT, S3_BUCKET } from '$env/static/private';
import { auth } from '$lib/server/lucia'; import { auth } from '$lib/server/lucia';
import { ObjectStorageS3 } from '$lib/server/storage/s3'; import { ObjectStorageNoop } from '$lib/server/storage/noop';
import { DatabasePrisma } from '$lib/server/db/prisma'; import { DatabasePrisma } from '$lib/server/db/prisma';
const s3Client = new ObjectStorageS3(S3_ENDPOINT, S3_BUCKET); const s3Client = new ObjectStorageNoop();
const prismaClient = new DatabasePrisma(); const prismaClient = new DatabasePrisma();
export const handle: Handle = async ({ event, resolve }) => { export const handle: Handle = async ({ event, resolve }) => {

View file

@ -0,0 +1,74 @@
<script lang="ts">
export let trackId: number;
export let latestVersionId: number;
let content = '';
const versions = Array.from(Array(latestVersionId).keys())
.map((x) => x + 1)
.reverse();
</script>
<form action={`/track/${trackId}?/createComment`}>
<div class="comment-input">
<input type="text" name="comment" placeholder="Leave some feedback" bind:value={content} />
{#if content.length > 0}
<button class="post-button">Post</button>
{/if}
</div>
{#if content.length > 0}
<div class="version-selector">
<small>For version</small>
<select name="version">
{#each versions as version}
<option value={version}>{version}</option>
{/each}
</select>
</div>
{/if}
</form>
<style>
.comment-input {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 5px;
& input {
margin: 0;
}
& button {
width: 6em;
margin: 0;
}
}
.version-selector {
display: flex;
align-items: center;
gap: 0.25rem;
color: gray;
& select {
width: auto;
padding: 0 0.5rem;
margin: auto 0;
color: gray;
text-align: center;
background-image: none;
border: none;
border-bottom: thin solid;
border-radius: 0;
}
}
</style>

View file

@ -34,7 +34,7 @@
<hr /> <hr />
{/each} {/each}
<CommentField /> <CommentField trackId={id} latestVersionId={version} />
</footer> </footer>
</article> </article>

View file

@ -5,24 +5,32 @@ export interface Database {
{ {
id: number; id: number;
title: string; title: string;
version: number; producer: {
producer: string; username: string;
comments: { };
author: string; versions: {
content: string; comments: {
createdAt: Date; createdAt: Date;
content: string;
author: {
username: string;
};
}[];
}[]; }[];
_count: {
versions: number;
};
}[] }[]
>; >;
fetchTrackPageData: (trackId: number) => Promise<{ fetchTrackPageData: (trackId: number) => Promise<{
title: string; title: string;
objectKey: string;
createdAt: Date; createdAt: Date;
producer: { producer: {
username: string; username: string;
}; };
versions: { versions: {
id: string;
comments: { comments: {
createdAt: Date; createdAt: Date;
content: string; content: string;
@ -32,6 +40,7 @@ export interface Database {
}[]; }[];
}[]; }[];
} | null>; } | null>;
createTrack: (producerId: string, title: string, objectKey: string) => Promise<Track>; createTrack: (producerId: string, title: string) => Promise<Track>;
createTrackVersion: (trackId: number) => Promise<TrackVersion>; createTrackVersion: (trackId: number) => Promise<TrackVersion>;
createComment: (versionId: number, producerId: string, content: string) => Promise<{}>;
} }

View file

@ -4,12 +4,18 @@ import { PrismaClient } from '@prisma/client';
export class DatabasePrisma implements Database { export class DatabasePrisma implements Database {
client: PrismaClient; client: PrismaClient;
constructor() { constructor(url: string) {
this.client = new PrismaClient(); this.client = new PrismaClient({
datasources: {
db: {
url: url
}
}
});
} }
fetchHomepageData = async (producerId: string) => { fetchHomepageData = async (producerId: string) => {
const tracks = await this.client.track.findMany({ return await this.client.track.findMany({
select: { select: {
id: true, id: true,
title: true, title: true,
@ -43,33 +49,12 @@ export class DatabasePrisma implements Database {
producerId producerId
} }
}); });
const res = tracks.map((track) => {
return {
id: track.id,
title: track.title,
version: track._count.versions,
producer: track.producer.username,
comments: track.versions.flatMap((v) => {
return v.comments.map((c) => {
return {
author: c.author.username,
content: c.content,
createdAt: c.createdAt
};
});
})
};
});
return res;
}; };
fetchTrackPageData = async (trackId: number) => { fetchTrackPageData = async (trackId: number) => {
const track = await this.client.track.findUnique({ return await this.client.track.findUnique({
select: { select: {
title: true, title: true,
objectKey: true,
createdAt: true, createdAt: true,
producer: { producer: {
select: { select: {
@ -81,6 +66,7 @@ export class DatabasePrisma implements Database {
id: 'desc' id: 'desc'
}, },
select: { select: {
id: true,
comments: { comments: {
select: { select: {
content: true, content: true,
@ -99,29 +85,27 @@ export class DatabasePrisma implements Database {
id: trackId id: trackId
} }
}); });
return track;
}; };
createTrack = async (producerId: string, title: string, objectKey: string) => { createTrack = async (producerId: string, title: string) => {
const track = await this.client.track.create({ return await this.client.track.create({
data: { data: {
title, title,
objectKey,
producerId producerId
} }
}); });
return track;
}; };
createTrackVersion = async (trackId: number) => { createTrackVersion = async (trackId: number) => {
const trackVersion = await this.client.trackVersion.create({ return await this.client.trackVersion.create({
data: { data: {
trackId trackId
} }
}); });
};
return trackVersion; createComment = async (versionId: number, producerId: string, content: string) => {
// TODO
return {};
}; };
} }

View file

@ -0,0 +1,33 @@
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals: { authReq, database } }) => {
const session = await authReq.validate();
if (!session)
return {
tracks: []
};
const raw_tracks = await database.fetchHomepageData(session.user.userId);
const tracks = raw_tracks.map((track) => {
return {
id: track.id,
title: track.title,
version: track._count.versions,
producer: track.producer.username,
comments: track.versions.flatMap((v) => {
return v.comments.map((c) => {
return {
author: c.author.username,
content: c.content,
createdAt: c.createdAt
};
});
})
};
});
return {
tracks
};
};

View file

@ -0,0 +1,38 @@
import { error, redirect } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params: { slug }, locals: { database } }) => {
const trackId = parseInt(slug);
if (isNaN(trackId)) {
throw error(404, 'Track not found');
}
let track = await database.fetchTrackPageData(trackId);
if (!track) {
throw error(440, 'Track not found');
}
return {
track
};
};
export const actions: Actions = {
comment: async ({ request, params: { slug }, locals: { authReq, database } }) => {
const session = await authReq.validate();
if (!session) throw redirect(302, '/login');
const trackId = parseInt(slug);
const formData = await request.formData();
const comment = formData.get('comment') as string;
const version = formData.get('version') as string;
const versionId = parseInt(version);
if (isNaN(versionId)) {
throw error(404, 'Invalid version');
}
database.createComment(trackId, versionId, comment);
}
};

View file

@ -37,5 +37,6 @@
{/each} {/each}
</details> </details>
{/each} {/each}
<CommentField />
<CommentField trackId={track.id} latestVersionId={track.versions.length} />
</section> </section>

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,29 +0,0 @@
<script lang="ts">
let content = '';
</script>
<div class="comment-field">
<label for="comment" class="comment-input">
<input type="text" name="comment" placeholder="Leave some feedback" bind:value={content} />
</label>
{#if content.length > 0}
<button class="post-button">Post</button>
{/if}
</div>
<style>
.comment-field {
display: flex;
align-items: center;
gap: 1em;
}
.comment-input {
flex-grow: 1;
}
.post-button {
width: 6em;
}
</style>

View file

@ -1,16 +0,0 @@
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals: { authReq, database } }) => {
const session = await authReq.validate();
if (!session)
return {
tracks: []
};
const tracks = await database.fetchHomepageData(session.user.userId);
return {
tracks
};
};

View file

@ -1,20 +0,0 @@
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params: { slug }, locals: { database } }) => {
const trackId = parseInt(slug);
if (isNaN(trackId)) {
throw error(404, 'Track not found');
}
let track = await database.fetchTrackPageData(trackId);
if (!track) {
throw error(440, 'Track not found');
}
return {
track
};
};