@magentrix-corp/magentrix-cli 1.2.1 → 1.3.1

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
 
@@ -209,6 +210,7 @@ This creates a `src` folder with all your files organized into:
209
210
  - `Pages/` - Your ASPX pages (`.aspx` files)
210
211
  - `Templates/` - Your templates (`.aspx` files)
211
212
  - `Assets/` - Your static assets (images, CSS, JavaScript, etc.)
213
+ - `iris-apps/` - Your Iris Vue.js applications
212
214
 
213
215
  ---
214
216
 
@@ -357,10 +359,25 @@ src/
357
359
  ├── Triggers/ # Trigger code (*.trigger files)
358
360
  ├── Pages/ # ASPX pages (*.aspx files)
359
361
  ├── Templates/ # Templates (*.aspx files)
360
- └── Contents/
361
- └── Assets/ # Static assets (images, CSS, JS, etc.)
362
+ ├── Contents/
363
+ └── Assets/ # Static assets (images, CSS, JS, etc.)
364
+ └── iris-apps/ # Vue.js Iris applications (see warning below)
365
+ └── <app-slug>/ # Each app in its own folder
362
366
  ```
363
367
 
368
+ > **⚠️ IMPORTANT: Deleting Iris Apps**
369
+ >
370
+ > **NEVER manually delete folders from `src/iris-apps/`!** Always use the `magentrix iris-delete` command to remove Iris apps. Manual deletion will cause:
371
+ > - No recovery backup created (you cannot restore the app)
372
+ > - App remains on the Magentrix server (orphaned)
373
+ > - Cache becomes out of sync (causes errors on next publish)
374
+ > - Linked Vue project not properly unlinked
375
+ >
376
+ > **Correct way to delete an Iris app:**
377
+ > ```bash
378
+ > magentrix iris-delete
379
+ > ```
380
+
364
381
  ### File Extensions
365
382
  - `.ac` - Classes
366
383
  - `.ctrl` - Controllers
@@ -433,6 +450,239 @@ The tool supports all file types including:
433
450
 
434
451
  ---
435
452
 
453
+ ## Deploying Vue.js (Iris) Apps
454
+
455
+ 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.
456
+
457
+ > **⚠️ CRITICAL: Always use `magentrix iris-delete` to remove Iris apps!**
458
+ >
459
+ > 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.
460
+
461
+ ### Overview
462
+
463
+ The Iris deployment workflow:
464
+ 1. **Link** your Vue project to the CLI
465
+ 2. **Build and stage** the project to the CLI workspace
466
+ 3. **Publish** to Magentrix (automatically handled by `magentrix publish`)
467
+
468
+ ### Commands
469
+
470
+ #### Link a Vue Project
471
+ ```bash
472
+ magentrix iris-link
473
+ ```
474
+ **What it does**: Opens an interactive menu to manage linked Vue.js projects. Projects are stored globally so they persist across Magentrix workspaces.
475
+
476
+ **Options:**
477
+ - `--path <dir>` - Specify Vue project path directly
478
+ - `--unlink` - Remove a linked project
479
+ - `--list` - Show all linked projects
480
+ - `--cleanup` - Remove invalid (non-existent) linked projects
481
+
482
+ **Menu options:**
483
+ - Link a new Vue project
484
+ - View all linked projects
485
+ - Unlink a project
486
+ - Cleanup invalid projects
487
+
488
+ #### Build and Stage
489
+ ```bash
490
+ magentrix vue-build-stage
491
+ ```
492
+ **What it does**: Builds a linked Vue project and copies the output to `src/iris-apps/<slug>/` for publishing.
493
+
494
+ **Options:**
495
+ - `--path <dir>` - Specify Vue project path directly
496
+ - `--skip-build` - Use existing `dist/` folder without rebuilding
497
+
498
+ **Process:**
499
+ 1. Select from linked projects or enter path manually
500
+ 2. Run `npm run build` in the Vue project
501
+ 3. Validate the build output
502
+ 4. Copy to CLI workspace `src/iris-apps/<app-slug>/`
503
+
504
+ #### Vue Development Server
505
+ ```bash
506
+ magentrix iris-dev
507
+ ```
508
+ **What it does**: Starts the Vue development server with platform assets (CSS, fonts) automatically injected from your Magentrix instance.
509
+
510
+ **Options:**
511
+ - `--path <dir>` - Specify Vue project path
512
+ - `--no-inject` - Skip asset injection, just run dev server
513
+ - `--restore` - Restore config.ts from backup without running
514
+
515
+ **Process:**
516
+ 1. Fetch platform assets from Magentrix
517
+ 2. Backup `config.ts` and inject assets
518
+ 3. Run `npm run dev`
519
+ 4. Restore `config.ts` on exit (Ctrl+C)
520
+
521
+ #### Delete an Iris App
522
+ ```bash
523
+ magentrix iris-delete
524
+ ```
525
+ **What it does**: Safely delete a published Iris app with automatic recovery backup.
526
+
527
+ **Process:**
528
+ 1. Select app from list of published apps
529
+ 2. Show destructive warning
530
+ 3. Confirm by typing exact app slug
531
+ 4. Ask if you want to unlink the Vue project
532
+ 5. Create recovery backup in `.magentrix/iris-backups/`
533
+ 6. Delete from server and local files
534
+ 7. Update cache
535
+
536
+ **Safety features:**
537
+ - Automatic backup before deletion
538
+ - Must type slug name to confirm
539
+ - Recovery possible with `iris-recover`
540
+
541
+ #### Recover a Deleted App
542
+ ```bash
543
+ magentrix iris-recover
544
+ ```
545
+ **What it does**: Restore a deleted Iris app from automatic backup.
546
+
547
+ **Options:**
548
+ - `--list` - Show all available recovery backups
549
+
550
+ **Process:**
551
+ 1. Select backup to restore (sorted by deletion time)
552
+ 2. Check if linked Vue project still exists
553
+ 3. Restore files to `src/iris-apps/<slug>/`
554
+ 4. Re-link Vue project (if path exists)
555
+ 5. Show warnings for edge cases
556
+ 6. Optionally delete backup after recovery
557
+ 7. Run `magentrix publish` to sync to server
558
+
559
+ ### Vue Project Requirements
560
+
561
+ Your Vue project must have a `config.ts` file with these required fields:
562
+
563
+ ```typescript
564
+ // src/config.ts
565
+ export const config = {
566
+ appPath: "my-app", // App identifier (folder name on server)
567
+ appName: "My Application", // Display name in navigation menu
568
+ siteUrl: "https://yourinstance.magentrix.com",
569
+ assets: [] // Injected automatically by iris-dev
570
+ }
571
+ ```
572
+
573
+ **Accepted field names:**
574
+ - Slug: `appPath`, `slug`, or `app_path`
575
+ - Name: `appName`, `app_name`, or `name`
576
+ - URL: `siteUrl`, `site_url`, `baseUrl`, or `base_url`
577
+
578
+ ### Typical Development Workflow
579
+
580
+ ```bash
581
+ # First time setup
582
+ magentrix iris-link # Link your Vue project
583
+
584
+ # Development
585
+ magentrix iris-dev # Start dev server with platform assets
586
+ # Make changes, test locally
587
+ # Press Ctrl+C to stop
588
+
589
+ # Deployment (run from Magentrix workspace, not Vue project folder)
590
+ cd ~/magentrix-workspace # Navigate to Magentrix workspace
591
+ magentrix vue-build-stage --path ~/my-vue-app # Build and stage
592
+ # Prompted: "Do you want to publish to Magentrix now?" → Yes/No
593
+ # If autopublish is running, it auto-deploys instead
594
+
595
+ # Deleting an app
596
+ magentrix iris-delete # Select app, confirm, auto-backup created
597
+ magentrix publish # Sync deletion to server
598
+
599
+ # Recovering a deleted app
600
+ magentrix iris-recover # Select backup, restore files
601
+ magentrix publish # Sync recovery to server
602
+ ```
603
+
604
+ ### Real-Time Deployment
605
+
606
+ For automatic deployment during development:
607
+
608
+ ```bash
609
+ # Terminal 1: Run autopublish
610
+ magentrix autopublish
611
+
612
+ # Terminal 2: Build and stage after making changes
613
+ magentrix vue-build-stage
614
+ # Autopublish will detect the changes and upload automatically
615
+ ```
616
+
617
+ ### Troubleshooting Iris Apps
618
+
619
+ #### "Warning: Magentrix Workspace Not Detected"
620
+ This warning appears when running `magentrix vue-build-stage` outside your Magentrix CLI workspace.
621
+
622
+ **Why it happens:**
623
+ - The command stages build files to `src/iris-apps/<slug>/` in your Magentrix workspace
624
+ - You ran it from your Vue project directory or another location
625
+
626
+ **How to fix:**
627
+ 1. Navigate to your Magentrix CLI workspace (the folder with `.magentrix/` and `src/`)
628
+ 2. Run the command from there
629
+ 3. Use `--path` to specify your Vue project: `magentrix vue-build-stage --path /path/to/vue-project`
630
+
631
+ **Example:**
632
+ ```bash
633
+ # Wrong - running from Vue project
634
+ cd ~/my-vue-app
635
+ magentrix vue-build-stage # ⚠ Warning!
636
+
637
+ # Right - running from Magentrix workspace
638
+ cd ~/magentrix-workspace
639
+ magentrix vue-build-stage --path ~/my-vue-app # ✓ Works!
640
+ ```
641
+
642
+ #### "Missing required field: slug"
643
+ Your Vue project's `config.ts` is missing the app identifier. Add an `appPath` or `slug` field.
644
+
645
+ #### "Missing required field: appName"
646
+ Your Vue project's `config.ts` is missing the display name. Add an `appName` field.
647
+
648
+ #### Build fails with "VITE_SITE_URL is not defined"
649
+ 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.
650
+
651
+ #### "No config.ts found"
652
+ The CLI looks for config in these locations:
653
+ - `src/config.ts`
654
+ - `config.ts`
655
+ - `src/iris-config.ts`
656
+ - `iris-config.ts`
657
+
658
+ #### Deleting an Iris app
659
+ To remove an Iris app:
660
+ ```bash
661
+ magentrix iris-delete
662
+ ```
663
+ This creates an automatic recovery backup before deletion. You can restore using `magentrix iris-recover`.
664
+
665
+ **Permission errors:**
666
+ If you get "Permission Denied" when deleting local files:
667
+ - The app is still deleted from the server and cache
668
+ - Delete the local folder manually with: `rm -rf src/iris-apps/<app-slug>`
669
+ - Or use sudo: `sudo rm -rf src/iris-apps/<app-slug>`
670
+
671
+ #### Recovering a deleted app
672
+ To restore a deleted Iris app:
673
+ ```bash
674
+ magentrix iris-recover --list # See all available backups
675
+ magentrix iris-recover # Select and restore a backup
676
+ magentrix publish # Sync to server
677
+ ```
678
+
679
+ **Important**: After recovery, you must run `magentrix publish` to sync the app back to the Magentrix server.
680
+
681
+ #### Changes not detected after vue-build-stage
682
+ 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.
683
+
684
+ ---
685
+
436
686
  ## Handling Conflicts
437
687
 
438
688
  When files have changed both locally and on the server, you'll see conflict options:
@@ -481,6 +731,31 @@ magentrix publish # Make sure all changes are uploaded
481
731
  magentrix status # Verify everything is in sync
482
732
  ```
