Skip to content

Commit 690256c

Browse files
authored
Merge pull request #3 from bigmontz/bolt-agent
Implements BoltAgent as structure
2 parents d00a4a1 + 4a8e3e4 commit 690256c

File tree

16 files changed

+460
-102
lines changed

16 files changed

+460
-102
lines changed

packages/bolt-connection/src/bolt/request-message.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,21 @@ export default class RequestMessage {
200200
* @return {RequestMessage} new HELLO message.
201201
*/
202202
static hello5x3 (userAgent, boltAgent, notificationFilter = null, routing = null) {
203-
const metadata = { bolt_agent: boltAgent }
203+
const metadata = { }
204204

205205
if (userAgent) {
206206
metadata.user_agent = userAgent
207207
}
208208

209+
if (boltAgent) {
210+
metadata.bolt_agent = {
211+
product: boltAgent.product,
212+
platform: boltAgent.platform,
213+
language: boltAgent.language,
214+
language_details: boltAgent.languageDetails
215+
}
216+
}
217+
209218
if (notificationFilter) {
210219
if (notificationFilter.minimumSeverityLevel) {
211220
metadata.notifications_minimum_severity = notificationFilter.minimumSeverityLevel

packages/bolt-connection/test/bolt/bolt-protocol-v5x3.test.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,11 @@ describe('#unit BoltProtocolV5x3', () => {
268268
utils.spyProtocolWrite(protocol)
269269

270270
const clientName = 'js-driver/1.2.3'
271-
const boltAgent = 'js-driver/1.2.3 (bolt agent)'
271+
const boltAgent = {
272+
product: 'neo4j-javascript/5.6',
273+
platform: 'netbsd 1.1.1; Some arch',
274+
languageDetails: 'Node/16.0.1 (v8 1.7.0)'
275+
}
272276
const authToken = { username: 'neo4j', password: 'secret' }
273277

274278
const observer = protocol.initialize({ userAgent: clientName, boltAgent: boltAgent, authToken })
@@ -306,14 +310,18 @@ describe('#unit BoltProtocolV5x3', () => {
306310
const protocol = new BoltProtocolV5x3(recorder, null, false)
307311
utils.spyProtocolWrite(protocol)
308312

309-
const clientName = 'js-driver/1.2.3'
313+
const boltAgent = {
314+
product: 'neo4j-javascript/5.6',
315+
platform: 'netbsd 1.1.1; Some arch',
316+
languageDetails: 'Node/16.0.1 (v8 1.7.0)'
317+
}
310318
const authToken = { username: 'neo4j', password: 'secret' }
311319

312-
const observer = protocol.initialize({ userAgent, boltAgent: clientName, authToken })
320+
const observer = protocol.initialize({ userAgent, boltAgent, authToken })
313321

314322
protocol.verifyMessageCount(2)
315323
expect(protocol.messages[0]).toBeMessage(
316-
RequestMessage.hello5x3(userAgent, clientName)
324+
RequestMessage.hello5x3(userAgent, boltAgent)
317325
)
318326
expect(protocol.messages[1]).toBeMessage(
319327
RequestMessage.logon(authToken)

packages/bolt-connection/test/bolt/request-message.test.js

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -531,22 +531,125 @@ describe('#unit RequestMessage', () => {
531531
)
532532
})
533533
})
534+
})
534535

535-
function notificationFilterFixtures () {
536-
return notificationFilterBehaviour.notificationFilterFixture()
537-
.map(notificationFilter => {
538-
const expectedNotificationFilter = {}
539-
if (notificationFilter) {
540-
if (notificationFilter.minimumSeverityLevel) {
541-
expectedNotificationFilter.notifications_minimum_severity = notificationFilter.minimumSeverityLevel
542-
}
543-
544-
if (notificationFilter.disabledCategories) {
545-
expectedNotificationFilter.notifications_disabled_categories = notificationFilter.disabledCategories
546-
}
547-
}
548-
return [notificationFilter, expectedNotificationFilter]
549-
})
550-
}
536+
describe('Bolt5.3', () => {
537+
it('should create HELLO with NodeJS Bolt Agent', () => {
538+
const userAgent = 'my-driver/1.0.2'
539+
const boltAgent = {
540+
product: 'neo4j-javascript/5.6',
541+
platform: 'netbsd 1.1.1; Some arch',
542+
languageDetails: 'Node/16.0.1 (v8 1.7.0)'
543+
}
544+
545+
const expectedFields = {
546+
user_agent: userAgent,
547+
bolt_agent: {
548+
product: 'neo4j-javascript/5.6',
549+
platform: 'netbsd 1.1.1; Some arch',
550+
language_details: 'Node/16.0.1 (v8 1.7.0)'
551+
}
552+
}
553+
554+
const message = RequestMessage.hello5x3(userAgent, boltAgent)
555+
556+
expect(message.signature).toEqual(0x01)
557+
expect(message.fields).toEqual([
558+
expectedFields
559+
])
560+
expect(message.toString()).toEqual(
561+
`HELLO ${json.stringify(expectedFields)}`
562+
)
563+
})
564+
565+
it('should create HELLO with Browser Bolt Agent', () => {
566+
const userAgent = 'my-driver/1.0.2'
567+
568+
const boltAgent = {
569+
product: 'neo4j-javascript/5.3',
570+
platform: 'Macintosh; Intel Mac OS X 10_15_7'
571+
}
572+
573+
const expectedFields = {
574+
user_agent: userAgent,
575+
bolt_agent: {
576+
product: 'neo4j-javascript/5.3',
577+
platform: 'Macintosh; Intel Mac OS X 10_15_7'
578+
}
579+
}
580+
581+
const message = RequestMessage.hello5x3(userAgent, boltAgent)
582+
583+
expect(message.signature).toEqual(0x01)
584+
expect(message.fields).toEqual([
585+
expectedFields
586+
])
587+
expect(message.toString()).toEqual(
588+
`HELLO ${json.stringify(expectedFields)}`
589+
)
590+
})
591+
592+
it('should create HELLO with Deno Bolt Agent', () => {
593+
const userAgent = 'my-driver/1.0.2'
594+
595+
const boltAgent = {
596+
product: 'neo4j-javascript/5.3',
597+
platform: 'macos 14.1; myArch',
598+
languageDetails: 'Deno/1.19.1 (v8 8.1.39)'
599+
}
600+
601+
const expectedFields = {
602+
user_agent: userAgent,
603+
bolt_agent: {
604+
product: 'neo4j-javascript/5.3',
605+
platform: 'macos 14.1; myArch',
606+
language_details: 'Deno/1.19.1 (v8 8.1.39)'
607+
}
608+
}
609+
610+
const message = RequestMessage.hello5x3(userAgent, boltAgent)
611+
612+
expect(message.signature).toEqual(0x01)
613+
expect(message.fields).toEqual([
614+
expectedFields
615+
])
616+
expect(message.toString()).toEqual(
617+
`HELLO ${json.stringify(expectedFields)}`
618+
)
619+
})
620+
621+
it.each(
622+
notificationFilterFixtures()
623+
)('should create HELLO message where notificationFilters=%o', (notificationFilter, expectedNotificationFilter) => {
624+
const userAgent = 'my-driver/1.0.2'
625+
const message = RequestMessage.hello5x3(userAgent, undefined, notificationFilter)
626+
627+
const expectedFields = { user_agent: userAgent, ...expectedNotificationFilter }
628+
629+
expect(message.signature).toEqual(0x01)
630+
expect(message.fields).toEqual([
631+
expectedFields
632+
])
633+
expect(message.toString()).toEqual(
634+
`HELLO ${json.stringify(expectedFields)}`
635+
)
636+
})
551637
})
638+
639+
function notificationFilterFixtures () {
640+
return notificationFilterBehaviour.notificationFilterFixture()
641+
.map(notificationFilter => {
642+
const expectedNotificationFilter = {}
643+
if (notificationFilter) {
644+
if (notificationFilter.minimumSeverityLevel) {
645+
expectedNotificationFilter.notifications_minimum_severity = notificationFilter.minimumSeverityLevel
646+
}
647+
648+
if (notificationFilter.disabledCategories) {
649+
expectedNotificationFilter.notifications_disabled_categories = notificationFilter.disabledCategories
650+
}
651+
}
652+
return [notificationFilter, expectedNotificationFilter]
653+
})
654+
}
552655
})

packages/core/src/internal/bolt-agent/browser/bolt-agent.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,35 @@
1717
* limitations under the License.
1818
*/
1919
/* eslint-disable */
20-
// @ts-ignore: browser code so must be skipped by ts
21-
export function fromVersion (version: string, windowProvider = () => window): string {
22-
// @ts-ignore: browser code so must be skipped by ts
23-
const APP_VERSION = windowProvider().navigator.appVersion
20+
21+
import { BoltAgent } from "../../../types";
22+
23+
interface SystemInfo {
24+
appVersion: string
25+
}
26+
27+
/**
28+
* Constructs a BoltAgent structure from a given product version.
29+
*
30+
* @param {string} version The product version
31+
* @param {function():SystemInfo} getSystemInfo Parameter used of inject system information and mock calls to the APIs.
32+
* @returns {BoltAgent} The bolt agent
33+
*/
34+
export function fromVersion (
35+
version: string,
36+
getSystemInfo: () => SystemInfo = () => ({
37+
// @ts-ignore: browser code so must be skipped by ts
38+
get appVersion(): window.navigator.appVersion
39+
})
40+
): BoltAgent {
41+
const systemInfo = getSystemInfo()
2442

2543
//APP_VERSION looks like 5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
26-
const OS = APP_VERSION.split("(")[1].split(")")[0];
44+
const OS = systemInfo.appVersion.split("(")[1].split(")")[0];
2745

28-
return `neo4j-javascript/${version} (${OS})`
46+
return {
47+
product: `neo4j-javascript/${version}`,
48+
platform: OS
49+
}
2950
}
3051
/* eslint-enable */

packages/core/src/internal/bolt-agent/deno/bolt-agent.ts

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,49 @@
1717
* limitations under the License.
1818
*/
1919

20+
import { BoltAgent } from '../../../types.ts'
21+
22+
export interface SystemInfo {
23+
hostArch: string
24+
denoVersion: string
25+
v8Version: string
26+
osVersion: string
27+
osRelease: string
28+
}
29+
30+
/**
31+
* Constructs a BoltAgent structure from a given product version.
32+
*
33+
* @param {string} version The product version
34+
* @param {function():SystemInfo} getSystemInfo Parameter used of inject system information and mock calls to the APIs.
35+
* @returns {BoltAgent} The bolt agent
36+
*/
2037
/* eslint-disable */
21-
export function fromVersion (version: string): string {
22-
//@ts-ignore
23-
const HOST_ARCH = Deno.build.arch
24-
//@ts-ignore
25-
const DENO_VERSION = `Deno/${Deno.version.deno}`
26-
//@ts-ignore
27-
const NODE_V8_VERSION = Deno.version.v8
28-
//@ts-ignore
29-
const OS_NAME_VERSION = `${Deno.build.os} ${Deno.osRelease ? Deno.osRelease() : ''}`.trim()
38+
export function fromVersion (
39+
version: string,
40+
getSystemInfo: () => SystemInfo = () => ({
41+
//@ts-ignore
42+
hostArch: Deno.build.arch,
43+
//@ts-ignore
44+
denoVersion: Deno.version.deno,
45+
//@ts-ignore:
46+
v8Version: Deno.version.v8,
47+
//@ts-ignore
48+
osVersion: Deno.build.os,
49+
get osRelease() {
50+
//@ts-ignore
51+
return Deno.osRelease ? Deno.osRelease() : ''
52+
}
53+
})
54+
): BoltAgent {
55+
const systemInfo = getSystemInfo()
56+
const DENO_VERSION = `Deno/${systemInfo.denoVersion}`
57+
const OS_NAME_VERSION = `${systemInfo.osVersion} ${systemInfo.osRelease}`.trim()
3058

31-
return `neo4j-javascript/${version} (${OS_NAME_VERSION}; ${HOST_ARCH}) ${DENO_VERSION} (v8 ${NODE_V8_VERSION})`
59+
return {
60+
product: `neo4j-javascript/${version}`,
61+
platform: `${OS_NAME_VERSION}; ${systemInfo.hostArch}`,
62+
languageDetails: `${DENO_VERSION} (v8 ${systemInfo.v8Version})`
63+
}
3264
}
3365
/* eslint-enable */

packages/core/src/internal/bolt-agent/node/bolt-agent.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,49 @@
1616
* See the License for the specific language governing permissions and
1717
* limitations under the License.
1818
*/
19-
import * as os from 'os'
19+
import { platform, release } from 'os'
20+
import { BoltAgent } from '../../../types'
2021

21-
export function fromVersion (version: string): string {
22-
const HOST_ARCH = process.config.variables.host_arch
23-
const NODE_VERSION = 'Node/' + process.versions.node
24-
const NODE_V8_VERSION = process.versions.v8
25-
const OS_NAME_VERSION = `${os.platform()} ${os.release()}`
22+
interface SystemInfo {
23+
hostArch: string
24+
nodeVersion: string
25+
v8Version: string
26+
platform: NodeJS.Platform
27+
release: string
28+
}
29+
30+
/**
31+
* Constructs a BoltAgent structure from a given product version.
32+
*
33+
* @param {string} version The product version
34+
* @param {function():SystemInfo} getSystemInfo Parameter used of inject system information and mock calls to the APIs.
35+
* @returns {BoltAgent} The bolt agent
36+
*/
37+
export function fromVersion (
38+
version: string,
39+
getSystemInfo: () => SystemInfo = () => ({
40+
hostArch: process.config.variables.host_arch,
41+
nodeVersion: process.versions.node,
42+
v8Version: process.versions.v8,
43+
get platform () {
44+
return platform()
45+
},
46+
get release () {
47+
return release()
48+
}
49+
})
50+
): BoltAgent {
51+
const systemInfo = getSystemInfo()
52+
const HOST_ARCH = systemInfo.hostArch
53+
const NODE_VERSION = 'Node/' + systemInfo.nodeVersion
54+
const NODE_V8_VERSION = systemInfo.v8Version
55+
const OS_NAME_VERSION = `${systemInfo.platform} ${systemInfo.release}`
2656

27-
return `neo4j-javascript/${version} (${OS_NAME_VERSION}; ${HOST_ARCH}) ${NODE_VERSION} (v8 ${NODE_V8_VERSION})`
57+
return {
58+
product: `neo4j-javascript/${version}`,
59+
platform: `${OS_NAME_VERSION}; ${HOST_ARCH}`,
60+
languageDetails: `${NODE_VERSION} (v8 ${NODE_V8_VERSION})`
61+
}
2862
}
63+
64+
export type { SystemInfo }

packages/core/src/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ export interface AuthToken {
4949
parameters?: Parameters
5050
}
5151

52+
export interface BoltAgent {
53+
product?: string
54+
platform?: string
55+
language?: string
56+
languageDetails?: string
57+
}
58+
5259
export interface Config {
5360
encrypted?: boolean | EncryptionLevel
5461
trust?: TrustStrategy
@@ -65,7 +72,7 @@ export interface Config {
6572
logging?: LoggingConfig
6673
resolver?: (address: string) => string[] | Promise<string[]>
6774
userAgent?: string
68-
boltAgent?: string
75+
boltAgent?: BoltAgent
6976
}
7077

7178
/**

0 commit comments

Comments
 (0)