--- Lua client for the public CEP API at [cep.is](https://cep.is). -- -- Quick use — for a script, the module-level functions are enough: -- -- local cepis = require("cepis") -- -- local address, err = cepis.lookup("01001-000") -- print(address.localidade, address.uf) --> São Paulo SP -- -- In an application — build a client once and reuse it: -- -- local client = cepis.new({ timeout = 5, total_timeout = 15 }) -- local address, err = client:lookup("01001000") -- -- Pointing at a local instance (the API repo brings one up with `just up`): -- -- local client = cepis.new({ base_url = "http://localhost:8080" }) -- -- Expected failures are returned, never thrown, and every error carries a -- `kind` so the caller branches on one string instead of matching messages: -- -- local address, err = cepis.lookup(cep_from_form) -- if not address then -- if err.kind == cepis.NOT_FOUND then -- -- the CEP does not exist: ask the user for another -- elseif err:is_retriable() then -- -- network, server, rate limit: reschedule -- end -- end -- -- `error()` is reserved for programmer mistakes — a bad option table, a wrong -- argument type. Those are bugs to fix, not conditions to handle. -- -- Note on field names: the API surface is English, but the **data fields keep -- the API's own Portuguese names** (`logradouro`, `bairro`, `localidade`). -- What you read in the JSON is what you index on the table. -- -- The module-level functions share one default client, built on first use. -- It applies process-wide, including to any other library that also requires -- this module. Anyone needing different settings should build their own. -- -- @module cepis local client = require("cepis.client") local errors = require("cepis.errors") local models = require("cepis.models") local M = {} --- Library version. M._VERSION = client.VERSION --- Where the API lives unless `base_url` says otherwise: `https://cep.is`. M.DEFAULT_URL = client.DEFAULT_URL --- How many CEPs the batch endpoint accepts in one request: `500`. M.MAX_BATCH = client.MAX_BATCH --- The `Client` class. `cepis.new` is the shorthand for `Client.new`. M.Client = client.Client --- The `Address` metatable, for `getmetatable(x) == cepis.Address`. M.Address = models.Address --- The `Geo` metatable. M.Geo = models.Geo --- The `Health` metatable. M.Health = models.Health --- Error kind: the CEP is not 8 digits. No request was made. M.INVALID_CEP = errors.INVALID_CEP --- Error kind: well-formed, but absent from the DNE database. M.NOT_FOUND = errors.NOT_FOUND --- Error kind: 429 on every attempt. `err.retry_after` may hold seconds. M.RATE_LIMITED = errors.RATE_LIMITED --- Error kind: 5xx on every attempt. `err.status` holds the last one seen. M.SERVER_ERROR = errors.SERVER_ERROR --- Error kind: the request never completed — DNS, connection, timeout, TLS. M.NETWORK_ERROR = errors.NETWORK_ERROR --- Error kind: a success status with a body that cannot be parsed. M.INVALID_RESPONSE = errors.INVALID_RESPONSE --- Every error kind, keyed by itself. M.kinds = errors.kinds --- Whether a value is one of this library's errors. -- @param value anything -- @treturn boolean M.is_error = errors.is --- Build a client. See `cepis.client.Client.new` for every option. -- @tparam[opt] table opts -- @treturn Client M.new = client.Client.new --- Return the CEP's 8 digits, accepting the mask. -- @tparam string value -- @treturn[1] string -- @treturn[2] nil -- @treturn[2] table the error M.normalize_cep = client.normalize_cep local default --- The shared client behind the module-level functions. -- -- Built on first use with every default. Do not mutate it: it applies -- process-wide. -- @treturn Client function M.default() if not default then default = client.Client.new() end return default end --- Look up a CEP using the default configuration. -- -- Shorthand for `cepis.default():lookup(cep)`. -- @tparam string cep masked or unmasked -- @treturn[1] Address -- @treturn[2] nil -- @treturn[2] table the error function M.lookup(cep) return M.default():lookup(cep) end --- Look up many CEPs in one batch, using the default configuration. -- -- Shorthand for `cepis.default():lookup_many(ceps)` — read that one, in -- particular why a missing CEP is `false` and not `nil`, and the warning that -- batches carry no coordinate. -- @tparam table ceps list of strings -- @treturn[1] table list of `Address|false` -- @treturn[2] nil -- @treturn[2] table the error function M.lookup_many(ceps) return M.default():lookup_many(ceps) end --- Query the API's health using the default configuration. -- -- Shorthand for `cepis.default():health()`. -- @treturn[1] Health -- @treturn[2] nil -- @treturn[2] table the error function M.health() return M.default():health() end return M