@currentjs/gen 0.5.0 → 0.5.2

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 (70) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +374 -996
  3. package/dist/cli.js +28 -10
  4. package/dist/commands/createModel.d.ts +1 -0
  5. package/dist/commands/createModel.js +764 -0
  6. package/dist/commands/createModule.js +13 -0
  7. package/dist/commands/generateAll.d.ts +1 -0
  8. package/dist/commands/generateAll.js +1 -1
  9. package/dist/commands/init.d.ts +1 -0
  10. package/dist/commands/{createApp.js → init.js} +2 -2
  11. package/dist/commands/migrateCommit.js +33 -68
  12. package/dist/generators/controllerGenerator.d.ts +7 -0
  13. package/dist/generators/controllerGenerator.js +56 -17
  14. package/dist/generators/domainLayerGenerator.js +51 -8
  15. package/dist/generators/dtoGenerator.js +13 -8
  16. package/dist/generators/serviceGenerator.d.ts +6 -0
  17. package/dist/generators/serviceGenerator.js +219 -23
  18. package/dist/generators/storeGenerator.d.ts +4 -0
  19. package/dist/generators/storeGenerator.js +116 -9
  20. package/dist/generators/templateGenerator.d.ts +1 -0
  21. package/dist/generators/templateGenerator.js +8 -2
  22. package/dist/generators/templates/appTemplates.js +1 -1
  23. package/dist/generators/templates/data/cursorRulesTemplate +11 -755
  24. package/dist/generators/templates/data/frontendScriptTemplate +11 -4
  25. package/dist/generators/templates/data/mainViewTemplate +1 -0
  26. package/dist/generators/templates/storeTemplates.d.ts +1 -1
  27. package/dist/generators/templates/storeTemplates.js +3 -26
  28. package/dist/generators/useCaseGenerator.js +6 -3
  29. package/dist/types/configTypes.d.ts +6 -0
  30. package/dist/utils/migrationUtils.d.ts +9 -19
  31. package/dist/utils/migrationUtils.js +80 -110
  32. package/dist/utils/promptUtils.d.ts +37 -0
  33. package/dist/utils/promptUtils.js +149 -0
  34. package/dist/utils/typeUtils.d.ts +4 -0
  35. package/dist/utils/typeUtils.js +7 -0
  36. package/package.json +1 -1
  37. package/dist/commands/createApp.d.ts +0 -1
  38. package/dist/commands/migratePush.d.ts +0 -1
  39. package/dist/commands/migratePush.js +0 -135
  40. package/dist/commands/migrateUpdate.d.ts +0 -1
  41. package/dist/commands/migrateUpdate.js +0 -147
  42. package/dist/commands/newGenerateAll.d.ts +0 -4
  43. package/dist/commands/newGenerateAll.js +0 -336
  44. package/dist/generators/domainModelGenerator.d.ts +0 -41
  45. package/dist/generators/domainModelGenerator.js +0 -242
  46. package/dist/generators/newControllerGenerator.d.ts +0 -55
  47. package/dist/generators/newControllerGenerator.js +0 -644
  48. package/dist/generators/newServiceGenerator.d.ts +0 -19
  49. package/dist/generators/newServiceGenerator.js +0 -266
  50. package/dist/generators/newStoreGenerator.d.ts +0 -39
  51. package/dist/generators/newStoreGenerator.js +0 -408
  52. package/dist/generators/newTemplateGenerator.d.ts +0 -29
  53. package/dist/generators/newTemplateGenerator.js +0 -510
  54. package/dist/generators/storeGeneratorV2.d.ts +0 -31
  55. package/dist/generators/storeGeneratorV2.js +0 -190
  56. package/dist/generators/templates/controllerTemplates.d.ts +0 -43
  57. package/dist/generators/templates/controllerTemplates.js +0 -82
  58. package/dist/generators/templates/newStoreTemplates.d.ts +0 -5
  59. package/dist/generators/templates/newStoreTemplates.js +0 -141
  60. package/dist/generators/templates/serviceTemplates.d.ts +0 -16
  61. package/dist/generators/templates/serviceTemplates.js +0 -59
  62. package/dist/generators/templates/validationTemplates.d.ts +0 -25
  63. package/dist/generators/templates/validationTemplates.js +0 -66
  64. package/dist/generators/templates/viewTemplates.d.ts +0 -25
  65. package/dist/generators/templates/viewTemplates.js +0 -491
  66. package/dist/generators/validationGenerator.d.ts +0 -29
  67. package/dist/generators/validationGenerator.js +0 -250
  68. package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
  69. package/dist/utils/new_parts_of_migrationUtils.js +0 -164
  70. package/howto.md +0 -667
