Skip to content

Commit

Permalink
style: resolve eslint findings
Browse files Browse the repository at this point in the history
* Create eslint.yml to automate eslint findings in GitHub Actions

* style(eslint): resolved style related findings for eslint

* refactor(cli): changed while loops from constant true to dynamic booleans

CLI had while(true) loops which have a higher risk of infinate loop. Replaced with variables.

re: #54
  • Loading branch information
flamingquaks authored May 23, 2024
1 parent f4688d6 commit 8a62c84
Show file tree
Hide file tree
Showing 58 changed files with 750 additions and 1,027 deletions.
9 changes: 8 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ lib/user-interface/genai-newsletter-ui/src/graphql/*
lib/user-interface/genai-newsletter-ui/vite.config.ts
vite.config.ts
misc/
lib/api/functions/out/*
lib/api/functions/out/*
cdk.out/*
node_modules/
lib/api/functions/resolver/*/index.js
lib/api/functions/pipeline/*/index.js

scripts/*
pages/*
4 changes: 1 addition & 3 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
"node": true
},
"extends": [
"plugin:react/jsx-runtime",
"standard-with-typescript",
"plugin:react/recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# ESLint is a tool for identifying and reporting on patterns
# found in ECMAScript/JavaScript code.
# More details at https://github.com/eslint/eslint
# and https://eslint.org

name: ESLint

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '45 13 * * 4'

jobs:
eslint:
name: Run eslint scanning
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node Packages
run: npm install --save-dev
- name: Run ESLint
run: npx eslint . --config .eslintrc.json --ext .js,.jsx,.ts,.tsx --format @microsoft/eslint-formatter-sarif --output-file eslint-results.sarif --debug
continue-on-error: false

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: eslint-results.sarif
wait-for-processing: true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ lib/user-interface/genai-newsletter-ui/public/amplifyconfiguration.json
lib/user-interface/genai-newsletter-ui/.DS_Store
.DS_Store
lib/api/functions/out
pages/.vitepress/cache
pages/.vitepress/cache
eslint-results.sarif
2 changes: 1 addition & 1 deletion bin/genai-newsletter-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { GenAINewsletter } from '../lib'
import getConfig from '../lib/config'
import path from 'path'
import { AwsSolutionsChecks } from 'cdk-nag'
import { addNagSuppressions } from './cdk-nag-supressions'
import { addNagSuppressions } from '../lib/cdk-nag-supressions'

const app = new App()

Expand Down
15 changes: 12 additions & 3 deletions cli/config-manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,18 @@ if (['UPDATE', 'NEW'].includes(configStyle)) {
console.log(formatText('Requires a hostname & a pre-existing AWS Certificate Manager public cert ARN.' +
'For more information, visit https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html',
{ italic: true }))
while (true) {
let loopA = true
while (loopA) {
const response = prompter(
formatText('Do you want to proceed? (y/N):', { bold: true, textColor: 'blue' }),
'N'
)
if (response.toLowerCase() === 'y') {
configHostname = true
loopA = false
break
} else if (response.toLowerCase() === 'n') {
loopA = false
break
} else {
console.log(
Expand All @@ -316,7 +319,8 @@ if (['UPDATE', 'NEW'].includes(configStyle)) {
}
}
if (configHostname) {
while (true) {
let loopB = true
while (loopB) {
const existingHostname = ((config.ui?.hostName) != null) ? config.ui.hostName : ''
const response = prompter(
formatText(`Enter the hostname you want to use for the frontend:(${existingHostname})`, { textColor: 'blue' })
Expand All @@ -327,8 +331,10 @@ if (['UPDATE', 'NEW'].includes(configStyle)) {
config.ui = {}
}
config.ui.hostName = response
loopB = false
break
} else if (response.length < 1 && config.ui?.hostName !== undefined && config.ui.hostName !== null) {
loopB = false
break
} else {
console.log(
Expand All @@ -340,7 +346,8 @@ if (['UPDATE', 'NEW'].includes(configStyle)) {
)
}
}
while (true) {
let loopC = true
while (loopC) {
const existingAcmCert = ((config.ui?.acmCertificateArn) != null) ? config.ui.acmCertificateArn : ''
const response = prompter(
formatText(`Enter the ACM Certificate ARN you want to use for the frontend:(${existingAcmCert})`, { textColor: 'blue' })
Expand All @@ -351,8 +358,10 @@ if (['UPDATE', 'NEW'].includes(configStyle)) {
config.ui = {}
}
config.ui.acmCertificateArn = response
loopC = false
break
} else if (response.length < 1 && config.ui?.acmCertificateArn !== undefined && config.ui.acmCertificateArn !== null) {
loopC = false;
break
} else {
console.log(
Expand Down
8 changes: 0 additions & 8 deletions jest.config.ts

This file was deleted.

4 changes: 2 additions & 2 deletions lib/api/functions/resolver-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const convertFieldIdToObjectId = (obj: any, idFieldName: string): any =>
return obj
}
obj.id = obj[idFieldName]
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete obj[idFieldName]
return obj
}
Expand All @@ -73,7 +73,7 @@ export const convertFieldIdToObject = (obj: any, fieldIdName: string, objectName
__typename: objectName,
id: obj[fieldIdName]
}
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete obj[fieldIdName]
return obj
}
Expand Down
4 changes: 2 additions & 2 deletions lib/authorization/authorization-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ export const getEntityItem = (schema: Record<string, any>, entityId: string, ent
}
}
if (entityData !== undefined) {
item.attributes = getEntityAttributes(schema, entityType, entityData, { logger })
item.attributes = getEntityAttributes(schema, entityType, entityData)
}
return item
}

export const getEntityAttributes = (schema: Record<string, any>, entityType: string, entityData: Record<string, any>, optionals?: { logger?: Logger }): Record<string, AttributeValue> => {
export const getEntityAttributes = (schema: Record<string, any>, entityType: string, entityData: Record<string, any>): Record<string, AttributeValue> => {
const avpSchema = schema.GenAINewsletter
const entityAttributes: Record<string, AttributeValue> = {}
if (avpSchema !== undefined && avpSchema.entityTypes !== undefined) {
Expand Down
5 changes: 2 additions & 3 deletions lib/authorization/index.action-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { Logger, injectLambdaContext } from '@aws-lambda-powertools/logger'
import { MetricUnits, Metrics } from '@aws-lambda-powertools/metrics'
import { CognitoJwtVerifier } from 'aws-jwt-verify'
import { CognitoIdentityProviderClient, GetUserCommand, type GetUserCommandInput } from '@aws-sdk/client-cognito-identity-provider' // ES Modules import
import middy from '@middy/core'
import { type Context } from 'aws-lambda'
import middy from '@middy/core'
import { GetSchemaCommand, VerifiedPermissionsClient, type IsAuthorizedCommandInput, IsAuthorizedCommand, Decision } from '@aws-sdk/client-verifiedpermissions'
import { queryToActionAuth } from './authorization-helper'

Expand Down Expand Up @@ -45,7 +44,7 @@ const cognitoIdp = tracer.captureAWSv3Client(new CognitoIdentityProviderClient()

let schema: Record<string, unknown>

const lambdaHandler = async (event: any, context: Context): Promise<any> => {
const lambdaHandler = async (event: any): Promise<any> => {
logger.debug('AuthorizationCheckEventTriggered', { event })
if (schema === undefined || schema === null || Object.keys(schema).length === 0) {
logger.debug('AVP Schema not yet cached. Retrieving AVP Schema')
Expand Down
3 changes: 1 addition & 2 deletions lib/authorization/index.list-filter-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { Logger, injectLambdaContext } from '@aws-lambda-powertools/logger'
import { MetricUnits, Metrics } from '@aws-lambda-powertools/metrics'

import middy from '@middy/core'
import { type Context } from 'aws-lambda'
import { GetSchemaCommand, VerifiedPermissionsClient, type IsAuthorizedCommandInput, IsAuthorizedCommand, Decision } from '@aws-sdk/client-verifiedpermissions'
import { getEntityItem, lowercaseFirstLetter, queryToActionAuth, queryToResourcesEntity } from './authorization-helper'

Expand All @@ -29,7 +28,7 @@ const verifiedpermissions = tracer.captureAWSv3Client(new VerifiedPermissionsCli

let schema: Record<string, unknown>

const lambdaHandler = async (event: any, context: Context): Promise<any> => {
const lambdaHandler = async (event: any): Promise<any> => {
logger.debug('FilterAuthorizationCheckEventTriggered', { event })
const { userId, accountId } = event
if (schema === undefined || schema === null || Object.keys(schema).length === 0) {
Expand Down
3 changes: 1 addition & 2 deletions lib/authorization/index.read-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { MetricUnits, Metrics } from '@aws-lambda-powertools/metrics'

// import { getEntityItem } from '../shared/api/schema-to-avp/permission-map'
import middy from '@middy/core'
import { type Context } from 'aws-lambda'
import { GetSchemaCommand, VerifiedPermissionsClient, type IsAuthorizedCommandInput, IsAuthorizedCommand, Decision } from '@aws-sdk/client-verifiedpermissions'
import { getEntityItem, lowercaseFirstLetter, queryToActionAuth, queryToResourceEntity } from './authorization-helper'

Expand All @@ -30,7 +29,7 @@ const verifiedpermissions = tracer.captureAWSv3Client(new VerifiedPermissionsCli

let schema: Record<string, unknown>

const lambdaHandler = async (event: any, context: Context): Promise<any> => {
const lambdaHandler = async (event: any): Promise<any> => {
logger.debug('AuthorizationCheckEventTriggered', { event })
const root = event.root as string | undefined
const contingentAction = event.contingentAction as string | undefined
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/data-feed-ingestion/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: MIT-0
*/
/* eslint-disable @typescript-eslint/no-extraneous-class */
export class ArticleIngestorPromptConfiguration {
private static readonly BASE_PROMPT =
'\n\nHuman: ' +
Expand Down
5 changes: 2 additions & 3 deletions lib/newsletter-generator/index.newsletter-campaign-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const lambdaHandler = async (
? await getEmailBodiesFromS3(emailKey)
: await getEmailBodiesFromS3(await getEmailKey(newsletterId, emailId))
await createEmailTemplate(emailId, html, text, title)
const campaignId = await createEmailCampaign(emailId, title)
const campaignId = await createEmailCampaign(emailId)
await saveCampaignId(newsletterId, emailId, campaignId)
}

Expand Down Expand Up @@ -196,8 +196,7 @@ const createEmailTemplate = async (
}

const createEmailCampaign = async (
emailId: string,
newsletterTitle: string
emailId: string
): Promise<string> => {
logger.debug('Creating email campaign', { emailId })
const input: CreateCampaignCommandInput = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ interface PinpointCampaignHookInput {
}

const lambdaHandler = async (
event: PinpointCampaignHookInput,
context: any
event: PinpointCampaignHookInput
): Promise<any> => {
logger.debug('Filter event called.', { event })
const newsletterId = await getNewsletterForCampaign(event.CampaignId)
Expand Down
2 changes: 1 addition & 1 deletion lib/shared/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable */
export type Maybe<T> = T | null
export type InputMaybe<T> = Maybe<T>
export type Exact<T extends { [key: string]: unknown }> = {
Expand Down
2 changes: 1 addition & 1 deletion lib/user-interface/genai-newsletter-ui/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import DataFeedDetails from './pages/data-feeds/detail'
import MyNewsletters from './pages/newsletters/my-newsletters'
import MyNewsletterSubscriptions from './pages/newsletters/my-subscriptions'
import EditDataFeed from './pages/data-feeds/edit'
function App() {
function App () {
return (
<div style={{ height: '100%' }}>
<BrowserRouter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ const THEME_STORAGE_NAME = `${PREFIX}-theme`
const NAVIGATION_PANEL_STATE_STORAGE_NAME = `${PREFIX}-navigation-panel-state`

export abstract class StorageHelper {
static getTheme() {
static getTheme () {
const value = localStorage.getItem(THEME_STORAGE_NAME) ?? Mode.Light
const theme = value === Mode.Dark ? Mode.Dark : Mode.Light

return theme
}

static applyTheme(theme: Mode) {
static applyTheme (theme: Mode) {
localStorage.setItem(THEME_STORAGE_NAME, theme)
applyMode(theme)

Expand All @@ -30,7 +30,7 @@ export abstract class StorageHelper {
return theme
}

static getNavigationPanelState(): NavigationPanelState {
static getNavigationPanelState (): NavigationPanelState {
const value =
localStorage.getItem(NAVIGATION_PANEL_STATE_STORAGE_NAME) ??
JSON.stringify({
Expand All @@ -47,7 +47,7 @@ export abstract class StorageHelper {
return state ?? {}
}

static setNavigationPanelState(state: Partial<NavigationPanelState>) {
static setNavigationPanelState (state: Partial<NavigationPanelState>) {
const currentState = this.getNavigationPanelState()
const newState = { ...currentState, ...state }
const stateStr = JSON.stringify(newState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useState } from 'react'
import { StorageHelper } from '../helpers/storage-helper'
import { NavigationPanelState } from '../types'

export function useNavigationPanelState(): [
export function useNavigationPanelState (): [
NavigationPanelState,
(state: Partial<NavigationPanelState>) => void
] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface FollowDetail {
href?: string
}

export default function useOnFollow() {
export default function useOnFollow () {
const navigate = useNavigate()

return useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Authenticator from './auth/custom-authenticator'
import { StorageHelper } from '../common/helpers/storage-helper'
import { Mode } from '@cloudscape-design/global-styles'

export default function AppConfigured() {
export default function AppConfigured () {
const [config, setConfig] = useState<AppConfig | null>(null)
const [error, setError] = useState<boolean | null>(null)
const [theme, setTheme] = useState(StorageHelper.getTheme());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import { useCallback, useContext, useState } from 'react'
import { AppContext } from '../../common/app-context'

export function DefaultAuthenticator() {
export function DefaultAuthenticator () {
const [username, setUsername] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [loading, setLoading] = useState<boolean>(false)
Expand Down Expand Up @@ -208,7 +208,7 @@ export function DefaultAuthenticator() {
)
}

export function CustomAuthenticator() {
export function CustomAuthenticator () {
const appContext = useContext(AppContext)
const handleFederateClick = () => {
let provider = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from './authenticator-views'
import { Container, SpaceBetween, Spinner } from '@cloudscape-design/components'

export default function Authenticator(props: PropsWithChildren) {
export default function Authenticator (props: PropsWithChildren) {
const appContext = useContext(AppContext)
const [isLoading, setIsLoading] = useState<boolean>(true)
const [userId, setUserId] = useState(userContextDefault.userId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AppLayout, AppLayoutProps } from '@cloudscape-design/components'
import NavigationPanel from './navigation-panel'
import { useNavigationPanelState } from '../common/hooks/use-navigation-panel-state'

export default function BaseAppLayout(props: AppLayoutProps) {
export default function BaseAppLayout (props: AppLayoutProps) {
const [navigationPanelState, setNavigationPanelState] =
useNavigationPanelState()
return (
Expand Down
Loading

0 comments on commit 8a62c84

Please sign in to comment.