@@ -330,6 +330,48 @@ const processSchema = (fileSchema) => {
330330 return fileSchema ;
331331} ;
332332
333+ /**
334+ * Processa os Widgets dentro das propriedades, como por exemplo a propriedade
335+ * <Foo renderItem={project => <A_192 projectId={project.registrant_id} />} />
336+ * onde o "A_192" é um Widget
337+ *
338+ * ATENCAO: Isso trata especificamente os casos em que um widget (stateful component) é encontrado
339+ * nas propriedades
340+ *
341+ * @param {* } childProps
342+ * @param {* } fileSchemas
343+ * @returns
344+ */
345+ const transformWidgetInChildProps = ( childProps , fileSchemas ) => {
346+ const childPropEntries = Object . entries ( childProps ) ;
347+
348+ childPropEntries . forEach ( ( entry ) => {
349+ // Skip children prop
350+ if ( entry [ 0 ] === "children" ) {
351+ return childProps ;
352+ }
353+
354+ const entryKey = entry [ 0 ] ;
355+ let entryValue = entry [ 1 ] ;
356+
357+ // Ignora se nao tiver conteúdo JSX
358+ if ( ! entryValue . includes ( "/>" ) ) {
359+ return ;
360+ }
361+
362+ const foundJSXs = extractJSX ( entryValue ) ;
363+ if ( foundJSXs . length > 0 ) {
364+ foundJSXs . forEach ( ( jsx ) => {
365+ const widgetContent = processChildrenWidget ( `<>${ jsx } </>` , fileSchemas ) ;
366+ entryValue = entryValue . replace ( jsx , widgetContent ) ;
367+ } ) ;
368+ }
369+ childProps [ entryKey ] = entryValue ;
370+ } ) ;
371+
372+ return childProps ;
373+ } ;
374+
333375/**
334376 * Faz o procedimento de trocar componentes nome de componentes por <Widget code={...} />
335377 *
@@ -367,18 +409,15 @@ const swapComponentsForStatelessFiles = (fileSchemas, fileSchema) => {
367409 Object . keys ( fileSchema . componentImportItems ) . forEach ( ( importItem ) => {
368410 // Se for um arquivo disponível, segue (null quer dizer que é um import de alguma lib nao local no src)
369411 const importItemFilePath = fileSchema . componentImportItems [ importItem ] ;
412+
370413 // Nao deve processar (copiar e colar) o conteúdo do arquivo mais de uma vez
371414 if ( importItemFilePath && ! pastedFiles . includes ( importItemFilePath ) ) {
372415 // Adiciona na lista de items ja processados
373416 pastedFiles . push ( importItemFilePath ) ;
374417
375- // INFO: Verifica se o caminho do arquivo a ser processado não é "null"
376- const importItemFileSource = fileSchema . componentImportItems [ importItem ] ; // src/path/to/file.tsx | null
377-
378418 // Le o nome do Widget dependente (usando o fileSchema dele)
379419 let importItemWidget = fileSchemas . find (
380- ( importFileSchema ) =>
381- importFileSchema . filePath === importItemFileSource ,
420+ ( importFileSchema ) => importFileSchema . filePath === importItemFilePath ,
382421 ) ;
383422
384423 // MODULOS - INICIO
@@ -403,108 +442,103 @@ const swapComponentsForStatelessFiles = (fileSchemas, fileSchema) => {
403442 // const rootHTML = parse(fileBundle, {});
404443
405444 // Files without source are the ones that not live in the src directory
445+ // NOTE: Aqui que a magica acontece!!!!
446+
447+ const importItemWidgetComponentName =
448+ importItemWidget . widgetName ||
449+ getComponentName ( importItemWidget . finalFileBundle ) ;
450+
451+ if ( importItemWidgetComponentName && ! importItemWidget . isStateless ) {
452+ // Processa todos os componentes filhos
453+ // Cada elemento do mesmo tipo é um filho diferente que foi adicionado ao elemento pai
454+ // const importItemElements =
455+ // fileSchema.htmlElementsProps[importItemWidgetComponentName] || [];
456+
457+ // Usa o rootHTML (conteúdo html do componente) para pegar a lista de Componentes do tipo desejado. ex: Title
458+ // const componentElements = rootHTML.getElementsByTagName(
459+ // importItemWidgetComponentName,
460+ // );
461+ // INFO: Esses comentarios acima creio que podem ser apagados, verificar
462+ // se ainda estou usando o modulo html parse
463+
464+ const jsxOnly = extractJSX ( fileSchema . content ) ;
465+
466+ const fixedJsxOnly =
467+ jsxOnly . length > 1
468+ ? `<>${ jsxOnly . join ( "\n" ) } </>`
469+ : jsxOnly . join ( "\n" ) ;
470+
471+ const componentElements = extractJSXElements (
472+ fixedJsxOnly ,
473+ importItemWidgetComponentName ,
474+ ) ;
475+
476+ // Seta qualquer erro se tiver
477+ if ( ! processError && componentElements . error ) {
478+ processError = `${ fileSchema . filePath } : ${ componentElements . error } ` ;
479+ }
480+ if ( processError ) return ;
406481
407- // // INFO: Verifica se o caminho do arquivo a ser processado não é "null"
408- // const importItemFileSource =
409- // fileSchema.componentImportItems[importItem]; // src/path/to/file.tsx | null
482+ // Transfor cada componente em Widget com suas propriedades
483+ componentElements . elements . forEach ( ( div , divIndex ) => {
484+ const htmlElementString = componentElements . elements [ divIndex ]
485+ . toString ( )
486+ . replaceAll ( LINE_BREAKS , "" )
487+ . replaceAll ( MORE_THAN_ONE_SPACE , " " ) ;
410488
411- // Se existir o conteúdo localmente... segue...
412- if ( importItemFileSource ) {
413- // NOTE: Aqui que a magica acontece!!!!
489+ const extractPropsResult = extractPropsFromJSX ( htmlElementString ) ;
490+ let childProps = extractPropsResult . keyValueProps ;
414491
415- const importItemWidgetComponentName =
416- importItemWidget . widgetName ||
417- getComponentName ( importItemWidget . finalFileBundle ) ;
492+ const childSpreads = extractPropsResult . spreads ;
418493
419- if ( importItemWidgetComponentName && ! importItemWidget . isStateless ) {
420- // Processa todos os componentes filhos
421- // Cada elemento do mesmo tipo é um filho diferente que foi adicionado ao elemento pai
422- // const importItemElements =
423- // fileSchema.htmlElementsProps[importItemWidgetComponentName] || [];
494+ // get the children (pega o filho(s) do elemento principal)
495+ let childChildren = extractJSXChildren ( htmlElementString ) ;
424496
425- // Usa o rootHTML (conteúdo html do componente) para pegar a lista de Componentes do tipo desejado. ex: Title
426- // const componentElements = rootHTML.getElementsByTagName(
427- // importItemWidgetComponentName,
428- // );
429- // INFO: Esses comentarios acima creio que podem ser apagados, verificar
430- // se ainda estou usando o modulo html parse
497+ if ( childChildren ) {
498+ childChildren = processChildrenWidget ( childChildren , fileSchemas ) ;
499+ childProps = { ...childProps , children : childChildren } ;
500+ }
501+
502+ // Processa os Widgets dentro das propriedades, como por exemplo a propriedade
503+ // <Foo renderItem={project => <A_192 projectId={project.registrant_id} />} />
504+ // onde o "A_192" é um Widget
505+ childProps = transformWidgetInChildProps ( childProps , fileSchemas ) ;
431506
432- const jsxOnly = extractJSX ( fileSchema . content ) ;
507+ let importItemPropsStringSequence =
508+ convertObjectToArray ( childProps ) . join ( "," ) ;
509+
510+ // Adiciona os spreads junto com as propriedades do elemento JSX. Ex:
511+ // <Widget code="..." {...{foo: 2, bar: "oi", ...mySpread1, ...mySpread2}}
512+ // no caso os spreads sao: ...mySpread1 e ...mySpread2
513+ if ( childSpreads . length > 0 ) {
514+ importItemPropsStringSequence += `${ importItemPropsStringSequence . length > 0 ? "," : "" } ${ childSpreads . join ( "," ) } ` ;
515+ }
433516
434- const fixedJsxOnly =
435- jsxOnly . length > 1
436- ? `<>${ jsxOnly . join ( "\n" ) } </>`
437- : jsxOnly . join ( "\n" ) ;
517+ // Babel segue os padroes JS, por isso:
518+ // 1 - Adiciona uma uma função no topo
519+ // 2 - Fecha a função no final
520+ fileBundle = `const TempMethod = () => {\n${ fileBundle } \n}` ;
521+ // NOTE: nao adicionando a ultima linha, mas estou removendo a ultima linha
522+ // Caso quebre, ver isso. [Provavelmente o escape acima esta adicionando o } no final]
438523
439- const componentElements = extractJSXElements (
440- fixedJsxOnly ,
524+ // Transform components generated by .jsx / .tsx into <Widget code={code} .../>
525+ fileBundle = replaceJSXElement (
526+ fileBundle ,
441527 importItemWidgetComponentName ,
528+ 0 ,
529+ `<Widget loading=" " code={props.alem.componentsCode.${ importItemWidgetComponentName } } props={{ ...({${ importItemPropsStringSequence ? `${ importItemPropsStringSequence } ,` : "" } ...props}) }} />` ,
442530 ) ;
443531
444- // Seta qualquer erro se tiver
445- if ( ! processError && componentElements . error ) {
446- processError = `${ fileSchema . filePath } : ${ componentElements . error } ` ;
447- }
448- if ( processError ) return ;
449-
450- // Transfor cada componente em Widget com suas propriedades
451- componentElements . elements . forEach ( ( div , divIndex ) => {
452- const htmlElementString = componentElements . elements [ divIndex ]
453- . toString ( )
454- . replaceAll ( LINE_BREAKS , "" )
455- . replaceAll ( MORE_THAN_ONE_SPACE , " " ) ;
456-
457- const extractPropsResult = extractPropsFromJSX ( htmlElementString ) ;
458- let childProps = extractPropsResult . keyValueProps ;
459-
460- const childSpreads = extractPropsResult . spreads ;
461-
462- // get the children
463- let childChildren = extractJSXChildren ( htmlElementString ) ;
464- if ( childChildren ) {
465- childChildren = processChildrenWidget (
466- childChildren ,
467- fileSchemas ,
468- ) ;
469- childProps = { ...childProps , children : childChildren } ;
470- }
471-
472- let importItemPropsStringSequence =
473- convertObjectToArray ( childProps ) . join ( "," ) ;
474-
475- // Adiciona os spreads junto com as propriedades do elemento JSX. Ex:
476- // <Widget code="..." {...{foo: 2, bar: "oi", ...mySpread1, ...mySpread2}}
477- // no caso os spreads sao: ...mySpread1 e ...mySpread2
478- if ( childSpreads . length > 0 ) {
479- importItemPropsStringSequence += `${ importItemPropsStringSequence . length > 0 ? "," : "" } ${ childSpreads . join ( "," ) } ` ;
480- }
481-
482- // Babel segue os padroes JS, por isso:
483- // 1 - Adiciona uma uma função no topo
484- // 2 - Fecha a função no final
485- fileBundle = `const TempMethod = () => {\n${ fileBundle } \n}` ;
486- // NOTE: nao adicionando a ultima linha, mas estou removendo a ultima linha
487- // Caso quebre, ver isso. [Provavelmente o escape acima esta adicionando o } no final]
488-
489- // Transform components generated by .jsx / .tsx into <Widget code={code} .../>
490- fileBundle = replaceJSXElement (
491- fileBundle ,
492- importItemWidgetComponentName ,
493- 0 ,
494- `<Widget loading=" " code={props.alem.componentsCode.${ importItemWidgetComponentName } } props={{ ...({${ importItemPropsStringSequence ? `${ importItemPropsStringSequence } ,` : "" } ...props}) }} />` ,
495- ) ;
496-
497- // Remove funcao no topo e ultima linha fechando a funcao
498- fileBundle = fileBundle . replace ( "const TempMethod = () => {" , "" ) ;
499- fileBundle = removeLastLineFromText ( fileBundle ) ;
500- } ) ;
501- }
502-
503- // Altera o jsContent com os Widgets
504- fileSchema . jsContent = fileBundle ;
505- // Altera o finalBundle que é usado posteriormente
506- fileSchema . finalFileBundle = fileBundle ;
532+ // Remove funcao no topo e ultima linha fechando a funcao
533+ fileBundle = fileBundle . replace ( "const TempMethod = () => {" , "" ) ;
534+ fileBundle = removeLastLineFromText ( fileBundle ) ;
535+ } ) ;
507536 }
537+
538+ // Altera o jsContent com os Widgets
539+ fileSchema . jsContent = fileBundle ;
540+ // Altera o finalBundle que é usado posteriormente
541+ fileSchema . finalFileBundle = fileBundle ;
508542 }
509543 }
510544 } ) ;
0 commit comments