@waron97/prbot 3.1.4 → 3.2.1

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.
Files changed (39) hide show
  1. package/README.md +50 -11
  2. package/agrippa-pb.md +375 -0
  3. package/package.json +7 -3
  4. package/src/agrippa/commands/clone.js +29 -13
  5. package/src/agrippa/commands/clonePb.js +107 -0
  6. package/src/agrippa/commands/diff.js +109 -20
  7. package/src/agrippa/commands/init.js +66 -12
  8. package/src/agrippa/commands/initPhase.js +16 -17
  9. package/src/agrippa/commands/pb.js +291 -0
  10. package/src/agrippa/commands/pull.js +122 -16
  11. package/src/agrippa/commands/pullPb.js +54 -0
  12. package/src/agrippa/commands/push.js +112 -48
  13. package/src/agrippa/commands/pushPb.js +87 -0
  14. package/src/agrippa/commands/repair.js +3 -1
  15. package/src/agrippa/index.js +144 -14
  16. package/src/agrippa/lib/api.js +17 -3
  17. package/src/agrippa/lib/checksum.js +3 -1
  18. package/src/agrippa/lib/config.js +2 -2
  19. package/src/agrippa/lib/pbApi.js +71 -0
  20. package/src/agrippa/lib/pbEdit.js +543 -0
  21. package/src/agrippa/lib/pbLayout.js +304 -0
  22. package/src/agrippa/lib/pbModel.js +701 -0
  23. package/src/agrippa/lib/pbPreview.js +153 -0
  24. package/src/agrippa/lib/pbProject.js +401 -0
  25. package/src/agrippa/lib/pbWorkspace.js +30 -0
  26. package/src/agrippa/lib/workspace.js +23 -3
  27. package/src/commands/autopr.js +5 -2
  28. package/src/commands/changelog.js +4 -1
  29. package/src/commands/export.js +3 -3
  30. package/src/commands/exportEmailTemplates.js +25 -15
  31. package/src/commands/exportImperex.js +4 -4
  32. package/src/commands/exportLrp.js +10 -7
  33. package/src/commands/exportPb.js +4 -5
  34. package/src/commands/exportWorkflow.js +27 -14
  35. package/src/commands/init.js +7 -0
  36. package/src/commands/routine.js +7 -5
  37. package/src/index.js +24 -7
  38. package/src/lib/premigrate.js +3 -3
  39. package/src/lib/updateCheck.js +5 -2
@@ -1,20 +1,20 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
- import fetch from 'node-fetch';
3
+ import { confirm, select } from '@inquirer/prompts';
4
4
  import search from '@inquirer/search';
5
- import { select, confirm } from '@inquirer/prompts';
6
- import { getToken } from '../lib/auth.js';
7
- import { execGit } from '../lib/git.js';
5
+ import fetch from 'node-fetch';
8
6
  import { resolveAddonsPath } from '../lib/addons.js';
7
+ import { getToken } from '../lib/auth.js';
9
8
  import { fuzzyMatch } from '../lib/fuzzy.js';
10
- import { log, isSilent } from '../lib/logger.js';
11
- import { verbot } from './ver.js';
9
+ import { execGit } from '../lib/git.js';
10
+ import { isSilent, log } from '../lib/logger.js';
12
11
  import {
13
- readEmailTemplateMappings,
14
- detectEmailRenames,
15
12
  computeMigrationVersion,
13
+ detectEmailRenames,
16
14
  generateEmailPreMigrateScript,
15
+ readEmailTemplateMappings,
17
16
  } from '../lib/premigrate.js';
17
+ import { verbot } from './ver.js';
18
18
 
19
19
  async function getWorkflows(token) {
20
20
  const url = `${process.env.RIP_URL}/symple.workflow/*`;
@@ -93,9 +93,7 @@ async function getModuleChoices() {
93
93
  const ADDONS_PATH = resolveAddonsPath(process.env.ADDONS_PATH);
94
94
  const configDir = path.join(ADDONS_PATH, 'config');
95
95
  const entries = await fs.readdir(configDir, { withFileTypes: true });
96
- return entries
97
- .filter((e) => e.isDirectory())
98
- .map((e) => ({ name: e.name, value: e.name }));
96
+ return entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, value: e.name }));
99
97
  }
100
98
 
