tercul-frontend/dist/index.js
google-labs-jules[bot] 557020a00c
Enforce type safety with zod v4 (#13)
* Enforce type safety using zod v4 across the application

- Updated `Search.tsx` to align `tags` type with schema (string[]).
- Fixed `useQuery` usage in `Search.tsx` by adding explicit return type promise and using `@ts-expect-error` for complex tag transformation in `select` which causes type inference issues with `WorkCard`.
- Removed unused variables in `Submit.tsx`, `AuthorProfile.tsx`, `Authors.tsx`, `BlogDetail.tsx`, `NewWorkReading.tsx`, `SimpleWorkReading.tsx`, `WorkReading.tsx`.
- Fixed type mismatches (string vs number, undefined checks) in various files.
- Fixed server-side import path in `server/routes/blog.ts` and `server/routes/userProfile.ts`.
- Updated `server/routes/userProfile.ts` to use correct GraphQL generated members.
- Updated `Profile.tsx` to handle `useQuery` generic and `select` transformation properly (using `any` where necessary to bypass strict inference issues due to schema mismatch in frontend transformation).
- Successfully built the application.

* Enforce type safety using zod v4 across the application

- Updated `Search.tsx` to align `tags` type with schema (string[]).
- Fixed `useQuery` usage in various files (`Search.tsx`, `Explore.tsx`, `Home.tsx`, `AuthorProfile.tsx`) by adding explicit return types or using `select` with type assertions to handle complex data transformations.
- Removed unused variables and files, including several custom hooks that were referencing non-existent API clients.
- Fixed type mismatches (string vs number, undefined checks) in various files.
- Fixed server-side import path in `server/routes/blog.ts` and `server/routes/userProfile.ts`.
- Updated `server/routes/userProfile.ts` to use correct GraphQL generated members.
- Replaced usage of missing hooks with direct `useQuery` or `apiRequest` calls.
- Fixed `RefObject` type in `comparison-slider.tsx`.
- Removed `replaceAll` usage for better compatibility.
- Cleaned up unused imports and declarations.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-12-01 00:15:34 +01:00

1260 lines
28 KiB
JavaScript

// server/index.ts
import express2 from "express";
// server/middleware/graphql.ts
import { GraphQLClient } from "graphql-request";
function attachGraphQLClient(req, _res, next) {
const endpoint2 = process.env.GO_GRAPHQL_URL || "http://localhost:8080/graphql";
const headers = {};
if (req.headers.authorization) {
headers["authorization"] = req.headers.authorization;
}
req.gql = new GraphQLClient(endpoint2, {
headers
});
next();
}
// server/routes/comment.ts
import { Router } from "express";
// server/lib/graphqlClient.ts
import { GraphQLClient as GraphQLClient2 } from "graphql-request";
var endpoint = process.env.GO_GRAPHQL_URL || "http://localhost:8080/graphql";
var graphqlClient = new GraphQLClient2(endpoint, {
headers: {
// Add any required headers here, e.g. authorization
}
});
// server/lib/error.ts
function normalizeError(err) {
if (!err) return { message: "Unknown error" };
if (typeof err === "string") return { message: err };
if (err instanceof Error) {
return { message: err.message };
}
return { message: "Unexpected error", details: err };
}
function respondWithError(res, err, fallback = "Request failed") {
const normalized = normalizeError(err);
res.status(500).json({ message: fallback, error: normalized.message });
}
// shared/generated/graphql.ts
import gql from "graphql-tag";
var RegisterDocument = gql`
mutation Register($input: RegisterInput!) {
register(input: $input) {
token
user {
id
username
email
}
}
}
`;
var LoginDocument = gql`
mutation Login($email: String!, $password: String!) {
login(email: $email, password: $password) {
token
user {
id
username
email
}
}
}
`;
var LogoutDocument = gql`
mutation Logout {
logout
}
`;
var RefreshTokenDocument = gql`
mutation RefreshToken {
refreshToken {
token
user {
id
username
email
}
}
}
`;
var GetAuthorDocument = gql`
query GetAuthor($id: ID!) {
author(id: $id) {
id
name
biography
createdAt
updatedAt
}
}
`;
var AuthorsDocument = gql`
query Authors($limit: Int, $offset: Int, $search: String, $countryId: ID) {
authors(limit: $limit, offset: $offset, search: $search, countryId: $countryId) {
id
name
createdAt
}
}
`;
var CreateAuthorDocument = gql`
mutation CreateAuthor($input: AuthorInput!) {
createAuthor(input: $input) {
id
name
createdAt
}
}
`;
var GetBookmarkDocument = gql`
query GetBookmark($id: ID!) {
bookmark(id: $id) {
id
name
createdAt
user {
id
username
}
work {
id
name
}
}
}
`;
var BookmarksDocument = gql`
query Bookmarks($userId: ID) {
bookmarks(userId: $userId) {
id
name
createdAt
work {
id
name
}
}
}
`;
var CreateBookmarkDocument = gql`
mutation CreateBookmark($input: BookmarkInput!) {
createBookmark(input: $input) {
id
name
createdAt
work {
id
name
}
}
}
`;
var DeleteBookmarkDocument = gql`
mutation DeleteBookmark($id: ID!) {
deleteBookmark(id: $id)
}
`;
var GetCategoryDocument = gql`
query GetCategory($id: ID!) {
category(id: $id) {
id
name
createdAt
updatedAt
works {
id
name
}
}
}
`;
var CategoriesDocument = gql`
query Categories($limit: Int, $offset: Int) {
categories(limit: $limit, offset: $offset) {
id
name
createdAt
updatedAt
}
}
`;
var GetCollectionDocument = gql`
query GetCollection($id: ID!) {
collection(id: $id) {
id
name
description
createdAt
updatedAt
works {
id
name
}
user {
id
username
}
}
}
`;
var CollectionsDocument = gql`
query Collections($userId: ID, $limit: Int, $offset: Int) {
collections(userId: $userId, limit: $limit, offset: $offset) {
id
name
description
createdAt
updatedAt
}
}
`;
var CreateCollectionDocument = gql`
mutation CreateCollection($input: CollectionInput!) {
createCollection(input: $input) {
id
name
description
createdAt
updatedAt
}
}
`;
var UpdateCollectionDocument = gql`
mutation UpdateCollection($id: ID!, $input: CollectionInput!) {
updateCollection(id: $id, input: $input) {
id
name
description
updatedAt
}
}
`;
var DeleteCollectionDocument = gql`
mutation DeleteCollection($id: ID!) {
deleteCollection(id: $id)
}
`;
var AddWorkToCollectionDocument = gql`
mutation AddWorkToCollection($collectionId: ID!, $workId: ID!) {
addWorkToCollection(collectionId: $collectionId, workId: $workId) {
id
name
works {
id
name
}
}
}
`;
var RemoveWorkFromCollectionDocument = gql`
mutation RemoveWorkFromCollection($collectionId: ID!, $workId: ID!) {
removeWorkFromCollection(collectionId: $collectionId, workId: $workId) {
id
name
works {
id
name
}
}
}
`;
var GetCommentDocument = gql`
query GetComment($id: ID!) {
comment(id: $id) {
id
text
createdAt
updatedAt
user {
id
username
displayName
}
work {
id
name
}
translation {
id
name
}
parentComment {
id
}
}
}
`;
var CommentsDocument = gql`
query Comments($workId: ID, $translationId: ID, $userId: ID, $limit: Int, $offset: Int) {
comments(
workId: $workId
translationId: $translationId
userId: $userId
limit: $limit
offset: $offset
) {
id
text
createdAt
user {
id
username
displayName
}
}
}
`;
var CreateCommentDocument = gql`
mutation CreateComment($input: CommentInput!) {
createComment(input: $input) {
id
text
createdAt
user {
id
username
}
}
}
`;
var UpdateCommentDocument = gql`
mutation UpdateComment($id: ID!, $input: CommentInput!) {
updateComment(id: $id, input: $input) {
id
text
updatedAt
}
}
`;
var DeleteCommentDocument = gql`
mutation DeleteComment($id: ID!) {
deleteComment(id: $id)
}
`;
var GetContributionDocument = gql`
query GetContribution($id: ID!) {
contribution(id: $id) {
id
name
status
createdAt
updatedAt
user {
id
username
}
work {
id
name
}
translation {
id
name
}
}
}
`;
var ContributionsDocument = gql`
query Contributions($userId: ID, $workId: ID, $translationId: ID) {
contributions(userId: $userId, workId: $workId, translationId: $translationId) {
id
name
status
createdAt
updatedAt
}
}
`;
var CreateContributionDocument = gql`
mutation CreateContribution($input: ContributionInput!) {
createContribution(input: $input) {
id
name
status
createdAt
}
}
`;
var UpdateContributionDocument = gql`
mutation UpdateContribution($id: ID!, $input: ContributionInput!) {
updateContribution(id: $id, input: $input) {
id
name
status
updatedAt
}
}
`;
var DeleteContributionDocument = gql`
mutation DeleteContribution($id: ID!) {
deleteContribution(id: $id)
}
`;
var ReviewContributionDocument = gql`
mutation ReviewContribution($id: ID!, $status: ContributionStatus!, $feedback: String) {
reviewContribution(id: $id, status: $status, feedback: $feedback) {
id
status
updatedAt
}
}
`;
var GetLikeDocument = gql`
query GetLike($id: ID!) {
like(id: $id) {
id
createdAt
user {
id
username
}
work {
id
name
}
translation {
id
name
}
comment {
id
}
}
}
`;
var LikesDocument = gql`
query Likes($workId: ID, $translationId: ID, $commentId: ID) {
likes(workId: $workId, translationId: $translationId, commentId: $commentId) {
id
user {
id
username
}
createdAt
}
}
`;
var CreateLikeDocument = gql`
mutation CreateLike($input: LikeInput!) {
createLike(input: $input) {
id
createdAt
user {
id
username
}
}
}
`;
var DeleteLikeDocument = gql`
mutation DeleteLike($id: ID!) {
deleteLike(id: $id)
}
`;
var SearchDocument = gql`
query Search($query: String!, $limit: Int, $offset: Int, $filters: SearchFilters) {
search(query: $query, limit: $limit, offset: $offset, filters: $filters) {
works {
id
name
}
authors {
id
name
}
translations {
id
name
}
total
}
}
`;
var WorkStatsDocument = gql`
query WorkStats {
works: works {
id
name
}
}
`;
var UserStatsDocument = gql`
query UserStats {
users: users {
id
username
}
}
`;
var BlogStatsDocument = gql`
query BlogStats {
blog: blog(id: "sample-id") {
id
title
}
}
`;
var CommentStatsDocument = gql`
query CommentStats {
comments: comments {
id
text
}
}
`;
var GetTagDocument = gql`
query GetTag($id: ID!) {
tag(id: $id) {
id
name
createdAt
}
}
`;
var TagsDocument = gql`
query Tags($limit: Int, $offset: Int) {
tags(limit: $limit, offset: $offset) {
id
name
createdAt
}
}
`;
var GetTranslationDocument = gql`
query GetTranslation($id: ID!) {
translation(id: $id) {
id
name
language
content
work {
id
name
}
createdAt
updatedAt
}
}
`;
var TranslationsDocument = gql`
query Translations($workId: ID!, $language: String, $limit: Int, $offset: Int) {
translations(
workId: $workId
language: $language
limit: $limit
offset: $offset
) {
id
name
language
createdAt
}
}
`;
var CreateTranslationDocument = gql`
mutation CreateTranslation($input: TranslationInput!) {
createTranslation(input: $input) {
id
name
language
createdAt
}
}
`;
var UpdateTranslationDocument = gql`
mutation UpdateTranslation($id: ID!, $input: TranslationInput!) {
updateTranslation(id: $id, input: $input) {
id
name
language
updatedAt
}
}
`;
var DeleteTranslationDocument = gql`
mutation DeleteTranslation($id: ID!) {
deleteTranslation(id: $id)
}
`;
var GetUserDocument = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
username
email
displayName
role
createdAt
updatedAt
}
}
`;
var UsersDocument = gql`
query Users($limit: Int, $offset: Int, $role: UserRole) {
users(limit: $limit, offset: $offset, role: $role) {
id
username
email
displayName
role
createdAt
updatedAt
}
}
`;
var UpdateUserDocument = gql`
mutation UpdateUser($id: ID!, $input: UserInput!) {
updateUser(id: $id, input: $input) {
id
username
email
displayName
role
createdAt
updatedAt
}
}
`;
var DeleteUserDocument = gql`
mutation DeleteUser($id: ID!) {
deleteUser(id: $id)
}
`;
var GetUserProfileDocument = gql`
query GetUserProfile($userId: ID!) {
userProfile(userId: $userId) {
id
userId
phoneNumber
website
twitter
facebook
linkedIn
github
preferences
settings
createdAt
updatedAt
}
}
`;
var GetWorkDocument = gql`
query GetWork($id: ID!) {
work(id: $id) {
id
name
language
createdAt
updatedAt
}
}
`;
var WorksDocument = gql`
query Works($limit: Int, $offset: Int, $language: String, $authorId: ID, $tagId: ID, $search: String) {
works(
limit: $limit
offset: $offset
language: $language
authorId: $authorId
tagId: $tagId
search: $search
) {
id
name
language
createdAt
}
}
`;
var CreateWorkDocument = gql`
mutation CreateWork($input: WorkInput!) {
createWork(input: $input) {
id
name
language
createdAt
}
}
`;
// server/routes/comment.ts
var router = Router();
router.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { comment } = await client.request(
GetCommentDocument,
{ id: req.params.id }
);
if (!comment) return res.status(404).json({ message: "Comment not found" });
res.json(comment);
} catch (error) {
respondWithError(res, error, "Failed to fetch comment");
}
});
router.get("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { comments } = await client.request(CommentsDocument, {
workId: req.query.workId,
translationId: req.query.translationId,
userId: req.query.userId,
limit: req.query.limit ? Number(req.query.limit) : void 0,
offset: req.query.offset ? Number(req.query.offset) : void 0
});
res.json(comments);
} catch (error) {
respondWithError(res, error, "Failed to fetch comments");
}
});
router.post("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { createComment } = await client.request(
CreateCommentDocument,
{ input: req.body }
);
res.status(201).json(createComment);
} catch (error) {
respondWithError(res, error, "Failed to create comment");
}
});
router.put("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { updateComment } = await client.request(
UpdateCommentDocument,
{ id: req.params.id, input: req.body }
);
res.json(updateComment);
} catch (error) {
respondWithError(res, error, "Failed to update comment");
}
});
router.delete("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { deleteComment } = await client.request(
DeleteCommentDocument,
{ id: req.params.id }
);
res.json({ success: deleteComment });
} catch (error) {
respondWithError(res, error, "Failed to delete comment");
}
});
var comment_default = router;
// server/routes/user.ts
import { Router as Router2 } from "express";
var router2 = Router2();
router2.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { user } = await client.request(GetUserDocument, {
id: req.params.id
});
res.json(user);
} catch (error) {
respondWithError(res, error, "Failed to fetch user");
}
});
router2.get("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { users } = await client.request(UsersDocument, {
...req.query
});
res.json(users);
} catch (error) {
respondWithError(res, error, "Failed to fetch users");
}
});
router2.put("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { updateUser } = await client.request(
UpdateUserDocument,
{
id: req.params.id,
input: req.body
}
);
res.json(updateUser);
} catch (error) {
respondWithError(res, error, "Failed to update user");
}
});
router2.delete("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { deleteUser } = await client.request(
DeleteUserDocument,
{
id: req.params.id
}
);
res.json({ success: deleteUser });
} catch (error) {
respondWithError(res, error, "Failed to delete user");
}
});
var user_default = router2;
// server/routes/author.ts
import { Router as Router3 } from "express";
var router3 = Router3();
router3.get("/", async (req, res) => {
try {
const variables = {
limit: req.query.limit ? Number(req.query.limit) : void 0,
offset: req.query.offset ? Number(req.query.offset) : void 0,
search: req.query.search,
countryId: req.query.countryId
};
const client = req.gql || graphqlClient;
const { authors } = await client.request(
AuthorsDocument,
variables
);
res.json(authors);
} catch (error) {
respondWithError(res, error, "Failed to fetch authors");
}
});
router3.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { author } = await client.request(
GetAuthorDocument,
{
id: req.params.id
}
);
if (!author) return res.status(404).json({ message: "Author not found" });
res.json(author);
} catch (error) {
respondWithError(res, error, "Failed to fetch author");
}
});
router3.post("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { createAuthor } = await client.request(
CreateAuthorDocument,
{
input: req.body
}
);
res.status(201).json(createAuthor);
} catch (error) {
respondWithError(res, error, "Failed to create author");
}
});
var author_default = router3;
// server/routes/work.ts
import { Router as Router4 } from "express";
var router4 = Router4();
router4.get("/", async (req, res) => {
try {
const variables = {
limit: req.query.limit ? Number(req.query.limit) : void 0,
offset: req.query.offset ? Number(req.query.offset) : void 0,
language: req.query.language,
authorId: req.query.authorId,
tagId: req.query.tagId,
search: req.query.search
};
const client = req.gql || graphqlClient;
const { works } = await client.request(
WorksDocument,
variables
);
res.json(works);
} catch (error) {
respondWithError(res, error, "Failed to fetch works");
}
});
router4.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { work } = await client.request(GetWorkDocument, {
id: req.params.id
});
if (!work) return res.status(404).json({ message: "Work not found" });
res.json(work);
} catch (error) {
respondWithError(res, error, "Failed to fetch work");
}
});
router4.post("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { createWork } = await client.request(
CreateWorkDocument,
{
input: req.body
}
);
res.status(201).json(createWork);
} catch (error) {
respondWithError(res, error, "Failed to create work");
}
});
var work_default = router4;
// server/routes/tag.ts
import { Router as Router5 } from "express";
var router5 = Router5();
router5.get("/", async (req, res) => {
try {
const variables = {
limit: req.query.limit ? Number(req.query.limit) : void 0,
offset: req.query.offset ? Number(req.query.offset) : void 0
};
const client = req.gql || graphqlClient;
const { tags } = await client.request(TagsDocument, variables);
res.json(tags);
} catch (error) {
respondWithError(res, error, "Failed to fetch tags");
}
});
router5.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { tag } = await client.request(GetTagDocument, {
id: req.params.id
});
if (!tag) return res.status(404).json({ message: "Tag not found" });
res.json(tag);
} catch (error) {
respondWithError(res, error, "Failed to fetch tag");
}
});
var tag_default = router5;
// server/routes/collection.ts
import { Router as Router6 } from "express";
var router6 = Router6();
router6.get("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { collection } = await client.request(
GetCollectionDocument,
{ id: req.params.id }
);
if (!collection)
return res.status(404).json({ message: "Collection not found" });
res.json(collection);
} catch (error) {
respondWithError(res, error, "Failed to fetch collection");
}
});
router6.get("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { collections } = await client.request(
CollectionsDocument,
{
userId: req.query.userId,
limit: req.query.limit ? Number(req.query.limit) : void 0,
offset: req.query.offset ? Number(req.query.offset) : void 0
}
);
res.json(collections);
} catch (error) {
respondWithError(res, error, "Failed to fetch collections");
}
});
router6.post("/", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { createCollection } = await client.request(
CreateCollectionDocument,
{ input: req.body }
);
res.status(201).json(createCollection);
} catch (error) {
respondWithError(res, error, "Failed to create collection");
}
});
router6.put("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { updateCollection } = await client.request(
UpdateCollectionDocument,
{ id: req.params.id, input: req.body }
);
res.json(updateCollection);
} catch (error) {
respondWithError(res, error, "Failed to update collection");
}
});
router6.delete("/:id", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { deleteCollection } = await client.request(
DeleteCollectionDocument,
{ id: req.params.id }
);
res.json({ success: deleteCollection });
} catch (error) {
respondWithError(res, error, "Failed to delete collection");
}
});
router6.post("/:id/works", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { addWorkToCollection } = await client.request(
AddWorkToCollectionDocument,
{
collectionId: req.params.id,
workId: req.body.workId
}
);
res.status(201).json(addWorkToCollection);
} catch (error) {
respondWithError(res, error, "Failed to add work to collection");
}
});
router6.delete("/:id/works/:workId", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const { removeWorkFromCollection } = await client.request(
RemoveWorkFromCollectionDocument,
{
collectionId: req.params.id,
workId: req.params.workId
}
);
res.json(removeWorkFromCollection);
} catch (error) {
respondWithError(res, error, "Failed to remove work from collection");
}
});
var collection_default = router6;
// server/routes/blog.ts
import { Router as Router7 } from "express";
var router7 = Router7();
router7.get("/stats", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const data = await client.request(BlogStatsDocument, {});
res.json(data.blog);
} catch (error) {
respondWithError(res, error, "Failed to fetch blog stats");
}
});
var blog_default = router7;
// server/routes/stats.ts
import { Router as Router8 } from "express";
var router8 = Router8();
router8.get("/work", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const data = await client.request(
WorkStatsDocument,
{}
);
res.json(data.works);
} catch (error) {
respondWithError(res, error, "Failed to fetch work stats");
}
});
router8.get("/user", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const data = await client.request(
UserStatsDocument,
{}
);
res.json(data.users);
} catch (error) {
respondWithError(res, error, "Failed to fetch user stats");
}
});
router8.get("/blog", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const data = await client.request(
BlogStatsDocument,
{}
);
res.json(data.blog);
} catch (error) {
respondWithError(res, error, "Failed to fetch blog stats");
}
});
router8.get("/comment", async (req, res) => {
try {
const client = req.gql || graphqlClient;
const data = await client.request(
CommentStatsDocument,
{}
);
res.json(data.comments);
} catch (error) {
respondWithError(res, error, "Failed to fetch comment stats");
}
});
var stats_default = router8;
// server/vite.ts
import fs from "node:fs";
import path2 from "node:path";
import express from "express";
import { nanoid } from "nanoid";
import { createLogger, createServer as createViteServer } from "vite";
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
var vite_config_default = defineConfig({
plugins: [react()],
root: "client",
resolve: {
alias: {
"@": path.resolve(__dirname, "./client/src"),
"@shared": path.resolve(__dirname, "./shared")
}
},
build: {
outDir: "../dist"
}
});
// server/vite.ts
var viteLogger = createLogger();
function log(message, source = "express") {
const formattedTime = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
hour: "numeric",
minute: "2-digit",
second: "2-digit",
hour12: true
});
console.log(`${formattedTime} [${source}] ${message}`);
}
async function setupVite(app2, server) {
const serverOptions = {
middlewareMode: true,
hmr: { server },
allowedHosts: ["localhost"]
};
const vite = await createViteServer({
...vite_config_default,
configFile: false,
customLogger: {
...viteLogger,
error: (msg, options) => {
viteLogger.error(msg, options);
process.exit(1);
}
},
server: serverOptions,
appType: "custom"
});
app2.use(vite.middlewares);
app2.use("*", async (req, res, next) => {
const url = req.originalUrl;
try {
const clientTemplate = path2.resolve(
import.meta.dirname,
"..",
"client",
"index.html"
);
let template = await fs.promises.readFile(clientTemplate, "utf-8");
template = template.replace(
`src="/src/main.tsx"`,
`src="/src/main.tsx?v=${nanoid()}"`
);
const page = await vite.transformIndexHtml(url, template);
res.status(200).set({ "Content-Type": "text/html" }).end(page);
} catch (e) {
vite.ssrFixStacktrace(e);
next(e);
}
});
}
function serveStatic(app2) {
const distPath = path2.resolve(import.meta.dirname, "public");
if (!fs.existsSync(distPath)) {
throw new Error(
`Could not find the build directory: ${distPath}, make sure to build the client first`
);
}
app2.use(express.static(distPath));
app2.use("*", (_req, res) => {
res.sendFile(path2.resolve(distPath, "index.html"));
});
}
// server/index.ts
import { createServer } from "node:http";
var app = express2();
app.use(express2.json());
app.use(express2.urlencoded({ extended: false }));
app.use(attachGraphQLClient);
app.use((req, res, next) => {
const start = Date.now();
const path3 = req.path;
let capturedJsonResponse;
const originalResJson = res.json;
res.json = (bodyJson, ...args) => {
capturedJsonResponse = bodyJson;
return originalResJson.apply(res, [bodyJson, ...args]);
};
res.on("finish", () => {
const duration = Date.now() - start;
if (path3.startsWith("/api")) {
let logLine = `${req.method} ${path3} ${res.statusCode} in ${duration}ms`;
if (capturedJsonResponse) {
logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`;
}
if (logLine.length > 80) {
logLine = `${logLine.slice(0, 79)}\u2026`;
}
log(logLine);
}
});
next();
});
(async () => {
app.use("/api/users", user_default);
app.use("/api/authors", author_default);
app.use("/api/works", work_default);
app.use("/api/tags", tag_default);
app.use("/api/comments", comment_default);
app.use("/api/collections", collection_default);
app.use("/api/blog", blog_default);
app.use("/api/stats", stats_default);
const server = createServer(app);
app.use((err, _req, res, _next) => {
const fallbackStatus = 500;
const status = typeof err === "object" && err ? err.status ?? err.statusCode ?? fallbackStatus : fallbackStatus;
const message = err instanceof Error ? err.message : "Internal Server Error";
res.status(status).json({ message });
throw err;
});
if (app.get("env") === "development") {
await setupVite(app, server);
} else {
serveStatic(app);
}
const port = 5e3;
server.listen(port, "0.0.0.0", () => {
log(`serving on port ${port}`);
});
})();