@stackframe/stack-shared 2.4.24 → 2.4.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.4.26
4
+
5
+ ### Patch Changes
6
+
7
+ - Improve docs
8
+ - Updated dependencies
9
+ - @stackframe/stack-sc@2.4.26
10
+
11
+ ## 2.4.25
12
+
13
+ ### Patch Changes
14
+
15
+ - Docs update
16
+ - @stackframe/stack-sc@2.4.25
17
+
3
18
  ## 2.4.24
4
19
 
5
20
  ### Patch Changes
package/dist/crud.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  import * as yup from 'yup';
2
2
  import { NullishCoalesce } from './utils/types';
3
3
  export type CrudOperation = "create" | "read" | "update" | "delete";
4
+ declare module 'yup' {
5
+ interface CustomSchemaMetadata {
6
+ openapi?: {
7
+ description?: string;
8
+ exampleValue?: any;
9
+ hide?: boolean;
10
+ };
11
+ }
12
+ }
4
13
  type InnerCrudSchema<CreateSchema extends yup.Schema<any> | undefined = yup.Schema<any> | undefined, ReadSchema extends yup.Schema<any> | undefined = yup.Schema<any> | undefined, UpdateSchema extends yup.Schema<any> | undefined = yup.Schema<any> | undefined, DeleteSchema extends yup.Schema<any> | undefined = yup.Schema<any> | undefined> = {
5
14
  createSchema: CreateSchema;
6
15
  readSchema: ReadSchema;
@@ -16,7 +25,7 @@ export type CrudSchema<ClientSchema extends InnerCrudSchema = InnerCrudSchema, S
16
25
  hasUpdate: boolean;
17
26
  hasDelete: boolean;
18
27
  };
