@olasphe/mysql 1.0.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/dist/index.d.ts +23 -0
- package/dist/index.js +132 -0
- package/package.json +28 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IUserRepository, ISessionRepository, User, Session } from '@olasubomimk/core';
|
|
2
|
+
import mysql from 'mysql2/promise';
|
|
3
|
+
export declare class MySQLUserRepository implements IUserRepository {
|
|
4
|
+
private pool;
|
|
5
|
+
constructor(pool: mysql.Pool);
|
|
6
|
+
create(data: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User>;
|
|
7
|
+
findByEmail(email: string): Promise<User | null>;
|
|
8
|
+
findById(id: string): Promise<User | null>;
|
|
9
|
+
update(id: string, updates: Partial<User>): Promise<User>;
|
|
10
|
+
delete(id: string): Promise<void>;
|
|
11
|
+
private map;
|
|
12
|
+
}
|
|
13
|
+
export declare class MySQLSessionRepository implements ISessionRepository {
|
|
14
|
+
private pool;
|
|
15
|
+
constructor(pool: mysql.Pool);
|
|
16
|
+
create(session: Session): Promise<Session>;
|
|
17
|
+
findByToken(token: string): Promise<Session | null>;
|
|
18
|
+
deleteByToken(token: string): Promise<void>;
|
|
19
|
+
revokeAllForUser(userId: string): Promise<void>;
|
|
20
|
+
revokeOtherSessions(userId: string, currentSessionId: string): Promise<void>;
|
|
21
|
+
private map;
|
|
22
|
+
}
|
|
23
|
+
export declare function createTables(pool: mysql.Pool): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MySQLSessionRepository = exports.MySQLUserRepository = void 0;
|
|
4
|
+
exports.createTables = createTables;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
class MySQLUserRepository {
|
|
7
|
+
constructor(pool) {
|
|
8
|
+
this.pool = pool;
|
|
9
|
+
}
|
|
10
|
+
async create(data) {
|
|
11
|
+
const id = (0, crypto_1.randomUUID)();
|
|
12
|
+
const now = new Date();
|
|
13
|
+
// Check table exists? Assumed migrated.
|
|
14
|
+
await this.pool.execute(`INSERT INTO users (id, email, passwordHash, isVerified, verificationToken, verificationExpires, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [id, data.email, data.passwordHash, data.isVerified, data.verificationToken || null, data.verificationExpires || null, now, now]);
|
|
15
|
+
return {
|
|
16
|
+
id,
|
|
17
|
+
...data,
|
|
18
|
+
isVerified: data.isVerified ?? false,
|
|
19
|
+
createdAt: now,
|
|
20
|
+
updatedAt: now
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
async findByEmail(email) {
|
|
24
|
+
const [rows] = await this.pool.execute('SELECT * FROM users WHERE email = ?', [email]);
|
|
25
|
+
if (rows.length === 0)
|
|
26
|
+
return null;
|
|
27
|
+
return this.map(rows[0]);
|
|
28
|
+
}
|
|
29
|
+
async findById(id) {
|
|
30
|
+
const [rows] = await this.pool.execute('SELECT * FROM users WHERE id = ?', [id]);
|
|
31
|
+
if (rows.length === 0)
|
|
32
|
+
return null;
|
|
33
|
+
return this.map(rows[0]);
|
|
34
|
+
}
|
|
35
|
+
async update(id, updates) {
|
|
36
|
+
const setClause = [];
|
|
37
|
+
const values = [];
|
|
38
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
39
|
+
if (key === 'id' || key === 'createdAt')
|
|
40
|
+
continue;
|
|
41
|
+
setClause.push(`${key} = ?`);
|
|
42
|
+
values.push(value);
|
|
43
|
+
}
|
|
44
|
+
if (setClause.length === 0) {
|
|
45
|
+
return (await this.findById(id));
|
|
46
|
+
}
|
|
47
|
+
setClause.push('updatedAt = ?');
|
|
48
|
+
values.push(new Date());
|
|
49
|
+
values.push(id); // For WHERE clause
|
|
50
|
+
await this.pool.execute(`UPDATE users SET ${setClause.join(', ')} WHERE id = ?`, values);
|
|
51
|
+
return (await this.findById(id));
|
|
52
|
+
}
|
|
53
|
+
async delete(id) {
|
|
54
|
+
await this.pool.execute('DELETE FROM users WHERE id = ?', [id]);
|
|
55
|
+
}
|
|
56
|
+
map(row) {
|
|
57
|
+
return {
|
|
58
|
+
id: row.id,
|
|
59
|
+
email: row.email,
|
|
60
|
+
passwordHash: row.passwordHash,
|
|
61
|
+
isVerified: Boolean(row.isVerified), // MySQL often returns 1/0
|
|
62
|
+
verificationToken: row.verificationToken,
|
|
63
|
+
verificationExpires: row.verificationExpires,
|
|
64
|
+
createdAt: row.createdAt,
|
|
65
|
+
updatedAt: row.updatedAt
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.MySQLUserRepository = MySQLUserRepository;
|
|
70
|
+
class MySQLSessionRepository {
|
|
71
|
+
constructor(pool) {
|
|
72
|
+
this.pool = pool;
|
|
73
|
+
}
|
|
74
|
+
async create(session) {
|
|
75
|
+
await this.pool.execute(`INSERT INTO sessions (id, userId, token, userAgent, ipAddress, expiresAt, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?)`, [session.id, session.userId, session.token, session.userAgent || null, session.ipAddress || null, session.expiresAt, session.createdAt]);
|
|
76
|
+
return session;
|
|
77
|
+
}
|
|
78
|
+
async findByToken(token) {
|
|
79
|
+
const [rows] = await this.pool.execute('SELECT * FROM sessions WHERE token = ?', [token]);
|
|
80
|
+
if (rows.length === 0)
|
|
81
|
+
return null;
|
|
82
|
+
return this.map(rows[0]);
|
|
83
|
+
}
|
|
84
|
+
async deleteByToken(token) {
|
|
85
|
+
await this.pool.execute('DELETE FROM sessions WHERE token = ?', [token]);
|
|
86
|
+
}
|
|
87
|
+
async revokeAllForUser(userId) {
|
|
88
|
+
await this.pool.execute('DELETE FROM sessions WHERE userId = ?', [userId]);
|
|
89
|
+
}
|
|
90
|
+
async revokeOtherSessions(userId, currentSessionId) {
|
|
91
|
+
await this.pool.execute('DELETE FROM sessions WHERE userId = ? AND id != ?', [userId, currentSessionId]);
|
|
92
|
+
}
|
|
93
|
+
map(row) {
|
|
94
|
+
return {
|
|
95
|
+
id: row.id,
|
|
96
|
+
userId: row.userId,
|
|
97
|
+
token: row.token,
|
|
98
|
+
userAgent: row.userAgent,
|
|
99
|
+
ipAddress: row.ipAddress,
|
|
100
|
+
expiresAt: row.expiresAt,
|
|
101
|
+
createdAt: row.createdAt
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.MySQLSessionRepository = MySQLSessionRepository;
|
|
106
|
+
// Helper to create tables (Basic Migration)
|
|
107
|
+
async function createTables(pool) {
|
|
108
|
+
await pool.execute(`
|
|
109
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
110
|
+
id VARCHAR(36) PRIMARY KEY,
|
|
111
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
112
|
+
passwordHash VARCHAR(255) NOT NULL,
|
|
113
|
+
isVerified BOOLEAN DEFAULT FALSE,
|
|
114
|
+
verificationToken VARCHAR(255),
|
|
115
|
+
verificationExpires DATETIME,
|
|
116
|
+
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
117
|
+
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
118
|
+
)
|
|
119
|
+
`);
|
|
120
|
+
await pool.execute(`
|
|
121
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
122
|
+
id VARCHAR(36) PRIMARY KEY,
|
|
123
|
+
userId VARCHAR(36) NOT NULL,
|
|
124
|
+
token VARCHAR(512) NOT NULL UNIQUE,
|
|
125
|
+
userAgent VARCHAR(255),
|
|
126
|
+
ipAddress VARCHAR(45),
|
|
127
|
+
expiresAt DATETIME NOT NULL,
|
|
128
|
+
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
129
|
+
FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE
|
|
130
|
+
)
|
|
131
|
+
`);
|
|
132
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@olasphe/mysql",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"author": "Auth SDK User <user@example.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/example/auth-sdk-monorepo"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@olasphe/core": "*",
|
|
23
|
+
"mysql2": "^3.0.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.0.0"
|
|
27
|
+
}
|
|
28
|
+
}
|