microslop_one_drive 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bf99630f0f09cb4d635d7881c2db5b0d53af498f33b32724b1522d10cd464985
4
+ data.tar.gz: a5111efbd38ae81fe7d06524461bade0fe49761a82dccad1747f09c8ae0c751b
5
+ SHA512:
6
+ metadata.gz: 2d683dcebe786a18941e751f0e8f9fa5962d266e9eb69e1ceadcafa1c710a563de06b3ee7153ef4cf0350658c0b735bb55e1ea45a5f6071212c66339696514c5
7
+ data.tar.gz: a2141155fc90fdc9c07bb7b725ee43d130d0e8e4e320193840a013621b0c1d0b6b901d5cd1d9df72e2635aab33514760473a39ab246630c52654ee56a5f82c97
data/LICENSE.txt ADDED
@@ -0,0 +1 @@
1
+ Proprietary for now
data/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # MicroslopOneDrive
2
+
3
+ Microslop OneDrive API client.
4
+
5
+ See <https://learn.microsoft.com/en-us/onedrive/developer/rest-api/>
6
+
7
+ Graph explorer (API sandbox): <https://developer.microsoft.com/en-us/graph/graph-explorer>
8
+
9
+ ## Installation
10
+
11
+ ```rb
12
+ TODO: DOCUMENT
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Create a client
18
+
19
+ ```rb
20
+ access_token = "..." # Get an access token via OAuth 2.0
21
+
22
+ client = MicroslopOneDrive::Client.new(access_token)
23
+ ```
24
+
25
+ ### Get the current user
26
+
27
+ ```rb
28
+ me = client.me
29
+ me.class # => MicroslopOneDrive::User
30
+ me.email_address # => person@example.com
31
+ me.display_name # => Example Person
32
+ ```
33
+
34
+ ### Get a list of the user's Drives
35
+
36
+ ```rb
37
+ drive_list = client.drives
38
+
39
+ drive_list.class # => MicroslopOneDrive::DriveList
40
+ drive_list.next_page? # => false
41
+ drive_list.drives # => [MicroslopOneDrive::Drive, ...]
42
+
43
+ drive = drive_list.drives.first
44
+ drive.class # => MicroslopOneDrive::Drive
45
+ drive.id # => "0f0**********42"
46
+ drive.name # => "OneDrive"
47
+ drive.url # => "https://my.microsoftpersonalcontent.com/..."
48
+ drive.drive_type # => "personal"
49
+ ```
50
+
51
+ ### Get a single Drive
52
+
53
+ ```rb
54
+ drive = client.drive(drive_id: "0f097********a42")
55
+
56
+ drive.class # => MicroslopOneDrive::Drive
57
+ drive.id # => "0f097********a42"
58
+ drive.name # => "OneDrive"
59
+ drive.url # => "https://my.microsoftpersonalcontent.com/personal/..."
60
+ drive.drive_type # => "personal"
61
+ ```
62
+
63
+ ### Get a delta of changes to a Drive
64
+
65
+ ```rb
66
+ # Initial delta (all current items + token for later)
67
+ drive_item_list = client.delta(drive_id: "0f097********a42")
68
+
69
+ drive_item_list.class # => MicroslopOneDrive::DriveItemList
70
+ drive_item_list.items # => [MicroslopOneDrive::DriveItem, ...]
71
+
72
+ drive_item_list.next_page? # => true if more pages
73
+ drive_item_list.next_token # => use with delta(drive_id:, token:) for next page
74
+ drive_item_list.delta_link # => URL for incremental sync (when no next_page?)
75
+ drive_item_list.delta_token # => use with delta(drive_id:, token:) for incremental sync
76
+
77
+ # Next page (if next_page? was true)
78
+ client.delta(drive_id: "0f097********a42", token: drive_item_list.next_token)
79
+
80
+ # Incremental sync (only changes since last delta)
81
+ client.delta(drive_id: "0f097********a42", token: saved_delta_token)
82
+ ```
83
+
84
+ Delta items have parent/child set: `item.parent`, `item.children`, and `item.path` (e.g. `"root:/folder/subfolder/file.txt"`).
85
+
86
+ ### Get a DriveItem (file or folder)
87
+
88
+ ```rb
89
+ item = client.drive_item(item_id: "F0**********42!sa466********************1479272d27")
90
+
91
+ item.class # => MicroslopOneDrive::DriveItem
92
+ item.name # => "Getting started with OneDrive.pdf"
93
+ item.identifier # => "F0**********42!sa466********************1479272d27"
94
+ item.url # => "https://onedrive.live.com?cid=..."
95
+ item.file? # => true
96
+ item.folder? # => false
97
+ item.mime_type # => "application/pdf"
98
+ item.size # => 1053417
99
+ item.created_at # => 2026-02-19 07:35:52 UTC
100
+ item.updated_at # => 2026-02-19 07:35:52 UTC
101
+ item.parent_identifier # => "F0**********42!sea8cc6b********************5c639"
102
+ item.deleted? # => false
103
+ item.shared? # => true if the item has sharing info
104
+ item.path # => "root:/Documents/Getting started with OneDrive.pdf" (from delta only; nil for single item)
105
+ item.is_root? # => true for root folder
106
+ ```
107
+
108
+ ### Check if a DriveItem exists
109
+
110
+ ```rb
111
+ client.item_exists?(item_id: "F0**********42!sa466********************1479272d27") # => true
112
+ client.item_exists?(item_id: "F0**********42!not-an-item-id") # => false
113
+ ```
114
+
115
+ ### Get permissions for a DriveItem
116
+
117
+ ```rb
118
+ permission_list = client.permissions(item_id: "F0**********42!sa466********************1479272d27")
119
+ permission_list.class # => MicroslopOneDrive::PermissionList
120
+ permission_list.permissions # => [MicroslopOneDrive::Permission, ...]
121
+
122
+ permission = permission_list.permissions.first
123
+ permission.role # => "write" or "owner" etc.
124
+ permission.audience.type # => "user" or "anyone"
125
+ permission.audience.identifier # => email for user, "anyone_with_the_link" for link
126
+ permission.audience.display_name # => "Amy Smith"
127
+ permission.audience.email_address # => "amy@example.com" (nil for "anyone with the link")
128
+ ```
129
+
130
+ Returns an empty permission list if the item does not exist (404).
131
+
132
+ ## Contributing
133
+
134
+ ### Setup
135
+
136
+ ```sh
137
+ mise init
138
+ bundle install
139
+ ```
140
+
141
+ ### Running tests
142
+
143
+ ```sh
144
+ bundle exec rake test
145
+ ```
146
+
147
+ ## Building and publishing
148
+
149
+ ```sh
150
+ # Signin if not already:
151
+ gem signin
152
+
153
+ # Bump version in lib/microslop_one_drive/version.rb
154
+
155
+ # Then build:
156
+ gem build microslop_drive.gemspec
157
+
158
+
159
+ gem push microslop_one_drive-0.1.0.gem
160
+ ```
@@ -0,0 +1,32 @@
1
+ module MicroslopOneDrive
2
+ class Audience
3
+ attr_reader :type, :identifier, :display_name, :email_address
4
+
5
+ def initialize(type:, identifier:, display_name:, email_address: nil)
6
+ @type = type
7
+ @identifier = identifier
8
+ @display_name = display_name
9
+ @email_address = email_address
10
+ end
11
+
12
+ # Converts a "siteUser" object into an OneDriveAudience object.
13
+ #
14
+ # A siteUser object looks like this:
15
+ #
16
+ # {
17
+ # "displayName" => "Bob Bentley",
18
+ # "email" => "bob@haikucode.dev",
19
+ # "id" => "12",
20
+ # "loginName" => "i:0#.f|membership|bob@haikucode.dev"
21
+ # }
22
+ #
23
+ def self.from_site_user(site_user)
24
+ new(
25
+ type: "user",
26
+ identifier: site_user.fetch("email"),
27
+ display_name: site_user.fetch("displayName"),
28
+ email_address: site_user.fetch("email")
29
+ )
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,113 @@
1
+ module MicroslopOneDrive
2
+ class Client
3
+ BASE_URL = "https://graph.microsoft.com/v1.0".freeze
4
+
5
+ def initialize(access_token)
6
+ @access_token = access_token
7
+
8
+ @headers = {
9
+ "Authorization" => "Bearer #{@access_token}",
10
+ "Content-Type" => "application/json",
11
+ "Prefer" => "hierarchicalsharing"
12
+ }
13
+ end
14
+
15
+ # Gets the current user
16
+ #
17
+ # @return [MicroslopOneDrive::User]
18
+ def me
19
+ response = get(path: "me", query: {})
20
+ handle_error(response) unless response.success?
21
+ MicroslopOneDrive::User.new(response.parsed_response)
22
+ end
23
+
24
+ # Gets all Drives the current user has access to.
25
+ #
26
+ # NOTE: This will include some internal Microsoft drives that aren't real drives, such as AI, Face scans, and other
27
+ # shitty things.
28
+ #
29
+ # @return [MicroslopOneDrive::DriveList]
30
+ def drives
31
+ response = get(path: "me/drives", query: {})
32
+ handle_error(response) unless response.success?
33
+ MicroslopOneDrive::DriveList.new(response.parsed_response)
34
+ end
35
+
36
+ # Gets a specific Drive by its ID.
37
+ #
38
+ # @param drive_id [String] The ID of the Drive to get.
39
+ #
40
+ # @return [MicroslopOneDrive::Drive]
41
+ def drive(drive_id:)
42
+ response = get(path: "me/drives/#{drive_id}", query: {})
43
+ handle_error(response) unless response.success?
44
+ MicroslopOneDrive::Drive.new(response.parsed_response)
45
+ end
46
+
47
+ # Gets a specific DriveItem (folder or file) by its ID.
48
+ #
49
+ # @param item_id [String] The ID of the Drive Item to get.
50
+ #
51
+ # @return [MicroslopOneDrive::DriveItem]
52
+ def drive_item(item_id:)
53
+ response = get(path: "me/drive/items/#{item_id}", query: {})
54
+ handle_error(response) unless response.success?
55
+ MicroslopOneDrive::DriveItem.new(response.parsed_response)
56
+ end
57
+
58
+ # Asks if a DriveItem (folder or file) exists by its ID.
59
+ #
60
+ # @param item_id [String] The ID of the Drive Item to check.
61
+ #
62
+ # @return [Boolean]
63
+ def item_exists?(item_id:)
64
+ response = get(path: "me/drive/items/#{item_id}", query: {})
65
+
66
+ return false if response.code == 404
67
+ return true if response.success?
68
+
69
+ handle_error(response)
70
+ end
71
+
72
+ # Gets a delta of changes to a Drive.
73
+ #
74
+ # @param drive_id [String] The ID of the Drive to get the delta of.
75
+ # @param token [String] The token to use for the delta. If not provided, the initial delta will be returned.
76
+ #
77
+ # @return [MicroslopOneDrive::DriveItemList]
78
+ def delta(drive_id:, token: nil)
79
+ response = get(path: "me/drives/#{drive_id}/root/delta", query: {token: token})
80
+ handle_error(response) unless response.success?
81
+ MicroslopOneDrive::DriveItemList.new(response.parsed_response)
82
+ end
83
+
84
+ # Gets the permissions for a DriveItem (folder or file).
85
+ #
86
+ # @param item_id [String] The ID of the Drive Item to get the permissions of.
87
+ #
88
+ # @return [MicroslopOneDrive::PermissionList]
89
+ def permissions(item_id:)
90
+ response = get(path: "me/drive/items/#{item_id}/permissions", query: {})
91
+
92
+ return MicroslopOneDrive::PermissionList.new("value" => []) if response.code == 404
93
+
94
+ handle_error(response) unless response.success?
95
+ MicroslopOneDrive::PermissionList.new(response.parsed_response)
96
+ end
97
+
98
+ private
99
+
100
+ def get(path:, query: {})
101
+ response = HTTParty.get("#{BASE_URL}/#{path}", headers: @headers, query: query)
102
+
103
+ @debug_response_writer&.call(path, response.parsed_response)
104
+
105
+ response
106
+ end
107
+
108
+ def handle_error(response)
109
+ error = MicroslopOneDrive::Errors::ClientError.new(response.parsed_response, response.code)
110
+ raise error
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,14 @@
1
+ module MicroslopOneDrive
2
+ class Drive
3
+ attr_reader :id, :name, :url, :drive_type
4
+
5
+ def initialize(drive_hash)
6
+ @drive_hash = drive_hash
7
+
8
+ @id = drive_hash.fetch("id", nil)
9
+ @name = drive_hash.fetch("name", nil)
10
+ @url = drive_hash.fetch("webUrl", nil)
11
+ @drive_type = drive_hash.fetch("driveType", nil)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,99 @@
1
+ module MicroslopOneDrive
2
+ class DriveItem
3
+ DIRECTORY_MIME_TYPE = "inode/directory".freeze
4
+
5
+ attr_reader :identifier,
6
+ :name,
7
+ :created_at,
8
+ :updated_at,
9
+ :url,
10
+ :size,
11
+ :file_or_folder,
12
+ :parent_identifier,
13
+ :mime_type,
14
+ :parent,
15
+ :children,
16
+ :path,
17
+ :full_path
18
+
19
+ def initialize(item_hash)
20
+ @item_hash = item_hash
21
+
22
+ @identifier = @item_hash.fetch("id", nil)
23
+ @name = @item_hash.fetch("name", nil)
24
+ @url = @item_hash.fetch("webUrl", nil)
25
+ @size = @item_hash.fetch("size", nil)
26
+
27
+ @created_at = Utils.safe_parse_time(@item_hash.fetch("createdDateTime", nil))
28
+ @updated_at = Utils.safe_parse_time(@item_hash.fetch("lastModifiedDateTime", nil))
29
+
30
+ if @item_hash.key?("file")
31
+ @file_or_folder = :file
32
+ @mime_type = @item_hash.dig("file", "mimeType")
33
+ elsif @item_hash.key?("folder")
34
+ @file_or_folder = :folder
35
+ @mime_type = DIRECTORY_MIME_TYPE
36
+ end
37
+
38
+ @parent_identifier = @item_hash.dig("parentReference", "id")
39
+
40
+ @deleted = @item_hash.dig("deleted", "state") == "deleted"
41
+
42
+ @path = build_path
43
+
44
+ @parent = nil
45
+ @children = []
46
+ end
47
+
48
+ def deleted?
49
+ @deleted
50
+ end
51
+
52
+ def shared?
53
+ @item_hash.key?("shared")
54
+ end
55
+
56
+ def file?
57
+ @file_or_folder == :file
58
+ end
59
+
60
+ def folder?
61
+ @file_or_folder == :folder
62
+ end
63
+
64
+ def set_parent(parent)
65
+ if @parent
66
+ @parent.remove_child(self)
67
+ end
68
+
69
+ @parent = parent
70
+ @parent.add_child(self)
71
+ end
72
+
73
+ def is_root?
74
+ @item_hash.key?("root")
75
+ end
76
+
77
+ protected
78
+
79
+ def add_child(child)
80
+ @children << child
81
+ end
82
+
83
+ def remove_child(child)
84
+ @children.delete(child)
85
+ end
86
+
87
+ private
88
+
89
+ def build_path
90
+ return "root:" if is_root?
91
+
92
+ full_parent_path = @item_hash.dig("parentReference", "path")
93
+ return nil if full_parent_path.nil?
94
+
95
+ full_path_with_name = File.join(full_parent_path, @name)
96
+ full_path_with_name.sub(/\A.*root:\//, "root:/")
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,32 @@
1
+ module MicroslopOneDrive
2
+ class DriveItemList < ListResponse
3
+ attr_reader :items
4
+
5
+ def initialize(parsed_response)
6
+ super(parsed_response)
7
+
8
+ @parsed_response = parsed_response
9
+ @items = build_items
10
+ end
11
+
12
+ private
13
+
14
+ def build_items
15
+ items = @parsed_response.fetch("value", []).map do
16
+ MicroslopOneDrive::DriveItem.new(it)
17
+ end
18
+
19
+ set_parent_and_child_relationships(items)
20
+ end
21
+
22
+ def set_parent_and_child_relationships(items)
23
+ items.each do |item|
24
+ next if item.parent_identifier.nil?
25
+ parent = items.find { it.identifier == item.parent_identifier }
26
+ next if parent.nil?
27
+
28
+ item.set_parent(parent)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ module MicroslopOneDrive
2
+ class DriveList < ListResponse
3
+ attr_reader :drives
4
+
5
+ def initialize(response_hash)
6
+ super(response_hash)
7
+
8
+ @drives = response_hash.fetch("value", []).map do
9
+ MicroslopOneDrive::Drive.new(it)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module MicroslopOneDrive
2
+ module Errors
3
+ class ClientError < StandardError
4
+ attr_reader :response_body, :response_code
5
+
6
+ def initialize(response_body, response_code)
7
+ super(response_body)
8
+ @response_body = response_body
9
+ @response_code = response_code
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module MicroslopOneDrive
2
+ class ListResponse
3
+ attr_reader :next_link, :next_token, :delta_link, :delta_token
4
+
5
+ def initialize(response_hash)
6
+ @response_hash = response_hash
7
+
8
+ @next_link = response_hash.fetch("@odata.nextLink", nil)
9
+ @next_token = @next_link.split("?token=").last if @next_link && !@next_link.empty?
10
+
11
+ @delta_link = response_hash.fetch("@odata.deltaLink", nil)
12
+ @delta_token = @delta_link.split("?token=").last if @delta_link && !@delta_link.empty?
13
+ end
14
+
15
+ def next_page?
16
+ !next_link.nil?
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module MicroslopOneDrive
2
+ class Permission
3
+ attr_reader :identifier, :role, :audience
4
+
5
+ def initialize(identifier:, role:, audience:)
6
+ @identifier = identifier
7
+ @role = role
8
+ @audience = audience
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,60 @@
1
+ module MicroslopOneDrive
2
+ class PermissionBatch
3
+ attr_reader :identifier, :role, :audiences
4
+
5
+ def initialize(parsed_response)
6
+ @parsed_response = parsed_response
7
+
8
+ @identifier = @parsed_response.fetch("id", nil)
9
+ @role = build_role
10
+ @audiences = build_audiences
11
+ end
12
+
13
+ def to_permissions
14
+ @audiences.map { Permission.new(identifier: @identifier, role: @role, audience: it) }
15
+ end
16
+
17
+ private
18
+
19
+ def build_role
20
+ roles = @parsed_response.fetch("roles", [])
21
+ roles.is_a?(Array) ? roles.first : roles
22
+ end
23
+
24
+ def build_audiences
25
+ audiences = []
26
+
27
+ audiences += audiences_from_site_users
28
+ audiences += audiences_from_anonymous_links
29
+
30
+ audiences.compact
31
+ end
32
+
33
+ def audiences_from_site_users
34
+ site_users = []
35
+ site_users += @parsed_response.fetch("grantedToIdentitiesV2", []).flat_map { it.fetch("siteUser", nil) }
36
+ site_users << @parsed_response.dig("grantedToV2", "siteUser")
37
+ site_users.compact!
38
+
39
+ site_users.map { Audience.from_site_user(it) }
40
+ end
41
+
42
+ def audiences_from_anonymous_links
43
+ link = @parsed_response.fetch("link", nil)
44
+ return [] if link.nil? || (link.respond_to?(:empty?) && link.empty?)
45
+
46
+ link_scope = link.fetch("scope", nil)
47
+
48
+ return [] unless link_scope == "anonymous" # I.e. an "anyone with the link" audience
49
+
50
+ [
51
+ Audience.new(
52
+ type: "anyone",
53
+ identifier: "anyone_with_the_link",
54
+ display_name: "Anyone with the link",
55
+ email_address: nil
56
+ )
57
+ ]
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ module MicroslopOneDrive
2
+ class PermissionList < ListResponse
3
+ attr_reader :permissions
4
+
5
+ def initialize(parsed_response)
6
+ super(parsed_response)
7
+
8
+ @parsed_response = parsed_response
9
+ @permissions = build_permissions
10
+ end
11
+
12
+ private
13
+
14
+ def build_permissions
15
+ value_list = @parsed_response.is_a?(Array) ? @parsed_response : @parsed_response.fetch("value", [])
16
+ permission_batches = value_list.map { MicroslopOneDrive::PermissionBatch.new(it) }
17
+
18
+ # At this stage, the permissions could contain multiple Audiences for the same Permission.
19
+ # This is because OneDrive can return multiple permissions for the same thing.
20
+ # For example, a file shared with one person and a public link will return in a single permission object.
21
+ # We therefore need to "explode" the permissions into multiple permissions, one for each Audience.
22
+ permission_batches.flat_map(&:to_permissions)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ module MicroslopOneDrive
2
+ class User
3
+ attr_reader :email_address, :display_name
4
+
5
+ def initialize(user_hash)
6
+ @user_hash = user_hash
7
+
8
+ @email_address = @user_hash.fetch("mail", nil)
9
+ @display_name = @user_hash.fetch("displayName", nil)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require "time"
2
+
3
+ module MicroslopOneDrive
4
+ module Utils
5
+ def self.safe_parse_time(value)
6
+ return nil if value.nil? || value.to_s.strip.empty?
7
+
8
+ Time.parse(value)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module MicroslopOneDrive
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,17 @@
1
+ require "httparty"
2
+ require "json"
3
+
4
+ require_relative "microslop_one_drive/version"
5
+ require_relative "microslop_one_drive/utils"
6
+ require_relative "microslop_one_drive/errors/client_error"
7
+ require_relative "microslop_one_drive/user"
8
+ require_relative "microslop_one_drive/list_response"
9
+ require_relative "microslop_one_drive/drive_list"
10
+ require_relative "microslop_one_drive/drive"
11
+ require_relative "microslop_one_drive/drive_item"
12
+ require_relative "microslop_one_drive/drive_item_list"
13
+ require_relative "microslop_one_drive/permission_list"
14
+ require_relative "microslop_one_drive/permission_batch"
15
+ require_relative "microslop_one_drive/permission"
16
+ require_relative "microslop_one_drive/audience"
17
+ require_relative "microslop_one_drive/client"
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: microslop_one_drive
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Bradley Marques
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: httparty
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.24'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.24'
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'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '5'
40
+ - !ruby/object:Gem::Dependency
41
+ name: mocha
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '13'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rubocop
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1'
82
+ description: Lightweight value objects and HTTP client for OneDrive delta sync, item
83
+ metadata, and sharing permissions.
84
+ email:
85
+ - ''
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - LICENSE.txt
91
+ - README.md
92
+ - lib/microslop_one_drive.rb
93
+ - lib/microslop_one_drive/audience.rb
94
+ - lib/microslop_one_drive/client.rb
95
+ - lib/microslop_one_drive/drive.rb
96
+ - lib/microslop_one_drive/drive_item.rb
97
+ - lib/microslop_one_drive/drive_item_list.rb
98
+ - lib/microslop_one_drive/drive_list.rb
99
+ - lib/microslop_one_drive/errors/client_error.rb
100
+ - lib/microslop_one_drive/list_response.rb
101
+ - lib/microslop_one_drive/permission.rb
102
+ - lib/microslop_one_drive/permission_batch.rb
103
+ - lib/microslop_one_drive/permission_list.rb
104
+ - lib/microslop_one_drive/user.rb
105
+ - lib/microslop_one_drive/utils.rb
106
+ - lib/microslop_one_drive/version.rb
107
+ homepage: https://github.com/bradleymarques/microslop_one_drive
108
+ licenses:
109
+ - MIT
110
+ metadata:
111
+ homepage_uri: https://github.com/bradleymarques/microslop_one_drive
112
+ source_code_uri: https://github.com/bradleymarques/microslop_one_drive
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 3.4.2
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.7.2
128
+ specification_version: 4
129
+ summary: Ruby client helpers for Microsoft Graph OneDrive/SharePoint API (drive items,
130
+ delta, permissions).
131
+ test_files: []