json 2.9.1 → 2.10.1

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/json.gemspec CHANGED
@@ -11,14 +11,13 @@ spec = Gem::Specification.new do |s|
11
11
  s.version = version
12
12
 
13
13
  s.summary = "JSON Implementation for Ruby"
14
- s.homepage = "https://ruby.github.io/json"
14
+ s.homepage = "https://github.com/ruby/json"
15
15
  s.metadata = {
16
16
  'bug_tracker_uri' => 'https://github.com/ruby/json/issues',
17
17
  'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md',
18
- 'documentation_uri' => 'https://ruby.github.io/json/doc/index.html',
18
+ 'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html',
19
19
  'homepage_uri' => s.homepage,
20
20
  'source_code_uri' => 'https://github.com/ruby/json',
21
- 'wiki_uri' => 'https://github.com/ruby/json/wiki'
22
21
  }
23
22
 
24
23
  s.required_ruby_version = Gem::Requirement.new(">= 2.7")
@@ -53,7 +52,7 @@ spec = Gem::Specification.new do |s|
53
52
  s.files += Dir["lib/json/ext/**/*.jar"]
54
53
  else
55
54
  s.extensions = Dir["ext/json/**/extconf.rb"]
56
- s.files += Dir["ext/json/**/*.{c,h,rl}"]
55
+ s.files += Dir["ext/json/**/*.{c,h}"]
57
56
  end
58
57
  end
59
58
 
@@ -36,8 +36,13 @@ class Symbol
36
36
  #
37
37
  # # {"json_class":"Symbol","s":"foo"}
38
38
  #
39
- def to_json(*a)
40
- as_json.to_json(*a)
39
+ def to_json(state = nil, *a)
40
+ state = ::JSON::State.from_state(state)
41
+ if state.strict?
42
+ super
43
+ else
44
+ as_json.to_json(state, *a)
45
+ end
41
46
  end
42
47
 
43
48
  # See #as_json.
data/lib/json/common.rb CHANGED
@@ -167,6 +167,30 @@ module JSON
167
167
  # system. Usually this means that the iconv library is not installed.
168
168
  class MissingUnicodeSupport < JSONError; end
169
169
 
170
+ # Fragment of JSON document that is to be included as is:
171
+ # fragment = JSON::Fragment.new("[1, 2, 3]")
172
+ # JSON.generate({ count: 3, items: fragments })
173
+ #
174
+ # This allows to easily assemble multiple JSON fragments that have
175
+ # been persisted somewhere without having to parse them nor resorting
176
+ # to string interpolation.
177
+ #
178
+ # Note: no validation is performed on the provided string. It is the
179
+ # responsability of the caller to ensure the string contains valid JSON.
180
+ Fragment = Struct.new(:json) do
181
+ def initialize(json)
182
+ unless string = String.try_convert(json)
183
+ raise TypeError, " no implicit conversion of #{json.class} into String"
184
+ end
185
+
186
+ super(string)
187
+ end
188
+
189
+ def to_json(state = nil, *)
190
+ json
191
+ end
192
+ end
193
+
170
194
  module_function
171
195
 
172
196
  # :call-seq:
@@ -232,12 +256,13 @@ module JSON
232
256
  # - Option +max_nesting+, if not provided, defaults to +false+,
233
257
  # which disables checking for nesting depth.
234
258
  # - Option +allow_nan+, if not provided, defaults to +true+.
235
- def parse!(source, opts = {})
236
- opts = {
259
+ def parse!(source, opts = nil)
260
+ options = {
237
261
  :max_nesting => false,
238
262
  :allow_nan => true
239
- }.merge(opts)
240
- Parser.new(source, **(opts||{})).parse
263
+ }
264
+ options.merge!(opts) if opts
265
+ Parser.new(source, options).parse
241
266
  end
242
267
 
243
268
  # :call-seq:
@@ -258,7 +283,7 @@ module JSON
258
283
  # JSON.parse!(File.read(path, opts))
259
284
  #
260
285
  # See method #parse!
261
- def load_file!(filespec, opts = {})
286
+ def load_file!(filespec, opts = nil)
262
287
  parse!(File.read(filespec, encoding: Encoding::UTF_8), opts)
263
288
  end
264
289
 
@@ -818,11 +843,7 @@ module JSON
818
843
  opts = merge_dump_options(opts, **kwargs) if kwargs
819
844
 
820
845
  begin
821
- if State === opts
822
- opts.generate(obj, anIO)
823
- else
824
- State.generate(obj, opts, anIO)
825
- end
846
+ State.generate(obj, opts, anIO)
826
847
  rescue JSON::NestingError
827
848
  raise ArgumentError, "exceed depth limit"
828
849
  end
@@ -841,6 +862,82 @@ module JSON
841
862
  class << self
842
863
  private :merge_dump_options
843
864
  end
865
+
866
+ # JSON::Coder holds a parser and generator configuration.
867
+ #
868
+ # module MyApp
869
+ # JSONC_CODER = JSON::Coder.new(
870
+ # allow_trailing_comma: true
871
+ # )
872
+ # end
873
+ #
874
+ # MyApp::JSONC_CODER.load(document)
875
+ #
876
+ class Coder
877
+ # :call-seq:
878
+ # JSON.new(options = nil, &block)
879
+ #
880
+ # Argument +options+, if given, contains a \Hash of options for both parsing and generating.
881
+ # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options].
882
+ #
883
+ # For generation, the <tt>strict: true</tt> option is always set. When a Ruby object with no native \JSON counterpart is
884
+ # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native
885
+ # \JSON counterpart:
886
+ #
887
+ # module MyApp
888
+ # API_JSON_CODER = JSON::Coder.new do |object|
889
+ # case object
890
+ # when Time
891
+ # object.iso8601(3)
892
+ # else
893
+ # object # Unknown type, will raise
894
+ # end
895
+ # end
896
+ # end
897
+ #
898
+ # puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z"
899
+ #
900
+ def initialize(options = nil, &as_json)
901
+ if options.nil?
902
+ options = { strict: true }
903
+ else
904
+ options = options.dup
905
+ options[:strict] = true
906
+ end
907
+ options[:as_json] = as_json if as_json
908
+ options[:create_additions] = false unless options.key?(:create_additions)
909
+
910
+ @state = State.new(options).freeze
911
+ @parser_config = Ext::Parser::Config.new(options)
912
+ end
913
+
914
+ # call-seq:
915
+ # dump(object) -> String
916
+ # dump(object, io) -> io
917
+ #
918
+ # Serialize the given object into a \JSON document.
919
+ def dump(object, io = nil)
920
+ @state.generate_new(object, io)
921
+ end
922
+ alias_method :generate, :dump
923
+
924
+ # call-seq:
925
+ # load(string) -> Object
926
+ #
927
+ # Parse the given \JSON document and return an equivalent Ruby object.
928
+ def load(source)
929
+ @parser_config.parse(source)
930
+ end
931
+ alias_method :parse, :load
932
+
933
+ # call-seq:
934
+ # load(path) -> Object
935
+ #
936
+ # Parse the given \JSON document and return an equivalent Ruby object.
937
+ def load_file(path)
938
+ load(File.read(path, encoding: Encoding::UTF_8))
939
+ end
940
+ end
844
941
  end
845
942
 
846
943
  module ::Kernel
@@ -47,17 +47,6 @@ module JSON
47
47
 
48
48
  alias_method :merge, :configure
49
49
 
50
- # call-seq:
51
- # generate(obj) -> String
52
- # generate(obj, anIO) -> anIO
53
- #
54
- # Generates a valid JSON document from object +obj+ and returns the
55
- # result. If no valid JSON document can be created this method raises a
56
- # GeneratorError exception.
57
- def generate(obj, io = nil)
58
- _generate(obj, io)
59
- end
60
-
61
50
  # call-seq: to_h
62
51
  #
63
52
  # Returns the configuration instance variables as a hash, that can be
@@ -69,6 +58,7 @@ module JSON
69
58
  space_before: space_before,
70
59
  object_nl: object_nl,
71
60
  array_nl: array_nl,
61
+ as_json: as_json,
72
62
  allow_nan: allow_nan?,
73
63
  ascii_only: ascii_only?,
74
64
  max_nesting: max_nesting,
data/lib/json/ext.rb CHANGED
@@ -6,15 +6,37 @@ module JSON
6
6
  # This module holds all the modules/classes that implement JSON's
7
7
  # functionality as C extensions.
8
8
  module Ext
