@boltic/cli 1.0.6-beta.11 ā 1.0.6-beta.12
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/README.md +14 -13
- package/commands/integration.js +26 -8
- package/helper/validation.js +260 -24
- package/llm.txt +295 -0
- package/package.json +1 -1
- package/templates/component-schemas.js +929 -0
- package/templates/schemas.js +13 -1
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/@boltic/cli)
|
|
6
6
|
[](https://github.com/<your-username>/<your-repo>)
|
|
7
7
|
[](./LICENSE)
|
|
8
|
+
[](https://github.com/bolticio/cli/actions/workflows/npm-publish.yml)
|
|
8
9
|
|
|
9
10
|
---
|
|
10
11
|
|
|
@@ -65,26 +66,26 @@ boltic integration edit
|
|
|
65
66
|
boltic integration sync
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
### š
|
|
69
|
+
### š Submit an Integration
|
|
69
70
|
|
|
70
71
|
```bash
|
|
71
|
-
boltic integration
|
|
72
|
+
boltic integration submit
|
|
72
73
|
```
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
## š Command Reference
|
|
77
78
|
|
|
78
|
-
| Command
|
|
79
|
-
|
|
|
80
|
-
| `boltic login`
|
|
81
|
-
| `boltic integration create`
|
|
82
|
-
| `boltic integration sync`
|
|
83
|
-
| `boltic integration
|
|
84
|
-
| `boltic integration pull`
|
|
85
|
-
| `boltic integration edit`
|
|
86
|
-
| `boltic help`
|
|
87
|
-
| `boltic version`
|
|
79
|
+
| Command | Description |
|
|
80
|
+
| --------------------------- | -------------------------------------------------------- |
|
|
81
|
+
| `boltic login` | Authenticate with Boltic |
|
|
82
|
+
| `boltic integration create` | Create a new integration |
|
|
83
|
+
| `boltic integration sync` | Sync changes to your draft |
|
|
84
|
+
| `boltic integration submit` | Submit integration for review |
|
|
85
|
+
| `boltic integration pull` | Pull the latest changes of an integration from the Cloud |
|
|
86
|
+
| `boltic integration edit` | Edit an existing integration |
|
|
87
|
+
| `boltic help` | Show CLI help |
|
|
88
|
+
| `boltic version` | Display CLI version |
|
|
88
89
|
|
|
89
90
|
---
|
|
90
91
|
|
|
@@ -101,7 +102,7 @@ boltic integration create
|
|
|
101
102
|
boltic integration sync
|
|
102
103
|
|
|
103
104
|
# Step 5: Submit for publishing and review
|
|
104
|
-
boltic integration
|
|
105
|
+
boltic integration submit
|
|
105
106
|
|
|
106
107
|
# Step 6: Pull the latest changes of a integration. Please call this command inside a integration folder.
|
|
107
108
|
boltic integration pull
|
package/commands/integration.js
CHANGED
|
@@ -34,8 +34,12 @@ const commands = {
|
|
|
34
34
|
description: "Edit an existing integration",
|
|
35
35
|
action: handleEdit,
|
|
36
36
|
},
|
|
37
|
+
submit: {
|
|
38
|
+
description: "Submit an integration for review",
|
|
39
|
+
action: handleSubmit,
|
|
40
|
+
},
|
|
37
41
|
publish: {
|
|
38
|
-
description: "Publish an integration",
|
|
42
|
+
description: "Publish an integration (deprecated, use submit)",
|
|
39
43
|
action: handlePublish,
|
|
40
44
|
},
|
|
41
45
|
sync: {
|
|
@@ -236,8 +240,8 @@ async function handleSync(args) {
|
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
// Publish an integration
|
|
239
|
-
async function
|
|
240
|
-
console.log(chalk.green("
|
|
243
|
+
async function handleSubmit(args) {
|
|
244
|
+
console.log(chalk.green("Submitting integration for review...\n"));
|
|
241
245
|
// Parse command line arguments
|
|
242
246
|
let currentDir = process.cwd();
|
|
243
247
|
const pathIndex = args.indexOf("--path");
|
|
@@ -347,18 +351,32 @@ async function handlePublish(args) {
|
|
|
347
351
|
if (review) {
|
|
348
352
|
console.log(
|
|
349
353
|
chalk.green(
|
|
350
|
-
"\nā
Integration
|
|
354
|
+
"\nā
Integration submitted for review successfully!\n"
|
|
351
355
|
)
|
|
352
356
|
);
|
|
353
357
|
}
|
|
354
358
|
} else {
|
|
355
359
|
console.error(
|
|
356
|
-
chalk.red("\nā Error
|
|
360
|
+
chalk.red("\nā Error submitting integration:", data.message)
|
|
357
361
|
);
|
|
358
362
|
}
|
|
359
363
|
}
|
|
360
364
|
}
|
|
361
365
|
|
|
366
|
+
async function handlePublish(args) {
|
|
367
|
+
console.log(
|
|
368
|
+
chalk.yellow(
|
|
369
|
+
"ā ļø WARNING: The 'publish' command is deprecated and will be removed in a future version."
|
|
370
|
+
)
|
|
371
|
+
);
|
|
372
|
+
console.log(
|
|
373
|
+
chalk.yellow("Please use 'boltic integration submit' instead.\n")
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
// Call the new submit function
|
|
377
|
+
await handleSubmit(args);
|
|
378
|
+
}
|
|
379
|
+
|
|
362
380
|
// Execute the integration command
|
|
363
381
|
const execute = async (args) => {
|
|
364
382
|
const subCommand = args[0];
|
|
@@ -609,15 +627,15 @@ async function handleCreate() {
|
|
|
609
627
|
create_catalogue
|
|
610
628
|
);
|
|
611
629
|
|
|
612
|
-
// Also share Documentation URL to the user: https://docs.boltic.io/docs/integration-builder/develop/boilerplate
|
|
613
630
|
const documentationUrl =
|
|
614
631
|
"https://docs.boltic.io/docs/integration-builder/develop/boilerplate";
|
|
632
|
+
|
|
615
633
|
console.log(
|
|
616
634
|
chalk.cyan(
|
|
617
|
-
|
|
618
|
-
chalk.underline.blue(documentationUrl)
|
|
635
|
+
`š For detailed instructions on next steps, refer to the official documentation:`
|
|
619
636
|
)
|
|
620
637
|
);
|
|
638
|
+
console.log(chalk.underline.blue(documentationUrl));
|
|
621
639
|
}
|
|
622
640
|
} catch (error) {
|
|
623
641
|
console.error(
|
package/helper/validation.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import isEmpty from "lodash.isempty";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import * as componentSchemas from "../templates/component-schemas.js";
|
|
5
|
+
|
|
6
|
+
const validateOptionObject = (options, fieldName, fileLabel, errors) => {
|
|
7
|
+
options.forEach((opt, index) => {
|
|
8
|
+
const missingKeys = ["label", "value", "description"].filter(
|
|
9
|
+
(key) => !(key in opt)
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
if (missingKeys.length > 0) {
|
|
13
|
+
errors.add(
|
|
14
|
+
`"${fieldName}" field in "${fileLabel}" has an option at index ${index} missing keys: ${missingKeys.join(", ")}.`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
4
19
|
|
|
5
20
|
const readAndParseJson = (filePath, fileLabel, errors) => {
|
|
6
21
|
try {
|
|
@@ -15,8 +30,7 @@ const readAndParseJson = (filePath, fileLabel, errors) => {
|
|
|
15
30
|
return null;
|
|
16
31
|
}
|
|
17
32
|
};
|
|
18
|
-
|
|
19
|
-
const findResourceFieldsWithOptions = (schema) => {
|
|
33
|
+
const findResourceFieldsWithOptions = (schema, fileLabel, errors) => {
|
|
20
34
|
const resourceFields = [];
|
|
21
35
|
if (Array.isArray(schema?.parameters)) {
|
|
22
36
|
schema.parameters.forEach((param) => {
|
|
@@ -24,6 +38,12 @@ const findResourceFieldsWithOptions = (schema) => {
|
|
|
24
38
|
param.name === "resource" &&
|
|
25
39
|
Array.isArray(param.meta?.options)
|
|
26
40
|
) {
|
|
41
|
+
validateOptionObject(
|
|
42
|
+
param.meta.options,
|
|
43
|
+
"resource",
|
|
44
|
+
fileLabel,
|
|
45
|
+
errors
|
|
46
|
+
);
|
|
27
47
|
resourceFields.push(
|
|
28
48
|
...param.meta.options.map((opt) => opt.value)
|
|
29
49
|
);
|
|
@@ -32,8 +52,7 @@ const findResourceFieldsWithOptions = (schema) => {
|
|
|
32
52
|
}
|
|
33
53
|
return resourceFields;
|
|
34
54
|
};
|
|
35
|
-
|
|
36
|
-
const findOperationFieldsWithOptions = (schema) => {
|
|
55
|
+
const findOperationFieldsWithOptions = (schema, fileLabel, errors) => {
|
|
37
56
|
const operationFields = [];
|
|
38
57
|
if (Array.isArray(schema?.parameters)) {
|
|
39
58
|
schema.parameters.forEach((param) => {
|
|
@@ -41,6 +60,12 @@ const findOperationFieldsWithOptions = (schema) => {
|
|
|
41
60
|
param.name === "operation" &&
|
|
42
61
|
Array.isArray(param.meta?.options)
|
|
43
62
|
) {
|
|
63
|
+
validateOptionObject(
|
|
64
|
+
param.meta.options,
|
|
65
|
+
"operation",
|
|
66
|
+
fileLabel,
|
|
67
|
+
errors
|
|
68
|
+
);
|
|
44
69
|
operationFields.push(
|
|
45
70
|
...param.meta.options.map((opt) => opt.value)
|
|
46
71
|
);
|
|
@@ -50,6 +75,164 @@ const findOperationFieldsWithOptions = (schema) => {
|
|
|
50
75
|
return operationFields;
|
|
51
76
|
};
|
|
52
77
|
|
|
78
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
79
|
+
// VALIDATE COMPONENT SCHEMAS
|
|
80
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Extract all possible keys from a component schema structure recursively
|
|
84
|
+
* @param {Object} obj - The object to extract keys from
|
|
85
|
+
* @param {string} prefix - Current key prefix for nested objects
|
|
86
|
+
* @returns {Set<string>} Set of all allowed keys with dot notation for nested paths
|
|
87
|
+
*/
|
|
88
|
+
const extractAllowedKeys = (obj, prefix = "") => {
|
|
89
|
+
const allowedKeys = new Set();
|
|
90
|
+
|
|
91
|
+
Object.keys(obj).forEach((key) => {
|
|
92
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
93
|
+
allowedKeys.add(fullKey);
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
typeof obj[key] === "object" &&
|
|
97
|
+
obj[key] !== null &&
|
|
98
|
+
!Array.isArray(obj[key])
|
|
99
|
+
) {
|
|
100
|
+
const nestedKeys = extractAllowedKeys(obj[key], fullKey);
|
|
101
|
+
nestedKeys.forEach((nestedKey) => allowedKeys.add(nestedKey));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return allowedKeys;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Validate that a schema object doesn't contain any extra keys
|
|
110
|
+
* @param {Object} schemaObj - The schema object to validate
|
|
111
|
+
* @param {Set<string>} allowedKeys - Set of allowed keys
|
|
112
|
+
* @param {string} schemaName - Name of the schema for error messages
|
|
113
|
+
* @param {string} displayType - The display type for error messages
|
|
114
|
+
* @param {Set} errors - Error collection
|
|
115
|
+
* @param {string} prefix - Current key prefix for nested objects
|
|
116
|
+
*/
|
|
117
|
+
const validateSchemaKeys = (
|
|
118
|
+
schemaObj,
|
|
119
|
+
allowedKeys,
|
|
120
|
+
schemaName,
|
|
121
|
+
displayType,
|
|
122
|
+
errors,
|
|
123
|
+
prefix = ""
|
|
124
|
+
) => {
|
|
125
|
+
Object.keys(schemaObj).forEach((key) => {
|
|
126
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
127
|
+
|
|
128
|
+
if (!allowedKeys.has(fullKey)) {
|
|
129
|
+
errors.add(
|
|
130
|
+
`"${schemaName}" has an invalid key "${fullKey}" for displayType "${displayType}".`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
typeof schemaObj[key] === "object" &&
|
|
136
|
+
schemaObj[key] !== null &&
|
|
137
|
+
!Array.isArray(schemaObj[key])
|
|
138
|
+
) {
|
|
139
|
+
validateSchemaKeys(
|
|
140
|
+
schemaObj[key],
|
|
141
|
+
allowedKeys,
|
|
142
|
+
schemaName,
|
|
143
|
+
displayType,
|
|
144
|
+
errors,
|
|
145
|
+
fullKey
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Validate a single component schema against its component type definition
|
|
153
|
+
* @param {Object} schema - The schema to validate
|
|
154
|
+
* @param {string} displayType - The display type to validate against
|
|
155
|
+
* @param {Set} errors - Error collection
|
|
156
|
+
*/
|
|
157
|
+
const validateComponentByType = (schema, displayType, errors) => {
|
|
158
|
+
// Get the component schema definition for this display type
|
|
159
|
+
const componentSchema = componentSchemas[displayType];
|
|
160
|
+
|
|
161
|
+
if (!componentSchema) {
|
|
162
|
+
errors.add(
|
|
163
|
+
`"${schema.name}" has an unsupported displayType "${displayType}".`
|
|
164
|
+
);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!componentSchema.meta) {
|
|
169
|
+
errors.add(
|
|
170
|
+
`Component schema for "${displayType}" is missing meta definition.`
|
|
171
|
+
);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Extract allowed keys from the component schema
|
|
176
|
+
const allowedKeys = extractAllowedKeys(componentSchema.meta);
|
|
177
|
+
|
|
178
|
+
// Validate the schema meta object (excluding displayType which we already handled)
|
|
179
|
+
const { displayType: currentDisplayType, ...restMeta } = schema.meta;
|
|
180
|
+
validateSchemaKeys(
|
|
181
|
+
restMeta,
|
|
182
|
+
allowedKeys,
|
|
183
|
+
schema.name,
|
|
184
|
+
currentDisplayType,
|
|
185
|
+
errors
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const validateComponentSchemas = (schemas, errors) => {
|
|
190
|
+
schemas.forEach((schema) => {
|
|
191
|
+
// Basic required field validation
|
|
192
|
+
if (!schema.name) {
|
|
193
|
+
errors.add(`Schema is missing a name.`);
|
|
194
|
+
return; // Can't continue without a name
|
|
195
|
+
}
|
|
196
|
+
if (!schema.meta) {
|
|
197
|
+
errors.add(`"${schema.name}" is missing a meta object.`);
|
|
198
|
+
return; // Can't continue without meta
|
|
199
|
+
}
|
|
200
|
+
if (!schema.meta.displayType) {
|
|
201
|
+
errors.add(`"${schema.name}" is missing a displayType.`);
|
|
202
|
+
return; // Can't continue without displayType
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Optional field validation (these are warnings, not blocking)
|
|
206
|
+
if (!schema.meta.displayName) {
|
|
207
|
+
errors.add(`"${schema.name}" is missing a displayName.`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Only require placeholder if the component schema defines it
|
|
211
|
+
const componentSchema = componentSchemas[schema.meta.displayType];
|
|
212
|
+
if (
|
|
213
|
+
componentSchema &&
|
|
214
|
+
componentSchema.meta &&
|
|
215
|
+
"placeholder" in componentSchema.meta &&
|
|
216
|
+
!schema.meta.placeholder
|
|
217
|
+
) {
|
|
218
|
+
errors.add(`"${schema.name}" is missing a placeholder.`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Only require description if the component schema defines it
|
|
222
|
+
if (
|
|
223
|
+
componentSchema &&
|
|
224
|
+
componentSchema.meta &&
|
|
225
|
+
"description" in componentSchema.meta &&
|
|
226
|
+
!schema.meta.description
|
|
227
|
+
) {
|
|
228
|
+
errors.add(`"${schema.name}" is missing a description.`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Validate against the specific component type schema
|
|
232
|
+
validateComponentByType(schema, schema.meta.displayType, errors);
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
|
|
53
236
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
54
237
|
// INDIVIDUAL VALIDATORS
|
|
55
238
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -83,6 +266,18 @@ const validateWebhook = (webhookPath, spec, errors) => {
|
|
|
83
266
|
`"webhook.json" exists but trigger_type is not defined in spec.json.`
|
|
84
267
|
);
|
|
85
268
|
}
|
|
269
|
+
|
|
270
|
+
// Validate webhook schema parameters if webhook exists
|
|
271
|
+
if (hasWebhook) {
|
|
272
|
+
const webhookSchema = readAndParseJson(
|
|
273
|
+
webhookPath,
|
|
274
|
+
"webhook.json",
|
|
275
|
+
errors
|
|
276
|
+
);
|
|
277
|
+
if (webhookSchema && Array.isArray(webhookSchema.parameters)) {
|
|
278
|
+
validateComponentSchemas(webhookSchema.parameters, errors);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
86
281
|
};
|
|
87
282
|
|
|
88
283
|
const validateBaseSchema = (baseSchemaPath, errors) => {
|
|
@@ -90,7 +285,49 @@ const validateBaseSchema = (baseSchemaPath, errors) => {
|
|
|
90
285
|
errors.add(`"base.json" not found in the "schemas" directory.`);
|
|
91
286
|
return null;
|
|
92
287
|
}
|
|
93
|
-
|
|
288
|
+
|
|
289
|
+
const baseSchema = readAndParseJson(baseSchemaPath, "base.json", errors);
|
|
290
|
+
|
|
291
|
+
// Validate base schema parameters
|
|
292
|
+
if (baseSchema && Array.isArray(baseSchema.parameters)) {
|
|
293
|
+
validateComponentSchemas(baseSchema.parameters, errors);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return baseSchema;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const validateAuthentication = (authPath, errors) => {
|
|
300
|
+
// Authentication is optional, so only validate if it exists
|
|
301
|
+
if (fs.existsSync(authPath)) {
|
|
302
|
+
const authSchema = readAndParseJson(
|
|
303
|
+
authPath,
|
|
304
|
+
"authentication.json",
|
|
305
|
+
errors
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
// Validate authentication schema parameters
|
|
309
|
+
if (authSchema && Array.isArray(authSchema.parameters)) {
|
|
310
|
+
validateComponentSchemas(authSchema.parameters, errors);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Validate authentication type-specific parameters (like api_key, oauth, etc.)
|
|
314
|
+
if (authSchema) {
|
|
315
|
+
Object.keys(authSchema).forEach((key) => {
|
|
316
|
+
if (
|
|
317
|
+
key !== "parameters" &&
|
|
318
|
+
typeof authSchema[key] === "object" &&
|
|
319
|
+
authSchema[key] !== null
|
|
320
|
+
) {
|
|
321
|
+
if (Array.isArray(authSchema[key].parameters)) {
|
|
322
|
+
validateComponentSchemas(
|
|
323
|
+
authSchema[key].parameters,
|
|
324
|
+
errors
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
94
331
|
};
|
|
95
332
|
|
|
96
333
|
const validateResources = (resourcesDir, resourceFields, errors) => {
|
|
@@ -121,7 +358,16 @@ const validateResources = (resourcesDir, resourceFields, errors) => {
|
|
|
121
358
|
);
|
|
122
359
|
if (!schema) return;
|
|
123
360
|
|
|
124
|
-
|
|
361
|
+
// Validate resource file parameters
|
|
362
|
+
if (Array.isArray(schema.parameters)) {
|
|
363
|
+
validateComponentSchemas(schema.parameters, errors);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const operationFields = findOperationFieldsWithOptions(
|
|
367
|
+
schema,
|
|
368
|
+
`${resourceFile}.json`,
|
|
369
|
+
errors
|
|
370
|
+
);
|
|
125
371
|
|
|
126
372
|
operationFields.forEach((operation) => {
|
|
127
373
|
const operationMethod = operation.split(".")[1];
|
|
@@ -144,6 +390,11 @@ const validateResources = (resourcesDir, resourceFields, errors) => {
|
|
|
144
390
|
errors.add(
|
|
145
391
|
`Operation "${operationMethod}" in "${resourceFile}.json" is missing parameters.`
|
|
146
392
|
);
|
|
393
|
+
} else {
|
|
394
|
+
// Validate operation parameters using component schemas
|
|
395
|
+
if (Array.isArray(methodDef.parameters)) {
|
|
396
|
+
validateComponentSchemas(methodDef.parameters, errors);
|
|
397
|
+
}
|
|
147
398
|
}
|
|
148
399
|
if (!methodDef.definition) {
|
|
149
400
|
errors.add(
|
|
@@ -154,23 +405,6 @@ const validateResources = (resourcesDir, resourceFields, errors) => {
|
|
|
154
405
|
});
|
|
155
406
|
};
|
|
156
407
|
|
|
157
|
-
// const validateParametersScema = (schema, errors) => {
|
|
158
|
-
// if (!schema || !Array.isArray(schema.parameters)) {
|
|
159
|
-
// errors.add(
|
|
160
|
-
// `Schema is missing or parameters are not defined as an array.`
|
|
161
|
-
// );
|
|
162
|
-
// return;
|
|
163
|
-
// }
|
|
164
|
-
// schema.parameters.forEach((param) => {
|
|
165
|
-
// const { meta } = param;
|
|
166
|
-
// if (!param.name) {
|
|
167
|
-
// errors.add(
|
|
168
|
-
// `Parameter in schema is missing a name. Ensure all parameters have a "name" field.`
|
|
169
|
-
// );
|
|
170
|
-
// }
|
|
171
|
-
// });
|
|
172
|
-
// };
|
|
173
|
-
|
|
174
408
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
175
409
|
// MAIN FUNCTION
|
|
176
410
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -184,6 +418,7 @@ export const validateIntegrationSchemas = (currentDir) => {
|
|
|
184
418
|
resources: path.join(currentDir, "schemas", "resources"),
|
|
185
419
|
spec: path.join(currentDir, "spec.json"),
|
|
186
420
|
webhook: path.join(currentDir, "schemas", "webhook.json"),
|
|
421
|
+
authentication: path.join(currentDir, "schemas", "authentication.json"),
|
|
187
422
|
documentation: path.join(currentDir, "Documentation.mdx"),
|
|
188
423
|
};
|
|
189
424
|
|
|
@@ -192,10 +427,11 @@ export const validateIntegrationSchemas = (currentDir) => {
|
|
|
192
427
|
|
|
193
428
|
const spec = validateSpec(paths.spec, errors);
|
|
194
429
|
validateWebhook(paths.webhook, spec, errors);
|
|
430
|
+
validateAuthentication(paths.authentication, errors);
|
|
195
431
|
|
|
196
432
|
const baseSchema = validateBaseSchema(paths.base, errors);
|
|
197
433
|
const resourceFields = baseSchema
|
|
198
|
-
? findResourceFieldsWithOptions(baseSchema)
|
|
434
|
+
? findResourceFieldsWithOptions(baseSchema, "base.json", errors)
|
|
199
435
|
: [];
|
|
200
436
|
|
|
201
437
|
validateResources(paths.resources, resourceFields, errors);
|