sobjectmodel 0.1.2

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.
@@ -0,0 +1,553 @@
1
+ require 'json'
2
+
3
+ module SObjectModel
4
+ #
5
+ # sObject Schema
6
+ #
7
+ class Schema
8
+ def initialize(schema_hash)
9
+ @schema = schema_hash
10
+ end
11
+
12
+ def name
13
+ @name = schema['name']
14
+ end
15
+
16
+ def label
17
+ @label = schema['label']
18
+ end
19
+
20
+ def fields
21
+ @fields ||= Fields.new(schema)
22
+ end
23
+
24
+ def field_names
25
+ @field_names ||= fields.map{|f| f.name.to_sym}.sort
26
+ end
27
+
28
+ def field_labels
29
+ @field_labels ||= fields.map{|f| f.label}.sort
30
+ end
31
+
32
+ def child_relations
33
+ @child_relations ||= schema['childRelationships'].select{|r| r['relationshipName'].nil? == false}
34
+ .map{|r| {name: r['relationshipName'].to_sym, field: r['field'].to_sym, class_name: r['childSObject'].to_sym}}
35
+ end
36
+
37
+ def parent_relations
38
+ @parent_relations ||= fields.select{|f| !(f.relationship_name.nil? || f.reference_to.nil?) && f.reference_to.size > 0}
39
+ .map{|f| {name: f.relationship_name.to_sym, field: f.name.to_sym, class_name: f.reference_to.first.to_sym} }
40
+ end
41
+
42
+ def relations
43
+ @relations = Relations.new(child_relations + parent_relations)
44
+ end
45
+
46
+ def relation_names
47
+ relations.names
48
+ end
49
+
50
+ def to_h
51
+ schema
52
+ end
53
+
54
+ def action_overrides
55
+ schema["actionOverrides"]
56
+ end
57
+
58
+ def activateable?
59
+ schema["activateable"]
60
+ end
61
+
62
+ def associateEntityType
63
+ schema["associateEntityType"]
64
+ end
65
+
66
+ def associateParentEntity
67
+ schema["associateParentEntity"]
68
+ end
69
+
70
+ def compact_layoutable?
71
+ schema["compactLayoutable"]
72
+ end
73
+
74
+ def createable?
75
+ schema["createable"]
76
+ end
77
+
78
+ def custom?
79
+ schema["custom"]
80
+ end
81
+
82
+ def custom_setting?
83
+ schema["customSetting"]
84
+ end
85
+
86
+ def deep_cloneable?
87
+ schema["deepCloneable"]
88
+ end
89
+
90
+ def default_implementation
91
+ schema["defaultImplementation"]
92
+ end
93
+
94
+ def deletable?
95
+ schema["deletable"]
96
+ end
97
+
98
+ def deprecated_and_hidden?
99
+ schema["deprecatedAndHidden"]
100
+ end
101
+
102
+ def extended_by
103
+ schema["extendedBy"]
104
+ end
105
+
106
+ def extends_interfaces
107
+ schema["extendsInterfaces"]
108
+ end
109
+
110
+ def feed_enabled?
111
+ schema["feedEnabled"]
112
+ end
113
+
114
+ def has_subtypes?
115
+ schema["hasSubtypes"]
116
+ end
117
+
118
+ def implemented_by
119
+ schema["implementedBy"]
120
+ end
121
+
122
+ def implements_interfaces
123
+ schema["implementsInterfaces"]
124
+ end
125
+
126
+ def interface?
127
+ schema["isInterface"]
128
+ end
129
+
130
+ def subtype?
131
+ schema["isSubtype"]
132
+ end
133
+
134
+ def key_prefix
135
+ schema["keyPrefix"]
136
+ end
137
+
138
+ def label_plural
139
+ schema["labelPlural"]
140
+ end
141
+
142
+ def layoutable?
143
+ schema["layoutable"]
144
+ end
145
+
146
+ def listviewable?
147
+ schema["listviewable"]
148
+ end
149
+
150
+ def lookup_layoutable
151
+ schema["lookupLayoutable"]
152
+ end
153
+
154
+ def mergeable?
155
+ schema["mergeable"]
156
+ end
157
+
158
+ def mruEnabled
159
+ schema["mruEnabled"]
160
+ end
161
+
162
+ def named_layouts
163
+ schema["namedLayoutInfos"]
164
+ end
165
+
166
+ def network_scope_field_name
167
+ schema["networkScopeFieldName"]
168
+ end
169
+
170
+ def queryable?
171
+ schema["queryable"]
172
+ end
173
+
174
+ def record_types
175
+ @record_types = schema["recordTypeInfos"].map{|rt| RecordType.new(**rt)}
176
+ end
177
+
178
+ def replicateable?
179
+ schema["replicateable"]
180
+ end
181
+
182
+ def retrieveable?
183
+ schema["retrieveable"]
184
+ end
185
+
186
+ def search_layoutable?
187
+ schema["searchLayoutable"]
188
+ end
189
+
190
+ def searchable?
191
+ schema["searchable"]
192
+ end
193
+
194
+ def sobject_describe_option
195
+ schema["sobjectDescribeOption"]
196
+ end
197
+
198
+ def supported_scopes
199
+ schema["supportedScopes"]
200
+ end
201
+
202
+ def triggerable?
203
+ schema["triggerable"]
204
+ end
205
+
206
+ def undeletable?
207
+ schema["undeletable"]
208
+ end
209
+
210
+ def updateable?
211
+ schema["updateable"]
212
+ end
213
+
214
+ def urls
215
+ schema["urls"]
216
+ end
217
+
218
+ private
219
+
220
+ def schema
221
+ @schema
222
+ end
223
+
224
+ Relation = Struct.new(:name, :field, :class_name)
225
+ RecordType = Struct.new(:active, :available, :defaultRecordTypeMapping, :developerName, :master, :name, :recordTypeId, :urls)
226
+
227
+ class Relations
228
+ include Enumerable
229
+
230
+ def initialize(relations)
231
+ @relations = relations.map{|r| Relation.new(name: r[:name], field: r[:field], class_name: r[:class_name])}
232
+ end
233
+
234
+ def each(&block)
235
+ relations.each(&block)
236
+ end
237
+
238
+ def names
239
+ map(&:name).sort
240
+ end
241
+
242
+ def find(name)
243
+ relations.find{|r| r.name == name.to_sym}
244
+ end
245
+
246
+ private
247
+
248
+ def relations
249
+ @relations
250
+ end
251
+ end
252
+
253
+ class Fields
254
+ include Enumerable
255
+
256
+ def initialize(schema)
257
+ @fields = schema['fields'].map{|h| Field.new(**h)}
258
+ end
259
+
260
+ def each(&block)
261
+ fields.each &block
262
+ end
263
+
264
+ def to_a
265
+ fields
266
+ end
267
+
268
+ def find_by(name: nil, label: nil)
269
+ return nil if name.nil? && label.nil?
270
+
271
+ attr_name = name.nil? ? :label : :name
272
+ val = name || label
273
+
274
+ find do |field|
275
+ attr_val = field.__send__(attr_name.to_sym)
276
+ attr_val == val.to_s
277
+ end
278
+ end
279
+
280
+ def name_and_labels
281
+ map{|field| [field.name, field.label]}
282
+ end
283
+
284
+ def names
285
+ map(&:name)
286
+ end
287
+
288
+ def labels
289
+ map(&:label)
290
+ end
291
+
292
+ private
293
+
294
+ def fields
295
+ @fields
296
+ end
297
+ end
298
+
299
+ class Field
300
+ def initialize(field)
301
+ @field = field
302
+ end
303
+
304
+ def aggregatable?
305
+ field["aggregatable"]
306
+ end
307
+
308
+ def ai_prediction_field?
309
+ field["aiPredictionField"]
310
+ end
311
+
312
+ def autoNumber?
313
+ field["autoNumber"]
314
+ end
315
+
316
+ def byteLength
317
+ field["byteLength"]
318
+ end
319
+
320
+ def calculated?
321
+ field["calculated"]
322
+ end
323
+
324
+ def calculated_formula
325
+ field["calculatedFormula"]
326
+ end
327
+
328
+ def cascade_delete?
329
+ field["cascadeDelete"]
330
+ end
331
+
332
+ def case_sensitive
333
+ field["caseSensitive"]
334
+ end
335
+
336
+ def compound_field_name
337
+ field["compoundFieldName"]
338
+ end
339
+
340
+ def controller_name
341
+ field["controllerName"]
342
+ end
343
+
344
+ def createable?
345
+ field["createable"]
346
+ end
347
+
348
+ def custom?
349
+ field["custom"]
350
+ end
351
+
352
+ def default_value
353
+ field["defaultValue"]
354
+ end
355
+
356
+ def default_value_formula
357
+ field["defaultValueFormula"]
358
+ end
359
+
360
+ def defaulted_on_create?
361
+ field["defaultedOnCreate"]
362
+ end
363
+
364
+ def dependent_picklist?
365
+ field["dependentPicklist"]
366
+ end
367
+
368
+ def deprecated_and_hidden?
369
+ field["deprecatedAndHidden"]
370
+ end
371
+
372
+ def digits
373
+ field["digits"]
374
+ end
375
+
376
+ def display_location_in_decimal?
377
+ field["displayLocationInDecimal"]
378
+ end
379
+
380
+ def encrypted?
381
+ field["encrypted"]
382
+ end
383
+
384
+ def external_id?
385
+ field["externalId"]
386
+ end
387
+
388
+ def extra_type_info
389
+ field["extraTypeInfo"]
390
+ end
391
+
392
+ def filterable?
393
+ field["filterable"]
394
+ end
395
+
396
+ def filtered_lookup_info
397
+ field["filteredLookupInfo"]
398
+ end
399
+
400
+ def formula_treat_null_number_as_zero?
401
+ field["formulaTreatNullNumberAsZero"]
402
+ end
403
+
404
+ def groupable?
405
+ field["groupable"]
406
+ end
407
+
408
+ def high_scale_number?
409
+ field["highScaleNumber"]
410
+ end
411
+
412
+ def html_formatted?
413
+ field["htmlFormatted"]
414
+ end
415
+
416
+ def id_lookup?
417
+ field["idLookup"]
418
+ end
419
+
420
+ def inline_help_text
421
+ field["inlineHelpText"]
422
+ end
423
+
424
+ def label
425
+ field["label"]
426
+ end
427
+
428
+ def length
429
+ field["length"]
430
+ end
431
+
432
+ def mask
433
+ field["mask"]
434
+ end
435
+
436
+ def mask_type
437
+ field["maskType"]
438
+ end
439
+
440
+ def name
441
+ field["name"]
442
+ end
443
+
444
+ def name_field?
445
+ field["nameField"]
446
+ end
447
+
448
+ def name_pointing?
449
+ field["namePointing"]
450
+ end
451
+
452
+ def nillable?
453
+ field["nillable"]
454
+ end
455
+
456
+ def permissionable?
457
+ field["permissionable"]
458
+ end
459
+
460
+ PicklistValue = Data.define(:active, :default_value, :label, :valid_for, :value)
461
+
462
+ def picklist_values
463
+ field["picklistValues"].map do |value|
464
+ PicklistValue.new(
465
+ active: value['active'],
466
+ default_value: value['defaultValue'],
467
+ label: value['label'],
468
+ valid_for: value['validFor'],
469
+ value: value['value'],
470
+ )
471
+ end
472
+ end
473
+
474
+ def polymorphic_foreign_key?
475
+ field["polymorphicForeignKey"]
476
+ end
477
+
478
+ def precision
479
+ field["precision"]
480
+ end
481
+
482
+ def query_by_distance?
483
+ field["queryByDistance"]
484
+ end
485
+
486
+ def reference_target_field
487
+ field["referenceTargetField"]
488
+ end
489
+
490
+ def reference_to
491
+ field["referenceTo"]
492
+ end
493
+
494
+ def relationship_name
495
+ field["relationshipName"]
496
+ end
497
+
498
+ def relationship_order
499
+ field["relationshipOrder"]
500
+ end
501
+
502
+ def restricted_delete
503
+ field["restrictedDelete"]
504
+ end
505
+
506
+ def restricted_picklist?
507
+ field["restrictedPicklist"]
508
+ end
509
+
510
+ def scale
511
+ field["scale"]
512
+ end
513
+
514
+ def search_prefilterable?
515
+ field["searchPrefilterable"]
516
+ end
517
+
518
+ def soapType
519
+ field["soapType"]
520
+ end
521
+
522
+ def sortable?
523
+ field["sortable"]
524
+ end
525
+
526
+ def type
527
+ field["type"]
528
+ end
529
+
530
+ def unique?
531
+ field["unique"]
532
+ end
533
+
534
+ def updateable?
535
+ field["updateable"]
536
+ end
537
+
538
+ def write_Requires_Master_Read?
539
+ field["writeRequiresMasterRead"]
540
+ end
541
+
542
+ def to_h
543
+ field
544
+ end
545
+
546
+ private
547
+
548
+ def field
549
+ @field
550
+ end
551
+ end
552
+ end
553
+ end
@@ -0,0 +1,63 @@
1
+ require 'sf_cli'
2
+ require 'sobject_model'
3
+
4
+ def use(target_org)
5
+ config = sf.org.display target_org: target_org
6
+ SObjectModel.connect(
7
+ :rest,
8
+ instance_url: config.instance_url,
9
+ access_token: config.access_token,
10
+ api_version: config.api_version
11
+ )
12
+ unless config.connected?
13
+ sf.org.login_web target_org: target_org, instance_url: config.instance_url
14
+ end
15
+
16
+ available_models.each do |model|
17
+ Object.const_get(model).connection = conn
18
+ end
19
+
20
+ @current_org = config
21
+
22
+ true
23
+ end
24
+
25
+ def available_models
26
+ @available_models ||= []
27
+ end
28
+
29
+ def generate(*object_types)
30
+ SObjectModel.generate(*object_types)
31
+ available_models.append(*object_types).flatten.uniq
32
+ object_types
33
+ end
34
+
35
+ def connection
36
+ SObjectModel.connection
37
+ end
38
+
39
+ def target_org
40
+ current_org.alias
41
+ end
42
+
43
+ def current_org
44
+ @current_org
45
+ end
46
+
47
+ def query(_soql)
48
+ soql = _soql.is_a?(SObjectModel::QueryMethods::QueryCondition) ? _soql.to_soql : _soql
49
+ conf.inspect_mode = false
50
+ puts sf.data.query(soql, format: :human, target_org: target_org)
51
+ conf.inspect_mode = true
52
+ end
53
+
54
+ def orgs
55
+ conf.inspect_mode = false
56
+ system 'sf org list'
57
+ conf.inspect_mode = true
58
+ end
59
+
60
+ alias :gen :generate
61
+ alias :conn :connection
62
+
63
+ use ARGV[0] if ARGV[0]
@@ -0,0 +1,29 @@
1
+ require 'sobject_model/rest/client'
2
+ require 'sobject_model/adapter/rest'
3
+ require 'sobject_model/adapter/sf'
4
+ require 'sobject_model/generator'
5
+
6
+ module SObjectModel
7
+ def self.connect(api_type, options = {})
8
+ @connection = case api_type.to_s.upcase
9
+ when 'REST'
10
+ client = Rest::Client.new(**options)
11
+ Adapter::Rest.new(client)
12
+ when 'CLI/SF'
13
+ Adapter::Sf.new(sf, **options)
14
+ end
15
+ end
16
+
17
+ def self.connection
18
+ @connection
19
+ end
20
+
21
+ def self.connection=(connector)
22
+ @connection = connector
23
+ end
24
+
25
+ def self.generate(*sobject_types)
26
+ generator = Generator.new(connection)
27
+ generator.generate(*sobject_types)
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sobjectmodel
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Takanobu Maekawa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Saleforce sObject class library
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/sobject_model.rb
20
+ - lib/sobject_model/adapter/base.rb
21
+ - lib/sobject_model/adapter/rest.rb
22
+ - lib/sobject_model/adapter/sf.rb
23
+ - lib/sobject_model/base_methods.rb
24
+ - lib/sobject_model/class_definition.rb
25
+ - lib/sobject_model/dml_methods.rb
26
+ - lib/sobject_model/generator.rb
27
+ - lib/sobject_model/query_condition.rb
28
+ - lib/sobject_model/query_methods.rb
29
+ - lib/sobject_model/rest/client.rb
30
+ - lib/sobject_model/rest/errors.rb
31
+ - lib/sobject_model/rest/http.rb
32
+ - lib/sobject_model/rest/query_result.rb
33
+ - lib/sobject_model/schema.rb
34
+ - lib/sobject_model/support/console.rb
35
+ homepage: https://github.com/tmkw/sobjectmodel
36
+ licenses:
37
+ - BSD-2-Clause
38
+ metadata:
39
+ homepage_uri: https://github.com/tmkw/sobjectmodel
40
+ source_code_uri: https://github.com/tmkw/sobjectmodel
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.3.3
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 3.5.11
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Saleforce sObject class library
60
+ test_files: []