@aifabrix/builder 2.11.0 → 2.20.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/.cursor/rules/project-rules.mdc +194 -0
- package/README.md +12 -0
- package/lib/api/applications.api.js +164 -0
- package/lib/api/auth.api.js +304 -0
- package/lib/api/datasources-core.api.js +87 -0
- package/lib/api/datasources-extended.api.js +117 -0
- package/lib/api/datasources.api.js +13 -0
- package/lib/api/deployments.api.js +126 -0
- package/lib/api/environments.api.js +245 -0
- package/lib/api/external-systems.api.js +251 -0
- package/lib/api/index.js +221 -0
- package/lib/api/pipeline.api.js +234 -0
- package/lib/api/types/applications.types.js +136 -0
- package/lib/api/types/auth.types.js +218 -0
- package/lib/api/types/datasources.types.js +272 -0
- package/lib/api/types/deployments.types.js +184 -0
- package/lib/api/types/environments.types.js +197 -0
- package/lib/api/types/external-systems.types.js +244 -0
- package/lib/api/types/pipeline.types.js +125 -0
- package/lib/app-list.js +5 -7
- package/lib/app-rotate-secret.js +4 -10
- package/lib/commands/login.js +19 -12
- package/lib/datasource-deploy.js +7 -30
- package/lib/datasource-list.js +9 -6
- package/lib/deployer.js +103 -135
- package/lib/environment-deploy.js +15 -26
- package/lib/external-system-deploy.js +12 -39
- package/lib/external-system-download.js +5 -13
- package/lib/external-system-test.js +9 -12
- package/lib/utils/app-register-api.js +5 -10
- package/lib/utils/deployment-errors.js +88 -6
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ const fsSync = require('fs');
|
|
|
14
14
|
const path = require('path');
|
|
15
15
|
const yaml = require('js-yaml');
|
|
16
16
|
const chalk = require('chalk');
|
|
17
|
-
const {
|
|
17
|
+
const { testDatasourceViaPipeline } = require('./api/pipeline.api');
|
|
18
18
|
const { getDeploymentAuth } = require('./utils/token-manager');
|
|
19
19
|
const { getDataplaneUrl } = require('./datasource-deploy');
|
|
20
20
|
const { getConfig } = require('./config');
|
|
@@ -270,7 +270,7 @@ async function retryApiCall(fn, maxRetries = 3, backoffMs = 1000) {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
/**
|
|
273
|
-
* Calls pipeline test endpoint
|
|
273
|
+
* Calls pipeline test endpoint using centralized API client
|
|
274
274
|
* @async
|
|
275
275
|
* @param {string} systemKey - System key
|
|
276
276
|
* @param {string} datasourceKey - Datasource key
|
|
@@ -281,17 +281,14 @@ async function retryApiCall(fn, maxRetries = 3, backoffMs = 1000) {
|
|
|
281
281
|
* @returns {Promise<Object>} Test response
|
|
282
282
|
*/
|
|
283
283
|
async function callPipelineTestEndpoint(systemKey, datasourceKey, payloadTemplate, dataplaneUrl, authConfig, timeout = 30000) {
|
|
284
|
-
const endpoint = `${dataplaneUrl}/api/v1/pipeline/${systemKey}/${datasourceKey}/test`;
|
|
285
|
-
|
|
286
284
|
const response = await retryApiCall(async() => {
|
|
287
|
-
return await
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
authConfig.token
|
|
285
|
+
return await testDatasourceViaPipeline(
|
|
286
|
+
dataplaneUrl,
|
|
287
|
+
systemKey,
|
|
288
|
+
datasourceKey,
|
|
289
|
+
authConfig,
|
|
290
|
+
{ payloadTemplate },
|
|
291
|
+
{ timeout }
|
|
295
292
|
);
|
|
296
293
|
});
|
|
297
294
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const chalk = require('chalk');
|
|
12
12
|
const logger = require('./logger');
|
|
13
|
-
const {
|
|
13
|
+
const { registerApplication } = require('../api/applications.api');
|
|
14
14
|
const { formatApiError } = require('./api-error-handler');
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -23,14 +23,9 @@ const { formatApiError } = require('./api-error-handler');
|
|
|
23
23
|
* @returns {Promise<Object>} API response
|
|
24
24
|
*/
|
|
25
25
|
async function callRegisterApi(apiUrl, token, environment, registrationData) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
method: 'POST',
|
|
30
|
-
body: JSON.stringify(registrationData)
|
|
31
|
-
},
|
|
32
|
-
token
|
|
33
|
-
);
|
|
26
|
+
// Use centralized API client
|
|
27
|
+
const authConfig = { type: 'bearer', token: token };
|
|
28
|
+
const response = await registerApplication(apiUrl, environment, authConfig, registrationData);
|
|
34
29
|
|
|
35
30
|
if (!response.success) {
|
|
36
31
|
const formattedError = response.formattedError || formatApiError(response);
|
|
@@ -48,7 +43,7 @@ async function callRegisterApi(apiUrl, token, environment, registrationData) {
|
|
|
48
43
|
}
|
|
49
44
|
|
|
50
45
|
// Handle API response structure:
|
|
51
|
-
//
|
|
46
|
+
// registerApplication returns: { success: true, data: <API response> }
|
|
52
47
|
// API response can be:
|
|
53
48
|
// 1. Direct format: { application: {...}, credentials: {...} }
|
|
54
49
|
// 2. Wrapped format: { success: true, data: { application: {...}, credentials: {...} } }
|
|
@@ -18,8 +18,17 @@ const { parseErrorResponse } = require('./api-error-handler');
|
|
|
18
18
|
* @returns {Object} Structured error information
|
|
19
19
|
*/
|
|
20
20
|
function handleDeploymentError(error) {
|
|
21
|
+
if (!error) {
|
|
22
|
+
return {
|
|
23
|
+
message: 'Unknown error',
|
|
24
|
+
code: 'UNKNOWN',
|
|
25
|
+
timeout: false,
|
|
26
|
+
status: undefined,
|
|
27
|
+
data: undefined
|
|
28
|
+
};
|
|
29
|
+
}
|
|
21
30
|
const safeError = {
|
|
22
|
-
message: error.message,
|
|
31
|
+
message: error.message || 'Unknown error',
|
|
23
32
|
code: error.code || 'UNKNOWN',
|
|
24
33
|
timeout: error.code === 'ECONNABORTED',
|
|
25
34
|
status: error.status || error.response?.status,
|
|
@@ -42,6 +51,38 @@ function handleDeploymentError(error) {
|
|
|
42
51
|
* @throws {Error} User-friendly error message
|
|
43
52
|
*/
|
|
44
53
|
async function handleDeploymentErrors(error, appName, url, alreadyLogged = false) {
|
|
54
|
+
// For validation errors (like URL validation), just re-throw them directly
|
|
55
|
+
// They already have user-friendly messages
|
|
56
|
+
// Handle both Error objects and strings
|
|
57
|
+
let errorMessage = '';
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
errorMessage = error.message || '';
|
|
60
|
+
} else if (typeof error === 'string') {
|
|
61
|
+
errorMessage = error;
|
|
62
|
+
} else if (error && typeof error === 'object' && error.message) {
|
|
63
|
+
errorMessage = error.message;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (errorMessage && (
|
|
67
|
+
errorMessage.includes('Controller URL must use HTTPS') ||
|
|
68
|
+
errorMessage.includes('Invalid environment key') ||
|
|
69
|
+
errorMessage.includes('Environment key is required') ||
|
|
70
|
+
errorMessage.includes('Authentication configuration is required') ||
|
|
71
|
+
errorMessage.includes('Invalid controller URL format') ||
|
|
72
|
+
errorMessage.includes('Controller URL is required')
|
|
73
|
+
)) {
|
|
74
|
+
// If error is a string, convert to Error object
|
|
75
|
+
if (typeof error === 'string') {
|
|
76
|
+
throw new Error(error);
|
|
77
|
+
}
|
|
78
|
+
// If it's already an Error object, re-throw it directly
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
// Otherwise, create a new Error with the message
|
|
83
|
+
throw new Error(errorMessage);
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
// Log to audit log if not already logged
|
|
46
87
|
if (!alreadyLogged) {
|
|
47
88
|
try {
|
|
@@ -63,7 +104,17 @@ async function handleDeploymentErrors(error, appName, url, alreadyLogged = false
|
|
|
63
104
|
|
|
64
105
|
// Ensure errorData is not undefined before parsing
|
|
65
106
|
// If errorData is undefined, use the error message instead
|
|
66
|
-
|
|
107
|
+
let errorResponse = errorData !== undefined ? errorData : safeError.message;
|
|
108
|
+
|
|
109
|
+
// Ensure errorResponse is a string or object, not an Error object
|
|
110
|
+
if (errorResponse instanceof Error) {
|
|
111
|
+
errorResponse = errorResponse.message || 'Unknown error occurred';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Ensure errorResponse is not null or undefined
|
|
115
|
+
if (errorResponse === null || errorResponse === undefined) {
|
|
116
|
+
errorResponse = safeError.message || 'Unknown error occurred';
|
|
117
|
+
}
|
|
67
118
|
|
|
68
119
|
// Determine if this is a network error
|
|
69
120
|
const isNetworkError = safeError.code === 'ECONNREFUSED' ||
|
|
@@ -72,13 +123,44 @@ async function handleDeploymentErrors(error, appName, url, alreadyLogged = false
|
|
|
72
123
|
safeError.timeout;
|
|
73
124
|
|
|
74
125
|
// Parse error using error handler
|
|
75
|
-
|
|
126
|
+
let parsedError;
|
|
127
|
+
try {
|
|
128
|
+
parsedError = parseErrorResponse(errorResponse, safeError.status || 0, isNetworkError);
|
|
129
|
+
// Ensure parsedError is a valid object
|
|
130
|
+
if (!parsedError || typeof parsedError !== 'object') {
|
|
131
|
+
throw new Error('parseErrorResponse returned invalid result');
|
|
132
|
+
}
|
|
133
|
+
} catch (parseErr) {
|
|
134
|
+
// If parsing fails, use the safe error message
|
|
135
|
+
parsedError = {
|
|
136
|
+
message: safeError.message || 'Unknown error occurred',
|
|
137
|
+
formatted: safeError.message || 'Unknown error occurred',
|
|
138
|
+
data: undefined
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Ensure parsedError is always a valid object with required properties
|
|
143
|
+
if (!parsedError || typeof parsedError !== 'object') {
|
|
144
|
+
parsedError = {
|
|
145
|
+
message: safeError.message || 'Unknown error occurred',
|
|
146
|
+
formatted: safeError.message || 'Unknown error occurred',
|
|
147
|
+
data: undefined
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Ensure we have a message - handle case where parsedError.message might be undefined
|
|
152
|
+
const finalErrorMessage = (parsedError && parsedError.message) ? parsedError.message : (safeError.message || 'Unknown error occurred');
|
|
153
|
+
|
|
154
|
+
// Validate finalErrorMessage is a string
|
|
155
|
+
if (typeof finalErrorMessage !== 'string') {
|
|
156
|
+
throw new Error(`Invalid error message type: ${typeof finalErrorMessage}. Error: ${JSON.stringify(error)}`);
|
|
157
|
+
}
|
|
76
158
|
|
|
77
159
|
// Throw clean error message (without emoji) - CLI will format it
|
|
78
|
-
const formattedError = new Error(
|
|
79
|
-
formattedError.formatted = parsedError
|
|
160
|
+
const formattedError = new Error(finalErrorMessage);
|
|
161
|
+
formattedError.formatted = parsedError?.formatted || finalErrorMessage;
|
|
80
162
|
formattedError.status = safeError.status;
|
|
81
|
-
formattedError.data = parsedError
|
|
163
|
+
formattedError.data = parsedError?.data;
|
|
82
164
|
formattedError._logged = true; // Mark as logged to prevent double-logging
|
|
83
165
|
throw formattedError;
|
|
84
166
|
}
|