9
+ class Parser
10
+ class << self
11
+ def parse(...)
12
+ new(...).parse
13
+ end
14
+ alias_method :parse, :parse # Allow redefinition by extensions
15
+ end
16
+
17
+ def initialize(source, opts = nil)
18
+ @source = source
19
+ @config = Config.new(opts)
20
+ end
21
+
22
+ def source
23
+ @source.dup
24
+ end
25
+
26
+ def parse
27
+ @config.parse(@source)
28
+ end
29
+ end
30
+
31
+ require 'json/ext/parser'
32
+ Ext::Parser::Config = Ext::ParserConfig
33
+ JSON.parser = Ext::Parser
34
+
9
35
  if RUBY_ENGINE == 'truffleruby'
10
- require 'json/ext/parser'
11
36
  require 'json/truffle_ruby/generator'
12
- JSON.parser = Parser
13
37
  JSON.generator = ::JSON::TruffleRuby::Generator
14
38
  else
15
- require 'json/ext/parser'
16
39
  require 'json/ext/generator'
17
- JSON.parser = Parser
18
40
  JSON.generator = Generator
19
41
  end
20
42
  end
@@ -39,30 +39,33 @@ module JSON
39
39
  '\\' => '\\\\',
40
40
  }.freeze # :nodoc:
41
41
 
42
- ESCAPE_PATTERN = /[\/"\\\x0-\x1f]/n # :nodoc:
43
-
44
42
  SCRIPT_SAFE_MAP = MAP.merge(
45
43
  '/' => '\\/',
46
- "\u2028".b => '\u2028',
47
- "\u2029".b => '\u2029',
44
+ "\u2028" => '\u2028',
45
+ "\u2029" => '\u2029',
48
46
  ).freeze
49
47
 
50
- SCRIPT_SAFE_ESCAPE_PATTERN = Regexp.union(ESCAPE_PATTERN, "\u2028".b, "\u2029".b)
48
+ SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/
51
49
 
52
50
  # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
53
51
  # UTF16 big endian characters as \u????, and return it.
54
- def utf8_to_json(string, script_safe = false) # :nodoc:
55
- string = string.b
52
+ def self.utf8_to_json(string, script_safe = false) # :nodoc:
56
53
  if script_safe
57
- string.gsub!(SCRIPT_SAFE_ESCAPE_PATTERN) { SCRIPT_SAFE_MAP[$&] || $& }
54
+ if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string)
55
+ string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP)
56
+ else
57
+ string
58
+ end
58
59
  else
59
- string.gsub!(ESCAPE_PATTERN) { MAP[$&] || $& }
60
+ if /["\\\x0-\x1f]/.match?(string)
61
+ string.gsub(/["\\\x0-\x1f]/, MAP)
62
+ else
63
+ string
64
+ end
60
65
  end
61
- string.force_encoding(::Encoding::UTF_8)
62
- string
63
66
  end
64
67
 
65
- def utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
68
+ def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc:
66
69
  string = original_string.b
67
70
  map = script_safe ? SCRIPT_SAFE_MAP : MAP
68
71
  string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& }
@@ -86,24 +89,17 @@ module JSON
86
89
  raise GeneratorError.new(e.message, original_string)
87
90
  end
88
91
 
89
- def valid_utf8?(string)
92
+ def self.valid_utf8?(string)
90
93
  encoding = string.encoding
91
94
  (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) &&
92
95
  string.valid_encoding?
93
96
  end
94
- module_function :utf8_to_json, :utf8_to_json_ascii, :valid_utf8?
95
97
 
96
98
  # This class is used to create State instances, that are use to hold data
97
99
  # while generating a JSON text from a Ruby data structure.
98
100
  class State
99
101
  def self.generate(obj, opts = nil, io = nil)
100
- string = new(opts).generate(obj)
101
- if io
102
- io.write(string)
103
- io
104
- else
105
- string
106
- end
102
+ new(opts).generate(obj, io)
107
103
  end
108
104
 
109
105
  # Creates a State object from _opts_, which ought to be Hash to create
@@ -111,16 +107,17 @@ module JSON
111
107
  # an unconfigured instance. If _opts_ is a State object, it is just
112
108
  # returned.
113
109
  def self.from_state(opts)
114
- case
115
- when self === opts
116
- opts
117
- when opts.respond_to?(:to_hash)
118
- new(opts.to_hash)
119
- when opts.respond_to?(:to_h)
120
- new(opts.to_h)
121
- else
122
- SAFE_STATE_PROTOTYPE.dup
110
+ if opts
111
+ case
112
+ when self === opts
113
+ return opts
114
+ when opts.respond_to?(:to_hash)
115
+ return new(opts.to_hash)
116
+ when opts.respond_to?(:to_h)
117
+ return new(opts.to_h)
118
+ end
123
119
  end
120
+ SAFE_STATE_PROTOTYPE.dup
124
121
  end
125
122
 
126
123
  # Instantiates a new State object, configured by _opts_.
@@ -148,6 +145,7 @@ module JSON
148
145
  @array_nl = ''
149
146
  @allow_nan = false
150
147
  @ascii_only = false
148
+ @as_json = false
151
149
  @depth = 0
152
150
  @buffer_initial_length = 1024
153
151
  @script_safe = false
@@ -173,6 +171,9 @@ module JSON
173
171
  # This string is put at the end of a line that holds a JSON array.
174
172
  attr_accessor :array_nl
175
173
 
174
+ # This proc converts unsupported types into native JSON types.
175
+ attr_accessor :as_json
176
+
176
177
  # This integer returns the maximum level of data structure nesting in
177
178
  # the generated JSON, max_nesting = 0 if no maximum is checked.
178
179
  attr_accessor :max_nesting
@@ -257,6 +258,7 @@ module JSON
257
258
  @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl)
258
259
  @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl)