package/howto.md DELETED
@@ -1,667 +0,0 @@
1
- # CurrentJS Framework Rules
2
-
3
- ## Architecture Overview
4
- This is a CurrentJS framework application using clean architecture principles with the following layers:
5
- - **Controllers**: Handle HTTP requests/responses and route handling
6
- - **Services**: Contain business logic and orchestrate operations
7
- - **Stores**: Provide data access layer and database operations
8
- - **Domain Entities**: Core business models
9
- - **Views**: HTML templates for server-side rendering
10
-
11
- ## Commands
12
-
13
- ```bash
14
- current create module Modulename # Creates "Modulename" with default structure and yaml file
15
- ```
16
- ```bash
17
- current generate Modulename # Generates all TypeScript files based on the module's yaml, and runs "npm run build"
18
- current generate # Does the same as above, but for all modules
19
- ```
20
- ```bash
21
- current commit [files...] # Commits all changes in the code, so they won't be overwritten after regeneration
22
- current diff [module] # Show differences between generated and current code
23
- ```
24
-
25
- ## The flow
26
- 1. Create an empty app (`current create app`)
27
- 2. Create a new module: `current create module Name`
28
- 3. In the module's yaml file, define module's:
29
- - model(s)
30
- - routes & actions
31
- - permissions
32
- 4. Generate TypeScript files: `current generate Name`
33
- 5. If required, make changes in the:
34
- - model (i.e. some specific business rules or validations)
35
- - views
36
- 6. Commit those changes: `current commit`
37
-
38
- --- If needed more than CRUD: ---
39
-
40
- 7. Define action in the service by creating a method
41
- 8. Describe this action in the module's yaml. Additionaly, you may define routes and permissions.
42
- 9. `current generate Modulename`
43
- 10. commit changes: `current commit`
44
-
45
- ## Configuration Files
46
-
47
- ### Application Configuration (app.yaml)
48
-
49
- **Do not modify this file**
50
-
51
- ### Module Configuration (modulename.yaml)
52
-
53
- **The most work must be done in these files**
54
-
55
- **Complete Module Example:**
56
- ```yaml
57
- models:
58
- - name: Post # Entity name (capitalized)
59
- fields:
60
- - name: title # Field name
61
- type: string # Field type: string, number, boolean, datetime
62
- required: true # Validation requirement
63
- - name: content
64
- type: string
65
- required: true
66
- - name: authorId
67
- type: number
68
- required: true
69
- - name: publishedAt
70
- type: datetime
71
- required: false
72
- - name: status
73
- type: string
74
- required: true
75
-
76
- api: # REST API configuration
77
- prefix: /api/posts # Base URL for API endpoints
78
- endpoints:
79
- - method: GET # HTTP method
80
- path: / # Relative path (becomes /api/posts/)
81
- action: list # Action name (references actions section)
82
- - method: GET
83
- path: /:id # Path parameter
84
- action: get
85
- - method: POST
86
- path: /
87
- action: create
88
- - method: PUT
89
- path: /:id
90
- action: update
91
- - method: DELETE
92
- path: /:id
93
- action: delete
94
- - method: POST # Custom endpoint
95
- path: /:id/publish
96
- action: publish
97
-
98
- routes: # Web interface configuration
99
- prefix: /posts # Base URL for web pages
100
- strategy: [toast, back] # Default success strategies for forms
101
- endpoints:
102
- - path: / # List page
103
- action: list
104
- view: postList # Template name
105
- - path: /:id # Detail page
106
- action: get
107
- view: postDetail
108
- - path: /create # Create form page
109
- action: empty # No data loading action
110
- view: postCreate
111
- - path: /:id/edit # Edit form page
112
- action: get # Load existing data
113
- view: postUpdate
114
-
115
- actions: # Business logic mapping
116
- list:
117
- handlers: [Post:default:list] # Use built-in list handler
118
- get:
119
- handlers: [Post:default:get] # Use built-in get handler
120
- create:
121
- handlers: [Post:default:create] # Built-in create
122
- update:
123
- handlers: [Post:default:update]
124
- delete:
125
- handlers: [ # Chain multiple handlers
126
- Post:checkCanDelete, # Custom business logic
127
- Post:default:delete
128
- ]
129
- publish: # Custom action
130
- handlers: [
131
- Post:default:get, # Fetch entity
132
- Post:validateForPublish, # Custom validation
133
- Post:updatePublishStatus # Custom update logic
134
- ]
135
-
136
- permissions: # Role-based access control
137
- - role: all
138
- actions: [list, get] # Anyone (including anonymous)
139
- - role: authenticated
140
- actions: [create] # Must be logged in
141
- - role: owner
142
- actions: [update, publish] # Entity owner permissions
143
- - role: admin
144
- actions: [update, delete, publish] # Admin role permissions
145
- - role: editor
146
- actions: [publish] # Editor role permissions
147
- ```
148
-
149
- **Make sure no `ID`/`owner id`/`is deleted` fields are present in the model definition, since it's added automatically**
150
-
151
- **Field Types:**
152
- - `string` - Text data
153
- - `number` - Numeric data (integer or float)
154
- - `boolean` - True/false values
155
- - `datetime` - Date and time values
156
- - `ModelName` - Relationship to another model (e.g., `Owner`, `User`, `Post`)
157
-
158
- **Multi-Model Endpoint Configuration:**
159
-
160
- When working with multiple models in a single module, you have flexible options:
161
-
162
- **Option 1: Per-Endpoint Model Override**
163
-
164
- Specify `model` on individual endpoints to override the section default:
165
-
166
- ```yaml
167
- models:
168
- - name: Cat
169
- - name: Person
170
- # do not forget to describe fields of each model
171
-
172
- routes:
173
- prefix: /cat
174
- model: Cat # Default for this section
175
- endpoints:
176
- - path: /create
177
- view: catCreate
178
- # Uses Cat model
179
-
180
- - path: /createOwner
181
- view: ownerCreate
182
- model: Person # Override for this endpoint
183
- ```
184
-
185
- **Option 2: Multiple API/Routes Sections**
186
-
187
- Use arrays to organize endpoints by model:
188
-
189
- ```yaml
190
- routes:
191
- - prefix: /cat
192
- model: Cat
193
- endpoints: [...]
194
-
195
- - prefix: /person
196
- model: Person
197
- endpoints: [...]
198
-
199
- # Same works for api sections
200
- api:
201
- - prefix: /api/cat
202
- model: Cat
203
- endpoints: [...]
204
-
205
- - prefix: /api/person
206
- model: Person
207
- endpoints: [...]
208
- ```
209
-
210
- **Model Resolution Priority:**
211
- 1. `endpoint.model` (explicit override)
212
- 2. Inferred from action handler (e.g., `Person:default:create`)
213
- 3. `api.model` or `routes.model` (section default)
214
- 4. First model in `models[]` array (fallback)
215
-
216
- **🔗 Model Relationships:**
217
-
218
- Define relationships by using another model's name as the field type:
219
-
220
- ```yaml
221
- models:
222
- - name: Owner
223
- fields:
224
- - name: name
225
- type: string
226
- required: true
227
-
228
- - name: Cat
229
- fields:
230
- - name: name
231
- type: string
232
- required: true
233
- - name: owner
234
- type: Owner # Creates relationship with Owner model
235
- required: true # Auto-generates foreign key: ownerId
236
- displayFields: [name] # Optional: fields to show in dropdowns
237
- ```
238
-
239
- **Generated Behavior:**
240
- - **Domain Model**: Rich object with `owner: Owner` (full object, not just ID)
241
- - **DTOs**: Use `ownerId: number` for API requests
242
- - **Database**: Stores `ownerId` foreign key column (references `Owner.id`)
243
- - **Store**: Automatically loads the related Owner object when fetching a Cat
244
- - **HTML Forms**: Auto-generates select dropdown with "Create New" button
245
- - **TypeScript**: Full type safety with proper imports
246
-
247
- **Naming Convention:**
248
- Foreign keys are automatically generated following the pattern `fieldName + 'Id'`:
249
- - `owner` → `ownerId`
250
- - `author` → `authorId`
251
- - `parentComment` → `parentCommentId`
252
-
253
- **Optional Configuration:**
254
- ```yaml
255
- - name: author
256
- type: User
257
- required: true
258
- displayFields: [name, email] # Show in dropdown (optional)
259
- ```
260
-
261
- **🔄 Handler vs Action Architecture:**
262
- - **Handler**: Creates a separate service method (one handler = one service method)
263
- - **Action**: Virtual controller concept that calls handler methods step-by-step
264
-
265
- **Built-in Action Handlers:**
266
- - `ModelName:default:list` - Creates service method with pagination parameters
267
- - `ModelName:default:get` - Creates service method named `get` with ID parameter
268
- - `ModelName:default:create` - Creates service method with DTO parameter
269
- - `ModelName:default:update` - Creates service method with ID and DTO parameters
270
- - `ModelName:default:delete` - Creates service method with ID parameter
271
-
272
- **Custom Action Handlers:**
273
- - `ModelName:customMethodName` - Creates service method that accepts `result, context` parameters
274
- - `result`: Result from previous handler (or `null` if it's the first handler)
275
- - `context`: The request context object
276
- - Each handler generates a separate method in the service
277
- - User can customize the implementation after generation
278
-
279
- **🔗 Multiple Handlers per Action:**
280
- When an action has multiple handlers, each handler generates a separate service method, and the controller action calls them sequentially. The action returns the result from the last handler.
281
-
282
- **Parameter Passing Rules:**
283
- - **Default handlers** (`:default:`): Receive standard parameters (id, pagination, DTO, etc.)
284
- - **Custom handlers**: Receive `(result, context)` where:
285
- - `result`: Result from previous handler, or `null` if it's the first handler
286
- - `context`: Request context object
287
-
288
- **Handler Format Examples:**
289
- - `Post:default:list` - Creates Post service method `list(page, limit)`
290
- - `Post:default:get` - Creates Post service method `get(id)`
291
- - `Post:validateContent` - Creates Post service method `validateContent(result, context)`
292
- - `Comment:notifySubscribers` - Creates Comment service method `notifySubscribers(result, context)`
293
-
294
- **Strategy Options (for forms):**
295
- - `toast` - Success toast notification
296
- - `back` - Navigate back in browser history
297
- - `message` - Inline success message
298
- - `modal` - Modal success dialog
299
- - `redirect` - Redirect to specific URL
300
- - `refresh` - Reload current page
301
-
302
- **Permission Roles:**
303
- - `all` - Anyone (including anonymous users)
304
- - `authenticated` - Any logged-in user
305
- - `owner` - User who created the entity
306
- - `admin`, `editor`, `user` - Custom roles from JWT token
307
- - Multiple roles can be specified for each action
308
-
309
- **Generated Files from Configuration:**
310
- - Domain entity class
311
- - Service class
312
- - API controller with REST endpoints
313
- - Web controller with page rendering
314
- - Store class with database operations
315
- - HTML templates for all views
316
- - TypeScript interfaces and DTOs
317
-
318
- ## Module Structure
319
- ```
320
- src/modules/ModuleName/
321
- ├── application/
322
- │ ├── services/ModuleService.ts # Business logic
323
- │ └── validation/ModuleValidation.ts # DTOs and validation
324
- ├── domain/
325
- │ └── entities/Module.ts # Domain model
326
- ├── infrastructure/
327
- │ ├── controllers/
328
- │ │ ├── ModuleApiController.ts # REST API endpoints
329
- │ │ └── ModuleWebController.ts # Web page controllers
330
- │ ├── interfaces/StoreInterface.ts # Data access interface
331
- │ └── stores/ModuleStore.ts # Data access implementation
332
- ├── views/
333
- │ ├── modulelist.html # List view template
334
- │ ├── moduledetail.html # Detail view template
335
- │ ├── modulecreate.html # Create form template
336
- │ └── moduleupdate.html # Update form template
337
- └── module.yaml # Module configuration
338
- ```
339
-
340
- ## Best Practices
341
-
342
- - Use Domain Driven Design and Clean Architecture (kind of).
343
- - Prefer declarative configuration over imperative programming: when possible, change yamls instead of writing the code. Write the code only when it's really neccessary.
344
- - CRUD operation are autogenerated (first in module's yaml, then in the generated code).
345
- - If some custom action is needed, then it has to be defined in the **Service** then just put this action to the module's yaml. You may also define new methods in the *Store* and its interface (if needed).
346
- - Business rules must be defined only in models. That also applies to business rules validations (in contrast to *just* validations: e.g. if field exists and is of needed type – then validators are in use)
347
-
348
- ## Core Package APIs (For Generated Code)
349
-
350
- ### @currentjs/router - Controller Decorators & Context
351
-
352
- **Decorators (in controllers):**
353
- ```typescript
354
- @Controller('/api/posts') // Base path for controller
355
- @Get('/') // GET endpoint
356
- @Get('/:id') // GET with path parameter
357
- @Post('/') // POST endpoint
358
- @Put('/:id') // PUT endpoint
359
- @Delete('/:id') // DELETE endpoint
360
- @Render('template', 'layout') // For web controllers
361
- ```
362
-
363
- **Context Object (in route handlers):**
364
- ```typescript
365
- interface IContext {
366
- request: {
367
- url: string;
368
- path: string;
369
- method: string;
370
- parameters: Record<string, string | number>; // Path params + query params
371
- body: any; // Parsed JSON or raw string
372
- headers: Record<string, string | string[]>;
373
- user?: AuthenticatedUser; // Parsed JWT user if authenticated
374
- };
375
- response: Record<string, any>;
376
- }
377
-
378
- // Usage examples
379
- const id = parseInt(ctx.request.parameters.id as string);
380
- const page = parseInt(ctx.request.parameters.page as string) || 1;
381
- const payload = ctx.request.body;
382
- const user = ctx.request.user; // If authenticated
383
- ```
384
-
385
- **Authentication Support:**
386
- - JWT tokens parsed automatically from `Authorization: Bearer <token>` header
387
- - User object available at `ctx.request.user` with `id`, `email`, `role` fields
388
- - No manual setup required in generated code
389
-
390
- ### @currentjs/templating - Template Syntax
391
-
392
- **Variables & Data Access:**
393
- ```html
394
- {{ variableName }}
395
- {{ object.property }}
396
- {{ $root.arrayData }} <!-- Access root data -->
397
- {{ $index }} <!-- Loop index -->
398
- ```
399
-
400
- **Control Structures:**
401
- ```html
402
- <!-- Loops -->
403
- <tbody x-for="$root" x-row="item">
404
- <tr>
405
- <td>{{ item.name }}</td>
406
- <td>{{ $index }}</td>
407
- </tr>
408
- </tbody>
409
-
410
- <!-- Conditionals -->
411
- <div x-if="user.isAdmin">Admin content</div>
412
- <span x-if="errors.name">{{ errors.name }}</span>
413
-
414
- <!-- Template includes -->
415
- <userCard name="{{ user.name }}" role="admin" />
416
- ```
417
-
418
- **Layout Integration:**
419
- - Templates use `<!-- @template name="templateName" -->` header
420
- - Main layout gets `{{ content }}` variable
421
- - Forms use `{{ formData.field || '' }}` for default values
422
-
423
- ### @currentjs/provider-mysql - Database Operations
424
-
425
- **Query Execution (in stores):**
426
- ```typescript
427
- // Named parameters (preferred)
428
- const result = await this.db.query(
429
- 'SELECT * FROM users WHERE status = :status AND age > :minAge',
430
- { status: 'active', minAge: 18 }
431
- );
432
-
433
- // Result handling
434
- if (result.success && result.data.length > 0) {
435
- return result.data.map(row => this.rowToModel(row));
436
- }
437
- ```
438
-
439
- **Common Query Patterns:**
440
- ```typescript
441
- // Insert with auto-generated fields
442
- const row = { ...data, created_at: new Date(), updated_at: new Date() };
443
- const result = await this.db.query(
444
- `INSERT INTO table_name (${fields.join(', ')}) VALUES (${placeholders})`,
445
- row
446
- );
447
- const newId = result.insertId;
448
-
449
- // Update with validation
450
- const query = `UPDATE table_name SET ${updateFields.join(', ')}, updated_at = :updated_at WHERE id = :id`;
451
- await this.db.query(query, { ...updateData, updated_at: new Date(), id });
452
-
453
- // Soft delete
454
- await this.db.query(
455
- 'UPDATE table_name SET deleted_at = :deleted_at WHERE id = :id',
456
- { deleted_at: new Date(), id }
457
- );
458
- ```
459
-
460
- **Error Handling:**
461
- ```typescript
462
- try {
463
- const result = await this.db.query(query, params);
464
- } catch (error) {
465
- if (error instanceof MySQLConnectionError) {
466
- throw new Error(`Database connection error: ${error.message}`);
467
- } else if (error instanceof MySQLQueryError) {
468
- throw new Error(`Query error: ${error.message}`);
469
- }
470
- throw error;
471
- }
472
- ```
473
-
474
- ## Frontend System (web/app.js)
475
-
476
- ### Translation System
477
-
478
- **Basic Usage:**
479
- ```javascript
480
- // Translate strings
481
- App.lang.t('Hello World') // Returns translated version or original
482
- App.lang.t('Save changes')
483
-
484
- // Set language
485
- App.lang.set('pl') // Switch to Polish
486
- App.lang.set('en') // Switch to English
487
- App.lang.get() // Get current language code
488
- ```
489
-
490
- **Translation File (web/translations.json):**
491
- ```json
492
- {
493
- "pl": {
494
- "Hello World": "Witaj Świecie",
495
- "Save changes": "Zapisz zmiany",
496
- "Delete": "Usuń"
497
- },
498
- "ru": {
499
- "Hello World": "Привет мир",
500
- "Save changes": "Сохранить изменения"
501
- }
502
- }
503
- ```
504
-
505
- ### UI Feedback & Notifications
506
-
507
- **Toast Notifications:**
508
- ```javascript
509
- App.ui.showToast('Success message', 'success') // Green toast
510
- App.ui.showToast('Error occurred', 'error') // Red toast
511
- App.ui.showToast('Information', 'info') // Blue toast
512
- App.ui.showToast('Warning', 'warning') // Yellow toast
513
- ```
514
-
515
- **Inline Messages:**
516
- ```javascript
517
- App.ui.showMessage('messageId', 'Success!', 'success')
518
- App.ui.showMessage('errorContainer', 'Validation failed', 'error')
519
- ```
520
-
521
- **Modal Dialogs:**
522
- ```javascript
523
- App.ui.showModal('confirmModal', 'Item saved successfully', 'success')
524
- App.ui.showModal('errorModal', 'Operation failed', 'error')
525
- ```
526
-
527
- ### Navigation & Page Actions
528
-
529
- **Navigation Functions:**
530
- ```javascript
531
- // SPA-style navigation
532
- App.nav.go('/posts/123') // Loads via AJAX, updates #main
533
-
534
- // Or use native browser APIs directly
535
- window.history.back() // Go back in history
536
- window.location.href = '/posts' // Full page redirect
537
- window.location.reload() // Reload page
538
- ```
539
-
540
- ### Form Handling & Strategy System
541
-
542
- **Form Strategy Configuration:**
543
- ```html
544
- <!-- Form with strategy attributes -->
545
- <form data-strategy='["toast", "back"]'
546
- data-entity-name="Post"
547
- data-field-types='{"age": "number", "active": "boolean"}'>
548
- <input name="title" type="text" required>
549
- <input name="age" type="number">
550
- <input name="active" type="checkbox">
551
- <button type="submit">Save</button>
552
- </form>
553
- ```
554
-
555
- **Available Strategies:**
556
- - `toast` - Show success toast notification
557
- - `back` - Navigate back using browser history
558
- - `message` - Show inline message in specific element
559
- - `modal` - Show modal dialog
560
- - `redirect` - Redirect to specific URL
561
- - `refresh` - Reload the page
562
- - `remove` - Remove form element
563
-
564
- **Manual Form Submission:**
565
- ```javascript
566
- const form = document.querySelector('#myForm');
567
- App.nav.submit(form, ['toast', 'back'], {
568
- entityName: 'Post',
569
- basePath: '/posts',
570
- messageId: 'form-message'
571
- });
572
- ```
573
-
574
- ### Loading States & Utilities
575
-
576
- **Loading Indicators:**
577
- ```javascript
578
- App.ui.showLoading('#form') // Show spinner on form
579
- App.ui.hideLoading('#form') // Hide spinner
580
- App.ui.showLoading('#main') // Show spinner on main content
581
- ```
582
-
583
- **Utility Functions:**
584
- ```javascript
585
- App.utils.debounce(searchFunction, 300) // Debounce for search inputs
586
- App.utils.$('#selector') // Safe element selection
587
- ```
588
-
589
- ### Event Handling & SPA Integration
590
-
591
- **Automatic Link Handling:**
592
- - Internal links automatically use AJAX navigation
593
- - External links work normally
594
- - Links with `data-external` skip AJAX handling
595
-
596
- **Automatic Form Handling:**
597
- - Forms with `data-strategy` use AJAX submission
598
- - Regular forms work normally
599
- - Automatic JSON conversion from FormData
600
-
601
- **Custom Event Listeners:**
602
- ```javascript
603
- // Re-initialize after dynamic content loading
604
- App.utils.initializeEventListeners();
605
-
606
- // Handle specific link navigation
607
- document.querySelector('#myLink').addEventListener('click', (e) => {
608
- e.preventDefault();
609
- App.nav.go('/custom/path');
610
- });
611
- ```
612
-
613
- ### Global App Object
614
-
615
- **Accessing Functions:**
616
- ```javascript
617
- // All functions available under window.App
618
- // Organized by category for better discoverability
619
-
620
- // UI Functions
621
- App.ui.showToast('Message', 'success');
622
- App.ui.showMessage('elementId', 'Success!', 'success');
623
- App.ui.showModal('modalId', 'Done!', 'success');
624
- App.ui.showLoading('#form');
625
- App.ui.hideLoading('#form');
626
-
627
- // Navigation Functions
628
- App.nav.go('/posts/123'); // SPA-style navigation with AJAX
629
- App.nav.submit(formElement, ['toast', 'back'], options); // Submit form via AJAX
630
-
631
- // Translation Functions
632
- App.lang.t('Translate this'); // Translate string
633
- App.lang.set('pl'); // Set language
634
- App.lang.get(); // Get current language
635
-
636
- // Utility Functions
637
- App.utils.$('#selector'); // Safe element selection
638
- App.utils.debounce(fn, 300); // Debounce function
639
- App.utils.initializeEventListeners(); // Re-initialize after dynamic content
640
-
641
- // Authentication Functions (JWT)
642
- App.auth.setAuthToken(token); // Store JWT token
643
- App.auth.clearAuthToken(); // Remove JWT token
644
- App.auth.buildAuthHeaders(additionalHeaders); // Build headers with auth token
645
- ```
646
-
647
- ### Template Data Binding
648
- ```html
649
- <!-- List with pagination -->
650
- <tbody x-for="modules" x-row="module">
651
- <tr>
652
- <td>{{ module.name }}</td>
653
- <td><a href="/module/{{ module.id }}">View</a></td>
654
- </tr>
655
- </tbody>
656
-
657
- <!-- Form with validation errors -->
658
- <div x-if="errors.name" class="text-danger">{{ errors.name }}</div>
659
- <input type="text" name="name" value="{{ formData.name || '' }}" class="form-control">
660
-
661
- <!-- Form with strategy attributes -->
662
- <form data-strategy='["toast", "back"]'
663
- data-entity-name="Module"
664
- data-field-types='{"count": "number", "active": "boolean"}'>
665
- <!-- form fields -->
666
- </form>
667
- ```