@salesforce/sdk-data 1.90.2 → 1.90.3
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/dist/index.js +286 -52
- package/dist/webapp/csrf/header.interceptor.d.ts +13 -0
- package/dist/webapp/csrf/header.interceptor.d.ts.map +1 -0
- package/dist/webapp/csrf/retry.interceptor.d.ts +8 -0
- package/dist/webapp/csrf/retry.interceptor.d.ts.map +1 -0
- package/dist/webapp/csrf/retry.policy.d.ts +38 -0
- package/dist/webapp/csrf/retry.policy.d.ts.map +1 -0
- package/dist/webapp/csrf/token-manager.d.ts +40 -0
- package/dist/webapp/csrf/token-manager.d.ts.map +1 -0
- package/dist/webapp/fetch.d.ts +20 -0
- package/dist/webapp/fetch.d.ts.map +1 -0
- package/dist/webapp/index.d.ts +1 -1
- package/dist/webapp/index.d.ts.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,42 +1,276 @@
|
|
|
1
|
-
import { getSurface as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
...n != null ? { variables: n } : {}
|
|
1
|
+
import { getSurface as T, Surface as h } from "@salesforce/sdk-core";
|
|
2
|
+
const m = "salesforce_graphql";
|
|
3
|
+
class v {
|
|
4
|
+
async graphql(e, r) {
|
|
5
|
+
return (await window.openai.callTool(m, {
|
|
6
|
+
query: e,
|
|
7
|
+
...r != null ? { variables: r } : {}
|
|
9
8
|
})).structuredContent;
|
|
10
9
|
}
|
|
11
10
|
}
|
|
12
|
-
|
|
11
|
+
function o(t) {
|
|
12
|
+
return R(t) ? t.then((e) => e) : {
|
|
13
|
+
then: (e, r) => {
|
|
14
|
+
try {
|
|
15
|
+
return o(e(t));
|
|
16
|
+
} catch (n) {
|
|
17
|
+
return e === void 0 ? o(t) : p(n);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function p(t) {
|
|
23
|
+
return R(t) ? t.then((e) => e) : {
|
|
24
|
+
then: (e, r) => {
|
|
25
|
+
if (typeof r == "function")
|
|
26
|
+
try {
|
|
27
|
+
return o(r(t));
|
|
28
|
+
} catch (n) {
|
|
29
|
+
return p(n);
|
|
30
|
+
}
|
|
31
|
+
return p(t);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function R(t) {
|
|
36
|
+
return typeof t?.then == "function";
|
|
37
|
+
}
|
|
38
|
+
function A(t = {
|
|
39
|
+
request: [],
|
|
40
|
+
retry: void 0,
|
|
41
|
+
response: [],
|
|
42
|
+
finally: []
|
|
43
|
+
}, e) {
|
|
44
|
+
return {
|
|
45
|
+
type: "fetch",
|
|
46
|
+
version: "1.0",
|
|
47
|
+
service: function(...r) {
|
|
48
|
+
var n;
|
|
49
|
+
const s = (n = t.createContext) == null ? void 0 : n.call(t), {
|
|
50
|
+
request: a = [],
|
|
51
|
+
retry: c = void 0,
|
|
52
|
+
response: u = [],
|
|
53
|
+
finally: w = []
|
|
54
|
+
} = t, P = a.reduce(
|
|
55
|
+
(i, l) => i.then((y) => l(y, s)),
|
|
56
|
+
o(r)
|
|
57
|
+
);
|
|
58
|
+
return Promise.resolve(P).then((i) => c ? c(i, e, s) : e ? e.applyRetry(() => fetch(...i)) : fetch(...i)).then((i) => u.reduce(
|
|
59
|
+
(l, y) => l.then((k) => y(k, s)),
|
|
60
|
+
o(i)
|
|
61
|
+
)).finally(() => {
|
|
62
|
+
if (w.length > 0)
|
|
63
|
+
return w.reduce(
|
|
64
|
+
(i, l) => i.then(() => l(s)),
|
|
65
|
+
Promise.resolve()
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function C(t, e, [r, n = {}], {
|
|
72
|
+
throwOnExisting: s = !1,
|
|
73
|
+
errorMessage: a = `Unexpected ${t} header encountered`
|
|
74
|
+
} = {}) {
|
|
75
|
+
let c = !1;
|
|
76
|
+
if (r instanceof Request && !n?.headers) {
|
|
77
|
+
if (s && r.headers.has(t))
|
|
78
|
+
throw new Error(a);
|
|
79
|
+
r.headers.set(t, e), c = !0;
|
|
80
|
+
}
|
|
81
|
+
if (n?.headers instanceof Headers) {
|
|
82
|
+
if (s && n.headers.has(t))
|
|
83
|
+
throw new Error(a);
|
|
84
|
+
n.headers.set(t, e);
|
|
85
|
+
} else {
|
|
86
|
+
if (s && n?.headers && Reflect.has(n.headers, t))
|
|
87
|
+
throw new Error(a);
|
|
88
|
+
c || (n.headers = {
|
|
89
|
+
...n?.headers,
|
|
90
|
+
[t]: e
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return [r, n];
|
|
94
|
+
}
|
|
13
95
|
class E {
|
|
96
|
+
constructor(e) {
|
|
97
|
+
this.defaultRetryPolicy = e;
|
|
98
|
+
}
|
|
99
|
+
applyRetry(e, r) {
|
|
100
|
+
return this.retry(e, r || this.defaultRetryPolicy);
|
|
101
|
+
}
|
|
102
|
+
async retry(e, r) {
|
|
103
|
+
const n = Date.now();
|
|
104
|
+
let s = 0, a = await e(), c = {
|
|
105
|
+
attempt: s,
|
|
106
|
+
totalElapsedMs: Date.now() - n,
|
|
107
|
+
lastResult: a
|
|
108
|
+
};
|
|
109
|
+
for (; await r.shouldRetry(a, c); ) {
|
|
110
|
+
const u = await r.calculateDelay(a, c);
|
|
111
|
+
await this.delay(u), r.prepareRetry && await r.prepareRetry(a, c), s++, a = await e(), c = {
|
|
112
|
+
attempt: s,
|
|
113
|
+
totalElapsedMs: Date.now() - n,
|
|
114
|
+
lastResult: a
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return a;
|
|
118
|
+
}
|
|
119
|
+
delay(e) {
|
|
120
|
+
return new Promise((r) => {
|
|
121
|
+
setTimeout(r, e);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
class I {
|
|
126
|
+
}
|
|
127
|
+
function b(t) {
|
|
128
|
+
return {
|
|
129
|
+
version: "1.0",
|
|
130
|
+
service: new E(t),
|
|
131
|
+
type: "retry"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const _ = "X-CSRF-Token";
|
|
135
|
+
function D(t, e = {}) {
|
|
136
|
+
const { protectedUrls: r = [] } = e;
|
|
137
|
+
return async (n) => {
|
|
138
|
+
const [s, a] = n, c = new Request(s, a);
|
|
139
|
+
if (q(c.method) && g(r, c.url) && !c.headers.has(_)) {
|
|
140
|
+
const u = await t.getToken();
|
|
141
|
+
n = C(_, u, n);
|
|
142
|
+
}
|
|
143
|
+
return o(n);
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function q(t) {
|
|
147
|
+
const e = t.toLowerCase();
|
|
148
|
+
return e === "post" || e === "put" || e === "patch" || e === "delete";
|
|
149
|
+
}
|
|
150
|
+
function g(t, e) {
|
|
151
|
+
const r = new URL(e);
|
|
152
|
+
return t.some((n) => r.pathname.includes(n));
|
|
153
|
+
}
|
|
154
|
+
function F(t, e = {}) {
|
|
155
|
+
const r = D(t, e);
|
|
156
|
+
async function n(s) {
|
|
157
|
+
const a = await r(s);
|
|
158
|
+
return fetch(a[0], a[1]);
|
|
159
|
+
}
|
|
160
|
+
return (s, a) => a ? a.applyRetry(async () => n(s)) : n(s);
|
|
161
|
+
}
|
|
162
|
+
class H extends I {
|
|
163
|
+
constructor(e) {
|
|
164
|
+
super(e), this.csrfTokenManager = e;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Determines if a failed request should be retried due to CSRF token issues.
|
|
168
|
+
*/
|
|
169
|
+
async shouldRetry(e, r) {
|
|
170
|
+
return r.attempt >= 1 || e.status !== 400 ? !1 : await M(e);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* CSRF token refresh should happen immediately with no delay.
|
|
174
|
+
*/
|
|
175
|
+
async calculateDelay(e, r) {
|
|
176
|
+
return 0;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Called by retry service before each retry attempt.
|
|
180
|
+
*
|
|
181
|
+
* @param _result - The failed response that triggered the retry (unused, already validated)
|
|
182
|
+
* @param _context - Current retry context (unused but part of interface)
|
|
183
|
+
*/
|
|
184
|
+
async prepareRetry(e, r) {
|
|
185
|
+
await this.csrfTokenManager.refreshToken();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async function M(t) {
|
|
189
|
+
try {
|
|
190
|
+
return (await t.clone().json())[0]?.errorCode === "INVALID_ACCESS_TOKEN";
|
|
191
|
+
} catch {
|
|
192
|
+
return !1;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
class O {
|
|
196
|
+
constructor(e, r) {
|
|
197
|
+
this.endpoint = e, this.cacheName = r, this.tokenPromise = this.obtainToken();
|
|
198
|
+
}
|
|
199
|
+
tokenPromise;
|
|
200
|
+
/**
|
|
201
|
+
* Returns the current token value as a Promise.
|
|
202
|
+
* Lazy-loads the token on first call (from cache or by fetching).
|
|
203
|
+
*/
|
|
204
|
+
async getToken() {
|
|
205
|
+
return this.tokenPromise;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Obtains and returns a new token value as a promise.
|
|
209
|
+
* This will clear the cached token and fetch a fresh one.
|
|
210
|
+
*/
|
|
211
|
+
async refreshToken() {
|
|
212
|
+
return await this.withCache((e) => e.delete(this.endpoint)), this.tokenPromise = this.obtainToken(), this.tokenPromise;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Obtains a CSRF token, using cache when available or fetching a new one.
|
|
216
|
+
*
|
|
217
|
+
* @returns Promise that resolves to the CSRF token string
|
|
218
|
+
*/
|
|
219
|
+
async obtainToken() {
|
|
220
|
+
let e = await this.withCache((s) => s.match(this.endpoint)), r = !1;
|
|
221
|
+
e || (e = await fetch(this.endpoint, { method: "get" }), r = !0);
|
|
222
|
+
const n = (await e.clone().json()).csrfToken;
|
|
223
|
+
return r && await this.withCache((s) => s.put(this.endpoint, e)), n;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Provides a safe way to interact with the Cache API with fallback for unsupported environments.
|
|
227
|
+
*
|
|
228
|
+
* @param callback - Function that receives the cache instance and returns a promise
|
|
229
|
+
* @returns The result of the callback, or undefined if caches API is not available
|
|
230
|
+
*/
|
|
231
|
+
async withCache(e) {
|
|
232
|
+
if (this.cacheName && caches) {
|
|
233
|
+
const r = await caches.open(this.cacheName);
|
|
234
|
+
return e(r);
|
|
235
|
+
} else
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function $(t) {
|
|
240
|
+
const e = t.csrf, r = new O(e.endpoint, e.cacheName);
|
|
241
|
+
return A(
|
|
242
|
+
{ retry: F(r, e) },
|
|
243
|
+
b(new H(r)).service
|
|
244
|
+
).service;
|
|
245
|
+
}
|
|
246
|
+
const N = 1, L = `@salesforce/sdk-data_v${N}`, j = typeof __SF_API_VERSION__ < "u" ? __SF_API_VERSION__ : "65.0", B = typeof __SF_SERVER_BASE_PATH__ < "u" ? __SF_SERVER_BASE_PATH__ : "", S = `/services/data/v${j}`, U = `${S}/ui-api`;
|
|
247
|
+
class x {
|
|
14
248
|
base;
|
|
15
|
-
|
|
249
|
+
clientFetch;
|
|
16
250
|
on401;
|
|
17
251
|
on403;
|
|
18
|
-
constructor(
|
|
19
|
-
this.base =
|
|
252
|
+
constructor(e) {
|
|
253
|
+
this.base = e?.basePath ?? B, this.on401 = e?.on401, this.on403 = e?.on403, this.clientFetch = $({
|
|
20
254
|
csrf: {
|
|
21
|
-
endpoint: `${this.base}${
|
|
22
|
-
cacheName:
|
|
255
|
+
endpoint: `${this.base}${U}/session/csrf`,
|
|
256
|
+
cacheName: L,
|
|
23
257
|
protectedUrls: ["/services/data/v"]
|
|
24
258
|
}
|
|
25
|
-
})
|
|
259
|
+
});
|
|
26
260
|
}
|
|
27
|
-
async graphql(
|
|
28
|
-
return (await this.fetch(`${
|
|
261
|
+
async graphql(e, r) {
|
|
262
|
+
return (await this.fetch(`${S}/graphql`, {
|
|
29
263
|
method: "POST",
|
|
30
|
-
body: JSON.stringify({ query:
|
|
264
|
+
body: JSON.stringify({ query: e, variables: r }),
|
|
31
265
|
headers: {
|
|
32
266
|
"Content-Type": "application/json",
|
|
33
267
|
Accept: "application/json"
|
|
34
268
|
}
|
|
35
269
|
})).json();
|
|
36
270
|
}
|
|
37
|
-
async fetch(
|
|
38
|
-
const
|
|
39
|
-
switch (
|
|
271
|
+
async fetch(e, r) {
|
|
272
|
+
const n = this.applySalesforceBase(e), s = await this.clientFetch(n, r);
|
|
273
|
+
switch (s.status) {
|
|
40
274
|
case 401:
|
|
41
275
|
await this.on401?.();
|
|
42
276
|
break;
|
|
@@ -44,50 +278,50 @@ class E {
|
|
|
44
278
|
await this.on403?.();
|
|
45
279
|
break;
|
|
46
280
|
}
|
|
47
|
-
return
|
|
281
|
+
return s;
|
|
48
282
|
}
|
|
49
283
|
/**
|
|
50
284
|
* If the url is relative, convert to it to an absolute Salesforce URL. This is due to the way Code
|
|
51
285
|
* Builder deployments structure the url for Salesforce
|
|
52
286
|
*/
|
|
53
|
-
applySalesforceBase(
|
|
54
|
-
return typeof
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function
|
|
58
|
-
let
|
|
59
|
-
for (let
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
async function
|
|
64
|
-
switch (
|
|
65
|
-
case
|
|
66
|
-
return new
|
|
67
|
-
case
|
|
68
|
-
case
|
|
69
|
-
return new
|
|
70
|
-
case
|
|
287
|
+
applySalesforceBase(e) {
|
|
288
|
+
return typeof e == "string" ? e.startsWith("http") ? e : this.base + e : e;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function W(t, ...e) {
|
|
292
|
+
let r = t[0] ?? "";
|
|
293
|
+
for (let n = 0; n < e.length; n += 1)
|
|
294
|
+
r += String(e[n]) + (t[n + 1] ?? "");
|
|
295
|
+
return r;
|
|
296
|
+
}
|
|
297
|
+
async function K(t) {
|
|
298
|
+
switch (T(t?.surface)) {
|
|
299
|
+
case h.OpenAI:
|
|
300
|
+
return new v();
|
|
301
|
+
case h.WebApp:
|
|
302
|
+
case h.MicroFrontend:
|
|
303
|
+
return new x(t?.webapp);
|
|
304
|
+
case h.SalesforceACC:
|
|
71
305
|
return {};
|
|
72
|
-
case
|
|
306
|
+
case h.MCPApps:
|
|
73
307
|
return {};
|
|
74
308
|
default:
|
|
75
309
|
return {};
|
|
76
310
|
}
|
|
77
311
|
}
|
|
78
|
-
let
|
|
79
|
-
async function
|
|
80
|
-
if (
|
|
81
|
-
return
|
|
82
|
-
|
|
312
|
+
let f = null, d = null;
|
|
313
|
+
async function z(t) {
|
|
314
|
+
if (f)
|
|
315
|
+
return f;
|
|
316
|
+
d || (d = K(t));
|
|
83
317
|
try {
|
|
84
|
-
return
|
|
85
|
-
} catch (
|
|
86
|
-
throw
|
|
318
|
+
return f = await d, f;
|
|
319
|
+
} catch (e) {
|
|
320
|
+
throw d = null, e;
|
|
87
321
|
}
|
|
88
322
|
}
|
|
89
323
|
export {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
324
|
+
K as createDataSDK,
|
|
325
|
+
z as getDataSDK,
|
|
326
|
+
W as gql
|
|
93
327
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RequestInterceptor } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
import { CsrfTokenManager } from './token-manager';
|
|
3
|
+
export interface HeaderInterceptorConfig {
|
|
4
|
+
protectedUrls?: string[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Builds a configured interceptor for applying CSRF header to requests
|
|
8
|
+
*
|
|
9
|
+
* @param csrfTokenManager
|
|
10
|
+
* @param config
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildInterceptor(csrfTokenManager: CsrfTokenManager, config?: HeaderInterceptorConfig): RequestInterceptor;
|
|
13
|
+
//# sourceMappingURL=header.interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header.interceptor.d.ts","sourceRoot":"","sources":["../../../src/webapp/csrf/header.interceptor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,MAAM,WAAW,uBAAuB;IACvC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC/B,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,GAAE,uBAA4B,GAClC,kBAAkB,CAmBpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FetchParameters } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
import { RetryService } from '@conduit-client/service-retry/v1';
|
|
3
|
+
import { HeaderInterceptorConfig } from './header.interceptor';
|
|
4
|
+
import { CsrfTokenManager } from './token-manager';
|
|
5
|
+
export interface RetryInterceptorConfig extends HeaderInterceptorConfig {
|
|
6
|
+
}
|
|
7
|
+
export declare function buildInterceptor(csrfTokenManager: CsrfTokenManager, config?: RetryInterceptorConfig): (fetchArgs: FetchParameters, retryService?: RetryService<Response>) => Promise<Response>;
|
|
8
|
+
//# sourceMappingURL=retry.interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.interceptor.d.ts","sourceRoot":"","sources":["../../../src/webapp/csrf/retry.interceptor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;CAAG;AAE1E,wBAAgB,gBAAgB,CAC/B,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,GAAE,sBAA2B,IAc3B,WAAW,eAAe,EAAE,eAAe,YAAY,CAAC,QAAQ,CAAC,uBAWzE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { RetryPolicy, RetryContext } from '@conduit-client/service-retry/v1';
|
|
2
|
+
import { CsrfTokenManager } from './token-manager';
|
|
3
|
+
/**
|
|
4
|
+
* Retry policy that handles CSRF token expiration errors.
|
|
5
|
+
*
|
|
6
|
+
* When a request fails with a CSRF token error this policy will:
|
|
7
|
+
* 1. Detect the error condition in shouldRetry
|
|
8
|
+
* 2. Refresh the CSRF token in prepareRetry hook
|
|
9
|
+
* 3. Retry the request once (maxRetries = 1)
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export declare class CsrfTokenRetryPolicy extends RetryPolicy<Response> {
|
|
13
|
+
private csrfTokenManager;
|
|
14
|
+
constructor(csrfTokenManager: CsrfTokenManager);
|
|
15
|
+
/**
|
|
16
|
+
* Determines if a failed request should be retried due to CSRF token issues.
|
|
17
|
+
*/
|
|
18
|
+
shouldRetry(result: Response, context: RetryContext<Response>): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* CSRF token refresh should happen immediately with no delay.
|
|
21
|
+
*/
|
|
22
|
+
calculateDelay(_result: Response, _context: RetryContext<Response>): Promise<number>;
|
|
23
|
+
/**
|
|
24
|
+
* Called by retry service before each retry attempt.
|
|
25
|
+
*
|
|
26
|
+
* @param _result - The failed response that triggered the retry (unused, already validated)
|
|
27
|
+
* @param _context - Current retry context (unused but part of interface)
|
|
28
|
+
*/
|
|
29
|
+
prepareRetry(_result: Response, _context: RetryContext<Response>): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Helper to check if a response indicates a CSRF token error.
|
|
33
|
+
*
|
|
34
|
+
* @param response - The response to check
|
|
35
|
+
* @returns true if the response indicates a CSRF token error (INVALID_ACCESS_TOKEN)
|
|
36
|
+
*/
|
|
37
|
+
export declare function isCsrfError(response: Response): Promise<boolean>;
|
|
38
|
+
//# sourceMappingURL=retry.policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.policy.d.ts","sourceRoot":"","sources":["../../../src/webapp/csrf/retry.policy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD;;;;;;;;GAQG;AACH,qBAAa,oBAAqB,SAAQ,WAAW,CAAC,QAAQ,CAAC;IAClD,OAAO,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,gBAAgB;IAKtD;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBtF;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1F;;;;;OAKG;IACY,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAI/F;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAYtE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Manages CSRF token fetching and caching for secure requests.
|
|
8
|
+
* Implements a singleton pattern to ensure consistent token management across the application.
|
|
9
|
+
*/
|
|
10
|
+
declare class CsrfTokenManager {
|
|
11
|
+
private endpoint;
|
|
12
|
+
private cacheName?;
|
|
13
|
+
private tokenPromise;
|
|
14
|
+
constructor(endpoint: string, cacheName?: string | undefined);
|
|
15
|
+
/**
|
|
16
|
+
* Returns the current token value as a Promise.
|
|
17
|
+
* Lazy-loads the token on first call (from cache or by fetching).
|
|
18
|
+
*/
|
|
19
|
+
getToken(): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Obtains and returns a new token value as a promise.
|
|
22
|
+
* This will clear the cached token and fetch a fresh one.
|
|
23
|
+
*/
|
|
24
|
+
refreshToken(): Promise<string | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Obtains a CSRF token, using cache when available or fetching a new one.
|
|
27
|
+
*
|
|
28
|
+
* @returns Promise that resolves to the CSRF token string
|
|
29
|
+
*/
|
|
30
|
+
private obtainToken;
|
|
31
|
+
/**
|
|
32
|
+
* Provides a safe way to interact with the Cache API with fallback for unsupported environments.
|
|
33
|
+
*
|
|
34
|
+
* @param callback - Function that receives the cache instance and returns a promise
|
|
35
|
+
* @returns The result of the callback, or undefined if caches API is not available
|
|
36
|
+
*/
|
|
37
|
+
private withCache;
|
|
38
|
+
}
|
|
39
|
+
export { CsrfTokenManager };
|
|
40
|
+
//# sourceMappingURL=token-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../../src/webapp/csrf/token-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,cAAM,gBAAgB;IAIpB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS,CAAC;IAJnB,OAAO,CAAC,YAAY,CAAkB;gBAG7B,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,YAAA;IAK3B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAUjD;;;;OAIG;YACW,WAAW;IAsBzB;;;;;OAKG;YACW,SAAS;CASvB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FetchService } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
import { RetryInterceptorConfig } from './csrf/retry.interceptor';
|
|
3
|
+
interface CsrfConfig extends RetryInterceptorConfig {
|
|
4
|
+
endpoint: string;
|
|
5
|
+
cacheName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FetchConfig {
|
|
8
|
+
csrf: CsrfConfig;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates an enhanced fetch function with automatic CSRF token handling.
|
|
12
|
+
* The returned function automatically adds CSRF tokens to protected requests
|
|
13
|
+
* and handles token refresh when tokens become invalid.
|
|
14
|
+
*
|
|
15
|
+
* @param config - Optional configuration for CSRF handling
|
|
16
|
+
* @returns An enhanced fetch function that handles CSRF protection
|
|
17
|
+
*/
|
|
18
|
+
export declare function createFetchService(config: FetchConfig): FetchService;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/webapp/fetch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,YAAY,EACjB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,0BAA0B,CAAC;AAIlC,UAAU,UAAW,SAAQ,sBAAsB;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,UAAU,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAQpE"}
|
package/dist/webapp/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const API_VERSION: string;
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class WebAppDataSDK implements DataSDK {
|
|
8
8
|
private readonly base;
|
|
9
|
-
private readonly
|
|
9
|
+
private readonly clientFetch;
|
|
10
10
|
private readonly on401?;
|
|
11
11
|
private readonly on403?;
|
|
12
12
|
constructor(options?: WebAppDataSDKOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webapp/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webapp/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AASrD,eAAO,MAAM,WAAW,QAA0E,CAAC;AAKnG;;GAEG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC5C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAgC;gBAE3C,OAAO,CAAC,EAAE,oBAAoB;IAcpC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAaxE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiBjF;;;OAGG;IACH,OAAO,CAAC,mBAAmB;CAY3B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sdk-data",
|
|
3
|
-
"version": "1.90.
|
|
3
|
+
"version": "1.90.3",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
"test:coverage": "vitest run --coverage"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@conduit-client/
|
|
30
|
-
"@
|
|
29
|
+
"@conduit-client/service-fetch-network": "3.17.0",
|
|
30
|
+
"@conduit-client/utils": "3.17.0",
|
|
31
|
+
"@salesforce/sdk-core": "^1.90.3"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"vite": "^7.3.1",
|