259
260
  @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
261
+ @as_json = opts[:as_json].to_proc if opts[:as_json]
260
262
  @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
261
263
  @depth = opts[:depth] || 0
262
264
  @buffer_initial_length ||= opts[:buffer_initial_length]
@@ -299,9 +301,9 @@ module JSON
299
301
  # returns the result. If no valid JSON document can be
300
302
  # created this method raises a
301
303
  # GeneratorError exception.
302
- def generate(obj)
304
+ def generate(obj, anIO = nil)
303
305
  if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and
304
- !@ascii_only and !@script_safe and @max_nesting == 0 and !@strict
306
+ !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj)
305
307
  result = generate_json(obj, ''.dup)
306
308
  else
307
309
  result = obj.to_json(self)
@@ -310,7 +312,16 @@ module JSON
310
312
  "source sequence #{result.inspect} is illegal/malformed utf-8",
311
313
  obj
312
314
  )
313
- result
315
+ if anIO
316
+ anIO.write(result)
317
+ anIO
318
+ else
319
+ result
320
+ end
321
+ end
322
+
323
+ def generate_new(obj, anIO = nil) # :nodoc:
324
+ dup.generate(obj, anIO)
314
325
  end
315
326
 
316
327
  # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above)
@@ -353,6 +364,12 @@ module JSON
353
364
  end
354
365
  when Integer
355
366
  buf << obj.to_s
367
+ when Symbol
368
+ if @strict
369
+ fast_serialize_string(obj.name, buf)
370
+ else
371
+ buf << obj.to_json(self)
372
+ end
356
373
  else
357
374
  # Note: Float is handled this way since Float#to_s is slow anyway
358
375
  buf << obj.to_json(self)
@@ -371,8 +388,8 @@ module JSON
371
388
  end
372
389
  raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding?
373
390
 
