@zodic/shared 0.0.236 β†’ 0.0.237

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -550,22 +550,20 @@ export class ConceptService {
550
550
  structuredContentEN: StructuredConceptContent;
551
551
  structuredContentPT: StructuredConceptContent;
552
552
  }> {
553
- console.log(
554
- `πŸ“Œ [START] Parsing structured content for ${conceptSlug} from ChatGPT response.`
555
- );
553
+ console.log(`πŸ“Œ [START] Parsing structured content for ${conceptSlug}`);
556
554
 
557
555
  // βœ… Step 1: Clean artifacts before processing
558
556
  let cleanedResponse = response
559
557
  .replace(/[*#β€’]/g, '') // Remove bullet points, bold markers, headings
560
558
  .replace(/---+/g, '') // Remove dividers (like "---")
561
559
  .replace(/\n\s*\n/g, '\n\n') // Normalize multiple line breaks
562
- .replace(/\s+EN:\s*/g, '\nEN: ') // Ensure consistent "EN:" formatting
563
- .replace(/\s+PT:\s*/g, '\nPT: ') // Ensure consistent "PT:" formatting
560
+ .replace(/\s+EN:\s*/g, '\nEN: ') // Normalize "EN:"
561
+ .replace(/\s+PT:\s*/g, '\nPT: ') // Normalize "PT:"
564
562
  .trim();
565
563
 
566
564
  console.log(
567
565
  'πŸ”Ή [CLEANED RESPONSE]:',
568
- cleanedResponse.slice(0, 500) + '...'
566
+ cleanedResponse.slice(0, 3000) + '...'
569
567
  );
570
568
 
571
569
  try {
@@ -677,12 +675,13 @@ export class ConceptService {
677
675
  }
678
676
 
679
677
  // βœ… Step 3: Detect if AI interleaved EN/PT sections
680
- const interleavedMatches = cleanedResponse.match(
681
- /(EN:\s*[\s\S]+?PT:\s*[\s\S]+?)(?=EN:|$)/
682
- );
683
678
  let extractedEN = '';
684
679
  let extractedPT = '';
685
680
 
681
+ const interleavedMatches = cleanedResponse.match(
682
+ /(EN:\s*[\s\S]+?PT:\s*[\s\S]+?)(?=EN:|$)/g
683
+ );
684
+
686
685
  if (interleavedMatches) {
687
686
  console.warn(
688
687
  '⚠️ Detected interleaved EN/PT sections. Parsing accordingly.'
@@ -706,21 +705,21 @@ export class ConceptService {
706
705
  }
707
706
 
708
707
  console.log(
709
- 'βœ… [MATCH SUCCESS] Extracted English Content:',
710
- extractedEN.slice(0, 500) + '...'
708
+ 'βœ… Extracted English Content:',
709
+ extractedEN.slice(0, 1000) + '...'
711
710
  );
712
711
  console.log(
713
- 'βœ… [MATCH SUCCESS] Extracted Portuguese Content:',
714
- extractedPT.slice(0, 500) + '...'
712
+ 'βœ… Extracted Portuguese Content:',
713
+ extractedPT.slice(0, 1000) + '...'
715
714
  );
716
715
 
717
716
  // βœ… Step 4: Extract structured sections dynamically
718
717
  function extractSections(text: string, sectionTitles: string[]) {
719
718
  return sectionTitles.map((title) => {
720
- console.log(`πŸ” [PROCESSING] Extracting section: "${title}"`);
719
+ console.log(`πŸ” Extracting section: "${title}"`);
721
720
 
722
721
  const regex = new RegExp(
723
- `\\d+\\.\\s*${title}:\\s*([\\s\\S]+?)(?=\\n\\d+\\.\\s*[A-Z]|$)`
722
+ `(?:\\d+\\.\\s*)?${title}\\s*:?\\s*([\\s\\S]+?)(?=\\n(?:\\d+\\.\\s*)?[A-Z]|$)`
724
723
  );
725
724
  const match = text.match(regex);
726
725
 
@@ -734,10 +733,7 @@ export class ConceptService {
734
733
  .map((p) => p.trim())
735
734
  .filter((p) => p.length > 0);
736
735
 
737
- console.log(
738
- `βœ… [EXTRACTED] "${title}" - Parsed Content:`,
739
- paragraphs
740
- );
736
+ console.log(`βœ… Extracted "${title}" - Parsed Content:`, paragraphs);
741
737
  return { type: 'section', title, content: paragraphs };
742
738
  });
743
739
  }
@@ -746,17 +742,15 @@ export class ConceptService {
746
742
  const structuredContentPT = extractSections(extractedPT, sectionsPT);
747
743
 
748
744
  console.log(
749
- '🎯 [FINAL RESULT] Parsed English Content:',
745
+ '🎯 Parsed English Content:',
750
746
  JSON.stringify(structuredContentEN, null, 2)
751
747
  );
752
748
  console.log(
753
- '🎯 [FINAL RESULT] Parsed Portuguese Content:',
749
+ '🎯 Parsed Portuguese Content:',
754
750
  JSON.stringify(structuredContentPT, null, 2)
755
751
  );
756
752
 
757
- console.log(
758
- 'βœ… [COMPLETE] Structured content parsing finished successfully.'
759
- );
753
+ console.log('βœ… Structured content parsing finished successfully.');
760
754
 
761
755
  return {
762
756
  structuredContentEN,
@@ -784,6 +778,247 @@ export class ConceptService {
784
778
  }
785
779
  }
786
780
 
781
+ // async parseStructuredContent(
782
+ // conceptSlug: Concept,
783
+ // response: string
784
+ // ): Promise<{
785
+ // structuredContentEN: StructuredConceptContent;
786
+ // structuredContentPT: StructuredConceptContent;
787
+ // }> {
788
+ // console.log(
789
+ // `πŸ“Œ [START] Parsing structured content for ${conceptSlug} from ChatGPT response.`
790
+ // );
791
+
792
+ // // βœ… Step 1: Clean artifacts before processing
793
+ // let cleanedResponse = response
794
+ // .replace(/[*#β€’]/g, '') // Remove bullet points, bold markers, headings
795
+ // .replace(/---+/g, '') // Remove dividers (like "---")
796
+ // .replace(/\n\s*\n/g, '\n\n') // Normalize multiple line breaks
797
+ // .replace(/\s+EN:\s*/g, '\nEN: ') // Ensure consistent "EN:" formatting
798
+ // .replace(/\s+PT:\s*/g, '\nPT: ') // Ensure consistent "PT:" formatting
799
+ // .trim();
800
+
801
+ // console.log(
802
+ // 'πŸ”Ή [CLEANED RESPONSE]:',
803
+ // cleanedResponse.slice(0, 500) + '...'
804
+ // );
805
+
806
+ // try {
807
+ // // βœ… Step 2: Define Section Titles Per Concept
808
+ // const conceptSections: Record<string, { en: string[]; pt: string[] }> = {
809
+ // crown: {
810
+ // en: [
811
+ // 'Core Identity',
812
+ // 'Strengths and Challenges',
813
+ // 'Path to Fulfillment',
814
+ // 'Emotional Depth',
815
+ // 'Vision and Aspirations',
816
+ // ],
817
+ // pt: [
818
+ // 'Identidade Essencial',
819
+ // 'ForΓ§as e Desafios',
820
+ // 'Caminho para a Plenitude',
821
+ // 'Profundidade Emocional',
822
+ // 'VisΓ£o e AspiraΓ§Γ΅es',
823
+ // ],
824
+ // },
825
+ // scepter: {
826
+ // en: [
827
+ // 'The Power of Expression',
828
+ // 'The Dance of Action and Reaction',
829
+ // 'Navigating Challenges',
830
+ // 'The Mirror of Relations',
831
+ // 'Impact on the World',
832
+ // ],
833
+ // pt: [
834
+ // 'O Poder da ExpressΓ£o',
835
+ // 'A DanΓ§a da AΓ§Γ£o e ReaΓ§Γ£o',
836
+ // 'Navegando Desafios',
837
+ // 'O Espelho das RelaΓ§Γ΅es',
838
+ // 'Impacto no Mundo',
839
+ // ],
840
+ // },
841
+ // amulet: {
842
+ // en: [
843
+ // 'The Shield of Protection',
844
+ // 'The Strength Within',
845
+ // 'Nurturing Growth',
846
+ // 'The Cycle of Renewal',
847
+ // 'The Anchor of Wisdom',
848
+ // ],
849
+ // pt: [
850
+ // 'O Escudo da ProteΓ§Γ£o',
851
+ // 'A ForΓ§a Interior',
852
+ // 'Cultivando o Crescimento',
853
+ // 'O Ciclo da RenovaΓ§Γ£o',
854
+ // 'A Γ‚ncora da Sabedoria',
855
+ // ],
856
+ // },
857
+ // ring: {
858
+ // en: [
859
+ // 'Magnetic Pull',
860
+ // 'Hidden Desires',
861
+ // 'The Fated Dance',
862
+ // 'Unveiling the Shadows',
863
+ // 'Your Love Power',
864
+ // ],
865
+ // pt: [
866
+ // 'ForΓ§a MagnΓ©tica',
867
+ // 'Desejos Ocultos',
868
+ // 'A DanΓ§a do Destino',
869
+ // 'Revelando as Sombras',
870
+ // 'Seu Poder no Amor',
871
+ // ],
872
+ // },
873
+ // lantern: {
874
+ // en: [
875
+ // 'The Call to Awakening',
876
+ // 'Walking Through Shadows',
877
+ // 'The Inner Flame',
878
+ // 'Revelations and Truths',
879
+ // 'Becoming the Light',
880
+ // ],
881
+ // pt: [
882
+ // 'O Chamado para o Despertar',
883
+ // 'Caminhando Pelas Sombras',
884
+ // 'A Chama Interior',
885
+ // 'RevelaΓ§Γ΅es e Verdades',
886
+ // 'Tornando-se a Luz',
887
+ // ],
888
+ // },
889
+ // orb: {
890
+ // en: [
891
+ // 'The Path Unfolding',
892
+ // 'A Calling Beyond the Self',
893
+ // 'Turning Points of Fate',
894
+ // 'Mastering the Journey',
895
+ // 'Legacy and Impact',
896
+ // ],
897
+ // pt: [
898
+ // 'O Caminho que se Revela',
899
+ // 'Um Chamado AlΓ©m de Si Mesmo',
900
+ // 'Pontos de Virada do Destino',
901
+ // 'Dominando a Jornada',
902
+ // 'Legado e Impacto',
903
+ // ],
904
+ // },
905
+ // };
906
+
907
+ // const sectionsEN = conceptSections[conceptSlug]?.en;
908
+ // const sectionsPT = conceptSections[conceptSlug]?.pt;
909
+
910
+ // if (!sectionsEN || !sectionsPT) {
911
+ // throw new Error(`Unknown concept: ${conceptSlug}`);
912
+ // }
913
+
914
+ // // βœ… Step 3: Detect if AI interleaved EN/PT sections
915
+ // const interleavedMatches = cleanedResponse.match(
916
+ // /(EN:\s*[\s\S]+?PT:\s*[\s\S]+?)(?=EN:|$)/
917
+ // );
918
+ // let extractedEN = '';
919
+ // let extractedPT = '';
920
+
921
+ // if (interleavedMatches) {
922
+ // console.warn(
923
+ // '⚠️ Detected interleaved EN/PT sections. Parsing accordingly.'
924
+ // );
925
+ // extractedEN = interleavedMatches
926
+ // .map(
927
+ // (pair) => pair.match(/EN:\s*([\s\S]+?)\s*PT:/)?.[1]?.trim() || ''
928
+ // )
929
+ // .join('\n\n');
930
+ // extractedPT = interleavedMatches
931
+ // .map((pair) => pair.match(/PT:\s*([\s\S]+)/)?.[1]?.trim() || '')
932
+ // .join('\n\n');
933
+ // } else {
934
+ // console.log(
935
+ // 'βœ… Standard format detected (EN block followed by PT block).'
936
+ // );
937
+ // extractedEN =
938
+ // cleanedResponse.match(/EN:\s*([\s\S]+?)\s*PT:/)?.[1]?.trim() || '';
939
+ // extractedPT =
940
+ // cleanedResponse.match(/PT:\s*([\s\S]+)/)?.[1]?.trim() || '';
941
+ // }
942
+
943
+ // console.log(
944
+ // 'βœ… [MATCH SUCCESS] Extracted English Content:',
945
+ // extractedEN.slice(0, 500) + '...'
946
+ // );
947
+ // console.log(
948
+ // 'βœ… [MATCH SUCCESS] Extracted Portuguese Content:',
949
+ // extractedPT.slice(0, 500) + '...'
950
+ // );
951
+
952
+ // // βœ… Step 4: Extract structured sections dynamically
953
+ // function extractSections(text: string, sectionTitles: string[]) {
954
+ // return sectionTitles.map((title) => {
955
+ // console.log(`πŸ” [PROCESSING] Extracting section: "${title}"`);
956
+
957
+ // const regex = new RegExp(
958
+ // `\\d+\\.\\s*${title}:\\s*([\\s\\S]+?)(?=\\n\\d+\\.\\s*[A-Z]|$)`
959
+ // );
960
+ // const match = text.match(regex);
961
+
962
+ // if (!match) {
963
+ // throw new Error(`❌ Missing section: "${title}"`);
964
+ // }
965
+
966
+ // const paragraphs = match[1]
967
+ // .trim()
968
+ // .split(/\n{2,}/)
969
+ // .map((p) => p.trim())
970
+ // .filter((p) => p.length > 0);
971
+
972
+ // console.log(
973
+ // `βœ… [EXTRACTED] "${title}" - Parsed Content:`,
974
+ // paragraphs
975
+ // );
976
+ // return { type: 'section', title, content: paragraphs };
977
+ // });
978
+ // }
979
+
980
+ // const structuredContentEN = extractSections(extractedEN, sectionsEN);
981
+ // const structuredContentPT = extractSections(extractedPT, sectionsPT);
982
+
983
+ // console.log(
984
+ // '🎯 [FINAL RESULT] Parsed English Content:',
985
+ // JSON.stringify(structuredContentEN, null, 2)
986
+ // );
987
+ // console.log(
988
+ // '🎯 [FINAL RESULT] Parsed Portuguese Content:',
989
+ // JSON.stringify(structuredContentPT, null, 2)
990
+ // );
991
+
992
+ // console.log(
993
+ // 'βœ… [COMPLETE] Structured content parsing finished successfully.'
994
+ // );
995
+
996
+ // return {
997
+ // structuredContentEN,
998
+ // structuredContentPT,
999
+ // };
1000
+ // } catch (error) {
1001
+ // console.error(`❌ Parsing failed for ${conceptSlug}. Logging failure.`);
1002
+
1003
+ // // βœ… Store failure in KV for debugging
1004
+ // const kvFailuresStore = this.context.kvConceptFailuresStore();
1005
+ // const failureKey = `failures:content:parsing:${conceptSlug}:${new Date().toISOString()}`;
1006
+
1007
+ // await kvFailuresStore.put(
1008
+ // failureKey,
1009
+ // JSON.stringify({
1010
+ // error: (error as Error).message,
1011
+ // conceptSlug,
1012
+ // cleanedResponse,
1013
+ // timestamp: new Date().toISOString(),
1014
+ // })
1015
+ // );
1016
+
1017
+ // console.error(`🚨 Failure logged in KV: ${failureKey}`);
1018
+ // throw error;
1019
+ // }
1020
+ // }
1021
+
787
1022
  // private parseStructuredContent(
788
1023
  // conceptSlug: Concept,
789
1024
  // response: string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.236",
3
+ "version": "0.0.237",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {