@aifabrix/builder 2.22.2 ā 2.31.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/jest.config.coverage.js +37 -0
- package/lib/api/pipeline.api.js +10 -9
- package/lib/app-deploy.js +36 -14
- package/lib/app-list.js +191 -71
- package/lib/app-prompts.js +77 -26
- package/lib/app-readme.js +123 -5
- package/lib/app-rotate-secret.js +101 -57
- package/lib/app-run-helpers.js +200 -172
- package/lib/app-run.js +137 -68
- package/lib/audit-logger.js +8 -7
- package/lib/build.js +161 -250
- package/lib/cli.js +73 -65
- package/lib/commands/login.js +45 -31
- package/lib/commands/logout.js +181 -0
- package/lib/commands/secure.js +59 -24
- package/lib/config.js +79 -45
- package/lib/datasource-deploy.js +89 -29
- package/lib/deployer.js +164 -129
- package/lib/diff.js +63 -21
- package/lib/environment-deploy.js +36 -19
- package/lib/external-system-deploy.js +134 -66
- package/lib/external-system-download.js +244 -171
- package/lib/external-system-test.js +199 -164
- package/lib/generator-external.js +145 -72
- package/lib/generator-helpers.js +49 -17
- package/lib/generator-split.js +105 -58
- package/lib/infra.js +101 -131
- package/lib/schema/application-schema.json +895 -896
- package/lib/schema/env-config.yaml +11 -4
- package/lib/template-validator.js +13 -4
- package/lib/utils/api.js +8 -8
- package/lib/utils/app-register-auth.js +36 -18
- package/lib/utils/app-run-containers.js +140 -0
- package/lib/utils/auth-headers.js +6 -6
- package/lib/utils/build-copy.js +60 -2
- package/lib/utils/build-helpers.js +94 -0
- package/lib/utils/cli-utils.js +177 -76
- package/lib/utils/compose-generator.js +12 -2
- package/lib/utils/config-tokens.js +151 -9
- package/lib/utils/deployment-errors.js +137 -69
- package/lib/utils/deployment-validation-helpers.js +103 -0
- package/lib/utils/docker-build.js +57 -0
- package/lib/utils/dockerfile-utils.js +13 -3
- package/lib/utils/env-copy.js +163 -94
- package/lib/utils/env-map.js +226 -86
- package/lib/utils/error-formatters/network-errors.js +0 -1
- package/lib/utils/external-system-display.js +14 -19
- package/lib/utils/external-system-env-helpers.js +107 -0
- package/lib/utils/external-system-test-helpers.js +144 -0
- package/lib/utils/health-check.js +10 -8
- package/lib/utils/infra-status.js +123 -0
- package/lib/utils/paths.js +228 -49
- package/lib/utils/schema-loader.js +125 -57
- package/lib/utils/token-manager.js +3 -3
- package/lib/utils/yaml-preserve.js +55 -16
- package/lib/validate.js +87 -89
- package/package.json +4 -4
- package/scripts/ci-fix.sh +19 -0
- package/scripts/ci-simulate.sh +19 -0
- package/templates/applications/miso-controller/test.yaml +1 -0
- package/templates/python/Dockerfile.hbs +8 -45
- package/templates/typescript/Dockerfile.hbs +8 -42
|
@@ -14,7 +14,8 @@ 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 testHelpers = require('./utils/external-system-test-helpers');
|
|
18
|
+
const { retryApiCall } = require('./utils/external-system-test-helpers');
|
|
18
19
|
const { getDeploymentAuth } = require('./utils/token-manager');
|
|
19
20
|
const { getDataplaneUrl } = require('./datasource-deploy');
|
|
20
21
|
const { getConfig } = require('./config');
|
|
@@ -115,6 +116,144 @@ async function loadExternalSystemFiles(appName) {
|
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Validate system files against schema
|
|
121
|
+
* @param {Array} systemFiles - Array of system file objects
|
|
122
|
+
* @param {Object} externalSystemSchema - External system schema
|
|
123
|
+
* @returns {Object} Validation results
|
|
124
|
+
*/
|
|
125
|
+
function validateSystemFiles(systemFiles, externalSystemSchema) {
|
|
126
|
+
const systemResults = [];
|
|
127
|
+
let valid = true;
|
|
128
|
+
const errors = [];
|
|
129
|
+
|
|
130
|
+
for (const systemFile of systemFiles) {
|
|
131
|
+
const validation = validateAgainstSchema(systemFile.data, externalSystemSchema);
|
|
132
|
+
if (!validation.valid) {
|
|
133
|
+
valid = false;
|
|
134
|
+
errors.push(`System file ${path.basename(systemFile.path)}: ${validation.errors.join(', ')}`);
|
|
135
|
+
} else {
|
|
136
|
+
systemResults.push({
|
|
137
|
+
file: path.basename(systemFile.path),
|
|
138
|
+
valid: true
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return { valid, errors, systemResults };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Validate datasource against schema and relationships
|
|
148
|
+
* @param {Object} datasource - Datasource configuration
|
|
149
|
+
* @param {string} systemKey - System key
|
|
150
|
+
* @param {Object} externalDataSourceSchema - External datasource schema
|
|
151
|
+
* @returns {Object} Validation result
|
|
152
|
+
*/
|
|
153
|
+
function validateDatasourceSchema(datasource, systemKey, externalDataSourceSchema) {
|
|
154
|
+
const errors = [];
|
|
155
|
+
const schemaValidation = validateAgainstSchema(datasource, externalDataSourceSchema);
|
|
156
|
+
if (!schemaValidation.valid) {
|
|
157
|
+
errors.push(...schemaValidation.errors);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (systemKey && datasource.systemKey !== systemKey) {
|
|
161
|
+
errors.push(`systemKey mismatch: expected '${systemKey}', got '${datasource.systemKey}'`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
valid: errors.length === 0,
|
|
166
|
+
errors
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Test datasource with payload template
|
|
172
|
+
* @param {Object} datasource - Datasource configuration
|
|
173
|
+
* @param {boolean} verbose - Show detailed output
|
|
174
|
+
* @returns {Object} Test results
|
|
175
|
+
*/
|
|
176
|
+
function testDatasourceWithPayload(datasource, verbose) {
|
|
177
|
+
const errors = [];
|
|
178
|
+
const warnings = [];
|
|
179
|
+
|
|
180
|
+
// Validate field mappings
|
|
181
|
+
const fieldMappingResults = validateFieldMappings(datasource, datasource.testPayload);
|
|
182
|
+
if (!fieldMappingResults.valid) {
|
|
183
|
+
errors.push(...fieldMappingResults.errors);
|
|
184
|
+
}
|
|
185
|
+
if (fieldMappingResults.warnings.length > 0) {
|
|
186
|
+
warnings.push(...fieldMappingResults.warnings);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Validate metadata schema
|
|
190
|
+
const metadataSchemaResults = validateMetadataSchema(datasource, datasource.testPayload);
|
|
191
|
+
if (!metadataSchemaResults.valid) {
|
|
192
|
+
errors.push(...metadataSchemaResults.errors);
|
|
193
|
+
}
|
|
194
|
+
if (metadataSchemaResults.warnings.length > 0) {
|
|
195
|
+
warnings.push(...metadataSchemaResults.warnings);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Compare with expectedResult if provided
|
|
199
|
+
if (datasource.testPayload.expectedResult && fieldMappingResults.mappedFields && verbose) {
|
|
200
|
+
warnings.push('expectedResult validation not yet implemented (requires transformation engine)');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
fieldMappingResults,
|
|
205
|
+
metadataSchemaResults,
|
|
206
|
+
errors,
|
|
207
|
+
warnings,
|
|
208
|
+
valid: errors.length === 0
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Validate a single datasource
|
|
214
|
+
* @param {Object} datasourceFile - Datasource file object
|
|
215
|
+
* @param {string} systemKey - System key
|
|
216
|
+
* @param {Object} externalDataSourceSchema - External datasource schema
|
|
217
|
+
* @param {boolean} verbose - Show detailed output
|
|
218
|
+
* @returns {Object} Datasource validation result
|
|
219
|
+
*/
|
|
220
|
+
function validateSingleDatasource(datasourceFile, systemKey, externalDataSourceSchema, verbose) {
|
|
221
|
+
const datasource = datasourceFile.data;
|
|
222
|
+
const datasourceResult = {
|
|
223
|
+
key: datasource.key,
|
|
224
|
+
file: path.basename(datasourceFile.path),
|
|
225
|
+
valid: true,
|
|
226
|
+
errors: [],
|
|
227
|
+
warnings: [],
|
|
228
|
+
fieldMappingResults: null,
|
|
229
|
+
metadataSchemaResults: null
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Validate against schema
|
|
233
|
+
const schemaValidation = validateDatasourceSchema(datasource, systemKey, externalDataSourceSchema);
|
|
234
|
+
if (!schemaValidation.valid) {
|
|
235
|
+
datasourceResult.valid = false;
|
|
236
|
+
datasourceResult.errors.push(...schemaValidation.errors);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Test with testPayload if available
|
|
240
|
+
if (datasource.testPayload && datasource.testPayload.payloadTemplate) {
|
|
241
|
+
logger.log(chalk.blue(` Testing datasource: ${datasource.key}`));
|
|
242
|
+
const payloadTestResults = testDatasourceWithPayload(datasource, verbose);
|
|
243
|
+
datasourceResult.fieldMappingResults = payloadTestResults.fieldMappingResults;
|
|
244
|
+
datasourceResult.metadataSchemaResults = payloadTestResults.metadataSchemaResults;
|
|
245
|
+
if (!payloadTestResults.valid) {
|
|
246
|
+
datasourceResult.valid = false;
|
|
247
|
+
datasourceResult.errors.push(...payloadTestResults.errors);
|
|
248
|
+
}
|
|
249
|
+
datasourceResult.warnings.push(...payloadTestResults.warnings);
|
|
250
|
+
} else {
|
|
251
|
+
datasourceResult.warnings.push('No testPayload.payloadTemplate found - skipping field mapping and metadata schema tests');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return datasourceResult;
|
|
255
|
+
}
|
|
256
|
+
|
|
118
257
|
/**
|
|
119
258
|
* Runs unit tests for external system (local validation, no API calls)
|
|
120
259
|
* @async
|
|
@@ -147,95 +286,28 @@ async function testExternalSystem(appName, options = {}) {
|
|
|
147
286
|
|
|
148
287
|
// Validate system files
|
|
149
288
|
logger.log(chalk.blue('š Validating system files...'));
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
results.errors.push(`System file ${path.basename(systemFile.path)}: ${validation.errors.join(', ')}`);
|
|
155
|
-
} else {
|
|
156
|
-
results.systemResults.push({
|
|
157
|
-
file: path.basename(systemFile.path),
|
|
158
|
-
valid: true
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
289
|
+
const systemValidation = validateSystemFiles(systemFiles, externalSystemSchema);
|
|
290
|
+
results.valid = systemValidation.valid;
|
|
291
|
+
results.errors.push(...systemValidation.errors);
|
|
292
|
+
results.systemResults = systemValidation.systemResults;
|
|
162
293
|
|
|
163
294
|
// Validate datasource files
|
|
164
295
|
logger.log(chalk.blue('š Validating datasource files...'));
|
|
165
|
-
const datasourcesToTest = options.datasource
|
|
166
|
-
|
|
167
|
-
: datasourceFiles;
|
|
296
|
+
const datasourcesToTest = determineDatasourcesToTest(datasourceFiles, options.datasource);
|
|
297
|
+
const systemKey = systemFiles.length > 0 ? systemFiles[0].data.key : null;
|
|
168
298
|
|
|
169
299
|
for (const datasourceFile of datasourcesToTest) {
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
metadataSchemaResults: null
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// Validate against schema
|
|
182
|
-
const schemaValidation = validateAgainstSchema(datasource, externalDataSourceSchema);
|
|
183
|
-
if (!schemaValidation.valid) {
|
|
184
|
-
datasourceResult.valid = false;
|
|
185
|
-
datasourceResult.errors.push(...schemaValidation.errors);
|
|
300
|
+
const datasourceResult = validateSingleDatasource(
|
|
301
|
+
datasourceFile,
|
|
302
|
+
systemKey,
|
|
303
|
+
externalDataSourceSchema,
|
|
304
|
+
options.verbose
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
if (!datasourceResult.valid) {
|
|
186
308
|
results.valid = false;
|
|
187
309
|
}
|
|
188
310
|
|
|
189
|
-
// Validate relationships
|
|
190
|
-
if (systemFiles.length > 0) {
|
|
191
|
-
const systemKey = systemFiles[0].data.key;
|
|
192
|
-
if (datasource.systemKey !== systemKey) {
|
|
193
|
-
datasourceResult.valid = false;
|
|
194
|
-
datasourceResult.errors.push(`systemKey mismatch: expected '${systemKey}', got '${datasource.systemKey}'`);
|
|
195
|
-
results.valid = false;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Test with testPayload if available
|
|
200
|
-
if (datasource.testPayload && datasource.testPayload.payloadTemplate) {
|
|
201
|
-
logger.log(chalk.blue(` Testing datasource: ${datasource.key}`));
|
|
202
|
-
|
|
203
|
-
// Validate field mappings
|
|
204
|
-
const fieldMappingResults = validateFieldMappings(datasource, datasource.testPayload);
|
|
205
|
-
datasourceResult.fieldMappingResults = fieldMappingResults;
|
|
206
|
-
if (!fieldMappingResults.valid) {
|
|
207
|
-
datasourceResult.valid = false;
|
|
208
|
-
datasourceResult.errors.push(...fieldMappingResults.errors);
|
|
209
|
-
results.valid = false;
|
|
210
|
-
}
|
|
211
|
-
if (fieldMappingResults.warnings.length > 0) {
|
|
212
|
-
datasourceResult.warnings.push(...fieldMappingResults.warnings);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Validate metadata schema
|
|
216
|
-
const metadataSchemaResults = validateMetadataSchema(datasource, datasource.testPayload);
|
|
217
|
-
datasourceResult.metadataSchemaResults = metadataSchemaResults;
|
|
218
|
-
if (!metadataSchemaResults.valid) {
|
|
219
|
-
datasourceResult.valid = false;
|
|
220
|
-
datasourceResult.errors.push(...metadataSchemaResults.errors);
|
|
221
|
-
results.valid = false;
|
|
222
|
-
}
|
|
223
|
-
if (metadataSchemaResults.warnings.length > 0) {
|
|
224
|
-
datasourceResult.warnings.push(...metadataSchemaResults.warnings);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Compare with expectedResult if provided
|
|
228
|
-
if (datasource.testPayload.expectedResult && fieldMappingResults.mappedFields) {
|
|
229
|
-
// This would require actual transformation execution, which is complex
|
|
230
|
-
// For now, we just note that expectedResult is present
|
|
231
|
-
if (options.verbose) {
|
|
232
|
-
datasourceResult.warnings.push('expectedResult validation not yet implemented (requires transformation engine)');
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
} else {
|
|
236
|
-
datasourceResult.warnings.push('No testPayload.payloadTemplate found - skipping field mapping and metadata schema tests');
|
|
237
|
-
}
|
|
238
|
-
|
|
239
311
|
results.datasourceResults.push(datasourceResult);
|
|
240
312
|
}
|
|
241
313
|
|
|
@@ -253,50 +325,49 @@ async function testExternalSystem(appName, options = {}) {
|
|
|
253
325
|
* @param {number} backoffMs - Initial backoff in milliseconds
|
|
254
326
|
* @returns {Promise<*>} Function result
|
|
255
327
|
*/
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Setup authentication and get dataplane URL for integration tests
|
|
331
|
+
* @async
|
|
332
|
+
* @param {string} appName - Application name
|
|
333
|
+
* @param {Object} options - Test options
|
|
334
|
+
* @param {Object} config - Configuration object
|
|
335
|
+
* @returns {Promise<Object>} Object with authConfig and dataplaneUrl
|
|
336
|
+
* @throws {Error} If authentication fails
|
|
337
|
+
*/
|
|
338
|
+
async function setupIntegrationTestAuth(appName, options, config) {
|
|
339
|
+
const environment = options.environment || 'dev';
|
|
340
|
+
const controllerUrl = options.controller || config.deployment?.controllerUrl || 'http://localhost:3000';
|
|
341
|
+
const authConfig = await getDeploymentAuth(controllerUrl, environment, appName);
|
|
342
|
+
|
|
343
|
+
if (!authConfig.token && !authConfig.clientId) {
|
|
344
|
+
throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register" first.');
|
|
268
345
|
}
|
|
269
|
-
|
|
346
|
+
|
|
347
|
+
logger.log(chalk.blue('š Getting dataplane URL from controller...'));
|
|
348
|
+
const dataplaneUrl = await getDataplaneUrl(controllerUrl, appName, environment, authConfig);
|
|
349
|
+
logger.log(chalk.green(`ā Dataplane URL: ${dataplaneUrl}`));
|
|
350
|
+
|
|
351
|
+
return { authConfig, dataplaneUrl };
|
|
270
352
|
}
|
|
271
353
|
|
|
272
354
|
/**
|
|
273
|
-
*
|
|
274
|
-
* @
|
|
275
|
-
* @param {string}
|
|
276
|
-
* @
|
|
277
|
-
* @
|
|
278
|
-
* @param {string} dataplaneUrl - Dataplane URL
|
|
279
|
-
* @param {Object} authConfig - Authentication configuration
|
|
280
|
-
* @param {number} timeout - Request timeout in milliseconds
|
|
281
|
-
* @returns {Promise<Object>} Test response
|
|
355
|
+
* Determine which datasources to test
|
|
356
|
+
* @param {Array} datasourceFiles - All datasource files
|
|
357
|
+
* @param {string} [datasourceFilter] - Optional datasource filter
|
|
358
|
+
* @returns {Array} Filtered datasource files
|
|
359
|
+
* @throws {Error} If no datasources found
|
|
282
360
|
*/
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
{ payloadTemplate },
|
|
291
|
-
{ timeout }
|
|
292
|
-
);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
if (!response.success || !response.data) {
|
|
296
|
-
throw new Error(`Test endpoint failed: ${response.error || response.formattedError || 'Unknown error'}`);
|
|
361
|
+
function determineDatasourcesToTest(datasourceFiles, datasourceFilter) {
|
|
362
|
+
const datasourcesToTest = datasourceFilter
|
|
363
|
+
? datasourceFiles.filter(ds => ds.data.key === datasourceFilter || path.basename(ds.path).includes(datasourceFilter))
|
|
364
|
+
: datasourceFiles;
|
|
365
|
+
|
|
366
|
+
if (datasourcesToTest.length === 0) {
|
|
367
|
+
throw new Error('No datasources found to test');
|
|
297
368
|
}
|
|
298
369
|
|
|
299
|
-
return
|
|
370
|
+
return datasourcesToTest;
|
|
300
371
|
}
|
|
301
372
|
|
|
302
373
|
/**
|
|
@@ -331,29 +402,12 @@ async function testExternalSystemIntegration(appName, options = {}) {
|
|
|
331
402
|
|
|
332
403
|
const systemKey = systemFiles[0].data.key;
|
|
333
404
|
|
|
334
|
-
//
|
|
405
|
+
// Setup authentication and dataplane URL
|
|
335
406
|
const config = await getConfig();
|
|
336
|
-
const
|
|
337
|
-
const controllerUrl = options.controller || config.deployment?.controllerUrl || 'http://localhost:3000';
|
|
338
|
-
const authConfig = await getDeploymentAuth(controllerUrl, environment, appName);
|
|
339
|
-
|
|
340
|
-
if (!authConfig.token && !authConfig.clientId) {
|
|
341
|
-
throw new Error('Authentication required. Run "aifabrix login" or "aifabrix app register" first.');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Get dataplane URL
|
|
345
|
-
logger.log(chalk.blue('š Getting dataplane URL from controller...'));
|
|
346
|
-
const dataplaneUrl = await getDataplaneUrl(controllerUrl, appName, environment, authConfig);
|
|
347
|
-
logger.log(chalk.green(`ā Dataplane URL: ${dataplaneUrl}`));
|
|
407
|
+
const { authConfig, dataplaneUrl } = await setupIntegrationTestAuth(appName, options, config);
|
|
348
408
|
|
|
349
409
|
// Determine datasources to test
|
|
350
|
-
const datasourcesToTest = options.datasource
|
|
351
|
-
? datasourceFiles.filter(ds => ds.data.key === options.datasource || path.basename(ds.path).includes(options.datasource))
|
|
352
|
-
: datasourceFiles;
|
|
353
|
-
|
|
354
|
-
if (datasourcesToTest.length === 0) {
|
|
355
|
-
throw new Error('No datasources found to test');
|
|
356
|
-
}
|
|
410
|
+
const datasourcesToTest = determineDatasourcesToTest(datasourceFiles, options.datasource);
|
|
357
411
|
|
|
358
412
|
const results = {
|
|
359
413
|
success: true,
|
|
@@ -362,12 +416,7 @@ async function testExternalSystemIntegration(appName, options = {}) {
|
|
|
362
416
|
};
|
|
363
417
|
|
|
364
418
|
// Load custom payload if provided
|
|
365
|
-
|
|
366
|
-
if (options.payload) {
|
|
367
|
-
const payloadPath = path.isAbsolute(options.payload) ? options.payload : path.join(process.cwd(), options.payload);
|
|
368
|
-
const payloadContent = await fs.readFile(payloadPath, 'utf8');
|
|
369
|
-
customPayload = JSON.parse(payloadContent);
|
|
370
|
-
}
|
|
419
|
+
const customPayload = await testHelpers.loadCustomPayload(options.payload);
|
|
371
420
|
|
|
372
421
|
// Test each datasource
|
|
373
422
|
for (const datasourceFile of datasourcesToTest) {
|
|
@@ -377,12 +426,8 @@ async function testExternalSystemIntegration(appName, options = {}) {
|
|
|
377
426
|
logger.log(chalk.blue(`\nš” Testing datasource: ${datasourceKey}`));
|
|
378
427
|
|
|
379
428
|
// Determine payload to use
|
|
380
|
-
|
|
381
|
-
if (
|
|
382
|
-
payloadTemplate = customPayload;
|
|
383
|
-
} else if (datasource.testPayload && datasource.testPayload.payloadTemplate) {
|
|
384
|
-
payloadTemplate = datasource.testPayload.payloadTemplate;
|
|
385
|
-
} else {
|
|
429
|
+
const payloadTemplate = testHelpers.determinePayloadTemplate(datasource, datasourceKey, customPayload);
|
|
430
|
+
if (!payloadTemplate) {
|
|
386
431
|
logger.log(chalk.yellow(` ā No test payload found for ${datasourceKey}, skipping...`));
|
|
387
432
|
results.datasourceResults.push({
|
|
388
433
|
key: datasourceKey,
|
|
@@ -393,23 +438,14 @@ async function testExternalSystemIntegration(appName, options = {}) {
|
|
|
393
438
|
}
|
|
394
439
|
|
|
395
440
|
try {
|
|
396
|
-
const
|
|
441
|
+
const datasourceResult = await testHelpers.testSingleDatasource({
|
|
397
442
|
systemKey,
|
|
398
443
|
datasourceKey,
|
|
399
444
|
payloadTemplate,
|
|
400
445
|
dataplaneUrl,
|
|
401
446
|
authConfig,
|
|
402
|
-
parseInt(options.timeout, 10) || 30000
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
const datasourceResult = {
|
|
406
|
-
key: datasourceKey,
|
|
407
|
-
skipped: false,
|
|
408
|
-
success: testResponse.success !== false,
|
|
409
|
-
validationResults: testResponse.validationResults || {},
|
|
410
|
-
fieldMappingResults: testResponse.fieldMappingResults || {},
|
|
411
|
-
endpointTestResults: testResponse.endpointTestResults || {}
|
|
412
|
-
};
|
|
447
|
+
timeout: parseInt(options.timeout, 10) || 30000
|
|
448
|
+
});
|
|
413
449
|
|
|
414
450
|
if (!datasourceResult.success) {
|
|
415
451
|
results.success = false;
|
|
@@ -438,6 +474,5 @@ module.exports = {
|
|
|
438
474
|
testExternalSystemIntegration,
|
|
439
475
|
displayTestResults,
|
|
440
476
|
displayIntegrationTestResults,
|
|
441
|
-
callPipelineTestEndpoint,
|
|
442
477
|
retryApiCall
|
|
443
478
|
};
|