chore: pnpm format
All checks were successful
Frontend CI / build (push) Successful in 1m21s
PR Title Check / pr-title-check (pull_request) Successful in 17s

This commit is contained in:
SquidSpirit 2025-10-12 18:26:56 +08:00
parent 898ee86f91
commit 8b1d643531
27 changed files with 77 additions and 73 deletions

View File

@ -1,7 +1,7 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"trailingComma": "es5",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"overrides": [

View File

@ -18,13 +18,13 @@ export default ts.config(
...svelte.configs.prettier,
{
languageOptions: {
globals: { ...globals.browser, ...globals.node }
globals: { ...globals.browser, ...globals.node },
},
rules: {
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
'no-undef': 'off'
}
'no-undef': 'off',
},
},
{
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
@ -33,8 +33,8 @@ export default ts.config(
projectService: true,
extraFileExtensions: ['.svelte'],
parser: ts.parser,
svelteConfig
}
}
svelteConfig,
},
},
}
);

View File

@ -19,7 +19,7 @@ Sentry.init({
replaysOnErrorSampleRate: 1.0,
// If you don't want to use Session Replay, just remove the line below:
integrations: [replayIntegration()]
integrations: [replayIntegration()],
});
// If you have a custom error handler, pass it to `handleErrorWithSentry`

View File

@ -12,7 +12,7 @@ import { Environment } from '$lib/environment';
Sentry.init({
dsn: Environment.SENTRY_DSN,
tracesSampleRate: 1,
enableLogs: true
enableLogs: true,
});
export const handle: Handle = sequence(Sentry.sentryHandle(), ({ event, resolve }) => {

View File

@ -2,7 +2,7 @@ export enum StatusType {
Idle,
Loading,
Success,
Error
Error,
}
export interface IdleState<T> {

View File

@ -2,7 +2,7 @@
let {
label,
link,
isSelected
isSelected,
}: {
label: string;
link: string;

View File

@ -11,7 +11,7 @@
'在這裡',
'我會分享我的技術筆記、開發心得',
'還有各式各樣實用工具的評測與介紹',
'一起探索數位世界的無限可能吧!'
'一起探索數位世界的無限可能吧!',
];
let isReady: boolean = $state(false);

View File

@ -44,7 +44,7 @@
hour12: false,
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
second: '2-digit',
});
}
</script>

View File

@ -31,7 +31,7 @@
'資工系',
'軟體工程',
'遊戲',
'魷魚'
'魷魚',
];
// Initialize with placeholder to prevent flickering

View File

@ -5,7 +5,7 @@ export const ColorResponseSchema = z.object({
red: z.number().int().min(0).max(255),
green: z.number().int().min(0).max(255),
blue: z.number().int().min(0).max(255),
alpha: z.number().int().min(0).max(255)
alpha: z.number().int().min(0).max(255),
});
export class ColorResponseDto {
@ -27,7 +27,7 @@ export class ColorResponseDto {
red: parsedJson.red,
green: parsedJson.green,
blue: parsedJson.blue,
alpha: parsedJson.alpha
alpha: parsedJson.alpha,
});
}
@ -36,7 +36,7 @@ export class ColorResponseDto {
red: this.red,
green: this.green,
blue: this.blue,
alpha: this.alpha
alpha: this.alpha,
});
}
}

View File

@ -5,7 +5,7 @@ import { z } from 'zod';
export const LabelResponseSchema = z.object({
id: z.int32(),
name: z.string(),
color: ColorResponseSchema
color: ColorResponseSchema,
});
export class LabelResponseDto {
@ -24,7 +24,7 @@ export class LabelResponseDto {
return new LabelResponseDto({
id: parsedJson.id,
name: parsedJson.name,
color: ColorResponseDto.fromJson(parsedJson.color)
color: ColorResponseDto.fromJson(parsedJson.color),
});
}
@ -32,7 +32,7 @@ export class LabelResponseDto {
return new Label({
id: this.id,
name: this.name,
color: this.color
color: this.color,
});
}
}

View File

@ -9,7 +9,7 @@ export const PostInfoResponseSchema = z.object({
description: z.string(),
preview_image_url: z.url(),
labels: z.array(LabelResponseSchema),
published_time: z.iso.datetime({ offset: true }).nullable()
published_time: z.iso.datetime({ offset: true }).nullable(),
});
export class PostInfoResponseDto {
@ -54,7 +54,7 @@ export class PostInfoResponseDto {
description: parsedJson.description,
previewImageUrl: new URL(parsedJson.preview_image_url),
labels: parsedJson.labels.map((label) => LabelResponseDto.fromJson(label)),
publishedTime: published_time
publishedTime: published_time,
});
}
@ -66,7 +66,7 @@ export class PostInfoResponseDto {
description: this.description,
previewImageUrl: this.previewImageUrl,
labels: this.labels.map((label) => label.toEntity()),
publishedTime: this.publishedTime
publishedTime: this.publishedTime,
});
}
}

