@aifabrix/builder 2.39.2 → 2.40.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.
Files changed (116) hide show
  1. package/.cursor/rules/project-rules.mdc +6 -6
  2. package/README.md +2 -2
  3. package/babel.config.js +6 -0
  4. package/integration/hubspot/README.md +53 -141
  5. package/integration/hubspot/application.yaml +37 -0
  6. package/integration/hubspot/env.template +2 -11
  7. package/integration/hubspot/hubspot-deploy.json +1 -0
  8. package/integration/hubspot/test.js +5 -5
  9. package/lib/api/credentials.api.js +5 -5
  10. package/lib/api/deployments.api.js +2 -2
  11. package/lib/api/pipeline.api.js +17 -17
  12. package/lib/api/wizard.api.js +2 -2
  13. package/lib/app/config.js +11 -6
  14. package/lib/app/deploy-config.js +13 -16
  15. package/lib/app/deploy.js +29 -22
  16. package/lib/app/display.js +1 -1
  17. package/lib/app/dockerfile.js +11 -12
  18. package/lib/app/helpers.js +51 -13
  19. package/lib/app/index.js +14 -2
  20. package/lib/app/prompts.js +37 -45
  21. package/lib/app/push.js +8 -11
  22. package/lib/app/readme.js +16 -12
  23. package/lib/app/register.js +3 -3
  24. package/lib/app/run-helpers.js +31 -22
  25. package/lib/app/run.js +44 -5
  26. package/lib/app/show-display.js +104 -44
  27. package/lib/app/show.js +123 -43
  28. package/lib/build/index.js +11 -18
  29. package/lib/cli/setup-app.js +38 -28
  30. package/lib/cli/setup-auth.js +18 -15
  31. package/lib/cli/setup-credential-deployment.js +3 -1
  32. package/lib/cli/setup-external-system.js +35 -16
  33. package/lib/cli/setup-infra.js +45 -23
  34. package/lib/cli/setup-utility.js +79 -31
  35. package/lib/commands/app-logs.js +165 -10
  36. package/lib/commands/app.js +30 -26
  37. package/lib/commands/convert.js +202 -0
  38. package/lib/commands/credential-list.js +78 -17
  39. package/lib/commands/datasource.js +24 -24
  40. package/lib/commands/deployment-list.js +13 -6
  41. package/lib/commands/up-common.js +80 -42
  42. package/lib/commands/up-dataplane.js +15 -14
  43. package/lib/commands/up-miso.js +15 -14
  44. package/lib/commands/upload.js +163 -0
  45. package/lib/commands/wizard-core.js +5 -4
  46. package/lib/core/diff.js +84 -9
  47. package/lib/core/key-generator.js +9 -12
  48. package/lib/core/secrets-docker-env.js +2 -2
  49. package/lib/core/secrets.js +3 -2
  50. package/lib/core/templates.js +2 -2
  51. package/lib/datasource/deploy.js +2 -1
  52. package/lib/deployment/deployer.js +76 -48
  53. package/lib/external-system/delete.js +0 -1
  54. package/lib/external-system/deploy-helpers.js +5 -6
  55. package/lib/external-system/deploy.js +7 -2
  56. package/lib/external-system/download-helpers.js +4 -4
  57. package/lib/external-system/download.js +11 -10
  58. package/lib/external-system/generator.js +19 -17
  59. package/lib/external-system/test.js +10 -15
  60. package/lib/generator/builders.js +1 -1
  61. package/lib/generator/external-controller-manifest.js +26 -29
  62. package/lib/generator/external-schema-utils.js +6 -18
  63. package/lib/generator/external.js +32 -27
  64. package/lib/generator/github.js +1 -1
  65. package/lib/generator/helpers.js +12 -19
  66. package/lib/generator/index.js +15 -15
  67. package/lib/generator/parse-image.js +35 -0
  68. package/lib/generator/split-readme.js +105 -0
  69. package/lib/generator/split-variables.js +149 -0
  70. package/lib/generator/split.js +86 -246
  71. package/lib/generator/wizard.js +46 -69
  72. package/lib/schema/application-schema.json +4 -4
  73. package/lib/schema/deployment-rules.yaml +0 -4
  74. package/lib/schema/external-datasource.schema.json +5 -0
  75. package/lib/schema/external-system.schema.json +10 -0
  76. package/lib/utils/app-config-resolver.js +52 -0
  77. package/lib/utils/app-register-api.js +1 -1
  78. package/lib/utils/app-register-auth.js +1 -1
  79. package/lib/utils/app-register-config.js +16 -23
  80. package/lib/utils/app-register-display.js +22 -3
  81. package/lib/utils/app-register-validator.js +2 -2
  82. package/lib/utils/cli-utils.js +47 -3
  83. package/lib/utils/config-format.js +154 -0
  84. package/lib/utils/config-paths.js +19 -52
  85. package/lib/utils/config-tokens.js +1 -0
  86. package/lib/utils/docker-build.js +71 -94
  87. package/lib/utils/dockerfile-utils.js +1 -1
  88. package/lib/utils/env-copy.js +4 -4
  89. package/lib/utils/env-ports.js +2 -2
  90. package/lib/utils/error-formatter.js +1 -1
  91. package/lib/utils/error-formatters/validation-errors.js +1 -1
  92. package/lib/utils/external-readme.js +12 -5
  93. package/lib/utils/external-system-test-helpers.js +2 -0
  94. package/lib/utils/health-check.js +55 -66
  95. package/lib/utils/image-version.js +12 -21
  96. package/lib/utils/paths.js +39 -66
  97. package/lib/utils/port-resolver.js +8 -8
  98. package/lib/utils/schema-loader.js +22 -0
  99. package/lib/utils/schema-resolver.js +23 -33
  100. package/lib/utils/secrets-helpers.js +7 -7
  101. package/lib/utils/secrets-utils.js +10 -12
  102. package/lib/utils/template-helpers.js +13 -13
  103. package/lib/utils/token-manager.js +20 -2
  104. package/lib/utils/variable-transformer.js +2 -2
  105. package/lib/validation/validate-display.js +3 -4
  106. package/lib/validation/validate.js +33 -27
  107. package/lib/validation/validator.js +50 -30
  108. package/package.json +2 -1
  109. package/templates/README.md +1 -1
  110. package/templates/applications/README.md.hbs +3 -3
  111. package/templates/applications/miso-controller/env.template +3 -1
  112. package/templates/external-system/README.md.hbs +4 -4
  113. package/integration/hubspot/variables.yaml +0 -17
  114. /package/templates/applications/dataplane/{variables.yaml → application.yaml} +0 -0
  115. /package/templates/applications/keycloak/{variables.yaml → application.yaml} +0 -0
  116. /package/templates/applications/miso-controller/{variables.yaml → application.yaml} +0 -0
