Skip to content

Commit

Permalink
feat: support fuzzy-search, refactor code structure ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
Avivbens committed Jun 7, 2024
1 parent 106b74e commit 4fcb431
Show file tree
Hide file tree
Showing 11 changed files with 596 additions and 161 deletions.
600 changes: 512 additions & 88 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"dependencies": {
"fast-alfred": "^1.3.3",
"fuse.js": "^7.0.0",
"libphonenumber-js": "^1.11.2",
"node-mac-contacts": "^1.7.2"
},
Expand Down Expand Up @@ -81,4 +82,4 @@
"publishConfig": {
"registry": "https://registry.npmjs.org/"
}
}
}
2 changes: 1 addition & 1 deletion src/main/clear-cache.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastAlfred } from 'fast-alfred'
import { CACHE_CONTACTS_KEY } from '../common/constants.js'
import { CACHE_CONTACTS_KEY } from '@common/constants.js'

;(() => {
const alfredClient = new FastAlfred()
Expand Down
36 changes: 20 additions & 16 deletions src/main/contacts.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { AlfredScriptFilter } from 'fast-alfred'
import { FastAlfred } from 'fast-alfred'
import type { CountryCode } from 'libphonenumber-js'
import { DEFAULT_MAX_RESULTS_COUNT } from '../common/constants.js'
import { Variables } from '../common/variables.js'
import type { ContactPayload } from '../models/contact-payload.model.js'
import type { IContact } from '../models/contact.model.js'
import { searchContacts } from '../services/search-contacts.service.js'
import { DEFAULT_MAX_RESULTS_COUNT } from '@common/constants.js'
import { Variables } from '@common/variables.js'
import type { ContactPayload } from '@models/contact-payload.model.js'
import type { IContact } from '@models/contact.model.js'
import { getContacts } from '@services/contacts.service.js'
import { searchContacts } from '@services/search.service.js'

;(() => {
const alfredClient = new FastAlfred()

const data: IContact[] = searchContacts(alfredClient)
const countryCode: CountryCode = alfredClient.env.getEnv<CountryCode>(Variables.COUNTRY_CODE, {
defaultValue: 'US',
})
Expand All @@ -20,17 +20,21 @@ import { searchContacts } from '../services/search-contacts.service.js'
parser: Number,
})

const items: AlfredScriptFilter['items'] = data.map(({ firstName, lastName, phoneNumbers }: IContact) => {
const payload: ContactPayload = { phoneNumber: phoneNumbers[0], countryCode }
const contacts: IContact[] = getContacts(alfredClient)

return {
title: `${firstName} ${lastName}`,
subtitle: `Phone: ${phoneNumbers[0]}`,
arg: JSON.stringify(payload),
}
})
const filteredContacts = searchContacts(contacts, alfredClient.input, sliceAmount)

const items: AlfredScriptFilter['items'] = filteredContacts.map(
({ firstName, lastName, phoneNumbers }: IContact) => {
const payload: ContactPayload = { phoneNumber: phoneNumbers[0], countryCode }

const sliced = items.slice(0, sliceAmount)
return {
title: `${firstName} ${lastName}`,
subtitle: `Phone: ${phoneNumbers[0]}`,
arg: JSON.stringify(payload),
}
},
)

alfredClient.output({ items: sliced })
alfredClient.output({ items })
})()
2 changes: 1 addition & 1 deletion src/main/open-whatsapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { PhoneNumber } from 'libphonenumber-js'
import { parsePhoneNumber } from 'libphonenumber-js'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import type { ContactPayload } from '../models/contact-payload.model.js'
import type { ContactPayload } from '@models/contact-payload.model.js'

const execPrm = promisify(exec)

Expand Down
34 changes: 34 additions & 0 deletions src/services/contacts.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { FastAlfred } from 'fast-alfred'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import contacts from 'node-mac-contacts'
import { CACHE_CONTACTS_KEY, CACHE_TTL } from '@common/constants.js'
import { AuthStatus } from '@models/auth-status.enum.js'
import type { IContact } from '@models/contact.model.js'

export function isAuth(): boolean {
const status: AuthStatus = contacts.getAuthStatus()
return status === AuthStatus.Authorized
}

export function requestAuth(): void {
contacts.requestAccess()
}

export function getContacts(alfredClient: FastAlfred): IContact[] {
const isHasAccess: boolean = isAuth()
if (!isHasAccess) {
requestAuth()
return []
}

const cacheContacts: IContact[] = alfredClient.cache.get(CACHE_CONTACTS_KEY) ?? contacts.getAllContacts()
if (cacheContacts) {
return cacheContacts
}

const fetchedContacts = contacts.getAllContacts()
alfredClient.cache.setWithTTL(CACHE_CONTACTS_KEY, fetchedContacts, { maxAge: CACHE_TTL })

return fetchedContacts
}
3 changes: 0 additions & 3 deletions src/services/search-contacts.config.ts

This file was deleted.

50 changes: 0 additions & 50 deletions src/services/search-contacts.service.ts

This file was deleted.

4 changes: 4 additions & 0 deletions src/services/search.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { IContact } from '@models/contact.model.js'

type SearchField = keyof IContact
export const SEARCH_FIELDS_CONFIG: SearchField[] = ['firstName', 'lastName', 'phoneNumbers']
16 changes: 16 additions & 0 deletions src/services/search.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Fuse from 'fuse.js'
import type { IContact } from '@models/contact.model.js'
import { SEARCH_FIELDS_CONFIG } from './search.config.js'

export function searchContacts(contacts: IContact[], searchTerm: string, limit: number): IContact[] {
const fuse = new Fuse(contacts, {
keys: SEARCH_FIELDS_CONFIG,
isCaseSensitive: false,
shouldSort: true,
threshold: 0.4,
})

const res = fuse.search(searchTerm, { limit })

return res.map((item) => item.item)
}
7 changes: 6 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
"strictNullChecks": true,
"strictPropertyInitialization": false,
"target": "ES2021",
"useUnknownInCatchVariables": false
"useUnknownInCatchVariables": false,
"paths": {
"@services/*": ["src/services/*"],
"@common/*": ["src/common/*"],
"@models/*": ["src/models/*"]
}
},
"exclude": ["node_modules", ".eslintrc.cjs"],
"include": ["src/**/*"]
Expand Down

0 comments on commit 4fcb431

Please sign in to comment.