exa-ai 0.4.1 → 0.6.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 +10 -0
- data/exe/exa-ai +61 -7
- data/exe/exa-ai-answer +9 -8
- data/exe/exa-ai-context +6 -5
- data/exe/exa-ai-enrichment-cancel +1 -0
- data/exe/exa-ai-enrichment-create +1 -0
- data/exe/exa-ai-enrichment-delete +1 -0
- data/exe/exa-ai-enrichment-get +1 -0
- data/exe/exa-ai-enrichment-list +1 -0
- data/exe/exa-ai-enrichment-update +1 -0
- data/exe/exa-ai-find-similar +1 -0
- data/exe/exa-ai-get-contents +9 -8
- data/exe/exa-ai-import-create +235 -0
- data/exe/exa-ai-import-delete +92 -0
- data/exe/exa-ai-import-get +92 -0
- data/exe/exa-ai-import-list +72 -0
- data/exe/exa-ai-import-update +164 -0
- data/exe/exa-ai-monitor-create +223 -0
- data/exe/exa-ai-monitor-delete +101 -0
- data/exe/exa-ai-monitor-get +92 -0
- data/exe/exa-ai-monitor-list +90 -0
- data/exe/exa-ai-monitor-runs-get +103 -0
- data/exe/exa-ai-monitor-runs-list +110 -0
- data/exe/exa-ai-monitor-update +207 -0
- data/exe/exa-ai-research-get +7 -7
- data/exe/exa-ai-research-list +5 -5
- data/exe/exa-ai-research-start +8 -7
- data/exe/exa-ai-search +20 -13
- data/exe/exa-ai-webset-cancel +1 -0
- data/exe/exa-ai-webset-create +44 -6
- data/exe/exa-ai-webset-delete +1 -0
- data/exe/exa-ai-webset-get +1 -0
- data/exe/exa-ai-webset-item-get +1 -0
- data/exe/exa-ai-webset-item-list +1 -0
- data/exe/exa-ai-webset-list +1 -0
- data/exe/exa-ai-webset-search-cancel +1 -0
- data/exe/exa-ai-webset-search-create +1 -0
- data/exe/exa-ai-webset-search-get +1 -0
- data/exe/exa-ai-webset-update +1 -0
- data/lib/exa/cli/base.rb +8 -2
- data/lib/exa/cli/formatters/answer_formatter.rb +2 -0
- data/lib/exa/cli/formatters/contents_formatter.rb +2 -0
- data/lib/exa/cli/formatters/context_formatter.rb +2 -0
- data/lib/exa/cli/formatters/enrichment_formatter.rb +4 -0
- data/lib/exa/cli/formatters/import_formatter.rb +85 -0
- data/lib/exa/cli/formatters/monitor_formatter.rb +81 -0
- data/lib/exa/cli/formatters/monitor_run_formatter.rb +75 -0
- data/lib/exa/cli/formatters/research_formatter.rb +4 -0
- data/lib/exa/cli/formatters/search_formatter.rb +2 -0
- data/lib/exa/cli/formatters/webset_formatter.rb +4 -0
- data/lib/exa/cli/formatters/webset_item_formatter.rb +4 -0
- data/lib/exa/client.rb +137 -0
- data/lib/exa/constants/websets.rb +19 -0
- data/lib/exa/middleware/raise_error.rb +5 -0
- data/lib/exa/resources/import.rb +86 -0
- data/lib/exa/resources/import_collection.rb +33 -0
- data/lib/exa/resources/monitor.rb +48 -0
- data/lib/exa/resources/monitor_collection.rb +30 -0
- data/lib/exa/resources/monitor_run.rb +52 -0
- data/lib/exa/resources/monitor_run_collection.rb +30 -0
- data/lib/exa/services/search.rb +21 -1
- data/lib/exa/services/websets/create_validator.rb +5 -3
- data/lib/exa/services/websets/import_create.rb +40 -0
- data/lib/exa/services/websets/import_delete.rb +37 -0
- data/lib/exa/services/websets/import_get.rb +37 -0
- data/lib/exa/services/websets/import_list.rb +25 -0
- data/lib/exa/services/websets/import_update.rb +38 -0
- data/lib/exa/services/websets/import_upload.rb +58 -0
- data/lib/exa/services/websets/monitors/create.rb +42 -0
- data/lib/exa/services/websets/monitors/delete.rb +32 -0
- data/lib/exa/services/websets/monitors/get.rb +33 -0
- data/lib/exa/services/websets/monitors/list.rb +27 -0
- data/lib/exa/services/websets/monitors/runs/get.rb +37 -0
- data/lib/exa/services/websets/monitors/runs/list.rb +30 -0
- data/lib/exa/services/websets/monitors/update.rb +33 -0
- data/lib/exa/version.rb +1 -1
- data/lib/exa.rb +23 -0
- metadata +50 -1
data/exe/exa-ai-research-start
CHANGED
|
@@ -39,7 +39,7 @@ def parse_args(argv)
|
|
|
39
39
|
i += 2
|
|
40
40
|
when "--help", "-h"
|
|
41
41
|
puts <<~HELP
|
|
42
|
-
Usage: exa-
|
|
42
|
+
Usage: exa-ai research-start --instructions "TEXT" [OPTIONS]
|
|
43
43
|
|
|
44
44
|
Start a research task using Exa AI
|
|
45
45
|
|
|
@@ -54,10 +54,10 @@ def parse_args(argv)
|
|
|
54
54
|
--help, -h Show this help message
|
|
55
55
|
|
|
56
56
|
Examples:
|
|
57
|
-
exa-
|
|
58
|
-
exa-
|
|
59
|
-
exa-
|
|
60
|
-
exa-
|
|
57
|
+
exa-ai research-start --instructions "Find Ruby performance tips"
|
|
58
|
+
exa-ai research-start --instructions "Analyze AI trends" --wait --events
|
|
59
|
+
exa-ai research-start --instructions "Summarize papers" --model exa-research-pro --wait
|
|
60
|
+
exa-ai research-start --instructions "Find stats" --output-schema '{"type":"object"}'
|
|
61
61
|
HELP
|
|
62
62
|
exit 0
|
|
63
63
|
else
|
|
@@ -75,7 +75,7 @@ begin
|
|
|
75
75
|
# Validate instructions
|
|
76
76
|
if args[:instructions].nil? || args[:instructions].empty?
|
|
77
77
|
$stderr.puts "Error: --instructions flag is required"
|
|
78
|
-
$stderr.puts "Run 'exa-
|
|
78
|
+
$stderr.puts "Run 'exa-ai research-start --help' for usage information"
|
|
79
79
|
exit 1
|
|
80
80
|
end
|
|
81
81
|
|
|
@@ -133,6 +133,7 @@ begin
|
|
|
133
133
|
# Format and output final result
|
|
134
134
|
output = Exa::CLI::Formatters::ResearchFormatter.format_task(final_task, output_format, show_events: args[:events])
|
|
135
135
|
puts output
|
|
136
|
+
$stdout.flush
|
|
136
137
|
|
|
137
138
|
# Exit with error code if task failed
|
|
138
139
|
exit 1 if final_task.failed?
|
|
@@ -140,7 +141,7 @@ begin
|
|
|
140
141
|
rescue Exa::CLI::Polling::TimeoutError => e
|
|
141
142
|
$stderr.puts "\nError: Task did not complete within timeout period (5 minutes)"
|
|
142
143
|
$stderr.puts "Task ID: #{task.research_id}"
|
|
143
|
-
$stderr.puts "You can check the status later with: exa-
|
|
144
|
+
$stderr.puts "You can check the status later with: exa-ai research-get #{task.research_id}"
|
|
144
145
|
exit 1
|
|
145
146
|
end
|
|
146
147
|
else
|
data/exe/exa-ai-search
CHANGED
|
@@ -20,7 +20,13 @@ def parse_args(argv)
|
|
|
20
20
|
args[:num_results] = argv[i + 1].to_i
|
|
21
21
|
i += 2
|
|
22
22
|
when "--type"
|
|
23
|
-
|
|
23
|
+
search_type = argv[i + 1]
|
|
24
|
+
valid_types = ["fast", "deep", "keyword", "auto"]
|
|
25
|
+
unless valid_types.include?(search_type)
|
|
26
|
+
$stderr.puts "Error: Search type must be one of: #{valid_types.join(', ')}"
|
|
27
|
+
exit 1
|
|
28
|
+
end
|
|
29
|
+
args[:type] = search_type
|
|
24
30
|
i += 2
|
|
25
31
|
when "--category"
|
|
26
32
|
category = argv[i + 1]
|
|
@@ -116,7 +122,7 @@ def parse_args(argv)
|
|
|
116
122
|
i += 2
|
|
117
123
|
when "--help", "-h"
|
|
118
124
|
puts <<~HELP
|
|
119
|
-
Usage: exa-
|
|
125
|
+
Usage: exa-ai search QUERY [OPTIONS]
|
|
120
126
|
|
|
121
127
|
Search the web using Exa AI
|
|
122
128
|
|
|
@@ -125,7 +131,7 @@ def parse_args(argv)
|
|
|
125
131
|
|
|
126
132
|
Options:
|
|
127
133
|
--num-results N Number of results to return (default: 10)
|
|
128
|
-
--type TYPE Search type:
|
|
134
|
+
--type TYPE Search type: fast, deep, keyword, or auto (default: fast)
|
|
129
135
|
--category CAT Focus on specific data category
|
|
130
136
|
Options: "company", "research paper", "news", "pdf",
|
|
131
137
|
"github", "tweet", "personal site", "linkedin profile",
|
|
@@ -160,15 +166,15 @@ def parse_args(argv)
|
|
|
160
166
|
--help, -h Show this help message
|
|
161
167
|
|
|
162
168
|
Examples:
|
|
163
|
-
exa-
|
|
164
|
-
exa-
|
|
165
|
-
exa-
|
|
166
|
-
exa-
|
|
167
|
-
exa-
|
|
168
|
-
exa-
|
|
169
|
-
exa-
|
|
170
|
-
exa-
|
|
171
|
-
exa-
|
|
169
|
+
exa-ai search "ruby programming"
|
|
170
|
+
exa-ai search "machine learning" --num-results 5 --type deep
|
|
171
|
+
exa-ai search "Latest LLM research" --category "research paper"
|
|
172
|
+
exa-ai search "AI startups" --category company
|
|
173
|
+
exa-ai search "Anthropic" --linkedin company
|
|
174
|
+
exa-ai search "Dario Amodei" --linkedin person
|
|
175
|
+
exa-ai search "AI" --linkedin all
|
|
176
|
+
exa-ai search "AI research" --include-domains arxiv.org,scholar.google.com
|
|
177
|
+
exa-ai search "tutorials" --output-format pretty
|
|
172
178
|
HELP
|
|
173
179
|
exit 0
|
|
174
180
|
else
|
|
@@ -237,7 +243,7 @@ begin
|
|
|
237
243
|
# Validate query
|
|
238
244
|
if args[:query].nil? || args[:query].empty?
|
|
239
245
|
$stderr.puts "Error: Query is required"
|
|
240
|
-
$stderr.puts "Run 'exa-
|
|
246
|
+
$stderr.puts "Run 'exa-ai search --help' for usage information"
|
|
241
247
|
exit 1
|
|
242
248
|
end
|
|
243
249
|
|
|
@@ -281,6 +287,7 @@ begin
|
|
|
281
287
|
# Format and output result
|
|
282
288
|
output = Exa::CLI::Formatters::SearchFormatter.format(result, output_format)
|
|
283
289
|
puts output
|
|
290
|
+
$stdout.flush
|
|
284
291
|
|
|
285
292
|
rescue Exa::ConfigurationError => e
|
|
286
293
|
$stderr.puts "Configuration error: #{e.message}"
|
data/exe/exa-ai-webset-cancel
CHANGED
data/exe/exa-ai-webset-create
CHANGED
|
@@ -46,6 +46,9 @@ def parse_args(argv)
|
|
|
46
46
|
while i < argv.length
|
|
47
47
|
arg = argv[i]
|
|
48
48
|
case arg
|
|
49
|
+
when "--import"
|
|
50
|
+
args[:import] = argv[i + 1]
|
|
51
|
+
i += 2
|
|
49
52
|
when "--search"
|
|
50
53
|
args[:search] = parse_json_or_file(argv[i + 1])
|
|
51
54
|
i += 2
|
|
@@ -72,12 +75,14 @@ def parse_args(argv)
|
|
|
72
75
|
i += 2
|
|
73
76
|
when "--help", "-h"
|
|
74
77
|
puts <<~HELP
|
|
75
|
-
Usage: exa-ai webset-create --search JSON [OPTIONS]
|
|
78
|
+
Usage: exa-ai webset-create (--search JSON | --import ID) [OPTIONS]
|
|
76
79
|
|
|
77
|
-
Create a new webset
|
|
80
|
+
Create a new webset from search criteria or an import
|
|
78
81
|
|
|
79
|
-
Required:
|
|
82
|
+
Required (choose one):
|
|
80
83
|
--search JSON Search configuration (supports @file.json)
|
|
84
|
+
--import ID Import or webset ID to create webset from
|
|
85
|
+
(accepts import_* or webset_* IDs)
|
|
81
86
|
|
|
82
87
|
Options:
|
|
83
88
|
--enrichments JSON Array of enrichment configs (supports @file.json)
|
|
@@ -90,9 +95,17 @@ def parse_args(argv)
|
|
|
90
95
|
--help, -h Show this help message
|
|
91
96
|
|
|
92
97
|
Examples:
|
|
98
|
+
# Create webset from search
|
|
93
99
|
exa-ai webset-create --search '{"query":"AI startups","count":10}'
|
|
94
100
|
exa-ai webset-create --search @search.json --enrichments @enrichments.json
|
|
95
101
|
exa-ai webset-create --search @search.json --wait
|
|
102
|
+
|
|
103
|
+
# Create webset from import
|
|
104
|
+
exa-ai webset-create --import import_abc123
|
|
105
|
+
exa-ai webset-create --import import_def456 --enrichments @enrichments.json
|
|
106
|
+
|
|
107
|
+
# Create webset from existing webset
|
|
108
|
+
exa-ai webset-create --import webset_xyz789
|
|
96
109
|
HELP
|
|
97
110
|
exit 0
|
|
98
111
|
else
|
|
@@ -109,8 +122,14 @@ begin
|
|
|
109
122
|
args = parse_args(ARGV)
|
|
110
123
|
|
|
111
124
|
# Validate required parameters
|
|
112
|
-
|
|
113
|
-
$stderr.puts "Error: --search
|
|
125
|
+
if args[:search] && args[:import]
|
|
126
|
+
$stderr.puts "Error: Cannot specify both --search and --import"
|
|
127
|
+
$stderr.puts "Run 'exa-ai webset-create --help' for usage information"
|
|
128
|
+
exit 1
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
unless args[:search] || args[:import]
|
|
132
|
+
$stderr.puts "Error: Either --search or --import is required"
|
|
114
133
|
$stderr.puts "Run 'exa-ai webset-create --help' for usage information"
|
|
115
134
|
exit 1
|
|
116
135
|
end
|
|
@@ -125,7 +144,25 @@ begin
|
|
|
125
144
|
client = Exa::CLI::Base.build_client(api_key)
|
|
126
145
|
|
|
127
146
|
# Prepare webset parameters
|
|
128
|
-
webset_params = {
|
|
147
|
+
webset_params = {}
|
|
148
|
+
|
|
149
|
+
if args[:search]
|
|
150
|
+
webset_params[:search] = args[:search]
|
|
151
|
+
elsif args[:import]
|
|
152
|
+
# Detect source type from ID prefix and convert to API format
|
|
153
|
+
import_id = args[:import]
|
|
154
|
+
source = if import_id.start_with?("import_")
|
|
155
|
+
"import"
|
|
156
|
+
elsif import_id.start_with?("webset_")
|
|
157
|
+
"webset"
|
|
158
|
+
else
|
|
159
|
+
$stderr.puts "Error: Import ID must start with 'import_' or 'webset_'"
|
|
160
|
+
exit 1
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
webset_params[:import] = [{ source: source, id: import_id }]
|
|
164
|
+
end
|
|
165
|
+
|
|
129
166
|
webset_params[:enrichments] = args[:enrichments] if args[:enrichments]
|
|
130
167
|
webset_params[:exclude] = args[:exclude] if args[:exclude]
|
|
131
168
|
webset_params[:externalId] = args[:external_id] if args[:external_id]
|
|
@@ -167,6 +204,7 @@ begin
|
|
|
167
204
|
# Format and output result
|
|
168
205
|
output = Exa::CLI::Formatters::WebsetFormatter.format(webset, output_format)
|
|
169
206
|
puts output
|
|
207
|
+
$stdout.flush
|
|
170
208
|
|
|
171
209
|
rescue Exa::ConfigurationError => e
|
|
172
210
|
$stderr.puts "Configuration error: #{e.message}"
|
data/exe/exa-ai-webset-delete
CHANGED
data/exe/exa-ai-webset-get
CHANGED
data/exe/exa-ai-webset-item-get
CHANGED
data/exe/exa-ai-webset-item-list
CHANGED
data/exe/exa-ai-webset-list
CHANGED
data/exe/exa-ai-webset-update
CHANGED
data/lib/exa/cli/base.rb
CHANGED
|
@@ -16,11 +16,11 @@ module Exa
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# Resolve and validate output format
|
|
19
|
-
# Valid formats: json, pretty, text
|
|
19
|
+
# Valid formats: json, pretty, text, toon
|
|
20
20
|
# Defaults to json
|
|
21
21
|
def self.resolve_output_format(flag_value)
|
|
22
22
|
format = (flag_value || "json").downcase
|
|
23
|
-
valid_formats = %w[json pretty text]
|
|
23
|
+
valid_formats = %w[json pretty text toon]
|
|
24
24
|
|
|
25
25
|
return format if valid_formats.include?(format)
|
|
26
26
|
|
|
@@ -46,6 +46,12 @@ module Exa
|
|
|
46
46
|
data.to_s
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
+
|
|
50
|
+
# Encode data as TOON format
|
|
51
|
+
def self.encode_as_toon(data)
|
|
52
|
+
require "toon" unless defined?(Toon)
|
|
53
|
+
Toon.encode(data)
|
|
54
|
+
end
|
|
49
55
|
end
|
|
50
56
|
end
|
|
51
57
|
end
|
|
@@ -12,6 +12,8 @@ module Exa
|
|
|
12
12
|
JSON.pretty_generate(enrichment.to_h)
|
|
13
13
|
when "text"
|
|
14
14
|
format_as_text(enrichment)
|
|
15
|
+
when "toon"
|
|
16
|
+
Exa::CLI::Base.encode_as_toon(enrichment.to_h)
|
|
15
17
|
else
|
|
16
18
|
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
17
19
|
end
|
|
@@ -25,6 +27,8 @@ module Exa
|
|
|
25
27
|
JSON.pretty_generate(collection.to_h)
|
|
26
28
|
when "text"
|
|
27
29
|
format_collection_as_text(collection)
|
|
30
|
+
when "toon"
|
|
31
|
+
Exa::CLI::Base.encode_as_toon(collection.to_h)
|
|
28
32
|
else
|
|
29
33
|
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
30
34
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exa
|
|
4
|
+
module CLI
|
|
5
|
+
module Formatters
|
|
6
|
+
class ImportFormatter
|
|
7
|
+
def self.format(import, output_format)
|
|
8
|
+
case output_format
|
|
9
|
+
when "json"
|
|
10
|
+
JSON.generate(import.to_h)
|
|
11
|
+
when "pretty"
|
|
12
|
+
JSON.pretty_generate(import.to_h)
|
|
13
|
+
when "text"
|
|
14
|
+
format_as_text(import)
|
|
15
|
+
when "toon"
|
|
16
|
+
Exa::CLI::Base.encode_as_toon(import.to_h)
|
|
17
|
+
else
|
|
18
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.format_collection(collection, output_format)
|
|
23
|
+
case output_format
|
|
24
|
+
when "json"
|
|
25
|
+
JSON.generate(collection.to_h)
|
|
26
|
+
when "pretty"
|
|
27
|
+
JSON.pretty_generate(collection.to_h)
|
|
28
|
+
when "text"
|
|
29
|
+
format_collection_as_text(collection)
|
|
30
|
+
when "toon"
|
|
31
|
+
Exa::CLI::Base.encode_as_toon(collection.to_h)
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.format_as_text(import)
|
|
38
|
+
lines = []
|
|
39
|
+
lines << "Import: #{import.id}"
|
|
40
|
+
lines << "Status: #{import.status}"
|
|
41
|
+
lines << "Title: #{import.title}" if import.title
|
|
42
|
+
lines << "Format: #{import.format}" if import.format
|
|
43
|
+
|
|
44
|
+
if import.entity
|
|
45
|
+
entity_type = import.entity['type'] || import.entity[:type]
|
|
46
|
+
lines << "Entity Type: #{entity_type}" if entity_type
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
lines << "Count: #{import.count}" if import.count
|
|
50
|
+
|
|
51
|
+
if import.failed?
|
|
52
|
+
lines << "\nFailure Details:"
|
|
53
|
+
lines << " Reason: #{import.failed_reason}" if import.failed_reason
|
|
54
|
+
lines << " Message: #{import.failed_message}" if import.failed_message
|
|
55
|
+
lines << " Failed At: #{import.failed_at}" if import.failed_at
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if import.upload_url
|
|
59
|
+
lines << "\nUpload:"
|
|
60
|
+
lines << " URL: #{import.upload_url}"
|
|
61
|
+
lines << " Valid Until: #{import.upload_valid_until}" if import.upload_valid_until
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
lines << "\nCreated: #{import.created_at}" if import.created_at
|
|
65
|
+
lines << "Updated: #{import.updated_at}" if import.updated_at
|
|
66
|
+
|
|
67
|
+
lines.join("\n")
|
|
68
|
+
end
|
|
69
|
+
private_class_method :format_as_text
|
|
70
|
+
|
|
71
|
+
def self.format_collection_as_text(collection)
|
|
72
|
+
lines = ["Imports (#{collection.data.length} items):"]
|
|
73
|
+
collection.data.each do |imp|
|
|
74
|
+
lines << "\n #{imp.id}"
|
|
75
|
+
lines << " Status: #{imp.status}"
|
|
76
|
+
lines << " Title: #{imp.title}" if imp.title
|
|
77
|
+
lines << " Count: #{imp.count}" if imp.count
|
|
78
|
+
end
|
|
79
|
+
lines.join("\n")
|
|
80
|
+
end
|
|
81
|
+
private_class_method :format_collection_as_text
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exa
|
|
4
|
+
module CLI
|
|
5
|
+
module Formatters
|
|
6
|
+
class MonitorFormatter
|
|
7
|
+
def self.format(monitor, output_format)
|
|
8
|
+
case output_format
|
|
9
|
+
when "json"
|
|
10
|
+
JSON.generate(monitor.to_h)
|
|
11
|
+
when "pretty"
|
|
12
|
+
JSON.pretty_generate(monitor.to_h)
|
|
13
|
+
when "text"
|
|
14
|
+
format_as_text(monitor)
|
|
15
|
+
when "toon"
|
|
16
|
+
Exa::CLI::Base.encode_as_toon(monitor.to_h)
|
|
17
|
+
else
|
|
18
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.format_collection(collection, output_format)
|
|
23
|
+
case output_format
|
|
24
|
+
when "json"
|
|
25
|
+
JSON.generate(collection.to_h)
|
|
26
|
+
when "pretty"
|
|
27
|
+
JSON.pretty_generate(collection.to_h)
|
|
28
|
+
when "text"
|
|
29
|
+
format_collection_as_text(collection)
|
|
30
|
+
when "toon"
|
|
31
|
+
Exa::CLI::Base.encode_as_toon(collection.to_h)
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.format_as_text(monitor)
|
|
38
|
+
lines = []
|
|
39
|
+
lines << "Monitor: #{monitor.id}"
|
|
40
|
+
lines << "Webset: #{monitor.webset_id}" if monitor.webset_id
|
|
41
|
+
lines << "Status: #{monitor.status}"
|
|
42
|
+
|
|
43
|
+
if monitor.cadence
|
|
44
|
+
lines << "\nCadence:"
|
|
45
|
+
lines << " Cron: #{monitor.cadence['cron']}" if monitor.cadence['cron']
|
|
46
|
+
lines << " Timezone: #{monitor.cadence['timezone']}" if monitor.cadence['timezone']
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if monitor.behavior
|
|
50
|
+
lines << "\nBehavior:"
|
|
51
|
+
lines << " Type: #{monitor.behavior['type']}" if monitor.behavior['type']
|
|
52
|
+
lines << " Query: #{monitor.behavior['query']}" if monitor.behavior['query']
|
|
53
|
+
lines << " Count: #{monitor.behavior['count']}" if monitor.behavior['count']
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
lines << "\nCreated: #{monitor.created_at}" if monitor.created_at
|
|
57
|
+
lines << "Updated: #{monitor.updated_at}" if monitor.updated_at
|
|
58
|
+
|
|
59
|
+
lines.join("\n")
|
|
60
|
+
end
|
|
61
|
+
private_class_method :format_as_text
|
|
62
|
+
|
|
63
|
+
def self.format_collection_as_text(collection)
|
|
64
|
+
lines = ["Monitors (#{collection.data.length} items):"]
|
|
65
|
+
collection.data.each do |mon|
|
|
66
|
+
lines << "\n #{mon['id']}"
|
|
67
|
+
lines << " Status: #{mon['status']}"
|
|
68
|
+
lines << " Webset: #{mon['websetId']}" if mon['websetId']
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if collection.has_more
|
|
72
|
+
lines << "\nMore available (cursor: #{collection.next_cursor})"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
lines.join("\n")
|
|
76
|
+
end
|
|
77
|
+
private_class_method :format_collection_as_text
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Exa
|
|
4
|
+
module CLI
|
|
5
|
+
module Formatters
|
|
6
|
+
class MonitorRunFormatter
|
|
7
|
+
def self.format(monitor_run, output_format)
|
|
8
|
+
case output_format
|
|
9
|
+
when "json"
|
|
10
|
+
JSON.generate(monitor_run.to_h)
|
|
11
|
+
when "pretty"
|
|
12
|
+
JSON.pretty_generate(monitor_run.to_h)
|
|
13
|
+
when "text"
|
|
14
|
+
format_as_text(monitor_run)
|
|
15
|
+
when "toon"
|
|
16
|
+
Exa::CLI::Base.encode_as_toon(monitor_run.to_h)
|
|
17
|
+
else
|
|
18
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.format_collection(collection, output_format)
|
|
23
|
+
case output_format
|
|
24
|
+
when "json"
|
|
25
|
+
JSON.generate(collection.to_h)
|
|
26
|
+
when "pretty"
|
|
27
|
+
JSON.pretty_generate(collection.to_h)
|
|
28
|
+
when "text"
|
|
29
|
+
format_collection_as_text(collection)
|
|
30
|
+
when "toon"
|
|
31
|
+
Exa::CLI::Base.encode_as_toon(collection.to_h)
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Unknown output format: #{output_format}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.format_as_text(monitor_run)
|
|
38
|
+
lines = []
|
|
39
|
+
lines << "Monitor Run: #{monitor_run.id}"
|
|
40
|
+
lines << "Monitor: #{monitor_run.monitor_id}" if monitor_run.monitor_id
|
|
41
|
+
lines << "Status: #{monitor_run.status}"
|
|
42
|
+
|
|
43
|
+
lines << "\nCreated: #{monitor_run.created_at}" if monitor_run.created_at
|
|
44
|
+
lines << "Updated: #{monitor_run.updated_at}" if monitor_run.updated_at
|
|
45
|
+
lines << "Completed: #{monitor_run.completed_at}" if monitor_run.completed_at
|
|
46
|
+
|
|
47
|
+
if monitor_run.failed?
|
|
48
|
+
lines << "Failed: #{monitor_run.failed_at}" if monitor_run.failed_at
|
|
49
|
+
lines << "Reason: #{monitor_run.failed_reason}" if monitor_run.failed_reason
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
lines.join("\n")
|
|
53
|
+
end
|
|
54
|
+
private_class_method :format_as_text
|
|
55
|
+
|
|
56
|
+
def self.format_collection_as_text(collection)
|
|
57
|
+
lines = ["Monitor Runs (#{collection.data.length} items):"]
|
|
58
|
+
collection.data.each do |run|
|
|
59
|
+
lines << "\n #{run['id']}"
|
|
60
|
+
lines << " Status: #{run['status']}"
|
|
61
|
+
lines << " Completed: #{run['completedAt']}" if run['completedAt']
|
|
62
|
+
lines << " Failed: #{run['failedReason']}" if run['failedReason']
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if collection.has_more
|
|
66
|
+
lines << "\nMore available (cursor: #{collection.next_cursor})"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
lines.join("\n")
|
|
70
|
+
end
|
|
71
|
+
private_class_method :format_collection_as_text
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -10,6 +10,8 @@ module Exa
|
|
|
10
10
|
format_task_pretty(task, show_events: show_events)
|
|
11
11
|
when "text"
|
|
12
12
|
format_task_text(task, show_events: show_events)
|
|
13
|
+
when "toon"
|
|
14
|
+
Exa::CLI::Base.encode_as_toon(task.to_h)
|
|
13
15
|
else
|
|
14
16
|
JSON.pretty_generate(task.to_h)
|
|
15
17
|
end
|
|
@@ -23,6 +25,8 @@ module Exa
|
|
|
23
25
|
format_list_pretty(list)
|
|
24
26
|
when "text"
|
|
25
27
|
format_list_text(list)
|
|
28
|
+
when "toon"
|
|
29
|
+
Exa::CLI::Base.encode_as_toon(list.to_h)
|
|
26
30
|
else
|
|
27
31
|
JSON.pretty_generate(list.to_h)
|
|
28
32
|
end
|