19
- type CrudSchemaCreationOptions = {
28
+ export type CrudSchemaCreationOptions = {
20
29
  clientCreateSchema?: yup.Schema<any>;
21
30
  clientReadSchema?: yup.Schema<any>;
22
31
  clientUpdateSchema?: yup.Schema<any>;
@@ -49,7 +58,7 @@ type FillInOptionalsStep<O extends FillInOptionalsPrepareStep<CrudSchemaCreation
49
58
  };
50
59
  type FillInOptionals<O extends CrudSchemaCreationOptions> = FillInOptionalsStep<FillInOptionalsStep<FillInOptionalsStep<FillInOptionalsPrepareStep<O>>>>;
51
60
  type CrudSchemaFromOptionsInner<O extends FillInOptionals<any>> = CrudSchema<InnerCrudSchema<O['clientCreateSchema'], O['clientReadSchema'], O['clientUpdateSchema'], O['clientDeleteSchema']>, InnerCrudSchema<O['serverCreateSchema'], O['serverReadSchema'], O['serverUpdateSchema'], O['serverDeleteSchema']>, InnerCrudSchema<O['adminCreateSchema'], O['adminReadSchema'], O['adminUpdateSchema'], O['adminDeleteSchema']>>;
52
- type CrudSchemaFromOptions<O extends CrudSchemaCreationOptions> = CrudSchemaFromOptionsInner<FillInOptionals<O>>;
61
+ export type CrudSchemaFromOptions<O extends CrudSchemaCreationOptions> = CrudSchemaFromOptionsInner<FillInOptionals<O>>;
53
62
  type InnerCrudTypeOf<S extends InnerCrudSchema> = (S['createSchema'] extends {} ? {
54
63
  Create: yup.InferType<S['createSchema']>;
55
64
  } : {}) & (S['readSchema'] extends {} ? {
@@ -1,161 +1,97 @@
1
1
  import { CrudTypeOf } from "../../crud";
2
2
  import * as yup from "yup";
3
- export declare const currentUserCrud: {
4
- client: {
5
- createSchema: undefined;
6
- readSchema: yup.ObjectSchema<{
7
- displayName: string | null;
8
- id: string;
9
- projectId: string;
10
- clientMetadata: {} | null;
11
- primaryEmail: string | null;
12
- primaryEmailVerified: NonNullable<boolean | undefined>;
13
- selectedTeamId: string | null;
14
- selectedTeam: {} | null;
15
- profileImageUrl: string | null;
16
- signedUpAtMillis: number;
17
- authMethod: NonNullable<"credential" | "oauth" | undefined>;
18
- hasPassword: NonNullable<boolean | undefined>;
19
- authWithEmail: NonNullable<boolean | undefined>;
20
- oauthProviders: string[];
21
- } | null, yup.AnyObject, {
22
- projectId: undefined;
23
- id: undefined;
24
- primaryEmail: undefined;
25
- primaryEmailVerified: undefined;
26
- displayName: undefined;
27
- clientMetadata: undefined;
28
- selectedTeamId: undefined;
29
- selectedTeam: undefined;
30
- profileImageUrl: undefined;
31
- signedUpAtMillis: undefined;
32
- authMethod: undefined;
33
- hasPassword: undefined;
34
- authWithEmail: undefined;
35
- oauthProviders: undefined;
36
- serverMetadata: undefined;
37
- }, "">;
38
- updateSchema: yup.ObjectSchema<{
39
- displayName: string | undefined;
40
- clientMetadata: {} | undefined;
41
- selectedTeamId: string | null | undefined;
42
- }, yup.AnyObject, {
43
- displayName: undefined;
44
- clientMetadata: {};
45
- serverMetadata: {};
46
- primaryEmail: undefined;
47
- primaryEmailVerified: undefined;
48
- selectedTeamId: undefined;
49
- }, "">;
50
- deleteSchema: undefined;
51
- };
52
- server: {
53
- createSchema: undefined;
54
- readSchema: yup.ObjectSchema<{
55
- projectId: string;
56
- id: string;
57
- primaryEmail: string | null;
58
- primaryEmailVerified: NonNullable<boolean | undefined>;
59
- displayName: string | null;
60
- clientMetadata: {} | null;
61
- selectedTeamId: string | null;
62
- selectedTeam: {} | null;
63
- profileImageUrl: string | null;
64
- signedUpAtMillis: number;
65
- authMethod: NonNullable<"credential" | "oauth" | undefined>;
66
- hasPassword: NonNullable<boolean | undefined>;
67
- authWithEmail: NonNullable<boolean | undefined>;
68
- oauthProviders: string[];
69
- serverMetadata: {} | null;
70
- } | null, yup.AnyObject, {
71
- projectId: undefined;
72
- id: undefined;
73
- primaryEmail: undefined;
74
- primaryEmailVerified: undefined;
75
- displayName: undefined;
76
- clientMetadata: undefined;
77
- selectedTeamId: undefined;
78
- selectedTeam: undefined;
79
- profileImageUrl: undefined;
80
- signedUpAtMillis: undefined;
81
- authMethod: undefined;
82
- hasPassword: undefined;
83
- authWithEmail: undefined;
84
- oauthProviders: undefined;
85
- serverMetadata: undefined;
86
- }, "">;
87
- updateSchema: yup.ObjectSchema<{
88
- displayName: string | undefined;
89
- clientMetadata: {} | undefined;
90
- serverMetadata: {} | undefined;
91
- primaryEmail: string | undefined;
92
- primaryEmailVerified: boolean | undefined;
93
- selectedTeamId: string | null | undefined;
94
- }, yup.AnyObject, {
95
- displayName: undefined;
96
- clientMetadata: {};
97
- serverMetadata: {};
98
- primaryEmail: undefined;
99
- primaryEmailVerified: undefined;
100
- selectedTeamId: undefined;
101
- }, "">;
102
- deleteSchema: undefined;
103
- };
104
- admin: {
105
- createSchema: undefined;
106
- readSchema: yup.ObjectSchema<{
107
- projectId: string;
108
- id: string;
109
- primaryEmail: string | null;
110
- primaryEmailVerified: NonNullable<boolean | undefined>;
111
- displayName: string | null;
112
- clientMetadata: {} | null;
113
- selectedTeamId: string | null;
114
- selectedTeam: {} | null;
115
- profileImageUrl: string | null;
116
- signedUpAtMillis: number;
117
- authMethod: NonNullable<"credential" | "oauth" | undefined>;
118
- hasPassword: NonNullable<boolean | undefined>;
119
- authWithEmail: NonNullable<boolean | undefined>;
120
- oauthProviders: string[];
121
- serverMetadata: {} | null;
122
- } | null, yup.AnyObject, {
123
- projectId: undefined;
124
- id: undefined;
125
- primaryEmail: undefined;
126
- primaryEmailVerified: undefined;
127
- displayName: undefined;
128
- clientMetadata: undefined;
129
- selectedTeamId: undefined;
130
- selectedTeam: undefined;
131
- profileImageUrl: undefined;
132
- signedUpAtMillis: undefined;
133
- authMethod: undefined;
134
- hasPassword: undefined;
135
- authWithEmail: undefined;
136
- oauthProviders: undefined;
137
- serverMetadata: undefined;
138
- }, "">;
139
- updateSchema: yup.ObjectSchema<{
140
- displayName: string | undefined;
141
- clientMetadata: {} | undefined;
142
- serverMetadata: {} | undefined;
143
- primaryEmail: string | undefined;
144
- primaryEmailVerified: boolean | undefined;
145
- selectedTeamId: string | null | undefined;
146
- }, yup.AnyObject, {
147
- displayName: undefined;
148
- clientMetadata: {};
149
- serverMetadata: {};
150
- primaryEmail: undefined;
151
- primaryEmailVerified: undefined;
152
- selectedTeamId: undefined;
153
- }, "">;
154
- deleteSchema: undefined;
155
- };
156
- hasCreate: boolean;
157
- hasRead: boolean;
158
- hasUpdate: boolean;
159
- hasDelete: boolean;
160
- };
3
+ export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions<{
4
+ clientReadSchema: yup.ObjectSchema<{
5
+ displayName: string | null;
6
+ id: string;
7
+ projectId: string;
8
+ clientMetadata: {} | null;
9
+ primaryEmail: string | null;
10
+ primaryEmailVerified: NonNullable<boolean | undefined>;
11
+ selectedTeamId: string | null;
12
+ selectedTeam: {} | null;
13
+ profileImageUrl: string | null;
14
+ signedUpAtMillis: number;
15
+ authMethod: NonNullable<"credential" | "oauth" | undefined>;
16
+ hasPassword: NonNullable<boolean | undefined>;
17
+ authWithEmail: NonNullable<boolean | undefined>;
18
+ oauthProviders: string[];
19
+ } | null, yup.AnyObject, {
20
+ projectId: undefined;
21
+ id: undefined;
22
+ primaryEmail: undefined;
23
+ primaryEmailVerified: undefined;
24
+ displayName: undefined;
25
+ selectedTeam: undefined;
26
+ selectedTeamId: undefined;
27
+ profileImageUrl: undefined;
28
+ signedUpAtMillis: undefined;
29
+ authMethod: undefined;
30
+ hasPassword: undefined;
31
+ authWithEmail: undefined;
32
+ oauthProviders: undefined;
33
+ clientMetadata: undefined;
34
+ serverMetadata: undefined;
35
+ }, "">;
36
+ serverReadSchema: yup.ObjectSchema<{
37
+ projectId: string;
38
+ id: string;
39
+ primaryEmail: string | null;
40
+ primaryEmailVerified: NonNullable<boolean | undefined>;
41
+ displayName: string | null;
42
+ selectedTeam: {} | null;
43
+ selectedTeamId: string | null;
44
+ profileImageUrl: string | null;
45
+ signedUpAtMillis: number;
46
+ authMethod: NonNullable<"credential" | "oauth" | undefined>;
47
+ hasPassword: NonNullable<boolean | undefined>;
48
+ authWithEmail: NonNullable<boolean | undefined>;
49
+ oauthProviders: string[];
50
+ clientMetadata: {} | null;
51
+ serverMetadata: {} | null;
52
+ } | null, yup.AnyObject, {
53
+ projectId: undefined;
54
+ id: undefined;
55
+ primaryEmail: undefined;
56
+ primaryEmailVerified: undefined;
57
+ displayName: undefined;
58
+ selectedTeam: undefined;
59
+ selectedTeamId: undefined;
60
+ profileImageUrl: undefined;
61
+ signedUpAtMillis: undefined;
62
+ authMethod: undefined;
63
+ hasPassword: undefined;
64
+ authWithEmail: undefined;
65
+ oauthProviders: undefined;
66
+ clientMetadata: undefined;
67
+ serverMetadata: undefined;
68
+ }, "">;
69
+ clientUpdateSchema: yup.ObjectSchema<{
70
+ displayName: string | undefined;
71
+ clientMetadata: {} | null | undefined;
72
+ selectedTeamId: string | null | undefined;
73
+ }, yup.AnyObject, {
74
+ displayName: undefined;
75
+ clientMetadata: undefined;
76
+ serverMetadata: undefined;
77
+ primaryEmail: undefined;
78
+ primaryEmailVerified: undefined;
79
+ selectedTeamId: undefined;
80
+ }, "">;
81
+ serverUpdateSchema: yup.ObjectSchema<{
82
+ displayName: string | undefined;
83
+ clientMetadata: {} | null | undefined;
84
+ serverMetadata: {} | null | undefined;
85
+ primaryEmail: string | null | undefined;
86
+ primaryEmailVerified: boolean | undefined;
87
+ selectedTeamId: string | null | undefined;
88
+ }, yup.AnyObject, {
89
+ displayName: undefined;
90
+ clientMetadata: undefined;
91
+ serverMetadata: undefined;
92
+ primaryEmail: undefined;
93
+ primaryEmailVerified: undefined;
94
+ selectedTeamId: undefined;
95
+ }, "">;
96
+ }>;
161
97
  export type CurrentUserCrud = CrudTypeOf<typeof currentUserCrud>;
@@ -16,58 +16,25 @@ export declare const emailTemplateCrudServerUpdateSchema: yup.ObjectSchema<{
16
16
  content: undefined;
17
17
  subject: undefined;
18
18
  }, "">;
19
- export declare const emailTemplateCrud: {
20
- client: {
21
- createSchema: undefined;
22
- readSchema: undefined;
23
- updateSchema: undefined;
24
- deleteSchema: undefined;
25
- };
26
- server: {
27
- createSchema: undefined;
28
- readSchema: yup.ObjectSchema<{
29
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
30
- subject: string;
31
- content: {};
32
- }, yup.AnyObject, {
33
- type: undefined;
34
- subject: undefined;
35
- content: undefined;
36
- }, "">;
37
- updateSchema: yup.ObjectSchema<{
38
- content: {};
39
- subject: string;
40
- }, yup.AnyObject, {
41
- content: undefined;
42
- subject: undefined;
43
- }, "">;
44
- deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
45
- };
46
- admin: {
47
- createSchema: undefined;
48
- readSchema: yup.ObjectSchema<{
49
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
50
- subject: string;
51
- content: {};
52
- }, yup.AnyObject, {
53
- type: undefined;
54
- subject: undefined;
55
- content: undefined;
56
- }, "">;
57
- updateSchema: yup.ObjectSchema<{
58
- content: {};
59
- subject: string;
60
- }, yup.AnyObject, {
61
- content: undefined;
62
- subject: undefined;
63
- }, "">;
64
- deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
65
- };
66
- hasCreate: boolean;
67
- hasRead: boolean;
68
- hasUpdate: boolean;
69
- hasDelete: boolean;
70
- };
19
+ export declare const emailTemplateCrud: import("../../crud").CrudSchemaFromOptions<{
20
+ serverReadSchema: yup.ObjectSchema<{
21
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
22
+ subject: string;
23
+ content: {};
24
+ }, yup.AnyObject, {
25
+ type: undefined;
26
+ subject: undefined;
27
+ content: undefined;
28
+ }, "">;
29
+ serverUpdateSchema: yup.ObjectSchema<{
30
+ content: {};
31
+ subject: string;
32
+ }, yup.AnyObject, {
33
+ content: undefined;
34
+ subject: undefined;
35
+ }, "">;
36
+ serverDeleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
37
+ }>;
71
38
  export type EmailTemplateCrud = CrudTypeOf<typeof emailTemplateCrud>;
72
39
  export declare const listEmailTemplatesReadSchema: yup.ArraySchema<{
73
40
  type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
@@ -82,38 +49,12 @@ export declare const emailTemplateCrudServerCreateSchema: yup.ObjectSchema<{
82
49
  type: undefined;
83
50
  content: undefined;
84
51
  }, "">;
85
- export declare const listEmailTemplatesCrud: {
86
- client: {
87
- createSchema: undefined;
88
- readSchema: undefined;
89
- updateSchema: undefined;
90
- deleteSchema: undefined;
91
- };
92
- server: {
93
- createSchema: undefined;
94
- readSchema: yup.ArraySchema<{
95
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
96
- default: NonNullable<boolean | undefined>;
97
- subject: string;
98
- content: {};
99
- }[], yup.AnyObject, "", "">;
100
- updateSchema: undefined;
101
- deleteSchema: undefined;
102
- };
103
- admin: {
104
- createSchema: undefined;
105
- readSchema: yup.ArraySchema<{
106
- type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
107
- default: NonNullable<boolean | undefined>;
108
- subject: string;
109
- content: {};
110
- }[], yup.AnyObject, "", "">;
111
- updateSchema: undefined;
112
- deleteSchema: undefined;
113
- };
114
- hasCreate: boolean;
115
- hasRead: boolean;
116
- hasUpdate: boolean;
117
- hasDelete: boolean;
118
- };
52
+ export declare const listEmailTemplatesCrud: import("../../crud").CrudSchemaFromOptions<{
53
+ serverReadSchema: yup.ArraySchema<{
54
+ type: NonNullable<"EMAIL_VERIFICATION" | "PASSWORD_RESET" | "MAGIC_LINK" | undefined>;
55
+ default: NonNullable<boolean | undefined>;
56
+ subject: string;
57
+ content: {};
58
+ }[], yup.AnyObject, "", "">;
59
+ }>;
119
60
  export type ListEmailTemplatesCrud = CrudTypeOf<typeof listEmailTemplatesCrud>;
@@ -0,0 +1,11 @@
1
+ import * as yup from "yup";
2
+ export declare const projectIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
3
+ export declare const userIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
4
+ export declare const primaryEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
5
+ export declare const primaryEmailVerifiedSchema: yup.BooleanSchema<boolean | undefined, yup.AnyObject, undefined, "">;
6
+ export declare const userDisplayNameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
7
+ export declare const selectedTeamIdSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
8
+ export declare const profileImageUrlSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
9
+ export declare const signedUpAtMillisSchema: yup.NumberSchema<number | undefined, yup.AnyObject, undefined, "">;
10
+ export declare const userClientMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
11
+ export declare const userServerMetadataSchema: yup.MixedSchema<{} | null, yup.AnyObject, undefined, "">;
@@ -0,0 +1,12 @@
1
+ import * as yup from "yup";
2
+ import { yupJson } from "../../utils/yup";
3
+ export const projectIdSchema = yup.string().meta({ openapi: { description: 'Stack dashboard project ID', exampleValue: 'project-id' } });
4
+ export const userIdSchema = yup.string().meta({ openapi: { description: 'Unique user identifier', exampleValue: 'user-id' } });
5
+ export const primaryEmailSchema = yup.string().meta({ openapi: { description: 'Primary email', exampleValue: 'johndoe@example.com' } });
6
+ export const primaryEmailVerifiedSchema = yup.boolean().meta({ openapi: { description: 'Whether the primary email has been verified to belong to this user', exampleValue: true } });
7
+ export const userDisplayNameSchema = yup.string().meta({ openapi: { description: 'Human-readable display name', exampleValue: 'John Doe' } });
8
+ export const selectedTeamIdSchema = yup.string().meta({ openapi: { description: 'ID of the team currently selected by the user', exampleValue: 'team-id' } });
9
+ export const profileImageUrlSchema = yup.string().meta({ openapi: { description: 'Profile image URL', exampleValue: 'https://example.com/image.jpg' } });
10
+ export const signedUpAtMillisSchema = yup.number().meta({ openapi: { description: 'Signed up at milliseconds', exampleValue: 1630000000000 } });
11
+ export const userClientMetadataSchema = yupJson.meta({ openapi: { description: 'Client metadata. Used as a data store, accessible from the client side', exampleValue: { key: 'value' } } });
12
+ export const userServerMetadataSchema = yupJson.meta({ openapi: { description: 'Server metadata. Used as a data store, only accessible from the server side', exampleValue: { key: 'value' } } });
@@ -10,52 +10,16 @@ export declare const accessTokenCreateSchema: yup.ObjectSchema<{
10
10
  }, yup.AnyObject, {
11
11
  scope: undefined;
12
12
  }, "">;
13
- export declare const accessTokenCrud: {
14
- client: {
15
- createSchema: yup.ObjectSchema<{
16
- scope: string | undefined;
17
- }, yup.AnyObject, {
18
- scope: undefined;
19
- }, "">;
20
- readSchema: yup.ObjectSchema<{
21
- accessToken: string;
22
- }, yup.AnyObject, {
23
- accessToken: undefined;
24
- }, "">;
25
- updateSchema: undefined;
26
- deleteSchema: undefined;
27
- };
28
- server: {
29
- createSchema: yup.ObjectSchema<{
30
- scope: string | undefined;
31
- }, yup.AnyObject, {
32
- scope: undefined;
33
- }, "">;
34
- readSchema: yup.ObjectSchema<{
35
- accessToken: string;
36
- }, yup.AnyObject, {
37
- accessToken: undefined;
38
- }, "">;
39
- updateSchema: undefined;
40
- deleteSchema: undefined;
41
- };
42
- admin: {
43
- createSchema: yup.ObjectSchema<{
44
- scope: string | undefined;
45
- }, yup.AnyObject, {
46
- scope: undefined;
47
- }, "">;
48
- readSchema: yup.ObjectSchema<{
49
- accessToken: string;
50
- }, yup.AnyObject, {
51
- accessToken: undefined;
52
- }, "">;
53
- updateSchema: undefined;
54
- deleteSchema: undefined;
55
- };
56
- hasCreate: boolean;
57
- hasRead: boolean;
58
- hasUpdate: boolean;
59
- hasDelete: boolean;
60
- };
13
+ export declare const accessTokenCrud: import("../../crud").CrudSchemaFromOptions<{
14
+ clientReadSchema: yup.ObjectSchema<{
15
+ accessToken: string;
16
+ }, yup.AnyObject, {
17
+ accessToken: undefined;
18
+ }, "">;
19
+ clientCreateSchema: yup.ObjectSchema<{
20
+ scope: string | undefined;
21
+ }, yup.AnyObject, {
22
+ scope: undefined;
23
+ }, "">;
24
+ }>;
61
25
  export type AccessTokenCrud = CrudTypeOf<typeof accessTokenCrud>;
@@ -2,15 +2,15 @@ import { CrudTypeOf } from "../../crud";
2
2
  import * as yup from "yup";
3
3
  export declare const usersCrudServerUpdateSchema: yup.ObjectSchema<{
4
4
  displayName: string | undefined;
5
- clientMetadata: {} | undefined;
6
- serverMetadata: {} | undefined;
7
- primaryEmail: string | undefined;
5
+ clientMetadata: {} | null | undefined;
6
+ serverMetadata: {} | null | undefined;
7
+ primaryEmail: string | null | undefined;
8
8
  primaryEmailVerified: boolean | undefined;
9
9
  selectedTeamId: string | null | undefined;
10
10
  }, yup.AnyObject, {
11
11
  displayName: undefined;
12
- clientMetadata: {};
13
- serverMetadata: {};
12
+ clientMetadata: undefined;
13
+ serverMetadata: undefined;
14
14
  primaryEmail: undefined;
15
15
  primaryEmailVerified: undefined;
16
16
  selectedTeamId: undefined;
@@ -21,15 +21,15 @@ export declare const usersCrudServerReadSchema: yup.ObjectSchema<{
21
21
  primaryEmail: string | null;
22
22
  primaryEmailVerified: NonNullable<boolean | undefined>;
23
23
  displayName: string | null;
24
- clientMetadata: {} | null;
25
- selectedTeamId: string | null;
26
24
  selectedTeam: {} | null;
25
+ selectedTeamId: string | null;
27
26
  profileImageUrl: string | null;
28
27
  signedUpAtMillis: number;
29
28
  authMethod: NonNullable<"credential" | "oauth" | undefined>;
30
29
  hasPassword: NonNullable<boolean | undefined>;
31
30
  authWithEmail: NonNullable<boolean | undefined>;
32
31
  oauthProviders: string[];
32
+ clientMetadata: {} | null;
33
33
  serverMetadata: {} | null;
34
34
  }, yup.AnyObject, {
35
35
  projectId: undefined;
@@ -37,131 +37,66 @@ export declare const usersCrudServerReadSchema: yup.ObjectSchema<{
37
37
  primaryEmail: undefined;
38
38
  primaryEmailVerified: undefined;
39
39
  displayName: undefined;
40
- clientMetadata: undefined;
41
- selectedTeamId: undefined;
42
40
  selectedTeam: undefined;
41
+ selectedTeamId: undefined;
43
42
  profileImageUrl: undefined;
44
43
  signedUpAtMillis: undefined;
45
44
  authMethod: undefined;
46
45
  hasPassword: undefined;
47
46
  authWithEmail: undefined;
48
47
  oauthProviders: undefined;
48
+ clientMetadata: undefined;
49
49
  serverMetadata: undefined;
50
50
  }, "">;
51
- export declare const usersCrud: {
52
- client: {
53
- createSchema: undefined;
54
- readSchema: undefined;
55
- updateSchema: undefined;
56
- deleteSchema: undefined;
57
- };
58
- server: {
59
- createSchema: undefined;
60
- readSchema: yup.ObjectSchema<{
61
- projectId: string;
62
- id: string;
63
- primaryEmail: string | null;
64
- primaryEmailVerified: NonNullable<boolean | undefined>;
65
- displayName: string | null;
66
- clientMetadata: {} | null;
67
- selectedTeamId: string | null;
68
- selectedTeam: {} | null;
69
- profileImageUrl: string | null;
70
- signedUpAtMillis: number;
71
- authMethod: NonNullable<"credential" | "oauth" | undefined>;
72
- hasPassword: NonNullable<boolean | undefined>;
73
- authWithEmail: NonNullable<boolean | undefined>;
74
- oauthProviders: string[];
75
- serverMetadata: {} | null;
76
- }, yup.AnyObject, {
77
- projectId: undefined;
78
- id: undefined;
79
- primaryEmail: undefined;
80
- primaryEmailVerified: undefined;
81
- displayName: undefined;
82
- clientMetadata: undefined;
83
- selectedTeamId: undefined;
84
- selectedTeam: undefined;
85
- profileImageUrl: undefined;
86
- signedUpAtMillis: undefined;
87
- authMethod: undefined;
88
- hasPassword: undefined;
89
- authWithEmail: undefined;
90
- oauthProviders: undefined;
91
- serverMetadata: undefined;
92
- }, "">;
93
- updateSchema: yup.ObjectSchema<{
94
- displayName: string | undefined;
95
- clientMetadata: {} | undefined;
96
- serverMetadata: {} | undefined;
97
- primaryEmail: string | undefined;
98
- primaryEmailVerified: boolean | undefined;
99
- selectedTeamId: string | null | undefined;
100
- }, yup.AnyObject, {
101
- displayName: undefined;
102
- clientMetadata: {};
103
- serverMetadata: {};
104
- primaryEmail: undefined;
105
- primaryEmailVerified: undefined;
106
- selectedTeamId: undefined;
107
- }, "">;
108
- deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
109
- };
110
- admin: {
111
- createSchema: undefined;
112
- readSchema: yup.ObjectSchema<{
113
- projectId: string;
114
- id: string;
115
- primaryEmail: string | null;
116
- primaryEmailVerified: NonNullable<boolean | undefined>;
117
- displayName: string | null;
118
- clientMetadata: {} | null;
119
- selectedTeamId: string | null;
120
- selectedTeam: {} | null;
121
- profileImageUrl: string | null;
122
- signedUpAtMillis: number;
123
- authMethod: NonNullable<"credential" | "oauth" | undefined>;
124
- hasPassword: NonNullable<boolean | undefined>;
125
- authWithEmail: NonNullable<boolean | undefined>;
126
- oauthProviders: string[];
127
- serverMetadata: {} | null;
128
- }, yup.AnyObject, {
129
- projectId: undefined;
130
- id: undefined;
131
- primaryEmail: undefined;
132
- primaryEmailVerified: undefined;
133
- displayName: undefined;
134
- clientMetadata: undefined;
135
- selectedTeamId: undefined;
136
- selectedTeam: undefined;
137
- profileImageUrl: undefined;
138
- signedUpAtMillis: undefined;
139
- authMethod: undefined;
140
- hasPassword: undefined;
141
- authWithEmail: undefined;
142
- oauthProviders: undefined;
143
- serverMetadata: undefined;
144
- }, "">;
145
- updateSchema: yup.ObjectSchema<{
146
- displayName: string | undefined;
147
- clientMetadata: {} | undefined;
148
- serverMetadata: {} | undefined;
149
- primaryEmail: string | undefined;
150
- primaryEmailVerified: boolean | undefined;
151
- selectedTeamId: string | null | undefined;
152
- }, yup.AnyObject, {
153
- displayName: undefined;
154
- clientMetadata: {};
155
- serverMetadata: {};
156
- primaryEmail: undefined;
157
- primaryEmailVerified: undefined;
158
- selectedTeamId: undefined;
159
- }, "">;
160
- deleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
161
- };
162
- hasCreate: boolean;
163
- hasRead: boolean;
164
- hasUpdate: boolean;
165
- hasDelete: boolean;
166
- };
51
+ export declare const usersCrud: import("../../crud").CrudSchemaFromOptions<{
52
+ serverReadSchema: yup.ObjectSchema<{
53
+ projectId: string;
54
+ id: string;
55
+ primaryEmail: string | null;
56
+ primaryEmailVerified: NonNullable<boolean | undefined>;
57
+ displayName: string | null;
58
+ selectedTeam: {} | null;
59
+ selectedTeamId: string | null;
60
+ profileImageUrl: string | null;
61
+ signedUpAtMillis: number;
62
+ authMethod: NonNullable<"credential" | "oauth" | undefined>;
63
+ hasPassword: NonNullable<boolean | undefined>;
64
+ authWithEmail: NonNullable<boolean | undefined>;
65
+ oauthProviders: string[];
66
+ clientMetadata: {} | null;
67
+ serverMetadata: {} | null;
68
+ }, yup.AnyObject, {
69
+ projectId: undefined;
70
+ id: undefined;
71
+ primaryEmail: undefined;
72
+ primaryEmailVerified: undefined;
73
+ displayName: undefined;
74
+ selectedTeam: undefined;
75
+ selectedTeamId: undefined;
76
+ profileImageUrl: undefined;
77
+ signedUpAtMillis: undefined;
78
+ authMethod: undefined;
79
+ hasPassword: undefined;
80
+ authWithEmail: undefined;
81
+ oauthProviders: undefined;
82
+ clientMetadata: undefined;
83
+ serverMetadata: undefined;
84
+ }, "">;
85
+ serverUpdateSchema: yup.ObjectSchema<{
86
+ displayName: string | undefined;
87
+ clientMetadata: {} | null | undefined;
88
+ serverMetadata: {} | null | undefined;
89
+ primaryEmail: string | null | undefined;
90
+ primaryEmailVerified: boolean | undefined;
91
+ selectedTeamId: string | null | undefined;
92
+ }, yup.AnyObject, {
93
+ displayName: undefined;
94
+ clientMetadata: undefined;
95
+ serverMetadata: undefined;
96
+ primaryEmail: undefined;
97
+ primaryEmailVerified: undefined;
98
+ selectedTeamId: undefined;
99
+ }, "">;
100
+ serverDeleteSchema: yup.MixedSchema<{} | undefined, yup.AnyObject, undefined, "">;
101
+ }>;
167
102
  export type UsersCrud = CrudTypeOf<typeof usersCrud>;
@@ -1,38 +1,35 @@
1
1
  import { createCrud } from "../../crud";
2
2
  import * as yup from "yup";
3
- import { yupJson } from "../../utils/yup";
3
+ import * as fieldSchema from "./fields";
4
4
  export const usersCrudServerUpdateSchema = yup.object({
5
- displayName: yup.string().optional(),
6
- clientMetadata: yup.object().optional(),
7
- serverMetadata: yup.object().optional(),
8
- primaryEmail: yup.string().optional(),
9
- primaryEmailVerified: yup.boolean().optional(),
10
- selectedTeamId: yup.string().nullable().optional(),
5
+ displayName: fieldSchema.userDisplayNameSchema.optional(),
6
+ clientMetadata: fieldSchema.userClientMetadataSchema.optional(),
7
+ serverMetadata: fieldSchema.userServerMetadataSchema.optional(),
8
+ primaryEmail: fieldSchema.primaryEmailSchema.nullable().optional(),
9
+ primaryEmailVerified: fieldSchema.primaryEmailVerifiedSchema.optional(),
10
+ selectedTeamId: fieldSchema.selectedTeamIdSchema.nullable().optional(),
11
11
  }).required();
12
12
  export const usersCrudServerReadSchema = yup.object({
13
- projectId: yup.string().required(),
14
- id: yup.string().required(),
15
- primaryEmail: yup.string().nullable().defined(),
16
- primaryEmailVerified: yup.boolean().required(),
17
- displayName: yup.string().nullable().defined(),
18
- clientMetadata: yupJson,
19
- selectedTeamId: yup.string().nullable().defined(),
13
+ projectId: fieldSchema.projectIdSchema.required(),
14
+ id: fieldSchema.userIdSchema.required(),
15
+ primaryEmail: fieldSchema.primaryEmailSchema.nullable().defined(),
16
+ primaryEmailVerified: fieldSchema.primaryEmailVerifiedSchema.required(),
17
+ displayName: fieldSchema.userDisplayNameSchema.nullable().defined(),
20
18
  // TODO give this one the type of an actual team
21
19
  selectedTeam: yup.mixed().nullable().defined(),
22
- profileImageUrl: yup.string().nullable().defined(),
23
- signedUpAtMillis: yup.number().required(),
24
- /**
25
- * not used anymore, for backwards compatibility
26
- */
27
- authMethod: yup.string().oneOf(["credential", "oauth"]).required(),
28
- hasPassword: yup.boolean().required(),
29
- authWithEmail: yup.boolean().required(),
30
- oauthProviders: yup.array(yup.string().required()).required(),
31
- serverMetadata: yupJson,
20
+ selectedTeamId: fieldSchema.selectedTeamIdSchema.nullable().defined(),
21
+ profileImageUrl: fieldSchema.profileImageUrlSchema.nullable().defined(),
22
+ signedUpAtMillis: fieldSchema.signedUpAtMillisSchema.required(),
23
+ authMethod: yup.string().oneOf(["credential", "oauth"]).required().meta({ openapi: { hide: true } }), // not used anymore, for backwards compatibility
24
+ hasPassword: yup.boolean().required().meta({ openapi: { description: 'Whether the user has a password', exampleValue: true } }),
25
+ authWithEmail: yup.boolean().required().meta({ openapi: { description: 'Whether the user can authenticate with their primary e-mail. If set to true, the user can log-in with credentials and/or magic link, if enabled in the project settings.', exampleValue: true } }),
26
+ oauthProviders: yup.array(yup.string().required()).required().meta({ openapi: { description: 'All the OAuth providers connected to this account', exampleValue: ['google', 'github'] } }),
27
+ clientMetadata: fieldSchema.userClientMetadataSchema,
28
+ serverMetadata: fieldSchema.userServerMetadataSchema,
32
29
  }).required();
33
30
  const serverDeleteSchema = yup.mixed();
34
31
  export const usersCrud = createCrud({
35
32
  serverReadSchema: usersCrudServerReadSchema,
36
33
  serverUpdateSchema: usersCrudServerUpdateSchema,
37
- serverDeleteSchema,
34
+ serverDeleteSchema: serverDeleteSchema,
38
35
  });
@@ -37,7 +37,7 @@ export declare class AsyncCache<D extends any[], T> {
37
37
  readonly forceSetCachedValueAsync: (key: D, value: Promise<T>) => ReactPromise<boolean>;
38
38
  readonly refresh: (key: D) => Promise<T>;
39
39
  readonly invalidate: (key: D) => Promise<T>;
40
- readonly onChange: (key: D, callback: (value: T, oldValue: T | undefined) => void) => {
40
+ readonly onStateChange: (key: D, callback: (value: T, oldValue: T | undefined) => void) => {
41
41
  unsubscribe: () => void;
42
42
  };
43
43
  }
@@ -79,7 +79,7 @@ declare class AsyncValueCache<T> {
79
79
  forceSetCachedValueAsync(value: Promise<T>): ReactPromise<boolean>;
80
80
  refresh(): Promise<T>;
81
81
  invalidate(): Promise<T>;
82
- onChange(callback: (value: T, oldValue: T | undefined) => void): {
82
+ onStateChange(callback: (value: T, oldValue: T | undefined) => void): {
83
83
  unsubscribe: () => void;
84
84
  };
85
85
  }
@@ -49,7 +49,7 @@ export class AsyncCache {
49
49
  forceSetCachedValueAsync = this._createKeyed("forceSetCachedValueAsync");
50
50
  refresh = this._createKeyed("refresh");
51
51
  invalidate = this._createKeyed("invalidate");
52
- onChange = this._createKeyed("onChange");
52
+ onStateChange = this._createKeyed("onStateChange");
53
53
  }
54
54
  class AsyncValueCache {
55
55
  _options;
@@ -117,7 +117,7 @@ class AsyncValueCache {
117
117
  this._pendingPromise = undefined;
118
118
  return await this.refresh();
119
119
  }
120
- onChange(callback) {
120
+ onStateChange(callback) {
121
121
  const storeObj = this._store.onChange(callback);
122
122
  if (this._subscriptionsCount++ === 0 && this._options.onSubscribe) {
123
123
  const unsubscribe = this._options.onSubscribe(() => {
@@ -0,0 +1,2 @@
1
+ export declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD", "TRACE", "CONNECT"];
2
+ export type HttpMethod = typeof HTTP_METHODS[number];
@@ -0,0 +1 @@
1
+ export const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD", "TRACE", "CONNECT"];
@@ -1,15 +1,24 @@
1
1
  import { Result } from "./results";
2
- import type { RejectedThenable, FulfilledThenable, PendingThenable } from "react";
3
- export type ReactPromise<T> = Promise<T> & (RejectedThenable<T> | FulfilledThenable<T> | PendingThenable<T>);
2
+ export type ReactPromise<T> = Promise<T> & ({
3
+ status: "rejected";
4
+ reason: unknown;
5
+ } | {
6
+ status: "fulfilled";
7
+ value: T;
8
+ } | {
9
+ status: "pending";
10
+ });
4
11
  type Resolve<T> = (value: T) => void;
5
12
  type Reject = (reason: unknown) => void;
6
13
  export declare function createPromise<T>(callback: (resolve: Resolve<T>, reject: Reject) => void): ReactPromise<T>;
7
14
  /**
8
- * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook.
15
+ * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook, and caches
16
+ * the value so that invoking `resolved` twice returns the same promise.
9
17
  */
10
18
  export declare function resolved<T>(value: T): ReactPromise<T>;
11
19
  /**
12
- * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook.
20
+ * Like Promise.reject(...), but also adds the status and value properties for use with React's `use` hook, and caches
21
+ * the value so that invoking `rejected` twice returns the same promise.
13
22
  */
14
23
  export declare function rejected<T>(reason: unknown): ReactPromise<T>;
15
24
  export declare function neverResolve(): ReactPromise<never>;
@@ -1,4 +1,5 @@
1
1
  import { StackAssertionError, captureError } from "./errors";
2
+ import { DependenciesMap } from "./maps";
2
3
  import { Result } from "./results";
3
4
  import { generateUuid } from "./uuids";
4
5
  export function createPromise(callback) {
@@ -29,26 +30,41 @@ export function createPromise(callback) {
29
30
  ...status === "rejected" ? { reason: valueOrReason } : {},
30
31
  });
31
32
  }
33
+ const resolvedCache = new DependenciesMap();
32
34
  /**
33
- * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook.
35
+ * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook, and caches
36
+ * the value so that invoking `resolved` twice returns the same promise.
34
37
  */
35
38
  export function resolved(value) {
36
- return Object.assign(Promise.resolve(value), {
39
+ if (resolvedCache.has([value])) {
40
+ return resolvedCache.get([value]);
41
+ }
42
+ const res = Object.assign(Promise.resolve(value), {
37
43
  status: "fulfilled",
38
44
  value,
39
45
  });
46
+ resolvedCache.set([value], res);
47
+ return res;
40
48
  }
49
+ const rejectedCache = new DependenciesMap();
41
50
  /**
42
- * Like Promise.resolve(...), but also adds the status and value properties for use with React's `use` hook.
51
+ * Like Promise.reject(...), but also adds the status and value properties for use with React's `use` hook, and caches
52
+ * the value so that invoking `rejected` twice returns the same promise.
43
53
  */
44
54
  export function rejected(reason) {
45
- return Object.assign(Promise.reject(reason), {
55
+ if (rejectedCache.has([reason])) {
56
+ return rejectedCache.get([reason]);
57
+ }
58
+ const res = Object.assign(Promise.reject(reason), {
46
59
  status: "rejected",
47
60
  reason: reason,
48
61
  });
62
+ rejectedCache.set([reason], res);
63
+ return res;
49
64
  }
65
+ const neverResolvePromise = pending(new Promise(() => { }));
50
66
  export function neverResolve() {
51
- return pending(new Promise(() => { }));
67
+ return neverResolvePromise;
52
68
  }
53
69
  export function pending(promise, options = {}) {
54
70
  const res = promise.then(value => {
@@ -9,6 +9,28 @@ export type ReadonlyStore<T> = {
9
9
  unsubscribe: () => void;
10
10
  };
11
11
  };
12
+ export type AsyncStoreStateChangeCallback<T> = (args: {
13
+ state: AsyncResult<T>;
14
+ oldState: AsyncResult<T>;
15
+ lastOkValue: T | undefined;
16
+ }) => void;
17
+ export type ReadonlyAsyncStore<T> = {
18
+ isAvailable(): boolean;
19
+ get(): AsyncResult<T, unknown, void>;
20
+ getOrWait(): ReactPromise<T>;
21
+ onChange(callback: (value: T, oldValue: T | undefined) => void): {
22
+ unsubscribe: () => void;
23
+ };
24
+ onceChange(callback: (value: T, oldValue: T | undefined) => void): {
25
+ unsubscribe: () => void;
26
+ };
27
+ onStateChange(callback: AsyncStoreStateChangeCallback<T>): {
28
+ unsubscribe: () => void;
29
+ };
30
+ onceStateChange(callback: AsyncStoreStateChangeCallback<T>): {
31
+ unsubscribe: () => void;
32
+ };
33
+ };
12
34
  export declare class Store<T> implements ReadonlyStore<T> {
13
35
  private _value;
14
36
  private readonly _callbacks;
@@ -23,20 +45,9 @@ export declare class Store<T> implements ReadonlyStore<T> {
23
45
  unsubscribe: () => void;
24
46
  };
25
47
  }
26
- export type ReadonlyAsyncStore<T> = {
27
- isAvailable(): boolean;
28
- get(): AsyncResult<T, unknown, void>;
29
- getOrWait(): ReactPromise<T>;
30
- onChange(callback: (value: T, oldValue: T | undefined) => void): {
31
- unsubscribe: () => void;
32
- };
33
- onceChange(callback: (value: T, oldValue: T | undefined) => void): {
34
- unsubscribe: () => void;
35
- };
36
- };
37
48
  export declare class AsyncStore<T> implements ReadonlyAsyncStore<T> {
38
49
  private _isAvailable;
39
- private _value;
50
+ private _mostRecentOkValue;
40
51
  private _isRejected;
41
52
  private _rejectionError;
42
53
  private readonly _waitingRejectFunctions;
@@ -74,7 +85,13 @@ export declare class AsyncStore<T> implements ReadonlyAsyncStore<T> {
74
85
  onChange(callback: (value: T, oldValue: T | undefined) => void): {
75
86
  unsubscribe: () => void;
76
87
  };
88
+ onStateChange(callback: AsyncStoreStateChangeCallback<T>): {
89
+ unsubscribe: () => void;
90
+ };
77
91
  onceChange(callback: (value: T, oldValue: T | undefined) => void): {
78
92
  unsubscribe: () => void;
79
93
  };
94
+ onceStateChange(callback: AsyncStoreStateChangeCallback<T>): {
95
+ unsubscribe: () => void;
96
+ };
80
97
  }
@@ -39,7 +39,7 @@ export class Store {
39
39
  }
40
40
  export class AsyncStore {
41
41
  _isAvailable;
42
- _value = undefined;
42
+ _mostRecentOkValue = undefined;
43
43
  _isRejected = false;
44
44
  _rejectionError;
45
45
  _waitingRejectFunctions = new Map();
@@ -52,7 +52,7 @@ export class AsyncStore {
52
52
  }
53
53
  else {
54
54
  this._isAvailable = true;
55
- this._value = args[0];
55
+ this._mostRecentOkValue = args[0];
56
56
  }
57
57
  }
58
58
  isAvailable() {
@@ -66,7 +66,7 @@ export class AsyncStore {
66
66
  return AsyncResult.error(this._rejectionError);
67
67
  }
68
68
  else if (this.isAvailable()) {
69
- return AsyncResult.ok(this._value);
69
+ return AsyncResult.ok(this._mostRecentOkValue);
70
70
  }
71
71
  else {
72
72
  return AsyncResult.pending();
@@ -78,7 +78,7 @@ export class AsyncStore {
78
78
  return rejected(this._rejectionError);
79
79
  }
80
80
  else if (this.isAvailable()) {
81
- return resolved(this._value);
81
+ return resolved(this._mostRecentOkValue);
82
82
  }
83
83
  const promise = new Promise((resolve, reject) => {
84
84
  this.onceChange((value) => {
@@ -92,17 +92,22 @@ export class AsyncStore {
92
92
  return pending(withFinally);
93
93
  }
94
94
  _setIfLatest(result, curCounter) {
95
+ const oldState = this.get();
96
+ const oldValue = this._mostRecentOkValue;
95
97
  if (curCounter > this._lastSuccessfulUpdate) {
96
98
  switch (result.status) {
97
99
  case "ok": {
98
- if (!this._isAvailable || this._isRejected || this._value !== result.data) {
99
- const oldValue = this._value;
100
+ if (!this._isAvailable || this._isRejected || this._mostRecentOkValue !== result.data) {
100
101
  this._lastSuccessfulUpdate = curCounter;
101
102
  this._isAvailable = true;
102
103
  this._isRejected = false;
103
- this._value = result.data;
104
+ this._mostRecentOkValue = result.data;
104
105
  this._rejectionError = undefined;
105
- this._callbacks.forEach((callback) => callback(result.data, oldValue));
106
+ this._callbacks.forEach((callback) => callback({
107
+ state: this.get(),
108
+ oldState,
109
+ lastOkValue: oldValue,
110
+ }));
106
111
  return true;
107
112
  }
108
113
  return false;
@@ -111,9 +116,13 @@ export class AsyncStore {
111
116
  this._lastSuccessfulUpdate = curCounter;
112
117
  this._isAvailable = false;
113
118
  this._isRejected = true;
114
- this._value = undefined;
115
119
  this._rejectionError = result.error;
116
120
  this._waitingRejectFunctions.forEach((reject) => reject(result.error));
121
+ this._callbacks.forEach((callback) => callback({
122
+ state: this.get(),
123
+ oldState,
124
+ lastOkValue: oldValue,
125
+ }));
117
126
  return true;
118
127
  }
119
128
  }
@@ -124,7 +133,7 @@ export class AsyncStore {
124
133
  this._setIfLatest(Result.ok(value), ++this._updateCounter);
125
134
  }
126
135
  update(updater) {
127
- const value = updater(this._value);
136
+ const value = updater(this._mostRecentOkValue);
128
137
  this.set(value);
129
138
  return value;
130
139
  }
@@ -137,7 +146,6 @@ export class AsyncStore {
137
146
  this._lastSuccessfulUpdate = ++this._updateCounter;
138
147
  this._isAvailable = false;
139
148
  this._isRejected = false;
140
- this._value = undefined;
141
149
  this._rejectionError = undefined;
142
150
  }
143
151
  setRejected(error) {
@@ -151,6 +159,13 @@ export class AsyncStore {
151
159
  return store;
152
160
  }
153
161
  onChange(callback) {
162
+ return this.onStateChange(({ state, lastOkValue }) => {
163
+ if (state.status === "ok") {
164
+ callback(state.data, lastOkValue);
165
+ }
166
+ });
167
+ }
168
+ onStateChange(callback) {
154
169
  const uuid = generateUuid();
155
170
  this._callbacks.set(uuid, callback);
156
171
  return {
@@ -166,4 +181,11 @@ export class AsyncStore {
166
181
  });
167
182
  return { unsubscribe };
168
183
  }
184
+ onceStateChange(callback) {
185
+ const { unsubscribe } = this.onStateChange((...args) => {
186
+ unsubscribe();
187
+ callback(...args);
188
+ });
189
+ return { unsubscribe };
190
+ }
169
191
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.4.24",
3
+ "version": "2.4.26",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  }
21
21
  },
22
22
  "peerDependencies": {
23
- "react": "^18.2",
23
+ "react": ">=18.2",
24
24
  "yup": "^1.4.0"
25
25
  },
26
26
  "peerDependenciesMeta": {
@@ -36,13 +36,15 @@
36
36
  "jose": "^5.2.2",
37
37
  "oauth4webapi": "^2.10.3",
38
38
  "uuid": "^9.0.1",
39
- "@stackframe/stack-sc": "2.4.24"
39
+ "@stackframe/stack-sc": "2.4.26"
40
40
  },
41
41
  "devDependencies": {
42
42
  "rimraf": "^5.0.5",
43
43
  "@types/bcrypt": "^5.0.2",
44
44
  "@types/react": "^18.2.66",
45
- "@types/uuid": "^9.0.8"
45
+ "@types/uuid": "^9.0.8",
46
+ "next": "^14.1.0",
47
+ "react": "^18.2.0"
46
48
  },
47
49
  "scripts": {
48
50
  "build": "tsc",