Skip to content

Commit

Permalink
feat(core): add runtime check for performBulk
Browse files Browse the repository at this point in the history
  • Loading branch information
eliangcs committed May 14, 2024
1 parent 0ba70f9 commit 1e8c53c
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/app-middlewares/after/checks.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const checkOutput = (output) => {
})
.map((check) => {
return check
.run(event.method, output.results, compiledApp)
.run(event.method, output.results, compiledApp, event.bundle)
.map((err) => ({ name: check.name, error: err }));
});
const checkResults = _.flatten(rawResults);
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/checks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ module.exports = {
triggerHasId: require('./trigger-has-id'),
firehoseSubscriptionIsArray: require('./firehose_is_array'),
firehoseSubscriptionKeyIsString: require('./firehose_is_string'),
performBulkReturnType: require('./perform-bulk-return-type'),
};
5 changes: 4 additions & 1 deletion packages/core/src/checks/is-create.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module.exports = (method) => {
// `method` will never start with "resources.". Seems like legacy code.
return (
(method.startsWith('creates.') && method.endsWith('.operation.perform')) ||
(method.startsWith('creates.') &&
(method.endsWith('.operation.perform') ||
method.endsWith('.operation.performBulk'))) ||
(method.startsWith('resources.') &&
method.endsWith('.create.operation.perform'))
);
Expand Down
60 changes: 60 additions & 0 deletions packages/core/src/checks/perform-bulk-return-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const _ = require('lodash');

const performBulkEchoesIds = {
name: 'performBulkReturnType',

shouldRun: (method) => {
return (
method.endsWith('.operation.performBulk') && method.startsWith('creates.')
);
},

run: (method, results, compiledApp, bundle) => {
if (!Array.isArray(bundle.bulk)) {
// Should not happen, but we don't want this check to break because of a bad
// input bundle either
return [];
}

if (!_.isPlainObject(results)) {
// create-is-object should have caught this
return [];
}

const inputIds = bundle.bulk
.map((b) => {
return b && b.meta ? b.meta.id : null;
})
.filter((id) => id);

const outputIds = Object.keys(results);
const missingIds = inputIds.filter((id) => !outputIds.includes(id));

if (missingIds.length > 0) {
return [
`Result object must have these IDs as keys: ${inputIds.join(', ')}; ` +
`missing IDs: ${missingIds.join(', ')}.`,
];
}

const errors = [];
for (const [id, item] of results.entries()) {
if (!_.isPlainObject(item)) {
errors.push(`Result object member with ID '${id}' must be an object`);
} else if (!_.isPlainObject(item.outputData)) {
errors.push(
`Result object member with ID '${id}' must have 'outputData' object`
);
}

if (errors.length >= 4) {
// No need to flood the user with too many errors
break;
}
}

return errors;
},
};

module.exports = performBulkEchoesIds;

0 comments on commit 1e8c53c

Please sign in to comment.