sobjectmodel 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []