jat 0.0.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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jat.rb +186 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0c17f2cb00d5dc319df32abc1b0fd41d00adb30f0f8357faf6d74b7d440ef1d9
4
+ data.tar.gz: 0d638bef47aa94698fa25a5c2dc0f6559e528ef8b5bf525bec07310307dbcda3
5
+ SHA512:
6
+ metadata.gz: 369741fcd71f789f49fe0e555db75982fd7758959c59833b1b3d4dd8c55d424cd159f825a9ee6a7d17d5da3c821d44c7052b3ec49910bcf5ab569114916ed6b4
7
+ data.tar.gz: 25a6235d5ec37e44917f64e0d40a98032bb391120832c0357741b56f98571d5941323b548c501bb4a1c761caf62f6cc0a65a09cb8b05f1376d20ba093799688c
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jat/attributes'
4
+ require 'jat/config'
5
+ require 'jat/error'
6
+ require 'jat/map'
7
+ require 'jat/map/construct'
8
+ require 'jat/opts'
9
+ require 'jat/preloads'
10
+ require 'jat/preload_handler'
11
+ require 'jat/response'
12
+ require 'jat/utils/preloads_to_hash'
13
+
14
+ # Main namespace
15
+ class Jat
16
+ module ClassMethods
17
+ def inherited(subclass)
18
+ subclass.extend DSLClassMethods
19
+ subclass.include DSLInstanceMethods
20
+ copy_to(subclass)
21
+
22
+ super
23
+ end
24
+
25
+ def config
26
+ @config ||= Config.new(self)
27
+ end
28
+
29
+ def config=(config)
30
+ @config = config
31
+ end
32
+
33
+ def attributes
34
+ @attributes ||= Attributes.new
35
+ end
36
+
37
+ # Used to validate provided params (fields, include)
38
+ def full_map
39
+ @full_map ||= Map::Construct.new(self, :all).to_h
40
+ end
41
+
42
+ def exposed_map
43
+ @exposed_map ||= Map::Construct.new(self, :exposed).to_h
44
+ end
45
+
46
+ def clear
47
+ @full_map = nil
48
+ @exposed_map = nil
49
+ end
50
+
51
+ def refresh
52
+ attributes.refresh
53
+ clear
54
+ end
55
+
56
+ def copy_to(subclass)
57
+ subclass.type(@type) if defined?(@type)
58
+ config.copy_to(subclass)
59
+ attributes.copy_to(subclass)
60
+ end
61
+ end
62
+
63
+ module DSLClassMethods
64
+ def call
65
+ self
66
+ end
67
+
68
+ def to_h(object, context = {})
69
+ new.to_h(object, context)
70
+ end
71
+
72
+ def to_str(object, context = {})
73
+ new.to_str(object, context)
74
+ end
75
+
76
+ def type(new_type = nil)
77
+ return @type || raise(Error, "#{self} has no defined type") unless new_type
78
+
79
+ new_type = new_type.to_sym
80
+ define_method(:type) { new_type }
81
+ @type = new_type
82
+ end
83
+
84
+ def id(key: nil, &block)
85
+ raise Error, "Key and block can't be provided together" if key && block
86
+ raise Error, 'Key or block must be provided' if !key && !block
87
+
88
+ block ||= proc { |obj| obj.public_send(key) }
89
+ define_method(:id, &block)
90
+ end
91
+
92
+ def attribute(name, **opts, &block)
93
+ add_attribute(name: name, opts: opts, block: block)
94
+ end
95
+
96
+ def relationship(name, serializer:, **opts, &block)
97
+ opts[:serializer] = serializer
98
+ add_attribute(name: name, opts: opts, block: block)
99
+ end
100
+
101
+ private
102
+
103
+ def add_attribute(params)
104
+ opts = Opts.new(self, params)
105
+
106
+ Attribute.new(opts).tap do |attribute|
107
+ attributes << attribute
108
+ add_method(attribute)
109
+ clear
110
+ end
111
+ end
112
+
113
+ def add_method(attribute)
114
+ block = attribute.block
115
+ return unless block
116
+
117
+ name = attribute.original_name
118
+ # Warning-free method redefinition
119
+ remove_method(name) if method_defined?(name)
120
+ define_method(name, &block)
121
+ end
122
+ end
123
+
124
+ # :reek:ModuleInitialize
125
+ module DSLInstanceMethods
126
+ attr_reader :_context
127
+
128
+ def initialize(context = {}, full_map = nil)
129
+ @_context = context.dup
130
+ @_full_map = full_map
131
+ end
132
+
133
+ def to_h(object, context = {})
134
+ _reinitialize(context)
135
+
136
+ Response.new(self, object).to_h
137
+ end
138
+
139
+ def to_str(object, context = {})
140
+ _reinitialize(context)
141
+ Response.new(self, object).to_str
142
+ end
143
+
144
+ def id(object)
145
+ object.id
146
+ end
147
+
148
+ def _preloads
149
+ Preloads.new(_full_map).for(self.class)
150
+ end
151
+
152
+ def _copy_to(nested_serializer)
153
+ nested_serializer.().new(_context, _full_map)
154
+ end
155
+
156
+ def _full_map
157
+ @_full_map ||= begin
158
+ params = _context[:params]
159
+ fields = params && (params[:fields] || params['fields'])
160
+ includes = params && (params[:include] || params['include'])
161
+ Map.(self.class, fields, includes)
162
+ end
163
+ end
164
+
165
+ def _map
166
+ @_map ||= _full_map.fetch(type)
167
+ end
168
+
169
+ private
170
+
171
+ def _reinitialize(context)
172
+ new_params = context[:params]
173
+ old_params = _context[:params]
174
+
175
+ # maps depend on params, so we should clear them when params changed
176
+ if new_params != old_params
177
+ @_full_map = nil
178
+ @_map = nil
179
+ end
180
+
181
+ @_context = _context.merge!(context)
182
+ end
183
+ end
184
+
185
+ extend ClassMethods
186
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - aglushkov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Serialization tool to build JSON API response
14
+
15
+ '
16
+ email: aglushkov@shakuro.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/jat.rb
22
+ homepage: https://github.com/aglushkov/jat
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: JSON API Serializer
45
+ test_files: []