@minecraft-docker/shared 1.6.0 → 1.6.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.
Files changed (261) hide show
  1. package/dist/application/index.d.ts +3 -0
  2. package/dist/application/index.d.ts.map +1 -0
  3. package/dist/application/index.js +5 -0
  4. package/dist/application/index.js.map +1 -0
  5. package/dist/application/ports/inbound/IBackupUseCase.d.ts +69 -0
  6. package/dist/application/ports/inbound/IBackupUseCase.d.ts.map +1 -0
  7. package/dist/application/ports/inbound/IBackupUseCase.js +2 -0
  8. package/dist/application/ports/inbound/IBackupUseCase.js.map +1 -0
  9. package/dist/application/ports/inbound/ICreateServerUseCase.d.ts +32 -0
  10. package/dist/application/ports/inbound/ICreateServerUseCase.d.ts.map +1 -0
  11. package/dist/application/ports/inbound/ICreateServerUseCase.js +2 -0
  12. package/dist/application/ports/inbound/ICreateServerUseCase.js.map +1 -0
  13. package/dist/application/ports/inbound/IDeleteServerUseCase.d.ts +26 -0
  14. package/dist/application/ports/inbound/IDeleteServerUseCase.d.ts.map +1 -0
  15. package/dist/application/ports/inbound/IDeleteServerUseCase.js +2 -0
  16. package/dist/application/ports/inbound/IDeleteServerUseCase.js.map +1 -0
  17. package/dist/application/ports/inbound/IPlayerLookupUseCase.d.ts +47 -0
  18. package/dist/application/ports/inbound/IPlayerLookupUseCase.d.ts.map +1 -0
  19. package/dist/application/ports/inbound/IPlayerLookupUseCase.js +2 -0
  20. package/dist/application/ports/inbound/IPlayerLookupUseCase.js.map +1 -0
  21. package/dist/application/ports/inbound/IServerStatusUseCase.d.ts +34 -0
  22. package/dist/application/ports/inbound/IServerStatusUseCase.d.ts.map +1 -0
  23. package/dist/application/ports/inbound/IServerStatusUseCase.js +2 -0
  24. package/dist/application/ports/inbound/IServerStatusUseCase.js.map +1 -0
  25. package/dist/application/ports/inbound/IWorldManagementUseCase.d.ts +97 -0
  26. package/dist/application/ports/inbound/IWorldManagementUseCase.d.ts.map +1 -0
  27. package/dist/application/ports/inbound/IWorldManagementUseCase.js +2 -0
  28. package/dist/application/ports/inbound/IWorldManagementUseCase.js.map +1 -0
  29. package/dist/application/ports/inbound/index.d.ts +7 -0
  30. package/dist/application/ports/inbound/index.d.ts.map +1 -0
  31. package/dist/application/ports/inbound/index.js +2 -0
  32. package/dist/application/ports/inbound/index.js.map +1 -0
  33. package/dist/application/ports/index.d.ts +3 -0
  34. package/dist/application/ports/index.d.ts.map +1 -0
  35. package/dist/application/ports/index.js +2 -0
  36. package/dist/application/ports/index.js.map +1 -0
  37. package/dist/application/ports/outbound/IDocProvider.d.ts +73 -0
  38. package/dist/application/ports/outbound/IDocProvider.d.ts.map +1 -0
  39. package/dist/application/ports/outbound/IDocProvider.js +2 -0
  40. package/dist/application/ports/outbound/IDocProvider.js.map +1 -0
  41. package/dist/application/ports/outbound/IModSourcePort.d.ts +71 -0
  42. package/dist/application/ports/outbound/IModSourcePort.d.ts.map +1 -0
  43. package/dist/application/ports/outbound/IModSourcePort.js +19 -0
  44. package/dist/application/ports/outbound/IModSourcePort.js.map +1 -0
  45. package/dist/application/ports/outbound/IPromptPort.d.ts +148 -0
  46. package/dist/application/ports/outbound/IPromptPort.d.ts.map +1 -0
  47. package/dist/application/ports/outbound/IPromptPort.js +2 -0
  48. package/dist/application/ports/outbound/IPromptPort.js.map +1 -0
  49. package/dist/application/ports/outbound/IServerRepository.d.ts +54 -0
  50. package/dist/application/ports/outbound/IServerRepository.d.ts.map +1 -0
  51. package/dist/application/ports/outbound/IServerRepository.js +2 -0
  52. package/dist/application/ports/outbound/IServerRepository.js.map +1 -0
  53. package/dist/application/ports/outbound/IServiceManagerPort.d.ts +115 -0
  54. package/dist/application/ports/outbound/IServiceManagerPort.d.ts.map +1 -0
  55. package/dist/application/ports/outbound/IServiceManagerPort.js +2 -0
  56. package/dist/application/ports/outbound/IServiceManagerPort.js.map +1 -0
  57. package/dist/application/ports/outbound/IShellPort.d.ts +114 -0
  58. package/dist/application/ports/outbound/IShellPort.d.ts.map +1 -0
  59. package/dist/application/ports/outbound/IShellPort.js +2 -0
  60. package/dist/application/ports/outbound/IShellPort.js.map +1 -0
  61. package/dist/application/ports/outbound/IUserRepository.d.ts +42 -0
  62. package/dist/application/ports/outbound/IUserRepository.d.ts.map +1 -0
  63. package/dist/application/ports/outbound/IUserRepository.js +2 -0
  64. package/dist/application/ports/outbound/IUserRepository.js.map +1 -0
  65. package/dist/application/ports/outbound/IWorldRepository.d.ts +90 -0
  66. package/dist/application/ports/outbound/IWorldRepository.d.ts.map +1 -0
  67. package/dist/application/ports/outbound/IWorldRepository.js +2 -0
  68. package/dist/application/ports/outbound/IWorldRepository.js.map +1 -0
  69. package/dist/application/ports/outbound/index.d.ts +9 -0
  70. package/dist/application/ports/outbound/index.d.ts.map +1 -0
  71. package/dist/application/ports/outbound/index.js +2 -0
  72. package/dist/application/ports/outbound/index.js.map +1 -0
  73. package/dist/application/use-cases/BackupUseCase.d.ts +35 -0
  74. package/dist/application/use-cases/BackupUseCase.d.ts.map +1 -0
  75. package/dist/application/use-cases/BackupUseCase.js +222 -0
  76. package/dist/application/use-cases/BackupUseCase.js.map +1 -0
  77. package/dist/application/use-cases/CreateServerUseCase.d.ts +22 -0
  78. package/dist/application/use-cases/CreateServerUseCase.d.ts.map +1 -0
  79. package/dist/application/use-cases/CreateServerUseCase.js +144 -0
  80. package/dist/application/use-cases/CreateServerUseCase.js.map +1 -0
  81. package/dist/application/use-cases/DeleteServerUseCase.d.ts +24 -0
  82. package/dist/application/use-cases/DeleteServerUseCase.d.ts.map +1 -0
  83. package/dist/application/use-cases/DeleteServerUseCase.js +108 -0
  84. package/dist/application/use-cases/DeleteServerUseCase.js.map +1 -0
  85. package/dist/application/use-cases/PlayerLookupUseCase.d.ts +23 -0
  86. package/dist/application/use-cases/PlayerLookupUseCase.d.ts.map +1 -0
  87. package/dist/application/use-cases/PlayerLookupUseCase.js +130 -0
  88. package/dist/application/use-cases/PlayerLookupUseCase.js.map +1 -0
  89. package/dist/application/use-cases/ServerStatusUseCase.d.ts +30 -0
  90. package/dist/application/use-cases/ServerStatusUseCase.d.ts.map +1 -0
  91. package/dist/application/use-cases/ServerStatusUseCase.js +117 -0
  92. package/dist/application/use-cases/ServerStatusUseCase.js.map +1 -0
  93. package/dist/application/use-cases/WorldManagementUseCase.d.ts +50 -0
  94. package/dist/application/use-cases/WorldManagementUseCase.d.ts.map +1 -0
  95. package/dist/application/use-cases/WorldManagementUseCase.js +571 -0
  96. package/dist/application/use-cases/WorldManagementUseCase.js.map +1 -0
  97. package/dist/application/use-cases/index.d.ts +7 -0
  98. package/dist/application/use-cases/index.d.ts.map +1 -0
  99. package/dist/application/use-cases/index.js +7 -0
  100. package/dist/application/use-cases/index.js.map +1 -0
  101. package/dist/docker/index.d.ts +125 -0
  102. package/dist/docker/index.d.ts.map +1 -0
  103. package/dist/docker/index.js +557 -0
  104. package/dist/docker/index.js.map +1 -0
  105. package/dist/domain/entities/Server.d.ts +77 -0
  106. package/dist/domain/entities/Server.d.ts.map +1 -0
  107. package/dist/domain/entities/Server.js +138 -0
  108. package/dist/domain/entities/Server.js.map +1 -0
  109. package/dist/domain/entities/User.d.ts +77 -0
  110. package/dist/domain/entities/User.d.ts.map +1 -0
  111. package/dist/domain/entities/User.js +121 -0
  112. package/dist/domain/entities/User.js.map +1 -0
  113. package/dist/domain/entities/World.d.ts +76 -0
  114. package/dist/domain/entities/World.d.ts.map +1 -0
  115. package/dist/domain/entities/World.js +141 -0
  116. package/dist/domain/entities/World.js.map +1 -0
  117. package/dist/domain/entities/index.d.ts +4 -0
  118. package/dist/domain/entities/index.d.ts.map +1 -0
  119. package/dist/domain/entities/index.js +4 -0
  120. package/dist/domain/entities/index.js.map +1 -0
  121. package/dist/domain/index.d.ts +3 -0
  122. package/dist/domain/index.d.ts.map +1 -0
  123. package/dist/domain/index.js +7 -0
  124. package/dist/domain/index.js.map +1 -0
  125. package/dist/domain/mod/ModDependency.d.ts +18 -0
  126. package/dist/domain/mod/ModDependency.d.ts.map +1 -0
  127. package/dist/domain/mod/ModDependency.js +5 -0
  128. package/dist/domain/mod/ModDependency.js.map +1 -0
  129. package/dist/domain/mod/ModFile.d.ts +27 -0
  130. package/dist/domain/mod/ModFile.d.ts.map +1 -0
  131. package/dist/domain/mod/ModFile.js +5 -0
  132. package/dist/domain/mod/ModFile.js.map +1 -0
  133. package/dist/domain/mod/ModProject.d.ts +36 -0
  134. package/dist/domain/mod/ModProject.d.ts.map +1 -0
  135. package/dist/domain/mod/ModProject.js +5 -0
  136. package/dist/domain/mod/ModProject.js.map +1 -0
  137. package/dist/domain/mod/ModSearchResult.d.ts +18 -0
  138. package/dist/domain/mod/ModSearchResult.d.ts.map +1 -0
  139. package/dist/domain/mod/ModSearchResult.js +5 -0
  140. package/dist/domain/mod/ModSearchResult.js.map +1 -0
  141. package/dist/domain/mod/ModVersion.d.ts +36 -0
  142. package/dist/domain/mod/ModVersion.d.ts.map +1 -0
  143. package/dist/domain/mod/ModVersion.js +5 -0
  144. package/dist/domain/mod/ModVersion.js.map +1 -0
  145. package/dist/domain/mod/index.d.ts +11 -0
  146. package/dist/domain/mod/index.d.ts.map +1 -0
  147. package/dist/domain/mod/index.js +6 -0
  148. package/dist/domain/mod/index.js.map +1 -0
  149. package/dist/domain/mod/types.d.ts +43 -0
  150. package/dist/domain/mod/types.d.ts.map +1 -0
  151. package/dist/domain/mod/types.js +6 -0
  152. package/dist/domain/mod/types.js.map +1 -0
  153. package/dist/domain/value-objects/McVersion.d.ts +35 -0
  154. package/dist/domain/value-objects/McVersion.d.ts.map +1 -0
  155. package/dist/domain/value-objects/McVersion.js +117 -0
  156. package/dist/domain/value-objects/McVersion.js.map +1 -0
  157. package/dist/domain/value-objects/Memory.d.ts +37 -0
  158. package/dist/domain/value-objects/Memory.d.ts.map +1 -0
  159. package/dist/domain/value-objects/Memory.js +107 -0
  160. package/dist/domain/value-objects/Memory.js.map +1 -0
  161. package/dist/domain/value-objects/ProcessInfo.d.ts +99 -0
  162. package/dist/domain/value-objects/ProcessInfo.d.ts.map +1 -0
  163. package/dist/domain/value-objects/ProcessInfo.js +171 -0
  164. package/dist/domain/value-objects/ProcessInfo.js.map +1 -0
  165. package/dist/domain/value-objects/Role.d.ts +41 -0
  166. package/dist/domain/value-objects/Role.d.ts.map +1 -0
  167. package/dist/domain/value-objects/Role.js +66 -0
  168. package/dist/domain/value-objects/Role.js.map +1 -0
  169. package/dist/domain/value-objects/ServerName.d.ts +21 -0
  170. package/dist/domain/value-objects/ServerName.d.ts.map +1 -0
  171. package/dist/domain/value-objects/ServerName.js +58 -0
  172. package/dist/domain/value-objects/ServerName.js.map +1 -0
  173. package/dist/domain/value-objects/ServerType.d.ts +40 -0
  174. package/dist/domain/value-objects/ServerType.d.ts.map +1 -0
  175. package/dist/domain/value-objects/ServerType.js +136 -0
  176. package/dist/domain/value-objects/ServerType.js.map +1 -0
  177. package/dist/domain/value-objects/ServiceStatus.d.ts +64 -0
  178. package/dist/domain/value-objects/ServiceStatus.d.ts.map +1 -0
  179. package/dist/domain/value-objects/ServiceStatus.js +99 -0
  180. package/dist/domain/value-objects/ServiceStatus.js.map +1 -0
  181. package/dist/domain/value-objects/UserId.d.ts +21 -0
  182. package/dist/domain/value-objects/UserId.d.ts.map +1 -0
  183. package/dist/domain/value-objects/UserId.js +43 -0
  184. package/dist/domain/value-objects/UserId.js.map +1 -0
  185. package/dist/domain/value-objects/Username.d.ts +16 -0
  186. package/dist/domain/value-objects/Username.d.ts.map +1 -0
  187. package/dist/domain/value-objects/Username.js +46 -0
  188. package/dist/domain/value-objects/Username.js.map +1 -0
  189. package/dist/domain/value-objects/WorldOptions.d.ts +49 -0
  190. package/dist/domain/value-objects/WorldOptions.d.ts.map +1 -0
  191. package/dist/domain/value-objects/WorldOptions.js +149 -0
  192. package/dist/domain/value-objects/WorldOptions.js.map +1 -0
  193. package/dist/domain/value-objects/index.d.ts +11 -0
  194. package/dist/domain/value-objects/index.d.ts.map +1 -0
  195. package/dist/domain/value-objects/index.js +13 -0
  196. package/dist/domain/value-objects/index.js.map +1 -0
  197. package/dist/index.d.ts +9 -0
  198. package/dist/index.d.ts.map +1 -0
  199. package/dist/index.js +21 -0
  200. package/dist/index.js.map +1 -0
  201. package/dist/infrastructure/adapters/ApiPromptAdapter.d.ts +115 -0
  202. package/dist/infrastructure/adapters/ApiPromptAdapter.d.ts.map +1 -0
  203. package/dist/infrastructure/adapters/ApiPromptAdapter.js +268 -0
  204. package/dist/infrastructure/adapters/ApiPromptAdapter.js.map +1 -0
  205. package/dist/infrastructure/adapters/DocsAdapter.d.ts +45 -0
  206. package/dist/infrastructure/adapters/DocsAdapter.d.ts.map +1 -0
  207. package/dist/infrastructure/adapters/DocsAdapter.js +490 -0
  208. package/dist/infrastructure/adapters/DocsAdapter.js.map +1 -0
  209. package/dist/infrastructure/adapters/ServerRepository.d.ts +49 -0
  210. package/dist/infrastructure/adapters/ServerRepository.d.ts.map +1 -0
  211. package/dist/infrastructure/adapters/ServerRepository.js +206 -0
  212. package/dist/infrastructure/adapters/ServerRepository.js.map +1 -0
  213. package/dist/infrastructure/adapters/ShellAdapter.d.ts +41 -0
  214. package/dist/infrastructure/adapters/ShellAdapter.d.ts.map +1 -0
  215. package/dist/infrastructure/adapters/ShellAdapter.js +198 -0
  216. package/dist/infrastructure/adapters/ShellAdapter.js.map +1 -0
  217. package/dist/infrastructure/adapters/SqliteUserRepository.d.ts +70 -0
  218. package/dist/infrastructure/adapters/SqliteUserRepository.d.ts.map +1 -0
  219. package/dist/infrastructure/adapters/SqliteUserRepository.js +149 -0
  220. package/dist/infrastructure/adapters/SqliteUserRepository.js.map +1 -0
  221. package/dist/infrastructure/adapters/WorldRepository.d.ts +67 -0
  222. package/dist/infrastructure/adapters/WorldRepository.d.ts.map +1 -0
  223. package/dist/infrastructure/adapters/WorldRepository.js +283 -0
  224. package/dist/infrastructure/adapters/WorldRepository.js.map +1 -0
  225. package/dist/infrastructure/adapters/YamlUserRepository.d.ts +67 -0
  226. package/dist/infrastructure/adapters/YamlUserRepository.d.ts.map +1 -0
  227. package/dist/infrastructure/adapters/YamlUserRepository.js +161 -0
  228. package/dist/infrastructure/adapters/YamlUserRepository.js.map +1 -0
  229. package/dist/infrastructure/adapters/index.d.ts +12 -0
  230. package/dist/infrastructure/adapters/index.d.ts.map +1 -0
  231. package/dist/infrastructure/adapters/index.js +12 -0
  232. package/dist/infrastructure/adapters/index.js.map +1 -0
  233. package/dist/infrastructure/config/Pm2EcosystemConfig.d.ts +192 -0
  234. package/dist/infrastructure/config/Pm2EcosystemConfig.d.ts.map +1 -0
  235. package/dist/infrastructure/config/Pm2EcosystemConfig.js +48 -0
  236. package/dist/infrastructure/config/Pm2EcosystemConfig.js.map +1 -0
  237. package/dist/infrastructure/config/index.d.ts +6 -0
  238. package/dist/infrastructure/config/index.d.ts.map +1 -0
  239. package/dist/infrastructure/config/index.js +6 -0
  240. package/dist/infrastructure/config/index.js.map +1 -0
  241. package/dist/infrastructure/factories/ModSourceFactory.d.ts +73 -0
  242. package/dist/infrastructure/factories/ModSourceFactory.d.ts.map +1 -0
  243. package/dist/infrastructure/factories/ModSourceFactory.js +98 -0
  244. package/dist/infrastructure/factories/ModSourceFactory.js.map +1 -0
  245. package/dist/infrastructure/factories/index.d.ts +5 -0
  246. package/dist/infrastructure/factories/index.d.ts.map +1 -0
  247. package/dist/infrastructure/factories/index.js +5 -0
  248. package/dist/infrastructure/factories/index.js.map +1 -0
  249. package/dist/infrastructure/index.d.ts +7 -0
  250. package/dist/infrastructure/index.d.ts.map +1 -0
  251. package/dist/infrastructure/index.js +7 -0
  252. package/dist/infrastructure/index.js.map +1 -0
  253. package/dist/types/index.d.ts +151 -0
  254. package/dist/types/index.d.ts.map +1 -0
  255. package/dist/types/index.js +2 -0
  256. package/dist/types/index.js.map +1 -0
  257. package/dist/utils/index.d.ts +81 -0
  258. package/dist/utils/index.d.ts.map +1 -0
  259. package/dist/utils/index.js +200 -0
  260. package/dist/utils/index.js.map +1 -0
  261. package/package.json +10 -2