View File

@ -1,6 +1,6 @@
import {
PostInfoResponseDto,
PostInfoResponseSchema
PostInfoResponseSchema,
} from '$lib/post/adapter/gateway/postInfoResponseDto';
import { Post } from '$lib/post/domain/entity/post';
import z from 'zod';
@ -8,7 +8,7 @@ import z from 'zod';
export const PostResponseSchema = z.object({
id: z.int32(),
info: PostInfoResponseSchema,
content: z.string()
content: z.string(),
});
export class PostResponseDto {
@ -27,7 +27,7 @@ export class PostResponseDto {
return new PostResponseDto({
id: parsedJson.id,
info: PostInfoResponseDto.fromJson(parsedJson.info),
content: parsedJson.content
content: parsedJson.content,
});
}
@ -35,7 +35,7 @@ export class PostResponseDto {
return new Post({
id: this.id,
info: this.info.toEntity(),
content: this.content
content: this.content,
});
}
}

View File

@ -43,7 +43,7 @@ export class ColorViewModel {
red: Math.round(r * 255),
green: Math.round(g * 255),
blue: Math.round(b * 255),
alpha: 255
alpha: 255,
});
}
@ -52,7 +52,7 @@ export class ColorViewModel {
red: color.red,
green: color.green,
blue: color.blue,
alpha: color.alpha
alpha: color.alpha,
});
}
@ -115,7 +115,7 @@ export class ColorViewModel {
red: this.red,
green: this.green,
blue: this.blue,
alpha: this.alpha
alpha: this.alpha,
};
}
}

View File

@ -1,6 +1,6 @@
import {
ColorViewModel,
type DehydratedColorProps
type DehydratedColorProps,
} from '$lib/post/adapter/presenter/colorViewModel';
import type { Label } from '$lib/post/domain/entity/label';
@ -19,7 +19,7 @@ export class LabelViewModel {
return new LabelViewModel({
id: label.id,
name: label.name,
color: ColorViewModel.fromEntity(label.color)
color: ColorViewModel.fromEntity(label.color),
});
}
@ -27,7 +27,7 @@ export class LabelViewModel {
return new LabelViewModel({
id: props.id,
name: props.name,
color: ColorViewModel.rehydrate(props.color)
color: ColorViewModel.rehydrate(props.color),
});
}
@ -35,7 +35,7 @@ export class LabelViewModel {
return {
id: this.id,
name: this.name,
color: this.color.dehydrate()
color: this.color.dehydrate(),
};
}
}

View File

@ -8,7 +8,7 @@ export type PostEvent = PostLoadedEvent;
export class PostBloc {
private readonly state = writable<PostState>({
status: StatusType.Idle
status: StatusType.Idle,
});
constructor(
@ -17,7 +17,7 @@ export class PostBloc {
) {
this.state.set({
status: StatusType.Idle,
data: initialData
data: initialData,
});
}
@ -44,7 +44,7 @@ export class PostBloc {
const postViewModel = PostViewModel.fromEntity(post);
const result: PostState = {
status: StatusType.Success,
data: postViewModel
data: postViewModel,
};
this.state.set(result);
@ -53,7 +53,7 @@ export class PostBloc {
}
export enum PostEventType {
PostLoadedEvent
PostLoadedEvent,
}
interface PostLoadedEvent {

View File

@ -1,6 +1,6 @@
import {
LabelViewModel,
type DehydratedLabelProps
type DehydratedLabelProps,
} from '$lib/post/adapter/presenter/labelViewModel';
import type { PostInfo } from '$lib/post/domain/entity/postInfo';
@ -39,7 +39,7 @@ export class PostInfoViewModel {
description: postInfo.description,
previewImageUrl: postInfo.previewImageUrl,
labels: postInfo.labels.map((label) => LabelViewModel.fromEntity(label)),
publishedTime: postInfo.publishedTime
publishedTime: postInfo.publishedTime,
});
}
@ -56,7 +56,7 @@ export class PostInfoViewModel {
description: props.description,
previewImageUrl: new URL(props.previewImageUrl),
labels: props.labels.map((label) => LabelViewModel.rehydrate(label)),
publishedTime: publishedTime
publishedTime: publishedTime,
});
}
@ -76,7 +76,7 @@ export class PostInfoViewModel {
description: this.description,
previewImageUrl: this.previewImageUrl.href,
labels: this.labels.map((label) => label.dehydrate()),
publishedTime: this.publishedTime?.getTime() ?? null
publishedTime: this.publishedTime?.getTime() ?? null,
};
}
}

