@xyd-js/mcp-server 0.0.0-build-9f87f13-20250930210637

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,217 @@
1
+ import express from "express";
2
+ import { randomUUID } from "crypto";
3
+
4
+ type Role = "user" | "admin" | "moderator";
5
+
6
+ interface User {
7
+ id: string;
8
+ email: string;
9
+ firstName: string;
10
+ lastName: string;
11
+ role: Role;
12
+ isActive: boolean;
13
+ createdAt: string;
14
+ updatedAt: string;
15
+ address?: { street?: string };
16
+ }
17
+
18
+ const app = express();
19
+ app.use(express.json());
20
+
21
+ const startedAt = Date.now();
22
+
23
+ const users: User[] = [
24
+ {
25
+ id: randomUUID(),
26
+ email: "alice@example.com",
27
+ firstName: "Alice",
28
+ lastName: "Anderson",
29
+ role: "admin",
30
+ isActive: true,
31
+ createdAt: new Date().toISOString(),
32
+ updatedAt: new Date().toISOString(),
33
+ address: { street: "123 Main St" },
34
+ },
35
+ {
36
+ id: randomUUID(),
37
+ email: "bob@example.com",
38
+ firstName: "Bob",
39
+ lastName: "Brown",
40
+ role: "user",
41
+ isActive: true,
42
+ createdAt: new Date().toISOString(),
43
+ updatedAt: new Date().toISOString(),
44
+ },
45
+ ];
46
+
47
+ // Health
48
+ app.get("/v1/health", (_req, res) => {
49
+ res.json({
50
+ status: "healthy",
51
+ timestamp: new Date().toISOString(),
52
+ version: "1.0.0",
53
+ uptime: (Date.now() - startedAt) / 1000,
54
+ });
55
+ });
56
+
57
+ // Auth
58
+ app.post("/v1/auth/login", (req, res) => {
59
+ const { email, password } = req.body || {};
60
+ if (typeof email !== "string" || typeof password !== "string") {
61
+ return res
62
+ .status(400)
63
+ .json({
64
+ error: "Invalid body",
65
+ code: "BAD_REQUEST",
66
+ timestamp: new Date().toISOString(),
67
+ });
68
+ }
69
+ const user = users.find((u) => u.email === email);
70
+ if (!user) {
71
+ return res
72
+ .status(401)
73
+ .json({
74
+ error: "Invalid credentials",
75
+ code: "UNAUTHORIZED",
76
+ timestamp: new Date().toISOString(),
77
+ });
78
+ }
79
+ res.json({
80
+ accessToken: "access-" + randomUUID(),
81
+ refreshToken: "refresh-" + randomUUID(),
82
+ expiresIn: 3600,
83
+ user,
84
+ });
85
+ });
86
+
87
+ app.post("/v1/auth/refresh", (req, res) => {
88
+ const { refreshToken } = req.body || {};
89
+ if (!refreshToken) {
90
+ return res
91
+ .status(401)
92
+ .json({
93
+ error: "Invalid refresh token",
94
+ code: "UNAUTHORIZED",
95
+ timestamp: new Date().toISOString(),
96
+ });
97
+ }
98
+ res.json({
99
+ accessToken: "access-" + randomUUID(),
100
+ refreshToken: "refresh-" + randomUUID(),
101
+ expiresIn: 3600,
102
+ user: users[0],
103
+ });
104
+ });
105
+
106
+ // Users list/create
107
+ app.get("/v1/users", (req, res) => {
108
+ const page = Math.max(1, parseInt(String(req.query.page ?? "1"), 10) || 1);
109
+ const limit = Math.min(
110
+ 100,
111
+ Math.max(1, parseInt(String(req.query.limit ?? "20"), 10) || 20)
112
+ );
113
+ const search = String(req.query.search ?? "").toLowerCase();
114
+ const filtered = search
115
+ ? users.filter((u) =>
116
+ [u.email, u.firstName, u.lastName].some((v) =>
117
+ (v ?? "").toLowerCase().includes(search)
118
+ )
119
+ )
120
+ : users;
121
+
122
+ const start = (page - 1) * limit;
123
+ const data = filtered.slice(start, start + limit);
124
+ const total = filtered.length;
125
+ const totalPages = Math.max(1, Math.ceil(total / limit));
126
+
127
+ res.json({ data, pagination: { page, limit, total, totalPages } });
128
+ });
129
+
130
+ app.post("/v1/users", (req, res) => {
131
+ const { email, password, firstName, lastName, role } = req.body || {};
132
+ if (!email || !password || !firstName || !lastName) {
133
+ return res
134
+ .status(400)
135
+ .json({
136
+ error: "Missing required fields",
137
+ code: "BAD_REQUEST",
138
+ timestamp: new Date().toISOString(),
139
+ });
140
+ }
141
+ if (users.some((u) => u.email === email)) {
142
+ return res
143
+ .status(409)
144
+ .json({
145
+ error: "User already exists",
146
+ code: "CONFLICT",
147
+ timestamp: new Date().toISOString(),
148
+ });
149
+ }
150
+ const now = new Date().toISOString();
151
+ const user: User = {
152
+ id: randomUUID(),
153
+ email,
154
+ firstName,
155
+ lastName,
156
+ role: (role as Role) ?? "user",
157
+ isActive: true,
158
+ createdAt: now,
159
+ updatedAt: now,
160
+ };
161
+ users.push(user);
162
+ res.status(201).json(user);
163
+ });
164
+
165
+ // Users get/update/delete by id
166
+ app.get("/v1/users/:userId", (req, res) => {
167
+ const user = users.find((u) => u.id === req.params.userId);
168
+ if (!user)
169
+ return res
170
+ .status(404)
171
+ .json({
172
+ error: "User not found",
173
+ code: "NOT_FOUND",
174
+ timestamp: new Date().toISOString(),
175
+ });
176
+ res.json(user);
177
+ });
178
+
179
+ app.put("/v1/users/:userId", (req, res) => {
180
+ const user = users.find((u) => u.id === req.params.userId);
181
+ if (!user)
182
+ return res
183
+ .status(404)
184
+ .json({
185
+ error: "User not found",
186
+ code: "NOT_FOUND",
187
+ timestamp: new Date().toISOString(),
188
+ });
189
+ const { firstName, lastName, role, isActive } = req.body || {};
190
+ if (typeof firstName === "string") user.firstName = firstName;
191
+ if (typeof lastName === "string") user.lastName = lastName;
192
+ if (role === "user" || role === "admin" || role === "moderator")
193
+ user.role = role;
194
+ if (typeof isActive === "boolean") user.isActive = isActive;
195
+ user.updatedAt = new Date().toISOString();
196
+ res.json(user);
197
+ });
198
+
199
+ app.delete("/v1/users/:userId", (req, res) => {
200
+ const index = users.findIndex((u) => u.id === req.params.userId);
201
+ if (index === -1)
202
+ return res
203
+ .status(404)
204
+ .json({
205
+ error: "User not found",
206
+ code: "NOT_FOUND",
207
+ timestamp: new Date().toISOString(),
208
+ });
209
+ users.splice(index, 1);
210
+ res.status(204).send();
211
+ });
212
+
213
+ const port = Number(process.env.PORT || 5050);
214
+ app.listen(port, () => {
215
+ // eslint-disable-next-line no-console
216
+ console.log(`Demo API listening at http://localhost:${port}/v1`);
217
+ });