code-ruby 5.2.3 → 6.0.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/VERSION +1 -1
- data/lib/code/concerns/shared.rb +8 -4
- data/lib/code/format.rb +22 -3
- data/lib/code/object/http.rb +30 -15
- data/lib/code/object/string.rb +3 -1
- data/lib/code/parser.rb +6 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1aec9dbb3d232f6cd9f80c2094505b60ad1f6d3ffb974fcc99ce1ccf06d7772c
|
|
4
|
+
data.tar.gz: 706e9983a36f38bad9687abb1edbbab6a546e63e643397b7bcbd50a8e21549a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65f90487ee1e6110b87605d7014963b44664912591291c2c5d3bac4b72303bec0c7955825c2b0d9f50ec3c1d25bb63d5b0815732ad79c1a8d65505efc74b3414
|
|
7
|
+
data.tar.gz: 9715125c292a852fe2f18179c3305e5b1f890ffd20661c4db509d359dee2099a42930a4befddce72666e9825239c174b76b6e43789752dc7afa32f42f2ce8a77
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
6.0.0
|
data/lib/code/concerns/shared.rb
CHANGED
|
@@ -319,10 +319,14 @@ class Code
|
|
|
319
319
|
|
|
320
320
|
code_context.code_fetch(self)
|
|
321
321
|
else
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
if code_operator.to_s.match?(/\A[A-Z]/)
|
|
323
|
+
raise(
|
|
324
|
+
Error,
|
|
325
|
+
"#{code_operator.inspect} not defined on #{code_inspect}:#{code_name}"
|
|
326
|
+
)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
Object::Nothing.new
|
|
326
330
|
end
|
|
327
331
|
end
|
|
328
332
|
|
data/lib/code/format.rb
CHANGED
|
@@ -201,7 +201,7 @@ class Code
|
|
|
201
201
|
return nil unless node.is_a?(Hash) && node.key?(:text)
|
|
202
202
|
|
|
203
203
|
text = node[:text].to_s
|
|
204
|
-
return nil unless text.match?(/\A[a-z_][a-z0-9_]
|
|
204
|
+
return nil unless text.match?(/\A[a-z_][a-z0-9_]*[?!]?\z/)
|
|
205
205
|
|
|
206
206
|
":#{text}"
|
|
207
207
|
end
|
|
@@ -349,7 +349,7 @@ class Code
|
|
|
349
349
|
return unless part.is_a?(Hash) && part.key?(:text)
|
|
350
350
|
|
|
351
351
|
text = part[:text].to_s
|
|
352
|
-
return unless text.match?(/\A[a-z_][a-z0-9_]
|
|
352
|
+
return unless text.match?(/\A[a-z_][a-z0-9_]*[?!]?\z/)
|
|
353
353
|
|
|
354
354
|
text
|
|
355
355
|
end
|
|
@@ -464,7 +464,11 @@ class Code
|
|
|
464
464
|
|
|
465
465
|
Array(operation[:others]).each do |other|
|
|
466
466
|
operator = format_operator(other[:operator])
|
|
467
|
-
right =
|
|
467
|
+
right = if compact_operator?(operator)
|
|
468
|
+
format_member_statement(other[:statement], indent: indent)
|
|
469
|
+
else
|
|
470
|
+
format_boolean_operand(other[:statement], operator, indent: indent)
|
|
471
|
+
end
|
|
468
472
|
|
|
469
473
|
expression =
|
|
470
474
|
if compact_operator?(operator)
|
|
@@ -511,6 +515,21 @@ class Code
|
|
|
511
515
|
expression
|
|
512
516
|
end
|
|
513
517
|
|
|
518
|
+
def format_member_statement(statement, indent:)
|
|
519
|
+
if statement.is_a?(Hash) && statement[:call] && (statement[:call][:arguments] || []).empty?
|
|
520
|
+
format_call(statement[:call].except(:arguments), indent: indent)
|
|
521
|
+
elsif statement.is_a?(Hash) && statement[:left_operation]
|
|
522
|
+
operation = statement[:left_operation].deep_dup
|
|
523
|
+
first = operation[:first]
|
|
524
|
+
if first[:call] && (first[:call][:arguments] || []).empty?
|
|
525
|
+
first[:call].delete(:arguments)
|
|
526
|
+
end
|
|
527
|
+
format_left_operation(operation, indent: indent)
|
|
528
|
+
else
|
|
529
|
+
format_nested_statement(statement, indent: indent)
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
|
|
514
533
|
def format_boolean_operand(statement, operator, indent:)
|
|
515
534
|
if BOOLEAN_WORD_OPERATORS.include?(operator) && statement.is_a?(Hash) &&
|
|
516
535
|
statement[:left_operation]
|
data/lib/code/object/http.rb
CHANGED
|
@@ -199,6 +199,20 @@ class Code
|
|
|
199
199
|
}.freeze
|
|
200
200
|
DEFAULT_TIMEOUT = 30
|
|
201
201
|
DEFAULT_OPEN_TIMEOUT = 10
|
|
202
|
+
DEFAULT_REDIRECTS = 0
|
|
203
|
+
DEFAULT_MAX_RETRIES = 0
|
|
204
|
+
DEFAULT_RETRY_DELAYS = [].freeze
|
|
205
|
+
MAX_REDIRECTS = 10
|
|
206
|
+
MAX_RETRIES = 5
|
|
207
|
+
MAX_RETRY_DELAY = 60
|
|
208
|
+
MAX_RESPONSE_BYTES = 50.megabytes
|
|
209
|
+
SAFE_RETRY_METHODS = %w[get head options].freeze
|
|
210
|
+
RETRYABLE_ERRORS = ["http timeout", "http error"].freeze
|
|
211
|
+
RETRYABLE_STATUSES = [408, 429].freeze
|
|
212
|
+
SERVER_ERROR_STATUSES = (500..599)
|
|
213
|
+
SUCCESS_STATUSES = (200..299)
|
|
214
|
+
REDIRECT_STATUSES = (300..399)
|
|
215
|
+
PRESERVE_METHOD_REDIRECT_STATUSES = [307, 308].freeze
|
|
202
216
|
MAX_HEADER_BYTES = 32.kilobytes
|
|
203
217
|
HEADER_NAME = /\A[A-Za-z0-9!#$%&'*+\-.^_`|~]+\z/
|
|
204
218
|
RESTRICTED_HEADERS = %w[
|
|
@@ -285,16 +299,16 @@ class Code
|
|
|
285
299
|
options = arguments.third.to_code
|
|
286
300
|
options = Dictionary.new if options.nothing?
|
|
287
301
|
delays = options.code_get("retry_delays")
|
|
288
|
-
delays = delays.nothing? ?
|
|
289
|
-
unless delays.size <=
|
|
302
|
+
delays = delays.nothing? ? DEFAULT_RETRY_DELAYS : delays.as_json
|
|
303
|
+
unless delays.size <= MAX_RETRIES &&
|
|
290
304
|
delays.all? do |delay|
|
|
291
305
|
delay.is_a?(::Numeric) && delay.finite? &&
|
|
292
|
-
delay.between?(0,
|
|
306
|
+
delay.between?(0, MAX_RETRY_DELAY)
|
|
293
307
|
end
|
|
294
308
|
raise ::Code::Error, "http: invalid retry delays"
|
|
295
309
|
end
|
|
296
310
|
|
|
297
|
-
safe =
|
|
311
|
+
safe = SAFE_RETRY_METHODS.include?(arguments.first.to_s.downcase)
|
|
298
312
|
safe ||= options.code_get("retry_unsafe").truthy?
|
|
299
313
|
safe ||=
|
|
300
314
|
(options.code_get("headers").as_json || {}).any? do |key, value|
|
|
@@ -306,7 +320,7 @@ class Code
|
|
|
306
320
|
begin
|
|
307
321
|
response = code_request(*arguments, redirects: redirects)
|
|
308
322
|
rescue ::Code::Error => e
|
|
309
|
-
unless
|
|
323
|
+
unless RETRYABLE_ERRORS.include?(e.message) &&
|
|
310
324
|
attempt < delays.size
|
|
311
325
|
raise
|
|
312
326
|
end
|
|
@@ -316,7 +330,7 @@ class Code
|
|
|
316
330
|
next
|
|
317
331
|
end
|
|
318
332
|
status = response.code_get("code").raw
|
|
319
|
-
unless
|
|
333
|
+
unless RETRYABLE_STATUSES.include?(status) || SERVER_ERROR_STATUSES.cover?(status)
|
|
320
334
|
return response
|
|
321
335
|
end
|
|
322
336
|
return response if attempt >= delays.size
|
|
@@ -333,7 +347,7 @@ class Code
|
|
|
333
347
|
delay = delays[attempt]
|
|
334
348
|
end
|
|
335
349
|
end
|
|
336
|
-
return response if delay >
|
|
350
|
+
return response if delay > MAX_RETRY_DELAY
|
|
337
351
|
|
|
338
352
|
sleep(delay)
|
|
339
353
|
attempt += 1
|
|
@@ -349,7 +363,7 @@ class Code
|
|
|
349
363
|
redirects =
|
|
350
364
|
(
|
|
351
365
|
if options.code_get("redirects").nothing?
|
|
352
|
-
|
|
366
|
+
DEFAULT_REDIRECTS
|
|
353
367
|
else
|
|
354
368
|
options.code_get("redirects").raw
|
|
355
369
|
end
|
|
@@ -358,12 +372,13 @@ class Code
|
|
|
358
372
|
max_retries =
|
|
359
373
|
(
|
|
360
374
|
if options.code_get("max_retries").nothing?
|
|
361
|
-
|
|
375
|
+
DEFAULT_MAX_RETRIES
|
|
362
376
|
else
|
|
363
377
|
options.code_get("max_retries").raw
|
|
364
378
|
end
|
|
365
379
|
)
|
|
366
|
-
unless redirects.between?(0,
|
|
380
|
+
unless redirects.between?(0, MAX_REDIRECTS) &&
|
|
381
|
+
max_retries.between?(0, MAX_RETRIES)
|
|
367
382
|
raise ::Code::Error, "http: invalid request limits"
|
|
368
383
|
end
|
|
369
384
|
|
|
@@ -399,7 +414,7 @@ class Code
|
|
|
399
414
|
|
|
400
415
|
max_bytes = options.code_get("max_bytes")
|
|
401
416
|
max_bytes = max_bytes.nothing? ? nil : max_bytes.raw
|
|
402
|
-
if max_bytes && !max_bytes.between?(1,
|
|
417
|
+
if max_bytes && !max_bytes.between?(1, MAX_RESPONSE_BYTES)
|
|
403
418
|
raise ::Code::Error, "http: invalid response size limit"
|
|
404
419
|
end
|
|
405
420
|
|
|
@@ -472,12 +487,12 @@ class Code
|
|
|
472
487
|
code = response.code.to_i
|
|
473
488
|
location = response["location"].to_s
|
|
474
489
|
|
|
475
|
-
if
|
|
490
|
+
if REDIRECT_STATUSES.cover?(code) && location.present? && redirects.positive?
|
|
476
491
|
new_uri = parse_uri(::URI.join(uri, location).to_s)
|
|
477
492
|
::Code::Network.validate_public_uri!(new_uri, service: "http")
|
|
478
493
|
|
|
479
494
|
redirect_options = options.as_json.except("query")
|
|
480
|
-
redirect_method =
|
|
495
|
+
redirect_method = PRESERVE_METHOD_REDIRECT_STATUSES.include?(code) ? verb : "get"
|
|
481
496
|
unless same_origin?(new_uri, uri)
|
|
482
497
|
unless %w[get head].include?(redirect_method)
|
|
483
498
|
raise ::Code::Error,
|
|
@@ -509,8 +524,8 @@ class Code
|
|
|
509
524
|
:headers => response_headers,
|
|
510
525
|
:method => verb,
|
|
511
526
|
:url => url,
|
|
512
|
-
"success?" =>
|
|
513
|
-
"redirect?" =>
|
|
527
|
+
"success?" => SUCCESS_STATUSES.cover?(code),
|
|
528
|
+
"redirect?" => REDIRECT_STATUSES.cover?(code),
|
|
514
529
|
:request => {
|
|
515
530
|
method: verb,
|
|
516
531
|
url: url,
|
data/lib/code/object/string.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
class Code
|
|
4
4
|
class Object
|
|
5
5
|
class String < Object
|
|
6
|
+
DEFAULT_OMISSION = "…"
|
|
7
|
+
|
|
6
8
|
CLASS_DOCUMENTATION = {
|
|
7
9
|
name: "String",
|
|
8
10
|
description:
|
|
@@ -1224,7 +1226,7 @@ class Code
|
|
|
1224
1226
|
def code_truncate(limit, options = nil)
|
|
1225
1227
|
limit = limit.to_code.raw
|
|
1226
1228
|
omission = options.to_code.code_get("omission")
|
|
1227
|
-
omission = omission.nothing? ?
|
|
1229
|
+
omission = omission.nothing? ? DEFAULT_OMISSION : omission.to_s
|
|
1228
1230
|
if limit < omission.length
|
|
1229
1231
|
raise ::Code::Error, "invalid truncation limit"
|
|
1230
1232
|
end
|
data/lib/code/parser.rb
CHANGED
|
@@ -523,7 +523,12 @@ class Code
|
|
|
523
523
|
if match?(:punctuation, ":") || match?(:operator, "=>")
|
|
524
524
|
advance
|
|
525
525
|
code = parse_optional_code(%w[, }])
|
|
526
|
-
|
|
526
|
+
parts = statement[:string]
|
|
527
|
+
if parts&.one? && parts.first[:text]&.match?(/\A[a-z_][a-z0-9_]*[?!]?\z/)
|
|
528
|
+
{ name_code: { name: parts.first[:text], code: code }.compact }
|
|
529
|
+
else
|
|
530
|
+
{ statement_code: { statement: statement, code: code }.compact }
|
|
531
|
+
end
|
|
527
532
|
else
|
|
528
533
|
{ code: wrap_code(statement) }
|
|
529
534
|
end
|