click_up 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +70 -0
- data/LICENSE +21 -0
- data/README.md +2 -0
- data/click_up.gemspec +19 -0
- data/lib/click_up.rb +27 -0
- data/lib/click_up/api_operations/all.rb +11 -0
- data/lib/click_up/api_operations/create.rb +11 -0
- data/lib/click_up/api_operations/get.rb +16 -0
- data/lib/click_up/api_resource.rb +16 -0
- data/lib/click_up/connection_manager.rb +55 -0
- data/lib/click_up/errors.rb +24 -0
- data/lib/click_up/hierarchy/folder.rb +33 -0
- data/lib/click_up/hierarchy/list.rb +54 -0
- data/lib/click_up/hierarchy/space.rb +66 -0
- data/lib/click_up/hierarchy/task.rb +60 -0
- data/lib/click_up/hierarchy/team.rb +13 -0
- data/lib/click_up/version.rb +5 -0
- data/lib/generators/click_up/install_generator.rb +14 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 63c4a01c0a82ecb2d67e78014791cc49201e986767178eba67b6674bc0dfb739
|
4
|
+
data.tar.gz: e9df7b7a8a6a0fe422477dd6819672dc876b30a0bc9069ced27fec3bace67889
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 374be8c97b3094db1eade7fb5030b7a2215657fd6d9cd266220a0b847f3b213d8aa449153fcbe3cb86a832b849f0c2f09d977adbefe5c6b7fec1d13734451e22
|
7
|
+
data.tar.gz: 81cd9b8691a072cdafa0c67ba02d8d98441a0a0ffe74843c2cafba126534a29e10092c14ebe471ff195adc585018325c58a75dea7106e6aff9c50bc4aed91a2b
|
data/.gitignore
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
*.rbc
|
2
|
+
capybara-*.html
|
3
|
+
.rspec
|
4
|
+
/db/*.sqlite3
|
5
|
+
/db/*.sqlite3-journal
|
6
|
+
/db/*.sqlite3-[0-9]*
|
7
|
+
/public/system
|
8
|
+
/coverage/
|
9
|
+
/spec/tmp
|
10
|
+
*.orig
|
11
|
+
rerun.txt
|
12
|
+
pickle-email-*.html
|
13
|
+
|
14
|
+
# Ignore all logfiles and tempfiles.
|
15
|
+
/log/*
|
16
|
+
/tmp/*
|
17
|
+
!/log/.keep
|
18
|
+
!/tmp/.keep
|
19
|
+
|
20
|
+
# TODO Comment out this rule if you are OK with secrets being uploaded to the repo
|
21
|
+
config/initializers/secret_token.rb
|
22
|
+
config/master.key
|
23
|
+
|
24
|
+
# Only include if you have production secrets in this file, which is no longer a Rails default
|
25
|
+
# config/secrets.yml
|
26
|
+
|
27
|
+
# dotenv
|
28
|
+
# TODO Comment out this rule if environment variables can be committed
|
29
|
+
.env
|
30
|
+
|
31
|
+
## Environment normalization:
|
32
|
+
/.bundle
|
33
|
+
/vendor/bundle
|
34
|
+
|
35
|
+
# these should all be checked in to normalize the environment:
|
36
|
+
# Gemfile.lock, .ruby-version, .ruby-gemset
|
37
|
+
|
38
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
39
|
+
.rvmrc
|
40
|
+
|
41
|
+
# if using bower-rails ignore default bower_components path bower.json files
|
42
|
+
/vendor/assets/bower_components
|
43
|
+
*.bowerrc
|
44
|
+
bower.json
|
45
|
+
|
46
|
+
# Ignore pow environment settings
|
47
|
+
.powenv
|
48
|
+
|
49
|
+
# Ignore Byebug command history file.
|
50
|
+
.byebug_history
|
51
|
+
|
52
|
+
# Ignore node_modules
|
53
|
+
node_modules/
|
54
|
+
|
55
|
+
# Ignore precompiled javascript packs
|
56
|
+
/public/packs
|
57
|
+
/public/packs-test
|
58
|
+
/public/assets
|
59
|
+
|
60
|
+
# Ignore yarn files
|
61
|
+
/yarn-error.log
|
62
|
+
yarn-debug.log*
|
63
|
+
.yarn-integrity
|
64
|
+
|
65
|
+
# Ignore uploaded files in development
|
66
|
+
/storage/*
|
67
|
+
!/storage/.keep
|
68
|
+
|
69
|
+
#Ignore Rubymine project directories
|
70
|
+
.idea/*
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2021 Dinesh Budhayer
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
data/click_up.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$:.unshift ::File.join(::File.dirname(__FILE__), "lib")
|
4
|
+
|
5
|
+
require "click_up/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "click_up"
|
9
|
+
s.version = ClickUp::VERSION
|
10
|
+
s.required_ruby_version = ">= 2.3.0"
|
11
|
+
s.summary = "Ruby library for the ClickUp API"
|
12
|
+
s.description = "ClickUp: One app to replace them all."
|
13
|
+
s.author = "ayer-dines"
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.email = "budhayer96d@gmail.com"
|
16
|
+
s.homepage = "https://github.com/ayerdines/clickup-ruby"
|
17
|
+
s.license = "MIT"
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
end
|
data/lib/click_up.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
require 'click_up/errors'
|
7
|
+
|
8
|
+
require 'click_up/connection_manager'
|
9
|
+
require 'click_up/api_resource'
|
10
|
+
|
11
|
+
require 'click_up/api_operations/create'
|
12
|
+
require 'click_up/api_operations/get'
|
13
|
+
require 'click_up/api_operations/all'
|
14
|
+
|
15
|
+
require 'click_up/hierarchy/team'
|
16
|
+
require 'click_up/hierarchy/space'
|
17
|
+
require 'click_up/hierarchy/folder'
|
18
|
+
require 'click_up/hierarchy/task'
|
19
|
+
require 'click_up/hierarchy/list'
|
20
|
+
|
21
|
+
require 'click_up/version'
|
22
|
+
|
23
|
+
module ClickUp
|
24
|
+
class << self
|
25
|
+
attr_accessor :api_token
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
module APIOperations
|
5
|
+
module Get
|
6
|
+
def get(id=nil, **opts)
|
7
|
+
params = opts.clone
|
8
|
+
unless params.has_key?(:id) || id
|
9
|
+
raise ParamRequiredError, "id is a required parameter.", "id"
|
10
|
+
end
|
11
|
+
params[:id] = id ? id : params[:id]
|
12
|
+
execute_request(:get, resource_path(params))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class APIResource
|
5
|
+
class << self
|
6
|
+
def execute_request(method, path, data={})
|
7
|
+
client(path, data).send(method)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def client(path, data)
|
12
|
+
ConnectionManager.new(path, data)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class ConnectionManager
|
5
|
+
attr_reader :path, :data
|
6
|
+
|
7
|
+
def initialize(path, data)
|
8
|
+
@path = path
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def get
|
13
|
+
net_http_response = https_client.request_get(resource_url.path, default_headers)
|
14
|
+
format_response(net_http_response.body)
|
15
|
+
end
|
16
|
+
|
17
|
+
def post
|
18
|
+
form_data = data.to_json if data.is_a?(Hash) && data.size > 0
|
19
|
+
net_http_response = https_client.request_post(resource_url.path, form_data, default_headers)
|
20
|
+
format_response(net_http_response.body)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def resource_url
|
25
|
+
uri = URI("#{api_base}#{namespace}#{path}")
|
26
|
+
uri.query = URI.encode_www_form(data) if data.size > 0
|
27
|
+
uri
|
28
|
+
end
|
29
|
+
|
30
|
+
def namespace
|
31
|
+
"/api/v2"
|
32
|
+
end
|
33
|
+
|
34
|
+
def api_base
|
35
|
+
"https://api.clickup.com"
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_headers
|
39
|
+
{
|
40
|
+
'Content-Type' => 'application/json',
|
41
|
+
'Authorization' => ClickUp.api_token
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def format_response(net_http_response)
|
46
|
+
JSON.parse(net_http_response)
|
47
|
+
end
|
48
|
+
|
49
|
+
def https_client
|
50
|
+
https = Net::HTTP.new(resource_url.host, resource_url.port)
|
51
|
+
https.use_ssl = true
|
52
|
+
https
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class ClickUpError < StandardError
|
5
|
+
attr_reader :message
|
6
|
+
|
7
|
+
def initialize(msg = nil)
|
8
|
+
@message = msg
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"#{message}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ParamRequiredError < ClickUpError
|
17
|
+
attr_reader :params
|
18
|
+
|
19
|
+
def initialize(msg, *params)
|
20
|
+
super(msg)
|
21
|
+
@params = params
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class Folder < APIResource
|
5
|
+
extend ClickUp::APIOperations::All
|
6
|
+
extend ClickUp::APIOperations::Create
|
7
|
+
extend ClickUp::APIOperations::Get
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def index_path(params={})
|
11
|
+
"/space/#{params[:space_id]}/folder"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resource_path(params={})
|
15
|
+
"/folder/#{params[:id]}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def rejected_params
|
19
|
+
[
|
20
|
+
:id,
|
21
|
+
:space_id
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def formatted_params(params)
|
26
|
+
params.reject {|key, _| rejected_params.include?(key) }
|
27
|
+
# {
|
28
|
+
# "name": "Updated Folder Name"
|
29
|
+
# }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class List < APIResource
|
5
|
+
extend ClickUp::APIOperations::All
|
6
|
+
extend ClickUp::APIOperations::Create
|
7
|
+
extend ClickUp::APIOperations::Get
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def index_path(params={})
|
11
|
+
if params.has_key?(:folder_id)
|
12
|
+
folder_path(params[:folder_id])
|
13
|
+
elsif params.has_key?(:space_id)
|
14
|
+
folderless_path(params[:space_id])
|
15
|
+
else
|
16
|
+
raise ArgumentError, "Either folder_id or space_id is required."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def folder_path(folder_id)
|
21
|
+
"/folder/#{folder_id}/list"
|
22
|
+
end
|
23
|
+
|
24
|
+
def folderless_path(space_id)
|
25
|
+
"/space/#{space_id}/list"
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_path(params={})
|
29
|
+
"/list/#{params[:id]}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def rejected_params
|
33
|
+
[
|
34
|
+
:id,
|
35
|
+
:folder_id,
|
36
|
+
:space_id
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
def formatted_params(params)
|
41
|
+
params.reject {|key, _| rejected_params.include?(key) }
|
42
|
+
# {
|
43
|
+
# "name": "New List Name",
|
44
|
+
# "content": "Sent from API V2",
|
45
|
+
# "due_date": 1577811600000,
|
46
|
+
# "due_date_time": false,
|
47
|
+
# "priority": 1,
|
48
|
+
# "assignee": 53480,
|
49
|
+
# "status": "red"
|
50
|
+
# }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class Space < APIResource
|
5
|
+
extend ClickUp::APIOperations::All
|
6
|
+
extend ClickUp::APIOperations::Create
|
7
|
+
extend ClickUp::APIOperations::Get
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def index_path(params={})
|
11
|
+
"/team/#{params[:team_id]}/space"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resource_path(params={})
|
15
|
+
"/space/#{params[:id]}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def rejected_params
|
19
|
+
[
|
20
|
+
:id,
|
21
|
+
:team_id
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def formatted_params(params)
|
26
|
+
params.reject {|key, _| rejected_params.include?(key) }
|
27
|
+
# {
|
28
|
+
# "name": "New Space Name",
|
29
|
+
# "multiple_assignees": true,
|
30
|
+
# "features": {
|
31
|
+
# "due_dates": {
|
32
|
+
# "enabled": true,
|
33
|
+
# "start_date": false,
|
34
|
+
# "remap_due_dates": true,
|
35
|
+
# "remap_closed_due_date": false
|
36
|
+
# },
|
37
|
+
# "time_tracking": {
|
38
|
+
# "enabled": false
|
39
|
+
# },
|
40
|
+
# "tags": {
|
41
|
+
# "enabled": true
|
42
|
+
# },
|
43
|
+
# "time_estimates": {
|
44
|
+
# "enabled": true
|
45
|
+
# },
|
46
|
+
# "checklists": {
|
47
|
+
# "enabled": true
|
48
|
+
# },
|
49
|
+
# "custom_fields": {
|
50
|
+
# "enabled": true
|
51
|
+
# },
|
52
|
+
# "remap_dependencies": {
|
53
|
+
# "enabled": true
|
54
|
+
# },
|
55
|
+
# "dependency_warning": {
|
56
|
+
# "enabled": true
|
57
|
+
# },
|
58
|
+
# "portfolios": {
|
59
|
+
# "enabled": true
|
60
|
+
# }
|
61
|
+
# }
|
62
|
+
# }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickUp
|
4
|
+
class Task < APIResource
|
5
|
+
extend ClickUp::APIOperations::All
|
6
|
+
extend ClickUp::APIOperations::Create
|
7
|
+
extend ClickUp::APIOperations::Get
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def index_path(params={})
|
11
|
+
"/list/#{params[:list_id]}/task"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resource_path(params={})
|
15
|
+
"/task/#{params[:id]}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def rejected_params
|
19
|
+
[
|
20
|
+
:id,
|
21
|
+
:list_id
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def formatted_params(params)
|
26
|
+
params.reject {|key, _| rejected_params.include?(key) }
|
27
|
+
# {
|
28
|
+
# "name": "New Task Name",
|
29
|
+
# "description": "New Task Description",
|
30
|
+
# "assignees": [
|
31
|
+
# 183
|
32
|
+
# ],
|
33
|
+
# "tags": [
|
34
|
+
# "tag name 1"
|
35
|
+
# ],
|
36
|
+
# "status": "Open",
|
37
|
+
# "priority": 3,
|
38
|
+
# "due_date": 1508369194377,
|
39
|
+
# "due_date_time": false,
|
40
|
+
# "time_estimate": 8640000,
|
41
|
+
# "start_date": 1567780450202,
|
42
|
+
# "start_date_time": false,
|
43
|
+
# "notify_all": true,
|
44
|
+
# "parent": null,
|
45
|
+
# "links_to": null,
|
46
|
+
# "custom_fields": [
|
47
|
+
# {
|
48
|
+
# "id": "0a52c486-5f05-403b-b4fd-c512ff05131c",
|
49
|
+
# "value": 23
|
50
|
+
# },
|
51
|
+
# {
|
52
|
+
# "id": "03efda77-c7a0-42d3-8afd-fd546353c2f5",
|
53
|
+
# "value": "Text field input"
|
54
|
+
# }
|
55
|
+
# ]
|
56
|
+
# }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators'
|
4
|
+
|
5
|
+
module ClickUp
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
8
|
+
desc "This generator creates click_up.rb file at config/initializers"
|
9
|
+
def create_initializer_file
|
10
|
+
create_file "config/initializers/click_up.rb", "# Add ClickUp.api_token here\nClickUp.api_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: click_up
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ayer-dines
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-01-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'ClickUp: One app to replace them all.'
|
14
|
+
email: budhayer96d@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- ".gitignore"
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- click_up.gemspec
|
23
|
+
- lib/click_up.rb
|
24
|
+
- lib/click_up/api_operations/all.rb
|
25
|
+
- lib/click_up/api_operations/create.rb
|
26
|
+
- lib/click_up/api_operations/get.rb
|
27
|
+
- lib/click_up/api_resource.rb
|
28
|
+
- lib/click_up/connection_manager.rb
|
29
|
+
- lib/click_up/errors.rb
|
30
|
+
- lib/click_up/hierarchy/folder.rb
|
31
|
+
- lib/click_up/hierarchy/list.rb
|
32
|
+
- lib/click_up/hierarchy/space.rb
|
33
|
+
- lib/click_up/hierarchy/task.rb
|
34
|
+
- lib/click_up/hierarchy/team.rb
|
35
|
+
- lib/click_up/version.rb
|
36
|
+
- lib/generators/click_up/install_generator.rb
|
37
|
+
homepage: https://github.com/ayerdines/clickup-ruby
|
38
|
+
licenses:
|
39
|
+
- MIT
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 2.3.0
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 2.7.6
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Ruby library for the ClickUp API
|
61
|
+
test_files: []
|