@stackframe/stack-shared 2.7.23 → 2.7.26
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 +10 -0
- package/dist/interface/crud/projects.d.ts +10 -0
- package/dist/interface/crud/projects.js +2 -0
- package/dist/known-errors.d.ts +4 -1
- package/dist/known-errors.js +11 -4
- package/dist/schema-fields.d.ts +1 -0
- package/dist/schema-fields.js +5 -0
- package/dist/utils/arrays.js +0 -1
- package/dist/utils/proxies.js +0 -31
- package/dist/utils/strings.js +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -64,6 +64,7 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
|
|
|
64
64
|
team_member_default_permissions: {
|
|
65
65
|
id: string;
|
|
66
66
|
}[];
|
|
67
|
+
oauth_account_merge_strategy: "link_method" | "raise_error" | "allow_duplicates";
|
|
67
68
|
};
|
|
68
69
|
}, import("yup").AnyObject, {
|
|
69
70
|
id: undefined;
|
|
@@ -96,6 +97,7 @@ export declare const projectsCrudAdminReadSchema: import("yup").ObjectSchema<{
|
|
|
96
97
|
create_team_on_sign_up: undefined;
|
|
97
98
|
team_creator_default_permissions: undefined;
|
|
98
99
|
team_member_default_permissions: undefined;
|
|
100
|
+
oauth_account_merge_strategy: undefined;
|
|
99
101
|
};
|
|
100
102
|
}, "">;
|
|
101
103
|
export declare const projectsCrudClientReadSchema: import("yup").ObjectSchema<{
|
|
@@ -166,6 +168,7 @@ export declare const projectsCrudAdminUpdateSchema: import("yup").ObjectSchema<{
|
|
|
166
168
|
team_member_default_permissions?: {
|
|
167
169
|
id: string;
|
|
168
170
|
}[] | undefined;
|
|
171
|
+
oauth_account_merge_strategy?: "link_method" | "raise_error" | "allow_duplicates" | undefined;
|
|
169
172
|
} | undefined;
|
|
170
173
|
}, import("yup").AnyObject, {
|
|
171
174
|
display_name: undefined;
|
|
@@ -214,6 +217,7 @@ export declare const projectsCrudAdminCreateSchema: import("yup").ObjectSchema<{
|
|
|
214
217
|
team_member_default_permissions?: {
|
|
215
218
|
id: string;
|
|
216
219
|
}[] | undefined;
|
|
220
|
+
oauth_account_merge_strategy?: "link_method" | "raise_error" | "allow_duplicates" | undefined;
|
|
217
221
|
} | undefined;
|
|
218
222
|
} & {
|
|
219
223
|
display_name: string;
|
|
@@ -300,6 +304,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
|
|
|
300
304
|
team_member_default_permissions: {
|
|
301
305
|
id: string;
|
|
302
306
|
}[];
|
|
307
|
+
oauth_account_merge_strategy: "link_method" | "raise_error" | "allow_duplicates";
|
|
303
308
|
};
|
|
304
309
|
}, import("yup").AnyObject, {
|
|
305
310
|
id: undefined;
|
|
@@ -332,6 +337,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
|
|
|
332
337
|
create_team_on_sign_up: undefined;
|
|
333
338
|
team_creator_default_permissions: undefined;
|
|
334
339
|
team_member_default_permissions: undefined;
|
|
340
|
+
oauth_account_merge_strategy: undefined;
|
|
335
341
|
};
|
|
336
342
|
}, "">;
|
|
337
343
|
adminUpdateSchema: import("yup").ObjectSchema<{
|
|
@@ -375,6 +381,7 @@ export declare const projectsCrud: import("../../crud").CrudSchemaFromOptions<{
|
|
|
375
381
|
team_member_default_permissions?: {
|
|
376
382
|
id: string;
|
|
377
383
|
}[] | undefined;
|
|
384
|
+
oauth_account_merge_strategy?: "link_method" | "raise_error" | "allow_duplicates" | undefined;
|
|
378
385
|
} | undefined;
|
|
379
386
|
}, import("yup").AnyObject, {
|
|
380
387
|
display_name: undefined;
|
|
@@ -456,6 +463,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
|
|
|
456
463
|
team_member_default_permissions: {
|
|
457
464
|
id: string;
|
|
458
465
|
}[];
|
|
466
|
+
oauth_account_merge_strategy: "link_method" | "raise_error" | "allow_duplicates";
|
|
459
467
|
};
|
|
460
468
|
}, import("yup").AnyObject, {
|
|
461
469
|
id: undefined;
|
|
@@ -488,6 +496,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
|
|
|
488
496
|
create_team_on_sign_up: undefined;
|
|
489
497
|
team_creator_default_permissions: undefined;
|
|
490
498
|
team_member_default_permissions: undefined;
|
|
499
|
+
oauth_account_merge_strategy: undefined;
|
|
491
500
|
};
|
|
492
501
|
}, "">;
|
|
493
502
|
clientCreateSchema: import("yup").ObjectSchema<{
|
|
@@ -531,6 +540,7 @@ export declare const internalProjectsCrud: import("../../crud").CrudSchemaFromOp
|
|
|
531
540
|
team_member_default_permissions?: {
|
|
532
541
|
id: string;
|
|
533
542
|
}[] | undefined;
|
|
543
|
+
oauth_account_merge_strategy?: "link_method" | "raise_error" | "allow_duplicates" | undefined;
|
|
534
544
|
} | undefined;
|
|
535
545
|
} & {
|
|
536
546
|
display_name: string;
|
|
@@ -74,6 +74,7 @@ export const projectsCrudAdminReadSchema = yupObject({
|
|
|
74
74
|
create_team_on_sign_up: schemaFields.projectCreateTeamOnSignUpSchema.defined(),
|
|
75
75
|
team_creator_default_permissions: yupArray(teamPermissionSchema.defined()).defined(),
|
|
76
76
|
team_member_default_permissions: yupArray(teamPermissionSchema.defined()).defined(),
|
|
77
|
+
oauth_account_merge_strategy: schemaFields.oauthAccountMergeStrategySchema.defined(),
|
|
77
78
|
}).defined(),
|
|
78
79
|
}).defined();
|
|
79
80
|
export const projectsCrudClientReadSchema = yupObject({
|
|
@@ -107,6 +108,7 @@ export const projectsCrudAdminUpdateSchema = yupObject({
|
|
|
107
108
|
create_team_on_sign_up: schemaFields.projectCreateTeamOnSignUpSchema.optional(),
|
|
108
109
|
team_creator_default_permissions: yupArray(teamPermissionSchema.defined()).optional(),
|
|
109
110
|
team_member_default_permissions: yupArray(teamPermissionSchema.defined()).optional(),
|
|
111
|
+
oauth_account_merge_strategy: schemaFields.oauthAccountMergeStrategySchema.optional(),
|
|
110
112
|
}).optional().default(undefined),
|
|
111
113
|
}).defined();
|
|
112
114
|
export const projectsCrudAdminCreateSchema = projectsCrudAdminUpdateSchema.concat(yupObject({
|
package/dist/known-errors.d.ts
CHANGED
|
@@ -218,6 +218,9 @@ export declare const KnownErrors: {
|
|
|
218
218
|
UserEmailAlreadyExists: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_EMAIL_ALREADY_EXISTS">, []> & {
|
|
219
219
|
errorCode: "USER_EMAIL_ALREADY_EXISTS";
|
|
220
220
|
};
|
|
221
|
+
EmailNotVerified: KnownErrorConstructor<KnownError & KnownErrorBrand<"EMAIL_NOT_VERIFIED">, []> & {
|
|
222
|
+
errorCode: "EMAIL_NOT_VERIFIED";
|
|
223
|
+
};
|
|
221
224
|
UserIdDoesNotExist: KnownErrorConstructor<KnownError & KnownErrorBrand<"USER_ID_DOES_NOT_EXIST">, [userId: string]> & {
|
|
222
225
|
errorCode: "USER_ID_DOES_NOT_EXIST";
|
|
223
226
|
};
|
|
@@ -380,7 +383,7 @@ export declare const KnownErrors: {
|
|
|
380
383
|
OAuthProviderAccessDenied: KnownErrorConstructor<KnownError & KnownErrorBrand<"OAUTH_PROVIDER_ACCESS_DENIED">, []> & {
|
|
381
384
|
errorCode: "OAUTH_PROVIDER_ACCESS_DENIED";
|
|
382
385
|
};
|
|
383
|
-
ContactChannelAlreadyUsedForAuthBySomeoneElse: KnownErrorConstructor<KnownError & KnownErrorBrand<"CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE">, [type: "email"]> & {
|
|
386
|
+
ContactChannelAlreadyUsedForAuthBySomeoneElse: KnownErrorConstructor<KnownError & KnownErrorBrand<"CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE">, [type: "email", contactChannelValue?: string | undefined]> & {
|
|
384
387
|
errorCode: "CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE";
|
|
385
388
|
};
|
|
386
389
|
};
|
package/dist/known-errors.js
CHANGED
|
@@ -263,6 +263,10 @@ const UserEmailAlreadyExists = createKnownErrorConstructor(KnownError, "USER_EMA
|
|
|
263
263
|
409,
|
|
264
264
|
"User email already exists.",
|
|
265
265
|
], () => []);
|
|
266
|
+
const EmailNotVerified = createKnownErrorConstructor(KnownError, "EMAIL_NOT_VERIFIED", () => [
|
|
267
|
+
400,
|
|
268
|
+
"The email is not verified.",
|
|
269
|
+
], () => []);
|
|
266
270
|
const CannotGetOwnUserWithoutUser = createKnownErrorConstructor(KnownError, "CANNOT_GET_OWN_USER_WITHOUT_USER", () => [
|
|
267
271
|
400,
|
|
268
272
|
"You have specified 'me' as a userId, but did not provide authentication for a user.",
|
|
@@ -531,11 +535,13 @@ const OAuthProviderAccessDenied = createKnownErrorConstructor(KnownError, "OAUTH
|
|
|
531
535
|
400,
|
|
532
536
|
"The OAuth provider denied access to the user.",
|
|
533
537
|
], () => []);
|
|
534
|
-
const ContactChannelAlreadyUsedForAuthBySomeoneElse = createKnownErrorConstructor(KnownError, "CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE", (type) => [
|
|
538
|
+
const ContactChannelAlreadyUsedForAuthBySomeoneElse = createKnownErrorConstructor(KnownError, "CONTACT_CHANNEL_ALREADY_USED_FOR_AUTH_BY_SOMEONE_ELSE", (type, contactChannelValue) => [
|
|
535
539
|
409,
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
540
|
+
contactChannelValue ?
|
|
541
|
+
`The ${type} (${contactChannelValue}) is already used for authentication by another account.` :
|
|
542
|
+
`This ${type} is already used for authentication by another account.`,
|
|
543
|
+
{ type, contact_channel_value: contactChannelValue ?? null },
|
|
544
|
+
], (json) => [json.type, json.contact_channel_value]);
|
|
539
545
|
export const KnownErrors = {
|
|
540
546
|
UnsupportedError,
|
|
541
547
|
BodyParsingError,
|
|
@@ -575,6 +581,7 @@ export const KnownErrors = {
|
|
|
575
581
|
ProviderRejected,
|
|
576
582
|
RefreshTokenNotFoundOrExpired,
|
|
577
583
|
UserEmailAlreadyExists,
|
|
584
|
+
EmailNotVerified,
|
|
578
585
|
UserIdDoesNotExist,
|
|
579
586
|
UserNotFound,
|
|
580
587
|
ApiKeyNotFound,
|
package/dist/schema-fields.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare const oauthClientIdSchema: yup.StringSchema<string | undefined, y
|
|
|
72
72
|
export declare const oauthClientSecretSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
73
73
|
export declare const oauthFacebookConfigIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
74
74
|
export declare const oauthMicrosoftTenantIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
75
|
+
export declare const oauthAccountMergeStrategySchema: yup.StringSchema<"link_method" | "raise_error" | "allow_duplicates" | undefined, yup.AnyObject, undefined, "">;
|
|
75
76
|
export declare const emailTypeSchema: yup.StringSchema<"shared" | "standard" | undefined, yup.AnyObject, undefined, "">;
|
|
76
77
|
export declare const emailSenderNameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
77
78
|
export declare const emailHostSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
package/dist/schema-fields.js
CHANGED
|
@@ -171,6 +171,10 @@ export const adaptSchema = yupMixed();
|
|
|
171
171
|
* Yup's URL schema does not recognize some URLs (including `http://localhost`) as a valid URL. This schema is a workaround for that.
|
|
172
172
|
*/
|
|
173
173
|
export const urlSchema = yupString().test({
|
|
174
|
+
name: 'no-spaces',
|
|
175
|
+
message: (params) => `${params.path} contains spaces`,
|
|
176
|
+
test: (value) => value == null || !value.includes(' ')
|
|
177
|
+
}).test({
|
|
174
178
|
name: 'url',
|
|
175
179
|
message: (params) => `${params.path} is not a valid URL`,
|
|
176
180
|
test: (value) => value == null || isValidUrl(value)
|
|
@@ -244,6 +248,7 @@ export const oauthClientIdSchema = yupString().meta({ openapiField: { descriptio
|
|
|
244
248
|
export const oauthClientSecretSchema = yupString().meta({ openapiField: { description: 'OAuth client secret. Needs to be specified when using type="standard"', exampleValue: 'google-oauth-client-secret' } });
|
|
245
249
|
export const oauthFacebookConfigIdSchema = yupString().meta({ openapiField: { description: 'The configuration id for Facebook business login (for things like ads and marketing). This is only required if you are using the standard OAuth with Facebook and you are using Facebook business login.' } });
|
|
246
250
|
export const oauthMicrosoftTenantIdSchema = yupString().meta({ openapiField: { description: 'The Microsoft tenant id for Microsoft directory. This is only required if you are using the standard OAuth with Microsoft and you have an Azure AD tenant.' } });
|
|
251
|
+
export const oauthAccountMergeStrategySchema = yupString().oneOf(['link_method', 'raise_error', 'allow_duplicates']).meta({ openapiField: { description: 'Determines how to handle OAuth logins that match an existing user by email. `link_method` adds the OAuth method to the existing user. `raise_error` rejects the login with an error. `allow_duplicates` creates a new user.', exampleValue: 'link_method' } });
|
|
247
252
|
// Project email config
|
|
248
253
|
export const emailTypeSchema = yupString().oneOf(['shared', 'standard']).meta({ openapiField: { description: 'Email provider type, one of shared, standard. "shared" uses Stack shared email provider and it is only meant for development. "standard" uses your own email server and will have your email address as the sender.', exampleValue: 'standard' } });
|
|
249
254
|
export const emailSenderNameSchema = yupString().meta({ openapiField: { description: 'Email sender name. Needs to be specified when using type="standard"', exampleValue: 'Stack' } });
|
package/dist/utils/arrays.js
CHANGED
|
@@ -75,7 +75,6 @@ import.meta.vitest?.test("groupBy", ({ expect }) => {
|
|
|
75
75
|
expect(grouped.get("odd")).toEqual([1, 3, 5]);
|
|
76
76
|
// Check the actual lengths of the words to ensure our test is correct
|
|
77
77
|
const words = ["apple", "banana", "cherry", "date", "elderberry"];
|
|
78
|
-
console.log("Word lengths:", words.map(w => `${w}: ${w.length}`));
|
|
79
78
|
const byLength = groupBy(words, (w) => w.length);
|
|
80
79
|
// Adjust expectations based on actual word lengths
|
|
81
80
|
expect(byLength.get(5)).toEqual(["apple"]);
|
package/dist/utils/proxies.js
CHANGED
|
@@ -57,37 +57,6 @@ export function logged(name, toLog, options = {}) {
|
|
|
57
57
|
});
|
|
58
58
|
return proxy;
|
|
59
59
|
}
|
|
60
|
-
import.meta.vitest?.test("logged", ({ expect }) => {
|
|
61
|
-
// Test with a simple object
|
|
62
|
-
const obj = {
|
|
63
|
-
value: 42,
|
|
64
|
-
method(x) { return x * 2; }
|
|
65
|
-
};
|
|
66
|
-
const loggedObj = logged("testObj", obj);
|
|
67
|
-
// Test property access
|
|
68
|
-
expect(loggedObj.value).toBe(42);
|
|
69
|
-
// Test method call
|
|
70
|
-
const result = loggedObj.method(21);
|
|
71
|
-
expect(result).toBe(42);
|
|
72
|
-
// Test property setting
|
|
73
|
-
loggedObj.value = 100;
|
|
74
|
-
expect(loggedObj.value).toBe(100);
|
|
75
|
-
// Test with a promise-returning method
|
|
76
|
-
const asyncObj = {
|
|
77
|
-
async asyncMethod(x) { return x * 3; }
|
|
78
|
-
};
|
|
79
|
-
const loggedAsyncObj = logged("asyncObj", asyncObj);
|
|
80
|
-
// Test async method
|
|
81
|
-
const promise = loggedAsyncObj.asyncMethod(7);
|
|
82
|
-
expect(promise instanceof Promise).toBe(true);
|
|
83
|
-
// Test error handling
|
|
84
|
-
const errorObj = {
|
|
85
|
-
throwError() { throw new Error("Test error"); }
|
|
86
|
-
};
|
|
87
|
-
const loggedErrorObj = logged("errorObj", errorObj);
|
|
88
|
-
// Test error throwing
|
|
89
|
-
expect(() => loggedErrorObj.throwError()).toThrow("Test error");
|
|
90
|
-
});
|
|
91
60
|
export function createLazyProxy(factory) {
|
|
92
61
|
let cache = undefined;
|
|
93
62
|
let initialized = false;
|
package/dist/utils/strings.js
CHANGED
|
@@ -2,6 +2,8 @@ import { findLastIndex, unique } from "./arrays";
|
|
|
2
2
|
import { StackAssertionError } from "./errors";
|
|
3
3
|
import { filterUndefined } from "./objects";
|
|
4
4
|
export function typedToLowercase(s) {
|
|
5
|
+
if (typeof s !== "string")
|
|
6
|
+
throw new StackAssertionError("Expected a string for typedToLowercase", { s });
|
|
5
7
|
return s.toLowerCase();
|
|
6
8
|
}
|
|
7
9
|
import.meta.vitest?.test("typedToLowercase", ({ expect }) => {
|
|
@@ -12,8 +14,11 @@ import.meta.vitest?.test("typedToLowercase", ({ expect }) => {
|
|
|
12
14
|
expect(typedToLowercase("123")).toBe("123");
|
|
13
15
|
expect(typedToLowercase("MIXED123case")).toBe("mixed123case");
|
|
14
16
|
expect(typedToLowercase("Special@Chars!")).toBe("special@chars!");
|
|
17
|
+
expect(() => typedToLowercase(123)).toThrow("Expected a string for typedToLowercase");
|
|
15
18
|
});
|
|
16
19
|
export function typedToUppercase(s) {
|
|
20
|
+
if (typeof s !== "string")
|
|
21
|
+
throw new StackAssertionError("Expected a string for typedToUppercase", { s });
|
|
17
22
|
return s.toUpperCase();
|
|
18
23
|
}
|
|
19
24
|
import.meta.vitest?.test("typedToUppercase", ({ expect }) => {
|
|
@@ -24,6 +29,7 @@ import.meta.vitest?.test("typedToUppercase", ({ expect }) => {
|
|
|
24
29
|
expect(typedToUppercase("123")).toBe("123");
|
|
25
30
|
expect(typedToUppercase("mixed123Case")).toBe("MIXED123CASE");
|
|
26
31
|
expect(typedToUppercase("special@chars!")).toBe("SPECIAL@CHARS!");
|
|
32
|
+
expect(() => typedToUppercase(123)).toThrow("Expected a string for typedToUppercase");
|
|
27
33
|
});
|
|
28
34
|
export function typedCapitalize(s) {
|
|
29
35
|
return s.charAt(0).toUpperCase() + s.slice(1);
|