flexops 1.0.1 → 1.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 +4 -4
- data/README.md +55 -25
- data/lib/flexops/errors.rb +35 -35
- data/lib/flexops/http.rb +5 -3
- data/lib/flexops/resources/analytics.rb +85 -85
- data/lib/flexops/resources/api_keys.rb +40 -40
- data/lib/flexops/resources/auth.rb +57 -57
- data/lib/flexops/resources/carriers.rb +129 -129
- data/lib/flexops/resources/insurance.rb +48 -48
- data/lib/flexops/resources/inventory.rb +39 -39
- data/lib/flexops/resources/orders.rb +67 -67
- data/lib/flexops/resources/pickups.rb +40 -40
- data/lib/flexops/resources/returns.rb +61 -61
- data/lib/flexops/resources/rules.rb +48 -48
- data/lib/flexops/resources/scan_forms.rb +36 -36
- data/lib/flexops/resources/shipping.rb +87 -84
- data/lib/flexops/resources/wallet.rb +41 -41
- data/lib/flexops/resources/webhooks.rb +59 -59
- data/lib/flexops/resources/workspaces.rb +53 -53
- data/lib/flexops/version.rb +11 -11
- data/lib/flexops.rb +35 -35
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae38cf941276d4053203fda4a44fb9ab1adb873d24bba9ec1de7fc634be3e7e2
|
|
4
|
+
data.tar.gz: 43b602d72cbac545bff0391aa2dee8ea28f73bd7807a6042ec17731fe7943881
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0959231eed12a9abd27bc7d370ab9576e32393a131248e231f2d7bebb622c74c29c21596f55036c1af8df73a277a3cbb8ee282c516aca90fc787839c76f102dc'
|
|
7
|
+
data.tar.gz: 42fa01ac062f0f54ed7632e403a0d3a5ed37e3e942e6f11a45797b047f7f343c3b0419d354e83af9be217d58d1877a322ee7fee7fa6c79e9749e069cfca0f7cf
|
data/README.md
CHANGED
|
@@ -35,28 +35,54 @@ client = FlexOps::Client.new(
|
|
|
35
35
|
|
|
36
36
|
# Get shipping rates from all carriers
|
|
37
37
|
rates = client.shipping.get_rates(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
origin: {addressLine1: "123 Main St", city: "New York", stateProvince: "NY", postalCode: "10001"},
|
|
39
|
+
destination: {addressLine1: "456 Oak Ave", city: "Los Angeles", stateProvince: "CA", postalCode: "90210"},
|
|
40
|
+
package: {weight: 16, weightUnit: "oz"}
|
|
41
41
|
)
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
request = {
|
|
44
|
+
carrierCode: "USPS", serviceCode: "GROUND_ADVANTAGE",
|
|
45
|
+
origin: {name: "Warehouse", addressLine1: "123 Main St", city: "New York", stateProvince: "NY", postalCode: "10001", countryCode: "US"},
|
|
46
|
+
destination: {name: "Customer", addressLine1: "456 Oak Ave", city: "Los Angeles", stateProvince: "CA", postalCode: "90210", countryCode: "US"},
|
|
47
|
+
package: {weight: 16, weightUnit: "oz"},
|
|
48
|
+
maximumPostageAmount: 10.25 # Caller-approved ceiling in USD.
|
|
49
|
+
}
|
|
50
|
+
preview = client.shipping.create_label(request)
|
|
51
|
+
puts preview["quotedPostageAmount"]
|
|
52
|
+
|
|
53
|
+
# Call only after explicit caller approval, within five minutes.
|
|
54
|
+
purchase_approved_label = lambda do |purchase_key|
|
|
55
|
+
client.shipping.create_label(
|
|
56
|
+
request.merge(confirmationToken: preview["confirmationToken"]),
|
|
57
|
+
idempotency_key: purchase_key # Persist per purchase; reuse on retries.
|
|
58
|
+
)
|
|
59
|
+
end
|
|
55
60
|
|
|
56
61
|
# Track a shipment
|
|
57
62
|
info = client.shipping.track("9400111899223456789012")
|
|
58
63
|
```
|
|
59
64
|
|
|
65
|
+
### Live label approval (1.1.0+)
|
|
66
|
+
|
|
67
|
+
The example below requires SDK 1.1.0 or later. Version 1.0.2 does not
|
|
68
|
+
include the per-call idempotency argument.
|
|
69
|
+
|
|
70
|
+
For live domestic single-label requests, `maximumPostageAmount` is required: positive
|
|
71
|
+
USD, at most two decimal places, up to 1,000,000. Missing or invalid values return
|
|
72
|
+
400 `ApprovalRequired`. Omitting `confirmationToken` returns a raw 200 preview
|
|
73
|
+
(`status`, `quotedPostageAmount`, `maximumPostageAmount`, `currency`, `expiresAt`,
|
|
74
|
+
`confirmationToken`). After explicit approval, resubmit the same shipment and ceiling
|
|
75
|
+
with the token and a unique per-purchase `Idempotency-Key` header. The token expires
|
|
76
|
+
after five minutes. A successful purchase returns the raw 201 label, including
|
|
77
|
+
`labelId`, `trackingNumber`, `carrierCode`, and `labelData`, without a `data` wrapper.
|
|
78
|
+
|
|
79
|
+
Keep the same key and request across retries. An uncertain outcome needs reconciliation;
|
|
80
|
+
do not start another purchase with a new key. An expired approval returns 409
|
|
81
|
+
`ApprovalExpired`; obtain and explicitly approve a fresh preview when no purchase is
|
|
82
|
+
unresolved. The ceiling bounds postage authorization, not later adjustments or separate
|
|
83
|
+
fees. Sandbox execution bypasses approval; batch, return, and raw carrier routes have
|
|
84
|
+
separate contracts. The SDK never automatically confirms a preview.
|
|
85
|
+
|
|
60
86
|
## Authentication
|
|
61
87
|
|
|
62
88
|
### API key (recommended)
|
|
@@ -119,27 +145,31 @@ Every SDK method is a thin wrapper around the FlexOps REST API. If you want to v
|
|
|
119
145
|
|
|
120
146
|
```bash
|
|
121
147
|
# Shop rates across all connected carriers
|
|
122
|
-
curl -X POST https://gateway.flexops.io/api/
|
|
148
|
+
curl -X POST https://gateway.flexops.io/api/shipping/rates \
|
|
123
149
|
-H "X-API-Key: fxk_live_..." \
|
|
124
150
|
-H "Content-Type: application/json" \
|
|
125
151
|
-d '{
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
152
|
+
"origin": {"addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"},
|
|
153
|
+
"destination": {"addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"},
|
|
154
|
+
"package": {"weight": 16, "weightUnit": "oz"}
|
|
129
155
|
}'
|
|
130
156
|
|
|
131
|
-
#
|
|
157
|
+
# Preview a live label; this does not purchase it.
|
|
132
158
|
curl -X POST https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/labels \
|
|
133
159
|
-H "X-API-Key: fxk_live_..." \
|
|
134
160
|
-H "Content-Type: application/json" \
|
|
135
161
|
-d '{
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
162
|
+
"carrierCode": "USPS", "serviceCode": "GROUND_ADVANTAGE",
|
|
163
|
+
"origin": {"name": "Warehouse", "addressLine1": "123 Main St", "city": "New York", "stateProvince": "NY", "postalCode": "10001", "countryCode": "US"},
|
|
164
|
+
"destination": {"name": "Customer", "addressLine1": "456 Oak Ave", "city": "Los Angeles", "stateProvince": "CA", "postalCode": "90210", "countryCode": "US"},
|
|
165
|
+
"package": {"weight": 16, "weightUnit": "oz"},
|
|
166
|
+
"maximumPostageAmount": 10.25
|
|
141
167
|
}'
|
|
142
168
|
|
|
169
|
+
# After explicit approval, resend the same body with confirmationToken from
|
|
170
|
+
# the preview and an Idempotency-Key header unique to this purchase.
|
|
171
|
+
# See the SDK example above; retain that key for retries.
|
|
172
|
+
|
|
143
173
|
# Track a shipment
|
|
144
174
|
curl https://gateway.flexops.io/api/workspaces/ws_abc123/shipping/track/9400111899223456789012 \
|
|
145
175
|
-H "X-API-Key: fxk_live_..."
|
data/lib/flexops/errors.rb
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
# ***********************************************************************
|
|
2
|
-
# Package : flexops
|
|
3
|
-
# Author : FlexOps, LLC
|
|
4
|
-
# Created : 2026-03-08
|
|
5
|
-
#
|
|
6
|
-
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
-
# ***********************************************************************
|
|
8
|
-
|
|
9
|
-
module FlexOps
|
|
10
|
-
class Error < StandardError
|
|
11
|
-
attr_reader :status, :code, :errors
|
|
12
|
-
|
|
13
|
-
def initialize(message, status: 0, code: nil, errors: nil)
|
|
14
|
-
super(message)
|
|
15
|
-
@status = status
|
|
16
|
-
@code = code
|
|
17
|
-
@errors = errors
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
class AuthError < Error
|
|
22
|
-
def initialize(message = "Authentication required. Check your access token or API key.")
|
|
23
|
-
super(message, status: 401, code: "UNAUTHORIZED")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
class RateLimitError < Error
|
|
28
|
-
attr_reader :retry_after
|
|
29
|
-
|
|
30
|
-
def initialize(retry_after: 0)
|
|
31
|
-
super("Rate limited. Retry after #{retry_after}s", status: 429, code: "RATE_LIMITED")
|
|
32
|
-
@retry_after = retry_after
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
1
|
+
# ***********************************************************************
|
|
2
|
+
# Package : flexops
|
|
3
|
+
# Author : FlexOps, LLC
|
|
4
|
+
# Created : 2026-03-08
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
+
# ***********************************************************************
|
|
8
|
+
|
|
9
|
+
module FlexOps
|
|
10
|
+
class Error < StandardError
|
|
11
|
+
attr_reader :status, :code, :errors
|
|
12
|
+
|
|
13
|
+
def initialize(message, status: 0, code: nil, errors: nil)
|
|
14
|
+
super(message)
|
|
15
|
+
@status = status
|
|
16
|
+
@code = code
|
|
17
|
+
@errors = errors
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class AuthError < Error
|
|
22
|
+
def initialize(message = "Authentication required. Check your access token or API key.")
|
|
23
|
+
super(message, status: 401, code: "UNAUTHORIZED")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class RateLimitError < Error
|
|
28
|
+
attr_reader :retry_after
|
|
29
|
+
|
|
30
|
+
def initialize(retry_after: 0)
|
|
31
|
+
super("Rate limited. Retry after #{retry_after}s", status: 429, code: "RATE_LIMITED")
|
|
32
|
+
@retry_after = retry_after
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/flexops/http.rb
CHANGED
|
@@ -38,8 +38,8 @@ module FlexOps
|
|
|
38
38
|
request(:get, path, query: query)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def post(path, body: nil, query: nil)
|
|
42
|
-
request(:post, path, body: body, query: query)
|
|
41
|
+
def post(path, body: nil, query: nil, headers: {})
|
|
42
|
+
request(:post, path, body: body, query: query, headers: headers)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def put(path, body: nil)
|
|
@@ -56,7 +56,7 @@ module FlexOps
|
|
|
56
56
|
|
|
57
57
|
private
|
|
58
58
|
|
|
59
|
-
def request(method, path, body: nil, query: nil)
|
|
59
|
+
def request(method, path, body: nil, query: nil, headers: {})
|
|
60
60
|
uri = build_uri(path, query)
|
|
61
61
|
last_error = nil
|
|
62
62
|
|
|
@@ -66,6 +66,7 @@ module FlexOps
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
req = build_request(method, uri, body)
|
|
69
|
+
headers.each { |name, value| req[name] = value }
|
|
69
70
|
begin
|
|
70
71
|
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https",
|
|
71
72
|
open_timeout: @timeout, read_timeout: @timeout) do |http|
|
|
@@ -97,6 +98,7 @@ module FlexOps
|
|
|
97
98
|
error = Error.new(
|
|
98
99
|
error_body["message"] || "HTTP #{status}: #{response.message}",
|
|
99
100
|
status: status,
|
|
101
|
+
code: error_body["errorCode"] || error_body["code"],
|
|
100
102
|
errors: error_body["errors"]
|
|
101
103
|
)
|
|
102
104
|
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
# ***********************************************************************
|
|
2
|
-
# Package : flexops
|
|
3
|
-
# Author : FlexOps, LLC
|
|
4
|
-
# Created : 2026-03-08
|
|
5
|
-
#
|
|
6
|
-
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
-
# ***********************************************************************
|
|
8
|
-
|
|
9
|
-
module FlexOps
|
|
10
|
-
module Resources
|
|
11
|
-
class Analytics
|
|
12
|
-
BASE = "/api/ApiProxy/api/v4/Analytics"
|
|
13
|
-
|
|
14
|
-
def initialize(http)
|
|
15
|
-
@http = http
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def shipments_trend(start_date: nil, end_date: nil)
|
|
19
|
-
@http.get("#{BASE}/ShipmentsTrend", query: date_query(start_date, end_date))
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def carrier_summary(start_date: nil, end_date: nil)
|
|
23
|
-
@http.get("#{BASE}/CarrierSummary", query: date_query(start_date, end_date))
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def top_destinations(start_date: nil, end_date: nil, limit: nil)
|
|
27
|
-
@http.get("#{BASE}/TopDestinations", query: date_query(start_date, end_date).merge(limit: limit).compact)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def inventory_metrics
|
|
31
|
-
@http.get("#{BASE}/InventoryMetrics")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def stock_by_warehouse
|
|
35
|
-
@http.get("#{BASE}/StockByWarehouse")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def order_metrics(start_date: nil, end_date: nil)
|
|
39
|
-
@http.get("#{BASE}/OrderMetrics", query: date_query(start_date, end_date))
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def order_trend(start_date: nil, end_date: nil)
|
|
43
|
-
@http.get("#{BASE}/OrderTrend", query: date_query(start_date, end_date))
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def top_selling_products(start_date: nil, end_date: nil, limit: nil)
|
|
47
|
-
@http.get("#{BASE}/TopSellingProducts", query: date_query(start_date, end_date).merge(limit: limit).compact)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def returns_metrics(start_date: nil, end_date: nil)
|
|
51
|
-
@http.get("#{BASE}/ReturnsMetrics", query: date_query(start_date, end_date))
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def returns_trend(start_date: nil, end_date: nil)
|
|
55
|
-
@http.get("#{BASE}/ReturnsTrend", query: date_query(start_date, end_date))
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def return_reasons(start_date: nil, end_date: nil)
|
|
59
|
-
@http.get("#{BASE}/ReturnReasons", query: date_query(start_date, end_date))
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def performance_metrics(start_date: nil, end_date: nil)
|
|
63
|
-
@http.get("#{BASE}/PerformanceMetrics", query: date_query(start_date, end_date))
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def carrier_performance(start_date: nil, end_date: nil)
|
|
67
|
-
@http.get("#{BASE}/CarrierPerformance", query: date_query(start_date, end_date))
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def shipping_cost_analytics(start_date: nil, end_date: nil)
|
|
71
|
-
@http.get("#{BASE}/ShippingCostAnalytics", query: date_query(start_date, end_date))
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def delivery_performance(start_date: nil, end_date: nil)
|
|
75
|
-
@http.get("#{BASE}/DeliveryPerformance", query: date_query(start_date, end_date))
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
private
|
|
79
|
-
|
|
80
|
-
def date_query(start_date, end_date)
|
|
81
|
-
{ startDate: start_date, endDate: end_date }.compact
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
1
|
+
# ***********************************************************************
|
|
2
|
+
# Package : flexops
|
|
3
|
+
# Author : FlexOps, LLC
|
|
4
|
+
# Created : 2026-03-08
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
+
# ***********************************************************************
|
|
8
|
+
|
|
9
|
+
module FlexOps
|
|
10
|
+
module Resources
|
|
11
|
+
class Analytics
|
|
12
|
+
BASE = "/api/ApiProxy/api/v4/Analytics"
|
|
13
|
+
|
|
14
|
+
def initialize(http)
|
|
15
|
+
@http = http
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def shipments_trend(start_date: nil, end_date: nil)
|
|
19
|
+
@http.get("#{BASE}/ShipmentsTrend", query: date_query(start_date, end_date))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def carrier_summary(start_date: nil, end_date: nil)
|
|
23
|
+
@http.get("#{BASE}/CarrierSummary", query: date_query(start_date, end_date))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def top_destinations(start_date: nil, end_date: nil, limit: nil)
|
|
27
|
+
@http.get("#{BASE}/TopDestinations", query: date_query(start_date, end_date).merge(limit: limit).compact)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def inventory_metrics
|
|
31
|
+
@http.get("#{BASE}/InventoryMetrics")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def stock_by_warehouse
|
|
35
|
+
@http.get("#{BASE}/StockByWarehouse")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def order_metrics(start_date: nil, end_date: nil)
|
|
39
|
+
@http.get("#{BASE}/OrderMetrics", query: date_query(start_date, end_date))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def order_trend(start_date: nil, end_date: nil)
|
|
43
|
+
@http.get("#{BASE}/OrderTrend", query: date_query(start_date, end_date))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def top_selling_products(start_date: nil, end_date: nil, limit: nil)
|
|
47
|
+
@http.get("#{BASE}/TopSellingProducts", query: date_query(start_date, end_date).merge(limit: limit).compact)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def returns_metrics(start_date: nil, end_date: nil)
|
|
51
|
+
@http.get("#{BASE}/ReturnsMetrics", query: date_query(start_date, end_date))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def returns_trend(start_date: nil, end_date: nil)
|
|
55
|
+
@http.get("#{BASE}/ReturnsTrend", query: date_query(start_date, end_date))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def return_reasons(start_date: nil, end_date: nil)
|
|
59
|
+
@http.get("#{BASE}/ReturnReasons", query: date_query(start_date, end_date))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def performance_metrics(start_date: nil, end_date: nil)
|
|
63
|
+
@http.get("#{BASE}/PerformanceMetrics", query: date_query(start_date, end_date))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def carrier_performance(start_date: nil, end_date: nil)
|
|
67
|
+
@http.get("#{BASE}/CarrierPerformance", query: date_query(start_date, end_date))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def shipping_cost_analytics(start_date: nil, end_date: nil)
|
|
71
|
+
@http.get("#{BASE}/ShippingCostAnalytics", query: date_query(start_date, end_date))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def delivery_performance(start_date: nil, end_date: nil)
|
|
75
|
+
@http.get("#{BASE}/DeliveryPerformance", query: date_query(start_date, end_date))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def date_query(start_date, end_date)
|
|
81
|
+
{ startDate: start_date, endDate: end_date }.compact
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
# ***********************************************************************
|
|
2
|
-
# Package : flexops
|
|
3
|
-
# Author : FlexOps, LLC
|
|
4
|
-
# Created : 2026-03-08
|
|
5
|
-
#
|
|
6
|
-
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
-
# ***********************************************************************
|
|
8
|
-
|
|
9
|
-
module FlexOps
|
|
10
|
-
module Resources
|
|
11
|
-
class ApiKeys
|
|
12
|
-
def initialize(http, ws_id_proc)
|
|
13
|
-
@http = http
|
|
14
|
-
@ws_id = ws_id_proc
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def list
|
|
18
|
-
@http.get("#{ws_path}/api-keys")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def create(request)
|
|
22
|
-
@http.post("#{ws_path}/api-keys", body: request)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def revoke(key_id)
|
|
26
|
-
@http.delete("#{ws_path}/api-keys/#{key_id}")
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def rotate(key_id)
|
|
30
|
-
@http.post("#{ws_path}/api-keys/#{key_id}/rotate")
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def ws_path
|
|
36
|
-
"/api/workspaces/#{@ws_id.call}"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
1
|
+
# ***********************************************************************
|
|
2
|
+
# Package : flexops
|
|
3
|
+
# Author : FlexOps, LLC
|
|
4
|
+
# Created : 2026-03-08
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
+
# ***********************************************************************
|
|
8
|
+
|
|
9
|
+
module FlexOps
|
|
10
|
+
module Resources
|
|
11
|
+
class ApiKeys
|
|
12
|
+
def initialize(http, ws_id_proc)
|
|
13
|
+
@http = http
|
|
14
|
+
@ws_id = ws_id_proc
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def list
|
|
18
|
+
@http.get("#{ws_path}/api-keys")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create(request)
|
|
22
|
+
@http.post("#{ws_path}/api-keys", body: request)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def revoke(key_id)
|
|
26
|
+
@http.delete("#{ws_path}/api-keys/#{key_id}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def rotate(key_id)
|
|
30
|
+
@http.post("#{ws_path}/api-keys/#{key_id}/rotate")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def ws_path
|
|
36
|
+
"/api/workspaces/#{@ws_id.call}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
# ***********************************************************************
|
|
2
|
-
# Package : flexops
|
|
3
|
-
# Author : FlexOps, LLC
|
|
4
|
-
# Created : 2026-03-08
|
|
5
|
-
#
|
|
6
|
-
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
-
# ***********************************************************************
|
|
8
|
-
|
|
9
|
-
module FlexOps
|
|
10
|
-
module Resources
|
|
11
|
-
class Auth
|
|
12
|
-
def initialize(http)
|
|
13
|
-
@http = http
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def login(email:, password:)
|
|
17
|
-
@http.post("/api/Account/login", body: { email: email, password: password })
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def register(request)
|
|
21
|
-
@http.post("/api/Account/register", body: request)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def refresh_token(refresh_token)
|
|
25
|
-
@http.post("/api/Account/refresh-token", body: { refreshToken: refresh_token })
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def logout
|
|
29
|
-
@http.post("/api/Account/logout")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def get_profile
|
|
33
|
-
@http.get("/api/Account/profile")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def update_profile(data)
|
|
37
|
-
@http.put("/api/Account/profile", body: data)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def change_password(current_password:, new_password:)
|
|
41
|
-
@http.post("/api/Account/change-password", body: { currentPassword: current_password, newPassword: new_password })
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def forgot_password(email:)
|
|
45
|
-
@http.post("/api/Account/forgot-password", body: { email: email })
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def reset_password(token:, new_password:)
|
|
49
|
-
@http.post("/api/Account/reset-password", body: { token: token, newPassword: new_password })
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def verify_email(token:)
|
|
53
|
-
@http.post("/api/Account/verify-email", body: { token: token })
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
1
|
+
# ***********************************************************************
|
|
2
|
+
# Package : flexops
|
|
3
|
+
# Author : FlexOps, LLC
|
|
4
|
+
# Created : 2026-03-08
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2021-2026 by FlexOps, LLC. All rights reserved.
|
|
7
|
+
# ***********************************************************************
|
|
8
|
+
|
|
9
|
+
module FlexOps
|
|
10
|
+
module Resources
|
|
11
|
+
class Auth
|
|
12
|
+
def initialize(http)
|
|
13
|
+
@http = http
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def login(email:, password:)
|
|
17
|
+
@http.post("/api/Account/login", body: { email: email, password: password })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def register(request)
|
|
21
|
+
@http.post("/api/Account/register", body: request)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def refresh_token(refresh_token)
|
|
25
|
+
@http.post("/api/Account/refresh-token", body: { refreshToken: refresh_token })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def logout
|
|
29
|
+
@http.post("/api/Account/logout")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_profile
|
|
33
|
+
@http.get("/api/Account/profile")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def update_profile(data)
|
|
37
|
+
@http.put("/api/Account/profile", body: data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def change_password(current_password:, new_password:)
|
|
41
|
+
@http.post("/api/Account/change-password", body: { currentPassword: current_password, newPassword: new_password })
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def forgot_password(email:)
|
|
45
|
+
@http.post("/api/Account/forgot-password", body: { email: email })
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reset_password(token:, new_password:)
|
|
49
|
+
@http.post("/api/Account/reset-password", body: { token: token, newPassword: new_password })
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def verify_email(token:)
|
|
53
|
+
@http.post("/api/Account/verify-email", body: { token: token })
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|