feat: auth backend (#111)
* refactor(types): extract inline anonymous types into named classes
Problem: several functions used inline `{...}` table types in their
`@param` and `@return` annotations, making them hard to read and
impossible to reference from other modules.
Solution: extract each into a named `---@class`: `pending.Metadata`,
`pending.TaskFields`, `pending.CompletionItem`, `pending.SystemResult`,
and `pending.OAuthClientOpts`.
* refactor(sync): extract shared utilities into `sync/util.lua`
Problem: sync epilogue code (`s:save()`, `_recompute_counts()`,
`buffer.render()`) and `fmt_counts` were duplicated across `gcal.lua`
and `gtasks.lua`. The concurrency guard lived in `oauth.lua`, coupling
non-OAuth backends to the OAuth module.
Solution: create `sync/util.lua` with `async`, `system`, `with_guard`,
`finish`, and `fmt_counts`. Delegate from `oauth.lua` and replace
duplicated code in both backends. Add per-backend `auth()` and
`auth_complete()` methods to `gcal.lua` and `gtasks.lua`.
* feat(sync): auto-discover backends, per-backend auth, S3 backend
Problem: sync backends were hardcoded in `SYNC_BACKENDS` list in
`init.lua`, auth routed directly through `oauth.google_client`, and
adding a non-OAuth backend required editing multiple files.
Solution: replace hardcoded list with `discover_backends()` that globs
`lua/pending/sync/*.lua` at runtime. Rewrite `M.auth()` to dispatch
to per-backend `auth()` methods with `vim.ui.select` fallback. Add
`lua/pending/sync/s3.lua` with push/pull/sync via AWS CLI, per-task
merge by `_s3_sync_id` (UUID), and `pending.S3Config` type.
This commit is contained in:
parent
ac02526cf1
commit
fe4c1d0e31
13 changed files with 1173 additions and 107 deletions
|
|
@ -1,6 +1,7 @@
|
|||
local config = require('pending.config')
|
||||
local log = require('pending.log')
|
||||
local oauth = require('pending.sync.oauth')
|
||||
local util = require('pending.sync.util')
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -154,21 +155,6 @@ local function unlink_remote(task, extra, now_ts)
|
|||
task.modified = now_ts
|
||||
end
|
||||
|
||||
---@param parts {[1]: integer, [2]: string}[]
|
||||
---@return string
|
||||
local function fmt_counts(parts)
|
||||
local items = {}
|
||||
for _, p in ipairs(parts) do
|
||||
if p[1] > 0 then
|
||||
table.insert(items, p[1] .. ' ' .. p[2])
|
||||
end
|
||||
end
|
||||
if #items == 0 then
|
||||
return 'nothing to do'
|
||||
end
|
||||
return table.concat(items, ' | ')
|
||||
end
|
||||
|
||||
function M.push()
|
||||
oauth.with_token(oauth.google_client, 'gcal', function(access_token)
|
||||
local calendars, cal_err = get_all_calendars(access_token)
|
||||
|
|
@ -246,13 +232,8 @@ function M.push()
|
|||
end
|
||||
end
|
||||
|
||||
s:save()
|
||||
require('pending')._recompute_counts()
|
||||
local buffer = require('pending.buffer')
|
||||
if buffer.bufnr() and vim.api.nvim_buf_is_valid(buffer.bufnr()) then
|
||||
buffer.render(buffer.bufnr())
|
||||
end
|
||||
log.info('gcal push: ' .. fmt_counts({
|
||||
util.finish(s)
|
||||
log.info('gcal push: ' .. util.fmt_counts({
|
||||
{ created, 'added' },
|
||||
{ updated, 'updated' },
|
||||
{ deleted, 'removed' },
|
||||
|
|
@ -261,6 +242,32 @@ function M.push()
|
|||
end)
|
||||
end
|
||||
|
||||
---@param args? string
|
||||
---@return nil
|
||||
function M.auth(args)
|
||||
if args == 'clear' then
|
||||
oauth.google_client:clear_tokens()
|
||||
log.info('gcal: OAuth tokens cleared — run :Pending auth gcal to re-authenticate.')
|
||||
elseif args == 'reset' then
|
||||
oauth.google_client:_wipe()
|
||||
log.info(
|
||||
'gcal: OAuth tokens and credentials cleared — run :Pending auth gcal to set up from scratch.'
|
||||
)
|
||||
else
|
||||
local creds = oauth.google_client:resolve_credentials()
|
||||
if creds.client_id == oauth.BUNDLED_CLIENT_ID then
|
||||
oauth.google_client:setup()
|
||||
else
|
||||
oauth.google_client:auth()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@return string[]
|
||||
function M.auth_complete()
|
||||
return { 'clear', 'reset' }
|
||||
end
|
||||
|
||||
---@return nil
|
||||
function M.health()
|
||||
oauth.health(M.name)
|
||||
|
|
@ -268,7 +275,7 @@ function M.health()
|
|||
if tokens and tokens.refresh_token then
|
||||
vim.health.ok('gcal tokens found')
|
||||
else
|
||||
vim.health.info('no gcal tokens — run :Pending auth')
|
||||
vim.health.info('no gcal tokens — run :Pending auth gcal')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue