Outlook_Addin_LLM/node_modules/eslint-plugin-office-addins/lib/rules/no-navigational-load.js

100 lines
4.8 KiB
JavaScript
Raw Permalink Normal View History

const utils_1 = require("@typescript-eslint/utils");
const getFunction_1 = require("../utils/getFunction");
const load_1 = require("../utils/load");
const propertiesType_1 = require("../utils/propertiesType");
module.exports = {
name: "no-navigational-load",
meta: {
type: "problem",
messages: {
navigationalLoad: "Calling load on the navigation property '{{loadValue}}' slows down your add-in.",
},
docs: {
description: "Calling load on a navigation property causes unneeded data to load and slows down your add-in.",
category: "Best Practices",
recommended: false,
url: "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#scalar-and-navigation-properties",
},
schema: [],
},
create: function (context) {
function isLoadingValidPropeties(propertyName) {
const properties = propertyName.split("/");
const lastProperty = properties.pop();
if (!lastProperty)
return false;
for (const property of properties) {
const propertyType = (0, propertiesType_1.getPropertyType)(property);
if (propertyType !== propertiesType_1.PropertyType.navigational &&
propertyType !== propertiesType_1.PropertyType.ambiguous) {
return false;
}
}
if (lastProperty === "*") {
return true;
}
const propertyType = (0, propertiesType_1.getPropertyType)(lastProperty);
return (propertyType === propertiesType_1.PropertyType.scalar ||
propertyType === propertiesType_1.PropertyType.ambiguous);
}
function findNavigationalLoad(scope) {
scope.variables.forEach((variable) => {
let getFound = false;
variable.references.forEach((reference) => {
var _a, _b;
const node = reference.identifier;
if (reference.isWrite()) {
getFound = false; // In case of reassignment
if (reference.writeExpr && (0, getFunction_1.isGetFunction)(reference.writeExpr)) {
getFound = true;
return;
}
}
if (!getFound) {
// If reference was not related to a previous get
return;
}
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression &&
(0, load_1.isLoadFunction)(node.parent)) {
// <obj>.load(...) call
const propertyNames = (0, load_1.parseLoadArguments)(node.parent);
propertyNames.forEach((propertyName) => {
if (propertyName && !isLoadingValidPropeties(propertyName)) {
context.report({
node: node.parent,
messageId: "navigationalLoad",
data: { name: node.name, loadValue: propertyName },
});
}
});
}
else if (((_b = node.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
//context.load(<obj>, "...") call
const callee = node.parent
.callee;
const args = node.parent.arguments;
if ((0, load_1.isLoadFunction)(callee) && args[0] == node && args.length < 3) {
const propertyNames = (0, load_1.parsePropertiesArgument)(args[1]);
propertyNames.forEach((propertyName) => {
if (propertyName && !isLoadingValidPropeties(propertyName)) {
context.report({
node: node.parent,
messageId: "navigationalLoad",
data: { name: node.name, loadValue: propertyName },
});
}
});
}
}
});
});
scope.childScopes.forEach(findNavigationalLoad);
}
return {
Program() {
findNavigationalLoad(context.getScope());
},
};
},
};
//# sourceMappingURL=no-navigational-load.js.map