Skip to content

Commit 2a26de3

Browse files
nbbeekendurran
andauthored
feat(NODE-5188): add alternative runtime detection to client metadata (#3636)
Co-authored-by: Durran Jordan <durran@gmail.com>
1 parent cc7c75a commit 2a26de3

File tree

2 files changed

+129
-5
lines changed

2 files changed

+129
-5
lines changed

src/cmap/handshake/client_metadata.ts

+41-5
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
116116
);
117117
}
118118

119-
const platformInfo =
120-
platform.length > 0
121-
? `Node.js ${process.version}, ${os.endianness()}|${platform}`
122-
: `Node.js ${process.version}, ${os.endianness()}`;
119+
let runtimeInfo = getRuntimeInfo();
120+
if (platform.length > 0) {
121+
runtimeInfo = `${runtimeInfo}|${platform}`;
122+
}
123123

124-
if (!metadataDocument.ifItFitsItSits('platform', platformInfo)) {
124+
if (!metadataDocument.ifItFitsItSits('platform', runtimeInfo)) {
125125
throw new MongoInvalidArgumentError(
126126
'Unable to include driverInfo platform, metadata cannot exceed 512 bytes'
127127
);
@@ -234,3 +234,39 @@ export function getFAASEnv(): Map<string, string | Int32> | null {
234234

235235
return null;
236236
}
237+
238+
/**
239+
* @internal
240+
* This type represents the global Deno object and the minimal type contract we expect it to satisfy.
241+
*/
242+
declare const Deno: { version?: { deno?: string } } | undefined;
243+
244+
/**
245+
* @internal
246+
* This type represents the global Bun object and the minimal type contract we expect it to satisfy.
247+
*/
248+
declare const Bun: { (): void; version?: string } | undefined;
249+
250+
/**
251+
* @internal
252+
* Get current JavaScript runtime platform
253+
*
254+
* NOTE: The version information fetching is intentionally written defensively
255+
* to avoid having a released driver version that becomes incompatible
256+
* with a future change to these global objects.
257+
*/
258+
function getRuntimeInfo(): string {
259+
if ('Deno' in globalThis) {
260+
const version = typeof Deno?.version?.deno === 'string' ? Deno?.version?.deno : '0.0.0-unknown';
261+
262+
return `Deno v${version}, ${os.endianness()}`;
263+
}
264+
265+
if ('Bun' in globalThis) {
266+
const version = typeof Bun?.version === 'string' ? Bun?.version : '0.0.0-unknown';
267+
268+
return `Bun v${version}, ${os.endianness()}`;
269+
}
270+
271+
return `Node.js ${process.version}, ${os.endianness()}`;
272+
}

test/unit/cmap/handshake/client_metadata.test.ts

+88
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,94 @@ describe('client metadata module', () => {
289289
});
290290
});
291291
});
292+
293+
context('when globalThis indicates alternative runtime', () => {
294+
context('deno', () => {
295+
afterEach(() => {
296+
expect(delete globalThis.Deno, 'failed to delete Deno global').to.be.true;
297+
});
298+
299+
it('sets platform to Deno', () => {
300+
globalThis.Deno = { version: { deno: '1.2.3' } };
301+
const metadata = makeClientMetadata({ driverInfo: {} });
302+
expect(metadata.platform).to.equal('Deno v1.2.3, LE');
303+
});
304+
305+
it('sets platform to Deno with driverInfo.platform', () => {
306+
globalThis.Deno = { version: { deno: '1.2.3' } };
307+
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
308+
expect(metadata.platform).to.equal('Deno v1.2.3, LE|myPlatform');
309+
});
310+
311+
it('ignores version if Deno.version.deno is not a string', () => {
312+
globalThis.Deno = { version: { deno: 1 } };
313+
const metadata = makeClientMetadata({ driverInfo: {} });
314+
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
315+
});
316+
317+
it('ignores version if Deno.version does not have a deno property', () => {
318+
globalThis.Deno = { version: { somethingElse: '1.2.3' } };
319+
const metadata = makeClientMetadata({ driverInfo: {} });
320+
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
321+
});
322+
323+
it('ignores version if Deno.version is null', () => {
324+
globalThis.Deno = { version: null };
325+
const metadata = makeClientMetadata({ driverInfo: {} });
326+
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
327+
});
328+
329+
it('ignores version if Deno is nullish', () => {
330+
globalThis.Deno = null;
331+
const metadata = makeClientMetadata({ driverInfo: {} });
332+
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
333+
});
334+
});
335+
336+
context('bun', () => {
337+
afterEach(() => {
338+
expect(delete globalThis.Bun, 'failed to delete Bun global').to.be.true;
339+
});
340+
341+
it('sets platform to Bun', () => {
342+
globalThis.Bun = class {
343+
static version = '1.2.3';
344+
};
345+
const metadata = makeClientMetadata({ driverInfo: {} });
346+
expect(metadata.platform).to.equal('Bun v1.2.3, LE');
347+
});
348+
349+
it('sets platform to Bun with driverInfo.platform', () => {
350+
globalThis.Bun = class {
351+
static version = '1.2.3';
352+
};
353+
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
354+
expect(metadata.platform).to.equal('Bun v1.2.3, LE|myPlatform');
355+
});
356+
357+
it('ignores version if Bun.version is not a string', () => {
358+
globalThis.Bun = class {
359+
static version = 1;
360+
};
361+
const metadata = makeClientMetadata({ driverInfo: {} });
362+
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE');
363+
});
364+
365+
it('ignores version if Bun.version is not a string and sets driverInfo.platform', () => {
366+
globalThis.Bun = class {
367+
static version = 1;
368+
};
369+
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
370+
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE|myPlatform');
371+
});
372+
373+
it('ignores version if Bun is nullish', () => {
374+
globalThis.Bun = null;
375+
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
376+
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE|myPlatform');
377+
});
378+
});
379+
});
292380
});
293381

294382
describe('FAAS metadata application to handshake', () => {

0 commit comments

Comments
 (0)