101
99
  async function resolveManifestPath(module, ADDONS_PATH) {
@@ -150,7 +148,9 @@ async function exportEmailTemplates(opts) {
150
148
  const templates = (await getEmailTemplates(workflowId, token))
151
149
  .filter((t) => t.template_code)
152
150
  .filter((t) => {
153
- return !excludes.some((ex) => ex === String(t.id) || ex === t.name || ex === t.template_code);
151
+ return !excludes.some(
152
+ (ex) => ex === String(t.id) || ex === t.name || ex === t.template_code
153
+ );
154
154
  });
155
155
 
156
156
  if (!templates.length) {
@@ -187,7 +187,9 @@ async function exportEmailTemplates(opts) {
187
187
  let preMigratePath = null;
188
188
 
189
189
  if (renames.length > 0) {
190
- log(`Renamed XML IDs (${renames.length}): ${renames.map((r) => `${r.oldXmlId} → ${r.newXmlId}`).join(', ')}`);
190
+ log(
191
+ `Renamed XML IDs (${renames.length}): ${renames.map((r) => `${r.oldXmlId} → ${r.newXmlId}`).join(', ')}`
192
+ );
191
193
 
192
194
  let shouldGenerate = opts.autoPremigrate;
193
195
  if (!shouldGenerate && !isSilent()) {
@@ -200,10 +202,18 @@ async function exportEmailTemplates(opts) {
200
202
  if (shouldGenerate) {
201
203
  const manifestPath = await resolveManifestPath(module, ADDONS_PATH);
202
204
  if (!manifestPath) {
203
- log(`Warning: __manifest__.py not found for ${module}, skipping pre-migrate generation`);
205
+ log(
206
+ `Warning: __manifest__.py not found for ${module}, skipping pre-migrate generation`
207
+ );
204
208
  } else {
205
209
  const version = await computeMigrationVersion(manifestPath, bumpLevel);
206
- const migrationDir = path.join(ADDONS_PATH, 'config', module, 'migrations', version);
210
+ const migrationDir = path.join(
211
+ ADDONS_PATH,
212
+ 'config',
213
+ module,
214
+ 'migrations',
215
+ version
216
+ );
207
217
  preMigratePath = path.join(migrationDir, 'pre-migrate.py');
208
218
  await fs.mkdir(migrationDir, { recursive: true });
209
219
  await fs.writeFile(preMigratePath, generateEmailPreMigrateScript(renames, module));
@@ -1,11 +1,11 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
- import fetch from 'node-fetch';
4
3
  import search from '@inquirer/search';
5
- import { getToken } from '../lib/auth.js';
6
- import { execGit } from '../lib/git.js';
4
+ import fetch from 'node-fetch';
7
5
  import { resolveAddonsPath } from '../lib/addons.js';
6
+ import { getToken } from '../lib/auth.js';
8
7
  import { fuzzyMatch } from '../lib/fuzzy.js';
8
+ import { execGit } from '../lib/git.js';
9
9
  import { log } from '../lib/logger.js';
10
10
 
11
11
  const IMPEREX_REL = 'sorgenia_imperex_metadata/migrations/0.0.0/imperex';
@@ -89,7 +89,7 @@ async function exportImperex(opts) {
89
89
  }
90
90
  await execGit(
91
91
  ['commit', '-m', `[IMP][sorgenia_imperex_metadata] update ${model} record`],
92
- ADDONS_PATH,
92
+ ADDONS_PATH
93
93
  );
94
94
  log('Committed.');
95
95
  }
@@ -1,10 +1,10 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
- import fetch from 'node-fetch';
4
3
  import search from '@inquirer/search';
4
+ import fetch from 'node-fetch';
5
+ import { resolveAddonsPath } from '../lib/addons.js';
5
6
  import { getToken } from '../lib/auth.js';
6
7
  import { execGit } from '../lib/git.js';
7
- import { resolveAddonsPath } from '../lib/addons.js';
8
8
  import { log } from '../lib/logger.js';
9
9
 
10
10
  function getSymphonyBase() {
@@ -17,9 +17,7 @@ function getSymphonyBase() {
17
17
  async function fetchProcesses(token, nameFilter, signal) {
18
18
  const base = getSymphonyBase();
19
19
  const size = nameFilter ? 20 : 12;
20
- const params = encodeURIComponent(
21
- JSON.stringify({ page: 1, size, sorters: [], filters: [] })
22
- );
20
+ const params = encodeURIComponent(JSON.stringify({ page: 1, size, sorters: [], filters: [] }));
23
21
  const otherfilters = encodeURIComponent(
24
22
  JSON.stringify([
25
23
  { field: 'id', type: '=', value: null },
@@ -28,7 +26,9 @@ async function fetchProcesses(token, nameFilter, signal) {
28
26
  { field: 'latestVersion', type: '=', value: true },
29
27
  ])
30
28
  );
31
- const othersort = encodeURIComponent(JSON.stringify({ field: 'lastModifiedDate', dir: 'desc' }));
29
+ const othersort = encodeURIComponent(
30
+ JSON.stringify({ field: 'lastModifiedDate', dir: 'desc' })
31
+ );
32
32
  const url = `${base}/symphony/restInfo/ajax/tabulator?params=${params}&connector=SymphBpmnFileTabCon&otherfilters=${otherfilters}&card=true&othersort=${othersort}`;
33
33
 
34
34
  const response = await fetch(url, {
@@ -146,7 +146,10 @@ async function exportLrp(opts) {
146
146
 
147
147
  if (opts.commit !== false) {
148
148
  await execGit(['add', savePath], ADDONS_PATH);
149
- await execGit(['commit', '-m', '[IMP][.cloudbuild] Update long running process'], ADDONS_PATH);
149
+ await execGit(
150
+ ['commit', '-m', '[IMP][.cloudbuild] Update long running process'],
151
+ ADDONS_PATH
152
+ );
150
153
  log('Committed.');
151
154
  }
152
155
  }
@@ -1,11 +1,11 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
- import fetch from 'node-fetch';
4
3
  import search from '@inquirer/search';
5
- import { getToken } from '../lib/auth.js';
6
- import { execGit } from '../lib/git.js';
4
+ import fetch from 'node-fetch';
7
5
  import { resolveAddonsPath } from '../lib/addons.js';
6
+ import { getToken } from '../lib/auth.js';
8
7
  import { fuzzyMatch } from '../lib/fuzzy.js';
8
+ import { execGit } from '../lib/git.js';
9
9
  import { log } from '../lib/logger.js';
10
10
 
11
11
  async function getProcessList(token) {
@@ -57,8 +57,7 @@ async function pollExportResult(guid, requestTime, token) {
57
57
  const { data } = await response.json();
58
58
  const match = data.find(
59
59
  (item) =>
60
- item.customResponse?.guid === guid &&
61
- new Date(item.createdDate).getTime() >= cutoff
60
+ item.customResponse?.guid === guid && new Date(item.createdDate).getTime() >= cutoff
62
61
  );
63
62
 
64
63
  if (!match) continue;
@@ -1,27 +1,25 @@
1
1
  import fs from 'fs/promises';
2
2
  import path from 'path';
3
+ import { confirm, select } from '@inquirer/prompts';
3
4
  import search from '@inquirer/search';
4
- import { select, confirm } from '@inquirer/prompts';
5
5
  import { resolveAddonsPath } from '../lib/addons.js';
6
6
  import { fuzzyMatch } from '../lib/fuzzy.js';
7
7
  import { execGit } from '../lib/git.js';
8
- import { log, isSilent } from '../lib/logger.js';
9
- import { runPr } from './pr.js';
10
- import { verbot } from './ver.js';
8
+ import { isSilent, log } from '../lib/logger.js';
11
9
  import {
12
- readWorkflowMappings,
13
- detectRenames,
14
10
  computeMigrationVersion,
11
+ detectRenames,
15
12
  generatePreMigrateScript,
13
+ readWorkflowMappings,
16
14
  } from '../lib/premigrate.js';
15
+ import { runPr } from './pr.js';
16
+ import { verbot } from './ver.js';
17
17
 
18
18
  async function getModuleChoices() {
19
19
  const ADDONS_PATH = resolveAddonsPath(process.env.ADDONS_PATH);
20
20
  const configDir = path.join(ADDONS_PATH, 'config');
21
21
  const entries = await fs.readdir(configDir, { withFileTypes: true });
22
- return entries
23
- .filter((e) => e.isDirectory())
24
- .map((e) => ({ name: e.name, value: e.name }));
22
+ return entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, value: e.name }));
25
23
  }
26
24
 
27
25
  async function resolveManifestPath(module, ADDONS_PATH) {
@@ -82,10 +80,14 @@ async function exportWorkflow(opts) {
82
80
 
83
81
  if (hasRenames) {
84
82
  if (renames.stateCodes.length > 0) {
85
- log(`Renamed state_codes (${renames.stateCodes.length}): ${renames.stateCodes.join(', ')}`);
83
+ log(
84
+ `Renamed state_codes (${renames.stateCodes.length}): ${renames.stateCodes.join(', ')}`
85
+ );
86
86
  }
87
87
  if (renames.phaseCodes.length > 0) {
88
- log(`Renamed phase_codes (${renames.phaseCodes.length}): ${renames.phaseCodes.join(', ')}`);
88
+ log(
89
+ `Renamed phase_codes (${renames.phaseCodes.length}): ${renames.phaseCodes.join(', ')}`
90
+ );
89
91
  }
90
92
 
91
93
  let shouldGenerate = opts.autoPremigrate;
@@ -99,13 +101,24 @@ async function exportWorkflow(opts) {
99
101
  if (shouldGenerate) {
100
102
  const manifestPath = await resolveManifestPath(module, ADDONS_PATH);
101
103
  if (!manifestPath) {
102
- log(`Warning: __manifest__.py not found for ${module}, skipping pre-migrate generation`);
104
+ log(
105
+ `Warning: __manifest__.py not found for ${module}, skipping pre-migrate generation`
106
+ );
103
107
  } else {
104
108
  const version = await computeMigrationVersion(manifestPath, bumpLevel);
105
- const migrationDir = path.join(ADDONS_PATH, 'config', module, 'migrations', version);
109
+ const migrationDir = path.join(
110
+ ADDONS_PATH,
111
+ 'config',
112
+ module,
113
+ 'migrations',
114
+ version
115
+ );
106
116
  preMigratePath = path.join(migrationDir, 'pre-migrate.py');
107
117
  await fs.mkdir(migrationDir, { recursive: true });
108
- await fs.writeFile(preMigratePath, generatePreMigrateScript(renames.stateCodes, renames.phaseCodes));
118
+ await fs.writeFile(
119
+ preMigratePath,
120
+ generatePreMigrateScript(renames.stateCodes, renames.phaseCodes)
121
+ );
109
122
  log(`Wrote pre-migrate: ${preMigratePath}`);
110
123
  }
111
124
  }
@@ -123,6 +123,13 @@ async function init() {
123
123
  existing.IMPORTEXPORT_URL ??
124
124
  'https://sorgenia-test-02.symple.cloud/api/importexport/v1/',
125
125
  },
126
+ {
127
+ type: 'input',
128
+ name: 'PB_URL',
129
+ message: 'Process Builder URL:',
130
+ default:
131
+ existing.PB_URL ?? 'https://sorgenia-test-02.symple.cloud/api/processbuilder/v1',
132
+ },
126
133
  ]);
127
134
 
128
135
  if (!answers.KC_PASSWORD && existing.KC_PASSWORD) {
@@ -1,14 +1,14 @@
1
1
  import { existsSync, readFileSync } from 'fs';
2
2
  import path from 'path';
3
- import { parse } from 'yaml';
4
3
  import { select } from '@inquirer/prompts';
4
+ import { parse } from 'yaml';
5
5
  import { CONFIG_DIR } from '../config.js';
6
6
  import { setSilent } from '../lib/logger.js';
7
- import { exportWorkflow } from './exportWorkflow.js';
8
- import { exportPb } from './exportPb.js';
9
- import { exportImperex } from './exportImperex.js';
10
7
  import { exportEmailTemplates } from './exportEmailTemplates.js';
8
+ import { exportImperex } from './exportImperex.js';
11
9
  import { exportLrp } from './exportLrp.js';
10
+ import { exportPb } from './exportPb.js';
11
+ import { exportWorkflow } from './exportWorkflow.js';
12
12
 
13
13
  const ROUTINES_FILE = path.join(CONFIG_DIR, 'routines.yaml');
14
14
  const WORKSPACE_FILE = 'agrippa.yaml';
@@ -84,7 +84,9 @@ async function routine() {
84
84
  const routines = loadRoutines();
85
85
 
86
86
  if (!routines.length) {
87
- console.log('No routines defined. Create ~/.config/prbot/routines.yaml or add routines: to agrippa.yaml.');
87
+ console.log(
88
+ 'No routines defined. Create ~/.config/prbot/routines.yaml or add routines: to agrippa.yaml.'
89
+ );
88
90
  return;
89
91
  }
90
92
 
package/src/index.js CHANGED
@@ -5,23 +5,34 @@ import { configDotenv } from 'dotenv';
5
5
  import { autopr } from './commands/autopr.js';
6
6
  import { changelog } from './commands/changelog.js';
7
7
  import { commit } from './commands/commit.js';
8
- import { exportPb, exportRip, exportImperex, exportEmailTemplates, exportWorkflow, exportLrp } from './commands/export.js';
9
- import { routine } from './commands/routine.js';
8
+ import {
9
+ exportEmailTemplates,
10
+ exportImperex,
11
+ exportLrp,
12
+ exportPb,
13
+ exportRip,
14
+ exportWorkflow,
15
+ } from './commands/export.js';
10
16
  import { init } from './commands/init.js';
11
17
  import { main as prMain } from './commands/pr.js';
18
+ import { routine } from './commands/routine.js';
12
19
  import { verbot } from './commands/ver.js';
13
20
  import { CONFIG_FILE } from './config.js';
14
- import { checkForUpdate, currentVersion } from './lib/updateCheck.js';
15
21
  import { setSilent } from './lib/logger.js';
22
+ import { checkForUpdate, currentVersion } from './lib/updateCheck.js';
16
23
 
17
24
  configDotenv({ path: CONFIG_FILE, quiet: true });
18
25
 
19
26
  let _updateAvailable = null;
20
- checkForUpdate().then((v) => { _updateAvailable = v; });
27
+ checkForUpdate().then((v) => {
28
+ _updateAvailable = v;
29
+ });
21
30
 
22
31
  process.on('exit', () => {
23
32
  if (_updateAvailable) {
24
- console.log(`\nUpdate available: ${currentVersion} → ${_updateAvailable}\nRun: prbot update`);
33
+ console.log(
34
+ `\nUpdate available: ${currentVersion} → ${_updateAvailable}\nRun: prbot update`
35
+ );
25
36
  }
26
37
  });
27
38
 
@@ -98,7 +109,10 @@ exportCmd
98
109
  .option('-b, --bump <level>', 'Version bump level (patch, minor, major)')
99
110
  .option('-m, --module <id>', 'Module/workflow ID to export (skips interactive selection)')
100
111
  .option('-s, --silent', 'Suppress all output and swallow errors')
101
- .option('--auto-premigrate', 'Auto-generate pre-migrate script when XML ID renames are detected (no prompt)')
112
+ .option(
113
+ '--auto-premigrate',
114
+ 'Auto-generate pre-migrate script when XML ID renames are detected (no prompt)'
115
+ )
102
116
  .action((opts) => {
103
117
  if (opts.silent) setSilent(true);
104
118
  exportWorkflow(opts).catch((err) => {
@@ -149,7 +163,10 @@ exportCmd
149
163
  .option('-m, --module <name>', 'module directory name (skip prompt)')
150
164
  .option('-w, --workflow <value>', 'workflow name or id (skip prompt)')
151
165
  .option('-s, --silent', 'Suppress all output and swallow errors')
152
- .option('--auto-premigrate', 'Auto-generate pre-migrate script when XML ID renames are detected (no prompt)')
166
+ .option(
167
+ '--auto-premigrate',
168
+ 'Auto-generate pre-migrate script when XML ID renames are detected (no prompt)'
169
+ )
153
170
  .action((opts) => {
154
171
  if (opts.silent) setSilent(true);
155
172
  exportEmailTemplates(opts).catch((err) => {
@@ -115,7 +115,7 @@ function generatePreMigrateScript(stateCodes, phaseCodes) {
115
115
  ' env.cr.execute(',
116
116
  ' "DELETE FROM symple_triplet_phase_result WHERE state_code IN %s",',
117
117
  ' (state_codes,),',
118
- ' )',
118
+ ' )'
119
119
  );
120
120
  }
121
121
 
@@ -132,7 +132,7 @@ function generatePreMigrateScript(stateCodes, phaseCodes) {
132
132
  ' env.cr.execute(',
133
133
  ' "DELETE FROM symple_triplet_phase WHERE phase_code IN %s",',
134
134
  ' (phase_codes,),',
135
- ' )',
135
+ ' )'
136
136
  );
137
137
  }
138
138
 
@@ -198,7 +198,7 @@ function generateEmailPreMigrateScript(renames, module) {
198
198
  ' env.cr.execute(',
199
199
  ` "UPDATE ir_model_data SET name = %s WHERE name = %s AND model = %s AND module = %s",`,
200
200
  ` (new_name, old_name, "mail.template", "${module}"),`,
201
- ' )',
201
+ ' )'
202
202
  );
203
203
 
204
204
  return lines.join('\n') + '\n';
@@ -1,5 +1,5 @@
1
1
  import { execFile } from 'child_process';
2
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
3
  import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { CONFIG_DIR } from '../config.js';
@@ -36,7 +36,10 @@ function readCache() {
36
36
  function writeCache(latestVersion) {
37
37
  try {
38
38
  mkdirSync(CONFIG_DIR, { recursive: true });
39
- writeFileSync(CACHE_FILE, JSON.stringify({ checkedAt: new Date().toISOString(), latestVersion }));
39
+ writeFileSync(
40
+ CACHE_FILE,
41
+ JSON.stringify({ checkedAt: new Date().toISOString(), latestVersion })
42
+ );
40
43
  } catch {
41
44
  // non-critical
42
45
  }