onelaraveljs 1.0.0 → 1.1.3

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 (121) hide show
  1. package/README.md +1 -1
  2. package/bin/onejs-build.js +32 -0
  3. package/index.js +3 -1
  4. package/package.json +11 -3
  5. package/scripts/README-template-compiler.md +133 -0
  6. package/scripts/README.md +61 -0
  7. package/scripts/__pycache__/build.cpython-314.pyc +0 -0
  8. package/scripts/__pycache__/compile.cpython-313.pyc +0 -0
  9. package/scripts/__pycache__/compile.cpython-314.pyc +0 -0
  10. package/scripts/build.py +574 -0
  11. package/scripts/check-system-errors.php +214 -0
  12. package/scripts/compile.py +101 -0
  13. package/scripts/compiler/README_CONFIG.md +196 -0
  14. package/scripts/compiler/__init__.py +18 -0
  15. package/scripts/compiler/__pycache__/__init__.cpython-313.pyc +0 -0
  16. package/scripts/compiler/__pycache__/__init__.cpython-314.pyc +0 -0
  17. package/scripts/compiler/__pycache__/binding_directive_service.cpython-314.pyc +0 -0
  18. package/scripts/compiler/__pycache__/class_binding_handler.cpython-314.pyc +0 -0
  19. package/scripts/compiler/__pycache__/compiler_utils.cpython-313.pyc +0 -0
  20. package/scripts/compiler/__pycache__/compiler_utils.cpython-314.pyc +0 -0
  21. package/scripts/compiler/__pycache__/conditional_handlers.cpython-313.pyc +0 -0
  22. package/scripts/compiler/__pycache__/conditional_handlers.cpython-314.pyc +0 -0
  23. package/scripts/compiler/__pycache__/config.cpython-313.pyc +0 -0
  24. package/scripts/compiler/__pycache__/config.cpython-314.pyc +0 -0
  25. package/scripts/compiler/__pycache__/declaration_tracker.cpython-314.pyc +0 -0
  26. package/scripts/compiler/__pycache__/directive_processors.cpython-313.pyc +0 -0
  27. package/scripts/compiler/__pycache__/directive_processors.cpython-314.pyc +0 -0
  28. package/scripts/compiler/__pycache__/echo_processor.cpython-314.pyc +0 -0
  29. package/scripts/compiler/__pycache__/event_directive_processor.cpython-313.pyc +0 -0
  30. package/scripts/compiler/__pycache__/event_directive_processor.cpython-314.pyc +0 -0
  31. package/scripts/compiler/__pycache__/function_generators.cpython-313.pyc +0 -0
  32. package/scripts/compiler/__pycache__/function_generators.cpython-314.pyc +0 -0
  33. package/scripts/compiler/__pycache__/loop_handlers.cpython-313.pyc +0 -0
  34. package/scripts/compiler/__pycache__/loop_handlers.cpython-314.pyc +0 -0
  35. package/scripts/compiler/__pycache__/main_compiler.cpython-313.pyc +0 -0
  36. package/scripts/compiler/__pycache__/main_compiler.cpython-314.pyc +0 -0
  37. package/scripts/compiler/__pycache__/parsers.cpython-313.pyc +0 -0
  38. package/scripts/compiler/__pycache__/parsers.cpython-314.pyc +0 -0
  39. package/scripts/compiler/__pycache__/php_converter.cpython-313.pyc +0 -0
  40. package/scripts/compiler/__pycache__/php_converter.cpython-314.pyc +0 -0
  41. package/scripts/compiler/__pycache__/php_js_converter.cpython-313.pyc +0 -0
  42. package/scripts/compiler/__pycache__/php_js_converter.cpython-314.pyc +0 -0
  43. package/scripts/compiler/__pycache__/register_parser.cpython-313.pyc +0 -0
  44. package/scripts/compiler/__pycache__/register_parser.cpython-314.pyc +0 -0
  45. package/scripts/compiler/__pycache__/section_handlers.cpython-313.pyc +0 -0
  46. package/scripts/compiler/__pycache__/section_handlers.cpython-314.pyc +0 -0
  47. package/scripts/compiler/__pycache__/show_directive_handler.cpython-314.pyc +0 -0
  48. package/scripts/compiler/__pycache__/style_directive_handler.cpython-314.pyc +0 -0
  49. package/scripts/compiler/__pycache__/template_analyzer.cpython-313.pyc +0 -0
  50. package/scripts/compiler/__pycache__/template_analyzer.cpython-314.pyc +0 -0
  51. package/scripts/compiler/__pycache__/template_processor.cpython-313.pyc +0 -0
  52. package/scripts/compiler/__pycache__/template_processor.cpython-314.pyc +0 -0
  53. package/scripts/compiler/__pycache__/template_processors.cpython-313.pyc +0 -0
  54. package/scripts/compiler/__pycache__/template_processors.cpython-314.pyc +0 -0
  55. package/scripts/compiler/__pycache__/utils.cpython-313.pyc +0 -0
  56. package/scripts/compiler/__pycache__/utils.cpython-314.pyc +0 -0
  57. package/scripts/compiler/__pycache__/wrapper_parser.cpython-313.pyc +0 -0
  58. package/scripts/compiler/__pycache__/wrapper_parser.cpython-314.pyc +0 -0
  59. package/scripts/compiler/binding_directive_service.py +103 -0
  60. package/scripts/compiler/class_binding_handler.py +347 -0
  61. package/scripts/compiler/cli.py +34 -0
  62. package/scripts/compiler/code_generator.py +141 -0
  63. package/scripts/compiler/compiler.config.json +36 -0
  64. package/scripts/compiler/compiler_utils.py +55 -0
  65. package/scripts/compiler/conditional_handlers.py +252 -0
  66. package/scripts/compiler/config.py +107 -0
  67. package/scripts/compiler/declaration_tracker.py +420 -0
  68. package/scripts/compiler/directive_processors.py +603 -0
  69. package/scripts/compiler/echo_processor.py +667 -0
  70. package/scripts/compiler/event_directive_processor.py +1099 -0
  71. package/scripts/compiler/fetch_parser.py +49 -0
  72. package/scripts/compiler/function_generators.py +310 -0
  73. package/scripts/compiler/loop_handlers.py +224 -0
  74. package/scripts/compiler/main_compiler.py +1763 -0
  75. package/scripts/compiler/parsers.py +1418 -0
  76. package/scripts/compiler/php_converter.py +470 -0
  77. package/scripts/compiler/php_js_converter.py +603 -0
  78. package/scripts/compiler/register_parser.py +480 -0
  79. package/scripts/compiler/section_handlers.py +122 -0
  80. package/scripts/compiler/show_directive_handler.py +85 -0
  81. package/scripts/compiler/style_directive_handler.py +169 -0
  82. package/scripts/compiler/template_analyzer.py +162 -0
  83. package/scripts/compiler/template_processor.py +1167 -0
  84. package/scripts/compiler/template_processors.py +1557 -0
  85. package/scripts/compiler/test_compiler.py +69 -0
  86. package/scripts/compiler/utils.py +54 -0
  87. package/scripts/compiler/variables_analyzer.py +135 -0
  88. package/scripts/compiler/view_identifier_generator.py +278 -0
  89. package/scripts/compiler/wrapper_parser.py +78 -0
  90. package/scripts/dev-context.js +311 -0
  91. package/scripts/dev.js +109 -0
  92. package/scripts/generate-assets-order.js +208 -0
  93. package/scripts/migrate-namespace.php +146 -0
  94. package/scripts/node/MIGRATION.md +190 -0
  95. package/scripts/node/README.md +269 -0
  96. package/scripts/node/build.js +208 -0
  97. package/scripts/node/compiler/compiler-utils.js +38 -0
  98. package/scripts/node/compiler/conditional-handlers.js +45 -0
  99. package/scripts/node/compiler/config.js +178 -0
  100. package/scripts/node/compiler/directive-processors.js +51 -0
  101. package/scripts/node/compiler/event-directive-processor.js +182 -0
  102. package/scripts/node/compiler/function-generators.js +239 -0
  103. package/scripts/node/compiler/loop-handlers.js +45 -0
  104. package/scripts/node/compiler/main-compiler.js +236 -0
  105. package/scripts/node/compiler/parsers.js +358 -0
  106. package/scripts/node/compiler/php-converter.js +227 -0
  107. package/scripts/node/compiler/register-parser.js +32 -0
  108. package/scripts/node/compiler/section-handlers.js +46 -0
  109. package/scripts/node/compiler/template-analyzer.js +50 -0
  110. package/scripts/node/compiler/template-processor.js +371 -0
  111. package/scripts/node/compiler/template-processors.js +219 -0
  112. package/scripts/node/compiler/utils.js +203 -0
  113. package/scripts/node/compiler/wrapper-parser.js +25 -0
  114. package/scripts/node/package.json +24 -0
  115. package/scripts/node/test-compiler.js +52 -0
  116. package/scripts/node-run.cjs +28 -0
  117. package/scripts/standardize-directories.php +92 -0
  118. package/src/core/ViewManager.js +4 -4
  119. package/templates/view.module.js +2 -0
  120. package/templates/view.tpl-raw.js +13 -0
  121. package/templates/wraper.js +71 -0
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Development Script with Context Support (web/admin)
5
+ * - Watch blade files and JS core files (auto-detect from build.config.json)
6
+ * - Auto-compile templates when changed
7
+ * - Auto-rebuild webpack when JS changed
8
+ * - Run PHP artisan serve
9
+ */
10
+
11
+ import { spawn } from 'child_process';
12
+ import { watch } from 'fs';
13
+ import { readFileSync, writeFileSync } from 'fs';
14
+ import path from 'path';
15
+ import { fileURLToPath } from 'url';
16
+ import { WebSocketServer } from 'ws';
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = path.dirname(__filename);
20
+
21
+ // Get context from command line argument
22
+ const context = process.argv[2] || 'web'; // Default to 'web'
23
+
24
+ if (!['web', 'admin'].includes(context)) {
25
+ console.error('❌ Invalid context. Use: web or admin');
26
+ process.exit(1);
27
+ }
28
+
29
+ // Load build config
30
+ const buildConfigPath = path.resolve(__dirname, '../build.config.json');
31
+ const buildConfig = JSON.parse(readFileSync(buildConfigPath, 'utf-8'));
32
+ const contextConfig = buildConfig.contexts[context];
33
+
34
+ if (!contextConfig) {
35
+ console.error(`❌ Context "${context}" not found in build.config.json`);
36
+ process.exit(1);
37
+ }
38
+
39
+ const config = {
40
+ context: context,
41
+ watchPaths: {
42
+ blade: contextConfig.sources, // Array of blade source paths from config
43
+ jsCore: 'resources/js/onejs', // Watch entire onejs directory
44
+ jsViewsExclude: 'resources/js/onejs/views', // Exclude views directory
45
+ compiler: 'scripts/compiler'
46
+ },
47
+ buildCommand: `npm run build:${context}`,
48
+ phpServeCommand: 'php artisan serve',
49
+ phpPort: context === 'admin' ? 8001 : 8000,
50
+ wsPort: context === 'admin' ? 3301 : 3300
51
+ };
52
+
53
+ class ContextDevServer {
54
+ constructor() {
55
+ this.processes = {
56
+ phpServe: null
57
+ };
58
+ this.wss = null;
59
+ this.isBuilding = false;
60
+ this.debounceTimer = null;
61
+ this.debounceDelay = 300; // ms
62
+ }
63
+
64
+ async start() {
65
+ console.log(`🚀 Starting Development Server for [${config.context.toUpperCase()}] context...\n`);
66
+
67
+ // Initial build (templates + webpack)
68
+ await this.runBuild();
69
+
70
+ // Start PHP artisan serve
71
+ this.startPhpServe();
72
+
73
+ // Start WebSocket server for auto-reload
74
+ this.startWebSocketServer();
75
+
76
+ // Create reload script file
77
+ this.createReloadScript();
78
+
79
+ // Start file watcher for blade and compiler files
80
+ this.startWatcher();
81
+
82
+ console.log('\n✅ Development server started!');
83
+ console.log(`📦 Context: ${config.context.toUpperCase()}`);
84
+ console.log('📝 Watching:');
85
+ console.log(` - Blade files: ${config.watchPaths.blade.join(', ')}`);
86
+ console.log(` - JS Core: ${config.watchPaths.jsCore} (excluding views)`);
87
+ console.log(` - Compiler: ${config.watchPaths.compiler}`);
88
+ console.log(`🌐 Laravel Server: http://localhost:${config.phpPort}`);
89
+ console.log(`🔄 Auto-reload: Active (add script to your layout)`);
90
+ console.log(`⚡ Auto-rebuild: npm run build:${config.context}`);
91
+ console.log('\n💡 Add this to your blade layout:');
92
+ console.log(` <script src="/reload-dev.js"></script>`);
93
+ console.log('\n💡 Press Ctrl+C to stop\n');
94
+ }
95
+
96
+ async runBuild() {
97
+ if (this.isBuilding) {
98
+ console.log('⏳ Build already in progress, skipping...');
99
+ return;
100
+ }
101
+
102
+ this.isBuilding = true;
103
+ console.log(`🔨 Building [${config.context}] (templates + webpack)...`);
104
+
105
+ return new Promise((resolve, reject) => {
106
+ const build = spawn('sh', ['-c', config.buildCommand], {
107
+ stdio: 'inherit',
108
+ cwd: path.resolve(__dirname, '..')
109
+ });
110
+
111
+ build.on('close', (code) => {
112
+ this.isBuilding = false;
113
+ if (code === 0) {
114
+ console.log(`✅ Build completed for [${config.context}]`);
115
+ // Trigger browser reload via WebSocket
116
+ this.notifyReload();
117
+ resolve();
118
+ } else {
119
+ console.error(`❌ Build failed with code ${code}\n`);
120
+ reject(new Error(`Build failed with code ${code}`));
121
+ }
122
+ });
123
+
124
+ build.on('error', (err) => {
125
+ this.isBuilding = false;
126
+ console.error('❌ Failed to start build process:', err);
127
+ reject(err);
128
+ });
129
+ });
130
+ }
131
+
132
+ startWebSocketServer() {
133
+ console.log(`🔄 Starting WebSocket server on port ${config.wsPort}...\n`);
134
+
135
+ this.wss = new WebSocketServer({ port: config.wsPort });
136
+
137
+ this.wss.on('connection', (ws) => {
138
+ ws.on('error', console.error);
139
+ });
140
+ }
141
+
142
+ notifyReload() {
143
+ if (this.wss) {
144
+ console.log('🔄 Reloading browser...\n');
145
+ this.wss.clients.forEach((client) => {
146
+ if (client.readyState === 1) { // OPEN
147
+ client.send('reload');
148
+ }
149
+ });
150
+ }
151
+ }
152
+
153
+ createReloadScript() {
154
+ const scriptContent = `
155
+ (function() {
156
+ if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
157
+ return; // Only run on local development
158
+ }
159
+
160
+ const ws = new WebSocket('ws://localhost:${config.wsPort}');
161
+
162
+ ws.onmessage = function(event) {
163
+ if (event.data === 'reload') {
164
+ console.log('[DEV] Reloading page...');
165
+ window.location.reload();
166
+ }
167
+ };
168
+
169
+ ws.onerror = function() {
170
+ console.log('[DEV] WebSocket connection failed');
171
+ };
172
+
173
+ ws.onclose = function() {
174
+ // Reconnect after 1 second
175
+ setTimeout(function() {
176
+ window.location.reload();
177
+ }, 1000);
178
+ };
179
+ })();
180
+ `;
181
+
182
+ const publicPath = path.resolve(__dirname, '../public/reload-dev.js');
183
+ writeFileSync(publicPath, scriptContent, 'utf-8');
184
+ console.log(`✅ Created reload script at public/reload-dev.js\n`);
185
+ }
186
+
187
+ startPhpServe() {
188
+ console.log(`🐘 Starting PHP server on port ${config.phpPort}...`);
189
+
190
+ this.processes.phpServe = spawn('php', ['artisan', 'serve', `--port=${config.phpPort}`], {
191
+ stdio: 'inherit',
192
+ cwd: path.resolve(__dirname, '..')
193
+ });
194
+
195
+ this.processes.phpServe.on('error', (err) => {
196
+ console.error('❌ PHP server error:', err);
197
+ });
198
+
199
+ this.processes.phpServe.on('close', (code) => {
200
+ if (code !== 0 && code !== null) {
201
+ console.error(`❌ PHP server exited with code ${code}`);
202
+ }
203
+ });
204
+ }
205
+
206
+ startWatcher() {
207
+ // Watch blade files (multiple source directories from config)
208
+ config.watchPaths.blade.forEach(bladePath => {
209
+ console.log(`👀 Watching blade files in: ${bladePath}`);
210
+ watch(bladePath, { recursive: true }, (eventType, filename) => {
211
+ if (filename && filename.endsWith('.blade.php')) {
212
+ this.handleFileChange('blade', path.join(bladePath, filename));
213
+ }
214
+ });
215
+ });
216
+
217
+ // Watch JS core files (entire onejs directory, excluding views)
218
+ console.log(`👀 Watching JS core in: ${config.watchPaths.jsCore} (excluding views)`);
219
+ watch(config.watchPaths.jsCore, { recursive: true }, (eventType, filename) => {
220
+ if (filename && filename.endsWith('.js')) {
221
+ const fullPath = path.join(config.watchPaths.jsCore, filename);
222
+ // Skip if file is in views directory
223
+ if (!fullPath.includes(path.sep + 'views' + path.sep) && !fullPath.endsWith(path.sep + 'views')) {
224
+ this.handleFileChange('js-core', filename);
225
+ }
226
+ }
227
+ });
228
+
229
+ // Watch compiler files
230
+ console.log(`👀 Watching compiler in: ${config.watchPaths.compiler}`);
231
+ watch(config.watchPaths.compiler, { recursive: true }, (eventType, filename) => {
232
+ if (filename && (filename.endsWith('.py') || filename.endsWith('.js'))) {
233
+ this.handleFileChange('compiler', filename);
234
+ }
235
+ });
236
+ }
237
+
238
+ handleFileChange(type, filename) {
239
+ // Clear existing timer
240
+ if (this.debounceTimer) {
241
+ clearTimeout(this.debounceTimer);
242
+ }
243
+
244
+ // Debounce to avoid multiple rapid builds
245
+ this.debounceTimer = setTimeout(() => {
246
+ console.log(`\n📝 [${type.toUpperCase()}] File changed: ${filename}`);
247
+
248
+ // Rebuild everything (templates + webpack) for any changes
249
+ this.runBuild().catch(err => {
250
+ console.error('Build error:', err);
251
+ });
252
+ }, this.debounceDelay);
253
+ }
254
+
255
+ stop() {
256
+ console.log('\n🛑 Shutting down development server...');
257
+
258
+ // Stop WebSocket Server
259
+ if (this.wss) {
260
+ console.log(' Stopping WebSocket server...');
261
+ this.wss.close();
262
+ }
263
+
264
+ // Kill all processes
265
+ Object.keys(this.processes).forEach(key => {
266
+ const proc = this.processes[key];
267
+ if (proc && !proc.killed) {
268
+ console.log(` Stopping ${key}...`);
269
+ proc.kill('SIGTERM');
270
+
271
+ // Force kill after 2 seconds if not terminated
272
+ setTimeout(() => {
273
+ if (!proc.killed) {
274
+ proc.kill('SIGKILL');
275
+ }
276
+ }, 2000);
277
+ }
278
+ });
279
+
280
+ console.log('✅ Development server stopped');
281
+ process.exit(0);
282
+ }
283
+ }
284
+
285
+ // Handle process termination
286
+ process.on('SIGINT', () => {
287
+ if (devServer) {
288
+ devServer.stop();
289
+ }
290
+ });
291
+
292
+ process.on('SIGTERM', () => {
293
+ if (devServer) {
294
+ devServer.stop();
295
+ }
296
+ });
297
+
298
+ // Catch unhandled errors
299
+ process.on('uncaughtException', (err) => {
300
+ console.error('❌ Uncaught exception:', err);
301
+ if (devServer) {
302
+ devServer.stop();
303
+ }
304
+ });
305
+
306
+ // Start development server
307
+ const devServer = new ContextDevServer();
308
+ devServer.start().catch(err => {
309
+ console.error('❌ Failed to start dev server:', err);
310
+ process.exit(1);
311
+ });
package/scripts/dev.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Development Script for Blade Compiler
5
+ * Provides development workflow with hot reload
6
+ */
7
+
8
+ import { spawn } from 'child_process';
9
+ import { watch } from 'fs';
10
+ import path from 'path';
11
+
12
+ const config = {
13
+ watchPaths: [
14
+ 'resources/views',
15
+ 'resources/js/app',
16
+ 'scripts/compiler'
17
+ ],
18
+ buildCommand: 'cd scripts && python3 build.py',
19
+ viteCommand: 'npm run dev'
20
+ };
21
+
22
+ class DevServer {
23
+ constructor() {
24
+ this.buildProcess = null;
25
+ this.viteProcess = null;
26
+ this.isBuilding = false;
27
+ }
28
+
29
+ async start() {
30
+ console.log('🚀 Starting Blade Compiler Development Server...\n');
31
+
32
+ // Initial build
33
+ await this.runBuild();
34
+
35
+ // Start Vite dev server
36
+ this.startVite();
37
+
38
+ // Start file watcher
39
+ this.startWatcher();
40
+
41
+ console.log('✅ Development server started!');
42
+ console.log('📝 Watching for changes in:', config.watchPaths.join(', '));
43
+ console.log('🌐 Vite dev server: http://localhost:5173');
44
+ console.log('⚡ Blade compiler: Auto-rebuild on file changes\n');
45
+ }
46
+
47
+ async runBuild() {
48
+ if (this.isBuilding) return;
49
+
50
+ this.isBuilding = true;
51
+ console.log('🔨 Building Blade templates...');
52
+
53
+ return new Promise((resolve, reject) => {
54
+ const build = spawn('sh', ['-c', 'cd scripts && python3 build.py'], {
55
+ stdio: 'inherit',
56
+ cwd: process.cwd()
57
+ });
58
+
59
+ build.on('close', (code) => {
60
+ this.isBuilding = false;
61
+ if (code === 0) {
62
+ console.log('✅ Build completed successfully\n');
63
+ resolve();
64
+ } else {
65
+ console.log('❌ Build failed\n');
66
+ reject(new Error(`Build failed with code ${code}`));
67
+ }
68
+ });
69
+ });
70
+ }
71
+
72
+ startVite() {
73
+ this.viteProcess = spawn('npm', ['run', 'dev'], {
74
+ stdio: 'inherit',
75
+ cwd: process.cwd()
76
+ });
77
+ }
78
+
79
+ startWatcher() {
80
+ config.watchPaths.forEach(watchPath => {
81
+ watch(watchPath, { recursive: true }, (eventType, filename) => {
82
+ if (filename && (filename.endsWith('.blade.php') || filename.endsWith('.js'))) {
83
+ console.log(`📝 File changed: ${filename}`);
84
+ this.runBuild().catch(console.error);
85
+ }
86
+ });
87
+ });
88
+ }
89
+
90
+ stop() {
91
+ if (this.buildProcess) {
92
+ this.buildProcess.kill();
93
+ }
94
+ if (this.viteProcess) {
95
+ this.viteProcess.kill();
96
+ }
97
+ console.log('🛑 Development server stopped');
98
+ }
99
+ }
100
+
101
+ // Handle process termination
102
+ process.on('SIGINT', () => {
103
+ console.log('\n🛑 Shutting down development server...');
104
+ process.exit(0);
105
+ });
106
+
107
+ // Start development server
108
+ const devServer = new DevServer();
109
+ devServer.start().catch(console.error);
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Generate assets loading order for HTML
5
+ * Reads webpack build output and creates ordered script tags
6
+ * Supports context-based builds (web, admin, etc.)
7
+ */
8
+
9
+ import fs from 'fs';
10
+ import path from 'path';
11
+ import { fileURLToPath } from 'url';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+
16
+ // Load build.config.json from project root
17
+ const projectRoot = process.env.ONEJS_PROJECT_ROOT || process.cwd();
18
+ const configPath = path.join(projectRoot, 'build.config.json');
19
+
20
+ try {
21
+ var buildConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
22
+ } catch (e) {
23
+ console.error(`Error loading build.config.json from ${configPath}:`, e.message);
24
+ process.exit(1);
25
+ }
26
+
27
+ // Get context from environment variable
28
+ const buildContext = process.env.BUILD_CONTEXT || 'web';
29
+
30
+ // Determine static path based on context
31
+ const STATIC_PATH = buildConfig.contexts[buildContext]
32
+ ? path.join(projectRoot, path.dirname(buildConfig.contexts[buildContext].dist.bundle))
33
+ : path.join(projectRoot, 'public/static/app');
34
+
35
+ // Determine base URL path for assets
36
+ const BASE_URL = buildConfig.contexts[buildContext]
37
+ ? `/static/${buildContext}/js/`
38
+ : '/static/app/';
39
+
40
+ const OUTPUT_FILE = path.join(projectRoot, 'resources/views/partials/assets-scripts.blade.php');
41
+
42
+ function getAssetsByCategory() {
43
+ const assets = {
44
+ runtime: [],
45
+ framework: [],
46
+ main: [],
47
+ other: []
48
+ };
49
+
50
+ try {
51
+ if (!fs.existsSync(STATIC_PATH)) {
52
+ console.warn(`⚠️ Static path does not exist: ${STATIC_PATH}`);
53
+ return assets;
54
+ }
55
+
56
+ const files = fs.readdirSync(STATIC_PATH);
57
+
58
+ files.forEach(file => {
59
+ if (!file.endsWith('.js') || file.endsWith('.map')) return;
60
+
61
+ // Runtime chunk (must load first)
62
+ if (file.startsWith('runtime')) {
63
+ assets.runtime.push(file);
64
+ }
65
+ // Framework chunks (vendor, core libraries)
66
+ else if (file.startsWith('framework-')) {
67
+ assets.framework.push(file);
68
+ }
69
+ // Main chunks (application code)
70
+ else if (file.startsWith('main')) {
71
+ assets.main.push(file);
72
+ }
73
+ // Legacy or other chunks
74
+ else {
75
+ assets.other.push(file);
76
+ }
77
+ });
78
+
79
+ // Sort by filename to ensure consistent order
80
+ Object.keys(assets).forEach(key => {
81
+ assets[key].sort();
82
+ });
83
+
84
+ return assets;
85
+ } catch (error) {
86
+ console.error('Error reading assets:', error);
87
+ return assets;
88
+ }
89
+ }
90
+
91
+ function generateBladeTemplate(assets) {
92
+ const lines = [
93
+ '{{-- Auto-generated webpack assets --}}',
94
+ `{{-- Context: ${buildContext} --}}`,
95
+ '{{-- Generated at: ' + new Date().toISOString() + ' --}}',
96
+ '{{-- Load order: runtime → framework → main --}}',
97
+ ''
98
+ ];
99
+
100
+ // Runtime chunk (must load first)
101
+ if (assets.runtime.length > 0) {
102
+ lines.push('{{-- Runtime chunk (webpack runtime) --}}');
103
+ assets.runtime.forEach(file => {
104
+ lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
105
+ });
106
+ lines.push('');
107
+ }
108
+
109
+ // Framework chunks (vendor dependencies)
110
+ if (assets.framework.length > 0) {
111
+ lines.push('{{-- Framework chunks (vendor dependencies) --}}');
112
+ assets.framework.forEach(file => {
113
+ lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
114
+ });
115
+ lines.push('');
116
+ }
117
+
118
+ // Main application chunks
119
+ if (assets.main.length > 0) {
120
+ lines.push('{{-- Main application chunks --}}');
121
+ assets.main.forEach(file => {
122
+ lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
123
+ });
124
+ }
125
+
126
+ // Other chunks (if any)
127
+ if (assets.other.length > 0) {
128
+ lines.push('');
129
+ lines.push('{{-- Other chunks --}}');
130
+ assets.other.forEach(file => {
131
+ lines.push(`<script src="${BASE_URL}${file}" defer></script>`);
132
+ });
133
+ }
134
+
135
+ return lines.join('\n');
136
+ }
137
+
138
+ function generateHTMLTemplate(assets) {
139
+ console.log('\n📋 **HTML Script Tags (in loading order):**\n');
140
+
141
+ if (assets.runtime.length > 0) {
142
+ console.log('<!-- Runtime chunk (webpack runtime) -->');
143
+ assets.runtime.forEach(file => {
144
+ console.log(`<script src="${BASE_URL}${file}" defer></script>`);
145
+ });
146
+ }
147
+
148
+ if (assets.framework.length > 0) {
149
+ console.log('<!-- Framework chunks -->');
150
+ assets.framework.forEach(file => {
151
+ console.log(`<script src="${BASE_URL}${file}" defer></script>`);
152
+ });
153
+ }
154
+
155
+ if (assets.main.length > 0) {
156
+ console.log('<!-- Main chunks -->');
157
+ assets.main.forEach(file => {
158
+ console.log(`<script src="${BASE_URL}${file}" defer></script>`);
159
+ });
160
+ }
161
+
162
+ if (assets.other.length > 0) {
163
+ console.log('<!-- Other chunks -->');
164
+ assets.other.forEach(file => {
165
+ console.log(`<script src="${BASE_URL}${file}" defer></script>`);
166
+ });
167
+ }
168
+
169
+ console.log('\n💡 **Usage in your layout:**'); console.log('');
170
+ }
171
+
172
+ function main() {
173
+ console.log('🔍 Analyzing webpack assets...');
174
+
175
+ const assets = getAssetsByCategory();
176
+
177
+ const totalFiles = Object.values(assets).flat().length;
178
+
179
+ console.log('📊 **Assets Summary:**');
180
+ console.log(`- Runtime chunks: ${assets.runtime.length}`);
181
+ console.log(`- Framework chunks: ${assets.framework.length}`);
182
+ console.log(`- Main chunks: ${assets.main.length}`);
183
+ console.log(`- Other chunks: ${assets.other.length}`);
184
+ console.log(`- Total JS files: ${totalFiles}`);
185
+
186
+ // Generate Blade template
187
+ const bladeContent = generateBladeTemplate(assets);
188
+
189
+ try {
190
+ fs.writeFileSync(OUTPUT_FILE, bladeContent);
191
+ console.log(`✅ Generated Blade template: ${OUTPUT_FILE}`);
192
+ } catch (error) {
193
+ console.error('❌ Error writing Blade template:', error);
194
+ }
195
+
196
+ // Show HTML version
197
+ generateHTMLTemplate(assets);
198
+
199
+ console.log('💡 **Usage in your layout:**');
200
+ console.log('@include("partials.assets-scripts")');
201
+ }
202
+
203
+ // Run if this is the main module
204
+ if (import.meta.url === `file://${process.argv[1]}`) {
205
+ main();
206
+ }
207
+
208
+ export { getAssetsByCategory, generateBladeTemplate };