@stackframe/stack-shared 2.5.2 → 2.5.4
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 +16 -0
- package/dist/crud.d.ts +10 -3
- package/dist/helpers/production-mode.d.ts +6 -0
- package/dist/helpers/production-mode.js +43 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/interface/adminInterface.d.ts +28 -67
- package/dist/interface/adminInterface.js +63 -22
- package/dist/interface/clientInterface.d.ts +21 -133
- package/dist/interface/clientInterface.js +92 -119
- package/dist/interface/crud/api-keys.d.ts +134 -0
- package/dist/interface/crud/api-keys.js +61 -0
- package/dist/interface/crud/current-user.d.ts +47 -11
- package/dist/interface/crud/current-user.js +7 -3
- package/dist/interface/crud/email-templates.d.ts +53 -34
- package/dist/interface/crud/email-templates.js +37 -24
- package/dist/interface/crud/oauth.d.ts +8 -9
- package/dist/interface/crud/oauth.js +5 -5
- package/dist/interface/crud/projects.d.ts +446 -0
- package/dist/interface/crud/projects.js +110 -0
- package/dist/interface/crud/team-memberships.d.ts +22 -0
- package/dist/interface/crud/team-memberships.js +22 -0
- package/dist/interface/crud/team-permissions.d.ts +129 -0
- package/dist/interface/crud/team-permissions.js +83 -0
- package/dist/interface/crud/teams.d.ts +148 -0
- package/dist/interface/crud/teams.js +80 -0
- package/dist/interface/crud/users.d.ts +88 -33
- package/dist/interface/crud/users.js +22 -14
- package/dist/interface/crud-deprecated/api-keys.d.ts +134 -0
- package/dist/interface/crud-deprecated/api-keys.js +61 -0
- package/dist/interface/crud-deprecated/current-user.d.ts +127 -0
- package/dist/interface/crud-deprecated/current-user.js +49 -0
- package/dist/interface/crud-deprecated/email-templates.d.ts +75 -0
- package/dist/interface/crud-deprecated/email-templates.js +41 -0
- package/dist/interface/crud-deprecated/oauth.d.ts +24 -0
- package/dist/interface/crud-deprecated/oauth.js +12 -0
- package/dist/interface/crud-deprecated/projects.d.ts +440 -0
- package/dist/interface/crud-deprecated/projects.js +109 -0
- package/dist/interface/crud-deprecated/team-memberships.d.ts +22 -0
- package/dist/interface/crud-deprecated/team-memberships.js +22 -0
- package/dist/interface/crud-deprecated/team-permissions.d.ts +129 -0
- package/dist/interface/crud-deprecated/team-permissions.js +83 -0
- package/dist/interface/crud-deprecated/teams.d.ts +126 -0
- package/dist/interface/crud-deprecated/teams.js +78 -0
- package/dist/interface/crud-deprecated/users.d.ts +201 -0
- package/dist/interface/crud-deprecated/users.js +75 -0
- package/dist/interface/serverInterface.d.ts +33 -60
- package/dist/interface/serverInterface.js +74 -102
- package/dist/known-errors.d.ts +43 -26
- package/dist/known-errors.js +135 -92
- package/dist/schema-fields.d.ts +53 -4
- package/dist/schema-fields.js +156 -26
- package/dist/sessions.d.ts +1 -0
- package/dist/sessions.js +20 -26
- package/dist/utils/arrays.d.ts +4 -0
- package/dist/utils/arrays.js +10 -0
- package/dist/utils/caches.js +11 -18
- package/dist/utils/compile-time.d.ts +3 -1
- package/dist/utils/compile-time.js +3 -1
- package/dist/utils/errors.d.ts +8 -1
- package/dist/utils/errors.js +58 -47
- package/dist/utils/globals.js +3 -0
- package/dist/utils/maps.js +8 -5
- package/dist/utils/numbers.js +5 -5
- package/dist/utils/objects.d.ts +4 -1
- package/dist/utils/objects.js +16 -8
- package/dist/utils/promises.js +6 -2
- package/dist/utils/proxies.d.ts +1 -0
- package/dist/utils/proxies.js +65 -0
- package/dist/utils/react.d.ts +1 -1
- package/dist/utils/react.js +2 -2
- package/dist/utils/results.js +0 -1
- package/dist/utils/stores.js +7 -10
- package/dist/utils/strings.js +7 -2
- package/dist/utils/urls.d.ts +1 -0
- package/dist/utils/urls.js +8 -0
- package/dist/utils/uuids.d.ts +1 -1
- package/dist/utils/uuids.js +2 -1
- package/package.json +2 -2
- package/dist/utils/yup.d.ts +0 -3
- package/dist/utils/yup.js +0 -13
package/dist/schema-fields.js
CHANGED
|
@@ -1,11 +1,63 @@
|
|
|
1
1
|
import * as yup from "yup";
|
|
2
|
-
|
|
2
|
+
const _idDescription = (identify) => `The immutable ID used to uniquely identify this ${identify}`;
|
|
3
|
+
const _displayNameDescription = (identify) => `Human-readable ${identify} display name, used in places like frontend UI. This is not a unique identifier.`;
|
|
4
|
+
const _clientMetaDataDescription = (identify) => `Client metadata. Used as a data store, accessible from the client side. Do not store information that should not be exposed to the client.`;
|
|
5
|
+
const _serverMetaDataDescription = (identify) => `Server metadata. Used as a data store, only accessible from the server side. You can store secret information related to the ${identify} here.`;
|
|
6
|
+
const _atMillisDescription = (identify) => `(the number of milliseconds since epoch, January 1, 1970, UTC)`;
|
|
7
|
+
const _createdAtMillisDescription = (identify) => `The time the ${identify} was created ${_atMillisDescription(identify)}`;
|
|
8
|
+
const _updatedAtMillisDescription = (identify) => `The time the ${identify} was last updated ${_atMillisDescription(identify)}`;
|
|
9
|
+
// Built-in replacements
|
|
10
|
+
/* eslint-disable no-restricted-syntax */
|
|
11
|
+
export function yupString(...args) {
|
|
12
|
+
return yup.string(...args);
|
|
13
|
+
}
|
|
14
|
+
export function yupNumber(...args) {
|
|
15
|
+
return yup.number(...args);
|
|
16
|
+
}
|
|
17
|
+
export function yupBoolean(...args) {
|
|
18
|
+
return yup.boolean(...args);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated, use number of milliseconds since epoch instead
|
|
22
|
+
*/
|
|
23
|
+
export function yupDate(...args) {
|
|
24
|
+
return yup.date(...args);
|
|
25
|
+
}
|
|
26
|
+
export function yupMixed(...args) {
|
|
27
|
+
return yup.mixed(...args);
|
|
28
|
+
}
|
|
29
|
+
export function yupArray(...args) {
|
|
30
|
+
return yup.array(...args);
|
|
31
|
+
}
|
|
32
|
+
export function yupTuple(...args) {
|
|
33
|
+
return yup.tuple(...args);
|
|
34
|
+
}
|
|
35
|
+
export function yupObject(...args) {
|
|
36
|
+
const object = yup.object(...args).test('no-unknown-object-properties', ({ path }) => `${path} contains unknown properties`, (value, context) => {
|
|
37
|
+
if (context.options.context?.noUnknownPathPrefixes?.some((prefix) => context.path.startsWith(prefix))) {
|
|
38
|
+
const availableKeys = new Set(Object.keys(context.schema.fields));
|
|
39
|
+
const unknownKeys = Object.keys(value ?? {}).filter(key => !availableKeys.has(key));
|
|
40
|
+
if (unknownKeys.length > 0) {
|
|
41
|
+
// TODO "did you mean XYZ"
|
|
42
|
+
return context.createError({
|
|
43
|
+
message: `${context.path} contains unknown properties: ${unknownKeys.join(', ')}`,
|
|
44
|
+
path: context.path,
|
|
45
|
+
params: { unknownKeys },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
});
|
|
51
|
+
// we don't want to update the type of `object` to have a default flag
|
|
52
|
+
return object.default(undefined);
|
|
53
|
+
}
|
|
54
|
+
/* eslint-enable no-restricted-syntax */
|
|
3
55
|
// Common
|
|
4
|
-
export const adaptSchema =
|
|
56
|
+
export const adaptSchema = yupMixed();
|
|
5
57
|
/**
|
|
6
58
|
* Yup's URL schema does not recognize some URLs (including `http://localhost`) as a valid URL. This schema is a workaround for that.
|
|
7
59
|
*/
|
|
8
|
-
export const urlSchema =
|
|
60
|
+
export const urlSchema = yupString().test({
|
|
9
61
|
name: 'url',
|
|
10
62
|
message: 'Invalid URL',
|
|
11
63
|
test: (value) => {
|
|
@@ -20,23 +72,62 @@ export const urlSchema = yup.string().test({
|
|
|
20
72
|
}
|
|
21
73
|
},
|
|
22
74
|
});
|
|
75
|
+
export const jsonSchema = yupMixed().nullable().defined().transform((value) => JSON.parse(JSON.stringify(value)));
|
|
76
|
+
export const jsonStringSchema = yupString().test("json", "Invalid JSON format", (value) => {
|
|
77
|
+
if (value == null)
|
|
78
|
+
return true;
|
|
79
|
+
try {
|
|
80
|
+
JSON.parse(value);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
export const emailSchema = yupString().email();
|
|
23
88
|
// Request auth
|
|
24
|
-
export const clientOrHigherAuthTypeSchema =
|
|
25
|
-
export const serverOrHigherAuthTypeSchema =
|
|
26
|
-
export const adminAuthTypeSchema =
|
|
89
|
+
export const clientOrHigherAuthTypeSchema = yupString().oneOf(['client', 'server', 'admin']);
|
|
90
|
+
export const serverOrHigherAuthTypeSchema = yupString().oneOf(['server', 'admin']);
|
|
91
|
+
export const adminAuthTypeSchema = yupString().oneOf(['admin']);
|
|
27
92
|
// Projects
|
|
28
|
-
export const projectIdSchema =
|
|
93
|
+
export const projectIdSchema = yupString().meta({ openapiField: { description: _idDescription('project'), exampleValue: 'e0b52f4d-dece-408c-af49-d23061bb0f8d' } });
|
|
94
|
+
export const projectDisplayNameSchema = yupString().meta({ openapiField: { description: _displayNameDescription('project'), exampleValue: 'MyMusic' } });
|
|
95
|
+
export const projectDescriptionSchema = yupString().nullable().meta({ openapiField: { description: 'A human readable description of the project', exampleValue: 'A music streaming service' } });
|
|
96
|
+
export const projectCreatedAtMillisSchema = yupNumber().meta({ openapiField: { description: _createdAtMillisDescription('project'), exampleValue: 1630000000000 } });
|
|
97
|
+
export const projectUserCountSchema = yupNumber().meta({ openapiField: { description: 'The number of users in this project', exampleValue: 10 } });
|
|
98
|
+
export const projectIsProductionModeSchema = yupBoolean().meta({ openapiField: { description: 'Whether the project is in production mode', exampleValue: true } });
|
|
99
|
+
// Project config
|
|
100
|
+
export const projectConfigIdSchema = yupString().meta({ openapiField: { description: _idDescription('project config'), exampleValue: 'd09201f0-54f5-40bd-89ff-6d1815ddad24' } });
|
|
101
|
+
export const projectAllowLocalhostSchema = yupBoolean().meta({ openapiField: { description: 'Whether localhost is allowed as a domain for this project. Should only be allowed in development mode', exampleValue: true } });
|
|
102
|
+
export const projectCreateTeamOnSignUpSchema = yupBoolean().meta({ openapiField: { description: 'Whether a team should be created for each user that signs up', exampleValue: true } });
|
|
103
|
+
export const projectMagicLinkEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether magic link authentication is enabled for this project', exampleValue: true } });
|
|
104
|
+
export const projectCredentialEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether email password authentication is enabled for this project', exampleValue: true } });
|
|
105
|
+
// Project OAuth config
|
|
106
|
+
export const oauthIdSchema = yupString().oneOf(['google', 'github', 'facebook', 'microsoft', 'spotify']).meta({ openapiField: { description: 'OAuth provider ID, one of google, github, facebook, microsoft, spotify', exampleValue: 'google' } });
|
|
107
|
+
export const oauthEnabledSchema = yupBoolean().meta({ openapiField: { description: 'Whether the OAuth provider is enabled. If an provider is first enabled, then disabled, it will be shown in the list but with enabled=false', exampleValue: true } });
|
|
108
|
+
export const oauthTypeSchema = yupString().oneOf(['shared', 'standard']).meta({ openapiField: { description: 'OAuth provider type, one of shared, standard. "shared" uses Stack shared OAuth keys and it is only meant for development. "standard" uses your own OAuth keys and will show your logo and company name when signing in with the provider.', exampleValue: 'standard' } });
|
|
109
|
+
export const oauthClientIdSchema = yupString().meta({ openapiField: { description: 'OAuth client ID. Needs to be specified when using type="standard"', exampleValue: 'google-oauth-client-id' } });
|
|
110
|
+
export const oauthClientSecretSchema = yupString().meta({ openapiField: { description: 'OAuth client secret. Needs to be specified when using type="standard"', exampleValue: 'google-oauth-client-secret' } });
|
|
111
|
+
// Project email config
|
|
112
|
+
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' } });
|
|
113
|
+
export const emailSenderNameSchema = yupString().meta({ openapiField: { description: 'Email sender name. Needs to be specified when using type="standard"', exampleValue: 'Stack' } });
|
|
114
|
+
export const emailHostSchema = yupString().meta({ openapiField: { description: 'Email host. Needs to be specified when using type="standard"', exampleValue: 'smtp.your-domain.com' } });
|
|
115
|
+
export const emailPortSchema = yupNumber().meta({ openapiField: { description: 'Email port. Needs to be specified when using type="standard"', exampleValue: 587 } });
|
|
116
|
+
export const emailUsernameSchema = yupString().meta({ openapiField: { description: 'Email username. Needs to be specified when using type="standard"', exampleValue: 'smtp-email' } });
|
|
117
|
+
export const emailSenderEmailSchema = emailSchema.meta({ openapiField: { description: 'Email sender email. Needs to be specified when using type="standard"', exampleValue: 'example@your-domain.com' } });
|
|
118
|
+
export const emailPasswordSchema = yupString().meta({ openapiField: { description: 'Email password. Needs to be specified when using type="standard"', exampleValue: 'your-email-password' } });
|
|
119
|
+
// Project domain config
|
|
120
|
+
export const domainSchema = yupString().test('is-https', 'Domain must start with https://', (value) => value?.startsWith('https://')).meta({ openapiField: { description: 'Your domain URL. Make sure you own and trust this domain. Needs to start with https://', exampleValue: 'example.com' } });
|
|
121
|
+
export const handlerPathSchema = yupString().test('is-handler-path', 'Handler path must start with /', (value) => value?.startsWith('/')).meta({ openapiField: { description: 'Handler path. If you did not setup a custom handler path, it should be "/handler" by default. It needs to start with /', exampleValue: '/handler' } });
|
|
29
122
|
// Users
|
|
30
|
-
export const userIdRequestSchema = yup.string().uuid().meta({ openapiField: { description: 'The ID of the user', exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
|
|
31
123
|
export class ReplaceFieldWithOwnUserId extends Error {
|
|
32
|
-
path;
|
|
33
124
|
constructor(path) {
|
|
34
125
|
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
126
|
this.path = path;
|
|
36
127
|
}
|
|
37
128
|
}
|
|
38
129
|
const userIdMeSentinelUuid = "cad564fd-f81b-43f4-b390-98abf3fcc17e";
|
|
39
|
-
export const
|
|
130
|
+
export const userIdOrMeSchema = yupString().uuid().transform(v => {
|
|
40
131
|
if (v === "me")
|
|
41
132
|
return userIdMeSentinelUuid;
|
|
42
133
|
else
|
|
@@ -46,23 +137,62 @@ export const userIdOrMeRequestSchema = yup.string().uuid().transform(v => {
|
|
|
46
137
|
throw new ReplaceFieldWithOwnUserId(context.path);
|
|
47
138
|
return true;
|
|
48
139
|
}).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
|
|
50
|
-
export const primaryEmailSchema =
|
|
51
|
-
export const primaryEmailVerifiedSchema =
|
|
52
|
-
export const userDisplayNameSchema =
|
|
53
|
-
export const selectedTeamIdSchema =
|
|
54
|
-
export const profileImageUrlSchema =
|
|
55
|
-
export const signedUpAtMillisSchema =
|
|
56
|
-
export const userClientMetadataSchema =
|
|
57
|
-
export const userServerMetadataSchema =
|
|
140
|
+
export const userIdSchema = yupString().uuid().meta({ openapiField: { description: _idDescription('user'), exampleValue: '3241a285-8329-4d69-8f3d-316e08cf140c' } });
|
|
141
|
+
export const primaryEmailSchema = emailSchema.meta({ openapiField: { description: 'Primary email', exampleValue: 'johndoe@example.com' } });
|
|
142
|
+
export const primaryEmailVerifiedSchema = yupBoolean().meta({ openapiField: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
|
|
143
|
+
export const userDisplayNameSchema = yupString().nullable().meta({ openapiField: { description: _displayNameDescription('user'), exampleValue: 'John Doe' } });
|
|
144
|
+
export const selectedTeamIdSchema = yupString().meta({ openapiField: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
|
|
145
|
+
export const profileImageUrlSchema = yupString().meta({ openapiField: { description: 'Profile image URL', exampleValue: 'https://example.com/image.jpg' } });
|
|
146
|
+
export const signedUpAtMillisSchema = yupNumber().meta({ openapiField: { description: 'Signed up at milliseconds', exampleValue: 1630000000000 } });
|
|
147
|
+
export const userClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('user'), exampleValue: { key: 'value' } } });
|
|
148
|
+
export const userServerMetadataSchema = jsonSchema.meta({ openapiField: { description: _serverMetaDataDescription('user'), exampleValue: { key: 'value' } } });
|
|
58
149
|
// Auth
|
|
59
|
-
export const signInEmailSchema =
|
|
60
|
-
export const
|
|
61
|
-
export const
|
|
62
|
-
export const
|
|
63
|
-
export const
|
|
150
|
+
export const signInEmailSchema = emailSchema.meta({ openapiField: { description: 'The email to sign in with.', exampleValue: 'johndoe@example.com' } });
|
|
151
|
+
export const emailOtpSignInCallbackUrlSchema = urlSchema.meta({ openapiField: { description: 'The base callback URL to construct the magic link from. A query argument `code` with the verification code will be appended to it. The page should then make a request to the `/auth/otp/sign-in` endpoint.', exampleValue: 'https://example.com/handler/magic-link-callback' } });
|
|
152
|
+
export const emailVerificationCallbackUrlSchema = urlSchema.meta({ openapiField: { description: 'The base callback URL to construct a verification link for the verification e-mail. A query argument `code` with the verification code will be appended to it. The page should then make a request to the `/contact-channels/verify` endpoint.', exampleValue: 'https://example.com/handler/email-verification' } });
|
|
153
|
+
export const accessTokenResponseSchema = yupString().meta({ openapiField: { description: 'Short-lived access token that can be used to authenticate the user', exampleValue: 'eyJhmMiJBMTO...diI4QT' } });
|
|
154
|
+
export const refreshTokenResponseSchema = yupString().meta({ openapiField: { description: 'Long-lived refresh token that can be used to obtain a new access token', exampleValue: 'i8nsoaq2...14y' } });
|
|
155
|
+
export const signInResponseSchema = yupObject({
|
|
64
156
|
refresh_token: refreshTokenResponseSchema.required(),
|
|
65
157
|
access_token: accessTokenResponseSchema.required(),
|
|
66
|
-
is_new_user:
|
|
67
|
-
user_id:
|
|
158
|
+
is_new_user: yupBoolean().meta({ openapiField: { description: 'Whether the user is a new user', exampleValue: true } }).required(),
|
|
159
|
+
user_id: userIdSchema.required(),
|
|
68
160
|
});
|
|
161
|
+
// Permissions
|
|
162
|
+
export const teamSystemPermissions = [
|
|
163
|
+
'$update_team',
|
|
164
|
+
'$delete_team',
|
|
165
|
+
'$read_members',
|
|
166
|
+
'$remove_members',
|
|
167
|
+
'$invite_members',
|
|
168
|
+
];
|
|
169
|
+
export const teamPermissionIdSchema = yupString()
|
|
170
|
+
.matches(/^\$?[a-z0-9_:]+$/, 'Only lowercase letters, numbers, ":", "_" and optional "$" at the beginning are allowed')
|
|
171
|
+
.test('is-system-permission', 'System permissions must start with a dollar sign', (value, ctx) => {
|
|
172
|
+
if (!value)
|
|
173
|
+
return true;
|
|
174
|
+
if (value.startsWith('$') && !teamSystemPermissions.includes(value)) {
|
|
175
|
+
return ctx.createError({ message: 'Invalid system permission' });
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
})
|
|
179
|
+
.meta({ openapiField: { description: `The permission ID used to uniquely identify a permission. Can either be a custom permission with lowercase letters, numbers, ":", and "_" characters, or one of the system permissions: ${teamSystemPermissions.join(', ')}`, exampleValue: '$read_secret_info' } });
|
|
180
|
+
export const customTeamPermissionIdSchema = yupString()
|
|
181
|
+
.matches(/^[a-z0-9_:]+$/, 'Only lowercase letters, numbers, ":", "_" are allowed')
|
|
182
|
+
.meta({ openapiField: { description: 'The permission ID used to uniquely identify a permission. Can only contain lowercase letters, numbers, ":", and "_" characters', exampleValue: 'read_secret_info' } });
|
|
183
|
+
export const teamPermissionDescriptionSchema = yupString().meta({ openapiField: { description: 'A human-readable description of the permission', exampleValue: 'Read secret information' } });
|
|
184
|
+
export const containedPermissionIdsSchema = yupArray(teamPermissionIdSchema.required()).meta({ openapiField: { description: 'The IDs of the permissions that are contained in this permission', exampleValue: ['read_public_info'] } });
|
|
185
|
+
// Teams
|
|
186
|
+
export const teamIdSchema = yupString().uuid().meta({ openapiField: { description: _idDescription('team'), exampleValue: 'ad962777-8244-496a-b6a2-e0c6a449c79e' } });
|
|
187
|
+
export const teamDisplayNameSchema = yupString().meta({ openapiField: { description: _displayNameDescription('team'), exampleValue: 'My Team' } });
|
|
188
|
+
export const teamClientMetadataSchema = jsonSchema.meta({ openapiField: { description: _clientMetaDataDescription('team'), exampleValue: { key: 'value' } } });
|
|
189
|
+
export const teamServerMetadataSchema = jsonSchema.meta({ openapiField: { description: _serverMetaDataDescription('team'), exampleValue: { key: 'value' } } });
|
|
190
|
+
export const teamCreatedAtMillisSchema = yupNumber().meta({ openapiField: { description: _createdAtMillisDescription('team'), exampleValue: 1630000000000 } });
|
|
191
|
+
// Utils
|
|
192
|
+
export function yupRequiredWhen(schema, triggerName, isValue) {
|
|
193
|
+
return schema.when(triggerName, {
|
|
194
|
+
is: isValue,
|
|
195
|
+
then: (schema) => schema.required(),
|
|
196
|
+
otherwise: (schema) => schema.optional()
|
|
197
|
+
});
|
|
198
|
+
}
|
package/dist/sessions.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export declare class InternalSession {
|
|
|
42
42
|
refreshToken: string | null;
|
|
43
43
|
accessToken?: string | null;
|
|
44
44
|
}): string;
|
|
45
|
+
isKnownToBeInvalid(): boolean;
|
|
45
46
|
/**
|
|
46
47
|
* Marks the session object as invalid, meaning that the refresh and access tokens can no longer be used.
|
|
47
48
|
*/
|
package/dist/sessions.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
import { StackAssertionError } from "./utils/errors";
|
|
1
2
|
import { Store } from "./utils/stores";
|
|
2
3
|
export class AccessToken {
|
|
3
|
-
token;
|
|
4
4
|
constructor(token) {
|
|
5
5
|
this.token = token;
|
|
6
|
+
if (token === "undefined") {
|
|
7
|
+
throw new StackAssertionError("Access token is the string 'undefined'; it's unlikely this is the correct value. They're supposed to be unguessable!");
|
|
8
|
+
}
|
|
6
9
|
}
|
|
7
10
|
}
|
|
8
11
|
export class RefreshToken {
|
|
9
|
-
token;
|
|
10
12
|
constructor(token) {
|
|
11
13
|
this.token = token;
|
|
14
|
+
if (token === "undefined") {
|
|
15
|
+
throw new StackAssertionError("Refresh token is the string 'undefined'; it's unlikely this is the correct value. They're supposed to be unguessable!");
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
19
|
/**
|
|
@@ -17,29 +22,15 @@ export class RefreshToken {
|
|
|
17
22
|
* A session never changes which user or session it belongs to, but the tokens in it may change over time.
|
|
18
23
|
*/
|
|
19
24
|
export class InternalSession {
|
|
20
|
-
_options;
|
|
21
|
-
/**
|
|
22
|
-
* Each session has a session key that depends on the tokens inside. If the session has a refresh token, the session key depends only on the refresh token. If the session does not have a refresh token, the session key depends only on the access token.
|
|
23
|
-
*
|
|
24
|
-
* Multiple Session objects may have the same session key, which implies that they represent the same session by the same user. Furthermore, a session's key never changes over the lifetime of a session object.
|
|
25
|
-
*
|
|
26
|
-
* This is useful for caching and indexing sessions.
|
|
27
|
-
*/
|
|
28
|
-
sessionKey;
|
|
29
|
-
/**
|
|
30
|
-
* An access token that is not known to be invalid (ie. may be valid, but may have expired).
|
|
31
|
-
*/
|
|
32
|
-
_accessToken;
|
|
33
|
-
_refreshToken;
|
|
34
|
-
/**
|
|
35
|
-
* Whether the session as a whole is known to be invalid. Used as a cache to avoid making multiple requests to the server (sessions never go back to being valid after being invalidated).
|
|
36
|
-
*
|
|
37
|
-
* Applies to both the access token and the refresh token (it is possible for the access token to be invalid but the refresh token to be valid, in which case the session is still valid).
|
|
38
|
-
*/
|
|
39
|
-
_knownToBeInvalid = new Store(false);
|
|
40
|
-
_refreshPromise = null;
|
|
41
25
|
constructor(_options) {
|
|
42
26
|
this._options = _options;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the session as a whole is known to be invalid. Used as a cache to avoid making multiple requests to the server (sessions never go back to being valid after being invalidated).
|
|
29
|
+
*
|
|
30
|
+
* Applies to both the access token and the refresh token (it is possible for the access token to be invalid but the refresh token to be valid, in which case the session is still valid).
|
|
31
|
+
*/
|
|
32
|
+
this._knownToBeInvalid = new Store(false);
|
|
33
|
+
this._refreshPromise = null;
|
|
43
34
|
this._accessToken = new Store(_options.accessToken ? new AccessToken(_options.accessToken) : null);
|
|
44
35
|
this._refreshToken = _options.refreshToken ? new RefreshToken(_options.refreshToken) : null;
|
|
45
36
|
this.sessionKey = InternalSession.calculateSessionKey({ accessToken: _options.accessToken ?? null, refreshToken: _options.refreshToken });
|
|
@@ -55,6 +46,9 @@ export class InternalSession {
|
|
|
55
46
|
return "not-logged-in";
|
|
56
47
|
}
|
|
57
48
|
}
|
|
49
|
+
isKnownToBeInvalid() {
|
|
50
|
+
return this._knownToBeInvalid.get();
|
|
51
|
+
}
|
|
58
52
|
/**
|
|
59
53
|
* Marks the session object as invalid, meaning that the refresh and access tokens can no longer be used.
|
|
60
54
|
*/
|
|
@@ -104,13 +98,13 @@ export class InternalSession {
|
|
|
104
98
|
* @returns An access token (cached if possible), or null if the session either does not represent a user or the session is invalid.
|
|
105
99
|
*/
|
|
106
100
|
async _getPotentiallyExpiredAccessToken() {
|
|
107
|
-
const oldAccessToken = this._accessToken.get();
|
|
108
|
-
if (oldAccessToken)
|
|
109
|
-
return oldAccessToken;
|
|
110
101
|
if (!this._refreshToken)
|
|
111
102
|
return null;
|
|
112
103
|
if (this._knownToBeInvalid.get())
|
|
113
104
|
return null;
|
|
105
|
+
const oldAccessToken = this._accessToken.get();
|
|
106
|
+
if (oldAccessToken)
|
|
107
|
+
return oldAccessToken;
|
|
114
108
|
// refresh access token
|
|
115
109
|
if (!this._refreshPromise) {
|
|
116
110
|
this._refreshAndSetRefreshPromise(this._refreshToken);
|
package/dist/utils/arrays.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export declare function typedIncludes<T extends readonly any[]>(arr: T, item: unknown): item is T[number];
|
|
2
2
|
export declare function enumerate<T extends readonly any[]>(arr: T): [number, T[number]][];
|
|
3
3
|
export declare function isShallowEqual(a: readonly any[], b: readonly any[]): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Ponyfill for ES2023's findLastIndex.
|
|
6
|
+
*/
|
|
7
|
+
export declare function findLastIndex<T>(arr: readonly T[], predicate: (item: T) => boolean): number;
|
|
4
8
|
export declare function groupBy<T extends any, K>(arr: Iterable<T>, key: (item: T) => K): Map<K, T[]>;
|
|
5
9
|
export declare function range(endExclusive: number): number[];
|
|
6
10
|
export declare function range(startInclusive: number, endExclusive: number): number[];
|
package/dist/utils/arrays.js
CHANGED
|
@@ -14,6 +14,16 @@ export function isShallowEqual(a, b) {
|
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Ponyfill for ES2023's findLastIndex.
|
|
19
|
+
*/
|
|
20
|
+
export function findLastIndex(arr, predicate) {
|
|
21
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
22
|
+
if (predicate(arr[i]))
|
|
23
|
+
return i;
|
|
24
|
+
}
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
17
27
|
export function groupBy(arr, key) {
|
|
18
28
|
const result = new Map;
|
|
19
29
|
for (const item of arr) {
|
package/dist/utils/caches.js
CHANGED
|
@@ -17,12 +17,18 @@ export function cacheFunction(f) {
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
export class AsyncCache {
|
|
20
|
-
_fetcher;
|
|
21
|
-
_options;
|
|
22
|
-
_map = new DependenciesMap();
|
|
23
20
|
constructor(_fetcher, _options = {}) {
|
|
24
21
|
this._fetcher = _fetcher;
|
|
25
22
|
this._options = _options;
|
|
23
|
+
this._map = new DependenciesMap();
|
|
24
|
+
this.isCacheAvailable = this._createKeyed("isCacheAvailable");
|
|
25
|
+
this.getIfCached = this._createKeyed("getIfCached");
|
|
26
|
+
this.getOrWait = this._createKeyed("getOrWait");
|
|
27
|
+
this.forceSetCachedValue = this._createKeyed("forceSetCachedValue");
|
|
28
|
+
this.forceSetCachedValueAsync = this._createKeyed("forceSetCachedValueAsync");
|
|
29
|
+
this.refresh = this._createKeyed("refresh");
|
|
30
|
+
this.invalidate = this._createKeyed("invalidate");
|
|
31
|
+
this.onStateChange = this._createKeyed("onStateChange");
|
|
26
32
|
// nothing here yet
|
|
27
33
|
}
|
|
28
34
|
_createKeyed(functionName) {
|
|
@@ -42,25 +48,12 @@ export class AsyncCache {
|
|
|
42
48
|
}
|
|
43
49
|
return cache;
|
|
44
50
|
}
|
|
45
|
-
isCacheAvailable = this._createKeyed("isCacheAvailable");
|
|
46
|
-
getIfCached = this._createKeyed("getIfCached");
|
|
47
|
-
getOrWait = this._createKeyed("getOrWait");
|
|
48
|
-
forceSetCachedValue = this._createKeyed("forceSetCachedValue");
|
|
49
|
-
forceSetCachedValueAsync = this._createKeyed("forceSetCachedValueAsync");
|
|
50
|
-
refresh = this._createKeyed("refresh");
|
|
51
|
-
invalidate = this._createKeyed("invalidate");
|
|
52
|
-
onStateChange = this._createKeyed("onStateChange");
|
|
53
51
|
}
|
|
54
52
|
class AsyncValueCache {
|
|
55
|
-
_options;
|
|
56
|
-
_store;
|
|
57
|
-
_pendingPromise;
|
|
58
|
-
_fetcher;
|
|
59
|
-
_rateLimitOptions;
|
|
60
|
-
_subscriptionsCount = 0;
|
|
61
|
-
_unsubscribers = [];
|
|
62
53
|
constructor(fetcher, _options = {}) {
|
|
63
54
|
this._options = _options;
|
|
55
|
+
this._subscriptionsCount = 0;
|
|
56
|
+
this._unsubscribers = [];
|
|
64
57
|
this._store = new AsyncStore();
|
|
65
58
|
this._rateLimitOptions = {
|
|
66
59
|
concurrency: 1,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns the first argument passed to it, but compilers won't be able to optimize it out. This is useful in some
|
|
2
|
+
* Returns the first argument passed to it, but compilers won't be able to optimize it out. This is useful in some
|
|
3
|
+
* cases where compiler warnings go awry; for example, when importing things that may not exist (but are guaranteed
|
|
4
|
+
* to exist at runtime).
|
|
3
5
|
*/
|
|
4
6
|
export declare function scrambleDuringCompileTime<T>(t: T): T;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns the first argument passed to it, but compilers won't be able to optimize it out. This is useful in some
|
|
2
|
+
* Returns the first argument passed to it, but compilers won't be able to optimize it out. This is useful in some
|
|
3
|
+
* cases where compiler warnings go awry; for example, when importing things that may not exist (but are guaranteed
|
|
4
|
+
* to exist at runtime).
|
|
3
5
|
*/
|
|
4
6
|
export function scrambleDuringCompileTime(t) {
|
|
5
7
|
return t;
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -13,8 +13,11 @@ type Status = {
|
|
|
13
13
|
message: string;
|
|
14
14
|
};
|
|
15
15
|
type StatusErrorConstructorParameters = [
|
|
16
|
-
|
|
16
|
+
status: Status,
|
|
17
17
|
message?: string
|
|
18
|
+
] | [
|
|
19
|
+
statusCode: number | Status,
|
|
20
|
+
message: string
|
|
18
21
|
];
|
|
19
22
|
export declare class StatusError extends Error {
|
|
20
23
|
name: string;
|
|
@@ -185,6 +188,10 @@ export declare class StatusError extends Error {
|
|
|
185
188
|
getStatusCode(): number;
|
|
186
189
|
getBody(): Uint8Array;
|
|
187
190
|
getHeaders(): Record<string, string[]>;
|
|
191
|
+
toDescriptiveJson(): Json;
|
|
192
|
+
/**
|
|
193
|
+
* @deprecated this is not a good way to make status errors human-readable, use toDescriptiveJson instead
|
|
194
|
+
*/
|
|
188
195
|
toHttpJson(): Json;
|
|
189
196
|
}
|
|
190
197
|
export {};
|
package/dist/utils/errors.js
CHANGED
|
@@ -12,7 +12,6 @@ export function throwErr(...args) {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
export class StackAssertionError extends Error {
|
|
15
|
-
extraData;
|
|
16
15
|
constructor(message, extraData, options) {
|
|
17
16
|
const disclaimer = `\n\nThis is likely an error in Stack. Please report it.`;
|
|
18
17
|
super(`${message}${message.endsWith(disclaimer) ? "" : disclaimer}`, options);
|
|
@@ -28,11 +27,11 @@ export function registerErrorSink(sink) {
|
|
|
28
27
|
errorSinks.add(sink);
|
|
29
28
|
}
|
|
30
29
|
registerErrorSink((location, ...args) => {
|
|
31
|
-
console.error(
|
|
30
|
+
console.error(`\x1b[41mError in ${location}:`, ...args, "\x1b[0m");
|
|
32
31
|
});
|
|
33
|
-
registerErrorSink((location, error, ...
|
|
32
|
+
registerErrorSink((location, error, ...extraArgs) => {
|
|
34
33
|
globalVar.stackCapturedErrors = globalVar.stackCapturedErrors ?? [];
|
|
35
|
-
globalVar.stackCapturedErrors.push({ location, error
|
|
34
|
+
globalVar.stackCapturedErrors.push({ location, error, extraArgs });
|
|
36
35
|
});
|
|
37
36
|
export function captureError(location, error) {
|
|
38
37
|
for (const sink of errorSinks) {
|
|
@@ -40,56 +39,17 @@ export function captureError(location, error) {
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
export class StatusError extends Error {
|
|
43
|
-
name = "StatusError";
|
|
44
|
-
statusCode;
|
|
45
|
-
static BadRequest = { statusCode: 400, message: "Bad Request" };
|
|
46
|
-
static Unauthorized = { statusCode: 401, message: "Unauthorized" };
|
|
47
|
-
static PaymentRequired = { statusCode: 402, message: "Payment Required" };
|
|
48
|
-
static Forbidden = { statusCode: 403, message: "Forbidden" };
|
|
49
|
-
static NotFound = { statusCode: 404, message: "Not Found" };
|
|
50
|
-
static MethodNotAllowed = { statusCode: 405, message: "Method Not Allowed" };
|
|
51
|
-
static NotAcceptable = { statusCode: 406, message: "Not Acceptable" };
|
|
52
|
-
static ProxyAuthenticationRequired = { statusCode: 407, message: "Proxy Authentication Required" };
|
|
53
|
-
static RequestTimeout = { statusCode: 408, message: "Request Timeout" };
|
|
54
|
-
static Conflict = { statusCode: 409, message: "Conflict" };
|
|
55
|
-
static Gone = { statusCode: 410, message: "Gone" };
|
|
56
|
-
static LengthRequired = { statusCode: 411, message: "Length Required" };
|
|
57
|
-
static PreconditionFailed = { statusCode: 412, message: "Precondition Failed" };
|
|
58
|
-
static PayloadTooLarge = { statusCode: 413, message: "Payload Too Large" };
|
|
59
|
-
static URITooLong = { statusCode: 414, message: "URI Too Long" };
|
|
60
|
-
static UnsupportedMediaType = { statusCode: 415, message: "Unsupported Media Type" };
|
|
61
|
-
static RangeNotSatisfiable = { statusCode: 416, message: "Range Not Satisfiable" };
|
|
62
|
-
static ExpectationFailed = { statusCode: 417, message: "Expectation Failed" };
|
|
63
|
-
static ImATeapot = { statusCode: 418, message: "I'm a teapot" };
|
|
64
|
-
static MisdirectedRequest = { statusCode: 421, message: "Misdirected Request" };
|
|
65
|
-
static UnprocessableEntity = { statusCode: 422, message: "Unprocessable Entity" };
|
|
66
|
-
static Locked = { statusCode: 423, message: "Locked" };
|
|
67
|
-
static FailedDependency = { statusCode: 424, message: "Failed Dependency" };
|
|
68
|
-
static TooEarly = { statusCode: 425, message: "Too Early" };
|
|
69
|
-
static UpgradeRequired = { statusCode: 426, message: "Upgrade Required" };
|
|
70
|
-
static PreconditionRequired = { statusCode: 428, message: "Precondition Required" };
|
|
71
|
-
static TooManyRequests = { statusCode: 429, message: "Too Many Requests" };
|
|
72
|
-
static RequestHeaderFieldsTooLarge = { statusCode: 431, message: "Request Header Fields Too Large" };
|
|
73
|
-
static UnavailableForLegalReasons = { statusCode: 451, message: "Unavailable For Legal Reasons" };
|
|
74
|
-
static InternalServerError = { statusCode: 500, message: "Internal Server Error" };
|
|
75
|
-
static NotImplemented = { statusCode: 501, message: "Not Implemented" };
|
|
76
|
-
static BadGateway = { statusCode: 502, message: "Bad Gateway" };
|
|
77
|
-
static ServiceUnavailable = { statusCode: 503, message: "Service Unavailable" };
|
|
78
|
-
static GatewayTimeout = { statusCode: 504, message: "Gateway Timeout" };
|
|
79
|
-
static HTTPVersionNotSupported = { statusCode: 505, message: "HTTP Version Not Supported" };
|
|
80
|
-
static VariantAlsoNegotiates = { statusCode: 506, message: "Variant Also Negotiates" };
|
|
81
|
-
static InsufficientStorage = { statusCode: 507, message: "Insufficient Storage" };
|
|
82
|
-
static LoopDetected = { statusCode: 508, message: "Loop Detected" };
|
|
83
|
-
static NotExtended = { statusCode: 510, message: "Not Extended" };
|
|
84
|
-
static NetworkAuthenticationRequired = { statusCode: 511, message: "Network Authentication Required" };
|
|
85
42
|
constructor(status, message) {
|
|
86
43
|
if (typeof status === "object") {
|
|
87
44
|
message ??= status.message;
|
|
88
45
|
status = status.statusCode;
|
|
89
46
|
}
|
|
90
|
-
message ??= "Server Error";
|
|
91
47
|
super(message);
|
|
48
|
+
this.name = "StatusError";
|
|
92
49
|
this.statusCode = status;
|
|
50
|
+
if (!message) {
|
|
51
|
+
throw new StackAssertionError("StatusError always requires a message unless a Status object is passed", {}, { cause: this });
|
|
52
|
+
}
|
|
93
53
|
}
|
|
94
54
|
isClientError() {
|
|
95
55
|
return this.statusCode >= 400 && this.statusCode < 500;
|
|
@@ -108,6 +68,16 @@ export class StatusError extends Error {
|
|
|
108
68
|
"Content-Type": ["text/plain; charset=utf-8"],
|
|
109
69
|
};
|
|
110
70
|
}
|
|
71
|
+
toDescriptiveJson() {
|
|
72
|
+
return {
|
|
73
|
+
status_code: this.getStatusCode(),
|
|
74
|
+
message: this.message,
|
|
75
|
+
headers: this.getHeaders(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @deprecated this is not a good way to make status errors human-readable, use toDescriptiveJson instead
|
|
80
|
+
*/
|
|
111
81
|
toHttpJson() {
|
|
112
82
|
return {
|
|
113
83
|
status_code: this.statusCode,
|
|
@@ -116,3 +86,44 @@ export class StatusError extends Error {
|
|
|
116
86
|
};
|
|
117
87
|
}
|
|
118
88
|
}
|
|
89
|
+
StatusError.BadRequest = { statusCode: 400, message: "Bad Request" };
|
|
90
|
+
StatusError.Unauthorized = { statusCode: 401, message: "Unauthorized" };
|
|
91
|
+
StatusError.PaymentRequired = { statusCode: 402, message: "Payment Required" };
|
|
92
|
+
StatusError.Forbidden = { statusCode: 403, message: "Forbidden" };
|
|
93
|
+
StatusError.NotFound = { statusCode: 404, message: "Not Found" };
|
|
94
|
+
StatusError.MethodNotAllowed = { statusCode: 405, message: "Method Not Allowed" };
|
|
95
|
+
StatusError.NotAcceptable = { statusCode: 406, message: "Not Acceptable" };
|
|
96
|
+
StatusError.ProxyAuthenticationRequired = { statusCode: 407, message: "Proxy Authentication Required" };
|
|
97
|
+
StatusError.RequestTimeout = { statusCode: 408, message: "Request Timeout" };
|
|
98
|
+
StatusError.Conflict = { statusCode: 409, message: "Conflict" };
|
|
99
|
+
StatusError.Gone = { statusCode: 410, message: "Gone" };
|
|
100
|
+
StatusError.LengthRequired = { statusCode: 411, message: "Length Required" };
|
|
101
|
+
StatusError.PreconditionFailed = { statusCode: 412, message: "Precondition Failed" };
|
|
102
|
+
StatusError.PayloadTooLarge = { statusCode: 413, message: "Payload Too Large" };
|
|
103
|
+
StatusError.URITooLong = { statusCode: 414, message: "URI Too Long" };
|
|
104
|
+
StatusError.UnsupportedMediaType = { statusCode: 415, message: "Unsupported Media Type" };
|
|
105
|
+
StatusError.RangeNotSatisfiable = { statusCode: 416, message: "Range Not Satisfiable" };
|
|
106
|
+
StatusError.ExpectationFailed = { statusCode: 417, message: "Expectation Failed" };
|
|
107
|
+
StatusError.ImATeapot = { statusCode: 418, message: "I'm a teapot" };
|
|
108
|
+
StatusError.MisdirectedRequest = { statusCode: 421, message: "Misdirected Request" };
|
|
109
|
+
StatusError.UnprocessableEntity = { statusCode: 422, message: "Unprocessable Entity" };
|
|
110
|
+
StatusError.Locked = { statusCode: 423, message: "Locked" };
|
|
111
|
+
StatusError.FailedDependency = { statusCode: 424, message: "Failed Dependency" };
|
|
112
|
+
StatusError.TooEarly = { statusCode: 425, message: "Too Early" };
|
|
113
|
+
StatusError.UpgradeRequired = { statusCode: 426, message: "Upgrade Required" };
|
|
114
|
+
StatusError.PreconditionRequired = { statusCode: 428, message: "Precondition Required" };
|
|
115
|
+
StatusError.TooManyRequests = { statusCode: 429, message: "Too Many Requests" };
|
|
116
|
+
StatusError.RequestHeaderFieldsTooLarge = { statusCode: 431, message: "Request Header Fields Too Large" };
|
|
117
|
+
StatusError.UnavailableForLegalReasons = { statusCode: 451, message: "Unavailable For Legal Reasons" };
|
|
118
|
+
StatusError.InternalServerError = { statusCode: 500, message: "Internal Server Error" };
|
|
119
|
+
StatusError.NotImplemented = { statusCode: 501, message: "Not Implemented" };
|
|
120
|
+
StatusError.BadGateway = { statusCode: 502, message: "Bad Gateway" };
|
|
121
|
+
StatusError.ServiceUnavailable = { statusCode: 503, message: "Service Unavailable" };
|
|
122
|
+
StatusError.GatewayTimeout = { statusCode: 504, message: "Gateway Timeout" };
|
|
123
|
+
StatusError.HTTPVersionNotSupported = { statusCode: 505, message: "HTTP Version Not Supported" };
|
|
124
|
+
StatusError.VariantAlsoNegotiates = { statusCode: 506, message: "Variant Also Negotiates" };
|
|
125
|
+
StatusError.InsufficientStorage = { statusCode: 507, message: "Insufficient Storage" };
|
|
126
|
+
StatusError.LoopDetected = { statusCode: 508, message: "Loop Detected" };
|
|
127
|
+
StatusError.NotExtended = { statusCode: 510, message: "Not Extended" };
|
|
128
|
+
StatusError.NetworkAuthenticationRequired = { statusCode: 511, message: "Network Authentication Required" };
|
|
129
|
+
StatusError.prototype.name = "StatusError";
|
package/dist/utils/globals.js
CHANGED
|
@@ -4,6 +4,9 @@ const globalVar = typeof globalThis !== 'undefined' ? globalThis :
|
|
|
4
4
|
typeof self !== 'undefined' ? self :
|
|
5
5
|
{};
|
|
6
6
|
export { globalVar, };
|
|
7
|
+
if (typeof globalThis === 'undefined') {
|
|
8
|
+
globalVar.globalThis = globalVar;
|
|
9
|
+
}
|
|
7
10
|
const stackGlobalsSymbol = Symbol.for('__stack-globals');
|
|
8
11
|
globalVar[stackGlobalsSymbol] ??= {};
|
|
9
12
|
export function createGlobal(key, init) {
|
package/dist/utils/maps.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
var _a, _b;
|
|
1
2
|
import { Result } from "./results";
|
|
2
3
|
export class MaybeWeakMap {
|
|
3
|
-
_primitiveMap;
|
|
4
|
-
_weakMap;
|
|
5
4
|
constructor(entries) {
|
|
5
|
+
this[_a] = "MaybeWeakMap";
|
|
6
6
|
const entriesArray = [...entries ?? []];
|
|
7
7
|
this._primitiveMap = new Map(entriesArray.filter((e) => !this._isAllowedInWeakMap(e[0])));
|
|
8
8
|
this._weakMap = new WeakMap(entriesArray.filter((e) => this._isAllowedInWeakMap(e[0])));
|
|
@@ -43,10 +43,13 @@ export class MaybeWeakMap {
|
|
|
43
43
|
return this._primitiveMap.has(key);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
[Symbol.toStringTag] = "MaybeWeakMap";
|
|
47
46
|
}
|
|
47
|
+
_a = Symbol.toStringTag;
|
|
48
48
|
export class DependenciesMap {
|
|
49
|
-
|
|
49
|
+
constructor() {
|
|
50
|
+
this._inner = { map: new MaybeWeakMap(), hasValue: false, value: undefined };
|
|
51
|
+
this[_b] = "DependenciesMap";
|
|
52
|
+
}
|
|
50
53
|
_valueToResult(inner) {
|
|
51
54
|
if (inner.hasValue) {
|
|
52
55
|
return Result.ok(inner.value);
|
|
@@ -106,5 +109,5 @@ export class DependenciesMap {
|
|
|
106
109
|
clear() {
|
|
107
110
|
this._inner = { map: new MaybeWeakMap(), hasValue: false, value: undefined };
|
|
108
111
|
}
|
|
109
|
-
[Symbol.toStringTag] = "DependenciesMap";
|
|
110
112
|
}
|
|
113
|
+
_b = Symbol.toStringTag;
|