notion 1.0.7 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 260bf00a0f7ffc3dec1cbf364c69815e5dcbf829677710e5b740bd58476ca9f7
4
- data.tar.gz: 7220c9399aca9756e4773dda4b5fbdd573bd3decfe32758797ea11e309e6f0e0
3
+ metadata.gz: f33fd46038d04e6945365a27f4c06bf271606c26738e0f829b303cf62bbb516d
4
+ data.tar.gz: 92e51354718ea8c3d947e77f1aa9073cb654312e8783f9e375d246b8f2145188
5
5
  SHA512:
6
- metadata.gz: d5933ae50944a7f77e6c68410d4291935b769869b59f71817dabd98df2e5a50f86f6200c4b7bc9800249e274c4e3ecd1e5d339df66cb08e258c50c25308e3bba
7
- data.tar.gz: e01f29a16242b81b586d7852062efe030a760f30620096a691be6ee47c45de3d5f1b1ef7ce0f166a6c3328e3972ca470aaffd51b235f8d9f2f6c8b6ead69c193
6
+ metadata.gz: b0c40153c1ec62514f1c6cea7c3a1c6e48bd5180c1eff123b92873527368ca64922a24ab1a9de28c33084a1e248e8a9d702456f3b7efc412bca9b9487dbb947e
7
+ data.tar.gz: a67029c37053b49be748fb5268ec1022be91194723fd9a4e68657cbc1baf9d0d1e13a5cf75e1f23dc2a4851ae611cf511c46aff2afc59e0fbcad347e256ef6c3
data/README.md CHANGED
@@ -310,8 +310,12 @@ From here, you can instantiate the Notion Client with the following code:
310
310
  )
311
311
  ```
312
312
  ### Retrieve a full-page Collection View
313
- Currently, either a "normal" Page URL or the Page Block ID is accepted to the `get_page` method. Therefore, if you pass the full URL to the CV Table, it will raise an error:
314
- ```text
315
- the URL or ID passed to the get_page method must be that of a Page Block.
313
+ A full-page collection view must have a URL that follows the below pattern:
314
+ https://www.notion.so/danmurphy/[page-id]?v=[view-id]
315
+ Then, it can be retrieved with the following code:
316
+ ```ruby
317
+ >>> @client = NotionAPI::Client.new(
318
+ "<insert_v2_token_here>"
319
+ )
320
+ >>> @client.get_page("https://www.notion.so/danmurphy/[page-id]?v=[view-id]")
316
321
  ```
317
- To avoid this, you must pass only the ID of the full-page collection-view to the `get_page` method. This is next up on the features list, so passing the full URL will be supported soon:smile:
@@ -17,6 +17,7 @@ require_relative "notion_types/table_of_contents_block"
17
17
  require_relative "notion_types/text_block"
18
18
  require_relative "notion_types/todo_block"
19
19
  require_relative "notion_types/toggle_block"
20
+ require_relative "notion_types/link_block"
20
21
 
21
22
  Classes = NotionAPI.constants.select { |c| NotionAPI.const_get(c).is_a? Class and c.to_s != 'BlockTemplate' and c.to_s != 'Core' and c.to_s !='Client' }
22
23
  notion_types = []
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'core'
4
- require_relative 'blocks'
3
+ require_relative "core"
4
+ require_relative "blocks"
5
5
 
6
6
  module NotionAPI
7
7
  # acts as the 'main interface' to the methods of this package.
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'utils'
4
- require 'httparty'
3
+ require_relative "utils"
4
+ require "httparty"
5
5
 
6
6
  module NotionAPI
7
7
  # the initial methods available to an instantiated Cloent object are defined
8
8
  class Core
9
9
  include Utils
10
- @options = { 'cookies' => { :token_v2 => nil, 'x-active-user-header' => nil }, 'headers' => { 'Content-Type' => 'application/json' } }
11
- @type_whitelist = 'divider'
10
+ @options = { "cookies" => { :token_v2 => nil, "x-active-user-header" => nil }, "headers" => { "Content-Type" => "application/json" } }
11
+ @type_whitelist = "divider"
12
12
 
