@magentrix-corp/magentrix-cli 1.2.0 → 1.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/README.md CHANGED
@@ -12,6 +12,7 @@ MagentrixCLI is a command-line tool that lets you:
12
12
  - Create new files with proper templates
13
13
  - Keep everything synchronized automatically
14
14
  - Work with your favorite code editor instead of the web interface
15
+ - Deploy Vue.js (Iris) applications to your Magentrix instance
15
16
 
16
17
  ---
17
18
 
@@ -357,10 +358,25 @@ src/
357
358
  ├── Triggers/ # Trigger code (*.trigger files)
358
359
  ├── Pages/ # ASPX pages (*.aspx files)
359
360
  ├── Templates/ # Templates (*.aspx files)
360
- └── Contents/
361
- └── Assets/ # Static assets (images, CSS, JS, etc.)
361
+ ├── Contents/
362
+ └── Assets/ # Static assets (images, CSS, JS, etc.)
363
+ └── iris-apps/ # Vue.js Iris applications (see warning below)
364
+ └── <app-slug>/ # Each app in its own folder
362
365
  ```
363
366
 
367
+ > **⚠️ IMPORTANT: Deleting Iris Apps**
368
+ >
369
+ > **NEVER manually delete folders from `src/iris-apps/`!** Always use the `magentrix iris-delete` command to remove Iris apps. Manual deletion will cause:
370
+ > - No recovery backup created (you cannot restore the app)
371
+ > - App remains on the Magentrix server (orphaned)
372
+ > - Cache becomes out of sync (causes errors on next publish)
373
+ > - Linked Vue project not properly unlinked
374
+ >
375
+ > **Correct way to delete an Iris app:**
376
+ > ```bash
377
+ > magentrix iris-delete
378
+ > ```
379
+
364
380
  ### File Extensions
365
381
  - `.ac` - Classes
366
382
  - `.ctrl` - Controllers
@@ -433,6 +449,239 @@ The tool supports all file types including:
433
449
 
434
450
  ---
435
451
 
452
+ ## Deploying Vue.js (Iris) Apps
453
+
454
+ MagentrixCLI supports deploying Vue.js applications (Iris apps) to your Magentrix instance. These apps are built with Vue.js and Module Federation, allowing you to create custom frontend experiences.
455
+
456
+ > **⚠️ CRITICAL: Always use `magentrix iris-delete` to remove Iris apps!**
457
+ >
458
+ > Never manually delete folders from `src/iris-apps/`. Manual deletion bypasses backups, leaves orphaned apps on the server, and corrupts the cache. See [Deleting an Iris app](#delete-an-iris-app) for proper deletion.
459
+
460
+ ### Overview
461
+
462
+ The Iris deployment workflow:
463
+ 1. **Link** your Vue project to the CLI
464
+ 2. **Build and stage** the project to the CLI workspace
465
+ 3. **Publish** to Magentrix (automatically handled by `magentrix publish`)
466
+
467
+ ### Commands
468
+
469
+ #### Link a Vue Project
470
+ ```bash
471
+ magentrix iris-link
472
+ ```
473
+ **What it does**: Opens an interactive menu to manage linked Vue.js projects. Projects are stored globally so they persist across Magentrix workspaces.
474
+
475
+ **Options:**
476
+ - `--path <dir>` - Specify Vue project path directly
477
+ - `--unlink` - Remove a linked project
478
+ - `--list` - Show all linked projects
479
+ - `--cleanup` - Remove invalid (non-existent) linked projects
480
+
481
+ **Menu options:**
482
+ - Link a new Vue project
483
+ - View all linked projects
484
+ - Unlink a project
485
+ - Cleanup invalid projects
486
+
487
+ #### Build and Stage
488
+ ```bash
489
+ magentrix vue-build-stage
490
+ ```
491
+ **What it does**: Builds a linked Vue project and copies the output to `src/iris-apps/<slug>/` for publishing.
492
+
493
+ **Options:**
494
+ - `--path <dir>` - Specify Vue project path directly
495
+ - `--skip-build` - Use existing `dist/` folder without rebuilding
496
+
497
+ **Process:**
498
+ 1. Select from linked projects or enter path manually
499
+ 2. Run `npm run build` in the Vue project
500
+ 3. Validate the build output
501
+ 4. Copy to CLI workspace `src/iris-apps/<app-slug>/`
502
+
503
+ #### Vue Development Server
504
+ ```bash
505
+ magentrix iris-dev
506
+ ```
507
+ **What it does**: Starts the Vue development server with platform assets (CSS, fonts) automatically injected from your Magentrix instance.
508
+
509
+ **Options:**
510
+ - `--path <dir>` - Specify Vue project path
511
+ - `--no-inject` - Skip asset injection, just run dev server
512
+ - `--restore` - Restore config.ts from backup without running
513
+
514
+ **Process:**
515
+ 1. Fetch platform assets from Magentrix
516
+ 2. Backup `config.ts` and inject assets
517
+ 3. Run `npm run dev`
518
+ 4. Restore `config.ts` on exit (Ctrl+C)
519
+
520
+ #### Delete an Iris App
521
+ ```bash
522
+ magentrix iris-delete
523
+ ```
524
+ **What it does**: Safely delete a published Iris app with automatic recovery backup.
525
+
526
+ **Process:**
527
+ 1. Select app from list of published apps
528
+ 2. Show destructive warning
529
+ 3. Confirm by typing exact app slug
530
+ 4. Ask if you want to unlink the Vue project
531
+ 5. Create recovery backup in `.magentrix/iris-backups/`
532
+ 6. Delete from server and local files
533
+ 7. Update cache
534
+
535
+ **Safety features:**
536
+ - Automatic backup before deletion
537
+ - Must type slug name to confirm
538
+ - Recovery possible with `iris-recover`
539
+
540
+ #### Recover a Deleted App
541
+ ```bash
542
+ magentrix iris-recover
543
+ ```
544
+ **What it does**: Restore a deleted Iris app from automatic backup.
545
+
546
+ **Options:**
547
+ - `--list` - Show all available recovery backups
548
+
549
+ **Process:**
550
+ 1. Select backup to restore (sorted by deletion time)
551
+ 2. Check if linked Vue project still exists
552
+ 3. Restore files to `src/iris-apps/<slug>/`
553
+ 4. Re-link Vue project (if path exists)
554
+ 5. Show warnings for edge cases
555
+ 6. Optionally delete backup after recovery
556
+ 7. Run `magentrix publish` to sync to server
557
+
558
+ ### Vue Project Requirements
559
+
560
+ Your Vue project must have a `config.ts` file with these required fields:
561
+
562
+ ```typescript
563
+ // src/config.ts
564
+ export const config = {
565
+ appPath: "my-app", // App identifier (folder name on server)
566
+ appName: "My Application", // Display name in navigation menu
567
+ siteUrl: "https://yourinstance.magentrix.com",
568
+ assets: [] // Injected automatically by iris-dev
569
+ }
570
+ ```
571
+
572
+ **Accepted field names:**
573
+ - Slug: `appPath`, `slug`, or `app_path`
574
+ - Name: `appName`, `app_name`, or `name`
575
+ - URL: `siteUrl`, `site_url`, `baseUrl`, or `base_url`
576
+
577
+ ### Typical Development Workflow
578
+
579
+ ```bash
580
+ # First time setup
581
+ magentrix iris-link # Link your Vue project
582
+
583
+ # Development
584
+ magentrix iris-dev # Start dev server with platform assets
585
+ # Make changes, test locally
586
+ # Press Ctrl+C to stop
587
+
588
+ # Deployment (run from Magentrix workspace, not Vue project folder)
589
+ cd ~/magentrix-workspace # Navigate to Magentrix workspace
590
+ magentrix vue-build-stage --path ~/my-vue-app # Build and stage
591
+ # Prompted: "Do you want to publish to Magentrix now?" → Yes/No
592
+ # If autopublish is running, it auto-deploys instead
593
+
594
+ # Deleting an app
595
+ magentrix iris-delete # Select app, confirm, auto-backup created
596
+ magentrix publish # Sync deletion to server
597
+
598
+ # Recovering a deleted app
599
+ magentrix iris-recover # Select backup, restore files
600
+ magentrix publish # Sync recovery to server
601
+ ```
602
+
603
+ ### Real-Time Deployment
604
+
605
+ For automatic deployment during development:
606
+
607
+ ```bash
608
+ # Terminal 1: Run autopublish
609
+ magentrix autopublish
610
+
611
+ # Terminal 2: Build and stage after making changes
612
+ magentrix vue-build-stage
613
+ # Autopublish will detect the changes and upload automatically
614
+ ```
615
+
616
+ ### Troubleshooting Iris Apps
617
+
618
+ #### "Warning: Magentrix Workspace Not Detected"
619
+ This warning appears when running `magentrix vue-build-stage` outside your Magentrix CLI workspace.
620
+
621
+ **Why it happens:**
622
+ - The command stages build files to `src/iris-apps/<slug>/` in your Magentrix workspace
623
+ - You ran it from your Vue project directory or another location
624
+
625
+ **How to fix:**
626
+ 1. Navigate to your Magentrix CLI workspace (the folder with `.magentrix/` and `src/`)
627
+ 2. Run the command from there
628
+ 3. Use `--path` to specify your Vue project: `magentrix vue-build-stage --path /path/to/vue-project`
629
+
630
+ **Example:**
631
+ ```bash
632
+ # Wrong - running from Vue project
633
+ cd ~/my-vue-app
634
+ magentrix vue-build-stage # ⚠ Warning!
635
+
636
+ # Right - running from Magentrix workspace
637
+ cd ~/magentrix-workspace
638
+ magentrix vue-build-stage --path ~/my-vue-app # ✓ Works!
639
+ ```
640
+
641
+ #### "Missing required field: slug"
642
+ Your Vue project's `config.ts` is missing the app identifier. Add an `appPath` or `slug` field.
643
+
644
+ #### "Missing required field: appName"
645
+ Your Vue project's `config.ts` is missing the display name. Add an `appName` field.
646
+
647
+ #### Build fails with "VITE_SITE_URL is not defined"
648
+ This is a Vue project configuration issue, not a CLI issue. Check your Vue project's `.env` file or `vite.config.ts` for missing environment variables.
649
+
650
+ #### "No config.ts found"
651
+ The CLI looks for config in these locations:
652
+ - `src/config.ts`
653
+ - `config.ts`
654
+ - `src/iris-config.ts`
655
+ - `iris-config.ts`
656
+
657
+ #### Deleting an Iris app
658
+ To remove an Iris app:
659
+ ```bash
660
+ magentrix iris-delete
661
+ ```
662
+ This creates an automatic recovery backup before deletion. You can restore using `magentrix iris-recover`.
663
+
664
+ **Permission errors:**
665
+ If you get "Permission Denied" when deleting local files:
666
+ - The app is still deleted from the server and cache
667
+ - Delete the local folder manually with: `rm -rf src/iris-apps/<app-slug>`
668
+ - Or use sudo: `sudo rm -rf src/iris-apps/<app-slug>`
669
+
670
+ #### Recovering a deleted app
671
+ To restore a deleted Iris app:
672
+ ```bash
673
+ magentrix iris-recover --list # See all available backups
674
+ magentrix iris-recover # Select and restore a backup
675
+ magentrix publish # Sync to server
676
+ ```
677
+
678
+ **Important**: After recovery, you must run `magentrix publish` to sync the app back to the Magentrix server.
679
+
680
+ #### Changes not detected after vue-build-stage
681
+ The CLI uses content hash tracking to detect changes. If you rebuild without changes, `magentrix publish` will show "All files are in sync — nothing to publish!" This is expected behavior and saves unnecessary uploads.
682
+
683
+ ---
684
+
436
685
  ## Handling Conflicts
437
686
 
438
687
  When files have changed both locally and on the server, you'll see conflict options:
@@ -481,6 +730,31 @@ magentrix publish # Make sure all changes are uploaded
481
730
  magentrix status # Verify everything is in sync
482
731
  ```
