nuxt-users 1.1.1 → 1.1.2
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/README.md +2 -0
- package/data/default.sqlite3 +0 -0
- package/dist/module.d.mts +8 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +72 -30
- package/dist/runtime/server/utils/db.js +15 -3
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ npx nuxt-users migrate
|
|
|
37
37
|
npx nuxt-users create-user user@example.com "John Doe" password123
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
> **Note**: For SQLite (default), the module automatically creates the database file. If installation hangs with other databases, add `skipDatabaseChecks: true` to your configuration. See [Troubleshooting](/docs/troubleshooting/hanging-during-install) for more details.
|
|
41
|
+
|
|
40
42
|
## Documentation
|
|
41
43
|
|
|
42
44
|
📚 **Full documentation is available at: [docs/](/docs/)**
|
|
Binary file
|
package/dist/module.d.mts
CHANGED
|
@@ -8,6 +8,9 @@ type DatabaseConfig = {
|
|
|
8
8
|
user?: string;
|
|
9
9
|
password?: string;
|
|
10
10
|
database?: string;
|
|
11
|
+
connectTimeout?: number;
|
|
12
|
+
acquireTimeout?: number;
|
|
13
|
+
connectionTimeoutMillis?: number;
|
|
11
14
|
};
|
|
12
15
|
interface ModuleOptions {
|
|
13
16
|
connector?: {
|
|
@@ -29,6 +32,11 @@ interface ModuleOptions {
|
|
|
29
32
|
* @default 'http://localhost:3000' // Example, will be set in module defaults
|
|
30
33
|
*/
|
|
31
34
|
passwordResetBaseUrl?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Skip database checks during module setup to prevent hanging
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
skipDatabaseChecks?: boolean;
|
|
32
40
|
}
|
|
33
41
|
interface MailerOptions {
|
|
34
42
|
host: string;
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addServerHandler, addPlugin, addComponent } from '@nuxt/kit';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
|
-
import { checkUsersTableExists, checkPersonalAccessTokensTableExists, checkPasswordResetTokensTableExists
|
|
3
|
+
import { hasAnyUsers, checkUsersTableExists, checkPersonalAccessTokensTableExists, checkPasswordResetTokensTableExists } from '../dist/runtime/server/utils/db.js';
|
|
4
4
|
import { getAppliedMigrations } from '../dist/runtime/server/utils/migrate.js';
|
|
5
|
+
import { promises } from 'node:fs';
|
|
6
|
+
import { dirname } from 'node:path';
|
|
5
7
|
|
|
6
8
|
const defaultOptions = {
|
|
7
9
|
connector: {
|
|
@@ -30,8 +32,39 @@ const defaultOptions = {
|
|
|
30
32
|
from: '"Nuxt Users Module" <noreply@example.com>'
|
|
31
33
|
}
|
|
32
34
|
},
|
|
33
|
-
passwordResetBaseUrl: "http://localhost:3000"
|
|
35
|
+
passwordResetBaseUrl: "http://localhost:3000",
|
|
34
36
|
// Added
|
|
37
|
+
// Add option to disable database checks during setup
|
|
38
|
+
skipDatabaseChecks: false
|
|
39
|
+
};
|
|
40
|
+
const runWithTimeout = async (operation, timeoutMs = 5e3) => {
|
|
41
|
+
return Promise.race([
|
|
42
|
+
operation(),
|
|
43
|
+
new Promise((resolve) => {
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
console.warn("[Nuxt Users DB] \u26A0\uFE0F Database operation timed out after", timeoutMs, "ms");
|
|
46
|
+
resolve(null);
|
|
47
|
+
}, timeoutMs);
|
|
48
|
+
})
|
|
49
|
+
]);
|
|
50
|
+
};
|
|
51
|
+
const ensureSqliteDatabaseExists = async (options) => {
|
|
52
|
+
if (options.connector?.name === "sqlite" && options.connector.options.path) {
|
|
53
|
+
const dbPath = options.connector.options.path;
|
|
54
|
+
try {
|
|
55
|
+
await promises.access(dbPath);
|
|
56
|
+
console.log(`[Nuxt Users DB] \u2139\uFE0F SQLite database exists: ${dbPath}`);
|
|
57
|
+
} catch {
|
|
58
|
+
try {
|
|
59
|
+
const dbDir = dirname(dbPath);
|
|
60
|
+
await promises.mkdir(dbDir, { recursive: true });
|
|
61
|
+
console.log(`[Nuxt Users DB] \u2139\uFE0F Created SQLite database directory: ${dbDir}`);
|
|
62
|
+
console.log(`[Nuxt Users DB] \u2139\uFE0F SQLite database will be created at: ${dbPath}`);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.warn(`[Nuxt Users DB] \u26A0\uFE0F Failed to create database directory: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
35
68
|
};
|
|
36
69
|
const module = defineNuxtModule({
|
|
37
70
|
meta: {
|
|
@@ -42,29 +75,20 @@ const module = defineNuxtModule({
|
|
|
42
75
|
defaults: defaultOptions,
|
|
43
76
|
async setup(options, nuxt) {
|
|
44
77
|
const resolver = createResolver(import.meta.url);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
console.warn("[Nuxt Users DB] \u26A0\uFE0F Users table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
60
|
-
}
|
|
61
|
-
const hasPersonalAccessTokensTable = await checkPersonalAccessTokensTableExists(options);
|
|
62
|
-
if (!hasPersonalAccessTokensTable) {
|
|
63
|
-
console.warn("[Nuxt Users DB] \u26A0\uFE0F Personal access tokens table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
64
|
-
}
|
|
65
|
-
const hasPasswordResetTokensTable = await checkPasswordResetTokensTableExists(options);
|
|
66
|
-
if (!hasPasswordResetTokensTable) {
|
|
67
|
-
console.warn("[Nuxt Users DB] \u26A0\uFE0F Password reset tokens table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
78
|
+
await ensureSqliteDatabaseExists(options);
|
|
79
|
+
if (!options.skipDatabaseChecks) {
|
|
80
|
+
const appliedMigrations = await runWithTimeout(() => getAppliedMigrations(options)) || [];
|
|
81
|
+
const requiredMigrations = [
|
|
82
|
+
"create_migrations_table",
|
|
83
|
+
"create_users_table",
|
|
84
|
+
"create_personal_access_tokens_table",
|
|
85
|
+
"create_password_reset_tokens_table"
|
|
86
|
+
];
|
|
87
|
+
const missingMigrations = requiredMigrations.filter((migration) => !appliedMigrations.includes(migration));
|
|
88
|
+
if (missingMigrations.length > 0) {
|
|
89
|
+
console.warn(`[Nuxt Users DB] \u26A0\uFE0F Missing migrations: ${missingMigrations.join(", ")}`);
|
|
90
|
+
console.warn("[Nuxt Users DB] \u26A0\uFE0F Run migrations with: npx nuxt-users-migrate");
|
|
91
|
+
}
|
|
68
92
|
}
|
|
69
93
|
const runtimeConfigOptions = defu(options, nuxt.options.runtimeConfig.nuxtUsers || {}, defaultOptions);
|
|
70
94
|
nuxt.options.runtimeConfig.nuxtUsers = {
|
|
@@ -75,19 +99,37 @@ const module = defineNuxtModule({
|
|
|
75
99
|
passwordResetTokens: options.tables?.passwordResetTokens || "password_reset_tokens"
|
|
76
100
|
}
|
|
77
101
|
};
|
|
102
|
+
let hasUsersTable = false;
|
|
103
|
+
let hasPersonalAccessTokensTable = false;
|
|
104
|
+
let hasPasswordResetTokensTable = false;
|
|
105
|
+
if (!options.skipDatabaseChecks) {
|
|
106
|
+
hasUsersTable = await runWithTimeout(() => checkUsersTableExists(options)) || false;
|
|
107
|
+
if (!hasUsersTable) {
|
|
108
|
+
console.warn("[Nuxt Users DB] \u26A0\uFE0F Users table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
109
|
+
}
|
|
110
|
+
hasPersonalAccessTokensTable = await runWithTimeout(() => checkPersonalAccessTokensTableExists(options)) || false;
|
|
111
|
+
if (!hasPersonalAccessTokensTable) {
|
|
112
|
+
console.warn("[Nuxt Users DB] \u26A0\uFE0F Personal access tokens table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
113
|
+
}
|
|
114
|
+
hasPasswordResetTokensTable = await runWithTimeout(() => checkPasswordResetTokensTableExists(options)) || false;
|
|
115
|
+
if (!hasPasswordResetTokensTable) {
|
|
116
|
+
console.warn("[Nuxt Users DB] \u26A0\uFE0F Password reset tokens table does not exist, you should run the migration script to create it by running: npx nuxt-users-migrate");
|
|
117
|
+
}
|
|
118
|
+
const hasUsers = await runWithTimeout(() => hasAnyUsers(options)) || false;
|
|
119
|
+
if (!hasUsers) {
|
|
120
|
+
console.warn('[Nuxt Users DB] \u26A0\uFE0F No users found! Create a default user by running: npx nuxt-users-create-user rrd@example.com "John Doe" mypassword123');
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
console.log("[Nuxt Users DB] \u2139\uFE0F Skipping database checks during setup");
|
|
124
|
+
}
|
|
78
125
|
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
79
126
|
nuxt.options.runtimeConfig.public.nuxtUsers = {
|
|
80
127
|
tables: {
|
|
81
128
|
users: hasUsersTable,
|
|
82
129
|
personalAccessTokens: hasPersonalAccessTokensTable,
|
|
83
130
|
passwordResetTokens: hasPasswordResetTokensTable
|
|
84
|
-
// Use stored value
|
|
85
131
|
}
|
|
86
132
|
};
|
|
87
|
-
const hasUsers = await hasAnyUsers(options);
|
|
88
|
-
if (!hasUsers) {
|
|
89
|
-
console.warn('[Nuxt Users DB] \u26A0\uFE0F No users found! Create a default user by running: npx nuxt-users-create-user rrd@example.com "John Doe" mypassword123');
|
|
90
|
-
}
|
|
91
133
|
addServerHandler({
|
|
92
134
|
route: "/api/login",
|
|
93
135
|
method: "post",
|
|
@@ -18,7 +18,19 @@ export const useDb = async (options) => {
|
|
|
18
18
|
if (connectorName !== "sqlite") {
|
|
19
19
|
delete connectorOptions.path;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
if (connectorName === "mysql") {
|
|
22
|
+
connectorOptions.connectTimeout = 5e3;
|
|
23
|
+
connectorOptions.acquireTimeout = 5e3;
|
|
24
|
+
}
|
|
25
|
+
if (connectorName === "postgresql") {
|
|
26
|
+
connectorOptions.connectionTimeoutMillis = 5e3;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return createDatabase(connector(connectorOptions));
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.warn(`[Nuxt Users DB] \u26A0\uFE0F Failed to connect to ${connectorName} database:`, error instanceof Error ? error.message : "Unknown error");
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
22
34
|
};
|
|
23
35
|
export const checkPasswordResetTokensTableExists = async (options) => {
|
|
24
36
|
return await checkTableExists(options, options.tables.passwordResetTokens);
|
|
@@ -30,8 +42,8 @@ export const checkPersonalAccessTokensTableExists = async (options) => {
|
|
|
30
42
|
return await checkTableExists(options, options.tables.personalAccessTokens);
|
|
31
43
|
};
|
|
32
44
|
export const checkTableExists = async (options, tableName) => {
|
|
33
|
-
const db = await useDb(options);
|
|
34
45
|
try {
|
|
46
|
+
const db = await useDb(options);
|
|
35
47
|
await db.sql`SELECT 1 FROM {${tableName}} LIMIT 1`;
|
|
36
48
|
return true;
|
|
37
49
|
} catch {
|
|
@@ -39,8 +51,8 @@ export const checkTableExists = async (options, tableName) => {
|
|
|
39
51
|
}
|
|
40
52
|
};
|
|
41
53
|
export const hasAnyUsers = async (options) => {
|
|
42
|
-
const db = await useDb(options);
|
|
43
54
|
try {
|
|
55
|
+
const db = await useDb(options);
|
|
44
56
|
const users = await db.sql`SELECT COUNT(*) as count FROM {${options.tables.users}}`;
|
|
45
57
|
return users.rows?.[0]?.count > 0;
|
|
46
58
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-users",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Nuxt users module",
|
|
5
5
|
"repository": "rrd108/nuxt-users",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
|
-
"src/cli"
|
|
24
|
+
"src/cli",
|
|
25
|
+
"data"
|
|
25
26
|
],
|
|
26
27
|
"bin": {
|
|
27
28
|
"nuxt-users": "./src/cli/main.ts"
|
|
28
29
|
},
|
|
29
30
|
"scripts": {
|
|
30
|
-
"prepack": "nuxt-module-build build",
|
|
31
|
+
"prepack": "npm run db:create-empty-sqlite && nuxt-module-build build",
|
|
31
32
|
"predev": "node -v | grep -q 'v22' || (echo 'Please use Node.js v22 for deployment' && exit 1)",
|
|
32
33
|
"dev": "npm run dev:prepare && nuxi dev playground",
|
|
33
34
|
"dev:build": "nuxi build playground",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"db:create-password-reset-tokens-table": "tsx src/cli/create-password-reset-tokens-table.ts",
|
|
50
51
|
"db:create-migrations-table": "tsx src/cli/create-migrations-table.ts",
|
|
51
52
|
"db:migrate": "tsx src/cli/migrate.ts",
|
|
53
|
+
"db:create-empty-sqlite": "node scripts/create-empty-sqlite.js",
|
|
52
54
|
"docs:dev": "vitepress dev docs",
|
|
53
55
|
"docs:build": "vitepress build docs",
|
|
54
56
|
"docs:preview": "vitepress preview docs",
|