13
13
  class << self
14
14
  attr_reader :options, :type_whitelist, :token_v2, :active_user_header
@@ -30,39 +30,16 @@ module NotionAPI
30
30
  pageId: clean_id,
31
31
  chunkNumber: 0,
32
32
  limit: 100,
33
- verticalColumns: false
33
+ verticalColumns: false,
34
34
  }
35
- jsonified_record_response = get_all_block_info(clean_id, request_body)
36
- i = 0
37
- while jsonified_record_response.empty? || jsonified_record_response['block'].empty?
38
- return {} if i >= 10
35
+ jsonified_record_response = get_all_block_info(request_body)
39
36
 
40
- jsonified_record_response = get_all_block_info(clean_id, request_body)
41
- i += 1
42
- end
43
-
44
- block_id = clean_id
45
37
  block_type = extract_type(clean_id, jsonified_record_response)
46
38
  block_parent_id = extract_parent_id(clean_id, jsonified_record_response)
47
39
 
48
- raise 'the URL or ID passed to the get_page method must be that of a Page Block.' if !['collection_view_page', 'page'].include?(block_type)
49
-
50
- if block_type == "page"
51
- block_title = extract_title(clean_id, jsonified_record_response)
52
- PageBlock.new(block_id, block_title, block_parent_id)
53
- elsif block_type == "collection_view_page"
54
- collection_id = extract_collection_id(block_id, jsonified_record_response)
55
- block_title = extract_collection_title(clean_id, collection_id, jsonified_record_response)
56
- view_id = extract_view_ids(block_id, jsonified_record_response)[0]
57
- schema = extract_collection_schema(collection_id, view_id, jsonified_record_response)
58
- column_mappings = schema.keys
59
- column_names = column_mappings.map { |mapping| schema[mapping]['name']}
60
-
61
- collection_view_page = CollectionViewPage.new(block_id, block_title, block_parent_id, collection_id, view_id)
62
- collection_view_page.instance_variable_set(:@column_names, column_names)
63
- CollectionView.class_eval{attr_reader :column_names}
64
- collection_view_page
65
- end
40
+ raise ArgumentError, "the URL or ID passed to the get_page method must be that of a Page Block." if !["collection_view_page", "page"].include?(block_type)
41
+
42
+ get_instantiated_instance_for(block_type, clean_id, block_parent_id, jsonified_record_response)
66
43
  end
67
44
 
68
45
  def children(url_or_id = @id)
@@ -87,18 +64,41 @@ module NotionAPI
87
64
  pageId: clean_id,
88
65
  chunkNumber: 0,
89
66
  limit: 100,
90
- verticalColumns: false
67
+ verticalColumns: false,
91
68
  }
92
- jsonified_record_response = get_all_block_info(clean_id, request_body)
93
- i = 0
94
- while jsonified_record_response.empty?
95
- return {} if i >= 10
69
+ jsonified_record_response = get_all_block_info(request_body)
96
70
 
97
- jsonified_record_response = get_all_block_info(clean_id, request_body)
98
- i += 1
99
- end
71
+ # if no content, returns empty list
72
+ jsonified_record_response["block"][clean_id]["value"]["content"] || []
73
+ end
74
+
75
+ def extract_id(url_or_id)
76
+ # ! parse and clean the URL or ID object provided.
77
+ # ! url_or_id -> the block ID or URL : ``str``
78
+ http_or_https = url_or_id.match(/^(http|https)/) # true if http or https in url_or_id...
79
+ collection_view_match = url_or_id.match(/(\?v=)/)
100
80
 
