Skip to content

Commit 9da1b1b

Browse files
authored
Merge pull request #725 from kuzzleio/7.10.7-proposal
# [7.10.7](https://github.com/kuzzleio/sdk-javascript/releases/tag/7.10.7) (2023-03-06) #### Enhancements - [ [#723](#723) ] Improve typings ([ScreamZ](https://github.com/ScreamZ)) - [ [#724](#724) ] Add support and documentation to use API keys ([ScreamZ](https://github.com/ScreamZ)) ---
2 parents 2033928 + 065accf commit 9da1b1b

File tree

13 files changed

+211
-48
lines changed

13 files changed

+211
-48
lines changed

doc/7/controllers/auth/create-api-key/snippets/create-api-key.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ try {
1818
*/
1919

2020
console.log('API key successfully created');
21+
22+
// Then use it with your client. Note: You don't need to call login after this because this bypasses the authentication system.
23+
kuzzle.setAPIKey(apiKey._source.token)
2124
} catch (e) {
2225
console.error(e);
2326
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "kuzzle-sdk",
3-
"version": "7.10.6",
3+
"version": "7.10.7",
44
"description": "Official Javascript SDK for Kuzzle",
55
"author": "The Kuzzle Team <[email protected]>",
66
"repository": {

src/Kuzzle.ts

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { KuzzleEventEmitter } from "./core/KuzzleEventEmitter";
1+
import {
2+
KuzzleEventEmitter,
3+
PrivateAndPublicSDKEvents,
4+
PublicKuzzleEvents,
5+
} from "./core/KuzzleEventEmitter";
26
import { KuzzleAbstractProtocol } from "./protocols/abstract/Base";
37

48
import { AuthController } from "./controllers/Auth";
@@ -15,11 +19,13 @@ import { Deprecation } from "./utils/Deprecation";
1519
import { uuidv4 } from "./utils/uuidv4";
1620
import { proxify } from "./utils/proxify";
1721
import { debug } from "./utils/debug";
18-
import { BaseRequest, JSONObject } from "./types";
22+
import { BaseRequest, JSONObject, Notification } from "./types";
1923
import { RequestPayload } from "./types/RequestPayload";
2024
import { ResponsePayload } from "./types/ResponsePayload";
2125
import { RequestTimeoutError } from "./RequestTimeoutError";
2226
import { BaseProtocolRealtime } from "./protocols/abstract/Realtime";
27+
import { KuzzleError } from "./KuzzleError";
28+
import { DisconnectionOrigin } from "./protocols/DisconnectionOrigin";
2329

2430
// Defined by webpack plugin
2531
declare const SDKVERSION: any;
@@ -72,7 +78,7 @@ export class Kuzzle extends KuzzleEventEmitter {
7278
/**
7379
* List of every events emitted by the SDK.
7480
*/
75-
public events = [
81+
public events: PublicKuzzleEvents[] = [
7682
"callbackError",
7783
"connected",
7884
"discarded",
@@ -542,7 +548,7 @@ export class Kuzzle extends KuzzleEventEmitter {
542548
* Emit an event to all registered listeners
543549
* An event cannot be emitted multiple times before a timeout has been reached.
544550
*/
545-
emit(eventName: string, ...payload) {
551+
public emit(eventName: PrivateAndPublicSDKEvents, ...payload: unknown[]) {
546552
const now = Date.now(),
547553
protectedEvent = this._protectedEvents[eventName];
548554

@@ -563,6 +569,48 @@ export class Kuzzle extends KuzzleEventEmitter {
563569
return super.emit(eventName, ...payload);
564570
}
565571

572+
on(
573+
eventName: "connected" | "reconnected" | "reAuthenticated" | "tokenExpired",
574+
listener: () => void
575+
): this;
576+
577+
on(
578+
eventName: "logoutAttempt",
579+
listener: (status: { success: true }) => void
580+
): this;
581+
on(
582+
eventName: "loginAttempt",
583+
listener: (data: { success: boolean; error: string }) => void
584+
): this;
585+
on(eventName: "discarded", listener: (request: RequestPayload) => void): this;
586+
on(
587+
eventName: "disconnected",
588+
listener: (context: { origin: DisconnectionOrigin }) => void
589+
): this;
590+
on(
591+
eventName: "networkError" | "reconnectionError",
592+
listener: (error: Error) => void
593+
): this;
594+
on(
595+
eventName: "offlineQueuePop",
596+
listener: (request: RequestPayload) => void
597+
): this;
598+
on(
599+
eventName: "offlineQueuePush",
600+
listener: (data: { request: RequestPayload }) => void
601+
): this;
602+
on(
603+
eventName: "queryError",
604+
listener: (data: { error: KuzzleError; request: RequestPayload }) => void
605+
): this;
606+
on(
607+
eventName: "callbackError",
608+
listener: (data: { error: KuzzleError; notification: Notification }) => void
609+
): this;
610+
on(eventName: PublicKuzzleEvents, listener: (args: any) => void): this {
611+
return super.on(eventName, listener);
612+
}
613+
566614
/**
567615
* Connects to a Kuzzle instance
568616
*/
@@ -620,6 +668,19 @@ export class Kuzzle extends KuzzleEventEmitter {
620668
return this.protocol.connect();
621669
}
622670

671+
/**
672+
* Set this client to use a specific API key.
673+
*
674+
* After doing this you don't need to use login as it bypasses the authentication process.
675+
*/
676+
public setAPIKey(apiKey: string) {
677+
if (apiKey.match(/^kapikey-/) === null) {
678+
throw new Error("Invalid API key. Missing the `kapikey-` prefix.");
679+
}
680+
681+
this.jwt = apiKey;
682+
}
683+
623684
async _reconnect() {
624685
if (this._reconnectInProgress) {
625686
return;

src/core/KuzzleEventEmitter.ts

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
type ListenerFunction = (...args: unknown[]) => unknown;
2+
13
class Listener {
2-
public fn: (...any) => any;
4+
public fn: ListenerFunction;
35
public once: boolean;
46

57
constructor(fn, once = false) {
@@ -8,6 +10,37 @@ class Listener {
810
}
911
}
1012

13+
export type PublicKuzzleEvents =
14+
| "callbackError"
15+
| "connected"
16+
| "discarded"
17+
| "disconnected"
18+
| "loginAttempt"
19+
| "logoutAttempt"
20+
| "networkError"
21+
| "offlineQueuePush"
22+
| "offlineQueuePop"
23+
| "queryError"
24+
| "reAuthenticated"
25+
| "reconnected"
26+
| "reconnectionError"
27+
| "tokenExpired";
28+
29+
type PrivateKuzzleEvents =
30+
| "connect"
31+
| "reconnect"
32+
| "disconnect"
33+
| "offlineQueuePush"
34+
| "websocketRenewalStart"
35+
| "websocketRenewalDone";
36+
37+
/**
38+
* For internal use only
39+
*/
40+
export type PrivateAndPublicSDKEvents =
41+
| PublicKuzzleEvents
42+
| PrivateKuzzleEvents;
43+
1144
/**
1245
* @todo proper TS conversion
1346
*/
@@ -18,23 +51,28 @@ export class KuzzleEventEmitter {
1851
this._events = new Map();
1952
}
2053

21-
private _exists(listeners, fn) {
54+
private _exists(listeners: Listener[], fn: ListenerFunction) {
2255
return Boolean(listeners.find((listener) => listener.fn === fn));
2356
}
2457

25-
listeners(eventName) {
58+
listeners(eventName: PrivateAndPublicSDKEvents) {
2659
if (!this._events.has(eventName)) {
2760
return [];
2861
}
2962

3063
return this._events.get(eventName).map((listener) => listener.fn);
3164
}
3265

33-
addListener(eventName, listener, once = false) {
66+
addListener(
67+
eventName: PrivateAndPublicSDKEvents,
68+
listener: ListenerFunction,
69+
once = false
70+
) {
3471
if (!eventName || !listener) {
3572
return this;
3673
}
3774

75+
// TODO: this check could be safely, when TypeScript type will be completed.
3876
const listenerType = typeof listener;
3977

4078
if (listenerType !== "function") {
@@ -54,7 +92,10 @@ export class KuzzleEventEmitter {
5492
return this;
5593
}
5694

57-
on(eventName, listener) {
95+
on(
96+
eventName: PrivateAndPublicSDKEvents,
97+
listener: (args: any) => void
98+
): this {
5899
return this.addListener(eventName, listener);
59100
}
60101

@@ -90,7 +131,12 @@ export class KuzzleEventEmitter {
90131
return this.prependListener(eventName, listener, true);
91132
}
92133

93-
removeListener(eventName, listener) {
134+
removeListener(
135+
eventName: PrivateAndPublicSDKEvents,
136+
listener: () => void
137+
): this;
138+
removeListener(eventName: string, listener: () => void): this;
139+
removeListener(eventName: string, listener: (...args: unknown[]) => void) {
94140
const listeners = this._events.get(eventName);
95141

96142
if (!listeners || !listeners.length) {
@@ -110,7 +156,9 @@ export class KuzzleEventEmitter {
110156
return this;
111157
}
112158

113-
removeAllListeners(eventName?: string) {
159+
removeAllListeners(eventName?: PrivateAndPublicSDKEvents): this;
160+
removeAllListeners(eventName?: string): this;
161+
removeAllListeners(eventName?: string): this {
114162
if (eventName) {
115163
this._events.delete(eventName);
116164
} else {
@@ -120,7 +168,10 @@ export class KuzzleEventEmitter {
120168
return this;
121169
}
122170

123-
emit(eventName, ...payload) {
171+
// TODO: Improve these unknown type someday, to secure all emit events and be sure they match {@link KuzzleEventEmitter.on}.
172+
emit(eventName: PrivateAndPublicSDKEvents, ...payload: unknown[]): boolean;
173+
emit(eventName: string, ...payload: unknown[]): boolean;
174+
emit(eventName: string, ...payload: unknown[]): boolean {
124175
const listeners = this._events.get(eventName);
125176

126177
if (listeners === undefined) {
@@ -148,7 +199,7 @@ export class KuzzleEventEmitter {
148199
return Array.from(this._events.keys());
149200
}
150201

151-
listenerCount(eventName) {
202+
listenerCount(eventName: PrivateAndPublicSDKEvents) {
152203
return (
153204
(this._events.has(eventName) && this._events.get(eventName).length) || 0
154205
);

src/protocols/DisconnectionOrigin.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const WEBSOCKET_AUTH_RENEWAL = "websocket/auth-renewal";
2-
const USER_CONNECTION_CLOSED = "user/connection-closed";
3-
const NETWORK_ERROR = "network/error";
4-
5-
export { WEBSOCKET_AUTH_RENEWAL, USER_CONNECTION_CLOSED, NETWORK_ERROR };
1+
export enum DisconnectionOrigin {
2+
WEBSOCKET_AUTH_RENEWAL = "websocket/auth-renewal",
3+
USER_CONNECTION_CLOSED = "user/connection-closed",
4+
NETWORK_ERROR = "network/error",
5+
}

src/protocols/WebSocket.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { BaseProtocolRealtime } from "./abstract/Realtime";
55
import { JSONObject } from "../types";
66
import { RequestPayload } from "../types/RequestPayload";
77
import HttpProtocol from "./Http";
8-
import * as DisconnectionOrigin from "./DisconnectionOrigin";
8+
import { DisconnectionOrigin } from "./DisconnectionOrigin";
99

1010
/**
1111
* WebSocket protocol used to connect to a Kuzzle server.
@@ -285,7 +285,7 @@ export default class WebSocketProtocol extends BaseProtocolRealtime {
285285
/**
286286
* @override
287287
*/
288-
clientDisconnected(origin: string) {
288+
clientDisconnected(origin: DisconnectionOrigin) {
289289
clearInterval(this.pingIntervalId);
290290
this.pingIntervalId = null;
291291
super.clientDisconnected(origin);

src/protocols/abstract/Realtime.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"use strict";
22

33
import { KuzzleAbstractProtocol } from "./Base";
4-
import * as DisconnectionOrigin from "../DisconnectionOrigin";
54
import { getBrowserWindow, isBrowser } from "../../utils/browser";
5+
import { DisconnectionOrigin } from "../DisconnectionOrigin";
6+
import { KuzzleError } from "../../KuzzleError";
67

78
export abstract class BaseProtocolRealtime extends KuzzleAbstractProtocol {
89
protected _reconnectionDelay: number;
@@ -56,17 +57,17 @@ export abstract class BaseProtocolRealtime extends KuzzleAbstractProtocol {
5657
*
5758
* @param {string} origin String that describe what is causing the disconnection
5859
*/
59-
clientDisconnected(origin: string) {
60+
clientDisconnected(origin: DisconnectionOrigin) {
6061
this.clear();
6162
this.emit("disconnect", { origin });
6263
}
6364

6465
/**
6566
* Called when the client's connection is closed with an error state
6667
*
67-
* @param {Error} error
68+
* @param {KuzzleError} error
6869
*/
69-
clientNetworkError(error) {
70+
clientNetworkError(error: KuzzleError) {
7071
// Only emit disconnect once, if the connection was ready before
7172
if (this.isReady()) {
7273
this.emit("disconnect", { origin: DisconnectionOrigin.NETWORK_ERROR });

src/types/JSONObject.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
/**
22
* An interface representing an object with string key and any value
33
*/
4-
export interface JSONObject {
5-
[key: string]: JSONObject | any;
6-
}
4+
export type JSONObject = Record<PropertyKey, any>;

src/types/Notification.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@ import { KDocument, KDocumentContentGeneric } from ".";
66
*/
77
export type NotificationType = "document" | "user" | "TokenExpired";
88

9-
/**
10-
* Real-time notifications sent by Kuzzle.
11-
*
12-
*/
13-
export interface Notification {
9+
export interface BaseNotification {
1410
/**
1511
* Notification type
1612
*/
1713
type: NotificationType;
18-
}
1914

20-
export interface BaseNotification extends Notification {
2115
/**
2216
* Controller that triggered the notification
2317
*/
@@ -62,11 +56,13 @@ export interface BaseNotification extends Notification {
6256
* Notification triggered by a document change.
6357
* (create, update, delete)
6458
*/
65-
export interface DocumentNotification extends BaseNotification {
59+
export interface DocumentNotification<
60+
TDocContent extends KDocumentContentGeneric = KDocumentContentGeneric
61+
> extends BaseNotification {
6662
/**
6763
* Updated document that triggered the notification
6864
*/
69-
result: KDocument<KDocumentContentGeneric>;
65+
result: KDocument<TDocContent>;
7066
/**
7167
* State of the document regarding the scope (`in` or `out`)
7268
*/
@@ -105,3 +101,11 @@ export interface ServerNotification extends BaseNotification {
105101

106102
type: "TokenExpired";
107103
}
104+
105+
/**
106+
* Real-time notifications sent by Kuzzle.
107+
*/
108+
export type Notification =
109+
| DocumentNotification
110+
| UserNotification
111+
| ServerNotification;

0 commit comments

Comments
 (0)