grist-grist 0.1.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +76 -0
- data/Rakefile +12 -0
- data/docker-compose.yml +11 -0
- data/examples/main.rb +83 -0
- data/examples/update.rb +56 -0
- data/lib/grist/accessible.rb +10 -0
- data/lib/grist/api_routes.rb +79 -0
- data/lib/grist/response.rb +39 -0
- data/lib/grist/rest.rb +95 -0
- data/lib/grist/searchable.rb +17 -0
- data/lib/grist/type/access.rb +69 -0
- data/lib/grist/type/base.rb +72 -0
- data/lib/grist/type/column.rb +25 -0
- data/lib/grist/type/doc.rb +99 -0
- data/lib/grist/type/organization.rb +111 -0
- data/lib/grist/type/record.rb +22 -0
- data/lib/grist/type/table.rb +132 -0
- data/lib/grist/type/workspace.rb +88 -0
- data/lib/grist/version.rb +7 -0
- data/lib/grist.rb +61 -0
- metadata +86 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Organization
|
|
6
|
+
class Access < Grist::Type::Base
|
|
7
|
+
PATH = "/access"
|
|
8
|
+
KEYS = %w[
|
|
9
|
+
id
|
|
10
|
+
email
|
|
11
|
+
name
|
|
12
|
+
picture
|
|
13
|
+
ref
|
|
14
|
+
access
|
|
15
|
+
isMember
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
attr_accessor(*KEYS)
|
|
19
|
+
|
|
20
|
+
# List all organizations
|
|
21
|
+
# @return [Array] Array of organizations
|
|
22
|
+
def self.all
|
|
23
|
+
grist_res = new.list
|
|
24
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
25
|
+
|
|
26
|
+
grist_res.data&.map { |org| Organization.new(org) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Finds an organization by ID
|
|
30
|
+
# @param id [Integer] The ID of the organization to find
|
|
31
|
+
# return [self | nil] The organization or nil if not found
|
|
32
|
+
def self.find(id)
|
|
33
|
+
grist_res = new.get(id)
|
|
34
|
+
return unless grist_res.success? && grist_res.data
|
|
35
|
+
|
|
36
|
+
new(grist_res.data)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Updates the organization
|
|
40
|
+
# @param id [Integer] The ID of the organization to delete
|
|
41
|
+
# @param data [Hash] The data to update the organization with
|
|
42
|
+
# @return [self | nil] The updated organization or nil if not found
|
|
43
|
+
def self.update(id, data)
|
|
44
|
+
org = find(id)
|
|
45
|
+
return unless org
|
|
46
|
+
|
|
47
|
+
org.update(data)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Deletes the organization
|
|
51
|
+
# @param id [Integer] The ID of the organization to delete
|
|
52
|
+
# @return [self | nil] The deleted organization or nil if not found
|
|
53
|
+
def self.delete(id)
|
|
54
|
+
org = find(id)
|
|
55
|
+
return unless org
|
|
56
|
+
|
|
57
|
+
org.delete
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.access(id)
|
|
61
|
+
org = find(id)
|
|
62
|
+
grist_res = org.access
|
|
63
|
+
return unless grist_res.success? && grist_res.data
|
|
64
|
+
|
|
65
|
+
grist_res.data
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
class Base
|
|
6
|
+
include Rest
|
|
7
|
+
include Accessible
|
|
8
|
+
include Searchable
|
|
9
|
+
|
|
10
|
+
PATH = ""
|
|
11
|
+
KEYS = %w[].freeze
|
|
12
|
+
attr_accessor(*KEYS)
|
|
13
|
+
|
|
14
|
+
def initialize(params = {})
|
|
15
|
+
keys.each do |key|
|
|
16
|
+
instance_variable_set("@#{key}", params[key])
|
|
17
|
+
end
|
|
18
|
+
@deleted = params.delete(:deleted) || false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def keys
|
|
22
|
+
self.class::KEYS
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def deleted?
|
|
26
|
+
!!@deleted
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# List all items
|
|
30
|
+
# @return [Array] Array of items
|
|
31
|
+
def self.all
|
|
32
|
+
grist_res = new.list
|
|
33
|
+
|
|
34
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
35
|
+
return [] unless grist_res&.data&.any?
|
|
36
|
+
|
|
37
|
+
grist_res.data.map { |org| new(org) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Finds an item by ID
|
|
41
|
+
# @param id [Integer] The ID of the item to find
|
|
42
|
+
# return [Grist::Type::Base, nil] The item or nil if not found
|
|
43
|
+
def self.find(id)
|
|
44
|
+
grist_res = new.get(id)
|
|
45
|
+
return unless grist_res.success? && grist_res.data
|
|
46
|
+
|
|
47
|
+
new(grist_res.data)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Updates the item
|
|
51
|
+
# @param id [Integer] The ID of the item to delete
|
|
52
|
+
# @param data [Hash] The data to update the item with
|
|
53
|
+
# @return [Grist::Type::Base, nil] The updated item or nil if not found
|
|
54
|
+
def self.update(id, data)
|
|
55
|
+
org = find(id)
|
|
56
|
+
return unless org
|
|
57
|
+
|
|
58
|
+
org.update(data)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Deletes the item
|
|
62
|
+
# @param id [Integer] The ID of the item to delete
|
|
63
|
+
# @return [Grist::Type::Base, nil] The deleted item or nil if not found
|
|
64
|
+
def self.delete(id)
|
|
65
|
+
org = find(id)
|
|
66
|
+
return unless org
|
|
67
|
+
|
|
68
|
+
org.delete
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Workspace
|
|
6
|
+
class Column
|
|
7
|
+
include Rest
|
|
8
|
+
|
|
9
|
+
PATH = "/docs"
|
|
10
|
+
KEYS = %w[
|
|
11
|
+
id
|
|
12
|
+
fields
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
attr_accessor(*KEYS)
|
|
16
|
+
|
|
17
|
+
def initialize(params = {})
|
|
18
|
+
@doc_id = params[:doc_id]
|
|
19
|
+
KEYS.each do |key|
|
|
20
|
+
instance_variable_set("@#{key}", params[key])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Workspace
|
|
6
|
+
class Doc < Grist::Type::Base
|
|
7
|
+
PATH = "/docs"
|
|
8
|
+
KEYS = %w[
|
|
9
|
+
name
|
|
10
|
+
createdAt
|
|
11
|
+
updatedAt
|
|
12
|
+
id
|
|
13
|
+
isPinned
|
|
14
|
+
urlId
|
|
15
|
+
trunkId
|
|
16
|
+
type
|
|
17
|
+
forks
|
|
18
|
+
access
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
attr_accessor(*KEYS)
|
|
22
|
+
|
|
23
|
+
def initialize(params = {})
|
|
24
|
+
super params
|
|
25
|
+
@ws_id = params[:ws_id]
|
|
26
|
+
@tables = []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def tables_path
|
|
30
|
+
"#{path}/#{@id}/tables"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def tables
|
|
34
|
+
grist_res = request(:get, tables_path)
|
|
35
|
+
return [] if grist_res&.error?
|
|
36
|
+
|
|
37
|
+
@tables = grist_res.data["tables"]&.map do |t|
|
|
38
|
+
Table.new(t.merge(doc_id: @id, ws_id: @ws_id))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def create_tables(data)
|
|
43
|
+
grist_res = request(:post, tables_path, data)
|
|
44
|
+
|
|
45
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
46
|
+
|
|
47
|
+
tables
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def update_table(data)
|
|
51
|
+
grist_res = request(:patch, tables_path, data)
|
|
52
|
+
|
|
53
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
54
|
+
|
|
55
|
+
tables
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# def base_api_url
|
|
59
|
+
# "#{ENV["GRIST_API_URL"]}/api/orgs/#{@org_id}"
|
|
60
|
+
# end
|
|
61
|
+
|
|
62
|
+
# Updates the workspace
|
|
63
|
+
# # @param id [Integer] The ID of the workspace to delete
|
|
64
|
+
# # # @param data [Hash] The data to update the workspace with
|
|
65
|
+
# # @return [self | nil] The updated workspace or nil if not found
|
|
66
|
+
def self.create(ws_id, data)
|
|
67
|
+
obj = new(ws_id: ws_id)
|
|
68
|
+
obj.create(data)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# List all workspaces
|
|
72
|
+
# # # @return [Array] Array of workspaces
|
|
73
|
+
def self.all(org_id)
|
|
74
|
+
grist_res = new(org_id: org_id).list
|
|
75
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
76
|
+
|
|
77
|
+
grist_res.data&.map { |org| Workspace.new(org) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Finds an workspace by ID
|
|
81
|
+
# # @param id [Integer] The ID of the workspace to find
|
|
82
|
+
# # # return [self | nil] The workspace or nil if not found
|
|
83
|
+
def self.find(id)
|
|
84
|
+
grist_res = new.get(id)
|
|
85
|
+
puts grist_res.inspect
|
|
86
|
+
return unless grist_res.success? && grist_res.data
|
|
87
|
+
|
|
88
|
+
new(grist_res.data)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.tables(doc_id)
|
|
92
|
+
org = find(doc_id)
|
|
93
|
+
return unless org
|
|
94
|
+
|
|
95
|
+
org.tables
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Organization
|
|
6
|
+
class Organization < Grist::Type::Base
|
|
7
|
+
PATH = "/orgs"
|
|
8
|
+
KEYS = %w[
|
|
9
|
+
id
|
|
10
|
+
name
|
|
11
|
+
createdAt
|
|
12
|
+
updatedAt
|
|
13
|
+
domain
|
|
14
|
+
host
|
|
15
|
+
owner
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
attr_accessor(*KEYS)
|
|
19
|
+
attr_reader :workspaces
|
|
20
|
+
|
|
21
|
+
# Initialize a new Organization
|
|
22
|
+
# @param params [Hash] The parameters to initialize the organization with
|
|
23
|
+
# @return [Grist::Type::Organization] The organization
|
|
24
|
+
# @note API: https://support.getgrist.com/api/#tag/organizations
|
|
25
|
+
# @example
|
|
26
|
+
# org = Grist::Type::Organization.new(
|
|
27
|
+
# "id" => 1,
|
|
28
|
+
# "name" => "Grist Labs",
|
|
29
|
+
# "domain" => "gristlabs",
|
|
30
|
+
# "host" => "gristlabs.com",
|
|
31
|
+
# )
|
|
32
|
+
def initialize(params = {})
|
|
33
|
+
super params
|
|
34
|
+
@workspaces = []
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# List Workspaces in the organization
|
|
38
|
+
# @return [Array] The array of Grist::Type::Workspace
|
|
39
|
+
# @note API: https://support.getgrist.com/api/#tag/workspaces
|
|
40
|
+
def workspaces
|
|
41
|
+
grist_res = request(:get, workspaces_path)
|
|
42
|
+
|
|
43
|
+
return [] unless grist_res.success? && grist_res.data
|
|
44
|
+
|
|
45
|
+
@workspaces = grist_res.data.map do |workspace|
|
|
46
|
+
Workspace.new(workspace)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Create a new Workspace in the organization
|
|
51
|
+
# @param data [Hash] The data to create the workspace with
|
|
52
|
+
# @return [Decidim::Type::Workspace, nil] The organization or nil if not found
|
|
53
|
+
def create_workspace(data)
|
|
54
|
+
grist_res = request(:post, workspaces_path, data)
|
|
55
|
+
|
|
56
|
+
unless grist_res.success?
|
|
57
|
+
grist_res.print_error
|
|
58
|
+
return
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
data["id"] = grist_res.data
|
|
62
|
+
data.transform_keys!(&:to_s)
|
|
63
|
+
|
|
64
|
+
ws = Workspace.new(data)
|
|
65
|
+
@workspaces << ws
|
|
66
|
+
|
|
67
|
+
ws
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get the path for the organization
|
|
71
|
+
# @return [String] The path for the organization
|
|
72
|
+
def workspaces_path
|
|
73
|
+
"#{path}/#{@id}/workspaces"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Get users which can access to the organization
|
|
77
|
+
# @param id [Integer] The ID of the organization
|
|
78
|
+
# @return [Array, nil] An array of Grist::Type::Access or nil
|
|
79
|
+
def self.access(id)
|
|
80
|
+
org = find(id)
|
|
81
|
+
grist_res = org.access
|
|
82
|
+
return unless grist_res.success? && grist_res.data
|
|
83
|
+
|
|
84
|
+
grist_res.data["users"].map do |access|
|
|
85
|
+
Access.new(access)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# List workspaces in the organization
|
|
90
|
+
# @param id [Integer] The ID of the organization
|
|
91
|
+
# @return [Array] An array of Grist::Type::Workspace
|
|
92
|
+
def self.list_workspaces(id)
|
|
93
|
+
org = find(id)
|
|
94
|
+
return [] unless org
|
|
95
|
+
|
|
96
|
+
org.workspaces
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Create a new workspace in the organization
|
|
100
|
+
# @param org_id [Integer] The ID of the organization
|
|
101
|
+
# @param data [Hash] The data to create the workspace with
|
|
102
|
+
# @return [Grist::Type::Workspace, nil] The created workspace or nil if not found
|
|
103
|
+
def self.create_workspace(org_id, data)
|
|
104
|
+
org = find(org_id)
|
|
105
|
+
return unless org
|
|
106
|
+
|
|
107
|
+
org.create_workspace(data)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Workspace
|
|
6
|
+
class Record < Grist::Type::Base
|
|
7
|
+
PATH = "/records"
|
|
8
|
+
KEYS = %w[
|
|
9
|
+
id
|
|
10
|
+
fields
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
attr_accessor(*KEYS)
|
|
14
|
+
|
|
15
|
+
def initialize(params = {})
|
|
16
|
+
super params
|
|
17
|
+
@table_id = params[:table_id]
|
|
18
|
+
@doc_id = params[:doc_id]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Workspace
|
|
6
|
+
class Table < Grist::Type::Base
|
|
7
|
+
KEYS = %w[
|
|
8
|
+
id
|
|
9
|
+
fields
|
|
10
|
+
columns
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
attr_accessor(*KEYS)
|
|
14
|
+
|
|
15
|
+
def initialize(params = {})
|
|
16
|
+
@doc_id = params[:doc_id]
|
|
17
|
+
super params
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_hash
|
|
21
|
+
{
|
|
22
|
+
"id" => @id,
|
|
23
|
+
"fields" => @fields,
|
|
24
|
+
"columns" => @columns
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def columns_path
|
|
29
|
+
"/docs/#{@doc_id}/tables/#{@id}/columns"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def columns
|
|
33
|
+
grist_res = request(:get, columns_path)
|
|
34
|
+
return [] unless grist_res.success? && grist_res.data
|
|
35
|
+
|
|
36
|
+
grist_res.data.map do |column|
|
|
37
|
+
Column.new(column)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def records_path
|
|
42
|
+
"/docs/#{@doc_id}/tables/#{@id}/records"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def records(params = {})
|
|
46
|
+
grist_res = request(:get, records_path, params)
|
|
47
|
+
|
|
48
|
+
return [] unless grist_res.success? && grist_res.data
|
|
49
|
+
|
|
50
|
+
@records = grist_res.data["records"].map do |record|
|
|
51
|
+
Record.new(record.merge(doc_id: @doc_id, table_id: @id))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
@records
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def create_records(data)
|
|
58
|
+
grist_res = request(:post, records_path, data)
|
|
59
|
+
return [] unless grist_res.success? && grist_res.data
|
|
60
|
+
|
|
61
|
+
@records = grist_res.data["records"].map do |record|
|
|
62
|
+
Record.new(record.merge(doc_id: @doc_id, table_id: @id))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@records
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# def base_api_url
|
|
69
|
+
# "#{ENV["GRIST_API_URL"]}/api/orgs/#{@org_id}"
|
|
70
|
+
# end
|
|
71
|
+
|
|
72
|
+
# Updates the workspace
|
|
73
|
+
# # @param id [Integer] The ID of the workspace to delete
|
|
74
|
+
# # # @param data [Hash] The data to update the workspace with
|
|
75
|
+
# # @return [self | nil] The updated workspace or nil if not found
|
|
76
|
+
def self.create(doc_id, data)
|
|
77
|
+
obj = new(doc_id: doc_id)
|
|
78
|
+
obj.create(data)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# List all workspaces
|
|
82
|
+
# # # @return [Array] Array of workspaces
|
|
83
|
+
def self.all(org_id)
|
|
84
|
+
grist_res = new(org_id: org_id).list
|
|
85
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
86
|
+
|
|
87
|
+
grist_res.data&.map { |org| Workspace.new(org) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Finds an workspace by ID
|
|
91
|
+
# # @param id [Integer] The ID of the workspace to find
|
|
92
|
+
# # # return [self | nil] The workspace or nil if not found
|
|
93
|
+
def self.find(id)
|
|
94
|
+
grist_res = new.get(id)
|
|
95
|
+
return unless grist_res.success? && grist_res.data
|
|
96
|
+
|
|
97
|
+
new(grist_res.data)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Updates the workspace
|
|
101
|
+
# # @param id [Integer] The ID of the workspace to delete
|
|
102
|
+
# # # @param data [Hash] The data to update the workspace with
|
|
103
|
+
# # @return [self | nil] The updated workspace or nil if not found
|
|
104
|
+
def self.update(id, data)
|
|
105
|
+
org = find(id)
|
|
106
|
+
return unless org
|
|
107
|
+
|
|
108
|
+
org.update(data)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Deletes the workspace
|
|
112
|
+
# # @param id [Integer] The ID of the workspace to delete
|
|
113
|
+
# # @return [self | nil] The deleted workspace or nil if not found
|
|
114
|
+
def self.delete(id)
|
|
115
|
+
org = find(id)
|
|
116
|
+
return unless org
|
|
117
|
+
|
|
118
|
+
org.delete
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.access(id)
|
|
122
|
+
org = find(id)
|
|
123
|
+
grist_res = org.access
|
|
124
|
+
return unless grist_res.success? && grist_res.data
|
|
125
|
+
|
|
126
|
+
grist_res.data["users"].map do |access|
|
|
127
|
+
Access.new(access)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Grist
|
|
4
|
+
module Type
|
|
5
|
+
# Defines a Grist Workspace
|
|
6
|
+
class Workspace < Grist::Type::Base
|
|
7
|
+
PATH = "/workspaces"
|
|
8
|
+
KEYS = %w[
|
|
9
|
+
id
|
|
10
|
+
name
|
|
11
|
+
createdAt
|
|
12
|
+
updatedAt
|
|
13
|
+
isSupportWorkspace
|
|
14
|
+
docs
|
|
15
|
+
access
|
|
16
|
+
owner
|
|
17
|
+
orgDomain
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
attr_accessor(*KEYS)
|
|
21
|
+
attr_reader :org_id
|
|
22
|
+
|
|
23
|
+
def initialize(params = {})
|
|
24
|
+
@org_id = params[:org_id]
|
|
25
|
+
@docs = []
|
|
26
|
+
super params
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def docs
|
|
30
|
+
return @docs if @docs&.any? && @docs.first.is_a?(Doc)
|
|
31
|
+
|
|
32
|
+
if @docs.any? && @docs.first.is_a?(Hash)
|
|
33
|
+
@docs = @docs.map do |doc|
|
|
34
|
+
Doc.new(doc.merge(ws_id: @id))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@docs
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Create a new Doc in the workspace
|
|
42
|
+
# @param data [Hash] The data to create the doc with
|
|
43
|
+
# @return [Grist::Type::Doc, nil] The created doc or nil if not found
|
|
44
|
+
def create_doc(data)
|
|
45
|
+
grist_res = request(:post, doc_path, data)
|
|
46
|
+
|
|
47
|
+
return unless grist_res.success?
|
|
48
|
+
|
|
49
|
+
data["id"] = grist_res.data
|
|
50
|
+
data.transform_keys!(&:to_s)
|
|
51
|
+
doc = Doc.new(data)
|
|
52
|
+
@docs ||= []
|
|
53
|
+
@docs << doc
|
|
54
|
+
|
|
55
|
+
doc
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Creates the workspace
|
|
59
|
+
# @param id [Integer] The ID of the workspace to create
|
|
60
|
+
# @param data [Hash] The data to create the workspace with
|
|
61
|
+
# @return [Grist::Type::Workspace, nil] The created workspace or nil if not found
|
|
62
|
+
def self.create(org_id, data)
|
|
63
|
+
org = Type::Organization.find(org_id)
|
|
64
|
+
org.create_workspace(data)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# List all workspaces
|
|
68
|
+
# @param org_id [Integer] The ID of the organization to list workspaces for
|
|
69
|
+
# @return [Array] Array of workspaces
|
|
70
|
+
def self.all(org_id)
|
|
71
|
+
grist_res = new(org_id: org_id).list
|
|
72
|
+
|
|
73
|
+
return [] unless grist_res&.data.is_a?(Array)
|
|
74
|
+
return [] unless grist_res&.data&.any?
|
|
75
|
+
|
|
76
|
+
grist_res.data.map { |org| Workspace.new(org) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
# @note Method to create a new doc in workspace
|
|
82
|
+
# @note API: https://support.getgrist.com/api/#tag/docs/operation/createDoc
|
|
83
|
+
def doc_path
|
|
84
|
+
"/workspaces/#{@id}/docs"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
data/lib/grist.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "logger"
|
|
5
|
+
require "json"
|
|
6
|
+
require_relative "grist/version"
|
|
7
|
+
require_relative "grist/rest"
|
|
8
|
+
require_relative "grist/accessible"
|
|
9
|
+
require_relative "grist/searchable"
|
|
10
|
+
require_relative "grist/type/base"
|
|
11
|
+
require_relative "grist/type/table"
|
|
12
|
+
require_relative "grist/type/record"
|
|
13
|
+
require_relative "grist/type/doc"
|
|
14
|
+
require_relative "grist/type/access"
|
|
15
|
+
require_relative "grist/type/workspace"
|
|
16
|
+
require_relative "grist/type/organization"
|
|
17
|
+
require_relative "grist/response"
|
|
18
|
+
|
|
19
|
+
module Grist
|
|
20
|
+
class Error < StandardError
|
|
21
|
+
def self.help; end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class NetworkError < Error; end
|
|
25
|
+
class APIError < Error; end
|
|
26
|
+
|
|
27
|
+
class InvalidApiKey < APIError
|
|
28
|
+
def self.help
|
|
29
|
+
"help: Ensure the GRIST_API_KEY environment variable is set and valid."
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class NotFound < APIError; end
|
|
34
|
+
|
|
35
|
+
def self.logger
|
|
36
|
+
@logger ||= Logger.new($stdout)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.logger=(logger)
|
|
40
|
+
@logger = logger
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.api_key
|
|
44
|
+
ENV["GRIST_API_KEY"]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.token_auth
|
|
48
|
+
"Bearer #{Grist.api_key}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.base_api_url
|
|
52
|
+
base_api_url = ENV["GRIST_API_URL"]
|
|
53
|
+
return base_api_url[0..-2] if !base_api_url.nil? && base_api_url != "" && base_api_url.end_with?("/")
|
|
54
|
+
|
|
55
|
+
base_api_url
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.localhost?
|
|
59
|
+
base_api_url.include?("http://localhost")
|
|
60
|
+
end
|
|
61
|
+
end
|