101
- jsonified_record_response['block'][clean_id]['value']['content'] || []
81
+ if (url_or_id.length == 36) && ((url_or_id.split("-").length == 5) && !http_or_https)
82
+ # passes if url_or_id is perfectly formatted already...
83
+ url_or_id
84
+ elsif (http_or_https && (url_or_id.split("-").last.length == 32)) || (!http_or_https && (url_or_id.length == 32)) || (collection_view_match)
85
+ # passes if either:
86
+ # 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
87
+ # 2. a URL is not passed and the ID length is 32 [aka unformatted]
88
+ pattern = [8, 13, 18, 23]
89
+ if collection_view_match
90
+ id_without_view = url_or_id.split("?")[0]
91
+ clean_id = id_without_view.split("/").last
92
+ pattern.each { |index| clean_id.insert(index, "-") }
93
+ clean_id
94
+ else
95
+ id = url_or_id.split("-").last
96
+ pattern.each { |index| id.insert(index, "-") }
97
+ id
98
+ end
99
+ else
100
+ raise ArgumentError, "Expected a Notion page URL or a page ID. Please consult the documentation for further information."
101
+ end
102
102
  end
103
103
 
104
104
  private
@@ -106,19 +106,19 @@ module NotionAPI
106
106
  def get_notion_id(body)
107
107
  # ! retrieves a users ID from the headers of a Notion response object.
108
108
  # ! body -> the body to send in the request : ``Hash``
109
- Core.options['cookies'][:token_v2] = @@token_v2
110
- Core.options['headers']['x-notion-active-user-header'] = @@active_user_header
111
- cookies = Core.options['cookies']
112
- headers = Core.options['headers']
109
+ Core.options["cookies"][:token_v2] = @@token_v2
110
+ Core.options["headers"]["x-notion-active-user-header"] = @@active_user_header
111
+ cookies = Core.options["cookies"]
112
+ headers = Core.options["headers"]
113
113
  request_url = URLS[:GET_BLOCK]
114
114
 
115
115
  response = HTTParty.post(
116
116
  request_url,
117
117
  body: body.to_json,
118
118
  cookies: cookies,
119
- headers: headers
119
+ headers: headers,
120
120
  )
121
- response.headers['x-notion-user-id']
121
+ response.headers["x-notion-user-id"]
122
122
  end
123
123
 
124
124
  def get_last_page_block_id(url_or_id)
@@ -132,48 +132,53 @@ module NotionAPI
132
132
  pageId: clean_id,
133
133
  chunkNumber: 0,
134
134
  limit: 100,
135
- verticalColumns: false
135
+ verticalColumns: false,
136
136
  }
137
- jsonified_record_response = get_all_block_info(clean_id, request_body)
138
- i = 0
139
- while jsonified_record_response.empty?
140
- return {:properties => {title: [[block_title]]}, :format => {}} if i >= 10
137
+ jsonified_record_response = get_all_block_info(request_body)
141
138
 
142
- jsonified_record_response = get_all_block_info(clean_id, request_body)
143
- i += 1
144
- end
145
- properties = jsonified_record_response['block'][clean_id]['value']['properties']
146
- formats = jsonified_record_response['block'][clean_id]['value']['format']
139
+ properties = jsonified_record_response["block"][clean_id]["value"]["properties"]
140
+ formats = jsonified_record_response["block"][clean_id]["value"]["format"]
147
141
  return {
148
- :properties => properties,
149
- :format => formats
150
- }
142
+ :properties => properties,
143
+ :format => formats,
144
+ }
151
145
  end
152
146
 
153
- def get_all_block_info(_clean_id, body)
147
+ def get_all_block_info(body, i = 0)
154
148
  # ! retrieves all info pertaining to a block Id.
155
149
  # ! clean_id -> the block ID or URL cleaned : ``str``
156
- Core.options['cookies'][:token_v2] = @@token_v2
157
- Core.options['headers']['x-notion-active-user-header'] = @@active_user_header
158
- cookies = Core.options['cookies']
159
- headers = Core.options['headers']
160
-
150
+ Core.options["cookies"][:token_v2] = @@token_v2
151
+ Core.options["headers"]["x-notion-active-user-header"] = @@active_user_header
152
+ cookies = Core.options["cookies"]
153
+ headers = Core.options["headers"]
161
154
  request_url = URLS[:GET_BLOCK]
162
155
 
163
156
  response = HTTParty.post(
164
157
  request_url,
165
158
  body: body.to_json,
166
159
  cookies: cookies,
167
- headers: headers
160
+ headers: headers,
168
161
  )
169
162
 
170
- JSON.parse(response.body)['recordMap']
163
+ jsonified_record_response = JSON.parse(response.body)["recordMap"]
164
+ response_invalid = (!jsonified_record_response || jsonified_record_response.empty? || jsonified_record_response["block"].empty?)
165
+
166
+ if i < 10 && response_invalid
167
+ i = i + 1
168
+ return get_all_block_info(body, i)
169
+ else
170
+ if i == 10 && response_invalid
171
+ raise InvalidClientInstantiationError, "Attempted to retrieve block 10 times and received an empty response each time. Please make sure you have a valid token_v2 value set. If you do, then try setting the 'active_user_header' variable as well."
172
+ else
173
+ return jsonified_record_response
174
+ end
175
+ end
171
176
  end
172
177
 
173
178
  def filter_nil_blocks(jsonified_record_response)
174
179
  # ! removes any blocks that are empty [i.e. have no title / content]
175
180
  # ! jsonified_record_responses -> parsed JSON representation of a notion response object : ``Json``
176
- jsonified_record_response.empty? || jsonified_record_response['block'].empty? ? nil : jsonified_record_response['block']
181
+ jsonified_record_response.empty? || jsonified_record_response["block"].empty? ? nil : jsonified_record_response["block"]
177
182
  end
178
183
 
179
184
  def extract_title(clean_id, jsonified_record_response)
@@ -181,14 +186,13 @@ module NotionAPI
181
186
  # ! clean_id -> the cleaned block ID: ``str``
182
187
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
183
188
  filter_nil_blocks = filter_nil_blocks(jsonified_record_response)
184
- if filter_nil_blocks.nil? || filter_nil_blocks[clean_id].nil? || filter_nil_blocks[clean_id]['value']['properties'].nil?
189
+ if filter_nil_blocks.nil? || filter_nil_blocks[clean_id].nil? || filter_nil_blocks[clean_id]["value"]["properties"].nil?
185
190
  nil
186
191
  else
187
192
  # titles for images are called source, while titles for text-based blocks are called title, so lets dynamically grab it
188
193
  # https://stackoverflow.com/questions/23765996/get-all-keys-from-ruby-hash/23766007
189
- title_value = filter_nil_blocks[clean_id]['value']['properties'].keys[0]
190
- Core.type_whitelist.include?(filter_nil_blocks[clean_id]['value']['type']) ? nil : jsonified_record_response['block'][clean_id]['value']['properties'][title_value].flatten[0]
191
-
194
+ title_value = filter_nil_blocks[clean_id]["value"]["properties"].keys[0]
195
+ Core.type_whitelist.include?(filter_nil_blocks[clean_id]["value"]["type"]) ? nil : jsonified_record_response["block"][clean_id]["value"]["properties"][title_value].flatten[0]
192
196
  end
193
197
  end
194
198
 
@@ -197,7 +201,7 @@ module NotionAPI
197
201
  # ! clean_id -> the cleaned block ID: ``str``
198
202
  # ! collection_id -> the collection ID: ``str``
199
203
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
200
- jsonified_record_response['collection'][collection_id]['value']['name'].flatten.join if jsonified_record_response['collection'] and jsonified_record_response['collection'][collection_id]['value']['name']
204
+ jsonified_record_response["collection"][collection_id]["value"]["name"].flatten.join if jsonified_record_response["collection"] and jsonified_record_response["collection"][collection_id]["value"]["name"]
201
205
  end
202
206
 
203
207
  def extract_type(clean_id, jsonified_record_response)
@@ -208,8 +212,7 @@ module NotionAPI
208
212
  if filter_nil_blocks.nil?
209
213
  nil
210
214
  else
211
- filter_nil_blocks[clean_id]['value']['type']
212
-
215
+ filter_nil_blocks[clean_id]["value"]["type"]
213
216
  end
214
217
  end
215
218
 
@@ -217,80 +220,135 @@ module NotionAPI
217
220
  # ! extract parent ID from core JSON response object.
218
221
  # ! clean_id -> the block ID or URL cleaned : ``str``
