Skip to content

Commit

Permalink
make it better
Browse files Browse the repository at this point in the history
see the linked issue/pr for more information on motivation
  • Loading branch information
Le0Developer committed Aug 26, 2023
1 parent 4f5c28d commit a153850
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 80 deletions.
63 changes: 63 additions & 0 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { detectors } from './detectors'
import { sources } from './sources'
import { BotdError, BotDetectionResult, BotKind, Component, ComponentDict, DetectionDict, State } from './types'

export function detect(components: ComponentDict): [DetectionDict, BotDetectionResult] {
const detections = {} as DetectionDict
let finalDetection: BotDetectionResult = {
bot: false,
}

for (const detectorName in detectors) {
const detector = detectors[detectorName as keyof typeof detectors]
const detectorRes = detector(components)

let detection: BotDetectionResult = { bot: false }

if (typeof detectorRes === 'string') {
detection = { bot: true, botKind: detectorRes }
} else if (detectorRes) {
detection = { bot: true, botKind: BotKind.Unknown }
}

detections[detectorName as keyof typeof detectors] = detection

if (detection.bot) {
finalDetection = detection
}
}

return [detections, finalDetection]
}

export async function collect(): Promise<ComponentDict> {
const components = {} as ComponentDict
const sourcesKeys = Object.keys(sources) as (keyof typeof sources)[]

await Promise.all(
sourcesKeys.map(async (sourceKey) => {
const res = sources[sourceKey]

try {
components[sourceKey] = ({
value: await res(),
state: State.Success,
} as Component<any>) as any
} catch (error) {
if (error instanceof BotdError) {
components[sourceKey] = {
state: error.state,
error: `${error.name}: ${error.message}`,
}
} else {
components[sourceKey] = {
state: State.UnexpectedBehaviour,
error: error instanceof Error ? `${error.name}: ${error.message}` : String(error),
}
}
}
}),
)

return components
}
84 changes: 4 additions & 80 deletions src/detector.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { detectors } from './detectors'
import { sources } from './sources'
import {
BotdError,
BotDetectionResult,
BotDetectorInterface,
BotKind,
Component,
ComponentDict,
DetectionDict,
State,
} from './types'
import { BotDetectionResult, BotDetectorInterface, ComponentDict, DetectionDict } from './types'
import { collect, detect } from './api'

/**
* Class representing a bot detector.
Expand All @@ -30,16 +20,6 @@ export default class BotDetector implements BotDetectorInterface {
return this.detections
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
protected getSources() {
return sources
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
protected getDetectors() {
return detectors
}

/**
* @inheritdoc
*/
Expand All @@ -48,73 +28,17 @@ export default class BotDetector implements BotDetectorInterface {
throw new Error("BotDetector.detect can't be called before BotDetector.collect")
}

const components = this.components
const detectors = this.getDetectors()

const detections = {} as DetectionDict
let finalDetection: BotDetectionResult = {
bot: false,
}

for (const detectorName in detectors) {
const detector = detectors[detectorName as keyof typeof detectors]
const detectorRes = detector(components)

let detection: BotDetectionResult = { bot: false }

if (typeof detectorRes === 'string') {
detection = { bot: true, botKind: detectorRes }
} else if (detectorRes) {
detection = { bot: true, botKind: BotKind.Unknown }
}

detections[detectorName as keyof typeof detectors] = detection

if (detection.bot) {
finalDetection = detection
}
}
const [detections, finalDetection] = detect(this.components)

this.detections = detections

return finalDetection
}

/**
* @inheritdoc
*/
public async collect(): Promise<ComponentDict> {
const sources = this.getSources()
const components = {} as ComponentDict

const sourcesKeys = Object.keys(sources) as (keyof typeof sources)[]

await Promise.all(
sourcesKeys.map(async (sourceKey) => {
const res = sources[sourceKey]

try {
components[sourceKey] = ({
value: await res(),
state: State.Success,
} as Component<any>) as any
} catch (error) {
if (error instanceof BotdError) {
components[sourceKey] = {
state: error.state,
error: `${error.name}: ${error.message}`,
}
} else {
components[sourceKey] = {
state: State.UnexpectedBehaviour,
error: error instanceof Error ? `${error.name}: ${error.message}` : String(error),
}
}
}
}),
)

this.components = components
this.components = await collect()
return this.components
}
}
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { version } from '../package.json'
import BotDetector from './detector'
import { sources, WindowSizePayload, ProcessPayload, DistinctivePropertiesPayload } from './sources'
import { detectors } from './detectors'
import { BotdError, BotDetectorInterface, BotKind, BotDetectionResult } from './types'
import { collect, detect } from './api'

/**
* Options for BotD loading
Expand Down Expand Up @@ -48,6 +50,9 @@ export default { load }
/** Not documented, out of Semantic Versioning, usage is at your own risk */
export {
sources,
detectors,
collect,
detect,
BotdError,
WindowSizePayload,
ProcessPayload,
Expand Down

0 comments on commit a153850

Please sign in to comment.