View File

@ -8,7 +8,7 @@ export type PostListEvent = PostListLoadedEvent;
export class PostListBloc {
private readonly state = writable<PostListState>({
status: StatusType.Idle
status: StatusType.Idle,
});
constructor(
@ -17,7 +17,7 @@ export class PostListBloc {
) {
this.state.set({
status: StatusType.Idle,
data: initialData
data: initialData,
});
}
@ -38,7 +38,7 @@ export class PostListBloc {
const postViewModels = posts.map((post) => PostInfoViewModel.fromEntity(post));
const result: PostListState = {
status: StatusType.Success,
data: postViewModels
data: postViewModels,
};
this.state.set(result);
@ -47,7 +47,7 @@ export class PostListBloc {
}
export enum PostListEventType {
PostListLoadedEvent
PostListLoadedEvent,
}
export interface PostListLoadedEvent {

View File

@ -1,6 +1,6 @@
import {
PostInfoViewModel,
type DehydratedPostInfoProps
type DehydratedPostInfoProps,
} from '$lib/post/adapter/presenter/postInfoViewModel';
import type { Post } from '$lib/post/domain/entity/post';
@ -19,7 +19,7 @@ export class PostViewModel {
return new PostViewModel({
id: post.id,
info: PostInfoViewModel.fromEntity(post.info),
content: post.content
content: post.content,
});
}
@ -27,7 +27,7 @@ export class PostViewModel {
return new PostViewModel({
id: props.id,
info: PostInfoViewModel.rehydrate(props.info),
content: props.content
content: props.content,
});
}
@ -35,7 +35,7 @@ export class PostViewModel {
return {
id: this.id,
info: this.info.dehydrate(),
content: this.content
content: this.content,
};
}
}

View File

@ -32,7 +32,7 @@
{/if}
{/if}
</svelte:head>
<article class="prose prose-gray container pb-10">
<article class="container prose pb-10 prose-gray">
{#if state.data}
<PostContentHeader postInfo={state.data.info} />
<div class="max-w-3xl">

View File

@ -17,7 +17,11 @@
}
</script>
<a class="flex cursor-pointer flex-col gap-y-6" href="/post/{postInfo.semanticId}" title={postInfo.title}>
<a
class="flex cursor-pointer flex-col gap-y-6"
href="/post/{postInfo.semanticId}"
title={postInfo.title}
>
<div class="relative aspect-video overflow-hidden rounded-2xl bg-gray-200">
<img
class="rounded-2xl object-cover transition-opacity duration-300

View File

@ -5,7 +5,7 @@
headline,
description,
datePublished,
image
image,
}: {
headline: string;
description: string;
@ -19,7 +19,7 @@
headline: headline,
description: description,
datePublished: datePublished.toISOString(),
image: image.href
image: image.href,
});
const jsonLdScript = $derived(

View File

@ -7,6 +7,6 @@ export const load: PageServerLoad = async ({ locals }) => {
const state = await postListBloc.dispatch({ event: PostListEventType.PostListLoadedEvent });
return {
dehydratedData: state.data?.map((post) => post.dehydrate())
dehydratedData: state.data?.map((post) => post.dehydrate()),
};
};

View File

@ -7,13 +7,13 @@ export const load: PageServerLoad = async ({ locals, params }) => {
const state = await postBloc.dispatch({
event: PostEventType.PostLoadedEvent,
id: params.id
id: params.id,
});
if (!state.data) {
error(404, { message: 'Post not found' });
}
return {
dehydratedData: state.data.dehydrate()
dehydratedData: state.data.dehydrate(),
};
};

View File

@ -11,8 +11,8 @@ const config = {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter()
}
adapter: adapter(),
},
};
export default config;

View File

@ -9,10 +9,10 @@ module.exports = {
'--tw-prose-headings': 'var(--color-gray-800)',
'--tw-prose-links': 'var(--color-gray-800)',
'--tw-prose-bold': 'var(--color-gray-800)',
'--tw-prose-quotes': 'var(--color-gray-800)'
}
}
})
}
}
'--tw-prose-quotes': 'var(--color-gray-800)',
},
},
}),
},
},
};

View File

@ -10,22 +10,22 @@ export default defineConfig({
sentrySvelteKit({
sourceMapsUploadOptions: {
org: 'squidspirit',
project: 'blog-beta-frontend'
}
project: 'blog-beta-frontend',
},
}),
tailwindcss(),
sveltekit()
sveltekit(),
],
define: {
'App.__VERSION__': JSON.stringify(version)
'App.__VERSION__': JSON.stringify(version),
},
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});