Skip to content

Commit

Permalink
chore: update eslint deps + rules
Browse files Browse the repository at this point in the history
update to the latest msgraph eslint config
fix a number of issues now treated as errors
improved typing in many areas reducing the number of explicit any type references
  • Loading branch information
gavinbarron committed Sep 22, 2023
1 parent 3c3ca97 commit 3c284e4
Show file tree
Hide file tree
Showing 39 changed files with 131 additions and 106 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = {
ignorePatterns: ['**/**-css.ts', '.eslintrc.js', '*.cjs'],
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }]
// prefer-nullish-coalescing requires strictNullChecking to be turned on
'@typescript-eslint/prefer-nullish-coalescing': 'off'
}
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"bundle": "cd ./packages/mgt && npm run bundle",
"clean": "lerna run --parallel --stream --scope @microsoft/* clean",
"lint:eslint": "eslint -c .eslintrc.js --quiet 'packages/*/src/**/*.ts'",
"lint:eslint:loud": "eslint -c .eslintrc.js 'packages/*/src/**/*.ts'",
"lint:styles": "stylelint './packages/mgt-components/**/*.{css,scss}'",
"lint:fix": "npm run lint:styles -- --fix",
"lint": "npm run lint:eslint && npm run lint:styles",
Expand Down Expand Up @@ -65,7 +66,7 @@
"@babel/preset-react": "^7.12.7",
"@babel/preset-typescript": "^7.12.7",
"@custom-elements-manifest/analyzer": "^0.8.3",
"@microsoft/eslint-config-msgraph": "file:/home/gavinb/dev/eslint-config-msgraph/microsoft-eslint-config-msgraph-2.0.0.tgz",
"@microsoft/eslint-config-msgraph": "^2.0.0",
"@octokit/rest": "^18.5.3",
"@open-wc/testing-helpers": "^2.3.0",
"@storybook/addon-a11y": "^6.5.16",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ export class MgtFileUpload extends MgtBaseComponent {
if (fileItems.length > 0) {
const templateFileItems = fileItems.map(fileItem => {
if (folderStructure.indexOf(fileItem.fullPath.substring(0, fileItem.fullPath.lastIndexOf('/'))) === -1) {
if (fileItem.fullPath.substring(0, fileItem.fullPath.lastIndexOf('/')) !== '') {
if (!fileItem.fullPath.endsWith('/')) {
folderStructure.push(fileItem.fullPath.substring(0, fileItem.fullPath.lastIndexOf('/')));
return mgtHtml`
<div class='file-upload-table'>
Expand Down Expand Up @@ -943,10 +943,9 @@ export class MgtFileUpload extends MgtBaseComponent {
let itemPath = '';
if (this.fileUploadList.itemPath) {
if (this.fileUploadList.itemPath.length > 0) {
itemPath =
this.fileUploadList.itemPath.substring(0, 1) === '/'
? this.fileUploadList.itemPath
: '/' + this.fileUploadList.itemPath;
itemPath = this.fileUploadList.itemPath.startsWith('/')
? this.fileUploadList.itemPath
: '/' + this.fileUploadList.itemPath;
}
}

Expand Down
8 changes: 5 additions & 3 deletions packages/mgt-components/src/components/mgt-get/mgt-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import { Entity } from '@microsoft/microsoft-graph-types';
/**
* Simple holder type for an image
*/
type ImageValue = { image: string };
interface ImageValue {
image: string;
}

/**
* A type guard to check if a value is a collection response
Expand Down Expand Up @@ -74,10 +76,10 @@ const getIsResponseCacheEnabled = (): boolean =>
/**
* Holder type emitted with the dataChange event
*/
export type DataChangedDetail = {
export interface DataChangedDetail {
response?: CollectionResponse<Entity>;
error?: object;
};
}

/**
* Custom element for making Microsoft Graph get queries
Expand Down
4 changes: 2 additions & 2 deletions packages/mgt-components/src/components/mgt-login/mgt-login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ registerFluentComponents(fluentListbox, fluentProgressRing, fluentButton, fluent
*/
export type LoginViewType = 'avatar' | 'compact' | 'full';

type PersonViewConfig = {
interface PersonViewConfig {
view: ViewType;
avatarSize: AvatarSize;
};
}

/**
* Web component button and flyout control to facilitate Microsoft identity platform authentication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { fluentTextField, fluentCard } from '@fluentui/web-components';
import { registerFluentComponents } from '../../utils/FluentComponents';
import { strings } from './strings';
import { Person, User } from '@microsoft/microsoft-graph-types';
import { isGraphError } from '../../graph/isGraphError';

registerFluentComponents(fluentTextField, fluentCard);

Expand Down Expand Up @@ -641,10 +642,10 @@ export class MgtPeoplePicker extends MgtTemplatedComponent {
try {
const personDetails = await getUser(graph, userId);
this.addPerson(personDetails);
} catch (e: any) {
} catch (e: unknown) {
// This caters for allow-any-email property if it's enabled on the component
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
if (e.message?.includes('does not exist') && this.allowAnyEmail) {
if (isGraphError(e) && e.message?.includes('does not exist') && this.allowAnyEmail) {
if (isValidEmail(userId)) {
const anyMailUser = {
mail: userId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ export class MgtPicker extends MgtTemplatedComponent {
this.error = error;
}

private handleClick(e: MouseEvent, item: any) {
private handleClick(e: MouseEvent, item: Entity) {
this.fireCustomEvent('selectionChanged', item, true, false, true);
}

Expand All @@ -312,15 +312,15 @@ export class MgtPicker extends MgtTemplatedComponent {
*/
private readonly handleComboboxKeydown = (e: KeyboardEvent) => {
let value: string;
let item: any;
let item: Entity;
const keyName: string = e.key;
const comboBox: HTMLElement = e.target as HTMLElement;
const fluentOptionEl = comboBox.querySelector('.selected');
if (fluentOptionEl) {
value = fluentOptionEl.getAttribute('value');
}

if (['Enter'].includes(keyName)) {
if ('Enter' === keyName) {
if (value) {
item = this.response.filter(res => res.id === value).pop();
this.fireCustomEvent('selectionChanged', item, true, false, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export const setTodoTaskIncomplete = async (graph: IGraph, taskId: string, eTag:
export const setTodoTaskDetails = async (
graph: IGraph,
taskId: string,
task: any,
task: Partial<OutlookTask>,
eTag: string
): Promise<OutlookTask> =>
(await graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export class MgtTasks extends MgtTemplatedComponent {
*
* @param _changedProperties Map of changed properties with old values
*/
protected firstUpdated(changedProperties: PropertyValueMap<any>) {
protected firstUpdated(changedProperties: PropertyValueMap<unknown>) {
super.firstUpdated(changedProperties);

if (this.initialId && !this._currentGroup) {
Expand Down
24 changes: 12 additions & 12 deletions packages/mgt-components/src/components/mgt-tasks/task-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/* eslint-disable max-classes-per-file */

import { IGraph, BetaGraph } from '@microsoft/mgt-element';
import { PlannerAssignments } from '@microsoft/microsoft-graph-types';
import { PlannerAssignments, PlannerBucket, PlannerPlan } from '@microsoft/microsoft-graph-types';
import { OutlookTask, OutlookTaskFolder, OutlookTaskGroup, PlannerTask } from '@microsoft/microsoft-graph-types-beta';
import {
addPlannerTask,
Expand Down Expand Up @@ -137,7 +137,7 @@ export interface ITaskFolder {
* @type {*}
* @memberof ITaskFolder
*/
_raw?: any;
_raw?: PlannerBucket | OutlookTaskFolder;
}

/**
Expand Down Expand Up @@ -174,7 +174,7 @@ export interface ITaskGroup {
* @type {*}
* @memberof ITaskGroup
*/
_raw?: any;
_raw?: PlannerPlan | OutlookTaskGroup;

/**
* Plan Container ID. Same as the group ID of the group in the plan.
Expand Down Expand Up @@ -251,7 +251,7 @@ export interface ITaskSource {
* @returns {Promise<any>}
* @memberof ITaskSource
*/
setTaskIncomplete(task: ITask): Promise<any>;
setTaskIncomplete(task: ITask): Promise<void>;

/**
* Promise to add a new task
Expand All @@ -260,7 +260,7 @@ export interface ITaskSource {
* @returns {Promise<any>}
* @memberof ITaskSource
*/
addTask(newTask: ITask): Promise<any>;
addTask(newTask: ITask): Promise<PlannerTask | OutlookTask>;

/**
* assign id's to task
Expand All @@ -279,7 +279,7 @@ export interface ITaskSource {
* @returns {Promise<any>}
* @memberof ITaskSource
*/
removeTask(task: ITask): Promise<any>;
removeTask(task: ITask): Promise<void>;

/**
* assigns task to the current signed in user
Expand Down Expand Up @@ -435,7 +435,7 @@ export class PlannerTaskSource extends TaskSourceBase implements ITaskSource {
* @returns {Promise<any>}
* @memberof PlannerTaskSource
*/
public async addTask(newTask: ITask): Promise<any> {
public async addTask(newTask: ITask): Promise<PlannerTask> {
return await addPlannerTask(this.graph, {
assignments: newTask.assignments,
bucketId: newTask.immediateParentId,
Expand Down Expand Up @@ -576,8 +576,8 @@ export class TodoTaskSource extends TaskSourceBase implements ITaskSource {
* @returns {Promise<any>}
* @memberof TodoTaskSource
*/
public async setTaskComplete(task: ITask): Promise<any> {
return await setTodoTaskComplete(this.graph, task.id, task.eTag);
public async setTaskComplete(task: ITask): Promise<void> {
await setTodoTaskComplete(this.graph, task.id, task.eTag);
}

/**
Expand All @@ -588,7 +588,7 @@ export class TodoTaskSource extends TaskSourceBase implements ITaskSource {
* @returns {Promise<any>}
* @memberof PlannerTaskSource
*/
public async assignPeopleToTask(task: ITask, people: PlannerAssignments): Promise<any> {
public async assignPeopleToTask(task: ITask, people: PlannerAssignments): Promise<void> {
return await assignPeopleToPlannerTask(this.graph, task, people);
}
/**
Expand All @@ -598,8 +598,8 @@ export class TodoTaskSource extends TaskSourceBase implements ITaskSource {
* @returns {Promise<any>}
* @memberof TodoTaskSource
*/
public async setTaskIncomplete(task: ITask): Promise<any> {
return await setTodoTaskIncomplete(this.graph, task.id, task.eTag);
public async setTaskIncomplete(task: ITask): Promise<void> {
await setTodoTaskIncomplete(this.graph, task.id, task.eTag);
}
/**
* add new task to planner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import './mgt-theme-toggle';
class Deferred<T = unknown> {
promise: Promise<T>;
resolve: (value: T) => void;
reject: (reason?: any) => void;
reject: (reason?: unknown) => void;
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class MgtThemeToggle extends MgtBaseComponent {
* @param {Map<string, any>} changedProperties
* @memberof MgtDarkToggle
*/
updated(changedProperties: Map<string, any>): void {
updated(changedProperties: Map<string, unknown>): void {
if (changedProperties.has('darkModeActive')) {
this.applyTheme(this.darkModeActive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,28 @@ interface BinaryThumbnail {
/**
* Object representing a Search Answer
*/
type Answer = {
interface Answer {
'@odata.type': string;
displayName?: string;
description?: string;
webUrl?: string;
};
}

/**
* Object representing a search resource supporting thumbnails
*/
type ThumbnailResource = {
interface ThumbnailResource {
thumbnail: Thumbnail;
};
}

type UserResource = {
interface UserResource {
lastModifiedBy?: {
user?: {
email?: string;
};
};
userPrincipalName?: string;
};
}

/**
* Object representing a Search Resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ export class MgtArrowOptions extends MgtBaseComponent {
* @type {object}
* @memberof MgtArrowOptions
*/
@property({ type: Object }) public options: Record<string, (e: UIEvent) => unknown>;
@property({ type: Object }) public options: Record<string, (e: UIEvent) => void>;

private readonly _clickHandler: (e: UIEvent) => unknown;
private readonly _clickHandler: (e: UIEvent) => void;

constructor() {
super();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton);
/**
* Defines the event functions passed to the option item.
*/
type MenuOptionEventFunction = (e: Event) => any;
type MenuOptionEventFunction = (e: Event) => void;

/**
* Custom Component used to handle an arrow rendering for TaskGroups utilized in the task component.
Expand Down Expand Up @@ -62,7 +62,7 @@ export class MgtDotOptions extends MgtBaseComponent {
*
* @memberof MgtDotOptions
*/
@property({ type: Object }) public options: Record<string, (e: Event) => any>;
@property({ type: Object }) public options: Record<string, (e: Event) => void>;

private readonly _clickHandler = () => (this.open = false);

Expand Down Expand Up @@ -116,7 +116,7 @@ export class MgtDotOptions extends MgtBaseComponent {
* @returns
* @memberof MgtDotOptions
*/
public getMenuOption(name: string, clickFn: (e: Event) => any) {
public getMenuOption(name: string, clickFn: (e: Event) => void) {
return html`
<fluent-menu-item
@click=${(e: MouseEvent) => this.handleItemClick(e, clickFn)}
Expand Down
2 changes: 1 addition & 1 deletion packages/mgt-components/src/graph/graph.files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { blobToBase64 } from '../utils/Utils';
* @param session
* @returns
*/
export const isUploadSession = (session: any): session is UploadSession => {
export const isUploadSession = (session: unknown): session is UploadSession => {
return Array.isArray((session as UploadSession).nextExpectedRanges);
};

Expand Down
13 changes: 8 additions & 5 deletions packages/mgt-components/src/graph/graph.userWithPhoto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { CacheUser, getIsUsersCacheEnabled, getUserInvalidationTime } from './gr
import { IDynamicPerson } from './types';
import { schemas } from './cacheStores';
import { Photo } from '@microsoft/microsoft-graph-types';
import { isGraphError } from './isGraphError';

/**
* async promise, returns IDynamicPerson
Expand Down Expand Up @@ -74,11 +75,13 @@ export const getUserWithPhoto = async (
} else {
cachedPhoto = null;
}
} catch (e: any) {
// if 404 received (photo not found) but user already in cache, update timeCache value to prevent repeated 404 error / graph calls on each page refresh
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (e.code === 'ErrorItemNotFound' || e.code === 'ImageNotFound') {
await storePhotoInCache(userId || 'me', schemas.photos.stores.users, { eTag: null, photo: null });
} catch (e: unknown) {
if (isGraphError(e)) {
// if 404 received (photo not found) but user already in cache, update timeCache value to prevent repeated 404 error / graph calls on each page refresh
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (e.code === 'ErrorItemNotFound' || e.code === 'ImageNotFound') {
await storePhotoInCache(userId || 'me', schemas.photos.stores.users, { eTag: null, photo: null });
}
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions packages/mgt-components/src/graph/isGraphError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GraphError } from '@microsoft/microsoft-graph-client';

export const isGraphError = (e: unknown): e is GraphError => {
const test = e as GraphError;
return (
test.statusCode &&
'code' in test &&
'body' in test &&
test.date &&
'message' in test &&
'name' in test &&
'requestId' in test
);
};
Loading

0 comments on commit 3c284e4

Please sign in to comment.