219
222
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
220
- jsonified_record_response.empty? || jsonified_record_response['block'].empty? ? {} : jsonified_record_response['block'][clean_id]['value']['parent_id']
223
+ jsonified_record_response.empty? || jsonified_record_response["block"].empty? ? {} : jsonified_record_response["block"][clean_id]["value"]["parent_id"]
221
224
  end
222
225
 
223
226
  def extract_collection_id(clean_id, jsonified_record_response)
224
227
  # ! extract the collection ID
225
228
  # ! clean_id -> the block ID or URL cleaned : ``str``
226
229
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
227
- jsonified_record_response['block'][clean_id]['value']['collection_id']
230
+ jsonified_record_response["block"][clean_id]["value"]["collection_id"]
228
231
  end
229
232
 
230
233
  def extract_view_ids(clean_id, jsonified_record_response)
231
- jsonified_record_response['block'][clean_id]['value']['view_ids'] || []
232
- end
233
-
234
- def extract_id(url_or_id)
235
- # ! parse and clean the URL or ID object provided.
236
- # ! url_or_id -> the block ID or URL : ``str``
237
- http_or_https = url_or_id.match(/^(http|https)/) # true if http or https in url_or_id...
238
- if (url_or_id.length == 36) && ((url_or_id.split('-').length == 5) && !http_or_https)
239
- # passes if url_or_id is perfectly formatted already...
240
- url_or_id
241
- elsif (http_or_https && (url_or_id.split('-').last.length == 32)) || (!http_or_https && (url_or_id.length == 32))
242
- # passes if either:
243
- # 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
244
- # 2. a URL is not passed and the ID length is 32 [aka unformatted]
245
- pattern = [8, 13, 18, 23]
246
- id = url_or_id.split('-').last
247
- pattern.each { |index| id.insert(index, '-') }
248
- id
249
- else
250
- raise ArgumentError, 'Expected a Notion page URL or a page ID. Please consult the documentation for further information.'
251
- end
234
+ jsonified_record_response["block"][clean_id]["value"]["view_ids"] || []
252
235
  end
253
236
 
237
+ # def extract_id(url_or_id)
238
+ # # ! parse and clean the URL or ID object provided.
239
+ # # ! url_or_id -> the block ID or URL : ``str``
240
+ # http_or_https = url_or_id.match(/^(http|https)/) # true if http or https in url_or_id...
241
+ # collection_view_match = url_or_id.match(/(\?v=)/)
242
+
243
+ # if (url_or_id.length == 36) && ((url_or_id.split("-").length == 5) && !http_or_https)
244
+ # # passes if url_or_id is perfectly formatted already...
245
+ # url_or_id
246
+ # elsif (http_or_https && (url_or_id.split("-").last.length == 32)) || (!http_or_https && (url_or_id.length == 32)) || (collection_view_match)
247
+ # # passes if either:
248
+ # # 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
249
+ # # 2. a URL is not passed and the ID length is 32 [aka unformatted]
250
+ # pattern = [8, 13, 18, 23]
251
+ # if collection_view_match
252
+ # id_without_view = url_or_id.split("?")[0]
253
+ # clean_id = id_without_view.split("/").last
254
+ # pattern.each { |index| clean_id.insert(index, "-") }
255
+ # clean_id
256
+ # else
257
+ # id = url_or_id.split("-").last
258
+ # pattern.each { |index| id.insert(index, "-") }
259
+ # id
260
+ # end
261
+ # else
262
+ # raise ArgumentError, "Expected a Notion page URL or a page ID. Please consult the documentation for further information."
263
+ # end
264
+ # end
265
+
254
266
  def extract_collection_schema(collection_id, view_id, response = {})
255
267
  # ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
256
268
  # ! collection_id -> the collection ID : ``str``
257
269
  # ! view_id -> the view ID : ``str``
258
- cookies = Core.options['cookies']
259
- headers = Core.options['headers']
270
+ cookies = Core.options["cookies"]
271
+ headers = Core.options["headers"]
260
272
 
261
273
  if response.empty?
262
- query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
274
+ query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, "")
263
275
 
264
276
  request_url = URLS[:GET_COLLECTION]
