From 06782d938626703e95b71b16461efa30bee8a6de Mon Sep 17 00:00:00 2001 From: Aschen Date: Fri, 17 Dec 2021 18:32:35 +0100 Subject: [PATCH 1/3] Add types for mRequest an mResponses --- doc/7/core-classes/kuzzle/properties/index.md | 4 +- src/Kuzzle.ts | 112 +++++---- src/controllers/Document.ts | 220 +++--------------- src/types/index.ts | 4 + src/types/mRequests.ts | 47 ++++ src/types/mResponses.ts | 105 +++++++++ 6 files changed, 254 insertions(+), 238 deletions(-) create mode 100644 src/types/mRequests.ts create mode 100644 src/types/mResponses.ts diff --git a/doc/7/core-classes/kuzzle/properties/index.md b/doc/7/core-classes/kuzzle/properties/index.md index ff1437e70..3b9d8070a 100644 --- a/doc/7/core-classes/kuzzle/properties/index.md +++ b/doc/7/core-classes/kuzzle/properties/index.md @@ -14,6 +14,8 @@ order: 10 | `connected` |
boolean
| Returns `true` if the SDK is currently connected to a Kuzzle server. | | `offlineQueue` |
object[]
| Contains the queued requests during offline mode | | `protocol` |
Protocol
| Protocol used by the SDK | +| `events` |
string[]
| List of every events emitted by the SDK | + ### connected @@ -42,7 +44,7 @@ See the associated documentation: The `authenticator` property can be set to a function returning a promise. -This function will be called after a successful reconnection if the current authentication token is not valid anymore. +This function will be called after a successful reconnection if the current authentication token is not valid anymore. This function has to authenticate the SDK. It can be a call to [auth.login](/sdk/js/7/controllers/auth/login) for example. diff --git a/src/Kuzzle.ts b/src/Kuzzle.ts index 7ed5aa587..9dbe7d8a1 100644 --- a/src/Kuzzle.ts +++ b/src/Kuzzle.ts @@ -22,22 +22,6 @@ import { RequestTimeoutError } from './RequestTimeoutError'; // Defined by webpack plugin declare const SDKVERSION: any; -const events = [ - 'connected', - 'discarded', - 'disconnected', - 'loginAttempt', - 'logoutAttempt', - 'networkError', - 'offlineQueuePush', - 'offlineQueuePop', - 'queryError', - 'reAuthenticated', - 'reconnected', - 'reconnectionError', - 'tokenExpired' -]; - export class Kuzzle extends KuzzleEventEmitter { // We need to define any string key because users can register new controllers [key: string]: any; @@ -45,46 +29,72 @@ export class Kuzzle extends KuzzleEventEmitter { /** * Protocol used by the SDK to communicate with Kuzzle. */ - protocol: any; + public protocol: any; + /** * If true, automatically renews all subscriptions on a reconnected event. */ - autoResubscribe: boolean; + public autoResubscribe: boolean; + /** * Timeout before sending again a similar event. */ - eventTimeout: number; + public eventTimeout: number; + /** * SDK version. */ - sdkVersion: string; + public sdkVersion: string; + /** * SDK name (e.g: `js@7.4.2`). */ - sdkName: string; + public sdkName: string; + /** * Common volatile data that will be sent to all future requests. */ - volatile: JSONObject; + public volatile: JSONObject; + /** * Handle deprecation warning in development mode (hidden in production) */ - deprecationHandler: Deprecation; + public deprecationHandler: Deprecation; + /** * Authenticator function called after a reconnection if the SDK is no longer * authenticated. */ - authenticator: () => Promise = null; - - auth: AuthController; - bulk: any; - collection: CollectionController; - document: DocumentController; - index: IndexController; - ms: any; - realtime: RealtimeController; - security: SecurityController; - server: any; + public authenticator: () => Promise = null; + + /** + * List of every events emitted by the SDK. + */ + public events = [ + 'connected', + 'discarded', + 'disconnected', + 'loginAttempt', + 'logoutAttempt', + 'networkError', + 'offlineQueuePush', + 'offlineQueuePop', + 'queryError', + 'reAuthenticated', + 'reconnected', + 'reconnectionError', + 'tokenExpired', + ]; + + public auth: AuthController; + public bulk: any; + public collection: CollectionController; + public document: DocumentController; + public index: IndexController; + public ms: any; + public realtime: RealtimeController; + public security: SecurityController; + public server: any; private _protectedEvents: any; private _offlineQueue: any; @@ -336,7 +346,7 @@ export class Kuzzle extends KuzzleEventEmitter { this._loggedIn = true; return; } - + /** * In case of login failure we need to be sure that the stored token is still valid */ @@ -376,8 +386,11 @@ export class Kuzzle extends KuzzleEventEmitter { }) as Kuzzle; } + /** + * Returns `true` if the SDK holds a valid token + */ get authenticated () { - return this.auth.authenticationToken && !this.auth.authenticationToken.expired; + return Boolean(this.auth.authenticationToken && ! this.auth.authenticationToken.expired); } get autoQueue () { @@ -407,10 +420,17 @@ export class Kuzzle extends KuzzleEventEmitter { this._autoReplay = value; } + /** + * Returns `true` if the SDK is using the cookie authentication mode. + * (Web only) + */ get cookieAuthentication () { return this._cookieAuthentication; } + /** + * Returns `true` if the SDK is currently connected to a Kuzzle server. + */ get connected () { return this.protocol.connected; } @@ -517,7 +537,7 @@ export class Kuzzle extends KuzzleEventEmitter { * Emit an event to all registered listeners * An event cannot be emitted multiple times before a timeout has been reached. */ - emit (eventName, ...payload) { + emit (eventName: string, ...payload) { const now = Date.now(), protectedEvent = this._protectedEvents[eventName]; @@ -593,11 +613,11 @@ export class Kuzzle extends KuzzleEventEmitter { if (this._reconnectInProgress) { return; } - + if (this.autoQueue) { this.stopQueuing(); } - + // If an authenticator was set, check if a user was logged in and if the token is still valid and try // to re-authenticate if needed. Otherwise the SDK is in disconnected state. if ( this._loggedIn @@ -605,14 +625,14 @@ export class Kuzzle extends KuzzleEventEmitter { ) { this._loggedIn = false; this.disconnect(); - + return; } - + if (this.autoReplay) { this.playQueue(); } - + this.emit('reconnected'); } @@ -690,8 +710,8 @@ export class Kuzzle extends KuzzleEventEmitter { * @param {function} listener - callback to invoke each time an event is fired */ addListener (event, listener) { - if (events.indexOf(event) === -1) { - throw new Error(`[${event}] is not a known event. Known events: ${events.toString()}`); + if (this.events.indexOf(event) === -1) { + throw new Error(`[${event}] is not a known event. Known events: ${this.events.join(', ')}`); } return this._superAddListener(event, listener); @@ -751,7 +771,7 @@ export class Kuzzle extends KuzzleEventEmitter { if (options && options.queuable === false) { queuable = false; } - + if (this.queueFilter) { queuable = queuable && this.queueFilter(request); } @@ -767,7 +787,7 @@ export class Kuzzle extends KuzzleEventEmitter { } request[key] = value; } - + if (request.refresh === undefined && options.refresh !== undefined) { request.refresh = options.refresh; } diff --git a/src/controllers/Document.ts b/src/controllers/Document.ts index c48cc3d87..5946a5810 100644 --- a/src/controllers/Document.ts +++ b/src/controllers/Document.ts @@ -1,7 +1,22 @@ import { BaseController } from './Base'; -import { SearchResult } from '../core/searchResult/SearchResultBase'; import { DocumentSearchResult } from '../core/searchResult/Document'; -import { JSONObject, Document, DocumentHit, ArgsDefault } from '../types'; +import { + JSONObject, + Document, + mCreateResponse, + ArgsDefault, + mCreateRequest, + mCreateOrReplaceRequest, + mCreateOrReplaceResponse, + mDeleteRequest, + mDeleteResponse, + mReplaceRequest, + mReplaceResponse, + mUpdateRequest, + mUpdateResponse, + DocumentHit, +} from '../types'; +import { SearchResult } from '../core/searchResult/SearchResultBase'; export class DocumentController extends BaseController { constructor (kuzzle) { @@ -311,40 +326,9 @@ export class DocumentController extends BaseController { mCreate ( index: string, collection: string, - documents: Array<{ - /** - * Optional document ID - */ - _id?: string; - /** - * Document content - */ - body: JSONObject; - }>, + documents: mCreateRequest, options: ArgsDocumentControllerMCreate = {} - ): Promise<{ - /** - * Array of successfully created documents - */ - successes: Array; - /** - * Array of failed creation - */ - errors: Array<{ - /** - * Document that cause the error - */ - document: Document; - /** - * HTTP error status - */ - status: number; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, @@ -378,40 +362,9 @@ export class DocumentController extends BaseController { mCreateOrReplace ( index: string, collection: string, - documents: Array<{ - /** - * Document ID - */ - _id: string; - /** - * Document content - */ - body: JSONObject; - }>, + documents: mCreateOrReplaceRequest, options: ArgsDocumentControllerMCreateOrReplace = {} - ): Promise<{ - /** - * Array of successfully created documents - */ - successes: Array; - /** - * Array of failed creation - */ - errors: Array<{ - /** - * Document that cause the error - */ - document: Document; - /** - * HTTP error status - */ - status: number; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, @@ -445,27 +398,9 @@ export class DocumentController extends BaseController { mDelete ( index: string, collection: string, - ids: Array, + ids: mDeleteRequest, options: ArgsDocumentControllerMDelete = {} - ): Promise<{ - /** - * Array of successfully deleted documents IDS - */ - successes: Array; - /** - * Array of failed deletion - */ - errors: Array<{ - /** - * Document ID - */ - id: string; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, @@ -540,40 +475,9 @@ export class DocumentController extends BaseController { mReplace ( index: string, collection: string, - documents: Array<{ - /** - * Document ID - */ - _id: string; - /** - * Document content - */ - body: JSONObject; - }>, + documents: mReplaceRequest, options: ArgsDocumentControllerMReplace = {} - ): Promise<{ - /** - * Array of successfully replaced documents - */ - successes: Array; - /** - * Array of failed creation - */ - errors: Array<{ - /** - * Document that cause the error - */ - document: Document; - /** - * HTTP error status - */ - status: number; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, @@ -611,40 +515,9 @@ export class DocumentController extends BaseController { mUpdate ( index: string, collection: string, - documents: Array<{ - /** - * Document ID - */ - _id: string; - /** - * Document content - */ - body: JSONObject; - }>, + documents: mUpdateRequest, options: ArgsDocumentControllerMUpdate = {} - ): Promise<{ - /** - * Array of successfully updated documents - */ - successes: Array; - /** - * Array of failed creation - */ - errors: Array<{ - /** - * Document that cause the error - */ - document: Document; - /** - * HTTP error status - */ - status: number; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, @@ -679,44 +552,9 @@ export class DocumentController extends BaseController { mUpsert ( index: string, collection: string, - documents: Array<{ - /** - * Document ID - */ - _id: string; - /** - * Partial content of the document to update - */ - changes: JSONObject; - /** - * Fields to add to the document if it gets created - */ - default: JSONObject - }>, + documents: mUpdateRequest, options: ArgsDocumentControllerMUpsert = {} - ): Promise<{ - /** - * Array of successfully updated documents - */ - successes: Array; - /** - * Array of failed creation - */ - errors: Array<{ - /** - * Document that cause the error - */ - document: Document; - /** - * HTTP error status - */ - status: number; - /** - * Human readable reason - */ - reason: string; - }>; - }> { + ): Promise { const request = { index, collection, diff --git a/src/types/index.ts b/src/types/index.ts index a8f9f7662..ca63244bd 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,3 +15,7 @@ export * from './ProfilePolicy'; export * from './RoleRightsDefinition'; export * from './ArgsDefault'; + +export * from './mRequests'; + +export * from './mResponses'; diff --git a/src/types/mRequests.ts b/src/types/mRequests.ts new file mode 100644 index 000000000..7f6bd55d5 --- /dev/null +++ b/src/types/mRequests.ts @@ -0,0 +1,47 @@ +import { JSONObject } from './JSONObject'; + +export type mCreateRequest = { + /** + * Document unique identifier + */ + _id?: string; + + /** + * Document content + */ + body: JSONObject; +}; + +export type mCreateOrReplaceRequest = { + /** + * Document unique identifier + */ + _id: string; + + /** + * Document content + */ + body: JSONObject; +}; + +export type mReplaceRequest = mCreateOrReplaceRequest; +export type mUpdateRequest = mCreateOrReplaceRequest; + +export type mUpsertRequest = { + /** + * Document unique identifier + */ + _id: string; + + /** + * Document partial changes + */ + changes: JSONObject; + + /** + * Document fields to add to the "update" part if the document is created + */ + default?: JSONObject; +}; + +export type mDeleteRequest = string[]; diff --git a/src/types/mResponses.ts b/src/types/mResponses.ts new file mode 100644 index 000000000..4fb96464b --- /dev/null +++ b/src/types/mResponses.ts @@ -0,0 +1,105 @@ +import { JSONObject } from './JSONObject'; + +type mResponseErrors = Array<{ + /** + * Original document that caused the error + */ + document: { + _id: string; + _source: JSONObject; + }; + + /** + * HTTP error status code + */ + status: number; + + /** + * Human readable reason + */ + reason: string; +}>; + +export type mCreateResponse = { + /** + * Array of succeeded operations + */ + successes: Array<{ + /** + * Document unique identifier + */ + _id: string; + + /** + * Document content + */ + _source: JSONObject; + + /** + * Document version number + */ + _version: number; + + /** + * `true` if document is created + */ + created: boolean; + }>; + + /** + * Arrays of errored operations + */ + errors: mResponseErrors; +}; + +export type mCreateOrReplaceResponse = mCreateResponse; +export type mUpsertResponse = mCreateResponse; + +export type mReplaceResponse = { + /** + * Array of succeeded operations + */ + successes: Array<{ + /** + * Document unique identifier + */ + _id: string; + + /** + * Document content + */ + _source: JSONObject; + + /** + * Document version number + */ + _version: number; + }>; + + /** + * Arrays of errored operations + */ + errors: mResponseErrors; +}; + +export type mUpdateResponse = mReplaceResponse; + +export type mDeleteResponse = { + /** + * IDs of deleted documents + */ + successes: string[]; + + errors: Array<{ + /** + * Document unique identifier + */ + _id: string; + + /** + * Human readable reason + */ + reason: string; + }>; +}; + From b69dc6c726d0434b1296dfdf740b078cc850b264 Mon Sep 17 00:00:00 2001 From: Aschen Date: Fri, 17 Dec 2021 18:35:29 +0100 Subject: [PATCH 2/3] add doc --- doc/7/essentials/events/index.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/7/essentials/events/index.md b/doc/7/essentials/events/index.md index 8e530efa3..1c59ea768 100644 --- a/doc/7/essentials/events/index.md +++ b/doc/7/essentials/events/index.md @@ -12,6 +12,17 @@ An event system allows to be notified when the SDK status changes. These events The API for interacting with events is described by our [KuzzleEventEmitter](/sdk/js/7/core-classes/kuzzle-event-emitter) class documentation. +::: info +You can listen to every events on the SDK by using the events property: + +```js +for (const event of kuzzle.events) { + kuzzle.on(event, (...args) => console.log(event, ...args)); +} +``` + +::: + **Note:** listeners are called in the order of their insertion. # Emitted Events From b14a902c6ed85112af2e54c54dc507daab6ea02d Mon Sep 17 00:00:00 2001 From: Aschen Date: Fri, 17 Dec 2021 18:38:25 +0100 Subject: [PATCH 3/3] fix test --- test/kuzzle/listenersManagement.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/kuzzle/listenersManagement.test.js b/test/kuzzle/listenersManagement.test.js index 45371de83..431ea1ef5 100644 --- a/test/kuzzle/listenersManagement.test.js +++ b/test/kuzzle/listenersManagement.test.js @@ -38,7 +38,7 @@ describe('Kuzzle listeners management', () => { should(function() { kuzzle.addListener('foo', sinon.stub()); - }).throw('[foo] is not a known event. Known events: ' + knownEvents.toString()); + }).throw('[foo] is not a known event. Known events: ' + knownEvents.join(', ')); let i; for (i = 0; i < knownEvents.length; i++) {