@stackframe/stack-shared 2.7.26 → 2.7.27

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
@@ -1,5 +1,11 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.7.27
4
+
5
+ ### Patch Changes
6
+
7
+ - Various changes
8
+
3
9
  ## 2.7.26
4
10
 
5
11
  ### Patch Changes
@@ -1,6 +1,7 @@
1
1
  import { InternalSession } from "../sessions";
2
2
  import { ApiKeysCrud } from "./crud/api-keys";
3
3
  import { EmailTemplateCrud, EmailTemplateType } from "./crud/email-templates";
4
+ import { InternalEmailsCrud } from "./crud/emails";
4
5
  import { ProjectsCrud } from "./crud/projects";
5
6
  import { SvixTokenCrud } from "./crud/svix-token";
6
7
  import { TeamPermissionDefinitionsCrud } from "./crud/team-permissions";
@@ -61,4 +62,5 @@ export declare class StackAdminInterface extends StackServerInterface {
61
62
  success: boolean;
62
63
  error_message?: string;
63
64
  }>;
65
+ listSentEmails(): Promise<InternalEmailsCrud["Admin"]["List"]>;
64
66
  }
@@ -136,4 +136,10 @@ export class StackAdminInterface extends StackServerInterface {
136
136
  }, null);
137
137
  return await response.json();
138
138
  }
139
+ async listSentEmails() {
140
+ const response = await this.sendAdminRequest("/internal/emails", {
141
+ method: "GET",
142
+ }, null);
143
+ return await response.json();
144
+ }
139
145
  }
@@ -7,6 +7,7 @@ import { ContactChannelsCrud } from './crud/contact-channels';
7
7
  import { CurrentUserCrud } from './crud/current-user';
8
8
  import { ConnectedAccountAccessTokenCrud } from './crud/oauth';
9
9
  import { InternalProjectsCrud, ProjectsCrud } from './crud/projects';
10
+ import { SessionsCrud } from './crud/sessions';
10
11
  import { TeamInvitationCrud } from './crud/team-invitation';
11
12
  import { TeamMemberProfilesCrud } from './crud/team-member-profiles';
12
13
  import { TeamPermissionsCrud } from './crud/team-permissions';
@@ -193,6 +194,9 @@ export declare class StackClientInterface {
193
194
  createClientContactChannel(data: ContactChannelsCrud['Client']['Create'], session: InternalSession): Promise<ContactChannelsCrud['Client']['Read']>;
194
195
  updateClientContactChannel(id: string, data: ContactChannelsCrud['Client']['Update'], session: InternalSession): Promise<ContactChannelsCrud['Client']['Read']>;
195
196
  deleteClientContactChannel(id: string, session: InternalSession): Promise<void>;
197
+ deleteSession(sessionId: string, session: InternalSession): Promise<void>;
198
+ listSessions(session: InternalSession): Promise<SessionsCrud['Client']['List']>;
196
199
  listClientContactChannels(session: InternalSession): Promise<ContactChannelsCrud['Client']['Read'][]>;
197
200
  sendCurrentUserContactChannelVerificationEmail(contactChannelId: string, callbackUrl: string, session: InternalSession): Promise<Result<undefined, KnownErrors["EmailAlreadyVerified"]>>;
201
+ cliLogin(loginCode: string, refreshToken: string, session: InternalSession): Promise<Result<undefined, KnownErrors["SchemaError"]>>;
198
202
  }
@@ -876,6 +876,17 @@ export class StackClientInterface {
876
876
  method: "DELETE",
877
877
  }, session);
878
878
  }
