nuxt-users 1.9.0 → 1.10.0
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.
- package/CHANGELOG.md +13 -0
- package/dist/cli.mjs +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +22 -2
- package/dist/runtime/server/api/nuxt-users/[id].delete.d.ts +4 -0
- package/dist/runtime/server/api/nuxt-users/[id].delete.js +23 -0
- package/dist/runtime/server/api/nuxt-users/[id].get.js +32 -0
- package/dist/runtime/server/api/nuxt-users/[id].patch.d.ts +4 -0
- package/dist/runtime/server/api/nuxt-users/[id].patch.js +24 -0
- package/dist/runtime/server/api/nuxt-users/index.post.d.ts +4 -0
- package/dist/runtime/server/api/nuxt-users/index.post.js +29 -0
- package/dist/runtime/server/api/nuxt-users/profile.get.d.ts +4 -0
- package/dist/runtime/server/utils/user.d.ts +12 -0
- package/dist/runtime/server/utils/user.js +54 -0
- package/package.json +1 -1
- /package/dist/runtime/server/api/{user/profile.get.d.ts → nuxt-users/[id].get.d.ts} +0 -0
- /package/dist/runtime/server/api/{user → nuxt-users}/profile.get.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v1.10.0
|
|
5
|
+
|
|
6
|
+
[compare changes](https://github.com/rrd108/nuxt-users/compare/v1.9.0...v1.10.0)
|
|
7
|
+
|
|
8
|
+
### 🚀 Enhancements
|
|
9
|
+
|
|
10
|
+
- Add user CRUD API endpoints ([8cf5e0a](https://github.com/rrd108/nuxt-users/commit/8cf5e0a))
|
|
11
|
+
- Add user API endpoints ([05f326e](https://github.com/rrd108/nuxt-users/commit/05f326e))
|
|
12
|
+
|
|
13
|
+
### ❤️ Contributors
|
|
14
|
+
|
|
15
|
+
- Rrd108 ([@rrd108](https://github.com/rrd108))
|
|
16
|
+
|
|
4
17
|
## v2.0.0
|
|
5
18
|
|
|
6
19
|
[compare changes](https://github.com/rrd108/nuxt-users/compare/v1.8.5...v2.0.0)
|
package/dist/cli.mjs
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -117,15 +117,35 @@ const module = defineNuxtModule({
|
|
|
117
117
|
handler: resolver.resolve("./runtime/server/api/auth/logout.get")
|
|
118
118
|
});
|
|
119
119
|
addServerHandler({
|
|
120
|
-
route: "/api/
|
|
120
|
+
route: "/api/nuxt-users/profile",
|
|
121
121
|
method: "get",
|
|
122
|
-
handler: resolver.resolve("./runtime/server/api/
|
|
122
|
+
handler: resolver.resolve("./runtime/server/api/nuxt-users/profile.get")
|
|
123
123
|
});
|
|
124
124
|
addServerHandler({
|
|
125
125
|
route: "/api/auth/update-password",
|
|
126
126
|
method: "post",
|
|
127
127
|
handler: resolver.resolve("./runtime/server/api/auth/update-password.post")
|
|
128
128
|
});
|
|
129
|
+
addServerHandler({
|
|
130
|
+
route: "/api/nuxt-users",
|
|
131
|
+
method: "post",
|
|
132
|
+
handler: resolver.resolve("./runtime/server/api/nuxt-users/index.post")
|
|
133
|
+
});
|
|
134
|
+
addServerHandler({
|
|
135
|
+
route: "/api/nuxt-users/:id",
|
|
136
|
+
method: "get",
|
|
137
|
+
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].get")
|
|
138
|
+
});
|
|
139
|
+
addServerHandler({
|
|
140
|
+
route: "/api/nuxt-users/:id",
|
|
141
|
+
method: "patch",
|
|
142
|
+
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].patch")
|
|
143
|
+
});
|
|
144
|
+
addServerHandler({
|
|
145
|
+
route: "/api/nuxt-users/:id",
|
|
146
|
+
method: "delete",
|
|
147
|
+
handler: resolver.resolve("./runtime/server/api/nuxt-users/[id].delete")
|
|
148
|
+
});
|
|
129
149
|
nuxt.hook("nitro:config", async (nitroConfig) => {
|
|
130
150
|
nitroConfig.experimental = nitroConfig.experimental || {};
|
|
131
151
|
nitroConfig.experimental.database = true;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createError, defineEventHandler } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { deleteUser } from "../../utils/user.js";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
6
|
+
const options = nuxtUsers;
|
|
7
|
+
const userId = Number(event.context.params?.id);
|
|
8
|
+
if (!userId) {
|
|
9
|
+
throw createError({
|
|
10
|
+
statusCode: 400,
|
|
11
|
+
statusMessage: "Invalid user ID"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await deleteUser(userId, options);
|
|
16
|
+
return { success: true };
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw createError({
|
|
19
|
+
statusCode: 500,
|
|
20
|
+
statusMessage: `Error deleting user: ${error.message}`
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createError, defineEventHandler } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { findUserById } from "../../utils/user.js";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
6
|
+
const options = nuxtUsers;
|
|
7
|
+
const userId = Number(event.context.params?.id);
|
|
8
|
+
if (!userId) {
|
|
9
|
+
throw createError({
|
|
10
|
+
statusCode: 400,
|
|
11
|
+
statusMessage: "Invalid user ID"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const user = await findUserById(userId, options);
|
|
16
|
+
if (!user) {
|
|
17
|
+
throw createError({
|
|
18
|
+
statusCode: 404,
|
|
19
|
+
statusMessage: "User not found"
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return { user };
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error && typeof error === "object" && "statusCode" in error) {
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
throw createError({
|
|
28
|
+
statusCode: 500,
|
|
29
|
+
statusMessage: `Error fetching user: ${error instanceof Error ? error.message : String(error)}`
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createError, defineEventHandler, readBody } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { updateUser } from "../../utils/user.js";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
6
|
+
const options = nuxtUsers;
|
|
7
|
+
const userId = Number(event.context.params?.id);
|
|
8
|
+
if (!userId) {
|
|
9
|
+
throw createError({
|
|
10
|
+
statusCode: 400,
|
|
11
|
+
statusMessage: "Invalid user ID"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const body = await readBody(event);
|
|
15
|
+
try {
|
|
16
|
+
const updatedUser = await updateUser(userId, body, options);
|
|
17
|
+
return { user: updatedUser };
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw createError({
|
|
20
|
+
statusCode: 500,
|
|
21
|
+
statusMessage: `Error updating user: ${error.message}`
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createError, defineEventHandler, readBody } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { createUser } from "../../utils/user.js";
|
|
4
|
+
export default defineEventHandler(async (event) => {
|
|
5
|
+
const { nuxtUsers } = useRuntimeConfig();
|
|
6
|
+
const options = nuxtUsers;
|
|
7
|
+
const body = await readBody(event);
|
|
8
|
+
if (!body.email || !body.name || !body.password) {
|
|
9
|
+
throw createError({
|
|
10
|
+
statusCode: 400,
|
|
11
|
+
statusMessage: "Missing required fields: email, name, password"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const newUser = await createUser({
|
|
16
|
+
email: body.email,
|
|
17
|
+
name: body.name,
|
|
18
|
+
password: body.password,
|
|
19
|
+
role: body.role
|
|
20
|
+
// role is optional
|
|
21
|
+
}, options);
|
|
22
|
+
return { user: newUser };
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw createError({
|
|
25
|
+
statusCode: 500,
|
|
26
|
+
statusMessage: `Error creating user: ${error.message}`
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
@@ -14,6 +14,18 @@ export declare const createUser: (userData: CreateUserParams, options: ModuleOpt
|
|
|
14
14
|
* Finds a user by their email address.
|
|
15
15
|
*/
|
|
16
16
|
export declare const findUserByEmail: (email: string, options: ModuleOptions) => Promise<User | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Finds a user by their ID.
|
|
19
|
+
*/
|
|
20
|
+
export declare const findUserById: <T extends boolean = false>(id: number, options: ModuleOptions, withPass?: T) => Promise<T extends true ? User | null : UserWithoutPassword | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Updates a user's details.
|
|
23
|
+
*/
|
|
24
|
+
export declare const updateUser: (id: number, userData: Partial<User>, options: ModuleOptions) => Promise<UserWithoutPassword>;
|
|
25
|
+
/**
|
|
26
|
+
* Deletes a user by their ID.
|
|
27
|
+
*/
|
|
28
|
+
export declare const deleteUser: (id: number, options: ModuleOptions) => Promise<void>;
|
|
17
29
|
/**
|
|
18
30
|
* Updates a user's password.
|
|
19
31
|
* Hashes the new password before storing.
|
|
@@ -47,6 +47,60 @@ export const findUserByEmail = async (email, options) => {
|
|
|
47
47
|
updated_at: user.updated_at instanceof Date ? user.updated_at.toISOString() : user.updated_at
|
|
48
48
|
};
|
|
49
49
|
};
|
|
50
|
+
export const findUserById = async (id, options, withPass = false) => {
|
|
51
|
+
const db = await useDb(options);
|
|
52
|
+
const usersTable = options.tables.users;
|
|
53
|
+
const result = await db.sql`SELECT * FROM {${usersTable}} WHERE id = ${id}`;
|
|
54
|
+
if (result.rows.length === 0) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const user = result.rows[0];
|
|
58
|
+
const normalizedUser = {
|
|
59
|
+
...user,
|
|
60
|
+
created_at: typeof user.created_at === "object" ? user.created_at.toISOString() : user.created_at,
|
|
61
|
+
updated_at: typeof user.updated_at === "object" ? user.updated_at.toISOString() : user.updated_at
|
|
62
|
+
};
|
|
63
|
+
if (withPass === true) {
|
|
64
|
+
return normalizedUser;
|
|
65
|
+
}
|
|
66
|
+
const { password, ...userWithoutPassword } = normalizedUser;
|
|
67
|
+
return userWithoutPassword;
|
|
68
|
+
};
|
|
69
|
+
export const updateUser = async (id, userData, options) => {
|
|
70
|
+
const db = await useDb(options);
|
|
71
|
+
const usersTable = options.tables.users;
|
|
72
|
+
const currentUser = await findUserById(id, options, true);
|
|
73
|
+
if (!currentUser) {
|
|
74
|
+
throw new Error("User not found.");
|
|
75
|
+
}
|
|
76
|
+
const fieldsToUpdate = { ...userData };
|
|
77
|
+
delete fieldsToUpdate.id;
|
|
78
|
+
delete fieldsToUpdate.password;
|
|
79
|
+
if (Object.keys(fieldsToUpdate).length === 0) {
|
|
80
|
+
const { password, ...user } = currentUser;
|
|
81
|
+
return user;
|
|
82
|
+
}
|
|
83
|
+
for (const [key, value] of Object.entries(fieldsToUpdate)) {
|
|
84
|
+
await db.sql`
|
|
85
|
+
UPDATE {${usersTable}}
|
|
86
|
+
SET ${key} = ${value}, updated_at = CURRENT_TIMESTAMP
|
|
87
|
+
WHERE id = ${id}
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
const updatedUser = await findUserById(id, options);
|
|
91
|
+
if (!updatedUser) {
|
|
92
|
+
throw new Error("Failed to retrieve updated user.");
|
|
93
|
+
}
|
|
94
|
+
return updatedUser;
|
|
95
|
+
};
|
|
96
|
+
export const deleteUser = async (id, options) => {
|
|
97
|
+
const db = await useDb(options);
|
|
98
|
+
const usersTable = options.tables.users;
|
|
99
|
+
const result = await db.sql`DELETE FROM {${usersTable}} WHERE id = ${id}`;
|
|
100
|
+
if (result.rows?.length === 0) {
|
|
101
|
+
throw new Error("User not found or could not be deleted.");
|
|
102
|
+
}
|
|
103
|
+
};
|
|
50
104
|
export const updateUserPassword = async (email, newPassword, options) => {
|
|
51
105
|
const db = await useDb(options);
|
|
52
106
|
const usersTable = options.tables.users;
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|