@aifabrix/builder 2.8.0 → 2.9.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/integration/hubspot/README.md +136 -0
- package/integration/hubspot/env.template +9 -0
- package/integration/hubspot/hubspot-deploy-company.json +200 -0
- package/integration/hubspot/hubspot-deploy-contact.json +228 -0
- package/integration/hubspot/hubspot-deploy-deal.json +248 -0
- package/integration/hubspot/hubspot-deploy.json +91 -0
- package/integration/hubspot/variables.yaml +17 -0
- package/lib/app-config.js +4 -3
- package/lib/app-deploy.js +8 -20
- package/lib/app-dockerfile.js +7 -9
- package/lib/app-prompts.js +6 -5
- package/lib/app-push.js +9 -9
- package/lib/app-register.js +23 -5
- package/lib/app-rotate-secret.js +10 -0
- package/lib/app-run.js +5 -11
- package/lib/app.js +42 -14
- package/lib/build.js +20 -16
- package/lib/cli.js +61 -2
- package/lib/datasource-deploy.js +14 -20
- package/lib/external-system-deploy.js +123 -40
- package/lib/external-system-download.js +431 -0
- package/lib/external-system-generator.js +13 -10
- package/lib/external-system-test.js +446 -0
- package/lib/generator-builders.js +323 -0
- package/lib/generator.js +200 -292
- package/lib/schema/application-schema.json +853 -852
- package/lib/schema/external-datasource.schema.json +823 -49
- package/lib/schema/external-system.schema.json +96 -78
- package/lib/templates.js +1 -1
- package/lib/utils/cli-utils.js +4 -4
- package/lib/utils/external-system-display.js +159 -0
- package/lib/utils/external-system-validators.js +245 -0
- package/lib/utils/paths.js +151 -1
- package/lib/utils/schema-resolver.js +7 -2
- package/lib/validator.js +5 -2
- package/package.json +1 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Fabrix Builder Deployment JSON Builder Helpers
|
|
3
|
+
*
|
|
4
|
+
* Helper functions for building deployment manifest structures
|
|
5
|
+
*
|
|
6
|
+
* @fileoverview Builder helper functions for deployment JSON generation
|
|
7
|
+
* @author AI Fabrix Team
|
|
8
|
+
* @version 2.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sanitizes authentication type - map keycloak to azure (schema allows: azure, local, none)
|
|
13
|
+
* @function sanitizeAuthType
|
|
14
|
+
* @param {string} authType - Authentication type
|
|
15
|
+
* @returns {string} Sanitized authentication type
|
|
16
|
+
*/
|
|
17
|
+
function sanitizeAuthType(authType) {
|
|
18
|
+
if (authType === 'keycloak') {
|
|
19
|
+
return 'azure';
|
|
20
|
+
}
|
|
21
|
+
if (authType && !['azure', 'local', 'none'].includes(authType)) {
|
|
22
|
+
return 'azure'; // Default to azure if invalid type
|
|
23
|
+
}
|
|
24
|
+
return authType;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Filters configuration based on registry mode
|
|
29
|
+
* When registryMode is "external", only DOCKER_REGISTRY_SERVER_* variables are allowed
|
|
30
|
+
* @function filterConfigurationByRegistryMode
|
|
31
|
+
* @param {Array} configuration - Environment configuration
|
|
32
|
+
* @param {string} registryMode - Registry mode ('external' or 'internal')
|
|
33
|
+
* @returns {Array} Filtered configuration
|
|
34
|
+
*/
|
|
35
|
+
function filterConfigurationByRegistryMode(configuration, registryMode) {
|
|
36
|
+
if (registryMode !== 'external') {
|
|
37
|
+
return configuration;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const allowedDockerRegistryVars = [
|
|
41
|
+
'DOCKER_REGISTRY_SERVER_URL',
|
|
42
|
+
'DOCKER_REGISTRY_SERVER_USERNAME',
|
|
43
|
+
'DOCKER_REGISTRY_SERVER_PASSWORD'
|
|
44
|
+
];
|
|
45
|
+
return configuration.filter(config => allowedDockerRegistryVars.includes(config.name));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function buildImageReference(variables) {
|
|
49
|
+
const imageName = variables.image?.name || variables.app?.key || 'app';
|
|
50
|
+
const registry = variables.image?.registry;
|
|
51
|
+
const tag = variables.image?.tag || 'latest';
|
|
52
|
+
|
|
53
|
+
if (registry) {
|
|
54
|
+
return `${registry}/${imageName}:${tag}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return `${imageName}:${tag}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function buildHealthCheck(variables) {
|
|
61
|
+
const healthCheck = {
|
|
62
|
+
path: variables.healthCheck?.path || '/health',
|
|
63
|
+
interval: variables.healthCheck?.interval || 30
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Add optional probe fields if present
|
|
67
|
+
if (variables.healthCheck?.probePath) {
|
|
68
|
+
healthCheck.probePath = variables.healthCheck.probePath;
|
|
69
|
+
}
|
|
70
|
+
if (variables.healthCheck?.probeRequestType) {
|
|
71
|
+
healthCheck.probeRequestType = variables.healthCheck.probeRequestType;
|
|
72
|
+
}
|
|
73
|
+
if (variables.healthCheck?.probeProtocol) {
|
|
74
|
+
healthCheck.probeProtocol = variables.healthCheck.probeProtocol;
|
|
75
|
+
}
|
|
76
|
+
if (variables.healthCheck?.probeIntervalInSeconds) {
|
|
77
|
+
healthCheck.probeIntervalInSeconds = variables.healthCheck.probeIntervalInSeconds;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return healthCheck;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function buildRequirements(variables) {
|
|
84
|
+
const requires = variables.requires || {};
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
database: requires.database || false,
|
|
88
|
+
databases: requires.databases || (requires.database ? [{ name: variables.app?.key || 'app' }] : []),
|
|
89
|
+
redis: requires.redis || false,
|
|
90
|
+
storage: requires.storage || false,
|
|
91
|
+
storageSize: requires.storageSize || '1Gi'
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function buildAuthentication(rbac) {
|
|
96
|
+
if (!rbac) {
|
|
97
|
+
return {
|
|
98
|
+
type: 'none',
|
|
99
|
+
enableSSO: false,
|
|
100
|
+
requiredRoles: []
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
type: 'azure', // Default to azure (enum: azure, local, none)
|
|
106
|
+
enableSSO: true,
|
|
107
|
+
requiredRoles: rbac.roles?.map(role => role.value) || []
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Builds base deployment structure
|
|
113
|
+
* @function buildBaseDeployment
|
|
114
|
+
* @param {string} appName - Application name
|
|
115
|
+
* @param {Object} variables - Variables configuration
|
|
116
|
+
* @param {Array} filteredConfiguration - Filtered environment configuration
|
|
117
|
+
* @returns {Object} Base deployment structure
|
|
118
|
+
*/
|
|
119
|
+
function buildBaseDeployment(appName, variables, filteredConfiguration) {
|
|
120
|
+
const requires = variables.requires || {};
|
|
121
|
+
return {
|
|
122
|
+
key: variables.app?.key || appName,
|
|
123
|
+
displayName: variables.app?.displayName || appName,
|
|
124
|
+
description: variables.app?.description || '',
|
|
125
|
+
type: variables.app?.type || 'webapp',
|
|
126
|
+
image: buildImageReference(variables),
|
|
127
|
+
registryMode: variables.image?.registryMode || 'external',
|
|
128
|
+
port: variables.port || 3000,
|
|
129
|
+
requiresDatabase: requires.database || false,
|
|
130
|
+
requiresRedis: requires.redis || false,
|
|
131
|
+
requiresStorage: requires.storage || false,
|
|
132
|
+
databases: requires.databases || (requires.database ? [{ name: variables.app?.key || 'app' }] : []),
|
|
133
|
+
configuration: filteredConfiguration
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Builds authentication configuration from variables or RBAC
|
|
139
|
+
* @function buildAuthenticationConfig
|
|
140
|
+
* @param {Object} variables - Variables configuration
|
|
141
|
+
* @param {Object|null} rbac - RBAC configuration
|
|
142
|
+
* @returns {Object} Authentication configuration
|
|
143
|
+
*/
|
|
144
|
+
function buildAuthenticationConfig(variables, rbac) {
|
|
145
|
+
if (variables.authentication) {
|
|
146
|
+
const auth = {
|
|
147
|
+
enableSSO: variables.authentication.enableSSO !== undefined ? variables.authentication.enableSSO : true
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// When enableSSO is false, default type to 'none' and requiredRoles to []
|
|
151
|
+
// When enableSSO is true, require type and requiredRoles
|
|
152
|
+
// Sanitize auth type (e.g., map keycloak to azure)
|
|
153
|
+
if (auth.enableSSO === false) {
|
|
154
|
+
auth.type = sanitizeAuthType(variables.authentication.type || 'none');
|
|
155
|
+
auth.requiredRoles = variables.authentication.requiredRoles || [];
|
|
156
|
+
} else {
|
|
157
|
+
auth.type = sanitizeAuthType(variables.authentication.type || 'azure');
|
|
158
|
+
auth.requiredRoles = variables.authentication.requiredRoles || [];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (variables.authentication.endpoints) {
|
|
162
|
+
auth.endpoints = variables.authentication.endpoints;
|
|
163
|
+
}
|
|
164
|
+
return auth;
|
|
165
|
+
}
|
|
166
|
+
return buildAuthentication(rbac);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Validates and transforms repository configuration
|
|
171
|
+
* @function validateRepositoryConfig
|
|
172
|
+
* @param {Object} repository - Repository configuration
|
|
173
|
+
* @returns {Object|null} Validated repository config or null
|
|
174
|
+
*/
|
|
175
|
+
function validateRepositoryConfig(repository) {
|
|
176
|
+
if (!repository || (!repository.enabled && !repository.repositoryUrl)) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (repository.repositoryUrl && repository.repositoryUrl.trim()) {
|
|
181
|
+
return {
|
|
182
|
+
enabled: repository.enabled || false,
|
|
183
|
+
repositoryUrl: repository.repositoryUrl
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (repository.enabled) {
|
|
188
|
+
return { enabled: true };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Validates and transforms build fields
|
|
196
|
+
* @function validateBuildFields
|
|
197
|
+
* @param {Object} build - Build configuration
|
|
198
|
+
* @returns {Object|null} Validated build config or null
|
|
199
|
+
*/
|
|
200
|
+
function validateBuildFields(build) {
|
|
201
|
+
if (!build) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const buildConfig = {};
|
|
206
|
+
if (build.envOutputPath) {
|
|
207
|
+
buildConfig.envOutputPath = build.envOutputPath;
|
|
208
|
+
}
|
|
209
|
+
if (build.dockerfile && build.dockerfile.trim()) {
|
|
210
|
+
buildConfig.dockerfile = build.dockerfile;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return Object.keys(buildConfig).length > 0 ? buildConfig : null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Validates and transforms deployment fields
|
|
218
|
+
* @function validateDeploymentFields
|
|
219
|
+
* @param {Object} deployment - Deployment configuration
|
|
220
|
+
* @returns {Object|null} Validated deployment config or null
|
|
221
|
+
*/
|
|
222
|
+
function validateDeploymentFields(deployment) {
|
|
223
|
+
if (!deployment) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const deploymentConfig = {};
|
|
228
|
+
if (deployment.controllerUrl && deployment.controllerUrl.trim() && deployment.controllerUrl.startsWith('https://')) {
|
|
229
|
+
deploymentConfig.controllerUrl = deployment.controllerUrl;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return Object.keys(deploymentConfig).length > 0 ? deploymentConfig : null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Adds optional fields to deployment manifest
|
|
237
|
+
* @function buildOptionalFields
|
|
238
|
+
* @param {Object} deployment - Deployment manifest
|
|
239
|
+
* @param {Object} variables - Variables configuration
|
|
240
|
+
* @param {Object|null} rbac - RBAC configuration
|
|
241
|
+
* @returns {Object} Deployment manifest with optional fields
|
|
242
|
+
*/
|
|
243
|
+
function buildOptionalFields(deployment, variables, rbac) {
|
|
244
|
+
if (variables.healthCheck) {
|
|
245
|
+
deployment.healthCheck = buildHealthCheck(variables);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
deployment.authentication = buildAuthenticationConfig(variables, rbac);
|
|
249
|
+
|
|
250
|
+
// Add roles and permissions (from variables.yaml or rbac.yaml)
|
|
251
|
+
// Priority: variables.yaml > rbac.yaml
|
|
252
|
+
if (variables.roles) {
|
|
253
|
+
deployment.roles = variables.roles;
|
|
254
|
+
} else if (rbac && rbac.roles) {
|
|
255
|
+
deployment.roles = rbac.roles;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (variables.permissions) {
|
|
259
|
+
deployment.permissions = variables.permissions;
|
|
260
|
+
} else if (rbac && rbac.permissions) {
|
|
261
|
+
deployment.permissions = rbac.permissions;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const repository = validateRepositoryConfig(variables.repository);
|
|
265
|
+
if (repository) {
|
|
266
|
+
deployment.repository = repository;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const build = validateBuildFields(variables.build);
|
|
270
|
+
if (build) {
|
|
271
|
+
deployment.build = build;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const deploymentConfig = validateDeploymentFields(variables.deployment);
|
|
275
|
+
if (deploymentConfig) {
|
|
276
|
+
deployment.deployment = deploymentConfig;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (variables.startupCommand) {
|
|
280
|
+
deployment.startupCommand = variables.startupCommand;
|
|
281
|
+
}
|
|
282
|
+
if (variables.runtimeVersion) {
|
|
283
|
+
deployment.runtimeVersion = variables.runtimeVersion;
|
|
284
|
+
}
|
|
285
|
+
if (variables.scaling) {
|
|
286
|
+
deployment.scaling = variables.scaling;
|
|
287
|
+
}
|
|
288
|
+
if (variables.frontDoorRouting) {
|
|
289
|
+
deployment.frontDoorRouting = variables.frontDoorRouting;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return deployment;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Builds deployment manifest structure
|
|
297
|
+
* @param {string} appName - Application name
|
|
298
|
+
* @param {Object} variables - Variables configuration
|
|
299
|
+
* @param {string} deploymentKey - Deployment key
|
|
300
|
+
* @param {Array} configuration - Environment configuration
|
|
301
|
+
* @param {Object|null} rbac - RBAC configuration
|
|
302
|
+
* @returns {Object} Deployment manifest
|
|
303
|
+
*/
|
|
304
|
+
function buildManifestStructure(appName, variables, deploymentKey, configuration, rbac) {
|
|
305
|
+
const registryMode = variables.image?.registryMode || 'external';
|
|
306
|
+
const filteredConfiguration = filterConfigurationByRegistryMode(configuration, registryMode);
|
|
307
|
+
const deployment = buildBaseDeployment(appName, variables, filteredConfiguration);
|
|
308
|
+
return buildOptionalFields(deployment, variables, rbac);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
module.exports = {
|
|
312
|
+
buildImageReference,
|
|
313
|
+
buildHealthCheck,
|
|
314
|
+
buildRequirements,
|
|
315
|
+
buildAuthentication,
|
|
316
|
+
buildBaseDeployment,
|
|
317
|
+
buildAuthenticationConfig,
|
|
318
|
+
buildOptionalFields,
|
|
319
|
+
buildManifestStructure,
|
|
320
|
+
filterConfigurationByRegistryMode,
|
|
321
|
+
sanitizeAuthType
|
|
322
|
+
};
|
|
323
|
+
|