@@ -8,115 +8,86 @@ const requestManager = require("../../core/request-manager");
88const API = require ( "../../../nr-security-api" ) ;
99const logger = API . getLogger ( ) ;
1010
11- const fs = require ( 'fs' ) ;
12- const path = require ( 'path' ) ;
11+ const semver = require ( 'semver' )
1312
1413module . exports = function initialize ( shim , nextjs ) {
15- const pkgVersion = shim . require ( 'package.json' ) . version ;
16- logger . info ( "Instrumenting nextjs" , pkgVersion ) ;
14+ const nextVersion = shim . require ( './ package.json' ) . version
15+ logger . info ( "Instrumenting nextjs" , nextVersion ) ;
1716
18- const utils = shim . require ( './dist/next-server/lib/router/utils' ) ;
17+ const nextServer = nextjs . default ;
18+ hookRunAPI ( shim , nextServer . prototype , nextVersion ) ;
19+ }
1920
20- if ( utils ) {
21- getRouteMatcherHook ( utils ) ;
22- }
21+ /**
22+ * Wrapper for Server.prototype.runApi
23+ * @param {* } shim
24+ * @param {* } mod
25+ * @param {* } nextVersion
26+ */
27+ function hookRunAPI ( shim , mod , nextVersion ) {
28+ shim . wrap ( mod , 'runApi' , function wrapRunApi ( shim , originalFn ) {
29+ if ( ! shim . isFunction ( originalFn ) ) {
30+ return originalFn
31+ }
32+ logger . debug ( "Instrumenting Server.prototype.runApi" ) ;
33+ return function wrappedRunApi ( ) {
34+ try {
35+ const { page, params } = extractAttrs ( arguments , nextVersion )
36+ extractParams ( shim , page , params ) ;
37+ } catch ( error ) {
38+ logger . debug ( "Error while processing path paramters" ) ;
39+ }
2340
24- const routeMatcher = shim . require ( './dist/shared/lib/router/utils/route-matcher.js' ) ;
41+ return originalFn . apply ( this , arguments )
42+ }
43+ } )
44+ }
2545
26- if ( routeMatcher ) {
27- getRouteMatcherHook ( routeMatcher ) ;
46+ /**
47+ * Extracts the page and params from an API request
48+ *
49+ * @param {object } args arguments to runApi
50+ * @param {string } version next.js version
51+ * @returns {object } { page, params }
52+ */
53+ function extractAttrs ( args , version ) {
54+ let params
55+ let page
56+ if ( semver . gte ( version , '13.4.13' ) ) {
57+ const [ , , , match ] = args
58+ page = match ?. definition ?. pathname
59+ params = { ...match ?. params }
60+ } else {
61+ ; [ , , , params , page ] = args
2862 }
2963
30- /**
31- * wrapper for route-matcher.getRouteMatcher
32- * @param {* } mod
33- */
34- function getRouteMatcherHook ( mod ) {
35- shim . wrap ( mod , 'getRouteMatcher' , function wrapGetRouterMatcher ( shim , fn ) {
36- if ( ! shim . isFunction ( fn ) ) {
37- return fn
38- }
39- logger . debug ( `Instrumenting route-matcher.getRouteMatcher` )
40- return function wrappedGetRouterMatcher ( ) {
41- let result = fn . apply ( this , arguments )
42- if ( ! shim . isFunction ( result ) ) {
43- return result ;
44- }
45- let original = result ;
46- result = function ( ) {
47- const res = original . apply ( this , arguments ) ;
48- extractParams ( this , res ) ;
49- return res ;
50- }
51- return result
52- }
53- } )
54- }
64+ return { params, page }
65+ }
5566
56- /**
57- * Utility to extract path params
58- * @param {* } obj
59- * @param {* } params
60- */
61- function extractParams ( obj , params ) {
62- try {
63- const transaction = shim . tracer . getTransaction ( ) ;
64- if ( transaction ) {
65- let request = requestManager . getRequestFromId ( transaction . id ) ;
66- Object . keys ( params ) . forEach ( function ( key ) {
67- if ( params [ key ] ) {
68- if ( ! request . parameterMap [ key ] ) {
69- request . parameterMap [ key ] = new Array ( params [ key ] . toString ( ) ) ;
70- requestManager . setRequest ( transaction . id , request ) ;
71- }
67+ /**
68+ * Utility to extract path params
69+ * @param {* } page
70+ * @param {* } params
71+ */
72+ function extractParams ( shim , page , params ) {
73+ try {
74+ const transaction = shim . tracer . getTransaction ( ) ;
75+ if ( transaction ) {
76+ let request = requestManager . getRequestFromId ( transaction . id ) ;
77+ Object . keys ( params ) . forEach ( function ( key ) {
78+ if ( params [ key ] ) {
79+ if ( ! request . parameterMap [ key ] ) {
80+ request . parameterMap [ key ] = new Array ( params [ key ] . toString ( ) ) ;
81+ requestManager . setRequest ( transaction . id , request ) ;
7282 }
73- } ) ;
74- if ( request && obj && obj . page ) {
75- request . uri = obj . page ;
76- requestManager . setRequest ( transaction . id , request ) ;
7783 }
84+ } ) ;
85+ if ( request && page ) {
86+ request . uri = page ;
87+ requestManager . setRequest ( transaction . id , request ) ;
7888 }
79- } catch ( error ) {
8089 }
90+ } catch ( error ) {
8191 }
82-
8392}
8493
85- /**
86- * Utility to scan pages directory to get all avaible routes
87- * @param {* } dir
88- * @returns
89- */
90- const getAllAPIEndpoints = ( dir ) => {
91- const apiEndpoints = [ ] ;
92-
93- const scanDirectory = ( currentDir ) => {
94- const files = fs . readdirSync ( currentDir ) ;
95-
96- files . forEach ( ( file ) => {
97- const filePath = path . join ( currentDir , file ) ;
98- const isDirectory = fs . statSync ( filePath ) . isDirectory ( ) ;
99-
100- if ( isDirectory ) {
101- scanDirectory ( filePath ) ;
102- } else {
103- const apiEndpoint = filePath . replace ( `${ dir } /` , '/' ) . replace ( / \. j s $ / , '' ) ;
104- apiEndpoints . push ( apiEndpoint ) ;
105- }
106- } ) ;
107- } ;
108-
109- scanDirectory ( dir ) ;
110- return apiEndpoints ;
111- } ;
112-
113-
114- //TODO need to update for API endpoints
115- // try {
116- // const appRoot = API.getSecAgent().applicationInfo.serverInfo.deployedApplications[0].deployedPath;
117- // const searchPath = appRoot + '/.next/server/pages';
118- // const allAPIEndpoints = getAllAPIEndpoints(searchPath);
119- // } catch (error) {
120- // logger.debug("Error while getting all API end points for next.js", error);
121- // }
122-
0 commit comments