nuxt-users 1.1.0 → 1.1.1

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 CHANGED
@@ -31,10 +31,10 @@ export default defineNuxtConfig({
31
31
  })
32
32
 
33
33
  # Run migrations
34
- yarn db:migrate
34
+ npx nuxt-users migrate
35
35
 
36
36
  # Create your first user
37
- yarn db:create-user user@example.com "John Doe" password123
37
+ npx nuxt-users create-user user@example.com "John Doe" password123
38
38
  ```
39
39
 
40
40
  ## Documentation
package/dist/module.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
3
  "configKey": "nuxtUsers",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
7
- "unbuild": "3.5.0"
7
+ "unbuild": "2.0.0"
8
8
  }
9
9
  }
package/dist/module.mjs CHANGED
@@ -52,19 +52,19 @@ const module = defineNuxtModule({
52
52
  const missingMigrations = requiredMigrations.filter((migration) => !appliedMigrations.includes(migration));
53
53
  if (missingMigrations.length > 0) {
54
54
  console.warn(`[Nuxt Users DB] \u26A0\uFE0F Missing migrations: ${missingMigrations.join(", ")}`);
55
- console.warn("[Nuxt Users DB] \u26A0\uFE0F Run migrations with: yarn db:migrate");
55
+ console.warn("[Nuxt Users DB] \u26A0\uFE0F Run migrations with: npx nuxt-users-migrate");
56
56
  }
57
57
  const hasUsersTable = await checkUsersTableExists(options);
58
58
  if (!hasUsersTable) {
59
- console.warn("[Nuxt Users DB] \u26A0\uFE0F Users table does not exist, you should run the migration script to create it by running: yarn db:migrate");
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
60
  }
61
61
  const hasPersonalAccessTokensTable = await checkPersonalAccessTokensTableExists(options);
62
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: yarn db:migrate");
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
64
  }
65
65
  const hasPasswordResetTokensTable = await checkPasswordResetTokensTableExists(options);
66
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: yarn db:migrate");
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");
68
68
  }
69
69
  const runtimeConfigOptions = defu(options, nuxt.options.runtimeConfig.nuxtUsers || {}, defaultOptions);
70
70
  nuxt.options.runtimeConfig.nuxtUsers = {
@@ -86,7 +86,7 @@ const module = defineNuxtModule({
86
86
  };
87
87
  const hasUsers = await hasAnyUsers(options);
88
88
  if (!hasUsers) {
89
- console.warn('[Nuxt Users DB] \u26A0\uFE0F No users found! Create a default user by running: yarn db:create-user rrd@example.com "John Doe" mypassword123');
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
90
  }
91
91
  addServerHandler({
92
92
  route: "/api/login",
@@ -1,2 +1,2 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
1
+ declare const _default: import("vue").DefineComponent<{}, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
2
  export default _default;
@@ -1,6 +1,6 @@
1
1
  import type { LoginFormData, LoginFormProps, User } from '../../types.js';
2
2
  declare var __VLS_9: {}, __VLS_11: {}, __VLS_18: {}, __VLS_25: {}, __VLS_32: {}, __VLS_39: {}, __VLS_41: {
3
- error: any;
3
+ error: string;
4
4
  };
5
5
  type __VLS_Slots = {} & {
6
6
  header?: (props: typeof __VLS_9) => any;
@@ -17,7 +17,7 @@ type __VLS_Slots = {} & {
17
17
  } & {
18
18
  'error-message'?: (props: typeof __VLS_41) => any;
19
19
  };
20
- declare const __VLS_component: import("vue").DefineComponent<LoginFormProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
20
+ declare const __VLS_component: import("vue").DefineComponent<LoginFormProps, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
21
21
  error: (error: string) => any;
22
22
  submit: (data: LoginFormData) => any;
23
23
  success: (user: User) => any;
@@ -25,7 +25,10 @@ declare const __VLS_component: import("vue").DefineComponent<LoginFormProps, {},
25
25
  onError?: ((error: string) => any) | undefined;
26
26
  onSubmit?: ((data: LoginFormData) => any) | undefined;
27
27
  onSuccess?: ((user: User) => any) | undefined;
28
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
+ }>, {
29
+ apiEndpoint: string;
30
+ redirectTo: string;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
29
32
  declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
30
33
  export default _default;
31
34
  type __VLS_WithSlots<T, S> = T & {
@@ -1,2 +1,2 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
1
+ declare const _default: import("vue").DefineComponent<{}, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
2
  export default _default;
@@ -1,6 +1,5 @@
1
1
  import { createError, defineEventHandler, readBody, setCookie } from "h3";
2
- import { getConnector } from "../utils/db.js";
3
- import { createDatabase } from "db0";
2
+ import { useDb } from "../utils/db.js";
4
3
  import bcrypt from "bcrypt";
5
4
  import crypto from "node:crypto";
6
5
  import { useRuntimeConfig } from "#imports";
@@ -15,9 +14,7 @@ export default defineEventHandler(async (event) => {
15
14
  }
16
15
  const { nuxtUsers } = useRuntimeConfig();
17
16
  const options = nuxtUsers;
18
- const connectorName = options.connector.name;
19
- const connector = await getConnector(connectorName);
20
- const db = createDatabase(connector(options.connector.options));
17
+ const db = await useDb(options);
21
18
  const usersTable = options.tables.users;
22
19
  const personalAccessTokensTable = options.tables.personalAccessTokens;
23
20
  const userResult = await db.sql`SELECT * FROM {${usersTable}} WHERE email = ${email}`;
@@ -2,8 +2,7 @@ import { createTransport } from "nodemailer";
2
2
  import crypto from "node:crypto";
3
3
  import bcrypt from "bcrypt";
4
4
  import { findUserByEmail, updateUserPassword } from "../utils/user.js";
5
- import { getConnector } from "../utils/db.js";
6
- import { createDatabase } from "db0";
5
+ import { useDb } from "../utils/db.js";
7
6
  const TOKEN_EXPIRATION_HOURS = 1;
8
7
  export const sendPasswordResetLink = async (email, options) => {
9
8
  const user = await findUserByEmail(email, options);
@@ -11,9 +10,7 @@ export const sendPasswordResetLink = async (email, options) => {
11
10
  console.log(`Password reset requested for non-existent email: ${email}`);
12
11
  return;
13
12
  }
14
- const connectorName = options.connector.name;
15
- const connector = await getConnector(connectorName);
16
- const db = createDatabase(connector(options.connector.options));
13
+ const db = await useDb(options);
17
14
  const token = crypto.randomBytes(32).toString("hex");
18
15
  const hashedToken = await bcrypt.hash(token, 10);
19
16
  const passwordResetTokensTable = options.tables.passwordResetTokens;
@@ -48,9 +45,7 @@ export const sendPasswordResetLink = async (email, options) => {
48
45
  }
49
46
  };
50
47
  export const resetPassword = async (token, email, newPassword, options) => {
51
- const connectorName = options.connector.name;
52
- const connector = await getConnector(connectorName);
53
- const db = createDatabase(connector(options.connector.options));
48
+ const db = await useDb(options);
54
49
  const passwordResetTokensTable = options.tables.passwordResetTokens;
55
50
  const tokenRecords = await db.sql`