265
277
  response = HTTParty.post(
266
278
  request_url,
267
279
  body: query_collection_hash.to_json,
268
280
  cookies: cookies,
269
- headers: headers
281
+ headers: headers,
270
282
  )
271
- response['recordMap']['collection'][collection_id]['value']['schema']
283
+ response["recordMap"]["collection"][collection_id]["value"]["schema"]
272
284
  else
273
- response['collection'][collection_id]['value']['schema']
285
+ response["collection"][collection_id]["value"]["schema"]
274
286
  end
275
287
  end
276
-
288
+
277
289
  def extract_collection_data(collection_id, view_id)
278
290
  # ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
279
291
  # ! collection_id -> the collection ID : ``str``
280
292
  # ! view_id -> the view ID : ``str``
281
- cookies = Core.options['cookies']
282
- headers = Core.options['headers']
293
+ cookies = Core.options["cookies"]
294
+ headers = Core.options["headers"]
283
295
 
284
- query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
296
+ query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, "")
285
297
 
286
298
  request_url = URLS[:GET_COLLECTION]
287
299
  response = HTTParty.post(
288
300
  request_url,
289
301
  body: query_collection_hash.to_json,
290
302
  cookies: cookies,
291
- headers: headers
303
+ headers: headers,
292
304
  )
293
- response['recordMap']
305
+ response["recordMap"]
306
+ end
307
+
308
+ def extract_page_information(page_meta = {})
309
+ # ! helper method for extracting information about a page block
310
+ # ! page_meta -> hash containing data points useful for the extraction of a page blocks information.
311
+ # ! This should include clean_id, jsonified_record_response, and parent_id
312
+ clean_id = page_meta.fetch(:clean_id)
313
+ jsonified_record_response = page_meta.fetch(:jsonified_record_response)
314
+ block_parent_id = page_meta.fetch(:parent_id)
315
+
316
+ block_title = extract_title(clean_id, jsonified_record_response)
317
+ PageBlock.new(clean_id, block_title, block_parent_id)
318
+ end
319
+
320
+ def extract_collection_view_page_information(page_meta = {})
321
+ # ! helper method for extracting information about a Collection View page block
322
+ # ! page_meta -> hash containing data points useful for the extraction of a page blocks information.
323
+ # ! This should include clean_id, jsonified_record_response, and parent_id
324
+ clean_id = page_meta.fetch(:clean_id)
325
+ jsonified_record_response = page_meta.fetch(:jsonified_record_response)
326
+ block_parent_id = page_meta.fetch(:parent_id)
327
+
328
+ collection_id = extract_collection_id(clean_id, jsonified_record_response)
329
+ block_title = extract_collection_title(clean_id, collection_id, jsonified_record_response)
330
+ view_id = extract_view_ids(clean_id, jsonified_record_response)[0]
331
+ schema = extract_collection_schema(collection_id, view_id, jsonified_record_response)
332
+ column_names = NotionAPI::CollectionView.extract_collection_view_column_names(schema)
333
+
334
+ collection_view_page = CollectionViewPage.new(clean_id, block_title, block_parent_id, collection_id, view_id)
335
+ collection_view_page.instance_variable_set(:@column_names, column_names)
336
+ CollectionView.class_eval { attr_reader :column_names }
337
+ collection_view_page
338
+ end
339
+
340
+ def get_instantiated_instance_for(block_type, clean_id, parent_id, jsonified_record_response)
341
+ case block_type
342
+ when "page" then extract_page_information(clean_id: clean_id, parent_id: parent_id, jsonified_record_response: jsonified_record_response)
343
+ when "collection_view_page" then extract_collection_view_page_information(clean_id: clean_id, parent_id: parent_id, jsonified_record_response: jsonified_record_response)
344
+ end
345
+ end
346
+
347
+ class InvalidClientInstantiationError < StandardError
348
+ def initialize(msg = "Custom exception that is raised when an invalid property type is passed as a mapping.", exception_type = "instantiation_type")
349
+ @exception_type = exception_type
350
+ super(msg)
351
+ end
294
352
  end
295
353
  end
296
354
  end