chub-dev 0.1.0 → 0.1.2-beta.0
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.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1241 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crm
|
|
3
|
+
description: "Salesforce JavaScript SDK (JSforce) coding guidelines for Salesforce API interactions"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "3.10.8"
|
|
7
|
+
updated-on: "2026-03-02"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "salesforce,crm,soql,enterprise,api"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Salesforce JavaScript SDK (JSforce) Coding Guidelines
|
|
13
|
+
|
|
14
|
+
You are a Salesforce API coding expert. Help me with writing code using the Salesforce API calling the official libraries and SDKs.
|
|
15
|
+
|
|
16
|
+
You can find the official SDK documentation and code samples here:
|
|
17
|
+
https://jsforce.github.io/
|
|
18
|
+
|
|
19
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
20
|
+
|
|
21
|
+
Always use JSforce to interact with Salesforce APIs. JSforce is the standard JavaScript library for all Salesforce API interactions, supporting both Node.js and browser environments.
|
|
22
|
+
|
|
23
|
+
- **Library Name:** JSforce
|
|
24
|
+
- **NPM Package:** `jsforce`
|
|
25
|
+
- **Alternative Package:** `@jsforce/jsforce-node` (Node.js only, smaller bundle)
|
|
26
|
+
- **Legacy Libraries**: Do not use deprecated or unofficial Salesforce JavaScript packages
|
|
27
|
+
|
|
28
|
+
**Installation:**
|
|
29
|
+
|
|
30
|
+
- **Correct:** `npm install jsforce`
|
|
31
|
+
- **Node.js only:** `npm install @jsforce/jsforce-node`
|
|
32
|
+
|
|
33
|
+
**APIs and Usage:**
|
|
34
|
+
|
|
35
|
+
- **Correct:** `const jsforce = require('jsforce')`
|
|
36
|
+
- **Correct:** `const conn = new jsforce.Connection()`
|
|
37
|
+
- **Correct:** `await conn.query(...)`
|
|
38
|
+
- **Correct:** `await conn.sobject('Account').create(...)`
|
|
39
|
+
- **Incorrect:** Using unofficial Salesforce client libraries
|
|
40
|
+
- **Incorrect:** Direct REST API calls without SDK
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Install JSforce via npm:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install jsforce
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For Node.js-only projects (smaller bundle):
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install @jsforce/jsforce-node
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For browser usage via CDN:
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<script src="https://cdn.jsdelivr.net/npm/jsforce@3.2.2/dist/jsforce.min.js"></script>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Environment Variables
|
|
63
|
+
|
|
64
|
+
Set up your Salesforce credentials using environment variables:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
export SALESFORCE_USERNAME="user@example.org"
|
|
68
|
+
export SALESFORCE_PASSWORD="your_password"
|
|
69
|
+
export SALESFORCE_SECURITY_TOKEN="your_security_token"
|
|
70
|
+
export SALESFORCE_LOGIN_URL="https://login.salesforce.com" # or https://test.salesforce.com for sandbox
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Or create a `.env` file:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
SALESFORCE_USERNAME=user@example.org
|
|
77
|
+
SALESFORCE_PASSWORD=your_password
|
|
78
|
+
SALESFORCE_SECURITY_TOKEN=your_security_token
|
|
79
|
+
SALESFORCE_LOGIN_URL=https://login.salesforce.com
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Initialization
|
|
83
|
+
|
|
84
|
+
JSforce requires creating a `Connection` instance for all API calls.
|
|
85
|
+
|
|
86
|
+
### Basic Connection
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const jsforce = require('jsforce');
|
|
90
|
+
|
|
91
|
+
// Create connection
|
|
92
|
+
const conn = new jsforce.Connection();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Connection with Login URL
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
const jsforce = require('jsforce');
|
|
99
|
+
|
|
100
|
+
// Connect to sandbox
|
|
101
|
+
const conn = new jsforce.Connection({
|
|
102
|
+
loginUrl: 'https://test.salesforce.com'
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Connection with Session ID (OAuth)
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const jsforce = require('jsforce');
|
|
110
|
+
|
|
111
|
+
const conn = new jsforce.Connection({
|
|
112
|
+
instanceUrl: 'https://na1.salesforce.com',
|
|
113
|
+
accessToken: 'your_access_token'
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Connection with Session ID and Server URL
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
const jsforce = require('jsforce');
|
|
121
|
+
|
|
122
|
+
const conn = new jsforce.Connection({
|
|
123
|
+
serverUrl: 'https://na1.salesforce.com',
|
|
124
|
+
sessionId: 'your_session_id'
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Authentication
|
|
129
|
+
|
|
130
|
+
### Username/Password Login
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
const jsforce = require('jsforce');
|
|
134
|
+
const conn = new jsforce.Connection();
|
|
135
|
+
|
|
136
|
+
async function login() {
|
|
137
|
+
try {
|
|
138
|
+
const userInfo = await conn.login(
|
|
139
|
+
process.env.SALESFORCE_USERNAME,
|
|
140
|
+
process.env.SALESFORCE_PASSWORD + process.env.SALESFORCE_SECURITY_TOKEN
|
|
141
|
+
);
|
|
142
|
+
console.log('User ID:', userInfo.id);
|
|
143
|
+
console.log('Org ID:', userInfo.organizationId);
|
|
144
|
+
console.log('Access Token:', conn.accessToken);
|
|
145
|
+
console.log('Instance URL:', conn.instanceUrl);
|
|
146
|
+
} catch (err) {
|
|
147
|
+
console.error('Login error:', err);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
login();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### OAuth 2.0 Username-Password Flow
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const jsforce = require('jsforce');
|
|
158
|
+
|
|
159
|
+
async function oauth2Login() {
|
|
160
|
+
const conn = new jsforce.Connection({
|
|
161
|
+
oauth2: {
|
|
162
|
+
loginUrl: 'https://login.salesforce.com',
|
|
163
|
+
clientId: 'your_client_id',
|
|
164
|
+
clientSecret: 'your_client_secret',
|
|
165
|
+
redirectUri: 'http://localhost:3000/oauth/callback'
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
const userInfo = await conn.login(
|
|
171
|
+
process.env.SALESFORCE_USERNAME,
|
|
172
|
+
process.env.SALESFORCE_PASSWORD
|
|
173
|
+
);
|
|
174
|
+
console.log('Access Token:', conn.accessToken);
|
|
175
|
+
console.log('Refresh Token:', conn.refreshToken);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error('OAuth login error:', err);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
oauth2Login();
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### OAuth 2.0 Authorization Code Flow
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
const jsforce = require('jsforce');
|
|
188
|
+
const express = require('express');
|
|
189
|
+
|
|
190
|
+
const oauth2 = new jsforce.OAuth2({
|
|
191
|
+
loginUrl: 'https://login.salesforce.com',
|
|
192
|
+
clientId: 'your_client_id',
|
|
193
|
+
clientSecret: 'your_client_secret',
|
|
194
|
+
redirectUri: 'http://localhost:3000/oauth/callback'
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const app = express();
|
|
198
|
+
|
|
199
|
+
app.get('/oauth', (req, res) => {
|
|
200
|
+
res.redirect(oauth2.getAuthorizationUrl({ scope: 'api id web' }));
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
app.get('/oauth/callback', async (req, res) => {
|
|
204
|
+
const conn = new jsforce.Connection({ oauth2 });
|
|
205
|
+
const code = req.query.code;
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const userInfo = await conn.authorize(code);
|
|
209
|
+
console.log('Access Token:', conn.accessToken);
|
|
210
|
+
console.log('Refresh Token:', conn.refreshToken);
|
|
211
|
+
res.send('OAuth authentication successful!');
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.error('OAuth error:', err);
|
|
214
|
+
res.status(500).send('OAuth error');
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
app.listen(3000);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### OAuth 2.0 Client Credentials Flow
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
const jsforce = require('jsforce');
|
|
225
|
+
|
|
226
|
+
async function clientCredentialsFlow() {
|
|
227
|
+
const conn = new jsforce.Connection({
|
|
228
|
+
oauth2: {
|
|
229
|
+
loginUrl: 'https://login.salesforce.com',
|
|
230
|
+
clientId: 'your_client_id',
|
|
231
|
+
clientSecret: 'your_client_secret'
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
await conn.oauth2.authenticate({
|
|
237
|
+
grant_type: 'client_credentials'
|
|
238
|
+
});
|
|
239
|
+
console.log('Access Token:', conn.accessToken);
|
|
240
|
+
} catch (err) {
|
|
241
|
+
console.error('Client credentials error:', err);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
clientCredentialsFlow();
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### JWT Bearer Flow
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
const jsforce = require('jsforce');
|
|
252
|
+
const fs = require('fs');
|
|
253
|
+
|
|
254
|
+
const privateKey = fs.readFileSync('private.key', 'utf8');
|
|
255
|
+
|
|
256
|
+
async function jwtBearerFlow() {
|
|
257
|
+
const conn = new jsforce.Connection({
|
|
258
|
+
oauth2: {
|
|
259
|
+
loginUrl: 'https://login.salesforce.com',
|
|
260
|
+
clientId: 'your_client_id',
|
|
261
|
+
privateKey: privateKey
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
await conn.oauth2.authenticate({
|
|
267
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
268
|
+
assertion: conn.oauth2.createJwtBearerToken({
|
|
269
|
+
iss: 'your_client_id',
|
|
270
|
+
sub: 'user@example.org',
|
|
271
|
+
aud: 'https://login.salesforce.com'
|
|
272
|
+
})
|
|
273
|
+
});
|
|
274
|
+
console.log('Access Token:', conn.accessToken);
|
|
275
|
+
} catch (err) {
|
|
276
|
+
console.error('JWT Bearer flow error:', err);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
jwtBearerFlow();
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Browser OAuth Initialization
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
jsforce.browser.init({
|
|
287
|
+
clientId: 'your_oauth2_client_id',
|
|
288
|
+
redirectUri: 'https://yourapp.example.com/oauth/callback'
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
jsforce.browser.login();
|
|
292
|
+
|
|
293
|
+
jsforce.browser.on('connect', function(conn) {
|
|
294
|
+
console.log('Connected to Salesforce');
|
|
295
|
+
console.log('Access Token:', conn.accessToken);
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## SOQL Queries
|
|
300
|
+
|
|
301
|
+
### Basic Query
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
const jsforce = require('jsforce');
|
|
305
|
+
const conn = new jsforce.Connection();
|
|
306
|
+
|
|
307
|
+
async function basicQuery() {
|
|
308
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
309
|
+
|
|
310
|
+
const result = await conn.query('SELECT Id, Name FROM Account LIMIT 10');
|
|
311
|
+
|
|
312
|
+
console.log('Total records:', result.totalSize);
|
|
313
|
+
console.log('Records fetched:', result.records.length);
|
|
314
|
+
|
|
315
|
+
result.records.forEach(record => {
|
|
316
|
+
console.log('Account:', record.Name);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
basicQuery();
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Query with WHERE Clause
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
async function queryWithFilter() {
|
|
327
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
328
|
+
|
|
329
|
+
const result = await conn.query(
|
|
330
|
+
"SELECT Id, Name, Industry FROM Account WHERE Industry = 'Technology'"
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
console.log('Found', result.totalSize, 'Technology accounts');
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Query with Relationships
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
async function queryRelationships() {
|
|
341
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
342
|
+
|
|
343
|
+
// Parent to child relationship
|
|
344
|
+
const result = await conn.query(
|
|
345
|
+
'SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account LIMIT 5'
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
result.records.forEach(account => {
|
|
349
|
+
console.log('Account:', account.Name);
|
|
350
|
+
if (account.Contacts) {
|
|
351
|
+
account.Contacts.records.forEach(contact => {
|
|
352
|
+
console.log(' Contact:', contact.Name);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Query All Records (Including Deleted)
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
async function queryAll() {
|
|
363
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
364
|
+
|
|
365
|
+
const result = await conn.queryAll(
|
|
366
|
+
'SELECT Id, Name, IsDeleted FROM Account WHERE IsDeleted = true'
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
console.log('Deleted accounts:', result.totalSize);
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Query with Pagination
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
async function queryWithPagination() {
|
|
377
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
378
|
+
|
|
379
|
+
let result = await conn.query('SELECT Id, Name FROM Account');
|
|
380
|
+
let records = result.records;
|
|
381
|
+
|
|
382
|
+
while (!result.done) {
|
|
383
|
+
result = await conn.queryMore(result.nextRecordsUrl);
|
|
384
|
+
records = records.concat(result.records);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
console.log('Total records retrieved:', records.length);
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Query with Method Chaining
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
async function methodChainQuery() {
|
|
395
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
396
|
+
|
|
397
|
+
const records = await conn.sobject('Account')
|
|
398
|
+
.select('Id, Name, Industry')
|
|
399
|
+
.where({ Industry: 'Technology' })
|
|
400
|
+
.limit(10)
|
|
401
|
+
.execute();
|
|
402
|
+
|
|
403
|
+
console.log('Records:', records);
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Event-Driven Query
|
|
408
|
+
|
|
409
|
+
```javascript
|
|
410
|
+
async function eventDrivenQuery() {
|
|
411
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
412
|
+
|
|
413
|
+
conn.query('SELECT Id, Name FROM Account')
|
|
414
|
+
.on('record', record => {
|
|
415
|
+
console.log('Account:', record.Name);
|
|
416
|
+
})
|
|
417
|
+
.on('end', () => {
|
|
418
|
+
console.log('Query completed');
|
|
419
|
+
})
|
|
420
|
+
.on('error', err => {
|
|
421
|
+
console.error('Query error:', err);
|
|
422
|
+
})
|
|
423
|
+
.run();
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## SOSL Search
|
|
428
|
+
|
|
429
|
+
### Basic Search
|
|
430
|
+
|
|
431
|
+
```javascript
|
|
432
|
+
async function basicSearch() {
|
|
433
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
434
|
+
|
|
435
|
+
const result = await conn.search(
|
|
436
|
+
'FIND {United*} IN NAME FIELDS RETURNING Account(Id, Name), Contact(Id, Name)'
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
console.log('Search results:', result.searchRecords);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## CRUD Operations
|
|
444
|
+
|
|
445
|
+
### Create Single Record
|
|
446
|
+
|
|
447
|
+
```javascript
|
|
448
|
+
async function createRecord() {
|
|
449
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
450
|
+
|
|
451
|
+
const result = await conn.sobject('Account').create({
|
|
452
|
+
Name: 'New Account',
|
|
453
|
+
Industry: 'Technology',
|
|
454
|
+
BillingCity: 'San Francisco'
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
console.log('Created account ID:', result.id);
|
|
458
|
+
console.log('Success:', result.success);
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Create Multiple Records
|
|
463
|
+
|
|
464
|
+
```javascript
|
|
465
|
+
async function createMultipleRecords() {
|
|
466
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
467
|
+
|
|
468
|
+
const results = await conn.sobject('Account').create([
|
|
469
|
+
{ Name: 'Account 1', Industry: 'Technology' },
|
|
470
|
+
{ Name: 'Account 2', Industry: 'Finance' },
|
|
471
|
+
{ Name: 'Account 3', Industry: 'Healthcare' }
|
|
472
|
+
]);
|
|
473
|
+
|
|
474
|
+
results.forEach(result => {
|
|
475
|
+
if (result.success) {
|
|
476
|
+
console.log('Created account ID:', result.id);
|
|
477
|
+
} else {
|
|
478
|
+
console.error('Error:', result.errors);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Retrieve Single Record
|
|
485
|
+
|
|
486
|
+
```javascript
|
|
487
|
+
async function retrieveRecord() {
|
|
488
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
489
|
+
|
|
490
|
+
const account = await conn.sobject('Account').retrieve('001XXXXXXXXXXXXXXX');
|
|
491
|
+
|
|
492
|
+
console.log('Account Name:', account.Name);
|
|
493
|
+
console.log('Industry:', account.Industry);
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Retrieve Multiple Records
|
|
498
|
+
|
|
499
|
+
```javascript
|
|
500
|
+
async function retrieveMultipleRecords() {
|
|
501
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
502
|
+
|
|
503
|
+
const accounts = await conn.sobject('Account').retrieve([
|
|
504
|
+
'001XXXXXXXXXXXXXXX',
|
|
505
|
+
'001YYYYYYYYYYYYYYY'
|
|
506
|
+
]);
|
|
507
|
+
|
|
508
|
+
accounts.forEach(account => {
|
|
509
|
+
console.log('Account:', account.Name);
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Update Single Record
|
|
515
|
+
|
|
516
|
+
```javascript
|
|
517
|
+
async function updateRecord() {
|
|
518
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
519
|
+
|
|
520
|
+
const result = await conn.sobject('Account').update({
|
|
521
|
+
Id: '001XXXXXXXXXXXXXXX',
|
|
522
|
+
Name: 'Updated Account Name',
|
|
523
|
+
Industry: 'Media'
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
console.log('Updated:', result.success);
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Update Multiple Records
|
|
531
|
+
|
|
532
|
+
```javascript
|
|
533
|
+
async function updateMultipleRecords() {
|
|
534
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
535
|
+
|
|
536
|
+
const results = await conn.sobject('Account').update([
|
|
537
|
+
{ Id: '001XXXXXXXXXXXXXXX', Name: 'Updated Name 1' },
|
|
538
|
+
{ Id: '001YYYYYYYYYYYYYYY', Name: 'Updated Name 2' }
|
|
539
|
+
]);
|
|
540
|
+
|
|
541
|
+
results.forEach(result => {
|
|
542
|
+
if (result.success) {
|
|
543
|
+
console.log('Updated account ID:', result.id);
|
|
544
|
+
} else {
|
|
545
|
+
console.error('Error:', result.errors);
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Upsert Records
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
async function upsertRecords() {
|
|
555
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
556
|
+
|
|
557
|
+
const results = await conn.sobject('Account').upsert(
|
|
558
|
+
[
|
|
559
|
+
{ ExternalId__c: 'EXT001', Name: 'Account 1', Industry: 'Technology' },
|
|
560
|
+
{ ExternalId__c: 'EXT002', Name: 'Account 2', Industry: 'Finance' }
|
|
561
|
+
],
|
|
562
|
+
'ExternalId__c'
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
results.forEach(result => {
|
|
566
|
+
if (result.success) {
|
|
567
|
+
console.log('Upserted account ID:', result.id);
|
|
568
|
+
console.log('Created:', result.created);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Delete Single Record
|
|
575
|
+
|
|
576
|
+
```javascript
|
|
577
|
+
async function deleteRecord() {
|
|
578
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
579
|
+
|
|
580
|
+
const result = await conn.sobject('Account').destroy('001XXXXXXXXXXXXXXX');
|
|
581
|
+
|
|
582
|
+
console.log('Deleted:', result.success);
|
|
583
|
+
}
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### Delete Multiple Records
|
|
587
|
+
|
|
588
|
+
```javascript
|
|
589
|
+
async function deleteMultipleRecords() {
|
|
590
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
591
|
+
|
|
592
|
+
const results = await conn.sobject('Account').destroy([
|
|
593
|
+
'001XXXXXXXXXXXXXXX',
|
|
594
|
+
'001YYYYYYYYYYYYYYY'
|
|
595
|
+
]);
|
|
596
|
+
|
|
597
|
+
results.forEach(result => {
|
|
598
|
+
if (result.success) {
|
|
599
|
+
console.log('Deleted account ID:', result.id);
|
|
600
|
+
} else {
|
|
601
|
+
console.error('Error:', result.errors);
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
## Bulk API
|
|
608
|
+
|
|
609
|
+
### Bulk Query
|
|
610
|
+
|
|
611
|
+
```javascript
|
|
612
|
+
async function bulkQuery() {
|
|
613
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
614
|
+
|
|
615
|
+
const records = [];
|
|
616
|
+
|
|
617
|
+
conn.bulk.query('SELECT Id, Name FROM Account')
|
|
618
|
+
.on('record', record => {
|
|
619
|
+
records.push(record);
|
|
620
|
+
})
|
|
621
|
+
.on('end', () => {
|
|
622
|
+
console.log('Total records:', records.length);
|
|
623
|
+
})
|
|
624
|
+
.on('error', err => {
|
|
625
|
+
console.error('Bulk query error:', err);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Bulk Insert
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
async function bulkInsert() {
|
|
634
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
635
|
+
|
|
636
|
+
const accounts = [];
|
|
637
|
+
for (let i = 0; i < 1000; i++) {
|
|
638
|
+
accounts.push({
|
|
639
|
+
Name: `Bulk Account ${i}`,
|
|
640
|
+
Industry: 'Technology'
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
conn.bulk.load('Account', 'insert', accounts, (err, results) => {
|
|
645
|
+
if (err) {
|
|
646
|
+
console.error('Bulk insert error:', err);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
results.forEach(result => {
|
|
651
|
+
if (result.success) {
|
|
652
|
+
console.log('Created ID:', result.id);
|
|
653
|
+
} else {
|
|
654
|
+
console.error('Error:', result.errors);
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Bulk Update
|
|
662
|
+
|
|
663
|
+
```javascript
|
|
664
|
+
async function bulkUpdate() {
|
|
665
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
666
|
+
|
|
667
|
+
const updates = [
|
|
668
|
+
{ Id: '001XXXXXXXXXXXXXXX', Industry: 'Finance' },
|
|
669
|
+
{ Id: '001YYYYYYYYYYYYYYY', Industry: 'Healthcare' }
|
|
670
|
+
];
|
|
671
|
+
|
|
672
|
+
conn.bulk.load('Account', 'update', updates, (err, results) => {
|
|
673
|
+
if (err) {
|
|
674
|
+
console.error('Bulk update error:', err);
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
console.log('Updated records:', results.length);
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Bulk Delete
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
async function bulkDelete() {
|
|
687
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
688
|
+
|
|
689
|
+
const idsToDelete = [
|
|
690
|
+
{ Id: '001XXXXXXXXXXXXXXX' },
|
|
691
|
+
{ Id: '001YYYYYYYYYYYYYYY' }
|
|
692
|
+
];
|
|
693
|
+
|
|
694
|
+
conn.bulk.load('Account', 'delete', idsToDelete, (err, results) => {
|
|
695
|
+
if (err) {
|
|
696
|
+
console.error('Bulk delete error:', err);
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
console.log('Deleted records:', results.length);
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### Bulk 2.0 Query
|
|
706
|
+
|
|
707
|
+
```javascript
|
|
708
|
+
async function bulk2Query() {
|
|
709
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
710
|
+
|
|
711
|
+
const recordStream = await conn.bulk2.query('SELECT Id, Name FROM Account');
|
|
712
|
+
|
|
713
|
+
recordStream.on('record', record => {
|
|
714
|
+
console.log('Record:', record);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
recordStream.on('end', () => {
|
|
718
|
+
console.log('Bulk 2.0 query completed');
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
recordStream.on('error', err => {
|
|
722
|
+
console.error('Bulk 2.0 query error:', err);
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
## SObject Metadata
|
|
728
|
+
|
|
729
|
+
### Describe SObject
|
|
730
|
+
|
|
731
|
+
```javascript
|
|
732
|
+
async function describeSObject() {
|
|
733
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
734
|
+
|
|
735
|
+
const metadata = await conn.sobject('Account').describe();
|
|
736
|
+
|
|
737
|
+
console.log('Label:', metadata.label);
|
|
738
|
+
console.log('Updateable:', metadata.updateable);
|
|
739
|
+
console.log('Fields:', metadata.fields.length);
|
|
740
|
+
|
|
741
|
+
metadata.fields.forEach(field => {
|
|
742
|
+
console.log(` ${field.name} (${field.type})`);
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
### Describe Global
|
|
748
|
+
|
|
749
|
+
```javascript
|
|
750
|
+
async function describeGlobal() {
|
|
751
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
752
|
+
|
|
753
|
+
const result = await conn.describeGlobal();
|
|
754
|
+
|
|
755
|
+
console.log('Available SObjects:');
|
|
756
|
+
result.sobjects.forEach(sobject => {
|
|
757
|
+
console.log(` ${sobject.name} - ${sobject.label}`);
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
### Describe Multiple SObjects
|
|
763
|
+
|
|
764
|
+
```javascript
|
|
765
|
+
async function describeMultiple() {
|
|
766
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
767
|
+
|
|
768
|
+
const result = await conn.describe(['Account', 'Contact', 'Opportunity']);
|
|
769
|
+
|
|
770
|
+
result.sobjects.forEach(sobject => {
|
|
771
|
+
console.log('SObject:', sobject.name);
|
|
772
|
+
console.log('Fields:', sobject.fields.length);
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
## Metadata API
|
|
778
|
+
|
|
779
|
+
### List Metadata Types
|
|
780
|
+
|
|
781
|
+
```javascript
|
|
782
|
+
async function listMetadataTypes() {
|
|
783
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
784
|
+
|
|
785
|
+
const result = await conn.metadata.describe();
|
|
786
|
+
|
|
787
|
+
console.log('API Version:', result.organizationNamespace);
|
|
788
|
+
result.metadataObjects.forEach(obj => {
|
|
789
|
+
console.log('Metadata Type:', obj.xmlName);
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### List Metadata
|
|
795
|
+
|
|
796
|
+
```javascript
|
|
797
|
+
async function listMetadata() {
|
|
798
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
799
|
+
|
|
800
|
+
const result = await conn.metadata.list([
|
|
801
|
+
{ type: 'CustomObject' },
|
|
802
|
+
{ type: 'ApexClass' }
|
|
803
|
+
]);
|
|
804
|
+
|
|
805
|
+
result.forEach(item => {
|
|
806
|
+
console.log('Full Name:', item.fullName);
|
|
807
|
+
console.log('Type:', item.type);
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### Read Metadata
|
|
813
|
+
|
|
814
|
+
```javascript
|
|
815
|
+
async function readMetadata() {
|
|
816
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
817
|
+
|
|
818
|
+
const result = await conn.metadata.read('CustomObject', ['Account', 'Contact']);
|
|
819
|
+
|
|
820
|
+
result.forEach(metadata => {
|
|
821
|
+
console.log('Object:', metadata.fullName);
|
|
822
|
+
console.log('Label:', metadata.label);
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Create Metadata
|
|
828
|
+
|
|
829
|
+
```javascript
|
|
830
|
+
async function createMetadata() {
|
|
831
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
832
|
+
|
|
833
|
+
const customField = {
|
|
834
|
+
fullName: 'Account.CustomField__c',
|
|
835
|
+
label: 'Custom Field',
|
|
836
|
+
type: 'Text',
|
|
837
|
+
length: 100
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
const result = await conn.metadata.create('CustomField', [customField]);
|
|
841
|
+
|
|
842
|
+
console.log('Created:', result[0].success);
|
|
843
|
+
}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### Update Metadata
|
|
847
|
+
|
|
848
|
+
```javascript
|
|
849
|
+
async function updateMetadata() {
|
|
850
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
851
|
+
|
|
852
|
+
const customField = {
|
|
853
|
+
fullName: 'Account.CustomField__c',
|
|
854
|
+
label: 'Updated Custom Field',
|
|
855
|
+
type: 'Text',
|
|
856
|
+
length: 255
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
const result = await conn.metadata.update('CustomField', [customField]);
|
|
860
|
+
|
|
861
|
+
console.log('Updated:', result[0].success);
|
|
862
|
+
}
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
### Delete Metadata
|
|
866
|
+
|
|
867
|
+
```javascript
|
|
868
|
+
async function deleteMetadata() {
|
|
869
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
870
|
+
|
|
871
|
+
const result = await conn.metadata.delete('CustomField', [
|
|
872
|
+
'Account.CustomField__c'
|
|
873
|
+
]);
|
|
874
|
+
|
|
875
|
+
console.log('Deleted:', result[0].success);
|
|
876
|
+
}
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
## Tooling API
|
|
880
|
+
|
|
881
|
+
### Query with Tooling API
|
|
882
|
+
|
|
883
|
+
```javascript
|
|
884
|
+
async function toolingQuery() {
|
|
885
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
886
|
+
|
|
887
|
+
const result = await conn.tooling.query(
|
|
888
|
+
'SELECT Id, Name FROM ApexClass WHERE Name LIKE \'Test%\''
|
|
889
|
+
);
|
|
890
|
+
|
|
891
|
+
result.records.forEach(record => {
|
|
892
|
+
console.log('Apex Class:', record.Name);
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
### Execute Anonymous Apex
|
|
898
|
+
|
|
899
|
+
```javascript
|
|
900
|
+
async function executeAnonymous() {
|
|
901
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
902
|
+
|
|
903
|
+
const apexCode = `
|
|
904
|
+
System.debug('Hello from anonymous Apex!');
|
|
905
|
+
Account acc = new Account(Name='Test Account');
|
|
906
|
+
insert acc;
|
|
907
|
+
`;
|
|
908
|
+
|
|
909
|
+
const result = await conn.tooling.executeAnonymous(apexCode);
|
|
910
|
+
|
|
911
|
+
console.log('Success:', result.success);
|
|
912
|
+
console.log('Compiled:', result.compiled);
|
|
913
|
+
console.log('Logs:', result.logs);
|
|
914
|
+
}
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
### Create Apex Class
|
|
918
|
+
|
|
919
|
+
```javascript
|
|
920
|
+
async function createApexClass() {
|
|
921
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
922
|
+
|
|
923
|
+
const result = await conn.tooling.sobject('ApexClass').create({
|
|
924
|
+
Name: 'MyApexClass',
|
|
925
|
+
Body: 'public class MyApexClass { public static void hello() { System.debug(\'Hello\'); } }'
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
console.log('Created Apex Class ID:', result.id);
|
|
929
|
+
}
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
## Analytics API
|
|
933
|
+
|
|
934
|
+
### List Reports
|
|
935
|
+
|
|
936
|
+
```javascript
|
|
937
|
+
async function listReports() {
|
|
938
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
939
|
+
|
|
940
|
+
const reports = await conn.analytics.reports();
|
|
941
|
+
|
|
942
|
+
reports.forEach(report => {
|
|
943
|
+
console.log('Report:', report.name);
|
|
944
|
+
console.log('ID:', report.id);
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
### Describe Report
|
|
950
|
+
|
|
951
|
+
```javascript
|
|
952
|
+
async function describeReport() {
|
|
953
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
954
|
+
|
|
955
|
+
const reportId = '00O1234567890ABCD';
|
|
956
|
+
const metadata = await conn.analytics.report(reportId).describe();
|
|
957
|
+
|
|
958
|
+
console.log('Report Metadata:', metadata.reportMetadata);
|
|
959
|
+
console.log('Report Type:', metadata.reportTypeMetadata);
|
|
960
|
+
}
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
### Execute Report
|
|
964
|
+
|
|
965
|
+
```javascript
|
|
966
|
+
async function executeReport() {
|
|
967
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
968
|
+
|
|
969
|
+
const reportId = '00O1234567890ABCD';
|
|
970
|
+
const result = await conn.analytics.report(reportId).execute();
|
|
971
|
+
|
|
972
|
+
console.log('Report Results:', result.factMap);
|
|
973
|
+
}
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### List Dashboards
|
|
977
|
+
|
|
978
|
+
```javascript
|
|
979
|
+
async function listDashboards() {
|
|
980
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
981
|
+
|
|
982
|
+
const dashboards = await conn.analytics.dashboards();
|
|
983
|
+
|
|
984
|
+
dashboards.forEach(dashboard => {
|
|
985
|
+
console.log('Dashboard:', dashboard.name);
|
|
986
|
+
console.log('ID:', dashboard.id);
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
## Chatter API
|
|
992
|
+
|
|
993
|
+
### Get User Info
|
|
994
|
+
|
|
995
|
+
```javascript
|
|
996
|
+
async function getUserInfo() {
|
|
997
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
998
|
+
|
|
999
|
+
const user = await conn.chatter.resource('/users/me').retrieve();
|
|
1000
|
+
|
|
1001
|
+
console.log('Username:', user.username);
|
|
1002
|
+
console.log('Email:', user.email);
|
|
1003
|
+
console.log('Display Name:', user.displayName);
|
|
1004
|
+
}
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
### Post to Feed
|
|
1008
|
+
|
|
1009
|
+
```javascript
|
|
1010
|
+
async function postToFeed() {
|
|
1011
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1012
|
+
|
|
1013
|
+
const result = await conn.chatter.resource('/feed-elements').create({
|
|
1014
|
+
body: {
|
|
1015
|
+
messageSegments: [
|
|
1016
|
+
{ type: 'Text', text: 'Hello from JSforce!' }
|
|
1017
|
+
]
|
|
1018
|
+
},
|
|
1019
|
+
feedElementType: 'FeedItem',
|
|
1020
|
+
subjectId: 'me'
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
console.log('Posted feed item ID:', result.id);
|
|
1024
|
+
}
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### Get Feed Items
|
|
1028
|
+
|
|
1029
|
+
```javascript
|
|
1030
|
+
async function getFeedItems() {
|
|
1031
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1032
|
+
|
|
1033
|
+
const result = await conn.chatter.resource('/feeds/news/me/feed-elements').retrieve();
|
|
1034
|
+
|
|
1035
|
+
result.elements.forEach(element => {
|
|
1036
|
+
console.log('Feed Item:', element.body.text);
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
## Streaming API
|
|
1042
|
+
|
|
1043
|
+
### Subscribe to PushTopic
|
|
1044
|
+
|
|
1045
|
+
```javascript
|
|
1046
|
+
async function subscribeToPushTopic() {
|
|
1047
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1048
|
+
|
|
1049
|
+
conn.streaming.topic('AllAccounts').subscribe((message) => {
|
|
1050
|
+
console.log('Event received:', message);
|
|
1051
|
+
console.log('Account ID:', message.sobject.Id);
|
|
1052
|
+
console.log('Account Name:', message.sobject.Name);
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
### Create PushTopic
|
|
1058
|
+
|
|
1059
|
+
```javascript
|
|
1060
|
+
async function createPushTopic() {
|
|
1061
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1062
|
+
|
|
1063
|
+
const result = await conn.sobject('PushTopic').create({
|
|
1064
|
+
Name: 'AllAccounts',
|
|
1065
|
+
Query: 'SELECT Id, Name FROM Account',
|
|
1066
|
+
ApiVersion: 58.0,
|
|
1067
|
+
NotifyForOperationCreate: true,
|
|
1068
|
+
NotifyForOperationUpdate: true,
|
|
1069
|
+
NotifyForOperationDelete: true,
|
|
1070
|
+
NotifyForFields: 'All'
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
console.log('PushTopic created:', result.id);
|
|
1074
|
+
}
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
### Platform Event Subscription
|
|
1078
|
+
|
|
1079
|
+
```javascript
|
|
1080
|
+
async function subscribeToEvent() {
|
|
1081
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1082
|
+
|
|
1083
|
+
conn.streaming.channel('/event/Custom_Event__e').subscribe((message) => {
|
|
1084
|
+
console.log('Platform Event received:', message);
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
### Change Data Capture
|
|
1090
|
+
|
|
1091
|
+
```javascript
|
|
1092
|
+
async function subscribeToChangeDataCapture() {
|
|
1093
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1094
|
+
|
|
1095
|
+
conn.streaming.channel('/data/AccountChangeEvent').subscribe((message) => {
|
|
1096
|
+
console.log('Change Event:', message);
|
|
1097
|
+
console.log('Change Type:', message.payload.ChangeEventHeader.changeType);
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
## Apex REST
|
|
1103
|
+
|
|
1104
|
+
### Call Custom Apex REST Endpoint
|
|
1105
|
+
|
|
1106
|
+
```javascript
|
|
1107
|
+
async function callApexRest() {
|
|
1108
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1109
|
+
|
|
1110
|
+
const result = await conn.apex.get('/MyApexRestService');
|
|
1111
|
+
|
|
1112
|
+
console.log('Response:', result);
|
|
1113
|
+
}
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
### POST to Apex REST
|
|
1117
|
+
|
|
1118
|
+
```javascript
|
|
1119
|
+
async function postToApexRest() {
|
|
1120
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1121
|
+
|
|
1122
|
+
const result = await conn.apex.post('/MyApexRestService', {
|
|
1123
|
+
name: 'Test',
|
|
1124
|
+
value: 123
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
console.log('Response:', result);
|
|
1128
|
+
}
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
### PUT to Apex REST
|
|
1132
|
+
|
|
1133
|
+
```javascript
|
|
1134
|
+
async function putToApexRest() {
|
|
1135
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1136
|
+
|
|
1137
|
+
const result = await conn.apex.put('/MyApexRestService/001XXXXXXXXXXXXXXX', {
|
|
1138
|
+
name: 'Updated Name'
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
console.log('Response:', result);
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
### DELETE to Apex REST
|
|
1146
|
+
|
|
1147
|
+
```javascript
|
|
1148
|
+
async function deleteToApexRest() {
|
|
1149
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1150
|
+
|
|
1151
|
+
const result = await conn.apex.del('/MyApexRestService/001XXXXXXXXXXXXXXX');
|
|
1152
|
+
|
|
1153
|
+
console.log('Response:', result);
|
|
1154
|
+
}
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
## Error Handling
|
|
1158
|
+
|
|
1159
|
+
### Basic Error Handling
|
|
1160
|
+
|
|
1161
|
+
```javascript
|
|
1162
|
+
const jsforce = require('jsforce');
|
|
1163
|
+
const conn = new jsforce.Connection();
|
|
1164
|
+
|
|
1165
|
+
async function handleErrors() {
|
|
1166
|
+
try {
|
|
1167
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1168
|
+
|
|
1169
|
+
const result = await conn.sobject('Account').create({
|
|
1170
|
+
Name: 'Test Account'
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
console.log('Success:', result.success);
|
|
1174
|
+
} catch (err) {
|
|
1175
|
+
console.error('Error Name:', err.name);
|
|
1176
|
+
console.error('Error Message:', err.message);
|
|
1177
|
+
console.error('Error Code:', err.errorCode);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
### CRUD Error Handling
|
|
1183
|
+
|
|
1184
|
+
```javascript
|
|
1185
|
+
async function handleCrudErrors() {
|
|
1186
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1187
|
+
|
|
1188
|
+
const results = await conn.sobject('Account').create([
|
|
1189
|
+
{ Name: 'Account 1' },
|
|
1190
|
+
{ Name: '' } // This will fail validation
|
|
1191
|
+
]);
|
|
1192
|
+
|
|
1193
|
+
results.forEach((result, index) => {
|
|
1194
|
+
if (result.success) {
|
|
1195
|
+
console.log(`Record ${index} created:`, result.id);
|
|
1196
|
+
} else {
|
|
1197
|
+
console.error(`Record ${index} failed:`, result.errors);
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
## Limits and Identity
|
|
1204
|
+
|
|
1205
|
+
### Get API Limits
|
|
1206
|
+
|
|
1207
|
+
```javascript
|
|
1208
|
+
async function getApiLimits() {
|
|
1209
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1210
|
+
|
|
1211
|
+
const limits = await conn.limits();
|
|
1212
|
+
|
|
1213
|
+
console.log('Daily API Requests:', limits.DailyApiRequests);
|
|
1214
|
+
console.log('Max:', limits.DailyApiRequests.Max);
|
|
1215
|
+
console.log('Remaining:', limits.DailyApiRequests.Remaining);
|
|
1216
|
+
}
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
### Get Identity Information
|
|
1220
|
+
|
|
1221
|
+
```javascript
|
|
1222
|
+
async function getIdentity() {
|
|
1223
|
+
await conn.login(process.env.SALESFORCE_USERNAME, process.env.SALESFORCE_PASSWORD);
|
|
1224
|
+
|
|
1225
|
+
const identity = await conn.identity();
|
|
1226
|
+
|
|
1227
|
+
console.log('User ID:', identity.user_id);
|
|
1228
|
+
console.log('Organization ID:', identity.organization_id);
|
|
1229
|
+
console.log('Username:', identity.username);
|
|
1230
|
+
console.log('Display Name:', identity.display_name);
|
|
1231
|
+
}
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
## Useful Links
|
|
1235
|
+
|
|
1236
|
+
- Documentation: https://jsforce.github.io/
|
|
1237
|
+
- Getting Started: https://jsforce.github.io/start/
|
|
1238
|
+
- API Reference: https://jsforce.github.io/document/
|
|
1239
|
+
- GitHub: https://github.com/jsforce/jsforce
|
|
1240
|
+
- Salesforce Developer Docs: https://developer.salesforce.com/
|
|
1241
|
+
- Salesforce REST API Guide: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/
|