wowsql-sdk 3.0.1 → 3.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.
data/lib/wowsql/auth.rb CHANGED
@@ -91,12 +91,12 @@ module WOWSQL
91
91
 
92
92
  # @param project_url [String] Project subdomain or full URL
93
93
  # @param api_key [String] API key for authentication
94
- # @param base_domain [String] Base domain (default: "wowsql.com")
94
+ # @param base_domain [String] Base domain (default: "wowsqlconnect.com")
95
95
  # @param secure [Boolean] Use HTTPS (default: true)
96
96
  # @param timeout [Integer] Request timeout in seconds (default: 30)
97
97
  # @param verify_ssl [Boolean] Verify SSL certificates (default: true)
98
98
  # @param token_storage [TokenStorage, nil] Optional token storage
99
- def initialize(project_url, api_key, base_domain: 'wowsql.com', secure: true,
99
+ def initialize(project_url, api_key, base_domain: 'wowsqlconnect.com', secure: true,
100
100
  timeout: 30, verify_ssl: true, token_storage: nil)
101
101
  @api_key = api_key
102
102
  @timeout = timeout
data/lib/wowsql/client.rb CHANGED
@@ -4,104 +4,93 @@ require_relative 'exceptions'
4
4
  require_relative 'table'
5
5
 
6
6
  module WOWSQL
7
- # WOWSQL client for interacting with your database via REST API.
7
+ # WowSQL client for PostgREST-native database operations.
8
8
  #
9
- # This client is used for DATABASE OPERATIONS (CRUD on tables).
10
- # Use Service Role Key or Anonymous Key for authentication.
11
- #
12
- # Key Types:
13
- # - Service Role Key: Full access to all database operations (server-side)
14
- # - Anonymous Key: Public access with limited permissions (client-side)
9
+ # All requests are sent directly to the PostgREST endpoint (/rest/v1).
15
10
  #
16
11
  # @example
17
- # client = WOWSQL::WOWSQLClient.new(
18
- # "myproject",
19
- # "wowbase_service_..."
20
- # )
21
- # users = client.table("users").get
12
+ # client = WOWSQL::WOWSQLClient.new("myproject", "wowsql_anon_...")
13
+ # result = client.table("users").get
22
14
  class WOWSQLClient
23
- attr_reader :api_url, :api_key, :timeout, :verify_ssl
15
+ attr_reader :api_url, :api_key, :timeout, :verify_ssl, :last_content_range
24
16
 
25
- # @param project_url [String] Project subdomain or full URL
26
- # @param api_key [String] API key for database operations
27
- # @param base_domain [String] Base domain (default: "wowsql.com")
28
- # @param secure [Boolean] Use HTTPS (default: true)
29
- # @param timeout [Integer] Request timeout in seconds (default: 30)
30
- # @param verify_ssl [Boolean] Verify SSL certificates (default: true)
31
- def initialize(project_url, api_key, base_domain: 'wowsql.com', secure: true, timeout: 30, verify_ssl: true)
32
- @api_key = api_key
33
- @timeout = timeout
17
+ # @param project_url [String] Project slug, domain, or full URL
18
+ # @param api_key [String] Anonymous or service role key
19
+ # @param base_domain [String] Base domain appended when project_url is a slug (default: wowsqlconnect.com)
20
+ # @param secure [Boolean] Use HTTPS (default: true)
21
+ # @param timeout [Integer] Request timeout in seconds (default: 30)
22
+ # @param verify_ssl [Boolean] Verify SSL certificates (default: true)
23
+ def initialize(project_url, api_key,
24
+ base_domain: 'wowsqlconnect.com',
25
+ secure: true,
26
+ timeout: 30,
27
+ verify_ssl: true)
28
+ @api_key = api_key
29
+ @timeout = timeout
34
30
  @verify_ssl = verify_ssl
31
+ @last_content_range = nil
35
32
 
36
- if project_url.start_with?('http://') || project_url.start_with?('https://')
37
- base_url = project_url.chomp('/')
38
- if base_url.include?('/api')
39
- base_url = base_url.split('/api').first
40
- @api_url = "#{base_url}/api/v2"
41
- else
42
- @api_url = "#{base_url}/api/v2"
43
- end
33
+ if project_url.start_with?('http://', 'https://')
34
+ base = project_url.chomp('/')
35
+ base = base.split('/api').first if base.include?('/api')
36
+ @base_url = base
44
37
  else
45
38
  protocol = secure ? 'https' : 'http'
46
39
  if project_url.include?(".#{base_domain}") || project_url.end_with?(base_domain)
47
- @api_url = "#{protocol}://#{project_url}/api/v2"
40
+ @base_url = "#{protocol}://#{project_url}"
48
41
  else
49
- @api_url = "#{protocol}://#{project_url}.#{base_domain}/api/v2"
42
+ @base_url = "#{protocol}://#{project_url}.#{base_domain}"
50
43
  end
51
44
  end
52
45
 
46
+ @api_url = "#{@base_url}/rest/v1"
47
+
53
48
  ssl_options = verify_ssl ? {} : { verify: false }
54
49
 
55
50
  @conn = Faraday.new(url: @api_url, ssl: ssl_options) do |f|
56
- f.request :json
51
+ f.request :json
57
52
  f.response :json
58
- f.adapter Faraday.default_adapter
53
+ f.adapter Faraday.default_adapter
59
54
  f.options.timeout = timeout
60
55
  end
61
56
 
62
- @conn.headers['Authorization'] = "Bearer #{api_key}"
57
+ @conn.headers['apikey'] = api_key
63
58
  @conn.headers['Content-Type'] = 'application/json'
64
59
  end
65
60
 
66
- # Get a table interface for fluent API.
61
+ # Return a Table interface for the given table name.
67
62
  #
68
- # @param table_name [String] Name of the table
69
- # @return [Table] Table instance for the specified table
63
+ # @param table_name [String]
64
+ # @return [Table]
70
65
  def table(table_name)
71
66
  Table.new(self, table_name)
72
67
  end
73
68
 
74
- # List all tables in the database.
75
- #
76
- # @return [Array<String>] List of table names
77
- def list_tables
78
- response = request('GET', '/tables', nil, nil)
79
- response['tables'] || []
80
- end
81
-
82
- # Get table schema information.
83
- #
84
- # @param table_name [String] Name of the table
85
- # @return [Hash] Table schema with columns and primary key
86
- def get_table_schema(table_name)
87
- request('GET', "/tables/#{table_name}/schema", nil, nil)
88
- end
89
-
90
- # Close the HTTP connection.
69
+ # Close the HTTP connection (no-op, provided for API parity).
91
70
  def close
92
71
  @conn.close if @conn.respond_to?(:close)
93
72
  end
94
73
 
95
- # Make HTTP request to API.
96
- def request(method, path, params = nil, json = nil)
74
+ # Make an HTTP request to the PostgREST endpoint.
75
+ #
76
+ # @param method [String] HTTP method
77
+ # @param path [String] Path (relative to /rest/v1)
78
+ # @param params [Hash, nil] Query parameters
79
+ # @param json [Hash, nil] Request body
80
+ # @param headers [Hash, nil] Additional headers (e.g. Prefer, on-conflict)
81
+ # @return [Array, Hash, nil]
82
+ def request(method, path, params = nil, json = nil, headers = nil)
97
83
  response = @conn.public_send(method.downcase, path) do |req|
98
- req.params = params if params
99
- req.body = json if json
84
+ req.params = params if params
85
+ req.body = json if json
86
+ req.headers = req.headers.merge(headers) if headers
100
87
  end
101
88
 
89
+ @last_content_range = response.headers['content-range']
90
+
102
91
  if response.status >= 400
103
92
  error_data = response.body.is_a?(Hash) ? response.body : {}
104
- error_msg = error_data['detail'] || error_data['message'] || "Request failed with status #{response.status}"
93
+ error_msg = error_data['message'] || error_data['detail'] || "Request failed with status #{response.status}"
105
94
  raise WOWSQLError.new(error_msg, response.status, error_data)
106
95
  end
107
96
 
@@ -109,5 +98,16 @@ module WOWSQL
109
98
  rescue Faraday::Error => e
110
99
  raise WOWSQLError.new("Request failed: #{e.message}")
111
100
  end
101
+
102
+ # Parse total count from a Content-Range header value.
103
+ #
104
+ # @param header [String, nil] e.g. "0-19/100"
105
+ # @param fallback [Integer]
106
+ # @return [Integer]
107
+ def self.parse_total_from_content_range(header, fallback)
108
+ return fallback unless header&.include?('/')
109
+ val = header.split('/').last.to_i
110
+ val > 0 ? val : fallback
111
+ end
112
112
  end
113
113
  end