@@ -27,6 +27,7 @@ import core, {
27
27
Attribute ,
28
28
type Class ,
29
29
type Doc ,
30
+ isId ,
30
31
generateId ,
31
32
PersonId ,
32
33
type Ref ,
@@ -63,6 +64,8 @@ import { type Logger } from '../importer/logger'
63
64
import { BaseMarkdownPreprocessor } from '../importer/preprocessor'
64
65
import { type FileUploader } from '../importer/uploader'
65
66
import { Props , UnifiedDoc } from '../types'
67
+ import { readMarkdownContent , readYamlHeader } from './parsing'
68
+ import { UnifiedDocProcessor } from './unified'
66
69
67
70
export interface HulyComment {
68
71
author : string
@@ -350,13 +353,16 @@ export class HulyFormatImporter {
350
353
351
354
private readonly personIdByEmail = new Map < string , PersonId > ( )
352
355
356
+ private readonly unifiedDocImporter : UnifiedDocProcessor
357
+
353
358
constructor (
354
359
private readonly client : TxOperations ,
355
360
private readonly fileUploader : FileUploader ,
356
361
private readonly logger : Logger ,
357
362
private readonly importerSocialId ?: PersonId ,
358
363
private readonly importerPerson ?: Ref < Person >
359
364
) {
365
+ this . unifiedDocImporter = new UnifiedDocProcessor ( this . client , this . logger )
360
366
}
361
367
362
368
private async initCaches ( ) : Promise < void > {
@@ -482,6 +488,29 @@ export class HulyFormatImporter {
482
488
}
483
489
}
484
490
491
+ // Импортируем UnifiedDoc сущности
492
+ const unifiedResult = await this . unifiedDocImporter . importFromDirectory ( folderPath )
493
+
494
+ // Разбираем и добавляем в билдер по классу
495
+ for ( const [ path , docs ] of unifiedResult . entries ( ) ) {
496
+ for ( const doc of docs ) {
497
+ switch ( doc . _class ) {
498
+ case card . class . MasterTag :
499
+ builder . addMasterTag ( path , doc as UnifiedDoc < MasterTag > )
500
+ break
501
+ case core . class . Attribute :
502
+ builder . addMasterTagAttributes ( path , [ doc as UnifiedDoc < Attribute < MasterTag > > ] )
503
+ break
504
+ default :
505
+ if ( isId ( doc . _class ) ) {
506
+ builder . addCard ( path , doc as UnifiedDoc < Card > )
507
+ } else {
508
+ this . logger . error ( `Unknown doc class ${ String ( doc . _class ) } for path ${ path } ` )
509
+ }
510
+ }
511
+ }
512
+ }
513
+
485
514
// Process all yaml files first
486
515
const yamlFiles = fs . readdirSync ( folderPath ) . filter ( ( f ) => f . endsWith ( '.yaml' ) && f !== 'settings.yaml' )
487
516
@@ -528,22 +557,7 @@ export class HulyFormatImporter {
528
557
}
529
558
530
559
case card . class . MasterTag : {
531
- const masterTag = await this . processMasterTag ( spaceConfig )
532
- const masterTagId = masterTag . props . _id as Ref < MasterTag >
533
- if ( masterTagId === undefined ) {
534
- throw new Error ( 'Master tag ID is undefined' )
535
- }
536
- builder . addMasterTag ( spacePath , masterTag )
537
-
538
- const attributesByLabel = await this . processMasterTagAttributes ( spaceConfig , masterTagId )
539
- builder . addMasterTagAttributes ( spacePath , Array . from ( attributesByLabel . values ( ) ) )
540
-
541
- if ( fs . existsSync ( spacePath ) && fs . statSync ( spacePath ) . isDirectory ( ) ) {
542
- // Сначала обрабатываем дочерние мастер-теги
543
- await this . processSubTagsRecursively ( builder , spacePath , spacePath , masterTagId , attributesByLabel )
544
- // Затем обрабатываем карточки
545
- await this . processCardsRecursively ( builder , spacePath , spacePath , masterTagId , attributesByLabel )
546
- }
560
+ this . logger . log ( `Skipping ${ spaceName } : master tag already processed` )
547
561
break
548
562
}
549
563
@@ -669,7 +683,7 @@ export class HulyFormatImporter {
669
683
670
684
for ( const cardFile of cardFiles ) {
671
685
const cardPath = path . join ( currentPath , cardFile )
672
- const cardHeader = ( await this . readYamlHeader ( cardPath ) ) as Record < string , any >
686
+ const cardHeader = await readYamlHeader ( cardPath )
673
687
674
688
if ( cardHeader . class === undefined ) { // means it's a card of class MasterTag
675
689
const card = await this . processCard ( cardHeader , cardPath , masterTagId , attributesByLabel )
@@ -710,7 +724,7 @@ export class HulyFormatImporter {
710
724
return {
711
725
_class : masterTagId ,
712
726
collabField : 'content' ,
713
- contentProvider : ( ) => this . readMarkdownContent ( cardPath ) ,
727
+ contentProvider : ( ) => readMarkdownContent ( cardPath ) ,
714
728
props : props as Props < Card > // todo: what is the correct props type?
715
729
}
716
730
}
@@ -726,7 +740,7 @@ export class HulyFormatImporter {
726
740
727
741
for ( const issueFile of issueFiles ) {
728
742
const issuePath = path . join ( currentPath , issueFile )
729
- const issueHeader = ( await this . readYamlHeader ( issuePath ) ) as HulyIssueHeader
743
+ const issueHeader = ( await readYamlHeader ( issuePath ) ) as HulyIssueHeader
730
744
731
745
if ( issueHeader . class === undefined ) {
732
746
this . logger . error ( `Skipping ${ issueFile } : not an issue` )
@@ -750,7 +764,7 @@ export class HulyFormatImporter {
750
764
class : tracker . class . Issue ,
751
765
title : issueHeader . title ,
752
766
number : parseInt ( issueNumber ?? 'NaN' ) ,
753
- descrProvider : async ( ) => await this . readMarkdownContent ( issuePath ) ,
767
+ descrProvider : async ( ) => await readMarkdownContent ( issuePath ) ,
754
768
status : { name : issueHeader . status } ,
755
769
priority : issueHeader . priority ,
756
770
estimation : issueHeader . estimation ,
@@ -838,7 +852,7 @@ export class HulyFormatImporter {
838
852
839
853
for ( const docFile of docFiles ) {
840
854
const docPath = path . join ( currentPath , docFile )
841
- const docHeader = ( await this . readYamlHeader ( docPath ) ) as HulyDocumentHeader
855
+ const docHeader = ( await readYamlHeader ( docPath ) ) as HulyDocumentHeader
842
856
843
857
if ( docHeader . class === undefined ) {
844
858
this . logger . error ( `Skipping ${ docFile } : not a document` )
@@ -859,7 +873,7 @@ export class HulyFormatImporter {
859
873
id : docMeta . id as Ref < Document > ,
860
874
class : document . class . Document ,
861
875
title : docHeader . title ,
862
- descrProvider : async ( ) => await this . readMarkdownContent ( docPath ) ,
876
+ descrProvider : async ( ) => await readMarkdownContent ( docPath ) ,
863
877
subdocs : [ ] // Will be added via builder
864
878
}
865
879
@@ -886,7 +900,7 @@ export class HulyFormatImporter {
886
900
887
901
for ( const docFile of docFiles ) {
888
902
const docPath = path . join ( currentPath , docFile )
889
- const docHeader = ( await this . readYamlHeader ( docPath ) ) as
903
+ const docHeader = ( await readYamlHeader ( docPath ) ) as
890
904
| HulyControlledDocumentHeader
891
905
| HulyDocumentTemplateHeader
892
906
@@ -1087,7 +1101,7 @@ export class HulyFormatImporter {
1087
1101
reviewers : header . reviewers ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1088
1102
approvers : header . approvers ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1089
1103
coAuthors : header . coAuthors ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1090
- descrProvider : async ( ) => await this . readMarkdownContent ( docPath ) ,
1104
+ descrProvider : async ( ) => await readMarkdownContent ( docPath ) ,
1091
1105
ccReason : header . changeControl ?. reason ,
1092
1106
ccImpact : header . changeControl ?. impact ,
1093
1107
ccDescription : header . changeControl ?. description ,
@@ -1125,30 +1139,14 @@ export class HulyFormatImporter {
1125
1139
reviewers : header . reviewers ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1126
1140
approvers : header . approvers ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1127
1141
coAuthors : header . coAuthors ?. map ( ( email ) => this . findEmployeeByName ( email ) ) ?? [ ] ,
1128
- descrProvider : async ( ) => await this . readMarkdownContent ( docPath ) ,
1142
+ descrProvider : async ( ) => await readMarkdownContent ( docPath ) ,
1129
1143
ccReason : header . changeControl ?. reason ,
1130
1144
ccImpact : header . changeControl ?. impact ,
1131
1145
ccDescription : header . changeControl ?. description ,
1132
1146
subdocs : [ ]
1133
1147
}
1134
1148
}
1135
1149
1136
- private async readYamlHeader ( filePath : string ) : Promise < any > {
1137
- this . logger . log ( 'Read YAML header from: ' + filePath )
1138
- const content = fs . readFileSync ( filePath , 'utf8' )
1139
- const match = content . match ( / ^ - - - \n ( [ \s \S ] * ?) \n - - - / )
1140
- if ( match != null ) {
1141
- return yaml . load ( match [ 1 ] )
1142
- }
1143
- return { }
1144
- }
1145
-
1146
- private async readMarkdownContent ( filePath : string ) : Promise < string > {
1147
- const content = fs . readFileSync ( filePath , 'utf8' )
1148
- const match = content . match ( / ^ - - - \n [ \s \S ] * ?\n - - - \n ( .* ) $ / s)
1149
- return match != null ? match [ 1 ] : content
1150
- }
1151
-
1152
1150
private async cacheAccountsByEmails ( ) : Promise < void > {
1153
1151
const employees = await this . client . findAll (
1154
1152
contact . mixin . Employee ,
0 commit comments