@stackframe/stack-shared 2.5.0 → 2.5.2

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.
@@ -15,9 +15,8 @@ export class KnownError extends StatusError {
15
15
  getBody() {
16
16
  return new TextEncoder().encode(JSON.stringify({
17
17
  code: this.errorCode,
18
- message: this.humanReadableMessage,
19
18
  details: this.details,
20
- error: true,
19
+ error: this.humanReadableMessage,
21
20
  }, undefined, 2));
22
21
  }
23
22
  getHeaders() {
@@ -55,9 +54,11 @@ function createKnownErrorConstructor(SuperClass, errorCode, create, constructorA
55
54
  class KnownErrorImpl extends SuperClass {
56
55
  static errorCode = errorCode;
57
56
  name = `KnownError<${errorCode}>`;
57
+ constructorArgs;
58
58
  constructor(...args) {
59
59
  // @ts-expect-error
60
60
  super(...createFn(...args));
61
+ this.constructorArgs = args;
61
62
  }
62
63
  static constructorArgsFromJson(json) {
63
64
  return constructorArgsFromJsonFn(json);
@@ -94,52 +95,93 @@ const AllOverloadsFailed = createKnownErrorConstructor(KnownError, "ALL_OVERLOAD
94
95
  `).join("\n\n")}
95
96
  `,
96
97
  {
97
- overloadErrors,
98
+ overload_errors: overloadErrors,
98
99
  },
99
100
  ], (json) => [
100
- json.details?.overloadErrors ?? throwErr("overloadErrors not found in AllOverloadsFailed details"),
101
+ json.details?.overload_errors ?? throwErr("overload_errors not found in AllOverloadsFailed details"),
101
102
  ]);
102
103
  const ProjectAuthenticationError = createKnownErrorConstructor(KnownError, "PROJECT_AUTHENTICATION_ERROR", "inherit", "inherit");
103
- const InvalidProjectAuthentication = createKnownErrorConstructor(ProjectAuthenticationError, "INVALID_PROJECT_AUTHENTICATION", "inherit", "inherit");
104
- const ProjectKeyWithoutRequestType = createKnownErrorConstructor(InvalidProjectAuthentication, "PROJECT_KEY_WITHOUT_REQUEST_TYPE", () => [
104
+ const InvalidProjectAccess = createKnownErrorConstructor(ProjectAuthenticationError, "INVALID_PROJECT_AUTHENTICATION", "inherit", "inherit");
105
+ /**
106
+ * @deprecated Use ProjectKeyWithoutAccessType instead
107
+ */
108
+ const ProjectKeyWithoutRequestType = createKnownErrorConstructor(InvalidProjectAccess, "PROJECT_KEY_WITHOUT_REQUEST_TYPE", () => [
105
109
  400,
106
110
  "Either an API key or an admin access token was provided, but the x-stack-request-type header is missing. Set it to 'client', 'server', or 'admin' as appropriate.",
107
111
  ], () => []);
108
- const InvalidRequestType = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_REQUEST_TYPE", (requestType) => [
112
+ /**
113
+ * @deprecated Use InvalidAccessType instead
114
+ */
115
+ const InvalidRequestType = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_REQUEST_TYPE", (requestType) => [
109
116
  400,
110
117
  `The x-stack-request-type header must be 'client', 'server', or 'admin', but was '${requestType}'.`,
111
118
  ], (json) => [
112
119
  json.details?.requestType ?? throwErr("requestType not found in InvalidRequestType details"),
113
120
  ]);
114
- const RequestTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAuthentication, "REQUEST_TYPE_WITHOUT_PROJECT_ID", (requestType) => [
121
+ /**
122
+ * @deprecated Use AccessTypeWithoutProjectId instead
123
+ */
124
+ const RequestTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAccess, "REQUEST_TYPE_WITHOUT_PROJECT_ID", (requestType) => [
115
125
  400,
116
126
  `The x-stack-request-type header was '${requestType}', but the x-stack-project-id header was not provided.`,
117
127
  {
118
- requestType,
128
+ request_type: requestType,
119
129
  },
120
- ], (json) => [json.requestType]);
121
- const InvalidPublishableClientKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_PUBLISHABLE_CLIENT_KEY", (projectId) => [
130
+ ], (json) => [json.request_type]);
131
+ const ProjectKeyWithoutAccessType = createKnownErrorConstructor(InvalidProjectAccess, "PROJECT_KEY_WITHOUT_ACCESS_TYPE", () => [
132
+ 400,
133
+ "Either an API key or an admin access token was provided, but the x-stack-access-type header is missing. Set it to 'client', 'server', or 'admin' as appropriate.",
134
+ ], () => []);
135
+ const InvalidAccessType = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_ACCESS_TYPE", (requestType) => [
136
+ 400,
137
+ `The x-stack-access-type header must be 'client', 'server', or 'admin', but was '${requestType}'.`,
138
+ ], (json) => [
139
+ json.details?.requestType ?? throwErr("requestType not found in InvalidRequestType details"),
140
+ ]);
141
+ const AccessTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAccess, "ACCESS_TYPE_WITHOUT_PROJECT_ID", (requestType) => [
142
+ 400,
143
+ `The x-stack-access-type header was '${requestType}', but the x-stack-project-id header was not provided.`,
144
+ {
145
+ request_type: requestType,
146
+ },
147
+ ], (json) => [json.request_type]);
148
+ const AccessTypeRequired = createKnownErrorConstructor(InvalidProjectAccess, "ACCESS_TYPE_REQUIRED", () => [
149
+ 400,
150
+ `You must specify an access level for this Stack project. Make sure project API keys are provided (eg. x-stack-publishable-client-key) and you set the x-stack-access-type header to 'client', 'server', or 'admin'.`,
151
+ ], () => []);
152
+ const InsufficientAccessType = createKnownErrorConstructor(InvalidProjectAccess, "INSUFFICIENT_ACCESS_TYPE", (actualAccessType, allowedAccessTypes) => [
153
+ 401,
154
+ `The x-stack-access-type header must be ${allowedAccessTypes.map(s => `'${s}'`).join(" or ")}, but was '${actualAccessType}'.`,
155
+ {
156
+ actual_access_type: actualAccessType,
157
+ allowed_access_types: allowedAccessTypes,
158
+ },
159
+ ], (json) => [
160
+ json.details.actual_access_type,
161
+ json.details.allowed_access_types,
162
+ ]);
163
+ const InvalidPublishableClientKey = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_PUBLISHABLE_CLIENT_KEY", (projectId) => [
122
164
  401,
123
165
  `The publishable key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
124
166
  {
125
- projectId,
167
+ project_id: projectId,
126
168
  },
127
- ], (json) => [json.projectId]);
128
- const InvalidSecretServerKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SECRET_SERVER_KEY", (projectId) => [
169
+ ], (json) => [json.project_id]);
170
+ const InvalidSecretServerKey = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_SECRET_SERVER_KEY", (projectId) => [
129
171
  401,
130
172
  `The secret server key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
131
173
  {
132
- projectId,
174
+ project_id: projectId,
133
175
  },
134
- ], (json) => [json.projectId]);
135
- const InvalidSuperSecretAdminKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SUPER_SECRET_ADMIN_KEY", (projectId) => [
176
+ ], (json) => [json.project_id]);
177
+ const InvalidSuperSecretAdminKey = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_SUPER_SECRET_ADMIN_KEY", (projectId) => [
136
178
  401,
137
179
  `The super secret admin key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
138
180
  {
139
- projectId,
181
+ project_id: projectId,
140
182
  },
141
- ], (json) => [json.projectId]);
142
- const InvalidAdminAccessToken = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_ADMIN_ACCESS_TOKEN", "inherit", "inherit");
183
+ ], (json) => [json.project_id]);
184
+ const InvalidAdminAccessToken = createKnownErrorConstructor(InvalidProjectAccess, "INVALID_ADMIN_ACCESS_TOKEN", "inherit", "inherit");
143
185
  const UnparsableAdminAccessToken = createKnownErrorConstructor(InvalidAdminAccessToken, "UNPARSABLE_ADMIN_ACCESS_TOKEN", () => [
144
186
  401,
145
187
  "Admin access token is not parsable.",
@@ -156,27 +198,48 @@ const AdminAccessTokenIsNotAdmin = createKnownErrorConstructor(InvalidAdminAcces
156
198
  401,
157
199
  "Admin access token does not have the required permissions to access this project.",
158
200
  ], () => []);
201
+ /**
202
+ * @deprecated Use InsufficientAccessType instead
203
+ */
159
204
  const ProjectAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationError, "PROJECT_AUTHENTICATION_REQUIRED", "inherit", "inherit");
205
+ /**
206
+ * @deprecated Use InsufficientAccessType instead
207
+ */
160
208
  const ClientAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "CLIENT_AUTHENTICATION_REQUIRED", () => [
161
209
  401,
162
210
  "The publishable client key must be provided.",
163
211
  ], () => []);
212
+ /**
213
+ * @deprecated Use InsufficientAccessType instead
214
+ */
164
215
  const ServerAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "SERVER_AUTHENTICATION_REQUIRED", () => [
165
216
  401,
166
217
  "The secret server key must be provided.",
167
218
  ], () => []);
219
+ /**
220
+ * @deprecated Use InsufficientAccessType instead
221
+ */
168
222
  const ClientOrServerAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "CLIENT_OR_SERVER_AUTHENTICATION_REQUIRED", () => [
169
223
  401,
170
224
  "Either the publishable client key or the secret server key must be provided.",
171
225
  ], () => []);
226
+ /**
227
+ * @deprecated Use InsufficientAccessType instead
228
+ */
172
229
  const ClientOrAdminAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "CLIENT_OR_ADMIN_AUTHENTICATION_REQUIRED", () => [
173
230
  401,
174
231
  "Either the publishable client key or the super secret admin key must be provided.",
175
232
  ], () => []);
233
+ /**
234
+ * @deprecated Use InsufficientAccessType instead
235
+ */
176
236
  const ClientOrServerOrAdminAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "CLIENT_OR_SERVER_OR_ADMIN_AUTHENTICATION_REQUIRED", () => [
177
237
  401,
178
238
  "Either the publishable client key, the secret server key, or the super secret admin key must be provided.",
179
239
  ], () => []);
240
+ /**
241
+ * @deprecated Use InsufficientAccessType instead
242
+ */
180
243
  const AdminAuthenticationRequired = createKnownErrorConstructor(ProjectAuthenticationRequired, "ADMIN_AUTHENTICATION_REQUIRED", () => [
181
244
  401,
182
245
  "The super secret admin key must be provided.",
@@ -221,6 +284,10 @@ const UserEmailAlreadyExists = createKnownErrorConstructor(KnownError, "USER_EMA
221
284
  400,
222
285
  "User already exists.",
223
286
  ], () => []);
287
+ const CannotGetOwnUserWithoutUser = createKnownErrorConstructor(KnownError, "CANNOT_GET_OWN_USER_WITHOUT_USER", () => [
288
+ 400,
289
+ "You have specified 'me' as a userId, but did not provide authentication for a user.",
290
+ ], () => []);
224
291
  const UserNotFound = createKnownErrorConstructor(KnownError, "USER_NOT_FOUND", () => [
225
292
  404,
226
293
  "User not found.",
@@ -260,52 +327,23 @@ const PasswordTooLong = createKnownErrorConstructor(PasswordRequirementsNotMet,
260
327
  ], (json) => [
261
328
  json.details?.maxLength ?? throwErr("maxLength not found in PasswordTooLong details"),
262
329
  ]);
263
- const EmailVerificationError = createKnownErrorConstructor(KnownError, "EMAIL_VERIFICATION_ERROR", "inherit", "inherit");
264
- const EmailVerificationCodeError = createKnownErrorConstructor(EmailVerificationError, "EMAIL_VERIFICATION_CODE_ERROR", "inherit", "inherit");
265
- const EmailVerificationCodeNotFound = createKnownErrorConstructor(EmailVerificationCodeError, "EMAIL_VERIFICATION_CODE_NOT_FOUND", () => [
266
- 404,
267
- "The e-mail verification code does not exist for this project.",
268
- ], () => []);
269
- const EmailVerificationCodeExpired = createKnownErrorConstructor(EmailVerificationCodeError, "EMAIL_VERIFICATION_CODE_EXPIRED", () => [
270
- 400,
271
- "The e-mail verification code has expired.",
272
- ], () => []);
273
- const EmailVerificationCodeAlreadyUsed = createKnownErrorConstructor(EmailVerificationCodeError, "EMAIL_VERIFICATION_CODE_ALREADY_USED", () => [
274
- 400,
275
- "The e-mail verification link has already been used.",
276
- ], () => []);
277
- const MagicLinkError = createKnownErrorConstructor(KnownError, "MAGIC_LINK_ERROR", "inherit", "inherit");
278
- const MagicLinkCodeError = createKnownErrorConstructor(MagicLinkError, "MAGIC_LINK_CODE_ERROR", "inherit", "inherit");
279
- const MagicLinkCodeNotFound = createKnownErrorConstructor(MagicLinkCodeError, "MAGIC_LINK_CODE_NOT_FOUND", () => [
330
+ const VerificationCodeError = createKnownErrorConstructor(KnownError, "VERIFICATION_ERROR", "inherit", "inherit");
331
+ const VerificationCodeNotFound = createKnownErrorConstructor(VerificationCodeError, "VERIFICATION_CODE_NOT_FOUND", () => [
280
332
  404,
281
- "The e-mail verification code does not exist for this project.",
333
+ "The verification code does not exist for this project.",
282
334
  ], () => []);
283
- const MagicLinkCodeExpired = createKnownErrorConstructor(MagicLinkCodeError, "MAGIC_LINK_CODE_EXPIRED", () => [
335
+ const VerificationCodeExpired = createKnownErrorConstructor(VerificationCodeError, "VERIFICATION_CODE_EXPIRED", () => [
284
336
  400,
285
- "The e-mail verification code has expired.",
337
+ "The verification code has expired.",
286
338
  ], () => []);
287
- const MagicLinkCodeAlreadyUsed = createKnownErrorConstructor(MagicLinkCodeError, "MAGIC_LINK_CODE_ALREADY_USED", () => [
339
+ const VerificationCodeAlreadyUsed = createKnownErrorConstructor(VerificationCodeError, "VERIFICATION_CODE_ALREADY_USED", () => [
288
340
  400,
289
- "The e-mail verification link has already been used.",
341
+ "The verification link has already been used.",
290
342
  ], () => []);
291
343
  const PasswordMismatch = createKnownErrorConstructor(KnownError, "PASSWORD_MISMATCH", () => [
292
344
  400,
293
345
  "Passwords do not match.",
294
346
  ], () => []);
295
- const PasswordResetError = createKnownErrorConstructor(KnownError, "PASSWORD_RESET_ERROR", "inherit", "inherit");
296
- const PasswordResetCodeError = createKnownErrorConstructor(PasswordResetError, "PASSWORD_RESET_CODE_ERROR", "inherit", "inherit");
297
- const PasswordResetCodeNotFound = createKnownErrorConstructor(PasswordResetCodeError, "PASSWORD_RESET_CODE_NOT_FOUND", () => [
298
- 404,
299
- "The password reset code does not exist for this project.",
300
- ], () => []);
301
- const PasswordResetCodeExpired = createKnownErrorConstructor(PasswordResetCodeError, "PASSWORD_RESET_CODE_EXPIRED", () => [
302
- 400,
303
- "The password reset code has expired.",
304
- ], () => []);
305
- const PasswordResetCodeAlreadyUsed = createKnownErrorConstructor(PasswordResetCodeError, "PASSWORD_RESET_CODE_ALREADY_USED", () => [
306
- 400,
307
- "The password reset code has already been used.",
308
- ], () => []);
309
347
  const EmailAlreadyVerified = createKnownErrorConstructor(KnownError, "EMAIL_ALREADY_VERIFIED", () => [
310
348
  400,
311
349
  "The e-mail is already verified.",
@@ -314,9 +352,9 @@ const PermissionNotFound = createKnownErrorConstructor(KnownError, "PERMISSION_N
314
352
  404,
315
353
  `Permission ${permissionId} not found. Make sure you created it on the dashboard.`,
316
354
  {
317
- permissionId,
355
+ permission_id: permissionId,
318
356
  },
319
- ], (json) => [json.details.permissionId]);
357
+ ], (json) => [json.details.permission_id]);
320
358
  const PermissionScopeMismatch = createKnownErrorConstructor(KnownError, "PERMISSION_SCOPE_MISMATCH", (permissionId, permissionScope, testScope) => {
321
359
  return [
322
360
  400,
@@ -326,19 +364,27 @@ const PermissionScopeMismatch = createKnownErrorConstructor(KnownError, "PERMISS
326
364
  "specific-team": `Please specify the team. For example: \`user.hasPermission(team, ${JSON.stringify(permissionId)})\`.`,
