leash-sdk 0.3.1 → 0.4.0
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 +4 -4
- data/Gemfile +1 -0
- data/README.md +156 -39
- data/leash-sdk.gemspec +5 -3
- data/lib/leash/auth.rb +216 -70
- data/lib/leash/client.rb +138 -0
- data/lib/leash/env.rb +165 -0
- data/lib/leash/errors.rb +107 -15
- data/lib/leash/integrations/base.rb +46 -0
- data/lib/leash/integrations/calendar.rb +64 -0
- data/lib/leash/integrations/drive.rb +53 -0
- data/lib/leash/integrations/gmail.rb +60 -0
- data/lib/leash/integrations/linear.rb +88 -0
- data/lib/leash/integrations.rb +36 -312
- data/lib/leash/transport.rb +188 -0
- data/lib/leash/types.rb +42 -0
- data/lib/leash/version.rb +1 -1
- data/lib/leash.rb +6 -1
- metadata +32 -14
- data/lib/leash/calendar.rb +0 -73
- data/lib/leash/custom_integration.rb +0 -32
- data/lib/leash/drive.rb +0 -48
- data/lib/leash/gmail.rb +0 -70
data/lib/leash.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "leash/version"
|
|
4
|
-
require_relative "leash/
|
|
4
|
+
require_relative "leash/errors"
|
|
5
|
+
require_relative "leash/types"
|
|
5
6
|
require_relative "leash/auth"
|
|
7
|
+
require_relative "leash/transport"
|
|
8
|
+
require_relative "leash/env"
|
|
9
|
+
require_relative "leash/integrations"
|
|
10
|
+
require_relative "leash/client"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leash-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leash
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: jwt
|
|
@@ -24,8 +23,24 @@ dependencies:
|
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '2.7'
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: minitest
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '5.0'
|
|
40
|
+
description: Server-side Leash client. Resolve the request user, read app env-vars
|
|
41
|
+
at runtime, and call platform integrations (Gmail, Google Calendar, Google Drive,
|
|
42
|
+
Linear, plus a generic escape hatch). Framework-agnostic — works with Rails, Sinatra,
|
|
43
|
+
Hanami, or plain Rack.
|
|
29
44
|
email:
|
|
30
45
|
- hello@leash.build
|
|
31
46
|
executables: []
|
|
@@ -38,12 +53,17 @@ files:
|
|
|
38
53
|
- leash-sdk.gemspec
|
|
39
54
|
- lib/leash.rb
|
|
40
55
|
- lib/leash/auth.rb
|
|
41
|
-
- lib/leash/
|
|
42
|
-
- lib/leash/
|
|
43
|
-
- lib/leash/drive.rb
|
|
56
|
+
- lib/leash/client.rb
|
|
57
|
+
- lib/leash/env.rb
|
|
44
58
|
- lib/leash/errors.rb
|
|
45
|
-
- lib/leash/gmail.rb
|
|
46
59
|
- lib/leash/integrations.rb
|
|
60
|
+
- lib/leash/integrations/base.rb
|
|
61
|
+
- lib/leash/integrations/calendar.rb
|
|
62
|
+
- lib/leash/integrations/drive.rb
|
|
63
|
+
- lib/leash/integrations/gmail.rb
|
|
64
|
+
- lib/leash/integrations/linear.rb
|
|
65
|
+
- lib/leash/transport.rb
|
|
66
|
+
- lib/leash/types.rb
|
|
47
67
|
- lib/leash/version.rb
|
|
48
68
|
homepage: https://github.com/leash-build/leash-sdk-ruby
|
|
49
69
|
licenses:
|
|
@@ -52,7 +72,6 @@ metadata:
|
|
|
52
72
|
homepage_uri: https://github.com/leash-build/leash-sdk-ruby
|
|
53
73
|
source_code_uri: https://github.com/leash-build/leash-sdk-ruby
|
|
54
74
|
changelog_uri: https://github.com/leash-build/leash-sdk-ruby/blob/main/CHANGELOG.md
|
|
55
|
-
post_install_message:
|
|
56
75
|
rdoc_options: []
|
|
57
76
|
require_paths:
|
|
58
77
|
- lib
|
|
@@ -60,15 +79,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
60
79
|
requirements:
|
|
61
80
|
- - ">="
|
|
62
81
|
- !ruby/object:Gem::Version
|
|
63
|
-
version: '
|
|
82
|
+
version: '2.7'
|
|
64
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
84
|
requirements:
|
|
66
85
|
- - ">="
|
|
67
86
|
- !ruby/object:Gem::Version
|
|
68
87
|
version: '0'
|
|
69
88
|
requirements: []
|
|
70
|
-
rubygems_version:
|
|
71
|
-
signing_key:
|
|
89
|
+
rubygems_version: 4.0.11
|
|
72
90
|
specification_version: 4
|
|
73
|
-
summary: Ruby SDK for the Leash platform integrations
|
|
91
|
+
summary: Unified Ruby SDK for the Leash platform — auth, env, integrations.
|
|
74
92
|
test_files: []
|
data/lib/leash/calendar.rb
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Leash
|
|
4
|
-
# Client for Google Calendar operations via the Leash platform proxy.
|
|
5
|
-
#
|
|
6
|
-
# Not instantiated directly -- use {Integrations#calendar} instead.
|
|
7
|
-
class CalendarClient
|
|
8
|
-
PROVIDER = "google_calendar"
|
|
9
|
-
|
|
10
|
-
# @api private
|
|
11
|
-
def initialize(call_fn)
|
|
12
|
-
@call = call_fn
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# List all calendars accessible to the user.
|
|
16
|
-
#
|
|
17
|
-
# @return [Hash] hash with calendar list data
|
|
18
|
-
def list_calendars
|
|
19
|
-
@call.call(PROVIDER, "list-calendars", {})
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# List events on a calendar.
|
|
23
|
-
#
|
|
24
|
-
# @param calendar_id [String, nil] calendar identifier (defaults to "primary" on the server)
|
|
25
|
-
# @param time_min [String, nil] lower bound for event start time (RFC 3339)
|
|
26
|
-
# @param time_max [String, nil] upper bound for event start time (RFC 3339)
|
|
27
|
-
# @param max_results [Integer, nil] maximum number of events to return
|
|
28
|
-
# @param single_events [Boolean, nil] whether to expand recurring events
|
|
29
|
-
# @param order_by [String, nil] sort order (e.g. "startTime", "updated")
|
|
30
|
-
# @return [Hash] hash with "items" list of events
|
|
31
|
-
def list_events(calendar_id: nil, time_min: nil, time_max: nil, max_results: nil, single_events: nil, order_by: nil)
|
|
32
|
-
params = {}
|
|
33
|
-
params["calendarId"] = calendar_id if calendar_id
|
|
34
|
-
params["timeMin"] = time_min if time_min
|
|
35
|
-
params["timeMax"] = time_max if time_max
|
|
36
|
-
params["maxResults"] = max_results if max_results
|
|
37
|
-
params["singleEvents"] = single_events unless single_events.nil?
|
|
38
|
-
params["orderBy"] = order_by if order_by
|
|
39
|
-
@call.call(PROVIDER, "list-events", params)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Create a new calendar event.
|
|
43
|
-
#
|
|
44
|
-
# @param summary [String] event title
|
|
45
|
-
# @param start [Hash, String] start time -- either an RFC 3339 string or a hash
|
|
46
|
-
# with keys "dateTime", "date", and/or "timeZone"
|
|
47
|
-
# @param end_time [Hash, String] end time (same format as +start+)
|
|
48
|
-
# @param calendar_id [String, nil] calendar identifier (defaults to "primary")
|
|
49
|
-
# @param description [String, nil] event description
|
|
50
|
-
# @param location [String, nil] event location
|
|
51
|
-
# @param attendees [Array<Hash>, nil] list of attendee hashes (e.g. [{ "email" => "a@b.com" }])
|
|
52
|
-
# @return [Hash] the created event object
|
|
53
|
-
def create_event(summary:, start:, end_time:, calendar_id: nil, description: nil, location: nil, attendees: nil)
|
|
54
|
-
params = { "summary" => summary, "start" => start, "end" => end_time }
|
|
55
|
-
params["calendarId"] = calendar_id if calendar_id
|
|
56
|
-
params["description"] = description if description
|
|
57
|
-
params["location"] = location if location
|
|
58
|
-
params["attendees"] = attendees if attendees
|
|
59
|
-
@call.call(PROVIDER, "create-event", params)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Get a single event by ID.
|
|
63
|
-
#
|
|
64
|
-
# @param event_id [String] the event identifier
|
|
65
|
-
# @param calendar_id [String, nil] the calendar identifier
|
|
66
|
-
# @return [Hash] the event object
|
|
67
|
-
def get_event(event_id, calendar_id: nil)
|
|
68
|
-
params = { "eventId" => event_id }
|
|
69
|
-
params["calendarId"] = calendar_id if calendar_id
|
|
70
|
-
@call.call(PROVIDER, "get-event", params)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Leash
|
|
4
|
-
# Untyped client for a custom integration.
|
|
5
|
-
#
|
|
6
|
-
# Obtained via {Integrations#integration}. Proxies requests through the
|
|
7
|
-
# Leash platform at +/api/integrations/custom/{name}+.
|
|
8
|
-
#
|
|
9
|
-
# @example
|
|
10
|
-
# stripe = client.integration("stripe")
|
|
11
|
-
# charges = stripe.call("/v1/charges", method: "GET")
|
|
12
|
-
class CustomIntegration
|
|
13
|
-
# @param name [String] the custom integration name
|
|
14
|
-
# @param call_fn [Method] internal callable that performs the HTTP request
|
|
15
|
-
def initialize(name, call_fn)
|
|
16
|
-
@name = name
|
|
17
|
-
@call_fn = call_fn
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Invoke the custom integration proxy.
|
|
21
|
-
#
|
|
22
|
-
# @param path [String] the endpoint path to forward (e.g. "/users")
|
|
23
|
-
# @param method [String] HTTP method (default "GET")
|
|
24
|
-
# @param body [Hash, nil] optional JSON body to forward
|
|
25
|
-
# @param headers [Hash, nil] optional extra headers to forward
|
|
26
|
-
# @return [Object] the "data" field from the platform response
|
|
27
|
-
# @raise [Leash::Error] if the platform returns a non-success response
|
|
28
|
-
def call(path, method: "GET", body: nil, headers: nil)
|
|
29
|
-
@call_fn.call(@name, path, method, body, headers)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
data/lib/leash/drive.rb
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Leash
|
|
4
|
-
# Client for Google Drive operations via the Leash platform proxy.
|
|
5
|
-
#
|
|
6
|
-
# Not instantiated directly -- use {Integrations#drive} instead.
|
|
7
|
-
class DriveClient
|
|
8
|
-
PROVIDER = "google_drive"
|
|
9
|
-
|
|
10
|
-
# @api private
|
|
11
|
-
def initialize(call_fn)
|
|
12
|
-
@call = call_fn
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# List files in the user's Drive.
|
|
16
|
-
#
|
|
17
|
-
# @param query [String, nil] Drive search query (Google Drive API query syntax)
|
|
18
|
-
# @param max_results [Integer, nil] maximum number of files to return
|
|
19
|
-
# @param folder_id [String, nil] restrict to files within a specific folder
|
|
20
|
-
# @return [Hash] hash with "files" list
|
|
21
|
-
def list_files(query: nil, max_results: nil, folder_id: nil)
|
|
22
|
-
params = {}
|
|
23
|
-
params["query"] = query if query
|
|
24
|
-
params["maxResults"] = max_results if max_results
|
|
25
|
-
params["folderId"] = folder_id if folder_id
|
|
26
|
-
@call.call(PROVIDER, "list-files", params)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Get file metadata by ID.
|
|
30
|
-
#
|
|
31
|
-
# @param file_id [String] the file identifier
|
|
32
|
-
# @return [Hash] the file metadata object
|
|
33
|
-
def get_file(file_id)
|
|
34
|
-
@call.call(PROVIDER, "get-file", { "fileId" => file_id })
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Search files using a query string.
|
|
38
|
-
#
|
|
39
|
-
# @param query [String] search query (Google Drive API query syntax)
|
|
40
|
-
# @param max_results [Integer, nil] maximum number of results
|
|
41
|
-
# @return [Hash] hash with "files" list
|
|
42
|
-
def search_files(query, max_results: nil)
|
|
43
|
-
params = { "query" => query }
|
|
44
|
-
params["maxResults"] = max_results if max_results
|
|
45
|
-
@call.call(PROVIDER, "search-files", params)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
data/lib/leash/gmail.rb
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Leash
|
|
4
|
-
# Client for Gmail operations via the Leash platform proxy.
|
|
5
|
-
#
|
|
6
|
-
# Not instantiated directly -- use {Integrations#gmail} instead.
|
|
7
|
-
class GmailClient
|
|
8
|
-
PROVIDER = "gmail"
|
|
9
|
-
|
|
10
|
-
# @api private
|
|
11
|
-
def initialize(call_fn)
|
|
12
|
-
@call = call_fn
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# List messages in the user's mailbox.
|
|
16
|
-
#
|
|
17
|
-
# @param query [String, nil] Gmail search query (e.g. "from:user@example.com")
|
|
18
|
-
# @param max_results [Integer] maximum number of messages to return
|
|
19
|
-
# @param label_ids [Array<String>, nil] filter by label IDs (e.g. ["INBOX"])
|
|
20
|
-
# @param page_token [String, nil] token for fetching the next page of results
|
|
21
|
-
# @return [Hash] hash with "messages", "nextPageToken", and "resultSizeEstimate"
|
|
22
|
-
def list_messages(query: nil, max_results: 20, label_ids: nil, page_token: nil)
|
|
23
|
-
params = { "maxResults" => max_results }
|
|
24
|
-
params["query"] = query if query
|
|
25
|
-
params["labelIds"] = label_ids if label_ids
|
|
26
|
-
params["pageToken"] = page_token if page_token
|
|
27
|
-
@call.call(PROVIDER, "list-messages", params)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Get a single message by ID.
|
|
31
|
-
#
|
|
32
|
-
# @param message_id [String] the message ID
|
|
33
|
-
# @param format [String] response format ("full", "metadata", "minimal", "raw")
|
|
34
|
-
# @return [Hash] the full message object
|
|
35
|
-
def get_message(message_id, format: "full")
|
|
36
|
-
@call.call(PROVIDER, "get-message", { "messageId" => message_id, "format" => format })
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Send an email message.
|
|
40
|
-
#
|
|
41
|
-
# @param to [String] recipient email address
|
|
42
|
-
# @param subject [String] email subject line
|
|
43
|
-
# @param body [String] email body text
|
|
44
|
-
# @param cc [String, nil] CC recipient(s)
|
|
45
|
-
# @param bcc [String, nil] BCC recipient(s)
|
|
46
|
-
# @return [Hash] the sent message metadata
|
|
47
|
-
def send_message(to:, subject:, body:, cc: nil, bcc: nil)
|
|
48
|
-
params = { "to" => to, "subject" => subject, "body" => body }
|
|
49
|
-
params["cc"] = cc if cc
|
|
50
|
-
params["bcc"] = bcc if bcc
|
|
51
|
-
@call.call(PROVIDER, "send-message", params)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Search messages using a Gmail query string.
|
|
55
|
-
#
|
|
56
|
-
# @param query [String] Gmail search query
|
|
57
|
-
# @param max_results [Integer] maximum number of results to return
|
|
58
|
-
# @return [Hash] hash with "messages", "nextPageToken", and "resultSizeEstimate"
|
|
59
|
-
def search_messages(query, max_results: 20)
|
|
60
|
-
@call.call(PROVIDER, "search-messages", { "query" => query, "maxResults" => max_results })
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# List all labels in the user's mailbox.
|
|
64
|
-
#
|
|
65
|
-
# @return [Hash] hash with "labels" list
|
|
66
|
-
def list_labels
|
|
67
|
-
@call.call(PROVIDER, "list-labels", {})
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|