879
+ async deleteSession(sessionId, session) {
880
+ await this.sendClientRequest(`/auth/sessions/${sessionId}?user_id=me`, {
881
+ method: "DELETE",
882
+ }, session);
883
+ }
884
+ async listSessions(session) {
885
+ const response = await this.sendClientRequest("/auth/sessions?user_id=me", {
886
+ method: "GET",
887
+ }, session);
888
+ return await response.json();
889
+ }
879
890
  async listClientContactChannels(session) {
880
891
  const response = await this.sendClientRequest("/contact-channels?user_id=me", {
881
892
  method: "GET",
@@ -896,4 +907,20 @@ export class StackClientInterface {
896
907
  }
897
908
  return Result.ok(undefined);
898
909
  }
910
+ async cliLogin(loginCode, refreshToken, session) {
911
+ const responseOrError = await this.sendClientRequestAndCatchKnownError("/auth/cli/complete", {
912
+ method: "POST",
913
+ headers: {
914
+ "Content-Type": "application/json"
915
+ },
916
+ body: JSON.stringify({
917
+ login_code: loginCode,
918
+ refresh_token: refreshToken,
919
+ }),
920
+ }, session, [KnownErrors.SchemaError]);
921
+ if (responseOrError.status === "error") {
922
+ return Result.error(responseOrError.error);
923
+ }
924
+ return Result.ok(undefined);
925
+ }
899
926
  }
@@ -0,0 +1,34 @@
1
+ import { CrudTypeOf } from "../../crud";
2
+ export declare const sentEmailReadSchema: import("yup").ObjectSchema<{
3
+ id: string;
4
+ subject: string;
5
+ sent_at_millis: number;
6
+ to: string[] | undefined;
7
+ sender_config: {} | null;
8
+ error: {} | null | undefined;
9
+ }, import("yup").AnyObject, {
10
+ id: undefined;
11
+ subject: undefined;
12
+ sent_at_millis: undefined;
13
+ to: undefined;
14
+ sender_config: undefined;
15
+ error: undefined;
16
+ }, "">;
17
+ export declare const internalEmailsCrud: import("../../crud").CrudSchemaFromOptions<{
18
+ clientReadSchema: import("yup").ObjectSchema<{
19
+ id: string;
20
+ subject: string;
21
+ sent_at_millis: number;
22
+ to: string[] | undefined;
23
+ sender_config: {} | null;
24
+ error: {} | null | undefined;
25
+ }, import("yup").AnyObject, {
26
+ id: undefined;
27
+ subject: undefined;
28
+ sent_at_millis: undefined;
29
+ to: undefined;
30
+ sender_config: undefined;
31
+ error: undefined;
32
+ }, "">;
33
+ }>;
34
+ export type InternalEmailsCrud = CrudTypeOf<typeof internalEmailsCrud>;
@@ -0,0 +1,13 @@
1
+ import { createCrud } from "../../crud";
2
+ import * as fieldSchema from "../../schema-fields";
3
+ export const sentEmailReadSchema = fieldSchema.yupObject({
4
+ id: fieldSchema.yupString().defined(),
5
+ subject: fieldSchema.yupString().defined(),
6
+ sent_at_millis: fieldSchema.yupNumber().defined(),
7
+ to: fieldSchema.yupArray(fieldSchema.yupString().defined()),
8
+ sender_config: fieldSchema.yupMixed().nullable().defined(),
9
+ error: fieldSchema.yupMixed().nullable().optional(),
10
+ }).defined();
11
+ export const internalEmailsCrud = createCrud({
12
+ clientReadSchema: sentEmailReadSchema,
13
+ });
@@ -0,0 +1,144 @@
1
+ import { CrudTypeOf } from "../../crud";
2
+ export declare const sessionsCrudServerCreateSchema: import("yup").ObjectSchema<{
3
+ user_id: string;
4
+ expires_in_millis: number;
5
+ is_impersonation: boolean;
6
+ }, import("yup").AnyObject, {
7
+ user_id: undefined;
8
+ expires_in_millis: number;
9
+ is_impersonation: false;
10
+ }, "">;
11
+ export declare const sessionsCreateOutputSchema: import("yup").ObjectSchema<{
12
+ refresh_token: string;
13
+ access_token: string;
14
+ }, import("yup").AnyObject, {
15
+ refresh_token: undefined;
16
+ access_token: undefined;
17
+ }, "">;
18
+ export declare const sessionsCrudReadSchema: import("yup").ObjectSchema<{
19
+ id: string;
20
+ user_id: string;
21
+ created_at: number;
22
+ is_impersonation: boolean;
23
+ last_used_at: number | undefined;
24
+ is_current_session: boolean | undefined;
25
+ last_used_at_end_user_ip_info: {
26
+ countryCode?: string | null | undefined;
27
+ regionCode?: string | null | undefined;
28
+ cityName?: string | null | undefined;
29
+ latitude?: number | null | undefined;
30
+ longitude?: number | null | undefined;
31
+ tzIdentifier?: string | null | undefined;
32
+ ip: string;
33
+ } | undefined;
34
+ }, import("yup").AnyObject, {
35
+ id: undefined;
36
+ user_id: undefined;
37
+ created_at: undefined;
38
+ is_impersonation: undefined;
39
+ last_used_at: undefined;
40
+ is_current_session: undefined;
41
+ last_used_at_end_user_ip_info: {
42
+ ip: undefined;
43
+ countryCode: undefined;
44
+ regionCode: undefined;
45
+ cityName: undefined;
46
+ latitude: undefined;
47
+ longitude: undefined;
48
+ tzIdentifier: undefined;
49
+ };
50
+ }, "">;
51
+ export declare const sessionsCrudDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
52
+ export declare const sessionsCrud: import("../../crud").CrudSchemaFromOptions<{
53
+ serverReadSchema: import("yup").ObjectSchema<{
54
+ id: string;
55
+ user_id: string;
56
+ created_at: number;
57
+ is_impersonation: boolean;
58
+ last_used_at: number | undefined;
59
+ is_current_session: boolean | undefined;
60
+ last_used_at_end_user_ip_info: {
61
+ countryCode?: string | null | undefined;
62
+ regionCode?: string | null | undefined;
63
+ cityName?: string | null | undefined;
64
+ latitude?: number | null | undefined;
65
+ longitude?: number | null | undefined;
66
+ tzIdentifier?: string | null | undefined;
67
+ ip: string;
68
+ } | undefined;
69
+ }, import("yup").AnyObject, {
70
+ id: undefined;
71
+ user_id: undefined;
72
+ created_at: undefined;
73
+ is_impersonation: undefined;
74
+ last_used_at: undefined;
75
+ is_current_session: undefined;
76
+ last_used_at_end_user_ip_info: {
77
+ ip: undefined;
78
+ countryCode: undefined;
79
+ regionCode: undefined;
80
+ cityName: undefined;
81
+ latitude: undefined;
82
+ longitude: undefined;
83
+ tzIdentifier: undefined;
84
+ };
85
+ }, "">;
86
+ serverDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
87
+ clientReadSchema: import("yup").ObjectSchema<{
88
+ id: string;
89
+ user_id: string;
90
+ created_at: number;
91
+ is_impersonation: boolean;
92
+ last_used_at: number | undefined;
93
+ is_current_session: boolean | undefined;
94
+ last_used_at_end_user_ip_info: {
95
+ countryCode?: string | null | undefined;
96
+ regionCode?: string | null | undefined;
97
+ cityName?: string | null | undefined;
98
+ latitude?: number | null | undefined;
99
+ longitude?: number | null | undefined;
100
+ tzIdentifier?: string | null | undefined;
101
+ ip: string;
102
+ } | undefined;
103
+ }, import("yup").AnyObject, {
104
+ id: undefined;
105
+ user_id: undefined;
106
+ created_at: undefined;
107
+ is_impersonation: undefined;
108
+ last_used_at: undefined;
109
+ is_current_session: undefined;
110
+ last_used_at_end_user_ip_info: {
111
+ ip: undefined;
112
+ countryCode: undefined;
113
+ regionCode: undefined;
114
+ cityName: undefined;
115
+ latitude: undefined;
116
+ longitude: undefined;
117
+ tzIdentifier: undefined;
118
+ };
119
+ }, "">;
120
+ clientDeleteSchema: import("yup").MixedSchema<{} | undefined, import("yup").AnyObject, undefined, "">;
121
+ docs: {
122
+ serverList: {
123
+ summary: string;
124
+ description: string;
125
+ tags: string[];
126
+ };
127
+ serverDelete: {
128
+ summary: string;
129
+ description: string;
130
+ tags: string[];
131
+ };
132
+ clientList: {
133
+ summary: string;
134
+ description: string;
135
+ tags: string[];
136
+ };
137
+ clientDelete: {
138
+ summary: string;
139
+ description: string;
140
+ tags: string[];
141
+ };
142
+ };
143
+ }>;
144
+ export type SessionsCrud = CrudTypeOf<typeof sessionsCrud>;
@@ -0,0 +1,55 @@
1
+ import { createCrud } from "../../crud";
2
+ import { yupBoolean, yupMixed, yupNumber, yupObject, yupString } from "../../schema-fields";
3
+ import { geoInfoSchema } from "../../utils/geo";
4
+ // Create
5
+ export const sessionsCrudServerCreateSchema = yupObject({
6
+ user_id: yupString().uuid().defined(),
7
+ expires_in_millis: yupNumber().max(1000 * 60 * 60 * 24 * 367).default(1000 * 60 * 60 * 24 * 365),
8
+ is_impersonation: yupBoolean().default(false),
9
+ }).defined();
10
+ export const sessionsCreateOutputSchema = yupObject({
11
+ refresh_token: yupString().defined(),
12
+ access_token: yupString().defined(),
13
+ }).defined();
14
+ export const sessionsCrudReadSchema = yupObject({
15
+ id: yupString().defined(),
16
+ user_id: yupString().uuid().defined(),
17
+ created_at: yupNumber().defined(),
18
+ is_impersonation: yupBoolean().defined(),
19
+ last_used_at: yupNumber().optional(),
20
+ is_current_session: yupBoolean(),
21
+ // TODO move this to a shared type
22
+ // TODO: what about if not trusted?
23
+ last_used_at_end_user_ip_info: geoInfoSchema.optional(),
24
+ }).defined();
25
+ // Delete
26
+ export const sessionsCrudDeleteSchema = yupMixed();
27
+ export const sessionsCrud = createCrud({
28
+ // serverCreateSchema: sessionsCrudServerCreateSchema,
29
+ serverReadSchema: sessionsCrudReadSchema,
30
+ serverDeleteSchema: sessionsCrudDeleteSchema,
31
+ clientReadSchema: sessionsCrudReadSchema,
32
+ clientDeleteSchema: sessionsCrudDeleteSchema,
33
+ docs: {
34
+ serverList: {
35
+ summary: "List sessions",
36
+ description: "List all sessions for the current user.",
37
+ tags: ["Sessions"],
38
+ },
39
+ serverDelete: {
40
+ summary: "Delete session",
41
+ description: "Delete a session by ID.",
42
+ tags: ["Sessions"],
43
+ },
44
+ clientList: {
45
+ summary: "List sessions",
46
+ description: "List all sessions for the current user.",
47
+ tags: ["Sessions"],
48
+ },
49
+ clientDelete: {
50
+ summary: "Delete session",
51
+ description: "Delete a session by ID.",
52
+ tags: ["Sessions"],
53
+ },
54
+ },
55
+ });
@@ -46,6 +46,40 @@ export declare const teamPermissionsCrud: import("../../crud").CrudSchemaFromOpt
46
46
  };
