@crowdedkingdomstudios/crowdyjs 4.3.0 → 5.0.1
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/MIGRATION.md +30 -0
- package/README.md +46 -26
- package/dist/domains/udp.d.ts +9 -5
- package/dist/domains/udp.d.ts.map +1 -1
- package/dist/domains/udp.js +10 -6
- package/dist/generated/graphql.d.ts +17 -0
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/realtime.d.ts +2 -1
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +26 -2
- package/dist/world.js +1 -1
- package/package.json +1 -1
package/MIGRATION.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
# CrowdyJS v5 Migration Notes
|
|
2
|
+
|
|
3
|
+
CrowdyJS v5 makes the realtime subscription **app-scoped** to fix a cross-app
|
|
4
|
+
notification leak: a single game token is app-agnostic and one UDP proxy
|
|
5
|
+
session is shared by every subscription on that token, so a token reused across
|
|
6
|
+
apps (e.g. a player in multiple tabs/apps) used to receive other apps' spatial
|
|
7
|
+
fan-out.
|
|
8
|
+
|
|
9
|
+
## Breaking change
|
|
10
|
+
|
|
11
|
+
- `client.udp.subscribe(handlers, appId)` — **`appId` is now required**. The
|
|
12
|
+
game-api fences `udpNotifications` by app and **rejects app-agnostic
|
|
13
|
+
subscriptions** with a `RealtimeConnectionEvent` `code = 'APP_ID_REQUIRED'`.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// Before (v4):
|
|
17
|
+
client.udp.subscribe({ actorUpdate });
|
|
18
|
+
// After (v5):
|
|
19
|
+
client.udp.subscribe({ actorUpdate }, '1');
|
|
20
|
+
// Or use the world helper, which passes its appId automatically:
|
|
21
|
+
client.world('1').subscribe({ actorUpdate });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Run one client per app (sharing the same `tokenStore`) when a player is in
|
|
25
|
+
multiple apps at once.
|
|
26
|
+
|
|
27
|
+
- Requires a game-api that enforces the app fence (`cks-game-api >= v0.9.0`).
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
1
31
|
# CrowdyJS v3 Migration Notes
|
|
2
32
|
|
|
3
33
|
CrowdyJS v3 is a breaking rewrite focused on browser game clients.
|
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ Auth and user reads always target `managementUrl`. Everything else targets `http
|
|
|
65
65
|
## Game-loop lifecycle
|
|
66
66
|
|
|
67
67
|
1. Authenticate with `client.auth.login()` or restore a previous token through `client.session.restore()`.
|
|
68
|
-
2. Subscribe to UDP proxy notifications with `client.udp.subscribe()` (the SDK
|
|
68
|
+
2. Subscribe to UDP proxy notifications with `client.udp.subscribe(handlers, appId)` — `appId` is **required** (the SDK opens the realtime socket on demand and scopes it to that app).
|
|
69
69
|
3. Join a chunk by sending an initial actor update.
|
|
70
70
|
4. Send actor, voxel, text, audio, and client-event updates through `client.udp` or the higher-level `client.world(appId)` helpers.
|
|
71
71
|
5. Call `client.udp.disconnect()` when leaving the world.
|
|
@@ -76,43 +76,63 @@ Auth and user reads always target `managementUrl`. Everything else targets `http
|
|
|
76
76
|
When a player is about to join an app, query its routing fields on the management API first:
|
|
77
77
|
|
|
78
78
|
```graphql
|
|
79
|
-
query AppForRouting($
|
|
80
|
-
app(
|
|
79
|
+
query AppForRouting($appId: BigInt!) {
|
|
80
|
+
app(appId: $appId) {
|
|
81
81
|
appId
|
|
82
82
|
splitMode
|
|
83
|
+
deploymentTarget
|
|
83
84
|
gameApiUrl
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
```
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
`gameApiUrl` is populated for **both** dedicated (`splitMode`) and shared
|
|
90
|
+
(`deploymentTarget: "shared"`) apps. When it's set, build a **second**
|
|
91
|
+
`CrowdyClient` with `httpUrl: gameApiUrl` (and the matching `wsUrl`) **sharing the
|
|
92
|
+
same `tokenStore` as the first client**, then drive gameplay through that client.
|
|
93
|
+
Apps with no `gameApiUrl` keep working against the default `httpUrl` you
|
|
94
|
+
configured.
|
|
89
95
|
|
|
90
96
|
## Realtime notifications
|
|
91
97
|
|
|
98
|
+
`subscribe` takes the handlers **and a required `appId`** (second argument). The
|
|
99
|
+
Game API scopes the realtime session to that app and rejects an app-agnostic
|
|
100
|
+
subscription with a `RealtimeConnectionEvent` (`code: 'APP_ID_REQUIRED'`). Run
|
|
101
|
+
one client per app (sharing the same `tokenStore`) when a player is in multiple
|
|
102
|
+
apps at once.
|
|
103
|
+
|
|
92
104
|
```ts
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const appId = '1';
|
|
106
|
+
|
|
107
|
+
const unsubscribe = client.udp.subscribe(
|
|
108
|
+
{
|
|
109
|
+
actorUpdate: (event) => {
|
|
110
|
+
console.log(event.uuid, event.state);
|
|
111
|
+
},
|
|
112
|
+
voxelUpdate: (event) => { /* ... */ },
|
|
113
|
+
text: (event) => { /* ... */ },
|
|
114
|
+
audio: (event) => { /* ... */ },
|
|
115
|
+
clientEvent: (event) => { /* ... */ },
|
|
116
|
+
serverEvent: (event) => { /* ... */ },
|
|
117
|
+
singleActorMessage: (event) => {
|
|
118
|
+
// A direct actor-to-actor message addressed to you.
|
|
119
|
+
console.log(event.uuid, event.payload); // payload is base64
|
|
120
|
+
},
|
|
121
|
+
genericError: (event) => {
|
|
122
|
+
console.warn(event.sequenceNumber, event.errorCode);
|
|
123
|
+
},
|
|
124
|
+
connectionEvent: (event) => {
|
|
125
|
+
console.warn(event.code, event.message);
|
|
126
|
+
},
|
|
127
|
+
error: (error) => {
|
|
128
|
+
console.error(error.code, error.message);
|
|
129
|
+
},
|
|
111
130
|
},
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
appId,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Or use the world helper, which passes its appId automatically:
|
|
135
|
+
// client.world(appId).subscribe(handlers);
|
|
116
136
|
|
|
117
137
|
client.realtime.onStatus((status) => {
|
|
118
138
|
console.log('realtime:', status);
|
package/dist/domains/udp.d.ts
CHANGED
|
@@ -54,12 +54,16 @@ export declare class UdpAPI {
|
|
|
54
54
|
*/
|
|
55
55
|
sendChannelMessage(input: SendChannelMessageMutationVariables['input']): Promise<boolean>;
|
|
56
56
|
/**
|
|
57
|
-
* Subscribe to udpNotifications. Pass any combination of
|
|
58
|
-
* handlers; the returned function detaches all of them. The first
|
|
59
|
-
* subscriber opens the shared WebSocket; the last one to leave closes
|
|
60
|
-
*
|
|
57
|
+
* Subscribe to udpNotifications for a single app. Pass any combination of
|
|
58
|
+
* typename handlers; the returned function detaches all of them. The first
|
|
59
|
+
* subscriber opens the shared WebSocket; the last one to leave closes it.
|
|
60
|
+
*
|
|
61
|
+
* `appId` is required and scopes the subscription to one app: the game-api
|
|
62
|
+
* only delivers that app's spatial notifications and rejects app-agnostic
|
|
63
|
+
* subscriptions (a single game token reused across apps would otherwise
|
|
64
|
+
* cross-deliver). Use a separate client per app (sharing the token store).
|
|
61
65
|
*/
|
|
62
|
-
subscribe(handlers: UdpNotificationHandlers): () => void;
|
|
66
|
+
subscribe(handlers: UdpNotificationHandlers, appId: string): () => void;
|
|
63
67
|
private withSequence;
|
|
64
68
|
}
|
|
65
69
|
//# sourceMappingURL=udp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,uBAAuB,EAG5B,KAAK,6BAA6B,EAElC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,+BAA+B,EAEpC,KAAK,gCAAgC,EAErC,KAAK,uCAAuC,EAE5C,KAAK,mCAAmC,EACzC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D;;;;;;GAMG;AACH,qBAAa,MAAM;IAIf,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IAJd,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;gBAG3C,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,mBAAmB;IAG7B,OAAO,IAAI,OAAO,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;IAK9D,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAK9B,gBAAgB,IAAI,OAAO,CAC/B,6BAA6B,CAAC,0BAA0B,CAAC,CAC1D;IAQK,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,cAAc,CAClB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAAC,OAAO,CAAC;IAKb,qBAAqB,CACzB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,EAC/C,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAO/B;;;;;;OAMG;IACG,sBAAsB,CAC1B,KAAK,EAAE,uCAAuC,CAAC,OAAO,CAAC,GACtD,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;;OAMG;IACG,kBAAkB,CACtB,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC;IAKnB
|
|
1
|
+
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,uBAAuB,EAG5B,KAAK,6BAA6B,EAElC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,+BAA+B,EAEpC,KAAK,gCAAgC,EAErC,KAAK,uCAAuC,EAE5C,KAAK,mCAAmC,EACzC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D;;;;;;GAMG;AACH,qBAAa,MAAM;IAIf,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IAJd,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;gBAG3C,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,mBAAmB;IAG7B,OAAO,IAAI,OAAO,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;IAK9D,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAK9B,gBAAgB,IAAI,OAAO,CAC/B,6BAA6B,CAAC,0BAA0B,CAAC,CAC1D;IAQK,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,cAAc,CAClB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAAC,OAAO,CAAC;IAKb,qBAAqB,CACzB,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,EAC/C,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAOzB,eAAe,CACnB,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAC/C,OAAO,CAAC,OAAO,CAAC;IAKb,sBAAsB,CAC1B,KAAK,EAAE,gCAAgC,CAAC,OAAO,CAAC,EAChD,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAO/B;;;;;;OAMG;IACG,sBAAsB,CAC1B,KAAK,EAAE,uCAAuC,CAAC,OAAO,CAAC,GACtD,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;;OAMG;IACG,kBAAkB,CACtB,KAAK,EAAE,mCAAmC,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC;IAKnB;;;;;;;;;OASG;IACH,SAAS,CAAC,QAAQ,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI;IAIvE,OAAO,CAAC,YAAY;CAQrB"}
|
package/dist/domains/udp.js
CHANGED
|
@@ -100,13 +100,17 @@ export class UdpAPI {
|
|
|
100
100
|
return data.sendChannelMessage;
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
|
-
* Subscribe to udpNotifications. Pass any combination of
|
|
104
|
-
* handlers; the returned function detaches all of them. The first
|
|
105
|
-
* subscriber opens the shared WebSocket; the last one to leave closes
|
|
106
|
-
*
|
|
103
|
+
* Subscribe to udpNotifications for a single app. Pass any combination of
|
|
104
|
+
* typename handlers; the returned function detaches all of them. The first
|
|
105
|
+
* subscriber opens the shared WebSocket; the last one to leave closes it.
|
|
106
|
+
*
|
|
107
|
+
* `appId` is required and scopes the subscription to one app: the game-api
|
|
108
|
+
* only delivers that app's spatial notifications and rejects app-agnostic
|
|
109
|
+
* subscriptions (a single game token reused across apps would otherwise
|
|
110
|
+
* cross-deliver). Use a separate client per app (sharing the token store).
|
|
107
111
|
*/
|
|
108
|
-
subscribe(handlers) {
|
|
109
|
-
return this.subs.subscribe(handlers);
|
|
112
|
+
subscribe(handlers, appId) {
|
|
113
|
+
return this.subs.subscribe(handlers, appId);
|
|
110
114
|
}
|
|
111
115
|
withSequence(input) {
|
|
112
116
|
return {
|
|
@@ -1663,6 +1663,12 @@ export type JoinSessionInput = {
|
|
|
1663
1663
|
role?: InputMaybe<Scalars['String']['input']>;
|
|
1664
1664
|
sessionId: Scalars['String']['input'];
|
|
1665
1665
|
};
|
|
1666
|
+
export type LinkAppToEnvironmentInput = {
|
|
1667
|
+
appId: Scalars['BigInt']['input'];
|
|
1668
|
+
/** Environment slug (cks_environments.slug) to link the app to. */
|
|
1669
|
+
environmentSlug: Scalars['String']['input'];
|
|
1670
|
+
orgId: Scalars['BigInt']['input'];
|
|
1671
|
+
};
|
|
1666
1672
|
export type ListVoxelUpdatesByDistanceInput = {
|
|
1667
1673
|
appId: Scalars['BigInt']['input'];
|
|
1668
1674
|
centerCoordinate: ChunkCoordinatesInput;
|
|
@@ -1776,6 +1782,8 @@ export type Mutation = {
|
|
|
1776
1782
|
leaveChannel: Scalars['Boolean']['output'];
|
|
1777
1783
|
/** Leave a team. */
|
|
1778
1784
|
leaveTeam: Scalars['Boolean']['output'];
|
|
1785
|
+
/** Links an unlinked app to an existing environment for split-mode routing. Refuses shared apps and apps already linked elsewhere. */
|
|
1786
|
+
linkAppToEnvironment: App;
|
|
1779
1787
|
login: AuthResponse;
|
|
1780
1788
|
logout: Scalars['Boolean']['output'];
|
|
1781
1789
|
logoutAllDevices: Scalars['Boolean']['output'];
|
|
@@ -2067,6 +2075,9 @@ export type MutationLeaveChannelArgs = {
|
|
|
2067
2075
|
export type MutationLeaveTeamArgs = {
|
|
2068
2076
|
groupId: Scalars['BigInt']['input'];
|
|
2069
2077
|
};
|
|
2078
|
+
export type MutationLinkAppToEnvironmentArgs = {
|
|
2079
|
+
input: LinkAppToEnvironmentInput;
|
|
2080
|
+
};
|
|
2070
2081
|
export type MutationLoginArgs = {
|
|
2071
2082
|
loginUserInput: LoginUserInput;
|
|
2072
2083
|
};
|
|
@@ -2551,6 +2562,7 @@ export type Query = {
|
|
|
2551
2562
|
environmentDatacenters: Array<CksOvhDatacenter>;
|
|
2552
2563
|
/** Customer-selectable instance flavors in the datacenter with current availability and customer pricing. */
|
|
2553
2564
|
environmentFlavors: Array<CksOvhFlavor>;
|
|
2565
|
+
environmentForwardVersions: Array<CksEnvironmentVersion>;
|
|
2554
2566
|
/** Pricing quote for the selected flavors. Fails if any flavor is unavailable, hidden, or lacks customer pricing. */
|
|
2555
2567
|
environmentQuote: CksEnvironmentQuote;
|
|
2556
2568
|
/** Per-app usage totals for apps linked to an environment. */
|
|
@@ -2786,6 +2798,10 @@ export type QueryEffectiveQuotaArgs = {
|
|
|
2786
2798
|
export type QueryEnvironmentFlavorsArgs = {
|
|
2787
2799
|
datacenter: Scalars['String']['input'];
|
|
2788
2800
|
};
|
|
2801
|
+
export type QueryEnvironmentForwardVersionsArgs = {
|
|
2802
|
+
orgId: Scalars['BigInt']['input'];
|
|
2803
|
+
slug: Scalars['String']['input'];
|
|
2804
|
+
};
|
|
2789
2805
|
export type QueryEnvironmentQuoteArgs = {
|
|
2790
2806
|
input: EnvironmentQuoteInput;
|
|
2791
2807
|
};
|
|
@@ -3028,6 +3044,7 @@ export type RedeployEnvironmentInput = {
|
|
|
3028
3044
|
deployMode?: InputMaybe<RedeployDeployMode>;
|
|
3029
3045
|
orgId: Scalars['BigInt']['input'];
|
|
3030
3046
|
slug: Scalars['String']['input'];
|
|
3047
|
+
version?: InputMaybe<Scalars['String']['input']>;
|
|
3031
3048
|
};
|
|
3032
3049
|
export type RegisterUserInput = {
|
|
3033
3050
|
email: Scalars['String']['input'];
|