483
732
 
733
+ ### Deploying a Vue.js App
734
+ ```bash
735
+ # Important: Run from your Magentrix CLI workspace, NOT the Vue project folder
736
+ cd ~/magentrix-workspace # Navigate to Magentrix workspace
737
+
738
+ magentrix iris-link # Link project (first time only)
739
+ magentrix vue-build-stage --path ~/my-vue-app # Build and stage
740
+ # Prompted: "Do you want to publish to Magentrix now?" (unless autopublish is running)
741
+ ```
742
+
743
+ **Note:** The `vue-build-stage` command must be run from your Magentrix CLI workspace directory (where `.magentrix/` and `src/` folders are). Use `--path` to specify your Vue project location.
744
+
745
+ ### Deleting and Recovering Apps
746
+ ```bash
747
+ # Delete an app (creates automatic backup)
748
+ magentrix iris-delete # Select app, confirm deletion
749
+
750
+ # View available backups
751
+ magentrix iris-recover --list
752
+
753
+ # Recover a deleted app
754
+ magentrix iris-recover # Select backup, restore
755
+ magentrix publish # Sync recovery to server
756
+ ```
757
+
484
758
  ---
485
759
 
486
760
  ## Using Git Alongside MagentrixCLI
@@ -762,6 +1036,11 @@ magentrix status # Shows sync status
762
1036
  - `magentrix status` - Check sync status
