fragment-ts 1.0.45 → 1.0.47

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 (65) hide show
  1. package/README.md +96 -91
  2. package/dist/cli/commands/build.command.d.ts.map +1 -1
  3. package/dist/cli/commands/build.command.js +12 -19
  4. package/dist/cli/commands/build.command.js.map +1 -1
  5. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -1
  6. package/dist/cli/commands/diagnostics.command.js +68 -14
  7. package/dist/cli/commands/diagnostics.command.js.map +1 -1
  8. package/dist/cli/commands/env.config.d.ts +10 -0
  9. package/dist/cli/commands/env.config.d.ts.map +1 -0
  10. package/dist/cli/commands/env.config.js +202 -0
  11. package/dist/cli/commands/env.config.js.map +1 -0
  12. package/dist/cli/commands/generate.command.js +9 -9
  13. package/dist/cli/commands/init.command.d.ts.map +1 -1
  14. package/dist/cli/commands/init.command.js +16 -59
  15. package/dist/cli/commands/init.command.js.map +1 -1
  16. package/dist/cli/commands/migrate.command.d.ts +5 -4
  17. package/dist/cli/commands/migrate.command.d.ts.map +1 -1
  18. package/dist/cli/commands/migrate.command.js +34 -9
  19. package/dist/cli/commands/migrate.command.js.map +1 -1
  20. package/dist/cli/commands/serve.command.d.ts.map +1 -1
  21. package/dist/cli/commands/serve.command.js +74 -38
  22. package/dist/cli/commands/serve.command.js.map +1 -1
  23. package/dist/cli/commands/test.command.d.ts.map +1 -1
  24. package/dist/cli/commands/test.command.js +21 -9
  25. package/dist/cli/commands/test.command.js.map +1 -1
  26. package/dist/cli/index.js +3 -12
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/core/scanner/component-scanner.d.ts +4 -0
  29. package/dist/core/scanner/component-scanner.d.ts.map +1 -1
  30. package/dist/core/scanner/component-scanner.js +15 -0
  31. package/dist/core/scanner/component-scanner.js.map +1 -1
  32. package/dist/shared/config.utils.d.ts +2 -3
  33. package/dist/shared/config.utils.d.ts.map +1 -1
  34. package/dist/shared/config.utils.js +2 -3
  35. package/dist/shared/config.utils.js.map +1 -1
  36. package/dist/shared/env.utils.d.ts +6 -6
  37. package/dist/shared/env.utils.d.ts.map +1 -1
  38. package/dist/shared/env.utils.js +25 -84
  39. package/dist/shared/env.utils.js.map +1 -1
  40. package/dist/testing/runner.d.ts.map +1 -1
  41. package/dist/testing/runner.js +12 -2
  42. package/dist/testing/runner.js.map +1 -1
  43. package/dist/typeorm/typeorm-module.d.ts.map +1 -1
  44. package/dist/typeorm/typeorm-module.js +3 -6
  45. package/dist/typeorm/typeorm-module.js.map +1 -1
  46. package/dist/web/application.d.ts.map +1 -1
  47. package/dist/web/application.js +20 -1
  48. package/dist/web/application.js.map +1 -1
  49. package/examples/blog-api/package-lock.json +0 -38
  50. package/package.json +3 -3
  51. package/src/cli/commands/build.command.ts +13 -29
  52. package/src/cli/commands/diagnostics.command.ts +74 -13
  53. package/src/cli/commands/{env.command.ts → env.config.ts} +9 -32
  54. package/src/cli/commands/generate.command.ts +9 -9
  55. package/src/cli/commands/init.command.ts +17 -63
  56. package/src/cli/commands/migrate.command.ts +37 -9
  57. package/src/cli/commands/serve.command.ts +205 -170
  58. package/src/cli/commands/test.command.ts +30 -8
  59. package/src/cli/index.ts +3 -12
  60. package/src/core/scanner/component-scanner.ts +15 -0
  61. package/src/shared/config.utils.ts +5 -6
  62. package/src/shared/env.utils.ts +27 -55
  63. package/src/testing/runner.ts +11 -2
  64. package/src/typeorm/typeorm-module.ts +4 -18
  65. package/src/web/application.ts +21 -1
@@ -4,7 +4,8 @@ import * as fs from "fs";
4
4
  import * as path from "path";
5
5
  import { EnvUtils } from "./env.utils";
6
6
 
7
- interface FragmentDatabaseConfig {
7
+ // Flat structure only
8
+ export interface FragmentDatabaseConfig {
8
9
  type?: string;
9
10
  host?: string;
10
11
  port?: number;
@@ -22,7 +23,7 @@ interface FragmentDatabaseConfig {
22
23
  }
23
24
 
24
25
  // Only support flat structure now
25
- interface FragmentConfig {
26
+ export interface FragmentConfig {
26
27
  database?: FragmentDatabaseConfig;
27
28
  }
28
29
 
@@ -41,9 +42,7 @@ export class ConfigUtils {
41
42
  try {
42
43
  const raw = fs.readFileSync(configPath, "utf-8");
43
44
  this.configCache = JSON.parse(raw) || {};
44
- if (!this.configCache) {
45
- return {};
46
- }
45
+ if (!this.configCache) return {};
47
46
  return this.configCache;
48
47
  } catch (error) {
49
48
  console.error("❌ Error loading fragment.json:", error);
@@ -74,7 +73,7 @@ export class ConfigUtils {
74
73
  return value;
75
74
  }
76
75
 
77
- // Always return the single database config
76
+ // ONLY use top-level `database`
78
77
  static getDatabaseConfig(): FragmentDatabaseConfig {
79
78
  const config = this.loadConfig();
80
79
  if (config.database) {
@@ -1,78 +1,50 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
-
4
1
  export class EnvUtils {
5
2
  static getString(key: string, defaultValue?: string): string {
6
- return process.env[key] ?? defaultValue ?? "";
3
+ const value = process.env[key];
4
+ return value !== undefined ? value : (defaultValue ?? "");
7
5
  }
8
6
 
9
- static getBoolean(key: string, defaultValue = false): boolean {
10
- const val = process.env[key];
11
- if (val === undefined) return defaultValue;
12
- return ["true", "1", "yes", "on"].includes(val.toLowerCase());
7
+ static getBoolean(key: string, defaultValue: boolean = false): boolean {
8
+ const value = process.env[key];
9
+ if (value === undefined) return defaultValue;
10
+ return ["true", "1", "yes", "on"].includes(value.toLowerCase());
13
11
  }
14
12
 
15
- static getNumber(key: string, defaultValue = 0): number {
16
- const val = process.env[key];
17
- if (val === undefined) return defaultValue;
18
- const num = Number(val);
13
+ static getNumber(key: string, defaultValue: number = 0): number {
14
+ const value = process.env[key];
15
+ if (value === undefined) return defaultValue;
16
+ const num = Number(value);
19
17
  return isNaN(num) ? defaultValue : num;
20
18
  }
21
19
 
22
20
  static getJson<T>(key: string, defaultValue: T): T {
23
- const val = process.env[key];
24
- if (val === undefined) return defaultValue;
21
+ const value = process.env[key];
22
+ if (value === undefined) return defaultValue;
25
23
  try {
26
- return JSON.parse(val) as T;
24
+ return JSON.parse(value) as T;
27
25
  } catch {
28
- console.warn(`⚠️ Invalid JSON in env var ${key}`);
26
+ console.warn(`⚠️ Invalid JSON in env var ${key}, using default`);
29
27
  return defaultValue;
30
28
  }
31
29
  }
32
30
 
33
31
  /**
34
- * Returns the current environment name based on the active .env file.
35
- * - If .env matches .env.prod → returns "prod"
36
- * - If .env matches .env.staging → returns "staging"
37
- * - If .env is custom or unmatched → returns "local"
38
- * - If no .env exists → returns "default"
32
+ * Check if running in development mode
39
33
  */
40
- static getEnv(): string {
41
- const cwd = process.cwd();
42
- const envPath = path.join(cwd, ".env");
43
-
44
- // Fast path: check for .env.mode (written by `fragment env:use`)
45
- const modePath = path.join(cwd, ".env.mode");
46
- if (fs.existsSync(modePath)) {
47
- try {
48
- const mode = fs.readFileSync(modePath, "utf8").trim();
49
- if (mode) return mode;
50
- } catch {
51
- // Ignore read errors
52
- }
34
+ static isDevelopmentMode(): boolean {
35
+ if (process.env.FRAGMENT_DEV_MODE !== undefined) {
36
+ return process.env.FRAGMENT_DEV_MODE === "true";
53
37
  }
54
-
55
- // Fallback: compare .env content with .env.* files
56
- if (!fs.existsSync(envPath)) {
57
- return "default";
58
- }
59
-
60
- const envContent = fs.readFileSync(envPath, "utf8");
61
- const files = fs.readdirSync(cwd).filter((f) => /^\.env\..+$/.test(f));
62
-
63
- for (const file of files) {
64
- const name = file.replace(/\.env\./, "");
65
- const fullPath = path.join(cwd, file);
66
- try {
67
- const content = fs.readFileSync(fullPath, "utf8");
68
- if (content === envContent) {
69
- return name;
70
- }
71
- } catch {
72
- // Skip unreadable files
73
- }
38
+ if (process.env.NODE_ENV) {
39
+ return process.env.NODE_ENV === "development";
74
40
  }
41
+ return false;
42
+ }
75
43
 
76
- return "local"; // custom or modified .env
44
+ /**
45
+ * Get current environment mode ('development' or 'production')
46
+ */
47
+ static getEnvironmentMode(): "development" | "production" {
48
+ return this.isDevelopmentMode() ? "development" : "production";
77
49
  }
78
50
  }
@@ -191,8 +191,17 @@ export class TestRunner {
191
191
  * Auto-detect test patterns based on environment and configuration
192
192
  */
193
193
  getAutoTestPattern(): string {
194
- const srcDir = TsConfigUtils.getRootDir();
195
- return `${path.relative(process.cwd(), srcDir)}/**/*.spec.ts`;
194
+ const isDevMode = EnvUtils.isDevelopmentMode();
195
+
196
+ if (isDevMode) {
197
+ // Development mode - use TypeScript
198
+ const srcDir = TsConfigUtils.getRootDir();
199
+ return `${path.relative(process.cwd(), srcDir)}/**/*.spec.ts`;
200
+ } else {
201
+ // Production mode - use JavaScript
202
+ const outDir = TsConfigUtils.getOutDir();
203
+ return `${path.relative(process.cwd(), outDir)}/**/*.spec.js`;
204
+ }
196
205
  }
197
206
  }
198
207
 
@@ -24,7 +24,7 @@ import { BetterSqlite3ConnectionOptions } from "typeorm/driver/better-sqlite3/Be
24
24
  import { CapacitorConnectionOptions } from "typeorm/driver/capacitor/CapacitorConnectionOptions";
25
25
  import { SpannerConnectionOptions } from "typeorm/driver/spanner/SpannerConnectionOptions";
26
26
  import { EnvUtils } from "../shared/env.utils";
27
- import { ConfigUtils } from "../shared/config.utils";
27
+ import { ConfigUtils, FragmentConfig } from "../shared/config.utils";
28
28
 
29
29
  /* ======================================================
30
30
  * Concrete configs TypeORM accepts
@@ -72,16 +72,6 @@ type SupportedDatabaseConfig =
72
72
  | Partial<CapacitorConnectionOptions>
73
73
  | Partial<SpannerConnectionOptions>;
74
74
 
75
- // New interface for the fragment.json structure
76
- interface FragmentConfig {
77
- development?: {
78
- database?: SupportedDatabaseConfig;
79
- };
80
- production?: {
81
- database?: SupportedDatabaseConfig;
82
- };
83
- }
84
-
85
75
  export class TypeORMModule {
86
76
  private static dataSource: DataSource;
87
77
 
@@ -749,14 +739,10 @@ export class TypeORMModule {
749
739
  fs.readFileSync(configPath, "utf-8"),
750
740
  ) as FragmentConfig;
751
741
 
752
- if (!raw.development) {
753
- throw new Error("fragment config not found | Invalid");
754
- }
755
- var dbConfig;
756
-
757
- dbConfig = raw.development.database;
742
+ // Simply use the top-level `database` object
743
+ const dbConfig = raw.database || {};
758
744
 
759
- // Interpolate environment variables
745
+ // Interpolate environment variables like ${DB_HOST}
760
746
  return this.interpolateEnvVars(dbConfig);
761
747
  } catch (error) {
762
748
  console.error(`Error loading fragment.json: ${error}`);
@@ -90,7 +90,27 @@ export class FragmentWebApplication {
90
90
  const distExists = fs.existsSync(path.join(cwd, "dist"));
91
91
  const srcExists = fs.existsSync(path.join(cwd, "src"));
92
92
 
93
- await ComponentScanner.scanSource();
93
+ console.log(`📁 Current working directory: ${cwd}`);
94
+ console.log(`📁 dist/ exists: ${distExists}`);
95
+ console.log(`📁 src/ exists: ${srcExists}`);
96
+
97
+ // Use EnvUtils for consistent environment detection
98
+ const isDevMode = EnvUtils.isDevelopmentMode();
99
+ console.log(
100
+ `💻 Running in ${isDevMode ? "development" : "production"} mode`,
101
+ );
102
+
103
+ if (isDevMode && srcExists) {
104
+ // Development mode: scan TypeScript source files
105
+ console.log(" 📝 Development mode: scanning TypeScript files");
106
+ await ComponentScanner.scanSource();
107
+ } else if (distExists) {
108
+ // Production mode: scan compiled JavaScript files
109
+ console.log(" 📦 Production mode: scanning compiled files");
110
+ await ComponentScanner.scan();
111
+ } else {
112
+ console.warn(" ⚠️ Warning: No src/ or dist/ directory found");
113
+ }
94
114
  }
95
115
 
96
116
  // Remove the old isRunningTypeScript method since we're using EnvUtils