bpm-core 0.0.126 → 0.0.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,10 +3,145 @@
3
3
 
4
4
  > Ensure your project is updated to Angular 19 to avoid compatibility issues.
5
5
 
6
- ## Recently Added Features
7
- - ### Time Picker
6
+ ## [Recently Added Features](#recently-added-features)
7
+ - ### [BPM Core CLI](#bpm-core-cli)
8
+ A command-line interface tool that provides helper scripts to speed up common tasks.
9
+
10
+ Run the tool using the `bpm-core` command in your terminal.
11
+ To see all available commands, run:
12
+
13
+ ```bash
14
+ bpm-core --help
15
+ ```
16
+
17
+ The BPM Core CLI includes several helper scripts. You can run any script using its corresponding command.
18
+
19
+ Below is the available commands:
20
+
21
+ ---
22
+
23
+ - `deploy`
24
+ Use this command to deploy your service (currently supports only **library services**) to one of the following environments: `dev`, `sit`, or `bat`.
25
+
26
+ The deployment process includes:
27
+ - Running the Angular build
28
+ - Syncing with the remote repository
29
+ - Triggering a Jenkins job
30
+
31
+ **Example usage**
32
+ In your terminal, navigate to the service directory and run the following command:
33
+
34
+ ```bash
35
+ bpm-core deploy --env sit --repo-path D:\stc\build\sit --commit-msg "COW: correct typo in Arabic translation" --remote-dir "cow-new" --username jenkinsUserName --token jenkinsTokenOrPassword
36
+ ```
37
+
38
+ **For more details about available options**, run:
39
+
40
+ ```bash
41
+ bpm-core deploy --help
42
+ ```
43
+
44
+
45
+ - ### [Input Mapping and Filtering](#input-mapping-and-filtering)
46
+ The `app-input` component now supports two powerful inputs:
47
+
48
+ - **`[mapFn]`** — A function that modifies the input value **before it's rendered**, allowing for transformations like uppercase conversion, formatting, or character replacement.
49
+ - **`[filterFn]`** — A function that validates or restricts what characters can be typed, pasted, or dropped into the input.
50
+
51
+ **Built-in Utility Classes Provided:**
52
+ >
53
+ > - `InputFilters`:
54
+ > - `InputFilters.arabicOnly`
55
+ > - `InputFilters.englishOnly`
56
+ > - `InputFilters.digitsOnly`
57
+ > - `InputFilters.buildPattern()`
58
+ >
59
+ > - `InputMappers`:
60
+ > - `InputMappers.toUpperCase`
61
+ > - `InputMappers.toLowerCase`
62
+
63
+ **Examples:**
64
+ - Example 1: Custom filter – Allow only numbers
65
+ ```ts
66
+ numbersOnlyFilter: InputFilterFn = (char, current, next, event) => {
67
+ return /^[0-9]+$/.test(char);
68
+ };
69
+ ```
70
+ ```html
71
+ <app-input
72
+ label="Phone Number"
73
+ [filterFn]="numbersOnlyFilter"
74
+ ></app-input>
75
+ ```
76
+
77
+ - Example 2: Built-in filter – Arabic-only characters
78
+ ```ts
79
+ import { InputFilters } from 'bpm-core';
80
+
81
+ class MyComponent {
82
+ InputFilters = InputFilters;
83
+ }
84
+ ```
85
+ ```html
86
+ <app-input
87
+ label="الاسم بالعربية"
88
+ [filterFn]="InputFilters.arabicOnly"
89
+ ></app-input>
90
+ ```
91
+ > 💡 **Hint:** Use `InputFilters.buildPattern()` when you need to **customize exactly which characters are allowed** in an input.
92
+ > You can combine multiple character groups like Arabic letters, digits, symbols, and spaces then generate a custom filter function using `.build()`.
93
+
94
+ - Example 3: Custom filter using `buildPattern()` — Allow English letters, digits, spaces, and symbols
95
+
96
+ ```ts
97
+ import { InputFilters } from 'bpm-core';
98
+
99
+ class MyComponent {
100
+ customEnglishFilter = InputFilters.buildPattern()
101
+ .allowEnglishAlphabets()
102
+ .allowDigits()
103
+ .allowSpace()
104
+ .allowSymbols()
105
+ .build();
106
+ }
107
+ ```
108
+ ```html
109
+ <app-input
110
+ label="Username"
111
+ [filterFn]="customEnglishFilter"
112
+ ></app-input>
113
+ ```
114
+ - Example 4: Custom map — Capitalize first letter of each word
115
+ ```ts
116
+ capitalizeWordsMapFn: InputMapFn = (char, current, next) => {
117
+ return next.replace(/\b\w/g, (match) => match.toUpperCase());
118
+ };
119
+ ```
120
+ ```html
121
+ <app-input
122
+ label="Full Name"
123
+ [mapFn]="capitalizeWordsMapFn"
124
+ ></app-input>
125
+ ```
126
+
127
+ - Example 5: Built-in map — Force lowercase
128
+ ```ts
129
+ import { InputMappers } from 'bpm-core';
130
+
131
+ class MyComponent {
132
+ InputMappers = InputMappers;
133
+ }
134
+ ```
135
+ ```html
136
+ <app-input
137
+ label="Email"
138
+ [mapFn]="InputMappers.toLowercase"
139
+ ></app-input>
140
+ ```
141
+
142
+ - ### [Time Picker](#time-picker)
8
143
  To use it, import `TimepickerComponent` in your TypeScript file and add `<app-timepicker>` to your template. For more information, hover over the selector after adding it to your template.