327
365
  }[permissionScope.type]}`,
328
366
  {
329
- permissionId,
330
- permissionScope,
331
- testScope,
367
+ permission_id: permissionId,
368
+ permission_scope: permissionScope,
369
+ test_scope: testScope,
332
370
  },
333
371
  ];
334
- }, (json) => [json.details.permissionId, json.details.permissionScope, json.details.testScope]);
372
+ }, (json) => [json.details.permission_id, json.details.permission_scope, json.details.test_scope]);
373
+ const UserNotInTeam = createKnownErrorConstructor(KnownError, "USER_NOT_IN_TEAM", (userId, teamId) => [
374
+ 400,
375
+ `User ${userId} is not in team ${teamId}.`,
376
+ {
377
+ user_id: userId,
378
+ team_id: teamId,
379
+ },
380
+ ], (json) => [json.details.user_id, json.details.team_id]);
335
381
  const TeamNotFound = createKnownErrorConstructor(KnownError, "TEAM_NOT_FOUND", (teamId) => [
336
382
  404,
337
383
  `Team ${teamId} not found.`,
338
384
  {
339
- teamId,
385
+ team_id: teamId,
340
386
  },
341
- ], (json) => [json.details.teamId]);
387
+ ], (json) => [json.details.team_id]);
342
388
  const EmailTemplateAlreadyExists = createKnownErrorConstructor(KnownError, "EMAIL_TEMPLATE_ALREADY_EXISTS", () => [
343
389
  400,
344
390
  "Email template already exists.",
@@ -377,10 +423,16 @@ export const KnownErrors = {
377
423
  SchemaError,
378
424
  AllOverloadsFailed,
379
425
  ProjectAuthenticationError,
380
- InvalidProjectAuthentication,
426
+ InvalidProjectAuthentication: InvalidProjectAccess,
381
427
  ProjectKeyWithoutRequestType,
382
428
  InvalidRequestType,
383
429
  RequestTypeWithoutProjectId,
430
+ ProjectKeyWithoutAccessType,
431
+ InvalidAccessType,
432
+ AccessTypeWithoutProjectId,
433
+ AccessTypeRequired,
434
+ CannotGetOwnUserWithoutUser,
435
+ InsufficientAccessType,
384
436
  InvalidPublishableClientKey,
385
437
  InvalidSecretServerKey,
386
438
  InvalidSuperSecretAdminKey,
@@ -417,21 +469,10 @@ export const KnownErrors = {
417
469
  PasswordRequirementsNotMet,
418
470
  PasswordTooShort,
419
471
  PasswordTooLong,
420
- EmailVerificationError,
421
- EmailVerificationCodeError,
422
- EmailVerificationCodeNotFound,
423
- EmailVerificationCodeExpired,
424
- EmailVerificationCodeAlreadyUsed,
425
- MagicLinkError,
426
- MagicLinkCodeError,
427
- MagicLinkCodeNotFound,
428
- MagicLinkCodeExpired,
429
- MagicLinkCodeAlreadyUsed,
430
- PasswordResetError,
431
- PasswordResetCodeError,
432
- PasswordResetCodeNotFound,
433
- PasswordResetCodeExpired,
434
- PasswordResetCodeAlreadyUsed,
472
+ VerificationCodeError,
473
+ VerificationCodeNotFound,
474
+ VerificationCodeExpired,
475
+ VerificationCodeAlreadyUsed,
435
476
  PasswordMismatch,
436
477
  EmailAlreadyVerified,
437
478
  PermissionNotFound,
@@ -0,0 +1,43 @@
1
+ import * as yup from "yup";
2
+ declare const StackAdaptSentinel: unique symbol;
3
+ export type StackAdaptSentinel = typeof StackAdaptSentinel;
4
+ export declare const adaptSchema: yup.MixedSchema<typeof StackAdaptSentinel | undefined, yup.AnyObject, undefined, "">;
5
+ /**
6
+ * Yup's URL schema does not recognize some URLs (including `http://localhost`) as a valid URL. This schema is a workaround for that.
7
+ */
8
+ export declare const urlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
9
+ export declare const clientOrHigherAuthTypeSchema: yup.StringSchema<"client" | "server" | "admin" | undefined, yup.AnyObject, undefined, "">;
10
+ export declare const serverOrHigherAuthTypeSchema: yup.StringSchema<"server" | "admin" | undefined, yup.AnyObject, undefined, "">;
11
+ export declare const adminAuthTypeSchema: yup.StringSchema<"admin" | undefined, yup.AnyObject, undefined, "">;
12
+ export declare const projectIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
13
+ export declare const userIdRequestSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
14
+ export declare class ReplaceFieldWithOwnUserId extends Error {
15
+ readonly path: string;
16
+ constructor(path: string);
17
+ }
18
+ export declare const userIdOrMeRequestSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
19
+ export declare const userIdResponseSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
20
+ export declare const primaryEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
21
+ export declare const primaryEmailVerifiedSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
22
+ export declare const userDisplayNameSchema: yup.StringSchema<string | null | undefined, yup.AnyObject, undefined, "">;
23
+ export declare const selectedTeamIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
24
+ export declare const profileImageUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
25
+ export declare const signedUpAtMillisSchema: yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
26
+ export declare const userClientMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
27
+ export declare const userServerMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
28
+ export declare const signInEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
29
+ export declare const verificationLinkRedirectUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
30
+ export declare const accessTokenResponseSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
31
+ export declare const refreshTokenResponseSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
32
+ export declare const signInResponseSchema: yup.ObjectSchema<{
33
+ refresh_token: string;
34
+ access_token: string;
35
+ is_new_user: NonNullable<boolean | undefined>;
36
+ user_id: string;
37
+ }, yup.AnyObject, {
38
+ refresh_token: undefined;
39
+ access_token: undefined;
40
+ is_new_user: undefined;
41
+ user_id: undefined;
42
+ }, "">;
43
+ export {};
@@ -0,0 +1,68 @@
1
+ import * as yup from "yup";
2
+ import { yupJson } from "./utils/yup";
3
+ // Common
4
+ export const adaptSchema = yup.mixed();
5
+ /**
6
+ * Yup's URL schema does not recognize some URLs (including `http://localhost`) as a valid URL. This schema is a workaround for that.
7
+ */
8
+ export const urlSchema = yup.string().test({
9
+ name: 'url',
10
+ message: 'Invalid URL',
11
+ test: (value) => {
12
+ if (value === undefined)
13
+ return true;
14
+ try {
15
+ new URL(value);
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ },
22
+ });
23
+ // Request auth
24
+ export const clientOrHigherAuthTypeSchema = yup.string().oneOf(['client', 'server', 'admin']);
25
+ export const serverOrHigherAuthTypeSchema = yup.string().oneOf(['server', 'admin']);
26
+ export const adminAuthTypeSchema = yup.string().oneOf(['admin']);
27
+ // Projects
28
+ export const projectIdSchema = yup.string().meta({ openapiField: { description: 'Project ID as retrieved on Stack\'s dashboard', exampleValue: 'project-id' } });
29
+ // Users
30
+ export const userIdRequestSchema = yup.string().uuid().meta({ openapiField: { description: 'The ID of the user', exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
31
+ export class ReplaceFieldWithOwnUserId extends Error {
32
+ path;
33
+ constructor(path) {
34
+ super(`This error should be caught by whoever validated the schema, and the field in the path '${path}' should be replaced with the current user's id. This is a workaround to yup not providing access to the context inside the transform function.`);
35
+ this.path = path;
36
+ }
37
+ }
38
+ const userIdMeSentinelUuid = "cad564fd-f81b-43f4-b390-98abf3fcc17e";
39
+ export const userIdOrMeRequestSchema = yup.string().uuid().transform(v => {
40
+ if (v === "me")
41
+ return userIdMeSentinelUuid;
42
+ else
43
+ return v;
44
+ }).test((v, context) => {
45
+ if (v === userIdMeSentinelUuid)
46
+ throw new ReplaceFieldWithOwnUserId(context.path);
47
+ return true;
48
+ }).meta({ openapiField: { description: 'The ID of the user, or the special value `me` to signify the currently authenticated user', exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
49
+ export const userIdResponseSchema = yup.string().uuid().meta({ openapiField: { description: 'The immutable user ID used to uniquely identify this user', exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
50
+ export const primaryEmailSchema = yup.string().email().meta({ openapiField: { description: 'Primary email', exampleValue: 'johndoe@example.com' } });
51
+ export const primaryEmailVerifiedSchema = yup.boolean().meta({ openapiField: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
52
+ export const userDisplayNameSchema = yup.string().nullable().meta({ openapiField: { description: 'Human-readable display name', exampleValue: 'John Doe' } });
53
+ export const selectedTeamIdSchema = yup.string().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
54
+ export const profileImageUrlSchema = yup.string().meta({ openapiField: { description: 'Profile image URL', exampleValue: 'https://example.com/image.jpg' } });
55
+ export const signedUpAtMillisSchema = yup.number().meta({ openapiField: { description: 'Signed up at milliseconds', exampleValue: 1630000000000 } });
56
+ export const userClientMetadataSchema = yupJson.meta({ openapiField: { description: 'Client metadata. Used as a data store, accessible from the client side', exampleValue: { key: 'value' } } });
57
+ export const userServerMetadataSchema = yupJson.meta({ openapiField: { description: 'Server metadata. Used as a data store, only accessible from the server side', exampleValue: { key: 'value' } } });
58
+ // Auth
59
+ export const signInEmailSchema = yup.string().email().meta({ openapiField: { description: 'The email to sign in with.', exampleValue: 'johndoe@example.com' } });
60
+ export const verificationLinkRedirectUrlSchema = urlSchema.meta({ openapiField: { description: 'The URL to redirect to after the user has verified their email. A query argument `code` with the verification code will be appended to it.', exampleValue: 'https://example.com/handler' } });
61
+ export const accessTokenResponseSchema = yup.string().meta({ openapiField: { description: 'Short-lived access token that can be used to authenticate the user', exampleValue: 'eyJhmMiJBMTO...diI4QT' } });
62
+ export const refreshTokenResponseSchema = yup.string().meta({ openapiField: { description: 'Long-lived refresh token that can be used to obtain a new access token', exampleValue: 'i8nsoaq2...14y' } });
63
+ export const signInResponseSchema = yup.object({
64
+ refresh_token: refreshTokenResponseSchema.required(),
65
+ access_token: accessTokenResponseSchema.required(),
66
+ is_new_user: yup.boolean().meta({ openapiField: { description: 'Whether the user is a new user', exampleValue: true } }).required(),
67
+ user_id: userIdResponseSchema.required(),
68
+ });
@@ -1,5 +1,6 @@
1
1
  export declare function isBrowserLike(): boolean;
2
2
  /**
3
- * Returns the environment variable with the given name, throwing an error if it's undefined or the empty string.
3
+ * Returns the environment variable with the given name, returning the default (if given) or throwing an error (otherwise) if it's undefined or the empty string.
4
4
  */
5
- export declare function getEnvVariable(name: string): string;
5
+ export declare function getEnvVariable(name: string, defaultValue?: string | undefined): string;
6
+ export declare function getNodeEnvironment(): string;
package/dist/utils/env.js CHANGED
@@ -4,9 +4,9 @@ export function isBrowserLike() {
4
4
  return typeof window !== "undefined" && typeof document !== "undefined" && typeof document.createElement !== "undefined";
5
5
  }
6
6
  /**
7
- * Returns the environment variable with the given name, throwing an error if it's undefined or the empty string.
7
+ * Returns the environment variable with the given name, returning the default (if given) or throwing an error (otherwise) if it's undefined or the empty string.
8
8
  */
9
- export function getEnvVariable(name) {
9
+ export function getEnvVariable(name, defaultValue) {
10
10
  if (isBrowserLike()) {
11
11
  throw new Error(deindent `
12
12
  Can't use getEnvVariable on the client because Next.js transpiles expressions of the kind process.env.XYZ at build-time on the client.
@@ -14,5 +14,8 @@ export function getEnvVariable(name) {
14
14
  Use process.env.XYZ directly instead.
15
15
  `);
16
16
  }
17
- return (process.env[name] ?? throwErr(`Missing environment variable: ${name}`)) || throwErr(`Empty environment variable: ${name}`);
17
+ return ((process.env[name] || defaultValue) ?? throwErr(`Missing environment variable: ${name}`)) || (defaultValue ?? throwErr(`Empty environment variable: ${name}`));
18
+ }
19
+ export function getNodeEnvironment() {
20
+ return getEnvVariable("NODE_ENV", "");
18
21
  }
@@ -110,7 +110,7 @@ export class StatusError extends Error {
110
110
  }
111
111
  toHttpJson() {
112
112
  return {
113
- statusCode: this.statusCode,
113
+ status_code: this.statusCode,
114
114
  body: this.message,
115
115
  headers: this.getHeaders(),
116
116
  };
@@ -7,11 +7,14 @@ export type DeepPartial<T> = T extends object ? {
7
7
  * Note that since they are assumed to be plain objects, this function does not compare prototypes.
8
8
  */
9
9
  export declare function deepPlainEquals<T>(obj1: T, obj2: unknown): obj2 is T;
10
+ export declare function deepPlainClone<T>(obj: T): T;
11
+ export declare function deepPlainSnakeCaseToCamelCase(snakeCaseObj: any): any;
12
+ export declare function deepPlainCamelCaseToSnakeCase(camelCaseObj: any): any;
10
13
  export declare function typedEntries<T extends {}>(obj: T): [keyof T, T[keyof T]][];
11
14
  export declare function typedFromEntries<K extends PropertyKey, V>(entries: [K, V][]): Record<K, V>;
12
15
  export declare function typedKeys<T extends {}>(obj: T): (keyof T)[];
13
16
  export declare function typedValues<T extends {}>(obj: T): T[keyof T][];
14
- export declare function typedAssign<T extends {}, U extends {}>(target: T, source: U): asserts target is T & U;
17
+ export declare function typedAssign<T extends {}, U extends {}>(target: T, source: U): T & U;
15
18
  export type FilterUndefined<T> = {
16
19
  [k in keyof T as (undefined extends T[k] ? (T[k] extends undefined | void ? never : k) : never)]+?: T[k] & ({} | null);
17
20
  } & {
@@ -1,3 +1,5 @@
1
+ import { StackAssertionError } from "./errors";
2
+ import { camelCaseToSnakeCase, snakeCaseToCamelCase } from "./strings";
1
3
  /**
2
4
  * Assumes both objects are primitives, arrays, or non-function plain objects, and compares them deeply.
3
5
  *
@@ -39,6 +41,35 @@ export function deepPlainEquals(obj1, obj2) {
39
41
  }
40
42
  }
41
43
  }
44
+ export function deepPlainClone(obj) {
45
+ if (typeof obj === 'function')
46
+ throw new StackAssertionError("deepPlainClone does not support functions");
47
+ if (typeof obj === 'symbol')
48
+ throw new StackAssertionError("deepPlainClone does not support symbols");
49
+ if (typeof obj !== 'object' || !obj)
50
+ return obj;
51
+ if (Array.isArray(obj))
52
+ return obj.map(deepPlainClone);
53
+ return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, deepPlainClone(v)]));
54
+ }
55
+ export function deepPlainSnakeCaseToCamelCase(snakeCaseObj) {
56
+ if (typeof snakeCaseObj === 'function')
57
+ throw new StackAssertionError("deepPlainSnakeCaseToCamelCase does not support functions");
58
+ if (typeof snakeCaseObj !== 'object' || !snakeCaseObj)
59
+ return snakeCaseObj;
60
+ if (Array.isArray(snakeCaseObj))
61
+ return snakeCaseObj.map(deepPlainSnakeCaseToCamelCase);
62
+ return Object.fromEntries(Object.entries(snakeCaseObj).map(([k, v]) => [snakeCaseToCamelCase(k), deepPlainSnakeCaseToCamelCase(v)]));
63
+ }
64
+ export function deepPlainCamelCaseToSnakeCase(camelCaseObj) {
65
+ if (typeof camelCaseObj === 'function')
66
+ throw new StackAssertionError("deepPlainCamelCaseToSnakeCase does not support functions");
67
+ if (typeof camelCaseObj !== 'object' || !camelCaseObj)
68
+ return camelCaseObj;
69
+ if (Array.isArray(camelCaseObj))
70
+ return camelCaseObj.map(deepPlainCamelCaseToSnakeCase);
71
+ return Object.fromEntries(Object.entries(camelCaseObj).map(([k, v]) => [camelCaseToSnakeCase(k), deepPlainCamelCaseToSnakeCase(v)]));
72
+ }
42
73
  export function typedEntries(obj) {
43
74
  return Object.entries(obj);
44
75
  }
@@ -52,7 +83,7 @@ export function typedValues(obj) {
52
83
  return Object.values(obj);
53
84
  }
54
85
  export function typedAssign(target, source) {
55
- Object.assign(target, source);
86
+ return Object.assign(target, source);
56
87
  }
57
88
  /**
58
89
  * Returns a new object with all undefined values removed. Useful when spreading optional parameters on an object, as
@@ -41,6 +41,8 @@ export declare function deindent(code: string): string;
41
41
  export declare function deindent(strings: TemplateStringsArray | readonly string[], ...values: any[]): string;
42
42
  export declare function extractScopes(scope: string, removeDuplicates?: boolean): string[];
43
43
  export declare function mergeScopeStrings(...scopes: string[]): string;
44
+ export declare function snakeCaseToCamelCase(snakeCase: string): string;
45
+ export declare function camelCaseToSnakeCase(camelCase: string): string;
44
46
  export type Nicifiable = {
45
47
  getNicifiableKeys?(): PropertyKey[];
46
48
  getNicifiedObjectExtraLines?(): string[];
@@ -57,7 +59,8 @@ export type NicifyOptions = {
57
59
  value: unknown;
58
60
  };
59
61
  keyInParent: PropertyKey | null;
60
- overrides: (...args: Parameters<typeof nicify>) => ["result", string] | ["replace", unknown] | null;
62
+ hideFields: PropertyKey[];
63
+ overrides: (...args: Parameters<typeof nicify>) => string | null;
61
64
  };
62
65
  export declare function nicify(value: unknown, options?: Partial<NicifyOptions>): string;
63
66
  export declare function replaceAll(input: string, searchValue: string, replaceValue: string): string;