@aifabrix/builder 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/project-rules.mdc +680 -0
- package/integration/hubspot/README.md +136 -0
- package/integration/hubspot/env.template +9 -0
- package/integration/hubspot/hubspot-deploy-company.json +200 -0
- package/integration/hubspot/hubspot-deploy-contact.json +228 -0
- package/integration/hubspot/hubspot-deploy-deal.json +248 -0
- package/integration/hubspot/hubspot-deploy.json +91 -0
- package/integration/hubspot/variables.yaml +17 -0
- package/lib/app-config.js +13 -2
- package/lib/app-deploy.js +9 -3
- package/lib/app-dockerfile.js +14 -1
- package/lib/app-prompts.js +177 -13
- package/lib/app-push.js +16 -1
- package/lib/app-register.js +37 -5
- package/lib/app-rotate-secret.js +10 -0
- package/lib/app-run.js +19 -0
- package/lib/app.js +70 -25
- package/lib/audit-logger.js +9 -4
- package/lib/build.js +25 -13
- package/lib/cli.js +109 -2
- package/lib/commands/login.js +40 -3
- package/lib/config.js +121 -114
- package/lib/datasource-deploy.js +14 -20
- package/lib/environment-deploy.js +305 -0
- package/lib/external-system-deploy.js +345 -0
- package/lib/external-system-download.js +431 -0
- package/lib/external-system-generator.js +190 -0
- package/lib/external-system-test.js +446 -0
- package/lib/generator-builders.js +323 -0
- package/lib/generator.js +200 -292
- package/lib/schema/application-schema.json +830 -800
- package/lib/schema/external-datasource.schema.json +868 -46
- package/lib/schema/external-system.schema.json +98 -80
- package/lib/schema/infrastructure-schema.json +1 -1
- package/lib/templates.js +32 -1
- package/lib/utils/cli-utils.js +4 -4
- package/lib/utils/device-code.js +10 -2
- package/lib/utils/external-system-display.js +159 -0
- package/lib/utils/external-system-validators.js +245 -0
- package/lib/utils/paths.js +151 -1
- package/lib/utils/schema-resolver.js +7 -2
- package/lib/utils/token-encryption.js +68 -0
- package/lib/validator.js +52 -5
- package/package.json +1 -1
- package/tatus +181 -0
- package/templates/external-system/external-datasource.json.hbs +55 -0
- package/templates/external-system/external-system.json.hbs +37 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
{
|
|
2
|
+
"key": "hubspot-deal",
|
|
3
|
+
"displayName": "HubSpot Deal",
|
|
4
|
+
"description": "HubSpot deals datasource with field mappings for CRM deal data",
|
|
5
|
+
"systemKey": "hubspot",
|
|
6
|
+
"entityKey": "deal",
|
|
7
|
+
"resourceType": "deal",
|
|
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
|
+
"dealname": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"value": {
|
|
23
|
+
"type": "string"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"amount": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"properties": {
|
|
30
|
+
"value": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"deal_currency_code": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"properties": {
|
|
38
|
+
"value": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"dealstage": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"properties": {
|
|
46
|
+
"value": {
|
|
47
|
+
"type": "string"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"pipeline": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"properties": {
|
|
54
|
+
"value": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"closedate": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"properties": {
|
|
62
|
+
"value": {
|
|
63
|
+
"type": "string"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"dealtype": {
|
|
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
|
+
"associations": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"properties": {
|
|
96
|
+
"companies": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"properties": {
|
|
99
|
+
"results": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"items": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"id": {
|
|
105
|
+
"type": "string"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"contacts": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"properties": {
|
|
115
|
+
"results": {
|
|
116
|
+
"type": "array",
|
|
117
|
+
"items": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"properties": {
|
|
120
|
+
"id": {
|
|
121
|
+
"type": "string"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"required": ["id", "properties"]
|
|
132
|
+
},
|
|
133
|
+
"fieldMappings": {
|
|
134
|
+
"accessFields": ["stage", "pipeline"],
|
|
135
|
+
"fields": {
|
|
136
|
+
"id": {
|
|
137
|
+
"expression": "{{id}}",
|
|
138
|
+
"type": "string",
|
|
139
|
+
"description": "Unique deal identifier",
|
|
140
|
+
"required": true
|
|
141
|
+
},
|
|
142
|
+
"dealName": {
|
|
143
|
+
"expression": "{{properties.dealname.value}} | trim",
|
|
144
|
+
"type": "string",
|
|
145
|
+
"description": "Deal name",
|
|
146
|
+
"required": false
|
|
147
|
+
},
|
|
148
|
+
"amount": {
|
|
149
|
+
"expression": "{{properties.amount.value}}",
|
|
150
|
+
"type": "string",
|
|
151
|
+
"description": "Deal amount",
|
|
152
|
+
"required": false
|
|
153
|
+
},
|
|
154
|
+
"currency": {
|
|
155
|
+
"expression": "{{properties.deal_currency_code.value}} | toUpper | trim",
|
|
156
|
+
"type": "string",
|
|
157
|
+
"description": "Currency code",
|
|
158
|
+
"required": false
|
|
159
|
+
},
|
|
160
|
+
"stage": {
|
|
161
|
+
"expression": "{{properties.dealstage.value}} | trim",
|
|
162
|
+
"type": "string",
|
|
163
|
+
"description": "Deal stage for ABAC filtering",
|
|
164
|
+
"required": false
|
|
165
|
+
},
|
|
166
|
+
"pipeline": {
|
|
167
|
+
"expression": "{{properties.pipeline.value}} | trim",
|
|
168
|
+
"type": "string",
|
|
169
|
+
"description": "Pipeline name for ABAC filtering",
|
|
170
|
+
"required": false
|
|
171
|
+
},
|
|
172
|
+
"closeDate": {
|
|
173
|
+
"expression": "{{properties.closedate.value}}",
|
|
174
|
+
"type": "string",
|
|
175
|
+
"description": "Expected close date",
|
|
176
|
+
"required": false
|
|
177
|
+
},
|
|
178
|
+
"dealType": {
|
|
179
|
+
"expression": "{{properties.dealtype.value}} | trim",
|
|
180
|
+
"type": "string",
|
|
181
|
+
"description": "Deal type",
|
|
182
|
+
"required": false
|
|
183
|
+
},
|
|
184
|
+
"associatedCompany": {
|
|
185
|
+
"expression": "{{associations.companies.results[0].id}}",
|
|
186
|
+
"type": "string",
|
|
187
|
+
"description": "Associated company ID",
|
|
188
|
+
"required": false
|
|
189
|
+
},
|
|
190
|
+
"associatedContacts": {
|
|
191
|
+
"expression": "{{associations.contacts.results}}",
|
|
192
|
+
"type": "array",
|
|
193
|
+
"description": "Array of associated contact IDs",
|
|
194
|
+
"required": false
|
|
195
|
+
},
|
|
196
|
+
"createdAt": {
|
|
197
|
+
"expression": "{{properties.createdate.value}}",
|
|
198
|
+
"type": "string",
|
|
199
|
+
"description": "Creation timestamp",
|
|
200
|
+
"required": false
|
|
201
|
+
},
|
|
202
|
+
"updatedAt": {
|
|
203
|
+
"expression": "{{properties.hs_lastmodifieddate.value}}",
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "Last modification timestamp",
|
|
206
|
+
"required": false
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"exposed": {
|
|
211
|
+
"fields": ["id", "dealName", "amount", "currency", "stage", "pipeline", "closeDate", "dealType", "associatedCompany", "associatedContacts", "createdAt", "updatedAt"],
|
|
212
|
+
"description": "Exposed fields for HubSpot deals"
|
|
213
|
+
},
|
|
214
|
+
"openapi": {
|
|
215
|
+
"enabled": true,
|
|
216
|
+
"documentKey": "hubspot-v3",
|
|
217
|
+
"baseUrl": "https://api.hubapi.com",
|
|
218
|
+
"operations": {
|
|
219
|
+
"list": {
|
|
220
|
+
"operationId": "getDeals",
|
|
221
|
+
"method": "GET",
|
|
222
|
+
"path": "/crm/v3/objects/deals"
|
|
223
|
+
},
|
|
224
|
+
"get": {
|
|
225
|
+
"operationId": "getDeal",
|
|
226
|
+
"method": "GET",
|
|
227
|
+
"path": "/crm/v3/objects/deals/{dealId}"
|
|
228
|
+
},
|
|
229
|
+
"create": {
|
|
230
|
+
"operationId": "createDeal",
|
|
231
|
+
"method": "POST",
|
|
232
|
+
"path": "/crm/v3/objects/deals"
|
|
233
|
+
},
|
|
234
|
+
"update": {
|
|
235
|
+
"operationId": "updateDeal",
|
|
236
|
+
"method": "PATCH",
|
|
237
|
+
"path": "/crm/v3/objects/deals/{dealId}"
|
|
238
|
+
},
|
|
239
|
+
"delete": {
|
|
240
|
+
"operationId": "deleteDeal",
|
|
241
|
+
"method": "DELETE",
|
|
242
|
+
"path": "/crm/v3/objects/deals/{dealId}"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
"autoRbac": true
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"key": "hubspot",
|
|
3
|
+
"displayName": "HubSpot CRM",
|
|
4
|
+
"description": "HubSpot CRM integration with OpenAPI support for companies, contacts, and deals",
|
|
5
|
+
"type": "openapi",
|
|
6
|
+
"enabled": true,
|
|
7
|
+
"environment": {
|
|
8
|
+
"baseUrl": "https://api.hubapi.com"
|
|
9
|
+
},
|
|
10
|
+
"authentication": {
|
|
11
|
+
"type": "oauth2",
|
|
12
|
+
"mode": "oauth2",
|
|
13
|
+
"oauth2": {
|
|
14
|
+
"tokenUrl": "{{TOKENURL}}",
|
|
15
|
+
"clientId": "{{CLIENTID}}",
|
|
16
|
+
"clientSecret": "{{CLIENTSECRET}}",
|
|
17
|
+
"scopes": [
|
|
18
|
+
"crm.objects.companies.read",
|
|
19
|
+
"crm.objects.companies.write",
|
|
20
|
+
"crm.objects.contacts.read",
|
|
21
|
+
"crm.objects.contacts.write",
|
|
22
|
+
"crm.objects.deals.read",
|
|
23
|
+
"crm.objects.deals.write"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"configuration": [
|
|
28
|
+
{
|
|
29
|
+
"name": "CLIENTID",
|
|
30
|
+
"value": "hubspot-clientidKeyVault",
|
|
31
|
+
"location": "keyvault",
|
|
32
|
+
"required": true
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "CLIENTSECRET",
|
|
36
|
+
"value": "hubspot-clientsecretKeyVault",
|
|
37
|
+
"location": "keyvault",
|
|
38
|
+
"required": true
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "TOKENURL",
|
|
42
|
+
"value": "https://api.hubapi.com/oauth/v1/token",
|
|
43
|
+
"location": "variable",
|
|
44
|
+
"required": true
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "REDIRECT_URI",
|
|
48
|
+
"value": "hubspot-redirect-uriKeyVault",
|
|
49
|
+
"location": "keyvault",
|
|
50
|
+
"required": false
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "HUBSPOT_API_VERSION",
|
|
54
|
+
"value": "v3",
|
|
55
|
+
"location": "variable",
|
|
56
|
+
"required": false,
|
|
57
|
+
"portalInput": {
|
|
58
|
+
"field": "select",
|
|
59
|
+
"label": "HubSpot API Version",
|
|
60
|
+
"placeholder": "Select API version",
|
|
61
|
+
"options": ["v1", "v2", "v3"],
|
|
62
|
+
"validation": {
|
|
63
|
+
"required": false
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "MAX_PAGE_SIZE",
|
|
69
|
+
"value": "100",
|
|
70
|
+
"location": "variable",
|
|
71
|
+
"required": false,
|
|
72
|
+
"portalInput": {
|
|
73
|
+
"field": "text",
|
|
74
|
+
"label": "Maximum Page Size",
|
|
75
|
+
"placeholder": "100",
|
|
76
|
+
"validation": {
|
|
77
|
+
"required": false,
|
|
78
|
+
"pattern": "^[0-9]+$",
|
|
79
|
+
"min": 1,
|
|
80
|
+
"max": 1000
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"openapi": {
|
|
86
|
+
"documentKey": "hubspot-v3",
|
|
87
|
+
"autoDiscoverEntities": false
|
|
88
|
+
},
|
|
89
|
+
"tags": ["crm", "sales", "marketing", "hubspot"]
|
|
90
|
+
}
|
|
91
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
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-deploy.json
|
|
11
|
+
dataSources:
|
|
12
|
+
- hubspot-deploy-company.json
|
|
13
|
+
- hubspot-deploy-contact.json
|
|
14
|
+
- hubspot-deploy-deal.json
|
|
15
|
+
autopublish: true
|
|
16
|
+
version: 1.0.0
|
|
17
|
+
|
package/lib/app-config.js
CHANGED
|
@@ -54,6 +54,11 @@ async function generateVariablesYamlFile(appPath, appName, config) {
|
|
|
54
54
|
* @param {Object} existingEnv - Existing environment variables
|
|
55
55
|
*/
|
|
56
56
|
async function generateEnvTemplateFile(appPath, config, existingEnv) {
|
|
57
|
+
// Skip env.template for external type
|
|
58
|
+
if (config.type === 'external') {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
const envTemplatePath = path.join(appPath, 'env.template');
|
|
58
63
|
if (!(await fileExists(envTemplatePath))) {
|
|
59
64
|
let envTemplate;
|
|
@@ -94,13 +99,18 @@ async function generateRbacYamlFile(appPath, appName, config) {
|
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
/**
|
|
97
|
-
* Generates
|
|
102
|
+
* Generates <app-name>-deploy.json file (consistent naming for all apps)
|
|
98
103
|
* @async
|
|
99
104
|
* @param {string} appPath - Path to application directory
|
|
100
105
|
* @param {string} appName - Application name
|
|
101
106
|
* @param {Object} config - Application configuration
|
|
102
107
|
*/
|
|
103
108
|
async function generateDeployJsonFile(appPath, appName, config) {
|
|
109
|
+
// Skip for external type (external system JSON is generated separately)
|
|
110
|
+
if (config.type === 'external') {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
104
114
|
const deployJson = {
|
|
105
115
|
apiVersion: 'v1',
|
|
106
116
|
kind: 'ApplicationDeployment',
|
|
@@ -128,8 +138,9 @@ async function generateDeployJsonFile(appPath, appName, config) {
|
|
|
128
138
|
}
|
|
129
139
|
};
|
|
130
140
|
|
|
141
|
+
// Use consistent naming: <app-name>-deploy.json
|
|
131
142
|
await fs.writeFile(
|
|
132
|
-
path.join(appPath,
|
|
143
|
+
path.join(appPath, `${appName}-deploy.json`),
|
|
133
144
|
JSON.stringify(deployJson, null, 2)
|
|
134
145
|
);
|
|
135
146
|
}
|
package/lib/app-deploy.js
CHANGED
|
@@ -17,6 +17,7 @@ const pushUtils = require('./push');
|
|
|
17
17
|
const logger = require('./utils/logger');
|
|
18
18
|
const config = require('./config');
|
|
19
19
|
const { getDeploymentAuth } = require('./utils/token-manager');
|
|
20
|
+
const { detectAppType } = require('./utils/paths');
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Validate application name format
|
|
@@ -215,10 +216,11 @@ function validateDeploymentConfig(deploymentConfig) {
|
|
|
215
216
|
* @throws {Error} If configuration is invalid
|
|
216
217
|
*/
|
|
217
218
|
async function loadDeploymentConfig(appName, options) {
|
|
218
|
-
|
|
219
|
-
await
|
|
219
|
+
// Detect app type and get correct path (integration or builder)
|
|
220
|
+
const { appPath } = await detectAppType(appName);
|
|
221
|
+
await validateAppDirectory(appPath, appName);
|
|
220
222
|
|
|
221
|
-
const variablesPath = path.join(
|
|
223
|
+
const variablesPath = path.join(appPath, 'variables.yaml');
|
|
222
224
|
const variables = await loadVariablesFile(variablesPath);
|
|
223
225
|
|
|
224
226
|
const deploymentConfig = extractDeploymentConfig(options, variables);
|
|
@@ -366,6 +368,10 @@ async function deployApp(appName, options = {}) {
|
|
|
366
368
|
|
|
367
369
|
validateAppName(appName);
|
|
368
370
|
|
|
371
|
+
// 2. Check if app type is external - use normal deployment flow with application-schema.json
|
|
372
|
+
// External systems now deploy via miso controller as normal application (full application file)
|
|
373
|
+
// The json command generates application-schema.json which is used for deployment
|
|
374
|
+
|
|
369
375
|
// 2. Load deployment configuration
|
|
370
376
|
config = await loadDeploymentConfig(appName, options);
|
|
371
377
|
controllerUrl = config.controllerUrl || options.controller || 'unknown';
|
package/lib/app-dockerfile.js
CHANGED
|
@@ -84,11 +84,24 @@ async function generateAndCopyDockerfile(appPath, dockerfilePath, config) {
|
|
|
84
84
|
* @returns {Promise<string>} Path to generated Dockerfile
|
|
85
85
|
*/
|
|
86
86
|
async function generateDockerfileForApp(appName, options = {}) {
|
|
87
|
+
// Check if app type is external - skip Dockerfile generation
|
|
88
|
+
const { detectAppType } = require('./utils/paths');
|
|
89
|
+
try {
|
|
90
|
+
const { isExternal } = await detectAppType(appName);
|
|
91
|
+
if (isExternal) {
|
|
92
|
+
logger.log(chalk.yellow('⚠️ External systems don\'t require Dockerfiles. Skipping...'));
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
// If detection fails, continue with normal generation
|
|
97
|
+
// (detectAppType throws if app doesn't exist, which is fine for dockerfile command)
|
|
98
|
+
}
|
|
87
99
|
try {
|
|
88
100
|
// Validate app name
|
|
89
101
|
validateAppName(appName);
|
|
90
102
|
|
|
91
|
-
|
|
103
|
+
// Detect app type and get correct path (integration or builder)
|
|
104
|
+
const { appPath } = await detectAppType(appName);
|
|
92
105
|
const dockerfilePath = path.join(appPath, 'Dockerfile');
|
|
93
106
|
|
|
94
107
|
// Check if Dockerfile already exists
|