@burgan-tech/vnext-workflow-cli 1.0.1 → 1.0.2
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 +244 -82
- package/bin/workflow.js +0 -0
- package/package.json +5 -5
- package/src/commands/check.js +62 -22
- package/src/commands/config.js +5 -6
- package/src/commands/csx.js +125 -44
- package/src/commands/reset.js +198 -80
- package/src/commands/sync.js +189 -107
- package/src/commands/update.js +217 -99
- package/src/lib/api.js +52 -34
- package/src/lib/config.js +43 -5
- package/src/lib/csx.js +130 -57
- package/src/lib/discover.js +131 -29
- package/src/lib/vnextConfig.js +124 -0
- package/src/lib/workflow.js +86 -39
package/src/lib/workflow.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
const fs = require('fs').promises;
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { glob } = require('glob');
|
|
4
|
+
const { publishComponent } = require('./api');
|
|
4
5
|
const { getInstanceId, deleteWorkflow } = require('./db');
|
|
5
|
-
const {
|
|
6
|
+
const { getComponentTypes } = require('./vnextConfig');
|
|
7
|
+
const { discoverComponents, findJsonInComponent } = require('./discover');
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
10
|
+
* Gets key and version values from JSON file
|
|
11
|
+
* @param {string} jsonPath - JSON file path
|
|
12
|
+
* @returns {Promise<Object>} Metadata object
|
|
9
13
|
*/
|
|
10
14
|
async function getJsonMetadata(jsonPath) {
|
|
11
15
|
const content = await fs.readFile(jsonPath, 'utf8');
|
|
@@ -20,11 +24,38 @@ async function getJsonMetadata(jsonPath) {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
|
-
*
|
|
27
|
+
* Detects component type from file path based on vnext.config.json paths
|
|
28
|
+
* @param {string} jsonPath - JSON file path
|
|
29
|
+
* @param {string} projectRoot - Project root folder
|
|
30
|
+
* @returns {string} Component type (sys-flows, sys-tasks, etc.)
|
|
24
31
|
*/
|
|
25
|
-
function
|
|
32
|
+
function detectComponentType(jsonPath, projectRoot) {
|
|
26
33
|
const pathLower = jsonPath.toLowerCase();
|
|
27
34
|
|
|
35
|
+
try {
|
|
36
|
+
const componentTypes = getComponentTypes(projectRoot);
|
|
37
|
+
|
|
38
|
+
// Check each component type folder
|
|
39
|
+
for (const [type, folderName] of Object.entries(componentTypes)) {
|
|
40
|
+
const folderPattern = `/${folderName.toLowerCase()}/`;
|
|
41
|
+
if (pathLower.includes(folderPattern)) {
|
|
42
|
+
// Map to flow type
|
|
43
|
+
switch (type.toLowerCase()) {
|
|
44
|
+
case 'workflows': return 'sys-flows';
|
|
45
|
+
case 'tasks': return 'sys-tasks';
|
|
46
|
+
case 'schemas': return 'sys-schemas';
|
|
47
|
+
case 'views': return 'sys-views';
|
|
48
|
+
case 'functions': return 'sys-functions';
|
|
49
|
+
case 'extensions': return 'sys-extensions';
|
|
50
|
+
default: return `sys-${type.toLowerCase()}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
// Fallback to path-based detection
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Fallback: detect from path directly
|
|
28
59
|
if (pathLower.includes('/workflows/')) return 'sys-flows';
|
|
29
60
|
if (pathLower.includes('/tasks/')) return 'sys-tasks';
|
|
30
61
|
if (pathLower.includes('/schemas/')) return 'sys-schemas';
|
|
@@ -36,63 +67,67 @@ function detectFlowFromPath(jsonPath) {
|
|
|
36
67
|
}
|
|
37
68
|
|
|
38
69
|
/**
|
|
39
|
-
*
|
|
70
|
+
* Processes a single component (DB check → delete if exists → publish)
|
|
71
|
+
* @param {string} jsonPath - JSON file path
|
|
72
|
+
* @param {Object} dbConfig - Database configuration
|
|
73
|
+
* @param {string} baseUrl - API base URL
|
|
74
|
+
* @param {string} projectRoot - Project root folder
|
|
75
|
+
* @returns {Promise<Object>} Process result
|
|
40
76
|
*/
|
|
41
|
-
async function
|
|
77
|
+
async function processComponent(jsonPath, dbConfig, baseUrl, projectRoot) {
|
|
42
78
|
const metadata = await getJsonMetadata(jsonPath);
|
|
43
79
|
|
|
44
80
|
if (!metadata.key || !metadata.version) {
|
|
45
|
-
throw new Error('
|
|
81
|
+
throw new Error('No key or version found in JSON');
|
|
46
82
|
}
|
|
47
83
|
|
|
48
|
-
const
|
|
84
|
+
const componentType = detectComponentType(jsonPath, projectRoot);
|
|
85
|
+
const flow = metadata.flow || componentType;
|
|
49
86
|
|
|
50
|
-
// 1.
|
|
51
|
-
const
|
|
87
|
+
// 1. Check if exists in DB
|
|
88
|
+
const existingId = await getInstanceId(dbConfig, flow, metadata.key, metadata.version);
|
|
52
89
|
|
|
53
|
-
// 2.
|
|
54
|
-
|
|
55
|
-
|
|
90
|
+
// 2. If exists, delete first
|
|
91
|
+
let wasDeleted = false;
|
|
92
|
+
if (existingId) {
|
|
93
|
+
await deleteWorkflow(dbConfig, flow, existingId);
|
|
94
|
+
wasDeleted = true;
|
|
56
95
|
}
|
|
57
96
|
|
|
58
|
-
// 3.
|
|
59
|
-
const
|
|
60
|
-
const apiVersion = apiConfig.version;
|
|
61
|
-
|
|
62
|
-
const postResult = await postWorkflow(apiUrl, apiVersion, flow, metadata.data);
|
|
63
|
-
const newInstanceId = postResult.id || postResult.Id;
|
|
97
|
+
// 3. Publish to API
|
|
98
|
+
const result = await publishComponent(baseUrl, metadata.data);
|
|
64
99
|
|
|
65
|
-
if (!
|
|
66
|
-
throw new Error(
|
|
100
|
+
if (!result.success) {
|
|
101
|
+
throw new Error(result.error);
|
|
67
102
|
}
|
|
68
103
|
|
|
69
|
-
// 4. Aktif et
|
|
70
|
-
await activateWorkflow(apiUrl, apiVersion, flow, newInstanceId, metadata.version);
|
|
71
|
-
|
|
72
104
|
return {
|
|
73
105
|
key: metadata.key,
|
|
74
106
|
version: metadata.version,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
107
|
+
componentType: componentType,
|
|
108
|
+
wasDeleted: wasDeleted,
|
|
109
|
+
success: true
|
|
78
110
|
};
|
|
79
111
|
}
|
|
80
112
|
|
|
81
113
|
/**
|
|
82
|
-
*
|
|
114
|
+
* Finds changed JSON files in Git
|
|
115
|
+
* Only returns files within PROJECT_ROOT
|
|
116
|
+
* @param {string} projectRoot - Project root folder
|
|
117
|
+
* @returns {Promise<string[]>} Changed JSON file paths
|
|
83
118
|
*/
|
|
84
119
|
async function getGitChangedJson(projectRoot) {
|
|
85
120
|
const { exec } = require('child_process');
|
|
86
121
|
const util = require('util');
|
|
87
122
|
const execPromise = util.promisify(exec);
|
|
88
|
-
const
|
|
123
|
+
const fsSync = require('fs');
|
|
89
124
|
|
|
90
125
|
try {
|
|
91
|
-
//
|
|
126
|
+
// Find git root
|
|
92
127
|
const { stdout: gitRoot } = await execPromise('git rev-parse --show-toplevel', { cwd: projectRoot });
|
|
93
128
|
const gitRootDir = gitRoot.trim();
|
|
94
129
|
|
|
95
|
-
//
|
|
130
|
+
// Run git status from git root
|
|
96
131
|
const { stdout } = await execPromise('git status --porcelain', { cwd: gitRootDir });
|
|
97
132
|
const lines = stdout.split('\n').filter(Boolean);
|
|
98
133
|
|
|
@@ -108,12 +143,13 @@ async function getGitChangedJson(projectRoot) {
|
|
|
108
143
|
return path.normalize(fullPath);
|
|
109
144
|
})
|
|
110
145
|
.filter(file => {
|
|
111
|
-
//
|
|
146
|
+
// Filter workflow JSONs and only those in project
|
|
112
147
|
const fileName = path.basename(file);
|
|
113
148
|
return file.endsWith('.json') &&
|
|
114
149
|
!fileName.includes('package') &&
|
|
115
150
|
!fileName.includes('config') &&
|
|
116
|
-
|
|
151
|
+
!fileName.includes('.diagram.') &&
|
|
152
|
+
fsSync.existsSync(file) &&
|
|
117
153
|
file.startsWith(path.normalize(projectRoot));
|
|
118
154
|
});
|
|
119
155
|
|
|
@@ -124,22 +160,34 @@ async function getGitChangedJson(projectRoot) {
|
|
|
124
160
|
}
|
|
125
161
|
|
|
126
162
|
/**
|
|
127
|
-
*
|
|
163
|
+
* Finds all JSON files in a component folder
|
|
164
|
+
* @param {string} componentDir - Component folder
|
|
165
|
+
* @returns {Promise<string[]>} JSON file paths
|
|
128
166
|
*/
|
|
129
167
|
async function findAllJsonInComponent(componentDir) {
|
|
130
168
|
const pattern = path.join(componentDir, '**/*.json');
|
|
131
169
|
const files = await glob(pattern, {
|
|
132
|
-
ignore: [
|
|
170
|
+
ignore: [
|
|
171
|
+
'**/.meta/**',
|
|
172
|
+
'**/.meta',
|
|
173
|
+
'**/*.diagram.json',
|
|
174
|
+
'**/package*.json',
|
|
175
|
+
'**/*config*.json'
|
|
176
|
+
]
|
|
133
177
|
});
|
|
134
178
|
return files;
|
|
135
179
|
}
|
|
136
180
|
|
|
137
181
|
/**
|
|
138
|
-
*
|
|
182
|
+
* Finds all JSON files in discovered components ONLY
|
|
183
|
+
* Does NOT scan folders outside of paths definition
|
|
184
|
+
* @param {Object} discovered - Discovered component folders
|
|
185
|
+
* @returns {Promise<string[]>} JSON file paths
|
|
139
186
|
*/
|
|
140
187
|
async function findAllJson(discovered) {
|
|
141
188
|
const allJsons = [];
|
|
142
189
|
|
|
190
|
+
// Only scan folders that were discovered from paths
|
|
143
191
|
for (const component in discovered) {
|
|
144
192
|
const componentDir = discovered[component];
|
|
145
193
|
if (componentDir) {
|
|
@@ -153,10 +201,9 @@ async function findAllJson(discovered) {
|
|
|
153
201
|
|
|
154
202
|
module.exports = {
|
|
155
203
|
getJsonMetadata,
|
|
156
|
-
|
|
157
|
-
|
|
204
|
+
detectComponentType,
|
|
205
|
+
processComponent,
|
|
158
206
|
getGitChangedJson,
|
|
159
207
|
findAllJsonInComponent,
|
|
160
208
|
findAllJson
|
|
161
209
|
};
|
|
162
|
-
|