@magentrix-corp/magentrix-cli 1.0.0 → 1.1.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 +161 -3
- package/actions/autopublish.v2.js +2 -2
- package/actions/create.js +180 -64
- package/actions/publish.js +348 -253
- package/actions/pull.js +53 -8
- package/actions/setup.js +34 -7
- package/bin/magentrix.js +61 -2
- package/package.json +3 -10
- package/utils/assetPaths.js +138 -0
- package/utils/cacher.js +5 -2
- package/utils/cli/helpers/compare.js +4 -2
- package/utils/downloadAssets.js +14 -8
- package/utils/magentrix/api/assets.js +21 -1
- package/utils/magentrix/api/retrieveEntity.js +55 -1
- package/utils/updateFileBase.js +8 -3
- package/vars/global.js +1 -0
package/README.md
CHANGED
|
@@ -63,9 +63,59 @@ You should see the version number displayed.
|
|
|
63
63
|
|
|
64
64
|
---
|
|
65
65
|
|
|
66
|
+
## Updating the Package
|
|
67
|
+
|
|
68
|
+
To update MagentrixCLI to the latest version:
|
|
69
|
+
|
|
70
|
+
### Global Installation Update
|
|
71
|
+
If you installed globally (recommended):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm update -g @magentrix-corp/magentrix-cli
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or to ensure you get the absolute latest version:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm install -g @magentrix-corp/magentrix-cli@latest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Local Installation Update
|
|
84
|
+
If you installed locally in your project:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm update @magentrix-corp/magentrix-cli
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or for the latest version:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install @magentrix-corp/magentrix-cli@latest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Check for Updates
|
|
97
|
+
To see if you're running the latest version:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Check your current version
|
|
101
|
+
magentrix --version
|
|
102
|
+
|
|
103
|
+
# Check the latest available version on npm
|
|
104
|
+
npm view @magentrix-corp/magentrix-cli version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### After Updating
|
|
108
|
+
Your configuration and local files are preserved during updates. You don't need to run `magentrix setup` again unless there are breaking changes (which will be noted in release notes).
|
|
109
|
+
|
|
110
|
+
**Note**: It's a good practice to check for updates periodically to get the latest features, bug fixes, and performance improvements.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
66
114
|
## First Time Setup
|
|
67
115
|
|
|
68
116
|
### Step 1: Configure Your Credentials
|
|
117
|
+
|
|
118
|
+
#### Interactive Setup
|
|
69
119
|
Run this command to set up your connection to Magentrix:
|
|
70
120
|
|
|
71
121
|
```bash
|
|
@@ -76,6 +126,17 @@ You'll be prompted for:
|
|
|
76
126
|
- **API Key**: Paste your Magentrix API key
|
|
77
127
|
- **Instance URL**: Enter your Magentrix URL (like `https://yourcompany.magentrixcloud.com`)
|
|
78
128
|
|
|
129
|
+
#### Non-Interactive Setup
|
|
130
|
+
For automation or CI/CD, you can provide credentials via command-line flags:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
magentrix setup --api-key YOUR_API_KEY --instance-url https://yourcompany.magentrixcloud.com
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Available flags:**
|
|
137
|
+
- `--api-key <apiKey>` - Your Magentrix API key
|
|
138
|
+
- `--instance-url <instanceUrl>` - Your Magentrix instance URL
|
|
139
|
+
|
|
79
140
|
The tool will test your credentials and save them securely. It will also automatically configure VS Code file associations for syntax highlighting of Magentrix file types (.ac, .ctrl, .trigger, .aspx files).
|
|
80
141
|
|
|
81
142
|
### Editor Support
|
|
@@ -96,6 +157,7 @@ This creates a `src` folder with all your files organized into:
|
|
|
96
157
|
- `Triggers/` - Your trigger code (`.trigger` files)
|
|
97
158
|
- `Pages/` - Your ASPX pages (`.aspx` files)
|
|
98
159
|
- `Templates/` - Your templates (`.aspx` files)
|
|
160
|
+
- `Assets/` - Your static assets (images, CSS, JavaScript, etc.)
|
|
99
161
|
|
|
100
162
|
---
|
|
101
163
|
|
|
@@ -132,7 +194,7 @@ magentrix status
|
|
|
132
194
|
```bash
|
|
133
195
|
magentrix publish
|
|
134
196
|
```
|
|
135
|
-
**What it does**: Sends all unpublished changes from your local machine to the Magentrix server and compiles them. Shows you exactly what will be created, updated, or deleted before doing it. Processes all changes in parallel for speed.
|
|
197
|
+
**What it does**: Sends all unpublished changes from your local machine to the Magentrix server and compiles them. Shows you exactly what will be created, updated, or deleted before doing it. Processes all changes in parallel for speed. Works with both code files and static assets.
|
|
136
198
|
**When to use**:
|
|
137
199
|
- After you've finished making changes and want to deploy them
|
|
138
200
|
- At the end of your work session
|
|
@@ -142,7 +204,7 @@ magentrix publish
|
|
|
142
204
|
```bash
|
|
143
205
|
magentrix autopublish
|
|
144
206
|
```
|
|
145
|
-
**What it does**: Watches your files for changes and automatically uploads and compiles them on the server whenever you save a file. Shows compilation status and any errors in the terminal in real-time. Can take some time to sync each file.
|
|
207
|
+
**What it does**: Watches your files for changes and automatically uploads and compiles them on the server whenever you save a file. Shows compilation status and any errors in the terminal in real-time. Works with both code files and static assets. Can take some time to sync each file.
|
|
146
208
|
**When to use**:
|
|
147
209
|
- During active development when you want immediate feedback
|
|
148
210
|
- When testing changes and want to see results right away
|
|
@@ -177,6 +239,43 @@ This starts an interactive wizard:
|
|
|
177
239
|
|
|
178
240
|
The tool creates the file both locally and on your Magentrix server with proper templates.
|
|
179
241
|
|
|
242
|
+
### Non-Interactive File Creation
|
|
243
|
+
For automation or scripting, you can provide all parameters via command-line flags:
|
|
244
|
+
|
|
245
|
+
#### Create a Controller
|
|
246
|
+
```bash
|
|
247
|
+
magentrix create --type class --class-type controller --name UserController --description "Handles user operations"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### Create a Utility Class
|
|
251
|
+
```bash
|
|
252
|
+
magentrix create --type class --class-type utility --name EmailHelper --description "Email utility functions"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### Create a Trigger
|
|
256
|
+
```bash
|
|
257
|
+
magentrix create --type class --class-type trigger --entity-id ENTITY_ID --name AccountTrigger --description "Account trigger logic"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Create a Page
|
|
261
|
+
```bash
|
|
262
|
+
magentrix create --type page --name Dashboard --description "Main dashboard page"
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### Create a Template
|
|
266
|
+
```bash
|
|
267
|
+
magentrix create --type template --name EmailTemplate --description "Email notification template"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Available flags:**
|
|
271
|
+
- `--type <type>` - Entity type: `class`, `page`, or `template`
|
|
272
|
+
- `--class-type <classType>` - For classes: `controller`, `utility`, or `trigger`
|
|
273
|
+
- `--name <name>` - Name of the file to create
|
|
274
|
+
- `--description <description>` - Optional description
|
|
275
|
+
- `--entity-id <entityId>` - Required for triggers: the entity ID to attach the trigger to
|
|
276
|
+
|
|
277
|
+
**Tip**: You can mix interactive and non-interactive modes. For example, provide just the `--name` flag and the tool will prompt you for the rest.
|
|
278
|
+
|
|
180
279
|
---
|
|
181
280
|
|
|
182
281
|
## Working with Files
|
|
@@ -189,7 +288,9 @@ src/
|
|
|
189
288
|
├── Controllers/ # Controllers (*.ctrl files)
|
|
190
289
|
├── Triggers/ # Trigger code (*.trigger files)
|
|
191
290
|
├── Pages/ # ASPX pages (*.aspx files)
|
|
192
|
-
|
|
291
|
+
├── Templates/ # Templates (*.aspx files)
|
|
292
|
+
└── Contents/
|
|
293
|
+
└── Assets/ # Static assets (images, CSS, JS, etc.)
|
|
193
294
|
```
|
|
194
295
|
|
|
195
296
|
### File Extensions
|
|
@@ -207,6 +308,63 @@ src/
|
|
|
207
308
|
|
|
208
309
|
---
|
|
209
310
|
|
|
311
|
+
## Working with Static Assets
|
|
312
|
+
|
|
313
|
+
### What Are Static Assets?
|
|
314
|
+
Static assets are non-code files like images, CSS stylesheets, JavaScript files, and other resources that your Magentrix application uses.
|
|
315
|
+
|
|
316
|
+
### Asset Organization
|
|
317
|
+
All static assets are stored in the `src/Contents/Assets/` directory. You can organize them into subfolders:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
src/Contents/Assets/
|
|
321
|
+
├── images/
|
|
322
|
+
│ ├── logo.png
|
|
323
|
+
│ └── banner.jpg
|
|
324
|
+
├── css/
|
|
325
|
+
│ └── custom-styles.css
|
|
326
|
+
└── js/
|
|
327
|
+
└── helpers.js
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Working with Assets
|
|
331
|
+
|
|
332
|
+
#### Downloading Assets
|
|
333
|
+
```bash
|
|
334
|
+
magentrix pull
|
|
335
|
+
```
|
|
336
|
+
Downloads all static assets from the server along with your code files. The folder structure is preserved.
|
|
337
|
+
|
|
338
|
+
#### Adding New Assets
|
|
339
|
+
1. Place your files in `src/Contents/Assets/` (or a subfolder)
|
|
340
|
+
2. Run `magentrix publish` to upload them
|
|
341
|
+
- Or use `magentrix autopublish` for automatic uploads
|
|
342
|
+
|
|
343
|
+
#### Updating Assets
|
|
344
|
+
1. Edit or replace the file locally in `src/Contents/Assets/`
|
|
345
|
+
2. Run `magentrix publish` to upload the updated version
|
|
346
|
+
- Or use `magentrix autopublish` for automatic uploads
|
|
347
|
+
|
|
348
|
+
#### Deleting Assets
|
|
349
|
+
1. Delete the file from `src/Contents/Assets/`
|
|
350
|
+
2. Run `magentrix publish` to remove it from the server
|
|
351
|
+
|
|
352
|
+
### Supported File Types
|
|
353
|
+
The tool supports all file types including:
|
|
354
|
+
- Images: `.png`, `.jpg`, `.jpeg`, `.gif`, `.svg`, `.ico`
|
|
355
|
+
- Stylesheets: `.css`
|
|
356
|
+
- Scripts: `.js`
|
|
357
|
+
- Documents: `.pdf`, `.txt`, `.json`
|
|
358
|
+
- Any other file type you need
|
|
359
|
+
|
|
360
|
+
### Important Notes
|
|
361
|
+
- Assets are synced alongside code files
|
|
362
|
+
- Folder structures are preserved when syncing
|
|
363
|
+
- Large files are handled efficiently using batch operations
|
|
364
|
+
- Binary files (like images) are fully supported
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
210
368
|
## Handling Conflicts
|
|
211
369
|
|
|
212
370
|
When files have changed both locally and on the server, you'll see conflict options:
|
|
@@ -117,11 +117,11 @@ const readFileSafe = (filePath) => {
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
|
-
* Checks if file is within
|
|
120
|
+
* Checks if file is within Assets (static asset)
|
|
121
121
|
*/
|
|
122
122
|
const isStaticAsset = (filePath) => {
|
|
123
123
|
const normalizedPath = path.normalize(filePath);
|
|
124
|
-
return normalizedPath.includes(path.join('
|
|
124
|
+
return normalizedPath.includes(path.join('Assets'));
|
|
125
125
|
};
|
|
126
126
|
|
|
127
127
|
/**
|
package/actions/create.js
CHANGED
|
@@ -10,6 +10,7 @@ import fs from 'fs';
|
|
|
10
10
|
import chalk from 'chalk';
|
|
11
11
|
import { setFileTag } from "../utils/filetag.js";
|
|
12
12
|
import { updateBase } from "../utils/updateFileBase.js";
|
|
13
|
+
import { sha256 } from "../utils/hash.js";
|
|
13
14
|
|
|
14
15
|
// Credentials and entity cache (module-scope for re-use during prompt session)
|
|
15
16
|
let credentials = {};
|
|
@@ -57,42 +58,68 @@ const searchEntities = async (term = '') => {
|
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* CLI prompt flow for creating an ActiveClass record.
|
|
60
|
-
*
|
|
61
|
+
*
|
|
61
62
|
* - Prompts for type (Controller, Utility, or Trigger)
|
|
62
63
|
* - For Trigger, also prompts for target entity selection (searchable)
|
|
63
64
|
* - Prompts for class name and optional description
|
|
64
|
-
*
|
|
65
|
+
*
|
|
65
66
|
* @async
|
|
67
|
+
* @param {Object} options - CLI options to bypass prompts
|
|
66
68
|
* @returns {Promise<Object>} The creation payload for ActiveClass.
|
|
67
69
|
*/
|
|
68
|
-
const createActiveClass = async () => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const createActiveClass = async (options = {}) => {
|
|
71
|
+
let classType = options.classType;
|
|
72
|
+
|
|
73
|
+
// Normalize class type from CLI format to internal format
|
|
74
|
+
if (classType) {
|
|
75
|
+
const typeMap = {
|
|
76
|
+
'controller': 'Controller',
|
|
77
|
+
'utility': 'Utility',
|
|
78
|
+
'class': 'Utility',
|
|
79
|
+
'trigger': 'Trigger'
|
|
80
|
+
};
|
|
81
|
+
classType = typeMap[classType.toLowerCase()] || classType;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!classType) {
|
|
85
|
+
classType = await select({
|
|
86
|
+
message: "Select ActiveClass type:",
|
|
87
|
+
choices: [
|
|
88
|
+
{ name: "Controller", value: "Controller" },
|
|
89
|
+
{ name: "Class", value: "Utility" },
|
|
90
|
+
{ name: "Trigger", value: "Trigger" }
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
77
94
|
|
|
78
95
|
if (classType === "Trigger") {
|
|
79
|
-
|
|
80
|
-
await loadEntities();
|
|
96
|
+
let entityId = options.entityId;
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
pageSize: 8
|
|
86
|
-
});
|
|
98
|
+
if (!entityId) {
|
|
99
|
+
// Ensure entity list is loaded for search prompt
|
|
100
|
+
await loadEntities();
|
|
87
101
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
102
|
+
entityId = await search({
|
|
103
|
+
message: "Search and select entity for this Trigger:",
|
|
104
|
+
source: searchEntities,
|
|
105
|
+
pageSize: 8
|
|
106
|
+
});
|
|
107
|
+
}
|
|
92
108
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
let className = options.name;
|
|
110
|
+
if (!className) {
|
|
111
|
+
className = await input({
|
|
112
|
+
message: "Trigger class name:",
|
|
113
|
+
validate: (input) => input.length > 0 || "Please enter a class name"
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let description = options.description;
|
|
118
|
+
if (description === undefined) {
|
|
119
|
+
description = await input({
|
|
120
|
+
message: "Description (optional):"
|
|
121
|
+
});
|
|
122
|
+
}
|
|
96
123
|
|
|
97
124
|
return {
|
|
98
125
|
type: "ActiveClass",
|
|
@@ -106,14 +133,20 @@ const createActiveClass = async () => {
|
|
|
106
133
|
const hint = classType === "Controller" ? "(without controller keyword)" : ""
|
|
107
134
|
|
|
108
135
|
// Flow for Controller or Utility
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
136
|
+
let className = options.name;
|
|
137
|
+
if (!className) {
|
|
138
|
+
className = await input({
|
|
139
|
+
message: `${classType} class name ${hint}:`,
|
|
140
|
+
validate: (input) => input.length > 0 || "Please enter a class name"
|
|
141
|
+
});
|
|
142
|
+
}
|
|
113
143
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
144
|
+
let description = options.description;
|
|
145
|
+
if (description === undefined) {
|
|
146
|
+
description = await input({
|
|
147
|
+
message: "Description (optional):"
|
|
148
|
+
});
|
|
149
|
+
}
|
|
117
150
|
|
|
118
151
|
return {
|
|
119
152
|
type: "ActiveClass",
|
|
@@ -125,29 +158,50 @@ const createActiveClass = async () => {
|
|
|
125
158
|
|
|
126
159
|
/**
|
|
127
160
|
* CLI prompt flow for creating an ActivePage record.
|
|
128
|
-
*
|
|
161
|
+
*
|
|
129
162
|
* - Prompts for page name and optional description.
|
|
130
|
-
*
|
|
163
|
+
*
|
|
131
164
|
* @async
|
|
165
|
+
* @param {Object} options - CLI options to bypass prompts
|
|
166
|
+
* @param {string} options.pageType - Pre-determined page type (Page or Template)
|
|
132
167
|
* @returns {Promise<Object>} The creation payload for ActivePage.
|
|
133
168
|
*/
|
|
134
|
-
const createActivePage = async () => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
169
|
+
const createActivePage = async (options = {}) => {
|
|
170
|
+
let pageType = options.pageType;
|
|
171
|
+
|
|
172
|
+
// Normalize page type from CLI format to internal format
|
|
173
|
+
if (pageType) {
|
|
174
|
+
const typeMap = {
|
|
175
|
+
'page': 'Page',
|
|
176
|
+
'template': 'Template'
|
|
177
|
+
};
|
|
178
|
+
pageType = typeMap[pageType.toLowerCase()] || pageType;
|
|
179
|
+
}
|
|
142
180
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
181
|
+
if (!pageType) {
|
|
182
|
+
pageType = await select({
|
|
183
|
+
message: "Select ActivePage type:",
|
|
184
|
+
choices: [
|
|
185
|
+
{ name: "Page", value: "Page" },
|
|
186
|
+
{ name: "Template", value: "Template" }
|
|
187
|
+
]
|
|
188
|
+
});
|
|
189
|
+
}
|
|
147
190
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
191
|
+
let pageName = options.name;
|
|
192
|
+
if (!pageName) {
|
|
193
|
+
pageName = await input({
|
|
194
|
+
message: `${pageType} name:`,
|
|
195
|
+
validate: (input) => input.length > 0 || `Please enter a ${pageType.toLowerCase()} name`
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
let description = options.description;
|
|
200
|
+
if (description === undefined) {
|
|
201
|
+
description = await input({
|
|
202
|
+
message: "Description (optional):"
|
|
203
|
+
});
|
|
204
|
+
}
|
|
151
205
|
|
|
152
206
|
return {
|
|
153
207
|
type: pageType,
|
|
@@ -193,24 +247,63 @@ const saveToFile = async (entityType, formattedData, recordId) => {
|
|
|
193
247
|
|
|
194
248
|
// Add a file tag so we can keep track of file changes
|
|
195
249
|
await setFileTag(filePath, recordId);
|
|
196
|
-
|
|
250
|
+
|
|
251
|
+
// Update base with content snapshot to ensure cache is in sync
|
|
252
|
+
const contentHash = sha256(fileContent);
|
|
253
|
+
updateBase(
|
|
254
|
+
filePath,
|
|
255
|
+
{ Id: recordId, Type: mapKey },
|
|
256
|
+
'',
|
|
257
|
+
{ content: fileContent, hash: contentHash }
|
|
258
|
+
);
|
|
197
259
|
|
|
198
260
|
return filePath;
|
|
199
261
|
};
|
|
200
262
|
|
|
201
263
|
/**
|
|
202
264
|
* Main CLI handler for `magentrix create`.
|
|
203
|
-
*
|
|
265
|
+
*
|
|
204
266
|
* - Ensures valid Magentrix credentials.
|
|
205
267
|
* - Prompts user to choose entity type (ActiveClass or ActivePage).
|
|
206
268
|
* - Runs the appropriate prompt flow to gather data.
|
|
207
269
|
* - Logs (or sends) the resulting payload.
|
|
208
|
-
*
|
|
270
|
+
*
|
|
209
271
|
* @async
|
|
210
272
|
* @function create
|
|
273
|
+
* @param {Object} cliOptions - Options passed from CLI flags
|
|
211
274
|
* @returns {Promise<void>}
|
|
212
275
|
*/
|
|
213
|
-
export const create = async () => {
|
|
276
|
+
export const create = async (cliOptions = {}) => {
|
|
277
|
+
// Validate CLI options
|
|
278
|
+
if (cliOptions.type) {
|
|
279
|
+
const validTypes = ['class', 'page', 'template'];
|
|
280
|
+
if (!validTypes.includes(cliOptions.type.toLowerCase())) {
|
|
281
|
+
throw new Error(`Invalid --type: "${cliOptions.type}". Valid options are: ${validTypes.join(', ')}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (cliOptions.classType) {
|
|
286
|
+
const validClassTypes = ['controller', 'utility', 'class', 'trigger'];
|
|
287
|
+
if (!validClassTypes.includes(cliOptions.classType.toLowerCase())) {
|
|
288
|
+
throw new Error(`Invalid --class-type: "${cliOptions.classType}". Valid options are: ${validClassTypes.join(', ')}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Ensure --class-type is only used with --type class
|
|
292
|
+
if (cliOptions.type && cliOptions.type.toLowerCase() !== 'class') {
|
|
293
|
+
throw new Error('--class-type can only be used with --type class');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (cliOptions.entityId) {
|
|
298
|
+
// Ensure --entity-id is only used with triggers
|
|
299
|
+
if (cliOptions.classType && cliOptions.classType.toLowerCase() !== 'trigger') {
|
|
300
|
+
throw new Error('--entity-id can only be used with --class-type trigger');
|
|
301
|
+
}
|
|
302
|
+
if (!cliOptions.classType) {
|
|
303
|
+
console.log(chalk.yellow('⚠️ Warning: --entity-id provided without --class-type trigger. It will be ignored unless you select Trigger interactively.'));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
214
307
|
// Clear the terminal
|
|
215
308
|
process.stdout.write('\x1Bc');
|
|
216
309
|
|
|
@@ -219,21 +312,44 @@ export const create = async () => {
|
|
|
219
312
|
return await ensureValidCredentials();
|
|
220
313
|
});
|
|
221
314
|
|
|
222
|
-
// 2.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
315
|
+
// 2. Determine entity type (from CLI or prompt)
|
|
316
|
+
let entityType;
|
|
317
|
+
let pageType;
|
|
318
|
+
|
|
319
|
+
if (cliOptions.type) {
|
|
320
|
+
const typeMap = {
|
|
321
|
+
'class': 'ActiveClass',
|
|
322
|
+
'page': 'ActivePage',
|
|
323
|
+
'template': 'ActivePage'
|
|
324
|
+
};
|
|
325
|
+
entityType = typeMap[cliOptions.type.toLowerCase()];
|
|
326
|
+
|
|
327
|
+
// If template was specified, set the pageType
|
|
328
|
+
if (cliOptions.type.toLowerCase() === 'template') {
|
|
329
|
+
pageType = 'Template';
|
|
330
|
+
} else if (cliOptions.type.toLowerCase() === 'page') {
|
|
331
|
+
pageType = 'Page';
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (!entityType) {
|
|
335
|
+
throw new Error(`Invalid type: ${cliOptions.type}. Valid types are: class, page, template`);
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
entityType = await select({
|
|
339
|
+
message: "What would you like to create?",
|
|
340
|
+
choices: [
|
|
341
|
+
{ name: "ActiveClass (Controller, Class, Trigger)", value: "ActiveClass" },
|
|
342
|
+
{ name: "ActivePage (ASPX Page)", value: "ActivePage" },
|
|
343
|
+
]
|
|
344
|
+
});
|
|
345
|
+
}
|
|
230
346
|
|
|
231
347
|
// 3. Build payload via relevant prompt flow
|
|
232
348
|
let result;
|
|
233
349
|
if (entityType === 'ActiveClass') {
|
|
234
|
-
result = await createActiveClass();
|
|
350
|
+
result = await createActiveClass(cliOptions);
|
|
235
351
|
} else if (entityType === 'ActivePage') {
|
|
236
|
-
result = await createActivePage();
|
|
352
|
+
result = await createActivePage({ ...cliOptions, pageType });
|
|
237
353
|
} else {
|
|
238
354
|
// Unknown
|
|
239
355
|
throw new Error("Unknown type selected.");
|
|
@@ -302,7 +418,7 @@ export const create = async () => {
|
|
|
302
418
|
const errors = creationResponse.errors || [];
|
|
303
419
|
|
|
304
420
|
if (errors.length > 0) {
|
|
305
|
-
errors.forEach((err
|
|
421
|
+
errors.forEach((err) => {
|
|
306
422
|
const code = err.code ? chalk.gray(`[${err.code}] `) : '';
|
|
307
423
|
const status = err.status ? chalk.yellow(`[${err.status}] `) : '';
|
|
308
424
|
const msg = chalk.whiteBright(err.message);
|