chore: pass validator into validator context (#34810)
This commit is contained in:
parent
024a52821a
commit
3606a434fe
|
|
@ -141,6 +141,14 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _validatorToWireContext(): ValidatorContext {
|
||||||
|
return {
|
||||||
|
tChannelImpl: tChannelImplToWire,
|
||||||
|
binary: this._connection.rawBuffers() ? 'buffer' : 'toBase64',
|
||||||
|
isUnderTest: () => this._platform.isUnderTest(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private _createChannel(base: Object): T {
|
private _createChannel(base: Object): T {
|
||||||
const channel = new Proxy(base, {
|
const channel = new Proxy(base, {
|
||||||
get: (obj: any, prop: string | symbol) => {
|
get: (obj: any, prop: string | symbol) => {
|
||||||
|
|
@ -149,7 +157,7 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
|
||||||
if (validator) {
|
if (validator) {
|
||||||
return async (params: any) => {
|
return async (params: any) => {
|
||||||
return await this._wrapApiCall(async apiZone => {
|
return await this._wrapApiCall(async apiZone => {
|
||||||
const validatedParams = validator(params, '', { tChannelImpl: tChannelImplToWire, binary: this._connection.rawBuffers() ? 'buffer' : 'toBase64' });
|
const validatedParams = validator(params, '', this._validatorToWireContext());
|
||||||
if (!apiZone.isInternal && !apiZone.reported) {
|
if (!apiZone.isInternal && !apiZone.reported) {
|
||||||
// Reporting/tracing/logging this api call for the first time.
|
// Reporting/tracing/logging this api call for the first time.
|
||||||
apiZone.params = params;
|
apiZone.params = params;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,10 @@
|
||||||
|
|
||||||
import { Connection } from './connection';
|
import { Connection } from './connection';
|
||||||
import { setPlatformForSelectors } from './selectors';
|
import { setPlatformForSelectors } from './selectors';
|
||||||
import { setIsUnderTestForValidator } from '../protocol/validatorPrimitives';
|
|
||||||
|
|
||||||
import type { Platform } from './platform';
|
import type { Platform } from './platform';
|
||||||
|
|
||||||
export function createConnectionFactory(platform: Platform): () => Connection {
|
export function createConnectionFactory(platform: Platform): () => Connection {
|
||||||
setPlatformForSelectors(platform);
|
setPlatformForSelectors(platform);
|
||||||
setIsUnderTestForValidator(() => platform.isUnderTest());
|
|
||||||
return () => new Connection(platform);
|
return () => new Connection(platform);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,14 @@ export class Connection extends EventEmitter {
|
||||||
return await new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject, apiName, type, method }));
|
return await new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject, apiName, type, method }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _validatorFromWireContext(): ValidatorContext {
|
||||||
|
return {
|
||||||
|
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||||
|
binary: this._rawBuffers ? 'buffer' : 'fromBase64',
|
||||||
|
isUnderTest: () => this._platform.isUnderTest(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(message: object) {
|
dispatch(message: object) {
|
||||||
if (this._closedError)
|
if (this._closedError)
|
||||||
return;
|
return;
|
||||||
|
|
@ -166,7 +174,7 @@ export class Connection extends EventEmitter {
|
||||||
callback.reject(parsedError);
|
callback.reject(parsedError);
|
||||||
} else {
|
} else {
|
||||||
const validator = findValidator(callback.type, callback.method, 'Result');
|
const validator = findValidator(callback.type, callback.method, 'Result');
|
||||||
callback.resolve(validator(result, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this._rawBuffers ? 'buffer' : 'fromBase64' }));
|
callback.resolve(validator(result, '', this._validatorFromWireContext()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +204,7 @@ export class Connection extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
const validator = findValidator(object._type, method, 'Event');
|
const validator = findValidator(object._type, method, 'Event');
|
||||||
(object._channel as any).emit(method, validator(params, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this._rawBuffers ? 'buffer' : 'fromBase64' }));
|
(object._channel as any).emit(method, validator(params, '', this._validatorFromWireContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
close(cause?: string) {
|
close(cause?: string) {
|
||||||
|
|
@ -227,7 +235,7 @@ export class Connection extends EventEmitter {
|
||||||
throw new Error(`Cannot find parent object ${parentGuid} to create ${guid}`);
|
throw new Error(`Cannot find parent object ${parentGuid} to create ${guid}`);
|
||||||
let result: ChannelOwner<any>;
|
let result: ChannelOwner<any>;
|
||||||
const validator = findValidator(type, '', 'Initializer');
|
const validator = findValidator(type, '', 'Initializer');
|
||||||
initializer = validator(initializer, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this._rawBuffers ? 'buffer' : 'fromBase64' });
|
initializer = validator(initializer, '', this._validatorFromWireContext());
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'Android':
|
case 'Android':
|
||||||
result = new Android(parent, type, guid, initializer);
|
result = new Android(parent, type, guid, initializer);
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let isUnderTest = () => false;
|
|
||||||
|
|
||||||
export function setIsUnderTestForValidator(getter: () => boolean) {
|
|
||||||
isUnderTest = getter;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ValidationError extends Error {}
|
export class ValidationError extends Error {}
|
||||||
export type Validator = (arg: any, path: string, context: ValidatorContext) => any;
|
export type Validator = (arg: any, path: string, context: ValidatorContext) => any;
|
||||||
export type ValidatorContext = {
|
export type ValidatorContext = {
|
||||||
tChannelImpl: (names: '*' | string[], arg: any, path: string, context: ValidatorContext) => any,
|
tChannelImpl: (names: '*' | string[], arg: any, path: string, context: ValidatorContext) => any;
|
||||||
binary: 'toBase64' | 'fromBase64' | 'buffer',
|
binary: 'toBase64' | 'fromBase64' | 'buffer';
|
||||||
|
isUnderTest: () => boolean;
|
||||||
};
|
};
|
||||||
export const scheme: { [key: string]: Validator } = {};
|
export const scheme: { [key: string]: Validator } = {};
|
||||||
|
|
||||||
|
|
@ -117,7 +112,7 @@ export const tObject = (s: { [key: string]: Validator }): Validator => {
|
||||||
if (!Object.is(value, undefined))
|
if (!Object.is(value, undefined))
|
||||||
result[key] = value;
|
result[key] = value;
|
||||||
}
|
}
|
||||||
if (isUnderTest()) {
|
if (context.isUnderTest()) {
|
||||||
for (const [key, value] of Object.entries(arg)) {
|
for (const [key, value] of Object.entries(arg)) {
|
||||||
if (key.startsWith('__testHook'))
|
if (key.startsWith('__testHook'))
|
||||||
result[key] = value;
|
result[key] = value;
|
||||||
|
|
|
||||||
|
|
@ -200,13 +200,13 @@ export class DispatcherConnection {
|
||||||
|
|
||||||
sendEvent(dispatcher: DispatcherScope, event: string, params: any) {
|
sendEvent(dispatcher: DispatcherScope, event: string, params: any) {
|
||||||
const validator = findValidator(dispatcher._type, event, 'Event');
|
const validator = findValidator(dispatcher._type, event, 'Event');
|
||||||
params = validator(params, '', { tChannelImpl: this._tChannelImplToWire.bind(this), binary: this._isLocal ? 'buffer' : 'toBase64' });
|
params = validator(params, '', this._validatorToWireContext());
|
||||||
this.onmessage({ guid: dispatcher._guid, method: event, params });
|
this.onmessage({ guid: dispatcher._guid, method: event, params });
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCreate(parent: DispatcherScope, type: string, guid: string, initializer: any) {
|
sendCreate(parent: DispatcherScope, type: string, guid: string, initializer: any) {
|
||||||
const validator = findValidator(type, '', 'Initializer');
|
const validator = findValidator(type, '', 'Initializer');
|
||||||
initializer = validator(initializer, '', { tChannelImpl: this._tChannelImplToWire.bind(this), binary: this._isLocal ? 'buffer' : 'toBase64' });
|
initializer = validator(initializer, '', this._validatorToWireContext());
|
||||||
this.onmessage({ guid: parent._guid, method: '__create__', params: { type, initializer, guid } });
|
this.onmessage({ guid: parent._guid, method: '__create__', params: { type, initializer, guid } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,6 +218,22 @@ export class DispatcherConnection {
|
||||||
this.onmessage({ guid: dispatcher._guid, method: '__dispose__', params: { reason } });
|
this.onmessage({ guid: dispatcher._guid, method: '__dispose__', params: { reason } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _validatorToWireContext(): ValidatorContext {
|
||||||
|
return {
|
||||||
|
tChannelImpl: this._tChannelImplToWire.bind(this),
|
||||||
|
binary: this._isLocal ? 'buffer' : 'toBase64',
|
||||||
|
isUnderTest,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private _validatorFromWireContext(): ValidatorContext {
|
||||||
|
return {
|
||||||
|
tChannelImpl: this._tChannelImplFromWire.bind(this),
|
||||||
|
binary: this._isLocal ? 'buffer' : 'fromBase64',
|
||||||
|
isUnderTest,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {
|
private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {
|
||||||
if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {
|
if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {
|
||||||
const guid = arg.guid;
|
const guid = arg.guid;
|
||||||
|
|
@ -279,8 +295,9 @@ export class DispatcherConnection {
|
||||||
let validMetadata: channels.Metadata;
|
let validMetadata: channels.Metadata;
|
||||||
try {
|
try {
|
||||||
const validator = findValidator(dispatcher._type, method, 'Params');
|
const validator = findValidator(dispatcher._type, method, 'Params');
|
||||||
validParams = validator(params, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this._isLocal ? 'buffer' : 'fromBase64' });
|
const validatorContext = this._validatorFromWireContext();
|
||||||
validMetadata = metadataValidator(metadata, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this._isLocal ? 'buffer' : 'fromBase64' });
|
validParams = validator(params, '', validatorContext);
|
||||||
|
validMetadata = metadataValidator(metadata, '', validatorContext);
|
||||||
if (typeof (dispatcher as any)[method] !== 'function')
|
if (typeof (dispatcher as any)[method] !== 'function')
|
||||||
throw new Error(`Mismatching dispatcher: "${dispatcher._type}" does not implement "${method}"`);
|
throw new Error(`Mismatching dispatcher: "${dispatcher._type}" does not implement "${method}"`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -338,7 +355,7 @@ export class DispatcherConnection {
|
||||||
try {
|
try {
|
||||||
const result = await dispatcher._handleCommand(callMetadata, method, validParams);
|
const result = await dispatcher._handleCommand(callMetadata, method, validParams);
|
||||||
const validator = findValidator(dispatcher._type, method, 'Result');
|
const validator = findValidator(dispatcher._type, method, 'Result');
|
||||||
response.result = validator(result, '', { tChannelImpl: this._tChannelImplToWire.bind(this), binary: this._isLocal ? 'buffer' : 'toBase64' });
|
response.result = validator(result, '', this._validatorToWireContext());
|
||||||
callMetadata.result = result;
|
callMetadata.result = result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isTargetClosedError(e) && sdkObject) {
|
if (isTargetClosedError(e) && sdkObject) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import EventEmitter from 'events';
|
||||||
|
|
||||||
import * as socks from './utils/socksProxy';
|
import * as socks from './utils/socksProxy';
|
||||||
import { ValidationError, findValidator } from '../protocol/validator';
|
import { ValidationError, findValidator } from '../protocol/validator';
|
||||||
|
import { isUnderTest } from './utils/debug';
|
||||||
|
|
||||||
import type { WebSocketTransport } from './transport';
|
import type { WebSocketTransport } from './transport';
|
||||||
import type { ValidatorContext } from '../protocol/validator';
|
import type { ValidatorContext } from '../protocol/validator';
|
||||||
|
|
@ -42,7 +43,7 @@ export class SocksInterceptor {
|
||||||
const id = --lastId;
|
const id = --lastId;
|
||||||
this._ids.add(id);
|
this._ids.add(id);
|
||||||
const validator = findValidator('SocksSupport', prop, 'Params');
|
const validator = findValidator('SocksSupport', prop, 'Params');
|
||||||
params = validator(params, '', { tChannelImpl: tChannelForSocks, binary: 'toBase64' });
|
params = validator(params, '', { tChannelImpl: tChannelForSocks, binary: 'toBase64', isUnderTest });
|
||||||
transport.send({ id, guid: this._socksSupportObjectGuid, method: prop, params, metadata: { stack: [], apiName: '', internal: true } } as any);
|
transport.send({ id, guid: this._socksSupportObjectGuid, method: prop, params, metadata: { stack: [], apiName: '', internal: true } } as any);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +75,7 @@ export class SocksInterceptor {
|
||||||
}
|
}
|
||||||
if (this._socksSupportObjectGuid && message.guid === this._socksSupportObjectGuid) {
|
if (this._socksSupportObjectGuid && message.guid === this._socksSupportObjectGuid) {
|
||||||
const validator = findValidator('SocksSupport', message.method, 'Event');
|
const validator = findValidator('SocksSupport', message.method, 'Event');
|
||||||
const params = validator(message.params, '', { tChannelImpl: tChannelForSocks, binary: 'fromBase64' });
|
const params = validator(message.params, '', { tChannelImpl: tChannelForSocks, binary: 'fromBase64', isUnderTest });
|
||||||
this._channel.emit(message.method, params);
|
this._channel.emit(message.method, params);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue