misc: initial move to pants
This commit is contained in:
parent
9fb666bc85
commit
7371819ed7
49 changed files with 269 additions and 129 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -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
14
pants.toml
Normal 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
12
plice/.gitignore
vendored
Normal 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
0
plice/.projectile
Normal file
54
plice/BUILD
Normal file
54
plice/BUILD
Normal 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"],
|
||||||
|
)
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "larsen",
|
"name": "larsen-plice",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
|
@ -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
|
0
src/app.d.ts → plice/src/app.d.ts
vendored
0
src/app.d.ts → plice/src/app.d.ts
vendored
|
@ -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 }) => {
|
74
plice/src/lib/components/CommentField.svelte
Normal file
74
plice/src/lib/components/CommentField.svelte
Normal 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>
|
|
@ -34,7 +34,7 @@
|
||||||
<hr />
|
<hr />
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<CommentField />
|
<CommentField trackId={id} latestVersionId={version} />
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -5,20 +5,6 @@ export interface Database {
|
||||||
{
|
{
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
version: number;
|
|
||||||
producer: string;
|
|
||||||
comments: {
|
|
||||||
author: string;
|
|
||||||
content: string;
|
|
||||||
createdAt: Date;
|
|
||||||
}[];
|
|
||||||
}[]
|
|
||||||
>;
|
|
||||||
|
|
||||||
fetchTrackPageData: (trackId: number) => Promise<{
|
|
||||||
title: string;
|
|
||||||
objectKey: string;
|
|
||||||
createdAt: Date;
|
|
||||||
producer: {
|
producer: {
|
||||||
username: string;
|
username: string;
|
||||||
};
|
};
|
||||||
|
@ -31,7 +17,30 @@ export interface Database {
|
||||||
};
|
};
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
|
_count: {
|
||||||
|
versions: number;
|
||||||
|
};
|
||||||
|
}[]
|
||||||
|
>;
|
||||||
|
|
||||||
|
fetchTrackPageData: (trackId: number) => Promise<{
|
||||||
|
title: string;
|
||||||
|
createdAt: Date;
|
||||||
|
producer: {
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
versions: {
|
||||||
|
id: string;
|
||||||
|
comments: {
|
||||||
|
createdAt: Date;
|
||||||
|
content: string;
|
||||||
|
author: {
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
}[];
|
||||||
} | 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<{}>;
|
||||||
}
|
}
|
|
@ -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 {};
|
||||||
};
|
};
|
||||||
}
|
}
|
33
plice/src/routes/+page.server.ts
Normal file
33
plice/src/routes/+page.server.ts
Normal 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
|
||||||
|
};
|
||||||
|
};
|
38
plice/src/routes/track/[slug]/+page.server.ts
Normal file
38
plice/src/routes/track/[slug]/+page.server.ts
Normal 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);
|
||||||
|
}
|
||||||
|
};
|
|
@ -37,5 +37,6 @@
|
||||||
{/each}
|
{/each}
|
||||||
</details>
|
</details>
|
||||||
{/each}
|
{/each}
|
||||||
<CommentField />
|
|
||||||
|
<CommentField trackId={track.id} latestVersionId={track.versions.length} />
|
||||||
</section>
|
</section>
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -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>
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -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
|
|
||||||
};
|
|
||||||
};
|
|
Loading…
Reference in a new issue