@@ -10,12 +10,14 @@
10
10
  */
11
11
 
12
12
  const fs = require('fs');
13
- const path = require('path');
13
+ const yaml = require('js-yaml');
14
14
  const validator = require('./validator');
15
15
  const { resolveExternalFiles } = require('../utils/schema-resolver');
16
16
  const { loadExternalSystemSchema, loadExternalDataSourceSchema, detectSchemaType } = require('../utils/schema-loader');
17
17
  const { formatValidationErrors } = require('../utils/error-formatter');
18
18
  const { detectAppType } = require('../utils/paths');
19
+ const { logOfflinePathWhenType } = require('../utils/cli-utils');
20
+ const { resolveApplicationConfigPath } = require('../utils/app-config-resolver');
19
21
  const { displayValidationResults } = require('./validate-display');
20
22
  const { generateControllerManifest } = require('../generator/external-controller-manifest');
21
23
  const { validateControllerManifest } = require('./external-manifest-validator');
@@ -43,8 +45,8 @@ async function validateFilePath(filePath) {
43
45
  * @param {string} appName - Application name
44
46
  * @returns {Promise<Array>} Array of validation results
45
47
  */
46
- async function validateExternalFilesForApp(appName) {
47
- const files = await resolveExternalFiles(appName);
48
+ async function validateExternalFilesForApp(appName, options = {}) {
49
+ const files = await resolveExternalFiles(appName, options);
48
50
  const validations = [];
49
51
 
50
52
  for (const file of files) {
@@ -105,21 +107,23 @@ function aggregateValidationResults(appValidation, externalValidations, rbacVali
105
107
  * @returns {Promise<Object>} Validation result
106
108
  */
107
109
  /**
108
- * Parses JSON file content
110
+ * Parses external system/datasource file content (JSON or YAML).
109
111
  * @function parseJsonFileContent
110
- * @param {string} filePath - File path
112
+ * @param {string} filePath - File path (.json, .yaml, or .yml)
111
113
  * @returns {Object} Parse result with parsed object or error
112
114
  */
113
115
  function parseJsonFileContent(filePath) {
114
116
  const content = fs.readFileSync(filePath, 'utf8');
117
+ const isYaml = /\.(yaml|yml)$/i.test(filePath);
115
118
  try {
116
- return { parsed: JSON.parse(content), error: null };
119
+ const parsed = isYaml ? yaml.load(content) : JSON.parse(content);
120
+ return { parsed: parsed || {}, error: null };
117
121
  } catch (error) {
118
122
  return {
119
123
  parsed: null,
120
124
  error: {
121
125
  valid: false,
122
- errors: [`Invalid JSON syntax: ${error.message}`],
126
+ errors: [isYaml ? `Invalid YAML syntax: ${error.message}` : `Invalid JSON syntax: ${error.message}`],
123
127
  warnings: []
124
128
  }
125
129
  };
@@ -206,7 +210,7 @@ async function validateExternalFile(filePath, type) {
206
210
  * @function validateAppOrFile
207
211
  * @param {string} appOrFile - Application name or file path
208
212
  * @param {Object} [options] - Validation options
209
- * @param {string} [options.type] - Forced application type (external)
213
+ *
210
214
  * @returns {Promise<Object>} Validation result with aggregated results
211
215
  * @throws {Error} If validation fails
212
216
  *
@@ -239,9 +243,9 @@ async function validateRbacForExternalSystem(isExternal, appName) {
239
243
  }
240
244
 
241
245
  /**
242
- * Loads and checks variables.yaml for externalIntegration
246
+ * Loads and checks application config for externalIntegration
243
247
  * @function loadVariablesAndCheckExternalIntegration
244
- * @param {string} variablesPath - Path to variables.yaml
248
+ * @param {string} variablesPath - Path to application config
245
249
  * @param {Object} appValidation - Application validation result
246
250
  * @returns {Object|null} Variables object or null if no externalIntegration
247
251
  */
@@ -265,7 +269,7 @@ function loadVariablesAndCheckExternalIntegration(variablesPath, appValidation)
265
269
  valid: appValidation.valid,
266
270
  application: appValidation,
267
271
  externalFiles: [],
268
- warnings: [`Could not parse variables.yaml to check externalIntegration: ${error.message}`]
272
+ warnings: [`Could not parse application config to check externalIntegration: ${error.message}`]
269
273
  };
270
274
  }
271
275
 
@@ -287,9 +291,9 @@ function loadVariablesAndCheckExternalIntegration(variablesPath, appValidation)
287
291
  * @param {string} appName - Application name
288
292
  * @returns {Promise<Object>} Application validation result
289
293
  */
290
- async function validateApplicationStep(appName) {
294
+ async function validateApplicationStep(appName, options = {}) {
291
295
  try {
292
- const appValidation = await validator.validateApplication(appName);
296
+ const appValidation = await validator.validateApplication(appName, options);
293
297
  return {
294
298
  valid: appValidation.valid,
295
299
  errors: appValidation.errors || [],
@@ -311,9 +315,9 @@ async function validateApplicationStep(appName) {
311
315
  * @param {string} appName - Application name
312
316
  * @returns {Promise<Object>} Components validation result
313
317
  */
314
- async function validateComponentsStep(appName) {
318
+ async function validateComponentsStep(appName, options = {}) {
315
319
  try {
316
- const externalValidations = await validateExternalFilesForApp(appName);
320
+ const externalValidations = await validateExternalFilesForApp(appName, options);
317
321
  const componentErrors = [];
318
322
  const componentWarnings = [];
319
323
  const componentFiles = [];
@@ -357,9 +361,9 @@ async function validateComponentsStep(appName) {
357
361
  * @param {string} appName - Application name
358
362
  * @returns {Promise<Object>} Manifest validation result
359
363
  */
360
- async function validateManifestStep(appName) {
364
+ async function validateManifestStep(appName, options = {}) {
361
365
  try {
362
- const manifest = await generateControllerManifest(appName);
366
+ const manifest = await generateControllerManifest(appName, options);
363
367
  const manifestValidation = await validateControllerManifest(manifest);
364
368
  return {
365
369
  valid: manifestValidation.valid,
@@ -389,7 +393,7 @@ async function validateManifestStep(appName) {
389
393
  * const result = await validateExternalSystemComplete('my-hubspot');
390
394
  * // Returns: { valid: true, errors: [], warnings: [], steps: {...} }
391
395
  */
392
- async function validateExternalSystemComplete(appName) {
396
+ async function validateExternalSystemComplete(appName, options = {}) {
393
397
  if (!appName || typeof appName !== 'string') {
394
398
  throw new Error('App name is required and must be a string');
395
399
  }
@@ -400,11 +404,13 @@ async function validateExternalSystemComplete(appName) {
400
404
  manifest: { valid: false, errors: [], warnings: [] }
401
405
  };
402
406
 
407
+ const externalOptions = { ...options };
408
+
403
409
  // Step 1: Validate Application Config
404
- steps.application = await validateApplicationStep(appName);
410
+ steps.application = await validateApplicationStep(appName, externalOptions);
405
411
 
406
412
  // Step 2: Validate Individual Components
407
- steps.components = await validateComponentsStep(appName);
413
+ steps.components = await validateComponentsStep(appName, externalOptions);
408
414
 
409
415
  // If components have errors, return early (don't validate manifest)
410
416
  if (!steps.components.valid) {
@@ -417,7 +423,7 @@ async function validateExternalSystemComplete(appName) {
417
423
  }
418
424
 
419
425
  // Step 3 & 4: Generate and Validate Full Manifest (only if Step 2 passes)
420
- steps.manifest = await validateManifestStep(appName);
426
+ steps.manifest = await validateManifestStep(appName, externalOptions);
421
427
 
422
428
  // Aggregate Results
423
429
  const allErrors = [...steps.application.errors, ...steps.components.errors, ...steps.manifest.errors];
@@ -442,23 +448,23 @@ async function validateAppOrFile(appOrFile, options = {}) {
442
448
  }
443
449
 
444
450
  const appName = appOrFile;
445
- const { appPath, isExternal } = await detectAppType(appName, options);
451
+ const { appPath, isExternal } = await detectAppType(appName);
452
+ logOfflinePathWhenType(appPath);
446
453
 
447
- // For external systems with --type external flag, use new unified validation
448
- if (isExternal && options.type === 'external') {
454
+ if (isExternal) {
449
455
  return await validateExternalSystemComplete(appName);
450
456
  }
451
457
 
452
- const appValidation = await validator.validateApplication(appName);
458
+ const appValidation = await validator.validateApplication(appName, options);
453
459
  const rbacValidation = await validateRbacForExternalSystem(isExternal, appName);
454
460
 
455
- const variablesPath = path.join(appPath, 'variables.yaml');
461
+ const variablesPath = resolveApplicationConfigPath(appPath);
456
462
  const earlyReturn = loadVariablesAndCheckExternalIntegration(variablesPath, appValidation);
457
463
  if (earlyReturn) {
458
464
  return earlyReturn;
459
465
  }
460
466
 
461
- const externalValidations = await validateExternalFilesForApp(appName);
467
+ const externalValidations = await validateExternalFilesForApp(appName, options);
462
468
  return aggregateValidationResults(appValidation, externalValidations, rbacValidation);
463
469
  }
464
470
 
@@ -2,7 +2,7 @@
2
2
  * AI Fabrix Builder Schema Validation
3
3
  *
4
4
  * This module provides schema validation with developer-friendly error messages.
5
- * Validates variables.yaml, rbac.yaml, and env.template files.
5
+ * Validates application.yaml, rbac.yaml, and env.template files.
6
6
  *
7
7
  * @fileoverview Schema validation with friendly error messages for AI Fabrix Builder
8
8
  * @author AI Fabrix Team
@@ -19,10 +19,11 @@ const externalDataSourceSchema = require('../schema/external-datasource.schema.j
19
19
  const { transformVariablesForValidation } = require('../utils/variable-transformer');
20
20
  const { checkEnvironment } = require('../utils/environment-checker');
21
21
  const { formatValidationErrors } = require('../utils/error-formatter');
22
- const { detectAppType } = require('../utils/paths');
22
+ const { detectAppType, resolveApplicationConfigPath } = require('../utils/paths');
23
+ const { loadConfigFile } = require('../utils/config-format');
23
24
 
24
25
  /**
25
- * Validates variables.yaml file against application schema
26
+ * Validates application config file against application schema
26
27
  * Provides detailed error messages for configuration issues
27
28
  *
28
29
  * @async
@@ -36,27 +37,17 @@ const { detectAppType } = require('../utils/paths');
36
37
  * // Returns: { valid: true, errors: [], warnings: [] }
37
38
  */
38
39
  /**
39
- * Loads and parses variables.yaml
40
+ * Loads and parses application config (application.yaml or application.json) via resolver + converter.
40
41
  * @async
41
42
  * @function loadVariablesYaml
42
43
  * @param {string} appName - Application name
43
44
  * @returns {Promise<Object>} Variables object
44
45
  * @throws {Error} If file not found or invalid
45
46
  */
46
- async function loadVariablesYaml(appName) {
47
- const { appPath } = await detectAppType(appName);
48
- const variablesPath = path.join(appPath, 'variables.yaml');
49
-
50
- if (!fs.existsSync(variablesPath)) {
51
- throw new Error(`variables.yaml not found: ${variablesPath}`);
52
- }
53
-
54
- const content = fs.readFileSync(variablesPath, 'utf8');
55
- try {
56
- return yaml.load(content);
57
- } catch (error) {
58
- throw new Error(`Invalid YAML syntax in variables.yaml: ${error.message}`);
59
- }
47
+ async function loadVariablesYaml(appName, options = {}) {
48
+ const { appPath } = await detectAppType(appName, options);
49
+ const configPath = resolveApplicationConfigPath(appPath);
50
+ return loadConfigFile(configPath);
60
51
  }
61
52
 
62
53
  /**
@@ -119,12 +110,12 @@ function validateFrontDoorRouting(variables, errors) {
119
110
  }
120
111
  }
121
112
 
122
- async function validateVariables(appName) {
113
+ async function validateVariables(appName, options = {}) {
123
114
  if (!appName || typeof appName !== 'string') {
124
115
  throw new Error('App name is required and must be a string');
125
116
  }
126
117
 
127
- const variables = await loadVariablesYaml(appName);
118
+ const variables = await loadVariablesYaml(appName, options);
128
119
  const transformed = transformVariablesForValidation(variables, appName);
129
120
  const validate = setupAjvValidator();
130
121
  const valid = validate(transformed);
@@ -203,16 +194,18 @@ function validatePermissions(permissions) {
203
194
  return errors;
204
195
  }
205
196
 
206
- async function validateRbac(appName) {
197
+ async function validateRbac(appName, options = {}) {
207
198
  if (!appName || typeof appName !== 'string') {
208
199
  throw new Error('App name is required and must be a string');
209
200
  }
210
201
 
211
202
  // Support both builder/ and integration/ directories using detectAppType
212
- const { appPath } = await detectAppType(appName);
213
- const rbacPath = path.join(appPath, 'rbac.yaml');
203
+ const { appPath } = await detectAppType(appName, options);
204
+ const rbacYaml = path.join(appPath, 'rbac.yaml');
205
+ const rbacYml = path.join(appPath, 'rbac.yml');
206
+ const rbacPath = fs.existsSync(rbacYaml) ? rbacYaml : (fs.existsSync(rbacYml) ? rbacYml : null);
214
207
 
215
- if (!fs.existsSync(rbacPath)) {
208
+ if (!rbacPath) {
216
209
  return { valid: true, errors: [], warnings: ['rbac.yaml not found - authentication disabled'] };
217
210
  }
218
211
 
@@ -251,13 +244,13 @@ async function validateRbac(appName) {
251
244
  * const result = await validateEnvTemplate('myapp');
252
245
  * // Returns: { valid: true, errors: [], warnings: [] }
253
246
  */
254
- async function validateEnvTemplate(appName) {
247
+ async function validateEnvTemplate(appName, options = {}) {
255
248
  if (!appName || typeof appName !== 'string') {
256
249
  throw new Error('App name is required and must be a string');
257
250
  }
258
251
 
259
252
  // Support both builder/ and integration/ directories using detectAppType
260
- const { appPath } = await detectAppType(appName);
253
+ const { appPath } = await detectAppType(appName, options);
261
254
  const templatePath = path.join(appPath, 'env.template');
262
255
 
263
256
  if (!fs.existsSync(templatePath)) {
@@ -305,6 +298,32 @@ async function validateEnvTemplate(appName) {
305
298
  };
306
299
  }
307
300
 
301
+ /**
302
+ * Validates a single object against the application schema (no app-name resolution).
303
+ * Supports both flat root (key, displayName, ...) and nested shape (app: {...}).
304
+ * Used by diff and other callers that have already parsed the config.
305
+ *
306
+ * @function validateObjectAgainstApplicationSchema
307
+ * @param {Object} obj - Parsed config object (root or { app, deployment })
308
+ * @returns {{ valid: boolean, errors: string[] }} Validation result
309
+ *
310
+ * @example
311
+ * const result = validateObjectAgainstApplicationSchema(parsed);
312
+ * if (!result.valid) throw new Error(result.errors.join('; '));
313
+ */
314
+ function validateObjectAgainstApplicationSchema(obj) {
315
+ if (!obj || typeof obj !== 'object') {
316
+ return { valid: false, errors: ['Config must be an object'] };
317
+ }
318
+ const toValidate = obj.app && typeof obj.app === 'object' && !obj.key ? obj.app : obj;
319
+ const validate = setupAjvValidator();
320
+ const valid = validate(toValidate);
321
+ return {
322
+ valid: !!valid,
323
+ errors: valid ? [] : formatValidationErrors(validate.errors)
324
+ };
325
+ }
326
+
308
327
  /**
309
328
  * Validates deployment JSON against application schema
310
329
  * Ensures generated <app-name>-deploy.json matches the schema structure
@@ -360,14 +379,14 @@ function validateDeploymentJson(deployment) {
360
379
  * const result = await validateApplication('myapp');
361
380
  * // Returns: { valid: true, variables: {...}, rbac: {...}, env: {...} }
362
381
  */
363
- async function validateApplication(appName) {
382
+ async function validateApplication(appName, options = {}) {
364
383
  if (!appName || typeof appName !== 'string') {
365
384
  throw new Error('App name is required and must be a string');
366
385
  }
367
386
 
368
- const variables = await validateVariables(appName);
369
- const rbac = await validateRbac(appName);
370
- const env = await validateEnvTemplate(appName);
387
+ const variables = await validateVariables(appName, options);
388
+ const rbac = await validateRbac(appName, options);
389
+ const env = await validateEnvTemplate(appName, options);
371
390
 
372
391
  const valid = variables.valid && rbac.valid && env.valid;
373
392
  const errors = [...(variables.errors || []), ...(rbac.errors || []), ...(env.errors || [])];
@@ -392,6 +411,7 @@ module.exports = {
392
411
  validateRbac,
393
412
  validateEnvTemplate,
394
413
  validateDeploymentJson,
414
+ validateObjectAgainstApplicationSchema,
395
415
  checkEnvironment,
396
416
  formatValidationErrors,
397
417
  validateApplication
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifabrix/builder",
3
- "version": "2.39.2",
3
+ "version": "2.40.0",
4
4
  "description": "AI Fabrix Local Fabric & Deployment SDK",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -78,6 +78,7 @@
78
78
  "ora": "^5.4.1"
79
79
  },
80
80
  "devDependencies": {
81
+ "@babel/preset-env": "^7.29.0",
81
82
  "@bcoe/v8-coverage": "^1.0.2",
82
83
  "@types/node": "^20.10.0",
83
84
  "cross-env": "^10.1.0",
@@ -106,7 +106,7 @@ Create your own step templates in `templates/github/steps/{your-step}.hbs` and r
106
106
 
107
107
  ### Language and Infrastructure Templates
108
108
 
109
- These templates are processed automatically by the AI Fabrix Builder SDK based on the application schema defined in `variables.yaml`. The generated files will be valid Docker files after template processing.
109
+ These templates are processed automatically by the AI Fabrix Builder SDK based on the application schema defined in `application.yaml`. The generated files will be valid Docker files after template processing.
110
110
 
111
111
  ## VS Code Configuration
112
112
 
@@ -61,7 +61,7 @@ aifabrix build {{appName}} --tag v1.0.0
61
61
  aifabrix push {{appName}} --registry {{registry}} --tag "v1.0.0,latest"
62
62
 
63
63
  # Deploy (controller and environment from config; set via aifabrix login or aifabrix auth config)
64
- aifabrix deploy {{appName}} --deployment local
64
+ aifabrix deploy {{appName}} --local
65
65
  ```
66
66
 
67
67
  ---
@@ -132,7 +132,7 @@ aifabrix push {{appName}} --registry {{registry}} --tag "v1.0.0,latest,stable"
132
132
  ### Deploy Options
133
133
 
134
134
  ```bash
135
- aifabrix deploy {{appName}} --deployment local # Uses controller and environment from config
135
+ aifabrix deploy {{appName}} --local # Uses controller and environment from config
136
136
  aifabrix deploy {{appName}} --no-poll # Deploy without polling for status
137
137
  ```
138
138
 
@@ -166,7 +166,7 @@ Controller URL and environment (for `deploy`, `app register`, etc.) are set via
166
166
 
167
167
  - **"Docker not running"** → Start Docker Desktop
168
168
  - **"Not logged in"** → Run `aifabrix login` first
169
- - **"Port already in use"** → Use `aifabrix run {{appName}} --port <port>` or set `build.localPort` in `variables.yaml` (default: {{localPort}})
169
+ - **"Port already in use"** → Use `aifabrix run {{appName}} --port <port>` or set `build.localPort` in `application.yaml` (default: {{localPort}})
170
170
  - **"Authentication failed"** → Run `aifabrix login` again
171
171
  - **"Build fails"** → Check Docker is running and `aifabrix-secrets` in `config.yaml` is configured correctly
172
172
  - **"Can't connect"** → Verify infrastructure is running{{#if hasDatabase}} and PostgreSQL is accessible{{/if}}
@@ -105,7 +105,9 @@ REDIS_PERMISSIONS_TTL=900
105
105
  # (KeycloakConfiguration + Application url/internalUrl). Sync env->DB at startup via
106
106
  # sync-application-urls-from-env.service.
107
107
  #
108
- # NOTE: Do NOT onboard Azure Entra SSO in Keycloak during onboarding (skipAzureEntraSso=true).
108
+ # Azure Entra SSO during onboarding: true = skip (default), false = onboard Azure Entra SSO client in Keycloak
109
+ # (onboarding Azure SSO requires Entra admin consent and Azure app credentials).
110
+ KEYCLOAK_SKIP_AZURE_ENTRA_SSO=false
109
111
 
110
112
  KEYCLOAK_REALM=aifabrix
111
113
  KEYCLOAK_SERVER_URL=kv://keycloak-server-urlKeyVault
@@ -10,8 +10,8 @@
10
10
 
11
11
  ## Files
12
12
 
13
- - `variables.yaml` – Application configuration with `app` and `externalIntegration` blocks
14
- - `{{systemKey}}-system.json` – External system definition (authentication, OpenAPI/MCP, RBAC)
13
+ - `application.yaml` – Application configuration with `app` and `externalIntegration` blocks
14
+ - `{{systemKey}}-system.yaml` – External system definition (authentication, OpenAPI/MCP, RBAC)
15
15
  {{#each datasources}}
16
16
  - `{{fileName}}` – Datasource: {{displayName}}
17
17
  {{/each}}
@@ -38,8 +38,8 @@ aifabrix wizard --app {{appName}}
38
38
 
39
39
  Edit files in `integration/{{appName}}/`:
40
40
 
41
- - **Authentication**: `{{systemKey}}-system.json` (auth type, credentials placeholders)
42
- - **Field mappings**: `{{systemKey}}-datasource-*.json` (dimensions, attributes, operations)
41
+ - **Authentication**: `{{systemKey}}-system.yaml` (auth type, credentials placeholders)
42
+ - **Field mappings**: `{{systemKey}}-datasource-*.yaml` (dimensions, attributes, operations)
43
43
 
44
44
  ### 3. Validate Configuration
45
45
 
@@ -1,17 +0,0 @@
1
- app:
2
- key: hubspot
3
- displayName: "HubSpot CRM Integration"
4
- description: "HubSpot CRM external system integration with companies, contacts, and deals"
5
- type: external
6
-
7
- externalIntegration:
8
- schemaBasePath: ./
9
- systems:
10
- - hubspot-system.json
11
- dataSources:
12
- - hubspot-datasource-company.json
13
- - hubspot-datasource-contact.json
14
- - hubspot-datasource-deal.json
15
- autopublish: true
16
- version: 1.0.0
17
-