lex-todoist 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 05ad4a771103ebab7a98c3bf7461f13be1b8d1f701d05053136d9222dcc261b5
4
+ data.tar.gz: d647c920597aeb280e07fbe7067194e8ff282b40c519cde6ff5cb63b91607f31
5
+ SHA512:
6
+ metadata.gz: e94d91e72560097d1349577c0e7203c51bc937d808c64e2d398a1b9d64d16fc017957bd231698f4d722000ead2ab3e400be6693921840b0ee63177637d7d6d23
7
+ data.tar.gz: 27d90aeb7b97773b6f795613879ab941aee8303e9b2eac7c35e8b3632594a2236ad4b242662dbf6fbf515094438573bda66ae5c1489bfbc18f507660c9fdc562
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,53 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
6
+ Layout/LineLength:
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
16
+ Metrics/MethodLength:
17
+ Max: 50
18
+
19
+ Metrics/ClassLength:
20
+ Max: 1500
21
+
22
+ Metrics/ModuleLength:
23
+ Max: 1500
24
+
25
+ Metrics/BlockLength:
26
+ Max: 40
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
30
+ Metrics/ParameterLists:
31
+ Max: 10
32
+
33
+ Metrics/AbcSize:
34
+ Max: 60
35
+
36
+ Metrics/CyclomaticComplexity:
37
+ Max: 15
38
+
39
+ Metrics/PerceivedComplexity:
40
+ Max: 17
41
+
42
+ Style/Documentation:
43
+ Enabled: false
44
+
45
+ Style/SymbolArray:
46
+ Enabled: true
47
+
48
+ Style/FrozenStringLiteralComment:
49
+ Enabled: true
50
+ EnforcedStyle: always
51
+
52
+ Naming/FileName:
53
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## [0.2.1] - 2026-03-22
4
+
5
+ ### Changed
6
+ - Add legion-logging, legion-settings, legion-json, legion-cache, legion-crypt, legion-data, and legion-transport as runtime dependencies
7
+ - Update spec_helper with real sub-gem helper stubs
8
+
9
+ ## [0.2.0] - 2026-03-15
10
+
11
+ ### Added
12
+ - Implemented `Helpers::Client#connection` using Faraday with Bearer token auth against Todoist REST API v2
13
+ - Implemented `Runners::Projects`: list_projects, get_project, create_project, update_project, delete_project, collaborators
14
+ - Implemented `Runners::Tasks`: create_task, get_task, list_tasks, update_task, close_task, reopen_task, delete_task
15
+ - Implemented `Runners::Sections`: list_sections, get_section, create_section, update_section, delete_section
16
+ - Implemented `Runners::Labels`: list_labels, get_label, create_label, update_label, delete_label
17
+ - Implemented `Runners::Comments`: get_comments, create_comment, update_comment, delete_comment
18
+ - Added standalone `Client` class that includes all runner modules for use outside the Legion runtime
19
+ - Added `faraday >= 2.0` runtime dependency to gemspec
20
+ - Added client spec covering project, task, label, and comment operations
21
+
22
+ ## [0.1.0] - 2026-03-13
23
+
24
+ ### Added
25
+ - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,61 @@
1
+ # lex-todoist: Todoist Integration for LegionIO
2
+
3
+ **Repository Level 3 Documentation**
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-other/CLAUDE.md`
5
+ - **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Legion Extension that connects LegionIO to the Todoist task management service. Provides runner modules for managing projects, tasks, sections, labels, and comments via the Todoist REST API.
10
+
11
+ **Version**: 0.2.0
12
+ **GitHub**: https://github.com/LegionIO/lex-todoist
13
+ **License**: MIT
14
+
15
+ ## Status
16
+
17
+ Implemented (v0.2.0). All five runner modules are fully implemented via `Helpers::Client` (Faraday to Todoist REST API v2). Standalone `Client` class included. `faraday >= 2.0` declared as a gemspec runtime dependency.
18
+
19
+ ## Architecture
20
+
21
+ ```
22
+ Legion::Extensions::Todoist
23
+ ├── Runners/
24
+ │ ├── Projects # list, create, get, update, delete, collaborators (6 methods)
25
+ │ ├── Tasks # create, get_active, list_active, update, close, reopen, delete (7 methods)
26
+ │ ├── Sections # list, get_project_section, create, get, update, delete (6 methods)
27
+ │ ├── Labels # list, get, create, update, delete (5 methods)
28
+ │ └── Comments # list, get, create, delete (4 methods)
29
+ ├── Helpers/
30
+ │ └── Client # Faraday connection to Todoist REST API v2 (Bearer token auth)
31
+ └── Client # Standalone client class (includes all runners)
32
+ ```
33
+
34
+ ## Key Files
35
+
36
+ | Path | Purpose |
37
+ |------|---------|
38
+ | `lib/legion/extensions/todoist.rb` | Entry point, extension registration |
39
+ | `lib/legion/extensions/todoist/runners/` | All Todoist resource runners (fully implemented) |
40
+ | `lib/legion/extensions/todoist/helpers/client.rb` | Faraday client to `https://api.todoist.com/rest/v2` with Bearer token auth |
41
+ | `lib/legion/extensions/todoist/client.rb` | Standalone `Client` class for use outside Legion framework |
42
+
43
+ ## Dependencies
44
+
45
+ | Gem | Purpose |
46
+ |-----|---------|
47
+ | `faraday` (>= 2.0) | HTTP client for Todoist REST API v2 |
48
+
49
+ ## Development
50
+
51
+ 9 specs total.
52
+
53
+ ```bash
54
+ bundle install
55
+ bundle exec rspec
56
+ bundle exec rubocop
57
+ ```
58
+
59
+ ---
60
+
61
+ **Maintained By**: Matthew Iverson (@Esity)
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in legion-extensions-todoist.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 12.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rspec_junit_formatter'
11
+ gem 'rubocop'
data/Gemfile.lock ADDED
@@ -0,0 +1,163 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lex-todoist (0.2.1)
5
+ faraday (>= 2.0)
6
+ legion-cache (>= 1.3.11)
7
+ legion-crypt (>= 1.4.9)
8
+ legion-data (>= 1.4.17)
9
+ legion-json (>= 1.2.1)
10
+ legion-logging (>= 1.3.2)
11
+ legion-settings (>= 1.3.14)
12
+ legion-transport (>= 1.3.9)
13
+
14
+ GEM
15
+ remote: https://rubygems.org/
16
+ specs:
17
+ addressable (2.8.9)
18
+ public_suffix (>= 2.0.2, < 8.0)
19
+ amq-protocol (2.5.1)
20
+ ast (2.4.3)
21
+ aws-eventstream (1.4.0)
22
+ aws-sigv4 (1.12.1)
23
+ aws-eventstream (~> 1, >= 1.0.2)
24
+ base64 (0.3.0)
25
+ bigdecimal (4.0.1)
26
+ bunny (2.24.0)
27
+ amq-protocol (~> 2.3)
28
+ sorted_set (~> 1, >= 1.0.2)
29
+ concurrent-ruby (1.3.6)
30
+ connection_pool (2.5.5)
31
+ dalli (5.0.2)
32
+ logger
33
+ diff-lcs (1.6.2)
34
+ ed25519 (1.4.0)
35
+ faraday (2.14.1)
36
+ faraday-net_http (>= 2.0, < 3.5)
37
+ json
38
+ logger
39
+ faraday-net_http (3.4.2)
40
+ net-http (~> 0.5)
41
+ json (2.19.1)
42
+ json-schema (6.2.0)
43
+ addressable (~> 2.8)
44
+ bigdecimal (>= 3.1, < 5)
45
+ json_pure (2.8.1)
46
+ jwt (3.1.2)
47
+ base64
48
+ language_server-protocol (3.17.0.5)
49
+ legion-cache (1.3.11)
50
+ connection_pool (>= 2.4)
51
+ dalli (>= 3.0)
52
+ legion-logging (>= 1.2.8)
53
+ legion-settings (>= 1.3.12)
54
+ redis (>= 5.0)
55
+ legion-crypt (1.4.9)
56
+ ed25519 (~> 1.3)
57
+ jwt (>= 2.7)
58
+ vault (>= 0.17)
59
+ legion-data (1.4.17)
60
+ legion-logging (>= 1.2.8)
61
+ legion-settings (>= 1.3.12)
62
+ sequel (>= 5.70)
63
+ sqlite3 (>= 2.0)
64
+ legion-json (1.2.1)
65
+ json_pure
66
+ multi_json
67
+ legion-logging (1.3.2)
68
+ logger
69
+ rainbow (~> 3)
70
+ legion-settings (1.3.14)
71
+ legion-json (>= 1.2.0)
72
+ legion-transport (1.3.9)
73
+ bunny (>= 2.23)
74
+ concurrent-ruby (>= 1.2)
75
+ legion-json (>= 1.2.0)
76
+ legion-settings (>= 1.3.12)
77
+ logger
78
+ lint_roller (1.1.0)
79
+ logger (1.7.0)
80
+ mcp (0.8.0)
81
+ json-schema (>= 4.1)
82
+ mini_portile2 (2.8.9)
83
+ multi_json (1.19.1)
84
+ net-http (0.9.1)
85
+ uri (>= 0.11.1)
86
+ net-http-persistent (4.0.8)
87
+ connection_pool (>= 2.2.4, < 4)
88
+ parallel (1.27.0)
89
+ parser (3.3.10.2)
90
+ ast (~> 2.4.1)
91
+ racc
92
+ prism (1.9.0)
93
+ public_suffix (7.0.5)
94
+ racc (1.8.1)
95
+ rainbow (3.1.1)
96
+ rake (12.3.3)
97
+ rbtree (0.4.6)
98
+ redis (5.4.1)
99
+ redis-client (>= 0.22.0)
100
+ redis-client (0.28.0)
101
+ connection_pool
102
+ regexp_parser (2.11.3)
103
+ rspec (3.13.2)
104
+ rspec-core (~> 3.13.0)
105
+ rspec-expectations (~> 3.13.0)
106
+ rspec-mocks (~> 3.13.0)
107
+ rspec-core (3.13.6)
108
+ rspec-support (~> 3.13.0)
109
+ rspec-expectations (3.13.5)
110
+ diff-lcs (>= 1.2.0, < 2.0)
111
+ rspec-support (~> 3.13.0)
112
+ rspec-mocks (3.13.8)
113
+ diff-lcs (>= 1.2.0, < 2.0)
114
+ rspec-support (~> 3.13.0)
115
+ rspec-support (3.13.7)
116
+ rspec_junit_formatter (0.6.0)
117
+ rspec-core (>= 2, < 4, != 2.12.0)
118
+ rubocop (1.85.1)
119
+ json (~> 2.3)
120
+ language_server-protocol (~> 3.17.0.2)
121
+ lint_roller (~> 1.1.0)
122
+ mcp (~> 0.6)
123
+ parallel (~> 1.10)
124
+ parser (>= 3.3.0.2)
125
+ rainbow (>= 2.2.2, < 4.0)
126
+ regexp_parser (>= 2.9.3, < 3.0)
127
+ rubocop-ast (>= 1.49.0, < 2.0)
128
+ ruby-progressbar (~> 1.7)
129
+ unicode-display_width (>= 2.4.0, < 4.0)
130
+ rubocop-ast (1.49.1)
131
+ parser (>= 3.3.7.2)
132
+ prism (~> 1.7)
133
+ ruby-progressbar (1.13.0)
134
+ sequel (5.102.0)
135
+ bigdecimal
136
+ sorted_set (1.1.0)
137
+ rbtree
138
+ sqlite3 (2.9.2)
139
+ mini_portile2 (~> 2.8.0)
140
+ sqlite3 (2.9.2-arm64-darwin)
141
+ unicode-display_width (3.2.0)
142
+ unicode-emoji (~> 4.1)
143
+ unicode-emoji (4.2.0)
144
+ uri (1.1.1)
145
+ vault (0.20.0)
146
+ aws-sigv4
147
+ base64
148
+ connection_pool (~> 2.4)
149
+ net-http-persistent (~> 4.0, >= 4.0.2)
150
+
151
+ PLATFORMS
152
+ arm64-darwin-25
153
+ ruby
154
+
155
+ DEPENDENCIES
156
+ lex-todoist!
157
+ rake (~> 12.0)
158
+ rspec (~> 3.0)
159
+ rspec_junit_formatter
160
+ rubocop
161
+
162
+ BUNDLED WITH
163
+ 2.6.9
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Esity
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # lex-todoist
2
+
3
+ Todoist task management integration for [LegionIO](https://github.com/LegionIO/LegionIO). Manage projects, tasks, sections, labels, and comments via the Todoist REST API v2 from within task chains or as a standalone client library.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install lex-todoist
9
+ ```
10
+
11
+ Or add to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'lex-todoist'
15
+ ```
16
+
17
+ ## Standalone Usage
18
+
19
+ ```ruby
20
+ require 'legion/extensions/todoist'
21
+
22
+ client = Legion::Extensions::Todoist::Client.new(token: 'your-api-token')
23
+
24
+ # Projects
25
+ client.list
26
+ client.create(name: 'My Project')
27
+ client.get(project_id: '123')
28
+
29
+ # Tasks
30
+ client.list_active(project_id: '123')
31
+ client.create(content: 'Buy milk', project_id: '123')
32
+ client.close(task_id: '456')
33
+
34
+ # Comments
35
+ client.list(task_id: '456')
36
+ client.create(task_id: '456', content: 'Done!')
37
+ ```
38
+
39
+ ## Runners
40
+
41
+ ### Projects
42
+
43
+ | Method | Parameters | Description |
44
+ |--------|-----------|-------------|
45
+ | `list` | (none) | List all projects |
46
+ | `create` | `name:` | Create a project |
47
+ | `get` | `project_id:` | Get a project |
48
+ | `update` | `project_id:`, `name:` | Update a project |
49
+ | `delete` | `project_id:` | Delete a project |
50
+ | `collaborators` | `project_id:` | List project collaborators |
51
+
52
+ ### Tasks
53
+
54
+ | Method | Parameters | Description |
55
+ |--------|-----------|-------------|
56
+ | `create` | `content:`, `project_id:` | Create a task |
57
+ | `get_active` | `task_id:` | Get an active task |
58
+ | `list_active` | `project_id:` (optional) | List active tasks |
59
+ | `update` | `task_id:` | Update a task |
60
+ | `close` | `task_id:` | Mark a task complete |
61
+ | `reopen` | `task_id:` | Reopen a completed task |
62
+ | `delete` | `task_id:` | Delete a task |
63
+
64
+ ### Sections
65
+
66
+ | Method | Parameters | Description |
67
+ |--------|-----------|-------------|
68
+ | `list` | `project_id:` (optional) | List sections |
69
+ | `get_project_section` | `project_id:` | List sections for a project |
70
+ | `create` | `project_id:`, `name:` | Create a section |
71
+ | `get` | `section_id:` | Get a section |
72
+ | `update` | `section_id:`, `name:` | Update a section |
73
+ | `delete` | `section_id:` | Delete a section |
74
+
75
+ ### Labels
76
+
77
+ | Method | Parameters | Description |
78
+ |--------|-----------|-------------|
79
+ | `list` | (none) | List all labels |
80
+ | `get` | `label_id:` | Get a label |
81
+ | `create` | `name:` | Create a label |
82
+ | `update` | `label_id:`, `name:` | Update a label |
83
+ | `delete` | `label_id:` | Delete a label |
84
+
85
+ ### Comments
86
+
87
+ | Method | Parameters | Description |
88
+ |--------|-----------|-------------|
89
+ | `list` | `task_id:` or `project_id:` | List comments |
90
+ | `get` | `comment_id:` | Get a comment |
91
+ | `create` | `task_id:`, `content:` | Create a comment |
92
+ | `delete` | `comment_id:` | Delete a comment |
93
+
94
+ ## Requirements
95
+
96
+ - Ruby >= 3.4
97
+ - Todoist API token (Bearer token auth)
98
+ - `faraday` >= 2.0
99
+
100
+ ## License
101
+
102
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'legion/extensions/todoist'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/todoist/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-todoist'
7
+ spec.version = Legion::Extensions::Todoist::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX::Todoist'
12
+ spec.description = 'Used to connect Legion to Todoist'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-todoist'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-todoist'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-todoist/blob/main/CHANGELOG.md'
20
+ spec.metadata['rubygems_mfa_required'] = 'true'
21
+
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_dependency 'faraday', '>= 2.0'
30
+ spec.add_dependency 'legion-cache', '>= 1.3.11'
31
+ spec.add_dependency 'legion-crypt', '>= 1.4.9'
32
+ spec.add_dependency 'legion-data', '>= 1.4.17'
33
+ spec.add_dependency 'legion-json', '>= 1.2.1'
34
+ spec.add_dependency 'legion-logging', '>= 1.3.2'
35
+ spec.add_dependency 'legion-settings', '>= 1.3.14'
36
+ spec.add_dependency 'legion-transport', '>= 1.3.9'
37
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers/client'
4
+ require_relative 'runners/projects'
5
+ require_relative 'runners/tasks'
6
+ require_relative 'runners/sections'
7
+ require_relative 'runners/labels'
8
+ require_relative 'runners/comments'
9
+
10
+ module Legion
11
+ module Extensions
12
+ module Todoist
13
+ class Client
14
+ include Helpers::Client
15
+ include Runners::Projects
16
+ include Runners::Tasks
17
+ include Runners::Sections
18
+ include Runners::Labels
19
+ include Runners::Comments
20
+
21
+ attr_reader :opts
22
+
23
+ def initialize(token:, **extra)
24
+ @opts = { token: token, **extra }
25
+ end
26
+
27
+ def connection(**override)
28
+ super(**@opts, **override)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module Todoist
8
+ module Helpers
9
+ module Client
10
+ def connection(token: nil, **_opts)
11
+ Faraday.new(url: 'https://api.todoist.com/rest/v2/') do |conn|
12
+ conn.request :json
13
+ conn.response :json, content_type: /\bjson$/
14
+ conn.headers['Authorization'] = "Bearer #{token}" if token
15
+ conn.adapter Faraday.default_adapter
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ module Runners
7
+ module Comments
8
+ def get_comments(task_id: nil, project_id: nil, **)
9
+ params = {}
10
+ params[:task_id] = task_id if task_id
11
+ params[:project_id] = project_id if project_id
12
+ resp = connection(**).get('comments', params)
13
+ { comments: resp.body }
14
+ end
15
+
16
+ def create_comment(content:, task_id: nil, project_id: nil, **)
17
+ body = { content: content }
18
+ body[:task_id] = task_id if task_id
19
+ body[:project_id] = project_id if project_id
20
+ resp = connection(**).post('comments', body)
21
+ { comment: resp.body }
22
+ end
23
+
24
+ def update_comment(comment_id:, content:, **)
25
+ resp = connection(**).post("comments/#{comment_id}", { content: content })
26
+ { comment: resp.body }
27
+ end
28
+
29
+ def delete_comment(comment_id:, **)
30
+ connection(**).delete("comments/#{comment_id}")
31
+ { deleted: true, comment_id: comment_id }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ module Runners
7
+ module Labels
8
+ def list_labels(**)
9
+ resp = connection(**).get('labels')
10
+ { labels: resp.body }
11
+ end
12
+
13
+ def get_label(label_id:, **)
14
+ resp = connection(**).get("labels/#{label_id}")
15
+ { label: resp.body }
16
+ end
17
+
18
+ def create_label(name:, color: nil, order: nil, **)
19
+ body = { name: name }
20
+ body[:color] = color if color
21
+ body[:order] = order if order
22
+ resp = connection(**).post('labels', body)
23
+ { label: resp.body }
24
+ end
25
+
26
+ def update_label(label_id:, name: nil, color: nil, **)
27
+ body = {}
28
+ body[:name] = name if name
29
+ body[:color] = color if color
30
+ resp = connection(**).post("labels/#{label_id}", body)
31
+ { label: resp.body }
32
+ end
33
+
34
+ def delete_label(label_id:, **)
35
+ connection(**).delete("labels/#{label_id}")
36
+ { deleted: true, label_id: label_id }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ module Runners
7
+ module Projects
8
+ def list_projects(**)
9
+ resp = connection(**).get('projects')
10
+ { projects: resp.body }
11
+ end
12
+
13
+ def get_project(project_id:, **)
14
+ resp = connection(**).get("projects/#{project_id}")
15
+ { project: resp.body }
16
+ end
17
+
18
+ def create_project(name:, parent_id: nil, color: nil, **)
19
+ body = { name: name }
20
+ body[:parent_id] = parent_id if parent_id
21
+ body[:color] = color if color
22
+ resp = connection(**).post('projects', body)
23
+ { project: resp.body }
24
+ end
25
+
26
+ def update_project(project_id:, name: nil, color: nil, **)
27
+ body = {}
28
+ body[:name] = name if name
29
+ body[:color] = color if color
30
+ resp = connection(**).post("projects/#{project_id}", body)
31
+ { project: resp.body }
32
+ end
33
+
34
+ def delete_project(project_id:, **)
35
+ connection(**).delete("projects/#{project_id}")
36
+ { deleted: true, project_id: project_id }
37
+ end
38
+
39
+ def collaborators(project_id:, **)
40
+ resp = connection(**).get("projects/#{project_id}/collaborators")
41
+ { collaborators: resp.body }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ module Runners
7
+ module Sections
8
+ def list_sections(project_id: nil, **)
9
+ params = {}
10
+ params[:project_id] = project_id if project_id
11
+ resp = connection(**).get('sections', params)
12
+ { sections: resp.body }
13
+ end
14
+
15
+ def get_section(section_id:, **)
16
+ resp = connection(**).get("sections/#{section_id}")
17
+ { section: resp.body }
18
+ end
19
+
20
+ def create_section(name:, project_id:, order: nil, **)
21
+ body = { name: name, project_id: project_id }
22
+ body[:order] = order if order
23
+ resp = connection(**).post('sections', body)
24
+ { section: resp.body }
25
+ end
26
+
27
+ def update_section(section_id:, name:, **)
28
+ resp = connection(**).post("sections/#{section_id}", { name: name })
29
+ { section: resp.body }
30
+ end
31
+
32
+ def delete_section(section_id:, **)
33
+ connection(**).delete("sections/#{section_id}")
34
+ { deleted: true, section_id: section_id }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ module Runners
7
+ module Tasks
8
+ def create_task(content:, project_id: nil, due_string: nil, priority: nil, labels: nil, **)
9
+ body = { content: content }
10
+ body[:project_id] = project_id if project_id
11
+ body[:due_string] = due_string if due_string
12
+ body[:priority] = priority if priority
13
+ body[:labels] = labels if labels
14
+ resp = connection(**).post('tasks', body)
15
+ { task: resp.body }
16
+ end
17
+
18
+ def get_task(task_id:, **)
19
+ resp = connection(**).get("tasks/#{task_id}")
20
+ { task: resp.body }
21
+ end
22
+
23
+ def list_tasks(project_id: nil, label: nil, filter: nil, **)
24
+ params = {}
25
+ params[:project_id] = project_id if project_id
26
+ params[:label] = label if label
27
+ params[:filter] = filter if filter
28
+ resp = connection(**).get('tasks', params)
29
+ { tasks: resp.body }
30
+ end
31
+
32
+ def update_task(task_id:, content: nil, due_string: nil, priority: nil, **)
33
+ body = {}
34
+ body[:content] = content if content
35
+ body[:due_string] = due_string if due_string
36
+ body[:priority] = priority if priority
37
+ resp = connection(**).post("tasks/#{task_id}", body)
38
+ { task: resp.body }
39
+ end
40
+
41
+ def close_task(task_id:, **)
42
+ connection(**).post("tasks/#{task_id}/close")
43
+ { closed: true, task_id: task_id }
44
+ end
45
+
46
+ def reopen_task(task_id:, **)
47
+ connection(**).post("tasks/#{task_id}/reopen")
48
+ { reopened: true, task_id: task_id }
49
+ end
50
+
51
+ def delete_task(task_id:, **)
52
+ connection(**).delete("tasks/#{task_id}")
53
+ { deleted: true, task_id: task_id }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module Todoist
6
+ VERSION = '0.2.1'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/todoist/version'
4
+ require 'legion/extensions/todoist/helpers/client'
5
+ require 'legion/extensions/todoist/runners/projects'
6
+ require 'legion/extensions/todoist/runners/tasks'
7
+ require 'legion/extensions/todoist/runners/sections'
8
+ require 'legion/extensions/todoist/runners/labels'
9
+ require 'legion/extensions/todoist/runners/comments'
10
+ require 'legion/extensions/todoist/client'
11
+
12
+ module Legion
13
+ module Extensions
14
+ module Todoist
15
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
16
+ end
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-todoist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: legion-cache
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.11
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 1.3.11
40
+ - !ruby/object:Gem::Dependency
41
+ name: legion-crypt
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.4.9
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.4.9
54
+ - !ruby/object:Gem::Dependency
55
+ name: legion-data
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.4.17
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 1.4.17
68
+ - !ruby/object:Gem::Dependency
69
+ name: legion-json
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.2.1
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 1.2.1
82
+ - !ruby/object:Gem::Dependency
83
+ name: legion-logging
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.3.2
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 1.3.2
96
+ - !ruby/object:Gem::Dependency
97
+ name: legion-settings
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.3.14
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 1.3.14
110
+ - !ruby/object:Gem::Dependency
111
+ name: legion-transport
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 1.3.9
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 1.3.9
124
+ description: Used to connect Legion to Todoist
125
+ email:
126
+ - matthewdiverson@gmail.com
127
+ executables: []
128
+ extensions: []
129
+ extra_rdoc_files: []
130
+ files:
131
+ - ".github/workflows/ci.yml"
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".rubocop.yml"
135
+ - CHANGELOG.md
136
+ - CLAUDE.md
137
+ - Gemfile
138
+ - Gemfile.lock
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - bin/console
143
+ - bin/setup
144
+ - lex-todoist.gemspec
145
+ - lib/legion/extensions/todoist.rb
146
+ - lib/legion/extensions/todoist/client.rb
147
+ - lib/legion/extensions/todoist/helpers/client.rb
148
+ - lib/legion/extensions/todoist/runners/comments.rb
149
+ - lib/legion/extensions/todoist/runners/labels.rb
150
+ - lib/legion/extensions/todoist/runners/projects.rb
151
+ - lib/legion/extensions/todoist/runners/sections.rb
152
+ - lib/legion/extensions/todoist/runners/tasks.rb
153
+ - lib/legion/extensions/todoist/version.rb
154
+ homepage: https://github.com/LegionIO/lex-todoist
155
+ licenses:
156
+ - MIT
157
+ metadata:
158
+ homepage_uri: https://github.com/LegionIO/lex-todoist
159
+ source_code_uri: https://github.com/LegionIO/lex-todoist
160
+ changelog_uri: https://github.com/LegionIO/lex-todoist/blob/main/CHANGELOG.md
161
+ rubygems_mfa_required: 'true'
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '3.4'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubygems_version: 3.6.9
177
+ specification_version: 4
178
+ summary: LEX::Todoist
179
+ test_files: []