vasuzex 2.2.4 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,58 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to Vasuzex will be documented in this file.
4
+
5
+ ## [2.3.0] - 2026-02-18
6
+
7
+ ### 🚀 Standalone Script Support
8
+
9
+ This release enables Config and Log facades to work in standalone scripts without Application instance, following Laravel's graceful degradation pattern.
10
+
11
+ ### ✨ Added
12
+
13
+ #### Config Facade Standalone Mode
14
+ - **Standalone script support** - Config.get() now works without Application instance
15
+ - **Auto-discovery** - Walks up directory tree to find project root with `config/` directory
16
+ - **Config loading** - Loads all .cjs files from `config/` directory using require()
17
+ - **Dot notation** - Full support for nested keys (`database.connections.default.host`)
18
+ - **Caching** - Loaded config cached for performance
19
+ - **Graceful fallback** - Tries Application-bound service first, falls back if unavailable
20
+ ```javascript
21
+ // Now works in standalone scripts!
22
+ import { Config } from 'vasuzex';
23
+ const dbHost = Config.get('database.connections.default.host', 'localhost');
24
+ ```
25
+
26
+ #### Log Facade Standalone Mode
27
+ - **Standalone script support** - Log methods now work without Application instance
28
+ - **Console fallback** - Falls back to console.log with structured formatting
29
+ - **ISO timestamps** - Production-quality log output: `[2026-02-18T05:21:16.107Z] [INFO] message`
30
+ - **Respects LOG_LEVEL** - Debug logs only show if `LOG_LEVEL=debug` or `DEBUG=true`
31
+ - **All log levels** - debug(), info(), warn(), error() all supported
32
+ - **Graceful fallback** - Tries Application-bound logger first, falls back if unavailable
33
+ ```javascript
34
+ // Now works in standalone scripts!
35
+ import { Log } from 'vasuzex';
36
+ Log.info('Processing data', { records: 100 });
37
+ // Output: [2026-02-18T05:21:16.107Z] [INFO] Processing data {"records":100}
38
+ ```
39
+
40
+ ### 🔧 Technical Details
41
+
42
+ - **Service container priority** - Always tries Application instance first (backward compatible)
43
+ - **Zero breaking changes** - All existing apps continue working unchanged
44
+ - **Laravel pattern** - Follows Laravel's facade graceful degradation pattern
45
+ - **Production-ready** - Proper error handling, silent failures, performance optimized
46
+
47
+ ### 🎯 Use Cases
48
+
49
+ This enables:
50
+ - ✅ Database migration scripts using Config.get()
51
+ - ✅ Cron jobs and workers using Log.info()
52
+ - ✅ CLI tools without full Application bootstrap
53
+ - ✅ Test scripts accessing configuration
54
+ - ✅ Utility scripts with proper logging
55
+
4
56
  ## [2.2.0] - 2026-02-06
5
57
 
6
58
  ### 🚀 Major Pro-Level Enhancements
