Skip to content

Commit 30075df

Browse files
committed
DX-1204: throw on v1 callback shape in 14 method families
1 parent 35d1243 commit 30075df

5 files changed

Lines changed: 90 additions & 14 deletions

File tree

scripts/moduleReport.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { gzip } from 'zlib';
66
import Table from 'cli-table';
77

88
// The maximum size we allow for a minimal useful Realtime bundle (i.e. one that can subscribe to a channel)
9-
const minimalUsefulRealtimeBundleSizeThresholdsKiB = { raw: 106, gzip: 32 };
9+
const minimalUsefulRealtimeBundleSizeThresholdsKiB = { raw: 107, gzip: 33 };
1010

1111
const baseClientNames = ['BaseRest', 'BaseRealtime'];
1212

src/common/lib/client/auth.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,12 @@ class Auth {
254254
*/
255255
async authorize(tokenParams: API.TokenParams | null, authOptions: AuthOptions | null): Promise<API.TokenDetails>;
256256

257-
async authorize(
257+
authorize(...args: any[]): Promise<API.TokenDetails> {
258+
Utils.detectV1Callback(args, 0);
259+
return this._authorizeImpl(args[0], args[1]);
260+
}
261+
262+
private async _authorizeImpl(
258263
tokenParams?: Record<string, any> | null,
259264
authOptions?: AuthOptions | null,
260265
): Promise<API.TokenDetails> {
@@ -390,7 +395,15 @@ class Auth {
390395
*/
391396
async requestToken(tokenParams: API.TokenParams | null, authOptions: AuthOptions): Promise<API.TokenDetails>;
392397

393-
async requestToken(tokenParams?: API.TokenParams | null, authOptions?: AuthOptions): Promise<API.TokenDetails> {
398+
requestToken(...args: any[]): Promise<API.TokenDetails> {
399+
Utils.detectV1Callback(args, 0);
400+
return this._requestTokenImpl(args[0], args[1]);
401+
}
402+
403+
private async _requestTokenImpl(
404+
tokenParams?: API.TokenParams | null,
405+
authOptions?: AuthOptions,
406+
): Promise<API.TokenDetails> {
394407
/* RSA8e: if authOptions passed in, they're used instead of stored, don't merge them */
395408
const resolvedAuthOptions = authOptions || this.authOptions;
396409
const resolvedTokenParams = tokenParams || Utils.copy(this.tokenParams);
@@ -744,7 +757,15 @@ class Auth {
744757
* - timestamp: (optional) the time in ms since the epoch. If none is specified,
745758
* the system will be queried for a time value to use.
746759
*/
747-
async createTokenRequest(tokenParams: API.TokenParams | null, authOptions: any): Promise<API.TokenRequest> {
760+
createTokenRequest(...args: any[]): Promise<API.TokenRequest> {
761+
Utils.detectV1Callback(args, 0);
762+
return this._createTokenRequestImpl(args[0], args[1]);
763+
}
764+
765+
private async _createTokenRequestImpl(
766+
tokenParams: API.TokenParams | null,
767+
authOptions: any,
768+
): Promise<API.TokenRequest> {
748769
/* RSA9h: if authOptions passed in, they're used instead of stored, don't merge them */
749770
authOptions = authOptions || this.authOptions;
750771
tokenParams = tokenParams || Utils.copy<API.TokenParams>(this.tokenParams);

src/common/lib/client/connection.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ConnectionManager from '../transport/connectionmanager';
33
import Logger from '../util/logger';
44
import ConnectionStateChange from './connectionstatechange';
55
import ErrorInfo from '../types/errorinfo';
6+
import * as Utils from '../util/utils';
67
import { NormalisedClientOptions } from '../../types/ClientOptions';
78
import BaseRealtime from './baserealtime';
89
import Platform from 'common/platform';
@@ -46,7 +47,12 @@ class Connection extends EventEmitter {
4647
this.connectionManager.requestState({ state: 'connecting' });
4748
}
4849

49-
async ping(): Promise<number> {
50+
ping(...args: any[]): Promise<number> {
51+
Utils.detectV1Callback(args, 0);
52+
return this._pingImpl();
53+
}
54+
55+
private async _pingImpl(): Promise<number> {
5056
Logger.logAction(this.logger, Logger.LOG_MINOR, 'Connection.ping()', '');
5157
return this.connectionManager.ping();
5258
}

src/common/lib/client/realtimechannel.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,15 @@ class RealtimeChannel extends EventEmitter {
250250
return false;
251251
}
252252

253-
async publish(...args: any[]): Promise<API.PublishResult> {
253+
publish(...args: any[]): Promise<API.PublishResult> {
254+
// Detect a v1-shape trailing callback synchronously, before the async body
255+
// starts — agents pasting v1 patterns need the throw to surface at the call
256+
// site, not as an unobserved Promise rejection.
257+
Utils.detectV1Callback(args, 0);
258+
return this._publishImpl(args);
259+
}
260+
261+
private async _publishImpl(args: any[]): Promise<API.PublishResult> {
254262
const first = args[0],
255263
second = args[1];
256264
let messages: Message[];
@@ -453,7 +461,12 @@ class RealtimeChannel extends EventEmitter {
453461
this.send(msg);
454462
}
455463

456-
async subscribe(...args: unknown[] /* [event], listener */): Promise<ChannelStateChange | null> {
464+
subscribe(...args: unknown[] /* [event], listener */): Promise<ChannelStateChange | null> {
465+
Utils.detectV1Callback(args, 2);
466+
return this._subscribeImpl(args);
467+
}
468+
469+
private async _subscribeImpl(args: unknown[]): Promise<ChannelStateChange | null> {
457470
const [event, listener] = RealtimeChannel.processListenerArgs(args);
458471

459472
if (this.state === 'failed') {
@@ -476,6 +489,7 @@ class RealtimeChannel extends EventEmitter {
476489
}
477490

478491
unsubscribe(...args: unknown[] /* [event], listener */): void {
492+
Utils.detectV1Callback(args, 2);
479493
const [event, listener] = RealtimeChannel.processListenerArgs(args);
480494

481495
// If we either have a filtered listener, a filter or both we need to do additional processing to find the original function(s)
@@ -985,7 +999,12 @@ class RealtimeChannel extends EventEmitter {
985999
}
9861000
}
9871001

988-
history = async function (
1002+
history = function (this: RealtimeChannel, ...args: any[]): Promise<PaginatedResult<Message>> {
1003+
Utils.detectV1Callback(args, 0);
1004+
return this._historyImpl(args[0]);
1005+
} as any;
1006+
1007+
private _historyImpl = async function (
9891008
this: RealtimeChannel,
9901009
params: RealtimeHistoryParams | null,
9911010
): Promise<PaginatedResult<Message>> {

src/common/lib/client/realtimepresence.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,24 @@ class RealtimePresence extends EventEmitter {
5454
this.pendingPresence = [];
5555
}
5656

57-
async enter(data: unknown): Promise<void> {
57+
enter(...args: any[]): Promise<void> {
58+
Utils.detectV1Callback(args, 0);
59+
return this._enterImpl(args[0]);
60+
}
61+
62+
private async _enterImpl(data: unknown): Promise<void> {
5863
if (isAnonymousOrWildcard(this)) {
5964
throw new ErrorInfo('clientId must be specified to enter a presence channel', 40012, 400);
6065
}
6166
return this._enterOrUpdateClient(undefined, undefined, data, 'enter');
6267
}
6368

64-
async update(data: unknown): Promise<void> {
69+
update(...args: any[]): Promise<void> {
70+
Utils.detectV1Callback(args, 0);
71+
return this._updateImpl(args[0]);
72+
}
73+
74+
private async _updateImpl(data: unknown): Promise<void> {
6575
if (isAnonymousOrWildcard(this)) {
6676
throw new ErrorInfo('clientId must be specified to update presence data', 40012, 400);
6777
}
@@ -129,7 +139,12 @@ class RealtimePresence extends EventEmitter {
129139
}
130140
}
131141

132-
async leave(data: unknown): Promise<void> {
142+
leave(...args: any[]): Promise<void> {
143+
Utils.detectV1Callback(args, 0);
144+
return this._leaveImpl(args[0]);
145+
}
146+
147+
private async _leaveImpl(data: unknown): Promise<void> {
133148
if (isAnonymousOrWildcard(this)) {
134149
throw new ErrorInfo('clientId must have been specified to enter or leave a presence channel', 40012, 400);
135150
}
@@ -176,7 +191,12 @@ class RealtimePresence extends EventEmitter {
176191
}
177192
}
178193

179-
async get(params?: RealtimePresenceParams): Promise<PresenceMessage[]> {
194+
get(...args: any[]): Promise<PresenceMessage[]> {
195+
Utils.detectV1Callback(args, 0);
196+
return this._getImpl(args[0]);
197+
}
198+
199+
private async _getImpl(params?: RealtimePresenceParams): Promise<PresenceMessage[]> {
180200
const waitForSync = !params || ('waitForSync' in params ? params.waitForSync : true);
181201

182202
function toMessages(members: PresenceMap): PresenceMessage[] {
@@ -204,7 +224,12 @@ class RealtimePresence extends EventEmitter {
204224
return toMessages(this.members);
205225
}
206226

207-
async history(params: RealtimeHistoryParams | null): Promise<PaginatedResult<PresenceMessage>> {
227+
history(...args: any[]): Promise<PaginatedResult<PresenceMessage>> {
228+
Utils.detectV1Callback(args, 0);
229+
return this._historyImpl(args[0]);
230+
}
231+
232+
private async _historyImpl(params: RealtimeHistoryParams | null): Promise<PaginatedResult<PresenceMessage>> {
208233
Logger.logAction(this.logger, Logger.LOG_MICRO, 'RealtimePresence.history()', 'channel = ' + this.name);
209234
// We fetch this first so that any plugin-not-provided error takes priority over other errors
210235
const restMixin = this.channel.client.rest.presenceMixin;
@@ -407,7 +432,12 @@ class RealtimePresence extends EventEmitter {
407432
});
408433
}
409434

410-
async subscribe(..._args: unknown[] /* [event], listener */): Promise<void> {
435+
subscribe(..._args: unknown[] /* [event], listener */): Promise<void> {
436+
Utils.detectV1Callback(_args, 2);
437+
return this._subscribeImpl(_args);
438+
}
439+
440+
private async _subscribeImpl(_args: unknown[]): Promise<void> {
411441
const args = RealtimeChannel.processListenerArgs(_args);
412442
const event = args[0];
413443
const listener = args[1];

0 commit comments

Comments
 (0)