@stackframe/stack-shared 2.5.9 → 2.5.10
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
CHANGED
|
@@ -21,6 +21,13 @@ export declare class StackClientInterface {
|
|
|
21
21
|
constructor(options: ClientInterfaceOptions);
|
|
22
22
|
get projectId(): string;
|
|
23
23
|
getApiUrl(): string;
|
|
24
|
+
runNetworkDiagnostics(session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<{
|
|
25
|
+
cfTrace: string;
|
|
26
|
+
apiRoot: string;
|
|
27
|
+
baseUrlBackend: string;
|
|
28
|
+
prodDashboard: string;
|
|
29
|
+
prodBackend: string;
|
|
30
|
+
}>;
|
|
24
31
|
fetchNewAccessToken(refreshToken: RefreshToken): Promise<AccessToken | null>;
|
|
25
32
|
protected sendClientRequest(path: string, requestOptions: RequestInit, session: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<Response & {
|
|
26
33
|
usedTokens: {
|
|
@@ -6,6 +6,7 @@ import { generateSecureRandomString } from '../utils/crypto';
|
|
|
6
6
|
import { StackAssertionError, throwErr } from '../utils/errors';
|
|
7
7
|
import { globalVar } from '../utils/globals';
|
|
8
8
|
import { Result } from "../utils/results";
|
|
9
|
+
import { deindent } from '../utils/strings';
|
|
9
10
|
export class StackClientInterface {
|
|
10
11
|
constructor(options) {
|
|
11
12
|
this.options = options;
|
|
@@ -17,6 +18,54 @@ export class StackClientInterface {
|
|
|
17
18
|
getApiUrl() {
|
|
18
19
|
return this.options.baseUrl + "/api/v1";
|
|
19
20
|
}
|
|
21
|
+
async runNetworkDiagnostics(session, requestType) {
|
|
22
|
+
const tryRequest = async (cb) => {
|
|
23
|
+
try {
|
|
24
|
+
await cb();
|
|
25
|
+
return "OK";
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return `${e}`;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const cfTrace = await tryRequest(async () => {
|
|
32
|
+
const res = await fetch("https://1.1.1.1/cdn-cgi/trace");
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const apiRoot = session !== undefined && requestType !== undefined ? await tryRequest(async () => {
|
|
38
|
+
const res = await this.sendClientRequestInner("/", {}, session, requestType);
|
|
39
|
+
if (res.status === "error") {
|
|
40
|
+
throw res.error;
|
|
41
|
+
}
|
|
42
|
+
}) : "Not tested";
|
|
43
|
+
const baseUrlBackend = await tryRequest(async () => {
|
|
44
|
+
const res = await fetch(new URL("/health", this.getApiUrl()));
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const prodDashboard = await tryRequest(async () => {
|
|
50
|
+
const res = await fetch("https://app.stackframe.com/health");
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const prodBackend = await tryRequest(async () => {
|
|
56
|
+
const res = await fetch("https://api.stackframe.com/health");
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
cfTrace,
|
|
63
|
+
apiRoot,
|
|
64
|
+
baseUrlBackend,
|
|
65
|
+
prodDashboard,
|
|
66
|
+
prodBackend,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
20
69
|
async fetchNewAccessToken(refreshToken) {
|
|
21
70
|
if (!('publishableClientKey' in this.options)) {
|
|
22
71
|
// TODO support it
|
|
@@ -59,7 +108,23 @@ export class StackClientInterface {
|
|
|
59
108
|
session ??= this.createSession({
|
|
60
109
|
refreshToken: null,
|
|
61
110
|
});
|
|
62
|
-
|
|
111
|
+
const retriedResult = await Result.retry(() => this.sendClientRequestInner(path, requestOptions, session, requestType), 5, { exponentialDelayBase: 1000 });
|
|
112
|
+
// try to diagnose the error for the user
|
|
113
|
+
if (retriedResult.status === "error") {
|
|
114
|
+
if (!navigator.onLine) {
|
|
115
|
+
throw new Error("Failed to send Stack request. It seems like you are offline. (window.navigator.onLine is falsy)", { cause: retriedResult.error });
|
|
116
|
+
}
|
|
117
|
+
throw new Error(deindent `
|
|
118
|
+
Stack is unable to connect to the server. Please check your internet connection and try again.
|
|
119
|
+
|
|
120
|
+
If the problem persists, please contact Stack support and provide a screenshot of your entire browser console.
|
|
121
|
+
|
|
122
|
+
${retriedResult.error}
|
|
123
|
+
|
|
124
|
+
${JSON.stringify(await this.runNetworkDiagnostics(session, requestType), null, 2)}
|
|
125
|
+
`, { cause: retriedResult.error });
|
|
126
|
+
}
|
|
127
|
+
return retriedResult.data;
|
|
63
128
|
}
|
|
64
129
|
createSession(options) {
|
|
65
130
|
const session = new InternalSession({
|
|
@@ -14,6 +14,7 @@ export declare const projectsCrudServerReadSchema: import("yup").ObjectSchema<{
|
|
|
14
14
|
oauth_providers: {
|
|
15
15
|
client_id?: string | undefined;
|
|
16
16
|
client_secret?: string | undefined;
|
|
17
|
+
facebook_config_id?: string | undefined;
|
|
17
18
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
18
19
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
19
20
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -101,6 +102,7 @@ export declare const projectsCrudServerUpdateSchema: import("yup").ObjectSchema<
|
|
|
101
102
|
oauth_providers?: {
|
|
102
103
|
client_id?: string | undefined;
|
|
103
104
|
client_secret?: string | undefined;
|
|
105
|
+
facebook_config_id?: string | undefined;
|
|
104
106
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
105
107
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
106
108
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -143,6 +145,7 @@ export declare const projectsCrudServerCreateSchema: import("yup").ObjectSchema<
|
|
|
143
145
|
oauth_providers?: {
|
|
144
146
|
client_id?: string | undefined;
|
|
145
147
|
client_secret?: string | undefined;
|
|
148
|
+
facebook_config_id?: string | undefined;
|
|
146
149
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
147
150
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
148
151
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -211,6 +214,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
|
|
|
211
214
|
oauth_providers: {
|
|
212
215
|
client_id?: string | undefined;
|
|
213
216
|
client_secret?: string | undefined;
|
|
217
|
+
facebook_config_id?: string | undefined;
|
|
214
218
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
215
219
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
216
220
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -279,6 +283,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
|
|
|
279
283
|
oauth_providers?: {
|
|
280
284
|
client_id?: string | undefined;
|
|
281
285
|
client_secret?: string | undefined;
|
|
286
|
+
facebook_config_id?: string | undefined;
|
|
282
287
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
283
288
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
284
289
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -345,6 +350,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
|
|
|
345
350
|
oauth_providers: {
|
|
346
351
|
client_id?: string | undefined;
|
|
347
352
|
client_secret?: string | undefined;
|
|
353
|
+
facebook_config_id?: string | undefined;
|
|
348
354
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
349
355
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
350
356
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -413,6 +419,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
|
|
|
413
419
|
oauth_providers?: {
|
|
414
420
|
client_id?: string | undefined;
|
|
415
421
|
client_secret?: string | undefined;
|
|
422
|
+
facebook_config_id?: string | undefined;
|
|
416
423
|
type: NonNullable<"shared" | "standard" | undefined>;
|
|
417
424
|
id: NonNullable<"google" | "github" | "facebook" | "microsoft" | "spotify" | undefined>;
|
|
418
425
|
enabled: NonNullable<boolean | undefined>;
|
|
@@ -10,6 +10,8 @@ const oauthProviderSchema = yupObject({
|
|
|
10
10
|
type: schemaFields.oauthTypeSchema.required(),
|
|
11
11
|
client_id: yupRequiredWhen(schemaFields.oauthClientIdSchema, 'type', 'standard'),
|
|
12
12
|
client_secret: yupRequiredWhen(schemaFields.oauthClientSecretSchema, 'type', 'standard'),
|
|
13
|
+
// extra params
|
|
14
|
+
facebook_config_id: yupString().optional().meta({ openapiField: { description: 'This parameter is the configuration id for Facebook business login (for things like ads and marketing).' } }),
|
|
13
15
|
});
|
|
14
16
|
const enabledOAuthProviderSchema = yupObject({
|
|
15
17
|
id: schemaFields.oauthIdSchema.required(),
|
package/dist/utils/results.js
CHANGED
|
@@ -86,13 +86,18 @@ function mapResult(result, fn) {
|
|
|
86
86
|
}
|
|
87
87
|
class RetryError extends AggregateError {
|
|
88
88
|
constructor(errors) {
|
|
89
|
+
const strings = errors.map(e => String(e));
|
|
90
|
+
const isAllSame = strings.length > 1 && strings.every(s => s === strings[0]);
|
|
89
91
|
super(errors, deindent `
|
|
90
92
|
Error after retrying ${errors.length} times.
|
|
91
93
|
|
|
92
|
-
${
|
|
93
|
-
|
|
94
|
-
${
|
|
95
|
-
`
|
|
94
|
+
${isAllSame ? deindent `
|
|
95
|
+
Attempts 1-${errors.length}:
|
|
96
|
+
${errors[0]}
|
|
97
|
+
` : errors.map((e, i) => deindent `
|
|
98
|
+
Attempt ${i + 1}:
|
|
99
|
+
${e}
|
|
100
|
+
`).join("\n\n")}
|
|
96
101
|
`, { cause: errors[errors.length - 1] });
|
|
97
102
|
this.errors = errors;
|
|
98
103
|
this.name = "RetryError";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackframe/stack-shared",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.10",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"jose": "^5.2.2",
|
|
37
37
|
"oauth4webapi": "^2.10.3",
|
|
38
38
|
"uuid": "^9.0.1",
|
|
39
|
-
"@stackframe/stack-sc": "2.5.
|
|
39
|
+
"@stackframe/stack-sc": "2.5.10"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"rimraf": "^5.0.5",
|