@superdangerous/app-framework 4.9.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.
Files changed (239) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +652 -0
  3. package/dist/api/logsRouter.d.ts +20 -0
  4. package/dist/api/logsRouter.d.ts.map +1 -0
  5. package/dist/api/logsRouter.js +515 -0
  6. package/dist/api/logsRouter.js.map +1 -0
  7. package/dist/cli/dev-server.d.ts +7 -0
  8. package/dist/cli/dev-server.d.ts.map +1 -0
  9. package/dist/cli/dev-server.js +640 -0
  10. package/dist/cli/dev-server.js.map +1 -0
  11. package/dist/cli/index.d.ts +7 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +26 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/core/StandardServer.d.ts +129 -0
  16. package/dist/core/StandardServer.d.ts.map +1 -0
  17. package/dist/core/StandardServer.js +453 -0
  18. package/dist/core/StandardServer.js.map +1 -0
  19. package/dist/core/apiResponse.d.ts +69 -0
  20. package/dist/core/apiResponse.d.ts.map +1 -0
  21. package/dist/core/apiResponse.js +127 -0
  22. package/dist/core/apiResponse.js.map +1 -0
  23. package/dist/core/healthCheck.d.ts +160 -0
  24. package/dist/core/healthCheck.d.ts.map +1 -0
  25. package/dist/core/healthCheck.js +398 -0
  26. package/dist/core/healthCheck.js.map +1 -0
  27. package/dist/core/index.d.ts +40 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +40 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/logger.d.ts +117 -0
  32. package/dist/core/logger.d.ts.map +1 -0
  33. package/dist/core/logger.js +826 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/portUtils.d.ts +71 -0
  36. package/dist/core/portUtils.d.ts.map +1 -0
  37. package/dist/core/portUtils.js +240 -0
  38. package/dist/core/portUtils.js.map +1 -0
  39. package/dist/core/storageService.d.ts +119 -0
  40. package/dist/core/storageService.d.ts.map +1 -0
  41. package/dist/core/storageService.js +405 -0
  42. package/dist/core/storageService.js.map +1 -0
  43. package/dist/desktop/bundler.d.ts +40 -0
  44. package/dist/desktop/bundler.d.ts.map +1 -0
  45. package/dist/desktop/bundler.js +176 -0
  46. package/dist/desktop/bundler.js.map +1 -0
  47. package/dist/desktop/index.d.ts +25 -0
  48. package/dist/desktop/index.d.ts.map +1 -0
  49. package/dist/desktop/index.js +15 -0
  50. package/dist/desktop/index.js.map +1 -0
  51. package/dist/desktop/native-modules.d.ts +66 -0
  52. package/dist/desktop/native-modules.d.ts.map +1 -0
  53. package/dist/desktop/native-modules.js +200 -0
  54. package/dist/desktop/native-modules.js.map +1 -0
  55. package/dist/index.d.ts +29 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +39 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/logging/LogCategories.d.ts +87 -0
  60. package/dist/logging/LogCategories.d.ts.map +1 -0
  61. package/dist/logging/LogCategories.js +205 -0
  62. package/dist/logging/LogCategories.js.map +1 -0
  63. package/dist/middleware/aiErrorHandler.d.ts +31 -0
  64. package/dist/middleware/aiErrorHandler.d.ts.map +1 -0
  65. package/dist/middleware/aiErrorHandler.js +181 -0
  66. package/dist/middleware/aiErrorHandler.js.map +1 -0
  67. package/dist/middleware/auth.d.ts +101 -0
  68. package/dist/middleware/auth.d.ts.map +1 -0
  69. package/dist/middleware/auth.js +230 -0
  70. package/dist/middleware/auth.js.map +1 -0
  71. package/dist/middleware/cors.d.ts +56 -0
  72. package/dist/middleware/cors.d.ts.map +1 -0
  73. package/dist/middleware/cors.js +123 -0
  74. package/dist/middleware/cors.js.map +1 -0
  75. package/dist/middleware/errorHandler.d.ts +13 -0
  76. package/dist/middleware/errorHandler.d.ts.map +1 -0
  77. package/dist/middleware/errorHandler.js +85 -0
  78. package/dist/middleware/errorHandler.js.map +1 -0
  79. package/dist/middleware/fileUpload.d.ts +62 -0
  80. package/dist/middleware/fileUpload.d.ts.map +1 -0
  81. package/dist/middleware/fileUpload.js +175 -0
  82. package/dist/middleware/fileUpload.js.map +1 -0
  83. package/dist/middleware/health.d.ts +48 -0
  84. package/dist/middleware/health.d.ts.map +1 -0
  85. package/dist/middleware/health.js +143 -0
  86. package/dist/middleware/health.js.map +1 -0
  87. package/dist/middleware/index.d.ts +20 -0
  88. package/dist/middleware/index.d.ts.map +1 -0
  89. package/dist/middleware/index.js +18 -0
  90. package/dist/middleware/index.js.map +1 -0
  91. package/dist/middleware/openapi.d.ts +64 -0
  92. package/dist/middleware/openapi.d.ts.map +1 -0
  93. package/dist/middleware/openapi.js +258 -0
  94. package/dist/middleware/openapi.js.map +1 -0
  95. package/dist/middleware/requestLogging.d.ts +22 -0
  96. package/dist/middleware/requestLogging.d.ts.map +1 -0
  97. package/dist/middleware/requestLogging.js +61 -0
  98. package/dist/middleware/requestLogging.js.map +1 -0
  99. package/dist/middleware/session.d.ts +84 -0
  100. package/dist/middleware/session.d.ts.map +1 -0
  101. package/dist/middleware/session.js +189 -0
  102. package/dist/middleware/session.js.map +1 -0
  103. package/dist/middleware/validation.d.ts +1337 -0
  104. package/dist/middleware/validation.d.ts.map +1 -0
  105. package/dist/middleware/validation.js +483 -0
  106. package/dist/middleware/validation.js.map +1 -0
  107. package/dist/services/aiService.d.ts +180 -0
  108. package/dist/services/aiService.d.ts.map +1 -0
  109. package/dist/services/aiService.js +547 -0
  110. package/dist/services/aiService.js.map +1 -0
  111. package/dist/services/conversationStorage.d.ts +38 -0
  112. package/dist/services/conversationStorage.d.ts.map +1 -0
  113. package/dist/services/conversationStorage.js +158 -0
  114. package/dist/services/conversationStorage.js.map +1 -0
  115. package/dist/services/crossPlatformBuffer.d.ts +84 -0
  116. package/dist/services/crossPlatformBuffer.d.ts.map +1 -0
  117. package/dist/services/crossPlatformBuffer.js +246 -0
  118. package/dist/services/crossPlatformBuffer.js.map +1 -0
  119. package/dist/services/index.d.ts +17 -0
  120. package/dist/services/index.d.ts.map +1 -0
  121. package/dist/services/index.js +18 -0
  122. package/dist/services/index.js.map +1 -0
  123. package/dist/services/networkService.d.ts +81 -0
  124. package/dist/services/networkService.d.ts.map +1 -0
  125. package/dist/services/networkService.js +268 -0
  126. package/dist/services/networkService.js.map +1 -0
  127. package/dist/services/queueService.d.ts +112 -0
  128. package/dist/services/queueService.d.ts.map +1 -0
  129. package/dist/services/queueService.js +338 -0
  130. package/dist/services/queueService.js.map +1 -0
  131. package/dist/services/settingsService.d.ts +135 -0
  132. package/dist/services/settingsService.d.ts.map +1 -0
  133. package/dist/services/settingsService.js +425 -0
  134. package/dist/services/settingsService.js.map +1 -0
  135. package/dist/services/systemMonitor.d.ts +208 -0
  136. package/dist/services/systemMonitor.d.ts.map +1 -0
  137. package/dist/services/systemMonitor.js +693 -0
  138. package/dist/services/systemMonitor.js.map +1 -0
  139. package/dist/services/updateService.d.ts +78 -0
  140. package/dist/services/updateService.d.ts.map +1 -0
  141. package/dist/services/updateService.js +252 -0
  142. package/dist/services/updateService.js.map +1 -0
  143. package/dist/services/websocketEvents.d.ts +372 -0
  144. package/dist/services/websocketEvents.d.ts.map +1 -0
  145. package/dist/services/websocketEvents.js +338 -0
  146. package/dist/services/websocketEvents.js.map +1 -0
  147. package/dist/services/websocketServer.d.ts +80 -0
  148. package/dist/services/websocketServer.d.ts.map +1 -0
  149. package/dist/services/websocketServer.js +299 -0
  150. package/dist/services/websocketServer.js.map +1 -0
  151. package/dist/settings/SettingsSchema.d.ts +151 -0
  152. package/dist/settings/SettingsSchema.d.ts.map +1 -0
  153. package/dist/settings/SettingsSchema.js +424 -0
  154. package/dist/settings/SettingsSchema.js.map +1 -0
  155. package/dist/testing/TestServer.d.ts +69 -0
  156. package/dist/testing/TestServer.d.ts.map +1 -0
  157. package/dist/testing/TestServer.js +250 -0
  158. package/dist/testing/TestServer.js.map +1 -0
  159. package/dist/types/index.d.ts +137 -0
  160. package/dist/types/index.d.ts.map +1 -0
  161. package/dist/types/index.js +5 -0
  162. package/dist/types/index.js.map +1 -0
  163. package/dist/utils/appPaths.d.ts +74 -0
  164. package/dist/utils/appPaths.d.ts.map +1 -0
  165. package/dist/utils/appPaths.js +162 -0
  166. package/dist/utils/appPaths.js.map +1 -0
  167. package/dist/utils/fs-utils.d.ts +50 -0
  168. package/dist/utils/fs-utils.d.ts.map +1 -0
  169. package/dist/utils/fs-utils.js +114 -0
  170. package/dist/utils/fs-utils.js.map +1 -0
  171. package/dist/utils/index.d.ts +12 -0
  172. package/dist/utils/index.d.ts.map +1 -0
  173. package/dist/utils/index.js +10 -0
  174. package/dist/utils/index.js.map +1 -0
  175. package/dist/utils/standardConfig.d.ts +61 -0
  176. package/dist/utils/standardConfig.d.ts.map +1 -0
  177. package/dist/utils/standardConfig.js +109 -0
  178. package/dist/utils/standardConfig.js.map +1 -0
  179. package/dist/utils/startupBanner.d.ts +34 -0
  180. package/dist/utils/startupBanner.d.ts.map +1 -0
  181. package/dist/utils/startupBanner.js +169 -0
  182. package/dist/utils/startupBanner.js.map +1 -0
  183. package/dist/utils/startupLogger.d.ts +45 -0
  184. package/dist/utils/startupLogger.d.ts.map +1 -0
  185. package/dist/utils/startupLogger.js +200 -0
  186. package/dist/utils/startupLogger.js.map +1 -0
  187. package/package.json +151 -0
  188. package/src/api/logsRouter.ts +600 -0
  189. package/src/cli/dev-server.ts +803 -0
  190. package/src/cli/index.ts +31 -0
  191. package/src/core/StandardServer.ts +587 -0
  192. package/src/core/apiResponse.ts +202 -0
  193. package/src/core/healthCheck.ts +565 -0
  194. package/src/core/index.ts +80 -0
  195. package/src/core/logger.ts +1092 -0
  196. package/src/core/portUtils.ts +319 -0
  197. package/src/core/storageService.ts +595 -0
  198. package/src/desktop/bundler.ts +271 -0
  199. package/src/desktop/index.ts +18 -0
  200. package/src/desktop/native-modules.ts +289 -0
  201. package/src/index.ts +142 -0
  202. package/src/logging/LogCategories.ts +302 -0
  203. package/src/middleware/aiErrorHandler.ts +278 -0
  204. package/src/middleware/auth.ts +329 -0
  205. package/src/middleware/cors.ts +187 -0
  206. package/src/middleware/errorHandler.ts +103 -0
  207. package/src/middleware/fileUpload.ts +252 -0
  208. package/src/middleware/health.ts +206 -0
  209. package/src/middleware/index.ts +71 -0
  210. package/src/middleware/openapi.ts +305 -0
  211. package/src/middleware/requestLogging.ts +92 -0
  212. package/src/middleware/session.ts +238 -0
  213. package/src/middleware/validation.ts +603 -0
  214. package/src/services/aiService.ts +789 -0
  215. package/src/services/conversationStorage.ts +232 -0
  216. package/src/services/crossPlatformBuffer.ts +341 -0
  217. package/src/services/index.ts +47 -0
  218. package/src/services/networkService.ts +351 -0
  219. package/src/services/queueService.ts +446 -0
  220. package/src/services/settingsService.ts +549 -0
  221. package/src/services/systemMonitor.ts +936 -0
  222. package/src/services/updateService.ts +334 -0
  223. package/src/services/websocketEvents.ts +409 -0
  224. package/src/services/websocketServer.ts +394 -0
  225. package/src/settings/SettingsSchema.ts +664 -0
  226. package/src/testing/TestServer.ts +312 -0
  227. package/src/types/index.ts +154 -0
  228. package/src/utils/appPaths.ts +196 -0
  229. package/src/utils/fs-utils.ts +130 -0
  230. package/src/utils/index.ts +15 -0
  231. package/src/utils/standardConfig.ts +178 -0
  232. package/src/utils/startupBanner.ts +287 -0
  233. package/src/utils/startupLogger.ts +268 -0
  234. package/ui/dist/index.d.mts +1221 -0
  235. package/ui/dist/index.d.ts +1221 -0
  236. package/ui/dist/index.js +73 -0
  237. package/ui/dist/index.js.map +1 -0
  238. package/ui/dist/index.mjs +73 -0
  239. package/ui/dist/index.mjs.map +1 -0
