plate_id 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d4151d00de7c7c38bc47ea35c0267bcba125771227fb74eee5f5fb9199e4ae28
4
+ data.tar.gz: 9103e79ca0733b0a6352dcfdfd03a23a67c52d8a49ff1be79b677978eb76ec19
5
+ SHA512:
6
+ metadata.gz: 5b70fca72ad26435053e59a4c14c511053c6234bcbe4d6d037076ef9a32aaf7f0df599ceae47ce4edaea4dc71d718825a4492392bfa9fda706f747c4238c07e5
7
+ data.tar.gz: a1d98817a18b6f6ca023e09d6e0592214b9ac7a9562fa1beaa91608f4ba413694a4cbdf6e6cfa6f192645b68866e302e5d1a5f8ba972b800cef370cfd00ba1f5
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in plate_id.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Kobus Post
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: %i[spec]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "plate_id"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/plate_id.rb ADDED
@@ -0,0 +1,67 @@
1
+ require_relative "uri/plate_id"
2
+
3
+ class PlateID
4
+ class << self
5
+
6
+ def create(model)
7
+ new(URI::PlateID.create(model))
8
+ end
9
+
10
+ def parse(plate_id)
11
+ plate_id.is_a?(self) ? plate_id : new(plate_id)
12
+ rescue URI::Error
13
+ nil
14
+ end
15
+
16
+ def find(plate_id)
17
+ res = parse(plate_id)
18
+ res&.find
19
+ end
20
+ end
21
+
22
+ attr_reader :uri
23
+
24
+ def host
25
+ uri.host
26
+ end
27
+
28
+ def base_class
29
+ uri.base_class
30
+ end
31
+
32
+ def id
33
+ uri.id
34
+ end
35
+
36
+ def to_s
37
+ uri.to_s
38
+ end
39
+
40
+ def initialize(plate_id)
41
+ @uri = fetch_uri(plate_id)
42
+ end
43
+
44
+ def plate_class
45
+ fetch_plate_class(uri)&.safe_constantize
46
+ end
47
+
48
+ def find
49
+ return unless uri.id
50
+
51
+ plate_class&.find_by(id: uri.id)
52
+ end
53
+
54
+ private
55
+
56
+ def fetch_uri(plate_id)
57
+ return plate_id if plate_id.is_a?(URI::PlateID)
58
+
59
+ URI::PlateID.parse(plate_id)
60
+ end
61
+
62
+ def fetch_plate_class(uri)
63
+ uri.class::MAPPING.detect do |_klass, map|
64
+ map[:host] == uri.host && map[:base_class] == uri.base_class
65
+ end[0]
66
+ end
67
+ end
@@ -0,0 +1,160 @@
1
+ module URI
2
+ class PlateID < Generic
3
+
4
+ # URI::PlateID encodes an Plate unique reference to a specific model as an URI
5
+ # and notates it according to a mapping. The PlateID URI is meant for external
6
+ # communication.
7
+ #
8
+ # The URI format looks like "plateid://group_name/base_class/id".
9
+
10
+ MAPPING = {
11
+ "Site" => { host: "Base", base_class: "Site" },
12
+ "Ngn::Attachment" => { host: "Base", base_class: "Attachment" },
13
+ "Ngn::Domain" => { host: "Base", base_class: "Domain" },
14
+ "Ngn::ClipboardItem" => { host: "Base", base_class: "ClipboardItem" },
15
+
16
+ "Ngn::Content::Post" => { host: "Content", base_class: "Post" },
17
+ "Ngn::Content::Section" => { host: "Content", base_class: "Section" },
18
+ "Ngn::Content::Row" => { host: "Content", base_class: "Row" },
19
+ "Ngn::Content::Column" => { host: "Content", base_class: "Column" },
20
+ "Ngn::Content::Element" => { host: "Content", base_class: "Element" },
21
+ "Ngn::Content::ContentObject" => { host: "Content", base_class: "ContentObject" },
22
+ "Ngn::Content::SiteTranslation" => { host: "Content", base_class: "SiteTranslation" },
23
+
24
+ "Ngn::ContentModel::ContentField" => { host: "ContentModel", base_class: "ContentField" },
25
+ "Ngn::ContentModel::ContentFieldTab" => { host: "ContentModel", base_class: "ContentFieldGroup" },
26
+ "Ngn::ContentModel::PostType" => { host: "ContentModel", base_class: "PostType" },
27
+ "Ngn::ContentModel::SectionType" => { host: "ContentModel", base_class: "SectionType" },
28
+ "Ngn::ContentModel::ElementType" => { host: "ContentModel", base_class: "ElementType" },
29
+ "Ngn::ContentModel::ObjectTypeKind" => { host: "ContentModel", base_class: "ContentType" },
30
+ "Ngn::ContentModel::TrayType" => { host: "ContentModel", base_class: "TrayType" },
31
+ "Ngn::ContentModel::AuthenticationType" => { host: "ContentModel", base_class: "AuthenticationType" },
32
+
33
+ "Ngn::Theming::SiteTheme" => { host: "Theming", base_class: "Theme" },
34
+ "Ngn::Theming::ThemeFile" => { host: "Theming", base_class: "ThemeFile" },
35
+ "Ngn::Theming::Prerender" => { host: "Theming", base_class: "Prerender" },
36
+
37
+ "Ngn::Auth::User" => { host: "Auth", base_class: "User" },
38
+ "Ngn::Auth::ApiIntegration" => { host: "Auth", base_class: "ApiIntegration" },
39
+
40
+ "Ngn::Auth::AccessControl::Policy" => { host: "AccessControl", base_class: "Policy" },
41
+
42
+ "Org::Company" => { host: "Organization", base_class: "Company" },
43
+ "Org::Partner" => { host: "Organization", base_class: "Partner" },
44
+ "Org::FormMessage" => { host: "Organization", base_class: "FormMessage" }
45
+ }
46
+
47
+ attr_reader :base_class, :id
48
+
49
+ class << self
50
+ # Create a new URI::PlateID by parsing a plateid string with argument check.
51
+ #
52
+ # URI::PlateID.parse 'plateid://Group/Class/1'
53
+ #
54
+ def parse(uri)
55
+ generic_components = URI.split(uri) << nil << true # nil parser, true arg_check
56
+ new(*generic_components)
57
+ end
58
+
59
+ # Shorthand to build a URI::PlateID from a model.
60
+ #
61
+ # URI::PlateID.create(Ngn::Content::Post.find(5))
62
+ # URI::PlateID.create(Ngn::Content::Post)
63
+ def create(model)
64
+ model = model.new if model.class == Class
65
+ build(model_name: model.class.name, model_id: model.id)
66
+ end
67
+
68
+ # Create a new URI::PlateID from components with argument check.
69
+ #
70
+ # The allowed components are app, model_name, model_id and params, which
71
+ # can be either a hash or an array.
72
+ #
73
+ # Using a hash:
74
+ #
75
+ # URI::PlateID.build(
76
+ # model_name: 'Ngn::ContentModelElementType',
77
+ # model_id: '1'
78
+ # )
79
+ def build(args)
80
+ comps = Util.make_components_hash(self, args)
81
+ parts = MAPPING[comps[:model_name]].dup
82
+ parts[:scheme] = comps[:scheme]
83
+ parts[:id] = comps[:model_id]
84
+ parts[:path] = "/#{parts[:base_class]}/#{CGI.escape(parts[:id].to_s)}"
85
+
86
+ super(parts)
87
+ end
88
+ end
89
+
90
+ # Implement #to_s to avoid no implicit conversion of nil into string when path is nil
91
+ def to_s
92
+ "plateid://#{host}/#{base_class}/#{id}"
93
+ end
94
+
95
+ protected
96
+
97
+ def set_path(path)
98
+ set_model_components(path) unless defined?(@model_name) && @model_id
99
+ super
100
+ end
101
+
102
+ private
103
+
104
+ COMPONENT = [:scheme, :host, :base_class, :id].freeze
105
+ # Extracts model_name and model_id from the URI path.
106
+ PATH_REGEXP = %r(\A/([A-Z][^/]+)/?([0-9]+)?\z)
107
+
108
+ def check_host(host)
109
+ validate_component(host)
110
+ super
111
+ end
112
+
113
+ def check_path(path)
114
+ validate_component(path)
115
+ set_model_components(path, true)
116
+ end
117
+
118
+ def check_scheme(scheme)
119
+ if scheme == "plateid"
120
+ super
121
+ else
122
+ raise URI::BadURIError, "Not a plateid:// URI scheme: #{inspect}"
123
+ end
124
+ end
125
+
126
+ def set_model_components(path, validate = false)
127
+ _, base_class, id = path.match(PATH_REGEXP).to_a
128
+ id = CGI.unescape(id) if id
129
+
130
+ if validate
131
+ validate_mapping(host, base_class)
132
+ validate_component(host)
133
+ validate_component(base_class)
134
+ end
135
+
136
+ @host = host
137
+ @base_class = base_class
138
+ @id = id
139
+ end
140
+
141
+ def validate_component(component)
142
+ return component unless component.nil? || component.empty?
143
+
144
+ raise URI::InvalidComponentError,
145
+ "Expected a URI like plateid://Group/Class/1234: #{inspect}"
146
+ end
147
+
148
+ def validate_mapping(host, base_class)
149
+ reverse_map = MAPPING.values.detect do |map|
150
+ map[:host] == host && map[:base_class] == base_class
151
+ end
152
+ return if reverse_map
153
+
154
+ raise URI::InvalidComponentError,
155
+ "Not a valid PlateID URI: #{inspect}"
156
+ end
157
+ end
158
+
159
+ @@schemes["PlateID"] = PlateID
160
+ end
data/plate_id.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "plate_id"
5
+ spec.version = "0.0.0"
6
+ spec.authors = ["Kobus Post"]
7
+ spec.email = ["kobus@getplate.com"]
8
+ spec.homepage = "https://www.getplate.com"
9
+
10
+ spec.summary = "Refer to any Plate object or class by using the URI syntax: plateid://Group/Class/id"
11
+ spec.description = "Identify any Plate record or class with URIs. Somewhat based on Rails's GlobalID gem."
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ # Uncomment to register a new dependency of your gem
25
+ # spec.add_dependency "example-gem", "~> 1.0"
26
+
27
+ # For more information and examples about making a new gem, checkout our
28
+ # guide at: https://bundler.io/guides/creating_gem.html
29
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: plate_id
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kobus Post
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Identify any Plate record or class with URIs. Somewhat based on Rails's
14
+ GlobalID gem.
15
+ email:
16
+ - kobus@getplate.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - ".rspec"
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - Rakefile
26
+ - bin/console
27
+ - bin/setup
28
+ - lib/plate_id.rb
29
+ - lib/uri/plate_id.rb
30
+ - plate_id.gemspec
31
+ homepage: https://www.getplate.com
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.4.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.1.2
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: 'Refer to any Plate object or class by using the URI syntax: plateid://Group/Class/id'
54
+ test_files: []