fragment-ts 1.0.30 → 1.0.31

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.
@@ -34,7 +34,7 @@ export class FragmentWebApplication {
34
34
 
35
35
  async bootstrap(appClass: any): Promise<void> {
36
36
  console.log("\nšŸš€ Bootstrapping application");
37
-
37
+
38
38
  try {
39
39
  await TypeORMModule.initialize();
40
40
  console.log("āœ… TypeORM initialized successfully");
@@ -47,7 +47,7 @@ export class FragmentWebApplication {
47
47
  METADATA_KEYS.APPLICATION,
48
48
  appClass,
49
49
  );
50
-
50
+
51
51
  console.log(`šŸŽÆ Application metadata:`, appMetadata);
52
52
 
53
53
  // CRITICAL: Scan and load all component files first
@@ -63,11 +63,13 @@ export class FragmentWebApplication {
63
63
 
64
64
  const port = appMetadata?.port || 3000;
65
65
  const host = appMetadata?.host || "0.0.0.0";
66
-
66
+
67
67
  this.app.use(this.errorHandler.bind(this));
68
-
68
+
69
69
  this.app.listen(port, host, () => {
70
- console.log(`\n✨ Fragment application running on http://${host}:${port}`);
70
+ console.log(
71
+ `\n✨ Fragment application running on http://${host}:${port}`,
72
+ );
71
73
  console.log("========================================\n");
72
74
  });
73
75
  }
@@ -76,15 +78,17 @@ export class FragmentWebApplication {
76
78
  const cwd = process.cwd();
77
79
  const distExists = fs.existsSync(path.join(cwd, "dist"));
78
80
  const srcExists = fs.existsSync(path.join(cwd, "src"));
79
-
81
+
80
82
  console.log(`šŸ“ Current working directory: ${cwd}`);
81
83
  console.log(`šŸ“ dist/ exists: ${distExists}`);
82
84
  console.log(`šŸ“ src/ exists: ${srcExists}`);
83
85
 
84
86
  // Determine if we're running TypeScript directly (dev) or compiled JS (prod)
85
87
  const isDevMode = this.isRunningTypeScript();
86
- console.log(`šŸ’» Running in ${isDevMode ? 'development' : 'production'} mode`);
87
-
88
+ console.log(
89
+ `šŸ’» Running in ${isDevMode ? "development" : "production"} mode`,
90
+ );
91
+
88
92
  if (isDevMode && srcExists) {
89
93
  // Development mode: scan TypeScript source files
90
94
  console.log(" šŸ“ Development mode: scanning TypeScript files");
@@ -103,11 +107,11 @@ export class FragmentWebApplication {
103
107
  if (require.extensions[".ts"]) {
104
108
  return true;
105
109
  }
106
-
110
+
107
111
  // Check if process is running with ts-node or tsx
108
112
  const execPath = process.argv[0];
109
113
  const scriptPath = process.argv[1] || "";
110
-
114
+
111
115
  if (
112
116
  execPath.includes("ts-node") ||
113
117
  execPath.includes("tsx") ||
@@ -116,24 +120,24 @@ export class FragmentWebApplication {
116
120
  ) {
117
121
  return true;
118
122
  }
119
-
123
+
120
124
  // Check if main module has .ts extension
121
125
  if (require.main?.filename.endsWith(".ts")) {
122
126
  return true;
123
127
  }
124
-
128
+
125
129
  // Check NODE_ENV or explicit flag
126
130
  if (process.env.FRAGMENT_DEV_MODE === "true") {
127
131
  return true;
128
132
  }
129
-
133
+
130
134
  return false;
131
135
  }
132
136
 
133
137
  private discoverAndRegisterComponents(): void {
134
138
  const classes = this.metadataStorage.getAllClasses();
135
139
  console.log(`\nšŸ“¦ Discovered ${classes.length} component(s)`);
136
-
140
+
137
141
  // Group by type for display
138
142
  const grouped = classes.reduce(
139
143
  (acc, cls) => {
@@ -143,19 +147,21 @@ export class FragmentWebApplication {
143
147
  },
144
148
  {} as Record<string, any[]>,
145
149
  );
146
-
150
+
147
151
  Object.entries(grouped).forEach(([type, items]) => {
148
152
  const icon = this.getTypeIcon(type);
149
153
  console.log(` ${icon} ${items.length} ${type}(s)`);
150
-
151
- items.forEach(item => {
152
- console.log(` • ${item.target.name}${item.path ? ` (${item.path})` : ''}`);
154
+
155
+ items.forEach((item) => {
156
+ console.log(
157
+ ` • ${item.target.name}${item.path ? ` (${item.path})` : ""}`,
158
+ );
153
159
  });
154
160
  });
155
161
 
156
162
  let registered = 0;
157
163
  let skipped = 0;
158
-
164
+
159
165
  classes.forEach((metadata) => {
160
166
  if (this.shouldRegister(metadata.target)) {
161
167
  // CRITICAL: Register with container
@@ -178,10 +184,10 @@ export class FragmentWebApplication {
178
184
  if (skipped > 0) {
179
185
  console.log(`⊘ Skipped ${skipped} component(s) (conditions not met)`);
180
186
  }
181
-
187
+
182
188
  // Pre-resolve all singleton components to ensure dependencies are injected
183
189
  console.log("\nšŸ”§ Initializing components");
184
- classes.forEach(metadata => {
190
+ classes.forEach((metadata) => {
185
191
  if (this.shouldRegister(metadata.target)) {
186
192
  const instance = this.container.resolve(metadata.target);
187
193
  console.log(` āœ“ Initialized: ${metadata.target.name}`);
@@ -205,9 +211,11 @@ export class FragmentWebApplication {
205
211
  METADATA_KEYS.CONDITIONAL_ON_CLASS,
206
212
  target,
207
213
  );
208
-
214
+
209
215
  if (conditionalClass && !this.isClassAvailable(conditionalClass)) {
210
- console.log(` 🚫 Conditional check failed for ${target.name}: Class not available`);
216
+ console.log(
217
+ ` 🚫 Conditional check failed for ${target.name}: Class not available`,
218
+ );
211
219
  return false;
212
220
  }
213
221
 
@@ -215,9 +223,11 @@ export class FragmentWebApplication {
215
223
  METADATA_KEYS.CONDITIONAL_ON_MISSING_BEAN,
216
224
  target,
217
225
  );
218
-
226
+
219
227
  if (conditionalMissingBean && this.container.has(conditionalMissingBean)) {
220
- console.log(` 🚫 Conditional check failed for ${target.name}: Bean already exists`);
228
+ console.log(
229
+ ` 🚫 Conditional check failed for ${target.name}: Bean already exists`,
230
+ );
221
231
  return false;
222
232
  }
223
233
 
@@ -225,17 +235,21 @@ export class FragmentWebApplication {
225
235
  METADATA_KEYS.CONDITIONAL_ON_PROPERTY,
226
236
  target,
227
237
  );
228
-
238
+
229
239
  if (conditionalProperty) {
230
240
  const value = process.env[conditionalProperty.key];
231
-
241
+
232
242
  if (conditionalProperty.expectedValue !== undefined) {
233
243
  if (value !== conditionalProperty.expectedValue) {
234
- console.log(` 🚫 Conditional check failed for ${target.name}: Expected ${conditionalProperty.expectedValue}, got ${value}`);
244
+ console.log(
245
+ ` 🚫 Conditional check failed for ${target.name}: Expected ${conditionalProperty.expectedValue}, got ${value}`,
246
+ );
235
247
  return false;
236
248
  }
237
249
  } else if (!value) {
238
- console.log(` 🚫 Conditional check failed for ${target.name}: Property not set`);
250
+ console.log(
251
+ ` 🚫 Conditional check failed for ${target.name}: Property not set`,
252
+ );
239
253
  return false;
240
254
  }
241
255
  }
@@ -255,44 +269,44 @@ export class FragmentWebApplication {
255
269
  const controllers = this.metadataStorage
256
270
  .getAllClasses()
257
271
  .filter((c) => c.type === "controller");
258
-
272
+
259
273
  if (controllers.length === 0) {
260
274
  console.log("\nšŸ›£ļø No routes to register");
261
275
  return;
262
276
  }
263
-
277
+
264
278
  let totalRoutes = 0;
265
279
  console.log(`\nšŸ›£ļø Registering routes...`);
266
-
280
+
267
281
  controllers.forEach((controllerMetadata) => {
268
282
  try {
269
283
  console.log(`\nšŸ“ Controller: ${controllerMetadata.target.name}`);
270
- console.log(` Base path: ${controllerMetadata.path || '/'}`);
271
-
284
+ console.log(` Base path: ${controllerMetadata.path || "/"}`);
285
+
272
286
  const controller = this.container.resolve(controllerMetadata.target);
273
287
  const basePath = controllerMetadata.path || "";
274
-
288
+
275
289
  const methods = this.metadataStorage
276
290
  .getAllMethods()
277
291
  .filter((m) => m.target === controllerMetadata.target);
278
-
292
+
279
293
  if (methods.length === 0) {
280
294
  console.log(` āš ļø No routes defined for this controller`);
281
295
  return;
282
296
  }
283
-
297
+
284
298
  methods.forEach((methodMetadata) => {
285
299
  const fullPath = this.normalizePath(basePath + methodMetadata.path);
286
300
  const httpMethod = methodMetadata.method.toLowerCase();
287
301
  const methodColor = this.getMethodColor(httpMethod);
288
302
  const methodIcon = this.getMethodIcon(httpMethod);
289
-
303
+
290
304
  console.log(
291
305
  ` ${methodIcon} ${methodColor}${httpMethod.toUpperCase().padEnd(7)}\x1b[0m ${fullPath}`,
292
306
  );
293
-
307
+
294
308
  totalRoutes++;
295
-
309
+
296
310
  (this.app as any)[httpMethod](
297
311
  fullPath,
298
312
  async (req: Request, res: Response, next: NextFunction) => {
@@ -302,14 +316,16 @@ export class FragmentWebApplication {
302
316
  req,
303
317
  res,
304
318
  );
305
-
306
- console.log(`\nšŸ” Handling ${httpMethod.toUpperCase()} ${fullPath}`);
319
+
320
+ console.log(
321
+ `\nšŸ” Handling ${httpMethod.toUpperCase()} ${fullPath}`,
322
+ );
307
323
  // console.log(` Parameters:`, args);
308
-
324
+
309
325
  const result = await (controller as any)[
310
326
  methodMetadata.propertyKey
311
327
  ](...args);
312
-
328
+
313
329
  if (!res.headersSent) {
314
330
  res.json(result);
315
331
  }
@@ -321,7 +337,10 @@ export class FragmentWebApplication {
321
337
  );
322
338
  });
323
339
  } catch (error) {
324
- console.error(`āŒ Failed to register controller ${controllerMetadata.target.name}:`, error);
340
+ console.error(
341
+ `āŒ Failed to register controller ${controllerMetadata.target.name}:`,
342
+ error,
343
+ );
325
344
  }
326
345
  });
327
346
 
@@ -358,7 +377,7 @@ export class FragmentWebApplication {
358
377
  const params = [...methodMetadata.paramMetadata].sort(
359
378
  (a: any, b: any) => a.index - b.index,
360
379
  );
361
-
380
+
362
381
  return params.map((param: any) => {
363
382
  switch (param.type) {
364
383
  case "body":
@@ -402,4 +421,4 @@ export class FragmentWebApplication {
402
421
  getExpressApp(): Express {
403
422
  return this.app;
404
423
  }
405
- }
424
+ }