@tywalk/pcf-helper 1.4.13 → 1.4.14
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 +2 -1
- package/dist/bin/build.js +66 -0
- package/dist/bin/deploy.js +103 -0
- package/dist/bin/import.js +72 -0
- package/dist/bin/init.js +84 -0
- package/dist/bin/upgrade.js +66 -0
- package/dist/tasks/build-pcf.js +28 -0
- package/dist/tasks/import-pcf.js +40 -0
- package/dist/tasks/init-pcf.js +51 -0
- package/dist/tasks/upgrade-pcf.js +28 -0
- package/dist/util/performanceUtil.js +63 -0
- package/package.json +15 -10
- package/{bin/build.js → src/bin/build.ts} +4 -4
- package/{bin/deploy.js → src/bin/deploy.ts} +15 -15
- package/{bin/import.js → src/bin/import.ts} +6 -6
- package/src/bin/init.ts +54 -0
- package/{bin/upgrade.js → src/bin/upgrade.ts} +5 -5
- package/src/tasks/build-pcf.ts +26 -0
- package/src/tasks/import-pcf.ts +40 -0
- package/src/tasks/init-pcf.ts +54 -0
- package/src/tasks/upgrade-pcf.ts +26 -0
- package/src/util/performanceUtil.ts +62 -0
- package/tsconfig.json +8 -0
- package/types/bin/build.d.ts +2 -0
- package/types/bin/deploy.d.ts +2 -0
- package/types/bin/import.d.ts +2 -0
- package/types/bin/init.d.ts +2 -0
- package/types/bin/upgrade.d.ts +2 -0
- package/types/tasks/build-pcf.d.ts +10 -0
- package/types/tasks/import-pcf.d.ts +11 -0
- package/types/tasks/init-pcf.d.ts +2 -0
- package/types/tasks/upgrade-pcf.d.ts +10 -0
- package/{util/performanceUtil.js → types/util/performanceUtil.d.ts} +5 -22
- package/tasks/build-pcf.js +0 -42
- package/tasks/import-pcf.js +0 -59
- package/tasks/upgrade-pcf.js +0 -42
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import * as task from '../tasks/build-pcf';
|
|
3
3
|
const version = require('../package.json').version;
|
|
4
|
-
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
5
|
const [, , ...args] = process.argv;
|
|
6
6
|
|
|
7
|
-
const commandArgument = args.at(0)?.toLowerCase();
|
|
7
|
+
const commandArgument = args.at(0)?.toLowerCase() ?? '';
|
|
8
8
|
if (['-v', '--version'].includes(commandArgument)) {
|
|
9
9
|
console.log('v%s', version);
|
|
10
10
|
process.exit(0);
|
|
@@ -30,4 +30,4 @@ if (typeof path === 'undefined') {
|
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
task.run(path);
|
|
33
|
+
task.run(path, verboseArgument !== undefined);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import * as upgradeTask from '../tasks/upgrade-pcf';
|
|
3
|
+
import * as buildTask from '../tasks/build-pcf';
|
|
4
|
+
import * as importTask from '../tasks/import-pcf';
|
|
5
|
+
import { formatMsToSec } from '../util/performanceUtil';
|
|
6
6
|
const version = require('../package.json').version;
|
|
7
|
-
|
|
7
|
+
import logger from '@tywalk/color-logger';
|
|
8
8
|
const [, , ...args] = process.argv;
|
|
9
9
|
|
|
10
|
-
const commandArgument = args.at(0)?.toLowerCase();
|
|
10
|
+
const commandArgument = args.at(0)?.toLowerCase() ?? '';
|
|
11
11
|
if (['-v', '--version'].includes(commandArgument)) {
|
|
12
12
|
console.log('v%s', version);
|
|
13
|
-
|
|
13
|
+
process.exit(0);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const verboseArgument = args.find(a => ['-v', '--verbose'].includes(a));
|
|
@@ -27,7 +27,7 @@ if (typeof pathArgument === 'undefined') {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const pathIndex = args.indexOf(pathArgument) + 1;
|
|
30
|
-
const path = args.at(pathIndex);
|
|
30
|
+
const path = args.at(pathIndex) as string;
|
|
31
31
|
if (typeof path === 'undefined') {
|
|
32
32
|
logger.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
33
33
|
process.exit(1);
|
|
@@ -35,19 +35,19 @@ if (typeof path === 'undefined') {
|
|
|
35
35
|
|
|
36
36
|
const tick = performance.now();
|
|
37
37
|
|
|
38
|
-
const envArgument = args.find(a => ['-env', '--environment'].includes(a));
|
|
38
|
+
const envArgument = args.find(a => ['-env', '--environment'].includes(a)) ?? '';
|
|
39
39
|
let envIndex = args.indexOf(envArgument) + 1;
|
|
40
40
|
let env = '';
|
|
41
41
|
if (envIndex > 0) {
|
|
42
|
-
env = args.at(envIndex);
|
|
42
|
+
env = args.at(envIndex) ?? '';
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function executeTasks() {
|
|
46
|
-
const upgradeResult = upgradeTask.run(path);
|
|
46
|
+
const upgradeResult = upgradeTask.run(path, typeof verboseArgument !== 'undefined');
|
|
47
47
|
if (upgradeResult === 1) return 1;
|
|
48
|
-
const buildResult = buildTask.run(path);
|
|
48
|
+
const buildResult = buildTask.run(path, typeof verboseArgument !== 'undefined');
|
|
49
49
|
if (buildResult === 1) return 1;
|
|
50
|
-
const importResult = importTask.run(path, env);
|
|
50
|
+
const importResult = importTask.run(path, env, typeof verboseArgument !== 'undefined');
|
|
51
51
|
if (importResult === 1) return 1;
|
|
52
52
|
return 0;
|
|
53
53
|
}
|
|
@@ -58,7 +58,7 @@ try {
|
|
|
58
58
|
if (result === 0) {
|
|
59
59
|
logger.log('Deploy complete!');
|
|
60
60
|
}
|
|
61
|
-
} catch (e) {
|
|
61
|
+
} catch (e: any) {
|
|
62
62
|
logger.error('One or more tasks failed while deploying: ', (e && e.message) || 'unkown error');
|
|
63
63
|
result = 1;
|
|
64
64
|
} finally {
|
|
@@ -66,4 +66,4 @@ try {
|
|
|
66
66
|
logger.log(formatMsToSec('Deploy finished in %is.', tock - tick));
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
process.exit(result);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import * as task from '../tasks/import-pcf';
|
|
3
3
|
const version = require('../package.json').version;
|
|
4
|
-
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
5
|
const [, , ...args] = process.argv;
|
|
6
6
|
|
|
7
|
-
const commandArgument = args.at(0)?.toLowerCase();
|
|
7
|
+
const commandArgument = args.at(0)?.toLowerCase() ?? '';
|
|
8
8
|
if (['-v', '--version'].includes(commandArgument)) {
|
|
9
9
|
console.log('v%s', version);
|
|
10
|
-
|
|
10
|
+
process.exit(0);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const verboseArgument = args.find(a => ['-v', '--verbose'].includes(a));
|
|
@@ -30,11 +30,11 @@ if (typeof path === 'undefined') {
|
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const envArgument = args.find(a => ['-env', '--environment'].includes(a));
|
|
33
|
+
const envArgument = args.find(a => ['-env', '--environment'].includes(a)) ?? '';
|
|
34
34
|
let envIndex = args.indexOf(envArgument) + 1;
|
|
35
35
|
let env = '';
|
|
36
36
|
if (envIndex > 0) {
|
|
37
|
-
env = args.at(envIndex);
|
|
37
|
+
env = args.at(envIndex) ?? '';
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
task.run(path, env);
|
package/src/bin/init.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as task from '../tasks/init-pcf';
|
|
3
|
+
const version = require('../package.json').version;
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
|
+
const [, , ...args] = process.argv;
|
|
6
|
+
|
|
7
|
+
const commandArgument = args.at(0)?.toLowerCase() ?? '';
|
|
8
|
+
if (['-v', '--version'].includes(commandArgument)) {
|
|
9
|
+
console.log('v%s', version);
|
|
10
|
+
process.exit(0);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const verboseArgument = args.find(a => ['-v', '--verbose'].includes(a));
|
|
14
|
+
if (typeof verboseArgument !== 'undefined') {
|
|
15
|
+
logger.setDebug(true);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
logger.log('PCF Helper version', version);
|
|
19
|
+
|
|
20
|
+
const nameArgument = args.find(a => ['-n', '--name'].includes(a));
|
|
21
|
+
if (typeof nameArgument === 'undefined') {
|
|
22
|
+
logger.error('Name argument is required. Use --name to specify the name of the control.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const nameIndex = args.indexOf(nameArgument) + 1;
|
|
27
|
+
const name = args.at(nameIndex);
|
|
28
|
+
if (typeof name === 'undefined') {
|
|
29
|
+
logger.error('Path argument is required. Use --path to specify the path to solution folder.');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let publisherName = '';
|
|
34
|
+
const publisherNameArgument = args.find(a => ['-pn', '--publisher-name'].includes(a));
|
|
35
|
+
if (typeof publisherNameArgument !== 'undefined') {
|
|
36
|
+
const publisherNameIndex = args.indexOf(publisherNameArgument) + 1;
|
|
37
|
+
publisherName = args.at(publisherNameIndex) ?? '';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let publisherPrefix = '';
|
|
41
|
+
const publisherPrefixArgument = args.find(a => ['-pp', '--publisher-prefix'].includes(a));
|
|
42
|
+
if (typeof publisherPrefixArgument !== 'undefined') {
|
|
43
|
+
const publisherPrefixIndex = args.indexOf(publisherPrefixArgument) + 1;
|
|
44
|
+
publisherPrefix = args.at(publisherPrefixIndex) ?? '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let path = '';
|
|
48
|
+
const pathArgument = args.find(a => ['-p', '--path'].includes(a));
|
|
49
|
+
if (typeof pathArgument !== 'undefined') {
|
|
50
|
+
const pathIndex = args.indexOf(pathArgument) + 1;
|
|
51
|
+
path = args.at(pathIndex) ?? '';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
task.run(path, name, publisherName, publisherPrefix, verboseArgument !== undefined);
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import * as task from '../tasks/upgrade-pcf';
|
|
3
3
|
const version = require('../package.json').version;
|
|
4
|
-
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
5
|
const [, , ...args] = process.argv;
|
|
6
6
|
|
|
7
|
-
const commandArgument = args.at(0)?.toLowerCase();
|
|
7
|
+
const commandArgument = args.at(0)?.toLowerCase() ?? '';
|
|
8
8
|
if (['-v', '--version'].includes(commandArgument)) {
|
|
9
9
|
console.log('v%s', version);
|
|
10
|
-
|
|
10
|
+
process.exit(0);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const verboseArgument = args.find(a => ['-v', '--verbose'].includes(a));
|
|
@@ -30,4 +30,4 @@ if (typeof path === 'undefined') {
|
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
task.run(path);
|
|
33
|
+
task.run(path, verboseArgument !== undefined);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { formatTime, handleTaskCompletion } from '../util/performanceUtil';
|
|
3
|
+
import logger from '@tywalk/color-logger';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Builds the Power Apps component framework project.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} path The path to the project folder containing the pcfproj.json file.
|
|
9
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
10
|
+
*
|
|
11
|
+
* @returns {number} The exit code of the spawned process.
|
|
12
|
+
*/
|
|
13
|
+
function run(path: string, verbose: boolean): number {
|
|
14
|
+
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting build...\n');
|
|
15
|
+
const tick = performance.now();
|
|
16
|
+
const task = spawnSync('dotnet build', ['--restore', '-c', 'Release', path], {
|
|
17
|
+
cwd: process.cwd(),
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
shell: true,
|
|
20
|
+
timeout: 1000 * 60 * 5 // 5 minutes
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return handleTaskCompletion(task, 'build', performance.now() - tick, verbose);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { run };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { join, extname } from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
|
+
import { formatTime, handleTaskCompletion } from '../util/performanceUtil';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Imports a PCF solution into a specified Dataverse environment.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} path - The path to the solution folder containing the build output.
|
|
11
|
+
* @param {string} env - The environment identifier (GUID or URL) where the solution will be imported.
|
|
12
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
13
|
+
*
|
|
14
|
+
* @returns {number} The exit status of the import process.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
function run(path: string, env: string, verbose?: boolean): number {
|
|
18
|
+
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting import...\n');
|
|
19
|
+
const tick = performance.now();
|
|
20
|
+
if (!env) {
|
|
21
|
+
logger.warn('Path argument not provided. Assuming active auth profile organization.');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const zipDirPath = join(path, '/bin/release');
|
|
25
|
+
// const zipDirPath = join(path, '');
|
|
26
|
+
const zipDirFiles = fs.readdirSync(zipDirPath);
|
|
27
|
+
const zipFile = zipDirFiles.find(file => extname(file).toLowerCase() === '.zip') ?? '';
|
|
28
|
+
const zipFilePath = join(zipDirPath, zipFile);
|
|
29
|
+
|
|
30
|
+
const task = spawnSync('pac solution import', ['-env', env, '-p', zipFilePath, '-pc'], {
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
stdio: 'inherit',
|
|
33
|
+
shell: true,
|
|
34
|
+
timeout: 1000 * 60 * 5, // 5 minutes
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return handleTaskCompletion(task, 'import', performance.now() - tick, verbose);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { run };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { join, extname } from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import logger from '@tywalk/color-logger';
|
|
5
|
+
import { formatTime, handleTaskCompletion } from '../util/performanceUtil';
|
|
6
|
+
|
|
7
|
+
function pcfExistsInParent(path: string) {
|
|
8
|
+
let levels = 0;
|
|
9
|
+
while (levels < 3) {
|
|
10
|
+
let pathFiles = fs.readdirSync(path);
|
|
11
|
+
let atRoot = pathFiles.some(file => extname(file).toLowerCase() === '.pcfproj');
|
|
12
|
+
if (atRoot) {
|
|
13
|
+
return path;
|
|
14
|
+
}
|
|
15
|
+
path = join(path, '..');
|
|
16
|
+
levels++;
|
|
17
|
+
}
|
|
18
|
+
throw new Error('PCF project not found.');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function run(path: string, name: string, publisherName: string, publisherPrefix: string, verbose: boolean): number {
|
|
22
|
+
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting init...\n');
|
|
23
|
+
const tick = performance.now();
|
|
24
|
+
|
|
25
|
+
path = path ?? process.cwd();
|
|
26
|
+
let pathFiles = fs.readdirSync(path);
|
|
27
|
+
let atRoot = pathFiles.some(file => extname(file).toLowerCase() === '.pcfproj');
|
|
28
|
+
const cdsPath = atRoot ? join(path, 'Solutions', name) : join(path, name);
|
|
29
|
+
|
|
30
|
+
const initTask = spawnSync('pac solution init', ['-pn', publisherName, '-pp', publisherPrefix, '-o', cdsPath], {
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
stdio: 'inherit',
|
|
33
|
+
shell: true,
|
|
34
|
+
timeout: 1000 * 60 * 5, // 5 minutes
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (initTask.status !== 0) {
|
|
38
|
+
return handleTaskCompletion(initTask, 'init', performance.now() - tick, verbose);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!atRoot) {
|
|
42
|
+
path = pcfExistsInParent(path);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const packageTask = spawnSync('pac solution add-reference', ['-p', path], {
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
stdio: 'inherit',
|
|
48
|
+
shell: true,
|
|
49
|
+
timeout: 1000 * 60 * 5, // 5 minutes
|
|
50
|
+
});
|
|
51
|
+
return handleTaskCompletion(packageTask, 'init', performance.now() - tick, verbose);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { run };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { formatTime, handleTaskCompletion } from '../util/performanceUtil';
|
|
3
|
+
import logger from '@tywalk/color-logger';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Upgrades the Power Apps component framework project.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} path The path to the project folder containing the pcfproj.json file.
|
|
9
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
10
|
+
*
|
|
11
|
+
* @returns {number} The exit code of the spawned process.
|
|
12
|
+
*/
|
|
13
|
+
function run(path: string, verbose?: boolean): number {
|
|
14
|
+
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting upgrade...\n');
|
|
15
|
+
const tick = performance.now();
|
|
16
|
+
const task = spawnSync(`pac solution version -s Solution -sp ${path} && pac pcf version -s Manifest && npm version patch --no-git-tag-version`, {
|
|
17
|
+
cwd: process.cwd(),
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
shell: true,
|
|
20
|
+
timeout: 1000 * 60 // 1 min
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return handleTaskCompletion(task, 'upgrade', performance.now() - tick, verbose);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { run }
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { SpawnSyncReturns } from 'child_process';
|
|
2
|
+
import util from 'util';
|
|
3
|
+
import logger from '@tywalk/color-logger';
|
|
4
|
+
|
|
5
|
+
var formatter = new Intl.DateTimeFormat('en-US', {
|
|
6
|
+
hour: '2-digit',
|
|
7
|
+
minute: '2-digit',
|
|
8
|
+
second: '2-digit',
|
|
9
|
+
hour12: false
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Formats a number of milliseconds into seconds.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} format - The string format to use when formatting the number of seconds.
|
|
16
|
+
* @param {number} ms - The number of milliseconds to be formatted.
|
|
17
|
+
*
|
|
18
|
+
* @returns {string} The formatted number of seconds.
|
|
19
|
+
*/
|
|
20
|
+
function formatMsToSec(format: string, ms: number): string {
|
|
21
|
+
const seconds = ms / 1000;
|
|
22
|
+
return util.format(format, seconds);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Formats a Date object into a human-readable string.
|
|
27
|
+
*
|
|
28
|
+
* @param {Date} date - The date object to be formatted.
|
|
29
|
+
*
|
|
30
|
+
* @returns {string} The formatted string.
|
|
31
|
+
*/
|
|
32
|
+
function formatTime(date: Date): string {
|
|
33
|
+
return formatter.format(date);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function handleTaskCompletion(task: SpawnSyncReturns<Buffer<ArrayBufferLike>>, name: string, duration: number, verbose?: boolean) {
|
|
37
|
+
if (task.status === 0) {
|
|
38
|
+
logger.success(`[PCF Helper] ${name} complete!`);
|
|
39
|
+
logger.debug(formatMsToSec(`[PCF Helper] ${formatTime(new Date())} ${name} finished in %is.\n`, duration));
|
|
40
|
+
} else {
|
|
41
|
+
if (task.error) {
|
|
42
|
+
if (task.signal === 'SIGTERM') {
|
|
43
|
+
logger.error(`[PCF Helper] Unable to complete ${name}. A timeout of 5 minutes was reached.`, task.error.message);
|
|
44
|
+
} else {
|
|
45
|
+
logger.error(`[PCF Helper] Unable to complete ${name}:`, task.signal, task.error.message);
|
|
46
|
+
}
|
|
47
|
+
if (verbose) {
|
|
48
|
+
logger.debug('[PCF Helper] Error details:', task.signal, task.error.stack);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
logger.error(`[PCF Helper] Unable to complete ${name}: One or more errors ocurred.`);
|
|
52
|
+
}
|
|
53
|
+
logger.debug(formatMsToSec(`[PCF Helper] ${formatTime(new Date())} ${name} finished with errors in %is.\n`, duration));
|
|
54
|
+
}
|
|
55
|
+
return task.status ?? 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
formatMsToSec,
|
|
60
|
+
formatTime,
|
|
61
|
+
handleTaskCompletion
|
|
62
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist", /* Specify an output folder for all emitted files. */
|
|
5
|
+
"declarationDir": "./types", /* Specify the output directory for generated declaration files. */
|
|
6
|
+
},
|
|
7
|
+
"include": ["src/bin/**/*.ts"],
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the Power Apps component framework project.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} path The path to the project folder containing the pcfproj.json file.
|
|
5
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
6
|
+
*
|
|
7
|
+
* @returns {number} The exit code of the spawned process.
|
|
8
|
+
*/
|
|
9
|
+
declare function run(path: string, verbose: boolean): number;
|
|
10
|
+
export { run };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Imports a PCF solution into a specified Dataverse environment.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} path - The path to the solution folder containing the build output.
|
|
5
|
+
* @param {string} env - The environment identifier (GUID or URL) where the solution will be imported.
|
|
6
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
7
|
+
*
|
|
8
|
+
* @returns {number} The exit status of the import process.
|
|
9
|
+
*/
|
|
10
|
+
declare function run(path: string, env: string, verbose?: boolean): number;
|
|
11
|
+
export { run };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrades the Power Apps component framework project.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} path The path to the project folder containing the pcfproj.json file.
|
|
5
|
+
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
6
|
+
*
|
|
7
|
+
* @returns {number} The exit code of the spawned process.
|
|
8
|
+
*/
|
|
9
|
+
declare function run(path: string, verbose?: boolean): number;
|
|
10
|
+
export { run };
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var formatter = new Intl.DateTimeFormat('en-US', {
|
|
4
|
-
hour: '2-digit',
|
|
5
|
-
minute: '2-digit',
|
|
6
|
-
second: '2-digit',
|
|
7
|
-
hour12: false
|
|
8
|
-
});
|
|
9
|
-
|
|
1
|
+
import { SpawnSyncReturns } from 'child_process';
|
|
10
2
|
/**
|
|
11
3
|
* Formats a number of milliseconds into seconds.
|
|
12
4
|
*
|
|
@@ -15,11 +7,7 @@ var formatter = new Intl.DateTimeFormat('en-US', {
|
|
|
15
7
|
*
|
|
16
8
|
* @returns {string} The formatted number of seconds.
|
|
17
9
|
*/
|
|
18
|
-
function formatMsToSec(format, ms)
|
|
19
|
-
const seconds = ms / 1000;
|
|
20
|
-
return util.format(format, seconds);
|
|
21
|
-
}
|
|
22
|
-
|
|
10
|
+
declare function formatMsToSec(format: string, ms: number): string;
|
|
23
11
|
/**
|
|
24
12
|
* Formats a Date object into a human-readable string.
|
|
25
13
|
*
|
|
@@ -27,11 +15,6 @@ function formatMsToSec(format, ms) {
|
|
|
27
15
|
*
|
|
28
16
|
* @returns {string} The formatted string.
|
|
29
17
|
*/
|
|
30
|
-
function formatTime(date)
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
module.exports = {
|
|
35
|
-
formatMsToSec,
|
|
36
|
-
formatTime
|
|
37
|
-
}
|
|
18
|
+
declare function formatTime(date: Date): string;
|
|
19
|
+
declare function handleTaskCompletion(task: SpawnSyncReturns<Buffer<ArrayBufferLike>>, name: string, duration: number, verbose?: boolean): number;
|
|
20
|
+
export { formatMsToSec, formatTime, handleTaskCompletion };
|
package/tasks/build-pcf.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
const { spawnSync } = require('child_process');
|
|
2
|
-
const { formatMsToSec, formatTime } = require('../util/performanceUtil');
|
|
3
|
-
const logger = require('@tywalk/color-logger').default;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Builds the Power Apps component framework project.
|
|
7
|
-
*
|
|
8
|
-
* @param {string} path The path to the project folder containing the pcfproj.json file.
|
|
9
|
-
*
|
|
10
|
-
* @returns {number} The exit code of the spawned process.
|
|
11
|
-
*/
|
|
12
|
-
function run(path) {
|
|
13
|
-
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting build...\n');
|
|
14
|
-
const tick = performance.now();
|
|
15
|
-
const task = spawnSync('dotnet build', ['--restore', '-c', 'Release', path], {
|
|
16
|
-
cwd: process.cwd(),
|
|
17
|
-
stdio: 'inherit',
|
|
18
|
-
shell: true,
|
|
19
|
-
timeout: 1000 * 60 * 5 // 5 minutes
|
|
20
|
-
});
|
|
21
|
-
const tock = performance.now();
|
|
22
|
-
|
|
23
|
-
if (task.status === 0) {
|
|
24
|
-
logger.success('[PCF Helper] Build complete!');
|
|
25
|
-
logger.debug(formatMsToSec('[PCF Helper] ' + formatTime(new Date()) + ' Build finished in %is.\n', tock - tick));
|
|
26
|
-
} else {
|
|
27
|
-
if (task.error) {
|
|
28
|
-
if (task.signal === 'SIGTERM') {
|
|
29
|
-
logger.error('[PCF Helper] Unable to complete build. A timeout of 5 minutes was reached.', task.error.message);
|
|
30
|
-
} else {
|
|
31
|
-
logger.error('[PCF Helper] Unable to complete build: ', task.signal, task.error.message);
|
|
32
|
-
}
|
|
33
|
-
logger.debug('[PCF Helper] Error details: ', task.signal, task.error.stack);
|
|
34
|
-
} else {
|
|
35
|
-
logger.error('[PCF Helper] Unable to complete build: One or more errors ocurred.');
|
|
36
|
-
}
|
|
37
|
-
logger.debug(formatMsToSec('[PCF Helper] ' + formatTime(new Date()) + ' Build finished with errors in %is.\n', tock - tick));
|
|
38
|
-
}
|
|
39
|
-
return task.status;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
exports.run = run;
|
package/tasks/import-pcf.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
const { spawnSync } = require('child_process');
|
|
2
|
-
const { join, extname } = require('path');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const logger = require('@tywalk/color-logger').default;
|
|
5
|
-
const { formatMsToSec, formatTime } = require('../util/performanceUtil');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Imports a PCF solution into a specified Dataverse environment.
|
|
9
|
-
*
|
|
10
|
-
* @param {string} path - The path to the solution folder containing the build output.
|
|
11
|
-
* @param {string} env - The environment identifier (GUID or URL) where the solution will be imported.
|
|
12
|
-
* @param {boolean} verbose - If true, additional debug information is logged.
|
|
13
|
-
*
|
|
14
|
-
* @returns {number} The exit status of the import process.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
function run(path, env, verbose) {
|
|
18
|
-
logger.log('[PCF Helper] ' + formatTime(new Date()) + ' Starting import...\n');
|
|
19
|
-
const tick = performance.now();
|
|
20
|
-
if (!env) {
|
|
21
|
-
logger.warn('Path argument not provided. Assuming active auth profile organization.');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const zipDirPath = join(path, '/bin/release');
|
|
25
|
-
// const zipDirPath = join(path, '');
|
|
26
|
-
const zipDirFiles = fs.readdirSync(zipDirPath);
|
|
27
|
-
const zipFile = zipDirFiles.find(file => extname(file).toLowerCase() === '.zip');
|
|
28
|
-
const zipFilePath = join(zipDirPath, zipFile);
|
|
29
|
-
|
|
30
|
-
const task = spawnSync('pac solution import', ['-env', env, '-p', zipFilePath, '-pc'], {
|
|
31
|
-
cwd: process.cwd(),
|
|
32
|
-
stdio: 'inherit',
|
|
33
|
-
shell: true,
|
|
34
|
-
timeout: 1000 * 60 * 5, // 5 minutes
|
|
35
|
-
});
|
|
36
|
-
const tock = performance.now();
|
|
37
|
-
|
|
38
|
-
if (task.status === 0) {
|
|
39
|
-
logger.success('[PCF Helper] Import complete!');
|
|
40
|
-
logger.debug(formatMsToSec('[PCF Helper] ' + formatTime(new Date()) + ' Import finished in %is.\n', tock - tick));
|
|
41
|
-
} else {
|
|
42
|
-
if (task.error) {
|
|
43
|
-
if (task.signal === 'SIGTERM') {
|
|
44
|
-
logger.error('[PCF Helper] Unable to complete import. A timeout of 5 minutes was reached.', task.error.message);
|
|
45
|
-
} else {
|
|
46
|
-
logger.error('[PCF Helper] Unable to complete import:', task.signal, task.error.message);
|
|
47
|
-
}
|
|
48
|
-
if (verbose) {
|
|
49
|
-
logger.debug('[PCF Helper] Error details:', task.signal, task.error.stack);
|
|
50
|
-
}
|
|
51
|
-
} else {
|
|
52
|
-
logger.error('[PCF Helper] Unable to complete import: One or more errors ocurred.');
|
|
53
|
-
}
|
|
54
|
-
logger.debug(formatMsToSec('[PCF Helper] ' + formatTime(new Date()) + ' Import finished with errors in %is.\n', tock - tick));
|
|
55
|
-
}
|
|
56
|
-
return task.status;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
exports.run = run;
|