@@ -0,0 +1,149 @@
1
+ import Database from 'better-sqlite3';
2
+ import { mkdirSync, existsSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import * as bcrypt from 'bcryptjs';
5
+ import { User } from '../../domain/entities/User.js';
6
+ /**
7
+ * SqliteUserRepository
8
+ * Implements IUserRepository using SQLite database storage with better-sqlite3
9
+ */
10
+ export class SqliteUserRepository {
11
+ static SALT_ROUNDS = 10;
12
+ db;
13
+ /**
14
+ * Create a new SqliteUserRepository
15
+ * @param dbPath - Path to the SQLite database file
16
+ */
17
+ constructor(dbPath) {
18
+ // Ensure directory exists
19
+ const dir = dirname(dbPath);
20
+ if (!existsSync(dir)) {
21
+ mkdirSync(dir, { recursive: true });
22
+ }
23
+ // Open database connection
24
+ this.db = new Database(dbPath);
25
+ // Enable WAL mode for better concurrency
26
+ this.db.pragma('journal_mode = WAL');
27
+ // Run migrations
28
+ this.migrate();
29
+ }
30
+ /**
31
+ * Run database migrations
32
+ * Creates tables and indexes if they don't exist
33
+ */
34
+ migrate() {
35
+ this.db.exec(`
36
+ CREATE TABLE IF NOT EXISTS users (
37
+ id TEXT PRIMARY KEY,
38
+ username TEXT UNIQUE NOT NULL COLLATE NOCASE,
39
+ password_hash TEXT NOT NULL,
40
+ role TEXT NOT NULL CHECK(role IN ('admin', 'viewer')),
41
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
42
+ updated_at TEXT DEFAULT CURRENT_TIMESTAMP
43
+ );
44
+
45
+ CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
46
+ CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
47
+ `);
48
+ }
49
+ /**
50
+ * Find a user by their unique ID
51
+ */
52
+ async findById(id) {
53
+ const stmt = this.db.prepare('SELECT * FROM users WHERE id = ?');
54
+ const row = stmt.get(id.value);
55
+ if (!row) {
56
+ return null;
57
+ }
58
+ return this.toUser(row);
59
+ }
60
+ /**
61
+ * Find a user by their username (case-insensitive)
62
+ */
63
+ async findByUsername(username) {
64
+ // SQLite COLLATE NOCASE handles case-insensitive comparison
65
+ const stmt = this.db.prepare('SELECT * FROM users WHERE username = ?');
66
+ const row = stmt.get(username.value);
67
+ if (!row) {
68
+ return null;
69
+ }
70
+ return this.toUser(row);
71
+ }
72
+ /**
73
+ * Get all users in the system
74
+ */
75
+ async findAll() {
76
+ const stmt = this.db.prepare('SELECT * FROM users ORDER BY created_at ASC');
77
+ const rows = stmt.all();
78
+ return rows.map((row) => this.toUser(row));
79
+ }
80
+ /**
81
+ * Save a user (create or update)
82
+ * Uses INSERT OR REPLACE for upsert behavior
83
+ */
84
+ async save(user) {
85
+ const stmt = this.db.prepare(`
86
+ INSERT INTO users (id, username, password_hash, role, created_at, updated_at)
87
+ VALUES (?, ?, ?, ?, ?, ?)
88
+ ON CONFLICT(id) DO UPDATE SET
89
+ username = excluded.username,
90
+ password_hash = excluded.password_hash,
91
+ role = excluded.role,
92
+ updated_at = excluded.updated_at
93
+ `);
94
+ stmt.run(user.id.value, user.username.value, user.passwordHash, user.role.value, user.createdAt.toISOString(), user.updatedAt.toISOString());
95
+ }
96
+ /**
97
+ * Delete a user by their ID
98
+ */
99
+ async delete(id) {
100
+ const stmt = this.db.prepare('DELETE FROM users WHERE id = ?');
101
+ stmt.run(id.value);
102
+ }
103
+ /**
104
+ * Get the total count of users
105
+ */
106
+ async count() {
107
+ const stmt = this.db.prepare('SELECT COUNT(*) as count FROM users');
108
+ const result = stmt.get();
109
+ return result?.count ?? 0;
110
+ }
111
+ /**
112
+ * Hash a password using bcrypt
113
+ * @param password - Plain text password to hash
114
+ * @returns Hashed password
115
+ */
116
+ async hashPassword(password) {
117
+ return bcrypt.hash(password, SqliteUserRepository.SALT_ROUNDS);
118
+ }
119
+ /**
120
+ * Verify a password against a hash
121
+ * @param password - Plain text password to verify
122
+ * @param hash - Password hash to verify against
123
+ * @returns True if password matches, false otherwise
124
+ */
125
+ async verifyPassword(password, hash) {
126
+ return bcrypt.compare(password, hash);
127
+ }
128
+ /**
129
+ * Close the database connection
130
+ * Should be called when the repository is no longer needed
131
+ */
132
+ close() {
133
+ this.db.close();
134
+ }
135
+ /**
136
+ * Convert a database row to a User entity
137
+ */
138
+ toUser(row) {
139
+ return User.fromRaw({
140
+ id: row.id,
141
+ username: row.username,
142
+ passwordHash: row.password_hash,
143
+ role: row.role,
144
+ createdAt: row.created_at,
145
+ updatedAt: row.updated_at,
146
+ });
147
+ }
148
+ }
149
+ //# sourceMappingURL=SqliteUserRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteUserRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/adapters/SqliteUserRepository.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAEnC,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAgBrD;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAU,WAAW,GAAG,EAAE,CAAC;IACxB,EAAE,CAAoB;IAEvC;;;OAGG;IACH,YAAY,MAAc;QACxB,0BAA0B;QAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE/B,yCAAyC;QACzC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAErC,iBAAiB;QACjB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,OAAO;QACb,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;KAYZ,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAU;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC1B,kCAAkC,CACnC,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAE/B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAkB;QACrC,4DAA4D;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC1B,wCAAwC,CACzC,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC1B,6CAA6C,CAC9C,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAExB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,IAAU;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;;;KAQ5B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,EAAE,CAAC,KAAK,EACb,IAAI,CAAC,QAAQ,CAAC,KAAK,EACnB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,IAAI,CAAC,KAAK,EACf,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAC5B,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAC7B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QAC/D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC1B,qCAAqC,CACtC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE1B,OAAO,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB;QACjC,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACjE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB,EAAE,IAAY;QACjD,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,GAAY;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,YAAY,EAAE,GAAG,CAAC,aAAa;YAC/B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,SAAS,EAAE,GAAG,CAAC,UAAU;SAC1B,CAAC,CAAC;IACL,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { Paths } from '../../utils/index.js';
2
+ import { World } from '../../domain/index.js';
3
+ import type { IWorldRepository, WorldLockData, WorldWithServerStatus } from '../../application/ports/outbound/IWorldRepository.js';
4
+ /**
5
+ * WorldRepository
6
+ * Implements IWorldRepository for world data access
7
+ */
8
+ export declare class WorldRepository implements IWorldRepository {
9
+ private readonly paths;
10
+ private readonly worldsDir;
11
+ private readonly locksDir;
12
+ constructor(paths?: Paths);
13
+ /**
14
+ * Get all worlds
15
+ */
16
+ findAll(): Promise<World[]>;
17
+ /**
18
+ * Find world by name
19
+ */
20
+ findByName(name: string): Promise<World | null>;
21
+ /**
22
+ * Check if world exists
23
+ */
24
+ exists(name: string): Promise<boolean>;
25
+ /**
26
+ * Get unlocked worlds
27
+ */
28
+ findUnlocked(): Promise<World[]>;
29
+ /**
30
+ * Get locked worlds
31
+ */
32
+ findLocked(): Promise<World[]>;
33
+ /**
34
+ * Get worlds locked by a specific server
35
+ */
36
+ findByServer(serverName: string): Promise<World[]>;
37
+ /**
38
+ * List world names
39
+ */
40
+ listNames(): Promise<string[]>;
41
+ /**
42
+ * Get lock status for a world
43
+ */
44
+ getLockStatus(name: string): Promise<WorldLockData | null>;
45
+ /**
46
+ * Get all worlds with their server status
47
+ * Returns worlds categorized by availability
48
+ */
49
+ findAllWithServerStatus(): Promise<WorldWithServerStatus[]>;
50
+ /**
51
+ * Delete a world directory and its lock file
52
+ */
53
+ delete(name: string): Promise<boolean>;
54
+ /**
55
+ * Get directory size recursively
56
+ */
57
+ private getDirectorySize;
58
+ /**
59
+ * Create a new world directory with optional seed
60
+ */
61
+ create(name: string, seed?: string): Promise<World>;
62
+ /**
63
+ * Get seed for a world from .meta file
64
+ */
65
+ getSeed(name: string): Promise<string | null>;
66
+ }
67
+ //# sourceMappingURL=WorldRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorldRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/adapters/WorldRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EAGtB,MAAM,sDAAsD,CAAC;AAE9D;;;GAGG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,KAAK,CAAC,EAAE,KAAK;IAMzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAcjC;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IA4BrD;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK5C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAKtC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAKpC;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAKxD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBpC;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IA0BhE;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IA0DjE;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsB5C;;OAEG;YACW,gBAAgB;IAuB9B;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAkCzD;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAepD"}
@@ -0,0 +1,283 @@
1
+ import { readdir, readFile, stat, rm, unlink, mkdir, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { existsSync } from 'node:fs';
4
+ import { Paths } from '../../utils/index.js';
5
+ import { World } from '../../domain/index.js';
6
+ import { getContainerStatus } from '../../docker/index.js';
7
+ /**
8
+ * WorldRepository
9
+ * Implements IWorldRepository for world data access
10
+ */
11
+ export class WorldRepository {
12
+ paths;
13
+ worldsDir;
14
+ locksDir;
15
+ constructor(paths) {
16
+ this.paths = paths ?? new Paths();
17
+ this.worldsDir = join(this.paths.root, 'worlds');
18
+ this.locksDir = join(this.worldsDir, '.locks');
19
+ }
20
+ /**
21
+ * Get all worlds
22
+ */
23
+ async findAll() {
24
+ const names = await this.listNames();
25
+ const worlds = [];
26
+ for (const name of names) {
27
+ const world = await this.findByName(name);
28
+ if (world) {
29
+ worlds.push(world);
30
+ }
31
+ }
32
+ return worlds;
33
+ }
34
+ /**
35
+ * Find world by name
36
+ */
37
+ async findByName(name) {
38
+ const worldPath = join(this.worldsDir, name);
39
+ if (!existsSync(worldPath)) {
40
+ return null;
41
+ }
42
+ const world = new World(name, worldPath);
43
+ // Get lock status
44
+ const lockData = await this.getLockStatus(name);
45
+ if (lockData) {
46
+ world.lockTo(lockData.serverName, lockData.pid);
47
+ }
48
+ // Get world metadata and seed
49
+ try {
50
+ const worldStat = await stat(worldPath);
51
+ const size = await this.getDirectorySize(worldPath);
52
+ const seed = await this.getSeed(name);
53
+ world.setMetadata(size, worldStat.mtime, seed ?? undefined);
54
+ }
55
+ catch {
56
+ // Ignore metadata errors
57
+ }
58
+ return world;
59
+ }
60
+ /**
61
+ * Check if world exists
62
+ */
63
+ async exists(name) {
64
+ const worldPath = join(this.worldsDir, name);
65
+ return existsSync(worldPath);
66
+ }
67
+ /**
68
+ * Get unlocked worlds
69
+ */
70
+ async findUnlocked() {
71
+ const worlds = await this.findAll();
72
+ return worlds.filter((w) => !w.isLocked);
73
+ }
74
+ /**
75
+ * Get locked worlds
76
+ */
77
+ async findLocked() {
78
+ const worlds = await this.findAll();
79
+ return worlds.filter((w) => w.isLocked);
80
+ }
81
+ /**
82
+ * Get worlds locked by a specific server
83
+ */
84
+ async findByServer(serverName) {
85
+ const worlds = await this.findAll();
86
+ return worlds.filter((w) => w.lockedBy === serverName);
87
+ }
88
+ /**
89
+ * List world names
90
+ */
91
+ async listNames() {
92
+ if (!existsSync(this.worldsDir)) {
93
+ return [];
94
+ }
95
+ try {
96
+ const entries = await readdir(this.worldsDir, { withFileTypes: true });
97
+ return entries
98
+ .filter((entry) => entry.isDirectory())
99
+ .filter((entry) => !entry.name.startsWith('.')) // Skip hidden dirs like .locks
100
+ .map((entry) => entry.name);
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ }
106
+ /**
107
+ * Get lock status for a world
108
+ */
109
+ async getLockStatus(name) {
110
+ const lockFile = join(this.locksDir, `${name}.lock`);
111
+ if (!existsSync(lockFile)) {
112
+ return null;
113
+ }
114
+ try {
115
+ const content = await readFile(lockFile, 'utf-8');
116
+ const [serverName, timestampStr, pidStr] = content.trim().split(':');
117
+ if (!serverName || !timestampStr) {
118
+ return null;
119
+ }
120
+ return {
121
+ worldName: name,
122
+ serverName,
123
+ timestamp: new Date(parseInt(timestampStr, 10) * 1000),
124
+ pid: pidStr ? parseInt(pidStr, 10) : undefined,
125
+ };
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
131
+ /**
132
+ * Get all worlds with their server status
133
+ * Returns worlds categorized by availability
134
+ */
135
+ async findAllWithServerStatus() {
136
+ const worlds = await this.findAll();
137
+ const results = [];
138
+ for (const world of worlds) {
139
+ if (!world.isLocked) {
140
+ // World is not locked by any server - available
141
+ results.push({
142
+ world,
143
+ category: 'available',
144
+ });
145
+ }
146
+ else {
147
+ // World is locked - check server status
148
+ const serverName = world.lockedBy;
149
+ const containerName = serverName.startsWith('mc-')
150
+ ? serverName
151
+ : `mc-${serverName}`;
152
+ const containerStatus = getContainerStatus(containerName);
153
+ let serverStatus;
154
+ let category;
155
+ if (containerStatus === 'running') {
156
+ serverStatus = 'running';
157
+ category = 'running';
158
+ }
159
+ else if (containerStatus === 'not_found') {
160
+ serverStatus = 'not_found';
161
+ // If container not found, treat as available (stale lock)
162
+ category = 'available';
163
+ }
164
+ else {
165
+ // exited, paused, created, etc. - server is stopped
166
+ serverStatus = 'stopped';
167
+ category = 'stopped';
168
+ }
169
+ results.push({
170
+ world,
171
+ assignedServer: serverName,
172
+ serverStatus,
173
+ category,
174
+ });
175
+ }
176
+ }
177
+ // Sort: available first, then stopped, then running
178
+ const categoryOrder = {
179
+ available: 0,
180
+ stopped: 1,
181
+ running: 2,
182
+ };
183
+ return results.sort((a, b) => {
184
+ const orderDiff = categoryOrder[a.category] - categoryOrder[b.category];
185
+ if (orderDiff !== 0)
186
+ return orderDiff;
187
+ return a.world.name.localeCompare(b.world.name);
188
+ });
189
+ }
190
+ /**
191
+ * Delete a world directory and its lock file
192
+ */
193
+ async delete(name) {
194
+ const worldPath = join(this.worldsDir, name);
195
+ const lockFile = join(this.locksDir, `${name}.lock`);
196
+ if (!existsSync(worldPath)) {
197
+ return false;
198
+ }
199
+ try {
200
+ // Delete lock file if exists
201
+ if (existsSync(lockFile)) {
202
+ await unlink(lockFile);
203
+ }
204
+ // Delete world directory
205
+ await rm(worldPath, { recursive: true, force: true });
206
+ return true;
207
+ }
208
+ catch {
209
+ return false;
210
+ }
211
+ }
212
+ /**
213
+ * Get directory size recursively
214
+ */
215
+ async getDirectorySize(dirPath) {
216
+ let totalSize = 0;
217
+ try {
218
+ const entries = await readdir(dirPath, { withFileTypes: true });
219
+ for (const entry of entries) {
220
+ const entryPath = join(dirPath, entry.name);
221
+ if (entry.isFile()) {
222
+ const fileStat = await stat(entryPath);
223
+ totalSize += fileStat.size;
224
+ }
225
+ else if (entry.isDirectory()) {
226
+ totalSize += await this.getDirectorySize(entryPath);
227
+ }
228
+ }
229
+ }
230
+ catch {
231
+ // Ignore errors
232
+ }
233
+ return totalSize;
234
+ }
235
+ /**
236
+ * Create a new world directory with optional seed
237
+ */
238
+ async create(name, seed) {
239
+ const worldPath = join(this.worldsDir, name);
240
+ // Check if already exists
241
+ if (existsSync(worldPath)) {
242
+ throw new Error(`World '${name}' already exists`);
243
+ }
244
+ // Ensure worlds directory exists
245
+ if (!existsSync(this.worldsDir)) {
246
+ await mkdir(this.worldsDir, { recursive: true });
247
+ }
248
+ // Create world directory
249
+ await mkdir(worldPath, { recursive: true });
250
+ // Create .meta file with seed if provided
251
+ const metaPath = join(worldPath, '.meta');
252
+ const metaContent = {
253
+ name,
254
+ seed: seed || null,
255
+ createdAt: new Date().toISOString(),
256
+ };
257
+ await writeFile(metaPath, JSON.stringify(metaContent, null, 2), 'utf-8');
258
+ // Create and return the World entity
259
+ const world = new World(name, worldPath);
260
+ if (seed) {
261
+ world.setSeed(seed);
262
+ }
263
+ return world;
264
+ }
265
+ /**
266
+ * Get seed for a world from .meta file
267
+ */
268
+ async getSeed(name) {
269
+ const metaPath = join(this.worldsDir, name, '.meta');
270
+ if (!existsSync(metaPath)) {
271
+ return null;
272
+ }
273
+ try {
274
+ const content = await readFile(metaPath, 'utf-8');
275
+ const meta = JSON.parse(content);
276
+ return meta.seed || null;
277
+ }
278
+ catch {
279
+ return null;
280
+ }
281
+ }
282
+ }
283
+ //# sourceMappingURL=WorldRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorldRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/adapters/WorldRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { IUserRepository } from '../../application/ports/outbound/IUserRepository.js';
2
+ import { User } from '../../domain/entities/User.js';
3
+ import { UserId } from '../../domain/value-objects/UserId.js';
4
+ import { Username } from '../../domain/value-objects/Username.js';
5
+ /**
6
+ * YamlUserRepository
7
+ * Implements IUserRepository using YAML file storage
8
+ */
9
+ export declare class YamlUserRepository implements IUserRepository {
10
+ private static readonly SALT_ROUNDS;
11
+ private readonly filePath;
12
+ /**
13
+ * Create a new YamlUserRepository
14
+ * @param filePath - Path to the YAML file for user storage
15
+ */
16
+ constructor(filePath: string);
17
+ /**
18
+ * Find a user by their unique ID
19
+ */
20
+ findById(id: UserId): Promise<User | null>;
21
+ /**
22
+ * Find a user by their username
23
+ */
24
+ findByUsername(username: Username): Promise<User | null>;
25
+ /**
26
+ * Get all users in the system
27
+ */
28
+ findAll(): Promise<User[]>;
29
+ /**
30
+ * Save a user (create or update)
31
+ */
32
+ save(user: User): Promise<void>;
33
+ /**
34
+ * Delete a user by their ID
35
+ */
36
+ delete(id: UserId): Promise<void>;
37
+ /**
38
+ * Get the total count of users
39
+ */
40
+ count(): Promise<number>;
41
+ /**
42
+ * Hash a password using bcrypt
43
+ * @param password - Plain text password to hash
44
+ * @returns Hashed password
45
+ */
46
+ hashPassword(password: string): Promise<string>;
47
+ /**
48
+ * Verify a password against a hash
49
+ * @param password - Plain text password to verify
50
+ * @param hash - Password hash to verify against
51
+ * @returns True if password matches, false otherwise
52
+ */
53
+ verifyPassword(password: string, hash: string): Promise<boolean>;
54
+ /**
55
+ * Load users from YAML file
56
+ */
57
+ private loadUsers;
58
+ /**
59
+ * Save users to YAML file
60
+ */
61
+ private saveUsers;
62
+ /**
63
+ * Convert YAML user data to User entity
64
+ */
65
+ private toUser;
66
+ }
67
+ //# sourceMappingURL=YamlUserRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"YamlUserRepository.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/adapters/YamlUserRepository.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qDAAqD,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAkBlE;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAM;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC;;;OAGG;gBACS,QAAQ,EAAE,MAAM;IAI5B;;OAEG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAWhD;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAc9D;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAKhC;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBrC;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B;;;;OAIG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD;;;;;OAKG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItE;;OAEG;YACW,SAAS;IAoBvB;;OAEG;YACW,SAAS;IAkBvB;;OAEG;IACH,OAAO,CAAC,MAAM;CAUf"}