@tywalk/pcf-helper-run 1.5.0 → 1.7.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 +99 -0
- package/dist/index.js +176 -61
- package/dist/package.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ This package provides a single, consolidated command-line interface that brings
|
|
|
13
13
|
- [Quick Start](#-quick-start)
|
|
14
14
|
- [Command Structure](#️-command-structure)
|
|
15
15
|
- [Available Subcommands](#️-available-subcommands)
|
|
16
|
+
- [Profiles](#-profiles)
|
|
16
17
|
- [Usage Examples](#-detailed-command-reference)
|
|
17
18
|
- [Workflow Examples](#-workflow-examples)
|
|
18
19
|
- [Global Options](#️-global-options)
|
|
@@ -83,6 +84,104 @@ Each subcommand corresponds to a specific PCF operation, with consistent option
|
|
|
83
84
|
| `deploy` | Deploy to environment (upgrade + build + import) | `pcf-helper-deploy` |
|
|
84
85
|
| `upgrade` | Upgrade project dependencies | `pcf-helper-upgrade` |
|
|
85
86
|
| `session` | Manage development sessions | `pcf-helper-session` |
|
|
87
|
+
| `profile` | Inspect named profiles (`list`, `show`, `current`, `paths`) | `pcf-helper-profile` |
|
|
88
|
+
|
|
89
|
+
## 🧭 Profiles
|
|
90
|
+
|
|
91
|
+
Every command accepts `-P, --profile <name>` so you don't have to retype `--environment`, `--path`, `--publisher-name`, or `--publisher-prefix` on every run. Profiles are defined in a JSON config file that's merged from two places (project overrides global):
|
|
92
|
+
|
|
93
|
+
1. `~/.pcf-helper/config.json` — global defaults for this machine.
|
|
94
|
+
2. `./pcf-helper.config.json` — project-specific overrides.
|
|
95
|
+
|
|
96
|
+
Example config:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"defaultProfile": "dev",
|
|
101
|
+
"profiles": {
|
|
102
|
+
"dev": { "environment": "DevEnv", "publisherName": "Tyler W", "publisherPrefix": "tyw" },
|
|
103
|
+
"test": { "environment": "TestEnv" },
|
|
104
|
+
"prod": { "environment": "ProdEnv" }
|
|
105
|
+
},
|
|
106
|
+
"session": {
|
|
107
|
+
"remoteEnvironmentUrl": "https://org.crm.dynamics.com",
|
|
108
|
+
"localBundlePath": "out/controls/MyControl/bundle.js",
|
|
109
|
+
"startWatch": true
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Precedence (highest wins)
|
|
115
|
+
|
|
116
|
+
For `build`, `deploy`, `import`, `upgrade`, `init`:
|
|
117
|
+
1. Explicit CLI flags
|
|
118
|
+
2. Active profile (`--profile <name>` or `defaultProfile`)
|
|
119
|
+
3. Defaults
|
|
120
|
+
|
|
121
|
+
For `session`:
|
|
122
|
+
1. Explicit CLI flags
|
|
123
|
+
2. Environment variables
|
|
124
|
+
3. Active profile's `session` block
|
|
125
|
+
4. Top-level `session` block in `pcf-helper.config.json`
|
|
126
|
+
5. Legacy `session.config.json` (kept for backward compatibility)
|
|
127
|
+
6. Defaults
|
|
128
|
+
|
|
129
|
+
### Usage
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Use the default profile
|
|
133
|
+
pcf-helper-run deploy -p ./MySolution
|
|
134
|
+
|
|
135
|
+
# Pick a specific profile
|
|
136
|
+
pcf-helper-run deploy -p ./MySolution --profile prod
|
|
137
|
+
|
|
138
|
+
# CLI flags always win
|
|
139
|
+
pcf-helper-run deploy -p ./MySolution --profile prod --environment HotfixEnv
|
|
140
|
+
|
|
141
|
+
# Inspect what is configured
|
|
142
|
+
pcf-helper-run profile list
|
|
143
|
+
pcf-helper-run profile show prod
|
|
144
|
+
pcf-helper-run profile current
|
|
145
|
+
pcf-helper-run profile paths
|
|
146
|
+
|
|
147
|
+
# Create a profile without editing JSON (see below for the full flag list)
|
|
148
|
+
pcf-helper-run profile init dev \
|
|
149
|
+
--environment MyDevOrg \
|
|
150
|
+
--publisher-name "Tyler W" \
|
|
151
|
+
--publisher-prefix tyw \
|
|
152
|
+
--path ./MySolution \
|
|
153
|
+
--set-default \
|
|
154
|
+
--no-interactive
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Creating a profile from the CLI
|
|
158
|
+
|
|
159
|
+
`profile init <name>` creates or updates a profile without hand-editing
|
|
160
|
+
`pcf-helper.config.json`. Project-level by default; pass `--global` to write to
|
|
161
|
+
`~/.pcf-helper/config.json` (parent directory is created on first use).
|
|
162
|
+
|
|
163
|
+
Interactive by default — each missing field prompts at the terminal, pre-filled
|
|
164
|
+
with whatever you passed as a flag. Pass `--no-interactive` to skip the prompts
|
|
165
|
+
entirely and write only what was supplied.
|
|
166
|
+
|
|
167
|
+
| Flag | Description |
|
|
168
|
+
|------|-------------|
|
|
169
|
+
| `-e, --environment <env>` | Dataverse environment name |
|
|
170
|
+
| `--publisher-name <name>` | Publisher display name |
|
|
171
|
+
| `--publisher-prefix <prefix>` | Publisher prefix (2-8 chars) |
|
|
172
|
+
| `-p, --path <path>` | Path to PCF solution folder |
|
|
173
|
+
| `--template <template>` | `field` or `dataset` |
|
|
174
|
+
| `--framework <framework>` | `none` or `react` |
|
|
175
|
+
| `--session-url <url>` | Session: remote environment URL |
|
|
176
|
+
| `--session-script <path>` | Session: remote script to intercept |
|
|
177
|
+
| `--session-bundle <path>` | Session: local bundle path |
|
|
178
|
+
| `-g, --global` | Write to `~/.pcf-helper/config.json` |
|
|
179
|
+
| `-d, --set-default` | Also set `defaultProfile: <name>` |
|
|
180
|
+
| `-f, --force` | Overwrite an existing profile of the same name |
|
|
181
|
+
| `--no-interactive` | Skip prompts; only use passed flags |
|
|
182
|
+
|
|
183
|
+
The write is atomic (temp file + rename), so an interrupted run never corrupts
|
|
184
|
+
your config.
|
|
86
185
|
|
|
87
186
|
## 📖 Detailed Command Reference
|
|
88
187
|
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
46
|
const commander_1 = require("commander");
|
|
47
47
|
const tasks = __importStar(require("@tywalk/pcf-helper"));
|
|
48
|
+
const pcf_helper_1 = require("@tywalk/pcf-helper");
|
|
48
49
|
const color_logger_1 = require("@tywalk/color-logger");
|
|
49
50
|
const package_json_1 = require("./package.json");
|
|
50
51
|
const performanceUtil_1 = require("./util/performanceUtil");
|
|
@@ -61,7 +62,7 @@ const preprocessArgs = (args) => {
|
|
|
61
62
|
}
|
|
62
63
|
return { args: processed, hadDeprecatedEnv };
|
|
63
64
|
};
|
|
64
|
-
// Preprocess arguments and track if deprecated flags were used
|
|
65
|
+
// Preprocess arguments and track if deprecated flags were used
|
|
65
66
|
const { args: processedArgs, hadDeprecatedEnv } = preprocessArgs(process.argv.slice(2));
|
|
66
67
|
process.argv = [...process.argv.slice(0, 2), ...processedArgs];
|
|
67
68
|
const parseWatchRetry = (value) => {
|
|
@@ -93,7 +94,8 @@ const withCommonOptions = (command) => {
|
|
|
93
94
|
throw new Error('Timeout must be a positive number');
|
|
94
95
|
}
|
|
95
96
|
return value;
|
|
96
|
-
})
|
|
97
|
+
})
|
|
98
|
+
.option('-P, --profile <name>', 'named profile from pcf-helper.config.json to use for defaults');
|
|
97
99
|
};
|
|
98
100
|
const withPathOptions = (command) => {
|
|
99
101
|
return withCommonOptions(command)
|
|
@@ -103,18 +105,16 @@ const withPathOptions = (command) => {
|
|
|
103
105
|
};
|
|
104
106
|
// Helper function to resolve environment value with deprecation warning
|
|
105
107
|
const resolveEnvironment = (options, logger) => {
|
|
106
|
-
// Check if deprecated --env flag was used
|
|
107
108
|
if (options.env && options.environment) {
|
|
108
|
-
logger.warn('
|
|
109
|
+
logger.warn('WARN: Both --env (deprecated) and --environment flags provided. Using --environment value.');
|
|
109
110
|
return options.environment;
|
|
110
111
|
}
|
|
111
112
|
else if (options.env) {
|
|
112
|
-
// Show deprecation warning using the proper logger
|
|
113
113
|
if (hadDeprecatedEnv) {
|
|
114
|
-
logger.warn('
|
|
114
|
+
logger.warn('WARN: The -env flag is DEPRECATED. Please use -e or --environment instead.');
|
|
115
115
|
}
|
|
116
116
|
else {
|
|
117
|
-
logger.warn('
|
|
117
|
+
logger.warn('WARN: The --env flag is DEPRECATED. Please use -e or --environment instead.');
|
|
118
118
|
}
|
|
119
119
|
return options.env;
|
|
120
120
|
}
|
|
@@ -122,6 +122,15 @@ const resolveEnvironment = (options, logger) => {
|
|
|
122
122
|
return options.environment || '';
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
+
// Loads a profile (if any) and logs which one is in use.
|
|
126
|
+
const loadProfile = (profileName, logger) => {
|
|
127
|
+
const { merged } = (0, pcf_helper_1.loadPcfHelperConfig)();
|
|
128
|
+
const { name, profile } = (0, pcf_helper_1.resolveProfile)(profileName, merged);
|
|
129
|
+
if (name) {
|
|
130
|
+
logger.log(`Using profile "${name}" from pcf-helper config.`);
|
|
131
|
+
}
|
|
132
|
+
return profile;
|
|
133
|
+
};
|
|
125
134
|
// Helper function to setup logger and performance tracking
|
|
126
135
|
const setupExecutionContext = (options) => {
|
|
127
136
|
const logger = new color_logger_1.Logger('log');
|
|
@@ -151,19 +160,22 @@ const handleResults = (taskName, logger, tick, result) => {
|
|
|
151
160
|
process.exit(result);
|
|
152
161
|
}
|
|
153
162
|
};
|
|
154
|
-
//
|
|
163
|
+
// upgrade
|
|
155
164
|
withPathOptions(commander_1.program.command('upgrade'))
|
|
156
165
|
.description('upgrade PCF controls')
|
|
157
166
|
.action((options) => {
|
|
167
|
+
var _a, _b;
|
|
158
168
|
const { logger, tick } = setupExecutionContext(options);
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
const profile = loadProfile(options.profile, logger);
|
|
170
|
+
const resolvedPath = (_b = (_a = options.path) !== null && _a !== void 0 ? _a : profile === null || profile === void 0 ? void 0 : profile.path) !== null && _b !== void 0 ? _b : '';
|
|
171
|
+
if (!resolvedPath) {
|
|
172
|
+
logger.error('Path argument is required. Use --path or set `path` in the active profile.');
|
|
161
173
|
process.exit(1);
|
|
162
174
|
}
|
|
163
175
|
let result = 0;
|
|
164
176
|
try {
|
|
165
177
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' upgrade started.\n');
|
|
166
|
-
result = tasks.runUpgrade(
|
|
178
|
+
result = tasks.runUpgrade(resolvedPath, options.verbose || false);
|
|
167
179
|
}
|
|
168
180
|
catch (e) {
|
|
169
181
|
logger.error('[PCF Helper Run] One or more tasks failed while upgrading: ', e instanceof Error ? e.message : 'unknown error');
|
|
@@ -171,19 +183,22 @@ withPathOptions(commander_1.program.command('upgrade'))
|
|
|
171
183
|
}
|
|
172
184
|
handleResults('upgrade', logger, tick, result);
|
|
173
185
|
});
|
|
174
|
-
//
|
|
186
|
+
// build
|
|
175
187
|
withPathOptions(commander_1.program.command('build'))
|
|
176
188
|
.description('build PCF controls')
|
|
177
189
|
.action((options) => {
|
|
190
|
+
var _a, _b;
|
|
178
191
|
const { logger, tick } = setupExecutionContext(options);
|
|
179
|
-
|
|
180
|
-
|
|
192
|
+
const profile = loadProfile(options.profile, logger);
|
|
193
|
+
const resolvedPath = (_b = (_a = options.path) !== null && _a !== void 0 ? _a : profile === null || profile === void 0 ? void 0 : profile.path) !== null && _b !== void 0 ? _b : '';
|
|
194
|
+
if (!resolvedPath) {
|
|
195
|
+
logger.error('Path argument is required. Use --path or set `path` in the active profile.');
|
|
181
196
|
process.exit(1);
|
|
182
197
|
}
|
|
183
198
|
let result = 0;
|
|
184
199
|
try {
|
|
185
200
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' build started.\n');
|
|
186
|
-
result = tasks.runBuild(
|
|
201
|
+
result = tasks.runBuild(resolvedPath, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
187
202
|
}
|
|
188
203
|
catch (e) {
|
|
189
204
|
logger.error('[PCF Helper Run] One or more tasks failed while building: ', e instanceof Error ? e.message : 'unknown error');
|
|
@@ -191,23 +206,27 @@ withPathOptions(commander_1.program.command('build'))
|
|
|
191
206
|
}
|
|
192
207
|
handleResults('build', logger, tick, result);
|
|
193
208
|
});
|
|
194
|
-
//
|
|
209
|
+
// import
|
|
195
210
|
withPathOptions(commander_1.program.command('import'))
|
|
196
211
|
.description('import PCF controls')
|
|
197
212
|
.action((options) => {
|
|
213
|
+
var _a, _b, _c;
|
|
198
214
|
const { logger, tick } = setupExecutionContext(options);
|
|
199
|
-
|
|
200
|
-
|
|
215
|
+
const profile = loadProfile(options.profile, logger);
|
|
216
|
+
const resolvedPath = (_b = (_a = options.path) !== null && _a !== void 0 ? _a : profile === null || profile === void 0 ? void 0 : profile.path) !== null && _b !== void 0 ? _b : '';
|
|
217
|
+
if (!resolvedPath) {
|
|
218
|
+
logger.error('Path argument is required. Use --path or set `path` in the active profile.');
|
|
201
219
|
process.exit(1);
|
|
202
220
|
}
|
|
203
|
-
const
|
|
221
|
+
const explicitEnv = resolveEnvironment(options, logger);
|
|
222
|
+
const env = explicitEnv !== '' ? explicitEnv : (_c = profile === null || profile === void 0 ? void 0 : profile.environment) !== null && _c !== void 0 ? _c : '';
|
|
204
223
|
if (env === '') {
|
|
205
224
|
logger.warn('No environment specified. Defaulting to "local".');
|
|
206
225
|
}
|
|
207
226
|
let result = 0;
|
|
208
227
|
try {
|
|
209
228
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' import started.\n');
|
|
210
|
-
result = tasks.runImport(
|
|
229
|
+
result = tasks.runImport(resolvedPath, env, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
211
230
|
}
|
|
212
231
|
catch (e) {
|
|
213
232
|
logger.error('[PCF Helper Run] One or more tasks failed while importing: ', e instanceof Error ? e.message : 'unknown error');
|
|
@@ -215,36 +234,37 @@ withPathOptions(commander_1.program.command('import'))
|
|
|
215
234
|
}
|
|
216
235
|
handleResults('import', logger, tick, result);
|
|
217
236
|
});
|
|
218
|
-
//
|
|
237
|
+
// deploy
|
|
219
238
|
withPathOptions(commander_1.program.command('deploy'))
|
|
220
239
|
.description('deploy PCF controls (runs upgrade, build, and import)')
|
|
221
240
|
.action((options) => {
|
|
241
|
+
var _a, _b, _c;
|
|
222
242
|
const { logger, tick } = setupExecutionContext(options);
|
|
223
|
-
|
|
224
|
-
|
|
243
|
+
const profile = loadProfile(options.profile, logger);
|
|
244
|
+
const resolvedPath = (_b = (_a = options.path) !== null && _a !== void 0 ? _a : profile === null || profile === void 0 ? void 0 : profile.path) !== null && _b !== void 0 ? _b : '';
|
|
245
|
+
if (!resolvedPath) {
|
|
246
|
+
logger.error('Path argument is required. Use --path or set `path` in the active profile.');
|
|
225
247
|
process.exit(1);
|
|
226
248
|
}
|
|
227
|
-
const
|
|
249
|
+
const explicitEnv = resolveEnvironment(options, logger);
|
|
250
|
+
const env = explicitEnv !== '' ? explicitEnv : (_c = profile === null || profile === void 0 ? void 0 : profile.environment) !== null && _c !== void 0 ? _c : '';
|
|
228
251
|
if (env === '') {
|
|
229
252
|
logger.warn('No environment specified. Defaulting to "local".');
|
|
230
253
|
}
|
|
231
254
|
let result = 0;
|
|
232
255
|
try {
|
|
233
256
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' deploy started.\n');
|
|
234
|
-
|
|
235
|
-
const upgradeResult = tasks.runUpgrade(options.path, options.verbose || false);
|
|
257
|
+
const upgradeResult = tasks.runUpgrade(resolvedPath, options.verbose || false);
|
|
236
258
|
if (upgradeResult === 1) {
|
|
237
259
|
result = 1;
|
|
238
260
|
}
|
|
239
261
|
else {
|
|
240
|
-
|
|
241
|
-
const buildResult = tasks.runBuild(options.path, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
262
|
+
const buildResult = tasks.runBuild(resolvedPath, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
242
263
|
if (buildResult === 1) {
|
|
243
264
|
result = 1;
|
|
244
265
|
}
|
|
245
266
|
else {
|
|
246
|
-
|
|
247
|
-
const importResult = tasks.runImport(options.path, env, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
267
|
+
const importResult = tasks.runImport(resolvedPath, env, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
248
268
|
if (importResult === 1) {
|
|
249
269
|
result = 1;
|
|
250
270
|
}
|
|
@@ -257,22 +277,25 @@ withPathOptions(commander_1.program.command('deploy'))
|
|
|
257
277
|
}
|
|
258
278
|
handleResults('deploy', logger, tick, result);
|
|
259
279
|
});
|
|
260
|
-
//
|
|
280
|
+
// init
|
|
261
281
|
withVerboseOption(commander_1.program.command('init'))
|
|
262
282
|
.description('initialize a new PCF project')
|
|
263
|
-
.requiredOption('-p, --path <path>', 'path to PCF folder')
|
|
264
283
|
.requiredOption('-n, --name <name>', 'name of the control')
|
|
265
|
-
.
|
|
266
|
-
.
|
|
267
|
-
.option('-
|
|
268
|
-
.option('-
|
|
284
|
+
.option('-p, --path <path>', 'path to PCF folder')
|
|
285
|
+
.option('--publisher-name <publisherName>', 'publisher name')
|
|
286
|
+
.option('--publisher-prefix <publisherPrefix>', 'publisher prefix')
|
|
287
|
+
.option('-t, --template <template>', 'template for the component (field|dataset)')
|
|
288
|
+
.option('-f, --framework <framework>', 'rendering framework for control (none|react)')
|
|
269
289
|
.option('--run-npm-install', 'run npm install after initialization', true)
|
|
290
|
+
.option('-P, --profile <name>', 'named profile from pcf-helper.config.json to use for defaults')
|
|
270
291
|
.action((options) => {
|
|
292
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
271
293
|
const { logger, tick } = setupExecutionContext(options);
|
|
294
|
+
const profile = loadProfile(options.profile, logger);
|
|
272
295
|
let result = 0;
|
|
273
296
|
try {
|
|
274
297
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' init started.\n');
|
|
275
|
-
result = tasks.runInit(options.path, options.name, options.publisherName, options.publisherPrefix, options.template || 'field', options.framework || 'react', options.runNpmInstall !== false, options.verbose || false);
|
|
298
|
+
result = tasks.runInit((_b = (_a = options.path) !== null && _a !== void 0 ? _a : profile === null || profile === void 0 ? void 0 : profile.path) !== null && _b !== void 0 ? _b : '', options.name, (_d = (_c = options.publisherName) !== null && _c !== void 0 ? _c : profile === null || profile === void 0 ? void 0 : profile.publisherName) !== null && _d !== void 0 ? _d : '', (_f = (_e = options.publisherPrefix) !== null && _e !== void 0 ? _e : profile === null || profile === void 0 ? void 0 : profile.publisherPrefix) !== null && _f !== void 0 ? _f : '', (_h = (_g = options.template) !== null && _g !== void 0 ? _g : profile === null || profile === void 0 ? void 0 : profile.template) !== null && _h !== void 0 ? _h : 'field', (_k = (_j = options.framework) !== null && _j !== void 0 ? _j : profile === null || profile === void 0 ? void 0 : profile.framework) !== null && _k !== void 0 ? _k : 'react', options.runNpmInstall !== false, options.verbose || false);
|
|
276
299
|
}
|
|
277
300
|
catch (e) {
|
|
278
301
|
logger.error('[PCF Helper Run] One or more tasks failed while initializing: ', e instanceof Error ? e.message : 'unknown error');
|
|
@@ -280,7 +303,7 @@ withVerboseOption(commander_1.program.command('init'))
|
|
|
280
303
|
}
|
|
281
304
|
handleResults('init', logger, tick, result);
|
|
282
305
|
});
|
|
283
|
-
//
|
|
306
|
+
// session
|
|
284
307
|
withCommonOptions(commander_1.program.command('session'))
|
|
285
308
|
.description('run development session')
|
|
286
309
|
.option('-u, --url <url>', 'remote environment URL')
|
|
@@ -292,31 +315,20 @@ withCommonOptions(commander_1.program.command('session'))
|
|
|
292
315
|
.option('-w, --watch', 'start pcf-scripts watch process')
|
|
293
316
|
.option('--watch-retry <enabled>', 'automatically retry watch process on failure (true|false)', parseWatchRetry)
|
|
294
317
|
.action((options, command) => __awaiter(void 0, void 0, void 0, function* () {
|
|
295
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j
|
|
318
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
296
319
|
const { logger, tick } = setupExecutionContext(options);
|
|
297
320
|
try {
|
|
298
321
|
logger.log('[PCF Helper Run] ' + (0, performanceUtil_1.formatTime)(new Date()) + ' session started.\n');
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
process.exit(1);
|
|
307
|
-
}
|
|
308
|
-
const watchRetry = (_d = (_c = options.watchRetry) !== null && _c !== void 0 ? _c : configWithWatchRetry.watchRetry) !== null && _d !== void 0 ? _d : true;
|
|
309
|
-
// Use the config values from the config file, falling back to the CLI options if the config values are not set
|
|
310
|
-
yield tasks.runSession((_e = config.remoteEnvironmentUrl) !== null && _e !== void 0 ? _e : options.url, (_f = config.remoteScriptToIntercept) !== null && _f !== void 0 ? _f : options.script, (_g = config.remoteStylesheetToIntercept) !== null && _g !== void 0 ? _g : options.stylesheet, (_h = config.localBundlePath) !== null && _h !== void 0 ? _h : options.bundle, (_j = config.localCssPath) !== null && _j !== void 0 ? _j : options.css, startWatch, watchRetry);
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
const watchRetryFlagWasSet = command.getOptionValueSource('watchRetry') === 'cli';
|
|
314
|
-
if (watchRetryFlagWasSet && !options.watch) {
|
|
315
|
-
logger.error('❌ --watch-retry can only be used when --watch is enabled.');
|
|
316
|
-
process.exit(1);
|
|
317
|
-
}
|
|
318
|
-
yield tasks.runSession(options.url, options.script, options.stylesheet, options.bundle, options.css, options.watch, (_k = options.watchRetry) !== null && _k !== void 0 ? _k : true);
|
|
322
|
+
const config = tasks.loadConfig(options.config, options.profile);
|
|
323
|
+
const configWithWatchRetry = config;
|
|
324
|
+
const startWatch = (_b = (_a = options.watch) !== null && _a !== void 0 ? _a : config.startWatch) !== null && _b !== void 0 ? _b : false;
|
|
325
|
+
const watchRetryFlagWasSet = command.getOptionValueSource('watchRetry') === 'cli';
|
|
326
|
+
if (watchRetryFlagWasSet && !startWatch) {
|
|
327
|
+
logger.error('Error: --watch-retry can only be used when --watch is enabled.');
|
|
328
|
+
process.exit(1);
|
|
319
329
|
}
|
|
330
|
+
const watchRetry = (_d = (_c = options.watchRetry) !== null && _c !== void 0 ? _c : configWithWatchRetry.watchRetry) !== null && _d !== void 0 ? _d : true;
|
|
331
|
+
yield tasks.runSession((_e = options.url) !== null && _e !== void 0 ? _e : config.remoteEnvironmentUrl, (_f = options.script) !== null && _f !== void 0 ? _f : config.remoteScriptToIntercept, (_g = options.stylesheet) !== null && _g !== void 0 ? _g : config.remoteStylesheetToIntercept, (_h = options.bundle) !== null && _h !== void 0 ? _h : config.localBundlePath, (_j = options.css) !== null && _j !== void 0 ? _j : config.localCssPath, startWatch, watchRetry);
|
|
320
332
|
const tock = performance.now();
|
|
321
333
|
logger.log((0, performanceUtil_1.formatMsToSec)('Session started successfully in %is.', tock - tick));
|
|
322
334
|
}
|
|
@@ -324,5 +336,108 @@ withCommonOptions(commander_1.program.command('session'))
|
|
|
324
336
|
logger.error('[PCF Helper Run] One or more tasks failed during session or session startup: ', e instanceof Error ? e.message : 'unknown error');
|
|
325
337
|
}
|
|
326
338
|
}));
|
|
327
|
-
//
|
|
328
|
-
commander_1.program.
|
|
339
|
+
// profile subcommand
|
|
340
|
+
const profileCmd = commander_1.program.command('profile').description('inspect pcf-helper profiles from pcf-helper.config.json');
|
|
341
|
+
profileCmd
|
|
342
|
+
.command('list')
|
|
343
|
+
.description('list all available profile names')
|
|
344
|
+
.action(() => {
|
|
345
|
+
var _a;
|
|
346
|
+
const { merged, sources } = (0, pcf_helper_1.loadPcfHelperConfig)();
|
|
347
|
+
const names = Object.keys((_a = merged.profiles) !== null && _a !== void 0 ? _a : {});
|
|
348
|
+
const isDefault = (n) => (merged.defaultProfile === n ? ' (default)' : '');
|
|
349
|
+
if (sources.length === 0) {
|
|
350
|
+
console.log('No pcf-helper config files found.');
|
|
351
|
+
console.log('Looked at:');
|
|
352
|
+
console.log(' - global: ~/.pcf-helper/config.json');
|
|
353
|
+
console.log(' - project: ./pcf-helper.config.json');
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
console.log('Loaded config from:');
|
|
357
|
+
for (const s of sources)
|
|
358
|
+
console.log(` - ${s}`);
|
|
359
|
+
if (names.length === 0) {
|
|
360
|
+
console.log('\nNo profiles defined.');
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
console.log('\nProfiles:');
|
|
364
|
+
for (const n of names)
|
|
365
|
+
console.log(` - ${n}${isDefault(n)}`);
|
|
366
|
+
});
|
|
367
|
+
profileCmd
|
|
368
|
+
.command('show <name>')
|
|
369
|
+
.description('print the resolved contents of a profile')
|
|
370
|
+
.action((name) => {
|
|
371
|
+
var _a, _b;
|
|
372
|
+
const { merged } = (0, pcf_helper_1.loadPcfHelperConfig)();
|
|
373
|
+
const profile = (_a = merged.profiles) === null || _a === void 0 ? void 0 : _a[name];
|
|
374
|
+
if (!profile) {
|
|
375
|
+
const available = Object.keys((_b = merged.profiles) !== null && _b !== void 0 ? _b : {});
|
|
376
|
+
console.error(`Profile "${name}" not found. Available: ${available.join(', ') || '(none)'}`);
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
console.log(JSON.stringify(profile, null, 2));
|
|
380
|
+
});
|
|
381
|
+
profileCmd
|
|
382
|
+
.command('current')
|
|
383
|
+
.description('print the profile that would be used by default')
|
|
384
|
+
.action(() => {
|
|
385
|
+
const { merged } = (0, pcf_helper_1.loadPcfHelperConfig)();
|
|
386
|
+
if (!merged.defaultProfile) {
|
|
387
|
+
console.log('No defaultProfile set.');
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
console.log(merged.defaultProfile);
|
|
391
|
+
});
|
|
392
|
+
profileCmd
|
|
393
|
+
.command('paths')
|
|
394
|
+
.description('print the global and project config paths')
|
|
395
|
+
.action(() => {
|
|
396
|
+
const { projectPath, globalPath, sources } = (0, pcf_helper_1.loadPcfHelperConfig)();
|
|
397
|
+
console.log(`global: ${globalPath}`);
|
|
398
|
+
console.log(`project: ${projectPath}`);
|
|
399
|
+
console.log(`loaded: ${sources.length ? sources.join(', ') : '(none)'}`);
|
|
400
|
+
});
|
|
401
|
+
profileCmd
|
|
402
|
+
.command('init <name>')
|
|
403
|
+
.description('create a new profile in pcf-helper.config.json (project or global)')
|
|
404
|
+
.option('-e, --environment <env>', 'Dataverse environment name')
|
|
405
|
+
.option('--publisher-name <name>', 'publisher display name')
|
|
406
|
+
.option('--publisher-prefix <prefix>', 'publisher prefix (2-8 chars)')
|
|
407
|
+
.option('-p, --path <path>', 'path to PCF solution folder')
|
|
408
|
+
.option('--template <template>', 'control template (field|dataset)')
|
|
409
|
+
.option('--framework <framework>', 'rendering framework (none|react)')
|
|
410
|
+
.option('--session-url <url>', 'session: remote environment URL')
|
|
411
|
+
.option('--session-script <path>', 'session: remote script to intercept')
|
|
412
|
+
.option('--session-bundle <path>', 'session: local bundle path')
|
|
413
|
+
.option('-g, --global', 'write to ~/.pcf-helper/config.json instead of project-level')
|
|
414
|
+
.option('-d, --set-default', 'set this profile as the defaultProfile')
|
|
415
|
+
.option('-f, --force', 'overwrite an existing profile of the same name')
|
|
416
|
+
.option('--no-interactive', 'skip prompts for missing fields')
|
|
417
|
+
.action((name, flags) => __awaiter(void 0, void 0, void 0, function* () {
|
|
418
|
+
const options = {
|
|
419
|
+
name,
|
|
420
|
+
environment: flags.environment,
|
|
421
|
+
publisherName: flags.publisherName,
|
|
422
|
+
publisherPrefix: flags.publisherPrefix,
|
|
423
|
+
path: flags.path,
|
|
424
|
+
template: flags.template,
|
|
425
|
+
framework: flags.framework,
|
|
426
|
+
sessionUrl: flags.sessionUrl,
|
|
427
|
+
sessionScript: flags.sessionScript,
|
|
428
|
+
sessionBundle: flags.sessionBundle,
|
|
429
|
+
global: !!flags.global,
|
|
430
|
+
setDefault: !!flags.setDefault,
|
|
431
|
+
force: !!flags.force,
|
|
432
|
+
nonInteractive: flags.interactive === false,
|
|
433
|
+
};
|
|
434
|
+
try {
|
|
435
|
+
yield (0, pcf_helper_1.runProfileInit)(options);
|
|
436
|
+
}
|
|
437
|
+
catch (e) {
|
|
438
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
439
|
+
console.error(`Error: ${message}`);
|
|
440
|
+
process.exit(1);
|
|
441
|
+
}
|
|
442
|
+
}));
|
|
443
|
+
commander_1.program.parseAsync();
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tywalk/pcf-helper-run",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Unified CLI interface for Power Platform Component Framework (PCF) development — init, build, import, deploy, and manage PCF controls in Dataverse.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./types/",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@tywalk/color-logger": "^1.0.3",
|
|
55
|
-
"@tywalk/pcf-helper": "^1.
|
|
55
|
+
"@tywalk/pcf-helper": "^1.16.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@semantic-release/git": "^10.0.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tywalk/pcf-helper-run",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Unified CLI interface for Power Platform Component Framework (PCF) development — init, build, import, deploy, and manage PCF controls in Dataverse.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./types/",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@tywalk/color-logger": "^1.0.3",
|
|
55
|
-
"@tywalk/pcf-helper": "^1.
|
|
55
|
+
"@tywalk/pcf-helper": "^1.16.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@semantic-release/git": "^10.0.1",
|