Skip to content

Commit

Permalink
refactor(api)!: replace callbacks with promises
Browse files Browse the repository at this point in the history
  • Loading branch information
rbardini committed Jun 11, 2022
1 parent e505717 commit d7f3338
Show file tree
Hide file tree
Showing 18 changed files with 183 additions and 271 deletions.
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Options:
## API
### `track(numbers [, options], callback)`
### `track(numbers, options?): Promise<[items, failures]>`
Tracks a collection of tracking numbers.
Expand All @@ -57,9 +57,15 @@ Tracks a collection of tracking numbers.
- `options` (Object) - Optional tracking options:
- `checkDigit` (Boolean) - Whether to validate the tracking number check digit
- `onProgress(progress, item)` (Function) - Callback function called for each number once its data has been retrieved. `progress` is a float number between 0 and 1. `item` is the item object. Invalid tracking numbers are filtered before any requests are made, so they will not be passed here.
- `callback(err, items, failures)` (Function) - Callback function called once all tracking numbers have been processed, or when an error occurs. `items` is an array of item objects. `failures` is an array of objects containing the tracking numbers that did not pass validation.
### `validate(number [, options], callback)`
#### Return
`[items, failures]` (Array)
- `items` (Array) - Item objects.
- `failures` (Array) - Objects containing the tracking numbers that did not pass validation.
### `validate(number, options?): [passes, failures]`
Validates a collection of tracking numbers.
Expand All @@ -68,8 +74,10 @@ Validates a collection of tracking numbers.
- `numbers` (String|Array) - Tracking number or array of tracking numbers to be validated
- `options` (Object) - Optional tracking options:
- `checkDigit` (Boolean) - Whether to validate the tracking number check digit
- `callback(err, passes, failures)` (Function) - Callback function called once all numbers have been processed, or when an error occurs. `passes` is an array of objects containing the tracking numbers that passed validation. `failures` is an array of objects containing the tracking numbers that did not pass validation.
#### Return
True if all tracking numbers are valid, false otherwise.
`[passes, failures]` (Array)
- `passes` (Array) - Objects containing the tracking numbers that passed validation.
- `failures` (Array) - Objects containing the tracking numbers that did not pass validation.
9 changes: 3 additions & 6 deletions bin/sro.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,12 @@ const formatter =
formatters[program.opts().output.trim().toLowerCase()] || formatters.table
const options = {
checkDigit: program.opts().check,
onProgress: (progress, item) => console.log(formatter.format([item]))
}
const callback = (err, items, failures) => {
if (err) throw err
console.log(formatter.format(undefined, failures))
onProgress: (_progress, item) => console.log(formatter([item]))
}