47
47
  }>;
48
48
  export type TeamPermissionsCrud = CrudTypeOf<typeof teamPermissionsCrud>;
49
+ export declare const teamPermissionCreatedWebhookEvent: {
50
+ type: string;
51
+ schema: import("yup").ObjectSchema<{
52
+ id: string;
53
+ user_id: string;
54
+ team_id: string;
55
+ }, import("yup").AnyObject, {
56
+ id: undefined;
57
+ user_id: undefined;
58
+ team_id: undefined;
59
+ }, "">;
60
+ metadata: {
61
+ summary: string;
62
+ description: string;
63
+ tags: string[];
64
+ };
65
+ };
66
+ export declare const teamPermissionDeletedWebhookEvent: {
67
+ type: string;
68
+ schema: import("yup").ObjectSchema<{
69
+ id: string;
70
+ user_id: string;
71
+ team_id: string;
72
+ }, import("yup").AnyObject, {
73
+ id: undefined;
74
+ user_id: undefined;
75
+ team_id: undefined;
76
+ }, "">;
77
+ metadata: {
78
+ summary: string;
79
+ description: string;
80
+ tags: string[];
81
+ };
82
+ };
49
83
  export declare const teamPermissionDefinitionsCrudAdminReadSchema: import("yup").ObjectSchema<{
50
84
  id: string;
51
85
  description: string | undefined;
@@ -36,6 +36,24 @@ export const teamPermissionsCrud = createCrud({
36
36
  },
37
37
  },
38
38
  });