56
51
  SELECT * FROM {${passwordResetTokensTable}}
@@ -98,9 +93,7 @@ export const resetPassword = async (token, email, newPassword, options) => {
98
93
  return true;
99
94
  };
100
95
  export const deleteExpiredPasswordResetTokens = async (options) => {
101
- const connectorName = options.connector.name;
102
- const connector = await getConnector(connectorName);
103
- const db = createDatabase(connector(options.connector.options));
96
+ const db = await useDb(options);
104
97
  const passwordResetTokensTable = options.tables.passwordResetTokens;
105
98
  const expirationDate = /* @__PURE__ */ new Date();
106
99
  expirationDate.setHours(expirationDate.getHours() - TOKEN_EXPIRATION_HOURS);
@@ -1,9 +1,7 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  export const createMigrationsTable = async (options) => {
4
3
  const connectorName = options.connector.name;
5
- const connector = await getConnector(connectorName);
6
- const db = createDatabase(connector(options.connector.options));
4
+ const db = await useDb(options);
7
5
  const tableName = "migrations";
8
6
  console.log(`[DB:Create Migrations ${connectorName} Table] Creating ${tableName} table with ${connectorName} connector...`);
9
7
  if (connectorName === "sqlite") {
@@ -1,9 +1,7 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  export const createPasswordResetTokensTable = async (options) => {
4
3
  const connectorName = options.connector.name;
5
- const connector = await getConnector(connectorName);
6
- const db = createDatabase(connector(options.connector.options));
4
+ const db = await useDb(options);
7
5
  const tableName = options.tables.passwordResetTokens;
8
6
  console.log(`[DB:Create Password Reset Tokens ${connectorName} Table] Creating ${tableName} table with ${connectorName} connector...`);
9
7
  if (connectorName === "sqlite") {
@@ -1,9 +1,7 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  export const createPersonalAccessTokensTable = async (options) => {
4
3
  const connectorName = options.connector.name;
5
- const connector = await getConnector(connectorName);
6
- const db = createDatabase(connector(options.connector.options));
4
+ const db = await useDb(options);
7
5
  const tableName = options.tables.personalAccessTokens;
8
6
  console.log(`[DB:Create Personal Access Tokens ${connectorName} Table] Creating ${tableName} table with ${connectorName} connector...`);
9
7
  if (connectorName === "sqlite") {
@@ -1,9 +1,7 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  export const createUsersTable = async (options) => {
4
3
  const connectorName = options.connector.name;
5
- const connector = await getConnector(connectorName);
6
- const db = createDatabase(connector(options.connector.options));
4
+ const db = await useDb(options);
7
5
  const tableName = options.tables.users;
8
6
  console.log(`[DB:Create ${connectorName} Users Table] Creating ${tableName}...`);
9
7
  if (connectorName === "sqlite") {
@@ -1,5 +1,6 @@
1
1
  import type { ModuleOptions } from '../../../types.js';
2
2
  export declare const getConnector: (name: string) => Promise<typeof import("db0/connectors/mysql2").default | typeof import("db0/connectors/postgresql").default | typeof import("db0/connectors/better-sqlite3").default>;
3
+ export declare const useDb: (options: ModuleOptions) => Promise<import("db0").Database<import("db0").Connector<Database.Database>>>;
3
4
  export declare const checkPasswordResetTokensTableExists: (options: ModuleOptions) => Promise<boolean>;
4
5
  export declare const checkUsersTableExists: (options: ModuleOptions) => Promise<boolean>;
5
6
  export declare const checkPersonalAccessTokensTableExists: (options: ModuleOptions) => Promise<boolean>;
@@ -11,10 +11,14 @@ export const getConnector = async (name) => {
11
11
  throw new Error(`Unsupported database connector: ${name}`);
12
12
  }
13
13
  };
14
- const useDb = async (options) => {
14
+ export const useDb = async (options) => {
15
15
  const connectorName = options.connector.name;
16
16
  const connector = await getConnector(connectorName);
17
- return createDatabase(connector(options.connector.options));
17
+ const connectorOptions = { ...options.connector.options };
18
+ if (connectorName !== "sqlite") {
19
+ delete connectorOptions.path;
20
+ }
21
+ return createDatabase(connector(connectorOptions));
18
22
  };
19
23
  export const checkPasswordResetTokensTableExists = async (options) => {
20
24
  return await checkTableExists(options, options.tables.passwordResetTokens);
@@ -1,5 +1,4 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  import { createUsersTable } from "./create-users-table.js";
4
3
  import { createPersonalAccessTokensTable } from "./create-personal-access-tokens-table.js";
5
4
  import { createPasswordResetTokensTable } from "./create-password-reset-tokens-table.js";
@@ -23,9 +22,7 @@ const migrations = [
23
22
  }
24
23
  ];
25
24
  export const getAppliedMigrations = async (options) => {
26
- const connectorName = options.connector.name;
27
- const connector = await getConnector(connectorName);
28
- const db = createDatabase(connector(options.connector.options));
25
+ const db = await useDb(options);
29
26
  try {
30
27
  const result = await db.sql`SELECT name FROM migrations ORDER BY id`;
31
28
  return result.rows.map((row) => row.name);
@@ -34,9 +31,7 @@ export const getAppliedMigrations = async (options) => {
34
31
  }
35
32
  };
36
33
  export const markMigrationAsApplied = async (options, migrationName) => {
37
- const connectorName = options.connector.name;
38
- const connector = await getConnector(connectorName);
39
- const db = createDatabase(connector(options.connector.options));
34
+ const db = await useDb(options);
40
35
  await db.sql`INSERT INTO migrations (name) VALUES (${migrationName})`;
41
36
  };
42
37
  export const runMigrations = async (options) => {
@@ -1,10 +1,7 @@
1
- import { createDatabase } from "db0";
2
- import { getConnector } from "./db.js";
1
+ import { useDb } from "./db.js";
3
2
  import bcrypt from "bcrypt";
4
3
  export const createUser = async (userData, options) => {
5
- const connectorName = options.connector.name;
6
- const connector = await getConnector(connectorName);
7
- const db = createDatabase(connector(options.connector.options));
4
+ const db = await useDb(options);
8
5
  const usersTable = options.tables.users;
9
6
  const hashedPassword = await bcrypt.hash(userData.password, 10);
10
7
  await db.sql`
@@ -25,9 +22,7 @@ export const createUser = async (userData, options) => {
25
22
  };
26
23
  };
27
24
  export const findUserByEmail = async (email, options) => {
28
- const connectorName = options.connector.name;
29
- const connector = await getConnector(connectorName);
30
- const db = createDatabase(connector(options.connector.options));
25
+ const db = await useDb(options);
31
26
  const usersTable = options.tables.users;
32
27
  const result = await db.sql`SELECT * FROM {${usersTable}} WHERE email = ${email}`;
33
28
  if (result.rows.length === 0) {
@@ -44,9 +39,7 @@ export const findUserByEmail = async (email, options) => {
44
39
  };
45
40
  };
46
41
  export const updateUserPassword = async (email, newPassword, options) => {
47
- const connectorName = options.connector.name;
48
- const connector = await getConnector(connectorName);
49
- const db = createDatabase(connector(options.connector.options));
42
+ const db = await useDb(options);
50
43
  const usersTable = options.tables.users;
51
44
  const hashedPassword = await bcrypt.hash(newPassword, 10);
52
45
  await db.sql`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-users",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Nuxt users module",
5
5
  "repository": "rrd108/nuxt-users",
6
6
  "license": "MIT",
@@ -20,8 +20,12 @@
20
20
  }
21
21
  },
22
22
  "files": [
23
- "dist"
23
+ "dist",
24
+ "src/cli"
24
25
  ],
26
+ "bin": {
27
+ "nuxt-users": "./src/cli/main.ts"
28
+ },
25
29
  "scripts": {
26
30
  "prepack": "nuxt-module-build build",
27
31
  "predev": "node -v | grep -q 'v22' || (echo 'Please use Node.js v22 for deployment' && exit 1)",
@@ -47,7 +51,8 @@
47
51
  "db:migrate": "tsx src/cli/migrate.ts",
48
52
  "docs:dev": "vitepress dev docs",
49
53
  "docs:build": "vitepress build docs",
50
- "docs:preview": "vitepress preview docs"
54
+ "docs:preview": "vitepress preview docs",
55
+ "docs:deploy": "npm run docs:build && ./scripts/deploy-docs.sh"
51
56
  },
52
57
  "dependencies": {
53
58
  "@nuxt/kit": "^3.17.6",
@@ -55,11 +60,11 @@
55
60
  "@types/pg": "^8.15.4",
56
61
  "bcrypt": "^6.0.0",
57
62
  "better-sqlite3": "^12.2.0",
63
+ "citty": "^0.1.6",
58
64
  "defu": "^6.1.4",
59
65
  "mysql2": "^3.14.2",
60
66
  "nodemailer": "^7.0.5",
61
- "pg": "^8.16.3",
62
- "vitepress": "^1.6.3"
67
+ "pg": "^8.16.3"
63
68
  },
64
69
  "devDependencies": {
65
70
  "@formkit/nuxt": "^1.6.9",
@@ -73,9 +78,10 @@
73
78
  "changelogen": "^0.6.2",
74
79
  "eslint": "^9.30.1",
75
80
  "nuxt": "^3.17.6",
76
- "ts-node": "^10.9.2",
77
81
  "tsx": "^4.20.3",
78
82
  "typescript": "~5.8.3",
83
+ "unbuild": "^2.0.0",
84
+ "vitepress": "^1.6.3",
79
85
  "vitest": "^3.2.4",
80
86
  "vue-tsc": "^3.0.1"
81
87
  }
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from 'citty'
2
+ import { createMigrationsTable } from '../runtime/server/utils/create-migrations-table'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'create-migrations-table',
8
+ description: 'Create the migrations table in the database'
9
+ },
10
+ async run() {
11
+ console.log('[Nuxt Users] Creating migrations table...')
12
+
13
+ const options = getOptionsFromEnv()
14
+
15
+ try {
16
+ await createMigrationsTable(options)
17
+ console.log('[Nuxt Users] Migrations table created successfully!')
18
+ }
19
+ catch (error) {
20
+ console.error('[DB:Create Migrations Table] Error:', error)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from 'citty'
2
+ import { createPasswordResetTokensTable } from '../runtime/server/utils/create-password-reset-tokens-table'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'create-password-reset-tokens-table',
8
+ description: 'Create the password reset tokens table in the database'
9
+ },
10
+ async run() {
11
+ console.log('[Nuxt Users] Creating password reset tokens table...')
12
+
13
+ const options = getOptionsFromEnv()
14
+
15
+ try {
16
+ await createPasswordResetTokensTable(options)
17
+ console.log('[Nuxt Users] Password reset tokens table created successfully!')
18
+ }
19
+ catch (error) {
20
+ console.error('[DB:Create Password Reset Tokens Table] Error:', error)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from 'citty'
2
+ import { createPersonalAccessTokensTable } from '../runtime/server/utils/create-personal-access-tokens-table'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'create-personal-access-tokens-table',
8
+ description: 'Create the personal access tokens table in the database'
9
+ },
10
+ async run() {
11
+ console.log('[Nuxt Users] Creating personal access tokens table...')
12
+
13
+ const options = getOptionsFromEnv()
14
+
15
+ try {
16
+ await createPersonalAccessTokensTable(options)
17
+ console.log('[Nuxt Users] Personal access tokens table created successfully!')
18
+ }
19
+ catch (error) {
20
+ console.error('[DB:Create Personal Access Tokens Table] Error:', error)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,40 @@
1
+ import { defineCommand } from 'citty'
2
+ import { createUser } from '../runtime/server/utils/user'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'create-user',
8
+ description: 'Create a new user in the database'
9
+ },
10
+ args: {
11
+ email: {
12
+ type: 'string',
13
+ description: 'User email address',
14
+ required: true
15
+ },
16
+ name: {
17
+ type: 'string',
18
+ description: 'User full name',
19
+ required: true
20
+ },
21
+ password: {
22
+ type: 'string',
23
+ description: 'User password',
24
+ required: true
25
+ }
26
+ },
27
+ async run({ args }) {
28
+ const { email, name, password } = args
29
+ const options = getOptionsFromEnv()
30
+
31
+ try {
32
+ const user = await createUser({ email, name, password }, options)
33
+ console.log(`[DB:Create User] User created successfully: ${user.email}`)
34
+ }
35
+ catch (error) {
36
+ console.error('[DB:Create User] Error:', error)
37
+ process.exit(1)
38
+ }
39
+ }
40
+ })
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from 'citty'
2
+ import { createUsersTable } from '../runtime/server/utils/create-users-table'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'create-users-table',
8
+ description: 'Create the users table in the database'
9
+ },
10
+ async run() {
11
+ console.log('[Nuxt Users] Creating users table...')
12
+
13
+ const options = getOptionsFromEnv()
14
+
15
+ try {
16
+ await createUsersTable(options)
17
+ console.log('[Nuxt Users] Users table created successfully!')
18
+ }
19
+ catch (error) {
20
+ console.error('[DB:Create Users Table] Error:', error)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ import { defineCommand, runMain } from 'citty'
3
+ import migrate from './migrate'
4
+ import createUser from './create-user'
5
+ import createUsersTable from './create-users-table'
6
+ import createPersonalAccessTokensTable from './create-personal-access-tokens-table'
7
+ import createPasswordResetTokensTable from './create-password-reset-tokens-table'
8
+ import createMigrationsTable from './create-migrations-table'
9
+ import projectInfo from './project-info'
10
+
11
+ const main = defineCommand({
12
+ meta: {
13
+ name: 'nuxt-users',
14
+ description: 'CLI for Nuxt Users Module - Manage users, migrations, and database operations',
15
+ version: '1.1.0'
16
+ },
17
+ subCommands: {
18
+ migrate,
19
+ 'create-user': createUser,
20
+ 'create-users-table': createUsersTable,
21
+ 'create-personal-access-tokens-table': createPersonalAccessTokensTable,
22
+ 'create-password-reset-tokens-table': createPasswordResetTokensTable,
23
+ 'create-migrations-table': createMigrationsTable,
24
+ 'project-info': projectInfo
25
+ }
26
+ })
27
+
28
+ runMain(main)
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from 'citty'
2
+ import { runMigrations } from '../runtime/server/utils/migrate'
3
+ import { getOptionsFromEnv } from './utils'
4
+
5
+ export default defineCommand({
6
+ meta: {
7
+ name: 'migrate',
8
+ description: 'Run database migrations for the Nuxt Users module'
9
+ },
10
+ async run() {
11
+ console.log('[Nuxt Users] Starting migration system...')
12
+
13
+ const options = getOptionsFromEnv()
14
+
15
+ try {
16
+ await runMigrations(options)
17
+ console.log('[Nuxt Users] Migration completed successfully!')
18
+ }
19
+ catch (error) {
20
+ console.error('[Nuxt Users] Migration failed:', error)
21
+ process.exit(1)
22
+ }
23
+ }
24
+ })
@@ -0,0 +1,45 @@
1
+ import { defineCommand } from 'citty'
2
+ import { loadNuxt } from '@nuxt/kit'
3
+
4
+ export default defineCommand({
5
+ meta: {
6
+ name: 'project-info',
7
+ description: 'Get information about the Nuxt project and module configuration'
8
+ },
9
+ async run() {
10
+ try {
11
+ console.log('[Nuxt Users] Loading Nuxt project...')
12
+ const nuxt = await loadNuxt({ cwd: process.cwd() })
13
+
14
+ console.log('✅ Nuxt project loaded successfully!')
15
+ console.log('📁 Source directory:', nuxt.options.srcDir)
16
+ console.log('🌐 Base URL:', nuxt.options.app?.baseURL || '/')
17
+
18
+ // Check if nuxt-users module is configured
19
+ const nuxtUsersConfig = nuxt.options.runtimeConfig?.nuxtUsers
20
+ if (nuxtUsersConfig) {
21
+ console.log('🔧 Nuxt Users module configuration:')
22
+ console.log(' Database connector:', nuxtUsersConfig.connector?.name)
23
+ console.log(' Users table:', nuxtUsersConfig.tables?.users)
24
+ console.log(' Personal access tokens table:', nuxtUsersConfig.tables?.personalAccessTokens)
25
+ console.log(' Password reset tokens table:', nuxtUsersConfig.tables?.passwordResetTokens)
26
+ }
27
+ else {
28
+ console.log('⚠️ Nuxt Users module not configured in runtime config')
29
+ }
30
+
31
+ // Check public runtime config
32
+ const publicConfig = nuxt.options.runtimeConfig?.public?.nuxtUsers
33
+ if (publicConfig) {
34
+ console.log('🌍 Public runtime config:')
35
+ console.log(' Users table exists:', publicConfig.tables?.users)
36
+ console.log(' Personal access tokens table exists:', publicConfig.tables?.personalAccessTokens)
37
+ console.log(' Password reset tokens table exists:', publicConfig.tables?.passwordResetTokens)
38
+ }
39
+ }
40
+ catch (error) {
41
+ console.error('❌ Could not load Nuxt project:', error)
42
+ process.exit(1)
43
+ }
44
+ }
45
+ })
@@ -0,0 +1,70 @@
1
+ import type { ModuleOptions, DatabaseConfig } from '../types'
2
+
3
+ export const defaultOptions: ModuleOptions = {
4
+ connector: {
5
+ name: 'sqlite',
6
+ options: {
7
+ path: './data/default.sqlite3',
8
+ },
9
+ },
10
+ tables: {
11
+ users: 'users',
12
+ personalAccessTokens: 'personal_access_tokens',
13
+ passwordResetTokens: 'password_reset_tokens',
14
+ },
15
+ mailer: {
16
+ host: 'smtp.ethereal.email',
17
+ port: 587,
18
+ secure: false,
19
+ auth: {
20
+ user: 'user@ethereal.email',
21
+ pass: 'password',
22
+ },
23
+ defaults: {
24
+ from: '"Nuxt Users Module" <noreply@example.com>',
25
+ },
26
+ },
27
+ passwordResetBaseUrl: 'http://localhost:3000',
28
+ }
29
+
30
+ export const getOptionsFromEnv = (): ModuleOptions => {
31
+ const connectorName = process.env.DB_CONNECTOR || 'sqlite'
32
+
33
+ let connectorOptions: DatabaseConfig
34
+
35
+ switch (connectorName) {
36
+ case 'sqlite':
37
+ connectorOptions = {
38
+ path: process.env.DB_PATH || './data/default.sqlite3',
39
+ }
40
+ break
41
+ case 'mysql':
42
+ connectorOptions = {
43
+ host: process.env.DB_HOST || 'localhost',
44
+ port: Number.parseInt(process.env.DB_PORT || '3306'),
45
+ user: process.env.DB_USER || 'root',
46
+ password: process.env.DB_PASSWORD || '',
47
+ database: process.env.DB_NAME || 'nuxt_users',
48
+ }
49
+ break
50
+ case 'postgresql':
51
+ connectorOptions = {
52
+ host: process.env.DB_HOST || 'localhost',
53
+ port: Number.parseInt(process.env.DB_PORT || '5432'),
54
+ user: process.env.DB_USER || 'postgres',
55
+ password: process.env.DB_PASSWORD || '',
56
+ database: process.env.DB_NAME || 'nuxt_users',
57
+ }
58
+ break
59
+ default:
60
+ throw new Error(`Unsupported database connector: ${connectorName}`)
61
+ }
62
+
63
+ return {
64
+ ...defaultOptions,
65
+ connector: {
66
+ name: connectorName as 'sqlite' | 'mysql' | 'postgresql',
67
+ options: connectorOptions,
68
+ },
69
+ }
70
+ }