globalid 0.4.2 → 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/MIT-LICENSE +1 -2
- data/README.md +28 -0
- data/lib/global_id/fixture_set.rb +21 -0
- data/lib/global_id/global_id.rb +14 -12
- data/lib/global_id/identification.rb +0 -4
- data/lib/global_id/locator.rb +0 -1
- data/lib/global_id/railtie.rb +8 -3
- data/lib/global_id/signed_global_id.rb +0 -1
- data/lib/global_id/uri/gid.rb +14 -9
- data/lib/global_id/verifier.rb +0 -1
- data/lib/global_id.rb +1 -1
- metadata +9 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 52c4368f15fc8952c9d79189ed9a78e649e0142421721aef338625c19b24c3b9
         | 
| 4 | 
            +
              data.tar.gz: 4d6d1c379d45ccaf5761488c540d19cac9d0488b578564964edd88c52073c511
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 49ff5a4b4d4f68afdffa67a85b5aebfb3b2f518257ffec22be8a60a29ac5596a67552aae46bebab28a4fe6b37a5802ac520b0f567098617110b2f54c4a74cfcb
         | 
| 7 | 
            +
              data.tar.gz: f6ba35dc2c080b0c996bd4529cec1438a35545c693cc0271e25c6b7bdaa8f759de61f26ae6ecf16487d89c7e6e5afc41caab7114541cd8a54ebdf9e2a3ce1f60
         | 
    
        data/MIT-LICENSE
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            Copyright (c) 2014- | 
| 1 | 
            +
            Copyright (c) 2014-2023 David Heinemeier Hansson
         | 
