11import * as fs from 'fs' ;
22import * as path from 'path' ;
33import * as babel from '@babel/parser' ;
4- import { getNonce } from './getNonce' ;
4+ import { getNonce } from './utils/ getNonce' ;
55import { ImportObj } from './types/ImportObj' ;
66import { Tree } from "./types/tree" ;
77import { File } from '@babel/types' ;
88
9- // // function to determine server or client component (can look for 'use client' and 'hooks')
10- // // input: ast node (object)
11- // // output: boolean
12- // checkForClientString(node) {
13- // if (node.type === 'Directive') {
14- // console.log('node', node);
15- // // access the value property of the Directive node
16- // console.log('Directive Value:', node.value);
17- // // check if the node.value is a 'DirectiveLiteral' node
18- // if (node.value && node.value.type === 'DirectiveLiteral') {
19- // // check the value to see if it is 'use client'
20- // if (typeof node.value.value === 'string' && node.value.value.trim() === 'use client') {
21- // // access the value property of the 'DirectiveLiteral' node
22- // console.log('DirectiveLiteral Value:', node.value.value);
23- // // might need to do something else here to make it known as client type
24- // return true;
25- // }
26- // }
27- // }
28- // return false;
29- // }
30-
319export class Parser {
3210 entryFile : string ;
3311 tree : Tree | undefined ;
@@ -86,7 +64,7 @@ export class Parser {
8664 return this . tree ;
8765 }
8866
89- // Set Sapling Parser with a specific Data Tree (from workspace state)
67+ // Set entryFile property with the result of Parser (from workspace state)
9068 public setTree ( tree : Tree ) {
9169 this . entryFile = tree . filePath ;
9270 this . tree = tree ;
@@ -131,7 +109,7 @@ export class Parser {
131109 return this . tree ! ;
132110 }
133111
134- // Traverses the tree and changes expanded property of node whose id matches provided id
112+ // Traverses the tree and changes expanded property of node whose ID matches provided ID
135113 public toggleNode ( id : string , expanded : boolean ) : Tree {
136114 const callback = ( node : { id : string ; expanded : boolean } ) => {
137115 if ( node . id === id ) {
@@ -204,14 +182,13 @@ export class Parser {
204182 // Find imports in the current file, then find child components in the current file
205183 const imports = this . getImports ( ast . program . body ) ;
206184
207- if ( this . getCallee ( ast . program . body ) ) {
185+ // Set value of isClientComponent property
186+ if ( this . getComponentType ( ast . program . directives , ast . program . body ) ) {
208187 componentTree . isClientComponent = true ;
209188 } else {
210189 componentTree . isClientComponent = false ;
211190 }
212191
213- // console.log('componentTree.isClientComponent', componentTree.isClientComponent);
214- // console.log('--------------------------------')
215192 // Get any JSX Children of current file:
216193 if ( ast . tokens ) {
217194 componentTree . children = this . getJSXChildren (
@@ -247,10 +224,8 @@ export class Parser {
247224 }
248225
249226 // Extracts Imports from current file
250- // const Page1 = lazy(() => import('./page1')); -> is parsed as 'ImportDeclaration'
251- // import Page2 from './page2'; -> is parsed as 'VariableDeclaration'
252- // input: array of objects: ast.program.body
253- // output: object of imoprts
227+ // const App1 = lazy(() => import('./App1')); => is parsed as 'ImportDeclaration'
228+ // import App2 from './App2'; => is parsed as 'VariableDeclaration'
254229 private getImports ( body : { [ key : string ] : any } [ ] ) : ImportObj {
255230 const bodyImports = body . filter ( ( item ) => item . type === 'ImportDeclaration' || 'VariableDeclaration' ) ;
256231
@@ -278,7 +253,7 @@ export class Parser {
278253 }
279254
280255 private findVarDecImports ( ast : { [ key : string ] : any } ) : string | boolean {
281- // find import path in variable declaration and return it,
256+ // Find import path in variable declaration and return it,
282257 if ( ast . hasOwnProperty ( 'callee' ) && ast . callee . type === 'Import' ) {
283258 return ast . arguments [ 0 ] . value ;
284259 }
@@ -294,20 +269,32 @@ export class Parser {
294269 return false ;
295270 }
296271
297- // helper function to determine component type (client)
298- // input: ast.program.body
299- // output: boolean
300- private getCallee ( body : { [ key : string ] : any } [ ] ) : boolean {
301- const defaultErr = ( err , ) => {
272+ // Determines server or client component type (looks for use of 'use client' and react/redux state hooks)
273+ private getComponentType ( directive : { [ key : string ] : any } [ ] , body : { [ key : string ] : any } [ ] ) : boolean {
274+ const defaultErr = ( err ) => {
302275 return {
303276 method : 'Error in getCallee method of Parser:' ,
304277 log : err ,
305278 }
306279 } ;
307280
281+ console . log ( 'directive: ' , directive ) ;
282+ // Initial check for use of directives (ex: 'use client', 'use server', 'use strict')
283+ // Accounts for more than one directive
284+ for ( let i = 0 ; i < directive . length ; i ++ ) {
285+ if ( directive [ i ] . type === 'Directive' ) {
286+ if ( typeof directive [ i ] . value . value === 'string' && directive [ i ] . value . value . trim ( ) === 'use client' ) {
287+ return true ;
288+ }
289+ }
290+ break ;
291+ }
292+
293+ // Second check for use of React/Redux hooks
308294 const bodyCallee = body . filter ( ( item ) => item . type === 'VariableDeclaration' ) ;
309295 if ( bodyCallee . length === 0 ) return false ;
310296
297+ // Helper function
311298 const calleeHelper = ( item ) => {
312299 const hooksObj = {
313300 useState : 0 ,
@@ -420,7 +407,7 @@ export class Parser {
420407 childNodes ,
421408 ) ;
422409
423- // Case for finding components passed in as props e.g. <Route component ={App} />
410+ // Case for finding components passed in as props e.g. <Route Component ={App} />
424411 } else if (
425412 astTokens [ i ] . type . label === 'jsxName' &&
426413 ( astTokens [ i ] . value === 'Component' ||
@@ -473,7 +460,6 @@ export class Parser {
473460 props : props ,
474461 children : [ ] ,
475462 parent : parent . id ,
476- // consider adding the id to the parentList array somehow for D3 integration...
477463 parentList : [ parent . filePath ] . concat ( parent . parentList ) ,
478464 error : '' ,
479465 isClientComponent : false
@@ -501,7 +487,7 @@ export class Parser {
501487
502488 // Checks if current Node is connected to React-Redux Store
503489 private checkForRedux ( astTokens : any [ ] , importsObj : ImportObj ) : boolean {
504- // Check that react-redux is imported in this file (and we have a connect method or otherwise)
490+ // Check that React-Redux is imported in this file (and we have a connect method or otherwise)
505491 let reduxImported = false ;
506492 let connectAlias ;
507493 Object . keys ( importsObj ) . forEach ( ( key ) => {
0 commit comments