@@ -0,0 +1,189 @@
1
+ # vasuzex v2.3.0 Release Notes
2
+
3
+ ## Laravel-Style Standalone Script Support
4
+
5
+ ### Overview
6
+ Added standalone script support to Config and Log facades, following Laravel's best practices for graceful facade degradation. This enables vasuzex facades to work in **both** application contexts (with service container) and standalone scripts (without Application instance).
7
+
8
+ ### Why This is v2.3.0 (MINOR), Not a Patch
9
+ This is a **new feature** that maintains backward compatibility:
10
+ - ✅ Existing apps continue to work exactly as before (no breaking changes)
11
+ - ✅ Adds new capability: facades now work in standalone scripts
12
+ - ✅ Follows Laravel patterns (service container first, graceful fallback)
13
+ - ✅ Production-ready implementation with proper error handling
14
+
15
+ Per semver: `MAJOR.MINOR.PATCH` - this is a MINOR version (new backward-compatible functionality).
16
+
17
+ ---
18
+
19
+ ## Changes Required
20
+
21
+ ### 1. `/framework/Support/Facades/Config.js`
22
+
23
+ **Purpose**: Enable Config.get() in standalone scripts by loading .cjs config files from `config/` directory.
24
+
25
+ **Implementation**:
26
+ - Tries Application-bound config service first (normal app behavior)
27
+ - Falls back to direct config file loading if no Application
28
+ - Discovers project root by walking up directory tree
29
+ - Loads all .cjs files from `config/` directory using `require()`
30
+ - Supports dot notation (`database.connections.default.host`)
31
+ - Caches loaded config for performance
32
+
33
+ **File location**: `framework/Support/Facades/Config.js`
34
+
35
+ **Full file content**: See `/Users/rishi/Desktop/work/neasto/node_modules/.pnpm/vasuzex@2.2.4_@azure+core-client@1.10.1_@types+node@25.2.3_react-redux@9.2.0_@types+rea_6b288229c8b08a609ae395ef19989414/node_modules/vasuzex/framework/Support/Facades/Config.js`
36
+
37
+ ---
38
+
39
+ ### 2. `/framework/Support/Facades/Log.js`
40
+
41
+ **Purpose**: Enable Log.info/error/warn/debug in standalone scripts with console fallback.
42
+
43
+ **Implementation**:
44
+ - Tries Application-bound logger first (normal app behavior)
45
+ - Falls back to console.log with structured formatting
46
+ - ISO timestamps for production-quality logs
47
+ - Respects LOG_LEVEL environment variable (debug only shows if LOG_LEVEL=debug)
48
+ - All log levels supported: debug, info, warn, error
49
+
50
+ **File location**: `framework/Support/Facades/Log.js`
51
+
52
+ **Full file content**: See `/Users/rishi/Desktop/work/neasto/node_modules/.pnpm/vasuzex@2.2.4_@azure+core-client@1.10.1_@types+node@25.2.3_react-redux@9.2.0_@types+rea_6b288229c8b08a609ae395ef19989414/node_modules/vasuzex/framework/Support/Facades/Log.js`
53
+
54
+ ---
55
+
56
+ ## Testing Done
57
+
58
+ ### Standalone Script Tests ✅
59
+ 1. ✅ Config.get() - basic values (app.name, app.env)
60
+ 2. ✅ Config.get() - nested dot notation (database.connections.default.host)
61
+ 3. ✅ Config.get() - default values for missing keys
62
+ 4. ✅ Log.info() - with structured data
63
+ 5. ✅ Log.error() - with error data
64
+ 6. ✅ Log.warn() - with warning data
65
+ 7. ✅ Log.debug() - respects LOG_LEVEL
66
+
67
+ ### Real-World Script Tests ✅
68
+ 1. ✅ Elasticsearch setup scripts (setup-indices.js)
69
+ 2. ✅ Elasticsearch client connection (ElasticsearchClient.js)
70
+ 3. ✅ Dispatch test scripts (full-dispatch-test.cjs)
71
+ 4. ✅ Database bootstrap scripts (work without Application)
72
+
73
+ ### Backward Compatibility ✅
74
+ - Apps with Application instance continue using service container
75
+ - No changes required to existing application code
76
+ - Facades try App context first, fall back only if needed
77
+
78
+ ---
79
+
80
+ ## Laravel Pattern Compliance
81
+
82
+ ### Config Facade Pattern:
83
+ - ✓ Loads from `config/` directory (like Laravel's config path)
84
+ - ✓ Supports dot notation (like Laravel's `config('database.default')`)
85
+ - ✓ Returns default if key not found
86
+ - ✓ Caches loaded config (like Laravel's config cache)
87
+
88
+ ### Log Facade Pattern:
89
+ - ✓ Service container first (facade root)
90
+ - ✓ Graceful degradation to console
91
+ - ✓ Standard log levels (debug/info/warn/error)
92
+ - ✓ Respects environment settings
93
+
94
+ ### Facade Pattern:
95
+ - ✓ Service container priority (tries Application first)
96
+ - ✓ Graceful fallback (standalone mode)
97
+ - ✓ No breaking changes (backward compatible)
98
+ - ✓ Production-ready error handling
99
+
100
+ ---
101
+
102
+ ## Publishing Instructions
103
+
104
+ ### 1. Copy Changes to vasuzex Repo
105
+ Copy updated files from neasto's node_modules:
106
+ ```bash
107
+ # Config.js
108
+ cp /Users/rishi/Desktop/work/neasto/node_modules/.pnpm/vasuzex@2.2.4_*/node_modules/vasuzex/framework/Support/Facades/Config.js \
109
+ <vasuzex-repo>/framework/Support/Facades/Config.js
110
+
111
+ # Log.js
112
+ cp /Users/rishi/Desktop/work/neasto/node_modules/.pnpm/vasuzex@2.2.4_*/node_modules/vasuzex/framework/Support/Facades/Log.js \
113
+ <vasuzex-repo>/framework/Support/Facades/Log.js
114
+ ```
115
+
116
+ ### 2. Update package.json
117
+ ```json
118
+ {
119
+ "version": "2.3.0"
120
+ }
121
+ ```
122
+
123
+ ### 3. Update CHANGELOG.md
124
+ ```markdown
125
+ ## [2.3.0] - 2026-02-18
126
+
127
+ ### Added
128
+ - **Standalone Script Support**: Config and Log facades now work without Application instance
129
+ - Config facade loads .cjs files from config/ directory in standalone mode
130
+ - Log facade falls back to console.log with ISO timestamps in standalone mode
131
+ - Graceful degradation pattern: tries service container first, falls back if no Application
132
+
133
+ ### Changed
134
+ - Config.js: Enhanced with standalone config loading (backward compatible)
135
+ - Log.js: Enhanced with console fallback logging (backward compatible)
136
+
137
+ ### Technical
138
+ - Follows Laravel service container pattern with graceful fallback
139
+ - Production-ready error handling
140
+ - Zero breaking changes - all existing apps continue working unchanged
141
+ ```
142
+
143
+ ### 4. Git Workflow
144
+ ```bash
145
+ git checkout -b feature/standalone-facade-support
146
+ git add framework/Support/Facades/Config.js
147
+ git add framework/Support/Facades/Log.js
148
+ git add package.json
149
+ git add CHANGELOG.md
150
+ git commit -m "feat: Add standalone script support to Config and Log facades (v2.3.0)
151
+
152
+ - Enable facades to work without Application instance
153
+ - Load config from files in standalone mode
154
+ - Fallback logging for standalone scripts
155
+ - Maintains backward compatibility
156
+ - Follows Laravel graceful degradation pattern"
157
+ git push origin feature/standalone-facade-support
158
+ ```
159
+
160
+ ### 5. Create PR & Merge
161
+ Review changes, merge to main
162
+
163
+ ### 6. Publish to npm
164
+ ```bash
165
+ npm version 2.3.0
166
+ npm publish
167
+ git push --tags
168
+ ```
169
+
170
+ ### 7. Update neasto
171
+ ```bash
172
+ cd /Users/rishi/Desktop/work/neasto
173
+ pnpm update vasuzex
174
+ # Should install vasuzex@2.3.0
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Summary
180
+
181
+ This is a **proper Laravel-standard implementation**, not a quick patch:
182
+
183
+ ✅ **Service container priority** - Uses Application-bound services when available
184
+ ✅ **Graceful degradation** - Falls back intelligently when no Application
185
+ ✅ **Production-ready** - Proper error handling, caching, performance
186
+ ✅ **Zero breaking changes** - All existing code continues working
187
+ ✅ **Laravel patterns** - Follows Laravel's facade and config patterns
188
+
189
+ **Version: 2.3.0** (minor version - new backward-compatible feature)
@@ -1,13 +1,147 @@
1
1
  /**
2
2
  * Config Facade
3
+ * Enhanced to support standalone scripts without Application instance
3
4
  */
4
5
 
5
6
  import { Facade, createFacade } from './Facade.js';
7
+ import path from 'path';
8
+ import { existsSync, readdirSync } from 'fs';
9
+ import { createRequire } from 'module';
10
+ import { fileURLToPath } from 'url';
11
+
12
+ // Create require for loading .cjs files
13
+ const require = createRequire(import.meta.url);
14
+
15
+ let standaloneConfig = null;
16
+ let standaloneConfigLoaded = false;
6
17
 
7
18
  class ConfigFacade extends Facade {
8
19
  static getFacadeAccessor() {
9
20
  return 'config';
10
21
  }
22
+
23
+ /**
24
+ * Get config value with standalone fallback
25
+ * Works in both app context and standalone scripts
26
+ */
27
+ static get(key, defaultValue = null) {
28
+ // Try app context first (if Application exists)
29
+ if (this.app) {
30
+ try {
31
+ const instance = this.getFacadeRoot();
32
+ return instance.get(key, defaultValue);
33
+ } catch (error) {
34
+ // Fall through to standalone mode
35
+ }
36
+ }
37
+
38
+ // Standalone mode: Load config directly
39
+ return this.getStandalone(key, defaultValue);
40
+ }
41
+
42
+ /**
43
+ * Load config in standalone mode (no Application)
44
+ * Discovers project root and loads config files
45
+ */
46
+ static getStandalone(key, defaultValue = null) {
47
+ if (!standaloneConfigLoaded) {
48
+ this.loadStandaloneConfig();
49
+ }
50
+
51
+ if (!standaloneConfig) {
52
+ return defaultValue;
53
+ }
54
+
55
+ // Navigate nested keys (e.g., 'database.connections.default')
56
+ const keys = key.split('.');
57
+ let value = standaloneConfig;
58
+
59
+ for (const k of keys) {
60
+ if (value && typeof value === 'object' && k in value) {
61
+ value = value[k];
62
+ } else {
63
+ return defaultValue;
64
+ }
65
+ }
66
+
67
+ return value !== undefined ? value : defaultValue;
68
+ }
69
+
70
+ /**
71
+ * Load all config files from config/ directory
72
+ */
73
+ static loadStandaloneConfig() {
74
+ try {
75
+ // Find project root (look for config/ directory)
76
+ const rootDir = this.findProjectRoot();
77
+ if (!rootDir) {
78
+ standaloneConfig = {};
79
+ standaloneConfigLoaded = true;
80
+ return;
81
+ }
82
+
83
+ const configDir = path.join(rootDir, 'config');
84
+ if (!existsSync(configDir)) {
85
+ standaloneConfig = {};
86
+ standaloneConfigLoaded = true;
87
+ return;
88
+ }
89
+
90
+ // Load all .cjs config files
91
+ const files = readdirSync(configDir);
92
+ standaloneConfig = {};
93
+
94
+ for (const file of files) {
95
+ if (file.endsWith('.cjs')) {
96
+ const configName = file.replace(/\.cjs$/, '');
97
+ const configPath = path.join(configDir, file);
98
+
99
+ try {
100
+ // Clear require cache to get fresh config
101
+ const resolvedPath = require.resolve(configPath);
102
+ delete require.cache[resolvedPath];
103
+
104
+ // Load config file
105
+ const configData = require(configPath);
106
+ standaloneConfig[configName] = configData;
107
+ } catch (error) {
108
+ // Silently skip files that can't be loaded
109
+ }
110
+ }
111
+ }
112
+
113
+ standaloneConfigLoaded = true;
114
+ } catch (error) {
115
+ standaloneConfig = {};
116
+ standaloneConfigLoaded = true;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Find project root by looking for config/ directory
122
+ */
123
+ static findProjectRoot() {
124
+ try {
125
+ // Start from current working directory
126
+ let dir = process.cwd();
127
+
128
+ // Walk up until we find config/
129
+ for (let i = 0; i < 10; i++) {
130
+ const configPath = path.join(dir, 'config');
131
+ if (existsSync(configPath)) {
132
+ return dir;
133
+ }
134
+
135
+ const parent = path.dirname(dir);
136
+ if (parent === dir) break; // Reached filesystem root
137
+ dir = parent;
138
+ }
139
+
140
+ return null;
141
+ } catch (error) {
142
+ return null;
143
+ }
144
+ }
11
145
  }
12
146
 
13
147
  export default createFacade(ConfigFacade);
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Log Facade
3
+ * Enhanced to support standalone scripts without Application instance
3
4
  */
4
5
 
5
6
  import { Facade, createFacade } from './Facade.js';
@@ -8,6 +9,66 @@ class LogFacade extends Facade {
8
9
  static getFacadeAccessor() {
9
10
  return 'log';
10
11
  }
12
+
13
+ /**
14
+ * Fallback logging methods for standalone scripts
15
+ */
16
+ static log(level, message, data = null) {
17
+ const timestamp = new Date().toISOString();
18
+ const dataStr = data ? ' ' + JSON.stringify(data) : '';
19
+ console.log(`[${timestamp}] [${level.toUpperCase()}] ${message}${dataStr}`);
20
+ }
21
+
22
+ static debug(message, data = null) {
23
+ if (this.app) {
24
+ try {
25
+ const instance = this.getFacadeRoot();
26
+ return instance.debug(message, data);
27
+ } catch (error) {
28
+ // Fall through to standalone mode
29
+ }
30
+ }
31
+ // Standalone: Only log debug in verbose mode
32
+ if (process.env.LOG_LEVEL === 'debug' || process.env.DEBUG) {
33
+ this.log('debug', message, data);
34
+ }
35
+ }
36
+
37
+ static info(message, data = null) {
38
+ if (this.app) {
39
+ try {
40
+ const instance = this.getFacadeRoot();
41
+ return instance.info(message, data);
42
+ } catch (error) {
43
+ // Fall through to standalone mode
44
+ }
45
+ }
46
+ this.log('info', message, data);
47
+ }
48
+
49
+ static warn(message, data = null) {
50
+ if (this.app) {
51
+ try {
52
+ const instance = this.getFacadeRoot();
53
+ return instance.warn(message, data);
54
+ } catch (error) {
55
+ // Fall through to standalone mode
56
+ }
57
+ }
58
+ this.log('warn', message, data);
59
+ }
60
+
61
+ static error(message, data = null) {
62
+ if (this.app) {
63
+ try {
64
+ const instance = this.getFacadeRoot();
65
+ return instance.error(message, data);
66
+ } catch (error) {
67
+ // Fall through to standalone mode
68
+ }
69
+ }
70
+ this.log('error', message, data);
71
+ }
11
72
  }
12
73
 
13
74
  export default createFacade(LogFacade);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vasuzex",
3
- "version": "2.2.4",
3
+ "version": "2.3.0",
4
4
  "description": "Laravel-inspired framework for Node.js monorepos - V2 with optimized dependencies",
5
5
  "type": "module",
6
6
  "main": "./framework/index.js",