forked from ForceCLI/force
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathforce.go
1262 lines (1108 loc) · 40.8 KB
/
force.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"encoding/pem"
"encoding/xml"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"runtime"
"strings"
)
const (
ProductionClientId = "3MVG9A2kN3Bn17huXZp1OQhPe8y4_ozAQZZCKxsWbef9GjSnHGOunHSwhnY1BWz_5vHkTL9BeLMriIX5EUKaw"
PrereleaseClientId = "3MVG9lKcPoNINVBIRgC7lsz5tIhlg0mtoEqkA9ZjDAwEMbBy43gsnfkzzdTdhFLeNnWS8M4bnRnVv1Qj0k9MD"
Mobile1ClientId = "3MVG9Iu66FKeHhIPqCB9VWfYPxjfcb5Ube.v5L81BLhnJtDYVP2nkA.mDPwfm5FTLbvL6aMftfi8w0rL7Dv7f"
RedirectUri = "https://force-cli.herokuapp.com/auth/callback"
)
var CustomEndpoint = ``
const (
EndpointProduction = iota
EndpointTest = iota
EndpointPrerelease = iota
EndpointMobile1 = iota
EndpointCustom = iota
)
const (
apiVersion = "v34.0"
apiVersionNumber = "34.0"
)
var RootCertificates = `
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEeDCCA2CgAwIBAgIOAQAAAAABNwQKT8CN490wDQYJKoZIhvcNAQEFBQAwUDEX
MBUGA1UEChMOQ3liZXJ0cnVzdCBJbmMxNTAzBgNVBAMTLEN5YmVydHJ1c3QgU3Vy
ZVNlcnZlciBTdGFuZGFyZCBWYWxpZGF0aW9uIENBMB4XDTEyMDQzMDE2MzI0NloX
DTE1MDQzMDE2MzI0NlowgbExCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRswGQYDVQQKExJTYWxlc2ZvcmNl
LmNvbSBJbmMxFTATBgNVBAsTDEFwcGxpY2F0aW9uczEhMB8GCSqGSIb3DQEJARYS
bm9jQHNhbGVzZm9yY2UuY29tMR4wHAYDVQQDDBUqLnNvbWEuc2FsZXNmb3JjZS5j
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHo8bILux1ZYwD1JTW
PBE6LTV0hAdILIv06++N0RkhYU0ry69/yAFKWM5SUqt19dk9H3x43uC50tFRUT/l
UoP/ztjT8Z47UczjVXSPrRCa/HloiA9zobLNFrsES/atCLHjzoxBLth477iZNnFs
sINW8Kz6+v+7G83zzrMs6J4eYzZauNlhvCHBjwotPqtbJEp6MESoEO0XcNJkVLXA
2sysfOpZH89P8j+1AMByc/32aauAZqwfmTD1iyGHyguieFdySWMDYL3r3j+uhey8
XjxMO5AYRRh6EB4UQ5IlsjyzoAeJg5+q7+dJRhZ3KVr9KJ74UkRLab4NiUFRbXjj
TnqjAgMBAAGjge0wgeowHwYDVR0jBBgwFoAUzTqWn65uD0BcHEj4Sy24cQHridow
OQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL2NybC5vbW5pcm9vdC5jb20vU3VyZVNl
cnZlckcyLmNybDAdBgNVHQ4EFgQUVKhO+ZroJ0ZNcV80wap72/eTqGswCQYDVR0T
BAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
BwMCMBEGCWCGSAGG+EIBAQQEAwIGwDAgBgNVHREEGTAXghUqLnNvbWEuc2FsZXNm
b3JjZS5jb20wDQYJKoZIhvcNAQEFBQADggEBACiMRXtltlPjDdzuTG6B8F6c0AOE
nJl5T4Lz4BMc5jvyin3zR1uPrZC7H/VEc6MOzXQK+n1i9xfNGURjTtfpCOdbcmZ9
MkkRbu8EJyoO2FM84BdVtCOs5nomE/Py9xqX4mdy38yhjnJywvFa+M4rGDNcVR4W
ZOV5H9LlMuEjuVuWYRLSRwu6Uk+QVN/tL9ImiWM1p4cziuizWXtjPqLyaQmOvykY
4ihtSnZuel7PqGhBMoFHbuw11CB3S3ap2hzfreeJcYT/019Y5p8DPuFh6BJ3Q85J
oo54Un5pgx/wX8L1UaMLMLUSv9d+nuKKLYYg+MW+1+LNNkLP704/Y/GWPvE=
-----END CERTIFICATE-----`
type Force struct {
Credentials ForceCredentials
Metadata *ForceMetadata
Partner *ForcePartner
}
type ForceCredentials struct {
AccessToken string
Id string
UserId string
InstanceUrl string
IssuedAt string
Scope string
IsCustomEP bool
Namespace string
ForceEndpoint ForceEndpoint
}
type LoginFault struct {
ExceptionCode string `xml:"exceptionCode"`
ExceptionMessage string `xml:"exceptionMessage"`
}
type SoapFault struct {
FaultCode string `xml:"Body>Fault>faultcode"`
FaultString string `xml:"Body>Fault>faultstring"`
Detail LoginFault `xml:"Body>Fault>detail>LoginFault"`
}
type GenericForceError struct {
Error_Description string
Error string
}
type ForceError struct {
Message string
ErrorCode string
}
type ForceEndpoint int
type ForceRecord map[string]interface{}
type ForceSobject map[string]interface{}
type ForceCreateRecordResult struct {
Errors []string
Id string
Success bool
}
type ForceLimits map[string]ForceLimit
type ForceLimit struct {
Name string
Remaining int64
Max int64
}
type ForcePasswordStatusResult struct {
IsExpired bool
}
type ForcePasswordResetResult struct {
NewPassword string
}
type ForceQueryResult struct {
Done bool
Records []ForceRecord
TotalSize int
NextRecordsUrl string
}
type ForceSobjectsResult struct {
Encoding string
MaxBatchSize int
Sobjects []ForceSobject
}
type Result struct {
Id string
Success bool
Created bool
Message string
}
type BatchResult struct {
Results []Result
}
type BatchInfo struct {
Id string `xml:"id"`
JobId string `xml:"jobId"`
State string `xml:"state"`
CreatedDate string `xml:"createdDate"`
SystemModstamp string `xml:"systemModstamp"`
NumberRecordsProcessed int `xml:"numberRecordsProcessed"`
}
type JobInfo struct {
Id string `xml:"id"`
Operation string `xml:"operation"`
Object string `xml:"object"`
CreatedById string `xml:"createdById"`
CreatedDate string `xml:"createdDate"`
SystemModStamp string `xml:"systemModstamp"`
State string `xml:"state"`
ContentType string `xml:"contentType"`
ConcurrencyMode string `xml:"concurrencyMode"`
NumberBatchesQueued int `xml:"numberBatchesQueued"`
NumberBatchesInProgress int `xml:"numberBatchesInProgress"`
NumberBatchesCompleted int `xml:"numberBatchesCompleted"`
NumberBatchesFailed int `xml:"numberBatchesFailed"`
NumberBatchesTotal int `xml:"numberBatchesTotal"`
NumberRecordsProcessed int `xml:"numberRecordsProcessed"`
NumberRetries int `xml:"numberRetries"`
ApiVersion string `xml:"apiVersion"`
NumberRecordsFailed int `xml:"numberRecordsFailed"`
TotalProcessingTime int `xml:"totalProcessingTime"`
ApiActiveProcessingTime int `xml:"apiActiveProcessingTime"`
ApexProcessingTime int `xml:"apexProcessingTime"`
}
type AuraDefinitionBundleResult struct {
Done bool
Records []ForceRecord
TotalSize int
QueryLocator string
Size int
EntityTypeName string
NextRecordsUrl string
}
type AuraDefinitionBundle struct {
Id string
IsDeleted bool
DeveloperName string
Language string
MasterLabel string
NamespacePrefix string
CreatedDate string
CreatedById string
LastModifiedDate string
LastModifiedById string
SystemModstamp string
ApiVersion int
Description string
}
type AuraDefinition struct {
Id string
IsDeleted bool
CreatedDate string
CreatedById string
LastModifiedDate string
LastModifiedById string
SystemModstamp string
AuraDefinitionBundleId string
DefType string
Format string
Source string
}
type ComponentFile struct {
FileName string
ComponentId string
}
type BundleManifest struct {
Name string
Id string
Files []ComponentFile
}
func NewForce(creds ForceCredentials) (force *Force) {
force = new(Force)
force.Credentials = creds
force.Metadata = NewForceMetadata(force)
force.Partner = NewForcePartner(force)
return
}
func ForceSoapLogin(endpoint ForceEndpoint, username string, password string) (creds ForceCredentials, err error) {
var surl string
version := strings.Split(apiVersion, "v")[1]
switch endpoint {
case EndpointProduction:
surl = fmt.Sprintf("https://login.salesforce.com/services/Soap/u/%s", version)
case EndpointTest:
surl = fmt.Sprintf("https://test.salesforce.com/services/Soap/u/%s", version)
case EndpointPrerelease:
surl = fmt.Sprintf("https://prerelna1.pre.salesforce.com/services/Soap/u/%s", version)
case EndpointCustom:
surl = fmt.Sprintf("%s/services/Soap/u/%s", CustomEndpoint, version)
default:
ErrorAndExit("no such endpoint type")
}
soap := NewSoap(surl, "", "")
response, err := soap.ExecuteLogin(username, password)
var result struct {
SessionId string `xml:"Body>loginResponse>result>sessionId"`
Id string `xml:"Body>loginResponse>result>userId"`
Instance_url string `xml:"Body>loginResponse>result>serverUrl"`
}
var fault SoapFault
if err = xml.Unmarshal(response, &fault); fault.Detail.ExceptionMessage != "" {
ErrorAndExit(fault.Detail.ExceptionCode + ": " + fault.Detail.ExceptionMessage)
}
if err = xml.Unmarshal(response, &result); err != nil {
return
}
orgid := strings.Split(result.SessionId, "!")[0]
u, err := url.Parse(result.Instance_url)
if err != nil {
return
}
instanceUrl := u.Scheme + "://" + u.Host
identity := u.Scheme + "://" + u.Host + "/id/" + orgid + "/" + result.Id
creds = ForceCredentials{result.SessionId, identity, result.Id, instanceUrl, "", "", endpoint == EndpointCustom, "", endpoint}
f := NewForce(creds)
url := fmt.Sprintf("https://force-cli.herokuapp.com/auth/soaplogin/?id=%s&access_token=%s&instance_url=%s", creds.Id, creds.AccessToken, creds.InstanceUrl)
body, err := f.httpGet(url)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println("Save login was ", string(body))
return
}
func ForceLogin(endpoint ForceEndpoint) (creds ForceCredentials, err error) {
ch := make(chan ForceCredentials)
port, err := startLocalHttpServer(ch)
var url string
switch endpoint {
case EndpointProduction:
url = fmt.Sprintf("https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id=%s&redirect_uri=%s&state=%d&prompt=login", ProductionClientId, RedirectUri, port)
case EndpointTest:
url = fmt.Sprintf("https://test.salesforce.com/services/oauth2/authorize?response_type=token&client_id=%s&redirect_uri=%s&state=%d&prompt=login", ProductionClientId, RedirectUri, port)
case EndpointPrerelease:
url = fmt.Sprintf("https://prerellogin.pre.salesforce.com/services/oauth2/authorize?response_type=token&client_id=%s&redirect_uri=%s&state=%d&prompt=login", PrereleaseClientId, RedirectUri, port)
case EndpointMobile1:
url = fmt.Sprintf("https://EndpointMobile1.t.salesforce.com/services/oauth2/authorize?response_type=token&client_id=%s&redirect_uri=%s&state=%d&prompt=login", Mobile1ClientId, RedirectUri, port)
default:
ErrorAndExit("no such endpoint type")
}
err = Open(url)
creds = <-ch
creds.ForceEndpoint = endpoint
return
}
func (f *Force) GetCodeCoverage(classId string, className string) (err error) {
url := fmt.Sprintf("%s/services/data/%s/query/?q=Select+Id+From+ApexClass+Where+Name+=+'%s'", f.Credentials.InstanceUrl, apiVersion, className)
body, err := f.httpGet(url)
if err != nil {
return
}
var result ForceQueryResult
json.Unmarshal(body, &result)
classId = result.Records[0]["Id"].(string)
url = fmt.Sprintf("%s/services/data/%s/tooling/query/?q=Select+Coverage,+NumLinesCovered,+NumLinesUncovered,+ApexTestClassId,+ApexClassorTriggerId+From+ApexCodeCoverage+Where+ApexClassorTriggerId='%s'", f.Credentials.InstanceUrl, apiVersion, classId)
body, err = f.httpGet(url)
if err != nil {
return
}
//var result ForceSobjectsResult
json.Unmarshal(body, &result)
fmt.Printf("\n%d lines covered\n%d lines not covered\n", int(result.Records[0]["NumLinesCovered"].(float64)), int(result.Records[0]["NumLinesUncovered"].(float64)))
return
}
func (f *Force) DeleteDataPipeline(id string) (err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/DataPipeline/%s", f.Credentials.InstanceUrl, apiVersion, id)
_, err = f.httpDelete(url)
return
}
func (f *Force) UpdateDataPipeline(id string, masterLabel string, scriptContent string) (err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/DataPipeline/%s", f.Credentials.InstanceUrl, apiVersion, id)
attrs := make(map[string]string)
attrs["MasterLabel"] = masterLabel
attrs["ScriptContent"] = scriptContent
_, err = f.httpPatch(url, attrs)
return
}
func (f *Force) CreateDataPipeline(name string, masterLabel string, apiVersionNumber string, scriptContent string, scriptType string) (result ForceCreateRecordResult, err error, emessages []ForceError) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/DataPipeline", f.Credentials.InstanceUrl, apiVersion)
attrs := make(map[string]string)
attrs["DeveloperName"] = name
attrs["ScriptType"] = scriptType
attrs["MasterLabel"] = masterLabel
attrs["ApiVersion"] = apiVersionNumber
attrs["ScriptContent"] = scriptContent
body, err, emessages := f.httpPost(aurl, attrs)
if err != nil {
return
}
json.Unmarshal(body, &result)
return
}
func (f *Force) CreateDataPipelineJob(id string) (result ForceCreateRecordResult, err error, emessages []ForceError) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/DataPipelineJob", f.Credentials.InstanceUrl, apiVersion)
attrs := make(map[string]string)
attrs["DataPipelineId"] = id
body, err, emessages := f.httpPost(aurl, attrs)
if err != nil {
return
}
json.Unmarshal(body, &result)
return
}
func (f *Force) GetDataPipeline(name string) (results ForceQueryResult, err error) {
query := fmt.Sprintf("SELECT Id, MasterLabel, DeveloperName, ScriptContent, ScriptType FROM DataPipeline Where DeveloperName = '%s'", name)
results, err = f.QueryDataPipeline(query)
return
}
func (f *Force) QueryDataPipeline(soql string) (results ForceQueryResult, err error) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape(soql))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &results)
return
}
func (f *Force) QueryDataPipelineJob(soql string) (results ForceQueryResult, err error) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape(soql))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &results)
return
}
func (f *Force) GetAuraBundles() (bundles AuraDefinitionBundleResult, definitions AuraDefinitionBundleResult, err error) {
bundles, err = f.GetAuraBundlesList()
definitions, err = f.GetAuraBundleDefinitions()
return
}
func (f *Force) GetAuraBundleDefinitions() (definitions AuraDefinitionBundleResult, err error) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape("SELECT Id, Source, AuraDefinitionBundleId, DefType, Format FROM AuraDefinition"))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &definitions)
if !definitions.Done {
f.GetMoreAuraBundleDefinitions(&definitions)
}
return
}
func (f *Force) GetMoreAuraBundleDefinitions(definitions *AuraDefinitionBundleResult) (err error) {
isDone := definitions.Done
nextRecordsUrl := definitions.NextRecordsUrl
for !isDone {
moreDefs := new(AuraDefinitionBundleResult)
aurl := fmt.Sprintf("%s%s", f.Credentials.InstanceUrl, nextRecordsUrl)
body, err := f.httpGet(aurl)
if err != nil {
return err
}
json.Unmarshal(body, &moreDefs)
definitions.Done = moreDefs.Done
definitions.Records = append(definitions.Records, moreDefs.Records...)
isDone = moreDefs.Done
if !isDone {
nextRecordsUrl = moreDefs.NextRecordsUrl
}
}
return
}
func (f *Force) GetAuraBundlesList() (bundles AuraDefinitionBundleResult, err error) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape("SELECT Id, DeveloperName, NamespacePrefix, ApiVersion, Description FROM AuraDefinitionBundle"))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &bundles)
return
}
func (f *Force) GetAuraBundle(bundleName string) (bundles AuraDefinitionBundleResult, definitions AuraDefinitionBundleResult, err error) {
bundles, err = f.GetAuraBundleByName(bundleName)
if len(bundles.Records) == 0 {
ErrorAndExit(fmt.Sprintf("There is no Aura bundle named %q", bundleName))
}
bundle := bundles.Records[0]
definitions, err = f.GetAuraBundleDefinition(bundle["Id"].(string))
return
}
func (f *Force) GetAuraBundleByName(bundleName string) (bundles AuraDefinitionBundleResult, err error) {
criteria := fmt.Sprintf(" Where DeveloperName = '%s'", bundleName)
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape(fmt.Sprintf("SELECT Id, DeveloperName, NamespacePrefix, ApiVersion, Description FROM AuraDefinitionBundle%s", criteria)))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &bundles)
return
}
func (f *Force) GetAuraBundleDefinition(id string) (definitions AuraDefinitionBundleResult, err error) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion,
url.QueryEscape(fmt.Sprintf("SELECT Id, Source, AuraDefinitionBundleId, DefType, Format FROM AuraDefinition WHERE AuraDefinitionBundleId = '%s'", id)))
body, err := f.httpGet(aurl)
if err != nil {
return
}
json.Unmarshal(body, &definitions)
return
}
func (f *Force) CreateAuraBundle(bundleName string) (result ForceCreateRecordResult, err error, emessages []ForceError) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/AuraDefinitionBundle", f.Credentials.InstanceUrl, apiVersion)
attrs := make(map[string]string)
attrs["DeveloperName"] = bundleName
attrs["Description"] = "An Aura Bundle"
attrs["MasterLabel"] = bundleName
attrs["ApiVersion"] = apiVersionNumber
body, err, emessages := f.httpPost(aurl, attrs)
if err != nil {
return
}
json.Unmarshal(body, &result)
return
}
func (f *Force) CreateAuraComponent(attrs map[string]string) (result ForceCreateRecordResult, err error, emessages []ForceError) {
aurl := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/AuraDefinition", f.Credentials.InstanceUrl, apiVersion)
body, err, emessages := f.httpPost(aurl, attrs)
if err != nil {
return
}
json.Unmarshal(body, &result)
return
}
func (f *Force) ListSobjects() (sobjects []ForceSobject, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects", f.Credentials.InstanceUrl, apiVersion)
body, err := f.httpGet(url)
if err != nil {
return
}
var result ForceSobjectsResult
json.Unmarshal(body, &result)
sobjects = result.Sobjects
return
}
func (f *Force) GetSobject(name string) (sobject ForceSobject, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/%s/describe", f.Credentials.InstanceUrl, apiVersion, name)
body, err := f.httpGet(url)
if err != nil {
return
}
json.Unmarshal(body, &sobject)
return
}
func (f *Force) Query(query string, isTooling bool) (result ForceQueryResult, err error) {
vurl := ""
if isTooling == true {
vurl = fmt.Sprintf("%s/services/data/%s/tooling/query?q=%s", f.Credentials.InstanceUrl, apiVersion, url.QueryEscape(query))
} else {
vurl = fmt.Sprintf("%s/services/data/%s/query?q=%s", f.Credentials.InstanceUrl, apiVersion, url.QueryEscape(query))
}
body, err := f.httpGet(vurl)
if err != nil {
return
}
json.Unmarshal(body, &result)
if result.Done == false {
var nextResult ForceQueryResult
nextResult.NextRecordsUrl = result.NextRecordsUrl
for nextResult.Done == false {
nextUrl := fmt.Sprintf("%s%s", f.Credentials.InstanceUrl, nextResult.NextRecordsUrl)
nextBody, nextErr := f.httpGet(nextUrl)
if nextErr != nil {
return
}
nextResult.Records = []ForceRecord{}
json.Unmarshal(nextBody, &nextResult)
result.Records = append(result.Records, nextResult.Records...)
}
}
return
}
func (f *Force) Get(url string) (object ForceRecord, err error) {
body, err := f.httpGet(url)
if err != nil {
return
}
err = json.Unmarshal(body, &object)
return
}
func (f *Force) GetLimits() (result map[string]ForceLimit, err error) {
url := fmt.Sprintf("%s/services/data/%s/limits", f.Credentials.InstanceUrl, apiVersion)
body, err := f.httpGet(url)
if err != nil {
return
}
err = json.Unmarshal([]byte(body), &result)
return
}
func (f *Force) GetPasswordStatus(id string) (result ForcePasswordStatusResult, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/User/%s/password", f.Credentials.InstanceUrl, apiVersion, id)
body, err := f.httpGet(url)
if err != nil {
return
}
err = json.Unmarshal(body, &result)
return
}
func (f *Force) ResetPassword(id string) (result ForcePasswordResetResult, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/User/%s/password", f.Credentials.InstanceUrl, apiVersion, id)
body, err := f.httpDelete(url)
if err != nil {
return
}
err = json.Unmarshal(body, &result)
return
}
func (f *Force) ChangePassword(id string, attrs map[string]string) (result string, err error, emessages []ForceError) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/User/%s/password", f.Credentials.InstanceUrl, apiVersion, id)
_, err, emessages = f.httpPost(url, attrs)
return
}
func (f *Force) GetRecord(sobject, id string) (object ForceRecord, err error) {
fields := strings.Split(id, ":")
var url string
if len(fields) == 1 {
url = fmt.Sprintf("%s/services/data/%s/sobjects/%s/%s", f.Credentials.InstanceUrl, apiVersion, sobject, id)
} else {
url = fmt.Sprintf("%s/services/data/%s/sobjects/%s/%s/%s", f.Credentials.InstanceUrl, apiVersion, sobject, fields[0], fields[1])
}
body, err := f.httpGet(url)
if err != nil {
return
}
err = json.Unmarshal(body, &object)
return
}
func (f *Force) CreateRecord(sobject string, attrs map[string]string) (id string, err error, emessages []ForceError) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/%s", f.Credentials.InstanceUrl, apiVersion, sobject)
body, err, emessages := f.httpPost(url, attrs)
var result ForceCreateRecordResult
json.Unmarshal(body, &result)
id = result.Id
return
}
func (f *Force) CreateBulkJob(xmlbody string) (result JobInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job", f.Credentials.InstanceUrl, apiVersionNumber)
body, err := f.httpPostXML(url, xmlbody)
xml.Unmarshal(body, &result)
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) CloseBulkJob(jobId string, xmlbody string) (result JobInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s", f.Credentials.InstanceUrl, apiVersionNumber, jobId)
body, err := f.httpPostXML(url, xmlbody)
xml.Unmarshal(body, &result)
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) GetBulkJobs() (result []JobInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/jobs", f.Credentials.InstanceUrl, apiVersionNumber)
body, err := f.httpGetBulk(url)
xml.Unmarshal(body, &result)
if len(result[0].Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) BulkQuery(soql string, jobId string, contettype string) (result BatchInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch", f.Credentials.InstanceUrl, apiVersionNumber, jobId)
var body []byte
if contettype == "CSV" {
body, err = f.httpPostCSV(url, soql)
xml.Unmarshal(body, &result)
} else {
body, err = f.httpPostXML(url, soql)
xml.Unmarshal(body, &result)
}
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) AddBatchToJob(xmlbody string, jobId string) (result BatchInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch", f.Credentials.InstanceUrl, apiVersionNumber, jobId)
body, err := f.httpPostCSV(url, xmlbody)
xml.Unmarshal(body, &result)
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) GetBatchInfo(jobId string, batchId string) (result BatchInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch/%s", f.Credentials.InstanceUrl, apiVersionNumber, jobId, batchId)
body, err := f.httpGetBulk(url)
xml.Unmarshal(body, &result)
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) GetBatches(jobId string) (result []BatchInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch", f.Credentials.InstanceUrl, apiVersionNumber, jobId)
body, err := f.httpGetBulk(url)
var batchInfoList struct {
BatchInfos []BatchInfo `xml:"batchInfo"`
}
xml.Unmarshal(body, &batchInfoList)
result = batchInfoList.BatchInfos
if len(result) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) GetJobInfo(jobId string) (result JobInfo, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s", f.Credentials.InstanceUrl, apiVersionNumber, jobId)
body, err := f.httpGetBulk(url)
xml.Unmarshal(body, &result)
if len(result.Id) == 0 {
var fault LoginFault
xml.Unmarshal(body, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
return
}
func (f *Force) RetrieveBulkQuery(jobId string, batchId string) (result []byte, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch/%s/result", f.Credentials.InstanceUrl, apiVersionNumber, jobId, batchId)
result, err = f.httpGetBulk(url)
return
}
func (f *Force) RetrieveBulkQueryResults(jobId string, batchId string, resultId string) (result []byte, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch/%s/result/%s", f.Credentials.InstanceUrl, apiVersionNumber, jobId, batchId, resultId)
result, err = f.httpGetBulk(url)
return
}
func (f *Force) RetrieveBulkBatchResults(jobId string, batchId string) (results BatchResult, err error) {
url := fmt.Sprintf("%s/services/async/%s/job/%s/batch/%s/result", f.Credentials.InstanceUrl, apiVersionNumber, jobId, batchId)
result, err := f.httpGetBulk(url)
if len(result) == 0 {
var fault LoginFault
xml.Unmarshal(result, &fault)
err = errors.New(fmt.Sprintf("%s: %s", fault.ExceptionCode, fault.ExceptionMessage))
}
// sreader = Reader.NewReader(result);
return
}
func (f *Force) QueryTraceFlags() (results ForceQueryResult, err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/query/?q=Select+Id,+ApexCode,+ApexProfiling,+Callout,+CreatedDate,+Database,+ExpirationDate,+Scope.Name,+System,+TracedEntity.Name,+Validation,+Visualforce,+Workflow+From+TraceFlag+Order+By+ExpirationDate,TracedEntity.Name,Scope.Name", f.Credentials.InstanceUrl, apiVersion)
body, err := f.httpGet(url)
if err != nil {
return
}
json.Unmarshal(body, &results)
return
}
func (f *Force) StartTrace() (result ForceCreateRecordResult, err error, emessages []ForceError) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/TraceFlag", f.Credentials.InstanceUrl, apiVersion)
// The log levels are currently hard-coded to a useful level of logging
// without hitting the maximum log size of 2MB in most cases, hopefully.
attrs := make(map[string]string)
attrs["ApexCode"] = "Debug"
attrs["ApexProfiling"] = "Error"
attrs["Callout"] = "Info"
attrs["Database"] = "Info"
attrs["System"] = "Info"
attrs["Validation"] = "Warn"
attrs["Visualforce"] = "Info"
attrs["Workflow"] = "Info"
attrs["TracedEntityId"] = f.Credentials.UserId
body, err, emessages := f.httpPost(url, attrs)
if err != nil {
return
}
json.Unmarshal(body, &result)
return
}
func (f *Force) RetrieveLog(logId string) (result string, err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/ApexLog/%s/Body", f.Credentials.InstanceUrl, apiVersion, logId)
body, err := f.httpGet(url)
result = string(body)
return
}
func (f *Force) QueryLogs() (results ForceQueryResult, err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/query/?q=Select+Id,+Application,+DurationMilliseconds,+Location,+LogLength,+LogUser.Name,+Operation,+Request,StartTime,+Status+From+ApexLog+Order+By+StartTime", f.Credentials.InstanceUrl, apiVersion)
body, err := f.httpGet(url)
if err != nil {
return
}
json.Unmarshal(body, &results)
return
}
func (f *Force) RetrieveEventLogFile(elfId string) (result string, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/EventLogFile/%s/LogFile", f.Credentials.InstanceUrl, apiVersion, elfId)
body, err := f.httpGet(url)
if err != nil {
return
}
result = string(body)
return
}
func (f *Force) QueryEventLogFiles() (results ForceQueryResult, err error) {
url := fmt.Sprintf("%s/services/data/%s/query/?q=Select+Id,+LogDate,+EventType,+LogFileLength+FROM+EventLogFile+ORDER+BY+LogDate+DESC,+EventType", f.Credentials.InstanceUrl, apiVersion)
body, err := f.httpGet(url)
if err != nil {
return
}
json.Unmarshal(body, &results)
return
}
func (f *Force) UpdateAuraComponent(source map[string]string, id string) (err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/AuraDefinition/%s", f.Credentials.InstanceUrl, apiVersion, id)
_, err = f.httpPatch(url, source)
return
}
func (f *Force) DeleteToolingRecord(objecttype string, id string) (err error) {
url := fmt.Sprintf("%s/services/data/%s/tooling/sobjects/%s/%s", f.Credentials.InstanceUrl, apiVersion, objecttype, id)
_, err = f.httpDelete(url)
return
}
func (f *Force) DescribeSObject(objecttype string) (result string, err error) {
url := fmt.Sprintf("%s/services/data/%s/sobjects/%s/describe", f.Credentials.InstanceUrl, apiVersion, objecttype)
body, err := f.httpGet(url)
if err != nil {
return
}
result = string(body)
return
}