Compose-ready workspace: packages/zappier (rate card, portal, Stripe), packages/verae-zapier-middleware (timestamp + NATS), packages/verae-zapier (CLI app), vendor/zapier-platform, and research/zapier vendor corpus. Gate 0 structure checks pass. Product code and research are not yet wired.
144 lines
4.2 KiB
JavaScript
144 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
const _ = require('lodash');
|
|
const jsonschema = require('jsonschema');
|
|
|
|
const actionTypes = ['triggers', 'searches', 'creates', 'bulkReads'];
|
|
const resourceMethods = ['get', 'list', 'hook', 'search', 'create'];
|
|
|
|
const validateInputFieldGroups = (
|
|
inputFields,
|
|
inputFieldGroups,
|
|
basePath,
|
|
schemaName,
|
|
) => {
|
|
const errors = [];
|
|
|
|
// Check for duplicate group keys in inputFieldGroups
|
|
const groupKeys = inputFieldGroups.map((group) => group.key);
|
|
const duplicateKeys = groupKeys.filter(
|
|
(key, index) => groupKeys.indexOf(key) !== index,
|
|
);
|
|
|
|
if (duplicateKeys.length > 0) {
|
|
duplicateKeys.forEach((duplicateKey) => {
|
|
const duplicateIndex = groupKeys.lastIndexOf(duplicateKey);
|
|
errors.push(
|
|
new jsonschema.ValidationError(
|
|
`Duplicate group key "${duplicateKey}" found in inputFieldGroups. Group keys must be unique.`,
|
|
inputFieldGroups[duplicateIndex],
|
|
schemaName,
|
|
`${basePath}.inputFieldGroups[${duplicateIndex}].key`,
|
|
'duplicateGroupKey',
|
|
'inputFieldGroups',
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
// Create a set of valid group keys
|
|
const validGroupKeys = new Set(groupKeys);
|
|
|
|
inputFields.forEach((inputField, index) => {
|
|
// Check children fields first - groups are not allowed in children
|
|
(inputField.children || []).forEach((childField, childIndex) => {
|
|
if (childField.group) {
|
|
errors.push(
|
|
new jsonschema.ValidationError(
|
|
`Group fields are not allowed in children fields. Remove the group property from this field.`,
|
|
childField.group,
|
|
'/PlainInputFieldSchema',
|
|
`${basePath}.inputFields[${index}].children[${childIndex}].group`,
|
|
'groupInChildren',
|
|
'group',
|
|
),
|
|
);
|
|
}
|
|
});
|
|
|
|
// Check if group reference is valid
|
|
if (inputField.group) {
|
|
if (!validGroupKeys.has(inputField.group)) {
|
|
const availableGroups =
|
|
Array.from(validGroupKeys).length > 0
|
|
? `[${Array.from(validGroupKeys).join(', ')}]`
|
|
: '[]';
|
|
errors.push(
|
|
new jsonschema.ValidationError(
|
|
`Group "${inputField.group}" is not defined in inputFieldGroups. Available groups: ${availableGroups}`,
|
|
inputField.group,
|
|
'/PlainInputFieldSchema',
|
|
`${basePath}.inputFields[${index}].group`,
|
|
'invalidGroupReference',
|
|
'group',
|
|
),
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
return errors;
|
|
};
|
|
|
|
const inputFieldGroupsConstraints = (definition) => {
|
|
const errors = [];
|
|
|
|
// Validate action types (triggers, searches, creates, bulkReads)
|
|
for (const actionType of actionTypes) {
|
|
const group = definition[actionType] || {};
|
|
_.each(group, (action, actionKey) => {
|
|
const inputFields = _.get(action, ['operation', 'inputFields'], []);
|
|
const inputFieldGroups = _.get(
|
|
action,
|
|
['operation', 'inputFieldGroups'],
|
|
[],
|
|
);
|
|
|
|
const basePath = `instance.${actionType}.${actionKey}.operation`;
|
|
const schemaName = '/BasicOperationSchema';
|
|
|
|
const actionErrors = validateInputFieldGroups(
|
|
inputFields,
|
|
inputFieldGroups,
|
|
basePath,
|
|
schemaName,
|
|
);
|
|
errors.push(...actionErrors);
|
|
});
|
|
}
|
|
|
|
// Validate resources
|
|
if (definition.resources) {
|
|
_.each(definition.resources, (resource, resourceKey) => {
|
|
resourceMethods.forEach((method) => {
|
|
if (resource[method] && resource[method].operation) {
|
|
const inputFields = _.get(
|
|
resource[method],
|
|
['operation', 'inputFields'],
|
|
[],
|
|
);
|
|
const inputFieldGroups = _.get(
|
|
resource[method],
|
|
['operation', 'inputFieldGroups'],
|
|
[],
|
|
);
|
|
|
|
const basePath = `instance.resources.${resourceKey}.${method}.operation`;
|
|
const schemaName = '/BasicOperationSchema';
|
|
|
|
const resourceErrors = validateInputFieldGroups(
|
|
inputFields,
|
|
inputFieldGroups,
|
|
basePath,
|
|
schemaName,
|
|
);
|
|
errors.push(...resourceErrors);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
return errors;
|
|
};
|
|
|
|
module.exports = inputFieldGroupsConstraints;
|