Skip to content

Commit d74050d

Browse files
author
Luke Gehorsam
authored
release v2.7.0 (#173)
1 parent 7dece4c commit d74050d

File tree

12 files changed

+1006
-39
lines changed

12 files changed

+1006
-39
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ The format is based on [keep a changelog](http://keepachangelog.com/) and this p
55

66
### Unreleased
77

8+
### [2.7.0]
9+
### Added
10+
- Satori: Added ability to schedule, update and delete outgoing messages for Live Events.
11+
- Satori: Added ability to add custom and default properties for a user at the point of authentication.
12+
- Satori: Add 'recompute' param to Satori's update-properties.
13+
- Satori: Added ability to delete identity.
14+
- Nakama: Added ability to create match by name.
15+
16+
### Changed
17+
- Nakama: Improves how outgoing messages are logged in verbose mode.
18+
- Nakama: Updated signature for Authenticate Game Center.
19+
20+
### Fixed
21+
- Nakama: Fixed typings distribution location for protobuf-js.
22+
- Nakama: Fixed how newer bundlers (such as those used by ViteJs) discover Nakama's type definitions.
23+
- Satori: Return live event ID when getting all live events.
24+
825
### [2.6.1]
926

1027
### Added

openapi-gen/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ go run main.go "$GOPATH/src/github.com/heroiclabs/nakama/apigrpc/apigrpc.swagger
1414
### Satori
1515

1616
```shell
17-
go run main.go "$GOPATH/src/github.com/heroiclabs/nakama/apigrpc/apigrpc.swagger.json" "Satori" > ../packages/satori-js/api.gen.ts
17+
go run main.go "$GOPATH/src/github.com/heroiclabs/satori/api/satori.swagger.json" "Satori" > ../packages/satori-js/api.gen.ts
1818
```
1919

2020
### Rationale

packages/nakama-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@heroiclabs/nakama-js",
3-
"version": "2.6.1",
3+
"version": "2.7.0",
44
"scripts": {
55
"build": "npx tsc && npx rollup -c --bundleConfigAsCjs && node build.mjs"
66
},

packages/satori-js/api.gen.ts

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export interface ApiAuthenticateRefreshRequest {
2020

2121
/** */
2222
export interface ApiAuthenticateRequest {
23+
//Optional custom properties to update with this call. If not set, properties are left as they are on the server.
24+
custom?: Record<string, string>;
25+
//Optional default properties to update with this call. If not set, properties are left as they are on the server.
26+
default?: Record<string, string>;
2327
//Identity ID. Must be between eight and 128 characters (inclusive). Must be an alphanumeric string with only underscores and hyphens allowed.
2428
id?: string;
2529
}
@@ -74,6 +78,18 @@ export interface ApiFlagList {
7478
flags?: Array<ApiFlag>;
7579
}
7680

81+
/** A response containing all the messages for an identity. */
82+
export interface ApiGetMessageListResponse {
83+
//Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors.
84+
cacheable_cursor?: string;
85+
//The list of messages.
86+
messages?: Array<ApiMessage>;
87+
//The cursor to send when retrieving the next page, if any.
88+
next_cursor?: string;
89+
//The cursor to send when retrieving the previous page, if any.
90+
prev_cursor?: string;
91+
}
92+
7793
/** Enrich/replace the current session with a new ID. */
7894
export interface ApiIdentifyRequest {
7995
//Optional custom properties to update with this call. If not set, properties are left as they are on the server.
@@ -92,6 +108,8 @@ export interface ApiLiveEvent {
92108
active_start_time_sec?: string;
93109
//Description.
94110
description?: string;
111+
//The live event identifier.
112+
id?: string;
95113
//Name.
96114
name?: string;
97115
//Event value.
@@ -104,6 +122,26 @@ export interface ApiLiveEventList {
104122
live_events?: Array<ApiLiveEvent>;
105123
}
106124

125+
/** A scheduled message. */
126+
export interface ApiMessage {
127+
//The time the message was consumed by the identity.
128+
consume_time?: string;
129+
//The time the message was created.
130+
create_time?: string;
131+
//A key-value pairs of metadata.
132+
metadata?: Record<string, string>;
133+
//The time the message was read by the client.
134+
read_time?: string;
135+
//The identifier of the schedule.
136+
schedule_id?: string;
137+
//The send time for the message.
138+
send_time?: string;
139+
//The message's text.
140+
text?: string;
141+
//The time the message was updated.
142+
update_time?: string;
143+
}
144+
107145
/** Properties associated with an identity. */
108146
export interface ApiProperties {
109147
//Event computed properties.
@@ -124,6 +162,16 @@ export interface ApiSession {
124162
token?: string;
125163
}
126164

165+
/** The request to update the status of a message. */
166+
export interface ApiUpdateMessageRequest {
167+
//The time the message was consumed by the identity.
168+
consume_time?: string;
169+
//The identifier of the messages.
170+
id?: string;
171+
//The time the message was read at the client.
172+
read_time?: string;
173+
}
174+
127175
/** Update Properties associated with this identity. */
128176
export interface ApiUpdatePropertiesRequest {
129177
//Event custom properties.
@@ -137,7 +185,9 @@ export interface ApiUpdatePropertiesRequest {
137185
/** */
138186
export interface ProtobufAny {
139187
//
140-
type?: string;
188+
type_url?: string;
189+
//
190+
value?: string;
141191
}
142192

143193
/** */
@@ -532,6 +582,120 @@ export class SatoriApi {
532582
]);
533583
}
534584

585+
/** Get the list of messages for the identity. */
586+
satoriGetMessageList(bearerToken: string,
587+
limit?:number,
588+
forward?:boolean,
589+
cursor?:string,
590+
options: any = {}): Promise<ApiGetMessageListResponse> {
591+
592+
const urlPath = "/v1/message";
593+
const queryParams = new Map<string, any>();
594+
queryParams.set("limit", limit);
595+
queryParams.set("forward", forward);
596+
queryParams.set("cursor", cursor);
597+
598+
let bodyJson : string = "";
599+
600+
const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
601+
const fetchOptions = buildFetchOptions("GET", options, bodyJson);
602+
if (bearerToken) {
603+
fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
604+
}
605+
606+
return Promise.race([
607+
fetch(fullUrl, fetchOptions).then((response) => {
608+
if (response.status == 204) {
609+
return response;
610+
} else if (response.status >= 200 && response.status < 300) {
611+
return response.json();
612+
} else {
613+
throw response;
614+
}
615+
}),
616+
new Promise((_, reject) =>
617+
setTimeout(reject, this.timeoutMs, "Request timed out.")
618+
),
619+
]);
620+
}
621+
622+
/** Deletes a message for an identity. */
623+
satoriDeleteMessage(bearerToken: string,
624+
id:string,
625+
options: any = {}): Promise<any> {
626+
627+
if (id === null || id === undefined) {
628+
throw new Error("'id' is a required parameter but is null or undefined.");
629+
}
630+
const urlPath = "/v1/message/{id}"
631+
.replace("{id}", encodeURIComponent(String(id)));
632+
const queryParams = new Map<string, any>();
633+
634+
let bodyJson : string = "";
635+
636+
const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
637+
const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
638+
if (bearerToken) {
639+
fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
640+
}
641+
642+
return Promise.race([
643+
fetch(fullUrl, fetchOptions).then((response) => {
644+
if (response.status == 204) {
645+
return response;
646+
} else if (response.status >= 200 && response.status < 300) {
647+
return response.json();
648+
} else {
649+
throw response;
650+
}
651+
}),
652+
new Promise((_, reject) =>
653+
setTimeout(reject, this.timeoutMs, "Request timed out.")
654+
),
655+
]);
656+
}
657+
658+
/** Updates a message for an identity. */
659+
satoriUpdateMessage(bearerToken: string,
660+
id:string,
661+
body:ApiUpdateMessageRequest,
662+
options: any = {}): Promise<any> {
663+
664+
if (id === null || id === undefined) {
665+
throw new Error("'id' is a required parameter but is null or undefined.");
666+
}
667+
if (body === null || body === undefined) {
668+
throw new Error("'body' is a required parameter but is null or undefined.");
669+
}
670+
const urlPath = "/v1/message/{id}"
671+
.replace("{id}", encodeURIComponent(String(id)));
672+
const queryParams = new Map<string, any>();
673+
674+
let bodyJson : string = "";
675+
bodyJson = JSON.stringify(body || {});
676+
677+
const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
678+
const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
679+
if (bearerToken) {
680+
fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
681+
}
682+
683+
return Promise.race([
684+
fetch(fullUrl, fetchOptions).then((response) => {
685+
if (response.status == 204) {
686+
return response;
687+
} else if (response.status >= 200 && response.status < 300) {
688+
return response.json();
689+
} else {
690+
throw response;
691+
}
692+
}),
693+
new Promise((_, reject) =>
694+
setTimeout(reject, this.timeoutMs, "Request timed out.")
695+
),
696+
]);
697+
}
698+
535699
/** List properties associated with this identity. */
536700
satoriListProperties(bearerToken: string,
537701
options: any = {}): Promise<ApiProperties> {

packages/satori-js/client.ts

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { SatoriApi, ApiSession, ApiAuthenticateRequest, ApiEventRequest, ApiAuthenticateLogoutRequest, ApiAuthenticateRefreshRequest, ApiIdentifyRequest, ApiUpdatePropertiesRequest, ApiEvent } from "./api.gen";
17+
import { SatoriApi, ApiSession, ApiAuthenticateRequest, ApiEventRequest, ApiAuthenticateLogoutRequest, ApiAuthenticateRefreshRequest, ApiIdentifyRequest, ApiUpdatePropertiesRequest, ApiEvent, ApiUpdateMessageRequest } from "./api.gen";
1818

1919
import { Session } from "./session";
2020

@@ -47,10 +47,12 @@ export class Client {
4747
}
4848

4949
/** Authenticate a user with an ID against the server. */
50-
async authenticate(id: string) {
50+
async authenticate(id: string, customProperties?: Record<string, string>, defaultProperties?: Record<string, string>) {
5151

5252
const request : ApiAuthenticateRequest = {
5353
"id": id,
54+
custom: customProperties,
55+
default: defaultProperties
5456
};
5557

5658
return this.apiClient.satoriAuthenticate(this.apiKey, "", request).then((apiSession : ApiSession) => {
@@ -149,7 +151,7 @@ export class Client {
149151
});
150152
}
151153

152-
154+
153155
/** Get a single flag for this identity. */
154156
async getFlagWithFallback(session: Session, name: string, fallbackValue?: string) {
155157
return this.getFlag(session, name)
@@ -278,9 +280,48 @@ export class Client {
278280
session.isexpired((Date.now() + this.expiredTimespanMs)/1000)) {
279281
await this.sessionRefresh(session);
280282
}
281-
283+
282284
return this.apiClient.satoriDeleteIdentity(session.token).then((response) => {
283285
return Promise.resolve(response !== undefined);
284286
});
285287
}
288+
289+
async getMessageList(session : Session) {
290+
if (this.autoRefreshSession && session.refresh_token &&
291+
session.isexpired((Date.now() + this.expiredTimespanMs)/1000)) {
292+
await this.sessionRefresh(session);
293+
}
294+
295+
return this.apiClient.satoriGetMessageList(session.token).then((response) => {
296+
return Promise.resolve(response !== undefined);
297+
});
298+
}
299+
300+
async deleteMessage(session : Session, id : string) {
301+
if (this.autoRefreshSession && session.refresh_token &&
302+
session.isexpired((Date.now() + this.expiredTimespanMs)/1000)) {
303+
await this.sessionRefresh(session);
304+
}
305+
306+
return this.apiClient.satoriDeleteMessage(session.token, id).then((response) => {
307+
return Promise.resolve(response !== undefined);
308+
});
309+
}
310+
311+
async updateMessage(session : Session, id : string, consume_time? : string, read_time? : string) {
312+
if (this.autoRefreshSession && session.refresh_token &&
313+
session.isexpired((Date.now() + this.expiredTimespanMs)/1000)) {
314+
await this.sessionRefresh(session);
315+
}
316+
317+
const request : ApiUpdateMessageRequest = {
318+
id: id,
319+
consume_time: consume_time,
320+
read_time: read_time
321+
};
322+
323+
return this.apiClient.satoriUpdateMessage(session.token, id, request).then((response) => {
324+
return Promise.resolve(response !== undefined);
325+
});
326+
}
286327
};

0 commit comments

Comments
 (0)