-
Notifications
You must be signed in to change notification settings - Fork 56
/
private_api_recorder.js
202 lines (194 loc) · 8.51 KB
/
private_api_recorder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
'use strict';
define(['test/support/output_directory_paths'], function (outputDirectoryPaths) {
const privateAPIIdentifiers = [
'call.BufferUtils.areBuffersEqual',
'call.BufferUtils.base64Decode',
'call.BufferUtils.base64Encode',
'call.BufferUtils.hexEncode',
'call.BufferUtils.isBuffer',
'call.BufferUtils.toArrayBuffer',
'call.BufferUtils.utf8Encode',
'call.ConnectionManager.supportedTransports',
'call.Defaults.getHost',
'call.Defaults.getHost',
'call.Defaults.getHosts',
'call.Defaults.getPort',
'call.Defaults.normaliseOptions',
'call.EventEmitter.emit',
'call.Message.decode',
'call.Message.encode',
'call.Platform.Config.push.storage.clear',
'call.Platform.nextTick',
'call.PresenceMessage.fromValues',
'call.ProtocolMessage.setFlag',
'call.Utils.copy',
'call.Utils.getRetryTime',
'call.Utils.inspectError',
'call.Utils.keysArray',
'call.Utils.mixin',
'call.Utils.toQueryString',
'call.auth.getAuthHeaders',
'call.channel.checkPendingState',
'call.channel.processMessage',
'call.channel.requestState',
'call.channel.sendPresence',
'call.channel.sync',
'call.connectionManager.activeProtocol.getTransport',
'call.connectionManager.disconnectAllTransports',
'call.connectionManager.notifyState',
'call.connectionManager.onChannelMessage',
'call.connectionManager.requestState',
'call.connectionManager.send',
'call.filteredSubscriptions.has',
'call.http._getHosts',
'call.http.checkConnectivity',
'call.http.doUri',
'call.msgpack.decode',
'call.msgpack.encode',
'call.presence._myMembers.put',
'call.presence.waitSync',
'call.protocolMessageFromDeserialized',
'call.realtime.baseUri',
'call.rest.baseUri',
'call.rest.http.do',
'call.restChannel._publish',
'call.transport.onProtocolMessage',
'call.transport.send',
'delete.auth.authOptions.requestHeaders',
'deserialize.recoveryKey',
'listen.channel._allChannelChanges.attached',
'listen.channel._allChannelChanges.update',
'listen.connectionManager.connectiondetails',
'listen.connectionManager.transport.active',
'listen.connectionManager.transport.pending',
'listen.transport.disposed',
'new.Crypto.CipherParams', // This is in a bit of a grey area re whether it’s private API. The CipherParams class is indeed part of the public API in the spec, but it’s not clear whether you’re meant to construct one directly, and furthermore the spec doesn’t describe it as being exposed as a property on Crypto.
'pass.clientOption.connectivityCheckUrl', // actually ably-js public API (i.e. it’s in the TypeScript typings) but no other SDK has it and it doesn’t enable ably-js-specific functionality
'pass.clientOption.disableConnectivityCheck', // actually ably-js public API (i.e. it’s in the TypeScript typings) but no other SDK has it and it doesn’t enable ably-js-specific functionality
'pass.clientOption.pushRecipientChannel',
'pass.clientOption.webSocketConnectTimeout',
'pass.clientOption.webSocketSlowTimeout',
'pass.clientOption.wsConnectivityCheckUrl', // actually ably-js public API (i.e. it’s in the TypeScript typings) but no other SDK has it. At the same time it's not entirely clear if websocket connectivity check should be considered an ably-js-specific functionality (as for other params above), so for the time being we consider it as private API
'read.Defaults.version',
'read.EventEmitter.events',
'read.Platform.Config.push',
'read.Realtime._transports',
'read.auth.authOptions.authUrl',
'read.auth.key',
'read.auth.method',
'read.auth.tokenParams.version',
'read.channel.channelOptions',
'read.channel.channelOptions.cipher',
'read.connectionManager.activeProtocol',
'read.connectionManager.activeProtocol.transport',
'read.connectionManager.baseTransport',
'read.connectionManager.connectionId',
'read.connectionManager.connectionId',
'read.connectionManager.connectionStateTtl',
'read.connectionManager.httpHosts',
'read.connectionManager.msgSerial',
'read.connectionManager.options',
'read.connectionManager.options.timeouts.httpMaxRetryDuration',
'read.connectionManager.options.timeouts.httpRequestTimeout',
'read.connectionManager.pendingTransport',
'read.connectionManager.queuedMessages.messages',
'read.connectionManager.states.disconnected.retryDelay',
'read.connectionManager.states.suspended.retryDelay',
'read.connectionManager.webSocketTransportAvailable',
'read.realtime.options',
'read.realtime.options.key',
'read.realtime.options.maxMessageSize',
'read.realtime.options.realtimeHost',
'read.realtime.options.token',
'read.rest._currentFallback',
'read.rest._currentFallback.host',
'read.rest._currentFallback.validUntil',
'read.rest.options.key',
'read.rest.options.realtimeHost',
'read.rest.options.token',
'read.rest.serverTimeOffset',
'read.transport.params.mode',
'read.transport.recvRequest.recvUri',
'read.transport.uri',
'replace.channel.attachImpl',
'replace.channel.processMessage',
'replace.channel.sendMessage',
'replace.channel.sendPresence',
'replace.connectionManager.onChannelMessage',
'replace.connectionManager.send',
'replace.connectionManager.tryATransport',
'replace.http.doUri',
'replace.rest.http.do',
'replace.rest.time',
'replace.restChannel._publish',
'replace.transport.onProtocolMessage',
'replace.transport.send',
'serialize.recoveryKey',
'write.Defaults.ENVIRONMENT',
'write.Defaults.wsConnectivityCheckUrl',
'write.Platform.Config.push', // This implies using a mock implementation of the internal IPlatformPushConfig interface. Our mock (in push_channel_transport.js) then interacts with internal objects and private APIs of public objects to implement this interface; I haven’t added annotations for that private API usage, since there wasn’t an easy way to pass test context information into the mock. I think that for now we can just say that if we wanted to get rid of this private API usage, then we’d need to remove this mock entirely.
'write.auth.authOptions.requestHeaders',
'write.auth.key',
'write.auth.tokenDetails.token',
'write.channel._lastPayload',
'write.channel.state',
'write.connectionManager.connectionDetails.maxMessageSize',
'write.connectionManager.connectionId',
'write.connectionManager.connectionKey',
'write.connectionManager.lastActivity',
'write.connectionManager.msgSerial',
'write.connectionManager.wsHosts',
'write.realtime.options.realtimeHost',
'write.realtime.options.wsConnectivityCheckUrl',
'write.realtime.options.timeouts.realtimeRequestTimeout',
'write.rest._currentFallback.validUntil',
];
class PrivateApiRecorder {
privateAPIUsages = [];
/**
* Creates a recording context for the current Mocha test case.
*
* @param context A description of the context for which the calls will be recorded.
*/
createContext(context) {
if (!context) {
throw new Error('No description passed to createContext');
}
const loggingDescription = JSON.stringify(context);
return {
record: (privateAPIIdentifier) => {
if (privateAPIIdentifiers.indexOf(privateAPIIdentifier) == -1) {
throw new Error(`(${loggingDescription}) Recorded unknown private API: ${privateAPIIdentifier}`);
}
this.privateAPIUsages.push({ context, privateAPIIdentifier });
},
recordTestStart: () => {
this.privateAPIUsages.push({ context, privateAPIIdentifier: null });
},
};
}
dump() {
if (isBrowser) {
window.dispatchEvent(new CustomEvent('privateApiUsageData', { detail: this.privateAPIUsages }));
} else {
try {
const fs = require('fs');
const path = require('path');
if (!fs.existsSync(outputDirectoryPaths.privateApiUsage)) {
fs.mkdirSync(outputDirectoryPaths.privateApiUsage);
}
const filename = `node-${process.version.split('.')[0]}.json`;
fs.writeFileSync(
path.join(outputDirectoryPaths.privateApiUsage, filename),
JSON.stringify(this.privateAPIUsages),
{ encoding: 'utf-8' },
);
} catch (err) {
console.log('Failed to write private API usage data: ', err);
throw err;
}
}
}
}
return (module.exports = new PrivateApiRecorder());
});