Initial commit

This commit is contained in:
2025-03-07 19:22:02 +01:00
commit 4a98255d83
55743 changed files with 5280367 additions and 0 deletions
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"callSyncAfterLoad", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,103 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const load_1 = require("../utils/load");
const utils_2 = require("../utils/utils");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#load")({
name: "call-sync-after-load",
meta: {
type: "suggestion",
messages: {
callSyncAfterLoad: "Call context.sync() after calling load on '{{name}}' for the property '{{loadValue}}' and before reading the property.",
},
docs: {
description: "Always call context.sync() between loading one or more properties on objects and reading any of those properties.",
},
schema: [],
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
class VariablePropertySet extends Set {
add(variableProperty) {
return super.add(JSON.stringify(variableProperty));
}
has(variableProperty) {
return super.has(JSON.stringify(variableProperty));
}
}
let apiReferences = [];
function findLoadBeforeSync() {
const needSync = new VariablePropertySet();
apiReferences.forEach((apiReference) => {
const operation = apiReference.operation;
const reference = apiReference.reference;
const identifier = reference.identifier;
const variable = reference.resolved;
if (operation === "Load" && variable) {
const propertiesArgument = getPropertiesArgument(identifier);
const propertyNames = propertiesArgument
? (0, load_1.parsePropertiesArgument)(propertiesArgument)
: ["*"];
propertyNames.forEach((propertyName) => {
needSync.add({
variable: variable.name,
property: propertyName,
});
});
}
else if (operation === "Sync") {
needSync.clear();
}
else if (operation === "Read" && variable) {
const propertyName = (0, utils_2.findPropertiesRead)(reference.identifier.parent);
if (needSync.has({ variable: variable.name, property: propertyName }) ||
needSync.has({ variable: variable.name, property: "*" })) {
const node = reference.identifier;
context.report({
node: node,
messageId: "callSyncAfterLoad",
data: { name: node.name, loadValue: propertyName },
});
}
}
});
}
function getPropertiesArgument(identifier) {
var _a, _b;
let propertiesArgument;
if (((_a = identifier.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
// Look for <obj>.load(...) call
const methodCall = (0, utils_2.findCallExpression)(identifier.parent);
if (methodCall && (0, load_1.isLoadCall)(methodCall)) {
propertiesArgument = methodCall.arguments[0];
}
}
else if (((_b = identifier.parent) === null || _b === void 0 ? void 0 : _b.type) === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
// Look for context.load(<obj>, "...") call
const args = identifier.parent.arguments;
if ((0, load_1.isLoadCall)(identifier.parent) &&
args[0] == identifier &&
args.length < 3) {
propertiesArgument = args[1];
}
}
return propertiesArgument;
}
return {
Program(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
apiReferences = (0, utils_2.findOfficeApiReferences)(scope);
apiReferences.sort((left, right) => {
return (left.reference.identifier.range[1] -
right.reference.identifier.range[1]);
});
findLoadBeforeSync();
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=call-sync-after-load.js.map
@@ -0,0 +1 @@
{"version":3,"file":"call-sync-after-load.js","sourceRoot":"","sources":["../../src/rules/call-sync-after-load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"callSync", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const utils_2 = require("../utils/utils");
const utils_3 = require("../utils/utils");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#sync")({
name: "call-sync-before-read",
meta: {
type: "problem",
messages: {
callSync: "Call context.sync() before trying to read '{{name}}'.",
},
docs: {
description: "Always call load on the object's properties followed by a context.sync() before reading them.",
},
schema: [],
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
let apiReferences = [];
function checkPropertyIsRead(node) {
var _a;
const topExpression = (0, utils_2.findTopMemberExpression)(node);
switch ((_a = topExpression.parent) === null || _a === void 0 ? void 0 : _a.type) {
case utils_1.TSESTree.AST_NODE_TYPES.AssignmentExpression:
return topExpression.parent.right === topExpression;
default:
return true;
}
}
function findReadBeforeSync() {
const needSync = new Set();
apiReferences.forEach((apiReference) => {
var _a;
const operation = apiReference.operation;
const reference = apiReference.reference;
const variable = reference.resolved;
if (operation === "Get" && variable) {
needSync.add(variable);
}
if (operation === "Sync") {
needSync.clear();
}
if (operation === "Read" && variable && needSync.has(variable)) {
const node = reference.identifier;
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression &&
checkPropertyIsRead(node.parent)) {
context.report({
node: node,
messageId: "callSync",
data: { name: node.name },
});
}
}
});
}
return {
Program(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
apiReferences = (0, utils_3.findOfficeApiReferences)(scope);
apiReferences.sort((left, right) => {
return (left.reference.identifier.range[1] -
right.reference.identifier.range[1]);
});
findReadBeforeSync();
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=call-sync-before-read.js.map
@@ -0,0 +1 @@
{"version":3,"file":"call-sync-before-read.js","sourceRoot":"","sources":["../../src/rules/call-sync-before-read.ts"],"names":[],"mappings":"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"}
+11
View File
@@ -0,0 +1,11 @@
declare const _default: {
"call-sync-before-read": import("@typescript-eslint/utils/ts-eslint").RuleModule<"callSync", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"load-object-before-read": import("@typescript-eslint/utils/ts-eslint").RuleModule<"loadBeforeRead", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"call-sync-after-load": import("@typescript-eslint/utils/ts-eslint").RuleModule<"callSyncAfterLoad", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"no-context-sync-in-loop": import("@typescript-eslint/utils/ts-eslint").RuleModule<"loopedSync", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"no-empty-load": import("@typescript-eslint/utils/ts-eslint").RuleModule<"emptyLoad", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"no-navigational-load": import("@typescript-eslint/utils/ts-eslint").RuleModule<"navigationalLoad", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"no-office-initialize": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noOfficeInitialize", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
"test-for-null-using-isNullObject": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useIsNullObject", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
};
export default _default;
+24
View File
@@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const call_sync_after_load_1 = __importDefault(require("./call-sync-after-load"));
const call_sync_before_read_1 = __importDefault(require("./call-sync-before-read"));
const load_object_before_read_1 = __importDefault(require("./load-object-before-read"));
const no_context_sync_in_loop_1 = __importDefault(require("./no-context-sync-in-loop"));
const no_empty_load_1 = __importDefault(require("./no-empty-load"));
const no_navigational_load_1 = __importDefault(require("./no-navigational-load"));
const no_office_initialize_1 = __importDefault(require("./no-office-initialize"));
const test_for_null_using_isNullObject_1 = __importDefault(require("./test-for-null-using-isNullObject"));
exports.default = {
"call-sync-before-read": call_sync_before_read_1.default,
"load-object-before-read": load_object_before_read_1.default,
"call-sync-after-load": call_sync_after_load_1.default,
"no-context-sync-in-loop": no_context_sync_in_loop_1.default,
"no-empty-load": no_empty_load_1.default,
"no-navigational-load": no_navigational_load_1.default,
"no-office-initialize": no_office_initialize_1.default,
"test-for-null-using-isNullObject": test_for_null_using_isNullObject_1.default,
};
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;;;AAAA,kFAAuD;AACvD,oFAAyD;AACzD,wFAA6D;AAC7D,wFAA4D;AAC5D,oEAA0C;AAC1C,kFAAwD;AACxD,kFAAwD;AACxD,0GAA8E;AAE9E,kBAAe;IACb,uBAAuB,EAAE,+BAAkB;IAC3C,yBAAyB,EAAE,iCAAoB;IAC/C,sBAAsB,EAAE,8BAAiB;IACzC,yBAAyB,EAAE,iCAAmB;IAC9C,eAAe,EAAE,uBAAW;IAC5B,sBAAsB,EAAE,8BAAkB;IAC1C,sBAAsB,EAAE,8BAAkB;IAC1C,kCAAkC,EAAE,0CAA4B;CACjE,CAAC"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"loadBeforeRead", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const load_1 = require("../utils/load");
const utils_2 = require("../utils/utils");
const getFunction_1 = require("../utils/getFunction");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#load")({
name: "load-object-before-read",
meta: {
type: "problem",
messages: {
loadBeforeRead: "An explicit load call on '{{name}}' for property '{{loadValue}}' needs to be made before the property can be read.",
},
docs: {
description: "Before you can read the properties of a proxy object, you must explicitly load the properties.",
},
schema: [],
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
function isInsideWriteStatement(node) {
while (node.parent) {
node = node.parent;
if (node.type === utils_1.TSESTree.AST_NODE_TYPES.AssignmentExpression)
return true;
}
return false;
}
function hasBeenLoaded(node, loadLocation, propertyName) {
var _a;
return (loadLocation.has(propertyName) && // If reference came after load, return
node.range[1] > ((_a = loadLocation.get(propertyName)) !== null && _a !== void 0 ? _a : 0));
}
function findLoadBeforeRead(scope) {
scope.variables.forEach((variable) => {
const loadLocation = new Map();
let getFound = false;
variable.references.forEach((reference) => {
const node = reference.identifier;
const parent = node.parent;
if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.TSESTree.AST_NODE_TYPES.VariableDeclarator) {
getFound = false; // In case of reassignment
if (parent.init &&
(0, getFunction_1.isGetFunction)(parent.init) &&
!(0, getFunction_1.isGetOrNullObjectFunction)(parent.init)) {
getFound = true;
return;
}
}
if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.TSESTree.AST_NODE_TYPES.AssignmentExpression) {
getFound = false; // In case of reassignment
if ((0, getFunction_1.isGetFunction)(parent.right) &&
!(0, getFunction_1.isGetOrNullObjectFunction)(parent.right)) {
getFound = true;
return;
}
}
if (!getFound) {
// If reference was not related to a previous get
return;
}
// Look for <obj>.load(...) call
if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.TSESTree.AST_NODE_TYPES.MemberExpression) {
const methodCall = (0, utils_2.findCallExpression)(parent);
if (methodCall && (0, load_1.isLoadCall)(methodCall)) {
const argument = methodCall.arguments[0];
const propertyNames = argument
? (0, load_1.parsePropertiesArgument)(argument)
: ["*"];
propertyNames.forEach((propertyName) => {
loadLocation.set(propertyName, node.range[1]);
});
return;
}
}
// Look for context.load(<obj>, "...") call
if ((parent === null || parent === void 0 ? void 0 : parent.type) === utils_1.TSESTree.AST_NODE_TYPES.CallExpression) {
const args = parent === null || parent === void 0 ? void 0 : parent.arguments;
if ((0, load_1.isLoadCall)(parent) && args[0] == node && args.length < 3) {
const propertyNames = args[1]
? (0, load_1.parsePropertiesArgument)(args[1])
: ["*"];
propertyNames.forEach((propertyName) => {
loadLocation.set(propertyName, node.range[1]);
});
return;
}
}
const propertyName = (0, utils_2.findPropertiesRead)(parent);
if (!propertyName ||
hasBeenLoaded(node, loadLocation, propertyName) ||
hasBeenLoaded(node, loadLocation, "*") ||
isInsideWriteStatement(node)) {
return;
}
context.report({
node: node,
messageId: "loadBeforeRead",
data: { name: node.name, loadValue: propertyName },
});
});
});
scope.childScopes.forEach(findLoadBeforeRead);
}
return {
Program(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
findLoadBeforeRead(scope);
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=load-object-before-read.js.map
@@ -0,0 +1 @@
{"version":3,"file":"load-object-before-read.js","sourceRoot":"","sources":["../../src/rules/load-object-before-read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"loopedSync", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/concepts/correlated-objects-pattern")({
name: "no-context-sync-in-loop",
meta: {
type: "problem",
messages: {
loopedSync: "Calling context.sync() inside a loop can lead to poor performance",
},
docs: {
description: "Calling context.sync() inside of a loop dramatically increases the time the code runs, proportional to the number of iterations.",
},
schema: [],
},
create: function (context) {
return {
":matches(ForStatement, ForInStatement, WhileStatement, DoWhileStatement, ForOfStatement) CallExpression[callee.object.name='context'][callee.property.name='sync']"(node) {
context.report({
node: node.callee,
messageId: "loopedSync",
});
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=no-context-sync-in-loop.js.map
@@ -0,0 +1 @@
{"version":3,"file":"no-context-sync-in-loop.js","sourceRoot":"","sources":["../../src/rules/no-context-sync-in-loop.ts"],"names":[],"mappings":";;AAAA,oDAAiE;AAEjE,kBAAe,mBAAW,CAAC,WAAW,CACpC,GAAG,EAAE,CACH,mFAAmF,CACtF,CAAC;IACA,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE;YACR,UAAU,EACR,mEAAmE;SACtE;QACD,IAAI,EAAE;YACJ,WAAW,EACT,kIAAkI;SACrI;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,EAAE,UAAU,OAAO;QACvB,OAAO;YACL,oKAAoK,CAClK,IAA6B;gBAE7B,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,IAAI,CAAC,MAAM;oBACjB,SAAS,EAAE,YAAY;iBACxB,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,EAAE;CACnB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"emptyLoad", [], unknown, ESLintUtils.RuleListener>;
export default _default;
+76
View File
@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const getFunction_1 = require("../utils/getFunction");
const load_1 = require("../utils/load");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#calling-load-without-parameters-not-recommended")({
name: "no-empty-load",
meta: {
type: "problem",
messages: {
emptyLoad: "Calling load without any argument slows down your add-in.",
},
docs: {
description: "Calling load without any argument causes unneeded data to load and slows down your add-in.",
},
schema: [],
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
function isEmptyLoad(node) {
if ((0, load_1.isLoadFunction)(node)) {
const propertyNames = (0, load_1.parseLoadArguments)(node);
if (propertyNames.length === 0) {
return true;
}
let foundEmptyProperty = false;
propertyNames.forEach((property) => {
if (!property) {
foundEmptyProperty = true;
}
});
return foundEmptyProperty;
}
return false;
}
function findEmptyLoad(scope) {
scope.variables.forEach((variable) => {
let getFound = false;
variable.references.forEach((reference) => {
var _a;
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 &&
isEmptyLoad(node.parent)) {
context.report({
node: node.parent,
messageId: "emptyLoad",
});
}
});
});
scope.childScopes.forEach(findEmptyLoad);
}
return {
Program(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
findEmptyLoad(scope);
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=no-empty-load.js.map
@@ -0,0 +1 @@
{"version":3,"file":"no-empty-load.js","sourceRoot":"","sources":["../../src/rules/no-empty-load.ts"],"names":[],"mappings":";;AAAA,oDAAiE;AAEjE,sDAAqD;AACrD,wCAAmE;AAEnE,kBAAe,mBAAW,CAAC,WAAW,CACpC,GAAG,EAAE,CACH,sIAAsI,CACzI,CAAC;IACA,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE;YACR,SAAS,EAAE,2DAA2D;SACvE;QACD,IAAI,EAAE;YACJ,WAAW,EACT,4FAA4F;SAC/F;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,EAAE,UAAU,OAAO;;QACvB,MAAM,UAAU,GAAG,MAAA,OAAO,CAAC,UAAU,mCAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QACjE,SAAS,WAAW,CAAC,IAA+B;YAClD,IAAI,IAAA,qBAAc,EAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM,aAAa,GAAa,IAAA,yBAAkB,EAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,IAAI,kBAAkB,GAAG,KAAK,CAAC;gBAC/B,aAAa,CAAC,OAAO,CAAC,CAAC,QAAgB,EAAE,EAAE;oBACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,kBAAkB,GAAG,IAAI,CAAC;oBAC5B,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,OAAO,kBAAkB,CAAC;YAC5B,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,SAAS,aAAa,CAAC,KAAY;YACjC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAkB,EAAE,EAAE;gBAC7C,IAAI,QAAQ,GAAY,KAAK,CAAC;gBAC9B,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAoB,EAAE,EAAE;;oBACnD,MAAM,IAAI,GAAkB,SAAS,CAAC,UAAU,CAAC;oBAEjD,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;wBACxB,QAAQ,GAAG,KAAK,CAAC,CAAC,0BAA0B;wBAC5C,IAAI,SAAS,CAAC,SAAS,IAAI,IAAA,2BAAa,EAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;4BAC9D,QAAQ,GAAG,IAAI,CAAC;4BAChB,OAAO;wBACT,CAAC;oBACH,CAAC;oBAED,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,iDAAiD;wBACjD,OAAO;oBACT,CAAC;oBAED,IACE,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,IAAI,MAAK,gBAAQ,CAAC,cAAc,CAAC,gBAAgB;wBAC9D,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EACxB,CAAC;wBACD,OAAO,CAAC,MAAM,CAAC;4BACb,IAAI,EAAE,IAAI,CAAC,MAAM;4BACjB,SAAS,EAAE,WAAW;yBACvB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO;YACL,OAAO,CAAC,IAAI;gBACV,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ;oBAC/B,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAC3B,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACvB,aAAa,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,EAAE;CACnB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"navigationalLoad", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,105 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#scalar-and-navigation-properties")({
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.",
},
schema: [],
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
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(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
findNavigationalLoad(scope);
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=no-navigational-load.js.map
@@ -0,0 +1 @@
{"version":3,"file":"no-navigational-load.js","sourceRoot":"","sources":["../../src/rules/no-navigational-load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"noOfficeInitialize", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/initialize-add-in#initialize-with-officeonready")({
name: "no-office-initialize",
meta: {
type: "suggestion",
messages: {
noOfficeInitialize: "Office.onReady() is preferred over Office.initialize.",
},
docs: {
description: "Office.onReady() is more flexible than Office.initialize.",
},
schema: [],
},
create: function (context) {
return {
"AssignmentExpression[left.object.name='Office'][left.property.name='initialize']"(node) {
context.report({
node: node,
messageId: "noOfficeInitialize",
});
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=no-office-initialize.js.map
@@ -0,0 +1 @@
{"version":3,"file":"no-office-initialize.js","sourceRoot":"","sources":["../../src/rules/no-office-initialize.ts"],"names":[],"mappings":";;AAAA,oDAAiE;AAEjE,kBAAe,mBAAW,CAAC,WAAW,CACpC,GAAG,EAAE,CACH,uGAAuG,CAC1G,CAAC;IACA,IAAI,EAAE,sBAAsB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,kBAAkB,EAChB,uDAAuD;SAC1D;QACD,IAAI,EAAE;YACJ,WAAW,EAAE,2DAA2D;SACzE;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,EAAE,UAAU,OAAO;QACvB,OAAO;YACL,kFAAkF,CAChF,IAAmC;gBAEnC,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI,EAAE,IAAI;oBACV,SAAS,EAAE,oBAAoB;iBAChC,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,EAAE;CACnB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
import { ESLintUtils } from "@typescript-eslint/utils";
declare const _default: ESLintUtils.RuleModule<"useIsNullObject", [], unknown, ESLintUtils.RuleListener>;
export default _default;
@@ -0,0 +1,119 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const getFunction_1 = require("../utils/getFunction");
exports.default = utils_1.ESLintUtils.RuleCreator(() => "https://docs.microsoft.com/office/dev/add-ins/develop/application-specific-api-model#ornullobject-methods-and-properties")({
name: "test-for-null-using-isNullObject",
meta: {
type: "problem",
messages: {
useIsNullObject: "Test the isNullObject property of '{{name}}'.",
},
docs: {
description: "Do not test the truthiness of an object returned by an OrNullObject method or property. Test it's isNullObject property.",
},
schema: [],
fixable: "code",
},
create: function (context) {
var _a;
const sourceCode = (_a = context.sourceCode) !== null && _a !== void 0 ? _a : context.getSourceCode();
function isConditionalTestExpression(node) {
return (node.parent != undefined &&
(node.parent.type === utils_1.AST_NODE_TYPES.IfStatement ||
node.parent.type === utils_1.AST_NODE_TYPES.WhileStatement ||
node.parent.type === utils_1.AST_NODE_TYPES.DoWhileStatement ||
node.parent.type === utils_1.AST_NODE_TYPES.ForStatement ||
node.parent.type === utils_1.AST_NODE_TYPES.ConditionalExpression) &&
node === node.parent.test);
}
function isInUnaryNullTest(node) {
return (node.parent != undefined &&
node.parent.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
node.parent.operator === "!" &&
node.parent.argument === node);
}
function isInBinaryNullTest(node) {
return (node.parent != undefined &&
node.parent.type === utils_1.AST_NODE_TYPES.BinaryExpression &&
((node.parent.left === node &&
node.parent.right.type === utils_1.AST_NODE_TYPES.Literal &&
node.parent.right.raw === "null") ||
(node.parent.right === node &&
node.parent.left.type === utils_1.AST_NODE_TYPES.Literal &&
node.parent.left.raw === "null")));
}
function isInNullTest(node) {
var _a;
return (isConditionalTestExpression(node) ||
((_a = node.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.LogicalExpression ||
isInUnaryNullTest(node) ||
isInBinaryNullTest(node));
}
function isNullObjectNode(node) {
if (node &&
((node.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
node.init &&
(0, getFunction_1.isGetOrNullObjectFunction)(node.init) &&
node.id.type === utils_1.AST_NODE_TYPES.Identifier) ||
(node.type === utils_1.AST_NODE_TYPES.AssignmentExpression &&
(0, getFunction_1.isGetOrNullObjectFunction)(node.right) &&
node.left.type === utils_1.AST_NODE_TYPES.Identifier))) {
return true;
}
return false;
}
function findNullObjectNullTests(scope) {
const variables = scope.variables;
const childScopes = scope.childScopes;
for (let i = 0; i < variables.length; i++) {
const variable = variables[i];
const references = variable.references;
let nullObjectCall = false;
const nullTests = [];
for (let ref = 0; ref < references.length; ref++) {
const identifier = references[ref].identifier;
if (isNullObjectNode(identifier.parent)) {
nullObjectCall = true;
}
if (isInNullTest(identifier)) {
nullTests.push(identifier);
}
}
if (nullObjectCall === true && nullTests.length > 0) {
nullTests.forEach((identifier) => {
context.report({
node: identifier,
messageId: "useIsNullObject",
data: { name: identifier.name },
fix: function (fixer) {
let ruleFix;
if (isInBinaryNullTest(identifier) && identifier.parent) {
const newTest = identifier.name + ".isNullObject";
ruleFix = fixer.replaceText(identifier.parent, newTest);
}
else {
ruleFix = fixer.insertTextAfter(identifier, ".isNullObject");
}
return ruleFix;
},
});
});
}
}
for (let i = 0; i < childScopes.length; ++i) {
findNullObjectNullTests(childScopes[i]);
}
}
return {
"Program:exit"(node) {
const scope = sourceCode.getScope
? sourceCode.getScope(node)
: context.getScope();
findNullObjectNullTests(scope);
},
};
},
defaultOptions: [],
});
//# sourceMappingURL=test-for-null-using-isNullObject.js.map
@@ -0,0 +1 @@
{"version":3,"file":"test-for-null-using-isNullObject.js","sourceRoot":"","sources":["../../src/rules/test-for-null-using-isNullObject.ts"],"names":[],"mappings":"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"}