@aifabrix/builder 2.8.0 → 2.10.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 (46) hide show
  1. package/integration/hubspot/README.md +136 -0
  2. package/integration/hubspot/env.template +9 -0
  3. package/integration/hubspot/hubspot-deploy-company.json +200 -0
  4. package/integration/hubspot/hubspot-deploy-contact.json +228 -0
  5. package/integration/hubspot/hubspot-deploy-deal.json +248 -0
  6. package/integration/hubspot/hubspot-deploy.json +91 -0
  7. package/integration/hubspot/variables.yaml +17 -0
  8. package/lib/app-config.js +4 -3
  9. package/lib/app-deploy.js +8 -20
  10. package/lib/app-dockerfile.js +7 -9
  11. package/lib/app-prompts.js +6 -5
  12. package/lib/app-push.js +9 -9
  13. package/lib/app-register.js +23 -5
  14. package/lib/app-rotate-secret.js +10 -0
  15. package/lib/app-run.js +5 -11
  16. package/lib/app.js +42 -14
  17. package/lib/build.js +20 -16
  18. package/lib/cli.js +61 -2
  19. package/lib/commands/login.js +7 -1
  20. package/lib/datasource-deploy.js +14 -20
  21. package/lib/external-system-deploy.js +123 -40
  22. package/lib/external-system-download.js +431 -0
  23. package/lib/external-system-generator.js +13 -10
  24. package/lib/external-system-test.js +446 -0
  25. package/lib/generator-builders.js +323 -0
  26. package/lib/generator.js +200 -292
  27. package/lib/schema/application-schema.json +853 -852
  28. package/lib/schema/env-config.yaml +9 -1
  29. package/lib/schema/external-datasource.schema.json +823 -49
  30. package/lib/schema/external-system.schema.json +96 -78
  31. package/lib/templates.js +36 -5
  32. package/lib/utils/api-error-handler.js +12 -12
  33. package/lib/utils/cli-utils.js +4 -4
  34. package/lib/utils/device-code.js +65 -2
  35. package/lib/utils/env-template.js +5 -4
  36. package/lib/utils/external-system-display.js +159 -0
  37. package/lib/utils/external-system-validators.js +245 -0
  38. package/lib/utils/paths.js +151 -1
  39. package/lib/utils/schema-resolver.js +7 -2
  40. package/lib/validator.js +5 -2
  41. package/package.json +1 -1
  42. package/templates/applications/keycloak/env.template +8 -2
  43. package/templates/applications/keycloak/variables.yaml +3 -3
  44. package/templates/applications/miso-controller/env.template +23 -10
  45. package/templates/applications/miso-controller/rbac.yaml +263 -213
  46. package/templates/applications/miso-controller/variables.yaml +3 -3
