prusalink 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +170 -0
- data/lib/prusalink/auto_initializable.rb +224 -0
- data/lib/prusalink/base_resource.rb +92 -0
- data/lib/prusalink/client.rb +190 -0
- data/lib/prusalink/deserializable.rb +491 -0
- data/lib/prusalink/digest_auth.rb +80 -0
- data/lib/prusalink/exceptions.rb +36 -0
- data/lib/prusalink/files/file.rb +87 -0
- data/lib/prusalink/files/folder.rb +84 -0
- data/lib/prusalink/files/refs.rb +36 -0
- data/lib/prusalink/files.rb +184 -0
- data/lib/prusalink/info.rb +82 -0
- data/lib/prusalink/job/file.rb +70 -0
- data/lib/prusalink/job.rb +191 -0
- data/lib/prusalink/server_version.rb +70 -0
- data/lib/prusalink/status/camera.rb +26 -0
- data/lib/prusalink/status/job.rb +41 -0
- data/lib/prusalink/status/printer.rb +136 -0
- data/lib/prusalink/status/storage.rb +40 -0
- data/lib/prusalink/status/transfer.rb +40 -0
- data/lib/prusalink/status.rb +64 -0
- data/lib/prusalink/storage.rb +87 -0
- data/lib/prusalink/transfer.rb +108 -0
- data/lib/prusalink/types.rb +27 -0
- data/lib/prusalink/version.rb +7 -0
- data/lib/prusalink.rb +77 -0
- data/lib/tapioca/dsl/compilers/auto_initializable.rb +88 -0
- metadata +158 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# The printer's current file transfer (upload or download).
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# transfer = Prusalink::Transfer.get # => nil when nothing is transferring
|
|
9
|
+
# transfer.transfer_type # => "FROM_WEB"
|
|
10
|
+
# transfer.progress # => 42.25
|
|
11
|
+
# transfer.stop
|
|
12
|
+
class Transfer < BaseResource
|
|
13
|
+
extend T::Sig
|
|
14
|
+
include AutoInitializable
|
|
15
|
+
include Deserializable
|
|
16
|
+
|
|
17
|
+
resource_path("/api/v1/transfer")
|
|
18
|
+
|
|
19
|
+
# @!attribute [r] id
|
|
20
|
+
# @return [Integer, nil] The transfer's id. Not documented in the API's Transfer schema, so it may be
|
|
21
|
+
# absent; {Status#transfer} always includes it.
|
|
22
|
+
auto_attr :id, type: Integer
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] transfer_type
|
|
25
|
+
# @return [String] The transfer's source/destination: "NO_TRANSFER", "FROM_WEB", "FROM_CONNECT",
|
|
26
|
+
# "FROM_PRINTER", "FROM_SLICER", "FROM_CLIENT", "TO_CONNECT" or "TO_CLIENT".
|
|
27
|
+
# Renamed from the API's `type` field.
|
|
28
|
+
auto_attr :transfer_type, type: String
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] display_name
|
|
31
|
+
# @return [String] Long filename of the transferred file
|
|
32
|
+
auto_attr :display_name, type: String
|
|
33
|
+
|
|
34
|
+
# @!attribute [r] path
|
|
35
|
+
# @return [String] Destination path, e.g. "/local"
|
|
36
|
+
auto_attr :path, type: String
|
|
37
|
+
|
|
38
|
+
# @!attribute [r] url
|
|
39
|
+
# @return [String, nil] Source URL, for downloads
|
|
40
|
+
auto_attr :url, type: String
|
|
41
|
+
|
|
42
|
+
# @!attribute [r] size
|
|
43
|
+
# @return [Integer, nil] Total size in bytes
|
|
44
|
+
auto_attr :size, type: Integer
|
|
45
|
+
|
|
46
|
+
# @!attribute [r] progress
|
|
47
|
+
# @return [Float] Completion, in percent
|
|
48
|
+
auto_attr :progress, type: Float
|
|
49
|
+
|
|
50
|
+
# @!attribute [r] transferred
|
|
51
|
+
# @return [Integer] Transferred data, in bytes
|
|
52
|
+
auto_attr :transferred, type: Integer
|
|
53
|
+
|
|
54
|
+
# @!attribute [r] time_remaining
|
|
55
|
+
# @return [Integer, nil] Estimated time left, in seconds
|
|
56
|
+
auto_attr :time_remaining, type: Integer
|
|
57
|
+
|
|
58
|
+
# @!attribute [r] time_transferring
|
|
59
|
+
# @return [Integer] Time spent transferring, in seconds
|
|
60
|
+
auto_attr :time_transferring, type: Integer
|
|
61
|
+
|
|
62
|
+
# @!attribute [r] to_print
|
|
63
|
+
# @return [Boolean] Whether the file will be printed once the transfer finishes
|
|
64
|
+
auto_attr :to_print, type: T::Boolean
|
|
65
|
+
|
|
66
|
+
# @!attribute [r] extra
|
|
67
|
+
# @return [Hash] Any additional fields returned by the API
|
|
68
|
+
auto_attr :extra, type: Hash
|
|
69
|
+
|
|
70
|
+
auto_initialize!
|
|
71
|
+
|
|
72
|
+
deserialize_config do
|
|
73
|
+
rename type: :transfer_type
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Retrieve the current transfer.
|
|
77
|
+
#
|
|
78
|
+
# @return [Transfer, nil] nil when nothing is transferring (the printer answers 204 No Content)
|
|
79
|
+
# @raise [Prusalink::Exceptions::Error] if the request fails
|
|
80
|
+
sig { returns(T.nilable(Transfer)) }
|
|
81
|
+
def self.get
|
|
82
|
+
fetch_resource
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Stop the transfer with the given id.
|
|
86
|
+
#
|
|
87
|
+
# @param id [Integer] The transfer's id
|
|
88
|
+
# @return [Boolean] true on success
|
|
89
|
+
# @raise [Prusalink::Exceptions::NotFoundError] if no transfer has this id
|
|
90
|
+
# @raise [Prusalink::Exceptions::ConflictError] if the transfer can't be stopped
|
|
91
|
+
sig { params(id: Integer).returns(T::Boolean) }
|
|
92
|
+
def self.stop(id)
|
|
93
|
+
delete(path: "/api/v1/transfer/#{id}")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Stop this transfer. See {Transfer.stop}.
|
|
97
|
+
#
|
|
98
|
+
# @return [Boolean] true on success
|
|
99
|
+
# @raise [ArgumentError] if the printer didn't report the transfer's id
|
|
100
|
+
sig { returns(T::Boolean) }
|
|
101
|
+
def stop
|
|
102
|
+
transfer_id = id
|
|
103
|
+
raise ArgumentError, "This transfer has no id. Use Transfer.stop with Status#transfer's id" if transfer_id.nil?
|
|
104
|
+
|
|
105
|
+
self.class.stop(transfer_id)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Prusalink
|
|
5
|
+
# Common type aliases for use with auto_attr and Sorbet signatures.
|
|
6
|
+
module Types
|
|
7
|
+
# A hash with symbol keys and untyped values (common for API responses)
|
|
8
|
+
Hash = T::Hash[Symbol, T.untyped]
|
|
9
|
+
|
|
10
|
+
# A boolean type (true or false)
|
|
11
|
+
Boolean = T.any(TrueClass, FalseClass)
|
|
12
|
+
|
|
13
|
+
# A nullable boolean (true, false or nil)
|
|
14
|
+
NilableBoolean = T.nilable(T.any(TrueClass, FalseClass))
|
|
15
|
+
|
|
16
|
+
# A number that PrusaLink may send as an integer or a float
|
|
17
|
+
Number = T.any(Integer, Float)
|
|
18
|
+
|
|
19
|
+
# Printer states reported by /api/v1/status
|
|
20
|
+
# IDLE, BUSY, PRINTING, PAUSED, FINISHED, STOPPED, ERROR, ATTENTION, READY
|
|
21
|
+
PrinterState = String
|
|
22
|
+
|
|
23
|
+
# Job states reported by /api/v1/job
|
|
24
|
+
# PRINTING, PAUSED, FINISHED, STOPPED, ERROR
|
|
25
|
+
JobState = String
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/prusalink.rb
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "active_support/all"
|
|
5
|
+
require "zeitwerk"
|
|
6
|
+
require "sorbet-runtime"
|
|
7
|
+
|
|
8
|
+
loader = Zeitwerk::Loader.for_gem
|
|
9
|
+
loader.ignore("#{__dir__}/tapioca")
|
|
10
|
+
loader.setup
|
|
11
|
+
|
|
12
|
+
# Load Tapioca compiler if available
|
|
13
|
+
require_relative "tapioca/dsl/compilers/auto_initializable" if defined?(Tapioca)
|
|
14
|
+
|
|
15
|
+
# Ruby client for PrusaLink, the local REST API of Prusa 3D printers.
|
|
16
|
+
#
|
|
17
|
+
# @example Configure the gem once, then call resources
|
|
18
|
+
# Prusalink.configure(host: "http://prusa-mk4.local", password: "from-the-printer-screen")
|
|
19
|
+
# Prusalink::Status.get.printer.state # => "PRINTING"
|
|
20
|
+
#
|
|
21
|
+
# @attr [Prusalink::Client] client The configured API client
|
|
22
|
+
module Prusalink
|
|
23
|
+
class << self
|
|
24
|
+
extend T::Sig
|
|
25
|
+
|
|
26
|
+
# Configure the API client with the printer's address and credentials.
|
|
27
|
+
#
|
|
28
|
+
# PrusaLink uses HTTP Digest authentication. The username is "maker" by default and the
|
|
29
|
+
# password is shown on the printer (Settings > Network > PrusaLink). Older firmware uses an
|
|
30
|
+
# API key instead: pass `api_key:` and leave the password out.
|
|
31
|
+
#
|
|
32
|
+
# @example Digest authentication (current firmware)
|
|
33
|
+
# Prusalink.configure(host: "http://192.168.1.42", password: "s3cr3t")
|
|
34
|
+
#
|
|
35
|
+
# @example API key (older firmware)
|
|
36
|
+
# Prusalink.configure(host: "http://192.168.1.42", api_key: "abcdef")
|
|
37
|
+
#
|
|
38
|
+
# @param [String] host Printer's address
|
|
39
|
+
# @param [String, nil] password PrusaLink password (Digest auth)
|
|
40
|
+
# @param [String] username PrusaLink username (Digest auth)
|
|
41
|
+
# @param [String, nil] api_key PrusaLink API key (older firmware)
|
|
42
|
+
# @param [Numeric, nil] open_timeout Seconds to wait for the connection to open
|
|
43
|
+
# @param [Numeric, nil] timeout Seconds to wait for a read or a write
|
|
44
|
+
# @return [nil]
|
|
45
|
+
sig do
|
|
46
|
+
params(
|
|
47
|
+
host: String,
|
|
48
|
+
password: T.nilable(String),
|
|
49
|
+
username: String,
|
|
50
|
+
api_key: T.nilable(String),
|
|
51
|
+
open_timeout: T.nilable(Numeric),
|
|
52
|
+
timeout: T.nilable(Numeric)
|
|
53
|
+
).void
|
|
54
|
+
end
|
|
55
|
+
def configure(host:, password: nil, username: Client::DEFAULT_USERNAME, api_key: nil,
|
|
56
|
+
open_timeout: Client::DEFAULT_OPEN_TIMEOUT, timeout: Client::DEFAULT_TIMEOUT)
|
|
57
|
+
self.client = Client.new(host: host, password: password, username: username, api_key: api_key,
|
|
58
|
+
open_timeout: open_timeout, timeout: timeout)
|
|
59
|
+
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The API client used for the requests in the current thread
|
|
64
|
+
# @return [Client, nil]
|
|
65
|
+
sig { returns(T.nilable(Client)) }
|
|
66
|
+
def client
|
|
67
|
+
Thread.current[:prusalink_client]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Sets the API client used for the requests in the current thread
|
|
71
|
+
# @param [Client, nil] client
|
|
72
|
+
sig { params(client: T.nilable(Client)).void }
|
|
73
|
+
def client=(client)
|
|
74
|
+
Thread.current[:prusalink_client] = client
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Tapioca
|
|
5
|
+
module Dsl
|
|
6
|
+
module Compilers
|
|
7
|
+
# Tapioca compiler for classes using AutoInitializable module.
|
|
8
|
+
#
|
|
9
|
+
# This compiler generates RBI files with proper Sorbet type signatures
|
|
10
|
+
# for classes that include the AutoInitializable module, replacing the
|
|
11
|
+
# need for dynamic code generation at runtime.
|
|
12
|
+
class AutoInitializable < Tapioca::Dsl::Compiler
|
|
13
|
+
ConstantType = type_member { { upper: Module } }
|
|
14
|
+
|
|
15
|
+
# Gather all classes that include AutoInitializable module.
|
|
16
|
+
sig { override.returns(T::Enumerable[Module]) }
|
|
17
|
+
def self.gather_constants
|
|
18
|
+
# Ensure our classes are loaded (fallback if require.rb doesn't work)
|
|
19
|
+
unless defined?(::Prusalink::AutoInitializable)
|
|
20
|
+
gem_root = File.expand_path("../../../..", __dir__)
|
|
21
|
+
require File.join(gem_root, "lib", "prusalink")
|
|
22
|
+
|
|
23
|
+
Zeitwerk::Registry.loaders.each(&:eager_load) if defined?(Zeitwerk::Registry)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
all_modules.select do |constant|
|
|
27
|
+
constant.is_a?(Class) &&
|
|
28
|
+
constant.respond_to?(:auto_attrs) &&
|
|
29
|
+
constant.included_modules.any? { |mod| mod.name == "Prusalink::AutoInitializable" }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Generates RBI content for the AutoInitializable class.
|
|
34
|
+
sig { override.void }
|
|
35
|
+
def decorate
|
|
36
|
+
auto_attrs = constant.auto_attrs
|
|
37
|
+
return if auto_attrs.empty?
|
|
38
|
+
|
|
39
|
+
root.create_path(constant) do |klass|
|
|
40
|
+
auto_attrs.each do |name, config|
|
|
41
|
+
sorbet_type = generate_sorbet_type(config)
|
|
42
|
+
|
|
43
|
+
klass.create_method(
|
|
44
|
+
name.to_s,
|
|
45
|
+
return_type: sorbet_type,
|
|
46
|
+
class_method: false
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
# Generates Sorbet type string for a configuration.
|
|
55
|
+
def generate_sorbet_type(config)
|
|
56
|
+
type = config[:type]
|
|
57
|
+
|
|
58
|
+
# Handle the case where type is already a Sorbet type
|
|
59
|
+
return type.to_s if type.respond_to?(:to_s) && (type.to_s.start_with?("T.") || type.to_s.start_with?("T::"))
|
|
60
|
+
|
|
61
|
+
# Convert type to string representation
|
|
62
|
+
base_type = case type
|
|
63
|
+
when Class
|
|
64
|
+
# For regular classes, use the class name
|
|
65
|
+
qualified_name_of(type)
|
|
66
|
+
when String
|
|
67
|
+
# For primitive types passed as strings
|
|
68
|
+
type
|
|
69
|
+
when Symbol
|
|
70
|
+
# For primitive types passed as symbols
|
|
71
|
+
type.to_s.capitalize
|
|
72
|
+
else
|
|
73
|
+
# Handle T.untyped case and other untyped cases
|
|
74
|
+
"T.untyped"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Handle array types
|
|
78
|
+
base_type = "T::Array[#{base_type}]" if config[:array]
|
|
79
|
+
|
|
80
|
+
# Handle nilable types
|
|
81
|
+
base_type = "T.nilable(#{base_type})" if config[:nilable]
|
|
82
|
+
|
|
83
|
+
base_type
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: prusalink
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sophie Déziel
|
|
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: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: faraday
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.2'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '3'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '2.2'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '3'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: net-http-digest_auth
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - "~>"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '1.4'
|
|
53
|
+
type: :runtime
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '1.4'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: sorbet-runtime
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 0.5.10908
|
|
67
|
+
- - "<"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 0.7.0
|
|
70
|
+
type: :runtime
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: 0.5.10908
|
|
77
|
+
- - "<"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 0.7.0
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: zeitwerk
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '2.6'
|
|
87
|
+
type: :runtime
|
|
88
|
+
prerelease: false
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - "~>"
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '2.6'
|
|
94
|
+
description: A type-safe Ruby wrapper for PrusaLink, the local web API of Prusa 3D
|
|
95
|
+
printers (MK4, MK3.9, MK3.5, XL, MINI, Core One and MK3 with a Raspberry Pi). Supports
|
|
96
|
+
printer status, jobs, storage, transfers and file uploads with HTTP Digest authentication.
|
|
97
|
+
email:
|
|
98
|
+
- courrier@sophiedeziel.com
|
|
99
|
+
executables: []
|
|
100
|
+
extensions: []
|
|
101
|
+
extra_rdoc_files: []
|
|
102
|
+
files:
|
|
103
|
+
- CHANGELOG.md
|
|
104
|
+
- LICENSE.txt
|
|
105
|
+
- README.md
|
|
106
|
+
- lib/prusalink.rb
|
|
107
|
+
- lib/prusalink/auto_initializable.rb
|
|
108
|
+
- lib/prusalink/base_resource.rb
|
|
109
|
+
- lib/prusalink/client.rb
|
|
110
|
+
- lib/prusalink/deserializable.rb
|
|
111
|
+
- lib/prusalink/digest_auth.rb
|
|
112
|
+
- lib/prusalink/exceptions.rb
|
|
113
|
+
- lib/prusalink/files.rb
|
|
114
|
+
- lib/prusalink/files/file.rb
|
|
115
|
+
- lib/prusalink/files/folder.rb
|
|
116
|
+
- lib/prusalink/files/refs.rb
|
|
117
|
+
- lib/prusalink/info.rb
|
|
118
|
+
- lib/prusalink/job.rb
|
|
119
|
+
- lib/prusalink/job/file.rb
|
|
120
|
+
- lib/prusalink/server_version.rb
|
|
121
|
+
- lib/prusalink/status.rb
|
|
122
|
+
- lib/prusalink/status/camera.rb
|
|
123
|
+
- lib/prusalink/status/job.rb
|
|
124
|
+
- lib/prusalink/status/printer.rb
|
|
125
|
+
- lib/prusalink/status/storage.rb
|
|
126
|
+
- lib/prusalink/status/transfer.rb
|
|
127
|
+
- lib/prusalink/storage.rb
|
|
128
|
+
- lib/prusalink/transfer.rb
|
|
129
|
+
- lib/prusalink/types.rb
|
|
130
|
+
- lib/prusalink/version.rb
|
|
131
|
+
- lib/tapioca/dsl/compilers/auto_initializable.rb
|
|
132
|
+
homepage: https://github.com/sophiedeziel/prusalink
|
|
133
|
+
licenses:
|
|
134
|
+
- MIT
|
|
135
|
+
metadata:
|
|
136
|
+
allowed_push_host: https://rubygems.org
|
|
137
|
+
homepage_uri: https://github.com/sophiedeziel/prusalink
|
|
138
|
+
source_code_uri: https://github.com/sophiedeziel/prusalink
|
|
139
|
+
changelog_uri: https://github.com/sophiedeziel/prusalink/blob/main/CHANGELOG.md
|
|
140
|
+
rubygems_mfa_required: 'true'
|
|
141
|
+
rdoc_options: []
|
|
142
|
+
require_paths:
|
|
143
|
+
- lib
|
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
|
+
requirements:
|
|
146
|
+
- - ">="
|
|
147
|
+
- !ruby/object:Gem::Version
|
|
148
|
+
version: '3.3'
|
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
|
+
requirements:
|
|
151
|
+
- - ">="
|
|
152
|
+
- !ruby/object:Gem::Version
|
|
153
|
+
version: '0'
|
|
154
|
+
requirements: []
|
|
155
|
+
rubygems_version: 4.0.20
|
|
156
|
+
specification_version: 4
|
|
157
|
+
summary: A type-safe Ruby wrapper for the PrusaLink REST API with full Sorbet integration.
|
|
158
|
+
test_files: []
|