9
- - ### Summary Section / Stage
144
+ - ### [Summary Section](#summary-section)
10
145
  This is a stage that appears before the request stage.
11
146
 
12
147
  To enable this feature:
@@ -63,17 +198,27 @@
63
198
  ```
64
199
  </details>
65
200
 
66
- ## Changes Log
201
+ ## [Changes Log](#changes-log)
202
+
203
+ <a id="bpm-core00128-2025-08-25"></a>
204
+ ### [bpm-core@0.0.128 — 2025-08-25](#bpm-core00128-2025-08-25)
205
+ - feat(cli): implement BPM Core CLI with deploy command.
206
+ - refactor(app-input): remove keyType parameter from filter function.
207
+
208
+ <a id="bpm-core00127-2025-08-06"></a>
209
+ ### [bpm-core@0.0.127 — 2025-08-06](#bpm-core00127-2025-08-06)
210
+ - feat(app-input): `app-input` now supports `filterFn` and `mapFn` inputs.
211
+ - feat(validation-errors): Added default error messages for `max` and `min` validators.
67
212
 
68
213
  <a id="bpm-core00126-2025-07-30"></a>
69
214
  ### [bpm-core@0.0.126 — 2025-07-30](#bpm-core00126-2025-07-30)
70
- - Fix (file-uploader): avoid clearing attachments with multiple enabled.
71
- - Fix (file-uploader): activate "maxLength" input to specify maximum number of files
72
- - Fix (attachment-section): resolve _intl console error and translate MatPaginator labels to Arabic.
215
+ - fix(file-uploader): avoid clearing attachments with multiple enabled.
216
+ - fix(file-uploader): activate "maxLength" input to specify maximum number of files
217
+ - fix(attachment-section): resolve _intl console error and translate MatPaginator labels to Arabic.
73
218
 
74
219
  <a id="bpm-core00125-2025-07-23"></a>
75
220
  ### [bpm-core@0.0.125 — 2025-07-23](#bpm-core00125-2025-07-23)
76
- - Fix: resolve issue with downloading attachments from comments history.
221
+ - fix: resolve issue with downloading attachments from comments history.
77
222
 
78
223
  <a id="bpm-core00124-2025-07-17"></a>
79
224
  ### [bpm-core@0.0.124 — 2025-07-17](#bpm-core00124-2025-07-17)
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.LibraryBuild = exports.Build = void 0;
27
+ const utilities_1 = require("./utilities");
28
+ const fs = __importStar(require("fs"));
29
+ class Build {
30
+ constructor() { }
31
+ async runBuild(servicePath) {
32
+ await this.runNgBuild(servicePath);
33
+ this.renameBuildFiles(servicePath);
34
+ this.removeUnneededBuildFiles(servicePath);
35
+ }
36
+ }
37
+ exports.Build = Build;
38
+ class LibraryBuild extends Build {
39
+ runNgBuild(servicePath) {
40
+ return (0, utilities_1.runCommand)('npx ng build --aot -c production --output-hashing none', servicePath);
41
+ }
42
+ isWebpackBuildRequired() {
43
+ return false;
44
+ }
45
+ renameBuildFiles(servicePath) {
46
+ const filesToRenameAfterBuild = [
47
+ { from: `${servicePath}/dist/main.js`, to: `${servicePath}/dist/wm-main.bundle.js` },
48
+ { from: `${servicePath}/dist/styles.css`, to: `${servicePath}/dist/wm-styles.bundle.css` },
49
+ { from: `${servicePath}/dist/polyfills.js`, to: `${servicePath}/dist/wm-polyfills.bundle.js` },
50
+ { from: `${servicePath}/dist/scripts.js`, to: `${servicePath}/dist/wm-scripts.bundle.js` },
51
+ { from: `${servicePath}/dist/runtime.js`, to: `${servicePath}/dist/wm-inline.bundle.js` }
52
+ ];
53
+ filesToRenameAfterBuild.forEach(item => fs.renameSync(item.from, item.to));
54
+ }
55
+ removeUnneededBuildFiles(servicePath) {
56
+ const scssDirPath = `${servicePath}/dis/assets/scss`;
57
+ if (fs.existsSync(scssDirPath)) {
58
+ fs.rmdirSync(scssDirPath, { recursive: true });
59
+ }
60
+ }
61
+ }
62
+ exports.LibraryBuild = LibraryBuild;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.GitOperationsHandler = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const util_1 = require("util");
30
+ const child_process_1 = require("child_process");
31
+ const utilities_1 = require("./utilities");
32
+ class GitOperationsHandler {
33
+ constructor() { }
34
+ async sync(localBuildRepoPath, serviceRemoteDir, servicePath, commitMessage, logger, env) {
35
+ if (await this.getCurrentBranch(localBuildRepoPath) !== env) {
36
+ throw new Error(`Current branch in build repo is not "${env}". Please switch to the correct branch and try again.`);
37
+ }
38
+ logger.log('Pulling latest changes from remote repo...');
39
+ await this.pull(localBuildRepoPath);
40
+ logger.log('Copying build files to service directory in build repo...');
41
+ await this.copyBuildFilesToServiceDirInBuildRepo(localBuildRepoPath, serviceRemoteDir, servicePath);
42
+ logger.log(`Files copied from "${servicePath}" to "${path.join(localBuildRepoPath, serviceRemoteDir)}".`);
43
+ logger.log('Committing changes to local build repo...');
44
+ await this.commit(localBuildRepoPath, commitMessage);
45
+ logger.log('Pushing changes to remote repo...');
46
+ await this.push(localBuildRepoPath);
47
+ }
48
+ async pull(localBuildRepoPath) {
49
+ return await (0, utilities_1.runCommand)('git pull', localBuildRepoPath);
50
+ }
51
+ copyBuildFilesToServiceDirInBuildRepo(localBuildRepoPath, serviceDirNameInBuildRepo, servicePath) {
52
+ const from = path.join(servicePath, 'dist');
53
+ const to = path.join(localBuildRepoPath, serviceDirNameInBuildRepo);
54
+ return this.copyFiles(from, to);
55
+ }
56
+ async commit(localBuildRepoPath, commitMessage) {
57
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
58
+ try {
59
+ const { stdout: status } = await execAsync('git status --porcelain', { cwd: localBuildRepoPath });
60
+ if (status.trim().length === 0) {
61
+ throw new Error('No changes to commit');
62
+ }
63
+ await execAsync('git add .', { cwd: localBuildRepoPath });
64
+ await execAsync(`git commit -m "${commitMessage}"`, { cwd: localBuildRepoPath });
65
+ }
66
+ catch (error) {
67
+ throw new Error('Failed to commit', { cause: error });
68
+ }
69
+ }
70
+ push(localBuildRepoPath) {
71
+ return (0, utilities_1.runCommand)('git push', localBuildRepoPath);
72
+ }
73
+ async copyFiles(srcDir, destDir) {
74
+ try {
75
+ await fs.promises.mkdir(destDir, { recursive: true });
76
+ const items = await fs.promises.readdir(srcDir, { withFileTypes: true });
77
+ for (const item of items) {
78
+ const srcPath = path.join(srcDir, item.name);
79
+ const destPath = path.join(destDir, item.name);
80
+ if (item.isDirectory()) {
81
+ await this.copyFiles(srcPath, destPath);
82
+ }
83
+ else {
84
+ await fs.promises.copyFile(srcPath, destPath);
85
+ }
86
+ }
87
+ }
88
+ catch (error) {
89
+ const errorMsg = `Error copying files: ${error.message}`;
90
+ throw Error(errorMsg);
91
+ }
92
+ }
93
+ async getCurrentBranch(localBuildRepoPath) {
94
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
95
+ try {
96
+ const { stdout: currentBranch } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd: localBuildRepoPath });
97
+ return currentBranch.trim();
98
+ }
99
+ catch (error) {
100
+ throw new Error('Failed to get current branch', { cause: error });
101
+ }
102
+ }
103
+ }
104
+ exports.GitOperationsHandler = GitOperationsHandler;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.deployCommand = void 0;
27
+ const path = __importStar(require("path"));
28
+ const commander_1 = require("commander");
29
+ const build_1 = require("./build");
30
+ const git_operations_handler_1 = require("./git-operations-handler");
31
+ const jenkins_manager_1 = require("./jenkins-manager");
32
+ const utilities_1 = require("./utilities");
33
+ exports.deployCommand = new commander_1.Command('deploy');
34
+ exports.deployCommand
35
+ .description('Deploy a service to a specific environment, deployment process includes building the service, syncing with the remote repository, and running a Jenkins job if credentials are provided.')
36
+ .requiredOption('--env <string>', 'The env you want to deploy to it (dev, sit, or bat)')
37
+ .requiredOption('--repo-path <string>', 'The path for the local build repo make sure it is switched to env branch you want to deploy to it')
38
+ .requiredOption('--commit-msg <string>', 'The commit message for the changes you want to commit to the build repo')
39
+ .requiredOption('--remote-dir <string>', 'The remote directory name in the build repo where the service files will be copied to')
40
+ .option('--skip-build', 'Skip Angular build (optional)', false)
41
+ .option('--username <string>', 'Jenkins username (optional, if not provided Jenkins job will not run)')
42
+ .option('--token <string>', 'Jenkins token or password (optional, if not provided Jenkins job will not run)')
43
+ .action(async (options) => {
44
+ const cwd = process.cwd();
45
+ const serviceName = path.basename(cwd);
46
+ const env = (0, utilities_1.parseEnv)(options.env);
47
+ const logger = new utilities_1.Logger();
48
+ try {
49
+ if (!options.skipBuild) {
50
+ await logger.asyncLog('Building...')(new build_1.LibraryBuild().runBuild(cwd), 'Build Done.', 'Build Failed.');
51
+ }
52
+ await logger.asyncLog('Syncing with the remote repo...')(new git_operations_handler_1.GitOperationsHandler().sync(options.repoPath, options.remoteDir, cwd, options.commitMsg, logger, env), 'Sync Done.', 'Sync Failed.');
53
+ if (options.username && options.token) {
54
+ await logger.asyncLog('Running Jenkins job...')(new jenkins_manager_1.JenkinsManager().run(options.username, options.token, env, logger), 'Jenkins Job Done.', 'Failed to run Jenkins job.');
55
+ logger.success(`${serviceName.toLocaleUpperCase()} deployed to ${options.env.toUpperCase()} successfully.`);
56
+ }
57
+ }
58
+ catch (err) {
59
+ console.log(`${err.message} ${(err.cause?.message || err.cause) ? 'because ' + (err.cause?.message || err.cause) : ''}`);
60
+ }
61
+ });
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JenkinsManager = void 0;
4
+ class JenkinsManager {
5
+ async run(username, token, env, logger) {
6
+ const jobName = this.getJobName(env);
7
+ try {
8
+ const buildNumber = await this.triggerJenkinsAndGetBuildNumber(username, token, jobName, logger);
9
+ await this.waitForBuildToFinish(buildNumber, username, token, jobName, logger);
10
+ }
11
+ catch (err) {
12
+ throw new Error(`Failed to run Jenkins job`, { cause: err });
13
+ }
14
+ }
15
+ async triggerJenkinsAndGetBuildNumber(username, token, jobName, logger) {
16
+ const JENKINS_URL = 'http://172.20.151.119:9090';
17
+ const auth = btoa(`${username}:${token}`);
18
+ try {
19
+ const triggerResponse = await fetch(`${JENKINS_URL}/job/${jobName}/build`, {
20
+ method: 'POST',
21
+ headers: {
22
+ 'Authorization': `Basic ${auth}`
23
+ },
24
+ redirect: 'manual'
25
+ });
26
+ if (triggerResponse.status !== 201) {
27
+ throw new Error(`Failed to trigger build:, ${triggerResponse.statusText}`);
28
+ }
29
+ const queueUrl = triggerResponse.headers.get('Location');
30
+ if (!queueUrl) {
31
+ throw new Error('No queue URL returned');
32
+ }
33
+ logger.log(`Build queued.`);
34
+ let buildNumber = null;
35
+ const maxAttempts = 20;
36
+ const delay = 3000;
37
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
38
+ const queueRes = await fetch(`${queueUrl}api/json`, {
39
+ headers: {
40
+ 'Authorization': `Basic ${auth}`
41
+ }
42
+ });
43
+ const queueData = await queueRes.json();
44
+ if (queueData.executable && queueData.executable.number) {
45
+ buildNumber = queueData.executable.number;
46
+ break;
47
+ }
48
+ logger.log(`Waiting for build to start... (${attempt + 1})`);
49
+ await new Promise(resolve => setTimeout(resolve, delay));
50
+ }
51
+ if (buildNumber) {
52
+ logger.log(`Build started with number: ${buildNumber}`);
53
+ return buildNumber;
54
+ }
55
+ else {
56
+ throw new Error('Failed to get build number.');
57
+ }
58
+ }
59
+ catch (err) {
60
+ throw new Error(`Error triggering Jenkins build: ${err.message}`);
61
+ }
62
+ }
63
+ async waitForBuildToFinish(buildNumber, username, token, jobName, logger) {
64
+ const JENKINS_URL = 'http://172.20.151.119:9090';
65
+ const auth = btoa(`${username}:${token}`);
66
+ const maxAttempts = 40;
67
+ const delay = 5000;
68
+ for (let i = 0; i < maxAttempts; i++) {
69
+ const res = await fetch(`${JENKINS_URL}/job/${jobName}/${buildNumber}/api/json`, {
70
+ headers: {
71
+ 'Authorization': `Basic ${auth}`
72
+ }
73
+ });
74
+ const data = await res.json();
75
+ if (!data.building) {
76
+ const result = data.result;
77
+ if (result === 'SUCCESS') {
78
+ logger.log(`Build #${buildNumber} completed successfully.`);
79
+ return data;
80
+ }
81
+ else {
82
+ throw new Error(`Build #${buildNumber} failed.`);
83
+ }
84
+ }
85
+ logger.log(`Build #${buildNumber} is still running... (${i + 1})`);
86
+ await new Promise(resolve => setTimeout(resolve, delay));
87
+ }
88
+ return null;
89
+ }
90
+ getJobName(env) {
91
+ if (!env) {
92
+ throw new Error('Environment is required to get the job name');
93
+ }
94
+ env = env.toLowerCase();
95
+ const jobNameMap = {
96
+ dev: 'wmbpm-web-dev',
97
+ sit: 'wmbpm-web-sit',
98
+ bat: 'wmbpm-web-bat'
99
+ };
100
+ const jobName = jobNameMap[env];
101
+ if (!jobName) {
102
+ throw new Error(`No job name found for environment: ${env}`);
103
+ }
104
+ return jobName;
105
+ }
106
+ }
107
+ exports.JenkinsManager = JenkinsManager;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Logger = void 0;
30
+ exports.runCommand = runCommand;
31
+ exports.parseEnv = parseEnv;
32
+ const child_process_1 = require("child_process");
33
+ const chalk_1 = __importDefault(require("chalk"));
34
+ const readline = __importStar(require("readline"));
35
+ function runCommand(command, pathToRunIn) {
36
+ return new Promise((resolve, reject) => {
37
+ const child = (0, child_process_1.spawn)(command, {
38
+ stdio: ['inherit', 'pipe', 'pipe'],
39
+ shell: true,
40
+ cwd: pathToRunIn
41
+ });
42
+ let stderrData = '';
43
+ let stdoutData = '';
44
+ child.stdout && child.stdout.on('data', data => {
45
+ stdoutData += data.toString();
46
+ });
47
+ child.stderr && child.stderr.on('data', (data) => {
48
+ stderrData += data.toString();
49
+ });
50
+ child.on('exit', function (code, signal) {
51
+ const isBundleExceededError = stderrData.includes('bundle initial exceeded maximum budget');
52
+ if (code === 0 || isBundleExceededError) {
53
+ resolve();
54
+ }
55
+ else {
56
+ reject(new Error(`Failed to run command "${command}" on path "${pathToRunIn}"`, { cause: stderrData }));
57
+ }
58
+ });
59
+ child.on('error', (err) => {
60
+ reject(new Error(`Failed to run command "${command}" on path "${pathToRunIn}"`, { cause: stderrData }));
61
+ });
62
+ });
63
+ }
64
+ function parseEnv(env) {
65
+ const allEnvs = ['dev', 'sit', 'bat'];
66
+ if (typeof env === 'string' && allEnvs.includes(env.toLowerCase())) {
67
+ return env.toLowerCase();
68
+ }
69
+ throw new Error(`Invalid environment: ${env}. Valid options are: ${allEnvs.join(', ')}.`);
70
+ }
71
+ class Logger {
72
+ loading(msg) {
73
+ this.currentLoadingMsg = msg;
74
+ const spinnerChars = ['|', '/', '-', '\\'];
75
+ let current = 0;
76
+ this.intervalId = setInterval(() => {
77
+ process.stdout.write(`\r${spinnerChars[current]} ${chalk_1.default.yellow(msg)}`);
78
+ current = (current + 1) % spinnerChars.length;
79
+ }, 100);
80
+ }
81
+ log(msg, useDefaultColor = true) {
82
+ this.stopLoading();
83
+ console.log(useDefaultColor ? chalk_1.default.dim(msg) : msg);
84
+ this.loading(this.currentLoadingMsg);
85
+ }
86
+ success(msg) {
87
+ this.stopLoading();
88
+ process.stdout.write(`${chalk_1.default.bold.green('✔ ' + msg)}\n`);
89
+ }
90
+ error(msg) {
91
+ this.stopLoading();
92
+ process.stdout.write(`${chalk_1.default.bold.red('X ' + msg)}\n`);
93
+ }
94
+ asyncLog(loadingMsg) {
95
+ this.loading(loadingMsg);
96
+ return async (promise, successMsg, failedMsg) => {
97
+ try {
98
+ await promise;
99
+ this.success(successMsg);
100
+ }
101
+ catch (err) {
102
+ this.error(failedMsg);
103
+ throw err;
104
+ }
105
+ };
106
+ }
107
+ stopLoading() {
108
+ readline.clearLine(process.stdout, 0);
109
+ readline.cursorTo(process.stdout, 0);
110
+ if (this.intervalId)
111
+ clearInterval(this.intervalId);
112
+ }
113
+ }
114
+ exports.Logger = Logger;
package/cli/index.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const deploy_1 = require("./deploy");
6
+ const program = new commander_1.Command();
7
+ program
8
+ .name("bpm-core")
9
+ .description("BPM Core CLI tool.")
10
+ .version("1.0.0");
11
+ program.addCommand(deploy_1.deployCommand);
12
+ program.parse(process.argv);