39
+ export const teamPermissionCreatedWebhookEvent = {
40
+ type: "team_permission.created",
41
+ schema: teamPermissionsCrud.server.readSchema,
42
+ metadata: {
43
+ summary: "Team Permission Created",
44
+ description: "This event is triggered when a team permission is created.",
45
+ tags: ["Teams"],
46
+ },
47
+ };
48
+ export const teamPermissionDeletedWebhookEvent = {
49
+ type: "team_permission.deleted",
50
+ schema: teamPermissionsCrud.server.readSchema,
51
+ metadata: {
52
+ summary: "Team Permission Deleted",
53
+ description: "This event is triggered when a team permission is deleted.",
54
+ tags: ["Teams"],
55
+ },
56
+ };
39
57
  // =============== Team permission definitions =================
40
58
  export const teamPermissionDefinitionsCrudAdminReadSchema = yupObject({
41
59
  id: schemaFields.teamPermissionDefinitionIdSchema.defined(),
@@ -5,6 +5,7 @@ import { ClientInterfaceOptions, StackClientInterface } from "./clientInterface"
5
5
  import { ContactChannelsCrud } from "./crud/contact-channels";
6
6
  import { CurrentUserCrud } from "./crud/current-user";
7
7
  import { ConnectedAccountAccessTokenCrud } from "./crud/oauth";
8
+ import { SessionsCrud } from "./crud/sessions";
8
9
  import { TeamInvitationCrud } from "./crud/team-invitation";
9
10
  import { TeamMemberProfilesCrud } from "./crud/team-member-profiles";
10
11
  import { TeamMembershipsCrud } from "./crud/team-memberships";
@@ -74,7 +75,7 @@ export declare class StackServerInterface extends StackClientInterface {
74
75
  }): Promise<void>;
75
76
  updateServerUser(userId: string, update: UsersCrud['Server']['Update']): Promise<UsersCrud['Server']['Read']>;
76
77
  createServerProviderAccessToken(userId: string, provider: string, scope: string): Promise<ConnectedAccountAccessTokenCrud['Server']['Read']>;
77
- createServerUserSession(userId: string, expiresInMillis: number): Promise<{
78
+ createServerUserSession(userId: string, expiresInMillis: number, isImpersonation: boolean): Promise<{
78
79
  accessToken: string;
79
80
  refreshToken: string;
80
81
  }>;
@@ -95,6 +96,8 @@ export declare class StackServerInterface extends StackClientInterface {
95
96
  deleteServerContactChannel(userId: string, contactChannelId: string): Promise<void>;
96
97
  listServerContactChannels(userId: string): Promise<ContactChannelsCrud['Server']['Read'][]>;
97
98
  sendServerContactChannelVerificationEmail(userId: string, contactChannelId: string, callbackUrl: string): Promise<void>;
99
+ listServerSessions(userId: string): Promise<SessionsCrud['Server']['Read'][]>;
100
+ deleteServerSession(sessionId: string): Promise<void>;
98
101
  sendServerTeamInvitation(options: {
99
102
  email: string;
100
103
  teamId: string;
@@ -58,10 +58,11 @@ export class StackServerInterface extends StackClientInterface {
58
58
  return user;
59
59
  }
60
60
  async getServerUserById(userId) {
61
- const response = await this.sendServerRequest(urlString `/users/${userId}`, {}, null);
62
- const user = await response.json();
63
- if (!user)
64
- return Result.error(new Error("Failed to get user"));
61
+ const responseOrError = await this.sendServerRequestAndCatchKnownError(urlString `/users/${userId}`, {}, null, [KnownErrors.UserNotFound]);
62
+ if (responseOrError.status === "error") {
63
+ return Result.error(responseOrError.error);
64
+ }
65
+ const user = await responseOrError.data.json();
65
66
  return Result.ok(user);
66
67
  }
67
68
  async listServerTeamInvitations(options) {
@@ -182,7 +183,7 @@ export class StackServerInterface extends StackClientInterface {
182
183
  }, null);
183
184
  return await response.json();
184
185
  }
185
- async createServerUserSession(userId, expiresInMillis) {
186
+ async createServerUserSession(userId, expiresInMillis, isImpersonation) {
186
187
  const response = await this.sendServerRequest("/auth/sessions", {
187
188
  method: "POST",
188
189
  headers: {
@@ -191,6 +192,7 @@ export class StackServerInterface extends StackClientInterface {
191
192
  body: JSON.stringify({
192
193
  user_id: userId,
193
194
  expires_in_millis: expiresInMillis,
195
+ is_impersonation: isImpersonation,
194
196
  }),
195
197
  }, null);
196
198
  const result = await response.json();
@@ -285,6 +287,17 @@ export class StackServerInterface extends StackClientInterface {
285
287
  body: JSON.stringify({ callback_url: callbackUrl }),
286
288
  }, null);
287
289
  }
290
+ async listServerSessions(userId) {
291
+ const response = await this.sendServerRequest(urlString `/auth/sessions?user_id=${userId}`, {
292
+ method: "GET",
293
+ }, null);
294
+ return await response.json();
295
+ }
296
+ async deleteServerSession(sessionId) {
297
+ await this.sendServerRequest(urlString `/auth/sessions/${sessionId}`, {
298
+ method: "DELETE",
299
+ }, null);
300
+ }
288
301
  async sendServerTeamInvitation(options) {
289
302
  await this.sendServerRequest("/team-invitations/send-code", {
290
303
  method: "POST",
@@ -46,6 +46,11 @@ export type KnownErrors = {
46
46
  [K in keyof typeof KnownErrors]: InstanceType<typeof KnownErrors[K]>;
47
47
  };
48
48
  export declare const KnownErrors: {
49
+ CannotDeleteCurrentSession: KnownErrorConstructor<KnownError & KnownErrorBrand<"REFRESH_TOKEN_ERROR"> & {
50
+ constructorArgs: [statusCode: number, humanReadableMessage: string, details?: Json | undefined];
51
+ } & KnownErrorBrand<"CANNOT_DELETE_CURRENT_SESSION">, []> & {
52
+ errorCode: "CANNOT_DELETE_CURRENT_SESSION";
53
+ };
49
54
  UnsupportedError: KnownErrorConstructor<KnownError & KnownErrorBrand<"UNSUPPORTED_ERROR">, [originalErrorCode: string]> & {
50
55
  errorCode: "UNSUPPORTED_ERROR";
51
56
  };
@@ -194,7 +199,7 @@ export declare const KnownErrors: {
194
199
  };
195
200
  AccessTokenExpired: KnownErrorConstructor<KnownError & KnownErrorBrand<"SESSION_AUTHENTICATION_ERROR"> & {
196
201
  constructorArgs: [statusCode: number, humanReadableMessage: string, details?: Json | undefined];
197
- } & KnownErrorBrand<"INVALID_SESSION_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ACCESS_TOKEN"> & KnownErrorBrand<"ACCESS_TOKEN_EXPIRED">, [expiredAt: Date | undefined]> & {
202
+ } & KnownErrorBrand<"INVALID_SESSION_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ACCESS_TOKEN"> & KnownErrorBrand<"ACCESS_TOKEN_EXPIRED">, [Date | undefined]> & {
198
203
  errorCode: "ACCESS_TOKEN_EXPIRED";
199
204
  };
200
205
  InvalidProjectForAccessToken: KnownErrorConstructor<KnownError & KnownErrorBrand<"SESSION_AUTHENTICATION_ERROR"> & {
@@ -386,5 +391,8 @@ export declare const KnownErrors: {
386
391
  ContactChannelAlreadyUsedForAuthBySomeoneElse: KnownErrorConstructor<KnownError & KnownErrorBrand<"CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE">, [type: "email", contactChannelValue?: string | undefined]> & {
387
392
  errorCode: "CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE";
388
393
  };
394
+ InvalidPollingCodeError: KnownErrorConstructor<KnownError & KnownErrorBrand<"INVALID_POLLING_CODE">, [details?: Json | undefined]> & {
395
+ errorCode: "INVALID_POLLING_CODE";
396
+ };
389
397
  };
390
398
  export {};
@@ -245,7 +245,7 @@ const AccessTokenExpired = createKnownErrorConstructor(InvalidAccessToken, "ACCE
245
245
  401,
246
246
  `Access token has expired. Please refresh it and try again.${expiredAt ? ` (The access token expired at ${expiredAt.toISOString()}.)` : ""}`,
247
247
  { expired_at_millis: expiredAt?.getTime() ?? null },
248
- ], (json) => [json.expired_at_millis ?? undefined]);
248
+ ], (json) => [json.expired_at_millis ? new Date(json.expired_at_millis) : undefined]);
249
249
  const InvalidProjectForAccessToken = createKnownErrorConstructor(InvalidAccessToken, "INVALID_PROJECT_FOR_ACCESS_TOKEN", () => [
250
250
  401,
251
251
  "Access token not valid for this project.",
@@ -255,6 +255,10 @@ const RefreshTokenNotFoundOrExpired = createKnownErrorConstructor(RefreshTokenEr
255
255
  401,
256
256
  "Refresh token not found for this project, or the session has expired/been revoked.",
257
257
  ], () => []);
258
+ const CannotDeleteCurrentSession = createKnownErrorConstructor(RefreshTokenError, "CANNOT_DELETE_CURRENT_SESSION", () => [
259
+ 400,
260
+ "Cannot delete the current session.",
261
+ ], () => []);
258
262
  const ProviderRejected = createKnownErrorConstructor(RefreshTokenError, "PROVIDER_REJECTED", () => [
259
263
  401,
260
264
  "The provider refused to refresh their token. This usually means that the provider used to authenticate the user no longer regards this session as valid, and the user must re-authenticate.",
@@ -542,7 +546,13 @@ const ContactChannelAlreadyUsedForAuthBySomeoneElse = createKnownErrorConstructo
542
546
  `This ${type} is already used for authentication by another account.`,
543
547
  { type, contact_channel_value: contactChannelValue ?? null },
544
548
  ], (json) => [json.type, json.contact_channel_value]);
549
+ const InvalidPollingCodeError = createKnownErrorConstructor(KnownError, "INVALID_POLLING_CODE", (details) => [
550
+ 400,
551
+ "The polling code is invalid or does not exist.",
552
+ details,
553
+ ], (json) => [json]);
545
554
  export const KnownErrors = {
555
+ CannotDeleteCurrentSession,
546
556
  UnsupportedError,
547
557
  BodyParsingError,
548
558
  SchemaError,
@@ -633,6 +643,7 @@ export const KnownErrors = {
633
643
  TeamPermissionNotFound,
634
644
  OAuthProviderAccessDenied,
635
645
  ContactChannelAlreadyUsedForAuthBySomeoneElse,
646
+ InvalidPollingCodeError,
636
647
  };
637
648
  // ensure that all known error codes are unique
638
649
  const knownErrorCodes = new Set();
@@ -0,0 +1,19 @@
1
+ import * as yup from "yup";
2
+ export declare const geoInfoSchema: yup.ObjectSchema<{
3
+ ip: string;
4
+ countryCode: string | null | undefined;
5
+ regionCode: string | null | undefined;
6
+ cityName: string | null | undefined;
7
+ latitude: number | null | undefined;
8
+ longitude: number | null | undefined;
9
+ tzIdentifier: string | null | undefined;
10
+ }, yup.AnyObject, {
11
+ ip: undefined;
12
+ countryCode: undefined;
13
+ regionCode: undefined;
14
+ cityName: undefined;
15
+ latitude: undefined;
16
+ longitude: undefined;
17
+ tzIdentifier: undefined;
18
+ }, "">;
19
+ export type GeoInfo = yup.InferType<typeof geoInfoSchema>;
@@ -0,0 +1,10 @@
1
+ import { yupNumber, yupObject, yupString } from "../schema-fields";
2
+ export const geoInfoSchema = yupObject({
3
+ ip: yupString().defined(),
4
+ countryCode: yupString().nullable(),
5
+ regionCode: yupString().nullable(),
6
+ cityName: yupString().nullable(),
7
+ latitude: yupNumber().nullable(),
8
+ longitude: yupNumber().nullable(),
9
+ tzIdentifier: yupString().nullable(),
10
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.7.26",
3
+ "version": "2.7.27",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",