if (numbers.length) {
track(numbers, options, callback)
const [, failures] = await track(numbers, options)
console.log(formatter(undefined, failures))
} else {
program.help()
}
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './src/sro.js'
export { default as track } from './src/track.js'
export { default as validate } from './src/validate.js'
export * as formatters from './src/formatters/index.js'
2 changes: 1 addition & 1 deletion src/formatters/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { default as table } from './table.js'
export { default as json } from './json.js'
export { default as pretty } from './pretty.js'
export { default as table } from './table.js'
24 changes: 10 additions & 14 deletions src/formatters/json.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
const JSONFormatter = {
format: (items = [], failures = []) => {
const formattedItems = items.reduce(
(result, item) => result + JSON.stringify(item),
''
)
const formattedFailures = failures.reduce(
(result, failure) => result + JSON.stringify(failure),
''
)
export default (items = [], failures = []) => {
const formattedItems = items.reduce(
(result, item) => result + JSON.stringify(item),
''
)
const formattedFailures = failures.reduce(
(result, failure) => result + JSON.stringify(failure),
''
)

return formattedItems + formattedFailures
}
return formattedItems + formattedFailures
}

export default JSONFormatter
24 changes: 10 additions & 14 deletions src/formatters/pretty.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
const PrettyFormatter = {
format: (items = [], failures = []) => {
const formattedItems = items.reduce(
(result, item) => result + JSON.stringify(item, null, 2),
''
)
const formattedFailures = failures.reduce(
(result, failure) => result + JSON.stringify(failure, null, 2),
''
)
export default (items = [], failures = []) => {
const formattedItems = items.reduce(
(result, item) => result + JSON.stringify(item, null, 2),
''
)
const formattedFailures = failures.reduce(
(result, failure) => result + JSON.stringify(failure, null, 2),
''
)

return formattedItems + formattedFailures
}
return formattedItems + formattedFailures
}

export default PrettyFormatter
77 changes: 34 additions & 43 deletions src/formatters/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,38 @@ import Table from 'cli-table'

const SYMBOLS = { pass: '✓', fail: '✖' }

const TableFormatter = {
format: (items = [], failures = []) => {
const formattedItems = items.reduce((result, item) => {
const header =
'\n ' +
chalk.bold(item.numero) +
'\n ' +
item.pais +
' via ' +
item.nome
const table = new Table({
head: ['Data', 'Local', 'Situação']
})

item.eventos.forEach(event => {
const data = new Date(event.data).toLocaleString()
const city = [event.cidade, event.uf].filter(Boolean).join('/')
let local = [event.local, city].filter(Boolean).join(' - ')
const descricao = event.descricao
const destino = event.destino

if (destino) {
local += `\nEm trânsito para ${destino.local} - ${destino.cidade}/${destino.uf}`
}

table.push([data, local, descricao])
})

return `${result}${header}\n${table.toString()}\n`
}, '')

const formattedFailures = failures.reduce(
(result, failure) =>
`${result}\n ${chalk.bold(failure.numero)}\n ${chalk.red(
`${SYMBOLS.fail} ${failure.error}\n`
)}`,
''
)

return formattedItems + formattedFailures
}
export default (items = [], failures = []) => {
const formattedItems = items.reduce((result, item) => {
const header =
'\n ' + chalk.bold(item.numero) + '\n ' + item.pais + ' via ' + item.nome
const table = new Table({
head: ['Data', 'Local', 'Situação']
})

item.eventos.forEach(event => {
const data = new Date(event.data).toLocaleString()
const city = [event.cidade, event.uf].filter(Boolean).join('/')
let local = [event.local, city].filter(Boolean).join(' - ')
const descricao = event.descricao
const destino = event.destino

if (destino) {
local += `\nEm trânsito para ${destino.local} - ${destino.cidade}/${destino.uf}`
}

table.push([data, local, descricao])
})

return `${result}${header}\n${table.toString()}\n`
}, '')

const formattedFailures = failures.reduce(
(result, failure) =>
`${result}\n ${chalk.bold(failure.numero)}\n ${chalk.red(
`${SYMBOLS.fail} ${failure.error}\n`
)}`,
''
)

return formattedItems + formattedFailures
}

export default TableFormatter
5 changes: 0 additions & 5 deletions src/sro.js

This file was deleted.

36 changes: 14 additions & 22 deletions src/utils/track.js → src/track.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
import normalizeItem from './normalizeItem.js'
import normalizeNumber from './normalizeNumber.js'
import apiRequest from './utils/apiRequest.js'
import normalizeItem from './utils/normalizeItem.js'
import normalizeNumber from './utils/normalizeNumber.js'
import validate from './validate.js'
import apiRequest from './apiRequest.js'

const track = (numbers, options = {}, callback = () => {}) => {
if (typeof options === 'function') {
callback = options
options = {}
}

export default async (numbers, options = {}) => {
if (!Array.isArray(numbers)) {
numbers = [numbers]
}

const items = []
const failures = []

numbers = numbers
.filter(number =>
validate(number, options, (err, pass, failure) => {
if (err) throw err
if (!pass.length) failures.push(failure[0])
})
)
.map(normalizeNumber)
numbers = await numbers.reduce(async (acc, number) => {
const [, failure] = await validate(number, options)
const hasFailure = failure.length !== 0

if (hasFailure) return failures.push(failure[0]) && acc
return (await acc).concat(normalizeNumber(number))
}, [])

let tracked = 0
const count = numbers.length
Expand All @@ -32,7 +26,7 @@ const track = (numbers, options = {}, callback = () => {}) => {
return acc[acc.length - 1].push(number) && acc
}, [])

Promise.all(
await Promise.all(
chunks.map(async chunk => {
const response = await apiRequest({ objetos: chunk })
const objetos = [response.objeto].flat().filter(Boolean)
Expand All @@ -47,8 +41,6 @@ const track = (numbers, options = {}, callback = () => {}) => {
})
})
)
.then(() => callback(null, items, failures))
.catch(err => callback(err))
}

export default track
return [items, failures]
}
9 changes: 2 additions & 7 deletions src/utils/apiRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ const buildEnvelope = ({ usuario, senha, tipo, resultado, lingua, objetos }) =>
<tipo>${tipo}</tipo>
<resultado>${resultado}</resultado>
<lingua>${lingua}</lingua>
${objetos.reduce(
(result, objeto) => `${result}<objetos>${objeto}</objetos>`,
''
)}
${objetos.map(objeto => `<objetos>${objeto}</objetos>`).join('')}
</res:buscaEventosLista>
</soap:Body>
</soap:Envelope>`

const apiRequest = async options => {
export default async options => {
const response = await fetch([REQUEST_HOST, REQUEST_PATH].join(''), {
method: 'POST',
headers: REQUEST_HEADERS,
Expand All @@ -53,5 +50,3 @@ const apiRequest = async options => {

return json.body.buscaeventoslistaresponse.return
}

export default apiRequest
4 changes: 1 addition & 3 deletions src/utils/checkDigit.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const WEIGHTS = [8, 6, 4, 2, 3, 5, 9, 7]

const checkDigit = number => {
export default number => {
const sum = WEIGHTS.reduce(
(sum, weight, i) => sum + number.charCodeAt(i + 2) * weight,
0
Expand All @@ -11,5 +11,3 @@ const checkDigit = number => {

return dv === +number.charAt(10)
}

export default checkDigit
4 changes: 1 addition & 3 deletions src/utils/normalizeEvent.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const normalizeEvent = ({ data, descricao, hora, ...restEvent }) => {
export default ({ data, descricao, hora, ...restEvent }) => {
const [day, month, year] = data.split('/')
const [hour, minute] = hora.split(':')

Expand All @@ -10,5 +10,3 @@ const normalizeEvent = ({ data, descricao, hora, ...restEvent }) => {
...restEvent
}
}

export default normalizeEvent
4 changes: 1 addition & 3 deletions src/utils/normalizeItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import normalizeEvent from './normalizeEvent.js'

const regionNames = new Intl.DisplayNames(['pt-BR'], { type: 'region' })

const normalizeItem = ({ evento, numero, ...restItem }) => {
export default ({ evento, numero, ...restItem }) => {
const countryCode = numero.slice(-2)

return {
Expand All @@ -12,5 +12,3 @@ const normalizeItem = ({ evento, numero, ...restItem }) => {
...restItem
}
}

export default normalizeItem
4 changes: 1 addition & 3 deletions src/utils/normalizeNumber.js
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
const normalizeNumber = number => number.trim().toUpperCase()

export default normalizeNumber
export default number => number.trim().toUpperCase()
16 changes: 4 additions & 12 deletions src/utils/validate.js → src/validate.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import normalizeNumber from './normalizeNumber.js'
import checkDigit from './checkDigit.js'

const validate = (numbers, options = {}, callback = () => {}) => {
if (typeof options === 'function') {
callback = options
options = {}
}
import checkDigit from './utils/checkDigit.js'
import normalizeNumber from './utils/normalizeNumber.js'

export default (numbers, options = {}) => {
if (!Array.isArray(numbers)) {
numbers = [numbers]
}
Expand Down Expand Up @@ -52,8 +47,5 @@ const validate = (numbers, options = {}, callback = () => {}) => {
passes.push(result)
})

callback(null, passes, failures)
return failures.length === 0
return [passes, failures]
}

export default validate
Loading

0 comments on commit d7f3338

Please sign in to comment.