@@ -0,0 +1,405 @@
1
+ /**
2
+ * Storage Service
3
+ * Unified service for secure file operations, user uploads, and internal data storage
4
+ * Provides path sanitization, validation, and consistent file handling
5
+ */
6
+ import path from "path";
7
+ import * as fsUtils from "../utils/fs-utils.js";
8
+ import { createWriteStream } from "fs";
9
+ import { createLogger } from "./index.js";
10
+ import crypto from "crypto";
11
+ let logger; // Will be initialized when needed
12
+ function ensureLogger() {
13
+ if (!logger) {
14
+ logger = createLogger("StorageService");
15
+ }
16
+ return logger;
17
+ }
18
+ // Define safe base directories
19
+ const DATA_DIR = path.join(process.cwd(), "data");
20
+ const BASE_DIRS = {
21
+ attachments: path.join(DATA_DIR, "uploads", "attachments"),
22
+ data: DATA_DIR,
23
+ templates: path.join(DATA_DIR, "templates"),
24
+ uploads: path.join(DATA_DIR, "uploads"),
25
+ logs: path.join(DATA_DIR, "logs"),
26
+ config: path.join(DATA_DIR, "config"),
27
+ };
28
+ export class StorageService {
29
+ initialized = false;
30
+ maxFileSize = 100 * 1024 * 1024; // 100MB
31
+ async initialize() {
32
+ if (this.initialized)
33
+ return;
34
+ try {
35
+ // Ensure all base directories exist
36
+ for (const dir of Object.values(BASE_DIRS)) {
37
+ await fsUtils.ensureDir(dir);
38
+ }
39
+ // Ensure .gitignore exists in attachments and data directories
40
+ const gitignoreContent = "*\n!.gitignore\n";
41
+ await fsUtils.writeFile(path.join(BASE_DIRS.attachments, ".gitignore"), gitignoreContent);
42
+ await fsUtils.writeFile(path.join(BASE_DIRS.data, ".gitignore"), gitignoreContent);
43
+ this.initialized = true;
44
+ // Storage service initialized
45
+ }
46
+ catch (_error) {
47
+ ensureLogger().error("Failed to initialize storage service:", _error);
48
+ throw _error;
49
+ }
50
+ }
51
+ /**
52
+ * Sanitize a filename to prevent path traversal attacks
53
+ */
54
+ sanitizeFilename(filename) {
55
+ if (!filename || typeof filename !== "string") {
56
+ throw new Error("Invalid filename provided");
57
+ }
58
+ // Remove any path components and keep only the basename
59
+ let sanitized = path.basename(filename);
60
+ // Remove any remaining special characters that could cause issues
61
+ sanitized = sanitized.replace(/[^a-zA-Z0-9._-]/g, "_");
62
+ // Ensure the filename is not empty after sanitization
63
+ if (!sanitized || sanitized === "." || sanitized === "..") {
64
+ sanitized = `file_${Date.now()}`;
65
+ }
66
+ // Limit filename length
67
+ if (sanitized.length > 255) {
68
+ const ext = path.extname(sanitized);
69
+ const name = path.basename(sanitized, ext);
70
+ sanitized = name.substring(0, 255 - ext.length) + ext;
71
+ }
72
+ return sanitized;
73
+ }
74
+ /**
75
+ * Validate that a path is within the allowed base directory
76
+ */
77
+ isPathSafe(filePath, baseDir) {
78
+ try {
79
+ const resolvedPath = path.resolve(filePath);
80
+ const resolvedBase = path.resolve(baseDir);
81
+ return resolvedPath.startsWith(resolvedBase);
82
+ }
83
+ catch (_error) {
84
+ ensureLogger().error("Error validating path safety:", _error);
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Get the full safe path for a file
90
+ */
91
+ getSafePath(filename, category = "data") {
92
+ const sanitizedName = this.sanitizeFilename(filename);
93
+ const baseDir = BASE_DIRS[category];
94
+ const fullPath = path.join(baseDir, sanitizedName);
95
+ if (!this.isPathSafe(fullPath, baseDir)) {
96
+ throw new Error("Invalid file path detected");
97
+ }
98
+ return fullPath;
99
+ }
100
+ /**
101
+ * Save a file securely
102
+ */
103
+ async saveFile(content, filename, category = "data", options = {}) {
104
+ await this.initialize();
105
+ const safePath = this.getSafePath(filename, category);
106
+ // Check if file exists and handle accordingly
107
+ if (await fsUtils.pathExists(safePath)) {
108
+ if (!options.overwrite) {
109
+ throw new Error(`File already exists: ${filename}`);
110
+ }
111
+ if (options.createBackup) {
112
+ const backupPath = `${safePath}.backup.${Date.now()}`;
113
+ await fsUtils.copy(safePath, backupPath);
114
+ ensureLogger().info(`Created backup: ${backupPath}`);
115
+ }
116
+ }
117
+ // Validate content size
118
+ const size = Buffer.isBuffer(content)
119
+ ? content.length
120
+ : Buffer.byteLength(content);
121
+ if (size > this.maxFileSize) {
122
+ throw new Error(`File size exceeds maximum allowed size of ${this.maxFileSize} bytes`);
123
+ }
124
+ // Save the file
125
+ await fsUtils.writeFile(safePath, content);
126
+ // Calculate hash
127
+ const hash = crypto
128
+ .createHash("sha256")
129
+ .update(Buffer.isBuffer(content) ? content : Buffer.from(content))
130
+ .digest("hex");
131
+ const stats = await fsUtils.stat(safePath);
132
+ ensureLogger().debug(`File saved: ${safePath} (${size} bytes)`);
133
+ return {
134
+ name: filename,
135
+ size,
136
+ path: safePath,
137
+ hash,
138
+ created: stats.birthtime,
139
+ modified: stats.mtime,
140
+ };
141
+ }
142
+ /**
143
+ * Read a file securely
144
+ */
145
+ async readFile(filename, category = "data", options = {}) {
146
+ await this.initialize();
147
+ const safePath = this.getSafePath(filename, category);
148
+ // Check if file exists
149
+ if (!(await fsUtils.pathExists(safePath))) {
150
+ throw new Error(`File not found: ${filename}`);
151
+ }
152
+ // Check file size
153
+ const stats = await fsUtils.stat(safePath);
154
+ const maxSize = options.maxSize || this.maxFileSize;
155
+ if (stats.size > maxSize) {
156
+ throw new Error(`File size (${stats.size}) exceeds maximum allowed size (${maxSize})`);
157
+ }
158
+ // Read the file
159
+ const content = options.encoding
160
+ ? await fsUtils.readFile(safePath, options.encoding)
161
+ : await fsUtils.readFile(safePath);
162
+ ensureLogger().debug(`File read: ${safePath} (${stats.size} bytes)`);
163
+ return content;
164
+ }
165
+ /**
166
+ * Delete a file securely
167
+ */
168
+ async deleteFile(filename, category = "data") {
169
+ await this.initialize();
170
+ const safePath = this.getSafePath(filename, category);
171
+ if (!(await fsUtils.pathExists(safePath))) {
172
+ ensureLogger().warn(`File not found for deletion: ${filename}`);
173
+ return false;
174
+ }
175
+ await fsUtils.unlink(safePath);
176
+ ensureLogger().debug(`File deleted: ${safePath}`);
177
+ return true;
178
+ }
179
+ /**
180
+ * List files in a category
181
+ */
182
+ async listFiles(category = "data", pattern) {
183
+ await this.initialize();
184
+ const baseDir = BASE_DIRS[category];
185
+ const files = [];
186
+ try {
187
+ const entries = await fsUtils.readdir(baseDir);
188
+ for (const entry of entries) {
189
+ if (pattern && !pattern.test(entry))
190
+ continue;
191
+ const fullPath = path.join(baseDir, entry);
192
+ const stats = await fsUtils.stat(fullPath);
193
+ if (stats.isFile()) {
194
+ files.push({
195
+ name: entry,
196
+ size: stats.size,
197
+ path: fullPath,
198
+ created: stats.birthtime,
199
+ modified: stats.mtime,
200
+ });
201
+ }
202
+ }
203
+ }
204
+ catch (_error) {
205
+ ensureLogger().error(`Error listing files in ${category}:`, _error);
206
+ }
207
+ return files;
208
+ }
209
+ /**
210
+ * Get file info
211
+ */
212
+ async getFileInfo(filename, category = "data") {
213
+ await this.initialize();
214
+ const safePath = this.getSafePath(filename, category);
215
+ if (!(await fsUtils.pathExists(safePath))) {
216
+ return null;
217
+ }
218
+ const stats = await fsUtils.stat(safePath);
219
+ return {
220
+ name: filename,
221
+ size: stats.size,
222
+ path: safePath,
223
+ created: stats.birthtime,
224
+ modified: stats.mtime,
225
+ };
226
+ }
227
+ /**
228
+ * Move file between categories
229
+ */
230
+ async moveFile(filename, fromCategory, toCategory) {
231
+ await this.initialize();
232
+ const sourcePath = this.getSafePath(filename, fromCategory);
233
+ const destPath = this.getSafePath(filename, toCategory);
234
+ if (!(await fsUtils.pathExists(sourcePath))) {
235
+ throw new Error(`Source file not found: ${filename}`);
236
+ }
237
+ await fsUtils.move(sourcePath, destPath, { overwrite: false });
238
+ const stats = await fsUtils.stat(destPath);
239
+ ensureLogger().debug(`File moved from ${fromCategory} to ${toCategory}: ${filename}`);
240
+ return {
241
+ name: filename,
242
+ size: stats.size,
243
+ path: destPath,
244
+ created: stats.birthtime,
245
+ modified: stats.mtime,
246
+ };
247
+ }
248
+ /**
249
+ * Get available base directories
250
+ */
251
+ getBaseDirectories() {
252
+ return { ...BASE_DIRS };
253
+ }
254
+ /**
255
+ * Save a user upload with security checks
256
+ * @param file - File buffer or stream
257
+ * @param originalName - Original filename from user
258
+ * @param options - Upload options
259
+ * @returns Information about the uploaded file
260
+ */
261
+ async saveUserUpload(file, originalName, options = {}) {
262
+ await this.initialize();
263
+ const { maxSize = this.maxFileSize, allowedTypes = [], destination = "uploads", generateUniqueName = true, preserveExtension = true, } = options;
264
+ // Sanitize the original filename
265
+ const sanitizedName = this.sanitizeFilename(originalName);
266
+ const ext = path.extname(sanitizedName).toLowerCase();
267
+ const nameWithoutExt = path.basename(sanitizedName, ext);
268
+ // Check file extension if restrictions are specified
269
+ if (allowedTypes.length > 0 && !allowedTypes.includes(ext)) {
270
+ throw new Error(`File type ${ext} is not allowed. Allowed types: ${allowedTypes.join(", ")}`);
271
+ }
272
+ // Generate filename
273
+ let filename;
274
+ if (generateUniqueName) {
275
+ const uniqueId = crypto.randomBytes(8).toString("hex");
276
+ filename = preserveExtension
277
+ ? `${nameWithoutExt}_${uniqueId}${ext}`
278
+ : `${uniqueId}`;
279
+ }
280
+ else {
281
+ filename = sanitizedName;
282
+ }
283
+ // Determine the upload path. Prefer known base directories, but allow custom
284
+ // destinations for backward compatibility with the old FileHandler API.
285
+ let uploadPath;
286
+ if (BASE_DIRS[destination]) {
287
+ uploadPath = this.getSafePath(filename, destination);
288
+ }
289
+ else {
290
+ const resolvedDest = path.isAbsolute(destination)
291
+ ? destination
292
+ : path.join(process.cwd(), destination);
293
+ await fsUtils.ensureDir(resolvedDest);
294
+ uploadPath = path.join(resolvedDest, this.sanitizeFilename(filename));
295
+ }
296
+ // Save the file
297
+ if (Buffer.isBuffer(file)) {
298
+ // Check size for buffer
299
+ if (file.length > maxSize) {
300
+ throw new Error(`File size exceeds maximum allowed size of ${maxSize} bytes`);
301
+ }
302
+ await fsUtils.writeFile(uploadPath, file);
303
+ }
304
+ else {
305
+ // For streams, we need to check size while writing
306
+ const writeStream = createWriteStream(uploadPath);
307
+ let size = 0;
308
+ await new Promise((resolve, reject) => {
309
+ file.on("data", (chunk) => {
310
+ size += chunk.length;
311
+ if (size > maxSize) {
312
+ writeStream.destroy();
313
+ fsUtils.unlink(uploadPath).catch(() => { }); // Clean up partial file
314
+ reject(new Error(`File size exceeds maximum allowed size of ${maxSize} bytes`));
315
+ }
316
+ });
317
+ file.on("error", reject);
318
+ writeStream.on("error", reject);
319
+ writeStream.on("finish", () => resolve(undefined));
320
+ file.pipe(writeStream);
321
+ });
322
+ }
323
+ // Generate file hash
324
+ const fileBuffer = await fsUtils.readFile(uploadPath);
325
+ const hash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
326
+ // Get file stats
327
+ const stats = await fsUtils.stat(uploadPath);
328
+ const uploadedFile = {
329
+ originalName,
330
+ filename,
331
+ path: uploadPath,
332
+ size: stats.size,
333
+ extension: ext,
334
+ hash,
335
+ };
336
+ ensureLogger().info("User file uploaded successfully", {
337
+ originalName,
338
+ filename,
339
+ size: stats.size,
340
+ hash,
341
+ });
342
+ return uploadedFile;
343
+ }
344
+ /**
345
+ * Clean temporary files older than a given age. Falls back to ./temp to
346
+ * preserve the previous middleware behaviour.
347
+ */
348
+ async cleanTempFiles(maxAgeMs = 24 * 60 * 60 * 1000, tempDir = path.join(process.cwd(), "temp")) {
349
+ await fsUtils.ensureDir(tempDir);
350
+ const now = Date.now();
351
+ let deletedCount = 0;
352
+ try {
353
+ const files = await fsUtils.readdir(tempDir);
354
+ for (const file of files) {
355
+ const filePath = path.join(tempDir, file);
356
+ const stats = await fsUtils.stat(filePath);
357
+ if (!stats.isFile())
358
+ continue;
359
+ if (now - stats.mtimeMs > maxAgeMs) {
360
+ await fsUtils.unlink(filePath);
361
+ deletedCount++;
362
+ }
363
+ }
364
+ if (deletedCount > 0) {
365
+ ensureLogger().info(`Cleaned ${deletedCount} temporary file(s) older than ${Math.round(maxAgeMs / (1000 * 60 * 60))}h`);
366
+ }
367
+ }
368
+ catch (_error) {
369
+ ensureLogger().error("Error cleaning temp files:", _error);
370
+ }
371
+ return deletedCount;
372
+ }
373
+ /**
374
+ * Save internal application data
375
+ * @param data - Data to save
376
+ * @param filename - Filename for the data
377
+ * @param category - Category/directory for the data
378
+ * @param options - Save options
379
+ */
380
+ async saveInternalData(data, filename, category = "data", options = {}) {
381
+ // If data is an object, stringify it
382
+ const finalData = typeof data === "object" && !Buffer.isBuffer(data)
383
+ ? JSON.stringify(data, null, 2)
384
+ : data;
385
+ // Use the existing save method
386
+ return this.saveFile(finalData, filename, category, options);
387
+ }
388
+ }
389
+ // Singleton instance
390
+ let storageService = null;
391
+ export function getStorageService() {
392
+ if (!storageService) {
393
+ storageService = new StorageService();
394
+ }
395
+ return storageService;
396
+ }
397
+ // Backward compatibility export (deprecated)
398
+ export function getSecureFileHandler() {
399
+ console.warn("getSecureFileHandler is deprecated. Use getStorageService instead.");
400
+ return getStorageService();
401
+ }
402
+ // Export for backward compatibility (deprecated)
403
+ export { StorageService as SecureFileHandler };
404
+ export default StorageService;
405
+ //# sourceMappingURL=storageService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageService.js","sourceRoot":"","sources":["../../src/core/storageService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Desktop Bundler Module
3
+ * Handles bundling Node.js backends for Electron desktop applications
4
+ */
5
+ export interface BundleOptions {
6
+ entryPoint: string;
7
+ outDir: string;
8
+ appName: string;
9
+ version: string;
10
+ platform?: "node" | "neutral";
11
+ target?: string;
12
+ format?: "cjs" | "esm";
13
+ minify?: boolean;
14
+ sourcemap?: boolean;
15
+ external?: string[];
16
+ env?: Record<string, string>;
17
+ resources?: {
18
+ config?: string;
19
+ data?: string[];
20
+ };
21
+ nativeModules?: {
22
+ autoDetect?: boolean;
23
+ modules?: string[];
24
+ rebuild?: boolean;
25
+ };
26
+ }
27
+ /**
28
+ * Bundle a Node.js backend for desktop deployment
29
+ */
30
+ export declare function bundleBackend(options: BundleOptions): Promise<void>;
31
+ /**
32
+ * Bundle dependencies separately for better caching
33
+ */
34
+ export declare function bundleDependencies(packageJsonPath: string, outDir: string): Promise<void>;
35
+ declare const _default: {
36
+ bundleBackend: typeof bundleBackend;
37
+ bundleDependencies: typeof bundleDependencies;
38
+ };
39
+ export default _default;
40
+ //# sourceMappingURL=bundler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundler.d.ts","sourceRoot":"","sources":["../../src/desktop/bundler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,aAAa,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6HzE;AA6CD;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAqCf;;;;;AAED,wBAGE"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Desktop Bundler Module
3
+ * Handles bundling Node.js backends for Electron desktop applications
4
+ */
5
+ import * as esbuild from "esbuild";
6
+ import { ensureDir, writeFile, stat, copy, move, remove, writeJson, } from "../utils/fs-utils.js";
7
+ import path from "path";
8
+ import { execSync } from "child_process";
9
+ import { createLogger } from "../core/index.js";
10
+ import { detectNativeModules, copyNativeModules, createNativeModuleLoader, } from "./native-modules.js";
11
+ const logger = createLogger("DesktopBundler");
12
+ /**
13
+ * Bundle a Node.js backend for desktop deployment
14
+ */
15
+ export async function bundleBackend(options) {
16
+ const { entryPoint, outDir, appName, version, platform = "node", target = "node18", format = "cjs", minify = false, sourcemap = false, external = [], env = {}, resources = {}, } = options;
17
+ logger.info(`Bundling backend for ${appName} v${version}`);
18
+ // Ensure output directory exists
19
+ await ensureDir(outDir);
20
+ // Default externals for Node.js
21
+ const defaultExternals = [
22
+ "fsevents", // Mac-specific, optional
23
+ "bufferutil", // Optional WebSocket performance
24
+ "utf-8-validate", // Optional WebSocket validation
25
+ "@superdangerous/app-framework/ui", // UI components not needed in backend
26
+ "serialport", // Optional serial port support
27
+ "@serialport/bindings-cpp", // Optional serial port bindings
28
+ "@aws-sdk/client-s3", // Optional AWS S3 support
29
+ "modbus-serial", // Optional Modbus communication
30
+ ];
31
+ // Build with esbuild
32
+ const result = await esbuild.build({
33
+ entryPoints: [entryPoint],
34
+ bundle: true,
35
+ platform,
36
+ target,
37
+ outfile: path.join(outDir, "backend.js"),
38
+ format,
39
+ minify,
40
+ sourcemap,
41
+ external: [...defaultExternals, ...external],
42
+ define: {
43
+ "process.env.NODE_ENV": '"production"',
44
+ "process.env.DESKTOP_MODE": '"true"',
45
+ ...Object.entries(env).reduce((acc, [key, value]) => {
46
+ acc[`process.env.${key}`] = JSON.stringify(value);
47
+ return acc;
48
+ }, {}),
49
+ },
50
+ loader: {
51
+ ".node": "file",
52
+ ".json": "json",
53
+ },
54
+ metafile: true,
55
+ logLevel: "info",
56
+ });
57
+ // Write metafile for analysis
58
+ await writeFile(path.join(outDir, "backend-meta.json"), JSON.stringify(result.metafile, null, 2));
59
+ // Create wrapper script
60
+ const wrapperScript = generateWrapperScript(appName, format);
61
+ await writeFile(path.join(outDir, "start-backend.js"), wrapperScript);
62
+ // Copy resources
63
+ if (resources.config) {
64
+ const configDest = path.join(outDir, "config");
65
+ await ensureDir(configDest);
66
+ await copy(resources.config, path.join(configDest, "app.json"));
67
+ }
68
+ if (resources.data) {
69
+ const dataDir = path.join(outDir, "data");
70
+ for (const dir of resources.data) {
71
+ await ensureDir(path.join(dataDir, dir));
72
+ }
73
+ }
74
+ // Handle native modules if configured
75
+ if (options.nativeModules) {
76
+ const projectDir = path.dirname(entryPoint);
77
+ // Detect native modules if requested
78
+ let nativeModulesList = options.nativeModules.modules || [];
79
+ if (options.nativeModules.autoDetect) {
80
+ const detected = await detectNativeModules(projectDir);
81
+ nativeModulesList = [...new Set([...nativeModulesList, ...detected])];
82
+ logger.info(`Detected native modules: ${nativeModulesList.join(", ")}`);
83
+ }
84
+ // Copy native modules to output directory
85
+ if (nativeModulesList.length > 0) {
86
+ await copyNativeModules({
87
+ modules: nativeModulesList,
88
+ sourceDir: projectDir,
89
+ targetDir: outDir,
90
+ rebuild: options.nativeModules.rebuild,
91
+ });
92
+ // Create native module loader
93
+ await createNativeModuleLoader(path.join(outDir, "native-loader.js"), nativeModulesList);
94
+ logger.info(`Copied ${nativeModulesList.length} native modules`);
95
+ }
96
+ }
97
+ // Get bundle size
98
+ const stats = await stat(path.join(outDir, "backend.js"));
99
+ const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
100
+ logger.info(`✅ Backend bundled successfully!`);
101
+ logger.info(` Bundle size: ${sizeMB} MB`);
102
+ logger.info(` Location: ${outDir}/backend.js`);
103
+ }
104
+ /**
105
+ * Generate wrapper script for starting the bundled backend
106
+ */
107
+ function generateWrapperScript(appName, format) {
108
+ return `#!/usr/bin/env node
109
+
110
+ /**
111
+ * Desktop App Backend Wrapper for ${appName}
112
+ * Sets up environment and starts the bundled backend
113
+ */
114
+
115
+ ${format === "esm" ? "import { fileURLToPath } from 'url';" : ""}
116
+ ${format === "esm" ? "import { dirname, join } from 'path';" : "const path = require('path');"}
117
+
118
+ ${format === "esm"
119
+ ? `
120
+ const __filename = fileURLToPath(import.meta.url);
121
+ const __dirname = dirname(__filename);
122
+ `
123
+ : ""}
124
+
125
+ // Set environment variables
126
+ process.env.NODE_ENV = process.env.NODE_ENV || 'production';
127
+ process.env.DESKTOP_MODE = 'true';
128
+
129
+ // Set data directory to app data location
130
+ if (!process.env.DATA_DIR) {
131
+ // In production, this will be set by Electron
132
+ // For testing, use a local data directory
133
+ process.env.DATA_DIR = ${format === "esm" ? "join" : "path.join"}(__dirname, 'data');
134
+ }
135
+
136
+ // Note: Using console.log in wrapper script as it runs in production without logger
137
+ console.log('Starting ${appName} Backend...');
138
+ console.log('Data directory:', process.env.DATA_DIR);
139
+
140
+ // Start the bundled backend
141
+ ${format === "cjs" ? "require('./backend.js');" : "import('./backend.js');"}
142
+ `;
143
+ }
144
+ /**
145
+ * Bundle dependencies separately for better caching
146
+ */
147
+ export async function bundleDependencies(packageJsonPath, outDir) {
148
+ const fs = await import("fs");
149
+ const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, "utf8"));
150
+ const dependencies = packageJson.dependencies || {};
151
+ logger.info("Installing production dependencies...");
152
+ // Create temporary directory for dependencies
153
+ const tempDir = path.join(outDir, "temp");
154
+ await ensureDir(tempDir);
155
+ // Create minimal package.json
156
+ const minimalPackage = {
157
+ name: packageJson.name,
158
+ version: packageJson.version,
159
+ dependencies,
160
+ };
161
+ await writeJson(path.join(tempDir, "package.json"), minimalPackage);
162
+ // Install production dependencies
163
+ execSync("npm install --production --no-audit --no-fund", {
164
+ cwd: tempDir,
165
+ stdio: "inherit",
166
+ });
167
+ // Move node_modules to output directory
168
+ await move(path.join(tempDir, "node_modules"), path.join(outDir, "node_modules"), { overwrite: true });
169
+ // Clean up temp directory
170
+ await remove(tempDir);
171
+ }
172
+ export default {
173
+ bundleBackend,
174
+ bundleDependencies,
175
+ };
176
+ //# sourceMappingURL=bundler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundler.js","sourceRoot":"","sources":["../../src/desktop/bundler.ts"],"names":[],"mappings":"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"}