763
1037
  - `magentrix autopublish` - Auto-sync mode
764
1038
  - `magentrix update` - Update to latest version
1039
+ - `magentrix iris-link` - Link Vue.js projects for deployment
1040
+ - `magentrix vue-build-stage` - Build and stage Vue.js apps
1041
+ - `magentrix iris-dev` - Start Vue dev server with platform assets
1042
+ - `magentrix iris-delete` - Delete an Iris app with recovery backup
1043
+ - `magentrix iris-recover` - Recover a deleted Iris app
765
1044
 
766
1045
  ---
767
1046
 
@@ -773,5 +1052,6 @@ Once you're comfortable with basic usage:
773
1052
  2. **Learn the autopublish workflow** for faster development
774
1053
  3. **Explore conflict resolution** if you work in a team
775
1054
  4. **Check out templates** created by the `create` command to understand best practices
1055
+ 5. **Deploy Vue.js apps** using `iris-link`, `vue-build-stage`, and `iris-dev` commands
776
1056
 
777
1057
  Happy coding with MagentrixCLI! 🚀
@@ -2,61 +2,21 @@ import chokidar from 'chokidar';
2
2
  import { ensureValidCredentials } from '../utils/cli/helpers/ensureCredentials.js';
3
3
  import { withSpinner } from '../utils/spinner.js';