374
- if /["\\\x0-\x1f]/n.match?(string)
375
- buf << string.gsub(/["\\\x0-\x1f]/n, MAP)
391
+ if /["\\\x0-\x1f]/.match?(string)
392
+ buf << string.gsub(/["\\\x0-\x1f]/, MAP)
376
393
  else
377
394
  buf << string
378
395
  end
@@ -404,8 +421,20 @@ module JSON
404
421
  # it to a JSON string, and returns the result. This is a fallback, if no
405
422
  # special method #to_json was defined for some object.
406
423
  def to_json(state = nil, *)
407
- if state && State.from_state(state).strict?
408
- raise GeneratorError.new("#{self.class} not allowed in JSON", self)
424
+ state = State.from_state(state) if state
425
+ if state&.strict?
426
+ value = self
427
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
428
+ if state.as_json
429
+ value = state.as_json.call(value)
430
+ unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
431
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
432
+ end
433
+ value.to_json(state)
434
+ else
435
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
436
+ end
437
+ end
409
438
  else
410
439
  to_s.to_json
411
440
  end
@@ -455,8 +484,16 @@ module JSON
455
484
  end
456
485
 
457
486
  result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
458
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
459
- raise GeneratorError.new("#{value.class} not allowed in JSON", value)
487
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
488
+ if state.as_json
489
+ value = state.as_json.call(value)
490
+ unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value
491
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
492
+ end
493
+ result << value.to_json(state)
494
+ else
495
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
496
+ end
460
497
  elsif value.respond_to?(:to_json)
461
498
  result << value.to_json(state)
462
499
  else
@@ -508,8 +545,16 @@ module JSON
508
545
  each { |value|
509
546
  result << delim unless first
510
547
  result << state.indent * depth if indent
511
- if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value)
512
- raise GeneratorError.new("#{value.class} not allowed in JSON", value)
548
+ if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value)
549
+ if state.as_json
550
+ value = state.as_json.call(value)
551
+ unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value
552
+ raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value)
553
+ end
554
+ result << value.to_json(state)
555
+ else
556
+ raise GeneratorError.new("#{value.class} not allowed in JSON", value)
557
+ end
513
558
  elsif value.respond_to?(:to_json)
514
559
  result << value.to_json(state)
515
560
  else
@@ -531,18 +576,23 @@ module JSON
531
576
 
532
577
  module Float
533
578
  # Returns a JSON string representation for this Float number.
534
- def to_json(state = nil, *)
579
+ def to_json(state = nil, *args)
535
580
  state = State.from_state(state)
536
- case
537
- when infinite?
538
- if state.allow_nan?
539
- to_s
540
- else
541
- raise GeneratorError.new("#{self} not allowed in JSON", self)
542
- end
543
- when nan?
581
+ if infinite? || nan?
544
582
  if state.allow_nan?
545
583
  to_s
584
+ elsif state.strict? && state.as_json
585
+ casted_value = state.as_json.call(self)
586
+
587
+ if casted_value.equal?(self)
588
+ raise GeneratorError.new("#{self} not allowed in JSON", self)
589
+ end
590
+
591
+ state.check_max_nesting
592
+ state.depth += 1
593
+ result = casted_value.to_json(state, *args)
594
+ state.depth -= 1
595
+ result
546
596
  else
547
597
  raise GeneratorError.new("#{self} not allowed in JSON", self)
548
598
  end
@@ -552,6 +602,17 @@ module JSON
552
602
  end
553
603
  end
554
604
 
605
+ module Symbol
606
+ def to_json(state = nil, *args)
607
+ state = State.from_state(state)
608
+ if state.strict?
609
+ name.to_json(state, *args)
610
+ else
611
+ super
612
+ end
613
+ end
614
+ end
615
+
555
616
  module String
556
617
  # This string should be encoded with UTF-8 A call to this method
557
618
  # returns a JSON string encoded with UTF16 big endian characters as
data/lib/json/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSON
4
- VERSION = '2.9.1'
4
+ VERSION = '2.10.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.1
4
+ version: 2.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-18 00:00:00.000000000 Z
10
+ date: 2025-02-10 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: This is a JSON implementation as a Ruby extension in C.
14
13
  email: flori@ping.de
@@ -29,7 +28,6 @@ files:
29
28
  - ext/json/ext/generator/generator.c
30
29
  - ext/json/ext/parser/extconf.rb
31
30
  - ext/json/ext/parser/parser.c
32
- - ext/json/ext/parser/parser.rl
33
31
  - json.gemspec
34
32
  - lib/json.rb
35
33
  - lib/json/add/bigdecimal.rb
@@ -52,17 +50,15 @@ files:
52
50
  - lib/json/generic_object.rb
53
51
  - lib/json/truffle_ruby/generator.rb
54
52
  - lib/json/version.rb
55
- homepage: https://ruby.github.io/json
53
+ homepage: https://github.com/ruby/json
56
54
  licenses:
57
55
  - Ruby
58
56
  metadata:
59
57
  bug_tracker_uri: https://github.com/ruby/json/issues
60
58
  changelog_uri: https://github.com/ruby/json/blob/master/CHANGES.md
61
- documentation_uri: https://ruby.github.io/json/doc/index.html
62
- homepage_uri: https://ruby.github.io/json
59
+ documentation_uri: https://docs.ruby-lang.org/en/master/JSON.html
60
+ homepage_uri: https://github.com/ruby/json
63
61
  source_code_uri: https://github.com/ruby/json
64
- wiki_uri: https://github.com/ruby/json/wiki
65
- post_install_message:
66
62
  rdoc_options:
67
63
  - "--title"
68
64
  - JSON implementation for Ruby
@@ -81,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
77
  - !ruby/object:Gem::Version
82
78
  version: '0'
83
79
  requirements: []
84
- rubygems_version: 3.5.11
85
- signing_key:
80
+ rubygems_version: 3.6.2
86
81
  specification_version: 4
87
82
  summary: JSON Implementation for Ruby
88
83
  test_files: []