483
733
 
734
+ ### Deploying a Vue.js App
735
+ ```bash
736
+ # Important: Run from your Magentrix CLI workspace, NOT the Vue project folder
737
+ cd ~/magentrix-workspace # Navigate to Magentrix workspace
738
+
739
+ magentrix iris-link # Link project (first time only)
740
+ magentrix vue-build-stage --path ~/my-vue-app # Build and stage
741
+ # Prompted: "Do you want to publish to Magentrix now?" (unless autopublish is running)
742
+ ```
743
+
744
+ **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.
745
+
746
+ ### Deleting and Recovering Apps
747
+ ```bash
748
+ # Delete an app (creates automatic backup)
749
+ magentrix iris-delete # Select app, confirm deletion
750
+
751
+ # View available backups
752
+ magentrix iris-recover --list
753
+
754
+ # Recover a deleted app
755
+ magentrix iris-recover # Select backup, restore
756
+ magentrix publish # Sync recovery to server
757
+ ```
758
+
484
759
  ---
485
760
 
486
761
  ## Using Git Alongside MagentrixCLI
@@ -762,6 +1037,11 @@ magentrix status # Shows sync status
762
1037
  - `magentrix status` - Check sync status
763
1038
  - `magentrix autopublish` - Auto-sync mode
764
1039
  - `magentrix update` - Update to latest version
1040
+ - `magentrix iris-link` - Link Vue.js projects for deployment
1041
+ - `magentrix vue-build-stage` - Build and stage Vue.js apps
1042
+ - `magentrix iris-dev` - Start Vue dev server with platform assets
1043
+ - `magentrix iris-delete` - Delete an Iris app with recovery backup
1044
+ - `magentrix iris-recover` - Recover a deleted Iris app
765
1045
 
766
1046
  ---
767
1047
 
@@ -773,5 +1053,6 @@ Once you're comfortable with basic usage:
773
1053
  2. **Learn the autopublish workflow** for faster development
774
1054
  3. **Explore conflict resolution** if you work in a team
775
1055
  4. **Check out templates** created by the `create` command to understand best practices
1056
+ 5. **Deploy Vue.js apps** using `iris-link`, `vue-build-stage`, and `iris-dev` commands
776
1057
 
777
1058
  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.'));