@aifabrix/builder 2.52.0 → 2.53.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/lib/api/datasources-extended.api.js +8 -8
- package/lib/api/keycloak.api.js +92 -0
- package/lib/api/token-providers.api.js +77 -0
- package/lib/api/types/keycloak.types.js +23 -0
- package/lib/api/types/token-providers.types.js +65 -0
- package/lib/app/deploy-config.js +3 -2
- package/lib/app/down.js +16 -1
- package/lib/channels/add-channel.js +134 -57
- package/lib/channels/approval-guides/chatgpt.js +1 -1
- package/lib/channels/approval-guides/index.js +3 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +27 -14
- package/lib/channels/channel-add-ensure.js +128 -0
- package/lib/channels/channel-add-existing.js +72 -0
- package/lib/channels/channel-artifact-generator.js +11 -1
- package/lib/channels/channel-branding.js +94 -0
- package/lib/channels/channel-credential.js +8 -0
- package/lib/channels/channel-discovery.js +330 -0
- package/lib/channels/channel-external-system.js +1 -1
- package/lib/channels/channel-runtime-resolver.js +107 -14
- package/lib/channels/channel-status-display.js +36 -3
- package/lib/channels/microsoft-copilot-channel-add.js +138 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +251 -0
- package/lib/channels/microsoft-copilot-entra-sso.js +285 -0
- package/lib/channels/microsoft-copilot-icons.js +74 -0
- package/lib/channels/microsoft-copilot-limits.js +103 -0
- package/lib/channels/microsoft-copilot-package.js +178 -52
- package/lib/channels/microsoft-copilot-validate.js +227 -0
- package/lib/cli/attach-default-help-examples.js +102 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/infra-guided.js +13 -6
- package/lib/cli/setup-credential-deployment.js +7 -5
- package/lib/cli/setup-infra.js +31 -4
- package/lib/cli/setup-utility-validate.js +1 -0
- package/lib/commands/channel-add-setup.js +28 -9
- package/lib/commands/channel.js +14 -10
- package/lib/commands/credential-push.js +37 -5
- package/lib/commands/integration-definition.js +158 -0
- package/lib/commands/package-score.js +72 -0
- package/lib/commands/repair-auth-apply.js +19 -5
- package/lib/commands/repair-datasource-sync-operations.js +4 -1
- package/lib/commands/role-assistant-test-output.js +200 -0
- package/lib/commands/role-assistant.js +163 -166
- package/lib/datasource/capability/capability-resolve.js +15 -5
- package/lib/datasource/capability/copy-operations.js +14 -4
- package/lib/deployment/deployer-poll-run.js +2 -2
- package/lib/deployment/deployer.js +1 -1
- package/lib/deployment/environment.js +2 -2
- package/lib/external-system/deploy.js +11 -21
- package/lib/infrastructure/index.js +19 -4
- package/lib/integration-definition/apply.js +476 -0
- package/lib/integration-definition/canonical-json.js +51 -0
- package/lib/integration-definition/emit-suite-bid.js +94 -0
- package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
- package/lib/integration-definition/enrich-openapi-operations.js +433 -0
- package/lib/integration-definition/from-discovery.js +339 -0
- package/lib/integration-definition/hash.js +37 -0
- package/lib/integration-definition/index.js +37 -0
- package/lib/integration-definition/resource-type-catalog.js +59 -0
- package/lib/integration-definition/system-kind-enum.js +40 -0
- package/lib/integration-definition/validate.js +148 -0
- package/lib/lab/package-parity-score.js +417 -0
- package/lib/programmatic/builder-api-request.js +5 -1
- package/lib/programmatic/builder-help-governance.js +3 -2
- package/lib/programmatic/capability-registry.js +20 -0
- package/lib/programmatic/help-content/channel-onboarding.md +35 -0
- package/lib/programmatic/help-content/cip-overview.md +27 -0
- package/lib/programmatic/help-content/connected-system-ui.md +70 -0
- package/lib/programmatic/help-content/dimensions-guide.md +23 -0
- package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
- package/lib/programmatic/help-content/overview.md +25 -0
- package/lib/programmatic/help-content/subscription-guide.md +27 -0
- package/lib/programmatic/help-content/workflow.md +50 -0
- package/lib/programmatic/openapi-component-schemas.js +7 -1
- package/lib/programmatic/openapi-descriptions.js +46 -0
- package/lib/programmatic/openapi-envelope-examples.js +280 -0
- package/lib/programmatic/openapi-operation-bindings.js +50 -0
- package/lib/programmatic/openapi-request-schemas.js +40 -0
- package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
- package/lib/programmatic/openapi-result-schemas.js +76 -99
- package/lib/programmatic/openapi-schema-descriptions-core.js +25 -4
- package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-operations.js +43 -0
- package/lib/programmatic/openapi-schema-helpers.js +9 -9
- package/lib/programmatic/openapi-spec.js +11 -1
- package/lib/programmatic/orchestration-openapi-meta.js +10 -0
- package/lib/programmatic/persist-supplied-openapi.js +180 -0
- package/lib/programmatic/route-handler-map.js +35 -1
- package/lib/programmatic/run-channel-package.js +236 -0
- package/lib/programmatic/run-integration-definition.js +77 -0
- package/lib/role-assistant/evidence-sync.js +55 -7
- package/lib/role-assistant/knowledge-sync-logging.js +58 -0
- package/lib/role-assistant/knowledge-sync.js +88 -93
- package/lib/role-assistant/test-cases-bid.js +155 -0
- package/lib/role-assistant/test-cases-evaluate.js +9 -1
- package/lib/role-assistant/test-cases-honesty.js +24 -10
- package/lib/role-assistant/test-cases.js +28 -0
- package/lib/role-assistant/test-runner-attachments.js +118 -0
- package/lib/role-assistant/test-runner-bid-apply.js +201 -0
- package/lib/role-assistant/test-runner-bid-document.js +278 -0
- package/lib/role-assistant/test-runner-start-payload.js +96 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +249 -20
- package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
- package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
- package/lib/role-assistant/test-runner-workhub.js +152 -107
- package/lib/role-assistant/test-runner.js +5 -63
- package/lib/role-assistant/test-suite.js +112 -0
- package/lib/schema/application-schema.json +56 -6
- package/lib/schema/external-datasource.schema.json +103 -17
- package/lib/schema/external-system.schema.json +54 -3
- package/lib/schema/integration-definition.schema.json +195 -0
- package/lib/utils/authentication-shape.js +6 -0
- package/lib/utils/compose-generator.js +10 -1
- package/lib/utils/compose-traefik-extra-routes.js +107 -0
- package/lib/utils/docker-build.js +2 -2
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/promote-dev-docker-image.js +102 -18
- package/lib/utils/transient-developer-id.js +28 -0
- package/package.json +14 -16
- package/templates/README.md +12 -1
- package/templates/applications/dataplane/application.yaml +10 -2
- package/templates/applications/dataplane/env.template +7 -6
- package/templates/applications/miso-controller/application.yaml +23 -8
- package/templates/applications/miso-controller/env.template +8 -2
- package/templates/applications/miso-controller/rbac.yaml +1 -0
- package/templates/channels/README.md +11 -1
- package/templates/channels/brand/color-192.png +0 -0
- package/templates/channels/brand/dark/128.png +0 -0
- package/templates/channels/brand/dark/192.png +0 -0
- package/templates/channels/brand/dark/256.png +0 -0
- package/templates/channels/brand/dark/32.png +0 -0
- package/templates/channels/brand/dark/512.png +0 -0
- package/templates/channels/brand/dark/64.png +0 -0
- package/templates/channels/brand/light/128.png +0 -0
- package/templates/channels/brand/light/192.png +0 -0
- package/templates/channels/brand/light/256.png +0 -0
- package/templates/channels/brand/light/32.png +0 -0
- package/templates/channels/brand/light/512.png +0 -0
- package/templates/channels/brand/light/64.png +0 -0
- package/templates/channels/brand/mono-white/128.png +0 -0
- package/templates/channels/brand/mono-white/192.png +0 -0
- package/templates/channels/brand/mono-white/256.png +0 -0
- package/templates/channels/brand/mono-white/32.png +0 -0
- package/templates/channels/brand/mono-white/512.png +0 -0
- package/templates/channels/brand/mono-white/64.png +0 -0
- package/templates/channels/brand/outline-32.png +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +6 -4
- package/templates/channels/chatgpt/integration/README.md +4 -5
- package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +14 -16
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +30 -0
- package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +93 -22
- package/templates/channels/microsoft-copilot/integration/README.md +2 -3
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -19
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +15 -0
- package/templates/channels/slack/integration/README.md +2 -4
- package/templates/channels/teams-bot/install.template.md.hbs +4 -0
- package/templates/channels/teams-bot/integration/README.md +3 -5
- package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
- package/templates/python/docker-compose.hbs +36 -0
- package/templates/typescript/docker-compose.hbs +36 -0
- package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +0 -374
- package/.cursor/process/README.md +0 -9
- package/.cursor/rules/anchor-docs.mdc +0 -15
- package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
- package/.cursor/rules/cli-layout.mdc +0 -81
- package/.cursor/rules/cli-product-neutral.mdc +0 -43
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
- package/.cursor/rules/docs-rules.mdc +0 -32
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
- package/.cursor/rules/project-rules.mdc +0 -913
- package/.cursor/skills/README.md +0 -15
- package/.dockerignore +0 -52
- package/.eslintignore +0 -22
- package/.markdownlint.json +0 -14
- package/anchor-docs/README.md +0 -10
- package/anchor-docs/_TEMPLATE +0 -24
- package/babel.config.js +0 -6
- package/bin/builder-api-cleanup.js +0 -26
- package/bin/builder-api-nest.js +0 -10
- package/bin/builder-api-spike.js +0 -19
- package/enterprise-knowledge/README.md +0 -50
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
- package/integration/README.md +0 -81
- package/integration/github/README.md +0 -53
- package/integration/github/application.json +0 -21
- package/integration/github/deploy.js +0 -72
- package/integration/github/env.template +0 -11
- package/integration/github/github-datasource-issue-comments.json +0 -239
- package/integration/github/github-datasource-issues.json +0 -399
- package/integration/github/github-datasource-repository.json +0 -354
- package/integration/github/github-deploy.json +0 -1202
- package/integration/github/github-system.json +0 -82
- package/integration/hubspot-test/README.md +0 -159
- package/integration/hubspot-test/application.json +0 -54
- package/integration/hubspot-test/companies.json +0 -2048
- package/integration/hubspot-test/create-hubspot.js +0 -523
- package/integration/hubspot-test/env.template +0 -4
- package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
- package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
- package/integration/hubspot-test/hubspot-test-system.json +0 -74
- package/integration/hubspot-test/rbac.json +0 -166
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
- package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
- package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
- package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
- package/integration/hubspot-test/test-dataplane-down.js +0 -209
- package/integration/hubspot-test/test.js +0 -1588
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
- package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
- package/integration/roundtrip-test-local/README.md +0 -143
- package/integration/roundtrip-test-local/application.yaml +0 -13
- package/integration/roundtrip-test-local/env.template +0 -15
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
- package/integration/roundtrip-test-local2/README.md +0 -143
- package/integration/roundtrip-test-local2/application.yaml +0 -13
- package/integration/roundtrip-test-local2/env.template +0 -15
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
- package/integration/test/wizard.yaml +0 -8
- package/jest.config.coverage.js +0 -37
- package/jest.config.default.js +0 -11
- package/jest.config.integration.fixtures.js +0 -22
- package/jest.config.integration.js +0 -33
- package/jest.config.isolated.js +0 -11
- package/jest.config.manual.js +0 -30
- package/jest.global-live-fabrix-hooks.js +0 -36
- package/jest.isolated-projects.js +0 -260
- package/jest.projects.js +0 -76
- package/packages/builder-api/README.md +0 -120
- package/packages/builder-api/package.json +0 -30
- package/packages/builder-api/src/app.module.ts +0 -7
- package/packages/builder-api/src/auth/auth.module.ts +0 -5
- package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
- package/packages/builder-api/src/main.ts +0 -16
- package/packages/builder-api/tsconfig.json +0 -15
- package/scripts/check-builder-api-architecture-grep.js +0 -79
- package/scripts/check-datasource-test-run-schema-sync.js +0 -34
- package/scripts/ci-fix.sh +0 -19
- package/scripts/ci-simulate.sh +0 -19
- package/scripts/diagnose-cli.js +0 -150
- package/scripts/docker_image_content_gate.js +0 -47
- package/scripts/docker_image_content_gate.sh +0 -5
- package/scripts/export-builder-api-evidence.js +0 -262
- package/scripts/install-local.js +0 -490
- package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
- package/scripts/lib/builder-api-docker-staging-core.js +0 -183
- package/scripts/lib/docker-image-content-gate-core.js +0 -166
- package/scripts/lib/plan-actor.js +0 -109
- package/scripts/lib/plan-config.js +0 -20
- package/scripts/lib/plan-gates.js +0 -154
- package/scripts/lib/plan-meta.js +0 -104
- package/scripts/lib/plan-parse.js +0 -162
- package/scripts/lib/plan-prevalidate-gates.js +0 -337
- package/scripts/lib/plan-run-core.js +0 -125
- package/scripts/lib/plan-run-report.js +0 -119
- package/scripts/plan-approve.js +0 -24
- package/scripts/plan-archive.js +0 -49
- package/scripts/plan-run.js +0 -13
- package/scripts/plan-set-actor.js +0 -21
- package/scripts/plan-validate.js +0 -80
- package/scripts/pnpm/af.mjs +0 -110
- package/scripts/pnpm/check-quiet.mjs +0 -32
- package/scripts/pnpm/dev-install.mjs +0 -29
- package/scripts/pnpm/dev-reload.mjs +0 -18
- package/scripts/pnpm/help.mjs +0 -55
- package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
- package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
- package/scripts/pnpm/lib/spinner.mjs +0 -42
- package/scripts/pnpm-global-remove.js +0 -48
- package/scripts/stage_builder_api_for_docker.js +0 -65
- package/scripts/sync-builder-api-template.js +0 -44
- package/scripts/test-dataplane-bootstrap.js +0 -331
|
@@ -110,6 +110,9 @@ function buildAuthenticationFromMethod(systemKey, authType) {
|
|
|
110
110
|
if (method === 'none') {
|
|
111
111
|
return { authType: 'none' };
|
|
112
112
|
}
|
|
113
|
+
if (method === 'system') {
|
|
114
|
+
return { authType: 'system' };
|
|
115
|
+
}
|
|
113
116
|
const flat = buildFlatCredentialTemplate(systemKey, method);
|
|
114
117
|
return {
|
|
115
118
|
authType: 'credential',
|
|
@@ -174,6 +177,9 @@ function migrateAuthenticationToNestedSchema(authentication, systemKey) {
|
|
|
174
177
|
if (authentication.authType === 'none') {
|
|
175
178
|
return { authentication: { authType: 'none' }, changed: false };
|
|
176
179
|
}
|
|
180
|
+
if (authentication.authType === 'system') {
|
|
181
|
+
return { authentication: { authType: 'system' }, changed: false };
|
|
182
|
+
}
|
|
177
183
|
if (authentication.authType === 'apiProvider' && authentication.apiProvider) {
|
|
178
184
|
return { authentication, changed: false };
|
|
179
185
|
}
|
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
buildTraefikIngressBase,
|
|
32
32
|
computeTraefikStripPathPrefix
|
|
33
33
|
} = require('./compose-traefik-ingress-base');
|
|
34
|
+
const { buildTraefikExtraRouters } = require('./compose-traefik-extra-routes');
|
|
34
35
|
const { parseDeveloperIdNum } = require('./declarative-url-ports');
|
|
35
36
|
|
|
36
37
|
registerComposeHelpers();
|
|
@@ -250,13 +251,20 @@ function buildTraefikConfig(config, devId, scopeOpts = null, remoteServer = null
|
|
|
250
251
|
// Traefik must only attach routers to `web` for developer-id > 0; `websecure`+tls labels without
|
|
251
252
|
// matching certs break routing on Traefik 3.6+ for HTTP traffic (404 on PathPrefix).
|
|
252
253
|
const terminateTlsAtTraefik = base.tls === true && devNum === 0;
|
|
254
|
+
const stripPathPrefix = computeTraefikStripPathPrefix(base.path, resolvedHealth);
|
|
255
|
+
const extra = buildTraefikExtraRouters(config.frontDoorRouting, base.path);
|
|
253
256
|
return {
|
|
254
257
|
enabled: true,
|
|
255
258
|
host: base.host,
|
|
256
259
|
path: base.path,
|
|
257
260
|
tls: terminateTlsAtTraefik,
|
|
258
261
|
certStore: terminateTlsAtTraefik ? base.certStore || null : null,
|
|
259
|
-
stripPathPrefix
|
|
262
|
+
stripPathPrefix,
|
|
263
|
+
passThroughRouters: extra.passThroughRouters,
|
|
264
|
+
aliasRouters: extra.aliasRouters.map((r) => ({
|
|
265
|
+
...r,
|
|
266
|
+
stripPrimary: stripPathPrefix === true && base.path !== '/'
|
|
267
|
+
}))
|
|
260
268
|
};
|
|
261
269
|
}
|
|
262
270
|
|
|
@@ -424,6 +432,7 @@ module.exports = {
|
|
|
424
432
|
getImageName,
|
|
425
433
|
derivePathFromPattern,
|
|
426
434
|
buildTraefikConfig,
|
|
435
|
+
buildTraefikExtraRouters,
|
|
427
436
|
computeAlignedHealthCheckPath,
|
|
428
437
|
resolveHealthCheckPathWithFrontDoorVdir,
|
|
429
438
|
buildDevUsername,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extra Traefik routers from frontDoorRouting.requiresRuleSet + ruleSetConditions.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Schema-legal pass-through routes (plan 171.0). No invented keys.
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.1.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Normalize a route pattern to a PathPrefix value (no trailing slash / wildcards).
|
|
11
|
+
* @param {unknown} pattern
|
|
12
|
+
* @returns {string|null}
|
|
13
|
+
*/
|
|
14
|
+
function normalizeRoutePrefix(pattern) {
|
|
15
|
+
if (!pattern || typeof pattern !== 'string') {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const trimmed = pattern.trim();
|
|
19
|
+
if (!trimmed.startsWith('/')) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (trimmed === '/' || trimmed === '/*') {
|
|
23
|
+
return '/';
|
|
24
|
+
}
|
|
25
|
+
const withoutWildcards = trimmed.replace(/\/\*+$/g, '').replace(/\*+$/g, '');
|
|
26
|
+
const withoutTrailing = withoutWildcards.replace(/\/+$/g, '');
|
|
27
|
+
return withoutTrailing || '/';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Safe Traefik label id fragment from a path prefix.
|
|
32
|
+
* @param {string} prefix
|
|
33
|
+
* @param {number} index
|
|
34
|
+
* @returns {string}
|
|
35
|
+
*/
|
|
36
|
+
function routeIdFromPrefix(prefix, index) {
|
|
37
|
+
const slug = String(prefix || 'x')
|
|
38
|
+
.replace(/^\//, '')
|
|
39
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
40
|
+
.replace(/^-+|-+$/g, '')
|
|
41
|
+
.slice(0, 40);
|
|
42
|
+
return `${slug || 'route'}-${index}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Collect PathPrefix values from ruleSetConditions matchValues.
|
|
47
|
+
* @param {Object} frontDoor
|
|
48
|
+
* @returns {string[]}
|
|
49
|
+
*/
|
|
50
|
+
function matchValuesFromRuleSetConditions(frontDoor) {
|
|
51
|
+
if (frontDoor.requiresRuleSet !== true) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const conditions = Array.isArray(frontDoor.ruleSetConditions)
|
|
55
|
+
? frontDoor.ruleSetConditions
|
|
56
|
+
: [];
|
|
57
|
+
const prefixes = [];
|
|
58
|
+
conditions.forEach((condition) => {
|
|
59
|
+
if (!condition || typeof condition !== 'object') {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const values = Array.isArray(condition.matchValues) ? condition.matchValues : [];
|
|
63
|
+
values.forEach((raw) => {
|
|
64
|
+
const pathPrefix = normalizeRoutePrefix(raw);
|
|
65
|
+
if (pathPrefix && pathPrefix !== '/') {
|
|
66
|
+
prefixes.push(pathPrefix);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return prefixes;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Build Traefik extra-route descriptors from frontDoorRouting (schema fields only).
|
|
75
|
+
* @param {Object|null|undefined} frontDoor
|
|
76
|
+
* @param {string} _primaryPath - Resolved primary PathPrefix (unused; reserved for callers)
|
|
77
|
+
* @returns {{ passThroughRouters: object[], aliasRouters: object[] }}
|
|
78
|
+
*/
|
|
79
|
+
function buildTraefikExtraRouters(frontDoor, _primaryPath) {
|
|
80
|
+
const passThroughRouters = [];
|
|
81
|
+
const aliasRouters = [];
|
|
82
|
+
if (!frontDoor || typeof frontDoor !== 'object') {
|
|
83
|
+
return { passThroughRouters, aliasRouters };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const prefixes = matchValuesFromRuleSetConditions(frontDoor);
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
prefixes.forEach((pathPrefix, index) => {
|
|
89
|
+
if (seen.has(pathPrefix)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
seen.add(pathPrefix);
|
|
93
|
+
passThroughRouters.push({
|
|
94
|
+
id: routeIdFromPrefix(pathPrefix, index),
|
|
95
|
+
pathPrefix
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return { passThroughRouters, aliasRouters };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
normalizeRoutePrefix,
|
|
104
|
+
routeIdFromPrefix,
|
|
105
|
+
matchValuesFromRuleSetConditions,
|
|
106
|
+
buildTraefikExtraRouters
|
|
107
|
+
};
|
|
@@ -253,8 +253,8 @@ async function executeBuild(imageName, dockerfilePath, contextPath, tag, options
|
|
|
253
253
|
);
|
|
254
254
|
await executeDockerBuild(imageName, dockerfilePath, contextPath, tag, buildArgs, noCache);
|
|
255
255
|
|
|
256
|
-
//
|
|
257
|
-
if (options && options.tag && options.tag !== 'latest') {
|
|
256
|
+
// Also apply floating `latest` when building a version tag (matches dev-promote dual tags).
|
|
257
|
+
if (options && options.tag && options.tag !== 'latest' && options.tag !== 'main') {
|
|
258
258
|
const { execFileWithDockerEnv } = require('./docker-exec');
|
|
259
259
|
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
260
260
|
const env = await getDockerExecEnv();
|
|
@@ -98,7 +98,8 @@ const CATEGORIES = [
|
|
|
98
98
|
{ name: 'validate', term: 'validate [appKey|systemKey|file]' },
|
|
99
99
|
{ name: 'validate-json', term: 'validate-json [appKey|systemKey]' },
|
|
100
100
|
{ name: 'parameters', term: 'parameters validate' },
|
|
101
|
-
{ name: 'diff', term: 'diff <file1> <file2>' }
|
|
101
|
+
{ name: 'diff', term: 'diff <file1> <file2>' },
|
|
102
|
+
{ name: 'package-score', term: 'package-score --reference <dir> --candidate <dir>' }
|
|
102
103
|
]
|
|
103
104
|
},
|
|
104
105
|
{
|
|
@@ -111,6 +112,7 @@ const CATEGORIES = [
|
|
|
111
112
|
{ name: 'delete', term: 'delete <systemKey>' },
|
|
112
113
|
{ name: 'repair', term: 'repair <systemKey>' },
|
|
113
114
|
{ name: 'manifest', term: 'manifest get-section <systemKey> <sectionKey>' },
|
|
115
|
+
{ name: 'integration-definition', term: 'integration-definition apply <file>' },
|
|
114
116
|
{ name: 'channel', term: 'channel scaffold <channelTarget>' },
|
|
115
117
|
{ name: 'datasource' },
|
|
116
118
|
{ name: 'datasource load', term: 'datasource load <datasourceKey>' },
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Promote a developer-scoped local Docker image to the manifest base repository (tag only).
|
|
3
3
|
*
|
|
4
|
-
* @fileoverview Used by `aifabrix build --base --from-dev` and dev-promote workflows
|
|
4
|
+
* @fileoverview Used by `aifabrix build --base --from-dev` and dev-promote workflows.
|
|
5
|
+
* Promote always applies two base tags: `latest` (floating) and the version tag (TAG / package version).
|
|
5
6
|
* @author AI Fabrix Team
|
|
6
|
-
* @version 1.
|
|
7
|
+
* @version 1.2.0
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
'use strict';
|
|
@@ -15,6 +16,12 @@ const { execWithDockerEnv } = require('./docker-exec');
|
|
|
15
16
|
const logger = require('./logger');
|
|
16
17
|
const { formatSuccessLine } = require('./cli-test-layout-chalk');
|
|
17
18
|
|
|
19
|
+
/** Floating base tag applied on every promote alongside the version tag (matches setup manifests). */
|
|
20
|
+
const PROMOTE_FLOATING_TAG = 'latest';
|
|
21
|
+
|
|
22
|
+
/** @deprecated Use {@link PROMOTE_FLOATING_TAG}. Kept for callers that imported the old name. */
|
|
23
|
+
const PROMOTE_MAIN_TAG = PROMOTE_FLOATING_TAG;
|
|
24
|
+
|
|
18
25
|
/**
|
|
19
26
|
* @param {string} value
|
|
20
27
|
* @returns {string}
|
|
@@ -61,6 +68,34 @@ async function dockerTagImageRef(sourceRef, targetRef) {
|
|
|
61
68
|
await execWithDockerEnv(`docker tag ${shellQuote(sourceRef)} ${shellQuote(targetRef)}`);
|
|
62
69
|
}
|
|
63
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Version tag for promote (not floating aliases).
|
|
73
|
+
* @param {Object} options
|
|
74
|
+
* @returns {string}
|
|
75
|
+
*/
|
|
76
|
+
function resolvePromoteVersionTag(options = {}) {
|
|
77
|
+
const raw = String(options.tag || '').trim();
|
|
78
|
+
// `main` accepted as legacy alias for the floating tag.
|
|
79
|
+
if (!raw || raw === PROMOTE_FLOATING_TAG || raw === 'main') {
|
|
80
|
+
return PROMOTE_FLOATING_TAG;
|
|
81
|
+
}
|
|
82
|
+
return raw;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Base tags to apply on promote: version first, then `latest` when distinct.
|
|
87
|
+
* @param {Object} options
|
|
88
|
+
* @returns {string[]}
|
|
89
|
+
*/
|
|
90
|
+
function resolvePromoteBaseTags(options = {}) {
|
|
91
|
+
const versionTag = resolvePromoteVersionTag(options);
|
|
92
|
+
const tags = [versionTag];
|
|
93
|
+
if (versionTag !== PROMOTE_FLOATING_TAG) {
|
|
94
|
+
tags.push(PROMOTE_FLOATING_TAG);
|
|
95
|
+
}
|
|
96
|
+
return tags;
|
|
97
|
+
}
|
|
98
|
+
|
|
64
99
|
/**
|
|
65
100
|
* @param {string} appName
|
|
66
101
|
* @param {Object} variables
|
|
@@ -69,7 +104,7 @@ async function dockerTagImageRef(sourceRef, targetRef) {
|
|
|
69
104
|
* @returns {Promise<{ devRef: string, baseRef: string, devTag: string, baseTag: string }>}
|
|
70
105
|
*/
|
|
71
106
|
async function resolveDevAndBaseImageRefs(appName, variables, developerId, options) {
|
|
72
|
-
const baseTag = options
|
|
107
|
+
const baseTag = resolvePromoteVersionTag(options);
|
|
73
108
|
const devTag = options.fromDevTag || 'latest';
|
|
74
109
|
const { buildImageName: baseName } = await resolveBuildDockerTagNames(appName, variables, developerId, {
|
|
75
110
|
...options,
|
|
@@ -93,31 +128,68 @@ async function resolveDevAndBaseImageRefs(appName, variables, developerId, optio
|
|
|
93
128
|
* @param {Object} appConfig
|
|
94
129
|
* @param {string|number} developerId
|
|
95
130
|
* @param {Object} options
|
|
96
|
-
* @returns {Promise<{
|
|
131
|
+
* @returns {Promise<{
|
|
132
|
+
* devRef: string,
|
|
133
|
+
* baseRef: string,
|
|
134
|
+
* baseName: string,
|
|
135
|
+
* baseTags: string[]
|
|
136
|
+
* }|null>}
|
|
97
137
|
*/
|
|
98
138
|
async function resolvePromoteSourceAndTargetRefs(appName, appConfig, developerId, options) {
|
|
99
|
-
const
|
|
139
|
+
const baseTags = resolvePromoteBaseTags(options);
|
|
140
|
+
const versionTag = baseTags[0];
|
|
100
141
|
const devTagCandidates = ['latest'];
|
|
101
|
-
if (
|
|
102
|
-
devTagCandidates.push(
|
|
142
|
+
if (versionTag !== 'latest' && !devTagCandidates.includes(versionTag)) {
|
|
143
|
+
devTagCandidates.push(versionTag);
|
|
103
144
|
}
|
|
104
145
|
for (const fromDevTag of devTagCandidates) {
|
|
105
146
|
const refs = await resolveDevAndBaseImageRefs(appName, appConfig, developerId, {
|
|
106
147
|
...options,
|
|
148
|
+
tag: versionTag,
|
|
107
149
|
fromDevTag
|
|
108
150
|
});
|
|
109
151
|
if (await dockerImageRefExists(refs.devRef)) {
|
|
110
|
-
|
|
152
|
+
const baseName = refs.baseRef.slice(0, refs.baseRef.lastIndexOf(':'));
|
|
153
|
+
return {
|
|
154
|
+
devRef: refs.devRef,
|
|
155
|
+
baseRef: refs.baseRef,
|
|
156
|
+
baseName,
|
|
157
|
+
baseTags
|
|
158
|
+
};
|
|
111
159
|
}
|
|
112
160
|
}
|
|
113
161
|
return null;
|
|
114
162
|
}
|
|
115
163
|
|
|
164
|
+
/**
|
|
165
|
+
* @param {string} baseName
|
|
166
|
+
* @param {string[]} baseTags
|
|
167
|
+
* @param {string|null} devId
|
|
168
|
+
* @returns {Promise<boolean>} true when every target already matches dev image id
|
|
169
|
+
*/
|
|
170
|
+
async function allBaseTagsMatchDev(baseName, baseTags, devId) {
|
|
171
|
+
if (!devId) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
for (const tag of baseTags) {
|
|
175
|
+
const ref = `${baseName}:${tag}`;
|
|
176
|
+
if (!(await dockerImageRefExists(ref))) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const baseId = await readDockerImageId(ref);
|
|
180
|
+
if (!baseId || baseId !== devId) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
|
|
116
187
|
/**
|
|
117
188
|
* Tag developer-scoped image as manifest base when present locally.
|
|
189
|
+
* Always applies the version tag and `latest`.
|
|
118
190
|
* @param {string} appName
|
|
119
191
|
* @param {Object} options - build options (`base`, `tag`, `registry`, `fromDev`)
|
|
120
|
-
* @returns {Promise<string|null>} base image ref when promoted
|
|
192
|
+
* @returns {Promise<string|null>} primary base image ref (version) when promoted; null when missing
|
|
121
193
|
*/
|
|
122
194
|
async function tryPromoteDevImageToBase(appName, options = {}) {
|
|
123
195
|
if (options.base !== true) {
|
|
@@ -135,19 +207,27 @@ async function tryPromoteDevImageToBase(appName, options = {}) {
|
|
|
135
207
|
if (!resolved) {
|
|
136
208
|
return null;
|
|
137
209
|
}
|
|
138
|
-
const { devRef, baseRef } = resolved;
|
|
210
|
+
const { devRef, baseRef, baseName, baseTags } = resolved;
|
|
139
211
|
|
|
140
212
|
const devId = await readDockerImageId(devRef);
|
|
141
|
-
if (await
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
213
|
+
if (await allBaseTagsMatchDev(baseName, baseTags, devId)) {
|
|
214
|
+
logger.log(
|
|
215
|
+
formatSuccessLine(
|
|
216
|
+
`Base image already matches dev build: ${baseTags.map((t) => `${baseName}:${t}`).join(', ')}`
|
|
217
|
+
)
|
|
218
|
+
);
|
|
219
|
+
return baseRef;
|
|
147
220
|
}
|
|
148
221
|
|
|
149
|
-
|
|
150
|
-
|
|
222
|
+
for (const tag of baseTags) {
|
|
223
|
+
const targetRef = `${baseName}:${tag}`;
|
|
224
|
+
await dockerTagImageRef(devRef, targetRef);
|
|
225
|
+
}
|
|
226
|
+
logger.log(
|
|
227
|
+
formatSuccessLine(
|
|
228
|
+
`Promoted dev image to base (tag only): ${baseTags.map((t) => `${baseName}:${t}`).join(', ')}`
|
|
229
|
+
)
|
|
230
|
+
);
|
|
151
231
|
return baseRef;
|
|
152
232
|
}
|
|
153
233
|
|
|
@@ -160,10 +240,14 @@ function shouldAttemptDevPromote(options) {
|
|
|
160
240
|
}
|
|
161
241
|
|
|
162
242
|
module.exports = {
|
|
243
|
+
PROMOTE_FLOATING_TAG,
|
|
244
|
+
PROMOTE_MAIN_TAG,
|
|
163
245
|
tryPromoteDevImageToBase,
|
|
164
246
|
shouldAttemptDevPromote,
|
|
165
247
|
resolveDevAndBaseImageRefs,
|
|
166
248
|
resolvePromoteSourceAndTargetRefs,
|
|
249
|
+
resolvePromoteBaseTags,
|
|
250
|
+
resolvePromoteVersionTag,
|
|
167
251
|
dockerImageRefExists,
|
|
168
252
|
readDockerImageId,
|
|
169
253
|
dockerTagImageRef
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transient developer-id override for CLI commands (does not persist config).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Resolve optional --developer-id / --developer without setDeveloperId
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { validateAndNormalizeDeveloperId } = require('../core/config-normalize');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Resolve optional CLI developer override (transient — does not persist).
|
|
13
|
+
* Prefers developerId (--developer-id) over developer (-d/--developer).
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} [options] - Commander options
|
|
16
|
+
* @returns {string|undefined} Normalized digit string, or undefined to use config
|
|
17
|
+
*/
|
|
18
|
+
function resolveTransientDeveloperIdFromOptions(options) {
|
|
19
|
+
const raw = options && (options.developerId ?? options.developer);
|
|
20
|
+
if (raw === undefined || raw === null || raw === '') {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return validateAndNormalizeDeveloperId(raw);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
resolveTransientDeveloperIdFromOptions
|
|
28
|
+
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifabrix/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.53.0",
|
|
4
4
|
"description": "AI Fabrix Builder — CLI and developer scripts (pnpm + af)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"aifabrix": "bin/aifabrix.js",
|
|
8
8
|
"af": "bin/aifabrix.js"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/aifabrix.js",
|
|
12
|
+
"lib/",
|
|
13
|
+
"templates/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
10
17
|
"scripts": {
|
|
11
18
|
"help": "node scripts/pnpm/help.mjs",
|
|
12
19
|
"dev-install": "node scripts/pnpm/dev-install.mjs",
|
|
@@ -21,32 +28,23 @@
|
|
|
21
28
|
"lint:fix": "eslint . --ext .js --fix",
|
|
22
29
|
"test": "node tests/scripts/test-wrapper.js",
|
|
23
30
|
"build": "npm run lint && npm run test",
|
|
24
|
-
"build:ci": "npm run lint && npm run check:schema-sync && npm run check:flags && npm run test:ci",
|
|
31
|
+
"build:ci": "npm run lint && npm run check:schema-sync && npm run check:flags && npm run check:cli-help && npm run test:ci",
|
|
25
32
|
"test:ci": "bash tests/scripts/ci-simulate.sh",
|
|
26
|
-
"install:local": "node scripts/install-local.js && which aifabrix && which af",
|
|
27
|
-
"uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
|
|
28
|
-
"sync-json": "node scripts/sync-builder-api-template.js",
|
|
29
|
-
"builder-api:build": "tsc -p packages/builder-api/tsconfig.json",
|
|
30
|
-
"builder-api:nest": "node bin/builder-api-nest.js",
|
|
31
|
-
"builder-api:cleanup": "node bin/builder-api-cleanup.js",
|
|
32
|
-
"check:builder-api-arch": "node scripts/check-builder-api-architecture-grep.js",
|
|
33
33
|
"check:schema-sync": "node scripts/check-datasource-test-run-schema-sync.js",
|
|
34
34
|
"check:flags": "jest tests/lib/schema/flag-map-validation-run.test.js --runInBand --config jest.config.default.js",
|
|
35
|
-
"
|
|
36
|
-
"test:154-docker-ip": "jest --runInBand tests/scripts/stage_builder_api_for_docker.test.js tests/scripts/docker_image_content_gate.test.js",
|
|
37
|
-
"stage-builder-api-docker": "node scripts/stage_builder_api_for_docker.js",
|
|
38
|
-
"docker-image-build-builder-api": "npm run stage-builder-api-docker && docker build -f builder/builder-api/Dockerfile -t builder-api:gate .",
|
|
39
|
-
"docker-image-gate-builder-api": "npm run docker-image-build-builder-api && node scripts/docker_image_content_gate.js builder-api:gate builder-api",
|
|
35
|
+
"check:cli-help": "node scripts/check-cli-help-examples.js",
|
|
40
36
|
"test:manual": "jest --config jest.config.manual.js --runInBand",
|
|
41
37
|
"test:integration": "jest --config jest.config.integration.js --runInBand",
|
|
42
38
|
"test:integration:fixtures": "jest --config jest.config.integration.fixtures.js --runInBand",
|
|
43
39
|
"test:hubspot-wizard": "node integration/hubspot-test/test.js",
|
|
44
40
|
"test:hubspot-dataplane-down": "node integration/hubspot-test/test-dataplane-down.js",
|
|
45
41
|
"test:coverage": "cross-env RUN_COVERAGE=1 node tests/scripts/test-wrapper.js",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
42
|
+
"docker-image-gate-builder-api": "node scripts/stage_builder_api_for_docker.js && docker build -f builder/builder-api/Dockerfile -t builder-api:gate . && node scripts/docker_image_content_gate.js builder-api:gate builder-api",
|
|
43
|
+
"install:local": "node scripts/install-local.js && which aifabrix && which af",
|
|
44
|
+
"uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
|
|
48
45
|
"install:global": "npm install -g . --force && which aifabrix && which af && aifabrix --version",
|
|
49
46
|
"uninstall:global": "npm uninstall -g @aifabrix/builder",
|
|
47
|
+
"sync-json": "node scripts/sync-builder-api-template.js",
|
|
50
48
|
"pack": "npm run build && npm pack",
|
|
51
49
|
"validate": "npm run build",
|
|
52
50
|
"prepublishOnly": "npm run validate"
|
package/templates/README.md
CHANGED
|
@@ -15,7 +15,18 @@ Application templates are folder-based and located under `templates/applications
|
|
|
15
15
|
- `templates/applications/keycloak/` - Keycloak application template
|
|
16
16
|
- `templates/applications/builder-api/` - Builder API platform webapp (published from `builder/builder-api/` via `npm run sync-json`)
|
|
17
17
|
|
|
18
|
-
**Platform
|
|
18
|
+
**Platform template sync (`pnpm run sync-json`):** Publishes local `builder/builder-api/` (`application.yaml`, `Dockerfile`, `env.template`) and, when sibling checkouts exist, pulls the same file sets as miso/dataplane sync-json:
|
|
19
|
+
|
|
20
|
+
| SSOT | → template |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `aifabrix-builder/builder/builder-api/` | `templates/applications/builder-api/` |
|
|
23
|
+
| `aifabrix-miso/builder/miso-controller/` (`env.template`, `rbac.yaml`, `application.yaml`) | `templates/applications/miso-controller/` |
|
|
24
|
+
| `aifabrix-miso/builder/keycloak/` (`env.template`, `application.yaml`) | `templates/applications/keycloak/` |
|
|
25
|
+
| `aifabrix-dataplane/builder/dataplane/` (`env.template`, `rbac.yaml`, `application.yaml`) | `templates/applications/dataplane/` |
|
|
26
|
+
|
|
27
|
+
**Schema master (dataplane):** Also copies dataplane `app/schemas/json/` core integration schemas + `type/*` and `configs/deployment-rules.yaml` into `lib/schema/` (same contract as dataplane `make sync-json`). Do not hand-edit those mirrors — edit dataplane SSOT, then sync. Builder-owned schemas in `lib/schema/` (wizard, infra, etc.) are left alone.
|
|
28
|
+
|
|
29
|
+
Overrides: `AIFABRIX_MISO_SRC`, `AIFABRIX_DATAPLANE_SRC` / `AIFABRIX_DATAPLANE_ROOT` (repo roots). Install with `aifabrix up-platform` / `up-builder-api` — do not hand-edit the template copies as primary.
|
|
19
30
|
|
|
20
31
|
**Template Validation:**
|
|
21
32
|
- Template folder must exist in `templates/applications/<name>/`
|
|
@@ -5,7 +5,7 @@ app:
|
|
|
5
5
|
description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
|
|
6
6
|
type: webapp
|
|
7
7
|
language: python # Explicitly specify Python language
|
|
8
|
-
version: 2.0.
|
|
8
|
+
version: 2.0.31
|
|
9
9
|
# Image Configuration
|
|
10
10
|
# Set tag to match your build (example: aifabrix build dataplane -t 1.0.0).
|
|
11
11
|
# Registry is required so the controller can pull the image (avoids docker-not-found on the controller host).
|
|
@@ -29,6 +29,13 @@ frontDoorRouting:
|
|
|
29
29
|
internalDockerUseOriginOnly: false
|
|
30
30
|
host: ${DEV_USERNAME}.${REMOTE_HOST}
|
|
31
31
|
tls: ${TLS_ENABLED}
|
|
32
|
+
# Origin RFC 9728 PRM (outside /data PathPrefix) — Builder Traefik pass-through (plan 171.0).
|
|
33
|
+
requiresRuleSet: true
|
|
34
|
+
ruleSetConditions:
|
|
35
|
+
- type: UrlPath
|
|
36
|
+
operator: BeginsWith
|
|
37
|
+
matchValues:
|
|
38
|
+
- /.well-known/oauth-protected-resource/data
|
|
32
39
|
|
|
33
40
|
# Azure Requirements
|
|
34
41
|
requires:
|
|
@@ -88,7 +95,8 @@ build:
|
|
|
88
95
|
# - MISO_*, KEYCLOAK_* → auto-generated during Azure install
|
|
89
96
|
# - AI params / provider secrets → LLM external systems + secret store
|
|
90
97
|
# (never product OPENAI_* / AZURE_OPENAI_*). ≥2 providers →
|
|
91
|
-
# ENTERPRISE_LLM_DEFAULT_SELECTOR (portal
|
|
98
|
+
# ENTERPRISE_LLM_DEFAULT_SELECTOR (portal/env deploy default); Environment
|
|
99
|
+
# Settings ai.llmProvider overrides without redeploy.
|
|
92
100
|
# - ENVIRONMENT → set by deployment target
|
|
93
101
|
|
|
94
102
|
configuration:
|
|
@@ -44,7 +44,7 @@ API_KEY_BYPASS_ROLES=full-access
|
|
|
44
44
|
|
|
45
45
|
# API Configuration
|
|
46
46
|
API_V1_STR=/api/v1
|
|
47
|
-
VERSION=2.0.
|
|
47
|
+
VERSION=2.0.31
|
|
48
48
|
# Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
|
|
49
49
|
# MIN_BUILDER_CLI_VERSION=2.45.0
|
|
50
50
|
MIN_BUILDER_CLI_VERSION=2.45.5
|
|
@@ -155,11 +155,10 @@ MISO_PIPELINE_ENV_KEY=
|
|
|
155
155
|
|
|
156
156
|
# LLM: chat/embed route through governed enterprise-llm only. Provider credentials
|
|
157
157
|
# live on LLM provider external systems + dataplane secret store (not product .env).
|
|
158
|
-
#
|
|
159
|
-
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
# enterprise-llm (fail-closed if empty). Portal category LLM can override.
|
|
158
|
+
# Deploy-time default provider (systemKey) when Environment Settings ai.llmProvider
|
|
159
|
+
# is empty. Operators can override in Environment Settings without redeploying.
|
|
160
|
+
# When ≥2 LLM providers are published and both settings and this env are empty,
|
|
161
|
+
# resolve fails closed. Ignored when only one provider is published.
|
|
163
162
|
# Lab default: openai (catalog also ships azure-openai).
|
|
164
163
|
ENTERPRISE_LLM_DEFAULT_SELECTOR=openai
|
|
165
164
|
|
|
@@ -180,6 +179,8 @@ ABAC_EXPLAIN_MODE_ENABLED=false
|
|
|
180
179
|
ABAC_PERFORMANCE_THRESHOLD_MS=1000
|
|
181
180
|
|
|
182
181
|
# RBAC Audit Configuration
|
|
182
|
+
# When true, audit denials (rbac.permission.check.failure) and decision traces.
|
|
183
|
+
# Successful allow checks are not audited (no forensic value; floods every request).
|
|
183
184
|
RBAC_AUDIT_ENABLED=true
|
|
184
185
|
# RBAC audit detail: summary | detailed | explain
|
|
185
186
|
RBAC_AUDIT_DETAIL_LEVEL=summary
|
|
@@ -4,7 +4,7 @@ app:
|
|
|
4
4
|
displayName: 'Miso Controller'
|
|
5
5
|
description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
|
|
6
6
|
type: webapp
|
|
7
|
-
version: '2.0.
|
|
7
|
+
version: '2.0.34'
|
|
8
8
|
|
|
9
9
|
# Image Configuration
|
|
10
10
|
# Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
|
|
@@ -81,7 +81,7 @@ configuration:
|
|
|
81
81
|
# Operations & Debugging
|
|
82
82
|
# -------------------------------------------------------------------------
|
|
83
83
|
- name: LOG_LEVEL
|
|
84
|
-
category:
|
|
84
|
+
category: Operations & Debugging
|
|
85
85
|
portalInput:
|
|
86
86
|
field: select
|
|
87
87
|
label: 'Log Level'
|
|
@@ -92,7 +92,7 @@ configuration:
|
|
|
92
92
|
- error
|
|
93
93
|
|
|
94
94
|
- name: ENABLE_API_DOCS
|
|
95
|
-
category:
|
|
95
|
+
category: Operations & Debugging
|
|
96
96
|
portalInput:
|
|
97
97
|
field: select
|
|
98
98
|
label: 'Enable API Documentation (Swagger/ReDoc)'
|
|
@@ -101,7 +101,7 @@ configuration:
|
|
|
101
101
|
- 'false'
|
|
102
102
|
|
|
103
103
|
- name: FAST_STARTUP
|
|
104
|
-
category:
|
|
104
|
+
category: Operations & Debugging
|
|
105
105
|
portalInput:
|
|
106
106
|
field: select
|
|
107
107
|
label: 'Fast Startup (skip non-critical init)'
|
|
@@ -110,7 +110,7 @@ configuration:
|
|
|
110
110
|
- 'false'
|
|
111
111
|
|
|
112
112
|
- name: LOG_TO_FILE
|
|
113
|
-
category:
|
|
113
|
+
category: Operations & Debugging
|
|
114
114
|
portalInput:
|
|
115
115
|
field: select
|
|
116
116
|
label: 'Log to File'
|
|
@@ -122,7 +122,7 @@ configuration:
|
|
|
122
122
|
# Keycloak Events (feature flag)
|
|
123
123
|
# -------------------------------------------------------------------------
|
|
124
124
|
- name: KEYCLOAK_EVENTS_ENABLED
|
|
125
|
-
category:
|
|
125
|
+
category: Keycloak Events
|
|
126
126
|
portalInput:
|
|
127
127
|
field: select
|
|
128
128
|
label: 'Keycloak Events (sync users/groups)'
|
|
@@ -130,18 +130,33 @@ configuration:
|
|
|
130
130
|
- 'true'
|
|
131
131
|
- 'false'
|
|
132
132
|
|
|
133
|
+
# -------------------------------------------------------------------------
|
|
134
|
+
# Identity — local user password / invitation
|
|
135
|
+
# -------------------------------------------------------------------------
|
|
136
|
+
- name: IDENTITY_LOCAL_PASSWORD_MODE
|
|
137
|
+
category: Identity
|
|
138
|
+
portalInput:
|
|
139
|
+
field: select
|
|
140
|
+
label: 'Password setup for new local users'
|
|
141
|
+
placeholder: 'Choose how new users set their password'
|
|
142
|
+
options:
|
|
143
|
+
- label: 'Send invitation email (user sets their own password)'
|
|
144
|
+
value: email
|
|
145
|
+
- label: 'Show a one-time temporary password to the admin'
|
|
146
|
+
value: admin-reveal
|
|
147
|
+
|
|
133
148
|
# -------------------------------------------------------------------------
|
|
134
149
|
# Rate Limiting (tune for environment)
|
|
135
150
|
# -------------------------------------------------------------------------
|
|
136
151
|
- name: RATE_LIMIT_WINDOW_MS
|
|
137
|
-
category:
|
|
152
|
+
category: Rate Limiting
|
|
138
153
|
portalInput:
|
|
139
154
|
field: text
|
|
140
155
|
label: 'Rate Limit Window (milliseconds)'
|
|
141
156
|
placeholder: '900000'
|
|
142
157
|
|
|
143
158
|
- name: RATE_LIMIT_MAX
|
|
144
|
-
category:
|
|
159
|
+
category: Rate Limiting
|
|
145
160
|
portalInput:
|
|
146
161
|
field: text
|
|
147
162
|
label: 'Rate Limit Max Requests per Window'
|