primate-run 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5e3646fb9a37d9abb014fbe158eb36a657c9b2cc981eadc9f9f9688964ba6676
4
+ data.tar.gz: 41f42c7f73ff43165363faf5c1df9431d7e36faf0e2178ebb88dc864cc6d3758
5
+ SHA512:
6
+ metadata.gz: 72bef66e9e5578b55874dea7f31408813e2c439240a60dd73e20421e1550743440065823d5bf41bd093a5bb5a333a11479a5cfe760ad80c986ae46d03b2dc687
7
+ data.tar.gz: 8c8084f98a4c0151b26506410c8ca4e60c2729e401f259ecf439381f00159d84d89e55efb2da381a3b68bab438e504118f0c8b64f0fe264ad4e13b25ea2c16bb
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Pema
4
+ class ValidationError < StandardError; end
5
+
6
+ class Field
7
+ def parse(value, coerce = false)
8
+ raise NotImplementedError, 'Subclasses must implement parse'
9
+ end
10
+ end
11
+
12
+ class StringType < Field
13
+ def parse(value, coerce = false)
14
+ return value if value.is_a?(String)
15
+
16
+ if coerce
17
+ return value.to_s
18
+ end
19
+
20
+ raise ValidationError, "expected string, got #{value.class}"
21
+ end
22
+ end
23
+
24
+ class BooleanType < Field
25
+ def parse(value, coerce = false)
26
+ return value if value.is_a?(TrueClass) || value.is_a?(FalseClass)
27
+
28
+ if coerce
29
+ case value
30
+ when String
31
+ return false if value.empty?
32
+ case value.downcase
33
+ when 'true', '1', 'yes', 'on'
34
+ return true
35
+ when 'false', '0', 'no', 'off'
36
+ return false
37
+ else
38
+ raise ValidationError, "cannot parse '#{value}' as boolean"
39
+ end
40
+ else
41
+ raise ValidationError, "cannot coerce #{value.class} to boolean"
42
+ end
43
+ end
44
+
45
+ raise ValidationError, "expected boolean, got #{value.class}"
46
+ end
47
+ end
48
+
49
+ class IntType < Field
50
+ def parse(value, coerce = false)
51
+ return value if value.is_a?(Integer)
52
+
53
+ if coerce
54
+ case value
55
+ when Float
56
+ return value.to_i
57
+ when String
58
+ return 0 if value.empty?
59
+ return Integer(value)
60
+ else
61
+ raise ValidationError, "cannot coerce #{value.class} to int"
62
+ end
63
+ end
64
+
65
+ raise ValidationError, "expected integer, got #{value.class}"
66
+ rescue ArgumentError
67
+ raise ValidationError, "cannot parse '#{value}' as integer"
68
+ end
69
+ end
70
+
71
+ class FloatType < Field
72
+ def parse(value, coerce = false)
73
+ return value if value.is_a?(Float)
74
+
75
+ if coerce
76
+ case value
77
+ when Integer
78
+ return value.to_f
79
+ when String
80
+ return 0.0 if value.empty?
81
+ return Float(value)
82
+ else
83
+ raise ValidationError, "cannot coerce #{value.class} to float"
84
+ end
85
+ end
86
+
87
+ raise ValidationError, "expected float, got #{value.class}"
88
+ rescue ArgumentError
89
+ raise ValidationError, "cannot parse '#{value}' as float"
90
+ end
91
+ end
92
+
93
+ def self.string
94
+ StringType.new
95
+ end
96
+
97
+ def self.boolean
98
+ BooleanType.new
99
+ end
100
+
101
+ def self.int
102
+ IntType.new
103
+ end
104
+
105
+ def self.float
106
+ FloatType.new
107
+ end
108
+
109
+ class Schema
110
+ def initialize(fields)
111
+ @fields = fields
112
+ end
113
+
114
+ def parse(data, coerce = false)
115
+ result = {}
116
+
117
+ @fields.each do |name, field|
118
+ value = data.key?(name) ? data[name] : ''
119
+
120
+ begin
121
+ result[name] = field.parse(value, coerce)
122
+ rescue ValidationError => e
123
+ raise ValidationError, "parsing failed for field '#{name}': #{e.message}"
124
+ end
125
+ end
126
+
127
+ result
128
+ end
129
+ end
130
+
131
+ def self.schema(fields)
132
+ Schema.new(fields)
133
+ end
134
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primate
4
+ class Readable
5
+ attr_reader :content_type
6
+
7
+ def initialize(typed_array, content_type = nil)
8
+ @ta = typed_array
9
+ @content_type = content_type
10
+ @pos = 0
11
+ @size = @ta[:length].to_i
12
+ end
13
+
14
+ def size = @size
15
+ def eof? = @pos >= @size
16
+ def rewind; @pos = 0; self; end
17
+
18
+ # return a binary string (ASCII-8BIT), advance position
19
+ def read(n = nil)
20
+ return ''.b if eof?
21
+ n = n ? [n, @size - @pos].min : (@size - @pos)
22
+ str = pack_range(@pos, n)
23
+ @pos += n
24
+ str
25
+ end
26
+
27
+ # return an array of bytes (integers), advance position
28
+ def bytes(n = nil)
29
+ return [] if eof?
30
+ n = n ? [n, @size - @pos].min : (@size - @pos)
31
+ arr = Array.new(n) { |i| @ta[@pos + i].to_i }
32
+ @pos += n
33
+ arr
34
+ end
35
+
36
+ # look ahead without advancing position (integers)
37
+ def peek(n)
38
+ n = [n, @size - @pos].min
39
+ Array.new(n) { |i| @ta[@pos + i].to_i }
40
+ end
41
+
42
+ # first n bytes from the beginning (integers), does not affect position
43
+ def head(n = 4)
44
+ n = [n, @size].min
45
+ Array.new(n) { |i| @ta[i].to_i }
46
+ end
47
+
48
+ # enumerate binary string chunks starting at current position (no rewind)
49
+ def each_chunk(chunk = 64 * 1024)
50
+ return enum_for(:each_chunk, chunk) unless block_given?
51
+ off = @pos
52
+ while off < @size
53
+ n = [chunk, @size - off].min
54
+ yield pack_range(off, n)
55
+ off += n
56
+ end
57
+ self
58
+ end
59
+
60
+ private
61
+
62
+ def pack_range(off, n)
63
+ Array.new(n) { |i| @ta[off + i].to_i }.pack('C*')
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'url'
4
+ require_relative 'request_bag'
5
+ require_relative 'request_body'
6
+
7
+ class Request
8
+ attr_reader :url, :body, :path, :query, :headers, :cookies
9
+
10
+ # @param request [Object] JavaScript request object from the runtime
11
+ # @param helpers [Object] Helper functions from JavaScript runtime
12
+ def initialize(request, helpers)
13
+ @url = Primate::URL.new(request['url'])
14
+ @body = RequestBody.new(request['body'], helpers)
15
+ @path = RequestBag.new(request['path'], helpers)
16
+ @query = RequestBag.new(request['query'], helpers)
17
+ @headers = RequestBag.new(request['headers'], helpers)
18
+ @cookies = RequestBag.new(request['cookies'], helpers)
19
+ end
20
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'type'
4
+
5
+ class RequestBag
6
+ # initialize with JavaScript object data
7
+ #
8
+ # @param data [Object] JavaScript object from runtime
9
+ def initialize(data, helpers)
10
+ @data = type(data, helpers)
11
+ end
12
+
13
+ # get a value by key
14
+ #
15
+ # @param key [String] The key to look up
16
+ # @return [String] The value as string
17
+ # @throws RuntimeError if key is missing
18
+ def get(key)
19
+ raise "RequestBag has no key #{key}" unless has?(key)
20
+ @data[key].to_s
21
+ end
22
+
23
+ # Get a value by key (alias for get, Ruby style)
24
+ def [](key)
25
+ get(key)
26
+ end
27
+
28
+ # Try to get a value by key
29
+ #
30
+ # @param key [String] The key to look up
31
+ # @return [String, nil] The value or nil if absent
32
+ def try(key)
33
+ has?(key) ? @data[key].to_s : nil
34
+ end
35
+
36
+ # Whether the bag contains a defined value for the key
37
+ #
38
+ # @param key [String] The key to check
39
+ # @return [Boolean] True if key exists with defined value
40
+ def has?(key)
41
+ @data.key?(key) && !@data[key].nil?
42
+ end
43
+
44
+ # Parse the entire bag with a schema
45
+ #
46
+ # @param schema [Object] Object with parse method
47
+ # @param coerce [Boolean] Whether to coerce types
48
+ # @return [Object] Parsed result
49
+ def parse(schema, coerce = false)
50
+ schema.parse(@data, coerce)
51
+ end
52
+
53
+ # Convert to hash (Ruby standard conversion)
54
+ #
55
+ # @return [Hash] The underlying data
56
+ def to_h
57
+ @data
58
+ end
59
+
60
+ # Size of the bag
61
+ #
62
+ # @return [Integer] Number of entries
63
+ def size
64
+ @data.size
65
+ end
66
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'readable'
5
+ require_relative 'uploaded_file'
6
+
7
+ # Wrapper for request body with type-specific methods
8
+ class RequestBody
9
+ # Initialize with JavaScript body object
10
+ #
11
+ # @param body [Object] JavaScript body object from runtime
12
+ # @param helpers [Object] Helper functions from JavaScript runtime
13
+ def initialize(body, helpers)
14
+ @body = body
15
+ @helpers = helpers
16
+ end
17
+
18
+ # Get body as JSON (parsed hash)
19
+ #
20
+ # @return [Hash] Parsed JSON data
21
+ def json
22
+ JSON.parse(@body.json.to_s)
23
+ end
24
+
25
+ # Get body as plain text
26
+ #
27
+ # @return [String] Body as string
28
+ def text
29
+ @body.text.to_s
30
+ end
31
+
32
+ # Get form fields as hash
33
+ #
34
+ # @return [Hash] Form field data
35
+ def fields
36
+ JSON.parse(@body.fields.to_s)
37
+ end
38
+
39
+ def files
40
+ files = @body.files
41
+
42
+ Array.new(files[:length].to_i) do |i|
43
+ f = files[i]
44
+ Primate::UploadedFile.new(
45
+ field: f['field'].to_s,
46
+ name: f['name'].to_s,
47
+ type: f['type'].to_s,
48
+ size: f['size'].to_i,
49
+ bytes: f['bytes']
50
+ )
51
+ end
52
+ end
53
+
54
+ def binary
55
+ binary = @body.binary
56
+ Primate::Readable.new(binary['buffer'], binary['mime'].to_s)
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Response
4
+ # Create a view response
5
+ #
6
+ # @param name [String] The view template name
7
+ # @param props [Hash] Props to pass to the view
8
+ # @param options [Hash] Additional view options
9
+ # @return [Hash] Response object for the Primate framework
10
+ def self.view(name, props = {}, options = {})
11
+ { __PRMT__: 'view', name: name, props: props, options: options }
12
+ end
13
+
14
+ # Create a redirect response
15
+ #
16
+ # @param location [String] URL to redirect to
17
+ # @param options [Hash] Redirect options (status code, etc.)
18
+ # @return [Hash] Response object for the Primate framework
19
+ def self.redirect(location, options = {})
20
+ { __PRMT__: 'redirect', location: location, options: options }
21
+ end
22
+
23
+ # Create an error response
24
+ #
25
+ # @param options [Hash] Error options
26
+ # @return [Hash] Response object for the Primate framework
27
+ def self.error(options = {})
28
+ { __PRMT__: 'error', options: options }
29
+ end
30
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'request'
4
+ require_relative 'response'
5
+ require_relative '../primate'
6
+
7
+ # Route registration and handling
8
+ module Route
9
+ @routes = {}
10
+
11
+ # Register a GET route handler
12
+ #
13
+ # @yieldparam request [Request] The HTTP request object
14
+ # @return [void]
15
+ def self.get(&block)
16
+ @routes['GET'] = block
17
+ end
18
+
19
+ # Register a POST route handler
20
+ #
21
+ # @yieldparam request [Request] The HTTP request object
22
+ # @return [void]
23
+ def self.post(&block)
24
+ @routes['POST'] = block
25
+ end
26
+
27
+ # Register a PUT route handler
28
+ #
29
+ # @yieldparam request [Request] The HTTP request object
30
+ # @return [void]
31
+ def self.put(&block)
32
+ @routes['PUT'] = block
33
+ end
34
+
35
+ # Register a PATCH route handler
36
+ #
37
+ # @yieldparam request [Request] The HTTP request object
38
+ # @return [void]
39
+ def self.patch(&block)
40
+ @routes['PATCH'] = block
41
+ end
42
+
43
+ # Register a DELETE route handler
44
+ #
45
+ # @yieldparam request [Request] The HTTP request object
46
+ # @return [void]
47
+ def self.delete(&block)
48
+ @routes['DELETE'] = block
49
+ end
50
+
51
+ # Register a HEAD route handler
52
+ #
53
+ # @yieldparam request [Request] The HTTP request object
54
+ # @return [void]
55
+ def self.head(&block)
56
+ @routes['HEAD'] = block
57
+ end
58
+
59
+ # Register a OPTIONS route handler
60
+ #
61
+ # @yieldparam request [Request] The HTTP request object
62
+ # @return [void]
63
+ def self.options(&block)
64
+ @routes['OPTIONS'] = block
65
+ end
66
+
67
+ # Register a CONNECT route handler
68
+ #
69
+ # @yieldparam request [Request] The HTTP request object
70
+ # @return [void]
71
+ def self.connect(&block)
72
+ @routes['CONNECT'] = block
73
+ end
74
+
75
+ # Register a TRACE route handler
76
+ #
77
+ # @yieldparam request [Request] The HTTP request object
78
+ # @return [void]
79
+ def self.trace(&block)
80
+ @routes['TRACE'] = block
81
+ end
82
+
83
+ # Get all registered routes
84
+ #
85
+ # @return [Hash] Hash of HTTP method => handler block
86
+ def self.routes
87
+ @routes
88
+ end
89
+
90
+ def self.set_session(session, helpers)
91
+ PrimateInternal.set_session(session, helpers)
92
+ end
93
+ # Execute a route handler for the given HTTP method
94
+ #
95
+ # @param method [String] HTTP method
96
+ # @param request [Request] Request object
97
+ # @return [Object] Response from the route handler
98
+ def self.call_route(method, request)
99
+ handler = @routes[method.upcase]
100
+ return Response.error(status: 404) unless handler
101
+
102
+ handler.call(request)
103
+ end
104
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Session management helpers
4
+ module Session
5
+ class << self
6
+ attr_accessor :current
7
+
8
+ # Set the current session instance (called by framework)
9
+ #
10
+ # @param session_instance [SessionInstance] Session instance from JavaScript runtime
11
+ # @return [void]
12
+ def set_current(session_instance)
13
+ self.current = session_instance
14
+ end
15
+
16
+ # Get the session ID
17
+ #
18
+ # @return [String] Session identifier
19
+ def id
20
+ current&.id
21
+ end
22
+
23
+ # Check if session exists
24
+ #
25
+ # @return [Boolean] True if session exists
26
+ def exists?
27
+ current&.exists || false
28
+ end
29
+
30
+ # Create a new session with data
31
+ #
32
+ # @param data [Hash] Initial session data
33
+ # @return [void]
34
+ def create(data)
35
+ current&.create(data)
36
+ end
37
+
38
+ # Get session data (raises if no session)
39
+ #
40
+ # @return [Hash] Session data
41
+ def get
42
+ current&.get || {}
43
+ end
44
+
45
+ # Try to get session data (returns empty if no session)
46
+ #
47
+ # @return [Hash] Session data or empty hash
48
+ def try
49
+ current&.try || {}
50
+ end
51
+
52
+ # Set session data
53
+ #
54
+ # @param data [Hash] Data to store in session
55
+ # @return [void]
56
+ def set(data)
57
+ current&.set(data)
58
+ end
59
+
60
+ # Destroy the session
61
+ #
62
+ # @return [void]
63
+ def destroy
64
+ current&.destroy
65
+ end
66
+ end
67
+ end
68
+
69
+ # Internal session instance class (used by framework)
70
+ class SessionInstance
71
+ # Initialize session with JavaScript session object and helpers
72
+ #
73
+ # @param session [Object] JavaScript session object from the runtime
74
+ # @param helpers [Object] Helper functions from JavaScript runtime
75
+ def initialize(session, helpers)
76
+ @session = session
77
+ @helpers = helpers
78
+ end
79
+
80
+ # Get the session ID
81
+ #
82
+ # @return [String] Session identifier
83
+ def id
84
+ @session['id']
85
+ end
86
+
87
+ # Check if session exists
88
+ #
89
+ # @return [Boolean] True if session exists
90
+ def exists
91
+ @session['exists']
92
+ end
93
+
94
+ # Create a new session with data
95
+ #
96
+ # @param data [Hash] Initial session data
97
+ # @return [void]
98
+ def create(data)
99
+ @session.create(data)
100
+ end
101
+
102
+ # Get session data (raises if no session)
103
+ #
104
+ # @return [Hash] Session data
105
+ def get
106
+ @session.get
107
+ end
108
+
109
+ # Try to get session data (returns empty if no session)
110
+ #
111
+ # @return [Hash] Session data or empty hash
112
+ def try
113
+ @session.try
114
+ end
115
+
116
+ # Set session data
117
+ #
118
+ # @param data [Hash] Data to store in session
119
+ # @return [void]
120
+ def set(data)
121
+ @session.set(data)
122
+ end
123
+
124
+ # Destroy the session
125
+ #
126
+ # @return [void]
127
+ def destroy
128
+ @session.destroy
129
+ end
130
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ def type(value, helpers)
6
+ type = helpers.type(value).to_s
7
+
8
+ if type == 'integer'
9
+ return value.to_i
10
+ end
11
+
12
+ if type == 'float'
13
+ return value.to_f
14
+ end
15
+
16
+ if type == 'boolean'
17
+ return value == JS::True
18
+ end
19
+
20
+ if type == 'string'
21
+ return value.to_s
22
+ end
23
+
24
+ if type == 'nil'
25
+ return nil
26
+ end
27
+
28
+ if type == 'array'
29
+ as_array = JS.global[:Array].from(value)
30
+ return Array.new(as_array[:length].to_i) {
31
+ type(as_array[_1], helpers)
32
+ }
33
+ end
34
+
35
+ if type == 'object'
36
+ as_entries = JS.global[:Object].entries(value)
37
+ return Hash[Array.new(as_entries[:length].to_i) {[
38
+ as_entries[_1][0].to_s,
39
+ type(as_entries[_1][1], helpers)
40
+ ]}]
41
+ end
42
+
43
+ value
44
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'readable'
4
+
5
+ module Primate
6
+ class UploadedFile
7
+ attr_reader :field, :filename, :content_type, :size
8
+
9
+ def initialize(field:, name:, type:, size:, bytes:)
10
+ @field = field
11
+ @filename = name
12
+ @content_type = type
13
+ @size = size
14
+ @io = Primate::Readable.new(bytes, type)
15
+ end
16
+
17
+ def io = @io
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primate
4
+ class URL
5
+ attr_reader :href, :origin, :protocol, :username, :password, :host,
6
+ :hostname, :port, :pathname, :search, :hash
7
+
8
+ # initialize URL from JavaScript URL object
9
+ # @param url [Object] JavaScript URL object from the runtime
10
+ def initialize(url)
11
+ @href = url['href'].to_s
12
+ @origin = url['origin'].to_s
13
+ @protocol = url['protocol'].to_s
14
+ @username = url['username'].to_s
15
+ @password = url['password'].to_s
16
+ @host = url['host'].to_s
17
+ @hostname = url['hostname'].to_s
18
+ @port = url['port'].to_s
19
+ @pathname = url['pathname'].to_s
20
+ @search = url['search'].to_s
21
+ @hash = url['hash'].to_s
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primate
4
+ VERSION = '0.1.0'
5
+ end
data/lib/primate.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "primate/version"
4
+
5
+ module PrimateInternal
6
+ def self.set_session(session, helpers)
7
+ require_relative "primate/session"
8
+ session_instance = SessionInstance.new(session, helpers)
9
+ Session.set_current(session_instance)
10
+ end
11
+ end
data/sig/primate.rbs ADDED
@@ -0,0 +1,162 @@
1
+ # RBS type signatures for Primate Ruby gem
2
+
3
+ module Primate
4
+ VERSION: String
5
+
6
+ class URL
7
+ attr_reader href: String
8
+ attr_reader origin: String
9
+ attr_reader protocol: String
10
+ attr_reader username: String
11
+ attr_reader password: String
12
+ attr_reader host: String
13
+ attr_reader hostname: String
14
+ attr_reader port: String
15
+ attr_reader pathname: String
16
+ attr_reader search: String
17
+ attr_reader hash: String
18
+
19
+ def initialize: (untyped url) -> void
20
+ end
21
+
22
+ class Readable
23
+ attr_reader content_type: String?
24
+
25
+ def initialize: (untyped typed_array, String? content_type) -> void
26
+ def size: () -> Integer
27
+ def eof?: () -> bool
28
+ def rewind: () -> self
29
+ def read: (?Integer? n) -> String
30
+ def bytes: (?Integer? n) -> Array[Integer]
31
+ def peek: (Integer n) -> Array[Integer]
32
+ def head: (?Integer n) -> Array[Integer]
33
+ def each_chunk: (?Integer chunk) { (String) -> void } -> self
34
+ | (?Integer chunk) -> Enumerator[String, self]
35
+ end
36
+
37
+ class UploadedFile
38
+ attr_reader field: String
39
+ attr_reader filename: String
40
+ attr_reader content_type: String
41
+ attr_reader size: Integer
42
+
43
+ def initialize: (field: String, name: String, type: String, size: Integer, bytes: untyped) -> void
44
+ def io: () -> Readable
45
+ end
46
+ end
47
+
48
+ class RequestBody
49
+ def initialize: (untyped body, untyped helpers) -> void
50
+ def json: () -> Hash[String, untyped]
51
+ def text: () -> String
52
+ def fields: () -> Hash[String, untyped]
53
+ def files: () -> Array[Primate::UploadedFile]
54
+ def binary: () -> Primate::Readable
55
+ end
56
+
57
+ class RequestBag
58
+ def initialize: (untyped data, untyped helpers) -> void
59
+ def get: (String key) -> String
60
+ def []: (String key) -> String
61
+ def try: (String key) -> String?
62
+ def has?: (String key) -> bool
63
+ def parse: (untyped schema, ?bool coerce) -> untyped
64
+ def to_h: () -> Hash[String, untyped]
65
+ def size: () -> Integer
66
+ end
67
+
68
+ class Request
69
+ attr_reader url: Primate::URL
70
+ attr_reader body: RequestBody
71
+ attr_reader path: RequestBag
72
+ attr_reader query: RequestBag
73
+ attr_reader headers: RequestBag
74
+ attr_reader cookies: RequestBag
75
+
76
+ def initialize: (untyped request, untyped helpers) -> void
77
+ end
78
+
79
+ class SessionInstance
80
+ def initialize: (untyped session, untyped helpers) -> void
81
+ def id: () -> String
82
+ def exists: () -> bool
83
+ def create: (Hash[String, untyped] data) -> void
84
+ def get: () -> Hash[String, untyped]
85
+ def try: () -> Hash[String, untyped]
86
+ def set: (Hash[String, untyped] data) -> void
87
+ def destroy: () -> void
88
+ end
89
+
90
+ module Session
91
+ def self.set_current: (SessionInstance session_instance) -> void
92
+ def self.id: () -> String?
93
+ def self.exists?: () -> bool
94
+ def self.create: (Hash[String, untyped] data) -> void
95
+ def self.get: () -> Hash[String, untyped]
96
+ def self.try: () -> Hash[String, untyped]
97
+ def self.set: (Hash[String, untyped] data) -> void
98
+ def self.destroy: () -> void
99
+ end
100
+
101
+ module Response
102
+ def self.view: (String name, ?Hash[String, untyped] props, ?Hash[String, untyped] options) -> Hash[Symbol, untyped]
103
+ def self.redirect: (String location, ?Hash[String, untyped] options) -> Hash[Symbol, untyped]
104
+ def self.error: (?Hash[String, untyped] options) -> Hash[Symbol, untyped]
105
+ end
106
+
107
+ module Route
108
+ def self.get: () { (Request) -> untyped } -> void
109
+ def self.post: () { (Request) -> untyped } -> void
110
+ def self.put: () { (Request) -> untyped } -> void
111
+ def self.patch: () { (Request) -> untyped } -> void
112
+ def self.delete: () { (Request) -> untyped } -> void
113
+ def self.head: () { (Request) -> untyped } -> void
114
+ def self.options: () { (Request) -> untyped } -> void
115
+ def self.connect: () { (Request) -> untyped } -> void
116
+ def self.trace: () { (Request) -> untyped } -> void
117
+ def self.routes: () -> Hash[String, Proc]
118
+ def self.set_session: (untyped session, untyped helpers) -> void
119
+ def self.call_route: (String method, Request request) -> untyped
120
+ end
121
+
122
+ module Pema
123
+ class ValidationError < StandardError
124
+ end
125
+
126
+ class Field
127
+ def parse: (untyped value, ?bool coerce) -> untyped
128
+ end
129
+
130
+ class StringType < Field
131
+ def parse: (untyped value, ?bool coerce) -> String
132
+ end
133
+
134
+ class BooleanType < Field
135
+ def parse: (untyped value, ?bool coerce) -> bool
136
+ end
137
+
138
+ class IntType < Field
139
+ def parse: (untyped value, ?bool coerce) -> Integer
140
+ end
141
+
142
+ class FloatType < Field
143
+ def parse: (untyped value, ?bool coerce) -> Float
144
+ end
145
+
146
+ class Schema
147
+ def initialize: (Hash[String, Field] fields) -> void
148
+ def parse: (Hash[String, untyped] data, ?bool coerce) -> Hash[String, untyped]
149
+ end
150
+
151
+ def self.string: () -> StringType
152
+ def self.boolean: () -> BooleanType
153
+ def self.int: () -> IntType
154
+ def self.float: () -> FloatType
155
+ def self.schema: (Hash[String, Field] fields) -> Schema
156
+ end
157
+
158
+ module PrimateInternal
159
+ def self.set_session: (untyped session, untyped helpers) -> void
160
+ end
161
+
162
+ def type: (untyped value, untyped helpers) -> untyped
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: primate-run
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Primate Team
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: bundler
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: ruby-lsp
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.26'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.26'
54
+ description: Provides Ruby support for building web applications with the Primate
55
+ framework
56
+ email:
57
+ - terrablue@proton.me
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/primate.rb
63
+ - lib/primate/pema.rb
64
+ - lib/primate/readable.rb
65
+ - lib/primate/request.rb
66
+ - lib/primate/request_bag.rb
67
+ - lib/primate/request_body.rb
68
+ - lib/primate/response.rb
69
+ - lib/primate/route.rb
70
+ - lib/primate/session.rb
71
+ - lib/primate/type.rb
72
+ - lib/primate/uploaded_file.rb
73
+ - lib/primate/url.rb
74
+ - lib/primate/version.rb
75
+ - sig/primate.rbs
76
+ homepage: https://primate.run
77
+ licenses:
78
+ - MIT
79
+ metadata:
80
+ homepage_uri: https://primate.run
81
+ source_code_uri: https://github.com/primate-run/ruby
82
+ bug_tracker_uri: https://github.com/primate-run/ruby/issues
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 3.0.0
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubygems_version: 3.6.9
98
+ specification_version: 4
99
+ summary: Ruby route handlers for the Primate web framework
100
+ test_files: []