4
4
  import { EXPORT_ROOT } from '../vars/global.js';
5
- import fs from 'fs';
6
5
  import path from 'path';
7
6
  import chalk from 'chalk';
8
7
  import { runPublish } from './publish.js';
8
+ import {
9
+ acquireAutopublishLock,
10
+ releaseAutopublishLock,
11
+ getLockFilePath
12
+ } from '../utils/autopublishLock.js';
9
13
 
10
- const LOCK_FILE = path.join(process.cwd(), '.magentrix', 'autopublish.lock');
14
+ const LOCK_FILE = getLockFilePath();
11
15
 
12
16
  let credentials = {};
13
17
  let isProcessing = false;
14
18
  let pendingFiles = new Set(); // Track files that have changed while processing
15
19
 
16
- /**
17
- * Creates a lock file to prevent multiple autopublish instances
18
- * @returns {boolean} True if lock was acquired, false if already locked
19
- */
20
- const acquireLock = () => {
21
- try {
22
- if (fs.existsSync(LOCK_FILE)) {
23
- // Check if the lock is stale (process might have crashed)
24
- const lockData = JSON.parse(fs.readFileSync(LOCK_FILE, 'utf-8'));
25
- const lockAge = Date.now() - lockData.timestamp;
26
-
27
- // If lock is older than 1 hour, consider it stale
28
- if (lockAge < 3600000) {
29
- return false;
30
- }
31
- }
32
-
33
- // Create lock file
34
- fs.mkdirSync(path.dirname(LOCK_FILE), { recursive: true });
35
- fs.writeFileSync(LOCK_FILE, JSON.stringify({
36
- pid: process.pid,
37
- timestamp: Date.now()
38
- }));
39
-
40
- return true;
41
- } catch (err) {
42
- console.error(chalk.red(`Failed to acquire lock: ${err.message}`));
43
- return false;
44
- }
45
- };
46
-
47
- /**
48
- * Releases the lock file
49
- */
50
- const releaseLock = () => {
51
- try {
52
- if (fs.existsSync(LOCK_FILE)) {
53
- fs.unlinkSync(LOCK_FILE);
54
- }
55
- } catch (err) {
56
- console.error(chalk.red(`Failed to release lock: ${err.message}`));
57
- }
58
- };
59
-
60
20
  /**
61
21
  * Debounce timer for batching changes
62
22
  */
@@ -220,6 +180,7 @@ const startWatcher = () => {
220
180
  console.log(chalk.gray('─'.repeat(48)));
221
181
  console.log(chalk.green('Watching for file changes in:'));
222
182
  console.log(chalk.cyan(` ${path.join(process.cwd(), EXPORT_ROOT)}`));
183
+ console.log(chalk.gray(' Includes: Code, Assets, and Iris apps'));
223
184
  console.log(chalk.gray('Press Ctrl+C to stop'));
224
185
  console.log();
225
186
 
@@ -244,7 +205,7 @@ const startWatcher = () => {
244
205
  const cleanup = () => {
245
206
  console.log(chalk.yellow('\n\nStopping auto-publish...'));
246
207
  watcher.close();
247
- releaseLock();
208
+ releaseAutopublishLock();
248
209
  process.exit(0);
249
210
  };
250
211
 
@@ -259,7 +220,7 @@ export const autoPublish = async () => {
259
220
  process.stdout.write('\x1Bc');
260
221
 
261
222
  // Check for existing lock
262
- if (!acquireLock()) {
223
+ if (!acquireAutopublishLock()) {
263
224
  console.log(chalk.bgRed.bold.white(' ✖ Already Running '));
264
225
  console.log(chalk.redBright('─'.repeat(48)));
265
226
  console.log(chalk.red('Another instance of autopublish is already running.'));