@tywalk/pcf-helper 1.4.24 → 1.5.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 +6 -0
- package/dist/__tests__/pcf-helper-build.test.js +1 -1
- package/dist/__tests__/pcf-helper-deploy.test.js +1 -1
- package/dist/__tests__/pcf-helper-import.test.js +1 -1
- package/dist/__tests__/pcf-helper-init.test.js +1 -1
- package/dist/__tests__/pcf-helper-session.test.js +32 -0
- package/dist/__tests__/pcf-helper-upgrade.test.js +1 -1
- package/dist/bin/build.js +18 -23
- package/dist/bin/deploy.js +16 -27
- package/dist/bin/import.js +13 -26
- package/dist/bin/init.js +16 -20
- package/dist/bin/session.js +64 -0
- package/dist/bin/upgrade.js +12 -16
- package/dist/package.json +6 -3
- package/dist/tasks/index.js +1 -0
- package/dist/tasks/session-pcf.js +236 -0
- package/dist/util/argumentUtil.js +97 -0
- package/package.json +6 -3
- package/types/__tests__/pcf-helper-session.test.d.ts +1 -0
- package/types/bin/session.d.ts +2 -0
- package/types/tasks/index.d.ts +1 -0
- package/types/tasks/session-pcf.d.ts +9 -0
- package/types/util/argumentUtil.d.ts +44 -0
package/README.md
CHANGED
|
@@ -25,3 +25,9 @@ This tool requires the following:
|
|
|
25
25
|
"init": "pcf-helper-init --path <path to pcf project folder (optional)> --name <name of the pcf project> --publisher-name <powerapps publisher name> --publisher-prefix <powerapps publisher prefix>"
|
|
26
26
|
},
|
|
27
27
|
```
|
|
28
|
+
|
|
29
|
+
## Contributing
|
|
30
|
+
|
|
31
|
+
### Deployment
|
|
32
|
+
|
|
33
|
+
|
|
@@ -13,7 +13,7 @@ test('build displays version', (done) => {
|
|
|
13
13
|
});
|
|
14
14
|
task.on('close', (code) => {
|
|
15
15
|
console.log(output);
|
|
16
|
-
expect(output).toContain(package_json_1.version);
|
|
16
|
+
expect(output).toContain(`v${package_json_1.version}`);
|
|
17
17
|
expect(code).toBe(0);
|
|
18
18
|
done();
|
|
19
19
|
});
|
|
@@ -13,7 +13,7 @@ test('deploy displays version', (done) => {
|
|
|
13
13
|
});
|
|
14
14
|
task.on('close', (code) => {
|
|
15
15
|
console.log(output);
|
|
16
|
-
expect(output).toContain(package_json_1.version);
|
|
16
|
+
expect(output).toContain(`v${package_json_1.version}`);
|
|
17
17
|
expect(code).toBe(0);
|
|
18
18
|
done();
|
|
19
19
|
});
|
|
@@ -10,7 +10,7 @@ test('import displays version', (done) => {
|
|
|
10
10
|
});
|
|
11
11
|
task.on('close', (code) => {
|
|
12
12
|
console.log(output);
|
|
13
|
-
expect(output).toContain(package_json_1.version);
|
|
13
|
+
expect(output).toContain(`v${package_json_1.version}`);
|
|
14
14
|
expect(code).toBe(0);
|
|
15
15
|
done();
|
|
16
16
|
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const child_process_1 = require("child_process");
|
|
4
|
+
const package_json_1 = require("../package.json");
|
|
5
|
+
test('session displays version', (done) => {
|
|
6
|
+
const task = (0, child_process_1.spawn)('node', ['./dist/bin/session.js', '-v']);
|
|
7
|
+
let output = '';
|
|
8
|
+
task.stdout.on('data', (data) => {
|
|
9
|
+
output += data.toString();
|
|
10
|
+
});
|
|
11
|
+
task.on('close', (code) => {
|
|
12
|
+
console.log(output);
|
|
13
|
+
expect(output).toContain(`v${package_json_1.version}`);
|
|
14
|
+
expect(code).toBe(0);
|
|
15
|
+
done();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
test('session errors if no args are provided', (done) => {
|
|
19
|
+
const task = (0, child_process_1.spawn)('node', ['./dist/bin/session.js', '-e']);
|
|
20
|
+
let output = '';
|
|
21
|
+
task.stdout.on('data', (data) => {
|
|
22
|
+
output += data.toString();
|
|
23
|
+
});
|
|
24
|
+
task.stderr.on('data', (data) => {
|
|
25
|
+
console.error(`stderr: ${data}`);
|
|
26
|
+
});
|
|
27
|
+
task.on('close', (code) => {
|
|
28
|
+
console.log(output);
|
|
29
|
+
expect(code).toBe(1);
|
|
30
|
+
done();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -10,7 +10,7 @@ test('upgrade displays version', (done) => {
|
|
|
10
10
|
});
|
|
11
11
|
task.on('close', (code) => {
|
|
12
12
|
console.log(output);
|
|
13
|
-
expect(output).toContain(package_json_1.version);
|
|
13
|
+
expect(output).toContain(`v${package_json_1.version}`);
|
|
14
14
|
expect(code).toBe(0);
|
|
15
15
|
done();
|
|
16
16
|
});
|
package/dist/bin/build.js
CHANGED
|
@@ -36,34 +36,29 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _a, _b;
|
|
40
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
40
|
const task = __importStar(require("../tasks/build-pcf"));
|
|
42
41
|
const package_json_1 = require("../package.json");
|
|
43
42
|
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
color_logger_1.default.error('Timeout argument must be a positive number representing milliseconds.');
|
|
56
|
-
process.exit(1);
|
|
43
|
+
const commander_1 = require("commander");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('pcf-helper-build')
|
|
47
|
+
.description('Build PCF controls')
|
|
48
|
+
.version(package_json_1.version, '-v, --version')
|
|
49
|
+
.option('-V, --verbose', 'enable verbose logging')
|
|
50
|
+
.option('-t, --timeout <milliseconds>', 'timeout in milliseconds', (value) => {
|
|
51
|
+
const num = Number(value);
|
|
52
|
+
if (isNaN(num) || num <= 0) {
|
|
53
|
+
throw new Error('Timeout must be a positive number');
|
|
57
54
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
return value;
|
|
56
|
+
})
|
|
57
|
+
.requiredOption('-p, --path <path>', 'path to solution folder')
|
|
58
|
+
.parse();
|
|
59
|
+
const options = program.opts();
|
|
60
|
+
if (options.verbose) {
|
|
61
61
|
color_logger_1.default.setDebug(true);
|
|
62
62
|
}
|
|
63
63
|
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
64
|
-
|
|
65
|
-
if (typeof path === 'undefined') {
|
|
66
|
-
color_logger_1.default.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
67
|
-
process.exit(1);
|
|
68
|
-
}
|
|
69
|
-
task.runBuild(path, verboseArgument !== undefined, typeof timeout !== 'undefined' ? Number(timeout) : undefined);
|
|
64
|
+
task.runBuild(options.path, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
package/dist/bin/deploy.js
CHANGED
|
@@ -36,7 +36,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _a, _b, _c;
|
|
40
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
40
|
const upgradeTask = __importStar(require("../tasks/upgrade-pcf"));
|
|
42
41
|
const buildTask = __importStar(require("../tasks/build-pcf"));
|
|
@@ -44,39 +43,29 @@ const importTask = __importStar(require("../tasks/import-pcf"));
|
|
|
44
43
|
const performanceUtil_1 = require("../util/performanceUtil");
|
|
45
44
|
const package_json_1 = require("../package.json");
|
|
46
45
|
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
46
|
+
const commander_1 = require("commander");
|
|
47
47
|
const argumentUtil_1 = require("../util/argumentUtil");
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
// Apply argument preprocessing for backward compatibility
|
|
49
|
+
const { hadDeprecatedEnv } = (0, argumentUtil_1.applyArgumentPreprocessing)(process.argv);
|
|
50
|
+
const program = new commander_1.Command();
|
|
51
|
+
(0, argumentUtil_1.addPathAndEnvironmentOptions)(program)
|
|
52
|
+
.name('pcf-helper-deploy')
|
|
53
|
+
.description('Deploy PCF controls (runs upgrade, build, and import)')
|
|
54
|
+
.version(package_json_1.version, '-v, --version')
|
|
55
|
+
.parse();
|
|
56
|
+
const options = program.opts();
|
|
57
|
+
(0, argumentUtil_1.setupLogging)(options.verbose);
|
|
58
58
|
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
59
|
-
const
|
|
60
|
-
if (typeof pathArgument === 'undefined') {
|
|
61
|
-
color_logger_1.default.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
const pathIndex = args.indexOf(pathArgument) + 1;
|
|
65
|
-
const path = args.at(pathIndex);
|
|
66
|
-
if (typeof path === 'undefined') {
|
|
67
|
-
color_logger_1.default.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
59
|
+
const env = (0, argumentUtil_1.resolveEnvironment)(options, hadDeprecatedEnv);
|
|
70
60
|
const tick = performance.now();
|
|
71
|
-
const env = (_c = (0, argumentUtil_1.getArgValue)(args, ['-env', '--environment'])) !== null && _c !== void 0 ? _c : '';
|
|
72
61
|
function executeTasks() {
|
|
73
|
-
const upgradeResult = upgradeTask.runUpgrade(path,
|
|
62
|
+
const upgradeResult = upgradeTask.runUpgrade(options.path, options.verbose || false);
|
|
74
63
|
if (upgradeResult === 1)
|
|
75
64
|
return 1;
|
|
76
|
-
const buildResult = buildTask.runBuild(path,
|
|
65
|
+
const buildResult = buildTask.runBuild(options.path, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
77
66
|
if (buildResult === 1)
|
|
78
67
|
return 1;
|
|
79
|
-
const importResult = importTask.runImport(path, env,
|
|
68
|
+
const importResult = importTask.runImport(options.path, env, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
|
80
69
|
if (importResult === 1)
|
|
81
70
|
return 1;
|
|
82
71
|
return 0;
|
|
@@ -89,7 +78,7 @@ try {
|
|
|
89
78
|
}
|
|
90
79
|
}
|
|
91
80
|
catch (e) {
|
|
92
|
-
color_logger_1.default.error('One or more tasks failed while deploying: ', (e && e.message) || '
|
|
81
|
+
color_logger_1.default.error('One or more tasks failed while deploying: ', (e && e.message) || 'unknown error');
|
|
93
82
|
result = 1;
|
|
94
83
|
}
|
|
95
84
|
finally {
|
package/dist/bin/import.js
CHANGED
|
@@ -36,35 +36,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _a, _b, _c;
|
|
40
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
40
|
const task = __importStar(require("../tasks/import-pcf"));
|
|
42
41
|
const package_json_1 = require("../package.json");
|
|
43
42
|
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
43
|
+
const commander_1 = require("commander");
|
|
44
44
|
const argumentUtil_1 = require("../util/argumentUtil");
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
color_logger_1.default.error('Timeout argument must be a positive number representing milliseconds.');
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const verboseArgument = args.find(a => ['-v', '--verbose'].includes(a));
|
|
60
|
-
if (typeof verboseArgument !== 'undefined') {
|
|
61
|
-
color_logger_1.default.setDebug(true);
|
|
62
|
-
}
|
|
45
|
+
// Apply argument preprocessing for backward compatibility
|
|
46
|
+
const { hadDeprecatedEnv } = (0, argumentUtil_1.applyArgumentPreprocessing)(process.argv);
|
|
47
|
+
const program = new commander_1.Command();
|
|
48
|
+
(0, argumentUtil_1.addPathAndEnvironmentOptions)(program)
|
|
49
|
+
.name('pcf-helper-import')
|
|
50
|
+
.description('Import PCF controls to Dataverse')
|
|
51
|
+
.version(package_json_1.version, '-v, --version')
|
|
52
|
+
.parse();
|
|
53
|
+
const options = program.opts();
|
|
54
|
+
(0, argumentUtil_1.setupLogging)(options.verbose);
|
|
63
55
|
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
color_logger_1.default.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
67
|
-
process.exit(1);
|
|
68
|
-
}
|
|
69
|
-
const env = (_c = (0, argumentUtil_1.getArgValue)(args, ['-env', '--environment'])) !== null && _c !== void 0 ? _c : '';
|
|
70
|
-
task.runImport(path, env, verboseArgument !== undefined, typeof timeout !== 'undefined' ? Number(timeout) : undefined);
|
|
56
|
+
const env = (0, argumentUtil_1.resolveEnvironment)(options, hadDeprecatedEnv);
|
|
57
|
+
task.runImport(options.path, env, options.verbose || false, options.timeout ? Number(options.timeout) : undefined);
|
package/dist/bin/init.js
CHANGED
|
@@ -36,30 +36,26 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _a, _b, _c, _d, _e;
|
|
40
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
40
|
const task = __importStar(require("../tasks/init-pcf"));
|
|
42
41
|
const package_json_1 = require("../package.json");
|
|
43
42
|
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
const commander_1 = require("commander");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('pcf-helper-init')
|
|
47
|
+
.description('Initialize a new PCF project')
|
|
48
|
+
.version(package_json_1.version, '-v, --version')
|
|
49
|
+
.option('-V, --verbose', 'enable verbose logging')
|
|
50
|
+
.requiredOption('-n, --name <name>', 'name of the PCF control')
|
|
51
|
+
.option('--publisher-name <publisherName>', 'publisher name')
|
|
52
|
+
.option('--publisher-prefix <publisherPrefix>', 'publisher prefix')
|
|
53
|
+
.option('-p, --path <path>', 'path to create the PCF project')
|
|
54
|
+
.option('--run-npm-install', 'run npm install after initialization', true)
|
|
55
|
+
.parse();
|
|
56
|
+
const options = program.opts();
|
|
57
|
+
if (options.verbose) {
|
|
53
58
|
color_logger_1.default.setDebug(true);
|
|
54
59
|
}
|
|
55
60
|
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
56
|
-
|
|
57
|
-
if (typeof name === 'undefined') {
|
|
58
|
-
color_logger_1.default.error('Name argument is required. Use --name to specify the name of the PCF control.');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
const publisherName = (_c = (0, argumentUtil_1.getArgValue)(args, ['-pn', '--publisher-name'])) !== null && _c !== void 0 ? _c : '';
|
|
62
|
-
const publisherPrefix = (_d = (0, argumentUtil_1.getArgValue)(args, ['-pp', '--publisher-prefix'])) !== null && _d !== void 0 ? _d : '';
|
|
63
|
-
const path = (_e = (0, argumentUtil_1.getArgValue)(args, ['-p', '--path'])) !== null && _e !== void 0 ? _e : '';
|
|
64
|
-
const npm = (0, argumentUtil_1.getArgValue)(args, ['-npm', '--run-npm-install'], 'true');
|
|
65
|
-
task.runInit(path, name, publisherName, publisherPrefix, npm === 'true', verboseArgument !== undefined);
|
|
61
|
+
task.runInit(options.path || '', options.name, options.publisherName || '', options.publisherPrefix || '', options.runNpmInstall !== false, options.verbose || false);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const task = __importStar(require("../tasks/session-pcf"));
|
|
41
|
+
const package_json_1 = require("../package.json");
|
|
42
|
+
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
43
|
+
const commander_1 = require("commander");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('pcf-helper-session')
|
|
47
|
+
.description('Run development session')
|
|
48
|
+
.version(package_json_1.version, '-v, --version')
|
|
49
|
+
.option('-V, --verbose', 'enable verbose logging')
|
|
50
|
+
.option('-u, --url <url>', 'remote environment URL')
|
|
51
|
+
.option('-s, --script <script>', 'remote script to intercept')
|
|
52
|
+
.option('-t, --stylesheet <stylesheet>', 'remote stylesheet to intercept')
|
|
53
|
+
.option('-b, --bundle <path>', 'local bundle path')
|
|
54
|
+
.option('-c, --css <path>', 'local CSS path')
|
|
55
|
+
.option('-f, --config <path>', 'config file path', 'dev-config.json')
|
|
56
|
+
.parse();
|
|
57
|
+
const options = program.opts();
|
|
58
|
+
if (options.verbose) {
|
|
59
|
+
color_logger_1.default.setDebug(true);
|
|
60
|
+
color_logger_1.default.debug('Verbose logging enabled');
|
|
61
|
+
}
|
|
62
|
+
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
63
|
+
const config = task.loadConfig(options.config);
|
|
64
|
+
task.runSession(config.remoteEnvironmentUrl, config.remoteScriptToIntercept, config.remoteStylesheetToIntercept, config.localBundlePath, config.localCssPath);
|
package/dist/bin/upgrade.js
CHANGED
|
@@ -36,26 +36,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _a, _b;
|
|
40
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
40
|
const task = __importStar(require("../tasks/upgrade-pcf"));
|
|
42
41
|
const package_json_1 = require("../package.json");
|
|
43
42
|
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
const commander_1 = require("commander");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('pcf-helper-upgrade')
|
|
47
|
+
.description('Upgrade PCF controls')
|
|
48
|
+
.version(package_json_1.version, '-v, --version')
|
|
49
|
+
.option('-V, --verbose', 'enable verbose logging')
|
|
50
|
+
.requiredOption('-p, --path <path>', 'path to solution folder')
|
|
51
|
+
.parse();
|
|
52
|
+
const options = program.opts();
|
|
53
|
+
if (options.verbose) {
|
|
53
54
|
color_logger_1.default.setDebug(true);
|
|
54
55
|
}
|
|
55
56
|
color_logger_1.default.log('PCF Helper version', package_json_1.version);
|
|
56
|
-
|
|
57
|
-
if (typeof path === 'undefined') {
|
|
58
|
-
color_logger_1.default.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
task.runUpgrade(path, verboseArgument !== undefined);
|
|
57
|
+
task.runUpgrade(options.path, options.verbose || false);
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tywalk/pcf-helper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Command line helper for building and publishing PCF controls to Dataverse.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./types/",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"pcf-helper-build": "dist/bin/build.js",
|
|
27
27
|
"pcf-helper-import": "dist/bin/import.js",
|
|
28
28
|
"pcf-helper-deploy": "dist/bin/deploy.js",
|
|
29
|
-
"pcf-helper-init": "dist/bin/init.js"
|
|
29
|
+
"pcf-helper-init": "dist/bin/init.js",
|
|
30
|
+
"pcf-helper-session": "dist/bin/session.js"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/jest": "^29.5.14",
|
|
@@ -36,6 +37,8 @@
|
|
|
36
37
|
"typescript": "^5.8.2"
|
|
37
38
|
},
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"@tywalk/color-logger": "^1.0.3"
|
|
40
|
+
"@tywalk/color-logger": "^1.0.3",
|
|
41
|
+
"commander": "^14.0.3",
|
|
42
|
+
"playwright": "^1.58.2"
|
|
40
43
|
}
|
|
41
44
|
}
|
package/dist/tasks/index.js
CHANGED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.runSession = runSession;
|
|
16
|
+
exports.loadConfig = loadConfig;
|
|
17
|
+
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const playwright_1 = require("playwright");
|
|
21
|
+
function loadConfig(config) {
|
|
22
|
+
// Load file config if exists
|
|
23
|
+
let fileConfig = {};
|
|
24
|
+
const configPath = path_1.default.join(__dirname, config || 'dev-config.json');
|
|
25
|
+
console.log(`📁 Looking for config file at: ${configPath}`);
|
|
26
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
27
|
+
fileConfig = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
28
|
+
console.log(`✅ Loaded config file: ${JSON.stringify(fileConfig, null, 2)}`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log(`⚠️ Config file not found, using defaults or CLI/env options.`);
|
|
32
|
+
}
|
|
33
|
+
// Get the base URL first
|
|
34
|
+
const remoteEnvironmentUrl = process.env.REMOTE_ENVIRONMENT_URL ||
|
|
35
|
+
fileConfig.remoteEnvironmentUrl ||
|
|
36
|
+
'https://app.your-remote-environment.com';
|
|
37
|
+
// Handle script argument - support both relative paths and full URLs
|
|
38
|
+
let remoteScriptToIntercept = process.env.REMOTE_SCRIPT_TO_INTERCEPT ||
|
|
39
|
+
fileConfig.remoteScriptToIntercept ||
|
|
40
|
+
'https://app.your-remote-environment.com/static/js/remote-control-bundle.js';
|
|
41
|
+
// If script is a relative path (doesn't start with http/https), combine with base URL
|
|
42
|
+
if (remoteScriptToIntercept && !remoteScriptToIntercept.startsWith('http')) {
|
|
43
|
+
// Normalize the base URL (remove trailing slash)
|
|
44
|
+
const baseUrl = remoteEnvironmentUrl.replace(/\/$/, '');
|
|
45
|
+
// Normalize the script path (ensure it starts with /)
|
|
46
|
+
const scriptPath = remoteScriptToIntercept.startsWith('/')
|
|
47
|
+
? remoteScriptToIntercept
|
|
48
|
+
: '/' + remoteScriptToIntercept;
|
|
49
|
+
remoteScriptToIntercept = `${baseUrl}${scriptPath}`;
|
|
50
|
+
}
|
|
51
|
+
let remoteStylesheetToIntercept = process.env.REMOTE_STYLESHEET_TO_INTERCEPT ||
|
|
52
|
+
fileConfig.remoteStylesheetToIntercept ||
|
|
53
|
+
'https://app.your-remote-environment.com/static/css/remote-control-styles.css';
|
|
54
|
+
// If stylesheet is a relative path (doesn't start with http/https), combine with base URL
|
|
55
|
+
if (remoteStylesheetToIntercept && !remoteStylesheetToIntercept.startsWith('http')) {
|
|
56
|
+
// Normalize the base URL (remove trailing slash)
|
|
57
|
+
const baseUrl = remoteEnvironmentUrl.replace(/\/$/, '');
|
|
58
|
+
// Normalize the stylesheet path (ensure it starts with /)
|
|
59
|
+
const stylesheetPath = remoteStylesheetToIntercept.startsWith('/')
|
|
60
|
+
? remoteStylesheetToIntercept
|
|
61
|
+
: '/' + remoteStylesheetToIntercept;
|
|
62
|
+
remoteStylesheetToIntercept = `${baseUrl}${stylesheetPath}`;
|
|
63
|
+
}
|
|
64
|
+
// Priority: CLI args > env vars > config file > defaults
|
|
65
|
+
return {
|
|
66
|
+
remoteEnvironmentUrl: remoteEnvironmentUrl,
|
|
67
|
+
remoteScriptToIntercept: remoteScriptToIntercept,
|
|
68
|
+
remoteStylesheetToIntercept: remoteStylesheetToIntercept,
|
|
69
|
+
localCssPath: process.env.LOCAL_CSS_PATH ||
|
|
70
|
+
fileConfig.localCssPath ||
|
|
71
|
+
path_1.default.join(__dirname, 'dist', 'local-control-styles.css'),
|
|
72
|
+
localBundlePath: process.env.LOCAL_BUNDLE_PATH ||
|
|
73
|
+
fileConfig.localBundlePath ||
|
|
74
|
+
path_1.default.join(__dirname, 'dist', 'local-control-bundle.js')
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function runSession(remoteEnvironmentUrl, remoteScriptToIntercept, remoteStylesheetToIntercept, localBundlePath, localCssPath) {
|
|
78
|
+
const REMOTE_ENVIRONMENT_URL = remoteEnvironmentUrl;
|
|
79
|
+
const REMOTE_SCRIPT_TO_INTERCEPT = remoteScriptToIntercept;
|
|
80
|
+
const REMOTE_STYLESHEET_TO_INTERCEPT = remoteStylesheetToIntercept;
|
|
81
|
+
const LOCAL_BUNDLE_PATH = path_1.default.resolve(localBundlePath);
|
|
82
|
+
const LOCAL_CSS_PATH = path_1.default.resolve(localCssPath);
|
|
83
|
+
// Debug logging for URL construction
|
|
84
|
+
color_logger_1.default.debug('🔍 Debug - Final URLs:');
|
|
85
|
+
color_logger_1.default.debug(` Remote Environment: ${REMOTE_ENVIRONMENT_URL}`);
|
|
86
|
+
color_logger_1.default.debug(` Script to intercept: ${REMOTE_SCRIPT_TO_INTERCEPT}`);
|
|
87
|
+
color_logger_1.default.debug(` CSS to intercept: ${REMOTE_STYLESHEET_TO_INTERCEPT}`);
|
|
88
|
+
color_logger_1.default.debug(` Local bundle path: ${LOCAL_BUNDLE_PATH}`);
|
|
89
|
+
color_logger_1.default.debug(` Local CSS path: ${LOCAL_CSS_PATH}`);
|
|
90
|
+
color_logger_1.default.debug('');
|
|
91
|
+
// Path to store your session cookies
|
|
92
|
+
const AUTH_DIR = path_1.default.join(__dirname, '.auth');
|
|
93
|
+
const STATE_FILE = path_1.default.join(AUTH_DIR, 'state.json');
|
|
94
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
color_logger_1.default.log('🚀 Starting ephemeral browser session...');
|
|
96
|
+
// 1. Prepare context options (load session if it exists)
|
|
97
|
+
let contextOptions = {};
|
|
98
|
+
if (fs_1.default.existsSync(STATE_FILE)) {
|
|
99
|
+
color_logger_1.default.log('🔓 Loading previous login session...');
|
|
100
|
+
contextOptions.storageState = STATE_FILE;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
color_logger_1.default.log('⚠️ No previous session found. You may need to log in.');
|
|
104
|
+
}
|
|
105
|
+
// 2. Launch browser and apply context
|
|
106
|
+
const browser = yield playwright_1.chromium.launch({ headless: false });
|
|
107
|
+
const context = yield browser.newContext(Object.assign(Object.assign({}, contextOptions), { viewport: null // Use the actual browser window size
|
|
108
|
+
}));
|
|
109
|
+
// Shared cleanup function to save state and close browser
|
|
110
|
+
const cleanup = (...args_1) => __awaiter(this, [...args_1], void 0, function* (reason = 'unknown') {
|
|
111
|
+
try {
|
|
112
|
+
color_logger_1.default.log(`💾 Saving session state (${reason})...`);
|
|
113
|
+
// Ensure the .auth directory exists before saving
|
|
114
|
+
if (!fs_1.default.existsSync(AUTH_DIR)) {
|
|
115
|
+
fs_1.default.mkdirSync(AUTH_DIR, { recursive: true });
|
|
116
|
+
}
|
|
117
|
+
if (!browser.isConnected()) {
|
|
118
|
+
color_logger_1.default.log('Browser already disconnected.');
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// Save the cookies and local storage to the JSON file
|
|
122
|
+
yield context.storageState({ path: STATE_FILE });
|
|
123
|
+
color_logger_1.default.log('🛑 Tearing down rules and session.');
|
|
124
|
+
yield browser.close();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
color_logger_1.default.error('Error during cleanup:', error);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
// Handle process exit signals
|
|
132
|
+
process.on('SIGINT', () => __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
yield cleanup('SIGINT');
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}));
|
|
136
|
+
process.on('SIGTERM', () => __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
yield cleanup('SIGTERM');
|
|
138
|
+
process.exit(0);
|
|
139
|
+
}));
|
|
140
|
+
process.on('beforeExit', () => __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
yield cleanup('beforeExit');
|
|
142
|
+
}));
|
|
143
|
+
// Handle uncaught exceptions
|
|
144
|
+
process.on('uncaughtException', (error) => __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
color_logger_1.default.error('Uncaught exception:', error);
|
|
146
|
+
yield cleanup('uncaughtException');
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}));
|
|
149
|
+
process.on('unhandledRejection', (reason) => __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
color_logger_1.default.error('Unhandled promise rejection:', reason);
|
|
151
|
+
yield cleanup('unhandledRejection');
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}));
|
|
154
|
+
// Handle browser disconnect
|
|
155
|
+
browser.on('disconnected', () => __awaiter(this, void 0, void 0, function* () {
|
|
156
|
+
color_logger_1.default.log('Browser disconnected');
|
|
157
|
+
yield cleanup('browser disconnected');
|
|
158
|
+
}));
|
|
159
|
+
// Handle context close (when all pages in context are closed)
|
|
160
|
+
context.on('close', () => __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
color_logger_1.default.log('Browser context closed');
|
|
162
|
+
yield cleanup('context closed');
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}));
|
|
165
|
+
// 3. Programmatically apply your network interception rule with pattern matching
|
|
166
|
+
// Handle dynamic version segments in CRM URLs like /version?/webresources/...
|
|
167
|
+
const scriptPattern = REMOTE_SCRIPT_TO_INTERCEPT.replace(/^https?:\/\/[^\/]+/, '');
|
|
168
|
+
const stylesheetPattern = REMOTE_STYLESHEET_TO_INTERCEPT.replace(/^https?:\/\/[^\/]+/, '');
|
|
169
|
+
color_logger_1.default.debug(`📡 Setting up interception patterns:`);
|
|
170
|
+
color_logger_1.default.debug(` Script pattern: **${scriptPattern}`);
|
|
171
|
+
color_logger_1.default.debug(` CSS pattern: **${stylesheetPattern}`);
|
|
172
|
+
yield context.route(route => {
|
|
173
|
+
if (!route.href) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
// Match script URLs that end with the same path structure
|
|
177
|
+
return route.href.includes(scriptPattern) && route.href.includes('bundle.js');
|
|
178
|
+
}, (route) => __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
color_logger_1.default.log(`✅ Intercepted script request: ${route.request().url()}`);
|
|
180
|
+
color_logger_1.default.log(` Serving local file: ${LOCAL_BUNDLE_PATH}`);
|
|
181
|
+
route.fulfill({
|
|
182
|
+
status: 200,
|
|
183
|
+
contentType: 'application/javascript',
|
|
184
|
+
body: fs_1.default.readFileSync(LOCAL_BUNDLE_PATH)
|
|
185
|
+
});
|
|
186
|
+
}));
|
|
187
|
+
yield context.route(route => {
|
|
188
|
+
if (!route.href) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
// Match CSS URLs that end with the same path structure
|
|
192
|
+
return route.href.includes(stylesheetPattern) && route.href.includes('ItemDescriptionPCF.css');
|
|
193
|
+
}, (route) => __awaiter(this, void 0, void 0, function* () {
|
|
194
|
+
color_logger_1.default.log(`✅ Intercepted CSS request: ${route.request().url()}`);
|
|
195
|
+
color_logger_1.default.log(` Serving local file: ${LOCAL_CSS_PATH}`);
|
|
196
|
+
route.fulfill({
|
|
197
|
+
status: 200,
|
|
198
|
+
contentType: 'text/css',
|
|
199
|
+
body: fs_1.default.readFileSync(LOCAL_CSS_PATH)
|
|
200
|
+
});
|
|
201
|
+
}));
|
|
202
|
+
// 4. Open a new tab and navigate to your remote environment
|
|
203
|
+
const page = yield context.newPage();
|
|
204
|
+
yield page.goto(REMOTE_ENVIRONMENT_URL);
|
|
205
|
+
// 5. Clean up and save state when the page is closed (but others may still be open)
|
|
206
|
+
page.on('close', () => __awaiter(this, void 0, void 0, function* () {
|
|
207
|
+
const pages = context.pages();
|
|
208
|
+
if (pages.length <= 1) {
|
|
209
|
+
// This was the last page, trigger full cleanup
|
|
210
|
+
yield cleanup('last page closed');
|
|
211
|
+
process.exit(0);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
color_logger_1.default.debug(`Page closed, but ${pages.length - 1} pages still open. Keeping session alive.`);
|
|
215
|
+
}
|
|
216
|
+
}));
|
|
217
|
+
// 6. Watch the local bundle for changes and auto-reload
|
|
218
|
+
let reloadTimeout;
|
|
219
|
+
fs_1.default.watch(LOCAL_BUNDLE_PATH, (eventType) => {
|
|
220
|
+
if (eventType === 'change') {
|
|
221
|
+
// Clear the previous timer if the file changes again quickly
|
|
222
|
+
clearTimeout(reloadTimeout);
|
|
223
|
+
// Wait 300ms for the bundler to finish writing the file before reloading
|
|
224
|
+
reloadTimeout = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
color_logger_1.default.log(`\n🔄 Local bundle updated! Reloading the page...`);
|
|
226
|
+
try {
|
|
227
|
+
yield page.reload();
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
color_logger_1.default.error('⚠️ Could not reload page (browser might be closed).', err);
|
|
231
|
+
}
|
|
232
|
+
}), 300);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}))();
|
|
236
|
+
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.getArg = getArg;
|
|
4
7
|
exports.getArgValue = getArgValue;
|
|
8
|
+
exports.preprocessArgs = preprocessArgs;
|
|
9
|
+
exports.resolveEnvironment = resolveEnvironment;
|
|
10
|
+
exports.applyArgumentPreprocessing = applyArgumentPreprocessing;
|
|
11
|
+
exports.addCommonOptions = addCommonOptions;
|
|
12
|
+
exports.addPathAndEnvironmentOptions = addPathAndEnvironmentOptions;
|
|
13
|
+
exports.setupLogging = setupLogging;
|
|
14
|
+
const color_logger_1 = __importDefault(require("@tywalk/color-logger"));
|
|
5
15
|
function getArg(args, arg) {
|
|
6
16
|
const index = args.indexOf(arg);
|
|
7
17
|
if (index !== -1 && index + 1 < args.length) {
|
|
@@ -18,3 +28,90 @@ function getArgValue(args, argOpts, defaultIfExists) {
|
|
|
18
28
|
const argIndex = args.indexOf(arg) + 1;
|
|
19
29
|
return (_a = args.at(argIndex)) !== null && _a !== void 0 ? _a : defaultIfExists;
|
|
20
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Preprocesses command line arguments to handle deprecated flags
|
|
33
|
+
* @param args - Raw command line arguments
|
|
34
|
+
* @returns Object containing processed args and deprecation flags
|
|
35
|
+
*/
|
|
36
|
+
function preprocessArgs(args) {
|
|
37
|
+
const processed = [...args];
|
|
38
|
+
let hadDeprecatedEnv = false;
|
|
39
|
+
// Handle deprecated -env flag (single dash) by converting to --env (double dash)
|
|
40
|
+
for (let i = 0; i < processed.length; i++) {
|
|
41
|
+
if (processed[i] === '-env') {
|
|
42
|
+
hadDeprecatedEnv = true;
|
|
43
|
+
processed[i] = '--env';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { args: processed, hadDeprecatedEnv };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolves environment value from options with proper deprecation warnings
|
|
50
|
+
* @param options - Parsed Commander.js options
|
|
51
|
+
* @param hadDeprecatedEnv - Whether the deprecated -env flag was used
|
|
52
|
+
* @returns Resolved environment string
|
|
53
|
+
*/
|
|
54
|
+
function resolveEnvironment(options, hadDeprecatedEnv) {
|
|
55
|
+
// Check if deprecated --env flag was used
|
|
56
|
+
if (options.env && options.environment) {
|
|
57
|
+
color_logger_1.default.warn('⚠️ Both --env (deprecated) and --environment flags provided. Using --environment value.');
|
|
58
|
+
return options.environment;
|
|
59
|
+
}
|
|
60
|
+
else if (options.env) {
|
|
61
|
+
if (hadDeprecatedEnv) {
|
|
62
|
+
color_logger_1.default.warn('⚠️ The -env flag is DEPRECATED. Please use -e or --environment instead.');
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
color_logger_1.default.warn('⚠️ The --env flag is DEPRECATED. Please use -e or --environment instead.');
|
|
66
|
+
}
|
|
67
|
+
return options.env;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return options.environment || '';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Applies argument preprocessing for backward compatibility
|
|
75
|
+
* @param originalArgv - The original process.argv
|
|
76
|
+
*/
|
|
77
|
+
function applyArgumentPreprocessing(originalArgv) {
|
|
78
|
+
const { args: processedArgs, hadDeprecatedEnv } = preprocessArgs(originalArgv.slice(2));
|
|
79
|
+
process.argv = [...originalArgv.slice(0, 2), ...processedArgs];
|
|
80
|
+
return { hadDeprecatedEnv };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Adds common CLI options to a Commander.js command
|
|
84
|
+
* @param command - Commander.js command instance
|
|
85
|
+
* @returns The command with common options added
|
|
86
|
+
*/
|
|
87
|
+
function addCommonOptions(command) {
|
|
88
|
+
return command
|
|
89
|
+
.option('-V, --verbose', 'enable verbose logging')
|
|
90
|
+
.option('-t, --timeout <milliseconds>', 'timeout in milliseconds', (value) => {
|
|
91
|
+
const num = Number(value);
|
|
92
|
+
if (isNaN(num) || num <= 0) {
|
|
93
|
+
throw new Error('Timeout must be a positive number');
|
|
94
|
+
}
|
|
95
|
+
return value;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Adds path and environment options to a Commander.js command
|
|
100
|
+
* @param command - Commander.js command instance
|
|
101
|
+
* @returns The command with path and environment options added
|
|
102
|
+
*/
|
|
103
|
+
function addPathAndEnvironmentOptions(command) {
|
|
104
|
+
return addCommonOptions(command)
|
|
105
|
+
.requiredOption('-p, --path <path>', 'path to solution folder')
|
|
106
|
+
.option('-e, --environment <environment>', 'environment name')
|
|
107
|
+
.option('--env <environment>', '[DEPRECATED: use -e/--environment] environment name (deprecated)');
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Sets up logging based on verbose option
|
|
111
|
+
* @param verbose - Whether verbose logging is enabled
|
|
112
|
+
*/
|
|
113
|
+
function setupLogging(verbose) {
|
|
114
|
+
if (verbose) {
|
|
115
|
+
color_logger_1.default.setDebug(true);
|
|
116
|
+
}
|
|
117
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tywalk/pcf-helper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Command line helper for building and publishing PCF controls to Dataverse.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "./types/",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"pcf-helper-build": "dist/bin/build.js",
|
|
27
27
|
"pcf-helper-import": "dist/bin/import.js",
|
|
28
28
|
"pcf-helper-deploy": "dist/bin/deploy.js",
|
|
29
|
-
"pcf-helper-init": "dist/bin/init.js"
|
|
29
|
+
"pcf-helper-init": "dist/bin/init.js",
|
|
30
|
+
"pcf-helper-session": "dist/bin/session.js"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@types/jest": "^29.5.14",
|
|
@@ -36,6 +37,8 @@
|
|
|
36
37
|
"typescript": "^5.8.2"
|
|
37
38
|
},
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"@tywalk/color-logger": "^1.0.3"
|
|
40
|
+
"@tywalk/color-logger": "^1.0.3",
|
|
41
|
+
"commander": "^14.0.3",
|
|
42
|
+
"playwright": "^1.58.2"
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/types/tasks/index.d.ts
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function loadConfig(config?: string): {
|
|
2
|
+
remoteEnvironmentUrl: any;
|
|
3
|
+
remoteScriptToIntercept: any;
|
|
4
|
+
remoteStylesheetToIntercept: any;
|
|
5
|
+
localCssPath: any;
|
|
6
|
+
localBundlePath: any;
|
|
7
|
+
};
|
|
8
|
+
declare function runSession(remoteEnvironmentUrl: string, remoteScriptToIntercept: string, remoteStylesheetToIntercept: string, localBundlePath: string, localCssPath: string): void;
|
|
9
|
+
export { runSession, loadConfig };
|
|
@@ -1,2 +1,46 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
1
2
|
export declare function getArg(args: string[], arg: string): string | undefined;
|
|
2
3
|
export declare function getArgValue(args: string[], argOpts: string[], defaultIfExists?: any): string | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Preprocesses command line arguments to handle deprecated flags
|
|
6
|
+
* @param args - Raw command line arguments
|
|
7
|
+
* @returns Object containing processed args and deprecation flags
|
|
8
|
+
*/
|
|
9
|
+
export declare function preprocessArgs(args: string[]): {
|
|
10
|
+
args: string[];
|
|
11
|
+
hadDeprecatedEnv: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Resolves environment value from options with proper deprecation warnings
|
|
15
|
+
* @param options - Parsed Commander.js options
|
|
16
|
+
* @param hadDeprecatedEnv - Whether the deprecated -env flag was used
|
|
17
|
+
* @returns Resolved environment string
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveEnvironment(options: {
|
|
20
|
+
env?: string;
|
|
21
|
+
environment?: string;
|
|
22
|
+
}, hadDeprecatedEnv: boolean): string;
|
|
23
|
+
/**
|
|
24
|
+
* Applies argument preprocessing for backward compatibility
|
|
25
|
+
* @param originalArgv - The original process.argv
|
|
26
|
+
*/
|
|
27
|
+
export declare function applyArgumentPreprocessing(originalArgv: string[]): {
|
|
28
|
+
hadDeprecatedEnv: boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Adds common CLI options to a Commander.js command
|
|
32
|
+
* @param command - Commander.js command instance
|
|
33
|
+
* @returns The command with common options added
|
|
34
|
+
*/
|
|
35
|
+
export declare function addCommonOptions(command: Command): Command;
|
|
36
|
+
/**
|
|
37
|
+
* Adds path and environment options to a Commander.js command
|
|
38
|
+
* @param command - Commander.js command instance
|
|
39
|
+
* @returns The command with path and environment options added
|
|
40
|
+
*/
|
|
41
|
+
export declare function addPathAndEnvironmentOptions(command: Command): Command;
|
|
42
|
+
/**
|
|
43
|
+
* Sets up logging based on verbose option
|
|
44
|
+
* @param verbose - Whether verbose logging is enabled
|
|
45
|
+
*/
|
|
46
|
+
export declare function setupLogging(verbose?: boolean): void;
|