@@ -0,0 +1,136 @@
1
+ # HubSpot CRM Integration
2
+
3
+ HubSpot CRM external system integration with companies, contacts, and deals datasources.
4
+
5
+ ## Overview
6
+
7
+ This integration connects to HubSpot CRM API and exposes companies, contacts, and deals data via the AI Fabrix Dataplane. Data is automatically synced and made available for querying via MCP/OpenAPI.
8
+
9
+ ## Files
10
+
11
+ - `variables.yaml` - Application configuration with externalIntegration block
12
+ - `hubspot-deploy.json` - External system definition with OAuth2 authentication
13
+ - `hubspot-deploy-company.json` - Companies datasource with field mappings
14
+ - `hubspot-deploy-contact.json` - Contacts datasource with field mappings
15
+ - `hubspot-deploy-deal.json` - Deals datasource with field mappings
16
+ - `env.template` - Environment variables template with kv:// references
17
+
18
+ ## Setup
19
+
20
+ ### 1. Configure OAuth2 Credentials
21
+
22
+ 1. Register an OAuth2 app in HubSpot:
23
+ - Go to HubSpot Settings → Integrations → Private Apps
24
+ - Create a new private app
25
+ - Grant scopes:
26
+ - `crm.objects.companies.read`
27
+ - `crm.objects.companies.write`
28
+ - `crm.objects.contacts.read`
29
+ - `crm.objects.contacts.write`
30
+ - `crm.objects.deals.read`
31
+ - `crm.objects.deals.write`
32
+
33
+ 2. Set credentials via Miso Controller or Dataplane portal:
34
+ - Navigate to the HubSpot external system configuration
35
+ - Enter OAuth2 Client ID and Client Secret
36
+ - Values are automatically stored in Key Vault by the platform
37
+ - No manual Key Vault operations required
38
+
39
+ **Note:** The platform manages Key Vault storage automatically. You only need to provide values via the interface.
40
+
41
+ ### 2. Validate Configuration
42
+
43
+ ```bash
44
+ aifabrix validate hubspot
45
+ ```
46
+
47
+ ### 3. Deploy
48
+
49
+ ```bash
50
+ # Login to controller
51
+ aifabrix login --controller https://controller.aifabrix.ai --method device --environment dev
52
+
53
+ # Register application
54
+ aifabrix app register hubspot --environment dev
55
+
56
+ # Deploy entire system
57
+ aifabrix deploy hubspot --controller https://controller.aifabrix.ai --environment dev
58
+
59
+ # Or deploy individual datasources for testing
60
+ aifabrix datasource deploy hubspot-company --environment dev --file integration/hubspot/hubspot-deploy-company.json
61
+ aifabrix datasource deploy hubspot-contact --environment dev --file integration/hubspot/hubspot-deploy-contact.json
62
+ aifabrix datasource deploy hubspot-deal --environment dev --file integration/hubspot/hubspot-deploy-deal.json
63
+ ```
64
+
65
+ ## Field Mappings
66
+
67
+ HubSpot uses a nested properties structure. Field mappings transform this to flat, normalized fields:
68
+
69
+ **HubSpot structure:**
70
+ ```json
71
+ {
72
+ "properties": {
73
+ "name": { "value": "Acme Corp" },
74
+ "country": { "value": "us" }
75
+ }
76
+ }
77
+ ```
78
+
79
+ **Normalized structure:**
80
+ ```json
81
+ {
82
+ "name": "Acme Corp",
83
+ "country": "US"
84
+ }
85
+ ```
86
+
87
+ Transformations applied:
88
+ - `trim` - Remove whitespace
89
+ - `toLower` - Convert to lowercase (for domains, emails)
90
+ - `toUpper` - Convert to uppercase (for country codes)
91
+
92
+ ## Datasources
93
+
94
+ ### Companies (`hubspot-company`)
95
+ - **Resource Type:** `customer`
96
+ - **Access Fields:** `country`, `domain` (for ABAC filtering)
97
+ - **Fields:** `id`, `name`, `domain`, `country`, `city`, `industry`, `website`, `phone`, `createdAt`, `updatedAt`
98
+
99
+ ### Contacts (`hubspot-contact`)
100
+ - **Resource Type:** `contact`
101
+ - **Access Fields:** `email`, `country` (for ABAC filtering)
102
+ - **Fields:** `id`, `firstName`, `lastName`, `email`, `phone`, `company`, `jobTitle`, `address`, `city`, `country`, `createdAt`, `updatedAt`
103
+
104
+ ### Deals (`hubspot-deal`)
105
+ - **Resource Type:** `deal`
106
+ - **Access Fields:** `stage`, `pipeline` (for ABAC filtering)
107
+ - **Fields:** `id`, `dealName`, `amount`, `currency`, `stage`, `pipeline`, `closeDate`, `dealType`, `associatedCompany`, `associatedContacts`, `createdAt`, `updatedAt`
108
+
109
+ ## OpenAPI Operations
110
+
111
+ All datasources expose full CRUD operations:
112
+ - `list` - GET `/crm/v3/objects/{entity}`
113
+ - `get` - GET `/crm/v3/objects/{entity}/{id}`
114
+ - `create` - POST `/crm/v3/objects/{entity}`
115
+ - `update` - PATCH `/crm/v3/objects/{entity}/{id}`
116
+ - `delete` - DELETE `/crm/v3/objects/{entity}/{id}`
117
+
118
+ RBAC permissions are auto-generated: `hubspot.company.list`, `hubspot.company.get`, etc.
119
+
120
+ ## Verification
121
+
122
+ ```bash
123
+ # List datasources
124
+ aifabrix datasource list --environment dev
125
+
126
+ # Validate specific datasource
127
+ aifabrix datasource validate hubspot-company --environment dev
128
+ ```
129
+
130
+ ## Documentation
131
+
132
+ - [External Systems Guide](../../docs/EXTERNAL-SYSTEMS.md) - Complete guide with examples
133
+ - [CLI Reference](../../docs/CLI-REFERENCE.md) - All commands
134
+ - [Configuration Reference](../../docs/CONFIGURATION.md) - Config file details
135
+
136
+
@@ -0,0 +1,9 @@
1
+ # HubSpot OAuth2 Configuration
2
+ # These values are set via the Miso Controller interface or Dataplane portal
3
+ # Values are stored in Key Vault automatically by the platform
4
+
5
+ CLIENTID=kv://hubspot-clientidKeyVault
6
+ CLIENTSECRET=kv://hubspot-clientsecretKeyVault
7
+ TOKENURL=https://api.hubapi.com/oauth/v1/token
8
+ REDIRECT_URI=kv://hubspot-redirect-uriKeyVault
9
+
@@ -0,0 +1,200 @@
1
+ {
2
+ "key": "hubspot-company",
3
+ "displayName": "HubSpot Company",
4
+ "description": "HubSpot companies datasource with field mappings for CRM company data",
5
+ "systemKey": "hubspot",
6
+ "entityKey": "company",
7
+ "resourceType": "customer",
8
+ "enabled": true,
9
+ "version": "1.0.0",
10
+ "metadataSchema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "id": {
14
+ "type": "string"
15
+ },
16
+ "properties": {
17
+ "type": "object",
18
+ "properties": {
19
+ "name": {
20
+ "type": "object",
21
+ "properties": {
22
+ "value": {
23
+ "type": "string"
24
+ }
25
+ }
26
+ },
27
+ "domain": {
28
+ "type": "object",
29
+ "properties": {
30
+ "value": {
31
+ "type": "string"
32
+ }
33
+ }
34
+ },
35
+ "country": {
36
+ "type": "object",
37
+ "properties": {
38
+ "value": {
39
+ "type": "string"
40
+ }
41
+ }
42
+ },
43
+ "city": {
44
+ "type": "object",
45
+ "properties": {
46
+ "value": {
47
+ "type": "string"
48
+ }
49
+ }
50
+ },
51
+ "industry": {
52
+ "type": "object",
53
+ "properties": {
54
+ "value": {
55
+ "type": "string"
56
+ }
57
+ }
58
+ },
59
+ "website": {
60
+ "type": "object",
61
+ "properties": {
62
+ "value": {
63
+ "type": "string"
64
+ }
65
+ }
66
+ },
67
+ "phone": {
68
+ "type": "object",
69
+ "properties": {
70
+ "value": {
71
+ "type": "string"
72
+ }
73
+ }
74
+ },
75
+ "createdate": {
76
+ "type": "object",
77
+ "properties": {
78
+ "value": {
79
+ "type": "string"
80
+ }
81
+ }
82
+ },
83
+ "hs_lastmodifieddate": {
84
+ "type": "object",
85
+ "properties": {
86
+ "value": {
87
+ "type": "string"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ },
94
+ "required": ["id", "properties"]
95
+ },
96
+ "fieldMappings": {
97
+ "accessFields": ["country", "domain"],
98
+ "fields": {
99
+ "id": {
100
+ "expression": "{{id}}",
101
+ "type": "string",
102
+ "description": "Unique company identifier",
103
+ "required": true
104
+ },
105
+ "name": {
106
+ "expression": "{{properties.name.value}} | trim",
107
+ "type": "string",
108
+ "description": "Company name",
109
+ "required": false
110
+ },
111
+ "domain": {
112
+ "expression": "{{properties.domain.value}} | toLower | trim",
113
+ "type": "string",
114
+ "description": "Company domain for ABAC filtering",
115
+ "required": false
116
+ },
117
+ "country": {
118
+ "expression": "{{properties.country.value}} | toUpper | trim",
119
+ "type": "string",
120
+ "description": "Country code for ABAC filtering",
121
+ "required": false
122
+ },
123
+ "city": {
124
+ "expression": "{{properties.city.value}} | trim",
125
+ "type": "string",
126
+ "description": "City name",
127
+ "required": false
128
+ },
129
+ "industry": {
130
+ "expression": "{{properties.industry.value}} | trim",
131
+ "type": "string",
132
+ "description": "Industry classification",
133
+ "required": false
134
+ },
135
+ "website": {
136
+ "expression": "{{properties.website.value}} | trim",
137
+ "type": "string",
138
+ "description": "Company website URL",
139
+ "required": false
140
+ },
141
+ "phone": {
142
+ "expression": "{{properties.phone.value}} | trim",
143
+ "type": "string",
144
+ "description": "Phone number",
145
+ "required": false
146
+ },
147
+ "createdAt": {
148
+ "expression": "{{properties.createdate.value}}",
149
+ "type": "string",
150
+ "description": "Creation timestamp",
151
+ "required": false
152
+ },
153
+ "updatedAt": {
154
+ "expression": "{{properties.hs_lastmodifieddate.value}}",
155
+ "type": "string",
156
+ "description": "Last modification timestamp",
157
+ "required": false
158
+ }
159
+ }
160
+ },
161
+ "exposed": {
162
+ "fields": ["id", "name", "domain", "country", "city", "industry", "website", "phone", "createdAt", "updatedAt"],
163
+ "description": "Exposed fields for HubSpot companies"
164
+ },
165
+ "openapi": {
166
+ "enabled": true,
167
+ "documentKey": "hubspot-v3",
168
+ "baseUrl": "https://api.hubapi.com",
169
+ "operations": {
170
+ "list": {
171
+ "operationId": "getCompanies",
172
+ "method": "GET",
173
+ "path": "/crm/v3/objects/companies"
174
+ },
175
+ "get": {
176
+ "operationId": "getCompany",
177
+ "method": "GET",
178
+ "path": "/crm/v3/objects/companies/{companyId}"
179
+ },
180
+ "create": {
181
+ "operationId": "createCompany",
182
+ "method": "POST",
183
+ "path": "/crm/v3/objects/companies"
184
+ },
185
+ "update": {
186
+ "operationId": "updateCompany",
187
+ "method": "PATCH",
188
+ "path": "/crm/v3/objects/companies/{companyId}"
189
+ },
190
+ "delete": {
191
+ "operationId": "deleteCompany",
192
+ "method": "DELETE",
193
+ "path": "/crm/v3/objects/companies/{companyId}"
194
+ }
195
+ },
196
+ "autoRbac": true
197
+ }
198
+ }
199
+
200
+
@@ -0,0 +1,228 @@
1
+ {
2
+ "key": "hubspot-contact",
3
+ "displayName": "HubSpot Contact",
4
+ "description": "HubSpot contacts datasource with field mappings for CRM contact data",
5
+ "systemKey": "hubspot",
6
+ "entityKey": "contact",
7
+ "resourceType": "contact",
8
+ "enabled": true,
9
+ "version": "1.0.0",
10
+ "metadataSchema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "id": {
14
+ "type": "string"
15
+ },
16
+ "properties": {
17
+ "type": "object",
18
+ "properties": {
19
+ "firstname": {
20
+ "type": "object",
21
+ "properties": {
22
+ "value": {
23
+ "type": "string"
24
+ }
25
+ }
26
+ },
27
+ "lastname": {
28
+ "type": "object",
29
+ "properties": {
30
+ "value": {
31
+ "type": "string"
32
+ }
33
+ }
34
+ },
35
+ "email": {
36
+ "type": "object",
37
+ "properties": {
38
+ "value": {
39
+ "type": "string"
40
+ }
41
+ }
42
+ },
43
+ "phone": {
44
+ "type": "object",
45
+ "properties": {
46
+ "value": {
47
+ "type": "string"
48
+ }
49
+ }
50
+ },
51
+ "company": {
52
+ "type": "object",
53
+ "properties": {
54
+ "value": {
55
+ "type": "string"
56
+ }
57
+ }
58
+ },
59
+ "jobtitle": {
60
+ "type": "object",
61
+ "properties": {
62
+ "value": {
63
+ "type": "string"
64
+ }
65
+ }
66
+ },
67
+ "address": {
68
+ "type": "object",
69
+ "properties": {
70
+ "value": {
71
+ "type": "string"
72
+ }
73
+ }
74
+ },
75
+ "city": {
76
+ "type": "object",
77
+ "properties": {
78
+ "value": {
79
+ "type": "string"
80
+ }
81
+ }
82
+ },
83
+ "country": {
84
+ "type": "object",
85
+ "properties": {
86
+ "value": {
87
+ "type": "string"
88
+ }
89
+ }
90
+ },
91
+ "createdate": {
92
+ "type": "object",
93
+ "properties": {
94
+ "value": {
95
+ "type": "string"
96
+ }
97
+ }
98
+ },
99
+ "hs_lastmodifieddate": {
100
+ "type": "object",
101
+ "properties": {
102
+ "value": {
103
+ "type": "string"
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ },
110
+ "required": ["id", "properties"]
111
+ },
112
+ "fieldMappings": {
113
+ "accessFields": ["email", "country"],
114
+ "fields": {
115
+ "id": {
116
+ "expression": "{{id}}",
117
+ "type": "string",
118
+ "description": "Unique contact identifier",
119
+ "required": true
120
+ },
121
+ "firstName": {
122
+ "expression": "{{properties.firstname.value}} | trim",
123
+ "type": "string",
124
+ "description": "First name",
125
+ "required": false
126
+ },
127
+ "lastName": {
128
+ "expression": "{{properties.lastname.value}} | trim",
129
+ "type": "string",
130
+ "description": "Last name",
131
+ "required": false
132
+ },
133
+ "email": {
134
+ "expression": "{{properties.email.value}} | toLower | trim",
135
+ "type": "string",
136
+ "description": "Email address for ABAC filtering",
137
+ "required": false
138
+ },
139
+ "phone": {
140
+ "expression": "{{properties.phone.value}} | trim",
141
+ "type": "string",
142
+ "description": "Phone number",
143
+ "required": false
144
+ },
145
+ "company": {
146
+ "expression": "{{properties.company.value}} | trim",
147
+ "type": "string",
148
+ "description": "Associated company name",
149
+ "required": false
150
+ },
151
+ "jobTitle": {
152
+ "expression": "{{properties.jobtitle.value}} | trim",
153
+ "type": "string",
154
+ "description": "Job title",
155
+ "required": false
156
+ },
157
+ "address": {
158
+ "expression": "{{properties.address.value}} | trim",
159
+ "type": "string",
160
+ "description": "Street address",
161
+ "required": false
162
+ },
163
+ "city": {
164
+ "expression": "{{properties.city.value}} | trim",
165
+ "type": "string",
166
+ "description": "City name",
167
+ "required": false
168
+ },
169
+ "country": {
170
+ "expression": "{{properties.country.value}} | toUpper | trim",
171
+ "type": "string",
172
+ "description": "Country code for ABAC filtering",
173
+ "required": false
174
+ },
175
+ "createdAt": {
176
+ "expression": "{{properties.createdate.value}}",
177
+ "type": "string",
178
+ "description": "Creation timestamp",
179
+ "required": false
180
+ },
181
+ "updatedAt": {
182
+ "expression": "{{properties.hs_lastmodifieddate.value}}",
183
+ "type": "string",
184
+ "description": "Last modification timestamp",
185
+ "required": false
186
+ }
187
+ }
188
+ },
189
+ "exposed": {
190
+ "fields": ["id", "firstName", "lastName", "email", "phone", "company", "jobTitle", "address", "city", "country", "createdAt", "updatedAt"],
191
+ "description": "Exposed fields for HubSpot contacts"
192
+ },
193
+ "openapi": {
194
+ "enabled": true,
195
+ "documentKey": "hubspot-v3",
196
+ "baseUrl": "https://api.hubapi.com",
197
+ "operations": {
198
+ "list": {
199
+ "operationId": "getContacts",
200
+ "method": "GET",
201
+ "path": "/crm/v3/objects/contacts"
202
+ },
203
+ "get": {
204
+ "operationId": "getContact",
205
+ "method": "GET",
206
+ "path": "/crm/v3/objects/contacts/{contactId}"
207
+ },
208
+ "create": {
209
+ "operationId": "createContact",
210
+ "method": "POST",
211
+ "path": "/crm/v3/objects/contacts"
212
+ },
213
+ "update": {
214
+ "operationId": "updateContact",
215
+ "method": "PATCH",
216
+ "path": "/crm/v3/objects/contacts/{contactId}"
217
+ },
218
+ "delete": {
219
+ "operationId": "deleteContact",
220
+ "method": "DELETE",
221
+ "path": "/crm/v3/objects/contacts/{contactId}"
222
+ }
223
+ },
224
+ "autoRbac": true
225
+ }
226
+ }
227
+
228
+