| 2 2 |  | 
| 3 3 | 
             
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            a copy of this software and associated documentation files (the
         | 
| @@ -18,4 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| 18 18 | 
             
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 19 | 
             
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 20 | 
             
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            -
             | 
    
        data/README.md
    CHANGED
    
    | @@ -133,6 +133,34 @@ GlobalID::Locator.locate_signed(signup_person_sgid.to_s, for: 'signup_form') | |
| 133 133 | 
             
            # => #<Person:0x007fae94bf6298 @id="1">
         | 
| 134 134 | 
             
            ```
         | 
| 135 135 |  | 
| 136 | 
            +
            ### Locating many Global IDs
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            When needing to locate many Global IDs use `GlobalID::Locator.locate_many` or `GlobalID::Locator.locate_many_signed` for Signed Global IDs to allow loading
         | 
| 139 | 
            +
            Global IDs more efficiently.
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            For instance, the default locator passes every `model_id` per `model_name` thus
         | 
| 142 | 
            +
            using `model_name.where(id: model_ids)` versus `GlobalID::Locator.locate`'s `model_name.find(id)`.
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            In the case of looking up Global IDs from a database, it's only necessary to query
         | 
| 145 | 
            +
            once per `model_name` as shown here:
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            ```ruby
         | 
| 148 | 
            +
            gids = users.concat(people).sort_by(&:id).map(&:to_global_id)
         | 
| 149 | 
            +
            # => [#<GlobalID:0x00007ffd6a8411a0 @uri=#<URI::GID gid://app/User/1>>,
         | 
| 150 | 
            +
            #<GlobalID:0x00007ffd675d32b8 @uri=#<URI::GID gid://app/Student/1>>,
         | 
| 151 | 
            +
            #<GlobalID:0x00007ffd6a840b10 @uri=#<URI::GID gid://app/User/2>>,
         | 
| 152 | 
            +
            #<GlobalID:0x00007ffd675d2c28 @uri=#<URI::GID gid://app/Student/2>>,
         | 
| 153 | 
            +
            #<GlobalID:0x00007ffd6a840480 @uri=#<URI::GID gid://app/User/3>>,
         | 
| 154 | 
            +
            #<GlobalID:0x00007ffd675d2598 @uri=#<URI::GID gid://app/Student/3>>]
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            GlobalID::Locator.locate_many gids
         | 
| 157 | 
            +
            # SELECT "users".* FROM "users" WHERE "users"."id" IN ($1, $2, $3)  [["id", 1], ["id", 2], ["id", 3]]
         | 
| 158 | 
            +
            # SELECT "students".* FROM "students" WHERE "students"."id" IN ($1, $2, $3)  [["id", 1], ["id", 2], ["id", 3]]
         | 
| 159 | 
            +
            # => [#<User id: 1>, #<Student id: 1>, #<User id: 2>, #<Student id: 2>, #<User id: 3>, #<Student id: 3>]
         | 
| 160 | 
            +
            ```
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            Note the order is maintained in the returned results.
         | 
| 163 | 
            +
             | 
| 136 164 | 
             
            ### Custom App Locator
         | 
| 137 165 |  | 
| 138 166 | 
             
            A custom locator can be set for an app by calling `GlobalID::Locator.use` and providing an app locator to use for that app.
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class GlobalID
         | 
| 4 | 
            +
              module FixtureSet
         | 
| 5 | 
            +
                def global_id(fixture_set_name, label, column_type: :integer, **options)
         | 
| 6 | 
            +
                  create_global_id(fixture_set_name, label, column_type: column_type, klass: GlobalID, **options)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def signed_global_id(fixture_set_name, label, column_type: :integer, **options)
         | 
| 10 | 
            +
                  create_global_id(fixture_set_name, label, column_type: column_type, klass: SignedGlobalID, **options)
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                private
         | 
| 14 | 
            +
                  def create_global_id(fixture_set_name, label, klass:, column_type: :integer, **options)
         | 
| 15 | 
            +
                    identifier = identify(label, column_type)
         | 
| 16 | 
            +
                    model_name = default_fixture_model_name(fixture_set_name)
         | 
| 17 | 
            +
                    uri = URI::GID.build([GlobalID.app, model_name, identifier, {}])
         | 
| 18 | 
            +
                    klass.new(uri, **options)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
    
        data/lib/global_id/global_id.rb
    CHANGED
    
    | @@ -1,4 +1,3 @@ | |
| 1 | 
            -
            require 'active_support'
         | 
| 2 1 | 
             
            require 'active_support/core_ext/string/inflections'  # For #model_class constantize
         | 
| 3 2 | 
             
            require 'active_support/core_ext/array/access'
         | 
| 4 3 | 
             
            require 'active_support/core_ext/object/try'          # For #find
         | 
| @@ -35,18 +34,12 @@ class GlobalID | |
| 35 34 |  | 
| 36 35 | 
             
                private
         | 
| 37 36 | 
             
                  def parse_encoded_gid(gid, options)
         | 
| 38 | 
            -
                    new(Base64.urlsafe_decode64( | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  # We removed the base64 padding character = during #to_param, now we're adding it back so decoding will work
         | 
| 42 | 
            -
                  def repad_gid(gid)
         | 
| 43 | 
            -
                    padding_chars = gid.length.modulo(4).zero? ? 0 : (4 - gid.length.modulo(4))
         | 
| 44 | 
            -
                    gid + ('=' * padding_chars)
         | 
| 37 | 
            +
                    new(Base64.urlsafe_decode64(gid), options) rescue nil
         | 
| 45 38 | 
             
                  end
         | 
| 46 39 | 
             
              end
         | 
| 47 40 |  | 
| 48 41 | 
             
              attr_reader :uri
         | 
| 49 | 
            -
              delegate :app, :model_name, :model_id, :params, :to_s, to: :uri
         | 
| 42 | 
            +
              delegate :app, :model_name, :model_id, :params, :to_s, :deconstruct_keys, to: :uri
         | 
| 50 43 |  | 
| 51 44 | 
             
              def initialize(gid, options = {})
         | 
| 52 45 | 
             
                @uri = gid.is_a?(URI::GID) ? gid : URI::GID.parse(gid)
         | 
| @@ -57,7 +50,13 @@ class GlobalID | |
| 57 50 | 
             
              end
         | 
| 58 51 |  | 
| 59 52 | 
             
              def model_class
         | 
| 60 | 
            -
                model_name.constantize
         | 
| 53 | 
            +
                model = model_name.constantize
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                unless model <= GlobalID
         | 
| 56 | 
            +
                  model
         | 
| 57 | 
            +
                else
         | 
| 58 | 
            +
                  raise ArgumentError, "GlobalID and SignedGlobalID cannot be used as model_class."
         | 
| 59 | 
            +
                end
         | 
| 61 60 | 
             
              end
         | 
| 62 61 |  | 
| 63 62 | 
             
              def ==(other)
         | 
| @@ -70,7 +69,10 @@ class GlobalID | |
| 70 69 | 
             
              end
         | 
| 71 70 |  | 
| 72 71 | 
             
              def to_param
         | 
| 73 | 
            -
                 | 
| 74 | 
            -
             | 
| 72 | 
            +
                Base64.urlsafe_encode64(to_s, padding: false)
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def as_json(*)
         | 
| 76 | 
            +
                to_s
         | 
| 75 77 | 
             
              end
         | 
| 76 78 | 
             
            end
         | 
    
        data/lib/global_id/locator.rb
    CHANGED
    
    
    
        data/lib/global_id/railtie.rb
    CHANGED
    
    | @@ -3,8 +3,8 @@ require 'rails/railtie' | |
| 3 3 | 
             
            rescue LoadError
         | 
| 4 4 | 
             
            else
         | 
| 5 5 | 
             
            require 'global_id'
         | 
| 6 | 
            -
            require 'active_support'
         | 
| 7 6 | 
             
            require 'active_support/core_ext/string/inflections'
         | 
| 7 | 
            +
            require 'active_support/core_ext/integer/time'
         | 
| 8 8 |  | 
| 9 9 | 
             
            class GlobalID
         | 
| 10 10 | 
             
              # = GlobalID Railtie
         | 
| @@ -18,11 +18,11 @@ class GlobalID | |
| 18 18 | 
             
                  default_app_name = app.railtie_name.remove('_application').dasherize
         | 
| 19 19 |  | 
| 20 20 | 
             
                  GlobalID.app = app.config.global_id.app ||= default_app_name
         | 
| 21 | 
            -
                  SignedGlobalID.expires_in = app.config.global_id.expires_in  | 
| 21 | 
            +
                  SignedGlobalID.expires_in = app.config.global_id.fetch(:expires_in, default_expires_in)
         | 
| 22 22 |  | 
| 23 23 | 
             
                  config.after_initialize do
         | 
| 24 24 | 
             
                    GlobalID.app = app.config.global_id.app ||= default_app_name
         | 
| 25 | 
            -
                    SignedGlobalID.expires_in = app.config.global_id.expires_in  | 
| 25 | 
            +
                    SignedGlobalID.expires_in = app.config.global_id.fetch(:expires_in, default_expires_in)
         | 
| 26 26 |  | 
| 27 27 | 
             
                    app.config.global_id.verifier ||= begin
         | 
| 28 28 | 
             
                      GlobalID::Verifier.new(app.key_generator.generate_key('signed_global_ids'))
         | 
| @@ -36,6 +36,11 @@ class GlobalID | |
| 36 36 | 
             
                    require 'global_id/identification'
         | 
| 37 37 | 
             
                    send :include, GlobalID::Identification
         | 
| 38 38 | 
             
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  ActiveSupport.on_load(:active_record_fixture_set) do
         | 
| 41 | 
            +
                    require 'global_id/fixture_set'
         | 
| 42 | 
            +
                    send :extend, GlobalID::FixtureSet
         | 
| 43 | 
            +
                  end
         | 
| 39 44 | 
             
                end
         | 
| 40 45 | 
             
              end
         | 
| 41 46 | 
             
            end
         | 
    
        data/lib/global_id/uri/gid.rb
    CHANGED
    
    | @@ -98,6 +98,10 @@ module URI | |
| 98 98 | 
             
                  "gid://#{app}#{path}#{'?' + query if query}"
         | 
| 99 99 | 
             
                end
         | 
| 100 100 |  | 
| 101 | 
            +
                def deconstruct_keys(_keys)
         | 
| 102 | 
            +
                  {app: app, model_name: model_name, model_id: model_id, params: params}
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 101 105 | 
             
                protected
         | 
| 102 106 | 
             
                  def set_path(path)
         | 
| 103 107 | 
             
                    set_model_components(path) unless defined?(@model_name) && @model_id
         | 
| @@ -123,9 +127,6 @@ module URI | |
| 123 127 | 
             
                private
         | 
| 124 128 | 
             
                  COMPONENT = [ :scheme, :app, :model_name, :model_id, :params ].freeze
         | 
| 125 129 |  | 
| 126 | 
            -
                  # Extracts model_name and model_id from the URI path.
         | 
| 127 | 
            -
                  PATH_REGEXP = %r(\A/([^/]+)/?([^/]+)?\z)
         | 
| 128 | 
            -
             | 
| 129 130 | 
             
                  def check_host(host)
         | 
| 130 131 | 
             
                    validate_component(host)
         | 
| 131 132 | 
             
                    super
         | 
| @@ -138,18 +139,18 @@ module URI | |
| 138 139 |  | 
| 139 140 | 
             
                  def check_scheme(scheme)
         | 
| 140 141 | 
             
                    if scheme == 'gid'
         | 
| 141 | 
            -
                       | 
| 142 | 
            +
                      true
         | 
| 142 143 | 
             
                    else
         | 
| 143 144 | 
             
                      raise URI::BadURIError, "Not a gid:// URI scheme: #{inspect}"
         | 
| 144 145 | 
             
                    end
         | 
| 145 146 | 
             
                  end
         | 
| 146 147 |  | 
| 147 148 | 
             
                  def set_model_components(path, validate = false)
         | 
| 148 | 
            -
                    _, model_name, model_id = path. | 
| 149 | 
            -
                    model_id = CGI.unescape(model_id) if model_id
         | 
| 150 | 
            -
             | 
| 149 | 
            +
                    _, model_name, model_id = path.split('/', 3)
         | 
| 151 150 | 
             
                    validate_component(model_name) && validate_model_id(model_id, model_name) if validate
         | 
| 152 151 |  | 
| 152 | 
            +
                    model_id = CGI.unescape(model_id) if model_id
         | 
| 153 | 
            +
             | 
| 153 154 | 
             
                    @model_name = model_name
         | 
| 154 155 | 
             
                    @model_id = model_id
         | 
| 155 156 | 
             
                  end
         | 
| @@ -162,7 +163,7 @@ module URI | |
| 162 163 | 
             
                  end
         | 
| 163 164 |  | 
| 164 165 | 
             
                  def validate_model_id(model_id, model_name)
         | 
| 165 | 
            -
                    return model_id unless model_id.blank?
         | 
| 166 | 
            +
                    return model_id unless model_id.blank? || model_id.include?('/')
         | 
| 166 167 |  | 
| 167 168 | 
             
                    raise MissingModelIdError, "Unable to create a Global ID for " \
         | 
| 168 169 | 
             
                      "#{model_name} without a model id."
         | 
| @@ -173,5 +174,9 @@ module URI | |
| 173 174 | 
             
                  end
         | 
| 174 175 | 
             
              end
         | 
| 175 176 |  | 
| 176 | 
            -
               | 
| 177 | 
            +
              if respond_to?(:register_scheme)
         | 
| 178 | 
            +
                register_scheme('GID', GID)
         | 
| 179 | 
            +
              else
         | 
| 180 | 
            +
                @@schemes['GID'] = GID
         | 
| 181 | 
            +
              end
         | 
| 177 182 | 
             
            end
         | 
    
        data/lib/global_id/verifier.rb
    CHANGED
    
    
    
        data/lib/global_id.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: globalid
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Heinemeier Hansson
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2023-01-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 19 | 
            +
                    version: '5.0'
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 26 | 
            +
                    version: '5.0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: rake
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -47,6 +47,7 @@ files: | |
| 47 47 | 
             
            - MIT-LICENSE
         | 
| 48 48 | 
             
            - README.md
         | 
| 49 49 | 
             
            - lib/global_id.rb
         | 
| 50 | 
            +
            - lib/global_id/fixture_set.rb
         | 
| 50 51 | 
             
            - lib/global_id/global_id.rb
         | 
| 51 52 | 
             
            - lib/global_id/identification.rb
         | 
| 52 53 | 
             
            - lib/global_id/locator.rb
         | 
| @@ -58,7 +59,8 @@ files: | |
| 58 59 | 
             
            homepage: http://www.rubyonrails.org
         | 
| 59 60 | 
             
            licenses:
         | 
| 60 61 | 
             
            - MIT
         | 
| 61 | 
            -
            metadata: | 
| 62 | 
            +
            metadata:
         | 
| 63 | 
            +
              rubygems_mfa_required: 'true'
         | 
| 62 64 | 
             
            post_install_message: 
         | 
| 63 65 | 
             
            rdoc_options: []
         | 
| 64 66 | 
             
            require_paths:
         | 
| @@ -67,14 +69,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 67 69 | 
             
              requirements:
         | 
| 68 70 | 
             
              - - ">="
         | 
| 69 71 | 
             
                - !ruby/object:Gem::Version
         | 
| 70 | 
            -
                  version:  | 
| 72 | 
            +
                  version: 2.5.0
         | 
| 71 73 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 72 74 | 
             
              requirements:
         | 
| 73 75 | 
             
              - - ">="
         | 
| 74 76 | 
             
                - !ruby/object:Gem::Version
         | 
| 75 77 | 
             
                  version: '0'
         | 
| 76 78 | 
             
            requirements: []
         | 
| 77 | 
            -
            rubygems_version: 3. | 
| 79 | 
            +
            rubygems_version: 3.4.1
         | 
| 78 80 | 
             
            signing_key: 
         | 
| 79 81 | 
             
            specification_version: 4
         | 
| 80 82 | 
             
            summary: 'Refer to any model with a URI: gid://app/class/id'
         |