@foir/sdk 0.10.0 → 0.12.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/CHANGELOG.md +353 -2
- package/README.md +10 -2
- package/dist/app/client.d.ts +371 -0
- package/dist/app/contract/index.d.ts +23 -0
- package/dist/app/contract/proto/apps/v1/apps_pb.d.ts +1465 -0
- package/dist/app/contract/proto/apps/v1/discovery_pb.d.ts +678 -0
- package/dist/app/dispatch.d.ts +64 -0
- package/dist/app/errors.d.ts +50 -0
- package/dist/app/index.d.ts +40 -0
- package/dist/app/manifest.d.ts +56 -0
- package/dist/app/naming.d.ts +31 -0
- package/dist/app/record-key.d.ts +17 -0
- package/dist/app/ticket.d.ts +37 -0
- package/dist/app/vocabulary.generated.d.ts +20 -0
- package/dist/app-contract.js +124 -0
- package/dist/app.js +998 -0
- package/dist/auth/auth.d.ts +24 -6
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/ops.d.ts +8 -0
- package/dist/auth.js +230 -60
- package/dist/client.js +80 -15
- package/dist/codegen/preset.d.ts +3 -2
- package/dist/data/builtins.d.ts +17 -1
- package/dist/data/client.d.ts +10 -8
- package/dist/data/document.d.ts +13 -0
- package/dist/data/index.d.ts +15 -5
- package/dist/data/manifest.d.ts +31 -3
- package/dist/data/schema.d.ts +16 -9
- package/dist/data/selection.d.ts +15 -0
- package/dist/data/transport.d.ts +277 -23
- package/dist/data/ws-transport.d.ts +8 -2
- package/dist/data.js +313 -72
- package/dist/graphql/client.d.ts +1 -1
- package/dist/graphql/foir-request.d.ts +1 -1
- package/dist/index.js +0 -9
- package/dist/live/drift.d.ts +9 -10
- package/dist/live.js +1 -1
- package/dist/next.js +158 -37
- package/dist/placement/index.d.ts +129 -0
- package/dist/placement.js +144 -0
- package/dist/push.js +212 -50
- package/dist/react.js +158 -37
- package/dist/server/callback-client.d.ts +30 -9
- package/dist/server/continue-run.d.ts +56 -0
- package/dist/server/index.d.ts +6 -3
- package/dist/server/operation-types.d.ts +114 -65
- package/dist/server/read-dispatch.d.ts +53 -0
- package/dist/server/require-scoped-token.d.ts +71 -7
- package/dist/server/verify-scoped-token.d.ts +109 -3
- package/dist/server.js +566 -138
- package/dist/transport/foir-http.d.ts +103 -5
- package/package.json +24 -6
package/dist/push.js
CHANGED
|
@@ -68,7 +68,12 @@ var FoirRequestError = class extends Error {
|
|
|
68
68
|
* failed on the first attempt for an hour.
|
|
69
69
|
*/
|
|
70
70
|
get retryable() {
|
|
71
|
-
if (this.status === void 0)
|
|
71
|
+
if (this.status === void 0) {
|
|
72
|
+
if (this.graphQLErrors?.length || this.prunedSelections?.length) {
|
|
73
|
+
return this.code === "RATE_LIMITED" || this.code === "UNAVAILABLE" || this.code === "TIMEOUT";
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
72
77
|
if (this.status === 429 || this.code === "RATE_LIMITED") return true;
|
|
73
78
|
if (this.status >= 500) return true;
|
|
74
79
|
return this.code === "UNAVAILABLE" || this.code === "TIMEOUT";
|
|
@@ -103,19 +108,50 @@ function readFoirRetryAfterMs(headers) {
|
|
|
103
108
|
const seconds = Number(headers.get("Retry-After"));
|
|
104
109
|
return Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : void 0;
|
|
105
110
|
}
|
|
111
|
+
var DISPATCH_RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
112
|
+
"x-api-key",
|
|
113
|
+
"authorization",
|
|
114
|
+
"x-foir-token",
|
|
115
|
+
"x-foir-context"
|
|
116
|
+
]);
|
|
117
|
+
function refuseCredentialHeaders(extra) {
|
|
118
|
+
if (!extra) return;
|
|
119
|
+
for (const name of Object.keys(extra)) {
|
|
120
|
+
if (DISPATCH_RESERVED_HEADERS.has(name.toLowerCase())) {
|
|
121
|
+
throw new FoirRequestError(
|
|
122
|
+
`[foir] a client built from a dispatch token cannot send "${name}" in \`headers\`. The dispatch token is the credential, and an api key or a bearer beside it would make the request two actors at once. Build a separate client for the other credential.`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
var FOIR_VISITOR_IP_HEADER = "X-Foir-Visitor-IP";
|
|
106
128
|
function buildFoirHeaders(input) {
|
|
107
129
|
const headers = {
|
|
108
|
-
"Content-Type": "application/json"
|
|
109
|
-
"x-api-key": input.apiKey
|
|
130
|
+
"Content-Type": "application/json"
|
|
110
131
|
};
|
|
111
|
-
if (input.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
headers["
|
|
132
|
+
if (input.dispatchToken !== void 0) {
|
|
133
|
+
refuseCredentialHeaders(input.extra);
|
|
134
|
+
headers["X-Foir-Token"] = input.dispatchToken;
|
|
135
|
+
if (input.dispatchContext) {
|
|
136
|
+
headers["X-Foir-Context"] = input.dispatchContext;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
headers["x-api-key"] = input.apiKey;
|
|
140
|
+
if (input.draftChannel) {
|
|
141
|
+
headers["X-Foir-Schema-Channel"] = "draft";
|
|
142
|
+
}
|
|
143
|
+
if (input.bearerToken) {
|
|
144
|
+
headers["Authorization"] = `Bearer ${input.bearerToken}`;
|
|
145
|
+
}
|
|
146
|
+
if (input.orgId) {
|
|
147
|
+
headers["X-Org-Id"] = input.orgId;
|
|
148
|
+
}
|
|
149
|
+
if (input.orgUrl) {
|
|
150
|
+
headers["X-Org-Url"] = input.orgUrl;
|
|
151
|
+
}
|
|
152
|
+
if (input.visitorAddress) {
|
|
153
|
+
headers[FOIR_VISITOR_IP_HEADER] = input.visitorAddress;
|
|
154
|
+
}
|
|
119
155
|
}
|
|
120
156
|
if (input.extra) {
|
|
121
157
|
for (const [key, value] of Object.entries(input.extra)) {
|
|
@@ -131,6 +167,26 @@ function foirApiEndpoint(apiUrl, path) {
|
|
|
131
167
|
}
|
|
132
168
|
return base + path;
|
|
133
169
|
}
|
|
170
|
+
var FoirAuthDowngradedError = class extends FoirRequestError {
|
|
171
|
+
downgrade;
|
|
172
|
+
constructor(downgrade) {
|
|
173
|
+
super(
|
|
174
|
+
`[foir] your customer token was ${downgrade.customerToken} (${downgrade.reason}), so the request was served as ${downgrade.servedAs}`,
|
|
175
|
+
{ graphQLErrors: [{ message: "customer token rejected", extensions: { code: "AUTH_DOWNGRADED" } }] }
|
|
176
|
+
);
|
|
177
|
+
this.name = "FoirAuthDowngradedError";
|
|
178
|
+
this.downgrade = downgrade;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var FoirSessionExpiredError = class extends FoirRequestError {
|
|
182
|
+
constructor(options) {
|
|
183
|
+
super("[foir] the customer session has expired and could not be refreshed: sign in again", {
|
|
184
|
+
cause: options?.cause,
|
|
185
|
+
graphQLErrors: [{ message: "session expired", extensions: { code: "SESSION_EXPIRED" } }]
|
|
186
|
+
});
|
|
187
|
+
this.name = "FoirSessionExpiredError";
|
|
188
|
+
}
|
|
189
|
+
};
|
|
134
190
|
var warnedDowngrade = null;
|
|
135
191
|
function reportAuthDowngrade(envelope) {
|
|
136
192
|
const downgrade = envelope.extensions?.auth;
|
|
@@ -159,12 +215,18 @@ function refusePrunedDocument(json, options) {
|
|
|
159
215
|
`[foir] selections stripped from this query: ${selections.map(describe).join(", ")}`
|
|
160
216
|
);
|
|
161
217
|
}
|
|
218
|
+
function answeredAnything(data) {
|
|
219
|
+
return typeof data === "object" && data !== null && Object.values(data).some((value) => value !== null && value !== void 0);
|
|
220
|
+
}
|
|
162
221
|
function readFoirEnvelope(json, options) {
|
|
222
|
+
if (options?.rejectDowngrade && json.extensions?.auth) {
|
|
223
|
+
throw new FoirAuthDowngradedError(json.extensions.auth);
|
|
224
|
+
}
|
|
163
225
|
reportAuthDowngrade(json);
|
|
164
226
|
refusePrunedDocument(json, options);
|
|
165
227
|
if (json.errors?.length) {
|
|
166
228
|
const msg = json.errors.map((e) => e.message).join("; ");
|
|
167
|
-
if (json.data && !options?.strict) {
|
|
229
|
+
if (answeredAnything(json.data) && !options?.strict) {
|
|
168
230
|
console.warn(`[foir] GraphQL partial errors (data returned): ${msg}`);
|
|
169
231
|
} else {
|
|
170
232
|
throw new FoirRequestError(`[foir] GraphQL errors: ${msg}`, {
|
|
@@ -232,12 +294,13 @@ async function foirRequest(env, document, variables, options) {
|
|
|
232
294
|
apiKey,
|
|
233
295
|
draftChannel: isFoirPreview(env),
|
|
234
296
|
bearerToken: options?.bearerToken,
|
|
235
|
-
orgId: options?.orgId
|
|
297
|
+
orgId: options?.orgId,
|
|
298
|
+
orgUrl: options?.orgUrl
|
|
236
299
|
});
|
|
237
300
|
const documentText = print2(document);
|
|
238
301
|
let res;
|
|
239
302
|
try {
|
|
240
|
-
if (isCdnEligible(env, documentText, options?.bearerToken, options?.orgId)) {
|
|
303
|
+
if (isCdnEligible(env, documentText, options?.bearerToken, options?.orgId ?? options?.orgUrl)) {
|
|
241
304
|
const hash = await documentHash(documentText);
|
|
242
305
|
let shared = await fetch(buildCdnUrl(endpoint, apiKey, hash, variables), {
|
|
243
306
|
method: "GET",
|
|
@@ -283,7 +346,7 @@ async function foirRequest(env, document, variables, options) {
|
|
|
283
346
|
);
|
|
284
347
|
}
|
|
285
348
|
const json = await res.json();
|
|
286
|
-
return readFoirEnvelope(json);
|
|
349
|
+
return readFoirEnvelope(json, { rejectDowngrade: options?.rejectDowngrade });
|
|
287
350
|
}
|
|
288
351
|
async function readErrorEnvelope(res) {
|
|
289
352
|
let errors;
|
|
@@ -788,15 +851,54 @@ function operationName(scope, op) {
|
|
|
788
851
|
function foirDataEndpoint(apiUrl, path) {
|
|
789
852
|
return foirApiEndpoint(apiUrl, path);
|
|
790
853
|
}
|
|
854
|
+
async function resolveVisitorAddress(config) {
|
|
855
|
+
const source = config.visitor;
|
|
856
|
+
const value = typeof source === "function" ? await source() : source;
|
|
857
|
+
const address = value?.trim();
|
|
858
|
+
return address ? address : void 0;
|
|
859
|
+
}
|
|
791
860
|
async function resolveBearerToken(config) {
|
|
792
861
|
const source = config.bearerToken;
|
|
793
862
|
if (typeof source === "function") return await source() ?? void 0;
|
|
794
863
|
return source ?? void 0;
|
|
795
864
|
}
|
|
865
|
+
async function resolveDispatchToken(dispatch) {
|
|
866
|
+
const token = (await dispatch.token())?.trim();
|
|
867
|
+
if (!token) {
|
|
868
|
+
throw new FoirRequestError(
|
|
869
|
+
"[foir] the dispatch token provider returned no token. A client built from a dispatch calls Foir as that operation and holds no other credential. Build it from the token the endpoint was handed: `(await requireScopedToken(request)).dispatch`."
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
return token;
|
|
873
|
+
}
|
|
874
|
+
async function resolveFoirAuth(config) {
|
|
875
|
+
if (config.dispatch !== void 0) {
|
|
876
|
+
return {
|
|
877
|
+
headers: buildFoirHeaders({
|
|
878
|
+
dispatchToken: await resolveDispatchToken(config.dispatch),
|
|
879
|
+
dispatchContext: config.dispatch.context ?? void 0,
|
|
880
|
+
extra: config.headers
|
|
881
|
+
})
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
const bearerToken = await resolveBearerToken(config);
|
|
885
|
+
return {
|
|
886
|
+
headers: buildFoirHeaders({
|
|
887
|
+
apiKey: config.apiKey,
|
|
888
|
+
draftChannel: config.channel === "draft",
|
|
889
|
+
bearerToken,
|
|
890
|
+
orgId: config.orgId,
|
|
891
|
+
orgUrl: config.orgUrl,
|
|
892
|
+
visitorAddress: await resolveVisitorAddress(config),
|
|
893
|
+
extra: config.headers
|
|
894
|
+
}),
|
|
895
|
+
key: { apiKey: config.apiKey, bearerToken }
|
|
896
|
+
};
|
|
897
|
+
}
|
|
796
898
|
function foirRoute(input) {
|
|
797
899
|
if (!input.apiKey.startsWith("pk_")) return { lane: "origin", reason: "key" };
|
|
798
900
|
if (input.bearerToken) return { lane: "origin", reason: "bearer" };
|
|
799
|
-
if (input.orgId) return { lane: "origin", reason: "org" };
|
|
901
|
+
if (input.orgId || input.orgUrl) return { lane: "origin", reason: "org" };
|
|
800
902
|
if (input.mutation) return { lane: "origin", reason: "operation" };
|
|
801
903
|
if (input.writeToken) return { lane: "origin", reason: "floor" };
|
|
802
904
|
if (input.channel === "draft") return { lane: "origin", reason: "channel" };
|
|
@@ -811,25 +913,45 @@ async function executeFoirDocument(config, plan) {
|
|
|
811
913
|
}
|
|
812
914
|
return data[plan.rootField];
|
|
813
915
|
}
|
|
916
|
+
var renewing = /* @__PURE__ */ new WeakMap();
|
|
917
|
+
function renewBearerOnce(refresh) {
|
|
918
|
+
const running = renewing.get(refresh);
|
|
919
|
+
if (running) return running;
|
|
920
|
+
const next = refresh().finally(() => renewing.delete(refresh));
|
|
921
|
+
renewing.set(refresh, next);
|
|
922
|
+
return next;
|
|
923
|
+
}
|
|
814
924
|
async function runFoirDocument(config, document, mutation, variables, options) {
|
|
925
|
+
try {
|
|
926
|
+
return await sendFoirDocument(config, document, mutation, variables, options);
|
|
927
|
+
} catch (err) {
|
|
928
|
+
const refresh = config.refreshBearer;
|
|
929
|
+
if (!(err instanceof FoirAuthDowngradedError) || !refresh || err.downgrade.reason === "wrong_project") {
|
|
930
|
+
throw err;
|
|
931
|
+
}
|
|
932
|
+
const token = err.downgrade.reason === "expired" ? await renewBearerOnce(refresh) : null;
|
|
933
|
+
if (!token) throw new FoirSessionExpiredError({ cause: err });
|
|
934
|
+
try {
|
|
935
|
+
return await sendFoirDocument({ ...config, bearerToken: token }, document, mutation, variables, options);
|
|
936
|
+
} catch (again) {
|
|
937
|
+
if (again instanceof FoirAuthDowngradedError) throw new FoirSessionExpiredError({ cause: again });
|
|
938
|
+
throw again;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
async function sendFoirDocument(config, document, mutation, variables, options) {
|
|
815
943
|
const doFetch = config.fetch ?? globalThis.fetch;
|
|
816
944
|
const endpoint = foirDataEndpoint(config.apiUrl, "/graphql");
|
|
817
|
-
const
|
|
818
|
-
const headers = buildFoirHeaders({
|
|
819
|
-
apiKey: config.apiKey,
|
|
820
|
-
draftChannel: config.channel === "draft",
|
|
821
|
-
bearerToken,
|
|
822
|
-
orgId: config.orgId,
|
|
823
|
-
extra: config.headers
|
|
824
|
-
});
|
|
945
|
+
const { headers, key } = await resolveFoirAuth(config);
|
|
825
946
|
const hash = await documentHash(document);
|
|
826
|
-
const
|
|
827
|
-
apiKey:
|
|
828
|
-
bearerToken,
|
|
947
|
+
const sharedKey = key !== void 0 && foirRoute({
|
|
948
|
+
apiKey: key.apiKey,
|
|
949
|
+
bearerToken: key.bearerToken,
|
|
829
950
|
orgId: config.orgId,
|
|
951
|
+
orgUrl: config.orgUrl,
|
|
830
952
|
mutation,
|
|
831
953
|
channel: config.channel
|
|
832
|
-
});
|
|
954
|
+
}).lane === "shared" ? key.apiKey : void 0;
|
|
833
955
|
const post = (body) => doFetch(endpoint, {
|
|
834
956
|
method: "POST",
|
|
835
957
|
headers,
|
|
@@ -839,8 +961,8 @@ async function runFoirDocument(config, document, mutation, variables, options) {
|
|
|
839
961
|
const extensions = persistedQueryExtension(hash);
|
|
840
962
|
let res;
|
|
841
963
|
try {
|
|
842
|
-
if (
|
|
843
|
-
res = await doFetch(buildCdnUrl(endpoint,
|
|
964
|
+
if (sharedKey !== void 0) {
|
|
965
|
+
res = await doFetch(buildCdnUrl(endpoint, sharedKey, hash, variables), {
|
|
844
966
|
method: "GET",
|
|
845
967
|
headers,
|
|
846
968
|
...config.requestInit
|
|
@@ -866,7 +988,7 @@ async function runFoirDocument(config, document, mutation, variables, options) {
|
|
|
866
988
|
});
|
|
867
989
|
}
|
|
868
990
|
const json = await res.json();
|
|
869
|
-
return readFoirEnvelope(json, options);
|
|
991
|
+
return readFoirEnvelope(json, { ...options, rejectDowngrade: Boolean(key?.bearerToken) });
|
|
870
992
|
}
|
|
871
993
|
async function readErrorBody(res) {
|
|
872
994
|
try {
|
|
@@ -878,20 +1000,16 @@ async function readErrorBody(res) {
|
|
|
878
1000
|
}
|
|
879
1001
|
|
|
880
1002
|
// src/data/manifest.ts
|
|
881
|
-
async function fetchFoirManifest(config) {
|
|
882
|
-
const
|
|
1003
|
+
async function fetchFoirManifest(config, options = {}) {
|
|
1004
|
+
const base = foirDataEndpoint(config.apiUrl, "/v1/manifest");
|
|
1005
|
+
const url = options.operation === void 0 ? base : `${base}?operation=${encodeURIComponent(options.operation)}`;
|
|
883
1006
|
const doFetch = config.fetch ?? globalThis.fetch;
|
|
1007
|
+
const { headers } = await resolveFoirAuth(config);
|
|
884
1008
|
let res;
|
|
885
1009
|
try {
|
|
886
1010
|
res = await doFetch(url, {
|
|
887
1011
|
method: "GET",
|
|
888
|
-
headers
|
|
889
|
-
apiKey: config.apiKey,
|
|
890
|
-
draftChannel: config.channel === "draft",
|
|
891
|
-
bearerToken: await resolveBearerToken(config),
|
|
892
|
-
orgId: config.orgId,
|
|
893
|
-
extra: config.headers
|
|
894
|
-
}),
|
|
1012
|
+
headers,
|
|
895
1013
|
...config.requestInit
|
|
896
1014
|
});
|
|
897
1015
|
} catch (err) {
|
|
@@ -963,6 +1081,7 @@ function authClientConfig(env, options) {
|
|
|
963
1081
|
channel: isFoirPreview(env) ? "draft" : "published",
|
|
964
1082
|
bearerToken: options?.bearerToken,
|
|
965
1083
|
orgId: options?.orgId,
|
|
1084
|
+
orgUrl: options?.orgUrl,
|
|
966
1085
|
headers: options?.headers,
|
|
967
1086
|
fetch: options?.fetch
|
|
968
1087
|
};
|
|
@@ -1014,6 +1133,9 @@ async function customerRefreshToken(env, refreshToken) {
|
|
|
1014
1133
|
async function saveSession(adapter, result) {
|
|
1015
1134
|
await adapter.set(TOKEN_KEY, result.token);
|
|
1016
1135
|
await adapter.set(REFRESH_KEY, result.refreshToken);
|
|
1136
|
+
if (!result.customerId) {
|
|
1137
|
+
return await getSessionCustomer(adapter) ?? { id: "", email: "" };
|
|
1138
|
+
}
|
|
1017
1139
|
await adapter.set(CUSTOMER_ID_KEY, result.customerId);
|
|
1018
1140
|
await adapter.set(EMAIL_KEY, result.email);
|
|
1019
1141
|
return { id: result.customerId, email: result.email };
|
|
@@ -1027,6 +1149,12 @@ async function clearSession(adapter) {
|
|
|
1027
1149
|
async function getSessionToken(adapter) {
|
|
1028
1150
|
return await adapter.get(TOKEN_KEY) ?? null;
|
|
1029
1151
|
}
|
|
1152
|
+
async function getSessionCustomer(adapter) {
|
|
1153
|
+
const id = await adapter.get(CUSTOMER_ID_KEY) ?? null;
|
|
1154
|
+
const email = await adapter.get(EMAIL_KEY) ?? null;
|
|
1155
|
+
if (!id) return null;
|
|
1156
|
+
return { id, email: email ?? "" };
|
|
1157
|
+
}
|
|
1030
1158
|
async function refreshSession(adapter, env) {
|
|
1031
1159
|
const refreshToken = await adapter.get(REFRESH_KEY) ?? null;
|
|
1032
1160
|
if (!refreshToken) return null;
|
|
@@ -1046,21 +1174,55 @@ function isAuthExpiredError(err) {
|
|
|
1046
1174
|
(e) => /authentication required/i.test(e.message)
|
|
1047
1175
|
);
|
|
1048
1176
|
}
|
|
1049
|
-
|
|
1177
|
+
var refreshing = /* @__PURE__ */ new WeakMap();
|
|
1178
|
+
function refreshSessionOnce(adapter, env) {
|
|
1179
|
+
const running = refreshing.get(adapter);
|
|
1180
|
+
if (running) return running;
|
|
1181
|
+
const next = refreshSession(adapter, env).finally(() => refreshing.delete(adapter));
|
|
1182
|
+
refreshing.set(adapter, next);
|
|
1183
|
+
return next;
|
|
1184
|
+
}
|
|
1185
|
+
function sessionLapse(err) {
|
|
1186
|
+
if (err instanceof FoirAuthDowngradedError) {
|
|
1187
|
+
switch (err.downgrade.reason) {
|
|
1188
|
+
case "expired":
|
|
1189
|
+
return "refresh";
|
|
1190
|
+
case "invalid":
|
|
1191
|
+
return "expired";
|
|
1192
|
+
default:
|
|
1193
|
+
return null;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return isAuthExpiredError(err) ? "refresh" : null;
|
|
1197
|
+
}
|
|
1198
|
+
async function withSessionRefresh(adapter, env, run) {
|
|
1050
1199
|
const token = await getSessionToken(adapter);
|
|
1051
1200
|
try {
|
|
1052
|
-
return await
|
|
1053
|
-
bearerToken: token ?? void 0
|
|
1054
|
-
});
|
|
1201
|
+
return await run(token ?? void 0);
|
|
1055
1202
|
} catch (err) {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
if (
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1203
|
+
const lapse = sessionLapse(err);
|
|
1204
|
+
if (!lapse) throw err;
|
|
1205
|
+
if (lapse === "expired") throw new FoirSessionExpiredError({ cause: err });
|
|
1206
|
+
const refreshed = await refreshSessionOnce(adapter, env);
|
|
1207
|
+
if (!refreshed) {
|
|
1208
|
+
if (err instanceof FoirAuthDowngradedError) throw new FoirSessionExpiredError({ cause: err });
|
|
1209
|
+
throw err;
|
|
1210
|
+
}
|
|
1211
|
+
try {
|
|
1212
|
+
return await run(refreshed.token);
|
|
1213
|
+
} catch (again) {
|
|
1214
|
+
if (again instanceof FoirAuthDowngradedError) throw new FoirSessionExpiredError({ cause: again });
|
|
1215
|
+
throw again;
|
|
1216
|
+
}
|
|
1062
1217
|
}
|
|
1063
1218
|
}
|
|
1219
|
+
async function authedRequest(adapter, env, document, variables) {
|
|
1220
|
+
return withSessionRefresh(
|
|
1221
|
+
adapter,
|
|
1222
|
+
env,
|
|
1223
|
+
(bearerToken) => foirRequest(env, document, variables, { bearerToken, rejectDowngrade: true })
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1064
1226
|
|
|
1065
1227
|
// src/push/operations.ts
|
|
1066
1228
|
import { parse } from "graphql";
|