@bonsae/node-red-salesforce 0.4.1 → 0.6.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 +82 -4
- package/icons/salesforce-apex-code.png +0 -0
- package/icons/salesforce-apex-invocation.png +0 -0
- package/index.d.ts +89 -39
- package/index.html +2 -1
- package/index.mjs +902 -403
- package/index.mjs.map +1 -1
- package/locales/de/index.html +68 -15
- package/locales/de/index.json +54 -12
- package/locales/en-US/index.html +69 -16
- package/locales/en-US/index.json +57 -16
- package/locales/es-ES/index.html +75 -22
- package/locales/es-ES/index.json +61 -19
- package/locales/fr/index.html +75 -22
- package/locales/fr/index.json +63 -21
- package/locales/ja/index.html +74 -21
- package/locales/ja/index.json +60 -18
- package/locales/ko/index.html +74 -21
- package/locales/ko/index.json +60 -18
- package/locales/pt-BR/index.html +70 -17
- package/locales/pt-BR/index.json +57 -15
- package/locales/ru/index.html +74 -21
- package/locales/ru/index.json +60 -18
- package/locales/zh-CN/index.html +74 -21
- package/locales/zh-CN/index.json +60 -18
- package/locales/zh-TW/index.html +74 -21
- package/locales/zh-TW/index.json +60 -18
- package/package.json +2 -2
- package/resources/index.C1dzx4s2.js +49 -0
- package/resources/index.zXteTlSH.css +48 -0
- package/resources/index.FDBQSjT7.js +0 -1
package/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
import { fileURLToPath as
|
|
6
|
-
import { dirname as
|
|
7
|
-
import { registerTypes as
|
|
8
|
-
import { defineSchema as
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
var
|
|
12
|
-
const
|
|
1
|
+
var V = Object.defineProperty;
|
|
2
|
+
var Q = (i, s, t) => s in i ? V(i, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[s] = t;
|
|
3
|
+
var h = (i, s) => V(i, "name", { value: s, configurable: !0 });
|
|
4
|
+
var a = (i, s, t) => Q(i, typeof s != "symbol" ? s + "" : s, t);
|
|
5
|
+
import { fileURLToPath as X } from "url";
|
|
6
|
+
import { dirname as W } from "path";
|
|
7
|
+
import { registerTypes as Z } from "@bonsae/nrg/server";
|
|
8
|
+
import { defineSchema as f, SchemaType as e, ConfigNode as _, IONode as C, defineModule as ee } from "@bonsae/nrg/server";
|
|
9
|
+
import Y from "jsforce";
|
|
10
|
+
import z from "node:crypto";
|
|
11
|
+
var K = X(import.meta.url), Ge = W(K);
|
|
12
|
+
const te = f(
|
|
13
13
|
{
|
|
14
14
|
name: e.String({ default: "" }),
|
|
15
15
|
loginUrl: e.String({
|
|
@@ -41,152 +41,152 @@ const W = h(
|
|
|
41
41
|
)
|
|
42
42
|
},
|
|
43
43
|
{ $id: "salesforce-connection:config" }
|
|
44
|
-
),
|
|
44
|
+
), ne = f(
|
|
45
45
|
{
|
|
46
46
|
accessToken: e.String({ default: "", format: "password" }),
|
|
47
47
|
refreshToken: e.String({ default: "", format: "password" }),
|
|
48
48
|
instanceUrl: e.String({ default: "" })
|
|
49
49
|
},
|
|
50
50
|
{ $id: "salesforce-connection:credentials" }
|
|
51
|
-
),
|
|
52
|
-
function
|
|
53
|
-
return
|
|
51
|
+
), J = 600 * 1e3, U = /* @__PURE__ */ new Map();
|
|
52
|
+
function se() {
|
|
53
|
+
return z.randomBytes(32).toString("base64url");
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
function
|
|
57
|
-
return
|
|
55
|
+
h(se, "generateCodeVerifier");
|
|
56
|
+
function oe(i) {
|
|
57
|
+
return z.createHash("sha256").update(i).digest("base64url");
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
function
|
|
61
|
-
const
|
|
62
|
-
U.set(
|
|
63
|
-
codeVerifier:
|
|
64
|
-
nodeId:
|
|
65
|
-
clientId:
|
|
66
|
-
loginUrl:
|
|
67
|
-
callbackUrl:
|
|
59
|
+
h(oe, "generateCodeChallenge");
|
|
60
|
+
function re(i) {
|
|
61
|
+
const s = z.randomUUID(), t = se(), n = oe(t);
|
|
62
|
+
U.set(s, {
|
|
63
|
+
codeVerifier: t,
|
|
64
|
+
nodeId: i.nodeId,
|
|
65
|
+
clientId: i.clientId,
|
|
66
|
+
loginUrl: i.loginUrl,
|
|
67
|
+
callbackUrl: i.callbackUrl,
|
|
68
68
|
timestamp: Date.now()
|
|
69
69
|
});
|
|
70
|
-
for (const [
|
|
71
|
-
Date.now() -
|
|
72
|
-
return { state:
|
|
70
|
+
for (const [o, r] of U)
|
|
71
|
+
Date.now() - r.timestamp > J && U.delete(o);
|
|
72
|
+
return { state: s, codeChallenge: n };
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
function
|
|
76
|
-
const
|
|
77
|
-
return !
|
|
74
|
+
h(re, "createAuthState");
|
|
75
|
+
function ae(i) {
|
|
76
|
+
const s = U.get(i);
|
|
77
|
+
return !s || (U.delete(i), Date.now() - s.timestamp > J) ? null : s;
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
function
|
|
81
|
-
return
|
|
79
|
+
h(ae, "consumeAuthState");
|
|
80
|
+
function ie(i) {
|
|
81
|
+
return i.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
return `<html><body><h2>Authorization Failed</h2><p>${
|
|
83
|
+
h(ie, "escapeHtml");
|
|
84
|
+
function v(i, s = !0) {
|
|
85
|
+
const t = s ? "<script>setTimeout(function(){window.close()},3000)</script>" : "";
|
|
86
|
+
return `<html><body><h2>Authorization Failed</h2><p>${ie(i)}</p>${t}</body></html>`;
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
function
|
|
90
|
-
const
|
|
88
|
+
h(v, "errorPage");
|
|
89
|
+
function ce(i) {
|
|
90
|
+
const s = (i.settings.httpAdminRoot || "").replace(
|
|
91
91
|
/\/$/,
|
|
92
92
|
""
|
|
93
93
|
);
|
|
94
|
-
|
|
94
|
+
i.httpAdmin.post("/salesforce/auth/start", (t, n) => {
|
|
95
95
|
try {
|
|
96
96
|
const {
|
|
97
|
-
nodeId:
|
|
98
|
-
loginUrl:
|
|
99
|
-
clientId:
|
|
100
|
-
callbackUrl:
|
|
101
|
-
} =
|
|
102
|
-
if (!
|
|
103
|
-
|
|
97
|
+
nodeId: o,
|
|
98
|
+
loginUrl: r,
|
|
99
|
+
clientId: c,
|
|
100
|
+
callbackUrl: u
|
|
101
|
+
} = t.body;
|
|
102
|
+
if (!o || !r || !c) {
|
|
103
|
+
n.status(400).json({ error: "nodeId, loginUrl, and clientId are required" });
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
const
|
|
107
|
-
nodeId:
|
|
108
|
-
clientId:
|
|
109
|
-
loginUrl:
|
|
110
|
-
callbackUrl:
|
|
106
|
+
const l = u || `${t.protocol}://${t.get("host")}${s}/salesforce/auth/callback`, { state: p, codeChallenge: d } = re({
|
|
107
|
+
nodeId: o,
|
|
108
|
+
clientId: c,
|
|
109
|
+
loginUrl: r,
|
|
110
|
+
callbackUrl: l
|
|
111
111
|
}), m = new URLSearchParams({
|
|
112
112
|
response_type: "code",
|
|
113
|
-
client_id:
|
|
114
|
-
redirect_uri:
|
|
115
|
-
state:
|
|
116
|
-
code_challenge:
|
|
113
|
+
client_id: c,
|
|
114
|
+
redirect_uri: l,
|
|
115
|
+
state: p,
|
|
116
|
+
code_challenge: d,
|
|
117
117
|
code_challenge_method: "S256"
|
|
118
118
|
});
|
|
119
|
-
|
|
120
|
-
authorizationUrl: `${
|
|
119
|
+
n.json({
|
|
120
|
+
authorizationUrl: `${r}/services/oauth2/authorize?${m.toString()}`
|
|
121
121
|
});
|
|
122
|
-
} catch (
|
|
123
|
-
|
|
124
|
-
`salesforce-connection: auth/start error: ${
|
|
125
|
-
),
|
|
122
|
+
} catch (o) {
|
|
123
|
+
i.log.error(
|
|
124
|
+
`salesforce-connection: auth/start error: ${o instanceof Error ? o.message : String(o)}`
|
|
125
|
+
), n.status(500).json({ error: "Failed to start authorization" });
|
|
126
126
|
}
|
|
127
|
-
}),
|
|
127
|
+
}), i.httpAdmin.get("/salesforce/auth/callback", async (t, n) => {
|
|
128
128
|
try {
|
|
129
|
-
const { code:
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
`salesforce-connection: OAuth error: ${
|
|
133
|
-
),
|
|
129
|
+
const { code: o, state: r, error: c, error_description: u } = t.query;
|
|
130
|
+
if (c) {
|
|
131
|
+
i.log.error(
|
|
132
|
+
`salesforce-connection: OAuth error: ${c} - ${u}`
|
|
133
|
+
), n.status(400).send(v(String(u || c)));
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
-
if (!
|
|
137
|
-
|
|
136
|
+
if (!o || !r) {
|
|
137
|
+
n.status(400).send(v("Missing code or state parameter"));
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
|
-
const
|
|
141
|
-
if (!
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
const l = ae(r);
|
|
141
|
+
if (!l) {
|
|
142
|
+
n.status(400).send(
|
|
143
|
+
v(
|
|
144
144
|
"Invalid or expired authorization state. Please try again."
|
|
145
145
|
)
|
|
146
146
|
);
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
const
|
|
150
|
-
`${
|
|
149
|
+
const p = await fetch(
|
|
150
|
+
`${l.loginUrl}/services/oauth2/token`,
|
|
151
151
|
{
|
|
152
152
|
method: "POST",
|
|
153
153
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
154
154
|
body: new URLSearchParams({
|
|
155
155
|
grant_type: "authorization_code",
|
|
156
|
-
code:
|
|
157
|
-
client_id:
|
|
158
|
-
redirect_uri:
|
|
159
|
-
code_verifier:
|
|
156
|
+
code: o,
|
|
157
|
+
client_id: l.clientId,
|
|
158
|
+
redirect_uri: l.callbackUrl,
|
|
159
|
+
code_verifier: l.codeVerifier
|
|
160
160
|
})
|
|
161
161
|
}
|
|
162
162
|
);
|
|
163
|
-
if (!
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
`salesforce-connection: Token exchange failed: ${
|
|
167
|
-
),
|
|
168
|
-
|
|
163
|
+
if (!p.ok) {
|
|
164
|
+
const g = await p.text();
|
|
165
|
+
i.log.error(
|
|
166
|
+
`salesforce-connection: Token exchange failed: ${g}`
|
|
167
|
+
), n.status(500).send(
|
|
168
|
+
v(
|
|
169
169
|
"Token exchange failed. Check the Node-RED logs for details."
|
|
170
170
|
)
|
|
171
171
|
);
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
accessToken:
|
|
177
|
-
refreshToken:
|
|
178
|
-
instanceUrl:
|
|
179
|
-
}),
|
|
180
|
-
`salesforce-connection: Successfully authorized node ${
|
|
174
|
+
const d = await p.json();
|
|
175
|
+
i.nodes.addCredentials(l.nodeId, {
|
|
176
|
+
accessToken: d.access_token,
|
|
177
|
+
refreshToken: d.refresh_token,
|
|
178
|
+
instanceUrl: d.instance_url
|
|
179
|
+
}), i.log.info(
|
|
180
|
+
`salesforce-connection: Successfully authorized node ${l.nodeId} for ${d.instance_url}`
|
|
181
181
|
);
|
|
182
182
|
const m = JSON.stringify({
|
|
183
183
|
type: "salesforce-auth-success",
|
|
184
|
-
nodeId:
|
|
185
|
-
accessToken:
|
|
186
|
-
refreshToken:
|
|
187
|
-
instanceUrl:
|
|
184
|
+
nodeId: l.nodeId,
|
|
185
|
+
accessToken: d.access_token,
|
|
186
|
+
refreshToken: d.refresh_token,
|
|
187
|
+
instanceUrl: d.instance_url
|
|
188
188
|
});
|
|
189
|
-
|
|
189
|
+
n.send(`<!DOCTYPE html>
|
|
190
190
|
<html>
|
|
191
191
|
<body>
|
|
192
192
|
<h2>Authorization Successful</h2>
|
|
@@ -199,77 +199,318 @@ function ne(a) {
|
|
|
199
199
|
</script>
|
|
200
200
|
</body>
|
|
201
201
|
</html>`);
|
|
202
|
-
} catch (
|
|
203
|
-
|
|
204
|
-
`salesforce-connection: auth/callback error: ${
|
|
205
|
-
),
|
|
202
|
+
} catch (o) {
|
|
203
|
+
i.log.error(
|
|
204
|
+
`salesforce-connection: auth/callback error: ${o instanceof Error ? o.message : String(o)}`
|
|
205
|
+
), n.status(500).send(v("An unexpected error occurred."));
|
|
206
206
|
}
|
|
207
|
-
}),
|
|
207
|
+
}), i.httpAdmin.get("/salesforce/auth/status/:nodeId", (t, n) => {
|
|
208
208
|
try {
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
authenticated:
|
|
212
|
-
instanceUrl:
|
|
209
|
+
const o = i.nodes.getCredentials(t.params.nodeId), r = !!(o != null && o.accessToken && (o != null && o.instanceUrl));
|
|
210
|
+
n.json({
|
|
211
|
+
authenticated: r,
|
|
212
|
+
instanceUrl: r ? o.instanceUrl : void 0
|
|
213
213
|
});
|
|
214
214
|
} catch {
|
|
215
|
-
|
|
215
|
+
n.json({ authenticated: !1 });
|
|
216
216
|
}
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
|
-
|
|
220
|
-
function
|
|
221
|
-
|
|
219
|
+
h(ce, "initAuthRoutes");
|
|
220
|
+
function P(i, s) {
|
|
221
|
+
const t = i.nodes.getCredentials(s);
|
|
222
|
+
if (!(t != null && t.accessToken) || !(t != null && t.instanceUrl))
|
|
223
|
+
throw new Error("Connection not authenticated");
|
|
224
|
+
return new Y.Connection({
|
|
225
|
+
instanceUrl: t.instanceUrl,
|
|
226
|
+
accessToken: t.accessToken
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
h(P, "getConnection");
|
|
230
|
+
const T = class T {
|
|
231
|
+
constructor(s) {
|
|
232
|
+
a(this, "conn");
|
|
233
|
+
this.conn = s;
|
|
234
|
+
}
|
|
235
|
+
// --- Apex REST ---
|
|
236
|
+
async invoke(s, t) {
|
|
237
|
+
const n = this.conn.version || "62.0", r = (await this.conn.request({
|
|
238
|
+
method: "POST",
|
|
239
|
+
url: `/services/data/v${n}/actions/custom/apex/${s}`,
|
|
240
|
+
body: JSON.stringify({
|
|
241
|
+
inputs: [{ payload: JSON.stringify(t) }]
|
|
242
|
+
}),
|
|
243
|
+
headers: { "Content-Type": "application/json" }
|
|
244
|
+
}))[0];
|
|
245
|
+
if (!r.isSuccess) {
|
|
246
|
+
const c = r.errors.map((u) => u.message).join("; ");
|
|
247
|
+
throw new Error(`Invocable action failed: ${c}`);
|
|
248
|
+
}
|
|
249
|
+
return r;
|
|
250
|
+
}
|
|
251
|
+
async post(s, t) {
|
|
252
|
+
return await this.conn.apex.post(
|
|
253
|
+
s,
|
|
254
|
+
t
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
async get(s) {
|
|
258
|
+
return await this.conn.apex.get(s);
|
|
259
|
+
}
|
|
260
|
+
async put(s, t) {
|
|
261
|
+
return await this.conn.apex.put(
|
|
262
|
+
s,
|
|
263
|
+
t
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
async patch(s, t) {
|
|
267
|
+
return await this.conn.apex.patch(
|
|
268
|
+
s,
|
|
269
|
+
t
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
async delete(s) {
|
|
273
|
+
return await this.conn.apex.delete(s);
|
|
274
|
+
}
|
|
275
|
+
// --- Tooling API ---
|
|
276
|
+
async queryApexClassesByName(s) {
|
|
277
|
+
const t = s.map((r) => `'${r}'`).join(","), n = await this.conn.tooling.query(
|
|
278
|
+
`SELECT Id, Name, Body FROM ApexClass WHERE Name IN (${t})`
|
|
279
|
+
), o = /* @__PURE__ */ new Map();
|
|
280
|
+
for (const r of n.records)
|
|
281
|
+
o.set(r.Name, {
|
|
282
|
+
Id: r.Id,
|
|
283
|
+
Name: r.Name,
|
|
284
|
+
Body: r.Body
|
|
285
|
+
});
|
|
286
|
+
return o;
|
|
287
|
+
}
|
|
288
|
+
async createApexClass(s, t) {
|
|
289
|
+
return this.withRetry(async () => {
|
|
290
|
+
var o;
|
|
291
|
+
const n = await this.conn.tooling.create("ApexClass", {
|
|
292
|
+
Name: s,
|
|
293
|
+
Body: t
|
|
294
|
+
});
|
|
295
|
+
if (!n.success) {
|
|
296
|
+
const r = (o = n.errors) == null ? void 0 : o.map((c) => c.message).join("; ");
|
|
297
|
+
throw new Error(`Apex create failed: ${r}`);
|
|
298
|
+
}
|
|
299
|
+
return { id: n.id };
|
|
300
|
+
}, `create ${s}`);
|
|
301
|
+
}
|
|
302
|
+
async deleteApexClass(s) {
|
|
303
|
+
await this.withRetry(
|
|
304
|
+
() => this.conn.tooling.destroy("ApexClass", s),
|
|
305
|
+
`delete ${s}`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
async queryApexRestAndInvocableClasses() {
|
|
309
|
+
var o, r;
|
|
310
|
+
const s = await this.conn.tooling.query(
|
|
311
|
+
"SELECT Name, Body FROM ApexClass ORDER BY Name"
|
|
312
|
+
), t = [], n = [];
|
|
313
|
+
for (const c of s.records) {
|
|
314
|
+
if ((o = c.Body) != null && o.includes("@RestResource")) {
|
|
315
|
+
const u = c.Body.match(
|
|
316
|
+
/@RestResource\s*\(\s*urlMapping\s*=\s*'([^']+)'/
|
|
317
|
+
);
|
|
318
|
+
t.push({ name: c.Name, urlMapping: u ? u[1] : void 0 });
|
|
319
|
+
}
|
|
320
|
+
(r = c.Body) != null && r.includes("@InvocableMethod") && n.push({ name: c.Name });
|
|
321
|
+
}
|
|
322
|
+
return { rest: t, invocable: n };
|
|
323
|
+
}
|
|
324
|
+
// --- Streaming ---
|
|
325
|
+
async queryStreamingChannels() {
|
|
326
|
+
const s = await this.conn.describeGlobal(), t = [];
|
|
327
|
+
for (const n of s.sobjects)
|
|
328
|
+
n.name.endsWith("__e") ? t.push({
|
|
329
|
+
value: `/event/${n.name}`,
|
|
330
|
+
label: `${n.label} (${n.name})`,
|
|
331
|
+
group: "Platform Events"
|
|
332
|
+
}) : n.name.endsWith("ChangeEvent") && t.push({
|
|
333
|
+
value: `/data/${n.name}`,
|
|
334
|
+
label: `${n.label} (${n.name})`,
|
|
335
|
+
group: "Change Data Capture"
|
|
336
|
+
});
|
|
337
|
+
return t.push({
|
|
338
|
+
value: "/data/ChangeEvents",
|
|
339
|
+
label: "All Change Events",
|
|
340
|
+
group: "Change Data Capture"
|
|
341
|
+
}), t;
|
|
342
|
+
}
|
|
343
|
+
// --- Retry ---
|
|
344
|
+
async withRetry(s, t) {
|
|
345
|
+
for (let n = 1; n <= T.MAX_RETRIES; n++)
|
|
346
|
+
try {
|
|
347
|
+
return await s();
|
|
348
|
+
} catch (o) {
|
|
349
|
+
if (n === T.MAX_RETRIES) throw o;
|
|
350
|
+
const r = T.RETRY_DELAY_MS * n;
|
|
351
|
+
console.warn(
|
|
352
|
+
`[SalesforceClient] ${t} failed (attempt ${n}/${T.MAX_RETRIES}), retrying in ${r}ms...`
|
|
353
|
+
), await new Promise((c) => setTimeout(c, r));
|
|
354
|
+
}
|
|
355
|
+
throw new Error("unreachable");
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
h(T, "SalesforceClient"), a(T, "MAX_RETRIES", 3), a(T, "RETRY_DELAY_MS", 1e3);
|
|
359
|
+
let R = T;
|
|
360
|
+
function le(i) {
|
|
361
|
+
switch (i) {
|
|
362
|
+
case "boolean":
|
|
363
|
+
return "Boolean";
|
|
364
|
+
case "int":
|
|
365
|
+
return "Integer";
|
|
366
|
+
case "long":
|
|
367
|
+
return "Long";
|
|
368
|
+
case "double":
|
|
369
|
+
return "Double";
|
|
370
|
+
case "currency":
|
|
371
|
+
case "percent":
|
|
372
|
+
return "Decimal";
|
|
373
|
+
case "date":
|
|
374
|
+
return "Date";
|
|
375
|
+
case "datetime":
|
|
376
|
+
return "Datetime";
|
|
377
|
+
case "time":
|
|
378
|
+
return "Time";
|
|
379
|
+
case "id":
|
|
380
|
+
return "Id";
|
|
381
|
+
case "reference":
|
|
382
|
+
return "Id";
|
|
383
|
+
case "base64":
|
|
384
|
+
return "Blob";
|
|
385
|
+
case "location":
|
|
386
|
+
return "Location";
|
|
387
|
+
case "address":
|
|
388
|
+
return "Address";
|
|
389
|
+
default:
|
|
390
|
+
return "String";
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
h(le, "sfTypeToApex");
|
|
394
|
+
function ue(i) {
|
|
395
|
+
const s = [`global class ${i.name} {`];
|
|
396
|
+
for (const t of i.fields) {
|
|
397
|
+
const n = le(t.type);
|
|
398
|
+
s.push(` global ${n} ${t.name};`);
|
|
399
|
+
}
|
|
400
|
+
return s.push("}"), s.join(`
|
|
401
|
+
`);
|
|
402
|
+
}
|
|
403
|
+
h(ue, "buildFauxClass");
|
|
404
|
+
function de(i) {
|
|
405
|
+
i.httpAdmin.get(
|
|
406
|
+
"/salesforce/list-apex-classes/:nodeId",
|
|
407
|
+
async (s, t) => {
|
|
408
|
+
try {
|
|
409
|
+
const n = P(i, s.params.nodeId), o = new R(n);
|
|
410
|
+
t.json(await o.queryApexRestAndInvocableClasses());
|
|
411
|
+
} catch (n) {
|
|
412
|
+
const o = n instanceof Error ? n.message : String(n);
|
|
413
|
+
t.status(500).json({ error: o });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
), i.httpAdmin.get(
|
|
417
|
+
"/salesforce/describe-sobjects/:nodeId",
|
|
418
|
+
async (s, t) => {
|
|
419
|
+
try {
|
|
420
|
+
const n = P(i, s.params.nodeId), o = s.params.nodeId, r = G.get(o);
|
|
421
|
+
if (r && Date.now() - r.timestamp < pe) {
|
|
422
|
+
t.json({ sobjects: r.data });
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const u = (await n.describeGlobal()).sobjects.filter((d) => d.queryable).map((d) => d.name), l = 25, p = {};
|
|
426
|
+
for (let d = 0; d < u.length; d += l) {
|
|
427
|
+
const m = u.slice(d, d + l), g = await Promise.all(
|
|
428
|
+
m.map((x) => n.describe(x).catch(() => null))
|
|
429
|
+
);
|
|
430
|
+
for (const x of g)
|
|
431
|
+
x && (p[x.name] = ue(x));
|
|
432
|
+
}
|
|
433
|
+
G.set(o, {
|
|
434
|
+
data: p,
|
|
435
|
+
timestamp: Date.now()
|
|
436
|
+
}), t.json({ sobjects: p });
|
|
437
|
+
} catch (n) {
|
|
438
|
+
const o = n instanceof Error ? n.message : String(n);
|
|
439
|
+
t.status(500).json({ error: o });
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
h(de, "initApexRoutes");
|
|
445
|
+
const pe = 1800 * 1e3, G = /* @__PURE__ */ new Map();
|
|
446
|
+
function he(i) {
|
|
447
|
+
i.httpAdmin.get(
|
|
448
|
+
"/salesforce/list-streaming-channels/:nodeId",
|
|
449
|
+
async (s, t) => {
|
|
450
|
+
try {
|
|
451
|
+
const n = P(i, s.params.nodeId), o = new R(n);
|
|
452
|
+
t.json(await o.queryStreamingChannels());
|
|
453
|
+
} catch (n) {
|
|
454
|
+
const o = n instanceof Error ? n.message : String(n);
|
|
455
|
+
t.status(500).json({ error: o });
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
h(he, "initStreamingRoutes");
|
|
461
|
+
function fe(i) {
|
|
462
|
+
ce(i), de(i), he(i);
|
|
222
463
|
}
|
|
223
|
-
|
|
224
|
-
const
|
|
464
|
+
h(fe, "initRoutes");
|
|
465
|
+
const F = class F extends _ {
|
|
225
466
|
constructor() {
|
|
226
467
|
super(...arguments);
|
|
227
|
-
|
|
468
|
+
a(this, "conn", null);
|
|
228
469
|
}
|
|
229
|
-
static async registered(
|
|
230
|
-
|
|
470
|
+
static async registered(t) {
|
|
471
|
+
fe(t);
|
|
231
472
|
}
|
|
232
473
|
async getConnection() {
|
|
233
474
|
if (this.conn) return this.conn;
|
|
234
|
-
const
|
|
235
|
-
if (!(
|
|
475
|
+
const t = this.credentials;
|
|
476
|
+
if (!(t != null && t.accessToken) || !(t != null && t.instanceUrl))
|
|
236
477
|
throw new Error(
|
|
237
478
|
"Salesforce connection not authorized. Please authorize in the node configuration."
|
|
238
479
|
);
|
|
239
|
-
return this.conn = new
|
|
480
|
+
return this.conn = new Y.Connection({
|
|
240
481
|
oauth2: {
|
|
241
482
|
clientId: this.config.clientId,
|
|
242
483
|
loginUrl: this.config.loginUrl
|
|
243
484
|
},
|
|
244
|
-
instanceUrl:
|
|
245
|
-
accessToken:
|
|
246
|
-
refreshToken:
|
|
485
|
+
instanceUrl: t.instanceUrl,
|
|
486
|
+
accessToken: t.accessToken,
|
|
487
|
+
refreshToken: t.refreshToken,
|
|
247
488
|
version: this.config.apiVersion
|
|
248
|
-
}), this.conn.on("refresh", (
|
|
489
|
+
}), this.conn.on("refresh", (n) => {
|
|
249
490
|
this.RED.nodes.addCredentials(this.id, {
|
|
250
491
|
...this.credentials,
|
|
251
|
-
accessToken:
|
|
492
|
+
accessToken: n
|
|
252
493
|
});
|
|
253
494
|
}), this.conn;
|
|
254
495
|
}
|
|
255
496
|
getAccessToken() {
|
|
256
|
-
var
|
|
257
|
-
return (
|
|
497
|
+
var t;
|
|
498
|
+
return (t = this.credentials) == null ? void 0 : t.accessToken;
|
|
258
499
|
}
|
|
259
500
|
getInstanceUrl() {
|
|
260
|
-
var
|
|
261
|
-
return (
|
|
501
|
+
var t;
|
|
502
|
+
return (t = this.credentials) == null ? void 0 : t.instanceUrl;
|
|
262
503
|
}
|
|
263
504
|
async closed() {
|
|
264
505
|
this.conn = null;
|
|
265
506
|
}
|
|
266
507
|
};
|
|
267
|
-
|
|
268
|
-
let
|
|
269
|
-
const
|
|
508
|
+
h(F, "SalesforceConnection"), a(F, "type", "salesforce-connection"), a(F, "configSchema", te), a(F, "credentialsSchema", ne);
|
|
509
|
+
let w = F;
|
|
510
|
+
const ge = f(
|
|
270
511
|
{
|
|
271
512
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
272
|
-
connection: e.NodeRef(
|
|
513
|
+
connection: e.NodeRef(w, {
|
|
273
514
|
"x-nrg-form": { icon: "cloud" }
|
|
274
515
|
}),
|
|
275
516
|
query: e.TypedInput({
|
|
@@ -283,56 +524,56 @@ const re = h(
|
|
|
283
524
|
statusPort: e.Boolean({ default: !1 })
|
|
284
525
|
},
|
|
285
526
|
{ $id: "salesforce-soql:config" }
|
|
286
|
-
),
|
|
527
|
+
), me = f(
|
|
287
528
|
{
|
|
288
529
|
payload: e.Any()
|
|
289
530
|
},
|
|
290
531
|
{ $id: "salesforce-soql:input" }
|
|
291
|
-
),
|
|
532
|
+
), ye = f(
|
|
292
533
|
{
|
|
293
534
|
payload: e.Array(e.Any()),
|
|
294
535
|
totalSize: e.Number(),
|
|
295
536
|
done: e.Boolean()
|
|
296
537
|
},
|
|
297
538
|
{ $id: "salesforce-soql:output" }
|
|
298
|
-
),
|
|
299
|
-
async input(
|
|
300
|
-
const
|
|
301
|
-
if (!
|
|
302
|
-
this.error("No Salesforce connection configured",
|
|
539
|
+
), $ = class $ extends C {
|
|
540
|
+
async input(s) {
|
|
541
|
+
const t = this.config.connection;
|
|
542
|
+
if (!t) {
|
|
543
|
+
this.error("No Salesforce connection configured", s);
|
|
303
544
|
return;
|
|
304
545
|
}
|
|
305
546
|
try {
|
|
306
547
|
this.status({ fill: "green", shape: "dot", text: "querying..." });
|
|
307
|
-
const
|
|
548
|
+
const n = await t.getConnection(), o = await this.config.query.resolve(s), r = await n.query(o);
|
|
308
549
|
this.status({
|
|
309
550
|
fill: "green",
|
|
310
551
|
shape: "dot",
|
|
311
|
-
text: `${
|
|
552
|
+
text: `${r.totalSize} records`
|
|
312
553
|
}), this.send({
|
|
313
|
-
...
|
|
314
|
-
payload:
|
|
315
|
-
totalSize:
|
|
316
|
-
done:
|
|
554
|
+
...s,
|
|
555
|
+
payload: r.records,
|
|
556
|
+
totalSize: r.totalSize,
|
|
557
|
+
done: r.done
|
|
317
558
|
});
|
|
318
|
-
} catch (
|
|
559
|
+
} catch (n) {
|
|
319
560
|
this.status({
|
|
320
561
|
fill: "red",
|
|
321
562
|
shape: "dot",
|
|
322
|
-
text:
|
|
563
|
+
text: n instanceof Error ? n.message : String(n)
|
|
323
564
|
}), this.error(
|
|
324
|
-
`SOQL query failed: ${
|
|
325
|
-
|
|
565
|
+
`SOQL query failed: ${n instanceof Error ? n.message : String(n)}`,
|
|
566
|
+
s
|
|
326
567
|
);
|
|
327
568
|
}
|
|
328
569
|
}
|
|
329
570
|
};
|
|
330
|
-
|
|
331
|
-
let
|
|
332
|
-
const
|
|
571
|
+
h($, "SalesforceSoql"), a($, "type", "salesforce-soql"), a($, "category", "salesforce"), a($, "color", "#FFFFFF"), a($, "configSchema", ge), a($, "inputSchema", me), a($, "outputsSchema", ye);
|
|
572
|
+
let k = $;
|
|
573
|
+
const xe = f(
|
|
333
574
|
{
|
|
334
575
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
335
|
-
connection: e.NodeRef(
|
|
576
|
+
connection: e.NodeRef(w, {
|
|
336
577
|
"x-nrg-form": { icon: "cloud" }
|
|
337
578
|
}),
|
|
338
579
|
operation: e.Union(
|
|
@@ -381,66 +622,66 @@ const ae = h(
|
|
|
381
622
|
}
|
|
382
623
|
}
|
|
383
624
|
}
|
|
384
|
-
),
|
|
625
|
+
), be = f(
|
|
385
626
|
{
|
|
386
627
|
payload: e.Any()
|
|
387
628
|
},
|
|
388
629
|
{ $id: "salesforce-dml:input" }
|
|
389
|
-
),
|
|
630
|
+
), we = f(
|
|
390
631
|
{
|
|
391
632
|
payload: e.Any()
|
|
392
633
|
},
|
|
393
634
|
{ $id: "salesforce-dml:output" }
|
|
394
|
-
),
|
|
395
|
-
async input(
|
|
396
|
-
const
|
|
397
|
-
if (!
|
|
398
|
-
this.error("No Salesforce connection configured",
|
|
635
|
+
), I = class I extends C {
|
|
636
|
+
async input(s) {
|
|
637
|
+
const t = this.config.connection;
|
|
638
|
+
if (!t) {
|
|
639
|
+
this.error("No Salesforce connection configured", s);
|
|
399
640
|
return;
|
|
400
641
|
}
|
|
401
642
|
try {
|
|
402
|
-
const
|
|
403
|
-
this.status({ fill: "green", shape: "dot", text: `${
|
|
404
|
-
const
|
|
405
|
-
let
|
|
406
|
-
switch (
|
|
643
|
+
const n = this.config.operation;
|
|
644
|
+
this.status({ fill: "green", shape: "dot", text: `${n}...` });
|
|
645
|
+
const o = await t.getConnection(), r = await this.config.sObjectType.resolve(s), c = o.sobject(r), u = await this.config.record.resolve(s) ?? s.payload;
|
|
646
|
+
let l;
|
|
647
|
+
switch (n) {
|
|
407
648
|
case "create":
|
|
408
|
-
|
|
649
|
+
l = await c.create(u);
|
|
409
650
|
break;
|
|
410
651
|
case "read":
|
|
411
|
-
|
|
652
|
+
l = await c.retrieve(u);
|
|
412
653
|
break;
|
|
413
654
|
case "update":
|
|
414
|
-
|
|
655
|
+
l = await c.update(u);
|
|
415
656
|
break;
|
|
416
657
|
case "delete":
|
|
417
|
-
|
|
658
|
+
l = await c.destroy(u);
|
|
418
659
|
break;
|
|
419
660
|
case "upsert":
|
|
420
|
-
|
|
661
|
+
l = await c.upsert(u, this.config.externalIdField);
|
|
421
662
|
break;
|
|
422
663
|
default:
|
|
423
|
-
throw new Error(`Unknown operation: ${
|
|
664
|
+
throw new Error(`Unknown operation: ${n}`);
|
|
424
665
|
}
|
|
425
|
-
this.status({ fill: "green", shape: "dot", text: `${
|
|
426
|
-
} catch (
|
|
666
|
+
this.status({ fill: "green", shape: "dot", text: `${n} done` }), this.send({ ...s, payload: l });
|
|
667
|
+
} catch (n) {
|
|
427
668
|
this.status({
|
|
428
669
|
fill: "red",
|
|
429
670
|
shape: "dot",
|
|
430
|
-
text:
|
|
671
|
+
text: n instanceof Error ? n.message : String(n)
|
|
431
672
|
}), this.error(
|
|
432
|
-
`DML ${this.config.operation} failed: ${
|
|
433
|
-
|
|
673
|
+
`DML ${this.config.operation} failed: ${n instanceof Error ? n.message : String(n)}`,
|
|
674
|
+
s
|
|
434
675
|
);
|
|
435
676
|
}
|
|
436
677
|
}
|
|
437
678
|
};
|
|
438
|
-
|
|
439
|
-
let
|
|
440
|
-
const
|
|
679
|
+
h(I, "SalesforceDml"), a(I, "type", "salesforce-dml"), a(I, "category", "salesforce"), a(I, "color", "#FFFFFF"), a(I, "configSchema", xe), a(I, "inputSchema", be), a(I, "outputsSchema", we);
|
|
680
|
+
let j = I;
|
|
681
|
+
const Te = f(
|
|
441
682
|
{
|
|
442
683
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
443
|
-
connection: e.NodeRef(
|
|
684
|
+
connection: e.NodeRef(w, {
|
|
444
685
|
"x-nrg-form": { icon: "cloud" }
|
|
445
686
|
}),
|
|
446
687
|
operation: e.Union(
|
|
@@ -449,6 +690,7 @@ const de = h(
|
|
|
449
690
|
e.Literal("update"),
|
|
450
691
|
e.Literal("upsert"),
|
|
451
692
|
e.Literal("delete"),
|
|
693
|
+
e.Literal("hardDelete"),
|
|
452
694
|
e.Literal("query")
|
|
453
695
|
],
|
|
454
696
|
{ default: "insert", "x-nrg-form": { icon: "database" } }
|
|
@@ -459,6 +701,12 @@ const de = h(
|
|
|
459
701
|
typedInputTypes: ["str", "msg"]
|
|
460
702
|
}
|
|
461
703
|
}),
|
|
704
|
+
query: e.TypedInput({
|
|
705
|
+
"x-nrg-form": {
|
|
706
|
+
icon: "search",
|
|
707
|
+
typedInputTypes: ["str", "msg", "jsonata"]
|
|
708
|
+
}
|
|
709
|
+
}),
|
|
462
710
|
externalIdField: e.Optional(
|
|
463
711
|
e.String({
|
|
464
712
|
default: "",
|
|
@@ -497,7 +745,7 @@ const de = h(
|
|
|
497
745
|
"x-nrg-form": { icon: "hourglass" }
|
|
498
746
|
}),
|
|
499
747
|
errorPort: e.Boolean({ default: !1 }),
|
|
500
|
-
completePort: e.Boolean({ default: !
|
|
748
|
+
completePort: e.Boolean({ default: !1 }),
|
|
501
749
|
statusPort: e.Boolean({ default: !1 })
|
|
502
750
|
},
|
|
503
751
|
{
|
|
@@ -514,119 +762,99 @@ const de = h(
|
|
|
514
762
|
}
|
|
515
763
|
}
|
|
516
764
|
}
|
|
517
|
-
),
|
|
765
|
+
), $e = f(
|
|
518
766
|
{
|
|
519
|
-
payload: e.Any(
|
|
767
|
+
payload: e.Any({
|
|
768
|
+
description: "Records array, CSV string, readable stream (ingest) or SOQL string (query)"
|
|
769
|
+
})
|
|
520
770
|
},
|
|
521
771
|
{ $id: "salesforce-bulk:input" }
|
|
522
|
-
)
|
|
523
|
-
h(
|
|
772
|
+
), Ie = f(
|
|
524
773
|
{
|
|
525
|
-
payload: e.
|
|
774
|
+
payload: e.Any({
|
|
775
|
+
description: "Query: individual record. Ingest: { successfulResults, failedResults, unprocessedRecords }"
|
|
776
|
+
})
|
|
526
777
|
},
|
|
527
778
|
{ $id: "salesforce-bulk:output" }
|
|
528
|
-
)
|
|
529
|
-
|
|
530
|
-
{},
|
|
531
|
-
{ $id: "salesforce-bulk:record-output" }
|
|
532
|
-
), pe = h(
|
|
533
|
-
{},
|
|
534
|
-
{ $id: "salesforce-bulk:job-created-output" }
|
|
535
|
-
), fe = {
|
|
536
|
-
record: he,
|
|
537
|
-
jobCreated: pe
|
|
538
|
-
}, b = class b extends k {
|
|
539
|
-
sendRecord(o, n) {
|
|
540
|
-
this.sendToPort("record", { ...o, payload: n });
|
|
541
|
-
}
|
|
542
|
-
sendJobCreated(o, n) {
|
|
543
|
-
this.sendToPort("jobCreated", { ...o, payload: n });
|
|
544
|
-
}
|
|
545
|
-
async input(o) {
|
|
546
|
-
const n = this.config.connection;
|
|
547
|
-
if (!n) {
|
|
548
|
-
this.error("No Salesforce connection configured", o);
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
779
|
+
), S = class S extends C {
|
|
780
|
+
async input(s) {
|
|
551
781
|
try {
|
|
552
|
-
const t = this.config.
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
782
|
+
const t = this.config.connection;
|
|
783
|
+
if (!t)
|
|
784
|
+
throw new Error("No Salesforce connection configured");
|
|
785
|
+
const n = await t.getConnection(), o = this.config.operation;
|
|
786
|
+
o === "query" ? await this.executeQuery(n, s) : await this.executeIngest(n, s, o);
|
|
787
|
+
} catch (t) {
|
|
788
|
+
const n = t instanceof Error ? t.message : String(t);
|
|
789
|
+
throw this.status({ fill: "red", shape: "dot", text: n }), t;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
async executeQuery(s, t) {
|
|
793
|
+
this.status({ fill: "green", shape: "dot", text: "query starting..." });
|
|
794
|
+
const n = await this.config.query.resolve(t), o = await s.bulk2.query(n, {
|
|
795
|
+
pollTimeout: this.config.pollTimeout,
|
|
796
|
+
pollInterval: this.config.pollInterval,
|
|
797
|
+
columnDelimiter: this.config.columnDelimiter,
|
|
798
|
+
lineEnding: this.config.lineEnding
|
|
799
|
+
});
|
|
800
|
+
let r = 0;
|
|
801
|
+
await new Promise((c, u) => {
|
|
802
|
+
o.on("data", (l) => {
|
|
803
|
+
r++, this.send({ ...t, payload: l }), r % 1e3 === 0 && this.status({
|
|
572
804
|
fill: "green",
|
|
573
805
|
shape: "dot",
|
|
574
|
-
text: `
|
|
575
|
-
}), this.sendToPort("complete", {
|
|
576
|
-
...o,
|
|
577
|
-
payload: { operation: t, sObjectType: i, totalRecords: l }
|
|
578
|
-
});
|
|
579
|
-
} else {
|
|
580
|
-
const d = o.payload, c = s.bulk2.createJob({
|
|
581
|
-
operation: t,
|
|
582
|
-
object: i,
|
|
583
|
-
columnDelimiter: this.config.columnDelimiter,
|
|
584
|
-
lineEnding: this.config.lineEnding,
|
|
585
|
-
...t === "upsert" && this.config.externalIdField ? { externalIdFieldName: this.config.externalIdField } : {},
|
|
586
|
-
...this.config.assignmentRuleId ? { assignmentRuleId: this.config.assignmentRuleId } : {}
|
|
587
|
-
});
|
|
588
|
-
await c.open(), this.sendJobCreated(o, {
|
|
589
|
-
jobId: c.id,
|
|
590
|
-
operation: t,
|
|
591
|
-
sObjectType: i,
|
|
592
|
-
state: "Open"
|
|
593
|
-
}), await c.uploadData(d), await c.close(), await c.poll(this.config.pollInterval, this.config.pollTimeout);
|
|
594
|
-
const g = await c.getAllResults(), u = g.successfulResults ?? [], m = g.failedResults ?? [], p = g.unprocessedRecords ?? [];
|
|
595
|
-
l = u.length + m.length + p.length;
|
|
596
|
-
for (const R of u)
|
|
597
|
-
this.sendRecord(o, R);
|
|
598
|
-
for (const R of m)
|
|
599
|
-
this.sendRecord(o, R);
|
|
600
|
-
const S = u.length, M = m.length;
|
|
601
|
-
this.status({
|
|
602
|
-
fill: M > 0 ? "red" : "green",
|
|
603
|
-
shape: "dot",
|
|
604
|
-
text: `bulk ${t}: ${l} records`
|
|
605
|
-
}), this.sendToPort("complete", {
|
|
606
|
-
...o,
|
|
607
|
-
payload: {
|
|
608
|
-
jobId: c.id,
|
|
609
|
-
operation: t,
|
|
610
|
-
sObjectType: i,
|
|
611
|
-
totalRecords: l,
|
|
612
|
-
successCount: S,
|
|
613
|
-
failureCount: M,
|
|
614
|
-
unprocessedCount: p.length
|
|
615
|
-
}
|
|
806
|
+
text: `query: ${r} records...`
|
|
616
807
|
});
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
808
|
+
}), o.on("end", () => c()), o.on("error", u);
|
|
809
|
+
}), this.status({
|
|
810
|
+
fill: "green",
|
|
811
|
+
shape: "dot",
|
|
812
|
+
text: `query complete: ${r} records`
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
async executeIngest(s, t, n) {
|
|
816
|
+
var d, m, g;
|
|
817
|
+
const o = await this.config.sObjectType.resolve(t);
|
|
818
|
+
this.status({
|
|
819
|
+
fill: "green",
|
|
820
|
+
shape: "dot",
|
|
821
|
+
text: `creating ${n} job...`
|
|
822
|
+
});
|
|
823
|
+
const r = s.bulk2.createJob({
|
|
824
|
+
operation: n,
|
|
825
|
+
object: o,
|
|
826
|
+
columnDelimiter: this.config.columnDelimiter,
|
|
827
|
+
lineEnding: this.config.lineEnding,
|
|
828
|
+
...n === "upsert" && this.config.externalIdField ? { externalIdFieldName: this.config.externalIdField } : {},
|
|
829
|
+
...this.config.assignmentRuleId ? { assignmentRuleId: this.config.assignmentRuleId } : {}
|
|
830
|
+
});
|
|
831
|
+
await r.open(), this.status({
|
|
832
|
+
fill: "green",
|
|
833
|
+
shape: "dot",
|
|
834
|
+
text: "uploading data..."
|
|
835
|
+
}), await r.uploadData(t.payload), this.status({
|
|
836
|
+
fill: "green",
|
|
837
|
+
shape: "dot",
|
|
838
|
+
text: "processing..."
|
|
839
|
+
}), await r.close(), await r.poll(this.config.pollInterval, this.config.pollTimeout), this.status({
|
|
840
|
+
fill: "green",
|
|
841
|
+
shape: "dot",
|
|
842
|
+
text: "retrieving results..."
|
|
843
|
+
});
|
|
844
|
+
const c = await r.getAllResults(), u = ((d = c.successfulResults) == null ? void 0 : d.length) ?? 0, l = ((m = c.failedResults) == null ? void 0 : m.length) ?? 0, p = u + l + (((g = c.unprocessedRecords) == null ? void 0 : g.length) ?? 0);
|
|
845
|
+
this.send({ ...t, payload: c }), this.status({
|
|
846
|
+
fill: l > 0 ? "red" : "green",
|
|
847
|
+
shape: "dot",
|
|
848
|
+
text: `${n} complete: ${u} ok, ${l} failed, ${p} total`
|
|
849
|
+
});
|
|
622
850
|
}
|
|
623
851
|
};
|
|
624
|
-
|
|
625
|
-
let
|
|
626
|
-
const
|
|
852
|
+
h(S, "SalesforceBulk"), a(S, "type", "salesforce-bulk"), a(S, "category", "salesforce"), a(S, "color", "#FFFFFF"), a(S, "configSchema", Te), a(S, "inputSchema", $e), a(S, "outputsSchema", Ie);
|
|
853
|
+
let M = S;
|
|
854
|
+
const Se = f(
|
|
627
855
|
{
|
|
628
856
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
629
|
-
connection: e.NodeRef(
|
|
857
|
+
connection: e.NodeRef(w, {
|
|
630
858
|
"x-nrg-form": { icon: "cloud" }
|
|
631
859
|
}),
|
|
632
860
|
sObjectType: e.TypedInput({
|
|
@@ -640,12 +868,12 @@ const ge = h(
|
|
|
640
868
|
statusPort: e.Boolean({ default: !1 })
|
|
641
869
|
},
|
|
642
870
|
{ $id: "salesforce-describe:config" }
|
|
643
|
-
),
|
|
871
|
+
), Ee = f(
|
|
644
872
|
{
|
|
645
873
|
payload: e.Any()
|
|
646
874
|
},
|
|
647
875
|
{ $id: "salesforce-describe:input" }
|
|
648
|
-
),
|
|
876
|
+
), Le = f(
|
|
649
877
|
{
|
|
650
878
|
payload: e.Object({
|
|
651
879
|
name: e.String(),
|
|
@@ -655,47 +883,47 @@ const ge = h(
|
|
|
655
883
|
})
|
|
656
884
|
},
|
|
657
885
|
{ $id: "salesforce-describe:output" }
|
|
658
|
-
),
|
|
659
|
-
async input(
|
|
660
|
-
const
|
|
661
|
-
if (!
|
|
662
|
-
this.error("No Salesforce connection configured",
|
|
886
|
+
), E = class E extends C {
|
|
887
|
+
async input(s) {
|
|
888
|
+
const t = this.config.connection;
|
|
889
|
+
if (!t) {
|
|
890
|
+
this.error("No Salesforce connection configured", s);
|
|
663
891
|
return;
|
|
664
892
|
}
|
|
665
893
|
try {
|
|
666
894
|
this.status({ fill: "green", shape: "dot", text: "describing..." });
|
|
667
|
-
const
|
|
895
|
+
const n = await t.getConnection(), o = await this.config.sObjectType.resolve(s), r = await n.sobject(o).describe();
|
|
668
896
|
this.status({
|
|
669
897
|
fill: "green",
|
|
670
898
|
shape: "dot",
|
|
671
|
-
text: `${
|
|
899
|
+
text: `${r.name}: ${r.fields.length} fields`
|
|
672
900
|
}), this.send({
|
|
673
|
-
...
|
|
901
|
+
...s,
|
|
674
902
|
payload: {
|
|
675
|
-
name:
|
|
676
|
-
fields:
|
|
677
|
-
childRelationships:
|
|
678
|
-
recordTypeInfos:
|
|
903
|
+
name: r.name,
|
|
904
|
+
fields: r.fields,
|
|
905
|
+
childRelationships: r.childRelationships,
|
|
906
|
+
recordTypeInfos: r.recordTypeInfos
|
|
679
907
|
}
|
|
680
908
|
});
|
|
681
|
-
} catch (
|
|
909
|
+
} catch (n) {
|
|
682
910
|
this.status({
|
|
683
911
|
fill: "red",
|
|
684
912
|
shape: "dot",
|
|
685
|
-
text:
|
|
913
|
+
text: n instanceof Error ? n.message : String(n)
|
|
686
914
|
}), this.error(
|
|
687
|
-
`Describe failed: ${
|
|
688
|
-
|
|
915
|
+
`Describe failed: ${n instanceof Error ? n.message : String(n)}`,
|
|
916
|
+
s
|
|
689
917
|
);
|
|
690
918
|
}
|
|
691
919
|
}
|
|
692
920
|
};
|
|
693
|
-
|
|
694
|
-
let
|
|
695
|
-
const
|
|
921
|
+
h(E, "SalesforceDescribe"), a(E, "type", "salesforce-describe"), a(E, "category", "salesforce"), a(E, "color", "#FFFFFF"), a(E, "configSchema", Se), a(E, "inputSchema", Ee), a(E, "outputsSchema", Le);
|
|
922
|
+
let B = E;
|
|
923
|
+
const Ae = f(
|
|
696
924
|
{
|
|
697
925
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
698
|
-
connection: e.NodeRef(
|
|
926
|
+
connection: e.NodeRef(w, {
|
|
699
927
|
"x-nrg-form": { icon: "cloud" }
|
|
700
928
|
}),
|
|
701
929
|
channelName: e.String({
|
|
@@ -740,7 +968,7 @@ const xe = h(
|
|
|
740
968
|
}
|
|
741
969
|
}
|
|
742
970
|
}
|
|
743
|
-
),
|
|
971
|
+
), Re = f(
|
|
744
972
|
{
|
|
745
973
|
payload: e.Any(),
|
|
746
974
|
replayId: e.Any(),
|
|
@@ -748,57 +976,57 @@ const xe = h(
|
|
|
748
976
|
topic: e.String()
|
|
749
977
|
},
|
|
750
978
|
{ $id: "salesforce-streaming:output" }
|
|
751
|
-
),
|
|
979
|
+
), A = class A extends C {
|
|
752
980
|
constructor() {
|
|
753
981
|
super(...arguments);
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
982
|
+
a(this, "client", null);
|
|
983
|
+
a(this, "reconnectAttempt", 0);
|
|
984
|
+
a(this, "maxReconnectDelay", 6e4);
|
|
985
|
+
a(this, "maxReconnectAttempts", 10);
|
|
986
|
+
a(this, "grpcErrorHandler", null);
|
|
987
|
+
a(this, "stopped", !1);
|
|
760
988
|
}
|
|
761
989
|
async created() {
|
|
762
|
-
const
|
|
763
|
-
if (!
|
|
990
|
+
const t = this.config.connection;
|
|
991
|
+
if (!t) {
|
|
764
992
|
this.status({ fill: "red", shape: "dot", text: "no connection" }), this.error("No Salesforce connection configured");
|
|
765
993
|
return;
|
|
766
994
|
}
|
|
767
|
-
await this.subscribe(
|
|
995
|
+
await this.subscribe(t);
|
|
768
996
|
}
|
|
769
|
-
async subscribe(
|
|
997
|
+
async subscribe(t) {
|
|
770
998
|
if (!this.stopped)
|
|
771
999
|
try {
|
|
772
1000
|
this.status({ fill: "green", shape: "dot", text: "connecting..." });
|
|
773
|
-
let
|
|
1001
|
+
let n;
|
|
774
1002
|
try {
|
|
775
|
-
|
|
1003
|
+
n = await t.getConnection(), await n.identity();
|
|
776
1004
|
} catch {
|
|
777
1005
|
this.status({ fill: "red", shape: "dot", text: "auth expired" }), this.error("Salesforce token expired. Re-authorize the connection.");
|
|
778
1006
|
return;
|
|
779
1007
|
}
|
|
780
|
-
const
|
|
781
|
-
if (!
|
|
1008
|
+
const o = n.accessToken, r = n.instanceUrl;
|
|
1009
|
+
if (!o || !r) {
|
|
782
1010
|
this.status({ fill: "red", shape: "dot", text: "not authorized" }), this.error("Salesforce connection not authorized");
|
|
783
1011
|
return;
|
|
784
1012
|
}
|
|
785
|
-
const
|
|
786
|
-
this.client = new
|
|
1013
|
+
const c = (await import("salesforce-pubsub-api-client")).default;
|
|
1014
|
+
this.client = new c({
|
|
787
1015
|
authType: "user-supplied",
|
|
788
|
-
accessToken:
|
|
789
|
-
instanceUrl:
|
|
1016
|
+
accessToken: o,
|
|
1017
|
+
instanceUrl: r
|
|
790
1018
|
}), await this.client.connect();
|
|
791
|
-
const
|
|
1019
|
+
const u = this.config.numRequested || null, l = this.config.channelName, p = /* @__PURE__ */ h((d, m, g) => {
|
|
792
1020
|
if (m === "event" || m === "lastevent")
|
|
793
1021
|
this.send({
|
|
794
|
-
payload: (
|
|
795
|
-
replayId:
|
|
796
|
-
channel:
|
|
797
|
-
topic:
|
|
1022
|
+
payload: (g == null ? void 0 : g.payload) ?? g,
|
|
1023
|
+
replayId: g == null ? void 0 : g.replayId,
|
|
1024
|
+
channel: l,
|
|
1025
|
+
topic: l
|
|
798
1026
|
});
|
|
799
1027
|
else if (m === "error") {
|
|
800
|
-
const
|
|
801
|
-
if (this.warn(`Streaming error: ${
|
|
1028
|
+
const x = g instanceof Error ? g.message : String(g ?? "stream error");
|
|
1029
|
+
if (this.warn(`Streaming error: ${x}`), x.includes("UNAUTHENTICATED") || x.includes("authentication")) {
|
|
802
1030
|
this.stopped = !0, this.status({
|
|
803
1031
|
fill: "red",
|
|
804
1032
|
shape: "dot",
|
|
@@ -808,51 +1036,51 @@ const xe = h(
|
|
|
808
1036
|
), this.cleanup();
|
|
809
1037
|
return;
|
|
810
1038
|
}
|
|
811
|
-
this.status({ fill: "red", shape: "dot", text:
|
|
1039
|
+
this.status({ fill: "red", shape: "dot", text: x }), this.scheduleReconnect(t);
|
|
812
1040
|
} else if (m === "end") {
|
|
813
1041
|
if (this.stopped) return;
|
|
814
|
-
this.log("Streaming subscription ended"), this.status({ fill: "red", shape: "dot", text: "disconnected" }), this.scheduleReconnect(
|
|
1042
|
+
this.log("Streaming subscription ended"), this.status({ fill: "red", shape: "dot", text: "disconnected" }), this.scheduleReconnect(t);
|
|
815
1043
|
}
|
|
816
1044
|
}, "callback");
|
|
817
|
-
if (this.grpcErrorHandler && process.removeListener("uncaughtException", this.grpcErrorHandler), this.grpcErrorHandler = (
|
|
818
|
-
var m,
|
|
819
|
-
((m =
|
|
1045
|
+
if (this.grpcErrorHandler && process.removeListener("uncaughtException", this.grpcErrorHandler), this.grpcErrorHandler = (d) => {
|
|
1046
|
+
var m, g;
|
|
1047
|
+
((m = d.message) != null && m.includes("UNAUTHENTICATED") || (g = d.message) != null && g.includes("authentication")) && (this.stopped = !0, this.warn(`Caught gRPC auth error: ${d.message}`), this.status({
|
|
820
1048
|
fill: "red",
|
|
821
1049
|
shape: "dot",
|
|
822
1050
|
text: "auth expired — re-authorize"
|
|
823
1051
|
}), this.cleanup());
|
|
824
1052
|
}, process.on("uncaughtException", this.grpcErrorHandler), this.config.subscribeType === "EARLIEST")
|
|
825
1053
|
this.client.subscribeFromEarliestEvent(
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1054
|
+
l,
|
|
1055
|
+
p,
|
|
1056
|
+
u
|
|
829
1057
|
);
|
|
830
1058
|
else if (this.config.subscribeType === "CUSTOM" && this.config.replayId) {
|
|
831
|
-
const
|
|
1059
|
+
const d = parseInt(this.config.replayId, 10);
|
|
832
1060
|
this.client.subscribeFromReplayId(
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
1061
|
+
l,
|
|
1062
|
+
p,
|
|
1063
|
+
u,
|
|
1064
|
+
d
|
|
837
1065
|
);
|
|
838
1066
|
} else
|
|
839
|
-
this.client.subscribe(
|
|
1067
|
+
this.client.subscribe(l, p, u);
|
|
840
1068
|
this.status({
|
|
841
1069
|
fill: "green",
|
|
842
1070
|
shape: "dot",
|
|
843
|
-
text: `subscribed: ${
|
|
1071
|
+
text: `subscribed: ${l}`
|
|
844
1072
|
}), this.reconnectAttempt = 0;
|
|
845
|
-
} catch (
|
|
1073
|
+
} catch (n) {
|
|
846
1074
|
this.status({
|
|
847
1075
|
fill: "red",
|
|
848
1076
|
shape: "dot",
|
|
849
|
-
text:
|
|
1077
|
+
text: n instanceof Error ? n.message : String(n)
|
|
850
1078
|
}), this.error(
|
|
851
|
-
`Streaming subscription failed: ${
|
|
852
|
-
), this.scheduleReconnect(
|
|
1079
|
+
`Streaming subscription failed: ${n instanceof Error ? n.message : String(n)}`
|
|
1080
|
+
), this.scheduleReconnect(t);
|
|
853
1081
|
}
|
|
854
1082
|
}
|
|
855
|
-
scheduleReconnect(
|
|
1083
|
+
scheduleReconnect(t) {
|
|
856
1084
|
if (this.stopped) return;
|
|
857
1085
|
if (this.reconnectAttempt++, this.reconnectAttempt > this.maxReconnectAttempts) {
|
|
858
1086
|
this.error(
|
|
@@ -864,24 +1092,24 @@ const xe = h(
|
|
|
864
1092
|
});
|
|
865
1093
|
return;
|
|
866
1094
|
}
|
|
867
|
-
const
|
|
1095
|
+
const n = Math.min(
|
|
868
1096
|
1e3 * Math.pow(2, this.reconnectAttempt),
|
|
869
1097
|
this.maxReconnectDelay
|
|
870
1098
|
);
|
|
871
1099
|
this.log(
|
|
872
|
-
`Scheduling reconnect in ${
|
|
1100
|
+
`Scheduling reconnect in ${n}ms (attempt ${this.reconnectAttempt}/${this.maxReconnectAttempts})`
|
|
873
1101
|
), this.status({
|
|
874
1102
|
fill: "green",
|
|
875
1103
|
shape: "dot",
|
|
876
|
-
text: `reconnecting in ${Math.round(
|
|
1104
|
+
text: `reconnecting in ${Math.round(n / 1e3)}s`
|
|
877
1105
|
}), this.setTimeout(async () => {
|
|
878
|
-
await this.cleanup(), await this.subscribe(
|
|
879
|
-
},
|
|
1106
|
+
await this.cleanup(), await this.subscribe(t);
|
|
1107
|
+
}, n);
|
|
880
1108
|
}
|
|
881
1109
|
async cleanup() {
|
|
882
|
-
var
|
|
1110
|
+
var t, n;
|
|
883
1111
|
try {
|
|
884
|
-
this.grpcErrorHandler && (process.removeListener("uncaughtException", this.grpcErrorHandler), this.grpcErrorHandler = null), this.client && (await ((
|
|
1112
|
+
this.grpcErrorHandler && (process.removeListener("uncaughtException", this.grpcErrorHandler), this.grpcErrorHandler = null), this.client && (await ((n = (t = this.client).close) == null ? void 0 : n.call(t)), this.client = null);
|
|
885
1113
|
} catch {
|
|
886
1114
|
}
|
|
887
1115
|
}
|
|
@@ -889,14 +1117,19 @@ const xe = h(
|
|
|
889
1117
|
await this.cleanup();
|
|
890
1118
|
}
|
|
891
1119
|
};
|
|
892
|
-
|
|
893
|
-
let
|
|
894
|
-
const
|
|
1120
|
+
h(A, "SalesforceStreaming"), a(A, "type", "salesforce-streaming"), a(A, "category", "salesforce"), a(A, "color", "#FFFFFF"), a(A, "configSchema", Ae), a(A, "outputsSchema", Re);
|
|
1121
|
+
let H = A;
|
|
1122
|
+
const Ce = f(
|
|
895
1123
|
{
|
|
896
1124
|
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
897
|
-
connection: e.NodeRef(
|
|
1125
|
+
connection: e.NodeRef(w, {
|
|
898
1126
|
"x-nrg-form": { icon: "cloud" }
|
|
899
1127
|
}),
|
|
1128
|
+
apexType: e.Union(
|
|
1129
|
+
[e.Literal("rest"), e.Literal("invocable")],
|
|
1130
|
+
{ default: "rest", "x-nrg-form": { icon: "cog" } }
|
|
1131
|
+
),
|
|
1132
|
+
// REST fields
|
|
900
1133
|
method: e.Union(
|
|
901
1134
|
[
|
|
902
1135
|
e.Literal("GET"),
|
|
@@ -913,63 +1146,329 @@ const Te = h(
|
|
|
913
1146
|
typedInputTypes: ["str", "msg"]
|
|
914
1147
|
}
|
|
915
1148
|
}),
|
|
1149
|
+
// Invocable field
|
|
1150
|
+
actionName: e.String({
|
|
1151
|
+
default: "",
|
|
1152
|
+
"x-nrg-form": { icon: "bolt" }
|
|
1153
|
+
}),
|
|
916
1154
|
errorPort: e.Boolean({ default: !1 }),
|
|
917
1155
|
completePort: e.Boolean({ default: !1 }),
|
|
918
1156
|
statusPort: e.Boolean({ default: !1 })
|
|
919
1157
|
},
|
|
920
|
-
{ $id: "salesforce-apex:config" }
|
|
921
|
-
),
|
|
1158
|
+
{ $id: "salesforce-apex-invocation:config" }
|
|
1159
|
+
), Fe = f(
|
|
1160
|
+
{ payload: e.Any() },
|
|
1161
|
+
{ $id: "salesforce-apex-invocation:input" }
|
|
1162
|
+
), ve = f(
|
|
1163
|
+
{ payload: e.Any() },
|
|
1164
|
+
{ $id: "salesforce-apex-invocation:output" }
|
|
1165
|
+
), L = class L extends C {
|
|
1166
|
+
async input(s) {
|
|
1167
|
+
const t = this.config.connection;
|
|
1168
|
+
if (!t) {
|
|
1169
|
+
this.error("No Salesforce connection configured", s);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
try {
|
|
1173
|
+
const n = await t.getConnection();
|
|
1174
|
+
if (this.status({ fill: "green", shape: "dot", text: "executing..." }), this.config.apexType === "rest") {
|
|
1175
|
+
const o = await this.config.path.resolve(s), r = this.config.method.toLowerCase();
|
|
1176
|
+
let c;
|
|
1177
|
+
r === "get" || r === "delete" ? c = await n.apex[r](o) : c = await n.apex[r](o, s.payload), this.status({
|
|
1178
|
+
fill: "green",
|
|
1179
|
+
shape: "dot",
|
|
1180
|
+
text: `${this.config.method} done`
|
|
1181
|
+
}), this.send({ ...s, payload: c });
|
|
1182
|
+
} else {
|
|
1183
|
+
const r = await new R(n).invoke(this.config.actionName, s.payload);
|
|
1184
|
+
this.status({ fill: "green", shape: "dot", text: "done" }), this.send({ ...s, payload: r.outputValues });
|
|
1185
|
+
}
|
|
1186
|
+
} catch (n) {
|
|
1187
|
+
const o = n instanceof Error ? n.message : String(n);
|
|
1188
|
+
this.status({ fill: "red", shape: "dot", text: o }), this.error(`Apex failed: ${o}`, s);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
h(L, "SalesforceApex"), a(L, "type", "salesforce-apex-invocation"), a(L, "category", "salesforce"), a(L, "color", "#FFFFFF"), a(L, "configSchema", Ce), a(L, "inputSchema", Fe), a(L, "outputsSchema", ve);
|
|
1193
|
+
let q = L;
|
|
1194
|
+
const Oe = `private static Object run(String payload) {
|
|
1195
|
+
// Your code here
|
|
1196
|
+
return payload;
|
|
1197
|
+
}`;
|
|
1198
|
+
function Ue(i, s) {
|
|
1199
|
+
return `public class ${i} {
|
|
1200
|
+
public class Input {
|
|
1201
|
+
@InvocableVariable(required=true)
|
|
1202
|
+
public String payload;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
public class Output {
|
|
1206
|
+
@InvocableVariable
|
|
1207
|
+
public String result;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
@InvocableMethod(label='${i}' description='Generated by NRG')
|
|
1211
|
+
public static List<Output> execute(List<Input> inputs) {
|
|
1212
|
+
Output out = new Output();
|
|
1213
|
+
Object returnValue = run(inputs[0].payload);
|
|
1214
|
+
out.result = returnValue instanceof String
|
|
1215
|
+
? (String) returnValue
|
|
1216
|
+
: JSON.serialize(returnValue);
|
|
1217
|
+
return new List<Output>{ out };
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
${s}
|
|
1221
|
+
}`;
|
|
1222
|
+
}
|
|
1223
|
+
h(Ue, "buildInvocableClass");
|
|
1224
|
+
const Ne = {
|
|
1225
|
+
HttpGet: "doGet",
|
|
1226
|
+
HttpPost: "doPost",
|
|
1227
|
+
HttpPut: "doPut",
|
|
1228
|
+
HttpPatch: "doPatch",
|
|
1229
|
+
HttpDelete: "doDelete"
|
|
1230
|
+
}, Pe = {
|
|
1231
|
+
HttpGet: !1,
|
|
1232
|
+
HttpPost: !0,
|
|
1233
|
+
HttpPut: !0,
|
|
1234
|
+
HttpPatch: !0,
|
|
1235
|
+
HttpDelete: !1
|
|
1236
|
+
};
|
|
1237
|
+
function ke(i, s, t, n) {
|
|
1238
|
+
const o = Ne[t], c = Pe[t] ? ` String payload = RestContext.request.requestBody != null
|
|
1239
|
+
? RestContext.request.requestBody.toString()
|
|
1240
|
+
: null;` : ` String payload = RestContext.request.params != null
|
|
1241
|
+
? JSON.serialize(RestContext.request.params)
|
|
1242
|
+
: null;`;
|
|
1243
|
+
return `@RestResource(urlMapping='${s}')
|
|
1244
|
+
global class ${i} {
|
|
1245
|
+
@${t}
|
|
1246
|
+
global static String ${o}() {
|
|
1247
|
+
${c}
|
|
1248
|
+
Object returnValue = run(payload);
|
|
1249
|
+
return returnValue instanceof String
|
|
1250
|
+
? (String) returnValue
|
|
1251
|
+
: JSON.serialize(returnValue);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
${n}
|
|
1255
|
+
}`;
|
|
1256
|
+
}
|
|
1257
|
+
h(ke, "buildRestClass");
|
|
1258
|
+
const je = f(
|
|
922
1259
|
{
|
|
923
|
-
|
|
1260
|
+
name: e.String({ default: "", "x-nrg-form": { icon: "tag" } }),
|
|
1261
|
+
connection: e.NodeRef(w, {
|
|
1262
|
+
"x-nrg-form": { icon: "cloud" }
|
|
1263
|
+
}),
|
|
1264
|
+
apexType: e.Union(
|
|
1265
|
+
[e.Literal("invocable"), e.Literal("rest")],
|
|
1266
|
+
{ default: "invocable", "x-nrg-form": { icon: "cog" } }
|
|
1267
|
+
),
|
|
1268
|
+
className: e.String({
|
|
1269
|
+
default: "",
|
|
1270
|
+
"x-nrg-form": { icon: "file-code-o" }
|
|
1271
|
+
}),
|
|
1272
|
+
urlMapping: e.String({
|
|
1273
|
+
default: "",
|
|
1274
|
+
"x-nrg-form": { icon: "link" }
|
|
1275
|
+
}),
|
|
1276
|
+
httpMethod: e.Union(
|
|
1277
|
+
[
|
|
1278
|
+
e.Literal("HttpGet"),
|
|
1279
|
+
e.Literal("HttpPost"),
|
|
1280
|
+
e.Literal("HttpPut"),
|
|
1281
|
+
e.Literal("HttpPatch"),
|
|
1282
|
+
e.Literal("HttpDelete")
|
|
1283
|
+
],
|
|
1284
|
+
{ default: "HttpPost", "x-nrg-form": { icon: "random" } }
|
|
1285
|
+
),
|
|
1286
|
+
code: e.String({
|
|
1287
|
+
default: Oe,
|
|
1288
|
+
"x-nrg-form": { editorLanguage: "apex" }
|
|
1289
|
+
}),
|
|
1290
|
+
errorPort: e.Boolean({ default: !1 }),
|
|
1291
|
+
completePort: e.Boolean({ default: !1 }),
|
|
1292
|
+
statusPort: e.Boolean({ default: !1 })
|
|
924
1293
|
},
|
|
925
|
-
{ $id: "salesforce-apex:
|
|
926
|
-
),
|
|
1294
|
+
{ $id: "salesforce-apex-code:config" }
|
|
1295
|
+
), Me = f(
|
|
927
1296
|
{
|
|
928
|
-
|
|
1297
|
+
classPrefix: e.String({ default: "NRG_" }),
|
|
1298
|
+
languageServerUrl: e.String({
|
|
1299
|
+
default: "",
|
|
1300
|
+
exportable: !0
|
|
1301
|
+
})
|
|
929
1302
|
},
|
|
930
|
-
{ $id: "salesforce-apex:
|
|
931
|
-
),
|
|
932
|
-
|
|
1303
|
+
{ $id: "salesforce-apex-code:settings" }
|
|
1304
|
+
), Be = f(
|
|
1305
|
+
{ payload: e.Any() },
|
|
1306
|
+
{ $id: "salesforce-apex-code:input" }
|
|
1307
|
+
), He = f(
|
|
1308
|
+
{ payload: e.Any() },
|
|
1309
|
+
{ $id: "salesforce-apex-code:output" }
|
|
1310
|
+
), y = class y {
|
|
1311
|
+
constructor(s) {
|
|
1312
|
+
a(this, "pendingDeploys", /* @__PURE__ */ new Map());
|
|
1313
|
+
a(this, "pendingDeletes", /* @__PURE__ */ new Set());
|
|
1314
|
+
a(this, "flushTimer", null);
|
|
1315
|
+
a(this, "connectionProvider");
|
|
1316
|
+
this.connectionProvider = s;
|
|
1317
|
+
}
|
|
1318
|
+
static getInstance(s, t) {
|
|
1319
|
+
return y.instances.has(s) || y.instances.set(
|
|
1320
|
+
s,
|
|
1321
|
+
new y(t)
|
|
1322
|
+
), y.instances.get(s);
|
|
1323
|
+
}
|
|
1324
|
+
static removeInstance(s) {
|
|
1325
|
+
y.instances.delete(s);
|
|
1326
|
+
}
|
|
1327
|
+
register(s, t) {
|
|
1328
|
+
return this.pendingDeletes.delete(s), new Promise((n, o) => {
|
|
1329
|
+
this.pendingDeploys.set(s, { className: s, body: t, resolve: n, reject: o }), this.scheduleFlush();
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
unregister(s) {
|
|
1333
|
+
const t = this.pendingDeploys.get(s);
|
|
1334
|
+
t && (t.reject(new Error("Deploy cancelled — node was removed")), this.pendingDeploys.delete(s)), this.pendingDeletes.add(s), this.scheduleFlush();
|
|
1335
|
+
}
|
|
1336
|
+
scheduleFlush() {
|
|
1337
|
+
this.flushTimer || (this.flushTimer = setTimeout(() => {
|
|
1338
|
+
this.flushTimer = null, this.flush().catch((s) => {
|
|
1339
|
+
console.error("[ApexClassManager] flush error:", s);
|
|
1340
|
+
});
|
|
1341
|
+
}, y.FLUSH_DELAY_MS));
|
|
1342
|
+
}
|
|
1343
|
+
async flush() {
|
|
1344
|
+
const s = new Set(this.pendingDeletes), t = new Map(this.pendingDeploys);
|
|
1345
|
+
if (this.pendingDeletes.clear(), this.pendingDeploys.clear(), s.size === 0 && t.size === 0) return;
|
|
1346
|
+
const n = await this.connectionProvider.getConnection(), o = new R(n), r = [...s, ...t.keys()], c = await o.queryApexClassesByName(r);
|
|
1347
|
+
for (const u of s) {
|
|
1348
|
+
const l = c.get(u);
|
|
1349
|
+
if (l)
|
|
1350
|
+
try {
|
|
1351
|
+
await o.deleteApexClass(l.Id);
|
|
1352
|
+
} catch (p) {
|
|
1353
|
+
console.error(`[ApexClassManager] Failed to delete ${u}:`, p);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
for (const [u, l] of t)
|
|
1357
|
+
try {
|
|
1358
|
+
const p = c.get(u);
|
|
1359
|
+
if (p) {
|
|
1360
|
+
if (p.Body === l.body) {
|
|
1361
|
+
l.resolve({ id: p.Id });
|
|
1362
|
+
continue;
|
|
1363
|
+
}
|
|
1364
|
+
await o.deleteApexClass(p.Id);
|
|
1365
|
+
}
|
|
1366
|
+
const { id: d } = await o.createApexClass(u, l.body);
|
|
1367
|
+
l.resolve({ id: d });
|
|
1368
|
+
} catch (p) {
|
|
1369
|
+
l.reject(p instanceof Error ? p : new Error(String(p)));
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
h(y, "ApexClassManager"), a(y, "instances", /* @__PURE__ */ new Map()), a(y, "FLUSH_DELAY_MS", 500);
|
|
1374
|
+
let N = y;
|
|
1375
|
+
const b = class b extends C {
|
|
1376
|
+
constructor() {
|
|
1377
|
+
super(...arguments);
|
|
1378
|
+
a(this, "deployed", !1);
|
|
1379
|
+
}
|
|
1380
|
+
getFullClassName() {
|
|
1381
|
+
return `${this.settings.classPrefix}${this.config.className}`;
|
|
1382
|
+
}
|
|
1383
|
+
buildApexBody() {
|
|
1384
|
+
const t = this.getFullClassName();
|
|
1385
|
+
return this.config.apexType === "rest" ? ke(
|
|
1386
|
+
t,
|
|
1387
|
+
this.config.urlMapping,
|
|
1388
|
+
this.config.httpMethod,
|
|
1389
|
+
this.config.code
|
|
1390
|
+
) : Ue(t, this.config.code);
|
|
1391
|
+
}
|
|
1392
|
+
async created() {
|
|
1393
|
+
const t = this.config.connection;
|
|
1394
|
+
if (!t) {
|
|
1395
|
+
this.status({ fill: "red", shape: "dot", text: "no connection" });
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
if (!this.config.className) {
|
|
1399
|
+
this.status({ fill: "red", shape: "dot", text: "class name required" });
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
const n = N.getInstance(
|
|
1403
|
+
t.id,
|
|
1404
|
+
t
|
|
1405
|
+
);
|
|
1406
|
+
this.status({ fill: "green", shape: "dot", text: "deploying..." }), n.register(this.getFullClassName(), this.buildApexBody()).then(() => {
|
|
1407
|
+
this.deployed = !0, this.status({ fill: "green", shape: "dot", text: "deployed" });
|
|
1408
|
+
}).catch((o) => {
|
|
1409
|
+
const r = o instanceof Error ? o.message : String(o);
|
|
1410
|
+
this.status({ fill: "red", shape: "dot", text: r }), this.error(`Apex deploy failed: ${r}`);
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
async input(t) {
|
|
1414
|
+
if (!this.deployed) {
|
|
1415
|
+
this.error(
|
|
1416
|
+
"Apex class not yet deployed — wait for deployment to complete",
|
|
1417
|
+
t
|
|
1418
|
+
);
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
933
1421
|
const n = this.config.connection;
|
|
934
1422
|
if (!n) {
|
|
935
|
-
this.error("No Salesforce connection configured",
|
|
1423
|
+
this.error("No Salesforce connection configured", t);
|
|
936
1424
|
return;
|
|
937
1425
|
}
|
|
938
1426
|
try {
|
|
939
|
-
const
|
|
940
|
-
this.status({ fill: "green", shape: "dot", text:
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
);
|
|
1427
|
+
const o = await n.getConnection(), r = new R(o);
|
|
1428
|
+
if (this.status({ fill: "green", shape: "dot", text: "executing..." }), this.config.apexType === "invocable") {
|
|
1429
|
+
const c = await r.invoke(
|
|
1430
|
+
this.getFullClassName(),
|
|
1431
|
+
t.payload
|
|
1432
|
+
);
|
|
1433
|
+
this.status({ fill: "green", shape: "dot", text: "done" }), this.send({ ...t, payload: c.outputValues });
|
|
1434
|
+
} else {
|
|
1435
|
+
const c = this.config.urlMapping, u = this.config.httpMethod;
|
|
1436
|
+
let l;
|
|
1437
|
+
u === "HttpGet" || u === "HttpDelete" ? l = u === "HttpGet" ? await r.get(c) : await r.delete(c) : l = await r[u === "HttpPut" ? "put" : u === "HttpPatch" ? "patch" : "post"](c, t.payload), this.status({ fill: "green", shape: "dot", text: "done" }), this.send({ ...t, payload: l });
|
|
1438
|
+
}
|
|
1439
|
+
} catch (o) {
|
|
1440
|
+
const r = o instanceof Error ? o.message : String(o);
|
|
1441
|
+
this.status({ fill: "red", shape: "dot", text: r }), this.error(`Apex execution failed: ${r}`, t);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
async closed(t) {
|
|
1445
|
+
if (t) {
|
|
1446
|
+
const n = this.config.connection;
|
|
1447
|
+
n && N.getInstance(
|
|
1448
|
+
n.id,
|
|
1449
|
+
n
|
|
1450
|
+
).unregister(this.getFullClassName());
|
|
954
1451
|
}
|
|
1452
|
+
this.deployed = !1;
|
|
955
1453
|
}
|
|
956
1454
|
};
|
|
957
|
-
|
|
958
|
-
let
|
|
959
|
-
const
|
|
1455
|
+
h(b, "SalesforceApexCode"), a(b, "type", "salesforce-apex-code"), a(b, "category", "salesforce"), a(b, "color", "#FFFFFF"), a(b, "configSchema", je), a(b, "inputSchema", Be), a(b, "outputsSchema", He), a(b, "settingsSchema", Me);
|
|
1456
|
+
let D = b;
|
|
1457
|
+
const qe = ee({
|
|
960
1458
|
nodes: [
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
C,
|
|
964
|
-
O,
|
|
965
|
-
P,
|
|
1459
|
+
w,
|
|
1460
|
+
k,
|
|
966
1461
|
j,
|
|
967
|
-
|
|
1462
|
+
M,
|
|
1463
|
+
B,
|
|
1464
|
+
H,
|
|
1465
|
+
q,
|
|
1466
|
+
D
|
|
968
1467
|
]
|
|
969
1468
|
});
|
|
970
|
-
var
|
|
971
|
-
|
|
1469
|
+
var O = qe;
|
|
1470
|
+
O && typeof O == "object" && Array.isArray(O.nodes) && (O = Z(O.nodes));
|
|
972
1471
|
export {
|
|
973
|
-
|
|
1472
|
+
O as default
|
|
974
1473
|
};
|
|
975
1474
|
//# sourceMappingURL=index.mjs.map
|